mirror of
https://github.com/a2-4am/4cade.git
synced 2025-02-17 07:31:19 +00:00
240 lines
8.0 KiB
Plaintext
240 lines
8.0 KiB
Plaintext
;license:MIT
|
|
;(c) 2018-9 by 4am
|
|
;
|
|
; Functions to launch games and self-running demos
|
|
;
|
|
; Public functions
|
|
; - AnyGameSelected
|
|
; - GetGameToLaunch
|
|
; - FindGame
|
|
; - PlayGame
|
|
; - Launch
|
|
; - Joystick
|
|
; - LoadXSingle
|
|
; - LoadStandardPrelaunch
|
|
;
|
|
; Public variables:
|
|
; - gGameToLaunch - 0-based index into gSearchStore (word)
|
|
;
|
|
|
|
gGameToLaunch
|
|
!word $FFFF
|
|
gLastMegaAttractGame
|
|
!word $FFFF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; AnyGameSelected
|
|
; get index of game that is currently selected in the UI (if any)
|
|
;
|
|
; in: none
|
|
; out: A/Y = gGameToLaunch (word)
|
|
; C clear if gGameToLaunch is not #$FFFF
|
|
; C set if gGameToLaunch is #$FFFF
|
|
; X preserved
|
|
;------------------------------------------------------------------------------
|
|
AnyGameSelected
|
|
+LD16 gGameToLaunch
|
|
+CMP16_NE $FFFF, ForceGoodResult
|
|
rts ; CMP sets carry when equal
|
|
|
|
;------------------------------------------------------------------------------
|
|
; GetGameToLaunch
|
|
; get filename of game that is currently selected in the UI (if any)
|
|
;
|
|
; in: gGameToLaunch = index into gSearchStore (word) or #$FFFF if no game selected
|
|
; gSearchStore populated
|
|
; out: C clear if a game is selected, and
|
|
; A/Y points to game filename
|
|
; C set if no game is selected
|
|
;------------------------------------------------------------------------------
|
|
GetGameToLaunch
|
|
jsr AnyGameSelected
|
|
bcs _gameToLaunchExit
|
|
+ST16 WINDEX
|
|
+LDADDR gSearchStore
|
|
jsr okvs_nth
|
|
ForceGoodResult
|
|
clc
|
|
_gameToLaunchExit
|
|
rts
|
|
|
|
;------------------------------------------------------------------------------
|
|
; FindGame
|
|
; check if an arbitrary game exists, for some definition of 'exists', while
|
|
; in the middle of a slideshow
|
|
;
|
|
; in: A/Y points to a key in gSlideshowStore
|
|
; out: C clear if game exists and is playable on current machine, and
|
|
; (SAVE) -> game display name, and
|
|
; (gLastMegaAttractGame) -> game filename
|
|
; C set otherwise
|
|
; clobbers $FF, PTR
|
|
; all registers clobbered
|
|
;------------------------------------------------------------------------------
|
|
FindGame
|
|
+ST16 gLastMegaAttractGame
|
|
jsr okvs_next_field ; (PTR) -> OKVS value (filename or empty string)
|
|
; Y=0
|
|
lda (PTR), y
|
|
beq +
|
|
+LD16 PTR
|
|
+ST16 gLastMegaAttractGame
|
|
+ jsr okvs_next_field_PTR_is_already_set ; (PTR) -> game display name
|
|
+LD16 PTR ; A/Y -> game display name
|
|
+ST16 SAVE ; (SAVE) -> game display name
|
|
jsr okvs_next_field ; (PTR) -> game requirements bitfield
|
|
; Y=0
|
|
|
|
; check if game requires joystick
|
|
lda (PTR), y
|
|
sta $FF
|
|
bpl @check128K
|
|
lda MachineStatus
|
|
and #HAS_JOYSTICK
|
|
beq @failedCheck ; machine doesn't have joystick but game requires it
|
|
|
|
@check128K
|
|
; check if game requires 128K
|
|
bit $FF
|
|
bvc @passedAllChecks
|
|
lda MachineStatus
|
|
and #HAS_128K
|
|
beq @failedCheck ; machine doesn't have 128K but game requires it
|
|
|
|
@passedAllChecks
|
|
clc
|
|
rts
|
|
|
|
@failedCheck
|
|
sec
|
|
rts
|
|
|
|
;------------------------------------------------------------------------------
|
|
; PlayGame
|
|
;
|
|
; in: gGameToLaunch != #$FFFF
|
|
; out: exits via the game, but also backs up the stack, which may get
|
|
; restored in |Reenter|... what I'm saying is that we might actually
|
|
; 'return' from this after the user is done playing the game, which is
|
|
; a neat trick
|
|
;------------------------------------------------------------------------------
|
|
PlayGame
|
|
jsr GetGameToLaunch
|
|
; A/Y = address of game filename in gSearchIndex
|
|
PlayGameInAY
|
|
+ST16 SAVE
|
|
+ST16 @pfile
|
|
+ST16 xfile
|
|
jsr okvs_next_field
|
|
jsr okvs_next_field_PTR_is_already_set
|
|
; (PTR) -> length-prefixed game info bitfield
|
|
; Y = 0
|
|
iny ; Y = 1
|
|
lda (PTR), y ; A = game info bitfield
|
|
and #IS_SINGLE_LOAD
|
|
php
|
|
|
|
jsr ClearScreens ; avoid seeing code load into the HGR page
|
|
; (clobbers $106, must do now before loading prelaunch code)
|
|
|
|
jsr LoadIndexedFile ; load prelaunch index file
|
|
- !word gSearchCache ; clobber gSearchCache which we no longer need
|
|
!word kPrelaunchIndexRecord
|
|
|
|
jsr okvs_find ; find this game's prelaunch index record
|
|
!word -
|
|
@pfile !word $FDFD ; SMC
|
|
+ST16 @prelaunchIndexRecordPtr
|
|
|
|
jsr LoadIndexedFile ; load this game's prelaunch code into $0106
|
|
!word $0106
|
|
@prelaunchIndexRecordPtr
|
|
!word $FDFD ; SMC
|
|
|
|
plp
|
|
beq @loadFromSubdirectory
|
|
|
|
jsr LoadXSingle_NameIsAlreadySet
|
|
jmp Launch
|
|
|
|
@loadFromSubdirectory
|
|
+LD16 SAVE
|
|
+ST16 @p
|
|
|
|
jsr LoadFile ; load the game startup file
|
|
!word kGameDirectory
|
|
@p !word $FDFD
|
|
!word 0 ; use file's default address
|
|
|
|
lda #1
|
|
sta ProDOS_prefix ; set 'root' directory to the path part
|
|
; of the game startup file we just loaded
|
|
; so games can load other files without
|
|
; knowing which directory they're in
|
|
|
|
; execution falls through here
|
|
Launch
|
|
jsr SwitchToBank2
|
|
lda #$BD
|
|
sta launchpatch
|
|
jsr saveslot ; set proper slot information
|
|
lda #$9D
|
|
sta launchpatch
|
|
jmp LaunchInternal
|
|
|
|
;------------------------------------------------------------------------------
|
|
; LoadXSingle/LoadXSingle_NameIsAlreadySet/LoadXFile
|
|
; load an indexed file via an extended index record that also contains starting
|
|
; address information
|
|
;
|
|
; in: A/Y points to game filename (must be listed in xsingle OKVS)
|
|
; out: all flags & registers clobbered
|
|
;------------------------------------------------------------------------------
|
|
LoadXSingle ; entry point used by demos to load additional resources
|
|
+ST16 xfile
|
|
LoadXSingle_NameIsAlreadySet ; entry point used by PlayGame
|
|
jsr LoadIndexedFile ; load xsingle index file (contains pointers to game binaries)
|
|
- !word gSearchCache ; clobber search cache which we no longer need
|
|
!word kXSingleRecord
|
|
LoadXFile ; entry point used by attract mode to load self-running demo
|
|
jsr okvs_find ; find this game's extended index record
|
|
!word -
|
|
xfile !word $FDFD ; SMC
|
|
+ST16 @xsingleIndexRecordPtr
|
|
jsr okvs_next_field
|
|
ldy #5
|
|
lda (PTR), y ; get game load address (stored immediately after index record)
|
|
sta @xsingleAddr
|
|
iny
|
|
lda (PTR), y
|
|
sta @xsingleAddr+1
|
|
|
|
jsr LoadIndexedFile ; load this game binary
|
|
@xsingleAddr
|
|
!word $FDFD ; SMC
|
|
@xsingleIndexRecordPtr
|
|
!word $FDFD ; SMC
|
|
rts
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Joystick
|
|
; launch joystick calibration program
|
|
;
|
|
; in: none
|
|
; out: exits via Launch
|
|
;------------------------------------------------------------------------------
|
|
Joystick
|
|
jsr LoadStandardPrelaunch
|
|
|
|
jsr LoadIndexedFile
|
|
!word $800
|
|
!word kJoystickRecord
|
|
|
|
jmp Launch
|
|
|
|
LoadStandardPrelaunch
|
|
jsr LoadIndexedFile ; load standard prelaunch code at $0106
|
|
!word $0106
|
|
!word kStandardPrelaunchRecord
|
|
rts
|