From 2358ee88e375ee9dd2a6b850c6a7642795e51eb1 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Sun, 19 May 2024 12:41:51 +0200 Subject: [PATCH 1/7] Fix virtual object events --- asm/macros/event.inc | 2 +- src/scrcmd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index ef1ba30270..25f688aff1 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1347,7 +1347,7 @@ @ The specified id can be used to refer to the sprite again later with turnvobject. .macro createvobject graphicsId:req, id:req, x:req, y:req, elevation=3, direction=DIR_SOUTH .byte 0xaa - .byte \graphicsId + .2byte \graphicsId .byte \id .2byte \x .2byte \y diff --git a/src/scrcmd.c b/src/scrcmd.c index a3531d3094..64c8c9880c 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1210,10 +1210,10 @@ bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx) bool8 ScrCmd_createvobject(struct ScriptContext *ctx) { - u16 graphicsId = ScriptReadByte(ctx); // Support u16 in createvobject + u16 graphicsId = ScriptReadHalfWord(ctx); // Support u16 in createvobject u8 virtualObjId = ScriptReadByte(ctx); u16 x = VarGet(ScriptReadHalfword(ctx)); - u32 y = VarGet(ScriptReadHalfword(ctx)); + u16 y = VarGet(ScriptReadHalfword(ctx)); u8 elevation = ScriptReadByte(ctx); u8 direction = ScriptReadByte(ctx); From 689f41803da6551a556ba761ad5fdd9658d89548 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Tue, 21 May 2024 09:46:27 +0200 Subject: [PATCH 2/7] fix uppercase typo --- src/scrcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scrcmd.c b/src/scrcmd.c index 64c8c9880c..4083dd82ba 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -1210,7 +1210,7 @@ bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx) bool8 ScrCmd_createvobject(struct ScriptContext *ctx) { - u16 graphicsId = ScriptReadHalfWord(ctx); // Support u16 in createvobject + u16 graphicsId = ScriptReadHalfword(ctx); // Support u16 in createvobject u8 virtualObjId = ScriptReadByte(ctx); u16 x = VarGet(ScriptReadHalfword(ctx)); u16 y = VarGet(ScriptReadHalfword(ctx)); From 0630acce442ae7a2641a602deb71af4bb8a7c3f7 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Mon, 27 May 2024 18:09:12 -0400 Subject: [PATCH 3/7] fix: make `LoadSheetGraphicsInfo` load, then free, tiles Fixes follower pokeball gfx showing garbage for 1 frame when emerging --- src/event_object_movement.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index b8cfb591b3..686bbdd267 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1587,10 +1587,12 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, u32 sheetSpan = GetSpanPerImage(info->oam->shape, info->oam->size); u16 oldTiles = 0; u16 tileStart; + bool32 oldInvisible; if (tag == TAG_NONE) tag = COMP_OW_TILE_TAG_BASE + uuid; if (sprite) { + oldInvisible = sprite->invisible; oldTiles = sprite->sheetTileStart; sprite->sheetTileStart = 0; // mark unused // Note: If sprite was not allocated to use a sheet, @@ -1604,9 +1606,19 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, if (tileStart == TAG_NONE) { struct SpriteFrameImage image = {.size = info->size, .data = info->images->data}; struct SpriteTemplate template = {.tileTag = tag, .images = &image}; - if (oldTiles) - FieldEffectFreeTilesIfUnused(oldTiles); + // Load, then free, in order to avoid displaying garbage data + // before sprite's `sheetTileStart` is repointed tileStart = LoadCompressedSpriteSheetByTemplate(&template, TILE_SIZE_4BPP << sheetSpan); + if (oldTiles) { + FieldEffectFreeTilesIfUnused(oldTiles); + // We weren't able to load the sheet; + // retry (after having freed), and set sprite to invisible until done + if (tileStart <= 0) { + if (sprite) + sprite->invisible = TRUE; + tileStart = LoadCompressedSpriteSheetByTemplate(&template, TILE_SIZE_4BPP << sheetSpan); + } + } // sheet loaded; unload any *other* sheet for sprite } else if (oldTiles && oldTiles != tileStart) { FieldEffectFreeTilesIfUnused(oldTiles); @@ -1616,6 +1628,7 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, sprite->sheetTileStart = tileStart; sprite->sheetSpan = sheetSpan; sprite->usingSheet = TRUE; + sprite->invisible = oldInvisible; } // Going from sheet -> !sheet, reset tile number // (sheet stays loaded) From 88cfd9e2673e462bd1f0bee058c20443ccadda3b Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Thu, 11 Jul 2024 00:01:45 -0400 Subject: [PATCH 4/7] fix: Removed `LoadSpriteSheetByTemplate` offset's dependence on EWRAM memory layout --- gflib/sprite.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gflib/sprite.c b/gflib/sprite.c index 31e320d77d..48d561cdf8 100644 --- a/gflib/sprite.c +++ b/gflib/sprite.c @@ -1496,7 +1496,7 @@ void SetOamMatrixRotationScaling(u8 matrixNum, s16 xScale, s16 yScale, u16 rotat CopyOamMatrix(matrixNum, &matrix); } -u16 LoadSpriteSheet(const struct SpriteSheet *sheet) +static u16 LoadSpriteSheetWithOffset(const struct SpriteSheet *sheet, u32 offset) { s16 tileStart = AllocSpriteTiles(sheet->size / TILE_SIZE_4BPP); @@ -1507,11 +1507,16 @@ u16 LoadSpriteSheet(const struct SpriteSheet *sheet) else { AllocSpriteTileRange(sheet->tag, (u16)tileStart, sheet->size / TILE_SIZE_4BPP); - CpuSmartCopy16(sheet->data, (u8 *)OBJ_VRAM0 + TILE_SIZE_4BPP * tileStart, sheet->size); + CpuSmartCopy16(sheet->data, (u8 *)OBJ_VRAM0 + TILE_SIZE_4BPP * tileStart + offset, sheet->size - offset); return (u16)tileStart; } } +u16 LoadSpriteSheet(const struct SpriteSheet *sheet) +{ + return LoadSpriteSheetWithOffset(sheet, 0); +} + // Like LoadSpriteSheet, but checks if already loaded, and uses template image frames u16 LoadSpriteSheetByTemplate(const struct SpriteTemplate *template, u32 frame, s32 offset) { u16 tileStart; @@ -1521,10 +1526,10 @@ u16 LoadSpriteSheetByTemplate(const struct SpriteTemplate *template, u32 frame, return TAG_NONE; if ((tileStart = GetSpriteTileStartByTag(template->tileTag)) != TAG_NONE) // return if already loaded return tileStart; - sheet.data = template->images[frame].data - offset; + sheet.data = template->images[frame].data; sheet.size = template->images[frame].size; sheet.tag = template->tileTag; - return LoadSpriteSheet(&sheet); + return LoadSpriteSheetWithOffset(&sheet, offset); } void LoadSpriteSheets(const struct SpriteSheet *sheets) From 0fb48e8a9a92e17a885cb08e8c6389b2f34c442e Mon Sep 17 00:00:00 2001 From: pkmnsnfrn Date: Sat, 3 Aug 2024 17:00:28 -0700 Subject: [PATCH 5/7] Fixed expanded OW IDs --- include/battle_tower.h | 4 ++-- src/battle_tower.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/battle_tower.h b/include/battle_tower.h index 8288ffb7ea..710d05b00c 100644 --- a/include/battle_tower.h +++ b/include/battle_tower.h @@ -34,9 +34,9 @@ struct FacilityMon }; extern const u8 gTowerMaleFacilityClasses[30]; -extern const u8 gTowerMaleTrainerGfxIds[30]; +extern const u16 gTowerMaleTrainerGfxIds[30]; extern const u8 gTowerFemaleFacilityClasses[20]; -extern const u8 gTowerFemaleTrainerGfxIds[20]; +extern const u16 gTowerFemaleTrainerGfxIds[20]; extern const u16 gBattleFrontierHeldItems[]; extern const struct FacilityMon gBattleFrontierMons[]; extern const struct BattleFrontierTrainer gBattleFrontierTrainers[]; diff --git a/src/battle_tower.c b/src/battle_tower.c index 91db376e53..42f9801651 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -208,7 +208,7 @@ const u8 gTowerFemaleFacilityClasses[20] = FACILITY_CLASS_LASS }; -const u8 gTowerMaleTrainerGfxIds[30] = +const u16 gTowerMaleTrainerGfxIds[30] = { OBJ_EVENT_GFX_HIKER, OBJ_EVENT_GFX_TUBER_M, @@ -242,7 +242,7 @@ const u8 gTowerMaleTrainerGfxIds[30] = OBJ_EVENT_GFX_HIKER }; -const u8 gTowerFemaleTrainerGfxIds[20] = +const u16 gTowerFemaleTrainerGfxIds[20] = { OBJ_EVENT_GFX_WOMAN_2, OBJ_EVENT_GFX_TUBER_F, @@ -3469,7 +3469,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) u16 FacilityClassToGraphicsId(u8 facilityClass) { - u8 trainerObjectGfxId; + u16 trainerObjectGfxId; u8 i; // Search male classes. From d88834dd586eef503bb677f9425f5876cfb6a05b Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 7 Aug 2024 13:42:18 -0400 Subject: [PATCH 6/7] Backported OBJ_EVENT_GFX_SPECIES macro from Expansion --- data/maps/DesertRuins/map.json | 2 +- data/maps/IslandCave/map.json | 2 +- include/constants/event_objects.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/data/maps/DesertRuins/map.json b/data/maps/DesertRuins/map.json index 80c8f6a483..be0a28481a 100644 --- a/data/maps/DesertRuins/map.json +++ b/data/maps/DesertRuins/map.json @@ -15,7 +15,7 @@ "connections": null, "object_events": [ { - "graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGIROCK", + "graphics_id": "OBJ_EVENT_GFX_SPECIES(REGIROCK)", "x": 8, "y": 7, "elevation": 3, diff --git a/data/maps/IslandCave/map.json b/data/maps/IslandCave/map.json index c6204ff1c5..142ec122d6 100644 --- a/data/maps/IslandCave/map.json +++ b/data/maps/IslandCave/map.json @@ -15,7 +15,7 @@ "connections": 0, "object_events": [ { - "graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGICE", + "graphics_id": "OBJ_EVENT_GFX_SPECIES(REGICE)", "x": 8, "y": 7, "elevation": 3, diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index dc4fdf8870..4eaa82b75d 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -280,6 +280,9 @@ #define OBJ_EVENT_GFX_SPECIES_BITS 11 #define OBJ_EVENT_GFX_SPECIES_MASK ((1 << OBJ_EVENT_GFX_SPECIES_BITS) - 1) +// Used to call a specific species' follower graphics. Useful for static encounters. +#define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE) + #define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE) #define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS) From e6e2285c441ba0b3965365f7a9f7c1919ea53d9c Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Sun, 11 Aug 2024 14:50:38 -0400 Subject: [PATCH 7/7] Added OBJ_EVENT_GFX_SPECIES_SHINY --- include/constants/event_objects.h | 1 + include/constants/species.h | 2 ++ include/data.h | 1 - src/event_object_movement.c | 8 ++++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 4eaa82b75d..2e7ec7939f 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -282,6 +282,7 @@ // Used to call a specific species' follower graphics. Useful for static encounters. #define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE) +#define OBJ_EVENT_GFX_SPECIES_SHINY(name) (SPECIES_##name + OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) #define OW_SPECIES(x) (((x)->graphicsId & OBJ_EVENT_GFX_SPECIES_MASK) - OBJ_EVENT_GFX_MON_BASE) #define OW_FORM(x) ((x)->graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS) diff --git a/include/constants/species.h b/include/constants/species.h index ec60c142ed..e6b6120a4f 100644 --- a/include/constants/species.h +++ b/include/constants/species.h @@ -419,6 +419,8 @@ #define NUM_SPECIES SPECIES_EGG +#define SPECIES_SHINY_TAG 500 + #define SPECIES_UNOWN_B (NUM_SPECIES + 1) #define SPECIES_UNOWN_C (SPECIES_UNOWN_B + 1) #define SPECIES_UNOWN_D (SPECIES_UNOWN_B + 2) diff --git a/include/data.h b/include/data.h index 99b695d72f..ef11242801 100644 --- a/include/data.h +++ b/include/data.h @@ -3,7 +3,6 @@ #include "constants/moves.h" -#define SPECIES_SHINY_TAG 500 #define N_FOLLOWER_HAPPY_MESSAGES 31 #define N_FOLLOWER_NEUTRAL_MESSAGES 14 #define N_FOLLOWER_SAD_MESSAGES 3 diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 77aee61fc0..a19d7a5169 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1672,6 +1672,12 @@ static u8 TrySetupObjectEventSprite(const struct ObjectEventTemplate *objectEven spriteTemplate->tileTag = LoadSheetGraphicsInfo(graphicsInfo, objectEvent->graphicsId, NULL); #endif + if (objectEvent->graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) + { + objectEvent->shiny = TRUE; + objectEvent->graphicsId -= SPECIES_SHINY_TAG; + } + spriteId = CreateSprite(spriteTemplate, 0, 0, 0); if (spriteId == MAX_SPRITES) { @@ -2749,6 +2755,8 @@ const struct ObjectEventGraphicsInfo *GetObjectEventGraphicsInfo(u16 graphicsId) if (graphicsId >= OBJ_EVENT_GFX_VARS && graphicsId <= OBJ_EVENT_GFX_VAR_F) graphicsId = VarGetObjectEventGraphicsId(graphicsId - OBJ_EVENT_GFX_VARS); + if (graphicsId >= OBJ_EVENT_GFX_MON_BASE + SPECIES_SHINY_TAG) + graphicsId -= SPECIES_SHINY_TAG; // graphicsId may contain mon form info if (graphicsId > OBJ_EVENT_GFX_SPECIES_MASK) { form = graphicsId >> OBJ_EVENT_GFX_SPECIES_BITS;