;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 LoadIndexedFile ; load pre-parsed attract mode configuration data into $6000 !word kTotalIndexFile - !word $6000 !word kAttractModeIndexRecord 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. +LD16 gLastMegaAttractGame jsr PlayGameInAY ; (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 (including gSearchStore) ;------------------------------------------------------------------------------ MiniAttractMode jsr GetGameToLaunch +ST16 + jsr LoadIndexedFile !word kTotalIndexFile - !word $0800 !word kMiniAttractIndexRecord jsr okvs_find !word - + !word $FDFD ; SMC jsr okvs_next_field jsr SwitchToBank2 sty OKVS_CACHE ldy #4 - lda (PTR), y sta OKVS_CACHE + 1, y dey bpl - jsr BlankHGR ; X = 0 stx @MiniAttractIndex+1 stx @MiniAttractIndex+3 @loop jsr LoadIndexedFile !word kTotalDataFile - !word $6000 !word OKVS_CACHE +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_next_field ; 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 demo has been patched to check joystick and memory requirements, ; so a demo won't run if the actual game wouldn't be playable. ; Demos are also patched to jump back to the |Reenter| entry point ; on any key, or at the natural end of the demo cycle. ; All demos are strictly 48K / main memory. No demo uses the ; language card or auxiliary memory. +ST16 PTR ldy #0 lda (PTR), y tay - lda (PTR), y sta DemoFilename, y dey bpl - +LDADDR DemoFilename +ST16 gLastMegaAttractGame ; save game filename in LC in case user hits Return to launch 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 LoadIndexedFile ; load slideshow configuration file into $4000 !word kTotalIndexFile - !word $4000 !word kAttractModeSlideshowIndexRecord jsr okvs_find !word - @key2 !word $FDFD ; SMC +ST16 + jsr LoadIndexedFile !word kTotalDataFile !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 DemoFilename !byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15