The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking
Reload this Page Help Thread ASM & Disassembly

Notices
For all updates, view the main page.

Binary ROM Hacking Need a helping hand or just want to talk about binary ROM hacks? Get comments and answers to any ROM Hacking-related problems, questions or thoughts you have here.

Ad Content
Closed Thread
 
Thread Tools
  #101   Link to this post, but load the entire thread.  
Old February 6th, 2015 (11:09 PM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 23
Gender: Male
Posts: 409
You forgot the +1. And again, this is not how everyone advices you to do it.
__________________
  #102   Link to this post, but load the entire thread.  
Old February 7th, 2015 (1:27 AM).
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Quote:
Originally Posted by Deokishisu View Post
Wait, you're trying to test Psystrike's battle effect in the OW with a signpost script? Really?

This should be put in a battlescript which is then attached to an attack. Then used in a battle. Wow.
I know, it is to test the swap. It will work in a script and in a battle script, no ?


So it is "callasm 0xOffset +1", thank you.
  #103   Link to this post, but load the entire thread.  
Old February 7th, 2015 (9:25 AM).
GoGoJJTech's Avatar
GoGoJJTech GoGoJJTech is offline
(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
 
Join Date: Nov 2012
Location: Earth
Age: 24
Gender: Female
Nature: Jolly
Posts: 2,475
Quote:
Originally Posted by Edwearth View Post
I know, it is to test the swap. It will work in a script and in a battle script, no ?


So it is "callasm 0xOffset +1", thank you.
You don't seem to understand..
It's a code for a move. There is no battle scene on the overworld. You can't just "callasm 0xmovescript" and make psystrike happen on the overworld. It doesn't make sense lol
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
The HGSS Music Patch - The BW/2 Music Patch - ASM: Switch Music Based on Seasons
Romhack.me Profile - Pokecommunity Profile - Youtube Channel

Support me at my site!
Pokémon Platinum Red and Blue
  #104   Link to this post, but load the entire thread.  
Old February 7th, 2015 (10:39 AM).
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Quote:
Originally Posted by GoGoJJTech View Post
You don't seem to understand..
It's a code for a move. There is no battle scene on the overworld. You can't just "callasm 0xmovescript" and make psystrike happen on the overworld. It doesn't make sense lol
This routine is not the move's script. It just swaps two "double bytes". I can swap two bytes when I want, in battle or not.
It will be call in the psystrike's battlescript.

But I have another question ! How to port the Jambo's callasm command ? I compile the routine with the address 0x02024214 for the scriptlocation (because I am on Emerald). Ok, but I have to repoint and extend the battle script command table to had the new command F9 XX XX XX 08. Where is this table ? And how do you find it ?
  #105   Link to this post, but load the entire thread.  
Old February 7th, 2015 (11:34 AM).
Spherical Ice's Avatar
Spherical Ice Spherical Ice is offline
 
Join Date: Nov 2007
Location: Leicester, UK
Age: 25
Posts: 5,251
I've moved this entire discussion to the ASM & Disassembly Help Thread because it is in no way an ASM Resource. :D
__________________
  #106   Link to this post, but load the entire thread.  
Old February 7th, 2015 (1:26 PM).
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Quote:
Originally Posted by Spherical Ice View Post
I've moved this entire discussion to the ASM & Disassembly Help Thread because it is in no way an ASM Resource. :D
Ok sorry i did see it :)
Actually, I don't understand how to insert a script in a battlescript.
  #107   Link to this post, but load the entire thread.  
Old February 7th, 2015 (1:57 PM).
C me's Avatar
C me C me is offline
Creator of Pokemon League Of Legends
 
Join Date: Jan 2014
Age: 26
Gender: Male
Posts: 681
Quote:
Originally Posted by Edwearth View Post
Actually, I don't understand how to insert a script in a battlescript.
Do you have battle script pro?
You can use that to compile battle scripts.
  #108   Link to this post, but load the entire thread.  
Old February 7th, 2015 (2:49 PM). Edited February 9th, 2015 by Edwearth.
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Quote:
Originally Posted by pokenoobend View Post
Do you have battle script pro?
You can use that to compile battle scripts.
Yes of course, i know how to create a battlescript.
I want to insert an ASM routine in my battlescript using Jambo's callasm command. I'm on Emerald so i have to use the address 0x02024214 as scriptlocation. But I also have to repoint and extend the battle script command table. I don't find it.

Edit : I found it! The table is at 0x31BD10 and its length is 0x3E4.
  #109   Link to this post, but load the entire thread.  
Old February 11th, 2015 (8:12 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
I would like to know, if it's possible, the offset of two routines :

- First, the one which creates an OW on the map when we come on this map ;
- And also, the one which check if there is an OW next to the player before walking.

Can someone help me ? Thanks ^^
Hi, unfortunately I don't know where the overworld is created. Though I do know that there's a collision check which occurs when the player tries to use surf or waterfall.

This sub routine is at 0x805C8B0. More specifically, the check to see if an NPC is blocking the way is done at 0x80636AC, it's used for stuff like ledge hopping and stuff too.
__________________
...
  #110   Link to this post, but load the entire thread.  
Old February 16th, 2015 (2:43 AM).
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Hello,

I don't understand why this doesn't work :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func
.global swap

main:
	push {r0-r3, lr}
	
	ldr r0, .CDEFA1
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFA1
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
	
	ldr r0, .CDEFA2
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFA2
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
		
	ldr r0, .CDEFE1
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFE1
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
		
	ldr r0, .CDEFE2
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFE2
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
	
	pop {r0-r3, pc}
	
.align 2
.CDEFA1:
	.word 0x0202409E
.CSPEDEFA1:
	.word 0x020240A1
.CDEFA2:
	.word 0x202414E
.CSPEDEFA2:
	.word 0x02024151
.CDEFE1:
	.word 0x020240F6
.CSPEDEFE1:
	.word 0x020240F9
.CDEFE2:
	.word 0x020241A6
.CSPEDEFE2:
	.word 0x020241A9


Whereas this works :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func
.global swap

main:
	push {r0-r3, lr}

	ldr r0, .DEFA1
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFA1
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFA2
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFA2
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFE1
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFE1
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFE2
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFE2
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	pop {r0-r3, pc}
	
.align 2
.DEFA1:
	.word 0x02024548
.SPEDEFA1:
	.word 0x0202454E
.DEFA2:
	.word 0x020245AC
.SPEDEFA2:
	.word 0x020245B2
.DEFE1:
	.word 0x020247A0
.SPEDEFE1:
	.word 0x020247A6
.DEFE2:
	.word 0x02024804
.SPEDEFE2:
	.word 0x0202480A


With the first routine I want to switch some bytes and with the second i switch some "double bytes".
  #111   Link to this post, but load the entire thread.  
Old February 16th, 2015 (6:44 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Edwearth View Post
Hello,

I don't understand why this doesn't work :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func
.global swap

main:
	push {r0-r3, lr}
	
	ldr r0, .CDEFA1
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFA1
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
	
	ldr r0, .CDEFA2
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFA2
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
		
	ldr r0, .CDEFE1
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFE1
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
		
	ldr r0, .CDEFE2
	ldrb r1, [r0]
	
	ldr r2, .CSPEDEFE2
	ldrb r3, [r2]
	
	strb r1, [r2]
	strb r3, [r0]
	
	pop {r0-r3, pc}
	
.align 2
.CDEFA1:
	.word 0x0202409E
.CSPEDEFA1:
	.word 0x020240A1
.CDEFA2:
	.word 0x202414E
.CSPEDEFA2:
	.word 0x02024151
.CDEFE1:
	.word 0x020240F6
.CSPEDEFE1:
	.word 0x020240F9
.CDEFE2:
	.word 0x020241A6
.CSPEDEFE2:
	.word 0x020241A9


Whereas this works :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func
.global swap

main:
	push {r0-r3, lr}

	ldr r0, .DEFA1
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFA1
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFA2
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFA2
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFE1
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFE1
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	ldr r0, .DEFE2
	ldrh r1, [r0]
	
	ldr r2, .SPEDEFE2
	ldrh r3, [r2]
	
	strh r1, [r2]
	strh r3, [r0]
	
	pop {r0-r3, pc}
	
.align 2
.DEFA1:
	.word 0x02024548
.SPEDEFA1:
	.word 0x0202454E
.DEFA2:
	.word 0x020245AC
.SPEDEFA2:
	.word 0x020245B2
.DEFE1:
	.word 0x020247A0
.SPEDEFE1:
	.word 0x020247A6
.DEFE2:
	.word 0x02024804
.SPEDEFE2:
	.word 0x0202480A


With the first routine I want to switch some bytes and with the second i switch some "double bytes".
Hi, it looks like it would do the same. I don't know which base you're using, but the offsets of the symbols from routine #1 don't match the offsets of the symbols in routine #2. Other than that, swapping a byte instead of a half word shouldn't be a problem (actually the halfword one has more limitations than the byte swapping, but that's besides the point).
__________________
...
  #112   Link to this post, but load the entire thread.  
Old February 16th, 2015 (7:58 AM). Edited February 16th, 2015 by Edwearth.
Edwearth's Avatar
Edwearth Edwearth is offline
 
Join Date: May 2014
Location: Paris
Gender: Male
Posts: 40
Quote:
Originally Posted by FBI agent View Post
Hi, it looks like it would do the same. I don't know which base you're using, but the offsets of the symbols from routine #1 don't match the offsets of the symbols in routine #2. Other than that, swapping a byte instead of a half word shouldn't be a problem (actually the halfword one has more limitations than the byte swapping, but that's besides the point).
The first one is to swap stat changes, and the second one is to swap stats. So it is normal that the offsets are not the same. Yes it shouldn't be a problem, that's why i don't understand why the game resets with the first routine.

Edit: Well, i'm stupid, I forgot a "0":
.CDEFA2:
.word 0x202414E

.CDEFA2:
.word 0x0202414E
  #113   Link to this post, but load the entire thread.  
Old February 18th, 2015 (8:33 AM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
Quote:
Originally Posted by FBI agent View Post
Hi, unfortunately I don't know where the overworld is created. Though I do know that there's a collision check which occurs when the player tries to use surf or waterfall.

This sub routine is at 0x805C8B0. More specifically, the check to see if an NPC is blocking the way is done at 0x80636AC, it's used for stuff like ledge hopping and stuff too.
Thanks a lot ;)

I found something : the result given by the routine at 0x80636AC is stored in r0.

Code:
Value of r0	|	Obstacle
0 		|	Nothing
2 		|	Solid block (buildings, trees...)
3 		|	Walking : water / Surfing : ground
4 		|	NPC
  #114   Link to this post, but load the entire thread.  
Old February 18th, 2015 (10:09 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
Thanks a lot ;)

I found something : the result given by the routine at 0x80636AC is stored in r0.

Code:
Value of r0	|	Obstacle
0 		|	Nothing
2 		|	Solid block (buildings, trees...)
3 		|	Walking : water / Surfing : ground
4 		|	NPC
Awesome. Did you figure out if it takes a player's X-Y? If it does perhaps it can be used to check if something is present on another part of the map the player isn't in currently.
__________________
...
  #115   Link to this post, but load the entire thread.  
Old February 18th, 2015 (11:48 AM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
I haven't studied the routine more, I used this data to make a Follow Me (https://vid.me/ynwf / https://vid.me/hSBA).

However, I noticed that before the execution of this routine, r1, r5 and r7 correspond to the player's X + 7. In the same way, r2, r4 and r9 correspond to the player's Y + 7.
  #116   Link to this post, but load the entire thread.  
Old February 18th, 2015 (2:03 PM). Edited February 18th, 2015 by Mana.
Mana's Avatar
Mana Mana is offline
 
Join Date: Jan 2009
Location: UK
Age: 31
Gender: Male
Posts: 10,075
NOOB HERE! o/

If this (from Shiny Quagsire's tutorial) saves a byte to a variable...

Spoiler:
.align 2
.thumb

main:
push {r0-r1,lr}
ldr r0, pokemon_data
ldrb r0, [r0]
lsl r0, #0x5
lsr r0, #0x5
ldr r1, var
strh r0, [r1]
pop {r0-r1,pc}

.align 2

pokemon_data:
.word 0x02024284 + 0x50
var:
.word 0x020270B6 + (0x800D * 2)


Then would switching "ldr r0, pokemon_data" to "ldr r0, var" (ldr r1, var too) then store whatever the value of 0x800D in the data? Or is life not that simple : <.
__________________
  #117   Link to this post, but load the entire thread.  
Old February 18th, 2015 (2:36 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Magic View Post
NOOB HERE! o/

If this (from Shiny Quagsire's tutorial) saves a byte to a variable...

Spoiler:
.align 2
.thumb

main:
push {r0-r1,lr}
ldr r0, pokemon_data
ldrb r0, [r0]
lsl r0, #0x5
lsr r0, #0x5
ldr r1, var
strh r0, [r1]
pop {r0-r1,pc}

.align 2

pokemon_data:
.word 0x02024284 + 0x50
var:
.word 0x020270B6 + (0x800D * 2)


Then would switching "ldr r0, pokemon_data" to "ldr r0, var" (ldr r1, var too) then store whatever the value of 0x800D in the data? Or is life not that simple : <.
You'll notice that he saves the value in r0 into the address in r1 (the variable).
So all you need to do is this:

Code:
push {r0-r1, lr}
mov r0, #0xValue
ldr r1, .var
strh r0, [r1]
pop {r0-r1, pc}
__________________
...
  #118   Link to this post, but load the entire thread.  
Old February 19th, 2015 (4:26 AM). Edited February 19th, 2015 by Mana.
Mana's Avatar
Mana Mana is offline
 
Join Date: Jan 2009
Location: UK
Age: 31
Gender: Male
Posts: 10,075
Quote:
Originally Posted by FBI agent View Post
You'll notice that he saves the value in r0 into the address in r1 (the variable).
So all you need to do is this:
Code:
push {r0-r1, lr}
mov r0, #0xValue @changes r0 to 0xValue?
ldr r1, .var @loads variable value to r1
strh r0, [r1] @stores r0's value to the var
pop {r0-r1, pc}
All this lingo still confuses me XD.

Sorry I'm not sure what you mean :<. Your code doesn't have any locations other than the var, so how can it set a byte to the value of the var? It might have just been I wasn't clear in my last post >< haha.

Also in regards to your tutorial (and our VMs) how do you know when you need to 'hook' and things?


Latest attempt of a routine. Think I must have oversimplified something? I get nothing ><. It runs but obviously not doing what I'd like it to XD. Vague comments about what I think ought to be happenin on the side :').

Spoiler:
Code:
.align 2
.thumb

main:
		push {r0-r1,lr}
		ldrb r0, move_data   ----> 8250cb8 is cut's data. Just because. +0x1 as it's the second byte that decides the power?
		ldrb r0, [r0]	
		add r0, #0x5  ----> Addings 0x5 to previous power
		ldr r1, var ----> Load 0x800D
		strh r0, [r1] ----> Put new power in 0x800D (to see if anything has happened).
		pop {r0-r1,pc}

.align 2

move_data:
		.word 0x08250CB8 + 0x1
var:
		.word 0x020270B6 + (0x800D * 2)


It now tells me 55 - which is correct! :o 50+5 power. How can I then extend this routine to replace the 50 (0x32) in the ROM with 55 (0x37)?

IM SO SORRY FOR ALL THE NOTIFICATIONS ;-; /thousanth edit
  #119   Link to this post, but load the entire thread.  
Old February 19th, 2015 (5:58 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Magic View Post
Code:
push {r0-r1, lr}
mov r0, #0xValue @changes r0 to 0xValue?
ldr r1, .var @loads variable value to r1
strh r0, [r1] @stores r0's value to the var
pop {r0-r1, pc}
All this lingo still confuses me XD.

Sorry I'm not sure what you mean :<. Your code doesn't have any locations other than the var, so how can it set a byte to the value of the var? It might have just been I wasn't clear in my last post >< haha.

Also in regards to your tutorial (and our VMs) how do you know when you need to 'hook' and things?


Latest attempt of a routine. Think I must have oversimplified something? I get nothing ><. It runs but obviously not doing what I'd like it to XD. Vague comments about what I think ought to be happenin on the side :').

Spoiler:
Code:
.align 2
.thumb

main:
		push {r0-r1,lr}
		ldrb r0, move_data   ----> 8250cb8 is cut's data. Just because. +0x1 as it's the second byte that decides the power?
		ldrb r0, [r0]	
		add r0, #0x5  ----> Addings 0x5 to previous power
		ldr r1, var ----> Load 0x800D
		strh r0, [r1] ----> Put new power in 0x800D (to see if anything has happened).
		pop {r0-r1,pc}

.align 2

move_data:
		.word 0x08250CB8 + 0x1
var:
		.word 0x020270B6 + (0x800D * 2)


It now tells me 55 - which is correct! :o 50+5 power. How can I then extend this routine to replace the 50 (0x32) in the ROM with 55 (0x37)?

IM SO SORRY FOR ALL THE NOTIFICATIONS ;-; /thousanth edit
OK, so when you do "ldr r0, move_data" you don't load it as a byte. move_data is a symbol which represents a pointer (in this case 0x8250CB8 + 1). We want a byte at that pointer so we do:
ldr r0, move_data @load the actual pointer
ldrb r0, [r0] @load a byte from the value of the pointer

If you did ldrb r0, move_data, it would just take move_data as a hex value and load the first byte of it, rather than the first byte of the value it's pointing to (power).

The rest of this is right. Also you seem to be confusing yourself with the names on the bottom. They're just definitions. It's the same thing to do ldr r0, move_data as it is to do ldr r0, =(0x8250CB8 +1).

Addressing your questions about what I've said last time, 0xValue is just a name I came up with. It's supposed to be some arbitrary, valid, constant. Replace it with 0xA or 0x50 or whatever your favorite hex value is.

mov r0, #0x50 @Sets r0 to be 0x50
ldr r1, =(0x20370D0) @loads address of Lastresult into r1. I.e pointer to the value in 0x800D (last result)
strh r0, [r1] @stores 2 bytes of whatever is in r0 into the address/location specified by r1. In this case stores 0x50 in the last result

I hope you see what we're doing with the pointers/symbols/storing now. With that out of the way I can address hooking.
I'm going to explain assuming you already know what a hook is. You basically know that a hook is required when you're reworking or adding additional features to existing game code. In this case you're changing the damage of a move's power based on badges. Thus you're added a feature to existing game code. If you were to just paste your code over the existing code at that region, then obviously you would be overwriting some other important code. This is why we place a hook.

Sometimes it's possible that the game code lends itself to be easily reworked and thus you just overwrite some existing bytes to do that (an example would be my "catch trainer's pokemon" thing). In these cases you don't need hooks (though it's kind of rare in comparison).
I should warn you, to hook successfully into some routines are harder than others. You need to analyze the code at said routine and note to yourself which registers are free, which registers contain information you need after you hook and of course which register you will use for the hook. In complex functions you often don't have a lot of resources, so you need to draw conclusions based on what the analyzed code is like.

Worst case scenario is usually that there's no registers you can use for the hook at the place you want to hook from. If that's the case you just hook early enough to a point where there are registers available and just derive their values and do your code from where you wanted to hook. OK, that last part doesn't make sense unless you've experienced what I'm talking about :P
This last paragraph isn't that important anyways, just me rambling, lol.
__________________
...
  #120   Link to this post, but load the entire thread.  
Old February 19th, 2015 (6:14 AM).
Mana's Avatar
Mana Mana is offline
 
Join Date: Jan 2009
Location: UK
Age: 31
Gender: Male
Posts: 10,075
Quote:
Originally Posted by FBI agent View Post
OK, so when you do "ldr r0, move_data" you don't load it as a byte. move_data is a symbol which represents a pointer (in this case 0x8250CB8 + 1). We want a byte at that pointer so we do:
ldr r0, move_data @load the actual pointer
ldrb r0, [r0] @load a byte from the value of the pointer

If you did ldrb r0, move_data, it would just take move_data as a hex value and load the first byte of it, rather than the first byte of the value it's pointing to (power).

The rest of this is right. Also you seem to be confusing yourself with the names on the bottom. They're just definitions. It's the same thing to do ldr r0, move_data as it is to do ldr r0, =(0x8250CB8 +1).

Addressing your questions about what I've said last time, 0xValue is just a name I came up with. It's supposed to be some arbitrary, valid, constant. Replace it with 0xA or 0x50 or whatever your favorite hex value is.

mov r0, #0x50 @Sets r0 to be 0x50
ldr r1, =(0x20370D0) @loads address of Lastresult into r1. I.e pointer to the value in 0x800D (last result)
strh r0, [r1] @stores 2 bytes of whatever is in r0 into the address/location specified by r1. In this case stores 0x50 in the last result

I hope you see what we're doing with the pointers/symbols/storing now. With that out of the way I can address hooking.
Spoiler:
I'm going to explain assuming you already know what a hook is. You basically know that a hook is required when you're reworking or adding additional features to existing game code. In this case you're changing the damage of a move's power based on badges. Thus you're added a feature to existing game code. If you were to just paste your code over the existing code at that region, then obviously you would be overwriting some other important code. This is why we place a hook.

Sometimes it's possible that the game code lends itself to be easily reworked and thus you just overwrite some existing bytes to do that (an example would be my "catch trainer's pokemon" thing). In these cases you don't need hooks (though it's kind of rare in comparison).
I should warn you, to hook successfully into some routines are harder than others. You need to analyze the code at said routine and note to yourself which registers are free, which registers contain information you need after you hook and of course which register you will use for the hook. In complex functions you often don't have a lot of resources, so you need to draw conclusions based on what the analyzed code is like.

Worst case scenario is usually that there's no registers you can use for the hook at the place you want to hook from. If that's the case you just hook early enough to a point where there are registers available and just derive their values and do your code from where you wanted to hook. OK, that last part doesn't make sense unless you've experienced what I'm talking about :P
This last paragraph isn't that important anyways, just me rambling, lol.
Ok thanks, I'll fix up those bits about ldr :). I think I'm clearer on what's happening now after rereading SQ's and your tutorials (in particular, looking at definitions and patterns of coding).

With the hook, I was worried exactly where I'd be needing it. In my head I still think in terms of scripts I'm afraid >< checking flags is easy in scripts, so I didn't see any need to hook. I think I'm going to drop the badges thing for now and instead focus on getting the change done.

So my routine so far does half it's job, once I've added the 0x5 how do I get it to store at the location? Storing at the variable seemed easy enough, but then again that's RAM location not ROM, I tried using strb to get it back to 8250cb9, but that seems illogical anyway (and didn't work).
  #121   Link to this post, but load the entire thread.  
Old February 19th, 2015 (7:49 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Magic View Post
Ok thanks, I'll fix up those bits about ldr :). I think I'm clearer on what's happening now after rereading SQ's and your tutorials (in particular, looking at definitions and patterns of coding).

With the hook, I was worried exactly where I'd be needing it. In my head I still think in terms of scripts I'm afraid >< checking flags is easy in scripts, so I didn't see any need to hook. I think I'm going to drop the badges thing for now and instead focus on getting the change done.

So my routine so far does half it's job, once I've added the 0x5 how do I get it to store at the location? Storing at the variable seemed easy enough, but then again that's RAM location not ROM, I tried using strb to get it back to 8250cb9, but that seems illogical anyway (and didn't work).
Oh you're thinking about the problem wrong in general. Even ASM can't write to the ROM. Here's what you do:

Hook at where Cut's power is loaded (lets pretend it was loaded into r0).
So when you reach your routine, r0 will contain Cut's power. You will merely add five to r0 (for 5 extra power) and then return. This way it's like the game read Cut's power as 5 more than what it is. You don't need to store anything, you just need to modify the power and return. Simple simple :D

EDIT:
It's like this in scripting terms:

Code:
#dyn 0x740000
#org @start
setvar 0x8000 0x0
call addFive
'then game applies it's formula
end

'Think of add five as your routine. The call addFive is like the hook
#org @addFive
addvar 0x8000 0x5
return
__________________
...
  #122   Link to this post, but load the entire thread.  
Old February 19th, 2015 (9:13 AM).
Mana's Avatar
Mana Mana is offline
 
Join Date: Jan 2009
Location: UK
Age: 31
Gender: Male
Posts: 10,075
Quote:
Originally Posted by FBI agent View Post
Oh you're thinking about the problem wrong in general. Even ASM can't write to the ROM. Here's what you do:

Hook at where Cut's power is loaded (lets pretend it was loaded into r0).
So when you reach your routine, r0 will contain Cut's power. You will merely add five to r0 (for 5 extra power) and then return. This way it's like the game read Cut's power as 5 more than what it is. You don't need to store anything, you just need to modify the power and return. Simple simple :D
My poor brain. Still going at this even now ;-;.

I'm still confused as to how I modify the power and return to where - maybe it's because I'm being awkward and trying to modify a HM's power? It's not just about it being read and changed for damage, but also for the HM info and on the moves list on a summary.

Anywho. I followed your guidance to find to hook the power - I tried it from two places, the TM menu and the Summary page.

The breaks that loaded 32 into a register were at 081334CE and 08136A34 respectively. I then used VBA disassemble thingy to look for a starting push function at each of these (does this sound right so far? XD).

Problem is the push functions were waaay waaaaay up from where I started. Including a lot of functions that didn't make sense even with the help of the tutorials. >< I pretty much ignored this, grabbed the offset for the push command, and tried to find another breaking point. It broke repeatedly at the same place, without showing 32 being loaded. So... stumped DX.

I'm sure this is way easier than I'm making it. 4 hours in.
  #123   Link to this post, but load the entire thread.  
Old February 19th, 2015 (9:23 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Magic View Post
My poor brain. Still going at this even now ;-;.

I'm still confused as to how I modify the power and return to where - maybe it's because I'm being awkward and trying to modify a HM's power? It's not just about it being read and changed for damage, but also for the HM info and on the moves list on a summary.

Anywho. I followed your guidance to find to hook the power - I tried it from two places, the TM menu and the Summary page.

The breaks that loaded 32 into a register were at 081334CE and 08136A34 respectively. I then used VBA disassemble thingy to look for a starting push function at each of these (does this sound right so far? XD).

Problem is the push functions were waaay waaaaay up from where I started. Including a lot of functions that didn't make sense even with the help of the tutorials. >< I pretty much ignored this, grabbed the offset for the push command, and tried to find another breaking point. It broke repeatedly at the same place, without showing 32 being loaded. So... stumped DX.

I'm sure this is way easier than I'm making it. 4 hours in.
Aww man Magic. I feel almost bad to tell you that the offsets you found have nothing to do with the move's damage calculations. Those are offsets to the routines which are graphically loading a move's power when looking at the summary page.

What you need to do is:
a) Have a Pokemon have the move cut

b) Get into battle with said Pokemon, and set a bpr @ the move table
Please note that the game will break before you use the move. This is probably for the "fight" menu where it will graphically display the move and it's PP. Make sure to write down all of the offsets it's breaking at anyways (even if you think it's graphical).

c) When the game breaks at the move table (and it's not for graphics) take note of that offset (write it down on notepad/stickynote). Once you get there, report back for further instruction.

I just want to first make sure you're finding the right offsets. In the beginning it will take you some time, as you get better these things will be MUCH faster. When I started, it took me 3 days to find the Surf routine with Touched holding my hand through it all. Don't feel bad, just keep at it :P
__________________
...
  #124   Link to this post, but load the entire thread.  
Old February 19th, 2015 (9:42 AM).
Mana's Avatar
Mana Mana is offline
 
Join Date: Jan 2009
Location: UK
Age: 31
Gender: Male
Posts: 10,075
That actually worked surprisingly well, I narrowed down how many bytes to search for (so PP wouldn't set it off) and got an offset of 0803ed32 pre-break.

It was the only time the game broke after selecting the move.
__________________
  #125   Link to this post, but load the entire thread.  
Old February 19th, 2015 (10:34 AM). Edited February 19th, 2015 by Blah.
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Magic View Post
That actually worked surprisingly well, I narrowed down how many bytes to search for (so PP wouldn't set it off) and got an offset of 0803ed32 pre-break.

It was the only time the game broke after selecting the move.
Alright, so around 0803ED32, we have this code:
Code:
0803ED30                 add    r0, r0, r1
0803ED32                 ldrb    r0, [r0, #0x1]
0803ED34                 strh    r0, [r2]
0803ED36                 b       0x803ED44
Obviously after the addition at 0803ED30, r0 will be the address to "Cut". Then the next line, we're loading the move's power into r0 and the third line we're storing it in r2. The last line we're going to branch unconditionally to 0x803ED44.

OK, I'll tell you that for your hook you should use R3. I know this because I took a look at what happens at the
"b 0x803ED44" 's code and noticed that R3 gets overwritten anyways, so we can use it for our hook. You also lucked our pretty hard here because to place a hook we need to overwrite 8 bytes and ldrb takes 4 bytes, of space, while most other instructions take 2. Which means we can place our hook using R3 at 0803ED30 without overwriting anything besides the instructions I've referenced in the above code block.

However, we ARE replacing them to place our hook, so we do need to restore them in our routine. Specifically you need to restore:
Code:
add r0, r0, r1 @get cut's pointer
ldrb r0, [r0, #0x1] @get cut's power and put it in r0
before starting your code, because we need to know cut's power before we add to it. So your routine needs to START with those two lines. After those two lines, you will do your own modifications to r0 inorder to boost the power (remember only r3 is known to be safe, so if you need an extra register push them or use r3).

Finally after you've increased the power by editing the value in r0, you want to do the rest of the code which we overwrote. That would obviously be:

Code:
strh    r0, [r2]
b       0x803ED44
EDIT:
Actually for the b 0x803ED44 you need to replace that line with:
ldr r3, =(0x803ED44 +1)
bx r3

Because "b" is limited in the distance it can branch to, bx is unlimited. Your compiler won't let you compile unless you use the bx way I've mentioned. R3 as I said earlier was safe to use, so this is fine.
__________________
...
Closed Thread

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 9:25 AM.