bye
Join Date: Jun 2016
Location: Some / Where
Posts: 680
|
I adapted tutorial 9 a bit - less allocations, more use of headers...
Code:
// Scoopex Tutorial 9 for Bebbo GCC 6.5.0b
#include <proto/exec.h>
#include <graphics/gfxbase.h>
#include <hardware/cia.h>
#include <hardware/custom.h>
#include <stdint.h>
#include <string.h>
#define bool short
#define true 1
#define false 0
// omit command line parsing - smalle executable
extern void __initlibraries(void);
void __nocommandline (void){ __initlibraries();}
extern struct GfxBase * GfxBase;
extern struct Custom custom;
extern struct CIA ciaa;
#define WIDTH 320
#define HEIGHT 256
__chip uint8_t screen_ptr[WIDTH*HEIGHT/8];
uint8_t* smile_sprite_ptr = 0;
uint16_t* copper_list = 0;
uint16_t* copper_list_end = 0;
__chip uint16_t SMILE_SPRITE[] = {
0x2C40,0x3C00, // Vstart.b,Hstart/2.b,Vstop.b,%A0000SEH
0x07C0,0x0000, // dc.w % ***** ,%
0x1FF0,0x0000, // dc.w % ********* ,%
0x3FF8,0x0000, // dc.w % *********** ,%
0x7FFC,0x0000, // dc.w % ************* ,%
0x67CC,0x1830, // dc.w % ** ***** ** ,% ** **
0xE7CE,0x1830, // dc.w %*** ***** *** ,% ** **
0xFFFE,0x0000, // dc.w %*************** ,%
0xFFFE,0x0000, // dc.w %*************** ,%
0xFFFE,0x2008, // dc.w %*************** ,% * *
0xFFFE,0x1830, // dc.w %*************** ,% ** **
0x7FFC,0x07C0, // dc.w % ************* ,% *****
0x7FFC,0x0000, // dc.w % ************* ,%
0x3FF8,0x0000, // dc.w % *********** ,%
0x1FF0,0x0000, // dc.w % ********* ,%
0x07C0,0x0000, // dc.w % ***** ,%
0x0000,0x0000, // dc.w % ,%
0,0
};
__chip uint16_t NULL_SPRITE[] = {
0x2a20,0x2b00,
0,0,
0,0
};
__chip uint16_t COPPER_LIST_BEGIN[] = {
//Copper:
0x1fc,0, // slow fetch mode, AGA compatibility
0x100,0x0200,
0x8e,0x2c81,
0x90,0x2cc1,
0x92,0x38,
0x94,0xd0,
0x108,0,
0x10a,0,
0x102,0,
0x1a2,0xe22,
0x1a4,0xff0,
0x1a6,0xfff
};
__chip uint16_t SPR_P[] = {
//SprP:
0x120, 0x0000, // Sprite 0 SMILE_SPRITE_HIGH (value is defined later)
0x122, 0x0000, // Sprite 0 SMILE_SPRITE_LOW
0x124, 0x0000, // Sprite 1 NULL_SPRITE_HIGH
0x126, 0x0000, // Sprite 1 NULL_SPRITE_LOW
0x128, 0x0000, // Sprite 2 NULL_SPRITE_HIGH
0x12a, 0x0000, // Sprite 2 NULL_SPRITE_LOW
0x12c, 0x0000, // Sprite 3 NULL_SPRITE_HIGH
0x12e, 0x0000, // Sprite 3 NULL_SPRITE_LOW
0x130, 0x0000, // Sprite 4 NULL_SPRITE_HIGH
0x132, 0x0000, // Sprite 4 NULL_SPRITE_LOW
0x134, 0x0000, // Sprite 5 NULL_SPRITE_HIGH
0x136, 0x0000, // Sprite 5 NULL_SPRITE_LOW
0x138, 0x0000, // Sprite 6 NULL_SPRITE_HIGH
0x13a, 0x0000, // Sprite 6 NULL_SPRITE_LOW
0x13c, 0x0000, // Sprite 7 NULL_SPRITE_HIGH
0x13e, 0x0000 // Sprite 7 NULL_SPRITE_LOW
};
__chip uint16_t COPPER_LIST_END[] = {
//CopBplP:
0xe0, 0x0006, // Screen HIGH WORD 0x0006 default
0xe2, 0x0000, // Screen LOW WORD 0x0000 default
0x180,0x349,
0x2b07,0xfffe,
0x180,0x56c,
0x2c07,0xfffe,
0x180,0x113,
0x100,0x1200,
0x182,0x379,
//waitras1: // COPPER_LIST_END[18]
0x8007,0xfffe,
0x180,0x055, // Adjusting color entry 0 of palette for horizontal bouncing bar
//waitras2: // COPPER_LIST_END[22]
0x8107,0xfffe,
0x180,0x0aa, // Adjusting color entry 0 again for next color of gradient
//waitras3: // COPPER_LIST_END[26]
0x8207,0xfffe,
0x180,0x0ff, // Next color
//waitras4: // COPPER_LIST_END[30]
0x8307,0xfffe,
0x180,0x0aa, // Next color
//waitras5: // COPPER_LIST_END[34]
0x8407,0xfffe,
0x180,0x055, // Next color
//waitras6: // COPPER_LIST_END[38]
0x8507,0xfffe,
0x180,0x113, // Next color
0xffdf,0xfffe,
0x2c07,0xfffe,
0x180,0x56c, // Next color
0x2d07,0xfffe,
0x180,0x349, // Last color of horizontal bar
0xffff,0xfffe
};
void waitRaster(uint32_t value) {
uint32_t mask = 0x1FF00;
uint32_t maskedValue = (value << 8) & mask;
while ((custom.vpos32 & mask) != maskedValue);
}
void fillScreenBuffer() {
const size_t bitplane_size = WIDTH * HEIGHT / 8;
uint8_t* helper = screen_ptr;
// Inicialización del hardware
for (uint32_t i = 0; i < bitplane_size; i++) {
// Filling frame buffer with horizontal position of beam. Assembler version of Scoopex
// is developed in assembler so it's faster. The look is different by this reason.
*helper++ = custom.vhposr;
}
}
void createCopperList() {
copper_list = COPPER_LIST_BEGIN;
uint16_t* spr_p_ptr = SPR_P;
copper_list_end = COPPER_LIST_END;
smile_sprite_ptr = (uint8_t*)SMILE_SPRITE;
uint16_t* null_sprite_ptr = NULL_SPRITE;
uint16_t lo_smile_sprite_ptr = ((uint32_t) smile_sprite_ptr) & 0xFFFF;
uint16_t hi_smile_sprite_ptr = ((uint32_t) smile_sprite_ptr) >> 16;
uint16_t lo_null_sprite_ptr = ((uint32_t) null_sprite_ptr) & 0xFFFF;
uint16_t hi_null_sprite_ptr = ((uint32_t) null_sprite_ptr) >> 16;
spr_p_ptr[1] = hi_smile_sprite_ptr;
spr_p_ptr[3] = lo_smile_sprite_ptr;
for (int i = 0; i < 7; i++) {
spr_p_ptr[5 + i * 4] = hi_null_sprite_ptr;
spr_p_ptr[7 + i * 4] = lo_null_sprite_ptr;
}
uint16_t lo_screen_ptr = ((uint32_t) screen_ptr) & 0xFFFF;
uint16_t hi_screen_ptr = ((uint32_t) screen_ptr) >> 16;
copper_list_end[1] = hi_screen_ptr;
copper_list_end[3] = lo_screen_ptr;
}
void setCopperList(uint16_t* cl) {
custom.cop1lc = (ULONG)cl;
}
void waitFrame() {
do {
while (custom.vposr & 1);
} while (custom.vhposr_h != 0x2a);
}
void waitFrame2() {
while (custom.vhposr_h != 0x2a);
}
bool leftClick() {
return (ciaa.ciapra & (1 << 6)) == 0;
}
int main(int argc, char** argv) {
struct copinit* copinit = GfxBase->copinit;
uint16_t old_INTENA = custom.intenar;
uint16_t old_DMACON = custom.dmaconr;
waitRaster(0x0138);
custom.intena = 0x7FFF; // Disable all bits in INTENA
custom.intreq = 0x7FFF; // Idem
custom.intreq = 0x7FFF; // Idem
//*INTREQW = 0x7FFF; // Idem. Original Scoopex code do this twice. I have removed without problems.
custom.dmacon = 0x7FFF; // Disable all bits in DMACON
custom.dmacon = 0x87E0; // Setting DMA channels
fillScreenBuffer(); // It's important to create screen buffer before Copper list
createCopperList();
setCopperList(copper_list);
// Wait loop
bool bar_lowering = true;
uint8_t bar_y_position = 0xAC;
while (true) {
waitFrame();
waitFrame2();
// Add 1 to sprite position (Smile icon)
smile_sprite_ptr[1]++;
bar_y_position = bar_lowering ? bar_y_position + 1 : bar_y_position - 1;
if (bar_y_position >= 0xF0)
bar_lowering = false;
if (bar_y_position <= 0x40)
bar_lowering = true;
*((uint8_t*) &copper_list_end[18]) = bar_y_position;
*((uint8_t*) &copper_list_end[22]) = bar_y_position + 1;
*((uint8_t*) &copper_list_end[26]) = bar_y_position + 2;
*((uint8_t*) &copper_list_end[30]) = bar_y_position + 3;
*((uint8_t*) &copper_list_end[34]) = bar_y_position + 4;
*((uint8_t*) &copper_list_end[38]) = bar_y_position + 5;
// Detecting left click to exit
if (leftClick())
break;
}
custom.dmacon = 0x7FFF; // Disabling DMACON
custom.dmacon = old_DMACON | 0x8200;
custom.cop1lc = (uint32_t) copinit;
custom.intena = old_INTENA | 0xC000;
return 0;
}
Save as C-file tut9.c and use
Code:
m68k-amigaos-gcc -Os -msmall-code -fomit-frame-pointer -mcrt=nix13 tut9.c -o tut9
And you'll get a file with ~2688 file size. (stripped 1744, but no debug infos then)
[/code]
EDIT:
add -msmall-code and -fomit-frame-pointer saves few more bytes.
Last edited by bebbo; 21 October 2019 at 14:53.
|