From f90edac57de93bbf4ff7d31cf7eda8345a3d530e Mon Sep 17 00:00:00 2001 From: blondie7575 Date: Tue, 16 Jan 2018 12:56:53 -0800 Subject: [PATCH] Optimized span rendering moved to $E1 --- .gitignore | 1 + GSCats.xcodeproj/project.pbxproj | 6 + Makefile | 17 +- ParseMapFile.py | 64 +++++++ collision.s | 2 +- equates.s | 20 ++ gamemanager.s | 14 +- gscats.2mg | Bin 819264 -> 819264 bytes gscats.s | 5 +- linkerConfig | 44 +++++ loader.s | 47 +++++ macros.s | 9 + tables.s | 12 -- terrain.s | 287 ----------------------------- terrain_e1.s | 304 +++++++++++++++++++++++++++++++ 15 files changed, 523 insertions(+), 309 deletions(-) create mode 100755 ParseMapFile.py create mode 100644 linkerConfig create mode 100644 terrain_e1.s diff --git a/.gitignore b/.gitignore index 57794ad..0829c50 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /gscats.lst /GSCats.xcodeproj/xcuserdata/qd.xcuserdatad/xcdebugger /loader.lst +/terrain_e1.lst diff --git a/GSCats.xcodeproj/project.pbxproj b/GSCats.xcodeproj/project.pbxproj index 099a370..875780a 100644 --- a/GSCats.xcodeproj/project.pbxproj +++ b/GSCats.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 700F21E01F4A3A5500D7007D /* GenerateTrigTables.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateTrigTables.py; sourceTree = ""; }; 700FFAFB1F40F3BF00A442DE /* font.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = font.s; sourceTree = ""; }; 7059502B1F37A0BE00BBE90F /* GenerateVRAMTable.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateVRAMTable.py; sourceTree = ""; }; + 705AAFA920040B0D001BB0ED /* terrain_e1.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = terrain_e1.s; sourceTree = ""; }; 706DF1641F2D39F700AA6680 /* loader.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = loader.s; sourceTree = ""; }; 706DF1651F2D4A8100AA6680 /* terrain.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = terrain.s; sourceTree = ""; }; 7088096D1F2ECE8D00D4C950 /* GenerateRenderSpans.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateRenderSpans.py; sourceTree = ""; }; @@ -20,6 +21,8 @@ 7099E3841F41022100182A82 /* gameobject.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameobject.s; sourceTree = ""; }; 7099E3851F4107B100182A82 /* GenerateVRAMYOffset.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = GenerateVRAMYOffset.py; sourceTree = ""; }; 70A80FB01F43D7F200BD34C9 /* gamemanager.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamemanager.s; sourceTree = ""; }; + 70BDCBC92006AD5F00CB51F1 /* linkerConfig */ = {isa = PBXFileReference; lastKnownFileType = text; path = linkerConfig; sourceTree = ""; }; + 70BDCBCA200A99F200CB51F1 /* ParseMapFile.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = ParseMapFile.py; sourceTree = ""; }; 70C073091F5BAA3E009844A9 /* collision.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = collision.s; sourceTree = ""; }; 70E266E31F6F262D005AC7E4 /* circleTable.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = circleTable.s; sourceTree = ""; }; 70E554C41F807ADB00F3C871 /* spritebank.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = spritebank.s; sourceTree = ""; }; @@ -45,6 +48,7 @@ 706DF1641F2D39F700AA6680 /* loader.s */, 700FFAFB1F40F3BF00A442DE /* font.s */, 706DF1651F2D4A8100AA6680 /* terrain.s */, + 705AAFA920040B0D001BB0ED /* terrain_e1.s */, 70C073091F5BAA3E009844A9 /* collision.s */, 70F086A01F4230CB002446C3 /* utility.s */, 700C39C51F2E5CA800C24F9C /* tables.s */, @@ -55,12 +59,14 @@ 70E554C41F807ADB00F3C871 /* spritebank.s */, 70E9D8611F2BD95400555C19 /* gscats.s */, 70E9D8631F2BD95400555C19 /* Makefile */, + 70BDCBC92006AD5F00CB51F1 /* linkerConfig */, 70FE79D21F8814A600E0095C /* MerlinToCA65.sh */, 7088096D1F2ECE8D00D4C950 /* GenerateRenderSpans.py */, 7059502B1F37A0BE00BBE90F /* GenerateVRAMTable.py */, 7099E3851F4107B100182A82 /* GenerateVRAMYOffset.py */, 700F21E01F4A3A5500D7007D /* GenerateTrigTables.py */, 709175C01F60D263008FAFAB /* GenerateCircles.py */, + 70BDCBCA200A99F200CB51F1 /* ParseMapFile.py */, ); sourceTree = ""; }; diff --git a/Makefile b/Makefile index 2b99679..fdc23eb 100644 --- a/Makefile +++ b/Makefile @@ -18,18 +18,21 @@ MRSPRITE=../MrSprite/mrsprite CHROMA=00ff00 PALETTE=a4dffb 008800 886611 cc9933 eebb44 dd6666 ff99aa 000000 0e7db1 ffff00 ffff00 ffff00 ffff00 ffff00 ffff00 ffffff SPRITES=SpriteBank +REMOTESYMBOLS=-Wl $(shell ./ParseMapFile.py *.map) -all: $(PGM) loader +all: terrain_e1 $(PGM) loader $(PGM): - @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh --cpu 65816 --start-addr 0000 -l$(PGM).lst $(PGM).s + @echo $(REMOTESYMBOLS) + @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh -C linkerConfig --cpu 65816 --start-addr 0000 -l$(PGM).lst $(REMOTESYMBOLS) $(PGM).s java -jar $(AC) -d $(PGM).2mg CODEBANK java -jar $(AC) -p $(PGM).2mg CODEBANK BIN 0x0000 < $(PGM) java -jar $(AC) -d $(PGM).2mg $(SPRITES)00 java -jar $(AC) -p $(PGM).2mg $(SPRITES)00 BIN 0x0000 < $(SPRITES)00.bin rm -f $(PGM) rm -f $(PGM).o + rm -f terrain_e1.map osascript V2Make.scpt $(PROJECT_DIR) $(PGM) loader: @@ -39,11 +42,21 @@ loader: rm -f loader rm -f loader.o +terrain_e1: + @PATH=$(PATH):/usr/local/bin; $(CL65) -t apple2enh -C linkerConfig --cpu 65816 --start-addr $(ADDR) -l -vm -m terrain_e1.map terrain_e1.s + java -jar $(AC) -d $(PGM).2mg CODEBANKE1 + java -jar $(AC) -p $(PGM).2mg CODEBANKE1 BIN 0x800 < terrain_e1 + rm -f terrain_e1 + rm -f terrain_e1.o + clean: rm -f $(PGM) rm -f $(PGM).o rm -f loader rm -f loader.o + rm -f terrain_e1.o + rm -f terrain_e1.map + rm -f terrain_e1 .PHONY: art art: diff --git a/ParseMapFile.py b/ParseMapFile.py new file mode 100755 index 0000000..b9ed593 --- /dev/null +++ b/ParseMapFile.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +# Outputs a list of exported symbols found in an ld65 link map file +# suitable for passing as a commandline option to define those +# same symbols in a cl65 compile/assemble operation. This allows +# sharing symbols between code banks without having to actually +# link them together. Sort of a low-budget DLL mechanism. :) + +import sys + + +def parseInputFile(filename,bank): + + inputFile = open(filename) + contents = inputFile.readlines() + output = "" + + # Find exported symbols + lineNum = 0 + for line in contents: + if line.find("Exports list") != -1: + break + lineNum+=1 + + # Found the exports table, so look for our symbol names + first=1 + for line in contents[lineNum+1:]: + if line.startswith("_") or line.startswith("-"): + continue + if line.startswith("Imports") or len(line)<2: + break + + if first!=1: + output += "," + first = 0 + + columns = line.split() + if len(columns) > 3: + output += ("-D,%s=0x%s,-D,%s=0x%s" % (columns[0],bank+columns[1][2:],columns[3],bank+columns[4][2:])) + else: + output += ("-D,%s=0x%s" % (columns[0],bank+columns[1][2:])) + + inputFile.close() + return output + + +def main(argv): + commandline = "" + first=1 + + for file in argv: + + if first!=1: + commandline += "," + first = 0 + + bank = file[-6:-4] # Assumes filename_XX.map + commandline += parseInputFile(file,bank) + + print (commandline) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/collision.s b/collision.s index 5ae9c71..91c0249 100644 --- a/collision.s +++ b/collision.s @@ -50,7 +50,7 @@ intersectRectTerrain: ; Check Y bottom intersectRectTerrainBottomLoop: - lda terrainData,y + lda terrainDataFar,y cmp rectParams+6 bpl intersectRectTerrainYep dey diff --git a/equates.s b/equates.s index a6e9dc1..8f7b9ae 100644 --- a/equates.s +++ b/equates.s @@ -28,6 +28,26 @@ SCRATCHL2 = $67 ; Second 16-bit scratch PARAM24 = $67 ; 24-bit param (This is almost certainly messing up AppleSoft, but meh) CACHEPTR = $6A ; General purpose cache pointer (This is almost certainly messing up AppleSoft, but meh) CACHEDATA = $6C ; General purpose cache data (This is almost certainly messing up AppleSoft, but meh) +leftScreenEdge = $6E ; Reserved for leftScreenEdge (This is almost certainly messing up AppleSoft, but meh) STACKPTR = $70 ; Cache for stack pointer in fast graphics SHADOWREGISTER = $72 ; Cache for shadow register in fast graphics STACKREGISTER = $73 ; Cache for stack register in fast graphics + + +; Terrain constants +TERRAINWIDTH = 640 ; In pixels +MAXTERRAINHEIGHT = 100 ; In pixels +COMPILEDTERRAINROW = TERRAINWIDTH/4+3 ; In words, +2 to make room for clipping jump at end of row +VISIBLETERRAINWIDTH = TERRAINWIDTH/4 ; In words- width minus jump return padding +VISIBLETERRAINWINDOW = 80 ; In words +MAXSPANSPERROW = 15 +SPANROWBYTES = MAXSPANSPERROW*2 + 2 ; In bytes + + +; Terrain data, stored as height values 2 pixels wide (bytes) +terrainDataFar = $02f500 +terrainData = $f500 +; .repeat TERRAINWIDTH/2 +; .word 0 +; .endrepeat +terrainDataEnd = terrainData + (TERRAINWIDTH/2 * 2) diff --git a/gamemanager.s b/gamemanager.s index 64b3dc9..acb0f02 100644 --- a/gamemanager.s +++ b/gamemanager.s @@ -27,11 +27,13 @@ beginGameplay: jsr colorFill ; Generate, compile, and clip terrain + stz leftScreenEdge jsr generateTerrain - jsr compileTerrainSpans + + jsl compileTerrainSpans ; jsr compileTerrain ; jsr clipTerrain - jsr renderTerrainSpans + jsl renderTerrainSpans ; Create players lda #56 @@ -58,8 +60,8 @@ gameplayLoop: ; lda terrainDirty ; beq gameplayLoopKbd BORDER_COLOR #$3 - jsr unrenderTerrainSpans - jsr renderTerrainSpans + jsl unrenderTerrainSpans + jsl renderTerrainSpans stz terrainDirty BORDER_COLOR #$1 @@ -334,7 +336,7 @@ paused: ; c) Byte-distance from left edge of logical terrain to right edge of visible screen minus game object width in words mapScrollPos: .word 0 -leftScreenEdge: - .word 0 +;leftScreenEdge = $6E ; Moved to zero page for speed and cross-bank convenience +; .word 0 rightScreenEdge: .word 160-GAMEOBJECTWIDTH/4-1 diff --git a/gscats.2mg b/gscats.2mg index e9d254fd889b287f4750b05b56b1d393379c6af3..52f8229626c8ae8d25ba798e6ad6632d51293b10 100644 GIT binary patch delta 3663 zcmZ{m4^&gv9mnr|f$#!(5>2a#%D4%FPk#mQd(o|INDE0@iM}ql>jnH+y8i`(6UI$0p~# z`+L9p{r&DQ_ulu(>+;U-^3HBqlZ4r-wMp%sbd1F8JUv1e5K9dP-SP0!pDz4a{(bY8 z6o?{1NP7+?BWuc-OfeXgbN^2sP(=B&RM{z{Lu=Br>tH#2&lb;XY;-$8oxMG5bQAP_QPy<5TWo%t4Kk<>A@UsS zybk`J6KwR6xNh;yx#&lmKv64E?|5K|CxPQ30$d;h@hZDY?3 ziP9^q^e2DaE^M3kA&Xu>NOMW)k}xu$XA#0!b6s(y=RWlC{H05C6F+_8ckc6Nb$q!C zCu8k`b1U`~g!~(Hc(P|SWm@o8$j1iQRQhQMKce%Q;imEU`?oh1)ghlYh>&UPa^2}N zLwZk-uOwhzC?b%Qct3YuEb~1PF#jH*!E>hP*F14rYe;YG>4_`C%XQv?0DE`z@Ye_p zk-)}%ge%oc-i?#rn-pAN^nbG(KX7~B+kcIodFS2t-v8ilXFvXAU~uTdrx!nK zTc-U2cg%Yp@6s_3P4K@_g;#q-Tew7LDl#Bxwk`anPRg@|V>)TBjW}(E?iB}>tx$xO7I)%Q!D;cbPAm9XCczMQFsQ4gZk%%m-5&Dl5gDgQhjw z2pSPB5${!hW;M1ZZ{=Zf|JiDMZwiRb$2S?PR!Sy+o*z&2tdJWxNFz0HH0^K$2Ude~ zxQUaRIJuE?4mWdBGZ#i9{mq;~Us>7L#2GHbS*UOaFhSS=V>JDr1Dfc6_AW36MQNeYdl&c|v1mGUrXsOs zfw2e1W0`Qf2tIKa)ufLPM+Yk*-XA@R=P*l*9bJ#&y-D@+-oQ-KhkyU*eB1ogZ*cv* zUaajna17679f*Ebl6BkpV#&4q!m`KGX}M~dW8G-&u#Q>_vO2tf!S`yI z#k{}s1fIgJE+acQ>+9^G6|sZsl@|HTa*F`F>*FI!QOq7N zJ1;FoK&?sM>EMe^37AbqOA*~$eZUMui|El?&%5RA{L~18Vw|*{Z`#h2{rcK1yt{Tg z@4XDiOe*EwWUC&El6-usugp~R5|VcF!BL34izhBUEi_k8m0Ni?#5a=NY4J2q#vOl5 zI5tAwO>`3f+LQRl{#Q=odseCCUYSZu=@x0F|F~PVdkVPBCN=*~JSFC11o~u~&4&Wo_ z+2Fiyn&M-@@6(dUjWsQT>dc?|EoZ9$1=h3+wL5r)9V=wJV9>bI?Q*MNDuR+*1=yJg z@)mpOCDGv76(n`B) zn@01`a?mM8$P-FG9JC9t1f2$$kks1gj%-m5!4BR%j%U~(SYOIoT9i?ZNdWf_flQCn z6-Hr!COQ-WJ+)@|-F|!qPnp{)h$)eyNYr`%9XUE`V7wm(lM&z?2(CuuI^=dCrmbxk zT)Aoj3g;zf@U((sLIc#&aQrKs^S^dmOe-e6{FRQLZ^^^Eq44oS!*iMLs30MYKF-*=y;t zT(jg^pR&GcMOm&mJo4}3)xVyDct{LtBsU@yGCE=`B;1UvQHz(kdL7$x@yIilrrCyK&w}Q(dK{}*DBV!CM^|ye_ z5kWel>N3aSvUvO#oG?a0$lYas}X$p~B?~z@?m*p876a zG7@mfOu!``9L@x|TvOoERwuocq`pG8`K9y8ySH7!&=_bMXi3nhPYW#t8VgMaEwy9Y JrL7LNJkdFlWjsug5wegJPg%PMx_R94{m5X z3=L&sg(7gr+z`iOpVc^x!&J3o_Y!_)qR}*-x-JmQwGuU@4WTI*QWD(8RFD{lI=1>& zvJ%?Uyxq6oe(&wueXD)LzO}=?wWoLIU_mHx_YJJNJtIw=9ENJHKb{|Cv57qR+!s2i?cG#FGU5ZcO14k3m1)#aU-Z z#8*4HFoVc;&NU0*sLCZ)E|BaGlGNvp;H5b~;*{sqOGmMz@RuBV0ihg>cyt6IjCHR@ zMvmaUxU+hG4Rd&1WPcAnj`b@X;ebQ^Jb)i1f4Fe*&C%G{AIIZwy`A{eJAc0Pm%qMy z`MoQDd;jlOuT5OPaqHYu>;#Tf_u`{QrrWMw4C02?e0Ox8(b~i#rNAA%ZB&Zf(WFsX z>?XzTMz5#GwD5(Z%|<0909V2GFtBy$R&OU8?T5UNU-5*Sjea(a5c$j=ZZ>7rL;q>~ zVv@XJpFl`t!#^+*)ABTlys(NX`tply?gfV0mx>6&Vg)EAH8 zWvvGbd=o*gBGLCLLN`e8$0r+yCq_tc|I$_47eZCsicm6l0QUD1LTzon z`~iITiJZd+B9wPv(Y6^zpcjkbv1yAa#10hjx6jzDyE)O~ z-+P9=uvfemROgMDe`=dV&j>vGIbyQ}xsq4|N_>(&wuS9ko9OoX5IXfNGc;|vz@2_L zOwbFq58>CBN{wbPZftCHVm_6)qi#NqOYLd!`7gkp41H{jrr;g$qA=`#7 zI@GuOaaqKdiq2Xj5%}J7@w|Ia76M4aUrv_+rhGl>C698RL2eR6zao6-Ht^5tqEP?-id%CEGoZn z_|^edmQ3VBXKfM#0mmrJCm(`g4SWj_<>Y@kow(ix_G+t!A7);5M25HH5p%?J19#!l zYGwh4w@`$q!GEyOrdGo4OpVB=_7}J)JsR zq3xii@d~X5#d#}iveW%> zk$O3XSMAC~{YeRpXGEmoepHds7eW{jsR9l`ft51~AmA{AWE4QQq!Cc`GIiyZHi7Py zBB$TOr5N7VfI-#@+ySGk<-6%~6=HF+)4_rc6P5gF$^;yj1d~ox_kIt<( zeUAI9U&m}KycC*IR_+V5M9ik!Ibqx*B{^a+#}G=a869R&VhTKzlw`#m){{G{jy*qS5#7*lQ`C@m&q;X=#IJIb&t1 z(z@g%+uJ4ATB@>9sZYo8(kD9Q5X2H1x@&aZH@K6mnDf$IBfa#>4#^9FKTuN*kSz|X zRn#cECV8j;(FNnE(H$aZ^Ex|P9-@zOxcK