PHO - Pokémon Hackers Online
Go Back   PHO - Pokémon Hackers Online > Discussion Board > Archive


Archive Old threads that serve no purpose are here.

Thread Tools Display Modes
Old 14th December 2013, 02:57 AM   #1
Shiny Quagsire
Super Awesome Ninja ASM Guy
Shiny Quagsire's Avatar
Join Date: Apr 2010
Age: 21
Posts: 62
Shiny Quagsire
Default Custom Title Screen Written in C

So the other day I was on the IRC and I had the inspiration after finishing the Crystal Intro that it'd be cool to replace the title screen too. At the time it was just a small tease, a hypothetical idea, but a month later I had the desire to go and implement this idea, and this is what I created:

When I was first making this title screen I started by finding the callback associated with the title screen. Once I found it, I discovered that when replacing the existing pointer with the pointer to my custom intro, it would actually go to my intro upon triggering the intro to title screen change (which effectively made my intro loop forever at the time). Since it worked without problems, I got out my Intro Template and began making modifications to create a custom title screen.

A few notes about this hack:
  • Since it modifies the game engine code, it is not reliant on my custom intro, meaning that it plays nice with both the original intro as well as my custom intro.
  • It works seamlessly within the game and properly goes to the Continue, New Game menu
  • The Berry Update and Save Delete menus are properly implemented with the same shortcut keys as before, making it have no disadvantages when compared to the original title screen (while giving it several advantages)

Since I already detailed how I hacked the GameFreak intro using callbacks, I'm going to leave that out and start with how the title screen works.

Basically, our title screen runs in steps. We start by loading all of our resources and setting things up in this clippet of code:
if(init[27] == 0)
Here we use init[27] as a sort of step counter, which is increased in initTitle(). We then kill the previous song from the intro and start to play ours while unfading the screen.

Over the next few steps I modified BG0VOFF to bring in the Skitty and Wailord from the bottom of the screen where they were tucked away:
else if(init[27] == 2)
		if(VAR[4] == 1)
			VAR[5] = VAR[5] + 3;
			VAR[4] = 0;
			VAR[5] = VAR[5] + 2;
			VAR[4] = 1;
		if(VAR[5] == 0 || VAR[5] > 0x1FF)
			VAR[5] = 0;
			init[27] = 3;
			TIMER[0] = 0;
The code here is a bit messy, but it's mostly due in part to the fact that we cannot use variables. To simplify, VAR[4] toggles on and off to increase VAR[5] by either 2 or 3. VAR[5] is then read and written to BG0VOFF to move the Skitty up from the screen. Once it has moved all the way (or too far) we reset it to 0 and begin the next steps to moving the logo, which is the same except it uses BG2Y since we're in mode 1.

Once everything is settled in we start spawning our OAMs into Game Freak's OAM system. All of the OAM info is located within the same file as the sprites that go with the OAM. Since the OAM system is quite complicated, I'll keep it a bit more simple. If you're interested in seeing how the OAM system works you can check out knizz's OAM-system Research Thread.

void spawnFlavor()
	int x = (240 / 2) - (64 / 2);
	int y = 70;
	int i = spawnOamFromUnk(&flavorTemplate,x,y,0x0);
	OAMBuffer[i].oam.tileProPal = 0;
	i = spawnOamFromUnk(&flavor2Template,x+64,y,0x0);
	OAMBuffer[i].oam.tileProPal = 0;
This code (located in titlescreen.c) spawns the OAMs for the "Hot Skitty on Wailord Edition". Each is a 64x32 OAM layed out to a 128x32 sprite. This function spawns each half in the center of the screen and changes it's palette to use palette 0.

After spawning the bottom text and flavor, we then begin the looping of our routine, making skitty's eyes glow while also spawning particles that float up the screen.
	else if(init[27] >= 6)
		if(random(3) == 2)
		if(!isFading() && VAR[0] < 0x20)
In this code, we create a random condition that will spawn a particle on a 1/3 chance, which gives us a good amount of particles while also not flooding the screen. I should note that since GameFreak's system has a lot of extra data, only 64 out of the 128 possible OAMs are able to be used, which is quite limiting in some aspects.

In the moveUp() function we have the logic that will move our particles. One of the small details in the video that you may or may not have noticed is that there are actually 2 types of particles. The fast animating ones that scroll up quickly and the large dots that scroll up slower, giving it a 32-ish view of the particles. To do this, we assign each particle at random a type by not only setting it's animation data but also the derp1 property to either 1 or 0. Since this property is unused we can store data in it.
void moveUp()
	if(VAR[14] == 0xFFFF) //Make sure we don't start scrolling until all of our text and stuff is there.
	for(int i = VAR[14]; i < 0x3F; i++)
		if(OAMBuffer[i].derp1 == 1)
			OAMBuffer[i].pos1.y -= 2;
			OAMBuffer[i].pos1.y -= 1;
		if((int)OAMBuffer[i].pos1.y > 0x160 || (int)OAMBuffer[i].pos1.y < 0)
To make this system a bit more flexible, we assign VAR[14] to the last OAM from the text and previous OAMs, which gives us the range of OAMs we actually want to scroll. Faster particles move in increments of 2 while the others move in increments of 1. If our particle leaves the screen, we delete it.

Now the pulseEyes() method is a bit more complicated. To do this, we increase and decrease skitty's eye palette by 0x1 every 6 frames. In addition to this, we also pause for 20 frames after it goes completely dark or bright so that it isn't just pure oscillation.

Once we have reached the main loop, we start to allow key input. If the users press A or Start, we lock that input, play the cries, and fade out into the next menu. However, if the player presses B and Select at the same time, this code is executed:
else if(keyDown(KEY_SELECT) && keyDown(KEY_B))
			int (*func)(void) = (int (*)(void))0x080796CD; //Save Delete
			int (*func)(void) = (int (*)(void))0x080796E9; //Berry Update
This basically allows us to keep the old functions from the previous title screen in case the game is loaded onto a flash cartridge and used to fix the RS berry glitch or they need to delete their save data. It was also cool to add in there. :P

Just as a last note, I think there's still some things that can be improved on with this system while also giving some key advantages. Since we have the entire code, it is possible to change anything with the title screen we want. However, this also means that it is prone to bugs and other oddities. For the full source code, you can download it and contribute back to it on my GitHub. If you have any questions, feel free to comment on this thread or PM me. And don't forget that since this is released under GPLv3 any hacks that use it are required to open-source any modifications done to it.

My Works:

Coming Soon/Working On:
  • Pokemon Amethyst
  • ?Using HMs via Items?
  • Custom GUIs using ASM (and soon) C

Shiny Quagsire is offline  
Sponsored Links

custom, screen, title, written, [Document]

Thread Tools
Display Modes

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. The time now is 03:23 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc. User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.
Feedback Buttons provided by Advanced Post Thanks / Like (Lite) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.
Pokémon characters and images belong to Pokémon USA, Inc. and Nintendo.
Pokémon Hackers Online (PHO) is in no way affiliated with or endorsed by Nintendo LLC, Creatures, GAMEFREAK inc,
The Pokémon Company, Pokémon USA, Inc., The Pokémon Company International, or Wizards of the Coast.
All forum/site content (unless noted otherwise) and site designs are © 2006-2013 Pokémon Hackers Online (PHO).
Green Charizard Christos TreeckoLv100

"Black 2" by ARTPOP. Kyurem artwork by XOUS.

no new posts