This commit is contained in:
Bivurnum 2026-03-21 06:07:46 -07:00 committed by GitHub
commit 67b393804b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 759 additions and 123 deletions

View File

@ -2691,6 +2691,11 @@
.byte \selectionType
.endm
.macro mappreview duration:req
callnative MapPreviewScript
.2byte \duration
.endm
@ Follower NPCs
@ Sets an existing NPC up to follow the player.

View File

@ -47,6 +47,7 @@
- [Struct Pokemon Generation](tutorials/mon_generation.md)
- [How to use FRLG](tutorials/how_to_frlg.md)
- [How to delete vanilla maps](tutorials/how_to_delete_vanilla_maps.md)
- [How to use Map Previews](tutorials/how_to_map_preview_screen.md)
- [Changelog](./CHANGELOG.md)
- [1.15.x]()
- [Version 1.15.0](changelogs/1.15.x/1.15.0.md)

View File

@ -0,0 +1,419 @@
# Map Preview Screen: How To
*written by Bivurnum*
![map_preview_example](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/map_preview_example.gif)
### [Click Here for a Guide to Creating a New Map Preview](#creating-a-new-map-preview-image)
## Using the Map Previews
I'll be using an example of adding a map preview to Petalburg Woods for this section.
You will need to define a new map preview screen in ***include/map_preview_screen.h***. Just add your new entry in the list in `MapPreviewScreenId`, leaving `MPS_COUNT` at the very end. Like so:
```diff
enum MapPreviewScreenId
{
MPS_VIRIDIAN_FOREST = 0u,
MPS_MT_MOON,
MPS_DIGLETTS_CAVE,
MPS_ROCK_TUNNEL,
MPS_POKEMON_TOWER,
MPS_SAFARI_ZONE,
MPS_SEAFOAM_ISLANDS,
MPS_POKEMON_MANSION,
MPS_ROCKET_HIDEOUT,
MPS_SILPH_CO,
MPS_VICTORY_ROAD,
MPS_CERULEAN_CAVE,
MPS_POWER_PLANT,
MPS_MT_EMBER,
MPS_ROCKET_WAREHOUSE,
MPS_MONEAN_CHAMBER,
MPS_DOTTED_HOLE,
MPS_BERRY_FOREST,
MPS_ICEFALL_CAVE,
MPS_LOST_CAVE,
MPS_ALTERING_CAVE,
MPS_PATTERN_BUSH,
MPS_LIPTOO_CHAMBER,
MPS_WEEPTH_CHAMBER,
MPS_TDILFORD_CHAMBER,
MPS_SCUFIB_CHAMBER,
MPS_RIXY_CHAMBER,
MPS_VIAPOIS_CHAMBER,
+ MPS_PETALBURG_WOODS,
MPS_COUNT
};
```
Then, you will go to ***src/map_preview_screen.c*** and add a new section in the `sMapPreviewScreenData` list for the map preview you just defined.
```diff
static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
[MPS_VIRIDIAN_FOREST] = {
.mapsec = MAPSEC_VIRIDIAN_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_VIRIDIAN_FOREST,
.tilesptr = sViridianForestMapPreviewTiles,
.tilemapptr = sViridianForestMapPreviewTilemap,
.palptr = sViridianForestMapPreviewPalette
},
+ [MPS_PETALBURG_WOODS] = {
+ .mapsec = MAPSEC_PETALBURG_WOODS,
+ .type = MPS_TYPE_FADE_IN,
+ .flagId = FLAG_VISITED_PETALBURG_WOODS,
+ .tilesptr = sViridianForestMapPreviewTiles,
+ .tilemapptr = sViridianForestMapPreviewTilemap,
+ .palptr = sViridianForestMapPreviewPalette
+ },
[MPS_MT_MOON] = {
.mapsec = MAPSEC_MT_MOON,
...
```
* `mapsec` is just the name of the map section your map is in. This map preview will apply to all maps within this map section (but not when traveling between maps within the same map section, similarly to the map name popups). If it doesn't have one already, the mapsec will need an entry in ***src/data/region_map/region_map_sections.json*** for the map name to show up in the map preview.
<a name="type"></a>
* `type` will be either `MPS_TYPE_BASIC`, `MPS_TYPE_FADE_IN` or `MPS_TYPE_CAVE`.
* `MPS_TYPE_BASIC` will show the map preview, then fade to black before loading into the new map.
* `MPS_TYPE_FADE_IN` will fade the map preview into the new map (see the [gif at the top of this page](#mps-fade-in-gif) for example).
* `MPS_TYPE_CAVE` will perform the warp animation for entering a cave at the end of the map preview, before the map is loaded in.
<details>
<summary><i>MPS_TYPE_BASIC example</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/ruins_of_alph_basic.gif)
</details>
<details>
<summary><i>MPS_TYPE_FADE_IN example</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/ruins_of_alph_fade.gif)
</details>
<details>
<summary><i>MPS_TYPE_CAVE example</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/ruins_of_alph_cave.gif)
</details>
* `flagId` is just the name of the flag you want to set when visiting this map for the first time. The flag state determines how long the map preview will last on screen; it gets a shorter duration if the player has been to that map before. A lot of Emerald maps already have associated flags, but Petalburg Woods does not have one by default, so I repurposed one of the unused flags for use in this example. If you don't want to use a flag, you can enter `MPS_FLAG_NULL` here and the duration will have its own custom value (this can be adjusted in the configs in ***include/map_preview_screen.h***).
* `tilesptr`, `tilemapptr`, and `palptr` are the image, tiles, and palette that you want to use for this preview. I'm just using the existing image from Viridian Forest here.
* If the image will load more than 3 16-color palettes, you should add `.usesAllPalettes = TRUE` to the entry. Otherwise the palettes won't be loaded properly. (None of the vanilla FRLG images need this.)
That's all there is to it!
### Scripting
* `mappreview` fades the screen to black, runs a map preview for the current map for the specified number of frames, then fades back from black before continuing the script. This uses the behavior of `MPS_TYPE_BASIC`, regardless of the designated type of the map.
### Configs
In the ***include/config/map_preview_screen.h*** file, there are a few configs you can customize for the map previews.
* `MPS_ENABLE_MAP_PREVIEWS` enables map previews for FRLG by default. To enable them for Emerald, change this value to `TRUE`. To disable map previews entirely, change this value to `FALSE`.
* `MPS_DURATION_LONG` determines how many frames the map preview lasts on screen the first time the player enters that map.
* `MPS_DURATION_SHORT` determines how many frames the map preview lasts on screen after the map's flag has been set.
* `MPS_DURATION_NO_FLAG` determines how many frames the map preview lasts if the flag has been set to `MPS_FLAG_NULL`.
* `MPS_BASIC_FADE_SPEED` determines how quickly the fade to black animation plays at the end of `MPS_TYPE_BASIC`. A larger value makes it fade out slower. A smaller value (even a negative number) makes it fade out faster.
### Notes
* Due to it needing the only blend register, `MPS_TYPE_FADE_IN` causes NPC shadows (`OW_OBJECT_VANILLA_SHADOWS == FALSE`) to lose their transparency while the map preview is running.
* `MPS_TYPE_FADE_IN` does not work properly if the map has any of the following weather types. (You can use `MPS_TYPE_BASIC` for the map preview instead.)
* `WEATHER_SUNNY_CLOUDS`
* `WEATHER_FOG_HORIZONTAL`
* `WEATHER_FOG_DIAGONAL`
* `WEATHER_UNDERWATER`
* `WEATHER_UNDERWATER_BUBBLES`
# Creating a New Map Preview Image
This guide will show you how to take a custom image and turn it into a map preview image. I'll be as comprehensive as I can with the relevant mechanics. I also provide example images from both Aseprite and Graphics Gale for the convenience of more users.
## Contents
* [The Image](#the-image)
* [The Tilemap](#the-tilemap)
* [The Palettes](#the-palettes)
* [Two Palette Image](#two-palette-image)
* [Fifteen Palette Image](#fifteen-palette-image)
* [Map Name Text](#map-name-text)
* [The Code](#the-code)
# The Image
I'm not much of an artist myself, so I will leave the design of the image to you. For this demonstration, I have picked out a lovely [preview image](https://bulbapedia.bulbagarden.net/wiki/Location_preview#/media/File:HGSS_Ruins_of_Alph-Day.png) from the HGSS games:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/HGSS_Ruins_of_Alph-Day.png)
The GBA display is exactly 240x160 pixels, so if your base image is larger than that you will have to crop it to fit. My image is a little too wide, so I'll have to trim it down. I also want to incorporate the cinematic black bars, like they used in the FRLG games, so I'll have to trim quite a bit off of the top and bottom as well.
I have created a template image that is an exact copy of the FRLG map preview, including the black bars and text box. You can find the image in the ***docs/tutorials/img/map_preview_screen/templates*** folder. Feel free to use it for your own previews:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/templates/map_preview_template.png)
Now I have my map preview exactly how I want it to look in game:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/alph_map_preview_image.png)
You're probably wondering why there is a big yellow bar along the right side of the image. Those extra tiles are needed because the game will load some tiles off screen. Without the yellow bar taking up that space, some of our map preview tiles would load there instead, screwing up the image. So while the GBA display is only 240x160, all map preview images must be 256x160 pixels in size. Don't worry. Those extra tiles won't show up in the game. (So you can make them whatever color you want. They don't have to be yellow.)
Finally, you need to make sure that the image is properly indexed.
<details>
<summary><i>How to index an image in Aseprite:</i></summary>
> You just need to click `Sprite`, then `Color Mode`, then make sure the `Indexed` option is checked.
>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_index_example.png)
>
> Make sure to save the image when you are done.
</details>
<details>
<summary><i>How to index an image in Graphics Gale:</i></summary>
> You need to click `All Frames`, then `Color Depth...`.
>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_color_depth.png)
>
> Because map preview images use more than one 16-color palette, you should select the `8bpp` option. Then click `OK`.
>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_8bpp.png)
>
> Make sure to save the image when you are done.
</details>
# The Tilemap
Now that we have our image, we need to covert it into a tile sheet and generate a tilemap using [Tilemap Studio](https://github.com/Rangi42/tilemap-studio/blob/master/README.md).
In Tilemap Studio, we want to use the Image to Tiles feature.
Click on `Tools`, then `Image to Tiles...`. Alternatively, you could also click on the little orange portrait icon on the far right, shown in the image below.
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_image_to_tiles.png)
This window will pop up:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/image_to_tiles_window.png)
For the `Input` and `Output` options, click where it says `No file selected` and select the proper files.
* The `Input` should be the png image you just created.
* The `Output` should be the location you want the tile sheet and tilemap files to be generated. I recommend making a new folder for your map inside of the ***graphics/map_preview*** folder and setting the `Output` there. The name of the new files can be whatever you want, but if you want to match what is used for the vanilla map previews, I recommend setting the name to "tiles".
If you want, you can check the box that says `Avoid extra blank tiles at the end`. That will make the tile sheet only contain tiles that are used in the image, saving a tiny bit of space. However, it is not strictly necessary and I will not be using it in this example. Just keep in mind that it might alter the dimensions of the tiles image to be different than my example, but it will still work properly. Leaving it unchecked might just include a handful of blank tiles at the bottom of the image. No big deal.
The Tilemap `Format` should be set to `GBA tiles + 4bpp palettes`.
Check the box for `Blank tiles use ID` and set its value to `000`.
The Palette `Format` should be set to `Indexed in tileset image`.
Check the box for `Color 0` and choose what color you want to use for transparency in all of the palettes. The transparent color won't be used in the visible part of the image, so it doesn't really matter. I like to use the color of the tiles that will be off screen in order to minimize the number of unique colors required in the palettes. (The yellow color is `FFFF00`)
My Image to Tiles window looks like this now:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/image_to_tiles_window_filled.png)
Now click `OK`. You should get a little alert telling you it was a success. If you get an error about too many palettes, you may have to edit your initial image to remove some unique colors or redraw parts of the image so the multiple palettes have to share less colors between them in order to transition smoothly from one palette to another.
Now it will display your new tile sheet and tilemap:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_tiles.png)
# The Palettes
You may have noticed that the colors of some of the tiles are not correct. This is FINE. The current version of Tilemap Studio (4.0.1) sets all of the pixels in the tiles.png file to use the first palette for whatever reason. However, as long as you retain the order of the colors in each palette in the png, the game will assign them the correct palette and the map preview will show up with the proper colors in-game.
If you use `MPS_TYPE_FADE_IN` as the map preview behavior, only three palettes can be loaded into the game for the tiles.png image to utilize. Otherwise, the map preview can take advantage of all 16 palette slots.
This is where the instructions diverge based on how many palettes your new tiles image has.
* If your map preview has 2 or fewer palettes, follow the instructions in the [Two Palette Image](#two-palette-image) section.
* If your map preview has more than 2 palettes, skip to the [Fifteen Palette Image](#fifteen-palette-image) section and follow the instructions there instead.
## Two Palette Image
This is the only method that supports `MPS_TYPE_FADE_IN`. If you have more than 2 palettes, you may need to reduce the number of colors used in your initial image and try the whole process again.
The map preview palettes will be loaded into palette slots that don't interfere with the overworld palettes. Specifically, they will be loaded into slots `D`, `E`, and `F`. So, we need to change the palettes in the tilemap to match. If you open the new tiles.png file in your image editor, you can see how many palettes the map preview ended up with:
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_2_palettes.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_2_palettes.png)
</details>
My image ended up with exactly two palettes, which is an ideal situation. I'm going to move the palettes around so none of them get loaded into palette slot `E`. Palette slot `E` is reserved specifically for the colors used for the text that displays the map name.
For now, we just want to leave the second palette empty, like so:
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_3_palettes.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_3_palettes.png)
</details>
Remember that you can move whole 16-color palettes to different positions in the png, but you should not rearrange the order of the colors within any individual 16-color palette. The Image to Tiles function sets the colors to very specific positions and you don't want to mess around with that unless you really know what you are doing.
As long as you follow what I do in my screenshots, you should be fine.
~ ~ ~
Now go back to Tilemap Studio and click on the `Palettes` tab.
Here you can see what tiles will use which palettes:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_palettes_initial.png)
We need to change the palette numbers in the tilemap to match the palette slots they will be loaded into. The tiles marked `0` should be changed to `D`. The ones marked `1` should be changed to `F`. Shift clicking acts as a fill tool.
Here is what my tilemap looks like after the change:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_palettes_fade_in.png)
If your tiles.png file only has one palette, just change the whole tilemap to the `D` palette.
If your tiles.png file ended up with more than two palettes, you may have to edit your initial image to remove some unique colors or redraw parts of the image so that multiple palettes have to share fewer colors between them in order to transition smoothly from one palette to another. If you are skilled enough (or masochistic enough) you can try to rearrange some colors so they can be included in the `E` palette. I'll go over the `E` palette in more detail in the [Map Name Text](#map-name-text) section later.
If your tiles.png file ended up with A LOT more than two palettes, you should use the instructions [here](#no-fade) to go to the [Fifteen Palette Image](#fifteen-palette-image) section instead.
Make sure to save your changes.
The following Fifteen Palette Image section should be skipped if your map preview uses two or less palettes. **[CLICK HERE](#map-name-text) to go to the next relevant section.**
## Fifteen Palette Image
If you open the new tiles.png file in your image editor, you can see how many palettes the map preview ended up with:
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_2_palettes.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_2_palettes.png)
</details>
If your image has 14 palettes or less, you can [CLICK HERE](#map-name-text) to move to the next section. My image ended up with two palettes, which is a small enough number that I wouldn't have to do anything else in this section.
If your image has 15 or 16 palettes, continue with this section.
~ ~ ~
I'm going to show you a different example that ended up with 15 palettes:
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_15_palettes.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_15_palettes.png)
</details>
I'm going to move the palettes around so none of them get loaded into palette slot `E`. Palette slot `E` is reserved specifically for the colors used for the text that displays the map name. For now, we just want to leave the 15<sup>th</sup> palette empty, like so:
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_16_palettes.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_16_palettes.png)
</details>
Remember that you can move whole 16-color palettes to different positions in the png, but you should not rearrange the order of the colors within any individual 16-color palette. The Image to Tiles function sets the colors to very specific positions and you don't want to mess around with that unless you really know what you are doing. It's a pain in the butt!
As long as you follow what I do in my screenshots, you should be fine.
If your tiles.png file ended up with 16 palettes, you may have to edit your initial image to remove some unique colors or redraw parts of the image so that multiple palettes have to share fewer colors between them in order to transition smoothly from one palette to another. If you are skilled enough (or masochistic enough) you can try to rearrange some colors so they can be included in the `E` palette. I'll go over the `E` palette in more detail in the [Map Name Text](#map-name-text) section next.
Make sure to save your changes.
~ ~ ~
Now go back to Tilemap Studio and click on the `Palettes` tab. Here you can see what tiles will use which palettes:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_palettes_15.png)
We need to change the palette numbers in the tilemap to match where we moved them to in the png. Since we moved a palette from the 15<sup>th</sup> position to the 16<sup>th</sup> position, the tiles marked `E` should be changed to `F`. Shift clicking acts as a fill tool. CTRL clicking a tile will replace every tile of that palette with the selected palette.
Here is what my tilemap looks like after the change:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/TS_palettes_16.png)
Make sure to save your changes.
# Map Name Text
The current map's name will be printed in a text box in the upper left corner of the screen. The FRLG template I used earlier shows the exact area of the image that the text box will take up (104x24 pixels, directly in the corner).
If the map's name is longer than the standard text box size, the text box's width will automatically be extended by an extra 72 pixels. I have another FRLG template image that conforms to this larger size. You can find it in the ***docs/tutorials/img/map_preview_screen/templates*** folder.
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/templates/map_preview_template_long.png)
The map name being loaded in separately from the image allows you to use the same map preview image for multiple different maps.
~ ~ ~
Palette `E`, the one that is loaded into the second to last palette slot, is the one that the game uses for text and text boxes (not to be confused with the borders around the text boxes). While the palette is comprised of 16 colors, we are only concerned with 3 of them:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/numbered_palette.png)
* Color `1` (Red): Used for the text box itself. This is what the text gets printed on top of.
* Color `3` (Green): Used for the shadow of the characters of text.
* Color `4` (Blue): Used for the text itself.
The positions of these colors in the palette are specific to these functions and cannot be changed.
To demonstrate this in action, here is what the map name text looks like with the colors used in FRLG. The yellow colors in the palettes are filler:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/map_name_frlg_pal.png)
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/map_name_frlg.png)
And here is the same map name text, but with the colors drastically changed:
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/map_name_vivid_pal.png)
![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/map_name_vivid.png)
The rest of the colors in this palette can be used like normal (other than the transparent color `0`). This means you can utilize the unused portion as a sort of partial 16<sup>th</sup> palette for your map preview image. This takes further skill and knowledge than I will be covering in this guide, but if you can get the colors to line up with the pixels properly, you'll have that much more versatility with the image.
Keep in mind that this palette needs to be in the 15<sup>th</sup> slot of tiles.png, unless your image has 2 palettes or less. In that case, you should put it in the second slot instead.
Here is what the final palettes will look like in my Ruins of Alph tiles.png image (2 palettes):
<details>
<summary><i>Aseprite:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/aseprite_complete_pal_fade.png)
</details>
<details>
<summary><i>Graphics Gale:</i></summary>
> ![](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/docs/tutorials/img/map_preview_screen/gale_complete_pal_fade.png)
</details>
Once again, make sure to save your changes.
# The Code
Now that we have our files all sorted, it is time to incorporate our new map preview into the code.
First, if you want to adhere to the naming conventions of the other map previews, you can rename the tiles.bin file to tilemap.bin. This isn't strictly necessary, but I find it convenient to keep all of the file names consistent.
Go to ***src/map_preview_screen.c*** and add filepaths to your new files. You'll need to add three new lines. One for the palette, one for the tiles image, and one for the tilemap. The palette file does not exist yet, but this line of code will tell the compiler to generate a gbapal file from the tiles image. You'll also need to add .4bpp.smol and .bin.smolTM suffixes to the tiles and tilemap filepaths respectively. That tells the compiler to generate compressed versions of those files that the GBA can read.
Here's how I did mine:
```diff
static const u8 sIcefallCaveMapPreviewPalette[] = INCBIN_U8("graphics/map_preview/icefall_cave/tiles.gbapal");
static const u8 sIcefallCaveMapPreviewTiles[] = INCBIN_U8("graphics/map_preview/icefall_cave/tiles.4bpp.smol");
static const u8 sIcefallCaveMapPreviewTilemap[] = INCBIN_U8("graphics/map_preview/icefall_cave/tilemap.bin.smolTM");
static const u8 sAlteringCaveMapPreviewPalette[] = INCBIN_U8("graphics/map_preview/altering_cave/tiles.gbapal");
static const u8 sAlteringCaveMapPreviewTiles[] = INCBIN_U8("graphics/map_preview/altering_cave/tiles.4bpp.smol");
static const u8 sAlteringCaveMapPreviewTilemap[] = INCBIN_U8("graphics/map_preview/altering_cave/tilemap.bin.smolTM");
+static const u8 sRuinsOfAlphMapPreviewPalette[] = INCBIN_U8("graphics/map_preview/ruins_of_alph/tiles.gbapal");
+static const u8 sRuinsOfAlphMapPreviewTiles[] = INCBIN_U8("graphics/map_preview/ruins_of_alph/tiles.4bpp.smol");
+static const u8 sRuinsOfAlphMapPreviewTilemap[] = INCBIN_U8("graphics/map_preview/ruins_of_alph/tilemap.bin.smolTM");
```
Again, the names of things can be whatever you want, but keeping with the existing name convention can help you stay organized and informed. For example, I could replace `sRuinsOfAlphMapPreviewTilemap` with `SmittyWerbenJaegerManJensen` and it would still work just fine. But `sRuinsOfAlphMapPreviewTilemap` is so much more descriptive, I never run the risk of forgetting what its intended use is. Do what feels right to you.
That's it! Now your new map preview has been added to the game!
Follow the instructions [HERE](#using-the-map-previews) to link the map preview to a map.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

View File

@ -0,0 +1,13 @@
#ifndef GUARD_CONFIG_MAP_PREVIEW_H
#define GUARD_CONFIG_MAP_PREVIEW_H
#define MPS_ENABLE_MAP_PREVIEWS IS_FRLG // Enables map previews.
#define MPS_DURATION_LONG 120 // This is the number of frames the map preview will last when the player enters the map for the first time.
#define MPS_DURATION_SHORT 40 // This is the number of frames the map preview will last if the player has visited the map before.
#define MPS_DURATION_NO_FLAG 40 // This is the number of frames the map preview will last if the map's flagId is MPS_FLAG_NULL.
#define MPS_BASIC_FADE_SPEED 1 // This sets the speed that the map preview fades to black when MPS_TYPE_BASIC is used.
// Numbers less than 1 will have a shorter fade time (negative numbers can be used).
// Numbers greater than 1 will have a longer fade time.
#endif // GUARD_CONFIG_MAP_PREVIEW_H

View File

@ -25,6 +25,7 @@
#include "config/follower_npc.h"
#include "config/general.h"
#include "config/item.h"
#include "config/map_preview_screen.h"
#include "config/overworld.h"
#include "config/pokemon.h"
#include "config/summary_screen.h"

View File

@ -55,4 +55,6 @@ bool8 FldEff_UseRockSmash(void);
bool32 SetUpFieldMove_Defog(void);
bool8 FldEff_Defog(void);
void Task_EnterCaveTransition2(u8 taskId);
#endif // GUARD_FLDEFF_H

View File

@ -34,14 +34,18 @@ enum MapPreviewScreenId
MPS_COUNT
};
#define MPS_TYPE_CAVE 0
#define MPS_TYPE_FOREST 1
#define MPS_TYPE_ANY 2
#define MPS_TYPE_CAVE 0
#define MPS_TYPE_FADE_IN 1
#define MPS_TYPE_BASIC 2
#define MPS_TYPE_ANY 3
#define MPS_FLAG_NULL 0
struct MapPreviewScreen
{
mapsec_u8_t mapsec;
u8 type;
u8 usesAllPalettes;
u16 flagId;
const void *tilesptr;
const void *tilemapptr;
@ -49,16 +53,16 @@ struct MapPreviewScreen
};
u16 MapPreview_CreateMapNameWindow(u8 id);
void MapPreview_SetFlag(u16 a0);
u16 MapPreview_GetDuration(u8 id);
bool8 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type);
bool32 ForestMapPreviewScreenIsRunning(void);
const struct MapPreviewScreen * GetDungeonMapPreviewScreenInfo(mapsec_u8_t mapsec);
bool32 MapHasPreviewScreen_HandleQLState2(mapsec_u8_t mapsec, u8 type);
bool32 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type);
bool32 FadeInMapPreviewScreenIsRunning(void);
void MapPreview_InitBgs(void);
void MapPreview_LoadGfx(mapsec_u8_t mapsec);
bool32 MapPreview_IsGfxLoadFinished(void);
void MapPreview_Unload(s32 windowId);
void MapPreview_StartForestTransition(mapsec_u8_t mapsec);
void RunMapPreviewScreenNonFade(u8 mapSecId);
void RunMapPreviewScreenFadeIn(mapsec_u8_t mapsec);
void Task_MapPreviewScreen_NonFade(u8 taskId);
void MapPreview_SetFlag(u16 flagId);
#endif //GUARD_MAP_PREVIEW_SCREEN_H

View File

@ -147,6 +147,7 @@ enum MapType GetMapTypeByGroupAndId(s8 mapGroup, s8 mapNum);
enum MapType GetMapTypeByWarpData(struct WarpData *warp);
enum MapType GetCurrentMapType(void);
enum MapType GetLastUsedWarpMapType(void);
mapsec_u8_t GetLastUsedWarpMapSectionId(void);
bool8 IsMapTypeOutdoors(enum MapType mapType);
bool8 Overworld_MapTypeAllowsTeleportAndFly(enum MapType mapType);
bool8 IsMapTypeIndoors(enum MapType mapType);

View File

@ -22,6 +22,7 @@
#include "follower_npc.h"
#include "item_menu.h"
#include "link.h"
#include "map_preview_screen.h"
#include "match_call.h"
#include "metatile_behavior.h"
#include "overworld.h"
@ -221,7 +222,7 @@ int ProcessPlayerFieldInput(struct FieldInput *input)
}
if (input->pressedAButton && TrySetupDiveDownScript() == TRUE)
return TRUE;
if (input->pressedStartButton)
if (input->pressedStartButton/* && !FadeInMapPreviewScreenIsRunning()*/) // Prevents opening the Start menu while the map preview is still fading out.
{
FlagSet(FLAG_OPENED_START_MENU);
PlaySE(SE_WIN_OPEN);

View File

@ -20,6 +20,7 @@
#include "link_rfu.h"
#include "load_save.h"
#include "main.h"
#include "map_preview_screen.h"
#include "menu.h"
#include "mirage_tower.h"
#include "metatile_behavior.h"
@ -384,7 +385,10 @@ static void Task_ExitDoor(u8 taskId)
}
break;
case 4:
UnlockPlayerFieldControls();
// Don't unlock controls until the map preview has finished.
if (!FadeInMapPreviewScreenIsRunning())
UnlockPlayerFieldControls();
DestroyTask(taskId);
break;
}
@ -431,7 +435,10 @@ static void Task_ExitNonAnimDoor(u8 taskId)
}
break;
case 3:
UnlockPlayerFieldControls();
// Don't unlock controls until the map preview has finished.
if (!FadeInMapPreviewScreenIsRunning())
UnlockPlayerFieldControls();
DestroyTask(taskId);
break;
}
@ -450,7 +457,10 @@ static void Task_ExitNonDoor(u8 taskId)
if (WaitForWeatherFadeIn())
{
UnfreezeObjectEvents();
UnlockPlayerFieldControls();
// Don't unlock controls until the map preview has finished.
if (!FadeInMapPreviewScreenIsRunning())
UnlockPlayerFieldControls();
DestroyTask(taskId);
}
break;

View File

@ -8,6 +8,7 @@
#include "field_weather.h"
#include "fieldmap.h"
#include "main.h"
#include "map_preview_screen.h"
#include "menu.h"
#include "palette.h"
#include "random.h"
@ -169,7 +170,11 @@ static const u8 ALIGNED(2) sBasePaletteColorMapTypes[32] =
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
#if MPS_ENABLE_MAP_PREVIEWS
COLOR_MAP_NONE,
#else
COLOR_MAP_DARK_CONTRAST,
#endif // MPS_ENABLE_MAP_PREVIEWS
COLOR_MAP_NONE,
COLOR_MAP_NONE,
// sprite palettes

View File

@ -7,6 +7,7 @@
#include "fldeff.h"
#include "gpu_regs.h"
#include "main.h"
#include "map_preview_screen.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
@ -36,7 +37,6 @@ static void Task_ExitCaveTransition4(u8 taskId);
static void Task_ExitCaveTransition5(u8 taskId);
static void DoEnterCaveTransition(void);
static void Task_EnterCaveTransition1(u8 taskId);
static void Task_EnterCaveTransition2(u8 taskId);
static void Task_EnterCaveTransition3(u8 taskId);
static void Task_EnterCaveTransition4(u8 taskId);
@ -157,6 +157,12 @@ static bool8 TryDoMapTransition(void)
enum MapType fromType = GetLastUsedWarpMapType();
enum MapType toType = GetCurrentMapType();
if (MPS_ENABLE_MAP_PREVIEWS && FlagGet(FLAG_HIDE_MAP_NAME_POPUP) != TRUE && GetLastUsedWarpMapSectionId() != gMapHeader.regionMapSectionId && (MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_CAVE) == TRUE || MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_BASIC) == TRUE))
{
RunMapPreviewScreenNonFade(gMapHeader.regionMapSectionId);
return TRUE;
}
for (i = 0; sTransitionTypes[i].fromType; i++)
{
if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
@ -298,7 +304,7 @@ static void Task_EnterCaveTransition1(u8 taskId)
gTasks[taskId].func = Task_EnterCaveTransition2;
}
static void Task_EnterCaveTransition2(u8 taskId)
void Task_EnterCaveTransition2(u8 taskId)
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
DecompressDataWithHeaderVram(sCaveTransitionTiles, (void *)(VRAM + 0xC000));

View File

@ -2,7 +2,10 @@
#include "event_data.h"
#include "field_screen_effect.h"
#include "field_weather.h"
#include "fldeff.h"
#include "gpu_regs.h"
#include "io_reg.h"
#include "main.h"
#include "malloc.h"
#include "map_preview_screen.h"
#include "menu.h"
@ -12,14 +15,12 @@
#include "script.h"
#include "string_util.h"
#include "constants/region_map_sections.h"
#include "constants/rgb.h"
static EWRAM_DATA bool8 sHasVisitedMapBefore = FALSE;
#if IS_FRLG
static EWRAM_DATA bool8 sAllocedBg0TilemapBuffer = FALSE;
static void Task_RunMapPreviewScreenForest(u8 taskId);
static void Task_MapPreviewScreen_FadeIn(u8 taskId);
static const u8 sViridianForestMapPreviewPalette[] = INCBIN_U8("graphics/map_preview/viridian_forest/tiles.gbapal");
static const u8 sViridianForestMapPreviewTiles[] = INCBIN_U8("graphics/map_preview/viridian_forest/tiles.4bpp.smol");
@ -88,7 +89,7 @@ static const u8 sAlteringCaveMapPreviewTilemap[] = INCBIN_U8("graphics/map_previ
static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
[MPS_VIRIDIAN_FOREST] = {
.mapsec = MAPSEC_VIRIDIAN_FOREST,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_VIRIDIAN_FOREST,
.tilesptr = sViridianForestMapPreviewTiles,
.tilemapptr = sViridianForestMapPreviewTilemap,
@ -128,7 +129,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_SAFARI_ZONE] = {
.mapsec = MAPSEC_KANTO_SAFARI_ZONE,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_SAFARI_ZONE_CENTER,
.tilesptr = sSafariZoneMapPreviewTiles,
.tilemapptr = sSafariZoneMapPreviewTilemap,
@ -144,7 +145,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_POKEMON_MANSION] = {
.mapsec = MAPSEC_POKEMON_MANSION,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_POKEMON_MANSION_1F,
.tilesptr = sPokemonMansionMapPreviewTiles,
.tilemapptr = sPokemonMansionMapPreviewTilemap,
@ -152,7 +153,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_ROCKET_HIDEOUT] = {
.mapsec = MAPSEC_ROCKET_HIDEOUT,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_ROCKET_HIDEOUT_B1F,
.tilesptr = sRocketHideoutMapPreviewTiles,
.tilemapptr = sRocketHideoutMapPreviewTilemap,
@ -184,7 +185,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_POWER_PLANT] = {
.mapsec = MAPSEC_POWER_PLANT,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_POWER_PLANT,
.tilesptr = sPowerPlantMapPreviewTiles,
.tilemapptr = sPowerPlantMapPreviewTilemap,
@ -200,7 +201,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_ROCKET_WAREHOUSE] = {
.mapsec = MAPSEC_ROCKET_WAREHOUSE,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_THREE_ISLAND_BERRY_FOREST,
.tilesptr = sRocketWarehouseMapPreviewTiles,
.tilemapptr = sRocketWarehouseMapPreviewTilemap,
@ -224,7 +225,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_BERRY_FOREST] = {
.mapsec = MAPSEC_BERRY_FOREST,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_THREE_ISLAND_BERRY_FOREST,
.tilesptr = sBerryForestMapPreviewTiles,
.tilemapptr = sBerryForestMapPreviewTilemap,
@ -256,7 +257,7 @@ static const struct MapPreviewScreen sMapPreviewScreenData[MPS_COUNT] = {
},
[MPS_PATTERN_BUSH] = {
.mapsec = MAPSEC_PATTERN_BUSH,
.type = MPS_TYPE_FOREST,
.type = MPS_TYPE_FADE_IN,
.flagId = FLAG_WORLD_MAP_SIX_ISLAND_PATTERN_BUSH,
.tilesptr = sViridianForestMapPreviewTiles,
.tilemapptr = sViridianForestMapPreviewTilemap,
@ -322,6 +323,16 @@ static const struct WindowTemplate sMapNameWindow = {
.baseBlock = 0x1C2
};
static const struct WindowTemplate sMapNameWindowLarge = {
.bg = 0,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 22,
.height = 2,
.paletteNum = 14,
.baseBlock = 0x259
};
static const struct BgTemplate sMapPreviewBgTemplate[1] = {
{
.mapBaseIndex = 31
@ -342,7 +353,7 @@ static u8 GetMapPreviewScreenIdx(mapsec_u8_t mapsec)
return MPS_COUNT;
}
bool8 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type)
bool32 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type)
{
u8 idx;
@ -350,13 +361,9 @@ bool8 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type)
if (idx != MPS_COUNT)
{
if (type == MPS_TYPE_ANY)
{
return TRUE;
}
else
{
return sMapPreviewScreenData[idx].type == type ? TRUE : FALSE;
}
}
else
{
@ -364,11 +371,6 @@ bool8 MapHasPreviewScreen(mapsec_u8_t mapsec, u8 type)
}
}
bool32 MapHasPreviewScreen_HandleQLState2(mapsec_u8_t mapsec, u8 type)
{
return MapHasPreviewScreen(mapsec, type);
}
void MapPreview_InitBgs(void)
{
InitBgsFromTemplates(0, sMapPreviewBgTemplate, NELEMS(sMapPreviewBgTemplate));
@ -382,20 +384,24 @@ void MapPreview_LoadGfx(mapsec_u8_t mapsec)
idx = GetMapPreviewScreenIdx(mapsec);
if (idx != MPS_COUNT)
{
ResetTempTileDataBuffers();
LoadPalette(sMapPreviewScreenData[idx].palptr, BG_PLTT_ID(13), 3 * PLTT_SIZE_4BPP);
DecompressAndCopyTileDataToVram(0, sMapPreviewScreenData[idx].tilesptr, 0, 0, 0);
if (GetBgTilemapBuffer(0) == NULL)
{
SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
sAllocedBg0TilemapBuffer = TRUE;
}
else
{
sAllocedBg0TilemapBuffer = FALSE;
}
CopyToBgTilemapBuffer(0, sMapPreviewScreenData[idx].tilemapptr, 0, 0x000);
CopyBgTilemapBufferToVram(0);
ResetTempTileDataBuffers();
if (sMapPreviewScreenData[idx].usesAllPalettes == TRUE)
LoadPalette(sMapPreviewScreenData[idx].palptr, BG_PLTT_ID(0), 16 * PLTT_SIZE_4BPP);
else
LoadPalette(sMapPreviewScreenData[idx].palptr, BG_PLTT_ID(13), 3 * PLTT_SIZE_4BPP);
DecompressAndCopyTileDataToVram(0, sMapPreviewScreenData[idx].tilesptr, 0, 0, 0);
if (GetBgTilemapBuffer(0) == NULL)
{
SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
sAllocedBg0TilemapBuffer = TRUE;
}
else
{
sAllocedBg0TilemapBuffer = FALSE;
}
CopyToBgTilemapBuffer(0, sMapPreviewScreenData[idx].tilemapptr, 0, 0x000);
CopyBgTilemapBufferToVram(0);
}
}
@ -413,11 +419,127 @@ bool32 MapPreview_IsGfxLoadFinished(void)
return FreeTempTileDataBuffersIfPossible();
}
void MapPreview_StartForestTransition(mapsec_u8_t mapsec)
u16 MapPreview_CreateMapNameWindow(mapsec_u8_t mapsec)
{
u16 windowId;
u32 xctr;
s32 stringWidth;
#ifdef BUGFIX
// Fixes access violations indicated below.
u8 color[3];
#else
u8 color[0];
#endif
GetMapName(gStringVar4, mapsec, 0);
// Use a longer window size if the map name is too long to fit.
stringWidth = GetStringWidth(FONT_NORMAL, gStringVar4, 0);
if (stringWidth > 104)
{
windowId = AddWindow(&sMapNameWindowLarge);
xctr = 177 - stringWidth;
}
else
{
xctr = 104 - stringWidth;
windowId = AddWindow(&sMapNameWindow);
}
FillWindowPixelBuffer(windowId, PIXEL_FILL(1));
PutWindowTilemap(windowId);
color[0] = TEXT_COLOR_WHITE; // Access violation
color[1] = TEXT_COLOR_RED; // Access violation
color[2] = TEXT_COLOR_LIGHT_GRAY; // Access violation
AddTextPrinterParameterized4(windowId, FONT_NORMAL, xctr / 2, 2, 0, 0, color/* Access violation */, -1, gStringVar4);
return windowId;
}
void RunMapPreviewScreenNonFade(u8 mapSecId)
{
u8 taskId = CreateTask(Task_MapPreviewScreen_NonFade, 0);
gTasks[taskId].data[3] = mapSecId;
}
void Task_MapPreviewScreen_NonFade(u8 taskId)
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
case 0:
SetWordTaskArg(taskId, 5, (uintptr_t)gMain.vblankCallback);
SetVBlankCallback(NULL);
MapPreview_InitBgs();
MapPreview_LoadGfx(data[3]);
BlendPalettes(PALETTES_ALL, 0x10, RGB_WHITE);
data[0]++;
break;
case 1:
if (!MapPreview_IsGfxLoadFinished())
{
data[4] = MapPreview_CreateMapNameWindow(data[3]);
CopyWindowToVram(data[4], COPYWIN_FULL);
data[0]++;
}
break;
case 2:
if (!IsDma3ManagerBusyWithBgCopy())
{
if (MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_CAVE) == TRUE)
BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_WHITE);
else
BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK);
SetVBlankCallback((IntrCallback)GetWordTaskArg(taskId, 5));
data[0]++;
}
break;
case 3:
if (!UpdatePaletteFade())
{
data[2] = MapPreview_GetDuration(data[3]);
data[0]++;
}
break;
case 4:
data[1]++;
if (data[1] > data[2] || JOY_NEW(B_BUTTON))
{
if (MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_CAVE) == TRUE)
{
BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, RGB_WHITE);
}
else {
BeginNormalPaletteFade(PALETTES_ALL, MPS_BASIC_FADE_SPEED, 0, 16, RGB_BLACK);
}
data[0]++;
}
break;
case 5:
if (!UpdatePaletteFade())
{
int i;
for (i = 0; i < 16; i++)
{
data[i] = 0;
}
MapPreview_Unload(data[4]);
if (MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_CAVE) == TRUE)
{
gTasks[taskId].func = Task_EnterCaveTransition2;
}
else
{
SetMainCallback2(gMain.savedCallback);
}
}
break;
}
}
void RunMapPreviewScreenFadeIn(mapsec_u8_t mapsec)
{
u8 taskId;
taskId = CreateTask(Task_RunMapPreviewScreenForest, 0);
taskId = CreateTask(Task_MapPreviewScreen_FadeIn, 0);
gTasks[taskId].data[2] = GetBgAttribute(0, BG_ATTR_PRIORITY);
gTasks[taskId].data[4] = GetGpuReg(REG_OFFSET_BLDCNT);
gTasks[taskId].data[5] = GetGpuReg(REG_OFFSET_BLDALPHA);
@ -428,50 +550,18 @@ void MapPreview_StartForestTransition(mapsec_u8_t mapsec)
gTasks[taskId].data[8] = 16;
gTasks[taskId].data[9] = 0;
SetBgAttribute(0, BG_ATTR_PRIORITY, 0);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
SetGpuRegBits(REG_OFFSET_WININ, WININ_WIN0_CLR | WININ_WIN1_CLR);
SetGpuRegBits(REG_OFFSET_WINOUT, WINOUT_WIN01_CLR);
gTasks[taskId].data[11] = MapPreview_CreateMapNameWindow(mapsec);
LockPlayerFieldControls();
}
u16 MapPreview_CreateMapNameWindow(mapsec_u8_t mapsec)
bool32 FadeInMapPreviewScreenIsRunning(void)
{
u16 windowId;
u32 xctr;
#ifdef BUGFIX
// Fixes access violations indicated below.
u8 color[3];
#else
u8 color[0];
#endif
windowId = AddWindow(&sMapNameWindow);
FillWindowPixelBuffer(windowId, PIXEL_FILL(1));
PutWindowTilemap(windowId);
color[0] = TEXT_COLOR_WHITE; // Access violation
color[1] = TEXT_COLOR_RED; // Access violation
color[2] = TEXT_COLOR_LIGHT_GRAY; // Access violation
GetMapName(gStringVar4, mapsec, 0);
xctr = 104 - GetStringWidth(FONT_NORMAL, gStringVar4, 0);
AddTextPrinterParameterized4(windowId, FONT_NORMAL, xctr / 2, 2, 0, 0, color/* Access violation */, -1, gStringVar4);
return windowId;
return FuncIsActiveTask(Task_MapPreviewScreen_FadeIn);
}
bool32 ForestMapPreviewScreenIsRunning(void)
{
if (FuncIsActiveTask(Task_RunMapPreviewScreenForest) == TRUE)
{
return FALSE;
}
else
{
return TRUE;
}
}
static void Task_RunMapPreviewScreenForest(u8 taskId)
static void Task_MapPreviewScreen_FadeIn(u8 taskId)
{
s16 * data;
@ -501,8 +591,10 @@ static void Task_RunMapPreviewScreenForest(u8 taskId)
break;
case 3:
data[1]++;
if (data[1] > data[10])
if (data[1] > data[10] || (JOY_NEW(B_BUTTON)))
{
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
data[1] = 0;
data[0]++;
}
@ -527,7 +619,7 @@ static void Task_RunMapPreviewScreenForest(u8 taskId)
}
data[1] = (data[1] + 1) % 3;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(data[8], data[9]));
if (data[8] == 0 && data[9] == 16)
if ((data[8] == 0 && data[9] == 16))
{
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32);
CopyBgTilemapBufferToVram(0);
@ -544,63 +636,43 @@ static void Task_RunMapPreviewScreenForest(u8 taskId)
SetGpuReg(REG_OFFSET_BLDALPHA, data[5]);
SetGpuReg(REG_OFFSET_WININ, data[6]);
SetGpuReg(REG_OFFSET_WINOUT, data[7]);
UnlockPlayerFieldControls();
DestroyTask(taskId);
}
break;
}
}
const struct MapPreviewScreen * GetDungeonMapPreviewScreenInfo(mapsec_u8_t mapsec)
{
u8 idx;
idx = GetMapPreviewScreenIdx(mapsec);
if (idx == MPS_COUNT)
{
return NULL;
}
else
{
return &sMapPreviewScreenData[idx];
}
}
u16 MapPreview_GetDuration(mapsec_u8_t mapsec)
{
u8 idx;
u16 flagId;
idx = GetMapPreviewScreenIdx(mapsec);
if (idx == MPS_COUNT)
{
return 0;
}
flagId = sMapPreviewScreenData[idx].flagId;
if (sMapPreviewScreenData[idx].type == MPS_TYPE_CAVE)
if (flagId == MPS_FLAG_NULL)
{
return MPS_DURATION_NO_FLAG;
}
else
{
if (!FlagGet(flagId))
{
return 120;
FlagSet(flagId);
return MPS_DURATION_LONG;
}
else
{
return 40;
}
}
else {
if (sHasVisitedMapBefore)
{
return 120;
}
else
{
return 40;
return MPS_DURATION_SHORT;
}
}
}
#endif // IS_FRLG
void MapPreview_SetFlag(u16 flagId)
{
if (!FlagGet(flagId))
@ -613,3 +685,88 @@ void MapPreview_SetFlag(u16 flagId)
}
FlagSet(flagId);
}
static void VblankCB_MapPreviewScript(void)
{
TransferPlttBuffer();
}
static void CB2_MapPreviewScript(void)
{
RunTasks();
DoScheduledBgTilemapCopiesToVram();
UpdatePaletteFade();
}
#define tTaskStep data[0]
#define tFrameCounter data[1]
#define tWindowId data[2]
#define tDuration data[3]
static void Task_MapPreviewScreen_Script(u8 taskId)
{
s16 *data;
data = gTasks[taskId].data;
switch (tTaskStep)
{
case 0:
if (!UpdatePaletteFade())
{
SetVBlankCallback(NULL);
MapPreview_LoadGfx(gMapHeader.regionMapSectionId);
BlendPalettes(PALETTES_ALL, 16, RGB_BLACK);
gMain.savedCallback = CB2_ReturnToFieldContinueScript;
SetMainCallback2(CB2_MapPreviewScript);
tTaskStep++;
}
break;
case 1:
if (!MapPreview_IsGfxLoadFinished() && !IsDma3ManagerBusyWithBgCopy())
{
tWindowId = MapPreview_CreateMapNameWindow(gMapHeader.regionMapSectionId);
CopyWindowToVram(tWindowId, COPYWIN_FULL);
tTaskStep++;
}
break;
case 2:
if (!IsDma3ManagerBusyWithBgCopy())
{
SetVBlankCallback(VblankCB_MapPreviewScript);
FadeInFromBlack();
tTaskStep++;
}
break;
case 3:
tFrameCounter++;
if (tFrameCounter > tDuration || JOY_HELD(B_BUTTON))
{
BeginNormalPaletteFade(PALETTES_ALL, MPS_BASIC_FADE_SPEED, 0, 16, RGB_BLACK);
tFrameCounter = 0;
tTaskStep++;
}
break;
case 4:
if (!UpdatePaletteFade())
{
MapPreview_Unload(tWindowId);
DestroyTask(taskId);
SetMainCallback2(gMain.savedCallback);
}
break;
}
}
void MapPreviewScript(struct ScriptContext *ctx)
{
u32 duration = ScriptReadHalfword(ctx);
u32 taskId;
if (!MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_ANY))
return;
ScriptContext_Stop();
FadeScreen(FADE_TO_BLACK, 0);
taskId = CreateTask(Task_MapPreviewScreen_Script, 0);
gTasks[taskId].tDuration = duration;
}

View File

@ -39,6 +39,7 @@
#include "malloc.h"
#include "m4a.h"
#include "map_name_popup.h"
#include "map_preview_screen.h"
#include "match_call.h"
#include "menu.h"
#include "metatile_behavior.h"
@ -1510,6 +1511,11 @@ enum MapType GetLastUsedWarpMapType(void)
return GetMapTypeByWarpData(&gLastUsedWarp);
}
mapsec_u8_t GetLastUsedWarpMapSectionId(void)
{
return Overworld_GetMapHeaderByGroupAndId(gLastUsedWarp.mapGroup, gLastUsedWarp.mapNum)->regionMapSectionId;
}
bool8 IsMapTypeOutdoors(enum MapType mapType)
{
if (mapType == MAP_TYPE_ROUTE
@ -2302,7 +2308,12 @@ static bool32 LoadMapInStepsLocal(u8 *state, bool32 a2)
(*state)++;
break;
case 11:
if (gMapHeader.showMapName == TRUE && SecretBaseMapPopupEnabled() == TRUE)
if (MPS_ENABLE_MAP_PREVIEWS && FlagGet(FLAG_HIDE_MAP_NAME_POPUP) != TRUE && GetLastUsedWarpMapSectionId() != gMapHeader.regionMapSectionId && MapHasPreviewScreen(gMapHeader.regionMapSectionId, MPS_TYPE_FADE_IN) == TRUE)
{
MapPreview_LoadGfx(gMapHeader.regionMapSectionId);
RunMapPreviewScreenFadeIn(gMapHeader.regionMapSectionId);
}
else if (gMapHeader.showMapName == TRUE && SecretBaseMapPopupEnabled() == TRUE)
ShowMapNamePopup();
(*state)++;
break;