--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* msdos.c *
+***********************************************************/
+
+#ifdef MSDOS
+#include "main.h"
+#include "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 BOOL joystick_event;
+static BOOL 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;
+
+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;
+
+}
+
+BOOL 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;
+ BOOL 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)
+{
+ BOOL 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)
+{
+ BOOL 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 BOOL 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<MAX_SOUNDS_PLAYING;i++)
+ if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) && !playlist[i].fade_sound) {
+ playlist[i].fade_sound = TRUE;
+ if(voice_check(playlist[i].voice))
+ voice_ramp_volume(playlist[i].voice, 1000, 0);
+ playlist[i].loop = PSND_NO_LOOP;
+ }
+ }
+ else if (snd_ctrl.stop_all_sounds)
+ {
+ if (!playing_sounds)
+ return;
+ SoundServer_StopAllSounds();
+ }
+ else if (snd_ctrl.stop_sound)
+ {
+ if (!playing_sounds)
+ return;
+ SoundServer_StopSound(snd_ctrl.nr);
+ }
+
+ for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+ {
+ if (!playlist[i].active || playlist[i].loop)
+ continue;
+
+ playlist[i].playingpos = voice_get_position(playlist[i].voice);
+ playlist[i].volume = voice_get_volume(playlist[i].voice);
+ if (playlist[i].playingpos == -1 || !playlist[i].volume)
+ {
+ deallocate_voice(playlist[i].voice);
+ playlist[i] = emptySoundControl;
+ playing_sounds--;
+ }
+ }
+
+ if (snd_ctrl.active)
+ SoundServer_InsertNewSound(snd_ctrl);
+
+}
+
+
+// GIF Loader
+// by Paul Bartrum
+
+int _color_load_depth(int depth);
+
+struct LZW_STRING
+{
+ short base;
+ char new;
+ short length;
+};
+
+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;
+
+
+void clear_table(void)
+{
+ empty_string = cc + 2;
+ curr_bit_size = bit_size + 1;
+ bit_overflow = 0;
+}
+
+
+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 ++;
+ }
+}
+
+
+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
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* ©1995 Artsoft Development *
+* Holger Schemel *
+* 33659 Bielefeld-Senne *
+* Telefon: (0521) 493245 *
+* eMail: aeglos@valinor.owl.de *
+* aeglos@uni-paderborn.de *
+* q99492@pbhrzx.uni-paderborn.de *
+*----------------------------------------------------------*
+* msdos.h *
+***********************************************************/
+
+#ifndef XPM_INCLUDE_FILE
+#define XPM_INCLUDE_FILE
+#endif
+
+#define XRES 800
+#define YRES 600
+
+#define TRUE 1
+#define FALSE 0
+
+#include <allegro.h>
+#include <time.h>
+
+// 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);
\ No newline at end of file