Since Gen 5, the current weather gets displayed during battles on the bottom screen. This tutorial will explain how to do so in Gen 2, more specifically, during move selection. It works by creating a sprite for the weather icon, so you'll also learn how to work with sprite graphics on the Game Boy Color. ## Add the code to display the sprites Edit [engine/battle/core.asm](../blob/master/engine/battle/core.asm) ```diff BattleTurn: ... .skip_iteration call ParsePlayerAction + push af + call ClearSprites + pop af jr nz, .loop1 ``` ```diff MoveSelectionScreen: ... .battle_player_moves call MoveInfoBox + call GetWeatherImage ld a, [wMoveSwapBuffer] ... .place_textbox_start_over + push hl + call ClearSprites + pop hl call StdBattleTextbox ``` There's not much to explain here. These changes are just to clear the sprite when we dont need it and to add the call function to the code below. Add this function to [engine/battle/core.asm](../blob/master/engine/battle/core.asm) ``` GetWeatherImage: ld a, [wBattleWeather] and a ret z cp WEATHER_RAIN ld de, RainWeatherImage lb bc, PAL_BATTLE_OB_BLUE, 4 jr z, .done cp WEATHER_SUN ld de, SunWeatherImage ld b, PAL_BATTLE_OB_YELLOW jr z, .done cp WEATHER_SANDSTORM ld de, SandstormWeatherImage ld b, PAL_BATTLE_OB_BROWN jr z, .done ret .done push bc ld b, BANK(WeatherImages) ; c = 4 ld hl, vTiles0 call Request2bpp pop bc ld hl, wVirtualOAMSprite00 ld de, .WeatherImageOAMData .loop ld a, [de] inc de ld [hli], a ld a, [de] inc de ld [hli], a dec c ld a, c ld [hli], a ld a, b ld [hli], a jr nz, .loop ret .WeatherImageOAMData ; positions are backwards since ; we load them in reverse order db $88, $1c ; y/x - bottom right db $88, $14 ; y/x - bottom left db $80, $1c ; y/x - top right db $80, $14 ; y/x - top left ``` Request2bpp is an important function. It grabs the image from ROM and places it where you want, usually VRAM. The description of it is kind of weird, but basically `b` is the bank that the image resides, `de` is the address that the image resides, `hl` is where you want to copy it to, and `c` is how many tiles to copy. If you're wanting to make an image a sprite, `wVirtualOAM` is where you want to go. You don't want to write directly to OAM because that would require specific timings that wouldn't be available all of the time. So, you must load the OAM data into `wVirtualOAM`. Every so often, many times per second actually, the game loads whatever is in `wVirtualOAM` into the actual OAM, when those timings I mentioned are available. OAM data works like this, each sprite is an 8x8 tile just like the background or map tiles, but they can be put anywhere on the screen. Each sprite uses 4 bytes in this order, Y position, X position, Tile number, Attributes. Look [here](http://gbdev.gg8.se/wiki/articles/Video_Display#VRAM_Sprite_Attribute_Table_.28OAM.29) for a better description of the OAM structure. ## Add the graphics Add these graphics to gfx/battle/weather ![rain.png](screenshots/rain_icon.png ![sun.png](screenshots/sun_icon.png ![sandstorm.png](screenshots/sandstorm_icon.png Creat a new file called weather_images.asm in gfx/ ```WeatherImages:: RainWeatherImage: INCBIN "gfx/battle/weather/rain.2bpp" SunWeatherImage: INCBIN "gfx/battle/weather/sun.2bpp" SandstormWeatherImage: INCBIN "gfx/battle/weather/sand.2bpp" ``` Add this section to [main.asm](../blob/master/main.asm) ``` SECTION "Battle Weather Images", ROMX INCLUDE "gfx/weather_images.asm" ``` RGBDS will add this section to any free space in a bank unless you add `"Battle WeatherImages"` to [pokecrystal.link](../blob/master/pokecrystal.link). ## Optimize the code Now, if you plan on not adding any new weather effects or weather icons, optimization is straightforward. Otherwise, there's some tricks you can use to keep the code optimized. A quick and easy optimzation is to replace the `cp WEATHER_X` in GetWeatherImage to `dec a` like so. ```diff GetWeatherImage: ld a, [wBattleWeather] and a ret z - cp WEATHER_RAIN + dec a ld de, RainWeatherImage lb bc, PAL_BATTLE_OB_BLUE, 4 jr z, .done - cp WEATHER_SUN + dec a ld de, SunWeatherImage ld b, PAL_BATTLE_OB_YELLOW jr z, .done - cp WEATHER_SANDSTORM + dec a ld de, SandstormWeatherImage ld b, PAL_BATTLE_OB_BROWN jr z, .done ret ``` You can do that because WEATHER_RAIN = 0 + 1, WEATHER_SUN = WEATHER_RAIN + 1, and WEATHER_SANDSTORM = WEATHER_SUN + 1. That format can be continued to be used if whatever new weather effects equal one more than the last. ## Addendum Here is a pre-made graphic for Hail made by Bronzeswagger if you decide to add Hail to your hack. ![hail.png](screenshots/hail_icon.png)