[4.1.5] and [4.5.9] Restore RELICS to NESmaker Projects

TurtleRescueNES

Active member
Relics are a feature of Mystic Searches but not utilized in the base NESmaker engines. Relics are still visible in the NESmaker tool, and their data can still be passed through to games via NPC text delivery.

In NESmaker, open any text and select "NPC Gives Item" and then select "RELIC-Relic 0". This results in the following data saved to the game--

Text1: ;;;;; Entry 1
.db _T, _E, _S, _T, _SPACE, _0, _0, _7, _BREAK
.db _R, _E, _L, _I, _C, _SPACE, _0, _ENDITEM, #$08

#$08 at the end of the text string represents the eighth item on the item giving list. Items 0 through 7 represent weapons. Currently, the game stops comprehending anything indexed 8th or higher, but this can be restored with the following steps.

This example does NOT restore Items and Songs, but if you understand what is happening here, it will be a cinch to restore them as well.
This fix is fully compatible with the Project Info screen that allows you to pre-load weapons and relics at game start (see step 7 below).
I have confirmed this code with 4.1.5, but have not been able to properly test in 4.5.9. If any code adjustments need to be made, just let me know! :)

BEGIN:

1) Create these Overflow RAM variables--
relicsUnlocked1 -- 1 byte
relicsUnlocked2 -- 1 byte

2a) 4.1.5: Open ZeroOutAssets and locate ValToBitTable_inverse table
2b) 4.5.9: Open Toggle Tables and locate ValToBitTable_inverse table

3) Copy and paste the data row two times so that it looks like this--
ValToBitTable_inverse:
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
This is so the indexing can properly assign item given values 8 through 23

4a) 4.1.5: Open Handle Text Box and locate notEndTrigger:
5a) 4.1.5: Replace that section with the following code--

CMP #_ENDITEM ;; Begin TurtleRescue Relic Code
BNE notEndItem
;;; gives player an item.
INC textboxOffsetHold
LDY textboxOffsetHold
LDA (temp16),y
CMP #8
BMI +giveWeapon
CMP #16
BMI +giveRelic1
CMP #24
BMI +giveRelic2
JMP EndText

+giveWeapon:
TAY
LDA ValToBitTable_inverse,y
ORA weaponsUnlocked
STA weaponsUnlocked
JMP +convergeTextItem

+giveRelic1:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked1
STA relicsUnlocked1
JMP +convergeTextItem

+giveRelic2:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked2
STA relicsUnlocked2
JMP +convergeTextItem

+convergeTextItem:
TriggerScreen screenType
JMP EndText ;; End TurtleRescue Relic Code
notEndItem:

-------------
4b) 4.5.9: Open doDrawText and locate notMoreText:
5b) 4.5.9: Replace that section with the following code--

CMP #_ENDITEM ;; Begin TurtleRescue Relic Code
BNE notEndItem
;;; gives player an item.
LDA textPointer
CLC
ADC #$01
STA textPointer
LDA textPointer+1
ADC #$00
STA textPointer+1
LDY #$00
LDA (textPointer),y
CMP #8
BMI +giveWeapon
CMP #16
BMI +giveRelic1
CMP #24
BMI +giveRelic2
JMP doneWithText

+giveWeapon:
TAY
LDA ValToBitTable_inverse,y
ORA weaponsUnlocked
STA weaponsUnlocked
JMP +convergeTextItem

+giveRelic1:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked1
STA relicsUnlocked1
JMP +convergeTextItem

+giveRelic2:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked2
STA relicsUnlocked2
JMP +convergeTextItem

+convergeTextItem:
TriggerScreen currentNametable
JMP doneWithText ;; End TurtleRescue Relic Code
notEndItem:

--------------------

6) Relics data is now stored as bits within relicsUnlocked1 and relicsUnlocked2, much like weaponsUnlocked.

7) To initialize the Relics data that may be passed through via Project Info, you need to insert the below code into InitLoads.asp or somewhere similar that runs early in the game.
LDA #RELIC_GROUP1
STA relicsUnlocked1
LDA #RELIC_GROUP2
STA relicsUnlocked2

8) How you use these relics is up to you. You can call them anywhere like this--
LDA relicsUnlocked1
AND #%00000001
BNE +canUseRelic0
JMP +continue
This checks for Relic 0 in the first relic group. Relic 1 would be AND #%00000010. Relic 2 would be AND #%00000100 and so on.
If the relic is obtained, branch to run your custom code.
 
Last edited:

IMBrendan

Member
I've been babbling in the Discord about unlocking songs and such as I realized that you could swap SONGS_LEARED with BOSSES_DEFEATED and have the same effect on gameplay with different tix marks.
I will 100% be testing this in 4.5.9 later on today as you way looks simpler than the approach direction I was coming from.
 

TurtleRescueNES

Active member
I've been babbling in the Discord about unlocking songs and such as I realized that you could swap SONGS_LEARED with BOSSES_DEFEATED and have the same effect on gameplay with different tix marks.
I will 100% be testing this in 4.5.9 later on today as you way looks simpler than the approach direction I was coming from.
Thanks for this! It made me realize that I missed part of the process above. You can copy this code into InitLoads.asm or anywhere else where your game initializes.

LDA #RELIC_GROUP1
STA relicsUnlocked1
LDA #RELIC_GROUP2
STA relicsUnlocked2
 

IMBrendan

Member
So the only thing that is missing from the code above in 4.5.9 is that you need to add a user variable labeled "weaponChoice"
 

TurtleRescueNES

Active member
While the variable weaponChoice which Joe introduced in the 4.5.x codebase is related to what is going on here, there are no dependencies in either direction. For example, my 4.1.5 project does not use it, but I can use relics.
 

Kanbei85

Member
Relics are a feature of Mystic Searches but not utilized in the base NESmaker engines. Relics are still visible in the NESmaker tool, and their data can still be passed through to games via NPC text delivery.

In NESmaker, open any text and select "NPC Gives Item" and then select "RELIC-Relic 0". This results in the following data saved to the game--

Text1: ;;;;; Entry 1
.db _T, _E, _S, _T, _SPACE, _0, _0, _7, _BREAK
.db _R, _E, _L, _I, _C, _SPACE, _0, _ENDITEM, #$08

#$08 at the end of the text string represents the eighth item on the item giving list. Items 0 through 7 represent weapons. Currently, the game stops comprehending anything indexed 8th or higher, but this can be restored with the following steps.

This example does NOT restore Items and Songs, but if you understand what is happening here, it will be a cinch to restore them as well.
This fix is fully compatible with the Project Info screen that allows you to pre-load weapons and relics at game start (see step 7 below).
I have confirmed this code with 4.1.5, but have not been able to properly test in 4.5.9. If any code adjustments need to be made, just let me know! :)

BEGIN:

1) Create these Overflow RAM variables--
relicsUnlocked1 -- 1 byte
relicsUnlocked2 -- 1 byte

2a) 4.1.5: Open ZeroOutAssets and locate ValToBitTable_inverse table
2b) 4.5.9: Open Toggle Tables and locate ValToBitTable_inverse table

3) Copy and paste the data row two times so that it looks like this--
ValToBitTable_inverse:
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
.db #%00000001, #%00000010, #%000000100, #%00001000, #%00010000, #%00100000, #%01000000, #%10000000
This is so the indexing can properly assign item given values 8 through 23

4a) 4.1.5: Open Handle Text Box and locate notEndTrigger:
5a) 4.1.5: Replace that section with the following code--

CMP #_ENDITEM ;; Begin TurtleRescue Relic Code
BNE notEndItem
;;; gives player an item.
INC textboxOffsetHold
LDY textboxOffsetHold
LDA (temp16),y
CMP #8
BMI +giveWeapon
CMP #16
BMI +giveRelic1
CMP #24
BMI +giveRelic2
JMP EndText

+giveWeapon:
TAY
LDA ValToBitTable_inverse,y
ORA weaponsUnlocked
STA weaponsUnlocked
JMP +convergeTextItem

+giveRelic1:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked1
STA relicsUnlocked1
JMP +convergeTextItem

+giveRelic2:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked2
STA relicsUnlocked2
JMP +convergeTextItem

+convergeTextItem:
TriggerScreen screenType
JMP EndText ;; End TurtleRescue Relic Code
notEndItem:

-------------
4b) 4.5.9: Open doDrawText and locate notMoreText:
5b) 4.5.9: Replace that section with the following code--

CMP #_ENDITEM ;; Begin TurtleRescue Relic Code
BNE notEndItem
;;; gives player an item.
LDA textPointer
CLC
ADC #$01
STA textPointer
LDA textPointer+1
ADC #$00
STA textPointer+1
LDY #$00
LDA (textPointer),y
CMP #8
BMI +giveWeapon
CMP #16
BMI +giveRelic1
CMP #24
BMI +giveRelic2
JMP doneWithText

+giveWeapon:
TAY
LDA ValToBitTable_inverse,y
ORA weaponsUnlocked
STA weaponsUnlocked
JMP +convergeTextItem

+giveRelic1:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked1
STA relicsUnlocked1
JMP +convergeTextItem

+giveRelic2:
TAY
LDA ValToBitTable_inverse,y
ORA relicsUnlocked2
STA relicsUnlocked2
JMP +convergeTextItem

+convergeTextItem:
TriggerScreen currentNametable
JMP doneWithText ;; End TurtleRescue Relic Code
notEndItem:

--------------------

6) Relics data is now stored as bits within relicsUnlocked1 and relicsUnlocked2, much like weaponsUnlocked.

7) To initialize the Relics data that may be passed through via Project Info, you need to insert the below code into InitLoads.asp or somewhere similar that runs early in the game.
LDA #RELIC_GROUP1
STA relicsUnlocked1
LDA #RELIC_GROUP2
STA relicsUnlocked2

8) How you use these relics is up to you. You can call them anywhere like this--
LDA relicsUnlocked1
AND #%00000001
BNE +canUseRelic0
JMP +continue
This checks for Relic 0 in the first relic group. Relic 1 would be AND #%00000010. Relic 2 would be AND #%00000100 and so on.
If the relic is obtained, branch to run your custom code.

Do you intend to be using CMP #8 above instead of CMP #$08?
 
Has anyone been able to restore relics in 4.5?
I am getting a Value of of range error on my Vectors.asm.
 

Attachments

  • Capture.JPG
    Capture.JPG
    29.6 KB · Views: 7
Last edited:
That error means that you have maxed out your game code. You need to look at your scripts and do some pruning.
Thanks Turtle! I did the bank 16 transfer from JamesNES and am no longer getting the error.

I had to change the last line: "JMP doneWithText ;; End TurtleRescue Relic Code"
to say: "JMP endOfText ;; End TurtleRescue Relic Code" because it was skipping the block that closes the text window.
Other than that is seems to be working perfectly. Thanks again!!
 
Last edited:
Top Bottom