+Release Version 2.0.0 [01 JAN 2001]
+-----------------------------------
+ - major code redesign to maintain generic game functions in a separate
+ library and make it easier to port the game to new targets like SDL
+ - can be compiled with SDL library to build native Windows version
+ - DOS and Windows versions can be compiled with gcc cross-compiler
+ - trying to open already busy audio device does not block the game
+ - fixed network playing bug (patch from web site)
+ - SDL version can load and play music modules
+ - fixed element description in level editor for EM doors and keys
-Release Version 1.3.5 [?? SEP 1999]
+Release Version 1.4.0 [27 OCT 1999]
-----------------------------------
- new Boulderdash elements for better game emulation
- new cool medium-sized crystal font
level directory, standalone server execution and verbose
execution
-Release Version 1.1 [???] [NOT RELEASED]
-----------------------------------------
+Version 1.1 [???] [NOT RELEASED]
+--------------------------------
- new (but broken) GIF graphics loader to be independent
from the XPM library and to replace all graphics by GIF files
-Release Version 1.0 [9 APR 1997] [NOT RELEASED]
------------------------------------------------
+Version 1.0 [9 APR 1997] [NOT RELEASED]
+---------------------------------------
- the game now contains many really playable levels,
not only a few levels for testing
- the game is now even better playable by keyboard
to make it possible to go on with a game at any tape
position
-Prerelease Version 0.9b2 [21 NOV 1995] [NOT RELEASED]
------------------------------------------------------
+Version 0.9b2 [21 NOV 1995] [NOT RELEASED]
+------------------------------------------
- new game elements
Prerelease Version 0.9b [4 NOV 1995]
-Installation instructions for Rocks'n'Diamonds 1.2.0
-====================================================
+Installation instructions for Rocks'n'Diamonds
+==============================================
Compilation
-----------
-If your system supports Linux/i386/ELF/libc5 executables (Linux package)
+If your system supports Linux/i386/ELF/glibc executables (Linux package)
or if you run DOS/Windows (DOS package), you can directly use the included
precompiled binary.
If you use a different system, just recompile the game:
-If you use Linux with gcc or DOS/Windows with djgpp, just try 'make'
+If you use Linux with gcc or DOS or Windows 3.x with djgpp, just try 'make'
which should work without problems.
If you use SUN/Solaris with gcc and GNU make, try 'make solaris'.
+To build the game with SDL support (needed for fullscreen and MOD support),
+type "make sdl". You need at least SDL version 1.1.x and the additional
+SDL libraries SDL_image and SDL_mixer. To get a recent version of the SDL
+library, see http://www.libsdl.org.
+
If the above doesn't work, edit the Makefile in the top level directory.
If it doesn't work either, edit the Makefile in the 'src' subdirectory.
If you had to modify any Makefile to compile it, please drop me a note
-about it to 'aeglos@valinor.owl.de'. Thanks!
+about it to 'info@artsoft.org'. Thanks!
Customization
If you have any comments, additions or modifications to the Makefile(s),
-please send me mail: 'aeglos@valinor.owl.de'. Thanks!
-
-05-DEC-1998, Holger Schemel
+please send me mail: 'info@artsoft.org'. Thanks!
#=============================================================================#
-# Makefile for Rocks'n'Diamonds 1.4.0 #
-# (c) 1995-1999 Holger Schemel, aeglos@valinor.owl.de #
+# Makefile for Rocks'n'Diamonds #
+# (c) 1995-2000 Holger Schemel, info@artsoft.org #
#=============================================================================#
#-----------------------------------------------------------------------------#
# specify your favorite ANSI C compiler
CC = gcc
-# explicitely choose your platform, if defaults doesn't work right
-# needed for SUN/Solaris; Linux and DOS work fine with auto detection
-# PLATFORM = solaris
-# PLATFORM = unix
-# PLATFORM = dos
-
# specify path to X11 on your system
# if undefined, use system defaults (works with Linux/gcc/libc5)
X11_PATH = /usr/X11
# uncomment this if your system has no joystick include file
# JOYSTICK = -DNO_JOYSTICK
-# uncomment this if your system has no sound
-# SOUNDS = -DNO_SOUNDS
-
# choose if you want to allow many global score file entries for one player
# default is 'MANY_PER_NAME'
# when installing the game in a multi user environment, choose this
# when installing the game in a single user environment, choose this
# SCORE_ENTRIES = MANY_PER_NAME
+# specify paths for cross-compiling (only needed for MS-DOS and Win32 build)
+CROSS_PATH_MSDOS=/usr/local/cross-msdos/i386-msdosdjgpp
+CROSS_PATH_WIN32=/usr/local/cross-tools/i386-mingw32msvc
+
#-----------------------------------------------------------------------------#
# you should not need to change anything below #
#-----------------------------------------------------------------------------#
MAKE = make
SRC_DIR = src
-MAKE_CMD = @$(MAKE) -C $(SRC_DIR)
+MAKE_CMD = $(MAKE) -C $(SRC_DIR)
all:
- $(MAKE_CMD)
+ @$(MAKE_CMD) TARGET=x11
+
+x11:
+ @$(MAKE_CMD) TARGET=x11
+
+sdl:
+ @$(MAKE_CMD) TARGET=sdl
solaris:
- $(MAKE_CMD) PLATFORM=solaris
+ @$(MAKE_CMD) PLATFORM=solaris
+
+msdos:
+ @$(MAKE_CMD) PLATFORM=msdos
+
+cross-msdos:
+ @PATH=$(CROSS_PATH_MSDOS)/bin:${PATH} $(MAKE_CMD) PLATFORM=cross-msdos
+
+cross-win32:
+ @PATH=$(CROSS_PATH_WIN32)/bin:${PATH} $(MAKE_CMD) PLATFORM=cross-win32
clean:
- $(MAKE_CMD) clean
+ @$(MAKE_CMD) clean
+
+
+#-----------------------------------------------------------------------------#
+# development only stuff #
+#-----------------------------------------------------------------------------#
+
+backup:
+ ./Scripts/make_backup.sh src
+
+backup_lev:
+ ./Scripts/make_backup.sh lev
+
+backup_gfx:
+ ./Scripts/make_backup.sh gfx
+
+dist-unix:
+ ./Scripts/make_dist.sh unix .
+
+dist-msdos:
+ ./Scripts/make_dist.sh dos .
+
+dist-win32:
+ ./Scripts/make_dist.sh win .
+
+dist: dist-unix dist-msdos dist-win32
+
+depend dep:
+ $(MAKE_CMD) depend
Welcome to
- R O C K S ' N ' D I A M O N D S 1 . 3 . 0
- -----------------------------------------------
+ R O C K S ' N ' D I A M O N D S
+ -----------------------------------
-A game for Unix/X11 by Holger Schemel, (c) 1995-99 by Holger Schemel.
-DOS/Windows port by Guido Schulz.
+A game for Unix/X11, DOS and Windows by Holger Schemel.
+DOS port based on code by Guido Schulz.
+(c) 1995-2000 by Holger Schemel.
Introduction
============
This is a nice little game with color graphics and sound for your
-Unix system with color X11. You need an 8-Bit color display or better.
-It will not work on black&white systems, and maybe not on gray scale systems.
+Unix system with color X11, DOS or Windows. You need an 8-bit color
+display or better.
+It will not work on black&white systems, and maybe not on gray scale
+systems.
If you know the game "Boulderdash" (Commodore C64) or "Emerald Mine"
(Amiga) or "Supaplex" (PC), you know what "ROCKS'N'DIAMONDS" is about.
Getting started
===============
-Just 'cd' to the directory 'rocksndiamonds-*' (Unix) or 'rocks-*' (DOS)
-and type 'rocksndiamonds' (Linux) or 'rocks' (DOS/Windows)!
-This works only on Linux and DOS systems, because the included binary was
-compiled for Linux (i386/glibc) (if you have the Unix package) and DOS
-(if you have the DOS/Windows package).
-If you have another Unix system like HPUX, NetBSD or SUN, you first have to
-type 'make' to compile it.
+Just 'cd' to the directory 'rocksndiamonds-*' (Unix, Windows) or 'rocks-*'
+(DOS) and type 'rocksndiamonds' (Linux, Windows) or 'rocks' (DOS)!
+This works only on Linux, DOS and Windows systems, because the included
+binary was compiled for Linux (i386/glibc) (if you have the Unix package)
+and DOS or Windows (if you have the DOS or Windows package).
+If you have another Unix system like HPUX, NetBSD or Solaris, you first have
+to type 'make' to compile it. See the file 'INSTALL' for details.
This may be needed on Linux systems, too, depending on your kernel version,
-your libc version, your binary format, your processor, ...
+your libc version, your binary format, your processor, your karma, ...
-(The included binary was compiled on the following system:
-AMD K6-2, kernel 2.2.1, glibc, gcc 2.7.2.3, ELF format)
+(The included Linux binary was compiled on a glibc 2.x system based on
+a 2.2.x Linux kernel and XFree86 4.0.x libraries.)
The Menues
This menu will show the text 'team' instead of 'name' if you activated
the team (local multiplayer) mode in the setup menu. See below.
-The menue 'level'
+The menu 'level'
-----------------
Choose any level from the current level series you want. The former
'handicap' limitation in choosing levels has been removed because of
If you have any comments, problems, suggestions, donations, flames,
send them to
- aeglos@valinor.owl.de
+ info@artsoft.org
or Snail Mail to
Holger Schemel
- Oststrasse 11a
+ Detmolder Strasse 189
33604 Bielefeld
GERMANY
#=============================================================================#
-# Makefile for Rocks'n'Diamonds 1.4.0 #
-# (c) 1995-1999 Holger Schemel, aeglos@valinor.owl.de #
+# Makefile for Rocks'n'Diamonds #
+# (c) 1995-2000 Holger Schemel, info@artsoft.org #
#=============================================================================#
+.EXPORT_ALL_VARIABLES:
+
ifndef PLATFORM # platform not specified -- try auto detection
ifdef COMSPEC
-PLATFORM = dos
+PLATFORM = msdos
else
PLATFORM = unix
endif
X11_LIBS = -L$(XLIB_PATH)
endif
+AR = ar
+RANLIB = ranlib
-ifeq ($(PLATFORM),dos) # DOS / Windows
+ifeq ($(PLATFORM),msdos) # MS-DOS native compiling
RM = del
PROGNAME = ../rocks.exe
-LIBS = -s -lm -lalleg
-else # Unix
+SYS_CFLAGS = -DTARGET_X11
+SYS_LDFLAGS = -s -lalleg
+
+else # Unix or cross-compiling for MS-DOS and Win32
RM = rm -f
PROGNAME = ../rocksndiamonds
ifeq ($(PLATFORM),solaris)
-EXTRA_LIBS = -lnsl -lsocket -R$(XLIB_PATH)
+EXTRA_LDFLAGS = -lnsl -lsocket -R$(XLIB_PATH)
+PLATFORM = unix
+endif
+
+ifeq ($(PLATFORM),unix)
+PROFILING_FLAGS = -pg
+endif
+
+ifeq ($(PLATFORM),cross-msdos)
+PROGNAME = ../rocks.exe
+TARGET = allegro
+endif
+
+ifeq ($(PLATFORM),cross-win32)
+PROGNAME = ../rocksndiamonds.exe
+TARGET = sdl
+endif
+
+ifeq ($(TARGET),x11)
+SYS_CFLAGS = -DTARGET_X11 $(X11_INCL)
+SYS_LDFLAGS = $(X11_LIBS) -lX11
endif
-INCL = $(X11_INCL)
-LIBS = $(X11_LIBS) -lX11 -lm $(EXTRA_LIBS)
+ifeq ($(TARGET),sdl)
+SYS_CFLAGS = -DTARGET_SDL $(shell sdl-config --cflags)
+SYS_LDFLAGS = -lSDL_image -lSDL_mixer $(shell sdl-config --libs)
+endif
+ifeq ($(TARGET),allegro)
+SYS_CFLAGS = -DTARGET_ALLEGRO -I$(CROSS_PATH_MSDOS)/include
+SYS_LDFLAGS = -lalleg
endif
+endif # (PLATFORM != msdos)
+
ifdef RO_GAME_DIR # path to read-only game data specified
CONFIG_RO_GAME_DIR = -DRO_GAME_DIR="\"$(RO_GAME_DIR)\""
CONFIG_GAME_DIR = $(CONFIG_RO_GAME_DIR) $(CONFIG_RW_GAME_DIR)
-CONFIG = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(SOUNDS) $(JOYSTICK)
+CONFIG = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(JOYSTICK)
+DEBUG = -DDEBUG -g
+# PROFILING = $(PROFILING_FLAGS)
-# OPTIONS = -DDEBUG -g -Wall -ansi -pedantic # only for debugging purposes
-# OPTIONS = -DDEBUG -g -Wall # only for debugging purposes
+# OPTIONS = $(DEBUG) -Wall # only for debugging purposes
+# OPTIONS = $(DEBUG) -O3 -Wall # only for debugging purposes
+# OPTIONS = $(DEBUG) -Wall -ansi -pedantic # only for debugging purposes
# OPTIONS = -O3 -Wall -ansi -pedantic
-# OPTIONS = -O3 -Wall
-OPTIONS = -O3
+OPTIONS = -O3 -Wall
+# OPTIONS = -O3
+# OPTIONS = -DSYSV -Ae # may be needed for HP-UX
-# SYSTEM = -DSYSV -Ae # may be needed for HP-UX
+CFLAGS = $(OPTIONS) $(SYS_CFLAGS) $(CONFIG)
+LDFLAGS = $(SYS_LDFLAGS) $(EXTRA_LDFLAGS) -lm
-CFLAGS = $(OPTIONS) $(SYSTEM) $(INCL) $(CONFIG)
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
+ 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
+ netserv.o
+
+LIBDIR = libgame
+LIBGAME = $(LIBDIR)/libgame.a
+
+
+all: $(PROGNAME)
-all: $(PROGNAME)
+$(PROGNAME): $(LIBGAME) $(OBJS)
+ $(CC) $(PROFILING) $(OBJS) $(LIBGAME) $(LDFLAGS) -o $(PROGNAME)
-$(PROGNAME): $(OBJS)
- $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $(PROGNAME)
+$(LIBGAME):
+ $(MAKE) -C $(LIBDIR)
.c.o:
- $(CC) $(CFLAGS) -c $*.c
+ $(CC) $(PROFILING) $(CFLAGS) -c $*.c
clean:
- $(RM) *.o
+ $(MAKE) -C $(LIBDIR) clean
+ $(RM) $(OBJS)
+ $(RM) $(LIBGAME)
$(RM) $(PROGNAME)
+ $(RM) ../*.exe
+
+
+#-----------------------------------------------------------------------------#
+# development only stuff #
+#-----------------------------------------------------------------------------#
+
+depend:
+ $(MAKE) -C $(LIBDIR) 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 "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;
-
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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)
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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)
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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;
-
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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;
-
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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()
-{
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
- XCopyArea(display,pix[PIX_DOOR],drawto,gc,
- 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);
- }
-
- XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
- 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:
- XCopyArea(display, gd->pixmap, drawto, gc,
- gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
- if (gi->deco.design.pixmap)
- XCopyArea(display, gi->deco.design.pixmap, drawto, gc,
- 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 */
- XCopyArea(display, gd->pixmap, drawto, gc,
- gd->x, gd->y, border, gi->height, gi->x, gi->y);
-
- /* middle part of gadget */
- for (i=0; i<=gi->text.size; i++)
- XCopyArea(display, gd->pixmap, drawto, gc,
- gd->x + border, gd->y, font_width, gi->height,
- gi->x + border + i * font_width, gi->y);
-
- /* right part of gadget */
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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 */
- XFillRectangle(display, backbuffer, gc,
- gi->x, gi->y, gi->width, gi->height);
-
- /* upper part of gadget */
- XCopyArea(display, gd->pixmap, drawto, gc,
- gd->x, gd->y,
- gi->width, gi->border.size,
- xpos, ypos);
-
- /* middle part of gadget */
- for (i=0; i<num_steps; i++)
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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)
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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 */
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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 */
- XFillRectangle(display, backbuffer, gc,
- gi->x, gi->y, gi->width, gi->height);
-
- /* left part of gadget */
- XCopyArea(display, gd->pixmap, drawto, gc,
- gd->x, gd->y,
- gi->border.size, gi->height,
- xpos, ypos);
-
- /* middle part of gadget */
- for (i=0; i<num_steps; i++)
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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)
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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 */
- XCopyArea(display, gd->pixmap, drawto, gc,
- 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)
- XCopyArea(display, drawto, window, gc,
- 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].pixmap = va_arg(ap, Pixmap);
- 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].pixmap = va_arg(ap, Pixmap);
- 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].pixmap= va_arg(ap, Pixmap);
- 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].pixmap = va_arg(ap, Pixmap);
- 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.pixmap = va_arg(ap, Pixmap);
- 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].pixmap ||
- !gi->design[GD_BUTTON_PRESSED].pixmap))
- Error(ERR_EXIT, "gadget incomplete (missing Pixmap)");
-
- /* 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(KeySym 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 = getCharFromKeySym(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 == XK_Left && cursor_pos > 0)
- {
- gi->text.cursor_position--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == XK_Right && cursor_pos < text_length)
- {
- gi->text.cursor_position++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == XK_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 == XK_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 == XK_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
-{
- Pixmap pixmap; /* Pixmap with gadget surface */
- int x, y; /* position of rectangle in Pixmap */
-};
-
-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(KeySym);
-
-#endif
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* cartoons.c *
+* cartoons.c *
***********************************************************/
#include "cartoons.h"
#include "main.h"
-#include "misc.h"
#include "tools.h"
+
static void HandleAnimation(int);
static boolean AnimateToon(int, boolean);
-static void DrawAnim(Pixmap, GC, int, int, int, int, int, int, int, int);
+static void DrawAnim(Bitmap *, GC, int, int, int, int, int, int, int, int);
struct AnimInfo
{
fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
- XCopyArea(display,fieldbuffer,backbuffer,gc,
- fx,fy, SXSIZE,SYSIZE,
- SX,SY);
+ BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
}
return;
},
};
struct AnimInfo *anim = &toon[toon_nr];
- Pixmap anim_pixmap = (toon_nr < 6 ? pix[PIX_TOONS] : pix[PIX_HEROES]);
- GC anim_clip_gc = (toon_nr < 6 ? clip_gc[PIX_TOONS] : clip_gc[PIX_HEROES]);
+ int anim_bitmap_nr = (toon_nr < 6 ? PIX_TOONS : PIX_HEROES);
+ Bitmap *anim_bitmap = pix[anim_bitmap_nr];
+ GC anim_clip_gc = pix[anim_bitmap_nr]->stored_clip_gc;
if (restart)
{
if ((game_status == HELPSCREEN ||
(game_status == MAINMENU && redraw_mask & REDRAW_MICROLEVEL))
&& !restart)
- DrawAnim(anim_pixmap, anim_clip_gc,
+ DrawAnim(anim_bitmap, anim_clip_gc,
src_x + cut_x, src_y + cut_y, width, height,
REAL_SX + dest_x, REAL_SY + dest_y, pad_x, pad_y);
else if (pos_y>FULL_SYSIZE-anim->height)
height -= (pos_y - (FULL_SYSIZE-anim->height));
- DrawAnim(anim_pixmap,anim_clip_gc,
+ DrawAnim(anim_bitmap,anim_clip_gc,
src_x+cut_x,src_y+cut_y, width,height,
REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
return(FALSE);
}
-void DrawAnim(Pixmap toon_pixmap, GC toon_clip_gc,
+void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc,
int src_x, int src_y, int width, int height,
int dest_x, int dest_y, int pad_x, int pad_y)
{
#if 1
/* special method to avoid flickering interference with BackToFront() */
- XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, buf_x,buf_y);
- XSetClipOrigin(display,toon_clip_gc,dest_x-src_x,dest_y-src_y);
- XCopyArea(display,toon_pixmap,backbuffer,toon_clip_gc,
- src_x,src_y, width,height, dest_x,dest_y);
- XCopyArea(display,backbuffer,window,gc, dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+ BlitBitmap(backbuffer, pix[PIX_DB_DOOR], dest_x-pad_x, dest_y-pad_y,
+ width+2*pad_x, height+2*pad_y, buf_x, buf_y);
+ SetClipOrigin(toon_bitmap, toon_clip_gc, dest_x-src_x, dest_y-src_y);
+ BlitBitmapMasked(toon_bitmap, backbuffer,
+ src_x, src_y, width, height, dest_x, dest_y);
+ BlitBitmap(backbuffer, window, dest_x-pad_x, dest_y-pad_y,
+ width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
BackToFront();
- XCopyArea(display,pix[PIX_DB_DOOR],backbuffer,gc, buf_x,buf_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+ BlitBitmap(pix[PIX_DB_DOOR], backbuffer, buf_x, buf_y,
+ width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
#else
/* normal method, causing flickering interference with BackToFront() */
- XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
- width+2*pad_x,height+2*pad_y, buf_x,buf_y);
- XSetClipOrigin(display,toon_clip_gc,
- buf_x-src_x+pad_x,buf_y-src_y+pad_y);
- XCopyArea(display,toon_pixmap,pix[PIX_DB_DOOR],toon_clip_gc,
- src_x,src_y, width,height, buf_x+pad_x,buf_y+pad_y);
- XCopyArea(display,pix[PIX_DB_DOOR],window,gc, buf_x,buf_y,
- width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
+ BlitBitmap(backbuffer, pix[PIX_DB_DOOR], dest_x-pad_x, dest_y-pad_y,
+ width+2*pad_x, height+2*pad_y, buf_x, buf_y);
+ SetClipOrigin(toon_bitmap,toon_clip_gc, buf_x-src_x+pad_x,buf_y-src_y+pad_y);
+ BlitBitmapMasked(toon_bitmap, pix[PIX_DB_DOOR],
+ src_x, src_y, width, height, buf_x+pad_x, buf_y+pad_y);
+ BlitBitmap(pix[PIX_DB_DOOR], window, buf_x, buf_y,
+ width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y);
#endif
- XFlush(display);
+ FlushDisplay();
}
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* cartoons.h *
+* cartoons.h *
***********************************************************/
#ifndef CARTOONS_H
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* editor.c *
+* editor.c *
***********************************************************/
#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"
static int new_element2 = EL_LEERRAUM;
static int new_element3 = EL_ERDREICH;
-#define BUTTON_ELEMENT(button) (button == 1 ? new_element1 : \
- button == 2 ? new_element2 : \
- button == 3 ? new_element3 : EL_LEERRAUM)
-#define BUTTON_STEPSIZE(button) (button == 1 ? 1 : button == 2 ? 5 : 10)
+#define BUTTON_ELEMENT(button) ((button) == 1 ? new_element1 : \
+ (button) == 2 ? new_element2 : \
+ (button) == 3 ? new_element3 : EL_LEERRAUM)
+#define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10)
/* forward declaration for internal use */
static void ModifyEditorCounter(int, int);
};
int elements_in_list = sizeof(editor_element)/sizeof(int);
+static char *getElementInfoText(int element)
+{
+ char *info_text = "unknown";
+
+ if (element < num_element_info)
+ info_text = element_info[element];
+ else
+ Error(ERR_WARN, "no element description for element %d", element);
+
+ return info_text;
+}
+
static void ScrollMiniLevel(int from_x, int from_y, int scroll)
{
int x,y;
int dx = (scroll == ED_SCROLL_LEFT ? -1 : scroll == ED_SCROLL_RIGHT ? 1 : 0);
int dy = (scroll == ED_SCROLL_UP ? -1 : scroll == ED_SCROLL_DOWN ? 1 : 0);
- XCopyArea(display, drawto, drawto, gc,
- SX + (dx == -1 ? MINI_TILEX : 0),
- SY + (dy == -1 ? MINI_TILEY : 0),
- (ed_fieldx * MINI_TILEX) - (dx != 0 ? MINI_TILEX : 0),
- (ed_fieldy * MINI_TILEY) - (dy != 0 ? MINI_TILEY : 0),
- SX + (dx == +1 ? MINI_TILEX : 0),
- SY + (dy == +1 ? MINI_TILEY : 0));
+ BlitBitmap(drawto, drawto,
+ SX + (dx == -1 ? MINI_TILEX : 0),
+ SY + (dy == -1 ? MINI_TILEY : 0),
+ (ed_fieldx * MINI_TILEX) - (dx != 0 ? MINI_TILEX : 0),
+ (ed_fieldy * MINI_TILEY) - (dy != 0 ? MINI_TILEY : 0),
+ SX + (dx == +1 ? MINI_TILEX : 0),
+ SY + (dy == +1 ? MINI_TILEY : 0));
if (dx)
{
x = (dx == 1 ? 0 : ed_fieldx - 1);
static void CreateControlButtons()
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
struct GadgetInfo *gi;
unsigned long event_mask;
int i;
GDI_STATE, GD_BUTTON_UNPRESSED,
GDI_RADIO_NR, radio_button_nr,
GDI_CHECKED, checked,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y1,
- GDI_ALT_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y2,
- GDI_ALT_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ 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_HEIGHT, height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ 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);
/* create buttons for element list */
for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
{
- Pixmap deco_pixmap;
+ Bitmap *deco_bitmap;
int deco_x, deco_y, deco_xpos, deco_ypos;
int gd_xoffset, gd_yoffset;
int gd_x1, gd_x2, gd_y;
gd_y = DOOR_GFX_PAGEY1 + ED_ELEMENTLIST_YPOS;
getMiniGraphicSource(el2gfx(editor_element[i]),
- &deco_pixmap, &deco_x, &deco_y);
+ &deco_bitmap, &deco_x, &deco_y);
deco_xpos = (ED_ELEMENTLIST_XSIZE - MINI_TILEX) / 2;
deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_INFO_TEXT, element_info[editor_element[i]],
+ GDI_INFO_TEXT, getElementInfoText(editor_element[i]),
GDI_X, DX + gd_xoffset,
GDI_Y, DY + gd_yoffset,
GDI_WIDTH, ED_ELEMENTLIST_XSIZE,
GDI_HEIGHT, ED_ELEMENTLIST_YSIZE,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
- GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
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);
for (j=0; j<2; j++)
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
struct GadgetInfo *gi;
int id = (j == 0 ?
counterbutton_info[i].gadget_id_down :
GDI_HEIGHT, y_size,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
+ GDI_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_NUMBER_MAX, counterbutton_info[i].max_value,
GDI_TEXT_SIZE, 3,
GDI_TEXT_FONT, font_type,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
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);
for (i=0; i<ED_NUM_TEXTINPUT; i++)
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
int gd_x, gd_y;
struct GadgetInfo *gi;
unsigned long event_mask;
GDI_TEXT_VALUE, textinput_info[i].value,
GDI_TEXT_SIZE, textinput_info[i].size,
GDI_TEXT_FONT, FC_YELLOW,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
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);
for (i=0; i<ED_NUM_SCROLLBARS; i++)
{
int id = scrollbar_info[i].gadget_id;
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
int gd_x1, gd_x2, gd_y1, gd_y2;
struct GadgetInfo *gi;
int items_max, items_visible, item_position;
GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
GDI_SCROLLBAR_ITEM_POSITION, item_position,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ 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);
static void CreateCheckbuttonGadgets()
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
struct GadgetInfo *gi;
unsigned long event_mask;
int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
GDI_TYPE, GD_TYPE_RADIO_BUTTON,
GDI_RADIO_NR, radiobutton_info[i].radio_button_nr,
GDI_CHECKED, checked,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
- GDI_ALT_DESIGN_UNPRESSED, gd_pixmap, gd_x3, gd_y,
- GDI_ALT_DESIGN_PRESSED, gd_pixmap, gd_x4, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ 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_HEIGHT, ED_CHECKBUTTON_YSIZE,
GDI_TYPE, GD_TYPE_CHECK_BUTTON,
GDI_CHECKED, *checkbutton_info[i].value,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
- GDI_ALT_DESIGN_UNPRESSED, gd_pixmap, gd_x3, gd_y,
- GDI_ALT_DESIGN_PRESSED, gd_pixmap, gd_x4, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ 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);
}
/* copy default editor door content to main double buffer */
- XCopyArea(display, pix[PIX_DOOR], drawto, gc,
- DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+ BlitBitmap(pix[PIX_DOOR], drawto,
+ DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
/* draw mouse button brush elements */
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
el2gfx(new_element1));
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
el2gfx(new_element2));
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
el2gfx(new_element3));
DrawSpecialEditorDoor();
/* draw new control window */
- XCopyArea(display, pix[PIX_DOOR], drawto, gc,
- DOOR_GFX_PAGEX8, 236,
- EXSIZE, EYSIZE,
- EX, EY);
+ BlitBitmap(pix[PIX_DOOR], drawto,
+ DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY);
redraw_mask |= REDRAW_ALL;
MapControlButtons();
/* copy actual editor door content to door double buffer for OpenDoor() */
- XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
DrawEditModeWindow();
if (button == 1)
{
new_element1 = element;
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
el2gfx(new_element1));
}
else if (button == 2)
{
new_element2 = element;
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
el2gfx(new_element2));
}
else
{
new_element3 = element;
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
el2gfx(new_element3));
}
for (x=0; x<2; x++)
DrawMiniElement(area_x + x, area_y + y, EL_ERDREICH);
- XFillRectangle(display, drawto, gc,
+ ClearRectangle(drawto,
area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1,
MINI_TILEX + 2, MINI_TILEY + 2);
/* copy border to the right location */
- XCopyArea(display, drawto, drawto, gc,
- area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+ BlitBitmap(drawto, drawto,
+ area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
+ area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
for (x=0; x<2; x++)
DrawMiniElement(area_x + x, area_y + y, EL_ERDREICH);
- XFillRectangle(display, drawto, gc,
+ ClearRectangle(drawto,
area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1,
MINI_TILEX + 2, MINI_TILEY + 2);
/* copy border to the right location */
- XCopyArea(display, drawto, drawto, gc,
- area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+ BlitBitmap(drawto, drawto,
+ area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
+ area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba",
FS_SMALL, font_color);
MapCounterButtons(counter_id);
/* delete content areas in case of reducing number of them */
- XFillRectangle(display, backbuffer, gc,
+ ClearRectangle(backbuffer,
SX, area_sy - MINI_TILEX,
SXSIZE, 12 * MINI_TILEY);
DrawMiniElement(area_x + 5 * (i % 4) + x, area_y + 6 * (i / 4) + y,
EL_ERDREICH);
- XFillRectangle(display, drawto, gc,
+ ClearRectangle(drawto,
area_sx + 5 * (i % 4) * MINI_TILEX + MINI_TILEX/2 - 1,
area_sy + 6 * (i / 4) * MINI_TILEY + MINI_TILEY/2 - 1,
3 * MINI_TILEX + 2, 3 * MINI_TILEY + 2);
}
/* copy border to the right location */
- XCopyArea(display, drawto, drawto, gc,
- area_sx, area_sy, (5 * 4 + 1) * MINI_TILEX, 11 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+ BlitBitmap(drawto, drawto,
+ area_sx, area_sy, (5 * 4 + 1) * MINI_TILEX, 11 * MINI_TILEY,
+ area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 0 * MINI_TILEY + 1,
"Content", FS_SMALL, font_color);
for (x=0; x<3; x++)
DrawMiniElement(xstart + x , ystart + y, EL_ERDREICH);
- XFillRectangle(display, drawto, gc,
+ ClearRectangle(drawto,
SX + xstart * MINI_TILEX + MINI_TILEX/2 - 1,
SY + ystart * MINI_TILEY + MINI_TILEY/2 - 1,
TILEX + 2, TILEY + 2);
/* copy border to the right location */
- XCopyArea(display, drawto, drawto, gc,
- SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY,
- 2 * TILEX, 2 * TILEY,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY/2);
+ BlitBitmap(drawto, drawto,
+ SX + xstart * MINI_TILEX,
+ SY + ystart * MINI_TILEY,
+ 2 * TILEX, 2 * TILEY,
+ SX + xstart * MINI_TILEX - MINI_TILEX/2,
+ SY + ystart * MINI_TILEY - MINI_TILEY/2);
DrawGraphic(xstart/2, ystart/2, el2gfx(properties_element));
/* copy the whole stuff to the definitive location */
- XCopyArea(display, drawto, drawto, gc,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY,
- 2 * TILEX, 2 * TILEY,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY/2);
+ BlitBitmap(drawto, drawto,
+ SX + xstart * MINI_TILEX - MINI_TILEX/2,
+ SY + ystart * MINI_TILEY - MINI_TILEY,
+ 2 * TILEX, 2 * TILEY,
+ SX + xstart * MINI_TILEX - MINI_TILEX/2,
+ SY + ystart * MINI_TILEY - MINI_TILEY/2);
DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY,
- font_color, element_info[properties_element]);
+ font_color, getElementInfoText(properties_element));
num_elements_in_level = 0;
for (y=0; y<lev_fieldy; y++)
}
}
-static void swap_numbers(int *i1, int *i2)
-{
- int help = *i1;
-
- *i1 = *i2;
- *i2 = help;
-}
-
-static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
-{
- int help_x = *x1;
- int help_y = *y1;
-
- *x1 = *x2;
- *x2 = help_x;
-
- *y1 = *y2;
- *y2 = help_y;
-}
-
static void DrawLineElement(int sx, int sy, int element, boolean change_level)
{
int lx = sx + level_xpos;
to_sx = SX + to_x * MINI_TILEX + MINI_TILEX - 1;
to_sy = SY + to_y * MINI_TILEY + MINI_TILEY - 1;
- XSetForeground(display, gc, WhitePixel(display, screen));
-
- XDrawLine(display, drawto, gc, from_sx, from_sy, to_sx, from_sy);
- XDrawLine(display, drawto, gc, to_sx, from_sy, to_sx, to_sy);
- XDrawLine(display, drawto, gc, to_sx, to_sy, from_sx, to_sy);
- XDrawLine(display, drawto, gc, from_sx, to_sy, from_sx, from_sy);
-
- XSetForeground(display, gc, BlackPixel(display, screen));
+ DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy);
+ DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy);
+ DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy);
+ DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy);
if (from_x == to_x && from_y == to_y)
MarkTileDirty(from_x/2, from_y/2);
}
else
{
- DrawMiniGraphicExt(drawto, gc,
+ DrawMiniGraphicExt(drawto,
gi->x + sx * MINI_TILEX,
gi->y + sy * MINI_TILEY,
el2gfx(new_element));
- DrawMiniGraphicExt(window, gc,
+ DrawMiniGraphicExt(window,
gi->x + sx * MINI_TILEX,
gi->y + sy * MINI_TILEY,
el2gfx(new_element));
{
CopyAreaToBrush(start_sx, start_sy, sx, sy, button);
CopyBrushToCursor(sx, sy);
- ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],MB_LEFT);
+ ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],
+ MB_LEFTBUTTON);
draw_with_brush = TRUE;
}
else if (drawing_function == GADGET_ID_TEXT)
case GADGET_ID_PICK_ELEMENT:
if (button_release_event)
- ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFT);
+ ClickOnGadget(level_editor_gadget[last_drawing_function],
+ MB_LEFTBUTTON);
else
PickDrawingElement(button, Feld[lx][ly]);
int element = editor_element[element_shift + i];
UnmapGadget(gi);
- getMiniGraphicSource(el2gfx(element), &gd->pixmap, &gd->x, &gd->y);
- ModifyGadget(gi, GDI_INFO_TEXT, element_info[element], GDI_END);
+ getMiniGraphicSource(el2gfx(element), &gd->bitmap, &gd->x, &gd->y);
+ ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
MapGadget(gi);
}
break;
else
{
CloseDoor(DOOR_CLOSE_1);
- XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_1);
}
break;
}
if (drawing_function == GADGET_ID_PICK_ELEMENT)
- ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFT);
+ ClickOnGadget(level_editor_gadget[last_drawing_function],
+ MB_LEFTBUTTON);
}
#ifdef DEBUG
else if (gi->event.type == GD_EVENT_PRESSED)
}
}
-void HandleLevelEditorKeyInput(KeySym key)
+void HandleLevelEditorKeyInput(Key key)
{
- char letter = getCharFromKeySym(key);
- int button = MB_LEFT;
+ char letter = getCharFromKey(key);
+ int button = MB_LEFTBUTTON;
if (drawing_function == GADGET_ID_TEXT &&
DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE)
{
if (letter)
DrawLevelText(0, 0, letter, TEXT_WRITECHAR);
- else if (key == XK_Delete || key == XK_BackSpace)
+ else if (key == KSYM_Delete || key == KSYM_BackSpace)
DrawLevelText(0, 0, 0, TEXT_BACKSPACE);
- else if (key == XK_Return)
+ else if (key == KSYM_Return)
DrawLevelText(0, 0, 0, TEXT_NEWLINE);
}
else if (button_status == MB_RELEASED)
switch (key)
{
- case XK_Left:
+ case KSYM_Left:
id = GADGET_ID_SCROLL_LEFT;
break;
- case XK_Right:
+ case KSYM_Right:
id = GADGET_ID_SCROLL_RIGHT;
break;
- case XK_Up:
+ case KSYM_Up:
id = GADGET_ID_SCROLL_UP;
break;
- case XK_Down:
+ case KSYM_Down:
id = GADGET_ID_SCROLL_DOWN;
break;
- case XK_Page_Up:
+ case KSYM_Page_Up:
id = GADGET_ID_SCROLL_LIST_UP;
- button = 3;
+ button = MB_RIGHTBUTTON;
break;
- case XK_Page_Down:
+ case KSYM_Page_Down:
id = GADGET_ID_SCROLL_LIST_DOWN;
- button = 3;
+ button = MB_RIGHTBUTTON;
break;
default:
ClickOnGadget(level_editor_gadget[id], button);
else if (letter == '.')
ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
- else if (key == XK_space || key == XK_Return)
+ else if (key == KSYM_space || key == KSYM_Return)
ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
else
for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
void ClearEditorGadgetInfoText()
{
- XFillRectangle(display, drawto, gc,
+ ClearRectangle(drawto,
INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE);
redraw_mask |= REDRAW_FIELD;
}
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 */
}
else if (drawing_function == GADGET_ID_PICK_ELEMENT)
DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
- "%s", element_info[Feld[lx][ly]]);
+ "%s", getElementInfoText(Feld[lx][ly]));
else
DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
"Level position: %d, %d", lx, ly);
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* editor.h *
+* editor.h *
***********************************************************/
#ifndef EDITOR_H
void CreateLevelEditorGadgets();
void UnmapLevelEditorGadgets();
void DrawLevelEd(void);
-void HandleLevelEditorKeyInput(KeySym);
+void HandleLevelEditorKeyInput(Key);
void HandleEditorGadgetInfoText(void *ptr);
#endif
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* events.c *
+* 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 */
#define KEY_RELEASED FALSE
#define KEY_PRESSED TRUE
+
+/* event filter especially needed for SDL event filtering due to
+ delay problems with lots of mouse motion events when mouse
+ button not pressed */
+
+int FilterMouseMotionEvents(const Event *event)
+{
+ if (event->type != EVENT_MOTIONNOTIFY)
+ return 1;
+
+ /* get mouse motion events without pressed button only in level editor */
+ if (button_status == MB_RELEASED && game_status != LEVELED)
+ return 0;
+ else
+ return 1;
+}
+
+/* this is only really needed for non-SDL targets to filter unwanted events;
+ when using SDL with properly installed event filter, this function can be
+ replaced with a simple "NextEvent()" call, but it doesn't hurt either */
+
+static boolean NextValidEvent(Event *event)
+{
+ while (PendingEvent())
+ {
+ NextEvent(event);
+
+ if (FilterMouseMotionEvents(event))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
void EventLoop(void)
{
while(1)
{
- if (XPending(display)) /* got event from X server */
+ if (PendingEvent()) /* got event */
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
-
- switch(event.type)
+ if (NextValidEvent(&event))
{
- case ButtonPress:
- case ButtonRelease:
- HandleButtonEvent((XButtonEvent *) &event);
- break;
-
- case MotionNotify:
- HandleMotionEvent((XMotionEvent *) &event);
- break;
-
- case KeyPress:
- case KeyRelease:
- HandleKeyEvent((XKeyEvent *) &event);
- break;
-
- default:
- HandleOtherEvents(&event);
- break;
+ switch(event.type)
+ {
+ case EVENT_BUTTONPRESS:
+ case EVENT_BUTTONRELEASE:
+ HandleButtonEvent((ButtonEvent *) &event);
+ break;
+
+ case EVENT_MOTIONNOTIFY:
+ HandleMotionEvent((MotionEvent *) &event);
+ break;
+
+ case EVENT_KEYPRESS:
+ case EVENT_KEYRELEASE:
+ HandleKeyEvent((KeyEvent *) &event);
+ break;
+
+ default:
+ HandleOtherEvents(&event);
+ break;
+ }
}
}
-
- HandleNoXEvent();
+ else
+ HandleNoEvent();
/* don't use all CPU time when idle; the main loop while playing
has its own synchronization and is CPU friendly, too */
- if (game_status != PLAYING)
+ if (game_status == PLAYING)
+ HandleGameActions();
+ else
{
- XSync(display, FALSE);
- if (!XPending(display)) /* delay only if no pending events */
+ SyncDisplay();
+ if (!PendingEvent()) /* delay only if no pending events */
Delay(10);
}
}
}
-void HandleOtherEvents(XEvent *event)
+void HandleOtherEvents(Event *event)
{
switch(event->type)
{
- case Expose:
- HandleExposeEvent((XExposeEvent *) event);
+ case EVENT_EXPOSE:
+ HandleExposeEvent((ExposeEvent *) event);
break;
- case UnmapNotify:
+ case EVENT_UNMAPNOTIFY:
SleepWhileUnmapped();
break;
- case FocusIn:
- case FocusOut:
- HandleFocusEvent((XFocusChangeEvent *) event);
+ case EVENT_FOCUSIN:
+ case EVENT_FOCUSOUT:
+ HandleFocusEvent((FocusChangeEvent *) event);
+ break;
+
+ case EVENT_CLIENTMESSAGE:
+ HandleClientMessageEvent((ClientMessageEvent *) event);
break;
- case ClientMessage:
- HandleClientMessageEvent((XClientMessageEvent *) event);
+#if defined(TARGET_SDL)
+ case SDL_JOYAXISMOTION:
+ case SDL_JOYBUTTONDOWN:
+ case SDL_JOYBUTTONUP:
+ HandleJoystickEvent(event);
break;
+#endif
default:
break;
void ClearEventQueue()
{
- while(XPending(display))
+ while (PendingEvent())
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
+ NextEvent(&event);
switch(event.type)
{
- case ButtonRelease:
+ case EVENT_BUTTONRELEASE:
button_status = MB_RELEASED;
break;
- case KeyRelease:
+ case EVENT_KEYRELEASE:
key_joystick_mapping = 0;
break;
{
boolean window_unmapped = TRUE;
- XAutoRepeatOn(display);
+ KeyboardAutoRepeatOn();
while(window_unmapped)
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
+ NextEvent(&event);
switch(event.type)
{
- case ButtonRelease:
+ case EVENT_BUTTONRELEASE:
button_status = MB_RELEASED;
break;
- case KeyRelease:
+ case EVENT_KEYRELEASE:
key_joystick_mapping = 0;
break;
- case MapNotify:
+ case EVENT_MAPNOTIFY:
window_unmapped = FALSE;
break;
- case UnmapNotify:
+ case EVENT_UNMAPNOTIFY:
/* this is only to surely prevent the 'should not happen' case
* of recursively looping between 'SleepWhileUnmapped()' and
* 'HandleOtherEvents()' which usually calls this funtion.
}
if (game_status == PLAYING)
- XAutoRepeatOff(display);
+ KeyboardAutoRepeatOff();
}
-void HandleExposeEvent(XExposeEvent *event)
+void HandleExposeEvent(ExposeEvent *event)
{
+#ifndef TARGET_SDL
int x = event->x, y = event->y;
int width = event->width, height = event->height;
fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
fy += (ScreenMovDir & (MV_UP|MV_DOWN) ? ScreenGfxPos : 0);
- XCopyArea(display,fieldbuffer,backbuffer,gc,
- fx,fy, SXSIZE,SYSIZE,
- SX,SY);
+ BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
}
- XCopyArea(display,drawto,window,gc, x,y, width,height, x,y);
+ BlitBitmap(drawto, window, x,y, width,height, x,y);
- XFlush(display);
+ FlushDisplay();
+#endif
}
-void HandleButtonEvent(XButtonEvent *event)
+void HandleButtonEvent(ButtonEvent *event)
{
motion_status = FALSE;
- if (event->type == ButtonPress)
+ if (event->type == EVENT_BUTTONPRESS)
button_status = event->button;
else
button_status = MB_RELEASED;
HandleButton(event->x, event->y, button_status);
}
-void HandleMotionEvent(XMotionEvent *event)
+void HandleMotionEvent(MotionEvent *event)
{
- Window root, child;
- int root_x, root_y;
- int win_x, win_y;
- unsigned int mask;
-
- if (!XQueryPointer(display, window, &root, &child, &root_x, &root_y,
- &win_x, &win_y, &mask))
- return;
+ if (!PointerInWindow(window))
+ return; /* window and pointer are on different screens */
- if (!button_status && game_status != LEVELED)
+#if 1
+ if (button_status == MB_RELEASED && game_status != LEVELED)
return;
+#endif
motion_status = TRUE;
- HandleButton(win_x, win_y, button_status);
+ HandleButton(event->x, event->y, button_status);
}
-void HandleKeyEvent(XKeyEvent *event)
+void HandleKeyEvent(KeyEvent *event)
{
- int key_status = (event->type == KeyPress ? KEY_PRESSED : KEY_RELEASED);
- KeySym key;
-
- if (game_status == PLAYING)
- {
- /* use '0' instead of 'event->state' to get the key without modifiers */
- key = XLookupKeysym(event, 0);
- }
- else
- {
- /* get the key with all modifiers */
- char buffer[10];
- int buffer_size = 10;
- XComposeStatus compose;
- int char_count;
-
- char_count = XLookupString(event, buffer, buffer_size, &key, &compose);
- buffer[char_count] = '\0';
- }
+ int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED);
+ boolean with_modifiers = (game_status == PLAYING ? FALSE : TRUE);
+ Key key = GetEventKey(event, with_modifiers);
HandleKey(key, key_status);
}
-void HandleFocusEvent(XFocusChangeEvent *event)
+void HandleFocusEvent(FocusChangeEvent *event)
{
static int old_joystick_status = -1;
- if (event->type == FocusOut)
+ if (event->type == EVENT_FOCUSOUT)
{
int i;
- XAutoRepeatOn(display);
+ KeyboardAutoRepeatOn();
old_joystick_status = joystick_status;
joystick_status = JOYSTICK_OFF;
for (i=0; i<MAX_PLAYERS; i++)
stored_player[i].action = 0;
}
- else if (event->type == FocusIn)
+ else if (event->type == EVENT_FOCUSIN)
{
/* When there are two Rocks'n'Diamonds windows which overlap and
the player moves the pointer from one game window to the other,
if (game_status == PLAYING)
{
Delay(100);
- XAutoRepeatOff(display);
+ KeyboardAutoRepeatOff();
}
if (old_joystick_status != -1)
joystick_status = old_joystick_status;
}
}
-void HandleClientMessageEvent(XClientMessageEvent *event)
+void HandleClientMessageEvent(ClientMessageEvent *event)
{
-#ifndef MSDOS
- if ((event->window == window) &&
- (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
+ if (CheckCloseWindowEvent(event))
CloseAllAndExit(0);
-#endif
}
void HandleButton(int mx, int my, int button)
break;
case TYPENAME:
- HandleTypeName(0, XK_Return);
+ HandleTypeName(0, KSYM_Return);
break;
case CHOOSELEVEL:
}
}
-void HandleKey(KeySym key, int key_status)
+void HandleKey(Key key, int key_status)
{
int joy = 0;
+ boolean anyTextGadgetActiveOrJustFinished = anyTextGadgetActive();
static struct SetupKeyboardInfo custom_key;
static struct
{
- KeySym *keysym_custom;
- KeySym keysym_default;
+ Key *key_custom;
+ Key key_default;
byte action;
} key_info[] =
{
custom_key = setup.input[pnr].key;
for (i=0; i<6; i++)
- if (key == *key_info[i].keysym_custom)
+ if (key == *key_info[i].key_custom)
key_action |= key_info[i].action;
if (key_status == KEY_PRESSED)
int i;
for (i=0; i<6; i++)
- if (key == key_info[i].keysym_default)
+ if (key == key_info[i].key_default)
joy |= key_info[i].action;
}
if (key_status == KEY_RELEASED)
return;
- if ((key == XK_Return || key == XK_space) &&
+ if ((key == KSYM_Return || key == KSYM_space) &&
game_status == PLAYING && AllPlayersGone)
{
CloseDoor(DOOR_CLOSE_1);
}
/* allow quick escape to the main menu with the Escape key */
- if (key == XK_Escape && game_status != MAINMENU)
+ if (key == KSYM_Escape && game_status != MAINMENU)
{
CloseDoor(DOOR_CLOSE_1 | DOOR_OPEN_2 | DOOR_NO_DELAY);
game_status = MAINMENU;
case SETUPINPUT:
switch(key)
{
- case XK_Return:
- case XK_space:
+ case KSYM_Return:
+ case KSYM_space:
if (game_status == MAINMENU)
HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE);
else if (game_status == CHOOSELEVEL)
HandleSetupInputScreen(0,0, 0,0, MB_MENU_CHOICE);
break;
- case XK_Page_Up:
+ case KSYM_Page_Up:
if (game_status == CHOOSELEVEL)
HandleChooseLevel(0,0, 0,-SCR_FIELDY, MB_MENU_MARK);
break;
- case XK_Page_Down:
+ case KSYM_Page_Down:
if (game_status == CHOOSELEVEL)
HandleChooseLevel(0,0, 0,SCR_FIELDY, MB_MENU_MARK);
break;
case HALLOFFAME:
switch(key)
{
- case XK_Return:
- case XK_space:
+ case KSYM_Return:
+ case KSYM_space:
game_status = MAINMENU;
DrawMainMenu();
BackToFront();
break;
- case XK_Page_Up:
+ case KSYM_Page_Up:
HandleHallOfFame(0,0, 0,-SCR_FIELDY, MB_MENU_MARK);
break;
- case XK_Page_Down:
+ case KSYM_Page_Down:
HandleHallOfFame(0,0, 0,SCR_FIELDY, MB_MENU_MARK);
break;
break;
case LEVELED:
- HandleLevelEditorKeyInput(key);
+ if (!anyTextGadgetActiveOrJustFinished)
+ HandleLevelEditorKeyInput(key);
break;
case PLAYING:
{
#ifdef DEBUG
- case XK_0:
- case XK_1:
- case XK_2:
- case XK_3:
- case XK_4:
- case XK_5:
- case XK_6:
- case XK_7:
- case XK_8:
- case XK_9:
- if (key == XK_0)
+ case KSYM_0:
+ case KSYM_1:
+ case KSYM_2:
+ case KSYM_3:
+ case KSYM_4:
+ case KSYM_5:
+ case KSYM_6:
+ case KSYM_7:
+ case KSYM_8:
+ case KSYM_9:
+ if (key == KSYM_0)
{
if (GameFrameDelay == 500)
GameFrameDelay = GAME_FRAME_DELAY;
GameFrameDelay = 500;
}
else
- GameFrameDelay = (key - XK_0) * 10;
+ GameFrameDelay = (key - KSYM_0) * 10;
printf("Game speed == %d%% (%d ms delay between two frames)\n",
GAME_FRAME_DELAY * 100 / GameFrameDelay, GameFrameDelay);
break;
+ case KSYM_d:
+ if (options.debug)
+ {
+ options.debug = FALSE;
+ printf("debug mode disabled\n");
+ }
+ else
+ {
+ options.debug = TRUE;
+ printf("debug mode enabled\n");
+ }
+ break;
+
+ case KSYM_s:
+ if (!global.fps_slowdown)
+ {
+ global.fps_slowdown = TRUE;
+ global.fps_slowdown_factor = 2;
+ printf("fps slowdown enabled -- display only every 2nd frame\n");
+ }
+ else if (global.fps_slowdown_factor == 2)
+ {
+ global.fps_slowdown_factor = 4;
+ printf("fps slowdown enabled -- display only every 4th frame\n");
+ }
+ else
+ {
+ global.fps_slowdown = FALSE;
+ global.fps_slowdown_factor = 1;
+ printf("fps slowdown disabled\n");
+ }
+ break;
#if 0
- case XK_a:
+ case KSYM_a:
if (ScrollStepSize == TILEX/8)
ScrollStepSize = TILEX/4;
else
#endif
#if 0
- case XK_m:
+ case KSYM_m:
if (MoveSpeed == 8)
{
MoveSpeed = 4;
break;
#endif
- case XK_f:
+ case KSYM_f:
ScrollStepSize = TILEX/8;
printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize);
break;
- case XK_g:
+ case KSYM_g:
ScrollStepSize = TILEX/4;
printf("ScrollStepSize == %d (1/4)\n", ScrollStepSize);
break;
- case XK_h:
+ case KSYM_h:
ScrollStepSize = TILEX/2;
printf("ScrollStepSize == %d (1/2)\n", ScrollStepSize);
break;
- case XK_l:
+ case KSYM_l:
ScrollStepSize = TILEX;
printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
break;
-#ifndef MSDOS
- case XK_Q:
-#endif
- case XK_q:
+ case KSYM_Q:
+ case KSYM_q:
local_player->dynamite = 1000;
break;
#if 0
- case XK_z:
+ case KSYM_z:
{
int i;
}
}
-void HandleNoXEvent()
+void HandleNoEvent()
{
if (button_status && game_status != PLAYING)
{
return;
}
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (options.network)
HandleNetworking();
#endif
HandleJoystick();
-
- if (game_status == PLAYING)
- HandleGameActions();
}
static int HandleJoystickForAllPlayers()
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* events.h *
+* events.h *
***********************************************************/
#ifndef EVENTS_H
#include "main.h"
+int FilterMouseMotionEvents(const Event *);
void EventLoop(void);
-void HandleOtherEvents(XEvent *);
+void HandleOtherEvents(Event *);
void ClearEventQueue(void);
void SleepWhileUnmapped(void);
-void HandleExposeEvent(XExposeEvent *);
-void HandleButtonEvent(XButtonEvent *);
-void HandleMotionEvent(XMotionEvent *);
-void HandleKeyEvent(XKeyEvent *);
-void HandleFocusEvent(XFocusChangeEvent *);
-void HandleClientMessageEvent(XClientMessageEvent *event);
+void HandleExposeEvent(ExposeEvent *);
+void HandleButtonEvent(ButtonEvent *);
+void HandleMotionEvent(MotionEvent *);
+void HandleKeyEvent(KeyEvent *);
+void HandleFocusEvent(FocusChangeEvent *);
+void HandleClientMessageEvent(ClientMessageEvent *event);
-void HandleNoXEvent(void);
+void HandleNoEvent(void);
void HandleButton(int, int, int);
-void HandleKey(KeySym, int);
+void HandleKey(Key, int);
void HandleJoystick();
#endif
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* files.h *
+* files.c *
***********************************************************/
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
-#include <unistd.h>
+
+#include "libgame/libgame.h"
#include "files.h"
#include "tools.h"
-#include "misc.h"
#include "tape.h"
#include "joystick.h"
#define TAPE_COOKIE_10 "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0"
/* file names and filename extensions */
-#ifndef MSDOS
-#define USERDATA_DIRECTORY ".rocksndiamonds"
+#if !defined(PLATFORM_MSDOS)
#define LEVELSETUP_DIRECTORY "levelsetup"
#define SETUP_FILENAME "setup.conf"
#define LEVELSETUP_FILENAME "levelsetup.conf"
#define TAPEFILE_EXTENSION "tape"
#define SCOREFILE_EXTENSION "score"
#else
-#define USERDATA_DIRECTORY "userdata"
#define LEVELSETUP_DIRECTORY "lvlsetup"
#define SETUP_FILENAME "setup.cnf"
#define LEVELSETUP_FILENAME "lvlsetup.cnf"
#define LEVELFILE_EXTENSION "lvl"
#define TAPEFILE_EXTENSION "tap"
#define SCOREFILE_EXTENSION "sco"
-#define ERROR_FILENAME "error.out"
#endif
+#if defined(PLATFORM_WIN32)
+#ifndef S_IRGRP
+#define S_IRGRP S_IRUSR
+#endif
+#ifndef S_IROTH
+#define S_IROTH S_IRUSR
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP S_IWUSR
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH S_IWUSR
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP S_IXUSR
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH S_IXUSR
+#endif
+#endif /* PLATFORM_WIN32 */
+
/* file permissions for newly written files */
#define MODE_R_ALL (S_IRUSR | S_IRGRP | S_IROTH)
#define MODE_W_ALL (S_IWUSR | S_IWGRP | S_IWOTH)
#define MODE_X_ALL (S_IXUSR | S_IXGRP | S_IXOTH)
-#define USERDATA_DIR_MODE (MODE_R_ALL | MODE_X_ALL | S_IWUSR)
#define LEVEL_PERMS (MODE_R_ALL | MODE_W_ALL)
#define SCORE_PERMS LEVEL_PERMS
#define TAPE_PERMS LEVEL_PERMS
static void SaveUserLevelInfo(); /* for 'InitUserLevelDir()' */
static char *getSetupLine(char *, int); /* for 'SaveUserLevelInfo()' */
-char *getUserDataDir()
-{
- static char *userdata_dir = NULL;
-
- if (!userdata_dir)
- {
- char *home_dir = getHomeDir();
- char *data_dir = USERDATA_DIRECTORY;
-
- userdata_dir = getPath2(home_dir, data_dir);
- }
-
- return userdata_dir;
-}
-
static char *getSetupDir()
{
return getUserDataDir();
return filename;
}
-static void createDirectory(char *dir, char *text)
-{
- if (access(dir, F_OK) != 0)
- if (mkdir(dir, USERDATA_DIR_MODE) != 0)
- Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
-}
-
-static void InitUserDataDirectory()
-{
- createDirectory(getUserDataDir(), "user data");
-}
-
static void InitTapeDirectory(char *level_subdir)
{
createDirectory(getUserDataDir(), "user data");
/* always start with reliable default values */
setLevelInfoToDefaults();
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
return;
char *oldest_possible_cookie;
FILE *file;
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save level file '%s'", filename);
return;
/* at least one (default: the first) player participates in every tape */
num_participating_players = 1;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
return;
/* check file identifier */
}
}
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save level recording file '%s'", filename);
return;
highscore[i].Score = 0;
}
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
return;
/* check file identifier */
InitScoreDirectory(leveldir_current->filename);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save score for level %d", level_nr);
return;
#define SETUP_TOKEN_TEAM_MODE 10
#define SETUP_TOKEN_HANDICAP 11
#define SETUP_TOKEN_TIME_LIMIT 12
+#define SETUP_TOKEN_FULLSCREEN 13
/* player setup */
-#define SETUP_TOKEN_USE_JOYSTICK 13
-#define SETUP_TOKEN_JOY_DEVICE_NAME 14
-#define SETUP_TOKEN_JOY_XLEFT 15
-#define SETUP_TOKEN_JOY_XMIDDLE 16
-#define SETUP_TOKEN_JOY_XRIGHT 17
-#define SETUP_TOKEN_JOY_YUPPER 18
-#define SETUP_TOKEN_JOY_YMIDDLE 19
-#define SETUP_TOKEN_JOY_YLOWER 20
-#define SETUP_TOKEN_JOY_SNAP 21
-#define SETUP_TOKEN_JOY_BOMB 22
-#define SETUP_TOKEN_KEY_LEFT 23
-#define SETUP_TOKEN_KEY_RIGHT 24
-#define SETUP_TOKEN_KEY_UP 25
-#define SETUP_TOKEN_KEY_DOWN 26
-#define SETUP_TOKEN_KEY_SNAP 27
-#define SETUP_TOKEN_KEY_BOMB 28
+#define SETUP_TOKEN_USE_JOYSTICK 14
+#define SETUP_TOKEN_JOY_DEVICE_NAME 15
+#define SETUP_TOKEN_JOY_XLEFT 16
+#define SETUP_TOKEN_JOY_XMIDDLE 17
+#define SETUP_TOKEN_JOY_XRIGHT 18
+#define SETUP_TOKEN_JOY_YUPPER 19
+#define SETUP_TOKEN_JOY_YMIDDLE 20
+#define SETUP_TOKEN_JOY_YLOWER 21
+#define SETUP_TOKEN_JOY_SNAP 22
+#define SETUP_TOKEN_JOY_BOMB 23
+#define SETUP_TOKEN_KEY_LEFT 24
+#define SETUP_TOKEN_KEY_RIGHT 25
+#define SETUP_TOKEN_KEY_UP 26
+#define SETUP_TOKEN_KEY_DOWN 27
+#define SETUP_TOKEN_KEY_SNAP 28
+#define SETUP_TOKEN_KEY_BOMB 29
/* level directory info */
-#define LEVELINFO_TOKEN_NAME 29
-#define LEVELINFO_TOKEN_NAME_SHORT 30
-#define LEVELINFO_TOKEN_NAME_SORTING 31
-#define LEVELINFO_TOKEN_AUTHOR 32
-#define LEVELINFO_TOKEN_IMPORTED_FROM 33
-#define LEVELINFO_TOKEN_LEVELS 34
-#define LEVELINFO_TOKEN_FIRST_LEVEL 35
-#define LEVELINFO_TOKEN_SORT_PRIORITY 36
-#define LEVELINFO_TOKEN_LEVEL_GROUP 37
-#define LEVELINFO_TOKEN_READONLY 38
+#define LEVELINFO_TOKEN_NAME 30
+#define LEVELINFO_TOKEN_NAME_SHORT 31
+#define LEVELINFO_TOKEN_NAME_SORTING 32
+#define LEVELINFO_TOKEN_AUTHOR 33
+#define LEVELINFO_TOKEN_IMPORTED_FROM 34
+#define LEVELINFO_TOKEN_LEVELS 35
+#define LEVELINFO_TOKEN_FIRST_LEVEL 36
+#define LEVELINFO_TOKEN_SORT_PRIORITY 37
+#define LEVELINFO_TOKEN_LEVEL_GROUP 38
+#define LEVELINFO_TOKEN_READONLY 39
#define FIRST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_PLAYER_NAME
-#define LAST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_TIME_LIMIT
+#define LAST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_FULLSCREEN
#define FIRST_PLAYER_SETUP_TOKEN SETUP_TOKEN_USE_JOYSTICK
#define LAST_PLAYER_SETUP_TOKEN SETUP_TOKEN_KEY_BOMB
#define TYPE_BOOLEAN 1
#define TYPE_SWITCH 2
-#define TYPE_KEYSYM 3
+#define TYPE_KEY 3
#define TYPE_INTEGER 4
#define TYPE_STRING 5
{ TYPE_SWITCH, &si.team_mode, "team_mode" },
{ TYPE_SWITCH, &si.handicap, "handicap" },
{ TYPE_SWITCH, &si.time_limit, "time_limit" },
+ { TYPE_SWITCH, &si.fullscreen, "fullscreen" },
/* player setup */
{ TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" },
{ TYPE_INTEGER, &sii.joy.ylower, ".joy.ylower" },
{ TYPE_INTEGER, &sii.joy.snap, ".joy.snap_field" },
{ TYPE_INTEGER, &sii.joy.bomb, ".joy.place_bomb" },
- { TYPE_KEYSYM, &sii.key.left, ".key.move_left" },
- { TYPE_KEYSYM, &sii.key.right, ".key.move_right" },
- { TYPE_KEYSYM, &sii.key.up, ".key.move_up" },
- { TYPE_KEYSYM, &sii.key.down, ".key.move_down" },
- { TYPE_KEYSYM, &sii.key.snap, ".key.snap_field" },
- { TYPE_KEYSYM, &sii.key.bomb, ".key.place_bomb" },
+ { TYPE_KEY, &sii.key.left, ".key.move_left" },
+ { TYPE_KEY, &sii.key.right, ".key.move_right" },
+ { TYPE_KEY, &sii.key.up, ".key.move_up" },
+ { TYPE_KEY, &sii.key.down, ".key.move_down" },
+ { TYPE_KEY, &sii.key.snap, ".key.snap_field" },
+ { TYPE_KEY, &sii.key.bomb, ".key.place_bomb" },
/* level directory info */
{ TYPE_STRING, &ldi.name, "name" },
FILE *file;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
return NULL;
si->team_mode = FALSE;
si->handicap = TRUE;
si->time_limit = TRUE;
+ si->fullscreen = FALSE;
for (i=0; i<MAX_PLAYERS; i++)
{
si->input[i].joy.ylower = JOYSTICK_YLOWER;
si->input[i].joy.snap = (i == 0 ? JOY_BUTTON_1 : 0);
si->input[i].joy.bomb = (i == 0 ? JOY_BUTTON_2 : 0);
- si->input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KEY_UNDEFINDED);
- si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KEY_UNDEFINDED);
- si->input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KEY_UNDEFINDED);
- si->input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KEY_UNDEFINDED);
- si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KEY_UNDEFINDED);
- si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KEY_UNDEFINDED);
+ si->input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KSYM_UNDEFINED);
+ si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KSYM_UNDEFINED);
+ si->input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KSYM_UNDEFINED);
+ si->input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KSYM_UNDEFINED);
+ si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED);
+ si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED);
}
}
*(boolean *)setup_value = get_string_boolean_value(token_value);
break;
- case TYPE_KEYSYM:
- *(KeySym *)setup_value = getKeySymFromX11KeyName(token_value);
+ case TYPE_KEY:
+ *(Key *)setup_value = getKeyFromX11KeyName(token_value);
break;
case TYPE_INTEGER:
filename = getPath2(getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write level info file '%s'", filename);
free(filename);
strcat(entry, (*(boolean *)setup_value ? "on" : "off"));
break;
- case TYPE_KEYSYM:
+ case TYPE_KEY:
{
- KeySym keysym = *(KeySym *)setup_value;
- char *keyname = getKeyNameFromKeySym(keysym);
+ Key key = *(Key *)setup_value;
+ char *keyname = getKeyNameFromKey(key);
- strcat(entry, getX11KeyNameFromKeySym(keysym));
+ strcat(entry, getX11KeyNameFromKey(key));
for (i=strlen(entry); i<50; i++)
strcat(entry, " ");
filename = getPath2(getSetupDir(), SETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
level_directory = getPath2((leveldir_current->user_defined ?
getUserLevelDir("") :
options.level_directory),
- leveldir_current->filename);
+ leveldir_current->fullpath);
if ((dir = opendir(level_directory)) == NULL)
{
filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
chmod(filename, SETUP_PERMS);
}
-
-#ifdef MSDOS
-void initErrorFile()
-{
- char *filename;
-
- InitUserDataDirectory();
-
- filename = getPath2(getUserDataDir(), ERROR_FILENAME);
- unlink(filename);
- free(filename);
-}
-
-FILE *openErrorFile()
-{
- char *filename;
- FILE *error_file;
-
- filename = getPath2(getUserDataDir(), ERROR_FILENAME);
- error_file = fopen(filename, "a");
- free(filename);
-
- return error_file;
-}
-
-void dumpErrorFile()
-{
- char *filename;
- FILE *error_file;
-
- filename = getPath2(getUserDataDir(), ERROR_FILENAME);
- error_file = fopen(filename, "r");
- free(filename);
-
- if (error_file != NULL)
- {
- while (!feof(error_file))
- fputc(fgetc(error_file), stderr);
-
- fclose(error_file);
- }
-}
-#endif
+/* LocalWords: Rocks'n
+ */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* files.h *
+* files.h *
***********************************************************/
#ifndef FILES_H
void LoadLevelSetup_SeriesInfo(void);
void SaveLevelSetup_SeriesInfo(void);
-#ifdef MSDOS
-void initErrorFile();
-FILE *openErrorFile();
-void dumpErrorFile();
-#endif
-
#endif /* FILES_H */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* game.c *
+* 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"
void GetPlayerConfig()
{
- if (sound_status == SOUND_OFF)
+ if (!audio.sound_available)
setup.sound = FALSE;
- if (!sound_loops_allowed)
+ if (!audio.loops_available)
{
setup.sound_loops = FALSE;
setup.sound_music = FALSE;
}
+ if (!video.fullscreen_available)
+ setup.fullscreen = FALSE;
+
setup.sound_simple = setup.sound;
+ SetAudioMode(setup.sound);
InitJoysticks();
}
network_player_action_received = FALSE;
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
/* initial null action */
if (network_playing)
SendToServer_MovePlayer(MV_NO_MOVING);
ZX = ZY = -1;
- game.yam_content_nr = 0;
FrameCounter = 0;
TimeFrames = 0;
TimePlayed = 0;
ScrollStepSize = 0; /* will be correctly initialized by ScrollScreen() */
AllPlayersGone = FALSE;
+
+ game.yam_content_nr = 0;
game.magic_wall_active = FALSE;
game.magic_wall_time_left = 0;
game.light_time_left = 0;
DrawAllPlayers();
FadeToFront();
- /* after drawing the level, corect some elements */
-
+ /* after drawing the level, correct some elements */
if (game.timegate_time_left == 0)
CloseAllOpenTimegates();
if (setup.soft_scrolling)
- XCopyArea(display, fieldbuffer, backbuffer, gc,
- FX, FY, SXSIZE, SYSIZE, SX, SY);
+ BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
redraw_mask |= REDRAW_FROM_BACKBUFFER;
/* copy default game door content to main double buffer */
- XCopyArea(display, pix[PIX_DOOR], drawto, gc,
- DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+ BlitBitmap(pix[PIX_DOOR], drawto,
+ DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
if (level_nr < 100)
DrawText(DX + XX_LEVEL, DY + YY_LEVEL,
int2str(level_nr, 2), FS_SMALL, FC_YELLOW);
else
{
- DrawTextExt(drawto, gc, DX + XX_EMERALDS, DY + YY_EMERALDS,
+ DrawTextExt(drawto, DX + XX_EMERALDS, DY + YY_EMERALDS,
int2str(level_nr, 3), FS_SMALL, FC_SPECIAL3);
- XCopyArea(display, drawto, drawto, gc,
- DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
- FONT5_XSIZE * 3, FONT5_YSIZE - 1,
- DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
+ BlitBitmap(drawto, drawto,
+ DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
+ FONT5_XSIZE * 3, FONT5_YSIZE - 1,
+ DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
}
DrawText(DX + XX_EMERALDS, DY + YY_EMERALDS,
MapTapeButtons();
/* copy actual game door content to door double buffer for OpenDoor() */
- XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_ALL);
- if (setup.sound_music)
- PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
+ if (setup.sound_music && num_bg_loops)
+ PlayMusic(level_nr % num_bg_loops);
- XAutoRepeatOff(display);
+ KeyboardAutoRepeatOff();
if (options.verbose)
{
StopSound(SND_SIRR);
}
+#if 0
FadeSounds();
+#endif
/* Hero disappears */
DrawLevelField(ExitX, ExitY);
{
leveldir_current->handicap_level++;
SaveLevelSetup_SeriesInfo();
-
- if (level_nr < leveldir_current->last_level)
- raise_level = TRUE;
}
+ if (level_editor_test_game)
+ local_player->score = -1; /* no highscore when playing from editor */
+ else if (level_nr < leveldir_current->last_level)
+ raise_level = TRUE; /* advance to next level */
+
if ((hi_pos = NewHiScore()) >= 0)
{
game_status = HALLOFFAME;
dest_x = FX + SCREENX(x)*TILEX;
dest_y = FY + SCREENY(y)*TILEY;
- XCopyArea(display, drawto_field, window, gc,
- dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
+ BlitBitmap(drawto_field, window,
+ dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
SetDrawtoField(DRAW_DIRECT);
}
}
#endif
*/
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
/* last chance to get network player actions without main loop delay */
HandleNetworking();
#endif
stored_player[i].effective_action = stored_player[i].action;
}
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (network_playing)
SendToServer_MovePlayer(summarized_player_action);
#endif
}
DrawAllPlayers();
+
+ if (options.debug) /* calculate frames per second */
+ {
+ static unsigned long fps_counter = 0;
+ static int fps_frames = 0;
+ unsigned long fps_delay_ms = Counter() - fps_counter;
+
+ fps_frames++;
+
+ if (fps_delay_ms >= 500) /* calculate fps every 0.5 seconds */
+ {
+ global.frames_per_second = 1000 * (float)fps_frames / fps_delay_ms;
+
+ fps_frames = 0;
+ fps_counter = Counter();
+ }
+
+ redraw_mask |= REDRAW_FPS;
+ }
}
static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
int softscroll_offset = (setup.soft_scrolling ? TILEX : 0);
int x, y;
- XCopyArea(display, drawto_field, drawto_field, gc,
- FX + TILEX*(dx == -1) - softscroll_offset,
- FY + TILEY*(dy == -1) - softscroll_offset,
- SXSIZE - TILEX*(dx!=0) + 2*softscroll_offset,
- SYSIZE - TILEY*(dy!=0) + 2*softscroll_offset,
- FX + TILEX*(dx == 1) - softscroll_offset,
- FY + TILEY*(dy == 1) - softscroll_offset);
+ BlitBitmap(drawto_field, drawto_field,
+ FX + TILEX*(dx == -1) - softscroll_offset,
+ FY + TILEY*(dy == -1) - softscroll_offset,
+ SXSIZE - TILEX*(dx!=0) + 2*softscroll_offset,
+ SYSIZE - TILEY*(dy!=0) + 2*softscroll_offset,
+ FX + TILEX*(dx == 1) - softscroll_offset,
+ FY + TILEY*(dy == 1) - softscroll_offset);
if (dx)
{
RemoveField(x, y);
player->key[key_nr] = TRUE;
RaiseScoreElement(EL_SCHLUESSEL);
- DrawMiniGraphicExt(drawto, gc,
- DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1+key_nr);
- DrawMiniGraphicExt(window, gc,
- DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1+key_nr);
+ DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ GFX_SCHLUESSEL1 + key_nr);
+ DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ GFX_SCHLUESSEL1 + key_nr);
PlaySoundLevel(x, y, SND_PONG);
break;
}
RemoveField(x, y);
player->key[key_nr] = TRUE;
RaiseScoreElement(EL_SCHLUESSEL);
- DrawMiniGraphicExt(drawto, gc,
- DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1+key_nr);
- DrawMiniGraphicExt(window, gc,
- DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1+key_nr);
+ DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ GFX_SCHLUESSEL1 + key_nr);
+ DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ GFX_SCHLUESSEL1 + key_nr);
PlaySoundLevel(x, y, SND_PONG);
break;
}
volume = PSND_MAX_VOLUME;
-#ifndef MSDOS
+#if !defined(PLATFORM_MSDOS)
stereo = (sx - SCR_FIELDX/2) * 12;
#else
stereo = PSND_MIDDLE + (2 * sx - (SCR_FIELDX - 1)) * 5;
for (i=0; i<NUM_GAME_BUTTONS; i++)
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
struct GadgetInfo *gi;
int button_type;
boolean checked;
GDI_TYPE, button_type,
GDI_STATE, GD_BUTTON_UNPRESSED,
GDI_CHECKED, checked,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y1,
- GDI_ALT_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y2,
- GDI_ALT_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ 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_ACTION, HandleGameButtons,
GDI_END);
Request("Do you really want to quit the game ?",
REQ_ASK | REQ_STAY_CLOSED))
{
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (options.network)
SendToServer_StopPlaying();
else
case GAME_CTRL_ID_PAUSE:
if (options.network)
{
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (tape.pausing)
SendToServer_ContinuePlaying();
else
case GAME_CTRL_ID_PLAY:
if (tape.pausing)
{
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (options.network)
SendToServer_ContinuePlaying();
else
if (setup.sound_music)
{
setup.sound_music = FALSE;
- FadeSound(background_loop[level_nr % num_bg_loops]);
+ FadeMusic();
}
- else if (sound_loops_allowed)
+ else if (audio.loops_available)
{
setup.sound = setup.sound_music = TRUE;
- PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
+ if (num_bg_loops)
+ PlayMusic(level_nr % num_bg_loops);
}
break;
case SOUND_CTRL_ID_LOOPS:
if (setup.sound_loops)
setup.sound_loops = FALSE;
- else if (sound_loops_allowed)
+ else if (audio.loops_available)
setup.sound = setup.sound_loops = TRUE;
break;
case SOUND_CTRL_ID_SIMPLE:
if (setup.sound_simple)
setup.sound_simple = FALSE;
- else if (sound_status==SOUND_AVAILABLE)
+ else if (audio.sound_available)
setup.sound = setup.sound_simple = TRUE;
break;
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* game.h *
+* game.h *
***********************************************************/
#ifndef GAME_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 *
-*----------------------------------------------------------*
-* image.c *
-***********************************************************/
-
-#include "image.h"
-#include "pcx.h"
-#include "misc.h"
-
-/* exclude all except newImage() and freeImage() */
-#ifndef MSDOS
-
-/* 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);
-}
-
-#endif /* !MSDOS */
-
-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);
-}
-
-#ifndef MSDOS
-
-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 /* !MSDOS */
+++ /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 "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;
-
-int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
-
-Image *newImage(unsigned int, unsigned int, unsigned int);
-void freeImage(Image *);
-void freeXImage(Image *, XImageInfo *);
-
-#endif /* IMAGE_H */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* init.c *
+* init.c *
***********************************************************/
-#include <signal.h>
+#include "libgame/libgame.h"
#include "init.h"
-#include "misc.h"
-#include "sound.h"
+#include "events.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"
-struct PictureFileInfo
-{
- char *picture_filename;
- boolean picture_with_mask;
-};
-
-struct IconFileInfo
-{
- char *picture_filename;
- char *picturemask_filename;
-};
-
-static int sound_process_id = 0;
-
-static void InitLevelAndPlayerInfo(void);
+static void InitPlayerInfo(void);
+static void InitLevelInfo(void);
static void InitNetworkServer(void);
-static void InitDisplay(void);
static void InitSound(void);
-static void InitSoundServer(void);
-static void InitWindow(int, char **);
static void InitGfx(void);
-static void LoadGfx(int, struct PictureFileInfo *);
+static void InitGfxBackground(void);
static void InitGadgets(void);
static void InitElementProperties(void);
-void OpenAll(int argc, char *argv[])
+void OpenAll(void)
{
-#ifdef MSDOS
- initErrorFile();
-#endif
-
if (options.serveronly)
{
+#if defined(PLATFORM_UNIX)
NetworkServer(options.server_port, options.serveronly);
-
- /* never reached */
- exit(0);
+#else
+ Error(ERR_WARN, "networking only supported in Unix version");
+#endif
+ exit(0); /* never reached */
}
+ InitProgramInfo(UNIX_USERDATA_DIRECTORY,
+ PROGRAM_TITLE_STRING, WINDOW_TITLE_STRING,
+ ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
+ MSDOS_POINTER_FILENAME);
+
+ InitPlayerInfo();
+
InitCounter();
InitSound();
- InitSoundServer();
InitJoysticks();
InitRND(NEW_RANDOMIZE);
- signal(SIGINT, CloseAllAndExit);
- signal(SIGTERM, CloseAllAndExit);
-
- InitDisplay();
- InitWindow(argc, argv);
+ InitVideoDisplay();
+ InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH,
+ setup.fullscreen);
- XMapWindow(display, window);
- XFlush(display);
+ InitEventFilter(FilterMouseMotionEvents);
InitGfx();
InitElementProperties(); /* initializes IS_CHAR() for el2gfx() */
- InitLevelAndPlayerInfo();
+ InitLevelInfo();
InitGadgets(); /* needs to know number of level series */
+ InitGfxBackground();
DrawMainMenu();
InitNetworkServer();
}
-void InitLevelAndPlayerInfo()
+void InitPlayerInfo()
{
int i;
local_player->connected = TRUE;
- LoadLevelInfo(); /* global level info */
LoadSetup(); /* global setup info */
+}
+
+void InitLevelInfo()
+{
+ LoadLevelInfo(); /* global level info */
LoadLevelSetup_LastSeries(); /* last played series info */
LoadLevelSetup_SeriesInfo(); /* last played level info */
}
void InitNetworkServer()
{
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
int nr_wanted;
#endif
if (!options.network)
return;
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
if (!ConnectToServer(options.server_host, options.server_port))
{
int i;
- if (sound_status == SOUND_OFF)
- return;
+ OpenAudio();
-#ifndef MSDOS
- if (access(sound_device_name, W_OK) != 0)
+ for(i=0; i<NUM_SOUNDS; i++)
{
- Error(ERR_WARN, "cannot access sound device - no sounds");
- sound_status = SOUND_OFF;
- return;
- }
+ if (!LoadSound(sound_name[i]))
+ {
+ audio.sound_available = FALSE;
+ audio.loops_available = FALSE;
+ audio.sound_enabled = FALSE;
- if ((sound_device = open(sound_device_name,O_WRONLY))<0)
- {
- Error(ERR_WARN, "cannot open sound device - no sounds");
- sound_status = SOUND_OFF;
- return;
+ return;
+ }
}
- close(sound_device);
- sound_status = SOUND_AVAILABLE;
-
-#ifdef VOXWARE
- sound_loops_allowed = TRUE;
+ num_bg_loops = LoadMusic();
- /*
- setup.sound_loops_on = TRUE;
- */
+ StartSoundserver();
+}
+void InitJoysticks()
+{
+#if defined(TARGET_SDL)
+ static boolean sdl_joystick_subsystem_initialized = FALSE;
#endif
-#else /* MSDOS */
- sound_loops_allowed = TRUE;
- /*
- setup.sound_loops_on = TRUE;
- */
+ int i;
-#endif /* MSDOS */
+ if (global_joystick_status == JOYSTICK_OFF)
+ return;
- for(i=0; i<NUM_SOUNDS; i++)
+ joystick_status = JOYSTICK_OFF;
+
+#if defined(TARGET_SDL)
+
+ if (!sdl_joystick_subsystem_initialized)
{
-#ifdef MSDOS
- sprintf(sound_name[i], "%d", i + 1);
-#endif
+ sdl_joystick_subsystem_initialized = TRUE;
- Sound[i].name = sound_name[i];
- if (!LoadSound(&Sound[i]))
+ if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
{
- sound_status = SOUND_OFF;
+ Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
return;
}
}
-}
-
-void InitSoundServer()
-{
- if (sound_status == SOUND_OFF)
- return;
-
-#ifndef MSDOS
-
- if (pipe(sound_pipe)<0)
- {
- Error(ERR_WARN, "cannot create pipe - no sounds");
- sound_status = SOUND_OFF;
- return;
- }
-
- if ((sound_process_id = fork()) < 0)
- {
- Error(ERR_WARN, "cannot create sound server process - no sounds");
- sound_status = SOUND_OFF;
- return;
- }
- if (!sound_process_id) /* we are child */
+ for (i=0; i<MAX_PLAYERS; i++)
{
- SoundServer();
+ char *device_name = setup.input[i].joy.device_name;
+ int joystick_nr = getJoystickNrFromDeviceName(device_name);
- /* never reached */
- exit(0);
- }
- else /* we are parent */
- close(sound_pipe[0]); /* no reading from pipe needed */
+ if (joystick_nr >= SDL_NumJoysticks())
+ joystick_nr = -1;
-#else /* MSDOS */
+ /* misuse joystick file descriptor variable to store joystick number */
+ stored_player[i].joystick_fd = joystick_nr;
- SoundServer();
+ /* this allows subsequent calls to 'InitJoysticks' for re-initialization */
+ if (Check_SDL_JoystickOpened(joystick_nr))
+ Close_SDL_Joystick(joystick_nr);
-#endif /* MSDOS */
-}
+ if (!setup.input[i].use_joystick)
+ continue;
-void InitJoysticks()
-{
- int i;
+ if (!Open_SDL_Joystick(joystick_nr))
+ {
+ Error(ERR_WARN, "cannot open joystick %d", joystick_nr);
+ continue;
+ }
- if (global_joystick_status == JOYSTICK_OFF)
- return;
+ joystick_status = JOYSTICK_AVAILABLE;
+ }
- joystick_status = JOYSTICK_OFF;
+#else /* !TARGET_SDL */
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
for (i=0; i<MAX_PLAYERS; i++)
{
char *device_name = setup.input[i].joy.device_name;
joystick_status = JOYSTICK_AVAILABLE;
}
-#else /* MSDOS */
+#else /* !PLATFORM_UNIX */
/* try to access two joysticks; if that fails, try to access just one */
if (install_joystick(JOY_TYPE_2PADS) == 0 ||
stored_player[i].joystick_fd = joystick_nr;
}
#endif
-}
-
-void InitDisplay()
-{
-#ifndef 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);
-
-#ifndef 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
-}
-
-void InitWindow(int argc, char *argv[])
-{
- unsigned int border_width = 4;
- XGCValues gc_values;
- unsigned long gc_valuemask;
-#ifndef 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;
-
-#ifndef 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);
-
-#ifndef 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,
- argv, argc, &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 */
- 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);
+#endif /* !TARGET_SDL */
}
void InitGfx()
{
- int i,j;
+ int i;
+
+#if defined(TARGET_X11)
GC copy_clipmask_gc;
XGCValues clip_gc_values;
unsigned long clip_gc_valuemask;
+#endif
-#ifdef MSDOS
- static struct PictureFileInfo pic[NUM_PICTURES] =
- {
- { "Screen", TRUE },
- { "Door", TRUE },
- { "Heroes", TRUE },
- { "Toons", TRUE },
- { "SP", TRUE },
- { "DC", TRUE },
- { "More", TRUE },
- { "Font", FALSE },
- { "Font2", FALSE },
- { "Font3", FALSE }
+#if !defined(PLATFORM_MSDOS)
+ static char *image_filename[NUM_PICTURES] =
+ {
+ "RocksScreen.pcx",
+ "RocksDoor.pcx",
+ "RocksHeroes.pcx",
+ "RocksToons.pcx",
+ "RocksSP.pcx",
+ "RocksDC.pcx",
+ "RocksMore.pcx",
+ "RocksFont.pcx",
+ "RocksFont2.pcx",
+ "RocksFont3.pcx"
};
#else
- static struct PictureFileInfo pic[NUM_PICTURES] =
- {
- { "RocksScreen", TRUE },
- { "RocksDoor", TRUE },
- { "RocksHeroes", TRUE },
- { "RocksToons", TRUE },
- { "RocksSP", TRUE },
- { "RocksDC", TRUE },
- { "RocksMore", TRUE },
- { "RocksFont", FALSE },
- { "RocksFont2", FALSE },
- { "RocksFont3", FALSE }
+ static char *image_filename[NUM_PICTURES] =
+ {
+ "Screen.pcx",
+ "Door.pcx",
+ "Heroes.pcx",
+ "Toons.pcx",
+ "SP.pcx",
+ "DC.pcx",
+ "More.pcx",
+ "Font.pcx",
+ "Font2.pcx",
+ "Font3.pcx"
};
#endif
-#ifdef DEBUG
-#if 0
- static struct PictureFileInfo test_pic1 =
- {
- "RocksFont2",
- FALSE
- };
- static struct PictureFileInfo test_pic2 =
- {
- "mouse",
- FALSE
- };
-#endif
-#endif
-
+#if defined(TARGET_X11_NATIVE)
static struct
{
int start;
{ GFX2_SHIELD_ACTIVE, 3 },
{ -1, 0 }
};
-
-#if DEBUG_TIMING
- debug_print_timestamp(0, NULL); /* initialize timestamp function */
#endif
-#ifdef DEBUG
-#if 0
- printf("Test: Loading RocksFont2.pcx ...\n");
- LoadGfx(PIX_SMALLFONT,&test_pic1);
- printf("Test: Done.\n");
- printf("Test: Loading mouse.pcx ...\n");
- LoadGfx(PIX_SMALLFONT,&test_pic2);
- printf("Test: Done.\n");
-#endif
-#endif
-
-
-
- LoadGfx(PIX_SMALLFONT,&pic[PIX_SMALLFONT]);
- DrawInitText(WINDOW_TITLE_STRING,20,FC_YELLOW);
- DrawInitText(COPYRIGHT_STRING,50,FC_RED);
-#ifdef MSDOS
- DrawInitText("MSDOS version done by Guido Schulz",210,FC_BLUE);
+ /* initialize some global variables */
+ global.frames_per_second = 0;
+ global.fps_slowdown = FALSE;
+ global.fps_slowdown_factor = 1;
+
+ /* initialize screen properties */
+ InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
+ REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
+ InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
+ InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+
+ /* create additional image buffers for double-buffering */
+ pix[PIX_DB_DOOR] = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
+ pix[PIX_DB_FIELD] = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
+
+ pix[PIX_SMALLFONT] = LoadImage(image_filename[PIX_SMALLFONT]);
+ InitFontInfo(NULL, NULL, pix[PIX_SMALLFONT]);
+
+ DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW);
+ DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED);
+#if defined(PLATFORM_MSDOS)
+ DrawInitText(PROGRAM_DOS_PORT_STRING, 210, FC_BLUE);
rest(200);
-#endif /* MSDOS */
+#endif
DrawInitText("Loading graphics:",120,FC_GREEN);
for(i=0; i<NUM_PICTURES; i++)
+ {
if (i != PIX_SMALLFONT)
- LoadGfx(i,&pic[i]);
+ {
+ DrawInitText(image_filename[i], 150, FC_YELLOW);
+ pix[i] = LoadImage(image_filename[i]);
+ }
+ }
-#if DEBUG_TIMING
- debug_print_timestamp(0, "SUMMARY LOADING ALL GRAPHICS:");
-#endif
+ InitFontInfo(pix[PIX_BIGFONT], pix[PIX_MEDIUMFONT], pix[PIX_SMALLFONT]);
- pix[PIX_DB_BACK] = XCreatePixmap(display, window,
- WIN_XSIZE,WIN_YSIZE,
- XDefaultDepth(display,screen));
- pix[PIX_DB_DOOR] = XCreatePixmap(display, window,
- 3*DXSIZE,DYSIZE+VYSIZE,
- XDefaultDepth(display,screen));
- pix[PIX_DB_FIELD] = XCreatePixmap(display, window,
- FXSIZE,FYSIZE,
- XDefaultDepth(display,screen));
+ /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */
+ for(i=0; i<NUM_TILES; i++)
+ tile_clipmask[i] = None;
+#if defined(TARGET_X11)
+ /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is
+ often very slow when preparing a masked XCopyArea() for big Pixmaps.
+ To prevent this, create small (tile-sized) mask Pixmaps which will then
+ be set much faster with XSetClipOrigin() and speed things up a lot. */
+
+ /* create graphic context structures needed for clipping */
clip_gc_values.graphics_exposures = False;
clip_gc_valuemask = GCGraphicsExposures;
copy_clipmask_gc =
- XCreateGC(display,clipmask[PIX_BACK],clip_gc_valuemask,&clip_gc_values);
+ XCreateGC(display, pix[PIX_BACK]->clip_mask,
+ clip_gc_valuemask, &clip_gc_values);
clip_gc_values.graphics_exposures = False;
clip_gc_valuemask = GCGraphicsExposures;
tile_clip_gc =
- XCreateGC(display,window,clip_gc_valuemask,&clip_gc_values);
+ XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values);
- /* initialize pixmap array to Pixmap 'None' */
- for(i=0; i<NUM_TILES; i++)
- tile_clipmask[i] = None;
+ for(i=0; i<NUM_BITMAPS; i++)
+ {
+ if (pix[i]->clip_mask)
+ {
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_values.clip_mask = pix[i]->clip_mask;
+ clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
+ pix[i]->stored_clip_gc = XCreateGC(display, window->drawable,
+ clip_gc_valuemask,&clip_gc_values);
+ }
+ }
+#if defined(TARGET_X11_NATIVE)
/* create only those clipping Pixmaps we really need */
for(i=0; tile_needs_clipping[i].start>=0; i++)
{
+ int j;
+
for(j=0; j<tile_needs_clipping[i].count; j++)
{
int tile = tile_needs_clipping[i].start + j;
Pixmap src_pixmap;
getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
- src_pixmap = clipmask[pixmap_nr];
+ src_pixmap = pix[pixmap_nr]->clip_mask;
- tile_clipmask[tile] = XCreatePixmap(display, window, TILEX,TILEY, 1);
+ tile_clipmask[tile] = XCreatePixmap(display, window->drawable,
+ TILEX, TILEY, 1);
- XCopyArea(display,src_pixmap,tile_clipmask[tile],copy_clipmask_gc,
- src_x,src_y, TILEX,TILEY, 0,0);
+ XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc,
+ src_x, src_y, TILEX, TILEY, 0, 0);
}
}
+#endif /* TARGET_X11_NATIVE */
+#endif /* TARGET_X11 */
+}
- if (!pix[PIX_DB_BACK] || !pix[PIX_DB_DOOR])
- Error(ERR_EXIT, "cannot create additional pixmaps");
-
- for(i=0; i<NUM_PIXMAPS; i++)
- {
- if (clipmask[i])
- {
- clip_gc_values.graphics_exposures = False;
- clip_gc_values.clip_mask = clipmask[i];
- clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
- clip_gc[i] = XCreateGC(display,window,clip_gc_valuemask,&clip_gc_values);
- }
- }
+void InitGfxBackground()
+{
+ int x, y;
- drawto = backbuffer = pix[PIX_DB_BACK];
+ drawto = backbuffer;
fieldbuffer = pix[PIX_DB_FIELD];
SetDrawtoField(DRAW_BACKBUFFER);
- XCopyArea(display,pix[PIX_BACK],backbuffer,gc,
- 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
- XFillRectangle(display,pix[PIX_DB_BACK],gc,
- REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
- XFillRectangle(display,pix[PIX_DB_DOOR],gc,
- 0,0, 3*DXSIZE,DYSIZE+VYSIZE);
+ BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
+ ClearRectangle(backbuffer, REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE);
+ ClearRectangle(pix[PIX_DB_DOOR], 0,0, 3*DXSIZE,DYSIZE+VYSIZE);
- for(i=0; i<MAX_BUF_XSIZE; i++)
- for(j=0; j<MAX_BUF_YSIZE; j++)
- redraw[i][j] = 0;
+ for(x=0; x<MAX_BUF_XSIZE; x++)
+ for(y=0; y<MAX_BUF_YSIZE; y++)
+ redraw[x][y] = 0;
redraw_tiles = 0;
redraw_mask = REDRAW_ALL;
}
-void LoadGfx(int pos, struct PictureFileInfo *pic)
-{
- char basefilename[256];
- char filename[256];
-
-#ifdef USE_XPM_LIBRARY
- int xpm_err, xbm_err;
- unsigned int width,height;
- int hot_x,hot_y;
- Pixmap shapemask;
- char *picture_ext = ".xpm";
- char *picturemask_ext = "Mask.xbm";
-#else
- int pcx_err;
- char *picture_ext = ".pcx";
-#endif
-
- /* Grafik laden */
- if (pic->picture_filename)
- {
- sprintf(basefilename, "%s%s", pic->picture_filename, picture_ext);
- DrawInitText(basefilename, 150, FC_YELLOW);
- sprintf(filename, "%s/%s/%s",
- options.ro_base_directory, GRAPHICS_DIRECTORY, basefilename);
-
-#ifdef MSDOS
- rest(100);
-#endif /* MSDOS */
-
-#if DEBUG_TIMING
- debug_print_timestamp(1, NULL); /* initialize timestamp function */
-#endif
-
-#ifdef USE_XPM_LIBRARY
-
- xpm_att[pos].valuemask = XpmCloseness;
- xpm_att[pos].closeness = 20000;
- xpm_err = XpmReadFileToPixmap(display,window,filename,
- &pix[pos],&shapemask,&xpm_att[pos]);
- switch(xpm_err)
- {
- case XpmOpenFailed:
- Error(ERR_EXIT, "cannot open XPM file '%s'", filename);
- case XpmFileInvalid:
- Error(ERR_EXIT, "invalid XPM file '%s'", filename);
- case XpmNoMemory:
- Error(ERR_EXIT, "not enough memory for XPM file '%s'", filename);
- case XpmColorFailed:
- Error(ERR_EXIT, "cannot get colors for XPM file '%s'", filename);
- default:
- break;
- }
-
-#if DEBUG_TIMING
- printf("LOADING XPM FILE %s:", filename);
- debug_print_timestamp(1, "");
-#endif
-
-#else /* !USE_XPM_LIBRARY */
-
- pcx_err = Read_PCX_to_Pixmap(display, window, gc, filename,
- &pix[pos], &clipmask[pos]);
- switch(pcx_err)
- {
- case PCX_Success:
- break;
- case PCX_OpenFailed:
- Error(ERR_EXIT, "cannot open PCX file '%s'", filename);
- case PCX_ReadFailed:
- Error(ERR_EXIT, "cannot read PCX file '%s'", filename);
- case PCX_FileInvalid:
- Error(ERR_EXIT, "invalid PCX file '%s'", filename);
- case PCX_NoMemory:
- Error(ERR_EXIT, "not enough memory for PCX file '%s'", filename);
- case PCX_ColorFailed:
- Error(ERR_EXIT, "cannot get colors for PCX file '%s'", filename);
- default:
- break;
- }
-
-#if DEBUG_TIMING
- printf("SUMMARY LOADING PCX FILE %s:", filename);
- debug_print_timestamp(1, "");
-#endif
-
-#endif /* !USE_XPM_LIBRARY */
-
- if (!pix[pos])
- Error(ERR_EXIT, "cannot get graphics for '%s'", pic->picture_filename);
- }
-
- /* zugehörige Maske laden (wenn vorhanden) */
- if (pic->picture_with_mask)
- {
-#ifdef USE_XPM_LIBRARY
-
- sprintf(basefilename, "%s%s", pic->picture_filename, picturemask_ext);
- DrawInitText(basefilename, 150, FC_YELLOW);
- sprintf(filename, "%s/%s/%s",
- options.ro_base_directory, GRAPHICS_DIRECTORY, basefilename);
-
-#if DEBUG_TIMING
- debug_print_timestamp(1, NULL); /* initialize timestamp function */
-#endif
-
- xbm_err = XReadBitmapFile(display,window,filename,
- &width,&height,&clipmask[pos],&hot_x,&hot_y);
- switch(xbm_err)
- {
- case BitmapSuccess:
- break;
- case BitmapOpenFailed:
- Error(ERR_EXIT, "cannot open XBM file '%s'", filename);
- case BitmapFileInvalid:
- Error(ERR_EXIT, "invalid XBM file '%s'", filename);
- case BitmapNoMemory:
- Error(ERR_EXIT, "not enough memory for XBM file '%s'", filename);
- break;
- default:
- break;
- }
-
-#if DEBUG_TIMING
- printf("LOADING XBM FILE %s:", filename);
- debug_print_timestamp(1, "");
-#endif
-
-#endif /* USE_XPM_LIBRARY */
-
- if (!clipmask[pos])
- Error(ERR_EXIT, "cannot get clipmask for '%s'", pic->picture_filename);
- }
-}
-
void InitGadgets()
{
CreateLevelEditorGadgets();
for(j=0; j<*(ep2_num[i]); j++)
Elementeigenschaften2[(ep2_array[i])[j]] |= ep2_bit[i];
- for(i=EL_CHAR_START; i<EL_CHAR_END; i++)
+ for(i=EL_CHAR_START; i<=EL_CHAR_END; i++)
Elementeigenschaften1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE);
}
{
int i;
- if (sound_process_id)
- {
- StopSounds();
- kill(sound_process_id, SIGTERM);
- FreeSounds(NUM_SOUNDS);
- }
-
- for(i=0; i<NUM_PIXMAPS; i++)
- {
- if (pix[i])
- {
-#ifdef USE_XPM_LIBRARY
- if (i < NUM_PICTURES) /* XPM pictures */
- {
- XFreeColors(display,DefaultColormap(display,screen),
- xpm_att[i].pixels,xpm_att[i].npixels,0);
- XpmFreeAttributes(&xpm_att[i]);
- }
-#endif
- XFreePixmap(display,pix[i]);
- }
- if (clipmask[i])
- XFreePixmap(display,clipmask[i]);
- if (clip_gc[i])
- XFreeGC(display, clip_gc[i]);
- }
-
- if (gc)
- XFreeGC(display, gc);
+ StopSounds();
+ FreeSounds(NUM_SOUNDS);
+ CloseAudio();
- if (display)
- {
- XAutoRepeatOn(display);
- XCloseDisplay(display);
- }
+ for(i=0; i<NUM_BITMAPS; i++)
+ FreeBitmap(pix[i]);
+ CloseVideoDisplay();
-#ifdef MSDOS
- dumpErrorFile();
-#endif
+ ClosePlatformDependantStuff();
exit(exit_value);
}
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* init.h *
+* init.h *
***********************************************************/
#ifndef INIT_H
#include "main.h"
-void OpenAll(int, char **);
+void OpenAll(void);
void CloseAllAndExit(int);
void InitJoysticks(void);
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* joystick.c *
+* joystick.c *
***********************************************************/
-#ifdef __FreeBSD__
+#if defined(PLATFORM_FREEBSD)
#include <machine/joystick.h>
#endif
+#include "libgame/libgame.h"
+
#include "joystick.h"
-#include "misc.h"
-void CheckJoystickData()
+#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;
- int distance = 100;
- for(i=0; i<MAX_PLAYERS; i++)
+ if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME)
{
- if (setup.input[i].joy.xmiddle <= distance)
- setup.input[i].joy.xmiddle = distance;
- if (setup.input[i].joy.ymiddle <= distance)
- setup.input[i].joy.ymiddle = distance;
+ *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;
+ }
+ }
+ }
+}
- if (setup.input[i].joy.xleft >= setup.input[i].joy.xmiddle)
- setup.input[i].joy.xleft = setup.input[i].joy.xmiddle - distance;
- if (setup.input[i].joy.xright <= setup.input[i].joy.xmiddle)
- setup.input[i].joy.xright = setup.input[i].joy.xmiddle + distance;
+char *getJoyNameFromJoySymbol(int joysymbol)
+{
+ char *name;
- if (setup.input[i].joy.yupper >= setup.input[i].joy.ymiddle)
- setup.input[i].joy.yupper = setup.input[i].joy.ymiddle - distance;
- if (setup.input[i].joy.ylower <= setup.input[i].joy.ymiddle)
- setup.input[i].joy.ylower = setup.input[i].joy.ymiddle + distance;
- }
+ translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME);
+ return name;
}
-#ifndef MSDOS
+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;
+}
+
+#if !defined(PLATFORM_MSDOS)
static int JoystickPosition(int middle, int margin, int actual)
{
long range, pos;
}
#endif
-#ifndef MSDOS
+#if defined(TARGET_SDL)
+
+static SDL_Joystick *sdl_joystick[MAX_PLAYERS] = { NULL, NULL, NULL, NULL };
+static int sdl_js_axis[MAX_PLAYERS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
+static int sdl_js_button[MAX_PLAYERS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
+
+SDL_Joystick *Get_SDL_Joystick(int nr)
+{
+ return sdl_joystick[nr];
+}
+
+boolean Open_SDL_Joystick(int nr)
+{
+ if (nr < 0 || nr > MAX_PLAYERS)
+ return FALSE;
+
+ return ((sdl_joystick[nr] = SDL_JoystickOpen(nr)) == NULL ? FALSE : TRUE);
+}
+
+void Close_SDL_Joystick(int nr)
+{
+ if (nr < 0 || nr > MAX_PLAYERS)
+ return;
+
+ SDL_JoystickClose(sdl_joystick[nr]);
+}
+
+boolean Check_SDL_JoystickOpened(int nr)
+{
+ if (nr < 0 || nr > MAX_PLAYERS)
+ return FALSE;
+
+ return (SDL_JoystickOpened(nr) ? TRUE : FALSE);
+}
+
+void HandleJoystickEvent(Event *event)
+{
+ switch(event->type)
+ {
+ case SDL_JOYAXISMOTION:
+ if (event->jaxis.axis < 2)
+ {
+ sdl_js_axis[event->jaxis.which][event->jaxis.axis]= event->jaxis.value;
+
+#if 0
+ printf("js_%d %s-axis: %d\n",
+ event->jaxis.which,
+ (event->jaxis.axis == 0 ? "x" : "y"),
+ event->jaxis.value);
+#endif
+ }
+ break;
+
+ case SDL_JOYBUTTONDOWN:
+ if (event->jbutton.button < 2)
+ {
+ sdl_js_button[event->jbutton.which][event->jbutton.button] = TRUE;
+
+#if 0
+ printf("js_%d button %d: pressed\n",
+ event->jbutton.which,
+ event->jbutton.button);
+#endif
+ }
+ break;
+
+ case SDL_JOYBUTTONUP:
+ if (event->jbutton.button < 2)
+ {
+ sdl_js_button[event->jbutton.which][event->jbutton.button] = FALSE;
+
+#if 0
+ printf("js_%d button %d: released\n",
+ event->jbutton.which,
+ event->jbutton.button);
+#endif
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+int Get_SDL_Joystick_Axis(int nr, int axis)
+{
+ if (nr < 0 || nr > MAX_PLAYERS)
+ return 0;
+
+ if (axis < 0 || axis > 1)
+ return 0;
+
+ return sdl_js_axis[nr][axis];
+}
+
+void CheckJoystickData()
+{
+}
+
+int Joystick(int player_nr)
+{
+ int joystick_nr = stored_player[player_nr].joystick_fd;
+ int js_x,js_y, js_b1,js_b2;
+ int left, right, up, down;
+ int result = 0;
+
+ if (joystick_status == JOYSTICK_OFF)
+ return 0;
+
+ if (game_status == SETUPINPUT)
+ return 0;
+
+ if (!setup.input[player_nr].use_joystick ||
+ !Check_SDL_JoystickOpened(joystick_nr))
+ return 0;
+
+ js_x = sdl_js_axis[joystick_nr][0];
+ js_y = sdl_js_axis[joystick_nr][1];
+
+ js_b1 = sdl_js_button[joystick_nr][0];
+ js_b2 = sdl_js_button[joystick_nr][1];
+
+
+
+#if 0
+ printf("JOYSTICK %d: js_x == %d, js_y == %d, js_b1 == %d, js_b2 == %d\n",
+ joystick_nr, js_x, js_y, js_b1, js_b2);
+#endif
+
+
+
+ left = JoystickPosition(setup.input[player_nr].joy.xmiddle,
+ setup.input[player_nr].joy.xleft, js_x);
+ right = JoystickPosition(setup.input[player_nr].joy.xmiddle,
+ setup.input[player_nr].joy.xright, js_x);
+ up = JoystickPosition(setup.input[player_nr].joy.ymiddle,
+ setup.input[player_nr].joy.yupper, js_y);
+ down = JoystickPosition(setup.input[player_nr].joy.ymiddle,
+ setup.input[player_nr].joy.ylower, js_y);
+
+ if (left > JOYSTICK_PERCENT)
+ result |= JOY_LEFT;
+ else if (right > JOYSTICK_PERCENT)
+ result |= JOY_RIGHT;
+ if (up > JOYSTICK_PERCENT)
+ result |= JOY_UP;
+ else if (down > JOYSTICK_PERCENT)
+ result |= JOY_DOWN;
+
+ if (js_b1)
+ result |= JOY_BUTTON_1;
+ if (js_b2)
+ result |= JOY_BUTTON_2;
+
+
+
+#if 0
+ printf("result == 0x%08x\n", result);
+#endif
+
+
+
+ return result;
+}
+
+#else /* !TARGET_SDL */
+
+void CheckJoystickData()
+{
+ int i;
+ int distance = 100;
+
+ for(i=0; i<MAX_PLAYERS; i++)
+ {
+ if (setup.input[i].joy.xmiddle <= distance)
+ setup.input[i].joy.xmiddle = distance;
+ if (setup.input[i].joy.ymiddle <= distance)
+ setup.input[i].joy.ymiddle = distance;
+
+ if (setup.input[i].joy.xleft >= setup.input[i].joy.xmiddle)
+ setup.input[i].joy.xleft = setup.input[i].joy.xmiddle - distance;
+ if (setup.input[i].joy.xright <= setup.input[i].joy.xmiddle)
+ setup.input[i].joy.xright = setup.input[i].joy.xmiddle + distance;
+
+ if (setup.input[i].joy.yupper >= setup.input[i].joy.ymiddle)
+ setup.input[i].joy.yupper = setup.input[i].joy.ymiddle - distance;
+ if (setup.input[i].joy.ylower <= setup.input[i].joy.ymiddle)
+ setup.input[i].joy.ylower = setup.input[i].joy.ymiddle + distance;
+ }
+}
+
+#if defined(PLATFORM_UNIX)
int Joystick(int player_nr)
{
#ifdef __FreeBSD__
return result;
}
-#else /* MSDOS */
+#else /* PLATFORM_MSDOS */
/* allegro global variables for joystick control */
extern int num_joysticks;
return 0;
/* the allegro global variable 'num_joysticks' contains the number
- of joysticks found at initialization under MSDOS / Windows */
+ of joysticks found at initialization under MS-DOS / Windows */
#if 0
if (joystick_nr >= num_joysticks || !setup.input[player_nr].use_joystick)
return result;
}
-#endif /* MSDOS */
+#endif /* PLATFORM_MSDOS */
+
+#endif /* !TARGET_SDL */
int JoystickButton(int player_nr)
{
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* joystick.h *
+* joystick.h *
***********************************************************/
#ifndef 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"
/* 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
#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
+#endif /* JOYSTICK_H */
--- /dev/null
+#=============================================================================#
+# Makefile for Artsoft Retro-Game Library #
+# (c) 1994-2000 Holger Schemel, info@artsoft.org #
+#=============================================================================#
+
+SRCS = system.c \
+ gadgets.c \
+ text.c \
+ sound.c \
+ pcx.c \
+ image.c \
+ random.c \
+ misc.c \
+ msdos.c \
+ x11.c \
+ sdl.c
+
+OBJS = system.o \
+ gadgets.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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* gadgets.c *
+***********************************************************/
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "gadgets.h"
+#include "text.h"
+#include "misc.h"
+
+
+/* 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 < gfx.sx + gfx.sxsize ? REDRAW_FIELD :
+ gi->y < gfx.dy + gfx.dysize ? REDRAW_DOOR_1 :
+ gi->y > gfx.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 < gfx.sx + gfx.sxsize) ||
+ (mode & MULTIMAP_DOOR_1 &&
+ gi->x >= gfx.dx && gi->y < gfx.dy + gfx.dysize) ||
+ (mode & MULTIMAP_DOOR_2 &&
+ gi->x >= gfx.dx && gi->y > gfx.dy + gfx.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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* gadgets.h *
+***********************************************************/
+
+#ifndef GADGETS_H
+#define GADGETS_H
+
+#include "system.h"
+
+
+#define GADGET_FRAME_DELAY 150 /* delay between gadget actions */
+
+/* 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 /* GADGETS_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* image.c *
+***********************************************************/
+
+#include "image.h"
+#include "pcx.h"
+#include "misc.h"
+
+
+#if defined(TARGET_X11)
+
+/* 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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* image.h *
+***********************************************************/
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include "system.h"
+
+
+#if defined(TARGET_X11)
+
+#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_X11 */
+
+#endif /* IMAGE_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* libgame.h *
+***********************************************************/
+
+#ifndef LIBGAME_H
+#define LIBGAME_H
+
+#define LIBGAME_VERSION_1_0_0
+
+#include "platform.h"
+#include "types.h"
+#include "system.h"
+#include "random.h"
+#include "gadgets.h"
+#include "text.h"
+#include "sound.h"
+#include "image.h"
+#include "pcx.h"
+#include "misc.h"
+
+#endif /* LIBGAME_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* misc.c *
+***********************************************************/
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "platform.h"
+
+#if !defined(PLATFORM_WIN32)
+#include <pwd.h>
+#include <sys/param.h>
+#endif
+
+#include "misc.h"
+#include "random.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 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;
+
+ 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.command_basename);
+ 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;
+ char *newline = "\n";
+
+ /* display warnings only when running in verbose mode */
+ if (mode & ERR_WARN && !options.verbose)
+ return;
+
+#if !defined(PLATFORM_UNIX)
+ newline = "\r\n";
+
+ if ((error = openErrorFile()) == NULL)
+ {
+ printf("Cannot write to error output file!%s", newline);
+ program.exit_function(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.command_basename, process_name);
+
+ if (mode & ERR_WARN)
+ fprintf(error, "warning: ");
+
+ va_start(ap, format);
+ vfprintf(error, format, ap);
+ va_end(ap);
+
+ fprintf(error, "%s", newline);
+ }
+
+ if (mode & ERR_HELP)
+ fprintf(error, "%s: Try option '--help' for more information.%s",
+ program.command_basename, newline);
+
+ if (mode & ERR_EXIT)
+ fprintf(error, "%s%s: aborting%s",
+ program.command_basename, process_name, newline);
+
+ if (error != stderr)
+ fclose(error);
+
+ if (mode & ERR_EXIT)
+ {
+ if (mode & ERR_FROM_SERVER)
+ exit(1); /* child process: normal exit */
+ else
+ program.exit_function(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;
+}
+
+void *checked_realloc(void *ptr, unsigned long size)
+{
+ ptr = realloc(ptr, 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;
+}
+
+/* ------------------------------------------------------------------------- */
+/* 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;
+}
+
+
+/* ========================================================================= */
+/* some stuff from "files.c" */
+/* ========================================================================= */
+
+#define MODE_R_ALL (S_IRUSR | S_IRGRP | S_IROTH)
+#define MODE_W_ALL (S_IWUSR | S_IWGRP | S_IWOTH)
+#define MODE_X_ALL (S_IXUSR | S_IXGRP | S_IXOTH)
+#define USERDATA_DIR_MODE (MODE_R_ALL | MODE_X_ALL | S_IWUSR)
+
+char *getUserDataDir(void)
+{
+ static char *userdata_dir = NULL;
+
+ if (!userdata_dir)
+ {
+ char *home_dir = getHomeDir();
+ char *data_dir = program.userdata_directory;
+
+ userdata_dir = getPath2(home_dir, data_dir);
+ }
+
+ return userdata_dir;
+}
+
+void createDirectory(char *dir, char *text)
+{
+ if (access(dir, F_OK) != 0)
+#if defined(PLATFORM_WIN32)
+ if (mkdir(dir) != 0)
+#else
+ if (mkdir(dir, USERDATA_DIR_MODE) != 0)
+#endif
+ Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
+}
+
+void InitUserDataDirectory()
+{
+ createDirectory(getUserDataDir(), "user data");
+}
+
+
+/* ========================================================================= */
+/* functions only needed for non-Unix (non-command-line) systems */
+/* ========================================================================= */
+
+#if !defined(PLATFORM_UNIX)
+
+#define ERROR_FILENAME "error.out"
+
+void initErrorFile()
+{
+ char *filename;
+
+ InitUserDataDirectory();
+
+ filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+ unlink(filename);
+ free(filename);
+}
+
+FILE *openErrorFile()
+{
+ char *filename;
+ FILE *error_file;
+
+ filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+ error_file = fopen(filename, MODE_APPEND);
+ free(filename);
+
+ return error_file;
+}
+
+void dumpErrorFile()
+{
+ char *filename;
+ FILE *error_file;
+
+ filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+ error_file = fopen(filename, MODE_READ);
+ free(filename);
+
+ if (error_file != NULL)
+ {
+ while (!feof(error_file))
+ fputc(fgetc(error_file), stderr);
+
+ fclose(error_file);
+ }
+}
+#endif
+
+
+/* ========================================================================= */
+/* 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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* misc.h *
+***********************************************************/
+
+#ifndef MISC_H
+#define MISC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "system.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 GetOptions(char **);
+void Error(int, char *, ...);
+void *checked_malloc(unsigned long);
+void *checked_calloc(unsigned long);
+void *checked_realloc(void *, 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 *);
+
+char *getUserDataDir(void);
+void createDirectory(char *, char *);
+void InitUserDataDirectory(void);
+
+#if !defined(PLATFORM_UNIX)
+void initErrorFile();
+FILE *openErrorFile();
+void dumpErrorFile();
+#endif
+
+void debug_print_timestamp(int, char *);
+
+#endif /* MISC_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* msdos.c *
+***********************************************************/
+
+#include "system.h"
+
+
+#if defined(PLATFORM_MSDOS)
+
+#include "sound.h"
+#include "misc.h"
+#include "pcx.h"
+
+#define AllegroDefaultScreen() (display->screens[display->default_screen])
+
+/* 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;
+ }
+}
+
+Pixel AllegroAllocColorCell(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++;
+
+ i = global_colormap_entries_used - 1;
+
+ global_colormap[i].r = r;
+ global_colormap[i].g = g;
+ global_colormap[i].b = b;
+
+ set_palette(global_colormap);
+
+ pixel_mapping = i;
+ }
+
+ return pixel_mapping;
+}
+
+void XMapWindow(Display *display, Window window)
+{
+ int x, y;
+ unsigned int width, height;
+ boolean mouse_off;
+
+ x = AllegroDefaultScreen().x;
+ y = AllegroDefaultScreen().y;
+ width = AllegroDefaultScreen().width;
+ height = AllegroDefaultScreen().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);
+}
+
+Display *XOpenDisplay(char *display_name)
+{
+ Screen *screen;
+ Display *display;
+ BITMAP *mouse_bitmap = NULL;
+
+ mouse_bitmap = Read_PCX_to_AllegroBitmap(program.msdos_pointer_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 = AllegroAllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
+ screen[0].black_pixel = AllegroAllocColorCell(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);
+
+ AllegroDefaultScreen().video_bitmap = video_bitmap;
+ AllegroDefaultScreen().x = x;
+ AllegroDefaultScreen().y = y;
+ AllegroDefaultScreen().width = XRES;
+ AllegroDefaultScreen().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(AllegroDefaultScreen().x + 1,
+ AllegroDefaultScreen().y + 1,
+ AllegroDefaultScreen().x + video.width + 1,
+ AllegroDefaultScreen().y + video.height + 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 += AllegroDefaultScreen().x;
+ y += AllegroDefaultScreen().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 == gfx.scrollbuffer_width && height == gfx.scrollbuffer_height)
+ 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 += AllegroDefaultScreen().x;
+ src_y += AllegroDefaultScreen().y;
+ }
+
+ if ((BITMAP *)dest == video_bitmap)
+ {
+ dest_x += AllegroDefaultScreen().x;
+ dest_y += AllegroDefaultScreen().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] = AllegroAllocColorCell(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;
+#if 0
+ *pixmap_mask = (Pixmap)bitmap;
+ /* !!! two pointers on same bitmap => second free() fails !!! */
+#else
+ /* pixmap_mask will never be used in Allegro (which uses masked_blit()),
+ so use non-NULL dummy pointer to empty Pixmap */
+ /*
+ *pixmap_mask = (Pixmap)checked_calloc(sizeof(Pixmap));
+ */
+ *pixmap_mask = (Pixmap)DUMMY_MASK;
+#endif
+
+ 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 XUnmapWindow(Display *display, Window window)
+{
+}
+
+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 - AllegroDefaultScreen().x;
+ xmotion->y = mouse_y - AllegroDefaultScreen().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 - AllegroDefaultScreen().x;
+ xbutton->y = mouse_y - AllegroDefaultScreen().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 += AllegroDefaultScreen().x;
+ y1 += AllegroDefaultScreen().y;
+ x2 += AllegroDefaultScreen().x;
+ y2 += AllegroDefaultScreen().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)
+{
+}
+
+void XDestroyWindow(Display *display, Window window)
+{
+}
+
+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 - AllegroDefaultScreen().x;
+ *win_y = mouse_y - AllegroDefaultScreen().y;
+
+ return True;
+}
+
+void XAutoRepeatOn(Display *display)
+{
+ keyboard_auto_repeat = TRUE;
+ clear_keybuf();
+}
+
+void XAutoRepeatOff(Display *display)
+{
+ keyboard_auto_repeat = FALSE;
+}
+
+void AllegroDrawLine(Drawable d, int from_x, int from_y, int to_x, int to_y,
+ Pixel color)
+{
+ boolean mouse_off = FALSE;
+
+ if ((BITMAP *)d == video_bitmap)
+ {
+ int dx = AllegroDefaultScreen().x;
+ int dy = AllegroDefaultScreen().y;
+ int x1, y1, x2, y2;
+
+ from_x += dx;
+ from_y += dy;
+ to_x += dx;
+ to_y += dy;
+
+ x1 = (from_x < to_x ? from_x : to_x);
+ y1 = (from_y < to_y ? from_y : to_y);
+ x2 = (from_x < to_x ? to_x : from_x);
+ y2 = (from_y < to_y ? to_y : from_y);
+
+ freeze_mouse_flag = TRUE;
+ mouse_off = hide_mouse(display, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ }
+
+ line((BITMAP *)d, from_x, from_y, to_x, to_y, color);
+
+ if (mouse_off)
+ unhide_mouse(display);
+
+ freeze_mouse_flag = FALSE;
+}
+
+Pixel AllegroGetPixel(Drawable d, int x, int y)
+{
+ return getpixel((BITMAP *)d, x, y);
+}
+
+void MSDOSOpenAudio(void)
+{
+ if (allegro_init_audio())
+ {
+ audio.sound_available = TRUE;
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
+ audio.sound_enabled = TRUE;
+ }
+
+ InitPlaylist();
+}
+
+void 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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* msdos.h *
+***********************************************************/
+
+#ifndef MSDOS_H
+#define MSDOS_H
+
+#include <time.h>
+#include "allegro.h"
+
+
+/* symbol 'window' is defined in DJGPP cross-compiler in libc.a(conio.o) */
+#define window window_djgpp
+
+/* symbol 'font' is defined in "allegro.h" */
+#define font font_allegro
+
+/* 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 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 LineSolid 0
+#define LineOnOffDash 1
+#define LineDoubleDash 2
+
+#define CapNotLast 0
+#define CapButt 1
+#define CapRound 2
+#define CapProjecting 3
+
+#define JoinMiter 0
+#define JoinRound 1
+#define JoinBevel 2
+
+#define GCForeground (1L << 2)
+#define GCBackground (1L << 3)
+#define GCLineWidth (1L << 4)
+#define GCLineStyle (1L << 5)
+#define GCCapStyle (1L << 6)
+#define GCJoinStyle (1L << 7)
+#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;
+ int line_width; /* line width */
+ int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
+ int cap_style; /* CapNotLast, CapButt,
+ CapRound, CapProjecting */
+ int join_style; /* JoinMiter, JoinRound, JoinBevel */
+
+} 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;
+
+Pixel AllegroAllocColorCell(int, int, int);
+
+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 XUnmapWindow(Display *, Window);
+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 *);
+void XDestroyWindow(Display *, Window);
+Bool XQueryPointer(Display *, Window, Window *, Window *, int *, int *,
+ int *, int *, unsigned int *);
+void XAutoRepeatOn(Display *);
+void XAutoRepeatOff(Display *);
+
+void AllegroDrawLine(Drawable, int, int, int, int, Pixel);
+Pixel AllegroGetPixel(Drawable, int, int);
+
+void MSDOSOpenAudio(void);
+void MSDOSCloseAudio(void);
+
+void NetworkServer(int, int);
+
+#endif /* MSDOS_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* pcx.c *
+***********************************************************/
+
+#ifndef TARGET_SDL
+
+#include <stdio.h>
+
+#include "pcx.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, MODE_READ)))
+ {
+ 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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* pcx.h *
+***********************************************************/
+
+#ifndef PCX_H
+#define PCX_H
+
+#include "system.h"
+#include "image.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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* 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 MS-DOS platform */
+/* ========================================================================= */
+
+#if defined(PLATFORM_MSDOS)
+
+#ifndef TARGET_ALLEGRO
+#define TARGET_ALLEGRO
+#endif
+
+#ifndef TARGET_X11
+#define TARGET_X11
+#endif
+
+#endif
+
+/* ========================================================================= */
+/* define additional keywords for several Unix platforms */
+/* ========================================================================= */
+
+#if defined(PLATFORM_UNIX) && defined(TARGET_X11)
+#define TARGET_X11_NATIVE
+#endif
+
+#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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* random.c *
+***********************************************************/
+
+/*
+ * 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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* random.h *
+***********************************************************/
+
+#ifndef RANDOM_H
+#define RANDOM_H
+
+void srandom_linux_libc(unsigned int);
+long int random_linux_libc(void);
+
+#endif
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* sdl.c *
+***********************************************************/
+
+#include "system.h"
+#include "sound.h"
+#include "misc.h"
+
+
+#if defined(TARGET_SDL)
+
+/* ========================================================================= */
+/* video functions */
+/* ========================================================================= */
+
+inline void SDLInitVideoDisplay(void)
+{
+ /* initialize SDL video */
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
+
+ /* set default SDL depth */
+ video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
+}
+
+inline void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window,
+ boolean fullscreen)
+{
+ /* open SDL video output device (window or fullscreen mode) */
+ if (!SDLSetVideoMode(backbuffer, fullscreen))
+ Error(ERR_EXIT, "setting video mode failed");
+
+ /* set window and icon title */
+ SDL_WM_SetCaption(program.window_title, program.window_title);
+
+ /* 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. */
+
+ /* create additional (symbolic) buffer for double-buffering */
+ *window = CreateBitmap(video.width, video.height, video.depth);
+}
+
+inline boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen)
+{
+ boolean success = TRUE;
+ int surface_flags_fullscreen = SURFACE_FLAGS | SDL_FULLSCREEN;
+ int surface_flags_window = SURFACE_FLAGS;
+ SDL_Surface *new_surface = NULL;
+
+ if (*backbuffer == NULL)
+ *backbuffer = CreateBitmapStruct();
+
+ if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available)
+ {
+ /* switch display to fullscreen mode, if available */
+ if ((new_surface = SDL_SetVideoMode(video.width, video.height,
+ video.depth, surface_flags_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
+ {
+ (*backbuffer)->surface = new_surface;
+
+ video.fullscreen_enabled = TRUE;
+ success = TRUE;
+ }
+ }
+
+ if ((!fullscreen && video.fullscreen_enabled) || new_surface == NULL)
+ {
+ /* switch display to window mode */
+ if ((new_surface = SDL_SetVideoMode(video.width, video.height,
+ video.depth, surface_flags_window))
+ == NULL)
+ {
+ /* switching display to window mode failed -- should not happen */
+ Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
+
+ success = FALSE;
+ }
+ else
+ {
+ (*backbuffer)->surface = new_surface;
+
+ video.fullscreen_enabled = FALSE;
+ success = TRUE;
+ }
+ }
+
+ return success;
+}
+
+inline void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y,
+ int width, int height,
+ int dst_x, int dst_y, int copy_mode)
+{
+ Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
+ 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_bitmap != backbuffer || dst_bitmap != window)
+ SDL_BlitSurface((copy_mode == SDLCOPYAREA_MASKED ?
+ src_bitmap->surface_masked : src_bitmap->surface),
+ &src_rect, real_dst_bitmap->surface, &dst_rect);
+
+ if (dst_bitmap == window)
+ SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
+}
+
+inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y,
+ int width, int height, unsigned int color)
+{
+ Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
+ 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(real_dst_bitmap->surface, &rect,
+ SDL_MapRGB(real_dst_bitmap->surface->format,
+ color_r, color_g, color_b));
+
+ if (dst_bitmap == window)
+ SDL_UpdateRect(backbuffer->surface, 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 void SDLDrawLine(SDL_Surface *surface, int from_x, int from_y,
+ int to_x, int to_y, Uint32 color)
+{
+ sge_Line(surface, from_x, from_y, to_x, to_y, color);
+}
+
+#if 0
+inline void SDLDrawLines(SDL_Surface *surface, struct XY *points,
+ int num_points, Uint32 color)
+{
+ int i, x, y;
+ int line_width = 4;
+
+ for (i=0; i<num_points - 1; i++)
+ {
+ for (x=0; x<line_width; x++)
+ {
+ for (y=0; y<line_width; y++)
+ {
+ int dx = x - line_width / 2;
+ int dy = y - line_width / 2;
+
+ if ((x == 0 && y == 0) ||
+ (x == 0 && y == line_width - 1) ||
+ (x == line_width - 1 && y == 0) ||
+ (x == line_width - 1 && y == line_width - 1))
+ continue;
+
+ sge_Line(surface, points[i].x + dx, points[i].y + dy,
+ points[i+1].x + dx, points[i+1].y + dy, color);
+ }
+ }
+ }
+}
+#endif
+
+
+/* ========================================================================= */
+/* The following functions have been taken from the SGE library */
+/* (SDL Graphics Extension Library) by Anders Lindström */
+/* http://www.etek.chalmers.se/~e8cal1/sge/index.html */
+/* ========================================================================= */
+
+void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ if (x >= 0 && x <= surface->w - 1 && y >= 0 && y <= surface->h - 1)
+ {
+ switch (surface->format->BytesPerPixel)
+ {
+ case 1:
+ {
+ /* Assuming 8-bpp */
+ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
+ }
+ break;
+
+ case 2:
+ {
+ /* Probably 15-bpp or 16-bpp */
+ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
+ }
+ break;
+
+ case 3:
+ {
+ /* Slow 24-bpp mode, usually not used */
+ Uint8 *pix;
+ int shift;
+
+ /* Gack - slow, but endian correct */
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
+ shift = surface->format->Rshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Gshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Bshift;
+ *(pix+shift/8) = color>>shift;
+ }
+ break;
+
+ case 4:
+ {
+ /* Probably 32-bpp */
+ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
+ }
+ break;
+ }
+ }
+}
+
+void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+ Uint8 R, Uint8 G, Uint8 B)
+{
+ _PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
+}
+
+void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
+}
+
+void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
+}
+
+void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ Uint8 *pix;
+ int shift;
+
+ /* Gack - slow, but endian correct */
+ pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
+ shift = surface->format->Rshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Gshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Bshift;
+ *(pix+shift/8) = color>>shift;
+}
+
+void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
+}
+
+void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
+{
+ switch (dest->format->BytesPerPixel)
+ {
+ case 1:
+ *((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
+ break;
+
+ case 2:
+ *((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
+ break;
+
+ case 3:
+ _PutPixel24(dest,x,y,color);
+ break;
+
+ case 4:
+ *((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
+ break;
+ }
+}
+
+void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+{
+ if (SDL_MUSTLOCK(surface))
+ {
+ if (SDL_LockSurface(surface) < 0)
+ {
+ return;
+ }
+ }
+
+ _PutPixel(surface, x, y, color);
+
+ if (SDL_MUSTLOCK(surface))
+ {
+ SDL_UnlockSurface(surface);
+ }
+}
+
+void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+ Uint8 R, Uint8 G, Uint8 B)
+{
+ sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
+}
+
+Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
+{
+ if (y >= 0 && y <= dest->h - 1)
+ {
+ switch (dest->format->BytesPerPixel)
+ {
+ case 1:
+ return y*dest->pitch;
+ break;
+
+ case 2:
+ return y*dest->pitch/2;
+ break;
+
+ case 3:
+ return y*dest->pitch;
+ break;
+
+ case 4:
+ return y*dest->pitch/4;
+ break;
+ }
+ }
+
+ return -1;
+}
+
+void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
+{
+ if (x >= 0 && x <= surface->w - 1 && ypitch >= 0)
+ {
+ switch (surface->format->BytesPerPixel)
+ {
+ case 1:
+ {
+ /* Assuming 8-bpp */
+ *((Uint8 *)surface->pixels + ypitch + x) = color;
+ }
+ break;
+
+ case 2:
+ {
+ /* Probably 15-bpp or 16-bpp */
+ *((Uint16 *)surface->pixels + ypitch + x) = color;
+ }
+ break;
+
+ case 3:
+ {
+ /* Slow 24-bpp mode, usually not used */
+ Uint8 *pix;
+ int shift;
+
+ /* Gack - slow, but endian correct */
+ pix = (Uint8 *)surface->pixels + ypitch + x*3;
+ shift = surface->format->Rshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Gshift;
+ *(pix+shift/8) = color>>shift;
+ shift = surface->format->Bshift;
+ *(pix+shift/8) = color>>shift;
+ }
+ break;
+
+ case 4:
+ {
+ /* Probably 32-bpp */
+ *((Uint32 *)surface->pixels + ypitch + x) = color;
+ }
+ break;
+ }
+ }
+}
+
+void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+ Uint32 Color)
+{
+ SDL_Rect l;
+
+ if (SDL_MUSTLOCK(Surface))
+ {
+ if (SDL_LockSurface(Surface) < 0)
+ {
+ return;
+ }
+ }
+
+ if (x1 > x2)
+ {
+ Sint16 tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+
+ /* Do the clipping */
+ if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
+ return;
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 > Surface->w - 1)
+ x2 = Surface->w - 1;
+
+ l.x = x1;
+ l.y = y;
+ l.w = x2 - x1 + 1;
+ l.h = 1;
+
+ SDL_FillRect(Surface, &l, Color);
+
+ if (SDL_MUSTLOCK(Surface))
+ {
+ SDL_UnlockSurface(Surface);
+ }
+}
+
+void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+ Uint8 R, Uint8 G, Uint8 B)
+{
+ sge_HLine(Surface, x1, x2, y, SDL_MapRGB(Surface->format, R, G, B));
+}
+
+void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
+{
+ SDL_Rect l;
+
+ if (x1 > x2)
+ {
+ Sint16 tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+
+ /* Do the clipping */
+ if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
+ return;
+ if (x1 < 0)
+ x1 = 0;
+ if (x2 > Surface->w - 1)
+ x2 = Surface->w - 1;
+
+ l.x = x1;
+ l.y = y;
+ l.w = x2 - x1 + 1;
+ l.h = 1;
+
+ SDL_FillRect(Surface, &l, Color);
+}
+
+void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+ Uint32 Color)
+{
+ SDL_Rect l;
+
+ if (SDL_MUSTLOCK(Surface))
+ {
+ if (SDL_LockSurface(Surface) < 0)
+ {
+ return;
+ }
+ }
+
+ if (y1 > y2)
+ {
+ Sint16 tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ /* Do the clipping */
+ if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
+ return;
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 > Surface->h - 1)
+ y2 = Surface->h - 1;
+
+ l.x = x;
+ l.y = y1;
+ l.w = 1;
+ l.h = y2 - y1 + 1;
+
+ SDL_FillRect(Surface, &l, Color);
+
+ if (SDL_MUSTLOCK(Surface))
+ {
+ SDL_UnlockSurface(Surface);
+ }
+}
+
+void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+ Uint8 R, Uint8 G, Uint8 B)
+{
+ sge_VLine(Surface, x, y1, y2, SDL_MapRGB(Surface->format, R, G, B));
+}
+
+void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
+{
+ SDL_Rect l;
+
+ if (y1 > y2)
+ {
+ Sint16 tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ /* Do the clipping */
+ if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
+ return;
+ if (y1 < 0)
+ y1 = 0;
+ if (y2 > Surface->h - 1)
+ y2 = Surface->h - 1;
+
+ l.x = x;
+ l.y = y1;
+ l.w = 1;
+ l.h = y2 - y1 + 1;
+
+ SDL_FillRect(Surface, &l, Color);
+}
+
+void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
+ Sint16 x2, Sint16 y2, Uint32 Color,
+ void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+ Uint32 Color))
+{
+ Sint16 dx, dy, sdx, sdy, x, y, px, py;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+
+ sdx = (dx < 0) ? -1 : 1;
+ sdy = (dy < 0) ? -1 : 1;
+
+ dx = sdx * dx + 1;
+ dy = sdy * dy + 1;
+
+ x = y = 0;
+
+ px = x1;
+ py = y1;
+
+ if (dx >= dy)
+ {
+ for (x = 0; x < dx; x++)
+ {
+ Callback(Surface, px, py, Color);
+
+ y += dy;
+ if (y >= dx)
+ {
+ y -= dx;
+ py += sdy;
+ }
+
+ px += sdx;
+ }
+ }
+ else
+ {
+ for (y = 0; y < dy; y++)
+ {
+ Callback(Surface, px, py, Color);
+
+ x += dx;
+ if (x >= dy)
+ {
+ x -= dy;
+ px += sdx;
+ }
+
+ py += sdy;
+ }
+ }
+}
+
+void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
+ Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
+ void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+ Uint32 Color))
+{
+ sge_DoLine(Surface, X1, Y1, X2, Y2,
+ SDL_MapRGB(Surface->format, R, G, B), Callback);
+}
+
+void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
+ Uint32 Color)
+{
+ if (SDL_MUSTLOCK(Surface))
+ {
+ if (SDL_LockSurface(Surface) < 0)
+ return;
+ }
+
+ /* Draw the line */
+ sge_DoLine(Surface, x1, y1, x2, y2, Color, _PutPixel);
+
+ /* unlock the display */
+ if (SDL_MUSTLOCK(Surface))
+ {
+ SDL_UnlockSurface(Surface);
+ }
+}
+
+void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
+ Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
+{
+ sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B));
+}
+
+Bitmap *SDLLoadImage(char *filename)
+{
+ Bitmap *new_bitmap = CreateBitmapStruct();
+ SDL_Surface *sdl_image_tmp;
+
+ /* load image to temporary surface */
+ if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
+ Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError());
+
+ /* create native non-transparent surface for current image */
+ if ((new_bitmap->surface = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+ /* create native transparent surface for current image */
+ SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
+ SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
+ if ((new_bitmap->surface_masked = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+ /* free temporary surface */
+ SDL_FreeSurface(sdl_image_tmp);
+
+ return new_bitmap;
+}
+
+
+/* ========================================================================= */
+/* audio functions */
+/* ========================================================================= */
+
+inline void SDLOpenAudio(void)
+{
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
+ {
+ Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError());
+ return;
+ }
+
+ if (Mix_OpenAudio(DEFAULT_AUDIO_SAMPLE_RATE, AUDIO_S16,
+ AUDIO_STEREO_CHANNELS,
+ DEFAULT_AUDIO_FRAGMENT_SIZE) < 0)
+ {
+ Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
+ return;
+ }
+
+ audio.sound_available = TRUE;
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
+ audio.sound_enabled = TRUE;
+
+ /* determine number of available channels */
+ audio.channels = Mix_AllocateChannels(MIX_CHANNELS);
+
+ if (!audio.mods_available) /* reserve first channel for music loops */
+ {
+ if (Mix_ReserveChannels(1) == 1)
+ audio.music_channel = 0;
+ else
+ audio.music_available = FALSE;
+ }
+
+ Mix_Volume(-1, SOUND_MAX_VOLUME);
+ Mix_VolumeMusic(SOUND_MAX_VOLUME);
+}
+
+inline void SDLCloseAudio(void)
+{
+ Mix_HaltMusic();
+ Mix_HaltChannel(-1);
+
+ Mix_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+}
+
+#endif /* TARGET_SDL */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* 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)
+
+#define SDLCOPYAREA_OPAQUE 0
+#define SDLCOPYAREA_MASKED 1
+
+/* system dependent definitions */
+
+#define TARGET_STRING "SDL"
+#define FULLSCREEN_STATUS FULLSCREEN_AVAILABLE
+
+
+/* SDL type definitions */
+
+typedef struct SDLSurfaceInfo Bitmap;
+typedef struct SDLSurfaceInfo DrawBuffer;
+typedef struct SDLSurfaceInfo DrawWindow;
+typedef Uint32 Pixel;
+
+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;
+
+
+/* structure definitions */
+
+struct SDLSurfaceInfo
+{
+ SDL_Surface *surface;
+ SDL_Surface *surface_masked;
+ GC gc;
+ GC stored_clip_gc;
+};
+
+struct XY
+{
+ short x, y;
+};
+
+
+/* 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 SDLInitVideoDisplay(void);
+inline void SDLInitVideoBuffer(DrawBuffer **, DrawWindow **, boolean);
+inline boolean SDLSetVideoMode(DrawBuffer **, boolean);
+inline void SDLCopyArea(Bitmap *, Bitmap *, int, int, int, int, int, int, int);
+inline void SDLFillRectangle(Bitmap *, int, int, int, int, unsigned int);
+inline void SDLDrawSimpleLine(SDL_Surface *, int, int, int, int, unsigned int);
+inline void SDLDrawLine(SDL_Surface *, int, int, int, int, Uint32);
+/* functions from SGE library */
+void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
+
+Bitmap *SDLLoadImage(char *);
+
+inline void SDLOpenAudio(void);
+inline void SDLCloseAudio(void);
+
+#endif /* SDL_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* sound.c *
+***********************************************************/
+
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <signal.h>
+
+#include "system.h"
+#include "sound.h"
+#include "misc.h"
+
+
+static int num_sounds = 0, num_music = 0;
+static struct SampleInfo *Sound = NULL;
+#if defined(TARGET_SDL)
+static int num_mods = 0;
+static struct SampleInfo *Mod = NULL;
+#endif
+
+
+/*** 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)
+static 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;
+}
+
+static boolean TestAudioDevices(void)
+{
+ 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 FALSE;
+ }
+
+ close(audio_fd);
+
+ audio.device_name = audio_device_name[i];
+
+ return TRUE;
+}
+
+#if !defined(TARGET_SDL)
+static boolean ForkAudioProcess(void)
+{
+ if (pipe(audio.soundserver_pipe) < 0)
+ {
+ Error(ERR_WARN, "cannot create pipe - no sounds");
+ return FALSE;
+ }
+
+ if ((audio.soundserver_pid = fork()) < 0)
+ {
+ Error(ERR_WARN, "cannot create sound server process - no sounds");
+ return FALSE;
+ }
+
+ if (audio.soundserver_pid == 0) /* we are child */
+ {
+ SoundServer();
+
+ /* never reached */
+ exit(0);
+ }
+ else /* we are parent */
+ close(audio.soundserver_pipe[0]); /* no reading from pipe needed */
+
+ return TRUE;
+}
+#endif
+
+void UnixOpenAudio(void)
+{
+ if (!TestAudioDevices())
+ return;
+
+ audio.sound_available = TRUE;
+ audio.sound_enabled = TRUE;
+
+#if defined(AUDIO_STREAMING_DSP)
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
+#endif
+}
+
+void UnixCloseAudio(void)
+{
+ if (audio.device_fd)
+ close(audio.device_fd);
+
+ if (audio.soundserver_pid)
+ kill(audio.soundserver_pid, SIGTERM);
+}
+#endif /* PLATFORM_UNIX */
+
+void InitPlaylist(void)
+{
+ int i;
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ playlist[i] = emptySoundControl;
+ playing_sounds = 0;
+}
+
+void StartSoundserver(void)
+{
+#if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
+ if (!ForkAudioProcess())
+ audio.sound_available = FALSE;
+#endif
+}
+
+#if defined(PLATFORM_UNIX)
+void SoundServer(void)
+{
+ int i;
+
+ struct SoundControl snd_ctrl;
+ fd_set sound_fdset;
+
+ close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
+
+ InitPlaylist();
+
+ 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 = DEFAULT_AUDIO_FRAGMENT_SIZE;
+ int sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
+ int stereo = TRUE;
+ /* 'ioctl()' expects pointer to integer value for stereo flag
+ (boolean is defined as 'char', which will not work here) */
+
+ if (playing_sounds ||
+ (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
+ {
+ if (!playing_sounds) /* we just opened the audio device */
+ {
+ unsigned long fragment_spec = 0;
+
+ /* determine logarithm (log2) of the fragment size */
+ for (fragment_spec=0; (1 << fragment_spec) < fragment_size;
+ fragment_spec++);
+
+ /* use two fragments (play one fragment, prepare the other);
+ one fragment would result in interrupted audio output, more
+ than two fragments would raise audio output latency to much */
+ fragment_spec |= 0x00020000;
+
+ /* Example for fragment specification:
+ - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
+ - (with stereo the effective buffer size will shrink to 256)
+ => fragment_size = 0x00020009 */
+
+ if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_spec) < 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 >= SOUND_FADING_VOLUME_THRESHOLD)
+ playlist[i].volume -= SOUND_FADING_VOLUME_STEP;
+
+ /* 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 <= SOUND_FADING_VOLUME_THRESHOLD)
+ {
+ 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 */
+
+static boolean LoadSoundExt(char *sound_name, boolean is_music)
+{
+ struct SampleInfo *snd_info;
+ char filename[256];
+#if !defined(TARGET_SDL) && !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
+
+ num_sounds++;
+ Sound = checked_realloc(Sound, num_sounds * sizeof(struct SampleInfo));
+
+ snd_info = &Sound[num_sounds - 1];
+ snd_info->name = sound_name;
+
+ sprintf(filename, "%s/%s/%s", options.ro_base_directory,
+ (is_music ? MUSIC_DIRECTORY : SOUNDS_DIRECTORY), snd_info->name);
+
+#if defined(TARGET_SDL)
+
+ if ((snd_info->mix_chunk = Mix_LoadWAV(filename)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
+ return FALSE;
+ }
+
+#elif defined(PLATFORM_UNIX)
+
+ if ((file = fopen(filename, MODE_READ)) == 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
+
+ return TRUE;
+}
+
+boolean LoadSound(char *sound_name)
+{
+ return LoadSoundExt(sound_name, FALSE);
+}
+
+boolean LoadMod(char *mod_name)
+{
+#if defined(TARGET_SDL)
+ struct SampleInfo *mod_info;
+ char filename[256];
+
+ num_mods++;
+ Mod = checked_realloc(Mod, num_mods * sizeof(struct SampleInfo));
+
+ mod_info = &Mod[num_mods - 1];
+ mod_info->name = mod_name;
+
+ sprintf(filename, "%s/%s/%s", options.ro_base_directory,
+ MUSIC_DIRECTORY, mod_info->name);
+
+ if ((mod_info->mix_music = Mix_LoadMUS(filename)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read music file '%s' - no music", filename);
+ return FALSE;
+ }
+
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+int LoadMusic(void)
+{
+ DIR *dir;
+ struct dirent *dir_entry;
+ char *music_directory = getPath2(options.ro_base_directory, MUSIC_DIRECTORY);
+ int num_wav_music = 0;
+ int num_mod_music = 0;
+
+ if ((dir = opendir(music_directory)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+ audio.music_available = FALSE;
+ free(music_directory);
+ return 0;
+ }
+
+ while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
+ {
+ char *filename = dir_entry->d_name;
+
+ if (strlen(filename) > 4 &&
+ strcmp(&filename[strlen(filename) - 4], ".wav") == 0)
+ {
+ if (LoadSoundExt(filename, TRUE))
+ num_wav_music++;
+ }
+ else if (strlen(filename) > 4 &&
+ (strcmp(&filename[strlen(filename) - 4], ".mod") == 0 ||
+ strcmp(&filename[strlen(filename) - 4], ".MOD") == 0 ||
+ strncmp(filename, "mod.", 4) == 0 ||
+ strncmp(filename, "MOD.", 4) == 0))
+ {
+ if (LoadMod(filename))
+ num_mod_music++;
+ }
+ }
+
+ closedir(dir);
+
+ if (num_wav_music == 0 && num_mod_music == 0)
+ Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
+ music_directory);
+
+ free(music_directory);
+
+ num_music = (num_mod_music > 0 ? num_mod_music : num_wav_music);
+
+ audio.mods_available = (num_mod_music > 0);
+ audio.music_available = (num_music > 0);
+
+ return num_music;
+}
+
+void PlayMusic(int nr)
+{
+ if (!audio.music_available)
+ return;
+
+ if (!audio.mods_available)
+ nr = num_sounds - num_music + nr;
+
+#if defined(TARGET_SDL)
+ if (audio.mods_available) /* play MOD music */
+ {
+ Mix_VolumeMusic(SOUND_MAX_VOLUME);
+ Mix_PlayMusic(Mod[nr].mix_music, -1);
+ }
+ else /* play WAV music loop */
+ {
+ Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
+ Mix_PlayChannel(audio.music_channel, Sound[nr].mix_chunk, -1);
+ }
+#else
+ audio.music_nr = nr;
+ PlaySoundLoop(nr);
+#endif
+}
+
+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 || !audio.sound_enabled)
+ 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, SOUND_MAX_VOLUME);
+ Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
+#elif defined(PLATFORM_UNIX)
+ 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 = audio.sound_enabled = FALSE;
+ return;
+ }
+#elif defined(PLATFORM_MSDOS)
+ sound_handler(snd_ctrl);
+#endif
+}
+
+void FadeMusic(void)
+{
+#if defined(TARGET_SDL)
+ if (audio.mods_available)
+ Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
+ else
+ Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
+#else
+ FadeSound(audio.music_nr);
+#endif
+}
+
+void FadeSound(int nr)
+{
+ StopSoundExt(nr, SSND_FADE_SOUND);
+}
+
+void FadeSounds()
+{
+ FadeMusic();
+ StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
+}
+
+void StopMusic(void)
+{
+#if defined(TARGET_SDL)
+ if (audio.mods_available)
+ Mix_HaltMusic();
+ else
+ Mix_HaltChannel(audio.music_channel);
+#else
+ StopSound(audio.music_nr);
+#endif
+}
+
+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))
+ {
+ int i;
+
+ for (i=0; i<audio.channels; i++)
+ if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
+ Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
+ if (snd_ctrl.stop_all_sounds)
+ Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
+ }
+ else
+ {
+ int i;
+
+ for (i=0; i<audio.channels; i++)
+ if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
+ Mix_HaltChannel(i);
+ if (snd_ctrl.stop_all_sounds)
+ 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 = audio.sound_enabled = 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(TARGET_SDL)
+ free(Sound[i].mix_chunk);
+#elif !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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* sound.h *
+***********************************************************/
+
+#ifndef SOUND_H
+#define SOUND_H
+
+#include <math.h>
+
+#include "platform.h"
+
+#if defined(PLATFORM_LINUX)
+#include <sys/ioctl.h>
+#endif
+
+#if defined(PLATFORM_LINUX)
+#include <linux/soundcard.h>
+#elif defined(PLATFORM_FREEBSD)
+#include <machine/soundcard.h>
+#elif defined(PLATFORM_HPUX)
+#include <sys/audio.h>
+#endif
+
+#include "system.h"
+
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) || defined(VOXWARE)
+#define AUDIO_STREAMING_DSP
+#endif
+
+#define AUDIO_SAMPLE_RATE_8000 8000
+#define AUDIO_SAMPLE_RATE_22050 22050
+
+#define AUDIO_FRAGMENT_SIZE_512 512
+#define AUDIO_FRAGMENT_SIZE_1024 1024
+#define AUDIO_FRAGMENT_SIZE_2048 2048
+#define AUDIO_FRAGMENT_SIZE_4096 4096
+
+#define AUDIO_MONO_CHANNEL 1
+#define AUDIO_STEREO_CHANNELS 2
+
+#if defined(TARGET_SDL)
+/* one second fading interval == 1000 ticks (milliseconds) */
+#define SOUND_FADING_INTERVAL 1000
+#define SOUND_MAX_VOLUME (SDL_MIX_MAXVOLUME / 4)
+#endif
+
+#if defined(AUDIO_STREAMING_DSP)
+#define SOUND_FADING_VOLUME_STEP (PSND_MAX_VOLUME / 40)
+#define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
+#endif
+
+#define DEFAULT_AUDIO_SAMPLE_RATE AUDIO_SAMPLE_RATE_22050
+#define DEFAULT_AUDIO_FRAGMENT_SIZE_UNIX AUDIO_FRAGMENT_SIZE_512
+#define DEFAULT_AUDIO_FRAGMENT_SIZE_WIN32 AUDIO_FRAGMENT_SIZE_2048
+
+#if defined(PLATFORM_UNIX)
+#define DEFAULT_AUDIO_FRAGMENT_SIZE DEFAULT_AUDIO_FRAGMENT_SIZE_UNIX
+#else
+#define DEFAULT_AUDIO_FRAGMENT_SIZE DEFAULT_AUDIO_FRAGMENT_SIZE_WIN32
+#endif
+
+#if !defined(PLATFORM_MSDOS)
+#define MAX_SOUNDS_PLAYING 16
+#else
+#define MAX_SOUNDS_PLAYING 8
+#endif
+
+#if !defined(PLATFORM_HPUX)
+#define SND_BLOCKSIZE 4096
+#else
+#define SND_BLOCKSIZE 32768
+#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;
+ Mix_Music *mix_music;
+#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(void);
+void UnixCloseAudio(void);
+
+/* sound server functions */
+void InitPlaylist(void);
+void StartSoundserver(void);
+void SoundServer(void);
+
+/* sound client functions */
+boolean LoadSound(char *);
+boolean LoadMod(char *);
+int LoadMusic(void);
+void PlayMusic(int);
+void PlaySound(int);
+void PlaySoundStereo(int, int);
+void PlaySoundLoop(int);
+void PlaySoundExt(int, int, int, boolean);
+void FadeMusic(void);
+void FadeSound(int);
+void FadeSounds(void);
+void StopMusic(void);
+void StopSound(int);
+void StopSounds(void);
+void StopSoundExt(int, int);
+void FreeSounds(int);
+
+#endif
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* system.c *
+***********************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+#include "platform.h"
+
+#if defined(PLATFORM_MSDOS)
+#include <fcntl.h>
+#endif
+
+#include "system.h"
+#include "sound.h"
+#include "misc.h"
+
+
+/* ========================================================================= */
+/* exported variables */
+/* ========================================================================= */
+
+struct ProgramInfo program;
+struct OptionInfo options;
+struct VideoSystemInfo video;
+struct AudioSystemInfo audio;
+struct GfxInfo gfx;
+
+struct LevelDirInfo *leveldir_first = NULL;
+struct LevelDirInfo *leveldir_current = NULL;
+
+Display *display = NULL;
+Visual *visual = NULL;
+int screen = 0;
+Colormap cmap = None;
+
+DrawWindow *window = NULL;
+DrawBuffer *backbuffer = NULL;
+DrawBuffer *drawto = NULL;
+
+int button_status = MB_NOT_PRESSED;
+boolean motion_status = FALSE;
+
+int redraw_mask = REDRAW_NONE;
+int redraw_tiles = 0;
+
+int FrameCounter = 0;
+
+
+/* ========================================================================= */
+/* init/close functions */
+/* ========================================================================= */
+
+void InitCommandName(char *argv0)
+{
+ program.command_basename =
+ (strrchr(argv0, '/') ? strrchr(argv0, '/') + 1 : argv0);
+}
+
+void InitExitFunction(void (*exit_function)(int))
+{
+ program.exit_function = exit_function;
+
+ /* set signal handlers to custom exit function */
+ signal(SIGINT, exit_function);
+ signal(SIGTERM, exit_function);
+
+#if defined(TARGET_SDL)
+ /* set exit function to automatically cleanup SDL stuff after exit() */
+ atexit(SDL_Quit);
+#endif
+}
+
+void InitPlatformDependantStuff(void)
+{
+#if defined(PLATFORM_MSDOS)
+ _fmode = O_BINARY;
+#endif
+
+#if !defined(PLATFORM_UNIX)
+ program.userdata_directory = "userdata";
+ initErrorFile();
+#endif
+
+#if defined(TARGET_SDL)
+ if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
+ Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+#endif
+}
+
+void ClosePlatformDependantStuff(void)
+{
+#if !defined(PLATFORM_UNIX)
+ dumpErrorFile();
+#endif
+}
+
+void InitProgramInfo(char *unix_userdata_directory, char *program_title,
+ char *window_title, char *icon_title,
+ char *x11_icon_basename, char *x11_iconmask_basename,
+ char *msdos_pointer_basename)
+{
+ char *gfx_dir = getPath2(options.ro_base_directory, GRAPHICS_DIRECTORY);
+ char *x11_icon_filename = getPath2(gfx_dir, x11_icon_basename);
+ char *x11_iconmask_filename = getPath2(gfx_dir, x11_iconmask_basename);
+ char *msdos_pointer_filename = getPath2(gfx_dir, msdos_pointer_basename);
+
+ free(gfx_dir);
+
+#if defined(PLATFORM_UNIX)
+ program.userdata_directory = unix_userdata_directory;
+#else
+ program.userdata_directory = "userdata";
+#endif
+
+ program.program_title = program_title;
+ program.window_title = window_title;
+ program.icon_title = icon_title;
+ program.x11_icon_filename = x11_icon_filename;
+ program.x11_iconmask_filename = x11_iconmask_filename;
+ program.msdos_pointer_filename = msdos_pointer_filename;
+}
+
+void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
+ int real_sx, int real_sy,
+ int full_sxsize, int full_sysize)
+{
+ gfx.sx = sx;
+ gfx.sy = sy;
+ gfx.sxsize = sxsize;
+ gfx.sysize = sysize;
+ gfx.real_sx = real_sx;
+ gfx.real_sy = real_sy;
+ gfx.full_sxsize = full_sxsize;
+ gfx.full_sysize = full_sysize;
+}
+
+void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
+{
+ gfx.dx = dx;
+ gfx.dy = dy;
+ gfx.dxsize = dxsize;
+ gfx.dysize = dysize;
+}
+
+void InitGfxDoor2Info(int vx, int vy, int vxsize, int vysize)
+{
+ gfx.vx = vx;
+ gfx.vy = vy;
+ gfx.vxsize = vxsize;
+ gfx.vysize = vysize;
+}
+
+void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
+{
+ /* currently only used by MSDOS code to alloc VRAM buffer, if available */
+ gfx.scrollbuffer_width = scrollbuffer_width;
+ gfx.scrollbuffer_height = scrollbuffer_height;
+}
+
+
+/* ========================================================================= */
+/* video functions */
+/* ========================================================================= */
+
+inline static int GetRealDepth(int depth)
+{
+ return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
+}
+
+inline void InitVideoDisplay(void)
+{
+#if defined(TARGET_SDL)
+ SDLInitVideoDisplay();
+#else
+ X11InitVideoDisplay();
+#endif
+}
+
+inline void CloseVideoDisplay(void)
+{
+ KeyboardAutoRepeatOn();
+
+#if defined(TARGET_SDL)
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+#else
+ if (display)
+ XCloseDisplay(display);
+#endif
+}
+
+inline void InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window,
+ int width, int height, int depth,
+ boolean fullscreen)
+{
+ video.width = width;
+ video.height = height;
+ video.depth = GetRealDepth(depth);
+ video.fullscreen_available = FULLSCREEN_STATUS;
+ video.fullscreen_enabled = FALSE;
+
+#ifdef TARGET_SDL
+ SDLInitVideoBuffer(backbuffer, window, fullscreen);
+#else
+ X11InitVideoBuffer(backbuffer, window);
+#endif
+}
+
+inline Bitmap *CreateBitmapStruct(void)
+{
+#ifdef TARGET_SDL
+ return checked_calloc(sizeof(struct SDLSurfaceInfo));
+#else
+ return checked_calloc(sizeof(struct X11DrawableInfo));
+#endif
+}
+
+inline Bitmap *CreateBitmap(int width, int height, int depth)
+{
+ Bitmap *new_bitmap = CreateBitmapStruct();
+ int real_depth = GetRealDepth(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);
+
+ new_bitmap->surface = surface_native;
+#else
+ Pixmap pixmap;
+
+ if ((pixmap = XCreatePixmap(display, window->drawable,
+ width, height, real_depth))
+ == None)
+ Error(ERR_EXIT, "cannot create pixmap");
+
+ new_bitmap->drawable = pixmap;
+
+ if (window == NULL)
+ Error(ERR_EXIT, "Window GC needed for Bitmap -- create Window first");
+
+ new_bitmap->gc = window->gc;
+
+ new_bitmap->line_gc[0] = window->line_gc[0];
+ new_bitmap->line_gc[1] = window->line_gc[1];
+#endif
+
+ return new_bitmap;
+}
+
+inline void FreeBitmap(Bitmap *bitmap)
+{
+ if (bitmap == NULL)
+ return;
+
+#ifdef TARGET_SDL
+ if (bitmap->surface)
+ SDL_FreeSurface(bitmap->surface);
+ if (bitmap->surface_masked)
+ SDL_FreeSurface(bitmap->surface_masked);
+#else
+ if (bitmap->drawable)
+ XFreePixmap(display, bitmap->drawable);
+ if (bitmap->clip_mask)
+ XFreePixmap(display, bitmap->clip_mask);
+ if (bitmap->stored_clip_gc)
+ XFreeGC(display, bitmap->stored_clip_gc);
+#endif
+
+ free(bitmap);
+}
+
+inline void CloseWindow(DrawWindow *window)
+{
+#ifdef TARGET_X11
+ if (window->drawable)
+ {
+ XUnmapWindow(display, window->drawable);
+ XDestroyWindow(display, window->drawable);
+ }
+ if (window->gc)
+ XFreeGC(display, window->gc);
+#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, SDLCOPYAREA_OPAQUE);
+#else
+ XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
+ dst_bitmap->gc, src_x, src_y, width, height, dst_x, dst_y);
+#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->drawable, bitmap->gc, x, y, width, height);
+#endif
+}
+
+#if 0
+#ifndef TARGET_SDL
+static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */
+#endif
+#endif
+
+inline void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
+{
+#ifdef TARGET_X11
+ if (clip_gc)
+ {
+ bitmap->clip_gc = clip_gc;
+ XSetClipMask(display, bitmap->clip_gc, clip_pixmap);
+ }
+#if 0
+ last_clip_gc = clip_gc;
+#endif
+#endif
+}
+
+inline void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
+{
+#ifdef TARGET_X11
+ if (clip_gc)
+ {
+ bitmap->clip_gc = clip_gc;
+ XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y);
+ }
+#if 0
+ last_clip_gc = clip_gc;
+#endif
+#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, SDLCOPYAREA_MASKED);
+#else
+ XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
+ src_bitmap->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->surface, from_x, from_y, to_x, to_y, 0xffffff);
+#else
+ XSetForeground(display, bitmap->gc, WhitePixel(display, screen));
+ XDrawLine(display, bitmap->drawable, bitmap->gc, from_x, from_y, to_x, to_y);
+ XSetForeground(display, bitmap->gc, BlackPixel(display, screen));
+#endif
+}
+
+#if !defined(TARGET_X11_NATIVE)
+inline void DrawLine(Bitmap *bitmap, int from_x, int from_y,
+ int to_x, int to_y, Pixel pixel, int line_width)
+{
+ int x, y;
+
+ for (x=0; x<line_width; x++)
+ {
+ for (y=0; y<line_width; y++)
+ {
+ int dx = x - line_width / 2;
+ int dy = y - line_width / 2;
+
+ if ((x == 0 && y == 0) ||
+ (x == 0 && y == line_width - 1) ||
+ (x == line_width - 1 && y == 0) ||
+ (x == line_width - 1 && y == line_width - 1))
+ continue;
+
+#if defined(TARGET_SDL)
+ sge_Line(bitmap->surface,
+ from_x + dx, from_y + dy, to_x + dx, to_y + dy, pixel);
+#elif defined(TARGET_ALLEGRO)
+ AllegroDrawLine(bitmap->drawable, from_x + dx, from_y + dy,
+ to_x + dx, to_y + dy, pixel);
+#endif
+ }
+ }
+}
+#endif
+
+inline void DrawLines(Bitmap *bitmap, struct XY *points, int num_points,
+ Pixel pixel)
+{
+#if !defined(TARGET_X11_NATIVE)
+ int line_width = 4;
+ int i;
+
+ for (i=0; i<num_points - 1; i++)
+ DrawLine(bitmap, points[i].x, points[i].y,
+ points[i + 1].x, points[i + 1].y, pixel, line_width);
+
+ /*
+ SDLDrawLines(bitmap->surface, points, num_points, pixel);
+ */
+#else
+ XSetForeground(display, bitmap->line_gc[1], pixel);
+ XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
+ (XPoint *)points, num_points, CoordModeOrigin);
+ /*
+ XSetForeground(display, gc, BlackPixel(display, screen));
+ */
+#endif
+}
+
+inline Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
+ unsigned int color_g, unsigned int color_b)
+{
+ Pixel pixel;
+
+#if defined(TARGET_SDL)
+ pixel = SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
+#elif defined(TARGET_ALLEGRO)
+ pixel = AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
+#elif defined(TARGET_X11_NATIVE)
+ XColor xcolor;
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ xcolor.red = (color_r << 8);
+ xcolor.green = (color_g << 8);
+ xcolor.blue = (color_b << 8);
+ XAllocColor(display, cmap, &xcolor);
+ pixel = xcolor.pixel;
+#endif
+
+ return pixel;
+}
+
+inline Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
+{
+ unsigned int color_r = (color >> 16) & 0xff;
+ unsigned int color_g = (color >> 8) & 0xff;
+ unsigned int color_b = (color >> 0) & 0xff;
+
+ return GetPixelFromRGB(bitmap, color_r, color_g, color_b);
+}
+
+/* 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
+ if (display)
+ XAutoRepeatOn(display);
+#endif
+}
+
+inline void KeyboardAutoRepeatOff(void)
+{
+#ifdef TARGET_SDL
+ SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_EnableUNICODE(0);
+#else
+ if (display)
+ XAutoRepeatOff(display);
+#endif
+}
+
+inline boolean PointerInWindow(DrawWindow *window)
+{
+#ifdef TARGET_SDL
+ return TRUE;
+#else
+ Window 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->drawable, &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);
+#endif
+
+ return fullscreen;
+}
+
+Bitmap *LoadImage(char *basename)
+{
+ Bitmap *new_bitmap;
+ char *filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
+ basename);
+
+#if defined(TARGET_SDL)
+ new_bitmap = SDLLoadImage(filename);
+#else
+ new_bitmap = X11LoadImage(filename);
+#endif
+
+ free(filename);
+
+ return new_bitmap;
+}
+
+
+/* ========================================================================= */
+/* audio functions */
+/* ========================================================================= */
+
+inline void OpenAudio(void)
+{
+ /* always start with reliable default values */
+ audio.sound_available = FALSE;
+ audio.music_available = FALSE;
+ audio.loops_available = FALSE;
+ audio.mods_available = FALSE;
+ audio.sound_enabled = FALSE;
+
+ audio.soundserver_pipe[0] = audio.soundserver_pipe[1] = 0;
+ audio.soundserver_pid = 0;
+ audio.device_name = NULL;
+ audio.device_fd = 0;
+
+ audio.channels = 0;
+ audio.music_channel = 0;
+ audio.music_nr = 0;
+
+#if defined(TARGET_SDL)
+ SDLOpenAudio();
+#elif defined(PLATFORM_MSDOS)
+ MSDOSOpenAudio();
+#elif defined(PLATFORM_UNIX)
+ UnixOpenAudio();
+#endif
+}
+
+inline void CloseAudio(void)
+{
+#if defined(TARGET_SDL)
+ SDLCloseAudio();
+#elif defined(PLATFORM_MSDOS)
+ MSDOSCloseAudio();
+#elif defined(PLATFORM_UNIX)
+ UnixCloseAudio();
+#endif
+
+ audio.sound_enabled = FALSE;
+}
+
+inline void SetAudioMode(boolean enabled)
+{
+ if (!audio.sound_available)
+ return;
+
+ audio.sound_enabled = enabled;
+}
+
+
+/* ========================================================================= */
+/* 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->drawable) &&
+ (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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* system.h *
+***********************************************************/
+
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include "platform.h"
+#include "types.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 */
+
+/* the additional 'b' is needed for Win32 to open files in binary mode */
+#define MODE_READ "rb"
+#define MODE_WRITE "wb"
+#define MODE_APPEND "ab"
+
+#define DEFAULT_DEPTH 0
+
+#define FULLSCREEN_NOT_AVAILABLE FALSE
+#define FULLSCREEN_AVAILABLE TRUE
+
+/* values for button_status */
+#define MB_NOT_PRESSED FALSE
+#define MB_NOT_RELEASED TRUE
+#define MB_RELEASED FALSE
+#define MB_PRESSED TRUE
+#define MB_MENU_CHOICE FALSE
+#define MB_MENU_MARK TRUE
+#define MB_MENU_INITIALIZE (-1)
+#define MB_LEFTBUTTON 1
+#define MB_MIDDLEBUTTON 2
+#define MB_RIGHTBUTTON 3
+
+/* values for redraw_mask */
+#define REDRAW_NONE (0)
+#define REDRAW_ALL (1 << 0)
+#define REDRAW_FIELD (1 << 1)
+#define REDRAW_TILES (1 << 2)
+#define REDRAW_DOOR_1 (1 << 3)
+#define REDRAW_VIDEO_1 (1 << 4)
+#define REDRAW_VIDEO_2 (1 << 5)
+#define REDRAW_VIDEO_3 (1 << 6)
+#define REDRAW_MICROLEVEL (1 << 7)
+#define REDRAW_MICROLABEL (1 << 8)
+#define REDRAW_FROM_BACKBUFFER (1 << 9)
+#define REDRAW_DOOR_2 (REDRAW_VIDEO_1 | \
+ REDRAW_VIDEO_2 | \
+ REDRAW_VIDEO_3)
+#define REDRAW_DOOR_3 (1 << 10)
+#define REDRAW_DOORS (REDRAW_DOOR_1 | \
+ REDRAW_DOOR_2 | \
+ REDRAW_DOOR_3)
+#define REDRAW_MAIN (REDRAW_FIELD | \
+ REDRAW_TILES | \
+ REDRAW_MICROLEVEL)
+#define REDRAW_FPS (1 << 11)
+#define REDRAWTILES_THRESHOLD (SCR_FIELDX * SCR_FIELDY / 2)
+
+
+/* default name for empty highscore entry */
+#define EMPTY_PLAYER_NAME "no name"
+
+/* default name for unknown player names */
+#define ANONYMOUS_NAME "anonymous"
+
+/* default name for new levels */
+#define NAMELESS_LEVEL_NAME "nameless level"
+
+/* definitions for game sub-directories */
+#ifndef RO_GAME_DIR
+#define RO_GAME_DIR "."
+#endif
+
+#ifndef RW_GAME_DIR
+#define RW_GAME_DIR "."
+#endif
+
+#define RO_BASE_PATH RO_GAME_DIR
+#define RW_BASE_PATH RW_GAME_DIR
+
+#define GRAPHICS_DIRECTORY "graphics"
+#define MUSIC_DIRECTORY "music"
+#define SOUNDS_DIRECTORY "sounds"
+#define LEVELS_DIRECTORY "levels"
+#define TAPES_DIRECTORY "tapes"
+#define SCORES_DIRECTORY "scores"
+
+/* areas in bitmap PIX_DOOR */
+/* meaning in PIX_DB_DOOR: (3 PAGEs)
+ PAGEX1: 1. buffer for DOOR_1
+ PAGEX2: 2. buffer for DOOR_1
+ PAGEX3: buffer for animations
+*/
+
+#define DOOR_GFX_PAGESIZE (gfx.dxsize)
+#define DOOR_GFX_PAGEX1 (0 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX2 (1 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX3 (2 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX4 (3 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX5 (4 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX6 (5 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX7 (6 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX8 (7 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEY1 (0)
+#define DOOR_GFX_PAGEY2 (gfx.dysize)
+
+
+/* type definitions */
+
+typedef int (*EventFilter)(const Event *);
+
+
+/* structure definitions */
+
+struct ProgramInfo
+{
+ char *command_basename;
+ char *userdata_directory;
+
+ char *program_title;
+ char *window_title;
+ char *icon_title;
+ char *x11_icon_filename;
+ char *x11_iconmask_filename;
+ char *msdos_pointer_filename;
+
+ void (*exit_function)(int);
+};
+
+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 VideoSystemInfo
+{
+ int default_depth;
+ int width, height, depth;
+ boolean fullscreen_available;
+ boolean fullscreen_enabled;
+};
+
+struct AudioSystemInfo
+{
+ boolean sound_available;
+ boolean music_available;
+ boolean loops_available;
+ boolean mods_available;
+ boolean sound_enabled;
+
+ int soundserver_pipe[2];
+ int soundserver_pid;
+ char *device_name;
+ int device_fd;
+
+ int channels;
+ int music_channel;
+ int music_nr;
+};
+
+struct GfxInfo
+{
+ int sx, sy;
+ int sxsize, sysize;
+ int real_sx, real_sy;
+ int full_sxsize, full_sysize;
+ int scrollbuffer_width, scrollbuffer_height;
+
+ int dx, dy;
+ int dxsize, dysize;
+
+ int vx, vy;
+ int vxsize, vysize;
+};
+
+struct LevelDirInfo
+{
+ char *filename; /* level series single directory name */
+ char *fullpath; /* complete path relative to level directory */
+ char *basepath; /* absolute base path of level directory */
+ char *name; /* level series name, as displayed on main screen */
+ char *name_short; /* optional short name for level selection screen */
+ char *name_sorting; /* optional sorting name for correct level sorting */
+ char *author; /* level series author name levels without author */
+ char *imported_from; /* optional comment for imported level series */
+ int levels; /* number of levels in level series */
+ int first_level; /* first level number (to allow start with 0 or 1) */
+ int last_level; /* last level number (automatically calculated) */
+ int sort_priority; /* sort levels by 'sort_priority' and then by name */
+ boolean level_group; /* directory contains more level series directories */
+ boolean parent_link; /* entry links back to parent directory */
+ boolean user_defined; /* user defined levels are stored in home directory */
+ boolean readonly; /* readonly levels can not be changed with editor */
+ int color; /* color to use on selection screen for this level */
+ char *class_desc; /* description of level series class */
+ int handicap_level; /* number of the lowest unsolved level */
+ int cl_first; /* internal control field for "choose level" screen */
+ int cl_cursor; /* internal control field for "choose level" screen */
+
+ struct LevelDirInfo *node_parent; /* parent level directory info */
+ struct LevelDirInfo *node_group; /* level group sub-directory info */
+ struct LevelDirInfo *next; /* next level series structure node */
+};
+
+
+/* ========================================================================= */
+/* exported variables */
+/* ========================================================================= */
+
+extern struct ProgramInfo program;
+extern struct OptionInfo options;
+extern struct VideoSystemInfo video;
+extern struct AudioSystemInfo audio;
+extern struct GfxInfo gfx;
+
+extern struct LevelDirInfo *leveldir_first;
+extern struct LevelDirInfo *leveldir_current;
+
+extern Display *display;
+extern Visual *visual;
+extern int screen;
+extern Colormap cmap;
+
+extern DrawWindow *window;
+extern DrawBuffer *backbuffer;
+extern DrawBuffer *drawto;
+
+extern int button_status;
+extern boolean motion_status;
+
+extern int redraw_mask;
+extern int redraw_tiles;
+
+extern int FrameCounter;
+
+
+/* function definitions */
+
+void InitCommandName(char *);
+void InitExitFunction(void (*exit_function)(int));
+void InitPlatformDependantStuff(void);
+void ClosePlatformDependantStuff(void);
+
+void InitProgramInfo(char *, char *, char *, char *, char *, char *, char *);
+
+void InitGfxFieldInfo(int, int, int, int, int, int, int, int);
+void InitGfxDoor1Info(int, int, int, int);
+void InitGfxDoor2Info(int, int, int, int);
+void InitGfxScrollbufferInfo(int, int);
+
+inline void InitVideoDisplay(void);
+inline void CloseVideoDisplay(void);
+inline void InitVideoBuffer(DrawBuffer **,DrawWindow **, int,int,int, boolean);
+inline Bitmap *CreateBitmapStruct(void);
+inline Bitmap *CreateBitmap(int, int, int);
+inline void FreeBitmap(Bitmap *);
+inline void BlitBitmap(Bitmap *, Bitmap *, int, int, int, int, int, int);
+inline void ClearRectangle(Bitmap *, int, int, int, int);
+inline void SetClipMask(Bitmap *, GC, Pixmap);
+inline void SetClipOrigin(Bitmap *, GC, int, int);
+inline void BlitBitmapMasked(Bitmap *, Bitmap *, int, int, int, int, int, int);
+inline void DrawSimpleWhiteLine(Bitmap *, int, int, int, int);
+inline void DrawLines(Bitmap *, struct XY *, int, Pixel);
+inline Pixel GetPixelFromRGB(Bitmap *, unsigned int,unsigned int,unsigned int);
+inline Pixel GetPixelFromRGBcompact(Bitmap *, unsigned 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);
+
+Bitmap *LoadImage(char *);
+
+inline void OpenAudio(void);
+inline void CloseAudio(void);
+inline void SetAudioMode(boolean);
+
+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
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* text.c *
+***********************************************************/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "text.h"
+
+
+/* ========================================================================= */
+/* exported variables */
+/* ========================================================================= */
+
+struct FontInfo font;
+
+
+/* ========================================================================= */
+/* font functions */
+/* ========================================================================= */
+
+void InitFontInfo(Bitmap *bitmap_big, Bitmap *bitmap_medium,
+ Bitmap *bitmap_small)
+{
+ font.bitmap_big = bitmap_big;
+ font.bitmap_medium = bitmap_medium;
+ font.bitmap_small = bitmap_small;
+}
+
+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 && font.bitmap_small)
+ {
+ ClearRectangle(window, 0, ypos, video.width, FONT2_YSIZE);
+ DrawTextExt(window, (video.width - strlen(text) * FONT2_XSIZE)/2,
+ ypos, text, FS_SMALL, color);
+ FlushDisplay();
+ }
+}
+
+void DrawTextFCentered(int y, int font_type, char *format, ...)
+{
+ char buffer[MAX_OUTPUT_LINESIZE + 1];
+ int font_width = getFontWidth(FS_SMALL, font_type);
+ va_list ap;
+
+ va_start(ap, format);
+ vsprintf(buffer, format, ap);
+ va_end(ap);
+
+ DrawText(gfx.sx + (gfx.sxsize - strlen(buffer) * font_width) / 2,
+ gfx.sy + y, buffer, FS_SMALL, font_type);
+}
+
+void DrawTextF(int x, int y, int font_type, char *format, ...)
+{
+ char buffer[MAX_OUTPUT_LINESIZE + 1];
+ va_list ap;
+
+ va_start(ap, format);
+ vsprintf(buffer, format, ap);
+ va_end(ap);
+
+ DrawText(gfx.sx + x, gfx.sy + y, buffer, FS_SMALL, font_type);
+}
+
+void DrawText(int x, int y, char *text, int font_size, int font_type)
+{
+ DrawTextExt(drawto, x, y, text, font_size, font_type);
+
+ if (x < gfx.dx)
+ redraw_mask |= REDRAW_FIELD;
+ else if (y < gfx.vy || gfx.vy == 0)
+ redraw_mask |= REDRAW_DOOR_1;
+}
+
+void DrawTextExt(DrawBuffer *bitmap, int x, int y,
+ char *text, int font_size, int font_type)
+{
+ Bitmap *font_bitmap;
+ int font_width, font_height, font_start;
+ 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 ? font.bitmap_big :
+ font_size == FS_MEDIUM ? font.bitmap_medium :
+ font.bitmap_small);
+ 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) || c == '°')
+ {
+ 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 (c == '°')
+ {
+ src_x = (FONT_CHARS_PER_LINE + 1) * font_width;
+ src_y = 3 * font_height + font_start;
+ }
+
+ if (print_inverse)
+ {
+ BlitBitmap(font_bitmap, bitmap,
+ FONT_CHARS_PER_LINE * font_width,
+ 3 * font_height + font_start,
+ font_width, font_height, x, y);
+
+ SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc,
+ dest_x - src_x, dest_y - src_y);
+ BlitBitmapMasked(font_bitmap, bitmap,
+ 0, 0, font_width, font_height, dest_x, dest_y);
+ }
+ else
+ BlitBitmap(font_bitmap, bitmap,
+ src_x, src_y, font_width, font_height, dest_x, dest_y);
+ }
+
+ x += font_width;
+ }
+}
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* text.h *
+***********************************************************/
+
+#ifndef TEXT_H
+#define TEXT_H
+
+#include "system.h"
+
+
+/* font types */
+#define FS_SMALL 0
+#define FS_BIG 1
+#define FS_MEDIUM 2
+
+/* font colors */
+#define FC_RED 0
+#define FC_BLUE 1
+#define FC_GREEN 2
+#define FC_YELLOW 3
+#define FC_SPECIAL1 4
+#define FC_SPECIAL2 5
+#define FC_SPECIAL3 6
+
+/* font graphics definitions */
+#define FONT1_XSIZE 32
+#define FONT1_YSIZE 32
+#define FONT2_XSIZE 14
+#define FONT2_YSIZE 14
+#define FONT3_XSIZE 11
+#define FONT3_YSIZE 14
+#define FONT4_XSIZE 16
+#define FONT4_YSIZE 16
+#define FONT5_XSIZE 10
+#define FONT5_YSIZE 14
+#define FONT6_XSIZE 16
+#define FONT6_YSIZE 32
+
+#define FONT_CHARS_PER_LINE 16
+#define FONT_LINES_PER_FONT 4
+
+/* text output definitions */
+#define MAX_OUTPUT_LINESIZE 256
+
+/* font structure definitions */
+
+struct FontInfo
+{
+ Bitmap *bitmap_big;
+ Bitmap *bitmap_medium;
+ Bitmap *bitmap_small;
+};
+
+
+void InitFontInfo(Bitmap *, Bitmap *, Bitmap *);
+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 *, int, int, char *, int, int);
+
+#endif /* TEXT_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* 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
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+#endif
+
+#ifndef SIGN
+#define SIGN(a) ((a) < 0 ? -1 : ((a)>0 ? 1 : 0))
+#endif
+
+#endif /* TYPES_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* x11.c *
+***********************************************************/
+
+#include "system.h"
+#include "pcx.h"
+#include "misc.h"
+
+
+#if defined(TARGET_X11)
+
+static void X11InitDisplay();
+static DrawWindow *X11InitWindow();
+
+inline void X11InitVideoDisplay(void)
+{
+ /* initialize X11 video */
+ X11InitDisplay();
+
+ /* set default X11 depth */
+ video.default_depth = XDefaultDepth(display, screen);
+}
+
+inline void X11InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window)
+{
+ *window = X11InitWindow();
+
+ XMapWindow(display, (*window)->drawable);
+ FlushDisplay();
+
+ /* create additional (off-screen) buffer for double-buffering */
+ *backbuffer = CreateBitmap(video.width, video.height, video.depth);
+}
+
+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()
+{
+ DrawWindow *new_window = CreateBitmapStruct();
+ 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;
+#if 0
+ char icon_filename[256];
+#endif
+ XSizeHints size_hints;
+ XWMHints wm_hints;
+ XClassHint class_hints;
+ char *window_name = program.window_title;
+ char *icon_name = program.window_title;
+ long window_event_mask;
+ Atom proto_atom = None, delete_atom = None;
+#endif
+ int screen_width, screen_height;
+ int win_xpos, win_ypos;
+ unsigned long pen_fg = WhitePixel(display,screen);
+ unsigned long pen_bg = BlackPixel(display,screen);
+ const int width = video.width, height = video.height;
+ int i;
+
+#if 0
+#if !defined(PLATFORM_MSDOS)
+ static struct IconFileInfo icon_pic =
+ {
+ "rocks_icon.xbm",
+ "rocks_iconmask.xbm"
+ };
+#endif
+#endif
+
+ screen_width = XDisplayWidth(display, screen);
+ screen_height = XDisplayHeight(display, screen);
+
+ win_xpos = (screen_width - width) / 2;
+ win_ypos = (screen_height - height) / 2;
+
+ new_window->drawable = 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, new_window->drawable, proto_atom, XA_ATOM, 32,
+ PropModePrepend, (unsigned char *) &delete_atom, 1);
+
+#if 0
+ sprintf(icon_filename, "%s/%s/%s",
+ options.ro_base_directory, GRAPHICS_DIRECTORY,
+ icon_pic.picture_filename);
+#endif
+ if (XReadBitmapFile(display, new_window->drawable,
+ program.x11_icon_filename,
+ &icon_width, &icon_height, &icon_pixmap,
+ &icon_hot_x, &icon_hot_y) != BitmapSuccess)
+ Error(ERR_EXIT, "cannot read icon bitmap file '%s'",
+ program.x11_icon_filename);
+
+#if 0
+ sprintf(icon_filename, "%s/%s/%s",
+ options.ro_base_directory, GRAPHICS_DIRECTORY,
+ icon_pic.picturemask_filename);
+#endif
+ if (XReadBitmapFile(display, new_window->drawable,
+ program.x11_iconmask_filename,
+ &icon_width, &icon_height, &iconmask_pixmap,
+ &icon_hot_x, &icon_hot_y) != BitmapSuccess)
+ Error(ERR_EXIT, "cannot read icon bitmap file '%s'",
+ program.x11_iconmask_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.command_basename;
+ class_hints.res_class = program.program_title;
+
+ XSetWMProperties(display, new_window->drawable, &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, new_window->drawable, 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;
+ new_window->gc =
+ XCreateGC(display, new_window->drawable, gc_valuemask, &gc_values);
+
+ /* create GCs for line drawing (black and white) */
+ for(i=0; i<2; i++)
+ {
+ gc_values.graphics_exposures = False;
+ gc_values.foreground = (i ? pen_fg : pen_bg);
+ gc_values.background = pen_bg;
+ gc_values.line_width = 4;
+ gc_values.line_style = LineSolid;
+ gc_values.cap_style = CapRound;
+ gc_values.join_style = JoinRound;
+
+ gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground |
+ GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle;
+ new_window->line_gc[i] =
+ XCreateGC(display, new_window->drawable, gc_valuemask, &gc_values);
+ }
+
+ return new_window;
+}
+
+Bitmap *X11LoadImage(char *filename)
+{
+ Bitmap *new_bitmap = CreateBitmapStruct();
+ int pcx_err;
+
+#if defined(PLATFORM_MSDOS)
+ rest(100);
+#endif
+
+ pcx_err = Read_PCX_to_Pixmap(display, window->drawable, window->gc, filename,
+ &new_bitmap->drawable, &new_bitmap->clip_mask);
+ switch(pcx_err)
+ {
+ case PCX_Success:
+ break;
+ case PCX_OpenFailed:
+ Error(ERR_EXIT, "cannot open PCX file '%s'", filename);
+ case PCX_ReadFailed:
+ Error(ERR_EXIT, "cannot read PCX file '%s'", filename);
+ case PCX_FileInvalid:
+ Error(ERR_EXIT, "invalid PCX file '%s'", filename);
+ case PCX_NoMemory:
+ Error(ERR_EXIT, "not enough memory for PCX file '%s'", filename);
+ case PCX_ColorFailed:
+ Error(ERR_EXIT, "cannot get colors for PCX file '%s'", filename);
+ default:
+ break;
+ }
+
+ if (!new_bitmap->drawable)
+ Error(ERR_EXIT, "cannot get graphics for '%s'", filename);
+
+ if (!new_bitmap->clip_mask)
+ Error(ERR_EXIT, "cannot get clipmask for '%s'", filename);
+
+ /* set GraphicContext inheritated from Window */
+ new_bitmap->gc = window->gc;
+
+ return new_bitmap;
+}
+
+#endif /* TARGET_X11 */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* 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 struct X11DrawableInfo Bitmap;
+typedef struct X11DrawableInfo DrawWindow;
+typedef struct X11DrawableInfo DrawBuffer;
+/* "Pixel" is already defined in X11/Intrinsic.h */
+
+typedef KeySym Key;
+
+typedef XEvent Event;
+typedef XButtonEvent ButtonEvent;
+typedef XMotionEvent MotionEvent;
+typedef XKeyEvent KeyEvent;
+typedef XExposeEvent ExposeEvent;
+typedef XFocusChangeEvent FocusChangeEvent;
+typedef XClientMessageEvent ClientMessageEvent;
+
+
+/* structure definitions */
+
+struct X11DrawableInfo
+{
+ Drawable drawable;
+ Drawable clip_mask;
+ GC gc; /* GC for normal drawing (inheritated from 'window') */
+ GC line_gc[2]; /* GC for foreground and background line drawing */
+ GC stored_clip_gc; /* GC for masked drawing (used for whole Pixmap) */
+ GC clip_gc; /* can be 'stored_clip_gc' or one-tile-only clip GC */
+};
+
+struct XY
+{
+ short x, y;
+};
+
+
+/* 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 X11InitVideoDisplay(void);
+inline void X11InitVideoBuffer(DrawBuffer **, DrawWindow **);
+Bitmap *X11LoadImage(char *);
+
+#endif /* X11_H */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* main.c *
+* 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"
-
-#ifdef MSDOS
-#include <fcntl.h>
-#endif
-
-Display *display;
-Visual *visual;
-int screen;
-Window window;
-GC gc, clip_gc[NUM_PIXMAPS], tile_clip_gc;
-Pixmap pix[NUM_PIXMAPS];
-Pixmap clipmask[NUM_PIXMAPS], tile_clipmask[NUM_TILES];
-
-#ifdef USE_XPM_LIBRARY
-XpmAttributes xpm_att[NUM_PICTURES];
-#endif
-Drawable drawto, drawto_field, backbuffer, fieldbuffer;
-Colormap cmap;
+GC tile_clip_gc;
+Bitmap *pix[NUM_BITMAPS];
+Pixmap tile_clipmask[NUM_TILES];
+DrawBuffer *fieldbuffer;
+DrawBuffer *drawto_field;
-int sound_pipe[2];
-int sound_device;
-char *sound_device_name = SOUND_DEVICE;
int joystick_device = 0;
char *joystick_device_name[MAX_PLAYERS] =
{
DEV_JOYSTICK_3
};
-char *program_name = NULL;
-
int game_status = MAINMENU;
boolean level_editor_test_game = FALSE;
boolean network_playing = FALSE;
-int button_status = MB_NOT_PRESSED;
-boolean motion_status = FALSE;
+
int key_joystick_mapping = 0;
int global_joystick_status = JOYSTICK_STATUS;
int joystick_status = JOYSTICK_STATUS;
-int sound_status = SOUND_STATUS;
-boolean sound_loops_allowed = FALSE;
boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
int redraw_x1 = 0, redraw_y1 = 0;
-int redraw_mask;
-int redraw_tiles;
short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
int SBY_Upper, SBY_Lower;
int ZX,ZY, ExitX,ExitY;
int AllPlayersGone;
-int FrameCounter, TimeFrames, TimePlayed, TimeLeft;
+
+int TimeFrames, TimePlayed, TimeLeft;
boolean network_player_action_received = FALSE;
-struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
struct LevelInfo level;
struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
struct HiScore highscore[MAX_SCORE_ENTRIES];
-struct SoundInfo Sound[NUM_SOUNDS];
struct TapeInfo tape;
-struct OptionInfo options;
struct SetupInfo setup;
struct GameInfo game;
struct GlobalInfo global;
-/* data needed for playing sounds */
+/* filenames of sound effects */
char *sound_name[NUM_SOUNDS] =
{
- "alchemy",
- "amoebe",
- "antigrav",
- "autsch",
- "blurb",
- "bong",
- "buing",
- "chase",
- "czardasz",
- "deng",
- "fuel",
- "gong",
- "halloffame",
- "holz",
- "hui",
- "kabumm",
- "kink",
- "klapper",
- "kling",
- "klopf",
- "klumpf",
- "knack",
- "knurk",
- "krach",
- "lachen",
- "laser",
- "miep",
- "network",
- "njam",
- "oeffnen",
- "pling",
- "pong",
- "pusch",
- "quiek",
- "quirk",
- "rhythmloop",
- "roaaar",
- "roehr",
- "rumms",
- "schlopp",
- "schlurf",
- "schrff",
- "schwirr",
- "sirr",
- "slurp",
- "sproing",
- "twilight",
- "tyger",
- "voyager",
- "warnton",
- "whoosh",
- "zisch",
- "base",
- "infotron",
- "zonkdown",
- "zonkpush",
- "bug",
- "boom",
- "booom",
- "exit",
- "empty",
- "gate"
+ "amoebe.wav",
+ "antigrav.wav",
+ "autsch.wav",
+ "blurb.wav",
+ "bong.wav",
+ "buing.wav",
+ "deng.wav",
+ "fuel.wav",
+ "gong.wav",
+ "halloffame.wav",
+ "holz.wav",
+ "hui.wav",
+ "kabumm.wav",
+ "kink.wav",
+ "klapper.wav",
+ "kling.wav",
+ "klopf.wav",
+ "klumpf.wav",
+ "knack.wav",
+ "knurk.wav",
+ "krach.wav",
+ "lachen.wav",
+ "laser.wav",
+ "miep.wav",
+ "njam.wav",
+ "oeffnen.wav",
+ "pling.wav",
+ "pong.wav",
+ "pusch.wav",
+ "quiek.wav",
+ "quirk.wav",
+ "rhythmloop.wav",
+ "roaaar.wav",
+ "roehr.wav",
+ "rumms.wav",
+ "schlopp.wav",
+ "schlurf.wav",
+ "schrff.wav",
+ "schwirr.wav",
+ "sirr.wav",
+ "slurp.wav",
+ "sproing.wav",
+ "warnton.wav",
+ "whoosh.wav",
+ "zisch.wav",
+ "base.wav",
+ "infotron.wav",
+ "zonkdown.wav",
+ "zonkpush.wav",
+ "bug.wav",
+ "boom.wav",
+ "booom.wav",
+ "exit.wav",
+ "empty.wav",
+ "gate.wav"
};
/* background music */
int background_loop[] =
{
+#if 0
SND_ALCHEMY,
SND_CHASE,
SND_NETWORK,
SND_TYGER,
SND_VOYAGER,
SND_TWILIGHT
+#endif
};
int num_bg_loops = sizeof(background_loop)/sizeof(int);
"normal wall (BD style)",
"rock (BD style)",
"open exit",
- "unknown",
+ "black orb bomb",
"amoeba",
"mole", /* 110 */
"penguin",
"arrow down",
"pig",
"fire breathing dragon",
- "unknown",
+ "red key (EM style)",
"letter ' '", /* 120 */
"letter '!'",
"letter '\"'",
"growing wall (horizontal)", /* 200 */
"growing wall (vertical)",
"growing wall (all directions)",
- "unused",
- "unused",
- "unused",
- "unused",
- "unused",
- "unused",
- "unused",
+ "red door (EM style)",
+ "yellow door (EM style)",
+ "green door (EM style)",
+ "blue door (EM style)",
+ "yellow key (EM style)",
+ "green key (EM style)",
+ "blue key (EM style)",
"empty space", /* 210 */
"zonk",
"base",
"hardware",
"chip (upper half)",
"chip (lower half)",
- "unknown", /* 250 */
- "unknown",
- "unknown",
- "unknown",
+ "gray door (EM style, red key)", /* 250 */
+ "gray door (EM style, yellow key)",
+ "gray door (EM style, green key)",
+ "gray door (EM style, blue key)",
"unknown",
"unknown",
"-------------------------------",
*/
};
+int num_element_info = sizeof(element_info)/sizeof(char *);
+
+
+/* ========================================================================= */
+/* main() */
+/* ========================================================================= */
int main(int argc, char *argv[])
{
- program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
-
-#ifdef MSDOS
- _fmode = O_BINARY;
-#endif
+ InitCommandName(argv[0]);
+ InitExitFunction(CloseAllAndExit);
+ InitPlatformDependantStuff();
GetOptions(argv);
- OpenAll(argc,argv);
+ OpenAll();
+
EventLoop();
CloseAllAndExit(0);
exit(0); /* to keep compilers happy */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* main.h *
+* main.h *
***********************************************************/
#ifndef MAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
-#ifndef 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>
-
-#ifdef XPM_INCLUDE_FILE
-#define USE_XPM_LIBRARY
-#include XPM_INCLUDE_FILE
-#endif
-#else /* MSDOS */
-#include "msdos.h"
-#endif /* MSDOS */
-
-#ifdef DEBUG
-#define DEBUG_TIMING 0
-#endif
-
-typedef unsigned char boolean;
-typedef unsigned char byte;
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE (!FALSE)
-#endif
+#include "libgame/libgame.h"
#define WIN_XSIZE 672
#define WIN_YSIZE 560
-#ifndef MSDOS
+
+#if !defined(PLATFORM_MSDOS)
#define WIN_XPOS 0
#define WIN_YPOS 0
-#else /* MSDOS */
+#else
#define WIN_XPOS ((XRES - WIN_XSIZE) / 2)
#define WIN_YPOS ((YRES - WIN_YSIZE) / 2)
-#endif /* MSDOS */
+#endif
+
#define SCR_FIELDX 17
#define SCR_FIELDY 17
#define MAX_BUF_XSIZE (SCR_FIELDX + 2)
#define MAX_PLAYERS 4
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef ABS
-#define ABS(a) ((a) < 0 ? -(a) : (a))
-#endif
-#ifndef SIGN
-#define SIGN(a) ((a) < 0 ? -1 : ((a)>0 ? 1 : 0))
-#endif
-
#define SCREENX(a) ((a) - scroll_x)
#define SCREENY(a) ((a) - scroll_y)
#define LEVELX(a) ((a) + scroll_x)
#define PLAYER_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \
PROTECTED_FIELD(x, y))
-/* Pixmaps with graphic file */
+/* Bitmaps with graphic file */
#define PIX_BACK 0
#define PIX_DOOR 1
#define PIX_HEROES 2
#define PIX_BIGFONT 7
#define PIX_SMALLFONT 8
#define PIX_MEDIUMFONT 9
-/* Pixmaps without graphic file */
-#define PIX_DB_BACK 10
-#define PIX_DB_DOOR 11
-#define PIX_DB_FIELD 12
+/* Bitmaps without graphic file */
+#define PIX_DB_DOOR 10
+#define PIX_DB_FIELD 11
#define NUM_PICTURES 10
-#define NUM_PIXMAPS 13
+#define NUM_BITMAPS 12
/* boundaries of arrays etc. */
#define MAX_PLAYER_NAME_LEN 10
#define GAME_FRAME_DELAY 20 /* frame delay in milliseconds */
#define FFWD_FRAME_DELAY 10 /* 200% speed for fast forward */
#define FRAMES_PER_SECOND (1000 / GAME_FRAME_DELAY)
-#define GADGET_FRAME_DELAY 150 /* delay between gadget actions */
#define MICROLEVEL_SCROLL_DELAY 50 /* delay for scrolling micro level */
#define MICROLEVEL_LABEL_DELAY 250 /* delay for micro level label */
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;
-};
-
struct SetupJoystickInfo
{
char *device_name;
struct SetupKeyboardInfo
{
- KeySym left;
- KeySym right;
- KeySym up;
- KeySym down;
- KeySym snap;
- KeySym bomb;
+ Key left;
+ Key right;
+ Key up;
+ Key down;
+ Key snap;
+ Key bomb;
};
struct SetupInputInfo
boolean team_mode;
boolean handicap;
boolean time_limit;
+ boolean fullscreen;
struct SetupInputInfo input[MAX_PLAYERS];
};
boolean gravity;
};
-struct LevelDirInfo
-{
- char *filename; /* level series single directory name */
- char *fullpath; /* complete path relative to level directory */
- char *basepath; /* absolute base path of level directory */
- char *name; /* level series name, as displayed on main screen */
- char *name_short; /* optional short name for level selection screen */
- char *name_sorting; /* optional sorting name for correct level sorting */
- char *author; /* level series author name levels without author */
- char *imported_from; /* optional comment for imported level series */
- int levels; /* number of levels in level series */
- int first_level; /* first level number (to allow start with 0 or 1) */
- int last_level; /* last level number (automatically calculated) */
- int sort_priority; /* sort levels by 'sort_priority' and then by name */
- boolean level_group; /* directory contains more level series directories */
- boolean parent_link; /* entry links back to parent directory */
- boolean user_defined; /* user defined levels are stored in home directory */
- boolean readonly; /* readonly levels can not be changed with editor */
- int color; /* color to use on selection screen for this level */
- char *class_desc; /* description of level series class */
- int handicap_level; /* number of the lowest unsolved level */
- int cl_first; /* internal control field for "choose level" screen */
- int cl_cursor; /* internal control field for "choose level" screen */
-
- struct LevelDirInfo *node_parent; /* parent level directory info */
- struct LevelDirInfo *node_group; /* level group sub-directory info */
- struct LevelDirInfo *next; /* next level series structure node */
-};
-
struct TapeInfo
{
int level_nr;
struct GlobalInfo
{
- int dummy;
+ float frames_per_second;
+ boolean fps_slowdown;
+ int fps_slowdown_factor;
};
-extern Display *display;
-extern Visual *visual;
-extern int screen;
-extern Window window;
-extern GC gc, clip_gc[], tile_clip_gc;
-extern Pixmap pix[];
-extern Pixmap clipmask[], tile_clipmask[];
-
-#ifdef USE_XPM_LIBRARY
-extern XpmAttributes xpm_att[];
-#endif
-
-extern Drawable drawto, drawto_field, backbuffer, fieldbuffer;
-extern Colormap cmap;
+extern GC tile_clip_gc;
+extern Bitmap *pix[];
+extern Pixmap tile_clipmask[];
+extern DrawBuffer *fieldbuffer;
+extern DrawBuffer *drawto_field;
-extern int sound_pipe[2];
-extern int sound_device;
-extern char *sound_device_name;
extern int joystick_device;
extern char *joystick_device_name[];
-extern char *program_name;
-
extern int game_status;
extern boolean level_editor_test_game;
extern boolean network_playing;
-extern int button_status;
-extern boolean motion_status;
+
extern int key_joystick_mapping;
extern int global_joystick_status, joystick_status;
-extern int sound_status;
-extern boolean sound_loops_allowed;
extern boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
extern int redraw_x1, redraw_y1;
-extern int redraw_mask;
-extern int redraw_tiles;
extern short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int SBY_Upper, SBY_Lower;
extern int ZX,ZY, ExitX,ExitY;
extern int AllPlayersGone;
-extern int FrameCounter, TimeFrames, TimePlayed, TimeLeft;
+
+extern int TimeFrames, TimePlayed, TimeLeft;
extern boolean SiebAktiv;
extern int SiebCount;
extern boolean network_player_action_received;
-extern struct LevelDirInfo *leveldir_first, *leveldir_current;
extern struct LevelInfo level;
extern struct PlayerInfo stored_player[], *local_player;
extern struct HiScore highscore[];
extern struct TapeInfo tape;
-extern struct SoundInfo Sound[];
extern struct JoystickInfo joystick[];
-extern struct OptionInfo options;
extern struct SetupInfo setup;
extern struct GameInfo game;
extern struct GlobalInfo global;
extern int background_loop[];
extern int num_bg_loops;
extern char *element_info[];
-
+extern int num_element_info;
/* often used screen positions */
#define SX 8
#define MICROLEV_XPOS (SX + (SXSIZE - MICROLEV_XSIZE) / 2)
#define MICROLEV_YPOS (SX + 12 * TILEY - MICRO_TILEY)
#define MICROLABEL_YPOS (MICROLEV_YPOS + MICROLEV_YSIZE + 7)
-#define FONT1_XSIZE 32
-#define FONT1_YSIZE 32
-#define FONT2_XSIZE 14
-#define FONT2_YSIZE 14
-#define FONT3_XSIZE 11
-#define FONT3_YSIZE 14
-#define FONT4_XSIZE 16
-#define FONT4_YSIZE 16
-#define FONT5_XSIZE 10
-#define FONT5_YSIZE 14
-#define FONT6_XSIZE 16
-#define FONT6_YSIZE 32
#define GFX_STARTX SX
#define GFX_STARTY SY
#define MINI_MORE_PER_LINE 16
#define MICRO_MORE_PER_LINE 16
-#define FONT_CHARS_PER_LINE 16
-#define FONT_LINES_PER_FONT 4
-
/* game elements:
** 0 - 499: real elements, stored in level file
** 500 - 699: flag elements, only used at runtime
/* the names of the sounds */
-#define SND_ALCHEMY 0
-#define SND_AMOEBE 1
-#define SND_ANTIGRAV 2
-#define SND_AUTSCH 3
-#define SND_BLURB 4
-#define SND_BONG 5
-#define SND_BUING 6
-#define SND_CHASE 7
-#define SND_CZARDASZ 8
-#define SND_DENG 9
-#define SND_FUEL 10
-#define SND_GONG 11
-#define SND_HALLOFFAME 12
-#define SND_HOLZ 13
-#define SND_HUI 14
-#define SND_KABUMM 15
-#define SND_KINK 16
-#define SND_KLAPPER 17
-#define SND_KLING 18
-#define SND_KLOPF 19
-#define SND_KLUMPF 20
-#define SND_KNACK 21
-#define SND_KNURK 22
-#define SND_KRACH 23
-#define SND_LACHEN 24
-#define SND_LASER 25
-#define SND_MIEP 26
-#define SND_NETWORK 27
-#define SND_NJAM 28
-#define SND_OEFFNEN 29
-#define SND_PLING 30
-#define SND_PONG 31
-#define SND_PUSCH 32
-#define SND_QUIEK 33
-#define SND_QUIRK 34
-#define SND_RHYTHMLOOP 35
-#define SND_ROAAAR 36
-#define SND_ROEHR 37
-#define SND_RUMMS 38
-#define SND_SCHLOPP 39
-#define SND_SCHLURF 40
-#define SND_SCHRFF 41
-#define SND_SCHWIRR 42
-#define SND_SIRR 43
-#define SND_SLURP 44
-#define SND_SPROING 45
-#define SND_TWILIGHT 46
-#define SND_TYGER 47
-#define SND_VOYAGER 48
-#define SND_WARNTON 49
-#define SND_WHOOSH 50
-#define SND_ZISCH 51
-#define SND_SP_BASE 52
-#define SND_SP_INFOTRON 53
-#define SND_SP_ZONKDOWN 54
-#define SND_SP_ZONKPUSH 55
-#define SND_SP_BUG 56
-#define SND_SP_BOOM 57
-#define SND_SP_BOOOM 58
-#define SND_SP_EXIT 59
-#define SND_EMPTY 60
-#define SND_GATE 61
-
-#define NUM_SOUNDS 62
+#define SND_AMOEBE 0
+#define SND_ANTIGRAV 1
+#define SND_AUTSCH 2
+#define SND_BLURB 3
+#define SND_BONG 4
+#define SND_BUING 5
+#define SND_DENG 6
+#define SND_FUEL 7
+#define SND_GONG 8
+#define SND_HALLOFFAME 9
+#define SND_HOLZ 10
+#define SND_HUI 11
+#define SND_KABUMM 12
+#define SND_KINK 13
+#define SND_KLAPPER 14
+#define SND_KLING 15
+#define SND_KLOPF 16
+#define SND_KLUMPF 17
+#define SND_KNACK 18
+#define SND_KNURK 19
+#define SND_KRACH 20
+#define SND_LACHEN 21
+#define SND_LASER 22
+#define SND_MIEP 23
+#define SND_NJAM 24
+#define SND_OEFFNEN 25
+#define SND_PLING 26
+#define SND_PONG 27
+#define SND_PUSCH 28
+#define SND_QUIEK 29
+#define SND_QUIRK 30
+#define SND_RHYTHMLOOP 31
+#define SND_ROAAAR 32
+#define SND_ROEHR 33
+#define SND_RUMMS 34
+#define SND_SCHLOPP 35
+#define SND_SCHLURF 36
+#define SND_SCHRFF 37
+#define SND_SCHWIRR 38
+#define SND_SIRR 39
+#define SND_SLURP 40
+#define SND_SPROING 41
+#define SND_WARNTON 42
+#define SND_WHOOSH 43
+#define SND_ZISCH 44
+#define SND_SP_BASE 45
+#define SND_SP_INFOTRON 46
+#define SND_SP_ZONKDOWN 47
+#define SND_SP_ZONKPUSH 48
+#define SND_SP_BUG 49
+#define SND_SP_BOOM 50
+#define SND_SP_BOOOM 51
+#define SND_SP_EXIT 52
+#define SND_EMPTY 53
+#define SND_GATE 54
+
+#define NUM_SOUNDS 55
/* default input keys */
-#define KEY_UNDEFINDED XK_VoidSymbol
-#define DEFAULT_KEY_LEFT XK_Left
-#define DEFAULT_KEY_RIGHT XK_Right
-#define DEFAULT_KEY_UP XK_Up
-#define DEFAULT_KEY_DOWN XK_Down
-#define DEFAULT_KEY_SNAP XK_Shift_L
-#define DEFAULT_KEY_BOMB XK_Shift_R
-#define DEFAULT_KEY_OKAY XK_Return
-#define DEFAULT_KEY_CANCEL XK_Escape
+#define DEFAULT_KEY_LEFT KSYM_Left
+#define DEFAULT_KEY_RIGHT KSYM_Right
+#define DEFAULT_KEY_UP KSYM_Up
+#define DEFAULT_KEY_DOWN KSYM_Down
+#define DEFAULT_KEY_SNAP KSYM_Shift_L
+#define DEFAULT_KEY_BOMB KSYM_Shift_R
+#define DEFAULT_KEY_OKAY KSYM_Return
+#define DEFAULT_KEY_CANCEL KSYM_Escape
/* directions for moving */
#define MV_NO_MOVING 0
#define MV_UP (1 << 2)
#define MV_DOWN (1 << 3)
-/* font types */
-#define FS_SMALL 0
-#define FS_BIG 1
-#define FS_MEDIUM 2
-/* font colors */
-#define FC_RED 0
-#define FC_BLUE 1
-#define FC_GREEN 2
-#define FC_YELLOW 3
-#define FC_SPECIAL1 4
-#define FC_SPECIAL2 5
-#define FC_SPECIAL3 6
-
/* values for game_status */
#define EXITGAME 0
#define MAINMENU 1
#define SETUPINPUT 9
#define CALIBRATION 10
-#ifndef RO_GAME_DIR
-#define RO_GAME_DIR "."
-#endif
-
-#ifndef RW_GAME_DIR
-#define RW_GAME_DIR "."
-#endif
-
-#define RO_BASE_PATH RO_GAME_DIR
-#define RW_BASE_PATH RW_GAME_DIR
-
-#define GRAPHICS_DIRECTORY "graphics"
-#define SOUNDS_DIRECTORY "sounds"
-#define LEVELS_DIRECTORY "levels"
-#define TAPES_DIRECTORY "tapes"
-#define SCORES_DIRECTORY "scores"
-
-#define PROGRAM_VERSION_STRING "1.4.0"
+#define PROGRAM_VERSION_STRING "2.0.0"
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define WINDOW_TITLE_STRING PROGRAM_TITLE_STRING " " PROGRAM_VERSION_STRING
-#define COPYRIGHT_STRING "Copyright ^1995-99 by " PROGRAM_AUTHOR_STRING
-
-/* default name for empty highscore entry */
-#define EMPTY_PLAYER_NAME "no name"
-
-/* default name for unknown player names */
-#define ANONYMOUS_NAME "anonymous"
-
-/* default name for new levels */
-#define NAMELESS_LEVEL_NAME "nameless level"
-
-/* values for button_status */
-#define MB_NOT_PRESSED FALSE
-#define MB_RELEASED FALSE
-#define MB_PRESSED TRUE
-#define MB_MENU_CHOICE FALSE
-#define MB_MENU_MARK TRUE
-#define MB_MENU_INITIALIZE (-1)
-#define MB_LEFT 1
-#define MB_MIDDLE 2
-#define MB_RIGHT 3
-
-/* values for redraw_mask */
-#define REDRAW_ALL (1 << 0)
-#define REDRAW_FIELD (1 << 1)
-#define REDRAW_TILES (1 << 2)
-#define REDRAW_DOOR_1 (1 << 3)
-#define REDRAW_VIDEO_1 (1 << 4)
-#define REDRAW_VIDEO_2 (1 << 5)
-#define REDRAW_VIDEO_3 (1 << 6)
-#define REDRAW_MICROLEVEL (1 << 7)
-#define REDRAW_FROM_BACKBUFFER (1 << 8)
-#define REDRAW_DOOR_2 (REDRAW_VIDEO_1 | \
- REDRAW_VIDEO_2 | \
- REDRAW_VIDEO_3)
-#define REDRAW_DOOR_3 (1 << 9)
-#define REDRAW_DOORS (REDRAW_DOOR_1 | \
- REDRAW_DOOR_2 | \
- REDRAW_DOOR_3)
-#define REDRAW_MAIN (REDRAW_FIELD | \
- REDRAW_TILES | \
- REDRAW_MICROLEVEL)
-#define REDRAWTILES_THRESHOLD (SCR_FIELDX * SCR_FIELDY / 2)
-
-/* areas in pixmap PIX_DOOR */
-/* meaning in PIX_DB_DOOR: (3 PAGEs)
- PAGEX1: 1. buffer for DOOR_1
- PAGEX2: 2. buffer for DOOR_1
- PAGEX3: buffer for animations
-*/
-
-#define DOOR_GFX_PAGESIZE DXSIZE
-#define DOOR_GFX_PAGEX1 (0 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX2 (1 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX3 (2 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX4 (3 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX5 (4 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX6 (5 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX7 (6 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEX8 (7 * DOOR_GFX_PAGESIZE)
-#define DOOR_GFX_PAGEY1 0
-#define DOOR_GFX_PAGEY2 DYSIZE
+#define PROGRAM_RIGHTS_STRING "Copyright ^1995-2000 by"
+#define PROGRAM_DOS_PORT_STRING "DOS port done by Guido Schulz"
+#define PROGRAM_IDENT_STRING PROGRAM_VERSION_STRING " " TARGET_STRING
+#define WINDOW_TITLE_STRING PROGRAM_TITLE_STRING " " PROGRAM_IDENT_STRING
+#define WINDOW_SUBTITLE_STRING PROGRAM_RIGHTS_STRING " " PROGRAM_AUTHOR_STRING
+#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
+#define UNIX_USERDATA_DIRECTORY ".rocksndiamonds"
+
+#define X11_ICON_FILENAME "rocks_icon.xbm"
+#define X11_ICONMASK_FILENAME "rocks_iconmask.xbm"
+#define MSDOS_POINTER_FILENAME "mouse.pcx"
/* for DrawGraphicAnimation() [tools.c] and AnimateToon() [cartoons.c] */
#define ANIM_NORMAL 0
+++ /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 <pwd.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include "misc.h"
-#include "init.h"
-#include "tools.h"
-#include "sound.h"
-#include "random.h"
-#include "joystick.h"
-#include "files.h"
-
-#ifdef 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
-
-#ifndef MSDOS
-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);
-
- 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
-
-void InitCounter() /* set counter back to zero */
-{
-#ifndef 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() */
-{
-#ifndef 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);
-
-#ifdef 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
- {
- 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");
- }
-}
-
-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)
-{
- 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);
-}
-
-#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)
-{
- 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;
- }
-}
-
-char *getLoginName()
-{
- struct passwd *pwd;
-
- if ((pwd = getpwuid(getuid())) == NULL)
- return ANONYMOUS_NAME;
- else
- return pwd->pw_name;
-}
-
-char *getRealName()
-{
-#ifndef MSDOS
- 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
- return ANONYMOUS_NAME;
-#endif
-}
-
-char *getHomeDir()
-{
-#ifndef MSDOS
- 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;
-
- 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 (*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;
-
-#ifdef MSDOS
- 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(KeySym *keysym, char **x11name, char **name, int mode)
-{
- static struct
- {
- KeySym keysym;
- char *x11name;
- char *name;
- } translate_key[] =
- {
- /* normal cursor keys */
- { XK_Left, "XK_Left", "cursor left" },
- { XK_Right, "XK_Right", "cursor right" },
- { XK_Up, "XK_Up", "cursor up" },
- { XK_Down, "XK_Down", "cursor down" },
-
- /* keypad cursor keys */
-#ifdef XK_KP_Left
- { XK_KP_Left, "XK_KP_Left", "keypad left" },
- { XK_KP_Right, "XK_KP_Right", "keypad right" },
- { XK_KP_Up, "XK_KP_Up", "keypad up" },
- { XK_KP_Down, "XK_KP_Down", "keypad down" },
-#endif
-
- /* other keypad keys */
-#ifdef XK_KP_Enter
- { XK_KP_Enter, "XK_KP_Enter", "keypad enter" },
- { XK_KP_Add, "XK_KP_Add", "keypad +" },
- { XK_KP_Subtract, "XK_KP_Subtract", "keypad -" },
- { XK_KP_Multiply, "XK_KP_Multiply", "keypad mltply" },
- { XK_KP_Divide, "XK_KP_Divide", "keypad /" },
- { XK_KP_Separator, "XK_KP_Separator", "keypad ," },
-#endif
-
- /* modifier keys */
- { XK_Shift_L, "XK_Shift_L", "left shift" },
- { XK_Shift_R, "XK_Shift_R", "right shift" },
- { XK_Control_L, "XK_Control_L", "left control" },
- { XK_Control_R, "XK_Control_R", "right control" },
- { XK_Meta_L, "XK_Meta_L", "left meta" },
- { XK_Meta_R, "XK_Meta_R", "right meta" },
- { XK_Alt_L, "XK_Alt_L", "left alt" },
- { XK_Alt_R, "XK_Alt_R", "right alt" },
- { XK_Mode_switch, "XK_Mode_switch", "mode switch" },
- { XK_Multi_key, "XK_Multi_key", "multi key" },
-
- /* some special keys */
- { XK_BackSpace, "XK_BackSpace", "backspace" },
- { XK_Delete, "XK_Delete", "delete" },
- { XK_Insert, "XK_Insert", "insert" },
- { XK_Tab, "XK_Tab", "tab" },
- { XK_Home, "XK_Home", "home" },
- { XK_End, "XK_End", "end" },
- { XK_Page_Up, "XK_Page_Up", "page up" },
- { XK_Page_Down, "XK_Page_Down", "page down" },
-
-
- /* ASCII 0x20 to 0x40 keys (except numbers) */
- { XK_space, "XK_space", "space" },
- { XK_exclam, "XK_exclam", "!" },
- { XK_quotedbl, "XK_quotedbl", "\"" },
- { XK_numbersign, "XK_numbersign", "#" },
- { XK_dollar, "XK_dollar", "$" },
- { XK_percent, "XK_percent", "%" },
- { XK_ampersand, "XK_ampersand", "&" },
- { XK_apostrophe, "XK_apostrophe", "'" },
- { XK_parenleft, "XK_parenleft", "(" },
- { XK_parenright, "XK_parenright", ")" },
- { XK_asterisk, "XK_asterisk", "*" },
- { XK_plus, "XK_plus", "+" },
- { XK_comma, "XK_comma", "," },
- { XK_minus, "XK_minus", "-" },
- { XK_period, "XK_period", "." },
- { XK_slash, "XK_slash", "/" },
- { XK_colon, "XK_colon", ":" },
- { XK_semicolon, "XK_semicolon", ";" },
- { XK_less, "XK_less", "<" },
- { XK_equal, "XK_equal", "=" },
- { XK_greater, "XK_greater", ">" },
- { XK_question, "XK_question", "?" },
- { XK_at, "XK_at", "@" },
-
- /* more ASCII keys */
- { XK_bracketleft, "XK_bracketleft", "[" },
- { XK_backslash, "XK_backslash", "backslash" },
- { XK_bracketright, "XK_bracketright", "]" },
- { XK_asciicircum, "XK_asciicircum", "circumflex" },
- { XK_underscore, "XK_underscore", "_" },
- { XK_grave, "XK_grave", "grave" },
- { XK_quoteleft, "XK_quoteleft", "quote left" },
- { XK_braceleft, "XK_braceleft", "brace left" },
- { XK_bar, "XK_bar", "bar" },
- { XK_braceright, "XK_braceright", "brace right" },
- { XK_asciitilde, "XK_asciitilde", "ascii tilde" },
-
- /* special (non-ASCII) keys */
- { XK_Adiaeresis, "XK_Adiaeresis", "Ä" },
- { XK_Odiaeresis, "XK_Odiaeresis", "Ö" },
- { XK_Udiaeresis, "XK_Udiaeresis", "Ü" },
- { XK_adiaeresis, "XK_adiaeresis", "ä" },
- { XK_odiaeresis, "XK_odiaeresis", "ö" },
- { XK_udiaeresis, "XK_udiaeresis", "ü" },
- { XK_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];
- KeySym key = *keysym;
-
- if (key >= XK_A && key <= XK_Z)
- sprintf(name_buffer, "%c", 'A' + (char)(key - XK_A));
- else if (key >= XK_a && key <= XK_z)
- sprintf(name_buffer, "%c", 'a' + (char)(key - XK_a));
- else if (key >= XK_0 && key <= XK_9)
- sprintf(name_buffer, "%c", '0' + (char)(key - XK_0));
- else if (key >= XK_KP_0 && key <= XK_KP_9)
- sprintf(name_buffer, "keypad %c", '0' + (char)(key - XK_KP_0));
- else if (key >= XK_F1 && key <= XK_F24)
- sprintf(name_buffer, "function F%d", (int)(key - XK_F1 + 1));
- else if (key == KEY_UNDEFINDED)
- strcpy(name_buffer, "(undefined)");
- else
- {
- i = 0;
-
- do
- {
- if (key == translate_key[i].keysym)
- {
- 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];
- KeySym key = *keysym;
-
- if (key >= XK_A && key <= XK_Z)
- sprintf(name_buffer, "XK_%c", 'A' + (char)(key - XK_A));
- else if (key >= XK_a && key <= XK_z)
- sprintf(name_buffer, "XK_%c", 'a' + (char)(key - XK_a));
- else if (key >= XK_0 && key <= XK_9)
- sprintf(name_buffer, "XK_%c", '0' + (char)(key - XK_0));
- else if (key >= XK_KP_0 && key <= XK_KP_9)
- sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - XK_KP_0));
- else if (key >= XK_F1 && key <= XK_F24)
- sprintf(name_buffer, "XK_F%d", (int)(key - XK_F1 + 1));
- else if (key == KEY_UNDEFINDED)
- strcpy(name_buffer, "[undefined]");
- else
- {
- i = 0;
-
- do
- {
- if (key == translate_key[i].keysym)
- {
- 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)
- {
- KeySym key = XK_VoidSymbol;
- 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 = XK_A + (KeySym)(c - 'A');
- else if (c >= 'a' && c <= 'z')
- key = XK_a + (KeySym)(c - 'a');
- else if (c >= '0' && c <= '9')
- key = XK_0 + (KeySym)(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 = XK_0 + (KeySym)(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 = XK_F1 + (KeySym)(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].keysym;
- 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 = (KeySym)value;
- }
-
- *keysym = key;
- }
-}
-
-char *getKeyNameFromKeySym(KeySym keysym)
-{
- char *name;
-
- translate_keyname(&keysym, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME);
- return name;
-}
-
-char *getX11KeyNameFromKeySym(KeySym keysym)
-{
- char *x11name;
-
- translate_keyname(&keysym, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME);
- return x11name;
-}
-
-KeySym getKeySymFromX11KeyName(char *x11name)
-{
- KeySym keysym;
-
- translate_keyname(&keysym, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM);
- return keysym;
-}
-
-char getCharFromKeySym(KeySym keysym)
-{
- char *keyname = getKeyNameFromKeySym(keysym);
- 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) /* start with first level directory entry */
- return getFirstValidLevelSeries(leveldir_first);
- 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;
- }
-}
-
-
-/* ------------------------------------------------------------------------- */
-/* 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 *getKeyNameFromKeySym(KeySym);
-char *getX11KeyNameFromKeySym(KeySym);
-KeySym getKeySymFromX11KeyName(char *);
-char getCharFromKeySym(KeySym);
-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 *));
-
-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 *
-***********************************************************/
-
-#ifdef 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_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;
-
- reserve_voices(MAX_SOUNDS_PLAYING, 0);
- if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1)
- if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1)
- sound_status = SOUND_OFF;
-}
-
-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_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 XpmReadFileToPixmap(Display *display, Drawable d, char *filename,
- Pixmap *pixmap_return, Pixmap *shapemask_return,
- XpmAttributes *attributes)
-{
- BITMAP *bitmap;
-
- if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
- return XpmOpenFailed;
-
- *pixmap_return = (Pixmap)bitmap;
-
- return XpmSuccess;
-}
-
-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;
-}
-
-void NetworkServer(int port, int serveronly)
-{
- Error(ERR_WARN, "networking not supported in DOS version");
-}
-
-#endif /* 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 *
-***********************************************************/
-
-#include <allegro.h>
-#include <time.h>
-
-/* 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 XpmFreeAttributes(a)
-#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 XpmSuccess 0
-#define XpmOpenFailed -1
-#define XpmFileInvalid -2
-#define XpmNoMemory -3
-#define XpmColorFailed -4
-
-#define XpmCloseness (1L << 12)
-
-#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
-{
- unsigned long valuemask; /* specifies which attributes are */
- unsigned int closeness; /* allowable RGB deviation */
- Pixel *pixels; /* list of used color pixels */
- unsigned int npixels; /* number of used pixels */
-} XpmAttributes;
-
-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;
-
-unsigned char get_ascii(KeySym);
-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 XpmReadFileToPixmap(Display *, Drawable, char *, Pixmap *, Pixmap *,
- XpmAttributes *);
-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 *);
-void NetworkServer(int, int);
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* network.c *
+* network.c *
***********************************************************/
-#ifndef MSDOS
+#include "libgame/libgame.h"
+
+#if defined(PLATFORM_UNIX)
-#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <signal.h>
#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;
}
}
-#endif /* !MSDOS */
+#endif /* PLATFORM_UNIX */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* netserv.h *
+* netserv.h *
***********************************************************/
#ifndef NETSERV_H
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* network.c *
+* network.c *
***********************************************************/
-#ifndef MSDOS
+#include "libgame/libgame.h"
+
+#if defined(PLATFORM_UNIX)
-#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#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
{
buffer[8] = (unsigned char)((new_random_seed >> 8) & 0xff);
buffer[9] = (unsigned char)((new_random_seed >> 0) & 0xff);
- strcpy((char *)&buffer[10], leveldir_current->name);
+ strcpy((char *)&buffer[10], leveldir_current->filename);
- SendBufferToServer(10 + strlen(leveldir_current->name) + 1);
+ SendBufferToServer(10 + strlen(leveldir_current->filename) + 1);
}
void SendToServer_PausePlaying()
int new_level_nr;
int dummy; /* !!! HAS NO MEANING ANYMORE !!! */
unsigned long new_random_seed;
- char *new_leveldir_name;
+ char *new_leveldir_filename;
new_level_nr = (buffer[2] << 8) + buffer[3];
dummy = (buffer[4] << 8) + buffer[5];
new_random_seed =
(buffer[6] << 24) | (buffer[7] << 16) | (buffer[8] << 8) | (buffer[9]);
- new_leveldir_name = (char *)&buffer[10];
+ new_leveldir_filename = (char *)&buffer[10];
- new_leveldir = getLevelDirInfoFromFilename(new_leveldir_name);
+ new_leveldir = getLevelDirInfoFromFilename(new_leveldir_filename);
if (new_leveldir == NULL)
{
- Error(ERR_WARN, "no such level directory: '%s'", new_leveldir_name);
+ Error(ERR_WARN, "no such level directory: '%s'", new_leveldir_filename);
new_leveldir = leveldir_first;
Error(ERR_WARN, "using default level directory: '%s'", new_leveldir->name);
}
}
-#endif /* !MSDOS */
+#endif /* PLATFORM_UNIX */
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* network.h *
+* network.h *
***********************************************************/
#ifndef NETWORK_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 *
-***********************************************************/
-
-#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;
-}
+++ /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 "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 /* PCX_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
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* screens.c *
+* 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"
static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
-#ifdef MSDOS
-extern unsigned char get_ascii(KeySym);
-#endif
-
void DrawHeadline()
{
int x = SX + (SXSIZE - strlen(PROGRAM_TITLE_STRING) * FONT1_XSIZE) / 2;
DrawText(x, SY + 8, PROGRAM_TITLE_STRING, FS_BIG, FC_YELLOW);
- DrawTextFCentered(46, FC_RED, COPYRIGHT_STRING);
+ DrawTextFCentered(46, FC_RED, WINDOW_SUBTITLE_STRING);
+}
+
+static void ToggleFullscreenIfNeeded()
+{
+ if (setup.fullscreen != video.fullscreen_enabled)
+ {
+ /* save old door content */
+ BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ /* toggle fullscreen */
+ ChangeVideoModeIfNeeded(setup.fullscreen);
+ setup.fullscreen = video.fullscreen_enabled;
+
+ /* redraw background to newly created backbuffer */
+ BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
+
+ /* restore old door content */
+ BlitBitmap(pix[PIX_DB_DOOR], backbuffer,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+
+ redraw_mask = REDRAW_ALL;
+ }
}
void DrawMainMenu()
UnmapAllGadgets();
FadeSounds();
- XAutoRepeatOn(display);
+ KeyboardAutoRepeatOn();
/* needed if last screen was the playing screen, invoked from level editor */
if (level_editor_test_game)
/* needed if last screen was the editor screen */
UndrawSpecialEditorDoor();
+ /* needed if last screen was the setup screen and fullscreen state changed */
+ ToggleFullscreenIfNeeded();
+
+#ifdef TARGET_SDL
+ SetDrawtoField(DRAW_BACKBUFFER);
+#endif
+
/* map gadgets for main menu screen */
MapTapeButtons();
level_nr = new_level_nr;
- DrawTextExt(drawto, gc, SX + 11 * 32, SY + 3 * 32,
+ DrawTextExt(drawto, SX + 11 * 32, SY + 3 * 32,
int2str(level_nr, 3), FS_BIG, font_color);
- DrawTextExt(window, gc, SX + 11 * 32, SY + 3 * 32,
+ DrawTextExt(window, SX + 11 * 32, SY + 3 * 32,
int2str(level_nr, 3), FS_BIG, font_color);
LoadLevel(level_nr);
/* needed because DrawMicroLevel() takes some time */
BackToFront();
- XSync(display, FALSE);
+ SyncDisplay();
DelayReached(&level_delay, 0); /* reset delay counter */
}
else if (x == 1 && y >= 3 && y <= 10)
if (setup.autorecord)
TapeStartRecording();
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (options.network)
SendToServer_StartPlaying();
else
{ "Voyager", "The Alan Parsons Project","Pyramid" },
{ "Twilight Painter", "Tangerine Dream", "Heartbreakers" }
};
+static int num_helpscreen_music = 7;
static int helpscreen_musicpos;
void DrawHelpScreenElAction(int start)
}
j++;
- DrawGraphicExt(drawto, gc, xstart, ystart+(i-start)*ystep, graphic+frame);
+ DrawGraphicExt(drawto, xstart, ystart+(i-start)*ystep, graphic+frame);
i++;
}
DrawTextFCentered(ybottom, FC_BLUE, "Press any key or button for next page");
+#if 0
PlaySoundLoop(background_loop[num]);
+#endif
}
void DrawHelpScreenCreditsText()
DrawTextFCentered(100, FC_GREEN,
"Credits:");
DrawTextFCentered(ystart + 0 * ystep, FC_YELLOW,
- "DOS/Windows port of the game:");
+ "DOS port of the game:");
DrawTextFCentered(ystart + 1 * ystep, FC_RED,
"Guido Schulz");
DrawTextFCentered(ystart + 2 * ystep, FC_YELLOW,
DrawTextFCentered(ystart + 1 * ystep, FC_YELLOW,
"If you like it, send e-mail to:");
DrawTextFCentered(ystart + 2 * ystep, FC_RED,
- "aeglos@valinor.owl.de");
+ "info@artsoft.org");
DrawTextFCentered(ystart + 3 * ystep, FC_YELLOW,
"or SnailMail to:");
DrawTextFCentered(ystart + 4 * ystep + 0, FC_RED,
"Holger Schemel");
DrawTextFCentered(ystart + 4 * ystep + 20, FC_RED,
- "Oststrasse 11a");
+ "Detmolder Strasse 189");
DrawTextFCentered(ystart + 4 * ystep + 40, FC_RED,
"33604 Bielefeld");
DrawTextFCentered(ystart + 4 * ystep + 60, FC_RED,
DrawHelpScreenElText(helpscreen_state*MAX_HELPSCREEN_ELS);
DrawHelpScreenElAction(helpscreen_state*MAX_HELPSCREEN_ELS);
}
- else if (helpscreen_state < num_helpscreen_els_pages + num_bg_loops - 1)
+ else if (helpscreen_state <
+ num_helpscreen_els_pages + num_helpscreen_music - 1)
{
helpscreen_state++;
DrawHelpScreenMusicText(helpscreen_state - num_helpscreen_els_pages);
}
- else if (helpscreen_state == num_helpscreen_els_pages + num_bg_loops - 1)
+ else if (helpscreen_state ==
+ num_helpscreen_els_pages + num_helpscreen_music - 1)
{
helpscreen_state++;
DrawHelpScreenCreditsText();
}
- else if (helpscreen_state == num_helpscreen_els_pages + num_bg_loops)
+ else if (helpscreen_state ==
+ num_helpscreen_els_pages + num_helpscreen_music)
{
helpscreen_state++;
DrawHelpScreenContactText();
BackToFront();
}
-void HandleTypeName(int newxpos, KeySym key)
+void HandleTypeName(int newxpos, Key key)
{
static int xpos = 0, ypos = 2;
return;
}
- if (((key >= XK_A && key <= XK_Z) || (key >= XK_a && key <= XK_z)) &&
+ if (((key >= KSYM_A && key <= KSYM_Z) ||
+ (key >= KSYM_a && key <= KSYM_z)) &&
xpos < MAX_PLAYER_NAME_LEN)
{
char ascii;
- if (key >= XK_A && key <= XK_Z)
- ascii = 'A' + (char)(key - XK_A);
+ if (key >= KSYM_A && key <= KSYM_Z)
+ ascii = 'A' + (char)(key - KSYM_A);
else
- ascii = 'a' + (char)(key - XK_a);
+ ascii = 'a' + (char)(key - KSYM_a);
setup.player_name[xpos] = ascii;
setup.player_name[xpos + 1] = 0;
xpos++;
- DrawTextExt(drawto, gc, SX + 6*32, SY + ypos*32,
+ DrawTextExt(drawto, SX + 6*32, SY + ypos*32,
setup.player_name, FS_BIG, FC_YELLOW);
- DrawTextExt(window, gc, SX + 6*32, SY + ypos*32,
+ DrawTextExt(window, SX + 6*32, SY + ypos*32,
setup.player_name, FS_BIG, FC_YELLOW);
DrawGraphic(xpos + 6, ypos, GFX_KUGEL_ROT);
}
- else if ((key == XK_Delete || key == XK_BackSpace) && xpos > 0)
+ else if ((key == KSYM_Delete || key == KSYM_BackSpace) && xpos > 0)
{
xpos--;
setup.player_name[xpos] = 0;
DrawGraphic(xpos + 6, ypos, GFX_KUGEL_ROT);
DrawGraphic(xpos + 7, ypos, GFX_LEERRAUM);
}
- else if (key == XK_Return && xpos > 0)
+ else if (key == KSYM_Return && xpos > 0)
{
DrawText(SX + 6*32, SY + ypos*32, setup.player_name, FS_BIG, FC_RED);
DrawGraphic(xpos + 6, ypos, GFX_LEERRAUM);
int max_buffer_len = (SCR_FIELDX - 2) * 2;
int num_leveldirs = numLevelDirInfoInGroup(leveldir_current);
- XFillRectangle(display, backbuffer, gc, SX, SY, SXSIZE - 32, SYSIZE);
+ ClearRectangle(backbuffer, SX, SY, SXSIZE - 32, SYSIZE);
redraw_mask |= REDRAW_FIELD;
DrawText(SX, SY, "Level Directories", FS_BIG, FC_GREEN);
node_first = getLevelDirInfoFirstGroupEntry(leveldir_current);
node = getLevelDirInfoFromPos(node_first, leveldir_pos);
- XFillRectangle(display, drawto, gc, SX + 32, SY + 32, SXSIZE - 64, 32);
+ ClearRectangle(drawto, SX + 32, SY + 32, SXSIZE - 64, 32);
if (node->parent_link)
DrawTextFCentered(40, FC_RED, "leave group \"%s\"", node->class_desc);
else
x = y = 0; /* no action */
- if (ABS(dy) == SCR_FIELDY) /* handle XK_Page_Up, XK_Page_Down */
+ if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
{
dy = SIGN(dy);
step = num_page_entries - 1;
return;
}
- if (ABS(dy) == SCR_FIELDY) /* handle XK_Page_Up, XK_Page_Down */
+ if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
step = MAX_LEVEL_SERIES_ON_SCREEN - 1;
if (dy < 0)
#endif
{ &setup.scroll_delay, "Scroll Delay:" },
{ &setup.soft_scrolling, "Soft Scroll.:" },
+#if 0
{ &setup.fading, "Fading:" },
+#endif
+ { &setup.fullscreen, "Fullscreen:" },
{ &setup.quick_doors, "Quick Doors:" },
{ &setup.autorecord, "Auto-Record:" },
{ &setup.team_mode, "Team-Mode:" },
{
int yy = y-1;
- if (y==3 && sound_status==SOUND_AVAILABLE)
+ if (y == 3 && audio.sound_available)
{
if (setup.sound)
{
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.sound = !setup.sound;
}
- else if (y==4 && sound_loops_allowed)
+ else if (y == 4 && audio.loops_available)
{
if (setup.sound_loops)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
}
setup.sound_loops = !setup.sound_loops;
}
- else if (y==5 && sound_loops_allowed)
+ else if (y == 5 && audio.loops_available)
{
if (setup.sound_music)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
}
#if 0
- else if (y==6)
+ else if (y == 6)
{
if (setup.toons)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.toons = !setup.toons;
}
- else if (y==7)
+ else if (y == 7)
{
#if 0
if (setup.double_buffering)
}
#endif
- else if (y==6)
+ else if (y == 6)
{
if (setup.scroll_delay)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.scroll_delay = !setup.scroll_delay;
}
- else if (y==7)
+ else if (y == 7)
{
if (setup.soft_scrolling)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.soft_scrolling = !setup.soft_scrolling;
}
- else if (y==8)
+#if 0
+ else if (y == 8)
{
if (setup.fading)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.fading = !setup.fading;
}
- else if (y==9)
+#endif
+ else if (y == 8 && video.fullscreen_available)
+ {
+ if (setup.fullscreen)
+ DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
+ else
+ DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
+ setup.fullscreen = !setup.fullscreen;
+ }
+ else if (y == 9)
{
if (setup.quick_doors)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.quick_doors = !setup.quick_doors;
}
- else if (y==10)
+ else if (y == 10)
{
if (setup.autorecord)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.autorecord = !setup.autorecord;
}
- else if (y==11)
+ else if (y == 11)
{
if (setup.team_mode)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.team_mode = !setup.team_mode;
}
- else if (y==12)
+ else if (y == 12)
{
if (setup.handicap)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.handicap = !setup.handicap;
}
- else if (y==13)
+ else if (y == 13)
{
if (setup.time_limit)
DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
DrawText(SX+14*32, SY+yy*32,"on ",FS_BIG,FC_YELLOW);
setup.time_limit = !setup.time_limit;
}
- else if (y==14)
+ else if (y == 14)
{
game_status = SETUPINPUT;
DrawSetupInputScreen();
SaveJoystickData();
*/
-#ifdef MSDOS
+#if defined(PLATFORM_MSDOS)
save_joystick_data(JOYSTICK_FILENAME);
#endif
static struct SetupKeyboardInfo custom_key;
static struct
{
- KeySym *keysym;
+ Key *key;
char *text;
} custom[] =
{
DrawText(SX + 3*32, SY + ypos*32,
(setup.input[player_nr].use_joystick ?
custom[i].text :
- getKeyNameFromKeySym(*custom[i].keysym)),
+ getKeyNameFromKey(*custom[i].key)),
FS_BIG, FC_YELLOW);
}
}
static struct SetupKeyboardInfo custom_key;
static struct
{
- KeySym *keysym;
+ Key *key;
char *text;
} customize_step[] =
{
DrawText(SX, SY + (2+2*step_nr+1)*32,
"Key:", FS_BIG, FC_RED);
DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
- getKeyNameFromKeySym(*customize_step[step_nr].keysym),
+ getKeyNameFromKey(*customize_step[step_nr].key),
FS_BIG, FC_BLUE);
while(!finished)
{
- if (XPending(display)) /* got event from X server */
+ if (PendingEvent()) /* got event */
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
+ NextEvent(&event);
switch(event.type)
{
- case KeyPress:
+ case EVENT_KEYPRESS:
{
- KeySym key = XLookupKeysym((XKeyEvent *)&event,
- ((XKeyEvent *)&event)->state);
+ Key key = GetEventKey((KeyEvent *)&event, TRUE);
- if (key == XK_Escape || (key == XK_Return && step_nr == 6))
+ if (key == KSYM_Escape || (key == KSYM_Return && step_nr == 6))
{
finished = TRUE;
break;
}
+ /* all keys configured -- wait for "Escape" or "Return" key */
+ if (step_nr == 6)
+ break;
+
/* press 'Enter' to keep the existing key binding */
- if (key == XK_Return || step_nr == 6)
- key = *customize_step[step_nr].keysym;
+ if (key == KSYM_Return)
+ key = *customize_step[step_nr].key;
/* check if key already used */
for (i=0; i<step_nr; i++)
- if (*customize_step[i].keysym == key)
+ if (*customize_step[i].key == key)
break;
if (i < step_nr)
break;
/* got new key binding */
- *customize_step[step_nr].keysym = key;
+ *customize_step[step_nr].key = key;
DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
" ", FS_BIG, FC_YELLOW);
DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
- getKeyNameFromKeySym(key), FS_BIG, FC_YELLOW);
+ getKeyNameFromKey(key), FS_BIG, FC_YELLOW);
step_nr++;
/* un-highlight last query */
DrawText(SX, SY+(2+2*step_nr+1)*32,
"Key:", FS_BIG, FC_RED);
DrawText(SX + 4*32, SY+(2+2*step_nr+1)*32,
- getKeyNameFromKeySym(*customize_step[step_nr].keysym),
+ getKeyNameFromKey(*customize_step[step_nr].key),
FS_BIG, FC_BLUE);
}
break;
- case KeyRelease:
+ case EVENT_KEYRELEASE:
key_joystick_mapping = 0;
break;
} joy_ctrl;
#endif
-#ifndef MSDOS
+#if !defined(PLATFORM_MSDOS)
int new_joystick_xleft = 128, new_joystick_xright = 128;
int new_joystick_yupper = 128, new_joystick_ylower = 128;
int new_joystick_xmiddle, new_joystick_ymiddle;
ClearWindow();
-#ifndef MSDOS
+#if !defined(PLATFORM_MSDOS)
DrawText(SX, SY + 6*32, " ROTATE JOYSTICK ", FS_BIG, FC_YELLOW);
DrawText(SX, SY + 7*32, "IN ALL DIRECTIONS", FS_BIG, FC_YELLOW);
DrawText(SX + 16, SY + 9*32, " IF ALL BALLS ", FS_BIG, FC_YELLOW);
while(result < 0)
{
- if (XPending(display)) /* got event from X server */
+ if (PendingEvent()) /* got event */
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
+ NextEvent(&event);
switch(event.type)
{
- case KeyPress:
- switch(XLookupKeysym((XKeyEvent *)&event,
- ((XKeyEvent *)&event)->state))
+ case EVENT_KEYPRESS:
+ switch(GetEventKey((KeyEvent *)&event, TRUE))
{
- case XK_Return:
+ case KSYM_Return:
if (check_remaining == 0)
result = 1;
break;
- case XK_Escape:
+ case KSYM_Escape:
result = 0;
break;
}
break;
- case KeyRelease:
+ case EVENT_KEYRELEASE:
key_joystick_mapping = 0;
break;
}
}
-#ifndef MSDOS
+#if !defined(PLATFORM_MSDOS)
+
+#if defined(TARGET_SDL)
+ joy_ctrl.x = Get_SDL_Joystick_Axis(joystick_fd, 0);
+ joy_ctrl.y = Get_SDL_Joystick_Axis(joystick_fd, 1);
+#else
if (read(joystick_fd, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
{
joystick_status = JOYSTICK_OFF;
goto error_out;
}
+#endif
new_joystick_xleft = MIN(new_joystick_xleft, joy_ctrl.x);
new_joystick_xright = MAX(new_joystick_xright, joy_ctrl.x);
{
result = 1;
-#ifdef MSDOS
+#if defined(PLATFORM_MSDOS)
if (calibration_step == 1)
{
remove_joystick();
if (x != last_x || y != last_y)
{
-#ifndef MSDOS
+#if !defined(PLATFORM_MSDOS)
DrawGraphic(xpos + last_x, ypos + last_y, GFX_KUGEL_GELB);
#else
DrawGraphic(xpos + last_x, ypos + last_y, GFX_KUGEL_BLAU);
StopAnimation();
DrawSetupInputScreen();
- while(Joystick(player_nr) & JOY_BUTTON);
+
+ /* wait until the last pressed button was released */
+ while(Joystick(player_nr) & JOY_BUTTON)
+ {
+ if (PendingEvent()) /* got event */
+ {
+ Event event;
+
+ NextEvent(&event);
+ HandleOtherEvents(&event);
+
+ Delay(10);
+ }
+ }
return;
error_out:
static void CreateScreenScrollbuttons()
{
- Pixmap gd_pixmap = pix[PIX_MORE];
+ Bitmap *gd_bitmap = pix[PIX_MORE];
struct GadgetInfo *gi;
unsigned long event_mask;
int i;
GDI_HEIGHT, height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ 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_ACTION, HandleScreenGadgets,
GDI_END);
for (i=0; i<NUM_SCREEN_SCROLLBARS; i++)
{
int id = scrollbar_info[i].gadget_id;
- Pixmap gd_pixmap = pix[PIX_MORE];
+ Bitmap *gd_bitmap = pix[PIX_MORE];
int gd_x1, gd_x2, gd_y1, gd_y2;
struct GadgetInfo *gi;
int items_max, items_visible, item_position;
GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
GDI_SCROLLBAR_ITEM_POSITION, item_position,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
GDI_BORDER_SIZE, SC_BORDER_SIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_ACTION, HandleScreenGadgets,
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* screens.h *
+* screens.h *
***********************************************************/
#ifndef SCREENS_H
void DrawHelpScreenCreditsText(void);
void DrawHelpScreen(void);
void HandleHelpScreen(int);
-void HandleTypeName(int, KeySym);
+void HandleTypeName(int, Key);
void DrawChooseLevel(void);
void HandleChooseLevel(int, int, int, int, int);
void DrawHallOfFame(int);
+++ /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
-};
-
-#ifndef MSDOS
-static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
-static char premix_first_buffer[SND_BLOCKSIZE];
-#ifdef VOXWARE
-static char premix_left_buffer[SND_BLOCKSIZE];
-static char premix_right_buffer[SND_BLOCKSIZE];
-static int premix_last_buffer[SND_BLOCKSIZE];
-#endif /* VOXWARE */
-static unsigned char playing_buffer[SND_BLOCKSIZE];
-#endif /* MSDOS */
-
-/* forward declaration of internal functions */
-#ifdef VOXWARE
-static void SoundServer_InsertNewSound(struct SoundControl);
-#endif
-#ifndef VOXWARE
-#ifndef MSDOS
-static unsigned char linear_to_ulaw(int);
-static int ulaw_to_linear(unsigned char);
-#endif
-#endif
-#ifdef HPUX_AUDIO
-static void HPUX_Audio_Control();
-#endif
-#ifdef MSDOS
-static void SoundServer_InsertNewSound(struct SoundControl);
-static void SoundServer_StopSound(int);
-static void SoundServer_StopAllSounds();
-#endif
-
-void SoundServer()
-{
- int i;
-#ifndef MSDOS
- struct SoundControl snd_ctrl;
- fd_set sound_fdset;
-
- close(sound_pipe[1]); /* no writing into pipe needed */
-#endif
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- playlist[i] = emptySoundControl;
- playing_sounds = 0;
-
-#ifndef MSDOS
- 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));
-
-#ifdef HPUX_AUDIO
- HPUX_Audio_Control();
-#endif
-
- FD_ZERO(&sound_fdset);
- FD_SET(sound_pipe[0], &sound_fdset);
-
- while(1) /* wait for sound playing commands from client */
- {
- FD_SET(sound_pipe[0], &sound_fdset);
- select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
- if (!FD_ISSET(sound_pipe[0], &sound_fdset))
- continue;
- if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
- Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
-
-#ifdef VOXWARE
-
- 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(sound_device);
- }
- 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(sound_device);
- }
-
- 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;
- int sample_rate = 8000;
-
- if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=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(sound_device, 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(sound_device, 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(sound_device, 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(sound_device, 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(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
- {
- FD_SET(sound_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(sound_device,playing_buffer,fragment_size);
- }
-
- /* if no sounds playing, free device for other sound programs */
- if (!playing_sounds)
- close(sound_device);
- }
- }
-
-#else /* !VOXWARE */
-
- 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 ((sound_device=open(sound_device_name,O_WRONLY))>=0)
- {
- playing_sounds = 1;
-
- while(playing_sounds &&
- select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
- {
- FD_SET(sound_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(sound_device,playing_buffer,sample_size);
-
- delay.tv_sec = 0;
- delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
- }
- close(sound_device);
- }
- }
-
-#endif /* !VOXWARE */
-
- }
-#endif /* !MSDOS */
-}
-
-#ifdef 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 /* MSDOS */
-
-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++)
- {
-#ifndef 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;
- }
- }
-#ifdef 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;
-#ifdef 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;
-
-#ifndef MSDOS
- actual = 100 * playlist[i].playingpos / playlist[i].data_len;
-#else
- actual = playlist[i].playingpos;
-#endif
- if (actual>=longest)
- {
- longest=actual;
- longest_nr=i;
- }
- }
-#ifdef 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++;
-#ifdef 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;
- }
- }
-}
-
-/*
-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;
-}
-*/
-
-#ifdef 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)
- {
-#ifdef MSDOS
- voice_set_volume(playlist[i].voice, 0);
- deallocate_voice(playlist[i].voice);
-#endif
- playlist[i] = emptySoundControl;
- playing_sounds--;
- }
-
-#ifndef MSDOS
- if (!playing_sounds)
- close(sound_device);
-#endif
-}
-
-static void SoundServer_StopAllSounds()
-{
- int i;
-
- for(i=0;i<MAX_SOUNDS_PLAYING;i++)
- {
-#ifdef MSDOS
- voice_set_volume(playlist[i].voice, 0);
- deallocate_voice(playlist[i].voice);
-#endif
- playlist[i]=emptySoundControl;
- }
- playing_sounds = 0;
-
-#ifndef MSDOS
- close(sound_device);
-#endif
-}
-#endif /* MSDOS */
-
-#ifdef HPUX_AUDIO
-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 /* HPUX_AUDIO */
-
-#ifndef VOXWARE
-#ifndef MSDOS
-/* 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 /* !MSDOS */
-#endif /* !VOXWARE */
-
-/*** 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 SoundInfo *snd_info)
-{
- char filename[256];
- char *sound_ext = "wav";
-#ifndef MSDOS
- byte sound_header_buffer[WAV_HEADER_SIZE];
- char chunk[CHUNK_ID_LEN + 1];
- int chunk_length, dummy;
- FILE *file;
- int i;
-#endif
-
- sprintf(filename, "%s/%s/%s.%s",
- options.ro_base_directory, SOUNDS_DIRECTORY,
- snd_info->name, sound_ext);
-
-#ifndef 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 /* 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 /* MSDOS */
-
- 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 (sound_status==SOUND_OFF || !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;
-
-#ifndef MSDOS
- if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
- {
- Error(ERR_WARN, "cannot pipe to child process - no sounds");
- sound_status = SOUND_OFF;
- return;
- }
-#else
- sound_handler(snd_ctrl);
-#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 (sound_status==SOUND_OFF)
- 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;
- }
-
-#ifndef MSDOS
- if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
- {
- Error(ERR_WARN, "cannot pipe to child process - no sounds");
- sound_status = SOUND_OFF;
- return;
- }
-#else
- sound_handler(snd_ctrl);
-#endif
-}
-
-void FreeSounds(int num_sounds)
-{
- int i;
-
- if (sound_status == SOUND_OFF)
- return;
-
- for(i=0; i<num_sounds; i++)
-#ifndef 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 <math.h>
-#include "main.h"
-
-#ifdef linux
-#include <linux/soundcard.h>
-#ifndef VOXWARE
-#define VOXWARE
-#endif
-
-#if 0
-/* where is the right declaration for 'ioctl'? */
-extern void ioctl(long, long, void *);
-#else
-#include <sys/ioctl.h>
-#endif
-
-#endif
-
-#ifdef __FreeBSD__
-#include <machine/soundcard.h>
-#endif
-
-#define SND_BLOCKSIZE 4096
-
-#ifdef _HPUX_SOURCE
-#include <sys/audio.h>
-#undef SND_BLOCKSIZE
-#define SND_BLOCKSIZE 32768
-#define HPUX_AUDIO
-#endif /* _HPUX_SOURCE */
-
-#ifndef MSDOS
-#define MAX_SOUNDS_PLAYING 16
-#else
-#define MAX_SOUNDS_PLAYING 8
-#endif
-
-/* some values for PlaySound(), StopSound() and friends */
-#ifndef 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 DEV_AUDIO "/dev/audio"
-#define DEV_DSP "/dev/dsp"
-
-#ifdef VOXWARE
-#define SOUND_DEVICE DEV_DSP
-#else
-#define SOUND_DEVICE DEV_AUDIO
-#endif
-
-#define SOUND_OFF 0
-#define SOUND_AVAILABLE 1
-
-#ifdef NO_SOUNDS
-#define SOUND_STATUS SOUND_OFF
-#else
-#define SOUND_STATUS SOUND_AVAILABLE
-#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 SoundInfo
-{
- char *name;
- byte *data_ptr;
- long data_len;
-#ifdef MSDOS
- SAMPLE *sample_ptr;
-#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;
-#ifdef MSDOS
- int voice;
-#endif
-};
-
-/* start sound server */
-void SoundServer(void);
-
-/* client functions */
-boolean LoadSound(struct SoundInfo *);
-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
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* tape.c *
+* 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"
static struct GadgetInfo *tape_gadget[NUM_TAPE_BUTTONS];
+
+/* ========================================================================= */
+/* video tape definitions */
+/* ========================================================================= */
+
+/* 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)
+
+
+/* ========================================================================= */
+/* video display functions */
+/* ========================================================================= */
+
+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,
+ gfx.vxsize, gfx.vysize, gfx.vx, gfx.vy);
+ BlitBitmap(pix[PIX_DOOR], drawto,
+ DOOR_GFX_PAGEX4 + VIDEO_CONTROL_XPOS,
+ DOOR_GFX_PAGEY2 + VIDEO_CONTROL_YPOS,
+ VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE,
+ gfx.vx + VIDEO_CONTROL_XPOS, gfx.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], gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+}
+
+
+/* ========================================================================= */
+/* tape control functions */
+/* ========================================================================= */
+
void TapeStartRecording()
{
time_t zeit1 = time(NULL);
DrawVideoDisplay(VIDEO_STATE_PBEND_OFF, VIDEO_DISPLAY_LABEL_ONLY);
}
- if (TimePlayed > tape.length_seconds - PAUSE_SECONDS_BEFORE_DEATH)
+ if (TimePlayed > tape.length_seconds - TAPE_PAUSE_SECONDS_BEFORE_DEATH)
{
TapeTogglePause();
return(FALSE);
for (i=0; i<NUM_TAPE_BUTTONS; i++)
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
struct GadgetInfo *gi;
int gd_xoffset, gd_yoffset;
int gd_x1, gd_x2, gd_y;
GDI_HEIGHT, TAPE_BUTTON_YSIZE,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
GDI_EVENT_MASK, GD_EVENT_RELEASED,
GDI_CALLBACK_ACTION, HandleTapeButtons,
GDI_END);
{
TapeStartRecording();
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
if (options.network)
SendToServer_StartPlaying();
else
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* tape.c *
+* tape.h *
***********************************************************/
#ifndef TAPE_H
#include "main.h"
-#define PAUSE_SECONDS_BEFORE_DEATH 3
+#define TAPE_PAUSE_SECONDS_BEFORE_DEATH 3
+
+/* 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);
void TapeStartRecording(void);
void TapeStopRecording(void);
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* tools.c *
+* tools.c *
***********************************************************/
#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"
+#include "tape.h"
-#ifdef MSDOS
+#if defined(PLATFORM_MSDOS)
extern boolean wait_for_vsync;
#endif
void BackToFront()
{
int x,y;
- Drawable buffer = (drawto_field == window ? backbuffer : drawto_field);
+ DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
if (setup.direct_draw && game_status == PLAYING)
redraw_mask &= ~REDRAW_MAIN;
if (!redraw_mask)
return;
+ if (global.fps_slowdown && game_status == PLAYING)
+ {
+ static boolean last_frame_skipped = FALSE;
+ boolean skip_even_when_not_scrolling = TRUE;
+ boolean just_scrolling = (ScreenMovDir != 0);
+ boolean verbose = FALSE;
+
+ if (global.fps_slowdown_factor > 1 &&
+ (FrameCounter % global.fps_slowdown_factor) &&
+ (just_scrolling || skip_even_when_not_scrolling))
+ {
+ redraw_mask &= ~REDRAW_MAIN;
+
+ last_frame_skipped = TRUE;
+
+ if (verbose)
+ printf("FRAME SKIPPED\n");
+ }
+ else
+ {
+ if (last_frame_skipped)
+ redraw_mask |= REDRAW_FIELD;
+
+ last_frame_skipped = FALSE;
+
+ if (verbose)
+ printf("frame not skipped\n");
+ }
+ }
+
/* synchronize X11 graphics at this point; if we would synchronize the
display immediately after the buffer switching (after the XFlush),
this could mean that we have to wait for the graphics to complete,
although we could go on doing calculations for the next frame */
- XSync(display, FALSE);
+ SyncDisplay();
if (redraw_mask & REDRAW_ALL)
{
- XCopyArea(display, backbuffer, window, gc,
- 0, 0, WIN_XSIZE, WIN_YSIZE,
- 0, 0);
+ BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
redraw_mask = 0;
}
{
if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
{
- XCopyArea(display, backbuffer, window, gc,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
- REAL_SX, REAL_SY);
+ BlitBitmap(backbuffer, window,
+ REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
}
else
{
ABS(ScreenMovPos) == ScrollStepSize ||
redraw_tiles > REDRAWTILES_THRESHOLD)
{
- XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
+ BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY);
#ifdef DEBUG
#if 0
#endif
}
}
+
redraw_mask &= ~REDRAW_MAIN;
}
if (redraw_mask & REDRAW_DOORS)
{
if (redraw_mask & REDRAW_DOOR_1)
- XCopyArea(display, backbuffer, window, gc,
- DX, DY, DXSIZE, DYSIZE,
- DX, DY);
+ BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
if (redraw_mask & REDRAW_DOOR_2)
{
if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2)
- XCopyArea(display,backbuffer,window,gc,
- VX,VY, VXSIZE,VYSIZE,
- VX,VY);
+ BlitBitmap(backbuffer, window, VX,VY, VXSIZE,VYSIZE, VX,VY);
else
{
if (redraw_mask & REDRAW_VIDEO_1)
- XCopyArea(display,backbuffer,window,gc,
- VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
- VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
- VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
+ BlitBitmap(backbuffer, window,
+ VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS,
+ VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
+ VX+VIDEO_DISPLAY1_XPOS,VY+VIDEO_DISPLAY1_YPOS);
if (redraw_mask & REDRAW_VIDEO_2)
- XCopyArea(display,backbuffer,window,gc,
- VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
- VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
- VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
+ BlitBitmap(backbuffer, window,
+ VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS,
+ VIDEO_DISPLAY_XSIZE,VIDEO_DISPLAY_YSIZE,
+ VX+VIDEO_DISPLAY2_XPOS,VY+VIDEO_DISPLAY2_YPOS);
if (redraw_mask & REDRAW_VIDEO_3)
- XCopyArea(display,backbuffer,window,gc,
- VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
- VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
- VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
+ BlitBitmap(backbuffer, window,
+ VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS,
+ VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
+ VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
}
}
if (redraw_mask & REDRAW_DOOR_3)
- XCopyArea(display, backbuffer, window, gc,
- EX, EY, EXSIZE, EYSIZE,
- EX, EY);
+ BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
redraw_mask &= ~REDRAW_DOORS;
}
if (redraw_mask & REDRAW_MICROLEVEL)
{
- XCopyArea(display,backbuffer,window,gc,
- MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
- MICROLEV_XPOS, MICROLEV_YPOS);
- XCopyArea(display,backbuffer,window,gc,
- SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
- SX, MICROLABEL_YPOS);
+ BlitBitmap(backbuffer, window,
+ MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
+ MICROLEV_XPOS, MICROLEV_YPOS);
+ BlitBitmap(backbuffer, window,
+ SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
+ SX, MICROLABEL_YPOS);
redraw_mask &= ~REDRAW_MICROLEVEL;
}
for(x=0; x<SCR_FIELDX; x++)
for(y=0; y<SCR_FIELDY; y++)
if (redraw[redraw_x1 + x][redraw_y1 + y])
- XCopyArea(display, buffer, window, gc,
- FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
- SX + x * TILEX, SY + y * TILEY);
+ BlitBitmap(buffer, window,
+ FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
+ SX + x * TILEX, SY + y * TILEY);
+ }
+
+ if (redraw_mask & REDRAW_FPS) /* display frames per second */
+ {
+ char text[100];
+ char info1[100];
+
+ sprintf(info1, " (only every %d. frame)", global.fps_slowdown_factor);
+ if (!global.fps_slowdown)
+ info1[0] = '\0';
+
+ sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
+ DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
}
- XFlush(display);
+ FlushDisplay();
for(x=0; x<MAX_BUF_XSIZE; x++)
for(y=0; y<MAX_BUF_YSIZE; y++)
void FadeToFront()
{
-/*
+#if 0
long fading_delay = 300;
if (setup.fading && (redraw_mask & REDRAW_FIELD))
{
-*/
+#endif
-/*
+#if 0
int x,y;
- XFillRectangle(display,window,gc,
- REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
- XFlush(display);
+ ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
+ FlushDisplay();
for(i=0;i<2*FULL_SYSIZE;i++)
{
for(y=0;y<FULL_SYSIZE;y++)
{
- XCopyArea(display,backbuffer,window,gc,
- REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
+ BlitBitmap(backbuffer, window,
+ REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
}
- XFlush(display);
+ FlushDisplay();
Delay(10);
}
-*/
+#endif
-/*
+#if 0
for(i=1;i<FULL_SYSIZE;i+=2)
- XCopyArea(display,backbuffer,window,gc,
- REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
- XFlush(display);
+ BlitBitmap(backbuffer, window,
+ REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
+ FlushDisplay();
Delay(fading_delay);
-*/
+#endif
-/*
- XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,0);
- XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
- REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
- XFlush(display);
+#if 0
+ SetClipOrigin(clip_gc[PIX_FADEMASK], 0, 0);
+ BlitBitmapMasked(backbuffer, window,
+ REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+ REAL_SX,REAL_SY);
+ FlushDisplay();
Delay(fading_delay);
- XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,-1);
- XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
- REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
- XFlush(display);
+ SetClipOrigin(clip_gc[PIX_FADEMASK], -1, -1);
+ BlitBitmapMasked(backbuffer, window,
+ REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+ REAL_SX,REAL_SY);
+ FlushDisplay();
Delay(fading_delay);
- XSetClipOrigin(display,clip_gc[PIX_FADEMASK],0,-1);
- XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
- REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
- XFlush(display);
+ SetClipOrigin(clip_gc[PIX_FADEMASK], 0, -1);
+ BlitBitmapMasked(backbuffer, window,
+ REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+ REAL_SX,REAL_SY);
+ FlushDisplay();
Delay(fading_delay);
- XSetClipOrigin(display,clip_gc[PIX_FADEMASK],-1,0);
- XCopyArea(display,backbuffer,window,clip_gc[PIX_FADEMASK],
- REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY);
- XFlush(display);
+ SetClipOrigin(clip_gc[PIX_FADEMASK], -1, 0);
+ BlitBitmapMasked(backbuffer, window,
+ REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
+ REAL_SX,REAL_SY);
+ FlushDisplay();
Delay(fading_delay);
redraw_mask &= ~REDRAW_MAIN;
}
-*/
+#endif
BackToFront();
}
void ClearWindow()
{
- XFillRectangle(display, backbuffer, gc,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
if (setup.soft_scrolling && game_status == PLAYING)
{
- XFillRectangle(display, fieldbuffer, gc, 0, 0, FXSIZE, FYSIZE);
+ ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
SetDrawtoField(DRAW_BUFFERED);
}
else
if (setup.direct_draw && game_status == PLAYING)
{
- XFillRectangle(display, window, gc,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
SetDrawtoField(DRAW_DIRECT);
}
redraw_mask |= REDRAW_FIELD;
}
-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 (display && window && pix[PIX_SMALLFONT])
- {
- XFillRectangle(display, window, gc, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
- DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
- ypos,text,FS_SMALL,color);
- XFlush(display);
- }
-}
-
-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, ...)
+void MarkTileDirty(int x, int y)
{
- char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
- va_list ap;
+ int xx = redraw_x1 + x;
+ int yy = redraw_y1 + y;
- va_start(ap, format);
- vsprintf(buffer, format, ap);
- va_end(ap);
+ if (!redraw[xx][yy])
+ redraw_tiles++;
- DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
+ redraw[xx][yy] = TRUE;
+ redraw_mask |= REDRAW_TILES;
}
-void DrawText(int x, int y, char *text, int font_size, int font_type)
+void SetBorderElement()
{
- 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(Drawable d, GC gc, int x, int y,
- char *text, int font_size, int font_type)
-{
- int font_width, font_height, font_start;
- int font_pixmap;
- 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_pixmap = (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);
+ int x, y;
- if (font_type == FC_SPECIAL3)
- font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
+ BorderElement = EL_LEERRAUM;
- while (*text)
+ for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
{
- 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)
+ for(x=0; x<lev_fieldx; x++)
{
- 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 (!IS_MASSIVE(Feld[x][y]))
+ BorderElement = EL_BETON;
- if (print_inverse)
- {
- XCopyArea(display, pix[font_pixmap], d, gc,
- FONT_CHARS_PER_LINE * font_width,
- 3 * font_height + font_start,
- font_width, font_height, x, y);
-
- XSetClipOrigin(display, clip_gc[font_pixmap],
- dest_x - src_x, dest_y - src_y);
- XCopyArea(display, pix[font_pixmap], d, clip_gc[font_pixmap],
- 0, 0, font_width, font_height, dest_x, dest_y);
- }
- else
- XCopyArea(display, pix[font_pixmap], d, gc,
- src_x, src_y, font_width, font_height, dest_x, dest_y);
+ if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
+ x = lev_fieldx - 2;
}
-
- x += font_width;
}
}
int x_size = TILEX * (1 + ABS(jx - last_jx));
int y_size = TILEY * (1 + ABS(jy - last_jy));
- XCopyArea(display, drawto_field, window, gc,
- dest_x, dest_y, x_size, y_size, dest_x, dest_y);
+ BlitBitmap(drawto_field, window,
+ dest_x, dest_y, x_size, y_size, dest_x, dest_y);
SetDrawtoField(DRAW_DIRECT);
}
DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
}
-void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
+void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
{
if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
{
graphic -= GFX_START_ROCKSSCREEN;
- *pixmap_nr = PIX_BACK;
+ *bitmap_nr = PIX_BACK;
*x = SX + (graphic % GFX_PER_LINE) * TILEX;
*y = SY + (graphic / GFX_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
{
graphic -= GFX_START_ROCKSHEROES;
- *pixmap_nr = PIX_HEROES;
+ *bitmap_nr = PIX_HEROES;
*x = (graphic % HEROES_PER_LINE) * TILEX;
*y = (graphic / HEROES_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
{
graphic -= GFX_START_ROCKSSP;
- *pixmap_nr = PIX_SP;
+ *bitmap_nr = PIX_SP;
*x = (graphic % SP_PER_LINE) * TILEX;
*y = (graphic / SP_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
{
graphic -= GFX_START_ROCKSDC;
- *pixmap_nr = PIX_DC;
+ *bitmap_nr = PIX_DC;
*x = (graphic % DC_PER_LINE) * TILEX;
*y = (graphic / DC_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
{
graphic -= GFX_START_ROCKSMORE;
- *pixmap_nr = PIX_MORE;
+ *bitmap_nr = PIX_MORE;
*x = (graphic % MORE_PER_LINE) * TILEX;
*y = (graphic / MORE_PER_LINE) * TILEY;
}
else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
{
graphic -= GFX_START_ROCKSFONT;
- *pixmap_nr = PIX_BIGFONT;
+ *bitmap_nr = PIX_BIGFONT;
*x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
*y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
}
else
{
- *pixmap_nr = PIX_SP;
+ *bitmap_nr = PIX_SP;
*x = 0;
*y = 0;
}
}
#endif
- DrawGraphicExt(drawto_field, gc, FX + x*TILEX, FY + y*TILEY, graphic);
+ DrawGraphicExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
MarkTileDirty(x,y);
}
-void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
+void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
{
- int pixmap_nr;
+ int bitmap_nr;
int src_x, src_y;
- getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
- XCopyArea(display, pix[pixmap_nr], d, gc,
- src_x, src_y, TILEX, TILEY, x, y);
+ getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
+ BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
}
void DrawGraphicThruMask(int x, int y, int graphic)
MarkTileDirty(x,y);
}
-void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
+void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic)
{
int tile = graphic;
- int pixmap_nr;
+ int bitmap_nr;
int src_x, src_y;
- Pixmap src_pixmap;
+ Bitmap *src_bitmap;
GC drawing_gc;
if (graphic == GFX_LEERRAUM)
return;
- getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
- src_pixmap = pix[pixmap_nr];
- drawing_gc = clip_gc[pixmap_nr];
+ getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
+ src_bitmap = pix[bitmap_nr];
+ drawing_gc = pix[bitmap_nr]->stored_clip_gc;
if (tile_clipmask[tile] != None)
{
- XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
- XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
- XCopyArea(display, src_pixmap, d, tile_clip_gc,
- src_x, src_y, TILEX, TILEY, dest_x, dest_y);
+ SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
+ SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
+ BlitBitmapMasked(src_bitmap, d,
+ src_x, src_y, TILEX, TILEY, dest_x, dest_y);
}
else
{
#if DEBUG
+#ifndef TARGET_SDL
printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
+#endif
#endif
- XSetClipOrigin(display, drawing_gc, dest_x-src_x, dest_y-src_y);
- XCopyArea(display, src_pixmap, d, drawing_gc,
- src_x, src_y, TILEX, TILEY, dest_x, dest_y);
+ SetClipOrigin(src_bitmap, drawing_gc, dest_x-src_x, dest_y-src_y);
+ BlitBitmapMasked(src_bitmap, d,
+ src_x, src_y, TILEX, TILEY, dest_x, dest_y);
}
}
void DrawMiniGraphic(int x, int y, int graphic)
{
- DrawMiniGraphicExt(drawto,gc, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
+ DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
MarkTileDirty(x/2, y/2);
}
-void getMiniGraphicSource(int graphic, Pixmap *pixmap, int *x, int *y)
+void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
{
if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
{
graphic -= GFX_START_ROCKSSCREEN;
- *pixmap = pix[PIX_BACK];
+ *bitmap = pix[PIX_BACK];
*x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
*y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
}
{
graphic -= GFX_START_ROCKSSP;
graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
- *pixmap = pix[PIX_SP];
+ *bitmap = pix[PIX_SP];
*x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
*y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
}
else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
{
graphic -= GFX_START_ROCKSDC;
- *pixmap = pix[PIX_DC];
+ *bitmap = pix[PIX_DC];
*x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
*y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
}
else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
{
graphic -= GFX_START_ROCKSMORE;
- *pixmap = pix[PIX_MORE];
+ *bitmap = pix[PIX_MORE];
*x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
*y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
}
else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
{
graphic -= GFX_START_ROCKSFONT;
- *pixmap = pix[PIX_SMALLFONT];
+ *bitmap = pix[PIX_SMALLFONT];
*x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
*y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
}
else
{
- *pixmap = pix[PIX_SP];
+ *bitmap = pix[PIX_SP];
*x = MINI_SP_STARTX;
*y = MINI_SP_STARTY;
}
}
-void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
+void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
{
- Pixmap pixmap;
+ Bitmap *bitmap;
int src_x, src_y;
- getMiniGraphicSource(graphic, &pixmap, &src_x, &src_y);
- XCopyArea(display, pixmap, d, gc,
- src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
+ getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
+ BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
}
void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
int cx = 0, cy = 0;
int src_x, src_y, dest_x, dest_y;
int tile = graphic;
- int pixmap_nr;
- Pixmap src_pixmap;
+ int bitmap_nr;
+ Bitmap *src_bitmap;
GC drawing_gc;
if (graphic < 0)
MarkTileDirty(x, y + SIGN(dy));
}
- getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
- src_pixmap = pix[pixmap_nr];
- drawing_gc = clip_gc[pixmap_nr];
+ getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
+ src_bitmap = pix[bitmap_nr];
+ drawing_gc = pix[bitmap_nr]->stored_clip_gc;
src_x += cx;
src_y += cy;
{
if (tile_clipmask[tile] != None)
{
- XSetClipMask(display, tile_clip_gc, tile_clipmask[tile]);
- XSetClipOrigin(display, tile_clip_gc, dest_x, dest_y);
- XCopyArea(display, src_pixmap, drawto_field, tile_clip_gc,
- src_x, src_y, TILEX, TILEY, dest_x, dest_y);
+ SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
+ SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
+ BlitBitmapMasked(src_bitmap, drawto_field,
+ src_x, src_y, TILEX, TILEY, dest_x, dest_y);
}
else
{
#if DEBUG
+#ifndef TARGET_SDL
printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
+#endif
#endif
- XSetClipOrigin(display, drawing_gc, dest_x - src_x, dest_y - src_y);
- XCopyArea(display, src_pixmap, drawto_field, drawing_gc,
- src_x, src_y, width, height, dest_x, dest_y);
+ SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto_field,
+ src_x, src_y, width, height, dest_x, dest_y);
}
}
else
- XCopyArea(display, src_pixmap, drawto_field, gc,
- src_x, src_y, width, height, dest_x, dest_y);
+ BlitBitmap(pix[bitmap_nr], drawto_field,
+ src_x, src_y, width, height, dest_x, dest_y);
MarkTileDirty(x,y);
}
cy = (i == 3 ? TILEY - snip : 0);
}
- XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
- SX + (graphic % GFX_PER_LINE) * TILEX + cx,
- SY + (graphic / GFX_PER_LINE) * TILEY + cy,
- width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
+ BlitBitmap(pix[PIX_BACK], drawto_field,
+ SX + (graphic % GFX_PER_LINE) * TILEX + cx,
+ SY + (graphic / GFX_PER_LINE) * TILEY + cy,
+ width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
}
MarkTileDirty(x, y);
cy = (i==0 ? TILEY-snip : 0);
}
- XCopyArea(display, pix[PIX_BACK], drawto_field, gc,
- SX + (graphic % GFX_PER_LINE) * TILEX + cx,
- SY + (graphic / GFX_PER_LINE) * TILEY + cy,
- width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
+ BlitBitmap(pix[PIX_BACK], drawto_field,
+ SX + (graphic % GFX_PER_LINE) * TILEX + cx,
+ SY + (graphic / GFX_PER_LINE) * TILEY + cy,
+ width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
MarkTileDirty(xx, yy);
}
{
graphic -= GFX_START_ROCKSSP;
graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
- XCopyArea(display, pix[PIX_SP], drawto, gc,
- MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
- MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ BlitBitmap(pix[PIX_SP], drawto,
+ MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
+ MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
+ MICRO_TILEX, MICRO_TILEY, xpos, ypos);
}
else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
{
graphic -= GFX_START_ROCKSDC;
- XCopyArea(display, pix[PIX_DC], drawto, gc,
- MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
- MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ BlitBitmap(pix[PIX_DC], drawto,
+ MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
+ MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
+ MICRO_TILEX, MICRO_TILEY, xpos, ypos);
}
else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
{
graphic -= GFX_START_ROCKSMORE;
- XCopyArea(display, pix[PIX_MORE], drawto, gc,
- MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
- MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ BlitBitmap(pix[PIX_MORE], drawto,
+ MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
+ MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
+ MICRO_TILEX, MICRO_TILEY, xpos, ypos);
}
else
- XCopyArea(display, pix[PIX_BACK], drawto, gc,
- MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
- MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ BlitBitmap(pix[PIX_BACK], drawto,
+ MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
+ MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
+ MICRO_TILEX, MICRO_TILEY, xpos, ypos);
}
void DrawLevel()
{
int x, y;
- XFillRectangle(display, drawto, gc,
- xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+ ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
if (lev_fieldx < STD_LEV_FIELDX)
xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
{
char label_text[MAX_MICROLABEL_SIZE + 1];
- XFillRectangle(display, drawto,gc,
- SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
+ ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
mode == MICROLABEL_CREATED_BY ? "created by" :
int mx, my, ty, result = -1;
unsigned int old_door_state;
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
/* pause network game while waiting for request to answer */
if (options.network &&
game_status == PLAYING &&
CloseDoor(DOOR_CLOSE_1);
/* save old door content */
- XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
+ BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
/* clear door drawing field */
- XFillRectangle(display, drawto, gc, DX, DY, DXSIZE, DYSIZE);
+ ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
/* write text for request */
for(ty=0; ty<13; ty++)
}
sprintf(txt, text);
txt[tl] = 0;
- DrawTextExt(drawto, gc,
- DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
+ DrawTextExt(drawto, DX + 51 - (tl * 14)/2, DY + 8 + ty * 16,
txt, FS_SMALL, FC_YELLOW);
text += tl + (tc == 32 ? 1 : 0);
}
}
/* copy request gadgets to door backbuffer */
- XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
- DX, DY, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ DX, DY, DXSIZE, DYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_1);
while(result < 0)
{
- if (XPending(display))
+ if (PendingEvent())
{
- XEvent event;
+ Event event;
- XNextEvent(display, &event);
+ NextEvent(&event);
switch(event.type)
{
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
+ case EVENT_BUTTONPRESS:
+ case EVENT_BUTTONRELEASE:
+ case EVENT_MOTIONNOTIFY:
{
- if (event.type == MotionNotify)
+ if (event.type == EVENT_MOTIONNOTIFY)
{
- Window root, child;
- int root_x, root_y;
- int win_x, win_y;
- unsigned int mask;
-
- if (!XQueryPointer(display, window, &root, &child,
- &root_x, &root_y, &win_x, &win_y, &mask))
- continue;
+ if (!PointerInWindow(window))
+ continue; /* window and pointer are on different screens */
if (!button_status)
continue;
motion_status = TRUE;
- mx = ((XMotionEvent *) &event)->x;
- my = ((XMotionEvent *) &event)->y;
+ mx = ((MotionEvent *) &event)->x;
+ my = ((MotionEvent *) &event)->y;
}
else
{
motion_status = FALSE;
- mx = ((XButtonEvent *) &event)->x;
- my = ((XButtonEvent *) &event)->y;
- if (event.type==ButtonPress)
- button_status = ((XButtonEvent *) &event)->button;
+ mx = ((ButtonEvent *) &event)->x;
+ my = ((ButtonEvent *) &event)->y;
+ if (event.type == EVENT_BUTTONPRESS)
+ button_status = ((ButtonEvent *) &event)->button;
else
button_status = MB_RELEASED;
}
break;
}
- case KeyPress:
- switch(XLookupKeysym((XKeyEvent *)&event,
- ((XKeyEvent *)&event)->state))
+ case EVENT_KEYPRESS:
+ switch(GetEventKey((KeyEvent *)&event, TRUE))
{
- case XK_Return:
+ case KSYM_Return:
result = 1;
break;
- case XK_Escape:
+ case KSYM_Escape:
result = 0;
break;
result = 0;
break;
- case KeyRelease:
+ case EVENT_KEYRELEASE:
key_joystick_mapping = 0;
break;
if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
{
- XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
- DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
- DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
+ BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ DOOR_GFX_PAGEX2,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
+ DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_1);
}
}
RemapAllGadgets();
-#ifndef MSDOS
+#if defined(PLATFORM_UNIX)
/* continue network game after request */
if (options.network &&
game_status == PLAYING &&
if (door_state & DOOR_COPY_BACK)
{
- XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
door_state &= ~DOOR_COPY_BACK;
}
{
unsigned int new_door_state;
- XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- XCopyArea(display, backbuffer, pix[PIX_DB_DOOR], gc,
- VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+ BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
new_door_state = MoveDoor(door_state);
for(x=start; x<=DXSIZE; x+=stepsize)
{
+ Bitmap *bitmap = pix[PIX_DOOR];
+ GC gc = bitmap->stored_clip_gc;
+
WaitUntilDelayReached(&door_delay, door_delay_value);
if (door_state & DOOR_ACTION_1)
int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
int j = (DXSIZE - i) / 3;
- XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
- DXSIZE,DYSIZE - i/2, DX, DY);
-
- XFillRectangle(display, drawto, gc, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
-
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- DX - i, (DY + j) - DOOR_GFX_PAGEY1);
- XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
- DXSIZE, DOOR_GFX_PAGEY1, i, 77, DX + DXSIZE - i, DY + j);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63, DX + DXSIZE - i,
- DY + 140 + j);
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j, DX, DY);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63, DX, DY + 140 - j);
-
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
- DX, DY + 77 - j);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
- DX, DY + 203 - j);
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- DX - i, (DY + j) - DOOR_GFX_PAGEY1);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
- DX + DXSIZE - i, DY + 77 + j);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
- DX + DXSIZE - i, DY + 203 + j);
+ BlitBitmap(pix[PIX_DB_DOOR], drawto,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
+ DXSIZE,DYSIZE - i/2, DX, DY);
+
+ ClearRectangle(drawto, DX, DY + DYSIZE - i/2, DXSIZE,i/2);
+
+ SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1, i, 77,
+ DX + DXSIZE - i, DY + j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 140, i, 63,
+ DX + DXSIZE - i, DY + 140 + j);
+ SetClipOrigin(bitmap, gc, DX - DXSIZE + i, DY - (DOOR_GFX_PAGEY1 + j));
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + j, i, 77 - j,
+ DX, DY);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE-i, DOOR_GFX_PAGEY1 + 140, i, 63,
+ DX, DY + 140 - j);
+
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + 77, i, 63,
+ DX, DY + 77 - j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE - i, DOOR_GFX_PAGEY1 + 203, i, 77,
+ DX, DY + 203 - j);
+ SetClipOrigin(bitmap, gc, DX - i, (DY + j) - DOOR_GFX_PAGEY1);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 77, i, 63,
+ DX + DXSIZE - i, DY + 77 + j);
+ BlitBitmapMasked(bitmap, drawto,
+ DXSIZE, DOOR_GFX_PAGEY1 + 203, i, 77 - j,
+ DX + DXSIZE - i, DY + 203 + j);
redraw_mask |= REDRAW_DOOR_1;
}
int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
int j = (VXSIZE - i) / 3;
- XCopyArea(display, pix[PIX_DB_DOOR], drawto, gc,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
- VXSIZE, VYSIZE - i/2, VX, VY);
-
- XFillRectangle(display, drawto, gc, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
-
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- VX - i, (VY + j) - DOOR_GFX_PAGEY2);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2, VX + VXSIZE-i, VY+j);
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
- XCopyArea(display, pix[PIX_DOOR], drawto,clip_gc[PIX_DOOR],
- VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j, VX, VY);
-
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2,
- VX, VY + VYSIZE / 2 - j);
- XSetClipOrigin(display, clip_gc[PIX_DOOR],
- VX - i, (VY + j) - DOOR_GFX_PAGEY2);
- XCopyArea(display, pix[PIX_DOOR], drawto, clip_gc[PIX_DOOR],
- VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2, i, VYSIZE / 2 - j,
- VX + VXSIZE - i, VY + VYSIZE / 2 + j);
+ BlitBitmap(pix[PIX_DB_DOOR], drawto,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
+ VXSIZE, VYSIZE - i/2, VX, VY);
+
+ ClearRectangle(drawto, VX, VY + VYSIZE-i/2, VXSIZE, i/2);
+
+ SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE, DOOR_GFX_PAGEY2, i, VYSIZE / 2,
+ VX + VXSIZE-i, VY+j);
+ SetClipOrigin(bitmap, gc,
+ VX - VXSIZE + i, VY - (DOOR_GFX_PAGEY2 + j));
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE - i, DOOR_GFX_PAGEY2 + j, i, VYSIZE / 2 - j,
+ VX, VY);
+
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE - i, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+ i, VYSIZE / 2, VX, VY + VYSIZE / 2 - j);
+ SetClipOrigin(bitmap, gc, VX - i, (VY + j) - DOOR_GFX_PAGEY2);
+ BlitBitmapMasked(bitmap, drawto,
+ VXSIZE, DOOR_GFX_PAGEY2 + VYSIZE / 2,
+ i, VYSIZE / 2 - j,
+ VX + VXSIZE - i, VY + VYSIZE / 2 + j);
redraw_mask |= REDRAW_DOOR_2;
}
void DrawSpecialEditorDoor()
{
/* draw bigger toolbox window */
- XCopyArea(display, pix[PIX_DOOR], drawto, gc,
- DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
+ BlitBitmap(pix[PIX_DOOR], drawto,
+ DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
redraw_mask |= REDRAW_ALL;
}
void UndrawSpecialEditorDoor()
{
/* draw normal tape recorder window */
- XCopyArea(display, pix[PIX_BACK], drawto, gc,
- 562, 344, 108, 56, EX - 4, EY - 12);
+ BlitBitmap(pix[PIX_BACK], drawto,
+ 562, 344, 108, 56, EX - 4, EY - 12);
redraw_mask |= REDRAW_ALL;
}
-int ReadPixel(Drawable d, int x, int y)
+#ifndef TARGET_SDL
+int ReadPixel(DrawBuffer *bitmap, int x, int y)
{
XImage *pixel_image;
unsigned long pixel_value;
- pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
+ pixel_image = XGetImage(display, bitmap->drawable,
+ x, y, 1, 1, AllPlanes, ZPixmap);
pixel_value = XGetPixel(pixel_image, 0, 0);
XDestroyImage(pixel_image);
return pixel_value;
}
+#endif
/* ---------- new tool button stuff ---------------------------------------- */
}
};
+#if 0
static void DoNotDisplayInfoText(void *ptr)
{
return;
}
+#endif
void CreateToolButtons()
{
for (i=0; i<NUM_TOOL_BUTTONS; i++)
{
- Pixmap gd_pixmap = pix[PIX_DOOR];
- Pixmap deco_pixmap = None;
+ Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *deco_bitmap = None;
int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
struct GadgetInfo *gi;
unsigned long event_mask;
if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
{
getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
- &deco_pixmap, &deco_x, &deco_y);
+ &deco_bitmap, &deco_x, &deco_y);
deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
}
GDI_HEIGHT, toolbutton_info[i].height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
- GDI_DECORATION_DESIGN, deco_pixmap, deco_x, deco_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
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)
/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+* 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 *
+* (c) 1995-2000 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* tools.h *
+* tools.h *
***********************************************************/
#ifndef TOOLS_H
void BackToFront();
void FadeToFront();
void ClearWindow();
-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(Drawable, GC, int, int, char *, int, int);
+
+void MarkTileDirty(int, int);
+void SetBorderElement();
+
void DrawAllPlayers(void);
void DrawPlayerField(int, int);
void DrawPlayer(struct PlayerInfo *);
void DrawGraphicAnimationThruMask(int, int, int, int, int, int);
void getGraphicSource(int, int *, int *, int *);
void DrawGraphic(int, int, int);
-void DrawGraphicExt(Drawable, GC, int, int, int);
+void DrawGraphicExt(DrawBuffer *, int, int, int);
void DrawGraphicThruMask(int, int, int);
-void DrawGraphicThruMaskExt(Drawable, int, int, int);
+void DrawGraphicThruMaskExt(DrawBuffer *, int, int, int);
void DrawMiniGraphic(int, int, int);
-void getMiniGraphicSource(int, Pixmap *, int *, int *);
-void DrawMiniGraphicExt(Drawable, GC, int, int, int);
+void getMiniGraphicSource(int, Bitmap **, int *, int *);
+void DrawMiniGraphicExt(DrawBuffer *, int, int, int);
void DrawGraphicShifted(int, int, int, int, int, int, int);
void DrawGraphicShiftedThruMask(int, int, int, int, int, int);
void DrawScreenElementExt(int, int, int, int, int, int, int);
unsigned int MoveDoor(unsigned int);
void DrawSpecialEditorDoor();
void UndrawSpecialEditorDoor();
-int ReadPixel(Drawable, int, int);
+int ReadPixel(DrawBuffer *, int, int);
void CreateToolButtons();
int el2gfx(int);
-#endif
+#endif /* TOOLS_H */