;license:MIT ;(c) 2018-9 by 4am ; ; Functions to launch games and self-running demos ; ; Public functions ; - GetGameToLaunch ; - GetGameInfo ; - GetGameInfoInActionSlideshow ; - PlayGame ; - Launch ; ; Public variables: ; - gGameToLaunch - 0-based index into gGamesListStore ; GetGameToLaunch ; in: gGameToLaunch = index into gGamesListStore ; out: A/Y points to game filename gGameToLaunch=*+1 ldx #$FF ; SMC +LDADDR gGamesListStore jmp okvs_nth GetGameInfo ; in: A/Y points to game filename ; out: C clear if game exists in gGamesListStore, and ; A/Y points to game display name (but see hack notes below) ; X = game index, or #$FF if the game doesn't really exist but ; we want to return a successful result anyway (really, read the ; hack notes, they're important) ; C set if game does not exist (this can happen because slideshows ; list games that require a joystick, but the games list parser ; filters out joystick-only games if the machine doesn't have a ; joystick) ldx #$60 +HIDE_NEXT_2_BYTES GetGameInfoInActionSlideshow ldx #$EA stx @maybeExit +STAY @key +STAY @slideshowKey jsr okvs_get !word gGamesListStore @key !word $FDFD ; SMC bcc @exit ; Hack to allow self-running demos that don't correspond to a game ; filename. If the name ends in a '.', accept it unconditionally. ; The filename is its own display name. Launching this fake game ; will of course fail, so don't do that. +LDAY @key +STAY PARAM ldy #0 lda (PARAM),y tay lda (PARAM),y cmp #"." beq @forceGoodResult sec @maybeExit !byte $00 ; SMC ; if the key is still not found, AND the caller said to try this, then try ; getting the value of the current record from gSlideshowStore ; (some games have multiple action screenshots, in which case the filename of ; the action screenshot is not the game name, but the value is) jsr okvs_get !word gSlideshowStore @slideshowKey !word $FDFD ; SMC +STAY @key3 jsr okvs_get !word gGamesListStore @key3 !word $FDFD ; SMC ; note that the game might still not be found (C will be set by okvs_get), ; which can happen if the game can't be played due to memory or joystick ; requirements rts @forceGoodResult +LDAY @key ldx #$FF clc @exit rts PlayGame jsr GetGameToLaunch ; A/Y = address of game filename +STAY SAVE +STAY @pfile jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) jsr LoadFile ; load this game's prelaunch file at $106 !word kPrelaunchDirectory @pfile !word $FDFD !word $0106 ; we start by placing the subdirectory name at gPathname+kGameDirectoryLen ; to leave room for the GameDirectory name as the parent lda #kGameDirectoryLen sta gPathname +LDAY SAVE jsr AddToPath ; attach the separator inc gPathname lda #'/' sta gPathname+1,x ; then we save the length of the resulting string without the count byte dex txa pha ; then attach the game name +LDAY SAVE jsr AddToPath ; don't look while I do this ; we "place" a string at gPathname+kGameDirectoryLen ; whose length is the subdirectory name and game name ; then we load it ; the load sets the path to the GameDirectory ; and then finds the subdirectory name and game name right after it ; and attaches it to the path by overwriting the count byte ;;sec ; carry set by AddToPath lda gPathname sbc #kGameDirectoryLen sta gPathname+kGameDirectoryLen jsr LoadFile ; load the game startup file !word kGameDirectory !word gPathname+kGameDirectoryLen !word 0 ; use file's default address pla 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 jmp LaunchInternal