20 |
#include "editor.hh" |
#include "editor.hh" |
21 |
#include "world.hh" |
#include "world.hh" |
22 |
#include "lua.hh" |
#include "lua.hh" |
23 |
|
#include "video.hh" |
24 |
#include "px/sdl.hh" |
#include "px/sdl.hh" |
25 |
#include <iostream> |
#include <iostream> |
26 |
|
|
27 |
|
#include "display.hh" |
28 |
|
#include "d_engine.hh" |
29 |
|
|
30 |
using namespace std; |
using namespace std; |
31 |
using namespace enigma; |
using namespace enigma; |
32 |
using namespace enigma::editor; |
using namespace enigma::editor; |
33 |
|
using namespace px; |
34 |
|
|
35 |
|
using display::ScreenArea; |
36 |
|
using display::DisplayEngine; |
37 |
|
|
38 |
namespace |
namespace |
39 |
{ |
{ |
72 |
|
|
73 |
namespace |
namespace |
74 |
{ |
{ |
|
struct Point |
|
|
{ |
|
|
// Constructors. |
|
|
Point (double a, double b) : x(a), y(b) {} |
|
|
|
|
|
// Variables. |
|
|
double x,y; // Coordinates of the point. |
|
|
}; |
|
|
|
|
|
struct Line |
|
|
{ |
|
|
// Constructors. |
|
|
Line (Point from, Point to) : p(from), q(to) {} |
|
|
Line (double x1, double y1, double x2, double y2) |
|
|
: p(x1,y1), q(x2, y2) |
|
|
{} |
|
|
|
|
|
// Variables. |
|
|
Point p, q; // Start- and endpoint of the line. |
|
|
}; |
|
|
|
|
|
|
|
75 |
class Image; |
class Image; |
76 |
|
|
77 |
class ImagePack { |
class ImagePack { |
88 |
Image *images[0]; |
Image *images[0]; |
89 |
}; |
}; |
90 |
|
|
91 |
class LevelView |
} |
|
{ |
|
|
public: |
|
|
// Constructors. |
|
|
LevelView (int w, int h); |
|
92 |
|
|
93 |
// Functions. |
|
94 |
void set_image (int x, int y, int layer, Image *img); |
//---------------------------------------------------------------------- |
95 |
|
// Level representation inside the level editor |
96 |
|
//---------------------------------------------------------------------- |
97 |
|
namespace |
98 |
|
{ |
99 |
|
class Level { |
100 |
|
public: |
101 |
|
Level (); |
102 |
|
|
103 |
|
|
|
int add_line (const Line &l); |
|
|
void remove_line (int linetag); |
|
104 |
private: |
private: |
105 |
// Private functions. |
/* |
106 |
|
** Variables. |
107 |
|
*/ |
108 |
|
|
109 |
|
}; |
110 |
|
|
111 |
|
class LevelReader { |
112 |
|
public: |
113 |
|
virtual ~LevelReader() {} |
114 |
|
virtual Level *load_level () = 0; |
115 |
|
}; |
116 |
|
|
117 |
|
class LevelWriter { |
118 |
|
public: |
119 |
|
virtual ~LevelWriter() {} |
120 |
|
virtual void write_level (Level *l) = 0; |
121 |
|
}; |
122 |
|
|
123 |
|
} |
124 |
|
|
125 |
|
Level::Level () |
126 |
|
{ |
127 |
|
} |
128 |
|
|
129 |
|
|
130 |
|
//---------------------------------------------------------------------- |
131 |
|
// Icon bar |
132 |
|
//---------------------------------------------------------------------- |
133 |
|
namespace |
134 |
|
{ |
135 |
|
class IconBar { |
136 |
|
public: |
137 |
|
IconBar (const ScreenArea &a) : m_area (a) {} |
138 |
|
~IconBar() {} |
139 |
|
|
140 |
|
ScreenArea get_area() const { return m_area; } |
141 |
|
|
142 |
|
private: |
143 |
// Variables. |
// Variables. |
144 |
int width, height; // Width and height of the level. |
ScreenArea m_area; |
145 |
}; |
}; |
146 |
} |
} |
147 |
|
|
148 |
LevelView::LevelView (int w, int h) |
|
149 |
: width (w), height (h) |
|
150 |
|
//---------------------------------------------------------------------- |
151 |
|
// Display engine for the editor |
152 |
|
//---------------------------------------------------------------------- |
153 |
|
namespace |
154 |
{ |
{ |
155 |
|
class EditorDisplay : public display::CommonDisplay { |
156 |
|
public: |
157 |
|
EditorDisplay(const ScreenArea &a); |
158 |
|
~EditorDisplay() {} |
159 |
|
|
160 |
|
void tick(double dtime) {} |
161 |
|
private: |
162 |
|
|
163 |
|
}; |
164 |
|
|
165 |
} |
} |
166 |
|
|
167 |
void |
EditorDisplay::EditorDisplay(const ScreenArea &a) |
168 |
LevelView::set_image (int x, int y, int layer, Image *img) |
: CommonDisplay(a) |
169 |
|
{} |
170 |
|
|
171 |
|
//---------------------------------------------------------------------- |
172 |
|
// Data structure containing information on the available object types |
173 |
|
//---------------------------------------------------------------------- |
174 |
|
namespace |
175 |
{ |
{ |
176 |
|
enum ObjectFlags { |
177 |
|
OBJFLAG_None = 0, |
178 |
|
OBJFLAG_SignalEmitter = 0x1, |
179 |
|
OBJFLAG_SignalRecipient = 0x2, |
180 |
|
}; |
181 |
|
|
182 |
|
enum ObjectType { |
183 |
|
OBJTYPE_Floor, |
184 |
|
OBJTYPE_Item, |
185 |
|
OBJTYPE_Stone, |
186 |
|
OBJTYPE_Actor |
187 |
|
}; |
188 |
|
|
189 |
|
enum Signals { |
190 |
|
SIGNAL_None = 0, |
191 |
|
SIGNAL_Trigger = 0x01, |
192 |
|
SIGNAL_Open = 0x02, |
193 |
|
SIGNAL_Close = 0x04, |
194 |
|
SIGNAL_OpenClose = 0x08, |
195 |
|
SIGNAL_On = 0x10, |
196 |
|
SIGNAL_Off = 0x20, |
197 |
|
SIGNAL_OnOff = 0x40, |
198 |
|
}; |
199 |
|
|
200 |
|
char *signal_names[] = { |
201 |
|
"trigger", |
202 |
|
"open", |
203 |
|
"close", |
204 |
|
"open / close", |
205 |
|
"on", |
206 |
|
"off", |
207 |
|
"on / off" |
208 |
|
}; |
209 |
|
|
210 |
|
struct ObjectTraits { |
211 |
|
ObjectTraits (const std::string &name_, |
212 |
|
const std::string &short_text_, |
213 |
|
const std::string &long_text_, |
214 |
|
ObjectType type_) |
215 |
|
: name(name_), |
216 |
|
short_text(short_text_), |
217 |
|
long_text(long_text_), |
218 |
|
type(type_), |
219 |
|
send_signals(SIGNAL_None), |
220 |
|
receive_signals (SIGNAL_None) |
221 |
|
{} |
222 |
|
|
223 |
|
string name; |
224 |
|
string short_text; |
225 |
|
string long_text; |
226 |
|
ObjectType type; |
227 |
|
Signals send_signals; |
228 |
|
Signals receive_signals; |
229 |
|
float required_enigma_version; |
230 |
|
}; |
231 |
|
|
232 |
|
class AvailableObjects { |
233 |
|
public: |
234 |
|
vector<string> m_avail_floors; |
235 |
|
vector<string> m_avail_items; |
236 |
|
vector<string> m_avail_stones; |
237 |
|
private: |
238 |
|
|
239 |
|
}; |
240 |
} |
} |
241 |
|
|
242 |
|
|
253 |
void run(); |
void run(); |
254 |
private: |
private: |
255 |
// Private methods. |
// Private methods. |
256 |
|
void set_floor (int x, int y, const std::string &name); |
257 |
|
|
258 |
|
void new_world (int w, int h); |
259 |
|
|
260 |
|
void scroll (double xoff, double yoff); |
261 |
|
void scroll_abs (double x, double y); |
262 |
|
|
263 |
// EventHandler interface. |
// EventHandler interface. |
264 |
bool on_mousemotion(SDL_Event &e); |
bool on_mousemotion (SDL_Event &e); |
265 |
bool on_mousedown(SDL_Event &e); |
bool on_mousebutton (SDL_Event &e); |
266 |
bool on_keydown(SDL_Event &e); |
bool on_keydown (SDL_Event &e); |
267 |
|
|
268 |
// Variables. |
// Variables. |
269 |
|
ScreenArea m_editarea; |
270 |
|
ScreenArea m_iconarea; |
271 |
|
EditorDisplay display; |
272 |
|
IconBar m_iconbar; |
273 |
|
bool m_quit_editor; |
274 |
|
display::SpriteHandle m_cursor; |
275 |
|
|
276 |
|
AvailableObjects m_avail_objects; |
277 |
}; |
}; |
278 |
} |
} |
279 |
|
|
280 |
Editor::Editor() |
Editor::Editor() |
281 |
{} |
: m_editarea (0,0,640,13*32), |
282 |
|
m_iconarea (0,13*32,640,64), |
283 |
|
display (m_editarea), |
284 |
|
m_iconbar (m_iconarea), |
285 |
|
m_quit_editor (false), |
286 |
|
m_cursor(display.add_effect(V2(), display::MakeModel("it-hammer"))) |
287 |
|
{ |
288 |
|
m_cursor.replace_model (display::MakeModel ("ac-blackball")); |
289 |
|
} |
290 |
|
|
291 |
Editor::~Editor() |
Editor::~Editor() |
292 |
{} |
{} |
294 |
void |
void |
295 |
Editor::run() |
Editor::run() |
296 |
{ |
{ |
297 |
|
// video::HideMouse(); |
298 |
|
cout << "Editor is up and running...\n"; |
299 |
|
|
300 |
|
new_world (20, 13); |
301 |
|
|
302 |
|
while (!m_quit_editor) { |
303 |
|
video::HideMouse(); |
304 |
|
display.redraw(); |
305 |
|
video::ShowMouse(); |
306 |
|
video::GetScreen()->flush_updates(); |
307 |
|
|
308 |
|
SDL_Event e; |
309 |
|
if (SDL_PollEvent (&e)) |
310 |
|
dispatch_event (e); |
311 |
|
|
312 |
|
SDL_Delay (10); |
313 |
|
} |
314 |
} |
} |
315 |
|
|
316 |
bool Editor::on_mousemotion(SDL_Event &e) |
void |
317 |
|
Editor::set_floor (int x, int y, const std::string &name) |
318 |
{ |
{ |
319 |
return false; |
display.set_floor (x, y, display::MakeModel (name)); |
320 |
|
cout << "setting floor at " << x << "," << y << ": " <<name<<endl; |
321 |
} |
} |
322 |
|
|
323 |
bool Editor::on_mousedown(SDL_Event &e) |
|
324 |
|
void |
325 |
|
Editor::new_world (int w, int h) |
326 |
{ |
{ |
327 |
return false; |
display.new_world (w, h); |
328 |
|
for (int x=0; x<w; ++x) |
329 |
|
for (int y=0; y<h; ++y) |
330 |
|
set_floor (x, y, "fl-normal"); |
331 |
|
} |
332 |
|
|
333 |
|
void |
334 |
|
Editor::scroll (double xoff, double yoff) |
335 |
|
{ |
336 |
|
DisplayEngine *engine = display.get_engine(); |
337 |
|
V2 newoffset = engine->get_offset() + V2(xoff, yoff); |
338 |
|
video::HideMouse(); |
339 |
|
engine->move_offset (newoffset); |
340 |
|
video::ShowMouse(); |
341 |
|
} |
342 |
|
|
343 |
|
void |
344 |
|
Editor::scroll_abs (double x, double y) |
345 |
|
{ |
346 |
|
DisplayEngine *engine = display.get_engine(); |
347 |
|
video::HideMouse(); |
348 |
|
engine->move_offset(V2 (x, y)); |
349 |
|
video::ShowMouse(); |
350 |
|
} |
351 |
|
|
352 |
|
bool |
353 |
|
Editor::on_mousemotion(SDL_Event &e) |
354 |
|
{ |
355 |
|
// DisplayEngine *engine = display.get_engine(); |
356 |
|
// V2 worldpos = engine->to_world (V2(e.motion.x, e.motion.y)); |
357 |
|
// cout << "cursor pos: " << worldpos << endl; |
358 |
|
// m_cursor.move (worldpos); |
359 |
|
return true; |
360 |
} |
} |
361 |
|
|
362 |
bool Editor::on_keydown(SDL_Event &e) |
bool |
363 |
|
Editor::on_mousebutton (SDL_Event &e) |
364 |
{ |
{ |
365 |
|
if (e.button.type == SDL_MOUSEBUTTONDOWN) |
366 |
|
{ |
367 |
|
DisplayEngine *engine = display.get_engine(); |
368 |
|
V2 worldpos = engine->to_world (V2(e.motion.x, e.motion.y)); |
369 |
|
set_floor (int(worldpos[0]), int(worldpos[1]), "fl-hay"); |
370 |
|
return true; |
371 |
|
} |
372 |
return false; |
return false; |
373 |
} |
} |
374 |
|
|
375 |
|
bool |
376 |
|
Editor::on_keydown(SDL_Event &e) |
377 |
|
{ |
378 |
|
switch (e.key.keysym.sym) { |
379 |
|
case SDLK_ESCAPE: |
380 |
|
m_quit_editor = true; |
381 |
|
break; |
382 |
|
case SDLK_LEFT: |
383 |
|
if (e.key.keysym.mod & KMOD_CTRL) |
384 |
|
scroll (-19, 0); |
385 |
|
else |
386 |
|
scroll (-1, 0); |
387 |
|
break; |
388 |
|
case SDLK_RIGHT: |
389 |
|
if (e.key.keysym.mod & KMOD_CTRL) |
390 |
|
scroll (+19, 0); |
391 |
|
else |
392 |
|
scroll (+1, 0); |
393 |
|
break; |
394 |
|
case SDLK_DOWN: |
395 |
|
if (e.key.keysym.mod & KMOD_CTRL) |
396 |
|
scroll (0, +12); |
397 |
|
else |
398 |
|
scroll (0, +1); |
399 |
|
break; |
400 |
|
case SDLK_UP: |
401 |
|
if (e.key.keysym.mod & KMOD_CTRL) |
402 |
|
scroll (0, -12); |
403 |
|
else |
404 |
|
scroll (0, -1); |
405 |
|
break; |
406 |
|
case SDLK_HOME: |
407 |
|
scroll_abs (0,0); |
408 |
|
break; |
409 |
|
|
410 |
|
case SDLK_a: |
411 |
|
if (e.key.keysym.mod & KMOD_SHIFT) |
412 |
|
; |
413 |
|
else |
414 |
|
; |
415 |
|
break; |
416 |
|
case SDLK_f: |
417 |
|
if (e.key.keysym.mod & KMOD_SHIFT) |
418 |
|
; |
419 |
|
else |
420 |
|
; |
421 |
|
break; |
422 |
|
case SDLK_i: |
423 |
|
if (e.key.keysym.mod & KMOD_SHIFT) |
424 |
|
; |
425 |
|
else |
426 |
|
; |
427 |
|
break; |
428 |
|
case SDLK_s: |
429 |
|
if (e.key.keysym.mod & KMOD_SHIFT) |
430 |
|
; |
431 |
|
else |
432 |
|
; |
433 |
|
break; |
434 |
|
|
435 |
|
default: |
436 |
|
return false; |
437 |
|
} |
438 |
|
return true; |
439 |
|
} |
440 |
|
|
441 |
|
|
442 |
|
|
443 |
void |
void |
444 |
editor::Run() |
editor::Run() |
445 |
{ |
{ |
446 |
lua::Dofile("editor.lua"); |
// lua::Dofile("editor.lua"); |
447 |
Editor e; |
Editor().run(); |
|
e.run(); |
|
448 |
} |
} |