diff --git a/src/test/kc/complex/bubbles64/bubbles64.c b/src/test/kc/complex/bubbles64/bubbles64.c deleted file mode 100644 index a71277813..000000000 --- a/src/test/kc/complex/bubbles64/bubbles64.c +++ /dev/null @@ -1,172 +0,0 @@ -// bubbles64 - Q&D C64 port of the bubbles demo from vbcc6502's NES exmaples -// Coded by Lazycow -// Source https://www.lemon64.com/forum/viewtopic.php?t=75283&start=15 - -#include "lazyply.h" - -#define scrPtr (( ubyte*)0xE000) -#define colPtr (( ubyte*)0xD800) -#define vicPtr (( ubyte*)0xD000) -#define chrPtr (( ubyte*)0xF800) -#define onePtr (( ubyte*)0x0001) -#define scr 0xE000 - -enum { - maxSprites=32, - maxSprImages=8, - maxC64Images=256, - sprOff=64 -}; - -ubyte - lcSprMapTab[maxSprImages], - lcSprColTab[maxC64Images]; - -enum { - maxDrawObjects=24, - F=3 -}; -ubyte cmIT[maxSprites+1], - cmSI[maxSprites], cmRX[maxSprites], cmRY[maxSprites], cmRF[maxSprites]; - - -typedef struct { - ubyte - s; // sprite image offset into bubbles[] table - sword - x, y; // coordinates (shifted) - sbyte - vx, vy, // velocity - ax, ay; // accelleration -} DrawObject; - -DrawObject dTab[maxDrawObjects]; - -void Print00(char* p, ubyte v0) { - char c; ubyte v=v0; - c='0'; while (v>=10) { ++c; v-=10; } - *p++=c; - c='0'; while (v>=1) { ++c; v-=1; } - *p++=c; -} - - // sprite support functions -// -ubyte GetSprite() { // get unused or dropped sprite - ubyte t0; for (t0=0;t0=rfDrop) - { cmRF[t0]=0; return t0; } - return 255; -} -void AddSprite(ubyte sn) { // activate prepared sprite into the (i)ndex (t)able - ubyte t0; if (rfDrop==cmRF[sn]) cmRF[sn]=0; else for - (t0=0;t0=128) - { cmRF[sn]=0; cmIT[t0]=sn; return; } -} -void DelSprite(ubyte sn) { // drop sprite, will be removed from IT in IRQ - cmRY[sn]=255; cmRF[sn]=rfDrop; -} - - // -// -int main() { - - register DrawObject* d; - - ubyte - i, - type=0, - stopIt=0, - objects=0, - preset=0; // 1 == preallocate 20 sprites (only for better benchmarking) - // 0 == allocate sprites on the fly (prefered) - uword - oCount=0, - c=0; - - // setup sprite images - lcSprMapTab[0]=sprOff+0; lcSprMapTab[1]=sprOff+1; - lcSprMapTab[2]=sprOff+2; lcSprMapTab[3]=sprOff+3; - lcSprMapTab[4]=sprOff+4; lcSprMapTab[5]=sprOff+5; - // setup sprite colors + flags - lcSprColTab[sprOff+0]=lcSprColTab[sprOff+1]=10|lfMC; - lcSprColTab[sprOff+2]=lcSprColTab[sprOff+3]=5|lfMC; - lcSprColTab[sprOff+4]=lcSprColTab[sprOff+5]=14|lfMC; - - // setup C64 / lazyply - lcVIC17=vicPtr[17]; lcVIC22=vicPtr[22]; lcVIC24=vicPtr[24]; - lcVIC33=6; lcVIC37=1; lcVIC38=11; - for (i=0;is=type; - type+=1; if (type>=6) type=0; - d->x=112<vx=(sbyte)i; d->ax=1; - d->y=24<vy=1<ay=1; - - if (preset && i<20) { - if ((c=GetSprite())<128) { - AddSprite((ubyte)c); - cmSI[i]=cmRX[i]=cmRF[i]=0; - cmRY[i]=i<<4; - } - } - } - - // main loop - c=0; for (;;) { - - // move objects - for (i=0,d=dTab; ivx+=d->ax; - if (d->vx<-32) d->ax=1; else if (d->vx>32) d->ax=-1; - if (d->y>248<vy=-1<y<24<vy=1<x+=d->vx; d->y+=d->vy; - if (cmRF[i]<128) { cmSI[i]=d->s; cmRX[i]=(ubyte)(d->x>>F); cmRY[i]=(ubyte)(d->y>>F); } - } - - // activate new bubble? - c+=1; if (c>=14) { - c=0; - if (0==stopIt && objects1) oCount+=2; else if (oCount>0) oCount-=1; - if (oCount>2 && objects>0) // stop adding objects? - { objects-=1; DelSprite(objects); stopIt=1; oCount=0; } - Print00(scr+(char*)983,objects); - } - return 0; -} diff --git a/src/test/kc/complex/bubbles64/build.sh b/src/test/kc/complex/bubbles64/build.sh deleted file mode 100644 index 578d7083e..000000000 --- a/src/test/kc/complex/bubbles64/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -rm out.raw -rm out.prg - -#cl65 -Oris -Cl -C c64o.cfg -t c64 bubbles64.c lazyply-ca65.s c64irq-ca65.s c64sprcore-ca65.s -o out.raw || exit - -vc +c64 -+ -Dmain=__main -O3 bubbles64.c -llazyply -o out.raw || exit -exomizer sfx sys out.raw sprites.spr@0xD000 -q -p 1 -m 1 -o out.prg || exit - -#x64 -pal out.prg diff --git a/src/test/kc/complex/bubbles64/lazyply.h b/src/test/kc/complex/bubbles64/lazyply.h deleted file mode 100644 index b9706c5df..000000000 --- a/src/test/kc/complex/bubbles64/lazyply.h +++ /dev/null @@ -1,78 +0,0 @@ -// lazyply - experimental C64 sprite multiplying code, 'Lazycow 2015 (prealpha) - -typedef signed char sbyte; -typedef unsigned char ubyte; -typedef signed short sword; -typedef unsigned short uword; - - // - // sprites -// - -enum { - lfMC=16, // sprite is multicolor - lfOL=32 // sprite is build out of 2 overlayed sprites (hires over multicolor) -}; - -extern ubyte lcSprMapTab[]; -extern ubyte lcSprColTab[]; - -enum { rfXMSB=16, rfDrop=254, rfNull=255 }; - -//enum { - //scNull=255, // unallocated (63) - //scDrop=254, // will be removed (62) - //scHide=253, // invisible (61) - //scVoid=128, // no collision detection - //scHold=64, // sprite holds on sprite cmSC[]&scMask, offset cmSU[]/cmSV[] - //scMask=63 -//}; - -extern ubyte - cmIT[], // sprite index table (dim must be maxSprites+1!) - cmSI[], // sprite image - //cmSC[], // sprite control - cmRX[], // raw sprite x coordinates (bits 0..7) - cmRY[], // raw sprite y coordinates (bits 0..7) - cmRF[]; // raw sprite flags: 1 == bit 8 of raw x coordinate - - // - // raster interrupt -// - -ubyte lcVIC17, lcVIC22, lcVIC24, lcVIC33, lcVIC37, lcVIC38; - -#if defined(__CC65__) - -ubyte fastcall lcSync(ubyte flags); -ubyte fastcall lcGetPad(ubyte port); - enum { lfU=1, lfD=2, lfL=4, lfR=8, lfA=16, lfB=32 }; - -#elif defined(__VBCC__) - - // flags: 0 - // result: amount of frames since the last call [0..31], +128 on NTSC -// -ubyte lcSync(__reg("a") ubyte flags); - - // port: 0==query both ports (other values not supported, yet) - // result: set of joypad flags -// -ubyte lcGetPad(__reg("a") ubyte port); - enum { lfU=1, lfD=2, lfL=4, lfR=8, lfA=16, lfB=32 }; - -#elif defined(__KICKC__) - - // flags: 0 - // result: amount of frames since the last call [0..31], +128 on NTSC -// -ubyte lcSync(ubyte flags) { return 0; } - - // port: 0==query both ports (other values not supported, yet) - // result: set of joypad flags -// -ubyte lcGetPad(ubyte port) { return 0; } - -enum { lfU=1, lfD=2, lfL=4, lfR=8, lfA=16, lfB=32 }; - -#endif diff --git a/src/test/kc/complex/bubbles64/liblazyply.a b/src/test/kc/complex/bubbles64/liblazyply.a deleted file mode 100644 index 807c11a05..000000000 Binary files a/src/test/kc/complex/bubbles64/liblazyply.a and /dev/null differ diff --git a/src/test/kc/complex/bubbles64/sprites.png b/src/test/kc/complex/bubbles64/sprites.png deleted file mode 100644 index 61d6a57f6..000000000 Binary files a/src/test/kc/complex/bubbles64/sprites.png and /dev/null differ diff --git a/src/test/kc/complex/bubbles64/sprites.spr b/src/test/kc/complex/bubbles64/sprites.spr deleted file mode 100644 index 60552652b..000000000 Binary files a/src/test/kc/complex/bubbles64/sprites.spr and /dev/null differ diff --git a/src/test/kc/complex/lazynes/balloon.c b/src/test/kc/complex/lazynes/balloon.c deleted file mode 100644 index c45ef9b80..000000000 --- a/src/test/kc/complex/lazynes/balloon.c +++ /dev/null @@ -1,47 +0,0 @@ -// lazyNES balloon demo - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") -#include "lazynes.h" - -int lnMain() { - static const ubyte bgColors[]={2,33}; - static const ubyte sprPal0[]={33}; - static const ubyte balloonData[]={ - 0,0,0,0, // balloon is build out of 6 sprites, 4 bytes define a sprite - 8,0,1,0, // x-offset, y-offset, tile, palette + flags - 0,8,2,0, - 8,8,3,0, - 0,16,4,0, - 8,16,5,0, - 128 // end of list marker (important!) - }; - - sword x=0, y=0; - - // To avoid glitches, always write color palettes immediately after lnSync()! - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,2,bgColors); // set colors, always directly after lnSync()! - lnPush(lnSprPal0,1,sprPal0); // set sprite colors - - while(1) { - ubyte j=lnGetPad(1); // query 1st joypad - if (0==j) { // automatic movement? - x+=1; if (x>=240) x=0; - y+=1; if (y>=240) y=0; - } - if (j&lfL) x-=1; else if (j&lfR) x+=1; // move left/right? - if (j&lfU) y-=1; else if (j&lfD) y+=1; // move up/down? - lnAddSpr(balloonData,x,y); // add meta sprite to display list - lnSync(0); // sync with vblank - } - - return 0; -} diff --git a/src/test/kc/complex/lazynes/bubbles.c b/src/test/kc/complex/lazynes/bubbles.c deleted file mode 100644 index 19528d9e0..000000000 --- a/src/test/kc/complex/lazynes/bubbles.c +++ /dev/null @@ -1,145 +0,0 @@ -// lazyNES bubbles demo - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#include "lazynes.h" - -enum { - F=3, // pseudo floating point shift value - maxDrawObjects=40, - dfAlive=1 -}; - - -typedef struct { - ubyte - f, // flags - s; // sprite image offset into bubbles[] table - sword - x, y; // coordinates (shifted) - sbyte - vx, vy, // velocity - ax, ay; // accelleration -} DrawObject; - - -DrawObject dTab[maxDrawObjects]; - - - // print some text in the static area -// -void Print(uword offset, ubyte value) { - static ubyte b[]={0,0,10,'B','U','B','B','L','E','S',':',0,0,lfEnd}; - b[0]=(offset>>8)|lfHor; b[1]=offset&255; b[11]=b[12]='0'; - while (value>=10) { ++b[11]; value-=10; } - while (value>=1) { ++b[12]; value-=1; } - lnList(b); -} - - - // -// -int lnMain() { - - static const ubyte bgColors[]={45,33,2}; - static const ubyte bubblesPal[]={ 0, 37,22,5, 0, 42,26,10, 0, 33,18,3 }; - static const ubyte bubbles[]={ // x-offset, y-offset, tile, palette+flags - 0,0,7,0, 8,0,9,0, 128, // 16x16, red, offset 0 - 0,0,7,1, 8,0,9,1, 128, // 16x16, green, offset 9 - 0,0,7,2, 8,0,9,2, 128, // 16x16, blue, offest 18 - 0,4,11,0,128, // 8x8, red, offset 27 - 0,4,11,1,128, // 8x8, green, offset 32 - 0,4,11,2,128, // 8x8, blue, offset 37 - }, - bubbleTab[]={0,27,9,32,18,37}; // start offsets in bubbles[] - - ubyte - i, - type=0, - stopIt=0, - objects=0; - uword - hScroll=0, - tics=0; - sbyte - hVel=0, hDir=1; - - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,3,bgColors); // set background colors - lnPush(lnSprPal0,3,&bubblesPal[1]); // set sprite colors - lnPush(lnSprPal1,3,&bubblesPal[5]); - lnPush(lnSprPal2,3,&bubblesPal[9]); - lnPPUCTRL|=32; // Select 8x16 sprites; has to be set after calling lnSync()! - - // draw some backgrounds - { // - static const ubyte g1[]={1}, g2[]={2,3,4,5}, g3[]={6,7,8,9}; - ubyte x; - // draw a line: Sprite #0 will be placed ontop later to trigger the split - i=2; for (x=0;x<32;x+=1) lnPush(lnNameTab0+(i<<5)+x,1,g1); - // draw some diamond shapes - for (i=8;i<=24;i+=4) for (x=0;x<4;x+=1) { - lnPush(lnNameTab0+(i<<5)+12+x*4,4,g2); - lnPush(lnNameTab0+32+(i<<5)+12+x*4,4,g3); - } - } - - // setup bubbles - type=0; - for (i=0;if=dfAlive; - d->s=bubbleTab[type]; - type+=1; if (type>=6) type=0; - d->x=80<vx=i; d->ax=1; - d->y=24<vy=1<ay=1; - } - - while(1) { - DrawObject* d; - - lnScroll(0,0); // reset scrolling offsets of area above split - lnScroll(hScroll>>6,32); // set scrolling offsets of area below split - hVel+=hDir; if (hVel>64 || hVel<-64) hDir=-hDir; - hScroll+=hVel; - - // add 1st sprite (SPR0) at a fixed position on top of background blocks - // mandatory for the SPR0HIT check later with lnSync(lfSplit) - lnAddSpr(&bubbles[bubbleTab[5]],16,16); - lnSpr0Wait=55; // delay the set of scrolling registers a bit - - // move bubbles - for (i=0,d=dTab; if&dfAlive) { - d->vx+=d->ax; - if (d->vx<-32) d->ax=1; else if (d->vx>32) d->ax=-1; - if (d->y>216<vy=-1<y<24<vy=1<x+=d->vx; - d->y+=d->vy; - lnAddSpr(&bubbles[d->s],d->x>>F,d->y>>F); - } - - // activate new bubble? - tics+=1; if (tics>8) { - tics=0; - if (0==stopIt && objects1), then we reduce the amount of - // objects (objects-=1) and everything moves with 60 fps again. - if (i>1 && objects>0) { objects-=1; stopIt=1; } // stop adding objects? - } - - return 0; -} diff --git a/src/test/kc/complex/lazynes/example.chr b/src/test/kc/complex/lazynes/example.chr deleted file mode 100644 index 06c1e76c1..000000000 Binary files a/src/test/kc/complex/lazynes/example.chr and /dev/null differ diff --git a/src/test/kc/complex/lazynes/lazyhello.c b/src/test/kc/complex/lazynes/lazyhello.c deleted file mode 100644 index d9a1e4542..000000000 --- a/src/test/kc/complex/lazynes/lazyhello.c +++ /dev/null @@ -1,23 +0,0 @@ -// lazyNES lazyhello demo - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") - -#include "lazynes.h" - -int lnMain() { - static const ubyte bgColors[] = { 0x02, 0x33 }; - static const char text[]="HELLO LAZYNES!"; - lnSync(lfBlank); // blank screen to enable lnPush() - lnPush(lnBackCol, sizeof(bgColors), bgColors); // set colors, always directly after lnSync() - lnPush(lnNameTab0+32, sizeof(text)-1, text); // draw text in 2nd line - while(1) - lnSync(0); // sync with vblank, unblank screen - return 0; -} diff --git a/src/test/kc/complex/lazynes/lazynes.c b/src/test/kc/complex/lazynes/lazynes.c deleted file mode 100644 index 0562e8933..000000000 --- a/src/test/kc/complex/lazynes/lazynes.c +++ /dev/null @@ -1,286 +0,0 @@ - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC aplha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#include "lazynes.h" -#include - -// Tile Set (in CHR ROM) -#pragma data_seg(Tiles) -export char TILES[] = kickasm(resource "example.chr", resource "sprites.chr") {{ - .import binary "example.chr" - .import binary "sprites.chr" -}}; - -// Interrupt Vectors (in PRG ROM) -#pragma data_seg(Vectors) -export void()* const VECTORS[] = { - // NMI Called when the PPU refreshes the screen (also known as the V-Blank period) - &vblank, - // RESET Called when the NES is reset, including when it is turned on. - &main, - // IRQ Called when a BRK instruction is executed. - 0 -}; - -// RESET Called when the NES is reset, including when it is turned on. -void main() { - // Initialize NES after RESET - initNES(); - // Clear the name table - ppuDataFill(PPU_NAME_TABLE_0, 0, 0x3c0); - // Fill the PPU attribute table - ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40); - // move all sprites off the screen - for(char i=0;i!=0x40;i++) - SPRITE_BUFFER[i].y = 0xff; - // Enable screen rendering and vblank - // Set sprite tileset to upper - enable vblank NMI - PPU->PPUCTRL = 0b10001000; - // Enable sprite and tile rendering - PPU->PPUMASK = 0b00011110; - // Reset scroll - scroll_x = scroll_y = 0; - // Execute lazynes main code - lnMain(); - // Infinite loop - while(1) ; -} - -// Sprite Buffer (in GAME RAM) -// Will be transferred to the PPU via DMA during vblank -#pragma data_seg(GameRam) -struct SpriteData __align(0x100) SPRITE_BUFFER[0x40]; - -// Data (in PRG ROM) -#pragma data_seg(Data) - -// Index of the next SpriteData in SPRITE_BUFFER to write to in lnAddSpr() -volatile char add_sprite_idx; - -// Counts the vblanks between syncs -volatile char vblank_count; - -// The current mode set by lnSync. -// lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls -// lfSplit = 2 activates split mode, NMI waits for SPR0HIT and sets registers -volatile char sync_mode; - -// Signal when vblank occurs. The NMI sets this to zero. To wait for a vblank set this no non-zero and wait for it to become zero. -volatile char vblank_signal; - -// Scroll x-position -volatile char scroll_x; -// Scroll y-position -volatile char scroll_y; - -// Update list with data to be moved to VRAM during blank -// The data is moved by when lnSync() is called -// - The format of the update list is an array of unsigned bytes. -// - There can be 3 different commands in the update list: -// a) addressHi, addressLo, value -// b) addressHi|lfHor, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// c) addressHi|lfVer, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// - Multiple commands can be queued in one list, -// but there can only be one activated updatelist at a time. -// - The end of the list is marked by lfEnd! (important!) -// - It's the same format that's used in set_vram_update() of Shiru's neslib -// See https://nesdoug.com/2017/04/13/my-neslib-notes/ -char * volatile vram_update_list; - -// NMI Called when the PPU refreshes the screen (also known as the V-Blank period) -__interrupt(hardware_clobber) void vblank() { - // Transfer any queued data to the PPU - lnListTransfer(); - // DMA transfer the entire sprite buffer to the PPU - ppuSpriteBufferDmaTransfer(SPRITE_BUFFER); - // Set scroll - PPU->PPUSCROLL = scroll_x; - PPU->PPUSCROLL = scroll_y; - // count vblanks - vblank_count++; - // send vblank signal - vblank_signal = 0; -} - - // Wait for next vblank - // flags: 0, lfBlank or lfSplit (see below) - // result: Amount of frames since last sync [0..31], 128 is added on NTSC -// lfBlank = 0, disables blank mode (if set), wait for vblank -// lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls -// lfSplit = 2 activates split mode, NMI waits for SPR0HIT and sets registers -ubyte lnSync(ubyte flags) { - // Is video output enabled (lfBlank==0) - if(!(flags&lfBlank)) { - // Move remaining sprites off the screen - for(char i=add_sprite_idx;i!=0x40;i++) - SPRITE_BUFFER[i].y = 0xff; - // Reset add sprite index - add_sprite_idx = 0; - // Enable video output (if it was disabled) - if(sync_mode&lfBlank) { - // Set sprite tileset to upper - enable vblank NMI - PPU->PPUCTRL = 0b10001000; - // Enable sprite and tile rendering - PPU->PPUMASK = 0b00011110; - } - } - - // Wait for V-Blank signal from the NMI (if vblank is currently enabled) - if(!(sync_mode&lfBlank)) { - vblank_signal = 0xff; - while(vblank_signal) ; - } - - // Disable video output if lfBlank set - if(flags&lfBlank) { - // lfBlank = 1, activates blank mode, blanks screen and allows lnPush() calls - // Disable vertical blank interrupt - PPU->PPUCTRL = 0; - // Disable sprite rendering - PPU->PPUMASK = 0; - } - - // Update the mode - sync_mode = flags; - - // TODO: Handle lfSplit = 2 : activates split mode, NMI waits for SPR0HIT and sets registers - - // Return number of vblank since last sync - char res = vblank_count; - vblank_count = 0; - return res; -} - - // Write data into nametables, palettes, CHRRAM, etc. - // (System must be in blank mode!) - // o: Destination address offset in vram - // a: Amount of bytes that should be written - // p: Pointer to data -// -void lnPush(uword o, ubyte a, void* s) { - ppuDataTransfer(o, s, a); -} - - // Plan a write of data into nametables, palettes, CHRRAM, etc. - // The data will be written next time lnSync() is called. - // (Screen has to be visible, doesn't work in blank mode!) - // updateList: Pointer to update list -// -// remarks: -// - The format of the update list is an array of unsigned bytes. -// - There can be 3 different commands in the update list: -// a) addressHi, addressLo, value -// b) addressHi|lfHor, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// c) addressHi|lfVer, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// - Multiple commands can be queued in one list, -// but there can only be one activated updatelist at a time. -// - The end of the list is marked by lfEnd! (important!) -// - It's the same format that's used in set_vram_update() of Shiru's neslib -// See https://nesdoug.com/2017/04/13/my-neslib-notes/ -void lnList(void* update_list) { - vram_update_list = update_list; -} - -// Execute any planned transfer of data into nametables, palettes, CHRRAM, etc. by lnList() -void lnListTransfer() { - if(vram_update_list) { - // Index into the update list (assumes no more than 256 bytes) - char idx = 0; - for(;;) { - char addrHi = vram_update_list[idx++]; - // Have we reached the end of the lsit - if(addrHi==0xff) break; - if(addrHi&lfHor) { - // The write is horizontal - char addrLo = vram_update_list[idx++]; - char* ppuAddr = (char*)(uword){ addrHi&0x3f, addrLo }; - char size = vram_update_list[idx++]; - ppuDataTransfer(ppuAddr, vram_update_list+idx, size); - idx += size; - } else if(addrHi&lfVer) { - // The write is vertical - char addrLo = vram_update_list[idx++]; - char* ppuAddr = (char*)(uword){ addrHi&0x3f, addrLo }; - char size = vram_update_list[idx++]; - // Set vertical mode bit in PPUCTRL - PPU->PPUCTRL = 0b10001100; - ppuDataTransfer(ppuAddr, vram_update_list+idx, size); - // restore PPUCTRL - PPU->PPUCTRL = 0b10001000; - idx += size; - } else { - // The write is single-byte - char addrLo = vram_update_list[idx++]; - char* ppuAddr = (char*)(uword){ addrHi, addrLo }; - char value = vram_update_list[idx++]; - ppuDataSet(ppuAddr, value); - } - } - // Set update list to zero - vram_update_list = 0; - } -} - - - - // Scroll background - // x: New horizotnal scrolling offset in pixels, allowed range: [0..511] - // y: New vertical scrolling offset in pixels, allowed range: [0..479] -// -// remarks: -// - If a SPR0HIT based splitscreen is used, the 1st call of lnScroll() sets -// the scrolling offsets of the area above the split and the 2nd call of -// lnScroll() sets the scrolling offsets of the area below the split. -void lnScroll(uword x, uword y) { - scroll_x = =6) SPRITE_BUFFER[add_sprite_idx].tile = 6; - ptr+=4; - add_sprite_idx++; - } - return add_sprite_idx*4; -} - - // Query joypad state - // port: Joypad port (1 or 2) - // result: Set of joypad flags (see below) -// -ubyte lnGetPad(ubyte port) { - return readJoy1(); -} - - // - // advanced usage -// - -// TODO: __zp volatile ubyte -// TODO: lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT -// TODO: lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI) -// TODO: lnPPUMASK; // current value of PPUMASK register (will be written in NMI) - // - // remark: The lazyNES NMI will write the PPUCTRL and PPUMASK registers, - // so don't write PPUCTRL and PPUMASK directly - use these two - // variables insead. Their values will be written in the next NMI. - // Also, don't use these variables before the 1st call of lnSync()! diff --git a/src/test/kc/complex/lazynes/lazynes.h b/src/test/kc/complex/lazynes/lazynes.h deleted file mode 100644 index ef1f7a61c..000000000 --- a/src/test/kc/complex/lazynes/lazynes.h +++ /dev/null @@ -1,107 +0,0 @@ - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC aplha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -typedef signed char sbyte; -typedef unsigned char ubyte; -typedef signed short sword; -typedef unsigned short uword; - -// RESET Called when the NES is reset, including when it is turned on. -void main(); -// NMI Called when the PPU refreshes the screen (also known as the V-Blank period) -__interrupt(hardware_clobber) void vblank(); - - // Wait for next vblank - // flags: 0, lfBlank or lfSplit (see below) - // result: Amount of frames since last sync [0..31], 128 is added on NTSC -// -ubyte lnSync(ubyte flags); - enum { - lfBlank = 1, // activates blank mode, blanks screen and allows lnPush() calls - lfSplit = 2 // activates split mode, NMI waits for SPR0HIT and sets registers - }; - - - // Write data into nametables, palettes, CHRRAM, etc. - // (System must be in blank mode!) - // o: Destination address offset in vram - // a: Amount of bytes that should be written - // p: Pointer to data -// -void lnPush(uword o, ubyte a, void* s); - - - // Write data into nametables, palettes, CHRRAM, etc. - // (Screen has to be visible, doesn't work in blank mode!) - // updateList: Pointer to update list -// -// remarks: -// - The format of the update list is an array of unsigned bytes. -// - There can be 3 different commands in the update list: -// a) addressHi, addressLo, value -// b) addressHi|lfHor, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// c) addressHi|lfVer, addressLo, amountOfBytes, byte1, byte2, byte3, ... -// - Multiple commands can be queued in one list, -// but there can only be one activated updatelist at a time. -// - The end of the list is marked by lfEnd! (important!) -// - It's the same format that's used in set_vram_update() of Shiru's neslib -// See https://nesdoug.com/2017/04/13/my-neslib-notes/ -void lnList(void* update_list); - -// Constants used to control VRAM updates in the list passed to lnList() -enum { lfHor=64, lfVer=128, lfEnd=255 }; - -// Common offsets for lnPush() and lnList() -const uword lnNameTab0=0x2000, lnNameTab1=0x2400, lnNameTab2=0x2800, lnNameTab3=0x2C00, - lnAttrTab0=0x23C0, lnAttrTab1=0x27C0, lnAttrTab2=0x2BC0, lnAttrTab3=0x2FC0, - lnBackCol=0x3F00, - lnChrPal0=0x3F01, lnChrPal1=0x3F05, lnChrPal2=0x3F09, lnChrPal3=0x3F0D, - lnSprPal0=0x3F11, lnSprPal1=0x3F15, lnSprPal2=0x3F19, lnSprPal3=0x3F1D; - - // Scroll background - // x: New horizotnal scrolling offset in pixels, allowed range: [0..511] - // y: New vertical scrolling offset in pixels, allowed range: [0..479] -// remarks: -// - If a SPR0HIT based splitscreen is used, the 1st call of lnScroll() sets -// the scrolling offsets of the area above the split and the 2nd call of -// lnScroll() sets the scrolling offsets of the area below the split. -void lnScroll(uword x, uword y); - - // Add meta-sprite to display list - // p: Pointer to metasprite data - // x,y: Sprite coordinates - // result: New position offset in OAM after the meta sprite has been added -// -ubyte lnAddSpr(void* p, sword x, sword y); - // - // remarks: - // - The format for the metasprite data is an array of unsigned bytes. - // - Four bytes per sprite: x-offset, y-offset, tile, attributes - // - The end of the list is marked by the value 128! (important!) - // - It's the same format that's used in oam_meta_spr() from Shiru's neslib - - - // Query joypad state - // port: Joypad port (1 or 2) - // result: Set of joypad flags (see below) -// -ubyte lnGetPad(ubyte port); -enum { lfU=8, lfD=4, lfL=2, lfR=1, lfA=128, lfB=64, lfStart=16, lfSelect=32 }; - - // - // advanced usage -// - -// TODO: extern __zp volatile ubyte -// TODO: lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT -// TODO: lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI) -// TODO: lnPPUMASK; // current value of PPUMASK register (will be written in NMI) - // - // remark: The lazyNES NMI will write the PPUCTRL and PPUMASK registers, - // so don't write PPUCTRL and PPUMASK directly - use these two - // variables insead. Their values will be written in the next NMI. - // Also, don't use these variables before the 1st call of lnSync()! diff --git a/src/test/kc/complex/lazynes/list.c b/src/test/kc/complex/lazynes/list.c deleted file mode 100644 index bb1c10299..000000000 --- a/src/test/kc/complex/lazynes/list.c +++ /dev/null @@ -1,54 +0,0 @@ -// lazyNES lnlist demo - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") -#include "lazynes.h" - -#pragma data_seg(GameRam) -ubyte list[64]; -#pragma data_seg(Data) - -void lnMain() { - // Set-up an update list in the lnList() format - uword offset1 = lnNameTab0+96+4; - uword offset2 = lnNameTab0+96+2; - uword offset3 = lnNameTab0+160+2; - list[0]=(ubyte)(offset1>>8)|lfHor; // PPU address hi - horizontal - list[1]=(ubyte)offset1; // PPU address lo - list[2]=3; // Size - list[3] = 'R'; // Data - list[4] = 'X'; // Data - list[5] = '0'; // Data - list[6]=(ubyte)(offset2>>8); // PPU address hi - single - list[7]=(ubyte)offset2; // PPU address lo - list[8]='X'; // Size - list[9]=(ubyte)(offset3>>8)|lfVer; // PPU address hi - vertical - list[10]=(ubyte)offset3; // PPU address lo - list[11]=3; // Size - list[12] = 'R'; // Data - list[13] = 'X'; // Data - list[14] = '0'; // Data - list[15] = lfEnd; // End transfer - - static const ubyte bgColors[]={45,33,2}; - static const char text[]="HELLO LAZYNES!"; - - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,3,bgColors); // set background colors - lnPush(lnNameTab0+32,14,text); // draw text in 2nd line - - for (;;) { - // Update the list with dynamic values - list[5] = ((list[5]+1)&7)+'0'; - list[8] = ((list[8]+1)&7)+'0'; - list[14] = ((list[14]+1)&7)+'0'; - lnList(list); // Send the list - lnSync(0); // sync with vblank - } - -} diff --git a/src/test/kc/complex/lazynes/print.c b/src/test/kc/complex/lazynes/print.c deleted file mode 100644 index dbdfee0ce..000000000 --- a/src/test/kc/complex/lazynes/print.c +++ /dev/null @@ -1,55 +0,0 @@ -// lazyNES print demo (using lnlist) - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") -#include "lazynes.h" - -// A string in RAM -#pragma data_seg(GameRam) -ubyte b[14]; - -// A string in ROM -#pragma data_seg(Data) -ubyte b_init[]={0,0,10,'B','U','B','B','L','E','S',':',0,0,lfEnd}; - - // print some text in the static area using lnList -void Print(uword offset, ubyte value) { - b[0]=(ubyte)(offset>>8)|lfHor; b[1]=(ubyte)offset; b[11]=b[12]='0'; - while (value>=10) { ++b[11]; value-=10; } - while (value>=1) { ++b[12]; value-=1; } - lnList(b); -} - -int lnMain() { - static const ubyte bgColors[]={45,33,2}; - ubyte objects=17; - uword tics=0; - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,3,bgColors); // set background colors - - // Copy string from ROM to RAM - for(char i=0;i8) { - tics=0; - objects = (objects+1)&0x3f; - } - // display a number - Print(lnNameTab0+64,objects+1); - lnSync(0); // sync with vblank - } - return 0; -} diff --git a/src/test/kc/complex/lazynes/scroll.c b/src/test/kc/complex/lazynes/scroll.c deleted file mode 100644 index c66ba3a3b..000000000 --- a/src/test/kc/complex/lazynes/scroll.c +++ /dev/null @@ -1,39 +0,0 @@ -// lazyNES scroll demo - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") -#include "lazynes.h" - -int lnMain() { - static const ubyte bgColors[]={45,33,2}; - ubyte i; - uword hScroll=0; - sbyte hVel=0, hDir=1; - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,3,bgColors); // set background colors - // draw some backgrounds - { // - static const ubyte g1[]={1}, g2[]={2,3,4,5}, g3[]={6,7,8,9}; - ubyte x; - // draw a line - i=2; for (x=0;x<32;x+=1) lnPush(lnNameTab0+((uword)i<<5)+x,1,g1); - // draw some diamond shapes - for (i=8;i<=24;i+=4) for (x=0;x<4;x+=1) { - lnPush(lnNameTab0+((uword)i<<5)+12+x*4,4,g2); - lnPush(lnNameTab0+32+((uword)i<<5)+12+x*4,4,g3); - } - } - for(;;) { - lnScroll(hScroll>>6,0); // set scrolling offsets - hVel+=hDir; if (hVel>64 || hVel<-64) hDir=-hDir; - hScroll+=hVel; - lnSync(0); - } - return 0; -} diff --git a/src/test/kc/complex/lazynes/spr0hit.c b/src/test/kc/complex/lazynes/spr0hit.c deleted file mode 100644 index b9450ab99..000000000 --- a/src/test/kc/complex/lazynes/spr0hit.c +++ /dev/null @@ -1,68 +0,0 @@ -// lazyNES spite 0 hit demo. Demonstrates sprite 0 raster NMI with different scroll values - // lazyNES - As lazy as possible NES hardware support library for vbcc6502 - // (happily cooperates with Shiru's famitone2 replay code) -// V1.0, 'Lazycow 2020 - -// Ported to KickC 2020 by Jesper Gravgaard -// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip - -#pragma target(nes) -#pragma emulator("java -jar c:/c64/Nintaco/Nintaco.jar") -#include "lazynes.h" - - -int lnMain() { - - static const ubyte bgColors[]={45,33,2}; - static const ubyte bubblesPal[]={ 0, 37,22,5, 0, 42,26,10, 0, 33,18,3 }; - static const ubyte bubbles[]={ // x-offset, y-offset, tile, palette+flags - 0,0,7,0, 8,0,9,0, 128, // 16x16, red, offset 0 - 0,0,7,1, 8,0,9,1, 128, // 16x16, green, offset 9 - 0,0,7,2, 8,0,9,2, 128, // 16x16, blue, offest 18 - 0,4,11,0,128, // 8x8, red, offset 27 - 0,4,11,1,128, // 8x8, green, offset 32 - 0,4,10,2,128, // 8x8, blue, offset 37 - }, - bubbleTab[]={0,27,9,32,18,37}; // start offsets in bubbles[] - - static const ubyte bubble0[] = { 0,4,10,2,128 }; // x-offset, y-offset, tile, palette+flags - - ubyte i; - uword hScroll=0; - sbyte hVel=0, hDir=1; - - lnSync(lfBlank); // blank screen to enable lnPush() usage - lnPush(lnBackCol,3,bgColors); // set background colors - lnPush(lnSprPal0,3,&bubblesPal[1]); // set sprite colors - lnPush(lnSprPal1,3,&bubblesPal[5]); - lnPush(lnSprPal2,3,&bubblesPal[9]); - //TODO: lnPPUCTRL|=32; // Select 8x16 sprites; has to be set after calling lnSync()! - - { - static const ubyte g1[]={1}, g2[]={2,3,4,5}, g3[]={6,7,8,9}; - ubyte x; - // draw a line - i=2; for (x=0;x<32;x+=1) lnPush(lnNameTab0+((uword)i<<5)+x,1,g1); - // draw some diamond shapes - for (i=8;i<=24;i+=4) for (x=0;x<4;x+=1) { - lnPush(lnNameTab0+((uword)i<<5)+12+x*4,4,g2); - lnPush(lnNameTab0+32+((uword)i<<5)+12+x*4,4,g3); - } - } - - while(1) { - lnScroll(0,0); // reset scrolling offsets of area above split - //lnScroll(hScroll>>6,32); // set scrolling offsets of area below split - hVel+=hDir; if (hVel>64 || hVel<-64) hDir=-hDir; - hScroll+=hVel; - - // add 1st sprite (SPR0) at a fixed position on top of background blocks - // mandatory for the SPR0HIT check later with lnSync(lfSplit) - lnAddSpr(&bubbles[bubbleTab[5]],16,16); - //TODO: lnSpr0Wait=55; // delay the set of scrolling registers a bit - - lnSync(lfSplit); // sync with vblank, activate SPR0HIT splitscreen - } - - return 0; -} diff --git a/src/test/kc/complex/lazynes/sprites.chr b/src/test/kc/complex/lazynes/sprites.chr deleted file mode 100644 index 1a97ed881..000000000 Binary files a/src/test/kc/complex/lazynes/sprites.chr and /dev/null differ diff --git a/src/test/kc/complex/medusa/medusa.c b/src/test/kc/complex/medusa/medusa.c deleted file mode 100644 index 34f42bd3e..000000000 --- a/src/test/kc/complex/medusa/medusa.c +++ /dev/null @@ -1,27 +0,0 @@ -// Display MEDUSA PETSCII by Buzz_clik -// https://csdb.dk/release/?id=178673 - -#include -#include - -char MEDUSA_SCREEN[1000] = kickasm(resource "medusas.prg" ) {{ - .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE) - .fill fileScreen.getSize(), fileScreen.get(i) -}}; - - -char MEDUSA_COLORS[] = kickasm(resource "medusac.prg" ) {{ - .var fileCols = LoadBinary("medusac.prg", BF_C64FILE) - .fill fileCols.getSize(), fileCols.get(i) -}}; - -byte* SCREEN = 0x0400; - -void main() { - *BG_COLOR = BLACK; - memcpy(SCREEN, MEDUSA_SCREEN, 1000); - memcpy(COLS, MEDUSA_COLORS, 1000); - while(true) { - (*(SCREEN+999)) ^= 0x0e; - } -} diff --git a/src/test/kc/complex/medusa/medusac.prg b/src/test/kc/complex/medusa/medusac.prg deleted file mode 100644 index a8f3d37fc..000000000 Binary files a/src/test/kc/complex/medusa/medusac.prg and /dev/null differ diff --git a/src/test/kc/complex/medusa/medusas.prg b/src/test/kc/complex/medusa/medusas.prg deleted file mode 100644 index 09f933fb2..000000000 Binary files a/src/test/kc/complex/medusa/medusas.prg and /dev/null differ diff --git a/src/test/kc/complex/nes-balls/kickballs-2.c b/src/test/kc/complex/nes-balls/kickballs-2.c deleted file mode 100644 index fe726975f..000000000 --- a/src/test/kc/complex/nes-balls/kickballs-2.c +++ /dev/null @@ -1,161 +0,0 @@ -#pragma target(nes) -//#pragma emulator("java -jar /Applications/Nintaco_bin_2020-05-01/Nintaco.jar") -#include -#include - -#define MAX_BALLS 32 -#define WEIGHT 0x0010 -#define RELEASE_TIMER 0x09 - -#define poke(addr) (*(unsigned byte *)(addr)) - -typedef struct -{ - unsigned short x_position; - unsigned short y_position; - unsigned short x_velocity; - unsigned short y_velocity; -} ball; - -#pragma data_seg(GameRam) -// Moving balls (in GameRAM) -ball balls[64]; - -#pragma data_seg(Data) - - static const unsigned char sine_table[256] = { - 0x40,0x42,0x43,0x45,0x46,0x48,0x49,0x4b,0x4c,0x4e,0x50,0x51,0x53,0x54,0x56,0x57, - 0x58,0x5a,0x5b,0x5d,0x5e,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6a,0x6b,0x6c, - 0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x78,0x79,0x7a,0x7b, - 0x7b,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,0x7c,0x7c, - 0x7b,0x7b,0x7a,0x79,0x78,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,0x6f,0x6e, - 0x6d,0x6c,0x6b,0x6a,0x69,0x67,0x66,0x65,0x64,0x62,0x61,0x60,0x5e,0x5d,0x5b,0x5a, - 0x58,0x57,0x56,0x54,0x53,0x51,0x50,0x4e,0x4c,0x4b,0x49,0x48,0x46,0x45,0x43,0x42, - 0x40,0x3e,0x3d,0x3b,0x3a,0x38,0x37,0x35,0x34,0x32,0x30,0x2f,0x2d,0x2c,0x2a,0x29, - 0x28,0x26,0x25,0x23,0x22,0x20,0x1f,0x1e,0x1c,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14, - 0x13,0x12,0x11,0x10,0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x8,0x7,0x6,0x5, - 0x5,0x4,0x4,0x3,0x3,0x2,0x2,0x2,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x3,0x3,0x4,0x4, - 0x5,0x5,0x6,0x7,0x8,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12, - 0x13,0x14,0x15,0x16,0x17,0x19,0x1a,0x1b,0x1c,0x1e,0x1f,0x20,0x22,0x23,0x25,0x26, - 0x28,0x29,0x2a,0x2c,0x2d,0x2f,0x30,0x32,0x34,0x35,0x37,0x38,0x3a,0x3b,0x3d,0x3e - }; - - static const unsigned char object[5] = { 0, 0, 10, 3, 128 }; - - const unsigned char palette[] = { 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04 }; - - const unsigned char h_bar_tilemap[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; - - volatile unsigned char scroll_y = 0; - volatile unsigned char vblank_hit = 0; - -int main(void) -{ - // Initialize NES after RESET - initNES(); - // Transfer the palette - ppuDataTransfer(PPU_PALETTE, palette, sizeof(palette)); - // Fill the PPU attribute table - ppuDataFill(PPU_NAME_TABLE_0, 0, 32*30); - ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40); - ppuDataTransfer(0x2040, h_bar_tilemap, sizeof(h_bar_tilemap)); - // Enable screen rendering and vblank - enableVideoOutput(); - // Enable vertical blank interrupt, select sprite pattern table 1 - PPU->PPUCTRL = 0b10001000; - - unsigned char i; - unsigned char active_balls = 0; - unsigned char timer = 0; - unsigned char timer_2 = 0; - unsigned char h_bar = 0x80; - unsigned char sprite_idx = 0; - - for (i = 0; i < MAX_BALLS; i++) - { - balls[i].x_velocity = rand() & 0x3FF; - balls[i].y_velocity = rand() & 0x0FF; - } - - while (1) - { - timer_2++; - h_bar = sine_table[timer_2] + 0x60; - scroll_y = h_bar ^ 0xFF; - - if (active_balls < MAX_BALLS) - { - if (timer++ == RELEASE_TIMER) - { - timer = 0; - active_balls++; - balls[active_balls].x_position = 0; - balls[active_balls].y_position = 0; - } - } - - sprite_idx = 0; - for (i = 0; i < active_balls; i++) - { - balls[i].x_position += balls[i].x_velocity; - balls[i].y_position += (balls[i].y_velocity += WEIGHT); - - if ((balls[i].x_position >> 8) < 8) - { - balls[i].x_velocity ^= 0xFFFF; - } - - if (((balls[i].y_position >> 8) >= h_bar) && (balls[i].y_position >> 8) < h_bar + 8) - { - balls[i].y_velocity ^= 0xFFFF; - balls[i].y_position = ((unsigned short)(h_bar - 2) << 8); - } - - SPRITE_BUFFER[sprite_idx].y = (unsigned char) (balls[i].y_position >> 8); - SPRITE_BUFFER[sprite_idx].tile = 0x0a; - SPRITE_BUFFER[sprite_idx].attributes = 3; - SPRITE_BUFFER[sprite_idx].x = (unsigned char) (balls[i].x_position >> 8); - sprite_idx++; - } - - poke(0x2001) = 0x98; - while (!vblank_hit); // wait for vblank - vblank_hit = 0; - poke(0x2001) = 0x18; - } - return 0; -} - -// NMI Called when the PPU refreshes the screen (also known as the V-Blank period) -__interrupt(hardware_clobber) void vblank() { - // Set scroll - PPU->PPUSCROLL = 0; - PPU->PPUSCROLL = scroll_y; - // DMA transfer the entire sprite buffer to the PPU - ppuSpriteBufferDmaTransfer(SPRITE_BUFFER); - vblank_hit++; -} - -// Tile Set (in CHR ROM) -#pragma data_seg(Tiles) -export char TILES[] = kickasm(resource "lazydata.chr") {{ - .import binary "lazydata.chr" -}}; - -// Sprite Buffer (in GAME RAM) -// Will be transferred to the PPU via DMA during vblank -#pragma data_seg(GameRam) -struct SpriteData __align(0x100) SPRITE_BUFFER[0x100]; - -// Interrupt Vectors (in PRG ROM) -#pragma data_seg(Vectors) -export void()* const VECTORS[] = { - // NMI Called when the PPU refreshes the screen (also known as the V-Blank period) - &vblank, - // RESET Called when the NES is reset, including when it is turned on. - &main, - // IRQ Called when a BRK instruction is executed. - 0 -}; \ No newline at end of file diff --git a/src/test/kc/complex/nes-balls/kickballs-3.c b/src/test/kc/complex/nes-balls/kickballs-3.c deleted file mode 100644 index aa0c4da26..000000000 --- a/src/test/kc/complex/nes-balls/kickballs-3.c +++ /dev/null @@ -1,161 +0,0 @@ -#pragma target(nes) -#pragma emulator("java -jar /Applications/Nintaco_bin_2020-05-01/Nintaco.jar") -#include -#include - -#define MAX_BALLS 50 -#define WEIGHT 0x0010 -#define RELEASE_TIMER 0x09 - -#define poke(addr) (*(unsigned byte *)(addr)) - -typedef struct -{ - unsigned short x_position; - unsigned short y_position; - unsigned short x_velocity; - unsigned short y_velocity; -} ball; - -#pragma data_seg(GameRam) -// Moving balls (in GameRAM) -ball balls[64]; - -#pragma data_seg(Data) - - static const unsigned char sine_table[256] = { - 0x40,0x42,0x43,0x45,0x46,0x48,0x49,0x4b,0x4c,0x4e,0x50,0x51,0x53,0x54,0x56,0x57, - 0x58,0x5a,0x5b,0x5d,0x5e,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6a,0x6b,0x6c, - 0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x78,0x79,0x7a,0x7b, - 0x7b,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,0x7c,0x7c, - 0x7b,0x7b,0x7a,0x79,0x78,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,0x6f,0x6e, - 0x6d,0x6c,0x6b,0x6a,0x69,0x67,0x66,0x65,0x64,0x62,0x61,0x60,0x5e,0x5d,0x5b,0x5a, - 0x58,0x57,0x56,0x54,0x53,0x51,0x50,0x4e,0x4c,0x4b,0x49,0x48,0x46,0x45,0x43,0x42, - 0x40,0x3e,0x3d,0x3b,0x3a,0x38,0x37,0x35,0x34,0x32,0x30,0x2f,0x2d,0x2c,0x2a,0x29, - 0x28,0x26,0x25,0x23,0x22,0x20,0x1f,0x1e,0x1c,0x1b,0x1a,0x19,0x17,0x16,0x15,0x14, - 0x13,0x12,0x11,0x10,0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x8,0x7,0x6,0x5, - 0x5,0x4,0x4,0x3,0x3,0x2,0x2,0x2,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x3,0x3,0x4,0x4, - 0x5,0x5,0x6,0x7,0x8,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12, - 0x13,0x14,0x15,0x16,0x17,0x19,0x1a,0x1b,0x1c,0x1e,0x1f,0x20,0x22,0x23,0x25,0x26, - 0x28,0x29,0x2a,0x2c,0x2d,0x2f,0x30,0x32,0x34,0x35,0x37,0x38,0x3a,0x3b,0x3d,0x3e - }; - - static const unsigned char object[5] = { 0, 0, 10, 3, 128 }; - - const unsigned char palette[] = { 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04, 0x34,0x24,0x14,0x04 }; - - const unsigned char h_bar_tilemap[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; - - volatile unsigned char scroll_y = 0; - volatile unsigned char vblank_hit = 0; - -int main(void) -{ - // Initialize NES after RESET - initNES(); - // Transfer the palette - ppuDataTransfer(PPU_PALETTE, palette, sizeof(palette)); - // Fill the PPU attribute table - ppuDataFill(PPU_NAME_TABLE_0, 0, 32*30); - ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40); - ppuDataTransfer(0x2040, h_bar_tilemap, sizeof(h_bar_tilemap)); - // Enable screen rendering and vblank - enableVideoOutput(); - // Enable vertical blank interrupt, select sprite pattern table 1 - PPU->PPUCTRL = 0b10001000; - - unsigned short i; - unsigned short active_balls = 0; - unsigned char timer = 0; - unsigned char timer_2 = 0; - unsigned char h_bar = 0x80; - unsigned char sprite_idx = 0; - - for (i = 0; i < MAX_BALLS; i++) - { - balls[i].x_velocity = rand() & 0x3FF; - balls[i].y_velocity = rand() & 0x0FF; - } - - while (1) - { - timer_2++; - h_bar = sine_table[timer_2] + 0x60; - scroll_y = h_bar ^ 0xFF; - - if (active_balls < MAX_BALLS) - { - if (timer++ == RELEASE_TIMER) - { - timer = 0; - active_balls++; - balls[active_balls].x_position = 0; - balls[active_balls].y_position = 0; - } - } - - sprite_idx = 0; - for (i = 0; i < active_balls; i++) - { - balls[i].x_position += balls[i].x_velocity; - balls[i].y_position += (balls[i].y_velocity += WEIGHT); - - if ((balls[i].x_position >> 8) < 8) - { - balls[i].x_velocity ^= 0xFFFF; - } - - if (((balls[i].y_position >> 8) >= h_bar) && (balls[i].y_position >> 8) < h_bar + 8) - { - balls[i].y_velocity ^= 0xFFFF; - balls[i].y_position = ((unsigned short)(h_bar - 2) << 8); - } - - SPRITE_BUFFER[sprite_idx].y = (unsigned char) (balls[i].y_position >> 8); - SPRITE_BUFFER[sprite_idx].tile = 0x0a; - SPRITE_BUFFER[sprite_idx].attributes = 3; - SPRITE_BUFFER[sprite_idx].x = (unsigned char) (balls[i].x_position >> 8); - sprite_idx++; - } - - poke(0x2001) = 0x98; - while (!vblank_hit); // wait for vblank - vblank_hit = 0; - poke(0x2001) = 0x18; - } - return 0; -} - -// NMI Called when the PPU refreshes the screen (also known as the V-Blank period) -__interrupt(hardware_clobber) void vblank() { - // Set scroll - PPU->PPUSCROLL = 0; - PPU->PPUSCROLL = scroll_y; - // DMA transfer the entire sprite buffer to the PPU - ppuSpriteBufferDmaTransfer(SPRITE_BUFFER); - vblank_hit++; -} - -// Tile Set (in CHR ROM) -#pragma data_seg(Tiles) -export char TILES[] = kickasm(resource "lazydata.chr") {{ - .import binary "lazydata.chr" -}}; - -// Sprite Buffer (in GAME RAM) -// Will be transferred to the PPU via DMA during vblank -#pragma data_seg(GameRam) -struct SpriteData __align(0x100) SPRITE_BUFFER[0x100]; - -// Interrupt Vectors (in PRG ROM) -#pragma data_seg(Vectors) -export void()* const VECTORS[] = { - // NMI Called when the PPU refreshes the screen (also known as the V-Blank period) - &vblank, - // RESET Called when the NES is reset, including when it is turned on. - &main, - // IRQ Called when a BRK instruction is executed. - 0 -}; \ No newline at end of file diff --git a/src/test/kc/complex/nes-balls/lazydata.chr b/src/test/kc/complex/nes-balls/lazydata.chr deleted file mode 100644 index 2d4925915..000000000 Binary files a/src/test/kc/complex/nes-balls/lazydata.chr and /dev/null differ diff --git a/src/test/kc/complex/prebob/grid-bobs.c b/src/test/kc/complex/prebob/grid-bobs.c deleted file mode 100644 index 275685cb0..000000000 --- a/src/test/kc/complex/prebob/grid-bobs.c +++ /dev/null @@ -1,278 +0,0 @@ -// Pre-calculated bobs inside a charset (pre-moved to all x/y-combinations) -#include -#include -#include -#include -#include -#include - -// The prototype BOB (a 3x3 char image with a bob image in the upper 2x2 chars) -// The chars are layout as follows with data in chars 0, 1, 3, 4 initially -// 0 3 6 -// 1 4 7 -// 2 5 8 -const char PROTO_BOB[3*3*8] = kickasm(resource "smiley.png") {{ - .var pic = LoadPicture("smiley.png", List().add($000000, $ffffff)) - .for (var x=0;x<3; x++) - .for (var y=0; y<24; y++) - .byte pic.getSinglecolorByte(x,y) -}}; - -// Sine and Cosine tables -// Angles: $00=0, $80=PI,$100=2*PI -// Sine/Cosine: signed fixed [-$7f,$7f] -signed char __align(0x40) SIN[0x140] = kickasm {{ - .for(var i=0;i<$140;i++) - .byte >round($7fff*sin(i*2*PI/256)) -}}; - -signed char* COS = SIN+$40; // sin(x) = cos(x+PI/2) - -// The BASIC screen -char* const BASIC_SCREEN = 0x0400; -// The BASIC charset -char* const BASIC_CHARSET = 0x1000; -// The BOB screen -char* const BOB_SCREEN = 0x2800; -// The BOB charset -char* const BOB_CHARSET = 0x2000; - -// Tables containing the char to use for a specific cell of a shifted BOB. -// char_id = BOB_TABLES[cell*BOB_SUBTABLE_SIZE + shift_y*BOB_SHIFTS_X + shift_x]; -char BOB_TABLES[9*8*4]; -// The number of different X-shifts -const char BOB_SHIFTS_X = 4; -// The number of different Y-shifts -const char BOB_SHIFTS_Y = 8; -// The size of a sub-table of BOB_TABLES -const char BOB_SUBTABLE_SIZE = BOB_SHIFTS_X*BOB_SHIFTS_Y; - -// The number of BOBs to render -const char NUM_BOBS = 25; - -void main() { - mulf_init(); - prepareBobs(); - renderBobInit(); - vicSelectGfxBank(BOB_SCREEN); - *D018 = toD018(BOB_SCREEN, BOB_CHARSET); - // Clear screen - memset(BOB_SCREEN, 0x00, 1000); - - // Origin point - int origX = 0x0a00; - int origY = 0x0a00; - // Row and column offset vectors - int rowOffsetX = 0x0c00; - int rowOffsetY = 0x0100; - int colOffsetX = 0x0100; - int colOffsetY = 0x1800; - // Render Grid of BOBs - while(true) { - do { } while (*RASTER<$f8); - *BORDER_COLOR = 0xf; - renderBobCleanup(); - int rowX = origX; - int rowY = origY; - for(char col: 0..4) { - int x = rowX; - int y = rowY; - for(char row: 0..4) { - //kickasm {{ .break }} - *BORDER_COLOR = 1; - renderBob(>x, >y); - x += rowOffsetX; - y += rowOffsetY; - *BORDER_COLOR = 2; - } - rowX += colOffsetX; - rowY += colOffsetY; - } - origX += 0x0100; - rowOffsetY += 0x0080; - *BORDER_COLOR = 0; - if(keyboard_key_pressed(KEY_SPACE)) { - break; - } - } - // Wait for space release - while(keyboard_key_pressed(KEY_SPACE)) {} - // Return to BASIC - vicSelectGfxBank(BASIC_SCREEN); - *D018 = toD018(BASIC_SCREEN, BASIC_CHARSET); -} - -// Table used for deleting rendered BOB's. Contains pointers to first char of each BOB. -char* RENDERBOB_CLEANUP[NUM_BOBS]; - -// Pointer to the next clean-up to add -char** renderBobCleanupNext; - -// *40 Table unsigned int MUL40[0x20] = { ((unsigned int)i)*40 }; -unsigned int MUL40[0x20]; - -// Initialize the tables used by renderBob() -void renderBobInit() { - for(char y: 0..0x1f) - MUL40[y] = ((unsigned int)y)*40; - for(char i: 0..NUM_BOBS-1) - RENDERBOB_CLEANUP[i] = BOB_SCREEN; -} - -// Render a single BOB at a given x/y-position -// X-position is 0-151. Each x-position is 2 pixels wide. -// Y-position is 0-183. Each y-position is 1 pixel high. -void renderBob(char xpos, char ypos) { - char x_char_offset = xpos/BOB_SHIFTS_X; - char y_char_offset = ypos/BOB_SHIFTS_Y; - unsigned int y_offset = MUL40[y_char_offset]; - char* screen = BOB_SCREEN+y_offset+x_char_offset; - char bob_table_idx = (ypos&7)*BOB_SHIFTS_X+(xpos&3); - *renderBobCleanupNext++ = screen; - screen[0] = (BOB_TABLES+0*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[40] = (BOB_TABLES+1*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[80] = (BOB_TABLES+2*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[1] = (BOB_TABLES+3*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[41] = (BOB_TABLES+4*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[81] = (BOB_TABLES+5*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[2] = (BOB_TABLES+6*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[42] = (BOB_TABLES+7*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[82] = (BOB_TABLES+8*BOB_SUBTABLE_SIZE)[bob_table_idx]; -} - -// Clean Up the rendered BOB's -void renderBobCleanup() { - for(char i: 0..NUM_BOBS-1) { - char* screen = RENDERBOB_CLEANUP[i]; - screen[0] = 0; - screen[40] = 0; - screen[80] = 0; - screen[1] = 0; - screen[41] = 0; - screen[81] = 0; - screen[2] = 0; - screen[42] = 0; - screen[82] = 0; - } - // Prepare for next clean-up - renderBobCleanupNext = RENDERBOB_CLEANUP; -} - -// Creates the pre-shifted bobs into BOB_CHARSET and populates the BOB_TABLES -// Modifies PROTO_BOB by shifting it around -void prepareBobs() { - progress_init(BASIC_SCREEN); - bob_charset_next_id = 0; - // Ensure that glyph #0 is empty - charsetFindOrAddGlyph(PROTO_BOB+48, BOB_CHARSET); - char bob_table_idx = 0; - for(char shift_y=0;shift_y>1; - // Update carry - carry = new_carry; - // Increment j to iterate over the PROTO_BOB left-to-right, top-to-bottom (0, 24, 48, 1, 25, 49, ...) - if(j>=48) { - j-=47; - } else { - j+=24; - } - } -} - -// Shift PROTO_BOB down one Y pixel -// At the same time restore PROTO_BOB X by shifting 8 pixels left -void protoBobShiftDown() { - for(char i=23;i>0;i--) { - PROTO_BOB[i] = (PROTO_BOB+23)[i]; - (PROTO_BOB+24)[i] = (PROTO_BOB+47)[i]; - (PROTO_BOB+48)[i] = 0x00; - } - PROTO_BOB[0] = 0; - PROTO_BOB[24] = 0; - PROTO_BOB[48] = 0; -} - -// BOB charset ID of the next glyph to be added -char bob_charset_next_id; - -// Looks through a charset to find a glyph if present. If not present it is added. -// Returns the glyph ID -char charsetFindOrAddGlyph(char* glyph, char* charset) { - char* glyph_cursor = charset; - char glyph_id = 0; - while(glyph_id!=bob_charset_next_id) { - char found = 1; - for(char i=0;i<8;i++) { - if(glyph_cursor[i]!=glyph[i]) { - found = 0; - break; - } - } - if(found) return glyph_id; - glyph_id++; - glyph_cursor +=8; - } - // Not found - add it - for(char i=0;i<8;i++) - glyph_cursor[i]=glyph[i]; - bob_charset_next_id++; - return glyph_id; -} - -// Current position of the progress cursor -char* progress_cursor; -// Current index within the progress cursor (0-7) -char progress_idx; - -// Initialize the PETSCII progress bar -void progress_init(char* line) { - progress_cursor = line; - progress_idx = 0; -} - -// Increase PETSCII progress one bit -// Done by increasing the character until the idx is 8 and then moving to the next char -void progress_inc() { - // Progress characters - const char progress_chars[] = { 0x20, 0x65, 0x74, 0x75, 0x61, 0xf6, 0xe7, 0xea, 0xe0 }; - if(++progress_idx==8) { - *progress_cursor = progress_chars[8]; - progress_cursor++; - progress_idx = 0; - } - *progress_cursor = progress_chars[progress_idx]; -} - diff --git a/src/test/kc/complex/prebob/smiley.png b/src/test/kc/complex/prebob/smiley.png deleted file mode 100644 index 78d647509..000000000 Binary files a/src/test/kc/complex/prebob/smiley.png and /dev/null differ diff --git a/src/test/kc/complex/prebob/vogel-bobs.c b/src/test/kc/complex/prebob/vogel-bobs.c deleted file mode 100644 index d2a818c56..000000000 --- a/src/test/kc/complex/prebob/vogel-bobs.c +++ /dev/null @@ -1,284 +0,0 @@ -// Pre-calculated bobs inside a charset (pre-moved to all x/y-combinations) -#include -#include -#include -#include -#include -#include - -// The prototype BOB (a 3x3 char image with a bob image in the upper 2x2 chars) -// The chars are layout as follows with data in chars 0, 1, 3, 4 initially -// 0 3 6 -// 1 4 7 -// 2 5 8 -const char PROTO_BOB[3*3*8] = kickasm(resource "smiley.png") {{ - .var pic = LoadPicture("smiley.png", List().add($000000, $ffffff)) - .for (var x=0;x<3; x++) - .for (var y=0; y<24; y++) - .byte pic.getSinglecolorByte(x,y) -}}; - -// Sine and Cosine tables -// Angles: $00=0, $80=PI,$100=2*PI -// Sine/Cosine: signed fixed [-$7f,$7f] -signed char __align(0x40) SIN[0x140] = kickasm {{ - .for(var i=0;i<$140;i++) - .byte >round($7fff*sin(i*2*PI/256)) -}}; - -signed char* COS = SIN+$40; // sin(x) = cos(x+PI/2) - -// Vogel Sunflower polar coordinates -__align(0x100) const char VOGEL_THETA[] = kickasm {{ - .const PHI = (1+sqrt(5))/2 - .fill 100, round(mod(256*i/(PHI*PHI),256)) -}}; -__align(0x100) const char VOGEL_R[] = kickasm {{ .fill 100, round(sqrt(i)*15) }}; - -// The BASIC screen -char* const SCREEN_BASIC = 0x0400; -// The BASIC charset -char* const CHARSET_BASIC = 0x1000; -// The BOB screen -char* const BOB_SCREEN = 0x2800; -// The BOB charset -char* const BOB_CHARSET = 0x2000; - -// Tables containing the char to use for a specific cell of a shifted BOB. -// char_id = BOB_TABLES[cell*BOB_SUBTABLE_SIZE + shift_y*BOB_SHIFTS_X + shift_x]; -char BOB_TABLES[9*8*4]; -// The number of different X-shifts -const char BOB_SHIFTS_X = 4; -// The number of different Y-shifts -const char BOB_SHIFTS_Y = 8; -// The size of a sub-table of BOB_TABLES -const char BOB_SUBTABLE_SIZE = BOB_SHIFTS_X*BOB_SHIFTS_Y; - -// The number of BOBs to render -const char NUM_BOBS = 20; - -void main() { - mulf_init(); - prepareBobs(); - renderBobInit(); - vicSelectGfxBank(BOB_SCREEN); - *D018 = toD018(BOB_SCREEN, BOB_CHARSET); - /* - // Clear screen - memset(BOB_SCREEN, 0x00, 1000); - // Display a BOB grid - for(char x: 0..7) - for(char y: 0..3) - renderBob(x*12+y, y*24+x); - // Wait for space - while(!keyboard_key_pressed(KEY_SPACE)) {} - while(keyboard_key_pressed(KEY_SPACE)) {} - */ - // Clear screen - memset(BOB_SCREEN, 0x00, 1000); - // Render Rotated BOBs - char angle = 0; - while(true) { - do { } while (*RASTER<$f8); - *BORDER_COLOR = 0xf; - renderBobCleanup(); - signed char r = 30; - char a = angle; - for(char i: 0..NUM_BOBS-1) { - //kickasm {{ .break }} - *BORDER_COLOR = 1; - int x = mulf8s(r, COS[a]) + 75*0x100; - int y = mulf8s(r, SIN[a])*2 + 90*0x100; - *BORDER_COLOR = 2; - a += 98; - r += 3; - renderBob(>x, >y); - } - angle += 3; - *BORDER_COLOR = 0; - if(keyboard_key_pressed(KEY_SPACE)) { - break; - } - } - // Wait for space release - while(keyboard_key_pressed(KEY_SPACE)) {} - // Return to BASIC - vicSelectGfxBank(SCREEN_BASIC); - *D018 = toD018(SCREEN_BASIC, CHARSET_BASIC); -} - -// Table used for deleting rendered BOB's. Contains pointers to first char of each BOB. -char* RENDERBOB_CLEANUP[NUM_BOBS]; - -// Pointer to the next clean-up to add -char** renderBobCleanupNext; - -// *40 Table unsigned int[0x20] MUL40 = { ((unsigned int)i)*40 }; -unsigned int MUL40[0x20]; - -// Initialize the tables used by renderBob() -void renderBobInit() { - for(char y: 0..0x1f) - MUL40[y] = ((unsigned int)y)*40; - for(char i: 0..NUM_BOBS-1) - RENDERBOB_CLEANUP[i] = BOB_SCREEN; -} - -// Render a single BOB at a given x/y-position -// X-position is 0-151. Each x-position is 2 pixels wide. -// Y-position is 0-183. Each y-position is 1 pixel high. -void renderBob(char xpos, char ypos) { - char x_char_offset = xpos/BOB_SHIFTS_X; - char y_char_offset = ypos/BOB_SHIFTS_Y; - unsigned int y_offset = MUL40[y_char_offset]; - char* screen = BOB_SCREEN+y_offset+x_char_offset; - char bob_table_idx = (ypos&7)*BOB_SHIFTS_X+(xpos&3); - *renderBobCleanupNext++ = screen; - screen[0] = (BOB_TABLES+0*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[40] = (BOB_TABLES+1*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[80] = (BOB_TABLES+2*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[1] = (BOB_TABLES+3*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[41] = (BOB_TABLES+4*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[81] = (BOB_TABLES+5*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[2] = (BOB_TABLES+6*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[42] = (BOB_TABLES+7*BOB_SUBTABLE_SIZE)[bob_table_idx]; - screen[82] = (BOB_TABLES+8*BOB_SUBTABLE_SIZE)[bob_table_idx]; -} - -// Clean Up the rendered BOB's -void renderBobCleanup() { - for(char i: 0..NUM_BOBS-1) { - char* screen = RENDERBOB_CLEANUP[i]; - screen[0] = 0; - screen[40] = 0; - screen[80] = 0; - screen[1] = 0; - screen[41] = 0; - screen[81] = 0; - screen[2] = 0; - screen[42] = 0; - screen[82] = 0; - } - // Prepare for next clean-up - renderBobCleanupNext = RENDERBOB_CLEANUP; -} - -// Creates the pre-shifted bobs into BOB_CHARSET and populates the BOB_TABLES -// Modifies PROTO_BOB by shifting it around -void prepareBobs() { - progress_init(SCREEN_BASIC); - bob_charset_next_id = 0; - // Ensure that glyph #0 is empty - bobCharsetFindOrAddGlyph(PROTO_BOB+48); - char bob_table_idx = 0; - for(char shift_y=0;shift_y>1; - // Update carry - carry = new_carry; - // Increment j to iterate over the PROTO_BOB left-to-right, top-to-bottom (0, 24, 48, 1, 25, 49, ...) - if(j>=48) { - j-=47; - } else { - j+=24; - } - } -} - -// Shift PROTO_BOB down one Y pixel -// At the same time restore PROTO_BOB X by shifting 8 pixels left -void shiftProtoBobDown() { - for(char i=23;i>0;i--) { - PROTO_BOB[i] = (PROTO_BOB+23)[i]; - (PROTO_BOB+24)[i] = (PROTO_BOB+47)[i]; - (PROTO_BOB+48)[i] = 0x00; - } - PROTO_BOB[0] = 0; - PROTO_BOB[24] = 0; - PROTO_BOB[48] = 0; -} - -// BOB charset ID of the next glyph to be added -char bob_charset_next_id; - -// Looks through BOB_CHARSET to find the passed bob glyph if present. -// If not present it is added -// Returns the glyph ID -char bobCharsetFindOrAddGlyph(char* bob_glyph) { - char* glyph_cursor = BOB_CHARSET; - char glyph_id = 0; - while(glyph_id!=bob_charset_next_id) { - char found = 1; - for(char i=0;i<8;i++) { - if(glyph_cursor[i]!=bob_glyph[i]) { - found = 0; - break; - } - } - if(found) return glyph_id; - glyph_id++; - glyph_cursor +=8; - } - // Not found - add it - for(char i=0;i<8;i++) - glyph_cursor[i]=bob_glyph[i]; - bob_charset_next_id++; - return glyph_id; -} - -// Current position of the progress cursor -char* progress_cursor; -// Current index within the progress cursor (0-7) -char progress_idx; - -// Initialize the PETSCII progress bar -void progress_init(char* line) { - progress_cursor = line; - progress_idx = 0; -} - -// Increase PETSCII progress one bit -// Done by increasing the character until the idx is 8 and then moving to the next char -void progress_inc() { - // Progress characters - const char progress_chars[] = { 0x20, 0x65, 0x74, 0x75, 0x61, 0xf6, 0xe7, 0xea, 0xe0 }; - if(++progress_idx==8) { - *progress_cursor = progress_chars[8]; - progress_cursor++; - progress_idx = 0; - } - *progress_cursor = progress_chars[progress_idx]; -} - diff --git a/src/test/kc/complex/prebob/vogel-sprites.c b/src/test/kc/complex/prebob/vogel-sprites.c deleted file mode 100644 index 34f0762ac..000000000 --- a/src/test/kc/complex/prebob/vogel-sprites.c +++ /dev/null @@ -1,105 +0,0 @@ -// Same animation using a multiplexer -#include -#include -#include -#include -#include - -// The BOB sprite -__align(0x1000) char SPRITE[] = kickasm(resource "smiley.png") {{ - .var pic = LoadPicture("smiley.png", List().add($000000, $ffffff)) - .for (var y=0; y<21; y++) - .for (var x=0;x<3; x++) - .byte pic.getSinglecolorByte(x,y) -}}; - -// Sine and Cosine tables -// Angles: $00=0, $80=PI,$100=2*PI -// Sine/Cosine: signed fixed [-$7f,$7f] -__align(0x40) signed char SIN[0x140] = kickasm {{ - .for(var i=0;i<$140;i++) - .byte >round($7fff*sin(i*2*PI/256)) -}}; - -signed char* COS = SIN+0x40; // sin(x) = cos(x+PI/2) - -// The BASIC screen -char* const SCREEN = 0x0400; - -// The number of BOBs to render -const char NUM_BOBS = 16; - -void main() { - asm { sei } - init(); - loop(); - exit(); - asm { cli } -} - -// Initialize the program -void init() { - *D011 = VICII_DEN | VICII_RSEL | 3; - // Initialize the multiplexer - plexInit(SCREEN); - // Set the sprite pointers & initial positions - for(char i: 0..PLEX_COUNT-1) { - PLEX_PTR[i] = (char)(SPRITE/0x40); - PLEX_XPOS[i] = 24+i*5; - PLEX_YPOS[i] = 50+i*8; - } - // Enable & initialize sprites - *SPRITES_ENABLE = 0xff; - for(char i: 0..7) { - SPRITES_COLOR[i] = GREEN; - } - mulf_init(); - // Clear screen - memset(SCREEN, ' ', 1000); -} - -// Exit the program -void exit() { - // Wait for space release - while(keyboard_key_pressed(KEY_SPACE)) {} -} - -// The main loop -void loop() { - // Render Rotated BOBs - char angle = 0; - while(true) { - do { } while (*RASTER<0xd8); - *BORDER_COLOR = 0xf; - signed char r = 30; - char a = angle; - for(char i: 0..NUM_BOBS-1) { - //kickasm {{ .break }} - *BORDER_COLOR = 6; - int x = mulf8s(r, COS[a])*2 + 125*0x100; - PLEX_XPOS[i] = >x; - int y = mulf8s(r, SIN[a])*2 + 125*0x100; - PLEX_YPOS[i] = >y; - a += 98; - r += 3; - } - *BORDER_COLOR = 3; - plexSort(); - angle += 3; - *BORDER_COLOR = BLACK; - // Sort the sprites by y-position - while((*D011&VICII_RST8)!=0) {} - // Show the sprites - for( char i: 0..PLEX_COUNT-1) { - *BORDER_COLOR = BLACK; - char rasterY = plexFreeNextYpos(); - while(*RASTER