Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Generation IV Glitch Discussion

"Void Knowledge Archive, by the members of HallofOrigin" - Page 6

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: SatoMew
Date: 2015-09-29 14:30:19

Yeah. It's thanks to that we'd be able to enter Hall of Origin without walk-through-walls cheat in case we found it in the void. I don't remember if this is the exact coordinates but going something like 65536 steps east, 65536 north and then 65536 east again you should enter a Fake HoO in an HoO area, assuming you're starting from its initial area (the steps would vary according from where you'd start from).


But does said Hall of Origin area play the same theme as the actual real Hall (map ID 0x01FE or 510)? Or is it the Spear Pillar theme that the other Hall (map ID 0x01FF or 511) also uses?

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-09-29 14:44:18
If anyone can help debug why this doesn't work, it would be greatly appreciated  O_o

function whereami()
aslr_data_ptr = memory.readdword(0x021C4D28)
mapdata_ptr = memory.readdword(aslr_data_ptr + 0x4)
m = memory.readword(mapdata_ptr + 0x14A4)
x = memory.readword(mapdata_ptr + 0x14A4 + 8)
y = memory.readword(mapdata_ptr + 0x14A4 + 12)
z = memory.readword(mapdata_ptr + 0x14A4 + 0x6C99A)

all_x = {0x226E7AC, 0x2291DE4, 0x2291DF0, 0x2291DFE,0x2333286,0x2333292,0x23332BA,0x2333E0A4}
all_y = {0x226E7AC+4, 0x2291DE4+4, 0x2291DF0+4, 0x2291DFE+4,0x2333286+4,0x2333292+4,0x23332BA+4,0x2333E0A4+4}
all_z = {0x21CEF76,0x2291E02,0x22DB13E,0x23067A6,0x232460A,0x2333296,0x23332BE}
for i = 1,7 do
-- The values above were taken from my own save state of Pearl. As such, we need to subtract my own map_data_ptr from them, and add the current session's:
-- (skipping over the eighth one since this only appears for x (and consequently y) but not z; its lack of a clear effect suggests the eighth value to be a false positive)
all_x[i] = all_x[i] - 0x226D300 + mapdata_ptr
all_y[i] = all_y[i] - 0x226D300 + mapdata_ptr
all_z[i] = all_z[i] - 0x226D300 + mapdata_ptr
end

all_m = {0x226E7A4,0x2291EC0,0x2291FE8,0x22ABCB0}
for i = 1,4 do
-- If we modify m (= all_m[1]), the game freezes. Perhaps we also need to update the others? Note interesting change counts: walking in and out of a building twice yields the expected change count of 4 for items 1 and 4, but 8 for item 3 and 10 for item 2.
all_m[i] = all_m[i] - 0x226D300 + mapdata_ptr
end

--memory.writeword(all_x[1],force_x) -- if this one is different from the others, the save file will be corrupted; if it is forced during save loading, the game will immediately crash when the save is loaded. This seems to actually move you collision-wise, but not visually.
--memory.writeword(all_x[2],force_x) -- the same; also if this one is forced, the save load screen will display a glitched white block. Does nothing live - perhaps this is the saved x position only?
--memory.writeword(all_x[3],force_x) -- changes map ID!!! but only live, not when loading save. Can be used to save inside a MZ (open start menu, change value to warp you into MZ), with bizarre results.
--memory.writeword(all_x[4],force_x) -- immediately snaps you into place, but without changing map id. Is saved when you save the game only if forced DURING the save, otherwise your new position is NOT saved. Interestingly, THIS IS ONLY GRAPHICAL
--memory.writeword(all_x[5],force_x) -- seems related to graphics loading
--memory.writeword(all_x[6],force_x) -- this one...
--memory.writeword(all_x[7],force_x) -- ...and this one are related; if one of them is flipped, the screen goes black and the other one starts counting like a madman. Counting resets when reloading the graphics. When forcing these to be set and taking a step, the perspective twists, showing this is contorlling the camera.
--memory.writeword(all_x[8],force_x) -- unknown?

function force_m(pos)
memory.writeword(all_m[1],pos) -- name tag. but based on real x,y,z! (i.e. OW locations get their name based on your coordinates)
memory.writeword(all_m[2],pos) -- graphics, but only after reload
--memory.writeword(all_m[3],pos)
--memory.writeword(all_m[4],pos)
end
function force_x(pos)
memory.writeword(all_x[1],pos) -- collision
memory.writeword(all_x[3],pos) -- graphics
memory.writeword(all_x[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end
function force_y(pos)
memory.writeword(all_y[1],pos) -- collision
memory.writeword(all_y[3],pos) -- graphics
memory.writeword(all_y[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end
function force_z(pos)
memory.writeword(all_z[1],pos) -- collision
memory.writeword(all_z[3],pos) -- graphics
memory.writeword(all_z[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end

force_m(3) -- Jubilife city
force_x(180) -- Jubilife city
force_y(777) -- Jubilife city
force_z(2) -- Jubilife city

gui.text(0,144,string.format("ASLR data: 0x%X / map data: 0x%X",aslr_data_ptr,mapdata_ptr))
gui.text(1,154,string.format("Matrix: %d, X: %d, Y: %d, Z: %d",m,x,y,z))
gui.text(0,164,string.format("X: %d %d %d %d %d %d %d %d",memory.readword(all_x[1]),memory.readword(all_x[2]),memory.readword(all_x[3]),memory.readword(all_x[4]),memory.readword(all_x[5]),memory.readword(all_x[6]),memory.readword(all_x[7]),memory.readword(all_x[8])))
gui.text(0,174,string.format("Addrs: %X %X %X %X\n      %X %X %X %X",all_x[1],all_x[2],all_x[3],all_x[4],all_x[5],all_x[6],all_x[7],all_x[8]))
end
gui.register(whereami)

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: Tsukuu
Date: 2015-09-29 14:48:08


Yeah. It's thanks to that we'd be able to enter Hall of Origin without walk-through-walls cheat in case we found it in the void. I don't remember if this is the exact coordinates but going something like 65536 steps east, 65536 north and then 65536 east again you should enter a Fake HoO in an HoO area, assuming you're starting from its initial area (the steps would vary according from where you'd start from).


But does said Hall of Origin area play the same theme as the actual real Hall (map ID 0x01FE or 510)? Or is it the Spear Pillar theme that the other Hall (map ID 0x01FF or 511) also uses?


That's an hypothetical real Hall of Origin, if we found it. So the real one. But the 511 should work like the other one anyway, you'd get trapped if you managed to enter it though, because it has no exit warp.

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: ~Poke~
Date: 2015-09-29 21:09:15

The Hall of Origin loads script file 232, which is:
Script #1

CheckFlag 0x8E
CompareLastResultJump 0x1 Function_#1
End


Script #2

LockAll
SetVar 0x4118 0x0
Call Function_#2
Call Function_#3
PlayCry 0x1ED 0x0
WaitCry
Call Function_#8
PlayCry 0x1ED 0x0
Message 0x0
CloseMessageOnKeyPress
ClearFlag 0x8E
WildBattle2 0x1ED 0x50
SetFlag 0x8E
CheckLost 0x800C
If 0x800C 0x0
CompareLastResultJump 0x1 Function_#9
CheckWildBattle2 0x800C
If 0x800C 0x1
CompareLastResultJump 0x1 Function_#10
ClearFlag 0x11E
ReleaseAll
End


Script #3

End


Script #4

UseScript_#2

There are also functions and movements as part of this script file, but they're less telling so I'll leave them out.

As you can see script 2 involves playing a cry and starting a battle, this would be the Arceus fight. All script 4 does is call script 2, which is nice since it doubles our chances of making this work.
In the event viewer, the HoO has 2 events. One overworld (Arceus) who is set to script 0 and one trigger set to script 2. The trigger has a flag associated - this probably means it only appears when that flag is set, that flag being the event? It's 16664 if anyone knows.


Is this for Diamond and Pearl or Platinum? In Diamond and Pearl, the Arceus sprite will appear even if you don't have the Azure Flute (regardless of the state of the event flag) but this is not the case in Platinum, in which the Azure Flute is required to make the sprite appear.


That was Pearl. Yes, Arceus is always visible but does not have a script. The trigger (3x1 space that triggers a script when you stand in it) only exists when flag 16664 is set (0x4118 in hex).

In Platinum it all looks the same except that Arceus only appears when flag 590 (hex 0x24E) is set, and script 3 (empty in Pearl) changes some flags.
Script #3

028B 0x2 0x4000
If 0x4000 0x0
CompareLastResultJump 0x1 Function_#12
CheckFlag 0x11E
CompareLastResultJump 0x1 Function_#12
SetFlag 0x24E
End


Function #12

ClearFlag 0x24E
End


This script manages whether Arceus will appear, based on some other flags. Probably to make it appear on entering? Not completely sure without going through everything but that sounds like a safe bet. Scripts 2 and 4 are exactly the same except for the after battle checks, so calling them through another npc if possible will work just as well on Platinum as it would on Diamond/Pearl.

After battle in Pearl:
If you lost: go to Pokecenter & set flag 0x26C
If "WildBattle2" set flag 0x26C and say "ARCEUS disappeared from sight…" (is this if ran away? or defeated it?)
Else: clear flag 0x11E

After battle in Platinum:
If you lost: go to Pokecenter & set flag 0x24E
If "WildBattle2" set flag 0x24E and say the same
If 0x4056 = 0: set variable 0x4056 = 1 and clear flag 0x11E
Else: clear flag 0x11E

Another result to the battle was added. Is it for caught? Is Arceus not rebattleable in Diamond/Pearl? Or maybe it had to be reworked for some other reason. Either way it shouldn't cause problems.


Yeah. It's thanks to that we'd be able to enter Hall of Origin without walk-through-walls cheat in case we found it in the void. I don't remember if this is the exact coordinates but going something like 65536 steps east, 65536 north and then 65536 east again you should enter a Fake HoO in an HoO area, assuming you're starting from its initial area (the steps would vary according from where you'd start from).

Huh, did people ever try tweaking in the void to get back inside? Maybe that's too unreliable/unstable.


If anyone can help debug why this doesn't work, it would be greatly appreciated  O_o

function whereami()
aslr_data_ptr = memory.readdword(0x021C4D28)
mapdata_ptr = memory.readdword(aslr_data_ptr + 0x4)
m = memory.readword(mapdata_ptr + 0x14A4)
x = memory.readword(mapdata_ptr + 0x14A4 + 8)
y = memory.readword(mapdata_ptr + 0x14A4 + 12)
z = memory.readword(mapdata_ptr + 0x14A4 + 0x6C99A)

all_x = {0x226E7AC, 0x2291DE4, 0x2291DF0, 0x2291DFE,0x2333286,0x2333292,0x23332BA,0x2333E0A4}
all_y = {0x226E7AC+4, 0x2291DE4+4, 0x2291DF0+4, 0x2291DFE+4,0x2333286+4,0x2333292+4,0x23332BA+4,0x2333E0A4+4}
all_z = {0x21CEF76,0x2291E02,0x22DB13E,0x23067A6,0x232460A,0x2333296,0x23332BE}
for i = 1,7 do
-- The values above were taken from my own save state of Pearl. As such, we need to subtract my own map_data_ptr from them, and add the current session's:
-- (skipping over the eighth one since this only appears for x (and consequently y) but not z; its lack of a clear effect suggests the eighth value to be a false positive)
all_x[i] = all_x[i] - 0x226D300 + mapdata_ptr
all_y[i] = all_y[i] - 0x226D300 + mapdata_ptr
all_z[i] = all_z[i] - 0x226D300 + mapdata_ptr
end

all_m = {0x226E7A4,0x2291EC0,0x2291FE8,0x22ABCB0}
for i = 1,4 do
-- If we modify m (= all_m[1]), the game freezes. Perhaps we also need to update the others? Note interesting change counts: walking in and out of a building twice yields the expected change count of 4 for items 1 and 4, but 8 for item 3 and 10 for item 2.
all_m[i] = all_m[i] - 0x226D300 + mapdata_ptr
end

--memory.writeword(all_x[1],force_x) -- if this one is different from the others, the save file will be corrupted; if it is forced during save loading, the game will immediately crash when the save is loaded. This seems to actually move you collision-wise, but not visually.
--memory.writeword(all_x[2],force_x) -- the same; also if this one is forced, the save load screen will display a glitched white block. Does nothing live - perhaps this is the saved x position only?
--memory.writeword(all_x[3],force_x) -- changes map ID!!! but only live, not when loading save. Can be used to save inside a MZ (open start menu, change value to warp you into MZ), with bizarre results.
--memory.writeword(all_x[4],force_x) -- immediately snaps you into place, but without changing map id. Is saved when you save the game only if forced DURING the save, otherwise your new position is NOT saved. Interestingly, THIS IS ONLY GRAPHICAL
--memory.writeword(all_x[5],force_x) -- seems related to graphics loading
--memory.writeword(all_x[6],force_x) -- this one...
--memory.writeword(all_x[7],force_x) -- ...and this one are related; if one of them is flipped, the screen goes black and the other one starts counting like a madman. Counting resets when reloading the graphics. When forcing these to be set and taking a step, the perspective twists, showing this is contorlling the camera.
--memory.writeword(all_x[8],force_x) -- unknown?

function force_m(pos)
memory.writeword(all_m[1],pos) -- name tag. but based on real x,y,z! (i.e. OW locations get their name based on your coordinates)
memory.writeword(all_m[2],pos) -- graphics, but only after reload
--memory.writeword(all_m[3],pos)
--memory.writeword(all_m[4],pos)
end
function force_x(pos)
memory.writeword(all_x[1],pos) -- collision
memory.writeword(all_x[3],pos) -- graphics
memory.writeword(all_x[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end
function force_y(pos)
memory.writeword(all_y[1],pos) -- collision
memory.writeword(all_y[3],pos) -- graphics
memory.writeword(all_y[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end
function force_z(pos)
memory.writeword(all_z[1],pos) -- collision
memory.writeword(all_z[3],pos) -- graphics
memory.writeword(all_z[4],pos) -- matrix
--memory.writeword(all_x[2],pos)
--memory.writeword(all_x[5],pos)
--memory.writeword(all_x[6],pos)
--memory.writeword(all_x[7],pos)
end

force_m(3) -- Jubilife city
force_x(180) -- Jubilife city
force_y(777) -- Jubilife city
force_z(2) -- Jubilife city

gui.text(0,144,string.format("ASLR data: 0x%X / map data: 0x%X",aslr_data_ptr,mapdata_ptr))
gui.text(1,154,string.format("Matrix: %d, X: %d, Y: %d, Z: %d",m,x,y,z))
gui.text(0,164,string.format("X: %d %d %d %d %d %d %d %d",memory.readword(all_x[1]),memory.readword(all_x[2]),memory.readword(all_x[3]),memory.readword(all_x[4]),memory.readword(all_x[5]),memory.readword(all_x[6]),memory.readword(all_x[7]),memory.readword(all_x[8])))
gui.text(0,174,string.format("Addrs: %X %X %X %X\n      %X %X %X %X",all_x[1],all_x[2],all_x[3],all_x[4],all_x[5],all_x[6],all_x[7],all_x[8]))
end
gui.register(whereami)



Interesting script!
From just initial testing, I think there's some confusion between map and matrix. Eg. Jubilife city is map header 3 in matrix 0. Route 204 is map header 345 in matrix 0. I'm not completely sure what the script is doing, but if I run it indoors I end up in that building's void so the matrix isn't being set.

I think the map header should be considered a result rather than something to set - it's the place you end up being in at certain coordinates within a certain matrix. (It gets a little more confusing with being indoors since warps point at a header which then loads the correct matrix, but I think that's just because they decided it should work like that? That seems to be backwards from how the engine runs. I think the fact that other headers are found by walking out of bounds in that target matrix shows that something doesn't line up there. Or maybe not backwards, but still a way to call them in the other order. Maybe you could do it by setting the map if you use a warp at the same time.)

If I run the script while already in Jubilife it seems to line my X up with the pokecenter, but not Y so I guess that address might not be right, at least for one of them? Also graphical glitches but that might be because of the Y. If I run the script in a different route I still go to the X of the Jubilife Pokecenter door. If I walk around with the script running (only possible with walk anywhere, even if it puts me in a clear spot) npcs get cloned.

To search for the matrix address you'll need to find the find the matrix values with Spiky's DS Map Editor, since there's no real correlation between header number and matrix number.

(Interestingly, a lot of the generic buildings are different headers that call the same matrix. This means the exact same map (graphics and movement) is loaded but with different npcs, warps, text, scripts and etc.)

EDIT: Ok that difference between warping via header and travelling via matrix has got me thinking. The 3 layer matrices and the 1 layer matrices are laid out differently. The overworld/marsh are [headers, mystery zone heights, map files] while indoor matrices are just [map files] because the entire indoor place uses the same header. When you move between two matrix cells in the overworld it loads the map header, mystery zone height, and map data from the matrix in that order. Does that mean that it's trying to read 2 layers above the map data in an indoor matrix when you walk out of bounds? Or maybe even the same layer, since it sounds kinda illogical to reference things relative to the third layer… That might explain why indoor matrices are all so similar, if they're getting some data from the start of the map file that's mostly the same. That doesn't explain being affected by flags though… unless hey. If it tries to look "2 layers above" the map file in memory without putting any map header data in that memory, it'll be reading whatever's there just before the map data. That sounds possible?

This wild speculation is convincing me that the Great Marsh is going to be interesting. I just took a quick look now and riding North 800 steps from the top left has given me a couple Turnback Caves and Mystery Zones… but no Floaroma or Veilstone Store… so no second section?

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-09-30 03:23:33
I've progressed some further with my script. I've done some simple digging for matrix values too, and the script now looks like this:
function whereami()
aslr_data_ptr = memory.readdword(0x021C4D28)
mapdata_ptr = memory.readdword(aslr_data_ptr + 0x4)
m_pksv = memory.readword(mapdata_ptr + 0x14A4)
x_pksv = memory.readword(mapdata_ptr + 0x14A4 + 8)
y_pksv = memory.readword(mapdata_ptr + 0x14A4 + 12)
z_pksv = memory.readword(mapdata_ptr + 0x14A4 + 0x6C99A)

mtx = {0x22B2E,0x6791C,0x67A40}
m  = {0x14A4,0x24BC0,0x24CE8}
x  = {-0x61C5A,-0x61C72,0x14AC,0x24AE4,0x24AF0,0x24AFE}
y  = {        -0x61C7A,0x14B0,0x24AEC,0x24AF8,0x24B06}
z  = {        -0x61C76,      0x24B02,                0x6DE3E,0x994A6,0xC5F96,0xC5FBE}

function _force(where,what)
for i,v in ipairs(where)
do
memory.writeword(mapdata_ptr+v,what)
end
end

function force(_mtx,_m,_x,_y,_z)
_force(mtx,_mtx)
_force(m,_m)
_force(x,_x)
_force(y,_y)
_force(z,_z)
end

--force(0,3,145,750,2) -- Jubilife city
--force(0,8,21,13,0) -- Poketch void
--force(0,8,21,65505,0) -- one step before SS
--_force(y,65504) -- after having warped into one step before SS, force to walk one more step into SS

gui.text(0,184,string.format("mtx: %d m: %d x: %d, y: %d, z: %d",memory.readword(mapdata_ptr+mtx[1]),m_pksv,x_pksv,y_pksv,z_pksv))
end
gui.register(whereami)

What is interesting is that it seems to warp correctly now, but that it still fails to load the next map on its own. That is, if you uncomment the line 'force(0,8,21,65505,0) – one step before SS', your new location will be correctly set to a few steps above Poketch Co such that, if you take one more step, you will enter the Floaroma Meadows. However, forcing the game to take that step by uncommenting the line after that does not do anything. Interestingly, you can't take that step yourself either - you're blocked by an invisible wall. If you save and reset, however, you can take that next step all of a sudden, and you will load Floaroma Meadows, but if you try to have the step walked automatically by uncommenting the _force(y,65504) line, it won't load Floaroma Meadows again. Unless, and this is the only scenario in which this works, you save one step before SS, load your save, and while at the journal pages activating the _force(y.. line; only in this case, you are correctly warped into Floaroma Meadows.

So, we still won't manage to automate searching the void. Apparently, pressing up and walking does something extra than just changing your y coordinate, which is apparently crucial for loading a new map area…

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: ~Poke~
Date: 2015-09-30 03:33:33

What is interesting is that it seems to warp correctly now, but that it still fails to load the next map on its own. That is, if you uncomment the line 'force(0,8,21,65505,0) – one step before SS', your new location will be correctly set to a few steps above Poketch Co such that, if you take one more step, you will enter the Floaroma Meadows. However, forcing the game to take that step by uncommenting the line after that does not do anything. Interestingly, you can't take that step yourself either - you're blocked by an invisible wall. If you save and reset, however, you can take that next step all of a sudden, and you will load Floaroma Meadows, but if you try to have the step walked automatically by uncommenting the _force(y,65504) line, it won't load Floaroma Meadows again. Unless, and this is the only scenario in which this works, you save one step before SS, load your save, and while at the journal pages activating the _force(y.. line; only in this case, you are correctly warped into Floaroma Meadows.

Nice progress!
On your previous script I was able to walk after warping with a walk anywhere code, try that.

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-09-30 04:13:22
On your previous script I was able to walk after warping with a walk anywhere code, try that.
Thanks! Now I can take that extra step, but it still only loads the correct area (Floaroma Meadows) if I came from the real Poketch Co (which turns out to be matrix 141, so change the commented code above with the below). If I warp directly to Poketch Co @ [21,65505] (from my original position of - coincidentally - somewhere in Jubilife), I get a mystery zone when I move that one step up, which I presume is the mystery zone from Jubilife's [21,65504/5] coordinates as opposed to Poketch Co's, but which is only shown to me after I manually take a step because that is the moment when map names happen to drawn in the top-left corner. In other words, the map name probably didn't shift because I crossed a map line in Poketch Co, but rather because my x and y coordinates were out of bounds for Jubilife and the game only updates the map name after you take a step. This means my warping is still unsuccessful: my x,y,z coordinates shift correctly, but my attempts to force the game to load a specific map or matrix are still not right.
--force(0,3,145,750,2) -- Jubilife city
--force(141,8,21,13,0) -- Poketch void
--force(141,8,21,65505,0) -- one step before SS
--_force(y,65504) -- after having warped into one step before SS, force to walk one more step into SS


What I wouldn't give for a disassembly of the keypress handler or the map handler right now  ;D

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: Stackout
Date: 2015-09-30 08:41:24

What I wouldn't give for a disassembly of the keypress handler or the map handler right now  ;D


Then go set some conditional breakpoints and find them :D

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: SatoMew
Date: 2015-09-30 13:24:40

That was Pearl. Yes, Arceus is always visible but does not have a script. The trigger (3x1 space that triggers a script when you stand in it) only exists when flag 16664 is set (0x4118 in hex).

In Platinum it all looks the same except that Arceus only appears when flag 590 (hex 0x24E) is set, and script 3 (empty in Pearl) changes some flags.
Script #3

028B 0x2 0x4000
If 0x4000 0x0
CompareLastResultJump 0x1 Function_#12
CheckFlag 0x11E
CompareLastResultJump 0x1 Function_#12
SetFlag 0x24E
End


Function #12

ClearFlag 0x24E
End


This script manages whether Arceus will appear, based on some other flags. Probably to make it appear on entering? Not completely sure without going through everything but that sounds like a safe bet. Scripts 2 and 4 are exactly the same except for the after battle checks, so calling them through another npc if possible will work just as well on Platinum as it would on Diamond/Pearl.

After battle in Pearl:
If you lost: go to Pokecenter & set flag 0x26C
If "WildBattle2" set flag 0x26C and say "ARCEUS disappeared from sight…" (is this if ran away? or defeated it?)
Else: clear flag 0x11E

After battle in Platinum:
If you lost: go to Pokecenter & set flag 0x24E
If "WildBattle2" set flag 0x24E and say the same
If 0x4056 = 0: set variable 0x4056 = 1 and clear flag 0x11E
Else: clear flag 0x11E

Another result to the battle was added. Is it for caught? Is Arceus not rebattleable in Diamond/Pearl? Or maybe it had to be reworked for some other reason. Either way it shouldn't cause problems.


I see, thanks.

"ARCEUS disappeared from sight…" appears if you defeat it or if you run away. You can see this on my video of the Hall of Origin event in Platinum, though I don't show what happens when you run.

Video: https://www.youtube.com/watch?v=s-mJkCVZ1pg

As to Diamond and Pearl, I currently don't have a save file ready so that I can test the event. I did find something interesting, though. The game seems to return the message "The Azure Flute echoed hollowly… It appears to be meaningless using the Azure Flute here…" in English or てのふはなくなひびのばでつってみなだ in Japanese if you go to Spear Pillar with the Azure Flute and the event flag set but don't meet all the conditions required to trigger the event (entering the Hall of Fame, obtaining the National Pokédex, and defeating Team Galactic at Spear Pillar). POKESAV lets you manage the save file's event flags, which comes in handy.

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-09-30 14:46:41


What I wouldn't give for a disassembly of the keypress handler or the map handler right now  ;D


Then go set some conditional breakpoints and find them :D
Even if I had the skill, I can't manage - when I fire up gdb connected to my desmume and press Ctrl+C, desmume says 'Breaking execution', but it doesn't. That makes live debugging via the gdb stub kind of impossible…

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: Stackout
Date: 2015-09-30 15:11:45



What I wouldn't give for a disassembly of the keypress handler or the map handler right now  ;D


Then go set some conditional breakpoints and find them :D
Even if I had the skill, I can't manage - when I fire up gdb connected to my desmume and press Ctrl+C, desmume says 'Breaking execution', but it doesn't. That makes live debugging via the gdb stub kind of impossible…


would no$gba debug version work?

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-10-01 13:16:32
would no$gba debug version work?
Ah, thanks for the pointer - I thought no$ was still dead! I'll try playing with it a bit, but I'm a complete noob at debugging, so I'm anticipating that I won't come up with any revolutionary findings. But thanks for the tip!

EDIT: OK, need some help again. I couldn't understand the nocash debugger, so I went back to playing with desmume. I noticed that changing the values at [mapdata_ptr+0x24AF0] and [mapdata_ptr+0x24AF8] changes the map id to the one that is found at the specified x and y coordinates. Or crashes the emu :-\. What I wanted to do is write a 'scanner': increment one of these values by 32, print the resulting map header, try again. However, I don't know how to print to stdout, and I can't exactly write 200000 gui.text() commands. Does anyone know how to write to stdout?
EDIT2: Fixed. Grepping the desmume source yields the desired command: 'print'  :-X
The script now prints a map of every 32x32 section of your current matrix to the lua console.

Note: this code still suffers a critical defect for being valid for void exploring: when walking through the void, the matrix sometimes changes. This will affect what map ids you will get next. However, since this script does not actually walk, these matrix changes are never triggered. Thus, once you cross a matrix boundary, the results from this script would no longer be valid. I don't have the knowledge to fix this - we'd need to know what exactly triggers a matrix change, and debugging this is just miles beyond me, I'm afraid.

aslr_data_ptr = memory.readdword(0x021C4D28)
mapdata_ptr = memory.readdword(aslr_data_ptr + 0x4)

mtxs = {0x22B2E,0x6791C,0x67A40}
ms  = {0x14A4,0x24BC0,0x24CE8}
xs  = {-0x61C5A,-0x61C72,0x14AC,0x24AE4,0x24AF0,0x24AFE}
ys  = {        -0x61C7A,0x14B0,0x24AEC,0x24AF8,0x24B06}
zs  = {        -0x61C76,      0x24B02,                0x6DE3E,0x994A6,0xC5F96,0xC5FBE}

function whereami()
m_pksv = memory.readword(mapdata_ptr + 0x14A4)
x_pksv = memory.readword(mapdata_ptr + 0x14A4 + 8)
y_pksv = memory.readword(mapdata_ptr + 0x14A4 + 12)
z_pksv = memory.readword(mapdata_ptr + 0x14A4 + 0x6C99A)
gui.text(0,174,string.format("matrix data starts at %X",mapdata_ptr+mtxs[1]))
gui.text(0,184,string.format("mtx: %d m: %d x: %d, y: %d, z: %d",memory.readword(mapdata_ptr+mtxs[1]),m_pksv,x_pksv,y_pksv,z_pksv))
end
gui.register(whereami)

-- The below functions don't really warp you (your real coords don't change), but do load the map header of the next section
function readmap()
return memory.readword(mapdata_ptr+0x14A4)
end
function readfakex()
return memory.readword(mapdata_ptr+0x24AF0)
end
function writefakex(pos)
memory.writeword(mapdata_ptr+0x24AF0,pos)
end
function readfakey()
return memory.readword(mapdata_ptr+0x24AF8)
end
function writefakey(pos)
memory.writeword(mapdata_ptr+0x24AF8,pos)
end

for newy=0,65535,32
do
writefakey(newy)
line = ""
for newx=0,65535,32
do
writefakex(newx)
emu.frameadvance()
line = string.format("%s%05d ",line,readmap())
end
print(line)
end

(Also, run this script. It does some hilarious things to your game, at least when you start it from the overworld (remember, it doesn't correctly switch matrices!) ;D ) )

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: ~Poke~
Date: 2015-10-02 06:03:12
Nice work on your script! I tried it out myself and it does look rather funny :P
By the way, I think it does show valid data as explained below, so maybe all that's needed now is an organised way to output it. Perhaps just .csv (basically plain text) so we can load it into google docs or excel or etc. Another approach would be to ignore most values and have it search for some specific ones, outputting their coordinates. I guess it depends whether we want a hard to look at map of the entire void or a way to search for specific places, both of which may differ between save files.



Note: this code still suffers a critical defect for being valid for void exploring: when walking through the void, the matrix sometimes changes. This will affect what map ids you will get next. However, since this script does not actually walk, these matrix changes are never triggered. Thus, once you cross a matrix boundary, the results from this script would no longer be valid. I don't have the knowledge to fix this - we'd need to know what exactly triggers a matrix change, and debugging this is just miles beyond me, I'm afraid.


I don't think the matrix does change while exploring. I just did a short test, see this video (A little over double speed because I wanted to test quickly).

[youtube]https://www.youtube.com/watch?v=UVuOdV1REWk&feature=youtu.be[/youtube]

Basically when going through warps or saving/loading the matrix depends on the header. When travelling between areas as you do on the overworld, in the great marsh or in the void (of any matrix), headers depend on matrix.
I'm on a trip to Fake Sinnoh now to confirm this, since this was just a short journey.
Edit: I got to North Fake Sinnoh. Matrix stayed 0 the whole way, but… I can't believe I forgot this? The headers don't line up with the world? So I guess there is something else to how they're loaded… :/
Apparently I need to go look over all the basics again haha. Saving in NFS should put me there in the real world right? Anyway, this script is a good start.
Stickymans SPHoO void: 70,000 North, 2,912 East

Maybe some coordinates are stored as 4 byte rather than 2 byte? I hope it isn't just that along the journey the good data is changed (though that sounds very possible) because if it's path specific I don't see any trustworthy way of faking it like this, we'd have to make the lua actually travel it properly. That would be so much slower and also means we don't avoid the Pt/HG/SS crashes that this script probably would? (not tested).

Edit again: Yes, I'm seeing three 4 byte x coordinates. They do underflow to full 4 byte numbers, so these must be why the headers are different.
They're at mapdata_ptr + 14AC,  24AE4,  24AF0

Here's the script I used, a slight edit on your first one:
local function whereami()
local aslr_data_ptr = memory.readdword(0x021C4D28)
local mapdata_ptr = memory.readdword(aslr_data_ptr + 0x4)
local map = memory.readword(mapdata_ptr + 0x14A4)
local x = memory.readword(mapdata_ptr + 0x14A4 + 8)
local y = memory.readword(mapdata_ptr + 0x14A4 + 12)
local mat = memory.readword(mapdata_ptr + 0x00022B2E)
gui.text(2,3,string.format("Map: %d, X: %d, Y: %d, Mat: %d",map,x,y,mat))
gui.text(2,182,string.format("ptr: %x",mapdata_ptr))
end
gui.register(whereami)

It doesn't show fps itself, I just turned that on in the HUD.

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: vowel
Date: 2015-10-02 11:06:51
By the way, I think it does show valid data as explained below, so maybe all that's needed now is an organised way to output it. Perhaps just .csv (basically plain text) so we can load it into google docs or excel or etc. Another approach would be to ignore most values and have it search for some specific ones, outputting their coordinates. I guess it depends whether we want a hard to look at map of the entire void or a way to search for specific places, both of which may differ between save files.

What it's doing right now (or at least, it should; I haven't tested it all the way) is printing a map to desume's stdout (the lua window). That it, for every 32 steps it takes to the right, it prints a zero-padded map id plus a space, and once it's reached x=65536 (which is the same as 0), it increments y by 32 and starts a new line. As such, when you let the script run, you will have a full map, and if there's a 510 in there all you can immediately see how you get to it.

I don't think the matrix does change while exploring. I just did a short test, see this video (A little over double speed because I wanted to test quickly).
Looks like you're right :o
Edit: I got to North Fake Sinnoh. Matrix stayed 0 the whole way, but… I can't believe I forgot this? The headers don't line up with the world? So I guess there is something else to how they're loaded… :/
Apparently I need to go look over all the basics again haha. Saving in NFS should put me there in the real world right? Anyway, this script is a good start.
Well, we know that all of FS is basically shit due to not being loaded properly (e.g. lots of routes missing or not lining up correctly), but for our purposes, none of this is relevant - the only thing that matters is that we can walk anywhere (barring z issues) and that we have to find a way to reach a map that is of id 510. (And then hope that it's still going to be a 510 after we walk back to whereever our script #1/#2 npc is.)
Stickymans SPHoO void: 70,000 North, 2,912 East

Maybe some coordinates are stored as 4 byte rather than 2 byte? I hope it isn't just that along the journey the good data is changed (though that sounds very possible) because if it's path specific I don't see any trustworthy way of faking it like this, we'd have to make the lua actually travel it properly. That would be so much slower and also means we don't avoid the Pt/HG/SS crashes that this script probably would? (not tested).

Edit again: Yes, I'm seeing three 4 byte x coordinates. They do underflow to full 4 byte numbers, so these must be why the headers are different.
They're at mapdata_ptr + 14AC,  24AE4,  24AF0

Well, something must definitely be going on, since the FS at 70k N should be exactly the same as the FS at 5k-430 N otherwise, and this is evidently not the case. Does my script correctly reach the Stickyman HoO? If so, then data changes along the way, but my script manages to emulate that properly. If not, then either data does change along the way but my script's way of "walking" doesn't trigger that (so we'd need to reprogram it to also do stuff to these other RAM pointers you mention), or the data doesn't change but these RAM areas do change as a function of real walking and we will still need to do the same.

Re: "Void Knowledge Archive, by the members of HallofOrigin"

Posted by: ~Poke~
Date: 2015-10-02 12:04:27
What it's doing right now (or at least, it should; I haven't tested it all the way) is printing a map to desume's stdout (the lua window). That it, for every 32 steps it takes to the right, it prints a zero-padded map id plus a space, and once it's reached x=65536 (which is the same as 0), it increments y by 32 and starts a new line. As such, when you let the script run, you will have a full map, and if there's a 510 in there all you can immediately see how you get to it.

It's just a little hard to look at is all, unless there's a way to get a horizontal scrollbar? (Assuming the new line of void prints on a new line? Yeah I guess it does.)

Well, we know that all of FS is basically s**t due to not being loaded properly (e.g. lots of routes missing or not lining up correctly), but for our purposes, none of this is relevant - the only thing that matters is that we can walk anywhere (barring z issues) and that we have to find a way to reach a map that is of id 510. (And then hope that it's still going to be a 510 after we walk back to whereever our script #1/#2 npc is.)

All the maps are there, minus tilesets which makes them look weird. I guess since neither headers nor even collision dara are there it's more "Fake" than "Real", but my worry is that if the coordinates really are 2 bytes then they can't distinguish between Real Sinnoh and any of the fakes.

Do we know what happens of you go to Fake Sinnoh then back to Real Sinnoh? I'll go test that now.

Well, something must definitely be going on, since the FS at 70k N should be exactly the same as the FS at 5k-430 N otherwise, and this is evidently not the case. Does my script correctly reach the Stickyman HoO? If so, then data changes along the way, but my script manages to emulate that properly. If not, then either data does change along the way but my script's way of "walking" doesn't trigger that (so we'd need to reprogram it to also do stuff to these other RAM pointers you mention), or the data doesn't change but these RAM areas do change as a function of real walking and we will still need to do the same.

Your script only increments to 65k, since that's a full 2 byte number so I don't see how it could reach 70k. I haven't run it extensively though, and in theory (so if it does wrap after 2 bytes) that'd show up near the end of your script since 70k North would be around 60k South, and you do horizontal first.
I don't really get how both a 2 byte and 4 byte number can be mapped to the same thing which sounds like an issue (unless you've just got the small end of it?)
Maybe if you just change both it'll work.


As a footnote I might add that going too far in either direction will lead to all areas acting like BSoD

This is something to keep in mind. 4 bytes gives us 4,294,967,295 possible values for each coordinate which is way too many. That takes too long to measure, too long to travel to manually and the game isn't stable enough it sounds like, so the search should probably be restricted… though hey if your method of virtually traveling doesn't suffer from instability maybe it'd be interesting to measure anyway? It'll take forever though.