From 983d8475c915bcc97333bac6442375c025193107 Mon Sep 17 00:00:00 2001 From: Titus Tscharntke Date: Sun, 7 Mar 2010 17:25:42 +0000 Subject: [PATCH] mapeditor from GAE ( removed macro stuff and so on ) --- source/glest_map_editor/main.cpp | 1087 ++++++++++++++++---------- source/glest_map_editor/main.h | 133 +++- source/glest_map_editor/map.cpp | 800 +++++++++++-------- source/glest_map_editor/map.h | 133 ++-- source/glest_map_editor/program.cpp | 332 ++++++-- source/glest_map_editor/program.h | 138 +++- source/glest_map_editor/renderer.cpp | 169 ++-- source/glest_map_editor/renderer.h | 21 +- 8 files changed, 1815 insertions(+), 998 deletions(-) diff --git a/source/glest_map_editor/main.cpp b/source/glest_map_editor/main.cpp index 7a2eb5a1a..8b13c1ee0 100644 --- a/source/glest_map_editor/main.cpp +++ b/source/glest_map_editor/main.cpp @@ -1,3 +1,16 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Marti�o Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + + + #include "main.h" #include @@ -5,420 +18,237 @@ #include "conversion.h" using namespace Shared::Util; - using namespace std; -namespace Glest{ namespace MapEditor{ +namespace MapEditor { -const string MainWindow::versionString= "v1.3.1"; -const string MainWindow::winHeader= "Glest Map Editor " + versionString + " - Built: " + __DATE__; +const string MainWindow::versionString = "v1.5.0-beta3"; +const string MainWindow::winHeader = "Glest Map Editor " + versionString + " - Built: " + __DATE__; // =============================================== // class Global functions // =============================================== -wxString ToUnicode(const char* str){ +wxString ToUnicode(const char* str) { return wxString(str, wxConvUTF8); } -wxString ToUnicode(const string& str){ +wxString ToUnicode(const string& str) { return wxString(str.c_str(), wxConvUTF8); } // =============================================== -// class MainWindow +// class MainWindow // =============================================== -MainWindow::MainWindow(): - wxFrame(NULL, -1, ToUnicode(winHeader), wxDefaultPosition, wxSize(800, 600)) -{ - lastX= 0; - lastY= 0; +MainWindow::MainWindow() + : wxFrame(NULL, -1, ToUnicode(winHeader), wxDefaultPosition, wxSize(800, 600)) { - radius= 1; - height= 5; - surface= 1; - object= 0; - resource= 0; - startLocation= 1; - enabledGroup= 0; - - + fileModified=false; + lastX=0; + lastY=0; + radius=1; + height=0; + surface=1; + object=0; + resource=0; + startLocation=1; + enabledGroup=ctHeight; + currentBrush=btHeight; + //gl canvas - int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER}; - glCanvas = new GlCanvas(this,args); + int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER }; + glCanvas = new GlCanvas(this, args); //menus - menuBar= new wxMenuBar(); - + menuBar = new wxMenuBar(); + //file - menuFile= new wxMenu(); - menuFile->Append(miFileLoad, wxT("Load")); + menuFile = new wxMenu(); + menuFile->Append(wxID_OPEN); menuFile->AppendSeparator(); - menuFile->Append(miFileSave, wxT("Save")); - menuFile->Append(miFileSaveAs, wxT("Save As")); + menuFile->Append(wxID_SAVE); + menuFile->Append(wxID_SAVEAS); menuFile->AppendSeparator(); - menuFile->Append(miFileExit, wxT("Exit")); - menuBar->Append(menuFile, wxT("File")); + menuFile->Append(wxID_EXIT); + menuBar->Append(menuFile, wxT("&File")); //edit - menuEdit= new wxMenu(); - menuEdit->Append(miEditReset, wxT("Reset")); - menuEdit->Append(miEditResetPlayers, wxT("Reset Players")); - menuEdit->Append(miEditResize, wxT("Resize")); - menuEdit->Append(miEditFlipX, wxT("Flip X")); - menuEdit->Append(miEditFlipY, wxT("Flip Y")); - menuEdit->Append(miEditRandomizeHeights, wxT("Randomize Heights")); - menuEdit->Append(miEditRandomize, wxT("Randomize")); - menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Surfaces")); - menuEdit->Append(miEditInfo, wxT("Info")); - menuEdit->Append(miEditAdvanced, wxT("Advanced")); - menuBar->Append(menuEdit, wxT("Edit")); + menuEdit = new wxMenu(); + menuEdit->Append(miEditUndo, wxT("&Undo\tCTRL+z")); + menuEdit->Append(miEditRedo, wxT("&Redo\tCTRL+y")); + menuEdit->Append(miEditReset, wxT("Rese&t")); + menuEdit->Append(miEditResetPlayers, wxT("Reset &Players")); + menuEdit->Append(miEditResize, wxT("Re&size")); + menuEdit->Append(miEditFlipX, wxT("Flip &X")); + menuEdit->Append(miEditFlipY, wxT("Flip &Y")); + menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights")); + menuEdit->Append(miEditRandomize, wxT("Randomi&ze")); + menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Su&rfaces")); + menuEdit->Append(miEditInfo, wxT("&Info")); + menuEdit->Append(miEditAdvanced, wxT("&Advanced")); + menuBar->Append(menuEdit, wxT("&Edit")); //misc - menuMisc= new wxMenu(); - menuMisc->Append(miMiscResetZoomAndPos, wxT("Reset zoom and pos")); - menuMisc->Append(miMiscAbout, wxT("About")); - menuMisc->Append(miMiscHelp, wxT("Help")); - menuBar->Append(menuMisc, wxT("Misc")); + menuMisc = new wxMenu(); + menuMisc->Append(miMiscResetZoomAndPos, wxT("&Reset zoom and pos")); + menuMisc->Append(miMiscAbout, wxT("&About")); + menuMisc->Append(miMiscHelp, wxT("&Help")); + menuBar->Append(menuMisc, wxT("&Misc")); //brush - menuBrush= new wxMenu(); + menuBrush = new wxMenu(); + + // Glest height brush + menuBrushHeight = new wxMenu(); + for (int i = 0; i < heightCount; ++i) { + menuBrushHeight->AppendCheckItem(miBrushHeight + i + 1, ToUnicode(intToStr(i - heightCount / 2))); + } + menuBrushHeight->Check(miBrushHeight + (heightCount + 1) / 2, true); + menuBrush->Append(miBrushHeight, wxT("&Height"), menuBrushHeight); + + enabledGroup = ctHeight; + + // ZombiePirate height brush + menuBrushGradient = new wxMenu(); + for (int i = 0; i < heightCount; ++i) { + menuBrushGradient->AppendCheckItem(miBrushGradient + i + 1, ToUnicode(intToStr(i - heightCount / 2))); + } + menuBrush->Append(miBrushGradient, wxT("&Gradient"), menuBrushGradient); - //height - menuBrushHeight= new wxMenu(); - for(int i=0; iAppendCheckItem(miBrushHeight+i+1, ToUnicode(intToStr(i-heightCount/2))); - } - menuBrushHeight->Check(miBrushHeight + 1 + heightCount/2, true); - menuBrush->Append(miBrushHeight, wxT("Height"), menuBrushHeight); - //surface - menuBrushSurface= new wxMenu(); - menuBrushSurface->AppendCheckItem(miBrushSurface+1, wxT("1 - Grass")); - menuBrushSurface->AppendCheckItem(miBrushSurface+2, wxT("2 - Secondary Grass")); - menuBrushSurface->AppendCheckItem(miBrushSurface+3, wxT("3 - Road")); - menuBrushSurface->AppendCheckItem(miBrushSurface+4, wxT("4 - Stone")); - menuBrushSurface->AppendCheckItem(miBrushSurface+5, wxT("5 - Custom")); - menuBrush->Append(miBrushSurface, wxT("Surface"), menuBrushSurface); - + menuBrushSurface = new wxMenu(); + menuBrushSurface->AppendCheckItem(miBrushSurface + 1, wxT("&1 - Grass")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 2, wxT("&2 - Secondary Grass")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 3, wxT("&3 - Road")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 4, wxT("&4 - Stone")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 5, wxT("&5 - Ground")); + menuBrush->Append(miBrushSurface, wxT("&Surface"), menuBrushSurface); + //objects - menuBrushObject= new wxMenu(); - menuBrushObject->AppendCheckItem(miBrushObject+1, wxT("0 - None")); - menuBrushObject->AppendCheckItem(miBrushObject+2, wxT("1 - Tree (unwalkable/harvestable)")); - menuBrushObject->AppendCheckItem(miBrushObject+3, wxT("2 - DeadTree/Cactuses/Thornbush (unwalkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+4, wxT("3 - Stone (unwalkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+5, wxT("4 - Bush/Grass/Fern (walkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+6, wxT("5 - Water Object/Reed/Papyrus (walkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+7, wxT("6 - C1 BigTree/DeadTree/OldPalm (unwalkable/not harvestable)")); - menuBrushObject->AppendCheckItem(miBrushObject+8, wxT("7 - C2 Hanged/Impaled (unwalkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+9, wxT("8 - C3, Statues (unwalkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+10, wxT("9 - Big Rock (Mountain) (unwalkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+11, wxT("10 - Invisible Blocking Object (unwalkable)")); - menuBrush->Append(miBrushObject, wxT("Object"), menuBrushObject); + menuBrushObject = new wxMenu(); + menuBrushObject->AppendCheckItem(miBrushObject + 1, wxT("&0 - None (erase)")); + menuBrushObject->AppendCheckItem(miBrushObject+2, wxT("&1 - Tree (unwalkable/harvestable)")); + menuBrushObject->AppendCheckItem(miBrushObject+3, wxT("&2 - DeadTree/Cactuses/Thornbush (unwalkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+4, wxT("&3 - Stone (unwalkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+5, wxT("&4 - Bush/Grass/Fern (walkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+6, wxT("&5 - Water Object/Reed/Papyrus (walkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+7, wxT("&6 - C1 BigTree/DeadTree/OldPalm (unwalkable/not harvestable)")); + menuBrushObject->AppendCheckItem(miBrushObject+8, wxT("&7 - C2 Hanged/Impaled (unwalkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+9, wxT("&8 - C3 Statues (unwalkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+10, wxT("&9 - C4 Big Rock (Mountain) (unwalkable)")); + menuBrushObject->AppendCheckItem(miBrushObject+11, wxT("10 &- C5 Invisible Blocking Object (unwalkable)")); + menuBrush->Append(miBrushObject, wxT("&Object"), menuBrushObject); //resources - menuBrushResource= new wxMenu(); - menuBrushResource->AppendCheckItem(miBrushResource+1, wxT("0 - None")); - menuBrushResource->AppendCheckItem(miBrushResource+2, wxT("1 - gold (unwalkable)")); - menuBrushResource->AppendCheckItem(miBrushResource+3, wxT("2 - stone (unwalkable)")); - menuBrushResource->AppendCheckItem(miBrushResource+4, wxT("3 - (not used yet)")); - menuBrushResource->AppendCheckItem(miBrushResource+5, wxT("4 - (not used yet)")); - menuBrushResource->AppendCheckItem(miBrushResource+6, wxT("5 - (not used yet)")); - menuBrush->Append(miBrushResource, wxT("Resource"), menuBrushResource); + menuBrushResource = new wxMenu(); + menuBrushResource->AppendCheckItem(miBrushResource + 1, wxT("&0 - None")); + menuBrushResource->AppendCheckItem(miBrushResource+2, wxT("&1 - gold (unwalkable)")); + menuBrushResource->AppendCheckItem(miBrushResource+3, wxT("&2 - stone (unwalkable)")); + menuBrushResource->AppendCheckItem(miBrushResource+4, wxT("&3 - custom")); + menuBrushResource->AppendCheckItem(miBrushResource+5, wxT("&4 - custom")); + menuBrushResource->AppendCheckItem(miBrushResource+6, wxT("&5 - custom")); + menuBrush->Append(miBrushResource, wxT("&Resource"), menuBrushResource); //players - menuBrushStartLocation= new wxMenu(); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+1, wxT("1 - Player 1 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+2, wxT("2 - Player 2 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+3, wxT("3 - Player 3 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+4, wxT("4 - Player 4 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+5, wxT("5 - Player 5 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+6, wxT("6 - Player 6 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+7, wxT("7 - Player 7 ")); - menuBrushStartLocation->AppendCheckItem(miBrushStartLocation+8, wxT("8 - Player 8 ")); - menuBrush->Append(miBrushStartLocation, wxT("Player"), menuBrushStartLocation); - - menuBar->Append(menuBrush, wxT("Brush")); + menuBrushStartLocation = new wxMenu(); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 1, wxT("&1 - Player 1")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 2, wxT("&2 - Player 2")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 3, wxT("&3 - Player 3")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 4, wxT("&4 - Player 4")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 5, wxT("&5 - Player 5 ")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 6, wxT("&6 - Player 6 ")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 7, wxT("&7 - Player 7 ")); + menuBrushStartLocation->AppendCheckItem(miBrushStartLocation + 8, wxT("&8 - Player 8 ")); + menuBrush->Append(miBrushStartLocation, wxT("&Player"), menuBrushStartLocation); + menuBar->Append(menuBrush, wxT("&Brush")); //radius - menuRadius= new wxMenu(); - for(int i=0; iAppendCheckItem(miRadius+i, ToUnicode(intToStr(i+1))); + menuRadius = new wxMenu(); + for (int i = 1; i <= radiusCount; ++i) { + menuRadius->AppendCheckItem(miRadius + i, ToUnicode("&" + intToStr(i) + "\tALT+" + intToStr(i))); } - menuRadius->Check(miRadius, true); - menuBar->Append(menuRadius, wxT("Radius")); + menuRadius->Check(miRadius + 1, true); + menuBar->Append(menuRadius, wxT("&Radius")); SetMenuBar(menuBar); + fileName = "New (unsaved) map"; + int status_widths[siCOUNT] = { + 10, // empty + -2, // File name + -2, // File type + -2, // Brush Type + -2, // Brush 'Value' + -1, // Brush Radius + }; + CreateStatusBar(siCOUNT); + GetStatusBar()->SetStatusWidths(siCOUNT, status_widths); + + SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); + SetStatusText(wxT("Type: Glest Map (gbm)"), siFILE_TYPE); + SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); + SetStatusText(wxT("Value: 0"), siBRUSH_VALUE); + SetStatusText(wxT("Radius: 1"), siBRUSH_RADIUS); + +#ifndef WIN32 timer = new wxTimer(this); - timer->Start(50); + timer->Start(100); +#endif + glCanvas->SetFocus(); } -void MainWindow::init(){ +void MainWindow::init(string fname) { glCanvas->SetCurrent(); - program= new Program(GetClientSize().x, GetClientSize().y); + program = new Program(GetClientSize().x, GetClientSize().y); + + fileName = "New (unsaved) Map"; + if (!fname.empty() && fileExists(fname)) { + program->loadMap(fname); + currentFile = fname; + fileName = cutLastExt(lastFile(fname)); + } + SetTitle(ToUnicode(winHeader + "; " + currentFile)); + setDirty(false); + setExtension(); } -void MainWindow::onClose(wxCloseEvent &event){ +void MainWindow::onClose(wxCloseEvent &event) { delete this; } -MainWindow::~MainWindow(){ +MainWindow::~MainWindow() { delete program; delete glCanvas; } -void MainWindow::onMouseDown(wxMouseEvent &event){ - if(event.LeftIsDown()){ - program->setRefAlt(event.GetX(), event.GetY()); - change(event.GetX(), event.GetY()); +void MainWindow::setDirty(bool val) { + if (fileModified && val) { + return; } - wxPaintEvent ev; - onPaint(ev); -} - -void MainWindow::onMouseMove(wxMouseEvent &event){ - int dif; - - int x= event.GetX(); - int y= event.GetY(); - - if(event.LeftIsDown()){ - change(x, y); - } - else if(event.MiddleIsDown()){ - dif= (y-lastY); - if(dif!=0){ - program->incCellSize(dif/abs(dif)); - } - } - else if(event.RightIsDown()){ - program->setOfset(x-lastX, y-lastY); - } - lastX= x; - lastY= y; - wxPaintEvent ev; - onPaint(ev); -} - -void MainWindow::onPaint(wxPaintEvent &event){ - program->renderMap(GetClientSize().x, GetClientSize().y); - glCanvas->SwapBuffers(); -} - -void MainWindow::onMenuFileLoad(wxCommandEvent &event){ - string fileName; - - wxFileDialog fileDialog(this); - fileDialog.SetWildcard(wxT("Glest Binary Map (*.gbm)|*.gbm")); - if(fileDialog.ShowModal()==wxID_OK){ - fileName= fileDialog.GetPath().ToAscii(); - program->loadMap(fileName); - } - - currentFile= fileName; - SetTitle(ToUnicode(winHeader + "; " + currentFile)); -} - -void MainWindow::onMenuFileSave(wxCommandEvent &event){ - if(currentFile.empty()){ - wxCommandEvent ev; - onMenuFileSaveAs(ev); - } - else{ - program->saveMap(currentFile); + fileModified = val; + if (fileModified) { + SetStatusText(wxT("File: ") + ToUnicode(fileName) + wxT("*"), siFILE_NAME); + } else { + SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); } } -void MainWindow::onMenuFileSaveAs(wxCommandEvent &event){ - string fileName; - - wxFileDialog fileDialog(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.gbm"), wxSAVE); - fileDialog.SetWildcard(wxT("Glest Binary Map (*.gbm)|*.gbm")); - if(fileDialog.ShowModal()==wxID_OK){ - fileName= fileDialog.GetPath().ToAscii(); - program->saveMap(fileName); +void MainWindow::setExtension() { + if (currentFile.empty()) { + return; } - - currentFile= fileName; - SetTitle(ToUnicode(winHeader + "; " + currentFile)); -} - -void MainWindow::onMenuFileExit(wxCommandEvent &event){ - Close(); -} - -void MainWindow::onMenuEditReset(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Altitude", "10"); - simpleDialog.addValue("Surface", "1"); - simpleDialog.addValue("Height", "64"); - simpleDialog.addValue("Width", "64"); - simpleDialog.show(); - - try{ - program->reset( - strToInt(simpleDialog.getValue("Height")), - strToInt(simpleDialog.getValue("Width")), - strToInt(simpleDialog.getValue("Altitude")), - strToInt(simpleDialog.getValue("Surface"))); + string extnsn = ext(currentFile); + if (extnsn == "gbm" || extnsn == "mgm") { + currentFile = cutLastExt(currentFile); } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + if (Program::getMap()->getMaxFactions() <= 4) { + SetStatusText(wxT("Type: Glest Map (gbm)"), siFILE_TYPE); + currentFile += ".gbm"; + } else { + SetStatusText(wxT("Type: Mega Map (mgm)"), siFILE_TYPE); + currentFile += ".mgm"; } - -} - -void MainWindow::onMenuEditResetPlayers(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Players", intToStr(program->getMap()->getMaxPlayers())); - simpleDialog.show(); - - try{ - program->resetPlayers(strToInt(simpleDialog.getValue("Players"))); - } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuEditResize(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Altitude", "10"); - simpleDialog.addValue("Surface", "1"); - simpleDialog.addValue("Height", "64"); - simpleDialog.addValue("Width", "64"); - simpleDialog.show(); - - try{ - program->resize( - strToInt(simpleDialog.getValue("Height")), - strToInt(simpleDialog.getValue("Width")), - strToInt(simpleDialog.getValue("Altitude")), - strToInt(simpleDialog.getValue("Surface"))); - } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuEditFlipX(wxCommandEvent &event){ - program->flipX(); -} - -void MainWindow::onMenuEditFlipY(wxCommandEvent &event){ - program->flipY(); -} - -void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event){ - program->randomizeMapHeights(); -} - -void MainWindow::onMenuEditRandomize(wxCommandEvent &event){ - program->randomizeMap(); -} - -void MainWindow::onMenuEditSwitchSurfaces(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Surface1", "1"); - simpleDialog.addValue("Surface2", "2"); - simpleDialog.show(); - - try{ - program->switchMapSurfaces( - strToInt(simpleDialog.getValue("Surface1")), - strToInt(simpleDialog.getValue("Surface2"))); - } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuEditInfo(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Title", program->getMap()->getTitle()); - simpleDialog.addValue("Desc", program->getMap()->getDesc()); - simpleDialog.addValue("Author", program->getMap()->getAuthor()); - - simpleDialog.show(); - - program->setMapTitle(simpleDialog.getValue("Title")); - program->setMapDesc(simpleDialog.getValue("Desc")); - program->setMapAuthor(simpleDialog.getValue("Author")); -} - -void MainWindow::onMenuEditAdvanced(wxCommandEvent &event){ - SimpleDialog simpleDialog; - simpleDialog.addValue("Height Factor", intToStr(program->getMap()->getHeightFactor())); - simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel())); - - simpleDialog.show(); - - try{ - program->setMapAdvanced( - strToInt(simpleDialog.getValue("Height Factor")), - strToInt(simpleDialog.getValue("Water Level"))); - } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuMiscResetZoomAndPos(wxCommandEvent &event){ - program->resetOfset(); -} - -void MainWindow::onMenuMiscAbout(wxCommandEvent &event){ - wxMessageDialog(NULL, wxT("Glest Map Editor - Copyright 2004 The Glest Team ( improved by titi )"), wxT("About")).ShowModal(); -} - -void MainWindow::onMenuMiscHelp(wxCommandEvent &event){ - wxMessageDialog( - NULL, - wxT("Left mouse click: draw\nRight mouse drag: move\nCenter mouse drag: zoom"), - wxT("Help")).ShowModal(); -} - -void MainWindow::onMenuBrushHeight(wxCommandEvent &event){ - uncheckBrush(); - menuBrushHeight->Check(event.GetId(), true); - height= event.GetId() - miBrushHeight - heightCount/2 - 1; - enabledGroup= 0; -} - -void MainWindow::onMenuBrushSurface(wxCommandEvent &event){ - uncheckBrush(); - menuBrushSurface->Check(event.GetId(), true); - surface= event.GetId() - miBrushSurface; - enabledGroup= 1; -} - -void MainWindow::onMenuBrushObject(wxCommandEvent &event){ - uncheckBrush(); - menuBrushObject->Check(event.GetId(), true); - object= event.GetId() - miBrushObject - 1; - enabledGroup= 2; -} - -void MainWindow::onMenuBrushResource(wxCommandEvent &event){ - uncheckBrush(); - menuBrushResource->Check(event.GetId(), true); - resource= event.GetId() - miBrushResource - 1; - enabledGroup= 3; -} - -void MainWindow::onMenuBrushStartLocation(wxCommandEvent &event){ - uncheckBrush(); - menuBrushStartLocation->Check(event.GetId(), true); - startLocation= event.GetId() - miBrushStartLocation - 1; - enabledGroup= 4; -} - -void MainWindow::onMenuRadius(wxCommandEvent &event){ - uncheckRadius(); - menuRadius->Check(event.GetId(), true); - radius= event.GetId() - miRadius + 1; } void MainWindow::onTimer(wxTimerEvent &event) { @@ -426,61 +256,478 @@ void MainWindow::onTimer(wxTimerEvent &event) { onPaint(paintEvent); } -void MainWindow::change(int x, int y){ - switch(enabledGroup){ - case 0: - program->changeMapHeight(x, y, height, radius); +void MainWindow::onMouseDown(wxMouseEvent &event) { + if (event.LeftIsDown()) { + program->setUndoPoint(enabledGroup); + program->setRefAlt(event.GetX(), event.GetY()); + change(event.GetX(), event.GetY()); + if (!isDirty()) { + setDirty(true); + } + wxPaintEvent ev; + onPaint(ev); + } + event.Skip(); +} + +void MainWindow::onMouseMove(wxMouseEvent &event) { + int dif; + + int x = event.GetX(); + int y = event.GetY(); + + bool doPaint = true; + if (event.LeftIsDown()) { + change(x, y); + } else if (event.MiddleIsDown()) { + dif = (y - lastY); + if (dif != 0) { + program->incCellSize(dif / abs(dif)); + } + } else if (event.RightIsDown()) { + program->setOfset(x - lastX, y - lastY); + } else { + doPaint = false; + } + lastX = x; + lastY = y; + if (doPaint) { + wxPaintEvent ev; + onPaint(ev); + } + event.Skip(); +} + +void MainWindow::onPaint(wxPaintEvent &event) { + program->renderMap(GetClientSize().x, GetClientSize().y); + glCanvas->SwapBuffers(); +} + +void MainWindow::onMenuFileLoad(wxCommandEvent &event) { + wxFileDialog fileDialog(this); + fileDialog.SetWildcard(wxT("Glest Map (*.gbm)|*.gbm|Mega Map (*.mgm)|*.mgm")); + if (fileDialog.ShowModal() == wxID_OK) { + currentFile = fileDialog.GetPath().ToAscii(); + program->loadMap(currentFile); + fileName = cutLastExt(lastFile(currentFile)); + setDirty(false); + setExtension(); + SetTitle(ToUnicode(winHeader + "; " + currentFile)); + } +} + +void MainWindow::onMenuFileSave(wxCommandEvent &event) { + if (currentFile.empty()) { + wxCommandEvent ev; + onMenuFileSaveAs(ev); + } else { + setExtension(); + program->saveMap(currentFile); + setDirty(false); + } +} + +void MainWindow::onMenuFileSaveAs(wxCommandEvent &event) { + wxFileDialog fileDialog(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.gbm|*.mgm"), wxSAVE); + fileDialog.SetWildcard(wxT("Glest Map (*.gbm)|*.gbm|Mega Map (*.mgm)|*.mgm")); + if (fileDialog.ShowModal() == wxID_OK) { + currentFile = fileDialog.GetPath().ToAscii(); + setExtension(); + program->saveMap(currentFile); + fileName = cutLastExt(lastFile(currentFile)); + setDirty(false); + } + SetTitle(ToUnicode(winHeader + "; " + currentFile)); +} + +void MainWindow::onMenuFileExit(wxCommandEvent &event) { + Close(); +} + +void MainWindow::onMenuEditUndo(wxCommandEvent &event) { + std::cout << "Undo Pressed" << std::endl; + if (program->undo()) { + Refresh(); + setDirty(); + } +} + +void MainWindow::onMenuEditRedo(wxCommandEvent &event) { + std::cout << "Redo Pressed" << std::endl; + if (program->redo()) { + Refresh(); + setDirty(); + } +} + +void MainWindow::onMenuEditReset(wxCommandEvent &event) { + program->setUndoPoint(ctAll); + SimpleDialog simpleDialog; + simpleDialog.addValue("Altitude", "10"); + simpleDialog.addValue("Surface", "1"); + simpleDialog.addValue("Width", "64"); + simpleDialog.addValue("Height", "64"); + simpleDialog.show(); + + try { + program->reset( + strToInt(simpleDialog.getValue("Width")), + strToInt(simpleDialog.getValue("Height")), + strToInt(simpleDialog.getValue("Altitude")), + strToInt(simpleDialog.getValue("Surface"))); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + currentFile = ""; + fileName = "New (unsaved) map"; +} + +void MainWindow::onMenuEditResetPlayers(wxCommandEvent &event) { + SimpleDialog simpleDialog; + simpleDialog.addValue("Factions", intToStr(program->getMap()->getMaxFactions())); + simpleDialog.show(); + + try { + program->resetFactions(strToInt(simpleDialog.getValue("Factions"))); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + setExtension(); +} + +void MainWindow::onMenuEditResize(wxCommandEvent &event) { + SimpleDialog simpleDialog; + simpleDialog.addValue("Altitude", "10"); + simpleDialog.addValue("Surface", "1"); + simpleDialog.addValue("Height", "64"); + simpleDialog.addValue("Width", "64"); + simpleDialog.show(); + + try { + program->resize( + strToInt(simpleDialog.getValue("Height")), + strToInt(simpleDialog.getValue("Width")), + strToInt(simpleDialog.getValue("Altitude")), + strToInt(simpleDialog.getValue("Surface"))); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); +} + +void MainWindow::onMenuEditFlipX(wxCommandEvent &event) { + program->flipX(); + setDirty(); +} + +void MainWindow::onMenuEditFlipY(wxCommandEvent &event) { + program->flipY(); + setDirty(); +} + +void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) { + program->randomizeMapHeights(); + setDirty(); +} + +void MainWindow::onMenuEditRandomize(wxCommandEvent &event) { + program->randomizeMap(); + setDirty(); +} + +void MainWindow::onMenuEditSwitchSurfaces(wxCommandEvent &event) { + SimpleDialog simpleDialog; + simpleDialog.addValue("Surface1", "1"); + simpleDialog.addValue("Surface2", "2"); + simpleDialog.show(); + + try { + program->switchMapSurfaces( + strToInt(simpleDialog.getValue("Surface1")), + strToInt(simpleDialog.getValue("Surface2"))); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); +} + +void MainWindow::onMenuEditInfo(wxCommandEvent &event) { + SimpleDialog simpleDialog; + simpleDialog.addValue("Title", program->getMap()->getTitle()); + simpleDialog.addValue("Desc", program->getMap()->getDesc()); + simpleDialog.addValue("Author", program->getMap()->getAuthor()); + + simpleDialog.show(); + + if (program->setMapTitle(simpleDialog.getValue("Title")) + || program->setMapDesc(simpleDialog.getValue("Desc")) + || program->setMapAuthor(simpleDialog.getValue("Author"))) { + if (!isDirty()) { + setDirty(true); + } + } +} + +void MainWindow::onMenuEditAdvanced(wxCommandEvent &event) { + SimpleDialog simpleDialog; + simpleDialog.addValue("Height Factor", intToStr(program->getMap()->getHeightFactor())); + simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel())); + + simpleDialog.show(); + + try { + program->setMapAdvanced( + strToInt(simpleDialog.getValue("Height Factor")), + strToInt(simpleDialog.getValue("Water Level"))); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); +} + +void MainWindow::onMenuMiscResetZoomAndPos(wxCommandEvent &event) { + program->resetOfset(); +} + +void MainWindow::onMenuMiscAbout(wxCommandEvent &event) { + wxMessageDialog( + NULL, + wxT("Glest Map Editor - Copyright 2004 The Glest Team\n(with improvements by others, 2010)."), + wxT("About")).ShowModal(); +} + +void MainWindow::onMenuMiscHelp(wxCommandEvent &event) { + wxMessageDialog( + NULL, + wxT("Left mouse click: draw\nRight mouse drag: move\nCenter mouse drag: zoom"), + wxT("Help")).ShowModal(); +} + +void MainWindow::onMenuBrushHeight(wxCommandEvent &e) { + uncheckBrush(); + menuBrushHeight->Check(e.GetId(), true); + height = e.GetId() - miBrushHeight - heightCount / 2 - 1; + enabledGroup = ctHeight; + currentBrush = btHeight; + SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); +} + +void MainWindow::onMenuBrushGradient(wxCommandEvent &e) { + uncheckBrush(); + menuBrushGradient->Check(e.GetId(), true); + height = e.GetId() - miBrushGradient - heightCount / 2 - 1; + enabledGroup = ctGradient; + currentBrush = btGradient; + SetStatusText(wxT("Brush: Gradient"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); +} + + +void MainWindow::onMenuBrushSurface(wxCommandEvent &e) { + uncheckBrush(); + menuBrushSurface->Check(e.GetId(), true); + surface = e.GetId() - miBrushSurface; + enabledGroup = ctSurface; + currentBrush = btSurface; + SetStatusText(wxT("Brush: Surface"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(surface)) + wxT(" ") + + ToUnicode(surface_descs[surface - 1]), siBRUSH_VALUE); +} + +void MainWindow::onMenuBrushObject(wxCommandEvent &e) { + uncheckBrush(); + menuBrushObject->Check(e.GetId(), true); + object = e.GetId() - miBrushObject - 1; + enabledGroup = ctObject; + currentBrush = btObject; + SetStatusText(wxT("Brush: Object"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(object)) + wxT(" ") + + ToUnicode(object_descs[object]), siBRUSH_VALUE); +} + +void MainWindow::onMenuBrushResource(wxCommandEvent &e) { + uncheckBrush(); + menuBrushResource->Check(e.GetId(), true); + resource = e.GetId() - miBrushResource - 1; + enabledGroup = ctResource; + currentBrush = btResource; + SetStatusText(wxT("Brush: Resource"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(resource)) + wxT(" ") + + ToUnicode(resource_descs[resource]), siBRUSH_VALUE); +} + +void MainWindow::onMenuBrushStartLocation(wxCommandEvent &e) { + uncheckBrush(); + menuBrushStartLocation->Check(e.GetId(), true); + startLocation = e.GetId() - miBrushStartLocation; + enabledGroup = ctLocation; + currentBrush = btStartLocation; + SetStatusText(wxT("Brush: Start Locations"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(startLocation)), siBRUSH_VALUE); +} + +void MainWindow::onMenuRadius(wxCommandEvent &e) { + uncheckRadius(); + menuRadius->Check(e.GetId(), true); + radius = e.GetId() - miRadius; + SetStatusText(wxT("Radius: ") + ToUnicode(intToStr(radius)), siBRUSH_RADIUS); +} + +void MainWindow::change(int x, int y) { + switch (enabledGroup) { + case ctHeight: + program->glestChangeMapHeight(x, y, height, radius); break; - case 1: + case ctSurface: program->changeMapSurface(x, y, surface, radius); break; - case 2: + case ctObject: program->changeMapObject(x, y, object, radius); break; - case 3: + case ctResource: program->changeMapResource(x, y, resource, radius); break; - case 4: - program->changeStartLocation(x, y, startLocation); + case ctLocation: + program->changeStartLocation(x, y, startLocation - 1); + break; + case ctGradient: + program->pirateChangeMapHeight(x, y, height, radius); break; } } -void MainWindow::uncheckBrush(){ - for(int i=0; iCheck(miBrushHeight+i+1, false); +void MainWindow::uncheckBrush() { + for (int i = 0; i < heightCount; ++i) { + menuBrushHeight->Check(miBrushHeight + i + 1, false); } - for(int i=0; iCheck(miBrushSurface+i+1, false); + for (int i = 0; i < heightCount; ++i) { + menuBrushGradient->Check(miBrushGradient + i + 1, false); } - for(int i=0; iCheck(miBrushObject+i+1, false); + for (int i = 0; i < surfaceCount; ++i) { + menuBrushSurface->Check(miBrushSurface + i + 1, false); } - for(int i=0; iCheck(miBrushResource+i+1, false); + for (int i = 0; i < objectCount; ++i) { + menuBrushObject->Check(miBrushObject + i + 1, false); } - for(int i=0; iCheck(miBrushStartLocation+i+1, false); + for (int i = 0; i < resourceCount; ++i) { + menuBrushResource->Check(miBrushResource + i + 1, false); + } + for (int i = 0; i < startLocationCount; ++i) { + menuBrushStartLocation->Check(miBrushStartLocation + i + 1, false); } } -void MainWindow::uncheckRadius(){ - for(int i=0; iCheck(miRadius+i, false); - } +void MainWindow::uncheckRadius() { + for (int i = 1; i <= radiusCount; ++i) { + menuRadius->Check(miRadius + i, false); + } +} + + void MainWindow::onKeyDown(wxKeyEvent &e) { + if (currentBrush == btHeight || currentBrush == btGradient) { // 'height' brush + if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') { + height = e.GetKeyCode() - 48; // '0'-'5' == 0-5 + if (e.GetModifiers() == wxMOD_CONTROL) { // Ctrl means negative + height = -height ; + } + int id_offset = heightCount / 2 + height + 1; + if (currentBrush == btHeight) { + wxCommandEvent evt(wxEVT_NULL, miBrushHeight + id_offset); + onMenuBrushHeight(evt); + } else { + wxCommandEvent evt(wxEVT_NULL, miBrushGradient + id_offset); + onMenuBrushGradient(evt); + } + return; + } + } + if (currentBrush == btSurface) { // surface texture + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '5') { + surface = e.GetKeyCode() - 48; // '1'-'5' == 1-5 + wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); + onMenuBrushSurface(evt); + return; + } + } + if (currentBrush == btObject) { + bool valid = true; + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '9') { + object = e.GetKeyCode() - 48; // '1'-'9' == 1-9 + } else if (e.GetKeyCode() == '0') { // '0' == 10 + object = 10; + } else if (e.GetKeyCode() == '-') { // '-' == 0 + object = 0; + } else { + valid = false; + } + if (valid) { + wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); + onMenuBrushObject(evt); + return; + } + } + if (currentBrush == btResource) { + if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') { + resource = e.GetKeyCode() - 48; // '0'-'5' == 0-5 + wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); + onMenuBrushResource(evt); + return; + } + } + if (currentBrush == btStartLocation) { + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '8') { + startLocation = e.GetKeyCode() - 48; // '1'-'8' == 0-7 + wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation); + onMenuBrushStartLocation(evt); + return; + } + } + if (e.GetKeyCode() == 'H') { + wxCommandEvent evt(wxEVT_NULL, miBrushHeight + height + heightCount / 2 + 1); + onMenuBrushHeight(evt); + } else if (e.GetKeyCode() == 'G') { + wxCommandEvent evt(wxEVT_NULL, miBrushGradient + height + heightCount / 2 + 1); + onMenuBrushGradient(evt); + } else if (e.GetKeyCode() == 'S') { + wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); + onMenuBrushSurface(evt); + } else if (e.GetKeyCode() == 'O') { + wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); + onMenuBrushObject(evt); + } else if (e.GetKeyCode() == 'R') { + wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); + onMenuBrushResource(evt); + } else if (e.GetKeyCode() == 'L') { + wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation + 1); + onMenuBrushStartLocation(evt); + } else { + e.Skip(); + } } BEGIN_EVENT_TABLE(MainWindow, wxFrame) + EVT_TIMER(-1, MainWindow::onTimer) + EVT_CLOSE(MainWindow::onClose) - EVT_LEFT_DOWN(MainWindow::onMouseDown) - EVT_MOTION(MainWindow::onMouseMove) - EVT_MENU(miFileLoad, MainWindow::onMenuFileLoad) - EVT_MENU(miFileSave, MainWindow::onMenuFileSave) - EVT_MENU(miFileSaveAs, MainWindow::onMenuFileSaveAs) - EVT_MENU(miFileExit, MainWindow::onMenuFileExit) + // these are 'handled' by GlCanvas and funneled to these handlers + //EVT_LEFT_DOWN(MainWindow::onMouseDown) + //EVT_MOTION(MainWindow::onMouseMove) + //EVT_KEY_DOWN(MainWindow::onKeyDown) + EVT_MENU(wxID_OPEN, MainWindow::onMenuFileLoad) + EVT_MENU(wxID_SAVE, MainWindow::onMenuFileSave) + EVT_MENU(wxID_SAVEAS, MainWindow::onMenuFileSaveAs) + EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) + + EVT_MENU(miEditUndo, MainWindow::onMenuEditUndo) + EVT_MENU(miEditRedo, MainWindow::onMenuEditRedo) EVT_MENU(miEditReset, MainWindow::onMenuEditReset) EVT_MENU(miEditResetPlayers, MainWindow::onMenuEditResetPlayers) EVT_MENU(miEditResize, MainWindow::onMenuEditResize) @@ -496,65 +743,71 @@ BEGIN_EVENT_TABLE(MainWindow, wxFrame) EVT_MENU(miMiscAbout, MainWindow::onMenuMiscAbout) EVT_MENU(miMiscHelp, MainWindow::onMenuMiscHelp) - EVT_MENU_RANGE(miBrushHeight+1, miBrushHeight+heightCount, MainWindow::onMenuBrushHeight) - EVT_MENU_RANGE(miBrushSurface+1, miBrushSurface+surfaceCount, MainWindow::onMenuBrushSurface) - EVT_MENU_RANGE(miBrushObject+1, miBrushObject+objectCount, MainWindow::onMenuBrushObject) - EVT_MENU_RANGE(miBrushResource+1, miBrushResource+resourceCount, MainWindow::onMenuBrushResource) - EVT_MENU_RANGE(miBrushStartLocation+1, miBrushStartLocation+startLocationCount, MainWindow::onMenuBrushStartLocation) - EVT_MENU_RANGE(miRadius, miRadius+radiusCount, MainWindow::onMenuRadius) + EVT_MENU_RANGE(miBrushHeight + 1, miBrushHeight + heightCount, MainWindow::onMenuBrushHeight) + EVT_MENU_RANGE(miBrushGradient + 1, miBrushGradient + heightCount, MainWindow::onMenuBrushGradient) + EVT_MENU_RANGE(miBrushSurface + 1, miBrushSurface + surfaceCount, MainWindow::onMenuBrushSurface) + EVT_MENU_RANGE(miBrushObject + 1, miBrushObject + objectCount, MainWindow::onMenuBrushObject) + EVT_MENU_RANGE(miBrushResource + 1, miBrushResource + resourceCount, MainWindow::onMenuBrushResource) + EVT_MENU_RANGE(miBrushStartLocation + 1, miBrushStartLocation + startLocationCount, MainWindow::onMenuBrushStartLocation) + EVT_MENU_RANGE(miRadius, miRadius + radiusCount, MainWindow::onMenuRadius) END_EVENT_TABLE() // ===================================================== -// class GlCanvas +// class GlCanvas // ===================================================== -GlCanvas::GlCanvas(MainWindow * mainWindow, int* args): - wxGLCanvas(mainWindow, -1, wxDefaultPosition,wxDefaultSize,0,wxT("GLCanvas"),args) -{ +GlCanvas::GlCanvas(MainWindow * mainWindow, int* args) + : wxGLCanvas(mainWindow, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) { this->mainWindow = mainWindow; } -void GlCanvas::onMouseDown(wxMouseEvent &event){ +void GlCanvas::onMouseDown(wxMouseEvent &event) { mainWindow->onMouseDown(event); } -void GlCanvas::onMouseMove(wxMouseEvent &event){ +void GlCanvas::onMouseMove(wxMouseEvent &event) { mainWindow->onMouseMove(event); } + void GlCanvas::onKeyDown(wxKeyEvent &event) { + mainWindow->onKeyDown(event); + } + BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) + EVT_KEY_DOWN(GlCanvas::onKeyDown) + EVT_LEFT_DOWN(GlCanvas::onMouseDown) EVT_MOTION(GlCanvas::onMouseMove) END_EVENT_TABLE() // =============================================== -// class SimpleDialog +// class SimpleDialog // =============================================== -void SimpleDialog::addValue(const string &key, const string &value){ +void SimpleDialog::addValue(const string &key, const string &value) { values.push_back(pair(key, value)); } -string SimpleDialog::getValue(const string &key){ - for(int i=0; i texts; - for(Values::iterator it= values.begin(); it!=values.end(); ++it){ + for (Values::iterator it = values.begin(); it != values.end(); ++it) { sizer->Add(new wxStaticText(this, -1, ToUnicode(it->first)), 0, wxALL, 5); - wxTextCtrl *text= new wxTextCtrl(this, -1, ToUnicode(it->second)); + wxTextCtrl *text = new wxTextCtrl(this, -1, ToUnicode(it->second)); sizer->Add(text, 0, wxALL, 5); texts.push_back(text); } @@ -562,36 +815,40 @@ void SimpleDialog::show(){ ShowModal(); - for(int i=0; iGetValue().ToAscii(); + for (int i = 0; i < texts.size(); ++i) { + values[i].second = texts[i]->GetValue().ToAscii(); } } // =============================================== -// class App +// class App // =============================================== -bool App::OnInit(){ - mainWindow= new MainWindow(); +bool App::OnInit() { + string fileparam; + if(argc==2){ + fileparam = wxFNCONV(argv[1]); + } + + mainWindow = new MainWindow(); mainWindow->Show(); - mainWindow->init(); + mainWindow->init(fileparam); return true; } -int App::MainLoop(){ - try{ +int App::MainLoop() { + try { return wxApp::MainLoop(); - } - catch(const exception &e){ + } catch (const exception &e) { wxMessageDialog(NULL, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); } return 0; } -int App::OnExit(){ +int App::OnExit() { return 0; } -}}// end namespace +}// end namespace -IMPLEMENT_APP(Glest::MapEditor::App) +IMPLEMENT_APP(MapEditor::App) diff --git a/source/glest_map_editor/main.h b/source/glest_map_editor/main.h index 087027327..72567e214 100644 --- a/source/glest_map_editor/main.h +++ b/source/glest_map_editor/main.h @@ -1,5 +1,16 @@ -#ifndef _GLEST_MAPEDITOR_MAIN_H_ -#define _GLEST_MAPEDITOR_MAIN_H_ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Marti�o Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _MAPEDITOR_MAIN_H_ +#define _MAPEDITOR_MAIN_H_ #include #include @@ -7,41 +18,88 @@ #include #include -#include "program.h" +#include "program.h" + +#include "util.h" using std::string; using std::vector; using std::pair; -namespace Glest{ namespace MapEditor{ +namespace MapEditor { class GlCanvas; +enum BrushType { + btHeight, + btGradient, + btSurface, + btObject, + btResource, + btStartLocation +}; + +enum StatusItems { + siNULL_ENTRY, + siFILE_NAME, + siFILE_TYPE, + siBRUSH_TYPE, + siBRUSH_VALUE, + siBRUSH_RADIUS, + siCOUNT +}; + + +const char *object_descs[] = { + "None (Erase)", + "Tree", + "Dead Tree", + "Stone", + "Bush", + "Water Object", + "Big/Dead Tree", + "Trophy Corpse", + "Statues", + "Big Rock", + "Invisible Blocking" +}; + +const char *resource_descs[] = { + "None (Erase)", "Gold", "Stone", "Custom", "Custom", "Custom" +}; + + +const char *surface_descs[] = { + "Grass", "Alt. Grass", "Road", "Stone", "Ground" +}; + // ===================================================== // class MainWindow // ===================================================== -class MainWindow: public wxFrame{ +class MainWindow: public wxFrame { private: DECLARE_EVENT_TABLE() private: static const string versionString; static const string winHeader; - static const int heightCount= 11; - static const int surfaceCount= 5; - static const int objectCount= 11; - static const int resourceCount= 6; - static const int startLocationCount= 8; - static const int radiusCount= 9; + static const int heightCount = 11; + static const int surfaceCount = 5; + static const int objectCount = 11; + static const int resourceCount = 6; + static const int startLocationCount = 8; + static const int radiusCount = 9; private: - enum MenuId{ + enum MenuId { miFileLoad, miFileSave, miFileSaveAs, miFileExit, + miEditUndo, + miEditRedo, miEditReset, miEditResetPlayers, miEditResize, @@ -58,12 +116,13 @@ private: miMiscHelp, miBrushHeight, - miBrushSurface= miBrushHeight + heightCount + 1, - miBrushObject= miBrushSurface + surfaceCount + 1, - miBrushResource= miBrushObject + objectCount + 1, - miBrushStartLocation= miBrushResource + resourceCount + 1, + miBrushGradient = miBrushHeight + heightCount + 1, + miBrushSurface = miBrushGradient + heightCount + 1, + miBrushObject = miBrushSurface + surfaceCount + 1, + miBrushResource = miBrushObject + objectCount + 1, + miBrushStartLocation = miBrushResource + resourceCount + 1, - miRadius= miBrushStartLocation + startLocationCount + 1 + miRadius = miBrushStartLocation + startLocationCount + 1 }; private: @@ -79,38 +138,47 @@ private: wxMenu *menuMisc; wxMenu *menuBrush; wxMenu *menuBrushHeight; + wxMenu *menuBrushGradient; + wxMenu *menuBrushSurface; wxMenu *menuBrushObject; wxMenu *menuBrushResource; wxMenu *menuBrushStartLocation; wxMenu *menuRadius; - string currentFile; + string currentFile; + BrushType currentBrush; int height; int surface; int radius; int object; int resource; int startLocation; - int enabledGroup; - + ChangeType enabledGroup; + + string fileName; + bool fileModified; + public: MainWindow(); ~MainWindow(); - - void init(); + + void init(string fname); void onClose(wxCloseEvent &event); void onMouseDown(wxMouseEvent &event); void onMouseMove(wxMouseEvent &event); void onPaint(wxPaintEvent &event); - + void onKeyDown(wxKeyEvent &e); + void onMenuFileLoad(wxCommandEvent &event); void onMenuFileSave(wxCommandEvent &event); void onMenuFileSaveAs(wxCommandEvent &event); void onMenuFileExit(wxCommandEvent &event); + void onMenuEditUndo(wxCommandEvent &event); + void onMenuEditRedo(wxCommandEvent &event); void onMenuEditReset(wxCommandEvent &event); void onMenuEditResetPlayers(wxCommandEvent &event); void onMenuEditResize(wxCommandEvent &event); @@ -127,6 +195,7 @@ public: void onMenuMiscHelp(wxCommandEvent &event); void onMenuBrushHeight(wxCommandEvent &event); + void onMenuBrushGradient(wxCommandEvent &event); void onMenuBrushSurface(wxCommandEvent &event); void onMenuBrushObject(wxCommandEvent &event); void onMenuBrushResource(wxCommandEvent &event); @@ -139,21 +208,27 @@ public: void uncheckBrush(); void uncheckRadius(); + +private: + bool isDirty() const { return fileModified; } + void setDirty(bool val=true); + void setExtension(); }; // ===================================================== // class GlCanvas // ===================================================== -class GlCanvas: public wxGLCanvas{ +class GlCanvas: public wxGLCanvas { private: DECLARE_EVENT_TABLE() public: - GlCanvas(MainWindow *mainWindow,int* args); + GlCanvas(MainWindow *mainWindow, int *args); void onMouseDown(wxMouseEvent &event); void onMouseMove(wxMouseEvent &event); + void onKeyDown(wxKeyEvent &event); private: MainWindow *mainWindow; @@ -163,7 +238,7 @@ private: // class SimpleDialog // ===================================================== -class SimpleDialog: public wxDialog{ +class SimpleDialog: public wxDialog { private: typedef vector > Values; @@ -185,7 +260,7 @@ public: // class App // ===================================================== -class App: public wxApp{ +class App: public wxApp { private: MainWindow *mainWindow; @@ -195,8 +270,8 @@ public: virtual int OnExit(); }; -}}// end namespace +}// end namespace -DECLARE_APP(Glest::MapEditor::App) +DECLARE_APP(MapEditor::App) #endif diff --git a/source/glest_map_editor/map.cpp b/source/glest_map_editor/map.cpp index 4e5cf0629..3af03484f 100644 --- a/source/glest_map_editor/map.cpp +++ b/source/glest_map_editor/map.cpp @@ -1,3 +1,15 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Marti�o Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + + #include "map.h" #include @@ -6,7 +18,7 @@ using namespace Shared::Util; using namespace std; -namespace Glest{ namespace MapEditor{ +namespace MapEditor { // =============================================== // class Map @@ -14,78 +26,77 @@ namespace Glest{ namespace MapEditor{ // ================== PUBLIC ===================== -Map::Map(){ - altFactor= 3; - waterLevel= 4; - cells= NULL; - startLocations= NULL; - reset(64, 64, 10.f, 1); - resetPlayers(4); - title=""; - desc=""; - author=""; - refAlt= 10; +Map::Map() { + altFactor = 3; + waterLevel = 4; + cells = NULL; + startLocations = NULL; + reset(64, 64, 10.f, 1); + resetFactions(8); + title = ""; + desc = ""; + author = ""; + refAlt = 10; } -Map::~Map(){ - delete [] startLocations; - for(int i=0; i (sqrt(dx * dx + dy * dy)); +static int get_dist(int delta_x, int delta_y) { + float dx = delta_x; + float dy = delta_y; + return static_cast(sqrtf(dx * dx + dy * dy)); } -void Map::changeHeight(int x, int y, int height, int radius){ - - for (int i=x-radius+1; idist){ - int oldAlt= static_cast(cells[i][j].height); - int altInc= height * (radius-dist-1)/radius; - if(height>0){ +void Map::glestChangeHeight(int x, int y, int height, int radius) { + + for (int i = x - radius + 1; i < x + radius; i++) { + for (int j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + int dist = get_dist(i - x, j - y); + if (radius > dist) { + int oldAlt = static_cast(cells[i][j].height); + int altInc = height * (radius - dist - 1) / radius; + if (height > 0) { altInc++; } - if(height<0){ + if (height < 0) { altInc--; - } - int newAlt= refAlt + altInc; - if((height>0 && newAlt>oldAlt) || (height<0 && newAlt=0 && newAlt<=20){ - cells[i][j].height= static_cast(newAlt); + } + int newAlt = refAlt + altInc; + if ((height > 0 && newAlt > oldAlt) || (height < 0 && newAlt < oldAlt) || height == 0) { + if (newAlt >= 0 && newAlt <= 20) { + cells[i][j].height = static_cast(newAlt); } } } @@ -94,388 +105,548 @@ void Map::changeHeight(int x, int y, int height, int radius){ } } -void Map::setRefAlt(int x, int y){ - if(inside(x, y)){ - refAlt= static_cast(cells[x][y].height); + +void Map::pirateChangeHeight(int x, int y, int height, int radius) { + // Make sure not to try and blanket change the height over the bounds + // Find our goal height for the centre of the brush + int goalAlt; + int overBounds = refAlt + height; + if (overBounds > 20) { + goalAlt = 20; + } + else if (overBounds < 0) { + goalAlt = 0; + } else { + goalAlt = overBounds; + } + + // If the radius is 1 don't bother doing any calculations + if (radius == 1) { + cells[x][y].height = goalAlt; + return; + } + + // Get Old height reference points and compute gradients + // from the heights of the sides and corners of the brush to the centre goal height + float gradient[3][3]; // [i][j] + int indexI = 0; + for (int i = x - radius; i <= x + radius; i += radius) { + int indexJ = 0; + for (int j = y - radius; j <= y + radius; j += radius) { + // round off the corners + int ti, tj; + if (abs(i - x) == abs(j - y)) { + ti = (i - x) * 0.707 + x + 0.5; + tj = (j - y) * 0.707 + y + 0.5; + } else { + ti = i; + tj = j; + } + if (inside(ti, tj)) { + gradient[indexI][indexJ] = (cells[ti][tj].height - goalAlt) / radius; + //} else if (dist == 0) { + //gradient[indexI][indexJ] = 0; + } else { + // assume outside the map bounds is height 10 + gradient[indexI][indexJ] = (10.0 - goalAlt) / radius; + } + //std::cout << "gradient[" << indexI << "][" << indexJ << "] = " << gradient[indexI][indexJ] << std::endl; + //std::cout << "derived from height " << cells[ti][tj].height << " at " << ti << " " << tj << std::endl; + indexJ++; + } + indexI++; + } + //std::cout << endl; + + // A brush with radius n cells should have a true radius of n-1 distance + radius -= 1; + for (int i = x - radius; i <= x + radius; i++) { + for (int j = y - radius; j <= y + radius; j++) { + int dist = get_dist(i - x, j - y); + if (inside(i, j) && dist < radius) { + // Normalize di and dj and round them to an int so they can be used as indicies + float normIf = (float(i - x)/ radius); + float normJf = (float(j - y)/ radius); + int normI[2]; + int normJ[2]; + float usedGrad; + + // Build a search box to find the gradients we are concerned about + // Find the nearest i indices + if (normIf < -0.33) { + normI[0] = 0; + if (normIf == 0) { + normI[1] = 0; + } else { + normI[1] = 1; + } + } else if (normIf < 0.33) { + normI[0] = 1; + if (normIf > 0) { + normI[1] = 2; + } else if (normIf < 0) { + normI[1] = 0; + } else /*(normIf == 0)*/ { + normI[1] = 1; + } + } else { + normI[0] = 2; + if (normIf == 1) { + normI[1] = 2; + } else { + normI[1] = 1; + } + } + // find nearest j indices + if (normJf < -0.33) { + normJ[0] = 0; + if (normJf == 0) { + normJ[1] = 0; + } else { + normJ[1] = 1; + } + } else if (normJf < 0.33) { + normJ[0] = 1; + if (normJf > 0) { + normJ[1] = 2; + } else if (normJf < 0) { + normJ[1] = 0; + } else /*(normJf == 0)*/ { + normJ[1] = 1; + } + } else { + normJ[0] = 2; + if (normJf == 1) { + normJ[1] = 2; + } else { + normJ[1] = 1; + } + } + + // Determine which gradients to use and take a weighted average + if (abs(normIf) > abs(normJf)) { + usedGrad = + gradient[normI[0]] [normJ[0]] * abs(normJf) + + gradient[normI[0]] [normJ[1]] * (1 - abs(normJf)); + } else if (abs(normIf) < abs(normJf)) { + usedGrad = + gradient[normI[0]] [normJ[0]] * abs(normIf) + + gradient[normI[1]] [normJ[0]] * (1 - abs(normIf)); + } else { + usedGrad = + gradient[normI[0]] [normJ[0]]; + } + + + float newAlt = usedGrad * dist + goalAlt; + + // if the change in height and what is supposed to be the change in height + // are the same sign then we can change the height + if ( ((newAlt - cells[i][j].height) > 0 && height > 0) || + ((newAlt - cells[i][j].height) < 0 && height < 0) || + height == 0) { + cells[i][j].height = newAlt; + } + } + } } } -void Map::flipX(){ - Cell **oldCells= cells; - - cells= new Cell*[w]; - for (int i=0; i(cells[x][y].height); + } +} + +void Map::flipX() { + Cell **oldCells = cells; + + cells = new Cell*[w]; + for (int i = 0; i < w; i++) { + cells[i] = new Cell[h]; + for (int j = 0; j < h; j++) { + cells[i][j].height = oldCells[w-i-1][j].height; + cells[i][j].object = oldCells[w-i-1][j].object; + cells[i][j].resource = oldCells[w-i-1][j].resource; + cells[i][j].surface = oldCells[w-i-1][j].surface; } } - for(int i=0; i=dist){ - cells[i][j].surface= surface; - } - } - } - } + for (i = x - radius + 1; i < x + radius; i++) { + for (j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + dist = get_dist(i - x, j - y); + if (radius >= dist) { + cells[i][j].surface = surface; + } + } + } + } } -void Map::changeObject(int x, int y, int object, int radius){ - int i, j; - int dist; - - for (i=x-radius+1; i=dist){ - cells[i][j].object= object; - cells[i][j].resource= 0; - } - } - } - } +void Map::setSurface(int x, int y, int surface) { + cells[x][y].surface = surface; } -void Map::changeResource(int x, int y, int resource, int radius){ - int i, j; - int dist; +void Map::changeObject(int x, int y, int object, int radius) { + int i, j; + int dist; - for (i=x-radius+1; i=dist){ - cells[i][j].resource= resource; - cells[i][j].object= 0; - } - } - } - } + for (i = x - radius + 1; i < x + radius; i++) { + for (j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + dist = get_dist(i - x, j - y); + if (radius >= dist) { + cells[i][j].object = object; + cells[i][j].resource = 0; + } + } + } + } } -void Map::changeStartLocation(int x, int y, int player){ - if ((player-1)=0 && x=0 && y= dist) { + cells[i][j].resource = resource; + cells[i][j].object = 0; + } + } + } + } } -void Map::reset(int w, int h, float alt, int surf){ - if (w<16 || h<16){ +void Map::setResource(int x, int y, int resource) { + cells[x][y].resource = resource; + if (resource != 0) cells[x][y].object = 0; +} + +void Map::changeStartLocation(int x, int y, int faction) { + if ((faction - 1) < maxFactions && inside(x, y)) { + startLocations[faction].x = x; + startLocations[faction].y = y; + } +} + +bool Map::inside(int x, int y) { + return (x >= 0 && x < w && y >= 0 && y < h); +} + +void Map::reset(int w, int h, float alt, int surf) { + if (w < 16 || h < 16) { throw runtime_error("Size of map must be at least 16x16"); return; } - if (w>1024 || h>1024){ + if (w > 1024 || h > 1024) { throw runtime_error("Size of map can be at most 1024x1024"); return; } - if (alt<0 || alt>20){ + if (alt < 0 || alt > 20) { throw runtime_error("Height must be in the range 0-20"); return; } - if (surf<1 || surf>5){ + if (surf < 1 || surf > 5) { throw runtime_error("Surface must be in the range 1-5"); return; } - - if (cells!=NULL){ - for(int i=0; iw; i++){ + + if (cells != NULL) { + for (int i = 0; i < this->w; i++) { delete cells[i]; } delete cells; } - - this->w= w; - this->h= h; - this->maxPlayers= maxPlayers; - cells= new Cell*[w]; - for (int i=0; iw = w; + this->h = h; + this->maxFactions = maxFactions; + + cells = new Cell*[w]; + for (int i = 0; i < w; i++) { + cells[i] = new Cell[h]; + for (int j = 0; j < h; j++) { + cells[i][j].height = alt; + cells[i][j].object = 0; + cells[i][j].resource = 0; + cells[i][j].surface = surf; } } } -void Map::resize(int w, int h, float alt, int surf){ - if (w<16 || h<16){ +void Map::resize(int w, int h, float alt, int surf) { + if (w < 16 || h < 16) { throw runtime_error("Size of map must be at least 16x16"); return; } - if (w>1024 || h>1024){ + if (w > 1024 || h > 1024) { throw runtime_error("Size of map can be at most 1024x1024"); return; } - if (alt<0 || alt>20){ + if (alt < 0 || alt > 20) { throw runtime_error("Height must be in the range 0-20"); return; } - if (surf<1 || surf>5){ + if (surf < 1 || surf > 5) { throw runtime_error("Surface must be in the range 1-5"); return; } - - int oldW= this->w; - int oldH= this->h; - this->w= w; - this->h= h; - this->maxPlayers= maxPlayers; + + int oldW = this->w; + int oldH = this->h; + this->w = w; + this->h = h; + this->maxFactions = maxFactions; //create new cells - Cell **oldCells= cells; - cells= new Cell*[w]; - for (int i=0; i8){ throw runtime_error("Max Players must be in the range 1-8"); - return; } - - if (startLocations!=NULL) + + if (startLocations != NULL) delete startLocations; - - this->maxPlayers= maxPlayers; - startLocations= new StartLocation[maxPlayers]; - for (int i=0; ititle= title; +void Map::setTitle(const string &title) { + this->title = title; } -void Map::setDesc(const string &desc){ - this->desc= desc; +void Map::setDesc(const string &desc) { + this->desc = desc; } -void Map::setAuthor(const string &author){ - this->author= author; +void Map::setAuthor(const string &author) { + this->author = author; } -void Map::setAdvanced(int altFactor, int waterLevel){ - this->altFactor= altFactor; - this->waterLevel= waterLevel; +void Map::setAdvanced(int altFactor, int waterLevel) { + this->altFactor = altFactor; + this->waterLevel = waterLevel; } -int Map::getHeightFactor() const{ - return altFactor; +int Map::getHeightFactor() const { + return altFactor; } -int Map::getWaterLevel() const{ - return waterLevel; +int Map::getWaterLevel() const { + return waterLevel; } -void Map::randomizeHeights(){ +void Map::randomizeHeights() { resetHeights(random.randRange(8, 10)); sinRandomize(0); decalRandomize(4); sinRandomize(1); } -void Map::randomize(){ +void Map::randomize() { randomizeHeights(); - int slPlaceFactorX= random.randRange(0, 1); - int slPlaceFactorY= random.randRange(0, 1)*2; + int slPlaceFactorX = random.randRange(0, 1); + int slPlaceFactorY = random.randRange(0, 1) * 2; - for(int i=0; i(w*slNoiseFactor * ((i+slPlaceFactorX)%2) + w*(1.f-slNoiseFactor)/2.f); - sl.y= static_cast(h*slNoiseFactor * (((i+slPlaceFactorY)/2) % 2)+ h*(1.f-slNoiseFactor)/2.f); - startLocations[i]= sl; + float slNoiseFactor = random.randRange(0.5f, 0.8f); + + sl.x = static_cast(w * slNoiseFactor * ((i + slPlaceFactorX) % 2) + w * (1.f - slNoiseFactor) / 2.f); + sl.y = static_cast(h * slNoiseFactor * (((i + slPlaceFactorY) / 2) % 2) + h * (1.f - slNoiseFactor) / 2.f); + startLocations[i] = sl; } } -void Map::switchSurfaces(int surf1, int surf2){ - if(surf1>0 && surf1<=5 && surf2>0 && surf2<=5){ - for(int i=0; i 0 && surf1 <= 5 && surf2 > 0 && surf2 <= 5) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + if (cells[i][j].surface == surf1) { + cells[i][j].surface = surf2; + } else if (cells[i][j].surface == surf2) { + cells[i][j].surface = surf1; } } } - } - else{ + } else { throw runtime_error("Incorrect surfaces"); } } -void Map::loadFromFile(const string &path){ +void Map::loadFromFile(const string &path) { - FILE *f1= fopen(path.c_str(), "rb"); - if(f1!=NULL){ + FILE *f1 = fopen(path.c_str(), "rb"); + if (f1 != NULL) { //read header MapFileHeader header; fread(&header, sizeof(MapFileHeader), 1, f1); - altFactor= header.altFactor; - waterLevel= header.waterLevel; - title= header.title; - author= header.author; - desc= header.description; + altFactor = header.altFactor; + waterLevel = header.waterLevel; + title = header.title; + author = header.author; + desc = header.description; //read start locations - resetPlayers(header.maxPlayers); - for(int i=0; i(height); +void Map::resetHeights(int height) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + cells[i][j].height = static_cast(height); } } } -void Map::sinRandomize(int strenght){ - float sinH1= random.randRange(5.f, 40.f); - float sinH2= random.randRange(5.f, 40.f); - float sinV1= random.randRange(5.f, 40.f); - float sinV2= random.randRange(5.f, 40.f); - float ah= static_cast(10 + random.randRange(-2, 2)); - float bh= static_cast((maxHeight-minHeight)/random.randRange(2, 3)); - float av= static_cast(10 + random.randRange(-2, 2)); - float bv= static_cast((maxHeight-minHeight)/random.randRange(2, 3)); +void Map::sinRandomize(int strenght) { + float sinH1 = random.randRange(5.f, 40.f); + float sinH2 = random.randRange(5.f, 40.f); + float sinV1 = random.randRange(5.f, 40.f); + float sinV2 = random.randRange(5.f, 40.f); + float ah = static_cast(10 + random.randRange(-2, 2)); + float bh = static_cast((maxHeight - minHeight) / random.randRange(2, 3)); + float av = static_cast(10 + random.randRange(-2, 2)); + float bv = static_cast((maxHeight - minHeight) / random.randRange(2, 3)); - for(int i=0; i(i)/w; - float normV= static_cast(j)/h; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + float normH = static_cast(i) / w; + float normV = static_cast(j) / h; - float sh= (sin(normH*sinH1) + sin(normH*sinH2))/2.f; - float sv= (sin(normV*sinV1) + sin(normV*sinV2))/2.f; + float sh = (sinf(normH * sinH1) + sin(normH * sinH2)) / 2.f; + float sv = (sinf(normV * sinV1) + sin(normV * sinV2)) / 2.f; - float newHeight= (ah+bh*sh+av+bv*sv)/2.f; + float newHeight = (ah + bh * sh + av + bv * sv) / 2.f; applyNewHeight(newHeight, i, j, strenght); } } } -void Map::decalRandomize(int strenght){ +void Map::decalRandomize(int strenght) { //first row - int lastHeight= 10; - for(int i=0; i(lastHeight), i, 0, strenght); } //other rows - for(int j=1; j(cells[0][j-1].height+random.randRange(-1, 1)); + for (int j = 1; j < h; ++j) { + int height = static_cast(cells[0][j-1].height + random.randRange(-1, 1)); applyNewHeight(static_cast(clamp(height, minHeight, maxHeight)), 0, j, strenght); - for(int i=1; i((cells[i][j-1].height+cells[i-1][j].height)/2.f+random.randRange(-1, 1)); - float newHeight= static_cast(clamp(height, minHeight, maxHeight)); + for (int i = 1; i < w; ++i) { + height = static_cast((cells[i][j-1].height + cells[i-1][j].height) / 2.f + random.randRange(-1, 1)); + float newHeight = static_cast(clamp(height, minHeight, maxHeight)); applyNewHeight(newHeight, i, j, strenght); } } } -void Map::applyNewHeight(float newHeight, int x, int y, int strenght){ - cells[x][y].height= static_cast(((cells[x][y].height*strenght)+newHeight)/(strenght+1)); +void Map::applyNewHeight(float newHeight, int x, int y, int strenght) { + cells[x][y].height = static_cast(((cells[x][y].height * strenght) + newHeight) / (strenght + 1)); } -}}// end namespace +}// end namespace diff --git a/source/glest_map_editor/map.h b/source/glest_map_editor/map.h index 5d34252e7..850375c1d 100644 --- a/source/glest_map_editor/map.h +++ b/source/glest_map_editor/map.h @@ -1,5 +1,16 @@ -#ifndef _GLEST_MAPEDITOR_MAP_H_ -#define _GLEST_MAPEDITOR_MAP_H_ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martiño Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _MAPEDITOR_MAP_H_ +#define _MAPEDITOR_MAP_H_ #include "util.h" #include "types.h" @@ -10,9 +21,11 @@ using Shared::Platform::int32; using Shared::Platform::float32; using Shared::Util::Random; -struct MapFileHeader{ +namespace MapEditor { + +struct MapFileHeader { int32 version; - int32 maxPlayers; + int32 maxFactions; int32 width; int32 height; int32 altFactor; @@ -22,88 +35,92 @@ struct MapFileHeader{ int8 description[256]; }; -namespace Glest{ namespace MapEditor{ - // =============================================== // class Map // =============================================== -class Map{ +class Map { public: - static const int maxHeight= 20; - static const int minHeight= 0; + static const int maxHeight = 20; + static const int minHeight = 0; private: - struct Cell{ - int surface; - int object; - int resource; - float height; - }; - - struct StartLocation{ - int x; - int y; - }; + struct Cell { + int surface; + int object; + int resource; + float height; + }; + + struct StartLocation { + int x; + int y; + }; Random random; - string title; - string author; - string desc; - string recScn; - int type; - int h; + string title; + string author; + string desc; + string recScn; + int type; + int h; int w; - int altFactor; - int waterLevel; - Cell **cells; - int maxPlayers; - StartLocation *startLocations; + int altFactor; + int waterLevel; + Cell **cells; + int maxFactions; + StartLocation *startLocations; int refAlt; public: - Map(); - ~Map(); - float getHeight(int x, int y) const; - int getSurface(int x, int y) const; - int getObject(int x, int y) const; - int getResource(int x, int y) const; - int getStartLocationX(int index) const; - int getStartLocationY(int index) const; - int getHeightFactor() const; - int getWaterLevel() const; - bool inside(int x, int y); + Map(); + ~Map(); + float getHeight(int x, int y) const; + int getSurface(int x, int y) const; + int getObject(int x, int y) const; + int getResource(int x, int y) const; + int getStartLocationX(int index) const; + int getStartLocationY(int index) const; + int getHeightFactor() const; + int getWaterLevel() const; + bool inside(int x, int y); - void setRefAlt(int x, int y); + void setRefAlt(int x, int y); void setAdvanced(int altFactor, int waterLevel); - void setTitle(const string &title); - void setDesc(const string &desc); - void setAuthor(const string &author); - + void setTitle(const string &title); + void setDesc(const string &desc); + void setAuthor(const string &author); + int getH() const {return h;} int getW() const {return w;} - int getMaxPlayers() const {return maxPlayers;} + int getMaxFactions() const {return maxFactions;} string getTitle() const {return title;} string getDesc() const {return desc;} string getAuthor() const {return author;} - void changeHeight(int x, int y, int height, int radius); + void glestChangeHeight(int x, int y, int height, int radius); + void pirateChangeHeight(int x, int y, int height, int radius); void changeSurface(int x, int y, int surface, int radius); - void changeObject(int x, int y, int object, int radius); - void changeResource(int x, int y, int resource, int radius); - void changeStartLocation(int x, int y, int player); - + void changeObject(int x, int y, int object, int radius); + void changeResource(int x, int y, int resource, int radius); + void changeStartLocation(int x, int y, int player); + + void setHeight(int x, int y, float height); + void setSurface(int x, int y, int surface); + void setObject(int x, int y, int object); + void setResource(int x, int y, int resource); + void flipX(); void flipY(); void reset(int w, int h, float alt, int surf); - void resize(int w, int h, float alt, int surf); - void resetPlayers(int maxPlayers); + void resize(int w, int h, float alt, int surf); + void resetFactions(int maxFactions); void randomizeHeights(); void randomize(); void switchSurfaces(int surf1, int surf2); - void loadFromFile(const string &path); - void saveToFile(const string &path); + void loadFromFile(const string &path); + void saveToFile(const string &path); public: void resetHeights(int height); @@ -112,6 +129,6 @@ public: void applyNewHeight(float newHeight, int x, int y, int strenght); }; -}}// end namespace +}// end namespace #endif diff --git a/source/glest_map_editor/program.cpp b/source/glest_map_editor/program.cpp index 1e3b3a41b..13c0bf9cd 100644 --- a/source/glest_map_editor/program.cpp +++ b/source/glest_map_editor/program.cpp @@ -1,132 +1,320 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Marti�o Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + + #include "program.h" -#include "util.h" +#include "util.h" using namespace Shared::Util; -namespace Glest{ namespace MapEditor{ +namespace MapEditor { + +//////////////////////////// +// class UndoPoint +//////////////////////////// +int UndoPoint::w = 0; +int UndoPoint::h = 0; + +UndoPoint::UndoPoint() + : height(0) + , surface(0) + , object(0) + , resource(0) + , change(ctNone) { + w = Program::map->getW(); + h = Program::map->getH(); +} +/* +UndoPoint::UndoPoint(ChangeType change) { + w = Program::map->getW(); + h = Program::map->getH(); + + init(change); +}*/ + +void UndoPoint::init(ChangeType change) { + this->change = change; + switch (change) { + // Back up everything + case ctAll: + // Back up heights + case ctHeight: + case ctGradient: + // Build an array of heights from the map + //std::cout << "Building an array of heights to use for our UndoPoint" << std::endl; + height = new float[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + height[j * w + i] = Program::map->getHeight(i, j); + } + } + //std::cout << "Built the array" << std::endl; + if (change != ctAll) break; + // Back up surfaces + case ctSurface: + surface = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + surface[j * w + i] = Program::map->getSurface(i, j); + } + } + if (change != ctAll) break; + // Back up both objects and resources if either changes + case ctObject: + case ctResource: + object = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + object[j * w + i] = Program::map->getObject(i, j); + } + } + resource = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + resource[j * w + i] = Program::map->getResource(i, j); + } + } + break; + } +} + +UndoPoint::~UndoPoint() { + delete [] height; + delete [] resource; + delete [] object; + delete [] surface; +} + +void UndoPoint::revert() { + //std::cout << "attempting to revert last changes to " << undoID << std::endl; + switch (change) { + // Revert Everything + case ctAll: + // Revert Heights + case ctHeight: + case ctGradient: + // Restore the array of heights to the map + //std::cout << "attempting to restore the height array" << std::endl; + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setHeight(i, j, height[j * w + i]); + } + } + if (change != ctAll) break; + // Revert surfaces + case ctSurface: + //std::cout << "attempting to restore the surface array" << std::endl; + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setSurface(i, j, surface[j * w + i]); + } + } + if (change != ctAll) break; + // Revert objects and resources + case ctObject: + case ctResource: + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setObject(i, j, object[j * w + i]); + } + } + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setResource(i, j, resource[j * w + i]); + } + } + break; + } + //std::cout << "reverted changes (we hope)" << std::endl; +} // =============================================== // class Program // =============================================== -Program::Program(int w, int h){ - cellSize=6; - ofsetX= 0; - ofsetY= 0; - map= new Map(); - renderer.init(w, h); +Map *Program::map = NULL; + +Program::Program(int w, int h) { + cellSize = 6; + ofsetX = 0; + ofsetY = 0; + map = new Map(); + renderer.init(w, h); } -Program::~Program(){ - delete map; +Program::~Program() { + delete map; } -void Program::changeMapHeight(int x, int y, int Height, int radius){ - map->changeHeight((x-ofsetX)/cellSize, (y+ofsetY)/cellSize, Height, radius); +void Program::glestChangeMapHeight(int x, int y, int Height, int radius) { + map->glestChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); } -void Program::changeMapSurface(int x, int y, int surface, int radius){ - map->changeSurface((x-ofsetX)/cellSize, (y+ofsetY)/cellSize, surface, radius); +void Program::pirateChangeMapHeight(int x, int y, int Height, int radius) { + map->pirateChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); } -void Program::changeMapObject(int x, int y, int object, int radius){ - map->changeObject((x-ofsetX)/cellSize, (y+ofsetY)/cellSize, object, radius); +void Program::changeMapSurface(int x, int y, int surface, int radius) { + map->changeSurface((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, surface, radius); } -void Program::changeMapResource(int x, int y, int resource, int radius){ - map->changeResource((x-ofsetX)/cellSize, (y+ofsetY)/cellSize, resource, radius); +void Program::changeMapObject(int x, int y, int object, int radius) { + map->changeObject((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, object, radius); } -void Program::changeStartLocation(int x, int y, int player){ - map->changeStartLocation((x-ofsetX)/cellSize, (y+ofsetY)/cellSize, player); +void Program::changeMapResource(int x, int y, int resource, int radius) { + map->changeResource((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, resource, radius); } -void Program::renderMap(int w, int h){ - renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize); +void Program::changeStartLocation(int x, int y, int player) { + map->changeStartLocation((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, player); } -void Program::setRefAlt(int x, int y){ - map->setRefAlt((x-ofsetX)/cellSize, (y+ofsetY)/cellSize); +void Program::setUndoPoint(ChangeType change) { + if (change == ctLocation) return; + + undoStack.push(UndoPoint()); + undoStack.top().init(change); + + redoStack.clear(); } -void Program::flipX(){ +bool Program::undo() { + if (undoStack.empty()) { + return false; + } + // push current state onto redo stack + redoStack.push(UndoPoint()); + redoStack.top().init(undoStack.top().getChange()); + + undoStack.top().revert(); + undoStack.pop(); + return true; +} + +bool Program::redo() { + if (redoStack.empty()) { + return false; + } + // push current state onto undo stack + undoStack.push(UndoPoint()); + undoStack.top().init(redoStack.top().getChange()); + + redoStack.top().revert(); + redoStack.pop(); + return true; +} + +void Program::renderMap(int w, int h) { + renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize); +} + +void Program::setRefAlt(int x, int y) { + map->setRefAlt((x - ofsetX) / cellSize, (y + ofsetY) / cellSize); +} + +void Program::flipX() { map->flipX(); } -void Program::flipY(){ +void Program::flipY() { map->flipY(); } -void Program::randomizeMapHeights(){ +void Program::randomizeMapHeights() { map->randomizeHeights(); } -void Program::randomizeMap(){ +void Program::randomizeMap() { map->randomize(); } -void Program::switchMapSurfaces(int surf1, int surf2){ +void Program::switchMapSurfaces(int surf1, int surf2) { map->switchSurfaces(surf1, surf2); } -void Program::reset(int w, int h, int alt, int surf){ - map->reset(w, h, (float) alt, surf); +void Program::reset(int w, int h, int alt, int surf) { + undoStack.clear(); + redoStack.clear(); + map->reset(w, h, (float) alt, surf); } -void Program::resize(int w, int h, int alt, int surf){ - map->resize(w, h, (float) alt, surf); +void Program::resize(int w, int h, int alt, int surf) { + map->resize(w, h, (float) alt, surf); } -void Program::resetPlayers(int maxPlayers){ - map->resetPlayers(maxPlayers); +void Program::resetFactions(int maxFactions) { + map->resetFactions(maxFactions); } -void Program::setMapTitle(const string &title){ - map->setTitle(title); -} - -void Program::setMapDesc(const string &desc){ - map->setDesc(desc); -} - -void Program::setMapAuthor(const string &author){ - map->setAuthor(author); -} - -void Program::setOfset(int x, int y){ - ofsetX+= x; - ofsetY-= y; -} - -void Program::incCellSize(int i){ - - int minInc= 2-cellSize; - - if(igetTitle() != title) { + map->setTitle(title); + return true; } - cellSize+= i; - ofsetX-= (map->getW()*i)/2; - ofsetY+= (map->getH()*i)/2; + return false; } -void Program::resetOfset(){ - ofsetX= 0; - ofsetY= 0; - cellSize= 6; +bool Program::setMapDesc(const string &desc) { + if (map->getDesc() != desc) { + map->setDesc(desc); + return true; + } + return false; } -void Program::setMapAdvanced(int altFactor, int waterLevel){ - map->setAdvanced(altFactor, waterLevel); +bool Program::setMapAuthor(const string &author) { + if (map->getAuthor() != author) { + map->setAuthor(author); + return true; + } + return false; } -void Program::loadMap(const string &path){ - map->loadFromFile(path); +void Program::setOfset(int x, int y) { + ofsetX += x; + ofsetY -= y; } -void Program::saveMap(const string &path){ - map->saveToFile(path); +void Program::incCellSize(int i) { + + int minInc = 2 - cellSize; + + if (i < minInc) { + i = minInc; + } + cellSize += i; + ofsetX -= (map->getW() * i) / 2; + ofsetY += (map->getH() * i) / 2; } -}}// end namespace +void Program::resetOfset() { + ofsetX = 0; + ofsetY = 0; + cellSize = 6; +} + +void Program::setMapAdvanced(int altFactor, int waterLevel) { + map->setAdvanced(altFactor, waterLevel); +} + +void Program::loadMap(const string &path) { + undoStack.clear(); + redoStack.clear(); + map->loadFromFile(path); +} + +void Program::saveMap(const string &path) { + map->saveToFile(path); +} + +}// end namespace diff --git a/source/glest_map_editor/program.h b/source/glest_map_editor/program.h index 8cece71ad..970953123 100644 --- a/source/glest_map_editor/program.h +++ b/source/glest_map_editor/program.h @@ -1,63 +1,145 @@ -#ifndef _GLEST_MAPEDITOR_PROGRAM_H_ -#define _GLEST_MAPEDITOR_PROGRAM_H_ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martiño Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _MAPEDITOR_PROGRAM_H_ +#define _MAPEDITOR_PROGRAM_H_ #include "map.h" #include "renderer.h" -namespace Glest{ namespace MapEditor{ +#include + +using std::stack; + +namespace MapEditor { class MainWindow; +enum ChangeType { + ctNone = -1, + ctHeight, + ctSurface, + ctObject, + ctResource, + ctLocation, + ctGradient, + ctAll +}; + +// ============================================= +// class Undo Point +// A linked list class that is more of an extension / modification on +// the already existing Cell struct in map.h +// Provides the ability to only specify a certain property of the map to change +// ============================================= +class UndoPoint { + private: + // Only keep a certain number of undo points in memory otherwise + // Big projects could hog a lot of memory + const static int MAX_UNDO_LIST_SIZE = 100; // TODO get feedback on this value + static int undoCount; + + ChangeType change; + + // Pointers to arrays of each property + int *surface; + int *object; + int *resource; + float *height; + + // Map width and height + static int w; + static int h; + + public: + UndoPoint(); + ~UndoPoint(); + void init(ChangeType change); + void revert(); + + inline ChangeType getChange() const { return change; } +}; + +class ChangeStack : public std::stack { +public: + static const int maxSize = 100; + + void clear() { c.clear(); } + + void push(UndoPoint p) { + if (c.size() >= maxSize) { + c.pop_front(); + } + stack::push(p); + } +}; + // =============================================== -// class Program +// class Program // =============================================== -class Program{ +class Program { private: Renderer renderer; - int ofsetX, ofsetY; - int cellSize; - Map *map; + int ofsetX, ofsetY; + int cellSize; + static Map *map; + friend class UndoPoint; + + ChangeStack undoStack, redoStack; public: - Program(int w, int h); - ~Program(); + Program(int w, int h); + ~Program(); //map cell change - void changeMapHeight(int x, int y, int Height, int radius); - void changeMapSurface(int x, int y, int surface, int radius); - void changeMapObject(int x, int y, int object, int radius); - void changeMapResource(int x, int y, int resource, int radius); - void changeStartLocation(int x, int y, int player); + void glestChangeMapHeight(int x, int y, int Height, int radius); + void pirateChangeMapHeight(int x, int y, int Height, int radius); + void changeMapSurface(int x, int y, int surface, int radius); + void changeMapObject(int x, int y, int object, int radius); + void changeMapResource(int x, int y, int resource, int radius); + void changeStartLocation(int x, int y, int player); + + void setUndoPoint(ChangeType change); + bool undo(); + bool redo(); //map ops - void reset(int w, int h, int alt, int surf); - void resize(int w, int h, int alt, int surf); - void resetPlayers(int maxPlayers); + void reset(int w, int h, int alt, int surf); + void resize(int w, int h, int alt, int surf); + void resetFactions(int maxFactions); void setRefAlt(int x, int y); void flipX(); void flipY(); void randomizeMapHeights(); void randomizeMap(); void switchMapSurfaces(int surf1, int surf2); - void loadMap(const string &path); - void saveMap(const string &path); + void loadMap(const string &path); + void saveMap(const string &path); //map misc - void setMapTitle(const string &title); - void setMapDesc(const string &desc); - void setMapAuthor(const string &author); - void setMapAdvanced(int altFactor, int waterLevel); + bool setMapTitle(const string &title); + bool setMapDesc(const string &desc); + bool setMapAuthor(const string &author); + void setMapAdvanced(int altFactor, int waterLevel); //misc void renderMap(int w, int h); void setOfset(int x, int y); - void incCellSize(int i); - void resetOfset(); + void incCellSize(int i); + void resetOfset(); - const Map *getMap() {return map;} + static const Map *getMap() {return map;} }; -}}// end namespace +}// end namespace #endif diff --git a/source/glest_map_editor/renderer.cpp b/source/glest_map_editor/renderer.cpp index ef3ead1ee..ded9fc2b5 100644 --- a/source/glest_map_editor/renderer.cpp +++ b/source/glest_map_editor/renderer.cpp @@ -1,41 +1,53 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Marti�o Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + + #include "renderer.h" #include #include "opengl.h" - #include "vec.h" using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; -namespace Glest{ namespace MapEditor{ +namespace MapEditor { // =============================================== -// class Renderer +// class Renderer // =============================================== -void Renderer::init(int clientW, int clientH){ +void Renderer::init(int clientW, int clientH) { assertGl(); glFrontFace(GL_CW); glEnable(GL_CULL_FACE); glPolygonMode(GL_FRONT, GL_FILL); glClearColor(0.5, 0.5, 0.5, 1.0); - + assertGl(); } -void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int cellSize){ - float alt; +void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int cellSize) { + float alt; + float showWater; assertGl(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, clientW,0, clientH,1,-1); + glOrtho(0, clientW, 0, clientH, 1, -1); glViewport(0, 0, clientW, clientH); - glMatrixMode(GL_MODELVIEW); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); glPushAttrib(GL_CURRENT_BIT); @@ -44,33 +56,38 @@ void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int c glClear(GL_COLOR_BUFFER_BIT); glColor3f(0, 0, 0); - for (int j=0; jgetH(); j++){ - for (int i=0; igetW(); i++){ - if (i*cellSize+x>-cellSize && i*cellSize+x-cellSize && clientH-cellSize-j*cellSize+ygetH(); j++) { + for (int i = 0; i < map->getW(); i++) { + if (i * cellSize + x > -cellSize + && i * cellSize + x < clientW + && clientH - cellSize - j * cellSize + y > -cellSize + && clientH - cellSize - j * cellSize + y < clientH) { + //surface - alt= map->getHeight(i, j)/20.f; + alt = map->getHeight(i, j) / 20.f; + showWater = map->getWaterLevel()/ 20.f - alt; + showWater = (showWater > 0)? showWater:0; Vec3f surfColor; - switch (map->getSurface(i, j)){ - case 1: surfColor= Vec3f(0.0, 0.8f*alt, 0.f); break; - case 2: surfColor= Vec3f(0.4f*alt, 0.6f*alt, 0.f); break; - case 3: surfColor= Vec3f(0.6f*alt, 0.3f*alt, 0.f); break; - case 4: surfColor= Vec3f(0.7f*alt, 0.7f*alt, 0.7f*alt); break; - case 5: surfColor= Vec3f(1.0f*alt, 0.f, 0.f); break; + switch (map->getSurface(i, j)) { + case 1: surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break; + case 2: surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break; + case 3: surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break; + case 4: surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break; + case 5: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break; } glColor3fv(surfColor.ptr()); - + glBegin(GL_TRIANGLE_STRIP); - glVertex2i(i*cellSize, clientH-j*cellSize-cellSize); - glVertex2i(i*cellSize, clientH-j*cellSize); - glVertex2i(i*cellSize+cellSize, clientH-j*cellSize-cellSize); - glVertex2i(i*cellSize+cellSize, clientH-j*cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); glEnd(); //objects - switch(map->getObject(i,j)){ - case 0: glColor3f(0.f, 0.f, 0.f); break; + switch (map->getObject(i, j)) { + case 0: glColor3f(0.f, 0.f, 0.f); break; case 1: glColor3f(1.f, 0.f, 0.f); break; case 2: glColor3f(1.f, 1.f, 1.f); break; case 3: glColor3f(0.5f, 0.5f, 1.f); break; @@ -80,54 +97,54 @@ void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int c case 7: glColor3f(0.f, 1.f, 1.f); break; case 8: glColor3f(0.7f, 0.1f, 0.3f); break; case 9: glColor3f(0.5f, 1.f, 0.1f); break; - case 10:glColor3f(1.f, 0.2f, 0.8f); break; + case 10: glColor3f(1.f, 0.2f, 0.8f); break; } - if(map->getObject(i, j)!=0){ - glPointSize(cellSize/2.f); + if (map->getObject(i, j) != 0) { + glPointSize(cellSize / 2.f); glBegin(GL_POINTS); - glVertex2i(i*cellSize+cellSize/2, clientH-j*cellSize-cellSize/2); + glVertex2i(i * cellSize + cellSize / 2, clientH - j * cellSize - cellSize / 2); glEnd(); } - bool found= false; +// bool found = false; //height lines - if(!found){ +// if (!found) { glColor3fv((surfColor*0.5f).ptr()); //left - if(i>0 && map->getHeight(i-1, j)>map->getHeight(i, j)){ + if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) { glBegin(GL_LINES); - glVertex2i(i*cellSize, clientH-(j+1)*cellSize); - glVertex2i(i*cellSize, clientH-j*cellSize); + glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); glEnd(); } //down - if(j>0 && map->getHeight(i, j-1)>map->getHeight(i, j)){ + if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) { glBegin(GL_LINES); - glVertex2i(i*cellSize, clientH-j*cellSize); - glVertex2i((i+1)*cellSize, clientH-j*cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i((i + 1) * cellSize, clientH - j * cellSize); glEnd(); } - + glColor3fv((surfColor*2.f).ptr()); //left - if(i>0 && map->getHeight(i-1, j)getHeight(i, j)){ + if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { glBegin(GL_LINES); - glVertex2i(i*cellSize, clientH-(j+1)*cellSize); - glVertex2i(i*cellSize, clientH-j*cellSize); - glEnd(); - } - if(j>0 && map->getHeight(i, j-1)getHeight(i, j)){ - glBegin(GL_LINES); - glVertex2i(i*cellSize, clientH-j*cellSize); - glVertex2i((i+1)*cellSize, clientH-j*cellSize); + glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); glEnd(); } - } - + if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } +// } + //resources - switch(map->getResource(i,j)){ + switch (map->getResource(i, j)) { case 1: glColor3f(1.f, 1.f, 0.f); break; case 2: glColor3f(0.5f, 0.5f, 0.5f); break; case 3: glColor3f(1.f, 0.f, 0.f); break; @@ -135,13 +152,13 @@ void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int c case 5: glColor3f(0.5f, 0.5f, 1.f); break; } - if (map->getResource(i,j)!=0){ - glBegin(GL_LINES); - glVertex2i(i*cellSize, clientH-j*cellSize-cellSize); - glVertex2i(i*cellSize+cellSize, clientH-j*cellSize); - glVertex2i(i*cellSize, clientH-j*cellSize); - glVertex2i(i*cellSize+cellSize, clientH-j*cellSize-cellSize); - glEnd(); + if (map->getResource(i, j) != 0) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glEnd(); } } } @@ -149,23 +166,23 @@ void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int c //start locations glLineWidth(3); - for (int i=0; igetMaxPlayers(); i++){ - switch(i){ - case 0: glColor3f(1.f, 0.f, 0.f); break; - case 1: glColor3f(0.f, 0.f, 1.f); break; - case 2: glColor3f(0.f, 1.f, 0.f); break; - case 3: glColor3f(1.f, 1.f, 0.f); break; - case 4: glColor3f(1.f, 1.f, 1.f); break; - case 5: glColor3f(0.f, 1.f, 0.8f); break; - case 6: glColor3f(1.f, 0.8f, 0.f); break; - case 7: glColor3f(1.f, 0.8f, 1.f); break; - } + for (int i = 0; i < map->getMaxFactions(); i++) { + switch (i) { + case 0: glColor3f(1.f, 0.f, 0.f); break; + case 1: glColor3f(0.f, 0.f, 1.f); break; + case 2: glColor3f(0.f, 1.f, 0.f); break; + case 3: glColor3f(1.f, 1.f, 0.f); break; + case 4: glColor3f(1.f, 1.f, 1.f); break; + case 5: glColor3f(0.f, 1.f, 0.8f); break; + case 6: glColor3f(1.f, 0.8f, 0.f); break; + case 7: glColor3f(1.f, 0.8f, 1.f); break; + } glBegin(GL_LINES); - glVertex2i((map->getStartLocationX(i)-1)*cellSize, clientH- (map->getStartLocationY(i)-1)*cellSize); - glVertex2i((map->getStartLocationX(i)+1)*cellSize+cellSize, clientH- (map->getStartLocationY(i)+1)*cellSize-cellSize); - glVertex2i((map->getStartLocationX(i)-1)*cellSize, clientH- (map->getStartLocationY(i)+1)*cellSize-cellSize); - glVertex2i((map->getStartLocationX(i)+1)*cellSize+cellSize, clientH- (map->getStartLocationY(i)-1)*cellSize); - glEnd(); + glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); + glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); + glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + glEnd(); } glPopMatrix(); @@ -174,4 +191,4 @@ void Renderer::renderMap(Map *map, int x, int y, int clientW, int clientH, int c assertGl(); } -}}// end namespace +}// end namespace diff --git a/source/glest_map_editor/renderer.h b/source/glest_map_editor/renderer.h index 0bbe6e865..8fe2ff694 100644 --- a/source/glest_map_editor/renderer.h +++ b/source/glest_map_editor/renderer.h @@ -1,20 +1,31 @@ -#ifndef _GLEST_MAPEDITOR_RENDERER_H_ -#define _GLEST_MAPEDITOR_RENDERER_H_ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martiño Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _MAPEDITOR_RENDERER_H_ +#define _MAPEDITOR_RENDERER_H_ #include "map.h" -namespace Glest{ namespace MapEditor{ +namespace MapEditor { // =============================================== // class Renderer // =============================================== -class Renderer{ +class Renderer { public: void init(int clientW, int clientH); void renderMap(Map *map, int x, int y, int clientW, int clientH, int cellSize); }; -}}// end namespace +}// end namespace #endif