oammanager.asm 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092
  1. /*
  2. this is the sprite/oam routine file.
  3. direct sprite features:
  4. -setup sprite variables
  5. -create and upload spritelist-buffer to oam-ram
  6. -upload sprite palettes
  7. object manager features:
  8. -create and process object list
  9. -create objects, each with own memory space
  10. -delete objects
  11. -routines for:
  12. -cycling through animations
  13. -moving objects along preset paths
  14. areas needed:
  15. OAMBuffer ds 200
  16. oam memory format:
  17. Byte 1 xxxxxxxx x: X coordinate
  18. Byte 2 yyyyyyyy y: Y coordinate
  19. Byte 3 cccccccc c: starting character (tile) number p: palette number
  20. Byte 4 vhoopppc v: vertical flip h: horizontal flip o: priority bits
  21. Note: the 'c' in byte 4 is the MOST significant bit in the 9-bit char #.
  22. 00110000
  23. OAMPriorityBuffer ds 20
  24. oam priority format:
  25. 2bits per sprite, 4 sprites per byte
  26. bit0 = size toggle
  27. bit1 = x coordinate msb
  28. ObjectList ds $400
  29. Maximum number of objects: 64
  30. Object Format: 32bytes per object
  31. .db %11101010 ;0 object type designation
  32. ;bit0=X position sign of sprite(usually 0)
  33. ;bit1=Object size flag
  34. ;bit2=collidable
  35. ;bit3=subroutine? if set, this object has its own subroutine that must be executed every frame
  36. ;bit4=animate? if set, this object is animated(a special table for each object specifies the exact animation with commands for tileloading, waiting, animation loop etc)
  37. ;bit5=bg-bound? if set, this object must move in accordance with background layer 0
  38. ;bit6=object active? if set, this object is active and needs to be drawn. if clear, this sprite doesnt need to be drawn, but must be processed, anyway
  39. ;bit7=object present? if set, this slot has an object. if clear, its considered empty and can be overwritten
  40. .db %00000000 ;1 object type designation 2
  41. ;bit7=pseudo 3d sprite that needs to be moved according to z-value when background moves
  42. ;bit6=don't upload tiles for this sprite. useful for stuff like particles and such where lots of sprites share the same tiles.
  43. .db 6 ;2 number of subroutine. executed if bit6 of object type is set
  44. .db 14 ;3 tileset to use
  45. .db 9 ;4 current "frame" of tileset to display
  46. .db $cc ;5 starting tile in vram
  47. .db %00111101 ;6 palette and config. vhoopppN; oo=priority. ppp=palette. N=nametable vh=flip
  48. .dw $0 ;7 x position
  49. .dw 201 ;9 y position
  50. .db 0 ;11 current frame in animation list
  51. .db 0 ;12 object command list to use
  52. .db 0 ;13 object offset in object list.
  53. .db 9 ;14 palette number to upload for this sprite
  54. .dw OamTypeTextbox ;15 object number
  55. .db 0 ;17 x-displacement
  56. .db 0 ;18 y-displacement
  57. .db 4 ;19 z-displacement
  58. .db 0 ;20 z-value for pseudo-3d scenes
  59. .db 0 ;21 collision subroutine
  60. .db 0 ;22 animation repeat counter for nop, must not be set up
  61. ;23-25 left void for future expansion
  62. ;custom variables differing between sprites:
  63. .db 0 ;26 spare variable
  64. .db $80 ;27 target x-pos /npc walking distance
  65. .db 32 ;28 target y-pos
  66. .db 0 ;29 current x-pos, must not be set up
  67. .db 8 ;30 current y-pos, must not be set up
  68. .db 0 ;void
  69. .db 0 ;void
  70. .db 0 ;void
  71. .db 0 ;void
  72. .db 0 ;void
  73. .db 0 ;void
  74. .db 0 ;void
  75. object command list format:
  76. an entry is always 2 bytes long, mostly consisting of a command byte and a parameter
  77. normally, one command from the list is executed per frame.
  78. ".." means no parameter.
  79. if bit7 of command byte is set, execute the next command immediately.
  80. this is used to execute multiple commands per frame.
  81. control code: function:
  82. -00NN create another object in object list. NN is the number of the object to create. searches for the next free slot in object list
  83. -01.. deletes object from list(can only delete itself. if an object wants to delete another one, it has to do this via the subroutine)
  84. -02XY adds signed xy-vector to objects position.
  85. -03TF increment current tileset frame. TF=number of frames to advance
  86. -04TF set tileset frame. TF=tileset frame to set
  87. -05PC set palette and config PC=palette and config ;IMPORTANT!! if this is executed, the tile positions of an object bigger than 8x8 must be swapped!!
  88. -06AF goto frame in animation list. can be used to create infinite looping objects. AF=frame in animation list
  89. -07CL goto command list. always starts at position 0 in that command list and discards current command list. CL=command list to go to.
  90. -08.b0 set/unset object screen-bound (with bit0 of parameter)
  91. -09.b0 set/unset object subroutine enable (with bit0 of parameter)
  92. -0aSS set object subroutine. SS=subroutine number
  93. -0bTS set tileset. TS:number of tileset to use
  94. -0cSE play soundeffect
  95. -0dFN nop and wait for next frame(s). used for delays. FN specifies number of frames to wait. 0=wait one frame, 5=wait 6 frames etc
  96. -0e.. inifite loop. object stays active
  97. -0f.. terminate. used to end object list processing. marks object as inactive.
  98. -10VS set target speed vector. bits0-5: speed (0-2subpixel precision) bits 6,7: accel type (0=direct, 1=linear slow, 2=linear fast, 3=smooth). speed 0 disables vector speed calculation
  99. -11VD set target vector direction/angle. bits0-5: target direction ($00=up $10=right $20=down $30=left) bits 6,7: direction change type (0=direct, 1=linear slow, 2=linear fast, 3=smooth). clockwise/counterclockwise direction is determined by distance between current and target direction(alsways uses fastest/smallest angle)
  100. -12NN create object and put it to the coordinates of the calling object. NN=number of object to create
  101. sprite palettes start at cgram entry 128
  102. oam registers:
  103. $2101 - global sprite size select
  104. sprite tile location select: 0,4000,8000,c000
  105. $2102 - oam adress
  106. $2103 - oam table and priority rotation select
  107. $2104 - oam data. this is a doublewrite/read register.
  108. free space for sprites:
  109. $4000 bytes at $c000
  110. $20 bytes per 8x8 sprite = 512 tiles for sprites
  111. first sprite tile must always be blank
  112. size: amount possible in terms of vram space:
  113. 8x8 512
  114. 16x16 128
  115. 32x32 32
  116. for sprites bigger than 8x8, the vram tile data is seperated into horizontal rows, each 16 tiles (=512 bytes) apart.
  117. they are always 16 tiles apart, no matter if the sprites are 16,32 or 64 pixels in size
  118. heres a table what to upload where for different sized sprites:
  119. xsize: ysize: number of lines to upload: number of bytes to transfer per line:
  120. 8 8 1 32
  121. 16 16 2 64
  122. 32 32 4 128
  123. 64 64 8 256
  124. 16 32 4 64
  125. 32 64 8 128
  126. initial setting for register $2101 gets loaded with
  127. graphics config file loader "SetBGMode" and put into variable "ObjSel", updated every vblank
  128. variables:
  129. ObjectListPointer dw ;pointer to current object in object list, used to set direct register
  130. CurrentObjectNumber db ;number of currently selected object in list
  131. OamBufferPointer dw ;pointer to current sprite in oam buffer
  132. fixed variables:
  133. .define ObjectFileSize 16 ;size of one object file
  134. routines in detail:
  135. InitOam:
  136. -clears oam table buffer
  137. -clears object memory
  138. CreateObject:
  139. -upload object file to first free slot in object list
  140. -upload current frame of tileset to vram
  141. -calculate transfer size by object size
  142. -calculate transfer source by object size*frame number
  143. -calculate transfer target by starting tile in vram
  144. -upload palette to vram according to palette number config
  145. -set object offset in object list variable
  146. ObjectProcessor:
  147. -check object list for active object
  148. -write sprite(s) to oambuffer according to object file
  149. -process animation list if enabled
  150. -execute subroutine if enabled
  151. */
  152. ObjectProcessSubroutine:
  153. rep #$31
  154. phx
  155. ldx.b ObjectListPointerCurrent
  156. lda.w ObjEntrySubRout,x
  157. and.w #$ff ;max number of routines: 256
  158. asl a
  159. tax
  160. php
  161. phd
  162. jsr (AniSubroutineJumpLUT,x)
  163. pld
  164. plp
  165. plx
  166. rts
  167. ObjectProcessAniList:
  168. php
  169. ObjectProcessAniListYes:
  170. rep #$31
  171. ;load pointer to current animation list:
  172. lda.w ObjEntryAniList,x ;get number of list to use
  173. and.w #$ff
  174. asl a
  175. phx
  176. tax
  177. ; sta.b TempBuffer
  178. lda.l (ObjectAnimationLUT+BaseAdress),x ;get relative pointer to object
  179. plx
  180. clc
  181. adc.w #ObjectAnimationLUT ;calculate real pointer
  182. sta.b ThreeBytePointerLo
  183. sep #$20
  184. lda.b #(:ObjectAnimationLUT+BaseAdress>>16)
  185. sta.b ThreeBytePointerBank
  186. ;get pointer to currently active frame:
  187. rep #$31
  188. lda.w ObjEntryAniFrame,x
  189. and.w #$ff
  190. asl a
  191. tay
  192. ;get command
  193. phx
  194. lda.b [ThreeBytePointerLo],y ;get current command
  195. sta.b OamAniListStraightRepeatFlag ;store for immediate repeat checking
  196. pha
  197. and.w #$1f ;mask off repeat flag, maximum number of commands: 32
  198. asl a
  199. tax
  200. pla
  201. phy
  202. php
  203. phd
  204. /*
  205. rep #$31
  206. pha
  207. lda.b ObjectListPointerCurrent
  208. clc
  209. adc.w #ObjectList & $ffff
  210. tcd
  211. pla
  212. */
  213. sep #$20
  214. lda.b #0 ;clear high byte
  215. xba ;and put parameter into a
  216. ;parameter is in a,8bit
  217. ;direct register points to current object
  218. ;bank is $7e
  219. jsr (AniListJumpLUT,x)
  220. pld
  221. plp
  222. ply
  223. plx
  224. sep #$20
  225. lda.b OamAniListStraightRepeatFlag
  226. bmi ObjectProcessAniListYes ;if bit7 is set, next command is executed immediately
  227. plp
  228. rts
  229. AniListJumpLUT:
  230. .dw AniListCreateObj ;0
  231. .dw AniListDelete
  232. .dw AniListMove
  233. .dw AniListTileFrameInc
  234. .dw AniListTileFrameSet
  235. .dw AniListPalConfSet
  236. .dw AniListGotoAniFrame
  237. .dw AniListGotoAniList
  238. .dw AniListMakeBGBound
  239. .dw AniListSubroutineEnable
  240. .dw AniListSetSubroutine ;10
  241. .dw AniListTileSetSet
  242. .dw AniListPlaySoundEffect
  243. .dw AniListVoid
  244. .dw AniListInfiniteLoop
  245. .dw AniListEnd ;15
  246. .dw AniListSetVectorSpeed
  247. .dw AniListSetVectorDir
  248. .dw AniListCreateObjPosition
  249. ;does nothing, doesn't proceed to next animation command
  250. AniListInfiniteLoop:
  251. rts
  252. AniListVoid:
  253. ldx.b ObjectListPointerCurrent
  254. sta.w TempBuffer
  255. lda.w TempBuffer
  256. beq AniListVoidProceed ;if argument is 0, proceed to next frame directly
  257. lda.w ObjEntryAniCmdRepeat,x ;if argument is not zero, but command list repeat is, we just encountered this void command. load new wait value.
  258. bne AniListVoidDecrease ;if argument is not zero, we're on a repeated loop here. don't load new value, just decrease old one.
  259. lda.w TempBuffer
  260. sta.w ObjEntryAniCmdRepeat,x
  261. rts
  262. ;argument was already loaded, decrease
  263. AniListVoidDecrease:
  264. dec a
  265. sta.w ObjEntryAniCmdRepeat,x
  266. beq AniListVoidProceed ;if repeat value just turned 0, we're done here, go to next command
  267. rts
  268. AniListVoidProceed:
  269. ; ldx.b ObjectListPointerCurrent
  270. ; stz.w ObjEntryAniCmdRepeat,x ;not needed, but do it anyway just to be safe
  271. inc.w ObjEntryAniFrame,x
  272. rts
  273. AniListCreateObj:
  274. ldx.b ObjectListPointerCurrent
  275. inc.w ObjEntryAniFrame,x
  276. jsr CreateObject
  277. rts
  278. AniListCreateObjPosition:
  279. rep #$31
  280. tay ;save number of object to load
  281. ldx.b ObjectListPointerCurrent ;get position of calling object
  282. lda.w ObjEntryXPos,x ;save to stack
  283. adc.w #8*16 ;move one tile to the left
  284. pha
  285. lda.w ObjEntryYPos,x
  286. clc
  287. adc.w #8*16 ;move one tile to the bottom
  288. pha
  289. inc.w ObjEntryAniFrame,x
  290. tya
  291. jsr CreateObject
  292. ldx.b ObjectListPointerCurrent ;get position of newly-created object
  293. pla
  294. sta.w ObjEntryYPos,x ;update position
  295. pla
  296. sta.w ObjEntryXPos,x
  297. rts
  298. AniListGotoAniFrame:
  299. ldx.b ObjectListPointerCurrent
  300. sta.w ObjEntryAniFrame,x ;store new animation frame
  301. rts
  302. AniListDelete:
  303. ldx.b ObjectListPointerCurrent
  304. sta.w ObjEntryType,x ;clear object type info and present flag
  305. rts
  306. AniListMove:
  307. ldx.b ObjectListPointerCurrent
  308. inc.w ObjEntryAniFrame,x
  309. pha
  310. and.b #$f0 ;get x-add
  311. clc
  312. lsr a
  313. lsr a
  314. lsr a
  315. lsr a
  316. bit.b #$08 ;check if negative
  317. beq AniListMoveXNotNeg
  318. and.b #$07
  319. eor.b #$ff ;xor to substract value
  320. inc a
  321. AniListMoveXNotNeg:
  322. rep #$31
  323. asl a ;subpixel precision
  324. asl a
  325. asl a
  326. asl a
  327. adc.w ObjEntryXPos,x
  328. sta.w ObjEntryXPos,x
  329. sep #$20
  330. pla
  331. and.b #$0f ;get x-add
  332. bit.b #$08 ;check if negative
  333. beq AniListMoveYNotNeg
  334. and.b #$07
  335. eor.b #$ff ;xor to substract value
  336. inc a
  337. AniListMoveYNotNeg:
  338. rep #$31
  339. and.w #$ff ;mask off high byte from x-position calculation
  340. asl a ;subpixel precision
  341. asl a
  342. asl a
  343. asl a
  344. adc.w ObjEntryYPos,x
  345. sta.w ObjEntryYPos,x
  346. sep #$20
  347. rts
  348. AniListTileFrameInc:
  349. ldx.b ObjectListPointerCurrent
  350. inc.w ObjEntryAniFrame,x ;increment animation frame
  351. clc
  352. adc.w ObjEntryTilesetFrame,x ;add increment number to tileset frame
  353. sta.w ObjEntryTilesetFrame,x ;store new tileset frame
  354. lda.w ObjEntryType,x
  355. bit.b #%01000000 ;check if active. if inactive/offscreen, dont waste time uploading a new frame
  356. beq AniListTileFrameIncOffscreen
  357. jsr CreateObjUploadSpriteFrame
  358. AniListTileFrameIncOffscreen:
  359. rts
  360. AniListTileSetSet:
  361. ldx.b ObjectListPointerCurrent
  362. sta.w ObjEntryTileset,x ;set tileset frame
  363. inc.w ObjEntryAniFrame,x ;increment animation frame
  364. jsr CreateObjUploadSpriteFrame
  365. rts
  366. AniListTileFrameSet:
  367. ldx.b ObjectListPointerCurrent
  368. inc.w ObjEntryAniFrame,x ;increment animation frame
  369. sta.w ObjEntryTilesetFrame,x ;set tileset frame
  370. jsr CreateObjUploadSpriteFrame
  371. rts
  372. AniListPalConfSet:
  373. ldx.b ObjectListPointerCurrent
  374. inc.w ObjEntryAniFrame,x ;increment animation frame
  375. sta.w ObjEntryPalConf,x ;set palette and priority config
  376. rts
  377. AniListGotoAniList:
  378. ldx.b ObjectListPointerCurrent
  379. sta.w ObjEntryAniList,x ;set animation list
  380. stz.w ObjEntryAniFrame,x ;reset animation frame
  381. stz.b TempBuffer+10 ;clear animation-command repeat flag
  382. rts
  383. AniListMakeBGBound:
  384. ldx.b ObjectListPointerCurrent
  385. inc.w ObjEntryAniFrame,x ;increment animation frame
  386. and.b #1 ;get bit 0
  387. clc
  388. asl a ;move to correct location
  389. asl a
  390. asl a
  391. asl a
  392. asl a
  393. sta.b TempBuffer
  394. lda.w ObjEntryType,x ;get object type byte
  395. and.b #$DF ;mask off bg bound flag
  396. ora.b TempBuffer ;set flag according to command parameter
  397. sta.w ObjEntryType,x ;get object type byte
  398. rts
  399. AniListSubroutineEnable:
  400. ldx.b ObjectListPointerCurrent
  401. inc.w ObjEntryAniFrame,x ;increment animation frame
  402. and.b #1 ;get bit 0
  403. clc
  404. asl a ;move to correct location
  405. asl a
  406. asl a
  407. sta.b TempBuffer
  408. lda.w ObjEntryType,x ;get object type byte
  409. and.b #$F7 ;mask off bg bound flag
  410. ora.b TempBuffer ;set flag according to command parameter
  411. sta.w ObjEntryType,x ;get object type byte
  412. rts
  413. AniListSetSubroutine:
  414. ldx.b ObjectListPointerCurrent
  415. inc.w ObjEntryAniFrame,x ;increment animation frame
  416. sta.w ObjEntrySubRout,x ;set new subroutine
  417. rts
  418. AniListPlaySoundEffect:
  419. rep #$31
  420. ldx.b ObjectListPointerCurrent
  421. inc.w ObjEntryAniFrame,x ;increment animation frame
  422. and.w #$ff
  423. jsr SpcPlaySoundEffectSimple
  424. rts
  425. AniListEnd:
  426. ldx.b ObjectListPointerCurrent
  427. inc.w ObjEntryAniFrame,x ;increment animation frame
  428. lda.w ObjEntryType,x ;
  429. and.b #$ef ;mask off animate flag
  430. sta.w ObjEntryType,x ;
  431. rts
  432. AniListSetVectorSpeed:
  433. ldx.b ObjectListPointerCurrent
  434. inc.w ObjEntryAniFrame,x ;increment animation frame
  435. sta.w ObjEntryVectorTarSpeed,x
  436. and.b #%111111
  437. cmp.b #$3f
  438. bne AniListSetVectorSpeedNoOver
  439. dec.w ObjEntryVectorTarSpeed,x
  440. AniListSetVectorSpeedNoOver:
  441. lda.w ObjEntryVectorSpeed,x
  442. and.b #%1111111 ;clear "target met" flag
  443. sta.w ObjEntryVectorSpeed,x
  444. rts
  445. AniListSetVectorDir:
  446. ldx.b ObjectListPointerCurrent
  447. inc.w ObjEntryAniFrame,x ;increment animation frame
  448. sta.w ObjEntryVectorTarDir,x
  449. and.b #%111111
  450. sta.b TempBuffer
  451. lda.w ObjEntryVectorDir,x
  452. and.b #%111111
  453. sta.b TempBuffer+1 ;34
  454. cmp.b TempBuffer ;28
  455. beq AniListSetVectorDirEqual
  456. bcs AniListSetVectorDirCurrBigger
  457. lda.b TempBuffer
  458. sec
  459. sbc.b TempBuffer+1
  460. cmp.b #32 ;check if that distance is bigger than 180 degrees
  461. bcs AniListSetVectorDirTargetCounterClock
  462. bra AniListSetVectorDirTargetClockwise
  463. AniListSetVectorDirCurrBigger:
  464. sec ;substract current from target to get distance between them
  465. sbc.b TempBuffer ;c
  466. cmp.b #32 ;check if that distance is bigger than 180 degrees
  467. bcc AniListSetVectorDirTargetCounterClock
  468. AniListSetVectorDirTargetClockwise:
  469. lda.w ObjEntryVectorDir,x
  470. and.b #%00111111 ;clear "target met"
  471. ora.b #%01000000 ;set "clockwise"-flag
  472. sta.w ObjEntryVectorDir,x
  473. rts
  474. AniListSetVectorDirTargetCounterClock:
  475. lda.w ObjEntryVectorDir,x
  476. and.b #%00111111 ;clear "target met" and turn direction flag(counter clockwise)
  477. sta.w ObjEntryVectorDir,x
  478. rts
  479. AniListSetVectorDirEqual:
  480. lda.w ObjEntryVectorDir,x
  481. ora.b #$80
  482. sta.w ObjEntryVectorDir,x
  483. rts
  484. ;in: x,16bit:relative object pointer
  485. ;out: x,16bit:relative pointer of next active object
  486. ;if carry is set on return, all objects have been processed
  487. CheckActiveObject:
  488. ; rep #$31
  489. CheckActiveObjectLoop:
  490. lda.l (ObjEntryType + $7e0000-1),x ;get object type byte (get -1 so that the bmi check still works in 16bit mode)
  491. ; xba
  492. ; nop
  493. bmi CheckActiveObjectDone ;if a not-present object is found, end list processing
  494. txa
  495. clc
  496. adc.w #ObjectFileSize ;increment slot pointer
  497. tax
  498. cpx.w #ObjectFileSize*63 ;check if maximum number of objects reached, then step out(maybe spit out an error if needed)
  499. bne CheckActiveObjectLoop
  500. CheckActiveObjectListDone:
  501. ; sep #$20
  502. sec
  503. rts
  504. ; bra CheckActiveObjectListDone ;this is to prevent a lockup if the list is full
  505. ; beq CheckActiveObjectListDone ;this is to prevent a lockup if the list is full
  506. ; bra CheckActiveObjectLoop
  507. CheckActiveObjectDone:
  508. ; rep #$31
  509. stx.b ObjectListPointerCurrent ;store currently found object so that routines can check this back later
  510. ; sep #$20
  511. clc
  512. rts
  513. ObjectProcessor:
  514. php
  515. sep #$20
  516. phb
  517. lda.b #$7e
  518. pha
  519. plb
  520. lda.b NMIOamUploadFlag ;don't process list if last frame wasn't uploaded first. needed to prevent sprite flicker due to dma'ing incomplete oam list(irq firing during oam processor)
  521. bne ObjectProcessorExit
  522. rep #$31
  523. stz.w ColObjListPointer ;clear pointer in collision object list
  524. ; sep #$20
  525. ;check for active objects
  526. jsr ClearOamBufferPart ;only clear the part of the buffer that was actually written to last frame
  527. jsr ClearOamPriorityBuffer
  528. ; jsr ClearPriorityZBuffer
  529. ; jsr ClearColObjList
  530. ldx.w #0 ;start at object 0
  531. ObjectProcessorLoop:
  532. jsr CheckActiveObject ;check for active object
  533. bcc ObjectProcessorNoExit ;if carry is set, all objects were processed
  534. jsr ZSortToOamBuffer
  535. ; rep #$31
  536. stz.b ObjectListPointerCurrent
  537. inc.b NMIOamUploadFlag ;initiate oam buffer upload
  538. ObjectProcessorExit:
  539. plb
  540. plp
  541. rts
  542. ObjectProcessorNoExit:
  543. ;check if sprite needs to be drawn on screen:
  544. lda.w ObjEntryType,x ;get object type byte
  545. ; bit.b #%01000000
  546. ; beq ObjProcInactive ;skip the oam write if bit isnt set
  547. bit.w #%00100000 ;check if sprite is screenbound. if it is, dont check if the sprite is offscreen.
  548. bne ObjProcDontCheckOnscreen
  549. ObjectProcessorCheckOnscreen:
  550. ; rep #$31
  551. lda.w ObjEntryXPos,x ;remove precision
  552. lsr a
  553. lsr a
  554. lsr a
  555. lsr a
  556. sta.w TempBufferTest
  557. lda.w ObjEntryYPos,x ;remove precision
  558. lsr a
  559. lsr a
  560. lsr a
  561. lsr a
  562. sta.w TempBufferTest+2
  563. lda.w ObjEntryXDisplacement,x
  564. and.w #$ff
  565. eor.w #$ffff
  566. ; adc.w ObjEntryXPos,x ;check if sprite is left of screen
  567. clc
  568. adc.w TempBufferTest
  569. clc
  570. adc.w #32
  571. cmp.b ScreenPixelPositionX
  572. bcc ObjProcInactive
  573. lda.w ObjEntryXDisplacement,x
  574. and.w #$ff
  575. clc
  576. adc.b ScreenPixelPositionX
  577. clc
  578. adc.w #(TileBufferSizeX+1)*8 ;check if sprite is right of screen
  579. ; cmp.w ObjEntryXPos,x
  580. cmp.w TempBufferTest
  581. bcc ObjProcInactive
  582. lda.w ObjEntryYDisplacement,x
  583. and.w #$ff
  584. eor.w #$ffff
  585. clc
  586. ; adc.w ObjEntryYPos,x ;check if sprite is on top of screen
  587. adc.w TempBufferTest+2
  588. clc
  589. adc.w #32
  590. cmp.b ScreenPixelPositionY
  591. bcc ObjProcInactive
  592. lda.w ObjEntryYDisplacement,x
  593. and.w #$ff
  594. clc
  595. adc.b ScreenPixelPositionY
  596. clc
  597. adc.w #TileBufferSizeX*8 ;check if sprite is below screen
  598. ; cmp.w ObjEntryYPos,x
  599. cmp.w TempBufferTest+2
  600. bcc ObjProcInactive
  601. ObjProcDontCheckOnscreen:
  602. jsr ObjectSingleSpriteToOam
  603. ; sep #$20
  604. lda.w ObjEntryType,x ;get object type byte
  605. ora.w #%01000000
  606. sta.w ObjEntryType,x ;set active flag
  607. bra ObjProcActive
  608. ObjProcInactive:
  609. ; sep #$20
  610. lda.w ObjEntryType,x ;get object type byte
  611. and.w #%10111111
  612. sta.w ObjEntryType,x ;clear active flag
  613. ObjProcActive:
  614. ; sep #$20
  615. lda.w ObjEntryType,x ;get object type byte
  616. phx
  617. bit.w #%00010000
  618. beq ObjProcNoAnim ;skip the oam write if bit isnt set
  619. jsr ObjectProcessAniList
  620. ObjProcNoAnim:
  621. plx
  622. stx.b ObjectListPointerCurrent ;must be saved cause ani list routines that create new sprites might rewrite it
  623. phx
  624. ; sep #$20
  625. lda.w ObjEntryType,x ;get object type byte
  626. bit.w #%00001000
  627. beq ObjProcNoSub ;skip the oam write if bit isnt set
  628. jsr ObjectProcessSubroutine
  629. ObjProcNoSub:
  630. ; sep #$20
  631. plx
  632. stx.b ObjectListPointerCurrent ;must be saved cause ani list routines that create new sprites might rewrite it
  633. phx
  634. lda.w ObjEntryType,x ;get object type byte
  635. bit.w #%00000100
  636. beq ObjProcNoColl ;skip the oam write if bit isnt set
  637. jsr CreateColListEntry
  638. ObjProcNoColl:
  639. plx
  640. stx.b ObjectListPointerCurrent ;must be saved cause ani list routines that create new sprites might rewrite it
  641. /*
  642. lda.w ObjEntryVectorTarSpeed,x ;get vector target speed
  643. and.w #%111111 ;mask off target bit
  644. beq ObjProcNoVectorMove ;skip vector move if vector speed is 0
  645. jsr ObjVectorMoveHandler
  646. ObjProcNoVectorMove:
  647. */
  648. ;check if object is of gravity decaying type
  649. lda.w ObjEntryType2,x ;get object type byte
  650. bit.w #%10000 ;check if sprite is screenbound. if it is, dont check if the sprite is offscreen.
  651. beq ObjProcNoGravity
  652. jsr ObjProcUpdateGravity
  653. ObjProcNoGravity:
  654. ; rep #$31
  655. txa
  656. clc
  657. adc.w #ObjectFileSize
  658. tax
  659. stx.b ObjectListPointerCurrent ;relative pointer to current object in objectlist
  660. jmp ObjectProcessorLoop
  661. plp
  662. rts
  663. ;upload collidable object information to a special list
  664. CreateColListEntry:
  665. php
  666. txy
  667. ldx ColObjListPointer ;get pointer to currently active slot in col obj list
  668. sep #$20
  669. ; lda.b #$80 ;load col-obj present flag
  670. lda.w ObjEntryColliSub,y ;get subroutine number and
  671. ora.b #$80 ;set enable flag
  672. xba
  673. lda.w ObjEntryListOffset,y ;load obj number in object list
  674. rep #$31
  675. sta.l ColObjList,x ;store in obj col list
  676. lda.w ObjEntryXPos,y ;get x pos of obj and divide by 16
  677. lsr a ;remove subpixel precision
  678. lsr a
  679. lsr a
  680. lsr a
  681. inx
  682. inx
  683. sta.l ColObjList,x ;store in obj col list
  684. lda.w ObjEntryYPos,y ;get y pos of obj and divide by 16
  685. lsr a ;remove subpixel precision
  686. lsr a
  687. lsr a
  688. lsr a
  689. inx
  690. inx
  691. sta.l ColObjList,x ;store in obj col list
  692. inx
  693. inx
  694. stx ColObjListPointer ;update pointer to next entry in collision list
  695. tyx
  696. plp
  697. rts
  698. ;in: a, 8bit: number of object to load
  699. ; x, 16bit: target low: x, high:y-position/8
  700. ;in y, 8bit: target z-position
  701. ;uses TempBuffer0,1. maybe convert to use own temp area for better flexibility?
  702. CreateObjectPosition:
  703. php
  704. rep #$31
  705. stx.b CollisionPixelX
  706. sty.b CollisionPixelY
  707. ; sty.b CollisionPixelY
  708. and.w #$ff ;2byte pointer
  709. asl a
  710. tax ;put into x
  711. phd
  712. lda.w #0
  713. tcd
  714. sep #$20
  715. phb
  716. lda.b #$7e
  717. pha
  718. plb
  719. rep #$31
  720. lda.l (ObjectLUT+BaseAdress),x ;get relative pointer to object
  721. clc
  722. adc.w #ObjectLUT ;calculate real pointer
  723. sta.b ThreeBytePointerLo
  724. sep #$20
  725. lda.b #(:ObjectLUT+BaseAdress>>16)
  726. sta.b ThreeBytePointerBank
  727. ;check for free object space in object list:
  728. ; rep #$31
  729. ldx.w #0
  730. CreateObjectPositionCheckFreeSpaceLoop:
  731. lda.w ObjEntryType,x ;get object type byte
  732. bpl CreateObjectPositionCheckFreeSpaceDone ;if free, step out
  733. rep #$31
  734. txa
  735. adc.w #ObjectFileSize ;increment slot pointer
  736. tax
  737. sep #$20
  738. cpx.w #ObjectFileSize*63 ;check if maximum number of objects reached, then step out(maybe spit out an error if needed)
  739. beq CreateObjectPositionCheckFreeSpaceDone ;this is to prevent a lockup if the list is full
  740. bra CreateObjectPositionCheckFreeSpaceLoop
  741. CreateObjectPositionCheckFreeSpaceDone:
  742. rep #$31
  743. stx.b ObjectListPointerCurrent ;relative pointer to current object in objectlist
  744. txa
  745. clc
  746. lsr a
  747. lsr a
  748. lsr a
  749. lsr a ;divide objectlist pointer by 16 to get current object number
  750. sep #$20
  751. sta.b CurrentObjectNumber
  752. rep #$31
  753. ldy.w #0
  754. CreateObjectPositionUploadLoop:
  755. lda.b [ThreeBytePointerLo],y ;get first byte of object file in rom
  756. sta.w ObjEntryType,x
  757. inx
  758. inx
  759. iny
  760. iny
  761. cpy.w #(ObjectFileSize&$fffe) ;check if object file was uploaded, word-aligned
  762. bne CreateObjectPositionUploadLoop
  763. ldx.b ObjectListPointerCurrent
  764. lda.w ObjEntryType,x ;get object type byte
  765. bit.w #%100000 ;check if screenbound
  766. beq CreateObjectPositionNotScreenBound
  767. lda.w ObjEntryType2-1,x ;pseudo-3d object?
  768. bpl CreateObjectPositionNot3D
  769. lda.b CollisionPixelX ;plot directly to loaded xy position if screenbound
  770. and.w #$ff
  771. clc
  772. asl a ;multiply with 16, 3d high-precision value
  773. asl a
  774. asl a
  775. asl a
  776. ; asl a
  777. ; asl a
  778. asl a
  779. asl a
  780. asl a
  781. sta.w ObjEntryXPos,x
  782. lda.b CollisionPixelX
  783. and.w #$ff00
  784. xba
  785. clc
  786. asl a ;multiply with 16, 3d high-precision value
  787. asl a
  788. asl a
  789. asl a
  790. ; asl a
  791. ; asl a
  792. asl a
  793. asl a
  794. asl a
  795. sta.w ObjEntryYPos,x
  796. lda.b CollisionPixelY ;store z-value
  797. sep #$20
  798. sta.w ObjEntryZDisplacement,x
  799. rep #$31
  800. bra CreateObjectPositionNotScreenBoundSkip
  801. CreateObjectPositionNot3D:
  802. lda.b CollisionPixelX ;plot directly to loaded xy position if screenbound
  803. and.w #$ff
  804. clc
  805. asl a ;multiply by 8
  806. asl a
  807. asl a
  808. asl a ;add subpixel precision
  809. asl a
  810. asl a
  811. asl a
  812. sta.w ObjEntryXPos,x
  813. lda.b CollisionPixelX
  814. xba
  815. and.w #$ff
  816. clc
  817. asl a ;multiply by 8
  818. asl a
  819. asl a
  820. asl a ;add subpixel precision
  821. asl a
  822. asl a
  823. asl a
  824. sta.w ObjEntryYPos,x
  825. bra CreateObjectPositionNotScreenBoundSkip
  826. CreateObjectPositionNotScreenBound:
  827. clc
  828. lda.b CollisionPixelX
  829. and.w #$ff
  830. asl a ;multiply by 8
  831. asl a
  832. asl a
  833. asl a ;add subpixel precision
  834. asl a
  835. asl a
  836. asl a
  837. sta.w ObjEntryXPos,x
  838. clc
  839. lda.b CollisionPixelX
  840. and.w #$ff00
  841. xba
  842. asl a ;multiply by 8
  843. asl a
  844. asl a
  845. asl a ;add subpixel precision
  846. asl a
  847. asl a
  848. asl a
  849. sta.w ObjEntryYPos,x
  850. CreateObjectPositionNotScreenBoundSkip:
  851. ;upload object number:
  852. ; ldx.b ObjectListPointer
  853. ; clc
  854. ; adc.w #(ObjectList & $ffff)
  855. ; clc
  856. ; adc.w #13
  857. ; tax
  858. lda.w #0
  859. tay
  860. ; tax
  861. ; inx
  862. sep #$20
  863. lda.b CurrentObjectNumber
  864. sta.w ObjEntryListOffset,x ;store in the object number offset in an object file
  865. jsr CreateObjUploadSpriteFrame
  866. jsr CreateObjUploadPalette
  867. ;the animation list has to be executed at once in case objects create additional objects
  868. ldx.b ObjectListPointerCurrent
  869. ; stx.b ObjectListPointerCurrent
  870. phx
  871. lda.w ObjEntryType,x ;get object type byte
  872. bit.b #%00010000
  873. beq ObjLoaderPositionNoAnim ;skip the oam write if bit isnt set
  874. jsr ObjectProcessAniList
  875. ObjLoaderPositionNoAnim:
  876. lda.w ObjEntryType2,x ;increase max obj number if gravity particle present
  877. bit.b #%10000
  878. beq ObjLoaderPositionNoGravObj ;skip the oam write if bit isnt set
  879. jsr ObjectProcessGravObjInc
  880. ObjLoaderPositionNoGravObj:
  881. plx
  882. stx.b ObjectListPointerCurrent ;must be saved cause ani list routines that create new sprites might rewrite it
  883. sep #$20
  884. lda.w ObjEntryType,x ;get object type byte
  885. bit.b #%00001000
  886. beq ObjLoaderPositionNoSub ;skip the oam write if bit isnt set
  887. jsr ObjectProcessSubroutine
  888. ObjLoaderPositionNoSub:
  889. plb
  890. pld
  891. plp
  892. rts
  893. ;upload palette:
  894. CreateObjUploadPalette:
  895. lda.w ObjEntryType2,x
  896. bit.b #%00100000 ;don't upload palette if corresponding flag is set
  897. bne CreateObjUploadPaletteCancel
  898. rep #$31
  899. lda.w ObjEntryPalConf,x ;get palette config
  900. sta.b TempBuffer
  901. lda.w ObjEntryPalNumber,x ;get palette number
  902. and.w #$ff ;2byte pointer
  903. asl a ;2byte length
  904. asl a
  905. tax ;put into x
  906. lda.l (SpritePaletteLUT+BaseAdress),x ;get relative pointer to object
  907. clc
  908. adc.w #SpritePaletteLUT ;calculate real pointer
  909. sta.b ThreeBytePointerLo
  910. lda.l (SpritePaletteLUT+BaseAdress+2),x ;get length
  911. and.w #$fe ;mask off bit0. palettes always have word entries. prevents uploader from crashing if invalid palette is being loaded
  912. cmp.w #$20
  913. bcs UploadObjPalNoOverflow
  914. lda.w #$20 ;never load palettes bigger than 32 bytes
  915. UploadObjPalNoOverflow:
  916. sta.b TempBuffer+1
  917. lda.w #0
  918. sep #$20
  919. lda.b #(:SpritePaletteLUT+BaseAdress>>16)
  920. sta.b ThreeBytePointerBank
  921. rep #$31
  922. lda.b TempBuffer
  923. and.w #$E ;only get three palette bits
  924. clc
  925. lsr a ;rotate right to get palette number
  926. clc
  927. adc.w #8 ;add sprite palette offset
  928. asl a ;multiply with 16 to get real start adress in palette buffer
  929. asl a
  930. asl a
  931. asl a
  932. asl a
  933. tax
  934. ldy.w #0
  935. CreateObjectPositionUploadPaletteLoop:
  936. lda.b [ThreeBytePointerLo],y ;get first byte of object file in rom
  937. sta.w PaletteBuffer & $ffff,x
  938. inx
  939. inx
  940. iny
  941. iny
  942. cpy.b TempBuffer+1 ;check if object file was uploaded, word-aligned
  943. bne CreateObjectPositionUploadPaletteLoop
  944. sep #$20
  945. inc.b NMIPaletteUploadFlag
  946. CreateObjUploadPaletteCancel:
  947. rts
  948. ;in: a, 8bit: number of object to load
  949. CreateObject:
  950. php
  951. rep #$31
  952. and.w #$ff ;2byte pointer
  953. sta.b TempBuffer
  954. asl a
  955. tax ;put into x
  956. phd
  957. lda.w #0
  958. tcd
  959. sep #$20
  960. phb
  961. lda.b #$7e
  962. pha
  963. plb
  964. rep #$31
  965. lda.l (ObjectLUT+BaseAdress),x ;get relative pointer to object
  966. clc
  967. adc.w #ObjectLUT ;calculate real pointer
  968. sta.b ThreeBytePointerLo
  969. sep #$20
  970. lda.b #(:ObjectLUT+BaseAdress>>16)
  971. sta.b ThreeBytePointerBank
  972. ;check for free object space in object list:
  973. ; rep #$31
  974. ldx.w #0
  975. CreateObjectCheckFreeSpaceLoop:
  976. lda.w ObjEntryType,x ;get object type byte
  977. bpl CreateObjectCheckFreeSpaceDone ;if free, step out
  978. rep #$31
  979. txa
  980. adc.w #ObjectFileSize ;increment slot pointer
  981. tax
  982. sep #$20
  983. cpx.w #ObjectFileSize*63 ;check if maximum number of objects reached, then step out(maybe spit out an error if needed)
  984. beq CreateObjectCheckFreeSpaceDone ;this is to prevent a lockup if the list is full
  985. bra CreateObjectCheckFreeSpaceLoop
  986. CreateObjectCheckFreeSpaceDone:
  987. rep #$31
  988. stx.b ObjectListPointerCurrent ;relative pointer to current object in objectlist
  989. txa
  990. clc
  991. lsr a
  992. lsr a
  993. lsr a
  994. lsr a ;divide objectlist pointer by 16 to get current object number
  995. sep #$20
  996. sta.b CurrentObjectNumber
  997. rep #$31
  998. ldy.w #0
  999. CreateObjectUploadLoop:
  1000. lda.b [ThreeBytePointerLo],y ;get first byte of object file in rom
  1001. sta.w ObjEntryType,x
  1002. inx
  1003. inx
  1004. iny
  1005. iny
  1006. cpy.w #(ObjectFileSize&$fffe) ;check if object file was uploaded, word-aligned
  1007. bne CreateObjectUploadLoop
  1008. ;upload object number:
  1009. ldx.b ObjectListPointerCurrent
  1010. ; clc
  1011. ; adc.w #(ObjectList & $ffff)
  1012. ; clc
  1013. ; adc.w #13
  1014. ; tax
  1015. lda.w #0
  1016. tay
  1017. ; tax
  1018. ; inx
  1019. ; lda.b TempBuffer ;store number of object so other routines can clearly identify it.
  1020. ; sta.w ObjEntryObjectNumber,x
  1021. sep #$20
  1022. lda.b CurrentObjectNumber
  1023. sta.w ObjEntryListOffset,x ;store in the object number offset in an object file
  1024. jsr CreateObjUploadSpriteFrame
  1025. /*
  1026. ;upload palette:
  1027. rep #$31
  1028. lda.w ObjEntryPalConf,x ;get palette config
  1029. sta.b TempBuffer
  1030. lda.w ObjEntryPalNumber,x ;get palette number
  1031. and.w #$ff ;2byte pointer
  1032. asl a ;2byte length
  1033. asl a
  1034. tax ;put into x
  1035. lda.l (SpritePaletteLUT+BaseAdress),x ;get relative pointer to object
  1036. clc
  1037. adc.w #SpritePaletteLUT ;calculate real pointer
  1038. sta.b ThreeBytePointerLo
  1039. lda.l (SpritePaletteLUT+BaseAdress+2),x ;get length
  1040. and.w #$fe ;word-align, no longer than 256 bytes
  1041. sta.b TempBuffer+1
  1042. lda.w #0
  1043. sep #$20
  1044. lda.b #(:SpritePaletteLUT+BaseAdress>>16)
  1045. sta.b ThreeBytePointerBank
  1046. rep #$31
  1047. lda.b TempBuffer
  1048. and.w #$E ;only get three palette bits
  1049. clc
  1050. lsr a ;rotate right to get palette number
  1051. clc
  1052. adc.w #8 ;add sprite palette offset
  1053. asl a ;multiply with 16 to get real start adress in palette buffer
  1054. asl a
  1055. asl a
  1056. asl a
  1057. asl a
  1058. tax
  1059. ldy.w #0
  1060. CreateObjectUploadPaletteLoop:
  1061. lda.b [ThreeBytePointerLo],y ;get first byte of object file in rom
  1062. sta.w PaletteBuffer & $ffff,x
  1063. inx
  1064. inx
  1065. iny
  1066. iny
  1067. cpy.b TempBuffer+1 ;check if object file was uploaded, word-aligned
  1068. bne CreateObjectUploadPaletteLoop
  1069. sep #$20
  1070. inc.b NMIPaletteUploadFlag
  1071. */
  1072. jsr CreateObjUploadPalette
  1073. ldx.b ObjectListPointerCurrent
  1074. ; stx.b ObjectListPointerCurrent
  1075. ; sep #$20
  1076. lda.w ObjEntryType,x ;get object type byte
  1077. bit.b #%00010000
  1078. beq ObjLoaderNoAnim ;skip the oam write if bit isnt set
  1079. jsr ObjectProcessAniList
  1080. ObjLoaderNoAnim:
  1081. lda.w ObjEntryType2,x ;increase max obj number if gravity particle present
  1082. bit.b #%10000
  1083. beq ObjLoaderPositionNoGravObj2 ;skip the oam write if bit isnt set
  1084. jsr ObjectProcessGravObjInc
  1085. ObjLoaderPositionNoGravObj2:
  1086. sep #$20
  1087. lda.w ObjEntryType,x ;get object type byte
  1088. bit.b #%00001000
  1089. beq ObjLoaderNoSub ;skip the oam write if bit isnt set
  1090. jsr ObjectProcessSubroutine
  1091. ObjLoaderNoSub:
  1092. rep #$30
  1093. ; stz.b ObjectListPointerCurrent
  1094. plb
  1095. pld
  1096. plp
  1097. rts
  1098. ;upload current frame to vram
  1099. ;get sprite config and lookup transfer type
  1100. CreateObjUploadSpriteFrame:
  1101. php
  1102. sep #$20
  1103. lda.w ObjEntryType2,x
  1104. bit.b #%01000000
  1105. beq CreateObjUploadSpriteFrameDontCancel
  1106. ;don't upload any sprite tiles if bit6 of object type 2 is set. this is used for the music notes and stuff like that where many sprites share the same tiles in order to minimize dma overhead.
  1107. plp
  1108. rts
  1109. CreateObjUploadSpriteFrameDontCancel:
  1110. rep #$31
  1111. lda.w ObjEntryType,x ;get sprite size bit
  1112. and.w #%10
  1113. clc
  1114. asl a ;put into bit3
  1115. asl a
  1116. sta.b TempBuffer
  1117. lda.b ObjSel
  1118. and.w #%11100000
  1119. clc
  1120. lsr a
  1121. lsr a
  1122. lsr a
  1123. lsr a
  1124. lsr a
  1125. ora.b TempBuffer ;add sprite size bit
  1126. sta.b TempBuffer
  1127. asl a ;multiply by 3 to get pointer
  1128. clc
  1129. adc.b TempBuffer
  1130. phx
  1131. tax ;put into x
  1132. lda.l (ObjSizeLUT+BaseAdress),x ;get transfer length and number of bytes to transfer for this sprite
  1133. sta.b TempBuffer+8 ;+8 is length, +9 is transfer number
  1134. lda.l (ObjSizeLUT+BaseAdress+2),x ;get transfer type
  1135. sta.b TempBuffer+14 ;+14 is type
  1136. plx
  1137. ; rep #$31
  1138. ; lda.w #80
  1139. ; sta.b TempBuffer ;this is the number of tiles of one frame
  1140. ; stz.b TempBuffer+1
  1141. ; sep #$20
  1142. clc
  1143. lda.b TempBuffer+8 ; length of one transfer and divide by 32 to get number of h-tiles
  1144. and.w #$ff
  1145. inc a ;increment once to get real length
  1146. lsr a
  1147. lsr a
  1148. lsr a
  1149. lsr a
  1150. lsr a
  1151. sta.b TempBuffer
  1152. lda.b TempBuffer+9 ; transfer number 16bit
  1153. and.w #$ff
  1154. sta.b TempBuffer+2
  1155. lda.w #0
  1156. tay
  1157. CreateObjCalcSizeLoop3:
  1158. cpy.b TempBuffer+2
  1159. beq CreateObjCalcSizeDone3
  1160. iny
  1161. adc.b TempBuffer
  1162. bra CreateObjCalcSizeLoop3
  1163. CreateObjCalcSizeDone3:
  1164. sta.b TempBuffer ;store total number of tiles
  1165. lda.w ObjEntryTilesetFrame,x ;get current tileset frame
  1166. and.w #$ff
  1167. sta.b TempBuffer+2
  1168. lda.w #0
  1169. tay
  1170. CreateObjCalcSizeLoop2:
  1171. cpy.b TempBuffer+2
  1172. beq CreateObjCalcSizeDone2
  1173. iny
  1174. adc.b TempBuffer
  1175. bra CreateObjCalcSizeLoop2
  1176. CreateObjCalcSizeDone2:
  1177. sta.b TempBuffer+2 ;this is the first tile to be uploaded
  1178. lda.w ObjEntryTileset,x ;get tileset number
  1179. and.w #$ff
  1180. sta.b TempBuffer+4 ;multiply with 3
  1181. asl a
  1182. clc
  1183. adc.b TempBuffer+4
  1184. txy
  1185. tax
  1186. lda.l (SpriteTilesetLUT+BaseAdress),x
  1187. sta.b TempBuffer+4
  1188. lda.l (SpriteTilesetLUT+1+BaseAdress),x
  1189. tyx
  1190. ; and.w #$ff
  1191. sta.b TempBuffer+5
  1192. lda.b TempBuffer+2 ;get first tile and multiply with 32 to get actual byte offset
  1193. clc
  1194. asl a
  1195. asl a
  1196. asl a
  1197. asl a
  1198. asl a
  1199. clc
  1200. adc.b TempBuffer+4
  1201. bcc CreateObjCalcSourceNoWrap
  1202. inc.b TempBuffer+6 ;increment bank
  1203. CreateObjCalcSourceNoWrap:
  1204. sta.b TempBuffer+4 ;store transfer source offset
  1205. sep #$20
  1206. lda.w ObjEntryPalConf,x ;get nametable bit(msb of sprites first tile)
  1207. and.b #1
  1208. xba
  1209. lda.w ObjEntryVramTile,x ;get target tile number
  1210. ; and.w #$ff
  1211. rep #$31
  1212. ; clc
  1213. asl a ;multiply by 16(bytesize is 32, but vram is word-aligned)
  1214. asl a
  1215. asl a
  1216. asl a
  1217. clc
  1218. adc.b SpriteTileOffsetVram ;add initial sprite offset
  1219. sta.b TempBuffer+10 ;this is the vram target
  1220. phx ;push object list pointer
  1221. ldx.b DmaFifoPointer
  1222. lda.b TempBuffer+8 ;get transfer length and increase by 1 to get real length 16bit
  1223. and.w #$ff
  1224. inc a
  1225. sta.b TempBuffer+12
  1226. CreateObjUploadTilesLoop:
  1227. rep #$31
  1228. lda.b TempBuffer+14 ;transfer type
  1229. sta.l DmaFifoEntryType,x
  1230. ;store transfer target
  1231. lda.b TempBuffer+10
  1232. sta.l DmaFifoEntryTarget,x ;vram target 2116
  1233. ;store transfer source
  1234. lda.b TempBuffer+4
  1235. sta.l DmaFifoEntrySrcLo,x ;source 4202
  1236. lda.b TempBuffer+5
  1237. sta.l DmaFifoEntrySrcHi,x ;source 4203
  1238. ;store transfer length
  1239. lda.b TempBuffer+12 ;get transfer length. not used except for 8x8 sprites, where it is 32 bytes
  1240. sta.l DmaFifoEntryCount,x ;length 4205
  1241. /*
  1242. ;update vram target pointer:
  1243. lda.b TempBuffer+10
  1244. clc
  1245. adc.w #32*16/2 ;add one 16tile-line to vram target
  1246. sta.b TempBuffer+10
  1247. */
  1248. ;update fifo buffer target:
  1249. txa ;update fifo entry pointer
  1250. clc
  1251. adc.w #DmaFifoEntryLength
  1252. /*
  1253. tax
  1254. ;update source pointer
  1255. lda.b TempBuffer+4
  1256. clc
  1257. adc.b TempBuffer+12
  1258. sta.b TempBuffer+4
  1259. sep #$20
  1260. dec.b TempBuffer+9 ;decrement number of transfers
  1261. bne CreateObjUploadTilesLoop
  1262. ;sprite tile transfer done
  1263. rep #$31
  1264. txa ;update fifo entry pointer
  1265. ; clc
  1266. ; adc.w #DmaFifoEntryLength
  1267. */
  1268. sta.b DmaFifoPointer
  1269. plx
  1270. plp ;fetch object list pointer
  1271. rts
  1272. /*
  1273. ;old version which created multiple transfers in fifo buffer
  1274. CreateObjUploadSpriteFrame:
  1275. CreateObjLookupSpriteSize:
  1276. php
  1277. rep #$31
  1278. lda.w ObjEntryType,x ;get sprite size bit
  1279. and.w #%10
  1280. clc
  1281. asl a ;put into bit3
  1282. asl a
  1283. sta.b TempBuffer
  1284. lda.b ObjSel
  1285. and.w #%11100000
  1286. clc
  1287. lsr a
  1288. lsr a
  1289. lsr a
  1290. lsr a
  1291. lsr a
  1292. ora.b TempBuffer ;add sprite size bit
  1293. asl a ;multiply by 2 to get pointer
  1294. phx
  1295. tax ;put into x
  1296. lda.l (ObjSizeLUT+BaseAdress),x ;get transfer length and number of bytes to transfer for this sprite
  1297. plx
  1298. sta.b TempBuffer+8 ;+8 is length, +9 is transfer number
  1299. ; rep #$31
  1300. ; lda.w #80
  1301. ; sta.b TempBuffer ;this is the number of tiles of one frame
  1302. ; stz.b TempBuffer+1
  1303. ; sep #$20
  1304. clc
  1305. lda.b TempBuffer+8 ; length of one transfer and divide by 32 to get number of h-tiles
  1306. and.w #$ff
  1307. inc a ;increment once to get real length
  1308. lsr a
  1309. lsr a
  1310. lsr a
  1311. lsr a
  1312. lsr a
  1313. sta.b TempBuffer
  1314. lda.b TempBuffer+9 ; transfer number 16bit
  1315. and.w #$ff
  1316. sta.b TempBuffer+2
  1317. lda.w #0
  1318. tay
  1319. CreateObjCalcSizeLoop3:
  1320. cpy.b TempBuffer+2
  1321. beq CreateObjCalcSizeDone3
  1322. iny
  1323. adc.b TempBuffer
  1324. bra CreateObjCalcSizeLoop3
  1325. CreateObjCalcSizeDone3:
  1326. sta.b TempBuffer ;store total number of tiles
  1327. lda.w ObjEntryTilesetFrame,x ;get current tileset frame
  1328. and.w #$ff
  1329. sta.b TempBuffer+2
  1330. lda.w #0
  1331. tay
  1332. ;this must be reprogrammed, too:
  1333. CreateObjCalcSizeLoop2:
  1334. cpy.b TempBuffer+2
  1335. beq CreateObjCalcSizeDone2
  1336. iny
  1337. adc.b TempBuffer
  1338. bra CreateObjCalcSizeLoop2
  1339. CreateObjCalcSizeDone2:
  1340. sta.b TempBuffer+2 ;this is the first tile to be uploaded
  1341. lda.w ObjEntryTileset,x ;get tileset number
  1342. and.w #$ff
  1343. sta.b TempBuffer+4 ;multiply with 3
  1344. asl a
  1345. clc
  1346. adc.b TempBuffer+4
  1347. txy
  1348. tax
  1349. lda.l (SpriteTilesetLUT+BaseAdress),x
  1350. sta.b TempBuffer+4
  1351. lda.l (SpriteTilesetLUT+1+BaseAdress),x
  1352. tyx
  1353. ; and.w #$ff
  1354. sta.b TempBuffer+5
  1355. lda.b TempBuffer+2 ;get first tile and multiply with 32 to get actual byte offset
  1356. clc
  1357. asl a
  1358. asl a
  1359. asl a
  1360. asl a
  1361. asl a
  1362. clc
  1363. adc.b TempBuffer+4
  1364. bcc CreateObjCalcSourceNoWrap
  1365. inc.b TempBuffer+6 ;increment bank
  1366. CreateObjCalcSourceNoWrap:
  1367. sta.b TempBuffer+4 ;store transfer source offset
  1368. sep #$20
  1369. lda.w ObjEntryPalConf,x ;get nametable bit(msb of sprites first tile)
  1370. and.b #1
  1371. xba
  1372. lda.w ObjEntryVramTile,x ;get target tile number
  1373. ; and.w #$ff
  1374. rep #$31
  1375. ; clc
  1376. asl a ;multiply by 16(bytesize is 32, but vram is word-aligned)
  1377. asl a
  1378. asl a
  1379. asl a
  1380. clc
  1381. adc.b SpriteTileOffsetVram ;add initial sprite offset
  1382. sta.b TempBuffer+10 ;this is the vram target
  1383. phx ;push object list pointer
  1384. ldx.b DmaFifoPointer
  1385. lda.b TempBuffer+8 ;get transfer length and increase by 1 to get real length 16bit
  1386. and.w #$ff
  1387. inc a
  1388. sta.b TempBuffer+12
  1389. CreateObjUploadTilesLoop:
  1390. rep #$31
  1391. lda #1 ;transfer type normal dma
  1392. sta.l DmaFifoEntryType,x
  1393. ;store transfer target
  1394. lda.b TempBuffer+10
  1395. sta.l DmaFifoEntryTarget,x ;vram target 2116
  1396. ;store transfer source
  1397. lda.b TempBuffer+4
  1398. sta.l DmaFifoEntrySrcLo,x ;source 4202
  1399. lda.b TempBuffer+5
  1400. sta.l DmaFifoEntrySrcHi,x ;source 4203
  1401. ;store transfer length
  1402. lda.b TempBuffer+12 ;get transfer length
  1403. sta.l DmaFifoEntryCount,x ;length 4205
  1404. ;update vram target pointer:
  1405. lda.b TempBuffer+10
  1406. clc
  1407. adc.w #32*16/2 ;add one 16tile-line to vram target
  1408. sta.b TempBuffer+10
  1409. ;update fifo buffer target:
  1410. txa ;update fifo entry pointer
  1411. clc
  1412. adc.w #DmaFifoEntryLength
  1413. tax
  1414. ;update source pointer
  1415. lda.b TempBuffer+4
  1416. clc
  1417. adc.b TempBuffer+12
  1418. sta.b TempBuffer+4
  1419. sep #$20
  1420. dec.b TempBuffer+9 ;decrement number of transfers
  1421. bne CreateObjUploadTilesLoop
  1422. ;sprite tile transfer done
  1423. rep #$31
  1424. txa ;update fifo entry pointer
  1425. ; clc
  1426. ; adc.w #DmaFifoEntryLength
  1427. sta.b DmaFifoPointer
  1428. plx
  1429. plp ;fetch object list pointer
  1430. rts
  1431. */
  1432. ;first writes a sorted list of object priorities, then transfers these to oam
  1433. ZSortToOamBuffer:
  1434. php
  1435. rep #$31
  1436. sep #$20
  1437. ldx.w #0 ;reset pointer to priority list
  1438. lda.b OamZsortSpriteNumber ;exit immediatly if there are no priority sprites on the current screen. else, it keeps on going on forever
  1439. bne ZSortToOamBufferNoExit
  1440. plp
  1441. rts
  1442. ZSortToOamBufferNoExit:
  1443. sta.b TempBuffer+2 ;counter for inner loop
  1444. sta.b TempBuffer+3 ;counter for outer loop
  1445. stz.b TempBuffer ;clear "highest priority" variable
  1446. ; ldx.w #0 ;reset pointer to priority list
  1447. txy ;reset pointer to zsort list
  1448. ZsortSortingInnerLoop:
  1449. lda.w OamZSortBuffer & $FFFF+4,y ;entry present?
  1450. bpl ZsortNotPresent
  1451. ;sprite present
  1452. lda.w OamZSortBuffer & $FFFF+5,y ;get priority
  1453. cmp.b TempBuffer ;check if bigger than last highest sprite
  1454. bcc ZsortNotBiggest
  1455. sta.b TempBuffer ;new highest priority
  1456. rep #$31
  1457. tya ;get pointer in sprite list, save to sort listing
  1458. sta.w OamZSortObjList & $FFFF,x
  1459. ZsortNotBiggest:
  1460. ZsortNotPresent:
  1461. rep #$31
  1462. tya
  1463. adc.w #OamZSortBufferSize ;get next entry
  1464. tay
  1465. sep #$20
  1466. dec.b TempBuffer+2 ;decrease inner counter
  1467. bne ZsortSortingInnerLoop
  1468. ;sorted through all once
  1469. lda.b OamZsortSpriteNumber
  1470. sta.b TempBuffer+2 ;set counter for inner loop
  1471. stz.b TempBuffer ;clear highest
  1472. ;clear "present"-bit of highest in this round
  1473. phy
  1474. lda.w OamZSortObjList & $FFFF,x ;get pointer to highest
  1475. tay
  1476. lda.w OamZSortBuffer & $FFFF+4,y ;clear "present"-bit
  1477. and.b #$7f
  1478. sta.w OamZSortBuffer & $FFFF+4,y
  1479. ply
  1480. inx ;figure out next one
  1481. inx
  1482. ldy.w #0 ;reset source buffer pointer
  1483. dec.b TempBuffer+3 ;decrease counter
  1484. bne ZsortSortingInnerLoop
  1485. ZSortToOamBufferDoneSorting:
  1486. ; lda.b OamZsortSpriteNumber
  1487. stz.b TempBuffer+2 ;clear pointer in priority list, counter
  1488. ldx.b OamBufferPointer ;get oam pointer, write after priorityless sprites
  1489. ; ldy.w #0
  1490. ZSortWriteToOamLoop:
  1491. rep #$31 ;get pointer to current priority list entry
  1492. lda.b TempBuffer+2
  1493. and.w #$ff
  1494. tay
  1495. lda.w OamZSortObjList & $FFFF,y ;get first pointer
  1496. tay
  1497. ;copy data from zbuffer to oam buffer
  1498. lda.w OamZSortBuffer & $FFFF,y
  1499. sta.w OamBuffer & $ffff,x ;store in oam buffer
  1500. lda.w OamZSortBuffer & $FFFF+2,y
  1501. sta.w OamBuffer & $ffff+2,x ;store in oam buffer
  1502. phx
  1503. phy
  1504. txa
  1505. and.w #$01f0 ;get byte target of size buffer
  1506. ; and.w #$0100 ;get byte target of size buffer
  1507. ; xba ;divide by 16
  1508. lsr a ;divide by 16
  1509. lsr a
  1510. lsr a
  1511. lsr a
  1512. sta.b TempBuffer ;this is the 16bit pointer to the current byte in size buffer
  1513. ;calculate bit offset in spritesize buffer:
  1514. txa
  1515. clc
  1516. and.w #$c ;get target bits of size buffer
  1517. lsr a ;shift right twice to get correct jump offset
  1518. tax
  1519. lda.w OamZSortBuffer & $FFFF+4,y
  1520. ldy.b TempBuffer
  1521. and.w #%11
  1522. jmp (PrioObjectProcessorSizeTableJTbl,x)
  1523. PrioObjectProcessorSizeTableJTbl:
  1524. .dw PrioObjProcSizeJtblBit0
  1525. .dw PrioObjProcSizeJtblBit1
  1526. .dw PrioObjProcSizeJtblBit2
  1527. .dw PrioObjProcSizeJtblBit3
  1528. PrioObjProcSizeJtblBit3:
  1529. asl a
  1530. asl a
  1531. PrioObjProcSizeJtblBit2:
  1532. asl a
  1533. asl a
  1534. PrioObjProcSizeJtblBit1:
  1535. asl a
  1536. asl a
  1537. PrioObjProcSizeJtblBit0:
  1538. ora.w OamPriorityBuffer & $ffff,y ;store in corresponding bits/bytes
  1539. sta.w OamPriorityBuffer & $ffff,y ;store in corresponding bits/bytes
  1540. ply
  1541. plx
  1542. lda.w #0
  1543. ; sta.w OamZSortBuffer & $FFFF,y ;clear zsort buffer entries right after use so we dont have to clear the whole list each frame
  1544. ; sta.w OamZSortBuffer & $FFFF+2,y
  1545. ; sta.w OamZSortBuffer & $FFFF+3,y
  1546. inx
  1547. inx
  1548. inx
  1549. inx
  1550. sep #$20
  1551. lda.b TempBuffer+2 ;process next entry
  1552. inc a
  1553. inc a
  1554. sta.b TempBuffer+2 ;process next entry
  1555. lsr a
  1556. cmp.b OamZsortSpriteNumber ;done copying?
  1557. bne ZSortWriteToOamLoop
  1558. stx.b OamBufferPointer
  1559. plp
  1560. rts
  1561. ;in: a,16bit: desired scanline to draw sprite to.
  1562. ;out: y,16bit: relative pointer to correct entry in zsort buffer
  1563. ObjectZSortGetFreeSlot:
  1564. ; php
  1565. ; rep #$31
  1566. ; tya
  1567. sta.b TempBuffer ;get desired scanline
  1568. asl a ;multiply by 5 to get pointer into zsort buffer
  1569. asl a
  1570. clc
  1571. adc.b TempBuffer
  1572. tay
  1573. ObjectZSortGetFreeSlotLoop:
  1574. lda.w OamZSortBuffer & $FFFF,y
  1575. beq ObjectZSortGetFreeSlotDone
  1576. tya
  1577. sec ;increase scanline by one if theres a sprite here already
  1578. sbc.w #OamZSortBufferSize
  1579. bcc ObjZSortGetSlotUnderrun
  1580. tay
  1581. bra ObjectZSortGetFreeSlotLoop
  1582. ObjZSortGetSlotUnderrun:
  1583. ldy.w #210*OamZSortBufferSize ;select max entry
  1584. bra ObjectZSortGetFreeSlotLoop
  1585. ObjectZSortGetFreeSlotDone:
  1586. ; tya
  1587. ; clc
  1588. ; adc.w #OamZSortBuffer ;make this a direct pointer
  1589. ; tay
  1590. ; plp
  1591. rts
  1592. ObjProcScreenBound:
  1593. sep #$20
  1594. lda.w ObjEntryZDisplacement,x ;calculate priority?
  1595. ; and.w #$ff ;only get z-priority
  1596. beq ObjProcScreenBoundNoPriorityCalc
  1597. ;****************************************************
  1598. ;write sprite to oam zsort buffer instead
  1599. ldy.b OamZsortBufferPointer ;get buffer pointer
  1600. ; rep #$31
  1601. lda.w ObjEntryType2,x ;pseudo-3d sprite?
  1602. bmi ObjProc3dSprite
  1603. lda.w ObjEntryZDisplacement,x ;store z
  1604. sta.w OamZSortBuffer & $ffff+5,y
  1605. rep #$31
  1606. lda.w ObjEntryXPos,x ;get xy-coordinates
  1607. lsr a ;remove subpixel precision
  1608. lsr a
  1609. lsr a
  1610. lsr a
  1611. ; sep #$20
  1612. sta.w OamZSortBuffer & $ffff,y ;store x coordinate
  1613. ; rep #$31
  1614. lda.w ObjEntryYPos,x ;get xy-coordinates
  1615. lsr a ;remove subpixel precision
  1616. lsr a
  1617. lsr a
  1618. lsr a
  1619. sep #$20
  1620. sta.w OamZSortBuffer & $ffff+1,y ;store x coordinate
  1621. jmp ObjProcZsortWriteExit
  1622. ObjProc3dSprite:
  1623. lda.w ObjEntryZDisplacement,x
  1624. eor.b #$ff ;invert priority for 3d sprites
  1625. sta.w OamZSortBuffer & $ffff+5,y
  1626. rep #$31
  1627. lda.w ObjEntryXPos,x ;get xy-coordinates
  1628. lsr a ;divide by 16, high precision position
  1629. lsr a
  1630. lsr a
  1631. lsr a
  1632. ; lsr a
  1633. ; lsr a
  1634. sep #$20
  1635. sta.w OamZSortBuffer & $ffff,y ;store x coordinate
  1636. rep #$31
  1637. lda.w ObjEntryYPos,x ;get xy-coordinates
  1638. lsr a ;divide by 16, high precision position
  1639. lsr a
  1640. lsr a
  1641. lsr a
  1642. ; lsr a
  1643. ; lsr a
  1644. sep #$20
  1645. sta.w OamZSortBuffer & $ffff+1,y ;store x coordinate
  1646. jmp ObjProcZsortWriteExit
  1647. ObjProcScreenBoundNoPriorityCalc:
  1648. rep #$31
  1649. lda.w ObjEntryXPos,x ;get xy-coordinates
  1650. lsr a ;remove subpixel precision
  1651. lsr a
  1652. lsr a
  1653. lsr a
  1654. sta.w OamBuffer & $ffff,y ;store x coordinate
  1655. lda.w ObjEntryYPos,x ;get xy-coordinates
  1656. lsr a ;remove subpixel precision
  1657. lsr a
  1658. lsr a
  1659. lsr a
  1660. sep #$20
  1661. sta.w OamBuffer & $ffff+1,y ;store y coordinate
  1662. jmp ObjProcDrawConfig
  1663. ObjectSingleSpriteToOam:
  1664. ;dont upload directly to sprite buffer, but put sprite in a seperate 256entry-list according to y+ydisplacement value so the sprites get z-sorted. ;upload sprite to oam buffer:
  1665. ; rep #$31
  1666. ldy.b OamBufferPointer ;get pointer to current oam buffer entry
  1667. lda.w ObjEntryType,x
  1668. bit.w #%00100000 ;check if screenbound
  1669. bne ObjProcScreenBound
  1670. lda.w ObjEntryZDisplacement,x
  1671. and.w #$ff
  1672. beq ObjProcNoPriorityCalc
  1673. ObjProcPriorityCalc:
  1674. ;****************************************************
  1675. ;write sprite to oam zsort buffer instead
  1676. ldy.b OamZsortBufferPointer ;get buffer pointer
  1677. lda.w ObjEntryYPos,x ;get xy-coordinates
  1678. lsr a ;remove subpixel precision
  1679. lsr a
  1680. lsr a
  1681. lsr a
  1682. sta.b TempBuffer
  1683. lda.w ObjEntryZDisplacement,x
  1684. and.w #$ff
  1685. clc
  1686. ; adc.w ObjEntryYPos,x ;get xy-coordinates
  1687. adc.b TempBuffer
  1688. sec
  1689. sbc.b ScreenPixelPositionY ;substract screen position to get sprite position on screen. before doing this, we made sure the sprite is actually onscreen.
  1690. sep #$20
  1691. sta.w OamZSortBuffer & $ffff+5,y
  1692. rep #$31
  1693. lda.w ObjEntryXPos,x ;get xy-coordinates
  1694. ; clc
  1695. lsr a ;remove subpixel precision
  1696. lsr a
  1697. lsr a
  1698. lsr a
  1699. ; adc.w #16 ;add 16 because of left border
  1700. sec
  1701. sbc.w ObjEntryXDisplacement,x
  1702. sec
  1703. sbc.b ScreenPixelPositionX ;substract screen position to get sprite position on screen. before doing this, we made sure the sprite is actually onscreen.
  1704. sta.w OamZSortBuffer & $ffff,y ;store x coordinate
  1705. bcs ObjProcPriorSprNoWrap1 ;if sprite wraps around left screen edge, carry is clear
  1706. lda.w ObjEntryType,x ;set x-position sign bit if sprite wraps around the edge
  1707. ora.w #%1
  1708. sta.w ObjEntryType,x
  1709. bra ObjProcPriorSprWrapDone
  1710. ObjProcPriorSprNoWrap1:
  1711. lda.w ObjEntryType,x ;clear x-position sign bit if sprite wraps around the edge
  1712. and.w #$fffe
  1713. sta.w ObjEntryType,x
  1714. ObjProcPriorSprWrapDone:
  1715. lda.w ObjEntryYPos,x ;get xy-coordinates
  1716. lsr a ;remove subpixel precision
  1717. lsr a
  1718. lsr a
  1719. lsr a
  1720. sec
  1721. sbc.b ScreenPixelPositionY ;substract screen position to get sprite position on screen. before doing this, we made sure the sprite is actually onscreen.
  1722. sec
  1723. sbc.w ObjEntryYDisplacement,x
  1724. sep #$20
  1725. sta.w OamZSortBuffer & $ffff+1,y ;store x coordinate
  1726. ObjProcZsortWriteExit:
  1727. lda.w ObjEntryType,x ;get size/x-sign bits
  1728. and.b #%11
  1729. ora.b #$80 ;set "present" bit
  1730. sta.w OamZSortBuffer & $ffff+4,y
  1731. inc.b OamZsortSpriteNumber ;increment number of sortable sprites
  1732. rep #$31
  1733. lda.w ObjEntryVramTile,x ;starting tile and config
  1734. sta.w OamZSortBuffer & $ffff+2,y ;store tile and config
  1735. tya ;calc new value for buffer
  1736. adc.w #OamZSortBufferSize
  1737. sta.b OamZsortBufferPointer
  1738. rts
  1739. ;****************************************************
  1740. ObjProcNoPriorityCalc:
  1741. lda.w ObjEntryXPos,x ;get xy-coordinates
  1742. lsr a ;remove subpixel precision
  1743. lsr a
  1744. lsr a
  1745. lsr a
  1746. clc
  1747. ; adc.w #16 ;add 16 because of left border
  1748. sec
  1749. sbc.w ObjEntryXDisplacement,x
  1750. sec
  1751. sbc.b ScreenPixelPositionX ;substract screen position to get sprite position on screen. before doing this, we made sure the sprite is actually onscreen.
  1752. sta.w OamBuffer & $ffff,y ;store x coordinate
  1753. bcs ObjProcSprNoWrap1 ;if sprite wraps around left screen edge, carry is clear
  1754. lda.w ObjEntryType,x ;set x-position sign bit if sprite wraps around the edge
  1755. ora.w #%1
  1756. sta.w ObjEntryType,x
  1757. bra ObjProcSprWrapDone
  1758. ObjProcSprNoWrap1:
  1759. lda.w ObjEntryType,x ;clear x-position sign bit if sprite wraps around the edge
  1760. and.w #$fffe
  1761. sta.w ObjEntryType,x
  1762. ObjProcSprWrapDone:
  1763. lda.w ObjEntryYPos,x ;get xy-coordinates
  1764. lsr a ;remove subpixel precision
  1765. lsr a
  1766. lsr a
  1767. lsr a
  1768. sec
  1769. sbc.b ScreenPixelPositionY ;substract screen position to get sprite position on screen. before doing this, we made sure the sprite is actually onscreen.
  1770. sec
  1771. sbc.w ObjEntryYDisplacement,x
  1772. sep #$20
  1773. sta.w OamBuffer & $ffff+1,y ;store x coordinate
  1774. ObjProcDrawConfig:
  1775. ;calculate byte offset in spritesize buffer:
  1776. rep #$31
  1777. ; ldy.b OamBufferPointer ;get pointer to current oam buffer entry
  1778. phx
  1779. phy
  1780. tya
  1781. and.w #$1f0 ;get byte target of size buffer
  1782. lsr a
  1783. lsr a
  1784. lsr a
  1785. lsr a
  1786. sta.b TempBuffer ;this is the 16bit pointer to the current byte in size buffer
  1787. ;calculate bit offset in spritesize buffer:
  1788. tya
  1789. clc
  1790. and.w #$c ;get target bits of size buffer
  1791. lsr a ;shift right twice to get correct jump offset
  1792. tay
  1793. lda.w ObjEntryType,x ;get size/x-sign bits
  1794. tyx
  1795. ldy.b TempBuffer
  1796. and.w #%11
  1797. jmp (ObjectProcessorSizeTableJTbl,x)
  1798. ObjectProcessorSizeTableJTbl:
  1799. .dw ObjProcSizeJtblBit0
  1800. .dw ObjProcSizeJtblBit1
  1801. .dw ObjProcSizeJtblBit2
  1802. .dw ObjProcSizeJtblBit3
  1803. ObjProcSizeJtblBit3:
  1804. asl a
  1805. asl a
  1806. ObjProcSizeJtblBit2:
  1807. asl a
  1808. asl a
  1809. ObjProcSizeJtblBit1:
  1810. asl a
  1811. asl a
  1812. ObjProcSizeJtblBit0:
  1813. ora.w OamPriorityBuffer & $ffff,y ;store in corresponding bits/bytes
  1814. sta.w OamPriorityBuffer & $ffff,y ;store in corresponding bits/bytes
  1815. ply
  1816. plx
  1817. ; sep #$20
  1818. rep #$31
  1819. lda.w ObjEntryVramTile,x ;starting tile and config
  1820. sta.w OamBuffer & $ffff+2,y ;store tile and config
  1821. iny ;move pointer to next tile
  1822. iny
  1823. iny
  1824. iny
  1825. sty.b OamBufferPointer ;store new buffer to next oam object
  1826. rts
  1827. InitOam:
  1828. php
  1829. jsr ClearOamBuffer
  1830. jsr ClearOamPriorityBuffer
  1831. jsr ClearObjectList
  1832. sep #$20
  1833. stz.w GravObjectCounter ;reset amount of gravity objects
  1834. stz.b NMIOamUploadFlag ;clear this flag so that oam processor is executed at least once (in case irq oam uploader fucks up)
  1835. .IF DEBUG == 1
  1836. lda.b #1 ;create cpu-usage object in every scene if debug is enabled
  1837. jsr CreateObject
  1838. .endif
  1839. plp
  1840. rts
  1841. ClearOamPriorityBuffer:
  1842. php
  1843. rep #$31
  1844. sep #$20
  1845. lda.b #0 ;clear word: $0000
  1846. ldy.w #$20
  1847. ldx.w #OamPriorityBuffer&$ffff
  1848. jsr ClearWRAM
  1849. plp
  1850. rts
  1851. /*
  1852. ClearOamPriorityBuffer:
  1853. php
  1854. rep #$31
  1855. lda.w #$0000 ;clear with y-position at line 255
  1856. ldx.w #$0020
  1857. ClearOamPriorityBufferLoop:
  1858. sta.l (OamPriorityBuffer &$ffff + $7e0000-2),x
  1859. dex
  1860. dex
  1861. bne ClearOamPriorityBufferLoop
  1862. plp
  1863. rts
  1864. */
  1865. ClearOamBufferPart:
  1866. /*
  1867. php
  1868. rep #$31
  1869. lda.w #$c900 ;clear with y-position at line 201
  1870. ldx.b OamBufferPointer
  1871. bra ClearOamBufferLoop
  1872. */
  1873. php
  1874. rep #$31
  1875. sep #$20
  1876. lda.b #3 ;clear word: $0000
  1877. ldy.b OamBufferPointer
  1878. beq ClearOamBufferPartNoTrans ;need to do this, else $ffff long transfer occurs
  1879. ldx.w #OamBuffer&$ffff
  1880. jsr ClearWRAM
  1881. ClearOamBufferPartNoTrans:
  1882. rep #$31
  1883. stz.b OamBufferPointer
  1884. stz.b OamZsortBufferPointer
  1885. stz.b OamZsortSpriteNumber
  1886. plp
  1887. rts
  1888. ClearOamBuffer:
  1889. /*
  1890. php
  1891. rep #$31
  1892. lda.w #$c900 ;clear with y-position at line 201
  1893. ldx.w #$0200
  1894. ClearOamBufferLoop:
  1895. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1896. dex
  1897. dex
  1898. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1899. dex
  1900. dex
  1901. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1902. dex
  1903. dex
  1904. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1905. dex
  1906. dex
  1907. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1908. dex
  1909. dex
  1910. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1911. dex
  1912. dex
  1913. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1914. dex
  1915. dex
  1916. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1917. dex
  1918. dex
  1919. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1920. dex
  1921. dex
  1922. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1923. dex
  1924. dex
  1925. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1926. dex
  1927. dex
  1928. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1929. dex
  1930. dex
  1931. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1932. dex
  1933. dex
  1934. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1935. dex
  1936. dex
  1937. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1938. dex
  1939. dex
  1940. sta.l (OamBuffer &$ffff + $7e0000-2),x
  1941. dex
  1942. dex
  1943. bpl ClearOamBufferLoop
  1944. */
  1945. php
  1946. rep #$31
  1947. sep #$20
  1948. lda.b #3 ;clear word: $0000
  1949. ldy.w #$200
  1950. ldx.w #OamBuffer&$ffff
  1951. jsr ClearWRAM
  1952. rep #$31
  1953. stz.b OamBufferPointer
  1954. stz.b OamZsortBufferPointer
  1955. stz.b OamZsortSpriteNumber
  1956. plp
  1957. rts
  1958. ClearColObjList:
  1959. php
  1960. rep #$31
  1961. sep #$20
  1962. lda.b #0 ;clear word: $0000
  1963. ldy.w #ColObjFileSize*32 ;old one was: ldx.w #ColObjFileSize*32-2, maybe -2 needed?
  1964. ldx.w #ColObjList&$ffff
  1965. jsr ClearWRAM
  1966. plp
  1967. rts
  1968. /*
  1969. php
  1970. rep #$31
  1971. lda.w #0 ;clear with y-position at line 201
  1972. ldx.w #ColObjFileSize*32-2
  1973. ClearColObjListLoop:
  1974. sta.l (ColObjList &$ffff + $7e0000-2),x
  1975. dex
  1976. dex
  1977. bne ClearColObjListLoop
  1978. stz.w ColObjListPointer
  1979. plp
  1980. rts
  1981. */
  1982. ClearZBuffer:
  1983. php
  1984. rep #$31
  1985. sep #$20
  1986. lda.b #0 ;clear word: $0000
  1987. ldy.w #OamZSortBufferSize*256
  1988. ldx.w #OamZSortBuffer&$ffff
  1989. jsr ClearWRAM
  1990. plp
  1991. rts
  1992. /*
  1993. php
  1994. rep #$31
  1995. lda.w #0 ;clear with y-position at line 201
  1996. ldx.w #OamZSortBufferSize*256
  1997. ClearZBufferLoop:
  1998. sta.l (OamZSortBuffer & $ffff + $7e0000-2),x
  1999. dex
  2000. dex
  2001. bne ClearZBufferLoop
  2002. ; stz.w ColObjListPointer
  2003. plp
  2004. rts
  2005. */
  2006. ClearObjectList:
  2007. php
  2008. rep #$31
  2009. sep #$20
  2010. lda.b #0 ;clear word: $0000
  2011. ldy.w #ObjectFileSize*64
  2012. ldx.w #ObjectList&$ffff
  2013. jsr ClearWRAM
  2014. plp
  2015. rts
  2016. /*
  2017. php
  2018. rep #$31
  2019. lda.w #$0000
  2020. ldx.w #ObjectFileSize*64
  2021. ClearObjectListLoop:
  2022. sta.l (ObjectList &$ffff + $7e0000-2),x
  2023. dex
  2024. dex
  2025. bne ClearObjectListLoop
  2026. plp
  2027. rts
  2028. */
  2029. ;in: a,16bit: type of objects to delete
  2030. ;uses TempBuffer
  2031. ;takes around 11 scanlines
  2032. SeekDeleteObjects:
  2033. php
  2034. rep #$31
  2035. sta.b TempBuffer ;store 16bit compare number
  2036. ldx.w #0
  2037. SeekDeleteObjectsLoop:
  2038. lda.l ObjEntryObjectNumber+$7e0000,x ;get object number
  2039. cmp.b TempBuffer
  2040. bne SeekDeleteObjectsNoMatch
  2041. lda.w #0
  2042. sta.l ObjEntryType+$7e0000,x ;delete object if number matches.
  2043. SeekDeleteObjectsNoMatch:
  2044. txa
  2045. clc
  2046. adc.w #ObjectFileSize ;goto next entry
  2047. tax
  2048. cpx.w #ObjectFileSize*64 ;check all 64 entries.
  2049. bne SeekDeleteObjectsLoop
  2050. plp
  2051. rts
  2052. ;in: a,16bit: type of object to seek
  2053. ;uses TempBuffer
  2054. ;takes around 11 scanlines max.
  2055. ;searches for first object of selected type.
  2056. ;returns relative pointer to object in x
  2057. ;if object was not found, carry is set
  2058. SeekObject:
  2059. php
  2060. rep #$31
  2061. sta.b TempBuffer ;store 16bit compare number
  2062. ldx.w #0
  2063. SeekObjectLoop:
  2064. lda.l ObjEntryObjectNumber+$7e0000,x ;get object number
  2065. cmp.b TempBuffer
  2066. bne SeekObjectNoMatch
  2067. ;match found:
  2068. plp
  2069. clc
  2070. rts
  2071. SeekObjectNoMatch:
  2072. txa
  2073. clc
  2074. adc.w #ObjectFileSize ;goto next entry
  2075. tax
  2076. cpx.w #ObjectFileSize*64 ;check all 64 entries.
  2077. bne SeekObjectLoop
  2078. plp
  2079. sec
  2080. rts
  2081. ;same as above, but don't reset pointer into obj list. useful for finding multiple objects of the same type
  2082. SeekObjectContinue:
  2083. php
  2084. rep #$31
  2085. sta.b TempBuffer
  2086. bra SeekObjectLoop
  2087. ObjVectorMoveHandler:
  2088. php
  2089. rep #$31
  2090. sep #$20
  2091. ldx.b ObjectListPointerCurrent
  2092. lda.w ObjEntryVectorSpeed,x
  2093. bmi ObjVectorSpeedMet
  2094. and.b #%111111
  2095. sta.b TempBuffer
  2096. lda.w ObjEntryVectorTarSpeed,x
  2097. pha
  2098. and.b #%111111
  2099. sta.b TempBuffer+1
  2100. pla ;get speed change mode (upper 2 bits) and use it as pointer to jump LUT
  2101. rol a
  2102. rol a
  2103. rol a
  2104. asl a
  2105. rep #$31
  2106. and.w #%110
  2107. phx
  2108. tax
  2109. sep #$20
  2110. jsr (ObjVectorSpeedChangeModeLUT,x)
  2111. plx
  2112. sta.b TempBuffer+2 ;store inc/dec value
  2113. ;speed inc/dec
  2114. lda.b TempBuffer+1
  2115. cmp.b TempBuffer ;check if target speed is bigger than actual speed
  2116. bcs ObjVectorTarSpeedBiggerLinear
  2117. ;target speed is lower than actual speed
  2118. lda.b TempBuffer
  2119. sec
  2120. sbc.b TempBuffer+2 ;#%1000 ;decrease speed by one full unit
  2121. cmp.b TempBuffer+1 ;has actual speed become => target?
  2122. bmi ObjVectorTarSpeedMetLin ;has speed wrapped around to $ff? if yes, target has also been reached(only needed if target is smaller than 1.0)
  2123. bcs ObjVectorTarSpeedNotMetLinInc
  2124. ;target speed met:
  2125. bra ObjVectorTarSpeedMetLin
  2126. ;target speed is bigger than actual speed
  2127. ObjVectorTarSpeedBiggerLinear:
  2128. lda.b TempBuffer
  2129. clc
  2130. adc.b TempBuffer+2 ;#%1000 ;increase speed by one full unit
  2131. cmp.b TempBuffer+1 ;has actual speed become => target?
  2132. bcc ObjVectorTarSpeedNotMetLinInc
  2133. ObjVectorTarSpeedMetLin:
  2134. lda.b TempBuffer+1 ;if target speed has been met or exceeded, write target speed into current and set "speed met"-flag.
  2135. and.b #%111111
  2136. ora.b #$80
  2137. ObjVectorTarSpeedNotMetLinInc:
  2138. sta.w ObjEntryVectorSpeed,x
  2139. ObjVectorSpeedMet:
  2140. rep #$31
  2141. ldx.b ObjectListPointerCurrent
  2142. lda.w ObjEntryVectorDir-1,x
  2143. bmi ObjVectorTargetDirMet
  2144. asl a
  2145. asl a
  2146. and.w #%1111110000000000 ;put into high byte
  2147. sta.b TempBuffer
  2148. lda.w ObjEntryVectorTurnSpeed,x ;get subpixel precision, 5bits starting at bit3
  2149. asl a ;put into bits 5-9
  2150. asl a
  2151. and.w #%0000001111100000 ;mask off unwanted stuff
  2152. ora.b TempBuffer
  2153. sta.b TempBuffer
  2154. lda.w ObjEntryVectorTarDir,x
  2155. pha
  2156. xba
  2157. asl a
  2158. asl a
  2159. and.w #%1111110000000000 ;put into high byte
  2160. sta.b TempBuffer+2
  2161. pla
  2162. lsr a
  2163. lsr a ;get speed change mode (upper 2 bits) and use it as pointer to jump LUT
  2164. lsr a
  2165. lsr a
  2166. lsr a
  2167. and.w #%110
  2168. phx
  2169. tax
  2170. jsr (ObjVectorDirChangeModeLUT,x)
  2171. plx
  2172. sta.b TempBuffer+4 ;store inc/dec value
  2173. ; lda.b TempBuffer+1
  2174. ; cmp.b TempBuffer ;check if target speed is bigger than actual speed
  2175. lda.w ObjEntryVectorDir,x
  2176. bit.w #%01000000
  2177. bne ObjVectorRotateClockwise ;bcs ObjVectorTarSpeedBiggerLinear
  2178. ;rotate anti-clockwise to meet target dir
  2179. lda.b TempBuffer ;get current angle
  2180. cmp.b TempBuffer+2 ;is target angle smaller? (=must 0 be crossed to reach target?)
  2181. bcs AntiClockwiseNoZeroCross
  2182. ;must cross 0 to reach target
  2183. sec
  2184. sbc.b TempBuffer+4 ;substract speed value
  2185. bcs AntiClockwiseTargetNotMet ;if 0 wasn't passed, target value couldn't have possibly been reached
  2186. cmp.b TempBuffer+2 ;compare target to new angle
  2187. bcc AntiClockwiseTargetMet ;target met if new angle is smaller than old
  2188. bra AntiClockwiseTargetNotMet
  2189. ObjVectorTargetDirMet:
  2190. jmp ObjVectorTargetDirMetLong
  2191. AntiClockwiseNoZeroCross:
  2192. sec
  2193. sbc.b TempBuffer+4 ;substract speed value
  2194. bcc AntiClockwiseTargetMet ;target met if angle wraps around through 0.
  2195. cmp.b TempBuffer+2 ;compare target to new angle
  2196. bcc AntiClockwiseTargetMet ;target met if new angle is smaller than old
  2197. bra AntiClockwiseTargetNotMet
  2198. ObjVectorRotateClockwise:
  2199. ;rotate clockwise to meet target dir
  2200. lda.b TempBuffer ;get current angle
  2201. cmp.b TempBuffer+2 ;is target angle smaller? (=must 0 be crossed to reach target?)
  2202. bcc ClockwiseNoZeroCross
  2203. ;must cross 0 to reach target
  2204. clc
  2205. adc.b TempBuffer+4 ;add speed value
  2206. bcc AntiClockwiseTargetNotMet ;if 0 wasn't passed, target value couldn't have possibly been reached
  2207. cmp.b TempBuffer+2 ;compare target to new angle
  2208. bcs AntiClockwiseTargetMet ;target met if new angle is bigger than old
  2209. bra AntiClockwiseTargetNotMet
  2210. ClockwiseNoZeroCross:
  2211. clc
  2212. adc.b TempBuffer+4 ;add speed value
  2213. bcs AntiClockwiseTargetMet ;target met if angle wraps around through 0.
  2214. cmp.b TempBuffer+2 ;compare target to new angle
  2215. bcs AntiClockwiseTargetMet ;target met if new angle is bigger than old
  2216. bra AntiClockwiseTargetNotMet
  2217. AntiClockwiseTargetMet:
  2218. lda.b TempBuffer+2 ;target met, set target without subpixel as new angle
  2219. and.w #%1111110000000000
  2220. lsr a
  2221. lsr a
  2222. ora.w #$8000 ;set "target met" flag
  2223. bra AntiClockwiseTargetWrite
  2224. AntiClockwiseTargetNotMet:
  2225. and.w #%1111111111100000 ;angle with subpixel precision
  2226. lsr a
  2227. lsr a
  2228. AntiClockwiseTargetWrite:
  2229. sta.b TempBuffer ;save new angle
  2230. sep #$20
  2231. lda.w ObjEntryVectorDir,x
  2232. and.b #%01000000
  2233. ora.b TempBuffer+1 ;save back new direction
  2234. sta.w ObjEntryVectorDir,x
  2235. lda.w ObjEntryVectorTurnSpeed,x
  2236. and.b #%111
  2237. ora.b TempBuffer
  2238. sta.w ObjEntryVectorTurnSpeed,x
  2239. ObjVectorTargetDirMetLong:
  2240. rep #$31 ;get current position in vector angle, 16 max
  2241. lda.w ObjEntryType2,x
  2242. and.w #$f
  2243. sta.b TempBuffer
  2244. lda.w ObjEntryVectorTurnSpeed,x ;get subpixel precision for later usage
  2245. and.w #%111
  2246. sta.b TempBuffer+2
  2247. lda.w ObjEntryVectorSpeed,x
  2248. and.w #%111111
  2249. pha
  2250. lda.w ObjEntryVectorDir,x ;get direction, multiply with 32, add current position in angle
  2251. and.w #%111111
  2252. asl a
  2253. asl a
  2254. asl a
  2255. asl a
  2256. asl a
  2257. adc.b TempBuffer
  2258. clc
  2259. adc.w #VectorAngleCodeLUT
  2260. tax ;source offset
  2261. ldy.w #VectorAngleSMCode&$ffff ;target offset
  2262. pla ;get vector speed
  2263. clc
  2264. adc.b TempBuffer+2 ;add sub-pixel buffer
  2265. pha
  2266. and.w #%111
  2267. sta.b TempBuffer+2 ;save back for next frame
  2268. pla
  2269. lsr a ;remove sub-pixel precision
  2270. lsr a
  2271. lsr a
  2272. and.w #%111
  2273. pha
  2274. beq VectorAngleNoSpeed ;triggers when vector move distance is lower than 1 and prevents ram thrashing.
  2275. dec a ;decrease length by one for mvn
  2276. .db $54 ;MVN
  2277. .db $7e ;destination bank
  2278. .db :VectorAngleCodeLUT+$c0 ;target bank
  2279. lda.w #$6b ;rtl opcode
  2280. sta.w $0,y ;store after sm-code. y conveniently points to the byte after the last one transferred by MVN.
  2281. ldx.b ObjectListPointerCurrent
  2282. lda.w ObjEntryYPos,x
  2283. lsr a ;remove subpixel precision
  2284. lsr a
  2285. lsr a
  2286. lsr a
  2287. tay
  2288. lda.w ObjEntryXPos,x
  2289. lsr a ;remove subpixel precision
  2290. lsr a
  2291. lsr a
  2292. lsr a
  2293. phx
  2294. tax
  2295. jsl VectorAngleSMCode
  2296. txa
  2297. plx
  2298. asl a ;add subpixel precision
  2299. asl a
  2300. asl a
  2301. asl a
  2302. sta.w ObjEntryXPos,x
  2303. tya
  2304. asl a ;add subpixel precision
  2305. asl a
  2306. asl a
  2307. asl a
  2308. sta.w ObjEntryYPos,x
  2309. VectorAngleNoSpeed:
  2310. pla ;update vector angle position
  2311. clc
  2312. adc.b TempBuffer
  2313. and.w #$f
  2314. sta.b TempBuffer
  2315. sep #$20
  2316. ldx.b ObjectListPointerCurrent
  2317. lda.w ObjEntryType2,x ;update vector angle position
  2318. and.b #%11110000
  2319. ora.b TempBuffer
  2320. sta.w ObjEntryType2,x
  2321. lda.w ObjEntryVectorTurnSpeed,x ;update vector speed sub-pixel position
  2322. and.b #%11111000
  2323. ora.b TempBuffer+2
  2324. sta.w ObjEntryVectorTurnSpeed,x
  2325. plp
  2326. rts
  2327. ObjVectorSpeedChangeModeLUT:
  2328. .dw ObjVectorSpeedChangeDirect
  2329. .dw ObjVectorSpeedChangeLinearSlow
  2330. .dw ObjVectorSpeedChangeLinearFast
  2331. .dw ObjVectorSpeedChangeLinearSmooth
  2332. ObjVectorSpeedChangeDirect:
  2333. lda.b #$40
  2334. rts
  2335. ObjVectorSpeedChangeLinearSlow:
  2336. lda.b #1 ;smallest possible unit, takes 64 frames max to reach target speed
  2337. rts
  2338. ObjVectorSpeedChangeLinearFast:
  2339. lda.b #8 ;one full unit, takes 8 frames max to reach target speed
  2340. rts
  2341. ;smooth: divide the difference between target and current speed by two and use that to alter the current speed
  2342. ObjVectorSpeedChangeLinearSmooth:
  2343. lda.b TempBuffer+1
  2344. sec
  2345. sbc.b TempBuffer ;check if target speed is bigger than actual speed
  2346. bcc ObjVectorTarSpeedBiggerSmooth
  2347. bra ObjVectorTarSpeedSmooth
  2348. ObjVectorTarSpeedBiggerSmooth:
  2349. lda.b TempBuffer
  2350. sec
  2351. sbc.b TempBuffer+1
  2352. ObjVectorTarSpeedSmooth:
  2353. lsr a
  2354. bne ObjVectorTarSpeedMinOKSmooth
  2355. lda.b #1 ;minimum speed: 1
  2356. rts
  2357. ObjVectorTarSpeedMinOKSmooth:
  2358. cmp.b #8
  2359. bcc ObjVectorTarSpeedMaxOKSmooth
  2360. lda.b #8 ;maximum speed: 8
  2361. ObjVectorTarSpeedMaxOKSmooth:
  2362. rts
  2363. ObjVectorDirChangeModeLUT:
  2364. .dw ObjVectorDirChangeDirect
  2365. .dw ObjVectorDirChangeLinearSlow
  2366. .dw ObjVectorDirChangeLinearFast
  2367. .dw ObjVectorDirChangeLinearSmooth
  2368. ObjVectorDirChangeDirect:
  2369. lda.w #$fc00
  2370. rts
  2371. ObjVectorDirChangeLinearSlow:
  2372. lda.w #$20 ;smallest possible unit, takes 64 frames max to reach target speed
  2373. rts
  2374. ObjVectorDirChangeLinearFast:
  2375. lda.w #$400 ;one full unit, takes 8 frames max to reach target speed
  2376. rts
  2377. ;smooth: divide the difference between target and current speed by two and use that to alter the current speed
  2378. ObjVectorDirChangeLinearSmooth:
  2379. lda.b TempBuffer+2
  2380. sec
  2381. sbc.b TempBuffer ;check if target speed is bigger than actual speed
  2382. bcc ObjVectorDirTarSpeedBiggerSmooth
  2383. bra ObjVectorDirTarSpeedSmooth
  2384. ObjVectorDirTarSpeedBiggerSmooth:
  2385. lda.b TempBuffer
  2386. sec
  2387. sbc.b TempBuffer+2
  2388. ObjVectorDirTarSpeedSmooth:
  2389. lsr a
  2390. cmp.w #$20 ;smaller than minimum speed?
  2391. bcs ObjVectorDirTarSpeedMinOKSmooth
  2392. lda.w #$20 ;minimum speed: 1
  2393. rts
  2394. ObjVectorDirTarSpeedMinOKSmooth:
  2395. cmp.w #$400
  2396. bcc ObjVectorDirTarSpeedMaxOKSmooth
  2397. lda.w #$400 ;maximum speed: 8
  2398. ObjVectorDirTarSpeedMaxOKSmooth:
  2399. rts
  2400. OamSubCreateParticles:
  2401. ;create a couple of particles, position and palette same as victim:
  2402. ;input: x=pointer to object that is emitting the particles
  2403. ; a=number to add to the random number(0-3) of particles to generate. (valid ranges:0-3)
  2404. ;modifies:paltemp
  2405. ;calls: createobject (uses TempBuffers), updates random a couple of times
  2406. php
  2407. rep #$31
  2408. phx
  2409. sep #$20
  2410. pha
  2411. lda.b R4
  2412. and.b #%11
  2413. sta.b PalTemp
  2414. pla
  2415. and.b #%11
  2416. clc
  2417. adc.b PalTemp
  2418. beq ParticleCreateExit
  2419. sta.b PalTemp
  2420. CreateParticleLoop:
  2421. rep #$31
  2422. lda.w ObjEntryYPos,x
  2423. lsr a ;remove subpixel precision
  2424. lsr a
  2425. lsr a
  2426. lsr a
  2427. lsr a
  2428. lsr a
  2429. lsr a
  2430. and.w #$ff
  2431. xba
  2432. sta.b TempBuffer
  2433. lda.w ObjEntryXDisplacement,x
  2434. and.w #$ff
  2435. sta.b TempBuffer+2
  2436. lda.w ObjEntryXPos,x
  2437. lsr a ;remove subpixel precision
  2438. lsr a
  2439. lsr a
  2440. lsr a
  2441. sec
  2442. sbc.w #10
  2443. lsr a
  2444. lsr a
  2445. lsr a
  2446. inc a
  2447. and.w #$ff
  2448. ora.b TempBuffer
  2449. tax
  2450. lda.w #54
  2451. jsr CreateObjectPosition
  2452. sep #$20
  2453. plx
  2454. lda.w ObjEntryPalConf,x
  2455. and.b #%1110
  2456. sta.b TempBuffer
  2457. phx
  2458. ldx.b ObjectListPointerCurrent
  2459. lda.w ObjEntryPalConf,x
  2460. and.b #%11110001
  2461. ora.b TempBuffer ;store palette of player for this particle
  2462. sta.w ObjEntryPalConf,x
  2463. jsr Random ;update random numbers so that all particles look different
  2464. jsr Random ;update random numbers so that all particles look different
  2465. dec.b PalTemp
  2466. bne CreateParticleLoop
  2467. ParticleCreateExit:
  2468. plx
  2469. plp
  2470. rts
  2471. ObjProcUpdateGravity:
  2472. lda.w ObjEntryLifeCounter,x
  2473. and.w #$ff
  2474. beq ObjProcGravityKill
  2475. dec.w ObjEntryLifeCounter,x ;decrease life counter
  2476. lda.w ObjEntryXSpeed,x ;add speed x-dir
  2477. and.w #$ff
  2478. clc
  2479. adc.w #$ff80 ;align in middle so that x-speed can be both positive and negative
  2480. clc
  2481. adc.w ObjEntryXPos,x
  2482. sta.w ObjEntryXPos,x
  2483. lda.w ObjEntryGravity,x
  2484. and.w #$ff
  2485. clc
  2486. adc.w ObjEntryYSpeed,x
  2487. sta.w ObjEntryYSpeed,x
  2488. clc
  2489. adc.w ObjEntryYPos,x
  2490. sta.w ObjEntryYPos,x
  2491. lsr a ;remove subpixel prec.
  2492. lsr a
  2493. lsr a
  2494. lsr a
  2495. cmp.w GravityCutOffYPos ;check if object is too low and should be deleted
  2496. bcs ObjProcGravityKill
  2497. rts
  2498. ObjProcGravityKill:
  2499. dec.w GravObjectCounter
  2500. stz.w ObjEntryType,x ;kill object if life is up
  2501. rts
  2502. ObjectProcessGravObjInc:
  2503. php
  2504. sep #$20
  2505. lda.w GravObjectCounter
  2506. cmp.w MaxGravObjCount ;number bigger than max count?
  2507. bcc ObjectProcessGravObjNoDel
  2508. stz.w ObjEntryType,x ;delete object if count is too high
  2509. stz.w ObjEntryType2,x
  2510. plp
  2511. rts
  2512. ObjectProcessGravObjNoDel:
  2513. inc.w GravObjectCounter
  2514. plp
  2515. rts