diff options
Diffstat (limited to 'tools/mapedit/src')
-rw-r--r-- | tools/mapedit/src/frame.cpp | 93 | ||||
-rw-r--r-- | tools/mapedit/src/frame.h | 16 | ||||
-rw-r--r-- | tools/mapedit/src/map.cpp | 84 | ||||
-rw-r--r-- | tools/mapedit/src/map.h | 23 | ||||
-rw-r--r-- | tools/mapedit/src/widget.cpp | 4 |
5 files changed, 204 insertions, 16 deletions
diff --git a/tools/mapedit/src/frame.cpp b/tools/mapedit/src/frame.cpp index 537cd16..3cd1c15 100644 --- a/tools/mapedit/src/frame.cpp +++ b/tools/mapedit/src/frame.cpp | |||
@@ -6,18 +6,31 @@ | |||
6 | 6 | ||
7 | enum { | 7 | enum { |
8 | MENU_VIEW_ZOOM_IN, | 8 | MENU_VIEW_ZOOM_IN, |
9 | MENU_VIEW_ZOOM_OUT | 9 | MENU_VIEW_ZOOM_OUT, |
10 | MENU_FILE_NEW, | ||
11 | MENU_FILE_OPEN, | ||
12 | MENU_FILE_SAVE, | ||
13 | MENU_FILE_CLOSE | ||
10 | }; | 14 | }; |
11 | 15 | ||
12 | wxBEGIN_EVENT_TABLE(MapeditFrame, wxFrame) | 16 | wxBEGIN_EVENT_TABLE(MapeditFrame, wxFrame) |
13 | EVT_MENU(wxID_EXIT, MapeditFrame::OnExit) | 17 | EVT_MENU(wxID_EXIT, MapeditFrame::OnQuit) |
14 | EVT_MENU(MENU_VIEW_ZOOM_IN, MapeditFrame::ZoomIn) | 18 | EVT_MENU(MENU_VIEW_ZOOM_IN, MapeditFrame::ZoomIn) |
15 | EVT_MENU(MENU_VIEW_ZOOM_OUT, MapeditFrame::ZoomOut) | 19 | EVT_MENU(MENU_VIEW_ZOOM_OUT, MapeditFrame::ZoomOut) |
20 | EVT_MENU(MENU_FILE_NEW, MapeditFrame::OnNew) | ||
21 | EVT_MENU(MENU_FILE_OPEN, MapeditFrame::OnOpen) | ||
22 | EVT_MENU(MENU_FILE_SAVE, MapeditFrame::OnSave) | ||
23 | EVT_MENU(MENU_FILE_CLOSE, MapeditFrame::OnClose) | ||
24 | EVT_CLOSE(MapeditFrame::OnExit) | ||
16 | wxEND_EVENT_TABLE() | 25 | wxEND_EVENT_TABLE() |
17 | 26 | ||
18 | MapeditFrame::MapeditFrame(Map map) : wxFrame(NULL, wxID_ANY, "Map Editor", wxPoint(50, 50), wxSize(GAME_WIDTH*3, GAME_HEIGHT*2)), map(map) | 27 | MapeditFrame::MapeditFrame(Map map, std::string filename) : wxFrame(NULL, wxID_ANY, "Map Editor", wxDefaultPosition, wxSize(GAME_WIDTH*3, GAME_HEIGHT*2)), map(map), filename(filename) |
19 | { | 28 | { |
20 | wxMenu* menuFile = new wxMenu; | 29 | wxMenu* menuFile = new wxMenu; |
30 | menuFile->Append(MENU_FILE_NEW, "New\tCtrl-N"); | ||
31 | menuFile->Append(MENU_FILE_OPEN, "Open\tCtrl-O"); | ||
32 | menuFile->Append(MENU_FILE_SAVE, "Save\tCtrl-S"); | ||
33 | menuFile->Append(MENU_FILE_CLOSE, "Close\tCtrl-W"); | ||
21 | menuFile->Append(wxID_EXIT); | 34 | menuFile->Append(wxID_EXIT); |
22 | 35 | ||
23 | wxMenu* menuView = new wxMenu; | 36 | wxMenu* menuView = new wxMenu; |
@@ -54,9 +67,34 @@ MapeditFrame::MapeditFrame(Map map) : wxFrame(NULL, wxID_ANY, "Map Editor", wxPo | |||
54 | sizermain->SetSizeHints(this); | 67 | sizermain->SetSizeHints(this); |
55 | } | 68 | } |
56 | 69 | ||
57 | void MapeditFrame::OnExit(wxCommandEvent& event) | 70 | void MapeditFrame::OnExit(wxCloseEvent& event) |
58 | { | 71 | { |
59 | Close(true); | 72 | if (event.CanVeto() && map.hasUnsavedChanges()) |
73 | { | ||
74 | switch (wxMessageBox("Current map has unsaved changes. Save before closing?", "Please confirm", wxICON_QUESTION|wxYES_NO|wxCANCEL, this)) | ||
75 | { | ||
76 | case wxYES: | ||
77 | if (filename == "") | ||
78 | { | ||
79 | wxFileDialog saveFileDialog(this, "Save map", "", "", "XML files (*.xml)|*.xml", wxFD_SAVE); | ||
80 | if (saveFileDialog.ShowModal() == wxID_CANCEL) | ||
81 | { | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | filename = saveFileDialog.GetPath().ToStdString(); | ||
86 | } | ||
87 | |||
88 | map.save(filename); | ||
89 | break; | ||
90 | |||
91 | case wxCANCEL: | ||
92 | event.Veto(true); | ||
93 | return; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | event.Skip(); | ||
60 | } | 98 | } |
61 | 99 | ||
62 | MapeditWidget* MapeditFrame::GetMapEditor() | 100 | MapeditWidget* MapeditFrame::GetMapEditor() |
@@ -73,3 +111,48 @@ void MapeditFrame::ZoomOut(wxCommandEvent& event) | |||
73 | { | 111 | { |
74 | mapEditor->ZoomOut(); | 112 | mapEditor->ZoomOut(); |
75 | } | 113 | } |
114 | |||
115 | void MapeditFrame::OnNew(wxCommandEvent& event) | ||
116 | { | ||
117 | MapeditFrame* frame = new MapeditFrame(); | ||
118 | frame->Show(true); | ||
119 | } | ||
120 | |||
121 | void MapeditFrame::OnOpen(wxCommandEvent& event) | ||
122 | { | ||
123 | wxFileDialog openFileDialog(this, "Open map", "", "", "XML files (*.xml)|*.xml", wxFD_OPEN|wxFD_FILE_MUST_EXIST); | ||
124 | if (openFileDialog.ShowModal() == wxID_CANCEL) | ||
125 | { | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | std::string filename = openFileDialog.GetPath().ToStdString(); | ||
130 | MapeditFrame* frame = new MapeditFrame(Map(filename), filename); | ||
131 | frame->Show(true); | ||
132 | } | ||
133 | |||
134 | void MapeditFrame::OnSave(wxCommandEvent& event) | ||
135 | { | ||
136 | if (filename == "") | ||
137 | { | ||
138 | wxFileDialog saveFileDialog(this, "Save map", "", "", "XML files (*.xml)|*.xml", wxFD_SAVE); | ||
139 | if (saveFileDialog.ShowModal() == wxID_CANCEL) | ||
140 | { | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | filename = saveFileDialog.GetPath().ToStdString(); | ||
145 | } | ||
146 | |||
147 | map.save(filename); | ||
148 | } | ||
149 | |||
150 | void MapeditFrame::OnClose(wxCommandEvent& event) | ||
151 | { | ||
152 | Close(false); | ||
153 | } | ||
154 | |||
155 | void MapeditFrame::OnQuit(wxCommandEvent& event) | ||
156 | { | ||
157 | // TODO | ||
158 | } | ||
diff --git a/tools/mapedit/src/frame.h b/tools/mapedit/src/frame.h index 4d6c3dc..53d8998 100644 --- a/tools/mapedit/src/frame.h +++ b/tools/mapedit/src/frame.h | |||
@@ -13,21 +13,25 @@ | |||
13 | 13 | ||
14 | class MapeditFrame : public wxFrame { | 14 | class MapeditFrame : public wxFrame { |
15 | public: | 15 | public: |
16 | MapeditFrame() : MapeditFrame(Map()) {} | 16 | MapeditFrame() : MapeditFrame(Map(), "") {} |
17 | MapeditFrame(Map map); | 17 | MapeditFrame(Map map, std::string filename); |
18 | 18 | ||
19 | MapeditWidget* GetMapEditor(); | 19 | MapeditWidget* GetMapEditor(); |
20 | 20 | ||
21 | protected: | 21 | private: |
22 | void ZoomIn(wxCommandEvent& event); | 22 | void ZoomIn(wxCommandEvent& event); |
23 | void ZoomOut(wxCommandEvent& event); | 23 | void ZoomOut(wxCommandEvent& event); |
24 | 24 | void OnNew(wxCommandEvent& event); | |
25 | private: | 25 | void OnOpen(wxCommandEvent& event); |
26 | void OnExit(wxCommandEvent& event); | 26 | void OnSave(wxCommandEvent& event); |
27 | void OnClose(wxCommandEvent& event); | ||
28 | void OnExit(wxCloseEvent& event); | ||
29 | void OnQuit(wxCommandEvent& event); | ||
27 | 30 | ||
28 | Map map; | 31 | Map map; |
29 | MapeditWidget* mapEditor; | 32 | MapeditWidget* mapEditor; |
30 | TileWidget* tileEditor; | 33 | TileWidget* tileEditor; |
34 | std::string filename; | ||
31 | 35 | ||
32 | wxDECLARE_EVENT_TABLE(); | 36 | wxDECLARE_EVENT_TABLE(); |
33 | }; | 37 | }; |
diff --git a/tools/mapedit/src/map.cpp b/tools/mapedit/src/map.cpp index 52a2096..7976419 100644 --- a/tools/mapedit/src/map.cpp +++ b/tools/mapedit/src/map.cpp | |||
@@ -1,12 +1,15 @@ | |||
1 | #include "map.h" | 1 | #include "map.h" |
2 | #include <libxml/parser.h> | 2 | #include <libxml/parser.h> |
3 | #include <libxml/xmlwriter.h> | ||
4 | #include <sstream> | ||
3 | 5 | ||
4 | Map::Map() | 6 | Map::Map() |
5 | { | 7 | { |
6 | mapdata = (int*) calloc(MAP_WIDTH * MAP_HEIGHT, sizeof(int)); | 8 | mapdata = (int*) calloc(MAP_WIDTH * MAP_HEIGHT, sizeof(int)); |
9 | dirty = true; | ||
7 | } | 10 | } |
8 | 11 | ||
9 | Map::Map(const std::string filename) | 12 | Map::Map(std::string filename) |
10 | { | 13 | { |
11 | xmlDocPtr doc = xmlParseFile(filename.c_str()); | 14 | xmlDocPtr doc = xmlParseFile(filename.c_str()); |
12 | if (doc == nullptr) | 15 | if (doc == nullptr) |
@@ -56,6 +59,8 @@ Map::Map(const std::string filename) | |||
56 | } | 59 | } |
57 | 60 | ||
58 | xmlFreeDoc(doc); | 61 | xmlFreeDoc(doc); |
62 | |||
63 | dirty = false; | ||
59 | } | 64 | } |
60 | 65 | ||
61 | Map::Map(const Map& map) | 66 | Map::Map(const Map& map) |
@@ -66,6 +71,7 @@ Map::Map(const Map& map) | |||
66 | title = map.title; | 71 | title = map.title; |
67 | leftmap = map.leftmap; | 72 | leftmap = map.leftmap; |
68 | rightmap = map.rightmap; | 73 | rightmap = map.rightmap; |
74 | dirty = map.dirty; | ||
69 | } | 75 | } |
70 | 76 | ||
71 | Map::Map(Map&& map) : Map() | 77 | Map::Map(Map&& map) : Map() |
@@ -91,4 +97,78 @@ void swap(Map& first, Map& second) | |||
91 | std::swap(first.title, second.title); | 97 | std::swap(first.title, second.title); |
92 | std::swap(first.leftmap, second.leftmap); | 98 | std::swap(first.leftmap, second.leftmap); |
93 | std::swap(first.rightmap, second.rightmap); | 99 | std::swap(first.rightmap, second.rightmap); |
94 | } \ No newline at end of file | 100 | std::swap(first.dirty, second.dirty); |
101 | } | ||
102 | |||
103 | #define MY_ENCODING "ISO-8859-1" | ||
104 | |||
105 | void Map::save(std::string name) | ||
106 | { | ||
107 | if (!dirty) return; | ||
108 | |||
109 | int rc; | ||
110 | |||
111 | xmlTextWriterPtr writer = xmlNewTextWriterFilename(name.c_str(), 0); | ||
112 | if (writer == NULL) throw MapWriteException(name); | ||
113 | |||
114 | rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); | ||
115 | if (rc < 0) throw MapWriteException(name); | ||
116 | |||
117 | rc = xmlTextWriterStartElement(writer, (xmlChar*) "map-def"); | ||
118 | if (rc < 0) throw MapWriteException(name); | ||
119 | |||
120 | rc = xmlTextWriterWriteElement(writer, (xmlChar*) "name", (xmlChar*) title.c_str()); | ||
121 | if (rc < 0) throw MapWriteException(name); | ||
122 | |||
123 | std::ostringstream mapdata_out; | ||
124 | for (int y=0; y<MAP_HEIGHT; y++) | ||
125 | { | ||
126 | for (int x=0; x<MAP_WIDTH; x++) | ||
127 | { | ||
128 | mapdata_out << mapdata[x+y*MAP_WIDTH] << ","; | ||
129 | } | ||
130 | |||
131 | mapdata_out << std::endl; | ||
132 | } | ||
133 | |||
134 | rc = xmlTextWriterWriteElement(writer, (xmlChar*) "environment", (xmlChar*) mapdata_out.str().c_str()); | ||
135 | if (rc < 0) throw MapWriteException(name); | ||
136 | |||
137 | if (leftmap != "") | ||
138 | { | ||
139 | rc = xmlTextWriterWriteElement(writer, (xmlChar*) "leftmap", (xmlChar*) leftmap.c_str()); | ||
140 | if (rc < 0) throw MapWriteException(name); | ||
141 | } | ||
142 | |||
143 | if (rightmap != "") | ||
144 | { | ||
145 | rc = xmlTextWriterWriteElement(writer, (xmlChar*) "rightmap", (xmlChar*) rightmap.c_str()); | ||
146 | if (rc < 0) throw MapWriteException(name); | ||
147 | } | ||
148 | |||
149 | rc = xmlTextWriterEndElement(writer); | ||
150 | if (rc < 0) throw MapWriteException(name); | ||
151 | |||
152 | rc = xmlTextWriterEndDocument(writer); | ||
153 | if (rc < 0) throw MapWriteException(name); | ||
154 | |||
155 | xmlFreeTextWriter(writer); | ||
156 | |||
157 | dirty = false; | ||
158 | } | ||
159 | |||
160 | bool Map::hasUnsavedChanges() const | ||
161 | { | ||
162 | return dirty; | ||
163 | } | ||
164 | |||
165 | void Map::setTileAt(int x, int y, int tile) | ||
166 | { | ||
167 | dirty = true; | ||
168 | mapdata[x+y*MAP_WIDTH] = tile; | ||
169 | } | ||
170 | |||
171 | int Map::getTileAt(int x, int y) const | ||
172 | { | ||
173 | return mapdata[x+y*MAP_WIDTH]; | ||
174 | } | ||
diff --git a/tools/mapedit/src/map.h b/tools/mapedit/src/map.h index 83244f3..66e4596 100644 --- a/tools/mapedit/src/map.h +++ b/tools/mapedit/src/map.h | |||
@@ -25,20 +25,41 @@ class MapLoadException: public std::exception | |||
25 | std::string mapname; | 25 | std::string mapname; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | class MapWriteException: public std::exception | ||
29 | { | ||
30 | public: | ||
31 | MapWriteException(std::string mapname) : mapname(mapname) {} | ||
32 | |||
33 | virtual const char* what() const throw() | ||
34 | { | ||
35 | return ("An error occured writing map " + mapname).c_str(); | ||
36 | } | ||
37 | |||
38 | private: | ||
39 | std::string mapname; | ||
40 | }; | ||
41 | |||
28 | class Map { | 42 | class Map { |
29 | public: | 43 | public: |
30 | Map(); | 44 | Map(); |
31 | Map(const std::string name); | 45 | Map(std::string name); |
32 | Map(const Map& map); | 46 | Map(const Map& map); |
33 | Map(Map&& map); | 47 | Map(Map&& map); |
34 | ~Map(); | 48 | ~Map(); |
35 | Map& operator= (Map other); | 49 | Map& operator= (Map other); |
36 | friend void swap(Map& first, Map& second); | 50 | friend void swap(Map& first, Map& second); |
37 | 51 | ||
52 | void save(std::string name); | ||
53 | bool hasUnsavedChanges() const; | ||
54 | void setTileAt(int x, int y, int tile); | ||
55 | int getTileAt(int x, int y) const; | ||
56 | |||
57 | private: | ||
38 | int* mapdata; | 58 | int* mapdata; |
39 | std::string title; | 59 | std::string title; |
40 | std::string leftmap; | 60 | std::string leftmap; |
41 | std::string rightmap; | 61 | std::string rightmap; |
62 | bool dirty; | ||
42 | }; | 63 | }; |
43 | 64 | ||
44 | #endif | 65 | #endif |
diff --git a/tools/mapedit/src/widget.cpp b/tools/mapedit/src/widget.cpp index 53249c7..9c8dae3 100644 --- a/tools/mapedit/src/widget.cpp +++ b/tools/mapedit/src/widget.cpp | |||
@@ -48,7 +48,7 @@ void MapeditWidget::OnPaint(wxPaintEvent& event) | |||
48 | { | 48 | { |
49 | for (int x=0; x<MAP_WIDTH; x++) | 49 | for (int x=0; x<MAP_WIDTH; x++) |
50 | { | 50 | { |
51 | int tile = map->mapdata[x+y*MAP_WIDTH]; | 51 | int tile = map->getTileAt(x, y); |
52 | dc.StretchBlit(x*TILE_WIDTH*scale-vX, y*TILE_HEIGHT*scale-vY, TILE_WIDTH*scale, TILE_HEIGHT*scale, &tiles_dc, tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | 52 | dc.StretchBlit(x*TILE_WIDTH*scale-vX, y*TILE_HEIGHT*scale-vY, TILE_WIDTH*scale, TILE_HEIGHT*scale, &tiles_dc, tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); |
53 | } | 53 | } |
54 | } | 54 | } |
@@ -76,7 +76,7 @@ void MapeditWidget::SetTile(wxPoint pos) | |||
76 | int x = (pos.x + vX) / (TILE_WIDTH * scale); | 76 | int x = (pos.x + vX) / (TILE_WIDTH * scale); |
77 | int y = (pos.y + vY) / (TILE_HEIGHT * scale); | 77 | int y = (pos.y + vY) / (TILE_HEIGHT * scale); |
78 | 78 | ||
79 | map->mapdata[x+y*MAP_WIDTH] = tileWidget->getSelected(); | 79 | map->setTileAt(x, y, tileWidget->getSelected()); |
80 | Refresh(); | 80 | Refresh(); |
81 | } | 81 | } |
82 | 82 | ||