;****************************************************************************** ;* ingame codes ;* ;****************************************************************************** __INGAME_NATIVE = 1 .include "snes.inc" .include "objects.inc" .include "level.inc" .include "graphics.inc" .include "snes_joypad.inc" .include "snes_decompress.inc" .include "players.inc" .include "snes_zvars.inc" .include "ingame.inc" .include "sprites.inc" .include "explosion.inc" .include "snesmod.inc" .include "soundbank.inc" .include "sounds.inc" .import oam_table, oam_hitable .import Player1_DimPal .import Player2_DimPal .import Player3_DimPal .import Arnold_Activate .import Arnold_Disable .import Arnold_Update .import Arnold_Draw .export BG3_Data .export Timer .export ExplodeSpace .export UpdatePlayerPalettes .export NextSobj .export CameraX_Limit, CameraY_Limit .export SpriteTransferQueue, SpriteTransferIndex .exportzp ActivePlayer .global RunGame .importzp frame_ready ;==================================================================== ; DEFS ;==================================================================== LASERTILES = 0000h BG3MAP = 800H IBGTILES = 1180H IBGMAP = 1000H IBG2TILES = 2000H IBG2MAP = 3800H CVTILES = 6000H+20480 EXPTILES = 0d000H BOSS_LEVEL = 8 .macro DEBUG_CPU_START ; stz REG_CGADD ; lda #1Fh ; sta REG_CGDATA ; stz REG_CGDATA .endmacro .macro DEBUG_CPU_END ; stz REG_CGADD ; lda #07Ch ; stz REG_CGDATA ; sta REG_CGDATA .endmacro ;==================================================================== .zeropage ;==================================================================== ActivePlayer: .res 1 PlayerPalettesDirty: .res 1 CameraScroll: .res 1 .exportzp CameraScroll .exportzp Flipper Flipper: .res 1 Timer: .res 2 .exportzp CameraPX, CameraPY, CameraTileX, CameraTileY CameraX: .res 1 CameraTileX: .res 1 CameraY: .res 1 CameraTileY: .res 1 CameraTX: .res 2 CameraTY: .res 2 CameraPX: .res 2 CameraPY: .res 2 P1_StatusPal: .res 1 P2_StatusPal: .res 1 P3_StatusPal: .res 1 Conveyor_Tile: .res 1 ENDTIMER: .res 1 RESULT: .res 1 RESTARTLEVEL: .res 1 FADEIN: .res 1 GAMEPAUSE: .res 1 ;==================================================================== .bss ;==================================================================== ;******************************************************************** ;* camera positions ;* ;* 12.4 fixed point (0.0 -> mapwidth/height*16-screenwidth/height) ;* x = current position, Tx = target position, Px = pixel conversions ;******************************************************************** ;CAMERAX_MAX = (1024-256)*16 ;CAMERAY_MAX = (512-SCREENHEIGHT)*16 CameraX_Limit: .res 2 CameraY_Limit: .res 2 CAMSCROLL_RATE = 100 HOFS_Shadow: .res 2 VOFS_Shadow: .res 2 ; ; 32x2 statusbar info ; Status_Shadow: .res 2*32*2 StatusDirty: .res 1 ; ; 32x12 BG3 shadow ; BG3_Data: .res 2*32*12 ;*************************************************** ;* 32x32 sprite transfers ; ; format: ; 1 byte: SRCBANK ; 2 bytes: SRCADDR ; 2 bytes: DESTADDR ;*************************************************** SpriteTransferQueue: ; .res 5*8 ; SpriteTransferIndex: ; .res 2 ; ;--------------------------------------------------- NSOBJ = 16 SOBJ_BASE = 64 .export SobjXL, SobjXH, SobjA1, SobjA2, SobjA3, SobjSize .exportzp SobjY SobjXL: .res NSOBJ ; 0..255 SobjXH: .res NSOBJ ; 0/1 SobjA1: .res NSOBJ ; oam:attr1 SobjA2: .res NSOBJ ; oam:attr2 SobjA3: .res NSOBJ ; oam:attr3 SobjSize: .res NSOBJ ; 0/1 NextSobj: .res 1 .zeropage SobjY: .res NSOBJ+1 ; 1..224 (0 = disabled) .segment "XCODE" .a8 .i16 ;============================================================================ .macro AdjustCameraPos source, targ, pixelcpy ;============================================================================ lda targ ; source += (targ-source) / 16 sec ; sbc source ; cmp #8000h ; ror ; cmp #8000h ; ror ; cmp #8000h ; ror ; cmp #8000h ; ror ; clc ; adc source ; ;---------------------------------------------------------------------------- sta source ; copy = round(source / 16) lsr ; lsr ; lsr ; lsr ; ; adc #0 ; sta pixelcpy ; ;---------------------------------------------------------------------------- .endmacro CAMSPEED = 150 .i8 ;======================================================================================== RunSort: ;======================================================================================== ldx #128 lda #1 .repeat NSOBJ, i cmp SobjY+i bcs :+ lda SobjY+i ldx #i : .endrep rts .i16 .export SortSprites ;======================================================================================== SortSprites: ;======================================================================================== lda #^oam_table ; setup WMDATA address sta REG_WMADDH ; ldx #.LOWORD(oam_table+SOBJ_BASE*4) ; stx REG_WMADDL ; sep #10h ; 8bit index stz m2+1 ; ;---------------------------------------------------------------------------------------- .macro Sort4 mm ;---------------------------------------------------------------------------------------- .scope lda #4 ; m2 = reverse iterator sta m2 ; ;---------------------------------------------------------------------------------------- sort_loop: ;---------------------------------------------------------------------------------------- jsr RunSort ; do sorting cpx #0 ; if x >= 128 then terminate bmi @end_of_sorting ; ;---------------------------------------------------------------------------------------- stz SobjY, x ; reset Y entry lda SobjXL, x ; copy data sta REG_WMDATA ; lda SobjA1, x ; sta REG_WMDATA ; lda SobjA2, x ; sta REG_WMDATA ; lda SobjA3, x ; sta REG_WMDATA ; ;--------------------------------------------------------------------------------------- lda SobjXH, x ; shift x msb into mm lsr ; ror mm ; ;--------------------------------------------------------------------------------------- lda SobjSize, x ; shift size into mm lsr ; ror mm ; ;--------------------------------------------------------------------------------------- dec m2 ; loop upto 4 times bne sort_loop ; ;--------------------------------------------------------------------------------------- bra :+++ ; jump to next function ;--------------------------------------------------------------------------------------- @end_of_sorting: ; jump to end of sorting ldx m2 beq :++ : lsr mm lsr mm dex bne :- : jmp end_of_sorting ; ;--------------------------------------------------------------------------------------- : inc m2+1 ; increment x4 counter .endscope .endmacro Sort4 m0 ; do sorting for 16 entries Sort4 m0+1 ; Sort4 m1 ; Sort4 m1+1 ; ;--------------------------------------------------------------------------------------- end_of_sorting: ;--------------------------------------------------------------------------------------- asl m2+1 ; x = (m2.H*4) + (4-m2.L) asl m2+1 ; lda #4 ; sec ; sbc m2 ; clc ; adc m2+1 ; sbc #16-1 ; eor #0FFh ; ina ; tax ; ;--------------------------------------------------------------------------------------- lda #224 ; clear the remaining sprite entries cpx #0 ; beq :++ ; : stz REG_WMDATA ; sta REG_WMDATA ; stz REG_WMDATA ; stz REG_WMDATA ; dex ; bne :- ; : ; ;--------------------------------------------------------------------------------------- rep #10h ; ldx m0 ; copy hitable entries stx oam_hitable+SOBJ_BASE/4 ldx m1 ; stx oam_hitable+SOBJ_BASE/4+2 ;--------------------------------------------------------------------------------------- rts ;--------------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------------- .macro UpdateBG3 ;--------------------------------------------------------------------------------------- lda #80h sta REG_VMAIN ldx #BG3MAP/2 stx REG_VMADD lda #1 sta REG_DMAP7 lda # lda #OBSEL_16_32 | OBSEL_BASE(0C000h) | OBSEL_NN_16K sta REG_OBSEL stz SpriteTransferIndex stz SpriteTransferIndex+1 stz SpriteTransferQueue lda #^oam_table sta REG_WMADDH ldy #.LOWORD(oam_table) sty REG_WMADDL ldy #128 lda #224 : stz REG_WMDATA sta REG_WMDATA stz REG_WMDATA stz REG_WMDATA dey bne :- .repeat NSOBJ+1, i stz SobjY+i .endrep stz ActivePlayer jsr Objects_DoInit ;-------------------------------------------------------- .importzp CURRENT_LEVEL lda CURRENT_LEVEL cmp #BOSS_LEVEL bne :+ jsr Arnold_Activate bra :++ : jsr Arnold_Disable : ;-------------------------------------------------------- jsr Sprites_Reset jsr UpdatePlayerPalettes stz FADEIN ResetExplosion lda ActivePlayer rep #20h and #255 tay sep #20h lda PL_XH, y xba lda PL_XL, y rep #21h sbc #(128)*16 bpl :+ lda #0 bra :++ : cmp CameraX_Limit bcc :+ lda CameraX_Limit : sta CameraX sep #20h lda PL_YH, y xba lda PL_YL, y rep #21h sbc #((SCREENHEIGHT/2)+16)*16 bpl :+ lda #0 bra :++ : cmp CameraY_Limit bcc :+ lda CameraY_Limit : sta CameraY sep #20h stz GAMEPAUSE ;---------------------------------------------------------------------------- ; full clear on bg3 ;---------------------------------------------------------------------------- lda #80h sta REG_VMAIN ldx #BG3MAP/2 stx REG_VMADD ldy #0 ldx #32*32 : sty REG_VMDATA dex bne :- ;---------------------------------------------------------------------------- ; fill up status bg ;---------------------------------------------------------------------------- lda #80h ; clear to black sta REG_VMAIN ; ldx #IBG2MAP/2 ; stx REG_VMADD ; ldx #16|(2<<10)|(1<<14)|(1<<15) ; ldy #32*6 ; : stx REG_VMDATA ; dey ; bne :- ; ;---------------------------------------------------------------------------- ldy #0 .macro copycname .local @next_name : lda character_names, y beq @next_name iny sta REG_VMDATAL lda #(2<<2)|(1<<5) sta REG_VMDATAH bra :- @next_name: iny .endmacro ldx #IBG2MAP/2+5+1*32 stx REG_VMADD copycname ldx #IBG2MAP/2+15+1*32 stx REG_VMADD copycname ldx #IBG2MAP/2+25+1*32 stx REG_VMADD copycname lda #80h sta REG_VMAIN SetupAvatar 0, 1 SetupAvatar 1, 3 SetupAvatar 2, 5 rep #20h lda #16+(2<<10) ldy #2*32*2-2 : sta Status_Shadow, y dey dey bpl :- sep #20h ldy #0 ldx #128 jsr InitStatus ldy #20 ldx #136 jsr InitStatus ldy #40 ldx #144 jsr InitStatus jsr UpdateHearts jsr UpdatePlayerMoves ;---------------------------------------------------------------------------- ; setup hdma ;---------------------------------------------------------------------------- lda #%011 ; 0,1 = 2 regs write twice each sta REG_DMAP0 ; (HOFS/VOFS) sta REG_DMAP1 ; ;---------------------------------------------------------------------------- lda #%001 sta REG_DMAP4 ; SC ;---------------------------------------------------------------------------- lda #%000 ; 2,3 = 1 reg write once sta REG_DMAP2 ; (TM, BGMODE) sta REG_DMAP3 ; sta REG_DMAP5 ; NBA ;---------------------------------------------------------------------------- lda #gfx_conveyorTiles adc Conveyor_Tile sta REG_A1T7H ldx #CVTILES/2 stx REG_VMADD ldx #128 stx REG_DAS7 lda #1<<7 sta REG_MDMAEN stx REG_DAS7 ldx #(CVTILES+512)/2 stx REG_VMADD sta REG_MDMAEN ;---------------------------------------------------------------------------- bit StatusDirty bpl :+ stz StatusDirty lda #%001 sta REG_DMAP7 ldx #Status_Shadow stx REG_A1T7 lda #^Status_Shadow sta REG_A1B7 ldx #IBG2MAP/2+96 stx REG_VMADD lda #>3) + (((g)>>3)<<5) + (((b)>>3)<<10)) ib_pal_normal: .word rgb8(220,220,220), rgb8(161,161,161), rgb8(140,140,140), rgb8(107,107,107), rgb8(85,85,85) ib_pal_active: .word rgb8(255,255,255), rgb8(187,187,187), rgb8(163,163,163), rgb8(125,125,125), rgb8(99,99,99) ib_pal_red: .word rgb8(255,148,155), rgb8(231,23,40), rgb8(183,0,0), rgb8(128,0,0), rgb8(101,0,0) ib_pal_green: .word rgb8(154,248,144), rgb8(43,224,16), rgb8(3,176,0), rgb8(2,128,0), rgb8(1,96,0) character_names: .asciiz "Skipp" .asciiz "Wedge" .asciiz "Apple" SpTilePalette: .word 0 .word rgb8(40,80,220) .word rgb8(0,0,0) LEVEL_MUSICS: .byte MOD_EXBORE .byte MOD_EXBORE .byte MOD_EXCITEBORE2 .byte MOD_EXCITEBORE2 .byte MOD_METEORIC .byte MOD_METEORIC .byte MOD_ICESHIP .byte MOD_DUCKIEST .byte MOD_EXCITEBORE2