MAKE_CMD = $(MAKE) -C $(SRC_DIR)
all:
- @$(MAKE_CMD) TARGET=sdl
+ @$(MAKE_CMD) TARGET=x11
x11:
@$(MAKE_CMD) TARGET=x11
# (c) 1995-2000 Holger Schemel, info@artsoft.org #
#=============================================================================#
+.EXPORT_ALL_VARIABLES:
+
ifndef PLATFORM # platform not specified -- try auto detection
ifdef COMSPEC
PLATFORM = msdos
X11_LIBS = -L$(XLIB_PATH)
endif
+AR = ar
+RANLIB = ranlib
ifeq ($(PLATFORM),msdos) # MS-DOS native compiling
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
#-----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
depend:
+ $(MAKE) -C $(LIBDIR) depend
for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
ifeq (.depend,$(wildcard .depend))
+++ /dev/null
-/***********************************************************
-* 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 <stdarg.h>
-
-#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<<i))
- {
- int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
-
- if (i%2) /* i ungerade => 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; i<num_steps; i++)
- BlitBitmap(gd->bitmap, 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; i<num_steps; i++)
- BlitBitmap(gd->bitmap, 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;
- }
-}
+++ /dev/null
-/***********************************************************
-* 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
* cartoons.c *
***********************************************************/
+#include "libgame/libgame.h"
+
#include "cartoons.h"
#include "main.h"
-#include "misc.h"
#include "tools.h"
static void HandleAnimation(int);
#include <math.h>
+#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"
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 */
* 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 */
#include <dirent.h>
#include <sys/stat.h>
+#include "libgame/libgame.h"
+
#include "files.h"
#include "tools.h"
-#include "misc.h"
#include "tape.h"
#include "joystick.h"
* 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"
setup.sound_music = FALSE;
}
- if (!fullscreen_available)
+ if (!video.fullscreen_available)
setup.fullscreen = FALSE;
setup.sound_simple = setup.sound;
+++ /dev/null
-/***********************************************************
-* 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; i<MAX_COLORS; i++)
- image->rgb.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; y<image->height; y++)
- {
- bitmask = 0x01; /* start with leftmost bit in the byte */
- dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */
-
- for (x=0; x<image->width; 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; i<num_pixmap_formats; i++)
- if (pixmap_format[i].depth == depth)
- bits_per_pixel = pixmap_format[i].bits_per_pixel;
-
- XFree(pixmap_format);
-
- if (bits_per_pixel == -1)
- Error(ERR_EXIT, "cannot find pixmap format for depth %d", depth);
-
- return bits_per_pixel;
-}
-
-XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
- Window window, GC gc, int depth, Image *image)
-{
- static XColor xcolor_private[NOFLASH_COLORS];
- static int colorcell_used[NOFLASH_COLORS];
- static Colormap global_cmap = 0;
- static Pixel *global_cmap_index;
- static int num_cmap_entries, free_cmap_entries;
- static boolean private_cmap = FALSE;
- Pixel *redvalue, *greenvalue, *bluevalue;
- unsigned int a, c = 0, x, y, bytes_per_pixel, bits_per_pixel;
- XColor xcolor;
- XImage *ximage;
- XImageInfo *ximageinfo;
- byte *src_ptr, *dst_ptr;
-
- if (!global_cmap)
- {
- if (visual == DefaultVisual(display, screen))
- global_cmap = DefaultColormap(display, screen);
- else
- {
- global_cmap = XCreateColormap(display, RootWindow(display, screen),
- visual, AllocNone);
- private_cmap = TRUE;
- }
- }
-
- xcolor.flags = DoRed | DoGreen | DoBlue;
- redvalue = greenvalue = bluevalue = NULL;
- ximageinfo = checked_malloc(sizeof(XImageInfo));
- ximageinfo->display = 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; a<visual->map_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; a<MAX_COLORS; a++)
- {
- XColor xcolor2;
- unsigned short mask;
- int color_found;
- int i;
-
- if (!image->rgb.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<NOFLASH_COLORS; i++)
- if (!XAllocColorCells(display, global_cmap, FALSE, NULL, 0,
- global_cmap_index + i, 1))
- break;
- num_cmap_entries = free_cmap_entries = i;
-
- /*
- printf("We've got %d free colormap entries.\n", free_cmap_entries);
- */
-
- /* to minimize colormap flashing, copy default colors and try
- to keep them as near as possible to the old values */
-
- for(i=0; i<num_cmap_entries; i++)
- {
- xcolor2.pixel = *(global_cmap_index + i);
- XQueryColor(display, DefaultColormap(display, screen), &xcolor2);
- XStoreColor(display, global_cmap, &xcolor2);
- xcolor_private[xcolor2.pixel] = xcolor2;
- colorcell_used[xcolor2.pixel] = FALSE;
- }
-
- /* now we have the default colormap private: all colors we
- successfully allocated so far are read-only, which is okay,
- because we don't want to change them anymore -- if we need
- an existing color again, we get it by XAllocColor; all other
- colors are read/write and we can set them by XStoreColor,
- but we will try to overwrite those color cells with our new
- color which are as close as possible to our new color */
- }
-
- /* look for an existing default color close the one we want */
-
- mask = 0xf000;
- color_found = FALSE;
-
- while (!color_found)
- {
- for (i=num_cmap_entries-1; 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; y<image->height; y++) /* general case */
- {
- for (x=0; x<image->width; 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; y<image->height; y++)
- for (x=0; x<image->width; x++)
- *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
- }
- else /* general case */
- {
- for (y=0; y<image->height; y++)
- {
- for (x=0; x<image->width; 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 */
+++ /dev/null
-/***********************************************************
-* 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 */
#include <signal.h>
+#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"
#include "tools.h"
#include "files.h"
#include "joystick.h"
-#include "image.h"
-#include "pcx.h"
#include "network.h"
#include "netserv.h"
* joystick.c *
***********************************************************/
-#ifdef __FreeBSD__
+#if defined(PLATFORM_FREEBSD)
#include <machine/joystick.h>
#endif
+#include "libgame/libgame.h"
+
#include "joystick.h"
-#include "misc.h"
#if !defined(PLATFORM_MSDOS)
static int JoystickPosition(int middle, int margin, int actual)
--- /dev/null
+#=============================================================================#
+# 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
--- /dev/null
+/***********************************************************
+* 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 <stdarg.h>
+
+#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<<i))
+ {
+ int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
+
+ if (i%2) /* i ungerade => 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; i<num_steps; i++)
+ BlitBitmap(gd->bitmap, 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; i<num_steps; i++)
+ BlitBitmap(gd->bitmap, 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;
+ }
+}
--- /dev/null
+/***********************************************************
+* 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
--- /dev/null
+/***********************************************************
+* 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; i<MAX_COLORS; i++)
+ image->rgb.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; y<image->height; y++)
+ {
+ bitmask = 0x01; /* start with leftmost bit in the byte */
+ dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */
+
+ for (x=0; x<image->width; 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; i<num_pixmap_formats; i++)
+ if (pixmap_format[i].depth == depth)
+ bits_per_pixel = pixmap_format[i].bits_per_pixel;
+
+ XFree(pixmap_format);
+
+ if (bits_per_pixel == -1)
+ Error(ERR_EXIT, "cannot find pixmap format for depth %d", depth);
+
+ return bits_per_pixel;
+}
+
+XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
+ Window window, GC gc, int depth, Image *image)
+{
+ static XColor xcolor_private[NOFLASH_COLORS];
+ static int colorcell_used[NOFLASH_COLORS];
+ static Colormap global_cmap = 0;
+ static Pixel *global_cmap_index;
+ static int num_cmap_entries, free_cmap_entries;
+ static boolean private_cmap = FALSE;
+ Pixel *redvalue, *greenvalue, *bluevalue;
+ unsigned int a, c = 0, x, y, bytes_per_pixel, bits_per_pixel;
+ XColor xcolor;
+ XImage *ximage;
+ XImageInfo *ximageinfo;
+ byte *src_ptr, *dst_ptr;
+
+ if (!global_cmap)
+ {
+ if (visual == DefaultVisual(display, screen))
+ global_cmap = DefaultColormap(display, screen);
+ else
+ {
+ global_cmap = XCreateColormap(display, RootWindow(display, screen),
+ visual, AllocNone);
+ private_cmap = TRUE;
+ }
+ }
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ redvalue = greenvalue = bluevalue = NULL;
+ ximageinfo = checked_malloc(sizeof(XImageInfo));
+ ximageinfo->display = 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; a<visual->map_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; a<MAX_COLORS; a++)
+ {
+ XColor xcolor2;
+ unsigned short mask;
+ int color_found;
+ int i;
+
+ if (!image->rgb.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<NOFLASH_COLORS; i++)
+ if (!XAllocColorCells(display, global_cmap, FALSE, NULL, 0,
+ global_cmap_index + i, 1))
+ break;
+ num_cmap_entries = free_cmap_entries = i;
+
+ /*
+ printf("We've got %d free colormap entries.\n", free_cmap_entries);
+ */
+
+ /* to minimize colormap flashing, copy default colors and try
+ to keep them as near as possible to the old values */
+
+ for(i=0; i<num_cmap_entries; i++)
+ {
+ xcolor2.pixel = *(global_cmap_index + i);
+ XQueryColor(display, DefaultColormap(display, screen), &xcolor2);
+ XStoreColor(display, global_cmap, &xcolor2);
+ xcolor_private[xcolor2.pixel] = xcolor2;
+ colorcell_used[xcolor2.pixel] = FALSE;
+ }
+
+ /* now we have the default colormap private: all colors we
+ successfully allocated so far are read-only, which is okay,
+ because we don't want to change them anymore -- if we need
+ an existing color again, we get it by XAllocColor; all other
+ colors are read/write and we can set them by XStoreColor,
+ but we will try to overwrite those color cells with our new
+ color which are as close as possible to our new color */
+ }
+
+ /* look for an existing default color close the one we want */
+
+ mask = 0xf000;
+ color_found = FALSE;
+
+ while (!color_found)
+ {
+ for (i=num_cmap_entries-1; 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; y<image->height; y++) /* general case */
+ {
+ for (x=0; x<image->width; 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; y<image->height; y++)
+ for (x=0; x<image->width; x++)
+ *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
+ }
+ else /* general case */
+ {
+ for (y=0; y<image->height; y++)
+ {
+ for (x=0; x<image->width; 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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 <machine/joystick.h>
+#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 */
--- /dev/null
+/***********************************************************
+* 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"
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+../main.h
\ No newline at end of file
--- /dev/null
+/***********************************************************
+* 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 <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#if !defined(PLATFORM_WIN32)
+#include <pwd.h>
+#include <sys/param.h>
+#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<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
+ {
+ for(x=0; x<lev_fieldx; x++)
+ {
+ if (!IS_MASSIVE(Feld[x][y]))
+ BorderElement = EL_BETON;
+
+ if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
+ x = lev_fieldx - 2;
+ }
+ }
+}
+
+void GetOptions(char *argv[])
+{
+ char **options_left = &argv[1];
+
+ /* initialize global program options */
+ options.display_name = NULL;
+ options.server_host = NULL;
+ options.server_port = 0;
+ options.ro_base_directory = RO_BASE_PATH;
+ options.rw_base_directory = RW_BASE_PATH;
+ options.level_directory = RO_BASE_PATH "/" LEVELS_DIRECTORY;
+ options.serveronly = FALSE;
+ options.network = FALSE;
+ options.verbose = FALSE;
+ options.debug = FALSE;
+
+ /* initialize some more global variables */
+ global.frames_per_second = 0;
+ global.fps_slowdown = FALSE;
+ global.fps_slowdown_factor = 1;
+
+ while (*options_left)
+ {
+ char option_str[MAX_OPTION_LEN];
+ char *option = options_left[0];
+ char *next_option = options_left[1];
+ char *option_arg = NULL;
+ int option_len = strlen(option);
+
+ if (option_len >= 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; i<depth * 3; i++)
+ printf(" ");
+
+ printf("filename == '%s'\n", node->filename);
+
+ 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; i<num_nodes - 1; i++)
+ sort_array[i]->next = 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();
+}
--- /dev/null
+/***********************************************************
+* 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 <stdlib.h>
+#include <stdio.h>
+
+#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 */
--- /dev/null
+/***********************************************************
+* 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<MAX_EVENT_BUFFER; i++)
+ event_buffer[i].type = 0;
+
+ for (i=0; i<MAX_SCANCODES; i++)
+ key_press_state[i] = KeyReleaseMask;
+
+ last_mouse_pos = mouse_pos;
+ last_mouse_b = 0;
+
+ pending_events = 0;
+ clear_keybuf();
+
+ /* enable Windows friendly timer mode (already default under Windows) */
+ i_love_bill = TRUE;
+
+ install_keyboard();
+ install_timer();
+ if (install_mouse() > 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; i<global_colormap_entries_used; i++)
+ {
+ if (r == global_colormap[i].r &&
+ g == global_colormap[i].g &&
+ b == global_colormap[i].b) /* color found */
+ {
+ pixel_mapping = i;
+ break;
+ }
+ }
+
+ if (i == global_colormap_entries_used) /* color not found */
+ {
+ if (global_colormap_entries_used < MAX_COLORS)
+ global_colormap_entries_used++;
+
+ global_colormap[i].r = r;
+ global_colormap[i].g = g;
+ global_colormap[i].b = b;
+
+ pixel_mapping = i;
+ }
+
+ return pixel_mapping;
+}
+
+Display *XOpenDisplay(char *display_name)
+{
+ Screen *screen;
+ Display *display;
+ BITMAP *mouse_bitmap = NULL;
+ char *filename;
+
+ filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
+ MOUSE_FILENAME);
+
+ mouse_bitmap = Read_PCX_to_AllegroBitmap(filename);
+ free(filename);
+
+ if (mouse_bitmap == NULL)
+ return NULL;
+
+ screen = malloc(sizeof(Screen));
+ display = malloc(sizeof(Display));
+
+ screen[0].cmap = 0;
+ screen[0].root = 0;
+#if 0
+ screen[0].white_pixel = 0xFF;
+ screen[0].black_pixel = 0x00;
+#else
+ screen[0].white_pixel = AllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
+ screen[0].black_pixel = AllocColorCell(0x0000, 0x0000, 0x0000);
+#endif
+ screen[0].video_bitmap = NULL;
+
+ display->default_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; i<MAX_COLORS; i++)
+ {
+
+#if 0
+ int r, g, b;
+#endif
+
+ if (!image->rgb.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; j<global_colormap_entries_used; j++)
+ {
+ if (r == global_colormap[j].r &&
+ g == global_colormap[j].g &&
+ b == global_colormap[j].b) /* color found */
+ {
+ pixel_mapping[i] = j;
+ break;
+ }
+ }
+
+ if (j == global_colormap_entries_used) /* color not found */
+ {
+ if (global_colormap_entries_used < MAX_COLORS)
+ global_colormap_entries_used++;
+
+ global_colormap[j].r = r;
+ global_colormap[j].g = g;
+ global_colormap[j].b = b;
+
+ pixel_mapping[i] = j;
+ }
+#else
+ pixel_mapping[i] = AllocColorCell(image->rgb.red[i],
+ image->rgb.green[i],
+ image->rgb.blue[i]);
+#endif
+
+ }
+
+ /* copy bitmap data */
+ for (y=0; y<image->height; y++)
+ for (x=0; x<image->width; 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<MAX_SCANCODES; i++)
+ {
+ int scancode, new_state, event_type;
+ char key_pressed;
+
+ if (mode == HANDLE_RAW_KB_MODIFIER_KEYS_ONLY)
+ {
+ if ((scancode = modifier_scancode[i]) == -1)
+ return;
+ }
+ else
+ scancode = i;
+
+ key_pressed = key[scancode];
+ new_state = (key_pressed ? KeyPressMask : KeyReleaseMask);
+ event_type = (key_pressed ? KeyPress : KeyRelease);
+
+ if (key_press_state[i] == new_state) /* state not changed */
+ continue;
+
+ key_press_state[i] = new_state;
+
+ NewKeyEvent(event_type, ScancodeToKeySym(scancode));
+ }
+}
+
+static void HandleKeyboardEvent()
+{
+ if (keypressed())
+ {
+ int key_info = readkey();
+ int scancode = (key_info >> 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 */
--- /dev/null
+/***********************************************************
+* 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 <allegro.h>
+#include <time.h>
+
+/* 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 */
--- /dev/null
+/***********************************************************
+* 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; i<PCX_MAXCOLORS; i++)
+ {
+ image->rgb.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; i<PCX_MAXCOLORS; i++)
+ if (image->rgb.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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/*
+ * 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 <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#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;
+ }
+}
--- /dev/null
+/***********************************************************
+* 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
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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<sizeof(audio_device_name)/sizeof(char *); i++)
+ if ((audio_fd = OpenAudioDevice(audio_device_name[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<MAX_SOUNDS_PLAYING;i++)
+ playlist[i] = emptySoundControl;
+ playing_sounds = 0;
+
+#if defined(PLATFORM_UNIX)
+ stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
+ for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
+ stereo_volume[i] =
+ (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
+
+#if defined(PLATFORM_HPUX)
+ HPUX_Audio_Control();
+#endif
+
+ FD_ZERO(&sound_fdset);
+ FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+
+ while(1) /* wait for sound playing commands from client */
+ {
+ FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+ select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
+ if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
+ continue;
+ if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
+ != sizeof(snd_ctrl))
+ Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
+
+#if defined(AUDIO_STREAMING_DSP)
+
+ if (snd_ctrl.fade_sound)
+ {
+ if (!playing_sounds)
+ continue;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
+ playlist[i].fade_sound = TRUE;
+ }
+ else if (snd_ctrl.stop_all_sounds)
+ {
+ if (!playing_sounds)
+ continue;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ playlist[i]=emptySoundControl;
+ playing_sounds=0;
+
+ close(audio.device_fd);
+ }
+ else if (snd_ctrl.stop_sound)
+ {
+ if (!playing_sounds)
+ continue;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ if (playlist[i].nr == snd_ctrl.nr)
+ {
+ playlist[i]=emptySoundControl;
+ playing_sounds--;
+ }
+
+ if (!playing_sounds)
+ close(audio.device_fd);
+ }
+
+ if (playing_sounds || snd_ctrl.active)
+ {
+ struct timeval delay = { 0, 0 };
+ byte *sample_ptr;
+ long sample_size;
+ static long max_sample_size = 0;
+ static long fragment_size = 0;
+ /* Even if the stereo flag is used as being boolean, it must be
+ defined as an integer, else 'ioctl()' will fail! */
+ int stereo = TRUE;
+#if 0
+ int sample_rate = 8000;
+#else
+ int sample_rate = 22050;
+#endif
+
+ if (playing_sounds ||
+ (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 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<MAX_SOUNDS_PLAYING;i++)
+ {
+ int j;
+
+ if (!playlist[i].active)
+ continue;
+
+ /* get pointer and size of the actual sound sample */
+ sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
+ sample_size =
+ MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
+ playlist[i].playingpos += sample_size;
+
+ /* fill the first mixing buffer with original sample */
+ memcpy(premix_first_buffer,sample_ptr,sample_size);
+
+ /* are we about to restart a looping sound? */
+ if (playlist[i].loop && sample_size<max_sample_size)
+ {
+ playlist[i].playingpos = max_sample_size-sample_size;
+ memcpy(premix_first_buffer+sample_size,
+ playlist[i].data_ptr,max_sample_size-sample_size);
+ sample_size = max_sample_size;
+ }
+
+ /* decrease volume if sound is fading out */
+ if (playlist[i].fade_sound &&
+ playlist[i].volume>=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<sample_size;j++)
+ premix_first_buffer[j] =
+ (playlist[i].volume * (int)premix_first_buffer[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<sample_size;j++)
+ {
+ premix_left_buffer[j] =
+ (left_volume * (int)premix_first_buffer[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<sample_size;j++)
+ premix_last_buffer[j] += (int)premix_first_buffer[j];
+ }
+
+ /* delete completed sound entries from the playlist */
+ if (playlist[i].playingpos >= 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;i<fragment_size;i++)
+ {
+ if (premix_last_buffer[i]<-255)
+ playing_buffer[i] = 0;
+ else if (premix_last_buffer[i]>255)
+ 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<sample_size;i++)
+ premix_first_buffer[i] =
+ (snd_ctrl.volume * (int)premix_first_buffer[i])
+ >> PSND_MAX_VOLUME_BITS;
+
+ for(i=0;i<sample_size;i++)
+ playing_buffer[i] =
+ linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
+
+ if (snd_ctrl.playingpos >= 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; i<MAX_SOUNDS_PLAYING; i++)
+ if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
+ !playlist[i].fade_sound)
+ {
+ playlist[i].fade_sound = TRUE;
+ if (voice_check(playlist[i].voice))
+ voice_ramp_volume(playlist[i].voice, 1000, 0);
+ playlist[i].loop = PSND_NO_LOOP;
+ }
+ }
+ else if (snd_ctrl.stop_all_sounds)
+ {
+ if (!playing_sounds)
+ return;
+ SoundServer_StopAllSounds();
+ }
+ else if (snd_ctrl.stop_sound)
+ {
+ if (!playing_sounds)
+ return;
+ SoundServer_StopSound(snd_ctrl.nr);
+ }
+
+ for (i=0; i<MAX_SOUNDS_PLAYING; i++)
+ {
+ if (!playlist[i].active || playlist[i].loop)
+ continue;
+
+ playlist[i].playingpos = voice_get_position(playlist[i].voice);
+ playlist[i].volume = voice_get_volume(playlist[i].voice);
+ if (playlist[i].playingpos == -1 || !playlist[i].volume)
+ {
+ deallocate_voice(playlist[i].voice);
+ playlist[i] = emptySoundControl;
+ playing_sounds--;
+ }
+ }
+
+ if (snd_ctrl.active)
+ SoundServer_InsertNewSound(snd_ctrl);
+}
+#endif /* PLATFORM_MSDOS */
+
+#if !defined(PLATFORM_WIN32)
+static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
+{
+ int i, k;
+
+ /* if playlist is full, remove oldest sound */
+ if (playing_sounds==MAX_SOUNDS_PLAYING)
+ {
+ int longest=0, longest_nr=0;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+#if !defined(PLATFORM_MSDOS)
+ int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+ int actual = playlist[i].playingpos;
+#endif
+
+ if (!playlist[i].loop && actual>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--;
+ }
+
+ /* check if sound is already being played (and how often) */
+ for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+ if (playlist[i].nr == snd_ctrl.nr)
+ k++;
+ }
+
+ /* restart loop sounds only if they are just fading out */
+ if (k>=1 && snd_ctrl.loop)
+ {
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+ if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
+ {
+ playlist[i].fade_sound = FALSE;
+ playlist[i].volume = PSND_MAX_VOLUME;
+#if defined(PLATFORM_MSDOS)
+ playlist[i].loop = PSND_LOOP;
+ voice_stop_volumeramp(playlist[i].voice);
+ voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
+#endif
+ }
+ }
+ return;
+ }
+
+ /* don't play sound more than n times simultaneously (with n == 2 for now) */
+ if (k>=2)
+ {
+ int longest=0, longest_nr=0;
+
+ /* look for oldest equal sound */
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+ int actual;
+
+ if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
+ continue;
+
+#if !defined(PLATFORM_MSDOS)
+ actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+ actual = playlist[i].playingpos;
+#endif
+ if (actual>=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<MAX_SOUNDS_PLAYING;i++)
+ {
+ if (!playlist[i].active)
+ {
+ playlist[i] = snd_ctrl;
+ playing_sounds++;
+
+#if defined(PLATFORM_MSDOS)
+ playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
+ if(snd_ctrl.loop)
+ voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
+ voice_set_volume(playlist[i].voice, snd_ctrl.volume);
+ voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
+ voice_start(playlist[i].voice);
+#endif
+ break;
+ }
+ }
+}
+#endif /* !PLATFORM_WIN32 */
+
+/*
+void SoundServer_FadeSound(int nr)
+{
+ int i;
+
+ if (!playing_sounds)
+ return;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
+ playlist[i].fade_sound = TRUE;
+}
+*/
+
+#if !defined(PLATFORM_WIN32)
+#if defined(PLATFORM_MSDOS)
+static void SoundServer_StopSound(int nr)
+{
+ int i;
+
+ if (!playing_sounds)
+ return;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ if (playlist[i].nr == nr)
+ {
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(playlist[i].voice, 0);
+ deallocate_voice(playlist[i].voice);
+#endif
+ playlist[i] = emptySoundControl;
+ playing_sounds--;
+ }
+
+#if !defined(PLATFORM_MSDOS)
+ if (!playing_sounds)
+ close(audio.device_fd);
+#endif
+}
+
+static void SoundServer_StopAllSounds()
+{
+ int i;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(playlist[i].voice, 0);
+ deallocate_voice(playlist[i].voice);
+#endif
+ playlist[i]=emptySoundControl;
+ }
+ playing_sounds = 0;
+
+#if !defined(PLATFORM_MSDOS)
+ close(audio.device_fd);
+#endif
+}
+#endif /* PLATFORM_MSDOS */
+#endif /* !PLATFORM_WIN32 */
+
+#if defined(PLATFORM_HPUX)
+static void HPUX_Audio_Control()
+{
+ struct audio_describe ainfo;
+ int audio_ctl;
+
+ audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
+ if (audio_ctl == -1)
+ Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
+
+ if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
+ Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
+
+ if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
+ Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
+
+ ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
+ ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
+
+ close(audio_ctl);
+}
+#endif /* PLATFORM_HPUX */
+
+#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
+
+/* these two are stolen from "sox"... :) */
+
+/*
+** This routine converts from linear to ulaw.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** Joe Campbell: Department of Defense
+** 29 September 1989
+**
+** References:
+** 1) CCITT Recommendation G.711 (very difficult to follow)
+** 2) "A New Digital Technique for Implementation of Any
+** Continuous PCM Companding Law," Villeret, Michel,
+** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
+** 1973, pg. 11.12-11.17
+** 3) MIL-STD-188-113,"Interoperability and Performance Standards
+** for Analog-to_Digital Conversion Techniques,"
+** 17 February 1987
+**
+** Input: Signed 16 bit linear sample
+** Output: 8 bit ulaw sample
+*/
+
+#define ZEROTRAP /* turn on the trap as per the MIL-STD */
+#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+
+static unsigned char linear_to_ulaw(int sample)
+{
+ static int exp_lut[256] =
+ {
+ 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+ };
+
+ int sign, exponent, mantissa;
+ unsigned char ulawbyte;
+
+ /* Get the sample into sign-magnitude. */
+ sign = (sample >> 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; i<WAV_HEADER_SIZE; i++)
+ sound_header_buffer[i] = fgetc(file);
+
+ /* read chunk "data" */
+ getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
+ if (strcmp(chunk, "data") != 0)
+ {
+ Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
+ fclose(file);
+ return FALSE;
+ }
+
+ snd_info->data_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; i<snd_info->data_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 (volume<PSND_MIN_VOLUME)
+ volume = PSND_MIN_VOLUME;
+ else if (volume>PSND_MAX_VOLUME)
+ volume = PSND_MAX_VOLUME;
+
+ if (stereo<PSND_MAX_LEFT)
+ stereo = PSND_MAX_LEFT;
+ else if (stereo>PSND_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<num_sounds; i++)
+#if !defined(PLATFORM_MSDOS)
+ free(Sound[i].data_ptr);
+#else
+ destroy_sample(Sound[i].sample_ptr);
+#endif
+}
+
+/*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/
--- /dev/null
+/***********************************************************
+* 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 *
+***********************************************************/
+
+#ifndef SOUND_H
+#define SOUND_H
+
+#include <sys/ioctl.h>
+#include <math.h>
+
+#define SND_BLOCKSIZE 4096
+
+#if defined(PLATFORM_LINUX)
+#include <linux/soundcard.h>
+#elif defined(PLATFORM_FREEBSD)
+#include <machine/soundcard.h>
+#elif defined(PLATFORM_HPUX)
+#include <sys/audio.h>
+#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
--- /dev/null
+/***********************************************************
+* 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
+}
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 <stdarg.h>
+
+#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;
+ }
+}
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 */
--- /dev/null
+/***********************************************************
+* 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 <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/keysymdef.h>
+#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 */
* 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 <fcntl.h>
#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] =
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;
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;
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 */
#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
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;
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[];
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;
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;
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[];
+++ /dev/null
-/***********************************************************
-* 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 <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#if !defined(PLATFORM_WIN32)
-#include <pwd.h>
-#include <sys/param.h>
-#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<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
- {
- for(x=0; x<lev_fieldx; x++)
- {
- if (!IS_MASSIVE(Feld[x][y]))
- BorderElement = EL_BETON;
-
- if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
- x = lev_fieldx - 2;
- }
- }
-}
-
-void GetOptions(char *argv[])
-{
- char **options_left = &argv[1];
-
- /* initialize global program options */
- options.display_name = NULL;
- options.server_host = NULL;
- options.server_port = 0;
- options.ro_base_directory = RO_BASE_PATH;
- options.rw_base_directory = RW_BASE_PATH;
- options.level_directory = RO_BASE_PATH "/" LEVELS_DIRECTORY;
- options.serveronly = FALSE;
- options.network = FALSE;
- options.verbose = FALSE;
- options.debug = FALSE;
-
- /* initialize some more global variables */
- global.frames_per_second = 0;
- global.fps_slowdown = FALSE;
- global.fps_slowdown_factor = 1;
-
- while (*options_left)
- {
- char option_str[MAX_OPTION_LEN];
- char *option = options_left[0];
- char *next_option = options_left[1];
- char *option_arg = NULL;
- int option_len = strlen(option);
-
- if (option_len >= 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; i<depth * 3; i++)
- printf(" ");
-
- printf("filename == '%s'\n", node->filename);
-
- 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; i<num_nodes - 1; i++)
- sort_array[i]->next = 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();
-}
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/***********************************************************
-* 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<MAX_EVENT_BUFFER; i++)
- event_buffer[i].type = 0;
-
- for (i=0; i<MAX_SCANCODES; i++)
- key_press_state[i] = KeyReleaseMask;
-
- last_mouse_pos = mouse_pos;
- last_mouse_b = 0;
-
- pending_events = 0;
- clear_keybuf();
-
- /* enable Windows friendly timer mode (already default under Windows) */
- i_love_bill = TRUE;
-
- install_keyboard();
- install_timer();
- if (install_mouse() > 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; i<global_colormap_entries_used; i++)
- {
- if (r == global_colormap[i].r &&
- g == global_colormap[i].g &&
- b == global_colormap[i].b) /* color found */
- {
- pixel_mapping = i;
- break;
- }
- }
-
- if (i == global_colormap_entries_used) /* color not found */
- {
- if (global_colormap_entries_used < MAX_COLORS)
- global_colormap_entries_used++;
-
- global_colormap[i].r = r;
- global_colormap[i].g = g;
- global_colormap[i].b = b;
-
- pixel_mapping = i;
- }
-
- return pixel_mapping;
-}
-
-Display *XOpenDisplay(char *display_name)
-{
- Screen *screen;
- Display *display;
- BITMAP *mouse_bitmap = NULL;
- char *filename;
-
- filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
- MOUSE_FILENAME);
-
- mouse_bitmap = Read_PCX_to_AllegroBitmap(filename);
- free(filename);
-
- if (mouse_bitmap == NULL)
- return NULL;
-
- screen = malloc(sizeof(Screen));
- display = malloc(sizeof(Display));
-
- screen[0].cmap = 0;
- screen[0].root = 0;
-#if 0
- screen[0].white_pixel = 0xFF;
- screen[0].black_pixel = 0x00;
-#else
- screen[0].white_pixel = AllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
- screen[0].black_pixel = AllocColorCell(0x0000, 0x0000, 0x0000);
-#endif
- screen[0].video_bitmap = NULL;
-
- display->default_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; i<MAX_COLORS; i++)
- {
-
-#if 0
- int r, g, b;
-#endif
-
- if (!image->rgb.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; j<global_colormap_entries_used; j++)
- {
- if (r == global_colormap[j].r &&
- g == global_colormap[j].g &&
- b == global_colormap[j].b) /* color found */
- {
- pixel_mapping[i] = j;
- break;
- }
- }
-
- if (j == global_colormap_entries_used) /* color not found */
- {
- if (global_colormap_entries_used < MAX_COLORS)
- global_colormap_entries_used++;
-
- global_colormap[j].r = r;
- global_colormap[j].g = g;
- global_colormap[j].b = b;
-
- pixel_mapping[i] = j;
- }
-#else
- pixel_mapping[i] = AllocColorCell(image->rgb.red[i],
- image->rgb.green[i],
- image->rgb.blue[i]);
-#endif
-
- }
-
- /* copy bitmap data */
- for (y=0; y<image->height; y++)
- for (x=0; x<image->width; 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<MAX_SCANCODES; i++)
- {
- int scancode, new_state, event_type;
- char key_pressed;
-
- if (mode == HANDLE_RAW_KB_MODIFIER_KEYS_ONLY)
- {
- if ((scancode = modifier_scancode[i]) == -1)
- return;
- }
- else
- scancode = i;
-
- key_pressed = key[scancode];
- new_state = (key_pressed ? KeyPressMask : KeyReleaseMask);
- event_type = (key_pressed ? KeyPress : KeyRelease);
-
- if (key_press_state[i] == new_state) /* state not changed */
- continue;
-
- key_press_state[i] = new_state;
-
- NewKeyEvent(event_type, ScancodeToKeySym(scancode));
- }
-}
-
-static void HandleKeyboardEvent()
-{
- if (keypressed())
- {
- int key_info = readkey();
- int scancode = (key_info >> 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 */
+++ /dev/null
-/***********************************************************
-* 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 <allegro.h>
-#include <time.h>
-
-/* 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 */
* network.c *
***********************************************************/
-#include "platform.h"
+#include "libgame/libgame.h"
#if defined(PLATFORM_UNIX)
#include <arpa/inet.h>
#include <netdb.h>
+#if 0
+#include "libgame/libgame.h"
+#endif
+
#include "netserv.h"
-#include "misc.h"
static int clients = 0;
static int onceonly = 0;
* network.c *
***********************************************************/
-#include "platform.h"
+#include "libgame/libgame.h"
#if defined(PLATFORM_UNIX)
#include <arpa/inet.h>
#include <netdb.h>
+#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
{
+++ /dev/null
-/***********************************************************
-* 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; i<PCX_MAXCOLORS; i++)
- {
- image->rgb.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; i<PCX_MAXCOLORS; i++)
- if (image->rgb.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 */
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/*
- * 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 <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#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;
- }
-}
+++ /dev/null
-/***********************************************************
-* 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
* 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"
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
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);
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/***********************************************************
-* 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<sizeof(audio_device_name)/sizeof(char *); i++)
- if ((audio_fd = OpenAudioDevice(sound_device_name)) >= 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<MAX_SOUNDS_PLAYING;i++)
- playlist[i] = emptySoundControl;
- playing_sounds = 0;
-
-#if defined(PLATFORM_UNIX)
- stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
- for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
- stereo_volume[i] =
- (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
-
-#if defined(PLATFORM_HPUX)
- HPUX_Audio_Control();
-#endif
-
- FD_ZERO(&sound_fdset);
- FD_SET(audio.soundserver_pipe[0], &sound_fdset);
-
- while(1) /* wait for sound playing commands from client */
- {
- FD_SET(audio.soundserver_pipe[0], &sound_fdset);
- select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
- if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
- continue;
- if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
- != sizeof(snd_ctrl))
- Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
-
-#if defined(AUDIO_STREAMING_DSP)
-
- if (snd_ctrl.fade_sound)
- {
- if (!playing_sounds)
- continue;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
- playlist[i].fade_sound = TRUE;
- }
- else if (snd_ctrl.stop_all_sounds)
- {
- if (!playing_sounds)
- continue;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- playlist[i]=emptySoundControl;
- playing_sounds=0;
-
- close(audio.device_fd);
- }
- else if (snd_ctrl.stop_sound)
- {
- if (!playing_sounds)
- continue;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- if (playlist[i].nr == snd_ctrl.nr)
- {
- playlist[i]=emptySoundControl;
- playing_sounds--;
- }
-
- if (!playing_sounds)
- close(audio.device_fd);
- }
-
- if (playing_sounds || snd_ctrl.active)
- {
- struct timeval delay = { 0, 0 };
- byte *sample_ptr;
- long sample_size;
- static long max_sample_size = 0;
- static long fragment_size = 0;
- /* Even if the stereo flag is used as being boolean, it must be
- defined as an integer, else 'ioctl()' will fail! */
- int stereo = TRUE;
-#if 0
- int sample_rate = 8000;
-#else
- int sample_rate = 22050;
-#endif
-
- if (playing_sounds ||
- (audio.device_fd = OpenAudioDevice(sound_device_name)) >= 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<MAX_SOUNDS_PLAYING;i++)
- {
- int j;
-
- if (!playlist[i].active)
- continue;
-
- /* get pointer and size of the actual sound sample */
- sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
- sample_size =
- MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
- playlist[i].playingpos += sample_size;
-
- /* fill the first mixing buffer with original sample */
- memcpy(premix_first_buffer,sample_ptr,sample_size);
-
- /* are we about to restart a looping sound? */
- if (playlist[i].loop && sample_size<max_sample_size)
- {
- playlist[i].playingpos = max_sample_size-sample_size;
- memcpy(premix_first_buffer+sample_size,
- playlist[i].data_ptr,max_sample_size-sample_size);
- sample_size = max_sample_size;
- }
-
- /* decrease volume if sound is fading out */
- if (playlist[i].fade_sound &&
- playlist[i].volume>=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<sample_size;j++)
- premix_first_buffer[j] =
- (playlist[i].volume * (int)premix_first_buffer[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<sample_size;j++)
- {
- premix_left_buffer[j] =
- (left_volume * (int)premix_first_buffer[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<sample_size;j++)
- premix_last_buffer[j] += (int)premix_first_buffer[j];
- }
-
- /* delete completed sound entries from the playlist */
- if (playlist[i].playingpos >= 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;i<fragment_size;i++)
- {
- if (premix_last_buffer[i]<-255)
- playing_buffer[i] = 0;
- else if (premix_last_buffer[i]>255)
- 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<sample_size;i++)
- premix_first_buffer[i] =
- (snd_ctrl.volume * (int)premix_first_buffer[i])
- >> PSND_MAX_VOLUME_BITS;
-
- for(i=0;i<sample_size;i++)
- playing_buffer[i] =
- linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
-
- if (snd_ctrl.playingpos >= 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; i<MAX_SOUNDS_PLAYING; i++)
- if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
- !playlist[i].fade_sound)
- {
- playlist[i].fade_sound = TRUE;
- if (voice_check(playlist[i].voice))
- voice_ramp_volume(playlist[i].voice, 1000, 0);
- playlist[i].loop = PSND_NO_LOOP;
- }
- }
- else if (snd_ctrl.stop_all_sounds)
- {
- if (!playing_sounds)
- return;
- SoundServer_StopAllSounds();
- }
- else if (snd_ctrl.stop_sound)
- {
- if (!playing_sounds)
- return;
- SoundServer_StopSound(snd_ctrl.nr);
- }
-
- for (i=0; i<MAX_SOUNDS_PLAYING; i++)
- {
- if (!playlist[i].active || playlist[i].loop)
- continue;
-
- playlist[i].playingpos = voice_get_position(playlist[i].voice);
- playlist[i].volume = voice_get_volume(playlist[i].voice);
- if (playlist[i].playingpos == -1 || !playlist[i].volume)
- {
- deallocate_voice(playlist[i].voice);
- playlist[i] = emptySoundControl;
- playing_sounds--;
- }
- }
-
- if (snd_ctrl.active)
- SoundServer_InsertNewSound(snd_ctrl);
-}
-#endif /* PLATFORM_MSDOS */
-
-#if !defined(PLATFORM_WIN32)
-static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
-{
- int i, k;
-
- /* if playlist is full, remove oldest sound */
- if (playing_sounds==MAX_SOUNDS_PLAYING)
- {
- int longest=0, longest_nr=0;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
-#if !defined(PLATFORM_MSDOS)
- int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
-#else
- int actual = playlist[i].playingpos;
-#endif
-
- if (!playlist[i].loop && actual>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--;
- }
-
- /* check if sound is already being played (and how often) */
- for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
- if (playlist[i].nr == snd_ctrl.nr)
- k++;
- }
-
- /* restart loop sounds only if they are just fading out */
- if (k>=1 && snd_ctrl.loop)
- {
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
- if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
- {
- playlist[i].fade_sound = FALSE;
- playlist[i].volume = PSND_MAX_VOLUME;
-#if defined(PLATFORM_MSDOS)
- playlist[i].loop = PSND_LOOP;
- voice_stop_volumeramp(playlist[i].voice);
- voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
-#endif
- }
- }
- return;
- }
-
- /* don't play sound more than n times simultaneously (with n == 2 for now) */
- if (k>=2)
- {
- int longest=0, longest_nr=0;
-
- /* look for oldest equal sound */
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
- int actual;
-
- if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
- continue;
-
-#if !defined(PLATFORM_MSDOS)
- actual = 100 * playlist[i].playingpos / playlist[i].data_len;
-#else
- actual = playlist[i].playingpos;
-#endif
- if (actual>=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<MAX_SOUNDS_PLAYING;i++)
- {
- if (!playlist[i].active)
- {
- playlist[i] = snd_ctrl;
- playing_sounds++;
-
-#if defined(PLATFORM_MSDOS)
- playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
- if(snd_ctrl.loop)
- voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
- voice_set_volume(playlist[i].voice, snd_ctrl.volume);
- voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
- voice_start(playlist[i].voice);
-#endif
- break;
- }
- }
-}
-#endif /* !PLATFORM_WIN32 */
-
-/*
-void SoundServer_FadeSound(int nr)
-{
- int i;
-
- if (!playing_sounds)
- return;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
- playlist[i].fade_sound = TRUE;
-}
-*/
-
-#if !defined(PLATFORM_WIN32)
-#if defined(PLATFORM_MSDOS)
-static void SoundServer_StopSound(int nr)
-{
- int i;
-
- if (!playing_sounds)
- return;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- if (playlist[i].nr == nr)
- {
-#if defined(PLATFORM_MSDOS)
- voice_set_volume(playlist[i].voice, 0);
- deallocate_voice(playlist[i].voice);
-#endif
- playlist[i] = emptySoundControl;
- playing_sounds--;
- }
-
-#if !defined(PLATFORM_MSDOS)
- if (!playing_sounds)
- close(audio.device_fd);
-#endif
-}
-
-static void SoundServer_StopAllSounds()
-{
- int i;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
-#if defined(PLATFORM_MSDOS)
- voice_set_volume(playlist[i].voice, 0);
- deallocate_voice(playlist[i].voice);
-#endif
- playlist[i]=emptySoundControl;
- }
- playing_sounds = 0;
-
-#if !defined(PLATFORM_MSDOS)
- close(audio.device_fd);
-#endif
-}
-#endif /* PLATFORM_MSDOS */
-#endif /* !PLATFORM_WIN32 */
-
-#if defined(PLATFORM_HPUX)
-static void HPUX_Audio_Control()
-{
- struct audio_describe ainfo;
- int audio_ctl;
-
- audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
- if (audio_ctl == -1)
- Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
-
- if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
- Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
-
- if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
- Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
-
- ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
- ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
-
- close(audio_ctl);
-}
-#endif /* PLATFORM_HPUX */
-
-#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
-
-/* these two are stolen from "sox"... :) */
-
-/*
-** This routine converts from linear to ulaw.
-**
-** Craig Reese: IDA/Supercomputing Research Center
-** Joe Campbell: Department of Defense
-** 29 September 1989
-**
-** References:
-** 1) CCITT Recommendation G.711 (very difficult to follow)
-** 2) "A New Digital Technique for Implementation of Any
-** Continuous PCM Companding Law," Villeret, Michel,
-** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
-** 1973, pg. 11.12-11.17
-** 3) MIL-STD-188-113,"Interoperability and Performance Standards
-** for Analog-to_Digital Conversion Techniques,"
-** 17 February 1987
-**
-** Input: Signed 16 bit linear sample
-** Output: 8 bit ulaw sample
-*/
-
-#define ZEROTRAP /* turn on the trap as per the MIL-STD */
-#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
-#define CLIP 32635
-
-static unsigned char linear_to_ulaw(int sample)
-{
- static int exp_lut[256] =
- {
- 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- };
-
- int sign, exponent, mantissa;
- unsigned char ulawbyte;
-
- /* Get the sample into sign-magnitude. */
- sign = (sample >> 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; i<WAV_HEADER_SIZE; i++)
- sound_header_buffer[i] = fgetc(file);
-
- /* read chunk "data" */
- getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
- if (strcmp(chunk, "data") != 0)
- {
- Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
- fclose(file);
- return FALSE;
- }
-
- snd_info->data_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; i<snd_info->data_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 (volume<PSND_MIN_VOLUME)
- volume = PSND_MIN_VOLUME;
- else if (volume>PSND_MAX_VOLUME)
- volume = PSND_MAX_VOLUME;
-
- if (stereo<PSND_MAX_LEFT)
- stereo = PSND_MAX_LEFT;
- else if (stereo>PSND_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<num_sounds; i++)
-#if !defined(PLATFORM_MSDOS)
- free(Sound[i].data_ptr);
-#else
- destroy_sample(Sound[i].sample_ptr);
-#endif
-}
-
-/*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/
+++ /dev/null
-/***********************************************************
-* 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 *
-***********************************************************/
-
-#ifndef SOUND_H
-#define SOUND_H
-
-#include "platform.h"
-
-#include <sys/ioctl.h>
-#include <math.h>
-
-#define SND_BLOCKSIZE 4096
-
-#if defined(PLATFORM_LINUX)
-#include <linux/soundcard.h>
-#elif defined(PLATFORM_FREEBSD)
-#include <machine/soundcard.h>
-#elif defined(PLATFORM_HPUX)
-#include <sys/audio.h>
-#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
+++ /dev/null
-/***********************************************************
-* 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
-}
+++ /dev/null
-/***********************************************************
-* 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 */
* 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"
#include <stdarg.h>
-#ifdef __FreeBSD__
+#if defined(PLATFORM_FREEBSD)
#include <machine/joystick.h>
#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"
redraw_mask |= REDRAW_FIELD;
}
+
+#if 0
int getFontWidth(int font_size, int font_type)
{
return (font_size == FS_BIG ? FONT1_XSIZE :
x += font_width;
}
}
+#endif
+
void DrawAllPlayers()
{
}
};
+#if 0
static void DoNotDisplayInfoText(void *ptr)
{
return;
}
+#endif
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)
void BackToFront();
void FadeToFront();
void ClearWindow();
+
+#if 0
int getFontWidth(int, int);
int getFontHeight(int, int);
void DrawInitText(char *, int, int);
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 *);
int el2gfx(int);
-#endif
+#endif /* TOOLS_H */
+++ /dev/null
-/***********************************************************
-* 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 */
+++ /dev/null
-/***********************************************************
-* 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 <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.h>
-#include <X11/Intrinsic.h>
-#include <X11/keysymdef.h>
-#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 */