Document fieldmap

This commit is contained in:
GriffinR 2021-04-06 16:05:43 -04:00
parent 8bad478b49
commit 86a9d94ce1
8 changed files with 66 additions and 73 deletions

View File

@ -241,5 +241,6 @@
#define MB_UNUSED_ED 0xED #define MB_UNUSED_ED 0xED
#define MB_UNUSED_EE 0xEE #define MB_UNUSED_EE 0xEE
#define MB_UNUSED_EF 0xEF #define MB_UNUSED_EF 0xEF
#define MB_INVALID 0xFF
#endif // GUARD_METATILE_BEHAVIORS #endif // GUARD_METATILE_BEHAVIORS

View File

@ -20,16 +20,13 @@ void MapGridSetMetatileEntryAt(int, int, u16);
void GetCameraCoords(u16*, u16*); void GetCameraCoords(u16*, u16*);
bool8 MapGridIsImpassableAt(int, int); bool8 MapGridIsImpassableAt(int, int);
int GetMapBorderIdAt(int x, int y); int GetMapBorderIdAt(int x, int y);
int CanCameraMoveInDirection(int direction); bool32 CanCameraMoveInDirection(int direction);
u16 GetBehaviorByMetatileId(u16 metatileId); u16 GetBehaviorByMetatileId(u16 metatileId);
void GetCameraFocusCoords(u16 *x, u16 *y); void GetCameraFocusCoords(u16 *x, u16 *y);
u8 MapGridGetMetatileLayerTypeAt(int x, int y); u8 MapGridGetMetatileLayerTypeAt(int x, int y);
u8 MapGridGetZCoordAt(int x, int y); u8 MapGridGetZCoordAt(int x, int y);
bool8 CameraMove(int deltaX, int deltaY); bool8 CameraMove(int deltaX, int deltaY);
struct MapConnection *sub_8088950(u8 direction, int x, int y); void SaveMapView(void);
bool8 sub_80889A8(u8 direction, int x, int y, struct MapConnection *connection);
bool8 sub_8088A0C(int x, int src_width, int dest_width, int offset);
void save_serialize_map(void);
void SetCameraFocusCoords(u16 x, u16 y); void SetCameraFocusCoords(u16 x, u16 y);
void InitMap(void); void InitMap(void);
void InitMapFromSavedGame(void); void InitMapFromSavedGame(void);

View File

@ -1,6 +1,7 @@
#ifndef GUARD_GLOBAL_FIELDMAP_H #ifndef GUARD_GLOBAL_FIELDMAP_H
#define GUARD_GLOBAL_FIELDMAP_H #define GUARD_GLOBAL_FIELDMAP_H
#define METATILE_BEHAVIOR_MASK 0x00FF
#define METATILE_COLLISION_MASK 0x0C00 #define METATILE_COLLISION_MASK 0x0C00
#define METATILE_ID_MASK 0x03FF #define METATILE_ID_MASK 0x03FF
#define METATILE_ID_UNDEFINED 0x03FF #define METATILE_ID_UNDEFINED 0x03FF
@ -12,7 +13,9 @@
enum enum
{ {
CONNECTION_SOUTH = 1, CONNECTION_INVALID = -1,
CONNECTION_NONE,
CONNECTION_SOUTH,
CONNECTION_NORTH, CONNECTION_NORTH,
CONNECTION_WEST, CONNECTION_WEST,
CONNECTION_EAST, CONNECTION_EAST,

View File

@ -711,7 +711,7 @@ static void SavePikeChallenge(void)
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005; gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_0, 0); VarSet(VAR_TEMP_0, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE; gSaveBlock2Ptr->frontier.challengePaused = TRUE;
save_serialize_map(); SaveMapView();
TrySavingData(SAVE_LINK); TrySavingData(SAVE_LINK);
} }

View File

@ -933,7 +933,7 @@ static void SavePyramidChallenge(void)
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005; gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_0, 0); VarSet(VAR_TEMP_0, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE; gSaveBlock2Ptr->frontier.challengePaused = TRUE;
save_serialize_map(); SaveMapView();
TrySavingData(SAVE_LINK); TrySavingData(SAVE_LINK);
} }

View File

@ -15,6 +15,7 @@
#include "trainer_hill.h" #include "trainer_hill.h"
#include "tv.h" #include "tv.h"
#include "constants/rgb.h" #include "constants/rgb.h"
#include "constants/metatile_behaviors.h"
struct ConnectionFlags struct ConnectionFlags
{ {
@ -43,6 +44,9 @@ static void FillEastConnection(struct MapHeader const *mapHeader, struct MapHead
static void InitBackupMapLayoutConnections(struct MapHeader *mapHeader); static void InitBackupMapLayoutConnections(struct MapHeader *mapHeader);
static void LoadSavedMapView(void); static void LoadSavedMapView(void);
static bool8 SkipCopyingMetatileFromSavedMap(u16* mapMetatilePtr, u16 mapWidth, u8 yMode); static bool8 SkipCopyingMetatileFromSavedMap(u16* mapMetatilePtr, u16 mapWidth, u8 yMode);
static struct MapConnection *GetIncomingConnection(u8 direction, int x, int y);
static bool8 IsPosInIncomingConnectingMap(u8 direction, int x, int y, struct MapConnection *connection);
static bool8 IsCoordInIncomingConnectingMap(int coord, int srcMax, int destMax, int offset);
struct MapHeader const *const GetMapHeaderFromConnection(struct MapConnection *connection) struct MapHeader const *const GetMapHeaderFromConnection(struct MapConnection *connection)
{ {
@ -149,7 +153,7 @@ static void InitBackupMapLayoutConnections(struct MapHeader *mapHeader)
} }
} }
static void sub_8087F54(int x, int y, struct MapHeader const *connectedMapHeader, int x2, int y2, int width, int height) static void FillConnection(int x, int y, struct MapHeader const *connectedMapHeader, int x2, int y2, int width, int height)
{ {
int i; int i;
u16 *src; u16 *src;
@ -207,7 +211,7 @@ static void FillSouthConnection(struct MapHeader const *mapHeader, struct MapHea
} }
} }
sub_8087F54( FillConnection(
x, y, x, y,
connectedMapHeader, connectedMapHeader,
x2, /*y2*/ 0, x2, /*y2*/ 0,
@ -255,7 +259,7 @@ static void FillNorthConnection(struct MapHeader const *mapHeader, struct MapHea
} }
} }
sub_8087F54( FillConnection(
x, /*y*/ 0, x, /*y*/ 0,
connectedMapHeader, connectedMapHeader,
x2, y2, x2, y2,
@ -302,7 +306,7 @@ static void FillWestConnection(struct MapHeader const *mapHeader, struct MapHead
} }
} }
sub_8087F54( FillConnection(
/*x*/ 0, y, /*x*/ 0, y,
connectedMapHeader, connectedMapHeader,
x2, y2, x2, y2,
@ -347,7 +351,7 @@ static void FillEastConnection(struct MapHeader const *mapHeader, struct MapHead
} }
} }
sub_8087F54( FillConnection(
x, y, x, y,
connectedMapHeader, connectedMapHeader,
/*x2*/ 0, y2, /*x2*/ 0, y2,
@ -458,7 +462,7 @@ u32 MapGridGetMetatileBehaviorAt(int x, int y)
{ {
u16 metatile; u16 metatile;
metatile = MapGridGetMetatileIdAt(x, y); metatile = MapGridGetMetatileIdAt(x, y);
return GetBehaviorByMetatileId(metatile) & 0xff; return GetBehaviorByMetatileId(metatile) & METATILE_BEHAVIOR_MASK;
} }
u8 MapGridGetMetatileLayerTypeAt(int x, int y) u8 MapGridGetMetatileLayerTypeAt(int x, int y)
@ -505,11 +509,11 @@ u16 GetBehaviorByMetatileId(u16 metatile)
} }
else else
{ {
return 0xFF; return MB_INVALID;
} }
} }
void save_serialize_map(void) void SaveMapView(void)
{ {
int i, j; int i, j;
int x, y; int x, y;
@ -595,7 +599,7 @@ static void LoadSavedMapView(void)
} }
} }
void sub_80885C4(u8 a1) static void MoveMapViewToBackup(u8 direction)
{ {
int width; int width;
u16 *mapView; u16 *mapView;
@ -614,7 +618,7 @@ void sub_80885C4(u8 a1)
y0 = gSaveBlock1Ptr->pos.y; y0 = gSaveBlock1Ptr->pos.y;
x2 = 15; x2 = 15;
y2 = 14; y2 = 14;
switch (a1) switch (direction)
{ {
case CONNECTION_NORTH: case CONNECTION_NORTH:
y0 += 1; y0 += 1;
@ -680,14 +684,14 @@ int GetMapBorderIdAt(int x, int y)
} }
goto success; goto success;
fail: fail:
return -1; return CONNECTION_INVALID;
success: success:
if (x >= (gBackupMapLayout.width - 8)) if (x >= (gBackupMapLayout.width - 8))
{ {
if (!gMapConnectionFlags.east) if (!gMapConnectionFlags.east)
{ {
return -1; return CONNECTION_INVALID;
} }
return CONNECTION_EAST; return CONNECTION_EAST;
} }
@ -695,7 +699,7 @@ success:
{ {
if (!gMapConnectionFlags.west) if (!gMapConnectionFlags.west)
{ {
return -1; return CONNECTION_INVALID;
} }
return CONNECTION_WEST; return CONNECTION_WEST;
} }
@ -703,7 +707,7 @@ success:
{ {
if (!gMapConnectionFlags.south) if (!gMapConnectionFlags.south)
{ {
return -1; return CONNECTION_INVALID;
} }
return CONNECTION_SOUTH; return CONNECTION_SOUTH;
} }
@ -711,13 +715,13 @@ success:
{ {
if (!gMapConnectionFlags.north) if (!gMapConnectionFlags.north)
{ {
return -1; return CONNECTION_INVALID;
} }
return CONNECTION_NORTH; return CONNECTION_NORTH;
} }
else else
{ {
return 0; return CONNECTION_NONE;
} }
} }
@ -726,19 +730,19 @@ int GetPostCameraMoveMapBorderId(int x, int y)
return GetMapBorderIdAt(gSaveBlock1Ptr->pos.x + 7 + x, gSaveBlock1Ptr->pos.y + 7 + y); return GetMapBorderIdAt(gSaveBlock1Ptr->pos.x + 7 + x, gSaveBlock1Ptr->pos.y + 7 + y);
} }
int CanCameraMoveInDirection(int direction) bool32 CanCameraMoveInDirection(int direction)
{ {
int x, y; int x, y;
x = gSaveBlock1Ptr->pos.x + 7 + gDirectionToVectors[direction].x; x = gSaveBlock1Ptr->pos.x + 7 + gDirectionToVectors[direction].x;
y = gSaveBlock1Ptr->pos.y + 7 + gDirectionToVectors[direction].y; y = gSaveBlock1Ptr->pos.y + 7 + gDirectionToVectors[direction].y;
if (GetMapBorderIdAt(x, y) == -1) if (GetMapBorderIdAt(x, y) == -1)
{ {
return 0; return FALSE;
} }
return 1; return TRUE;
} }
void sub_80887F8(struct MapConnection *connection, int direction, int x, int y) static void SetPositionFromConnection(struct MapConnection *connection, int direction, int x, int y)
{ {
struct MapHeader const *mapHeader; struct MapHeader const *mapHeader;
mapHeader = GetMapHeaderFromConnection(connection); mapHeader = GetMapHeaderFromConnection(connection);
@ -765,69 +769,57 @@ void sub_80887F8(struct MapConnection *connection, int direction, int x, int y)
bool8 CameraMove(int x, int y) bool8 CameraMove(int x, int y)
{ {
unsigned int direction; int direction;
struct MapConnection *connection; struct MapConnection *connection;
int old_x, old_y; int old_x, old_y;
gCamera.active = FALSE; gCamera.active = FALSE;
direction = GetPostCameraMoveMapBorderId(x, y); direction = GetPostCameraMoveMapBorderId(x, y);
if (direction + 1 <= 1) if (direction == CONNECTION_NONE || direction == CONNECTION_INVALID)
{ {
gSaveBlock1Ptr->pos.x += x; gSaveBlock1Ptr->pos.x += x;
gSaveBlock1Ptr->pos.y += y; gSaveBlock1Ptr->pos.y += y;
} }
else else
{ {
save_serialize_map(); SaveMapView();
ClearMirageTowerPulseBlendEffect(); ClearMirageTowerPulseBlendEffect();
old_x = gSaveBlock1Ptr->pos.x; old_x = gSaveBlock1Ptr->pos.x;
old_y = gSaveBlock1Ptr->pos.y; old_y = gSaveBlock1Ptr->pos.y;
connection = sub_8088950(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y); connection = GetIncomingConnection(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y);
sub_80887F8(connection, direction, x, y); SetPositionFromConnection(connection, direction, x, y);
LoadMapFromCameraTransition(connection->mapGroup, connection->mapNum); LoadMapFromCameraTransition(connection->mapGroup, connection->mapNum);
gCamera.active = TRUE; gCamera.active = TRUE;
gCamera.x = old_x - gSaveBlock1Ptr->pos.x; gCamera.x = old_x - gSaveBlock1Ptr->pos.x;
gCamera.y = old_y - gSaveBlock1Ptr->pos.y; gCamera.y = old_y - gSaveBlock1Ptr->pos.y;
gSaveBlock1Ptr->pos.x += x; gSaveBlock1Ptr->pos.x += x;
gSaveBlock1Ptr->pos.y += y; gSaveBlock1Ptr->pos.y += y;
sub_80885C4(direction); MoveMapViewToBackup(direction);
} }
return gCamera.active; return gCamera.active;
} }
struct MapConnection *sub_8088950(u8 direction, int x, int y) static struct MapConnection *GetIncomingConnection(u8 direction, int x, int y)
{ {
int count; int count;
int i; int i;
struct MapConnection *connection; struct MapConnection *connection;
const struct MapConnections *connections = gMapHeader.connections; const struct MapConnections *connections = gMapHeader.connections;
// UB: Multiple possible null dereferences
#ifdef UBFIX #ifdef UBFIX // UB: Multiple possible null dereferences
if (connections != NULL) if (connections == NULL || connections->connections == NULL)
{ return NULL;
count = connections->count; #endif
connection = connections->connections;
if (connection != NULL)
{
for (i = 0; i < count; i++, connection++)
{
if (connection->direction == direction && sub_80889A8(direction, x, y, connection) == TRUE)
return connection;
}
}
}
#else
count = connections->count; count = connections->count;
connection = connections->connections; connection = connections->connections;
for (i = 0; i < count; i++, connection++) for (i = 0; i < count; i++, connection++)
{ {
if (connection->direction == direction && sub_80889A8(direction, x, y, connection) == TRUE) if (connection->direction == direction && IsPosInIncomingConnectingMap(direction, x, y, connection) == TRUE)
return connection; return connection;
} }
#endif
return NULL; return NULL;
} }
bool8 sub_80889A8(u8 direction, int x, int y, struct MapConnection *connection) static bool8 IsPosInIncomingConnectingMap(u8 direction, int x, int y, struct MapConnection *connection)
{ {
struct MapHeader const *mapHeader; struct MapHeader const *mapHeader;
mapHeader = GetMapHeaderFromConnection(connection); mapHeader = GetMapHeaderFromConnection(connection);
@ -835,15 +827,15 @@ bool8 sub_80889A8(u8 direction, int x, int y, struct MapConnection *connection)
{ {
case CONNECTION_SOUTH: case CONNECTION_SOUTH:
case CONNECTION_NORTH: case CONNECTION_NORTH:
return sub_8088A0C(x, gMapHeader.mapLayout->width, mapHeader->mapLayout->width, connection->offset); return IsCoordInIncomingConnectingMap(x, gMapHeader.mapLayout->width, mapHeader->mapLayout->width, connection->offset);
case CONNECTION_WEST: case CONNECTION_WEST:
case CONNECTION_EAST: case CONNECTION_EAST:
return sub_8088A0C(y, gMapHeader.mapLayout->height, mapHeader->mapLayout->height, connection->offset); return IsCoordInIncomingConnectingMap(y, gMapHeader.mapLayout->height, mapHeader->mapLayout->height, connection->offset);
} }
return FALSE; return FALSE;
} }
bool8 sub_8088A0C(int x, int src_width, int dest_width, int offset) static bool8 IsCoordInIncomingConnectingMap(int coord, int srcMax, int destMax, int offset)
{ {
int offset2; int offset2;
offset2 = offset; offset2 = offset;
@ -851,24 +843,24 @@ bool8 sub_8088A0C(int x, int src_width, int dest_width, int offset)
if (offset2 < 0) if (offset2 < 0)
offset2 = 0; offset2 = 0;
if (dest_width + offset < src_width) if (destMax + offset < srcMax)
src_width = dest_width + offset; srcMax = destMax + offset;
if (offset2 <= x && x <= src_width) if (offset2 <= coord && coord <= srcMax)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int sub_8088A38(int x, int width) static int IsCoordInConnectingMap(int coord, int max)
{ {
if (x >= 0 && x < width) if (coord >= 0 && coord < max)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int sub_8088A4C(struct MapConnection *connection, int x, int y) static int IsPosInConnectingMap(struct MapConnection *connection, int x, int y)
{ {
struct MapHeader const *mapHeader; struct MapHeader const *mapHeader;
mapHeader = GetMapHeaderFromConnection(connection); mapHeader = GetMapHeaderFromConnection(connection);
@ -876,10 +868,10 @@ int sub_8088A4C(struct MapConnection *connection, int x, int y)
{ {
case CONNECTION_SOUTH: case CONNECTION_SOUTH:
case CONNECTION_NORTH: case CONNECTION_NORTH:
return sub_8088A38(x - connection->offset, mapHeader->mapLayout->width); return IsCoordInConnectingMap(x - connection->offset, mapHeader->mapLayout->width);
case CONNECTION_WEST: case CONNECTION_WEST:
case CONNECTION_EAST: case CONNECTION_EAST:
return sub_8088A38(y - connection->offset, mapHeader->mapLayout->height); return IsCoordInConnectingMap(y - connection->offset, mapHeader->mapLayout->height);
} }
return FALSE; return FALSE;
} }
@ -909,7 +901,7 @@ struct MapConnection *GetConnectionAtCoords(s16 x, s16 y)
{ {
continue; continue;
} }
if (sub_8088A4C(connection, x - 7, y - 7) == TRUE) if (IsPosInConnectingMap(connection, x - 7, y - 7) == TRUE)
{ {
return connection; return connection;
} }
@ -991,12 +983,12 @@ static void CopyTilesetToVramUsingHeap(struct Tileset const *tileset, u16 numTil
} }
} }
void nullsub_3(u16 a0, u16 a1) static void FieldmapPaletteDummy(u16 offset, u16 size)
{ {
} }
void nullsub_90(void) static void FieldmapUnkDummy(void)
{ {
} }
@ -1011,17 +1003,17 @@ void LoadTilesetPalette(struct Tileset const *tileset, u16 destOffset, u16 size)
{ {
LoadPalette(&black, destOffset, 2); LoadPalette(&black, destOffset, 2);
LoadPalette(((u16*)tileset->palettes) + 1, destOffset + 1, size - 2); LoadPalette(((u16*)tileset->palettes) + 1, destOffset + 1, size - 2);
nullsub_3(destOffset + 1, (size - 2) >> 1); FieldmapPaletteDummy(destOffset + 1, (size - 2) >> 1);
} }
else if (tileset->isSecondary == TRUE) else if (tileset->isSecondary == TRUE)
{ {
LoadPalette(((u16*)tileset->palettes) + (NUM_PALS_IN_PRIMARY * 16), destOffset, size); LoadPalette(((u16*)tileset->palettes) + (NUM_PALS_IN_PRIMARY * 16), destOffset, size);
nullsub_3(destOffset, size >> 1); FieldmapPaletteDummy(destOffset, size >> 1);
} }
else else
{ {
LoadCompressedPalette((u32*)tileset->palettes, destOffset, size); LoadCompressedPalette((u32*)tileset->palettes, destOffset, size);
nullsub_3(destOffset, size >> 1); FieldmapPaletteDummy(destOffset, size >> 1);
} }
} }
} }

View File

@ -913,7 +913,7 @@ void Task_LinkSave(u8 taskId)
if (IsLinkTaskFinished()) if (IsLinkTaskFinished())
{ {
if (!tPartialSave) if (!tPartialSave)
save_serialize_map(); SaveMapView();
tState = 3; tState = 3;
} }
break; break;

View File

@ -850,7 +850,7 @@ static bool8 BattlePyramidRetireCallback(void)
static void InitSave(void) static void InitSave(void)
{ {
save_serialize_map(); SaveMapView();
sSaveDialogCallback = SaveConfirmSaveCallback; sSaveDialogCallback = SaveConfirmSaveCallback;
sSavingComplete = FALSE; sSavingComplete = FALSE;
} }