12 float screen_y)
const {
44 float canvas_y)
const {
116 const float tile16_size = 16.0f;
124 int tile_x =
static_cast<int>(canvas_x / tile16_size);
125 int tile_y =
static_cast<int>(canvas_y / tile16_size);
127 if (tile_x < 0 || tile_y < 0 || tile_x >= tile16_per_row) {
131 return tile_y * tile16_per_row + tile_x;
142 return tile_x >= 0 && tile_y >= 0 &&
148 uint32_t base_offset)
const {
157 return base_offset + (tile_id * 8);
159 return base_offset + (tile_id * 32);
164 float content_y)
const {
173 const int maps_per_row = 8;
174 return local_y * maps_per_row + local_x;
178 const std::vector<std::pair<float, float>>& positions)
const {
179 std::vector<ScreenToTileResult> results;
180 results.reserve(positions.size());
182 for (
const auto& [x, y] : positions) {
190 float canvas_y)
const {
209 return {tile_x, tile_y};
215 float screen_x,
float screen_y,
220 if (screen_x < runtime.canvas_p0.x || screen_x >= runtime.
canvas_p0.x + runtime.
canvas_sz.x ||
221 screen_y < runtime.canvas_p0.y || screen_y >= runtime.
canvas_p0.y + runtime.
canvas_sz.y) {
227 float canvas_x = screen_x - runtime.
canvas_p0.x;
228 float canvas_y = screen_y - runtime.
canvas_p0.y;
231 float scale = runtime.
scale > 0 ? runtime.
scale : 1.0f;
232 float scaled_x = canvas_x / scale;
233 float scaled_y = canvas_y / scale;
236 float content_x = scaled_x - runtime.
scrolling.x;
237 float content_y = scaled_y - runtime.
scrolling.y;
240 if (content_x < 0 || content_y < 0 || tile_size <= 0) {
245 int tile_x =
static_cast<int>(content_x / tile_size);
246 int tile_y =
static_cast<int>(content_y / tile_size);
249 int tiles_per_row =
static_cast<int>(runtime.
canvas_sz.x / (tile_size * scale));
250 if (tiles_per_row <= 0) tiles_per_row = 32;
254 info.
tile_id = tile_y * tiles_per_row + tile_x;
255 info.
tile_origin_px = ImVec2(tile_x * tile_size, tile_y * tile_size);
263 float tile_size,
int tiles_per_row) {
264 if (tile_size <= 0 || tiles_per_row <= 0) {
268 int tile_x =
static_cast<int>(local_x / tile_size);
269 int tile_y =
static_cast<int>(local_y / tile_size);
271 if (tile_x < 0 || tile_y < 0 || tile_x >= tiles_per_row) {
275 return tile_y * tiles_per_row + tile_x;
279 float x = tile_x * tile_size * scale;
280 float y = tile_y * tile_size * scale;
281 float w = tile_size * scale;
282 float h = tile_size * scale;
283 return ImVec4(x, y, x + w, y + h);
bool IsInCanvasBounds(float screen_x, float screen_y) const
Check if screen coordinates are within canvas bounds.
int GetTileId(float canvas_x, float canvas_y) const
Get tile ID from canvas position.
std::pair< int, int > SnapToTileGrid(float x, float y) const
ImVec2 TileToScreen(int tile_x, int tile_y) const
Convert tile coordinates to screen position.
ImVec2 ApplyInverseScale(float x, float y) const
ScreenToTileResult ScreenToTile(float screen_x, float screen_y) const
Convert screen coordinates to tile information.
std::vector< ScreenToTileResult > ScreenToTileBatch(const std::vector< std::pair< float, float > > &positions) const
Convert multiple screen positions to tile info.
TileHitInfo CanvasToTile(float canvas_x, float canvas_y) const
Convert canvas-relative coordinates to tile information.
int GetTile16Index(float canvas_x, float canvas_y) const
Get tile16 index from canvas position.
ImVec2 ApplyScrollOffset(float canvas_x, float canvas_y) const
int CalculateLocalMapId(float content_x, float content_y) const
Calculate local map ID from content coordinates.
CoordinateMapperConfig config_
bool IsValidTileCoord(int tile_x, int tile_y) const
Check if tile coordinates are valid.
RomOffsetCalculator rom_offset_calculator_
uint32_t CalculateRomOffset(int tile_id, uint32_t base_offset=0) const
Calculate ROM offset for a given tile ID.
ImVec2 TileToCanvas(int tile_x, int tile_y) const
Convert tile coordinates to canvas position.
int CalculateTileIndex(float local_x, float local_y, float tile_size, int tiles_per_row)
Calculate tile index from local position and grid settings.
ImVec4 GetTileBounds(int tile_x, int tile_y, float tile_size, float scale)
Get tile bounds in canvas space.
TileHitInfo ScreenToTileQuick(const CanvasRuntime &runtime, float screen_x, float screen_y, float tile_size)
Quick screen-to-tile lookup using canvas runtime state.
bool use_tile16
Use 16x16 tile indexing.
int tiles_per_col
Number of tiles per column.
int local_map_size
Size of local map in pixels (512 for OW)
int tiles_per_row
Number of tiles per row in the map.
float tile_size
Size of tiles in pixels (8 or 16)
Screen coordinate mapping result.
float scaled_x
X after applying inverse scale.
TileHitInfo tile_info
Full tile information.
float scaled_y
Y after applying inverse scale.
float canvas_x
X position relative to canvas origin.
float canvas_y
Y position relative to canvas origin.
float content_y
Y in content space (with scroll)
float screen_x
Original screen X coordinate.
float screen_y
Original screen Y coordinate.
bool in_canvas_bounds
Whether point is within canvas.
float content_x
X in content space (with scroll)
Information about a tile at a specific screen location.
bool is_valid
Whether the hit is valid.
ImVec2 tile_origin_px
Top-left of tile in canvas space (pixels)
uint32_t rom_offset
ROM offset for tile data.
std::string canvas_id
ID of the canvas that was hit.
int tile_id
8x8 tile ID (-1 if invalid)
int map_y
Tile Y coordinate in map space.
int tile16_index
16x16 tile index (-1 if invalid)
int local_map_id
Local map ID (for overworld)
int map_x
Tile X coordinate in map space.
ImVec2 tile_size_px
Size of the tile in pixels.