154 lines
5.3 KiB
C++
154 lines
5.3 KiB
C++
#include "app/core/platform/renderer.h"
|
|
#include "app/editor/overworld/overworld_editor.h"
|
|
|
|
namespace yaze {
|
|
namespace app {
|
|
namespace editor {
|
|
|
|
using core::Renderer;
|
|
|
|
void OverworldEditor::RefreshChildMap(int map_index) {
|
|
overworld_.mutable_overworld_map(map_index)->LoadAreaGraphics();
|
|
status_ = overworld_.mutable_overworld_map(map_index)->BuildTileset();
|
|
PRINT_IF_ERROR(status_);
|
|
status_ = overworld_.mutable_overworld_map(map_index)->BuildTiles16Gfx(
|
|
*overworld_.mutable_tiles16(), overworld_.tiles16().size());
|
|
PRINT_IF_ERROR(status_);
|
|
status_ = overworld_.mutable_overworld_map(map_index)->BuildBitmap(
|
|
overworld_.GetMapTiles(current_world_));
|
|
maps_bmp_[map_index].set_data(
|
|
overworld_.mutable_overworld_map(map_index)->bitmap_data());
|
|
maps_bmp_[map_index].set_modified(true);
|
|
PRINT_IF_ERROR(status_);
|
|
}
|
|
|
|
void OverworldEditor::RefreshOverworldMap() {
|
|
std::vector<std::future<void>> futures;
|
|
int indices[4];
|
|
|
|
auto refresh_map_async = [this](int map_index) {
|
|
RefreshChildMap(map_index);
|
|
};
|
|
|
|
int source_map_id = current_map_;
|
|
bool is_large = overworld_.overworld_map(current_map_)->is_large_map();
|
|
if (is_large) {
|
|
source_map_id = current_parent_;
|
|
// We need to update the map and its siblings if it's a large map
|
|
for (int i = 1; i < 4; i++) {
|
|
int sibling_index = overworld_.overworld_map(source_map_id)->parent() + i;
|
|
if (i >= 2) sibling_index += 6;
|
|
futures.push_back(
|
|
std::async(std::launch::async, refresh_map_async, sibling_index));
|
|
indices[i] = sibling_index;
|
|
}
|
|
}
|
|
indices[0] = source_map_id;
|
|
futures.push_back(
|
|
std::async(std::launch::async, refresh_map_async, source_map_id));
|
|
|
|
for (auto &each : futures) {
|
|
each.get();
|
|
}
|
|
int n = is_large ? 4 : 1;
|
|
// We do texture updating on the main thread
|
|
for (int i = 0; i < n; ++i) {
|
|
Renderer::GetInstance().UpdateBitmap(&maps_bmp_[indices[i]]);
|
|
}
|
|
}
|
|
|
|
absl::Status OverworldEditor::RefreshMapPalette() {
|
|
RETURN_IF_ERROR(
|
|
overworld_.mutable_overworld_map(current_map_)->LoadPalette());
|
|
const auto current_map_palette = overworld_.current_area_palette();
|
|
|
|
if (overworld_.overworld_map(current_map_)->is_large_map()) {
|
|
// We need to update the map and its siblings if it's a large map
|
|
for (int i = 1; i < 4; i++) {
|
|
int sibling_index = overworld_.overworld_map(current_map_)->parent() + i;
|
|
if (i >= 2) sibling_index += 6;
|
|
RETURN_IF_ERROR(
|
|
overworld_.mutable_overworld_map(sibling_index)->LoadPalette());
|
|
RETURN_IF_ERROR(
|
|
maps_bmp_[sibling_index].ApplyPalette(current_map_palette));
|
|
}
|
|
}
|
|
|
|
RETURN_IF_ERROR(maps_bmp_[current_map_].ApplyPalette(current_map_palette));
|
|
return absl::OkStatus();
|
|
}
|
|
|
|
void OverworldEditor::RefreshMapProperties() {
|
|
auto ¤t_ow_map = *overworld_.mutable_overworld_map(current_map_);
|
|
if (current_ow_map.is_large_map()) {
|
|
// We need to copy the properties from the parent map to the children
|
|
for (int i = 1; i < 4; i++) {
|
|
int sibling_index = current_ow_map.parent() + i;
|
|
if (i >= 2) {
|
|
sibling_index += 6;
|
|
}
|
|
auto &map = *overworld_.mutable_overworld_map(sibling_index);
|
|
map.set_area_graphics(current_ow_map.area_graphics());
|
|
map.set_area_palette(current_ow_map.area_palette());
|
|
map.set_sprite_graphics(game_state_,
|
|
current_ow_map.sprite_graphics(game_state_));
|
|
map.set_sprite_palette(game_state_,
|
|
current_ow_map.sprite_palette(game_state_));
|
|
map.set_message_id(current_ow_map.message_id());
|
|
}
|
|
}
|
|
}
|
|
|
|
absl::Status OverworldEditor::RefreshTile16Blockset() {
|
|
if (current_blockset_ ==
|
|
overworld_.overworld_map(current_map_)->area_graphics()) {
|
|
return absl::OkStatus();
|
|
}
|
|
current_blockset_ = overworld_.overworld_map(current_map_)->area_graphics();
|
|
|
|
overworld_.set_current_map(current_map_);
|
|
palette_ = overworld_.current_area_palette();
|
|
// Create the tile16 blockset image
|
|
Renderer::GetInstance().UpdateBitmap(&tile16_blockset_bmp_);
|
|
RETURN_IF_ERROR(tile16_blockset_bmp_.ApplyPalette(palette_));
|
|
|
|
// Copy the tile16 data into individual tiles.
|
|
const auto tile16_data = overworld_.tile16_blockset_data();
|
|
|
|
std::vector<std::future<void>> futures;
|
|
// Loop through the tiles and copy their pixel data into separate vectors
|
|
for (uint i = 0; i < zelda3::overworld::kNumTile16Individual; i++) {
|
|
futures.push_back(std::async(
|
|
std::launch::async,
|
|
[&](int index) {
|
|
std::vector<uint8_t> tile_data(16 * 16, 0x00);
|
|
for (int ty = 0; ty < 16; ty++) {
|
|
for (int tx = 0; tx < 16; tx++) {
|
|
int position = tx + (ty * 0x10);
|
|
uint8_t value =
|
|
tile16_data[(index % 8 * 16) + (index / 8 * 16 * 0x80) +
|
|
(ty * 0x80) + tx];
|
|
tile_data[position] = value;
|
|
}
|
|
}
|
|
tile16_individual_[index].set_data(tile_data);
|
|
},
|
|
i));
|
|
}
|
|
|
|
for (auto &future : futures) {
|
|
future.get();
|
|
}
|
|
|
|
// Render the bitmaps of each tile.
|
|
for (uint id = 0; id < zelda3::overworld::kNumTile16Individual; id++) {
|
|
RETURN_IF_ERROR(tile16_individual_[id].ApplyPalette(palette_));
|
|
Renderer::GetInstance().UpdateBitmap(&tile16_individual_[id]);
|
|
}
|
|
|
|
return absl::OkStatus();
|
|
}
|
|
|
|
} // namespace editor
|
|
} // namespace app
|
|
} // namespace yaze
|