From: Holger Schemel Date: Wed, 18 Nov 1998 19:48:10 +0000 (+0100) Subject: rnd-19981118-2 X-Git-Tag: 1.2.0^2~21 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=6ea6dac4068909e5adc06102dd215539c64afef8 rnd-19981118-2 --- diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..914925fe --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +#=============================================================================# +# Makefile for Rocks'n'Diamonds 1.2 # +# (c) 1995-98 Holger Schemel, aeglos@valinor.owl.de # +#=============================================================================# + +#-----------------------------------------------------------------------------# +# configuration section # +#-----------------------------------------------------------------------------# + +#-----------------------------------------------------------------------------# +# you shouldn't need to change anything below # +#-----------------------------------------------------------------------------# + +PROGNAME = rocksndiamonds +SRC_DIR = src + +MAKE = make +RM = rm -f + +MAKE_CMD = $(MAKE) -C $(SRC_DIR) + + +all: $(PROGNAME) + +$(PROGNAME): + $(MAKE_CMD) + +clean: + $(MAKE_CMD) clean + $(RM) $(PROGNAME) + +backup: + $(MAKE) clean + ./scripts/make_backup.sh + +depend: + $(MAKE_CMD) depend diff --git a/src/Makefile b/src/Makefile index a652a6d4..9f2e9505 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,30 +7,131 @@ # configuration section # #-----------------------------------------------------------------------------# +# change this to your favorite ANSI C compiler +CC = gcc + +# on Solaris and similar systems, you'll need to uncomment this +# EXTRA_LIBS = -lnsl -lsocket + +# specify X11 library path on your system +XLIB_PATH = /usr/X11/lib + +# change this to the directory where you want to install game data like levels +GAME_DIR = . + +# 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 +# when installing the game in a multi user environment, choose this +# SCORE_ENTRIES = ONE_PER_NAME +# when installing the game in a single user environment, choose this +SCORE_ENTRIES = MANY_PER_NAME + +# The XPM-Library is no longer needed to build this program, +# but is used to load graphics if XPM_INCLUDE_FILE is defined, +# because the GIF loading routines are still a bit beta. +# If you want to use the Xpm library, convert the GIF files to Xpm +# files (and you need corresponding mask files in xbm format). + +# XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="" +# EXTRA_X11_LIBS = -lXpm + #-----------------------------------------------------------------------------# # you shouldn't need to change anything below # #-----------------------------------------------------------------------------# PROGNAME = rocksndiamonds -SRC_DIR = src -MAKE = make RM = rm -f +CPP = $(CC) -E + +CONFIG_GAME_DIR = -DGAME_DIR="\"$(GAME_DIR)\"" +CONFIG_SCORE_ENTRIES = -D$(SCORE_ENTRIES) -MAKE_CMD = $(MAKE) -C $(SRC_DIR) +CONFIG = $(CONFIG_GAME_DIR) $(SOUNDS) $(JOYSTICK) \ + $(CONFIG_SCORE_ENTRIES) $(XPM_INCLUDE_FILE) +# DEBUG = -DDEBUG -g -ansi -pedantic -Wall +DEBUG = -DDEBUG -g -Wall +# DEBUG = -O6 + +# SYSTEM = -Aa -D_HPUX_SOURCE -Dhpux # for HP-UX (obsolete) +# SYSTEM = -DSYSV -Ae # for HP-UX +# INCL = -I/usr/include/X11R5 # for HP-UX and others +# INCL = -I/usr/local/X11/include # for SunOS and others +# LIBS = -L/usr/lib/X11R5 -lXpm -lX11 -lm +# # for HP-UX and others +# LIBS = -L/usr/local/X11/lib -lXpm -lX11 -lm -lsocket -R/usr/local/X11/lib +# # for SunOS and others + +# LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm +# LIBS = -L/usr/X11R6/lib -lX11 -lm + +# LIBS = -L/usr/X11R6/lib $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS) +LIBS = -L$(XLIB_PATH) $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS) + +# CFLAGS = -O2 $(CONFIG) $(SYSTEM) +CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL) + +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 + +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 all: $(PROGNAME) -$(PROGNAME): - $(MAKE_CMD) +$(PROGNAME): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $(PROGNAME) + +.c.o: + $(CC) $(CFLAGS) -c $*.c clean: - $(MAKE_CMD) clean + $(RM) $(OBJS) $(RM) $(PROGNAME) -backup: - ./scripts/make_backup.sh - depend: - $(MAKE_CMD) depend + for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/src/files.c b/src/files.c new file mode 100644 index 00000000..46671d46 --- /dev/null +++ b/src/files.c @@ -0,0 +1,1433 @@ +/*********************************************************** +* 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 * +*----------------------------------------------------------* +* files.h * +***********************************************************/ + +#include +#include +#include +#include + +#include "files.h" +#include "tools.h" +#include "misc.h" +#include "tape.h" +#include "joystick.h" + +#define MAX_LINE_LEN 1000 + +static void SaveUserLevelInfo(); /* for 'InitUserLevelDir()' */ +static char *getSetupLine(char *, int); /* for 'SaveUserLevelInfo()' */ + +static char *getGlobalDataDir() +{ + return GAME_DIR; +} + +static char *getUserDataDir() +{ + static char *userdata_dir = NULL; + + if (!userdata_dir) + { + char *home_dir = getHomeDir(); + char *data_dir = USERDATA_DIRECTORY; + + userdata_dir = checked_malloc(strlen(home_dir) + strlen(data_dir) + 2); + sprintf(userdata_dir, "%s/%s", home_dir, data_dir); + } + + return userdata_dir; +} + +static char *getSetupDir() +{ + return getUserDataDir(); +} + +static char *getUserLevelDir(char *level_subdir) +{ + static char *userlevel_dir = NULL; + char *data_dir = getUserDataDir(); + char *userlevel_subdir = LEVELS_DIRECTORY; + + if (userlevel_dir) + free(userlevel_dir); + + userlevel_dir = checked_malloc(strlen(data_dir) + strlen(userlevel_subdir) + + strlen(level_subdir) + 3); + sprintf(userlevel_dir, "%s/%s%s%s", data_dir, userlevel_subdir, + (strlen(level_subdir) > 0 ? "/" : ""), level_subdir); + + return userlevel_dir; +} + +static char *getTapeDir(char *level_subdir) +{ + static char *tape_dir = NULL; + char *data_dir = getUserDataDir(); + char *tape_subdir = TAPES_DIRECTORY; + + if (tape_dir) + free(tape_dir); + + tape_dir = checked_malloc(strlen(data_dir) + strlen(tape_subdir) + + strlen(level_subdir) + 3); + sprintf(tape_dir, "%s/%s%s%s", data_dir, tape_subdir, + (strlen(level_subdir) > 0 ? "/" : ""), level_subdir); + + return tape_dir; +} + +static char *getScoreDir(char *level_subdir) +{ + static char *score_dir = NULL; + char *data_dir = getGlobalDataDir(); + char *score_subdir = SCORES_DIRECTORY; + + if (score_dir) + free(score_dir); + + score_dir = checked_malloc(strlen(data_dir) + strlen(score_subdir) + + strlen(level_subdir) + 3); + sprintf(score_dir, "%s/%s%s%s", data_dir, score_subdir, + (strlen(level_subdir) > 0 ? "/" : ""), level_subdir); + + return score_dir; +} + +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(getTapeDir(""), "main tape"); + createDirectory(getTapeDir(level_subdir), "level tape"); +} + +static void InitScoreDirectory(char *level_subdir) +{ + createDirectory(getScoreDir(""), "main score"); + createDirectory(getScoreDir(level_subdir), "level score"); +} + +static void InitUserLevelDirectory(char *level_subdir) +{ + if (access(getUserLevelDir(level_subdir), F_OK) != 0) + { + createDirectory(getUserLevelDir(""), "main user level"); + createDirectory(getUserLevelDir(level_subdir), "user level"); + + SaveUserLevelInfo(); + } +} + +void LoadLevel(int level_nr) +{ + int i, x, y; + char filename[MAX_FILENAME_LEN]; + char cookie[MAX_FILENAME_LEN]; + FILE *file; + + if (leveldir[leveldir_nr].user_defined) + sprintf(filename, "%s/%s/%d", + getUserLevelDir(""), leveldir[leveldir_nr].filename, level_nr); + else + sprintf(filename, "%s/%s/%d", + options.level_directory, leveldir[leveldir_nr].filename, level_nr); + + if (!(file = fopen(filename, "r"))) + Error(ERR_WARN, "cannot read level '%s' - creating new level", filename); + else + { + fgets(cookie, LEVEL_COOKIE_LEN, file); + fgetc(file); + + if (strcmp(cookie,LEVEL_COOKIE)) + { + Error(ERR_WARN, "wrong format of level file '%s'", filename); + fclose(file); + file = NULL; + } + } + + if (file) + { + lev_fieldx = level.fieldx = fgetc(file); + lev_fieldy = level.fieldy = fgetc(file); + + level.time = (fgetc(file)<<8) | fgetc(file); + level.edelsteine = (fgetc(file)<<8) | fgetc(file); + for(i=0; i= MAX_TAPELEN) + break; + + for(j=0; j 0) + { + tape.pos[i].action[j] = MV_NO_MOVING; + continue; + } + tape.pos[i].action[j] = fgetc(file); + } + + tape.pos[i].delay = fgetc(file); + + if (levelrec_10) + { + /* eliminate possible diagonal moves in old tapes */ + /* this is only for backward compatibility */ + + byte joy_dir[4] = { JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN }; + byte action = tape.pos[i].action[0]; + int k, num_moves = 0; + + for (k=0; k<4; k++) + { + if (action & joy_dir[k]) + { + tape.pos[i + num_moves].action[0] = joy_dir[k]; + if (num_moves > 0) + tape.pos[i + num_moves].delay = 0; + num_moves++; + } + } + + if (num_moves > 1) + { + num_moves--; + i += num_moves; + tape.length += num_moves; + } + } + + if (feof(file)) + break; + } + + fclose(file); + + if (i != tape.length) + Error(ERR_WARN, "level recording file '%s' corrupted", filename); + + tape.length_seconds = GetTapeLength(); +} + +void SaveTape(int level_nr) +{ + int i; + char filename[MAX_FILENAME_LEN]; + FILE *file; + boolean new_tape = TRUE; + + InitTapeDirectory(leveldir[leveldir_nr].filename); + + sprintf(filename, "%s/%d.%s", + getTapeDir(leveldir[leveldir_nr].filename), + level_nr, TAPEFILE_EXTENSION); + + /* if a tape still exists, ask to overwrite it */ + if ((file = fopen(filename, "r"))) + { + new_tape = FALSE; + fclose(file); + + if (!Request("Replace old tape ?", REQ_ASK)) + return; + } + + if (!(file = fopen(filename, "w"))) + { + Error(ERR_WARN, "cannot save level recording file '%s'", filename); + return; + } + + fputs(LEVELREC_COOKIE, file); /* Formatkennung */ + fputc(0x0a, file); + + fputc((tape.random_seed >> 24) & 0xff,file); + fputc((tape.random_seed >> 16) & 0xff,file); + fputc((tape.random_seed >> 8) & 0xff,file); + fputc((tape.random_seed >> 0) & 0xff,file); + + fputc((tape.date >> 24) & 0xff,file); + fputc((tape.date >> 16) & 0xff,file); + fputc((tape.date >> 8) & 0xff,file); + fputc((tape.date >> 0) & 0xff,file); + + fputc((tape.length >> 24) & 0xff,file); + fputc((tape.length >> 16) & 0xff,file); + fputc((tape.length >> 8) & 0xff,file); + fputc((tape.length >> 0) & 0xff,file); + + for(i=0; i= 100) + return s; + + strcpy(s_lower, s); + + for (i=0; itoken) + free(setup_file_list->token); + if (setup_file_list->value) + free(setup_file_list->value); + if (setup_file_list->next) + freeSetupFileList(setup_file_list->next); + free(setup_file_list); +} + +static struct SetupFileList *newSetupFileList(char *token, char *value) +{ + struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList)); + + new->token = checked_malloc(strlen(token) + 1); + strcpy(new->token, token); + + new->value = checked_malloc(strlen(value) + 1); + strcpy(new->value, value); + + new->next = NULL; + + return new; +} + +static char *getTokenValue(struct SetupFileList *setup_file_list, + char *token) +{ + if (!setup_file_list) + return NULL; + + if (strcmp(setup_file_list->token, token) == 0) + return setup_file_list->value; + else + return getTokenValue(setup_file_list->next, token); +} + +static void setTokenValue(struct SetupFileList *setup_file_list, + char *token, char *value) +{ + if (!setup_file_list) + return; + + if (strcmp(setup_file_list->token, token) == 0) + { + free(setup_file_list->value); + setup_file_list->value = checked_malloc(strlen(value) + 1); + strcpy(setup_file_list->value, value); + } + else if (setup_file_list->next == NULL) + setup_file_list->next = newSetupFileList(token, value); + else + setTokenValue(setup_file_list->next, token, value); +} + +#ifdef DEBUG +static void printSetupFileList(struct SetupFileList *setup_file_list) +{ + if (!setup_file_list) + return; + + printf("token: '%s'\n", setup_file_list->token); + printf("value: '%s'\n", setup_file_list->value); + + printSetupFileList(setup_file_list->next); +} +#endif + +static struct SetupFileList *loadSetupFileList(char *filename) +{ + int line_len; + char line[MAX_LINE_LEN]; + char *token, *value, *line_ptr; + struct SetupFileList *setup_file_list = newSetupFileList("", ""); + struct SetupFileList *first_valid_list_entry; + + FILE *file; + + if (!(file = fopen(filename, "r"))) + { + Error(ERR_WARN, "cannot open setup/info file '%s'", filename); + return NULL; + } + + while(!feof(file)) + { + /* read next line of input file */ + if (!fgets(line, MAX_LINE_LEN, file)) + break; + + /* cut trailing comment or whitespace from input line */ + for (line_ptr = line; *line_ptr; line_ptr++) + { + if (*line_ptr == '#' || *line_ptr == '\n') + { + *line_ptr = '\0'; + break; + } + } + + /* cut trailing whitespaces from input line */ + for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--) + if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0') + *line_ptr = '\0'; + + /* ignore empty lines */ + if (*line == '\0') + continue; + + line_len = strlen(line); + + /* cut leading whitespaces from token */ + for (token = line; *token; token++) + if (*token != ' ' && *token != '\t') + break; + + /* find end of token */ + for (line_ptr = token; *line_ptr; line_ptr++) + { + if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':') + { + *line_ptr = '\0'; + break; + } + } + + if (line_ptr < line + line_len) + value = line_ptr + 1; + else + value = "\0"; + + /* cut leading whitespaces from value */ + for (; *value; value++) + if (*value != ' ' && *value != '\t') + break; + + if (*token && *value) + setTokenValue(setup_file_list, token, value); + } + + fclose(file); + + first_valid_list_entry = setup_file_list->next; + + /* free empty list header */ + setup_file_list->next = NULL; + freeSetupFileList(setup_file_list); + + if (first_valid_list_entry == NULL) + Error(ERR_WARN, "setup/info file '%s' is empty", filename); + + return first_valid_list_entry; +} + +static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list, + char *identifier) +{ + if (!setup_file_list) + return; + + if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0) + { + if (strcmp(setup_file_list->value, identifier) != 0) + { + Error(ERR_WARN, "setup/info file has wrong version"); + return; + } + else + return; + } + + if (setup_file_list->next) + checkSetupFileListIdentifier(setup_file_list->next, identifier); + else + { + Error(ERR_WARN, "setup/info file has no version information"); + return; + } +} + +static void setLevelDirInfoToDefaults(struct LevelDirInfo *ldi) +{ + ldi->name = getStringCopy("non-existing"); + ldi->levels = 0; + ldi->sort_priority = 999; /* default: least priority */ + ldi->readonly = TRUE; +} + +static void setSetupInfoToDefaults(struct SetupInfo *si) +{ + int i; + + si->player_name = getStringCopy(getLoginName()); + + si->sound = TRUE; + si->sound_loops = FALSE; + si->sound_music = FALSE; + si->sound_simple = FALSE; + si->toons = TRUE; + si->double_buffering = TRUE; + si->direct_draw = !si->double_buffering; + si->scroll_delay = FALSE; + si->soft_scrolling = TRUE; + si->fading = FALSE; + si->autorecord = FALSE; + si->quick_doors = FALSE; + + for (i=0; iinput[i].use_joystick = FALSE; + si->input[i].joy.device_name = getStringCopy(joystick_device_name[i]); + si->input[i].joy.xleft = JOYSTICK_XLEFT; + si->input[i].joy.xmiddle = JOYSTICK_XMIDDLE; + si->input[i].joy.xright = JOYSTICK_XRIGHT; + si->input[i].joy.yupper = JOYSTICK_YUPPER; + si->input[i].joy.ymiddle = JOYSTICK_YMIDDLE; + 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); + } +} + +static void setSetupInfo(int token_nr, char *token_value) +{ + int token_type = token_info[token_nr].type; + void *setup_value = token_info[token_nr].value; + + if (token_value == NULL) + return; + + /* set setup field to corresponding token value */ + switch (token_type) + { + case TYPE_BOOLEAN: + case TYPE_SWITCH: + *(boolean *)setup_value = get_string_boolean_value(token_value); + break; + + case TYPE_KEYSYM: + *(KeySym *)setup_value = getKeySymFromX11KeyName(token_value); + break; + + case TYPE_INTEGER: + *(int *)setup_value = get_string_integer_value(token_value); + break; + + case TYPE_STRING: + if (*(char **)setup_value != NULL) + free(*(char **)setup_value); + *(char **)setup_value = getStringCopy(token_value); + break; + + default: + break; + } +} + +static void decodeSetupFileList(struct SetupFileList *setup_file_list) +{ + int i, pnr; + + if (!setup_file_list) + return; + + /* handle global setup values */ + si = setup; + for (i=FIRST_GLOBAL_SETUP_TOKEN; i<=LAST_GLOBAL_SETUP_TOKEN; i++) + setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text)); + setup = si; + + /* handle player specific setup values */ + for (pnr=0; pnr highest_level_nr) + last_level_nr = highest_level_nr; + } + + return last_level_nr; +} + +static int compareLevelDirInfoEntries(const void *object1, const void *object2) +{ + const struct LevelDirInfo *entry1 = object1; + const struct LevelDirInfo *entry2 = object2; + int compare_result; + + if (entry1->sort_priority != entry2->sort_priority) + compare_result = entry1->sort_priority - entry2->sort_priority; + else + { + char *name1 = getStringToLower(entry1->name); + char *name2 = getStringToLower(entry2->name); + + compare_result = strcmp(name1, name2); + + free(name1); + free(name2); + } + + return compare_result; +} + +static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry) +{ + DIR *dir; + struct stat file_status; + char *directory = NULL; + char *filename = NULL; + struct SetupFileList *setup_file_list = NULL; + struct dirent *dir_entry; + int i, current_entry = start_entry; + + if ((dir = opendir(level_directory)) == NULL) + Error(ERR_EXIT, "cannot read level directory '%s'", level_directory); + + while (current_entry < MAX_LEVDIR_ENTRIES) + { + if ((dir_entry = readdir(dir)) == NULL) /* last directory entry */ + break; + + /* skip entries for current and parent directory */ + if (strcmp(dir_entry->d_name, ".") == 0 || + strcmp(dir_entry->d_name, "..") == 0) + continue; + + /* find out if directory entry is itself a directory */ + directory = getPath2(level_directory, dir_entry->d_name); + if (stat(directory, &file_status) != 0 || /* cannot stat file */ + (file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */ + { + free(directory); + continue; + } + + if (strlen(dir_entry->d_name) >= MAX_LEVDIR_FILENAME) + { + Error(ERR_WARN, "filename of level directory '%s' too long -- ignoring", + dir_entry->d_name); + continue; + } + + filename = getPath2(directory, LEVELINFO_FILENAME); + setup_file_list = loadSetupFileList(filename); + + if (setup_file_list) + { + checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE); + setLevelDirInfoToDefaults(&leveldir[current_entry]); + + ldi = leveldir[current_entry]; + for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++) + setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text)); + leveldir[current_entry] = ldi; + + leveldir[current_entry].filename = getStringCopy(dir_entry->d_name); + leveldir[current_entry].user_defined = + (level_directory == options.level_directory ? FALSE : TRUE); + + freeSetupFileList(setup_file_list); + current_entry++; + } + else + Error(ERR_WARN, "ignoring level directory '%s'", directory); + + free(directory); + free(filename); + } + + if (current_entry == MAX_LEVDIR_ENTRIES) + Error(ERR_WARN, "using %d level directories -- ignoring the rest", + current_entry); + + closedir(dir); + + if (current_entry == start_entry && start_entry != -1) + Error(ERR_EXIT, "cannot find any valid level series in directory '%s'", + level_directory); + + return current_entry; +} + +void LoadLevelInfo() +{ + InitUserLevelDirectory(getLoginName()); + + num_leveldirs = 0; + leveldir_nr = 0; + + num_leveldirs = LoadLevelInfoFromLevelDir(options.level_directory, + num_leveldirs); + num_leveldirs = LoadLevelInfoFromLevelDir(getUserLevelDir(""), + num_leveldirs); + if (num_leveldirs > 1) + qsort(leveldir, num_leveldirs, sizeof(struct LevelDirInfo), + compareLevelDirInfoEntries); +} + +static void SaveUserLevelInfo() +{ + char filename[MAX_FILENAME_LEN]; + FILE *file; + int i; + + sprintf(filename, "%s/%s", + getUserLevelDir(getLoginName()), LEVELINFO_FILENAME); + + if (!(file = fopen(filename, "w"))) + { + Error(ERR_WARN, "cannot write level info file '%s'", filename); + return; + } + + ldi.name = getLoginName(); + ldi.levels = 100; + ldi.sort_priority = 300; + ldi.readonly = FALSE; + + fprintf(file, "%s\n\n", + getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, LEVELINFO_COOKIE)); + + for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++) + fprintf(file, "%s\n", getSetupLine("", i)); + + fclose(file); + + chmod(filename, SETUP_PERMS); +} + +void LoadSetup() +{ + char filename[MAX_FILENAME_LEN]; + struct SetupFileList *setup_file_list = NULL; + + /* always start with reliable default setup values */ + setSetupInfoToDefaults(&setup); + + sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME); + + setup_file_list = loadSetupFileList(filename); + + if (setup_file_list) + { + checkSetupFileListIdentifier(setup_file_list, SETUP_COOKIE); + decodeSetupFileList(setup_file_list); + + setup.direct_draw = !setup.double_buffering; + + freeSetupFileList(setup_file_list); + + /* needed to work around problems with fixed length strings */ + if (strlen(setup.player_name) >= MAX_NAMELEN) + setup.player_name[MAX_NAMELEN - 1] = '\0'; + else if (strlen(setup.player_name) < MAX_NAMELEN - 1) + { + char *new_name = checked_malloc(MAX_NAMELEN); + + strcpy(new_name, setup.player_name); + free(setup.player_name); + setup.player_name = new_name; + } + } + else + Error(ERR_WARN, "using default setup values"); +} + +static char *getSetupLine(char *prefix, int token_nr) +{ + int i; + static char entry[MAX_LINE_LEN]; + int token_type = token_info[token_nr].type; + void *setup_value = token_info[token_nr].value; + char *token_text = token_info[token_nr].text; + + /* start with the prefix, token and some spaces to format output line */ + sprintf(entry, "%s%s:", prefix, token_text); + for (i=strlen(entry); itoken, TOKEN_STR_FILE_IDENTIFIER) != 0) + fprintf(file, "%s\n", + getFormattedSetupEntry(list_entry->token, list_entry->value)); + + /* just to make things nicer :) */ + if (strcmp(list_entry->token, TOKEN_STR_LAST_LEVEL_SERIES) == 0) + fprintf(file, "\n"); + + list_entry = list_entry->next; + } + + fclose(file); + + chmod(filename, SETUP_PERMS); +} diff --git a/src/gadget.c b/src/gadget.c deleted file mode 100644 index dee0566d..00000000 --- a/src/gadget.c +++ /dev/null @@ -1,7 +0,0 @@ -/* gadget.c */ - -#include "gadget.h" - -struct Gadget *gadget_list; - -void NextGadgetEvent() diff --git a/src/gadget.h b/src/gadget.h deleted file mode 100644 index 5ee9c98d..00000000 --- a/src/gadget.h +++ /dev/null @@ -1,54 +0,0 @@ -/* gadget.h */ - -/* gadget types */ -#define GD_TYPE_NORMAL_BUTTON (1<<0) -#define GD_TYPE_TWO_STATE_BUTTON (1<<1) -#define GD_TYPE_DRAWING_AREA (1<<2) -#define GD_TYPE_TEXTINPUT (1<<3) -#define GD_TYPE_TEXTOUTPUT (1<<4) -#define GD_TYPE_NUMBERINPUT (1<<5) -#define GD_TYPE_NUMBEROUTPUT (1<<6) - -/* gadget events */ -#define GD_EVENT_PRESSED (1<<0) -#define GD_EVENT_RELEASED (1<<1) -#define GD_EVENT_MOVING (1<<2) - -/* gadget structure constants */ -#define MAX_GADGET_TEXTSIZE 1024 - -struct GadgetDesign -{ - Pixmap pixmap; /* Pixmap with gadget surface */ - int x,y; /* position of rectangle in Pixmap */ -}; - -struct Gadget -{ - int x,y; /* screen position */ - int width,height; /* screen size */ - unsigned long type; /* type (button, text input, ...) */ - unsigned long state; /* state (pressed, released, ...) */ - long number_value; - char text_value[MAX_GADGET_TEXTSIZE]; - struct GadgetDesign *design[2]; /* 0: normal; 1: pressed */ - struct GadgetDesign *alt_design[2]; /* alternative design */ - unsigned long event; /* actual gadget event */ - struct Gadget *next; /* next list entry */ -}; - -struct NewGadget -{ - int x,y; /* screen position */ - int width,height; /* screen size */ - unsigned long type; /* type (button, text input, ...) */ - struct GadgetDesign *design[2]; /* 0: normal; 1: pressed */ - struct GadgetDesign *alt_design[2]; /* alternative design */ - unsigned long value_mask; /* actual gadget event */ -}; - -struct GadgetEvent -{ - unsigned long state; /* state (pressed, released, ...) */ - int x,y; /* position inside drawing area */ -}; diff --git a/src/gfxload.c b/src/gfxload.c deleted file mode 100644 index bcc7f221..00000000 --- a/src/gfxload.c +++ /dev/null @@ -1,1120 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* gfxload.c * -***********************************************************/ - -#ifndef MSDOS -#include "gfxload.h" - - - - - - -extern Window window; -extern void Delay(long); - - - - - - -#ifdef DEBUG -/* -#define DEBUG_GIF -#define DEBUG_ILBM -*/ -#endif - -struct IFF_ILBM_FORM_big_endian -{ - char magic_FORM[4]; - unsigned char chunk_size[4]; - char magic_ILBM[4]; -}; - -struct IFF_ILBM_BMHD_big_endian -{ - char Width[2], Height[2]; - char LeftEdge[2], TopEdge[2]; - char Depth; - char Mask; - char Compression; - char pad1; - char transparentColor[2]; - char xAspect, yAspect; - char pageWidth[2], pageHeight[2]; -}; - -struct IFF_ILBM_BMHD -{ - unsigned int Width, Height; - int LeftEdge, TopEdge; - unsigned int Depth; - unsigned int Mask; - unsigned int Compression; - unsigned char pad1; - unsigned int transparentColor; - unsigned int xAspect, yAspect; - int pageWidth, pageHeight; -}; - -static int ConvertXImageDepth(Display *, XImage **); -static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int); - -#define READ_GIF_TO_BITMAP 0 -#define READ_GIF_TO_PIXMAP 1 - -int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) -{ - return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, - pixmap, READ_GIF_TO_BITMAP)); -} - -int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap) -{ - return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, - pixmap, READ_GIF_TO_PIXMAP)); -} - -int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename, - Pixmap *pixmap, int mode) -{ - XImage *image = NULL; - Pixmap new_pixmap = 0; - int return_code; - - *pixmap = 0; - return_code = Read_GIF_to_XImage(display, filename, &image); - if (return_code != GIF_Success) - return(return_code); - - if (image) - { - int screen = DefaultScreen(display); - Drawable root = RootWindow(display,screen); - int depth = DefaultDepth(display, screen); - int width = image->width; - int height = image->height; - - if (mode == READ_GIF_TO_BITMAP) - { - int i,x,y; - unsigned long black_pixel = BlackPixel(display,screen); - int bytes_per_line = (width+7) / 8; - int size = bytes_per_line * height; - char *data, *ptr; - - data = (char *)malloc(size); - if (!data) - return(GIF_NoMemory); - - ptr = data; - for(i=0;i filesize) - return(GIF_FileInvalid); - } - while(ch1); - - free(RawGIF); /* We're done with the raw data now... */ - -#ifdef DEBUG_GIF - fprintf(stderr, "done\n"); - fprintf(stderr, " Decompressing... "); -#endif - - /* Allocate the X Image */ - ImageData = (byte *) malloc(Width*Height); - if (!ImageData) - return(GIF_NoMemory); - - new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData, - Width,Height,8,Width); - if (!new_image) - return(GIF_NoMemory); - - BytesPerScanline = Width; - - - /* Decompress the file, continuing until you see the GIF EOF code. - * One obvious enhancement is to add checking for corrupt files here. - */ - - Code = ReadCode(); - while (Code != EOFCode) - { - /* Clear code sets everything back to its initial value, then reads the - * immediately subsequent code as uncompressed data. - */ - - if (Code == ClearCode) - { - CodeSize = InitCodeSize; - MaxCode = (1 << CodeSize); - ReadMask = MaxCode - 1; - FreeCode = FirstFree; - CurCode = OldCode = Code = ReadCode(); - FinChar = CurCode & BitMask; - AddToPixel(FinChar); - } - else - { - /* If not a clear code, then must be data: - * save same as CurCode and InCode - */ - - CurCode = InCode = Code; - - /* If greater or equal to FreeCode, not in the hash table yet; - * repeat the last character decoded - */ - - if (CurCode >= FreeCode) - { - CurCode = OldCode; - OutCode[OutCount++] = FinChar; - } - - /* Unless this code is raw data, pursue the chain pointed to by CurCode - * through the hash table to its end; each code in the chain puts its - * associated output code on the output queue. - */ - - while (CurCode > BitMask) - { - if (OutCount > 1024) - return(GIF_FileInvalid); - - OutCode[OutCount++] = Suffix[CurCode]; - CurCode = Prefix[CurCode]; - } - - /* The last code in the chain is treated as raw data. */ - - FinChar = CurCode & BitMask; - OutCode[OutCount++] = FinChar; - - /* Now we put the data out to the Output routine. - * It's been stacked LIFO, so deal with it that way... - */ - - for (i = OutCount - 1; i >= 0; i--) - AddToPixel(OutCode[i]); - OutCount = 0; - - /* Build the hash table on-the-fly. No table is stored in the file. */ - - Prefix[FreeCode] = OldCode; - Suffix[FreeCode] = FinChar; - OldCode = InCode; - - /* Point to the next slot in the table. If we exceed the current - * MaxCode value, increment the code size unless it's already 12. If it - * is, do nothing: the next code decompressed better be CLEAR - */ - - FreeCode++; - if (FreeCode >= MaxCode) - { - if (CodeSize < 12) - { - CodeSize++; - MaxCode *= 2; - ReadMask = (1 << CodeSize) - 1; - } - } - } - Code = ReadCode(); - } - - free(Raster); - -#ifdef DEBUG_GIF - fprintf(stderr, "done\n"); - fprintf(stderr," %d colors used\n",numused); -#endif - - if (file != stdin) - fclose(file); - - if (ColorDicking(display) != GIF_Success) - return(GIF_ColorFailed); - - *image = new_image; - return(GIF_Success); -} - - -/* Fetch the next code from the raster data stream. The codes can be - * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to - * maintain our location in the Raster array as a BIT Offset. We compute - * the byte Offset into the raster array by dividing this by 8, pick up - * three bytes, compute the bit Offset into our 24-bit chunk, shift to - * bring the desired code to the bottom, then mask it off and return it. - */ - -static int ReadCode() -{ - int RawCode, ByteOffset; - - ByteOffset = BitOffset / 8; - RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]); - if (CodeSize >= 8) - RawCode += (0x10000 * Raster[ByteOffset + 2]); - RawCode >>= (BitOffset % 8); - BitOffset += CodeSize; - return(RawCode & ReadMask); -} - - -static void AddToPixel(byte Index) -{ - if (YC= Height) - { - Pass++; - YC = 4; - } - break; - - case 1: - YC += 8; - if (YC >= Height) - { - Pass++; - YC = 2; - } - break; - - case 2: - YC += 4; - if (YC >= Height) - { - Pass++; - YC = 1; - } - break; - - case 3: - YC += 2; - break; - - default: - break; - } - } - } -} - - -static int ColorDicking(Display *display) -{ - /* we've got the picture loaded, we know what colors are needed. get 'em */ - - register int i,j; - static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; - byte lmask, *ptr; - int screen = DefaultScreen(display); - Colormap cmap = DefaultColormap(display,screen); - int dispcells = DisplayCells(display,screen); - - int strip = 0; - int nostrip = 0; - - if (!HasColormap) - return(GIF_Success); - /* no need to allocate any colors if no colormap in GIF file */ - - /* Allocate the X colors for this picture */ - - if (nostrip) - { - /* nostrip was set. try REAL hard to do it */ - for (i=j=0; i>8)) + - abs(g - (ctab[j].green>>8)) + - abs(b - (ctab[j].blue>>8)); - if (d=0; i--) - if (used[i]) - XFreeColors(display,cmap,cols+i,1,0L); - } - else - break; - } - -#ifdef DEBUG_GIF - if (j && strip<8) - fprintf(stderr,"%s: stripped %d bits\n",progname,strip); -#endif - - if (strip==8) - { - fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n"); - for (i=0; idepth == %d\n", - (*image)->depth); - printf("DefaultDepth(display, screen) == %d\n", - DefaultDepth(display, screen)); - - - - - if ((*image)->depth != depth) - { - XImage *old_image, *new_image; - - Visual *visual = DefaultVisual(display,screen); - - int width = (*image)->width; - int height = (*image)->height; - register int dwx, dwy; - byte *data; - - - - - - printf("ConvertXImageDepth: ---------> CONVERTING...\n"); - - - - - - - data = (byte *)malloc(width * height * depth); - old_image = *image; - -#if 1 - new_image = XCreateImage(display,visual,depth, - ZPixmap,0,data,width,height,8,0); -#else - new_image = XGetImage(display,RootWindow(display,screen), - 0,0,width,height,0xffffffff,ZPixmap); -#endif - - if (!new_image) - return(GIF_NoMemory); - - if (old_image->depth == 8 && new_image->depth == 4) - { - /* speedup for the most common format change */ - - register byte *sptr = (byte *)old_image->data; - register byte *dptr = (byte *)new_image->data; - - for (dwy=1; dwy<=height; dwy++) - { - for (dwx=1; dwx 4 bit */ - { - unsigned long pixel_value; - - for (dwx=0; dwx 0xff) - printf("pixel = %lx", pixel_value); - - XPutPixel(new_image, dwx, dwy, pixel_value); - } - } - } - - free(old_image->data); - old_image->data = NULL; - XDestroyImage(old_image); - - *image = new_image; - } - - return(GIF_Success); -} - - -static unsigned long be2long(unsigned char *be) /* big-endian -> long int */ -{ - return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]); -} - -static unsigned short be2short(unsigned char *be) /* big-endian -> short int */ -{ - return((be[0]<<8) | be[1]); -} - -static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data) -{ - struct IFF_ILBM_BMHD_big_endian *bmhd_be; - struct IFF_ILBM_BMHD *bmhd; - - bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data; - bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD)); - if (!bmhd) - return(NULL); - - bmhd->Width = be2short(bmhd_be->Width); - bmhd->Height = be2short(bmhd_be->Height); - bmhd->LeftEdge = be2short(bmhd_be->LeftEdge); - bmhd->TopEdge = be2short(bmhd_be->TopEdge); - bmhd->Depth = (int)bmhd_be->Depth; - bmhd->Mask = (int)bmhd_be->Mask; - bmhd->Compression = (int)bmhd_be->Compression; - bmhd->pad1 = bmhd_be->pad1; - bmhd->transparentColor = be2short(bmhd_be->transparentColor); - bmhd->xAspect = (int)bmhd_be->xAspect; - bmhd->yAspect = (int)bmhd_be->yAspect; - bmhd->pageWidth = be2short(bmhd_be->pageWidth); - bmhd->pageHeight = be2short(bmhd_be->pageHeight); - - return(bmhd); -} - -static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte) -{ - unsigned char lsb_byte = 0; - int i; - - for(i=7;i>=0;i--) - { - lsb_byte |= (msb_byte & 1) << i; - msb_byte >>= 1; - } - - return(lsb_byte); -} - -int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) -{ - Pixmap new_pixmap = 0; - int screen = DefaultScreen(display); - Drawable root = RootWindow(display,screen); - struct IFF_ILBM_FORM_big_endian *form_header; - struct IFF_ILBM_BMHD *bitmap_header; - unsigned long file_len, body_len; - unsigned char *file_data, *bitmap_data; - unsigned char *file_ptr, *bitmap_ptr, *body_ptr; - unsigned char byte_count, byte_value; - int i,x,y,z; - int width, height, depth; - int bytes_per_line, bitmap_size; - FILE *file; - - if (!(file = fopen(filename,"r"))) - return(ILBM_OpenFailed); - - if (fseek(file,0,SEEK_END) < 0) - { - fclose(file); - return(ILBM_ReadFailed); - } - - file_len = ftell(file); - rewind(file); - - if (!(file_data = (unsigned char *)malloc(file_len))) - { - fclose(file); - return(ILBM_NoMemory); - } - - if (fread(file_data,1,file_len,file) != file_len) - { - free(file_data); - fclose(file); - return(ILBM_ReadFailed); - } - - fclose(file); - - form_header = (struct IFF_ILBM_FORM_big_endian *)file_data; - - if (strncmp(form_header->magic_FORM,"FORM",4) || - file_len != be2long(form_header->chunk_size)+8 || - strncmp(form_header->magic_ILBM,"ILBM",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename); -#endif - free(file_data); - return(ILBM_FileInvalid); - } - - bitmap_header = NULL; - body_ptr = NULL; - file_ptr = file_data + 12; - - while(file_ptr < (unsigned char *)(file_data + file_len)) - { - if (!strncmp(file_ptr,"BMHD",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BMHD' found.\n",filename); -#endif - bitmap_header = ConvertBMHD(file_ptr + 8); - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - else if (!strncmp(file_ptr,"BODY",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BODY' found.\n",filename); -#endif - body_ptr = file_ptr + 8; - body_len = be2long(file_ptr + 4); - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - else - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename, - file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]); -#endif - /* other chunk not recognized here */ - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - } - - if (!bitmap_header || !body_ptr) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename); -#endif - free(file_data); - return(ILBM_FileInvalid); - } - - width = bitmap_header->Width; - height = bitmap_header->Height; - depth = bitmap_header->Depth; - -#ifdef DEBUG_ILBM - if (depth > 1) - printf("%s: %d bitplanes found; using only the first plane.\n", - filename,depth); -#endif - - bytes_per_line = ((width + 15) / 16) * 2; - bitmap_size = bytes_per_line * height; - - bitmap_data = (char *)malloc(bitmap_size); - if (!bitmap_data) - { - free(file_data); - free(bitmap_header); - return(ILBM_NoMemory); - } - - bitmap_ptr = bitmap_data; - for(i=0;iCompression) - { - while(x++ < bytes_per_line) - *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++); - } - else - { - while(x < bytes_per_line) - { - byte_count = *body_ptr++; - - if (byte_count <= 128) - { - for(i=0;i -#include -#include -#include -#include - -#define GIF_Success 0 -#define GIF_OpenFailed -1 -#define GIF_ReadFailed -2 -#define GIF_FileInvalid -3 -#define GIF_NoMemory -4 -#define GIF_ColorFailed -5 - -#define ILBM_Success 0 -#define ILBM_OpenFailed -1 -#define ILBM_ReadFailed -2 -#define ILBM_FileInvalid -3 -#define ILBM_NoMemory -4 -#define ILBM_ColorFailed -5 - -int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *); -int Read_GIF_to_Bitmap(Display *, char *, Pixmap *); -int Read_GIF_to_Pixmap(Display *, char *, Pixmap *); -int Read_GIF_to_XImage(Display *, char *, XImage **); - -#endif -#endif diff --git a/src/gfxloader.c b/src/gfxloader.c deleted file mode 100644 index 9a28f435..00000000 --- a/src/gfxloader.c +++ /dev/null @@ -1,1155 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* ©1995 Artsoft Development * -* Holger Schemel * -* 33659 Bielefeld-Senne * -* Telefon: (0521) 493245 * -* eMail: aeglos@valinor.owl.de * -* aeglos@uni-paderborn.de * -* q99492@pbhrzx.uni-paderborn.de * -*----------------------------------------------------------* -* gfxloader.c * -***********************************************************/ - -#include "gfxloader.h" - - - - - - -extern Window window; -extern void Delay(long); - - - - - - -#ifdef DEBUG -/* -#define DEBUG_GIF -#define DEBUG_ILBM -*/ -#endif - -struct IFF_ILBM_FORM_big_endian -{ - char magic_FORM[4]; - unsigned char chunk_size[4]; - char magic_ILBM[4]; -}; - -struct IFF_ILBM_BMHD_big_endian -{ - char Width[2], Height[2]; - char LeftEdge[2], TopEdge[2]; - char Depth; - char Mask; - char Compression; - char pad1; - char transparentColor[2]; - char xAspect, yAspect; - char pageWidth[2], pageHeight[2]; -}; - -struct IFF_ILBM_BMHD -{ - unsigned int Width, Height; - int LeftEdge, TopEdge; - unsigned int Depth; - unsigned int Mask; - unsigned int Compression; - unsigned char pad1; - unsigned int transparentColor; - unsigned int xAspect, yAspect; - int pageWidth, pageHeight; -}; - -static int ConvertXImageDepth(Display *, XImage **); -static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int); - -#define READ_GIF_TO_BITMAP 0 -#define READ_GIF_TO_PIXMAP 1 - - -int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) -{ - printf("Read_GIF_to_Bitmap\n"); - - - - - return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, - pixmap, READ_GIF_TO_BITMAP)); -} - -int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap) -{ - printf("Read_GIF_to_Pixmap\n"); - - - - - return(Read_GIF_to_Pixmap_or_Bitmap(display, filename, - pixmap, READ_GIF_TO_PIXMAP)); -} - -int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename, - Pixmap *pixmap, int mode) -{ - XImage *image = NULL; - Pixmap new_pixmap = 0; - int return_code; - - *pixmap = 0; - return_code = Read_GIF_to_XImage(display, filename, &image); - if (return_code != GIF_Success) - return(return_code); - - if (image) - { - int screen = DefaultScreen(display); - Drawable root = RootWindow(display,screen); - int depth = DefaultDepth(display, screen); - int width = image->width; - int height = image->height; - - if (mode == READ_GIF_TO_BITMAP) - { - int i,x,y; - unsigned long black_pixel = BlackPixel(display,screen); - int bytes_per_line = (width+7) / 8; - int size = bytes_per_line * height; - char *data, *ptr; - - data = (char *)malloc(size); - if (!data) - return(GIF_NoMemory); - - ptr = data; - for(i=0;i filesize) - return(GIF_FileInvalid); - } - while(ch1); - - free(RawGIF); /* We're done with the raw data now... */ - -#ifdef DEBUG_GIF - fprintf(stderr, "done\n"); - fprintf(stderr, " Decompressing... "); -#endif - - /* Allocate the X Image */ - ImageData = (byte *) malloc(Width*Height); - if (!ImageData) - return(GIF_NoMemory); - - new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData, - Width,Height,8,Width); - if (!new_image) - return(GIF_NoMemory); - - BytesPerScanline = Width; - - - /* Decompress the file, continuing until you see the GIF EOF code. - * One obvious enhancement is to add checking for corrupt files here. - */ - - Code = ReadCode(); - while (Code != EOFCode) - { - /* Clear code sets everything back to its initial value, then reads the - * immediately subsequent code as uncompressed data. - */ - - if (Code == ClearCode) - { - CodeSize = InitCodeSize; - MaxCode = (1 << CodeSize); - ReadMask = MaxCode - 1; - FreeCode = FirstFree; - CurCode = OldCode = Code = ReadCode(); - FinChar = CurCode & BitMask; - AddToPixel(FinChar); - } - else - { - /* If not a clear code, then must be data: - * save same as CurCode and InCode - */ - - CurCode = InCode = Code; - - /* If greater or equal to FreeCode, not in the hash table yet; - * repeat the last character decoded - */ - - if (CurCode >= FreeCode) - { - CurCode = OldCode; - OutCode[OutCount++] = FinChar; - } - - /* Unless this code is raw data, pursue the chain pointed to by CurCode - * through the hash table to its end; each code in the chain puts its - * associated output code on the output queue. - */ - - while (CurCode > BitMask) - { - if (OutCount > 1024) - return(GIF_FileInvalid); - - OutCode[OutCount++] = Suffix[CurCode]; - CurCode = Prefix[CurCode]; - } - - /* The last code in the chain is treated as raw data. */ - - FinChar = CurCode & BitMask; - OutCode[OutCount++] = FinChar; - - /* Now we put the data out to the Output routine. - * It's been stacked LIFO, so deal with it that way... - */ - - for (i = OutCount - 1; i >= 0; i--) - AddToPixel(OutCode[i]); - OutCount = 0; - - /* Build the hash table on-the-fly. No table is stored in the file. */ - - Prefix[FreeCode] = OldCode; - Suffix[FreeCode] = FinChar; - OldCode = InCode; - - /* Point to the next slot in the table. If we exceed the current - * MaxCode value, increment the code size unless it's already 12. If it - * is, do nothing: the next code decompressed better be CLEAR - */ - - FreeCode++; - if (FreeCode >= MaxCode) - { - if (CodeSize < 12) - { - CodeSize++; - MaxCode *= 2; - ReadMask = (1 << CodeSize) - 1; - } - } - } - Code = ReadCode(); - } - - free(Raster); - -#ifdef DEBUG_GIF - fprintf(stderr, "done\n"); - fprintf(stderr," %d colors used\n",numused); -#endif - - if (file != stdin) - fclose(file); - - if (ColorDicking(display) != GIF_Success) - return(GIF_ColorFailed); - - *image = new_image; - return(GIF_Success); -} - - -/* Fetch the next code from the raster data stream. The codes can be - * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to - * maintain our location in the Raster array as a BIT Offset. We compute - * the byte Offset into the raster array by dividing this by 8, pick up - * three bytes, compute the bit Offset into our 24-bit chunk, shift to - * bring the desired code to the bottom, then mask it off and return it. - */ - -static int ReadCode() -{ - int RawCode, ByteOffset; - - ByteOffset = BitOffset / 8; - RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]); - if (CodeSize >= 8) - RawCode += (0x10000 * Raster[ByteOffset + 2]); - RawCode >>= (BitOffset % 8); - BitOffset += CodeSize; - return(RawCode & ReadMask); -} - - -static void AddToPixel(byte Index) -{ - if (YC= Height) - { - Pass++; - YC = 4; - } - break; - - case 1: - YC += 8; - if (YC >= Height) - { - Pass++; - YC = 2; - } - break; - - case 2: - YC += 4; - if (YC >= Height) - { - Pass++; - YC = 1; - } - break; - - case 3: - YC += 2; - break; - - default: - break; - } - } - } -} - - -static int ColorDicking(Display *display) -{ - /* we've got the picture loaded, we know what colors are needed. get 'em */ - - register int i,j; - static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; - byte lmask, *ptr; - int screen = DefaultScreen(display); - Colormap cmap = DefaultColormap(display,screen); - int dispcells = DisplayCells(display,screen); - - int strip = 0; - int nostrip = 0; - - if (!HasColormap) - return(GIF_Success); - /* no need to allocate any colors if no colormap in GIF file */ - - /* Allocate the X colors for this picture */ - - if (nostrip) - { - /* nostrip was set. try REAL hard to do it */ - for (i=j=0; i>8)) + - abs(g - (ctab[j].green>>8)) + - abs(b - (ctab[j].blue>>8)); - if (d=0; i--) - if (used[i]) - XFreeColors(display,cmap,cols+i,1,0L); - } - else - break; - } - -#ifdef DEBUG_GIF - if (j && strip<8) - fprintf(stderr,"%s: stripped %d bits\n",progname,strip); -#endif - - if (strip==8) - { - fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n"); - for (i=0; idepth == %d\n", - (*image)->depth); - printf("DefaultDepth(display, screen) == %d\n", - DefaultDepth(display, screen)); - - - - - if ((*image)->depth != depth) - { - XImage *old_image, *new_image; - /* - Visual *visual = DefaultVisual(display,screen); - */ - int width = (*image)->width; - int height = (*image)->height; - register int dwx, dwy; - byte *data; - - - - - - printf("ConvertXImageDepth: ---------> CONVERTING...\n"); - - - - - - - data = (byte *)malloc(width * height * depth); - old_image = *image; - - /* - new_image = XCreateImage(display,visual,depth, - ZPixmap,0,data,width,height,8,0); - */ - - new_image = XGetImage(display,RootWindow(display,screen), - 0,0,width,height,0xffffffff,ZPixmap); - - - if (!new_image) - return(GIF_NoMemory); - - if (old_image->depth == 8 && new_image->depth == 4) - { - /* speedup for the most common format change */ - - register byte *sptr = (byte *)old_image->data; - register byte *dptr = (byte *)new_image->data; - - for (dwy=1; dwy<=height; dwy++) - { - for (dwx=1; dwx 4 bit */ - { - unsigned long pixel_value; - - for (dwx=0; dwx 0xff) - printf("pixel = %lx", pixel_value); - - XPutPixel(new_image, dwx, dwy, pixel_value); - } - } - } - - free(old_image->data); - old_image->data = NULL; - XDestroyImage(old_image); - - *image = new_image; - } - - return(GIF_Success); -} - - -static unsigned long be2long(unsigned char *be) /* big-endian -> long int */ -{ - return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]); -} - -static unsigned short be2short(unsigned char *be) /* big-endian -> short int */ -{ - return((be[0]<<8) | be[1]); -} - -static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data) -{ - struct IFF_ILBM_BMHD_big_endian *bmhd_be; - struct IFF_ILBM_BMHD *bmhd; - - bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data; - bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD)); - if (!bmhd) - return(NULL); - - bmhd->Width = be2short(bmhd_be->Width); - bmhd->Height = be2short(bmhd_be->Height); - bmhd->LeftEdge = be2short(bmhd_be->LeftEdge); - bmhd->TopEdge = be2short(bmhd_be->TopEdge); - bmhd->Depth = (int)bmhd_be->Depth; - bmhd->Mask = (int)bmhd_be->Mask; - bmhd->Compression = (int)bmhd_be->Compression; - bmhd->pad1 = bmhd_be->pad1; - bmhd->transparentColor = be2short(bmhd_be->transparentColor); - bmhd->xAspect = (int)bmhd_be->xAspect; - bmhd->yAspect = (int)bmhd_be->yAspect; - bmhd->pageWidth = be2short(bmhd_be->pageWidth); - bmhd->pageHeight = be2short(bmhd_be->pageHeight); - - return(bmhd); -} - -static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte) -{ - unsigned char lsb_byte = 0; - int i; - - for(i=7;i>=0;i--) - { - lsb_byte |= (msb_byte & 1) << i; - msb_byte >>= 1; - } - - return(lsb_byte); -} - -int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap) -{ - Pixmap new_pixmap = 0; - int screen = DefaultScreen(display); - Drawable root = RootWindow(display,screen); - struct IFF_ILBM_FORM_big_endian *form_header; - struct IFF_ILBM_BMHD *bitmap_header; - unsigned long file_len, body_len; - unsigned char *file_data, *bitmap_data; - unsigned char *file_ptr, *bitmap_ptr, *body_ptr; - unsigned char byte_count, byte_value; - int i,x,y,z; - int width, height, depth; - int bytes_per_line, bitmap_size; - FILE *file; - - - - - - printf("Read_ILBM_to_Bitmap\n"); - - - - - if (!(file = fopen(filename,"r"))) - return(ILBM_OpenFailed); - - if (fseek(file,0,SEEK_END) < 0) - { - fclose(file); - return(ILBM_ReadFailed); - } - - file_len = ftell(file); - rewind(file); - - if (!(file_data = (unsigned char *)malloc(file_len))) - { - fclose(file); - return(ILBM_NoMemory); - } - - if (fread(file_data,1,file_len,file) != file_len) - { - free(file_data); - fclose(file); - return(ILBM_ReadFailed); - } - - fclose(file); - - form_header = (struct IFF_ILBM_FORM_big_endian *)file_data; - - if (strncmp(form_header->magic_FORM,"FORM",4) || - file_len != be2long(form_header->chunk_size)+8 || - strncmp(form_header->magic_ILBM,"ILBM",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename); -#endif - free(file_data); - return(ILBM_FileInvalid); - } - - bitmap_header = NULL; - body_ptr = NULL; - file_ptr = file_data + 12; - - while(file_ptr < (unsigned char *)(file_data + file_len)) - { - if (!strncmp(file_ptr,"BMHD",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BMHD' found.\n",filename); -#endif - bitmap_header = ConvertBMHD(file_ptr + 8); - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - else if (!strncmp(file_ptr,"BODY",4)) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BODY' found.\n",filename); -#endif - body_ptr = file_ptr + 8; - body_len = be2long(file_ptr + 4); - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - else - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename, - file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]); -#endif - /* other chunk not recognized here */ - file_ptr += be2long(file_ptr + 4) + 8; - continue; - } - } - - if (!bitmap_header || !body_ptr) - { -#ifdef DEBUG_ILBM - printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename); -#endif - free(file_data); - return(ILBM_FileInvalid); - } - - width = bitmap_header->Width; - height = bitmap_header->Height; - depth = bitmap_header->Depth; - -#ifdef DEBUG_ILBM - if (depth > 1) - printf("%s: %d bitplanes found; using only the first plane.\n", - filename,depth); -#endif - - bytes_per_line = ((width + 15) / 16) * 2; - bitmap_size = bytes_per_line * height; - - bitmap_data = (char *)malloc(bitmap_size); - if (!bitmap_data) - { - free(file_data); - free(bitmap_header); - return(ILBM_NoMemory); - } - - bitmap_ptr = bitmap_data; - for(i=0;iCompression) - { - while(x++ < bytes_per_line) - *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++); - } - else - { - while(x < bytes_per_line) - { - byte_count = *body_ptr++; - - if (byte_count <= 128) - { - for(i=0;i -#include -#include -#include -#include - -#define GIF_Success 0 -#define GIF_OpenFailed -1 -#define GIF_ReadFailed -2 -#define GIF_FileInvalid -3 -#define GIF_NoMemory -4 -#define GIF_ColorFailed -5 - -#define ILBM_Success 0 -#define ILBM_OpenFailed -1 -#define ILBM_ReadFailed -2 -#define ILBM_FileInvalid -3 -#define ILBM_NoMemory -4 -#define ILBM_ColorFailed -5 - -int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *); -int Read_GIF_to_Bitmap(Display *, char *, Pixmap *); -int Read_GIF_to_Pixmap(Display *, char *, Pixmap *); -int Read_GIF_to_XImage(Display *, char *, XImage **); - -#endif diff --git a/src/gif.c b/src/gif.c deleted file mode 100644 index bf3f5fc7..00000000 --- a/src/gif.c +++ /dev/null @@ -1,616 +0,0 @@ - -/* gif.c */ - -#define GIF_C - -#include "gif.h" -#include "image.h" - -#define PUSH_PIXEL(p) \ -{ \ - if (pstk_idx == PSTK_SIZE) \ - return GIFIN_ERR_PSO; \ - else \ - pstk[pstk_idx++] = (p); \ -} - -/* - * push a string (denoted by a code) onto the pixel stack - * (returns the code of the first pixel in the string in ps_rslt) - */ - -int ps_rslt; /* return result */ - -#define GIFIN_PUSH_STRING(code) \ -{ \ - int ps_code; \ - ps_code = code; \ - \ - while (((unsigned int)ps_code) < STAB_SIZE && prefix[ps_code] != NULL_CODE) \ - { \ - PUSH_PIXEL(extnsn[ps_code]); \ - ps_code = prefix[ps_code]; \ - } \ - \ - if (((unsigned int)ps_code) >= STAB_SIZE) \ - return GIFIN_ERR_TAO; \ - PUSH_PIXEL(extnsn[ps_code]); \ - ps_rslt = extnsn[ps_code]; \ - if (((unsigned int)ps_rslt) >= STAB_SIZE) \ - return GIFIN_ERR_TAO; \ -} - -/* - * Look up the ascii message coresponding to - * the error number. - */ -static char *get_err_string(int errno) -{ - int i; - for (i=0;gif_err_strings[i].err_no != 0;i++) - { - if (gif_err_strings[i].err_no == errno) - return gif_err_strings[i].name; - } - return ""; -} - - -static int interlace_start[4] = /* start line for interlacing */ -{ - 0, 4, 2, 1 -}; - -static int interlace_rate[4] = /* rate at which we accelerate vertically */ -{ - 8, 8, 4, 2 -}; - -static BYTE file_open = 0; /* status flags */ -static BYTE image_open = 0; - -static FILE *ins; /* input stream */ - -static int root_size; /* root code size */ -static int clr_code; /* clear code */ -static int eoi_code; /* end of information code */ -static int code_size; /* current code size */ -static int code_mask; /* current code mask */ -static int prev_code; /* previous code */ - -static long work_data; /* working bit buffer */ -static int work_bits; /* working bit count */ - -static BYTE buf[256]; /* byte buffer */ -static int buf_cnt; /* byte count */ -static int buf_idx; /* buffer index */ - -static int table_size; /* string table size */ -static int prefix[STAB_SIZE]; /* string table : prefixes */ -static int extnsn[STAB_SIZE]; /* string table : extensions */ - -static BYTE pstk[PSTK_SIZE]; /* pixel stack */ -static int pstk_idx; /* pixel stack pointer */ - - -static int gifin_rast_width; /* raster width */ -static int gifin_rast_height; /* raster height */ -static BYTE gifin_g_cmap_flag; /* global colormap flag */ -static int gifin_g_pixel_bits; /* bits per pixel, global colormap */ -static int gifin_g_ncolors; /* number of colors, global colormap */ -static BYTE gifin_g_cmap[3][256]; /* global colormap */ -static BYTE gifin_g_cmap_sorted; /* global colormap sorted (GIF89a only) */ -static int gifin_bg_color; /* background color index */ -static int gifin_color_bits; /* bits of color resolution */ -static double gifin_aspect; /* pixel aspect ratio (width/height) */ -static int gifin_version; /* gif file version */ - -static int gifin_img_left; /* image position on raster */ -static int gifin_img_top; /* image position on raster */ -static int gifin_img_width; /* image width */ -static int gifin_img_height; /* image height */ -static BYTE gifin_l_cmap_flag; /* local colormap flag */ -static int gifin_l_pixel_bits; /* bits per pixel, local colormap */ -static int gifin_l_ncolors; /* number of colors, local colormap */ -static BYTE gifin_l_cmap[3][256]; /* local colormap */ -static BYTE gifin_interlace_flag; /* interlace image format flag */ - -/* - * open a GIF file, using s as the input stream - */ - -static int gifin_open_file(FILE *s) -{ - int errno; - /* make sure there isn't already a file open */ - if (file_open) - return GIFIN_ERR_FAO; - - /* remember that we've got this file open */ - file_open = 1; - ins = s; - - /* check GIF signature */ - if (fread(buf, 1, GIF_SIG_LEN, ins) != GIF_SIG_LEN) - return GIFIN_ERR_EOF; - - buf[GIF_SIG_LEN] = '\0'; - if (strcmp((char *) buf, GIF_SIG) == 0) - gifin_version = GIF87a; - else if (strcmp((char *) buf, GIF_SIG_89) == 0) - gifin_version = GIF89a; - else - return GIFIN_ERR_BAD_SIG; - - /* read screen descriptor */ - if (fread(buf, 1, GIF_SD_SIZE, ins) != GIF_SD_SIZE) - return GIFIN_ERR_EOF; - - /* decode screen descriptor */ - gifin_rast_width = (buf[1] << 8) + buf[0]; - gifin_rast_height = (buf[3] << 8) + buf[2]; - gifin_g_cmap_flag = (buf[4] & 0x80) ? 1 : 0; - gifin_color_bits = (((int)(buf[4] & 0x70)) >> 4) + 1; - gifin_g_pixel_bits = (buf[4] & 0x07) + 1; - gifin_bg_color = buf[5]; - gifin_aspect = 1.0; - - if (gifin_version == GIF87a) - { - if (buf[4] & 0x08 || buf[6] != 0) - return GIFIN_ERR_BAD_SD; - } - else - { - gifin_g_cmap_sorted = ((buf[4] & 0x08) != 0); - if (buf[6] != 0) - gifin_aspect = ((double)buf[6] + 15.0) / 64.0; - } - - /* load global colormap */ - if (gifin_g_cmap_flag) - { - gifin_g_ncolors = (1 << gifin_g_pixel_bits); - - if ((errno = gifin_load_cmap(gifin_g_cmap, gifin_g_ncolors)) != GIFIN_SUCCESS) - return errno; - } - else - { - gifin_g_ncolors = 0; - } - - /* done! */ - return GIFIN_SUCCESS; -} - - -/* - * open next GIF image in the input stream; returns GIFIN_SUCCESS if - * successful. if there are no more images, returns GIFIN_DONE. (might - * also return various GIFIN_ERR codes.) - */ - -static int gifin_open_image() -{ - int i; - int separator; - int errno; - - /* make sure there's a file open */ - if (!file_open) - return GIFIN_ERR_NFO; - - /* make sure there isn't already an image open */ - if (image_open) - return GIFIN_ERR_IAO; - - /* remember that we've got this image open */ - image_open = 1; - - /* skip over any extension blocks */ - do - { - separator = fgetc(ins); - if (separator == GIF_EXTENSION) - { - if ((errno = gifin_skip_extension()) != GIFIN_SUCCESS) - return errno; - } - } - while (separator == GIF_EXTENSION); - - /* check for end of file marker */ - if (separator == GIF_TERMINATOR) - return GIFIN_DONE; - - /* make sure we've got an image separator */ - if (separator != GIF_SEPARATOR) - return GIFIN_ERR_BAD_SEP; - - /* read image descriptor */ - if (fread(buf, 1, GIF_ID_SIZE, ins) != GIF_ID_SIZE) - return GIFIN_ERR_EOF; - - /* decode image descriptor */ - gifin_img_left = (buf[1] << 8) + buf[0]; - gifin_img_top = (buf[3] << 8) + buf[2]; - gifin_img_width = (buf[5] << 8) + buf[4]; - gifin_img_height = (buf[7] << 8) + buf[6]; - gifin_l_cmap_flag = (buf[8] & 0x80) ? 1 : 0; - gifin_interlace_flag = (buf[8] & 0x40) ? 1 : 0; - gifin_l_pixel_bits = (buf[8] & 0x07) + 1; - - /* load local colormap */ - if (gifin_l_cmap_flag) - { - gifin_l_ncolors = (1 << gifin_l_pixel_bits); - - if ((errno = gifin_load_cmap(gifin_l_cmap, gifin_l_ncolors)) != GIFIN_SUCCESS) - return errno; - } - else - { - gifin_l_ncolors = 0; - } - - /* initialize raster data stream decoder */ - root_size = fgetc(ins); - clr_code = 1 << root_size; - eoi_code = clr_code + 1; - code_size = root_size + 1; - code_mask = (1 << code_size) - 1; - work_bits = 0; - work_data = 0; - buf_cnt = 0; - buf_idx = 0; - - /* initialize string table */ - for (i=0; i>= code_size; - work_bits -= code_size; - - /* interpret the code */ - if (code == clr_code) - { - /* reset decoder stream */ - code_size = root_size + 1; - code_mask = (1 << code_size) - 1; - prev_code = NULL_CODE; - table_size = eoi_code + 1; - } - else if (code == eoi_code) - { - /* Ooops! no more pixels */ - return GIFIN_ERR_EOF; - } - else if (prev_code == NULL_CODE) - { - GIFIN_PUSH_STRING(code); - prev_code = code; - } - else - { - if (code < table_size) - { - GIFIN_PUSH_STRING(code); - first = ps_rslt; - } - else - { - place = pstk_idx; - PUSH_PIXEL(NULL_CODE); - GIFIN_PUSH_STRING(prev_code); - first = ps_rslt; - pstk[place] = first; - } - - if ((errno = gifin_add_string(prev_code, first)) != GIFIN_SUCCESS) - return errno; - prev_code = code; - } - } - - /* pop a pixel off the pixel stack */ - *pel = (int) pstk[--pstk_idx]; - - /* done! */ - return GIFIN_SUCCESS; -} - -/* - * close an open GIF file - */ - -static int gifin_close_file() -{ - /* make sure there's a file open */ - if (!file_open) - return GIFIN_ERR_NFO; - - /* mark file (and image) as closed */ - file_open = 0; - image_open = 0; - - /* done! */ - return GIFIN_SUCCESS; -} - -/* - * load a colormap from the input stream - */ - -static int gifin_load_cmap(BYTE cmap[3][256], int ncolors) -{ - int i; - - for (i=0; i 0); - - /* done! */ - return GIFIN_SUCCESS; -} - -/* - * read a new data block from the input stream - */ - -static int gifin_read_data_block() -{ - /* read the data block header */ - buf_cnt = fgetc(ins); - - /* read the data block body */ - if (fread(buf, 1, buf_cnt, ins) != buf_cnt) - return GIFIN_ERR_EOF; - - buf_idx = 0; - - /* done! */ - return GIFIN_SUCCESS; -} - - -/* - * add a new string to the string table - */ - -static int gifin_add_string(int p, int e) -{ - prefix[table_size] = p; - extnsn[table_size] = e; - - if ((table_size == code_mask) && (code_size < 12)) - { - code_size += 1; - code_mask = (1 << code_size) - 1; - } - - table_size += 1; - if (table_size > STAB_SIZE) - return GIFIN_ERR_TAO; - return GIFIN_SUCCESS; -} - -Image *Read_GIF_to_Image(char *fullname) -{ - FILE *f; - Image *image; - int x, y, pixel, pass, scanlen; - byte *pixptr, *pixline; - int errno; - - if (!(f = fopen(fullname,"r"))) - { - perror("gifLoad"); - return(NULL); - } - - if ((gifin_open_file(f) != GIFIN_SUCCESS) || /* read GIF header */ - (gifin_open_image() != GIFIN_SUCCESS)) /* read image header */ - { - printf("gifin_open_file or gifin_open_image failed!\n"); - - gifin_close_file(); - fclose(f); - return(NULL); - } - - - - /* - printf("%s:\n %dx%d %s%s image with %d colors at depth %d\n", - fullname, gifin_img_width, gifin_img_height, - (gifin_interlace_flag ? "interlaced " : ""), - gif_version_name[gifin_version], - (gifin_l_cmap_flag ? gifin_l_ncolors : gifin_g_ncolors), - (gifin_l_cmap_flag ? gifin_l_pixel_bits : gifin_g_pixel_bits)); - */ - - - - image = newRGBImage(gifin_img_width, gifin_img_height, (gifin_l_cmap_flag ? - gifin_l_pixel_bits : - gifin_g_pixel_bits)); - - /* if image has a local colormap, override global colormap - */ - - if (gifin_l_cmap_flag) - { - for (x=0; xrgb.red[x] = gifin_l_cmap[GIF_RED][x] << 8; - image->rgb.green[x] = gifin_l_cmap[GIF_GRN][x] << 8; - image->rgb.blue[x] = gifin_l_cmap[GIF_BLU][x] << 8; - } - image->rgb.used = gifin_l_ncolors; - } - else - { - for (x=0; xrgb.red[x] = gifin_g_cmap[GIF_RED][x] << 8; - image->rgb.green[x] = gifin_g_cmap[GIF_GRN][x] << 8; - image->rgb.blue[x] = gifin_g_cmap[GIF_BLU][x] << 8; - } - image->rgb.used = gifin_g_ncolors; - } - - /* interlaced image -- futz with the vertical trace. i wish i knew what - * kind of drugs the GIF people were on when they decided that they - * needed to support interlacing. - */ - - if (gifin_interlace_flag) - { - scanlen = image->height * image->pixlen; - - /* interlacing takes four passes to read, each starting at a different - * vertical point. - */ - - for (pass=0; pass<4; pass++) - { - y = interlace_start[pass]; - scanlen = image->width * image->pixlen * interlace_rate[pass]; - pixline = image->data + (y * image->width * image->pixlen); - while (y < gifin_img_height) - { - pixptr = pixline; - for (x=0; xpixlen); - pixptr += image->pixlen; - } - y += interlace_rate[pass]; - pixline += scanlen; - } - } - } - else - { - /* not an interlaced image, just read in sequentially - */ - - if (image->pixlen == 1) /* the usual case */ - { - pixptr = image->data; - for (y=0; ydata; - for (y=0; ypixlen); - pixptr += image->pixlen; - } - } - } - - gifin_close_file(); - fclose(f); - - return(image); -} diff --git a/src/gif.h b/src/gif.h deleted file mode 100644 index 89c252fa..00000000 --- a/src/gif.h +++ /dev/null @@ -1,121 +0,0 @@ - -/* gif.h: - * - * gifin.h - * kirk johnson - * november 1989 - * external interface to gifin.c - * - * Copyright 1989 Kirk L. Johnson (see the included file - * "kljcpyrght.h" for complete copyright information) - */ - -/* - * gifin return codes - */ -#define GIFIN_SUCCESS 0 /* success */ -#define GIFIN_DONE 1 /* no more images */ - -#define GIFIN_ERR_BAD_SD -1 /* bad screen descriptor */ -#define GIFIN_ERR_BAD_SEP -2 /* bad image separator */ -#define GIFIN_ERR_BAD_SIG -3 /* bad signature */ -#define GIFIN_ERR_EOD -4 /* unexpected end of raster data */ -#define GIFIN_ERR_EOF -5 /* unexpected end of input stream */ -#define GIFIN_ERR_FAO -6 /* file already open */ -#define GIFIN_ERR_IAO -7 /* image already open */ -#define GIFIN_ERR_NFO -8 /* no file open */ -#define GIFIN_ERR_NIO -9 /* no image open */ -#define GIFIN_ERR_PSO -10 /* pixel stack overflow */ -#define GIFIN_ERR_TAO -11 /* table overflow */ -#define GIFIN_ERR_BAD_DES -12 /* bad image descriptor */ - -#define GIFIN_ERR_BAD_SD_STR "Bad screen descriptor" -#define GIFIN_ERR_BAD_SEP_STR "Bad image separator" -#define GIFIN_ERR_BAD_SIG_STR "Bad signature" -#define GIFIN_ERR_EOD_STR "Unexpected end of raster data" -#define GIFIN_ERR_EOF_STR "Unexpected end of input stream" -#define GIFIN_ERR_FAO_STR "File already open" -#define GIFIN_ERR_IAO_STR "Image already open" -#define GIFIN_ERR_NFO_STR "No file open" -#define GIFIN_ERR_NIO_STR "No image open" -#define GIFIN_ERR_PSO_STR "Pixel stack overflow" -#define GIFIN_ERR_TAO_STR "Table overflow" -#define GIFIN_ERR_BAD_DES_STR "Bad image descriptor" - -typedef struct { - int err_no; - char *name; - } gif_err_string; - -#ifdef GIF_C -gif_err_string gif_err_strings[] = { - {GIFIN_ERR_BAD_SD, GIFIN_ERR_BAD_SD_STR}, - {GIFIN_ERR_BAD_SEP, GIFIN_ERR_BAD_SEP_STR}, - {GIFIN_ERR_BAD_SIG, GIFIN_ERR_BAD_SIG_STR}, - {GIFIN_ERR_EOD, GIFIN_ERR_EOD_STR}, - {GIFIN_ERR_EOF, GIFIN_ERR_EOF_STR}, - {GIFIN_ERR_FAO, GIFIN_ERR_FAO_STR}, - {GIFIN_ERR_IAO, GIFIN_ERR_IAO_STR}, - {GIFIN_ERR_NFO, GIFIN_ERR_NFO_STR}, - {GIFIN_ERR_NIO, GIFIN_ERR_NIO_STR}, - {GIFIN_ERR_PSO, GIFIN_ERR_PSO_STR}, - {GIFIN_ERR_TAO, GIFIN_ERR_TAO_STR}, - {GIFIN_ERR_BAD_DES, GIFIN_ERR_BAD_DES_STR}, - {0} - }; -#endif - -/* - * colormap indices - */ - -#define GIF_RED 0 -#define GIF_GRN 1 -#define GIF_BLU 2 - -/* - * typedef BYTE for convenience - */ - -typedef unsigned char BYTE; - -static int gifin_open_file(); -static int gifin_open_image(); -static int gifin_get_pixel(); -#if 0 -static int gifin_close_image(); -#endif -static int gifin_close_file(); -static int gifin_load_cmap(); -static int gifin_skip_extension(); -static int gifin_read_data_block(); -static int gifin_add_string(); - -/* #defines, typedefs, and such - */ - -#define GIF_SIG "GIF87a" -#define GIF_SIG_89 "GIF89a" - -#define GIF87a 0 /* Gif file version type */ -#define GIF89a 1 /* Gif file version type */ - -#define GIF_SIG_LEN 6 /* GIF signature length */ -#define GIF_SD_SIZE 7 /* GIF screen descriptor size */ -#define GIF_ID_SIZE 9 /* GIF image descriptor size */ - -#define GIF_SEPARATOR ',' /* GIF image separator */ -#define GIF_EXTENSION '!' /* GIF extension block marker */ -#define GIF_TERMINATOR ';' /* GIF terminator */ - -#define STAB_SIZE 4096 /* string table size */ -#define PSTK_SIZE 4096 /* pixel stack size */ - -#define NULL_CODE -1 /* string table null code */ - -#ifdef GIF_C -char *gif_version_name[] = { - GIF_SIG, - GIF_SIG_89 - }; -#endif diff --git a/src/gifload.c b/src/gifload.c deleted file mode 100644 index f7bb5146..00000000 --- a/src/gifload.c +++ /dev/null @@ -1,19 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* gifload.c * -***********************************************************/ - -#ifndef MSDOS -#include "gifload.h" - -#include "image.h" - -#endif diff --git a/src/gifload.h b/src/gifload.h deleted file mode 100644 index 1f8cf1c8..00000000 --- a/src/gifload.h +++ /dev/null @@ -1,25 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* gifload.h * -***********************************************************/ - -#ifndef GIFLOAD_H -#define GIFLOAD_H - -#ifndef MSDOS -#include -#include -#include -#include -#include -#endif - -#endif diff --git a/src/msdos.c b/src/msdos.c deleted file mode 100644 index 4d2c4329..00000000 --- a/src/msdos.c +++ /dev/null @@ -1,980 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* msdos.c * -***********************************************************/ - -#ifdef MSDOS -#include "main.h" -#include "tools.h" -#include "sound.h" -#include "files.h" -#include "joystick.h" - -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) - -static int key_buffer[OSD_MAX_KEY]; -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; - -boolean wait_for_vsync; - -extern int playing_sounds; -extern struct SoundControl playlist[MAX_SOUNDS_PLAYING]; -extern struct SoundControl emptySoundControl; - -void allegro_drivers() -{ - int i; - - for(i = 0; i < MAX_EVENT_BUFFER; i++); - event_buffer[i].type = 0; - for(i=0; i < OSD_MAX_KEY; i++) key_buffer[i] = KeyReleaseMask; - last_mouse_pos = mouse_pos; - last_mouse_b = 0; - - pending_events = 0; - clear_keybuf(); - - i_love_bill = TRUE; - install_keyboard(); - install_timer(); - if (install_mouse() > 0) mouse_installed = TRUE; - install_joystick(JOY_TYPE_2PADS); - - load_joystick_data(JOYDAT_FILE); - last_joystick_state = 0; - joystick_event = FALSE; - - reserve_voices(MAX_SOUNDS_PLAYING, 0); - if(install_sound(DIGI_AUTODETECT, MIDI_NONE, "ROCKS.SND") == -1) - if(install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) sound_status = SOUND_OFF; - -} - -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); -} - -void unhide_mouse(Display *display) -{ - if(mouse_installed) show_mouse(video_bitmap); -} - -int get_joystick_state() -{ - int state = 0; - poll_joystick(); - - if (joy[joystick_nr].stick[0].axis[0].d1) state |= JOY_LEFT; - if (joy[joystick_nr].stick[0].axis[0].d2) state |= JOY_RIGHT; - if (joy[joystick_nr].stick[0].axis[1].d1) state |= JOY_UP; - if (joy[joystick_nr].stick[0].axis[1].d2) state |= JOY_DOWN; - if (joy[joystick_nr].button[0].b) state |= JOY_BUTTON_1; - - switch (state) - { - case (JOY_DOWN | JOY_LEFT): - state = XK_KP_1; - break; - case (JOY_DOWN): - state = XK_KP_2; - break; - case (JOY_DOWN | JOY_RIGHT): - state = XK_KP_3; - break; - case (JOY_LEFT): - state = XK_KP_4; - break; - case (JOY_RIGHT): - state = XK_KP_6; - break; - case (JOY_UP | JOY_LEFT): - state = XK_KP_7; - break; - case (JOY_UP): - state = XK_KP_8; - break; - case (JOY_UP | JOY_RIGHT): - state = XK_KP_9; - break; - - case (JOY_DOWN | JOY_BUTTON_1): - state = XK_X; - break; - case (JOY_LEFT | JOY_BUTTON_1): - state = XK_S; - break; - case (JOY_RIGHT | JOY_BUTTON_1): - state = XK_D; - break; - case (JOY_UP | JOY_BUTTON_1): - state = XK_E; - break; - - default: - state = 0; - } - - return(state); -} - -unsigned char get_ascii(KeySym key) -{ - switch(key) { - - case OSD_KEY_Q: return 'Q'; - case OSD_KEY_W: return 'W'; - case OSD_KEY_E: return 'E'; - case OSD_KEY_R: return 'R'; - case OSD_KEY_T: return 'T'; - case OSD_KEY_Y: return 'Y'; - case OSD_KEY_U: return 'U'; - case OSD_KEY_I: return 'I'; - case OSD_KEY_O: return 'O'; - case OSD_KEY_P: return 'P'; - case OSD_KEY_A: return 'A'; - case OSD_KEY_S: return 'S'; - case OSD_KEY_D: return 'D'; - case OSD_KEY_F: return 'F'; - case OSD_KEY_G: return 'G'; - case OSD_KEY_H: return 'H'; - case OSD_KEY_J: return 'J'; - case OSD_KEY_K: return 'K'; - case OSD_KEY_L: return 'L'; - case OSD_KEY_Z: return 'Z'; - case OSD_KEY_X: return 'X'; - case OSD_KEY_C: return 'C'; - case OSD_KEY_V: return 'V'; - case OSD_KEY_B: return 'B'; - case OSD_KEY_N: return 'N'; - case OSD_KEY_M: return 'M'; - case OSD_KEY_1: return '1'; - case OSD_KEY_2: return '2'; - case OSD_KEY_3: return '3'; - case OSD_KEY_4: return '4'; - case OSD_KEY_5: return '5'; - case OSD_KEY_6: return '6'; - case OSD_KEY_7: return '7'; - case OSD_KEY_8: return '8'; - case OSD_KEY_9: return '9'; - case OSD_KEY_0: return '0'; - case OSD_KEY_SPACE: return ' '; - } - return (0); -} - -long osd_key_pressed(int keycode) -{ - if (keycode == OSD_KEY_RCONTROL) keycode = KEY_RCONTROL; - if (keycode == OSD_KEY_ALTGR) keycode = KEY_ALTGR; - - if (key[keycode]) - return(KeyPressMask); - else - return(KeyReleaseMask); -} - -void XMapWindow(Display* display, Window w) -{ - 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 *)w, video_bitmap, 0, 0, x, y, width, height); - if(mouse_off) unhide_mouse(display); -} - -Display *XOpenDisplay(char* dummy) -{ - Screen *MyScreens; - Display *MyDisplay; - BITMAP *MyMouse = NULL; - RGB pal[256]; - - MyScreens = malloc(sizeof(Screen)); - MyDisplay = malloc(sizeof(Display)); - - if(MOUSE_FILENAME) - MyMouse = load_gif(MOUSE_FILENAME, pal); - - MyScreens[0].cmap = 0; - MyScreens[0].root = 0; - MyScreens[0].white_pixel = 0xFF; - MyScreens[0].black_pixel = 0x00; - MyScreens[0].video_bitmap = NULL; - - MyDisplay->default_screen = 0; - MyDisplay->screens = MyScreens; - MyDisplay->mouse_ptr = MyMouse; - - allegro_init(); - allegro_drivers(); - set_color_depth(8); - set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); // force Windows 95 to switch to fullscreen mode - rest(200); - set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0); - - return(MyDisplay); -} - -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); - 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); -} - -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 *bmp; - RGB pal[256]; - - if((bmp = load_gif(filename, pal)) == NULL) - return(BitmapOpenFailed); - - *width_return = bmp->w; - *height_return = bmp->h; - *x_hot_return = -1; - *y_hot_return = -1; - *bitmap_return = (Pixmap) bmp; - - return(BitmapSuccess); -} - -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 XFillRectangle( - Display* display, - Drawable d, - GC gc, - int x, - int y, - unsigned int width, - unsigned int height) -{ - boolean mouse_off; - - 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, y+height, ((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 *MyBitmap = NULL; - - if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE) - MyBitmap = create_video_bitmap(width, height); - - if(MyBitmap == NULL) - MyBitmap = create_bitmap(width, height); - - return((Pixmap) MyBitmap); -} - -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; - - 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; -} - -int XpmReadFileToPixmap( - Display* display, - Drawable d, - char* filename, - Pixmap* pixmap_return, - Pixmap* shapemask_return, - XpmAttributes* attributes) -{ - BITMAP *bmp; - RGB pal[256]; - - if((bmp = load_gif(filename, pal)) == NULL) - return(XpmOpenFailed); - - *pixmap_return = (Pixmap) bmp; - set_pallete(pal); - - return(XpmSuccess); -} - -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 * bmp; - bmp = video_bitmap; - - if(is_screen_bitmap(bmp)) - destroy_bitmap(bmp); - if(display->screens) - free(display->screens); - if(display) - free(display); -} - -void XNextEvent(Display* display, XEvent* event_return) -{ - while(!pending_events) XPending(display); - - memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent)); - pending_events--; -} - -int XPending(Display* display) -{ - int i, state; - static boolean joy_button_2 = FALSE; - - XKeyEvent *xkey; - XButtonEvent *xbutton; - XMotionEvent *xmotion; - - // joystick event (simulating keyboard event) - - state = get_joystick_state(); - - if (joy[joystick_nr].button[1].b && !joy_button_2) - { - pending_events++; - xkey = (XKeyEvent *) &event_buffer[pending_events]; - xkey->type = KeyPress; - xkey->state = XK_B; - joy_button_2 = TRUE; - } - else if (!joy[joystick_nr].button[1].b && joy_button_2) - { - pending_events++; - xkey = (XKeyEvent *) &event_buffer[pending_events]; - xkey->type = KeyRelease; - xkey->state = XK_B; - joy_button_2 = FALSE; - } - - if(state && !joystick_event) - { - pending_events++; - xkey = (XKeyEvent *) &event_buffer[pending_events]; - xkey->type = KeyPress; - xkey->state = state; - joystick_event = TRUE; - last_joystick_state = state; - } - else if((state != last_joystick_state) && joystick_event) - { - pending_events++; - xkey = (XKeyEvent *) &event_buffer[pending_events]; - xkey->type = KeyRelease; - xkey->state = last_joystick_state; - joystick_event = FALSE; - } - - // keyboard event - - for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++) - { - state = osd_key_pressed(i); - - if(state != key_buffer[i]) - { - key_buffer[i] = state; - pending_events++; - xkey = (XKeyEvent *) &event_buffer[pending_events]; - xkey->type = state&KeyPressMask ? KeyPress : KeyRelease; - xkey->state = i; - } - } - - // mouse motion event - - if((mouse_pos != last_mouse_pos && mouse_b != last_mouse_b)) - { - 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; - return; - } - - // mouse button event - - if(mouse_b != last_mouse_b) - { - for(i = 1; i<4; i<<=1) - { - if((last_mouse_b&i) != (mouse_b&i)) - { - pending_events++; - xbutton = (XButtonEvent *) &event_buffer[pending_events]; - xbutton->type = mouse_b&i ? ButtonPress : ButtonRelease; - xbutton->button = 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); -} - -void sound_handler(struct SoundControl snd_ctrl) -{ - int i; - - if (snd_ctrl.fade_sound) - { - if (!playing_sounds) - return; - - for(i=0;i 8) { - if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; } - entire = (pack_getc(f) << 8) + entire; - data_pos ++; - } - if(bit_pos + curr_bit_size > 16) { - if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; } - entire = (pack_getc(f) << 16) + entire; - data_pos ++; - } - code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1); - if(bit_pos + curr_bit_size > 8) - entire >>= 8; - if(bit_pos + curr_bit_size > 16) - entire >>= 8; - bit_pos = (bit_pos + curr_bit_size) % 8; - if(bit_pos == 0) { - if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; } - entire = pack_getc(f); - data_pos ++; - } -} - - -void get_string(int num) -{ - if(num < cc) - { - string_length = 1; - string[0] = str[num].new; - } - else - { - i = str[num].length; - string_length = i; - while(i > 0) - { - i --; - string[i] = str[num].new; - num = str[num].base; - } - /* if(num != -1) **-{[ERROR]}-** */ - } -} - - -void output_string(void) -{ - for(i = 0; i < string_length; i ++) - { - putpixel(bmp, x, y, string[i]); - x ++; - if(x >= image_x + image_w) - { - x = image_x; - y += interlace; - if(interlace) - { - if(y >= image_y + image_h) - { - if(interlace == 8 && (y - image_y) % 8 == 0) { - interlace = 8; - y = image_y + 4; - } - else if(interlace == 8 && (y - image_y) % 8 == 4) { - interlace = 4; - y = image_y + 2; - } - else if(interlace == 4) { - interlace = 2; - y = image_y + 1; - } - } - } - } - } -} - -/* load_gif: - * Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap - * structure and storing the pallete data in the specified pallete (this - * should be an array of at least 256 RGB structures). - */ -BITMAP *load_gif(char *filename, RGB *pal) -{ - int width, height, depth; - int old; - BITMAP *bmp2; - int dest_depth; - - f = pack_fopen(filename, F_READ); - if (!f) /* can't open file */ - return NULL; - - i = pack_mgetw(f) << 8; - i += pack_getc(f); - if(i != 0x474946) /* is it really a GIF? */ - { - pack_fclose(f); - return NULL; - } - pack_fseek(f, 3); /* skip version */ - - width = pack_igetw(f); - height = pack_igetw(f); - - bmp = create_bitmap_ex(8, width, height); - if(bmp == NULL) { - pack_fclose(f); - return NULL; - } - clear(bmp); - - i = pack_getc(f); - if(i & 128) /* no global colour table? */ - depth = (i & 7) + 1; - else - depth = 0; - - pack_fseek(f, 2); /* skip background colour and aspect ratio */ - - if(pal && depth) /* only read palette if pal and depth are not 0 */ - { - for(i = 0; i < (1 << depth); i ++) - { - pal[i].r = pack_getc(f) / 4; - pal[i].g = pack_getc(f) / 4; - pal[i].b = pack_getc(f) / 4; - } - } - else - if(depth) - pack_fseek(f, (1 << depth) * 3); - - do - { - i = pack_getc(f); - switch(i) - { - case 0x2C: /* Image Descriptor */ - image_x = pack_igetw(f); - image_y = pack_igetw(f); /* individual image dimensions */ - image_w = pack_igetw(f); - image_h = pack_igetw(f); - - i = pack_getc(f); - if(i & 64) - interlace = 8; - else - interlace = 1; - - if(i & 128) - { - depth = (i & 7) + 1; - if(pal) - { - for(i = 0; i < (1 << depth); i ++) - { - pal[i].r = pack_getc(f) / 4; - pal[i].g = pack_getc(f) / 4; - pal[i].b = pack_getc(f) / 4; - } - } - else - pack_fseek(f, (1 << depth) * 3); - } - - /* lzw stream starts now */ - bit_size = pack_getc(f); - cc = 1 << bit_size; - - /* initialise string table */ - for(i = 0; i < cc; i ++) - { - str[i].base = -1; - str[i].new = i; - str[i].length = 1; - } - - /* initialise the variables */ - bit_pos = 0; - data_len = pack_getc(f); data_pos = 0; - entire = pack_getc(f); data_pos ++; - string_length = 0; x = image_x; y = image_y; - - /* starting code */ - clear_table(); - get_code(); - if(code == cc) - get_code(); - get_string(code); - output_string(); - old = code; - - while(TRUE) - { - get_code(); - - if(code == cc) - { - /* starting code */ - clear_table(); - get_code(); - get_string(code); - output_string(); - old = code; - } - else if(code == cc + 1) - { - break; - } - else if(code < empty_string) - { - get_string(code); - output_string(); - - if(bit_overflow == 0) { - str[empty_string].base = old; - str[empty_string].new = string[0]; - str[empty_string].length = str[old].length + 1; - empty_string ++; - if(empty_string == (1 << curr_bit_size)) - curr_bit_size ++; - if(curr_bit_size == 13) { - curr_bit_size = 12; - bit_overflow = 1; - } - } - - old = code; - } - else - { - get_string(old); - string[str[old].length] = string[0]; - string_length ++; - - if(bit_overflow == 0) { - str[empty_string].base = old; - str[empty_string].new = string[0]; - str[empty_string].length = str[old].length + 1; - empty_string ++; - if(empty_string == (1 << curr_bit_size)) - curr_bit_size ++; - if(curr_bit_size == 13) { - curr_bit_size = 12; - bit_overflow = 1; - } - } - - output_string(); - old = code; - } - } - break; - case 0x21: /* Extension Introducer */ - i = pack_getc(f); - if(i == 0xF9) /* Graphic Control Extension */ - { - pack_fseek(f, 1); /* skip size (it's 4) */ - i = pack_getc(f); - if(i & 1) /* is transparency enabled? */ - { - pack_fseek(f, 2); - pack_getc(f); /* transparent colour */ - } - else - pack_fseek(f, 3); - } - i = pack_getc(f); - while(i) /* skip Data Sub-blocks */ - { - pack_fseek(f, i); - i = pack_getc(f); - } - break; - case 0x3B: /* Trailer - end of data */ - pack_fclose(f); - - /* convert to correct colour depth */ - dest_depth = _color_load_depth(8); - - if (dest_depth != 8) - { - bmp2 = create_bitmap_ex(dest_depth, bmp->w, bmp->h); - if (!bmp2) - { - destroy_bitmap(bmp); - return NULL; - } - - select_palette(pal); - blit(bmp, bmp2, 0, 0, 0, 0, bmp->w, bmp->h); - unselect_palette(); - - destroy_bitmap(bmp); - bmp = bmp2; - } - - return bmp; - } - } while(TRUE); - - /* this is never executed but DJGPP complains if you leave it out */ - return NULL; -} - -#endif diff --git a/src/msdos.h b/src/msdos.h deleted file mode 100644 index f4f7a5ad..00000000 --- a/src/msdos.h +++ /dev/null @@ -1,477 +0,0 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * -*----------------------------------------------------------* -* msdos.h * -***********************************************************/ - -#ifndef XPM_INCLUDE_FILE -#define XPM_INCLUDE_FILE -#endif - -#define XRES 800 -#define YRES 600 - -#define TRUE 1 -#define FALSE 0 - -#include -#include - -/* some file path definitions */ - -#define JOYDAT_PATH GAME_DIR -#define JOYDAT_FILENAME "ROCKS.joy" -#define JOYDAT_FILE JOYDAT_PATH "/" JOYDAT_FILENAME - -/* Allegro keyboard mapping */ - -#define OSD_KEY_ESC 1 /* keyboard scan codes */ -#define OSD_KEY_1 2 /* (courtesy of allegro.h) */ -#define OSD_KEY_2 3 -#define OSD_KEY_3 4 -#define OSD_KEY_4 5 -#define OSD_KEY_5 6 -#define OSD_KEY_6 7 -#define OSD_KEY_7 8 -#define OSD_KEY_8 9 -#define OSD_KEY_9 10 -#define OSD_KEY_0 11 -#define OSD_KEY_MINUS 12 -#define OSD_KEY_EQUALS 13 -#define OSD_KEY_BACKSPACE 14 -#define OSD_KEY_TAB 15 -#define OSD_KEY_Q 16 -#define OSD_KEY_W 17 -#define OSD_KEY_E 18 -#define OSD_KEY_R 19 -#define OSD_KEY_T 20 -#define OSD_KEY_Y 21 -#define OSD_KEY_U 22 -#define OSD_KEY_I 23 -#define OSD_KEY_O 24 -#define OSD_KEY_P 25 -#define OSD_KEY_OPENBRACE 26 -#define OSD_KEY_CLOSEBRACE 27 -#define OSD_KEY_ENTER 28 -#define OSD_KEY_LCONTROL 29 -#define OSD_KEY_A 30 -#define OSD_KEY_S 31 -#define OSD_KEY_D 32 -#define OSD_KEY_F 33 -#define OSD_KEY_G 34 -#define OSD_KEY_H 35 -#define OSD_KEY_J 36 -#define OSD_KEY_K 37 -#define OSD_KEY_L 38 -#define OSD_KEY_COLON 39 -#define OSD_KEY_QUOTE 40 -#define OSD_KEY_TILDE 41 -#define OSD_KEY_LSHIFT 42 -/* 43 */ -#define OSD_KEY_Z 44 -#define OSD_KEY_X 45 -#define OSD_KEY_C 46 -#define OSD_KEY_V 47 -#define OSD_KEY_B 48 -#define OSD_KEY_N 49 -#define OSD_KEY_M 50 -#define OSD_KEY_COMMA 51 -#define OSD_KEY_STOP 52 -#define OSD_KEY_SLASH 53 -#define OSD_KEY_RSHIFT 54 -#define OSD_KEY_ASTERISK 55 -#define OSD_KEY_ALT 56 -#define OSD_KEY_SPACE 57 -#define OSD_KEY_CAPSLOCK 58 -#define OSD_KEY_F1 59 -#define OSD_KEY_F2 60 -#define OSD_KEY_F3 61 -#define OSD_KEY_F4 62 -#define OSD_KEY_F5 63 -#define OSD_KEY_F6 64 -#define OSD_KEY_F7 65 -#define OSD_KEY_F8 66 -#define OSD_KEY_F9 67 -#define OSD_KEY_F10 68 -#define OSD_KEY_NUMLOCK 69 -#define OSD_KEY_SCRLOCK 70 -#define OSD_KEY_HOME 71 -#define OSD_KEY_UP 72 -#define OSD_KEY_PGUP 73 -#define OSD_KEY_MINUS_PAD 74 -#define OSD_KEY_LEFT 75 -#define OSD_KEY_5_PAD 76 -#define OSD_KEY_RIGHT 77 -#define OSD_KEY_PLUS_PAD 78 -#define OSD_KEY_END 79 -#define OSD_KEY_DOWN 80 -#define OSD_KEY_PGDN 81 -#define OSD_KEY_INSERT 82 -#define OSD_KEY_DEL 83 -#define OSD_KEY_RCONTROL 84 /* different from Allegro */ -#define OSD_KEY_ALTGR 85 /* different from Allegro */ -/* 86 */ -#define OSD_KEY_F11 87 -#define OSD_KEY_F12 88 -#define OSD_KEY_COMMAND 89 -#define OSD_KEY_OPTION 90 -/* 91 - 100 */ -/* The following are all undefined in Allegro */ -#define OSD_KEY_1_PAD 101 -#define OSD_KEY_2_PAD 102 -#define OSD_KEY_3_PAD 103 -#define OSD_KEY_4_PAD 104 -/* 105 */ -#define OSD_KEY_6_PAD 106 -#define OSD_KEY_7_PAD 107 -#define OSD_KEY_8_PAD 108 -#define OSD_KEY_9_PAD 109 -#define OSD_KEY_0_PAD 110 -#define OSD_KEY_STOP_PAD 111 -#define OSD_KEY_EQUALS_PAD 112 -#define OSD_KEY_SLASH_PAD 113 -#define OSD_KEY_ASTER_PAD 114 -#define OSD_KEY_ENTER_PAD 115 - -#define OSD_MAX_KEY 115 - -/* X11 keyboard mapping */ - -#define XK_KP_Enter OSD_KEY_ENTER_PAD -#define XK_KP_0 OSD_KEY_0_PAD -#define XK_KP_1 OSD_KEY_1_PAD -#define XK_KP_2 OSD_KEY_2_PAD -#define XK_KP_3 OSD_KEY_3_PAD -#define XK_KP_4 OSD_KEY_4_PAD -#define XK_KP_6 OSD_KEY_6_PAD -#define XK_KP_7 OSD_KEY_7_PAD -#define XK_KP_8 OSD_KEY_8_PAD -#define XK_KP_9 OSD_KEY_9_PAD -/* -#define XK_KP_Home OSD_KEY_7_PAD -#define XK_KP_Page_Up OSD_KEY_9_PAD -#define XK_KP_Page_Down OSD_KEY_3_PAD -#define XK_KP_End OSD_KEY_1_PAD -#define XK_KP_Left OSD_KEY_4_PAD -#define XK_KP_Up OSD_KEY_8_PAD -#define XK_KP_Right OSD_KEY_6_PAD -#define XK_KP_Down OSD_KEY_2_PAD -*/ -#define XK_0 OSD_KEY_1 -#define XK_1 OSD_KEY_2 -#define XK_2 OSD_KEY_3 -#define XK_3 OSD_KEY_4 -#define XK_4 OSD_KEY_5 -#define XK_5 OSD_KEY_6 -#define XK_6 OSD_KEY_7 -#define XK_7 OSD_KEY_8 -#define XK_8 OSD_KEY_9 -#define XK_9 OSD_KEY_0 -#define XK_A OSD_KEY_A -#define XK_B OSD_KEY_B -#define XK_C OSD_KEY_C -#define XK_D OSD_KEY_D -#define XK_E OSD_KEY_E -#define XK_F OSD_KEY_F -#define XK_G OSD_KEY_G -#define XK_H OSD_KEY_H -#define XK_I OSD_KEY_I -#define XK_J OSD_KEY_J -#define XK_K OSD_KEY_K -#define XK_L OSD_KEY_L -#define XK_M OSD_KEY_M -#define XK_N OSD_KEY_N -#define XK_O OSD_KEY_O -#define XK_P OSD_KEY_P -#define XK_Q OSD_KEY_Q -#define XK_R OSD_KEY_R -#define XK_S OSD_KEY_S -#define XK_T OSD_KEY_T -#define XK_U OSD_KEY_U -#define XK_V OSD_KEY_V -#define XK_W OSD_KEY_W -#define XK_X OSD_KEY_X -#define XK_Y OSD_KEY_Y -#define XK_Z OSD_KEY_Z -#define XK_a OSD_KEY_A -#define XK_b OSD_KEY_B -#define XK_c OSD_KEY_C -#define XK_d OSD_KEY_D -#define XK_e OSD_KEY_E -#define XK_f OSD_KEY_F -#define XK_g OSD_KEY_G -#define XK_h OSD_KEY_H -#define XK_i OSD_KEY_I -#define XK_j OSD_KEY_J -#define XK_k OSD_KEY_K -#define XK_l OSD_KEY_L -#define XK_m OSD_KEY_M -#define XK_n OSD_KEY_N -#define XK_o OSD_KEY_O -#define XK_p OSD_KEY_P -#define XK_q OSD_KEY_Q -#define XK_r OSD_KEY_R -#define XK_s OSD_KEY_S -#define XK_t OSD_KEY_T -#define XK_u OSD_KEY_U -#define XK_v OSD_KEY_V -#define XK_w OSD_KEY_W -#define XK_x OSD_KEY_X -#define XK_y OSD_KEY_Y -#define XK_z OSD_KEY_Z -#define XK_Return OSD_KEY_ENTER -#define XK_Escape OSD_KEY_ESC -#define XK_Shift_L OSD_KEY_LSHIFT -#define XK_Shift_R OSD_KEY_RSHIFT -#define XK_Left OSD_KEY_LEFT -#define XK_Up OSD_KEY_UP -#define XK_Right OSD_KEY_RIGHT -#define XK_Down OSD_KEY_DOWN -#define XK_BackSpace OSD_KEY_BACKSPACE -#define XK_Delete OSD_KEY_DEL -#define XK_Space OSD_KEY_SPACE -#define XK_F12 OSD_KEY_F12 -#define XK_F11 OSD_KEY_F11 -#define XK_F10 OSD_KEY_F10 - -#define MOUSE_FILENAME "graphics\\mouse.gif" -#define screen myscreen - -#define XFlush(a) -#define XSync(a,b) -#define XSetClipOrigin(a,b,c,d) -#define XGetImage(a,b,c,d,e,f,g,h) ((XImage *) NULL) -#define XAutoRepeatOn(a) -#define XAutoRepeatOff(a) -#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 Status int -#define Bool int -#define True 1 -#define False 0 - -#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 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 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 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 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; - unsigned long black_pixel; /* White and Black pixel values */ - 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; /* origin for clipping */ - int clip_y_origin; - 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 union _XEvent { - int type; /* must not be changed; first element */ - XExposeEvent xexpose; - XButtonEvent xbutton; - XMotionEvent xmotion; - XKeyEvent xkey; -} XEvent; - - -extern void XMapWindow(Display*, Window); -// extern void XFlush(Display*); -extern Display *XOpenDisplay(char*); -// extern char *XDisplayName(char*); -extern Window XCreateSimpleWindow(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); -extern int XReadBitmapFile(Display*, Drawable, char*, unsigned int*, unsigned int*, Pixmap*, int*, int*); -extern Status XStringListToTextProperty(char**, int, XTextProperty*); -// extern void XSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -extern void XFree(void*); -// extern void XSelectInput(Display*, Window, long); -extern GC XCreateGC(Display*, Drawable, unsigned long, XGCValues*); -extern void XFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int); -extern Pixmap XCreatePixmap(Display*, Drawable, unsigned int, unsigned int, unsigned int); -// extern int XDefaultDepth(Display*, int); -extern inline void XCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -extern int XpmReadFileToPixmap(Display*, Drawable, char*, Pixmap*, Pixmap*, XpmAttributes*); -// extern void XFreeColors(Display*, Colormap, unsigned long*, int, unsigned long); -// extern void XpmFreeAttributes(XpmAttributes*); -extern void XFreePixmap(Display*, Pixmap); -extern void XFreeGC(Display*, GC); -extern void XCloseDisplay(Display*); -extern int XPending(Display*); -extern void XNextEvent(Display*, XEvent*); -// extern void XSync(Display*, Bool); -// extern void XAutoRepeatOn(Display*); -// extern void XAutoRepeatOff(Display*); -extern KeySym XLookupKeysym(XKeyEvent*, int); -// extern void XSetClipOrigin(Display*, GC, int, int); -// extern XImage *XGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); - -BITMAP *load_gif(char *filename, RGB *pal); diff --git a/src/netserv.c b/src/netserv.c new file mode 100644 index 00000000..6ff6e52e --- /dev/null +++ b/src/netserv.c @@ -0,0 +1,904 @@ +/* + * A server for a multi-player version of Tetris + * + * Copyright (C) 1996 Roger Espel Llima + * + * Started: 10 Oct 1996 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. See the file COPYING for details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netserv.h" +#include "misc.h" + +static int clients = 0; +static int bots = 0; +static int onceonly = 0; +static int timetoplay = 0; +static int is_daemon = 0; +static int levelnr = 5; +static int mode = -1; +static int paused = 0; + +struct user +{ + int fd; + unsigned char nick[16]; + unsigned char number; + struct user *next, *nextvictim; + char active; + char introduced; + unsigned char readbuf[MAX_BUFFER_SIZE]; + int nread; + unsigned char writbuf[MAX_BUFFER_SIZE]; + int nwrite; + char playing; + char isbot; + int lines; + unsigned int games; + unsigned char action; + int action_received; +}; + +static struct user *user0 = NULL; + +#define NEXT(u) ((u)->next ? (u)->next : user0) + +static struct sockaddr_in saddr; +static int lfd; +static unsigned char realbuf[512], *buf = realbuf + 4; + +static int interrupt; +static int tcp = -1; + +static unsigned long frame_counter = 0; + +static fd_set fds; + +static void syserr(char *s) +{ + if (!is_daemon) + fprintf(stderr, "fatal: %s failed.\n", s); + exit(1); +} + +static void addtobuffer(struct user *u, unsigned char *b, int len) +{ + if (u->nwrite + len >= MAX_BUFFER_SIZE) + Error(ERR_EXIT, "internal error: network send buffer overflow"); + + memcpy(u->writbuf + u->nwrite, b, len); + u->nwrite += len; +} + +static void flushuser(struct user *u) +{ + if (u->nwrite) + { + write(u->fd, u->writbuf, u->nwrite); + u->nwrite = 0; + } +} + +static void broadcast(struct user *except, int len, int activeonly) +{ + struct user *u; + + realbuf[0] = realbuf[1] = realbuf[2] = 0; + realbuf[3] = (unsigned char)len; + for (u=user0; u; u=u->next) + if (u != except && (u->active || !activeonly) && u->introduced) + addtobuffer(u, realbuf, 4 + len); +} + +static void sendtoone(struct user *to, int len) +{ + realbuf[0] = realbuf[1] = realbuf[2] = 0; + realbuf[3] = (unsigned char)len; + addtobuffer(to, realbuf, 4 + len); +} + +static void dropuser(struct user *u) +{ + struct user *v, *w; + + if (options.verbose) + printf("RND_SERVER: dropping client %d (%s)\n", u->number, u->nick); + + if (u == user0) + user0 = u->next; + else + { + for (v=user0; v; v=v->next) + { + if (v->next && v->next == u) + { + v->next = u->next; + break; + } + } + } + close(u->fd); + + if (u->introduced) + { + buf[0] = u->number; + buf[1] = OP_PLAYER_DISCONNECTED; + broadcast(u, 2, 0); + } + + for (v=user0; v; v=v->next) + { + if (v->nextvictim == u) + { + for (w=NEXT(v); w!=v; w=NEXT(w)) + { + if (w->active && w->playing) + { + v->nextvictim = w; + break; + } + } + if (v->nextvictim == u) + v->nextvictim = NULL; + } + } + + if (u->isbot) + bots--; + + free(u); + clients--; + + if (onceonly && clients == bots) + { + if (options.verbose) + { + printf("RND_SERVER: no clients left\n"); + printf("RND_SERVER: aborting\n"); + } + exit(0); + } + + if (clients == 0) + { + mode = -1; + levelnr = 5; + timetoplay = 0; + } +} + +static void new_connect(int fd) +{ + struct user *u, *v; + unsigned char nxn; + + u = checked_malloc(sizeof (struct user)); + + u->fd = fd; + u->nick[0] = 0; + u->next = user0; + u->nextvictim = NULL; + u->active = 0; + u->nread = 0; + u->nwrite = 0; + u->playing = 0; + u->isbot = 0; + u->introduced = 0; + u->games = 0; + u->action = 0; + u->action_received = 0; + + user0 = u; + + nxn = 1; + + again: + v = u->next; + while(v) + { + if (v->number == nxn) + { + nxn++; + goto again; + } + v = v->next; + } + + u->number = nxn; + if (options.verbose) + printf("RND_SERVER: client %d connecting from %s\n", nxn, inet_ntoa(saddr.sin_addr)); + clients++; + + buf[0] = 0; + buf[1] = OP_YOUR_NUMBER; + buf[2] = u->number; + sendtoone(u, 3); +} + +static void Handle_OP_PROTOCOL_VERSION(struct user *u, unsigned int len) +{ + if (len != 5 || buf[2] != PROT_VERS_1 || buf[3] != PROT_VERS_2) + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) has wrong protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]); + + buf[0] = 0; + buf[1] = OP_BADVERS; + buf[2] = PROT_VERS_1; + buf[3] = PROT_VERS_2; + buf[4] = PROT_VERS_3; + sendtoone(u, 5); + flushuser(u); + + dropuser(u); + interrupt = 1; + } + else + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) uses protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]); + } +} + +static void Handle_OP_NUMBER_WANTED(struct user *u) +{ + struct user *v; + int client_nr = u->number; + int nr_wanted = buf[2]; + int nr_is_free = 1; + + if (options.verbose) + printf("RND_SERVER: client %d (%s) wants to switch to # %d\n", + u->number, u->nick, nr_wanted); + + for (v=user0; v; v=v->next) + { + if (v->number == nr_wanted) + { + nr_is_free = 0; + break; + } + } + + if (options.verbose) + { + if (nr_is_free) + printf("RND_SERVER: client %d (%s) switches to # %d\n", + u->number, u->nick, nr_wanted); + else if (u->number == nr_wanted) + printf("RND_SERVER: client %d (%s) still has # %d\n", + u->number, u->nick, nr_wanted); + else + printf("RND_SERVER: client %d (%s) cannot switch (client %d still exists)\n", + u->number, u->nick, nr_wanted); + } + + if (nr_is_free) + u->number = nr_wanted; + + buf[0] = client_nr; + buf[1] = OP_NUMBER_WANTED; + buf[2] = nr_wanted; + buf[3] = u->number; + + /* + sendtoone(u, 4); + */ + + broadcast(NULL, 4, 0); +} + +static void Handle_OP_NICKNAME(struct user *u, unsigned int len) +{ + struct user *v; + int i; + + if (len>16) + len=16; + memcpy(u->nick, &buf[2], len-2); + u->nick[len-2] = 0; + for (i=0; inick[i] < ' ' || + (u->nick[i] > 0x7e && u->nick[i] <= 0xa0)) + { + u->nick[i] = 0; + break; + } + } + + if (!u->introduced) + { + buf[0] = u->number; + buf[1] = OP_PLAYER_CONNECTED; + broadcast(u, 2, 0); + } + + if (options.verbose) + printf("RND_SERVER: client %d calls itself \"%s\"\n", u->number, u->nick); + buf[1] = OP_NICKNAME; + broadcast(u, len, 0); + + if (!u->introduced) + { + for (v=user0; v; v=v->next) + { + if (v != u && v->introduced) + { + buf[0] = v->number; + buf[1] = OP_PLAYER_CONNECTED; + buf[2] = (v->games >> 8); + buf[3] = (v->games & 0xff); + sendtoone(u, 4); + buf[1] = OP_NICKNAME; + memcpy(&buf[2], v->nick, 14); + sendtoone(u, 2+strlen(v->nick)); + } + } + if (levelnr != 5) + { + buf[0] = 0; + buf[1] = OP_LEVEL; + buf[2] = levelnr; + sendtoone(u, 3); + } + if (mode >= 0) + { + buf[1] = OP_MODE; + buf[2] = mode; + sendtoone(u, 3); + } + } + + u->introduced = 1; +} + +static void Handle_OP_START_PLAYING(struct user *u) +{ + struct user *v, *w; + + if (options.verbose) + printf("RND_SERVER: client %d (%s) starts game [level %d from levedir %d (%s)]\n", + u->number, u->nick, + (buf[2] << 8) + buf[3], + (buf[4] << 8) + buf[5], + &buf[6]); + timetoplay = 0; + + for (w=user0; w; w=w->next) + { + if (w->introduced) + { + w->active = 1; + w->playing = 1; + w->lines = 0; + w->nextvictim = NULL; + for (v=NEXT(w); v!=w; v=NEXT(v)) + { + if (v->introduced) + { + w->nextvictim = v; + break; + } + } + } + } + + /* + if (paused) + { + paused = 0; + buf[1] = OP_CONT; + broadcast(NULL, 2, 0); + } + buf[1] = OP_START_PLAYING; + broadcast(NULL, 2, 0); + */ + + /* reset frame counter */ + frame_counter = 0; + + /* reset player actions */ + for (v=user0; v; v=v->next) + { + v->action = 0; + v->action_received = 0; + } + + broadcast(NULL, 10 + strlen(&buf[10])+1, 0); +} + +static void Handle_OP_PAUSE_PLAYING(struct user *u) +{ + if (options.verbose) + printf("RND_SERVER: client %d (%s) pauses game\n", u->number, u->nick); + broadcast(NULL, 2, 0); + paused = 1; +} + +static void Handle_OP_CONTINUE_PLAYING(struct user *u) +{ + if (options.verbose) + printf("RND_SERVER: client %d (%s) continues game\n", u->number, u->nick); + broadcast(NULL, 2, 0); + paused = 0; +} + +static void Handle_OP_STOP_PLAYING(struct user *u) +{ + if (options.verbose) + printf("RND_SERVER: client %d (%s) stops game\n", u->number, u->nick); + broadcast(NULL, 2, 0); +} + +static void Handle_OP_MOVE_FIGURE(struct user *u) +{ + struct user *v; + int last_client_nr = 0; + int i; + + /* store player action */ + for (v=user0; v; v=v->next) + { + if (v->number == u->number) + { + v->action = buf[2]; + v->action_received = 1; + } + } + + /* check if server received action from each player */ + for (v=user0; v; v=v->next) + { + if (!v->action_received) + return; + + if (v->number > last_client_nr) + last_client_nr = v->number; + } + + /* initialize all player actions to zero */ + for (i=0; inext) + { + buf[6 + v->number-1] = v->action; + v->action = 0; + v->action_received = 0; + } + + buf[2] = (unsigned char)((frame_counter >> 24) & 0xff); + buf[3] = (unsigned char)((frame_counter >> 16) & 0xff); + buf[4] = (unsigned char)((frame_counter >> 8) & 0xff); + buf[5] = (unsigned char)((frame_counter >> 0) & 0xff); + + broadcast(NULL, 6 + last_client_nr, 0); + + frame_counter++; + + /* + if (verbose) + printf("RND_SERVER: frame %d: client %d (%s) moves player [0x%02x]\n", + frame_counter, + u->number, u->nick, buf[2]); + */ +} + +void NetworkServer(int port, int serveronly) +{ + int i, sl, on; + struct user *u, *v, *w; + int mfd; + int r; + unsigned int len; + struct protoent *tcpproto; + struct timeval tv; + int is_daemon = 0; + +#ifndef NeXT + struct sigaction sact; +#endif + + if (port == 0) + port = DEFAULTPORT; + + if (!serveronly) + onceonly = 1; + + if ((tcpproto = getprotobyname("tcp")) != NULL) + tcp = tcpproto->p_proto; + +#ifdef NeXT + signal(SIGPIPE, SIG_IGN); +#else + sact.sa_handler = SIG_IGN; + sigemptyset(&sact.sa_mask); + sact.sa_flags = 0; + sigaction(SIGPIPE, &sact, NULL); +#endif + + + lfd = socket(PF_INET, SOCK_STREAM, 0); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons(port); + + if (lfd < 0) + syserr("socket"); + on = 1; + + setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(int)); + if (bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) + syserr("bind"); + + listen(lfd, 5); + + if (is_daemon) + { + /* become a daemon, breaking all ties with the controlling terminal */ + options.verbose = 0; + for (i=0; i<255; i++) + { + if (i != lfd) + close(i); + } + + if (fork()) + exit(0); + setsid(); + if (fork()) + exit(0); + chdir("/"); + + /* open a fake stdin, stdout, stderr, just in case */ + open("/dev/null", O_RDONLY); + open("/dev/null", O_WRONLY); + open("/dev/null", O_WRONLY); + } + + if (options.verbose) + { + printf("rocksndiamonds network server: started up, listening on port %d\n", + port); + printf("rocksndiamonds network server: using protocol version %d.%d.%d\n", + PROT_VERS_1, PROT_VERS_2, PROT_VERS_3); + } + + while(1) + { + interrupt = 0; + + /* + if (timetoplay && time(NULL) >= timetoplay) + { + buf[0] = 0; + do_play(); + if (options.verbose) + printf("RND_SERVER: everyone lost... restarting game\n"); + timetoplay = 0; + } + */ + + for (u=user0; u; u=u->next) + flushuser(u); + + FD_ZERO(&fds); + mfd = lfd; + u = user0; + while (u) + { + FD_SET(u->fd, &fds); + if (u->fd > mfd) + mfd = u->fd; + u = u->next; + } + FD_SET(lfd, &fds); + tv.tv_sec = 0; + tv.tv_usec = 500000; + if ((sl = select(mfd + 1, &fds, NULL, NULL, &tv)) < 0) + { + if (errno != EINTR) + syserr("select"); + else + continue; + } + + if (sl < 0) + continue; + + if (clients > 0 && clients == bots) + { + if (options.verbose) + printf("RND_SERVER: only bots left... dropping all bots\n"); + while (user0) + dropuser(user0); + continue; + } + + if (sl == 0) + continue; + + if (FD_ISSET(lfd, &fds)) + { + int newfd, slen; + + slen = sizeof(saddr); + newfd = accept(lfd, (struct sockaddr *)&saddr, &slen); + if (newfd < 0) + { + if (errno != EINTR) + syserr("accept"); + } + else + { + if (tcp != -1) + { + on = 1; + setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int)); + } + new_connect(newfd); + } + continue; + } + + u = user0; + + do + { + if (FD_ISSET(u->fd, &fds)) + { + r = read(u->fd, u->readbuf + u->nread, MAX_BUFFER_SIZE - u->nread); + if (r <= 0) + { + if (options.verbose) + printf("RND_SERVER: EOF from client %d (%s)\n", u->number, u->nick); + dropuser(u); + interrupt = 1; + break; + } + u->nread += r; + while (u->nread >= 4 && u->nread >= 4 + u->readbuf[3]) + { + len = u->readbuf[3]; + if (u->readbuf[0] || u->readbuf[1] || u->readbuf[2]) + { + if (options.verbose) + printf("RND_SERVER: crap from client %d (%s)\n", u->number, u->nick); + write(u->fd, "\033]50;kanji24\007\033#8\033(0", 19); + dropuser(u); + interrupt = 1; + break; + } + memcpy(buf, &u->readbuf[4], len); + u->nread -= 4 + len; + memmove(u->readbuf, u->readbuf + 4 + len, u->nread); + + buf[0] = u->number; + if (!u->introduced && buf[1] != OP_NICKNAME) + { + if (options.verbose) + printf("RND_SERVER: !(client %d)->introduced && buf[1]==%d (expected OP_NICKNAME)\n", buf[0], buf[1]); + + dropuser(u); + interrupt = 1; + break; + } + + switch(buf[1]) + { + case OP_NICKNAME: + Handle_OP_NICKNAME(u, len); + break; + + case OP_PROTOCOL_VERSION: + Handle_OP_PROTOCOL_VERSION(u, len); + break; + + case OP_NUMBER_WANTED: + Handle_OP_NUMBER_WANTED(u); + break; + + case OP_START_PLAYING: + Handle_OP_START_PLAYING(u); + break; + + case OP_PAUSE_PLAYING: + Handle_OP_PAUSE_PLAYING(u); + break; + + case OP_CONTINUE_PLAYING: + Handle_OP_CONTINUE_PLAYING(u); + break; + + case OP_STOP_PLAYING: + Handle_OP_STOP_PLAYING(u); + break; + + case OP_MOVE_FIGURE: + Handle_OP_MOVE_FIGURE(u); + break; + + case OP_KILL: + for (v=user0; v; v=v->next) + { + if (v->number == buf[2]) + break; + } + if (v) + { + if (v->isbot) + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) kills bot %d (%s)\n", u->number, u->nick, v->number, v->nick); + + dropuser(v); + interrupt = 1; + break; + } + else + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) attempting to kill non-bot %d (%s)\n", u->number, u->nick, v->number, v->nick); + } + } + break; + + case OP_MODE: + mode = buf[2]; + if (options.verbose) + printf("RND_SERVER: client %d (%s) sets mode %d (%s)\n", u->number, u->nick, buf[2], buf[2] == 0 ? "normal" : (buf[2] == 1 ? "fun" : "unknown")); + broadcast(NULL, 3, 0); + break; + + case OP_BOT: + if (!u->isbot) + bots++; + u->isbot = 1; + if (options.verbose) + printf("RND_SERVER: client %d (%s) declares itself to be a bot\n", u->number, u->nick); + break; + + case OP_LEVEL: + levelnr = buf[2]; + if (options.verbose) + printf("RND_SERVER: client %d (%s) sets level %d\n", u->number, u->nick, buf[2]); + broadcast(NULL, 3, 0); + break; + + case OP_LOST: + { + struct user *won = NULL; + + if (options.verbose) + printf("RND_SERVER: client %d (%s) has lost\n", u->number, u->nick); + u->playing = 0; + broadcast(u, 2, 1); + i = 0; + for (v=user0; v; v=v->next) + { + if (v->nextvictim == u) + { + for (w=NEXT(v); w!=v; w=NEXT(w)) + { + if (w->active && w->playing) + { + v->nextvictim = w; + break; + } + } + if (v->nextvictim == u) + v->nextvictim = NULL; + } + } + for (v=user0; v; v=v->next) + { + if (v->playing) + { + i++; + won = v; + } + } + if (i == 1) + { + buf[0] = won->number; + buf[1] = OP_WON; + won->games++; + broadcast(NULL, 2, 0); + } + else if (i == 0) + { + buf[0] = u->number; + buf[1] = OP_WON; + u->games++; + broadcast(NULL, 2, 0); + } + if (i < 2 && clients > 1) + timetoplay = time(NULL) + 4; + } + break; + + case OP_ZERO: + broadcast(NULL, 2, 0); + if (options.verbose) + printf("RND_SERVER: client %d (%s) resets the game counters\n", u->number, u->nick); + for (v=user0; v; v=v->next) + v->games = 0; + break; + + case OP_CLEAR: + case OP_GROW: + broadcast(u, 2, 1); + break; + + case OP_MSG: + buf[len] = '\0'; + if (options.verbose) + printf("RND_SERVER: client %d (%s) sends message: %s\n", u->number, u->nick, &buf[2]); + broadcast(u, len, 0); + break; + + case OP_LINES: + if (len != 3) + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) sends crap for an OP_LINES\n", u->number, u->nick); + + dropuser(u); + interrupt = 1; + break; + } + if (u->nextvictim) + { + if (options.verbose) + printf("RND_SERVER: client %d (%s) sends %d %s to client %d (%s)\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines", u->nextvictim->number, u->nextvictim->nick); + sendtoone(u->nextvictim, 3); + buf[3] = u->nextvictim->number; + buf[1] = OP_LINESTO; + broadcast(u->nextvictim, 4, 1); + for (v=NEXT(u->nextvictim); v!=u->nextvictim; v=NEXT(v)) + { + if (v->active && v != u && v->playing) + { + u->nextvictim = v; + break; + } + } + } + else if (options.verbose) + printf("RND_SERVER: client %d (%s) makes %d %s but has no victim\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines"); + break; + + default: + if (options.verbose) + printf("RND_SERVER: opcode %d from client %d (%s) not understood\n", buf[0], u->number, u->nick); + } + } + } + + if (u && !interrupt) + u = u->next; + } + while (u && !interrupt); + } +} diff --git a/src/new.c b/src/new.c deleted file mode 100644 index 95926b37..00000000 --- a/src/new.c +++ /dev/null @@ -1,5 +0,0 @@ - -/* new.c */ - -#include "image.h" -#include "misc.h" diff --git a/src/send.c b/src/send.c deleted file mode 100644 index f0aeee1a..00000000 --- a/src/send.c +++ /dev/null @@ -1,890 +0,0 @@ - -/* send.c */ - -#include "xli.h" - -/* extra colors to try allocating in private color maps to minimise flashing */ -#define NOFLASH_COLORS 256 - -Image *monochrome(Image *cimage) -{ - Image *image; - unsigned char *sp, *dp, *dp2; /* data pointers */ - unsigned int spl; /* source pixel length in bytes */ - unsigned int dll; /* destination line length in bytes */ - Pixel color; /* pixel color */ - unsigned int x, y; /* random counters */ - int bitmap_pixel; - - if (BITMAPP(cimage)) - return(NULL); - - /* - printf(" Converting to monochrome..."); - fflush(stdout); - */ - - image= newBitImage(cimage->width, cimage->height); - if (cimage->title) - { - image->title= (char *)lmalloc(strlen(cimage->title) + 13); - sprintf(image->title, "%s (monochrome)", cimage->title); - } - - spl = cimage->pixlen; - dll = (image->width / 8) + (image->width % 8 ? 1 : 0); - - sp = cimage->data; - dp = image->data; - - for (y= 0; y < cimage->height; y++) - { - for (x= 0; x < cimage->width; x++) - { - dp2 = dp + (x / 8); /* dp + x/8 */ - color= memToVal(sp, spl); - - if (cimage->rgb.red[color] > 0x0000 || - cimage->rgb.green[color] > 0x0000 || - cimage->rgb.blue[color] > 0x0000) - bitmap_pixel = 0x00; - else - bitmap_pixel = 0x80; - - *dp2 |= bitmap_pixel >> ( x % 8); - sp += spl; - } - - dp += dll; /* next row */ - } - - /* - printf("done\n"); - */ - - return(image); -} - -static unsigned int *buildIndex(unsigned int width, - unsigned int zoom, - unsigned int *rwidth) -{ - float fzoom; - unsigned int *index; - unsigned int a; - - if (!zoom) - { - fzoom= 100.0; - *rwidth= width; - } - else - { - fzoom= (float)zoom / 100.0; - *rwidth= (unsigned int)(fzoom * width + 0.5); - } - index= (unsigned int *)lmalloc(sizeof(unsigned int) * *rwidth); - for (a= 0; a < *rwidth; a++) - { - if (zoom) - *(index + a)= (unsigned int)((float)a / fzoom + 0.5); - else - *(index + a)= a; - } - return(index); -} - -Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom) -{ - Image *image; - unsigned int *xindex, *yindex; - unsigned int xwidth, ywidth; - unsigned int x, y, xsrc, ysrc; - unsigned int pixlen; - unsigned int srclinelen; - unsigned int destlinelen; - byte *srcline, *srcptr; - byte *destline, *destptr; - byte srcmask, destmask, bit; - Pixel value; - - if ((!xzoom || xzoom==100) && (!yzoom || yzoom==100)) - return(oimage); - - if (!xzoom) - printf(" Zooming image Y axis by %d%%...", yzoom); - else if (!yzoom) - printf(" Zooming image X axis by %d%%...", xzoom); - else if (xzoom == yzoom) - printf(" Zooming image by %d%%...", xzoom); - else - printf(" Zooming image X axis by %d%% and Y axis by %d%%...", - xzoom, yzoom); - fflush(stdout); - - xindex= buildIndex(oimage->width, xzoom, &xwidth); - yindex= buildIndex(oimage->height, yzoom, &ywidth); - - switch (oimage->type) - { - case IBITMAP: - image= newBitImage(xwidth, ywidth); - for (x= 0; x < oimage->rgb.used; x++) - { - *(image->rgb.red + x)= *(oimage->rgb.red + x); - *(image->rgb.green + x)= *(oimage->rgb.green + x); - *(image->rgb.blue + x)= *(oimage->rgb.blue + x); - } - image->rgb.used= oimage->rgb.used; - destline= image->data; - destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0); - srcline= oimage->data; - srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0); - for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) - { - while (ysrc != *(yindex + y)) - { - ysrc++; - srcline += srclinelen; - } - srcptr= srcline; - destptr= destline; - srcmask= 0x80; - destmask= 0x80; - bit= srcmask & *srcptr; - for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) - { - if (xsrc != *(xindex + x)) - { - do - { - xsrc++; - if (!(srcmask >>= 1)) - { - srcmask= 0x80; - srcptr++; - } - } - while (xsrc != *(xindex + x)); - - bit= srcmask & *srcptr; - } - if (bit) - *destptr |= destmask; - if (!(destmask >>= 1)) - { - destmask= 0x80; - destptr++; - } - } - destline += destlinelen; - } - break; - - case IRGB: - image= newRGBImage(xwidth, ywidth, oimage->depth); - for (x= 0; x < oimage->rgb.used; x++) - { - *(image->rgb.red + x)= *(oimage->rgb.red + x); - *(image->rgb.green + x)= *(oimage->rgb.green + x); - *(image->rgb.blue + x)= *(oimage->rgb.blue + x); - } - image->rgb.used= oimage->rgb.used; - - pixlen= oimage->pixlen; - destptr= image->data; - srcline= oimage->data; - srclinelen= oimage->width * pixlen; - for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) - { - while (ysrc != *(yindex + y)) - { - ysrc++; - srcline += srclinelen; - } - - srcptr = srcline; - value = memToVal(srcptr, image->pixlen); - - for (x=0, xsrc= *(xindex + x); xtitle = dupString(oimage->title); - free((byte *)xindex); - free((byte *)yindex); - - printf("done\n"); - - return(image); -} - -void compress(Image *image) -{ - unsigned char *used, fast[32][32][32]; - unsigned int dmask; /* Depth mask protection */ - Pixel *map; - unsigned int next_index; - Intensity *red = image->rgb.red, - *green = image->rgb.green, - *blue = image->rgb.blue; - Intensity r,g,b; - unsigned int x, y, badcount = 0, dupcount = 0, unusedcount = 0; - unsigned char *pixptr, *pixend; - - if (!RGBP(image) || image->rgb.compressed) - return; - - /* - printf(" Compressing colormap..."); - fflush(stdout); - */ - - used = (unsigned char *)lcalloc(sizeof(unsigned char) * depthToColors(image->depth)); - dmask = (1 << image->depth) -1; /* Mask any illegal bits for that depth */ - map = (Pixel *)lcalloc(sizeof(Pixel) * depthToColors(image->depth)); - - /* init fast duplicate check table */ - for(r=0;r<32;r++) - for(g=0;g<32;g++) - for(b=0;b<32;b++) - fast[r][g][b] = 0; - - /* do pass 1 through the image to check index usage */ - - pixptr = image->data; - pixend = pixptr + (image->height * image->width); - for(;pixptr < pixend; pixptr++) - used[(*pixptr) & dmask] = 1; - - /* count the bad pixels */ - for (x = image->rgb.used; x < depthToColors(image->depth); x++) - if (used[x]) - badcount++; - - /* figure out duplicates and unuseds, and create the new mapping */ - next_index = 0; - for (x = 0; x < image->rgb.used; x++) - { - if (!used[x]) - { - unusedcount++; - continue; /* delete this index */ - } - - /* check for duplicate */ - r = red[x]; - g = green[x]; - b = blue[x]; - if (fast[r>>11][g>>11][b>>11]) /* if matches fast check */ - { - /* then do a linear search */ - for (y = x+1; y < image->rgb.used; y++) - { - if (r == red[y] && g == green[y] && b == blue[y]) - break; - } - if (y < image->rgb.used) /* found match */ - { - map[x] = y; - dupcount++; - continue; /* delete this index */ - } - fast[r>>11][g>>11][b>>11] = 1; - } - /* will map to this index */ - map[x] = next_index; - next_index++; - } - - /* change the image pixels */ - pixptr = image->data; - pixend = pixptr + (image->height * image->width); - for(;pixptr < pixend; pixptr++) - *pixptr = map[(*pixptr) & dmask]; - - /* change the colormap */ - for (x = 0; x < image->rgb.used; x++) - { - if (!used[x]) - continue; - red[map[x]] = red[x]; - green[map[x]] = green[x]; - blue[map[x]] = blue[x]; - } - image->rgb.used = next_index; - - /* clean up */ - free(map); - free(used); - - /* - if (badcount) - printf("%d out-of-range pixels, ", badcount); - - if (!unusedcount && !dupcount) - printf("no improvment\n"); - else - { - if (dupcount) - printf("%d duplicate%s and %d unused color%s removed...", - dupcount, (dupcount == 1 ? "" : "s"), - unusedcount, (unusedcount == 1 ? "" : "s")); - printf("%d unique color%s\n", - next_index, (next_index == 1 ? "" : "s")); - } - */ - - image->rgb.compressed= TRUE; /* don't do it again */ -} - - - - -Pixmap ximageToPixmap(Display *disp, Window parent, XImageInfo *ximageinfo) -{ - Pixmap pixmap; - - pixmap = XCreatePixmap(disp, parent, - ximageinfo->ximage->width, ximageinfo->ximage->height, - ximageinfo->depth); - - ximageinfo->drawable = pixmap; - - sendXImage(ximageinfo, 0, 0, 0, 0, - ximageinfo->ximage->width, ximageinfo->ximage->height); - return(pixmap); -} - -/* find the best pixmap depth supported by the server for a particular - * visual and return that depth. - * - * this is complicated by R3's lack of XListPixmapFormats so we fake it - * by looking at the structure ourselves. - */ - -static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn, - unsigned int depth) -{ -#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 4) - /* the way things are */ - XPixmapFormatValues *xf; - int nxf, a; - - xf = XListPixmapFormats(disp, &nxf); - for (a = 0; a < nxf; a++) - { - if (xf[a].depth == depth) - { - int bpp; - bpp = xf[a].bits_per_pixel; - XFree(xf); - return (unsigned int) bpp; - } - } - XFree(xf); -#else /* the way things were (X11R3) */ - unsigned int a; - - for (a= 0; a < disp->nformats; a++) - if (disp->pixmap_format[a].depth == depth) - return(disp->pixmap_format[a].bits_per_pixel); -#endif - - /* this should never happen; if it does, we're in trouble - */ - - fprintf(stderr, "bitsPerPixelAtDepth: Can't find pixmap depth info!\n"); - exit(1); -} - -XImageInfo *imageToXImage(Display *disp, int scrn, Visual *visual, - unsigned int ddepth, 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 private_cmap = FALSE; - Pixel *redvalue, *greenvalue, *bluevalue; - unsigned int a, c=0, x, y, linelen, dpixlen, dbits; - XColor xcolor; - XGCValues gcv; - XImageInfo *ximageinfo; - - if (!global_cmap) - { - if (visual == DefaultVisual(disp, scrn)) - global_cmap = DefaultColormap(disp, scrn); - else - { - global_cmap = XCreateColormap(disp, RootWindow(disp, scrn), - visual, AllocNone); - private_cmap = TRUE; - } - } - - xcolor.flags = DoRed | DoGreen | DoBlue; - redvalue = greenvalue = bluevalue = NULL; - ximageinfo = (XImageInfo *)lmalloc(sizeof(XImageInfo)); - ximageinfo->disp = disp; - ximageinfo->scrn = scrn; - ximageinfo->depth = 0; - ximageinfo->drawable = None; - ximageinfo->index = NULL; - ximageinfo->rootimage = FALSE; - ximageinfo->foreground = ximageinfo->background= 0; - ximageinfo->gc = NULL; - ximageinfo->ximage = NULL; - - 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 *)lmalloc(sizeof(Pixel) * 256); - greenvalue = (Pixel *)lmalloc(sizeof(Pixel) * 256); - bluevalue = (Pixel *)lmalloc(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; - } - - /* sanity check - */ - - if ((redcolors > visual->map_entries) || - (greencolors > visual->map_entries) || - (bluecolors > visual->map_entries)) - { - fprintf(stderr, "Warning: inconsistency in color information (this may be ugly)\n"); - } - - redstep = 256 / redcolors; - greenstep = 256 / greencolors; - bluestep = 256 / bluecolors; - redbottom = greenbottom = bluebottom = 0; - redtop = greentop = bluetop = 0; - for (a=0; amap_entries; a++) - { - if (redbottom < 256) - redtop = redbottom + redstep; - if (greenbottom < 256) - greentop = greenbottom + greenstep; - if (bluebottom < 256) - bluetop = bluebottom + bluestep; - - xcolor.red = (redtop - 1) << 8; - xcolor.green = (greentop - 1) << 8; - xcolor.blue = (bluetop - 1) << 8; - if (!XAllocColor(disp, 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(disp, scrn))) - { - global_cmap = XCopyColormapAndFree(disp, 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((byte *)redvalue); - free((byte *)greenvalue); - free((byte *)bluevalue); - free((byte *)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; - ximageinfo->index = (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used); - - for (a=0; argb.used; a++) - { - XColor xcolor2; - unsigned short mask; - int color_found; - int i; - - 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(disp, ximageinfo->cmap, &xcolor)) - { - if (!private_cmap) - { - /* - printf("switching to private colormap...\n"); - */ - - /* we just filled up the default colormap -- get a private one - which contains all already allocated colors */ - - global_cmap = XCopyColormapAndFree(disp, global_cmap); - ximageinfo->cmap = global_cmap; - private_cmap = TRUE; - - /* allocate the rest of the color cells read/write */ - global_cmap_index = - (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS); - for (i=0; i=0; i--) - { - xcolor2.pixel = *(global_cmap_index + i); - xcolor2 = xcolor_private[xcolor2.pixel]; - - if (colorcell_used[xcolor2.pixel]) - continue; - - if ((xcolor.red & mask) == (xcolor2.red & mask) && - (xcolor.green & mask) == (xcolor2.green & mask) && - (xcolor.blue & mask) == (xcolor2.blue & mask)) - { - /* - printf("replacing color cell %ld with a close color\n", - xcolor2.pixel); - */ - color_found = TRUE; - break; - } - } - - if (mask == 0x0000) - break; - - mask = (mask << 1) & 0xffff; - } - - if (!color_found) /* no more free color cells */ - { - printf("Sorry, cannot allocate enough colors!\n"); - exit(0); - } - - xcolor.pixel = xcolor2.pixel; - xcolor_private[xcolor.pixel] = xcolor; - colorcell_used[xcolor.pixel] = TRUE; - XStoreColor(disp, 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: - printf("Sorry, only DirectColor, TrueColor and PseudoColor supported\n"); - exit(0); - break; - } - - /* create an XImage and related colormap based on the image type - * we have. - */ - - /* - printf(" Building XImage..."); - fflush(stdout); - */ - - switch (image->type) - { - case IBITMAP: - { - byte *data; - - /* we copy the data to be more consistent - */ - - linelen = ((image->width + 7) / 8); - data= lmalloc(linelen * image->height); - - memcpy((char *)data, (char *)image->data, linelen * image->height); - - gcv.function= GXcopy; - ximageinfo->ximage= XCreateImage(disp, visual, 1, XYBitmap, - 0, (char *)data, image->width, image->height, - 8, linelen); - - /* use this if you want to use the bitmap as a mask */ - ximageinfo->depth = image->depth; - - if(visual->class == DirectColor || visual->class == TrueColor) - { - Pixel pixval; - dbits= bitsPerPixelAtDepth(disp, scrn, ddepth); - dpixlen= (dbits + 7) / 8; - pixval= redvalue[image->rgb.red[0] >> 8] | - greenvalue[image->rgb.green[0] >> 8] | - bluevalue[image->rgb.blue[0] >> 8]; - ximageinfo->background = pixval; - pixval= redvalue[image->rgb.red[1] >> 8] | - greenvalue[image->rgb.green[1] >> 8] | - bluevalue[image->rgb.blue[1] >> 8]; - ximageinfo->foreground = pixval; - } - else /* Not Direct or True Color */ - { - ximageinfo->foreground = BlackPixel(disp,scrn); - ximageinfo->background = WhitePixel(disp,scrn); - } - ximageinfo->ximage->bitmap_bit_order= MSBFirst; - ximageinfo->ximage->byte_order= MSBFirst; - - break; - } - - case IRGB: - { - /* modify image data to match visual and colormap - */ - - byte *data, *destptr, *srcptr; - - dbits = bitsPerPixelAtDepth(disp, scrn, ddepth); /* bits per pixel */ - dpixlen = (dbits + 7) / 8; /* bytes per pixel */ - - ximageinfo->ximage = XCreateImage(disp, visual, ddepth, ZPixmap, 0, - NULL, image->width, image->height, - 8, image->width * dpixlen); - - data = (byte *)lmalloc(image->width * image->height * dpixlen); - ximageinfo->depth = ddepth; - ximageinfo->ximage->data = (char *)data; - ximageinfo->ximage->byte_order = MSBFirst; - srcptr = image->data; - destptr = data; - - switch (visual->class) - { - case DirectColor: - case TrueColor: - { - Pixel pixval; - - for (y=0; yheight; y++) - { - for (x=0; xwidth; x++) - { - pixval = memToVal(srcptr, 1); - pixval = redvalue[image->rgb.red[pixval] >> 8] | - greenvalue[image->rgb.green[pixval] >> 8] | - bluevalue[image->rgb.blue[pixval] >> 8]; - valToMem(pixval, destptr, dpixlen); - srcptr += 1; - destptr += dpixlen; - } - } - break; - } - - default: - { - if (dpixlen == 1) /* most common */ - { - for (y=0; yheight; y++) - { - for (x=0; xwidth; x++) - { - *destptr = ximageinfo->index[c + *srcptr]; - srcptr++; - destptr++; - } - } - } - else /* less common */ - { - for (y=0; yheight; y++) - { - for (x=0; xwidth; x++) - { - register unsigned long temp; - temp = memToVal(srcptr, 1); - valToMem(ximageinfo->index[c + temp], destptr, dpixlen); - srcptr += 1; - destptr += dpixlen; - } - } - } - } - break; - } - } - } - - /* - printf("done\n"); - */ - - if (redvalue) - { - free((byte *)redvalue); - free((byte *)greenvalue); - free((byte *)bluevalue); - } - - return(ximageinfo); -} - -/* Given an XImage and a drawable, move a rectangle from the Ximage - * to the drawable. - */ - -void sendXImage(XImageInfo *ximageinfo, - int src_x, int src_y, int dst_x, int dst_y, - unsigned int w, unsigned int h) -{ - XGCValues gcv; - - /* build and cache the GC - */ - - if (!ximageinfo->gc) - { - gcv.function = GXcopy; - if (ximageinfo->ximage->depth == 1) - { - gcv.foreground = ximageinfo->foreground; - gcv.background = ximageinfo->background; - ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable, - GCFunction | GCForeground | GCBackground, - &gcv); - } - else - ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable, - GCFunction, &gcv); - } - - XPutImage(ximageinfo->disp, ximageinfo->drawable, ximageinfo->gc, - ximageinfo->ximage, src_x, src_y, dst_x, dst_y, w, h); -} - -/* free up anything cached in the local Ximage structure. - */ - -void freeXImage(Image *image, XImageInfo *ximageinfo) -{ - if (ximageinfo->index != NULL) /* if we allocated colors */ - { - if (ximageinfo->no > 0 && !ximageinfo->rootimage) /* don't free root colors */ - XFreeColors(ximageinfo->disp, ximageinfo->cmap, ximageinfo->index, ximageinfo->no, 0); - free(ximageinfo->index); - } - if (ximageinfo->gc) - XFreeGC(ximageinfo->disp, ximageinfo->gc); - free((byte *)ximageinfo->ximage->data); - ximageinfo->ximage->data= NULL; - XDestroyImage(ximageinfo->ximage); - free((byte *)ximageinfo); - /* should we free private color map to ??? */ -} diff --git a/src/xli.h b/src/xli.h deleted file mode 100644 index 50826558..00000000 --- a/src/xli.h +++ /dev/null @@ -1,153 +0,0 @@ - -/* xli.h: - * - * jim frost 06.21.89 - * - * Copyright 1989 Jim Frost. See included file "copyright.h" for complete - * copyright information. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -typedef unsigned long Pixel; /* what X thinks a pixel is */ -typedef unsigned short Intensity; /* what X thinks an RGB intensity is */ -typedef unsigned char byte; /* unsigned byte type */ - -#define FALSE 0 -#define TRUE (!FALSE) - -/* Display device dependent Information structure */ -typedef struct -{ - int width; /* Display width and height */ - int height; - - Display *disp; - int scrn; - Colormap colormap; -} DisplayInfo; - -/* This struct holds the X-client side bits for a rendered image. */ -typedef struct -{ - Display *disp; /* destination display */ - int scrn; /* destination screen */ - int depth; /* depth of drawable we want/have */ - Drawable drawable; /* drawable to send image to */ - Pixel *index; /* array of pixel values allocated */ - int no; /* number of pixels in the array */ - int rootimage; /* True if is a root image - eg, retain colors */ - Pixel foreground; /* foreground and background pixels for mono images */ - Pixel background; - Colormap cmap; /* colormap used for image */ - GC gc; /* cached gc for sending image */ - XImage *ximage; /* ximage structure */ -} XImageInfo; - -/* Function declarations */ -void sendXImage(); /* send.c */ -XImageInfo *imageToXImage(); -Pixmap ximageToPixmap(); -void freeXImage(); - - -typedef struct rgbmap { - unsigned int size; /* size of RGB map */ - unsigned int used; /* number of colors used in RGB map */ - int compressed; /* image uses colormap fully */ - Intensity *red; /* color values in X style */ - Intensity *green; - Intensity *blue; -} RGBMap; - -/* image structure - */ - -typedef struct { - char *title; /* name of image */ - unsigned int type; /* type of image */ - 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 */ - unsigned int pixlen; /* length of pixel if IRGB type */ - byte *data; /* data rounded to full byte for each row */ - float gamma; /* gamma of display the image is adjusted for */ -} Image; - -#define IBITMAP 0 /* image is a bitmap */ -#define IRGB 1 /* image is RGB */ - -#define BITMAPP(IMAGE) ((IMAGE)->type == IBITMAP) -#define RGBP(IMAGE) ((IMAGE)->type == IRGB) - -#define depthToColors(n) DepthToColorsTable[((n) < 24 ? (n) : 24)] - -/* - * Architecture independent memory to value conversions. - * Note the "Normal" internal format is big endian. - */ - -#define memToVal(PTR,LEN) ( \ -(LEN) == 1 ? (unsigned long)( *( (byte *)(PTR)) ) : \ -(LEN) == 2 ? (unsigned long)(((unsigned long)(*( (byte *)(PTR)) ))<< 8) \ - + ( *(((byte *)(PTR))+1) ) : \ -(LEN) == 3 ? (unsigned long)(((unsigned long)(*( (byte *)(PTR)) ))<<16) \ - + (((unsigned long)(*(((byte *)(PTR))+1)))<< 8) \ - + ( *(((byte *)(PTR))+2) ) : \ - (unsigned long)(((unsigned long)(*( (byte *)(PTR)) ))<<24) \ - + (((unsigned long)(*(((byte *)(PTR))+1)))<<16) \ - + (((unsigned long)(*(((byte *)(PTR))+2)))<< 8) \ - + ( *(((byte *)(PTR))+3) ) ) - -#define valToMem(VAL,PTR,LEN) ( \ -(LEN) == 1 ? (*( (byte *)(PTR) ) = ( VAL ) ) : \ -(LEN) == 2 ? (*( (byte *)(PTR) ) = (((unsigned long)(VAL))>> 8), \ - *(((byte *)(PTR))+1) = ( VAL ) ) : \ -(LEN) == 3 ? (*( (byte *)(PTR) ) = (((unsigned long)(VAL))>>16), \ - *(((byte *)(PTR))+1) = (((unsigned long)(VAL))>> 8), \ - *(((byte *)(PTR))+2) = ( VAL ) ) : \ - (*( (byte *)(PTR) ) = (((unsigned long)(VAL))>>24), \ - *(((byte *)(PTR))+1) = (((unsigned long)(VAL))>>16), \ - *(((byte *)(PTR))+2) = (((unsigned long)(VAL))>> 8), \ - *(((byte *)(PTR))+3) = ( VAL ) )) - - -/* functions */ - -void cleanUpWindow(); /* window.c */ -char imageInWindow(); - -int visualClassFromName(); -char *nameOfVisualClass(); - -extern unsigned long DepthToColorsTable[]; /* new.c */ -char *dupString(); -Image *newBitImage(); -Image *newRGBImage(); -void freeImage(); -void freeImageData(); -void newRGBMapData(); -void freeRGBMapData(); -byte *lcalloc(); -byte *lmalloc(); - -Image *gifLoad(); -Image *monochrome(); -Image *zoom(); - -void compress(); /* compress.c */ - -int xliOpenDisplay(); -void tellAboutDisplay(DisplayInfo *); -void xliCloseDisplay(DisplayInfo *);