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 BOOL joystick_event;
34 static BOOL 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;
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 BOOL hide_mouse(Display *display, int x, int y, unsigned int width, unsigned int height)
77 if(mouse_x + display->mouse_ptr->w < x || mouse_x > x+width) return FALSE;
78 if(mouse_y + display->mouse_ptr->h < y || mouse_y > y+height) return FALSE;
83 void unhide_mouse(Display *display)
85 if(mouse_installed) show_mouse(video_bitmap);
88 int get_joystick_state()
93 if (joy[joystick_nr].stick[0].axis[0].d1) state |= JOY_LEFT;
94 if (joy[joystick_nr].stick[0].axis[0].d2) state |= JOY_RIGHT;
95 if (joy[joystick_nr].stick[0].axis[1].d1) state |= JOY_UP;
96 if (joy[joystick_nr].stick[0].axis[1].d2) state |= JOY_DOWN;
97 if (joy[joystick_nr].button[0].b) state |= JOY_BUTTON_1;
101 case (JOY_DOWN | JOY_LEFT):
107 case (JOY_DOWN | JOY_RIGHT):
116 case (JOY_UP | JOY_LEFT):
122 case (JOY_UP | JOY_RIGHT):
126 case (JOY_DOWN | JOY_BUTTON_1):
129 case (JOY_LEFT | JOY_BUTTON_1):
132 case (JOY_RIGHT | JOY_BUTTON_1):
135 case (JOY_UP | JOY_BUTTON_1):
146 unsigned char get_ascii(KeySym key)
150 case OSD_KEY_Q: return 'Q';
151 case OSD_KEY_W: return 'W';
152 case OSD_KEY_E: return 'E';
153 case OSD_KEY_R: return 'R';
154 case OSD_KEY_T: return 'T';
155 case OSD_KEY_Y: return 'Y';
156 case OSD_KEY_U: return 'U';
157 case OSD_KEY_I: return 'I';
158 case OSD_KEY_O: return 'O';
159 case OSD_KEY_P: return 'P';
160 case OSD_KEY_A: return 'A';
161 case OSD_KEY_S: return 'S';
162 case OSD_KEY_D: return 'D';
163 case OSD_KEY_F: return 'F';
164 case OSD_KEY_G: return 'G';
165 case OSD_KEY_H: return 'H';
166 case OSD_KEY_J: return 'J';
167 case OSD_KEY_K: return 'K';
168 case OSD_KEY_L: return 'L';
169 case OSD_KEY_Z: return 'Z';
170 case OSD_KEY_X: return 'X';
171 case OSD_KEY_C: return 'C';
172 case OSD_KEY_V: return 'V';
173 case OSD_KEY_B: return 'B';
174 case OSD_KEY_N: return 'N';
175 case OSD_KEY_M: return 'M';
176 case OSD_KEY_1: return '1';
177 case OSD_KEY_2: return '2';
178 case OSD_KEY_3: return '3';
179 case OSD_KEY_4: return '4';
180 case OSD_KEY_5: return '5';
181 case OSD_KEY_6: return '6';
182 case OSD_KEY_7: return '7';
183 case OSD_KEY_8: return '8';
184 case OSD_KEY_9: return '9';
185 case OSD_KEY_0: return '0';
186 case OSD_KEY_SPACE: return ' ';
191 long osd_key_pressed(int keycode)
193 if (keycode == OSD_KEY_RCONTROL) keycode = KEY_RCONTROL;
194 if (keycode == OSD_KEY_ALTGR) keycode = KEY_ALTGR;
197 return(KeyPressMask);
199 return(KeyReleaseMask);
202 void XMapWindow(Display* display, Window w)
205 unsigned int width, height;
208 x = display->screens[display->default_screen].x;
209 y = display->screens[display->default_screen].y;
210 width = display->screens[display->default_screen].width;
211 height = display->screens[display->default_screen].height;
213 mouse_off = hide_mouse(display, x, y, width, height);
214 blit((BITMAP *)w, video_bitmap, 0, 0, x, y, width, height);
215 if(mouse_off) unhide_mouse(display);
218 Display *XOpenDisplay(char* dummy)
222 BITMAP *MyMouse = NULL;
225 MyScreens = malloc(sizeof(Screen));
226 MyDisplay = malloc(sizeof(Display));
229 MyMouse = load_gif(MOUSE_FILENAME, pal);
231 MyScreens[0].cmap = 0;
232 MyScreens[0].root = 0;
233 MyScreens[0].white_pixel = 0xFF;
234 MyScreens[0].black_pixel = 0x00;
235 MyScreens[0].video_bitmap = NULL;
237 MyDisplay->default_screen = 0;
238 MyDisplay->screens = MyScreens;
239 MyDisplay->mouse_ptr = MyMouse;
244 set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); // force Windows 95 to switch to fullscreen mode
246 set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
251 Window XCreateSimpleWindow(
258 unsigned int border_width,
259 unsigned long border,
260 unsigned long background)
262 video_bitmap = create_video_bitmap(XRES, YRES);
263 clear_to_color(video_bitmap, background);
265 display->screens[display->default_screen].video_bitmap = video_bitmap;
266 display->screens[display->default_screen].x = x;
267 display->screens[display->default_screen].y = y;
268 display->screens[display->default_screen].width = XRES;
269 display->screens[display->default_screen].height = YRES;
271 set_mouse_sprite(display->mouse_ptr);
272 set_mouse_range(display->screens[display->default_screen].x+1,
273 display->screens[display->default_screen].y+1,
274 display->screens[display->default_screen].x+WIN_XSIZE+1,
275 display->screens[display->default_screen].y+WIN_YSIZE+1);
277 show_video_bitmap(video_bitmap);
279 return((Window) video_bitmap);
286 unsigned int* width_return,
287 unsigned int* height_return,
288 Pixmap* bitmap_return,
295 if((bmp = load_gif(filename, pal)) == NULL)
296 return(BitmapOpenFailed);
298 *width_return = bmp->w;
299 *height_return = bmp->h;
302 *bitmap_return = (Pixmap) bmp;
304 return(BitmapSuccess);
307 Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return)
313 string = malloc(strlen(list[0]+1));
314 strcpy(string, list[0]);
315 text_prop_return->value = (unsigned char *) string;
320 text_prop_return = NULL;
325 void XFree(void* data)
330 GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* values)
333 gcv = malloc(sizeof(XGCValues));
334 gcv->foreground = values->foreground;
335 gcv->background = values->background;
336 gcv->graphics_exposures = values->graphics_exposures;
337 gcv->clip_mask = values->clip_mask;
338 gcv->clip_x_origin = values->clip_x_origin;
339 gcv->clip_y_origin = values->clip_y_origin;
340 gcv->value_mask = value_mask;
355 if((BITMAP *) d == video_bitmap)
357 x += display->screens[display->default_screen].x;
358 y += display->screens[display->default_screen].y;
359 freeze_mouse_flag = TRUE;
360 mouse_off = hide_mouse(display, x, y, width, height);
363 rectfill((BITMAP *) d, x, y, x+width, y+height, ((XGCValues *)gc)->foreground);
364 if(mouse_off) unhide_mouse(display);
365 freeze_mouse_flag = FALSE;
368 Pixmap XCreatePixmap(
375 BITMAP *MyBitmap = NULL;
377 if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE)
378 MyBitmap = create_video_bitmap(width, height);
381 MyBitmap = create_bitmap(width, height);
383 return((Pixmap) MyBitmap);
386 inline void XCopyArea(
400 if((BITMAP *) src == video_bitmap )
402 src_x += display->screens[display->default_screen].x;
403 src_y += display->screens[display->default_screen].y;
405 if((BITMAP *) dest == video_bitmap )
407 dest_x += display->screens[display->default_screen].x;
408 dest_y += display->screens[display->default_screen].y;
409 freeze_mouse_flag = TRUE;
410 mouse_off = hide_mouse(display, dest_x, dest_y, width, height);
415 wait_for_vsync = FALSE;
419 if(((XGCValues *)gc)->value_mask&GCClipMask)
420 masked_blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
422 blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
424 if(mouse_off) unhide_mouse(display);
425 freeze_mouse_flag = FALSE;
428 int XpmReadFileToPixmap(
432 Pixmap* pixmap_return,
433 Pixmap* shapemask_return,
434 XpmAttributes* attributes)
439 if((bmp = load_gif(filename, pal)) == NULL)
440 return(XpmOpenFailed);
442 *pixmap_return = (Pixmap) bmp;
448 void XFreePixmap(Display* display, Pixmap pixmap)
450 if( pixmap != DUMMY_MASK &&
451 (is_memory_bitmap((BITMAP *) pixmap) || is_screen_bitmap((BITMAP *) pixmap)) )
452 destroy_bitmap((BITMAP *) pixmap);
455 void XFreeGC(Display* display, GC gc)
459 gcv = (XGCValues *) gc;
463 void XCloseDisplay(Display* display)
468 if(is_screen_bitmap(bmp))
471 free(display->screens);
476 void XNextEvent(Display* display, XEvent* event_return)
478 while(!pending_events) XPending(display);
480 memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
484 int XPending(Display* display)
487 static BOOL joy_button_2 = FALSE;
490 XButtonEvent *xbutton;
491 XMotionEvent *xmotion;
493 // joystick event (simulating keyboard event)
495 state = get_joystick_state();
497 if (joy[joystick_nr].button[1].b && !joy_button_2)
500 xkey = (XKeyEvent *) &event_buffer[pending_events];
501 xkey->type = KeyPress;
505 else if (!joy[joystick_nr].button[1].b && joy_button_2)
508 xkey = (XKeyEvent *) &event_buffer[pending_events];
509 xkey->type = KeyRelease;
511 joy_button_2 = FALSE;
514 if(state && !joystick_event)
517 xkey = (XKeyEvent *) &event_buffer[pending_events];
518 xkey->type = KeyPress;
520 joystick_event = TRUE;
521 last_joystick_state = state;
523 else if((state != last_joystick_state) && joystick_event)
526 xkey = (XKeyEvent *) &event_buffer[pending_events];
527 xkey->type = KeyRelease;
528 xkey->state = last_joystick_state;
529 joystick_event = FALSE;
534 for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++)
536 state = osd_key_pressed(i);
538 if(state != key_buffer[i])
540 key_buffer[i] = state;
542 xkey = (XKeyEvent *) &event_buffer[pending_events];
543 xkey->type = state&KeyPressMask ? KeyPress : KeyRelease;
548 // mouse motion event
550 if((mouse_pos != last_mouse_pos && mouse_b != last_mouse_b))
552 last_mouse_pos = mouse_pos;
554 xmotion = (XMotionEvent *) &event_buffer[pending_events];
555 xmotion->type = MotionNotify;
556 xmotion->x = mouse_x - display->screens[display->default_screen].x;
557 xmotion->y = mouse_y - display->screens[display->default_screen].y;
561 // mouse button event
563 if(mouse_b != last_mouse_b)
565 for(i = 1; i<4; i<<=1)
567 if((last_mouse_b&i) != (mouse_b&i))
570 xbutton = (XButtonEvent *) &event_buffer[pending_events];
571 xbutton->type = mouse_b&i ? ButtonPress : ButtonRelease;
573 xbutton->x = mouse_x - display->screens[display->default_screen].x;
574 xbutton->y = mouse_y - display->screens[display->default_screen].y;
577 last_mouse_b = mouse_b;
580 return pending_events;
583 KeySym XLookupKeysym(XKeyEvent* key_event, int index)
585 return(key_event->state);
588 void sound_handler(struct SoundControl snd_ctrl)
592 if (snd_ctrl.fade_sound)
597 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
598 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) && !playlist[i].fade_sound) {
599 playlist[i].fade_sound = TRUE;
600 if(voice_check(playlist[i].voice))
601 voice_ramp_volume(playlist[i].voice, 1000, 0);
602 playlist[i].loop = PSND_NO_LOOP;
605 else if (snd_ctrl.stop_all_sounds)
609 SoundServer_StopAllSounds();
611 else if (snd_ctrl.stop_sound)
615 SoundServer_StopSound(snd_ctrl.nr);
618 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
620 if (!playlist[i].active || playlist[i].loop)
623 playlist[i].playingpos = voice_get_position(playlist[i].voice);
624 playlist[i].volume = voice_get_volume(playlist[i].voice);
625 if (playlist[i].playingpos == -1 || !playlist[i].volume)
627 deallocate_voice(playlist[i].voice);
628 playlist[i] = emptySoundControl;
634 SoundServer_InsertNewSound(snd_ctrl);
642 int _color_load_depth(int depth);
652 int empty_string, curr_bit_size, bit_overflow;
653 int bit_pos, data_pos, data_len, entire, code;
654 int cc, string_length, i, bit_size;
655 unsigned char string[4096];
656 struct LZW_STRING str[4096];
658 int image_x, image_y, image_w, image_h, x, y;
662 void clear_table(void)
664 empty_string = cc + 2;
665 curr_bit_size = bit_size + 1;
672 if(bit_pos + curr_bit_size > 8) {
673 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
674 entire = (pack_getc(f) << 8) + entire;
677 if(bit_pos + curr_bit_size > 16) {
678 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
679 entire = (pack_getc(f) << 16) + entire;
682 code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1);
683 if(bit_pos + curr_bit_size > 8)
685 if(bit_pos + curr_bit_size > 16)
687 bit_pos = (bit_pos + curr_bit_size) % 8;
689 if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
690 entire = pack_getc(f);
696 void get_string(int num)
701 string[0] = str[num].new;
710 string[i] = str[num].new;
713 /* if(num != -1) **-{[ERROR]}-** */
718 void output_string(void)
720 for(i = 0; i < string_length; i ++)
722 putpixel(bmp, x, y, string[i]);
724 if(x >= image_x + image_w)
730 if(y >= image_y + image_h)
732 if(interlace == 8 && (y - image_y) % 8 == 0) {
736 else if(interlace == 8 && (y - image_y) % 8 == 4) {
740 else if(interlace == 4) {
751 * Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap
752 * structure and storing the pallete data in the specified pallete (this
753 * should be an array of at least 256 RGB structures).
755 BITMAP *load_gif(char *filename, RGB *pal)
757 int width, height, depth;
762 f = pack_fopen(filename, F_READ);
763 if (!f) /* can't open file */
766 i = pack_mgetw(f) << 8;
768 if(i != 0x474946) /* is it really a GIF? */
773 pack_fseek(f, 3); /* skip version */
775 width = pack_igetw(f);
776 height = pack_igetw(f);
778 bmp = create_bitmap_ex(8, width, height);
786 if(i & 128) /* no global colour table? */
791 pack_fseek(f, 2); /* skip background colour and aspect ratio */
793 if(pal && depth) /* only read palette if pal and depth are not 0 */
795 for(i = 0; i < (1 << depth); i ++)
797 pal[i].r = pack_getc(f) / 4;
798 pal[i].g = pack_getc(f) / 4;
799 pal[i].b = pack_getc(f) / 4;
804 pack_fseek(f, (1 << depth) * 3);
811 case 0x2C: /* Image Descriptor */
812 image_x = pack_igetw(f);
813 image_y = pack_igetw(f); /* individual image dimensions */
814 image_w = pack_igetw(f);
815 image_h = pack_igetw(f);
828 for(i = 0; i < (1 << depth); i ++)
830 pal[i].r = pack_getc(f) / 4;
831 pal[i].g = pack_getc(f) / 4;
832 pal[i].b = pack_getc(f) / 4;
836 pack_fseek(f, (1 << depth) * 3);
839 /* lzw stream starts now */
840 bit_size = pack_getc(f);
843 /* initialise string table */
844 for(i = 0; i < cc; i ++)
851 /* initialise the variables */
853 data_len = pack_getc(f); data_pos = 0;
854 entire = pack_getc(f); data_pos ++;
855 string_length = 0; x = image_x; y = image_y;
879 else if(code == cc + 1)
883 else if(code < empty_string)
888 if(bit_overflow == 0) {
889 str[empty_string].base = old;
890 str[empty_string].new = string[0];
891 str[empty_string].length = str[old].length + 1;
893 if(empty_string == (1 << curr_bit_size))
895 if(curr_bit_size == 13) {
906 string[str[old].length] = string[0];
909 if(bit_overflow == 0) {
910 str[empty_string].base = old;
911 str[empty_string].new = string[0];
912 str[empty_string].length = str[old].length + 1;
914 if(empty_string == (1 << curr_bit_size))
916 if(curr_bit_size == 13) {
927 case 0x21: /* Extension Introducer */
929 if(i == 0xF9) /* Graphic Control Extension */
931 pack_fseek(f, 1); /* skip size (it's 4) */
933 if(i & 1) /* is transparency enabled? */
936 pack_getc(f); /* transparent colour */
942 while(i) /* skip Data Sub-blocks */
948 case 0x3B: /* Trailer - end of data */
951 /* convert to correct colour depth */
952 dest_depth = _color_load_depth(8);
956 bmp2 = create_bitmap_ex(dest_depth, bmp->w, bmp->h);
964 blit(bmp, bmp2, 0, 0, 0, 0, bmp->w, bmp->h);
975 /* this is never executed but DJGPP complains if you leave it out */