1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
21 DECLARE_GFX_DRIVER_LIST(
25 DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8)
26 DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB)
27 DECLARE_MIDI_DRIVER_LIST()
28 DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD)
30 static int key_buffer[OSD_MAX_KEY];
31 static XEvent event_buffer[MAX_EVENT_BUFFER];
32 static int pending_events;
33 static boolean joystick_event;
34 static boolean mouse_installed = FALSE;
35 static int last_mouse_pos;
36 static int last_mouse_b;
37 static int last_joystick_state;
38 static BITMAP* video_bitmap;
40 boolean wait_for_vsync;
42 extern int playing_sounds;
43 extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
44 extern struct SoundControl emptySoundControl;
46 void allegro_drivers()
50 for(i = 0; i < MAX_EVENT_BUFFER; i++);
51 event_buffer[i].type = 0;
52 for(i=0; i < OSD_MAX_KEY; i++) key_buffer[i] = KeyReleaseMask;
53 last_mouse_pos = mouse_pos;
62 if (install_mouse() > 0) mouse_installed = TRUE;
63 install_joystick(JOY_TYPE_2PADS);
65 load_joystick_data(JOYDAT_FILE);
66 last_joystick_state = 0;
67 joystick_event = FALSE;
69 reserve_voices(MAX_SOUNDS_PLAYING, 0);
70 if(install_sound(DIGI_AUTODETECT, MIDI_NONE, "ROCKS.SND") == -1)
71 if(install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) sound_status = SOUND_OFF;
75 boolean hide_mouse(Display *display, int x, int y,
76 unsigned int width, unsigned int height)
78 if(mouse_x + display->mouse_ptr->w < x || mouse_x > x+width) return FALSE;
79 if(mouse_y + display->mouse_ptr->h < y || mouse_y > y+height) return FALSE;
84 void unhide_mouse(Display *display)
86 if(mouse_installed) show_mouse(video_bitmap);
89 int get_joystick_state()
94 if (joy[joystick_nr].stick[0].axis[0].d1) state |= JOY_LEFT;
95 if (joy[joystick_nr].stick[0].axis[0].d2) state |= JOY_RIGHT;
96 if (joy[joystick_nr].stick[0].axis[1].d1) state |= JOY_UP;
97 if (joy[joystick_nr].stick[0].axis[1].d2) state |= JOY_DOWN;
98 if (joy[joystick_nr].button[0].b) state |= JOY_BUTTON_1;
102 case (JOY_DOWN | JOY_LEFT):
108 case (JOY_DOWN | JOY_RIGHT):
117 case (JOY_UP | JOY_LEFT):
123 case (JOY_UP | JOY_RIGHT):
127 case (JOY_DOWN | JOY_BUTTON_1):
130 case (JOY_LEFT | JOY_BUTTON_1):
133 case (JOY_RIGHT | JOY_BUTTON_1):
136 case (JOY_UP | JOY_BUTTON_1):
147 unsigned char get_ascii(KeySym key)
151 case OSD_KEY_Q: return 'Q';
152 case OSD_KEY_W: return 'W';
153 case OSD_KEY_E: return 'E';
154 case OSD_KEY_R: return 'R';
155 case OSD_KEY_T: return 'T';
156 case OSD_KEY_Y: return 'Y';
157 case OSD_KEY_U: return 'U';
158 case OSD_KEY_I: return 'I';
159 case OSD_KEY_O: return 'O';
160 case OSD_KEY_P: return 'P';
161 case OSD_KEY_A: return 'A';
162 case OSD_KEY_S: return 'S';
163 case OSD_KEY_D: return 'D';
164 case OSD_KEY_F: return 'F';
165 case OSD_KEY_G: return 'G';
166 case OSD_KEY_H: return 'H';
167 case OSD_KEY_J: return 'J';
168 case OSD_KEY_K: return 'K';
169 case OSD_KEY_L: return 'L';
170 case OSD_KEY_Z: return 'Z';
171 case OSD_KEY_X: return 'X';
172 case OSD_KEY_C: return 'C';
173 case OSD_KEY_V: return 'V';
174 case OSD_KEY_B: return 'B';
175 case OSD_KEY_N: return 'N';
176 case OSD_KEY_M: return 'M';
177 case OSD_KEY_1: return '1';
178 case OSD_KEY_2: return '2';
179 case OSD_KEY_3: return '3';
180 case OSD_KEY_4: return '4';
181 case OSD_KEY_5: return '5';
182 case OSD_KEY_6: return '6';
183 case OSD_KEY_7: return '7';
184 case OSD_KEY_8: return '8';
185 case OSD_KEY_9: return '9';
186 case OSD_KEY_0: return '0';
187 case OSD_KEY_SPACE: return ' ';
192 long osd_key_pressed(int keycode)
194 if (keycode == OSD_KEY_RCONTROL) keycode = KEY_RCONTROL;
195 if (keycode == OSD_KEY_ALTGR) keycode = KEY_ALTGR;
198 return(KeyPressMask);
200 return(KeyReleaseMask);
203 void XMapWindow(Display* display, Window w)
206 unsigned int width, height;
209 x = display->screens[display->default_screen].x;
210 y = display->screens[display->default_screen].y;
211 width = display->screens[display->default_screen].width;
212 height = display->screens[display->default_screen].height;
214 mouse_off = hide_mouse(display, x, y, width, height);
215 blit((BITMAP *)w, video_bitmap, 0, 0, x, y, width, height);
216 if(mouse_off) unhide_mouse(display);
219 Display *XOpenDisplay(char* dummy)
223 BITMAP *MyMouse = NULL;
226 MyScreens = malloc(sizeof(Screen));
227 MyDisplay = malloc(sizeof(Display));
230 MyMouse = load_gif(MOUSE_FILENAME, pal);
232 MyScreens[0].cmap = 0;
233 MyScreens[0].root = 0;
234 MyScreens[0].white_pixel = 0xFF;
235 MyScreens[0].black_pixel = 0x00;
236 MyScreens[0].video_bitmap = NULL;
238 MyDisplay->default_screen = 0;
239 MyDisplay->screens = MyScreens;
240 MyDisplay->mouse_ptr = MyMouse;
245 set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); // force Windows 95 to switch to fullscreen mode
247 set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
252 Window XCreateSimpleWindow(
259 unsigned int border_width,
260 unsigned long border,
261 unsigned long background)
263 video_bitmap = create_video_bitmap(XRES, YRES);
264 clear_to_color(video_bitmap, background);
266 display->screens[display->default_screen].video_bitmap = video_bitmap;
267 display->screens[display->default_screen].x = x;
268 display->screens[display->default_screen].y = y;
269 display->screens[display->default_screen].width = XRES;
270 display->screens[display->default_screen].height = YRES;
272 set_mouse_sprite(display->mouse_ptr);
273 set_mouse_range(display->screens[display->default_screen].x+1,
274 display->screens[display->default_screen].y+1,
275 display->screens[display->default_screen].x+WIN_XSIZE+1,
276 display->screens[display->default_screen].y+WIN_YSIZE+1);
278 show_video_bitmap(video_bitmap);
280 return((Window) video_bitmap);
287 unsigned int* width_return,
288 unsigned int* height_return,
289 Pixmap* bitmap_return,
296 if((bmp = load_gif(filename, pal)) == NULL)
297 return(BitmapOpenFailed);
299 *width_return = bmp->w;
300 *height_return = bmp->h;
303 *bitmap_return = (Pixmap) bmp;
305 return(BitmapSuccess);
308 Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return)
314 string = malloc(strlen(list[0]+1));
315 strcpy(string, list[0]);
316 text_prop_return->value = (unsigned char *) string;
321 text_prop_return = NULL;
326 void XFree(void* data)
331 GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* values)
334 gcv = malloc(sizeof(XGCValues));
335 gcv->foreground = values->foreground;
336 gcv->background = values->background;
337 gcv->graphics_exposures = values->graphics_exposures;
338 gcv->clip_mask = values->clip_mask;
339 gcv->clip_x_origin = values->clip_x_origin;
340 gcv->clip_y_origin = values->clip_y_origin;
341 gcv->value_mask = value_mask;
356 if((BITMAP *) d == video_bitmap)
358 x += display->screens[display->default_screen].x;
359 y += display->screens[display->default_screen].y;
360 freeze_mouse_flag = TRUE;
361 mouse_off = hide_mouse(display, x, y, width, height);
364 rectfill((BITMAP *) d, x, y, x+width, y+height, ((XGCValues *)gc)->foreground);
365 if(mouse_off) unhide_mouse(display);
366 freeze_mouse_flag = FALSE;
369 Pixmap XCreatePixmap(
376 BITMAP *MyBitmap = NULL;
378 if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE)
379 MyBitmap = create_video_bitmap(width, height);
382 MyBitmap = create_bitmap(width, height);
384 return((Pixmap) MyBitmap);
387 inline void XCopyArea(
401 if((BITMAP *) src == video_bitmap )
403 src_x += display->screens[display->default_screen].x;
404 src_y += display->screens[display->default_screen].y;
406 if((BITMAP *) dest == video_bitmap )
408 dest_x += display->screens[display->default_screen].x;
409 dest_y += display->screens[display->default_screen].y;
410 freeze_mouse_flag = TRUE;
411 mouse_off = hide_mouse(display, dest_x, dest_y, width, height);
416 wait_for_vsync = FALSE;
420 if(((XGCValues *)gc)->value_mask&GCClipMask)
421 masked_blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
423 blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
425 if(mouse_off) unhide_mouse(display);
426 freeze_mouse_flag = FALSE;
429 int XpmReadFileToPixmap(
433 Pixmap* pixmap_return,
434 Pixmap* shapemask_return,
435 XpmAttributes* attributes)
440 if((bmp = load_gif(filename, pal)) == NULL)
441 return(XpmOpenFailed);
443 *pixmap_return = (Pixmap) bmp;
449 void XFreePixmap(Display* display, Pixmap pixmap)
451 if( pixmap != DUMMY_MASK &&
452 (is_memory_bitmap((BITMAP *) pixmap) || is_screen_bitmap((BITMAP *) pixmap)) )
453 destroy_bitmap((BITMAP *) pixmap);
456 void XFreeGC(Display* display, GC gc)
460 gcv = (XGCValues *) gc;
464 void XCloseDisplay(Display* display)
469 if(is_screen_bitmap(bmp))
472 free(display->screens);
477 void XNextEvent(Display* display, XEvent* event_return)
479 while(!pending_events) XPending(display);
481 memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
485 int XPending(Display* display)
488 static boolean joy_button_2 = FALSE;
491 XButtonEvent *xbutton;
492 XMotionEvent *xmotion;
494 // joystick event (simulating keyboard event)
496 state = get_joystick_state();
498 if (joy[joystick_nr].button[1].b && !joy_button_2)
501 xkey = (XKeyEvent *) &event_buffer[pending_events];
502 xkey->type = KeyPress;
506 else if (!joy[joystick_nr].button[1].b && joy_button_2)
509 xkey = (XKeyEvent *) &event_buffer[pending_events];
510 xkey->type = KeyRelease;
512 joy_button_2 = FALSE;
515 if(state && !joystick_event)
518 xkey = (XKeyEvent *) &event_buffer[pending_events];
519 xkey->type = KeyPress;
521 joystick_event = TRUE;
522 last_joystick_state = state;
524 else if((state != last_joystick_state) && joystick_event)
527 xkey = (XKeyEvent *) &event_buffer[pending_events];
528 xkey->type = KeyRelease;
529 xkey->state = last_joystick_state;
530 joystick_event = FALSE;
535 for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++)
537 state = osd_key_pressed(i);
539 if(state != key_buffer[i])
541 key_buffer[i] = state;
543 xkey = (XKeyEvent *) &event_buffer[pending_events];
544 xkey->type = state&KeyPressMask ? KeyPress : KeyRelease;
549 // mouse motion event
551 if((mouse_pos != last_mouse_pos && mouse_b != last_mouse_b))
553 last_mouse_pos = mouse_pos;
555 xmotion = (XMotionEvent *) &event_buffer[pending_events];
556 xmotion->type = MotionNotify;
557 xmotion->x = mouse_x - display->screens[display->default_screen].x;
558 xmotion->y = mouse_y - display->screens[display->default_screen].y;
562 // mouse button event
564 if(mouse_b != last_mouse_b)
566 for(i = 1; i<4; i<<=1)
568 if((last_mouse_b&i) != (mouse_b&i))
571 xbutton = (XButtonEvent *) &event_buffer[pending_events];
572 xbutton->type = mouse_b&i ? ButtonPress : ButtonRelease;
574 xbutton->x = mouse_x - display->screens[display->default_screen].x;
575 xbutton->y = mouse_y - display->screens[display->default_screen].y;
578 last_mouse_b = mouse_b;
581 return pending_events;
584 KeySym XLookupKeysym(XKeyEvent* key_event, int index)
586 return(key_event->state);
589 void sound_handler(struct SoundControl snd_ctrl)
593 if (snd_ctrl.fade_sound)
598 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
599 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) && !playlist[i].fade_sound) {
600 playlist[i].fade_sound = TRUE;
601 if(voice_check(playlist[i].voice))
602 voice_ramp_volume(playlist[i].voice, 1000, 0);
603 playlist[i].loop = PSND_NO_LOOP;
606 else if (snd_ctrl.stop_all_sounds)
610 SoundServer_StopAllSounds();
612 else if (snd_ctrl.stop_sound)
616 SoundServer_StopSound(snd_ctrl.nr);
619 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
621 if (!playlist[i].active || playlist[i].loop)
624 playlist[i].playingpos = voice_get_position(playlist[i].voice);
625 playlist[i].volume = voice_get_volume(playlist[i].voice);
626 if (playlist[i].playingpos == -1 || !playlist[i].volume)
628 deallocate_voice(playlist[i].voice);
629 playlist[i] = emptySoundControl;
635 SoundServer_InsertNewSound(snd_ctrl);
643 int _color_load_depth(int depth);
653 int empty_string, curr_bit_size, bit_overflow;
654 int bit_pos, data_pos, data_len, entire, code;
655 int cc, string_length, i, bit_size;
656 unsigned char string[4096];
657 struct LZW_STRING str[4096];
659 int image_x, image_y, image_w, image_h, x, y;
663 void clear_table(void)
665 empty_string = cc + 2;
666 curr_bit_size = bit_size + 1;
673 if(bit_pos + curr_bit_size > 8) {
674 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
675 entire = (pack_getc(f) << 8) + entire;
678 if(bit_pos + curr_bit_size > 16) {
679 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
680 entire = (pack_getc(f) << 16) + entire;
683 code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1);
684 if(bit_pos + curr_bit_size > 8)
686 if(bit_pos + curr_bit_size > 16)
688 bit_pos = (bit_pos + curr_bit_size) % 8;
690 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
691 entire = pack_getc(f);
697 void get_string(int num)
702 string[0] = str[num].new;
711 string[i] = str[num].new;
714 /* if(num != -1) **-{[ERROR]}-** */
719 void output_string(void)
721 for(i = 0; i < string_length; i ++)
723 putpixel(bmp, x, y, string[i]);
725 if(x >= image_x + image_w)
731 if(y >= image_y + image_h)
733 if(interlace == 8 && (y - image_y) % 8 == 0) {
737 else if(interlace == 8 && (y - image_y) % 8 == 4) {
741 else if(interlace == 4) {
752 * Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap
753 * structure and storing the pallete data in the specified pallete (this
754 * should be an array of at least 256 RGB structures).
756 BITMAP *load_gif(char *filename, RGB *pal)
758 int width, height, depth;
763 f = pack_fopen(filename, F_READ);
764 if (!f) /* can't open file */
767 i = pack_mgetw(f) << 8;
769 if(i != 0x474946) /* is it really a GIF? */
774 pack_fseek(f, 3); /* skip version */
776 width = pack_igetw(f);
777 height = pack_igetw(f);
779 bmp = create_bitmap_ex(8, width, height);
787 if(i & 128) /* no global colour table? */
792 pack_fseek(f, 2); /* skip background colour and aspect ratio */
794 if(pal && depth) /* only read palette if pal and depth are not 0 */
796 for(i = 0; i < (1 << depth); i ++)
798 pal[i].r = pack_getc(f) / 4;
799 pal[i].g = pack_getc(f) / 4;
800 pal[i].b = pack_getc(f) / 4;
805 pack_fseek(f, (1 << depth) * 3);
812 case 0x2C: /* Image Descriptor */
813 image_x = pack_igetw(f);
814 image_y = pack_igetw(f); /* individual image dimensions */
815 image_w = pack_igetw(f);
816 image_h = pack_igetw(f);
829 for(i = 0; i < (1 << depth); i ++)
831 pal[i].r = pack_getc(f) / 4;
832 pal[i].g = pack_getc(f) / 4;
833 pal[i].b = pack_getc(f) / 4;
837 pack_fseek(f, (1 << depth) * 3);
840 /* lzw stream starts now */
841 bit_size = pack_getc(f);
844 /* initialise string table */
845 for(i = 0; i < cc; i ++)
852 /* initialise the variables */
854 data_len = pack_getc(f); data_pos = 0;
855 entire = pack_getc(f); data_pos ++;
856 string_length = 0; x = image_x; y = image_y;
880 else if(code == cc + 1)
884 else if(code < empty_string)
889 if(bit_overflow == 0) {
890 str[empty_string].base = old;
891 str[empty_string].new = string[0];
892 str[empty_string].length = str[old].length + 1;
894 if(empty_string == (1 << curr_bit_size))
896 if(curr_bit_size == 13) {
907 string[str[old].length] = string[0];
910 if(bit_overflow == 0) {
911 str[empty_string].base = old;
912 str[empty_string].new = string[0];
913 str[empty_string].length = str[old].length + 1;
915 if(empty_string == (1 << curr_bit_size))
917 if(curr_bit_size == 13) {
928 case 0x21: /* Extension Introducer */
930 if(i == 0xF9) /* Graphic Control Extension */
932 pack_fseek(f, 1); /* skip size (it's 4) */
934 if(i & 1) /* is transparency enabled? */
937 pack_getc(f); /* transparent colour */
943 while(i) /* skip Data Sub-blocks */
949 case 0x3B: /* Trailer - end of data */
952 /* convert to correct colour depth */
953 dest_depth = _color_load_depth(8);
957 bmp2 = create_bitmap_ex(dest_depth, bmp->w, bmp->h);
965 blit(bmp, bmp2, 0, 0, 0, 0, bmp->w, bmp->h);
976 /* this is never executed but DJGPP complains if you leave it out */