Shiny Quagsire

I'm Still Alive, Elsewhere

Age 22
Male
Hoenn Safari Zone
Seen 10 Hours Ago
Posted April 17th, 2017
700 posts
11.2 Years
Greets once again,

If case the thread title was too confusing, basically what this does is it will initiate the overworld from any code point in the game (ie an intro sequence or the likes) and allow you to manipulate the camera. An example of a good use for this would be something like the flying overworld camera as seen in the credits sequence for Fire Red. That is basically what this is. Combined with the proper overworld loading functions and a few small RAM edits, I created a small C file which can be included and used for various things. I actually originally made it due to me being on GoGo's IRC and him mentioning that he would have needed something like this, and luckily I happened to be bored and curious enough to actually do it. That being said, the implementation:

#define mapMem				((u8 *)(*(u32*)0x03005008))
#define saveX				(*(u16 *)(*(u32*)0x03005008))
#define saveY				(*(u16 *)((*(u32*)0x03005008)+2))
#define mem 				(*(u32*)0x020370FC)		
#define mapLoadingState     ((u8 *)0x03003528)

#define mapAx				(*(u16*)(mem))
#define mapAy				(*(u16*)(mem+2))

#define mapxVel				(*(u32*)(mem+8))
#define mapyVel				(*(u32*)(mem+12))

#define mapX 				(*(u16*)(*(u32*)0x03005008))
#define mapY 				(*(u16*)((*(u32*)0x03005008)+2))

#define playerNPCID			(*(u8*)0x0203707D)

void initMap(u8 bank, u8 map, u8 x, u8 y)
{
	//if(mem != 0)
		//free(mem);
	mem = 0x020D0000;//Overriding here because malloc apparently can't actually give me a non-allocated area .-. //malloc(0x2000);
	(*(u8*)0x0203ADFA) = 3; //Disables map sign thingies on entry. Also gives some nice letterboxing bars if set to 2
	flag_set_(0x4001); //Disable map music change on map change
	(*(u32*)0x03005020) = 0x08059B8F; //Disable initial map music

	mapMem[4] = bank;
	mapMem[5] = map;
	saveX = x;
	saveY = y;

	doMapLoad();
	(*(u32*)0x03005050) = 0;
	(*(u16*)0x03000FC0) = 327; //Map music
}

void setMapXVel(u32 vel)
{
	mapxVel = vel;
}

void setMapYVel(u32 vel)
{
	mapyVel = vel;
}

void doMapLoad()
{
	mapLoadingState[0] = 0;
	int (*mapLoadLoop)(u32) = (int (*)(void))0x08056E5C+1;
	mapLoadLoop(0x03003528);
}

void updateMapRenderer()
{
	moveCam();
	doTheThing();
}

void fullRerender()
{
	int (*drawMap)(void) = (int (*)(void))0x0805A684+1;
	drawMap();
}


void moveCam()
{
	int (*updateCam)(void) = (int (*)(void))0x0805ABB0+1;

	mapAx = mapAx + mapxVel*2;
	mapAy = mapAy + mapyVel*2;
	(*(u32*)0x03005058) = mapxVel;
	(*(u32*)0x0300505C) = mapyVel;

	updateCam();

	init[0] = init[0] + 1;
}

void doTheThing()
{
	coro_del_(coro_getid_(0x0806E83C+1)); //Prevents random wild cries
	npc_hide_(0x02036E38+(((playerNPCID << 3) + playerNPCID) << 2));
	(*(u32*)0x03005020) = 0x08059B8F; //Disable initial map music
	int (*func2)(void) = (int (*)(void))0x0805ABB0+1;
	int (*func3)(void) = (int (*)(void))0x08115798+1;
	int (*adjustOverworlds)(void) = (int (*)(void))0x0805AE28+1;
	int (*func7)(void) = (int (*)(void))0x0806FFBC+1;
	int (*func8)(void) = (int (*)(void))0x080F67B8+1;
	int (*updateAnimsandOWs)(void) = (int (*)(void))0x08056A04+1;

		int (*copyPalToDMA)(void) = (int (*)(void))0x08070474+1;
		copyPalToDMA();

	func2();
	func3();
	adjustOverworlds();
	func7();
	func8();
	updateAnimsandOWs();
}

void coro_del_(int *addr)
{
	int (*func)(u32) = (int (*)(void))0x08077508+1;
	func(addr);
}

int coro_getid_(int *addr)
{
	int (*func)(u32) = (int (*)(void))0x08077688+1;
	return func(addr);
}

int npc_hide_(int *addr)
{
	int (*func)(u32) = (int (*)(void))0x0805E4B4+1;
	return func(addr);
}

void flag_set_(int *flag)
{
	int (*func)(u32) = (int (*)(void))0x0806E680+1;
	return func(flag);
}
The basic usage involves 4 functions: initMap, updateMapRenderer, setMapXVel and setMapYVel. To demo this I made a small C file based on one of my older intros, and later stripped of the unneeded functions. The basic usage, however, is done as such. One time on load, call initMap. On every frame in which you want to update the overworld, call updateMapRenderer. To adjust the camera, use setMapXVel and setMapYVel. In my case, I just bound the d-pad to create a sort of floating map viewer:


In the video you'll notice a few things. First, tile animations and overworlds work and function as proper. However they'll sometimes disappear off the camera due to some odd offsetting of the camera on occasion which occurs mostly when the velocities are not done at a proper pace like walking or biking (in this case it happened to be me rapidly pulsating left and right to the song). This also causes some issues with the scrolling as seen on the edges of the screen on occasion, and at the moment there isn't really a fix for this since it's purely an issue if how the camera was implemented in this example and in the engine. Luckily however this is a non-issue if you are properly manipulating the camera in code at a constant velocity.

As usual, the full source for this demo can be found at my Github (link below). I'm also including a patch for this demo in the event that anyone wants to explore or whatever (routine patches over the 0x790000 area). Controls are fairly simple. D-pad to move, B to redraw the map (if it gets weird looking). A and Start go to the titlescreen.
https://github.com/shinyquagsire23/FR-Overworld
Male
Manassas
Seen 2 Weeks Ago
Posted May 23rd, 2015
43 posts
6.2 Years
Although I don't have a use for this personally, I'm pretty sure that others can find a use for this, mainly for Machinama, or their ROM-Hacks. Still, neat to see though :P.
This signature has been disabled.
spoilers are not allowed in signatures
Please review and fix the issues by reading the signature rules.

You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.

Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.

Deokishisu

Mr. Magius

Male
If I'm online, it's a safe bet I'm at a computer.
Seen March 15th, 2020
Posted March 4th, 2018
859 posts
14.5 Years
If you could force the screen to scroll at a certain speed and change directions at pre-determined points, you could also do some sort of scrolling mosaic/painting/mural/whatever to do some backstory on your region or the mascot of your hack or whatever by making that a map.

My thought was that it would be similar to how the backstory is explained in the second Monster Rancher game for the original PS1, it was basically an animated scrolling mural that explained how monsters came about.
For ROMHackers, PokeCommunity is dead after the scandal. If you enjoy the ROMHacking scene, come with the rest of us to Silph Co. It is a forum by ROMHackers, for ROMHackers. None of the bloat of PC, and staff that knows what our subset of the community needs.

Shiny Quagsire

I'm Still Alive, Elsewhere

Age 22
Male
Hoenn Safari Zone
Seen 10 Hours Ago
Posted April 17th, 2017
700 posts
11.2 Years
Wow, this is something. I believe this is going to be extremely useful for credits, cutscenes and the likes. Now, if we could load pictures directly with their tilemaps onto the OW with a script... that would be something. Just saying, this may be the start of something extraordinary here.
Definitely possible, BG0 is completely free along with the usual text palettes (although they get loaded along with the map, but they can be overwritten safely as long as you don't plan on using textboxes).
Male
Seen July 20th, 2019
Posted July 25th, 2014
1 posts
6.1 Years
This is awesome. I have been looking for a way to get something like this done, but in a cut-scene with text boxes and pre determined sprite events, and it replaces the professor oak's intro sequence.
The game starts normally after the cut-scene event. The cut-scene event however only plays out when you start a new game. Is there already a way to do this? I dont think its impossible.

GoGoJJTech

(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)

Age 21
Female
Earth
Seen December 9th, 2016
Posted December 5th, 2016
2,473 posts
7.8 Years
Didn't realize you posted this lol
Remember to have an uninitMap for C projects, which should be:

void uninitMap()
{
(*(u32*)0x030030FC) = 0x080EC5A4+1;
}
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