iigs-game-engine/demos/kfest-2022/demo-1/App.Main.s
2023-04-26 08:47:56 -05:00

564 lines
15 KiB
ArmAsm

; Test driver to exercise graphics routines.
REL
DSK MAINSEG
use Locator.Macs
use Load.Macs
use Mem.Macs
use Misc.Macs
use Util.Macs
use EDS.GSOS.Macs
use GTE.Macs
mx %00
tiledata EXT ; tileset buffer
TileSetPalette EXT
; Keycodes
LEFT_ARROW equ $08
RIGHT_ARROW equ $15
UP_ARROW equ $0B
DOWN_ARROW equ $0A
; Direct page space
MyUserId equ 0
BankLoad equ 2
StartX equ 4
StartY equ 6
TileMapWidth equ 8
TileMapHeight equ 10
ScreenWidth equ 12
ScreenHeight equ 14
MaxGlobalX equ 16
MaxGlobalY equ 18
MaxBG0X equ 20
MaxBG0Y equ 22
frameCount equ 24
OldOneSecondCounter equ 26
appTmp0 equ 28
seg1x equ 30
seg2x equ 32
seg3x equ 34
seg4x equ 36 ; BG1 x-pos
frameCountTotal equ 38
PlayerX equ 40
PlayerY equ 42
PlayerXVel equ 44
PlayerYVel equ 46
OverlayTop equ 48
phk
plb
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program
tdc
sta MyDirectPage ; Keep a copy for the overlay callback
_MTStartUp ; GTE requires the miscellaneous toolset to be running
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER ; Engine in Fast Mode as a User Tool
jsr GTEStartUp ; Load and install the GTE User Tool
; Initialize the graphics screen playfield
pea #160
pea #200
_GTESetScreenMode
; Load a tileset
pea 0
pea 256
pea #^tiledata
pea #tiledata
_GTELoadTileSet
pea $0000
pea #^TileSetPalette
pea #TileSetPalette
_GTESetPalette
pea $0
_GTEClearBG1Buffer
; Set up our level data
; jsr BG0SetUp
pea 416
pea 30
pea ^App_TileMapBG0
pea App_TileMapBG0+{10*416}
_GTESetBG0TileMapInfo
stz seg1x
stz seg2x
stz seg3x
stz seg4x
jsr SetLimits
jsr DoLoadBG1
; Initialize local variables
lda #56
sta StartX
lda #0
sta StartY
stz frameCount
stz frameCountTotal
stz OverlayTop
pei StartX
pei StartY
_GTESetBG0Origin
lda #193 ; Tile ID of '0'
jsr InitOverlay ; Initialize the status bar
pha
_GTEGetSeconds
pla
sta OldOneSecondCounter
jsr UdtOverlay
; Create some sprites
lda #16
sta PlayerX
lda MaxGlobalY
sec
sbc #48 ; 32 for tiles, 16 for sprite
lda #48 ; 32 for tiles, 16 for sprite
sta PlayerY
stz PlayerXVel
stz PlayerYVel
HERO_SIZE equ {SPRITE_16X16}
HERO_FLAGS equ HERO_SIZE ; no extra H/V bits for now
HERO_FRAME_1 equ HERO_SIZE+145
HERO_VBUFF_1 equ VBUFF_SPRITE_START+0*VBUFF_SPRITE_STEP
HERO_SLOT equ 1
pea HERO_FRAME_1
pea HERO_VBUFF_1
_GTECreateSpriteStamp
pha ; Space for result
pea HERO_SIZE
pea HERO_VBUFF_1
_GTECompileSpriteStamp
pla
pea HERO_SLOT ; Put the player in slot 1
pea HERO_FLAGS+SPRITE_COMPILED ; mark this as a compiled sprite (can only use in RENDER_WITH_SHADOWING mode)
pha ; pass in the token of the compiled stamp
pei PlayerX
pei PlayerY
_GTEAddSprite
; Set up the per-scanline rendering
lda StartX
jsr InitOffsets
pea #scanlineHorzOffset
pea #^BG0Offsets
pea #BG0Offsets
_GTESetAddress
pea #scanlineHorzOffset2
pea #^BG1Offsets
pea #BG1Offsets
_GTESetAddress
pea #RENDER_WITH_SHADOWING ; one regular render to fill the screen with the tilemap
_GTERender
; Set up a very specific test. First, we draw a sprite into the sprite plane, and then
; leave it alone. We are just testing the ability to merge sprite plane data into
; the play field tiles.
EvtLoop
pha
_GTEReadControl
pla
jsr HandleKeys ; Do the generic key handlers
bcs :do_more
brl :do_render
:do_more
cmp #'d'
bne :not_d
jsr DecRanges
jsr SetOffsets
brl :do_render
:not_d
cmp #'a'
bne :not_a
jsr IncRanges
jsr SetOffsets
brl :do_render
:not_a
cmp #'s'
bne :not_s
lda StartY
cmp MaxBG0Y
bcs :do_render
inc StartY
pei StartX
pei StartY
_GTESetBG0Origin
bra :do_render
:not_s
cmp #'w'
bne :not_w
lda StartY
beq :do_render
dec StartY
pei StartX
pei StartY
_GTESetBG0Origin
bra :do_render
:not_w
cmp #' '
bne :not_space
lda OverlayTop
inc
and #$3F
sta OverlayTop
pha
clc
adc #8
pha
pea #^StatusBar
pea #StatusBar
_GTEUpdateOverlay
:not_space
:do_render
jsr SetBG1Animation ; Update the per-scanline BG1 offsets
jsr _GetVBLTicks
and #$00FC
lsr
lsr
sta PlayerX
pea HERO_SLOT
pei PlayerX
pei PlayerY
_GTEMoveSprite ; Move the sprite to this local position
pea #RENDER_PER_SCANLINE
; pea #0
_GTERender
; Update the performance counters
inc frameCount
inc frameCountTotal
pha
_GTEGetSeconds
pla
cmp OldOneSecondCounter
beq :noudt
sta OldOneSecondCounter
jsr UdtOverlay
stz frameCount
:noudt
brl EvtLoop
; Exit code
Exit
_GTEShutDown
Quit
_QuitGS qtRec
bcs Fatal
Fatal brk $00
qtRec adrl $0000
da $00
; Color palette
MyDirectPage ds 2
_GetVBLTicks
PushLong #0
_GetTick
pla
plx
rts
SetLimits
pha ; Allocate space for width (in tiles), height (in tiles), pointer
pha
pha
pha
_GTEGetBG0TileMapInfo
pla
sta TileMapWidth
pla
sta TileMapHeight
pla
pla ; discard the pointer
pha ; Allocate space for x, y, width, height
pha
pha
pha
_GTEGetScreenInfo
pla
pla ; Discard screen corner
pla
sta ScreenWidth
pla
sta ScreenHeight
lda TileMapWidth
asl
asl
sta MaxGlobalX
sec
sbc ScreenWidth
sta MaxBG0X
lda TileMapHeight
asl
asl
asl
sta MaxGlobalY
sec
sbc ScreenHeight
sta MaxBG0Y
; Check if the current StartX and StartY are out of bounds
lda StartX
cmp MaxBG0X
bcc :x_ok
lda MaxBG0X
:x_ok pha
lda StartY
cmp MaxBG0Y
bcc :y_ok
lda MaxBG0Y
:y_ok pha
_GTESetBG0Origin
rts
DecRanges
lda seg1x
bne *+5
lda #164
dec
sta seg1x
bit #1
bne :out
lda seg2x
bne *+5
lda #164
dec
sta seg2x
bit #1
bne :out
lda seg3x
bne *+5
lda #164
dec
sta seg3x
:out
rts
IncRanges
lda seg1x
inc
cmp #164
bcc *+5
lda #0
sta seg1x
bit #1
bne :out
lda seg2x
inc
cmp #164
bcc *+5
lda #0
sta seg2x
bit #1
bne :out
lda seg3x
inc
cmp #164
bcc *+5
lda #0
sta seg3x
bit #1
bne :out
lda seg4x
inc
cmp #164
bcc *+5
lda #0
sta seg4x
:out
rts
InitOffsets
pha
ldx #0
ldy #40
jsr _InitRange
ldx #40
ldy #80
jsr _InitRange
ldx #120
ldy #88
jsr _InitRange
jsr _InitBG1
pla
sta seg1x
jsr SetOffset1
lsr
sta seg2x
jsr SetOffset2
lsr
sta seg3x
jsr SetOffset3
jsr SetBG1Offsets
rts
SetOffsets
lda seg1x
jsr SetOffset1
lda seg2x
jsr SetOffset2
lda seg3x
jsr SetOffset3
SetBG1Offsets
pei seg4x
pea 0
_GTESetBG1Origin
rts
SetBG1Animation
pea #scanlineHorzOffset2
pea #^BG1Offsets
lda frameCountTotal
and #$000F
asl
adc #BG1Offsets
pha
_GTESetAddress
rts
SetOffset1
ldx #120
ldy #88
jmp _SetRange
SetOffset2
ldx #40
ldy #80
jmp _SetRange
SetOffset3
ldx #0
ldy #40
jmp _SetRange
_SetRange
pha
txa
asl
tax
:loop2 lda BG0Offsets,x
and #$FF00
ora 1,s
sta BG0Offsets,x
dey
beq :done
inx
inx
cpx #416
bcc :loop2
:done
pla
rts
_offsets dw 0,0,0,1,1,2,3,3,4,4,4,3,3,2,1,1
_InitBG1
ldx #0
ldy #0
:loop lda _offsets,y
sta BG1Offsets,x
iny
iny
cpy #31
bcc *+5
ldy #0
inx
inx
cpx #448
bcc :loop
rts
_InitRange
txa
asl
tax
tya
dec
and #$00FF
xba
:loop1 sta BG0Offsets,x
sec
sbc #$0100
dey
beq :done
inx
inx
cpx #416
bcc :loop1
:done
rts
; Load a binary file in the BG1 buffer
DoLoadBG1
jsr AllocBank ; Alloc 64KB for Load/Unpack
sta BankLoad ; Store "Bank Pointer"
ldx #BG1DataFile ; Load the background file into the bank
jsr LoadFile
pea #164 ; Fill everything
pea #200
pea #256
lda BankLoad
pha
pea $0000
pea COPY_PIC_SCANLINE ; Copy in a mode that supports per-scanline offsets
_GTECopyPicToBG1
rts
BG1DataFile strl '1/bg1.bin'
BG0Offsets ds 416
BG1Offsets ds 448 ; Make this a bit larger so we can just update a pointer
PUT ../StartUp.s
PUT ../../shell/Overlay.s
PUT gen/App.TileMapBG0.s