OverworldMap sprite entities, canvas drawing updates

This commit is contained in:
scawful
2024-01-28 12:04:52 -05:00
parent 4463e6be32
commit e006702df1
12 changed files with 872 additions and 414 deletions

38
src/app/zelda3/common.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef YAZE_APP_ZELDA3_COMMON_H
#define YAZE_APP_ZELDA3_COMMON_H
namespace yaze {
namespace app {
namespace zelda3 {
class OverworldEntity {
public:
enum EntityType {
kEntrance = 0,
kExit = 1,
kItem = 2,
kSprite = 3,
kTransport = 4,
kMusic = 5,
kTilemap = 6,
kProperties = 7
} type_;
int x_;
int y_;
int game_x_;
int game_y_;
int entity_id_;
int map_id_;
auto set_x(int x) { x_ = x; }
auto set_y(int y) { y_ = y; }
OverworldEntity() = default;
virtual void UpdateMapProperties(short map_id) = 0;
};
} // namespace zelda3
} // namespace app
} // namespace yaze
#endif // YAZE_APP_ZELDA3_COMMON_H

View File

@@ -141,8 +141,8 @@ absl::Status Overworld::Load(ROM &rom) {
FetchLargeMaps();
LoadEntrances();
LoadExits();
LoadSprites();
RETURN_IF_ERROR(LoadItems());
RETURN_IF_ERROR(LoadSprites());
RETURN_IF_ERROR(LoadOverworldMaps())
is_loaded_ = true;
@@ -862,6 +862,12 @@ void Overworld::FetchLargeMaps() {
}
}
void Overworld::LoadTileTypes() {
for (int i = 0; i < 0x200; i++) {
all_tiles_types_[i] = rom()->data()[overworldTilesType + i];
}
}
void Overworld::LoadEntrances() {
for (int i = 0; i < 129; i++) {
short map_id = rom()->toint16(OWEntranceMap + (i * 2));
@@ -939,6 +945,37 @@ absl::Status Overworld::SaveExits() {
return absl::OkStatus();
}
namespace {
bool compareItemsArrays(std::vector<OverworldItem> itemArray1,
std::vector<OverworldItem> itemArray2) {
if (itemArray1.size() != itemArray2.size()) {
return false;
}
bool match;
for (int i = 0; i < itemArray1.size(); i++) {
match = false;
for (int j = 0; j < itemArray2.size(); j++) {
// Check all sprite in 2nd array if one match
if (itemArray1[i].x_ == itemArray2[j].x_ &&
itemArray1[i].y_ == itemArray2[j].y_ &&
itemArray1[i].id == itemArray2[j].id) {
match = true;
break;
}
}
if (!match) {
return false;
}
}
return true;
}
} // namespace
absl::Status Overworld::SaveItems() {
std::vector<std::vector<OverworldItem>> roomItems(128);
@@ -968,13 +1005,19 @@ absl::Status Overworld::SaveItems() {
itemPointersReuse[i] = -2;
break;
}
// Unclear: this.compareItemsArrays(roomItems[i].ToArray(),
// roomItems[ci].ToArray()) Commenting out for now if
// (this.compareItemsArrays(roomItems[i].ToArray(),
// roomItems[ci].ToArray())) {
// itemPointersReuse[i] = ci;
// break;
// }
// Unclear:
compareItemsArrays(
std::vector<OverworldItem>(roomItems[i].begin(), roomItems[i].end()),
std::vector<OverworldItem>(roomItems[ci].begin(),
roomItems[ci].end()));
if (compareItemsArrays(std::vector<OverworldItem>(roomItems[i].begin(),
roomItems[i].end()),
std::vector<OverworldItem>(roomItems[ci].begin(),
roomItems[ci].end()))) {
itemPointersReuse[i] = ci;
break;
}
}
}
@@ -1051,10 +1094,6 @@ void Overworld::LoadExits() {
rom_data[OWExitYPlayer + (i * 2)]);
ushort px = (ushort)((rom_data[OWExitXPlayer + (i * 2) + 1] << 8) +
rom_data[OWExitXPlayer + (i * 2)]);
OverworldExit exit(exit_room_id, exit_map_id, exit_vram, exit_y_scroll,
exit_x_scroll, py, px, exit_y_camera, exit_x_camera,
exit_scroll_mod_y, exit_scroll_mod_x, exit_door_type_1,
exit_door_type_2);
if (rom()->flags()->kLogToConsole) {
std::cout << "Exit: " << i << " RoomID: " << exit_room_id
@@ -1069,22 +1108,24 @@ void Overworld::LoadExits() {
<< " DoorType2: " << exit_door_type_2 << std::endl;
}
if ((px & py) == 0xFFFF) {
exit.deleted = true;
}
exits.push_back(exit);
exits.emplace_back(exit_room_id, exit_map_id, exit_vram, exit_y_scroll,
exit_x_scroll, py, px, exit_y_camera, exit_x_camera,
exit_scroll_mod_y, exit_scroll_mod_x, exit_door_type_1,
exit_door_type_2, (px & py) == 0xFFFF);
}
all_exits_ = exits;
}
absl::Status Overworld::LoadItems() {
ASSIGN_OR_RETURN(int pointer, rom()->ReadLong(zelda3::overworldItemsAddress));
int oointerPC = core::SnesToPc(pointer); // 1BC2F9 -> 0DC2F9
int pointer_pc = core::SnesToPc(pointer); // 1BC2F9 -> 0DC2F9
for (int i = 0; i < 128; i++) {
int addr = (pointer & 0xFF0000) + // 1B
(rom()->data()[oointerPC + (i * 2) + 1] << 8) + // F9
rom()->data()[oointerPC + (i * 2)]; // 3C
ASSIGN_OR_RETURN(uint16_t word_address,
rom()->ReadWord(pointer_pc + i * 2));
int addr = (pointer & 0xFF0000) | word_address; // 1B
// (rom()->data()[pointer_pc + (i * 2) + 1] << 8) + // F9
// rom()->data()[pointer_pc + (i * 2)]; // 3C
addr = core::SnesToPc(addr);
@@ -1095,9 +1136,9 @@ absl::Status Overworld::LoadItems() {
}
while (true) {
uint8_t b1 = rom()->data()[addr];
uint8_t b2 = rom()->data()[addr + 1];
uint8_t b3 = rom()->data()[addr + 2];
ASSIGN_OR_RETURN(uint8_t b1, rom()->ReadByte(addr));
ASSIGN_OR_RETURN(uint8_t b2, rom()->ReadByte(addr + 1));
ASSIGN_OR_RETURN(uint8_t b3, rom()->ReadByte(addr + 2));
if (b1 == 0xFF && b2 == 0xFF) {
break;
@@ -1116,51 +1157,41 @@ absl::Status Overworld::LoadItems() {
int sy = fakeID / 8;
int sx = fakeID - (sy * 8);
all_items_.emplace_back(zelda3::OverworldItem(
b3, (ushort)i, (x * 16) + (sx * 512), (y * 16) + (sy * 512), false));
all_items_.emplace_back(b3, (ushort)i, (x * 16) + (sx * 512),
(y * 16) + (sy * 512), false);
auto size = all_items_.size();
all_items_.at(size - 1).game_x = (uint8_t)x;
all_items_.at(size - 1).game_y = (uint8_t)y;
all_items_[size - 1].game_x = (uint8_t)x;
all_items_[size - 1].game_y = (uint8_t)y;
addr += 3;
}
}
return absl::OkStatus();
}
void Overworld::LoadSprites() {
absl::Status Overworld::LoadSprites() {
for (int i = 0; i < 3; i++) {
all_sprites_.emplace_back();
}
for (int i = 0; i < 64; i++) {
all_sprites_[0].emplace_back();
}
for (int i = 0; i < 144; i++) {
all_sprites_[1].emplace_back();
}
for (int i = 0; i < 144; i++) {
all_sprites_[2].emplace_back();
}
LoadSpritesFromMap(overworldSpritesBegining, 64, 0);
LoadSpritesFromMap(overworldSpritesZelda, 144, 1);
LoadSpritesFromMap(overworldSpritesAgahnim, 144, 2);
RETURN_IF_ERROR(LoadSpritesFromMap(overworldSpritesBegining, 64, 0));
RETURN_IF_ERROR(LoadSpritesFromMap(overworldSpritesZelda, 144, 1));
RETURN_IF_ERROR(LoadSpritesFromMap(overworldSpritesAgahnim, 144, 2));
return absl::OkStatus();
}
void Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
int sprite_index) {
absl::Status Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
int sprite_index) {
for (int i = 0; i < sprite_count; i++) {
if (map_parent_[i] != i) continue;
int ptrPos = sprite_start + (i * 2);
int sprite_address =
core::SnesToPc((0x09 << 0x10) | rom()->toint16(ptrPos));
ASSIGN_OR_RETURN(auto word_addr, rom()->ReadWord(ptrPos));
int sprite_address = core::SnesToPc((0x09 << 0x10) | word_addr);
while (true) {
uchar b1 = rom_[sprite_address];
uchar b2 = rom_[sprite_address + 1];
uchar b3 = rom_[sprite_address + 2];
ASSIGN_OR_RETURN(uint8_t b1, rom()->ReadByte(sprite_address));
ASSIGN_OR_RETURN(uint8_t b2, rom()->ReadByte(sprite_address + 1));
ASSIGN_OR_RETURN(uint8_t b3, rom()->ReadByte(sprite_address + 2));
if (b1 == 0xFF) break;
int editor_map_index = i;
@@ -1175,14 +1206,16 @@ void Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
int realX = ((b2 & 0x3F) * 16) + mapX * 512;
int realY = ((b1 & 0x3F) * 16) + mapY * 512;
all_sprites_[sprite_index][i].InitSprite(
overworld_maps_[i].AreaGraphics(), (uchar)i, b3, (uchar)(b2 & 0x3F),
(uchar)(b1 & 0x3F), realX, realY);
all_sprites_[sprite_index][i].Draw();
all_sprites_[sprite_index].emplace_back(overworld_maps_[i].AreaGraphics(),
(uchar)i, b3, (uchar)(b2 & 0x3F),
(uchar)(b1 & 0x3F), realX, realY);
// all_sprites_[sprite_index][i].Draw();
sprite_address += 3;
}
}
return absl::OkStatus();
}
absl::Status Overworld::SaveMapProperties() {

View File

@@ -14,6 +14,7 @@
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
#include "app/zelda3/common.h"
#include "app/zelda3/overworld_map.h"
#include "app/zelda3/sprite/sprite.h"
@@ -21,33 +22,6 @@ namespace yaze {
namespace app {
namespace zelda3 {
class OverworldEntity {
public:
enum EntityType {
kEntrance = 0,
kExit = 1,
kItem = 2,
kSprite = 3,
kTransport = 4,
kMusic = 5,
kTilemap = 6,
kProperties = 7
} type_;
int x_;
int y_;
int game_x_;
int game_y_;
int entity_id_;
int map_id_;
auto set_x(int x) { x_ = x; }
auto set_y(int y) { y_ = y; }
OverworldEntity() = default;
virtual void UpdateMapProperties(short map_id) = 0;
};
// List of secret item names
const std::vector<std::string> kSecretItemNames = {
"Nothing", // 0
@@ -96,15 +70,6 @@ class OverworldItem : public OverworldEntity {
bool deleted = false;
OverworldItem() = default;
/// <summary>
/// Initializes a new instance of the <see cref="OverworldItem"/>
/// class.
/// </summary>
/// <param name="id"> The ID. </param>
/// <param name="room_map_id"> The dungeon room ID or overworld area ID.
/// </param> <param name="x"> The in editor X position. </param> <param
/// name="y"> The in editor Y position. </param> <param name="bg2"> Whether
/// the Item is on BG2 or not. </param>
OverworldItem(uint8_t id, uint16_t room_map_id, int x, int y, bool bg2) {
this->id = id;
this->x_ = x;
@@ -123,12 +88,6 @@ class OverworldItem : public OverworldEntity {
// this->unique_id = ROM.unique_item_id++;
}
/// <summary>
/// Updates the item info when needed. Generally when moving items around
/// in editor.
/// </summary>
/// <param name="room_map_id"> The dungeon room ID or overworld area ID where
/// the item was moved to. </param>
void UpdateMapProperties(int16_t room_map_id) override {
this->room_map_id = static_cast<uint16_t>(room_map_id);
@@ -205,7 +164,7 @@ class OverworldExit : public OverworldEntity {
uchar area_x_;
uchar area_y_;
bool is_hole_ = false;
bool deleted = false;
bool deleted_ = false;
bool is_automatic_ = false;
bool large_map_ = false;
@@ -214,7 +173,7 @@ class OverworldExit : public OverworldEntity {
ushort y_scroll, ushort x_scroll, ushort player_y,
ushort player_x, ushort camera_y, ushort camera_x,
uchar scroll_mod_y, uchar scroll_mod_x, ushort door_type_1,
ushort door_type_2)
ushort door_type_2, bool deleted = false)
: map_pos_(vram_location),
entrance_id_(0),
area_x_(0),
@@ -230,7 +189,8 @@ class OverworldExit : public OverworldEntity {
scroll_mod_y_(scroll_mod_y),
scroll_mod_x_(scroll_mod_x),
door_type_1_(door_type_1),
door_type_2_(door_type_2) {
door_type_2_(door_type_2),
deleted_(deleted) {
// Initialize entity variables
this->x_ = player_x;
this->y_ = player_y;
@@ -494,6 +454,10 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
absl::Status SaveMapProperties();
int GetTile16Id(int grid_id) const {
return map_tiles_.light_world[game_state_][grid_id];
}
auto overworld_maps() const { return overworld_maps_; }
auto overworld_map(int i) const { return &overworld_maps_[i]; }
auto mutable_overworld_map(int i) { return &overworld_maps_[i]; }
@@ -528,6 +492,8 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
auto all_items() const { return all_items_; }
auto mutable_all_items() { return &all_items_; }
auto &ref_all_items() { return all_items_; }
auto all_tiles_types() const { return all_tiles_types_; }
auto mutable_all_tiles_types() { return &all_tiles_types_; }
absl::Status LoadPrototype(ROM &rom_, const std::string &tilemap_filename);
@@ -549,11 +515,13 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
absl::Status DecompressAllMapTiles();
absl::Status DecompressProtoMapTiles(const std::string &filename);
void FetchLargeMaps();
void LoadTileTypes();
void LoadEntrances();
void LoadExits();
absl::Status LoadItems();
void LoadSprites();
void LoadSpritesFromMap(int spriteStart, int spriteCount, int spriteIndex);
absl::Status LoadSprites();
absl::Status LoadSpritesFromMap(int spriteStart, int spriteCount,
int spriteIndex);
bool is_loaded_ = false;
@@ -564,6 +532,8 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
ROM rom_;
OWMapTiles map_tiles_;
uint8_t all_tiles_types_[0x200];
std::vector<gfx::Tile16> tiles16_;
std::vector<gfx::Tile32> tiles32;
std::vector<gfx::Tile32> tiles32_unique_;

View File

@@ -9,6 +9,7 @@
#include <vector>
#include "app/core/common.h"
#include "app/editor/context/gfx_context.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
@@ -18,138 +19,6 @@ namespace yaze {
namespace app {
namespace zelda3 {
namespace {
void CopyTile8bpp16(int x, int y, int tile, Bytes& bitmap, Bytes& blockset) {
int src_pos =
((tile - ((tile / 0x08) * 0x08)) * 0x10) + ((tile / 0x08) * 2048);
int dest_pos = (x + (y * 0x200));
for (int yy = 0; yy < 0x10; yy++) {
for (int xx = 0; xx < 0x10; xx++) {
bitmap[dest_pos + xx + (yy * 0x200)] =
blockset[src_pos + xx + (yy * 0x80)];
}
}
}
void SetColorsPalette(ROM& rom, int index, gfx::SNESPalette& current,
gfx::SNESPalette main, gfx::SNESPalette animated,
gfx::SNESPalette aux1, gfx::SNESPalette aux2,
gfx::SNESPalette hud, gfx::SNESColor bgrcolor,
gfx::SNESPalette spr, gfx::SNESPalette spr2) {
// Palettes infos, color 0 of a palette is always transparent (the arrays
// contains 7 colors width wide) There is 16 color per line so 16*Y
// Left side of the palette - Main, Animated
std::vector<gfx::SNESColor> new_palette(256);
// Main Palette, Location 0,2 : 35 colors [7x5]
int k = 0;
for (int y = 2; y < 7; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = main[k];
k++;
}
}
// Animated Palette, Location 0,7 : 7colors
for (int x = 1; x < 8; x++) {
new_palette[(16 * 7) + (x)] = animated[(x - 1)];
}
// Right side of the palette - Aux1, Aux2
// Aux1 Palette, Location 8,2 : 21 colors [7x3]
k = 0;
for (int y = 2; y < 5; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = aux1[k];
k++;
}
}
// Aux2 Palette, Location 8,5 : 21 colors [7x3]
k = 0;
for (int y = 5; y < 8; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = aux2[k];
k++;
}
}
// Hud Palette, Location 0,0 : 32 colors [16x2]
for (int i = 0; i < 32; i++) {
new_palette[i] = hud[i];
}
// Hardcoded grass color (that might change to become invisible instead)
for (int i = 0; i < 8; i++) {
new_palette[(i * 16)] = bgrcolor;
new_palette[(i * 16) + 8] = bgrcolor;
}
// Sprite Palettes
k = 0;
for (int y = 8; y < 9; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = rom.palette_group("sprites_aux1")[1][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 8; y < 9; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("sprites_aux3")[0][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 9; y < 13; y++) {
for (int x = 1; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("global_sprites")[0][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 13; y < 14; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = spr[k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 14; y < 15; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = spr2[k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 15; y < 16; y++) {
for (int x = 1; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("armors")[0][k];
k++;
}
}
current.Create(new_palette);
for (int i = 0; i < 256; i++) {
current[(i / 16) * 16].SetTransparent(true);
}
}
} // namespace
OverworldMap::OverworldMap(int index, ROM& rom,
std::vector<gfx::Tile16>& tiles16)
: parent_(index), index_(index), rom_(rom), tiles16_(tiles16) {
@@ -322,14 +191,6 @@ void OverworldMap::DrawAnimatedTiles() {
}
static_graphics_[7] = 0x5B;
}
// if (static_graphics_[7] == 0x5A) {
// static_graphics_[7] = 0x5B;
// } else {
// if (static_graphics_[7] == 0x58) {
// static_graphics_[7] = 0x59;
// }
// static_graphics_[7] = 0x5A;
// }
}
void OverworldMap::LoadAreaGraphicsBlocksets() {
@@ -359,6 +220,125 @@ void OverworldMap::LoadAreaGraphics() {
LoadDeathMountainGFX();
}
namespace palette_internal {
void SetColorsPalette(ROM& rom, int index, gfx::SNESPalette& current,
gfx::SNESPalette main, gfx::SNESPalette animated,
gfx::SNESPalette aux1, gfx::SNESPalette aux2,
gfx::SNESPalette hud, gfx::SNESColor bgrcolor,
gfx::SNESPalette spr, gfx::SNESPalette spr2) {
// Palettes infos, color 0 of a palette is always transparent (the arrays
// contains 7 colors width wide) There is 16 color per line so 16*Y
// Left side of the palette - Main, Animated
std::vector<gfx::SNESColor> new_palette(256);
// Main Palette, Location 0,2 : 35 colors [7x5]
int k = 0;
for (int y = 2; y < 7; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = main[k];
k++;
}
}
// Animated Palette, Location 0,7 : 7colors
for (int x = 1; x < 8; x++) {
new_palette[(16 * 7) + (x)] = animated[(x - 1)];
}
// Right side of the palette - Aux1, Aux2
// Aux1 Palette, Location 8,2 : 21 colors [7x3]
k = 0;
for (int y = 2; y < 5; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = aux1[k];
k++;
}
}
// Aux2 Palette, Location 8,5 : 21 colors [7x3]
k = 0;
for (int y = 5; y < 8; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = aux2[k];
k++;
}
}
// Hud Palette, Location 0,0 : 32 colors [16x2]
for (int i = 0; i < 32; i++) {
new_palette[i] = hud[i];
}
// Hardcoded grass color (that might change to become invisible instead)
for (int i = 0; i < 8; i++) {
new_palette[(i * 16)] = bgrcolor;
new_palette[(i * 16) + 8] = bgrcolor;
}
// Sprite Palettes
k = 0;
for (int y = 8; y < 9; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = rom.palette_group("sprites_aux1")[1][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 8; y < 9; y++) {
for (int x = 9; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("sprites_aux3")[0][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 9; y < 13; y++) {
for (int x = 1; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("global_sprites")[0][k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 13; y < 14; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = spr[k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 14; y < 15; y++) {
for (int x = 1; x < 8; x++) {
new_palette[x + (16 * y)] = spr2[k];
k++;
}
}
// Sprite Palettes
k = 0;
for (int y = 15; y < 16; y++) {
for (int x = 1; x < 16; x++) {
new_palette[x + (16 * y)] = rom.palette_group("armors")[0][k];
k++;
}
}
current.Create(new_palette);
for (int i = 0; i < 256; i++) {
current[(i / 16) * 16].SetTransparent(true);
}
}
} // namespace palette_internal
// New helper function to get a palette from the ROM.
gfx::SNESPalette OverworldMap::GetPalette(const std::string& group, int index,
int previousIndex, int limit) {
@@ -427,8 +407,11 @@ void OverworldMap::LoadPalette() {
gfx::SNESPalette spr2 =
GetPalette("sprites_aux3", pal5, previousSprPalId, 24);
SetColorsPalette(rom_, parent_, current_palette_, main, animated, aux1, aux2,
hud, bgr, spr, spr2);
palette_internal::SetColorsPalette(rom_, parent_, current_palette_, main,
animated, aux1, aux2, hud, bgr, spr, spr2);
gfx::Paletteset paletteset{main, animated, aux1, aux2, bgr, hud, spr, spr2};
palettesets_[area_graphics_] = paletteset;
}
// New helper function to process graphics buffer.
@@ -450,7 +433,7 @@ void OverworldMap::ProcessGraphicsBuffer(int index, int static_graphics_offset,
absl::Status OverworldMap::BuildTileset() {
all_gfx_ = rom_.graphics_buffer();
current_gfx_.resize(0x10000, 0x00);
if (current_gfx_.size() == 0) current_gfx_.resize(0x10000, 0x00);
for (int i = 0; i < 0x10; i++) {
ProcessGraphicsBuffer(i, static_graphics_[i], 0x1000);
@@ -460,13 +443,8 @@ absl::Status OverworldMap::BuildTileset() {
}
absl::Status OverworldMap::BuildTiles16Gfx(int count) {
if (current_blockset_.size() != 0) {
current_blockset_.clear();
}
current_blockset_.reserve(0x100000);
for (int i = 0; i < 0x100000; i++) {
current_blockset_.push_back(0x00);
}
if (current_blockset_.size() == 0) current_blockset_.resize(0x100000, 0x00);
const int offsets[] = {0x00, 0x08, 0x400, 0x408};
auto yy = 0;
auto xx = 0;
@@ -509,6 +487,22 @@ absl::Status OverworldMap::BuildTiles16Gfx(int count) {
return absl::OkStatus();
}
namespace {
void CopyTile8bpp16(int x, int y, int tile, Bytes& bitmap, Bytes& blockset) {
int src_pos =
((tile - ((tile / 0x08) * 0x08)) * 0x10) + ((tile / 0x08) * 2048);
int dest_pos = (x + (y * 0x200));
for (int yy = 0; yy < 0x10; yy++) {
for (int xx = 0; xx < 0x10; xx++) {
bitmap[dest_pos + xx + (yy * 0x200)] =
blockset[src_pos + xx + (yy * 0x80)];
}
}
}
} // namespace
absl::Status OverworldMap::BuildBitmap(OWBlockset& world_blockset) {
if (bitmap_data_.size() != 0) {
bitmap_data_.clear();

View File

@@ -11,6 +11,7 @@
#include "absl/status/status.h"
#include "app/core/common.h"
#include "app/editor/context/gfx_context.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
@@ -22,7 +23,9 @@ namespace zelda3 {
static constexpr int kTileOffsets[] = {0, 8, 4096, 4104};
class OverworldMap {
using editor::GfxContext;
class OverworldMap : public GfxContext {
public:
OverworldMap() = default;
OverworldMap(int index, ROM& rom, std::vector<gfx::Tile16>& tiles16);
@@ -38,6 +41,7 @@ class OverworldMap {
void DrawAnimatedTiles();
auto Tile16Blockset() const { return current_blockset_; }
auto AreaGraphics() const { return current_gfx_; }
auto AreaPalette() const { return current_palette_; }
@@ -46,7 +50,7 @@ class OverworldMap {
auto IsLargeMap() const { return large_map_; }
auto IsInitialized() const { return initialized_; }
auto Parent() const { return parent_; }
auto mutable_current_palette() { return &current_palette_; }
auto area_graphics() const { return area_graphics_; }

View File

@@ -4,39 +4,40 @@ namespace yaze {
namespace app {
namespace zelda3 {
Sprite::Sprite() {
preview_gfx_.reserve(64 * 64);
for (int i = 0; i < 64 * 64; i++) {
preview_gfx_.push_back(0xFF);
}
}
void Sprite::InitSprite(const Bytes& src, uchar mapid, uchar id, uchar x,
uchar y, int map_x, int map_y) {
current_gfx_ = src;
overworld_ = true;
map_id_ = mapid;
map_id_ = static_cast<int>(mapid);
id_ = id;
x_ = x;
y_ = y;
this->type_ = zelda3::OverworldEntity::EntityType::kSprite;
this->entity_id_ = id;
this->x_ = map_x_;
this->y_ = map_y_;
nx_ = x;
ny_ = y;
name_ = core::kSpriteDefaultNames[id];
map_x_ = map_x;
map_y_ = map_y;
preview_gfx_.reserve(64 * 64);
for (int i = 0; i < 64 * 64; i++) {
preview_gfx_.push_back(0xFF);
}
}
Sprite::Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x,
int map_y)
: current_gfx_(src),
map_id_(mapid),
map_id_(static_cast<int>(mapid)),
id_(id),
x_(x),
y_(y),
nx_(x),
ny_(y),
map_x_(map_x),
map_y_(map_y) {
this->type_ = zelda3::OverworldEntity::EntityType::kSprite;
this->entity_id_ = id;
this->x_ = map_x_;
this->y_ = map_y_;
current_gfx_ = src;
overworld_ = true;
@@ -47,6 +48,12 @@ Sprite::Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x,
}
}
void Sprite::UpdateMapProperties(short map_id) {
map_x_ = x_;
map_y_ = y_;
name_ = core::kSpriteDefaultNames[id_];
}
void Sprite::updateCoordinates(int map_x, int map_y) {
map_x_ = map_x;
map_y_ = map_y;

View File

@@ -13,14 +13,15 @@
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
#include "app/zelda3/common.h"
namespace yaze {
namespace app {
namespace zelda3 {
class Sprite {
class Sprite : public OverworldEntity {
public:
Sprite();
Sprite() = default;
Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x,
int map_y);
void InitSprite(const Bytes& src, uchar mapid, uchar id, uchar x, uchar y,
@@ -32,13 +33,14 @@ class Sprite {
bool mirror_x = false, bool mirror_y = false,
int sizex = 2, int sizey = 2);
void UpdateMapProperties(short map_id) override;
// New methods
void updateCoordinates(int map_x, int map_y);
auto PreviewGraphics() const { return preview_gfx_; }
auto GetRealX() const { return bounding_box_.x; }
auto GetRealY() const { return bounding_box_.y; }
auto id() const { return id_; }
auto set_id(uchar id) { id_ = id; }
auto x() const { return x_; }
auto y() const { return y_; }
auto nx() const { return nx_; }
@@ -55,6 +57,7 @@ class Sprite {
auto Height() const { return bounding_box_.h; }
std::string& Name() { return name_; }
auto deleted() const { return deleted_; }
auto set_deleted(bool deleted) { deleted_ = deleted; }
private:
Bytes current_gfx_;
@@ -62,8 +65,8 @@ class Sprite {
uchar map_id_;
uchar id_;
uchar x_;
uchar y_;
// uchar x_;
// uchar y_;
uchar nx_;
uchar ny_;
uchar overlord_ = 0;