X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fmisc.c;h=c560ae4bc0f6c3ae2931b82d5d5a9f5a4f9e39f6;hp=56b651cbc38f3d9cf6c9a2abe4e0f5098006d9bd;hb=49dab46aa55cb43233c7f9a310593f8bd8debc29;hpb=59c2e609872b70cb4c458004cd9e2fe22c86a54b diff --git a/src/misc.c b/src/misc.c index 56b651cb..c560ae4b 100644 --- a/src/misc.c +++ b/src/misc.c @@ -24,6 +24,7 @@ #include "tools.h" #include "sound.h" #include "random.h" +#include "joystick.h" static unsigned long mainCounter(int mode) { @@ -75,7 +76,7 @@ static void sleep_milliseconds(unsigned long milliseconds_delay) delay.tv_usec = 1000 * (milliseconds_delay % 1000); if (select(0, NULL, NULL, NULL, &delay) != 0) - Error(ERR_RETURN, "sleep_milliseconds(): select() failed"); + Error(ERR_WARN, "sleep_milliseconds(): select() failed"); } } @@ -84,7 +85,8 @@ void Delay(unsigned long delay) /* Sleep specified number of milliseconds */ sleep_milliseconds(delay); } -BOOL FrameReached(unsigned long *frame_counter_var, unsigned long frame_delay) +boolean FrameReached(unsigned long *frame_counter_var, + unsigned long frame_delay) { unsigned long actual_frame_counter = FrameCounter; @@ -96,7 +98,8 @@ BOOL FrameReached(unsigned long *frame_counter_var, unsigned long frame_delay) return(TRUE); } -BOOL DelayReached(unsigned long *counter_var, unsigned long delay) +boolean DelayReached(unsigned long *counter_var, + unsigned long delay) { unsigned long actual_counter = Counter(); @@ -126,12 +129,23 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay) *counter_var = actual_counter; } -char *int2str(int ct, int nr) +char *int2str(int number, int size) { - static char str[20]; + static char s[40]; - sprintf(str,"%09d",ct); - return(&str[strlen(str)-nr]); + if (size > 20) + size = 20; + + if (size) + { + sprintf(s, " %09d", number); + return &s[strlen(s) - size]; + } + else + { + sprintf(s, "%d", number); + return s; + } } unsigned int SimpleRND(unsigned int max) @@ -141,39 +155,59 @@ unsigned int SimpleRND(unsigned int max) gettimeofday(¤t_time,NULL); root = root * 4253261 + current_time.tv_sec + current_time.tv_usec; - return(root % max); + return (root % max); } unsigned int RND(unsigned int max) { - return(random_linux_libc() % max); + return (random_linux_libc() % max); } unsigned int InitRND(long seed) { struct timeval current_time; - if (seed==NEW_RANDOMIZE) + if (seed == NEW_RANDOMIZE) { gettimeofday(¤t_time,NULL); srandom_linux_libc((unsigned int) current_time.tv_usec); - return((unsigned int) current_time.tv_usec); + return (unsigned int)current_time.tv_usec; } else { srandom_linux_libc((unsigned int) seed); - return((unsigned int) seed); + return (unsigned int)seed; } } -char *GetLoginName() +char *getLoginName() { struct passwd *pwd; - if (!(pwd=getpwuid(getuid()))) - return("ANONYMOUS"); + if (!(pwd = getpwuid(getuid()))) + return "ANONYMOUS"; else - return(pwd->pw_name); + return pwd->pw_name; +} + +char *getHomeDir() +{ + static char *home_dir = NULL; + + if (!home_dir) + { + if (!(home_dir = getenv("HOME"))) + { + struct passwd *pwd; + + if ((pwd = getpwuid(getuid()))) + home_dir = pwd->pw_dir; + else + home_dir = "."; + } + } + + return home_dir; } void MarkTileDirty(int x, int y) @@ -182,17 +216,26 @@ void MarkTileDirty(int x, int y) int yy = redraw_y1 + y; if (!redraw[xx][yy]) - { - redraw[xx][yy] = TRUE; redraw_tiles++; - redraw_mask |= REDRAW_TILES; - } + + redraw[xx][yy] = TRUE; + redraw_mask |= REDRAW_TILES; } void GetOptions(char *argv[]) { char **options_left = &argv[1]; + /* initialize global program options */ + options.display_name = NULL; + options.server_host = NULL; + options.server_port = 0; + options.base_directory = BASE_PATH; + options.level_directory = BASE_PATH "/" LEVELS_DIRECTORY; + options.serveronly = FALSE; + options.network = FALSE; + options.verbose = FALSE; + while (*options_left) { char option_str[MAX_OPTION_LEN]; @@ -232,6 +275,7 @@ void GetOptions(char *argv[]) printf("Usage: %s [options] [server.name [port]]\n" "Options:\n" " -d, --display machine:0 X server display\n" + " -b, --basepath directory alternative base directory\n" " -l, --levels directory alternative level directory\n" " -s, --serveronly only start network server\n" " -n, --network network multiplayer game\n" @@ -244,56 +288,73 @@ void GetOptions(char *argv[]) if (option_arg == NULL) Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); - display_name = option_arg; + options.display_name = option_arg; if (option_arg == next_option) options_left++; - printf("--display == '%s'\n", display_name); + printf("--display == '%s'\n", options.display_name); + } + else if (strncmp(option, "-basepath", option_len) == 0) + { + if (option_arg == NULL) + Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); + + options.base_directory = option_arg; + if (option_arg == next_option) + options_left++; + + printf("--basepath == '%s'\n", options.base_directory); + + /* adjust path for level directory accordingly */ + options.level_directory = checked_malloc(strlen(options.base_directory) + + strlen(LEVELS_DIRECTORY) + 2); + sprintf(options.level_directory, "%s/%s", + options.base_directory, LEVELS_DIRECTORY); } else if (strncmp(option, "-levels", option_len) == 0) { if (option_arg == NULL) Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str); - level_directory = option_arg; + options.level_directory = option_arg; if (option_arg == next_option) options_left++; - printf("--levels == '%s'\n", level_directory); + printf("--levels == '%s'\n", options.level_directory); } else if (strncmp(option, "-network", option_len) == 0) { printf("--network\n"); - network = TRUE; + options.network = TRUE; } else if (strncmp(option, "-serveronly", option_len) == 0) { printf("--serveronly\n"); - serveronly = TRUE; + options.serveronly = TRUE; } else if (strncmp(option, "-verbose", option_len) == 0) { printf("--verbose\n"); - verbose = TRUE; + options.verbose = TRUE; } else if (*option == '-') Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str); - else if (server_host == NULL) + else if (options.server_host == NULL) { - server_host = *options_left; + options.server_host = *options_left; - printf("server.name == '%s'\n", server_host); + printf("server.name == '%s'\n", options.server_host); } - else if (server_port == 0) + else if (options.server_port == 0) { - server_port = atoi(*options_left); - if (server_port < 1024) - Error(ERR_EXIT_HELP, "bad port number '%d'", server_port); + options.server_port = atoi(*options_left); + if (options.server_port < 1024) + Error(ERR_EXIT_HELP, "bad port number '%d'", options.server_port); - printf("port == %d\n", server_port); + printf("port == %d\n", options.server_port); } else Error(ERR_EXIT_HELP, "too many arguments"); @@ -307,7 +368,7 @@ void Error(int mode, char *format_str, ...) FILE *output_stream = stderr; char *process_name = ""; - if (mode == ERR_EXIT_SOUNDSERVER) + if (mode & ERR_SOUNDSERVER) process_name = " sound server"; if (format_str) @@ -320,6 +381,9 @@ void Error(int mode, char *format_str, ...) fprintf(output_stream, "%s%s: ", program_name, process_name); + if (mode & ERR_WARN) + fprintf(output_stream, "warning: "); + va_start(ap, format_str); /* ap points to first unnamed argument */ for(format_ptr=format_str; *format_ptr; format_ptr++) @@ -359,26 +423,354 @@ void Error(int mode, char *format_str, ...) fprintf(output_stream, "\n"); } - if (mode == ERR_EXIT_HELP) + if (mode & ERR_HELP) fprintf(output_stream, "%s: Try option '--help' for more information.\n", program_name); - if (mode != ERR_RETURN) + if (mode & ERR_EXIT) { fprintf(output_stream, "%s%s: aborting\n", program_name, process_name); CloseAllAndExit(1); } } -/* like memcpy, but guaranteed to handle overlap when s <= t */ -void copydown(char *s, char *t, int n) +void *checked_malloc(unsigned long size) { - for (; n; n--) - *(s++) = *(t++); + void *ptr; + + ptr = malloc(size); + + if (ptr == NULL) + Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size); + + return ptr; } -void fatal(char *s) +#define TRANSLATE_KEYSYM_TO_KEYNAME 0 +#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1 +#define TRANSLATE_X11KEYNAME_TO_KEYSYM 2 + +void translate_keyname(KeySym *keysym, char **x11name, char **name, int mode) { - fprintf(stderr, "%s.\n", s); - exit(1); + static struct + { + KeySym keysym; + char *x11name; + char *name; + } translate_key[] = + { + /* normal cursor keys */ + { XK_Left, "XK_Left", "cursor left" }, + { XK_Right, "XK_Right", "cursor right" }, + { XK_Up, "XK_Up", "cursor up" }, + { XK_Down, "XK_Down", "cursor down" }, + + /* keypad cursor keys */ +#ifdef XK_KP_Left + { XK_KP_Left, "XK_KP_Left", "keypad left" }, + { XK_KP_Right, "XK_KP_Right", "keypad right" }, + { XK_KP_Up, "XK_KP_Up", "keypad up" }, + { XK_KP_Down, "XK_KP_Down", "keypad down" }, +#endif + + /* other keypad keys */ +#ifdef XK_KP_Enter + { XK_KP_Enter, "XK_KP_Enter", "keypad enter" }, + { XK_KP_Add, "XK_KP_Add", "keypad +" }, + { XK_KP_Subtract, "XK_KP_Subtract", "keypad -" }, + { XK_KP_Multiply, "XK_KP_Multiply", "keypad mltply" }, + { XK_KP_Divide, "XK_KP_Divide", "keypad /" }, + { XK_KP_Separator, "XK_KP_Separator", "keypad ," }, +#endif + + /* modifier keys */ + { XK_Shift_L, "XK_Shift_L", "left shift" }, + { XK_Shift_R, "XK_Shift_R", "right shift" }, + { XK_Control_L, "XK_Control_L", "left control" }, + { XK_Control_R, "XK_Control_R", "right control" }, + { XK_Meta_L, "XK_Meta_L", "left meta" }, + { XK_Meta_R, "XK_Meta_R", "right meta" }, + { XK_Alt_L, "XK_Alt_L", "left alt" }, + { XK_Alt_R, "XK_Alt_R", "right alt" }, + { XK_Mode_switch, "XK_Mode_switch", "mode switch" }, + { XK_Multi_key, "XK_Multi_key", "multi key" }, + + /* some special keys */ + { XK_BackSpace, "XK_BackSpace", "backspace" }, + { XK_Delete, "XK_Delete", "delete" }, + { XK_Insert, "XK_Insert", "insert" }, + { XK_Tab, "XK_Tab", "tab" }, + { XK_Home, "XK_Home", "home" }, + { XK_End, "XK_End", "end" }, + { XK_Page_Up, "XK_Page_Up", "page up" }, + { XK_Page_Down, "XK_Page_Down", "page down" }, + { XK_space, "XK_space", "space" }, + + /* even more special keys */ + { XK_adiaeresis, "XK_adiaeresis", "ä" }, + { XK_odiaeresis, "XK_odiaeresis", "ö" }, + { XK_udiaeresis, "XK_udiaeresis", "ü" }, + { XK_apostrophe, "XK_apostrophe", "'" }, + { XK_plus, "XK_plus", "+" }, + { XK_minus, "XK_minus", "-" }, + { XK_comma, "XK_comma", "," }, + { XK_period, "XK_period", "." }, + { XK_numbersign, "XK_numbersign", "#" }, + { XK_less, "XK_less", "less" }, + { XK_greater, "XK_greater", "greater" }, + { XK_asciicircum, "XK_asciicircum", "circumflex" }, + { XK_ssharp, "XK_ssharp", "sharp s" }, + + /* end-of-array identifier */ + { 0, NULL, NULL } + }; + + int i; + + if (mode == TRANSLATE_KEYSYM_TO_KEYNAME) + { + static char name_buffer[30]; + KeySym key = *keysym; + + if (key >= XK_A && key <= XK_Z) + sprintf(name_buffer, "%c", 'A' + (char)(key - XK_A)); + else if (key >= XK_a && key <= XK_z) + sprintf(name_buffer, "%c", 'a' + (char)(key - XK_a)); + else if (key >= XK_0 && key <= XK_9) + sprintf(name_buffer, "%c", '0' + (char)(key - XK_0)); + else if (key >= XK_KP_0 && key <= XK_KP_9) + sprintf(name_buffer, "keypad %c", '0' + (char)(key - XK_KP_0)); + else if (key >= XK_F1 && key <= XK_F24) + sprintf(name_buffer, "function F%d", (int)(key - XK_F1 + 1)); + else if (key == KEY_UNDEFINDED) + strcpy(name_buffer, "(undefined)"); + else + { + i = 0; + + do + { + if (key == translate_key[i].keysym) + { + strcpy(name_buffer, translate_key[i].name); + break; + } + } + while (translate_key[++i].name); + + if (!translate_key[i].name) + strcpy(name_buffer, "(unknown)"); + } + + *name = name_buffer; + } + else if (mode == TRANSLATE_KEYSYM_TO_X11KEYNAME) + { + static char name_buffer[30]; + KeySym key = *keysym; + + if (key >= XK_A && key <= XK_Z) + sprintf(name_buffer, "XK_%c", 'A' + (char)(key - XK_A)); + else if (key >= XK_a && key <= XK_z) + sprintf(name_buffer, "XK_%c", 'a' + (char)(key - XK_a)); + else if (key >= XK_0 && key <= XK_9) + sprintf(name_buffer, "XK_%c", '0' + (char)(key - XK_0)); + else if (key >= XK_KP_0 && key <= XK_KP_9) + sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - XK_KP_0)); + else if (key >= XK_F1 && key <= XK_F24) + sprintf(name_buffer, "XK_F%d", (int)(key - XK_F1 + 1)); + else if (key == KEY_UNDEFINDED) + strcpy(name_buffer, "[undefined]"); + else + { + i = 0; + + do + { + if (key == translate_key[i].keysym) + { + strcpy(name_buffer, translate_key[i].x11name); + break; + } + } + while (translate_key[++i].x11name); + + if (!translate_key[i].x11name) + sprintf(name_buffer, "0x%04lx", (unsigned long)key); + } + + *x11name = name_buffer; + } + else if (mode == TRANSLATE_X11KEYNAME_TO_KEYSYM) + { + KeySym key = XK_VoidSymbol; + char *name_ptr = *x11name; + + if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4) + { + char c = name_ptr[3]; + + if (c >= 'A' && c <= 'Z') + key = XK_A + (KeySym)(c - 'A'); + else if (c >= 'a' && c <= 'z') + key = XK_a + (KeySym)(c - 'a'); + else if (c >= '0' && c <= '9') + key = XK_0 + (KeySym)(c - '0'); + } + else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7) + { + char c = name_ptr[6]; + + if (c >= '0' && c <= '9') + key = XK_0 + (KeySym)(c - '0'); + } + else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6) + { + char c1 = name_ptr[4]; + char c2 = name_ptr[5]; + int d = 0; + + if ((c1 >= '0' && c1 <= '9') && + ((c2 >= '0' && c1 <= '9') || c2 == '\0')) + d = atoi(&name_ptr[4]); + + if (d >=1 && d <= 24) + key = XK_F1 + (KeySym)(d - 1); + } + else if (strncmp(name_ptr, "XK_", 3) == 0) + { + i = 0; + + do + { + if (strcmp(name_ptr, translate_key[i].x11name) == 0) + { + key = translate_key[i].keysym; + break; + } + } + while (translate_key[++i].x11name); + } + else if (strncmp(name_ptr, "0x", 2) == 0) + { + unsigned long value = 0; + + name_ptr += 2; + + while (name_ptr) + { + char c = *name_ptr++; + int d = -1; + + if (c >= '0' && c <= '9') + d = (int)(c - '0'); + else if (c >= 'a' && c <= 'f') + d = (int)(c - 'a' + 10); + else if (c >= 'A' && c <= 'F') + d = (int)(c - 'A' + 10); + + if (d == -1) + { + value = -1; + break; + } + + value = value * 16 + d; + } + + if (value != -1) + key = (KeySym)value; + } + + *keysym = key; + } +} + +char *getKeyNameFromKeySym(KeySym keysym) +{ + char *name; + + translate_keyname(&keysym, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME); + return name; +} + +char *getX11KeyNameFromKeySym(KeySym keysym) +{ + char *x11name; + + translate_keyname(&keysym, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME); + return x11name; +} + +KeySym getKeySymFromX11KeyName(char *x11name) +{ + KeySym keysym; + + translate_keyname(&keysym, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM); + return keysym; +} + +#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0 +#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1 + +void translate_joyname(int *joysymbol, char **name, int mode) +{ + static struct + { + int joysymbol; + char *name; + } translate_joy[] = + { + { JOY_LEFT, "joystick_left" }, + { JOY_RIGHT, "joystick_right" }, + { JOY_UP, "joystick_up" }, + { JOY_DOWN, "joystick_down" }, + { JOY_BUTTON_1, "joystick_button_1" }, + { JOY_BUTTON_2, "joystick_button_2" }, + }; + + int i; + + if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME) + { + *name = "[undefined]"; + + for (i=0; i<6; i++) + { + if (*joysymbol == translate_joy[i].joysymbol) + { + *name = translate_joy[i].name; + break; + } + } + } + else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL) + { + *joysymbol = 0; + + for (i=0; i<6; i++) + { + if (strcmp(*name, translate_joy[i].name) == 0) + { + *joysymbol = translate_joy[i].joysymbol; + break; + } + } + } +} + +char *getJoyNameFromJoySymbol(int joysymbol) +{ + char *name; + + translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME); + return name; +} + +int getJoySymbolFromJoyName(char *name) +{ + int joysymbol; + + translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL); + return joysymbol; }