From: Holger Schemel Date: Mon, 14 Dec 1998 13:09:43 +0000 (+0100) Subject: rnd-19981214-1 X-Git-Tag: 1.3.0^2~64 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=cd47bf969c6d8c602b8f5dfa100f0be944bd0e46 rnd-19981214-1 --- diff --git a/src/buttons.c b/src/buttons.c index 62c5a1c1..d990bc13 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -11,6 +11,8 @@ * buttons.c * ***********************************************************/ +#include + #include "buttons.h" #include "tools.h" #include "misc.h" @@ -1461,3 +1463,235 @@ int CheckCountButtons(int mx, int my, int button) BackToFront(); return(return_code); } + + +/* NEW GADGET STUFF -------------------------------------------------------- */ + + +static struct GadgetInfo *gadget_list_first_entry = NULL; +static struct GadgetInfo *gadget_list_last_entry = NULL; + +static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my) +{ + struct GadgetInfo *gi = gadget_list_first_entry; + + while (gi) + { + if (mx >= gi->x && mx < gi->x + gi->width && + my >= gi->y && my < gi->y + gi->height) + break; + + gi = gi->next; + } + + return gi; +} + +struct GadgetInfo *CreateGadget(int first_tag, ...) +{ + struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo)); + int tag = first_tag; + va_list ap; + + va_start(ap, first_tag); + + /* always start with reliable default values */ + memset(new_gadget, 0, sizeof(struct GadgetInfo)); + + while (tag != GDI_END) + { + printf("tag: %d\n", tag); + + + switch(tag) + { + case GDI_X: + new_gadget->x = va_arg(ap, int); + break; + case GDI_Y: + new_gadget->y = va_arg(ap, int); + break; + case GDI_WIDTH: + new_gadget->width = va_arg(ap, int); + break; + case GDI_HEIGHT: + new_gadget->height = va_arg(ap, int); + break; + case GDI_TYPE: + new_gadget->type = va_arg(ap, unsigned long); + break; + case GDI_STATE: + new_gadget->state = va_arg(ap, unsigned long); + break; + case GDI_ALT_STATE: + new_gadget->state = va_arg(ap, boolean); + break; + case GDI_NUMBER_VALUE: + new_gadget->number_value = va_arg(ap, long); + break; + case GDI_TEXT_VALUE: + strcpy(new_gadget->text_value, va_arg(ap, char *)); + break; + case GDI_DESIGN_UNPRESSED: + new_gadget->design[GD_BUTTON_UNPRESSED].pixmap = va_arg(ap, Pixmap); + new_gadget->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + new_gadget->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + break; + case GDI_DESIGN_PRESSED: + new_gadget->design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); + new_gadget->design[GD_BUTTON_PRESSED].x = va_arg(ap, int); + new_gadget->design[GD_BUTTON_PRESSED].y = va_arg(ap, int); + break; + case GDI_ALT_DESIGN_UNPRESSED: + new_gadget->alt_design[GD_BUTTON_UNPRESSED].pixmap= va_arg(ap, Pixmap); + new_gadget->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + new_gadget->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + break; + case GDI_ALT_DESIGN_PRESSED: + new_gadget->alt_design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); + 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_CALLBACK: + new_gadget->callback = va_arg(ap, gadget_callback_function); + break; + + default: + Error(ERR_EXIT, "CreateGadget(): unknown tag %d", tag); + } + + tag = va_arg(ap, int); /* read next tag */ + } + + va_end(ap); + + /* check if gadget complete */ + if (!new_gadget->design[GD_BUTTON_UNPRESSED].pixmap || + !new_gadget->design[GD_BUTTON_PRESSED].pixmap) + Error(ERR_EXIT, "gadget incomplete (missing Pixmap)"); + + /* insert new gadget into gloabl gadget list */ + + if (gadget_list_last_entry) + { + gadget_list_last_entry->next = new_gadget; + gadget_list_last_entry = gadget_list_last_entry->next; + } + else + { + gadget_list_first_entry = gadget_list_last_entry = new_gadget; + } + + return new_gadget; +} + +void FreeGadget(struct GadgetInfo *gi) +{ + struct GadgetInfo *gi_previous = gadget_list_first_entry; + + while (gi_previous && gi_previous->next != gi) + gi_previous = gi_previous->next; + + if (gi == gadget_list_first_entry) + gadget_list_first_entry = gi->next; + + if (gi == gadget_list_last_entry) + gadget_list_last_entry = gi_previous; + + gi_previous->next = gi->next; + free(gi); +} + +static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) +{ + int state = (pressed ? 1 : 0); + struct GadgetDesign *gd = (gi->alt_state ? + &gi->alt_design[state] : + &gi->design[state]); + + XCopyArea(display, gd->pixmap, 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); +} + +void UnmapGadget(struct GadgetInfo *gi) +{ + gi->mapped = FALSE; +} + +void HandleGadgets(int mx, int my, int button) +{ + static struct GadgetInfo *choice = NULL; + static boolean pressed = FALSE; + struct GadgetInfo *new_choice; + + if (gadget_list_first_entry == NULL) + return; + + new_choice = getGadgetInfoFromMousePosition(mx,my); + + if (button) + { + if (!motion_status) /* mouse button just pressed */ + { + if (new_choice != NULL) + { + choice = new_choice; + choice->state = GD_BUTTON_PRESSED; + choice->event = GD_EVENT_PRESSED; + DrawGadget(choice, TRUE, TRUE); + choice->callback(choice); + pressed = TRUE; + } + } + else /* mouse movement with pressed mouse button */ + { + if ((new_choice == NULL || new_choice != choice) && + choice != NULL && pressed) + { + choice->state = GD_BUTTON_UNPRESSED; + DrawGadget(choice, FALSE, TRUE); + pressed = FALSE; + } + else if (new_choice != NULL && new_choice == choice) + { + if (!pressed) + DrawGadget(choice, TRUE, TRUE); + choice->state = GD_BUTTON_PRESSED; + + /* + choice->callback(choice); + */ + + pressed = TRUE; + } + } + } + else /* mouse button just released */ + { + if (new_choice != NULL && new_choice == choice && pressed) + { + choice->state = GD_BUTTON_UNPRESSED; + choice->event = GD_EVENT_RELEASED; + DrawGadget(choice, FALSE, TRUE); + choice->callback(choice); + choice = NULL; + pressed = FALSE; + } + else + { + choice = NULL; + pressed = FALSE; + } + } +} diff --git a/src/buttons.h b/src/buttons.h index 8111aaeb..d52b4a62 100644 --- a/src/buttons.h +++ b/src/buttons.h @@ -264,4 +264,101 @@ int CheckCtrlButtons(int, int, int); int CheckElemButtons(int, int, int); int CheckCountButtons(int, int, int); + +/* NEW GADGET STUFF -------------------------------------------------------- */ + + +/* gadget types */ +#define GD_TYPE_NORMAL_BUTTON (1<<0) +#define GD_TYPE_TWO_STATE_BUTTON (1<<1) +#define GD_TYPE_DRAWING_AREA (1<<2) +#define GD_TYPE_TEXTINPUT (1<<3) +#define GD_TYPE_TEXTOUTPUT (1<<4) +#define GD_TYPE_NUMBERINPUT (1<<5) +#define GD_TYPE_NUMBEROUTPUT (1<<6) +#define GD_TYPE_SCROLLBAR_VERTICAL (1<<7) +#define GD_TYPE_SCROLLBAR_HORIZONTAL (1<<8) + +/* gadget events */ +#define GD_EVENT_PRESSED (1<<0) +#define GD_EVENT_RELEASED (1<<1) +#define GD_EVENT_MOVING (1<<2) + +/* gadget button states */ +#define GD_BUTTON_UNPRESSED 0 +#define GD_BUTTON_PRESSED 1 + +/* gadget structure constants */ +#define MAX_GADGET_TEXTSIZE 1024 + +/* 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 + +typedef void (*gadget_callback_function)(void *); + +struct GadgetDesign +{ + Pixmap pixmap; /* Pixmap with gadget surface */ + int x, y; /* position of rectangle in Pixmap */ +}; + +struct GadgetInfo +{ + int x, y; /* gadget position */ + int width, height; /* gadget size */ + unsigned long type; /* type (button, text input, ...) */ + unsigned long state; /* state (pressed, released, ...) */ + boolean alt_state; /* alternative state */ + boolean mapped; /* gadget is active */ + long number_value; + 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 */ + 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 *); + +void MapGadget(struct GadgetInfo *); +void UnmapGadget(struct GadgetInfo *); + +void HandleGadgets(int, int, int); + #endif diff --git a/src/editor.c b/src/editor.c index 2955faec..1b40735e 100644 --- a/src/editor.c +++ b/src/editor.c @@ -419,6 +419,22 @@ void DrawLevelEd() OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2); } + + +void test_func(struct GadgetInfo *gi) +{ + if (gi->event == 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"); +} + + + + + void DrawControlWindow() { int i,x,y; @@ -575,6 +591,32 @@ 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) diff --git a/src/events.c b/src/events.c index 2d8eca3e..2fe47e4d 100644 --- a/src/events.c +++ b/src/events.c @@ -20,6 +20,7 @@ #include "misc.h" #include "tape.h" #include "joystick.h" +#include "buttons.h" #include "network.h" /* values for key_status */ @@ -279,6 +280,7 @@ void HandleButton(int mx, int my, int button) old_mx = mx; old_my = my; + HandleGadgets(mx,my, button); HandleVideoButtons(mx,my, button); HandleSoundButtons(mx,my, button); HandleGameButtons(mx,my, button); diff --git a/src/game.c b/src/game.c index 64a7c1aa..9897b56d 100644 --- a/src/game.c +++ b/src/game.c @@ -103,7 +103,7 @@ int game_emulation = EMU_NONE; #ifdef DEBUG -#if 1 +#if 0 static unsigned int getStateCheckSum(int counter) { int x, y; @@ -3250,7 +3250,7 @@ void GameActions() #ifdef DEBUG - + /* if (TimeFrames == 0 && !local_player->gone) { extern unsigned int last_RND(); @@ -3260,7 +3260,7 @@ void GameActions() last_RND(), getStateCheckSum(level.time - TimeLeft)); } - + */ #endif