backend-infra-engineer: Release v0.3.3 snapshot
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "app/rom.h"
|
||||
#include "zelda3/overworld/overworld.h"
|
||||
@@ -12,23 +13,25 @@ namespace yaze {
|
||||
namespace zelda3 {
|
||||
|
||||
class SpritePositionTest : public ::testing::Test {
|
||||
protected:
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Try to load a vanilla ROM for testing
|
||||
rom_ = std::make_unique<Rom>();
|
||||
std::string rom_path = "bin/zelda3.sfc";
|
||||
|
||||
|
||||
// Check if ROM exists in build directory
|
||||
std::ifstream rom_file(rom_path);
|
||||
if (rom_file.good()) {
|
||||
ASSERT_TRUE(rom_->LoadFromFile(rom_path).ok()) << "Failed to load ROM from " << rom_path;
|
||||
ASSERT_TRUE(rom_->LoadFromFile(rom_path).ok())
|
||||
<< "Failed to load ROM from " << rom_path;
|
||||
} else {
|
||||
// Skip test if ROM not found
|
||||
GTEST_SKIP() << "ROM file not found at " << rom_path;
|
||||
}
|
||||
|
||||
|
||||
overworld_ = std::make_unique<Overworld>(rom_.get());
|
||||
ASSERT_TRUE(overworld_->Load(rom_.get()).ok()) << "Failed to load overworld";
|
||||
ASSERT_TRUE(overworld_->Load(rom_.get()).ok())
|
||||
<< "Failed to load overworld";
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
@@ -47,24 +50,28 @@ TEST_F(SpritePositionTest, SpriteCoordinateSystem) {
|
||||
const auto& sprites = overworld_->sprites(game_state);
|
||||
std::cout << "\n=== Game State " << game_state << " ===" << std::endl;
|
||||
std::cout << "Total sprites: " << sprites.size() << std::endl;
|
||||
|
||||
|
||||
int sprite_count = 0;
|
||||
for (const auto& sprite : sprites) {
|
||||
if (!sprite.deleted() && sprite_count < 10) { // Show first 10 sprites
|
||||
std::cout << "Sprite " << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(sprite.id()) << " (" << const_cast<Sprite&>(sprite).name() << ")" << std::endl;
|
||||
std::cout << " Map ID: 0x" << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< sprite.map_id() << std::endl;
|
||||
std::cout << " X: " << std::dec << sprite.x() << " (0x" << std::hex << sprite.x() << ")" << std::endl;
|
||||
std::cout << " Y: " << std::dec << sprite.y() << " (0x" << std::hex << sprite.y() << ")" << std::endl;
|
||||
if (!sprite.deleted() && sprite_count < 10) { // Show first 10 sprites
|
||||
std::cout << "Sprite " << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(sprite.id()) << " ("
|
||||
<< const_cast<Sprite&>(sprite).name() << ")" << std::endl;
|
||||
std::cout << " Map ID: 0x" << std::hex << std::setw(2)
|
||||
<< std::setfill('0') << sprite.map_id() << std::endl;
|
||||
std::cout << " X: " << std::dec << sprite.x() << " (0x" << std::hex
|
||||
<< sprite.x() << ")" << std::endl;
|
||||
std::cout << " Y: " << std::dec << sprite.y() << " (0x" << std::hex
|
||||
<< sprite.y() << ")" << std::endl;
|
||||
std::cout << " map_x: " << std::dec << sprite.map_x() << std::endl;
|
||||
std::cout << " map_y: " << std::dec << sprite.map_y() << std::endl;
|
||||
|
||||
|
||||
// Calculate expected world ranges
|
||||
int world_start = game_state * 0x40;
|
||||
int world_end = world_start + 0x40;
|
||||
std::cout << " World range: 0x" << std::hex << world_start << " - 0x" << world_end << std::endl;
|
||||
|
||||
std::cout << " World range: 0x" << std::hex << world_start << " - 0x"
|
||||
<< world_end << std::endl;
|
||||
|
||||
sprite_count++;
|
||||
}
|
||||
}
|
||||
@@ -76,30 +83,32 @@ TEST_F(SpritePositionTest, SpriteFilteringLogic) {
|
||||
// Test the filtering logic used in DrawOverworldSprites
|
||||
for (int current_world = 0; current_world < 3; current_world++) {
|
||||
const auto& sprites = overworld_->sprites(current_world);
|
||||
|
||||
std::cout << "\n=== Testing World " << current_world << " Filtering ===" << std::endl;
|
||||
|
||||
|
||||
std::cout << "\n=== Testing World " << current_world
|
||||
<< " Filtering ===" << std::endl;
|
||||
|
||||
int visible_sprites = 0;
|
||||
int total_sprites = 0;
|
||||
|
||||
|
||||
for (const auto& sprite : sprites) {
|
||||
if (!sprite.deleted()) {
|
||||
total_sprites++;
|
||||
|
||||
|
||||
// This is the filtering logic from DrawOverworldSprites
|
||||
bool should_show = (sprite.map_id() < 0x40 + (current_world * 0x40) &&
|
||||
sprite.map_id() >= (current_world * 0x40));
|
||||
|
||||
sprite.map_id() >= (current_world * 0x40));
|
||||
|
||||
if (should_show) {
|
||||
visible_sprites++;
|
||||
std::cout << " Visible: Sprite 0x" << std::hex << static_cast<int>(sprite.id())
|
||||
<< " on map 0x" << sprite.map_id() << " at ("
|
||||
<< std::dec << sprite.x() << ", " << sprite.y() << ")" << std::endl;
|
||||
std::cout << " Visible: Sprite 0x" << std::hex
|
||||
<< static_cast<int>(sprite.id()) << " on map 0x"
|
||||
<< sprite.map_id() << " at (" << std::dec << sprite.x()
|
||||
<< ", " << sprite.y() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "World " << current_world << ": " << visible_sprites << "/"
|
||||
|
||||
std::cout << "World " << current_world << ": " << visible_sprites << "/"
|
||||
<< total_sprites << " sprites visible" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -109,45 +118,53 @@ TEST_F(SpritePositionTest, MapCoordinateCalculations) {
|
||||
// Test how map coordinates should be calculated
|
||||
for (int current_world = 0; current_world < 3; current_world++) {
|
||||
const auto& sprites = overworld_->sprites(current_world);
|
||||
|
||||
std::cout << "\n=== World " << current_world << " Coordinate Analysis ===" << std::endl;
|
||||
|
||||
|
||||
std::cout << "\n=== World " << current_world
|
||||
<< " Coordinate Analysis ===" << std::endl;
|
||||
|
||||
for (const auto& sprite : sprites) {
|
||||
if (!sprite.deleted() &&
|
||||
if (!sprite.deleted() &&
|
||||
sprite.map_id() < 0x40 + (current_world * 0x40) &&
|
||||
sprite.map_id() >= (current_world * 0x40)) {
|
||||
|
||||
// Calculate map position
|
||||
int sprite_map_id = sprite.map_id();
|
||||
int local_map_index = sprite_map_id - (current_world * 0x40);
|
||||
int map_col = local_map_index % 8;
|
||||
int map_row = local_map_index / 8;
|
||||
|
||||
int map_canvas_x = map_col * 512; // kOverworldMapSize
|
||||
|
||||
int map_canvas_x = map_col * 512; // kOverworldMapSize
|
||||
int map_canvas_y = map_row * 512;
|
||||
|
||||
std::cout << "Sprite 0x" << std::hex << static_cast<int>(sprite.id())
|
||||
|
||||
std::cout << "Sprite 0x" << std::hex << static_cast<int>(sprite.id())
|
||||
<< " on map 0x" << sprite_map_id << std::endl;
|
||||
std::cout << " Local map index: " << std::dec << local_map_index << std::endl;
|
||||
std::cout << " Map position: (" << map_col << ", " << map_row << ")" << std::endl;
|
||||
std::cout << " Map canvas pos: (" << map_canvas_x << ", " << map_canvas_y << ")" << std::endl;
|
||||
std::cout << " Sprite global pos: (" << sprite.x() << ", " << sprite.y() << ")" << std::endl;
|
||||
std::cout << " Sprite local pos: (" << sprite.map_x() << ", " << sprite.map_y() << ")" << std::endl;
|
||||
|
||||
std::cout << " Local map index: " << std::dec << local_map_index
|
||||
<< std::endl;
|
||||
std::cout << " Map position: (" << map_col << ", " << map_row << ")"
|
||||
<< std::endl;
|
||||
std::cout << " Map canvas pos: (" << map_canvas_x << ", "
|
||||
<< map_canvas_y << ")" << std::endl;
|
||||
std::cout << " Sprite global pos: (" << sprite.x() << ", "
|
||||
<< sprite.y() << ")" << std::endl;
|
||||
std::cout << " Sprite local pos: (" << sprite.map_x() << ", "
|
||||
<< sprite.map_y() << ")" << std::endl;
|
||||
|
||||
// Verify the calculation
|
||||
int expected_global_x = map_canvas_x + sprite.map_x();
|
||||
int expected_global_y = map_canvas_y + sprite.map_y();
|
||||
|
||||
std::cout << " Expected global: (" << expected_global_x << ", " << expected_global_y << ")" << std::endl;
|
||||
std::cout << " Actual global: (" << sprite.x() << ", " << sprite.y() << ")" << std::endl;
|
||||
|
||||
if (expected_global_x == sprite.x() && expected_global_y == sprite.y()) {
|
||||
|
||||
std::cout << " Expected global: (" << expected_global_x << ", "
|
||||
<< expected_global_y << ")" << std::endl;
|
||||
std::cout << " Actual global: (" << sprite.x() << ", " << sprite.y()
|
||||
<< ")" << std::endl;
|
||||
|
||||
if (expected_global_x == sprite.x() &&
|
||||
expected_global_y == sprite.y()) {
|
||||
std::cout << " ✓ Coordinates match!" << std::endl;
|
||||
} else {
|
||||
std::cout << " ✗ Coordinate mismatch!" << std::endl;
|
||||
}
|
||||
|
||||
break; // Only test first sprite for brevity
|
||||
|
||||
break; // Only test first sprite for brevity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user