;license:MIT ;(c) 2018-9 by 4am ; ; Functions to launch games and self-running demos ; ; Public functions ; - GetGameDisplayName ; - PlayGameFromSearch ; - PlayGameFromBrowse ; - PlayGameFromAttract ; - Prelaunch ; - Launch ; ; Public variables ; - gCurrentAttractIndex ; [byte] numeric index in gAttractModeStore of current Mega-Attract Module ; - gCurrentlyVisibleSlideshowIndex ; [byte] numeric index in gSlideshowStore of currently visible slideshow picture ; (only valid during slideshows, not updated once a key is pressed) !zone { GetGameDisplayName ; in: A/Y points to game filename ; X = #$60 if we should only look in gGamesListStore for a match ; X = #$EA if we should also look in gSlideshowStore ; out: C clear if game exists in gGamesListStore, and ; A/Y points to game display name (but see hack notes below) ; 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) 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 clc @exit rts PlayGameFromSearch PlayGameFromBrowse stx @gameIndex jsr okvs_nth !word gGamesListStore @gameIndex !byte $FD ; SMC jmp .Go PlayGameFromAttract jsr LoadAndParseAttractModeConf jsr okvs_nth ; get filename of current attract-mode module !word gAttractModeStore gCurrentAttractIndex !byte $FD ; set in MegaAttractMode +STAY @key jsr okvs_get !word gAttractModeStore @key !word $FDFD ; SMC +STAY PTR ldy #1 lda (PTR),y and #$0F bne @playFromSlideshow ; we reached here by pressing during a self-running demo, ; which means that @key points to the filename of the game we want to play +LDAY @key jmp .Go @playFromSlideshow ; we reached here by pressing during a slideshow ; gSlideshowStore is still in memory, and gCurrentlyVisibleSlideshowIndex ; is the index into gSlideshowStore of the picture that is being displayed jsr okvs_nth !word gSlideshowStore gCurrentlyVisibleSlideshowIndex !byte $FD ; set in HGRTitleCallback, HGRActionCallback, DHGRTitleCallback +STAY @sskey +STAY @sskey2 jsr okvs_get !word gGamesListStore @sskey !word $FDFD ; SMC bcs + +LDAY @sskey jmp .Go + ; if the key is not found, try getting the value of the current record ; from gSlideshowStore and using that instead ; (some games have multiple action screenshots, value points to the key in gGamesListStore) jsr okvs_get !word gSlideshowStore @sskey2 !word $FDFD ; SMC bcc .Go rts .Go +STAY SAVE ; TODO check if cheats are enabled and available for this game jsr LoadFile ; load standard prelaunch code (|Launch| will call it) !word kPrelaunchDirectory !word kStandardPrelaunch !word $0106 ldx #1 ; construct path to game's startup file sec ; which is always /X/game/game !byte $2c -- pha clc php ldy #0 lda (SAVE), y tay iny sty @runlength+1 ldy #0 lda #'X' sta ProDOS_prefix+1 lda #'/' - inx sta ProDOS_prefix, x iny lda (SAVE), y @runlength cpy #$D1 ; SMC bne - txa plp bcs -- stx ProDOS_prefix jsr LoadFile ; load the game startup file !word kRootDirectory !word ProDOS_prefix !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 +READ_RAM2_WRITE_RAM2 jsr SaveOrRestoreScreenHoles ; save screen hole contents ldx #$F1 - lda $100,x sta $DF00,x ; back up stack inx bne - tsx ; back up stack pointer stx $DFF0 lda #$38 ; 'sec' opcode to tell |Reenter| to sta RestoreStackNextTime ; restore the stack and stack pointer ldx #(end_promote-promote-1) - lda promote,x ; copy ProDOS shim to main memory sta $bf00,x dex bpl - jmp $106 ; jump to pre-launch code }