Register - Login
Views: 95816474
Main - Memberlist - Active users - Calendar - Wiki - IRC Chat - Online users
Ranks - Rules/FAQ - Stats - Latest Posts - Color Chart - Smilies
11-20-18 06:23:01 AM

Jul - General Game/ROM Hacking - Pokémon Generation V Orthographic Maps New poll - New thread - New reply
Next newer thread | Next older thread
GuyPerfect
Catgirl
Level: 65


Posts: 813/1094
EXP: 2327529
For next: 8099

Since: 07-23-07


Since last post: 218 days
Last activity: 103 days

Posted on 07-08-13 01:26:42 PM Link | Quote
A bit of a departure from the regular ROM hacking, this one is an emulator hack!

As of Pokémon Diamond and Pearl on Nintendo DS, the games have ventured into the realm of 3D graphics, which makes maps somewhat difficult to construct. Fortunately, all of the Generation IV games have a camera mode built-in that will use a "2D" orhtographic projection that's great for maps (it's used inside buildings). A little Action Replay code and you can use that camera mode anywhere. The Generation V games, on the other hand, I'm not sure there's even code in the camera system to do it.

But to make maps anyway, it's necessary to get the games into an orthographic projection in some form or another. What I wound up doing was just tweaking an emulator to always use a particular projection matrix. It's not fancy, but it gets the job done.

In the DeSmuME source code, gfx3d.cpp, is the following function:
static BOOL gfx3d_glLoadMatrix4x4(s32 v)

{
mtxCurrent[mode][ML4x4ind] = v;

++ML4x4ind;
if(ML4x4ind16) return FALSE;
ML4x4ind = 0;

GFX_DELAY(19);

//vector_fix2float<4>(mtxCurrent[mode], 4096.f);

if (mode == 2)
MatrixCopy (mtxCurrent[1], mtxCurrent[2]);

//printf("load4x4: matrix %d to: \n",mode); MatrixPrint(mtxCurrent[1]);
return TRUE;
}

This handles the assignment of transformation matrix values in the 3D subsystem. To set a matrix on DS, you first specify the matrix mode, then write 16 values (one at a time) to define the matrix. The values are sent in column-major order.

For this function in particular, mode specifies the matrix mode (the projection matrix is mode 0 in DeSmuME), and ML4x4ind is the current write index within a 16-element array for storing the values. Thanks to this convenient organization, it's a simple matter to inject a custom projection matrix into the code. So we can replace that first line with this:
	static s32 fudge[16] = {

0x00000025, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000032, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xFFFFFFFC, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00001000
};

mtxCurrent[mode][ML4x4ind] = mode ? v : fudge[ML4x4ind];

DS matrix values are 20.12 fixed-point, two's complement. These particular values specify an orthographic projection such that the player character is of identical size and position as in the default perspective projection of the games.

The result is a world view that works just dandy for maps:



This works for all four Generation V games: Black, White, Black 2 and White 2.
Xkeeper

Level: 250


Posts: 21022/24696
EXP: 250258151
For next: 270860

Since: 07-03-07

Pronouns: they/them, she/her, etc.

Since last post: 17 hours
Last activity: 3 hours

Posted on 07-08-13 01:29:40 PM Link | Quote
What's probably most interesting is that the window isn't attached to the wall, but floating a bit off of it.
Xkeeper

Level: 250


Posts: 21023/24696
EXP: 250258151
For next: 270860

Since: 07-03-07

Pronouns: they/them, she/her, etc.

Since last post: 17 hours
Last activity: 3 hours

Posted on 07-08-13 01:34:30 PM Link | Quote
I suppose a good question is, do you have a downloadable version of this? I also wonder what happens if you use this sort of thing on a different game...
andlabs
Member
Level: 35


Posts: 72/290
EXP: 277982
For next: 1954

Since: 03-18-10

From: United States

Since last post: 70 days
Last activity: 7 days

Posted on 07-08-13 01:42:32 PM Link | Quote
Maybe this could be made into some extension in the next version of DeSmuME, such as in the Tools menu? I imagine being able to modify the projection in real time like that would be very handy to homebrew development in any case...

How easy would it be to adjust the matrix to rotate the room at 90 degree angles, which I think would make map editing somewhat easier? Does the code you say exists in the Gen IV games let you do that? (I haven't played either Gen IV or V yet, sorry... I have a 3DS now, though, so)
GuyPerfect
Catgirl
Level: 65


Posts: 814/1094
EXP: 2327529
For next: 8099

Since: 07-23-07


Since last post: 218 days
Last activity: 103 days

Posted on 07-08-13 01:56:02 PM Link | Quote
Originally posted by Xkeeper
I suppose a good question is, do you have a downloadable version of this?

Yeah, I've got a build ready that I've been using for maps, but I don't want to host it off of my apartment internet. Gimme a few minutes to set up a web server so I can get the file to you. Maybe you could attach it to a post in this thread or something.

Originally posted by andlabs
How easy would it be to adjust the matrix to rotate the room at 90 degree angles, which I think would make map editing somewhat easier? Does the code you say exists in the Gen IV games let you do that?

All of the DS games have a simple camera system where the camera has a position and an angle, and follows the player. It should be simple enough to modify those values in memory. I know someone already put together a button-controlled camera code for Black and White, so it's definitely an option. Not sure how well it'd work for maps, though.
GuyPerfect
Catgirl
Level: 65


Posts: 815/1094
EXP: 2327529
For next: 8099

Since: 07-23-07


Since last post: 218 days
Last activity: 103 days

Posted on 07-08-13 03:21:34 PM (last edited by GuyPerfect at 07-08-13 04:21:00 PM) Link | Quote
A'ight, Xkeeper was kind enough to re-host the file: http://xkeeper.net/private/DeSmuME_0.9.9_PokeOrtho.zip

This is a standard release build of DeSmuME 0.9.9, with a forced projection matrix configured for the Generation V Pokémon games. Should you want to edit the matrix values, they're located in the EXE file at address 0x48F840. You can learn more about how to calculate projection matrices here:

gluPerspective()
glOrtho()

Converting numbers into the DS matrix format is easy: multiply by 4096, then round to the nearest integer, then store as a 32-bit int.

In DeSmuME, if you click Tools->View Matrices, you can examine the current values for each matrix mode. Here's a sample taken from Pokémon White:



That was calculated in-game using the standard perspective formula. If you examine it, you'll notice something is amiss: the constant -1 is at row 3 column 4, whereas it should be at row 4 column 3. The View Matrices window in DeSmuME naïvely lists the values as though they were row-major, when really they're supposed to be column-major. What you see as the topmost row should actually be the leftmost column, etc.

There's some rounding going on due to the DS's lack of true floating-point arithmetic, but the values used by the game were most likely as follows: fovy = 40 degrees, zNear = 1, zFar = 1000. To produce the orthographic projection matrix in this hack, I used the standard orthographic formula with the following values: right/left = ±110, top/bottom = ±82.5, farVal/nearVal = ±1000.

That oughtta be enough information to get started making your own matrices, I would think. This method should work great for other, similar games, not just Pokémon. However, do expect to see a few artifacts here and there from where the games aren't expecting the projection to be orthographic.

EDIT:
Oh yeah, I forgot. The aspect ratio is the aspect ratio of the screen itself, which is 256x192 pixels. Just divide width by height to get 1.33333...

EDIT2:
Yeah, using an aspect ratio of 1.33315 and rounding to 4 digits after the decimal point, my perspective matrix was identical to the one DeSmuME showed.
Xenesis
Actually a Doctor
Level: 94


Posts: 2063/2543
EXP: 8244435
For next: 112222

Since: 07-28-07

Pronouns: he/him
From: The Land of Kangaroos and Drop Bears

Since last post: 15 days
Last activity: 4 hours

Posted on 07-12-13 12:23:06 AM Link | Quote
So legitimately curious, how simple would it be to do this at a game level instead of an emulator level?

Are the memory addresses used to control this common across games?

(No issue if it involves rewriting the game's assembly, I'd just be interested in how it's actually controlled)
GuyPerfect
Catgirl
Level: 65


Posts: 816/1094
EXP: 2327529
For next: 8099

Since: 07-23-07


Since last post: 218 days
Last activity: 103 days

Posted on 07-12-13 07:45:39 PM Link | Quote
The values are written to the 3D subsystem's matrix memory by the program, so they'll always be set by the same addresses. See here: http://nocash.emubase.de/gbatek.htm#ds3dmatrixloadmultiply.

More specifically, write 0 to 0x04000440 to specify projection matrix mode, then 16 writes to 0x04000458 for each value in the 4x4 projection matrix (column-major). I'm not sure of the feasibility of doing it with an Action Replay, since I'm not sure it can reliably inject custom matrix values during frame rendering, but any game should be simple enough to override the default projection handler if you can pin it down.

That's another thing DS emulators need. Memory access breakpoints.
Xenesis
Actually a Doctor
Level: 94


Posts: 2064/2543
EXP: 8244435
For next: 112222

Since: 07-28-07

Pronouns: he/him
From: The Land of Kangaroos and Drop Bears

Since last post: 15 days
Last activity: 4 hours

Posted on 07-14-13 01:52:46 PM Link | Quote
Well, no$gba does memory access breakpoints for NDS.

Although it's ability as an NDS emulator can be questionable at best.

But thanks for the offsets, that looks exactly like what I need!
Rena

Star Mario
Fennel
Level: 129


Posts: 5049/5258
EXP: 24528470
For next: 521184

Since: 07-22-07

Pronouns: he/him/whatever
From: RSP Segment 6

Since last post: 27 days
Last activity: 16 days

Posted on 07-26-13 12:32:42 AM Link | Quote
This looks a lot like Dolphin's "free look" function (allows you to move the camera with the mouse, overriding the game's positioning). Any chance it could evolve into something like that?
Next newer thread | Next older thread
Jul - General Game/ROM Hacking - Pokémon Generation V Orthographic Maps New poll - New thread - New reply




Rusted Logic

Acmlmboard - commit 220d144 [2018-11-04]
©2000-2018 Acmlm, Xkeeper, Inuyasha, et al.

28 database queries, 3 query cache hits.
Query execution time: 0.166707 seconds
Script execution time: 0.020416 seconds
Total render time: 0.187123 seconds