mirror of
https://github.com/a2-4am/4cade.git
synced 2024-12-23 16:29:34 +00:00
add cheats subsystem (parsing of games.conf, UI, loading appropriate prelaunch file)
This commit is contained in:
parent
4682a8201a
commit
4b66697758
4
Makefile
4
Makefile
@ -20,7 +20,9 @@ ACME=acme
|
||||
# https://github.com/mach-kernel/cadius
|
||||
CADIUS=cadius
|
||||
|
||||
asm: md asmfx asmprelaunch
|
||||
asm: md asmlauncher asmfx asmprelaunch
|
||||
|
||||
asmlauncher:
|
||||
$(ACME) src/4cade.a 2>build/relbase.log
|
||||
$(ACME) -r build/4cade.lst -DRELBASE=`cat build/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4cade.a
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -72,6 +72,7 @@ RestoreStackNextTime
|
||||
!source "src/ui.attract.dhgr.a"
|
||||
!source "src/ui.attract.shr.a"
|
||||
!source "src/ui.attract.gr.a"
|
||||
!source "src/ui.cheats.a"
|
||||
!source "src/prodos.path.a"
|
||||
!source "src/glue.launch.a"
|
||||
!source "src/glue.prorwts2.a"
|
||||
@ -90,7 +91,7 @@ gDFXStore
|
||||
gSlideshowStore
|
||||
!word $0800
|
||||
gGlobalPrefsStore
|
||||
!word $D000
|
||||
!word $D100
|
||||
gGamesListStore
|
||||
!word $FDFD ; SMC
|
||||
!word Reenter ; NMI vector ($FFFA-B)
|
||||
|
@ -215,6 +215,10 @@ OneTimeSetup
|
||||
!word gGamesListStore
|
||||
sta GameCount
|
||||
sta SAVE
|
||||
|
||||
lda #$80 ; TODO make this a pref
|
||||
sta gCheatsEnabled
|
||||
|
||||
; calculate and update visible game count (3-digit decimal number as ASCII string)
|
||||
ldy #0
|
||||
@outer
|
||||
|
@ -81,5 +81,10 @@ gKey = $1F01
|
||||
gValLen = $1F80
|
||||
gVal = $1F81
|
||||
|
||||
; LC RAM 1
|
||||
gCheatsAvailable = $D000 ; master cheats table, indexed by game index in gGamesListStore
|
||||
; 1 byte per game, so max size = 256 games
|
||||
gCheatsEnabled = $D0FF ; bit 7 = 1 if cheats are enabled
|
||||
|
||||
; actual constants
|
||||
SUPPORTS_SHR = %00110000 ; AND mask for MachineStatus
|
||||
|
@ -9,6 +9,7 @@
|
||||
; Public functions
|
||||
; - DrawPage
|
||||
; - Draw40Chars
|
||||
; - DrawCenteredString
|
||||
; - DrawString
|
||||
; - DrawBuffer
|
||||
;
|
||||
@ -25,6 +26,12 @@ Draw40Chars
|
||||
+READ_RAM1_WRITE_RAM1
|
||||
rts
|
||||
|
||||
DrawCenteredString
|
||||
+READ_RAM2_WRITE_RAM2
|
||||
jsr DrawCenteredStringInternal
|
||||
+READ_RAM1_WRITE_RAM1
|
||||
rts
|
||||
|
||||
DrawString
|
||||
+READ_RAM2_WRITE_RAM2
|
||||
jsr DrawStringInternal
|
||||
|
@ -129,15 +129,29 @@ gCurrentlyVisibleSlideshowIndex
|
||||
rts
|
||||
|
||||
.Go
|
||||
; in: A/Y = lo/hi address of filename
|
||||
; X = game index
|
||||
+STAY SAVE
|
||||
+STAY +
|
||||
|
||||
; TODO check if cheats are enabled and available for this game
|
||||
bit gCheatsEnabled ; are cheats enabled?
|
||||
bpl @noCheats
|
||||
ldy gCheatsAvailable,x ; are there any cheats for this game?
|
||||
beq @noCheats
|
||||
|
||||
jsr LoadFile ; load standard prelaunch code (|Launch| will call it)
|
||||
!word kPrelaunchDirectory
|
||||
jsr LoadFile ; cheats are enabled and this game has a prelaunch
|
||||
!word kPrelaunchDirectory ; file that will set up the cheats, so load that
|
||||
+ !word $FDFD ; SMC
|
||||
!word $0106
|
||||
jmp @loadedPrelaunch
|
||||
|
||||
@noCheats
|
||||
jsr LoadFile ; no game-specific prelaunch file, so
|
||||
!word kPrelaunchDirectory ; load standard prelaunch file instead
|
||||
!word kStandardPrelaunch
|
||||
!word $0106
|
||||
|
||||
@loadedPrelaunch
|
||||
ldx #1 ; construct path to game's startup file
|
||||
sec ; which is always /X/game/game
|
||||
!byte $2c
|
||||
|
@ -116,7 +116,8 @@ okvs_len
|
||||
; +3 [word] address of key
|
||||
; +5 [word] address of value
|
||||
; +7 [byte] maximum length of value (or 0 to fit)
|
||||
; out: all registers clobbered
|
||||
; out: X = new number of records (same as calling okvs_len after okvs_append)
|
||||
; A/Y clobbered
|
||||
; $00/$01 clobbered
|
||||
; $02/$03 clobbered
|
||||
; $04/$05 has the address of the next available byte after the new record
|
||||
@ -130,6 +131,7 @@ okvs_append
|
||||
lda (PTR),y ; A = number of keys in store
|
||||
clc
|
||||
adc #1
|
||||
pha ; will return this later
|
||||
sta (PTR),y ; increment number of keys
|
||||
iny
|
||||
lda (PTR),y ; get address of next free space
|
||||
@ -201,6 +203,8 @@ okvs_append
|
||||
iny
|
||||
lda SRC+1
|
||||
sta (PTR),y
|
||||
pla
|
||||
tax ; X = new OKVS length
|
||||
jsr GetStoreAddress
|
||||
; PTR -> store
|
||||
ldy #1
|
||||
|
@ -66,15 +66,17 @@ ParseGamesList
|
||||
@filterOnMemory
|
||||
jsr IncAndGetChar ; get second filter character ('1' if game requires 128K)
|
||||
cmp #$30 ; '0' -> no filtering on memory
|
||||
beq @swallowComma
|
||||
beq @parseCheatsAvailable
|
||||
cmp #$31 ; not '0' or '1' -> ignore entire line
|
||||
bne @skipLine
|
||||
bit zpMachineStatus
|
||||
bvc @skipLine ; game requires 128K but we only have 64K, so ignore entire line
|
||||
@parseCheatsAvailable
|
||||
jsr IncAndGetChar ; get third character (cheat category, int)
|
||||
and #$0F
|
||||
pha
|
||||
@swallowComma
|
||||
jsr IncAndGetChar
|
||||
cmp #$2C ; ',' delimiter (required)
|
||||
bne @skipLine
|
||||
@gatherKey
|
||||
jsr IncAndGetChar
|
||||
cmp #$3D ; '=' ends the key
|
||||
@ -100,8 +102,12 @@ ParseGamesList
|
||||
!word gKeyLen
|
||||
!word gValLen
|
||||
!byte 0
|
||||
pla
|
||||
; X = new OKVS length
|
||||
pla ; pop saved Y
|
||||
tay
|
||||
pla ; pop cheat category
|
||||
dex ; X = new OKVS length - 1
|
||||
sta gCheatsAvailable,x
|
||||
clc
|
||||
bcc @newkey ; always branches
|
||||
|
||||
|
@ -130,12 +130,10 @@ GameCount = *+1
|
||||
sta UI_ToPlay,x
|
||||
dex
|
||||
bpl -
|
||||
ldx #40
|
||||
lda #0
|
||||
- sta UILine1-1,x ; reset UI line 1
|
||||
dex
|
||||
bne -
|
||||
jsr DrawSearchBarOffscreen ; actually draw the search UI (offscreen)
|
||||
ldx @index
|
||||
jsr BuildUILine1WithNoDots ; build UI line 1 with bars and other shapes
|
||||
ldx @index
|
||||
jsr DrawSearchBarOffscreen ; actually draw the UI (offscreen)
|
||||
jmp ShowOtherPage ; now show everything at once
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
|
145
src/ui.cheats.a
Normal file
145
src/ui.cheats.a
Normal file
@ -0,0 +1,145 @@
|
||||
BuildUILine1WithNoDots
|
||||
; in: X = game index, or #$FF if no game selected
|
||||
; out: all registers clobbered
|
||||
; UILine1 contains 40-character buffer (not length-prefixed) to print
|
||||
cpx #$FF
|
||||
beq +
|
||||
ldy gCheatsAvailable,x
|
||||
+HIDE_NEXT_2_BYTES
|
||||
+
|
||||
ldy #.kCheatsEnabled
|
||||
|
||||
ldx #40
|
||||
lda #$00 ; horizontal bar
|
||||
- sta UILine1-1,x ; first, reset entire line to solid bar
|
||||
dex
|
||||
bne -
|
||||
|
||||
bit gCheatsEnabled
|
||||
bpl @done ; if cheats are not enabled, we're done
|
||||
|
||||
lda .kCheatDescriptionLo,y
|
||||
sta PTR
|
||||
lda .kCheatDescriptionHi,y
|
||||
sta PTR+1
|
||||
; (PTR) -> length-prefixed cheat description
|
||||
ldy #0
|
||||
lda (PTR),y ; A = length of cheat description
|
||||
clc
|
||||
adc #8 ; extra padding (4 on each side) for string
|
||||
sta @len
|
||||
lda #40
|
||||
sec
|
||||
sbc @len
|
||||
lsr
|
||||
tax
|
||||
lda #$09 ; rounded bottom-right character
|
||||
sta UILine1,x
|
||||
ldy #1 ; fill the proper width with spaces
|
||||
lda #$20 ; space character
|
||||
- inx
|
||||
sta UILine1,x
|
||||
iny
|
||||
@len=*+1
|
||||
cpy #$FD ; SMC
|
||||
bne -
|
||||
lda #$08 ; rounded bottom-left character
|
||||
sta UILine1,x
|
||||
|
||||
@done rts
|
||||
|
||||
BuildCheatLine1
|
||||
; in: X = game index, or #$FF if no game is selected
|
||||
; out: gPathname contains length-prefixed string to print centered
|
||||
; all registers clobbered
|
||||
; PTR clobbered
|
||||
cpx #$FF
|
||||
beq +
|
||||
ldy gCheatsAvailable,x
|
||||
+HIDE_NEXT_2_BYTES
|
||||
+
|
||||
ldy #.kCheatsEnabled
|
||||
|
||||
ldx #39 ; reset gPathname+2 to gPathname+41 to
|
||||
lda #$00 ; horizontal bar character
|
||||
- sta gPathname+1,x
|
||||
dex
|
||||
bne -
|
||||
|
||||
lda #$06 ; gPathname+1 = top-left rounded corner character
|
||||
sta gPathname+1
|
||||
|
||||
lda .kCheatDescriptionLo,y
|
||||
sta PTR
|
||||
lda .kCheatDescriptionHi,y
|
||||
sta PTR+1
|
||||
; (PTR) -> length-prefixed cheat description
|
||||
ldy #0
|
||||
lda (PTR),y ; A = length of cheat description
|
||||
clc
|
||||
adc #8 ; extra padding (4 on each side) for string
|
||||
sta gPathname ; gPathname = length
|
||||
tax
|
||||
lda #$07 ; gPathname+length = top-right rounded corner character
|
||||
sta gPathname,x
|
||||
rts
|
||||
|
||||
BuildCheatLine2
|
||||
; in: X = game index, or #$FF if no game is selected
|
||||
; out: gPathname contains length-prefixed string to print centered
|
||||
; all registers clobbered
|
||||
; PTR clobbered
|
||||
; SAVE clobbered
|
||||
cpx #$FF
|
||||
beq +
|
||||
ldy gCheatsAvailable,x
|
||||
+HIDE_NEXT_2_BYTES
|
||||
+
|
||||
ldy #.kCheatsEnabled
|
||||
lda .kCheatDescriptionLo,y
|
||||
sta SAVE
|
||||
lda .kCheatDescriptionHi,y
|
||||
sta SAVE+1
|
||||
; (SAVE) -> length-prefixed cheat description
|
||||
+LDADDR .sCheatDescriptionPrefix
|
||||
jsr SetPath
|
||||
+LDAY SAVE
|
||||
jsr AddToPath
|
||||
+LDADDR .sCheatDescriptionSuffix
|
||||
jmp AddToPath
|
||||
|
||||
.kCheatsEnabled = 3 ; index of 'cheats enabled' string in following table
|
||||
.kCheatDescriptionLo
|
||||
!byte <.sNoCheats
|
||||
!byte <.sInfiniteLives
|
||||
!byte <.sInfiniteLivesAndWeapons
|
||||
!byte <.sCheatsEnabled
|
||||
.kCheatDescriptionHi
|
||||
!byte >.sNoCheats
|
||||
!byte >.sInfiniteLives
|
||||
!byte >.sInfiniteLivesAndWeapons
|
||||
!byte >.sCheatsEnabled
|
||||
.sNoCheats
|
||||
!byte 14
|
||||
!text "no cheats yet!"
|
||||
.sInfiniteLives
|
||||
!byte 14
|
||||
!text "infinite lives"
|
||||
.sInfiniteLivesAndWeapons
|
||||
!byte 24
|
||||
!text "infinite lives & weapons"
|
||||
.sCheatsEnabled
|
||||
!byte 14
|
||||
!text "cheats enabled"
|
||||
.sCheatDescriptionPrefix
|
||||
!byte 4
|
||||
!byte $03 ; vertical line
|
||||
!text " "
|
||||
!byte $16 ; bolt
|
||||
!text " "
|
||||
.sCheatDescriptionSuffix
|
||||
!byte 4
|
||||
!text " "
|
||||
!byte $16 ; bolt
|
||||
!text " "
|
||||
!byte $03 ; vertical line
|
@ -142,20 +142,47 @@ CoverFade
|
||||
; DrawSearchBarOffscreen
|
||||
; draw 2-line search UI on the HGR page that is not currently showing
|
||||
;
|
||||
; in: none
|
||||
; in: X = game index, or #$FF if no game is selected
|
||||
; out: all flags and registers clobbered
|
||||
;------------------------------------------------------------------------------
|
||||
DrawSearchBarOffscreen
|
||||
txa
|
||||
pha
|
||||
lda #22 ; draw visible search bar
|
||||
sta VTAB
|
||||
lda OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
ror ; draw line 1 on offscreen page
|
||||
+LDADDR UILine1
|
||||
jsr Draw40Chars
|
||||
lda OffscreenPage
|
||||
ror ; draw on offscreen page
|
||||
ror ; draw line 2 on offscreen page
|
||||
+LDADDR UILine2
|
||||
jmp Draw40Chars
|
||||
jsr Draw40Chars
|
||||
|
||||
pla
|
||||
bit gCheatsEnabled
|
||||
bpl @done ; if cheats are not enabled, we're done
|
||||
|
||||
pha
|
||||
tax
|
||||
lda #20
|
||||
sta VTAB
|
||||
jsr BuildCheatLine1
|
||||
lda OffscreenPage
|
||||
ror
|
||||
+LDADDR gPathname
|
||||
jsr DrawCenteredString
|
||||
|
||||
inc VTAB
|
||||
pla
|
||||
tax
|
||||
jsr BuildCheatLine2
|
||||
lda OffscreenPage
|
||||
ror
|
||||
+LDADDR gPathname
|
||||
jsr DrawCenteredString
|
||||
|
||||
@done rts
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; ClearOffscreen
|
||||
|
@ -10,6 +10,7 @@
|
||||
; Public functions
|
||||
; - DrawPageInternal
|
||||
; - Draw40CharsInternal
|
||||
; - DrawCenteredStringInternal
|
||||
; - DrawStringInternal
|
||||
; - DrawBufferInternal
|
||||
;
|
||||
@ -86,6 +87,27 @@ Draw40CharsInternal
|
||||
stx HTAB
|
||||
rts
|
||||
|
||||
DrawCenteredStringInternal
|
||||
; A/Y contains address of length-prefixed string
|
||||
; carry bit clear -> draw on page 1
|
||||
; carry bit set -> draw on page 2
|
||||
; $25 contains textpage line (0..23) (this is the standard VTAB address)
|
||||
; clobbers A/X/Y
|
||||
; clobbers PTR/PTR+1
|
||||
+STAY PTR
|
||||
|
||||
php
|
||||
ldy #0
|
||||
lda (PTR),y
|
||||
sta HTAB
|
||||
lda #40
|
||||
sec
|
||||
sbc HTAB
|
||||
lsr
|
||||
sta HTAB
|
||||
plp
|
||||
jmp +
|
||||
|
||||
DrawStringInternal
|
||||
; A/Y contains address of length-prefixed string
|
||||
; carry bit clear -> draw on page 1
|
||||
@ -97,7 +119,7 @@ DrawStringInternal
|
||||
+STAY PTR
|
||||
|
||||
ldy #0
|
||||
lda (PTR),y
|
||||
+ lda (PTR),y
|
||||
tax
|
||||
inc PTR
|
||||
bne +
|
||||
|
@ -120,16 +120,17 @@ SearchMode
|
||||
; no input, reset params and UI
|
||||
lda #$FF
|
||||
sta SelectedIndex ; no game selected
|
||||
ldx #39 ; reset visible line
|
||||
- lda #0
|
||||
sta UILine1,x
|
||||
lda Instructions,x
|
||||
ldx #39 ; copy instructions to line 2
|
||||
- lda Instructions,x
|
||||
sta UILine2,x
|
||||
dex
|
||||
bpl -
|
||||
jsr LoadTitleOffscreen
|
||||
jsr DrawSearchBarOffscreen
|
||||
jsr ShowOtherPage
|
||||
ldx #$FF ; no game selected
|
||||
jsr BuildUILine1WithNoDots; build UI line 1 with bars and other shapes
|
||||
ldx #$FF ; no game selected
|
||||
jsr DrawSearchBarOffscreen; draw everything at once (offscreen)
|
||||
jsr ShowOtherPage ; show it all at once
|
||||
clc
|
||||
rts
|
||||
|
||||
@ -199,19 +200,20 @@ SearchMode
|
||||
sta UI_ToPlay,x
|
||||
dex
|
||||
bpl -
|
||||
ldx #40
|
||||
lda #0
|
||||
- sta UILine1-1,x ; reset search bar
|
||||
dex
|
||||
bne -
|
||||
tay
|
||||
|
||||
ldx SelectedIndex
|
||||
jsr BuildUILine1WithNoDots; build UI line 1 with bars and other shapes
|
||||
|
||||
; now add dots to UI line 1 to highlight matched characters
|
||||
ldx #0
|
||||
ldy #0
|
||||
@dotloop
|
||||
iny
|
||||
lda (SRC),y
|
||||
+LOW_ASCII_TO_LOWER
|
||||
cmp InputBuffer,x
|
||||
bne +
|
||||
lda #$11 ; add dots to highlight matched characters
|
||||
lda #$11 ; dot character
|
||||
sta UILine1,y
|
||||
inx
|
||||
cpx InputLength ; if input buffer is exhausted, we're done
|
||||
@ -220,6 +222,7 @@ SearchMode
|
||||
cpy SAVE ; if game name is exhausted, we're done
|
||||
bne @dotloop
|
||||
@doneHighlight
|
||||
ldx SelectedIndex
|
||||
jsr DrawSearchBarOffscreen; actually draw the search UI (offscreen)
|
||||
jmp ShowOtherPage ; now show everything at once
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user