From e54bf0f282a70ec160df67c42914d812fdb99407 Mon Sep 17 00:00:00 2001 From: Paul Robson Date: Thu, 16 May 2024 06:49:07 +0100 Subject: [PATCH] New tilemap demo --- basic/images/graphics.gfx | Bin 4608 -> 4608 bytes basic/images/tile_16.png | Bin 2701 -> 2729 bytes basic/storage/graphics.gfx | Bin 4608 -> 4608 bytes basic/test.bsc | 92 ++++++++++++++------- documents/release/basic.md | 13 +++ examples/basic/examples/tilebenchmark.bas | Bin 0 -> 1271 bytes examples/basic/examples/tilebenchmark.bsc | 47 +++++++++++ examples/basic/examples/tiles.bas | Bin 1271 -> 1927 bytes examples/basic/examples/tiles.bsc | 93 +++++++++++++--------- 9 files changed, 180 insertions(+), 65 deletions(-) create mode 100644 examples/basic/examples/tilebenchmark.bas create mode 100644 examples/basic/examples/tilebenchmark.bsc diff --git a/basic/images/graphics.gfx b/basic/images/graphics.gfx index 83b64dd9ed17ce3af81da8cebe933e7c53547647..668e641a1b7034815c8c99aca6a375c762f5cf68 100644 GIT binary patch delta 145 ncmZorX;4|fQeO@Qf`a0L6deBTN0}|16BW08ZNm^Z)<= diff --git a/basic/images/tile_16.png b/basic/images/tile_16.png index c9dfebd4036a092894c3924ebe8818a8829fe1ee..b5f7fa44c12f752320e08aca07bf96595ae26741 100644 GIT binary patch literal 2729 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 diff --git a/basic/storage/graphics.gfx b/basic/storage/graphics.gfx index 83b64dd9ed17ce3af81da8cebe933e7c53547647..668e641a1b7034815c8c99aca6a375c762f5cf68 100644 GIT binary patch delta 145 ncmZorX;4|fQeO@Qf`a0L6deBTN0}|16BW08ZNm^Z)<= diff --git a/basic/test.bsc b/basic/test.bsc index 3fcdd0b58..7a10dc086 100644 --- a/basic/test.bsc +++ b/basic/test.bsc @@ -1,34 +1,68 @@ ' -' New Blitter +' *** Tile map demonstration program *** ' -f = alloc(16) -t = alloc(16) +cls:sprite clear:gload "graphics.gfx" +rect 0,0 solid ink 4 to 319,239 -cls:sprite clear:cursor 0,20 -dat = alloc(256) -for i = 0 to 255:poke dat+i,(i >> 4)+5:next - -call setup(f,0,dat,64,64,1) -call setup(t,$80,0,8,320,8) -t1 = time() -for x = 0 to 39 - for y = 0 to 23 - while peek($FF00):wend - doke t,x*8+y*320*8 - poke $FF04,0 - doke $FF05,f - doke $FF07,t - poke $FF01,3 - poke $FF00,12 - next -next -print time()-t1 +call CreateTileMap() +xPos = 0:yPos = 0 +call DrawTileMap(xPos,yPos) +repeat + if event(t1,2) + fire = joypad(dx,dy) + xPos = max(xPos+dx,0):yPos = max(yPos+dy,0) + call DrawTileMap(xPos,yPos) + endif +until false end +' +' This draws the tilemap offset by x,y +' +proc DrawTileMap(xo,yo) + ink 7:print chr$(20);"At offset ";xo;" ";yo;" " + ' Sets the tilemap data to draw with and the offset in pixels. + tilemap map,xo,yo + ' Draw the tilemap in a window + tiledraw 10,20 to 240,210 + ' Draw a small second one using the same data + tiledraw 250,20 to 310,80 +endproc +' +' This creates a single tile map in memory. See api.pdf +' +proc CreateTileMap() + width = 30:height = 20 + ' an array of memory with a small header : type, width and height. + map = alloc(width*height+3) + poke map,1: poke map+1, width: poke map+2, height + ' Fill the map with $F2 which is a solid green block. + for i = 0 to width*height-1:poke map+3+i,$F2:next + ' Draw a frame around the whole screen + call DrawRect(0,0,width,height,$F3,-1) + ' Draw some things on the tilemap + call DrawRect(3,2,8,5,6,0) + call DrawRect(17,6,10,7,6,3) + call DrawRect(5,10,10,7,6,5) +endproc -proc setup(a,p,addr,size,offset,count) - doke a+0,addr - poke a+2,p - doke a+4,size:doke a+6,0 - doke a+8,offset:doke a+10,0 - doke a+12,count:doke a+14,0 -endproc \ No newline at end of file +' +' Draw a rectangle on the tile map at (x,y) size (w,h) with frame edgeColour +' and fill with fillColour (if >= 0) +' +proc DrawRect(x,y,w,h,edgeColour,fillColour) + if fillColour >= 0 + for i = x to x+w-1 + for j = y to y+h-1 + call set(i,j,fillColour) + next + next + endif + for i = x to x+w-1:call set(i,y,edgeColour):call set(i,y+h-1,edgeColour):next + for i = y to y+h-1:call set(x,i,edgeColour):call set(x+w-1,i,edgeColour):next +endproc +' +' Set tilemap tile to x,y +' +proc set(x,y,t) + poke map+x+3+y*width,t +endproc diff --git a/documents/release/basic.md b/documents/release/basic.md index 018434bf4..d94b281c2 100644 --- a/documents/release/basic.md +++ b/documents/release/basic.md @@ -5,6 +5,19 @@ fontsize: 12pt # Basic Reference +This is a reference for Neo6502's BASIC interpreter. + +There are many example programs available which are designed to show and explain the features of the Neo6502 +and its hardware and firmware in the examples directory of the release. + +For example if.bsc/if.bas so the options available for the 'if' statement, graphics.bsc/graphics.bas show the +drawing commands, and joypad.bsc/joypad.bas show how to access the joypad (or the keyboard backup if none is +plugged in) + +Many of these are helpful for understanding specific API functions, as many BASIC commands are just wrappers +for those functions. + + ## Binary Operators +------------+----------+--------------------------------------------+ diff --git a/examples/basic/examples/tilebenchmark.bas b/examples/basic/examples/tilebenchmark.bas new file mode 100644 index 0000000000000000000000000000000000000000..f28b1cf09f4dee5d89abe6cfe8d907a487635f73 GIT binary patch literal 1271 zcmeHFy-yQi9R3~gwAk7-qNyKA^R|Qtf#AvDK%(6BTH*MP9GWngG^IkDQfhlm7#vz+ zWY7T|9E>&&48+02j{$6Aey0t=<2XOkh+l&)3{DPC4#xMrEB*&=UYh%TJ@51U-sjq| z57?tS;k6UqIN^g6K04u569f9fFulSXKmkDR9$iCN6#z6>Mp%Q_0m51|MgEC;3r`VNd~rxN7ZCH zL1toEq9yWLGBZW8x!I{)Y^D?WISLBQgT82f(~G8lujrwJ>~u1o@0_|kXX=X>ya~^s zMG&i!Xnum0P}C6hC8=s>@~l}w*KOE_4hxUnr&>+%SUOEcbIFXxREJ{O);4T<0H5_G zS-+(iN;Q%< t2 + rCount = rCount + 1 + next +next +t = (time()-t1)/100/rCount +print 1/t +end + +proc BuildTileMap() + width = 22:height = 14 + map = alloc(width*height+3) + poke map,1 + poke map+1, width + poke map+2, height + for i = 0 to width*height-1:poke map+3+i,$F2:next + for i = 0 to width-1:call set(i,0,0):call set(i,height-1,0):next + for i = 0 to height-1:call set(0,i,1):call set(width-1,i,1):next + for i = 2 to 6:call set(i,i,i):call set(i+4,i+1,i):next + for i = 1 to 9:call set(2+i,height-3,i+$F0):next + call set(0,1,$F3):call set(0,2,$F1) +endproc + +proc PrintTileMap() + for y = 0 to height-1 + for x = 0 to width-1 + c = peek(map+3+y*width+x):if c <> 7:print c;:else:print " ";:endif + next + print + next +endproc + +proc set(x,y,t) + poke map+x+3+y*width,t +endproc diff --git a/examples/basic/examples/tiles.bas b/examples/basic/examples/tiles.bas index f28b1cf09f4dee5d89abe6cfe8d907a487635f73..fab1d329b7b476554ac82abdfde0bbfcb62a85a7 100644 GIT binary patch literal 1927 zcmd^9-A^1<6hE_Z5!ymGprNJ}FNlOMH=7boAl2+LyL<(N!kW^Tnt`3&nYg>N&J2ZZ zOk9i_t3H%y`aojqLrI7aCQzd&#@sd7;$?SADwS4!(8TiKgYm(>n8tYSorO^U1^3~8 z{N|kBIp=rIUC+b7e|dMi;clDmcH7}@f+@b`bLHD7z%A36o*s&;pqAyaqNrq z_x5eMDSdaCLn72@M2;@H=(fA9`-FWY+#8XH2Zvw0>E3(#2M67|YsN%UzOl%z`<8I~ zpDo@P6zS7xDCU}4TU#rldQv4RB|~Cr%1B$bso1)aCK=O6m`aME3H8pP$I;gzf1&Ve zK3B+pm^*~uGMYYV`4jOOTJs+K6lB5t`}w)>TKF|48?^i)Y{OFyt^5d}GY~9*90=0N zj}aV#P6o0=y`REo^x)U9{5HJAx*b}z4v+}E39m57I`r|I-0w1U5(I({_rDA>fh=BV z<AIXZI;1#hc>rM`MKW0wRfY=M(#k!-gVf3*^Qh;HsJh5&O->5pT!_2 z##H-3`j}!X#5P1=GOgPhQPMGyKq;_}^6E2c((==)pp?G?b4*00PYxjAu`nk5K)z_N zAW=GIOw+2Uv@^h>YjTFkqxAS0bZ8R}3b9g3GD$3T(!g*=S|wAKo=ylROG&AO=S2@| z(vEx%3BqStXoPxA=?m(86%{z~7E(PU6q__v#a1m0$_a2hxNu@dFq0IHiJA42F;yi> zM)zl8aq7K*1m*K6A#eE=3FZT53a}7}(%w&yHKD>2bP+q7 zQQPrbtR$MI>Iu#EQ{RdNbAd}R-vA2)hv(=w(iW-~D&R^&4Cck5o52F@DqzHp9v!9N zJ?H%vJ!tGXPNs2WHG(sNl^IDrMiQo~rpZLon0(n!$q&+(uoMWci7@ppInLY?o0ZMN zDsB4(nHx)D$MJEX0H!fj>g}{5zV-=%F>!8d`aVNyt7vHFlhoBl$ICj^CM zpuer5z!o-Zf4^zXKipep-K>vASPvihnsN_9C-E}CdT~V!YN|ODLBNF~_@<6|u$xVu zB0U-K6mtWmTupV-RzxHB1ro|AHfhE;(1MLVr;_IBcCE!#%PmihB~;l+8dD~1=|aK= zKFDz{t&o(T+|Q(0kCW%0BY_s`4P*GnUhu5I3e+;FV{n~;!{8Q!yAG`w_bkKR_8_gE z@NluAb`5F?T(1w&>Leof0#LUGbp#wld}p!3`=~$M6VBe8XO(*2;mZe}tF+_Ne<%ti zYm9lz*}DiXfvnPwMb~97hOojkF-FP7&1M(DP|IA?udt}PYbZf2KKH#p67eqZrHj9j lO*HZSh;`q0>z2wK`si;SKA~75&QV&&48+02j{$6Aey0t=<2XOkh+l&)3{DPC4#xMrEB*&=UYh%TJ@51U-sjq| z57?tS;k6UqIN^g6K04u569f9fFulSXKmkDR9$iCN6#z6>Mp%Q_0m51|MgEC;3r`VNd~rxN7ZCH zL1toEq9yWLGBZW8x!I{)Y^D?WISLBQgT82f(~G8lujrwJ>~u1o@0_|kXX=X>ya~^s zMG&i!Xnum0P}C6hC8=s>@~l}w*KOE_4hxUnr&>+%SUOEcbIFXxREJ{O);4T<0H5_G zS-+(iN;Q%< t2 - rCount = rCount + 1 - next -next -t = (time()-t1)/100/rCount -print 1/t -end +' *** Tile map demonstration program *** +' +cls:sprite clear:gload "graphics.gfx" +rect 0,0 solid ink 4 to 319,239 -proc BuildTileMap() - width = 22:height = 14 +call CreateTileMap() +xPos = 0:yPos = 0 +call DrawTileMap(xPos,yPos) +repeat + if event(t1,2) + fire = joypad(dx,dy) + xPos = max(xPos+dx,0):yPos = max(yPos+dy,0) + call DrawTileMap(xPos,yPos) + endif +until false +end +' +' This draws the tilemap offset by x,y +' +proc DrawTileMap(xo,yo) + ink 7:print chr$(20);"At offset ";xo;" ";yo;" " + ' Sets the tilemap data to draw with and the offset in pixels. + tilemap map,xo,yo + ' Draw the tilemap in a window + tiledraw 10,20 to 240,210 + ' Draw a small second one using the same data + tiledraw 250,20 to 310,80 +endproc +' +' This creates a single tile map in memory. See api.pdf +' +proc CreateTileMap() + width = 30:height = 20 + ' an array of memory with a small header : type, width and height. map = alloc(width*height+3) - poke map,1 - poke map+1, width - poke map+2, height + poke map,1: poke map+1, width: poke map+2, height + ' Fill the map with $F2 which is a solid green block. for i = 0 to width*height-1:poke map+3+i,$F2:next - for i = 0 to width-1:call set(i,0,0):call set(i,height-1,0):next - for i = 0 to height-1:call set(0,i,1):call set(width-1,i,1):next - for i = 2 to 6:call set(i,i,i):call set(i+4,i+1,i):next - for i = 1 to 9:call set(2+i,height-3,i+$F0):next - call set(0,1,$F3):call set(0,2,$F1) + ' Draw a frame around the whole screen + call DrawRect(0,0,width,height,$F3,-1) + ' Draw some things on the tilemap + call DrawRect(3,2,8,5,6,0) + call DrawRect(17,6,10,7,6,3) + call DrawRect(5,10,10,7,6,5) endproc -proc PrintTileMap() - for y = 0 to height-1 - for x = 0 to width-1 - c = peek(map+3+y*width+x):if c <> 7:print c;:else:print " ";:endif +' +' Draw a rectangle on the tile map at (x,y) size (w,h) with frame edgeColour +' and fill with fillColour (if >= 0) +' +proc DrawRect(x,y,w,h,edgeColour,fillColour) + if fillColour >= 0 + for i = x to x+w-1 + for j = y to y+h-1 + call set(i,j,fillColour) + next next - print - next + endif + for i = x to x+w-1:call set(i,y,edgeColour):call set(i,y+h-1,edgeColour):next + for i = y to y+h-1:call set(x,i,edgeColour):call set(x+w-1,i,edgeColour):next endproc - +' +' Set tilemap tile to x,y +' proc set(x,y,t) poke map+x+3+y*width,t endproc