;license:MIT ;(c) 2018-2021 by 4am & qkumba ; ; Attract Mode - cycle through slideshows and self-running demos ; ; Public functions ; - MegaAttractMode ; - MiniAttractMode ; - RunAttractModule ;------------------------------------------------------------------------------ ; MegaAttractMode ; main entry point for Mega Attract Mode, which endlessly cycles through ; modules listed in ATTRACT.CONF to display title pages, action screenshots, ; super hi-res box art (on supporting platforms), and self-running game demos ; ; in: gGlobalPrefsStore must be initialized ; out: never returns to caller (may JMP to other major modes) ;------------------------------------------------------------------------------ MegaAttractMode jsr SwitchToBank1 ldx #$FF txs jsr BlankHGR ; switch to HGR page 1 (once cleared) jsr LoadFile ; load pre-parsed attract mode configuration data into $6000 !word kRootDirectory !word kAttractModeIndexFile - !word $6000 jsr pref_get ; get attract mode module from prefs !word kNextAttract !word - +ST16 @mname ; A/Y = module name ; $WINDEX = index of module in attract store +LDADDR - jsr okvs_next ; get module after this one +ST16 + jsr pref_set ; update prefs store and save to disk !word kNextAttract + !word $FDFD ; SMC jsr okvs_get ; sets PTR !word - @mname !word $FDFD ; SMC ldy #1 lda (PTR),y tax ; X = module type +LD16 @mname ; A/Y = address of module name jsr RunAttractModule lda KBD bpl MegaAttractMode cmp #$8D ; Enter plays the game shown on screen. bne + ; Any other key switches to Search Mode. jsr ReloadSearchIndex jsr PlayGame ; (might return if user hits Ctrl-Reset) + jmp SearchMode ;------------------------------------------------------------------------------ ; MiniAttractMode ; run attract modules related to one game ; ; in: gGameToLaunch = index in gSearchStore (word) ; gSearchStore populated ; out: all flags and registers clobbered ; assume all of main memory has been clobbered ;------------------------------------------------------------------------------ MiniAttractMode jsr GetGameToLaunch +ST16 + jsr BlankHGR ; X = 0 stx @MiniAttractIndex+1 stx @MiniAttractIndex+3 @loop jsr LoadFile ; load mini attract mode configuration file into $6000 !word kRootDirectory !word kMiniAttractIndexFile - !word $6000 jsr okvs_find !word - + !word $FDFD ; SMC +ST16 @indexRecordPtr jsr LoadIndexedFile !word kAttractModeFulFile - !word $6000 @indexRecordPtr !word $FDFD ; SMC +LDADDR - jsr okvs_len lda WCOUNT cmp @MiniAttractIndex+1 bne + lda WCOUNT+1 cmp @MiniAttractIndex+3 beq ATTRTS ; we've run through all modules, so exit to caller + @MiniAttractIndex +LDADDR 0 ; SMC +ST16 WINDEX +LDADDR - jsr okvs_nth ; get the next module on the list +ST16 SAVE jsr okvs_get_current ; get module type ; Y = 0 iny lda (PTR),y tax ; X = module type +LD16 SAVE ; A/Y = address of module name jsr RunAttractModule ; execute the module inc @MiniAttractIndex+1 bne + inc @MiniAttractIndex+3 + lda KBD bpl @loop ATTRTS rts ;------------------------------------------------------------------------------ ; RunAttractModule ; run a single attract module of any type and return to caller ; ; in: X = module type as ASCII char (1-6,A-C, see attract.conf) ; A/Y = address of module name ; for demos, this is the filename of an executable in /demo/ ; for slideshows, this is the filename of a .conf file in /ss/ ; for singles, this is a pathname of the graphic to load ; gGlobalPrefsStore must be initialized (if we load a transition effect ; of any kind, we will update the global prefs with the next one) ; out: all flags and registers clobbered ; assume all of main memory has been clobbered ;------------------------------------------------------------------------------ RunAttractModule +ST16 @key +ST16 @key2 cpx #$30 bne @NotDemo ; Self-running demos are loaded into main memory and executed. ; Each binary has been patched to quit on any key and jump back ; to the |Reenter| entry point. ; All demos are strictly 48K / main memory. No demo uses the ; language card or auxiliary memory. +LD16 @key jsr FindGame bcs ATTRTS ; if game doesn't exist, skip the demo +LD16 WINDEX +CMP16_E $FFFF, @nogame +ST16 gGameToLaunch ; if this demo corresponds to a game, save its index ; in case user presses RETURN during the demo (we will launch the game) @nogame jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) jsr LoadStandardPrelaunch ; load standard prelaunch code (|Launch| will call it) jsr LoadFile ; load self-running demo into its default address (varies) !word kDemoDirectory @key !word $FDFD !word 0 jmp Launch ; will return to caller via |Reenter| ; not a demo, so maybe a slideshow or single screenshot @NotDemo txa cmp #$41 ; numbers are slideshow modules, bcs @dispatchSingle ; letters are single files ; it's a slideshow, so load slideshow configuration file pha ; save module type jsr LoadFile ; load slideshow configuration file into $4000 !word kAttractModeSlideshowIndexFile !word kRootDirectory - !word $4000 jsr okvs_find !word - @key2 !word $FDFD ; SMC +ST16 + jsr LoadIndexedFile !word kAttractModeSlideshowFulFile !word $800 + !word $FDFD ; SMC pla ; restore module type +HIDE_NEXT_2_BYTES @dispatchSingle adc #(@singleslo-@slideshowslo)-1 - and #$0F ; convert ASCII digit to int tax lda @slideshowslo-1,x sta @jmp+1 lda @slideshowshi-1,x sta @jmp+2 +LD16 @key ; pass in module name @jmp jmp $FDFD ; SMC @slideshowslo !byte HGRTitleSlideshow !byte >HGRActionSlideshow !byte >DHGRTitleSlideshow !byte >DHGRActionSlideshow !byte >SHRSlideshow !byte >GRActionSlideshow @singleshi !byte >HGRSingle !byte >DHGRSingle !byte >SHRSingle !byte >GRSingle