From: Holger Schemel Date: Fri, 1 Dec 2000 18:22:24 +0000 (+0100) Subject: rnd-20001201-1-src X-Git-Tag: 2.0.0^2~24 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=da14f69fd95c7bd5a0d70cdf4935af06f1f20a04;p=rocksndiamonds.git rnd-20001201-1-src --- diff --git a/Makefile b/Makefile index cf775274..e058339a 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ SRC_DIR = src MAKE_CMD = $(MAKE) -C $(SRC_DIR) all: - @$(MAKE_CMD) TARGET=sdl + @$(MAKE_CMD) TARGET=x11 x11: @$(MAKE_CMD) TARGET=x11 diff --git a/src/Makefile b/src/Makefile index cc8e1df0..6bf31b87 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,6 +3,8 @@ # (c) 1995-2000 Holger Schemel, info@artsoft.org # #=============================================================================# +.EXPORT_ALL_VARIABLES: + ifndef PLATFORM # platform not specified -- try auto detection ifdef COMSPEC PLATFORM = msdos @@ -18,6 +20,8 @@ X11_INCL = -I$(XINC_PATH) X11_LIBS = -L$(XLIB_PATH) endif +AR = ar +RANLIB = ranlib ifeq ($(PLATFORM),msdos) # MS-DOS native compiling @@ -98,66 +102,56 @@ OPTIONS = $(DEBUG) -Wall # only for debugging purposes CFLAGS = $(OPTIONS) $(SYS_CFLAGS) $(CONFIG) LDFLAGS = $(SYS_LDFLAGS) $(EXTRA_LDFLAGS) -lm + SRCS = main.c \ init.c \ events.c \ tools.c \ screens.c \ - misc.c \ game.c \ editor.c \ - buttons.c \ files.c \ tape.c \ - sound.c \ joystick.c \ cartoons.c \ - random.c \ - pcx.c \ - image.c \ network.c \ - netserv.c \ - msdos.c \ - system.c \ - x11.c \ - sdl.c + netserv.c OBJS = main.o \ init.o \ events.o \ tools.o \ screens.o \ - misc.o \ game.o \ editor.o \ - buttons.o \ files.o \ tape.o \ - sound.o \ joystick.o \ cartoons.o \ - random.o \ - pcx.o \ - image.o \ network.o \ - netserv.o \ - msdos.o \ - system.o \ - x11.o \ - sdl.o + netserv.o + +LIBDIR = libgame +LIBGAME = $(LIBDIR)/libgame.a + -all: $(PROGNAME) +all: $(PROGNAME) -$(PROGNAME): $(OBJS) - $(CC) $(PROFILING) $(OBJS) $(LDFLAGS) -o $(PROGNAME) +$(PROGNAME): $(LIBGAME) $(OBJS) + $(CC) $(PROFILING) $(OBJS) $(LIBGAME) $(LDFLAGS) -o $(PROGNAME) + +$(LIBGAME): + $(MAKE) -C $(LIBDIR) .c.o: $(CC) $(PROFILING) $(CFLAGS) -c $*.c clean: - $(RM) *.o - $(RM) ../*.exe + $(MAKE) -C $(LIBDIR) clean + $(RM) $(OBJS) + $(RM) $(LIBGAME) $(RM) $(PROGNAME) + $(RM) ../*.exe #-----------------------------------------------------------------------------# @@ -165,6 +159,7 @@ clean: #-----------------------------------------------------------------------------# depend: + $(MAKE) -C $(LIBDIR) depend for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend ifeq (.depend,$(wildcard .depend)) diff --git a/src/buttons.c b/src/buttons.c deleted file mode 100644 index 88ff994e..00000000 --- a/src/buttons.c +++ /dev/null @@ -1,1345 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* buttons.c * -***********************************************************/ - -#include - -#include "buttons.h" -#include "tools.h" -#include "misc.h" -#include "editor.h" -#include "tape.h" - -/* some positions in the video tape control window */ -#define VIDEO_DATE_LABEL_XPOS (VIDEO_DISPLAY1_XPOS) -#define VIDEO_DATE_LABEL_YPOS (VIDEO_DISPLAY1_YPOS) -#define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE) -#define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE) -#define VIDEO_DATE_XPOS (VIDEO_DISPLAY1_XPOS + 1) -#define VIDEO_DATE_YPOS (VIDEO_DISPLAY1_YPOS + 14) -#define VIDEO_DATE_XSIZE (VIDEO_DISPLAY_XSIZE) -#define VIDEO_DATE_YSIZE 16 -#define VIDEO_REC_LABEL_XPOS (VIDEO_DISPLAY2_XPOS) -#define VIDEO_REC_LABEL_YPOS (VIDEO_DISPLAY2_YPOS) -#define VIDEO_REC_LABEL_XSIZE 20 -#define VIDEO_REC_LABEL_YSIZE 12 -#define VIDEO_REC_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 20) -#define VIDEO_REC_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) -#define VIDEO_REC_SYMBOL_XSIZE 16 -#define VIDEO_REC_SYMBOL_YSIZE 16 -#define VIDEO_PLAY_LABEL_XPOS (VIDEO_DISPLAY2_XPOS + 65) -#define VIDEO_PLAY_LABEL_YPOS (VIDEO_DISPLAY2_YPOS) -#define VIDEO_PLAY_LABEL_XSIZE 22 -#define VIDEO_PLAY_LABEL_YSIZE 12 -#define VIDEO_PLAY_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 52) -#define VIDEO_PLAY_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) -#define VIDEO_PLAY_SYMBOL_XSIZE 11 -#define VIDEO_PLAY_SYMBOL_YSIZE 13 -#define VIDEO_PAUSE_LABEL_XPOS (VIDEO_DISPLAY2_XPOS) -#define VIDEO_PAUSE_LABEL_YPOS (VIDEO_DISPLAY2_YPOS + 20) -#define VIDEO_PAUSE_LABEL_XSIZE 35 -#define VIDEO_PAUSE_LABEL_YSIZE 8 -#define VIDEO_PAUSE_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 35) -#define VIDEO_PAUSE_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) -#define VIDEO_PAUSE_SYMBOL_XSIZE 17 -#define VIDEO_PAUSE_SYMBOL_YSIZE 13 -#define VIDEO_TIME_XPOS (VIDEO_DISPLAY2_XPOS + 38) -#define VIDEO_TIME_YPOS (VIDEO_DISPLAY2_YPOS + 14) -#define VIDEO_TIME_XSIZE 50 -#define VIDEO_TIME_YSIZE 16 - -/* special */ -#define VIDEO_PBEND_LABEL_XPOS 6 -#define VIDEO_PBEND_LABEL_YPOS 220 -#define VIDEO_PBEND_LABEL_XSIZE 35 -#define VIDEO_PBEND_LABEL_YSIZE 30 - -#define VIDEO_STATE_OFF (VIDEO_STATE_PLAY_OFF | \ - VIDEO_STATE_REC_OFF | \ - VIDEO_STATE_PAUSE_OFF | \ - VIDEO_STATE_FFWD_OFF | \ - VIDEO_STATE_PBEND_OFF | \ - VIDEO_STATE_DATE_OFF | \ - VIDEO_STATE_TIME_OFF) -#define VIDEO_PRESS_OFF (VIDEO_PRESS_PLAY_OFF | \ - VIDEO_PRESS_REC_OFF | \ - VIDEO_PRESS_PAUSE_OFF | \ - VIDEO_PRESS_STOP_OFF | \ - VIDEO_PRESS_EJECT_OFF) -#define VIDEO_ALL_OFF (VIDEO_STATE_OFF | VIDEO_PRESS_OFF) - -#define VIDEO_STATE_ON (VIDEO_STATE_PLAY_ON | \ - VIDEO_STATE_REC_ON | \ - VIDEO_STATE_PAUSE_ON | \ - VIDEO_STATE_FFWD_ON | \ - VIDEO_STATE_PBEND_ON | \ - VIDEO_STATE_DATE_ON | \ - VIDEO_STATE_TIME_ON) -#define VIDEO_PRESS_ON (VIDEO_PRESS_PLAY_ON | \ - VIDEO_PRESS_REC_ON | \ - VIDEO_PRESS_PAUSE_ON | \ - VIDEO_PRESS_STOP_ON | \ - VIDEO_PRESS_EJECT_ON) -#define VIDEO_ALL_ON (VIDEO_STATE_ON | VIDEO_PRESS_ON) - -#define VIDEO_STATE (VIDEO_STATE_ON | VIDEO_STATE_OFF) -#define VIDEO_PRESS (VIDEO_PRESS_ON | VIDEO_PRESS_OFF) -#define VIDEO_ALL (VIDEO_ALL_ON | VIDEO_ALL_OFF) - - -void DrawVideoDisplay(unsigned long state, unsigned long value) -{ - int i; - int part_label = 0, part_symbol = 1; - int xpos = 0, ypos = 1, xsize = 2, ysize = 3; - static char *monatsname[12] = - { - "JAN", "FEB", "MAR", "APR", "MAY", "JUN", - "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" - }; - static int video_pos[5][2][4] = - { - {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS, - VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE }, - { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS, - VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }}, - - {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS, - VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE }, - { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS, - VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }}, - - {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS, - VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE }, - { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS, - VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }}, - - {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS, - VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE }, - { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS, - VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }}, - - {{ 0,0, - 0,0 }, - { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS, - VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }} - }; - - if (state & VIDEO_STATE_PBEND_OFF) - { - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - BlitBitmap(pix[PIX_DOOR], drawto, - cx + VIDEO_REC_LABEL_XPOS, - cy + VIDEO_REC_LABEL_YPOS, - VIDEO_PBEND_LABEL_XSIZE, - VIDEO_PBEND_LABEL_YSIZE, - VX + VIDEO_REC_LABEL_XPOS, - VY + VIDEO_REC_LABEL_YPOS); - } - - for(i=0;i<10;i++) - { - if (state & (1< STATE_ON / PRESS_OFF */ - cx = DOOR_GFX_PAGEX4; - else - cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */ - - if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY) - BlitBitmap(pix[PIX_DOOR], drawto, - cx + video_pos[pos][part_label][xpos], - cy + video_pos[pos][part_label][ypos], - video_pos[pos][part_label][xsize], - video_pos[pos][part_label][ysize], - VX + video_pos[pos][part_label][xpos], - VY + video_pos[pos][part_label][ypos]); - if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(pix[PIX_DOOR], drawto, - cx + video_pos[pos][part_symbol][xpos], - cy + video_pos[pos][part_symbol][ypos], - video_pos[pos][part_symbol][xsize], - video_pos[pos][part_symbol][ysize], - VX + video_pos[pos][part_symbol][xpos], - VY + video_pos[pos][part_symbol][ypos]); - } - } - - if (state & VIDEO_STATE_FFWD_ON) - { - int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2; - - BlitBitmap(pix[PIX_DOOR], drawto, - cx + VIDEO_PLAY_SYMBOL_XPOS, - cy + VIDEO_PLAY_SYMBOL_YPOS, - VIDEO_PLAY_SYMBOL_XSIZE - 2, - VIDEO_PLAY_SYMBOL_YSIZE, - VX + VIDEO_PLAY_SYMBOL_XPOS - 9, - VY + VIDEO_PLAY_SYMBOL_YPOS); - } - - if (state & VIDEO_STATE_PBEND_ON) - { - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - - BlitBitmap(pix[PIX_DOOR], drawto, - cx + VIDEO_PBEND_LABEL_XPOS, - cy + VIDEO_PBEND_LABEL_YPOS, - VIDEO_PBEND_LABEL_XSIZE, - VIDEO_PBEND_LABEL_YSIZE, - VX + VIDEO_REC_LABEL_XPOS, - VY + VIDEO_REC_LABEL_YPOS); - } - - if (state & VIDEO_STATE_DATE_ON) - { - int tag = value % 100; - int monat = (value/100) % 100; - int jahr = (value/10000); - - DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS, - int2str(tag,2),FS_SMALL,FC_SPECIAL1); - DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS, - monatsname[monat],FS_SMALL,FC_SPECIAL1); - DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS, - int2str(jahr,2),FS_SMALL,FC_SPECIAL1); - } - - if (state & VIDEO_STATE_TIME_ON) - { - int min = value / 60; - int sec = value % 60; - - DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS, - int2str(min,2),FS_SMALL,FC_SPECIAL1); - DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS, - int2str(sec,2),FS_SMALL,FC_SPECIAL1); - } - - if (state & VIDEO_STATE_DATE) - redraw_mask |= REDRAW_VIDEO_1; - if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE) - redraw_mask |= REDRAW_VIDEO_2; - if (state & VIDEO_PRESS) - redraw_mask |= REDRAW_VIDEO_3; -} - -void DrawCompleteVideoDisplay() -{ - BlitBitmap(pix[PIX_DOOR], drawto, - DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY); - BlitBitmap(pix[PIX_DOOR], drawto, - DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS, - DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS, - VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE, - VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS); - - DrawVideoDisplay(VIDEO_ALL_OFF,0); - if (tape.date && tape.length) - { - DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); - DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds); - } - - BlitBitmap(drawto, pix[PIX_DB_DOOR], - VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2); -} - - -/* NEW GADGET STUFF -------------------------------------------------------- */ - - -/* values for DrawGadget() */ -#define DG_UNPRESSED 0 -#define DG_PRESSED 1 -#define DG_BUFFERED 0 -#define DG_DIRECT 1 - -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) -{ - struct GadgetInfo *gi = gadget_list_first_entry; - - while (gi) - { - if (gi->mapped && - mx >= gi->x && mx < gi->x + gi->width && - my >= gi->y && my < gi->y + gi->height) - break; - - gi = gi->next; - } - - return gi; -} - -static void default_callback_info(void *ptr) -{ - if (game_status == LEVELED) - HandleEditorGadgetInfoText(ptr); -} - -static void default_callback_action(void *ptr) -{ - return; -} - -static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) -{ - int state = (pressed ? 1 : 0); - struct GadgetDesign *gd = (gi->checked ? - &gi->alt_design[state] : - &gi->design[state]); - - switch (gi->type) - { - case GD_TYPE_NORMAL_BUTTON: - case GD_TYPE_CHECK_BUTTON: - case GD_TYPE_RADIO_BUTTON: - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); - if (gi->deco.design.bitmap) - BlitBitmap(gi->deco.design.bitmap, drawto, - gi->deco.design.x, gi->deco.design.y, - gi->deco.width, gi->deco.height, - gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0), - gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0)); - break; - - case GD_TYPE_TEXTINPUT_ALPHANUMERIC: - case GD_TYPE_TEXTINPUT_NUMERIC: - { - int i; - char cursor_letter; - char cursor_string[3]; - char text[MAX_GADGET_TEXTSIZE + 1]; - int font_type = gi->text.font_type; - int font_width = getFontWidth(FS_SMALL, font_type); - int border = gi->border.size; - strcpy(text, gi->text.value); - strcat(text, " "); - - /* left part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, border, gi->height, gi->x, gi->y); - - /* middle part of gadget */ - for (i=0; i<=gi->text.size; i++) - BlitBitmap(gd->bitmap, drawto, - gd->x + border, gd->y, font_width, gi->height, - gi->x + border + i * font_width, gi->y); - - /* right part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x + gi->border.width - border, gd->y, - border, gi->height, gi->x + gi->width - border, gi->y); - - /* gadget text value */ - DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type); - - cursor_letter = gi->text.value[gi->text.cursor_position]; - cursor_string[0] = '~'; - cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' '); - cursor_string[2] = '\0'; - - /* draw cursor, if active */ - if (pressed) - DrawText(gi->x + border + gi->text.cursor_position * font_width, - gi->y + border, cursor_string, FS_SMALL, font_type); - } - break; - - case GD_TYPE_SCROLLBAR_VERTICAL: - { - int i; - int xpos = gi->x; - int ypos = gi->y + gi->scrollbar.position; - int design_full = gi->width; - int design_body = design_full - 2 * gi->border.size; - int size_full = gi->scrollbar.size; - int size_body = size_full - 2 * gi->border.size; - int num_steps = size_body / design_body; - int step_size_remain = size_body - num_steps * design_body; - - /* clear scrollbar area */ - ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height); - - /* upper part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, - gi->width, gi->border.size, - xpos, ypos); - - /* middle part of gadget */ - for (i=0; ibitmap, drawto, - gd->x, gd->y + gi->border.size, - gi->width, design_body, - xpos, ypos + gi->border.size + i * design_body); - - /* remaining middle part of gadget */ - if (step_size_remain > 0) - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y + gi->border.size, - gi->width, step_size_remain, - xpos, ypos + gi->border.size + num_steps * design_body); - - /* lower part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y + design_full - gi->border.size, - gi->width, gi->border.size, - xpos, ypos + size_full - gi->border.size); - } - break; - - case GD_TYPE_SCROLLBAR_HORIZONTAL: - { - int i; - int xpos = gi->x + gi->scrollbar.position; - int ypos = gi->y; - int design_full = gi->height; - int design_body = design_full - 2 * gi->border.size; - int size_full = gi->scrollbar.size; - int size_body = size_full - 2 * gi->border.size; - int num_steps = size_body / design_body; - int step_size_remain = size_body - num_steps * design_body; - - /* clear scrollbar area */ - ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height); - - /* left part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x, gd->y, - gi->border.size, gi->height, - xpos, ypos); - - /* middle part of gadget */ - for (i=0; ibitmap, drawto, - gd->x + gi->border.size, gd->y, - design_body, gi->height, - xpos + gi->border.size + i * design_body, ypos); - - /* remaining middle part of gadget */ - if (step_size_remain > 0) - BlitBitmap(gd->bitmap, drawto, - gd->x + gi->border.size, gd->y, - step_size_remain, gi->height, - xpos + gi->border.size + num_steps * design_body, ypos); - - /* right part of gadget */ - BlitBitmap(gd->bitmap, drawto, - gd->x + design_full - gi->border.size, gd->y, - gi->border.size, gi->height, - xpos + size_full - gi->border.size, ypos); - } - break; - - default: - return; - } - - if (direct) - BlitBitmap(drawto, window, - gi->x, gi->y, gi->width, gi->height, gi->x, gi->y); - else - redraw_mask |= (gi->x < SX + SXSIZE ? REDRAW_FIELD : - gi->y < DY + DYSIZE ? REDRAW_DOOR_1 : - gi->y > VY ? REDRAW_DOOR_2 : REDRAW_DOOR_3); -} - -static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) -{ - int tag = first_tag; - - while (tag != GDI_END) - { - switch(tag) - { - case GDI_CUSTOM_ID: - gi->custom_id = va_arg(ap, int); - break; - - case GDI_CUSTOM_TYPE_ID: - gi->custom_type_id = va_arg(ap, int); - break; - - case GDI_INFO_TEXT: - { - int max_textsize = MAX_INFO_TEXTSIZE - 1; - - strncpy(gi->info_text, va_arg(ap, char *), max_textsize); - gi->info_text[max_textsize] = '\0'; - } - break; - - case GDI_X: - gi->x = va_arg(ap, int); - break; - - case GDI_Y: - gi->y = va_arg(ap, int); - break; - - case GDI_WIDTH: - gi->width = va_arg(ap, int); - break; - - case GDI_HEIGHT: - gi->height = va_arg(ap, int); - break; - - case GDI_TYPE: - gi->type = va_arg(ap, unsigned long); - break; - - case GDI_STATE: - gi->state = va_arg(ap, unsigned long); - break; - - case GDI_CHECKED: - gi->checked = va_arg(ap, boolean); - break; - - case GDI_RADIO_NR: - gi->radio_nr = va_arg(ap, unsigned long); - break; - - case GDI_NUMBER_VALUE: - gi->text.number_value = va_arg(ap, long); - sprintf(gi->text.value, "%d", gi->text.number_value); - gi->text.cursor_position = strlen(gi->text.value); - break; - - case GDI_NUMBER_MIN: - gi->text.number_min = va_arg(ap, long); - if (gi->text.number_value < gi->text.number_min) - { - gi->text.number_value = gi->text.number_min; - sprintf(gi->text.value, "%d", gi->text.number_value); - } - break; - - case GDI_NUMBER_MAX: - gi->text.number_max = va_arg(ap, long); - if (gi->text.number_value > gi->text.number_max) - { - gi->text.number_value = gi->text.number_max; - sprintf(gi->text.value, "%d", gi->text.number_value); - } - break; - - case GDI_TEXT_VALUE: - { - int max_textsize = MAX_GADGET_TEXTSIZE; - - if (gi->text.size) - max_textsize = MIN(gi->text.size, MAX_GADGET_TEXTSIZE - 1); - - strncpy(gi->text.value, va_arg(ap, char *), max_textsize); - gi->text.value[max_textsize] = '\0'; - gi->text.cursor_position = strlen(gi->text.value); - } - break; - - case GDI_TEXT_SIZE: - { - int tag_value = va_arg(ap, int); - int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1); - - gi->text.size = max_textsize; - gi->text.value[max_textsize] = '\0'; - } - break; - - case GDI_TEXT_FONT: - gi->text.font_type = va_arg(ap, int); - break; - - case GDI_DESIGN_UNPRESSED: - gi->design[GD_BUTTON_UNPRESSED].bitmap = va_arg(ap, Bitmap); - gi->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); - gi->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); - break; - - case GDI_DESIGN_PRESSED: - gi->design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap); - gi->design[GD_BUTTON_PRESSED].x = va_arg(ap, int); - gi->design[GD_BUTTON_PRESSED].y = va_arg(ap, int); - break; - - case GDI_ALT_DESIGN_UNPRESSED: - gi->alt_design[GD_BUTTON_UNPRESSED].bitmap= va_arg(ap, Bitmap); - gi->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); - gi->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); - break; - - case GDI_ALT_DESIGN_PRESSED: - gi->alt_design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap); - gi->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int); - gi->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int); - break; - - case GDI_BORDER_SIZE: - gi->border.size = va_arg(ap, int); - break; - - case GDI_TEXTINPUT_DESIGN_WIDTH: - gi->border.width = va_arg(ap, int); - break; - - case GDI_DECORATION_DESIGN: - gi->deco.design.bitmap = va_arg(ap, Bitmap); - gi->deco.design.x = va_arg(ap, int); - gi->deco.design.y = va_arg(ap, int); - break; - - case GDI_DECORATION_POSITION: - gi->deco.x = va_arg(ap, int); - gi->deco.y = va_arg(ap, int); - break; - - case GDI_DECORATION_SIZE: - gi->deco.width = va_arg(ap, int); - gi->deco.height = va_arg(ap, int); - break; - - case GDI_DECORATION_SHIFTING: - gi->deco.xshift = va_arg(ap, int); - gi->deco.yshift = va_arg(ap, int); - break; - - case GDI_EVENT_MASK: - gi->event_mask = va_arg(ap, unsigned long); - break; - - case GDI_AREA_SIZE: - gi->drawing.area_xsize = va_arg(ap, int); - gi->drawing.area_ysize = va_arg(ap, int); - - /* determine dependent values for drawing area gadget, if needed */ - if (gi->width == 0 && gi->height == 0 && - gi->drawing.item_xsize !=0 && gi->drawing.item_ysize !=0) - { - gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; - gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; - } - else if (gi->drawing.item_xsize == 0 && gi->drawing.item_ysize == 0 && - gi->width != 0 && gi->height != 0) - { - gi->drawing.item_xsize = gi->width / gi->drawing.area_xsize; - gi->drawing.item_ysize = gi->height / gi->drawing.area_ysize; - } - break; - - case GDI_ITEM_SIZE: - gi->drawing.item_xsize = va_arg(ap, int); - gi->drawing.item_ysize = va_arg(ap, int); - - /* determine dependent values for drawing area gadget, if needed */ - if (gi->width == 0 && gi->height == 0 && - gi->drawing.area_xsize !=0 && gi->drawing.area_ysize !=0) - { - gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; - gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; - } - else if (gi->drawing.area_xsize == 0 && gi->drawing.area_ysize == 0 && - gi->width != 0 && gi->height != 0) - { - gi->drawing.area_xsize = gi->width / gi->drawing.item_xsize; - gi->drawing.area_ysize = gi->height / gi->drawing.item_ysize; - } - break; - - case GDI_SCROLLBAR_ITEMS_MAX: - gi->scrollbar.items_max = va_arg(ap, int); - break; - - case GDI_SCROLLBAR_ITEMS_VISIBLE: - gi->scrollbar.items_visible = va_arg(ap, int); - break; - - case GDI_SCROLLBAR_ITEM_POSITION: - gi->scrollbar.item_position = va_arg(ap, int); - break; - - case GDI_CALLBACK_INFO: - gi->callback_info = va_arg(ap, gadget_function); - break; - - case GDI_CALLBACK_ACTION: - gi->callback_action = va_arg(ap, gadget_function); - break; - - default: - Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag); - } - - tag = va_arg(ap, int); /* read next tag */ - } - - /* check if gadget complete */ - if (gi->type != GD_TYPE_DRAWING_AREA && - (!gi->design[GD_BUTTON_UNPRESSED].bitmap || - !gi->design[GD_BUTTON_PRESSED].bitmap)) - Error(ERR_EXIT, "gadget incomplete (missing Bitmap)"); - - /* adjust gadget values in relation to other gadget values */ - - if (gi->type & GD_TYPE_TEXTINPUT) - { - int font_width = getFontWidth(FS_SMALL, gi->text.font_type); - int font_height = getFontHeight(FS_SMALL, gi->text.font_type); - - gi->width = 2 * gi->border.size + (gi->text.size + 1) * font_width; - gi->height = 2 * gi->border.size + font_height; - } - - if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC) - { - struct GadgetTextInput *text = &gi->text; - int value = text->number_value; - - text->number_value = (value < text->number_min ? text->number_min : - value > text->number_max ? text->number_max : - value); - - sprintf(text->value, "%d", text->number_value); - } - - if (gi->type & GD_TYPE_SCROLLBAR) - { - struct GadgetScrollbar *gs = &gi->scrollbar; - - if (gi->width == 0 || gi->height == 0 || - gs->items_max == 0 || gs->items_visible == 0) - Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)"); - - /* calculate internal scrollbar values */ - gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? - gi->height : gi->width); - gs->size = gs->size_max * gs->items_visible / gs->items_max; - gs->position = gs->size_max * gs->item_position / gs->items_max; - gs->position_max = gs->size_max - gs->size; - gs->correction = gs->size_max / gs->items_max / 2; - - /* finetuning for maximal right/bottom position */ - if (gs->item_position == gs->items_max - gs->items_visible) - gs->position = gs->position_max; - } -} - -void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...) -{ - va_list ap; - - va_start(ap, first_tag); - HandleGadgetTags(gi, first_tag, ap); - va_end(ap); - - RedrawGadget(gi); -} - -void RedrawGadget(struct GadgetInfo *gi) -{ - if (gi->mapped) - DrawGadget(gi, gi->state, DG_DIRECT); -} - -struct GadgetInfo *CreateGadget(int first_tag, ...) -{ - struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo)); - va_list ap; - - /* always start with reliable default values */ - memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */ - new_gadget->id = getNewGadgetID(); - new_gadget->callback_info = default_callback_info; - new_gadget->callback_action = default_callback_action; - - va_start(ap, first_tag); - HandleGadgetTags(new_gadget, first_tag, ap); - va_end(ap); - - /* insert new gadget into global 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 CheckRangeOfNumericInputGadget(struct GadgetInfo *gi) -{ - if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC) - return; - - gi->text.number_value = atoi(gi->text.value); - - if (gi->text.number_value < gi->text.number_min) - gi->text.number_value = gi->text.number_min; - if (gi->text.number_value > gi->text.number_max) - gi->text.number_value = gi->text.number_max; - - sprintf(gi->text.value, "%d", gi->text.number_value); - - if (gi->text.cursor_position < 0) - gi->text.cursor_position = 0; - else if (gi->text.cursor_position > strlen(gi->text.value)) - gi->text.cursor_position = strlen(gi->text.value); -} - -/* global pointer to gadget actually in use (when mouse button pressed) */ -static struct GadgetInfo *last_gi = NULL; - -static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw) -{ - if (gi == NULL || gi->mapped) - return; - - gi->mapped = TRUE; - - if (redraw) - DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED); -} - -void MapGadget(struct GadgetInfo *gi) -{ - MapGadgetExt(gi, TRUE); -} - -void UnmapGadget(struct GadgetInfo *gi) -{ - if (gi == NULL || !gi->mapped) - return; - - gi->mapped = FALSE; - - if (gi == last_gi) - last_gi = NULL; -} - -#define MAX_NUM_GADGETS 1024 -#define MULTIMAP_UNMAP (1 << 0) -#define MULTIMAP_REMAP (1 << 1) -#define MULTIMAP_REDRAW (1 << 2) -#define MULTIMAP_PLAYFIELD (1 << 3) -#define MULTIMAP_DOOR_1 (1 << 4) -#define MULTIMAP_DOOR_2 (1 << 5) -#define MULTIMAP_ALL (MULTIMAP_PLAYFIELD | \ - MULTIMAP_DOOR_1 | \ - MULTIMAP_DOOR_2) - -static void MultiMapGadgets(int mode) -{ - struct GadgetInfo *gi = gadget_list_first_entry; - static boolean map_state[MAX_NUM_GADGETS]; - int map_count = 0; - - while (gi) - { - if ((mode & MULTIMAP_PLAYFIELD && gi->x < SX + SXSIZE) || - (mode & MULTIMAP_DOOR_1 && gi->x >= DX && gi->y < DY + DYSIZE) || - (mode & MULTIMAP_DOOR_2 && gi->x >= DX && gi->y > DY + DYSIZE) || - (mode & MULTIMAP_ALL) == MULTIMAP_ALL) - { - if (mode & MULTIMAP_UNMAP) - { - map_state[map_count++ % MAX_NUM_GADGETS] = gi->mapped; - UnmapGadget(gi); - } - else - { - if (map_state[map_count++ % MAX_NUM_GADGETS]) - MapGadgetExt(gi, (mode & MULTIMAP_REDRAW)); - } - } - - gi = gi->next; - } -} - -void UnmapAllGadgets() -{ - MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_UNMAP); -} - -void RemapAllGadgets() -{ - MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP); -} - -boolean anyTextGadgetActive() -{ - return (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped); -} - -void ClickOnGadget(struct GadgetInfo *gi, int button) -{ - /* simulate releasing mouse button over last gadget, if still pressed */ - if (button_status) - HandleGadgets(-1, -1, 0); - - /* simulate pressing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, button); - - /* simulate releasing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, 0); -} - -void HandleGadgets(int mx, int my, int button) -{ - static struct GadgetInfo *last_info_gi = NULL; - static unsigned long pressed_delay = 0; - static int last_button = 0; - static int last_mx = 0, last_my = 0; - int scrollbar_mouse_pos = 0; - struct GadgetInfo *new_gi, *gi; - boolean press_event; - boolean release_event; - boolean mouse_moving; - boolean gadget_pressed; - boolean gadget_pressed_repeated; - boolean gadget_moving; - boolean gadget_moving_inside; - boolean gadget_moving_off_borders; - boolean gadget_released; - boolean gadget_released_inside; - boolean gadget_released_off_borders; - boolean changed_position = FALSE; - - /* check if there are any gadgets defined */ - if (gadget_list_first_entry == NULL) - return; - - /* check which gadget is under the mouse pointer */ - new_gi = getGadgetInfoFromMousePosition(mx, my); - - /* check if button state has changed since last invocation */ - press_event = (button != 0 && last_button == 0); - release_event = (button == 0 && last_button != 0); - last_button = button; - - /* check if mouse has been moved since last invocation */ - mouse_moving = ((mx != last_mx || my != last_my) && motion_status); - last_mx = mx; - last_my = my; - - /* special treatment for text and number input gadgets */ - if (anyTextGadgetActive() && button != 0 && !motion_status) - { - struct GadgetInfo *gi = last_gi; - - if (new_gi == last_gi) - { - /* if mouse button pressed inside activated text gadget, set cursor */ - gi->text.cursor_position = - (mx - gi->x - gi->border.size) / - getFontWidth(FS_SMALL, gi->text.font_type); - - if (gi->text.cursor_position < 0) - gi->text.cursor_position = 0; - else if (gi->text.cursor_position > strlen(gi->text.value)) - gi->text.cursor_position = strlen(gi->text.value); - - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else - { - /* if mouse button pressed outside text input gadget, deactivate it */ - CheckRangeOfNumericInputGadget(gi); - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); - - gi->event.type = GD_EVENT_TEXT_LEAVING; - - if (gi->event_mask & GD_EVENT_TEXT_LEAVING) - gi->callback_action(gi); - - last_gi = NULL; - } - } - - gadget_pressed = - (button != 0 && last_gi == NULL && new_gi != NULL && press_event); - gadget_pressed_repeated = - (button != 0 && last_gi != NULL && new_gi == last_gi); - - gadget_released = (release_event && last_gi != NULL); - gadget_released_inside = (gadget_released && new_gi == last_gi); - gadget_released_off_borders = (gadget_released && new_gi != last_gi); - - gadget_moving = (button != 0 && last_gi != NULL && mouse_moving); - gadget_moving_inside = (gadget_moving && new_gi == last_gi); - gadget_moving_off_borders = (gadget_moving && new_gi != last_gi); - - /* if new gadget pressed, store this gadget */ - if (gadget_pressed) - last_gi = new_gi; - - /* 'gi' is actually handled gadget */ - gi = last_gi; - - /* if gadget is scrollbar, choose mouse position value */ - if (gi && gi->type & GD_TYPE_SCROLLBAR) - scrollbar_mouse_pos = - (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y); - - /* if mouse button released, no gadget needs to be handled anymore */ - if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT)) - last_gi = NULL; - - /* modify event position values even if no gadget is pressed */ - if (button == 0 && !release_event) - gi = new_gi; - - if (gi) - { - int last_x = gi->event.x; - int last_y = gi->event.y; - - gi->event.x = mx - gi->x; - gi->event.y = my - gi->y; - - if (gi->type == GD_TYPE_DRAWING_AREA) - { - gi->event.x /= gi->drawing.item_xsize; - gi->event.y /= gi->drawing.item_ysize; - - if (last_x != gi->event.x || last_y != gi->event.y) - changed_position = TRUE; - } - } - - /* handle gadget popup info text */ - if (last_info_gi != new_gi || - (new_gi && new_gi->type == GD_TYPE_DRAWING_AREA && changed_position)) - { - last_info_gi = new_gi; - - if (new_gi != NULL && (button == 0 || new_gi == last_gi)) - { - new_gi->event.type = 0; - new_gi->callback_info(new_gi); - } - else - default_callback_info(NULL); - } - - if (gadget_pressed) - { - if (gi->type == GD_TYPE_CHECK_BUTTON) - { - gi->checked = !gi->checked; - } - else if (gi->type == GD_TYPE_RADIO_BUTTON) - { - struct GadgetInfo *rgi = gadget_list_first_entry; - - while (rgi) - { - if (rgi->mapped && - rgi->type == GD_TYPE_RADIO_BUTTON && - rgi->radio_nr == gi->radio_nr && - rgi != gi) - { - rgi->checked = FALSE; - DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT); - } - - rgi = rgi->next; - } - - gi->checked = TRUE; - } - else if (gi->type & GD_TYPE_SCROLLBAR) - { - int mpos, gpos; - - if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL) - { - mpos = mx; - gpos = gi->x; - } - else - { - mpos = my; - gpos = gi->y; - } - - if (mpos >= gpos + gi->scrollbar.position && - mpos < gpos + gi->scrollbar.position + gi->scrollbar.size) - { - /* drag scrollbar */ - gi->scrollbar.drag_position = - scrollbar_mouse_pos - gi->scrollbar.position; - } - else - { - /* click scrollbar one scrollbar length up/left or down/right */ - - struct GadgetScrollbar *gs = &gi->scrollbar; - int old_item_position = gs->item_position; - - changed_position = FALSE; - - gs->item_position += - gs->items_visible * (mpos < gpos + gi->scrollbar.position ? -1 : +1); - - if (gs->item_position < 0) - gs->item_position = 0; - if (gs->item_position > gs->items_max - gs->items_visible) - gs->item_position = gs->items_max - gs->items_visible; - - if (old_item_position != gs->item_position) - { - gi->event.item_position = gs->item_position; - changed_position = TRUE; - } - - ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, gs->item_position, - GDI_END); - - gi->state = GD_BUTTON_UNPRESSED; - gi->event.type = GD_EVENT_MOVING; - gi->event.off_borders = FALSE; - - if (gi->event_mask & GD_EVENT_MOVING && changed_position) - gi->callback_action(gi); - - /* don't handle this scrollbar anymore while mouse button pressed */ - last_gi = NULL; - - return; - } - } - - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - - gi->state = GD_BUTTON_PRESSED; - gi->event.type = GD_EVENT_PRESSED; - gi->event.button = button; - gi->event.off_borders = FALSE; - - /* initialize delay counter */ - DelayReached(&pressed_delay, 0); - - if (gi->event_mask & GD_EVENT_PRESSED) - gi->callback_action(gi); - } - - if (gadget_pressed_repeated) - { - gi->event.type = GD_EVENT_PRESSED; - - if (gi->event_mask & GD_EVENT_REPEATED && - DelayReached(&pressed_delay, GADGET_FRAME_DELAY)) - gi->callback_action(gi); - } - - if (gadget_moving) - { - if (gi->type & GD_TYPE_BUTTON) - { - if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED) - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); - } - - if (gi->type & GD_TYPE_SCROLLBAR) - { - struct GadgetScrollbar *gs = &gi->scrollbar; - int old_item_position = gs->item_position; - - gs->position = scrollbar_mouse_pos - gs->drag_position; - - if (gs->position < 0) - gs->position = 0; - if (gs->position > gs->position_max) - gs->position = gs->position_max; - - gs->item_position = - gs->items_max * (gs->position + gs->correction) / gs->size_max; - - if (gs->item_position < 0) - gs->item_position = 0; - if (gs->item_position > gs->items_max - 1) - gs->item_position = gs->items_max - 1; - - if (old_item_position != gs->item_position) - { - gi->event.item_position = gs->item_position; - changed_position = TRUE; - } - - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - - gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ? - GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED); - gi->event.type = GD_EVENT_MOVING; - gi->event.off_borders = gadget_moving_off_borders; - - if (gi->event_mask & GD_EVENT_MOVING && changed_position && - (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS)) - gi->callback_action(gi); - } - - if (gadget_released_inside) - { - if (!(gi->type & GD_TYPE_TEXTINPUT)) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); - - gi->state = GD_BUTTON_UNPRESSED; - gi->event.type = GD_EVENT_RELEASED; - - if (gi->event_mask & GD_EVENT_RELEASED) - gi->callback_action(gi); - } - - if (gadget_released_off_borders) - { - if (gi->type & GD_TYPE_SCROLLBAR) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); - - gi->event.type = GD_EVENT_RELEASED; - - if (gi->event_mask & GD_EVENT_RELEASED && - gi->event_mask & GD_EVENT_OFF_BORDERS) - gi->callback_action(gi); - } -} - -void HandleGadgetsKeyInput(Key key) -{ - struct GadgetInfo *gi = last_gi; - char text[MAX_GADGET_TEXTSIZE]; - int text_length; - int cursor_pos; - char letter; - boolean legal_letter; - - if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped) - return; - - text_length = strlen(gi->text.value); - cursor_pos = gi->text.cursor_position; - letter = getCharFromKey(key); - legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ? - letter >= '0' && letter <= '9' : - letter != 0); - - if (legal_letter && text_length < gi->text.size) - { - strcpy(text, gi->text.value); - strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]); - gi->text.value[cursor_pos] = letter; - gi->text.cursor_position++; - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else if (key == KSYM_Left && cursor_pos > 0) - { - gi->text.cursor_position--; - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else if (key == KSYM_Right && cursor_pos < text_length) - { - gi->text.cursor_position++; - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else if (key == KSYM_BackSpace && cursor_pos > 0) - { - strcpy(text, gi->text.value); - strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]); - gi->text.cursor_position--; - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else if (key == KSYM_Delete && cursor_pos < text_length) - { - strcpy(text, gi->text.value); - strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]); - DrawGadget(gi, DG_PRESSED, DG_DIRECT); - } - else if (key == KSYM_Return) - { - CheckRangeOfNumericInputGadget(gi); - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); - - gi->event.type = GD_EVENT_TEXT_RETURN; - - if (gi->event_mask & GD_EVENT_TEXT_RETURN) - gi->callback_action(gi); - - last_gi = NULL; - } -} diff --git a/src/buttons.h b/src/buttons.h deleted file mode 100644 index 368fa9ee..00000000 --- a/src/buttons.h +++ /dev/null @@ -1,265 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* buttons.h * -***********************************************************/ - -#ifndef BUTTONS_H -#define BUTTONS_H - -#include "main.h" - -/* the following definitions are also used by tools.c */ - -/* some positions in the video tape control window */ -#define VIDEO_DISPLAY1_XPOS 5 -#define VIDEO_DISPLAY1_YPOS 5 -#define VIDEO_DISPLAY2_XPOS 5 -#define VIDEO_DISPLAY2_YPOS 41 -#define VIDEO_DISPLAY_XSIZE 90 -#define VIDEO_DISPLAY_YSIZE 31 -#define VIDEO_BUTTON_XSIZE 18 -#define VIDEO_BUTTON_YSIZE 18 -#define VIDEO_CONTROL_XPOS 5 -#define VIDEO_CONTROL_YPOS 77 -#define VIDEO_CONTROL_XSIZE VIDEO_DISPLAY_XSIZE -#define VIDEO_CONTROL_YSIZE VIDEO_BUTTON_YSIZE - -/* values for video tape control */ -#define VIDEO_STATE_PLAY_OFF (1L << 0) -#define VIDEO_STATE_PLAY_ON (1L << 1) -#define VIDEO_STATE_PLAY (VIDEO_STATE_PLAY_OFF | VIDEO_STATE_PLAY_ON) -#define VIDEO_STATE_REC_OFF (1L << 2) -#define VIDEO_STATE_REC_ON (1L << 3) -#define VIDEO_STATE_REC (VIDEO_STATE_REC_OFF | VIDEO_STATE_REC_ON) -#define VIDEO_STATE_PAUSE_OFF (1L << 4) -#define VIDEO_STATE_PAUSE_ON (1L << 5) -#define VIDEO_STATE_PAUSE (VIDEO_STATE_PAUSE_OFF | VIDEO_STATE_PAUSE_ON) -#define VIDEO_STATE_DATE_OFF (1L << 6) -#define VIDEO_STATE_DATE_ON (1L << 7) -#define VIDEO_STATE_DATE (VIDEO_STATE_DATE_OFF | VIDEO_STATE_DATE_ON) -#define VIDEO_STATE_TIME_OFF (1L << 8) -#define VIDEO_STATE_TIME_ON (1L << 9) -#define VIDEO_STATE_TIME (VIDEO_STATE_TIME_OFF | VIDEO_STATE_TIME_ON) -#define VIDEO_PRESS_PLAY_ON (1L << 10) -#define VIDEO_PRESS_PLAY_OFF (1L << 11) -#define VIDEO_PRESS_PLAY (VIDEO_PRESS_PLAY_OFF | VIDEO_PRESS_PLAY_ON) -#define VIDEO_PRESS_REC_ON (1L << 12) -#define VIDEO_PRESS_REC_OFF (1L << 13) -#define VIDEO_PRESS_REC (VIDEO_PRESS_REC_OFF | VIDEO_PRESS_REC_ON) -#define VIDEO_PRESS_PAUSE_ON (1L << 14) -#define VIDEO_PRESS_PAUSE_OFF (1L << 15) -#define VIDEO_PRESS_PAUSE (VIDEO_PRESS_PAUSE_OFF | VIDEO_PRESS_PAUSE_ON) -#define VIDEO_PRESS_STOP_ON (1L << 16) -#define VIDEO_PRESS_STOP_OFF (1L << 17) -#define VIDEO_PRESS_STOP (VIDEO_PRESS_STOP_OFF | VIDEO_PRESS_STOP_ON) -#define VIDEO_PRESS_EJECT_ON (1L << 18) -#define VIDEO_PRESS_EJECT_OFF (1L << 19) -#define VIDEO_PRESS_EJECT (VIDEO_PRESS_EJECT_OFF | VIDEO_PRESS_EJECT_ON) - -/* special */ -#define VIDEO_STATE_FFWD_OFF ((1L << 20) | VIDEO_STATE_PAUSE_OFF) -#define VIDEO_STATE_FFWD_ON (1L << 21) -#define VIDEO_STATE_FFWD (VIDEO_STATE_FFWD_OFF | VIDEO_STATE_FFWD_ON) -#define VIDEO_STATE_PBEND_OFF (1L << 22) -#define VIDEO_STATE_PBEND_ON (1L << 23) -#define VIDEO_STATE_PBEND (VIDEO_STATE_PBEND_OFF | VIDEO_STATE_PBEND_ON) - -/* tags to draw video display labels or symbols only */ -#define VIDEO_DISPLAY_DEFAULT 0 -#define VIDEO_DISPLAY_LABEL_ONLY 1 -#define VIDEO_DISPLAY_SYMBOL_ONLY 2 - -void DrawVideoDisplay(unsigned long, unsigned long); -void DrawCompleteVideoDisplay(void); - - -/* NEW GADGET STUFF -------------------------------------------------------- */ - -/* gadget types */ -#define GD_TYPE_NORMAL_BUTTON (1 << 0) -#define GD_TYPE_CHECK_BUTTON (1 << 1) -#define GD_TYPE_RADIO_BUTTON (1 << 2) -#define GD_TYPE_DRAWING_AREA (1 << 3) -#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4) -#define GD_TYPE_TEXTINPUT_NUMERIC (1 << 5) -#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 6) -#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 7) - -#define GD_TYPE_BUTTON (GD_TYPE_NORMAL_BUTTON | \ - GD_TYPE_CHECK_BUTTON | \ - GD_TYPE_RADIO_BUTTON) -#define GD_TYPE_SCROLLBAR (GD_TYPE_SCROLLBAR_VERTICAL | \ - GD_TYPE_SCROLLBAR_HORIZONTAL) -#define GD_TYPE_TEXTINPUT (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \ - GD_TYPE_TEXTINPUT_NUMERIC) - -/* gadget events */ -#define GD_EVENT_PRESSED (1 << 0) -#define GD_EVENT_RELEASED (1 << 1) -#define GD_EVENT_MOVING (1 << 2) -#define GD_EVENT_REPEATED (1 << 3) -#define GD_EVENT_OFF_BORDERS (1 << 4) -#define GD_EVENT_TEXT_RETURN (1 << 5) -#define GD_EVENT_TEXT_LEAVING (1 << 6) - -/* gadget button states */ -#define GD_BUTTON_UNPRESSED 0 -#define GD_BUTTON_PRESSED 1 - -/* gadget structure constants */ -#define MAX_GADGET_TEXTSIZE 1024 -#define MAX_INFO_TEXTSIZE 1024 - -/* gadget creation tags */ -#define GDI_END 0 -#define GDI_CUSTOM_ID 1 -#define GDI_CUSTOM_TYPE_ID 2 -#define GDI_X 3 -#define GDI_Y 4 -#define GDI_WIDTH 5 -#define GDI_HEIGHT 6 -#define GDI_TYPE 7 -#define GDI_STATE 8 -#define GDI_CHECKED 9 -#define GDI_RADIO_NR 10 -#define GDI_NUMBER_VALUE 11 -#define GDI_NUMBER_MIN 12 -#define GDI_NUMBER_MAX 13 -#define GDI_TEXT_VALUE 14 -#define GDI_TEXT_SIZE 15 -#define GDI_TEXT_FONT 16 -#define GDI_DESIGN_UNPRESSED 17 -#define GDI_DESIGN_PRESSED 18 -#define GDI_ALT_DESIGN_UNPRESSED 19 -#define GDI_ALT_DESIGN_PRESSED 20 -#define GDI_BORDER_SIZE 21 -#define GDI_TEXTINPUT_DESIGN_WIDTH 22 -#define GDI_DECORATION_DESIGN 23 -#define GDI_DECORATION_POSITION 24 -#define GDI_DECORATION_SIZE 25 -#define GDI_DECORATION_SHIFTING 26 -#define GDI_EVENT_MASK 27 -#define GDI_EVENT 28 -#define GDI_CALLBACK_INFO 29 -#define GDI_CALLBACK_ACTION 30 -#define GDI_AREA_SIZE 31 -#define GDI_ITEM_SIZE 32 -#define GDI_SCROLLBAR_ITEMS_MAX 33 -#define GDI_SCROLLBAR_ITEMS_VISIBLE 34 -#define GDI_SCROLLBAR_ITEM_POSITION 35 -#define GDI_INFO_TEXT 36 - -typedef void (*gadget_function)(void *); - -struct GadgetBorder -{ - int size; /* size of gadget border */ - int width; /* for text input gadgets */ -}; - -struct GadgetDesign -{ - Bitmap bitmap; /* Bitmap with gadget surface */ - int x, y; /* position of rectangle in Bitmap */ -}; - -struct GadgetDecoration -{ - struct GadgetDesign design; /* decoration design structure */ - int x, y; /* position of deco on the gadget */ - int width, height; /* width and height of decoration */ - int xshift, yshift; /* deco shifting when gadget pressed */ -}; - -struct GadgetEvent -{ - unsigned long type; /* event type */ - int button; /* button number for button events */ - int x, y; /* gadget position at event time */ - boolean off_borders; /* mouse pointer outside gadget? */ - int item_x, item_y, item_position; /* new item position */ -}; - -struct GadgetDrawingArea -{ - int area_xsize, area_ysize; /* size of drawing area (in items) */ - int item_xsize, item_ysize; /* size of each item in drawing area */ -}; - -struct GadgetTextInput -{ - char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */ - int number_value; /* integer value, if numeric */ - int number_min; /* minimal allowed numeric value */ - int number_max; /* maximal allowed numeric value */ - int size; /* maximal size of input text */ - int cursor_position; /* actual cursor position */ - int font_type; /* font to use for text input */ -}; - -struct GadgetScrollbar -{ - int items_max; /* number of items to access */ - int items_visible; /* number of visible items */ - int item_position; /* actual item position */ - int size_max; /* this is either width or height */ - int size; /* scrollbar size on screen */ - int position; /* scrollbar position on screen */ - int position_max; /* bottom/right scrollbar position */ - int drag_position; /* drag position on scrollbar */ - int correction; /* scrollbar position correction */ -}; - -struct GadgetInfo -{ - int id; /* internal gadget identifier */ - int custom_id; /* custom gadget identifier */ - int custom_type_id; /* custom gadget type identifier */ - char info_text[MAX_INFO_TEXTSIZE]; /* short popup info text */ - int x, y; /* gadget position */ - int width, height; /* gadget size */ - unsigned long type; /* type (button, text input, ...) */ - unsigned long state; /* state (pressed, released, ...) */ - boolean checked; /* check/radio button state */ - int radio_nr; /* number of radio button series */ - boolean mapped; /* gadget is active */ - struct GadgetBorder border; /* gadget border design */ - struct GadgetDesign design[2]; /* 0: normal; 1: pressed */ - struct GadgetDesign alt_design[2]; /* alternative design */ - struct GadgetDecoration deco; /* decoration on top of gadget */ - unsigned long event_mask; /* possible events for this gadget */ - struct GadgetEvent event; /* actual gadget event */ - gadget_function callback_info; /* function for pop-up info text */ - gadget_function callback_action; /* function for gadget action */ - struct GadgetDrawingArea drawing; /* fields for drawing area gadget */ - struct GadgetTextInput text; /* fields for text input gadget */ - struct GadgetScrollbar scrollbar; /* fields for scrollbar gadget */ - struct GadgetInfo *next; /* next list entry */ -}; - -struct GadgetInfo *CreateGadget(int, ...); -void FreeGadget(struct GadgetInfo *); - -void ModifyGadget(struct GadgetInfo *, int, ...); -void RedrawGadget(struct GadgetInfo *); - -void MapGadget(struct GadgetInfo *); -void UnmapGadget(struct GadgetInfo *); -void UnmapAllGadgets(); -void RemapAllGadgets(); - -boolean anyTextGadgetActive(); -void ClickOnGadget(struct GadgetInfo *, int); - -void HandleGadgets(int, int, int); -void HandleGadgetsKeyInput(Key); - -#endif diff --git a/src/cartoons.c b/src/cartoons.c index 3290331e..b3a639a3 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -11,9 +11,10 @@ * cartoons.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "cartoons.h" #include "main.h" -#include "misc.h" #include "tools.h" static void HandleAnimation(int); diff --git a/src/editor.c b/src/editor.c index 0977a92a..2ed164c1 100644 --- a/src/editor.c +++ b/src/editor.c @@ -13,11 +13,11 @@ #include +#include "libgame/libgame.h" + #include "editor.h" #include "screens.h" #include "tools.h" -#include "misc.h" -#include "buttons.h" #include "files.h" #include "game.h" #include "tape.h" @@ -1394,6 +1394,7 @@ static void CreateControlButtons() GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2, GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, GDI_END); @@ -1451,6 +1452,7 @@ static void CreateControlButtons() GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, GDI_END); @@ -1501,6 +1503,7 @@ static void CreateControlButtons() GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY, GDI_DECORATION_SHIFTING, 1, 1, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, GDI_END); @@ -1579,6 +1582,7 @@ static void CreateCounterButtons() GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCounterButtons, GDI_END); @@ -1629,6 +1633,7 @@ static void CreateCounterButtons() GDI_BORDER_SIZE, ED_BORDER_SIZE, GDI_TEXTINPUT_DESIGN_WIDTH, gd_width, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCounterButtons, GDI_END); @@ -1772,6 +1777,7 @@ static void CreateTextInputGadgets() GDI_BORDER_SIZE, ED_BORDER_SIZE, GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleTextInputGadgets, GDI_END); @@ -1841,6 +1847,7 @@ static void CreateScrollbarGadgets() GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, GDI_BORDER_SIZE, ED_BORDER_SIZE, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleControlButtons, GDI_END); @@ -1890,6 +1897,7 @@ static void CreateCheckbuttonGadgets() GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y, GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleRadiobuttons, GDI_END); @@ -1922,6 +1930,7 @@ static void CreateCheckbuttonGadgets() GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y, GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y, GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleEditorGadgetInfoText, GDI_CALLBACK_ACTION, HandleCheckbuttons, GDI_END); @@ -4048,6 +4057,9 @@ void HandleEditorGadgetInfoText(void *ptr) char infotext[MAX_INFOTEXT_LEN + 1]; char shortcut[MAX_INFOTEXT_LEN + 1]; + if (game_status != LEVELED) + return; + ClearEditorGadgetInfoText(); /* misuse this function to delete brush cursor, if needed */ diff --git a/src/events.c b/src/events.c index 95d37522..604345d9 100644 --- a/src/events.c +++ b/src/events.c @@ -11,16 +11,16 @@ * events.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "events.h" #include "init.h" #include "screens.h" #include "tools.h" #include "game.h" #include "editor.h" -#include "misc.h" #include "tape.h" #include "joystick.h" -#include "buttons.h" #include "network.h" /* values for key_status */ diff --git a/src/files.c b/src/files.c index 42f7a993..f8bbea80 100644 --- a/src/files.c +++ b/src/files.c @@ -15,9 +15,10 @@ #include #include +#include "libgame/libgame.h" + #include "files.h" #include "tools.h" -#include "misc.h" #include "tape.h" #include "joystick.h" diff --git a/src/game.c b/src/game.c index 670f8cb1..1f39cd8f 100644 --- a/src/game.c +++ b/src/game.c @@ -11,13 +11,12 @@ * game.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "game.h" -#include "misc.h" #include "tools.h" #include "screens.h" -#include "sound.h" #include "init.h" -#include "buttons.h" #include "files.h" #include "tape.h" #include "joystick.h" @@ -176,7 +175,7 @@ void GetPlayerConfig() setup.sound_music = FALSE; } - if (!fullscreen_available) + if (!video.fullscreen_available) setup.fullscreen = FALSE; setup.sound_simple = setup.sound; diff --git a/src/image.c b/src/image.c deleted file mode 100644 index 9dd4c249..00000000 --- a/src/image.c +++ /dev/null @@ -1,554 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* image.c * -***********************************************************/ - -#if defined(TARGET_X11) - -#include "image.h" -#include "pcx.h" -#include "misc.h" - -/* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */ - -Image *newImage(unsigned int width, unsigned int height, unsigned int depth) -{ - Image *image; - const unsigned int bytes_per_pixel = 1; - int i; - - if (depth > 8) - Error(ERR_EXIT, "images with more than 256 colors are not supported"); - - depth = 8; - image = checked_malloc(sizeof(Image)); - image->data = checked_malloc(width * height * bytes_per_pixel); - image->width = width; - image->height = height; - image->depth = depth; - image->rgb.used = 0; - for (i=0; irgb.color_used[i] = FALSE; - - return image; -} - -void freeImage(Image *image) -{ - free(image->data); - free(image); -} - -#if defined(PLATFORM_UNIX) - -/* extra colors to try allocating in private color maps to minimize flashing */ -#define NOFLASH_COLORS 256 - -/* architecture independent value-to-memory conversion - note: the internal format is big endian */ - -#define value_to_memory(value, ptr, length) ( \ -(length) == 1 ? (*( (byte *)(ptr) ) = ( value ) ) : \ -(length) == 2 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+1) = ( value ) ) : \ -(length) == 3 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>>16), \ - *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+2) = ( value ) ) : \ - (*( (byte *)(ptr) ) = (((unsigned long)(value))>>24), \ - *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \ - *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \ - *(((byte *)(ptr))+3) = ( value ) )) - -static Pixmap Image_to_Mask(Image *image, Display *display, Window window) -{ - byte *src_ptr, *dst_ptr, *dst_ptr2; - unsigned int bytes_per_row; - unsigned int x, y; - byte bitmask; - byte *mask_data; - Pixmap mask_pixmap; - - bytes_per_row = (image->width + 7) / 8; - mask_data = checked_calloc(bytes_per_row * image->height); - - src_ptr = image->data; - dst_ptr = mask_data; - - /* create bitmap data which can be used by 'XCreateBitmapFromData()' - * directly to create a pixmap of depth 1 for use as a clip mask for - * the corresponding image pixmap - */ - - for (y=0; yheight; y++) - { - bitmask = 0x01; /* start with leftmost bit in the byte */ - dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */ - - for (x=0; xwidth; x++) - { - if (*src_ptr++) /* source pixel solid? (pixel index != 0) */ - *dst_ptr2 |= bitmask; /* then write a bit into the image mask */ - - if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */ - { - bitmask = 0x01; /* start again with leftmost bit position */ - dst_ptr2++; /* continue with next byte in image mask */ - } - } - - dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */ - } - - mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data, - image->width, image->height); - free(mask_data); - - return mask_pixmap; -} - -static int bitsPerPixelAtDepth(Display *display, int screen, int depth) -{ - XPixmapFormatValues *pixmap_format; - int i, num_pixmap_formats, bits_per_pixel = -1; - - /* get Pixmap formats supported by the X server */ - pixmap_format = XListPixmapFormats(display, &num_pixmap_formats); - - /* find format that matches the given depth */ - for (i=0; idisplay = display; - ximageinfo->depth = depth; - - switch (visual->class) - { - case TrueColor: - case DirectColor: - { - Pixel pixval; - unsigned int redcolors, greencolors, bluecolors; - unsigned int redstep, greenstep, bluestep; - unsigned int redbottom, greenbottom, bluebottom; - unsigned int redtop, greentop, bluetop; - - redvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); - greenvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); - bluevalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); - - ximageinfo->cmap = global_cmap; - - retry_direct: /* tag we hit if a DirectColor allocation fails on - * default colormap */ - - /* calculate number of distinct colors in each band */ - - redcolors = greencolors = bluecolors = 1; - for (pixval=1; pixval; pixval <<= 1) - { - if (pixval & visual->red_mask) - redcolors <<= 1; - if (pixval & visual->green_mask) - greencolors <<= 1; - if (pixval & visual->blue_mask) - bluecolors <<= 1; - } - - /* consistency check */ - if (redcolors > visual->map_entries || - greencolors > visual->map_entries || - bluecolors > visual->map_entries) - Error(ERR_WARN, "inconsistency in color information"); - - redstep = 256 / redcolors; - greenstep = 256 / greencolors; - bluestep = 256 / bluecolors; - redbottom = greenbottom = bluebottom = 0; - redtop = greentop = bluetop = 0; - for (a=0; amap_entries; a++) - { - if (redbottom < 256) - redtop = redbottom + redstep; - if (greenbottom < 256) - greentop = greenbottom + greenstep; - if (bluebottom < 256) - bluetop = bluebottom + bluestep; - - xcolor.red = (redtop - 1) << 8; - xcolor.green = (greentop - 1) << 8; - xcolor.blue = (bluetop - 1) << 8; - if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) - { - /* if an allocation fails for a DirectColor default visual then - we should create a private colormap and try again. */ - - if ((visual->class == DirectColor) && - (visual == DefaultVisual(display, screen))) - { - global_cmap = XCopyColormapAndFree(display, global_cmap); - ximageinfo->cmap = global_cmap; - private_cmap = TRUE; - - goto retry_direct; - } - - /* something completely unexpected happened */ - - fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n"); - free(redvalue); - free(greenvalue); - free(bluevalue); - free(ximageinfo); - return NULL; - } - - /* fill in pixel values for each band at this intensity */ - - while ((redbottom < 256) && (redbottom < redtop)) - redvalue[redbottom++] = xcolor.pixel & visual->red_mask; - while ((greenbottom < 256) && (greenbottom < greentop)) - greenvalue[greenbottom++] = xcolor.pixel & visual->green_mask; - while ((bluebottom < 256) && (bluebottom < bluetop)) - bluevalue[bluebottom++] = xcolor.pixel & visual->blue_mask; - } - break; - } - - case PseudoColor: - - ximageinfo->cmap = global_cmap; - - for (a=0; argb.color_used[a]) - continue; - - xcolor.red = *(image->rgb.red + a); - xcolor.green = *(image->rgb.green + a); - xcolor.blue = *(image->rgb.blue + a); - - /* look if this color already exists in our colormap */ - if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) - { - if (!private_cmap) - { - if (options.verbose) - Error(ERR_RETURN, "switching to private colormap"); - - /* we just filled up the default colormap -- get a private one - which contains all already allocated colors */ - - global_cmap = XCopyColormapAndFree(display, global_cmap); - ximageinfo->cmap = global_cmap; - private_cmap = TRUE; - - /* allocate the rest of the color cells read/write */ - global_cmap_index = - (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS); - for (i=0; i=0; i--) - { - xcolor2.pixel = *(global_cmap_index + i); - xcolor2 = xcolor_private[xcolor2.pixel]; - - if (colorcell_used[xcolor2.pixel]) - continue; - - if ((xcolor.red & mask) == (xcolor2.red & mask) && - (xcolor.green & mask) == (xcolor2.green & mask) && - (xcolor.blue & mask) == (xcolor2.blue & mask)) - { - /* - printf("replacing color cell %ld with a close color\n", - xcolor2.pixel); - */ - color_found = TRUE; - break; - } - } - - if (mask == 0x0000) - break; - - mask = (mask << 1) & 0xffff; - } - - if (!color_found) /* no more free color cells */ - Error(ERR_EXIT, "cannot allocate enough color cells"); - - xcolor.pixel = xcolor2.pixel; - xcolor_private[xcolor.pixel] = xcolor; - colorcell_used[xcolor.pixel] = TRUE; - XStoreColor(display, ximageinfo->cmap, &xcolor); - free_cmap_entries--; - } - - *(ximageinfo->index + a) = xcolor.pixel; - } - - /* - printf("still %d free colormap entries\n", free_cmap_entries); - */ - - ximageinfo->no = a; /* number of pixels allocated for this image */ - break; - - default: - Error(ERR_RETURN, "display class not supported"); - Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); - break; - } - -#if DEBUG_TIMING - debug_print_timestamp(2, " ALLOCATING IMAGE COLORS: "); -#endif - - /* create XImage from internal image structure and convert it to Pixmap */ - - bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth); - bytes_per_pixel = (bits_per_pixel + 7) / 8; - - ximage = XCreateImage(display, visual, depth, ZPixmap, 0, - NULL, image->width, image->height, - 8, image->width * bytes_per_pixel); - ximage->data = - checked_malloc(image->width * image->height * bytes_per_pixel); - ximage->byte_order = MSBFirst; - - src_ptr = image->data; - dst_ptr = (byte *)ximage->data; - - switch (visual->class) - { - case DirectColor: - case TrueColor: - { - Pixel pixval; - - for (y=0; yheight; y++) /* general case */ - { - for (x=0; xwidth; x++) - { - pixval = *src_ptr++; - pixval = - redvalue[image->rgb.red[pixval] >> 8] | - greenvalue[image->rgb.green[pixval] >> 8] | - bluevalue[image->rgb.blue[pixval] >> 8]; - value_to_memory(pixval, dst_ptr, bytes_per_pixel); - dst_ptr += bytes_per_pixel; - } - } - break; - } - - case PseudoColor: - { - if (bytes_per_pixel == 1) /* (common) special case */ - { - for (y=0; yheight; y++) - for (x=0; xwidth; x++) - *dst_ptr++ = ximageinfo->index[c + *src_ptr++]; - } - else /* general case */ - { - for (y=0; yheight; y++) - { - for (x=0; xwidth; x++) - { - value_to_memory(ximageinfo->index[c + *src_ptr++], - dst_ptr, bytes_per_pixel); - dst_ptr += bytes_per_pixel; - } - } - } - break; - } - - default: - Error(ERR_RETURN, "display class not supported"); - Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); - break; - } - - if (redvalue) - { - free((byte *)redvalue); - free((byte *)greenvalue); - free((byte *)bluevalue); - } - -#if DEBUG_TIMING - debug_print_timestamp(2, " CONVERTING IMAGE TO XIMAGE:"); -#endif - - ximageinfo->pixmap = XCreatePixmap(display, window, - ximage->width, ximage->height, - ximageinfo->depth); - - XPutImage(ximageinfo->display, ximageinfo->pixmap, gc, - ximage, 0, 0, 0, 0, ximage->width, ximage->height); - - free(ximage->data); - ximage->data = NULL; - XDestroyImage(ximage); - - return(ximageinfo); -} - -void freeXImage(Image *image, XImageInfo *ximageinfo) -{ - if (ximageinfo->index != NULL && ximageinfo->no > 0) - XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index, - ximageinfo->no, 0); - /* this ^^^^^^^^^^^^^^ is wrong, because the used color cells - * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no' - * used color cells, but they are not at array position 0 - 'ximageinfo->no' - */ - - free(ximageinfo); -} - -int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename, - Pixmap *pixmap, Pixmap *pixmap_mask) -{ - Image *image; - XImageInfo *ximageinfo; - int screen; - Visual *visual; - int depth; - -#if DEBUG_TIMING - debug_print_timestamp(2, NULL); /* initialize timestamp function */ -#endif - - /* read the graphic file in PCX format to image structure */ - if ((image = Read_PCX_to_Image(filename)) == NULL) - return errno_pcx; - -#if DEBUG_TIMING - printf("%s:\n", filename); - debug_print_timestamp(2, " READING PCX FILE TO IMAGE: "); -#endif - - screen = DefaultScreen(display); - visual = DefaultVisual(display, screen); - depth = DefaultDepth(display, screen); - - /* convert image structure to X11 Pixmap */ - if (!(ximageinfo = Image_to_Pixmap(display, screen, visual, - window, gc, depth, image))) - Error(ERR_EXIT, "cannot convert Image to Pixmap"); - - /* if a private colormap has been created, install it */ - if (ximageinfo->cmap != DefaultColormap(display, screen)) - XSetWindowColormap(display, window, ximageinfo->cmap); - -#if DEBUG_TIMING - debug_print_timestamp(2, " CONVERTING IMAGE TO PIXMAP:"); -#endif - - /* create clip mask for the image */ - ximageinfo->pixmap_mask = Image_to_Mask(image, display, window); - -#if DEBUG_TIMING - debug_print_timestamp(2, " CONVERTING IMAGE TO MASK: "); -#endif - - *pixmap = ximageinfo->pixmap; - *pixmap_mask = ximageinfo->pixmap_mask; - - return PCX_Success; -} - -#endif /* PLATFORM_UNIX */ -#endif /* TARGET_X11 */ diff --git a/src/image.h b/src/image.h deleted file mode 100644 index 860521c0..00000000 --- a/src/image.h +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* image.h * -***********************************************************/ - -#ifndef IMAGE_H -#define IMAGE_H - -#ifndef TARGET_SDL - -#include "main.h" - -#define MAX_COLORS 256 /* maximal number of colors for each image */ - -typedef unsigned short Intensity; /* RGB intensity for X11 */ - -typedef struct -{ - Display *display; /* destination display */ - int depth; /* depth of destination drawable */ - Pixel index[MAX_COLORS]; /* array of pixel values */ - int no; /* number of pixels in the array */ - Colormap cmap; /* colormap used for image */ - Pixmap pixmap; /* final pixmap */ - Pixmap pixmap_mask; /* final pixmap of mask */ -} XImageInfo; - -struct RGBMap -{ - unsigned int used; /* number of colors used in RGB map */ - Intensity red[MAX_COLORS]; /* color values in X style */ - Intensity green[MAX_COLORS]; - Intensity blue[MAX_COLORS]; - boolean color_used[MAX_COLORS]; /* flag if color cell is used */ -}; - -typedef struct -{ - struct RGBMap rgb; /* RGB map of image if IRGB type */ - unsigned int width; /* width of image in pixels */ - unsigned int height; /* height of image in pixels */ - unsigned int depth; /* depth of image in bits if IRGB type */ - byte *data; /* image data */ -} Image; - -Image *newImage(unsigned int, unsigned int, unsigned int); -void freeImage(Image *); -void freeXImage(Image *, XImageInfo *); -int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *); - -#endif /* !TARGET_SDL */ -#endif /* IMAGE_H */ diff --git a/src/init.c b/src/init.c index 851eaa5e..d48e713c 100644 --- a/src/init.c +++ b/src/init.c @@ -13,10 +13,10 @@ #include +#include "libgame/libgame.h" + #include "init.h" #include "events.h" -#include "misc.h" -#include "sound.h" #include "screens.h" #include "editor.h" #include "game.h" @@ -24,8 +24,6 @@ #include "tools.h" #include "files.h" #include "joystick.h" -#include "image.h" -#include "pcx.h" #include "network.h" #include "netserv.h" diff --git a/src/joystick.c b/src/joystick.c index 8f6a0d6a..16d00d78 100644 --- a/src/joystick.c +++ b/src/joystick.c @@ -11,12 +11,13 @@ * joystick.c * ***********************************************************/ -#ifdef __FreeBSD__ +#if defined(PLATFORM_FREEBSD) #include #endif +#include "libgame/libgame.h" + #include "joystick.h" -#include "misc.h" #if !defined(PLATFORM_MSDOS) static int JoystickPosition(int middle, int margin, int actual) diff --git a/src/libgame/Makefile b/src/libgame/Makefile new file mode 100644 index 00000000..f096730d --- /dev/null +++ b/src/libgame/Makefile @@ -0,0 +1,60 @@ +#=============================================================================# +# Makefile for Rocks'n'Diamonds # +# (c) 1995-2000 Holger Schemel, info@artsoft.org # +#=============================================================================# + +SRCS = libgame.c \ + private.c \ + system.c \ + buttons.c \ + text.c \ + sound.c \ + pcx.c \ + image.c \ + random.c \ + misc.c \ + msdos.c \ + x11.c \ + sdl.c + +OBJS = libgame.o \ + private.o \ + system.o \ + buttons.o \ + text.o \ + sound.o \ + pcx.o \ + image.o \ + random.o \ + misc.o \ + msdos.o \ + x11.o \ + sdl.o + +LIBGAME = libgame.a + + +all: $(LIBGAME) + +$(LIBGAME): $(OBJS) + $(AR) cru $(LIBGAME) $(OBJS) + $(RANLIB) $(LIBGAME) + +.c.o: + $(CC) $(PROFILING) $(CFLAGS) -c $*.c + +clean: + $(RM) $(OBJS) + $(RM) $(LIBGAME) + + +#-----------------------------------------------------------------------------# +# development only stuff # +#-----------------------------------------------------------------------------# + +depend: + for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/src/libgame/buttons.c b/src/libgame/buttons.c new file mode 100644 index 00000000..3fad7560 --- /dev/null +++ b/src/libgame/buttons.c @@ -0,0 +1,1349 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* buttons.c * +***********************************************************/ + +#include + +#include "libgame.h" + +#include "main_TMP.h" + +#include "buttons.h" + +/* some positions in the video tape control window */ +#define VIDEO_DATE_LABEL_XPOS (VIDEO_DISPLAY1_XPOS) +#define VIDEO_DATE_LABEL_YPOS (VIDEO_DISPLAY1_YPOS) +#define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE) +#define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE) +#define VIDEO_DATE_XPOS (VIDEO_DISPLAY1_XPOS + 1) +#define VIDEO_DATE_YPOS (VIDEO_DISPLAY1_YPOS + 14) +#define VIDEO_DATE_XSIZE (VIDEO_DISPLAY_XSIZE) +#define VIDEO_DATE_YSIZE 16 +#define VIDEO_REC_LABEL_XPOS (VIDEO_DISPLAY2_XPOS) +#define VIDEO_REC_LABEL_YPOS (VIDEO_DISPLAY2_YPOS) +#define VIDEO_REC_LABEL_XSIZE 20 +#define VIDEO_REC_LABEL_YSIZE 12 +#define VIDEO_REC_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 20) +#define VIDEO_REC_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) +#define VIDEO_REC_SYMBOL_XSIZE 16 +#define VIDEO_REC_SYMBOL_YSIZE 16 +#define VIDEO_PLAY_LABEL_XPOS (VIDEO_DISPLAY2_XPOS + 65) +#define VIDEO_PLAY_LABEL_YPOS (VIDEO_DISPLAY2_YPOS) +#define VIDEO_PLAY_LABEL_XSIZE 22 +#define VIDEO_PLAY_LABEL_YSIZE 12 +#define VIDEO_PLAY_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 52) +#define VIDEO_PLAY_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) +#define VIDEO_PLAY_SYMBOL_XSIZE 11 +#define VIDEO_PLAY_SYMBOL_YSIZE 13 +#define VIDEO_PAUSE_LABEL_XPOS (VIDEO_DISPLAY2_XPOS) +#define VIDEO_PAUSE_LABEL_YPOS (VIDEO_DISPLAY2_YPOS + 20) +#define VIDEO_PAUSE_LABEL_XSIZE 35 +#define VIDEO_PAUSE_LABEL_YSIZE 8 +#define VIDEO_PAUSE_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 35) +#define VIDEO_PAUSE_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS) +#define VIDEO_PAUSE_SYMBOL_XSIZE 17 +#define VIDEO_PAUSE_SYMBOL_YSIZE 13 +#define VIDEO_TIME_XPOS (VIDEO_DISPLAY2_XPOS + 38) +#define VIDEO_TIME_YPOS (VIDEO_DISPLAY2_YPOS + 14) +#define VIDEO_TIME_XSIZE 50 +#define VIDEO_TIME_YSIZE 16 + +/* special */ +#define VIDEO_PBEND_LABEL_XPOS 6 +#define VIDEO_PBEND_LABEL_YPOS 220 +#define VIDEO_PBEND_LABEL_XSIZE 35 +#define VIDEO_PBEND_LABEL_YSIZE 30 + +#define VIDEO_STATE_OFF (VIDEO_STATE_PLAY_OFF | \ + VIDEO_STATE_REC_OFF | \ + VIDEO_STATE_PAUSE_OFF | \ + VIDEO_STATE_FFWD_OFF | \ + VIDEO_STATE_PBEND_OFF | \ + VIDEO_STATE_DATE_OFF | \ + VIDEO_STATE_TIME_OFF) +#define VIDEO_PRESS_OFF (VIDEO_PRESS_PLAY_OFF | \ + VIDEO_PRESS_REC_OFF | \ + VIDEO_PRESS_PAUSE_OFF | \ + VIDEO_PRESS_STOP_OFF | \ + VIDEO_PRESS_EJECT_OFF) +#define VIDEO_ALL_OFF (VIDEO_STATE_OFF | VIDEO_PRESS_OFF) + +#define VIDEO_STATE_ON (VIDEO_STATE_PLAY_ON | \ + VIDEO_STATE_REC_ON | \ + VIDEO_STATE_PAUSE_ON | \ + VIDEO_STATE_FFWD_ON | \ + VIDEO_STATE_PBEND_ON | \ + VIDEO_STATE_DATE_ON | \ + VIDEO_STATE_TIME_ON) +#define VIDEO_PRESS_ON (VIDEO_PRESS_PLAY_ON | \ + VIDEO_PRESS_REC_ON | \ + VIDEO_PRESS_PAUSE_ON | \ + VIDEO_PRESS_STOP_ON | \ + VIDEO_PRESS_EJECT_ON) +#define VIDEO_ALL_ON (VIDEO_STATE_ON | VIDEO_PRESS_ON) + +#define VIDEO_STATE (VIDEO_STATE_ON | VIDEO_STATE_OFF) +#define VIDEO_PRESS (VIDEO_PRESS_ON | VIDEO_PRESS_OFF) +#define VIDEO_ALL (VIDEO_ALL_ON | VIDEO_ALL_OFF) + + +void DrawVideoDisplay(unsigned long state, unsigned long value) +{ + int i; + int part_label = 0, part_symbol = 1; + int xpos = 0, ypos = 1, xsize = 2, ysize = 3; + static char *monatsname[12] = + { + "JAN", "FEB", "MAR", "APR", "MAY", "JUN", + "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" + }; + static int video_pos[5][2][4] = + { + {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS, + VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE }, + { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS, + VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }}, + + {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS, + VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE }, + { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS, + VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }}, + + {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS, + VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE }, + { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS, + VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }}, + + {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS, + VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE }, + { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS, + VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }}, + + {{ 0,0, + 0,0 }, + { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS, + VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }} + }; + + if (state & VIDEO_STATE_PBEND_OFF) + { + int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; + + BlitBitmap(pix[PIX_DOOR], drawto, + cx + VIDEO_REC_LABEL_XPOS, + cy + VIDEO_REC_LABEL_YPOS, + VIDEO_PBEND_LABEL_XSIZE, + VIDEO_PBEND_LABEL_YSIZE, + VX + VIDEO_REC_LABEL_XPOS, + VY + VIDEO_REC_LABEL_YPOS); + } + + for(i=0;i<10;i++) + { + if (state & (1< STATE_ON / PRESS_OFF */ + cx = DOOR_GFX_PAGEX4; + else + cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */ + + if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY) + BlitBitmap(pix[PIX_DOOR], drawto, + cx + video_pos[pos][part_label][xpos], + cy + video_pos[pos][part_label][ypos], + video_pos[pos][part_label][xsize], + video_pos[pos][part_label][ysize], + VX + video_pos[pos][part_label][xpos], + VY + video_pos[pos][part_label][ypos]); + if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY) + BlitBitmap(pix[PIX_DOOR], drawto, + cx + video_pos[pos][part_symbol][xpos], + cy + video_pos[pos][part_symbol][ypos], + video_pos[pos][part_symbol][xsize], + video_pos[pos][part_symbol][ysize], + VX + video_pos[pos][part_symbol][xpos], + VY + video_pos[pos][part_symbol][ypos]); + } + } + + if (state & VIDEO_STATE_FFWD_ON) + { + int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2; + + BlitBitmap(pix[PIX_DOOR], drawto, + cx + VIDEO_PLAY_SYMBOL_XPOS, + cy + VIDEO_PLAY_SYMBOL_YPOS, + VIDEO_PLAY_SYMBOL_XSIZE - 2, + VIDEO_PLAY_SYMBOL_YSIZE, + VX + VIDEO_PLAY_SYMBOL_XPOS - 9, + VY + VIDEO_PLAY_SYMBOL_YPOS); + } + + if (state & VIDEO_STATE_PBEND_ON) + { + int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; + + BlitBitmap(pix[PIX_DOOR], drawto, + cx + VIDEO_PBEND_LABEL_XPOS, + cy + VIDEO_PBEND_LABEL_YPOS, + VIDEO_PBEND_LABEL_XSIZE, + VIDEO_PBEND_LABEL_YSIZE, + VX + VIDEO_REC_LABEL_XPOS, + VY + VIDEO_REC_LABEL_YPOS); + } + + if (state & VIDEO_STATE_DATE_ON) + { + int tag = value % 100; + int monat = (value/100) % 100; + int jahr = (value/10000); + + DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS, + int2str(tag,2),FS_SMALL,FC_SPECIAL1); + DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS, + monatsname[monat],FS_SMALL,FC_SPECIAL1); + DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS, + int2str(jahr,2),FS_SMALL,FC_SPECIAL1); + } + + if (state & VIDEO_STATE_TIME_ON) + { + int min = value / 60; + int sec = value % 60; + + DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS, + int2str(min,2),FS_SMALL,FC_SPECIAL1); + DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS, + int2str(sec,2),FS_SMALL,FC_SPECIAL1); + } + + if (state & VIDEO_STATE_DATE) + redraw_mask |= REDRAW_VIDEO_1; + if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE) + redraw_mask |= REDRAW_VIDEO_2; + if (state & VIDEO_PRESS) + redraw_mask |= REDRAW_VIDEO_3; +} + +void DrawCompleteVideoDisplay() +{ + BlitBitmap(pix[PIX_DOOR], drawto, + DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY); + BlitBitmap(pix[PIX_DOOR], drawto, + DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS, + DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS, + VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE, + VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS); + + DrawVideoDisplay(VIDEO_ALL_OFF,0); + if (tape.date && tape.length) + { + DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date); + DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds); + } + + BlitBitmap(drawto, pix[PIX_DB_DOOR], + VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2); +} + + +/* NEW GADGET STUFF -------------------------------------------------------- */ + + +/* values for DrawGadget() */ +#define DG_UNPRESSED 0 +#define DG_PRESSED 1 +#define DG_BUFFERED 0 +#define DG_DIRECT 1 + +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) +{ + struct GadgetInfo *gi = gadget_list_first_entry; + + while (gi) + { + if (gi->mapped && + mx >= gi->x && mx < gi->x + gi->width && + my >= gi->y && my < gi->y + gi->height) + break; + + gi = gi->next; + } + + return gi; +} + +static void default_callback_info(void *ptr) +{ +#if 0 + if (game_status == LEVELED) + HandleEditorGadgetInfoText(ptr); +#endif + + return; +} + +static void default_callback_action(void *ptr) +{ + return; +} + +static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) +{ + int state = (pressed ? 1 : 0); + struct GadgetDesign *gd = (gi->checked ? + &gi->alt_design[state] : + &gi->design[state]); + + switch (gi->type) + { + case GD_TYPE_NORMAL_BUTTON: + case GD_TYPE_CHECK_BUTTON: + case GD_TYPE_RADIO_BUTTON: + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); + if (gi->deco.design.bitmap) + BlitBitmap(gi->deco.design.bitmap, drawto, + gi->deco.design.x, gi->deco.design.y, + gi->deco.width, gi->deco.height, + gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0), + gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0)); + break; + + case GD_TYPE_TEXTINPUT_ALPHANUMERIC: + case GD_TYPE_TEXTINPUT_NUMERIC: + { + int i; + char cursor_letter; + char cursor_string[3]; + char text[MAX_GADGET_TEXTSIZE + 1]; + int font_type = gi->text.font_type; + int font_width = getFontWidth(FS_SMALL, font_type); + int border = gi->border.size; + strcpy(text, gi->text.value); + strcat(text, " "); + + /* left part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y, border, gi->height, gi->x, gi->y); + + /* middle part of gadget */ + for (i=0; i<=gi->text.size; i++) + BlitBitmap(gd->bitmap, drawto, + gd->x + border, gd->y, font_width, gi->height, + gi->x + border + i * font_width, gi->y); + + /* right part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x + gi->border.width - border, gd->y, + border, gi->height, gi->x + gi->width - border, gi->y); + + /* gadget text value */ + DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type); + + cursor_letter = gi->text.value[gi->text.cursor_position]; + cursor_string[0] = '~'; + cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' '); + cursor_string[2] = '\0'; + + /* draw cursor, if active */ + if (pressed) + DrawText(gi->x + border + gi->text.cursor_position * font_width, + gi->y + border, cursor_string, FS_SMALL, font_type); + } + break; + + case GD_TYPE_SCROLLBAR_VERTICAL: + { + int i; + int xpos = gi->x; + int ypos = gi->y + gi->scrollbar.position; + int design_full = gi->width; + int design_body = design_full - 2 * gi->border.size; + int size_full = gi->scrollbar.size; + int size_body = size_full - 2 * gi->border.size; + int num_steps = size_body / design_body; + int step_size_remain = size_body - num_steps * design_body; + + /* clear scrollbar area */ + ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height); + + /* upper part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y, + gi->width, gi->border.size, + xpos, ypos); + + /* middle part of gadget */ + for (i=0; ibitmap, drawto, + gd->x, gd->y + gi->border.size, + gi->width, design_body, + xpos, ypos + gi->border.size + i * design_body); + + /* remaining middle part of gadget */ + if (step_size_remain > 0) + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y + gi->border.size, + gi->width, step_size_remain, + xpos, ypos + gi->border.size + num_steps * design_body); + + /* lower part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y + design_full - gi->border.size, + gi->width, gi->border.size, + xpos, ypos + size_full - gi->border.size); + } + break; + + case GD_TYPE_SCROLLBAR_HORIZONTAL: + { + int i; + int xpos = gi->x + gi->scrollbar.position; + int ypos = gi->y; + int design_full = gi->height; + int design_body = design_full - 2 * gi->border.size; + int size_full = gi->scrollbar.size; + int size_body = size_full - 2 * gi->border.size; + int num_steps = size_body / design_body; + int step_size_remain = size_body - num_steps * design_body; + + /* clear scrollbar area */ + ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height); + + /* left part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x, gd->y, + gi->border.size, gi->height, + xpos, ypos); + + /* middle part of gadget */ + for (i=0; ibitmap, drawto, + gd->x + gi->border.size, gd->y, + design_body, gi->height, + xpos + gi->border.size + i * design_body, ypos); + + /* remaining middle part of gadget */ + if (step_size_remain > 0) + BlitBitmap(gd->bitmap, drawto, + gd->x + gi->border.size, gd->y, + step_size_remain, gi->height, + xpos + gi->border.size + num_steps * design_body, ypos); + + /* right part of gadget */ + BlitBitmap(gd->bitmap, drawto, + gd->x + design_full - gi->border.size, gd->y, + gi->border.size, gi->height, + xpos + size_full - gi->border.size, ypos); + } + break; + + default: + return; + } + + if (direct) + BlitBitmap(drawto, window, + gi->x, gi->y, gi->width, gi->height, gi->x, gi->y); + else + redraw_mask |= (gi->x < SX + SXSIZE ? REDRAW_FIELD : + gi->y < DY + DYSIZE ? REDRAW_DOOR_1 : + gi->y > VY ? REDRAW_DOOR_2 : REDRAW_DOOR_3); +} + +static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) +{ + int tag = first_tag; + + while (tag != GDI_END) + { + switch(tag) + { + case GDI_CUSTOM_ID: + gi->custom_id = va_arg(ap, int); + break; + + case GDI_CUSTOM_TYPE_ID: + gi->custom_type_id = va_arg(ap, int); + break; + + case GDI_INFO_TEXT: + { + int max_textsize = MAX_INFO_TEXTSIZE - 1; + + strncpy(gi->info_text, va_arg(ap, char *), max_textsize); + gi->info_text[max_textsize] = '\0'; + } + break; + + case GDI_X: + gi->x = va_arg(ap, int); + break; + + case GDI_Y: + gi->y = va_arg(ap, int); + break; + + case GDI_WIDTH: + gi->width = va_arg(ap, int); + break; + + case GDI_HEIGHT: + gi->height = va_arg(ap, int); + break; + + case GDI_TYPE: + gi->type = va_arg(ap, unsigned long); + break; + + case GDI_STATE: + gi->state = va_arg(ap, unsigned long); + break; + + case GDI_CHECKED: + gi->checked = va_arg(ap, boolean); + break; + + case GDI_RADIO_NR: + gi->radio_nr = va_arg(ap, unsigned long); + break; + + case GDI_NUMBER_VALUE: + gi->text.number_value = va_arg(ap, long); + sprintf(gi->text.value, "%d", gi->text.number_value); + gi->text.cursor_position = strlen(gi->text.value); + break; + + case GDI_NUMBER_MIN: + gi->text.number_min = va_arg(ap, long); + if (gi->text.number_value < gi->text.number_min) + { + gi->text.number_value = gi->text.number_min; + sprintf(gi->text.value, "%d", gi->text.number_value); + } + break; + + case GDI_NUMBER_MAX: + gi->text.number_max = va_arg(ap, long); + if (gi->text.number_value > gi->text.number_max) + { + gi->text.number_value = gi->text.number_max; + sprintf(gi->text.value, "%d", gi->text.number_value); + } + break; + + case GDI_TEXT_VALUE: + { + int max_textsize = MAX_GADGET_TEXTSIZE; + + if (gi->text.size) + max_textsize = MIN(gi->text.size, MAX_GADGET_TEXTSIZE - 1); + + strncpy(gi->text.value, va_arg(ap, char *), max_textsize); + gi->text.value[max_textsize] = '\0'; + gi->text.cursor_position = strlen(gi->text.value); + } + break; + + case GDI_TEXT_SIZE: + { + int tag_value = va_arg(ap, int); + int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1); + + gi->text.size = max_textsize; + gi->text.value[max_textsize] = '\0'; + } + break; + + case GDI_TEXT_FONT: + gi->text.font_type = va_arg(ap, int); + break; + + case GDI_DESIGN_UNPRESSED: + gi->design[GD_BUTTON_UNPRESSED].bitmap = va_arg(ap, Bitmap); + gi->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + gi->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + break; + + case GDI_DESIGN_PRESSED: + gi->design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap); + gi->design[GD_BUTTON_PRESSED].x = va_arg(ap, int); + gi->design[GD_BUTTON_PRESSED].y = va_arg(ap, int); + break; + + case GDI_ALT_DESIGN_UNPRESSED: + gi->alt_design[GD_BUTTON_UNPRESSED].bitmap= va_arg(ap, Bitmap); + gi->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + gi->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + break; + + case GDI_ALT_DESIGN_PRESSED: + gi->alt_design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap); + gi->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int); + gi->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int); + break; + + case GDI_BORDER_SIZE: + gi->border.size = va_arg(ap, int); + break; + + case GDI_TEXTINPUT_DESIGN_WIDTH: + gi->border.width = va_arg(ap, int); + break; + + case GDI_DECORATION_DESIGN: + gi->deco.design.bitmap = va_arg(ap, Bitmap); + gi->deco.design.x = va_arg(ap, int); + gi->deco.design.y = va_arg(ap, int); + break; + + case GDI_DECORATION_POSITION: + gi->deco.x = va_arg(ap, int); + gi->deco.y = va_arg(ap, int); + break; + + case GDI_DECORATION_SIZE: + gi->deco.width = va_arg(ap, int); + gi->deco.height = va_arg(ap, int); + break; + + case GDI_DECORATION_SHIFTING: + gi->deco.xshift = va_arg(ap, int); + gi->deco.yshift = va_arg(ap, int); + break; + + case GDI_EVENT_MASK: + gi->event_mask = va_arg(ap, unsigned long); + break; + + case GDI_AREA_SIZE: + gi->drawing.area_xsize = va_arg(ap, int); + gi->drawing.area_ysize = va_arg(ap, int); + + /* determine dependent values for drawing area gadget, if needed */ + if (gi->width == 0 && gi->height == 0 && + gi->drawing.item_xsize !=0 && gi->drawing.item_ysize !=0) + { + gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; + gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; + } + else if (gi->drawing.item_xsize == 0 && gi->drawing.item_ysize == 0 && + gi->width != 0 && gi->height != 0) + { + gi->drawing.item_xsize = gi->width / gi->drawing.area_xsize; + gi->drawing.item_ysize = gi->height / gi->drawing.area_ysize; + } + break; + + case GDI_ITEM_SIZE: + gi->drawing.item_xsize = va_arg(ap, int); + gi->drawing.item_ysize = va_arg(ap, int); + + /* determine dependent values for drawing area gadget, if needed */ + if (gi->width == 0 && gi->height == 0 && + gi->drawing.area_xsize !=0 && gi->drawing.area_ysize !=0) + { + gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; + gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; + } + else if (gi->drawing.area_xsize == 0 && gi->drawing.area_ysize == 0 && + gi->width != 0 && gi->height != 0) + { + gi->drawing.area_xsize = gi->width / gi->drawing.item_xsize; + gi->drawing.area_ysize = gi->height / gi->drawing.item_ysize; + } + break; + + case GDI_SCROLLBAR_ITEMS_MAX: + gi->scrollbar.items_max = va_arg(ap, int); + break; + + case GDI_SCROLLBAR_ITEMS_VISIBLE: + gi->scrollbar.items_visible = va_arg(ap, int); + break; + + case GDI_SCROLLBAR_ITEM_POSITION: + gi->scrollbar.item_position = va_arg(ap, int); + break; + + case GDI_CALLBACK_INFO: + gi->callback_info = va_arg(ap, gadget_function); + break; + + case GDI_CALLBACK_ACTION: + gi->callback_action = va_arg(ap, gadget_function); + break; + + default: + Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag); + } + + tag = va_arg(ap, int); /* read next tag */ + } + + /* check if gadget complete */ + if (gi->type != GD_TYPE_DRAWING_AREA && + (!gi->design[GD_BUTTON_UNPRESSED].bitmap || + !gi->design[GD_BUTTON_PRESSED].bitmap)) + Error(ERR_EXIT, "gadget incomplete (missing Bitmap)"); + + /* adjust gadget values in relation to other gadget values */ + + if (gi->type & GD_TYPE_TEXTINPUT) + { + int font_width = getFontWidth(FS_SMALL, gi->text.font_type); + int font_height = getFontHeight(FS_SMALL, gi->text.font_type); + + gi->width = 2 * gi->border.size + (gi->text.size + 1) * font_width; + gi->height = 2 * gi->border.size + font_height; + } + + if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC) + { + struct GadgetTextInput *text = &gi->text; + int value = text->number_value; + + text->number_value = (value < text->number_min ? text->number_min : + value > text->number_max ? text->number_max : + value); + + sprintf(text->value, "%d", text->number_value); + } + + if (gi->type & GD_TYPE_SCROLLBAR) + { + struct GadgetScrollbar *gs = &gi->scrollbar; + + if (gi->width == 0 || gi->height == 0 || + gs->items_max == 0 || gs->items_visible == 0) + Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)"); + + /* calculate internal scrollbar values */ + gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? + gi->height : gi->width); + gs->size = gs->size_max * gs->items_visible / gs->items_max; + gs->position = gs->size_max * gs->item_position / gs->items_max; + gs->position_max = gs->size_max - gs->size; + gs->correction = gs->size_max / gs->items_max / 2; + + /* finetuning for maximal right/bottom position */ + if (gs->item_position == gs->items_max - gs->items_visible) + gs->position = gs->position_max; + } +} + +void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...) +{ + va_list ap; + + va_start(ap, first_tag); + HandleGadgetTags(gi, first_tag, ap); + va_end(ap); + + RedrawGadget(gi); +} + +void RedrawGadget(struct GadgetInfo *gi) +{ + if (gi->mapped) + DrawGadget(gi, gi->state, DG_DIRECT); +} + +struct GadgetInfo *CreateGadget(int first_tag, ...) +{ + struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo)); + va_list ap; + + /* always start with reliable default values */ + memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */ + new_gadget->id = getNewGadgetID(); + new_gadget->callback_info = default_callback_info; + new_gadget->callback_action = default_callback_action; + + va_start(ap, first_tag); + HandleGadgetTags(new_gadget, first_tag, ap); + va_end(ap); + + /* insert new gadget into global 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 CheckRangeOfNumericInputGadget(struct GadgetInfo *gi) +{ + if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC) + return; + + gi->text.number_value = atoi(gi->text.value); + + if (gi->text.number_value < gi->text.number_min) + gi->text.number_value = gi->text.number_min; + if (gi->text.number_value > gi->text.number_max) + gi->text.number_value = gi->text.number_max; + + sprintf(gi->text.value, "%d", gi->text.number_value); + + if (gi->text.cursor_position < 0) + gi->text.cursor_position = 0; + else if (gi->text.cursor_position > strlen(gi->text.value)) + gi->text.cursor_position = strlen(gi->text.value); +} + +/* global pointer to gadget actually in use (when mouse button pressed) */ +static struct GadgetInfo *last_gi = NULL; + +static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw) +{ + if (gi == NULL || gi->mapped) + return; + + gi->mapped = TRUE; + + if (redraw) + DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED); +} + +void MapGadget(struct GadgetInfo *gi) +{ + MapGadgetExt(gi, TRUE); +} + +void UnmapGadget(struct GadgetInfo *gi) +{ + if (gi == NULL || !gi->mapped) + return; + + gi->mapped = FALSE; + + if (gi == last_gi) + last_gi = NULL; +} + +#define MAX_NUM_GADGETS 1024 +#define MULTIMAP_UNMAP (1 << 0) +#define MULTIMAP_REMAP (1 << 1) +#define MULTIMAP_REDRAW (1 << 2) +#define MULTIMAP_PLAYFIELD (1 << 3) +#define MULTIMAP_DOOR_1 (1 << 4) +#define MULTIMAP_DOOR_2 (1 << 5) +#define MULTIMAP_ALL (MULTIMAP_PLAYFIELD | \ + MULTIMAP_DOOR_1 | \ + MULTIMAP_DOOR_2) + +static void MultiMapGadgets(int mode) +{ + struct GadgetInfo *gi = gadget_list_first_entry; + static boolean map_state[MAX_NUM_GADGETS]; + int map_count = 0; + + while (gi) + { + if ((mode & MULTIMAP_PLAYFIELD && gi->x < SX + SXSIZE) || + (mode & MULTIMAP_DOOR_1 && gi->x >= DX && gi->y < DY + DYSIZE) || + (mode & MULTIMAP_DOOR_2 && gi->x >= DX && gi->y > DY + DYSIZE) || + (mode & MULTIMAP_ALL) == MULTIMAP_ALL) + { + if (mode & MULTIMAP_UNMAP) + { + map_state[map_count++ % MAX_NUM_GADGETS] = gi->mapped; + UnmapGadget(gi); + } + else + { + if (map_state[map_count++ % MAX_NUM_GADGETS]) + MapGadgetExt(gi, (mode & MULTIMAP_REDRAW)); + } + } + + gi = gi->next; + } +} + +void UnmapAllGadgets() +{ + MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_UNMAP); +} + +void RemapAllGadgets() +{ + MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP); +} + +boolean anyTextGadgetActive() +{ + return (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped); +} + +void ClickOnGadget(struct GadgetInfo *gi, int button) +{ + /* simulate releasing mouse button over last gadget, if still pressed */ + if (button_status) + HandleGadgets(-1, -1, 0); + + /* simulate pressing mouse button over specified gadget */ + HandleGadgets(gi->x, gi->y, button); + + /* simulate releasing mouse button over specified gadget */ + HandleGadgets(gi->x, gi->y, 0); +} + +void HandleGadgets(int mx, int my, int button) +{ + static struct GadgetInfo *last_info_gi = NULL; + static unsigned long pressed_delay = 0; + static int last_button = 0; + static int last_mx = 0, last_my = 0; + int scrollbar_mouse_pos = 0; + struct GadgetInfo *new_gi, *gi; + boolean press_event; + boolean release_event; + boolean mouse_moving; + boolean gadget_pressed; + boolean gadget_pressed_repeated; + boolean gadget_moving; + boolean gadget_moving_inside; + boolean gadget_moving_off_borders; + boolean gadget_released; + boolean gadget_released_inside; + boolean gadget_released_off_borders; + boolean changed_position = FALSE; + + /* check if there are any gadgets defined */ + if (gadget_list_first_entry == NULL) + return; + + /* check which gadget is under the mouse pointer */ + new_gi = getGadgetInfoFromMousePosition(mx, my); + + /* check if button state has changed since last invocation */ + press_event = (button != 0 && last_button == 0); + release_event = (button == 0 && last_button != 0); + last_button = button; + + /* check if mouse has been moved since last invocation */ + mouse_moving = ((mx != last_mx || my != last_my) && motion_status); + last_mx = mx; + last_my = my; + + /* special treatment for text and number input gadgets */ + if (anyTextGadgetActive() && button != 0 && !motion_status) + { + struct GadgetInfo *gi = last_gi; + + if (new_gi == last_gi) + { + /* if mouse button pressed inside activated text gadget, set cursor */ + gi->text.cursor_position = + (mx - gi->x - gi->border.size) / + getFontWidth(FS_SMALL, gi->text.font_type); + + if (gi->text.cursor_position < 0) + gi->text.cursor_position = 0; + else if (gi->text.cursor_position > strlen(gi->text.value)) + gi->text.cursor_position = strlen(gi->text.value); + + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else + { + /* if mouse button pressed outside text input gadget, deactivate it */ + CheckRangeOfNumericInputGadget(gi); + DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); + + gi->event.type = GD_EVENT_TEXT_LEAVING; + + if (gi->event_mask & GD_EVENT_TEXT_LEAVING) + gi->callback_action(gi); + + last_gi = NULL; + } + } + + gadget_pressed = + (button != 0 && last_gi == NULL && new_gi != NULL && press_event); + gadget_pressed_repeated = + (button != 0 && last_gi != NULL && new_gi == last_gi); + + gadget_released = (release_event && last_gi != NULL); + gadget_released_inside = (gadget_released && new_gi == last_gi); + gadget_released_off_borders = (gadget_released && new_gi != last_gi); + + gadget_moving = (button != 0 && last_gi != NULL && mouse_moving); + gadget_moving_inside = (gadget_moving && new_gi == last_gi); + gadget_moving_off_borders = (gadget_moving && new_gi != last_gi); + + /* if new gadget pressed, store this gadget */ + if (gadget_pressed) + last_gi = new_gi; + + /* 'gi' is actually handled gadget */ + gi = last_gi; + + /* if gadget is scrollbar, choose mouse position value */ + if (gi && gi->type & GD_TYPE_SCROLLBAR) + scrollbar_mouse_pos = + (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y); + + /* if mouse button released, no gadget needs to be handled anymore */ + if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT)) + last_gi = NULL; + + /* modify event position values even if no gadget is pressed */ + if (button == 0 && !release_event) + gi = new_gi; + + if (gi) + { + int last_x = gi->event.x; + int last_y = gi->event.y; + + gi->event.x = mx - gi->x; + gi->event.y = my - gi->y; + + if (gi->type == GD_TYPE_DRAWING_AREA) + { + gi->event.x /= gi->drawing.item_xsize; + gi->event.y /= gi->drawing.item_ysize; + + if (last_x != gi->event.x || last_y != gi->event.y) + changed_position = TRUE; + } + } + + /* handle gadget popup info text */ + if (last_info_gi != new_gi || + (new_gi && new_gi->type == GD_TYPE_DRAWING_AREA && changed_position)) + { + last_info_gi = new_gi; + + if (new_gi != NULL && (button == 0 || new_gi == last_gi)) + { + new_gi->event.type = 0; + new_gi->callback_info(new_gi); + } + else + default_callback_info(NULL); + } + + if (gadget_pressed) + { + if (gi->type == GD_TYPE_CHECK_BUTTON) + { + gi->checked = !gi->checked; + } + else if (gi->type == GD_TYPE_RADIO_BUTTON) + { + struct GadgetInfo *rgi = gadget_list_first_entry; + + while (rgi) + { + if (rgi->mapped && + rgi->type == GD_TYPE_RADIO_BUTTON && + rgi->radio_nr == gi->radio_nr && + rgi != gi) + { + rgi->checked = FALSE; + DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT); + } + + rgi = rgi->next; + } + + gi->checked = TRUE; + } + else if (gi->type & GD_TYPE_SCROLLBAR) + { + int mpos, gpos; + + if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL) + { + mpos = mx; + gpos = gi->x; + } + else + { + mpos = my; + gpos = gi->y; + } + + if (mpos >= gpos + gi->scrollbar.position && + mpos < gpos + gi->scrollbar.position + gi->scrollbar.size) + { + /* drag scrollbar */ + gi->scrollbar.drag_position = + scrollbar_mouse_pos - gi->scrollbar.position; + } + else + { + /* click scrollbar one scrollbar length up/left or down/right */ + + struct GadgetScrollbar *gs = &gi->scrollbar; + int old_item_position = gs->item_position; + + changed_position = FALSE; + + gs->item_position += + gs->items_visible * (mpos < gpos + gi->scrollbar.position ? -1 : +1); + + if (gs->item_position < 0) + gs->item_position = 0; + if (gs->item_position > gs->items_max - gs->items_visible) + gs->item_position = gs->items_max - gs->items_visible; + + if (old_item_position != gs->item_position) + { + gi->event.item_position = gs->item_position; + changed_position = TRUE; + } + + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, gs->item_position, + GDI_END); + + gi->state = GD_BUTTON_UNPRESSED; + gi->event.type = GD_EVENT_MOVING; + gi->event.off_borders = FALSE; + + if (gi->event_mask & GD_EVENT_MOVING && changed_position) + gi->callback_action(gi); + + /* don't handle this scrollbar anymore while mouse button pressed */ + last_gi = NULL; + + return; + } + } + + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + + gi->state = GD_BUTTON_PRESSED; + gi->event.type = GD_EVENT_PRESSED; + gi->event.button = button; + gi->event.off_borders = FALSE; + + /* initialize delay counter */ + DelayReached(&pressed_delay, 0); + + if (gi->event_mask & GD_EVENT_PRESSED) + gi->callback_action(gi); + } + + if (gadget_pressed_repeated) + { + gi->event.type = GD_EVENT_PRESSED; + + if (gi->event_mask & GD_EVENT_REPEATED && + DelayReached(&pressed_delay, GADGET_FRAME_DELAY)) + gi->callback_action(gi); + } + + if (gadget_moving) + { + if (gi->type & GD_TYPE_BUTTON) + { + if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED) + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED) + DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); + } + + if (gi->type & GD_TYPE_SCROLLBAR) + { + struct GadgetScrollbar *gs = &gi->scrollbar; + int old_item_position = gs->item_position; + + gs->position = scrollbar_mouse_pos - gs->drag_position; + + if (gs->position < 0) + gs->position = 0; + if (gs->position > gs->position_max) + gs->position = gs->position_max; + + gs->item_position = + gs->items_max * (gs->position + gs->correction) / gs->size_max; + + if (gs->item_position < 0) + gs->item_position = 0; + if (gs->item_position > gs->items_max - 1) + gs->item_position = gs->items_max - 1; + + if (old_item_position != gs->item_position) + { + gi->event.item_position = gs->item_position; + changed_position = TRUE; + } + + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + + gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ? + GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED); + gi->event.type = GD_EVENT_MOVING; + gi->event.off_borders = gadget_moving_off_borders; + + if (gi->event_mask & GD_EVENT_MOVING && changed_position && + (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS)) + gi->callback_action(gi); + } + + if (gadget_released_inside) + { + if (!(gi->type & GD_TYPE_TEXTINPUT)) + DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); + + gi->state = GD_BUTTON_UNPRESSED; + gi->event.type = GD_EVENT_RELEASED; + + if (gi->event_mask & GD_EVENT_RELEASED) + gi->callback_action(gi); + } + + if (gadget_released_off_borders) + { + if (gi->type & GD_TYPE_SCROLLBAR) + DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); + + gi->event.type = GD_EVENT_RELEASED; + + if (gi->event_mask & GD_EVENT_RELEASED && + gi->event_mask & GD_EVENT_OFF_BORDERS) + gi->callback_action(gi); + } +} + +void HandleGadgetsKeyInput(Key key) +{ + struct GadgetInfo *gi = last_gi; + char text[MAX_GADGET_TEXTSIZE]; + int text_length; + int cursor_pos; + char letter; + boolean legal_letter; + + if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped) + return; + + text_length = strlen(gi->text.value); + cursor_pos = gi->text.cursor_position; + letter = getCharFromKey(key); + legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ? + letter >= '0' && letter <= '9' : + letter != 0); + + if (legal_letter && text_length < gi->text.size) + { + strcpy(text, gi->text.value); + strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]); + gi->text.value[cursor_pos] = letter; + gi->text.cursor_position++; + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else if (key == KSYM_Left && cursor_pos > 0) + { + gi->text.cursor_position--; + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else if (key == KSYM_Right && cursor_pos < text_length) + { + gi->text.cursor_position++; + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else if (key == KSYM_BackSpace && cursor_pos > 0) + { + strcpy(text, gi->text.value); + strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]); + gi->text.cursor_position--; + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else if (key == KSYM_Delete && cursor_pos < text_length) + { + strcpy(text, gi->text.value); + strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]); + DrawGadget(gi, DG_PRESSED, DG_DIRECT); + } + else if (key == KSYM_Return) + { + CheckRangeOfNumericInputGadget(gi); + DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); + + gi->event.type = GD_EVENT_TEXT_RETURN; + + if (gi->event_mask & GD_EVENT_TEXT_RETURN) + gi->callback_action(gi); + + last_gi = NULL; + } +} diff --git a/src/libgame/buttons.h b/src/libgame/buttons.h new file mode 100644 index 00000000..38fbe634 --- /dev/null +++ b/src/libgame/buttons.h @@ -0,0 +1,265 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* buttons.h * +***********************************************************/ + +#ifndef BUTTONS_H +#define BUTTONS_H + +#include "libgame.h" + +/* the following definitions are also used by tools.c */ + +/* some positions in the video tape control window */ +#define VIDEO_DISPLAY1_XPOS 5 +#define VIDEO_DISPLAY1_YPOS 5 +#define VIDEO_DISPLAY2_XPOS 5 +#define VIDEO_DISPLAY2_YPOS 41 +#define VIDEO_DISPLAY_XSIZE 90 +#define VIDEO_DISPLAY_YSIZE 31 +#define VIDEO_BUTTON_XSIZE 18 +#define VIDEO_BUTTON_YSIZE 18 +#define VIDEO_CONTROL_XPOS 5 +#define VIDEO_CONTROL_YPOS 77 +#define VIDEO_CONTROL_XSIZE VIDEO_DISPLAY_XSIZE +#define VIDEO_CONTROL_YSIZE VIDEO_BUTTON_YSIZE + +/* values for video tape control */ +#define VIDEO_STATE_PLAY_OFF (1L << 0) +#define VIDEO_STATE_PLAY_ON (1L << 1) +#define VIDEO_STATE_PLAY (VIDEO_STATE_PLAY_OFF | VIDEO_STATE_PLAY_ON) +#define VIDEO_STATE_REC_OFF (1L << 2) +#define VIDEO_STATE_REC_ON (1L << 3) +#define VIDEO_STATE_REC (VIDEO_STATE_REC_OFF | VIDEO_STATE_REC_ON) +#define VIDEO_STATE_PAUSE_OFF (1L << 4) +#define VIDEO_STATE_PAUSE_ON (1L << 5) +#define VIDEO_STATE_PAUSE (VIDEO_STATE_PAUSE_OFF | VIDEO_STATE_PAUSE_ON) +#define VIDEO_STATE_DATE_OFF (1L << 6) +#define VIDEO_STATE_DATE_ON (1L << 7) +#define VIDEO_STATE_DATE (VIDEO_STATE_DATE_OFF | VIDEO_STATE_DATE_ON) +#define VIDEO_STATE_TIME_OFF (1L << 8) +#define VIDEO_STATE_TIME_ON (1L << 9) +#define VIDEO_STATE_TIME (VIDEO_STATE_TIME_OFF | VIDEO_STATE_TIME_ON) +#define VIDEO_PRESS_PLAY_ON (1L << 10) +#define VIDEO_PRESS_PLAY_OFF (1L << 11) +#define VIDEO_PRESS_PLAY (VIDEO_PRESS_PLAY_OFF | VIDEO_PRESS_PLAY_ON) +#define VIDEO_PRESS_REC_ON (1L << 12) +#define VIDEO_PRESS_REC_OFF (1L << 13) +#define VIDEO_PRESS_REC (VIDEO_PRESS_REC_OFF | VIDEO_PRESS_REC_ON) +#define VIDEO_PRESS_PAUSE_ON (1L << 14) +#define VIDEO_PRESS_PAUSE_OFF (1L << 15) +#define VIDEO_PRESS_PAUSE (VIDEO_PRESS_PAUSE_OFF | VIDEO_PRESS_PAUSE_ON) +#define VIDEO_PRESS_STOP_ON (1L << 16) +#define VIDEO_PRESS_STOP_OFF (1L << 17) +#define VIDEO_PRESS_STOP (VIDEO_PRESS_STOP_OFF | VIDEO_PRESS_STOP_ON) +#define VIDEO_PRESS_EJECT_ON (1L << 18) +#define VIDEO_PRESS_EJECT_OFF (1L << 19) +#define VIDEO_PRESS_EJECT (VIDEO_PRESS_EJECT_OFF | VIDEO_PRESS_EJECT_ON) + +/* special */ +#define VIDEO_STATE_FFWD_OFF ((1L << 20) | VIDEO_STATE_PAUSE_OFF) +#define VIDEO_STATE_FFWD_ON (1L << 21) +#define VIDEO_STATE_FFWD (VIDEO_STATE_FFWD_OFF | VIDEO_STATE_FFWD_ON) +#define VIDEO_STATE_PBEND_OFF (1L << 22) +#define VIDEO_STATE_PBEND_ON (1L << 23) +#define VIDEO_STATE_PBEND (VIDEO_STATE_PBEND_OFF | VIDEO_STATE_PBEND_ON) + +/* tags to draw video display labels or symbols only */ +#define VIDEO_DISPLAY_DEFAULT 0 +#define VIDEO_DISPLAY_LABEL_ONLY 1 +#define VIDEO_DISPLAY_SYMBOL_ONLY 2 + +void DrawVideoDisplay(unsigned long, unsigned long); +void DrawCompleteVideoDisplay(void); + + +/* NEW GADGET STUFF -------------------------------------------------------- */ + +/* gadget types */ +#define GD_TYPE_NORMAL_BUTTON (1 << 0) +#define GD_TYPE_CHECK_BUTTON (1 << 1) +#define GD_TYPE_RADIO_BUTTON (1 << 2) +#define GD_TYPE_DRAWING_AREA (1 << 3) +#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4) +#define GD_TYPE_TEXTINPUT_NUMERIC (1 << 5) +#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 6) +#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 7) + +#define GD_TYPE_BUTTON (GD_TYPE_NORMAL_BUTTON | \ + GD_TYPE_CHECK_BUTTON | \ + GD_TYPE_RADIO_BUTTON) +#define GD_TYPE_SCROLLBAR (GD_TYPE_SCROLLBAR_VERTICAL | \ + GD_TYPE_SCROLLBAR_HORIZONTAL) +#define GD_TYPE_TEXTINPUT (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \ + GD_TYPE_TEXTINPUT_NUMERIC) + +/* gadget events */ +#define GD_EVENT_PRESSED (1 << 0) +#define GD_EVENT_RELEASED (1 << 1) +#define GD_EVENT_MOVING (1 << 2) +#define GD_EVENT_REPEATED (1 << 3) +#define GD_EVENT_OFF_BORDERS (1 << 4) +#define GD_EVENT_TEXT_RETURN (1 << 5) +#define GD_EVENT_TEXT_LEAVING (1 << 6) + +/* gadget button states */ +#define GD_BUTTON_UNPRESSED 0 +#define GD_BUTTON_PRESSED 1 + +/* gadget structure constants */ +#define MAX_GADGET_TEXTSIZE 1024 +#define MAX_INFO_TEXTSIZE 1024 + +/* gadget creation tags */ +#define GDI_END 0 +#define GDI_CUSTOM_ID 1 +#define GDI_CUSTOM_TYPE_ID 2 +#define GDI_X 3 +#define GDI_Y 4 +#define GDI_WIDTH 5 +#define GDI_HEIGHT 6 +#define GDI_TYPE 7 +#define GDI_STATE 8 +#define GDI_CHECKED 9 +#define GDI_RADIO_NR 10 +#define GDI_NUMBER_VALUE 11 +#define GDI_NUMBER_MIN 12 +#define GDI_NUMBER_MAX 13 +#define GDI_TEXT_VALUE 14 +#define GDI_TEXT_SIZE 15 +#define GDI_TEXT_FONT 16 +#define GDI_DESIGN_UNPRESSED 17 +#define GDI_DESIGN_PRESSED 18 +#define GDI_ALT_DESIGN_UNPRESSED 19 +#define GDI_ALT_DESIGN_PRESSED 20 +#define GDI_BORDER_SIZE 21 +#define GDI_TEXTINPUT_DESIGN_WIDTH 22 +#define GDI_DECORATION_DESIGN 23 +#define GDI_DECORATION_POSITION 24 +#define GDI_DECORATION_SIZE 25 +#define GDI_DECORATION_SHIFTING 26 +#define GDI_EVENT_MASK 27 +#define GDI_EVENT 28 +#define GDI_CALLBACK_INFO 29 +#define GDI_CALLBACK_ACTION 30 +#define GDI_AREA_SIZE 31 +#define GDI_ITEM_SIZE 32 +#define GDI_SCROLLBAR_ITEMS_MAX 33 +#define GDI_SCROLLBAR_ITEMS_VISIBLE 34 +#define GDI_SCROLLBAR_ITEM_POSITION 35 +#define GDI_INFO_TEXT 36 + +typedef void (*gadget_function)(void *); + +struct GadgetBorder +{ + int size; /* size of gadget border */ + int width; /* for text input gadgets */ +}; + +struct GadgetDesign +{ + Bitmap bitmap; /* Bitmap with gadget surface */ + int x, y; /* position of rectangle in Bitmap */ +}; + +struct GadgetDecoration +{ + struct GadgetDesign design; /* decoration design structure */ + int x, y; /* position of deco on the gadget */ + int width, height; /* width and height of decoration */ + int xshift, yshift; /* deco shifting when gadget pressed */ +}; + +struct GadgetEvent +{ + unsigned long type; /* event type */ + int button; /* button number for button events */ + int x, y; /* gadget position at event time */ + boolean off_borders; /* mouse pointer outside gadget? */ + int item_x, item_y, item_position; /* new item position */ +}; + +struct GadgetDrawingArea +{ + int area_xsize, area_ysize; /* size of drawing area (in items) */ + int item_xsize, item_ysize; /* size of each item in drawing area */ +}; + +struct GadgetTextInput +{ + char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */ + int number_value; /* integer value, if numeric */ + int number_min; /* minimal allowed numeric value */ + int number_max; /* maximal allowed numeric value */ + int size; /* maximal size of input text */ + int cursor_position; /* actual cursor position */ + int font_type; /* font to use for text input */ +}; + +struct GadgetScrollbar +{ + int items_max; /* number of items to access */ + int items_visible; /* number of visible items */ + int item_position; /* actual item position */ + int size_max; /* this is either width or height */ + int size; /* scrollbar size on screen */ + int position; /* scrollbar position on screen */ + int position_max; /* bottom/right scrollbar position */ + int drag_position; /* drag position on scrollbar */ + int correction; /* scrollbar position correction */ +}; + +struct GadgetInfo +{ + int id; /* internal gadget identifier */ + int custom_id; /* custom gadget identifier */ + int custom_type_id; /* custom gadget type identifier */ + char info_text[MAX_INFO_TEXTSIZE]; /* short popup info text */ + int x, y; /* gadget position */ + int width, height; /* gadget size */ + unsigned long type; /* type (button, text input, ...) */ + unsigned long state; /* state (pressed, released, ...) */ + boolean checked; /* check/radio button state */ + int radio_nr; /* number of radio button series */ + boolean mapped; /* gadget is active */ + struct GadgetBorder border; /* gadget border design */ + struct GadgetDesign design[2]; /* 0: normal; 1: pressed */ + struct GadgetDesign alt_design[2]; /* alternative design */ + struct GadgetDecoration deco; /* decoration on top of gadget */ + unsigned long event_mask; /* possible events for this gadget */ + struct GadgetEvent event; /* actual gadget event */ + gadget_function callback_info; /* function for pop-up info text */ + gadget_function callback_action; /* function for gadget action */ + struct GadgetDrawingArea drawing; /* fields for drawing area gadget */ + struct GadgetTextInput text; /* fields for text input gadget */ + struct GadgetScrollbar scrollbar; /* fields for scrollbar gadget */ + struct GadgetInfo *next; /* next list entry */ +}; + +struct GadgetInfo *CreateGadget(int, ...); +void FreeGadget(struct GadgetInfo *); + +void ModifyGadget(struct GadgetInfo *, int, ...); +void RedrawGadget(struct GadgetInfo *); + +void MapGadget(struct GadgetInfo *); +void UnmapGadget(struct GadgetInfo *); +void UnmapAllGadgets(); +void RemapAllGadgets(); + +boolean anyTextGadgetActive(); +void ClickOnGadget(struct GadgetInfo *, int); + +void HandleGadgets(int, int, int); +void HandleGadgetsKeyInput(Key); + +#endif diff --git a/src/libgame/image.c b/src/libgame/image.c new file mode 100644 index 00000000..9dd4c249 --- /dev/null +++ b/src/libgame/image.c @@ -0,0 +1,554 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* image.c * +***********************************************************/ + +#if defined(TARGET_X11) + +#include "image.h" +#include "pcx.h" +#include "misc.h" + +/* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */ + +Image *newImage(unsigned int width, unsigned int height, unsigned int depth) +{ + Image *image; + const unsigned int bytes_per_pixel = 1; + int i; + + if (depth > 8) + Error(ERR_EXIT, "images with more than 256 colors are not supported"); + + depth = 8; + image = checked_malloc(sizeof(Image)); + image->data = checked_malloc(width * height * bytes_per_pixel); + image->width = width; + image->height = height; + image->depth = depth; + image->rgb.used = 0; + for (i=0; irgb.color_used[i] = FALSE; + + return image; +} + +void freeImage(Image *image) +{ + free(image->data); + free(image); +} + +#if defined(PLATFORM_UNIX) + +/* extra colors to try allocating in private color maps to minimize flashing */ +#define NOFLASH_COLORS 256 + +/* architecture independent value-to-memory conversion + note: the internal format is big endian */ + +#define value_to_memory(value, ptr, length) ( \ +(length) == 1 ? (*( (byte *)(ptr) ) = ( value ) ) : \ +(length) == 2 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+1) = ( value ) ) : \ +(length) == 3 ? (*( (byte *)(ptr) ) = (((unsigned long)(value))>>16), \ + *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+2) = ( value ) ) : \ + (*( (byte *)(ptr) ) = (((unsigned long)(value))>>24), \ + *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \ + *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \ + *(((byte *)(ptr))+3) = ( value ) )) + +static Pixmap Image_to_Mask(Image *image, Display *display, Window window) +{ + byte *src_ptr, *dst_ptr, *dst_ptr2; + unsigned int bytes_per_row; + unsigned int x, y; + byte bitmask; + byte *mask_data; + Pixmap mask_pixmap; + + bytes_per_row = (image->width + 7) / 8; + mask_data = checked_calloc(bytes_per_row * image->height); + + src_ptr = image->data; + dst_ptr = mask_data; + + /* create bitmap data which can be used by 'XCreateBitmapFromData()' + * directly to create a pixmap of depth 1 for use as a clip mask for + * the corresponding image pixmap + */ + + for (y=0; yheight; y++) + { + bitmask = 0x01; /* start with leftmost bit in the byte */ + dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */ + + for (x=0; xwidth; x++) + { + if (*src_ptr++) /* source pixel solid? (pixel index != 0) */ + *dst_ptr2 |= bitmask; /* then write a bit into the image mask */ + + if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */ + { + bitmask = 0x01; /* start again with leftmost bit position */ + dst_ptr2++; /* continue with next byte in image mask */ + } + } + + dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */ + } + + mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data, + image->width, image->height); + free(mask_data); + + return mask_pixmap; +} + +static int bitsPerPixelAtDepth(Display *display, int screen, int depth) +{ + XPixmapFormatValues *pixmap_format; + int i, num_pixmap_formats, bits_per_pixel = -1; + + /* get Pixmap formats supported by the X server */ + pixmap_format = XListPixmapFormats(display, &num_pixmap_formats); + + /* find format that matches the given depth */ + for (i=0; idisplay = display; + ximageinfo->depth = depth; + + switch (visual->class) + { + case TrueColor: + case DirectColor: + { + Pixel pixval; + unsigned int redcolors, greencolors, bluecolors; + unsigned int redstep, greenstep, bluestep; + unsigned int redbottom, greenbottom, bluebottom; + unsigned int redtop, greentop, bluetop; + + redvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); + greenvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); + bluevalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256); + + ximageinfo->cmap = global_cmap; + + retry_direct: /* tag we hit if a DirectColor allocation fails on + * default colormap */ + + /* calculate number of distinct colors in each band */ + + redcolors = greencolors = bluecolors = 1; + for (pixval=1; pixval; pixval <<= 1) + { + if (pixval & visual->red_mask) + redcolors <<= 1; + if (pixval & visual->green_mask) + greencolors <<= 1; + if (pixval & visual->blue_mask) + bluecolors <<= 1; + } + + /* consistency check */ + if (redcolors > visual->map_entries || + greencolors > visual->map_entries || + bluecolors > visual->map_entries) + Error(ERR_WARN, "inconsistency in color information"); + + redstep = 256 / redcolors; + greenstep = 256 / greencolors; + bluestep = 256 / bluecolors; + redbottom = greenbottom = bluebottom = 0; + redtop = greentop = bluetop = 0; + for (a=0; amap_entries; a++) + { + if (redbottom < 256) + redtop = redbottom + redstep; + if (greenbottom < 256) + greentop = greenbottom + greenstep; + if (bluebottom < 256) + bluetop = bluebottom + bluestep; + + xcolor.red = (redtop - 1) << 8; + xcolor.green = (greentop - 1) << 8; + xcolor.blue = (bluetop - 1) << 8; + if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) + { + /* if an allocation fails for a DirectColor default visual then + we should create a private colormap and try again. */ + + if ((visual->class == DirectColor) && + (visual == DefaultVisual(display, screen))) + { + global_cmap = XCopyColormapAndFree(display, global_cmap); + ximageinfo->cmap = global_cmap; + private_cmap = TRUE; + + goto retry_direct; + } + + /* something completely unexpected happened */ + + fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n"); + free(redvalue); + free(greenvalue); + free(bluevalue); + free(ximageinfo); + return NULL; + } + + /* fill in pixel values for each band at this intensity */ + + while ((redbottom < 256) && (redbottom < redtop)) + redvalue[redbottom++] = xcolor.pixel & visual->red_mask; + while ((greenbottom < 256) && (greenbottom < greentop)) + greenvalue[greenbottom++] = xcolor.pixel & visual->green_mask; + while ((bluebottom < 256) && (bluebottom < bluetop)) + bluevalue[bluebottom++] = xcolor.pixel & visual->blue_mask; + } + break; + } + + case PseudoColor: + + ximageinfo->cmap = global_cmap; + + for (a=0; argb.color_used[a]) + continue; + + xcolor.red = *(image->rgb.red + a); + xcolor.green = *(image->rgb.green + a); + xcolor.blue = *(image->rgb.blue + a); + + /* look if this color already exists in our colormap */ + if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) + { + if (!private_cmap) + { + if (options.verbose) + Error(ERR_RETURN, "switching to private colormap"); + + /* we just filled up the default colormap -- get a private one + which contains all already allocated colors */ + + global_cmap = XCopyColormapAndFree(display, global_cmap); + ximageinfo->cmap = global_cmap; + private_cmap = TRUE; + + /* allocate the rest of the color cells read/write */ + global_cmap_index = + (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS); + for (i=0; i=0; i--) + { + xcolor2.pixel = *(global_cmap_index + i); + xcolor2 = xcolor_private[xcolor2.pixel]; + + if (colorcell_used[xcolor2.pixel]) + continue; + + if ((xcolor.red & mask) == (xcolor2.red & mask) && + (xcolor.green & mask) == (xcolor2.green & mask) && + (xcolor.blue & mask) == (xcolor2.blue & mask)) + { + /* + printf("replacing color cell %ld with a close color\n", + xcolor2.pixel); + */ + color_found = TRUE; + break; + } + } + + if (mask == 0x0000) + break; + + mask = (mask << 1) & 0xffff; + } + + if (!color_found) /* no more free color cells */ + Error(ERR_EXIT, "cannot allocate enough color cells"); + + xcolor.pixel = xcolor2.pixel; + xcolor_private[xcolor.pixel] = xcolor; + colorcell_used[xcolor.pixel] = TRUE; + XStoreColor(display, ximageinfo->cmap, &xcolor); + free_cmap_entries--; + } + + *(ximageinfo->index + a) = xcolor.pixel; + } + + /* + printf("still %d free colormap entries\n", free_cmap_entries); + */ + + ximageinfo->no = a; /* number of pixels allocated for this image */ + break; + + default: + Error(ERR_RETURN, "display class not supported"); + Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); + break; + } + +#if DEBUG_TIMING + debug_print_timestamp(2, " ALLOCATING IMAGE COLORS: "); +#endif + + /* create XImage from internal image structure and convert it to Pixmap */ + + bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth); + bytes_per_pixel = (bits_per_pixel + 7) / 8; + + ximage = XCreateImage(display, visual, depth, ZPixmap, 0, + NULL, image->width, image->height, + 8, image->width * bytes_per_pixel); + ximage->data = + checked_malloc(image->width * image->height * bytes_per_pixel); + ximage->byte_order = MSBFirst; + + src_ptr = image->data; + dst_ptr = (byte *)ximage->data; + + switch (visual->class) + { + case DirectColor: + case TrueColor: + { + Pixel pixval; + + for (y=0; yheight; y++) /* general case */ + { + for (x=0; xwidth; x++) + { + pixval = *src_ptr++; + pixval = + redvalue[image->rgb.red[pixval] >> 8] | + greenvalue[image->rgb.green[pixval] >> 8] | + bluevalue[image->rgb.blue[pixval] >> 8]; + value_to_memory(pixval, dst_ptr, bytes_per_pixel); + dst_ptr += bytes_per_pixel; + } + } + break; + } + + case PseudoColor: + { + if (bytes_per_pixel == 1) /* (common) special case */ + { + for (y=0; yheight; y++) + for (x=0; xwidth; x++) + *dst_ptr++ = ximageinfo->index[c + *src_ptr++]; + } + else /* general case */ + { + for (y=0; yheight; y++) + { + for (x=0; xwidth; x++) + { + value_to_memory(ximageinfo->index[c + *src_ptr++], + dst_ptr, bytes_per_pixel); + dst_ptr += bytes_per_pixel; + } + } + } + break; + } + + default: + Error(ERR_RETURN, "display class not supported"); + Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); + break; + } + + if (redvalue) + { + free((byte *)redvalue); + free((byte *)greenvalue); + free((byte *)bluevalue); + } + +#if DEBUG_TIMING + debug_print_timestamp(2, " CONVERTING IMAGE TO XIMAGE:"); +#endif + + ximageinfo->pixmap = XCreatePixmap(display, window, + ximage->width, ximage->height, + ximageinfo->depth); + + XPutImage(ximageinfo->display, ximageinfo->pixmap, gc, + ximage, 0, 0, 0, 0, ximage->width, ximage->height); + + free(ximage->data); + ximage->data = NULL; + XDestroyImage(ximage); + + return(ximageinfo); +} + +void freeXImage(Image *image, XImageInfo *ximageinfo) +{ + if (ximageinfo->index != NULL && ximageinfo->no > 0) + XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index, + ximageinfo->no, 0); + /* this ^^^^^^^^^^^^^^ is wrong, because the used color cells + * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no' + * used color cells, but they are not at array position 0 - 'ximageinfo->no' + */ + + free(ximageinfo); +} + +int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename, + Pixmap *pixmap, Pixmap *pixmap_mask) +{ + Image *image; + XImageInfo *ximageinfo; + int screen; + Visual *visual; + int depth; + +#if DEBUG_TIMING + debug_print_timestamp(2, NULL); /* initialize timestamp function */ +#endif + + /* read the graphic file in PCX format to image structure */ + if ((image = Read_PCX_to_Image(filename)) == NULL) + return errno_pcx; + +#if DEBUG_TIMING + printf("%s:\n", filename); + debug_print_timestamp(2, " READING PCX FILE TO IMAGE: "); +#endif + + screen = DefaultScreen(display); + visual = DefaultVisual(display, screen); + depth = DefaultDepth(display, screen); + + /* convert image structure to X11 Pixmap */ + if (!(ximageinfo = Image_to_Pixmap(display, screen, visual, + window, gc, depth, image))) + Error(ERR_EXIT, "cannot convert Image to Pixmap"); + + /* if a private colormap has been created, install it */ + if (ximageinfo->cmap != DefaultColormap(display, screen)) + XSetWindowColormap(display, window, ximageinfo->cmap); + +#if DEBUG_TIMING + debug_print_timestamp(2, " CONVERTING IMAGE TO PIXMAP:"); +#endif + + /* create clip mask for the image */ + ximageinfo->pixmap_mask = Image_to_Mask(image, display, window); + +#if DEBUG_TIMING + debug_print_timestamp(2, " CONVERTING IMAGE TO MASK: "); +#endif + + *pixmap = ximageinfo->pixmap; + *pixmap_mask = ximageinfo->pixmap_mask; + + return PCX_Success; +} + +#endif /* PLATFORM_UNIX */ +#endif /* TARGET_X11 */ diff --git a/src/libgame/image.h b/src/libgame/image.h new file mode 100644 index 00000000..4f55fe3a --- /dev/null +++ b/src/libgame/image.h @@ -0,0 +1,63 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* image.h * +***********************************************************/ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "platform.h" + +#ifndef TARGET_SDL + +#include "types.h" +#include "x11.h" + +#define MAX_COLORS 256 /* maximal number of colors for each image */ + +typedef unsigned short Intensity; /* RGB intensity for X11 */ + +typedef struct +{ + Display *display; /* destination display */ + int depth; /* depth of destination drawable */ + Pixel index[MAX_COLORS]; /* array of pixel values */ + int no; /* number of pixels in the array */ + Colormap cmap; /* colormap used for image */ + Pixmap pixmap; /* final pixmap */ + Pixmap pixmap_mask; /* final pixmap of mask */ +} XImageInfo; + +struct RGBMap +{ + unsigned int used; /* number of colors used in RGB map */ + Intensity red[MAX_COLORS]; /* color values in X style */ + Intensity green[MAX_COLORS]; + Intensity blue[MAX_COLORS]; + boolean color_used[MAX_COLORS]; /* flag if color cell is used */ +}; + +typedef struct +{ + struct RGBMap rgb; /* RGB map of image if IRGB type */ + unsigned int width; /* width of image in pixels */ + unsigned int height; /* height of image in pixels */ + unsigned int depth; /* depth of image in bits if IRGB type */ + byte *data; /* image data */ +} Image; + +Image *newImage(unsigned int, unsigned int, unsigned int); +void freeImage(Image *); +void freeXImage(Image *, XImageInfo *); +int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *); + +#endif /* !TARGET_SDL */ +#endif /* IMAGE_H */ diff --git a/src/libgame/joystick_TMP.h b/src/libgame/joystick_TMP.h new file mode 100644 index 00000000..ccf728aa --- /dev/null +++ b/src/libgame/joystick_TMP.h @@ -0,0 +1,90 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* joystick.h * +***********************************************************/ + +#ifndef JOYSTICK_H +#define JOYSTICK_H + +/* values for the joystick */ +#define JOYSTICK_OFF 0 +#define JOYSTICK_AVAILABLE 1 + +#ifdef __FreeBSD__ +#include +#define DEV_JOYSTICK_0 "/dev/joy0" +#define DEV_JOYSTICK_1 "/dev/joy1" +#define DEV_JOYSTICK_2 "/dev/joy2" +#define DEV_JOYSTICK_3 "/dev/joy3" +#else +#define DEV_JOYSTICK_0 "/dev/js0" +#define DEV_JOYSTICK_1 "/dev/js1" +#define DEV_JOYSTICK_2 "/dev/js2" +#define DEV_JOYSTICK_3 "/dev/js3" +#endif + +/* get these values from the program 'js' from the joystick package, */ +/* set JOYSTICK_PERCENT to a threshold appropriate for your joystick */ + +#ifdef TARGET_SDL +#define JOYSTICK_XLEFT -32767 +#define JOYSTICK_XMIDDLE 0 +#define JOYSTICK_XRIGHT 32767 +#define JOYSTICK_YUPPER -32767 +#define JOYSTICK_YMIDDLE 0 +#define JOYSTICK_YLOWER 32767 +#else +#define JOYSTICK_XLEFT 30 +#define JOYSTICK_XMIDDLE 530 +#define JOYSTICK_XRIGHT 1250 +#define JOYSTICK_YUPPER 40 +#define JOYSTICK_YMIDDLE 680 +#define JOYSTICK_YLOWER 1440 +#endif + +#define JOYSTICK_PERCENT 25 + +#define JOY_LEFT MV_LEFT +#define JOY_RIGHT MV_RIGHT +#define JOY_UP MV_UP +#define JOY_DOWN MV_DOWN +#define JOY_BUTTON_1 (1<<4) +#define JOY_BUTTON_2 (1<<5) +#define JOY_BUTTON (JOY_BUTTON_1 | JOY_BUTTON_2) + +#define JOY_BUTTON_NOT_PRESSED 0 +#define JOY_BUTTON_PRESSED 1 +#define JOY_BUTTON_NEW_PRESSED 2 +#define JOY_BUTTON_NEW_RELEASED 3 + +#ifdef NO_JOYSTICK +#define JOYSTICK_STATUS JOYSTICK_OFF +#else +#define JOYSTICK_STATUS JOYSTICK_AVAILABLE +#endif + + +#if defined(TARGET_SDL) +SDL_Joystick *Get_SDL_Joystick(int); +boolean Open_SDL_Joystick(int); +void Close_SDL_Joystick(int); +boolean Check_SDL_JoystickOpened(int); +void HandleJoystickEvent(Event *); +int Get_SDL_Joystick_Axis(int, int); +#endif + +void CheckJoystickData(void); +int Joystick(int); +int JoystickButton(int); +int AnyJoystick(void); +int AnyJoystickButton(void); + +#endif /* JOYSTICK_H */ diff --git a/src/libgame/libgame.c b/src/libgame/libgame.c new file mode 100644 index 00000000..8c000c20 --- /dev/null +++ b/src/libgame/libgame.c @@ -0,0 +1,14 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* libgame.c * +***********************************************************/ + +#include "libgame.h" diff --git a/src/libgame/libgame.h b/src/libgame/libgame.h new file mode 100644 index 00000000..b2af1408 --- /dev/null +++ b/src/libgame/libgame.h @@ -0,0 +1,29 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* libgame.h * +***********************************************************/ + +#ifndef LIBGAME_H +#define LIBGAME_H + +#include "platform.h" +#include "types.h" +#include "private.h" +#include "system.h" +#include "random.h" +#include "buttons.h" +#include "text.h" +#include "sound.h" +#include "image.h" +#include "pcx.h" +#include "misc.h" + +#endif /* LIBGAME_H */ diff --git a/src/libgame/main_TMP.h b/src/libgame/main_TMP.h new file mode 120000 index 00000000..31e337c4 --- /dev/null +++ b/src/libgame/main_TMP.h @@ -0,0 +1 @@ +../main.h \ No newline at end of file diff --git a/src/libgame/misc.c b/src/libgame/misc.c new file mode 100644 index 00000000..bfc6d454 --- /dev/null +++ b/src/libgame/misc.c @@ -0,0 +1,1390 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* misc.c * +***********************************************************/ + +#include +#include +#include +#include +#include + +#if !defined(PLATFORM_WIN32) +#include +#include +#endif + +#include "libgame.h" + +#include "main_TMP.h" + +#include "misc.h" + +#include "joystick_TMP.h" + +#if defined(PLATFORM_MSDOS) +volatile unsigned long counter = 0; + +void increment_counter() +{ + counter++; +} + +END_OF_FUNCTION(increment_counter); +#endif + + +/* maximal allowed length of a command line option */ +#define MAX_OPTION_LEN 256 + +#ifdef TARGET_SDL +static unsigned long mainCounter(int mode) +{ + static unsigned long base_ms = 0; + unsigned long current_ms; + unsigned long counter_ms; + + current_ms = SDL_GetTicks(); + + /* reset base time in case of counter initializing or wrap-around */ + if (mode == INIT_COUNTER || current_ms < base_ms) + base_ms = current_ms; + + counter_ms = current_ms - base_ms; + + return counter_ms; /* return milliseconds since last init */ +} + +#else /* !TARGET_SDL */ + +#if defined(PLATFORM_UNIX) +static unsigned long mainCounter(int mode) +{ + static struct timeval base_time = { 0, 0 }; + struct timeval current_time; + unsigned long counter_ms; + + gettimeofday(¤t_time, NULL); + + /* reset base time in case of counter initializing or wrap-around */ + if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec) + base_time = current_time; + + counter_ms = (current_time.tv_sec - base_time.tv_sec) * 1000 + + (current_time.tv_usec - base_time.tv_usec) / 1000; + + return counter_ms; /* return milliseconds since last init */ +} +#endif /* PLATFORM_UNIX */ +#endif /* !TARGET_SDL */ + +void InitCounter() /* set counter back to zero */ +{ +#if !defined(PLATFORM_MSDOS) + mainCounter(INIT_COUNTER); +#else + LOCK_VARIABLE(counter); + LOCK_FUNCTION(increment_counter); + install_int_ex(increment_counter, BPS_TO_TIMER(100)); +#endif +} + +unsigned long Counter() /* get milliseconds since last call of InitCounter() */ +{ +#if !defined(PLATFORM_MSDOS) + return mainCounter(READ_COUNTER); +#else + return (counter * 10); +#endif +} + +static void sleep_milliseconds(unsigned long milliseconds_delay) +{ + boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE); + +#if defined(PLATFORM_MSDOS) + /* don't use select() to perform waiting operations under DOS/Windows + environment; always use a busy loop for waiting instead */ + do_busy_waiting = TRUE; +#endif + + if (do_busy_waiting) + { + /* we want to wait only a few ms -- if we assume that we have a + kernel timer resolution of 10 ms, we would wait far to long; + therefore it's better to do a short interval of busy waiting + to get our sleeping time more accurate */ + + unsigned long base_counter = Counter(), actual_counter = Counter(); + + while (actual_counter < base_counter + milliseconds_delay && + actual_counter >= base_counter) + actual_counter = Counter(); + } + else + { +#if defined(TARGET_SDL) + SDL_Delay(milliseconds_delay); +#else + struct timeval delay; + + delay.tv_sec = milliseconds_delay / 1000; + delay.tv_usec = 1000 * (milliseconds_delay % 1000); + + if (select(0, NULL, NULL, NULL, &delay) != 0) + Error(ERR_WARN, "sleep_milliseconds(): select() failed"); +#endif + } +} + +void Delay(unsigned long delay) /* Sleep specified number of milliseconds */ +{ + sleep_milliseconds(delay); +} + +boolean FrameReached(unsigned long *frame_counter_var, + unsigned long frame_delay) +{ + unsigned long actual_frame_counter = FrameCounter; + + if (actual_frame_counter < *frame_counter_var+frame_delay && + actual_frame_counter >= *frame_counter_var) + return(FALSE); + + *frame_counter_var = actual_frame_counter; + return(TRUE); +} + +boolean DelayReached(unsigned long *counter_var, + unsigned long delay) +{ + unsigned long actual_counter = Counter(); + + if (actual_counter < *counter_var + delay && + actual_counter >= *counter_var) + return(FALSE); + + *counter_var = actual_counter; + return(TRUE); +} + +void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) +{ + unsigned long actual_counter; + + while(1) + { + actual_counter = Counter(); + + if (actual_counter < *counter_var + delay && + actual_counter >= *counter_var) + sleep_milliseconds((*counter_var + delay - actual_counter) / 2); + else + break; + } + + *counter_var = actual_counter; +} + +/* int2str() returns a number converted to a string; + the used memory is static, but will be overwritten by later calls, + so if you want to save the result, copy it to a private string buffer; + there can be 10 local calls of int2str() without buffering the result -- + the 11th call will then destroy the result from the first call and so on. +*/ + +char *int2str(int number, int size) +{ + static char shift_array[10][40]; + static int shift_counter = 0; + char *s = shift_array[shift_counter]; + + shift_counter = (shift_counter + 1) % 10; + + if (size > 20) + size = 20; + + if (size) + { + sprintf(s, " %09d", number); + return &s[strlen(s) - size]; + } + else + { + sprintf(s, "%d", number); + return s; + } +} + +unsigned int SimpleRND(unsigned int max) +{ +#if defined(TARGET_SDL) + static unsigned long root = 654321; + unsigned long current_ms; + + current_ms = SDL_GetTicks(); + root = root * 4253261 + current_ms; + return (root % max); +#else + static unsigned long root = 654321; + struct timeval current_time; + + gettimeofday(¤t_time, NULL); + root = root * 4253261 + current_time.tv_sec + current_time.tv_usec; + return (root % max); +#endif +} + +#ifdef DEBUG +static unsigned int last_RND_value = 0; + +unsigned int last_RND() +{ + return last_RND_value; +} +#endif + +unsigned int RND(unsigned int max) +{ +#ifdef DEBUG + return (last_RND_value = random_linux_libc() % max); +#else + return (random_linux_libc() % max); +#endif +} + +unsigned int InitRND(long seed) +{ +#if defined(TARGET_SDL) + unsigned long current_ms; + + if (seed == NEW_RANDOMIZE) + { + current_ms = SDL_GetTicks(); + srandom_linux_libc((unsigned int) current_ms); + return (unsigned int) current_ms; + } + else + { + srandom_linux_libc((unsigned int) seed); + return (unsigned int) seed; + } +#else + struct timeval current_time; + + if (seed == NEW_RANDOMIZE) + { + gettimeofday(¤t_time, NULL); + srandom_linux_libc((unsigned int) current_time.tv_usec); + return (unsigned int) current_time.tv_usec; + } + else + { + srandom_linux_libc((unsigned int) seed); + return (unsigned int) seed; + } +#endif +} + +char *getLoginName() +{ +#if defined(PLATFORM_WIN32) + return ANONYMOUS_NAME; +#else + struct passwd *pwd; + + if ((pwd = getpwuid(getuid())) == NULL) + return ANONYMOUS_NAME; + else + return pwd->pw_name; +#endif +} + +char *getRealName() +{ +#if defined(PLATFORM_UNIX) + struct passwd *pwd; + + if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0) + return ANONYMOUS_NAME; + else + { + static char real_name[1024]; + char *from_ptr = pwd->pw_gecos, *to_ptr = real_name; + + if (strchr(pwd->pw_gecos, 'ß') == NULL) + return pwd->pw_gecos; + + /* the user's real name contains a 'ß' character (german sharp s), + which has no equivalent in upper case letters (which our fonts use) */ + while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2) + { + if (*from_ptr != 'ß') + *to_ptr++ = *from_ptr++; + else + { + from_ptr++; + *to_ptr++ = 's'; + *to_ptr++ = 's'; + } + } + *to_ptr = '\0'; + + return real_name; + } +#else /* !PLATFORM_UNIX */ + return ANONYMOUS_NAME; +#endif +} + +char *getHomeDir() +{ +#if defined(PLATFORM_UNIX) + static char *home_dir = NULL; + + if (!home_dir) + { + if (!(home_dir = getenv("HOME"))) + { + struct passwd *pwd; + + if ((pwd = getpwuid(getuid()))) + home_dir = pwd->pw_dir; + else + home_dir = "."; + } + } + + return home_dir; +#else + return "."; +#endif +} + +char *getPath2(char *path1, char *path2) +{ + char *complete_path = checked_malloc(strlen(path1) + 1 + + strlen(path2) + 1); + + sprintf(complete_path, "%s/%s", path1, path2); + return complete_path; +} + +char *getPath3(char *path1, char *path2, char *path3) +{ + char *complete_path = checked_malloc(strlen(path1) + 1 + + strlen(path2) + 1 + + strlen(path3) + 1); + + sprintf(complete_path, "%s/%s/%s", path1, path2, path3); + return complete_path; +} + +char *getStringCopy(char *s) +{ + char *s_copy; + + if (s == NULL) + return NULL; + + s_copy = checked_malloc(strlen(s) + 1); + + strcpy(s_copy, s); + return s_copy; +} + +char *getStringToLower(char *s) +{ + char *s_copy = checked_malloc(strlen(s) + 1); + char *s_ptr = s_copy; + + while (*s) + *s_ptr++ = tolower(*s++); + *s_ptr = '\0'; + + return s_copy; +} + +void MarkTileDirty(int x, int y) +{ + int xx = redraw_x1 + x; + int yy = redraw_y1 + y; + + if (!redraw[xx][yy]) + redraw_tiles++; + + redraw[xx][yy] = TRUE; + redraw_mask |= REDRAW_TILES; +} + +void SetBorderElement() +{ + int x, y; + + BorderElement = EL_LEERRAUM; + + for(y=0; y= MAX_OPTION_LEN) + Error(ERR_EXIT_HELP, "unrecognized option '%s'", option); + + strcpy(option_str, option); /* copy argument into buffer */ + option = option_str; + + if (strcmp(option, "--") == 0) /* stop scanning arguments */ + break; + + if (strncmp(option, "--", 2) == 0) /* treat '--' like '-' */ + option++; + + option_arg = strchr(option, '='); + if (option_arg == NULL) /* no '=' in option */ + option_arg = next_option; + else + { + *option_arg++ = '\0'; /* cut argument from option */ + if (*option_arg == '\0') /* no argument after '=' */ + Error(ERR_EXIT_HELP, "option '%s' has invalid argument", option_str); + } + + option_len = strlen(option); + + if (strcmp(option, "-") == 0) + Error(ERR_EXIT_HELP, "unrecognized option '%s'", option); + else if (strncmp(option, "-help", option_len) == 0) + { + printf("Usage: %s [options] [server.name [port]]\n" + "Options:\n" + " -d, --display machine:0 X server display\n" + " -b, --basepath directory alternative base directory\n" + " -l, --level directory alternative level directory\n" + " -s, --serveronly only start network server\n" + " -n, --network network multiplayer game\n" + " -v, --verbose verbose mode\n", + program_name); + exit(0); + } + else if (strncmp(option, "-display", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.display_name = option_arg; + if (option_arg == next_option) + options_left++; + } + else if (strncmp(option, "-basepath", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + /* this should be extended to separate options for ro and rw data */ + options.ro_base_directory = option_arg; + options.rw_base_directory = option_arg; + if (option_arg == next_option) + options_left++; + + /* adjust path for level directory accordingly */ + options.level_directory = + getPath2(options.ro_base_directory, LEVELS_DIRECTORY); + } + else if (strncmp(option, "-levels", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.level_directory = option_arg; + if (option_arg == next_option) + options_left++; + } + else if (strncmp(option, "-network", option_len) == 0) + { + options.network = TRUE; + } + else if (strncmp(option, "-serveronly", option_len) == 0) + { + options.serveronly = TRUE; + } + else if (strncmp(option, "-verbose", option_len) == 0) + { + options.verbose = TRUE; + } + else if (strncmp(option, "-debug", option_len) == 0) + { + options.debug = TRUE; + } + else if (*option == '-') + { + Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str); + } + else if (options.server_host == NULL) + { + options.server_host = *options_left; + } + else if (options.server_port == 0) + { + options.server_port = atoi(*options_left); + if (options.server_port < 1024) + Error(ERR_EXIT_HELP, "bad port number '%d'", options.server_port); + } + else + Error(ERR_EXIT_HELP, "too many arguments"); + + options_left++; + } +} + +void Error(int mode, char *format, ...) +{ + char *process_name = ""; + FILE *error = stderr; + + /* display warnings only when running in verbose mode */ + if (mode & ERR_WARN && !options.verbose) + return; + +#if !defined(PLATFORM_UNIX) + if ((error = openErrorFile()) == NULL) + { + printf("Cannot write to error output file!\n"); + CloseAllAndExit(1); + } +#endif + + if (mode & ERR_SOUND_SERVER) + process_name = " sound server"; + else if (mode & ERR_NETWORK_SERVER) + process_name = " network server"; + else if (mode & ERR_NETWORK_CLIENT) + process_name = " network client **"; + + if (format) + { + va_list ap; + + fprintf(error, "%s%s: ", program_name, process_name); + + if (mode & ERR_WARN) + fprintf(error, "warning: "); + + va_start(ap, format); + vfprintf(error, format, ap); + va_end(ap); + + fprintf(error, "\n"); + } + + if (mode & ERR_HELP) + fprintf(error, "%s: Try option '--help' for more information.\n", + program_name); + + if (mode & ERR_EXIT) + fprintf(error, "%s%s: aborting\n", program_name, process_name); + + if (error != stderr) + fclose(error); + + if (mode & ERR_EXIT) + { + if (mode & ERR_FROM_SERVER) + exit(1); /* child process: normal exit */ + else + CloseAllAndExit(1); /* main process: clean up stuff */ + } +} + +void *checked_malloc(unsigned long size) +{ + void *ptr; + + ptr = malloc(size); + + if (ptr == NULL) + Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); + + return ptr; +} + +void *checked_calloc(unsigned long size) +{ + void *ptr; + + ptr = calloc(1, size); + + if (ptr == NULL) + Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); + + return ptr; +} + +short getFile16BitInteger(FILE *file, int byte_order) +{ + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + return ((fgetc(file) << 8) | + (fgetc(file) << 0)); + else /* BYTE_ORDER_LITTLE_ENDIAN */ + return ((fgetc(file) << 0) | + (fgetc(file) << 8)); +} + +void putFile16BitInteger(FILE *file, short value, int byte_order) +{ + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + { + fputc((value >> 8) & 0xff, file); + fputc((value >> 0) & 0xff, file); + } + else /* BYTE_ORDER_LITTLE_ENDIAN */ + { + fputc((value >> 0) & 0xff, file); + fputc((value >> 8) & 0xff, file); + } +} + +int getFile32BitInteger(FILE *file, int byte_order) +{ + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + return ((fgetc(file) << 24) | + (fgetc(file) << 16) | + (fgetc(file) << 8) | + (fgetc(file) << 0)); + else /* BYTE_ORDER_LITTLE_ENDIAN */ + return ((fgetc(file) << 0) | + (fgetc(file) << 8) | + (fgetc(file) << 16) | + (fgetc(file) << 24)); +} + +void putFile32BitInteger(FILE *file, int value, int byte_order) +{ + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + { + fputc((value >> 24) & 0xff, file); + fputc((value >> 16) & 0xff, file); + fputc((value >> 8) & 0xff, file); + fputc((value >> 0) & 0xff, file); + } + else /* BYTE_ORDER_LITTLE_ENDIAN */ + { + fputc((value >> 0) & 0xff, file); + fputc((value >> 8) & 0xff, file); + fputc((value >> 16) & 0xff, file); + fputc((value >> 24) & 0xff, file); + } +} + +void getFileChunk(FILE *file, char *chunk_buffer, int *chunk_length, + int byte_order) +{ + const int chunk_identifier_length = 4; + + /* read chunk identifier */ + fgets(chunk_buffer, chunk_identifier_length + 1, file); + + /* read chunk length */ + *chunk_length = getFile32BitInteger(file, byte_order); +} + +void putFileChunk(FILE *file, char *chunk_name, int chunk_length, + int byte_order) +{ + /* write chunk identifier */ + fputs(chunk_name, file); + + /* write chunk length */ + putFile32BitInteger(file, chunk_length, byte_order); +} + +#define TRANSLATE_KEYSYM_TO_KEYNAME 0 +#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1 +#define TRANSLATE_X11KEYNAME_TO_KEYSYM 2 + +void translate_keyname(Key *keysym, char **x11name, char **name, int mode) +{ + static struct + { + Key key; + char *x11name; + char *name; + } translate_key[] = + { + /* normal cursor keys */ + { KSYM_Left, "XK_Left", "cursor left" }, + { KSYM_Right, "XK_Right", "cursor right" }, + { KSYM_Up, "XK_Up", "cursor up" }, + { KSYM_Down, "XK_Down", "cursor down" }, + + /* keypad cursor keys */ +#ifdef KSYM_KP_Left + { KSYM_KP_Left, "XK_KP_Left", "keypad left" }, + { KSYM_KP_Right, "XK_KP_Right", "keypad right" }, + { KSYM_KP_Up, "XK_KP_Up", "keypad up" }, + { KSYM_KP_Down, "XK_KP_Down", "keypad down" }, +#endif + + /* other keypad keys */ +#ifdef KSYM_KP_Enter + { KSYM_KP_Enter, "XK_KP_Enter", "keypad enter" }, + { KSYM_KP_Add, "XK_KP_Add", "keypad +" }, + { KSYM_KP_Subtract, "XK_KP_Subtract", "keypad -" }, + { KSYM_KP_Multiply, "XK_KP_Multiply", "keypad mltply" }, + { KSYM_KP_Divide, "XK_KP_Divide", "keypad /" }, + { KSYM_KP_Separator,"XK_KP_Separator", "keypad ," }, +#endif + + /* modifier keys */ + { KSYM_Shift_L, "XK_Shift_L", "left shift" }, + { KSYM_Shift_R, "XK_Shift_R", "right shift" }, + { KSYM_Control_L, "XK_Control_L", "left control" }, + { KSYM_Control_R, "XK_Control_R", "right control" }, + { KSYM_Meta_L, "XK_Meta_L", "left meta" }, + { KSYM_Meta_R, "XK_Meta_R", "right meta" }, + { KSYM_Alt_L, "XK_Alt_L", "left alt" }, + { KSYM_Alt_R, "XK_Alt_R", "right alt" }, + { KSYM_Super_L, "XK_Super_L", "left super" }, /* Win-L */ + { KSYM_Super_R, "XK_Super_R", "right super" }, /* Win-R */ + { KSYM_Mode_switch, "XK_Mode_switch", "mode switch" }, /* Alt-R */ + { KSYM_Multi_key, "XK_Multi_key", "multi key" }, /* Ctrl-R */ + + /* some special keys */ + { KSYM_BackSpace, "XK_BackSpace", "backspace" }, + { KSYM_Delete, "XK_Delete", "delete" }, + { KSYM_Insert, "XK_Insert", "insert" }, + { KSYM_Tab, "XK_Tab", "tab" }, + { KSYM_Home, "XK_Home", "home" }, + { KSYM_End, "XK_End", "end" }, + { KSYM_Page_Up, "XK_Page_Up", "page up" }, + { KSYM_Page_Down, "XK_Page_Down", "page down" }, + { KSYM_Menu, "XK_Menu", "menu" }, /* Win-Menu */ + + /* ASCII 0x20 to 0x40 keys (except numbers) */ + { KSYM_space, "XK_space", "space" }, + { KSYM_exclam, "XK_exclam", "!" }, + { KSYM_quotedbl, "XK_quotedbl", "\"" }, + { KSYM_numbersign, "XK_numbersign", "#" }, + { KSYM_dollar, "XK_dollar", "$" }, + { KSYM_percent, "XK_percent", "%" }, + { KSYM_ampersand, "XK_ampersand", "&" }, + { KSYM_apostrophe, "XK_apostrophe", "'" }, + { KSYM_parenleft, "XK_parenleft", "(" }, + { KSYM_parenright, "XK_parenright", ")" }, + { KSYM_asterisk, "XK_asterisk", "*" }, + { KSYM_plus, "XK_plus", "+" }, + { KSYM_comma, "XK_comma", "," }, + { KSYM_minus, "XK_minus", "-" }, + { KSYM_period, "XK_period", "." }, + { KSYM_slash, "XK_slash", "/" }, + { KSYM_colon, "XK_colon", ":" }, + { KSYM_semicolon, "XK_semicolon", ";" }, + { KSYM_less, "XK_less", "<" }, + { KSYM_equal, "XK_equal", "=" }, + { KSYM_greater, "XK_greater", ">" }, + { KSYM_question, "XK_question", "?" }, + { KSYM_at, "XK_at", "@" }, + + /* more ASCII keys */ + { KSYM_bracketleft, "XK_bracketleft", "[" }, + { KSYM_backslash, "XK_backslash", "backslash" }, + { KSYM_bracketright,"XK_bracketright", "]" }, + { KSYM_asciicircum, "XK_asciicircum", "circumflex" }, + { KSYM_underscore, "XK_underscore", "_" }, + { KSYM_grave, "XK_grave", "grave" }, + { KSYM_quoteleft, "XK_quoteleft", "quote left" }, + { KSYM_braceleft, "XK_braceleft", "brace left" }, + { KSYM_bar, "XK_bar", "bar" }, + { KSYM_braceright, "XK_braceright", "brace right" }, + { KSYM_asciitilde, "XK_asciitilde", "ascii tilde" }, + + /* special (non-ASCII) keys */ + { KSYM_Adiaeresis, "XK_Adiaeresis", "Ä" }, + { KSYM_Odiaeresis, "XK_Odiaeresis", "Ö" }, + { KSYM_Udiaeresis, "XK_Udiaeresis", "Ü" }, + { KSYM_adiaeresis, "XK_adiaeresis", "ä" }, + { KSYM_odiaeresis, "XK_odiaeresis", "ö" }, + { KSYM_udiaeresis, "XK_udiaeresis", "ü" }, + { KSYM_ssharp, "XK_ssharp", "sharp s" }, + + /* end-of-array identifier */ + { 0, NULL, NULL } + }; + + int i; + + if (mode == TRANSLATE_KEYSYM_TO_KEYNAME) + { + static char name_buffer[30]; + Key key = *keysym; + + if (key >= KSYM_A && key <= KSYM_Z) + sprintf(name_buffer, "%c", 'A' + (char)(key - KSYM_A)); + else if (key >= KSYM_a && key <= KSYM_z) + sprintf(name_buffer, "%c", 'a' + (char)(key - KSYM_a)); + else if (key >= KSYM_0 && key <= KSYM_9) + sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0)); + else if (key >= KSYM_KP_0 && key <= KSYM_KP_9) + sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0)); + else if (key >= KSYM_F1 && key <= KSYM_F24) + sprintf(name_buffer, "function F%d", (int)(key - KSYM_F1 + 1)); + else if (key == KSYM_UNDEFINED) + strcpy(name_buffer, "(undefined)"); + else + { + i = 0; + + do + { + if (key == translate_key[i].key) + { + strcpy(name_buffer, translate_key[i].name); + break; + } + } + while (translate_key[++i].name); + + if (!translate_key[i].name) + strcpy(name_buffer, "(unknown)"); + } + + *name = name_buffer; + } + else if (mode == TRANSLATE_KEYSYM_TO_X11KEYNAME) + { + static char name_buffer[30]; + Key key = *keysym; + + if (key >= KSYM_A && key <= KSYM_Z) + sprintf(name_buffer, "XK_%c", 'A' + (char)(key - KSYM_A)); + else if (key >= KSYM_a && key <= KSYM_z) + sprintf(name_buffer, "XK_%c", 'a' + (char)(key - KSYM_a)); + else if (key >= KSYM_0 && key <= KSYM_9) + sprintf(name_buffer, "XK_%c", '0' + (char)(key - KSYM_0)); + else if (key >= KSYM_KP_0 && key <= KSYM_KP_9) + sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - KSYM_KP_0)); + else if (key >= KSYM_F1 && key <= KSYM_F24) + sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_F1 + 1)); + else if (key == KSYM_UNDEFINED) + strcpy(name_buffer, "[undefined]"); + else + { + i = 0; + + do + { + if (key == translate_key[i].key) + { + strcpy(name_buffer, translate_key[i].x11name); + break; + } + } + while (translate_key[++i].x11name); + + if (!translate_key[i].x11name) + sprintf(name_buffer, "0x%04lx", (unsigned long)key); + } + + *x11name = name_buffer; + } + else if (mode == TRANSLATE_X11KEYNAME_TO_KEYSYM) + { + Key key = KSYM_UNDEFINED; + char *name_ptr = *x11name; + + if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4) + { + char c = name_ptr[3]; + + if (c >= 'A' && c <= 'Z') + key = KSYM_A + (Key)(c - 'A'); + else if (c >= 'a' && c <= 'z') + key = KSYM_a + (Key)(c - 'a'); + else if (c >= '0' && c <= '9') + key = KSYM_0 + (Key)(c - '0'); + } + else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7) + { + char c = name_ptr[6]; + + if (c >= '0' && c <= '9') + key = KSYM_0 + (Key)(c - '0'); + } + else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6) + { + char c1 = name_ptr[4]; + char c2 = name_ptr[5]; + int d = 0; + + if ((c1 >= '0' && c1 <= '9') && + ((c2 >= '0' && c1 <= '9') || c2 == '\0')) + d = atoi(&name_ptr[4]); + + if (d >=1 && d <= 24) + key = KSYM_F1 + (Key)(d - 1); + } + else if (strncmp(name_ptr, "XK_", 3) == 0) + { + i = 0; + + do + { + if (strcmp(name_ptr, translate_key[i].x11name) == 0) + { + key = translate_key[i].key; + break; + } + } + while (translate_key[++i].x11name); + } + else if (strncmp(name_ptr, "0x", 2) == 0) + { + unsigned long value = 0; + + name_ptr += 2; + + while (name_ptr) + { + char c = *name_ptr++; + int d = -1; + + if (c >= '0' && c <= '9') + d = (int)(c - '0'); + else if (c >= 'a' && c <= 'f') + d = (int)(c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + d = (int)(c - 'A' + 10); + + if (d == -1) + { + value = -1; + break; + } + + value = value * 16 + d; + } + + if (value != -1) + key = (Key)value; + } + + *keysym = key; + } +} + +char *getKeyNameFromKey(Key key) +{ + char *name; + + translate_keyname(&key, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME); + return name; +} + +char *getX11KeyNameFromKey(Key key) +{ + char *x11name; + + translate_keyname(&key, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME); + return x11name; +} + +Key getKeyFromX11KeyName(char *x11name) +{ + Key key; + + translate_keyname(&key, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM); + return key; +} + +char getCharFromKey(Key key) +{ + char *keyname = getKeyNameFromKey(key); + char letter = 0; + + if (strlen(keyname) == 1) + letter = keyname[0]; + else if (strcmp(keyname, "space") == 0) + letter = ' '; + else if (strcmp(keyname, "circumflex") == 0) + letter = '^'; + + return letter; +} + +#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0 +#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1 + +void translate_joyname(int *joysymbol, char **name, int mode) +{ + static struct + { + int joysymbol; + char *name; + } translate_joy[] = + { + { JOY_LEFT, "joystick_left" }, + { JOY_RIGHT, "joystick_right" }, + { JOY_UP, "joystick_up" }, + { JOY_DOWN, "joystick_down" }, + { JOY_BUTTON_1, "joystick_button_1" }, + { JOY_BUTTON_2, "joystick_button_2" }, + }; + + int i; + + if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME) + { + *name = "[undefined]"; + + for (i=0; i<6; i++) + { + if (*joysymbol == translate_joy[i].joysymbol) + { + *name = translate_joy[i].name; + break; + } + } + } + else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL) + { + *joysymbol = 0; + + for (i=0; i<6; i++) + { + if (strcmp(*name, translate_joy[i].name) == 0) + { + *joysymbol = translate_joy[i].joysymbol; + break; + } + } + } +} + +char *getJoyNameFromJoySymbol(int joysymbol) +{ + char *name; + + translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME); + return name; +} + +int getJoySymbolFromJoyName(char *name) +{ + int joysymbol; + + translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL); + return joysymbol; +} + +int getJoystickNrFromDeviceName(char *device_name) +{ + char c; + int joystick_nr = 0; + + if (device_name == NULL || device_name[0] == '\0') + return 0; + + c = device_name[strlen(device_name) - 1]; + + if (c >= '0' && c <= '9') + joystick_nr = (int)(c - '0'); + + if (joystick_nr < 0 || joystick_nr >= MAX_PLAYERS) + joystick_nr = 0; + + return joystick_nr; +} + +/* ------------------------------------------------------------------------- */ +/* some functions to handle lists of level directories */ +/* ------------------------------------------------------------------------- */ + +struct LevelDirInfo *newLevelDirInfo() +{ + return checked_calloc(sizeof(struct LevelDirInfo)); +} + +void pushLevelDirInfo(struct LevelDirInfo **node_first, + struct LevelDirInfo *node_new) +{ + node_new->next = *node_first; + *node_first = node_new; +} + +int numLevelDirInfo(struct LevelDirInfo *node) +{ + int num = 0; + + while (node) + { + num++; + node = node->next; + } + + return num; +} + +boolean validLevelSeries(struct LevelDirInfo *node) +{ + return (node != NULL && !node->node_group && !node->parent_link); +} + +struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node) +{ + if (node == NULL) + { + if (leveldir_first) /* start with first level directory entry */ + return getFirstValidLevelSeries(leveldir_first); + else + return NULL; + } + else if (node->node_group) /* enter level group (step down into tree) */ + return getFirstValidLevelSeries(node->node_group); + else if (node->parent_link) /* skip start entry of level group */ + { + if (node->next) /* get first real level series entry */ + return getFirstValidLevelSeries(node->next); + else /* leave empty level group and go on */ + return getFirstValidLevelSeries(node->node_parent->next); + } + else /* this seems to be a regular level series */ + return node; +} + +struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node) +{ + if (node == NULL) + return NULL; + + if (node->node_parent == NULL) /* top level group */ + return leveldir_first; + else /* sub level group */ + return node->node_parent->node_group; +} + +int numLevelDirInfoInGroup(struct LevelDirInfo *node) +{ + return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node)); +} + +int posLevelDirInfo(struct LevelDirInfo *node) +{ + struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node); + int pos = 0; + + while (node_cmp) + { + if (node_cmp == node) + return pos; + + pos++; + node_cmp = node_cmp->next; + } + + return 0; +} + +struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos) +{ + struct LevelDirInfo *node_default = node; + int pos_cmp = 0; + + while (node) + { + if (pos_cmp == pos) + return node; + + pos_cmp++; + node = node->next; + } + + return node_default; +} + +struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node, + char *filename) +{ + if (filename == NULL) + return NULL; + + while (node) + { + if (node->node_group) + { + struct LevelDirInfo *node_group; + + node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename); + + if (node_group) + return node_group; + } + else if (!node->parent_link) + { + if (strcmp(filename, node->filename) == 0) + return node; + } + + node = node->next; + } + + return NULL; +} + +struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename) +{ + return getLevelDirInfoFromFilenameExt(leveldir_first, filename); +} + +void dumpLevelDirInfo(struct LevelDirInfo *node, int depth) +{ + int i; + + while (node) + { + for (i=0; ifilename); + + if (node->node_group != NULL) + dumpLevelDirInfo(node->node_group, depth + 1); + + node = node->next; + } +} + +void sortLevelDirInfo(struct LevelDirInfo **node_first, + int (*compare_function)(const void *, const void *)) +{ + int num_nodes = numLevelDirInfo(*node_first); + struct LevelDirInfo **sort_array; + struct LevelDirInfo *node = *node_first; + int i = 0; + + if (num_nodes == 0) + return; + + /* allocate array for sorting structure pointers */ + sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *)); + + /* writing structure pointers to sorting array */ + while (i < num_nodes && node) /* double boundary check... */ + { + sort_array[i] = node; + + i++; + node = node->next; + } + + /* sorting the structure pointers in the sorting array */ + qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *), + compare_function); + + /* update the linkage of list elements with the sorted node array */ + for (i=0; inext = sort_array[i + 1]; + sort_array[num_nodes - 1]->next = NULL; + + /* update the linkage of the main list anchor pointer */ + *node_first = sort_array[0]; + + free(sort_array); + + /* now recursively sort the level group structures */ + node = *node_first; + while (node) + { + if (node->node_group != NULL) + sortLevelDirInfo(&node->node_group, compare_function); + + node = node->next; + } +} + +inline void swap_numbers(int *i1, int *i2) +{ + int help = *i1; + + *i1 = *i2; + *i2 = help; +} + +inline 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; +} + + +/* ------------------------------------------------------------------------- */ +/* the following is only for debugging purpose and normally not used */ +/* ------------------------------------------------------------------------- */ + +#define DEBUG_NUM_TIMESTAMPS 3 + +void debug_print_timestamp(int counter_nr, char *message) +{ + static long counter[DEBUG_NUM_TIMESTAMPS][2]; + + if (counter_nr >= DEBUG_NUM_TIMESTAMPS) + Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); + + counter[counter_nr][0] = Counter(); + + if (message) + printf("%s %.2f seconds\n", message, + (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); + + counter[counter_nr][1] = Counter(); +} diff --git a/src/libgame/misc.h b/src/libgame/misc.h new file mode 100644 index 00000000..3002844e --- /dev/null +++ b/src/libgame/misc.h @@ -0,0 +1,103 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* misc.h * +***********************************************************/ + +#ifndef MISC_H +#define MISC_H + +#include +#include + +#include "libgame.h" + +/* values for InitCounter() and Counter() */ +#define INIT_COUNTER 0 +#define READ_COUNTER 1 + +/* values for InitRND() */ +#define NEW_RANDOMIZE -1 + +/* values for Error() */ +#define ERR_RETURN 0 +#define ERR_WARN (1 << 0) +#define ERR_EXIT (1 << 1) +#define ERR_HELP (1 << 2) +#define ERR_SOUND_SERVER (1 << 3) +#define ERR_NETWORK_SERVER (1 << 4) +#define ERR_NETWORK_CLIENT (1 << 5) +#define ERR_FROM_SERVER (ERR_SOUND_SERVER | ERR_NETWORK_SERVER) +#define ERR_EXIT_HELP (ERR_EXIT | ERR_HELP) +#define ERR_EXIT_SOUND_SERVER (ERR_EXIT | ERR_SOUND_SERVER) +#define ERR_EXIT_NETWORK_SERVER (ERR_EXIT | ERR_NETWORK_SERVER) +#define ERR_EXIT_NETWORK_CLIENT (ERR_EXIT | ERR_NETWORK_CLIENT) + +/* values for getFile...() and putFile...() */ +#define BYTE_ORDER_BIG_ENDIAN 0 +#define BYTE_ORDER_LITTLE_ENDIAN 1 + +void InitCounter(void); +unsigned long Counter(void); +void Delay(unsigned long); +boolean FrameReached(unsigned long *, unsigned long); +boolean DelayReached(unsigned long *, unsigned long); +void WaitUntilDelayReached(unsigned long *, unsigned long); +char *int2str(int, int); +unsigned int SimpleRND(unsigned int); +unsigned int RND(unsigned int); +unsigned int InitRND(long); +char *getLoginName(void); +char *getRealName(void); +char *getHomeDir(void); +char *getPath2(char *, char *); +char *getPath3(char *, char *, char*); +char *getStringCopy(char *); +char *getStringToLower(char *); +void MarkTileDirty(int, int); +void SetBorderElement(); +void GetOptions(char **); +void Error(int, char *, ...); +void *checked_malloc(unsigned long); +void *checked_calloc(unsigned long); +short getFile16BitInteger(FILE *, int); +void putFile16BitInteger(FILE *, short, int); +int getFile32BitInteger(FILE *, int); +void putFile32BitInteger(FILE *, int, int); +void getFileChunk(FILE *, char *, int *, int); +void putFileChunk(FILE *, char *, int, int); +char *getKeyNameFromKey(Key); +char *getX11KeyNameFromKey(Key); +Key getKeyFromX11KeyName(char *); +char getCharFromKey(Key); +char *getJoyNameFromJoySymbol(int); +int getJoySymbolFromJoyName(char *); +int getJoystickNrFromDeviceName(char *); + +struct LevelDirInfo *newLevelDirInfo(); +void pushLevelDirInfo(struct LevelDirInfo **, struct LevelDirInfo *); +int numLevelDirInfo(struct LevelDirInfo *); +boolean validLevelSeries(struct LevelDirInfo *); +struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *); +struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *); +int numLevelDirInfoInGroup(struct LevelDirInfo *); +int posLevelDirInfo(struct LevelDirInfo *); +struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *, int); +struct LevelDirInfo *getLevelDirInfoFromFilename(char *); +void dumpLevelDirInfo(struct LevelDirInfo *, int); +void sortLevelDirInfo(struct LevelDirInfo **, + int (*compare_function)(const void *, const void *)); + +inline void swap_numbers(int *, int *); +inline void swap_number_pairs(int *, int *, int *, int *); + +void debug_print_timestamp(int, char *); + +#endif /* MISC_H */ diff --git a/src/libgame/msdos.c b/src/libgame/msdos.c new file mode 100644 index 00000000..cc8aedd7 --- /dev/null +++ b/src/libgame/msdos.c @@ -0,0 +1,929 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* msdos.c * +***********************************************************/ + +#include "libgame.h" + +#if defined(PLATFORM_MSDOS) + +/* allegro driver declarations */ +DECLARE_GFX_DRIVER_LIST(GFX_DRIVER_VBEAF GFX_DRIVER_VESA2L GFX_DRIVER_VESA1) +DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8) +DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB) +DECLARE_MIDI_DRIVER_LIST() +DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD) + +/* allegro global variables */ +extern volatile int key_shifts; +extern int num_joysticks; +extern JOYSTICK_INFO joy[]; +extern int i_love_bill; + +/* internal variables of msdos.c */ +static boolean keyboard_auto_repeat = TRUE; +static int key_press_state[MAX_SCANCODES]; +static XEvent event_buffer[MAX_EVENT_BUFFER]; +static int pending_events; +static boolean joystick_event; +static boolean mouse_installed = FALSE; +static int last_mouse_pos; +static int last_mouse_b; +static int last_joystick_state; +static BITMAP* video_bitmap; + +static RGB global_colormap[MAX_COLORS]; +static int global_colormap_entries_used = 0; + +boolean wait_for_vsync; + +/* +extern int playing_sounds; +extern struct SoundControl playlist[MAX_SOUNDS_PLAYING]; +extern struct SoundControl emptySoundControl; +*/ + +static BITMAP *Read_PCX_to_AllegroBitmap(char *); + +static void allegro_init_drivers() +{ + int i; + + for (i=0; i 0) + mouse_installed = TRUE; + + last_joystick_state = 0; + joystick_event = FALSE; +} + +static boolean allegro_init_audio() +{ + reserve_voices(MAX_SOUNDS_PLAYING, 0); + + if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1) + if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) + return FALSE; + + return TRUE; +} + +static boolean hide_mouse(Display *display, int x, int y, + unsigned int width, unsigned int height) +{ + if (mouse_x + display->mouse_ptr->w < x || mouse_x > x + width) + return FALSE; + if (mouse_y + display->mouse_ptr->h < y || mouse_y > y + height) + return FALSE; + + show_mouse(NULL); + + return TRUE; +} + +static void unhide_mouse(Display *display) +{ + if (mouse_installed) + show_mouse(video_bitmap); +} + +static KeySym ScancodeToKeySym(byte scancode) +{ + switch(scancode) + { + case KEY_ESC: return XK_Escape; + case KEY_1: return XK_1; + case KEY_2: return XK_2; + case KEY_3: return XK_3; + case KEY_4: return XK_4; + case KEY_5: return XK_5; + case KEY_6: return XK_6; + case KEY_7: return XK_7; + case KEY_8: return XK_8; + case KEY_9: return XK_9; + case KEY_0: return XK_0; + case KEY_MINUS: return XK_minus; + case KEY_EQUALS: return XK_equal; + case KEY_BACKSPACE: return XK_BackSpace; + case KEY_TAB: return XK_Tab; + case KEY_Q: return XK_q; + case KEY_W: return XK_w; + case KEY_E: return XK_e; + case KEY_R: return XK_r; + case KEY_T: return XK_t; + case KEY_Y: return XK_y; + case KEY_U: return XK_u; + case KEY_I: return XK_i; + case KEY_O: return XK_o; + case KEY_P: return XK_p; + case KEY_OPENBRACE: return XK_braceleft; + case KEY_CLOSEBRACE: return XK_braceright; + case KEY_ENTER: return XK_Return; + case KEY_LCONTROL: return XK_Control_L; + case KEY_A: return XK_a; + case KEY_S: return XK_s; + case KEY_D: return XK_d; + case KEY_F: return XK_f; + case KEY_G: return XK_g; + case KEY_H: return XK_h; + case KEY_J: return XK_j; + case KEY_K: return XK_k; + case KEY_L: return XK_l; + case KEY_COLON: return XK_colon; + case KEY_QUOTE: return XK_apostrophe; + case KEY_TILDE: return XK_asciitilde; + case KEY_LSHIFT: return XK_Shift_L; + case KEY_BACKSLASH: return XK_backslash; + case KEY_Z: return XK_z; + case KEY_X: return XK_x; + case KEY_C: return XK_c; + case KEY_V: return XK_v; + case KEY_B: return XK_b; + case KEY_N: return XK_n; + case KEY_M: return XK_m; + case KEY_COMMA: return XK_comma; + case KEY_STOP: return XK_period; + case KEY_SLASH: return XK_slash; + case KEY_RSHIFT: return XK_Shift_R; + case KEY_ASTERISK: return XK_KP_Multiply; + case KEY_ALT: return XK_Alt_L; + case KEY_SPACE: return XK_space; + case KEY_CAPSLOCK: return XK_Caps_Lock; + case KEY_F1: return XK_F1; + case KEY_F2: return XK_F2; + case KEY_F3: return XK_F3; + case KEY_F4: return XK_F4; + case KEY_F5: return XK_F5; + case KEY_F6: return XK_F6; + case KEY_F7: return XK_F7; + case KEY_F8: return XK_F8; + case KEY_F9: return XK_F9; + case KEY_F10: return XK_F10; + case KEY_NUMLOCK: return XK_Num_Lock; + case KEY_SCRLOCK: return XK_Scroll_Lock; + case KEY_HOME: return XK_Home; + case KEY_UP: return XK_Up; + case KEY_PGUP: return XK_Page_Up; + case KEY_MINUS_PAD: return XK_KP_Subtract; + case KEY_LEFT: return XK_Left; + case KEY_5_PAD: return XK_KP_5; + case KEY_RIGHT: return XK_Right; + case KEY_PLUS_PAD: return XK_KP_Add; + case KEY_END: return XK_End; + case KEY_DOWN: return XK_Down; + case KEY_PGDN: return XK_Page_Down; + case KEY_INSERT: return XK_Insert; + case KEY_DEL: return XK_Delete; + case KEY_PRTSCR: return XK_Print; + case KEY_F11: return XK_F11; + case KEY_F12: return XK_F12; + case KEY_LWIN: return XK_Meta_L; + case KEY_RWIN: return XK_Meta_R; + case KEY_MENU: return XK_Menu; + case KEY_PAD: return XK_VoidSymbol; + case KEY_RCONTROL: return XK_Control_R; + case KEY_ALTGR: return XK_Alt_R; + case KEY_SLASH2: return XK_KP_Divide; + case KEY_PAUSE: return XK_Pause; + + case NEW_KEY_BACKSLASH: return XK_backslash; + case NEW_KEY_1_PAD: return XK_KP_1; + case NEW_KEY_2_PAD: return XK_KP_2; + case NEW_KEY_3_PAD: return XK_KP_3; + case NEW_KEY_4_PAD: return XK_KP_4; + case NEW_KEY_5_PAD: return XK_KP_5; + case NEW_KEY_6_PAD: return XK_KP_6; + case NEW_KEY_7_PAD: return XK_KP_7; + case NEW_KEY_8_PAD: return XK_KP_8; + case NEW_KEY_9_PAD: return XK_KP_9; + case NEW_KEY_0_PAD: return XK_KP_0; + case NEW_KEY_STOP_PAD: return XK_KP_Separator; + case NEW_KEY_EQUALS_PAD: return XK_KP_Equal; + case NEW_KEY_SLASH_PAD: return XK_KP_Divide; + case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply; + case NEW_KEY_ENTER_PAD: return XK_KP_Enter; + + default: return XK_VoidSymbol; + } +} + +void XMapWindow(Display *display, Window window) +{ + int x, y; + unsigned int width, height; + boolean mouse_off; + + x = display->screens[display->default_screen].x; + y = display->screens[display->default_screen].y; + width = display->screens[display->default_screen].width; + height = display->screens[display->default_screen].height; + + mouse_off = hide_mouse(display, x, y, width, height); + blit((BITMAP *)window, video_bitmap, 0, 0, x, y, width, height); + + if (mouse_off) + unhide_mouse(display); +} + +static unsigned long AllocColorCell(int r, int g, int b) +{ + byte pixel_mapping = 0; + int i; + + r >>= 10; + g >>= 10; + b >>= 10; + + /* try to use existing colors from the global colormap */ + for (i=0; idefault_screen = 0; + display->screens = screen; + display->mouse_ptr = mouse_bitmap; + + allegro_init(); + allegro_init_drivers(); + set_color_depth(8); + + /* force Windows 95 to switch to fullscreen mode */ + set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); + rest(200); + set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0); + + return display; +} + +Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, unsigned long border, + unsigned long background) +{ + video_bitmap = create_video_bitmap(XRES, YRES); + clear_to_color(video_bitmap, background); + + display->screens[display->default_screen].video_bitmap = video_bitmap; + display->screens[display->default_screen].x = x; + display->screens[display->default_screen].y = y; + display->screens[display->default_screen].width = XRES; + display->screens[display->default_screen].height = YRES; + + set_mouse_sprite(display->mouse_ptr); + +#if 0 + set_mouse_sprite_focus(1, 1); +#endif + + set_mouse_speed(1, 1); + set_mouse_range(display->screens[display->default_screen].x + 1, + display->screens[display->default_screen].y + 1, + display->screens[display->default_screen].x + WIN_XSIZE + 1, + display->screens[display->default_screen].y + WIN_YSIZE + 1); + + show_video_bitmap(video_bitmap); + + return (Window)video_bitmap; +} + +Status XStringListToTextProperty(char **list, int count, + XTextProperty *text_prop_return) +{ + char *string; + + if (count >= 1) + { + string = malloc(strlen(list[0] + 1)); + strcpy(string, list[0]); + text_prop_return->value = (unsigned char *)string; + return 1; + } + else + text_prop_return = NULL; + + return 0; +} + +void XFree(void *data) +{ + if (data) + free(data); +} + +GC XCreateGC(Display *display, Drawable d, unsigned long value_mask, + XGCValues *values) +{ + XGCValues *gcv; + gcv = malloc(sizeof(XGCValues)); + gcv->foreground = values->foreground; + gcv->background = values->background; + gcv->graphics_exposures = values->graphics_exposures; + gcv->clip_mask = values->clip_mask; + gcv->clip_x_origin = values->clip_x_origin; + gcv->clip_y_origin = values->clip_y_origin; + gcv->value_mask = value_mask; + return (GC)gcv; +} + +void XSetClipMask(Display *display, GC gc, Pixmap pixmap) +{ + XGCValues *gcv = (XGCValues *)gc; + + gcv->clip_mask = pixmap; + gcv->value_mask |= GCClipMask; +} + +void XSetClipOrigin(Display *display, GC gc, int x, int y) +{ + XGCValues *gcv = (XGCValues *)gc; + + gcv->clip_x_origin = x; + gcv->clip_x_origin = y; +} + +void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, + unsigned int width, unsigned int height) +{ + boolean mouse_off = FALSE; + + if ((BITMAP *)d == video_bitmap) + { + x += display->screens[display->default_screen].x; + y += display->screens[display->default_screen].y; + freeze_mouse_flag = TRUE; + mouse_off = hide_mouse(display, x, y, width, height); + } + + rectfill((BITMAP *)d, x, y, x + width - 1, y + height - 1, + ((XGCValues *)gc)->foreground); + + if (mouse_off) + unhide_mouse(display); + + freeze_mouse_flag = FALSE; +} + +Pixmap XCreatePixmap(Display *display, Drawable d, unsigned int width, + unsigned int height, unsigned int depth) +{ + BITMAP *bitmap = NULL; + + if (gfx_capabilities & GFX_HW_VRAM_BLIT && + width == FXSIZE && height == FYSIZE) + bitmap = create_video_bitmap(width, height); + + if (bitmap == NULL) + bitmap = create_bitmap(width, height); + + return (Pixmap)bitmap; +} + +void XSync(Display *display, Bool discard_events) +{ + wait_for_vsync = TRUE; +} + +inline void XCopyArea(Display *display, Drawable src, Drawable dest, GC gc, + int src_x, int src_y, + unsigned int width, unsigned int height, + int dest_x, int dest_y) +{ + boolean mouse_off = FALSE; + + if ((BITMAP *)src == video_bitmap) + { + src_x += display->screens[display->default_screen].x; + src_y += display->screens[display->default_screen].y; + } + + if ((BITMAP *)dest == video_bitmap) + { + dest_x += display->screens[display->default_screen].x; + dest_y += display->screens[display->default_screen].y; + freeze_mouse_flag = TRUE; + mouse_off = hide_mouse(display, dest_x, dest_y, width, height); + } + + if (wait_for_vsync) + { + wait_for_vsync = FALSE; + vsync(); + } + + if (((XGCValues *)gc)->value_mask & GCClipMask) + masked_blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y, + width, height); + else + blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y, + width, height); + + if (mouse_off) + unhide_mouse(display); + + freeze_mouse_flag = FALSE; +} + +static BITMAP *Image_to_AllegroBitmap(Image *image) +{ + BITMAP *bitmap; + byte *src_ptr = image->data; + byte pixel_mapping[MAX_COLORS]; + unsigned int depth = 8; + +#if 0 + int i, j, x, y; +#else + int i, x, y; +#endif + + /* allocate new allegro bitmap structure */ + if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL) + { + errno_pcx = PCX_NoMemory; + return NULL; + } + + clear(bitmap); + + /* try to use existing colors from the global colormap */ + for (i=0; irgb.color_used[i]) + continue; + + +#if 0 + r = image->rgb.red[i] >> 10; + g = image->rgb.green[i] >> 10; + b = image->rgb.blue[i] >> 10; + + for (j=0; jrgb.red[i], + image->rgb.green[i], + image->rgb.blue[i]); +#endif + + } + + /* copy bitmap data */ + for (y=0; yheight; y++) + for (x=0; xwidth; x++) + putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]); + + return bitmap; +} + +static BITMAP *Read_PCX_to_AllegroBitmap(char *filename) +{ + BITMAP *bitmap; + Image *image; + + /* read the graphic file in PCX format to internal image structure */ + if ((image = Read_PCX_to_Image(filename)) == NULL) + return NULL; + + /* convert internal image structure to allegro bitmap structure */ + if ((bitmap = Image_to_AllegroBitmap(image)) == NULL) + return NULL; + + set_palette(global_colormap); + + return bitmap; +} + +int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename, + Pixmap *pixmap, Pixmap *pixmap_mask) +{ + BITMAP *bitmap; + + if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) + return errno_pcx; + + *pixmap = (Pixmap)bitmap; + *pixmap_mask = (Pixmap)bitmap; + + return PCX_Success; +} + +int XReadBitmapFile(Display *display, Drawable d, char *filename, + unsigned int *width_return, unsigned int *height_return, + Pixmap *bitmap_return, + int *x_hot_return, int *y_hot_return) +{ + BITMAP *bitmap; + + if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) + return BitmapOpenFailed; + + *width_return = bitmap->w; + *height_return = bitmap->h; + *x_hot_return = -1; + *y_hot_return = -1; + *bitmap_return = (Pixmap)bitmap; + + return BitmapSuccess; +} + +void XFreePixmap(Display *display, Pixmap pixmap) +{ + if (pixmap != DUMMY_MASK && + (is_memory_bitmap((BITMAP *)pixmap) || + is_screen_bitmap((BITMAP *)pixmap))) + destroy_bitmap((BITMAP *)pixmap); +} + +void XFreeGC(Display *display, GC gc) +{ + XGCValues *gcv; + + gcv = (XGCValues *)gc; + if (gcv) + free(gcv); +} + +void XCloseDisplay(Display *display) +{ + BITMAP *bitmap = video_bitmap; + + if (is_screen_bitmap(bitmap)) + destroy_bitmap(bitmap); + + if (display->screens) + free(display->screens); + + if (display) + free(display); + + /* return to text mode (or DOS box on Windows screen) */ + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); +} + +void XNextEvent(Display *display, XEvent *event_return) +{ + while (!pending_events) + XPending(display); + + memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent)); + pending_events--; +} + +static void NewKeyEvent(int key_press_state, KeySym keysym) +{ + XKeyEvent *xkey; + + if (pending_events >= MAX_EVENT_BUFFER) + return; + + pending_events++; + xkey = (XKeyEvent *)&event_buffer[pending_events]; + xkey->type = key_press_state; + xkey->state = (unsigned int)keysym; +} + +#define HANDLE_RAW_KB_ALL_KEYS 0 +#define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY 1 + +static int modifier_scancode[] = +{ + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_ALT, + KEY_ALTGR, + KEY_LWIN, + KEY_RWIN, + KEY_CAPSLOCK, + KEY_NUMLOCK, + KEY_SCRLOCK, + -1 +}; + +static void HandleKeyboardRaw(int mode) +{ + int i; + + for (i=0; i> 8); + int ascii = (key_info & 0xff); + KeySym keysym = ScancodeToKeySym(scancode); + + if (scancode == KEY_PAD) + { + /* keys on the numeric keypad return just scancode 'KEY_PAD' + for some reason, so we must handle them separately */ + + if (ascii >= '0' && ascii <= '9') + keysym = XK_KP_0 + (KeySym)(ascii - '0'); + else if (ascii == '.') + keysym = XK_KP_Separator; + } + else if (ascii >= ' ' && ascii <= 'Z') + keysym = XK_space + (KeySym)(ascii - ' '); + else if (ascii == '^') + keysym = XK_asciicircum; + else if (ascii == '_') + keysym = XK_underscore; + else if (ascii == 'Ä') + keysym = XK_Adiaeresis; + else if (ascii == 'Ö') + keysym = XK_Odiaeresis; + else if (ascii == 'Ü') + keysym = XK_Udiaeresis; + else if (ascii == 'ä') + keysym = XK_adiaeresis; + else if (ascii == 'ö') + keysym = XK_odiaeresis; + else if (ascii == 'ü') + keysym = XK_udiaeresis; + else if (ascii == 'ß') + keysym = XK_ssharp; + + NewKeyEvent(KeyPress, keysym); + } + else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)) + { + /* the allegro function keypressed() does not give us single pressed + modifier keys, so we must detect them with the internal global + allegro variable 'key_shifts' and then handle them separately */ + + HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY); + } +} + +int XPending(Display *display) +{ + XButtonEvent *xbutton; + XMotionEvent *xmotion; + int i; + + /* When using 'HandleKeyboardRaw()', keyboard input is also stored in + the allegro keyboard input buffer and would be available a second + time by calling 'HandleKeyboardEvent()'. To avoid double keyboard + events, the allegro function 'clear_keybuf()' must be called each + time when switching from calling 'HandleKeyboardRaw()' to calling + 'HandleKeyboardEvent()' to get keyboard input, which is actually + done by 'XAutoRepeatOn()' which sets keyboard_auto_repeat to TRUE. */ + + /* keyboard event */ + if (keyboard_auto_repeat) + HandleKeyboardEvent(); + else + HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS); + + /* mouse motion event */ + if (mouse_pos != last_mouse_pos) + { + last_mouse_pos = mouse_pos; + pending_events++; + xmotion = (XMotionEvent *)&event_buffer[pending_events]; + xmotion->type = MotionNotify; + xmotion->x = mouse_x - display->screens[display->default_screen].x; + xmotion->y = mouse_y - display->screens[display->default_screen].y; + } + + /* mouse button event */ + if (mouse_b != last_mouse_b) + { + for (i=0; i<3; i++) /* check all three mouse buttons */ + { + int bitmask = (1 << i); + + if ((last_mouse_b & bitmask) != (mouse_b & bitmask)) + { + int mapping[3] = { 1, 3, 2 }; + + pending_events++; + xbutton = (XButtonEvent *)&event_buffer[pending_events]; + xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease); + xbutton->button = mapping[i]; + xbutton->x = mouse_x - display->screens[display->default_screen].x; + xbutton->y = mouse_y - display->screens[display->default_screen].y; + } + } + last_mouse_b = mouse_b; + } + + return pending_events; +} + +KeySym XLookupKeysym(XKeyEvent *key_event, int index) +{ + return key_event->state; +} + +int XLookupString(XKeyEvent *key_event, char *buffer, int buffer_size, + KeySym *key, XComposeStatus *compose) +{ + *key = key_event->state; + return 0; +} + +void XSetForeground(Display *display, GC gc, unsigned long pixel) +{ + XGCValues *gcv = (XGCValues *)gc; + + gcv->foreground = pixel; +} + +void XDrawLine(Display *display, Drawable d, GC gc, + int x1, int y1, int x2, int y2) +{ + XGCValues *gcv = (XGCValues *)gc; + boolean mouse_off = FALSE; + + if ((BITMAP *)d == video_bitmap) + { + x1 += display->screens[display->default_screen].x; + y1 += display->screens[display->default_screen].y; + x2 += display->screens[display->default_screen].x; + y2 += display->screens[display->default_screen].y; + freeze_mouse_flag = TRUE; + mouse_off = hide_mouse(display, MIN(x1, x2), MIN(y1, y2), + MAX(x1, x2) - MIN(x1, x2), + MAX(y1, y2) - MIN(y1, y2)); + } + + line((BITMAP *)d, x1, y1, x2, y2, gcv->foreground); + + if (mouse_off) + unhide_mouse(display); + + freeze_mouse_flag = FALSE; +} + +void XDestroyImage(XImage *ximage) +{ +} + +Bool XQueryPointer(Display *display, Window window, + Window *root, Window *child, int *root_x, int *root_y, + int *win_x, int *win_y, unsigned int *mask) +{ + *win_x = mouse_x - display->screens[display->default_screen].x; + *win_y = mouse_y - display->screens[display->default_screen].y; + + return True; +} + +void XAutoRepeatOn(Display *display) +{ + keyboard_auto_repeat = TRUE; + clear_keybuf(); +} + +void XAutoRepeatOff(Display *display) +{ + keyboard_auto_repeat = FALSE; +} + +boolean MSDOSOpenAudio(void) +{ + return allegro_init_audio(); +} + +boolean MSDOSCloseAudio(void) +{ + /* nothing to be done here */ +} + +void NetworkServer(int port, int serveronly) +{ + Error(ERR_WARN, "networking not supported in DOS version"); +} + +#endif /* PLATFORM_MSDOS */ diff --git a/src/libgame/msdos.h b/src/libgame/msdos.h new file mode 100644 index 00000000..26a3f791 --- /dev/null +++ b/src/libgame/msdos.h @@ -0,0 +1,712 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* msdos.h * +***********************************************************/ + +#ifndef MSDOS_H +#define MSDOS_H + +#include +#include + +/* symbol 'window' is defined in DJGPP cross-compiler in libc.a(conio.o) */ +#define window window_djgpp + +/* system dependent definitions */ + +#define TARGET_STRING "DOS" + +/* allegro defines TRUE as -1 */ +#ifdef TRUE +#undef TRUE +#undef FALSE +#endif + +#define TRUE 1 +#define FALSE 0 + +#define XRES 800 +#define YRES 600 + +/* additional Allegro keyboard mapping */ + +/* The following are all undefined in Allegro */ +#define NEW_KEY_BACKSLASH 86 +#define NEW_KEY_1_PAD 101 +#define NEW_KEY_2_PAD 102 +#define NEW_KEY_3_PAD 103 +#define NEW_KEY_4_PAD 104 +#define NEW_KEY_5_PAD 105 +#define NEW_KEY_6_PAD 106 +#define NEW_KEY_7_PAD 107 +#define NEW_KEY_8_PAD 108 +#define NEW_KEY_9_PAD 109 +#define NEW_KEY_0_PAD 110 +#define NEW_KEY_STOP_PAD 111 +#define NEW_KEY_EQUALS_PAD 112 +#define NEW_KEY_SLASH_PAD 113 +#define NEW_KEY_ASTERISK_PAD 114 +#define NEW_KEY_ENTER_PAD 115 + +/* X11 keyboard mapping (from 'keysymdef.h') */ + +#define XK_VoidSymbol 0xFFFFFF /* void symbol */ + +/* + * TTY Functions, cleverly chosen to map to ascii, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code. + */ + +#define XK_BackSpace 0xFF08 /* back space, back char */ +#define XK_Tab 0xFF09 +#define XK_Linefeed 0xFF0A /* Linefeed, LF */ +#define XK_Clear 0xFF0B +#define XK_Return 0xFF0D /* Return, enter */ +#define XK_Pause 0xFF13 /* Pause, hold */ +#define XK_Scroll_Lock 0xFF14 +#define XK_Sys_Req 0xFF15 +#define XK_Escape 0xFF1B +#define XK_Delete 0xFFFF /* Delete, rubout */ + +/* International & multi-key character composition */ + +#define XK_Multi_key 0xFF20 /* Multi-key character compose */ +#define XK_SingleCandidate 0xFF3C +#define XK_MultipleCandidate 0xFF3D +#define XK_PreviousCandidate 0xFF3E + +/* Cursor control & motion */ + +#define XK_Home 0xFF50 +#define XK_Left 0xFF51 /* Move left, left arrow */ +#define XK_Up 0xFF52 /* Move up, up arrow */ +#define XK_Right 0xFF53 /* Move right, right arrow */ +#define XK_Down 0xFF54 /* Move down, down arrow */ +#define XK_Prior 0xFF55 /* Prior, previous */ +#define XK_Page_Up 0xFF55 +#define XK_Next 0xFF56 /* Next */ +#define XK_Page_Down 0xFF56 +#define XK_End 0xFF57 /* EOL */ +#define XK_Begin 0xFF58 /* BOL */ + +/* Misc Functions */ + +#define XK_Select 0xFF60 /* Select, mark */ +#define XK_Print 0xFF61 +#define XK_Execute 0xFF62 /* Execute, run, do */ +#define XK_Insert 0xFF63 /* Insert, insert here */ +#define XK_Undo 0xFF65 /* Undo, oops */ +#define XK_Redo 0xFF66 /* redo, again */ +#define XK_Menu 0xFF67 +#define XK_Find 0xFF68 /* Find, search */ +#define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xFF6A /* Help */ +#define XK_Break 0xFF6B +#define XK_Mode_switch 0xFF7E /* Character set switch */ +#define XK_script_switch 0xFF7E /* Alias for mode_switch */ +#define XK_Num_Lock 0xFF7F + +/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + +#define XK_KP_Space 0xFF80 /* space */ +#define XK_KP_Tab 0xFF89 +#define XK_KP_Enter 0xFF8D /* enter */ +#define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xFF92 +#define XK_KP_F3 0xFF93 +#define XK_KP_F4 0xFF94 +#define XK_KP_Home 0xFF95 +#define XK_KP_Left 0xFF96 +#define XK_KP_Up 0xFF97 +#define XK_KP_Right 0xFF98 +#define XK_KP_Down 0xFF99 +#define XK_KP_Prior 0xFF9A +#define XK_KP_Page_Up 0xFF9A +#define XK_KP_Next 0xFF9B +#define XK_KP_Page_Down 0xFF9B +#define XK_KP_End 0xFF9C +#define XK_KP_Begin 0xFF9D +#define XK_KP_Insert 0xFF9E +#define XK_KP_Delete 0xFF9F +#define XK_KP_Equal 0xFFBD /* equals */ +#define XK_KP_Multiply 0xFFAA +#define XK_KP_Add 0xFFAB +#define XK_KP_Separator 0xFFAC /* separator, often comma */ +#define XK_KP_Subtract 0xFFAD +#define XK_KP_Decimal 0xFFAE +#define XK_KP_Divide 0xFFAF + +#define XK_KP_0 0xFFB0 +#define XK_KP_1 0xFFB1 +#define XK_KP_2 0xFFB2 +#define XK_KP_3 0xFFB3 +#define XK_KP_4 0xFFB4 +#define XK_KP_5 0xFFB5 +#define XK_KP_6 0xFFB6 +#define XK_KP_7 0xFFB7 +#define XK_KP_8 0xFFB8 +#define XK_KP_9 0xFFB9 + +/* + * Auxilliary Functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1 0xFFBE +#define XK_F2 0xFFBF +#define XK_F3 0xFFC0 +#define XK_F4 0xFFC1 +#define XK_F5 0xFFC2 +#define XK_F6 0xFFC3 +#define XK_F7 0xFFC4 +#define XK_F8 0xFFC5 +#define XK_F9 0xFFC6 +#define XK_F10 0xFFC7 +#define XK_F11 0xFFC8 +#define XK_L1 0xFFC8 +#define XK_F12 0xFFC9 +#define XK_L2 0xFFC9 +#define XK_F13 0xFFCA +#define XK_L3 0xFFCA +#define XK_F14 0xFFCB +#define XK_L4 0xFFCB +#define XK_F15 0xFFCC +#define XK_L5 0xFFCC +#define XK_F16 0xFFCD +#define XK_L6 0xFFCD +#define XK_F17 0xFFCE +#define XK_L7 0xFFCE +#define XK_F18 0xFFCF +#define XK_L8 0xFFCF +#define XK_F19 0xFFD0 +#define XK_L9 0xFFD0 +#define XK_F20 0xFFD1 +#define XK_L10 0xFFD1 +#define XK_F21 0xFFD2 +#define XK_R1 0xFFD2 +#define XK_F22 0xFFD3 +#define XK_R2 0xFFD3 +#define XK_F23 0xFFD4 +#define XK_R3 0xFFD4 +#define XK_F24 0xFFD5 +#define XK_R4 0xFFD5 +#define XK_F25 0xFFD6 +#define XK_R5 0xFFD6 +#define XK_F26 0xFFD7 +#define XK_R6 0xFFD7 +#define XK_F27 0xFFD8 +#define XK_R7 0xFFD8 +#define XK_F28 0xFFD9 +#define XK_R8 0xFFD9 +#define XK_F29 0xFFDA +#define XK_R9 0xFFDA +#define XK_F30 0xFFDB +#define XK_R10 0xFFDB +#define XK_F31 0xFFDC +#define XK_R11 0xFFDC +#define XK_F32 0xFFDD +#define XK_R12 0xFFDD +#define XK_F33 0xFFDE +#define XK_R13 0xFFDE +#define XK_F34 0xFFDF +#define XK_R14 0xFFDF +#define XK_F35 0xFFE0 +#define XK_R15 0xFFE0 + +/* Modifiers */ + +#define XK_Shift_L 0xFFE1 /* Left shift */ +#define XK_Shift_R 0xFFE2 /* Right shift */ +#define XK_Control_L 0xFFE3 /* Left control */ +#define XK_Control_R 0xFFE4 /* Right control */ +#define XK_Caps_Lock 0xFFE5 /* Caps lock */ +#define XK_Shift_Lock 0xFFE6 /* Shift lock */ + +#define XK_Meta_L 0xFFE7 /* Left meta */ +#define XK_Meta_R 0xFFE8 /* Right meta */ +#define XK_Alt_L 0xFFE9 /* Left alt */ +#define XK_Alt_R 0xFFEA /* Right alt */ +#define XK_Super_L 0xFFEB /* Left super */ +#define XK_Super_R 0xFFEC /* Right super */ +#define XK_Hyper_L 0xFFED /* Left hyper */ +#define XK_Hyper_R 0xFFEE /* Right hyper */ + +/* + * Latin 1 + * Byte 3 = 0 + */ + +#define XK_space 0x020 +#define XK_exclam 0x021 +#define XK_quotedbl 0x022 +#define XK_numbersign 0x023 +#define XK_dollar 0x024 +#define XK_percent 0x025 +#define XK_ampersand 0x026 +#define XK_apostrophe 0x027 +#define XK_quoteright 0x027 /* deprecated */ +#define XK_parenleft 0x028 +#define XK_parenright 0x029 +#define XK_asterisk 0x02a +#define XK_plus 0x02b +#define XK_comma 0x02c +#define XK_minus 0x02d +#define XK_period 0x02e +#define XK_slash 0x02f +#define XK_0 0x030 +#define XK_1 0x031 +#define XK_2 0x032 +#define XK_3 0x033 +#define XK_4 0x034 +#define XK_5 0x035 +#define XK_6 0x036 +#define XK_7 0x037 +#define XK_8 0x038 +#define XK_9 0x039 +#define XK_colon 0x03a +#define XK_semicolon 0x03b +#define XK_less 0x03c +#define XK_equal 0x03d +#define XK_greater 0x03e +#define XK_question 0x03f +#define XK_at 0x040 +#define XK_A 0x041 +#define XK_B 0x042 +#define XK_C 0x043 +#define XK_D 0x044 +#define XK_E 0x045 +#define XK_F 0x046 +#define XK_G 0x047 +#define XK_H 0x048 +#define XK_I 0x049 +#define XK_J 0x04a +#define XK_K 0x04b +#define XK_L 0x04c +#define XK_M 0x04d +#define XK_N 0x04e +#define XK_O 0x04f +#define XK_P 0x050 +#define XK_Q 0x051 +#define XK_R 0x052 +#define XK_S 0x053 +#define XK_T 0x054 +#define XK_U 0x055 +#define XK_V 0x056 +#define XK_W 0x057 +#define XK_X 0x058 +#define XK_Y 0x059 +#define XK_Z 0x05a +#define XK_bracketleft 0x05b +#define XK_backslash 0x05c +#define XK_bracketright 0x05d +#define XK_asciicircum 0x05e +#define XK_underscore 0x05f +#define XK_grave 0x060 +#define XK_quoteleft 0x060 /* deprecated */ +#define XK_a 0x061 +#define XK_b 0x062 +#define XK_c 0x063 +#define XK_d 0x064 +#define XK_e 0x065 +#define XK_f 0x066 +#define XK_g 0x067 +#define XK_h 0x068 +#define XK_i 0x069 +#define XK_j 0x06a +#define XK_k 0x06b +#define XK_l 0x06c +#define XK_m 0x06d +#define XK_n 0x06e +#define XK_o 0x06f +#define XK_p 0x070 +#define XK_q 0x071 +#define XK_r 0x072 +#define XK_s 0x073 +#define XK_t 0x074 +#define XK_u 0x075 +#define XK_v 0x076 +#define XK_w 0x077 +#define XK_x 0x078 +#define XK_y 0x079 +#define XK_z 0x07a +#define XK_braceleft 0x07b +#define XK_bar 0x07c +#define XK_braceright 0x07d +#define XK_asciitilde 0x07e + +#define XK_nobreakspace 0x0a0 +#define XK_exclamdown 0x0a1 +#define XK_cent 0x0a2 +#define XK_sterling 0x0a3 +#define XK_currency 0x0a4 +#define XK_yen 0x0a5 +#define XK_brokenbar 0x0a6 +#define XK_section 0x0a7 +#define XK_diaeresis 0x0a8 +#define XK_copyright 0x0a9 +#define XK_ordfeminine 0x0aa +#define XK_guillemotleft 0x0ab /* left angle quotation mark */ +#define XK_notsign 0x0ac +#define XK_hyphen 0x0ad +#define XK_registered 0x0ae +#define XK_macron 0x0af +#define XK_degree 0x0b0 +#define XK_plusminus 0x0b1 +#define XK_twosuperior 0x0b2 +#define XK_threesuperior 0x0b3 +#define XK_acute 0x0b4 +#define XK_mu 0x0b5 +#define XK_paragraph 0x0b6 +#define XK_periodcentered 0x0b7 +#define XK_cedilla 0x0b8 +#define XK_onesuperior 0x0b9 +#define XK_masculine 0x0ba +#define XK_guillemotright 0x0bb /* right angle quotation mark */ +#define XK_onequarter 0x0bc +#define XK_onehalf 0x0bd +#define XK_threequarters 0x0be +#define XK_questiondown 0x0bf +#define XK_Agrave 0x0c0 +#define XK_Aacute 0x0c1 +#define XK_Acircumflex 0x0c2 +#define XK_Atilde 0x0c3 +#define XK_Adiaeresis 0x0c4 +#define XK_Aring 0x0c5 +#define XK_AE 0x0c6 +#define XK_Ccedilla 0x0c7 +#define XK_Egrave 0x0c8 +#define XK_Eacute 0x0c9 +#define XK_Ecircumflex 0x0ca +#define XK_Ediaeresis 0x0cb +#define XK_Igrave 0x0cc +#define XK_Iacute 0x0cd +#define XK_Icircumflex 0x0ce +#define XK_Idiaeresis 0x0cf +#define XK_ETH 0x0d0 +#define XK_Eth 0x0d0 /* deprecated */ +#define XK_Ntilde 0x0d1 +#define XK_Ograve 0x0d2 +#define XK_Oacute 0x0d3 +#define XK_Ocircumflex 0x0d4 +#define XK_Otilde 0x0d5 +#define XK_Odiaeresis 0x0d6 +#define XK_multiply 0x0d7 +#define XK_Ooblique 0x0d8 +#define XK_Ugrave 0x0d9 +#define XK_Uacute 0x0da +#define XK_Ucircumflex 0x0db +#define XK_Udiaeresis 0x0dc +#define XK_Yacute 0x0dd +#define XK_THORN 0x0de +#define XK_Thorn 0x0de /* deprecated */ +#define XK_ssharp 0x0df +#define XK_agrave 0x0e0 +#define XK_aacute 0x0e1 +#define XK_acircumflex 0x0e2 +#define XK_atilde 0x0e3 +#define XK_adiaeresis 0x0e4 +#define XK_aring 0x0e5 +#define XK_ae 0x0e6 +#define XK_ccedilla 0x0e7 +#define XK_egrave 0x0e8 +#define XK_eacute 0x0e9 +#define XK_ecircumflex 0x0ea +#define XK_ediaeresis 0x0eb +#define XK_igrave 0x0ec +#define XK_iacute 0x0ed +#define XK_icircumflex 0x0ee +#define XK_idiaeresis 0x0ef +#define XK_eth 0x0f0 +#define XK_ntilde 0x0f1 +#define XK_ograve 0x0f2 +#define XK_oacute 0x0f3 +#define XK_ocircumflex 0x0f4 +#define XK_otilde 0x0f5 +#define XK_odiaeresis 0x0f6 +#define XK_division 0x0f7 +#define XK_oslash 0x0f8 +#define XK_ugrave 0x0f9 +#define XK_uacute 0x0fa +#define XK_ucircumflex 0x0fb +#define XK_udiaeresis 0x0fc +#define XK_yacute 0x0fd +#define XK_thorn 0x0fe +#define XK_ydiaeresis 0x0ff + +/* end of X11 keyboard mapping */ + +#define MOUSE_FILENAME "mouse.pcx" +#define JOYSTICK_FILENAME "joystick.cnf" + +#define screen myscreen + +#define XFlush(a) +#define XGetImage(a,b,c,d,e,f,g,h) ((XImage *) NULL) +#define XDisplayName(a) ((char *) NULL) +#define XFreeColors(a,b,c,d,e) +#define XSelectInput(a,b,c) +#define XDefaultDepth(a,b) (8) +#define XSetWMProperties(a,b,c,d,e,f,g,h,i) + +#define MAX_EVENT_BUFFER 256 +#define MAX_SCANCODES 128 + +#define True 1 +#define False 0 +#define None 0L + +#define DUMMY_FILE ((void *) -1) +#define DUMMY_MASK (-1) + +#define KeyPressMask (1L << 0) +#define KeyReleaseMask (1L << 1) +#define ButtonPressMask (1L << 2) +#define ButtonReleaseMask (1L << 3) +#define ButtonMotionMask (1L << 13) +#define ExposureMask (1L << 15) +#define StructureNotifyMask (1L << 17) +#define FocusChangeMask (1L << 21) + +#define KeyPress 2 +#define KeyRelease 3 +#define ButtonPress 4 +#define ButtonRelease 5 +#define MotionNotify 6 +#define FocusIn 9 +#define FocusOut 10 +#define Expose 12 +#define UnmapNotify 18 +#define MapNotify 19 +#define ClientMessage 33 + +#define GCForeground (1L << 2) +#define GCBackground (1L << 3) +#define GCGraphicsExposures (1L << 16) +#define GCClipMask (1L << 19) + +#define NormalState 1 /* most applications want to start this way */ +#define InputHint (1L << 0) +#define StateHint (1L << 1) +#define IconPixmapHint (1L << 2) +#define IconMaskHint (1L << 5) +#define PSize (1L << 3) /* program specified size */ +#define PMinSize (1L << 4) /* program specified minimum size */ +#define PMaxSize (1L << 5) /* program specified maximum size */ + +#define PCX_Success 0 +#define PCX_OpenFailed -1 +#define PCX_ReadFailed -2 +#define PCX_FileInvalid -3 +#define PCX_NoMemory -4 +#define PCX_ColorFailed -5 + +#define BitmapSuccess 0 +#define BitmapOpenFailed 1 +#define BitmapFileInvalid 2 +#define BitmapNoMemory 3 + +#define ZPixmap 2 /* depth == drawable depth */ + +#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen) +#define DefaultColormap(dpy, scr) (ScreenOfDisplay(dpy,scr)->cmap) +#define ScreenOfDisplay(dpy, scr) (&((_XPrivDisplay)dpy)->screens[scr]) +#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel) +#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel) +#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root) +#define AllPlanes ((unsigned long)~0L) + +#define DefaultVisual(dpy, scr) (NULL) +#define DefaultDepth(dpy, scr) (NULL) +#define XDisplayWidth(dpy, scr) (XRES) +#define XDisplayHeight(dpy, scr) (YRES) + +#define XGetPixel(ximage, x, y) \ + ((*((ximage)->f.get_pixel))((ximage), (x), (y))) + +typedef unsigned long Pixel; /* Index into colormap */ +typedef unsigned long XID; +typedef XID Window; +typedef XID Drawable; +typedef XID Pixmap; +typedef XID Colormap; +typedef XID KeySym; +typedef XID GContext; +typedef struct _XDisplay Display; +typedef long Visual; +typedef long XVisualInfo; +typedef long Atom; +typedef int Status; +typedef int Bool; +typedef int XComposeStatus; /* we don't need the real type */ + +typedef struct _XGC +{ + GContext gid; /* protocol ID for graphics context */ +} *GC; + +typedef struct +{ + Colormap cmap; /* default color map */ + Window root; /* root window id */ + unsigned long white_pixel; /* white pixel value */ + unsigned long black_pixel; /* black pixel value */ + int x; + int y; + unsigned int width; + unsigned int height; + BITMAP *video_bitmap; +} Screen; + +typedef struct _XDisplay +{ + int default_screen; /* default screen for operations */ + Screen *screens; /* pointer to list of screens */ + BITMAP *mouse_ptr; +} *_XPrivDisplay; + +typedef struct _XImage +{ + struct funcs + { + unsigned long (*get_pixel) (struct _XImage *, int, int); + } f; +} XImage; + +typedef struct +{ + long flags; /* marks which fields in this structure are defined */ + int width, height; /* should set so old wm's don't mess up */ + int min_width, min_height; + int max_width, max_height; +} XSizeHints; + +typedef struct +{ + long flags; /* marks which fields in this structure are defined */ + Bool input; /* does this application rely on the window manager to + get keyboard input? */ + int initial_state; /* see below */ + Pixmap icon_pixmap; /* pixmap to be used as icon */ + Pixmap icon_mask; /* icon mask bitmap */ +} XWMHints; + +typedef struct +{ + char *res_name; + char *res_class; +} XClassHint; + +typedef struct +{ + unsigned char *value; /* same as Property routines */ +} XTextProperty; + +typedef struct +{ + unsigned long foreground; /* foreground pixel */ + unsigned long background; /* background pixel */ + Bool graphics_exposures; /* boolean, should exposures be generated */ + Pixmap clip_mask; /* bitmap clipping; other calls for rects */ + int clip_x_origin; /* x origin for clipping */ + int clip_y_origin; /* y origin for clipping */ + unsigned long value_mask; +} XGCValues; + +typedef struct +{ + int type; + int x, y; + int width, height; +} XExposeEvent; + +typedef struct +{ + int type; /* of event */ + int x, y; /* pointer x, y coordinates in event window */ + unsigned int button; /* detail */ +} XButtonEvent; + +typedef struct +{ + int type; + int x, y; /* pointer x, y coordinates in event window */ +} XMotionEvent; + +typedef struct +{ + int type; /* of event */ + unsigned int state; /* key or button mask */ +} XKeyEvent; + +typedef struct +{ + int type; /* FocusIn or FocusOut */ +} XFocusChangeEvent; + +typedef struct +{ + int type; /* ClientMessage */ +} XClientMessageEvent; + +typedef union _XEvent +{ + int type; /* must not be changed; first element */ + XExposeEvent xexpose; + XButtonEvent xbutton; + XMotionEvent xmotion; + XKeyEvent xkey; +} XEvent; + +void XMapWindow(Display *, Window); +Display *XOpenDisplay(char *); +Window XCreateSimpleWindow(Display *, Window, int, int, + unsigned int, unsigned int, unsigned int, + unsigned long, unsigned long); +Status XStringListToTextProperty(char **, int, XTextProperty *); +void XFree(void *); +GC XCreateGC(Display *, Drawable, unsigned long, XGCValues *); +void XSetClipMask(Display *, GC, Pixmap); +void XSetClipOrigin(Display *, GC, int, int); +void XFillRectangle(Display *, Drawable, GC, int, int, + unsigned int, unsigned int); +Pixmap XCreatePixmap(Display *, Drawable, unsigned int, unsigned int, + unsigned int); +void XSync(Display *, Bool); +inline void XCopyArea(Display *, Drawable, Drawable, GC, int, int, + unsigned int, unsigned int, int, int); +int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *); +int XReadBitmapFile(Display *, Drawable, char *, + unsigned int *, unsigned int *, Pixmap *, int *, int *); +void XFreePixmap(Display *, Pixmap); +void XFreeGC(Display *, GC); +void XCloseDisplay(Display *); +void XNextEvent(Display *, XEvent *); +int XPending(Display *); +KeySym XLookupKeysym(XKeyEvent *, int); +int XLookupString(XKeyEvent *, char *, int, KeySym *, XComposeStatus *); +void XSetForeground(Display *, GC, unsigned long); +void XDrawLine(Display *, Drawable, GC, int, int, int, int); +void XDestroyImage(XImage *); +Bool XQueryPointer(Display *, Window, Window *, Window *, int *, int *, + int *, int *, unsigned int *); +void XAutoRepeatOn(Display *); +void XAutoRepeatOff(Display *); + +boolean MSDOSOpenAudio(void); +boolean MSDOSCloseAudio(void); + +void NetworkServer(int, int); + +#endif /* MSDOS_H */ diff --git a/src/libgame/pcx.c b/src/libgame/pcx.c new file mode 100644 index 00000000..b075940c --- /dev/null +++ b/src/libgame/pcx.c @@ -0,0 +1,265 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* pcx.c * +***********************************************************/ + +#ifndef TARGET_SDL + +#include "pcx.h" +#include "image.h" +#include "misc.h" + +#define PCX_DEBUG FALSE + +#define PCX_MAGIC 0x0a /* first byte in a PCX image file */ +#define PCX_LAST_VERSION 5 /* last acceptable version number */ +#define PCX_ENCODING 1 /* PCX encoding method */ +#define PCX_256COLORS_MAGIC 0x0c /* first byte of a PCX 256 color map */ +#define PCX_MAXDEPTH 8 /* supports up to 8 bits per pixel */ +#define PCX_MAXCOLORS 256 /* maximum number of colors */ + +#define PCX_HEADER_SIZE 128 +#define PCX_COLORMAP_SIZE (3 * PCX_MAXCOLORS) + +struct PCX_Header +{ + unsigned char signature; /* PCX file identifier */ + unsigned char version; /* version compatibility level */ + unsigned char encoding; /* encoding method */ + unsigned char bits_per_pixel; /* bits per pixel, or depth */ + unsigned short xmin; /* X position of left edge */ + unsigned short ymin; /* Y position of top edge */ + unsigned short xmax; /* X position of right edge */ + unsigned short ymax; /* Y position of bottom edge */ + unsigned short hres; /* X screen resolution of source image */ + unsigned short vres; /* Y screen resolution of source image */ + unsigned char palette[16][3]; /* PCX color map */ + unsigned char reserved; /* should be 0, 1 if std res fax */ + unsigned char color_planes; /* bit planes in image */ + unsigned short bytes_per_line;/* byte delta between scanlines */ + unsigned short palette_type; /* 0 = undef, 1 = color, 2 = grayscale */ + unsigned char filler[58]; /* fill to struct size of 128 */ +}; + +/* global PCX error value */ +int errno_pcx = PCX_Success; + +static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last) +{ + /* Run Length Encoding: If the two high bits are set, + * then the low 6 bits contain a repeat count, and the byte to + * repeat is the next byte in the file. If the two high bits are + * not set, then this is the byte to write. + */ + + unsigned int bytes_per_pixel = (image->depth + 7) / 8; + register byte *bitmap_ptr, *bitmap_last; + register byte value, count; + + bitmap_ptr = image->data; + bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel); + + while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last) + { + value = *buffer_ptr++; + + if ((value & 0xc0) == 0xc0) /* this is a repeat count byte */ + { + count = value & 0x3f; /* extract repeat count from byte */ + value = *buffer_ptr++; /* next byte is value to repeat */ + + for (; count && bitmap_ptr < bitmap_last; count--) + *bitmap_ptr++ = value; + + if (count) /* repeat count spans end of bitmap */ + return NULL; + } + else + *bitmap_ptr++ = value; + + image->rgb.color_used[value] = TRUE; + } + + /* check if end of buffer was reached before end of bitmap */ + if (bitmap_ptr < bitmap_last) + return NULL; + + /* return current buffer position for next decoding function */ + return buffer_ptr; +} + +static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last) +{ + int i, magic; + + /* read colormap magic byte */ + magic = *buffer_ptr++; + + /* check magic colormap header byte */ + if (magic != PCX_256COLORS_MAGIC) + return NULL; + + /* check if enough bytes left for a complete colormap */ + if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last) + return NULL; + + /* read 256 colors from PCX colormap */ + for (i=0; irgb.red[i] = *buffer_ptr++ << 8; + image->rgb.green[i] = *buffer_ptr++ << 8; + image->rgb.blue[i] = *buffer_ptr++ << 8; + } + + /* return current buffer position for next decoding function */ + return buffer_ptr; +} + +Image *Read_PCX_to_Image(char *filename) +{ + FILE *file; + byte *file_buffer; + byte *buffer_ptr, *buffer_last; + unsigned int file_length; + struct PCX_Header pcx; + Image *image; + int width, height, depth; + int i; + + errno_pcx = PCX_Success; + + if (!(file = fopen(filename, "r"))) + { + errno_pcx = PCX_OpenFailed; + return NULL; + } + + if (fseek(file, 0, SEEK_END) == -1) + { + fclose(file); + errno_pcx = PCX_ReadFailed; + return NULL; + } + + file_length = ftell(file); + rewind(file); + + if (file_length < PCX_HEADER_SIZE) + { + /* PCX file is too short to contain a valid PCX header */ + fclose(file); + + errno_pcx = PCX_FileInvalid; + return NULL; + } + + file_buffer = checked_malloc(file_length); + + if (fread(file_buffer, 1, file_length, file) != file_length) + { + fclose(file); + errno_pcx = PCX_ReadFailed; + return NULL; + } + + fclose(file); + + pcx.signature = file_buffer[0]; + pcx.version = file_buffer[1]; + pcx.encoding = file_buffer[2]; + pcx.bits_per_pixel = file_buffer[3]; + pcx.xmin = file_buffer[4] + 256 * file_buffer[5]; + pcx.ymin = file_buffer[6] + 256 * file_buffer[7]; + pcx.xmax = file_buffer[8] + 256 * file_buffer[9]; + pcx.ymax = file_buffer[10] + 256 * file_buffer[11]; + pcx.color_planes = file_buffer[65]; + pcx.bytes_per_line = file_buffer[66] + 256 * file_buffer[67]; + pcx.palette_type = file_buffer[68] + 256 * file_buffer[69]; + + width = pcx.xmax - pcx.xmin + 1; + height = pcx.ymax - pcx.ymin + 1; + depth = pcx.bits_per_pixel; + + if (pcx.signature != PCX_MAGIC || pcx.version > PCX_LAST_VERSION || + pcx.encoding != PCX_ENCODING || pcx.color_planes > PCX_MAXDEPTH || + width < 0 || height < 0) + { + free(file_buffer); + + errno_pcx = PCX_FileInvalid; + return NULL; + } + +#if PCX_DEBUG + if (options.verbose) + { + printf("%s is a %dx%d PC Paintbrush image with %d bitplanes\n", + filename, width, height, + pcx.color_planes); + printf("depth: %d\n", pcx.bits_per_pixel); + printf("color_planes: %d\n", pcx.color_planes); + printf("bytes_per_line: %d\n", pcx.bytes_per_line); + printf("palette type: %s\n", + (pcx.palette_type == 1 ? "color" : + pcx.palette_type == 2 ? "grayscale" : "undefined")); + } +#endif + + /* allocate new image structure */ + image = newImage(width, height, depth); + + buffer_ptr = file_buffer + PCX_HEADER_SIZE; + buffer_last = file_buffer + file_length; + + /* read compressed bitmap data */ + if ((buffer_ptr = PCX_ReadBitmap(image, buffer_ptr, buffer_last)) == NULL) + { + free(file_buffer); + freeImage(image); + + errno_pcx = PCX_FileInvalid; + return NULL; + } + + if (file_length < PCX_HEADER_SIZE + PCX_COLORMAP_SIZE) + { + /* PCX file is too short to contain a valid 256 colors colormap */ + fclose(file); + errno_pcx = PCX_ColorFailed; + return NULL; + } + + /* read colormap data */ + if (!PCX_ReadColormap(image, buffer_ptr, buffer_last)) + { + free(file_buffer); + freeImage(image); + errno_pcx = PCX_ColorFailed; + return NULL; + } + + free(file_buffer); + + /* determine number of used colormap entries */ + image->rgb.used = 0; + for (i=0; irgb.color_used[i]) + image->rgb.used++; + +#if PCX_DEBUG + if (options.verbose) + printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used); +#endif + + return image; +} + +#endif /* !TARGET_SDL */ diff --git a/src/libgame/pcx.h b/src/libgame/pcx.h new file mode 100644 index 00000000..f214971b --- /dev/null +++ b/src/libgame/pcx.h @@ -0,0 +1,34 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* pcx.h * +***********************************************************/ + +#ifndef PCX_H +#define PCX_H + +#include "libgame.h" + +#if !defined(TARGET_SDL) + +#define PCX_Success 0 +#define PCX_OpenFailed -1 +#define PCX_ReadFailed -2 +#define PCX_FileInvalid -3 +#define PCX_NoMemory -4 +#define PCX_ColorFailed -5 + +/* global PCX error value */ +extern int errno_pcx; + +Image *Read_PCX_to_Image(char *); + +#endif /* !TARGET_SDL */ +#endif /* PCX_H */ diff --git a/src/libgame/platform.h b/src/libgame/platform.h new file mode 100644 index 00000000..02513071 --- /dev/null +++ b/src/libgame/platform.h @@ -0,0 +1,47 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* platform.h * +***********************************************************/ + +#ifndef PLATFORM_H +#define PLATFORM_H + +/* define keywords for supported main platforms */ + +#if defined(MSDOS) +#define PLATFORM_MSDOS +#elif defined(WIN32) +#define PLATFORM_WIN32 +#else +#define PLATFORM_UNIX +#endif + +/* define additional keywords for several Unix platforms */ + +#if defined(linux) +#define PLATFORM_LINUX +#endif + +#if defined(__FreeBSD__) +#define PLATFORM_FREEBSD +#endif + +/* detecting HP-UX by the following compiler keyword definitions: + - in K&R mode (the default), the HP C compiler defines "hpux" + - in ANSI mode (-Aa or -Ae), the HP C compiler defines "__hpux" + - the gcc (Gnu) C compiler defines "__hpux__" + Thanks to Jarkko Hietaniemi for this note. */ + +#if defined(__hpux__) || defined(__hpux) || defined(hpux) +#define PLATFORM_HPUX +#endif + +#endif /* PLATFORM_H */ diff --git a/src/libgame/private.c b/src/libgame/private.c new file mode 100644 index 00000000..90de58af --- /dev/null +++ b/src/libgame/private.c @@ -0,0 +1,22 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* private.c * +***********************************************************/ + +#include "libgame.h" + +#if 0 +Display *display; +Visual *visual; +int screen; + +DrawWindow window = None; +#endif diff --git a/src/libgame/private.h b/src/libgame/private.h new file mode 100644 index 00000000..e79f00d9 --- /dev/null +++ b/src/libgame/private.h @@ -0,0 +1,27 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* private.h * +***********************************************************/ + +#ifndef PRIVATE_H +#define PRIVATE_H + +#include "libgame.h" + +#if 0 +extern Display *display; +extern Visual *visual; +extern int screen; + +extern DrawWindow window; +#endif + +#endif /* PRIVATE_H */ diff --git a/src/libgame/random.c b/src/libgame/random.c new file mode 100644 index 00000000..864f3dcc --- /dev/null +++ b/src/libgame/random.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * This is derived from the Berkeley source: + * @(#)random.c 5.5 (Berkeley) 7/6/88 + * It was reworked for the GNU C Library by Roland McGrath. + */ + +#include +#include +#include + +#include "random.h" + + +/* An improved random number generation package. In addition to the standard + rand()/srand() like interface, this package also has a special state info + interface. The initstate() routine is called with a seed, an array of + bytes, and a count of how many bytes are being passed in; this array is + then initialized to contain information for random number generation with + that much state information. Good sizes for the amount of state + information are 32, 64, 128, and 256 bytes. The state can be switched by + calling the setstate() function with the same array as was initiallized + with initstate(). By default, the package runs with 128 bytes of state + information and generates far better random numbers than a linear + congruential generator. If the amount of state information is less than + 32 bytes, a simple linear congruential R.N.G. is used. Internally, the + state information is treated as an array of longs; the zeroeth element of + the array is the type of R.N.G. being used (small integer); the remainder + of the array is the state information for the R.N.G. Thus, 32 bytes of + state information will give 7 longs worth of state information, which will + allow a degree seven polynomial. (Note: The zeroeth word of state + information also has some other information stored in it; see setstate + for details). The random number generation technique is a linear feedback + shift register approach, employing trinomials (since there are fewer terms + to sum up that way). In this approach, the least significant bit of all + the numbers in the state table will act as a linear feedback shift register, + and will have period 2^deg - 1 (where deg is the degree of the polynomial + being used, assuming that the polynomial is irreducible and primitive). + The higher order bits will have longer periods, since their values are + also influenced by pseudo-random carries out of the lower bits. The + total period of the generator is approximately deg*(2**deg - 1); thus + doubling the amount of state information has a vast influence on the + period of the generator. Note: The deg*(2**deg - 1) is an approximation + only good for large deg, when the period of the shift register is the + dominant factor. With deg equal to seven, the period is actually much + longer than the 7*(2**7 - 1) predicted by this formula. */ + + + +/* For each of the currently supported random number generators, we have a + break value on the amount of state information (you need at least thi + bytes of state info to support this random number generator), a degree for + the polynomial (actually a trinomial) that the R.N.G. is based on, and + separation between the two lower order coefficients of the trinomial. */ + +/* Linear congruential. */ +#define TYPE_0 0 +#define BREAK_0 8 +#define DEG_0 0 +#define SEP_0 0 + +/* x**7 + x**3 + 1. */ +#define TYPE_1 1 +#define BREAK_1 32 +#define DEG_1 7 +#define SEP_1 3 + +/* x**15 + x + 1. */ +#define TYPE_2 2 +#define BREAK_2 64 +#define DEG_2 15 +#define SEP_2 1 + +/* x**31 + x**3 + 1. */ +#define TYPE_3 3 +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +/* x**63 + x + 1. */ +#define TYPE_4 4 +#define BREAK_4 256 +#define DEG_4 63 +#define SEP_4 1 + + +/* Array versions of the above information to make code run faster. + Relies on fact that TYPE_i == i. */ + +#define MAX_TYPES 5 /* Max number of types above. */ + + + +/* Initially, everything is set up as if from: + initstate(1, randtbl, 128); + Note that this initialization takes advantage of the fact that srandom + advances the front and rear pointers 10*rand_deg times, and hence the + rear pointer which starts at 0 will also end up at zero; thus the zeroeth + element of the state information, which contains info about the current + position of the rear pointer is just + (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */ + +static long int randtbl[DEG_3 + 1] = +{ + TYPE_3, + -851904987, -43806228, -2029755270, 1390239686, -1912102820, + -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712, + -1714531963, 1800685987, -2015299881, 654595283, -1149023258, + -1470005550, -1143256056, -1325577603, -1568001885, 1275120390, + -607508183, -205999574, -1696891592, 1492211999, -1528267240, + -952028296, -189082757, 362343714, 1424981831, 2039449641, +}; + +/* FPTR and RPTR are two pointers into the state info, a front and a rear + pointer. These two pointers are always rand_sep places aparts, as they + cycle through the state information. (Yes, this does mean we could get + away with just one pointer, but the code for random is more efficient + this way). The pointers are left positioned as they would be from the call: + initstate(1, randtbl, 128); + (The position of the rear pointer, rptr, is really 0 (as explained above + in the initialization of randtbl) because the state table pointer is set + to point to randtbl[1] (as explained below).) */ + +static long int *fptr = &randtbl[SEP_3 + 1]; +static long int *rptr = &randtbl[1]; + + + +/* The following things are the pointer to the state information table, + the type of the current generator, the degree of the current polynomial + being used, and the separation between the two pointers. + Note that for efficiency of random, we remember the first location of + the state information, not the zeroeth. Hence it is valid to access + state[-1], which is used to store the type of the R.N.G. + Also, we remember the last location, since this is more efficient than + indexing every time to find the address of the last element to see if + the front and rear pointers have wrapped. */ + +static long int *state = &randtbl[1]; + +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; + +static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])]; + +/* Initialize the random number generator based on the given seed. If the + type is the trivial no-state-information type, just remember the seed. + Otherwise, initializes state[] based on the given "seed" via a linear + congruential generator. Then, the pointers are set to known locations + that are exactly rand_sep places apart. Lastly, it cycles the state + information a given number of times to get rid of any initial dependencies + introduced by the L.C.R.N.G. Note that the initialization of randtbl[] + for default usage relies on values produced by this routine. */ + +void srandom_linux_libc(unsigned int x) +{ + state[0] = x; + if (rand_type != TYPE_0) + { + register long int i; + for (i = 1; i < rand_deg; ++i) + state[i] = (1103515145 * state[i - 1]) + 12345; + fptr = &state[rand_sep]; + rptr = &state[0]; + for (i = 0; i < 10 * rand_deg; ++i) + (void) random_linux_libc(); + } +} + +/* If we are using the trivial TYPE_0 R.N.G., just do the old linear + congruential bit. Otherwise, we do our fancy trinomial stuff, which is the + same in all ther other cases due to all the global variables that have been + set up. The basic operation is to add the number at the rear pointer into + the one at the front pointer. Then both pointers are advanced to the next + location cyclically in the table. The value returned is the sum generated, + reduced to 31 bits by throwing away the "least random" low bit. + Note: The code takes advantage of the fact that both the front and + rear pointers can't wrap on the same call by not testing the rear + pointer if the front one has wrapped. Returns a 31-bit random number. */ + +long int random_linux_libc() +{ + if (rand_type == TYPE_0) + { + state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX; + return state[0]; + } + else + { + long int i; + *fptr += *rptr; + /* Chucking least random bit. */ + i = (*fptr >> 1) & LONG_MAX; + ++fptr; + if (fptr >= end_ptr) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end_ptr) + rptr = state; + } + return i; + } +} diff --git a/src/libgame/random.h b/src/libgame/random.h new file mode 100644 index 00000000..366d1ff5 --- /dev/null +++ b/src/libgame/random.h @@ -0,0 +1,20 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* random.h * +***********************************************************/ + +#ifndef RANDOM_H +#define RANDOM_H + +void srandom_linux_libc(unsigned int); +long int random_linux_libc(void); + +#endif diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c new file mode 100644 index 00000000..8e2ec948 --- /dev/null +++ b/src/libgame/sdl.c @@ -0,0 +1,213 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* sdl.c * +***********************************************************/ + +#include "libgame.h" + +#ifdef TARGET_SDL + +inline void SDLInitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) +{ + /* initialize SDL video */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) + Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); + + /* automatically cleanup SDL stuff after exit() */ + atexit(SDL_Quit); + + /* open SDL video output device (window or fullscreen mode) */ + if (!SDLSetVideoMode(backbuffer)) + Error(ERR_EXIT, "setting video mode failed"); + + /* set window and icon title */ + SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING); + + /* create additional buffer for double-buffering */ + pix[PIX_DB_BACK] = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); + + /* SDL cannot directly draw to the visible video framebuffer like X11, + but always uses a backbuffer, which is then blitted to the visible + video framebuffer with 'SDL_UpdateRect' (or replaced with the current + visible video framebuffer with 'SDL_Flip', if the hardware supports + this). Therefore do not use an additional backbuffer for drawing, but + use a symbolic buffer (distinguishable from the SDL backbuffer) called + 'window', which indicates that the SDL backbuffer should be updated to + the visible video framebuffer when attempting to blit to it. + + For convenience, it seems to be a good idea to create this symbolic + buffer 'window' at the same size as the SDL backbuffer. Although it + should never be drawn to directly, it would do no harm nevertheless. */ + + *window = pix[PIX_DB_BACK]; /* 'window' is only symbolic buffer */ + pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is SDL screen buffer */ +} + +inline boolean SDLSetVideoMode(DrawBuffer *backbuffer, boolean fullscreen) +{ + boolean success = TRUE; + + if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available) + { + /* switch display to fullscreen mode, if available */ + DrawWindow window_old = *backbuffer; + DrawWindow window_new; + + if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, + SDL_HWSURFACE|SDL_FULLSCREEN)) + == NULL) + { + /* switching display to fullscreen mode failed */ + Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); + + /* do not try it again */ + video.fullscreen_available = FALSE; + success = FALSE; + } + else + { + if (window_old) + SDL_FreeSurface(window_old); + *backbuffer = window_new; + + video.fullscreen_enabled = TRUE; + success = TRUE; + } + } + + if ((!fullscreen && video.fullscreen_enabled) || !*backbuffer) + { + /* switch display to window mode */ + DrawWindow window_old = *backbuffer; + DrawWindow window_new; + + if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, + SDL_HWSURFACE)) + == NULL) + { + /* switching display to window mode failed -- should not happen */ + Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); + + success = FALSE; + } + else + { + if (window_old) + SDL_FreeSurface(window_old); + *backbuffer = window_new; + + video.fullscreen_enabled = FALSE; + success = TRUE; + } + } + + return success; +} + +inline void SDLCopyArea(SDL_Surface *src_surface, SDL_Surface *dst_surface, + int src_x, int src_y, + int width, int height, + int dst_x, int dst_y) +{ + SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface); + SDL_Rect src_rect, dst_rect; + + src_rect.x = src_x; + src_rect.y = src_y; + src_rect.w = width; + src_rect.h = height; + + dst_rect.x = dst_x; + dst_rect.y = dst_y; + dst_rect.w = width; + dst_rect.h = height; + + if (src_surface != backbuffer || dst_surface != window) + SDL_BlitSurface(src_surface, &src_rect, surface, &dst_rect); + + if (dst_surface == window) + SDL_UpdateRect(backbuffer, dst_x, dst_y, width, height); +} + +inline void SDLFillRectangle(SDL_Surface *dst_surface, int x, int y, + int width, int height, unsigned int color) +{ + SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface); + SDL_Rect rect; + unsigned int color_r = (color >> 16) && 0xff; + unsigned int color_g = (color >> 8) && 0xff; + unsigned int color_b = (color >> 0) && 0xff; + + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + + SDL_FillRect(surface, &rect, + SDL_MapRGB(surface->format, color_r, color_g, color_b)); + + if (dst_surface == window) + SDL_UpdateRect(backbuffer, x, y, width, height); +} + +inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y, + int to_x, int to_y, unsigned int color) +{ + SDL_Rect rect; + unsigned int color_r = (color >> 16) & 0xff; + unsigned int color_g = (color >> 8) & 0xff; + unsigned int color_b = (color >> 0) & 0xff; + + if (from_x > to_x) + swap_numbers(&from_x, &to_x); + + if (from_y > to_y) + swap_numbers(&from_y, &to_y); + + rect.x = from_x; + rect.y = from_y; + rect.w = (to_x - from_x + 1); + rect.h = (to_y - from_y + 1); + + SDL_FillRect(surface, &rect, + SDL_MapRGB(surface->format, color_r, color_g, color_b)); +} + +inline boolean SDLOpenAudio(void) +{ + if (SDL_Init(SDL_INIT_AUDIO) < 0) + { + Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError()); + return FALSE; + } + + if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0) + { + Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError()); + return FALSE; + } + + Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4); + Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4); + + return TRUE; +} + +inline void SDLCloseAudio(void) +{ + Mix_HaltMusic(); + Mix_HaltChannel(-1); + + Mix_CloseAudio(); +} + +#endif /* TARGET_SDL */ diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h new file mode 100644 index 00000000..f150e7df --- /dev/null +++ b/src/libgame/sdl.h @@ -0,0 +1,309 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* sdl.h * +***********************************************************/ + +#ifndef SDL_H +#define SDL_H + +#include "SDL.h" +#include "SDL_image.h" +#include "SDL_mixer.h" + + +/* definitions needed for "system.c" */ + +#define SURFACE_FLAGS (SDL_SWSURFACE) + + +/* system dependent definitions */ + +#define TARGET_STRING "SDL" +#define FULLSCREEN_STATUS FULLSCREEN_AVAILABLE + + +/* SDL type definitions */ + +typedef SDL_Surface *Bitmap; +typedef SDL_Surface *DrawWindow; +typedef SDL_Surface *DrawBuffer; + +typedef SDLKey Key; + +typedef SDL_Event Event; +typedef SDL_MouseButtonEvent ButtonEvent; +typedef SDL_MouseMotionEvent MotionEvent; +typedef SDL_KeyboardEvent KeyEvent; +typedef SDL_Event ExposeEvent; +typedef SDL_Event FocusChangeEvent; +typedef SDL_Event ClientMessageEvent; + +typedef int GC; +typedef int Pixmap; +typedef int Display; +typedef int Visual; +typedef int Colormap; + + +/* SDL symbol definitions */ + +#define None 0L + +#define EVENT_BUTTONPRESS SDL_MOUSEBUTTONDOWN +#define EVENT_BUTTONRELEASE SDL_MOUSEBUTTONUP +#define EVENT_MOTIONNOTIFY SDL_MOUSEMOTION +#define EVENT_KEYPRESS SDL_KEYDOWN +#define EVENT_KEYRELEASE SDL_KEYUP +#define EVENT_EXPOSE SDL_USEREVENT + 0 +#define EVENT_FOCUSIN SDL_USEREVENT + 1 +#define EVENT_FOCUSOUT SDL_USEREVENT + 2 +#define EVENT_CLIENTMESSAGE SDL_QUIT +#define EVENT_MAPNOTIFY SDL_USEREVENT + 4 +#define EVENT_UNMAPNOTIFY SDL_USEREVENT + 5 + +#define KSYM_UNDEFINED SDLK_UNKNOWN + +#define KSYM_Return SDLK_RETURN +#define KSYM_Escape SDLK_ESCAPE + +#define KSYM_Left SDLK_LEFT +#define KSYM_Right SDLK_RIGHT +#define KSYM_Up SDLK_UP +#define KSYM_Down SDLK_DOWN + +#ifdef SDLK_KP_LEFT +#define KSYM_KP_Left SDLK_KP_LEFT +#define KSYM_KP_Right SDLK_KP_RIGHT +#define KSYM_KP_Up SDLK_KP_UP +#define KSYM_KP_Down SDLK_KP_DOWN +#endif + +#define KSYM_KP_Enter SDLK_KP_ENTER +#define KSYM_KP_Add SDLK_KP_PLUS +#define KSYM_KP_Subtract SDLK_KP_MINUS +#define KSYM_KP_Multiply SDLK_KP_MULTIPLY +#define KSYM_KP_Divide SDLK_KP_DIVIDE +#define KSYM_KP_Separator SDLK_KP_PERIOD + +#define KSYM_Shift_L SDLK_LSHIFT +#define KSYM_Shift_R SDLK_RSHIFT +#define KSYM_Control_L SDLK_LCTRL +#define KSYM_Control_R SDLK_RCTRL +#define KSYM_Meta_L SDLK_LMETA +#define KSYM_Meta_R SDLK_RMETA +#define KSYM_Alt_L SDLK_LALT +#define KSYM_Alt_R SDLK_RALT +#define KSYM_Super_L SDLK_LSUPER +#define KSYM_Super_R SDLK_RSUPER +#define KSYM_Mode_switch SDLK_MODE +#define KSYM_Multi_key SDLK_RCTRL + +#define KSYM_BackSpace SDLK_BACKSPACE +#define KSYM_Delete SDLK_DELETE +#define KSYM_Insert SDLK_INSERT +#define KSYM_Tab SDLK_TAB +#define KSYM_Home SDLK_HOME +#define KSYM_End SDLK_END +#define KSYM_Page_Up SDLK_PAGEUP +#define KSYM_Page_Down SDLK_PAGEDOWN +#define KSYM_Menu SDLK_MENU + +#define KSYM_space SDLK_SPACE +#define KSYM_exclam SDLK_EXCLAIM +#define KSYM_quotedbl SDLK_QUOTEDBL +#define KSYM_numbersign SDLK_HASH +#define KSYM_dollar SDLK_DOLLAR +#define KSYM_percent KSYM_UNDEFINED /* undefined */ +#define KSYM_ampersand SDLK_AMPERSAND +#define KSYM_apostrophe SDLK_QUOTE +#define KSYM_parenleft SDLK_LEFTPAREN +#define KSYM_parenright SDLK_RIGHTPAREN +#define KSYM_asterisk SDLK_ASTERISK +#define KSYM_plus SDLK_PLUS +#define KSYM_comma SDLK_COMMA +#define KSYM_minus SDLK_MINUS +#define KSYM_period SDLK_PERIOD +#define KSYM_slash SDLK_SLASH + +#define KSYM_colon SDLK_COLON +#define KSYM_semicolon SDLK_SEMICOLON +#define KSYM_less SDLK_LESS +#define KSYM_equal SDLK_EQUALS +#define KSYM_greater SDLK_GREATER +#define KSYM_question SDLK_QUESTION +#define KSYM_at SDLK_AT + +#define KSYM_bracketleft SDLK_LEFTBRACKET +#define KSYM_backslash SDLK_BACKSLASH +#define KSYM_bracketright SDLK_RIGHTBRACKET +#define KSYM_asciicircum SDLK_CARET +#define KSYM_underscore SDLK_UNDERSCORE +#define KSYM_grave SDLK_BACKQUOTE + +#define KSYM_quoteleft KSYM_UNDEFINED /* undefined */ +#define KSYM_braceleft KSYM_UNDEFINED /* undefined */ +#define KSYM_bar KSYM_UNDEFINED /* undefined */ +#define KSYM_braceright KSYM_UNDEFINED /* undefined */ +#define KSYM_asciitilde KSYM_UNDEFINED /* undefined */ + +#define KSYM_Adiaeresis SDLK_WORLD_36 +#define KSYM_Odiaeresis SDLK_WORLD_54 +#define KSYM_Udiaeresis SDLK_WORLD_60 +#define KSYM_adiaeresis SDLK_WORLD_68 +#define KSYM_odiaeresis SDLK_WORLD_86 +#define KSYM_udiaeresis SDLK_WORLD_92 +#define KSYM_ssharp SDLK_WORLD_63 + +#ifndef SDLK_A +#define SDLK_A 65 +#define SDLK_B 66 +#define SDLK_C 67 +#define SDLK_D 68 +#define SDLK_E 69 +#define SDLK_F 70 +#define SDLK_G 71 +#define SDLK_H 72 +#define SDLK_I 73 +#define SDLK_J 74 +#define SDLK_K 75 +#define SDLK_L 76 +#define SDLK_M 77 +#define SDLK_N 78 +#define SDLK_O 79 +#define SDLK_P 80 +#define SDLK_Q 81 +#define SDLK_R 82 +#define SDLK_S 83 +#define SDLK_T 84 +#define SDLK_U 85 +#define SDLK_V 86 +#define SDLK_W 87 +#define SDLK_X 88 +#define SDLK_Y 89 +#define SDLK_Z 90 +#endif + +#define KSYM_A SDLK_A +#define KSYM_B SDLK_B +#define KSYM_C SDLK_C +#define KSYM_D SDLK_D +#define KSYM_E SDLK_E +#define KSYM_F SDLK_F +#define KSYM_G SDLK_G +#define KSYM_H SDLK_H +#define KSYM_I SDLK_I +#define KSYM_J SDLK_J +#define KSYM_K SDLK_K +#define KSYM_L SDLK_L +#define KSYM_M SDLK_M +#define KSYM_N SDLK_N +#define KSYM_O SDLK_O +#define KSYM_P SDLK_P +#define KSYM_Q SDLK_Q +#define KSYM_R SDLK_R +#define KSYM_S SDLK_S +#define KSYM_T SDLK_T +#define KSYM_U SDLK_U +#define KSYM_V SDLK_V +#define KSYM_W SDLK_W +#define KSYM_X SDLK_X +#define KSYM_Y SDLK_Y +#define KSYM_Z SDLK_Z + +#define KSYM_a SDLK_a +#define KSYM_b SDLK_b +#define KSYM_c SDLK_c +#define KSYM_d SDLK_d +#define KSYM_e SDLK_e +#define KSYM_f SDLK_f +#define KSYM_g SDLK_g +#define KSYM_h SDLK_h +#define KSYM_i SDLK_i +#define KSYM_j SDLK_j +#define KSYM_k SDLK_k +#define KSYM_l SDLK_l +#define KSYM_m SDLK_m +#define KSYM_n SDLK_n +#define KSYM_o SDLK_o +#define KSYM_p SDLK_p +#define KSYM_q SDLK_q +#define KSYM_r SDLK_r +#define KSYM_s SDLK_s +#define KSYM_t SDLK_t +#define KSYM_u SDLK_u +#define KSYM_v SDLK_v +#define KSYM_w SDLK_w +#define KSYM_x SDLK_x +#define KSYM_y SDLK_y +#define KSYM_z SDLK_z + +#define KSYM_0 SDLK_0 +#define KSYM_1 SDLK_1 +#define KSYM_2 SDLK_2 +#define KSYM_3 SDLK_3 +#define KSYM_4 SDLK_4 +#define KSYM_5 SDLK_5 +#define KSYM_6 SDLK_6 +#define KSYM_7 SDLK_7 +#define KSYM_8 SDLK_8 +#define KSYM_9 SDLK_9 + +#define KSYM_KP_0 SDLK_KP0 +#define KSYM_KP_1 SDLK_KP1 +#define KSYM_KP_2 SDLK_KP2 +#define KSYM_KP_3 SDLK_KP3 +#define KSYM_KP_4 SDLK_KP4 +#define KSYM_KP_5 SDLK_KP5 +#define KSYM_KP_6 SDLK_KP6 +#define KSYM_KP_7 SDLK_KP7 +#define KSYM_KP_8 SDLK_KP8 +#define KSYM_KP_9 SDLK_KP9 + +#define KSYM_F1 SDLK_F1 +#define KSYM_F2 SDLK_F2 +#define KSYM_F3 SDLK_F3 +#define KSYM_F4 SDLK_F4 +#define KSYM_F5 SDLK_F5 +#define KSYM_F6 SDLK_F6 +#define KSYM_F7 SDLK_F7 +#define KSYM_F8 SDLK_F8 +#define KSYM_F9 SDLK_F9 +#define KSYM_F10 SDLK_F10 +#define KSYM_F11 SDLK_F11 +#define KSYM_F12 SDLK_F12 +#define KSYM_F13 SDLK_F13 +#define KSYM_F14 SDLK_F14 +#define KSYM_F15 SDLK_F15 +#define KSYM_F16 KSYM_UNDEFINED +#define KSYM_F17 KSYM_UNDEFINED +#define KSYM_F18 KSYM_UNDEFINED +#define KSYM_F19 KSYM_UNDEFINED +#define KSYM_F20 KSYM_UNDEFINED +#define KSYM_F21 KSYM_UNDEFINED +#define KSYM_F22 KSYM_UNDEFINED +#define KSYM_F23 KSYM_UNDEFINED +#define KSYM_F24 KSYM_UNDEFINED + + +/* SDL function definitions */ + +inline void SDLInitBufferedDisplay(DrawBuffer *, DrawWindow *); +inline boolean SDLSetVideoMode(DrawBuffer *, boolean); +inline void SDLCopyArea(SDL_Surface *, SDL_Surface *, + int, int, int, int, int, int); +inline void SDLFillRectangle(SDL_Surface *, int, int, int, int, unsigned int); +inline void SDLDrawSimpleLine(SDL_Surface *, int, int, int, int, unsigned int); + +inline boolean SDLOpenAudio(void); +inline void SDLCloseAudio(void); + +#endif /* SDL_H */ diff --git a/src/libgame/sound.c b/src/libgame/sound.c new file mode 100644 index 00000000..745e3cd9 --- /dev/null +++ b/src/libgame/sound.c @@ -0,0 +1,1032 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* sound.c * +***********************************************************/ + +#include "libgame.h" + +#include "main_TMP.h" + +#include "sound.h" +#include "misc.h" + +/*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/ + +static int playing_sounds = 0; +static struct SoundControl playlist[MAX_SOUNDS_PLAYING]; +static struct SoundControl emptySoundControl = +{ + -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL +}; + +#if defined(PLATFORM_UNIX) +static int stereo_volume[PSND_MAX_LEFT2RIGHT+1]; +static char premix_first_buffer[SND_BLOCKSIZE]; +#if defined(AUDIO_STREAMING_DSP) +static char premix_left_buffer[SND_BLOCKSIZE]; +static char premix_right_buffer[SND_BLOCKSIZE]; +static int premix_last_buffer[SND_BLOCKSIZE]; +#endif +static unsigned char playing_buffer[SND_BLOCKSIZE]; +#endif + +/* forward declaration of internal functions */ +#if defined(AUDIO_STREAMING_DSP) +static void SoundServer_InsertNewSound(struct SoundControl); +#elif defined(PLATFORM_UNIX) +static unsigned char linear_to_ulaw(int); +static int ulaw_to_linear(unsigned char); +#endif + +#if defined(PLATFORM_HPUX) +static void HPUX_Audio_Control(); +#endif + +#if defined(PLATFORM_MSDOS) +static void SoundServer_InsertNewSound(struct SoundControl); +static void SoundServer_StopSound(int); +static void SoundServer_StopAllSounds(); +#endif + +#if defined(PLATFORM_UNIX) +int OpenAudioDevice(char *audio_device_name) +{ + int audio_fd; + + /* check if desired audio device is accessible */ + if (access(audio_device_name, W_OK) != 0) + return -1; + + /* try to open audio device in non-blocking mode */ + if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0) + return audio_fd; + + /* re-open audio device in blocking mode */ + close(audio_fd); + audio_fd = open(audio_device_name, O_WRONLY); + + return audio_fd; +} + +void UnixOpenAudio(struct AudioSystemInfo *audio) +{ + static char *audio_device_name[] = + { + DEVICENAME_DSP, + DEVICENAME_AUDIO + }; + int audio_fd = -1; + int i; + + /* look for available audio devices, starting with preferred ones */ + for (i=0; i= 0) + break; + + if (audio_fd < 0) + { + Error(ERR_WARN, "cannot open audio device - no sound"); + return; + } + + close(audio_fd); + + audio->device_name = audio_device_name[i]; + audio->sound_available = TRUE; + +#if defined(AUDIO_STREAMING_DSP) + audio->loops_available = TRUE; +#endif +} + +void UnixCloseAudio(struct AudioSystemInfo *audio) +{ + if (audio->device_fd) + close(audio->device_fd); +} + +#endif /* PLATFORM_UNIX */ + +void SoundServer() +{ + int i; +#if defined(PLATFORM_UNIX) + struct SoundControl snd_ctrl; + fd_set sound_fdset; + + close(audio.soundserver_pipe[1]); /* no writing into pipe needed */ +#endif + + for(i=0;i= 0) + { + if (!playing_sounds) /* we just opened the audio device */ + { + /* 2 buffers / 512 bytes, giving 1/16 second resolution */ + /* (with stereo the effective buffer size will shrink to 256) */ + fragment_size = 0x00020009; + + if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0) + Error(ERR_EXIT_SOUND_SERVER, + "cannot set fragment size of /dev/dsp - no sounds"); + + /* try if we can use stereo sound */ + if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0) + { +#ifdef DEBUG + static boolean reported = FALSE; + + if (!reported) + { + Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp"); + reported = TRUE; + } +#endif + stereo = FALSE; + } + + if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0) + Error(ERR_EXIT_SOUND_SERVER, + "cannot set sample rate of /dev/dsp - no sounds"); + + /* get the real fragmentation size; this should return 512 */ + if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0) + Error(ERR_EXIT_SOUND_SERVER, + "cannot get fragment size of /dev/dsp - no sounds"); + + max_sample_size = fragment_size / (stereo ? 2 : 1); + } + + if (snd_ctrl.active) /* new sound has arrived */ + SoundServer_InsertNewSound(snd_ctrl); + + while(playing_sounds && + select(audio.soundserver_pipe[0] + 1, + &sound_fdset, NULL, NULL, &delay) < 1) + { + FD_SET(audio.soundserver_pipe[0], &sound_fdset); + + /* first clear the last premixing buffer */ + memset(premix_last_buffer,0,fragment_size*sizeof(int)); + + for(i=0;i=PSND_MAX_VOLUME/10) + playlist[i].volume-=PSND_MAX_VOLUME/20; + + /* adjust volume of actual sound sample */ + if (playlist[i].volume != PSND_MAX_VOLUME) + for(j=0;j> PSND_MAX_VOLUME_BITS; + + /* fill the last mixing buffer with stereo or mono sound */ + if (stereo) + { + int middle_pos = PSND_MAX_LEFT2RIGHT/2; + int left_volume = stereo_volume[middle_pos+playlist[i].stereo]; + int right_volume = stereo_volume[middle_pos-playlist[i].stereo]; + + for(j=0;j> PSND_MAX_LEFT2RIGHT_BITS; + premix_right_buffer[j] = + (right_volume * (int)premix_first_buffer[j]) + >> PSND_MAX_LEFT2RIGHT_BITS; + premix_last_buffer[2*j+0] += premix_left_buffer[j]; + premix_last_buffer[2*j+1] += premix_right_buffer[j]; + } + } + else + { + for(j=0;j= playlist[i].data_len) + { + if (playlist[i].loop) + playlist[i].playingpos = 0; + else + { + playlist[i] = emptySoundControl; + playing_sounds--; + } + } + else if (playlist[i].volume <= PSND_MAX_VOLUME/10) + { + playlist[i] = emptySoundControl; + playing_sounds--; + } + } + + /* put last mixing buffer to final playing buffer */ + for(i=0;i255) + playing_buffer[i] = 255; + else + playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80; + } + + /* finally play the sound fragment */ + write(audio.device_fd, playing_buffer,fragment_size); + } + + /* if no sounds playing, free device for other sound programs */ + if (!playing_sounds) + close(audio.device_fd); + } + } + +#else /* !AUDIO_STREAMING_DSP */ + + if (snd_ctrl.active && !snd_ctrl.loop) + { + struct timeval delay = { 0, 0 }; + byte *sample_ptr; + long sample_size, max_sample_size = SND_BLOCKSIZE; + long sample_rate = 8000; /* standard "/dev/audio" sampling rate */ + int wait_percent = 90; /* wait 90% of the real playing time */ + int i; + + if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0) + { + playing_sounds = 1; + + while(playing_sounds && + select(audio.soundserver_pipe[0] + 1, + &sound_fdset, NULL, NULL, &delay) < 1) + { + FD_SET(audio.soundserver_pipe[0], &sound_fdset); + + /* get pointer and size of the actual sound sample */ + sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos; + sample_size = + MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos); + snd_ctrl.playingpos += sample_size; + + /* fill the first mixing buffer with original sample */ + memcpy(premix_first_buffer,sample_ptr,sample_size); + + + /* adjust volume of actual sound sample */ + if (snd_ctrl.volume != PSND_MAX_VOLUME) + for(i=0;i> PSND_MAX_VOLUME_BITS; + + for(i=0;i= snd_ctrl.data_len) + playing_sounds = 0; + + /* finally play the sound fragment */ + write(audio.device_fd,playing_buffer,sample_size); + + delay.tv_sec = 0; + delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000; + } + close(audio.device_fd); + } + } + +#endif /* !AUDIO_STREAMING_DSP */ + + } + +#endif /* PLATFORM_UNIX */ + +} + +#if defined(PLATFORM_MSDOS) +static void sound_handler(struct SoundControl snd_ctrl) +{ + int i; + + if (snd_ctrl.fade_sound) + { + if (!playing_sounds) + return; + + for (i=0; ilongest) + { + longest=actual; + longest_nr=i; + } + } +#if defined(PLATFORM_MSDOS) + voice_set_volume(playlist[longest_nr].voice, 0); + deallocate_voice(playlist[longest_nr].voice); +#endif + playlist[longest_nr] = emptySoundControl; + playing_sounds--; + } + + /* check if sound is already being played (and how often) */ + for(k=0,i=0;i=1 && snd_ctrl.loop) + { + for(i=0;i=2) + { + int longest=0, longest_nr=0; + + /* look for oldest equal sound */ + for(i=0;i=longest) + { + longest=actual; + longest_nr=i; + } + } + +#if defined(PLATFORM_MSDOS) + voice_set_volume(playlist[longest_nr].voice, 0); + deallocate_voice(playlist[longest_nr].voice); +#endif + playlist[longest_nr] = emptySoundControl; + playing_sounds--; + } + + /* neuen Sound in Liste packen */ + for(i=0;i> 8) & 0x80; /* set aside the sign */ + if (sign != 0) + sample = -sample; /* get magnitude */ + if (sample > CLIP) + sample = CLIP; /* clip the magnitude */ + + /* Convert from 16 bit linear to ulaw. */ + sample = sample + BIAS; + exponent = exp_lut[( sample >> 7 ) & 0xFF]; + mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F; + ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa ); +#ifdef ZEROTRAP + if (ulawbyte == 0) + ulawbyte = 0x02; /* optional CCITT trap */ +#endif + + return(ulawbyte); +} + +/* +** This routine converts from ulaw to 16 bit linear. +** +** Craig Reese: IDA/Supercomputing Research Center +** 29 September 1989 +** +** References: +** 1) CCITT Recommendation G.711 (very difficult to follow) +** 2) MIL-STD-188-113,"Interoperability and Performance Standards +** for Analog-to_Digital Conversion Techniques," +** 17 February 1987 +** +** Input: 8 bit ulaw sample +** Output: signed 16 bit linear sample +*/ + +static int ulaw_to_linear(unsigned char ulawbyte) +{ + static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; + int sign, exponent, mantissa, sample; + + ulawbyte = ~ ulawbyte; + sign = ( ulawbyte & 0x80 ); + exponent = ( ulawbyte >> 4 ) & 0x07; + mantissa = ulawbyte & 0x0F; + sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) ); + if (sign != 0) + sample = -sample; + + return(sample); +} +#endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */ + +/*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/ + +/*===========================================================================*/ + +/*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/ + +#define CHUNK_ID_LEN 4 /* IFF style chunk id length */ +#define WAV_HEADER_SIZE 20 /* size of WAV file header */ + +boolean LoadSound(struct SampleInfo *snd_info) +{ + char filename[256]; + char *sound_ext = "wav"; +#if !defined(TARGET_SDL) +#if !defined(PLATFORM_MSDOS) + byte sound_header_buffer[WAV_HEADER_SIZE]; + char chunk[CHUNK_ID_LEN + 1]; + int chunk_length, dummy; + FILE *file; + int i; +#endif +#endif + + sprintf(filename, "%s/%s/%s.%s", + options.ro_base_directory, SOUNDS_DIRECTORY, + snd_info->name, sound_ext); + +#if defined(TARGET_SDL) + + snd_info->mix_chunk = Mix_LoadWAV(filename); + if (snd_info->mix_chunk == NULL) + { + Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); + return FALSE; + } + +#else /* !TARGET_SDL */ + +#if !defined(PLATFORM_MSDOS) + + if ((file = fopen(filename, "r")) == NULL) + { + Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename); + return FALSE; + } + + /* read chunk "RIFF" */ + getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN); + if (strcmp(chunk, "RIFF") != 0) + { + Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename); + fclose(file); + return FALSE; + } + + /* read chunk "WAVE" */ + getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN); + if (strcmp(chunk, "WAVE") != 0) + { + Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename); + fclose(file); + return FALSE; + } + + /* read header information */ + for (i=0; idata_len = chunk_length; + snd_info->data_ptr = checked_malloc(snd_info->data_len); + + /* read sound data */ + if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) != + snd_info->data_len) + { + Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); + fclose(file); + return FALSE; + } + + fclose(file); + + for (i=0; idata_len; i++) + snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80; + +#else /* PLATFORM_MSDOS */ + + snd_info->sample_ptr = load_sample(filename); + if (!snd_info->sample_ptr) + { + Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); + return FALSE; + } + +#endif /* PLATFORM_MSDOS */ +#endif /* !TARGET_SDL */ + + return TRUE; +} + +void PlaySound(int nr) +{ + PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP); +} + +void PlaySoundStereo(int nr, int stereo) +{ + PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP); +} + +void PlaySoundLoop(int nr) +{ + PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP); +} + +void PlaySoundExt(int nr, int volume, int stereo, boolean loop) +{ + struct SoundControl snd_ctrl = emptySoundControl; + + if (!audio.sound_available || !setup.sound) + return; + + if (volumePSND_MAX_VOLUME) + volume = PSND_MAX_VOLUME; + + if (stereoPSND_MAX_RIGHT) + stereo = PSND_MAX_RIGHT; + + snd_ctrl.nr = nr; + snd_ctrl.volume = volume; + snd_ctrl.stereo = stereo; + snd_ctrl.loop = loop; + snd_ctrl.active = TRUE; + snd_ctrl.data_ptr = Sound[nr].data_ptr; + snd_ctrl.data_len = Sound[nr].data_len; + +#if defined(TARGET_SDL) + + Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4); + Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4); + + Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0)); + +#else +#if !defined(PLATFORM_MSDOS) + if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0) + { + Error(ERR_WARN, "cannot pipe to child process - no sounds"); + audio.sound_available = FALSE; + return; + } +#else + sound_handler(snd_ctrl); +#endif +#endif +} + +void FadeSound(int nr) +{ + StopSoundExt(nr, SSND_FADE_SOUND); +} + +void FadeSounds() +{ + StopSoundExt(-1, SSND_FADE_ALL_SOUNDS); +} + +void StopSound(int nr) +{ + StopSoundExt(nr, SSND_STOP_SOUND); +} + +void StopSounds() +{ + StopSoundExt(-1, SSND_STOP_ALL_SOUNDS); +} + +void StopSoundExt(int nr, int method) +{ + struct SoundControl snd_ctrl = emptySoundControl; + + if (!audio.sound_available) + return; + + if (SSND_FADING(method)) + snd_ctrl.fade_sound = TRUE; + + if (SSND_ALL(method)) + snd_ctrl.stop_all_sounds = TRUE; + else + { + snd_ctrl.nr = nr; + snd_ctrl.stop_sound = TRUE; + } + +#if defined(TARGET_SDL) + + if (SSND_FADING(method)) + { + Mix_FadeOutChannel(-1, 1000); + Mix_FadeOutMusic(1000); + } + else + { + Mix_HaltChannel(-1); + Mix_HaltMusic(); + } + +#else +#if !defined(PLATFORM_MSDOS) + if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0) + { + Error(ERR_WARN, "cannot pipe to child process - no sounds"); + audio.sound_available = FALSE; + return; + } +#else + sound_handler(snd_ctrl); +#endif +#endif +} + +void FreeSounds(int num_sounds) +{ + int i; + + if (!audio.sound_available) + return; + + for(i=0; i +#include + +#define SND_BLOCKSIZE 4096 + +#if defined(PLATFORM_LINUX) +#include +#elif defined(PLATFORM_FREEBSD) +#include +#elif defined(PLATFORM_HPUX) +#include +#undef SND_BLOCKSIZE +#define SND_BLOCKSIZE 32768 +#endif + +#include "libgame.h" + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) || defined(VOXWARE) +#define AUDIO_STREAMING_DSP +#endif + +#if !defined(PLATFORM_MSDOS) +#define MAX_SOUNDS_PLAYING 16 +#else +#define MAX_SOUNDS_PLAYING 8 +#endif + +/* some values for PlaySound(), StopSound() and friends */ +#if !defined(PLATFORM_MSDOS) +#define PSND_SILENCE 0 +#define PSND_MAX_VOLUME_BITS 7 +#define PSND_MIN_VOLUME 0 +#define PSND_MAX_VOLUME (1 << PSND_MAX_VOLUME_BITS) +#define PSND_NO_LOOP 0 +#define PSND_LOOP 1 +#define PSND_MIDDLE 0 +#define PSND_MAX_STEREO_BITS 7 +#define PSND_MAX_STEREO (1 << PSND_MAX_STEREO_BITS) +#define PSND_MAX_LEFT (-PSND_MAX_STEREO) +#define PSND_MAX_RIGHT (+PSND_MAX_STEREO) +#define PSND_MAX_LEFT2RIGHT_BITS (PSND_MAX_STEREO_BITS+1) +#define PSND_MAX_LEFT2RIGHT (1 << PSND_MAX_LEFT2RIGHT_BITS) +#else +#define PSND_SILENCE 0 +#define PSND_MIN_VOLUME 0 +#define PSND_MAX_VOLUME 255 +#define PSND_NO_LOOP 0 +#define PSND_LOOP 1 +#define PSND_MAX_LEFT 0 +#define PSND_MAX_RIGHT 255 +#define PSND_MIDDLE 128 +#endif + +#define SSND_FADE_SOUND (1<<0) +#define SSND_FADE_ALL_SOUNDS (1<<1) +#define SSND_FADING(x) (x & (SSND_FADE_SOUND | SSND_FADE_ALL_SOUNDS)) +#define SSND_STOP_SOUND (1<<2) +#define SSND_STOP_ALL_SOUNDS (1<<3) +#define SSND_STOPPING(x) (x & (SSND_STOP_SOUND | SSND_STOP_ALL_SOUNDS)) +#define SSND_ALL(x) (x&(SSND_FADE_ALL_SOUNDS|SSND_STOP_ALL_SOUNDS)) + +/* settings for sound path, sound device, etc. */ +#ifndef SND_PATH +#define SND_PATH "./sounds" +#endif + +#define DEVICENAME_DSP "/dev/dsp" +#define DEVICENAME_AUDIO "/dev/audio" +#define DEVICENAME_AUDIOCTL "/dev/audioCtl" + +#if 0 +#if defined(AUDIO_STREAMING_DSP) +#define AUDIO_DEVICE DEVICENAME_DSP +#else +#define AUDIO_DEVICE DEVICENAME_AUDIO +#endif +#endif + +struct SoundHeader_SUN +{ + unsigned long magic; + unsigned long hdr_size; + unsigned long data_size; + unsigned long encoding; + unsigned long sample_rate; + unsigned long channels; +}; + +struct SoundHeader_8SVX +{ + char magic_FORM[4]; + unsigned long chunk_size; + char magic_8SVX[4]; +}; + +struct SampleInfo +{ + char *name; + byte *data_ptr; + long data_len; + +#if defined(PLATFORM_MSDOS) + SAMPLE *sample_ptr; +#endif + +#if defined(TARGET_SDL) + Mix_Chunk *mix_chunk; +#endif +}; + +struct SoundControl +{ + int nr; + int volume; + int stereo; + boolean active; + boolean loop; + boolean fade_sound; + boolean stop_sound; + boolean stop_all_sounds; + int playingtime; + long playingpos; + long data_len; + byte *data_ptr; + +#if defined(PLATFORM_MSDOS) + int voice; +#endif +}; + +/* general sound functions */ +void UnixOpenAudio(struct AudioSystemInfo *); +void UnixCloseAudio(struct AudioSystemInfo *); + +/* sound server functions */ +void SoundServer(void); + +/* sound client functions */ +boolean LoadSound(struct SampleInfo *); +void PlaySound(int); +void PlaySoundStereo(int, int); +void PlaySoundLoop(int); +void PlaySoundExt(int, int, int, boolean); +void FadeSound(int); +void FadeSounds(void); +void StopSound(int); +void StopSounds(void); +void StopSoundExt(int, int); +void FreeSounds(int); + +#endif diff --git a/src/libgame/system.c b/src/libgame/system.c new file mode 100644 index 00000000..5a55f1c2 --- /dev/null +++ b/src/libgame/system.c @@ -0,0 +1,387 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* system.c * +***********************************************************/ + +#include "libgame.h" + + +/* ========================================================================= */ +/* internal variables */ +/* ========================================================================= */ + +Display *display; +Visual *visual; +int screen; +Colormap cmap; + +DrawWindow window = None; +GC gc; + +int FrameCounter; + + +/* ========================================================================= */ +/* exported variables */ +/* ========================================================================= */ + +struct VideoSystemInfo video; +struct AudioSystemInfo audio; +struct OptionInfo options; + + +/* ========================================================================= */ +/* video functions */ +/* ========================================================================= */ + +inline void InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) +{ + video.fullscreen_available = FULLSCREEN_STATUS; + video.fullscreen_enabled = FALSE; + +#ifdef TARGET_SDL + SDLInitBufferedDisplay(backbuffer, window); +#else + X11InitBufferedDisplay(backbuffer, window); +#endif +} + +inline int GetDisplayDepth(void) +{ +#ifdef TARGET_SDL + return SDL_GetVideoSurface()->format->BitsPerPixel; +#else + return XDefaultDepth(display, screen); +#endif +} + +inline Bitmap CreateBitmap(int width, int height, int depth) +{ + int real_depth = (depth == DEFAULT_DEPTH ? GetDisplayDepth() : depth); + +#ifdef TARGET_SDL + SDL_Surface *surface_tmp, *surface_native; + + if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, + real_depth, 0, 0, 0, 0)) + == NULL) + Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); + + if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL) + Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError()); + + SDL_FreeSurface(surface_tmp); + + return surface_native; +#else + Pixmap pixmap; + + if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth))) + Error(ERR_EXIT, "cannot create pixmap"); + + return pixmap; +#endif +} + +inline void FreeBitmap(Bitmap bitmap) +{ +#ifdef TARGET_SDL + SDL_FreeSurface(bitmap); +#else + XFreePixmap(display, bitmap); +#endif +} + +inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height) +{ +#ifdef TARGET_SDL + SDLFillRectangle(bitmap, x, y, width, height, 0x000000); +#else + XFillRectangle(display, bitmap, gc, x, y, width, height); +#endif +} + +inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap, + int src_x, int src_y, + int width, int height, + int dst_x, int dst_y) +{ +#ifdef TARGET_SDL + SDLCopyArea(src_bitmap, dst_bitmap, + src_x, src_y, width, height, dst_x, dst_y); +#else + XCopyArea(display, src_bitmap, dst_bitmap, gc, + src_x, src_y, width, height, dst_x, dst_y); +#endif +} + +#ifndef TARGET_SDL +static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */ +#endif + +inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap) +{ +#ifndef TARGET_SDL + XSetClipMask(display, clip_gc, clip_pixmap); + last_clip_gc = clip_gc; +#endif +} + +inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y) +{ +#ifndef TARGET_SDL + XSetClipOrigin(display, clip_gc, clip_x, clip_y); + last_clip_gc = clip_gc; +#endif +} + +inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap, + int src_x, int src_y, + int width, int height, + int dst_x, int dst_y) +{ +#ifdef TARGET_SDL + SDLCopyArea(src_bitmap, dst_bitmap, + src_x, src_y, width, height, dst_x, dst_y); +#else + XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc, + src_x, src_y, width, height, dst_x, dst_y); +#endif +} + +inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y, + int to_x, int to_y) +{ +#ifdef TARGET_SDL + SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff); +#else + XSetForeground(display, gc, WhitePixel(display, screen)); + XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y); + XSetForeground(display, gc, BlackPixel(display, screen)); +#endif +} + +/* execute all pending screen drawing operations */ +inline void FlushDisplay(void) +{ +#ifndef TARGET_SDL + XFlush(display); +#endif +} + +/* execute and wait for all pending screen drawing operations */ +inline void SyncDisplay(void) +{ +#ifndef TARGET_SDL + XSync(display, FALSE); +#endif +} + +inline void KeyboardAutoRepeatOn(void) +{ +#ifdef TARGET_SDL + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2, + SDL_DEFAULT_REPEAT_INTERVAL / 2); + SDL_EnableUNICODE(1); +#else + XAutoRepeatOn(display); +#endif +} + +inline void KeyboardAutoRepeatOff(void) +{ +#ifdef TARGET_SDL + SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); + SDL_EnableUNICODE(0); +#else + XAutoRepeatOff(display); +#endif +} + +inline boolean PointerInWindow(DrawWindow window) +{ +#ifdef TARGET_SDL + return TRUE; +#else + DrawWindow root, child; + int root_x, root_y; + unsigned int mask; + int win_x, win_y; + + /* if XQueryPointer() returns False, the pointer + is not on the same screen as the specified window */ + return XQueryPointer(display, window, &root, &child, &root_x, &root_y, + &win_x, &win_y, &mask); +#endif +} + +inline boolean SetVideoMode(boolean fullscreen) +{ +#ifdef TARGET_SDL + return SDLSetVideoMode(&backbuffer, fullscreen); +#else + boolean success = TRUE; + + if (fullscreen && video.fullscreen_available) + { + Error(ERR_WARN, "fullscreen not available in X11 version"); + + /* display error message only once */ + video.fullscreen_available = FALSE; + + success = FALSE; + } + + return success; +#endif +} + +inline boolean ChangeVideoModeIfNeeded(boolean fullscreen) +{ +#ifdef TARGET_SDL + if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)|| + (!fullscreen && video.fullscreen_enabled)) + fullscreen = SetVideoMode(fullscreen_wanted); +#endif + + return fullscreen; +} + + +/* ========================================================================= */ +/* audio functions */ +/* ========================================================================= */ + +inline boolean OpenAudio(struct AudioSystemInfo *audio) +{ + audio->sound_available = FALSE; + audio->loops_available = FALSE; + audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0; + audio->soundserver_pid = 0; + audio->device_name = NULL; + audio->device_fd = 0; + +#if defined(TARGET_SDL) + if (SDLOpenAudio()) + { + audio->sound_available = TRUE; + audio->loops_available = TRUE; + } +#elif defined(PLATFORM_MSDOS) + if (MSDOSOpenAudio()) + { + audio->sound_available = TRUE; + audio->loops_available = TRUE; + } +#elif defined(PLATFORM_UNIX) + UnixOpenAudio(audio); +#endif + + return audio->sound_available; +} + +inline void CloseAudio(struct AudioSystemInfo *audio) +{ +#if defined(TARGET_SDL) + SDLCloseAudio(); +#elif defined(PLATFORM_MSDOS) + MSDOSCloseAudio(); +#elif defined(PLATFORM_UNIX) + UnixCloseAudio(audio); +#endif + + audio->sound_available = FALSE; + audio->loops_available = FALSE; +} + + +/* ========================================================================= */ +/* event functions */ +/* ========================================================================= */ + +inline void InitEventFilter(EventFilter filter_function) +{ +#ifdef TARGET_SDL + /* set event filter to filter out certain events */ + SDL_SetEventFilter(filter_function); +#endif +} + +inline boolean PendingEvent(void) +{ +#ifdef TARGET_SDL + return (SDL_PollEvent(NULL) ? TRUE : FALSE); +#else + return (XPending(display) ? TRUE : FALSE); +#endif +} + +inline void NextEvent(Event *event) +{ +#ifdef TARGET_SDL + SDL_WaitEvent(event); +#else + XNextEvent(display, event); +#endif +} + +inline Key GetEventKey(KeyEvent *event, boolean with_modifiers) +{ +#ifdef TARGET_SDL +#if 0 + printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n", + (int)event->keysym.unicode, + (int)event->keysym.sym, + (int)SDL_GetModState()); +#endif + + if (with_modifiers && event->keysym.unicode != 0) + return event->keysym.unicode; + else + return event->keysym.sym; +#else +#if 0 + printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n", + (int)XLookupKeysym(event, event->state), + (int)XLookupKeysym(event, 0)); +#endif + + if (with_modifiers) + return XLookupKeysym(event, event->state); + else + return XLookupKeysym(event, 0); +#endif +} + +inline boolean CheckCloseWindowEvent(ClientMessageEvent *event) +{ + if (event->type != EVENT_CLIENTMESSAGE) + return FALSE; + +#if defined(TARGET_SDL) + return TRUE; /* the only possible message here is SDL_QUIT */ +#elif defined(PLATFORM_UNIX) + if ((event->window == window) && + (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE))) + return TRUE; +#endif + + return FALSE; +} + + +inline void dummy(void) +{ +#ifdef TARGET_SDL +#else +#endif +} diff --git a/src/libgame/system.h b/src/libgame/system.h new file mode 100644 index 00000000..fe805c8a --- /dev/null +++ b/src/libgame/system.h @@ -0,0 +1,128 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* system.h * +***********************************************************/ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#include "libgame.h" + +#if defined(PLATFORM_MSDOS) +#include "msdos.h" +#endif + +#if defined(TARGET_SDL) +#include "sdl.h" +#elif defined(TARGET_X11) +#include "x11.h" +#endif + + +/* contant definitions */ + +#define DEFAULT_DEPTH 0 + +#define FULLSCREEN_NOT_AVAILABLE FALSE +#define FULLSCREEN_AVAILABLE TRUE + + +/* type definitions */ + +typedef int (*EventFilter)(const Event *); + + +/* structure definitions */ + +struct VideoSystemInfo +{ + boolean fullscreen_available; + boolean fullscreen_enabled; +}; + +struct AudioSystemInfo +{ + boolean sound_available; + boolean loops_available; + int soundserver_pipe[2]; + int soundserver_pid; + char *device_name; + int device_fd; +}; + +struct OptionInfo +{ + char *display_name; + char *server_host; + int server_port; + char *ro_base_directory; + char *rw_base_directory; + char *level_directory; + boolean serveronly; + boolean network; + boolean verbose; + boolean debug; +}; + + +/* ========================================================================= */ +/* exported variables */ +/* ========================================================================= */ + +extern struct VideoSystemInfo video; +extern struct AudioSystemInfo audio; +extern struct OptionInfo options; + + +/* declarations of internal variables */ + +extern Display *display; +extern Visual *visual; +extern int screen; +extern Colormap cmap; + +extern DrawWindow window; +extern GC gc; + +extern int FrameCounter; + + +/* function definitions */ + +inline void InitBufferedDisplay(DrawBuffer *, DrawWindow *); +inline int GetDisplayDepth(void); +inline Bitmap CreateBitmap(int, int, int); +inline void FreeBitmap(Bitmap); +inline void ClearRectangle(Bitmap, int, int, int, int); +inline void BlitBitmap(Bitmap, Bitmap, int, int, int, int, int, int); +inline void SetClipMask(GC, Pixmap); +inline void SetClipOrigin(GC, int, int); +inline void BlitBitmapMasked(Bitmap, Bitmap, int, int, int, int, int, int); +inline void DrawSimpleWhiteLine(Bitmap, int, int, int, int); +inline void FlushDisplay(void); +inline void SyncDisplay(void); +inline void KeyboardAutoRepeatOn(void); +inline void KeyboardAutoRepeatOff(void); +inline boolean PointerInWindow(DrawWindow); +inline boolean SetVideoMode(boolean); +inline boolean ChangeVideoModeIfNeeded(boolean); + +inline boolean OpenAudio(struct AudioSystemInfo *); +inline void CloseAudio(struct AudioSystemInfo *); + +inline void InitEventFilter(EventFilter); +inline boolean PendingEvent(void); +inline void NextEvent(Event *event); +inline Key GetEventKey(KeyEvent *, boolean); +inline boolean CheckCloseWindowEvent(ClientMessageEvent *); + +#endif /* SYSTEM_H */ diff --git a/src/libgame/text.c b/src/libgame/text.c new file mode 100644 index 00000000..28f88c56 --- /dev/null +++ b/src/libgame/text.c @@ -0,0 +1,156 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* text.c * +***********************************************************/ + +#include + +#include "libgame.h" + +#include "main_TMP.h" + +int getFontWidth(int font_size, int font_type) +{ + return (font_size == FS_BIG ? FONT1_XSIZE : + font_size == FS_MEDIUM ? FONT6_XSIZE : + font_type == FC_SPECIAL1 ? FONT3_XSIZE : + font_type == FC_SPECIAL2 ? FONT4_XSIZE : + font_type == FC_SPECIAL3 ? FONT5_XSIZE : + FONT2_XSIZE); +} + +int getFontHeight(int font_size, int font_type) +{ + return (font_size == FS_BIG ? FONT1_YSIZE : + font_size == FS_MEDIUM ? FONT6_YSIZE : + font_type == FC_SPECIAL1 ? FONT3_YSIZE : + font_type == FC_SPECIAL2 ? FONT4_YSIZE : + font_type == FC_SPECIAL3 ? FONT5_YSIZE : + FONT2_YSIZE); +} + +void DrawInitText(char *text, int ypos, int color) +{ + if (window && pix[PIX_SMALLFONT]) + { + ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE); + DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2, + ypos, text, FS_SMALL, color); + FlushDisplay(); + } +} + +void DrawTextFCentered(int y, int font_type, char *format, ...) +{ + char buffer[FULL_SXSIZE / FONT5_XSIZE + 10]; + int font_width = getFontWidth(FS_SMALL, font_type); + va_list ap; + + va_start(ap, format); + vsprintf(buffer, format, ap); + va_end(ap); + + DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y, + buffer, FS_SMALL, font_type); +} + +void DrawTextF(int x, int y, int font_type, char *format, ...) +{ + char buffer[FULL_SXSIZE / FONT5_XSIZE + 10]; + va_list ap; + + va_start(ap, format); + vsprintf(buffer, format, ap); + va_end(ap); + + DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type); +} + +void DrawText(int x, int y, char *text, int font_size, int font_type) +{ + DrawTextExt(drawto, gc, x, y, text, font_size, font_type); + + if (x < DX) + redraw_mask |= REDRAW_FIELD; + else if (y < VY) + redraw_mask |= REDRAW_DOOR_1; +} + +void DrawTextExt(DrawBuffer d, GC gc, int x, int y, + char *text, int font_size, int font_type) +{ + int font_width, font_height, font_start; + int font_bitmap; + boolean print_inverse = FALSE; + + if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM) + font_size = FS_SMALL; + if (font_type < FC_RED || font_type > FC_SPECIAL3) + font_type = FC_RED; + + font_width = getFontWidth(font_size, font_type); + font_height = getFontHeight(font_size, font_type); + + font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT : + font_size == FS_MEDIUM ? PIX_MEDIUMFONT : + PIX_SMALLFONT); + font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE : + font_size == FS_MEDIUM ? FONT6_YSIZE : + FONT2_YSIZE) * + FONT_LINES_PER_FONT); + + if (font_type == FC_SPECIAL3) + font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT; + + while (*text) + { + char c = *text++; + + if (c == '~' && font_size == FS_SMALL) + { + print_inverse = TRUE; + continue; + } + + if (c >= 'a' && c <= 'z') + c = 'A' + (c - 'a'); + else if (c == 'ä' || c == 'Ä') + c = 91; + else if (c == 'ö' || c == 'Ö') + c = 92; + else if (c == 'ü' || c == 'Ü') + c = 93; + + if (c >= 32 && c <= 95) + { + int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width; + int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start; + int dest_x = x, dest_y = y; + + if (print_inverse) + { + BlitBitmap(pix[font_bitmap], d, + FONT_CHARS_PER_LINE * font_width, + 3 * font_height + font_start, + font_width, font_height, x, y); + + SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y); + BlitBitmapMasked(pix_masked[font_bitmap], d, + 0, 0, font_width, font_height, dest_x, dest_y); + } + else + BlitBitmap(pix[font_bitmap], d, + src_x, src_y, font_width, font_height, dest_x, dest_y); + } + + x += font_width; + } +} diff --git a/src/libgame/text.h b/src/libgame/text.h new file mode 100644 index 00000000..57fa7e13 --- /dev/null +++ b/src/libgame/text.h @@ -0,0 +1,27 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* text.h * +***********************************************************/ + +#ifndef TEXT_H +#define TEXT_H + +#include "libgame.h" + +int getFontWidth(int, int); +int getFontHeight(int, int); +void DrawInitText(char *, int, int); +void DrawTextF(int, int, int, char *, ...); +void DrawTextFCentered(int, int, char *, ...); +void DrawText(int, int, char *, int, int); +void DrawTextExt(DrawBuffer, GC, int, int, char *, int, int); + +#endif /* TEXT_H */ diff --git a/src/libgame/types.h b/src/libgame/types.h new file mode 100644 index 00000000..e4aad2a3 --- /dev/null +++ b/src/libgame/types.h @@ -0,0 +1,25 @@ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* types.h * +***********************************************************/ + +#ifndef TYPES_H +#define TYPES_H + +typedef unsigned char boolean; +typedef unsigned char byte; + +#ifndef FALSE +#define FALSE 0 +#define TRUE (!FALSE) +#endif + +#endif /* TYPES_H */ diff --git a/src/libgame/x11.c b/src/libgame/x11.c new file mode 100644 index 00000000..9de89c95 --- /dev/null +++ b/src/libgame/x11.c @@ -0,0 +1,207 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* x11.c * +***********************************************************/ + +#include "libgame.h" + +#if defined(TARGET_X11) + +#include "main_TMP.h" + +struct IconFileInfo +{ + char *picture_filename; + char *picturemask_filename; +}; + +static void X11InitDisplay() +{ +#if !defined(PLATFORM_MSDOS) + XVisualInfo vinfo_template, *vinfo; + int num_visuals; +#endif + unsigned int depth; + + /* connect to X server */ + if (!(display = XOpenDisplay(options.display_name))) + Error(ERR_EXIT, "cannot connect to X server %s", + XDisplayName(options.display_name)); + + screen = DefaultScreen(display); + visual = DefaultVisual(display, screen); + depth = DefaultDepth(display, screen); + cmap = DefaultColormap(display, screen); + +#if !defined(PLATFORM_MSDOS) + /* look for good enough visual */ + vinfo_template.screen = screen; + vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor); + vinfo_template.depth = depth; + if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask | + VisualDepthMask, &vinfo_template, &num_visuals))) + { + visual = vinfo->visual; + XFree((void *)vinfo); + } + + /* got appropriate visual? */ + if (depth < 8) + { + printf("Sorry, displays with less than 8 bits per pixel not supported.\n"); + exit(-1); + } + else if ((depth ==8 && visual->class != PseudoColor) || + (depth > 8 && visual->class != TrueColor && + visual->class != DirectColor)) + { + printf("Sorry, cannot get appropriate visual.\n"); + exit(-1); + } +#endif /* !PLATFORM_MSDOS */ +} + +static DrawWindow X11InitWindow() +{ + Window window; + unsigned int border_width = 4; + XGCValues gc_values; + unsigned long gc_valuemask; +#if !defined(PLATFORM_MSDOS) + XTextProperty windowName, iconName; + Pixmap icon_pixmap, iconmask_pixmap; + unsigned int icon_width, icon_height; + int icon_hot_x, icon_hot_y; + char icon_filename[256]; + XSizeHints size_hints; + XWMHints wm_hints; + XClassHint class_hints; + char *window_name = WINDOW_TITLE_STRING; + char *icon_name = WINDOW_TITLE_STRING; + long window_event_mask; + Atom proto_atom = None, delete_atom = None; +#endif + int screen_width, screen_height; + int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS; + unsigned long pen_fg = WhitePixel(display,screen); + unsigned long pen_bg = BlackPixel(display,screen); + const int width = WIN_XSIZE, height = WIN_YSIZE; + +#if !defined(PLATFORM_MSDOS) + static struct IconFileInfo icon_pic = + { + "rocks_icon.xbm", + "rocks_iconmask.xbm" + }; +#endif + + screen_width = XDisplayWidth(display, screen); + screen_height = XDisplayHeight(display, screen); + + win_xpos = (screen_width - width) / 2; + win_ypos = (screen_height - height) / 2; + + window = XCreateSimpleWindow(display, RootWindow(display, screen), + win_xpos, win_ypos, width, height, border_width, + pen_fg, pen_bg); + +#if !defined(PLATFORM_MSDOS) + proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE); + delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE); + if ((proto_atom != None) && (delete_atom != None)) + XChangeProperty(display, window, proto_atom, XA_ATOM, 32, + PropModePrepend, (unsigned char *) &delete_atom, 1); + + sprintf(icon_filename, "%s/%s/%s", + options.ro_base_directory, GRAPHICS_DIRECTORY, + icon_pic.picture_filename); + XReadBitmapFile(display,window,icon_filename, + &icon_width,&icon_height, + &icon_pixmap,&icon_hot_x,&icon_hot_y); + if (!icon_pixmap) + Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); + + sprintf(icon_filename, "%s/%s/%s", + options.ro_base_directory, GRAPHICS_DIRECTORY, + icon_pic.picturemask_filename); + XReadBitmapFile(display,window,icon_filename, + &icon_width,&icon_height, + &iconmask_pixmap,&icon_hot_x,&icon_hot_y); + if (!iconmask_pixmap) + Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); + + size_hints.width = size_hints.min_width = size_hints.max_width = width; + size_hints.height = size_hints.min_height = size_hints.max_height = height; + size_hints.flags = PSize | PMinSize | PMaxSize; + + if (win_xpos || win_ypos) + { + size_hints.x = win_xpos; + size_hints.y = win_ypos; + size_hints.flags |= PPosition; + } + + if (!XStringListToTextProperty(&window_name, 1, &windowName)) + Error(ERR_EXIT, "structure allocation for windowName failed"); + + if (!XStringListToTextProperty(&icon_name, 1, &iconName)) + Error(ERR_EXIT, "structure allocation for iconName failed"); + + wm_hints.initial_state = NormalState; + wm_hints.input = True; + wm_hints.icon_pixmap = icon_pixmap; + wm_hints.icon_mask = iconmask_pixmap; + wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint; + + class_hints.res_name = program_name; + class_hints.res_class = "Rocks'n'Diamonds"; + + XSetWMProperties(display, window, &windowName, &iconName, + NULL, 0, &size_hints, &wm_hints, + &class_hints); + + XFree(windowName.value); + XFree(iconName.value); + + /* Select event types wanted */ + window_event_mask = + ExposureMask | StructureNotifyMask | FocusChangeMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + PointerMotionHintMask | KeyPressMask | KeyReleaseMask; + + XSelectInput(display, window, window_event_mask); +#endif + + /* create GC for drawing with window depth and background color (black) */ + gc_values.graphics_exposures = False; + gc_values.foreground = pen_bg; + gc_values.background = pen_bg; + gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground; + gc = XCreateGC(display, window, gc_valuemask, &gc_values); + + return window; +} + +inline void X11InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) +{ + X11InitDisplay(); + *window = X11InitWindow(); + + XMapWindow(display, *window); + FlushDisplay(); + + /* create additional buffer for double-buffering */ + *backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); + pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is off-screen buffer */ +} + +#endif /* TARGET_X11 */ diff --git a/src/libgame/x11.h b/src/libgame/x11.h new file mode 100644 index 00000000..ca1247c5 --- /dev/null +++ b/src/libgame/x11.h @@ -0,0 +1,273 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* x11.h * +***********************************************************/ + +#ifndef X11_H +#define X11_H + +#if !defined(PLATFORM_MSDOS) +#define XK_MISCELLANY +#define XK_LATIN1 + +#include +#include +#include +#include +#include +#include +#endif + + +/* system dependent definitions */ + +/* MS-DOS header file also defines "TARGET_STRING" */ +#ifndef TARGET_STRING +#define TARGET_STRING "X11" +#endif + +#define FULLSCREEN_STATUS FULLSCREEN_NOT_AVAILABLE + + +/* X11 type definitions */ + +typedef Pixmap Bitmap; +typedef Window DrawWindow; +typedef Drawable DrawBuffer; + +typedef KeySym Key; + +typedef XEvent Event; +typedef XButtonEvent ButtonEvent; +typedef XMotionEvent MotionEvent; +typedef XKeyEvent KeyEvent; +typedef XExposeEvent ExposeEvent; +typedef XFocusChangeEvent FocusChangeEvent; +typedef XClientMessageEvent ClientMessageEvent; + + +/* X11 symbol definitions */ + +#define EVENT_BUTTONPRESS ButtonPress +#define EVENT_BUTTONRELEASE ButtonRelease +#define EVENT_MOTIONNOTIFY MotionNotify +#define EVENT_KEYPRESS KeyPress +#define EVENT_KEYRELEASE KeyRelease +#define EVENT_EXPOSE Expose +#define EVENT_FOCUSIN FocusIn +#define EVENT_FOCUSOUT FocusOut +#define EVENT_CLIENTMESSAGE ClientMessage +#define EVENT_MAPNOTIFY MapNotify +#define EVENT_UNMAPNOTIFY UnmapNotify + +#define KSYM_UNDEFINED XK_VoidSymbol + +#define KSYM_Return XK_Return +#define KSYM_Escape XK_Escape + +#define KSYM_Left XK_Left +#define KSYM_Right XK_Right +#define KSYM_Up XK_Up +#define KSYM_Down XK_Down + +#ifdef XK_KP_Left +#define KSYM_KP_Left XK_KP_Left +#define KSYM_KP_Right XK_KP_Right +#define KSYM_KP_Up XK_KP_Up +#define KSYM_KP_Down XK_KP_Down +#endif + +#ifdef XK_KP_Enter +#define KSYM_KP_Enter XK_KP_Enter +#define KSYM_KP_Add XK_KP_Add +#define KSYM_KP_Subtract XK_KP_Subtract +#define KSYM_KP_Multiply XK_KP_Multiply +#define KSYM_KP_Divide XK_KP_Divide +#define KSYM_KP_Separator XK_KP_Separator +#endif + +#define KSYM_Shift_L XK_Shift_L +#define KSYM_Shift_R XK_Shift_R +#define KSYM_Control_L XK_Control_L +#define KSYM_Control_R XK_Control_R +#define KSYM_Meta_L XK_Meta_L +#define KSYM_Meta_R XK_Meta_R +#define KSYM_Alt_L XK_Alt_L +#define KSYM_Alt_R XK_Alt_R +#define KSYM_Super_L XK_Super_L +#define KSYM_Super_R XK_Super_R +#define KSYM_Mode_switch XK_Mode_switch +#define KSYM_Multi_key XK_Multi_key + +#define KSYM_BackSpace XK_BackSpace +#define KSYM_Delete XK_Delete +#define KSYM_Insert XK_Insert +#define KSYM_Tab XK_Tab +#define KSYM_Home XK_Home +#define KSYM_End XK_End +#define KSYM_Page_Up XK_Page_Up +#define KSYM_Page_Down XK_Page_Down +#define KSYM_Menu XK_Menu + +#define KSYM_space XK_space +#define KSYM_exclam XK_exclam +#define KSYM_quotedbl XK_quotedbl +#define KSYM_numbersign XK_numbersign +#define KSYM_dollar XK_dollar +#define KSYM_percent XK_percent +#define KSYM_ampersand XK_ampersand +#define KSYM_apostrophe XK_apostrophe +#define KSYM_parenleft XK_parenleft +#define KSYM_parenright XK_parenright +#define KSYM_asterisk XK_asterisk +#define KSYM_plus XK_plus +#define KSYM_comma XK_comma +#define KSYM_minus XK_minus +#define KSYM_period XK_period +#define KSYM_slash XK_slash + +#define KSYM_colon XK_colon +#define KSYM_semicolon XK_semicolon +#define KSYM_less XK_less +#define KSYM_equal XK_equal +#define KSYM_greater XK_greater +#define KSYM_question XK_question +#define KSYM_at XK_at + +#define KSYM_bracketleft XK_bracketleft +#define KSYM_backslash XK_backslash +#define KSYM_bracketright XK_bracketright +#define KSYM_asciicircum XK_asciicircum +#define KSYM_underscore XK_underscore +#define KSYM_grave XK_grave + +#define KSYM_quoteleft XK_quoteleft +#define KSYM_braceleft XK_braceleft +#define KSYM_bar XK_bar +#define KSYM_braceright XK_braceright +#define KSYM_asciitilde XK_asciitilde + +#define KSYM_Adiaeresis XK_Adiaeresis +#define KSYM_Odiaeresis XK_Odiaeresis +#define KSYM_Udiaeresis XK_Udiaeresis +#define KSYM_adiaeresis XK_adiaeresis +#define KSYM_odiaeresis XK_odiaeresis +#define KSYM_udiaeresis XK_udiaeresis +#define KSYM_ssharp XK_ssharp + +#define KSYM_A XK_A +#define KSYM_B XK_B +#define KSYM_C XK_C +#define KSYM_D XK_D +#define KSYM_E XK_E +#define KSYM_F XK_F +#define KSYM_G XK_G +#define KSYM_H XK_H +#define KSYM_I XK_I +#define KSYM_J XK_J +#define KSYM_K XK_K +#define KSYM_L XK_L +#define KSYM_M XK_M +#define KSYM_N XK_N +#define KSYM_O XK_O +#define KSYM_P XK_P +#define KSYM_Q XK_Q +#define KSYM_R XK_R +#define KSYM_S XK_S +#define KSYM_T XK_T +#define KSYM_U XK_U +#define KSYM_V XK_V +#define KSYM_W XK_W +#define KSYM_X XK_X +#define KSYM_Y XK_Y +#define KSYM_Z XK_Z + +#define KSYM_a XK_a +#define KSYM_b XK_b +#define KSYM_c XK_c +#define KSYM_d XK_d +#define KSYM_e XK_e +#define KSYM_f XK_f +#define KSYM_g XK_g +#define KSYM_h XK_h +#define KSYM_i XK_i +#define KSYM_j XK_j +#define KSYM_k XK_k +#define KSYM_l XK_l +#define KSYM_m XK_m +#define KSYM_n XK_n +#define KSYM_o XK_o +#define KSYM_p XK_p +#define KSYM_q XK_q +#define KSYM_r XK_r +#define KSYM_s XK_s +#define KSYM_t XK_t +#define KSYM_u XK_u +#define KSYM_v XK_v +#define KSYM_w XK_w +#define KSYM_x XK_x +#define KSYM_y XK_y +#define KSYM_z XK_z + +#define KSYM_0 XK_0 +#define KSYM_1 XK_1 +#define KSYM_2 XK_2 +#define KSYM_3 XK_3 +#define KSYM_4 XK_4 +#define KSYM_5 XK_5 +#define KSYM_6 XK_6 +#define KSYM_7 XK_7 +#define KSYM_8 XK_8 +#define KSYM_9 XK_9 + +#define KSYM_KP_0 XK_KP_0 +#define KSYM_KP_1 XK_KP_1 +#define KSYM_KP_2 XK_KP_2 +#define KSYM_KP_3 XK_KP_3 +#define KSYM_KP_4 XK_KP_4 +#define KSYM_KP_5 XK_KP_5 +#define KSYM_KP_6 XK_KP_6 +#define KSYM_KP_7 XK_KP_7 +#define KSYM_KP_8 XK_KP_8 +#define KSYM_KP_9 XK_KP_9 + +#define KSYM_F1 XK_F1 +#define KSYM_F2 XK_F2 +#define KSYM_F3 XK_F3 +#define KSYM_F4 XK_F4 +#define KSYM_F5 XK_F5 +#define KSYM_F6 XK_F6 +#define KSYM_F7 XK_F7 +#define KSYM_F8 XK_F8 +#define KSYM_F9 XK_F9 +#define KSYM_F10 XK_F10 +#define KSYM_F11 XK_F11 +#define KSYM_F12 XK_F12 +#define KSYM_F13 XK_F13 +#define KSYM_F14 XK_F14 +#define KSYM_F15 XK_F15 +#define KSYM_F16 XK_F16 +#define KSYM_F17 XK_F17 +#define KSYM_F18 XK_F18 +#define KSYM_F19 XK_F19 +#define KSYM_F20 XK_F20 +#define KSYM_F21 XK_F21 +#define KSYM_F22 XK_F22 +#define KSYM_F23 XK_F23 +#define KSYM_F24 XK_F24 + + +/* X11 function definitions */ + +inline void X11InitBufferedDisplay(DrawBuffer *, DrawWindow *); + +#endif /* X11_H */ diff --git a/src/main.c b/src/main.c index 8d927cb1..8bf9e775 100644 --- a/src/main.c +++ b/src/main.c @@ -11,31 +11,36 @@ * main.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "main.h" #include "init.h" #include "game.h" #include "events.h" -#include "sound.h" #include "joystick.h" -#include "misc.h" #if defined(PLATFORM_MSDOS) #include #endif -Display *display; -Visual *visual; -int screen; +#if 0 DrawWindow window = None; -GC gc, clip_gc[NUM_BITMAPS], tile_clip_gc; +GC gc; +#endif + +GC clip_gc[NUM_BITMAPS], tile_clip_gc; Bitmap pix[NUM_BITMAPS]; Bitmap pix_masked[NUM_BITMAPS], tile_masked[NUM_TILES]; Pixmap clipmask[NUM_BITMAPS], tile_clipmask[NUM_TILES]; DrawBuffer drawto, drawto_field, backbuffer, fieldbuffer; +#if 0 Colormap cmap; +#endif +#if 0 char *sound_device_name = AUDIO_DEVICE; +#endif int joystick_device = 0; char *joystick_device_name[MAX_PLAYERS] = @@ -56,8 +61,11 @@ boolean motion_status = FALSE; int key_joystick_mapping = 0; int global_joystick_status = JOYSTICK_STATUS; int joystick_status = JOYSTICK_STATUS; + +#if 0 boolean fullscreen_available = FULLSCREEN_STATUS; boolean fullscreen_enabled = FALSE; +#endif boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE]; int redraw_x1 = 0, redraw_y1 = 0; @@ -94,7 +102,12 @@ int SBX_Left, SBX_Right; int SBY_Upper, SBY_Lower; int ZX,ZY, ExitX,ExitY; int AllPlayersGone; -int FrameCounter, TimeFrames, TimePlayed, TimeLeft; + +#if 0 +int FrameCounter; +#endif + +int TimeFrames, TimePlayed, TimeLeft; boolean network_player_action_received = FALSE; @@ -104,10 +117,19 @@ struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL; struct HiScore highscore[MAX_SCORE_ENTRIES]; struct SampleInfo Sound[NUM_SOUNDS]; struct TapeInfo tape; + +#if 0 struct OptionInfo options; +#endif + struct SetupInfo setup; struct GameInfo game; + +#if 0 +struct VideoSystemInfo video; struct AudioSystemInfo audio; +#endif + struct GlobalInfo global; /* data needed for playing sounds */ diff --git a/src/main.h b/src/main.h index 3eb6993d..c53408b2 100644 --- a/src/main.h +++ b/src/main.h @@ -28,10 +28,9 @@ #define DEBUG_TIMING 0 #endif -typedef unsigned char boolean; -typedef unsigned char byte; - -#include "system.h" +#if 0 +#include "libgame/libgame.h" +#endif #ifndef FALSE #define FALSE 0 @@ -238,20 +237,6 @@ struct HiScore int Score; }; -struct OptionInfo -{ - char *display_name; - char *server_host; - int server_port; - char *ro_base_directory; - char *rw_base_directory; - char *level_directory; - boolean serveronly; - boolean network; - boolean verbose; - boolean debug; -}; - struct SetupJoystickInfo { char *device_name; @@ -451,19 +436,24 @@ struct GlobalInfo int fps_slowdown_factor; }; -extern Display *display; -extern Visual *visual; -extern int screen; +#if 0 extern DrawWindow window; -extern GC gc, clip_gc[], tile_clip_gc; +extern GC gc; +#endif + +extern GC clip_gc[], tile_clip_gc; extern Bitmap pix[]; extern Bitmap pix_masked[], tile_masked[]; extern Pixmap clipmask[], tile_clipmask[]; extern DrawBuffer drawto, drawto_field, backbuffer, fieldbuffer; +#if 0 extern Colormap cmap; +#endif +#if 0 extern char *sound_device_name; +#endif extern int joystick_device; extern char *joystick_device_name[]; @@ -477,8 +467,11 @@ extern int button_status; extern boolean motion_status; extern int key_joystick_mapping; extern int global_joystick_status, joystick_status; + +#if 0 extern boolean fullscreen_available; extern boolean fullscreen_enabled; +#endif extern boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE]; extern int redraw_x1, redraw_y1; @@ -514,7 +507,12 @@ extern int SBX_Left, SBX_Right; extern int SBY_Upper, SBY_Lower; extern int ZX,ZY, ExitX,ExitY; extern int AllPlayersGone; -extern int FrameCounter, TimeFrames, TimePlayed, TimeLeft; + +#if 0 +extern int FrameCounter; +#endif + +extern int TimeFrames, TimePlayed, TimeLeft; extern boolean SiebAktiv; extern int SiebCount; @@ -527,10 +525,19 @@ extern struct HiScore highscore[]; extern struct TapeInfo tape; extern struct SampleInfo Sound[]; extern struct JoystickInfo joystick[]; + +#if 0 extern struct OptionInfo options; +#endif + extern struct SetupInfo setup; extern struct GameInfo game; + +#if 0 +extern struct VideoSystemInfo video; extern struct AudioSystemInfo audio; +#endif + extern struct GlobalInfo global; extern char *sound_name[]; diff --git a/src/misc.c b/src/misc.c deleted file mode 100644 index a87a9b32..00000000 --- a/src/misc.c +++ /dev/null @@ -1,1392 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* misc.c * -***********************************************************/ - -#include "platform.h" - -#include -#include -#include -#include -#include - -#if !defined(PLATFORM_WIN32) -#include -#include -#endif - -#include "misc.h" -#include "init.h" -#include "tools.h" -#include "sound.h" -#include "random.h" -#include "joystick.h" -#include "files.h" - -#if defined(PLATFORM_MSDOS) -volatile unsigned long counter = 0; - -void increment_counter() -{ - counter++; -} - -END_OF_FUNCTION(increment_counter); -#endif - - -/* maximal allowed length of a command line option */ -#define MAX_OPTION_LEN 256 - -#ifdef TARGET_SDL -static unsigned long mainCounter(int mode) -{ - static unsigned long base_ms = 0; - unsigned long current_ms; - unsigned long counter_ms; - - current_ms = SDL_GetTicks(); - - /* reset base time in case of counter initializing or wrap-around */ - if (mode == INIT_COUNTER || current_ms < base_ms) - base_ms = current_ms; - - counter_ms = current_ms - base_ms; - - return counter_ms; /* return milliseconds since last init */ -} - -#else /* !TARGET_SDL */ - -#if defined(PLATFORM_UNIX) -static unsigned long mainCounter(int mode) -{ - static struct timeval base_time = { 0, 0 }; - struct timeval current_time; - unsigned long counter_ms; - - gettimeofday(¤t_time, NULL); - - /* reset base time in case of counter initializing or wrap-around */ - if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec) - base_time = current_time; - - counter_ms = (current_time.tv_sec - base_time.tv_sec) * 1000 - + (current_time.tv_usec - base_time.tv_usec) / 1000; - - return counter_ms; /* return milliseconds since last init */ -} -#endif /* PLATFORM_UNIX */ -#endif /* !TARGET_SDL */ - -void InitCounter() /* set counter back to zero */ -{ -#if !defined(PLATFORM_MSDOS) - mainCounter(INIT_COUNTER); -#else - LOCK_VARIABLE(counter); - LOCK_FUNCTION(increment_counter); - install_int_ex(increment_counter, BPS_TO_TIMER(100)); -#endif -} - -unsigned long Counter() /* get milliseconds since last call of InitCounter() */ -{ -#if !defined(PLATFORM_MSDOS) - return mainCounter(READ_COUNTER); -#else - return (counter * 10); -#endif -} - -static void sleep_milliseconds(unsigned long milliseconds_delay) -{ - boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE); - -#if defined(PLATFORM_MSDOS) - /* don't use select() to perform waiting operations under DOS/Windows - environment; always use a busy loop for waiting instead */ - do_busy_waiting = TRUE; -#endif - - if (do_busy_waiting) - { - /* we want to wait only a few ms -- if we assume that we have a - kernel timer resolution of 10 ms, we would wait far to long; - therefore it's better to do a short interval of busy waiting - to get our sleeping time more accurate */ - - unsigned long base_counter = Counter(), actual_counter = Counter(); - - while (actual_counter < base_counter + milliseconds_delay && - actual_counter >= base_counter) - actual_counter = Counter(); - } - else - { -#if defined(TARGET_SDL) - SDL_Delay(milliseconds_delay); -#else - struct timeval delay; - - delay.tv_sec = milliseconds_delay / 1000; - delay.tv_usec = 1000 * (milliseconds_delay % 1000); - - if (select(0, NULL, NULL, NULL, &delay) != 0) - Error(ERR_WARN, "sleep_milliseconds(): select() failed"); -#endif - } -} - -void Delay(unsigned long delay) /* Sleep specified number of milliseconds */ -{ - sleep_milliseconds(delay); -} - -boolean FrameReached(unsigned long *frame_counter_var, - unsigned long frame_delay) -{ - unsigned long actual_frame_counter = FrameCounter; - - if (actual_frame_counter < *frame_counter_var+frame_delay && - actual_frame_counter >= *frame_counter_var) - return(FALSE); - - *frame_counter_var = actual_frame_counter; - return(TRUE); -} - -boolean DelayReached(unsigned long *counter_var, - unsigned long delay) -{ - unsigned long actual_counter = Counter(); - - if (actual_counter < *counter_var + delay && - actual_counter >= *counter_var) - return(FALSE); - - *counter_var = actual_counter; - return(TRUE); -} - -void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) -{ - unsigned long actual_counter; - - while(1) - { - actual_counter = Counter(); - - if (actual_counter < *counter_var + delay && - actual_counter >= *counter_var) - sleep_milliseconds((*counter_var + delay - actual_counter) / 2); - else - break; - } - - *counter_var = actual_counter; -} - -/* int2str() returns a number converted to a string; - the used memory is static, but will be overwritten by later calls, - so if you want to save the result, copy it to a private string buffer; - there can be 10 local calls of int2str() without buffering the result -- - the 11th call will then destroy the result from the first call and so on. -*/ - -char *int2str(int number, int size) -{ - static char shift_array[10][40]; - static int shift_counter = 0; - char *s = shift_array[shift_counter]; - - shift_counter = (shift_counter + 1) % 10; - - if (size > 20) - size = 20; - - if (size) - { - sprintf(s, " %09d", number); - return &s[strlen(s) - size]; - } - else - { - sprintf(s, "%d", number); - return s; - } -} - -unsigned int SimpleRND(unsigned int max) -{ -#if defined(TARGET_SDL) - static unsigned long root = 654321; - unsigned long current_ms; - - current_ms = SDL_GetTicks(); - root = root * 4253261 + current_ms; - return (root % max); -#else - static unsigned long root = 654321; - struct timeval current_time; - - gettimeofday(¤t_time, NULL); - root = root * 4253261 + current_time.tv_sec + current_time.tv_usec; - return (root % max); -#endif -} - -#ifdef DEBUG -static unsigned int last_RND_value = 0; - -unsigned int last_RND() -{ - return last_RND_value; -} -#endif - -unsigned int RND(unsigned int max) -{ -#ifdef DEBUG - return (last_RND_value = random_linux_libc() % max); -#else - return (random_linux_libc() % max); -#endif -} - -unsigned int InitRND(long seed) -{ -#if defined(TARGET_SDL) - unsigned long current_ms; - - if (seed == NEW_RANDOMIZE) - { - current_ms = SDL_GetTicks(); - srandom_linux_libc((unsigned int) current_ms); - return (unsigned int) current_ms; - } - else - { - srandom_linux_libc((unsigned int) seed); - return (unsigned int) seed; - } -#else - struct timeval current_time; - - if (seed == NEW_RANDOMIZE) - { - gettimeofday(¤t_time, NULL); - srandom_linux_libc((unsigned int) current_time.tv_usec); - return (unsigned int) current_time.tv_usec; - } - else - { - srandom_linux_libc((unsigned int) seed); - return (unsigned int) seed; - } -#endif -} - -char *getLoginName() -{ -#if defined(PLATFORM_WIN32) - return ANONYMOUS_NAME; -#else - struct passwd *pwd; - - if ((pwd = getpwuid(getuid())) == NULL) - return ANONYMOUS_NAME; - else - return pwd->pw_name; -#endif -} - -char *getRealName() -{ -#if defined(PLATFORM_UNIX) - struct passwd *pwd; - - if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0) - return ANONYMOUS_NAME; - else - { - static char real_name[1024]; - char *from_ptr = pwd->pw_gecos, *to_ptr = real_name; - - if (strchr(pwd->pw_gecos, 'ß') == NULL) - return pwd->pw_gecos; - - /* the user's real name contains a 'ß' character (german sharp s), - which has no equivalent in upper case letters (which our fonts use) */ - while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2) - { - if (*from_ptr != 'ß') - *to_ptr++ = *from_ptr++; - else - { - from_ptr++; - *to_ptr++ = 's'; - *to_ptr++ = 's'; - } - } - *to_ptr = '\0'; - - return real_name; - } -#else /* !PLATFORM_UNIX */ - return ANONYMOUS_NAME; -#endif -} - -char *getHomeDir() -{ -#if defined(PLATFORM_UNIX) - static char *home_dir = NULL; - - if (!home_dir) - { - if (!(home_dir = getenv("HOME"))) - { - struct passwd *pwd; - - if ((pwd = getpwuid(getuid()))) - home_dir = pwd->pw_dir; - else - home_dir = "."; - } - } - - return home_dir; -#else - return "."; -#endif -} - -char *getPath2(char *path1, char *path2) -{ - char *complete_path = checked_malloc(strlen(path1) + 1 + - strlen(path2) + 1); - - sprintf(complete_path, "%s/%s", path1, path2); - return complete_path; -} - -char *getPath3(char *path1, char *path2, char *path3) -{ - char *complete_path = checked_malloc(strlen(path1) + 1 + - strlen(path2) + 1 + - strlen(path3) + 1); - - sprintf(complete_path, "%s/%s/%s", path1, path2, path3); - return complete_path; -} - -char *getStringCopy(char *s) -{ - char *s_copy; - - if (s == NULL) - return NULL; - - s_copy = checked_malloc(strlen(s) + 1); - - strcpy(s_copy, s); - return s_copy; -} - -char *getStringToLower(char *s) -{ - char *s_copy = checked_malloc(strlen(s) + 1); - char *s_ptr = s_copy; - - while (*s) - *s_ptr++ = tolower(*s++); - *s_ptr = '\0'; - - return s_copy; -} - -void MarkTileDirty(int x, int y) -{ - int xx = redraw_x1 + x; - int yy = redraw_y1 + y; - - if (!redraw[xx][yy]) - redraw_tiles++; - - redraw[xx][yy] = TRUE; - redraw_mask |= REDRAW_TILES; -} - -void SetBorderElement() -{ - int x, y; - - BorderElement = EL_LEERRAUM; - - for(y=0; y= MAX_OPTION_LEN) - Error(ERR_EXIT_HELP, "unrecognized option '%s'", option); - - strcpy(option_str, option); /* copy argument into buffer */ - option = option_str; - - if (strcmp(option, "--") == 0) /* stop scanning arguments */ - break; - - if (strncmp(option, "--", 2) == 0) /* treat '--' like '-' */ - option++; - - option_arg = strchr(option, '='); - if (option_arg == NULL) /* no '=' in option */ - option_arg = next_option; - else - { - *option_arg++ = '\0'; /* cut argument from option */ - if (*option_arg == '\0') /* no argument after '=' */ - Error(ERR_EXIT_HELP, "option '%s' has invalid argument", option_str); - } - - option_len = strlen(option); - - if (strcmp(option, "-") == 0) - Error(ERR_EXIT_HELP, "unrecognized option '%s'", option); - else if (strncmp(option, "-help", option_len) == 0) - { - printf("Usage: %s [options] [server.name [port]]\n" - "Options:\n" - " -d, --display machine:0 X server display\n" - " -b, --basepath directory alternative base directory\n" - " -l, --level directory alternative level directory\n" - " -s, --serveronly only start network server\n" - " -n, --network network multiplayer game\n" - " -v, --verbose verbose mode\n", - program_name); - exit(0); - } - else if (strncmp(option, "-display", option_len) == 0) - { - if (option_arg == NULL) - Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); - - options.display_name = option_arg; - if (option_arg == next_option) - options_left++; - } - else if (strncmp(option, "-basepath", option_len) == 0) - { - if (option_arg == NULL) - Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); - - /* this should be extended to separate options for ro and rw data */ - options.ro_base_directory = option_arg; - options.rw_base_directory = option_arg; - if (option_arg == next_option) - options_left++; - - /* adjust path for level directory accordingly */ - options.level_directory = - getPath2(options.ro_base_directory, LEVELS_DIRECTORY); - } - else if (strncmp(option, "-levels", option_len) == 0) - { - if (option_arg == NULL) - Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); - - options.level_directory = option_arg; - if (option_arg == next_option) - options_left++; - } - else if (strncmp(option, "-network", option_len) == 0) - { - options.network = TRUE; - } - else if (strncmp(option, "-serveronly", option_len) == 0) - { - options.serveronly = TRUE; - } - else if (strncmp(option, "-verbose", option_len) == 0) - { - options.verbose = TRUE; - } - else if (strncmp(option, "-debug", option_len) == 0) - { - options.debug = TRUE; - } - else if (*option == '-') - { - Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str); - } - else if (options.server_host == NULL) - { - options.server_host = *options_left; - } - else if (options.server_port == 0) - { - options.server_port = atoi(*options_left); - if (options.server_port < 1024) - Error(ERR_EXIT_HELP, "bad port number '%d'", options.server_port); - } - else - Error(ERR_EXIT_HELP, "too many arguments"); - - options_left++; - } -} - -void Error(int mode, char *format, ...) -{ - char *process_name = ""; - FILE *error = stderr; - - /* display warnings only when running in verbose mode */ - if (mode & ERR_WARN && !options.verbose) - return; - -#if !defined(PLATFORM_UNIX) - if ((error = openErrorFile()) == NULL) - { - printf("Cannot write to error output file!\n"); - CloseAllAndExit(1); - } -#endif - - if (mode & ERR_SOUND_SERVER) - process_name = " sound server"; - else if (mode & ERR_NETWORK_SERVER) - process_name = " network server"; - else if (mode & ERR_NETWORK_CLIENT) - process_name = " network client **"; - - if (format) - { - va_list ap; - - fprintf(error, "%s%s: ", program_name, process_name); - - if (mode & ERR_WARN) - fprintf(error, "warning: "); - - va_start(ap, format); - vfprintf(error, format, ap); - va_end(ap); - - fprintf(error, "\n"); - } - - if (mode & ERR_HELP) - fprintf(error, "%s: Try option '--help' for more information.\n", - program_name); - - if (mode & ERR_EXIT) - fprintf(error, "%s%s: aborting\n", program_name, process_name); - - if (error != stderr) - fclose(error); - - if (mode & ERR_EXIT) - { - if (mode & ERR_FROM_SERVER) - exit(1); /* child process: normal exit */ - else - CloseAllAndExit(1); /* main process: clean up stuff */ - } -} - -void *checked_malloc(unsigned long size) -{ - void *ptr; - - ptr = malloc(size); - - if (ptr == NULL) - Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); - - return ptr; -} - -void *checked_calloc(unsigned long size) -{ - void *ptr; - - ptr = calloc(1, size); - - if (ptr == NULL) - Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); - - return ptr; -} - -short getFile16BitInteger(FILE *file, int byte_order) -{ - if (byte_order == BYTE_ORDER_BIG_ENDIAN) - return ((fgetc(file) << 8) | - (fgetc(file) << 0)); - else /* BYTE_ORDER_LITTLE_ENDIAN */ - return ((fgetc(file) << 0) | - (fgetc(file) << 8)); -} - -void putFile16BitInteger(FILE *file, short value, int byte_order) -{ - if (byte_order == BYTE_ORDER_BIG_ENDIAN) - { - fputc((value >> 8) & 0xff, file); - fputc((value >> 0) & 0xff, file); - } - else /* BYTE_ORDER_LITTLE_ENDIAN */ - { - fputc((value >> 0) & 0xff, file); - fputc((value >> 8) & 0xff, file); - } -} - -int getFile32BitInteger(FILE *file, int byte_order) -{ - if (byte_order == BYTE_ORDER_BIG_ENDIAN) - return ((fgetc(file) << 24) | - (fgetc(file) << 16) | - (fgetc(file) << 8) | - (fgetc(file) << 0)); - else /* BYTE_ORDER_LITTLE_ENDIAN */ - return ((fgetc(file) << 0) | - (fgetc(file) << 8) | - (fgetc(file) << 16) | - (fgetc(file) << 24)); -} - -void putFile32BitInteger(FILE *file, int value, int byte_order) -{ - if (byte_order == BYTE_ORDER_BIG_ENDIAN) - { - fputc((value >> 24) & 0xff, file); - fputc((value >> 16) & 0xff, file); - fputc((value >> 8) & 0xff, file); - fputc((value >> 0) & 0xff, file); - } - else /* BYTE_ORDER_LITTLE_ENDIAN */ - { - fputc((value >> 0) & 0xff, file); - fputc((value >> 8) & 0xff, file); - fputc((value >> 16) & 0xff, file); - fputc((value >> 24) & 0xff, file); - } -} - -void getFileChunk(FILE *file, char *chunk_buffer, int *chunk_length, - int byte_order) -{ - const int chunk_identifier_length = 4; - - /* read chunk identifier */ - fgets(chunk_buffer, chunk_identifier_length + 1, file); - - /* read chunk length */ - *chunk_length = getFile32BitInteger(file, byte_order); -} - -void putFileChunk(FILE *file, char *chunk_name, int chunk_length, - int byte_order) -{ - /* write chunk identifier */ - fputs(chunk_name, file); - - /* write chunk length */ - putFile32BitInteger(file, chunk_length, byte_order); -} - -#define TRANSLATE_KEYSYM_TO_KEYNAME 0 -#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1 -#define TRANSLATE_X11KEYNAME_TO_KEYSYM 2 - -void translate_keyname(Key *keysym, char **x11name, char **name, int mode) -{ - static struct - { - Key key; - char *x11name; - char *name; - } translate_key[] = - { - /* normal cursor keys */ - { KSYM_Left, "XK_Left", "cursor left" }, - { KSYM_Right, "XK_Right", "cursor right" }, - { KSYM_Up, "XK_Up", "cursor up" }, - { KSYM_Down, "XK_Down", "cursor down" }, - - /* keypad cursor keys */ -#ifdef KSYM_KP_Left - { KSYM_KP_Left, "XK_KP_Left", "keypad left" }, - { KSYM_KP_Right, "XK_KP_Right", "keypad right" }, - { KSYM_KP_Up, "XK_KP_Up", "keypad up" }, - { KSYM_KP_Down, "XK_KP_Down", "keypad down" }, -#endif - - /* other keypad keys */ -#ifdef KSYM_KP_Enter - { KSYM_KP_Enter, "XK_KP_Enter", "keypad enter" }, - { KSYM_KP_Add, "XK_KP_Add", "keypad +" }, - { KSYM_KP_Subtract, "XK_KP_Subtract", "keypad -" }, - { KSYM_KP_Multiply, "XK_KP_Multiply", "keypad mltply" }, - { KSYM_KP_Divide, "XK_KP_Divide", "keypad /" }, - { KSYM_KP_Separator,"XK_KP_Separator", "keypad ," }, -#endif - - /* modifier keys */ - { KSYM_Shift_L, "XK_Shift_L", "left shift" }, - { KSYM_Shift_R, "XK_Shift_R", "right shift" }, - { KSYM_Control_L, "XK_Control_L", "left control" }, - { KSYM_Control_R, "XK_Control_R", "right control" }, - { KSYM_Meta_L, "XK_Meta_L", "left meta" }, - { KSYM_Meta_R, "XK_Meta_R", "right meta" }, - { KSYM_Alt_L, "XK_Alt_L", "left alt" }, - { KSYM_Alt_R, "XK_Alt_R", "right alt" }, - { KSYM_Super_L, "XK_Super_L", "left super" }, /* Win-L */ - { KSYM_Super_R, "XK_Super_R", "right super" }, /* Win-R */ - { KSYM_Mode_switch, "XK_Mode_switch", "mode switch" }, /* Alt-R */ - { KSYM_Multi_key, "XK_Multi_key", "multi key" }, /* Ctrl-R */ - - /* some special keys */ - { KSYM_BackSpace, "XK_BackSpace", "backspace" }, - { KSYM_Delete, "XK_Delete", "delete" }, - { KSYM_Insert, "XK_Insert", "insert" }, - { KSYM_Tab, "XK_Tab", "tab" }, - { KSYM_Home, "XK_Home", "home" }, - { KSYM_End, "XK_End", "end" }, - { KSYM_Page_Up, "XK_Page_Up", "page up" }, - { KSYM_Page_Down, "XK_Page_Down", "page down" }, - { KSYM_Menu, "XK_Menu", "menu" }, /* Win-Menu */ - - /* ASCII 0x20 to 0x40 keys (except numbers) */ - { KSYM_space, "XK_space", "space" }, - { KSYM_exclam, "XK_exclam", "!" }, - { KSYM_quotedbl, "XK_quotedbl", "\"" }, - { KSYM_numbersign, "XK_numbersign", "#" }, - { KSYM_dollar, "XK_dollar", "$" }, - { KSYM_percent, "XK_percent", "%" }, - { KSYM_ampersand, "XK_ampersand", "&" }, - { KSYM_apostrophe, "XK_apostrophe", "'" }, - { KSYM_parenleft, "XK_parenleft", "(" }, - { KSYM_parenright, "XK_parenright", ")" }, - { KSYM_asterisk, "XK_asterisk", "*" }, - { KSYM_plus, "XK_plus", "+" }, - { KSYM_comma, "XK_comma", "," }, - { KSYM_minus, "XK_minus", "-" }, - { KSYM_period, "XK_period", "." }, - { KSYM_slash, "XK_slash", "/" }, - { KSYM_colon, "XK_colon", ":" }, - { KSYM_semicolon, "XK_semicolon", ";" }, - { KSYM_less, "XK_less", "<" }, - { KSYM_equal, "XK_equal", "=" }, - { KSYM_greater, "XK_greater", ">" }, - { KSYM_question, "XK_question", "?" }, - { KSYM_at, "XK_at", "@" }, - - /* more ASCII keys */ - { KSYM_bracketleft, "XK_bracketleft", "[" }, - { KSYM_backslash, "XK_backslash", "backslash" }, - { KSYM_bracketright,"XK_bracketright", "]" }, - { KSYM_asciicircum, "XK_asciicircum", "circumflex" }, - { KSYM_underscore, "XK_underscore", "_" }, - { KSYM_grave, "XK_grave", "grave" }, - { KSYM_quoteleft, "XK_quoteleft", "quote left" }, - { KSYM_braceleft, "XK_braceleft", "brace left" }, - { KSYM_bar, "XK_bar", "bar" }, - { KSYM_braceright, "XK_braceright", "brace right" }, - { KSYM_asciitilde, "XK_asciitilde", "ascii tilde" }, - - /* special (non-ASCII) keys */ - { KSYM_Adiaeresis, "XK_Adiaeresis", "Ä" }, - { KSYM_Odiaeresis, "XK_Odiaeresis", "Ö" }, - { KSYM_Udiaeresis, "XK_Udiaeresis", "Ü" }, - { KSYM_adiaeresis, "XK_adiaeresis", "ä" }, - { KSYM_odiaeresis, "XK_odiaeresis", "ö" }, - { KSYM_udiaeresis, "XK_udiaeresis", "ü" }, - { KSYM_ssharp, "XK_ssharp", "sharp s" }, - - /* end-of-array identifier */ - { 0, NULL, NULL } - }; - - int i; - - if (mode == TRANSLATE_KEYSYM_TO_KEYNAME) - { - static char name_buffer[30]; - Key key = *keysym; - - if (key >= KSYM_A && key <= KSYM_Z) - sprintf(name_buffer, "%c", 'A' + (char)(key - KSYM_A)); - else if (key >= KSYM_a && key <= KSYM_z) - sprintf(name_buffer, "%c", 'a' + (char)(key - KSYM_a)); - else if (key >= KSYM_0 && key <= KSYM_9) - sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0)); - else if (key >= KSYM_KP_0 && key <= KSYM_KP_9) - sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0)); - else if (key >= KSYM_F1 && key <= KSYM_F24) - sprintf(name_buffer, "function F%d", (int)(key - KSYM_F1 + 1)); - else if (key == KSYM_UNDEFINED) - strcpy(name_buffer, "(undefined)"); - else - { - i = 0; - - do - { - if (key == translate_key[i].key) - { - strcpy(name_buffer, translate_key[i].name); - break; - } - } - while (translate_key[++i].name); - - if (!translate_key[i].name) - strcpy(name_buffer, "(unknown)"); - } - - *name = name_buffer; - } - else if (mode == TRANSLATE_KEYSYM_TO_X11KEYNAME) - { - static char name_buffer[30]; - Key key = *keysym; - - if (key >= KSYM_A && key <= KSYM_Z) - sprintf(name_buffer, "XK_%c", 'A' + (char)(key - KSYM_A)); - else if (key >= KSYM_a && key <= KSYM_z) - sprintf(name_buffer, "XK_%c", 'a' + (char)(key - KSYM_a)); - else if (key >= KSYM_0 && key <= KSYM_9) - sprintf(name_buffer, "XK_%c", '0' + (char)(key - KSYM_0)); - else if (key >= KSYM_KP_0 && key <= KSYM_KP_9) - sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - KSYM_KP_0)); - else if (key >= KSYM_F1 && key <= KSYM_F24) - sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_F1 + 1)); - else if (key == KSYM_UNDEFINED) - strcpy(name_buffer, "[undefined]"); - else - { - i = 0; - - do - { - if (key == translate_key[i].key) - { - strcpy(name_buffer, translate_key[i].x11name); - break; - } - } - while (translate_key[++i].x11name); - - if (!translate_key[i].x11name) - sprintf(name_buffer, "0x%04lx", (unsigned long)key); - } - - *x11name = name_buffer; - } - else if (mode == TRANSLATE_X11KEYNAME_TO_KEYSYM) - { - Key key = KSYM_UNDEFINED; - char *name_ptr = *x11name; - - if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4) - { - char c = name_ptr[3]; - - if (c >= 'A' && c <= 'Z') - key = KSYM_A + (Key)(c - 'A'); - else if (c >= 'a' && c <= 'z') - key = KSYM_a + (Key)(c - 'a'); - else if (c >= '0' && c <= '9') - key = KSYM_0 + (Key)(c - '0'); - } - else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7) - { - char c = name_ptr[6]; - - if (c >= '0' && c <= '9') - key = KSYM_0 + (Key)(c - '0'); - } - else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6) - { - char c1 = name_ptr[4]; - char c2 = name_ptr[5]; - int d = 0; - - if ((c1 >= '0' && c1 <= '9') && - ((c2 >= '0' && c1 <= '9') || c2 == '\0')) - d = atoi(&name_ptr[4]); - - if (d >=1 && d <= 24) - key = KSYM_F1 + (Key)(d - 1); - } - else if (strncmp(name_ptr, "XK_", 3) == 0) - { - i = 0; - - do - { - if (strcmp(name_ptr, translate_key[i].x11name) == 0) - { - key = translate_key[i].key; - break; - } - } - while (translate_key[++i].x11name); - } - else if (strncmp(name_ptr, "0x", 2) == 0) - { - unsigned long value = 0; - - name_ptr += 2; - - while (name_ptr) - { - char c = *name_ptr++; - int d = -1; - - if (c >= '0' && c <= '9') - d = (int)(c - '0'); - else if (c >= 'a' && c <= 'f') - d = (int)(c - 'a' + 10); - else if (c >= 'A' && c <= 'F') - d = (int)(c - 'A' + 10); - - if (d == -1) - { - value = -1; - break; - } - - value = value * 16 + d; - } - - if (value != -1) - key = (Key)value; - } - - *keysym = key; - } -} - -char *getKeyNameFromKey(Key key) -{ - char *name; - - translate_keyname(&key, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME); - return name; -} - -char *getX11KeyNameFromKey(Key key) -{ - char *x11name; - - translate_keyname(&key, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME); - return x11name; -} - -Key getKeyFromX11KeyName(char *x11name) -{ - Key key; - - translate_keyname(&key, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM); - return key; -} - -char getCharFromKey(Key key) -{ - char *keyname = getKeyNameFromKey(key); - char letter = 0; - - if (strlen(keyname) == 1) - letter = keyname[0]; - else if (strcmp(keyname, "space") == 0) - letter = ' '; - else if (strcmp(keyname, "circumflex") == 0) - letter = '^'; - - return letter; -} - -#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0 -#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1 - -void translate_joyname(int *joysymbol, char **name, int mode) -{ - static struct - { - int joysymbol; - char *name; - } translate_joy[] = - { - { JOY_LEFT, "joystick_left" }, - { JOY_RIGHT, "joystick_right" }, - { JOY_UP, "joystick_up" }, - { JOY_DOWN, "joystick_down" }, - { JOY_BUTTON_1, "joystick_button_1" }, - { JOY_BUTTON_2, "joystick_button_2" }, - }; - - int i; - - if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME) - { - *name = "[undefined]"; - - for (i=0; i<6; i++) - { - if (*joysymbol == translate_joy[i].joysymbol) - { - *name = translate_joy[i].name; - break; - } - } - } - else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL) - { - *joysymbol = 0; - - for (i=0; i<6; i++) - { - if (strcmp(*name, translate_joy[i].name) == 0) - { - *joysymbol = translate_joy[i].joysymbol; - break; - } - } - } -} - -char *getJoyNameFromJoySymbol(int joysymbol) -{ - char *name; - - translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME); - return name; -} - -int getJoySymbolFromJoyName(char *name) -{ - int joysymbol; - - translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL); - return joysymbol; -} - -int getJoystickNrFromDeviceName(char *device_name) -{ - char c; - int joystick_nr = 0; - - if (device_name == NULL || device_name[0] == '\0') - return 0; - - c = device_name[strlen(device_name) - 1]; - - if (c >= '0' && c <= '9') - joystick_nr = (int)(c - '0'); - - if (joystick_nr < 0 || joystick_nr >= MAX_PLAYERS) - joystick_nr = 0; - - return joystick_nr; -} - -/* ------------------------------------------------------------------------- */ -/* some functions to handle lists of level directories */ -/* ------------------------------------------------------------------------- */ - -struct LevelDirInfo *newLevelDirInfo() -{ - return checked_calloc(sizeof(struct LevelDirInfo)); -} - -void pushLevelDirInfo(struct LevelDirInfo **node_first, - struct LevelDirInfo *node_new) -{ - node_new->next = *node_first; - *node_first = node_new; -} - -int numLevelDirInfo(struct LevelDirInfo *node) -{ - int num = 0; - - while (node) - { - num++; - node = node->next; - } - - return num; -} - -boolean validLevelSeries(struct LevelDirInfo *node) -{ - return (node != NULL && !node->node_group && !node->parent_link); -} - -struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node) -{ - if (node == NULL) - { - if (leveldir_first) /* start with first level directory entry */ - return getFirstValidLevelSeries(leveldir_first); - else - return NULL; - } - else if (node->node_group) /* enter level group (step down into tree) */ - return getFirstValidLevelSeries(node->node_group); - else if (node->parent_link) /* skip start entry of level group */ - { - if (node->next) /* get first real level series entry */ - return getFirstValidLevelSeries(node->next); - else /* leave empty level group and go on */ - return getFirstValidLevelSeries(node->node_parent->next); - } - else /* this seems to be a regular level series */ - return node; -} - -struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node) -{ - if (node == NULL) - return NULL; - - if (node->node_parent == NULL) /* top level group */ - return leveldir_first; - else /* sub level group */ - return node->node_parent->node_group; -} - -int numLevelDirInfoInGroup(struct LevelDirInfo *node) -{ - return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node)); -} - -int posLevelDirInfo(struct LevelDirInfo *node) -{ - struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node); - int pos = 0; - - while (node_cmp) - { - if (node_cmp == node) - return pos; - - pos++; - node_cmp = node_cmp->next; - } - - return 0; -} - -struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos) -{ - struct LevelDirInfo *node_default = node; - int pos_cmp = 0; - - while (node) - { - if (pos_cmp == pos) - return node; - - pos_cmp++; - node = node->next; - } - - return node_default; -} - -struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node, - char *filename) -{ - if (filename == NULL) - return NULL; - - while (node) - { - if (node->node_group) - { - struct LevelDirInfo *node_group; - - node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename); - - if (node_group) - return node_group; - } - else if (!node->parent_link) - { - if (strcmp(filename, node->filename) == 0) - return node; - } - - node = node->next; - } - - return NULL; -} - -struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename) -{ - return getLevelDirInfoFromFilenameExt(leveldir_first, filename); -} - -void dumpLevelDirInfo(struct LevelDirInfo *node, int depth) -{ - int i; - - while (node) - { - for (i=0; ifilename); - - if (node->node_group != NULL) - dumpLevelDirInfo(node->node_group, depth + 1); - - node = node->next; - } -} - -void sortLevelDirInfo(struct LevelDirInfo **node_first, - int (*compare_function)(const void *, const void *)) -{ - int num_nodes = numLevelDirInfo(*node_first); - struct LevelDirInfo **sort_array; - struct LevelDirInfo *node = *node_first; - int i = 0; - - if (num_nodes == 0) - return; - - /* allocate array for sorting structure pointers */ - sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *)); - - /* writing structure pointers to sorting array */ - while (i < num_nodes && node) /* double boundary check... */ - { - sort_array[i] = node; - - i++; - node = node->next; - } - - /* sorting the structure pointers in the sorting array */ - qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *), - compare_function); - - /* update the linkage of list elements with the sorted node array */ - for (i=0; inext = sort_array[i + 1]; - sort_array[num_nodes - 1]->next = NULL; - - /* update the linkage of the main list anchor pointer */ - *node_first = sort_array[0]; - - free(sort_array); - - /* now recursively sort the level group structures */ - node = *node_first; - while (node) - { - if (node->node_group != NULL) - sortLevelDirInfo(&node->node_group, compare_function); - - node = node->next; - } -} - -inline void swap_numbers(int *i1, int *i2) -{ - int help = *i1; - - *i1 = *i2; - *i2 = help; -} - -inline 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; -} - - -/* ------------------------------------------------------------------------- */ -/* the following is only for debugging purpose and normally not used */ -/* ------------------------------------------------------------------------- */ - -#define DEBUG_NUM_TIMESTAMPS 3 - -void debug_print_timestamp(int counter_nr, char *message) -{ - static long counter[DEBUG_NUM_TIMESTAMPS][2]; - - if (counter_nr >= DEBUG_NUM_TIMESTAMPS) - Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); - - counter[counter_nr][0] = Counter(); - - if (message) - printf("%s %.2f seconds\n", message, - (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); - - counter[counter_nr][1] = Counter(); -} diff --git a/src/misc.h b/src/misc.h deleted file mode 100644 index e376cd26..00000000 --- a/src/misc.h +++ /dev/null @@ -1,100 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* misc.h * -***********************************************************/ - -#ifndef MISC_H -#define MISC_H - -#include "main.h" - -/* values for InitCounter() and Counter() */ -#define INIT_COUNTER 0 -#define READ_COUNTER 1 - -/* values for InitRND() */ -#define NEW_RANDOMIZE -1 - -/* values for Error() */ -#define ERR_RETURN 0 -#define ERR_WARN (1 << 0) -#define ERR_EXIT (1 << 1) -#define ERR_HELP (1 << 2) -#define ERR_SOUND_SERVER (1 << 3) -#define ERR_NETWORK_SERVER (1 << 4) -#define ERR_NETWORK_CLIENT (1 << 5) -#define ERR_FROM_SERVER (ERR_SOUND_SERVER | ERR_NETWORK_SERVER) -#define ERR_EXIT_HELP (ERR_EXIT | ERR_HELP) -#define ERR_EXIT_SOUND_SERVER (ERR_EXIT | ERR_SOUND_SERVER) -#define ERR_EXIT_NETWORK_SERVER (ERR_EXIT | ERR_NETWORK_SERVER) -#define ERR_EXIT_NETWORK_CLIENT (ERR_EXIT | ERR_NETWORK_CLIENT) - -/* values for getFile...() and putFile...() */ -#define BYTE_ORDER_BIG_ENDIAN 0 -#define BYTE_ORDER_LITTLE_ENDIAN 1 - -void InitCounter(void); -unsigned long Counter(void); -void Delay(unsigned long); -boolean FrameReached(unsigned long *, unsigned long); -boolean DelayReached(unsigned long *, unsigned long); -void WaitUntilDelayReached(unsigned long *, unsigned long); -char *int2str(int, int); -unsigned int SimpleRND(unsigned int); -unsigned int RND(unsigned int); -unsigned int InitRND(long); -char *getLoginName(void); -char *getRealName(void); -char *getHomeDir(void); -char *getPath2(char *, char *); -char *getPath3(char *, char *, char*); -char *getStringCopy(char *); -char *getStringToLower(char *); -void MarkTileDirty(int, int); -void SetBorderElement(); -void GetOptions(char **); -void Error(int, char *, ...); -void *checked_malloc(unsigned long); -void *checked_calloc(unsigned long); -short getFile16BitInteger(FILE *, int); -void putFile16BitInteger(FILE *, short, int); -int getFile32BitInteger(FILE *, int); -void putFile32BitInteger(FILE *, int, int); -void getFileChunk(FILE *, char *, int *, int); -void putFileChunk(FILE *, char *, int, int); -char *getKeyNameFromKey(Key); -char *getX11KeyNameFromKey(Key); -Key getKeyFromX11KeyName(char *); -char getCharFromKey(Key); -char *getJoyNameFromJoySymbol(int); -int getJoySymbolFromJoyName(char *); -int getJoystickNrFromDeviceName(char *); - -struct LevelDirInfo *newLevelDirInfo(); -void pushLevelDirInfo(struct LevelDirInfo **, struct LevelDirInfo *); -int numLevelDirInfo(struct LevelDirInfo *); -boolean validLevelSeries(struct LevelDirInfo *); -struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *); -struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *); -int numLevelDirInfoInGroup(struct LevelDirInfo *); -int posLevelDirInfo(struct LevelDirInfo *); -struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *, int); -struct LevelDirInfo *getLevelDirInfoFromFilename(char *); -void dumpLevelDirInfo(struct LevelDirInfo *, int); -void sortLevelDirInfo(struct LevelDirInfo **, - int (*compare_function)(const void *, const void *)); - -inline void swap_numbers(int *, int *); -inline void swap_number_pairs(int *, int *, int *, int *); - -void debug_print_timestamp(int, char *); - -#endif /* MISC_H */ diff --git a/src/msdos.c b/src/msdos.c deleted file mode 100644 index 960609df..00000000 --- a/src/msdos.c +++ /dev/null @@ -1,938 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* msdos.c * -***********************************************************/ - -#include "platform.h" - -#if defined(PLATFORM_MSDOS) - -#include "main.h" -#include "misc.h" -#include "tools.h" -#include "sound.h" -#include "files.h" -#include "joystick.h" -#include "image.h" -#include "pcx.h" - -/* allegro driver declarations */ -DECLARE_GFX_DRIVER_LIST(GFX_DRIVER_VBEAF GFX_DRIVER_VESA2L GFX_DRIVER_VESA1) -DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8) -DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB) -DECLARE_MIDI_DRIVER_LIST() -DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD) - -/* allegro global variables */ -extern volatile int key_shifts; -extern int num_joysticks; -extern JOYSTICK_INFO joy[]; -extern int i_love_bill; - -/* internal variables of msdos.c */ -static boolean keyboard_auto_repeat = TRUE; -static int key_press_state[MAX_SCANCODES]; -static XEvent event_buffer[MAX_EVENT_BUFFER]; -static int pending_events; -static boolean joystick_event; -static boolean mouse_installed = FALSE; -static int last_mouse_pos; -static int last_mouse_b; -static int last_joystick_state; -static BITMAP* video_bitmap; - -static RGB global_colormap[MAX_COLORS]; -static int global_colormap_entries_used = 0; - -boolean wait_for_vsync; - -/* -extern int playing_sounds; -extern struct SoundControl playlist[MAX_SOUNDS_PLAYING]; -extern struct SoundControl emptySoundControl; -*/ - -static BITMAP *Read_PCX_to_AllegroBitmap(char *); - -static void allegro_init_drivers() -{ - int i; - - for (i=0; i 0) - mouse_installed = TRUE; - - last_joystick_state = 0; - joystick_event = FALSE; -} - -static boolean allegro_init_audio() -{ - reserve_voices(MAX_SOUNDS_PLAYING, 0); - - if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1) - if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) - return FALSE; - - return TRUE; -} - -static boolean hide_mouse(Display *display, int x, int y, - unsigned int width, unsigned int height) -{ - if (mouse_x + display->mouse_ptr->w < x || mouse_x > x + width) - return FALSE; - if (mouse_y + display->mouse_ptr->h < y || mouse_y > y + height) - return FALSE; - - show_mouse(NULL); - - return TRUE; -} - -static void unhide_mouse(Display *display) -{ - if (mouse_installed) - show_mouse(video_bitmap); -} - -static KeySym ScancodeToKeySym(byte scancode) -{ - switch(scancode) - { - case KEY_ESC: return XK_Escape; - case KEY_1: return XK_1; - case KEY_2: return XK_2; - case KEY_3: return XK_3; - case KEY_4: return XK_4; - case KEY_5: return XK_5; - case KEY_6: return XK_6; - case KEY_7: return XK_7; - case KEY_8: return XK_8; - case KEY_9: return XK_9; - case KEY_0: return XK_0; - case KEY_MINUS: return XK_minus; - case KEY_EQUALS: return XK_equal; - case KEY_BACKSPACE: return XK_BackSpace; - case KEY_TAB: return XK_Tab; - case KEY_Q: return XK_q; - case KEY_W: return XK_w; - case KEY_E: return XK_e; - case KEY_R: return XK_r; - case KEY_T: return XK_t; - case KEY_Y: return XK_y; - case KEY_U: return XK_u; - case KEY_I: return XK_i; - case KEY_O: return XK_o; - case KEY_P: return XK_p; - case KEY_OPENBRACE: return XK_braceleft; - case KEY_CLOSEBRACE: return XK_braceright; - case KEY_ENTER: return XK_Return; - case KEY_LCONTROL: return XK_Control_L; - case KEY_A: return XK_a; - case KEY_S: return XK_s; - case KEY_D: return XK_d; - case KEY_F: return XK_f; - case KEY_G: return XK_g; - case KEY_H: return XK_h; - case KEY_J: return XK_j; - case KEY_K: return XK_k; - case KEY_L: return XK_l; - case KEY_COLON: return XK_colon; - case KEY_QUOTE: return XK_apostrophe; - case KEY_TILDE: return XK_asciitilde; - case KEY_LSHIFT: return XK_Shift_L; - case KEY_BACKSLASH: return XK_backslash; - case KEY_Z: return XK_z; - case KEY_X: return XK_x; - case KEY_C: return XK_c; - case KEY_V: return XK_v; - case KEY_B: return XK_b; - case KEY_N: return XK_n; - case KEY_M: return XK_m; - case KEY_COMMA: return XK_comma; - case KEY_STOP: return XK_period; - case KEY_SLASH: return XK_slash; - case KEY_RSHIFT: return XK_Shift_R; - case KEY_ASTERISK: return XK_KP_Multiply; - case KEY_ALT: return XK_Alt_L; - case KEY_SPACE: return XK_space; - case KEY_CAPSLOCK: return XK_Caps_Lock; - case KEY_F1: return XK_F1; - case KEY_F2: return XK_F2; - case KEY_F3: return XK_F3; - case KEY_F4: return XK_F4; - case KEY_F5: return XK_F5; - case KEY_F6: return XK_F6; - case KEY_F7: return XK_F7; - case KEY_F8: return XK_F8; - case KEY_F9: return XK_F9; - case KEY_F10: return XK_F10; - case KEY_NUMLOCK: return XK_Num_Lock; - case KEY_SCRLOCK: return XK_Scroll_Lock; - case KEY_HOME: return XK_Home; - case KEY_UP: return XK_Up; - case KEY_PGUP: return XK_Page_Up; - case KEY_MINUS_PAD: return XK_KP_Subtract; - case KEY_LEFT: return XK_Left; - case KEY_5_PAD: return XK_KP_5; - case KEY_RIGHT: return XK_Right; - case KEY_PLUS_PAD: return XK_KP_Add; - case KEY_END: return XK_End; - case KEY_DOWN: return XK_Down; - case KEY_PGDN: return XK_Page_Down; - case KEY_INSERT: return XK_Insert; - case KEY_DEL: return XK_Delete; - case KEY_PRTSCR: return XK_Print; - case KEY_F11: return XK_F11; - case KEY_F12: return XK_F12; - case KEY_LWIN: return XK_Meta_L; - case KEY_RWIN: return XK_Meta_R; - case KEY_MENU: return XK_Menu; - case KEY_PAD: return XK_VoidSymbol; - case KEY_RCONTROL: return XK_Control_R; - case KEY_ALTGR: return XK_Alt_R; - case KEY_SLASH2: return XK_KP_Divide; - case KEY_PAUSE: return XK_Pause; - - case NEW_KEY_BACKSLASH: return XK_backslash; - case NEW_KEY_1_PAD: return XK_KP_1; - case NEW_KEY_2_PAD: return XK_KP_2; - case NEW_KEY_3_PAD: return XK_KP_3; - case NEW_KEY_4_PAD: return XK_KP_4; - case NEW_KEY_5_PAD: return XK_KP_5; - case NEW_KEY_6_PAD: return XK_KP_6; - case NEW_KEY_7_PAD: return XK_KP_7; - case NEW_KEY_8_PAD: return XK_KP_8; - case NEW_KEY_9_PAD: return XK_KP_9; - case NEW_KEY_0_PAD: return XK_KP_0; - case NEW_KEY_STOP_PAD: return XK_KP_Separator; - case NEW_KEY_EQUALS_PAD: return XK_KP_Equal; - case NEW_KEY_SLASH_PAD: return XK_KP_Divide; - case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply; - case NEW_KEY_ENTER_PAD: return XK_KP_Enter; - - default: return XK_VoidSymbol; - } -} - -void XMapWindow(Display *display, Window window) -{ - int x, y; - unsigned int width, height; - boolean mouse_off; - - x = display->screens[display->default_screen].x; - y = display->screens[display->default_screen].y; - width = display->screens[display->default_screen].width; - height = display->screens[display->default_screen].height; - - mouse_off = hide_mouse(display, x, y, width, height); - blit((BITMAP *)window, video_bitmap, 0, 0, x, y, width, height); - - if (mouse_off) - unhide_mouse(display); -} - -static unsigned long AllocColorCell(int r, int g, int b) -{ - byte pixel_mapping = 0; - int i; - - r >>= 10; - g >>= 10; - b >>= 10; - - /* try to use existing colors from the global colormap */ - for (i=0; idefault_screen = 0; - display->screens = screen; - display->mouse_ptr = mouse_bitmap; - - allegro_init(); - allegro_init_drivers(); - set_color_depth(8); - - /* force Windows 95 to switch to fullscreen mode */ - set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); - rest(200); - set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0); - - return display; -} - -Window XCreateSimpleWindow(Display *display, Window parent, int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, unsigned long border, - unsigned long background) -{ - video_bitmap = create_video_bitmap(XRES, YRES); - clear_to_color(video_bitmap, background); - - display->screens[display->default_screen].video_bitmap = video_bitmap; - display->screens[display->default_screen].x = x; - display->screens[display->default_screen].y = y; - display->screens[display->default_screen].width = XRES; - display->screens[display->default_screen].height = YRES; - - set_mouse_sprite(display->mouse_ptr); - -#if 0 - set_mouse_sprite_focus(1, 1); -#endif - - set_mouse_speed(1, 1); - set_mouse_range(display->screens[display->default_screen].x + 1, - display->screens[display->default_screen].y + 1, - display->screens[display->default_screen].x + WIN_XSIZE + 1, - display->screens[display->default_screen].y + WIN_YSIZE + 1); - - show_video_bitmap(video_bitmap); - - return (Window)video_bitmap; -} - -Status XStringListToTextProperty(char **list, int count, - XTextProperty *text_prop_return) -{ - char *string; - - if (count >= 1) - { - string = malloc(strlen(list[0] + 1)); - strcpy(string, list[0]); - text_prop_return->value = (unsigned char *)string; - return 1; - } - else - text_prop_return = NULL; - - return 0; -} - -void XFree(void *data) -{ - if (data) - free(data); -} - -GC XCreateGC(Display *display, Drawable d, unsigned long value_mask, - XGCValues *values) -{ - XGCValues *gcv; - gcv = malloc(sizeof(XGCValues)); - gcv->foreground = values->foreground; - gcv->background = values->background; - gcv->graphics_exposures = values->graphics_exposures; - gcv->clip_mask = values->clip_mask; - gcv->clip_x_origin = values->clip_x_origin; - gcv->clip_y_origin = values->clip_y_origin; - gcv->value_mask = value_mask; - return (GC)gcv; -} - -void XSetClipMask(Display *display, GC gc, Pixmap pixmap) -{ - XGCValues *gcv = (XGCValues *)gc; - - gcv->clip_mask = pixmap; - gcv->value_mask |= GCClipMask; -} - -void XSetClipOrigin(Display *display, GC gc, int x, int y) -{ - XGCValues *gcv = (XGCValues *)gc; - - gcv->clip_x_origin = x; - gcv->clip_x_origin = y; -} - -void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, - unsigned int width, unsigned int height) -{ - boolean mouse_off = FALSE; - - if ((BITMAP *)d == video_bitmap) - { - x += display->screens[display->default_screen].x; - y += display->screens[display->default_screen].y; - freeze_mouse_flag = TRUE; - mouse_off = hide_mouse(display, x, y, width, height); - } - - rectfill((BITMAP *)d, x, y, x + width - 1, y + height - 1, - ((XGCValues *)gc)->foreground); - - if (mouse_off) - unhide_mouse(display); - - freeze_mouse_flag = FALSE; -} - -Pixmap XCreatePixmap(Display *display, Drawable d, unsigned int width, - unsigned int height, unsigned int depth) -{ - BITMAP *bitmap = NULL; - - if (gfx_capabilities & GFX_HW_VRAM_BLIT && - width == FXSIZE && height == FYSIZE) - bitmap = create_video_bitmap(width, height); - - if (bitmap == NULL) - bitmap = create_bitmap(width, height); - - return (Pixmap)bitmap; -} - -void XSync(Display *display, Bool discard_events) -{ - wait_for_vsync = TRUE; -} - -inline void XCopyArea(Display *display, Drawable src, Drawable dest, GC gc, - int src_x, int src_y, - unsigned int width, unsigned int height, - int dest_x, int dest_y) -{ - boolean mouse_off = FALSE; - - if ((BITMAP *)src == video_bitmap) - { - src_x += display->screens[display->default_screen].x; - src_y += display->screens[display->default_screen].y; - } - - if ((BITMAP *)dest == video_bitmap) - { - dest_x += display->screens[display->default_screen].x; - dest_y += display->screens[display->default_screen].y; - freeze_mouse_flag = TRUE; - mouse_off = hide_mouse(display, dest_x, dest_y, width, height); - } - - if (wait_for_vsync) - { - wait_for_vsync = FALSE; - vsync(); - } - - if (((XGCValues *)gc)->value_mask & GCClipMask) - masked_blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y, - width, height); - else - blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y, - width, height); - - if (mouse_off) - unhide_mouse(display); - - freeze_mouse_flag = FALSE; -} - -static BITMAP *Image_to_AllegroBitmap(Image *image) -{ - BITMAP *bitmap; - byte *src_ptr = image->data; - byte pixel_mapping[MAX_COLORS]; - unsigned int depth = 8; - -#if 0 - int i, j, x, y; -#else - int i, x, y; -#endif - - /* allocate new allegro bitmap structure */ - if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL) - { - errno_pcx = PCX_NoMemory; - return NULL; - } - - clear(bitmap); - - /* try to use existing colors from the global colormap */ - for (i=0; irgb.color_used[i]) - continue; - - -#if 0 - r = image->rgb.red[i] >> 10; - g = image->rgb.green[i] >> 10; - b = image->rgb.blue[i] >> 10; - - for (j=0; jrgb.red[i], - image->rgb.green[i], - image->rgb.blue[i]); -#endif - - } - - /* copy bitmap data */ - for (y=0; yheight; y++) - for (x=0; xwidth; x++) - putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]); - - return bitmap; -} - -static BITMAP *Read_PCX_to_AllegroBitmap(char *filename) -{ - BITMAP *bitmap; - Image *image; - - /* read the graphic file in PCX format to internal image structure */ - if ((image = Read_PCX_to_Image(filename)) == NULL) - return NULL; - - /* convert internal image structure to allegro bitmap structure */ - if ((bitmap = Image_to_AllegroBitmap(image)) == NULL) - return NULL; - - set_palette(global_colormap); - - return bitmap; -} - -int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename, - Pixmap *pixmap, Pixmap *pixmap_mask) -{ - BITMAP *bitmap; - - if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) - return errno_pcx; - - *pixmap = (Pixmap)bitmap; - *pixmap_mask = (Pixmap)bitmap; - - return PCX_Success; -} - -int XReadBitmapFile(Display *display, Drawable d, char *filename, - unsigned int *width_return, unsigned int *height_return, - Pixmap *bitmap_return, - int *x_hot_return, int *y_hot_return) -{ - BITMAP *bitmap; - - if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) - return BitmapOpenFailed; - - *width_return = bitmap->w; - *height_return = bitmap->h; - *x_hot_return = -1; - *y_hot_return = -1; - *bitmap_return = (Pixmap)bitmap; - - return BitmapSuccess; -} - -void XFreePixmap(Display *display, Pixmap pixmap) -{ - if (pixmap != DUMMY_MASK && - (is_memory_bitmap((BITMAP *)pixmap) || - is_screen_bitmap((BITMAP *)pixmap))) - destroy_bitmap((BITMAP *)pixmap); -} - -void XFreeGC(Display *display, GC gc) -{ - XGCValues *gcv; - - gcv = (XGCValues *)gc; - if (gcv) - free(gcv); -} - -void XCloseDisplay(Display *display) -{ - BITMAP *bitmap = video_bitmap; - - if (is_screen_bitmap(bitmap)) - destroy_bitmap(bitmap); - - if (display->screens) - free(display->screens); - - if (display) - free(display); - - /* return to text mode (or DOS box on Windows screen) */ - set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); -} - -void XNextEvent(Display *display, XEvent *event_return) -{ - while (!pending_events) - XPending(display); - - memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent)); - pending_events--; -} - -static void NewKeyEvent(int key_press_state, KeySym keysym) -{ - XKeyEvent *xkey; - - if (pending_events >= MAX_EVENT_BUFFER) - return; - - pending_events++; - xkey = (XKeyEvent *)&event_buffer[pending_events]; - xkey->type = key_press_state; - xkey->state = (unsigned int)keysym; -} - -#define HANDLE_RAW_KB_ALL_KEYS 0 -#define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY 1 - -static int modifier_scancode[] = -{ - KEY_LSHIFT, - KEY_RSHIFT, - KEY_LCONTROL, - KEY_RCONTROL, - KEY_ALT, - KEY_ALTGR, - KEY_LWIN, - KEY_RWIN, - KEY_CAPSLOCK, - KEY_NUMLOCK, - KEY_SCRLOCK, - -1 -}; - -static void HandleKeyboardRaw(int mode) -{ - int i; - - for (i=0; i> 8); - int ascii = (key_info & 0xff); - KeySym keysym = ScancodeToKeySym(scancode); - - if (scancode == KEY_PAD) - { - /* keys on the numeric keypad return just scancode 'KEY_PAD' - for some reason, so we must handle them separately */ - - if (ascii >= '0' && ascii <= '9') - keysym = XK_KP_0 + (KeySym)(ascii - '0'); - else if (ascii == '.') - keysym = XK_KP_Separator; - } - else if (ascii >= ' ' && ascii <= 'Z') - keysym = XK_space + (KeySym)(ascii - ' '); - else if (ascii == '^') - keysym = XK_asciicircum; - else if (ascii == '_') - keysym = XK_underscore; - else if (ascii == 'Ä') - keysym = XK_Adiaeresis; - else if (ascii == 'Ö') - keysym = XK_Odiaeresis; - else if (ascii == 'Ü') - keysym = XK_Udiaeresis; - else if (ascii == 'ä') - keysym = XK_adiaeresis; - else if (ascii == 'ö') - keysym = XK_odiaeresis; - else if (ascii == 'ü') - keysym = XK_udiaeresis; - else if (ascii == 'ß') - keysym = XK_ssharp; - - NewKeyEvent(KeyPress, keysym); - } - else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)) - { - /* the allegro function keypressed() does not give us single pressed - modifier keys, so we must detect them with the internal global - allegro variable 'key_shifts' and then handle them separately */ - - HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY); - } -} - -int XPending(Display *display) -{ - XButtonEvent *xbutton; - XMotionEvent *xmotion; - int i; - - /* When using 'HandleKeyboardRaw()', keyboard input is also stored in - the allegro keyboard input buffer and would be available a second - time by calling 'HandleKeyboardEvent()'. To avoid double keyboard - events, the allegro function 'clear_keybuf()' must be called each - time when switching from calling 'HandleKeyboardRaw()' to calling - 'HandleKeyboardEvent()' to get keyboard input, which is actually - done by 'XAutoRepeatOn()' which sets keyboard_auto_repeat to TRUE. */ - - /* keyboard event */ - if (keyboard_auto_repeat) - HandleKeyboardEvent(); - else - HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS); - - /* mouse motion event */ - if (mouse_pos != last_mouse_pos) - { - last_mouse_pos = mouse_pos; - pending_events++; - xmotion = (XMotionEvent *)&event_buffer[pending_events]; - xmotion->type = MotionNotify; - xmotion->x = mouse_x - display->screens[display->default_screen].x; - xmotion->y = mouse_y - display->screens[display->default_screen].y; - } - - /* mouse button event */ - if (mouse_b != last_mouse_b) - { - for (i=0; i<3; i++) /* check all three mouse buttons */ - { - int bitmask = (1 << i); - - if ((last_mouse_b & bitmask) != (mouse_b & bitmask)) - { - int mapping[3] = { 1, 3, 2 }; - - pending_events++; - xbutton = (XButtonEvent *)&event_buffer[pending_events]; - xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease); - xbutton->button = mapping[i]; - xbutton->x = mouse_x - display->screens[display->default_screen].x; - xbutton->y = mouse_y - display->screens[display->default_screen].y; - } - } - last_mouse_b = mouse_b; - } - - return pending_events; -} - -KeySym XLookupKeysym(XKeyEvent *key_event, int index) -{ - return key_event->state; -} - -int XLookupString(XKeyEvent *key_event, char *buffer, int buffer_size, - KeySym *key, XComposeStatus *compose) -{ - *key = key_event->state; - return 0; -} - -void XSetForeground(Display *display, GC gc, unsigned long pixel) -{ - XGCValues *gcv = (XGCValues *)gc; - - gcv->foreground = pixel; -} - -void XDrawLine(Display *display, Drawable d, GC gc, - int x1, int y1, int x2, int y2) -{ - XGCValues *gcv = (XGCValues *)gc; - boolean mouse_off = FALSE; - - if ((BITMAP *)d == video_bitmap) - { - x1 += display->screens[display->default_screen].x; - y1 += display->screens[display->default_screen].y; - x2 += display->screens[display->default_screen].x; - y2 += display->screens[display->default_screen].y; - freeze_mouse_flag = TRUE; - mouse_off = hide_mouse(display, MIN(x1, x2), MIN(y1, y2), - MAX(x1, x2) - MIN(x1, x2), - MAX(y1, y2) - MIN(y1, y2)); - } - - line((BITMAP *)d, x1, y1, x2, y2, gcv->foreground); - - if (mouse_off) - unhide_mouse(display); - - freeze_mouse_flag = FALSE; -} - -void XDestroyImage(XImage *ximage) -{ -} - -Bool XQueryPointer(Display *display, Window window, - Window *root, Window *child, int *root_x, int *root_y, - int *win_x, int *win_y, unsigned int *mask) -{ - *win_x = mouse_x - display->screens[display->default_screen].x; - *win_y = mouse_y - display->screens[display->default_screen].y; - - return True; -} - -void XAutoRepeatOn(Display *display) -{ - keyboard_auto_repeat = TRUE; - clear_keybuf(); -} - -void XAutoRepeatOff(Display *display) -{ - keyboard_auto_repeat = FALSE; -} - -boolean MSDOSOpenAudio(void) -{ - return allegro_init_audio(); -} - -boolean MSDOSCloseAudio(void) -{ - /* nothing to be done here */ -} - -void NetworkServer(int port, int serveronly) -{ - Error(ERR_WARN, "networking not supported in DOS version"); -} - -#endif /* PLATFORM_MSDOS */ diff --git a/src/msdos.h b/src/msdos.h deleted file mode 100644 index 26a3f791..00000000 --- a/src/msdos.h +++ /dev/null @@ -1,712 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* msdos.h * -***********************************************************/ - -#ifndef MSDOS_H -#define MSDOS_H - -#include -#include - -/* symbol 'window' is defined in DJGPP cross-compiler in libc.a(conio.o) */ -#define window window_djgpp - -/* system dependent definitions */ - -#define TARGET_STRING "DOS" - -/* allegro defines TRUE as -1 */ -#ifdef TRUE -#undef TRUE -#undef FALSE -#endif - -#define TRUE 1 -#define FALSE 0 - -#define XRES 800 -#define YRES 600 - -/* additional Allegro keyboard mapping */ - -/* The following are all undefined in Allegro */ -#define NEW_KEY_BACKSLASH 86 -#define NEW_KEY_1_PAD 101 -#define NEW_KEY_2_PAD 102 -#define NEW_KEY_3_PAD 103 -#define NEW_KEY_4_PAD 104 -#define NEW_KEY_5_PAD 105 -#define NEW_KEY_6_PAD 106 -#define NEW_KEY_7_PAD 107 -#define NEW_KEY_8_PAD 108 -#define NEW_KEY_9_PAD 109 -#define NEW_KEY_0_PAD 110 -#define NEW_KEY_STOP_PAD 111 -#define NEW_KEY_EQUALS_PAD 112 -#define NEW_KEY_SLASH_PAD 113 -#define NEW_KEY_ASTERISK_PAD 114 -#define NEW_KEY_ENTER_PAD 115 - -/* X11 keyboard mapping (from 'keysymdef.h') */ - -#define XK_VoidSymbol 0xFFFFFF /* void symbol */ - -/* - * TTY Functions, cleverly chosen to map to ascii, for convenience of - * programming, but could have been arbitrary (at the cost of lookup - * tables in client code. - */ - -#define XK_BackSpace 0xFF08 /* back space, back char */ -#define XK_Tab 0xFF09 -#define XK_Linefeed 0xFF0A /* Linefeed, LF */ -#define XK_Clear 0xFF0B -#define XK_Return 0xFF0D /* Return, enter */ -#define XK_Pause 0xFF13 /* Pause, hold */ -#define XK_Scroll_Lock 0xFF14 -#define XK_Sys_Req 0xFF15 -#define XK_Escape 0xFF1B -#define XK_Delete 0xFFFF /* Delete, rubout */ - -/* International & multi-key character composition */ - -#define XK_Multi_key 0xFF20 /* Multi-key character compose */ -#define XK_SingleCandidate 0xFF3C -#define XK_MultipleCandidate 0xFF3D -#define XK_PreviousCandidate 0xFF3E - -/* Cursor control & motion */ - -#define XK_Home 0xFF50 -#define XK_Left 0xFF51 /* Move left, left arrow */ -#define XK_Up 0xFF52 /* Move up, up arrow */ -#define XK_Right 0xFF53 /* Move right, right arrow */ -#define XK_Down 0xFF54 /* Move down, down arrow */ -#define XK_Prior 0xFF55 /* Prior, previous */ -#define XK_Page_Up 0xFF55 -#define XK_Next 0xFF56 /* Next */ -#define XK_Page_Down 0xFF56 -#define XK_End 0xFF57 /* EOL */ -#define XK_Begin 0xFF58 /* BOL */ - -/* Misc Functions */ - -#define XK_Select 0xFF60 /* Select, mark */ -#define XK_Print 0xFF61 -#define XK_Execute 0xFF62 /* Execute, run, do */ -#define XK_Insert 0xFF63 /* Insert, insert here */ -#define XK_Undo 0xFF65 /* Undo, oops */ -#define XK_Redo 0xFF66 /* redo, again */ -#define XK_Menu 0xFF67 -#define XK_Find 0xFF68 /* Find, search */ -#define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ -#define XK_Help 0xFF6A /* Help */ -#define XK_Break 0xFF6B -#define XK_Mode_switch 0xFF7E /* Character set switch */ -#define XK_script_switch 0xFF7E /* Alias for mode_switch */ -#define XK_Num_Lock 0xFF7F - -/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ - -#define XK_KP_Space 0xFF80 /* space */ -#define XK_KP_Tab 0xFF89 -#define XK_KP_Enter 0xFF8D /* enter */ -#define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ -#define XK_KP_F2 0xFF92 -#define XK_KP_F3 0xFF93 -#define XK_KP_F4 0xFF94 -#define XK_KP_Home 0xFF95 -#define XK_KP_Left 0xFF96 -#define XK_KP_Up 0xFF97 -#define XK_KP_Right 0xFF98 -#define XK_KP_Down 0xFF99 -#define XK_KP_Prior 0xFF9A -#define XK_KP_Page_Up 0xFF9A -#define XK_KP_Next 0xFF9B -#define XK_KP_Page_Down 0xFF9B -#define XK_KP_End 0xFF9C -#define XK_KP_Begin 0xFF9D -#define XK_KP_Insert 0xFF9E -#define XK_KP_Delete 0xFF9F -#define XK_KP_Equal 0xFFBD /* equals */ -#define XK_KP_Multiply 0xFFAA -#define XK_KP_Add 0xFFAB -#define XK_KP_Separator 0xFFAC /* separator, often comma */ -#define XK_KP_Subtract 0xFFAD -#define XK_KP_Decimal 0xFFAE -#define XK_KP_Divide 0xFFAF - -#define XK_KP_0 0xFFB0 -#define XK_KP_1 0xFFB1 -#define XK_KP_2 0xFFB2 -#define XK_KP_3 0xFFB3 -#define XK_KP_4 0xFFB4 -#define XK_KP_5 0xFFB5 -#define XK_KP_6 0xFFB6 -#define XK_KP_7 0xFFB7 -#define XK_KP_8 0xFFB8 -#define XK_KP_9 0xFFB9 - -/* - * Auxilliary Functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufactures have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -#define XK_F1 0xFFBE -#define XK_F2 0xFFBF -#define XK_F3 0xFFC0 -#define XK_F4 0xFFC1 -#define XK_F5 0xFFC2 -#define XK_F6 0xFFC3 -#define XK_F7 0xFFC4 -#define XK_F8 0xFFC5 -#define XK_F9 0xFFC6 -#define XK_F10 0xFFC7 -#define XK_F11 0xFFC8 -#define XK_L1 0xFFC8 -#define XK_F12 0xFFC9 -#define XK_L2 0xFFC9 -#define XK_F13 0xFFCA -#define XK_L3 0xFFCA -#define XK_F14 0xFFCB -#define XK_L4 0xFFCB -#define XK_F15 0xFFCC -#define XK_L5 0xFFCC -#define XK_F16 0xFFCD -#define XK_L6 0xFFCD -#define XK_F17 0xFFCE -#define XK_L7 0xFFCE -#define XK_F18 0xFFCF -#define XK_L8 0xFFCF -#define XK_F19 0xFFD0 -#define XK_L9 0xFFD0 -#define XK_F20 0xFFD1 -#define XK_L10 0xFFD1 -#define XK_F21 0xFFD2 -#define XK_R1 0xFFD2 -#define XK_F22 0xFFD3 -#define XK_R2 0xFFD3 -#define XK_F23 0xFFD4 -#define XK_R3 0xFFD4 -#define XK_F24 0xFFD5 -#define XK_R4 0xFFD5 -#define XK_F25 0xFFD6 -#define XK_R5 0xFFD6 -#define XK_F26 0xFFD7 -#define XK_R6 0xFFD7 -#define XK_F27 0xFFD8 -#define XK_R7 0xFFD8 -#define XK_F28 0xFFD9 -#define XK_R8 0xFFD9 -#define XK_F29 0xFFDA -#define XK_R9 0xFFDA -#define XK_F30 0xFFDB -#define XK_R10 0xFFDB -#define XK_F31 0xFFDC -#define XK_R11 0xFFDC -#define XK_F32 0xFFDD -#define XK_R12 0xFFDD -#define XK_F33 0xFFDE -#define XK_R13 0xFFDE -#define XK_F34 0xFFDF -#define XK_R14 0xFFDF -#define XK_F35 0xFFE0 -#define XK_R15 0xFFE0 - -/* Modifiers */ - -#define XK_Shift_L 0xFFE1 /* Left shift */ -#define XK_Shift_R 0xFFE2 /* Right shift */ -#define XK_Control_L 0xFFE3 /* Left control */ -#define XK_Control_R 0xFFE4 /* Right control */ -#define XK_Caps_Lock 0xFFE5 /* Caps lock */ -#define XK_Shift_Lock 0xFFE6 /* Shift lock */ - -#define XK_Meta_L 0xFFE7 /* Left meta */ -#define XK_Meta_R 0xFFE8 /* Right meta */ -#define XK_Alt_L 0xFFE9 /* Left alt */ -#define XK_Alt_R 0xFFEA /* Right alt */ -#define XK_Super_L 0xFFEB /* Left super */ -#define XK_Super_R 0xFFEC /* Right super */ -#define XK_Hyper_L 0xFFED /* Left hyper */ -#define XK_Hyper_R 0xFFEE /* Right hyper */ - -/* - * Latin 1 - * Byte 3 = 0 - */ - -#define XK_space 0x020 -#define XK_exclam 0x021 -#define XK_quotedbl 0x022 -#define XK_numbersign 0x023 -#define XK_dollar 0x024 -#define XK_percent 0x025 -#define XK_ampersand 0x026 -#define XK_apostrophe 0x027 -#define XK_quoteright 0x027 /* deprecated */ -#define XK_parenleft 0x028 -#define XK_parenright 0x029 -#define XK_asterisk 0x02a -#define XK_plus 0x02b -#define XK_comma 0x02c -#define XK_minus 0x02d -#define XK_period 0x02e -#define XK_slash 0x02f -#define XK_0 0x030 -#define XK_1 0x031 -#define XK_2 0x032 -#define XK_3 0x033 -#define XK_4 0x034 -#define XK_5 0x035 -#define XK_6 0x036 -#define XK_7 0x037 -#define XK_8 0x038 -#define XK_9 0x039 -#define XK_colon 0x03a -#define XK_semicolon 0x03b -#define XK_less 0x03c -#define XK_equal 0x03d -#define XK_greater 0x03e -#define XK_question 0x03f -#define XK_at 0x040 -#define XK_A 0x041 -#define XK_B 0x042 -#define XK_C 0x043 -#define XK_D 0x044 -#define XK_E 0x045 -#define XK_F 0x046 -#define XK_G 0x047 -#define XK_H 0x048 -#define XK_I 0x049 -#define XK_J 0x04a -#define XK_K 0x04b -#define XK_L 0x04c -#define XK_M 0x04d -#define XK_N 0x04e -#define XK_O 0x04f -#define XK_P 0x050 -#define XK_Q 0x051 -#define XK_R 0x052 -#define XK_S 0x053 -#define XK_T 0x054 -#define XK_U 0x055 -#define XK_V 0x056 -#define XK_W 0x057 -#define XK_X 0x058 -#define XK_Y 0x059 -#define XK_Z 0x05a -#define XK_bracketleft 0x05b -#define XK_backslash 0x05c -#define XK_bracketright 0x05d -#define XK_asciicircum 0x05e -#define XK_underscore 0x05f -#define XK_grave 0x060 -#define XK_quoteleft 0x060 /* deprecated */ -#define XK_a 0x061 -#define XK_b 0x062 -#define XK_c 0x063 -#define XK_d 0x064 -#define XK_e 0x065 -#define XK_f 0x066 -#define XK_g 0x067 -#define XK_h 0x068 -#define XK_i 0x069 -#define XK_j 0x06a -#define XK_k 0x06b -#define XK_l 0x06c -#define XK_m 0x06d -#define XK_n 0x06e -#define XK_o 0x06f -#define XK_p 0x070 -#define XK_q 0x071 -#define XK_r 0x072 -#define XK_s 0x073 -#define XK_t 0x074 -#define XK_u 0x075 -#define XK_v 0x076 -#define XK_w 0x077 -#define XK_x 0x078 -#define XK_y 0x079 -#define XK_z 0x07a -#define XK_braceleft 0x07b -#define XK_bar 0x07c -#define XK_braceright 0x07d -#define XK_asciitilde 0x07e - -#define XK_nobreakspace 0x0a0 -#define XK_exclamdown 0x0a1 -#define XK_cent 0x0a2 -#define XK_sterling 0x0a3 -#define XK_currency 0x0a4 -#define XK_yen 0x0a5 -#define XK_brokenbar 0x0a6 -#define XK_section 0x0a7 -#define XK_diaeresis 0x0a8 -#define XK_copyright 0x0a9 -#define XK_ordfeminine 0x0aa -#define XK_guillemotleft 0x0ab /* left angle quotation mark */ -#define XK_notsign 0x0ac -#define XK_hyphen 0x0ad -#define XK_registered 0x0ae -#define XK_macron 0x0af -#define XK_degree 0x0b0 -#define XK_plusminus 0x0b1 -#define XK_twosuperior 0x0b2 -#define XK_threesuperior 0x0b3 -#define XK_acute 0x0b4 -#define XK_mu 0x0b5 -#define XK_paragraph 0x0b6 -#define XK_periodcentered 0x0b7 -#define XK_cedilla 0x0b8 -#define XK_onesuperior 0x0b9 -#define XK_masculine 0x0ba -#define XK_guillemotright 0x0bb /* right angle quotation mark */ -#define XK_onequarter 0x0bc -#define XK_onehalf 0x0bd -#define XK_threequarters 0x0be -#define XK_questiondown 0x0bf -#define XK_Agrave 0x0c0 -#define XK_Aacute 0x0c1 -#define XK_Acircumflex 0x0c2 -#define XK_Atilde 0x0c3 -#define XK_Adiaeresis 0x0c4 -#define XK_Aring 0x0c5 -#define XK_AE 0x0c6 -#define XK_Ccedilla 0x0c7 -#define XK_Egrave 0x0c8 -#define XK_Eacute 0x0c9 -#define XK_Ecircumflex 0x0ca -#define XK_Ediaeresis 0x0cb -#define XK_Igrave 0x0cc -#define XK_Iacute 0x0cd -#define XK_Icircumflex 0x0ce -#define XK_Idiaeresis 0x0cf -#define XK_ETH 0x0d0 -#define XK_Eth 0x0d0 /* deprecated */ -#define XK_Ntilde 0x0d1 -#define XK_Ograve 0x0d2 -#define XK_Oacute 0x0d3 -#define XK_Ocircumflex 0x0d4 -#define XK_Otilde 0x0d5 -#define XK_Odiaeresis 0x0d6 -#define XK_multiply 0x0d7 -#define XK_Ooblique 0x0d8 -#define XK_Ugrave 0x0d9 -#define XK_Uacute 0x0da -#define XK_Ucircumflex 0x0db -#define XK_Udiaeresis 0x0dc -#define XK_Yacute 0x0dd -#define XK_THORN 0x0de -#define XK_Thorn 0x0de /* deprecated */ -#define XK_ssharp 0x0df -#define XK_agrave 0x0e0 -#define XK_aacute 0x0e1 -#define XK_acircumflex 0x0e2 -#define XK_atilde 0x0e3 -#define XK_adiaeresis 0x0e4 -#define XK_aring 0x0e5 -#define XK_ae 0x0e6 -#define XK_ccedilla 0x0e7 -#define XK_egrave 0x0e8 -#define XK_eacute 0x0e9 -#define XK_ecircumflex 0x0ea -#define XK_ediaeresis 0x0eb -#define XK_igrave 0x0ec -#define XK_iacute 0x0ed -#define XK_icircumflex 0x0ee -#define XK_idiaeresis 0x0ef -#define XK_eth 0x0f0 -#define XK_ntilde 0x0f1 -#define XK_ograve 0x0f2 -#define XK_oacute 0x0f3 -#define XK_ocircumflex 0x0f4 -#define XK_otilde 0x0f5 -#define XK_odiaeresis 0x0f6 -#define XK_division 0x0f7 -#define XK_oslash 0x0f8 -#define XK_ugrave 0x0f9 -#define XK_uacute 0x0fa -#define XK_ucircumflex 0x0fb -#define XK_udiaeresis 0x0fc -#define XK_yacute 0x0fd -#define XK_thorn 0x0fe -#define XK_ydiaeresis 0x0ff - -/* end of X11 keyboard mapping */ - -#define MOUSE_FILENAME "mouse.pcx" -#define JOYSTICK_FILENAME "joystick.cnf" - -#define screen myscreen - -#define XFlush(a) -#define XGetImage(a,b,c,d,e,f,g,h) ((XImage *) NULL) -#define XDisplayName(a) ((char *) NULL) -#define XFreeColors(a,b,c,d,e) -#define XSelectInput(a,b,c) -#define XDefaultDepth(a,b) (8) -#define XSetWMProperties(a,b,c,d,e,f,g,h,i) - -#define MAX_EVENT_BUFFER 256 -#define MAX_SCANCODES 128 - -#define True 1 -#define False 0 -#define None 0L - -#define DUMMY_FILE ((void *) -1) -#define DUMMY_MASK (-1) - -#define KeyPressMask (1L << 0) -#define KeyReleaseMask (1L << 1) -#define ButtonPressMask (1L << 2) -#define ButtonReleaseMask (1L << 3) -#define ButtonMotionMask (1L << 13) -#define ExposureMask (1L << 15) -#define StructureNotifyMask (1L << 17) -#define FocusChangeMask (1L << 21) - -#define KeyPress 2 -#define KeyRelease 3 -#define ButtonPress 4 -#define ButtonRelease 5 -#define MotionNotify 6 -#define FocusIn 9 -#define FocusOut 10 -#define Expose 12 -#define UnmapNotify 18 -#define MapNotify 19 -#define ClientMessage 33 - -#define GCForeground (1L << 2) -#define GCBackground (1L << 3) -#define GCGraphicsExposures (1L << 16) -#define GCClipMask (1L << 19) - -#define NormalState 1 /* most applications want to start this way */ -#define InputHint (1L << 0) -#define StateHint (1L << 1) -#define IconPixmapHint (1L << 2) -#define IconMaskHint (1L << 5) -#define PSize (1L << 3) /* program specified size */ -#define PMinSize (1L << 4) /* program specified minimum size */ -#define PMaxSize (1L << 5) /* program specified maximum size */ - -#define PCX_Success 0 -#define PCX_OpenFailed -1 -#define PCX_ReadFailed -2 -#define PCX_FileInvalid -3 -#define PCX_NoMemory -4 -#define PCX_ColorFailed -5 - -#define BitmapSuccess 0 -#define BitmapOpenFailed 1 -#define BitmapFileInvalid 2 -#define BitmapNoMemory 3 - -#define ZPixmap 2 /* depth == drawable depth */ - -#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen) -#define DefaultColormap(dpy, scr) (ScreenOfDisplay(dpy,scr)->cmap) -#define ScreenOfDisplay(dpy, scr) (&((_XPrivDisplay)dpy)->screens[scr]) -#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel) -#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel) -#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root) -#define AllPlanes ((unsigned long)~0L) - -#define DefaultVisual(dpy, scr) (NULL) -#define DefaultDepth(dpy, scr) (NULL) -#define XDisplayWidth(dpy, scr) (XRES) -#define XDisplayHeight(dpy, scr) (YRES) - -#define XGetPixel(ximage, x, y) \ - ((*((ximage)->f.get_pixel))((ximage), (x), (y))) - -typedef unsigned long Pixel; /* Index into colormap */ -typedef unsigned long XID; -typedef XID Window; -typedef XID Drawable; -typedef XID Pixmap; -typedef XID Colormap; -typedef XID KeySym; -typedef XID GContext; -typedef struct _XDisplay Display; -typedef long Visual; -typedef long XVisualInfo; -typedef long Atom; -typedef int Status; -typedef int Bool; -typedef int XComposeStatus; /* we don't need the real type */ - -typedef struct _XGC -{ - GContext gid; /* protocol ID for graphics context */ -} *GC; - -typedef struct -{ - Colormap cmap; /* default color map */ - Window root; /* root window id */ - unsigned long white_pixel; /* white pixel value */ - unsigned long black_pixel; /* black pixel value */ - int x; - int y; - unsigned int width; - unsigned int height; - BITMAP *video_bitmap; -} Screen; - -typedef struct _XDisplay -{ - int default_screen; /* default screen for operations */ - Screen *screens; /* pointer to list of screens */ - BITMAP *mouse_ptr; -} *_XPrivDisplay; - -typedef struct _XImage -{ - struct funcs - { - unsigned long (*get_pixel) (struct _XImage *, int, int); - } f; -} XImage; - -typedef struct -{ - long flags; /* marks which fields in this structure are defined */ - int width, height; /* should set so old wm's don't mess up */ - int min_width, min_height; - int max_width, max_height; -} XSizeHints; - -typedef struct -{ - long flags; /* marks which fields in this structure are defined */ - Bool input; /* does this application rely on the window manager to - get keyboard input? */ - int initial_state; /* see below */ - Pixmap icon_pixmap; /* pixmap to be used as icon */ - Pixmap icon_mask; /* icon mask bitmap */ -} XWMHints; - -typedef struct -{ - char *res_name; - char *res_class; -} XClassHint; - -typedef struct -{ - unsigned char *value; /* same as Property routines */ -} XTextProperty; - -typedef struct -{ - unsigned long foreground; /* foreground pixel */ - unsigned long background; /* background pixel */ - Bool graphics_exposures; /* boolean, should exposures be generated */ - Pixmap clip_mask; /* bitmap clipping; other calls for rects */ - int clip_x_origin; /* x origin for clipping */ - int clip_y_origin; /* y origin for clipping */ - unsigned long value_mask; -} XGCValues; - -typedef struct -{ - int type; - int x, y; - int width, height; -} XExposeEvent; - -typedef struct -{ - int type; /* of event */ - int x, y; /* pointer x, y coordinates in event window */ - unsigned int button; /* detail */ -} XButtonEvent; - -typedef struct -{ - int type; - int x, y; /* pointer x, y coordinates in event window */ -} XMotionEvent; - -typedef struct -{ - int type; /* of event */ - unsigned int state; /* key or button mask */ -} XKeyEvent; - -typedef struct -{ - int type; /* FocusIn or FocusOut */ -} XFocusChangeEvent; - -typedef struct -{ - int type; /* ClientMessage */ -} XClientMessageEvent; - -typedef union _XEvent -{ - int type; /* must not be changed; first element */ - XExposeEvent xexpose; - XButtonEvent xbutton; - XMotionEvent xmotion; - XKeyEvent xkey; -} XEvent; - -void XMapWindow(Display *, Window); -Display *XOpenDisplay(char *); -Window XCreateSimpleWindow(Display *, Window, int, int, - unsigned int, unsigned int, unsigned int, - unsigned long, unsigned long); -Status XStringListToTextProperty(char **, int, XTextProperty *); -void XFree(void *); -GC XCreateGC(Display *, Drawable, unsigned long, XGCValues *); -void XSetClipMask(Display *, GC, Pixmap); -void XSetClipOrigin(Display *, GC, int, int); -void XFillRectangle(Display *, Drawable, GC, int, int, - unsigned int, unsigned int); -Pixmap XCreatePixmap(Display *, Drawable, unsigned int, unsigned int, - unsigned int); -void XSync(Display *, Bool); -inline void XCopyArea(Display *, Drawable, Drawable, GC, int, int, - unsigned int, unsigned int, int, int); -int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *); -int XReadBitmapFile(Display *, Drawable, char *, - unsigned int *, unsigned int *, Pixmap *, int *, int *); -void XFreePixmap(Display *, Pixmap); -void XFreeGC(Display *, GC); -void XCloseDisplay(Display *); -void XNextEvent(Display *, XEvent *); -int XPending(Display *); -KeySym XLookupKeysym(XKeyEvent *, int); -int XLookupString(XKeyEvent *, char *, int, KeySym *, XComposeStatus *); -void XSetForeground(Display *, GC, unsigned long); -void XDrawLine(Display *, Drawable, GC, int, int, int, int); -void XDestroyImage(XImage *); -Bool XQueryPointer(Display *, Window, Window *, Window *, int *, int *, - int *, int *, unsigned int *); -void XAutoRepeatOn(Display *); -void XAutoRepeatOff(Display *); - -boolean MSDOSOpenAudio(void); -boolean MSDOSCloseAudio(void); - -void NetworkServer(int, int); - -#endif /* MSDOS_H */ diff --git a/src/netserv.c b/src/netserv.c index 2e356e92..6a2479e5 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -11,7 +11,7 @@ * network.c * ***********************************************************/ -#include "platform.h" +#include "libgame/libgame.h" #if defined(PLATFORM_UNIX) @@ -26,8 +26,11 @@ #include #include +#if 0 +#include "libgame/libgame.h" +#endif + #include "netserv.h" -#include "misc.h" static int clients = 0; static int onceonly = 0; diff --git a/src/network.c b/src/network.c index e3a07c64..410695be 100644 --- a/src/network.c +++ b/src/network.c @@ -11,7 +11,7 @@ * network.c * ***********************************************************/ -#include "platform.h" +#include "libgame/libgame.h" #if defined(PLATFORM_UNIX) @@ -24,15 +24,17 @@ #include #include +#if 0 +#include "libgame/libgame.h" +#endif + #include "network.h" #include "netserv.h" #include "game.h" #include "tape.h" #include "files.h" #include "tools.h" -#include "buttons.h" #include "screens.h" -#include "misc.h" struct NetworkClientPlayerInfo { diff --git a/src/pcx.c b/src/pcx.c deleted file mode 100644 index b075940c..00000000 --- a/src/pcx.c +++ /dev/null @@ -1,265 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* pcx.c * -***********************************************************/ - -#ifndef TARGET_SDL - -#include "pcx.h" -#include "image.h" -#include "misc.h" - -#define PCX_DEBUG FALSE - -#define PCX_MAGIC 0x0a /* first byte in a PCX image file */ -#define PCX_LAST_VERSION 5 /* last acceptable version number */ -#define PCX_ENCODING 1 /* PCX encoding method */ -#define PCX_256COLORS_MAGIC 0x0c /* first byte of a PCX 256 color map */ -#define PCX_MAXDEPTH 8 /* supports up to 8 bits per pixel */ -#define PCX_MAXCOLORS 256 /* maximum number of colors */ - -#define PCX_HEADER_SIZE 128 -#define PCX_COLORMAP_SIZE (3 * PCX_MAXCOLORS) - -struct PCX_Header -{ - unsigned char signature; /* PCX file identifier */ - unsigned char version; /* version compatibility level */ - unsigned char encoding; /* encoding method */ - unsigned char bits_per_pixel; /* bits per pixel, or depth */ - unsigned short xmin; /* X position of left edge */ - unsigned short ymin; /* Y position of top edge */ - unsigned short xmax; /* X position of right edge */ - unsigned short ymax; /* Y position of bottom edge */ - unsigned short hres; /* X screen resolution of source image */ - unsigned short vres; /* Y screen resolution of source image */ - unsigned char palette[16][3]; /* PCX color map */ - unsigned char reserved; /* should be 0, 1 if std res fax */ - unsigned char color_planes; /* bit planes in image */ - unsigned short bytes_per_line;/* byte delta between scanlines */ - unsigned short palette_type; /* 0 = undef, 1 = color, 2 = grayscale */ - unsigned char filler[58]; /* fill to struct size of 128 */ -}; - -/* global PCX error value */ -int errno_pcx = PCX_Success; - -static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last) -{ - /* Run Length Encoding: If the two high bits are set, - * then the low 6 bits contain a repeat count, and the byte to - * repeat is the next byte in the file. If the two high bits are - * not set, then this is the byte to write. - */ - - unsigned int bytes_per_pixel = (image->depth + 7) / 8; - register byte *bitmap_ptr, *bitmap_last; - register byte value, count; - - bitmap_ptr = image->data; - bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel); - - while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last) - { - value = *buffer_ptr++; - - if ((value & 0xc0) == 0xc0) /* this is a repeat count byte */ - { - count = value & 0x3f; /* extract repeat count from byte */ - value = *buffer_ptr++; /* next byte is value to repeat */ - - for (; count && bitmap_ptr < bitmap_last; count--) - *bitmap_ptr++ = value; - - if (count) /* repeat count spans end of bitmap */ - return NULL; - } - else - *bitmap_ptr++ = value; - - image->rgb.color_used[value] = TRUE; - } - - /* check if end of buffer was reached before end of bitmap */ - if (bitmap_ptr < bitmap_last) - return NULL; - - /* return current buffer position for next decoding function */ - return buffer_ptr; -} - -static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last) -{ - int i, magic; - - /* read colormap magic byte */ - magic = *buffer_ptr++; - - /* check magic colormap header byte */ - if (magic != PCX_256COLORS_MAGIC) - return NULL; - - /* check if enough bytes left for a complete colormap */ - if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last) - return NULL; - - /* read 256 colors from PCX colormap */ - for (i=0; irgb.red[i] = *buffer_ptr++ << 8; - image->rgb.green[i] = *buffer_ptr++ << 8; - image->rgb.blue[i] = *buffer_ptr++ << 8; - } - - /* return current buffer position for next decoding function */ - return buffer_ptr; -} - -Image *Read_PCX_to_Image(char *filename) -{ - FILE *file; - byte *file_buffer; - byte *buffer_ptr, *buffer_last; - unsigned int file_length; - struct PCX_Header pcx; - Image *image; - int width, height, depth; - int i; - - errno_pcx = PCX_Success; - - if (!(file = fopen(filename, "r"))) - { - errno_pcx = PCX_OpenFailed; - return NULL; - } - - if (fseek(file, 0, SEEK_END) == -1) - { - fclose(file); - errno_pcx = PCX_ReadFailed; - return NULL; - } - - file_length = ftell(file); - rewind(file); - - if (file_length < PCX_HEADER_SIZE) - { - /* PCX file is too short to contain a valid PCX header */ - fclose(file); - - errno_pcx = PCX_FileInvalid; - return NULL; - } - - file_buffer = checked_malloc(file_length); - - if (fread(file_buffer, 1, file_length, file) != file_length) - { - fclose(file); - errno_pcx = PCX_ReadFailed; - return NULL; - } - - fclose(file); - - pcx.signature = file_buffer[0]; - pcx.version = file_buffer[1]; - pcx.encoding = file_buffer[2]; - pcx.bits_per_pixel = file_buffer[3]; - pcx.xmin = file_buffer[4] + 256 * file_buffer[5]; - pcx.ymin = file_buffer[6] + 256 * file_buffer[7]; - pcx.xmax = file_buffer[8] + 256 * file_buffer[9]; - pcx.ymax = file_buffer[10] + 256 * file_buffer[11]; - pcx.color_planes = file_buffer[65]; - pcx.bytes_per_line = file_buffer[66] + 256 * file_buffer[67]; - pcx.palette_type = file_buffer[68] + 256 * file_buffer[69]; - - width = pcx.xmax - pcx.xmin + 1; - height = pcx.ymax - pcx.ymin + 1; - depth = pcx.bits_per_pixel; - - if (pcx.signature != PCX_MAGIC || pcx.version > PCX_LAST_VERSION || - pcx.encoding != PCX_ENCODING || pcx.color_planes > PCX_MAXDEPTH || - width < 0 || height < 0) - { - free(file_buffer); - - errno_pcx = PCX_FileInvalid; - return NULL; - } - -#if PCX_DEBUG - if (options.verbose) - { - printf("%s is a %dx%d PC Paintbrush image with %d bitplanes\n", - filename, width, height, - pcx.color_planes); - printf("depth: %d\n", pcx.bits_per_pixel); - printf("color_planes: %d\n", pcx.color_planes); - printf("bytes_per_line: %d\n", pcx.bytes_per_line); - printf("palette type: %s\n", - (pcx.palette_type == 1 ? "color" : - pcx.palette_type == 2 ? "grayscale" : "undefined")); - } -#endif - - /* allocate new image structure */ - image = newImage(width, height, depth); - - buffer_ptr = file_buffer + PCX_HEADER_SIZE; - buffer_last = file_buffer + file_length; - - /* read compressed bitmap data */ - if ((buffer_ptr = PCX_ReadBitmap(image, buffer_ptr, buffer_last)) == NULL) - { - free(file_buffer); - freeImage(image); - - errno_pcx = PCX_FileInvalid; - return NULL; - } - - if (file_length < PCX_HEADER_SIZE + PCX_COLORMAP_SIZE) - { - /* PCX file is too short to contain a valid 256 colors colormap */ - fclose(file); - errno_pcx = PCX_ColorFailed; - return NULL; - } - - /* read colormap data */ - if (!PCX_ReadColormap(image, buffer_ptr, buffer_last)) - { - free(file_buffer); - freeImage(image); - errno_pcx = PCX_ColorFailed; - return NULL; - } - - free(file_buffer); - - /* determine number of used colormap entries */ - image->rgb.used = 0; - for (i=0; irgb.color_used[i]) - image->rgb.used++; - -#if PCX_DEBUG - if (options.verbose) - printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used); -#endif - - return image; -} - -#endif /* !TARGET_SDL */ diff --git a/src/pcx.h b/src/pcx.h deleted file mode 100644 index 47250992..00000000 --- a/src/pcx.h +++ /dev/null @@ -1,35 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* pcx.h * -***********************************************************/ - -#ifndef PCX_H -#define PCX_H - -#ifndef TARGET_SDL - -#include "main.h" -#include "image.h" - -#define PCX_Success 0 -#define PCX_OpenFailed -1 -#define PCX_ReadFailed -2 -#define PCX_FileInvalid -3 -#define PCX_NoMemory -4 -#define PCX_ColorFailed -5 - -/* global PCX error value */ -extern int errno_pcx; - -Image *Read_PCX_to_Image(char *); - -#endif /* !TARGET_SDL */ -#endif /* PCX_H */ diff --git a/src/platform.h b/src/platform.h deleted file mode 100644 index 02513071..00000000 --- a/src/platform.h +++ /dev/null @@ -1,47 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* platform.h * -***********************************************************/ - -#ifndef PLATFORM_H -#define PLATFORM_H - -/* define keywords for supported main platforms */ - -#if defined(MSDOS) -#define PLATFORM_MSDOS -#elif defined(WIN32) -#define PLATFORM_WIN32 -#else -#define PLATFORM_UNIX -#endif - -/* define additional keywords for several Unix platforms */ - -#if defined(linux) -#define PLATFORM_LINUX -#endif - -#if defined(__FreeBSD__) -#define PLATFORM_FREEBSD -#endif - -/* detecting HP-UX by the following compiler keyword definitions: - - in K&R mode (the default), the HP C compiler defines "hpux" - - in ANSI mode (-Aa or -Ae), the HP C compiler defines "__hpux" - - the gcc (Gnu) C compiler defines "__hpux__" - Thanks to Jarkko Hietaniemi for this note. */ - -#if defined(__hpux__) || defined(__hpux) || defined(hpux) -#define PLATFORM_HPUX -#endif - -#endif /* PLATFORM_H */ diff --git a/src/random.c b/src/random.c deleted file mode 100644 index 864f3dcc..00000000 --- a/src/random.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * This is derived from the Berkeley source: - * @(#)random.c 5.5 (Berkeley) 7/6/88 - * It was reworked for the GNU C Library by Roland McGrath. - */ - -#include -#include -#include - -#include "random.h" - - -/* An improved random number generation package. In addition to the standard - rand()/srand() like interface, this package also has a special state info - interface. The initstate() routine is called with a seed, an array of - bytes, and a count of how many bytes are being passed in; this array is - then initialized to contain information for random number generation with - that much state information. Good sizes for the amount of state - information are 32, 64, 128, and 256 bytes. The state can be switched by - calling the setstate() function with the same array as was initiallized - with initstate(). By default, the package runs with 128 bytes of state - information and generates far better random numbers than a linear - congruential generator. If the amount of state information is less than - 32 bytes, a simple linear congruential R.N.G. is used. Internally, the - state information is treated as an array of longs; the zeroeth element of - the array is the type of R.N.G. being used (small integer); the remainder - of the array is the state information for the R.N.G. Thus, 32 bytes of - state information will give 7 longs worth of state information, which will - allow a degree seven polynomial. (Note: The zeroeth word of state - information also has some other information stored in it; see setstate - for details). The random number generation technique is a linear feedback - shift register approach, employing trinomials (since there are fewer terms - to sum up that way). In this approach, the least significant bit of all - the numbers in the state table will act as a linear feedback shift register, - and will have period 2^deg - 1 (where deg is the degree of the polynomial - being used, assuming that the polynomial is irreducible and primitive). - The higher order bits will have longer periods, since their values are - also influenced by pseudo-random carries out of the lower bits. The - total period of the generator is approximately deg*(2**deg - 1); thus - doubling the amount of state information has a vast influence on the - period of the generator. Note: The deg*(2**deg - 1) is an approximation - only good for large deg, when the period of the shift register is the - dominant factor. With deg equal to seven, the period is actually much - longer than the 7*(2**7 - 1) predicted by this formula. */ - - - -/* For each of the currently supported random number generators, we have a - break value on the amount of state information (you need at least thi - bytes of state info to support this random number generator), a degree for - the polynomial (actually a trinomial) that the R.N.G. is based on, and - separation between the two lower order coefficients of the trinomial. */ - -/* Linear congruential. */ -#define TYPE_0 0 -#define BREAK_0 8 -#define DEG_0 0 -#define SEP_0 0 - -/* x**7 + x**3 + 1. */ -#define TYPE_1 1 -#define BREAK_1 32 -#define DEG_1 7 -#define SEP_1 3 - -/* x**15 + x + 1. */ -#define TYPE_2 2 -#define BREAK_2 64 -#define DEG_2 15 -#define SEP_2 1 - -/* x**31 + x**3 + 1. */ -#define TYPE_3 3 -#define BREAK_3 128 -#define DEG_3 31 -#define SEP_3 3 - -/* x**63 + x + 1. */ -#define TYPE_4 4 -#define BREAK_4 256 -#define DEG_4 63 -#define SEP_4 1 - - -/* Array versions of the above information to make code run faster. - Relies on fact that TYPE_i == i. */ - -#define MAX_TYPES 5 /* Max number of types above. */ - - - -/* Initially, everything is set up as if from: - initstate(1, randtbl, 128); - Note that this initialization takes advantage of the fact that srandom - advances the front and rear pointers 10*rand_deg times, and hence the - rear pointer which starts at 0 will also end up at zero; thus the zeroeth - element of the state information, which contains info about the current - position of the rear pointer is just - (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */ - -static long int randtbl[DEG_3 + 1] = -{ - TYPE_3, - -851904987, -43806228, -2029755270, 1390239686, -1912102820, - -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712, - -1714531963, 1800685987, -2015299881, 654595283, -1149023258, - -1470005550, -1143256056, -1325577603, -1568001885, 1275120390, - -607508183, -205999574, -1696891592, 1492211999, -1528267240, - -952028296, -189082757, 362343714, 1424981831, 2039449641, -}; - -/* FPTR and RPTR are two pointers into the state info, a front and a rear - pointer. These two pointers are always rand_sep places aparts, as they - cycle through the state information. (Yes, this does mean we could get - away with just one pointer, but the code for random is more efficient - this way). The pointers are left positioned as they would be from the call: - initstate(1, randtbl, 128); - (The position of the rear pointer, rptr, is really 0 (as explained above - in the initialization of randtbl) because the state table pointer is set - to point to randtbl[1] (as explained below).) */ - -static long int *fptr = &randtbl[SEP_3 + 1]; -static long int *rptr = &randtbl[1]; - - - -/* The following things are the pointer to the state information table, - the type of the current generator, the degree of the current polynomial - being used, and the separation between the two pointers. - Note that for efficiency of random, we remember the first location of - the state information, not the zeroeth. Hence it is valid to access - state[-1], which is used to store the type of the R.N.G. - Also, we remember the last location, since this is more efficient than - indexing every time to find the address of the last element to see if - the front and rear pointers have wrapped. */ - -static long int *state = &randtbl[1]; - -static int rand_type = TYPE_3; -static int rand_deg = DEG_3; -static int rand_sep = SEP_3; - -static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])]; - -/* Initialize the random number generator based on the given seed. If the - type is the trivial no-state-information type, just remember the seed. - Otherwise, initializes state[] based on the given "seed" via a linear - congruential generator. Then, the pointers are set to known locations - that are exactly rand_sep places apart. Lastly, it cycles the state - information a given number of times to get rid of any initial dependencies - introduced by the L.C.R.N.G. Note that the initialization of randtbl[] - for default usage relies on values produced by this routine. */ - -void srandom_linux_libc(unsigned int x) -{ - state[0] = x; - if (rand_type != TYPE_0) - { - register long int i; - for (i = 1; i < rand_deg; ++i) - state[i] = (1103515145 * state[i - 1]) + 12345; - fptr = &state[rand_sep]; - rptr = &state[0]; - for (i = 0; i < 10 * rand_deg; ++i) - (void) random_linux_libc(); - } -} - -/* If we are using the trivial TYPE_0 R.N.G., just do the old linear - congruential bit. Otherwise, we do our fancy trinomial stuff, which is the - same in all ther other cases due to all the global variables that have been - set up. The basic operation is to add the number at the rear pointer into - the one at the front pointer. Then both pointers are advanced to the next - location cyclically in the table. The value returned is the sum generated, - reduced to 31 bits by throwing away the "least random" low bit. - Note: The code takes advantage of the fact that both the front and - rear pointers can't wrap on the same call by not testing the rear - pointer if the front one has wrapped. Returns a 31-bit random number. */ - -long int random_linux_libc() -{ - if (rand_type == TYPE_0) - { - state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX; - return state[0]; - } - else - { - long int i; - *fptr += *rptr; - /* Chucking least random bit. */ - i = (*fptr >> 1) & LONG_MAX; - ++fptr; - if (fptr >= end_ptr) - { - fptr = state; - ++rptr; - } - else - { - ++rptr; - if (rptr >= end_ptr) - rptr = state; - } - return i; - } -} diff --git a/src/random.h b/src/random.h deleted file mode 100644 index 366d1ff5..00000000 --- a/src/random.h +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* random.h * -***********************************************************/ - -#ifndef RANDOM_H -#define RANDOM_H - -void srandom_linux_libc(unsigned int); -long int random_linux_libc(void); - -#endif diff --git a/src/screens.c b/src/screens.c index e4be1318..43027323 100644 --- a/src/screens.c +++ b/src/screens.c @@ -11,15 +11,14 @@ * screens.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "screens.h" #include "events.h" -#include "sound.h" #include "game.h" #include "tools.h" #include "editor.h" -#include "misc.h" #include "files.h" -#include "buttons.h" #include "tape.h" #include "joystick.h" #include "cartoons.h" @@ -85,7 +84,7 @@ void DrawMainMenu() UndrawSpecialEditorDoor(); /* needed if last screen was the setup screen and fullscreen state changed */ - ChangeVideoModeIfNeeded(); + setup.fullscreen = ChangeVideoModeIfNeeded(setup.fullscreen); #ifdef TARGET_SDL SetDrawtoField(DRAW_BACKBUFFER); #endif @@ -1500,7 +1499,7 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) setup.fading = !setup.fading; } #endif - else if (y == 8 && fullscreen_available) + else if (y == 8 && video.fullscreen_available) { if (setup.fullscreen) DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE); diff --git a/src/sdl.c b/src/sdl.c deleted file mode 100644 index 6e4b781b..00000000 --- a/src/sdl.c +++ /dev/null @@ -1,214 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* sdl.c * -***********************************************************/ - -#ifdef TARGET_SDL - -#include "main.h" -#include "misc.h" - -inline void SDLInitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) -{ - /* initialize SDL video */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) - Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); - - /* automatically cleanup SDL stuff after exit() */ - atexit(SDL_Quit); - - /* open SDL video output device (window or fullscreen mode) */ - if (!SDLSetVideoMode(backbuffer)) - Error(ERR_EXIT, "setting video mode failed"); - - /* set window and icon title */ - SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING); - - /* create additional buffer for double-buffering */ - pix[PIX_DB_BACK] = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); - - /* SDL cannot directly draw to the visible video framebuffer like X11, - but always uses a backbuffer, which is then blitted to the visible - video framebuffer with 'SDL_UpdateRect' (or replaced with the current - visible video framebuffer with 'SDL_Flip', if the hardware supports - this). Therefore do not use an additional backbuffer for drawing, but - use a symbolic buffer (distinguishable from the SDL backbuffer) called - 'window', which indicates that the SDL backbuffer should be updated to - the visible video framebuffer when attempting to blit to it. - - For convenience, it seems to be a good idea to create this symbolic - buffer 'window' at the same size as the SDL backbuffer. Although it - should never be drawn to directly, it would do no harm nevertheless. */ - - *window = pix[PIX_DB_BACK]; /* 'window' is only symbolic buffer */ - pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is SDL screen buffer */ -} - -inline boolean SDLSetVideoMode(DrawBuffer *backbuffer) -{ - boolean success = TRUE; - - if (setup.fullscreen && !fullscreen_enabled && fullscreen_available) - { - /* switch display to fullscreen mode, if available */ - DrawWindow window_old = *backbuffer; - DrawWindow window_new; - - if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, - SDL_HWSURFACE|SDL_FULLSCREEN)) - == NULL) - { - /* switching display to fullscreen mode failed */ - Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); - - /* do not try it again */ - fullscreen_available = FALSE; - success = FALSE; - } - else - { - if (window_old) - SDL_FreeSurface(window_old); - *backbuffer = window_new; - - fullscreen_enabled = TRUE; - success = TRUE; - } - } - - if ((!setup.fullscreen && fullscreen_enabled) || !*backbuffer) - { - /* switch display to window mode */ - DrawWindow window_old = *backbuffer; - DrawWindow window_new; - - if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, - SDL_HWSURFACE)) - == NULL) - { - /* switching display to window mode failed -- should not happen */ - Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); - - success = FALSE; - } - else - { - if (window_old) - SDL_FreeSurface(window_old); - *backbuffer = window_new; - - fullscreen_enabled = FALSE; - success = TRUE; - } - } - - return success; -} - -inline void SDLCopyArea(SDL_Surface *src_surface, SDL_Surface *dst_surface, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y) -{ - SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface); - SDL_Rect src_rect, dst_rect; - - src_rect.x = src_x; - src_rect.y = src_y; - src_rect.w = width; - src_rect.h = height; - - dst_rect.x = dst_x; - dst_rect.y = dst_y; - dst_rect.w = width; - dst_rect.h = height; - - if (src_surface != backbuffer || dst_surface != window) - SDL_BlitSurface(src_surface, &src_rect, surface, &dst_rect); - - if (dst_surface == window) - SDL_UpdateRect(backbuffer, dst_x, dst_y, width, height); -} - -inline void SDLFillRectangle(SDL_Surface *dst_surface, int x, int y, - int width, int height, unsigned int color) -{ - SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface); - SDL_Rect rect; - unsigned int color_r = (color >> 16) && 0xff; - unsigned int color_g = (color >> 8) && 0xff; - unsigned int color_b = (color >> 0) && 0xff; - - rect.x = x; - rect.y = y; - rect.w = width; - rect.h = height; - - SDL_FillRect(surface, &rect, - SDL_MapRGB(surface->format, color_r, color_g, color_b)); - - if (dst_surface == window) - SDL_UpdateRect(backbuffer, x, y, width, height); -} - -inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y, - int to_x, int to_y, unsigned int color) -{ - SDL_Rect rect; - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; - - if (from_x > to_x) - swap_numbers(&from_x, &to_x); - - if (from_y > to_y) - swap_numbers(&from_y, &to_y); - - rect.x = from_x; - rect.y = from_y; - rect.w = (to_x - from_x + 1); - rect.h = (to_y - from_y + 1); - - SDL_FillRect(surface, &rect, - SDL_MapRGB(surface->format, color_r, color_g, color_b)); -} - -inline boolean SDLOpenAudio(void) -{ - if (SDL_Init(SDL_INIT_AUDIO) < 0) - { - Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError()); - return FALSE; - } - - if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0) - { - Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError()); - return FALSE; - } - - Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4); - Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4); - - return TRUE; -} - -inline void SDLCloseAudio(void) -{ - Mix_HaltMusic(); - Mix_HaltChannel(-1); - - Mix_CloseAudio(); -} - -#endif /* TARGET_SDL */ diff --git a/src/sdl.h b/src/sdl.h deleted file mode 100644 index cd503c1d..00000000 --- a/src/sdl.h +++ /dev/null @@ -1,309 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* sdl.h * -***********************************************************/ - -#ifndef SDL_H -#define SDL_H - -#include "SDL.h" -#include "SDL_image.h" -#include "SDL_mixer.h" - - -/* definitions needed for "system.c" */ - -#define SURFACE_FLAGS (SDL_SWSURFACE) - - -/* system dependent definitions */ - -#define TARGET_STRING "SDL" -#define FULLSCREEN_STATUS FULLSCREEN_AVAILABLE - - -/* SDL type definitions */ - -typedef SDL_Surface *Bitmap; -typedef SDL_Surface *DrawWindow; -typedef SDL_Surface *DrawBuffer; - -typedef SDLKey Key; - -typedef SDL_Event Event; -typedef SDL_MouseButtonEvent ButtonEvent; -typedef SDL_MouseMotionEvent MotionEvent; -typedef SDL_KeyboardEvent KeyEvent; -typedef SDL_Event ExposeEvent; -typedef SDL_Event FocusChangeEvent; -typedef SDL_Event ClientMessageEvent; - -typedef int GC; -typedef int Pixmap; -typedef int Display; -typedef int Visual; -typedef int Colormap; - - -/* SDL symbol definitions */ - -#define None 0L - -#define EVENT_BUTTONPRESS SDL_MOUSEBUTTONDOWN -#define EVENT_BUTTONRELEASE SDL_MOUSEBUTTONUP -#define EVENT_MOTIONNOTIFY SDL_MOUSEMOTION -#define EVENT_KEYPRESS SDL_KEYDOWN -#define EVENT_KEYRELEASE SDL_KEYUP -#define EVENT_EXPOSE SDL_USEREVENT + 0 -#define EVENT_FOCUSIN SDL_USEREVENT + 1 -#define EVENT_FOCUSOUT SDL_USEREVENT + 2 -#define EVENT_CLIENTMESSAGE SDL_QUIT -#define EVENT_MAPNOTIFY SDL_USEREVENT + 4 -#define EVENT_UNMAPNOTIFY SDL_USEREVENT + 5 - -#define KSYM_UNDEFINED SDLK_UNKNOWN - -#define KSYM_Return SDLK_RETURN -#define KSYM_Escape SDLK_ESCAPE - -#define KSYM_Left SDLK_LEFT -#define KSYM_Right SDLK_RIGHT -#define KSYM_Up SDLK_UP -#define KSYM_Down SDLK_DOWN - -#ifdef SDLK_KP_LEFT -#define KSYM_KP_Left SDLK_KP_LEFT -#define KSYM_KP_Right SDLK_KP_RIGHT -#define KSYM_KP_Up SDLK_KP_UP -#define KSYM_KP_Down SDLK_KP_DOWN -#endif - -#define KSYM_KP_Enter SDLK_KP_ENTER -#define KSYM_KP_Add SDLK_KP_PLUS -#define KSYM_KP_Subtract SDLK_KP_MINUS -#define KSYM_KP_Multiply SDLK_KP_MULTIPLY -#define KSYM_KP_Divide SDLK_KP_DIVIDE -#define KSYM_KP_Separator SDLK_KP_PERIOD - -#define KSYM_Shift_L SDLK_LSHIFT -#define KSYM_Shift_R SDLK_RSHIFT -#define KSYM_Control_L SDLK_LCTRL -#define KSYM_Control_R SDLK_RCTRL -#define KSYM_Meta_L SDLK_LMETA -#define KSYM_Meta_R SDLK_RMETA -#define KSYM_Alt_L SDLK_LALT -#define KSYM_Alt_R SDLK_RALT -#define KSYM_Super_L SDLK_LSUPER -#define KSYM_Super_R SDLK_RSUPER -#define KSYM_Mode_switch SDLK_MODE -#define KSYM_Multi_key SDLK_RCTRL - -#define KSYM_BackSpace SDLK_BACKSPACE -#define KSYM_Delete SDLK_DELETE -#define KSYM_Insert SDLK_INSERT -#define KSYM_Tab SDLK_TAB -#define KSYM_Home SDLK_HOME -#define KSYM_End SDLK_END -#define KSYM_Page_Up SDLK_PAGEUP -#define KSYM_Page_Down SDLK_PAGEDOWN -#define KSYM_Menu SDLK_MENU - -#define KSYM_space SDLK_SPACE -#define KSYM_exclam SDLK_EXCLAIM -#define KSYM_quotedbl SDLK_QUOTEDBL -#define KSYM_numbersign SDLK_HASH -#define KSYM_dollar SDLK_DOLLAR -#define KSYM_percent KSYM_UNDEFINED /* undefined */ -#define KSYM_ampersand SDLK_AMPERSAND -#define KSYM_apostrophe SDLK_QUOTE -#define KSYM_parenleft SDLK_LEFTPAREN -#define KSYM_parenright SDLK_RIGHTPAREN -#define KSYM_asterisk SDLK_ASTERISK -#define KSYM_plus SDLK_PLUS -#define KSYM_comma SDLK_COMMA -#define KSYM_minus SDLK_MINUS -#define KSYM_period SDLK_PERIOD -#define KSYM_slash SDLK_SLASH - -#define KSYM_colon SDLK_COLON -#define KSYM_semicolon SDLK_SEMICOLON -#define KSYM_less SDLK_LESS -#define KSYM_equal SDLK_EQUALS -#define KSYM_greater SDLK_GREATER -#define KSYM_question SDLK_QUESTION -#define KSYM_at SDLK_AT - -#define KSYM_bracketleft SDLK_LEFTBRACKET -#define KSYM_backslash SDLK_BACKSLASH -#define KSYM_bracketright SDLK_RIGHTBRACKET -#define KSYM_asciicircum SDLK_CARET -#define KSYM_underscore SDLK_UNDERSCORE -#define KSYM_grave SDLK_BACKQUOTE - -#define KSYM_quoteleft KSYM_UNDEFINED /* undefined */ -#define KSYM_braceleft KSYM_UNDEFINED /* undefined */ -#define KSYM_bar KSYM_UNDEFINED /* undefined */ -#define KSYM_braceright KSYM_UNDEFINED /* undefined */ -#define KSYM_asciitilde KSYM_UNDEFINED /* undefined */ - -#define KSYM_Adiaeresis SDLK_WORLD_36 -#define KSYM_Odiaeresis SDLK_WORLD_54 -#define KSYM_Udiaeresis SDLK_WORLD_60 -#define KSYM_adiaeresis SDLK_WORLD_68 -#define KSYM_odiaeresis SDLK_WORLD_86 -#define KSYM_udiaeresis SDLK_WORLD_92 -#define KSYM_ssharp SDLK_WORLD_63 - -#ifndef SDLK_A -#define SDLK_A 65 -#define SDLK_B 66 -#define SDLK_C 67 -#define SDLK_D 68 -#define SDLK_E 69 -#define SDLK_F 70 -#define SDLK_G 71 -#define SDLK_H 72 -#define SDLK_I 73 -#define SDLK_J 74 -#define SDLK_K 75 -#define SDLK_L 76 -#define SDLK_M 77 -#define SDLK_N 78 -#define SDLK_O 79 -#define SDLK_P 80 -#define SDLK_Q 81 -#define SDLK_R 82 -#define SDLK_S 83 -#define SDLK_T 84 -#define SDLK_U 85 -#define SDLK_V 86 -#define SDLK_W 87 -#define SDLK_X 88 -#define SDLK_Y 89 -#define SDLK_Z 90 -#endif - -#define KSYM_A SDLK_A -#define KSYM_B SDLK_B -#define KSYM_C SDLK_C -#define KSYM_D SDLK_D -#define KSYM_E SDLK_E -#define KSYM_F SDLK_F -#define KSYM_G SDLK_G -#define KSYM_H SDLK_H -#define KSYM_I SDLK_I -#define KSYM_J SDLK_J -#define KSYM_K SDLK_K -#define KSYM_L SDLK_L -#define KSYM_M SDLK_M -#define KSYM_N SDLK_N -#define KSYM_O SDLK_O -#define KSYM_P SDLK_P -#define KSYM_Q SDLK_Q -#define KSYM_R SDLK_R -#define KSYM_S SDLK_S -#define KSYM_T SDLK_T -#define KSYM_U SDLK_U -#define KSYM_V SDLK_V -#define KSYM_W SDLK_W -#define KSYM_X SDLK_X -#define KSYM_Y SDLK_Y -#define KSYM_Z SDLK_Z - -#define KSYM_a SDLK_a -#define KSYM_b SDLK_b -#define KSYM_c SDLK_c -#define KSYM_d SDLK_d -#define KSYM_e SDLK_e -#define KSYM_f SDLK_f -#define KSYM_g SDLK_g -#define KSYM_h SDLK_h -#define KSYM_i SDLK_i -#define KSYM_j SDLK_j -#define KSYM_k SDLK_k -#define KSYM_l SDLK_l -#define KSYM_m SDLK_m -#define KSYM_n SDLK_n -#define KSYM_o SDLK_o -#define KSYM_p SDLK_p -#define KSYM_q SDLK_q -#define KSYM_r SDLK_r -#define KSYM_s SDLK_s -#define KSYM_t SDLK_t -#define KSYM_u SDLK_u -#define KSYM_v SDLK_v -#define KSYM_w SDLK_w -#define KSYM_x SDLK_x -#define KSYM_y SDLK_y -#define KSYM_z SDLK_z - -#define KSYM_0 SDLK_0 -#define KSYM_1 SDLK_1 -#define KSYM_2 SDLK_2 -#define KSYM_3 SDLK_3 -#define KSYM_4 SDLK_4 -#define KSYM_5 SDLK_5 -#define KSYM_6 SDLK_6 -#define KSYM_7 SDLK_7 -#define KSYM_8 SDLK_8 -#define KSYM_9 SDLK_9 - -#define KSYM_KP_0 SDLK_KP0 -#define KSYM_KP_1 SDLK_KP1 -#define KSYM_KP_2 SDLK_KP2 -#define KSYM_KP_3 SDLK_KP3 -#define KSYM_KP_4 SDLK_KP4 -#define KSYM_KP_5 SDLK_KP5 -#define KSYM_KP_6 SDLK_KP6 -#define KSYM_KP_7 SDLK_KP7 -#define KSYM_KP_8 SDLK_KP8 -#define KSYM_KP_9 SDLK_KP9 - -#define KSYM_F1 SDLK_F1 -#define KSYM_F2 SDLK_F2 -#define KSYM_F3 SDLK_F3 -#define KSYM_F4 SDLK_F4 -#define KSYM_F5 SDLK_F5 -#define KSYM_F6 SDLK_F6 -#define KSYM_F7 SDLK_F7 -#define KSYM_F8 SDLK_F8 -#define KSYM_F9 SDLK_F9 -#define KSYM_F10 SDLK_F10 -#define KSYM_F11 SDLK_F11 -#define KSYM_F12 SDLK_F12 -#define KSYM_F13 SDLK_F13 -#define KSYM_F14 SDLK_F14 -#define KSYM_F15 SDLK_F15 -#define KSYM_F16 KSYM_UNDEFINED -#define KSYM_F17 KSYM_UNDEFINED -#define KSYM_F18 KSYM_UNDEFINED -#define KSYM_F19 KSYM_UNDEFINED -#define KSYM_F20 KSYM_UNDEFINED -#define KSYM_F21 KSYM_UNDEFINED -#define KSYM_F22 KSYM_UNDEFINED -#define KSYM_F23 KSYM_UNDEFINED -#define KSYM_F24 KSYM_UNDEFINED - - -/* SDL function definitions */ - -inline void SDLInitBufferedDisplay(DrawBuffer *, DrawWindow *); -inline boolean SDLSetVideoMode(DrawBuffer *); -inline void SDLCopyArea(SDL_Surface *, SDL_Surface *, - int, int, int, int, int, int); -inline void SDLFillRectangle(SDL_Surface *, int, int, int, int, unsigned int); -inline void SDLDrawSimpleLine(SDL_Surface *, int, int, int, int, unsigned int); - -inline boolean SDLOpenAudio(void); -inline void SDLCloseAudio(void); - -#endif /* SDL_H */ diff --git a/src/sound.c b/src/sound.c deleted file mode 100644 index 91da5d7d..00000000 --- a/src/sound.c +++ /dev/null @@ -1,1027 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* sound.c * -***********************************************************/ - -#include "sound.h" -#include "misc.h" - -/*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/ - -static int playing_sounds = 0; -static struct SoundControl playlist[MAX_SOUNDS_PLAYING]; -static struct SoundControl emptySoundControl = -{ - -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL -}; - -#if defined(PLATFORM_UNIX) -static int stereo_volume[PSND_MAX_LEFT2RIGHT+1]; -static char premix_first_buffer[SND_BLOCKSIZE]; -#if defined(AUDIO_STREAMING_DSP) -static char premix_left_buffer[SND_BLOCKSIZE]; -static char premix_right_buffer[SND_BLOCKSIZE]; -static int premix_last_buffer[SND_BLOCKSIZE]; -#endif -static unsigned char playing_buffer[SND_BLOCKSIZE]; -#endif - -/* forward declaration of internal functions */ -#if defined(AUDIO_STREAMING_DSP) -static void SoundServer_InsertNewSound(struct SoundControl); -#elif defined(PLATFORM_UNIX) -static unsigned char linear_to_ulaw(int); -static int ulaw_to_linear(unsigned char); -#endif - -#if defined(PLATFORM_HPUX) -static void HPUX_Audio_Control(); -#endif - -#if defined(PLATFORM_MSDOS) -static void SoundServer_InsertNewSound(struct SoundControl); -static void SoundServer_StopSound(int); -static void SoundServer_StopAllSounds(); -#endif - -#if defined(PLATFORM_UNIX) -int OpenAudioDevice(char *audio_device_name) -{ - int audio_fd; - - /* check if desired audio device is accessible */ - if (access(sound_device_name, W_OK) != 0) - return -1; - - /* try to open audio device in non-blocking mode */ - if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0) - return audio_fd; - - /* re-open audio device in blocking mode */ - close(audio_fd); - audio_fd = open(audio_device_name, O_WRONLY); - - return audio_fd; -} - -void UnixOpenAudio(struct AudioSystemInfo *audio) -{ - static char *audio_device_name[] = - { - DEVICENAME_DSP, - DEVICENAME_AUDIO - }; - int audio_fd; - int i; - - /* look for available audio devices, starting with preferred ones */ - for (i=0; i= 0) - break; - - if (audio_fd < 0) - { - Error(ERR_WARN, "cannot open audio device - no sound"); - return; - } - - close(audio_fd); - - audio->sound_available = TRUE; - -#if defined(AUDIO_STREAMING_DSP) - audio->loops_available = TRUE; -#endif -} - -void UnixCloseAudio(struct AudioSystemInfo *audio) -{ - if (audio->device_fd) - close(audio->device_fd); -} - -#endif /* PLATFORM_UNIX */ - -void SoundServer() -{ - int i; -#if defined(PLATFORM_UNIX) - struct SoundControl snd_ctrl; - fd_set sound_fdset; - - close(audio.soundserver_pipe[1]); /* no writing into pipe needed */ -#endif - - for(i=0;i= 0) - { - if (!playing_sounds) /* we just opened the audio device */ - { - /* 2 buffers / 512 bytes, giving 1/16 second resolution */ - /* (with stereo the effective buffer size will shrink to 256) */ - fragment_size = 0x00020009; - - if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0) - Error(ERR_EXIT_SOUND_SERVER, - "cannot set fragment size of /dev/dsp - no sounds"); - - /* try if we can use stereo sound */ - if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0) - { -#ifdef DEBUG - static boolean reported = FALSE; - - if (!reported) - { - Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp"); - reported = TRUE; - } -#endif - stereo = FALSE; - } - - if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0) - Error(ERR_EXIT_SOUND_SERVER, - "cannot set sample rate of /dev/dsp - no sounds"); - - /* get the real fragmentation size; this should return 512 */ - if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0) - Error(ERR_EXIT_SOUND_SERVER, - "cannot get fragment size of /dev/dsp - no sounds"); - - max_sample_size = fragment_size / (stereo ? 2 : 1); - } - - if (snd_ctrl.active) /* new sound has arrived */ - SoundServer_InsertNewSound(snd_ctrl); - - while(playing_sounds && - select(audio.soundserver_pipe[0] + 1, - &sound_fdset, NULL, NULL, &delay) < 1) - { - FD_SET(audio.soundserver_pipe[0], &sound_fdset); - - /* first clear the last premixing buffer */ - memset(premix_last_buffer,0,fragment_size*sizeof(int)); - - for(i=0;i=PSND_MAX_VOLUME/10) - playlist[i].volume-=PSND_MAX_VOLUME/20; - - /* adjust volume of actual sound sample */ - if (playlist[i].volume != PSND_MAX_VOLUME) - for(j=0;j> PSND_MAX_VOLUME_BITS; - - /* fill the last mixing buffer with stereo or mono sound */ - if (stereo) - { - int middle_pos = PSND_MAX_LEFT2RIGHT/2; - int left_volume = stereo_volume[middle_pos+playlist[i].stereo]; - int right_volume = stereo_volume[middle_pos-playlist[i].stereo]; - - for(j=0;j> PSND_MAX_LEFT2RIGHT_BITS; - premix_right_buffer[j] = - (right_volume * (int)premix_first_buffer[j]) - >> PSND_MAX_LEFT2RIGHT_BITS; - premix_last_buffer[2*j+0] += premix_left_buffer[j]; - premix_last_buffer[2*j+1] += premix_right_buffer[j]; - } - } - else - { - for(j=0;j= playlist[i].data_len) - { - if (playlist[i].loop) - playlist[i].playingpos = 0; - else - { - playlist[i] = emptySoundControl; - playing_sounds--; - } - } - else if (playlist[i].volume <= PSND_MAX_VOLUME/10) - { - playlist[i] = emptySoundControl; - playing_sounds--; - } - } - - /* put last mixing buffer to final playing buffer */ - for(i=0;i255) - playing_buffer[i] = 255; - else - playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80; - } - - /* finally play the sound fragment */ - write(audio.device_fd, playing_buffer,fragment_size); - } - - /* if no sounds playing, free device for other sound programs */ - if (!playing_sounds) - close(audio.device_fd); - } - } - -#else /* !AUDIO_STREAMING_DSP */ - - if (snd_ctrl.active && !snd_ctrl.loop) - { - struct timeval delay = { 0, 0 }; - byte *sample_ptr; - long sample_size, max_sample_size = SND_BLOCKSIZE; - long sample_rate = 8000; /* standard "/dev/audio" sampling rate */ - int wait_percent = 90; /* wait 90% of the real playing time */ - int i; - - if ((audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0) - { - playing_sounds = 1; - - while(playing_sounds && - select(audio.soundserver_pipe[0] + 1, - &sound_fdset, NULL, NULL, &delay) < 1) - { - FD_SET(audio.soundserver_pipe[0], &sound_fdset); - - /* get pointer and size of the actual sound sample */ - sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos; - sample_size = - MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos); - snd_ctrl.playingpos += sample_size; - - /* fill the first mixing buffer with original sample */ - memcpy(premix_first_buffer,sample_ptr,sample_size); - - - /* adjust volume of actual sound sample */ - if (snd_ctrl.volume != PSND_MAX_VOLUME) - for(i=0;i> PSND_MAX_VOLUME_BITS; - - for(i=0;i= snd_ctrl.data_len) - playing_sounds = 0; - - /* finally play the sound fragment */ - write(audio.device_fd,playing_buffer,sample_size); - - delay.tv_sec = 0; - delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000; - } - close(audio.device_fd); - } - } - -#endif /* !AUDIO_STREAMING_DSP */ - - } - -#endif /* PLATFORM_UNIX */ - -} - -#if defined(PLATFORM_MSDOS) -static void sound_handler(struct SoundControl snd_ctrl) -{ - int i; - - if (snd_ctrl.fade_sound) - { - if (!playing_sounds) - return; - - for (i=0; ilongest) - { - longest=actual; - longest_nr=i; - } - } -#if defined(PLATFORM_MSDOS) - voice_set_volume(playlist[longest_nr].voice, 0); - deallocate_voice(playlist[longest_nr].voice); -#endif - playlist[longest_nr] = emptySoundControl; - playing_sounds--; - } - - /* check if sound is already being played (and how often) */ - for(k=0,i=0;i=1 && snd_ctrl.loop) - { - for(i=0;i=2) - { - int longest=0, longest_nr=0; - - /* look for oldest equal sound */ - for(i=0;i=longest) - { - longest=actual; - longest_nr=i; - } - } - -#if defined(PLATFORM_MSDOS) - voice_set_volume(playlist[longest_nr].voice, 0); - deallocate_voice(playlist[longest_nr].voice); -#endif - playlist[longest_nr] = emptySoundControl; - playing_sounds--; - } - - /* neuen Sound in Liste packen */ - for(i=0;i> 8) & 0x80; /* set aside the sign */ - if (sign != 0) - sample = -sample; /* get magnitude */ - if (sample > CLIP) - sample = CLIP; /* clip the magnitude */ - - /* Convert from 16 bit linear to ulaw. */ - sample = sample + BIAS; - exponent = exp_lut[( sample >> 7 ) & 0xFF]; - mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F; - ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa ); -#ifdef ZEROTRAP - if (ulawbyte == 0) - ulawbyte = 0x02; /* optional CCITT trap */ -#endif - - return(ulawbyte); -} - -/* -** This routine converts from ulaw to 16 bit linear. -** -** Craig Reese: IDA/Supercomputing Research Center -** 29 September 1989 -** -** References: -** 1) CCITT Recommendation G.711 (very difficult to follow) -** 2) MIL-STD-188-113,"Interoperability and Performance Standards -** for Analog-to_Digital Conversion Techniques," -** 17 February 1987 -** -** Input: 8 bit ulaw sample -** Output: signed 16 bit linear sample -*/ - -static int ulaw_to_linear(unsigned char ulawbyte) -{ - static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; - int sign, exponent, mantissa, sample; - - ulawbyte = ~ ulawbyte; - sign = ( ulawbyte & 0x80 ); - exponent = ( ulawbyte >> 4 ) & 0x07; - mantissa = ulawbyte & 0x0F; - sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) ); - if (sign != 0) - sample = -sample; - - return(sample); -} -#endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */ - -/*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/ - -/*===========================================================================*/ - -/*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/ - -#define CHUNK_ID_LEN 4 /* IFF style chunk id length */ -#define WAV_HEADER_SIZE 20 /* size of WAV file header */ - -boolean LoadSound(struct SampleInfo *snd_info) -{ - char filename[256]; - char *sound_ext = "wav"; -#if !defined(TARGET_SDL) -#if !defined(PLATFORM_MSDOS) - byte sound_header_buffer[WAV_HEADER_SIZE]; - char chunk[CHUNK_ID_LEN + 1]; - int chunk_length, dummy; - FILE *file; - int i; -#endif -#endif - - sprintf(filename, "%s/%s/%s.%s", - options.ro_base_directory, SOUNDS_DIRECTORY, - snd_info->name, sound_ext); - -#if defined(TARGET_SDL) - - snd_info->mix_chunk = Mix_LoadWAV(filename); - if (snd_info->mix_chunk == NULL) - { - Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); - return FALSE; - } - -#else /* !TARGET_SDL */ - -#if !defined(PLATFORM_MSDOS) - - if ((file = fopen(filename, "r")) == NULL) - { - Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename); - return FALSE; - } - - /* read chunk "RIFF" */ - getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN); - if (strcmp(chunk, "RIFF") != 0) - { - Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename); - fclose(file); - return FALSE; - } - - /* read chunk "WAVE" */ - getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN); - if (strcmp(chunk, "WAVE") != 0) - { - Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename); - fclose(file); - return FALSE; - } - - /* read header information */ - for (i=0; idata_len = chunk_length; - snd_info->data_ptr = checked_malloc(snd_info->data_len); - - /* read sound data */ - if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) != - snd_info->data_len) - { - Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); - fclose(file); - return FALSE; - } - - fclose(file); - - for (i=0; idata_len; i++) - snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80; - -#else /* PLATFORM_MSDOS */ - - snd_info->sample_ptr = load_sample(filename); - if (!snd_info->sample_ptr) - { - Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename); - return FALSE; - } - -#endif /* PLATFORM_MSDOS */ -#endif /* !TARGET_SDL */ - - return TRUE; -} - -void PlaySound(int nr) -{ - PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP); -} - -void PlaySoundStereo(int nr, int stereo) -{ - PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP); -} - -void PlaySoundLoop(int nr) -{ - PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP); -} - -void PlaySoundExt(int nr, int volume, int stereo, boolean loop) -{ - struct SoundControl snd_ctrl = emptySoundControl; - - if (!audio.sound_available || !setup.sound) - return; - - if (volumePSND_MAX_VOLUME) - volume = PSND_MAX_VOLUME; - - if (stereoPSND_MAX_RIGHT) - stereo = PSND_MAX_RIGHT; - - snd_ctrl.nr = nr; - snd_ctrl.volume = volume; - snd_ctrl.stereo = stereo; - snd_ctrl.loop = loop; - snd_ctrl.active = TRUE; - snd_ctrl.data_ptr = Sound[nr].data_ptr; - snd_ctrl.data_len = Sound[nr].data_len; - -#if defined(TARGET_SDL) - - Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4); - Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4); - - Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0)); - -#else -#if !defined(PLATFORM_MSDOS) - if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0) - { - Error(ERR_WARN, "cannot pipe to child process - no sounds"); - audio.sound_available = FALSE; - return; - } -#else - sound_handler(snd_ctrl); -#endif -#endif -} - -void FadeSound(int nr) -{ - StopSoundExt(nr, SSND_FADE_SOUND); -} - -void FadeSounds() -{ - StopSoundExt(-1, SSND_FADE_ALL_SOUNDS); -} - -void StopSound(int nr) -{ - StopSoundExt(nr, SSND_STOP_SOUND); -} - -void StopSounds() -{ - StopSoundExt(-1, SSND_STOP_ALL_SOUNDS); -} - -void StopSoundExt(int nr, int method) -{ - struct SoundControl snd_ctrl = emptySoundControl; - - if (!audio.sound_available) - return; - - if (SSND_FADING(method)) - snd_ctrl.fade_sound = TRUE; - - if (SSND_ALL(method)) - snd_ctrl.stop_all_sounds = TRUE; - else - { - snd_ctrl.nr = nr; - snd_ctrl.stop_sound = TRUE; - } - -#if defined(TARGET_SDL) - - if (SSND_FADING(method)) - { - Mix_FadeOutChannel(-1, 1000); - Mix_FadeOutMusic(1000); - } - else - { - Mix_HaltChannel(-1); - Mix_HaltMusic(); - } - -#else -#if !defined(PLATFORM_MSDOS) - if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0) - { - Error(ERR_WARN, "cannot pipe to child process - no sounds"); - audio.sound_available = FALSE; - return; - } -#else - sound_handler(snd_ctrl); -#endif -#endif -} - -void FreeSounds(int num_sounds) -{ - int i; - - if (!audio.sound_available) - return; - - for(i=0; i -#include - -#define SND_BLOCKSIZE 4096 - -#if defined(PLATFORM_LINUX) -#include -#elif defined(PLATFORM_FREEBSD) -#include -#elif defined(PLATFORM_HPUX) -#include -#undef SND_BLOCKSIZE -#define SND_BLOCKSIZE 32768 -#endif - -#include "main.h" - -#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) || defined(VOXWARE) -#define AUDIO_STREAMING_DSP -#endif - -#if !defined(PLATFORM_MSDOS) -#define MAX_SOUNDS_PLAYING 16 -#else -#define MAX_SOUNDS_PLAYING 8 -#endif - -/* some values for PlaySound(), StopSound() and friends */ -#if !defined(PLATFORM_MSDOS) -#define PSND_SILENCE 0 -#define PSND_MAX_VOLUME_BITS 7 -#define PSND_MIN_VOLUME 0 -#define PSND_MAX_VOLUME (1 << PSND_MAX_VOLUME_BITS) -#define PSND_NO_LOOP 0 -#define PSND_LOOP 1 -#define PSND_MIDDLE 0 -#define PSND_MAX_STEREO_BITS 7 -#define PSND_MAX_STEREO (1 << PSND_MAX_STEREO_BITS) -#define PSND_MAX_LEFT (-PSND_MAX_STEREO) -#define PSND_MAX_RIGHT (+PSND_MAX_STEREO) -#define PSND_MAX_LEFT2RIGHT_BITS (PSND_MAX_STEREO_BITS+1) -#define PSND_MAX_LEFT2RIGHT (1 << PSND_MAX_LEFT2RIGHT_BITS) -#else -#define PSND_SILENCE 0 -#define PSND_MIN_VOLUME 0 -#define PSND_MAX_VOLUME 255 -#define PSND_NO_LOOP 0 -#define PSND_LOOP 1 -#define PSND_MAX_LEFT 0 -#define PSND_MAX_RIGHT 255 -#define PSND_MIDDLE 128 -#endif - -#define SSND_FADE_SOUND (1<<0) -#define SSND_FADE_ALL_SOUNDS (1<<1) -#define SSND_FADING(x) (x & (SSND_FADE_SOUND | SSND_FADE_ALL_SOUNDS)) -#define SSND_STOP_SOUND (1<<2) -#define SSND_STOP_ALL_SOUNDS (1<<3) -#define SSND_STOPPING(x) (x & (SSND_STOP_SOUND | SSND_STOP_ALL_SOUNDS)) -#define SSND_ALL(x) (x&(SSND_FADE_ALL_SOUNDS|SSND_STOP_ALL_SOUNDS)) - -/* settings for sound path, sound device, etc. */ -#ifndef SND_PATH -#define SND_PATH "./sounds" -#endif - -#define DEVICENAME_DSP "/dev/dsp" -#define DEVICENAME_AUDIO "/dev/audio" -#define DEVICENAME_AUDIOCTL "/dev/audioCtl" - -#if defined(AUDIO_STREAMING_DSP) -#define AUDIO_DEVICE DEVICENAME_DSP -#else -#define AUDIO_DEVICE DEVICENAME_AUDIO -#endif - -struct SoundHeader_SUN -{ - unsigned long magic; - unsigned long hdr_size; - unsigned long data_size; - unsigned long encoding; - unsigned long sample_rate; - unsigned long channels; -}; - -struct SoundHeader_8SVX -{ - char magic_FORM[4]; - unsigned long chunk_size; - char magic_8SVX[4]; -}; - -struct SampleInfo -{ - char *name; - byte *data_ptr; - long data_len; - -#if defined(PLATFORM_MSDOS) - SAMPLE *sample_ptr; -#endif - -#if defined(TARGET_SDL) - Mix_Chunk *mix_chunk; -#endif -}; - -struct SoundControl -{ - int nr; - int volume; - int stereo; - boolean active; - boolean loop; - boolean fade_sound; - boolean stop_sound; - boolean stop_all_sounds; - int playingtime; - long playingpos; - long data_len; - byte *data_ptr; - -#if defined(PLATFORM_MSDOS) - int voice; -#endif -}; - -/* general sound functions */ -void UnixOpenAudio(struct AudioSystemInfo *); -void UnixCloseAudio(struct AudioSystemInfo *); - -/* sound server functions */ -void SoundServer(void); - -/* sound client functions */ -boolean LoadSound(struct SampleInfo *); -void PlaySound(int); -void PlaySoundStereo(int, int); -void PlaySoundLoop(int); -void PlaySoundExt(int, int, int, boolean); -void FadeSound(int); -void FadeSounds(void); -void StopSound(int); -void StopSounds(void); -void StopSoundExt(int, int); -void FreeSounds(int); - -#endif diff --git a/src/system.c b/src/system.c deleted file mode 100644 index 37ca4841..00000000 --- a/src/system.c +++ /dev/null @@ -1,359 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* system.c * -***********************************************************/ - -#include "main.h" -#include "misc.h" -#include "sound.h" - - -/* ========================================================================= */ -/* video functions */ -/* ========================================================================= */ - -inline void InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) -{ -#ifdef TARGET_SDL - SDLInitBufferedDisplay(backbuffer, window); -#else - X11InitBufferedDisplay(backbuffer, window); -#endif -} - -inline int GetDisplayDepth(void) -{ -#ifdef TARGET_SDL - return SDL_GetVideoSurface()->format->BitsPerPixel; -#else - return XDefaultDepth(display, screen); -#endif -} - -inline Bitmap CreateBitmap(int width, int height, int depth) -{ - int real_depth = (depth == DEFAULT_DEPTH ? GetDisplayDepth() : depth); - -#ifdef TARGET_SDL - SDL_Surface *surface_tmp, *surface_native; - - if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, - real_depth, 0, 0, 0, 0)) - == NULL) - Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError()); - - if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL) - Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError()); - - SDL_FreeSurface(surface_tmp); - - return surface_native; -#else - Pixmap pixmap; - - if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth))) - Error(ERR_EXIT, "cannot create pixmap"); - - return pixmap; -#endif -} - -inline void FreeBitmap(Bitmap bitmap) -{ -#ifdef TARGET_SDL - SDL_FreeSurface(bitmap); -#else - XFreePixmap(display, bitmap); -#endif -} - -inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height) -{ -#ifdef TARGET_SDL - SDLFillRectangle(bitmap, x, y, width, height, 0x000000); -#else - XFillRectangle(display, bitmap, gc, x, y, width, height); -#endif -} - -inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y) -{ -#ifdef TARGET_SDL - SDLCopyArea(src_bitmap, dst_bitmap, - src_x, src_y, width, height, dst_x, dst_y); -#else - XCopyArea(display, src_bitmap, dst_bitmap, gc, - src_x, src_y, width, height, dst_x, dst_y); -#endif -} - -#ifndef TARGET_SDL -static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */ -#endif - -inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap) -{ -#ifndef TARGET_SDL - XSetClipMask(display, clip_gc, clip_pixmap); - last_clip_gc = clip_gc; -#endif -} - -inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y) -{ -#ifndef TARGET_SDL - XSetClipOrigin(display, clip_gc, clip_x, clip_y); - last_clip_gc = clip_gc; -#endif -} - -inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y) -{ -#ifdef TARGET_SDL - SDLCopyArea(src_bitmap, dst_bitmap, - src_x, src_y, width, height, dst_x, dst_y); -#else - XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc, - src_x, src_y, width, height, dst_x, dst_y); -#endif -} - -inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y, - int to_x, int to_y) -{ -#ifdef TARGET_SDL - SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff); -#else - XSetForeground(display, gc, WhitePixel(display, screen)); - XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y); - XSetForeground(display, gc, BlackPixel(display, screen)); -#endif -} - -/* execute all pending screen drawing operations */ -inline void FlushDisplay(void) -{ -#ifndef TARGET_SDL - XFlush(display); -#endif -} - -/* execute and wait for all pending screen drawing operations */ -inline void SyncDisplay(void) -{ -#ifndef TARGET_SDL - XSync(display, FALSE); -#endif -} - -inline void KeyboardAutoRepeatOn(void) -{ -#ifdef TARGET_SDL - SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2, - SDL_DEFAULT_REPEAT_INTERVAL / 2); - SDL_EnableUNICODE(1); -#else - XAutoRepeatOn(display); -#endif -} - -inline void KeyboardAutoRepeatOff(void) -{ -#ifdef TARGET_SDL - SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL); - SDL_EnableUNICODE(0); -#else - XAutoRepeatOff(display); -#endif -} - -inline boolean PointerInWindow(DrawWindow window) -{ -#ifdef TARGET_SDL - return TRUE; -#else - DrawWindow root, child; - int root_x, root_y; - unsigned int mask; - int win_x, win_y; - - /* if XQueryPointer() returns False, the pointer - is not on the same screen as the specified window */ - return XQueryPointer(display, window, &root, &child, &root_x, &root_y, - &win_x, &win_y, &mask); -#endif -} - -inline boolean SetVideoMode(void) -{ -#ifdef TARGET_SDL - return SDLSetVideoMode(&backbuffer); -#else - boolean success = TRUE; - - if (setup.fullscreen && fullscreen_available) - { - Error(ERR_WARN, "fullscreen not available in X11 version"); - - /* display error message only once */ - fullscreen_available = FALSE; - - success = FALSE; - } - - return success; -#endif -} - -inline void ChangeVideoModeIfNeeded(void) -{ -#ifdef TARGET_SDL - if ((setup.fullscreen && !fullscreen_enabled && fullscreen_available) || - (!setup.fullscreen && fullscreen_enabled)) - SetVideoMode(); -#endif -} - - -/* ========================================================================= */ -/* audio functions */ -/* ========================================================================= */ - -inline boolean OpenAudio(struct AudioSystemInfo *audio) -{ - audio->sound_available = FALSE; - audio->loops_available = FALSE; - audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0; - audio->soundserver_pid = 0; - audio->device_fd = 0; - -#if defined(TARGET_SDL) - if (SDLOpenAudio()) - { - audio->sound_available = TRUE; - audio->loops_available = TRUE; - } -#elif defined(PLATFORM_MSDOS) - if (MSDOSOpenAudio()) - { - audio->sound_available = TRUE; - audio->loops_available = TRUE; - } -#elif defined(PLATFORM_UNIX) - UnixOpenAudio(audio); -#endif - - return audio->sound_available; -} - -inline void CloseAudio(struct AudioSystemInfo *audio) -{ -#if defined(TARGET_SDL) - SDLCloseAudio(); -#elif defined(PLATFORM_MSDOS) - MSDOSCloseAudio(); -#elif defined(PLATFORM_UNIX) - UnixCloseAudio(audio); -#endif - - audio->sound_available = FALSE; - audio->loops_available = FALSE; -} - - -/* ========================================================================= */ -/* event functions */ -/* ========================================================================= */ - -inline void InitEventFilter(EventFilter filter_function) -{ -#ifdef TARGET_SDL - /* set event filter to filter out certain events */ - SDL_SetEventFilter(filter_function); -#endif -} - -inline boolean PendingEvent(void) -{ -#ifdef TARGET_SDL - return (SDL_PollEvent(NULL) ? TRUE : FALSE); -#else - return (XPending(display) ? TRUE : FALSE); -#endif -} - -inline void NextEvent(Event *event) -{ -#ifdef TARGET_SDL - SDL_WaitEvent(event); -#else - XNextEvent(display, event); -#endif -} - -inline Key GetEventKey(KeyEvent *event, boolean with_modifiers) -{ -#ifdef TARGET_SDL -#if 0 - printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n", - (int)event->keysym.unicode, - (int)event->keysym.sym, - (int)SDL_GetModState()); -#endif - - if (with_modifiers && event->keysym.unicode != 0) - return event->keysym.unicode; - else - return event->keysym.sym; -#else -#if 0 - printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n", - (int)XLookupKeysym(event, event->state), - (int)XLookupKeysym(event, 0)); -#endif - - if (with_modifiers) - return XLookupKeysym(event, event->state); - else - return XLookupKeysym(event, 0); -#endif -} - -inline boolean CheckCloseWindowEvent(ClientMessageEvent *event) -{ - if (event->type != EVENT_CLIENTMESSAGE) - return FALSE; - -#if defined(TARGET_SDL) - return TRUE; /* the only possible message here is SDL_QUIT */ -#elif defined(PLATFORM_UNIX) - if ((event->window == window) && - (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE))) - return TRUE; -#endif - - return FALSE; -} - - -inline void dummy(void) -{ -#ifdef TARGET_SDL -#else -#endif -} diff --git a/src/system.h b/src/system.h deleted file mode 100644 index fdfb4a6a..00000000 --- a/src/system.h +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* system.h * -***********************************************************/ - -#ifndef SYSTEM_H -#define SYSTEM_H - -#include "platform.h" - -#if defined(PLATFORM_MSDOS) -#include "msdos.h" -#endif - -#if defined(TARGET_SDL) -#include "sdl.h" -#elif defined(TARGET_X11) -#include "x11.h" -#endif - - -/* contant definitions */ - -#define DEFAULT_DEPTH 0 - -#define FULLSCREEN_NOT_AVAILABLE FALSE -#define FULLSCREEN_AVAILABLE TRUE - - -/* type definitions */ - -typedef int (*EventFilter)(const Event *); - - -/* structure definitions */ - -struct AudioSystemInfo -{ - boolean sound_available; - boolean loops_available; - int soundserver_pipe[2]; - int soundserver_pid; - int device_fd; -}; - - -/* function definitions */ - -inline void InitBufferedDisplay(DrawBuffer *, DrawWindow *); -inline int GetDisplayDepth(void); -inline Bitmap CreateBitmap(int, int, int); -inline void FreeBitmap(Bitmap); -inline void ClearRectangle(Bitmap, int, int, int, int); -inline void BlitBitmap(Bitmap, Bitmap, int, int, int, int, int, int); -inline void SetClipMask(GC, Pixmap); -inline void SetClipOrigin(GC, int, int); -inline void BlitBitmapMasked(Bitmap, Bitmap, int, int, int, int, int, int); -inline void DrawSimpleWhiteLine(Bitmap, int, int, int, int); -inline void FlushDisplay(void); -inline void SyncDisplay(void); -inline void KeyboardAutoRepeatOn(void); -inline void KeyboardAutoRepeatOff(void); -inline boolean PointerInWindow(DrawWindow); -inline boolean SetVideoMode(void); -inline void ChangeVideoModeIfNeeded(void); - -inline boolean OpenAudio(struct AudioSystemInfo *); -inline void CloseAudio(struct AudioSystemInfo *); - -inline void InitEventFilter(EventFilter); -inline boolean PendingEvent(void); -inline void NextEvent(Event *event); -inline Key GetEventKey(KeyEvent *, boolean); -inline boolean CheckCloseWindowEvent(ClientMessageEvent *); - -#endif /* SYSTEM_H */ diff --git a/src/tape.c b/src/tape.c index 49fa39ae..7a5d5ff3 100644 --- a/src/tape.c +++ b/src/tape.c @@ -11,10 +11,10 @@ * tape.c * ***********************************************************/ +#include "libgame/libgame.h" + #include "tape.h" -#include "misc.h" #include "game.h" -#include "buttons.h" #include "tools.h" #include "files.h" #include "network.h" diff --git a/src/tools.c b/src/tools.c index 423ce49d..61e1bac1 100644 --- a/src/tools.c +++ b/src/tools.c @@ -13,16 +13,15 @@ #include -#ifdef __FreeBSD__ +#if defined(PLATFORM_FREEBSD) #include #endif +#include "libgame/libgame.h" + #include "tools.h" #include "game.h" #include "events.h" -#include "sound.h" -#include "misc.h" -#include "buttons.h" #include "joystick.h" #include "cartoons.h" #include "network.h" @@ -352,6 +351,8 @@ void ClearWindow() redraw_mask |= REDRAW_FIELD; } + +#if 0 int getFontWidth(int font_size, int font_type) { return (font_size == FS_BIG ? FONT1_XSIZE : @@ -489,6 +490,8 @@ void DrawTextExt(DrawBuffer d, GC gc, int x, int y, x += font_width; } } +#endif + void DrawAllPlayers() { @@ -2365,10 +2368,12 @@ static struct } }; +#if 0 static void DoNotDisplayInfoText(void *ptr) { return; } +#endif void CreateToolButtons() { @@ -2416,8 +2421,12 @@ void CreateToolButtons() GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY, GDI_DECORATION_SHIFTING, 1, 1, GDI_EVENT_MASK, event_mask, - GDI_CALLBACK_ACTION, HandleToolButtons, + +#if 0 GDI_CALLBACK_INFO, DoNotDisplayInfoText, +#endif + + GDI_CALLBACK_ACTION, HandleToolButtons, GDI_END); if (gi == NULL) diff --git a/src/tools.h b/src/tools.h index 0fc1f2da..721aa002 100644 --- a/src/tools.h +++ b/src/tools.h @@ -62,6 +62,8 @@ void SetDrawtoField(int); void BackToFront(); void FadeToFront(); void ClearWindow(); + +#if 0 int getFontWidth(int, int); int getFontHeight(int, int); void DrawInitText(char *, int, int); @@ -69,6 +71,8 @@ void DrawTextF(int, int, int, char *, ...); void DrawTextFCentered(int, int, char *, ...); void DrawText(int, int, char *, int, int); void DrawTextExt(DrawBuffer, GC, int, int, char *, int, int); +#endif + void DrawAllPlayers(void); void DrawPlayerField(int, int); void DrawPlayer(struct PlayerInfo *); @@ -116,4 +120,4 @@ void CreateToolButtons(); int el2gfx(int); -#endif +#endif /* TOOLS_H */ diff --git a/src/x11.c b/src/x11.c deleted file mode 100644 index 3c60b153..00000000 --- a/src/x11.c +++ /dev/null @@ -1,206 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* x11.c * -***********************************************************/ - -#if defined(TARGET_X11) - -#include "main.h" -#include "misc.h" - -struct IconFileInfo -{ - char *picture_filename; - char *picturemask_filename; -}; - -static void X11InitDisplay() -{ -#if !defined(PLATFORM_MSDOS) - XVisualInfo vinfo_template, *vinfo; - int num_visuals; -#endif - unsigned int depth; - - /* connect to X server */ - if (!(display = XOpenDisplay(options.display_name))) - Error(ERR_EXIT, "cannot connect to X server %s", - XDisplayName(options.display_name)); - - screen = DefaultScreen(display); - visual = DefaultVisual(display, screen); - depth = DefaultDepth(display, screen); - cmap = DefaultColormap(display, screen); - -#if !defined(PLATFORM_MSDOS) - /* look for good enough visual */ - vinfo_template.screen = screen; - vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor); - vinfo_template.depth = depth; - if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask | - VisualDepthMask, &vinfo_template, &num_visuals))) - { - visual = vinfo->visual; - XFree((void *)vinfo); - } - - /* got appropriate visual? */ - if (depth < 8) - { - printf("Sorry, displays with less than 8 bits per pixel not supported.\n"); - exit(-1); - } - else if ((depth ==8 && visual->class != PseudoColor) || - (depth > 8 && visual->class != TrueColor && - visual->class != DirectColor)) - { - printf("Sorry, cannot get appropriate visual.\n"); - exit(-1); - } -#endif /* !PLATFORM_MSDOS */ -} - -static DrawWindow X11InitWindow() -{ - Window window; - unsigned int border_width = 4; - XGCValues gc_values; - unsigned long gc_valuemask; -#if !defined(PLATFORM_MSDOS) - XTextProperty windowName, iconName; - Pixmap icon_pixmap, iconmask_pixmap; - unsigned int icon_width, icon_height; - int icon_hot_x, icon_hot_y; - char icon_filename[256]; - XSizeHints size_hints; - XWMHints wm_hints; - XClassHint class_hints; - char *window_name = WINDOW_TITLE_STRING; - char *icon_name = WINDOW_TITLE_STRING; - long window_event_mask; - Atom proto_atom = None, delete_atom = None; -#endif - int screen_width, screen_height; - int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS; - unsigned long pen_fg = WhitePixel(display,screen); - unsigned long pen_bg = BlackPixel(display,screen); - const int width = WIN_XSIZE, height = WIN_YSIZE; - -#if !defined(PLATFORM_MSDOS) - static struct IconFileInfo icon_pic = - { - "rocks_icon.xbm", - "rocks_iconmask.xbm" - }; -#endif - - screen_width = XDisplayWidth(display, screen); - screen_height = XDisplayHeight(display, screen); - - win_xpos = (screen_width - width) / 2; - win_ypos = (screen_height - height) / 2; - - window = XCreateSimpleWindow(display, RootWindow(display, screen), - win_xpos, win_ypos, width, height, border_width, - pen_fg, pen_bg); - -#if !defined(PLATFORM_MSDOS) - proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE); - delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE); - if ((proto_atom != None) && (delete_atom != None)) - XChangeProperty(display, window, proto_atom, XA_ATOM, 32, - PropModePrepend, (unsigned char *) &delete_atom, 1); - - sprintf(icon_filename, "%s/%s/%s", - options.ro_base_directory, GRAPHICS_DIRECTORY, - icon_pic.picture_filename); - XReadBitmapFile(display,window,icon_filename, - &icon_width,&icon_height, - &icon_pixmap,&icon_hot_x,&icon_hot_y); - if (!icon_pixmap) - Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); - - sprintf(icon_filename, "%s/%s/%s", - options.ro_base_directory, GRAPHICS_DIRECTORY, - icon_pic.picturemask_filename); - XReadBitmapFile(display,window,icon_filename, - &icon_width,&icon_height, - &iconmask_pixmap,&icon_hot_x,&icon_hot_y); - if (!iconmask_pixmap) - Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); - - size_hints.width = size_hints.min_width = size_hints.max_width = width; - size_hints.height = size_hints.min_height = size_hints.max_height = height; - size_hints.flags = PSize | PMinSize | PMaxSize; - - if (win_xpos || win_ypos) - { - size_hints.x = win_xpos; - size_hints.y = win_ypos; - size_hints.flags |= PPosition; - } - - if (!XStringListToTextProperty(&window_name, 1, &windowName)) - Error(ERR_EXIT, "structure allocation for windowName failed"); - - if (!XStringListToTextProperty(&icon_name, 1, &iconName)) - Error(ERR_EXIT, "structure allocation for iconName failed"); - - wm_hints.initial_state = NormalState; - wm_hints.input = True; - wm_hints.icon_pixmap = icon_pixmap; - wm_hints.icon_mask = iconmask_pixmap; - wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint; - - class_hints.res_name = program_name; - class_hints.res_class = "Rocks'n'Diamonds"; - - XSetWMProperties(display, window, &windowName, &iconName, - NULL, 0, &size_hints, &wm_hints, - &class_hints); - - XFree(windowName.value); - XFree(iconName.value); - - /* Select event types wanted */ - window_event_mask = - ExposureMask | StructureNotifyMask | FocusChangeMask | - ButtonPressMask | ButtonReleaseMask | PointerMotionMask | - PointerMotionHintMask | KeyPressMask | KeyReleaseMask; - - XSelectInput(display, window, window_event_mask); -#endif - - /* create GC for drawing with window depth and background color (black) */ - gc_values.graphics_exposures = False; - gc_values.foreground = pen_bg; - gc_values.background = pen_bg; - gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground; - gc = XCreateGC(display, window, gc_valuemask, &gc_values); - - return window; -} - -inline void X11InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) -{ - X11InitDisplay(); - *window = X11InitWindow(); - - XMapWindow(display, *window); - FlushDisplay(); - - /* create additional buffer for double-buffering */ - *backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); - pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is off-screen buffer */ -} - -#endif /* TARGET_X11 */ diff --git a/src/x11.h b/src/x11.h deleted file mode 100644 index ca1247c5..00000000 --- a/src/x11.h +++ /dev/null @@ -1,273 +0,0 @@ -/*********************************************************** -* 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 * -*----------------------------------------------------------* -* x11.h * -***********************************************************/ - -#ifndef X11_H -#define X11_H - -#if !defined(PLATFORM_MSDOS) -#define XK_MISCELLANY -#define XK_LATIN1 - -#include -#include -#include -#include -#include -#include -#endif - - -/* system dependent definitions */ - -/* MS-DOS header file also defines "TARGET_STRING" */ -#ifndef TARGET_STRING -#define TARGET_STRING "X11" -#endif - -#define FULLSCREEN_STATUS FULLSCREEN_NOT_AVAILABLE - - -/* X11 type definitions */ - -typedef Pixmap Bitmap; -typedef Window DrawWindow; -typedef Drawable DrawBuffer; - -typedef KeySym Key; - -typedef XEvent Event; -typedef XButtonEvent ButtonEvent; -typedef XMotionEvent MotionEvent; -typedef XKeyEvent KeyEvent; -typedef XExposeEvent ExposeEvent; -typedef XFocusChangeEvent FocusChangeEvent; -typedef XClientMessageEvent ClientMessageEvent; - - -/* X11 symbol definitions */ - -#define EVENT_BUTTONPRESS ButtonPress -#define EVENT_BUTTONRELEASE ButtonRelease -#define EVENT_MOTIONNOTIFY MotionNotify -#define EVENT_KEYPRESS KeyPress -#define EVENT_KEYRELEASE KeyRelease -#define EVENT_EXPOSE Expose -#define EVENT_FOCUSIN FocusIn -#define EVENT_FOCUSOUT FocusOut -#define EVENT_CLIENTMESSAGE ClientMessage -#define EVENT_MAPNOTIFY MapNotify -#define EVENT_UNMAPNOTIFY UnmapNotify - -#define KSYM_UNDEFINED XK_VoidSymbol - -#define KSYM_Return XK_Return -#define KSYM_Escape XK_Escape - -#define KSYM_Left XK_Left -#define KSYM_Right XK_Right -#define KSYM_Up XK_Up -#define KSYM_Down XK_Down - -#ifdef XK_KP_Left -#define KSYM_KP_Left XK_KP_Left -#define KSYM_KP_Right XK_KP_Right -#define KSYM_KP_Up XK_KP_Up -#define KSYM_KP_Down XK_KP_Down -#endif - -#ifdef XK_KP_Enter -#define KSYM_KP_Enter XK_KP_Enter -#define KSYM_KP_Add XK_KP_Add -#define KSYM_KP_Subtract XK_KP_Subtract -#define KSYM_KP_Multiply XK_KP_Multiply -#define KSYM_KP_Divide XK_KP_Divide -#define KSYM_KP_Separator XK_KP_Separator -#endif - -#define KSYM_Shift_L XK_Shift_L -#define KSYM_Shift_R XK_Shift_R -#define KSYM_Control_L XK_Control_L -#define KSYM_Control_R XK_Control_R -#define KSYM_Meta_L XK_Meta_L -#define KSYM_Meta_R XK_Meta_R -#define KSYM_Alt_L XK_Alt_L -#define KSYM_Alt_R XK_Alt_R -#define KSYM_Super_L XK_Super_L -#define KSYM_Super_R XK_Super_R -#define KSYM_Mode_switch XK_Mode_switch -#define KSYM_Multi_key XK_Multi_key - -#define KSYM_BackSpace XK_BackSpace -#define KSYM_Delete XK_Delete -#define KSYM_Insert XK_Insert -#define KSYM_Tab XK_Tab -#define KSYM_Home XK_Home -#define KSYM_End XK_End -#define KSYM_Page_Up XK_Page_Up -#define KSYM_Page_Down XK_Page_Down -#define KSYM_Menu XK_Menu - -#define KSYM_space XK_space -#define KSYM_exclam XK_exclam -#define KSYM_quotedbl XK_quotedbl -#define KSYM_numbersign XK_numbersign -#define KSYM_dollar XK_dollar -#define KSYM_percent XK_percent -#define KSYM_ampersand XK_ampersand -#define KSYM_apostrophe XK_apostrophe -#define KSYM_parenleft XK_parenleft -#define KSYM_parenright XK_parenright -#define KSYM_asterisk XK_asterisk -#define KSYM_plus XK_plus -#define KSYM_comma XK_comma -#define KSYM_minus XK_minus -#define KSYM_period XK_period -#define KSYM_slash XK_slash - -#define KSYM_colon XK_colon -#define KSYM_semicolon XK_semicolon -#define KSYM_less XK_less -#define KSYM_equal XK_equal -#define KSYM_greater XK_greater -#define KSYM_question XK_question -#define KSYM_at XK_at - -#define KSYM_bracketleft XK_bracketleft -#define KSYM_backslash XK_backslash -#define KSYM_bracketright XK_bracketright -#define KSYM_asciicircum XK_asciicircum -#define KSYM_underscore XK_underscore -#define KSYM_grave XK_grave - -#define KSYM_quoteleft XK_quoteleft -#define KSYM_braceleft XK_braceleft -#define KSYM_bar XK_bar -#define KSYM_braceright XK_braceright -#define KSYM_asciitilde XK_asciitilde - -#define KSYM_Adiaeresis XK_Adiaeresis -#define KSYM_Odiaeresis XK_Odiaeresis -#define KSYM_Udiaeresis XK_Udiaeresis -#define KSYM_adiaeresis XK_adiaeresis -#define KSYM_odiaeresis XK_odiaeresis -#define KSYM_udiaeresis XK_udiaeresis -#define KSYM_ssharp XK_ssharp - -#define KSYM_A XK_A -#define KSYM_B XK_B -#define KSYM_C XK_C -#define KSYM_D XK_D -#define KSYM_E XK_E -#define KSYM_F XK_F -#define KSYM_G XK_G -#define KSYM_H XK_H -#define KSYM_I XK_I -#define KSYM_J XK_J -#define KSYM_K XK_K -#define KSYM_L XK_L -#define KSYM_M XK_M -#define KSYM_N XK_N -#define KSYM_O XK_O -#define KSYM_P XK_P -#define KSYM_Q XK_Q -#define KSYM_R XK_R -#define KSYM_S XK_S -#define KSYM_T XK_T -#define KSYM_U XK_U -#define KSYM_V XK_V -#define KSYM_W XK_W -#define KSYM_X XK_X -#define KSYM_Y XK_Y -#define KSYM_Z XK_Z - -#define KSYM_a XK_a -#define KSYM_b XK_b -#define KSYM_c XK_c -#define KSYM_d XK_d -#define KSYM_e XK_e -#define KSYM_f XK_f -#define KSYM_g XK_g -#define KSYM_h XK_h -#define KSYM_i XK_i -#define KSYM_j XK_j -#define KSYM_k XK_k -#define KSYM_l XK_l -#define KSYM_m XK_m -#define KSYM_n XK_n -#define KSYM_o XK_o -#define KSYM_p XK_p -#define KSYM_q XK_q -#define KSYM_r XK_r -#define KSYM_s XK_s -#define KSYM_t XK_t -#define KSYM_u XK_u -#define KSYM_v XK_v -#define KSYM_w XK_w -#define KSYM_x XK_x -#define KSYM_y XK_y -#define KSYM_z XK_z - -#define KSYM_0 XK_0 -#define KSYM_1 XK_1 -#define KSYM_2 XK_2 -#define KSYM_3 XK_3 -#define KSYM_4 XK_4 -#define KSYM_5 XK_5 -#define KSYM_6 XK_6 -#define KSYM_7 XK_7 -#define KSYM_8 XK_8 -#define KSYM_9 XK_9 - -#define KSYM_KP_0 XK_KP_0 -#define KSYM_KP_1 XK_KP_1 -#define KSYM_KP_2 XK_KP_2 -#define KSYM_KP_3 XK_KP_3 -#define KSYM_KP_4 XK_KP_4 -#define KSYM_KP_5 XK_KP_5 -#define KSYM_KP_6 XK_KP_6 -#define KSYM_KP_7 XK_KP_7 -#define KSYM_KP_8 XK_KP_8 -#define KSYM_KP_9 XK_KP_9 - -#define KSYM_F1 XK_F1 -#define KSYM_F2 XK_F2 -#define KSYM_F3 XK_F3 -#define KSYM_F4 XK_F4 -#define KSYM_F5 XK_F5 -#define KSYM_F6 XK_F6 -#define KSYM_F7 XK_F7 -#define KSYM_F8 XK_F8 -#define KSYM_F9 XK_F9 -#define KSYM_F10 XK_F10 -#define KSYM_F11 XK_F11 -#define KSYM_F12 XK_F12 -#define KSYM_F13 XK_F13 -#define KSYM_F14 XK_F14 -#define KSYM_F15 XK_F15 -#define KSYM_F16 XK_F16 -#define KSYM_F17 XK_F17 -#define KSYM_F18 XK_F18 -#define KSYM_F19 XK_F19 -#define KSYM_F20 XK_F20 -#define KSYM_F21 XK_F21 -#define KSYM_F22 XK_F22 -#define KSYM_F23 XK_F23 -#define KSYM_F24 XK_F24 - - -/* X11 function definitions */ - -inline void X11InitBufferedDisplay(DrawBuffer *, DrawWindow *); - -#endif /* X11_H */