mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Merge 45e1af321a into 47cac73a61
This commit is contained in:
commit
00f1ea26ab
|
|
@ -605,15 +605,6 @@ struct NatureInfo
|
|||
const u8 *natureGirlMessage;
|
||||
};
|
||||
|
||||
#define SPINDA_SPOT_WIDTH 16
|
||||
#define SPINDA_SPOT_HEIGHT 16
|
||||
|
||||
struct SpindaSpot
|
||||
{
|
||||
u8 x, y;
|
||||
u16 image[SPINDA_SPOT_HEIGHT];
|
||||
};
|
||||
|
||||
struct LevelUpMove
|
||||
{
|
||||
enum Move move;
|
||||
|
|
@ -853,7 +844,6 @@ enum HoennDexOrder SpeciesToHoennPokedexNum(enum Species species);
|
|||
enum NationalDexOrder RegionalToNationalOrder(u32 regionNum);
|
||||
enum NationalDexOrder KantoToNationalOrder(enum KantoDexOrder kantoNum);
|
||||
enum NationalDexOrder HoennToNationalOrder(enum HoennDexOrder hoennNum);
|
||||
void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame);
|
||||
void EvolutionRenameMon(struct Pokemon *mon, enum Species oldSpecies, enum Species newSpecies);
|
||||
u8 GetPlayerFlankId(void);
|
||||
u16 GetLinkTrainerFlankId(u8 linkPlayerId);
|
||||
|
|
|
|||
31
include/pokemon_spots.h
Normal file
31
include/pokemon_spots.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef GUARD_POKEMON_SPOTS_H
|
||||
#define GUARD_POKEMON_SPOTS_H
|
||||
|
||||
enum SpotAnimFrame {
|
||||
FRAME_1,
|
||||
FRAME_2
|
||||
};
|
||||
|
||||
struct MonSpot {
|
||||
u8 x, y;
|
||||
const u32* image;
|
||||
};
|
||||
|
||||
struct MonSpotTemplate {
|
||||
const struct MonSpot* spots;
|
||||
u8 count;
|
||||
u8 scale;
|
||||
s8 xOffsetFrame2;
|
||||
s8 yOffsetFrame2;
|
||||
u8 firstColor;
|
||||
u8 lastColor;
|
||||
u8 colorAdjust;
|
||||
};
|
||||
|
||||
extern const struct MonSpotTemplate* const gSpottedSpecies[];
|
||||
|
||||
bool32 ShouldDrawSpotsOnSpecies(enum Species species);
|
||||
void DrawPokemonSpots(u32 personality, const struct MonSpotTemplate* spotTemplate, u8 *dest, enum SpotAnimFrame SpotAnimFrame);
|
||||
void DrawPokemonSpotsBothFrames(u32 personality, const struct MonSpotTemplate* spotTemplate, u8* dest);
|
||||
|
||||
#endif /* end of include guard: GUARD_POKEMON_SPOTS_H */
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include "decompress.h"
|
||||
#include "decompress_error_handler.h"
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_spots.h"
|
||||
#include "pokemon_sprite_visualizer.h"
|
||||
#include "text.h"
|
||||
#include "menu.h"
|
||||
|
|
@ -1172,10 +1173,9 @@ void LoadSpecialPokePicIsEgg(void *dest, enum Species species, u32 personality,
|
|||
DecompressDataWithHeaderWram(gSpeciesInfo[SPECIES_NONE].backPic, dest);
|
||||
}
|
||||
|
||||
if (species == SPECIES_SPINDA && isFrontPic)
|
||||
if (ShouldDrawSpotsOnSpecies(species) && isFrontPic)
|
||||
{
|
||||
DrawSpindaSpots(personality, dest, FALSE);
|
||||
DrawSpindaSpots(personality, dest, TRUE);
|
||||
DrawPokemonSpotsBothFrames(personality, gSpottedSpecies[species], dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
108
src/pokemon.c
108
src/pokemon.c
|
|
@ -631,14 +631,6 @@ static const enum NationalDexOrder sHoennToNationalOrder[HOENN_DEX_COUNT - 1] =
|
|||
HOENN_TO_NATIONAL(DEOXYS),
|
||||
};
|
||||
|
||||
const struct SpindaSpot gSpindaSpotGraphics[] =
|
||||
{
|
||||
{.x = 16, .y = 7, .image = INCBIN_U16("graphics/pokemon/spinda/spots/spot_0.1bpp")},
|
||||
{.x = 40, .y = 8, .image = INCBIN_U16("graphics/pokemon/spinda/spots/spot_1.1bpp")},
|
||||
{.x = 22, .y = 25, .image = INCBIN_U16("graphics/pokemon/spinda/spots/spot_2.1bpp")},
|
||||
{.x = 34, .y = 26, .image = INCBIN_U16("graphics/pokemon/spinda/spots/spot_3.1bpp")}
|
||||
};
|
||||
|
||||
// In Battle Palace, moves are chosen based on the pokemons nature rather than by the player
|
||||
// Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*)
|
||||
// Each nature has a certain percent chance of selecting a move from a particular group
|
||||
|
|
@ -5293,106 +5285,6 @@ enum NationalDexOrder HoennToNationalOrder(enum HoennDexOrder hoennNum)
|
|||
return sHoennToNationalOrder[hoennNum - 1];
|
||||
}
|
||||
|
||||
// Spots can be drawn on Spinda's color indexes 1, 2, or 3
|
||||
#define FIRST_SPOT_COLOR 1
|
||||
#define LAST_SPOT_COLOR 3
|
||||
|
||||
// To draw a spot pixel, add 4 to the color index
|
||||
#define SPOT_COLOR_ADJUSTMENT 4
|
||||
/*
|
||||
The function below handles drawing the randomly-placed spots on Spinda's front sprite.
|
||||
Spinda has 4 spots, each with an entry in gSpindaSpotGraphics. Each entry contains
|
||||
a base x and y coordinate for the spot and a 16x16 binary image. Each bit in the image
|
||||
determines whether that pixel should be considered part of the spot.
|
||||
|
||||
The position of each spot is randomized using the Spinda's personality. The entire 32 bit
|
||||
personality value is used, 4 bits for each coordinate of the 4 spots. If the personality
|
||||
value is 0x87654321, then 0x1 will be used for the 1st spot's x coord, 0x2 will be used for
|
||||
the 1st spot's y coord, 0x3 will be used for the 2nd spot's x coord, and so on. Each
|
||||
coordinate is calculated as (baseCoord + (given 4 bits of personality) - 8). In effect this
|
||||
means each spot can start at any position -8 to +7 off of its base coordinates (256 possibilities).
|
||||
|
||||
The function then loops over the 16x16 spot image. For each bit in the spot's binary image, if
|
||||
the bit is set then it's part of the spot; try to draw it. A pixel is drawn on Spinda if the
|
||||
pixel is between FIRST_SPOT_COLOR and LAST_SPOT_COLOR (so only colors 1, 2, or 3 on Spinda will
|
||||
allow a spot to be drawn). These color indexes are Spinda's light brown body colors. To create
|
||||
the spot it adds 4 to the color index, so Spinda's spots will be colors 5, 6, and 7.
|
||||
|
||||
The above is done in TRY_DRAW_SPOT_PIXEL two different ways: one with << 4, and one without.
|
||||
This is because Spinda's sprite is a 4 bits per pixel image, but the pointer to Spinda's pixels
|
||||
(destPixels) is an 8 bit pointer, so it addresses two pixels. Shifting by 4 accesses the 2nd
|
||||
of these pixels, so this is done every other time.
|
||||
*/
|
||||
|
||||
// Draw spot pixel if this is Spinda's body color
|
||||
#define TRY_DRAW_SPOT_PIXEL(pixels, shift) \
|
||||
if (((*(pixels) & (0xF << (shift))) >= (FIRST_SPOT_COLOR << (shift))) \
|
||||
&& ((*(pixels) & (0xF << (shift))) <= (LAST_SPOT_COLOR << (shift)))) \
|
||||
{ \
|
||||
*(pixels) += (SPOT_COLOR_ADJUSTMENT << (shift)); \
|
||||
}
|
||||
|
||||
|
||||
void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < (s32)ARRAY_COUNT(gSpindaSpotGraphics); i++)
|
||||
{
|
||||
s32 row;
|
||||
u8 x = gSpindaSpotGraphics[i].x + (personality & 0x0F);
|
||||
u8 y = gSpindaSpotGraphics[i].y + ((personality & 0xF0) >> 4);
|
||||
|
||||
if (isSecondFrame)
|
||||
{
|
||||
x -= 12;
|
||||
y += 56;
|
||||
}
|
||||
else
|
||||
{
|
||||
x -= 8;
|
||||
y -= 8;
|
||||
}
|
||||
|
||||
for (row = 0; row < SPINDA_SPOT_HEIGHT; row++)
|
||||
{
|
||||
s32 column;
|
||||
s32 spotPixelRow = gSpindaSpotGraphics[i].image[row];
|
||||
|
||||
for (column = x; column < x + SPINDA_SPOT_WIDTH; column++)
|
||||
{
|
||||
/* Get target pixels on Spinda's sprite */
|
||||
u8 *destPixels = dest + ((column / 8) * TILE_SIZE_4BPP) +
|
||||
((column % 8) / 2) +
|
||||
((y / 8) * TILE_SIZE_4BPP * 8) +
|
||||
((y % 8) * 4);
|
||||
|
||||
/* Is this pixel in the 16x16 spot image part of the spot? */
|
||||
if (spotPixelRow & 1)
|
||||
{
|
||||
/* destPixels addressess two pixels, alternate which */
|
||||
/* of the two pixels is being considered for drawing */
|
||||
if (column & 1)
|
||||
{
|
||||
/* Draw spot pixel if this is Spinda's body color */
|
||||
TRY_DRAW_SPOT_PIXEL(destPixels, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Draw spot pixel if this is Spinda's body color */
|
||||
TRY_DRAW_SPOT_PIXEL(destPixels, 0);
|
||||
}
|
||||
}
|
||||
|
||||
spotPixelRow >>= 1;
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
personality >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionRenameMon(struct Pokemon *mon, enum Species oldSpecies, enum Species newSpecies)
|
||||
{
|
||||
u8 language;
|
||||
|
|
|
|||
114
src/pokemon_spots.c
Normal file
114
src/pokemon_spots.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#include "global.h"
|
||||
#include "constants/species.h"
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_spots.h"
|
||||
|
||||
#define EVEN_PIXEL_SHIFT 0
|
||||
#define ODD_PIXEL_SHIFT 4
|
||||
#define FRAME_SIZE 64
|
||||
|
||||
#define MON_SPOT(name, idx, _x, _y) \
|
||||
{.x = _x, .y =_y, .image = s##name##SpotImages[idx]},
|
||||
|
||||
/* Define Spots Below */
|
||||
|
||||
// SPECIES_SPINDA
|
||||
static const u32 sSpindaSpotImages[4][8] = {
|
||||
INCBIN_U32("graphics/pokemon/spinda/spots/spot_0.1bpp"),
|
||||
INCBIN_U32("graphics/pokemon/spinda/spots/spot_1.1bpp"),
|
||||
INCBIN_U32("graphics/pokemon/spinda/spots/spot_2.1bpp"),
|
||||
INCBIN_U32("graphics/pokemon/spinda/spots/spot_3.1bpp"),
|
||||
};
|
||||
static const struct MonSpot sSpindaSpots[] = {
|
||||
MON_SPOT(Spinda, 0, 16, 7)
|
||||
MON_SPOT(Spinda, 1, 40, 8)
|
||||
MON_SPOT(Spinda, 2, 22, 27)
|
||||
MON_SPOT(Spinda, 3, 34, 26)
|
||||
};
|
||||
const struct MonSpotTemplate gSpindaSpotTemplate = {
|
||||
.spots = sSpindaSpots,
|
||||
.count = ARRAY_COUNT(sSpindaSpots),
|
||||
.scale = 1,
|
||||
.xOffsetFrame2 = -4,
|
||||
.yOffsetFrame2 = 0,
|
||||
.firstColor = 1,
|
||||
.lastColor = 3,
|
||||
.colorAdjust = 4,
|
||||
};
|
||||
|
||||
/* End of Spot Defintions */
|
||||
|
||||
const struct MonSpotTemplate* const gSpottedSpecies[NUM_SPECIES] = {[SPECIES_SPINDA] = &gSpindaSpotTemplate};
|
||||
|
||||
static inline void TryDrawSpotPixel(u8* pixels, u8 pixelShift, u8 firstColor, u8 lastColor, u8 spotColorAdjust)
|
||||
{
|
||||
u8 pixel = (*pixels >> pixelShift) & 0xF;
|
||||
if ((u8)(pixel - firstColor) <= (lastColor - firstColor))
|
||||
*pixels += (spotColorAdjust << pixelShift);
|
||||
}
|
||||
|
||||
bool32 ShouldDrawSpotsOnSpecies(enum Species species)
|
||||
{
|
||||
return gSpottedSpecies[SanitizeSpeciesId(species)] != NULL;
|
||||
}
|
||||
|
||||
static inline u32 GetSpotRow(const u32* image, u32 row, u32 size)
|
||||
{
|
||||
u32 numRows = 32 / size;
|
||||
u32 packedRow = row / numRows;
|
||||
u32 idx = row & (numRows - 1);
|
||||
|
||||
return (image[packedRow] >> (idx * size)) & ((size == 32) ? 0xFFFFFFFFu : ((1u << size) - 1));
|
||||
}
|
||||
|
||||
void DrawPokemonSpots(u32 personality, const struct MonSpotTemplate* spotTemplate, u8* dest,
|
||||
enum SpotAnimFrame spotAnimFrame)
|
||||
{
|
||||
u8 size = 16 * spotTemplate->scale; // We only expect square spots
|
||||
u32 i;
|
||||
for (i = 0; i < spotTemplate->count; i++) {
|
||||
const struct MonSpot* spot = &spotTemplate->spots[i];
|
||||
u16 x = spot->x + (personality & 0x0F) * spotTemplate->scale;
|
||||
u8 y = spot->y + ((personality & 0xF0) >> 4) * spotTemplate->scale;
|
||||
|
||||
switch (spotAnimFrame) {
|
||||
case FRAME_1:
|
||||
x -= size / 2;
|
||||
y -= size / 2;
|
||||
break;
|
||||
|
||||
case FRAME_2:
|
||||
x += spotTemplate->xOffsetFrame2 - size / 2;
|
||||
y += FRAME_SIZE + spotTemplate->yOffsetFrame2 - size / 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 row = 0; row < size; row++) {
|
||||
u32 spotPixelRow = GetSpotRow(spot->image, row, size);
|
||||
for (u32 column = x; column < x + size; column++) {
|
||||
u8* destPixels = dest + ((column / 8) * TILE_SIZE_4BPP) + ((column % 8) / 2) +
|
||||
((y / 8) * TILE_SIZE_4BPP * 8) + ((y % 8) * 4);
|
||||
|
||||
if (spotPixelRow & 1) {
|
||||
TryDrawSpotPixel(destPixels, (column & 1 ? 4 : 0), spotTemplate->firstColor,
|
||||
spotTemplate->lastColor, spotTemplate->colorAdjust);
|
||||
}
|
||||
|
||||
spotPixelRow >>= 1;
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
personality >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPokemonSpotsBothFrames(u32 personality, const struct MonSpotTemplate* spotTemplate, u8* dest)
|
||||
{
|
||||
DrawPokemonSpots(personality, spotTemplate, dest, FALSE);
|
||||
DrawPokemonSpots(personality, spotTemplate, dest, TRUE);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user