Coordinates to world map location [Complete/Full Source]
Something I wrote up. I've been thinking about this for a while. Any input would be nice (Virus, Toe, etc).
Code:
My theory,
Using ASM, make a code that uses your coordinates to compare to your location on the world
map (the layer where the items are stored). For example, in the very top left the
coordinates read D70F D70F and the item slot location is 0x021E3124. I've found that
the first byte in each coordinate is unimportant to this code. What is important is the
second byte (0F in this example). This byte increases less rapidly so in each item slot
on the world map (moving across it) this value will only increase maybe 30-40 (dec).
Here is my idea, in each item slot on the world map, you can increase the coordinate by
32 (dec) and you will roughly be in the same spot on the next item slot. So when people
use this code, they use the activator, it rounds this second byte to the nearest multiple
of 16 so it'll put them roughly in the middle of the item slot they are on. This will
make it easier for the rest of the code. Once they're in the same spot on each item slot we can
add the same value to the coordinates to get the item slot address. Basically, this is a
way of using the coordinates to get your location on the world map. In theory, you could
use this to make a code that allows you to delete an item you're standing on without
using search and replace and replacing all instances of the item and without knowing the
item's exact coordinate.
EXAMPLE:
Item Slot 1 (Top left corner): 0x021E3124
2nd byte of Coordinates (Multiple of 16): 10
Add to address (slot addr-coord): 21E3114
Item slot 2: 0x021E3126
2nd byte of Coordinates (Multiple of 16/add 32): 30
Add to address: 21E30F6
Item slot 3: 0x021e3128
2nd byte of coordinates: 50
Add to address: 21E30D8
I'm stuck at this part. If we get the '2nd byte of coordinates' always divisible by 16 (dec)
and we add 32 to it each time to get onto the next item slot then shouldn't the 'Add to
address' always be equal? Any input to make this work would be helpful. Right now we would
have to not only get the 2nd bytes divisible by 16, but we would have to add 30 to each
'Add to address' value depending on what the 2nd byte was.
Extremely confusing. I'm hoping the more advanced hackers can help me out. The only reason I posted this in Amateur Coding is because it's a work in progress.
Re: Coordinates to world map location
im bit lazy to play the game .. ill try to debug and see how the game calculated the location later ..
btw as i understand on your post .. the 2nd byte of coordinate is more like incremented by 32[20h] that initiate/starts with 16[10h]
so formula is like
Code:
16 + (([MapSlotNo]-1) * 32)
for example for Slot 2
16 + ((2-1)*32)
16 + ((1)*32)
16 + 32
48[30h]
Slot 3
16 + ((3-1)*32)
16 + ((2)*32)
16 + 64
80[50h]
if it really works that way then Slot 4 is like this
16 + ((4-1)*32)
16 + ((3)*32)
16 + 96
112[70h]
now to reverse that formula, this should be look like
if [2ndByte] is less than 48 then [MapSlotNo] = 1
now here is the formula if [2ndByte] is greater than or equal to 48
[MapSlotNo] = (([2ndByte] - 16)/32) + 1
for example if 2ndByte value is 54[36h]
[MapSlotNo] = ((54-16)/32) + 1
[MapSlotNo] = (38/32) + 1
[MapSlotNo] = 1+ 1 //remainder is ignored
[MapSlotNo] = 2
now to retrieve the Final Address the formula is like this
[FinalAddress] = (([MapSlotNo]-1) * 2) + 0x021E3124
so for example if Slot 2
[FinalAddress] = ((2-1)*2) + 0x021E3124
[FinalAddress] = ((1)*2) + 0x021E3124
[FinalAddress] = 2 + 0x021E3124
[FinalAddress] = 0x021E3126
To simplified the two formula .. the new formula can be
if [2ndByte] is less than 48[30h] then
Code:
[MapSlotAddress] = 0x021E3124
if [2ndByte] is greater or equal to 48[30h] then
Code:
[MapSlotAddress] = 0x021E3124 + ((([2ndByte]-16)/32) * 2)
so to retrieve a data using that formula its more like like this in ASM
Code:
mov r0,#0
ldr r1,SecByte
ldrb r1,[r1] //retrieve the 2nd byte
sub r1, #16 //deduct it by 16[10h]
div: //since ARM doesnt have Division we will make our own, r0 = r1/32
cmp r1, #32 // compare value of r1 with 32[20h]
addge r0,#1 //increment r0 with 1 if r1 is greater or equal with 32
subge r1, #32 //sub r1, #32 if r1 is greater or equal with 32
bge div // loop if r1 is greater or equal with 32
//after the loop, r0 = quotient & r1 = remainder/Modulus
end:
lsl r0,#1 //left-shift with 1 is the same as r0*2
ldr r1, Map
add r0,r1 //add value of r0 to the Map location
ldr r0,[r0] // retrieve value in r0 which is the final Address
bx lr
SecByte:
.long 0x00000000 // hehehe im too lazy to check
Map:
.long 0x021E3124
PS.
as always the above code is for bases of idea since it will only work on the first seven slot of the map since it was designed only to check for a byte which is maximum of 255[FFh] .. the next issues to solve was the remaining slot using the other bytes of coordinate mod..
Re: Coordinates to world map location
Very nice. The coordinates are technically structured like this:
Code:
D7 0F 02 00 D7 0F 02 00
|Left/Right| | Up/Down |
The first 4 bytes are Left/Right. When the first byte reaches it's max it increases the 2nd byte by 1. We would have to use the 2nd AND 3rd byte now because when the 2nd byte reaches it's max it increases the 3rd byte by 1. The 3rd byte only gets up to a max of 09 when you're all the way to the right (without going past the normal town borders). The minimum is 02 for this value (all the way to the left when boundaries are normal). This could make it much more difficult. Let me know if you have any idea how we could do this...
Oh and the basic idea behind this method is to use it for an in game world map modifier. It could be combined with the Text to Item code so when you stand on an item, enter the text of a new item in the chat, activate the code the item you're standing on will turn into your new item. Or you could use this method for a more basic code. You stand on something, activate, and it changes to whatever value you set up in the code.
EDIT: The coordinates address are both pointers. You'd have to ask Virus for that information. He did, afterall, create the coordinates mod.
Re: Coordinates to world map location
I have the coord mod in ASM... >_>
Re: Coordinates to world map location
Could you post the source with notes for Toe? I know the coordinates are pointers so maybe that could help him. If the source is private (since it is Zeld's work) I understand.
Re: Coordinates to world map location
Quote:
Originally Posted by Maniac
I have the coord mod in ASM... >_>
is it ASM hack or Custom ASM Routine?
Quote:
Originally Posted by Vash
EDIT: The coordinates address are both pointers. You'd have to ask Virus for that information. He did, afterall, create the coordinates mod.
frankly i don't have problem with pointers .. im just lazy to look for it in releases hehehe
to retrieve the value of it can be this
Code:
ldr r0, =0x21C6DEC
ldr r0,[r0]
cmp r0, #0
ldrne r0,[r0,#0xFFFFFAC0]
andne r1, r0, #0xFF00
r1 will hold the 2nd byte .. while r0 has the whole x - coordinate
anyway .. ill post later the 3rd byte computation .. according to your post ..
[im still on my lazy self hehehe]
Re: Coordinates to world map location
Haha, alright sounds good.
Re: Coordinates to world map location
Quote:
Originally Posted by toenailed
is it ASM hack or Custom ASM Routine?
ASM Routine I do believe. lol
Re: Coordinates to world map location
my country is currently experiencing "la nina" phenomenon .. and the current weather makes me so lazy anyway ill just base this according to your post
now instead of using a per byte check, we try to use a whole 32bit of coordinate both of x and y..
so for example if slot 2, 3rdd byte is 0x02 and 2nd byte is 0x30 then it is clear to say that lower than 0x023000 is Slot 1 and we just need to make a computation on more than slot 1
one whole row has 64 slots while column has 64 slot, so meaning the column 64 and row 64 has a value of 0x9F0xx in x - coordinate and 0x9F0xx in y - coordinate .. and so our formula will be
Legend:
x = x-coordinate
y = y-coordinate
Code:
if [x] < 0x023000 then rowSlot = 1 else
rowSlot = ((([x] lsr 8) - 0x0210)/32) + 1
if [y] < 0x023000 then columnSlot = 1 else
columnSlot = ((([y] lsr 8) - 0x0210)/32) + 1
in ASM
Code:
ldr r0, =0x21C6DEC
ldr r0,[r0]
cmp r0,#0
bxeq lr
mov r12,lr
ldr r3,[r0,#0xFFFFFAC0] @ y - coordinate , [value @ r0] - #0x540
bl checkslot @ check rowSlot
mov r1,r2 @ r1 has the rowSlot
ldr r3,[r0,#0xFFFFFAB8] @ x - coordinate , [value @ r0] - #0x548
bl checkslot @ check columnSlot
mov r0,r2 @ r0 has the columnSlot
@..........................
@ insert unsolve issues here
@..........................
mov pc, r12
checkslot:
lsr r3, #8
mov r2,#1
cmp r3,#0x0230
bxlt lr
sub r3, #0x0210
div:
cmp r3, #32
addge r2,#1
subge r3,#32
bge div
bx lr
so for example if x - coordinate has 0x9FO1F and y - coordinate has 0x230D7
rowSlot = ((((0x9FO1F ) lsr 8) - 0x0210)/0x20) + 1
rowSlot = ((((0x9FO) - 0x0210)/0x20) + 1
rowSlot = (0x7E0/0x20) + 1
rowSlot = 63 + 1
rowSlot = 64
columnSlot = ((((0x0230D7) lsr 8) - 0x0210)/0x20) + 1
columnSlot = (((0x0230) - 0x0210)/0x20) + 1
columnSlot = (0x20/0x20) +1
columnSlot = 1 + 1
columnSlot = 2
it means that the character is in Row 64 at column 2 of the map .. now there is one more issue need to be solve ..
the map has 16 tiles with 16x16 square .. (you can confirm it in animal map) .. and the first tile uses the first 512bytes while second tile uses the second 512bytes and so on .. so we cannot directly use .. 0x21E3124 + ((((rowSlot-1)*64) + (columnSlot-1))*2) .. instead we need a different approach
Re: Coordinates to world map location
Well the world map, excluding the area with walls, is 64x64 slots. We're trying to edit the individual slot you're standing on, not the entire acre (16x16).