summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlawter666 <38655737+Slawter666@users.noreply.github.com>2018-09-16 20:09:49 +0100
committerSlawter666 <38655737+Slawter666@users.noreply.github.com>2018-09-16 20:09:49 +0100
commit013d6483ad183cf60e879b97e604bedee37fcb70 (patch)
tree47f3da095d8c8a43457ce06750ec55febaadb1f6
parent5686ea0596e6dad65f128cb714b9ef0c5dc8be5c (diff)
Created Adding new overworlds (markdown)
-rw-r--r--Adding-new-overworlds.md181
1 files changed, 181 insertions, 0 deletions
diff --git a/Adding-new-overworlds.md b/Adding-new-overworlds.md
new file mode 100644
index 0000000..28a8c2d
--- /dev/null
+++ b/Adding-new-overworlds.md
@@ -0,0 +1,181 @@
+This tutorial is for adding a new overworld sprite. We'll be using the following sprite sheet as an example.
+
+![](https://raw.githubusercontent.com/Slawter666/pokeemerald/costume/graphics/event_objects/pics/people/red/walking.png)
+
+## Contents
+
+1. [Formatting your image](#1-formatting-your-image)
+2. [Adding your image](#2-adding-your-image)
+3. [Adding a new palette](#3-adding-a-new-palette)
+4. [Adding a new pic table](#4-adding-a-new-pic-table)
+5. [Adding a new EventObjectGraphicsInfo entry](#5-adding-a-new-eventobjectgraphicsinfo-entry)
+6. [Adding a define for your overworld](#6-adding-a-define-for-your-overworld)
+
+## 1. Formatting your image
+Your image should be saved as a .png with a bit depth of 4, allowing for a maximum palette of 16 colours. The first colour within the palette will be transparent in game so ensure that your background colour is in that first slot. The width and height should be a multiple of 8 (16, 32, 64 for example) and the poses should be ordered like the sprite sheet above in order to avoid having to make changes to the animation tables, although if desired making custom animations should be somewhat simple.
+
+The overworld, or event object graphics are located in **graphics/event_objects/pics** so it is recommended to save your image there.
+
+## 2. Adding your image
+Within **src/data/event_object_graphics.h** add a label for your image:
+
+```c
+const u32 gEventObjectPic_Example[] = INCBIN_U32(“graphics/event_objects/pic/people/example.4bpp”);
+```
+If you want your new overworld to use a new palette then add that too. The palette can be generated from the .png so you don’t need to have a separate .pal file.
+```c
+const u16 gEventObjectPalette_Example[] = INCBIN_U16(“graphics/event_objects/pic/people/example.gbapal”);
+```
+Next you need to specify the build rules for the sprite sheet within **spritesheet_rules.mk**.
+
+–mwidth and –mheight represent the size of one frame of your spritesheet, in tiles rather than pixels (1 tile is 8x8 pixels).
+Each frame of the example above is 32x32 pixels so the build rule becomes:
+```mk
+$(EVENTOBJGFXDIR)/people/example.4bpp: %.4bpp: %.png
+ $(GFX) $< $@ -mwidth 4 -mheight 4
+```
+## 3. Adding a new palette
+If your new overworld uses an existing palette then you can skip this step.
+
+In **src/event_object_movement.c** you will need to add a reference to your new palette to sEventObjectSpritePalettes[], the palette requires a unique tag which we will use later.
+The existing tags are defined above sEventObjectSpritePalettes[].
+```c
+ #define EVENT_OBJ_PAL_TAG_30 0x111F
+ #define EVENT_OBJ_PAL_TAG_31 0x1120
+ #define EVENT_OBJ_PAL_TAG_32 0x1121
+ #define EVENT_OBJ_PAL_TAG_33 0x1122
+ #define EVENT_OBJ_PAL_TAG_34 0x1123
++ #define EVENT_OBJ_PAL_EXAMPLE 0x1124
+ #define EVENT_OBJ_PAL_TAG_NONE 0x11FF
+```
+```c
+const struct SpritePalette sEventObjectSpritePalettes[] = {
+ // removed for brevity
+ {gEventObjectPalette30, EVENT_OBJ_PAL_TAG_30},
+ {gEventObjectPalette31, EVENT_OBJ_PAL_TAG_31},
+ {gEventObjectPalette32, EVENT_OBJ_PAL_TAG_32},
+ {gEventObjectPalette33, EVENT_OBJ_PAL_TAG_33},
+ {gEventObjectPalette34, EVENT_OBJ_PAL_TAG_34},
++ {gEventObjectPalette_Example, EVENT_OBJ_PAL_EXAMPLE},
+ {NULL, 0x0000},
+};
+```
+## 4. Adding a new pic table
+Within **src/data/field_event_obj/event_obj_pic_tables.h** add a new pic table for your overworld.
+We will be using the macro:
+```c
+overworld_frame(ptr, width, height, frame)
+```
+Where the width and height are in tiles rather than pixels. So our new pic table becomes:
+```c
+const struct SpriteFrameImage gEventObjectPicTable_Example[] = {
+ overworld_frame(gEventObjectPic_Example, 4, 4, 0),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 1),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 2),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 3),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 4),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 5),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 6),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 7),
+ overworld_frame(gEventObjectPic_Example, 4, 4, 8),
+};
+```
+If the frames in your sprite sheet are in a different order to the example shown above then this table will need re-arranging.
+## 5. Adding a new EventObjectGraphicsInfo entry
+Within **src/data/field_event_obj/event_object_graphics_info.h** add a new entry for your overworld.
+```c
+const struct EventObjectGraphicsInfo gEventObjectGraphicsInfo_Example = {
+ .tileTag = 0xFFFF,
+ .paletteTag1 = EVENT_OBJ_PAL_EXAMPLE,
+ .paletteTag2 = EVENT_OBJ_PAL_TAG_NONE,
+ .size = 512,
+ .width = 32,
+ .height = 32,
+ .paletteSlot = 0,
+ .shadowSize = SHADOW_SIZE_M,
+ .inanimate = FALSE,
+ .disableReflectionPaletteLoad = FALSE,
+ .tracks = TRACKS_FOOT,
+ .oam = &gEventObjectBaseOam_32x32,
+ .subspriteTables = gEventObjectSpriteOamTables_32x32,
+ .anims = gEventObjectImageAnimTable_Standard,
+ .images = gEventObjectPicTable_Example,
+ .affineAnims = gDummySpriteAffineAnimTable,
+};
+```
+- `.tileTag` is always 0xFFFF.
+- `.paletteTag1` is the standard palette used by the overworld sprite.
+- `.paletteTag2` is the reflection palette used, for NPCs this is typically EVENT_OBJ_PAL_TAG_NONE.
+- `.size` refers to the size in bytes of 1 frame of your overworld. It can be calculated by multiplying the width by height by bit depth (in this case 32x32x4) to get the size in bits, then divide by 8 to convert it into bytes.
+- `.width` is the width in pixels of one frame of your sprite sheet.
+- `.height` is the height in pixels of one frame of your sprite sheet.
+- `.paletteSlot`: There are 16 available palette slots, slot 0 is used by the main character your play as, slot 10 is used by special NPCs such as the cable car or invisible keckleon. Note that whilst slot 0 is used by the main character there are duplicate entries for your rival which uses slot 10 instead, so as not to load the wrong palette when both Brendan and May are on screen.
+- `.inanimate` If set to TRUE then your overworld won't be animated, used for NPCs such as the dolls or cushions.
+
+- `.tracks` determines what tracks, if any are left when moving through sand or similar tiles.
+- `.oam` The oam tables are located in **src/data/field_event_obj/base_oam.h** and are size dependant.
+- `.subspriteTables` The subsprite tables are located in **src/data/field_event_obj/event_object_subsprites.h** and are size dependant.
+- `.anims` The anim tables are located in **src/data/field_event_obj/event_object_anims.h**. Most NPCs use gEventObjectImageAnimTable_Standard which allows for the walking animation.
+- `.images` refers to the pic table we just created.
+- `.affineAnims` allows for effects such as rotation and scale, most overworlds use gDummySpriteAffineAnimTable although Groudon and Kyogre do use such effects.
+
+Next we need to add a pointer to our new EventObjectGraphicsInfo and amend the table of pointers within **src/data/field_event_obj/event_object_graphics_info_pointers.h**
+
+First add a declaration before the table of pointers; gEventObjectGraphicsInfoPointers[], then add an entry to the table itself.
+```c
+const struct EventObjectGraphicsInfo gEventObjectGraphicsInfo_Example;
+```
+```c
+const struct EventObjectGraphicsInfo *const gEventObjectGraphicsInfoPointers[] = {
+ // removed for brevity
+ &gEventObjectGraphicsInfo_Brandon,
+ &gEventObjectGraphicsInfo_RubySapphireBrendan,
+ &gEventObjectGraphicsInfo_RubySapphireMay,
+ &gEventObjectGraphicsInfo_Lugia,
+ &gEventObjectGraphicsInfo_HoOh,
++ &gEventObjectGraphicsInfo_Example,
+};
+```
+## 6. Adding a define for your overworld
+Finally we want to add a define for our overworld in **include/constants/event_objects.h** so we can use that as opposed to raw numbers.
+As we've added our overworld to the end of the standard overworld table (i.e before gMauvilleOldManGraphicsInfoPointers[]) we will need to add our define between EVENT_OBJ_GFX_HOOH and EVENT_OBJ_GFX_BARD_2 and update the numbers as necessary.
+```c
+Original
+#define EVENT_OBJ_GFX_LUGIA 237
+#define EVENT_OBJ_GFX_HOOH 238
+
+#define EVENT_OBJ_GFX_BARD_2 239
+#define EVENT_OBJ_GFX_HIPSTER 240
+#define EVENT_OBJ_GFX_TRADER 241
+#define EVENT_OBJ_GFX_STORYTELLER 242
+#define EVENT_OBJ_GFX_GIDDY 243
+#define EVENT_OBJ_GFX_PLACEHOLDER_1 244
+#define EVENT_OBJ_GFX_PLACEHOLDER_2 245
+```
+```c
+Updated
+#define EVENT_OBJ_GFX_LUGIA 237
+#define EVENT_OBJ_GFX_HOOH 238
+#define EVENT_OBJ_GFX_EXAMPLE 239
+
+#define EVENT_OBJ_GFX_BARD_2 240
+#define EVENT_OBJ_GFX_HIPSTER 241
+#define EVENT_OBJ_GFX_TRADER 242
+#define EVENT_OBJ_GFX_STORYTELLER 243
+#define EVENT_OBJ_GFX_GIDDY 244
+#define EVENT_OBJ_GFX_PLACEHOLDER_1 245
+#define EVENT_OBJ_GFX_PLACEHOLDER_2 246
+```
+Note that by default there is a limit of 256 overworlds (0-255) but this can be expanded. Though at the time of writing this tutorial doing so crashes the game and needs more code to be decompiled.
+
+As our final step we need to update NUM_OBJECT_GRAPHICS_INFO and SPRITE_VAR within **include/event_object_movement.h**.
+```c
+Original
+#define NUM_OBJECT_GRAPHICS_INFO 239
+#define SPRITE_VAR 240
+```
+```c
+Updated
+#define NUM_OBJECT_GRAPHICS_INFO 240
+#define SPRITE_VAR 241
+``` \ No newline at end of file