From: Holger Schemel Date: Mon, 14 Dec 1998 20:32:38 +0000 (+0100) Subject: rnd-19981214-2 X-Git-Tag: 1.3.0^2~63 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=4ec434ee1acb955d0e2e8c33558e5f9226904174 rnd-19981214-2 --- diff --git a/src/buttons.c b/src/buttons.c index d990bc13..8148e448 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -840,7 +840,7 @@ void DrawElemButton(int button_nr, int button_state) DrawMiniGraphicExt(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 + + DY+ED_BUTTON_ELEM_YPOS+3+shift + (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE, graphic); } @@ -1470,6 +1470,41 @@ int CheckCountButtons(int mx, int my, int button) static struct GadgetInfo *gadget_list_first_entry = NULL; static struct GadgetInfo *gadget_list_last_entry = NULL; +static int next_free_gadget_id = 1; +static boolean gadget_id_wrapped = FALSE; + +static struct GadgetInfo *getGadgetInfoFromGadgetID(int id) +{ + struct GadgetInfo *gi = gadget_list_first_entry; + + while (gi && gi->id != id) + gi = gi->next; + + return gi; +} + +static int getNewGadgetID() +{ + int id = next_free_gadget_id++; + + if (next_free_gadget_id <= 0) /* counter overrun */ + { + gadget_id_wrapped = TRUE; /* now we must check each ID */ + next_free_gadget_id = 0; + } + + if (gadget_id_wrapped) + { + next_free_gadget_id++; + while (getGadgetInfoFromGadgetID(next_free_gadget_id) != NULL) + next_free_gadget_id++; + } + + if (next_free_gadget_id <= 0) /* cannot get new gadget id */ + Error(ERR_EXIT, "too much gadgets -- this should not happen"); + + return id; +} static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my) { @@ -1477,7 +1512,8 @@ static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my) while (gi) { - if (mx >= gi->x && mx < gi->x + gi->width && + if (gi->mapped && + mx >= gi->x && mx < gi->x + gi->width && my >= gi->y && my < gi->y + gi->height) break; @@ -1498,13 +1534,24 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) /* always start with reliable default values */ memset(new_gadget, 0, sizeof(struct GadgetInfo)); + new_gadget->id = getNewGadgetID(); + while (tag != GDI_END) { + + + +#if 0 printf("tag: %d\n", tag); +#endif + switch(tag) { + case GDI_ID: + new_gadget->id = va_arg(ap, int); + break; case GDI_X: new_gadget->x = va_arg(ap, int); break; @@ -1552,6 +1599,9 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) new_gadget->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int); new_gadget->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int); break; + case GDI_EVENT_MASK: + new_gadget->event_mask = va_arg(ap, unsigned long); + break; case GDI_CALLBACK: new_gadget->callback = va_arg(ap, gadget_callback_function); break; @@ -1609,19 +1659,17 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) &gi->alt_design[state] : &gi->design[state]); - XCopyArea(display, gd->pixmap, drawto, gc, + XCopyArea(display, gd->pixmap, (direct ? window : drawto), gc, gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); - - if (direct) - XCopyArea(display, gd->pixmap, window, gc, - gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); } void MapGadget(struct GadgetInfo *gi) { gi->mapped = TRUE; - DrawGadget(gi, (gi->state == GD_BUTTON_PRESSED), TRUE); + DrawGadget(gi, (gi->state == GD_BUTTON_PRESSED), FALSE); + + redraw_mask |= REDRAW_ALL; } void UnmapGadget(struct GadgetInfo *gi) @@ -1631,47 +1679,52 @@ void UnmapGadget(struct GadgetInfo *gi) void HandleGadgets(int mx, int my, int button) { - static struct GadgetInfo *choice = NULL; + static struct GadgetInfo *gi = NULL; static boolean pressed = FALSE; - struct GadgetInfo *new_choice; + struct GadgetInfo *new_gi; if (gadget_list_first_entry == NULL) return; - new_choice = getGadgetInfoFromMousePosition(mx,my); + new_gi = getGadgetInfoFromMousePosition(mx,my); if (button) { if (!motion_status) /* mouse button just pressed */ { - if (new_choice != NULL) + if (new_gi != NULL) { - choice = new_choice; - choice->state = GD_BUTTON_PRESSED; - choice->event = GD_EVENT_PRESSED; - DrawGadget(choice, TRUE, TRUE); - choice->callback(choice); + gi = new_gi; + gi->state = GD_BUTTON_PRESSED; + gi->event.type = GD_EVENT_PRESSED; + gi->event.button = button; + DrawGadget(gi, TRUE, TRUE); + + if (gi->event_mask & GD_EVENT_PRESSED) + gi->callback(gi); + pressed = TRUE; } } else /* mouse movement with pressed mouse button */ { - if ((new_choice == NULL || new_choice != choice) && - choice != NULL && pressed) + if ((new_gi == NULL || new_gi != gi) && + gi != NULL && pressed) { - choice->state = GD_BUTTON_UNPRESSED; - DrawGadget(choice, FALSE, TRUE); + gi->state = GD_BUTTON_UNPRESSED; + DrawGadget(gi, FALSE, TRUE); pressed = FALSE; } - else if (new_choice != NULL && new_choice == choice) + else if (new_gi != NULL && new_gi == gi) { if (!pressed) - DrawGadget(choice, TRUE, TRUE); - choice->state = GD_BUTTON_PRESSED; + DrawGadget(gi, TRUE, TRUE); + gi->state = GD_BUTTON_PRESSED; + gi->event.type = GD_EVENT_MOVING; + gi->event.button = button; - /* - choice->callback(choice); - */ + if (gi->event_mask & GD_EVENT_MOVING) + gi->callback(gi); pressed = TRUE; } @@ -1679,18 +1732,22 @@ void HandleGadgets(int mx, int my, int button) } else /* mouse button just released */ { - if (new_choice != NULL && new_choice == choice && pressed) + if (new_gi != NULL && new_gi == gi && pressed) { - choice->state = GD_BUTTON_UNPRESSED; - choice->event = GD_EVENT_RELEASED; - DrawGadget(choice, FALSE, TRUE); - choice->callback(choice); - choice = NULL; + gi->state = GD_BUTTON_UNPRESSED; + gi->event.type = GD_EVENT_RELEASED; + gi->event.button = button; + DrawGadget(gi, FALSE, TRUE); + + if (gi->event_mask & GD_EVENT_RELEASED) + gi->callback(gi); + + gi = NULL; pressed = FALSE; } else { - choice = NULL; + gi = NULL; pressed = FALSE; } } diff --git a/src/buttons.h b/src/buttons.h index d52b4a62..695aef6b 100644 --- a/src/buttons.h +++ b/src/buttons.h @@ -293,21 +293,23 @@ int CheckCountButtons(int, int, int); /* gadget creation tags */ #define GDI_END 0 -#define GDI_X 1 -#define GDI_Y 2 -#define GDI_WIDTH 3 -#define GDI_HEIGHT 4 -#define GDI_TYPE 5 -#define GDI_STATE 6 -#define GDI_ALT_STATE 7 -#define GDI_NUMBER_VALUE 8 -#define GDI_TEXT_VALUE 9 -#define GDI_DESIGN_UNPRESSED 10 -#define GDI_DESIGN_PRESSED 11 -#define GDI_ALT_DESIGN_UNPRESSED 12 -#define GDI_ALT_DESIGN_PRESSED 13 -#define GDI_EVENT 14 -#define GDI_CALLBACK 15 +#define GDI_ID 1 +#define GDI_X 2 +#define GDI_Y 3 +#define GDI_WIDTH 4 +#define GDI_HEIGHT 5 +#define GDI_TYPE 6 +#define GDI_STATE 7 +#define GDI_ALT_STATE 8 +#define GDI_NUMBER_VALUE 9 +#define GDI_TEXT_VALUE 10 +#define GDI_DESIGN_UNPRESSED 11 +#define GDI_DESIGN_PRESSED 12 +#define GDI_ALT_DESIGN_UNPRESSED 13 +#define GDI_ALT_DESIGN_PRESSED 14 +#define GDI_EVENT_MASK 15 +#define GDI_EVENT 16 +#define GDI_CALLBACK 17 typedef void (*gadget_callback_function)(void *); @@ -317,8 +319,15 @@ struct GadgetDesign int x, y; /* position of rectangle in Pixmap */ }; +struct GadgetEvent +{ + unsigned long type; /* event type */ + int button; /* button number for button events */ +}; + struct GadgetInfo { + int id; /* gadget identifier */ int x, y; /* gadget position */ int width, height; /* gadget size */ unsigned long type; /* type (button, text input, ...) */ @@ -329,30 +338,12 @@ struct GadgetInfo char text_value[MAX_GADGET_TEXTSIZE]; struct GadgetDesign design[2]; /* 0: normal; 1: pressed */ struct GadgetDesign alt_design[2]; /* alternative design */ - unsigned long event; /* actual gadget event */ + unsigned long event_mask; /* possible events for this gadget */ + struct GadgetEvent event; /* actual gadget event */ gadget_callback_function callback; struct GadgetInfo *next; /* next list entry */ }; - -#if 0 -struct NewGadget -{ - int x, y; /* screen position */ - int width, height; /* screen size */ - unsigned long type; /* type (button, text input, ...) */ - struct GadgetDesign *design[2]; /* 0: normal; 1: pressed */ - struct GadgetDesign *alt_design[2]; /* alternative design */ - unsigned long value_mask; /* actual gadget event */ -}; -#endif - -struct GadgetEvent -{ - unsigned long state; /* state (pressed, released, ...) */ - int x,y; /* position inside drawing area */ -}; - struct GadgetInfo *CreateGadget(int, ...); void FreeGadget(struct GadgetInfo *); diff --git a/src/editor.c b/src/editor.c index 1b40735e..96718762 100644 --- a/src/editor.c +++ b/src/editor.c @@ -38,6 +38,54 @@ /* delay value to avoid too fast scrolling etc. */ #define CHOICE_DELAY_VALUE 100 +/* 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_LINES 2 +#define ED_CTRL_ID_TEXT 3 +#define ED_CTRL_ID_RECTANGLE 4 +#define ED_CTRL_ID_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 HandleDrawingFunction(int, int, int); + +static struct GadgetInfo *control_button_gadget[ED_NUM_CTRL_BUTTONS]; +static boolean control_button_gadgets_created = FALSE; + +static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS; + static int level_xpos,level_ypos; static boolean edit_mode; static boolean name_typing; @@ -341,6 +389,336 @@ int editor_element[] = }; 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 HandlePressedControlButtons() +{ + static unsigned long button_delay = 0; + int i = 0; + + /* buttons with action when held pressed */ + int gadget_id[] = + { + ED_CTRL_ID_WRAP_UP, + ED_CTRL_ID_WRAP_LEFT, + ED_CTRL_ID_WRAP_RIGHT, + ED_CTRL_ID_WRAP_DOWN, + -1 + }; + + if (!DelayReached(&button_delay, CHOICE_DELAY_VALUE)) + return; + + while (gadget_id[i] != -1) + { + int id = gadget_id[i++]; + int state = control_button_gadget[id]->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) + { + 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; + } + } +} + +void HandleLevelEditorControlButtons(struct GadgetInfo *gi) +{ + int event_type = gi->event.type; + + /* + int button = gi->event.button; + */ + + int id; + int i, x, y; + + /* get the button id */ + for (i=0; iid == control_button_gadget[i]->id) + id = i; + + switch (id) + { + case ED_CTRL_ID_SINGLE_ITEMS: + case ED_CTRL_ID_CONNECTED_ITEMS: + case ED_CTRL_ID_LINES: + case ED_CTRL_ID_TEXT: + case ED_CTRL_ID_RECTANGLE: + case ED_CTRL_ID_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_CLEAR: + if (Request("Are you sure to clear this level ?", REQ_ASK)) + { + for(x=0; xevent == GD_EVENT_PRESSED) - printf("test_func: GD_EVENT_PRESSED\n"); - else if (gi->event == GD_EVENT_RELEASED) - printf("test_func: GD_EVENT_RELEASED\n"); - else - printf("test_func: ?\n"); -} + /* draw new control window */ + XCopyArea(display, pix[PIX_DOOR], drawto, gc, + DOOR_GFX_PAGEX8, 236, + EXSIZE, EYSIZE, + EX, EY); + redraw_mask |= REDRAW_ALL; + OpenDoor(DOOR_OPEN_1); + MapLevelEditorControlButtons(); + /* + OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2); + */ +} void DrawControlWindow() { @@ -591,59 +973,6 @@ void DrawControlWindow() int2str(level.fieldx,3),FS_SMALL,FC_YELLOW); DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE, int2str(level.fieldy,3),FS_SMALL,FC_YELLOW); - - { - Pixmap gd_pixmap = pix[PIX_DOOR]; - int gd_x1 = DOOR_GFX_PAGEX4 + ED_BUTTON_MINUS_XPOS; - int gd_x2 = DOOR_GFX_PAGEX3 + ED_BUTTON_MINUS_XPOS; - int gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS; - struct GadgetInfo *gi; - - gi = CreateGadget(GDI_X, 100, - GDI_Y, 100, - GDI_WIDTH, ED_BUTTON_MINUS_XSIZE, - GDI_HEIGHT, ED_BUTTON_MINUS_YSIZE, - GDI_TYPE, GD_TYPE_NORMAL_BUTTON, - GDI_STATE, GD_BUTTON_UNPRESSED, - GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y, - GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y, - GDI_CALLBACK, test_func, - GDI_END); - - if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); - - MapGadget(gi); - } - - -} - -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 AdjustLevelScrollPosition() @@ -663,47 +992,28 @@ void AdjustLevelScrollPosition() 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; - - /* check if starting field still has the desired content */ - if (Feld[from_x][from_y] == fill_element) - return; - - safety++; - - if (safety > lev_fieldx*lev_fieldy) - Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug."); - - 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 boolean use_floodfill = FALSE; + + + /* int x = (mx-SX)/MINI_TILEX; int y = (my-SY)/MINI_TILEY; + */ + + + HandlePressedControlButtons(); + HandleDrawingFunction(mx, my, button); if (use_floodfill) /********** FLOOD FILL **********/ { + + +#if 0 + if (button) { if (mx>=SX && mx=SY && my=SX && mx=SY && my=ED_COUNT_GADGET_XPOS && mx=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE && @@ -1312,3 +1651,232 @@ void LevelNameTyping(KeySym key) name_typing = FALSE; } } + +static void swap_numbers(int *i1, int *i2) +{ + int help = *i1; + + *i1 = *i2; + *i2 = help; +} + +static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) +{ + int help_x = *x1; + int help_y = *y1; + + *x1 = *x2; + *x2 = help_x; + + *y1 = *y2; + *y2 = help_y; +} + +static void DrawLineElement(int sx, int sy, int element) +{ + int lx = sx + level_xpos; + int ly = sy + level_ypos; + + if (element < 0) + DrawMiniElement(sx, sy, Feld[lx][ly]); + else + { + Feld[lx][ly] = element; + DrawMiniElement(sx, sy, element); + } +} + +void DrawLine(int from_x, int from_y, int to_x, int to_y, int element) +{ + if (from_y == to_y) /* horizontal line */ + { + int x; + int y = from_y; + + if (from_x > to_x) + swap_numbers(&from_x, &to_x); + + for (x=from_x; x<=to_x; x++) + DrawLineElement(x, y, element); + } + else if (from_x == to_x) /* vertical line */ + { + int x = from_x; + int y; + + if (from_y > to_y) + swap_numbers(&from_y, &to_y); + + for (y=from_y; y<=to_y; y++) + DrawLineElement(x, y, element); + } + else /* diagonal line */ + { + int len_x = ABS(to_x - from_x); + int len_y = ABS(to_y - from_y); + int x, y; + + if (len_y < len_x) /* < 45° */ + { + float a = (float)len_y / (float)len_x; + + if (from_x > to_x) + swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + + for (x=0; x= 45° */ + { + float a = (float)len_x / (float)len_y; + + if (from_y > to_y) + swap_number_pairs(&from_x, &from_y, &to_x, &to_y); + + for (y=0; y lev_fieldx*lev_fieldy) + Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug."); + + 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 HandleDrawingFunction(int mx, int my, int button) +{ + static int in_field_pressed = FALSE; + int new_element; + int sx = (mx - SX) / MINI_TILEX; + int sy = (my - SY) / MINI_TILEY; + int lx = sx + level_xpos; + int ly = sy + level_ypos; + int x, y; + + if (mx < SX || mx >= SX + SXSIZE || my < SY || my >= SY + SYSIZE) + { + /* pointer ouside drawing area */ + + if (!motion_status) /* button pressed or released outside drawing area */ + in_field_pressed = FALSE; + + return; + } + + if (button && !motion_status) + in_field_pressed = TRUE; + + if (!button || + !in_field_pressed || + button < 1 || button > 3 || + 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) + { + case ED_CTRL_ID_SINGLE_ITEMS: + if (new_element != Feld[lx][ly]) + { + if (new_element == EL_SPIELFIGUR) + { + /* remove player at old position */ + for(y=0; y= 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); + } + break; + + case ED_CTRL_ID_CONNECTED_ITEMS: + { + static int last_x = -1; + static int last_y = -1; + + if (last_x == -1) + { + Feld[lx][ly] = new_element; + DrawMiniElement(sx, sy, new_element); + + last_x = sx; + last_y = sy; + } + else if (last_x != sx || last_y != sy) + { + DrawLine(last_x, last_y, sx, sy, new_element); + + last_x = -1; + last_y = -1; + } + + /* + last_x = sx; + last_y = sy; + */ + } + break; + + case ED_CTRL_ID_FLOOD_FILL: + FloodFill(lx, ly, new_element); + DrawMiniLevel(level_xpos, level_ypos); + break; + + default: + break; + } +} diff --git a/src/editor.h b/src/editor.h index dae87c12..169fbce7 100644 --- a/src/editor.h +++ b/src/editor.h @@ -24,6 +24,7 @@ extern int element_shift; extern int editor_element[]; extern int elements_in_list; +void UnmapLevelEditorControlButtons(); void DrawLevelEd(void); void LevelEd(int, int, int); void LevelNameTyping(KeySym); diff --git a/src/events.c b/src/events.c index 2fe47e4d..53b81714 100644 --- a/src/events.c +++ b/src/events.c @@ -429,7 +429,17 @@ void HandleKey(KeySym key, int key_status) /* allow quick escape to the main menu with the Escape key */ if (key == XK_Escape && game_status != MAINMENU) { - CloseDoor(DOOR_CLOSE_1 | DOOR_NO_DELAY); + if (game_status == LEVELED) + { + /* draw smaller door */ + XCopyArea(display, pix[PIX_DOOR], drawto, gc, + DOOR_GFX_PAGEX7, 64, + 108, 64, + EX - 4, EY - 12); + redraw_mask |= REDRAW_ALL; + } + + CloseDoor(DOOR_CLOSE_1 | DOOR_OPEN_2 | DOOR_NO_DELAY); game_status = MAINMENU; DrawMainMenu(); return; diff --git a/src/main.h b/src/main.h index fed17ca6..8f2a6440 100644 --- a/src/main.h +++ b/src/main.h @@ -460,6 +460,8 @@ extern int num_bg_loops; #define DY 60 #define VX DX #define VY 400 +#define EX DX +#define EY (VY - 44) #define TILEX 32 #define TILEY 32 #define MINI_TILEX (TILEX/2) @@ -476,6 +478,8 @@ extern int num_bg_loops; #define DYSIZE 280 #define VXSIZE DXSIZE #define VYSIZE 100 +#define EXSIZE DXSIZE +#define EYSIZE (VXSIZE + 44) #define FULL_SXSIZE (2+SXSIZE+2) #define FULL_SYSIZE (2+SYSIZE+2) #define MICROLEV_XPOS (SX+4*32+16) @@ -1084,17 +1088,18 @@ extern int num_bg_loops; #endif /* values for redraw_mask */ -#define REDRAW_ALL (1L<<0) -#define REDRAW_FIELD (1L<<1) -#define REDRAW_TILES (1L<<2) -#define REDRAW_DOOR_1 (1L<<3) -#define REDRAW_VIDEO_1 (1L<<4) -#define REDRAW_VIDEO_2 (1L<<5) -#define REDRAW_VIDEO_3 (1L<<6) -#define REDRAW_MICROLEV (1L<<7) -#define REDRAW_FROM_BACKBUFFER (1L<<8) +#define REDRAW_ALL (1L << 0) +#define REDRAW_FIELD (1L << 1) +#define REDRAW_TILES (1L << 2) +#define REDRAW_DOOR_1 (1L << 3) +#define REDRAW_VIDEO_1 (1L << 4) +#define REDRAW_VIDEO_2 (1L << 5) +#define REDRAW_VIDEO_3 (1L << 6) +#define REDRAW_MICROLEV (1L << 7) +#define REDRAW_FROM_BACKBUFFER (1L << 8) #define REDRAW_DOOR_2 (REDRAW_VIDEO_1 | REDRAW_VIDEO_2 | REDRAW_VIDEO_3) -#define REDRAW_DOORS (REDRAW_DOOR_1 | REDRAW_DOOR_2) +#define REDRAW_DOOR_3 (1L << 9) +#define REDRAW_DOORS (REDRAW_DOOR_1 | REDRAW_DOOR_2 | REDRAW_DOOR_3) #define REDRAW_MAIN (REDRAW_FIELD | REDRAW_TILES | REDRAW_MICROLEV) #define REDRAWTILES_THRESHOLD SCR_FIELDX*SCR_FIELDY/2 @@ -1112,6 +1117,8 @@ extern int num_bg_loops; #define DOOR_GFX_PAGEX4 (3 * DOOR_GFX_PAGESIZE) #define DOOR_GFX_PAGEX5 (4 * DOOR_GFX_PAGESIZE) #define DOOR_GFX_PAGEX6 (5 * DOOR_GFX_PAGESIZE) +#define DOOR_GFX_PAGEX7 (6 * DOOR_GFX_PAGESIZE) +#define DOOR_GFX_PAGEX8 (7 * DOOR_GFX_PAGESIZE) #define DOOR_GFX_PAGEY1 0 #define DOOR_GFX_PAGEY2 DYSIZE diff --git a/src/screens.c b/src/screens.c index c0a3b8c6..0da69783 100644 --- a/src/screens.c +++ b/src/screens.c @@ -58,6 +58,9 @@ void DrawMainMenu() int i; char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:"); + /* needed if last screen was the level editor */ + UnmapLevelEditorControlButtons(); + FadeSounds(); GetPlayerConfig(); LoadLevel(level_nr); diff --git a/src/tools.c b/src/tools.c index d2645960..4bbe67f2 100644 --- a/src/tools.c +++ b/src/tools.c @@ -161,6 +161,10 @@ void BackToFront() VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS); } } + if (redraw_mask & REDRAW_DOOR_3) + XCopyArea(display, backbuffer, window, gc, + EX, EY, EXSIZE, EYSIZE, + EX, EY); redraw_mask &= ~REDRAW_DOORS; }