;(c) 2018-2021 by 4am & qkumba ; ; Double hi-res slideshows ; ; Public functions ; - DHGRTitleSlideshow ; - DHGRActionSlideshow ; - DHGRSingle ; - BlankHGR ; - HGRMode ; - GRMode ; - ForceHGRMode ; - DrawGameTitleInActionSlideshow ; - RedrawForDHGR ; ;------------------------------------------------------------------------------ ; DHGRTitleSlideshow ; execute a slideshow of double hi-res title screenshots ; ; safe to call if machine only has 64K (does nothing and exits) ; ; in: none ; out: everything clobbered ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ DHGRTitleSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files !word gSlideshowStore !word DHGRTitleCallback ; address of callback (called on each file) beq BlankHGR ; switch back to HGR mode with initial blank screen on exit ; (always branches because Z=1 on exit of okvs_iter) ;------------------------------------------------------------------------------ ; DHGRActionSlideshow ; execute a slideshow of double hi-res action screenshots ; ; safe to call if machine only has 64K (does nothing and exits) ; ; in: none ; out: everything clobbered ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ DHGRActionSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files !word gSlideshowStore !word DHGRActionCallback ; address of callback (called on each file) beq BlankHGR ; switch back to HGR mode with initial blank screen on exit ; (always branches because Z=1 on exit of okvs_iter) ;------------------------------------------------------------------------------ ; DHGRSingle ; display a single double hi-res screenshot, with transition effect ; ; safe to call if machine only has 64K (does nothing and exits) ; ; in: none ; out: everything clobbered ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ DHGRSingle bit MachineStatus ; only show DHGR screenshots if we have 128K bvc DHGRRTS0 +ST16 IndexedDHGRFilename jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr LoadIndexedDHGRFile ; load compressed DHGR screenshot at aux $3FF8 jsr DecompressDHGR jsr LoadDHGRTransition ; load transition effect code at $6000 jsr ExecuteTransitionAt6000AndWait ; switch back to HGR mode with initial blank screen on exit ; /!\ execution falls through here to BlankHGR ;------------------------------------------------------------------------------ ; BlankHGR ; clear and show HGR page 1 without flickering ; ; in: none ; out: text page clobbered ; A/X/Y=0 (guaranteed by ClearHGR1) ; $2000..$3FFF cleared ;------------------------------------------------------------------------------ BlankHGR jsr Home BlankHGRNoHome jsr ClearHGR1 ; clear hi-res screen 1 bit PAGE1 ; show hi-res screen 1 (now blank) lda #1 sta OffscreenPage ; /!\ execution falls through here to HGRMode ;------------------------------------------------------------------------------ ; HGRMode / GRMode ; twiddles softswitches to set (H)GR mode (does not set page 1 or 2) ; ; in: none ; out: all registers preserved ;------------------------------------------------------------------------------ HGRMode bit $C057 GRMode bit $C052 bit $C050 DHGRRTS0 rts ;------------------------------------------------------------------------------ ; ForceHGRMode ; if machine is in DHGR mode, switch it back to HGR mode ; otherwise do nothing ; ; in: none ; out: see BlankHGR ;------------------------------------------------------------------------------ ForceHGRMode gMachineInDHGRMode=*+1 lda #$00 ; SMC bne BlankHGR rts ;------------------------------------------------------------------------------ ; LoadDHGRTransition [private] ; looks up name of next DHGR transition effect in DFX.CONF and loads that file ; at $6000 ; in: gDFXStore has been initialized ; gGlobalPrefsStore has been initialized ; out: all registers and flags clobbered ; $6000..$BFFF/main contains transition effect code ;------------------------------------------------------------------------------ LoadDHGRTransition jsr LoadIndexedFile ; load DHGR transition effects list into $6000 - !word $6000 !word kDFXIndexRecord jsr pref_get ; get DHGR transition effect from prefs !word kNextDFX !word - +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) ; $WINDEX = index of the transition in DFX store +LDADDR - jsr okvs_next ; get transition after this one +ST16 + jsr pref_set ; update prefs store and save to disk !word kNextDFX + !word $FDFD ; SMC jsr LoadIndexedFile !word $6000 @indexRecordPtr !word $FDFD ; SMC DHGRRTS1 rts ;------------------------------------------------------------------------------ ; DHGRTitleCallback [private] ; callback called by okvs_iter on gSlideshowStore ; to load and display a single DHGR title screenshot ; in: A/Y contains address of filename (name only, path is always /TITLE.DHGR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code ; $2000..$5FFF/aux clobbered ;------------------------------------------------------------------------------ DHGRTitleCallback bit KBD bmi DHGRRTS1 +ST16 + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows bcs DHGRRTS1 +LD16 WINDEX ; save game index in case user hits RETURN +ST16 gGameToLaunch ; while it's visible (we'll launch it) jsr LoadIndexedFile ; load index file into $4000 - !word $4000 !word kDHGRTitleIndexRecord jsr okvs_get !word - + !word $FDFD ; SMC jsr SwitchToBank2 ldy #4 - lda (PTR), y sta OKVS_CACHE + 1, y dey bpl - jsr LoadIndexedDHRFile jmp ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ ; DHGRActionCallback [private] ; callback called by okvs_iter on gSlideshowStore ; to load and display a single DHGR action screenshot ; in: A/Y contains address of filename (name only, path is always /ACTION.DHGR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code ; $2000..$5FFF/aux clobbered ;------------------------------------------------------------------------------ DHGRActionCallback bit KBD bmi DHGRRTS1 +ST16 IndexedDHGRFilename jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs DHGRRTS1 jsr LoadIndexedDHGRFile jsr DecompressDHGR lda #$EA ; NOP +HIDE_NEXT_2_BYTES ; /!\ execution falls through here to DrawGameTitleInActionSlideshowHGR ;------------------------------------------------------------------------------ ; DrawGameTitleInActionSlideshow ; draw the game title in the lower left corner of the screen ; ; /!\ exits via ExecuteTransitionAt6000AndWait, and the transition code must ; already be loaded at $6000 ; ; in: none ; out: exits via ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ DrawGameTitleInActionSlideshow lda #$60 ; RTS sta @fallthroughForDHGR ; display game name in the bottom-left corner lda #22 sta VTAB lda #0 ; solid horizontal bar character jsr @resetline lda (SAVE),y ; (SAVE) -> game display name, Y = 0, so A = display length clc adc #$03 sta gPathname lda #7 ; top-right rounded corner character jsr @drawline lda #" " jsr @resetline lda (SAVE),y ; A = display length tay - lda (SAVE),y sta gPathname+1,y dey bne - lda #3 ; solid vertical bar character jsr @drawline jmp ExecuteTransitionAt6000AndWait @resetline ldy #40 - sta gPathname,y dey bne - sty HTAB rts @drawline ldy gPathname sta gPathname,y +LDADDR gPathname sec jsr DrawString @fallthroughForDHGR nop ; SMC ; /!\ execution sometimes falls through here to RedrawForDHGR ;------------------------------------------------------------------------------ ; RedrawForDHGR ; After drawing text on HGR screen, this will transform the low-level bytes ; to display properly on the DHGR screen. ; ; /!\ must be called immediately after calling one of the font drawing routines ; (Draw40Chars, DrawCenteredString, DrawString) ; ; in: gPathname contains number of bytes to transform ; DBIRow0/LC2 contains address of first byte of first row to transform ; (this will be true if you just called DrawBufferInternal or ; something that calls it, see above) ; out: clobbers zero page $00,$01,$02,$26,$27,$F7 ;------------------------------------------------------------------------------ RedrawForDHGR jsr SwitchToBank2 +LD16 DBIRow0+1 +ST16 $26 lda #8 sta i -- ldy gPathname dey - lda ($26),y +HGR_BYTE_TO_DHGR_BYTES sta ($26),y txa sta WRITEAUXMEM sta ($26),y sta WRITEMAINMEM dey bpl - lda $27 clc adc #$04 sta $27 dec i bne -- jmp SwitchToBank1 LoadIndexedDHGRFile ; in: caller has set IndexedDHGRFilename ; out: all flags & registers clobbered jsr LoadIndexedFile ; load index file into $4000 - !word $4000 !word kDHGRActionIndexRecord jsr okvs_find !word - IndexedDHGRFilename !word $FDFD ; SMC +ST16 @indexRecordPtr jsr LoadAuxIndexedFile ; load compressed DHGR screenshot at aux $3FF8 !word $3FF8 @indexRecordPtr !word $FDFD ; SMC rts