mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 11:37:40 +01:00
Merge pull request #1604 from GriffinRichards/clean-spinda
Document Spinda spot algorithm
This commit is contained in:
commit
79dfac92c9
@ -239,10 +239,13 @@ struct BattleMove
|
|||||||
u8 flags;
|
u8 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SPINDA_SPOT_WIDTH 16
|
||||||
|
#define SPINDA_SPOT_HEIGHT 16
|
||||||
|
|
||||||
struct SpindaSpot
|
struct SpindaSpot
|
||||||
{
|
{
|
||||||
u8 x, y;
|
u8 x, y;
|
||||||
u16 image[16];
|
u16 image[SPINDA_SPOT_HEIGHT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) LevelUpMove
|
struct __attribute__((packed)) LevelUpMove
|
||||||
|
@ -1345,10 +1345,10 @@ static const u16 sHoennToNationalOrder[NUM_SPECIES - 1] =
|
|||||||
|
|
||||||
const struct SpindaSpot gSpindaSpotGraphics[] =
|
const struct SpindaSpot gSpindaSpotGraphics[] =
|
||||||
{
|
{
|
||||||
{16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")},
|
{.x = 16, .y = 7, .image = INCBIN_U16("graphics/spinda_spots/spot_0.bin")},
|
||||||
{40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")},
|
{.x = 40, .y = 8, .image = INCBIN_U16("graphics/spinda_spots/spot_1.bin")},
|
||||||
{22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")},
|
{.x = 22, .y = 25, .image = INCBIN_U16("graphics/spinda_spots/spot_2.bin")},
|
||||||
{34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")}
|
{.x = 34, .y = 26, .image = INCBIN_U16("graphics/spinda_spots/spot_3.bin")}
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "data/pokemon/item_effects.h"
|
#include "data/pokemon/item_effects.h"
|
||||||
@ -5653,42 +5653,81 @@ u16 SpeciesToCryId(u16 species)
|
|||||||
return gSpeciesIdToCryId[species - (SPECIES_TREECKO - 1)];
|
return gSpeciesIdToCryId[species - (SPECIES_TREECKO - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DRAW_SPINDA_SPOTS \
|
// 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 macro 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 macro 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 on Spinda satisfies the following formula: ((u8)(colorIndex - 1) <= 2). The -1 excludes
|
||||||
|
transparent pixels, as these are index 0. Therefore 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 two different ways in the macro: 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.
|
||||||
|
*/
|
||||||
|
#define DRAW_SPINDA_SPOTS(personality, dest) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
s32 i; \
|
||||||
for (i = 0; i < 4; i++) \
|
for (i = 0; i < (s32)ARRAY_COUNT(gSpindaSpotGraphics); i++) \
|
||||||
{ \
|
{ \
|
||||||
int j; \
|
s32 row; \
|
||||||
u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); \
|
u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); \
|
||||||
u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); \
|
u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); \
|
||||||
\
|
\
|
||||||
for (j = 0; j < 16; j++) \
|
for (row = 0; row < SPINDA_SPOT_HEIGHT; row++) \
|
||||||
{ \
|
{ \
|
||||||
int k; \
|
s32 column; \
|
||||||
s32 row = gSpindaSpotGraphics[i].image[j]; \
|
s32 spotPixelRow = gSpindaSpotGraphics[i].image[row]; \
|
||||||
\
|
\
|
||||||
for (k = x; k < x + 16; k++) \
|
for (column = x; column < x + SPINDA_SPOT_WIDTH; column++) \
|
||||||
{ \
|
{ \
|
||||||
u8 *val = dest + ((k / 8) * 32) + \
|
/* Get target pixels on Spinda's sprite */ \
|
||||||
((k % 8) / 2) + \
|
u8 *destPixels = dest + ((column / 8) * TILE_SIZE_4BPP) + \
|
||||||
((y >> 3) << 8) + \
|
((column % 8) / 2) + \
|
||||||
((y & 7) << 2); \
|
((y / 8) * TILE_SIZE_4BPP * 8) + \
|
||||||
|
((y % 8) * 4); \
|
||||||
\
|
\
|
||||||
if (row & 1) \
|
/* Is this pixel in the 16x16 spot image part of the spot? */ \
|
||||||
|
if (spotPixelRow & 1) \
|
||||||
{ \
|
{ \
|
||||||
if (k & 1) \
|
/* destPixels addressess two pixels, alternate which */ \
|
||||||
|
/* of the two pixels is being considered for drawing */ \
|
||||||
|
if (column & 1) \
|
||||||
{ \
|
{ \
|
||||||
if ((u8)((*val & 0xF0) - 0x10) <= 0x20) \
|
/* Draw spot pixel if this is Spinda's body color */ \
|
||||||
*val += 0x40; \
|
if ((u8)((*destPixels & 0xF0) - (FIRST_SPOT_COLOR << 4))\
|
||||||
|
<= ((LAST_SPOT_COLOR - FIRST_SPOT_COLOR) << 4))\
|
||||||
|
*destPixels += (SPOT_COLOR_ADJUSTMENT << 4); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
if ((u8)((*val & 0xF) - 0x01) <= 0x02) \
|
/* Draw spot pixel if this is Spinda's body color */ \
|
||||||
*val += 0x04; \
|
if ((u8)((*destPixels & 0xF) - FIRST_SPOT_COLOR) \
|
||||||
|
<= (LAST_SPOT_COLOR - FIRST_SPOT_COLOR)) \
|
||||||
|
*destPixels += SPOT_COLOR_ADJUSTMENT; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
row >>= 1; \
|
spotPixelRow >>= 1; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
y++; \
|
y++; \
|
||||||
@ -5705,13 +5744,13 @@ static void DrawSpindaSpotsUnused(u16 species, u32 personality, u8 *dest)
|
|||||||
if (species == SPECIES_SPINDA
|
if (species == SPECIES_SPINDA
|
||||||
&& dest != gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT]
|
&& dest != gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT]
|
||||||
&& dest != gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_RIGHT])
|
&& dest != gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_RIGHT])
|
||||||
DRAW_SPINDA_SPOTS;
|
DRAW_SPINDA_SPOTS(personality, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, bool8 isFrontPic)
|
void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, bool8 isFrontPic)
|
||||||
{
|
{
|
||||||
if (species == SPECIES_SPINDA && isFrontPic)
|
if (species == SPECIES_SPINDA && isFrontPic)
|
||||||
DRAW_SPINDA_SPOTS;
|
DRAW_SPINDA_SPOTS(personality, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
|
void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
|
||||||
|
Loading…
Reference in New Issue
Block a user