The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking
Reload this Page ASM & Hex Creating a new day/night system (using colour filters in Fire Red)

Notices
For all updates, view the main page.

Binary ROM Hacking Need a helping hand or just want to talk about binary ROM hacks? Get comments and answers to any ROM Hacking-related problems, questions or thoughts you have here.

Ad Content
Reply
 
Thread Tools
  #1   Link to this post, but load the entire thread.  
Old February 2nd, 2017 (2:39 PM).
kobold kobold is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 13
Hi folks,

I'm looking to develop my own day/night system that checks a statusbyte and applies a coloured filter depending on the time of day. This is how the widely used DNS tool works.

I can't work out how to tint the screen colour on Fire Red using ASM at all though, despite looking through the IDB, checking how the DNS tool itself works etc. Could anyone here help me understand how to apply a filter to the screen?

Thank you!
Reply With Quote
  #2   Link to this post, but load the entire thread.  
Old February 13th, 2017 (6:13 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by kobold View Post
Hi folks,

I'm looking to develop my own day/night system that checks a statusbyte and applies a coloured filter depending on the time of day. This is how the widely used DNS tool works.

I can't work out how to tint the screen colour on Fire Red using ASM at all though, despite looking through the IDB, checking how the DNS tool itself works etc. Could anyone here help me understand how to apply a filter to the screen?

Thank you!
The existing tint functions only get applied to the palette when the palette is initially loaded, which doesn't really help if you want the palette to change over time (you'll only notice a change when the map is refreshed).

What you need to do is make a function that acts similarly to the function that applies the built-in tints (load_palette_3) but instead make it run every frame. Basically this means you must loop through all the colours in the in-memory palette copy (palette_bg_unfaded and palette_obj_unfaded) and apply your filter to each colour. The engine will take care of copying these colours to palette RAM (in the vblank handler).

Once you have written this function to modify the palette, you can make it get called every frame by hooking into c1_overworld_normal (just before it returns) and adding a call to your function.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
Reply With Quote
  #3   Link to this post, but load the entire thread.  
Old February 14th, 2017 (6:34 PM).
Deokishisu's Avatar
Deokishisu Deokishisu is offline
Mr. Magius
 
Join Date: Feb 2006
Location: If I'm online, it's a safe bet I'm at a computer.
Gender: Male
Nature: Relaxed
Posts: 984
Quote:
Originally Posted by Touched View Post
What you need to do is make a function that acts similarly to the function that applies the built-in tints (load_palette_3) but instead make it run every frame. Basically this means you must loop through all the colours in the in-memory palette copy (palette_bg_unfaded and palette_obj_unfaded) and apply your filter to each colour. The engine will take care of copying these colours to palette RAM (in the vblank handler).

Once you have written this function to modify the palette, you can make it get called every frame by hooking into c1_overworld_normal (just before it returns) and adding a call to your function.
Related but unrelated, can we use the built-in tint functionality to overwrite (instead of tint) specific colors in a palette when (re)loaded with a minor rewrite? Or would the palette be overwritten by GameFreak's engine on the next VBlank, requiring a different approach? I know that messing with palettes can be tricky because of how GameFreak handles them.
Reply With Quote
  #4   Link to this post, but load the entire thread.  
Old February 15th, 2017 (12:09 PM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by Deokishisu View Post
Related but unrelated, can we use the built-in tint functionality to overwrite (instead of tint) specific colors in a palette when (re)loaded with a minor rewrite? Or would the palette be overwritten by GameFreak's engine on the next VBlank, requiring a different approach? I know that messing with palettes can be tricky because of how GameFreak handles them.
Yes you can do that. It will not be overwritten on vblank because it's (palette_xxx_unfaded) a copy of the palette memory in EWRAM, not in Palette RAM . The only way it will be overwritten is if there is another routine that gets run later that writes to the same buffer.

Basically, GameFreak handled the palettes by having two buffers in EWRAM: palette_xxx_unfaded and palette_xxx_faded. The palette_xxx_unfaded is the working buffer and this is where everything loads palettes into. Near the end of a callback, the function 080704D0 (fade_and_return_progress_probably) is usually called. This handles the fadescreen-like commands and will fade every colour in palette_xxx_unfaded to a given fade colour (usually black or white, but it can be any colour). This faded copy gets written to palette_xxx_faded. Finally, when the vblank handler is called this usually calls the function 08070474 (gpu_pal_upload). This function copies the palette_xxx_faded buffer to palette RAM (and applies handles some specialised palette fading cases with the built-in IO register-controlled blending).

In case you're wondering, this practice of maintaining a buffer for palettes, tilemaps, etc. is quite common (and actually is the recommended approach). It's called double buffering, where a working buffer is used to write images during the frame and then swapped with an active buffer (copied to) during vblank so that the display never shows the buffer being worked on and thus causing screen tearing. Therefore, as long as you write to the working buffer and not directly to Pallete RAM/VRAM/whereever you should be good. It's just an issue of reading the code and figuring out where that buffer is.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
Reply With Quote
  #5   Link to this post, but load the entire thread.  
Old February 15th, 2017 (12:19 PM).
kobold kobold is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 13
Quote:
Originally Posted by Touched View Post
The existing tint functions only get applied to the palette when the palette is initially loaded, which doesn't really help if you want the palette to change over time (you'll only notice a change when the map is refreshed).

What you need to do is make a function that acts similarly to the function that applies the built-in tints (load_palette_3) but instead make it run every frame. Basically this means you must loop through all the colours in the in-memory palette copy (palette_bg_unfaded and palette_obj_unfaded) and apply your filter to each colour. The engine will take care of copying these colours to palette RAM (in the vblank handler).

Once you have written this function to modify the palette, you can make it get called every frame by hooking into c1_overworld_normal (just before it returns) and adding a call to your function.
Alright, thanks. So this function causes the palettes to reload whenever it is run? As for running it every frame, there is a frame counter in the game time update function at 05487C - would I be able to hook into the function and run it like that?
Reply With Quote
  #6   Link to this post, but load the entire thread.  
Old February 15th, 2017 (12:53 PM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by kobold View Post
Alright, thanks. So this function causes the palettes to reload whenever it is run? As for running it every frame, there is a frame counter in the game time update function at 05487C - would I be able to hook into the function and run it like that?
No, the palettes are loaded from that buffer every frame. You just need to write a function to write to that buffer every frame, by hooking into a function.

You don't want to hook into the main loop (i.e., at 05487C), because you only want D/N to work on the overworld. If you hooked there it would apply that to the titlescreen, intro, battles, pokedex and all that which is obviously not good. Use c1_overworld_normal - it's called every frame when you're on the overworld.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
Reply With Quote
Reply

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content

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 -8. The time now is 9:23 AM.