Implement item table encryption

This commit is contained in:
Kevin Cathcart
2018-07-08 16:38:45 -04:00
parent bc2d9d95a5
commit 14783a12e0
11 changed files with 214 additions and 68 deletions

View File

@@ -165,6 +165,7 @@ incsrc retro.asm
incsrc dpadinvert.asm
incsrc boots.asm
incsrc fileselect.asm
incsrc decryption.asm
warnpc $A58000
;org $228000 ; contrib area

View File

@@ -2,20 +2,21 @@
; Randomize Book of Mudora
;--------------------------------------------------------------------------------
LoadLibraryItemGFX:
LDA.l LibraryItem
%GetPossiblyEncryptedItem(LibraryItem, SpriteItemValues)
STA $0DA0, X ; Store item type
JSL.l PrepDynamicTile
RTL
;--------------------------------------------------------------------------------
DrawLibraryItemGFX:
PHA
LDA.l LibraryItem
LDA $0DA0, X ; Retrieve stored item type
JSL.l DrawDynamicTile
PLA
RTL
;--------------------------------------------------------------------------------
SetLibraryItem:
PHA
LDA LibraryItem : TAY
LDY $0DA0, X ; Retrieve stored item type
PLA
JSL.l ItemSet_Library ; contains thing we wrote over
RTL

93
decryption.asm Normal file
View File

@@ -0,0 +1,93 @@
!CryptoBuffer = "$7F5100"
;!keyBase = "$7F50D0"
;--------------------------------------------------------------------------------
LoadStaticDecryptionKey:
PHB : PHA : PHX : PHY : PHP
REP #$30 ; set 16-bit accumulator & index registers
LDX.w #StaticDecryptionKey ; Source
LDY.w #!keyBase ; Target
LDA.w #$000F ; Length
MVN $307F
PLP : PLY : PLX : PLA : PLB
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
RetrieveValueFromEncryptedTable:
;Requires 16-bit A and X/Y
;$00-$02 are long address of start of table
;A is desired byte offset into table
;Returns result in A
PHX : PHY
PHA
LDY $04 : PHY : LDY $06 : PHY : LDY $08 : PHY
LDY $0A : PHY : LDY $0C : PHY : LDY $0E : PHY
AND.w #$FFF8 : TAY
LDA [$00], Y : STA.l !CryptoBuffer : INY #2
LDA [$00], Y : STA.l !CryptoBuffer+2 : INY #2
LDA [$00], Y : STA.l !CryptoBuffer+4 : INY #2
LDA [$00], Y : STA.l !CryptoBuffer+6
; TODO: copy key into crypto Memory
LDA.w #$0002 : STA $04 ;set block size
JSL.l XXTEA_Decode
PLA : STA $0E : PLA : STA $0C : PLA : STA $0A
PLA : STA $08 : PLA : STA $06 : PLA : STA $04
PLA : AND.w #$0007 : TAX
LDA.l !CryptoBuffer, X
STZ.l !CryptoBuffer
STZ.l !CryptoBuffer+2
STZ.l !CryptoBuffer+4
STZ.l !CryptoBuffer+6
PLY : PLX
RTL
;--------------------------------------------------------------------------------
!ChestData = "$01E96C"
!ChestData_Payload = "$1EABC" ; !ChestData+$0150
;--------------------------------------------------------------------------------
GetChestData:
LDA.l IsEncrypted : BNE .encrypted
INC $0E : LDX.w #$FFFD ; what we wrote over
JML.l Dungeon_OpenKeyedObject_nextChest
.encrypted
INC $0E : LDX.w #$FFFE
.nextChest
INX #2 : CPX.w #$0150 : BEQ .couldntFindChest
LDA !ChestData, X : AND.w #$7FFF : CMP $A0 : BNE .nextChest
DEC $0E : BNE .nextChest
LDA $00 : PHA : LDA $02 : PHA
LDA.w #!ChestData_Payload : STA $00
LDA.w #!ChestData_Payload>>16 : STA $02
TXA : LSR
JSL RetrieveValueFromEncryptedTable
STA $0C
PLA : STA $02 : PLA : STA $00
LDA !ChestData, X : ASL A : BCC .smallChest
JML.l Dungeon_OpenKeyedObject_bigChest ;(bank01.asm line #13783)
.smallChest
JML.l Dungeon_OpenKeyedObject_smallChest
.couldntFindChest
JML.l Dungeon_OpenKeyedObject_couldntFindChest
;--------------------------------------------------------------------------------

View File

@@ -93,6 +93,10 @@ OnFileLoad:
JSL.l RefreshRainAmmo
JSL.l SetEscapeAssist
LDA.l IsEncrypted : CMP.b #01 : BNE +
JSL LoadStaticDecryptionKey
+
REP #$20 ; restore 16 bit accumulator
LDA.w #$0007 : STA $7EC00D : STA $7EC013 ; thing we wrote over - sets up some graphics timers
RTL

View File

@@ -5,7 +5,7 @@ SpawnHauntedGroveItem:
LDA $8A : CMP.b #$2A : BEQ + : RTL : + ; Skip if not the haunted grove
LDA $1B : BEQ + : RTL : + ; Skip if indoors
LDA.l HauntedGroveItem
%GetPossiblyEncryptedItem(HauntedGroveItem, HeartPieceOutdoorValues)
JSL.l PrepDynamicTile
LDA.b #$EB

View File

@@ -3,7 +3,8 @@
;--------------------------------------------------------------------------------
GetMagicBatItem:
JSL.l ItemSet_MagicBat
LDA MagicBatItem : CMP.b #$FF : BEQ .normalLogic
%GetPossiblyEncryptedItem(MagicBatItem, SpriteItemValues)
CMP.b #$FF : BEQ .normalLogic
TAY
STZ $02E9 ; 0 = Receiving item from an NPC or message
JSL.l Link_ReceiveItem

View File

@@ -3,7 +3,7 @@
;--------------------------------------------------------------------------------
HeartPieceGet:
PHX : PHY
JSL.l LoadHeartPieceRoomValue : TAY ; load item value into Y register
LDY $0DA0, X ; load item value into Y register
JSL.l MaybeMarkDigSpotCollected
.skipLoad
@@ -34,7 +34,7 @@ RTL
HeartContainerGet:
PHX : PHY
JSL.l AddInventory_incrementBossSwordLong
JSL.l LoadHeartContainerRoomValue : TAY ; load item value into Y register
LDY $0DA0, X ; load item value into Y register
BRA HeartPieceGet_skipLoad
;--------------------------------------------------------------------------------
@@ -49,7 +49,7 @@ DrawHeartPieceGFX:
BRL .done ; don't draw on the init frame
.skipInit
JSL.l LoadHeartPieceRoomValue
LDA $0DA0, X ; Retrieve stored item type
.skipLoad
@@ -81,7 +81,7 @@ DrawHeartContainerGFX:
BRA DrawHeartPieceGFX_done ; don't draw on the init frame
.skipInit
JSL.l LoadHeartContainerRoomValue
LDA $0DA0, X ; Retrieve stored item type
BRA DrawHeartPieceGFX_skipLoad
;--------------------------------------------------------------------------------
@@ -144,6 +144,7 @@ HeartPieceSpritePrep:
LDA #$00 : STA !REDRAW
JSL.l LoadHeartPieceRoomValue ; load item type
STA $0DA0, X ; Store item type
JSL.l PrepDynamicTile
.skip
@@ -156,6 +157,7 @@ HeartContainerSpritePrep:
LDA #$00 : STA !REDRAW
JSL.l LoadHeartContainerRoomValue ; load item type
STA $0DA0, X ; Store item type
JSL.l PrepDynamicTile
PLA
@@ -188,32 +190,51 @@ MaybeMarkDigSpotCollected:
PLP : PLA
RTL
;--------------------------------------------------------------------------------
macro GetPossiblyEncryptedItem(ItemLabel,TableLabel)
LDA IsEncrypted : BNE ?encrypted
LDA.l <ItemLabel>
BRA ?done
?encrypted:
PHX : PHP
REP #$30 ; set 16-bit accumulator & index registers
LDA $00 : PHA : LDA $02 : PHA
LDA.w #<TableLabel> : STA $00
LDA.w #<TableLabel>>>16 : STA $02
LDA.w #<ItemLabel>-<TableLabel>
JSL RetrieveValueFromEncryptedTable
PLX : STX $02 : PLX : STX $01
PLP : PLX
?done:
endmacro
LoadIndoorValue:
PHP
REP #$20 ; set 16-bit accumulator
LDA $A0 ; these are all decimal because i got them that way
CMP.w #225 : BNE +
LDA HeartPiece_Forest_Thieves
%GetPossiblyEncryptedItem(HeartPiece_Forest_Thieves, HeartPieceIndoorValues)
BRL .done
+ CMP.w #226 : BNE +
LDA HeartPiece_Lumberjack_Tree
%GetPossiblyEncryptedItem(HeartPiece_Lumberjack_Tree, HeartPieceIndoorValues)
BRL .done
+ CMP.w #234 : BNE +
LDA HeartPiece_Spectacle_Cave
%GetPossiblyEncryptedItem(HeartPiece_Spectacle_Cave, HeartPieceIndoorValues)
BRL .done
+ CMP.w #283 : BNE +
LDA $22 : XBA : AND.w #$0001 ; figure out where link is
BNE ++
LDA HeartPiece_Circle_Bushes
%GetPossiblyEncryptedItem(HeartPiece_Circle_Bushes, HeartPieceIndoorValues)
BRL .done
++
LDA HeartPiece_Graveyard_Warp
%GetPossiblyEncryptedItem(HeartPiece_Graveyard_Warp, HeartPieceIndoorValues)
BRL .done
+ CMP.w #294 : BNE +
LDA HeartPiece_Mire_Warp
%GetPossiblyEncryptedItem(HeartPiece_Mire_Warp, HeartPieceIndoorValues)
BRL .done
+ CMP.w #295 : BNE +
LDA HeartPiece_Smith_Pegs
%GetPossiblyEncryptedItem(HeartPiece_Smith_Pegs, HeartPieceIndoorValues)
BRL .done
+ CMP.w #135 : BNE +
LDA StandingKey_Hera
@@ -239,47 +260,47 @@ LoadOutdoorValue:
LDA $8A
CMP.w #$03 : BNE +
LDA $22 : CMP.w #1890 : !BLT ++
LDA HeartPiece_Spectacle
%GetPossiblyEncryptedItem(HeartPiece_Spectacle, HeartPieceOutdoorValues)
BRL .done
++
LDA EtherItem
%GetPossiblyEncryptedItem(EtherItem, SpriteItemValues)
BRL .done
+ CMP.w #$05 : BNE +
LDA HeartPiece_Mountain_Warp
%GetPossiblyEncryptedItem(HeartPiece_Mountain_Warp, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$28 : BNE +
LDA HeartPiece_Maze
%GetPossiblyEncryptedItem(HeartPiece_Maze, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$2A : BNE +
LDA HauntedGroveItem
%GetPossiblyEncryptedItem(HauntedGroveItem, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$30 : BNE +
LDA $22 : CMP.w #512 : !BGE ++
LDA HeartPiece_Desert
%GetPossiblyEncryptedItem(HeartPiece_Desert, HeartPieceOutdoorValues)
BRL .done
++
LDA BombosItem
%GetPossiblyEncryptedItem(BombosItem, SpriteItemValues)
BRL .done
+ CMP.w #$35 : BNE +
LDA HeartPiece_Lake
%GetPossiblyEncryptedItem(HeartPiece_Lake, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$3B : BNE +
LDA HeartPiece_Swamp
%GetPossiblyEncryptedItem(HeartPiece_Swamp, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$42 : BNE +
LDA HeartPiece_Cliffside
%GetPossiblyEncryptedItem(HeartPiece_Cliffside, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$4A : BNE +
LDA HeartPiece_Cliffside
%GetPossiblyEncryptedItem(HeartPiece_Cliffside, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$5B : BNE +
LDA HeartPiece_Pyramid
%GetPossiblyEncryptedItem(HeartPiece_Pyramid, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$68 : BNE +
LDA HeartPiece_Digging
%GetPossiblyEncryptedItem(HeartPiece_Digging, HeartPieceOutdoorValues)
BRL .done
+ CMP.w #$81 : BNE +
LDA HeartPiece_Zora
%GetPossiblyEncryptedItem(HeartPiece_Zora, HeartPieceOutdoorValues)
BRL .done
+
LDA.w #$0017 ; default to a normal hp
@@ -306,34 +327,34 @@ LoadBossValue:
REP #$20 ; set 16-bit accumulator
LDA $A0 ; these are all decimal because i got them that way
CMP.w #200 : BNE +
LDA HeartContainer_ArmosKnights
%GetPossiblyEncryptedItem(HeartContainer_ArmosKnights, HeartContainerBossValues)
BRL .done
+ CMP.w #51 : BNE +
LDA HeartContainer_Lanmolas
%GetPossiblyEncryptedItem(HeartContainer_Lanmolas, HeartContainerBossValues)
BRL .done
+ CMP.w #7 : BNE +
LDA HeartContainer_Moldorm
%GetPossiblyEncryptedItem(HeartContainer_Moldorm, HeartContainerBossValues)
BRL .done
+ CMP.w #90 : BNE +
LDA HeartContainer_HelmasaurKing
%GetPossiblyEncryptedItem(HeartContainer_HelmasaurKing, HeartContainerBossValues)
BRL .done
+ CMP.w #6 : BNE +
LDA HeartContainer_Arrghus
%GetPossiblyEncryptedItem(HeartContainer_Arrghus, HeartContainerBossValues)
BRL .done
+ CMP.w #41 : BNE +
LDA HeartContainer_Mothula
%GetPossiblyEncryptedItem(HeartContainer_Mothula, HeartContainerBossValues)
BRL .done
+ CMP.w #172 : BNE +
LDA HeartContainer_Blind
%GetPossiblyEncryptedItem(HeartContainer_Blind, HeartContainerBossValues)
BRL .done
+ CMP.w #222 : BNE +
LDA HeartContainer_Kholdstare
%GetPossiblyEncryptedItem(HeartContainer_Kholdstare, HeartContainerBossValues)
BRL .done
+ CMP.w #144 : BNE +
LDA HeartContainer_Vitreous
%GetPossiblyEncryptedItem(HeartContainer_Vitreous, HeartContainerBossValues)
BRL .done
+ CMP.w #164 : BNE +
LDA HeartContainer_Trinexx
%GetPossiblyEncryptedItem(HeartContainer_Trinexx, HeartContainerBossValues)
BRL .done
+
LDA.w #$003E ; default to a normal boss heart

View File

@@ -2221,3 +2221,18 @@ org $0DA9C8 ; <- 06A9C8 - player_oam.asm: 1663 (AND.w #$00FF : CMP.w #$00F8 : BC
LDA $02 ; always zero! (this replaces the BCC)
ADC.w #0000 ; put the carry bit into the accumulator instead of a hardcoded 1.
;================================================================================
;================================================================================
; Chest Encryption
;--------------------------------------------------------------------------------
org $01EBEB ; <- 0EBEB - bank01.asm : 13760 (INC $0E)
JML.l GetChestData : NOP
org $01EBDE ; <- 0EBDE - bank01.asm : 13740 (.couldntFindChest)
Dungeon_OpenKeyedObject_couldntFindChest:
org $01EBF0 ; <- 0EBF0 - bank01.asm : 13764 (.nextChest)
Dungeon_OpenKeyedObject_nextChest:
org $01EC14 ; <- 0EC14 - bank01.asm : 13783 (LDX $040C)
Dungeon_OpenKeyedObject_bigChest:
org $01EC38 ; <- 0EC38 - bank01.asm : 13809 (.smallChest)
Dungeon_OpenKeyedObject_smallChest:
;================================================================================

View File

@@ -931,7 +931,8 @@ RTL
;--------------------------------------------------------------------------------
LoadPowder:
JSL.l Sprite_SpawnDynamically ; thing we wrote over
LDA WitchItem
%GetPossiblyEncryptedItem(WitchItem, SpriteItemValues)
STA $0DA0, Y ; Store item type
JSL.l PrepDynamicTile
RTL
;--------------------------------------------------------------------------------
@@ -957,12 +958,12 @@ RTL
DrawPowder:
LDA $02DA : BNE .defer ; defer if link is buying a potion
LDA.l !REDRAW : BEQ +
LDA WitchItem
LDA $0DA0, X ; Retrieve stored item type
JSL.l PrepDynamicTile
LDA #$00 : STA.l !REDRAW ; reset redraw flag
BRA .defer
+
LDA WitchItem
LDA $0DA0, X ; Retrieve stored item type
JSL.l DrawDynamicTile
.defer
RTL
@@ -983,7 +984,8 @@ LoadMushroom:
LDA $5D : CMP #$14 : BEQ .skip ; skip if we're mid-mirror
LDA #$00 : STA !REDRAW
LDA MushroomItem
%GetPossiblyEncryptedItem(MushroomItem, SpriteItemValues)
STA $0DA0, X ; Store item type
JSL.l PrepDynamicTile
.skip
@@ -1003,7 +1005,7 @@ DrawMushroom:
BRA .done ; don't draw on the init frame
.skipInit
LDA MushroomItem
LDA $0DA0, X ; Retrieve stored item type
JSL.l DrawDynamicTile
.done
@@ -1015,7 +1017,7 @@ RTL
; CollectPowder:
;--------------------------------------------------------------------------------
CollectPowder:
LDA.l WitchItem : TAY ; load witch item
LDY $0DA0, X ; Retrieve stored item type
STZ $02E9 ; item from NPC
JSL.l Link_ReceiveItem
;JSL.l FullInventoryExternal

View File

@@ -155,19 +155,14 @@ RTL
ItemSet_Mushroom:
PHA
LDA !NPC_FLAGS_2 : ORA.b #$10 : STA !NPC_FLAGS_2
LDA.l MushroomItem : TAY
LDY $0DA0, X ; Retrieve stored item type
PLA
;LDY.b #$29
STZ $02E9 ; thing we wrote over - the mushroom is an npc for item purposes apparently
RTL
ItemSet_Powder:
PHA
LDA !NPC_FLAGS_2 : ORA.b #$20 : STA !NPC_FLAGS_2
LDA.l WitchItem : TAY
PLA
;LDY.b #$0D
STZ $02E9 ; thing we wrote over
PHA : LDA !NPC_FLAGS_2 : ORA.b #$20 : STA !NPC_FLAGS_2 : PLA
RTL
;================================================================================
@@ -181,10 +176,12 @@ Set300RupeeNPCItem:
REP #$20 ; set 16-bit accumulator
LDA $A0 ; these are all decimal because i got them that way
CMP.w #291 : BNE +
LDA RupeeNPC_MoldormCave : TAY ; load moldorm cave value into Y
%GetPossiblyEncryptedItem(RupeeNPC_MoldormCave, SpriteItemValues)
TAY ; load moldorm cave value into Y
BRA .done
+ CMP.w #286 : BNE +
LDA RupeeNPC_NortheastDarkSwampCave : TAY ; load northeast dark swamp cave value into Y
%GetPossiblyEncryptedItem(RupeeNPC_NortheastDarkSwampCave, SpriteItemValues)
TAY ; load northeast dark swamp cave value into Y
BRA .done
+
LDY.b #$46 ; default to a normal 300 rupees

View File

@@ -1,7 +1,7 @@
;================================================================================
; Item Tables
;--------------------------------------------------------------------------------
org $308000 ; bank #$30 ; PC 0x180000 - 0x180006
org $308000 ; bank #$30 ; PC 0x180000 - 0x180006 [encrypted]
HeartPieceIndoorValues:
HeartPiece_Forest_Thieves:
db #$17 ; #$17 = Heart Piece
@@ -18,9 +18,10 @@ HeartPiece_Mire_Warp:
HeartPiece_Smith_Pegs:
db #$17
;--------------------------------------------------------------------------------
; 0x180006 - 0x18000F (unused)
; 0x180006 - 0x18000F (unused) [encrypted]
;--------------------------------------------------------------------------------
org $308010 ; PC 0x180010 - 0x180017
org $308010 ; PC 0x180010 - 0x180017 [encrypted]
SpriteItemValues:
RupeeNPC_MoldormCave:
db #$46 ; #$46 = 300 Rupees
RupeeNPC_NortheastDarkSwampCave:
@@ -38,7 +39,7 @@ EtherItem:
BombosItem:
db #$0F ; #$0F = Bombos Medallion
;--------------------------------------------------------------------------------
; 0x180017 - 0x18001F (unused)
; 0x180017 - 0x18001F (unused) [encrypted]
;--------------------------------------------------------------------------------
org $308020 ; PC 0x180020
DiggingGameRNG:
@@ -350,7 +351,11 @@ org $308086 ; PC 0x180086
GanonAgahRNG:
db #$00 ; $00 = static rng, $01 = no extra blue balls/warps
;--------------------------------------------------------------------------------
; 0x180087 - 0x18008F (unused)
org $308087 ; PC 0x180087
IsEncrypted:
dw #$0000 ; $0000 = not encrypted, $0001 = encrypted with static key, $0002 = Encrypted w/ passcode entry screen (Not implemented yet)
;--------------------------------------------------------------------------------
; 0x180089 - 0x18008F (unused)
;--------------------------------------------------------------------------------
org $308090 ; PC 0x180090 - 0x180097
ProgressiveSwordLimit:
@@ -384,7 +389,13 @@ db #$01 ; #$00 = Original Behavior - #$01 = Randomizer Behavior (Default)
Bugfix_PodEG:
db #$01 ; #$00 = Original Behavior - #$01 = Randomizer Behavior (Default)
;--------------------------------------------------------------------------------
; 0x1800A5- 0x1800FF (unused)
; 0x1800A5 - 0x1800AF (unused)
;--------------------------------------------------------------------------------
org $3080B0 ; 0x1800B0-0x1800BF
StaticDecryptionKey:
dd $00000000, $00000000, $00000000, $00000000
;--------------------------------------------------------------------------------
; 0x1800C0 - 0x1800FF (unused)
;--------------------------------------------------------------------------------
org $308100 ; PC 0x180100 (0x40 bytes)
ShovelSpawnTable:
@@ -686,7 +697,7 @@ org $06C93B ; PC 0x3493B
PyramidPotion:
db #$2C ; #$2C = Green Potion
;--------------------------------------------------------------------------------
org $308140 ; PC 0x180140 - 0x18014A
org $308140 ; PC 0x180140 - 0x18014A [encrypted]
HeartPieceOutdoorValues:
HeartPiece_Spectacle:
db #$17
@@ -711,9 +722,9 @@ HeartPiece_Zora:
HauntedGroveItem:
db #$14 ; #$14 = Flute
;--------------------------------------------------------------------------------
; 0x18014B - 0x18014F (unused)
; 0x18014B - 0x18014F (unused) [encrypted]
;================================================================================
org $308150 ; PC 0x180150 - 0x180159
org $308150 ; PC 0x180150 - 0x180159 [encrypted]
HeartContainerBossValues:
HeartContainer_ArmosKnights:
db #$3E ; #$3E = Boss Heart (putting pendants here causes main pendants to not drop for obvious (in retrospect) reasons)
@@ -736,7 +747,7 @@ HeartContainer_Vitreous:
HeartContainer_Trinexx:
db #$3E
;--------------------------------------------------------------------------------
; 0x180159 - 0x18015F (unused)
; 0x180159 - 0x18015F (unused) [encrypted]
;================================================================================
org $308160 ; PC 0x180160 - 0x180162
BonkKey_Desert: