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