1 /*
2 Xye License (it is a PNG/ZLIB license)
3
4 Copyright (c) 2006 Victor Hugo Soliz Kuncar
5
6 This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
9
10 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
11
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
14 3. This notice may not be removed or altered from any source distribution.
15
16 */
17
18 #include<cstdio>
19 #include<cstdlib>
20 #include<iostream>
21 #include<fstream>
22
23 #include "levels.h"
24 #include "xyedit.h"
25 #include "xye.h"
26 #include "xye_script.h"
27 #include "options.h"
28 #include "dialogs.h"
29
30
31 #define sz editor::GRIDSIZE //typing game::GRIDSIZE is an annoyance
32
33
34
35 int editor::Width,editor::Height, editor::GRIDSIZE;
36
37 window* editor::editorwindow;
38 editorbuttons *editor::buttons;
39 editorboard * editor::board;
40
41 unsigned int editor::tic4;
42 unsigned int editor::subtic4;
43
44 string editor::filename;
45 string editor::filename_name;
46 string editor::filename_path;
47
48 bool editor::SavedFile=true;
49 bool editor::ExitPrompt=false;
50
51
52 button * editor::savebutton;
53 button * editor::solutionbutton;
54 button * nextbutton;
55 button * previousbutton;
56 button * erasebutton;
57 button * changelevelnumberbutton;
58 LuminositySprites editor::sprites;
59 Font* editor::FontRes;
60 bool SavedSolution = false;
61 bool EnterPressed = false;
62
63 string editorboard::filetitle;
64 string editorboard::description;
65 string editorboard::author;
66
onExitWithoutSavingClick(bool yes)67 void editor::onExitWithoutSavingClick(bool yes)
68 {
69 ExitPrompt=false;
70 if(yes) cancel();
71 }
72
onBrowseWithoutSavingClick(bool yes)73 void editor::onBrowseWithoutSavingClick(bool yes)
74 {
75 if(yes)
76 editor::editorwindow->SetTransition(LevelBrowser::StartSection);
77 }
78
79
onExitAttempt()80 void editor::onExitAttempt()
81 {
82 if(! SavedFile) {
83 if(!ExitPrompt) {
84 ExitPrompt=true;
85 dialogs::makeYesNoDialog(editorwindow,"Are you sure you want to close the editor before saving the level?","Yes","No",editor::onExitWithoutSavingClick);
86 }
87 } else {
88 cancel();
89 }
90 };
91
onQuitClick(const buttondata * data)92 void editor::onQuitClick(const buttondata* data)
93 {
94 onExitAttempt();
95 }
96
SendSolution(const char * sol)97 void editor::SendSolution(const char* sol)
98 {
99 SavedFile = false;
100 SavedSolution = true;
101 editorboard::SetCopySolution(sol);
102 }
103
104
beforeDraw()105 void editor::beforeDraw()
106 {
107 solutionbutton->Enabled = (board->solution != "");
108 subtic4++; if (subtic4==10)
109 {
110 subtic4=0;
111 tic4++; if (tic4==4) tic4=0;
112 }
113 }
114
115
testSubWindowDo(bool okclicked,const string text,inputDialogData * dat)116 void testSubWindowDo(bool okclicked, const string text, inputDialogData * dat)
117 {
118 if(okclicked) printf(": %s\n",text.c_str());
119 else printf("<--Cancel-->\n");
120
121 }
122
123 editor::setText_state_enum editor::setText_state;
124
SelectedType()125 editorobjecttype editor::SelectedType()
126 {
127 return buttons->SelectedObjectType;
128 }
129
continueSetText(bool okclicked,const string text,inputDialogData * dat)130 void editor::continueSetText(bool okclicked, const string text, inputDialogData * dat)
131 {
132 if(! okclicked ) return;
133 SavedFile=false;
134 switch(setText_state)
135 {
136 case ASSIGN_TITLE:
137 editorboard::filetitle=text;
138 setText_state = ASSIGN_DESCRIPTION;
139 dialogs::makeTextInputDialog(editorwindow,"Enter file description",editorboard::description, 3, "Ok", "Cancel", continueSetText,NULL);
140 break;
141 case ASSIGN_LEVEL_TITLE:
142 board->title = text;
143 setText_state = ASSIGN_HINT;
144 dialogs::makeTextInputDialog(editorwindow,"Enter level hint (can leave empty)",board->hint, 3, "Ok", "Cancel", continueSetText,NULL);
145 break;
146 case ASSIGN_DESCRIPTION:
147 editorboard::description=text;
148 setText_state = ASSIGN_AUTHOR;
149 dialogs::makeTextInputDialog(editorwindow,"Enter file author(s)",editorboard::author, 1, "Ok", "Cancel", continueSetText,NULL);
150 break;
151
152 case ASSIGN_AUTHOR:
153 editorboard::author=text;
154 if (editorboard::CountLevels() > 1) {
155 char x[30];
156 sprintf(x, "%d", editorboard::CurrentLevelNumber() + 1);
157 setText_state = ASSIGN_LEVEL_TITLE;
158 dialogs::makeTextInputDialog(editorwindow,"Enter level title (level "+string(x)+" )", board->title, 3, "Ok", "Cancel", continueSetText,NULL);
159 } else {
160 board->title = editorboard::filetitle;
161 setText_state = ASSIGN_HINT;
162 dialogs::makeTextInputDialog(editorwindow,"Enter level hint (can leave empty)",board->hint, 3, "Ok", "Cancel", continueSetText,NULL);
163
164 }
165
166
167 break;
168
169 case ASSIGN_HINT:
170 board->hint=text;
171 setText_state = ASSIGN_BYE;
172 dialogs::makeTextInputDialog(editorwindow,"Enter level end message (You can leave it empty)",board->bye, 3, "Ok", "Cancel", continueSetText,NULL);
173 break;
174
175 case ASSIGN_BYE:
176 board->bye = text;
177
178
179 }
180 }
beginSetText(const buttondata * data)181 void editor::beginSetText(const buttondata* data)
182 {
183 setText_state=ASSIGN_TITLE;
184 dialogs::makeTextInputDialog(editorwindow,"Enter file title",editorboard::filetitle, 1, "Ok", "Cancel", continueSetText,NULL);
185
186 }
187
188
stripDotXyeExtension(const string s)189 string stripDotXyeExtension(const string s)
190 {
191 int l=s.length();
192 if ( (l<4) || (s[l-1]!='e') || (s[l-2]!='y') || (s[l-3]!='x') || (s[l-4]!='.') ) return s+string(".xye");
193 return s;
194
195 }
196
197
continueAppendFile(bool okclicked,const string text,inputDialogData * dat)198 void editor::continueAppendFile(bool okclicked, const string text, inputDialogData * dat)
199 {
200 if (!okclicked) {
201 return;
202 }
203 SavedFile = false;
204 string tname=stripDotXyeExtension(text);
205 string tfilename=options::GetMyLevelsFolder()+tname;
206 std::ifstream file;
207 file.open(tfilename.c_str(), std::ios::in );
208 if(! file.is_open()) {
209 dialogs::makeMessageDialog(editorwindow, string("File ")+tfilename+string(" does not exist. Cannot append."), "Ok" , onDialogClickDoNothing);
210 } else {
211 file.close();
212 if (! appendLevels(tfilename)) {
213 dialogs::makeMessageDialog(editorwindow, editor::loadError+" Had to halt append operation.","Ok",onDialogClickDoNothing);
214 } else if ( editor::loadError != "") {
215 dialogs::makeMessageDialog(editorwindow, editor::loadError,"Ok",onDialogClickDoNothing);
216 }
217
218 }
219
220 }
221
beginAppendFile(const buttondata * data)222 void editor::beginAppendFile(const buttondata* data)
223 {
224 dialogs::makeTextInputDialog(editorwindow,"This advanced option will (try to) append the contents of a level file at the end of the level you are currently editing. Type the file name.", "filename.xye", 1, "Ok", "Cancel", continueAppendFile,NULL);
225 }
226
continueChangeLevelNumber(bool okclicked,const string text,inputDialogData * dat)227 void editor::continueChangeLevelNumber(bool okclicked, const string text, inputDialogData * dat)
228 {
229 if (!okclicked) {
230 return;
231 }
232 SavedFile = false;
233 int x;
234 string s = "";
235
236 if ( TryS2I(text, x) ) {
237 int n = board->CountLevels();
238 if ( (x >= 1) && (x <= n ) ) {
239 editorboard::MoveToLevelNumber(board, x-1);
240 editor::updateCountRelated();
241 } else {
242 char buf[30];
243 sprintf(buf, "%d", n);
244 s = string("\n\nPlease type a level number between 1 and ")+string(buf)+string(".");
245 }
246 } else {
247 s = "\n\nThe requested input must be a number.";
248 }
249 if (s != "") {
250 char buf[30];
251 sprintf(buf, "%d",board->CurrentLevelNumber()+1);
252 dialogs::makeTextInputDialog(editorwindow,"This advanced option will move the current level to a different position in the file. The other levels will be slided accordingly. Type the new level number. "+s, string(buf), 1, "Ok", "Cancel", continueChangeLevelNumber,NULL);
253
254 }
255
256 }
beginChangeLevelNumber(const buttondata * data)257 void editor::beginChangeLevelNumber(const buttondata*data)
258 {
259 char buf[30];
260 sprintf(buf, "%d",board->CurrentLevelNumber()+1);
261 dialogs::makeTextInputDialog(editorwindow,"This advanced option will move the current level to a different position in the file. The other levels will be slided accordingly. Type the new level number.", string(buf), 1, "Ok", "Cancel", continueChangeLevelNumber,NULL);
262 }
263
parseColorString(string x,DefaultColorData & cd)264 bool parseColorString(string x, DefaultColorData& cd)
265 {
266 if (x=="") {
267 cd.useDefault = true;
268 return true;
269 }
270 if (x.length() != 6) {
271 return false;
272 }
273 string rs = x.substr(0,2);
274 string gs = x.substr(2,2);
275 string bs = x.substr(4,2);
276 int r,g,b;
277 if (sscanf(rs.c_str(), "%x", &r) != 1) {
278 return false;
279 }
280 if (sscanf(gs.c_str(), "%x", &g) != 1) {
281 return false;
282 }
283 if (sscanf(bs.c_str(), "%x", &b) != 1) {
284 return false;
285 }
286 cd.useDefault = false;
287 cd.color.r = r;
288 cd.color.g = g;
289 cd.color.b = b;
290 return true;
291 }
makeColorString(DefaultColorData & cd)292 string makeColorString(DefaultColorData&cd)
293 {
294 if (cd.useDefault) {
295 return "";
296 }
297 string r = "";
298 char buf[3];
299 sprintf(buf,"%02X", cd.color.r );
300 r += buf;
301 sprintf(buf,"%02X", cd.color.g );
302 r += buf;
303 sprintf(buf,"%02X", cd.color.b );
304 r += buf;
305 return r;
306 }
307 int ChangeLevelColor_stage;
308
continueChangeLevelColor(bool okclicked,const string text,inputDialogData * dat)309 void editor::continueChangeLevelColor(bool okclicked, const string text, inputDialogData * dat)
310 {
311 if (!okclicked) {
312 return;
313 }
314 string wallq = "This advanced option will allow you to change the level colors. Type the wall color you want to use in RRGGBB format. (For example, FFFFFF is white, 00FF00 is green). Leave empty to use the skin's default color.";
315 string floorq = "This advanced option will allow you to change the level colors. Type the floor (background) color you want to use in RRGGBB format. (For example, FFFFFF is white, 00FF00 is green). Leave empty to use the skin's default color.";
316 string earthq = "This advanced option will allow you to change the level colors. Type the earth (soft-block) color you want to use in RRGGBB format. (For example, FFFFFF is white, 00FF00 is green). Leave empty to use the skin's default color.";
317
318 string error = "";
319 int & stage =ChangeLevelColor_stage;
320
321 bool good = true;
322 if (stage == 0) {
323 good = parseColorString(text, board->colors[EDITOR_COLOR_WALLS]);
324 } else if (stage == 1) {
325 good = parseColorString(text, board->colors[EDITOR_COLOR_EARTH]);
326 } else if (stage == 2) {
327 good = parseColorString(text, board->colors[EDITOR_COLOR_FLOOR]);
328 }
329 string ntext = text;
330 if (! good) {
331 error = "\n\nPlease enter a string in the requested format.";
332 } else {
333 stage++;
334 if (stage == 1) {
335 ntext = makeColorString( board->colors[EDITOR_COLOR_EARTH] );
336 } else if (stage == 2) {
337 ntext = makeColorString( board->colors[EDITOR_COLOR_FLOOR] );
338 }
339 }
340 if (stage < 3) {
341 if (stage==1) {
342 dialogs::makeTextInputDialog(editorwindow,earthq+error, ntext, 1, "Ok", "Cancel", continueChangeLevelColor,NULL);
343 } else if (stage==2) {
344 dialogs::makeTextInputDialog(editorwindow,floorq+error, ntext, 1, "Ok", "Cancel", continueChangeLevelColor,NULL);
345 } else {
346 dialogs::makeTextInputDialog(editorwindow,wallq+error, ntext, 1, "Ok", "Cancel", continueChangeLevelColor,NULL);
347 }
348 }
349 SavedFile = false;
350 }
beginChangeLevelColor(const buttondata * data)351 void editor::beginChangeLevelColor(const buttondata*data)
352 {
353 ChangeLevelColor_stage = 0;
354 string x = makeColorString( board->colors[EDITOR_COLOR_WALLS] );
355 dialogs::makeTextInputDialog(editorwindow,"This advanced option will allow you to change the level colors. Type the wall color you want to use in RRGGBB format. (For example, FFFFFF is white, 00FF00 is green). Leave empty to use the skin's default color.", x, 1, "Ok", "Cancel", continueChangeLevelColor,NULL);
356 }
357
onClearConfirmation(bool yes)358 void editor::onClearConfirmation(bool yes)
359 {
360 if(yes)
361 {
362 SavedFile=false;
363 board->makeDefaultLevel();
364 }
365 }
366
onClearClick(const buttondata * data)367 void editor::onClearClick(const buttondata* data)
368 {
369 dialogs::makeYesNoDialog(editorwindow,"Clearing will restore the entire level to the default layout, are you sure you want to clear the level?","Yes","No",editor::onClearConfirmation);
370 }
371
onPreviousLevelClick(const buttondata * data)372 void editor::onPreviousLevelClick(const buttondata* data)
373 {
374 editorboard::SaveCopy(board);
375 int n = ( editorboard::CountLevels() );
376 int x = ( editorboard::CurrentLevelNumber() + n - 1 ) % n;
377 editorboard::LoadLevelNumber(board, x);
378 updateCountRelated();
379 }
380
onNextLevelClick(const buttondata * data)381 void editor::onNextLevelClick(const buttondata* data)
382 {
383 editorboard::SaveCopy(board);
384 int n = ( editorboard::CountLevels() );
385 int x = ( editorboard::CurrentLevelNumber() + 1 ) % n;
386 editorboard::LoadLevelNumber(board, x);
387 updateCountRelated();
388 }
389
onInsertLevelClick(const buttondata * data)390 void editor::onInsertLevelClick(const buttondata* data)
391 {
392 SavedFile=false;
393 editorboard::CreateLevel(board);
394 updateCountRelated();
395 }
396
onEraseLevelConfirmation(bool yes)397 void editor::onEraseLevelConfirmation(bool yes)
398 {
399 if(yes)
400 {
401 SavedFile=false;
402 editorboard::DeleteLevel(board);
403 updateCountRelated();
404 }
405 }
406
407
onEraseLevelClick(const buttondata * data)408 void editor::onEraseLevelClick(const buttondata* data)
409 {
410 dialogs::makeYesNoDialog(editorwindow,"Are you sure you want to erase this level?","Yes","No",editor::onEraseLevelConfirmation);
411 }
412
413
414
updateCountRelated()415 void editor::updateCountRelated()
416 {
417 int t = editorboard::CountLevels();
418
419 if (t == 1) {
420 previousbutton->Enabled = false;
421 nextbutton->Enabled = false;
422 erasebutton->Enabled = false;
423 changelevelnumberbutton->Enabled = false;
424 } else {
425 previousbutton->Enabled = true;
426 nextbutton->Enabled = true;
427 erasebutton->Enabled = true;
428 changelevelnumberbutton->Enabled = true;
429 }
430
431 char x[30];
432 char y[30];
433 int ln = editorboard::CurrentLevelNumber()+1;
434 options::SaveLevelFile( filename , ln);
435
436 sprintf(x,"%d", ln );
437 sprintf(y,"%d", t );
438
439 string mylevels = options::GetMyLevelsFolder();
440 int i=0;
441 while ( i < filename.length() && i < mylevels.length() && (filename[i]==mylevels[i]) ) {
442 i++;
443 }
444
445 string title = "Xye - Editor: "+filename.substr(i)+" : "+string(x)+"/"+string(y);
446 SDL_WM_SetCaption(title.c_str(),0);
447
448
449 }
450
451
saveAs(bool okclicked,const string text,inputDialogData * dat)452 void editor::saveAs(bool okclicked, const string text, inputDialogData * dat)
453 {
454 if(okclicked)
455 {
456 string tname=stripDotXyeExtension(text);
457 string tfilename=options::GetMyLevelsFolder()+tname;
458 std::ifstream file;
459 file.open (tfilename.c_str(), std::ios::in );
460 if(file.is_open() && (filename!=tfilename) )
461 {
462 dialogs::makeMessageDialog(editorwindow, string("File ")+string(tfilename)+string(" already exists, unable to replace it."),"Ok",onDialogClickDoNothing);
463 file.close();
464 return;
465 }
466
467 filename=tfilename;
468 filename_name=tname;
469 filename_path=options::GetMyLevelsFolder();
470 if (save())
471 {
472 updateCountRelated();
473 dialogs::makeMessageDialog(editorwindow, string(filename)+string(" saved successfully."),"Ok",onDialogClickDoNothing);
474
475 }
476 }
477 }
478
onSaveAsClick(const buttondata * data)479 void editor::onSaveAsClick(const buttondata* data)
480 {
481 dialogs::makeTextInputDialog(editorwindow,"Enter a new level file name","", 1, "Ok", "Cancel", saveAs,NULL);
482 }
483
484
onBrowseClick(const buttondata * data)485 void editor::onBrowseClick(const buttondata* data)
486 {
487 if(! SavedFile)
488 {
489 dialogs::makeYesNoDialog(editorwindow,"Are you sure you want to close the editor before saving the level?","Yes","No",editor::onBrowseWithoutSavingClick);
490 }
491 else
492 editor::editorwindow->SetTransition(LevelBrowser::StartSection);
493 }
494
495
cancel()496 void editor::cancel()
497 {
498 printf("Closing the editor without saving\n");
499 editorwindow->stop();
500 }
501
ResumeSectionAndQuit(window * wind)502 void editor::ResumeSectionAndQuit(window* wind)
503 {
504 ResumeSection(wind);
505 editor::onQuitClick(NULL);
506 }
507
ResumeSection(window * wind)508 void editor::ResumeSection(window* wind)
509 {
510 Sint16 sz32 = (game::GRIDSIZE*3)/2;
511
512 tic4=0;
513
514 Width=6+XYE_HORZ*GRIDSIZE;
515
516 Height=GRIDSIZE+3+XYE_VERT*GRIDSIZE + 9+(GRIDSIZE+2)*4;
517 editorwindow = wind;
518 editorwindow->Resize(Width, Height);
519 editorwindow->onExitAttempt=editor::onExitAttempt;
520
521
522 SDL_WM_SetCaption("Xye - Editor",0);
523
524
525
526
527 SDL_Color c;
528 //Setup widgets settings:
529
530
531 editorwindow->beforeDraw = editor::beforeDraw;
532 editorwindow->onKeyDown= editor::onKeyDown;
533 editorwindow->onKeyUp= editor::onKeyUp;
534
535 editorwindow->addControl(new rectangle(0,0,Width,Height, 0,0,0 ) );
536
537
538
539
540 control* tmcntrl=new rectangle(0,0,Width,sz, options::LevelMenu_info );
541 tmcntrl->depth=1;
542 editorwindow->addControl(tmcntrl);
543
544 int bx=1;
545 int bw;
546
547 button* tmbut;
548
549 //*** button tooltip
550 buttontooltip* btt = new buttontooltip();
551 btt->depth = 22;
552 wind->addControl(btt);
553 btt->minx = 0;
554 btt->maxx = Width;
555 btt->miny = 0;
556 btt->maxy = GRIDSIZE*2;
557
558 //******* Browse
559 bw=sz32;
560 tmbut= new button(bx,0,bw,button::Size);
561 tmbut->Icon(5,15);
562 tmbut->toolTipControl = btt;
563 tmbut->toolTip = "[Backspace] Return to level browser.";
564 tmbut->onClick = editor::onBrowseClick;
565 tmbut->depth=20;
566 savebutton=tmbut;
567 editorwindow->addControl(tmbut);
568 bx+=bw+1;
569
570
571 //**** Test button
572 bw=sz32;
573 tmbut= new button(bx,0,bw,button::Size);
574 tmbut->Icon(7,3);
575 tmbut->toolTipControl = btt;
576 tmbut->toolTip = "[Enter] Test level.";
577 tmbut->onClick = editor::test;
578 tmbut->depth=20;
579 editorwindow->addControl(tmbut);
580 bx+=bw+1;
581
582
583 // Previous
584 bw=sz32;
585 tmbut= new button(bx,0,bw,button::Size);
586 tmbut->Icon(4,18);
587
588 tmbut->onClick = onPreviousLevelClick;
589 tmbut->toolTipControl = btt;
590 tmbut->toolTip = "[P] Edit previous level.";
591 tmbut->depth=20;
592 previousbutton = tmbut;
593 editorwindow->addControl(tmbut);
594 bx+=bw+1;
595
596 // Next
597 bw=sz32;
598 tmbut= new button(bx,0,bw,button::Size);
599 tmbut->Icon(5,18);
600 tmbut->toolTipControl = btt;
601 tmbut->toolTip = "[N] Edit next level";
602 tmbut->onClick = onNextLevelClick;
603 tmbut->depth=20;
604 nextbutton = tmbut;
605 editorwindow->addControl(tmbut);
606 bx+=bw+1;
607
608
609 //*** insert button
610 bw=button::recommendedWidth("+");
611 tmbut= new button(bx,0,bw,button::Size);
612 tmbut->text="+";
613 tmbut->toolTipControl = btt;
614 tmbut->toolTip = "Insert new level.";
615 tmbut->onClick = onInsertLevelClick;
616 tmbut->depth=20;
617 editorwindow->addControl(tmbut);
618 bx+=bw+1;
619
620 bw=button::recommendedWidth("x");
621 tmbut= new button(bx,0,bw,button::Size);
622 tmbut->text="x";
623 tmbut->toolTipControl = btt;
624 tmbut->toolTip = "Erase this level.";
625 tmbut->onClick = onEraseLevelClick;
626 tmbut->depth=20;
627 erasebutton = tmbut;
628 editorwindow->addControl(tmbut);
629 bx+=bw+1;
630
631
632 bw=button::recommendedWidth("c");
633 tmbut= new button(bx,0,bw,button::Size);
634 tmbut->text="c";
635 tmbut->toolTipControl = btt;
636 tmbut->toolTip = "Clear";
637 tmbut->onClick = onClearClick;
638 tmbut->depth=20;
639 editorwindow->addControl(tmbut);
640 bx+=bw+1;
641
642 bw=button::recommendedWidth("a");
643 tmbut= new button(bx,0,bw,button::Size);
644 tmbut->text="a";
645 tmbut->toolTipControl = btt;
646 tmbut->toolTip = "Edit text...";
647 tmbut->onClick = beginSetText;
648 tmbut->depth=20;
649 editorwindow->addControl(tmbut);
650 bx+=bw+1;
651
652 //*** Solution button:
653 bw=sz32;
654 tmbut = new button(bx,0, bw, button::Size);
655 tmbut->Icon(8,4);
656 tmbut->toolTipControl = btt;
657 tmbut->toolTip = "[S] Play solution";
658 tmbut->depth=20;
659 tmbut->onClick = editor::playSolution;
660 editorwindow->addControl(tmbut);
661 solutionbutton=tmbut;
662 bx+=bw+1;
663
664
665 //********
666
667 bx+=sz/2;
668 bw=button::recommendedWidth("*");
669 tmbut= new button(bx,0,bw,button::Size);
670 tmbut->text="*";
671 tmbut->toolTipControl = btt;
672 tmbut->toolTip = "Append levels from file... (advanced)";
673 tmbut->onClick = beginAppendFile;
674 tmbut->depth=20;
675 editorwindow->addControl(tmbut);
676 bx+=bw+1;
677
678 bw=button::recommendedWidth("#");
679 tmbut= new button(bx,0,bw,button::Size);
680 tmbut->text="#";
681 tmbut->toolTipControl = btt;
682 tmbut->toolTip = "Change level number... (advanced)";
683 tmbut->onClick = beginChangeLevelNumber;
684 tmbut->depth=20;
685 changelevelnumberbutton = tmbut;
686 editorwindow->addControl(tmbut);
687 bx+=bw+1;
688
689 //*** Colors:
690 bw=sz32;
691 bw=button::recommendedWidth("$");
692 tmbut= new button(bx,0,bw,button::Size);
693 tmbut->text="$";
694 tmbut->toolTipControl = btt;
695 tmbut->toolTip = "Edit level colors... (advanced)";
696 tmbut->depth=20;
697 tmbut->onClick = beginChangeLevelColor;
698 editorwindow->addControl(tmbut);
699 bx+=bw+1;
700
701 bx+=sz/2;
702
703 bw=button::recommendedWidth("Save");
704 tmbut= new button(bx,0,bw,button::Size);
705 tmbut->text="Save";
706 tmbut->onClick = editor::buttonSave;
707 tmbut->depth=20;
708 savebutton=tmbut;
709 editorwindow->addControl(tmbut);
710 bx+=bw+1;
711
712 bw=button::recommendedWidth("Save as");
713 tmbut= new button(bx,0,bw,button::Size);
714 tmbut->text="Save as";
715 tmbut->onClick = editor::onSaveAsClick;
716 tmbut->depth=20;
717 savebutton=tmbut;
718 editorwindow->addControl(tmbut);
719 bx+=bw+1;
720
721
722 bw=button::recommendedWidth("Quit");
723 tmbut= new button(Width-1 -bw,0,bw,button::Size);
724 tmbut->text="Quit";
725 tmbut->onClick = editor::onQuitClick;
726 tmbut->depth=21;
727 editorwindow->addControl(tmbut);
728 bx+=bw+1;
729 Sint16 by = 0;
730
731
732
733 tmcntrl=new rectangle(3, XYE_VERT*sz + sz+3+by+3 , Width-6, 4+(sz+2)*4 , 255,255,255 );
734 tmcntrl->depth=2;
735 editorwindow->addControl(tmcntrl);
736
737
738 board = new editorboard(3,by+3+sz);
739 editorboard::LoadCopy(board);
740 updateCountRelated();
741
742 buttons = new editorbuttons(5, XYE_VERT*sz + by+8+sz , Width-10, 2+(sz+2)*4 );
743
744
745 board->depth = 3;
746 buttons->depth = 3;
747
748 editorwindow->addControl(buttons);
749 editorwindow->addControl(board);
750
751 }
752
StartSection(window * wind)753 void editor::StartSection(window* wind)
754 {
755 ResumeSection(wind);
756 bool trytest = true;
757 if (!load())
758 {
759 editorboard::ResetLevels();
760 editorboard::LoadCopy(board);
761 updateCountRelated();
762 dialogs::makeMessageDialog(editorwindow, editor::loadError,"Ok",onDialogClickDoNothing);
763
764 } else if ( editor::loadError != "") {
765 dialogs::makeMessageDialog(editorwindow, editor::loadError,"Ok",onDialogClickDoNothing);
766 }
767
768 editorwindow = wind;
769 }
770
SetFile(const string & path,const string & file)771 void editor::SetFile(const string &path, const string &file)
772 {
773 filename_path=path;
774 filename_name=file;
775 filename=path+file;
776 }
777
778
779
Error(const char * msg)780 void editor::Error(const char* msg)
781 {
782 fprintf(stderr,"%s", msg);
783 fprintf(stderr,"\n");
784 throw (msg);
785 }
786
787 bool editorEscapePressed=false;
onKeyDown(SDLKey keysim,Uint16 unicode)788 void editor::onKeyDown(SDLKey keysim, Uint16 unicode)
789 {
790 switch(keysim)
791 {
792 case (SDLK_ESCAPE): //ESC
793 editorEscapePressed=true;
794 break;
795 case (SDLK_RETURN): case (SDLK_KP_ENTER): //Enter
796 EnterPressed = true;
797 break;
798 };
799
800 }
801
onKeyUp(SDLKey keysim,Uint16 unicode)802 void editor::onKeyUp(SDLKey keysim, Uint16 unicode)
803 {
804 switch(keysim)
805 {
806 case (SDLK_ESCAPE): //ESC
807 if(editorEscapePressed)
808 {
809 editorEscapePressed=false;
810 onExitAttempt();
811 }
812 break;
813 case (SDLK_BACKSPACE):
814 onBrowseClick(NULL);
815 break;
816 case(SDLK_RETURN): case(SDLK_KP_ENTER): //Enter
817 if(EnterPressed)
818 {
819 EnterPressed=false;
820 test(false);
821 }
822 break;
823 case (SDLK_s):
824 if( solutionbutton->Enabled ) {
825 playSolution(NULL);
826 }
827 break;
828 case(SDLK_PLUS): case(SDLK_KP_PLUS): case(SDLK_n): //Plus - N
829 if (nextbutton->Enabled) {
830 onNextLevelClick(NULL);
831 }
832 break;
833
834 case(SDLK_MINUS): case(SDLK_KP_MINUS): case(SDLK_b): case(SDLK_p): //Minus - b - p
835 if (previousbutton->Enabled) {
836 onPreviousLevelClick(NULL);
837 }
838 break;
839
840 };
841 }
test(bool solution)842 void editor::test(bool solution)
843 {
844 string nfilename = filename+"~";
845 if (! save(nfilename, true) )
846 {
847 dialogs::makeMessageDialog(editorwindow, string("Unable to test the level because xyedit cannot rewrite ")+string(filename+"~")+".","Ok",onDialogClickDoNothing);
848 return;
849 }
850 editorboard::SaveCopy(editor::board);
851 buttons->SaveCopy();
852 game::TestLevel(nfilename.c_str(), 1, solution);
853 }
854
855
856
test()857 void editor::test()
858 {
859 test(false);
860 }
861
playSolution(const buttondata * data)862 void editor::playSolution(const buttondata*data)
863 {
864 test(true);
865 }
866
867 class passHintObject: public inputDialogData
868 {
869 public:
870 boardelement* o;
871 };
872
continueAskHint(bool okclicked,const string text,inputDialogData * dat)873 void editor::continueAskHint(bool okclicked, const string text, inputDialogData * dat)
874 {
875 if (!okclicked) {
876 return;
877 }
878 passHintObject * dt = static_cast<passHintObject*>(dat);
879 boardelement*o = dt->o;
880 o->hint = text;
881 }
882
askHint(boardelement * o)883 void editor::askHint(boardelement* o) {
884 string oldhint = o->hint;
885 passHintObject * dat = new passHintObject();
886 dat->o = o;
887 dialogs::makeTextInputDialog(editorwindow,"Type the hint", oldhint, 1, "Ok", "Cancel", continueAskHint, dat);
888 }
889
890 /*********** Plenty of object handling ***/
891
892
893
894
895
896 /*********** editorbuttons control! ***/
setInfo(const string & msg)897 void editorbuttons::setInfo(const string & msg)
898 {
899 text=msg;
900 SelectedObjectType= EDOT_NONE;
901 Eraser=true;
902
903 }
904
editorbuttons(int sx,int sy,int sw,int sh)905 editorbuttons::editorbuttons(int sx, int sy, int sw, int sh)
906 {
907 saved = false;
908 depth=0;
909 x=sx;y=sy;w=sw;h=sh;
910 mousex=mousey=0;
911 clicked=mouse=false;
912
913 for (int i=0;i<EDITORBUTTONS_COUNTX;i++)
914 for (int j=0;j<EDITORBUTTONS_COUNTY;j++)
915 {
916 singleobject &o=buttons[i][j];
917 o.content=CONTENT_NOCONTENT;
918 o.type = EDOT_GEM;
919 o.selected=false;
920 o.flash=false;
921 o.color=EDCO_YELLOW;
922 o.variation=0;
923 o.direction = 0;
924 o.round=false;
925 }
926
927 hover=NULL;
928 clickedempty=NULL;
929 clickedobject=NULL;
930 selection=NULL;
931
932
933 if(SavedSolution)
934 {
935 SavedSolution = false;
936 text = "The new solution has been recorded";
937 }
938 else
939 {
940 text="Welcome to xyedit!";
941 }
942
943 int bp=-1;
944 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
945 buttons[bp][1].type=EDOT_XYE;
946
947 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
948 buttons[bp][1].type=EDOT_GEM;
949 buttons[bp][1].color=EDCO_BLUE;
950
951
952 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
953 buttons[bp][1].type=EDOT_WALL;
954
955 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
956 buttons[bp][1].type=EDOT_BLOCK;
957
958 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
959 buttons[bp][1].type=EDOT_SPECIALBLOCKS;
960
961
962 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
963 buttons[bp][1].type=EDOT_EARTH;
964
965 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
966 buttons[bp][1].type=EDOT_GEMBLOCK;
967
968 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
969 buttons[bp][1].type=EDOT_MAGNET;
970
971
972 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
973 buttons[bp][1].type=EDOT_PUSHER;
974
975 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
976 buttons[bp][1].type=EDOT_ARROWMAKER;
977
978
979 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
980 buttons[bp][1].type=EDOT_HAZARD;
981
982 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
983 buttons[bp][1].type=EDOT_ONEDIRECTION;
984
985 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
986 buttons[bp][1].type=EDOT_BEAST;
987
988 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
989 buttons[bp][1].type=EDOT_TELEPORT;
990
991 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
992 buttons[bp][1].type=EDOT_TURNER;
993
994 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
995 buttons[bp][1].type=EDOT_COLORSYSTEM;
996
997 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
998 buttons[bp][1].type=EDOT_BOT;
999
1000 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1001 buttons[bp][1].type=EDOT_KEYSYSTEM;
1002
1003 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1004 buttons[bp][1].type=EDOT_NUMBER;
1005
1006 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1007 buttons[bp][1].type=EDOT_FIREPAD;
1008
1009 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1010 buttons[bp][1].type=EDOT_RATTLERHEAD;
1011
1012 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1013 buttons[bp][1].type=EDOT_FOOD;
1014
1015 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1016 buttons[bp][1].type=EDOT_LARGEBLOCK;
1017 buttons[bp][1].variation = 4;
1018
1019 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1020 buttons[bp][1].type=EDOT_PORTAL;
1021
1022 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1023 buttons[bp][1].type=EDOT_COLORFACTORY;
1024
1025 buttons[++bp][1].content=CONTENT_CHANGEOBJECT;
1026 buttons[bp][1].type=EDOT_DANGERFACTORY;
1027
1028 buttons[0][2].content=CONTENT_CHANGEOBJECT;
1029 buttons[0][2].type=EDOT_HINT;
1030
1031
1032 SelectedObjectType= EDOT_NONE;
1033 Eraser=true;
1034
1035 if (copy.saved) {
1036 LoadCopy();
1037 }
1038 }
1039
getbuttonbyxy(int x,int y)1040 singleobject * editorbuttons::getbuttonbyxy(int x, int y)
1041 {
1042
1043 x-=2; if (x<0) return NULL;
1044 int bx=x/(sz+2);
1045
1046
1047
1048 if (bx>=EDITORBUTTONS_COUNTX) return NULL;
1049 y-=2; if (y<0) return NULL;
1050
1051 int by=y/(sz+2);
1052
1053 if (by>=EDITORBUTTONS_COUNTY) return NULL;
1054
1055 lastclickedx=bx;
1056 lastclickedy=by;
1057
1058 return &buttons[bx][by];
1059 }
1060
detectRotation(int x0,int y0,int x1,int y1)1061 int editorbuttons::detectRotation(int x0, int y0, int x1, int y1)
1062 {
1063 if((x0==x1)&&(y0==y1)) return 0;
1064 singleobject * a=getbuttonbyxy(x0,y0);
1065 singleobject * b=getbuttonbyxy(x1,y1);
1066 if ((a!=b) || (a==NULL)) return 0;
1067 x0= (x0-2)%(sz+2);if(x0>sz) x0=sz;
1068 x1= (x1-2)%(sz+2);if(x1>sz) x1=sz;
1069 y0= (y0-2)%(sz+2);if(y0>sz) y0=sz;
1070 y1= (y1-2)%(sz+2);if(y1>sz) y1=sz;
1071
1072 int sz2=sz>>1;
1073
1074 int q0,q1;
1075
1076 if (x0>sz2)
1077 {
1078 if( y0>sz2) q0=3;
1079 else q0=0;
1080 }
1081 else
1082 {
1083 if( y0>sz2) q0=2;
1084 else q0=1;
1085 }
1086 if (x1>sz2)
1087 {
1088 if( y1>sz2) q1=3;
1089 else q1=0;
1090 }
1091 else
1092 {
1093 if( y1>sz2) q1=2;
1094 else q1=1;
1095 }
1096 if(q1==q0) return 0;
1097 if(q1== (q0+1)%4 ) return 1;
1098 return -1;
1099 }
1100
onMouseMove(int px,int py)1101 void editorbuttons::onMouseMove(int px,int py)
1102 {
1103 singleobject * obj;
1104 obj=getbuttonbyxy(px,py);
1105
1106 if((hover!=obj) && (hover!=NULL)) hover->flash=false;
1107 hover=obj;
1108 if (hover) hover->flash=true;
1109
1110 if(clicked)
1111 {
1112 //Drag and drop, handle rotation...
1113 int rot=detectRotation(mousex,mousey,px,py);
1114 if (clickedobject != NULL) {
1115 clickedobject->direction+=rot+4;
1116 clickedobject->direction%=4;
1117 SelectedDirection = clickedobject->direction;
1118 for (int i=0;i<EDITORBUTTONS_COUNTX;i++) {
1119 for (int j=0;j<EDITORBUTTONS_COUNTY;j++){
1120 singleobject &o=buttons[i][j];
1121 if (o.content != CONTENT_DIRECTION && o.content != CONTENT_NOCONTENT ) {
1122 if (o.type == clickedobject->type) {
1123 o.direction = clickedobject-> direction;
1124 }
1125 }
1126 }
1127 }
1128 }
1129 }
1130 mousex=px;
1131 mousey=py;
1132 mouse=true;
1133 }
1134
onMouseOut()1135 void editorbuttons::onMouseOut()
1136 {
1137 if(hover!=NULL)
1138 {
1139 hover->flash=false;
1140 hover=NULL;
1141 }
1142 mouse=false;
1143 clicked=false;
1144 }
1145
onMouseDown(int px,int py)1146 void editorbuttons::onMouseDown(int px,int py)
1147 {
1148 clicked=true;
1149 }
1150
ifnotnulldeselect(singleobject * s)1151 void ifnotnulldeselect(singleobject*s)
1152 {
1153 if(s!=NULL) s->selected=false;
1154 }
ifnotnullselect(singleobject * s)1155 void ifnotnullselect(singleobject*s)
1156 {
1157 if(s!=NULL) s->selected=true;
1158 }
1159
handleClick(singleobject * target)1160 void editorbuttons::handleClick(singleobject* target)
1161 {
1162 switch(target->content)
1163 {
1164 case CONTENT_NOCONTENT:
1165 if(clickedempty==target) break;
1166 ifnotnulldeselect(clickedempty);
1167 ifnotnulldeselect(selection);
1168 target->selected=true;
1169 clickedempty=target;
1170 text="Eraser tool";
1171 Eraser=true;
1172 break;
1173
1174 case CONTENT_CHANGEOBJECT:
1175
1176 ifnotnulldeselect(clickedempty); clickedempty=NULL;
1177 ifnotnulldeselect(clickedobject);
1178 ifnotnulldeselect(selection);
1179
1180
1181 switchToObject(target->type,target->color,target->round,target->variation, target->direction);
1182 target->selected=true;
1183 selection=clickedobject=target;
1184 break;
1185
1186 case CONTENT_RECOLOR:
1187 ifnotnulldeselect(clickedempty); clickedempty=NULL;
1188 ifnotnulldeselect(selection);
1189 switchToObject(SelectedObjectType,target->color, SelectedRound, SelectedVariation, SelectedDirection);
1190 target->selected=true;
1191
1192 clickedobject->color=target->color;
1193 selection=target;
1194 break;
1195
1196 case CONTENT_DIRECTION:
1197
1198 ifnotnulldeselect(clickedempty); clickedempty=NULL;
1199 ifnotnulldeselect(selection);
1200 switchToObject(SelectedObjectType,SelectedColor, SelectedRound, SelectedVariation, target->direction);
1201 target->selected=true;
1202
1203 clickedobject->direction=target->direction;
1204 selection=target;
1205 break;
1206
1207 case CONTENT_VARIATION:
1208
1209 ifnotnulldeselect(clickedempty); clickedempty=NULL;
1210 ifnotnulldeselect(selection);
1211 switchToObject(SelectedObjectType,SelectedColor, SelectedRound, target->variation, SelectedDirection);
1212 target->selected=true;
1213
1214 clickedobject->variation=target->variation;
1215 selection=target;
1216 break;
1217
1218 case CONTENT_MAKEROUND:
1219
1220
1221 ifnotnulldeselect(clickedempty); clickedempty=NULL;
1222 ifnotnulldeselect(selection);
1223 switchToObject(SelectedObjectType,SelectedColor, target->round, SelectedVariation, SelectedDirection);
1224 target->selected=true;
1225
1226 clickedobject->round=target->round;
1227 selection=target;
1228 }
1229 }
1230
onMouseUp(int px,int py)1231 void editorbuttons::onMouseUp(int px,int py)
1232 {
1233 clicked=false;
1234 singleobject* target=getbuttonbyxy(px,py);
1235 Eraser=false;
1236 if(target)
1237 {
1238 handleClick( target );
1239 }
1240 }
1241
drawbutton(SDL_Surface * target,singleobject & o,int x,int y)1242 void editorbuttons::drawbutton(SDL_Surface* target,singleobject &o, int x, int y)
1243 {
1244 if(o.selected || o.flash)
1245 {
1246
1247 if(o.flash)
1248 {
1249 if(clicked) SDL_FillRect(target,x-2,y-2,editor::GRIDSIZE+4,editor::GRIDSIZE+4,SDL_MapRGB(target->format,200,200,255));
1250 else SDL_FillRect(target,x-2,y-2,editor::GRIDSIZE+4,editor::GRIDSIZE+4,SDL_MapRGB(target->format,200,200,200));
1251 }
1252 else SDL_FillRect(target,x-2,y-2,editor::GRIDSIZE+4,editor::GRIDSIZE+4,SDL_MapRGB(target->format,0,0,0));
1253 SDL_FillRect(target,x,y,editor::GRIDSIZE,editor::GRIDSIZE,SDL_MapRGB(target->format,255,255,255));
1254
1255 }
1256 switch(o.content)
1257 {
1258 case CONTENT_NOCONTENT:
1259 //SDL_FillRect(target,x,y,editor::GRIDSIZE,editor::GRIDSIZE,SDL_MapRGB(target->format,0,0,120));
1260 break;
1261 case CONTENT_CHANGEOBJECT:
1262 drawObjectBySpecs( target,x,y,o.type,o.color, o.round, o.variation, o.direction);
1263 break;
1264
1265 case CONTENT_RECOLOR:
1266 drawObjectBySpecs( target,x,y, SelectedObjectType, o.color, SelectedRound, SelectedVariation, SelectedDirection);
1267 break;
1268 case CONTENT_VARIATION:
1269 drawObjectBySpecs( target,x,y, SelectedObjectType, SelectedColor, SelectedRound, o.variation, SelectedDirection);
1270 break;
1271 case CONTENT_MAKEROUND:
1272 drawObjectBySpecs( target,x,y, SelectedObjectType, SelectedColor, o.round, SelectedVariation, SelectedDirection);
1273 break;
1274 case CONTENT_DIRECTION:
1275 drawObjectBySpecs( target,x,y, SelectedObjectType, SelectedColor, SelectedRound, SelectedVariation, o.direction);
1276 break;
1277
1278
1279 }
1280 }
1281
draw(SDL_Surface * target)1282 void editorbuttons::draw(SDL_Surface* target)
1283 {
1284
1285 SDL_FillRect(target,x,y,w,h,SDL_MapRGB(target->format,255,255,255));
1286
1287 int i,j;
1288 for (i=0;i<EDITORBUTTONS_COUNTX;i++) for (j=0;j<EDITORBUTTONS_COUNTY;j++)
1289 {
1290 singleobject &o=buttons[i][j];
1291 drawbutton(target, o,2+x+i*(editor::GRIDSIZE+2),2+y+j*(editor::GRIDSIZE+2));
1292
1293 }
1294
1295 const char* c = text.c_str();
1296 int tw= editor::FontRes->TextWidth(c);
1297 int ty=2+y+EDITORBUTTONS_COUNTY*(sz+2)+(sz-editor::FontRes->Height())/2+2;
1298 int tx=(w-tw)/2;
1299
1300 editor::FontRes->Write(target,x+tx,ty,c);
1301
1302 }
1303
1304 editorbuttons editorbuttons::copy(0,0,0,0);
SaveCopy()1305 void editorbuttons::SaveCopy() {
1306 copy.saved = true;
1307 for (int i=0;i<EDITORBUTTONS_COUNTX;i++) {
1308 for (int j=0;j<EDITORBUTTONS_COUNTY;j++) {
1309 copy.buttons[i][j] = buttons[i][j];
1310 }
1311 }
1312
1313 }
LoadCopy()1314 void editorbuttons::LoadCopy() {
1315 for (int i=0;i<EDITORBUTTONS_COUNTX;i++) {
1316 //for (int j=0;j<EDITORBUTTONS_COUNTY;j++) {
1317 //only load the objects from the middle line.
1318 buttons[i][1] = copy.buttons[i][1];
1319 buttons[i][1].selected = false;
1320 //}
1321 }
1322
1323 }
1324
1325 /**** editorbuttons object specific: ***/
1326
gettextRC(const char * base,editorcolor color,bool round)1327 string gettextRC(const char * base, editorcolor color, bool round)
1328 {
1329 string res="";
1330 switch (color)
1331 {
1332 case EDCO_BLUE: res="Blue "; break;
1333 case EDCO_RED: res="Red "; break;
1334 case EDCO_GREEN: res="Green "; break;
1335 case EDCO_YELLOW: res="Yellow "; break;
1336 case EDCO_PURPLE: res="Purple "; break;
1337 case EDCO_WHITE: res="White "; break;
1338 case EDCO_METAL: res="Metal "; break;
1339 case EDCO_WILD: res="Wildcard "; break;
1340 }
1341 if(round) res+="round ";
1342 res+=base;
1343 if(color == EDCO_METAL) res+=" (resists fire)";
1344 return res;
1345 }
1346
GetMonsterName(int variation)1347 const char* GetMonsterName(int variation)
1348 {
1349 switch ((btype)(variation))
1350 {
1351 case BT_GNASHER: return "Gnasher";
1352 case BT_BLOB: return "Blob"; break;
1353 case BT_TWISTER: return "Twister"; break;
1354 case BT_SPIKE: return "Spike"; break;
1355 case BT_STATIC : return "Inertia"; break;
1356 case BT_PATIENCE: return "Patience"; break;
1357 case BT_TIGER: return "Tiger"; break;
1358 case BT_DARD: return "Dart"; break;
1359 case BT_RANGER: return "Ranger"; break;
1360 case BT_SPINNER: return "Spinner (clockwise)"; break;
1361 case BT_ASPINNER: return "Spinner (anti-clockwise)"; break;
1362 case BT_BLOBBOSS: return "Blob mind"; break;
1363 case BT_WARD: return "Ward"; break;
1364 case BT_VIRUS: return "Virus"; break;
1365
1366 }
1367 return "?";
1368 }
updateText(editorobjecttype ot,editorcolor color,bool round,int variation,int direction)1369 void editorbuttons::updateText( editorobjecttype ot, editorcolor color, bool round, int variation, int direction)
1370 {
1371 switch(ot)
1372 {
1373 case EDOT_BOT: text="Bot";break;
1374 case EDOT_FOOD: text="Snake food";break;
1375 case EDOT_RATTLERHEAD:
1376 text="Snake";
1377 if(variation>0)
1378 {
1379 char lengthtex[20];
1380 sprintf(lengthtex," (Length: %d) ",variation);
1381 text+=lengthtex;
1382 }
1383
1384
1385
1386
1387 break;
1388 case EDOT_FIREPAD: text="Fire pad";break;
1389
1390
1391 case EDOT_XYE:
1392 text="Xye";
1393 if( variation!=0)
1394 {
1395 char livetex[8];
1396 sprintf(livetex,"%d",variation);
1397 text += " (+";
1398 text += livetex;
1399 if(variation==1) text += " extra life)";
1400 else text+=" extra lives)";
1401 }
1402 break;
1403
1404 case EDOT_COLORSYSTEM:
1405 switch(variation)
1406 {
1407 case 0: text="Color door (closed)"; break;
1408 case 1: text="Color door (open)"; break;
1409 case 2: text="Color trapdoor (closed)"; break;
1410 case 3: text="Color trapdoor (open)"; break;
1411 case 4: text="Color marked area"; break;
1412 case 5: text="Color requirement-block"; break;
1413 case 6: text="Color marked area (with block)"; break;
1414 case 7: text="Color marked area (with wildcard block)"; break;
1415
1416 }
1417 break;
1418
1419 case EDOT_KEYSYSTEM:
1420 if(variation) text="Lock";
1421 else text="Key";
1422 break;
1423
1424 case EDOT_BLOCK:
1425 text=gettextRC("block",color,round); break;
1426
1427 case EDOT_NUMBER:
1428
1429 switch(color)
1430 {
1431 case EDCO_RED: text="Exploding number-block"; break;
1432 case EDCO_GREEN: text="Security timer block"; break;
1433 case EDCO_BLUE: text="Slow timer block"; break;
1434 case EDCO_YELLOW: text="Timer block"; break;
1435
1436 }
1437
1438 break;
1439
1440 case EDOT_WALL:
1441 if(round)
1442 {
1443 if (variation>3) text="Wall (auto-round, fire-resistant)";
1444 else text="Wall (auto-round)";
1445 }
1446 else
1447 {
1448 if (variation>3) text="Wall (fire-resistant)";
1449 else text="Wall";
1450 }
1451 break;
1452 case EDOT_GEM:
1453
1454 switch (color)
1455 {
1456 case EDCO_GREEN: text="Emerald (green gem)"; break;
1457 case EDCO_YELLOW: text="Topaz (yellow gem)"; break;
1458 case EDCO_BLUE: text="Diamond (blue gem)"; break;
1459 case EDCO_RED: text="Ruby (red gem)"; break;
1460 default: text="Star (optional gem)";
1461 }
1462 break;
1463
1464 case EDOT_EARTH:
1465 if(round) text="Round soft block";
1466 else text="Soft block"; break;
1467 case EDOT_GEMBLOCK: text="Gem requirement block"; break;
1468 case EDOT_MAGNET:
1469
1470 switch(variation)
1471 {
1472 case 0: text="Magnet"; break;
1473 case 2: text="Sticky block"; break;
1474 case 1: text="Inverse magnet"; break;
1475
1476 }
1477 break;
1478
1479 case EDOT_LARGEBLOCK:
1480 switch(variation)
1481 {
1482 case 0: text="Large block (1-0-0-0)"; break;
1483 case 1: text="Large block (1-1-0-0)"; break;
1484 case 2: text="Large block (1-0-1-0)"; break;
1485 case 3: text="Large block (1-1-1-0)"; break;
1486 case 4: text="Large block (1-1-1-1)"; break;
1487 }
1488
1489 break;
1490
1491 case EDOT_PORTAL:
1492
1493 if(variation==0) text=gettextRC("portal (primary)",color,false);
1494 else if(variation==1) text=gettextRC("portal (secondary)",color,false);
1495 else text=gettextRC("portal (exit)",color,false);
1496 break;
1497
1498 case EDOT_COLORFACTORY:
1499 switch(variation)
1500 {
1501 case 0: text=gettextRC("block factory",color,round); break;
1502 case 1: text=gettextRC("arrow block factory",color,round); break;
1503 case 2: text=gettextRC("dot-block factory",color,round); break;
1504 case 3: text=gettextRC("pusher factory",color,false); break;
1505 case 4: text=gettextRC("gem factory",color,false); break;
1506 }
1507 break;
1508 case EDOT_DANGERFACTORY:
1509 switch(variation)
1510 {
1511 case 14: text="Rattler factory"; break;
1512 case 15: text="Rattler food factory"; break;
1513 case 16: text="Land mine factory"; break;
1514
1515 default: text=string(GetMonsterName(variation))+" factory";
1516 }
1517 break;
1518
1519
1520 case EDOT_PUSHER:
1521 switch(color)
1522 {
1523 case EDCO_YELLOW: text="Bouncer pusher"; break;
1524 case EDCO_RED: text="Persistent pusher"; break;
1525 case EDCO_BLUE: text="Clock-wise pusher"; break;
1526 case EDCO_GREEN: text="Anticlock-wise pusher"; break;
1527
1528 }
1529 break;
1530
1531 case EDOT_ARROWMAKER:
1532
1533 if(variation==0) text=gettextRC("shooter clock",color ,round);
1534 else if (variation==1) text=gettextRC("filler",color ,round);
1535 else if (variation==2) text=gettextRC("sniper",color ,round);
1536 break;
1537
1538 case EDOT_HAZARD:
1539 switch(variation)
1540 {
1541 case 0: text="Black hole"; break;
1542 case 1: text="Land mine"; break;
1543 case 2: text="Pit"; break;
1544 }
1545
1546 break;
1547 case EDOT_ONEDIRECTION:
1548 if(!variation) switch(direction)
1549 {
1550 case EDITORDIRECTION_DOWN : text="One-way door (up->down)"; break;
1551 case EDITORDIRECTION_UP : text="One-way door (down->up)"; break;
1552 case EDITORDIRECTION_LEFT : text="One-way door (right->left)"; break;
1553 case EDITORDIRECTION_RIGHT : text="One-way door (left->right)"; break;
1554 }
1555 else if (variation==1) {
1556 text="Force arrow";
1557 } else {
1558 Uint32 flags = getHiddenWayFlagsByVariationAndDir(variation, direction);
1559 text = "Hidden path ";
1560 if ( flags & (1<<8) ) {
1561 text += "(up) ";
1562 }
1563 if ( flags & (1<<2) ) {
1564 text += "(down) ";
1565 }
1566 if ( flags & (1<<4) ) {
1567 text += "(left) ";
1568 }
1569 if ( flags & (1<<6) ) {
1570 text += "(right) ";
1571 }
1572
1573 }
1574 break;
1575
1576 case EDOT_TELEPORT:
1577 switch(direction) {
1578 case EDITORDIRECTION_DOWN : text="Teleport (down->up)"; break;
1579 case EDITORDIRECTION_UP : text="Teleport (up->down)"; break;
1580 case EDITORDIRECTION_LEFT : text="Teleport (left->right)"; break;
1581 case EDITORDIRECTION_RIGHT : text="Teleport (right->left)"; break;
1582 }
1583 break;
1584
1585 case EDOT_TURNER:
1586 if(variation) text=gettextRC("turning block (anticlock-wise)",color ,round);
1587 else text=gettextRC("turning block (clock-wise)",color ,round);
1588 break;
1589
1590 case EDOT_SPECIALBLOCKS:
1591 switch(variation)
1592 {
1593 case 0: text=gettextRC("arrow-block",color,round);break;
1594 case 1: text=gettextRC("scroll-block",color,round);break;
1595 case 2: text=gettextRC("toggle-block (on)",color,round);break;
1596 case 3: text=gettextRC("toggle-block (off)",color,round);break;
1597 case 4: text=gettextRC("dot-block",color,round);break;
1598 case 5: text=gettextRC("surprise! block",color,round);break;
1599 }
1600 break;
1601
1602 case EDOT_BEAST:
1603 text = GetMonsterName(variation);
1604
1605 break;
1606 case EDOT_HINT:
1607 text = "Place / Edit hint.";
1608 break;
1609 default:
1610 text = "unknown";
1611 }
1612 }
1613
extendButtons(editorobjecttype ot,editorcolor color,bool round,int variation)1614 void editorbuttons::extendButtons( editorobjecttype ot, editorcolor color, bool round, int variation)
1615 {
1616 bool roundchoice=false;
1617 int maxvariations=0;
1618 int colorchoice = 0;
1619 int dirchoice = 0;
1620
1621 switch(ot)
1622 {
1623 case EDOT_GEM: colorchoice=1; break;
1624
1625 case EDOT_COLORSYSTEM: colorchoice=1; maxvariations=8; break;
1626 case EDOT_RATTLERHEAD: maxvariations=10; dirchoice = 4;break;
1627
1628 case EDOT_NUMBER: colorchoice=1; roundchoice=1; maxvariations=10; break;
1629
1630 case EDOT_BLOCK: colorchoice=4; roundchoice=true; break;
1631 case EDOT_TURNER: colorchoice=2; roundchoice=true; maxvariations=2; break;
1632
1633
1634 case EDOT_XYE: maxvariations=4; break;
1635 case EDOT_WALL: maxvariations=6; roundchoice=true; break;
1636 case EDOT_MAGNET: maxvariations=3; dirchoice = 2; break;
1637
1638 case EDOT_EARTH: roundchoice=true; break;
1639
1640 case EDOT_KEYSYSTEM: colorchoice=1; maxvariations=2; break;
1641 case EDOT_SPECIALBLOCKS: roundchoice=true; colorchoice=1; maxvariations=6; dirchoice = 4; break;
1642 case EDOT_GEMBLOCK: colorchoice=1; break;
1643
1644
1645
1646
1647 case EDOT_ARROWMAKER: colorchoice=1; roundchoice=true; maxvariations=3; dirchoice = 4; break;
1648
1649
1650 case EDOT_PUSHER: colorchoice=1; dirchoice = 4; break;
1651
1652 case EDOT_HAZARD: maxvariations=3; break;
1653 case EDOT_ONEDIRECTION: maxvariations=8; dirchoice = 4; break;
1654 case EDOT_BEAST: maxvariations=14; dirchoice = 4; break;
1655
1656 case EDOT_LARGEBLOCK: maxvariations=5; colorchoice=2; dirchoice = 4; break;
1657 case EDOT_PORTAL: maxvariations=3; colorchoice=2; break;
1658 case EDOT_COLORFACTORY: maxvariations=5; colorchoice=1; roundchoice=1; dirchoice=4; break;
1659 case EDOT_DANGERFACTORY: maxvariations=17; dirchoice=4; break;
1660
1661 case EDOT_TELEPORT: dirchoice=4; break;
1662
1663 //default : //EDOT_BOT,EDOT_FIREPAD, EDOT_FOOD
1664 }
1665
1666 int roundstart=0;
1667 int colorstart=3;
1668 int variationstart=2;
1669 int colorcount=0;
1670 int dirstart=0;
1671 if(colorchoice == 4) colorcount=8;
1672 else if(colorchoice == 3) colorcount=7;
1673 else if (colorchoice == 2) colorcount=6;
1674 else if (colorchoice == 1) colorcount=5;
1675
1676 int upperlength = 0;
1677 int upperstart = 0;
1678
1679 if (roundchoice) {
1680 upperlength = 2;
1681 }
1682 if (colorchoice) {
1683 upperlength = upperlength + colorcount + ( upperlength? 1 : 0);
1684 }
1685 if (dirchoice != 0) {
1686 upperlength = upperlength + dirchoice + ( upperlength? 1 : 0);
1687 }
1688
1689 if (upperlength > 0) {
1690 upperstart = lastclickedx - upperlength/2;
1691 if (upperstart < 0) {
1692 upperstart = 0;
1693 }
1694 upperstart = min<int>(upperstart, EDITORBUTTONS_COUNTX - upperlength);
1695 }
1696
1697 if(roundchoice)
1698 {
1699 roundstart = upperstart;
1700 upperstart += 3;
1701 for (int i=0;i<2;i++)
1702 {
1703 singleobject &o=buttons[roundstart+i][0];
1704 o.content= CONTENT_MAKEROUND;
1705 o.round=(bool)(i);
1706 /*if ((bool)(i)== round)
1707 {
1708 o.selected=true;
1709 clickedround=&o;
1710 }*/
1711 }
1712 }
1713
1714 if ( colorchoice ) {
1715 colorstart = upperstart;
1716 upperstart += 1 + colorcount;
1717 for (int i=0;i<colorcount;i++)
1718 {
1719 singleobject &o=buttons[i+colorstart][0];
1720 o.content= CONTENT_RECOLOR;
1721 o.color=(editorcolor)(i);
1722 }
1723 }
1724
1725
1726 if (dirchoice) {
1727 dirstart = upperstart;
1728 upperstart += dirchoice + 1;
1729 for (int i=0; i<dirchoice; i++)
1730 {
1731 singleobject &o=buttons[dirstart+i][0];
1732 o.content= CONTENT_DIRECTION;
1733 o.direction=i;
1734
1735 }
1736
1737 }
1738
1739
1740
1741 if(maxvariations>0)
1742 {
1743 variationstart = lastclickedx - maxvariations/2;
1744 if (variationstart < 2) {
1745 variationstart = 2;
1746 }
1747
1748 // { variationstart + maxvariations-1 < EDITORBUTTONS_COUNTX }
1749 // { variationstart < EDITORBUTTONS_COUNTX - maxvariations + 1 }
1750
1751 variationstart = min<int>(variationstart, EDITORBUTTONS_COUNTX - maxvariations);
1752
1753 for (int i=0;i<maxvariations;i++)
1754 {
1755 singleobject &o=buttons[variationstart+i][2];
1756 o.content=CONTENT_VARIATION;
1757 o.variation=i;
1758 }
1759 }
1760
1761 }
1762
switchToObject(editorobjecttype ot,editorcolor color,bool round,int variation,int direction)1763 void editorbuttons::switchToObject( editorobjecttype ot, editorcolor color, bool round, int variation, int direction)
1764 {
1765 updateText(ot,color,round,variation, direction);
1766
1767 if(SelectedObjectType!=ot)
1768 {
1769 for (int i=0;i<EDITORBUTTONS_COUNTX;i++)
1770 {
1771 singleobject &o=buttons[i][0];
1772 o.content=CONTENT_NOCONTENT;
1773 o.selected=false;
1774
1775 if (i>=2) {
1776 singleobject &p=buttons[i][2];
1777 p.content=CONTENT_NOCONTENT;
1778 p.selected=false;
1779 }
1780 }
1781
1782 extendButtons(ot,color,round,variation);
1783 }
1784
1785
1786 SelectedColor = color;
1787 SelectedObjectType=ot;
1788 SelectedRound=round;
1789 SelectedVariation=variation;
1790 SelectedDirection = direction;
1791 }
1792
1793 /*** editorboard control **/
1794
makewall(boardelement & o)1795 void makewall(boardelement &o)
1796 {
1797 o.type=EDOT_WALL;
1798 o.variation=0;
1799 o.round=false;
1800 }
1801
1802 vector<editorboard> editorboard::levelList(1);
1803 int editorboard::currentLevel;
1804
assign(editorboard * other)1805 void editorboard::assign(editorboard* other)
1806 {
1807 for (int i=0; i<XYE_HORZ; i++) {
1808 for (int j=0; j<XYE_VERT; j++) {
1809 objects[i][j] = other->objects[i][j];
1810 }
1811 }
1812
1813 for (int i=0; i<TOTAL_EDITOR_COLOR_OPTIONS; i++) {
1814 colors[i] = other->colors[i];
1815 }
1816
1817 xye_x = other->xye_x;
1818 xye_y = other->xye_y;
1819 for (int i=0; i<XYE_OBJECT_COLORS+1; i++)
1820 for (int j=0; j<2; j++)
1821 {
1822 portal_x[i][j] = other->portal_x[i][j];
1823 portal_y[i][j] = other->portal_y[i][j];
1824 }
1825 title=other->title;
1826 hint=other->hint;
1827 bye=other->bye;
1828 solution=other->solution;
1829
1830 }
CreateLevel(editorboard * ed)1831 void editorboard::CreateLevel(editorboard* ed)
1832 {
1833
1834 SaveCopy(ed);
1835 int x = levelList.size();
1836 levelList.resize(++x);
1837 for (int i=x-1; i > currentLevel+1; i--) {
1838 levelList[i] = levelList[i-1];
1839 }
1840 LoadLevelNumber(ed, currentLevel+1);
1841 ed->objects[0][0].type = EDOT_NONE;
1842 ed->makeDefaultLevel();
1843
1844 }
MoveToLevelNumber(editorboard * ed,int x)1845 void editorboard::MoveToLevelNumber(editorboard* ed, int x)
1846 {
1847 int old = CurrentLevelNumber();
1848 if (old == x) {
1849 //nothing
1850 } else if (old > x) {
1851 //x -> x+1
1852 //x+1 -> x+2
1853 // ...
1854 // x+t -> old
1855 for (int y=old; y>x; y--) {
1856 levelList[y].assign(&levelList[y-1]);
1857 }
1858 levelList[x].assign(&levelList[old]);
1859 currentLevel = x;
1860
1861 } else if (old < x) {
1862 // old -> x
1863 // x -> x-1
1864 // x-1 -> x-2
1865 // ...
1866 // x-t -> old
1867 for (int y=old; y<x; y++) {
1868 levelList[y].assign(&levelList[y+1]);
1869 }
1870 levelList[x].assign(&levelList[old]);
1871 currentLevel = x;
1872 }
1873
1874
1875 }
1876
1877
DeleteLevel(editorboard * ed)1878 void editorboard::DeleteLevel(editorboard* ed)
1879 {
1880 int x = levelList.size();
1881 if (x > 1) {
1882 for (int i=currentLevel; i < x-1; i++) {
1883 levelList[i] = levelList[i+1];
1884 }
1885 levelList.resize(x-1);
1886 if (currentLevel >= levelList.size() ) {
1887 LoadLevelNumber(ed, levelList.size()-1);
1888 } else {
1889 LoadLevelNumber(ed, currentLevel);
1890 }
1891
1892 }
1893 }
1894
SaveAtLevelNumber(editorboard * ed,int num)1895 void editorboard::SaveAtLevelNumber(editorboard* ed, int num)
1896 {
1897 if( num >= levelList.size() ) {
1898 levelList.resize(num+1);
1899 }
1900 levelList[num].assign(ed);
1901 }
ResetLevels(bool empty)1902 void editorboard::ResetLevels(bool empty)
1903 {
1904 levelList.resize(0);
1905 if (empty) {
1906 currentLevel = -1;
1907 } else {
1908 levelList.resize(1);
1909 currentLevel = 0;
1910 filetitle = "Editor test";
1911 description = "Generated with Xyedit";
1912 author = "";
1913 }
1914 }
1915
1916
CountLevels()1917 int editorboard::CountLevels()
1918 {
1919 return levelList.size();
1920 }
CurrentLevelNumber()1921 int editorboard::CurrentLevelNumber()
1922 {
1923 return currentLevel;
1924 }
1925
LoadLevelNumber(editorboard * ed,int num)1926 void editorboard::LoadLevelNumber(editorboard* ed, int num)
1927 {
1928 if( num >= levelList.size() ) {
1929 if ( levelList.size() == 0 ) {
1930 num = 0;
1931 levelList.resize(1);
1932 } else {
1933 num = levelList.size() - 1;
1934 }
1935 } else {
1936 ed->assign(&levelList[num] );
1937 }
1938 currentLevel = num;
1939 }
1940
SaveCopy(editorboard * ed)1941 void editorboard::SaveCopy(editorboard* ed)
1942 {
1943 assert(currentLevel < levelList.size());
1944 levelList[currentLevel].assign(ed);
1945 }
SetCopySolution(const char * sol)1946 void editorboard::SetCopySolution(const char* sol)
1947 {
1948 assert(currentLevel < levelList.size());
1949 levelList[currentLevel].solution=sol;
1950 }
LoadCopy(editorboard * ed)1951 void editorboard::LoadCopy(editorboard* ed)
1952 {
1953 assert(currentLevel < levelList.size());
1954 ed->assign(&levelList[currentLevel]);
1955 }
1956
makeDefaultLevel()1957 void editorboard::makeDefaultLevel()
1958 {
1959 int i,j;
1960 for (i=0; i<TOTAL_EDITOR_COLOR_OPTIONS; i++) {
1961 colors[i].useDefault = true;
1962 }
1963 bool already = true;
1964 for (i=0;i<XYE_HORZ;i++)for (j=0;j<XYE_VERT;j++)
1965 {
1966 if (objects[i][j].type != EDOT_NONE)
1967 {
1968 if(objects[i][j].type==EDOT_WALL)
1969 {
1970 already = already && ( (i==0) || (j==0) || (i==XYE_HORZ-1) || (j==XYE_VERT-1));
1971 }
1972 else already = false;
1973 }
1974 else if( (i==0) || (j==0) || (i==XYE_HORZ-1) || (j==XYE_VERT-1))
1975 already=false;
1976
1977 objects[i][j].type=EDOT_NONE;
1978 }
1979 if( ! already)
1980 {
1981 //fill border walls
1982 for (j=0;j<XYE_VERT;j++)
1983 {
1984 makewall(objects[0][j]);
1985 makewall(objects[XYE_HORZ-1][j]);
1986 }
1987 for (j=0;j<XYE_HORZ;j++)
1988 {
1989 makewall(objects[j][0]);
1990 makewall(objects[j][XYE_VERT-1]);
1991 }
1992 }
1993 xye_x=-1;
1994 xye_y=-1;
1995 for (int i=0; i<XYE_OBJECT_COLORS+1; i++)
1996 for (int j=0; j<2; j++)
1997 portal_x[i][j]= portal_y[i][j]=-1;
1998 }
1999
editorboard(int sx,int sy)2000 editorboard::editorboard(int sx, int sy)
2001 {
2002 title=editor::filename_name;
2003 hint=solution="";
2004 bye ="";
2005
2006 depth=0;
2007 x=sx;y=sy;
2008 w=sz*XYE_HORZ;
2009 h=sz*XYE_VERT;
2010 mousex=mousey=0;
2011 clicked=mouse=false;
2012
2013 makeDefaultLevel();
2014 }
2015
2016
editorboard()2017 editorboard::editorboard()
2018 {
2019 editorboard(0,0);
2020 }
2021
onMouseMove(int px,int py)2022 void editorboard::onMouseMove(int px,int py)
2023 {
2024 if(clicked)
2025 {
2026 int bi=px/sz,bj=py/sz;
2027 //solution = "";
2028 applyFromButtons(bi,bj);
2029
2030 }
2031 mousex=px;
2032 mousey=py;
2033 mouse=true;
2034 }
2035
onMouseOut()2036 void editorboard::onMouseOut()
2037 {
2038 mouse=false;
2039 clicked=false;
2040 }
2041
onMouseDown(int px,int py)2042 void editorboard::onMouseDown(int px,int py)
2043 {
2044 int bi=px/sz,bj=py/sz;
2045 //solution = "";
2046 applyFromButtons(bi,bj);
2047 clicked=true;
2048 }
2049
onMouseUp(int px,int py)2050 void editorboard::onMouseUp(int px,int py)
2051 {
2052 clicked=false;
2053 if ( editor::buttons->SelectedObjectType == EDOT_HINT ) {
2054 int x = px/sz, y = py/sz;
2055 if ( (x<0) || (y<0) || (x>=XYE_HORZ) || (y>=XYE_VERT) ) {
2056 return ;
2057 }
2058
2059
2060 editor::SavedFile=false;
2061 boardelement &o=objects[x][y];
2062 o.type = EDOT_HINT;
2063
2064 if (editor::buttons->SelectedObjectType == EDOT_HINT) {
2065 editor::askHint(&o);
2066 }
2067
2068 }
2069
2070 }
2071
2072
onMouseRightUp(int px,int py)2073 void editorboard::onMouseRightUp(int px,int py)
2074 {
2075 int bi=px/sz,bj=py/sz;
2076
2077
2078 bool er=editor::buttons->Eraser;
2079 editor::buttons->Eraser=true;
2080 applyFromButtons(bi,bj);
2081 editor::buttons->Eraser=er;
2082
2083 }
2084
wallContainsRoundCorners(int x,int y)2085 bool editorboard::wallContainsRoundCorners(int x, int y)
2086 {
2087 return ( objects[x][y].r1mem || objects[x][y].r3mem || objects[x][y].r9mem || objects[x][y].r7mem);
2088 }
2089
2090
findWall(int x,int y,int variation)2091 bool editorboard::findWall(int x, int y, int variation)
2092 {
2093 return (( objects[x][y].type == EDOT_WALL) && (objects[x][y].variation == variation));
2094 }
2095
updateWallMem(int ox,int oy)2096 void editorboard::updateWallMem(int ox, int oy)
2097 {
2098 boardelement &o=objects[ox][oy];
2099 bool r7,r9,r1,r3;
2100 r7=r9=r1=r3=o.round;
2101
2102 if( (ox>0) && (objects[ox-1][oy].type==EDOT_WALL) ) r7=r1=false;
2103 if( (ox<XYE_HORZ-1) && (objects[ox+1][oy].type==EDOT_WALL) ) r9=r3=false;
2104
2105 if( (oy>0) && (objects[ox][oy-1].type==EDOT_WALL) ) r9=r7=false;
2106 if( (oy<XYE_VERT-1) && (objects[ox][oy+1].type==EDOT_WALL) ) r1=r3=false;
2107
2108
2109 o.r1mem=(Uint8)(r1);
2110 o.r7mem=(Uint8)(r7);
2111 o.r9mem=(Uint8)(r9);
2112 o.r3mem=(Uint8)(r3);
2113
2114 }
2115
editorWallColors(Drawer & D,int variation)2116 void editorWallColors(Drawer &D, int variation)
2117 {
2118 DefaultColorData & cd = editor::board->colors[EDITOR_COLOR_WALLS];
2119 if (! cd.useDefault ) {
2120 D.SetColors( &cd.color, 255);
2121 } else {
2122 D.SetColors( &options::WallColor[variation], 255);
2123 }
2124
2125 }
2126
drawWallInBoard(SDL_Surface * target,int ox,int oy,int x,int y,int variation,bool round)2127 void editorboard::drawWallInBoard(SDL_Surface*target,int ox,int oy, int x, int y, int variation, bool round)
2128 {
2129 updateWallMem(ox,oy);
2130 bool r7,r9,r1,r3;
2131 boardelement &o=objects[ox][oy];
2132 r1 = o.r1mem;
2133 r7 = o.r7mem;
2134 r9 = o.r9mem;
2135 r3 = o.r3mem;
2136
2137 Drawer D(editor::sprites,0,0,0,0);
2138 editorWallColors(D, variation);
2139 Sint16 sz2=sz/2;
2140 Sint16 ty;
2141 ty=sz*(variation);
2142
2143 //D.SetColors(R,G,B,255);
2144
2145 char px=ox, py=oy;
2146 char rx=px+1, lx=px-1, dy=py+1, uy=py-1;
2147 if(rx>=XYE_HORZ) rx=0;
2148 if(dy>=XYE_VERT) dy=0;
2149 if(lx<0) lx=XYE_HORZ-1;
2150 if(uy<0) uy=XYE_VERT-1;
2151
2152 bool up = findWall( px, uy, variation);
2153 bool down = findWall( px, dy, variation);
2154 bool left = findWall( lx, py, variation);
2155 bool right = findWall( rx, py, variation);
2156
2157 bool upright = findWall( rx, uy, variation);
2158 bool downright =findWall( rx, dy, variation);
2159 bool upleft = findWall( lx, uy, variation);
2160 bool downleft = findWall( lx, dy, variation);
2161
2162
2163
2164 up = up && !r7 && !r9;
2165 down = down && !r1 && !r3;
2166 right = right && !r9 && !r3;
2167 left = left && !r7 && !r1;
2168
2169 bool inborder = (!left||!up||!right||!down);
2170 if( !inborder && (!upright || !upleft || !downright ||!downleft) )
2171 {
2172 /*inborder = !( wallContainsRoundCorners(px,uy)
2173 || wallContainsRoundCorners(px,dy)
2174 || wallContainsRoundCorners(lx, py)
2175 || wallContainsRoundCorners(rx, py) );*/
2176 inborder = true;
2177
2178 }
2179
2180
2181 if (r7)
2182 D.ChangeRect(10*sz,ty,sz2,sz2);
2183 else if( up && left && !inborder)
2184 D.ChangeRect(15*sz,ty,sz2,sz2);
2185 else if(up&&left&&upleft)
2186 D.ChangeRect(14*sz,ty,sz2,sz2);
2187 else if(up&&left)
2188 D.ChangeRect(13*sz,ty,sz2,sz2);
2189 else if ( up)
2190 D.ChangeRect(12*sz,ty,sz2,sz2);
2191 else if ( left)
2192 D.ChangeRect(11*sz,ty,sz2,sz2);
2193 else
2194 D.ChangeRect(9*sz,ty,sz2,sz2);
2195
2196
2197 D.Draw(target,x,y);
2198
2199 if (r9)
2200 D.ChangeRect(21*sz2,ty,sz2,sz2);
2201 else if( up && right && !inborder)
2202 D.ChangeRect(15*sz+sz2,ty,sz2,sz2);
2203 else if(up&&right&&upright)
2204 D.ChangeRect(14*sz+sz2,ty,sz2,sz2);
2205 else if(up&&right)
2206 D.ChangeRect(13*sz+sz2,ty,sz2,sz2);
2207 else if ( up)
2208 D.ChangeRect(12*sz+sz2,ty,sz2,sz2);
2209 else if ( right)
2210 D.ChangeRect(11*sz+sz2,ty,sz2,sz2);
2211 else
2212 D.ChangeRect(19*sz2,ty,sz2,sz2);
2213
2214 //D.SetColors(255,255,255,50);
2215 D.Draw(target,x+sz2,y);
2216 //D.SetColors(255,255,255,255);
2217
2218 if (r1)
2219 D.ChangeRect(10*sz,ty+sz2,sz2,sz2);
2220 else if( down && left && !inborder)
2221 D.ChangeRect(15*sz,ty+sz2,sz2,sz2);
2222 else if(down&&left&&downleft)
2223 D.ChangeRect(14*sz,ty+sz2,sz2,sz2);
2224 else if(down&&left)
2225 D.ChangeRect(13*sz,ty+sz2,sz2,sz2);
2226 else if ( down)
2227 D.ChangeRect(12*sz,ty+sz2,sz2,sz2);
2228 else if ( left)
2229 D.ChangeRect(11*sz,ty+sz2,sz2,sz2);
2230 else
2231 D.ChangeRect(9*sz,ty+sz2,sz2,sz2);
2232
2233
2234
2235 D.Draw(target,x,y+sz2);
2236
2237 if (r3)
2238 D.ChangeRect(21*sz2,ty+sz2,sz2,sz2);
2239 else if( down && right && !inborder)
2240 D.ChangeRect(15*sz+sz2,ty+sz2,sz2,sz2);
2241 else if(down&&right&&downright)
2242 D.ChangeRect(14*sz+sz2,ty+sz2,sz2,sz2);
2243 else if(down&&right)
2244 D.ChangeRect(13*sz+sz2,ty+sz2,sz2,sz2);
2245 else if ( down)
2246 D.ChangeRect(12*sz+sz2,ty+sz2,sz2,sz2);
2247 else if ( right)
2248 D.ChangeRect(11*sz+sz2,ty+sz2,sz2,sz2);
2249 else
2250 D.ChangeRect(19*sz2,ty+sz2,sz2,sz2);
2251
2252 D.Draw(target,x+sz2,y+sz2);
2253
2254 }
2255
drawTeleportInBoard(SDL_Surface * target,int ox,int oy,int x,int y,int direction)2256 void editorboard::drawTeleportInBoard(SDL_Surface*target,int ox,int oy, int x, int y, int direction)
2257 {
2258 Uint8 variation = 0;
2259 switch(direction) {
2260 case EDITORDIRECTION_LEFT: case EDITORDIRECTION_RIGHT:
2261 for (int i=0; i < XYE_HORZ; i++) if (i != ox) {
2262 boardelement & o = objects[i][oy];
2263 if ( (o.type == EDOT_TELEPORT) && (o.direction != direction )
2264 && ( o.direction == EDITORDIRECTION_RIGHT || o.direction == EDITORDIRECTION_LEFT)
2265 ) {
2266 variation = 1;
2267 break;
2268 }
2269 }
2270 break;
2271 case EDITORDIRECTION_UP: case EDITORDIRECTION_DOWN:
2272 for (int j=0; j < XYE_VERT; j++) if (j != oy) {
2273 boardelement & o = objects[ox][j];
2274 if ( (o.type == EDOT_TELEPORT) && (o.direction != direction )
2275 && ( o.direction == EDITORDIRECTION_UP || o.direction == EDITORDIRECTION_DOWN)
2276 ) {
2277 variation = 1;
2278 break;
2279 }
2280 }
2281 break;
2282 }
2283
2284
2285 Uint8 tx,ty;
2286 switch(direction) {
2287 case EDITORDIRECTION_RIGHT: tx=4;break;
2288 case EDITORDIRECTION_DOWN: tx=5; break;
2289 case EDITORDIRECTION_LEFT: tx=6; break;
2290 default: /*up*/ tx=7;
2291 }
2292 ty = (variation? 1: 2);
2293 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2294 D.Draw(target,x,y);
2295 }
2296
2297
draw(SDL_Surface * target)2298 void editorboard::draw(SDL_Surface* target)
2299 {
2300 int i,j;
2301 DefaultColorData &cd = colors[EDITOR_COLOR_FLOOR];
2302 if (cd.useDefault) {
2303 SDL_FillRect(target,x,y,w,h,SDL_MapRGB(target->format,options::FloorColor));
2304 } else {
2305 SDL_FillRect(target,x,y,w,h,SDL_MapRGB(target->format,cd.color));
2306 }
2307 for (i=0;i<XYE_HORZ;i++) for (j=0;j<XYE_VERT;j++) {
2308 boardelement &o=objects[i][j];
2309 if(o.type!=EDOT_NONE) {
2310 if ( o.type==EDOT_WALL) {
2311 drawWallInBoard(target,i,j,x+i*sz,y+j*sz,o.variation, o.round);
2312 } else if ( o.type == EDOT_LARGEBLOCK ) {
2313 drawLargeBlockInBoard(target,i,j,x+i*sz,y+j*sz,o.color, o.variation, o.direction);
2314 } else if ( o.type == EDOT_TELEPORT) {
2315 drawTeleportInBoard(target, i, j, x+i*sz, y+j*sz, o.direction);
2316 } else {
2317 drawObjectBySpecs(target,x+i*sz,y+j*sz, o.type, o.color, o.round, o.variation, o.direction);
2318 }
2319 }
2320 }
2321 }
2322
enforceUniquePortals(int x,int y,int variation,editorcolor color)2323 void editorboard::enforceUniquePortals(int x, int y, int variation, editorcolor color)
2324 {
2325 int cid = (int)(color);
2326 int use = 0;
2327
2328 if(variation > 0 ) use = 1;
2329
2330
2331 int tx= portal_x[cid][use], ty=portal_y[cid][use];
2332 if(tx!=-1)
2333 {
2334 objects[tx][ty].type=EDOT_NONE;
2335 }
2336 portal_x[cid][use]=x;
2337 portal_y[cid][use]=y;
2338
2339
2340
2341 }
2342
applyFromButtons(int x,int y)2343 void editorboard::applyFromButtons(int x, int y)
2344 {
2345 if((x<0) || (y<0) || (x>=XYE_HORZ) || (y>=XYE_VERT)) return ;
2346
2347
2348 editor::SavedFile=false;
2349 boardelement &o=objects[x][y];
2350 if((x==xye_x) && (y==xye_y))
2351 {
2352 xye_x=-1;
2353 xye_y=-1;
2354 }
2355 for (int i=0; i<XYE_OBJECT_COLORS+1; i++)
2356 for (int j=0; j<2; j++)
2357 if((x==portal_x[i][j]) && (y==portal_y[i][j]))
2358 {
2359 portal_x[i][j] = portal_y[i][j] = -1;
2360 }
2361
2362
2363
2364 if (editor::buttons->Eraser)
2365 {
2366 o.type=EDOT_NONE;
2367 return;
2368 }
2369
2370 switch(editor::buttons->SelectedObjectType)
2371 {
2372 case EDOT_XYE:
2373 if(xye_x!=-1) objects[xye_x][xye_y].type=EDOT_NONE;
2374 xye_x=x;
2375 xye_y=y;
2376 break;
2377 case EDOT_PORTAL:
2378 enforceUniquePortals(x,y, editor::buttons->SelectedVariation, editor::buttons->SelectedColor);
2379 break;
2380 }
2381 //Hints are a special case, because we only want the input dialog to appear once.
2382 if (editor::buttons->SelectedObjectType == EDOT_HINT) {
2383 return;
2384 }
2385 o.type=editor::buttons->SelectedObjectType;
2386 o.color=editor::buttons->SelectedColor;
2387 o.variation=editor::buttons->SelectedVariation;
2388 o.round=editor::buttons->SelectedRound;
2389 o.direction=editor::buttons->SelectedDirection;
2390 o.parentx = o.parenty = -1;
2391 }
2392
2393 /****** object drawing, Very painful ****/
2394
drawXye(SDL_Surface * target,int x,int y,int variation)2395 void drawXye( SDL_Surface * target, int x, int y, int variation)
2396 {
2397 Drawer D(editor::sprites,0,0,sz,sz);
2398 D.SetColors( &game::PlayerColor);
2399 D.Draw(target,x,y);
2400 if(variation)
2401 {
2402 char vartext[3];
2403 vartext[0]='+';
2404 vartext[1]=(char)variation+'0';
2405 vartext[2]='\0';
2406 editor::FontRes->Write(target,x,y,vartext);
2407 }
2408 }
2409
2410
drawRattlerHead(SDL_Surface * target,int x,int y,int variation,int direction)2411 void drawRattlerHead( SDL_Surface * target, int x, int y, int variation, int direction)
2412 {
2413 Uint8 tx,ty;
2414
2415
2416 switch(direction)
2417 {
2418 case EDITORDIRECTION_LEFT: tx=12,ty=10; break;
2419 case EDITORDIRECTION_UP: tx=13,ty=10; break;
2420 case EDITORDIRECTION_RIGHT: tx=14,ty=10; break;
2421 case EDITORDIRECTION_DOWN: tx=15,ty=10; break;
2422 }
2423 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2424
2425 if(variation)
2426 {
2427 D.SetColors(255,255,255,70);
2428 }
2429 D.Draw(target,x,y);
2430
2431 if(variation)
2432 {
2433 char vartext[3];
2434 vartext[0]='+';
2435 vartext[1]=(char)variation+'0';
2436 vartext[2]='\0';
2437 editor::FontRes->Write(target,x,y,vartext);
2438 }
2439 }
2440
2441
2442
drawGem(SDL_Surface * target,int x,int y,editorcolor color)2443 void drawGem( SDL_Surface * target, int x, int y, editorcolor color)
2444 {
2445 Uint8 tx,ty;
2446 ty=3;
2447 switch(color)
2448 {
2449 case(EDCO_BLUE): tx=2; break;
2450 case(EDCO_RED): tx=3; break;
2451 case(EDCO_GREEN): tx=4; break;
2452 case(EDCO_YELLOW): tx=5; break;
2453 default:
2454 ty = 13, tx=9;
2455 }
2456 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2457
2458 D.Draw(target,x,y);
2459 }
drawWall(SDL_Surface * target,int x,int y,bool round,int variation)2460 void drawWall( SDL_Surface * target, int x, int y, bool round, int variation)
2461 {
2462 Uint8 tx,ty;
2463 ty=variation;
2464 if(round) tx=10;
2465 else tx=9;
2466 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2467 editorWallColors(D, variation);
2468 D.Draw(target,x,y);
2469 }
2470
drawBlock(SDL_Surface * target,int x,int y,bool round,editorcolor color)2471 void drawBlock( SDL_Surface * target, int x, int y, bool round, editorcolor color)
2472 {
2473 Uint8 tx,ty=0;
2474 if(round) tx=2;
2475 else tx=1;
2476 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2477 if( color==EDCO_WILD)
2478 {
2479 ty = 2, tx = 1+round;
2480 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2481 }
2482 else if(color==EDCO_METAL)
2483 {
2484 ty = 8, tx = 9+round;
2485 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2486 }
2487 else if(color!=EDCO_WHITE)
2488 {
2489 D.SetColors(&options::BKColor[color],255);
2490 } else {
2491 D.SetColors(&options::BKColor[5],255);
2492 }
2493 D.Draw(target,x,y);
2494 }
2495
drawPortal(SDL_Surface * target,int x,int y,editorcolor color,int variation)2496 void drawPortal( SDL_Surface * target, int x, int y, editorcolor color, int variation)
2497 {
2498 Uint8 tx=8,ty=0;
2499 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2500
2501 Uint8 alpha = 255;
2502 if(variation>0) alpha = 200;
2503 if(color!=EDCO_WHITE) {
2504 D.SetColors(&options::BKColor[color],alpha);
2505 } else if(alpha!=255) {
2506 D.SetColors(255,255,255,alpha);
2507 }
2508 D.Draw(target,x,y);
2509 if(variation==2)
2510 {
2511 tx=4, ty=10;
2512 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2513 alpha = 62;
2514 D.SetColors(0,0,0,alpha);
2515 D.Draw(target,x,y);
2516 }
2517 }
2518
drawMetalBlock(SDL_Surface * target,int x,int y,bool round)2519 void drawMetalBlock( SDL_Surface * target, int x, int y, bool round)
2520 {
2521 Uint8 tx,ty=8;
2522 if(round) tx=10;
2523 else tx=9;
2524 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2525 D.Draw(target,x,y);
2526 }
2527
drawGemBlock(SDL_Surface * target,int x,int y,editorcolor color)2528 void drawGemBlock( SDL_Surface * target, int x, int y, editorcolor color)
2529 {
2530 Uint8 tx=6,ty=9;
2531 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2532
2533 D.SetColors(&options::BKColor[color],255);
2534 D.Draw(target,x,y);
2535
2536 tx=8;
2537 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2538 D.SetColors(&options::BFColor[color],255);
2539 D.Draw(target,x,y);
2540 }
2541
drawColorSystem(SDL_Surface * target,int x,int y,editorcolor color,int variation)2542 void drawColorSystem( SDL_Surface * target, int x, int y, editorcolor color, int variation)
2543 {
2544 Uint8 tx,ty;
2545
2546 switch (variation)
2547 {
2548 case 0: /*closed door*/ tx=7,ty=5; break;
2549 case 1: /*open door*/ tx=7,ty=7; break;
2550 case 2: /*closed trap*/ tx=8,ty=5; break;
2551 case 3: /*open trap*/ tx=8,ty=7; break;
2552 case 4: /*marked*/ tx=6,ty=5; break;
2553 case 5: /*window*/ tx=9,ty=7; break;
2554 case 6:
2555 drawBlock(target,x,y,false,color);
2556 tx=6,ty=5;
2557 break;
2558 case 7:
2559 drawBlock(target,x,y,false,EDCO_WILD);
2560 tx=6,ty=5;
2561 break;
2562 }
2563
2564 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2565
2566 D.SetColors(&options::BKColor[color],255);
2567 D.Draw(target,x,y);
2568
2569 }
2570
2571
2572
drawKeySystem(SDL_Surface * target,int x,int y,editorcolor color,int variation)2573 void drawKeySystem( SDL_Surface * target, int x, int y, editorcolor color, int variation)
2574 {
2575 Uint8 tx,ty;
2576
2577 switch (variation)
2578 {
2579 case 0: /*key*/ tx=6,ty=4; break;
2580 case 1: /*lock*/ tx=7,ty=4; break;
2581
2582 }
2583
2584 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2585
2586 D.SetColors(&options::BKColor[color],255);
2587 D.Draw(target,x,y);
2588
2589 }
2590
2591
2592
drawEarth(SDL_Surface * target,int x,int y,bool round)2593 void drawEarth( SDL_Surface * target, int x, int y, bool round)
2594 {
2595 Uint8 tx,ty=1;
2596 if(round) tx=2;
2597 else tx=1;
2598 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2599 DefaultColorData & cd = editor::board->colors[EDITOR_COLOR_EARTH];
2600 if (! cd.useDefault ) {
2601 D.SetColors( &cd.color, 255);
2602 } else {
2603 D.SetColors( &options::EarthColor, 255);
2604 }
2605 D.Draw(target,x,y);
2606 }
2607
2608
2609
drawNumber(SDL_Surface * target,int x,int y,editorcolor color,bool round,int variation)2610 void drawNumber( SDL_Surface * target, int x, int y, editorcolor color, bool round, int variation)
2611 {
2612 //drawBlock(target,x,y,round,color);
2613
2614
2615 Uint8 tx,ty;
2616 tx = 16+round;
2617 ty = 6 + variation;
2618 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2619 D.SetColors(&options::BKColor[color],255);
2620 D.Draw(target,x,y);
2621 tx = 18;
2622 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2623 D.SetColors(&options::BFColor[color],255);
2624 D.Draw(target,x,y);
2625 }
2626
2627
drawSpecialBlocks(SDL_Surface * target,int x,int y,bool round,editorcolor color,int variation,int direction)2628 void drawSpecialBlocks( SDL_Surface * target, int x, int y, bool round, editorcolor color, int variation, int direction)
2629 {
2630 drawBlock(target,x,y,round,color);
2631
2632
2633 Uint8 tx,ty;
2634 if (variation==0)
2635 {
2636 switch(direction)
2637 {
2638 case(EDITORDIRECTION_RIGHT): tx=4; ty=9; break;
2639 case(EDITORDIRECTION_LEFT): tx=5; ty=9; break;
2640 case(EDITORDIRECTION_UP): tx=5; ty=10; break;
2641 default: tx=4; ty=10;
2642 }
2643 }
2644 else if (variation==1)
2645 {
2646 switch(direction)
2647 {
2648 case(EDITORDIRECTION_RIGHT): tx=4; ty=16; break;
2649 case(EDITORDIRECTION_LEFT): tx=5; ty=16; break;
2650 case(EDITORDIRECTION_UP): tx=5; ty=17; break;
2651 default: tx=4; ty=17;
2652 }
2653
2654 }
2655 else if(variation==2) tx=3,ty=8;
2656 else if (variation==3) tx=3,ty=9;
2657 else if (variation==4) tx=3,ty=12;
2658 else tx=3,ty=7;
2659
2660 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2661
2662 D.SetColors(&options::BFColor[color],255);
2663 D.Draw(target,x,y);
2664 }
2665
drawTurner(SDL_Surface * target,int x,int y,bool round,editorcolor color,int variation)2666 void drawTurner( SDL_Surface * target, int x, int y, bool round, editorcolor color, int variation)
2667 {
2668 drawBlock(target,x,y,round,color);
2669
2670
2671 Uint8 tx=3,ty;
2672 if(variation) ty=10;
2673 else ty=11;
2674
2675 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2676
2677 if(color!=EDCO_WHITE) {
2678 D.SetColors(&options::BFColor[color],255);
2679 } else {
2680 D.SetColors(&options::BFColor[5],255);
2681 }
2682 D.Draw(target,x,y);
2683 }
2684
2685 /*
2686 * 0 | 1 | 2
2687 * 7 - - 3
2688 * 6 | 5 | 4
2689 *
2690 * */
drawLargeBlockByFlags(SDL_Surface * target,int x,int y,editorcolor color,Uint8 flags,bool doalpha=false)2691 void drawLargeBlockByFlags( SDL_Surface * target, int x, int y, editorcolor color, Uint8 flags, bool doalpha=false)
2692 {
2693 Uint8 tx,ty;
2694 Uint8 sz2 = sz>>1;
2695
2696 //flags = 0b1101;
2697
2698
2699 Uint8 up = (flags>>1)&1;
2700 Uint8 right = (flags>>3)&1;
2701 Uint8 down = (flags>>5)&1;
2702 Uint8 left = (flags>>7)&1;
2703
2704 Uint8 upleft = (flags>>0)&1;
2705 Uint8 upright = (flags>>2)&1;
2706 Uint8 downright = (flags>>4)&1;
2707 Uint8 downleft = (flags>>6)&1;
2708
2709 //top left corner:
2710 Uint8 var = 0;
2711 if( up&&left&&upleft) var=4;
2712 else if( up&&left) var = 3;
2713 else if(up) var = 2;
2714 else if(left) var = 1;
2715
2716 tx = 10;
2717 ty = var + 15;
2718 Drawer D(editor::sprites, tx*sz, ty*sz,sz2,sz2);
2719 Uint8 alpha = 255;
2720 if( doalpha) alpha = 128;
2721
2722
2723
2724 if(color!=EDCO_WHITE) {
2725 D.SetColors(&options::BKColor[color],alpha);
2726 } else {
2727 Uint8 r = options::BKColor[5].r;
2728 Uint8 g = options::BKColor[5].g;
2729 Uint8 b = options::BKColor[5].b;
2730 if(editor::buttons->SelectedObjectType == EDOT_LARGEBLOCK) {
2731 r *= 0.86;
2732 g *= 0.86;
2733 b *= 0.86;
2734 }
2735 D.SetColors(r,g,b,alpha);
2736 }
2737 D.Draw(target,x,y);
2738
2739 //top right corner:
2740 var = 0;
2741 if( up&&right&&upright) var=4;
2742 else if( up&&right) var = 3;
2743 else if(up) var = 2;
2744 else if(right) var = 1;
2745
2746 tx = 10;
2747 ty = var + 15;
2748 D.ChangeRect(tx*sz+sz2, ty*sz, sz2,sz2);
2749 D.Draw(target,x+sz2,y);
2750
2751 //bottom left corner:
2752 var = 0;
2753 if( down&&left&&downleft) var=4;
2754 else if( down&&left) var = 3;
2755 else if(down) var = 2;
2756 else if(left) var = 1;
2757
2758 tx = 10;
2759 ty = var + 15;
2760 D.ChangeRect(tx*sz, ty*sz + sz2,sz2,sz2);
2761 D.Draw(target,x,y+sz2);
2762
2763 //bottom right corner:
2764 var = 0;
2765 if( down&&right&& downright) var=4;
2766 else if( down&&right) var = 3;
2767 else if(down) var = 2;
2768 else if(right) var = 1;
2769
2770 tx = 10;
2771 ty = var + 15;
2772 D.ChangeRect(tx*sz+sz2, ty*sz +sz2, sz2,sz2);
2773 D.Draw(target,x+sz2,y+sz2);
2774
2775 }
2776
getLargeBlockFlagsByVarDir(int variation,int direction)2777 Uint8 getLargeBlockFlagsByVarDir( int variation, int direction)
2778 {
2779 /* |0|
2780 * - -
2781 * 3 1
2782 * -|2| */
2783 Uint8 flags = 0;
2784
2785 switch(variation)
2786 {
2787 case 0: flags = /*0b0001*/ 1; break;
2788 case 1: flags = /*0b0011*/ 3; break;
2789 case 2: flags = /*0b0101*/ 5; break;
2790 case 3: flags = /*0b1011*/11; break;
2791 case 4: flags = /*0b1111*/15; break;
2792 }
2793 switch(direction)
2794 {
2795 case EDITORDIRECTION_DOWN: //bit 0 to 2
2796 flags = ( ((flags<<2)&/*0b1111*/15) | (flags>>2) );
2797 break;
2798 case EDITORDIRECTION_UP: //bit 0 to 0
2799 break;
2800 case EDITORDIRECTION_LEFT: //bit 0 to 3
2801 flags = ( ((flags<<3)&/*0b1111*/15) | (flags>>1) );
2802 break;
2803 case EDITORDIRECTION_RIGHT: //bit 0 to 1
2804 flags = ( ((flags<<1)&/*0b1111*/15) | (flags>>3) );
2805 break;
2806 }
2807 Uint8 up = flags&1;
2808 Uint8 right = (flags>>1)&1;
2809 Uint8 down = (flags>>2)&1;
2810 Uint8 left = (flags>>3)&1;
2811 Uint8 nflags = (up<<1)|(right<<3)|(down<<5)|(left<<7);
2812 return nflags;
2813 }
2814
drawLargeBlock(SDL_Surface * target,int x,int y,editorcolor color,int variation,int direction)2815 void drawLargeBlock( SDL_Surface * target, int x, int y, editorcolor color, int variation, int direction)
2816 {
2817 Uint8 nflags = getLargeBlockFlagsByVarDir(variation, direction);
2818 drawLargeBlockByFlags( target, x,y, color, nflags);
2819 }
2820
2821 Uint8 largeBlockDFS[XYE_HORZ][XYE_VERT] = {};
2822
dfsLargeBlocks(int x,int y,editorcolor color,int px,int py,editorboard * eb)2823 void dfsLargeBlocks(int x, int y, editorcolor color, int px, int py, editorboard* eb)
2824 {
2825
2826 if(largeBlockDFS[x][y] != editor::tic4)
2827 {
2828
2829 largeBlockDFS[x][y] = editor::tic4;
2830 boardelement &o=eb->objects[x][y];
2831 Uint8 nflags = getLargeBlockFlagsByVarDir(o.variation, o.direction);
2832
2833
2834 o.parentx = px,
2835 o.parenty = py;
2836 int dx[4] = { 0, 1, 0, -1};
2837 int dy[4] = { -1, 0, 1, 0};
2838 int df[4] = { 1, 3, 5, 7};
2839 int dop[4] = { 5, 7, 1, 3};
2840 for (int r=0; r<4; r++)
2841 {
2842 int nx = dx[r]+x, ny = dy[r]+y;
2843 if(nx<0) nx = XYE_HORZ-1;
2844 if(ny<0) ny = XYE_VERT-1;
2845 if(ny>=XYE_VERT) ny = 0;
2846 if(nx>=XYE_HORZ) nx = 0;
2847
2848 boardelement &o2 = eb->objects[nx][ny];
2849 Uint8 nflags2 = getLargeBlockFlagsByVarDir(o2.variation, o2.direction);
2850
2851 if( ((nflags &( 1<<df[r]) ) && (nflags2 &( 1<<dop[r]) ) ) && (o2.type==EDOT_LARGEBLOCK ) && (o2.color==color ) )
2852 {
2853 dfsLargeBlocks(nx,ny, color,px,py, eb);
2854 }
2855 }
2856
2857 }
2858 }
2859
drawLargeBlockInBoard(SDL_Surface * target,int ox,int oy,int x,int y,editorcolor color,int variation,int direction)2860 void editorboard::drawLargeBlockInBoard(SDL_Surface * target, int ox,int oy, int x, int y, editorcolor color, int variation, int direction)
2861 {
2862 Uint8 flags = getLargeBlockFlagsByVarDir(variation, direction);
2863 Uint8 nflags = 0;
2864 {
2865 dfsLargeBlocks(ox,oy, color, ox,oy, this);
2866 boardelement &o = objects[ox][oy];
2867 int dy[8] = {-1,-1,-1, 0, 1,1, 1, 0};
2868 int dx[8] = {-1, 0, 1, 1, 1, 0,-1, -1};
2869 for (int r=0; r<8; r++)
2870 {
2871 int nx = dx[r]+ox, ny = dy[r]+oy;
2872 if(nx<0) nx = XYE_HORZ-1;
2873 if(ny<0) ny = XYE_VERT-1;
2874 if(ny>=XYE_VERT) ny = 0;
2875 if(nx>=XYE_HORZ) nx = 0;
2876 boardelement &o2 = objects[nx][ny];
2877 if( (o2.type==EDOT_LARGEBLOCK) && (o2.parentx == o.parentx) && (o.parenty==o2.parenty)) {
2878 nflags|=(1<<r);
2879 }
2880 }
2881
2882 }
2883 bool doalpha = false;
2884 if( /*( editor::tic4 > 1) &&*/ ( editor::buttons->SelectedObjectType == EDOT_LARGEBLOCK) )
2885 {
2886
2887 if ( flags != (nflags-(nflags&/*0b01010101*/85) ) )
2888 {
2889 doalpha = true;
2890 if(editor::tic4<2)
2891 {
2892 drawLargeBlockByFlags( target, x,y, color, nflags , doalpha);
2893 return;
2894 }
2895
2896 // nflags |= flags;
2897 }
2898 nflags = flags|(nflags&/*0b01010101*/85);
2899 }
2900 drawLargeBlockByFlags( target, x,y, color, nflags , doalpha);
2901 }
2902
drawMagnet(SDL_Surface * target,int x,int y,int variation,int direction)2903 void drawMagnet( SDL_Surface * target, int x, int y, int variation, int direction)
2904 {
2905 Uint8 tx,ty;
2906
2907 bool vert=((direction==EDITORDIRECTION_DOWN)||(direction==EDITORDIRECTION_UP));
2908 if (vert) ty=12;
2909 else ty=13;
2910
2911 tx=6+variation;
2912
2913
2914 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2915
2916 D.Draw(target,x,y);
2917 }
2918
drawPusher(SDL_Surface * target,int x,int y,editorcolor color,int direction)2919 void drawPusher( SDL_Surface * target, int x, int y, editorcolor color, int direction)
2920 {
2921 Uint8 tx,ty;
2922
2923 switch(direction)
2924 {
2925 case EDITORDIRECTION_RIGHT :tx=4;ty=5; break;
2926 case EDITORDIRECTION_LEFT :tx=5;ty=5; break;
2927 case EDITORDIRECTION_DOWN :tx=4;ty=6; break;
2928 case EDITORDIRECTION_UP :tx=5;ty=6; break;
2929 }
2930 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2931 D.SetColors(&options::BKColor[color],255);
2932 D.Draw(target,x,y);
2933
2934 ty+=2;
2935 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2936 D.SetColors(&options::BFColor[color],255);
2937 D.Draw(target,x,y);
2938 }
2939
drawArrowMaker(SDL_Surface * target,int x,int y,bool round,editorcolor color,int direction,int variation)2940 void drawArrowMaker( SDL_Surface * target, int x, int y, bool round, editorcolor color, int direction, int variation)
2941 {
2942 Uint8 dx,dy,tx,ty;
2943
2944 switch(direction)
2945 {
2946 case EDITORDIRECTION_RIGHT :dx=0;dy=0; break;
2947 case EDITORDIRECTION_LEFT :dx=1;dy=0; break;
2948 case EDITORDIRECTION_DOWN :dx=0;dy=1; break;
2949 case EDITORDIRECTION_UP :dx=1;dy=1; break;
2950 }
2951
2952 switch(variation)
2953 {
2954 case 0: tx=2;ty=7; break;
2955 case 1: tx=1;ty=15; break;
2956 case 2: tx=3;ty=15; break;
2957 }
2958 if(round)tx--;
2959 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2960 D.SetColors(&options::BKColor[color],255);
2961 D.Draw(target,x,y);
2962
2963 switch(variation)
2964 {
2965 case 0: tx=1+dx;ty=8+dy; break;
2966 case 1: tx=dx;ty=16+dy; break;
2967 case 2: tx=2+dx;ty=16+dy; break;
2968 }
2969
2970
2971 D.ChangeRect(tx*sz,ty*sz,sz,sz);
2972 D.SetColors(&options::BFColor[color],255);
2973 D.Draw(target,x,y);
2974
2975
2976 }
2977
drawHazard(SDL_Surface * target,int x,int y,int variation)2978 void drawHazard( SDL_Surface * target, int x, int y, int variation)
2979 {
2980 Uint8 tx,ty;
2981 if(variation==0)
2982 {
2983 Drawer Black(editor::sprites,0,sz*4,sz,sz);
2984 Black.Draw(target,x,y);
2985 }
2986
2987 switch(variation)
2988 {
2989 case 0: tx=0;ty=3; break;
2990 case 1: tx=0;ty=7; break;
2991 case 2: tx=4;ty=19; break;
2992 }
2993 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
2994 D.Draw(target,x,y);
2995 }
2996
drawTeleport(SDL_Surface * target,int x,int y,int direction)2997 void drawTeleport( SDL_Surface * target, int x, int y, int direction)
2998 {
2999 Uint8 tx,ty;
3000 switch(direction)
3001 {
3002 case EDITORDIRECTION_RIGHT: tx=4; break;
3003 case EDITORDIRECTION_DOWN: tx=5; break;
3004 case EDITORDIRECTION_LEFT: tx=6; break;
3005 default: /*up*/ tx=7;
3006 }
3007 ty=2;
3008 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3009 D.Draw(target,x,y);
3010 }
3011
3012
3013
3014
drawBot(SDL_Surface * target,int x,int y)3015 void drawBot( SDL_Surface * target, int x, int y)
3016 {
3017 Drawer D(editor::sprites,3*sz,1*sz,sz,sz);
3018 D.Draw(target,x,y);
3019 }
3020
drawHint(SDL_Surface * target,int x,int y,bool trans)3021 void drawHint( SDL_Surface * target, int x, int y, bool trans)
3022 {
3023 Drawer D(editor::sprites,6*sz,3*sz,sz,sz);
3024 if (trans) {
3025 D.SetColors(255,255,255, 128);
3026 }
3027 D.Draw(target,x,y);
3028 }
3029
3030
drawFirePad(SDL_Surface * target,int x,int y)3031 void drawFirePad( SDL_Surface * target, int x, int y)
3032 {
3033 Drawer D(editor::sprites,2*sz,5*sz,sz,sz);
3034 D.Draw(target,x,y);
3035 }
drawError(SDL_Surface * target,int x,int y)3036 void drawError( SDL_Surface * target, int x, int y)
3037 {
3038 Uint32 col;
3039 if (editor::tic4%2==0) {
3040 col =SDL_MapRGB(target->format,255,0,0);
3041 } else {
3042 col =SDL_MapRGB(target->format,255,255,255);
3043 }
3044 SDL_FillRect(target, x,y, sz,sz, col );
3045 }
3046
drawFood(SDL_Surface * target,int x,int y)3047 void drawFood( SDL_Surface * target, int x, int y)
3048 {
3049 Drawer D(editor::sprites,11*sz,13*sz,sz,sz);
3050 D.Draw(target,x,y);
3051 }
3052
drawWildCard(SDL_Surface * target,int x,int y,bool round)3053 void drawWildCard( SDL_Surface * target, int x, int y, bool round)
3054 {
3055 Uint8 tx;
3056 if(round)tx=2;
3057 else tx=1;
3058 Drawer D(editor::sprites,tx*sz,2*sz,sz,sz);
3059 D.Draw(target,x,y);
3060 }
3061
getHiddenWayFlagsByVariationAndDir(int variation,int direction)3062 Uint32 getHiddenWayFlagsByVariationAndDir(int variation, int direction)
3063 {
3064 Uint32 flags = 0;
3065 variation -= 2;
3066 if (variation == 0) {
3067 flags = 15; // 1111
3068 } else if (variation == 1) {
3069 flags = 14; // 0111 - 1011 - 1101 - 1110
3070 } else if (variation == 2) {
3071 flags = 12; // 0011 - 0110 - 1100 - 1001
3072 } else if (variation == 3) {
3073 flags = 10; // 0101 - 1010
3074 } else if (variation == 4) {
3075 flags = 8; // 0001 - 0010 - 0100 - 1000
3076 } else if (variation == 5) {
3077 flags = 0; // 0000
3078 }
3079 switch(direction)
3080 {
3081 case EDITORDIRECTION_DOWN: //bit 0 to 2
3082 flags = ( ((flags<<2)&/*0b1111*/15) | (flags>>2) );
3083 break;
3084 case EDITORDIRECTION_UP: //bit 0 to 0
3085 break;
3086 case EDITORDIRECTION_LEFT: //bit 0 to 3
3087 flags = ( ((flags<<3)&/*0b1111*/15) | (flags>>1) );
3088 break;
3089 case EDITORDIRECTION_RIGHT: //bit 0 to 1
3090 flags = ( ((flags<<1)&/*0b1111*/15) | (flags>>3) );
3091 break;
3092 }
3093 Uint32 up = flags&1;
3094 Uint32 right = (flags>>1)&1;
3095 Uint32 down = (flags>>2)&1;
3096 Uint32 left = (flags>>3)&1;
3097 flags = (up<<8)|(right<<6)|(down<<2)|(left<<4);
3098 return flags;
3099
3100 }
3101
drawOneDir(SDL_Surface * target,int x,int y,int direction,int variation)3102 void drawOneDir( SDL_Surface * target, int x, int y, int direction, int variation)
3103 {
3104 Uint8 tx,ty;
3105 if (variation >= 2) {
3106 Uint32 flags = getHiddenWayFlagsByVariationAndDir( variation, direction );
3107 Uint32 up = (flags>>8)&1;
3108 Uint32 right = (flags>>6)&1;
3109 Uint32 down = (flags>>2)&1;
3110 Uint32 left = (flags>>4)&1;
3111
3112 tx = 6; ty = 10;
3113 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3114 DefaultColorData & cd = editor::board->colors[EDITOR_COLOR_DOORS];
3115 if (! cd.useDefault ) {
3116 D.SetColors( &cd.color, 255);
3117 } else {
3118 D.SetColors( &options::OneWayDoorColor, 255);
3119 }
3120 D.Draw(target,x,y);
3121
3122 Sint16 k = sz/8;
3123 Uint32 black = SDL_MapRGB(target->format, 0,0,0 );
3124 Uint32 white = SDL_MapRGB(target->format, 255,255,255 );
3125
3126 if (!up) {
3127 SDL_FillRect(target, x+k-1,y+k-1,sz-2*k+2,k+2, white );
3128 SDL_FillRect(target, x+k,y+k,sz-2*k,k, black );
3129 }
3130 if (!down) {
3131 SDL_FillRect(target, x+k-1,y+sz-2*k-1,sz-2*k+2,k+2, white );
3132 SDL_FillRect(target, x+k,y+sz-2*k,sz-2*k,k, black );
3133 }
3134 if (!left) {
3135 SDL_FillRect(target, x+k-1, y+k-1, k+2,sz-2*k+2, white );
3136 SDL_FillRect(target, x+k,y+k,k,sz-2*k, black );
3137 }
3138 if (!right) {
3139 SDL_FillRect(target, x+sz-2*k-1,y+k-1, k+2,sz-2*k+2, white );
3140 SDL_FillRect(target, x+sz-2*k,y+k,k,sz-2*k, black );
3141 }
3142
3143 } else if(variation) { //ground arrow
3144
3145 switch(direction)
3146 {
3147 case EDITORDIRECTION_DOWN: tx=9; ty=11; break;
3148 case EDITORDIRECTION_UP: tx=10; ty=11; break;
3149 case EDITORDIRECTION_RIGHT: tx=9; ty=10; break;
3150 default: tx=10; ty=10; break;
3151 }
3152 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3153 DefaultColorData & cd = editor::board->colors[EDITOR_COLOR_FORCE];
3154 if (! cd.useDefault ) {
3155 D.SetColors( &cd.color, 255);
3156 } else {
3157 D.SetColors( &options::ForceArrowColor, 255);
3158 }
3159 D.Draw(target,x,y);
3160 } else {
3161 ty=10;
3162 if( (direction==EDITORDIRECTION_DOWN) || (direction==EDITORDIRECTION_UP) ) tx=7;
3163 else tx=8;
3164
3165 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3166 DefaultColorData & cd = editor::board->colors[EDITOR_COLOR_DOORS];
3167 if (! cd.useDefault ) {
3168 D.SetColors( &cd.color, 255);
3169 } else {
3170 D.SetColors( &options::OneWayDoorColor, 255);
3171 }
3172
3173 D.Draw(target,x,y);
3174
3175 switch(direction)
3176 {
3177 case EDITORDIRECTION_DOWN: tx=4; ty=10; break;
3178 case EDITORDIRECTION_UP: tx=5; ty=10; break;
3179 case EDITORDIRECTION_RIGHT: tx=4; ty=11; break;
3180 default: tx=5; ty=11; break;
3181 }
3182 D.ChangeRect(tx*sz,ty*sz,sz,sz);
3183 D.SetColors(0,0,0,120);
3184 D.Draw(target,x,y);
3185 }
3186 }
3187
drawBeast(SDL_Surface * target,int x,int y,int direction,int variation,bool noDirectionAid=false)3188 void drawBeast( SDL_Surface * target, int x, int y, int direction, int variation, bool noDirectionAid=false)
3189 {
3190 Uint8 tx,ty;
3191
3192 switch((btype)variation)
3193 {
3194 case(BT_TWISTER): tx=17; ty=0; break;
3195 case(BT_SPIKE): tx=19; ty=0; break;
3196 case(BT_VIRUS): tx=18; ty=0; break;
3197 case(BT_BLOB): tx=19; ty=6; break;
3198 case(BT_BLOBBOSS): tx=19; ty=12; break;
3199 case(BT_PATIENCE): tx=19; ty=9; break;
3200 case(BT_TIGER): tx=10; ty=14; break;
3201
3202 case(BT_STATIC): tx=11; ty=15; break;
3203
3204 case(BT_DARD):
3205 switch(direction)
3206 {
3207 case(EDITORDIRECTION_UP): tx=19; break;
3208 case(EDITORDIRECTION_LEFT): tx=18; break;
3209 case(EDITORDIRECTION_DOWN): tx=17; break;
3210 default: tx=16;
3211 }
3212 ty= 2;
3213 break;
3214 case(BT_WARD):
3215 switch(direction)
3216 {
3217 case(EDITORDIRECTION_UP): tx=19; break;
3218 case(EDITORDIRECTION_LEFT): tx=18; break;
3219 case(EDITORDIRECTION_DOWN): tx=17; break;
3220 default: tx=16;
3221 }
3222 ty= 4;
3223 break;
3224
3225 case(BT_RANGER):
3226 switch(direction)
3227 {
3228 case(EDITORDIRECTION_UP): tx=15; break;
3229 case(EDITORDIRECTION_LEFT): tx=14; break;
3230 case(EDITORDIRECTION_DOWN): tx=13; break;
3231 default: tx=12;
3232 }
3233 ty= 18;
3234 break;
3235
3236
3237 case(BT_SPINNER):case(BT_ASPINNER):
3238 tx=11;
3239 if (variation==(int)BT_ASPINNER) ty=11;
3240 else ty=9;
3241 break;
3242
3243
3244 default: //gnasher
3245 tx=16;
3246 ty=0;
3247
3248
3249 }
3250 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3251
3252
3253 if(( (variation==(int)(BT_SPINNER) ) || (variation==(int)(BT_ASPINNER) ) ) && (editor::tic4<2) && !noDirectionAid)
3254 {
3255 D.SetColors(255,255,255,128);
3256 D.Draw(target,x,y);
3257
3258 switch(direction)
3259 {
3260 case(EDITORDIRECTION_RIGHT): tx=4; ty=11; break;
3261 case(EDITORDIRECTION_LEFT): tx=5; ty=11; break;
3262 case(EDITORDIRECTION_DOWN): tx=4; ty=12; break;
3263 default: tx=5; ty=12;
3264 }
3265 D.ChangeRect(tx*sz,ty*sz,sz,sz);
3266
3267 D.SetColors(0,0,0,255);
3268 D.Draw(target,x,y);
3269 }
3270 else D.Draw(target,x,y);
3271
3272 }
3273
3274
drawFactoryTop(SDL_Surface * target,int x,int y,int direction,bool dotrans)3275 void drawFactoryTop( SDL_Surface * target, int x, int y, int direction, bool dotrans)
3276 {
3277 Uint8 tx, ty=14;
3278 switch(direction)
3279 {
3280 case(EDITORDIRECTION_RIGHT): tx=6; break;
3281 case(EDITORDIRECTION_DOWN): tx=7; break;
3282 case(EDITORDIRECTION_LEFT): tx=8; break;
3283 default: tx=9;
3284 }
3285 Drawer D(editor::sprites,tx*sz,ty*sz,sz,sz);
3286 if( dotrans )
3287 {
3288 Uint8 alpha = 255;
3289 if((editor::tic4<2) ) alpha = 120;
3290
3291 D.SetColors(255,255,255,alpha);
3292 }
3293 D.Draw(target,x,y);
3294 tx = ((tx-6)+2)%4+6;
3295 ty ++;
3296 D.ChangeRect(tx*sz,ty*sz,sz,sz);
3297 D.Draw(target,x,y);
3298 }
3299
drawColorFactory(SDL_Surface * target,int x,int y,bool round,editorcolor color,int variation,int direction)3300 void drawColorFactory( SDL_Surface * target, int x, int y, bool round, editorcolor color, int variation, int direction)
3301 {
3302 switch(variation)
3303 {
3304 case 0: drawBlock(target, x,y, round, color); break;
3305 case 1: drawSpecialBlocks(target,x,y,round, color, 0, direction); break;
3306 case 2: drawSpecialBlocks(target,x,y,round, color, 4, direction); break;
3307 case 3: drawPusher(target,x,y,color,direction); break;
3308 case 4: drawGem(target,x,y,color);
3309
3310 }
3311 drawFactoryTop(target,x,y, direction, (editor::SelectedType() == EDOT_COLORFACTORY)||(editor::SelectedType() == EDOT_DANGERFACTORY) );
3312 }
drawDangerFactory(SDL_Surface * target,int x,int y,int variation,int direction)3313 void drawDangerFactory( SDL_Surface * target, int x, int y, int variation, int direction)
3314 {
3315 switch(variation)
3316 {
3317 case 14: drawRattlerHead(target,x,y,0,direction); break;
3318 case 15: drawFood(target,x,y); break;
3319 case 16: drawHazard(target,x,y,1); break;
3320 default : drawBeast(target,x,y,direction,variation, true);
3321
3322 }
3323 drawFactoryTop(target,x,y, direction, (editor::SelectedType() == EDOT_COLORFACTORY)||(editor::SelectedType() == EDOT_DANGERFACTORY) );
3324 }
3325
drawObjectBySpecs(SDL_Surface * target,int x,int y,editorobjecttype ot,editorcolor color,bool round,int variation,int direction)3326 void drawObjectBySpecs( SDL_Surface * target, int x, int y, editorobjecttype ot, editorcolor color, bool round, int variation, int direction)
3327 {
3328 switch(ot)
3329 {
3330 case EDOT_XYE: drawXye(target,x,y,variation); break;
3331 case EDOT_RATTLERHEAD: drawRattlerHead(target,x,y,variation,direction); break;
3332 case EDOT_GEM: drawGem(target,x,y,color); break;
3333 case EDOT_WALL: drawWall(target,x,y,round,variation); break;
3334 case EDOT_BLOCK: drawBlock(target,x,y,round,color); break;
3335 case EDOT_HINT: drawHint(target,x,y, false); break;
3336 case EDOT_LARGEBLOCK: drawLargeBlock(target,x,y,color,variation, direction); break;
3337 case EDOT_PORTAL: drawPortal(target,x,y,color,variation); break;
3338 case EDOT_COLORFACTORY: drawColorFactory(target,x,y,round, color,variation, direction); break;
3339 case EDOT_DANGERFACTORY: drawDangerFactory(target,x,y,variation, direction); break;
3340 case EDOT_TURNER: drawTurner(target,x,y,round,color,variation); break;
3341
3342
3343 case EDOT_NUMBER: drawNumber(target,x,y,color,round,variation); break;
3344 case EDOT_SPECIALBLOCKS: drawSpecialBlocks(target,x,y,round,color,variation,direction); break;
3345
3346 case EDOT_EARTH: drawEarth(target,x,y,round); break;
3347 case EDOT_GEMBLOCK: drawGemBlock(target,x,y,color); break;
3348 case EDOT_MAGNET: drawMagnet(target,x,y,variation,direction); break;
3349 case EDOT_PUSHER: drawPusher(target,x,y,color,direction); break;
3350 case EDOT_ARROWMAKER: drawArrowMaker(target,x,y,round,color,direction,variation); break;
3351 case EDOT_HAZARD: drawHazard(target,x,y,variation); break;
3352 case EDOT_ONEDIRECTION: drawOneDir(target,x,y,direction,variation); break;
3353 case EDOT_BEAST: drawBeast(target,x,y,direction,variation); break;
3354 case EDOT_TELEPORT: drawTeleport(target,x,y,direction); break;
3355 case EDOT_BOT: drawBot(target,x,y); break;
3356 case EDOT_FOOD: drawFood(target,x,y); break;
3357 case EDOT_FIREPAD: drawFirePad(target,x,y); break;
3358 case EDOT_ERROR: drawError(target,x,y); break;
3359
3360
3361
3362 case EDOT_COLORSYSTEM: drawColorSystem(target,x,y,color,variation); break;
3363 case EDOT_KEYSYSTEM: drawKeySystem(target,x,y,color,variation); break;
3364 }
3365 }
3366
3367
3368
3369
3370