Pages: 1
Posted on 07-16-16, 08:54 pm (rev. 5 by  MeroMero on 08-02-16, 02:33 pm)
Death by cuteness

Karma: 6554
Posts: 473/598
Since: 05-01-13
Posted by MeroMero
I dare say you can (…) even (…) make the game select even a background, foreground, tileset, Soundset, Spriteset per View located in one given Area (but it'll have to be changed dynamically as the game reload the Area)!

And I dare say I was right in being stubborn and…

Oh, hi! It's me again! Another ASM Hack?
Yes, yes, another ASM Hack, but this time this was something that was captivating me for a while:
_Could you make the game load custom graphics for each View in a given Area?
And now I can say that the answer is YES!

Views have their own parameters for ASM-template:
@Force the game to reload the Area even when switching Views within the same Area @Beneficial side effect: prevents a graphical glitch for FG Effects upon View Change within the same Area repl_0215E4AC_ov_36: BX LR nsub_0211963C_ov_0A: B 0x2119664 @No matter the Area, do NOT nuke Event IDs until Mario exits the level! repl_0201DEA8: repl_0201DEAC: repl_0201DF00: repl_0201DF04: repl_0201DF34: BX LR @Set Entrance ID to go to repl_0201E99C: LDR R12, =0x20CA8FF LDRB R8, [R4, #0xC] @Get Destination Entrance STRB R8, [R12] @Set Placeholder Destination Entrance LDRH R8, [R4, #2] BX LR @Set Entrance ID from Warp repl_021564D0_ov_36: LDR R1, =0x20CA8FF LDRB R0, [R5, #0x410] STRB R0, [R1] LDRB R0, [R5, #0x410] BX LR @Set Entrance ID from Clogged Pipe repl_021732C0_ov_3B: LDR R1, =0x20CA8FF LDRB R0, [R5, #0x4B7] STRB R0, [R1] LDRB R0, [R5, #0x4B7] BX LR @Set Entrance ID from Event Door repl_0218CAF8_ov_76: LDR R1, =0x20CA8FF AND R4, R5, #0xFF STRB R4, [R1] MOV R1, R5, LSR #8 BX LR @Reload Tileset, Foreground, Background, Sounds Set and Actors Set repl_0201FB6C: LDR R0, =0x20CA8FF LDR R4, =0x208589C LDR R4, [R4] CMP R4, #0 @Check if level (not area) is loading BEQ .LevelAlreadyLoaded @If already loaded jump to next function MOV R4, #0 @Fetch Start Entrance LDR R6, =0x2085A30 LDRB R6, [R6] @Get Midway flag CMP R6, #0xFF MOVNE R4, #1 @If Midway flag is set, fetch Midway Entrance instead LDR R1, [R5] ADD R1, R5, R1 LDRB R6, [R1, R4] STRB R6, [R0] @Store Entrance ID .LevelAlreadyLoaded: LDRB R0, [R0] ADD R4, R5, #0x28 LDR R1, [R4] ADD R1, R5, R1 @Get beginning offset LDR R4, [R4, #4] ADD R4, R1, R4 @Get end offset MOV R7, #0 @Set default View Number at 0 .LoopViewNumber: LDRB R6, [R1, #8] @Get Entrance ID CMP R6, R0 @Compare Entrance ID with the placeholder Entrance ID LDREQB R7, [R1, #0x12] @If both IDs match get View Number BEQ .SuccessViewNumber ADD R1, R1, #0x14 @Go to next Entrance Data CMP R1, R4 @Compare current offset to end offset BCC .LoopViewNumber @Continue looping until end offset becomes the lesser one .SuccessViewNumber: MOV R0, #0 @Set counter for LoopLoadFromView CMP R7, #0 @Compare View Number to 0 BEQ .Return @If true then Return MOV R1, R5 LDR R6, [R5, #-0xC] @Get filesize ADD R6, R5, R6 @Get end of file offset .LoopLoadFromView: MOV R4, R1 LDR R1, [R4, #0x68] ADD R1, R5, R1 ADD R1, R1, #0x10 CMP R1, R6 BCS .Return @If greater or equal then Return, this will consider the default View Number ADD R0, R0, #1 CMP R0, R7 @Compare counter to View Number BCC .LoopLoadFromView @Exit the loop if greater or equal (most likely equal) MOV R4, R5 MOV R6, #0 .LoopWriteForView: LDR R0, [R1], #4 @Fetch offsets and sizes for each of the 14 blocks for selected View Number STR R0, [R4], #4 @Write them to the beginning of the file, where they are supposed to be read ADD R6, R6, #1 CMP R6, #0x1C @14 blocks, 8 bytes, maximum of 4 bytes per register BCC .LoopWriteForView @Hence why the loop is broken at 28 and not 14 .Return: LDR R4, =0x208B168 @Default instruction that was replaced to allow this mod BX LR @Reload Music if necessary repl_0201E790: ADD LR, LR, #0xC BIC R1, R1, #0x80 LDR R0, [SP] CMP R0, #0 BLT .GetView CMP R0, #4 BGE .GetView LDR R2, =0x2085A3C LDR R2, [R2] CMP R0, R2 BEQ .GetView CMP R1, #0x70 BXCC LR .GetView: STMFD SP!, {R3-R4} LDR R4, =0x20CA8FF LDRB R4, [R4] LDR R0, =0x2086A2C LDR R0, [R0] LDR R2, [R0, #0x28] ADD R2, R0, R2 LDR R3, [R0, #0x2C] ADD R3, R2, R3 .LoopGetView: LDRB R0, [R2, #0x8] CMP R0, R4 BEQ .OutLoopGetView ADD R2, R2, #0x14 CMP R2, R3 BCC .LoopGetView .OutLoopGetView: LDRB R0, [R2, #0x12] @Get View Number LDR R4, =0x2086A2C LDR R4, [R4] LDR R3, [R4, #0x38] ADD R3, R4, R3 LDR R4, [R4, #0x3C] ADD R4, R4, R3 .LoopGetView2: LDRB R2, [R3, #0x8] CMP R2, R0 BEQ .OutLoopGetView2 ADD R3, R3, #0x10 CMP R3, R4 BCC .LoopGetView2 .OutLoopGetView2: LDRB R1, [R3, #0xA] BIC R1, R1, #0x80 LDMFD SP!, {R3-R4} BX LR



Now onto the second part.
To take full advantage of this hack, you will need to mess with the files in the course folder (the ones with 14 blocks of data, not the bgdat ones)

First, I'll remind you of how those files are laid out:
_info data
_block 1
_block 2
_block 3
_…
_block 13
_block 14

The info data is where are stored the offsets and the sizes for all 14 blocks (8 bytes per block)
So for example if I wanted to know where to read block 5, I first need the info data for block 5.
To calculate it, I need this formula:
(B-1)*8
Where B is the Block Number, so:
(5-1)*8 = 4*8 = 32

To read the info data for block 5, I need to go to offset 32 (0x20), and I read this:
00 01 00 00 14 00 00 00

??

So the offset is 4 bytes in size, the same goes for the block size:
Offset: 00 01 00 00
Size: 14 00 00 00

??

Let's invert the reading:
Offset: 00 00 01 00
Size: 00 00 00 14

Much better, so this means that block 5 begins at offset 0x100 and is 20 (0x14) bytes long!



But what does this have to do with this ASM Hack?
This is where I spice up the difficulty!
Remember the original layout? This is what you'll need to do:
_Info Data for View 0
_Block 1
_Block 2
_…
_Block 14
_Info Data for View 1
_Block 1
_Blocks 3 to 5
_Block 14
_Info Data for View 2
_Block 1
_Blocks 3 to 5
_Block 14
etc.

Basically for each additional View, the layout is:
_Info Data for View non 0
_Block 1
_Block 3
_Block 4
_Block 5
_Block 14

But why only those 5 Blocks?
_Block 1 allows you to change the Tileset, FG and BG .ncg as well as the Sounds Set
_Block 3 allows you to change the BG .nsc and .ncl respectively
_Block 4 allows you to change the Tileset .ncl
_Block 5 allows you to change the FG .nsc and .ncl respectively
_Block 14 allows you to change the Actors Sets

As an example you can download this level: Level 2-3 Area 1.nml
If you go look at the file B03_1.bin in the course folder, what I said earlier will start to make more sense, especially how the Info Data for additional Blocks is set.


Q: What if I only have 1 Block Set for all Views?
A: No problem, the game will work as it normally would, no graphical glitch or anything.

Q: Can you run this ASM Hack alongside the Dedicated graphics per Area Hack?
A: Yes you can, but keep in mind that only Sound Sets and Actor Sets will truly have an effect since the Tileset, FG and BG will get superseded anyways by the Dedicated graphics code!

Q: Does this work on the real deal?
A: Of course it works on a NDS!
Posted on 07-16-16, 09:04 pm


Karma: 19752
Posts: 443/1100
Since: 04-02-13
Holy shizzle~
Posted on 07-16-16, 09:19 pm
(Words)

Karma: 730
Posts: 71/265
Since: 01-03-16
So what you're telling me is that you basically did what Nintendo was wanting to do but couldn't because reasons?

I love it.
_________________________
"I strikingly thought you would know how but it clearly seems you have no knowledge of hacking" - MiiU 2017
Posted on 07-17-16, 06:25 am
Not a hacker

Karma: 188
Posts: 133/153
Since: 04-05-16
MeroMero, you should REALLY work for nintendo (and being a miderator of the asm section:) )
_________________________
Discord server
Posted on 07-17-16, 10:28 am (rev. 1 by  MeroMero on 07-17-16, 10:34 am)
Death by cuteness

Karma: 6554
Posts: 474/598
Since: 05-01-13
So there was indeed a slight glitch that caused a non modified level 1-4 to not load…
And I found the culprit: it was because of the Info Data for Level 1-4 Area 3 Block 14 on a non-modified A04_3.bin.

Data was 50 01 00 00 00 00 00 00 when it should have been 50 01 00 00 10 00 00 00, especially when the 16 bytes at offset 0x150 are present…

Since Block 14 is supposed to always be 16 (0x10) bytes in size anyways, I changed this part of the code:
LDR R4, [R4, #0x6C] ADD R1, R4, R1

into this:
ADD R1, R1, #0x10

to prevent that kind of miscalculation to happen again.
Posted on 07-28-16, 05:36 pm (rev. 1 by  MeroMero on 07-28-16, 05:37 pm)
Death by cuteness

Karma: 6554
Posts: 492/598
Since: 05-01-13
Code updated to take into account music change on same Area!

Tested on a NDS.
Posted on 07-28-16, 05:54 pm
Panser


Karma: 577
Posts: 112/332
Since: 04-09-16
meromero but you can use a different tileset for each view through an ASM hack?
Posted on 07-28-16, 08:04 pm
Ninji


Karma: 379
Posts: 180/226
Since: 08-17-11
Can someone show off a video?
_________________________
Pro lurker

My Hack (whoops link is fixed now):
http://nsmbhd.net/thread/2953-super-luigi-world-ds/
Posted on 07-28-16, 10:19 pm
Death by cuteness

Karma: 6554
Posts: 494/598
Since: 05-01-13
Sure:

Posted on 07-29-16, 07:35 pm
Ninji


Karma: 379
Posts: 181/226
Since: 08-17-11
Awesome!
_________________________
Pro lurker

My Hack (whoops link is fixed now):
http://nsmbhd.net/thread/2953-super-luigi-world-ds/
Posted on 08-02-16, 11:40 am
Fire Brother
Eugene

Karma: 3646
Posts: 925/1120
Since: 11-29-11
Next thing should be sound sets per view instead of per area
Posted on 08-02-16, 11:49 am (rev. 1 by  MeroMero on 08-02-16, 11:52 am)
Death by cuteness

Karma: 6554
Posts: 510/598
Since: 05-01-13
Posted by MeroMero
@Reload Tileset, Foreground, Background, Sounds Set and Actors Set

@Reload Music if necessary


That was already taken care off since the thread creation though.

And on top of that this is literally showcased in the video, proven by the fact that Scuttlebugs, Snow Spikes and Squigglers all need different Sound Sets to be heard properly.
Posted on 08-02-16, 12:03 pm
Fire Brother
Eugene

Karma: 3646
Posts: 926/1120
Since: 11-29-11
Ah okay.

Actor sets = Sprite sets, right?
Posted on 08-02-16, 12:06 pm
Death by cuteness

Karma: 6554
Posts: 511/598
Since: 05-01-13
It is, I choose to call those settings Actor Sets because this is more representative of what they truly are.
Posted on 08-02-16, 12:12 pm
Fire Brother
Eugene

Karma: 3646
Posts: 927/1120
Since: 11-29-11
Ah, that makes sense.
Pages: 1