1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
17 #if defined(PLATFORM_MSDOS)
25 #define AllegroDefaultScreen() (display->screens[display->default_screen])
27 /* allegro driver declarations */
28 DECLARE_GFX_DRIVER_LIST(GFX_DRIVER_VBEAF GFX_DRIVER_VESA2L GFX_DRIVER_VESA1)
29 DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8)
30 DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB)
31 DECLARE_MIDI_DRIVER_LIST()
32 DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD)
34 /* allegro global variables */
35 extern volatile int key_shifts;
36 extern int num_joysticks;
37 extern JOYSTICK_INFO joy[];
38 extern int i_love_bill;
40 /* internal variables of msdos.c */
41 static boolean keyboard_auto_repeat = TRUE;
42 static int key_press_state[MAX_SCANCODES];
43 static XEvent event_buffer[MAX_EVENT_BUFFER];
44 static int pending_events;
45 static boolean joystick_event;
46 static boolean mouse_installed = FALSE;
47 static int last_mouse_pos;
48 static int last_mouse_b;
49 static int last_joystick_state;
50 static BITMAP* video_bitmap;
52 static RGB global_colormap[MAX_COLORS];
53 static int global_colormap_entries_used = 0;
55 boolean wait_for_vsync;
58 extern int playing_sounds;
59 extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
60 extern struct SoundControl emptySoundControl;
63 static BITMAP *Read_PCX_to_AllegroBitmap(char *);
65 static void allegro_init_drivers()
69 for (i=0; i<MAX_EVENT_BUFFER; i++)
70 event_buffer[i].type = 0;
72 for (i=0; i<MAX_SCANCODES; i++)
73 key_press_state[i] = KeyReleaseMask;
75 last_mouse_pos = mouse_pos;
81 /* enable Windows friendly timer mode (already default under Windows) */
86 if (install_mouse() > 0)
87 mouse_installed = TRUE;
89 last_joystick_state = 0;
90 joystick_event = FALSE;
93 static boolean allegro_init_audio()
95 reserve_voices(MAX_SOUNDS_PLAYING, 0);
97 if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1)
98 if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1)
104 static boolean hide_mouse(Display *display, int x, int y,
105 unsigned int width, unsigned int height)
107 if (mouse_x + display->mouse_ptr->w < x || mouse_x > x + width)
109 if (mouse_y + display->mouse_ptr->h < y || mouse_y > y + height)
117 static void unhide_mouse(Display *display)
120 show_mouse(video_bitmap);
123 static KeySym ScancodeToKeySym(byte scancode)
127 case KEY_ESC: return XK_Escape;
128 case KEY_1: return XK_1;
129 case KEY_2: return XK_2;
130 case KEY_3: return XK_3;
131 case KEY_4: return XK_4;
132 case KEY_5: return XK_5;
133 case KEY_6: return XK_6;
134 case KEY_7: return XK_7;
135 case KEY_8: return XK_8;
136 case KEY_9: return XK_9;
137 case KEY_0: return XK_0;
138 case KEY_MINUS: return XK_minus;
139 case KEY_EQUALS: return XK_equal;
140 case KEY_BACKSPACE: return XK_BackSpace;
141 case KEY_TAB: return XK_Tab;
142 case KEY_Q: return XK_q;
143 case KEY_W: return XK_w;
144 case KEY_E: return XK_e;
145 case KEY_R: return XK_r;
146 case KEY_T: return XK_t;
147 case KEY_Y: return XK_y;
148 case KEY_U: return XK_u;
149 case KEY_I: return XK_i;
150 case KEY_O: return XK_o;
151 case KEY_P: return XK_p;
152 case KEY_OPENBRACE: return XK_braceleft;
153 case KEY_CLOSEBRACE: return XK_braceright;
154 case KEY_ENTER: return XK_Return;
155 case KEY_LCONTROL: return XK_Control_L;
156 case KEY_A: return XK_a;
157 case KEY_S: return XK_s;
158 case KEY_D: return XK_d;
159 case KEY_F: return XK_f;
160 case KEY_G: return XK_g;
161 case KEY_H: return XK_h;
162 case KEY_J: return XK_j;
163 case KEY_K: return XK_k;
164 case KEY_L: return XK_l;
165 case KEY_COLON: return XK_colon;
166 case KEY_QUOTE: return XK_apostrophe;
167 case KEY_TILDE: return XK_asciitilde;
168 case KEY_LSHIFT: return XK_Shift_L;
169 case KEY_BACKSLASH: return XK_backslash;
170 case KEY_Z: return XK_z;
171 case KEY_X: return XK_x;
172 case KEY_C: return XK_c;
173 case KEY_V: return XK_v;
174 case KEY_B: return XK_b;
175 case KEY_N: return XK_n;
176 case KEY_M: return XK_m;
177 case KEY_COMMA: return XK_comma;
178 case KEY_STOP: return XK_period;
179 case KEY_SLASH: return XK_slash;
180 case KEY_RSHIFT: return XK_Shift_R;
181 case KEY_ASTERISK: return XK_KP_Multiply;
182 case KEY_ALT: return XK_Alt_L;
183 case KEY_SPACE: return XK_space;
184 case KEY_CAPSLOCK: return XK_Caps_Lock;
185 case KEY_F1: return XK_F1;
186 case KEY_F2: return XK_F2;
187 case KEY_F3: return XK_F3;
188 case KEY_F4: return XK_F4;
189 case KEY_F5: return XK_F5;
190 case KEY_F6: return XK_F6;
191 case KEY_F7: return XK_F7;
192 case KEY_F8: return XK_F8;
193 case KEY_F9: return XK_F9;
194 case KEY_F10: return XK_F10;
195 case KEY_NUMLOCK: return XK_Num_Lock;
196 case KEY_SCRLOCK: return XK_Scroll_Lock;
197 case KEY_HOME: return XK_Home;
198 case KEY_UP: return XK_Up;
199 case KEY_PGUP: return XK_Page_Up;
200 case KEY_MINUS_PAD: return XK_KP_Subtract;
201 case KEY_LEFT: return XK_Left;
202 case KEY_5_PAD: return XK_KP_5;
203 case KEY_RIGHT: return XK_Right;
204 case KEY_PLUS_PAD: return XK_KP_Add;
205 case KEY_END: return XK_End;
206 case KEY_DOWN: return XK_Down;
207 case KEY_PGDN: return XK_Page_Down;
208 case KEY_INSERT: return XK_Insert;
209 case KEY_DEL: return XK_Delete;
210 case KEY_PRTSCR: return XK_Print;
211 case KEY_F11: return XK_F11;
212 case KEY_F12: return XK_F12;
213 case KEY_LWIN: return XK_Meta_L;
214 case KEY_RWIN: return XK_Meta_R;
215 case KEY_MENU: return XK_Menu;
216 case KEY_PAD: return XK_VoidSymbol;
217 case KEY_RCONTROL: return XK_Control_R;
218 case KEY_ALTGR: return XK_Alt_R;
219 case KEY_SLASH2: return XK_KP_Divide;
220 case KEY_PAUSE: return XK_Pause;
222 case NEW_KEY_BACKSLASH: return XK_backslash;
223 case NEW_KEY_1_PAD: return XK_KP_1;
224 case NEW_KEY_2_PAD: return XK_KP_2;
225 case NEW_KEY_3_PAD: return XK_KP_3;
226 case NEW_KEY_4_PAD: return XK_KP_4;
227 case NEW_KEY_5_PAD: return XK_KP_5;
228 case NEW_KEY_6_PAD: return XK_KP_6;
229 case NEW_KEY_7_PAD: return XK_KP_7;
230 case NEW_KEY_8_PAD: return XK_KP_8;
231 case NEW_KEY_9_PAD: return XK_KP_9;
232 case NEW_KEY_0_PAD: return XK_KP_0;
233 case NEW_KEY_STOP_PAD: return XK_KP_Separator;
234 case NEW_KEY_EQUALS_PAD: return XK_KP_Equal;
235 case NEW_KEY_SLASH_PAD: return XK_KP_Divide;
236 case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply;
237 case NEW_KEY_ENTER_PAD: return XK_KP_Enter;
239 default: return XK_VoidSymbol;
243 Pixel AllegroAllocColorCell(int r, int g, int b)
245 byte pixel_mapping = 0;
252 /* try to use existing colors from the global colormap */
253 for (i=0; i<global_colormap_entries_used; i++)
255 if (r == global_colormap[i].r &&
256 g == global_colormap[i].g &&
257 b == global_colormap[i].b) /* color found */
264 if (i == global_colormap_entries_used) /* color not found */
266 if (global_colormap_entries_used < MAX_COLORS)
267 global_colormap_entries_used++;
269 i = global_colormap_entries_used - 1;
271 global_colormap[i].r = r;
272 global_colormap[i].g = g;
273 global_colormap[i].b = b;
275 set_palette(global_colormap);
280 return pixel_mapping;
283 void XMapWindow(Display *display, Window window)
286 unsigned int width, height;
289 x = AllegroDefaultScreen().x;
290 y = AllegroDefaultScreen().y;
291 width = AllegroDefaultScreen().width;
292 height = AllegroDefaultScreen().height;
294 mouse_off = hide_mouse(display, x, y, width, height);
295 blit((BITMAP *)window, video_bitmap, 0, 0, x, y, width, height);
298 unhide_mouse(display);
301 Display *XOpenDisplay(char *display_name)
305 BITMAP *mouse_bitmap = NULL;
306 char *mouse_filename =getCustomImageFilename(program.msdos_pointer_filename);
308 if ((mouse_bitmap = Read_PCX_to_AllegroBitmap(mouse_filename)) == NULL)
311 screen = malloc(sizeof(Screen));
312 display = malloc(sizeof(Display));
316 screen[0].white_pixel = AllegroAllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
317 screen[0].black_pixel = AllegroAllocColorCell(0x0000, 0x0000, 0x0000);
318 screen[0].video_bitmap = NULL;
320 display->default_screen = 0;
321 display->screens = screen;
322 display->mouse_ptr = mouse_bitmap;
325 allegro_init_drivers();
328 /* force Windows 95 to switch to fullscreen mode */
329 set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
331 set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
336 Window XCreateSimpleWindow(Display *display, Window parent, int x, int y,
337 unsigned int width, unsigned int height,
338 unsigned int border_width, unsigned long border,
339 unsigned long background)
341 video_bitmap = create_video_bitmap(XRES, YRES);
342 clear_to_color(video_bitmap, background);
344 AllegroDefaultScreen().video_bitmap = video_bitmap;
345 AllegroDefaultScreen().x = x;
346 AllegroDefaultScreen().y = y;
347 AllegroDefaultScreen().width = XRES;
348 AllegroDefaultScreen().height = YRES;
350 set_mouse_sprite(display->mouse_ptr);
353 set_mouse_sprite_focus(1, 1);
356 set_mouse_speed(1, 1);
357 set_mouse_range(AllegroDefaultScreen().x + 1,
358 AllegroDefaultScreen().y + 1,
359 AllegroDefaultScreen().x + video.width + 1,
360 AllegroDefaultScreen().y + video.height + 1);
362 show_video_bitmap(video_bitmap);
364 return (Window)video_bitmap;
367 Status XStringListToTextProperty(char **list, int count,
368 XTextProperty *text_prop_return)
374 string = malloc(strlen(list[0] + 1));
375 strcpy(string, list[0]);
376 text_prop_return->value = (unsigned char *)string;
380 text_prop_return = NULL;
385 void XFree(void *data)
391 GC XCreateGC(Display *display, Drawable d, unsigned long value_mask,
395 gcv = malloc(sizeof(XGCValues));
396 gcv->foreground = values->foreground;
397 gcv->background = values->background;
398 gcv->graphics_exposures = values->graphics_exposures;
399 gcv->clip_mask = values->clip_mask;
400 gcv->clip_x_origin = values->clip_x_origin;
401 gcv->clip_y_origin = values->clip_y_origin;
402 gcv->value_mask = value_mask;
406 void XSetClipMask(Display *display, GC gc, Pixmap pixmap)
408 XGCValues *gcv = (XGCValues *)gc;
410 gcv->clip_mask = pixmap;
411 gcv->value_mask |= GCClipMask;
414 void XSetClipOrigin(Display *display, GC gc, int x, int y)
416 XGCValues *gcv = (XGCValues *)gc;
418 gcv->clip_x_origin = x;
419 gcv->clip_x_origin = y;
422 void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y,
423 unsigned int width, unsigned int height)
425 boolean mouse_off = FALSE;
427 if ((BITMAP *)d == video_bitmap)
429 x += AllegroDefaultScreen().x;
430 y += AllegroDefaultScreen().y;
431 freeze_mouse_flag = TRUE;
432 mouse_off = hide_mouse(display, x, y, width, height);
435 rectfill((BITMAP *)d, x, y, x + width - 1, y + height - 1,
436 ((XGCValues *)gc)->foreground);
439 unhide_mouse(display);
441 freeze_mouse_flag = FALSE;
444 Pixmap XCreatePixmap(Display *display, Drawable d, unsigned int width,
445 unsigned int height, unsigned int depth)
447 BITMAP *bitmap = NULL;
449 if (gfx_capabilities & GFX_HW_VRAM_BLIT &&
450 width == gfx.scrollbuffer_width && height == gfx.scrollbuffer_height)
451 bitmap = create_video_bitmap(width, height);
454 bitmap = create_bitmap(width, height);
456 return (Pixmap)bitmap;
459 void XSync(Display *display, Bool discard_events)
461 wait_for_vsync = TRUE;
464 inline void XCopyArea(Display *display, Drawable src, Drawable dest, GC gc,
465 int src_x, int src_y,
466 unsigned int width, unsigned int height,
467 int dest_x, int dest_y)
469 boolean mouse_off = FALSE;
471 if ((BITMAP *)src == video_bitmap)
473 src_x += AllegroDefaultScreen().x;
474 src_y += AllegroDefaultScreen().y;
477 if ((BITMAP *)dest == video_bitmap)
479 dest_x += AllegroDefaultScreen().x;
480 dest_y += AllegroDefaultScreen().y;
481 freeze_mouse_flag = TRUE;
482 mouse_off = hide_mouse(display, dest_x, dest_y, width, height);
487 wait_for_vsync = FALSE;
491 if (((XGCValues *)gc)->value_mask & GCClipMask)
492 masked_blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y,
495 blit((BITMAP *)src, (BITMAP *)dest, src_x, src_y, dest_x, dest_y,
499 unhide_mouse(display);
501 freeze_mouse_flag = FALSE;
504 static BITMAP *Image_to_AllegroBitmap(Image *image)
507 byte *src_ptr = image->data;
508 byte pixel_mapping[MAX_COLORS];
509 unsigned int depth = 8;
512 if (image->type == IMAGETYPE_TRUECOLOR && depth == 8)
513 Error(ERR_EXIT, "cannot handle true-color images on 8-bit display");
515 /* allocate new allegro bitmap structure */
516 if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL)
518 errno_pcx = PCX_NoMemory;
524 /* try to use existing colors from the global colormap */
525 for (i=0; i<MAX_COLORS; i++)
527 if (!image->rgb.color_used[i])
530 pixel_mapping[i] = AllegroAllocColorCell(image->rgb.red[i],
535 /* copy bitmap data */
536 for (y=0; y<image->height; y++)
537 for (x=0; x<image->width; x++)
538 putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]);
543 static BITMAP *Read_PCX_to_AllegroBitmap(char *filename)
548 /* read the graphic file in PCX format to internal image structure */
549 if ((image = Read_PCX_to_Image(filename)) == NULL)
552 /* convert internal image structure to allegro bitmap structure */
553 if ((bitmap = Image_to_AllegroBitmap(image)) == NULL)
556 set_palette(global_colormap);
561 int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
562 Pixmap *pixmap, Pixmap *pixmap_mask)
566 if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
569 *pixmap = (Pixmap)bitmap;
571 /* pixmap_mask will never be used in Allegro (which uses masked_blit()),
572 so use non-NULL dummy pointer to empty Pixmap */
573 *pixmap_mask = (Pixmap)DUMMY_MASK;
578 int XReadBitmapFile(Display *display, Drawable d, char *filename,
579 unsigned int *width_return, unsigned int *height_return,
580 Pixmap *bitmap_return,
581 int *x_hot_return, int *y_hot_return)
585 if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
586 return BitmapOpenFailed;
588 *width_return = bitmap->w;
589 *height_return = bitmap->h;
592 *bitmap_return = (Pixmap)bitmap;
594 return BitmapSuccess;
597 void XFreePixmap(Display *display, Pixmap pixmap)
599 if (pixmap != DUMMY_MASK &&
600 (is_memory_bitmap((BITMAP *)pixmap) ||
601 is_screen_bitmap((BITMAP *)pixmap)))
602 destroy_bitmap((BITMAP *)pixmap);
605 void XFreeGC(Display *display, GC gc)
609 gcv = (XGCValues *)gc;
614 void XUnmapWindow(Display *display, Window window)
618 void XCloseDisplay(Display *display)
620 BITMAP *bitmap = video_bitmap;
622 if (is_screen_bitmap(bitmap))
623 destroy_bitmap(bitmap);
625 if (display->screens)
626 free(display->screens);
631 /* return to text mode (or DOS box on Windows screen) */
632 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
635 void XNextEvent(Display *display, XEvent *event_return)
637 while (!pending_events)
640 memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
644 static void NewKeyEvent(int key_press_state, KeySym keysym)
648 if (pending_events >= MAX_EVENT_BUFFER)
652 xkey = (XKeyEvent *)&event_buffer[pending_events];
653 xkey->type = key_press_state;
654 xkey->state = (unsigned int)keysym;
657 #define HANDLE_RAW_KB_ALL_KEYS 0
658 #define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY 1
660 static int modifier_scancode[] =
676 static void HandleKeyboardRaw(int mode)
680 for (i=0; i<MAX_SCANCODES; i++)
682 int scancode, new_state, event_type;
685 if (mode == HANDLE_RAW_KB_MODIFIER_KEYS_ONLY)
687 if ((scancode = modifier_scancode[i]) == -1)
693 key_pressed = key[scancode];
694 new_state = (key_pressed ? KeyPressMask : KeyReleaseMask);
695 event_type = (key_pressed ? KeyPress : KeyRelease);
697 if (key_press_state[i] == new_state) /* state not changed */
700 key_press_state[i] = new_state;
702 NewKeyEvent(event_type, ScancodeToKeySym(scancode));
706 static void HandleKeyboardEvent()
710 int key_info = readkey();
711 int scancode = (key_info >> 8);
712 int ascii = (key_info & 0xff);
713 KeySym keysym = ScancodeToKeySym(scancode);
715 if (scancode == KEY_PAD)
717 /* keys on the numeric keypad return just scancode 'KEY_PAD'
718 for some reason, so we must handle them separately */
720 if (ascii >= '0' && ascii <= '9')
721 keysym = XK_KP_0 + (KeySym)(ascii - '0');
722 else if (ascii == '.')
723 keysym = XK_KP_Separator;
725 else if (ascii >= ' ' && ascii <= 'Z')
726 keysym = XK_space + (KeySym)(ascii - ' ');
727 else if (ascii == '^')
728 keysym = XK_asciicircum;
729 else if (ascii == '_')
730 keysym = XK_underscore;
731 else if (ascii == 'Ä')
732 keysym = XK_Adiaeresis;
733 else if (ascii == 'Ö')
734 keysym = XK_Odiaeresis;
735 else if (ascii == 'Ü')
736 keysym = XK_Udiaeresis;
737 else if (ascii == 'ä')
738 keysym = XK_adiaeresis;
739 else if (ascii == 'ö')
740 keysym = XK_odiaeresis;
741 else if (ascii == 'ü')
742 keysym = XK_udiaeresis;
743 else if (ascii == 'ß')
746 NewKeyEvent(KeyPress, keysym);
748 else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG))
750 /* the allegro function keypressed() does not give us single pressed
751 modifier keys, so we must detect them with the internal global
752 allegro variable 'key_shifts' and then handle them separately */
754 HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY);
758 int XPending(Display *display)
760 XButtonEvent *xbutton;
761 XMotionEvent *xmotion;
764 /* When using 'HandleKeyboardRaw()', keyboard input is also stored in
765 the allegro keyboard input buffer and would be available a second
766 time by calling 'HandleKeyboardEvent()'. To avoid double keyboard
767 events, the allegro function 'clear_keybuf()' must be called each
768 time when switching from calling 'HandleKeyboardRaw()' to calling
769 'HandleKeyboardEvent()' to get keyboard input, which is actually
770 done by 'XAutoRepeatOn()' which sets keyboard_auto_repeat to TRUE. */
773 if (keyboard_auto_repeat)
774 HandleKeyboardEvent();
776 HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS);
778 /* mouse motion event */
779 if (mouse_pos != last_mouse_pos)
781 last_mouse_pos = mouse_pos;
783 xmotion = (XMotionEvent *)&event_buffer[pending_events];
784 xmotion->type = MotionNotify;
785 xmotion->x = mouse_x - AllegroDefaultScreen().x;
786 xmotion->y = mouse_y - AllegroDefaultScreen().y;
789 /* mouse button event */
790 if (mouse_b != last_mouse_b)
792 for (i=0; i<3; i++) /* check all three mouse buttons */
794 int bitmask = (1 << i);
796 if ((last_mouse_b & bitmask) != (mouse_b & bitmask))
798 int mapping[3] = { 1, 3, 2 };
801 xbutton = (XButtonEvent *)&event_buffer[pending_events];
802 xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease);
803 xbutton->button = mapping[i];
804 xbutton->x = mouse_x - AllegroDefaultScreen().x;
805 xbutton->y = mouse_y - AllegroDefaultScreen().y;
808 last_mouse_b = mouse_b;
811 return pending_events;
814 KeySym XLookupKeysym(XKeyEvent *key_event, int index)
816 return key_event->state;
819 int XLookupString(XKeyEvent *key_event, char *buffer, int buffer_size,
820 KeySym *key, XComposeStatus *compose)
822 *key = key_event->state;
826 void XSetForeground(Display *display, GC gc, unsigned long pixel)
828 XGCValues *gcv = (XGCValues *)gc;
830 gcv->foreground = pixel;
833 void XDrawLine(Display *display, Drawable d, GC gc,
834 int x1, int y1, int x2, int y2)
836 XGCValues *gcv = (XGCValues *)gc;
837 boolean mouse_off = FALSE;
839 if ((BITMAP *)d == video_bitmap)
841 x1 += AllegroDefaultScreen().x;
842 y1 += AllegroDefaultScreen().y;
843 x2 += AllegroDefaultScreen().x;
844 y2 += AllegroDefaultScreen().y;
845 freeze_mouse_flag = TRUE;
846 mouse_off = hide_mouse(display, MIN(x1, x2), MIN(y1, y2),
847 MAX(x1, x2) - MIN(x1, x2),
848 MAX(y1, y2) - MIN(y1, y2));
851 line((BITMAP *)d, x1, y1, x2, y2, gcv->foreground);
854 unhide_mouse(display);
856 freeze_mouse_flag = FALSE;
859 void XDestroyImage(XImage *ximage)
863 void XDestroyWindow(Display *display, Window window)
867 Bool XQueryPointer(Display *display, Window window,
868 Window *root, Window *child, int *root_x, int *root_y,
869 int *win_x, int *win_y, unsigned int *mask)
871 *win_x = mouse_x - AllegroDefaultScreen().x;
872 *win_y = mouse_y - AllegroDefaultScreen().y;
877 void XAutoRepeatOn(Display *display)
879 keyboard_auto_repeat = TRUE;
883 void XAutoRepeatOff(Display *display)
885 keyboard_auto_repeat = FALSE;
888 void AllegroDrawLine(Drawable d, int from_x, int from_y, int to_x, int to_y,
891 boolean mouse_off = FALSE;
893 if ((BITMAP *)d == video_bitmap)
895 int dx = AllegroDefaultScreen().x;
896 int dy = AllegroDefaultScreen().y;
904 x1 = (from_x < to_x ? from_x : to_x);
905 y1 = (from_y < to_y ? from_y : to_y);
906 x2 = (from_x < to_x ? to_x : from_x);
907 y2 = (from_y < to_y ? to_y : from_y);
909 freeze_mouse_flag = TRUE;
910 mouse_off = hide_mouse(display, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
913 line((BITMAP *)d, from_x, from_y, to_x, to_y, color);
916 unhide_mouse(display);
918 freeze_mouse_flag = FALSE;
921 Pixel AllegroGetPixel(Drawable d, int x, int y)
923 return getpixel((BITMAP *)d, x, y);
926 void MSDOSOpenAudio(void)
928 if (allegro_init_audio())
930 audio.sound_available = TRUE;
931 audio.music_available = TRUE;
932 audio.loops_available = TRUE;
933 audio.sound_enabled = TRUE;
939 void MSDOSCloseAudio(void)
941 /* nothing to be done here */
944 void NetworkServer(int port, int serveronly)
946 Error(ERR_WARN, "networking not supported in DOS version");
950 /* ========================================================================= */
951 /* joystick functions */
952 /* ========================================================================= */
954 void MSDOSInitJoysticks()
958 /* start from scratch */
961 /* try to access two joysticks; if that fails, try to access just one */
962 if (install_joystick(JOY_TYPE_2PADS) == 0 ||
963 install_joystick(JOY_TYPE_AUTODETECT) == 0)
964 joystick.status = JOYSTICK_ACTIVATED;
966 for (i=0; i<MAX_PLAYERS; i++)
968 char *device_name = setup.input[i].joy.device_name;
969 int joystick_nr = getJoystickNrFromDeviceName(device_name);
971 if (joystick_nr >= num_joysticks)
974 /* misuse joystick file descriptor variable to store joystick number */
975 joystick.fd[i] = joystick_nr;
979 boolean MSDOSReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
981 /* the allegro global variable 'num_joysticks' contains the number
982 of joysticks found at initialization under MS-DOS / Windows */
984 if (nr < 0 || nr >= num_joysticks)
990 *x = joy[nr].stick[0].axis[0].pos;
992 *y = joy[nr].stick[0].axis[1].pos;
995 *b1 = joy[nr].button[0].b;
997 *b2 = joy[nr].button[1].b;
1002 #endif /* PLATFORM_MSDOS */