From bc79312d48781a35597705bf6663ac2a39598873 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Mon, 7 Jan 2019 08:54:56 -0500 Subject: Start decomping fieldmap --- src/fieldmap.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/fieldmap.c (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c new file mode 100644 index 000000000..f9b3ad897 --- /dev/null +++ b/src/fieldmap.c @@ -0,0 +1,42 @@ +#include "global.h" +#include "overworld.h" +#include "script.h" +#include "fieldmap.h" + +void sub_8058A00(struct MapHeader *mapHeader); +void map_copy_with_padding(u16 *map, u16 width, u16 height); +void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader); +void sub_80591C4(void); + +struct BackupMapData VMap; +EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE]; + +const struct MapHeader * mapconnection_get_mapheader(struct MapConnection * connection) +{ + return get_mapheader_by_bank_and_number(connection->mapGroup, connection->mapNum); +} + +void not_trainer_hill_battle_pyramid(void) +{ + sub_8058A00(&gMapHeader); + mapheader_run_script_with_tag_x1(); +} + +void sub_80589E8(void) +{ + sub_8058A00(&gMapHeader); + sub_80591C4(); + mapheader_run_script_with_tag_x1(); +} + +void sub_8058A00(struct MapHeader * mapHeader) +{ + const struct MapData * mapData = mapHeader->mapData; + CpuFastFill(0x03FF03FF, gBackupMapData, sizeof(gBackupMapData)); + VMap.map = gBackupMapData; + VMap.Xsize = mapData->width + 15; + VMap.Ysize = mapData->height + 14; + AGB_ASSERT_EX(VMap.Xsize * VMap.Ysize <= VIRTUAL_MAP_SIZE, "C:/WORK/POKeFRLG/src/pm_lgfr_ose/source/fieldmap.c", 158); + map_copy_with_padding(mapData->map, mapData->width, mapData->height); + mapheader_copy_mapdata_of_adjacent_maps(mapHeader); +} -- cgit v1.2.3 From ee25c7a9755b8ed1111a3677a5f519ac602f6391 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 10:17:44 -0500 Subject: through fillEastConnection --- src/fieldmap.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 283 insertions(+), 1 deletion(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index f9b3ad897..a78b7189c 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -3,13 +3,29 @@ #include "script.h" #include "fieldmap.h" +struct ConnectionFlags +{ + u8 south:1; + u8 north:1; + u8 west:1; + u8 east:1; +}; + void sub_8058A00(struct MapHeader *mapHeader); void map_copy_with_padding(u16 *map, u16 width, u16 height); void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader); +void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); +void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); +void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); +void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void sub_80591C4(void); struct BackupMapData VMap; -EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE]; +EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE] = {}; +EWRAM_DATA struct MapHeader gMapHeader = {}; +EWRAM_DATA struct ConnectionFlags gMapConnectionFlags = {}; + +extern const struct ConnectionFlags sDummyConnectionFlags; const struct MapHeader * mapconnection_get_mapheader(struct MapConnection * connection) { @@ -40,3 +56,269 @@ void sub_8058A00(struct MapHeader * mapHeader) map_copy_with_padding(mapData->map, mapData->width, mapData->height); mapheader_copy_mapdata_of_adjacent_maps(mapHeader); } + +void map_copy_with_padding(u16 *map, u16 width, u16 height) +{ + s32 y; + u16 *dest = VMap.map; + dest += VMap.Xsize * 7 + 7; + + for (y = 0; y < height; y++) + { + CpuCopy16(map, dest, width * sizeof(u16)); + dest += width + 15; + map += width; + } +} + +void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader) +{ + int count; + struct MapConnection *connection; + int i; + + gMapConnectionFlags = sDummyConnectionFlags; + + /* + * This null pointer check is new to FireRed. It was kept in + * Emerald, with the above struct assignment moved to after + * this check. + */ + if (mapHeader->connections) + { + count = mapHeader->connections->count; + connection = mapHeader->connections->connections; + // Emerald puts this line here instead: + // gMapConnectionFlags = sDummyConnectionFlags; + for (i = 0; i < count; i++, connection++) + { + struct MapHeader const *cMap = mapconnection_get_mapheader(connection); + u32 offset = connection->offset; + switch (connection->direction) + { + case CONNECTION_SOUTH: + fillSouthConnection(mapHeader, cMap, offset); + gMapConnectionFlags.south = 1; + break; + case CONNECTION_NORTH: + fillNorthConnection(mapHeader, cMap, offset); + gMapConnectionFlags.north = 1; + break; + case CONNECTION_WEST: + fillWestConnection(mapHeader, cMap, offset); + gMapConnectionFlags.west = 1; + break; + case CONNECTION_EAST: + fillEastConnection(mapHeader, cMap, offset); + gMapConnectionFlags.east = 1; + break; + } + } + } +} + +void sub_8058B54(s32 x, s32 y, const struct MapHeader *connectedMapHeader, s32 x2, s32 y2, s32 width, s32 height) +{ + int i; + u16 *src; + u16 *dest; + int mapWidth; + + mapWidth = connectedMapHeader->mapData->width; + src = &connectedMapHeader->mapData->map[mapWidth * y2 + x2]; + dest = &VMap.map[VMap.Xsize * y + x]; + + for (i = 0; i < height; i++) + { + CpuCopy16(src, dest, width * 2); + dest += VMap.Xsize; + src += mapWidth; + } +} + +void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) +{ + int x, y; + int x2; + int width; + int cWidth; + + if (connectedMapHeader) + { + cWidth = connectedMapHeader->mapData->width; + x = offset + 7; + y = mapHeader->mapData->height + 7; + if (x < 0) + { + x2 = -x; + x += cWidth; + if (x < VMap.Xsize) + { + width = x; + } + else + { + width = VMap.Xsize; + } + x = 0; + } + else + { + x2 = 0; + if (x + cWidth < VMap.Xsize) + { + width = cWidth; + } + else + { + width = VMap.Xsize - x; + } + } + + sub_8058B54( + x, y, + connectedMapHeader, + x2, /*y2*/ 0, + width, /*height*/ 7); + } +} + +void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) +{ + int x; + int x2, y2; + int width; + int cWidth, cHeight; + + if (connectedMapHeader) + { + cWidth = connectedMapHeader->mapData->width; + cHeight = connectedMapHeader->mapData->height; + x = offset + 7; + y2 = cHeight - 7; + if (x < 0) + { + x2 = -x; + x += cWidth; + if (x < VMap.Xsize) + { + width = x; + } + else + { + width = VMap.Xsize; + } + x = 0; + } + else + { + x2 = 0; + if (x + cWidth < VMap.Xsize) + { + width = cWidth; + } + else + { + width = VMap.Xsize - x; + } + } + + sub_8058B54( + x, /*y*/ 0, + connectedMapHeader, + x2, y2, + width, /*height*/ 7); + + } +} + +void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) +{ + int y; + int x2, y2; + int height; + int cWidth, cHeight; + if (connectedMapHeader) + { + cWidth = connectedMapHeader->mapData->width; + cHeight = connectedMapHeader->mapData->height; + y = offset + 7; + x2 = cWidth - 7; + if (y < 0) + { + y2 = -y; + if (y + cHeight < VMap.Ysize) + { + height = y + cHeight; + } + else + { + height = VMap.Ysize; + } + y = 0; + } + else + { + y2 = 0; + if (y + cHeight < VMap.Ysize) + { + height = cHeight; + } + else + { + height = VMap.Ysize - y; + } + } + + sub_8058B54( + /*x*/ 0, y, + connectedMapHeader, + x2, y2, + /*width*/ 7, height); + } +} + +void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) +{ + int x, y; + int y2; + int height; + int cHeight; + if (connectedMapHeader) + { + cHeight = connectedMapHeader->mapData->height; + x = mapHeader->mapData->width + 7; + y = offset + 7; + if (y < 0) + { + y2 = -y; + if (y + cHeight < VMap.Ysize) + { + height = y + cHeight; + } + else + { + height = VMap.Ysize; + } + y = 0; + } + else + { + y2 = 0; + if (y + cHeight < VMap.Ysize) + { + height = cHeight; + } + else + { + height = VMap.Ysize - y; + } + } + + sub_8058B54( + x, y, + connectedMapHeader, + /*x2*/ 0, y2, + /*width*/ 8, height); + } +} -- cgit v1.2.3 From 9aab26afa5315c32f83ae7f40e19c9053d602089 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 14:39:28 -0500 Subject: through MapGridGetMetatileIdAt --- src/fieldmap.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 21 deletions(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index a78b7189c..de29efe56 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -73,9 +73,9 @@ void map_copy_with_padding(u16 *map, u16 width, u16 height) void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader) { - int count; + s32 count; struct MapConnection *connection; - int i; + s32 i; gMapConnectionFlags = sDummyConnectionFlags; @@ -119,10 +119,10 @@ void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader) void sub_8058B54(s32 x, s32 y, const struct MapHeader *connectedMapHeader, s32 x2, s32 y2, s32 width, s32 height) { - int i; + s32 i; u16 *src; u16 *dest; - int mapWidth; + s32 mapWidth; mapWidth = connectedMapHeader->mapData->width; src = &connectedMapHeader->mapData->map[mapWidth * y2 + x2]; @@ -135,13 +135,13 @@ void sub_8058B54(s32 x, s32 y, const struct MapHeader *connectedMapHeader, s32 x src += mapWidth; } } - + void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) { - int x, y; - int x2; - int width; - int cWidth; + s32 x, y; + s32 x2; + s32 width; + s32 cWidth; if (connectedMapHeader) { @@ -185,10 +185,10 @@ void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader con void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) { - int x; - int x2, y2; - int width; - int cWidth, cHeight; + s32 x; + s32 x2, y2; + s32 width; + s32 cWidth, cHeight; if (connectedMapHeader) { @@ -234,10 +234,10 @@ void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader con void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) { - int y; - int x2, y2; - int height; - int cWidth, cHeight; + s32 y; + s32 x2, y2; + s32 height; + s32 cWidth, cHeight; if (connectedMapHeader) { cWidth = connectedMapHeader->mapData->width; @@ -280,10 +280,10 @@ void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader cons void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset) { - int x, y; - int y2; - int height; - int cHeight; + s32 x, y; + s32 y2; + s32 height; + s32 cHeight; if (connectedMapHeader) { cHeight = connectedMapHeader->mapData->height; @@ -322,3 +322,99 @@ void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader cons /*width*/ 8, height); } } + +union Block +{ + struct + { + u16 block:10; + u16 collision:2; + u16 elevation:4; + } block; + u16 value; +}; + +#define MapGridGetBorderTileAt(x, y) ({ \ + u16 block; \ + s32 xprime; \ + s32 yprime; \ + \ + struct MapData *mapData = gMapHeader.mapData; \ + \ + xprime = x - 7; \ + xprime += 8 * mapData->unk18; \ + xprime %= mapData->unk18; \ + \ + yprime = y - 7; \ + yprime += 8 * mapData->unk19; \ + yprime %= mapData->unk19; \ + \ + block = mapData->border[xprime + yprime * mapData->unk18]; \ + block |= 0xC00; \ + block; \ +}) + +#define MapGridGetBorderTileAt2(x, y) ({ \ + u16 block; \ + s32 xprime; \ + s32 yprime; \ + \ + struct MapData *mapData = gMapHeader.mapData; \ + \ + xprime = x - 7; \ + xprime += 8 * mapData->unk18; \ + xprime %= mapData->unk18; \ + \ + yprime = y - 7; \ + yprime += 8 * mapData->unk19; \ + yprime %= mapData->unk19; \ + \ + block = mapData->border[xprime + yprime * mapData->unk18] | 0xC00; \ + block; \ +}) + +#define MapGridGetTileAt(x, y) ({ \ + u16 block; \ + if (x >= 0 && x < VMap.Xsize \ + && y >= 0 && y < VMap.Ysize) \ + block = VMap.map[x + VMap.Xsize * y]; \ + else \ + block = MapGridGetBorderTileAt2(x, y); \ + block; \ +}) + +u8 MapGridGetZCoordAt(s32 x, s32 y) +{ + u16 block = MapGridGetTileAt(x, y); + + if (block == 0x3ff) + { + return 0; + } + + return block >> 12; +} + +u8 MapGridIsImpassableAt(s32 x, s32 y) +{ + + u16 block = MapGridGetTileAt(x, y); + + if (block == 0x3ff) + { + return 1; + } + + return (block & 0xc00) >> 10; +} + +u32 MapGridGetMetatileIdAt(s32 x, s32 y) +{ + u16 block = MapGridGetTileAt(x, y); + + if (block == 0x3FF) + { + return MapGridGetBorderTileAt(x, y) & 0x3FF; + } + return block & 0x3FF; +} -- cgit v1.2.3 From b4f57a6c265af82f7ae222a5ae2d66450aea512c Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 15:02:57 -0500 Subject: through sub_8059024 --- src/fieldmap.c | 157 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 121 insertions(+), 36 deletions(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index de29efe56..c0926ffad 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -18,6 +18,7 @@ void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader con void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); +u32 sub_8059080(struct MapData *mapData, u16 metatileId, u8 z); void sub_80591C4(void); struct BackupMapData VMap; @@ -25,7 +26,29 @@ EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE] = {}; EWRAM_DATA struct MapHeader gMapHeader = {}; EWRAM_DATA struct ConnectionFlags gMapConnectionFlags = {}; -extern const struct ConnectionFlags sDummyConnectionFlags; +const struct ConnectionFlags sDummyConnectionFlags = {}; + +const u32 gUnknown_8352EF0[] = { + 0x1ff, + 0x3e00, + 0x3c000, + 0xfc0000, + 0x7000000, + 0x18000000, + 0x60000000, + 0x80000000 +}; + +const u8 gUnknown_8352F10[] = { + 0, + 9, + 14, + 18, + 24, + 27, + 29, + 31 +}; const struct MapHeader * mapconnection_get_mapheader(struct MapConnection * connection) { @@ -334,43 +357,43 @@ union Block u16 value; }; -#define MapGridGetBorderTileAt(x, y) ({ \ - u16 block; \ - s32 xprime; \ - s32 yprime; \ - \ - struct MapData *mapData = gMapHeader.mapData; \ - \ - xprime = x - 7; \ - xprime += 8 * mapData->unk18; \ - xprime %= mapData->unk18; \ - \ - yprime = y - 7; \ - yprime += 8 * mapData->unk19; \ - yprime %= mapData->unk19; \ - \ - block = mapData->border[xprime + yprime * mapData->unk18]; \ - block |= 0xC00; \ - block; \ +#define MapGridGetBorderTileAt(x, y) ({ \ + u16 block; \ + s32 xprime; \ + s32 yprime; \ + \ + struct MapData *mapData = gMapHeader.mapData; \ + \ + xprime = x - 7; \ + xprime += 8 * mapData->unk18; \ + xprime %= mapData->unk18; \ + \ + yprime = y - 7; \ + yprime += 8 * mapData->unk19; \ + yprime %= mapData->unk19; \ + \ + block = mapData->border[xprime + yprime * mapData->unk18]; \ + block |= 0xC00; \ + block; \ }) -#define MapGridGetBorderTileAt2(x, y) ({ \ - u16 block; \ - s32 xprime; \ - s32 yprime; \ - \ - struct MapData *mapData = gMapHeader.mapData; \ - \ - xprime = x - 7; \ - xprime += 8 * mapData->unk18; \ - xprime %= mapData->unk18; \ - \ - yprime = y - 7; \ - yprime += 8 * mapData->unk19; \ - yprime %= mapData->unk19; \ - \ - block = mapData->border[xprime + yprime * mapData->unk18] | 0xC00; \ - block; \ +#define MapGridGetBorderTileAt2(x, y) ({ \ + u16 block; \ + s32 xprime; \ + s32 yprime; \ + \ + struct MapData *mapData = gMapHeader.mapData; \ + \ + xprime = x - 7; \ + xprime += 8 * mapData->unk18; \ + xprime %= mapData->unk18; \ + \ + yprime = y - 7; \ + yprime += 8 * mapData->unk19; \ + yprime %= mapData->unk19; \ + \ + block = mapData->border[xprime + yprime * mapData->unk18] | 0xC00; \ + block; \ }) #define MapGridGetTileAt(x, y) ({ \ @@ -418,3 +441,65 @@ u32 MapGridGetMetatileIdAt(s32 x, s32 y) } return block & 0x3FF; } + +u32 sub_8058F1C(u32 original, u8 bit) +{ + if (bit >= 8) + return original; + + return (original & gUnknown_8352EF0[bit]) >> gUnknown_8352F10[bit]; +} + +u32 sub_8058F48(s16 x, s16 y, u8 z) +{ + u16 metatileId = MapGridGetMetatileIdAt(x, y); + return sub_8059080(gMapHeader.mapData, metatileId, z); +} + +u32 MapGridGetMetatileBehaviorAt(s32 x, s32 y) +{ + return sub_8058F48(x, y, 0); +} + +u8 MapGridGetMetatileLayerTypeAt(s32 x, s32 y) +{ + return sub_8058F48(x, y, 6); +} + +void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatile) +{ + int i; + if (x >= 0 && x < VMap.Xsize + && y >= 0 && y < VMap.Ysize) + { + i = x + y * VMap.Xsize; + VMap.map[i] = (VMap.map[i] & 0xf000) | (metatile & 0xfff); + } +} + +void MapGridSetMetatileEntryAt(s32 x, s32 y, u16 metatile) +{ + int i; + if (x >= 0 && x < VMap.Xsize + && y >= 0 && y < VMap.Ysize) + { + i = x + VMap.Xsize * y; + VMap.map[i] = metatile; + } +} + +void sub_8059024(s32 x, s32 y, bool32 arg2) +{ + if (x >= 0 && x < VMap.Xsize + && y >= 0 && y < VMap.Ysize) + { + if (arg2) + { + VMap.map[x + VMap.Xsize * y] |= 0x0C00; + } + else + { + VMap.map[x + VMap.Xsize * y] &= ~0x0C00; + } + } +} -- cgit v1.2.3 From e1bd043bf3049b8a91b718ca1e4416711f0b8646 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 15:32:11 -0500 Subject: through sub_8059250 --- src/fieldmap.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 144 insertions(+), 6 deletions(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index c0926ffad..4193ece97 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -18,8 +18,7 @@ void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader con void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); -u32 sub_8059080(struct MapData *mapData, u16 metatileId, u8 z); -void sub_80591C4(void); +void LoadSavedMapView(void); struct BackupMapData VMap; EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE] = {}; @@ -64,7 +63,7 @@ void not_trainer_hill_battle_pyramid(void) void sub_80589E8(void) { sub_8058A00(&gMapHeader); - sub_80591C4(); + LoadSavedMapView(); mapheader_run_script_with_tag_x1(); } @@ -453,7 +452,7 @@ u32 sub_8058F1C(u32 original, u8 bit) u32 sub_8058F48(s16 x, s16 y, u8 z) { u16 metatileId = MapGridGetMetatileIdAt(x, y); - return sub_8059080(gMapHeader.mapData, metatileId, z); + return GetBehaviorByMetatileIdAndMapData(gMapHeader.mapData, metatileId, z); } u32 MapGridGetMetatileBehaviorAt(s32 x, s32 y) @@ -468,7 +467,7 @@ u8 MapGridGetMetatileLayerTypeAt(s32 x, s32 y) void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatile) { - int i; + s32 i; if (x >= 0 && x < VMap.Xsize && y >= 0 && y < VMap.Ysize) { @@ -479,7 +478,7 @@ void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatile) void MapGridSetMetatileEntryAt(s32 x, s32 y, u16 metatile) { - int i; + s32 i; if (x >= 0 && x < VMap.Xsize && y >= 0 && y < VMap.Ysize) { @@ -503,3 +502,142 @@ void sub_8059024(s32 x, s32 y, bool32 arg2) } } } + +u32 GetBehaviorByMetatileIdAndMapData(struct MapData *mapData, u16 metatile, u8 attr) +{ + u32 * attributes; + + if (metatile < 0x280) + { + attributes = mapData->primaryTileset->metatileAttributes; + return sub_8058F1C(attributes[metatile], attr); + } + else if (metatile < 0x400) + { + attributes = mapData->secondaryTileset->metatileAttributes; + return sub_8058F1C(attributes[metatile - 0x280], attr); + } + else + { + return 0xFF; + } +} + +void save_serialize_map(void) +{ + s32 i, j; + s32 x, y; + u16 *mapView; + s32 width; + mapView = gSaveBlock2Ptr->mapView; + width = VMap.Xsize; + x = gSaveBlock1Ptr->pos.x; + y = gSaveBlock1Ptr->pos.y; + for (i = y; i < y + 14; i++) + { + for (j = x; j < x + 15; j++) + { + *mapView++ = gBackupMapData[width * i + j]; + } + } +} + +bool32 SavedMapViewIsEmpty(void) +{ + u16 i; + u32 marker = 0; + + // BUG: This loop extends past the bounds of the mapView array. Its size is only 0x100. + for (i = 0; i < 0x200; i++) + marker |= gSaveBlock2Ptr->mapView[i]; + + if (marker == 0) + return TRUE; + else + return FALSE; +} + +void ClearSavedMapView(void) +{ + CpuFill16(0, gSaveBlock2Ptr->mapView, sizeof(gSaveBlock2Ptr->mapView)); +} + +void LoadSavedMapView(void) +{ + s32 i, j; + s32 x, y; + u16 *mapView; + s32 width; + mapView = gSaveBlock2Ptr->mapView; + if (!SavedMapViewIsEmpty()) + { + width = VMap.Xsize; + x = gSaveBlock1Ptr->pos.x; + y = gSaveBlock1Ptr->pos.y; + for (i = y; i < y + 14; i++) + { + for (j = x; j < x + 15; j++) + { + gBackupMapData[j + width * i] = *mapView; + mapView++; + } + } + ClearSavedMapView(); + } +} + +void sub_8059250(u8 a1) +{ + s32 width; + u16 *mapView; + s32 x0, y0; + s32 x2, y2; + u16 *src, *dest; + s32 srci, desti; + s32 r9, r8; + s32 x, y; + s32 i, j; + mapView = gSaveBlock2Ptr->mapView; + width = VMap.Xsize; + r9 = 0; + r8 = 0; + x0 = gSaveBlock1Ptr->pos.x; + y0 = gSaveBlock1Ptr->pos.y; + x2 = 15; + y2 = 14; + switch (a1) + { + case CONNECTION_NORTH: + y0 += 1; + y2 = 13; + break; + case CONNECTION_SOUTH: + r8 = 1; + y2 = 13; + break; + case CONNECTION_WEST: + x0 += 1; + x2 = 14; + break; + case CONNECTION_EAST: + r9 = 1; + x2 = 14; + break; + } + for (y = 0; y < y2; y++) + { + i = 0; + j = 0; + for (x = 0; x < x2; x++) + { + desti = width * (y + y0); + srci = (y + r8) * 15 + r9; + src = &mapView[srci + i]; + dest = &gBackupMapData[x0 + desti + j]; + *dest = *src; + i++; + j++; + } + } + ClearSavedMapView(); +} -- cgit v1.2.3 From 34cf3662fc0343d77fe36b1a3083605110764c9a Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 15:48:36 -0500 Subject: GetMapBorderIdAt --- src/fieldmap.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index 4193ece97..06385ff35 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -395,15 +395,7 @@ union Block block; \ }) -#define MapGridGetTileAt(x, y) ({ \ - u16 block; \ - if (x >= 0 && x < VMap.Xsize \ - && y >= 0 && y < VMap.Ysize) \ - block = VMap.map[x + VMap.Xsize * y]; \ - else \ - block = MapGridGetBorderTileAt2(x, y); \ - block; \ -}) +#define MapGridGetTileAt(x, y) ((x >= 0 && x < VMap.Xsize && y >= 0 && y < VMap.Ysize) ? VMap.map[x + VMap.Xsize * y] : MapGridGetBorderTileAt2(x, y)) u8 MapGridGetZCoordAt(s32 x, s32 y) { @@ -641,3 +633,49 @@ void sub_8059250(u8 a1) } ClearSavedMapView(); } + +s32 GetMapBorderIdAt(s32 x, s32 y) +{ + if (MapGridGetTileAt(x, y) == 0x3FF) + { + return -1; + } + + if (x >= VMap.Xsize - 8) + { + if (!gMapConnectionFlags.east) + { + return -1; + } + return CONNECTION_EAST; + } + + if (x < 7) + { + if (!gMapConnectionFlags.west) + { + return -1; + } + return CONNECTION_WEST; + } + + if (y >= VMap.Ysize - 7) + { + if (!gMapConnectionFlags.south) + { + return -1; + } + return CONNECTION_SOUTH; + } + + if (y < 7) + { + if (!gMapConnectionFlags.north) + { + return -1; + } + return CONNECTION_NORTH; + } + + return 0; +} -- cgit v1.2.3 From 38abcf9774612094d8552904fbeed3d1b2c4bba1 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 16:39:32 -0500 Subject: through sub_80598CC --- src/fieldmap.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 1 deletion(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index 06385ff35..559506829 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -1,6 +1,11 @@ #include "global.h" +#include "bg.h" +#include "palette.h" #include "overworld.h" #include "script.h" +#include "menu.h" +#include "new_menu_helpers.h" +#include "quest_log.h" #include "fieldmap.h" struct ConnectionFlags @@ -19,6 +24,9 @@ void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader con void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset); void LoadSavedMapView(void); +struct MapConnection *sub_8059600(u8 direction, s32 x, s32 y); +bool8 sub_8059658(u8 direction, s32 x, s32 y, struct MapConnection *connection); +bool8 sub_80596BC(s32 x, s32 src_width, s32 dest_width, s32 offset); struct BackupMapData VMap; EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE] = {}; @@ -395,7 +403,9 @@ union Block block; \ }) -#define MapGridGetTileAt(x, y) ((x >= 0 && x < VMap.Xsize && y >= 0 && y < VMap.Ysize) ? VMap.map[x + VMap.Xsize * y] : MapGridGetBorderTileAt2(x, y)) +#define AreCoordsWithinMapGridBounds(x, y) (x >= 0 && x < VMap.Xsize && y >= 0 && y < VMap.Ysize) + +#define MapGridGetTileAt(x, y) (AreCoordsWithinMapGridBounds(x, y) ? VMap.map[x + VMap.Xsize * y] : MapGridGetBorderTileAt2(x, y)) u8 MapGridGetZCoordAt(s32 x, s32 y) { @@ -679,3 +689,246 @@ s32 GetMapBorderIdAt(s32 x, s32 y) return 0; } + +s32 GetPostCameraMoveMapBorderId(s32 x, s32 y) +{ + return GetMapBorderIdAt(7 + gSaveBlock1Ptr->pos.x + x, 7 + gSaveBlock1Ptr->pos.y + y); +} + +bool32 CanCameraMoveInDirection(s32 direction) +{ + s32 x, y; + + x = gSaveBlock1Ptr->pos.x + 7 + gDirectionToVectors[direction].x; + y = gSaveBlock1Ptr->pos.y + 7 + gDirectionToVectors[direction].y; + if (GetMapBorderIdAt(x, y) == -1) + { + return FALSE; + } + return TRUE; +} + +void sub_80594AC(struct MapConnection *connection, int direction, s32 x, s32 y) +{ + struct MapHeader const *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (direction) + { + case CONNECTION_EAST: + gSaveBlock1Ptr->pos.x = -x; + gSaveBlock1Ptr->pos.y -= connection->offset; + break; + case CONNECTION_WEST: + gSaveBlock1Ptr->pos.x = mapHeader->mapData->width; + gSaveBlock1Ptr->pos.y -= connection->offset; + break; + case CONNECTION_SOUTH: + gSaveBlock1Ptr->pos.x -= connection->offset; + gSaveBlock1Ptr->pos.y = -y; + break; + case CONNECTION_NORTH: + gSaveBlock1Ptr->pos.x -= connection->offset; + gSaveBlock1Ptr->pos.y = mapHeader->mapData->height; + break; + } +} + +bool8 CameraMove(s32 x, s32 y) +{ + u32 direction; + struct MapConnection *connection; + s32 old_x, old_y; + gCamera.active = FALSE; + direction = GetPostCameraMoveMapBorderId(x, y); + if (direction + 1 <= 1) + { + gSaveBlock1Ptr->pos.x += x; + gSaveBlock1Ptr->pos.y += y; + } + else + { + save_serialize_map(); + old_x = gSaveBlock1Ptr->pos.x; + old_y = gSaveBlock1Ptr->pos.y; + connection = sub_8059600(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y); + sub_80594AC(connection, direction, x, y); + sub_8055864(connection->mapGroup, connection->mapNum); + gCamera.active = TRUE; + gCamera.x = old_x - gSaveBlock1Ptr->pos.x; + gCamera.y = old_y - gSaveBlock1Ptr->pos.y; + gSaveBlock1Ptr->pos.x += x; + gSaveBlock1Ptr->pos.y += y; + sub_8059250(direction); + } + return gCamera.active; +} + +struct MapConnection *sub_8059600(u8 direction, s32 x, s32 y) +{ + s32 count; + struct MapConnection *connection; + s32 i; + count = gMapHeader.connections->count; + connection = gMapHeader.connections->connections; + for (i = 0; i < count; i++, connection++) + { + if (connection->direction == direction && sub_8059658(direction, x, y, connection) == TRUE) + return connection; + } + return NULL; + +} + +bool8 sub_8059658(u8 direction, s32 x, s32 y, struct MapConnection *connection) +{ + struct MapHeader const *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (direction) + { + case CONNECTION_SOUTH: + case CONNECTION_NORTH: + return sub_80596BC(x, gMapHeader.mapData->width, mapHeader->mapData->width, connection->offset); + case CONNECTION_WEST: + case CONNECTION_EAST: + return sub_80596BC(y, gMapHeader.mapData->height, mapHeader->mapData->height, connection->offset); + } + return FALSE; +} + +bool8 sub_80596BC(s32 x, s32 src_width, s32 dest_width, s32 offset) +{ + s32 offset2 = max(offset, 0); + + if (dest_width + offset < src_width) + src_width = dest_width + offset; + + if (offset2 <= x && x <= src_width) + return TRUE; + + return FALSE; +} + +bool32 sub_80596E8(s32 x, s32 width) +{ + if (x >= 0 && x < width) + return TRUE; + + return FALSE; +} + +s32 sub_80596FC(struct MapConnection *connection, s32 x, s32 y) +{ + struct MapHeader const *mapHeader; + mapHeader = mapconnection_get_mapheader(connection); + switch (connection->direction) + { + case CONNECTION_SOUTH: + case CONNECTION_NORTH: + return sub_80596E8(x - connection->offset, mapHeader->mapData->width); + case CONNECTION_WEST: + case CONNECTION_EAST: + return sub_80596E8(y - connection->offset, mapHeader->mapData->height); + } + return FALSE; +} + +struct MapConnection *sub_805973C(s16 x, s16 y) +{ + s32 count; + struct MapConnection *connection; + s32 i; + u8 direction; + if (!gMapHeader.connections) + { + return NULL; + } + else + { + count = gMapHeader.connections->count; + connection = gMapHeader.connections->connections; + for (i = 0; i < count; i++, connection++) + { + direction = connection->direction; + if ((direction == CONNECTION_DIVE || direction == CONNECTION_EMERGE) + || (direction == CONNECTION_NORTH && y > 6) + || (direction == CONNECTION_SOUTH && y < gMapHeader.mapData->height + 7) + || (direction == CONNECTION_WEST && x > 6) + || (direction == CONNECTION_EAST && x < gMapHeader.mapData->width + 7)) + { + continue; + } + if (sub_80596FC(connection, x - 7, y - 7) == TRUE) + { + return connection; + } + } + } + return NULL; +} + +void SetCameraFocusCoords(u16 x, u16 y) +{ + gSaveBlock1Ptr->pos.x = x - 7; + gSaveBlock1Ptr->pos.y = y - 7; +} + +void GetCameraFocusCoords(u16 *x, u16 *y) +{ + *x = gSaveBlock1Ptr->pos.x + 7; + *y = gSaveBlock1Ptr->pos.y + 7; +} + +void SetCameraCoords(u16 x, u16 y) +{ + gSaveBlock1Ptr->pos.x = x; + gSaveBlock1Ptr->pos.y = y; +} + +void GetCameraCoords(u16 *x, u16 *y) +{ + *x = gSaveBlock1Ptr->pos.x; + *y = gSaveBlock1Ptr->pos.y; +} +void copy_tileset_patterns_to_vram(struct Tileset const *tileset, u16 numTiles, u16 offset) +{ + if (tileset) + { + if (!tileset->isCompressed) + LoadBgTiles(2, tileset->tiles, numTiles * 32, offset); + else + sub_80F68F0(2, tileset->tiles, numTiles * 32, offset, 0); + } +} + +void copy_tileset_patterns_to_vram2(struct Tileset const *tileset, u16 numTiles, u16 offset) +{ + if (tileset) + { + if (!tileset->isCompressed) + LoadBgTiles(2, tileset->tiles, numTiles * 32, offset); + else + sub_80F69E8(2, tileset->tiles, numTiles * 32, offset, 0); + } +} + +void sub_80598CC(u16 a0, u16 a1) +{ + switch (gUnknown_2036E28) + { + case 0: + return; + case 1: + TintPalette_GrayScale(gPlttBufferUnfaded + a0, a1); + break; + case 2: + TintPalette_SepiaTone(gPlttBufferUnfaded + a0, a1); + break; + case 3: + sub_8111F38(a0, a1); + TintPalette_GrayScale(gPlttBufferUnfaded + a0, a1); + break; + default: + return; + } + CpuCopy16(gPlttBufferUnfaded + a0, gPlttBufferFaded + a0, a1 * sizeof(u16)); +} -- cgit v1.2.3 From 316975ebeae7ca15f9a55bcfc3c493a9f35c6242 Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 16:47:21 -0500 Subject: Complete code decomp of fieldmap.s --- src/fieldmap.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index 559506829..2984465c7 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -509,7 +509,7 @@ u32 GetBehaviorByMetatileIdAndMapData(struct MapData *mapData, u16 metatile, u8 { u32 * attributes; - if (metatile < 0x280) + if (metatile < NUM_METATILES_IN_PRIMARY) { attributes = mapData->primaryTileset->metatileAttributes; return sub_8058F1C(attributes[metatile], attr); @@ -517,7 +517,7 @@ u32 GetBehaviorByMetatileIdAndMapData(struct MapData *mapData, u16 metatile, u8 else if (metatile < 0x400) { attributes = mapData->secondaryTileset->metatileAttributes; - return sub_8058F1C(attributes[metatile - 0x280], attr); + return sub_8058F1C(attributes[metatile - NUM_METATILES_IN_PRIMARY], attr); } else { @@ -932,3 +932,93 @@ void sub_80598CC(u16 a0, u16 a1) } CpuCopy16(gPlttBufferUnfaded + a0, gPlttBufferFaded + a0, a1 * sizeof(u16)); } + +void sub_8059948(u8 a0, u8 a1) +{ + switch (gUnknown_2036E28) + { + case 0: + return; + case 1: + TintPalette_GrayScale(gPlttBufferUnfaded + a0 * 16, a1 * 16); + break; + case 2: + TintPalette_SepiaTone(gPlttBufferUnfaded + a0 * 16, a1 * 16); + break; + case 3: + sub_8111F38(a0 * 16, a1 * 16); + TintPalette_GrayScale(gPlttBufferUnfaded + a0 * 16, a1 * 16); + break; + default: + return; + } + CpuFastCopy(gPlttBufferUnfaded + a0 * 16, gPlttBufferFaded + a0 * 16, a1 * 16 * sizeof(u16)); +} + +void apply_map_tileset_palette(struct Tileset const *tileset, u16 destOffset, u16 size) +{ + u16 black = RGB_BLACK; + + if (tileset) + { + if (tileset->isSecondary == FALSE) + { + LoadPalette(&black, destOffset, 2); + LoadPalette(((u16*)tileset->palettes) + 1, destOffset + 1, size - 2); + sub_80598CC(destOffset + 1, (size - 2) >> 1); + } + else if (tileset->isSecondary == TRUE) + { + LoadPalette(((u16*)tileset->palettes) + (NUM_PALS_IN_PRIMARY * 16), destOffset, size); + sub_80598CC(destOffset, size >> 1); + } + else + { + LoadCompressedPalette((u32*)tileset->palettes, destOffset, size); + sub_80598CC(destOffset, size >> 1); + } + } +} + +void copy_map_tileset1_to_vram(const struct MapData *mapData) +{ + copy_tileset_patterns_to_vram(mapData->primaryTileset, NUM_TILES_IN_PRIMARY, 0); +} + +void copy_map_tileset2_to_vram(const struct MapData *mapData) +{ + copy_tileset_patterns_to_vram(mapData->secondaryTileset, NUM_TILES_TOTAL - NUM_TILES_IN_PRIMARY, NUM_TILES_IN_PRIMARY); +} + +void copy_map_tileset2_to_vram_2(const struct MapData *mapData) +{ + copy_tileset_patterns_to_vram2(mapData->secondaryTileset, NUM_TILES_TOTAL - NUM_TILES_IN_PRIMARY, NUM_TILES_IN_PRIMARY); +} + +void apply_map_tileset1_palette(const struct MapData *mapData) +{ + apply_map_tileset_palette(mapData->primaryTileset, 0, NUM_PALS_IN_PRIMARY * 16 * 2); +} + +void apply_map_tileset2_palette(const struct MapData *mapData) +{ + apply_map_tileset_palette(mapData->secondaryTileset, NUM_PALS_IN_PRIMARY * 16, (NUM_PALS_TOTAL - NUM_PALS_IN_PRIMARY) * 16 * 2); +} + +void copy_map_tileset1_tileset2_to_vram(struct MapData const *mapData) +{ + if (mapData) + { + copy_tileset_patterns_to_vram2(mapData->primaryTileset, NUM_TILES_IN_PRIMARY, 0); + copy_tileset_patterns_to_vram2(mapData->secondaryTileset, NUM_TILES_TOTAL - NUM_TILES_IN_PRIMARY, NUM_TILES_IN_PRIMARY); + } +} + +void apply_map_tileset1_tileset2_palette(struct MapData const *mapData) +{ + if (mapData) + { + apply_map_tileset1_palette(mapData); + apply_map_tileset2_palette(mapData); + } +} \ No newline at end of file -- cgit v1.2.3 From 6da60e9b36303ac9d67a59db9092adb1dae6b43f Mon Sep 17 00:00:00 2001 From: scnorton Date: Mon, 7 Jan 2019 16:53:28 -0500 Subject: fieldmap: Common and EWRAM syms --- src/fieldmap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index 2984465c7..be5e1d54a 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -31,6 +31,7 @@ bool8 sub_80596BC(s32 x, s32 src_width, s32 dest_width, s32 offset); struct BackupMapData VMap; EWRAM_DATA u16 gBackupMapData[VIRTUAL_MAP_SIZE] = {}; EWRAM_DATA struct MapHeader gMapHeader = {}; +EWRAM_DATA struct Camera gCamera = {}; EWRAM_DATA struct ConnectionFlags gMapConnectionFlags = {}; const struct ConnectionFlags sDummyConnectionFlags = {}; -- cgit v1.2.3 From 28885f5a471489390ccde928f735985f15039eac Mon Sep 17 00:00:00 2001 From: garak Date: Tue, 21 May 2019 14:35:12 -0400 Subject: dump event script text strings --- src/fieldmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/fieldmap.c') diff --git a/src/fieldmap.c b/src/fieldmap.c index be5e1d54a..5d11c7d99 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -1022,4 +1022,4 @@ void apply_map_tileset1_tileset2_palette(struct MapData const *mapData) apply_map_tileset1_palette(mapData); apply_map_tileset2_palette(mapData); } -} \ No newline at end of file +} -- cgit v1.2.3