mirror of
https://github.com/opentibiabr/remeres-map-editor
synced 2026-08-15 18:26:04 -04:00
New Features: - Added a modern OpenGL renderer with batched 2D drawing, textured bitmap text, stippled lines, polygons and a baked font atlas. Refactor: - App-wide rendering switched to the new renderer. - Map and lighting now draw via renderer primitives and sprite lookups use stable sprite IDs. Bug Fixes: - Improved texture allocation/invalidation/cleanup and sprite bounds safety. - Restored/normalized keyboard shortcut behavior (Q/B remap, SHOW_NPCS → Shift+N, Linux shortcut dispatch). Chores: - Replaced legacy GLUT with a GL loader and integrated stb. - Updated build configuration and project files.
235 lines
6.6 KiB
C++
235 lines
6.6 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
// This file is part of Remere's Map Editor
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Remere's Map Editor is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Remere's Map Editor is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "main.h"
|
|
|
|
#include "map_window.h"
|
|
#include "gui.h"
|
|
#include "sprites.h"
|
|
#include "editor.h"
|
|
|
|
MapWindow::MapWindow(wxWindow* parent, Editor &editor) :
|
|
wxPanel(parent, PANE_MAIN),
|
|
editor(editor),
|
|
replaceItemsDialog(nullptr) {
|
|
int GL_settings[8];
|
|
GL_settings[0] = WX_GL_RGBA;
|
|
GL_settings[1] = WX_GL_DOUBLEBUFFER;
|
|
GL_settings[2] = WX_GL_CORE_PROFILE;
|
|
GL_settings[3] = WX_GL_MAJOR_VERSION;
|
|
GL_settings[4] = 3;
|
|
GL_settings[5] = WX_GL_MINOR_VERSION;
|
|
GL_settings[6] = 3;
|
|
GL_settings[7] = 0;
|
|
canvas = newd MapCanvas(this, editor, GL_settings);
|
|
|
|
vScroll = newd MapScrollBar(this, MAP_WINDOW_VSCROLL, wxVERTICAL, canvas);
|
|
hScroll = newd MapScrollBar(this, MAP_WINDOW_HSCROLL, wxHORIZONTAL, canvas);
|
|
|
|
gem = newd DCButton(this, MAP_WINDOW_GEM, wxDefaultPosition, DC_BTN_NORMAL, RENDER_SIZE_16x16, EDITOR_SPRITE_SELECTION_GEM);
|
|
|
|
wxFlexGridSizer* topsizer = newd wxFlexGridSizer(2, 0, 0);
|
|
|
|
topsizer->AddGrowableCol(0);
|
|
topsizer->AddGrowableRow(0);
|
|
|
|
topsizer->Add(canvas, wxSizerFlags(1).Expand());
|
|
topsizer->Add(vScroll, wxSizerFlags(1).Expand());
|
|
topsizer->Add(hScroll, wxSizerFlags(1).Expand());
|
|
topsizer->Add(gem, wxSizerFlags(1));
|
|
|
|
SetSizerAndFit(topsizer);
|
|
}
|
|
|
|
MapWindow::~MapWindow() {
|
|
////
|
|
}
|
|
|
|
void MapWindow::ShowReplaceItemsDialog(bool selectionOnly) {
|
|
if (replaceItemsDialog) {
|
|
return;
|
|
}
|
|
|
|
replaceItemsDialog = new ReplaceItemsDialog(this, selectionOnly);
|
|
replaceItemsDialog->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(MapWindow::OnReplaceItemsDialogClose), nullptr, this);
|
|
replaceItemsDialog->Show();
|
|
}
|
|
|
|
void MapWindow::CloseReplaceItemsDialog() {
|
|
if (replaceItemsDialog) {
|
|
replaceItemsDialog->Close();
|
|
}
|
|
}
|
|
|
|
void MapWindow::OnReplaceItemsDialogClose(wxCloseEvent &event) {
|
|
if (replaceItemsDialog) {
|
|
replaceItemsDialog->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(MapWindow::OnReplaceItemsDialogClose), nullptr, this);
|
|
replaceItemsDialog->Destroy();
|
|
replaceItemsDialog = nullptr;
|
|
}
|
|
}
|
|
|
|
void MapWindow::SetSize(int x, int y, bool center) {
|
|
if (x == 0 || y == 0) {
|
|
return;
|
|
}
|
|
|
|
int windowSizeX;
|
|
int windowSizeY;
|
|
|
|
canvas->GetSize(&windowSizeX, &windowSizeY);
|
|
|
|
hScroll->SetScrollbar(center ? (x - windowSizeX) / 2 : hScroll->GetThumbPosition(), windowSizeX / x, x, windowSizeX / x);
|
|
vScroll->SetScrollbar(center ? (y - windowSizeY) / 2 : vScroll->GetThumbPosition(), windowSizeY / y, y, windowSizeX / y);
|
|
}
|
|
|
|
void MapWindow::UpdateScrollbars(int nx, int ny) {
|
|
// nx and ny are size of this window
|
|
hScroll->SetScrollbar(hScroll->GetThumbPosition(), nx / std::max(1, hScroll->GetRange()), std::max(1, hScroll->GetRange()), 96);
|
|
vScroll->SetScrollbar(vScroll->GetThumbPosition(), ny / std::max(1, vScroll->GetRange()), std::max(1, vScroll->GetRange()), 96);
|
|
}
|
|
|
|
void MapWindow::UpdateDialogs(bool show) {
|
|
if (replaceItemsDialog) {
|
|
replaceItemsDialog->Show(show);
|
|
}
|
|
}
|
|
|
|
void MapWindow::GetViewStart(int* x, int* y) {
|
|
*x = hScroll->GetThumbPosition();
|
|
*y = vScroll->GetThumbPosition();
|
|
}
|
|
|
|
void MapWindow::GetViewSize(int* x, int* y) {
|
|
canvas->GetSize(x, y);
|
|
*x *= canvas->GetContentScaleFactor();
|
|
*y *= canvas->GetContentScaleFactor();
|
|
}
|
|
|
|
void MapWindow::FitToMap() {
|
|
const Map &map = editor.getMap();
|
|
SetSize(map.getWidth() * rme::TileSize, map.getHeight() * rme::TileSize, true);
|
|
}
|
|
|
|
Position MapWindow::GetScreenCenterPosition() {
|
|
int x, y;
|
|
canvas->GetScreenCenter(&x, &y);
|
|
return Position(x, y, canvas->GetFloor());
|
|
}
|
|
|
|
void MapWindow::SetScreenCenterPosition(const Position &position, bool showIndicator) {
|
|
if (!position.isValid()) {
|
|
return;
|
|
}
|
|
|
|
int x = position.x * rme::TileSize;
|
|
int y = position.y * rme::TileSize;
|
|
int z = position.z;
|
|
if (position.z < 8) {
|
|
// Compensate for floor offset above ground
|
|
x -= (rme::MapGroundLayer - z) * rme::TileSize;
|
|
y -= (rme::MapGroundLayer - z) * rme::TileSize;
|
|
}
|
|
|
|
const Position ¢er = GetScreenCenterPosition();
|
|
if (previous_position != center) {
|
|
previous_position.x = center.x;
|
|
previous_position.y = center.y;
|
|
previous_position.z = center.z;
|
|
}
|
|
|
|
Scroll(x, y, true);
|
|
canvas->ChangeFloor(z);
|
|
|
|
if (showIndicator) {
|
|
canvas->ShowPositionIndicator(position);
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
void MapWindow::GoToPreviousCenterPosition() {
|
|
SetScreenCenterPosition(previous_position, true);
|
|
}
|
|
|
|
void MapWindow::Scroll(int x, int y, bool center) {
|
|
if (center) {
|
|
int windowSizeX, windowSizeY;
|
|
|
|
canvas->GetSize(&windowSizeX, &windowSizeY);
|
|
x -= int((windowSizeX * g_gui.GetCurrentZoom()) / 2.0);
|
|
y -= int((windowSizeY * g_gui.GetCurrentZoom()) / 2.0);
|
|
}
|
|
|
|
hScroll->SetThumbPosition(x);
|
|
vScroll->SetThumbPosition(y);
|
|
g_gui.UpdateMinimap();
|
|
}
|
|
|
|
void MapWindow::ScrollRelative(int x, int y) {
|
|
hScroll->SetThumbPosition(hScroll->GetThumbPosition() + x);
|
|
vScroll->SetThumbPosition(vScroll->GetThumbPosition() + y);
|
|
g_gui.UpdateMinimap();
|
|
}
|
|
|
|
void MapWindow::OnGem(wxCommandEvent &WXUNUSED(event)) {
|
|
g_gui.SwitchMode();
|
|
}
|
|
|
|
void MapWindow::OnSize(wxSizeEvent &event) {
|
|
UpdateScrollbars(event.GetSize().GetWidth(), event.GetSize().GetHeight());
|
|
event.Skip();
|
|
}
|
|
|
|
void MapWindow::OnScroll(wxScrollEvent &event) {
|
|
Refresh();
|
|
}
|
|
|
|
void MapWindow::OnScrollLineDown(wxScrollEvent &event) {
|
|
if (event.GetOrientation() == wxHORIZONTAL) {
|
|
ScrollRelative(96, 0);
|
|
} else {
|
|
ScrollRelative(0, 96);
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
void MapWindow::OnScrollLineUp(wxScrollEvent &event) {
|
|
if (event.GetOrientation() == wxHORIZONTAL) {
|
|
ScrollRelative(-96, 0);
|
|
} else {
|
|
ScrollRelative(0, -96);
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
void MapWindow::OnScrollPageDown(wxScrollEvent &event) {
|
|
if (event.GetOrientation() == wxHORIZONTAL) {
|
|
ScrollRelative(5 * 96, 0);
|
|
} else {
|
|
ScrollRelative(0, 5 * 96);
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
void MapWindow::OnScrollPageUp(wxScrollEvent &event) {
|
|
if (event.GetOrientation() == wxHORIZONTAL) {
|
|
ScrollRelative(-5 * 96, 0);
|
|
} else {
|
|
ScrollRelative(0, -5 * 96);
|
|
}
|
|
Refresh();
|
|
}
|