mirror of
https://github.com/resetes12/pokeemerald
synced 2025-10-05 16:02:43 +02:00
Merge branch 'lighting-expanded-id' of https://github.com/aarant/pokeemerald
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
725252905baf28dbb9298dd5fa0daaf0e804a455
|
||||
afbb88d77ada8a636a318ec32b61b4ea849d85ab
|
||||
f861504cfc50941768286c0703d24ab0aaceb88e
|
||||
ebbcb7d025cff716eec5008b5dd2b7d55aa8c3f3
|
||||
ebbcb7d025cff716eec5008b5dd2b7d55aa8c3f3
|
||||
# 24759293+aarant@users.noreply.github.com
|
||||
# meta: cleaned up spacing of lighting code
|
||||
0ae5cb1e39f64955107707bbacd1d6dfc117fc01
|
||||
|
@@ -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
|
||||
|
@@ -15,7 +15,7 @@
|
||||
"connections": 0,
|
||||
"object_events": [
|
||||
{
|
||||
"graphics_id": "OBJ_EVENT_GFX_MON_BASE+SPECIES_REGIROCK",
|
||||
"graphics_id": "OBJ_EVENT_GFX_SPECIES(REGIROCK)",
|
||||
"x": 8,
|
||||
"y": 3,
|
||||
"elevation": 3,
|
||||
|
@@ -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": 3,
|
||||
"elevation": 3,
|
||||
|
@@ -107,4 +107,3 @@ UnionRoom_EventScript_Unused::
|
||||
waitstate
|
||||
releaseall
|
||||
end
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -34,9 +34,9 @@ struct FacilityMon
|
||||
};
|
||||
|
||||
extern const u8 gTowerMaleFacilityClasses[43];
|
||||
extern const u8 gTowerMaleTrainerGfxIds[43];
|
||||
extern const u16 gTowerMaleTrainerGfxIds[43];
|
||||
extern const u8 gTowerFemaleFacilityClasses[27];
|
||||
extern const u8 gTowerFemaleTrainerGfxIds[27];
|
||||
extern const u16 gTowerFemaleTrainerGfxIds[27];
|
||||
extern const u16 gBattleFrontierHeldItems[];
|
||||
extern const struct FacilityMon gBattleFrontierMons[];
|
||||
extern const struct FacilityMon gBattleFrontierMonsSplit[];
|
||||
|
@@ -281,6 +281,10 @@
|
||||
#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 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)
|
||||
|
||||
@@ -324,6 +328,9 @@
|
||||
#define OBJ_KIND_CLONE 255 // Exclusive to FRLG
|
||||
|
||||
// Special object event local ids
|
||||
// Used for link player OWs in CreateLinkPlayerSprite
|
||||
#define OBJ_EVENT_ID_DYNAMIC_BASE 0xF0
|
||||
|
||||
#define OBJ_EVENT_ID_PLAYER 0xFF
|
||||
#define OBJ_EVENT_ID_CAMERA 0x7F
|
||||
#define OBJ_EVENT_ID_FOLLOWER 0xFE
|
||||
|
@@ -469,6 +469,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)
|
||||
|
@@ -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
|
||||
|
@@ -65,7 +65,7 @@ struct FollowerMsgInfoExtended {
|
||||
#define MATCH_SPECIES(species) MATCH_U24(MSG_COND_SPECIES, species)
|
||||
#define MATCH_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, 0)
|
||||
// Checks that follower has *neither* of the two types
|
||||
#define MATCH_NOT_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, TYPE_NONE)
|
||||
#define MATCH_NOT_TYPES(type1, type2) MATCH_U8(MSG_COND_TYPE, type1, type2, TYPE_NONE | 1)
|
||||
#define MATCH_STATUS(status) MATCH_U24(MSG_COND_STATUS, status)
|
||||
#define MATCH_MAPSEC(mapsec) MATCH_U24(MSG_COND_MAPSEC, mapsec)
|
||||
#define MATCH_MAP_RAW(mapGroup, mapNum) MATCH_U8(MSG_COND_MAP, mapGroup, mapNum, 0)
|
||||
|
@@ -14,6 +14,8 @@
|
||||
#define PALETTE_FADE_STATUS_LOADING 0xFF
|
||||
|
||||
#define PALETTES_BG 0x0000FFFF
|
||||
// like PALETTES_BG but excludes UI pals [13, 15]
|
||||
#define PALETTES_MAP 0x00001FFF
|
||||
#define PALETTES_OBJECTS 0xFFFF0000
|
||||
#define PALETTES_ALL (PALETTES_BG | PALETTES_OBJECTS)
|
||||
|
||||
@@ -24,6 +26,11 @@
|
||||
#define OBJ_PLTT_ID(n) (OBJ_PLTT_OFFSET + PLTT_ID(n))
|
||||
#define OBJ_PLTT_ID2(n) (PLTT_ID((n) + 16))
|
||||
|
||||
// Used to determine whether a sprite palette tag
|
||||
// should be excluded from time (and weather) blending
|
||||
#define BLEND_IMMUNE_FLAG (1 << 15)
|
||||
#define IS_BLEND_IMMUNE_TAG(tag) ((tag) & BLEND_IMMUNE_FLAG)
|
||||
|
||||
enum
|
||||
{
|
||||
FAST_FADE_IN_FROM_WHITE,
|
||||
|
@@ -318,7 +318,7 @@ const u8 gTowerFemaleFacilityClasses[27] =
|
||||
FACILITY_CLASS_LEAF
|
||||
};
|
||||
|
||||
const u8 gTowerMaleTrainerGfxIds[43] =
|
||||
const u16 gTowerMaleTrainerGfxIds[43] =
|
||||
{
|
||||
OBJ_EVENT_GFX_HIKER,
|
||||
OBJ_EVENT_GFX_TUBER_M,
|
||||
@@ -365,7 +365,7 @@ const u8 gTowerMaleTrainerGfxIds[43] =
|
||||
OBJ_EVENT_GFX_MAXIE
|
||||
};
|
||||
|
||||
const u8 gTowerFemaleTrainerGfxIds[27] =
|
||||
const u16 gTowerFemaleTrainerGfxIds[27] =
|
||||
{
|
||||
OBJ_EVENT_GFX_WOMAN_2,
|
||||
OBJ_EVENT_GFX_TUBER_F,
|
||||
@@ -3674,7 +3674,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount)
|
||||
|
||||
u16 FacilityClassToGraphicsId(u8 facilityClass)
|
||||
{
|
||||
u8 trainerObjectGfxId;
|
||||
u16 trainerObjectGfxId;
|
||||
u8 i;
|
||||
|
||||
// Search male classes.
|
||||
|
@@ -34,7 +34,7 @@ static const u8 sHappyMsg11[] = _("Your POKéMON has caught the scent of\nsmoke.
|
||||
static const u8 sHappyMsg12[] = _("{STR_VAR_1} is poking at your belly.");
|
||||
static const u8 sHappyMsg13[] = _("Your POKéMON stretched out its body\nand is relaxing.");
|
||||
static const u8 sHappyMsg14[] = _("{STR_VAR_1} looks like it wants to\nlead!");
|
||||
static const u8 sHappyMsg15[] = _("{STR_VAR_1} is doing it's best to\nkeep up with you.");
|
||||
static const u8 sHappyMsg15[] = _("{STR_VAR_1} is doing its best to\nkeep up with you.");
|
||||
static const u8 sHappyMsg16[] = _("{STR_VAR_1} is happily cuddling up\nto you!");
|
||||
static const u8 sHappyMsg17[] = _("{STR_VAR_1} is full of life!");
|
||||
static const u8 sHappyMsg18[] = _("{STR_VAR_1} seems to be very happy!");
|
||||
@@ -134,7 +134,7 @@ const struct FollowerMsgInfo gFollowerUpsetMessages[] = {
|
||||
|
||||
// Unconditional angry messages
|
||||
static const u8 sAngryMsg00[] = _("{STR_VAR_1} let out a roar!");
|
||||
static const u8 sAngryMsg01[] = _("{STR_VAR_1} is making a face like\nits angry!");
|
||||
static const u8 sAngryMsg01[] = _("{STR_VAR_1} is making a face like\nit's angry!");
|
||||
static const u8 sAngryMsg02[] = _("{STR_VAR_1} seems to be angry for\nsome reason.");
|
||||
static const u8 sAngryMsg03[] = _("Your POKéMON turned to face the\nother way, showing a defiant face.");
|
||||
static const u8 sAngryMsg04[] = _("{STR_VAR_1} cried out.");
|
||||
|
@@ -1435,7 +1435,7 @@ u8 GetFirstInactiveObjectEventId(void)
|
||||
|
||||
u8 GetObjectEventIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroupId)
|
||||
{
|
||||
if (localId < OBJ_EVENT_ID_FOLLOWER)
|
||||
if (localId < OBJ_EVENT_ID_DYNAMIC_BASE)
|
||||
return GetObjectEventIdByLocalIdAndMapInternal(localId, mapNum, mapGroupId);
|
||||
|
||||
return GetObjectEventIdByLocalId(localId);
|
||||
@@ -1674,10 +1674,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,
|
||||
@@ -1691,9 +1693,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);
|
||||
@@ -1703,6 +1715,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)
|
||||
@@ -1746,6 +1759,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)
|
||||
{
|
||||
@@ -2317,12 +2336,12 @@ bool32 CheckMsgCondition(const struct MsgCondition *cond, struct Pokemon *mon, u
|
||||
case MSG_COND_TYPE:
|
||||
multi = (SpeciesHasType(species, cond->data.bytes[0]) ||
|
||||
SpeciesHasType(species, cond->data.bytes[1]));
|
||||
// if bytes[2] == TYPE_NONE,
|
||||
// if bytes[2] nonzero,
|
||||
// invert; check that mon has *neither* type!
|
||||
if (cond->data.bytes[2] == 0)
|
||||
return multi;
|
||||
else
|
||||
if (cond->data.bytes[2] != 0)
|
||||
return !multi;
|
||||
else
|
||||
return multi;
|
||||
break;
|
||||
case MSG_COND_STATUS:
|
||||
return (cond->data.raw & mon->status);
|
||||
@@ -2340,7 +2359,9 @@ bool32 CheckMsgCondition(const struct MsgCondition *cond, struct Pokemon *mon, u
|
||||
case MSG_COND_MUSIC:
|
||||
return (cond->data.raw == GetCurrentMapMusic());
|
||||
case MSG_COND_TIME_OF_DAY:
|
||||
return (cond->data.raw == gTimeOfDay);
|
||||
// Must match time of day, have natural light on the map,
|
||||
// and not have weather that obscures the sky
|
||||
return (cond->data.raw == gTimeOfDay && MapHasNaturalLight(gMapHeader.mapType) && GetCurrentWeather() < WEATHER_RAIN);
|
||||
case MSG_COND_NEAR_MB:
|
||||
multi = FindMetatileBehaviorWithinRange(
|
||||
obj->currentCoords.x, obj->currentCoords.y,
|
||||
@@ -2392,9 +2413,11 @@ bool8 ScrFunc_getfolloweraction(struct ScriptContext *ctx) // Essentially a big
|
||||
[FOLLOWER_EMOTION_UPSET] = 15,
|
||||
[FOLLOWER_EMOTION_ANGRY] = 15,
|
||||
[FOLLOWER_EMOTION_PENSIVE] = 15,
|
||||
[FOLLOWER_EMOTION_LOVE] = 0,
|
||||
[FOLLOWER_EMOTION_SURPRISE] = 10,
|
||||
[FOLLOWER_EMOTION_CURIOUS] = 10,
|
||||
[FOLLOWER_EMOTION_MUSIC] = 15,
|
||||
[FOLLOWER_EMOTION_POISONED] = 0,
|
||||
};
|
||||
u32 i, j;
|
||||
bool32 pickedCondition = FALSE;
|
||||
@@ -2422,7 +2445,7 @@ bool8 ScrFunc_getfolloweraction(struct ScriptContext *ctx) // Essentially a big
|
||||
if (GetCurrentWeather() == WEATHER_SUNNY_CLOUDS)
|
||||
condEmotes[condCount++] = (struct SpecialEmote) {.emotion=FOLLOWER_EMOTION_HAPPY, .index=31};
|
||||
// Health & status-related
|
||||
multi = mon->hp * 100 / mon->maxHP;
|
||||
multi = SAFE_DIV(mon->hp * 100, mon->maxHP);
|
||||
if (multi < 20) {
|
||||
emotion_weight[FOLLOWER_EMOTION_SAD] = 30;
|
||||
condEmotes[condCount++] = (struct SpecialEmote) {.emotion=FOLLOWER_EMOTION_SAD, .index=4};
|
||||
@@ -2974,6 +2997,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;
|
||||
|
@@ -64,6 +64,7 @@
|
||||
#include "constants/battle_frontier.h"
|
||||
#include "constants/weather.h"
|
||||
#include "constants/metatile_labels.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "palette.h"
|
||||
#include "constants/metatile_behaviors.h"
|
||||
#include "item.h"
|
||||
@@ -3448,7 +3449,7 @@ void SetDeoxysRockPalette(void)
|
||||
u32 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
|
||||
LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
|
||||
// Set faded to all black, weather blending handled during fade-in
|
||||
CpuFill16(0, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], 32);
|
||||
CpuFill16(RGB_BLACK, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], PLTT_SIZE_4BPP);
|
||||
}
|
||||
|
||||
void SetPCBoxToSendMon(u8 boxId)
|
||||
|
@@ -497,7 +497,7 @@ static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
|
||||
{
|
||||
// don't blend special palettes immune to blending
|
||||
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE ||
|
||||
(curPalIndex >= 16 && GetSpritePaletteTagByPaletteNum(curPalIndex - 16) >> 15))
|
||||
(curPalIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(curPalIndex - 16))))
|
||||
{
|
||||
// No palette change.
|
||||
palOffset += 16;
|
||||
@@ -686,7 +686,7 @@ static void ApplyFogBlend(u8 blendCoeff, u16 blendColor)
|
||||
CpuFastCopy(gPlttBufferUnfaded, gPlttBufferFaded, PLTT_BUFFER_SIZE * 2);
|
||||
UpdatePalettesWithTime(PALETTES_ALL);
|
||||
// Then blend tile palettes [0, 12] faded->faded with fadeIn color
|
||||
BlendPalettesFine(0x1FFF, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
|
||||
BlendPalettesFine(PALETTES_MAP, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
|
||||
|
||||
// Do fog blending on marked sprite palettes
|
||||
for (curPalIndex = 16; curPalIndex < 32; curPalIndex++) {
|
||||
@@ -710,7 +710,7 @@ static bool8 LightenSpritePaletteInFog(u8 paletteIndex)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
if (paletteIndex >= 16 && (GetSpritePaletteTagByPaletteNum(i - 16) >> 15)) // don't blend specialpalette tags
|
||||
if (paletteIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteIndex - 16)))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < gWeatherPtr->lightenedFogSpritePalsCount; i++)
|
||||
|
@@ -1361,20 +1361,20 @@ static void DestroyFogHorizontalSprites(void);
|
||||
|
||||
// Updates just the color of shadows to match special weather blending
|
||||
u8 UpdateShadowColor(u16 color) {
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
|
||||
u16 ALIGNED(4) tempBuffer[16];
|
||||
u16 blendedColor;
|
||||
if (paletteNum != 0xFF) {
|
||||
u16 index = (paletteNum+16)*16+SHADOW_COLOR_INDEX;
|
||||
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
|
||||
// Copy to temporary buffer, blend, and keep just the shadow color index
|
||||
CpuFastCopy(&gPlttBufferFaded[index-SHADOW_COLOR_INDEX], tempBuffer, 32);
|
||||
UpdateSpritePaletteWithTime(paletteNum);
|
||||
blendedColor = gPlttBufferFaded[index];
|
||||
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index-SHADOW_COLOR_INDEX], 32);
|
||||
gPlttBufferFaded[index] = blendedColor;
|
||||
}
|
||||
return paletteNum;
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
|
||||
u16 ALIGNED(4) tempBuffer[16];
|
||||
u16 blendedColor;
|
||||
if (paletteNum < 16) {
|
||||
u16 index = OBJ_PLTT_ID(paletteNum)+SHADOW_COLOR_INDEX;
|
||||
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
|
||||
// Copy to temporary buffer, blend, and keep just the shadow color index
|
||||
CpuFastCopy(&gPlttBufferFaded[index-SHADOW_COLOR_INDEX], tempBuffer, PLTT_SIZE_4BPP);
|
||||
UpdateSpritePaletteWithTime(paletteNum);
|
||||
blendedColor = gPlttBufferFaded[index];
|
||||
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index-SHADOW_COLOR_INDEX], PLTT_SIZE_4BPP);
|
||||
gPlttBufferFaded[index] = blendedColor;
|
||||
}
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
void FogHorizontal_InitVars(void)
|
||||
|
@@ -55,7 +55,7 @@ static const u8* const sFearTexts[] = {sCondMsg29, sCondMsg30, NULL};
|
||||
static const u8 sCondMsg31[] = _("{STR_VAR_1} is taking shelter in the\ngrass from the rain.");
|
||||
static const u8 sCondMsg32[] = _("{STR_VAR_1} seems very cold.");
|
||||
static const u8 sCondMsg33[] = _("{STR_VAR_1} is staring at the sea.");
|
||||
static const u8 sCondMsg34[] = _("Your pokemon is staring intently at\nthe sea!");
|
||||
static const u8 sCondMsg34[] = _("Your POKéMON is staring intently at\nthe sea!");
|
||||
static const u8 sCondMsg35[] = _("{STR_VAR_1} is looking at the\nsurging sea.");
|
||||
static const u8* const sSeaTexts[] = {sCondMsg33, sCondMsg34, sCondMsg35, NULL};
|
||||
static const u8 sCondMsg36[] = _("{STR_VAR_1} is listening to the\nsound of the waterfall.");
|
||||
|
103
src/overworld.c
103
src/overworld.c
@@ -12,6 +12,7 @@
|
||||
#include "field_camera.h"
|
||||
#include "field_control_avatar.h"
|
||||
#include "field_effect.h"
|
||||
#include "field_effect_helpers.h"
|
||||
#include "field_message_box.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "field_screen_effect.h"
|
||||
@@ -61,6 +62,7 @@
|
||||
#include "wild_encounter.h"
|
||||
#include "frontier_util.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "constants/layouts.h"
|
||||
#include "constants/map_types.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
@@ -1535,9 +1537,9 @@ void CB1_Overworld(void)
|
||||
|
||||
const struct BlendSettings gTimeOfDayBlend[] =
|
||||
{
|
||||
[TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE},
|
||||
[TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE},
|
||||
[TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0},
|
||||
[TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE},
|
||||
[TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE},
|
||||
[TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0},
|
||||
};
|
||||
|
||||
u8 UpdateTimeOfDay(void) {
|
||||
@@ -1585,8 +1587,12 @@ u8 UpdateTimeOfDay(void) {
|
||||
}
|
||||
|
||||
bool8 MapHasNaturalLight(u8 mapType) { // Whether a map type is naturally lit/outside
|
||||
return mapType == MAP_TYPE_TOWN || mapType == MAP_TYPE_CITY || mapType == MAP_TYPE_ROUTE
|
||||
|| mapType == MAP_TYPE_OCEAN_ROUTE;
|
||||
return (
|
||||
mapType == MAP_TYPE_TOWN
|
||||
|| mapType == MAP_TYPE_CITY
|
||||
|| mapType == MAP_TYPE_ROUTE
|
||||
|| mapType == MAP_TYPE_OCEAN_ROUTE
|
||||
);
|
||||
}
|
||||
|
||||
// Update & mix day / night bg palettes (into unfaded)
|
||||
@@ -1598,7 +1604,7 @@ void UpdateAltBgPalettes(u16 palettes) {
|
||||
return;
|
||||
palettes &= ~((1 << NUM_PALS_IN_PRIMARY) - 1) | primary->swapPalettes;
|
||||
palettes &= ((1 << NUM_PALS_IN_PRIMARY) - 1) | (secondary->swapPalettes << NUM_PALS_IN_PRIMARY);
|
||||
palettes &= 0x1FFE; // don't blend palette 0, [13,15]
|
||||
palettes &= PALETTES_MAP ^ (1 << 0); // don't blend palette 0, [13,15]
|
||||
palettes >>= 1; // start at palette 1
|
||||
if (!palettes)
|
||||
return;
|
||||
@@ -1615,40 +1621,42 @@ void UpdateAltBgPalettes(u16 palettes) {
|
||||
}
|
||||
|
||||
void UpdatePalettesWithTime(u32 palettes) {
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
u32 i;
|
||||
u32 mask = 1 << 16;
|
||||
if (palettes >= 0x10000)
|
||||
for (i = 0; i < 16; i++, mask <<= 1)
|
||||
if (GetSpritePaletteTagByPaletteNum(i) >> 15) // Don't blend special sprite palette tags
|
||||
palettes &= ~(mask);
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
u32 i;
|
||||
u32 mask = 1 << 16;
|
||||
if (palettes >= (1 << 16))
|
||||
for (i = 0; i < 16; i++, mask <<= 1)
|
||||
if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
|
||||
palettes &= ~(mask);
|
||||
|
||||
palettes &= 0xFFFF1FFF; // Don't blend UI BG palettes [13,15]
|
||||
palettes &= PALETTES_MAP | PALETTES_OBJECTS; // Don't blend UI pals
|
||||
if (!palettes)
|
||||
return;
|
||||
TimeMixPalettes(palettes,
|
||||
gPlttBufferUnfaded,
|
||||
gPlttBufferFaded,
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
|
||||
currentTimeBlend.weight);
|
||||
}
|
||||
return;
|
||||
TimeMixPalettes(
|
||||
palettes,
|
||||
gPlttBufferUnfaded,
|
||||
gPlttBufferFaded,
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
|
||||
currentTimeBlend.weight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
u8 UpdateSpritePaletteWithTime(u8 paletteNum) {
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
u16 offset;
|
||||
if (GetSpritePaletteTagByPaletteNum(paletteNum) >> 15)
|
||||
return paletteNum;
|
||||
offset = (paletteNum + 16) << 4;
|
||||
TimeMixPalettes(1,
|
||||
gPlttBufferUnfaded + offset,
|
||||
gPlttBufferFaded + offset,
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
|
||||
currentTimeBlend.weight);
|
||||
}
|
||||
return paletteNum;
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteNum)))
|
||||
return paletteNum;
|
||||
TimeMixPalettes(
|
||||
1,
|
||||
&gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)],
|
||||
&gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
|
||||
currentTimeBlend.weight
|
||||
);
|
||||
}
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
static void OverworldBasic(void)
|
||||
@@ -1664,19 +1672,20 @@ static void OverworldBasic(void)
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
// Every minute if no palette fade is active, update TOD blending as needed
|
||||
if (!gPaletteFade.active && ++gTimeUpdateCounter >= 3600) {
|
||||
struct TimeBlendSettings cachedBlend = {
|
||||
.time0 = currentTimeBlend.time0,
|
||||
.time1 = currentTimeBlend.time1,
|
||||
.weight = currentTimeBlend.weight,
|
||||
};
|
||||
gTimeUpdateCounter = 0;
|
||||
UpdateTimeOfDay();
|
||||
if (cachedBlend.time0 != currentTimeBlend.time0
|
||||
|| cachedBlend.time1 != currentTimeBlend.time1
|
||||
|| cachedBlend.weight != currentTimeBlend.weight) {
|
||||
struct TimeBlendSettings cachedBlend = {
|
||||
.time0 = currentTimeBlend.time0,
|
||||
.time1 = currentTimeBlend.time1,
|
||||
.weight = currentTimeBlend.weight,
|
||||
};
|
||||
gTimeUpdateCounter = 0;
|
||||
UpdateTimeOfDay();
|
||||
if (cachedBlend.time0 != currentTimeBlend.time0
|
||||
|| cachedBlend.time1 != currentTimeBlend.time1
|
||||
|| cachedBlend.weight != currentTimeBlend.weight)
|
||||
{
|
||||
UpdateAltBgPalettes(PALETTES_BG);
|
||||
UpdatePalettesWithTime(PALETTES_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3429,6 +3438,8 @@ static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion)
|
||||
sprite->coordOffsetEnabled = TRUE;
|
||||
sprite->data[0] = linkPlayerId;
|
||||
objEvent->triggerGroundEffectsOnMove = 0;
|
||||
objEvent->localId = OBJ_EVENT_ID_DYNAMIC_BASE + linkPlayerId;
|
||||
SetUpShadow(objEvent, sprite);
|
||||
}
|
||||
}
|
||||
|
||||
|
123
src/palette.c
123
src/palette.c
@@ -515,25 +515,25 @@ static u8 UpdateTimeOfDayPaletteFade(void)
|
||||
u32 i;
|
||||
u32 j = 1;
|
||||
for (i = 0; i < 16; i++, j <<= 1) { // Mask out palettes that should not be light blended
|
||||
if ((selectedPalettes & j) && !(GetSpritePaletteTagByPaletteNum(i) >> 15))
|
||||
timePalettes |= j;
|
||||
if ((selectedPalettes & j) && !IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
|
||||
timePalettes |= j;
|
||||
}
|
||||
} else { // tile palettes, don't blend [13, 15]
|
||||
timePalettes = selectedPalettes & 0x1FFF;
|
||||
timePalettes = selectedPalettes & PALETTES_MAP;
|
||||
}
|
||||
TimeMixPalettes(timePalettes, src, dst, gPaletteFade.bld0, gPaletteFade.bld1, gPaletteFade.weight);
|
||||
|
||||
// palettes that were not blended above must be copied through
|
||||
if ((copyPalettes = ~timePalettes)) {
|
||||
u16 * src1 = src;
|
||||
u16 * dst1 = dst;
|
||||
while (copyPalettes) {
|
||||
if (copyPalettes & 1)
|
||||
CpuFastCopy(src1, dst1, 32);
|
||||
copyPalettes >>= 1;
|
||||
src1 += 16;
|
||||
dst1 += 16;
|
||||
}
|
||||
u16 * src1 = src;
|
||||
u16 * dst1 = dst;
|
||||
while (copyPalettes) {
|
||||
if (copyPalettes & 1)
|
||||
CpuFastCopy(src1, dst1, 32);
|
||||
copyPalettes >>= 1;
|
||||
src1 += 16;
|
||||
dst1 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, blend from faded->faded with native BlendPalettes
|
||||
@@ -1330,58 +1330,59 @@ void TintPalette_CustomTone(u16 *palette, u16 count, u16 rTone, u16 gTone, u16 b
|
||||
|
||||
// Tints from Unfaded to Faded, using a 15-bit GBA color
|
||||
void TintPalette_RGB_Copy(u16 palOffset, u32 blendColor) {
|
||||
s32 newR, newG, newB, rTone, gTone, bTone;
|
||||
u16 * src = gPlttBufferUnfaded + palOffset;
|
||||
u16 * dst = gPlttBufferFaded + palOffset;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
u16 *srcEnd = src + 16;
|
||||
u16 altBlendIndices = *dst++ = *src++; // color 0 is copied through unchanged
|
||||
u32 altBlendColor;
|
||||
|
||||
newR = ((blendColor << 27) >> 27) << 3;
|
||||
newG = ((blendColor << 22) >> 27) << 3;
|
||||
newB = ((blendColor << 17) >> 27) << 3;
|
||||
|
||||
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
|
||||
// Note that bit 0 of altBlendIndices specifies color 1
|
||||
altBlendColor = src[14]; // color 15
|
||||
if (altBlendColor >> 15) { // Set alternate blend color
|
||||
rTone = ((altBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((altBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((altBlendColor << 17) >> 27) << 3;
|
||||
} else { // Set default blend color
|
||||
rTone = ((defaultBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((defaultBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((defaultBlendColor << 17) >> 27) << 3;
|
||||
s32 newR, newG, newB, rTone, gTone, bTone;
|
||||
u16 * src = gPlttBufferUnfaded + palOffset;
|
||||
u16 * dst = gPlttBufferFaded + palOffset;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
u16 *srcEnd = src + 16;
|
||||
u16 altBlendIndices = *dst++ = *src++; // color 0 is copied through unchanged
|
||||
u32 altBlendColor;
|
||||
|
||||
newR = ((blendColor << 27) >> 27) << 3;
|
||||
newG = ((blendColor << 22) >> 27) << 3;
|
||||
newB = ((blendColor << 17) >> 27) << 3;
|
||||
|
||||
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
|
||||
// Note that bit 0 of altBlendIndices specifies color 1
|
||||
altBlendColor = src[14]; // color 15
|
||||
if (altBlendColor >> 15) { // Set alternate blend color
|
||||
rTone = ((altBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((altBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((altBlendColor << 17) >> 27) << 3;
|
||||
} else { // Set default blend color
|
||||
rTone = ((defaultBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((defaultBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((defaultBlendColor << 17) >> 27) << 3;
|
||||
}
|
||||
} else {
|
||||
altBlendIndices = 0;
|
||||
}
|
||||
} else {
|
||||
altBlendIndices = 0;
|
||||
}
|
||||
while (src != srcEnd) {
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices & 1) {
|
||||
r = (u16)((rTone * r)) >> 8;
|
||||
g = (u16)((gTone * g)) >> 8;
|
||||
b = (u16)((bTone * b)) >> 8;
|
||||
} else { // Use provided blend color
|
||||
r = (u16)((newR * r)) >> 8;
|
||||
g = (u16)((newG * g)) >> 8;
|
||||
b = (u16)((newB * b)) >> 8;
|
||||
while (src != srcEnd) {
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices & 1) {
|
||||
r = (u16)((rTone * r)) >> 8;
|
||||
g = (u16)((gTone * g)) >> 8;
|
||||
b = (u16)((bTone * b)) >> 8;
|
||||
} else { // Use provided blend color
|
||||
r = (u16)((newR * r)) >> 8;
|
||||
g = (u16)((newG * g)) >> 8;
|
||||
b = (u16)((newB * b)) >> 8;
|
||||
}
|
||||
if (r > 31)
|
||||
r = 31;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
src++;
|
||||
*dst++ = RGB2(r, g, b);
|
||||
altBlendIndices >>= 1;
|
||||
}
|
||||
if (r > 31)
|
||||
r = 31;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
src++;
|
||||
*dst++ = RGB2(r, g, b);
|
||||
altBlendIndices >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define tCoeff data[0]
|
||||
|
@@ -385,8 +385,7 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend)
|
||||
if (--pulseBlendPalette->delayCounter == 0xFF)
|
||||
{
|
||||
pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
|
||||
// TODO: Optimize pulse blending
|
||||
CpuFastCopy(gPlttBufferUnfaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, 32);
|
||||
CpuFastCopy(gPlttBufferUnfaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, PLTT_SIZE_4BPP);
|
||||
UpdatePalettesWithTime(1 << (pulseBlendPalette->pulseBlendSettings.paletteOffset >> 4));
|
||||
// pulseBlendSettings has a numColors field, but it is only ever set to 16 (for mirage tower)
|
||||
// So, it's ok to use the fine blending here which blends the entire palette
|
||||
|
@@ -101,16 +101,16 @@ void ShuffleListU16(u16 *list, u16 count, u32 seed)
|
||||
u8 RandomWeightedIndex(u8 *weights, u8 length)
|
||||
{
|
||||
u32 i;
|
||||
u16 random_value;
|
||||
u16 randomValue;
|
||||
u16 weightSum = 0;
|
||||
for (i = 0; i < length; i++)
|
||||
weightSum += weights[i];
|
||||
random_value = Random() % weightSum;
|
||||
randomValue = weightSum > 0 ? Random() % weightSum : 0;
|
||||
weightSum = 0;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
weightSum += weights[i];
|
||||
if (random_value <= weightSum)
|
||||
if (randomValue <= weightSum)
|
||||
return i;
|
||||
}
|
||||
}
|
@@ -1233,10 +1233,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);
|
||||
|
||||
|
Reference in New Issue
Block a user