X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Feditor.c;h=5a8035a888d4d82693be1bd0392949bef2448f2e;hb=6fe98dc77891e9fc45cbd99bbd4793e2133c6960;hp=ee7fe4e58942403d9a98ae51274dee45b79c515f;hpb=d0893e6987c21c25ec137438a18cfe1288362139;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index ee7fe4e5..5a8035a8 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1,34 +1,173 @@ /*********************************************************** * Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* ©1995 Artsoft Development * -* Holger Schemel * -* 33659 Bielefeld-Senne * -* Telefon: (0521) 493245 * -* eMail: aeglos@valinor.owl.de * -* aeglos@uni-paderborn.de * -* q99492@pbhrzx.uni-paderborn.de * +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * *----------------------------------------------------------* * editor.c * -* * -* Letzte Aenderung: 15.06.1995 * ***********************************************************/ #include "editor.h" #include "screens.h" -#include "game.h" #include "tools.h" #include "misc.h" +#include "buttons.h" +#include "files.h" +#include "game.h" + +/* positions in the level editor */ +#define ED_WIN_MB_LEFT_XPOS 7 +#define ED_WIN_MB_LEFT_YPOS 6 +#define ED_WIN_LEVELNR_XPOS 77 +#define ED_WIN_LEVELNR_YPOS 7 +#define ED_WIN_MB_MIDDLE_XPOS 7 +#define ED_WIN_MB_MIDDLE_YPOS 258 +#define ED_WIN_MB_RIGHT_XPOS 77 +#define ED_WIN_MB_RIGHT_YPOS 258 + +/* other constants for the editor */ +#define ED_SCROLL_NO 0 +#define ED_SCROLL_LEFT 1 +#define ED_SCROLL_RIGHT 2 +#define ED_SCROLL_UP 4 +#define ED_SCROLL_DOWN 8 + +/* delay value to avoid too fast scrolling etc. */ +#define CHOICE_DELAY_VALUE 100 + +/* how many steps can be cancelled */ +#define NUM_UNDO_STEPS (10 + 1) + +/* values for the control window */ +#define ED_CTRL_BUTTONS_GFX_YPOS 236 +#define ED_CTRL1_BUTTONS_HORIZ 4 +#define ED_CTRL1_BUTTONS_VERT 4 +#define ED_CTRL1_BUTTON_XSIZE 22 +#define ED_CTRL1_BUTTON_YSIZE 22 +#define ED_CTRL1_BUTTONS_XPOS 6 +#define ED_CTRL1_BUTTONS_YPOS 6 +#define ED_CTRL2_BUTTONS_HORIZ 3 +#define ED_CTRL2_BUTTONS_VERT 2 +#define ED_CTRL2_BUTTON_XSIZE 30 +#define ED_CTRL2_BUTTON_YSIZE 20 +#define ED_CTRL2_BUTTONS_XPOS 5 +#define ED_CTRL2_BUTTONS_YPOS 100 +#define ED_NUM_CTRL1_BUTTONS (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT) +#define ED_NUM_CTRL2_BUTTONS (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT) +#define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS) + +/* control button names */ +#define ED_CTRL_ID_SINGLE_ITEMS 0 +#define ED_CTRL_ID_CONNECTED_ITEMS 1 +#define ED_CTRL_ID_LINE 2 +#define ED_CTRL_ID_TEXT 3 +#define ED_CTRL_ID_RECTANGLE 4 +#define ED_CTRL_ID_FILLED_BOX 5 +#define ED_CTRL_ID_WRAP_UP 6 +#define ED_CTRL_ID_ITEM_PROPERTIES 7 +#define ED_CTRL_ID_FLOOD_FILL 8 +#define ED_CTRL_ID_WRAP_LEFT 9 +#define ED_CTRL_ID_WRAP_RIGHT 11 +#define ED_CTRL_ID_RANDOM_PLACEMENT 12 +#define ED_CTRL_ID_BRUSH 13 +#define ED_CTRL_ID_WRAP_DOWN 14 +#define ED_CTRL_ID_UNDO 16 +#define ED_CTRL_ID_INFO 17 +#define ED_CTRL_ID_SAVE 18 +#define ED_CTRL_ID_CLEAR 19 +#define ED_CTRL_ID_TEST 20 +#define ED_CTRL_ID_EXIT 21 + +/* forward declaration for internal use */ +void HandleDrawingFunctions(int, int, int); +void HandlePressedControlButtons(); +void HandleControlButtons(struct GadgetInfo *); + +static struct GadgetInfo *control_button_gadget[ED_NUM_CTRL_BUTTONS]; +static boolean control_button_gadgets_created = FALSE; +static boolean control_button_gadgets_mapped = FALSE; + +static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS; + +static short OrigBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +static int undo_buffer_position = 0; +static int undo_buffer_steps = 0; static int level_xpos,level_ypos; -static BOOL edit_mode; -static BOOL name_typing; -static int element_shift; +static boolean edit_mode; +static boolean name_typing; static int new_element1 = EL_MAUERWERK; static int new_element2 = EL_LEERRAUM; static int new_element3 = EL_ERDREICH; -static int editor_element[] = + +int element_shift; +int editor_element[] = { + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('U' - 'A'), + EL_CHAR_A + ('L' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('R' - 'A'), + + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('S' - 'A'), + EL_CHAR_A + ('H' - 'A'), + + EL_SPIELFIGUR, + EL_LEERRAUM, + EL_ERDREICH, + EL_BETON, + + EL_FELSBODEN, + EL_SIEB2_LEER, + EL_AUSGANG_ZU, + EL_AUSGANG_AUF, + + EL_EDELSTEIN_BD, + EL_BUTTERFLY_O, + EL_FIREFLY_O, + EL_FELSBROCKEN, + + EL_BUTTERFLY_L, + EL_FIREFLY_L, + EL_BUTTERFLY_R, + EL_FIREFLY_R, + + EL_AMOEBE_BD, + EL_BUTTERFLY_U, + EL_FIREFLY_U, + EL_LEERRAUM, + + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_MINUS, + + EL_CHAR_A + ('R' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('L' - 'A'), + EL_CHAR_A + ('D' - 'A'), + + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('I' - 'A'), + EL_CHAR_A + ('N' - 'A'), + EL_CHAR_A + ('E' - 'A'), + + EL_SPIELER1, + EL_SPIELER2, + EL_SPIELER3, + EL_SPIELER4, + EL_SPIELFIGUR, EL_LEERRAUM, EL_ERDREICH, @@ -44,46 +183,45 @@ static int editor_element[] = EL_KOKOSNUSS, EL_BOMBE, + EL_ERZ_EDEL, + EL_ERZ_DIAM, EL_MORAST_LEER, EL_MORAST_VOLL, + + EL_DYNAMIT_AUS, + EL_DYNAMIT, EL_AUSGANG_ZU, EL_AUSGANG_AUF, - EL_KAEFER, - EL_FLIEGER, EL_MAMPFER, - EL_ZOMBIE, + EL_KAEFER_O, + EL_FLIEGER_O, + EL_ROBOT, + + EL_KAEFER_L, + EL_FLIEGER_L, + EL_KAEFER_R, + EL_FLIEGER_R, - EL_PACMAN, - EL_DYNAMIT_AUS, - EL_DYNAMIT, EL_ABLENK_AUS, + EL_KAEFER_U, + EL_FLIEGER_U, + EL_UNSICHTBAR, EL_BADEWANNE1, EL_SALZSAEURE, EL_BADEWANNE2, - EL_BADEWANNE, + EL_LEERRAUM, EL_BADEWANNE3, EL_BADEWANNE4, EL_BADEWANNE5, - EL_UNSICHTBAR, + EL_LEERRAUM, EL_TROPFEN, - EL_AMOEBE1, - EL_AMOEBE2, - EL_AMOEBE3, - - EL_LIFE, - EL_LIFE_ASYNC, - - EL_ERZ_1, - EL_ERZ_2, - -/* - EL_BIRNE_AUS, - EL_BIRNE_EIN, -*/ + EL_AMOEBE_TOT, + EL_AMOEBE_NASS, + EL_AMOEBE_NORM, EL_SCHLUESSEL1, EL_SCHLUESSEL2, @@ -100,20 +238,92 @@ static int editor_element[] = EL_PFORTE3X, EL_PFORTE4X, - EL_KAEFER_R, - EL_KAEFER_O, - EL_KAEFER_L, - EL_KAEFER_U, + EL_CHAR_A + ('M' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('R' - 'A'), + EL_CHAR_A + ('E' - 'A'), - EL_FLIEGER_R, - EL_FLIEGER_O, - EL_FLIEGER_L, - EL_FLIEGER_U, + EL_PFEIL_L, + EL_PFEIL_R, + EL_PFEIL_O, + EL_PFEIL_U, - EL_PACMAN_R, + EL_AMOEBE_VOLL, + EL_EDELSTEIN_GELB, + EL_EDELSTEIN_ROT, + EL_EDELSTEIN_LILA, + + EL_ERZ_EDEL_BD, + EL_ERZ_EDEL_GELB, + EL_ERZ_EDEL_ROT, + EL_ERZ_EDEL_LILA, + + EL_LIFE, EL_PACMAN_O, + EL_ZEIT_VOLL, + EL_ZEIT_LEER, + EL_PACMAN_L, + EL_MAMPFER2, + EL_PACMAN_R, + EL_MAUER_LEBT, + + EL_LIFE_ASYNC, EL_PACMAN_U, + EL_BIRNE_AUS, + EL_BIRNE_EIN, + + EL_DYNABOMB_NR, + EL_DYNABOMB_SZ, + EL_DYNABOMB_XL, + EL_BADEWANNE, + + EL_MAULWURF, + EL_PINGUIN, + EL_SCHWEIN, + EL_DRACHE, + + EL_SONDE, + EL_MAUER_X, + EL_MAUER_Y, + EL_MAUER_XY, + + EL_CHAR_A + ('S' - 'A'), + EL_CHAR_A + ('O' - 'A'), + EL_CHAR_A + ('K' - 'A'), + EL_CHAR_A + ('O' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('N' - 'A'), + + EL_SOKOBAN_OBJEKT, + EL_SOKOBAN_FELD_LEER, + EL_SOKOBAN_FELD_VOLL, + EL_BETON, + +/* + EL_CHAR_A + ('D' - 'A'), + EL_CHAR_A + ('Y' - 'A'), + EL_CHAR_A + ('N' - 'A'), + EL_CHAR_A + ('A' - 'A'), + + EL_CHAR_A + ('B' - 'A'), + EL_CHAR_A + ('L' - 'A'), + EL_CHAR_A + ('A' - 'A'), + EL_CHAR_A + ('S' - 'A'), + + EL_CHAR_MINUS, + EL_CHAR_A + ('T' - 'A'), + EL_CHAR_A + ('E' - 'A'), + EL_CHAR_A + ('R' - 'A'), +*/ + + EL_LEERRAUM, + EL_LEERRAUM, + EL_LEERRAUM, + EL_LEERRAUM, EL_CHAR_AUSRUF, EL_CHAR_ZOLL, @@ -189,11 +399,134 @@ static int editor_element[] = EL_CHAR_UE, EL_CHAR_COPY }; -static int elements_in_list = sizeof(editor_element)/sizeof(int); +int elements_in_list = sizeof(editor_element)/sizeof(int); + +void ScrollMiniLevel(int from_x, int from_y, int scroll) +{ + int x,y; + int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0); + int dy = (scroll==ED_SCROLL_UP ? -1 : scroll==ED_SCROLL_DOWN ? 1 : 0); + + XCopyArea(display,drawto,drawto,gc, + SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1), + SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy), + SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1)); + if (dx) + { + x = (dx==1 ? 0 : 2*SCR_FIELDX-1); + for(y=0;y<2*SCR_FIELDY;y++) + DrawMiniElementOrWall(x,y,from_x,from_y); + } + else if (dy) + { + y = (dy==1 ? 0 : 2*SCR_FIELDY-1); + for(x=0;x<2*SCR_FIELDX;x++) + DrawMiniElementOrWall(x,y,from_x,from_y); + } + + redraw_mask |= REDRAW_FIELD; + BackToFront(); +} + +void CreateLevelEditorControlButtons() +{ + int i; + + if (control_button_gadgets_created) + return; + + for (i=0; ilev_fieldx-2*SCR_FIELDX+1) - level_xpos = lev_fieldx-2*SCR_FIELDX+1; - if (lev_fieldx<2*SCR_FIELDX-2) + if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1) + level_xpos = lev_fieldx - 2*SCR_FIELDX + 1; + if (lev_fieldx < 2*SCR_FIELDX - 2) level_xpos = -1; - if (level_ypos<-1) + if (level_ypos < -1) level_ypos = -1; - if (level_ypos>lev_fieldy-2*SCR_FIELDY+1) - level_ypos = lev_fieldy-2*SCR_FIELDY+1; - if (lev_fieldy<2*SCR_FIELDY-2) + if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1) + level_ypos = lev_fieldy - 2*SCR_FIELDY + 1; + if (lev_fieldy < 2*SCR_FIELDY - 2) level_ypos = -1; } -void FloodFill(int from_x, int from_y, int fill_element) -{ - int i,x,y; - int old_element; - static int check[4][2] = { -1,0, 0,-1, 1,0, 0,1 }; - static int safety = 0; - - safety++; - - if (safety>lev_fieldx*lev_fieldy) - { - fprintf(stderr,"Something went wrong in 'FloodFill()'. Please debug.\n"); - exit(-1); - } - - old_element = Feld[from_x][from_y]; - Feld[from_x][from_y] = fill_element; - - for(i=0;i<4;i++) - { - x = from_x+check[i][0]; - y = from_y+check[i][1]; - - if (IN_LEV_FIELD(x,y) && Feld[x][y]==old_element) - FloodFill(x,y,fill_element); - } - - safety--; -} - void LevelEd(int mx, int my, int button) { static int last_button = 0; static int in_field_pressed = FALSE; - static BOOL use_floodfill = FALSE; + static boolean use_floodfill = FALSE; + + + /* int x = (mx-SX)/MINI_TILEX; int y = (my-SY)/MINI_TILEY; + */ + + + HandlePressedControlButtons(); + HandleDrawingFunctions(mx, my, button); if (use_floodfill) /********** FLOOD FILL **********/ { + + +#if 0 + if (button) { if (mx>=SX && mx=SY && my0) || + (choice == ED_BUTTON_EDOWN && + element_shift0) || - (choice==ED_BUTTON_EDOWN && - element_shiftelements_in_list-MAX_ELEM_X*MAX_ELEM_Y) - element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y; - if (element_shift % MAX_ELEM_X) - element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X); - - for(i=0;i=0 && elem_poselements_in_list-MAX_ELEM_X*MAX_ELEM_Y) + element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y; + if (element_shift % MAX_ELEM_X) + element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X); + + for(i=0;i=0 && elem_pos=0) { + if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE)) + break; if (lev_fieldx<2*SCR_FIELDX-2) break; @@ -622,13 +971,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_RIGHT: if (level_xpos<=lev_fieldx-2*SCR_FIELDX) { + if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE)) + break; if (lev_fieldx<2*SCR_FIELDX-2) break; @@ -639,13 +988,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_UP: if (level_ypos>=0) { + if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE)) + break; if (lev_fieldy<2*SCR_FIELDY-2) break; @@ -656,13 +1005,13 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; case ED_BUTTON_DOWN: if (level_ypos<=lev_fieldy-2*SCR_FIELDY) { + if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE)) + break; if (lev_fieldy<2*SCR_FIELDY-2) break; @@ -673,14 +1022,18 @@ void LevelEd(int mx, int my, int button) ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP); else DrawMiniLevel(level_xpos,level_ypos); - BackToFront(); - Delay(100000); } break; default: break; } +#endif + + + +#if 0 + if (mx>=SX && mx=SY && my=0 && choice<36 && DelayReached(&choice_delay,10)) + if (choice >= 0 && choice < 36 && + DelayReached(&choice_delay, CHOICE_DELAY_VALUE)) { if (!(choice % 2)) step = -step; @@ -856,6 +1214,10 @@ void LevelEd(int mx, int my, int button) XFlush(display); } + + +#if 0 + switch(CheckCtrlButtons(mx,my,button)) { case ED_BUTTON_EDIT: @@ -870,7 +1232,7 @@ void LevelEd(int mx, int my, int button) edit_mode = TRUE; break; case ED_BUTTON_CLEAR: - if (AreYouSure("Are you sure to clear this level ?",AYS_ASK)) + if (Request("Are you sure to clear this level ?",REQ_ASK)) { for(x=0;x=ED_COUNT_GADGET_XPOS && mx=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE && @@ -952,6 +1326,25 @@ void LevelEd(int mx, int my, int button) } } + if (mx>=SX+29*MINI_TILEX && mx=SY+26*MINI_TILEY && my3) + return; + + new_element = (button==1 ? new_element1 : + button==2 ? new_element2 : + button==3 ? new_element3 : 0); + + if (new_element != level.amoebe_inhalt) + { + level.amoebe_inhalt = new_element; + DrawMiniElement(29,26,new_element); + } + } + if (mx>=SX+1*MINI_TILEX && mx=SY+2*MINI_TILEY && my0) + else if ((key==XK_Delete || key==XK_BackSpace) && len>0) { level.name[len-1] = 0; len--; @@ -1085,432 +1478,596 @@ void LevelNameTyping(KeySym key) } } -void DrawEditButton(unsigned long state) +static void swap_numbers(int *i1, int *i2) { - int i; - int xpos = 0, ypos = 1, xsize = 2, ysize = 3; - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2; - static int edit_pos[6][4] = - { - ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS, - ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE, + int help = *i1; - ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS, - ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE, + *i1 = *i2; + *i2 = help; +} - ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS, - ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE, +static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) +{ + int help_x = *x1; + int help_y = *y1; - ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS, - ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE, + *x1 = *x2; + *x2 = help_x; - ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS, - ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE, + *y1 = *y2; + *y2 = help_y; +} - ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS, - ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE - }; +static void DrawLineElement(int sx, int sy, int element, boolean change_level) +{ + int lx = sx + level_xpos; + int ly = sy + level_ypos; - if (state & ED_BUTTON_PRESSED) - cx = DOOR_GFX_PAGEX5; + DrawMiniElement(sx, sy, (element < 0 ? Feld[lx][ly] : element)); + + if (change_level) + Feld[lx][ly] = element; +} - for(i=0;i<6;i++) +void DrawLine(int from_x, int from_y, int to_x, int to_y, int element, + boolean change_level) +{ + if (from_y == to_y) /* horizontal line */ { - if (state & (1< to_x) + swap_numbers(&from_x, &to_x); + + for (x=from_x; x<=to_x; x++) + DrawLineElement(x, y, element, change_level); } + else if (from_x == to_x) /* vertical line */ + { + int x = from_x; + int y; - redraw_mask |= REDRAW_DOOR_2; -} + if (from_y > to_y) + swap_numbers(&from_y, &to_y); -void DrawCtrlButton(unsigned long state) -{ - int i; - int xpos = 0, ypos = 1, xsize = 2, ysize = 3; - int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80; - static int edit_pos[4][4] = + for (y=from_y; y<=to_y; y++) + DrawLineElement(x, y, element, change_level); + } + else /* diagonal line */ { - ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS, - ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE, + int len_x = ABS(to_x - from_x); + int len_y = ABS(to_y - from_y); + int x, y; - ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS, - ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE, + if (len_y < len_x) /* a < 1 */ + { + float a = (float)len_y / (float)len_x; - ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS, - ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE, + if (from_x > to_x) + swap_number_pairs(&from_x, &from_y, &to_x, &to_y); - ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS, - ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE - }; + for (x=0; x<=len_x; x++) + { + int y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1); - if (state & ED_BUTTON_PRESSED) - cx = DOOR_GFX_PAGEX3; + DrawLineElement(from_x + x, from_y + y, element, change_level); + } + } + else /* a >= 1 */ + { + float a = (float)len_x / (float)len_y; - for(i=0;i<4;i++) - { - if (state & (1<<(i+6))) - XCopyArea(display,pix[PIX_DOOR],drawto,gc, - cx + edit_pos[i][xpos], - cy + edit_pos[i][ypos], - edit_pos[i][xsize], - edit_pos[i][ysize], - VX + edit_pos[i][xpos], - VY + edit_pos[i][ypos]); + if (from_y > to_y) + swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + + for (y=0; y<=len_y; y++) + { + int x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1); + + DrawLineElement(from_x + x, from_y + y, element, change_level); + } + } } +} - redraw_mask |= REDRAW_DOOR_2; +void DrawRectangle(int from_x, int from_y, int to_x, int to_y, int element, + boolean change_level) +{ + DrawLine(from_x, from_y, from_x, to_y, element, change_level); + DrawLine(from_x, to_y, to_x, to_y, element, change_level); + DrawLine(to_x, to_y, to_x, from_y, element, change_level); + DrawLine(to_x, from_y, from_x, from_y, element, change_level); } -void DrawElemButton(int button_nr, int button_state) +void DrawFilledBox(int from_x, int from_y, int to_x, int to_y, int element, + boolean change_level) { - int xpos = 0, ypos = 1, xsize = 2, ysize = 3; - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - int from_x, from_y, to_x,to_y, size_x, size_y; - static int edit_pos[3][4] = - { - ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS, - ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE, + int y; - ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS, - ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE, + if (from_y > to_y) + swap_number_pairs(&from_x, &from_y, &to_x, &to_y); - ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS, - ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE - }; + for (y=from_y; y<=to_y; y++) + DrawLine(from_x, y, to_x, y, element, change_level); +} - if (button_nr lev_fieldx*lev_fieldy) + Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug."); - from_x = cx + edit_pos[pos][xpos]; - from_y = cy + edit_pos[pos][ypos]; - size_x = edit_pos[pos][xsize]; - size_y = edit_pos[pos][ysize]; - to_x = DX + edit_pos[pos][xpos] + x * ED_BUTTON_ELEM_XSIZE; - to_y = DY + edit_pos[pos][ypos] + y * ED_BUTTON_ELEM_YSIZE; + old_element = Feld[from_x][from_y]; + Feld[from_x][from_y] = fill_element; - if (button_state & ED_BUTTON_PRESSED) - { - from_y = ED_BUTTON_ELEM_Y2POS; - shift = 1; - } + for(i=0;i<4;i++) + { + x = from_x + check[i][0]; + y = from_y + check[i][1]; - XCopyArea(display,pix[PIX_DOOR],drawto,gc, - from_x,from_y, size_x,size_y, to_x,to_y); - - DrawMiniGraphicExtHiRes(drawto,gc, - DX+ED_BUTTON_ELEM_XPOS+3+shift + - (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE, - DY+ED_BUTTON_ELEM_YPOS+3-shift + - (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE, - graphic); + if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element) + FloodFill(x, y, fill_element); } - redraw_mask |= REDRAW_DOOR_1; + safety--; } -void DrawCountButton(int button_nr, int button_state) +void CopyLevelToUndoBuffer() { - int from_x, from_y, to_x,to_y, size_x, size_y; - - from_x = - DOOR_GFX_PAGEX4+(button_nr%2 ? ED_BUTTON_PLUS_XPOS : ED_BUTTON_MINUS_XPOS); - from_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS; - size_x = ED_BUTTON_MINUS_XSIZE; - size_y = ED_BUTTON_MINUS_YSIZE; - to_x = (button_nr<32 ? ED_COUNT_GADGET_XPOS : ED_SIZE_GADGET_XPOS); - if (button_nr % 2) - to_x += (ED_BUTTON_PLUS_XPOS - ED_BUTTON_MINUS_XPOS); - to_y = (button_nr<32 ? ED_COUNT_GADGET_YPOS : ED_SIZE_GADGET_YPOS) + - ((button_nr<32 ? button_nr : button_nr-32)/2)*ED_COUNT_GADGET_YSIZE; - - if (button_state & ED_BUTTON_PRESSED) - from_x -= DXSIZE; + int x, y; - XCopyArea(display,pix[PIX_DOOR],drawto,gc, - from_x,from_y, size_x,size_y, to_x,to_y); - XCopyArea(display,pix[PIX_DOOR],window,gc, - from_x,from_y, size_x,size_y, to_x,to_y); + undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS; + + if (undo_buffer_steps < NUM_UNDO_STEPS - 1) + undo_buffer_steps++; + + for(x=0; x= SX + SXSIZE || my < SY || my >= SY + SYSIZE) + return; - if (button) + if ((!button && !button_release_event) || + sx > lev_fieldx || sy > lev_fieldy || + (sx == 0 && level_xpos<0) || + (sx == 2*SCR_FIELDX - 1 && level_xpos > lev_fieldx - 2*SCR_FIELDX) || + (sy == 0 && level_ypos < 0) || + (sy == 2*SCR_FIELDY - 1 && level_ypos > lev_fieldy - 2*SCR_FIELDY)) + return; + + new_element = (button == 1 ? new_element1 : + button == 2 ? new_element2 : + button == 3 ? new_element3 : 0); + + switch (drawing_function) { - if (!motion_status) /* Maustaste neu gedrückt */ - { - if (ON_EDIT_BUTTON(mx,my)) + case ED_CTRL_ID_SINGLE_ITEMS: + if (button_release_event) + copy_to_undo_buffer = TRUE; + + if (!button) + break; + + if (new_element != Feld[lx][ly]) { - choice = EDIT_BUTTON(mx,my); - pressed = TRUE; - DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED); - if (edit_button[choice]!=ED_BUTTON_CTRL && - edit_button[choice]!=ED_BUTTON_FILL) - return_code = 1<= 0 && x - level_xpos < 2*SCR_FIELDX && + y - level_ypos >= 0 && y - level_ypos < 2*SCR_FIELDY) + DrawMiniElement(x - level_xpos, y - level_ypos, EL_LEERRAUM); + } + } + } + } + + Feld[lx][ly] = new_element; + DrawMiniElement(sx, sy, new_element); } - } - else /* Mausbewegung bei gedrückter Maustaste */ - { - if ((!ON_EDIT_BUTTON(mx,my) || EDIT_BUTTON(mx,my)!=choice) && - choice>=0 && pressed) + break; + + case ED_CTRL_ID_CONNECTED_ITEMS: { - pressed = FALSE; - DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED); + static int last_sx = -1; + static int last_sy = -1; + + if (button_release_event) + copy_to_undo_buffer = TRUE; + + if (button) + { + if (!button_press_event) + DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); + + last_sx = sx; + last_sy = sy; + } } - else if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice) + break; + + case ED_CTRL_ID_LINE: + case ED_CTRL_ID_RECTANGLE: + case ED_CTRL_ID_FILLED_BOX: { - if (!pressed) - DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED); - pressed = TRUE; - if (edit_button[choice]!=ED_BUTTON_CTRL && - edit_button[choice]!=ED_BUTTON_FILL) - return_code = 1<state; + int button = control_button_gadget[id]->event.button; + int step = (button == 1 ? 1 : button == 2 ? 5 : 10); + + if (state != GD_BUTTON_PRESSED) + continue; + + switch (id) { - choice = -1; - pressed = FALSE; + case ED_CTRL_ID_WRAP_LEFT: + if (level_xpos >= 0) + { + if (lev_fieldx < 2*SCR_FIELDX - 2) + break; + + level_xpos -= step; + if (level_xpos <- 1) + level_xpos = -1; + if (button == 1) + ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT); + else + DrawMiniLevel(level_xpos, level_ypos); + } + break; + + case ED_CTRL_ID_WRAP_RIGHT: + if (level_xpos <= lev_fieldx - 2*SCR_FIELDX) + { + if (lev_fieldx < 2*SCR_FIELDX - 2) + break; + + level_xpos += step; + if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1) + level_xpos = lev_fieldx - 2*SCR_FIELDX + 1; + if (button == 1) + ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT); + else + DrawMiniLevel(level_xpos, level_ypos); + } + break; + + case ED_CTRL_ID_WRAP_UP: + if (level_ypos >= 0) + { + if (lev_fieldy < 2*SCR_FIELDY - 2) + break; + + level_ypos -= step; + if (level_ypos < -1) + level_ypos = -1; + if (button == 1) + ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN); + else + DrawMiniLevel(level_xpos, level_ypos); + } + break; + + case ED_CTRL_ID_WRAP_DOWN: + if (level_ypos <= lev_fieldy - 2*SCR_FIELDY) + { + if (lev_fieldy < 2*SCR_FIELDY - 2) + break; + + level_ypos += step; + if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1) + level_ypos = lev_fieldy - 2*SCR_FIELDY + 1; + if (button == 1) + ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP); + else + DrawMiniLevel(level_xpos, level_ypos); + } + break; + + default: + break; } } - - BackToFront(); - return(return_code); } -int CheckCtrlButtons(int mx, int my, int button) +void HandleControlButtons(struct GadgetInfo *gi) { - int return_code = 0; - static int choice = -1; - static BOOL pressed = FALSE; - static int ctrl_button[4] = + int event_type = gi->event.type; + int player_present = FALSE; + int level_changed = FALSE; + int id; + int i, x, y; + + /* get the button id */ + for (i=0; iid == control_button_gadget[i]->id) + id = i; + + if (id < ED_NUM_CTRL1_BUTTONS && !edit_mode) { - ED_BUTTON_EDIT, - ED_BUTTON_CLEAR, - ED_BUTTON_UNDO, - ED_BUTTON_EXIT - }; + AdjustLevelScrollPosition(); + DrawMiniLevel(level_xpos, level_ypos); + edit_mode = TRUE; + } - if (button) + switch (id) { - if (!motion_status) /* Maustaste neu gedrückt */ - { - if (ON_CTRL_BUTTON(mx,my)) + case ED_CTRL_ID_SINGLE_ITEMS: + case ED_CTRL_ID_CONNECTED_ITEMS: + case ED_CTRL_ID_LINE: + case ED_CTRL_ID_TEXT: + case ED_CTRL_ID_RECTANGLE: + case ED_CTRL_ID_FILLED_BOX: + case ED_CTRL_ID_FLOOD_FILL: + case ED_CTRL_ID_RANDOM_PLACEMENT: + case ED_CTRL_ID_BRUSH: + drawing_function = id; + break; + + case ED_CTRL_ID_UNDO: + if (undo_buffer_steps == 0) { - choice = CTRL_BUTTON(mx,my); - pressed = TRUE; - DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED); + Request("Undo buffer empty !", REQ_CONFIRM); + break; } - } - else /* Mausbewegung bei gedrückter Maustaste */ - { - if ((!ON_CTRL_BUTTON(mx,my) || CTRL_BUTTON(mx,my)!=choice) && - choice>=0 && pressed) + + undo_buffer_position = + (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS; + undo_buffer_steps--; + + for(x=0; x=0 && pressed) + + for(y=0; y=0 && pressed) + break; + + case ED_CTRL_ID_EXIT: + for(y=0; y