From 391c03b8aa6b09523403b24f395548ce237075fd Mon Sep 17 00:00:00 2001 From: John Bintz Date: Tue, 28 May 2024 08:02:28 -0400 Subject: [PATCH] (wip) --- bun.c | 166 +++++++++++++++++++++++++++++++++++++++++++++ bun.h | 10 +++ main | Bin 9536 -> 5460 bytes main.c | 199 +++++++++++++----------------------------------------- screen.c | 62 +++++++++++++---- screen.h | 41 +++++++---- smakefile | 6 +- 7 files changed, 303 insertions(+), 181 deletions(-) create mode 100644 bun.c create mode 100644 bun.h diff --git a/bun.c b/bun.c new file mode 100644 index 0000000..d000357 --- /dev/null +++ b/bun.c @@ -0,0 +1,166 @@ +#include "screen.h" +#include "bun.h" + +extern unsigned char far coolbun[]; + +unsigned char *coolbunArea; + +#define COOL_BUN_WIDTH (32) +#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8) +#define COOL_BUN_HEIGHT (32) +#define COOL_BUN_PLANES (2) + +#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT) +#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES) + +void setupBun() { + unsigned char *currentCoolBunArea, *currentCoolBun; + + coolbunArea = AllocMem(COOL_BUN_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); + currentCoolBun = coolbun; + + currentCoolBunArea = coolbunArea; + + for (plane = 0; plane < COOL_BUN_PLANES; ++plane) { + for (y = 0; y < COOL_BUN_HEIGHT; ++y) { + for (x = 0; x < COOL_BUN_WIDTH_BYTES; ++x) { + *(currentCoolBunArea++) = *(currentCoolBun++); + } + } + } +} + +void teardownBun() { + FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE); +} + +void bun_offRightSide(int plusXValue, int y, struct ScreenSetup *screenSetup) { + uint8_t i, plane = 0; + uint8_t shift = plusXValue & 15; + uint8_t wordShift = (plusXValue >> 4); + uint16_t bltalwm; + + for (plane = 0; plane < 2; ++plane) { + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); + custom.bltcon1 = (shift << 12); + + custom.bltadat = 0xffff; + custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; + custom.bltdpt = screenSetup->memoryStart + + plane * screenSetup->nextBitplaneAdvance + + (y * screenSetup.width + screenSetup.width - COOL_BUN_WIDTH) / 8 + + wordShift * 2; + + custom.bltafwm = 0xffff; + bltalwm = 0x0000; + for (i = 0; i < 15 - shift; ++i) { + bltalwm += (1 << (15 - i)); + } + custom.bltalwm = bltalwm; + + custom.bltbmod = wordShift * 2; + custom.bltdmod = (screenSetup.width - COOL_BUN_WIDTH) / 8 + wordShift * 2; + + custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); + + WaitBlit(); + } +} + +#define BLTCON0( \ + minterm, aChan, bChan, cChan, dChan, shift \ +) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12) +#define BLTCON1(descending, shift) ((descending << 1) + (shift << 12)) + +void bun_offLeftSide(int minusXValue, int y, struct CurrentScreen *currentScreen) { + unsigned char plane; + uint8_t shift = minusXValue & 15; + uint8_t wordShift = (minusXValue >> 4); + uint8_t i; + uint16_t bltalwm; + + // y can't be 0 otherwise we will corrupt memory for now + if (y == 0) return; + + for (plane = 0; plane < 2; ++plane) { + // shift left, so descending + custom.bltcon0 = BLTCON0(0xc0, 0, 1, 0, 1, shift); + custom.bltcon1 = BLTCON1(1, shift); + + // a has a mask we're shifting + custom.bltadat = 0xffff; + // b has bun data + custom.bltbpt = coolbunArea + 2 + ((COOL_BUN_HEIGHT - 1) * 4) + plane * COOL_BUN_PLANE_SIZE; + + // d is the part on screen + custom.bltdpt = screenSetup.memoryStart + screenSetup.nextBitplaneAdvance * plane + (screenSetup.width * (y + COOL_BUN_HEIGHT - 1) / 8) + 2 - wordShift * 2; + + custom.bltafwm = 0xffff; + bltalwm = 0x0000; + for (i = 0; i < 15 - shift; ++i) { + bltalwm += (1 << i); + } + custom.bltalwm = bltalwm; + + custom.bltbmod = wordShift * 2; + custom.bltdmod = screenSetup.width / 8 - 4 + wordShift * 2; + + custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); + + WaitBlit(); + } +} + +void bun_anywhere(int x, int y, struct ScreenSetup *screenSetup) { + uint8_t plane; + uint8_t shift = x & 15; + uint8_t needsExtraWord = shift != 0; + + for (plane = 0; plane < 2; ++plane) { + // if we extend the bun area by a word, we only need one write + + // buns will never interfere with a background so they don't need a mask + // they do need the scratch area though + custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); + custom.bltcon1 = (shift << 12); + + custom.bltadat = 0xffff; + custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; + custom.bltdpt = screenSetup.memoryStart + WORD_ALIGNED_BYTE_POSITION(screenSetup.width, x, y) + screenSetup.nextBitplaneAdvance * plane; + + // custom.bltdpt = screenSetup.memoryStart; + custom.bltafwm = 0xffff; + if (needsExtraWord) { + custom.bltalwm = 0x0000; + } else { + custom.bltalwm = 0xffff; + } + custom.bltbmod = -(needsExtraWord * 2); + custom.bltdmod = (screenSetup.width / 8) - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); + custom.bltsize = (2 + needsExtraWord) + (COOL_BUN_HEIGHT << 6); + + WaitBlit(); + } +} + +void renderBun(int x, int y, struct CurrentScreen *currentScreen) { + /** + * Conditions that will cause the program to crash if met. If your bun + * isn't rendering, it's due to here. + * + * TODO: Handle top/bottom off-screen as well. + */ + if (x < -31) return; + if (x > currentScreen->pixelWidth + 31) return; + if (y < 1) return; + if (y > currentScreen->pixelHeight- COOL_BUN_HEIGHT - 1) return; + + if (x < 0) { + bun_offLeftSide(-x, y, currentScreen); + } else if (x > screenSetup.width - COOL_BUN_WIDTH) { + bun_offRightSide(x - (currentScreen->pixelWidth - COOL_BUN_WIDTH), y, currentScreen); + } else { + bun_anywhere(x, y, currentScreen); + } +} + diff --git a/bun.h b/bun.h new file mode 100644 index 0000000..9cdc378 --- /dev/null +++ b/bun.h @@ -0,0 +1,10 @@ +#ifndef __BUN_H__ +#define __BUN_H__ + +#include "screen.h" + +void setupBun(); +void renderBun(int x, int y, struct ScreenSetup *screenSetup); +void teardownBun(); + +#endif diff --git a/main b/main index a245d7e76fe56a205f5edd15aa81ece3b45cac32..3aeb5e4c4dd2546adf01551fa957411bd89cbd46 100755 GIT binary patch delta 2688 zcmZWrZ){W775}~G7sn3y<9ZfLX+&Nf4-(7xnUGlsMT?VG)XE|!WNDYG6*z5bhs}VA zLdBvCKNy8*VwK@l6+#H{0Zn|cQnaFpMNyVSX!0afxrh(ZWGyhIg&~U~6jc<3c)$B> zGNw5>_n!anoO91R_swaeNi)sehvV|h#T^Zz)aJMk903uUs zUu`)kx!!mtO(jV^U!+q#W=#%9nOMuOaUP3CKvHXw%N^gV%OU0v!Wm<)wO96YRKITx+-3#=Av6*C)5PBY~chZ)Dd`EMxY=UnYKOX)??L?Y5Qst zQAO3DcoMkv6SO375n10+DDP%)r5t;e$i>W0@h5PFRl5^c)KDaqrlSR+Tvl{;XONCp zi-OSnyfE>1Q#})}b|-LEXfh-}weoRQ1nl-8MV*2}+cR++d6UA9 zyH42$YGcn*>R9B6aZ`3$k^KnvDkCq)0=V||LQ@t?k9$VpRN8!42rsDe5Ny9<5oW)h z3;1v&Jma9k2bVzk>er|L@-# zHZD~RoBm6&m+VzWSuvG6{jDyuL5pka87ze7m|X>>X(MReDf}m`n)JDG+3E_2fGd3A z`%Um^aQQVjlJ{oy1F=%(BDz`q;9ydk(GT>KH*G9iRfj0bsG6qeP`ywzT$O&lA|FAy zbZHgs;rmwVSc*iOS~2R&9lxi$G1hVWL~y>fy|@;fXHP1@h2X0F#+bTW&Yhsue6Rqe>pdoN zQ`;~ETo~*sH@ z<~Isxf2)8#&Za9#aa;$D;kunh)ZzBxmJ*Uy{GrIRVjCdltj3q;duPdO_&zqWU=H33 z%SOh*3AP-)z?ruk2eSRTn1J8tqf)q&({C5wsse8Z;eW+VBgRrNx?Z_5g5{W%M4oe; ztd=ky@cgHHmPQZ-yjrd4a3hCqA@1ncnSJ3K)3q3>KAuG6u!t*sUsC+=CNLbesRuZy z)84n$n%Ih3*|VhToLym~s(!N*`B;_j=QO?PN7ThhKVs~vZ;&<``~Prp{@{~iXb$bhR9!lN?RWbF1pZC;35eOsC~qx zl0dp@9I*4kw|fX=**6oM6z?KoCCJqIC*c9%Z-g20T!igaB_S+4*k?5ImT84}JwX`r zXL(ZklEA|+Lz`cbQlFV066Ouvvm~Qwj^asQsOb?~02ZD57ValIf8fmk4W&KM%s4_i zb_ne=YU4}%hIRg@|HI$B&QHJ0uZCk?aL&j#zTJ5SpKqT?6>(uZd(`qNcR^h=sWf*% zT{5Y2xb(WvISJh-_DQ!`^)E-&ZpoN?{dX;mqNI|}tWm|ac2ZzK%}(Ok5-vWh>Mk4C z-R{(e7+KB5B3Fff=5Isk3LyUBp@X}&2Q>cgXbosP1DYu}kFi`?yiZn`z-pUEQvPle zM`l6~ca^~3`YBXvwIX($?D_F`JUW|r7evPZF9gO#&%XV(GPOc^gV|9fGtz5MO8RCf nFCHa2qMU-|F>!g{FNgMz4fO6N?jTr9x+}4NjKqI`mM8xKPM+~Z literal 9536 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 diff --git a/main.c b/main.c index 7fdeefd..9d01e32 100644 --- a/main.c +++ b/main.c @@ -15,17 +15,9 @@ #include "screen.h" #include "types.h" +#include "bun.h" extern struct Custom far custom; -extern unsigned char far coolbun[]; - -#define COOL_BUN_WIDTH (32) -#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8) -#define COOL_BUN_HEIGHT (32) -#define COOL_BUN_PLANES (2) - -#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT) -#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES) // this should be large enough to hold one bitplane of the largest object // you are blitting, plus one additional word on each side @@ -35,160 +27,30 @@ extern unsigned char far coolbun[]; volatile short *dbg = (volatile short *)0x100; -unsigned char *coolbunArea; unsigned char *scratchArea; struct ScreenSetup screenSetup; +struct CurrentScreen currentScreen; -void bun_offRightSide(int plusXValue, int y) { - uint8_t i, plane = 0; - uint8_t shift = plusXValue & 15; - uint8_t wordShift = (plusXValue >> 4); - uint16_t bltalwm; - - for (plane = 0; plane < 2; ++plane) { - custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); - custom.bltcon1 = (shift << 12); - - custom.bltadat = 0xffff; - custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; - custom.bltdpt = screenSetup.memoryStart + plane * screenSetup.nextBitplaneAdvance + (y * screenSetup.width + screenSetup.width - COOL_BUN_WIDTH) / 8 + wordShift * 2; - - custom.bltafwm = 0xffff; - bltalwm = 0x0000; - for (i = 0; i < 15 - shift; ++i) { - bltalwm += (1 << (15 - i)); - } - custom.bltalwm = bltalwm; - - custom.bltbmod = wordShift * 2; - custom.bltdmod = (screenSetup.width - COOL_BUN_WIDTH) / 8 + wordShift * 2; - - custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); - - WaitBlit(); - } -} - -void bun_offLeftSide(int minusXValue, int y) { - unsigned char plane; - uint8_t shift = minusXValue & 15; - uint8_t wordShift = (minusXValue >> 4); - uint8_t i; - uint16_t bltalwm; - - // y can't be 0 otherwise we will corrupt memory for now - if (y == 0) return; - - for (plane = 0; plane < 2; ++plane) { - // shift left, so desccending - custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); - custom.bltcon1 = (1 << 1) + (shift << 12); - - // a has a mask we're shifting - custom.bltadat = 0xffff; - // b has bun data - custom.bltbpt = coolbunArea + 2 + ((COOL_BUN_HEIGHT - 1) * 4) + plane * COOL_BUN_PLANE_SIZE; - - // d is the part on screen - custom.bltdpt = screenSetup.memoryStart + screenSetup.nextBitplaneAdvance * plane + (screenSetup.width * (y + COOL_BUN_HEIGHT - 1) / 8) + 2 - wordShift * 2; - - custom.bltafwm = 0xffff; - bltalwm = 0x0000; - for (i = 0; i < 15 - shift; ++i) { - bltalwm += (1 << i); - } - custom.bltalwm = bltalwm; - - custom.bltbmod = wordShift * 2; - custom.bltdmod = screenSetup.width / 8 - 4 + wordShift * 2; - - custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); - - WaitBlit(); - } -} - -void bun_anywhere(int x, int y) { - uint8_t plane; - uint8_t shift = x & 15; - uint8_t needsExtraWord = shift != 0; - - for (plane = 0; plane < 2; ++plane) { - // if we extend the bun area by a word, we only need one write - - // buns will never interfere with a background so they don't need a mask - // they do need the scratch area though - custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12); - custom.bltcon1 = (shift << 12); - - custom.bltadat = 0xffff; - custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; - custom.bltdpt = screenSetup.memoryStart + WORD_ALIGNED_BYTE_POSITION(screenSetup.width, x, y) + screenSetup.nextBitplaneAdvance * plane; - - // custom.bltdpt = screenSetup.memoryStart; - custom.bltafwm = 0xffff; - if (needsExtraWord) { - custom.bltalwm = 0x0000; - } else { - custom.bltalwm = 0xffff; - } - custom.bltbmod = -(needsExtraWord * 2); - custom.bltdmod = (screenSetup.width / 8) - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); - custom.bltsize = (2 + needsExtraWord) + (COOL_BUN_HEIGHT << 6); - - WaitBlit(); - } -} - -void renderBun(int x, int y) { - if (x < -31) return; - if (x > screenSetup.width + 31) return; - if (y < 1) return; - if (y > screenSetup.height - COOL_BUN_HEIGHT - 1) return; - - if (x < 0) { - bun_offLeftSide(-x, y); - } else if (x > screenSetup.width - COOL_BUN_WIDTH) { - bun_offRightSide(x - (screenSetup.width - COOL_BUN_WIDTH), y); - } else { - bun_anywhere(x, y); - } -} +#define offsetof(s, m) &((struct s *)0)->m +uint16_t custom_color = (uint16_t)offsetof(Custom, color); int main(void) { uint16_t *copperlist, *currentCopperlist; int i, x, y, plane, result; int blitShiftRight, memoryXOffset, blitWidth; - int bunPosition = -31; - - color_t colors[16]; - - unsigned char *currentCoolBunArea, *currentCoolBun; - - coolbunArea = AllocMem(COOL_BUN_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); - currentCoolBun = coolbun; - - scratchArea = AllocMem(SCRATCH_AREA_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR); + color_t colors[8]; colors[0] = 0x09b8; colors[1] = 0x0000; colors[2] = 0x0fff; colors[3] = 0x000f; - prepareScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 4); - allocateScreenMemory(&screenSetup); - - currentCoolBunArea = coolbunArea; - - for (plane = 0; plane < COOL_BUN_PLANES; ++plane) { - for (y = 0; y < COOL_BUN_HEIGHT; ++y) { - for (x = 0; x < COOL_BUN_WIDTH_BYTES; ++x) { - *(currentCoolBunArea++) = *(currentCoolBun++); - } - } - } + setupScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 3); + setupInitialCurrentScreen(&screenSetup, ¤tScreen); + teardownScreen(&screenSetup); + return 0; // blitter copy the first bitplane row down to the second @@ -200,11 +62,38 @@ int main(void) { setUpDisplay(&screenSetup); currentCopperlist = addDisplayToCopperlist(copperlist, &screenSetup); - currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); + //currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16); + *(currentCopperlist++) = custom_color; + *(currentCopperlist++) = 0x000; + + *(currentCopperlist++) = custom_color + 2; + *(currentCopperlist++) = 0x000; + + *(currentCopperlist++) = custom_color + 4; + *(currentCopperlist++) = 0xfff; + + *(currentCopperlist++) = custom_color + 6; + *(currentCopperlist++) = 0x00F; + + for (y = 0; y < 256; ++y) { + *(currentCopperlist++) = 1 + (31 << 1) + ((44 + y) << 8); + *(currentCopperlist++) = 0xFFFE; + *(currentCopperlist++) = custom_color; + *(currentCopperlist++) = 0x9b8; + + *(currentCopperlist++) = 1 + (31 + (320 / 4) << 1) + ((44 + y) << 8); + *(currentCopperlist++) = 0xFFFE; + *(currentCopperlist++) = custom_color; + *(currentCopperlist++) = 0x000; + } + endCopperlist(currentCopperlist); for (i = -31; i < screenSetup.width - 1; ++i) { - y = WaitBOF(250); + //y = WaitBOF(250); + WaitTOF(); + + /* for (plane = 0; plane < 2; ++plane) { custom.bltcon0 = 0xc0 + (1 << 8); custom.bltcon1 = 0; @@ -216,18 +105,22 @@ int main(void) { custom.bltsize = 20 + (COOL_BUN_MEMORY_SIZE << 6); WaitBlit(); } + */ - renderBun(i, 45); + renderBun(i, 45, &screenSetup); + } + + for (i = 0; i < 100; ++i) { + WaitTOF(); } giveBackSystem(); - freeScreenMemory(&screenSetup); + freeScreen(&screenSetup); freeCopperlist(copperlist); - FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE); - FreeMem(scratchArea, SCRATCH_AREA_MEMORY_SIZE); + teardownBun(); return 0; } diff --git a/screen.c b/screen.c index c17fa07..379aa98 100644 --- a/screen.c +++ b/screen.c @@ -4,31 +4,69 @@ #include #include -void allocateScreenMemory(struct ScreenSetup *screenSetup) { - char *memory = (char *)AllocMem( +/** + * Includes double buffer space + */ +#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes * 2) + +void setupScreen( + struct ScreenSetup *screenSetup, + uint16_t width, + uint16_t height, + uint8_t bitplanes +) { + unsigned char *memory; + + screenSetup->width = width; + screenSetup->height = height; + screenSetup->bitplanes = bitplanes; + + memory = (unsigned char *)AllocMem( TOTAL_SCREEN_SETUP_SIZE(screenSetup), MEMF_CLEAR | MEMF_CHIP ); screenSetup->memoryStart = memory; + screenSetup->byteWidth = width / 8; + + // memory is not interleaved + screenSetup->nextBitplaneAdvance = screenSetup->byteWidth * height; + screenSetup->nextBufferAdvance = screenSetup->nextBitplaneAdvance * bitplanes; } -void freeScreenMemory(struct ScreenSetup *screenSetup) { +void teardownScreen( + struct ScreenSetup *screenSetup +) { FreeMem( screenSetup->memoryStart, TOTAL_SCREEN_SETUP_SIZE(screenSetup) ); } -void prepareScreen( +void setCurrentScreen( struct ScreenSetup *screenSetup, - uint16_t width, - uint16_t height, - uint8_t bitplanes + struct CurrentScreen *currentScreen, + short int buffer ) { - screenSetup->width = width; - screenSetup->height = height; - screenSetup->bitplanes = bitplanes; - screenSetup->nextBitplaneAdvance = width * height / 8; - screenSetup->currentBuffer = 0; + int plane; + + currentScreen->currentBuffer = buffer; + + for (plane = 0; plane < screenSetup->bitplanes; ++plane) { + currentScreen->planes[plane] = screenSetup->memoryStart + + buffer * screenSetup->nextBufferAdvance + + plane * screenSetup->nextBitplaneAdvance; + } } + +void setupInitialCurrentScreen( + struct ScreenSetup *screenSetup, + struct CurrentScreen *currentScreen +) { + currentScreen->pixelWidth = screenSetup->width; + currentScreen->pixelHeight = screenSetup->height; + currentScreen->byteWidth = screenSetup->byteWidth; + + setCurrentScreen(screenSetup, currentScreen, 0); +} + diff --git a/screen.h b/screen.h index 728d6b9..c7e878d 100644 --- a/screen.h +++ b/screen.h @@ -3,28 +3,41 @@ #include "types.h" -struct ScreenSetup { - short int width; - short int height; - short int bitplanes; - unsigned char *memoryStart; - short int nextBitplaneAdvance; - - short int currentBuffer; -}; - #define SCREEN_WIDTH (320) #define SCREEN_HEIGHT (256) -#define TOTAL_SCREEN_SETUP_SIZE(s) ((s->width / 8) * s->height * s->bitplanes * 2) +struct ScreenSetup { + // human entered + uint16_t width; + uint16_t height; + short int bitplanes; -void allocateScreenMemory(struct ScreenSetup *screenSetup); -void freeScreenMemory(struct ScreenSetup *screenSetup); -void prepareScreen( + // calculated + unsigned char *memoryStart; + uint16_t byteWidth; + uint16_t nextBitplaneAdvance; + uint16_t nextBufferAdvance; +}; + +struct CurrentScreen { + uint16_t currentBuffer; + uint16_t pixelWidth; + uint16_t byteWidth; + uint16_t pixelHeight; + unsigned char *planes[8]; +}; + +void setupScreen( struct ScreenSetup *screenSetup, uint16_t width, uint16_t height, uint8_t bitplanes ); +void teardownScreen(struct ScreenSetup *screenSetup); +void setCurrentScreen( + struct ScreenSetup *screenSetup, + struct CurrentScreen *currentScreen, + short int buffer +); #endif diff --git a/smakefile b/smakefile index cb94cdf..2d770f7 100644 --- a/smakefile +++ b/smakefile @@ -1,3 +1,5 @@ +MAIN_OBJS = main.o images.o system.lib screen.o bun.o + all: main .c.o: @@ -9,8 +11,8 @@ all: main system.lib: system/system.o system/copper.o system/blitter.o sc objectlibrary=system.lib system/system.o system/copper.o system/blitter.o -main: main.o images.o system.lib screen.o - sc link to main main.o system.lib screen.o images.o +main: $(MAIN_OBJS) + sc link to main $(MAIN_OBJS) test: blitter_test.o blitter.o system.o sc link to blitter_test identifierlength=32 math=standard blitter_test.o blitter.o cutest/CuTest.c system.o