X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fmsdos.c;h=efcd80205918fd491e3524139bab1884c4fd071f;hp=54502aeff53a43c6ae791c82d84f9a6d55368f96;hb=3d97e3d9c20a984e70dae5e63e7c5069fb136c91;hpb=823bddb0d9cc63ddda17a2cd20266aa3b82bde38 diff --git a/src/msdos.c b/src/msdos.c index 54502aef..efcd8020 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -1,209 +1,242 @@ /*********************************************************** * 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 * +* ©1995 Artsoft Development * +* Holger Schemel * +* 33659 Bielefeld-Senne * +* Telefon: (0521) 493245 * +* eMail: aeglos@valinor.owl.de * +* aeglos@uni-paderborn.de * +* q99492@pbhrzx.uni-paderborn.de * *----------------------------------------------------------* * msdos.c * ***********************************************************/ #ifdef MSDOS + #include "main.h" +#include "misc.h" #include "tools.h" #include "sound.h" #include "files.h" #include "joystick.h" +#include "image.h" +#include "pcx.h" -DECLARE_GFX_DRIVER_LIST( - GFX_DRIVER_VBEAF - GFX_DRIVER_VESA2L - GFX_DRIVER_VESA1) +/* allegro driver declarations */ +DECLARE_GFX_DRIVER_LIST(GFX_DRIVER_VBEAF GFX_DRIVER_VESA2L GFX_DRIVER_VESA1) DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8) DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB) DECLARE_MIDI_DRIVER_LIST() DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD) -static int key_buffer[OSD_MAX_KEY]; +/* allegro global variables */ +extern volatile int key_shifts; +extern int num_joysticks; +extern JOYSTICK_INFO joy[]; +extern int i_love_bill; + +/* internal variables of msdos.c */ +static int key_press_state[MAX_SCANCODES]; static XEvent event_buffer[MAX_EVENT_BUFFER]; static int pending_events; -static BOOL joystick_event; -static BOOL mouse_installed = FALSE; +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; -BOOL wait_for_vsync; +static RGB global_colormap[MAX_COLORS]; +static int global_colormap_entries_used = 0; + +boolean wait_for_vsync; +/* extern int playing_sounds; extern struct SoundControl playlist[MAX_SOUNDS_PLAYING]; extern struct SoundControl emptySoundControl; +*/ -void allegro_drivers() +static BITMAP *Read_PCX_to_AllegroBitmap(char *); + +static void allegro_drivers() { int i; - for(i = 0; i < MAX_EVENT_BUFFER; i++); - event_buffer[i].type = 0; - for(i=0; i < OSD_MAX_KEY; i++) key_buffer[i] = KeyReleaseMask; + for (i=0; i 0) mouse_installed = TRUE; - install_joystick(JOY_TYPE_2PADS); + if (install_mouse() > 0) + mouse_installed = TRUE; - 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; - + if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1) + if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) + sound_status = SOUND_OFF; } -BOOL hide_mouse(Display *display, int x, int y, unsigned int width, unsigned int height) +static boolean hide_mouse(Display *display, int x, int y, + unsigned int width, unsigned int height) { - if(mouse_x + display->mouse_ptr->w < x || mouse_x > x+width) return FALSE; - if(mouse_y + display->mouse_ptr->h < y || mouse_y > y+height) return FALSE; + 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); + + return TRUE; } -void unhide_mouse(Display *display) +static void unhide_mouse(Display *display) { - if(mouse_installed) show_mouse(video_bitmap); + if (mouse_installed) + show_mouse(video_bitmap); } -int get_joystick_state() +static KeySym ScancodeToKeySym(byte scancode) { - 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) + switch(scancode) { - 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; + case KEY_ESC: return XK_Escape; + case KEY_1: return XK_1; + case KEY_2: return XK_2; + case KEY_3: return XK_3; + case KEY_4: return XK_4; + case KEY_5: return XK_5; + case KEY_6: return XK_6; + case KEY_7: return XK_7; + case KEY_8: return XK_8; + case KEY_9: return XK_9; + case KEY_0: return XK_0; + case KEY_MINUS: return XK_minus; + case KEY_EQUALS: return XK_equal; + case KEY_BACKSPACE: return XK_BackSpace; + case KEY_TAB: return XK_Tab; + case KEY_Q: return XK_q; + case KEY_W: return XK_w; + case KEY_E: return XK_e; + case KEY_R: return XK_r; + case KEY_T: return XK_t; + case KEY_Y: return XK_y; + case KEY_U: return XK_u; + case KEY_I: return XK_i; + case KEY_O: return XK_o; + case KEY_P: return XK_p; + case KEY_OPENBRACE: return XK_braceleft; + case KEY_CLOSEBRACE: return XK_braceright; + case KEY_ENTER: return XK_Return; + case KEY_LCONTROL: return XK_Control_L; + case KEY_A: return XK_a; + case KEY_S: return XK_s; + case KEY_D: return XK_d; + case KEY_F: return XK_f; + case KEY_G: return XK_g; + case KEY_H: return XK_h; + case KEY_J: return XK_j; + case KEY_K: return XK_k; + case KEY_L: return XK_l; + case KEY_COLON: return XK_colon; + case KEY_QUOTE: return XK_apostrophe; + case KEY_TILDE: return XK_asciitilde; + case KEY_LSHIFT: return XK_Shift_L; + case KEY_BACKSLASH: return XK_backslash; + case KEY_Z: return XK_z; + case KEY_X: return XK_x; + case KEY_C: return XK_c; + case KEY_V: return XK_v; + case KEY_B: return XK_b; + case KEY_N: return XK_n; + case KEY_M: return XK_m; + case KEY_COMMA: return XK_comma; + case KEY_STOP: return XK_period; + case KEY_SLASH: return XK_slash; + case KEY_RSHIFT: return XK_Shift_R; + case KEY_ASTERISK: return XK_KP_Multiply; + case KEY_ALT: return XK_Alt_L; + case KEY_SPACE: return XK_space; + case KEY_CAPSLOCK: return XK_Caps_Lock; + case KEY_F1: return XK_F1; + case KEY_F2: return XK_F2; + case KEY_F3: return XK_F3; + case KEY_F4: return XK_F4; + case KEY_F5: return XK_F5; + case KEY_F6: return XK_F6; + case KEY_F7: return XK_F7; + case KEY_F8: return XK_F8; + case KEY_F9: return XK_F9; + case KEY_F10: return XK_F10; + case KEY_NUMLOCK: return XK_Num_Lock; + case KEY_SCRLOCK: return XK_Scroll_Lock; + case KEY_HOME: return XK_Home; + case KEY_UP: return XK_Up; + case KEY_PGUP: return XK_Page_Up; + case KEY_MINUS_PAD: return XK_KP_Subtract; + case KEY_LEFT: return XK_Left; + case KEY_5_PAD: return XK_KP_5; + case KEY_RIGHT: return XK_Right; + case KEY_PLUS_PAD: return XK_KP_Add; + case KEY_END: return XK_End; + case KEY_DOWN: return XK_Down; + case KEY_PGDN: return XK_Page_Down; + case KEY_INSERT: return XK_Insert; + case KEY_DEL: return XK_Delete; + case KEY_PRTSCR: return XK_Print; + case KEY_F11: return XK_F11; + case KEY_F12: return XK_F12; + case KEY_LWIN: return XK_Meta_L; + case KEY_RWIN: return XK_Meta_R; + case KEY_MENU: return XK_Menu; + case KEY_PAD: return XK_VoidSymbol; + case KEY_RCONTROL: return XK_Control_R; + case KEY_ALTGR: return XK_Alt_R; + case KEY_SLASH2: return XK_KP_Divide; + case KEY_PAUSE: return XK_Pause; + + case NEW_KEY_BACKSLASH: return XK_backslash; + case NEW_KEY_1_PAD: return XK_KP_1; + case NEW_KEY_2_PAD: return XK_KP_2; + case NEW_KEY_3_PAD: return XK_KP_3; + case NEW_KEY_4_PAD: return XK_KP_4; + case NEW_KEY_5_PAD: return XK_KP_5; + case NEW_KEY_6_PAD: return XK_KP_6; + case NEW_KEY_7_PAD: return XK_KP_7; + case NEW_KEY_8_PAD: return XK_KP_8; + case NEW_KEY_9_PAD: return XK_KP_9; + case NEW_KEY_0_PAD: return XK_KP_0; + case NEW_KEY_STOP_PAD: return XK_KP_Separator; + case NEW_KEY_EQUALS_PAD: return XK_KP_Equal; + case NEW_KEY_SLASH_PAD: return XK_KP_Divide; + case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply; + case NEW_KEY_ENTER_PAD: return XK_KP_Enter; + + default: return XK_VoidSymbol; } - - 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) +void XMapWindow(Display *display, Window window) { int x, y; unsigned int width, height; - BOOL mouse_off; + boolean mouse_off; x = display->screens[display->default_screen].x; y = display->screens[display->default_screen].y; @@ -211,53 +244,57 @@ void XMapWindow(Display* display, Window w) 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); + blit((BITMAP *)window, video_bitmap, 0, 0, x, y, width, height); + + if (mouse_off) + unhide_mouse(display); } -Display *XOpenDisplay(char* dummy) +Display *XOpenDisplay(char *display_name) { - Screen *MyScreens; - Display *MyDisplay; - BITMAP *MyMouse = NULL; - RGB pal[256]; + Screen *screen; + Display *display; + BITMAP *mouse_bitmap = NULL; + char *filename; + + filename = getPath3(options.base_directory, GRAPHICS_DIRECTORY, + MOUSE_FILENAME); + + mouse_bitmap = Read_PCX_to_AllegroBitmap(filename); + free(filename); - MyScreens = malloc(sizeof(Screen)); - MyDisplay = malloc(sizeof(Display)); + if (mouse_bitmap == NULL) + return NULL; - if(MOUSE_FILENAME) - MyMouse = load_gif(MOUSE_FILENAME, pal); + screen = malloc(sizeof(Screen)); + display = malloc(sizeof(Display)); - MyScreens[0].cmap = 0; - MyScreens[0].root = 0; - MyScreens[0].white_pixel = 0xFF; - MyScreens[0].black_pixel = 0x00; - MyScreens[0].video_bitmap = NULL; + screen[0].cmap = 0; + screen[0].root = 0; + screen[0].white_pixel = 0xFF; + screen[0].black_pixel = 0x00; + screen[0].video_bitmap = NULL; - MyDisplay->default_screen = 0; - MyDisplay->screens = MyScreens; - MyDisplay->mouse_ptr = MyMouse; + display->default_screen = 0; + display->screens = screen; + display->mouse_ptr = mouse_bitmap; 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 + + /* force Windows 95 to switch to fullscreen mode */ + set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); rest(200); set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0); - return(MyDisplay); + return display; } -Window XCreateSimpleWindow( - Display* display, - Window parent, - int x, - int y, - unsigned int width, - unsigned int height, - unsigned int border_width, - unsigned long border, - unsigned long background) +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); @@ -269,65 +306,43 @@ Window XCreateSimpleWindow( 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); + set_mouse_speed(1, 1); + set_mouse_range(display->screens[display->default_screen].x + 1, + display->screens[display->default_screen].y + 1, + display->screens[display->default_screen].x + WIN_XSIZE + 1, + display->screens[display->default_screen].y + WIN_YSIZE + 1); show_video_bitmap(video_bitmap); - return((Window) video_bitmap); -} - -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); + return (Window)video_bitmap; } -Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return) +Status XStringListToTextProperty(char **list, int count, + XTextProperty *text_prop_return) { char *string; - if(count >= 1) + if (count >= 1) { - string = malloc(strlen(list[0]+1)); - strcpy(string, list[0]); - text_prop_return->value = (unsigned char *) string; - return(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); + text_prop_return = NULL; + + return 0; } -void XFree(void* data) +void XFree(void *data) { - if(data) free(data); + if (data) + free(data); } -GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* values) +GC XCreateGC(Display *display, Drawable d, unsigned long value_mask, + XGCValues *values) { XGCValues *gcv; gcv = malloc(sizeof(XGCValues)); @@ -338,642 +353,424 @@ GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* gcv->clip_x_origin = values->clip_x_origin; gcv->clip_y_origin = values->clip_y_origin; gcv->value_mask = value_mask; - return((GC) gcv); + return (GC)gcv; } -void XFillRectangle( - Display* display, - Drawable d, - GC gc, - int x, - int y, - unsigned int width, - unsigned int height) +void XSetClipMask(Display *display, GC gc, Pixmap pixmap) { - BOOL mouse_off; + XGCValues *gcv = (XGCValues *)gc; - if((BITMAP *) d == video_bitmap) + gcv->clip_mask = pixmap; + gcv->value_mask |= GCClipMask; +} + +void XSetClipOrigin(Display *display, GC gc, int x, int y) +{ + XGCValues *gcv = (XGCValues *)gc; + + gcv->clip_x_origin = x; + gcv->clip_x_origin = y; +} + +void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, + unsigned int width, unsigned int height) +{ + boolean mouse_off = FALSE; + + if ((BITMAP *)d == video_bitmap) { - x += display->screens[display->default_screen].x; - y += display->screens[display->default_screen].y; - freeze_mouse_flag = TRUE; - mouse_off = hide_mouse(display, x, y, width, height); + 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); + 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) +Pixmap XCreatePixmap(Display *display, Drawable d, unsigned int width, + unsigned int height, unsigned int depth) { - BITMAP *MyBitmap = NULL; + BITMAP *bitmap = NULL; + + if (gfx_capabilities & GFX_HW_VRAM_BLIT && + width == FXSIZE && height == FYSIZE) + bitmap = create_video_bitmap(width, height); - if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE) - MyBitmap = create_video_bitmap(width, height); + if (bitmap == NULL) + bitmap = create_bitmap(width, height); - if(MyBitmap == NULL) - MyBitmap = create_bitmap(width, height); + return (Pixmap)bitmap; +} - return((Pixmap) MyBitmap); +void XSync(Display *display, Bool discard_events) +{ + wait_for_vsync = TRUE; } -inline void XCopyArea( - Display* display, - Drawable src, - Drawable dest, - GC gc, - int src_x, - int src_y, - unsigned int width, - unsigned int height, - int dest_x, - int dest_y) -{ - BOOL mouse_off; - - if((BITMAP *) src == video_bitmap ) +inline void XCopyArea(Display *display, Drawable src, Drawable dest, GC gc, + int src_x, int src_y, + unsigned int width, unsigned int height, + int dest_x, int dest_y) +{ + boolean mouse_off = FALSE; + + if ((BITMAP *)src == video_bitmap) { - src_x += display->screens[display->default_screen].x; - src_y += display->screens[display->default_screen].y; + src_x += display->screens[display->default_screen].x; + src_y += display->screens[display->default_screen].y; } - if((BITMAP *) dest == video_bitmap ) + + 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); + 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) + 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); + 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); + blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y, + width, height); + + if (mouse_off) + unhide_mouse(display); - 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) +static BITMAP *Image_to_AllegroBitmap(Image *image) { - BITMAP *bmp; - RGB pal[256]; + BITMAP *bitmap; + byte *src_ptr = image->data; + byte pixel_mapping[MAX_COLORS]; + unsigned int depth = 8; + int i, j, x, y; - if((bmp = load_gif(filename, pal)) == NULL) - return(XpmOpenFailed); + /* allocate new allegro bitmap structure */ + if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL) + return NULL; - *pixmap_return = (Pixmap) bmp; - set_pallete(pal); + clear(bitmap); - return(XpmSuccess); -} + /* try to use existing colors from the global colormap */ + for (i=0; irgb.color_used[i]) + continue; + + r = image->rgb.red[i] >> 10; + g = image->rgb.green[i] >> 10; + b = image->rgb.blue[i] >> 10; + + for (j=0; jheight; y++) + for (x=0; xwidth; x++) + putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]); + + return bitmap; } -void XFreeGC(Display* display, GC gc) +static BITMAP *Read_PCX_to_AllegroBitmap(char *filename) { - XGCValues *gcv; + BITMAP *bitmap; + Image *image; - gcv = (XGCValues *) gc; - if(gcv) free(gcv); + /* read the graphic file in PCX format to internal image structure */ + if ((image = Read_PCX_to_Image(filename)) == NULL) + return NULL; + + /* convert internal image structure to allegro bitmap structure */ + if ((bitmap = Image_to_AllegroBitmap(image)) == NULL) + return NULL; + + set_pallete(global_colormap); + + return bitmap; } -void XCloseDisplay(Display* display) +int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename, + Pixmap *pixmap, Pixmap *pixmap_mask) { - BITMAP * bmp; - bmp = video_bitmap; + BITMAP *bitmap; - if(is_screen_bitmap(bmp)) - destroy_bitmap(bmp); - if(display->screens) - free(display->screens); - if(display) - free(display); + if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) + return PCX_FileInvalid; + + *pixmap = (Pixmap)bitmap; + *pixmap_mask = (Pixmap)bitmap; + + return PCX_Success; } -void XNextEvent(Display* display, XEvent* event_return) +int XpmReadFileToPixmap(Display *display, Drawable d, char *filename, + Pixmap *pixmap_return, Pixmap *shapemask_return, + XpmAttributes *attributes) { - while(!pending_events) XPending(display); + BITMAP *bitmap; - memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent)); - pending_events--; + if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) + return XpmOpenFailed; + + *pixmap_return = (Pixmap)bitmap; + + return XpmSuccess; } -int XPending(Display* display) +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) { - int i, state; - static BOOL joy_button_2 = FALSE; + BITMAP *bitmap; - XKeyEvent *xkey; - XButtonEvent *xbutton; - XMotionEvent *xmotion; + if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL) + return BitmapOpenFailed; - // joystick event (simulating keyboard event) + *width_return = bitmap->w; + *height_return = bitmap->h; + *x_hot_return = -1; + *y_hot_return = -1; + *bitmap_return = (Pixmap)bitmap; - state = get_joystick_state(); + return BitmapSuccess; +} - 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; - } +void XFreePixmap(Display *display, Pixmap pixmap) +{ + if (pixmap != DUMMY_MASK && + (is_memory_bitmap((BITMAP *)pixmap) || + is_screen_bitmap((BITMAP *)pixmap))) + destroy_bitmap((BITMAP *)pixmap); +} - 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; - } +void XFreeGC(Display *display, GC gc) +{ + XGCValues *gcv; - // keyboard event + gcv = (XGCValues *)gc; + if (gcv) + free(gcv); +} - for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++) - { - state = osd_key_pressed(i); +void XCloseDisplay(Display *display) +{ + BITMAP *bitmap = video_bitmap; - 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; - } - } + if (is_screen_bitmap(bitmap)) + destroy_bitmap(bitmap); - // mouse motion event + if (display->screens) + free(display->screens); - 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; - } + if (display) + free(display); - // mouse button event + /* return to text mode (or DOS box on Windows screen) */ + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); +} - 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; - } +void XNextEvent(Display *display, XEvent *event_return) +{ + while (!pending_events) + XPending(display); - return pending_events; + memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent)); + pending_events--; } -KeySym XLookupKeysym(XKeyEvent* key_event, int index) +static void NewKeyEvent(int key_press_state, KeySym keysym) { - return(key_event->state); + XKeyEvent *xkey; + + if (pending_events >= MAX_EVENT_BUFFER) + return; + + pending_events++; + xkey = (XKeyEvent *)&event_buffer[pending_events]; + xkey->type = key_press_state; + xkey->state = (unsigned int)keysym; } -void sound_handler(struct SoundControl snd_ctrl) +#define HANDLE_RAW_KB_ALL_KEYS 0 +#define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY 1 + +static int modifier_scancode[] = { - int i; + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_ALT, + KEY_ALTGR, + KEY_LWIN, + KEY_RWIN, + KEY_CAPSLOCK, + KEY_NUMLOCK, + KEY_SCRLOCK, + -1 +}; - if (snd_ctrl.fade_sound) - { - if (!playing_sounds) - return; +static void HandleKeyboardRaw(int mode) +{ + int i; - for(i=0;i> 8); + int ascii = (key_info & 0xff); + KeySym keysym = ScancodeToKeySym(scancode); -// GIF Loader -// by Paul Bartrum - -int _color_load_depth(int depth); + if (scancode == KEY_PAD) + { + /* keys on the numeric keypad return just scancode 'KEY_PAD' + for some reason, so we must handle them separately */ -struct LZW_STRING -{ - short base; - char new; - short length; -}; + if (ascii >= '0' && ascii <= '9') + keysym = XK_KP_0 + (KeySym)(ascii - '0'); + else if (ascii == '.') + keysym = XK_KP_Separator; + } -PACKFILE *f; -int empty_string, curr_bit_size, bit_overflow; -int bit_pos, data_pos, data_len, entire, code; -int cc, string_length, i, bit_size; -unsigned char string[4096]; -struct LZW_STRING str[4096]; -BITMAP *bmp; -int image_x, image_y, image_w, image_h, x, y; -int interlace; + NewKeyEvent(KeyPress, keysym); + } + else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)) + { + /* the allegro function keypressed() does not give us single pressed + modifier keys, so we must detect them with the internal global + allegro variable 'key_shifts' and then handle them separately */ + HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY); + } +} -void clear_table(void) +int XPending(Display *display) { - empty_string = cc + 2; - curr_bit_size = bit_size + 1; - bit_overflow = 0; -} + XButtonEvent *xbutton; + XMotionEvent *xmotion; + int i; + /* keyboard event */ + if (game_status == PLAYING) + HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS); + else + HandleKeyboardEvent(); -void get_code(void) -{ - if(bit_pos + curr_bit_size > 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 ++; - } -} + /* mouse motion event */ + /* generate mouse motion event only if any mouse buttons are pressed */ + if (mouse_pos != last_mouse_pos && 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; + } + /* mouse button event */ + if (mouse_b != last_mouse_b) + { + for (i=0; i<3; i++) /* check all three mouse buttons */ + { + int bitmask = (1 << i); -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]}-** */ - } -} + if ((last_mouse_b & bitmask) != (mouse_b & bitmask)) + { + int mapping[3] = { 1, 3, 2 }; + pending_events++; + xbutton = (XButtonEvent *)&event_buffer[pending_events]; + xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease); + xbutton->button = mapping[i]; + xbutton->x = mouse_x - display->screens[display->default_screen].x; + xbutton->y = mouse_y - display->screens[display->default_screen].y; + } + } + last_mouse_b = mouse_b; + } + + return pending_events; +} -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; - } - } - } - } - } +KeySym XLookupKeysym(XKeyEvent *key_event, int index) +{ + return key_event->state; } -/* 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; +void NetworkServer(int port, int serveronly) +{ + Error(ERR_WARN, "networking not supported in DOS version"); } -#endif +#endif /* MSDOS */