19 #include "../stdafx.h" 
   20 #include "../openttd.h" 
   21 #include "../gfx_func.h" 
   23 #include "../blitter/factory.hpp" 
   24 #include "../network/network.h" 
   25 #include "../core/random_func.hpp" 
   26 #include "../core/math_func.hpp" 
   30 #include "../safeguards.h" 
   40 static BITMAP *_allegro_screen;
 
   42 #define MAX_DIRTY_RECTS 100 
   44 static int _num_dirty_rects;
 
   48   if (_num_dirty_rects < MAX_DIRTY_RECTS) {
 
   49     _dirty_rects[_num_dirty_rects].x = left;
 
   50     _dirty_rects[_num_dirty_rects].y = top;
 
   51     _dirty_rects[_num_dirty_rects].width = width;
 
   52     _dirty_rects[_num_dirty_rects].height = height;
 
   57 static void DrawSurfaceToScreen()
 
   59   int n = _num_dirty_rects;
 
   63   if (n > MAX_DIRTY_RECTS) {
 
   64     blit(_allegro_screen, screen, 0, 0, 0, 0, _allegro_screen->w, _allegro_screen->h);
 
   68   for (
int i = 0; i < n; i++) {
 
   69     blit(_allegro_screen, screen, _dirty_rects[i].x, _dirty_rects[i].y, _dirty_rects[i].x, _dirty_rects[i].y, _dirty_rects[i].width, _dirty_rects[i].height);
 
   74 static void UpdatePalette(uint start, uint count)
 
   78   uint end = start + count;
 
   79   for (uint i = start; i != end; i++) {
 
   86   set_palette_range(pal, start, end - 1, 1);
 
   89 static void InitPalette()
 
   91   UpdatePalette(0, 256);
 
   94 static void CheckPaletteAnim()
 
  118 static const Dimension default_resolutions[] = {
 
  132 static void GetVideoModes()
 
  136   set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
 
  138   GFX_MODE_LIST *mode_list = get_gfx_mode_list(gfx_driver->id);
 
  139   if (mode_list == NULL) {
 
  140     memcpy(
_resolutions, default_resolutions, 
sizeof(default_resolutions));
 
  145   GFX_MODE *modes = mode_list->mode;
 
  148   for (
int i = 0; modes[i].bpp != 0; i++) {
 
  149     uint w = modes[i].width;
 
  150     uint h = modes[i].height;
 
  151     if (w >= 640 && h >= 480) {
 
  153       for (j = 0; j < n; j++) {
 
  167   destroy_gfx_mode_list(mode_list);
 
  170 static void GetAvailableVideoMode(uint *w, uint *h)
 
  185     if (newdelta < delta) {
 
  194 static bool CreateMainSurface(uint w, uint h)
 
  197   if (bpp == 0) 
usererror(
"Can't use a blitter that blits 0 bpp for normal visuals");
 
  198   set_color_depth(bpp);
 
  200   GetAvailableVideoMode(&w, &h);
 
  201   if (set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, w, h, 0, 0) != 0) {
 
  202     DEBUG(driver, 0, 
"Allegro: Couldn't allocate a window to draw on '%s'", allegro_error);
 
  208   _allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct);
 
  209   _screen.width = _allegro_screen->w;
 
  210   _screen.height = _allegro_screen->h;
 
  211   _screen.pitch = ((byte*)screen->line[1] - (byte*)screen->line[0]) / (bpp / 8);
 
  212   _screen.dst_ptr = _allegro_screen->line[0];
 
  215   memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);
 
  219   _cursor.
pos.x = mouse_x;
 
  220   _cursor.
pos.y = mouse_y;
 
  227   seprintf(caption, 
lastof(caption), 
"OpenTTD %s", _openttd_revision);
 
  228   set_window_title(caption);
 
  230   enable_hardware_cursor();
 
  231   select_mouse_cursor(MOUSE_CURSOR_ARROW);
 
  232   show_mouse(_allegro_screen);
 
  239 bool VideoDriver_Allegro::ClaimMousePointer()
 
  241   select_mouse_cursor(MOUSE_CURSOR_NONE);
 
  243   disable_hardware_cursor();
 
  253 #define AS(x, z) {x, 0, z} 
  254 #define AM(x, y, z, w) {x, y - x, z} 
  258   AM(KEY_PGUP, KEY_PGDN, WKC_PAGEUP, WKC_PAGEDOWN),
 
  260   AS(KEY_DOWN,   WKC_DOWN),
 
  261   AS(KEY_LEFT,   WKC_LEFT),
 
  262   AS(KEY_RIGHT,  WKC_RIGHT),
 
  264   AS(KEY_HOME,   WKC_HOME),
 
  265   AS(KEY_END,    WKC_END),
 
  267   AS(KEY_INSERT, WKC_INSERT),
 
  268   AS(KEY_DEL,    WKC_DELETE),
 
  271   AM(KEY_A, KEY_Z, 
'A', 
'Z'),
 
  272   AM(KEY_0, KEY_9, 
'0', 
'9'),
 
  274   AS(KEY_ESC,       WKC_ESC),
 
  275   AS(KEY_PAUSE,     WKC_PAUSE),
 
  276   AS(KEY_BACKSPACE, WKC_BACKSPACE),
 
  278   AS(KEY_SPACE,     WKC_SPACE),
 
  279   AS(KEY_ENTER,     WKC_RETURN),
 
  280   AS(KEY_TAB,       WKC_TAB),
 
  283   AM(KEY_F1, KEY_F12, WKC_F1, WKC_F12),
 
  286   AM(KEY_0_PAD, KEY_9_PAD, 
'0', 
'9'),
 
  287   AS(KEY_SLASH_PAD,   WKC_NUM_DIV),
 
  288   AS(KEY_ASTERISK,    WKC_NUM_MUL),
 
  289   AS(KEY_MINUS_PAD,   WKC_NUM_MINUS),
 
  290   AS(KEY_PLUS_PAD,    WKC_NUM_PLUS),
 
  291   AS(KEY_ENTER_PAD,   WKC_NUM_ENTER),
 
  292   AS(KEY_DEL_PAD,     WKC_DELETE),
 
  306   AS(KEY_TILDE,   WKC_BACKQUOTE),
 
  309 static uint32 ConvertAllegroKeyIntoMy(
WChar *character)
 
  312   int unicode = ureadkey(&scancode);
 
  317   for (map = _vk_mapping; map != 
endof(_vk_mapping); ++map) {
 
  318     if ((uint)(scancode - map->vk_from) <= map->vk_count) {
 
  319       key = scancode - map->vk_from + map->map_to;
 
  324   if (key_shifts & KB_SHIFT_FLAG) key |= WKC_SHIFT;
 
  325   if (key_shifts & KB_CTRL_FLAG)  key |= WKC_CTRL;
 
  326   if (key_shifts & KB_ALT_FLAG)   key |= WKC_ALT;
 
  328   DEBUG(driver, 0, 
"Scancode character pressed %u", scancode);
 
  329   DEBUG(driver, 0, 
"Unicode character pressed %u", unicode);
 
  332   *character = unicode;
 
  336 static const uint LEFT_BUTTON  = 0;
 
  337 static const uint RIGHT_BUTTON = 1;
 
  339 static void PollEvent()
 
  343   bool mouse_action = 
false;
 
  346   static int prev_button_state;
 
  347   if (prev_button_state != mouse_b) {
 
  348     uint diff = prev_button_state ^ mouse_b;
 
  352       if (
HasBit(mouse_b, button)) {
 
  355           button = RIGHT_BUTTON;
 
  356           ClrBit(diff, RIGHT_BUTTON);
 
  378         } 
else if (button == LEFT_BUTTON) {
 
  381         } 
else if (button == RIGHT_BUTTON) {
 
  386     prev_button_state = mouse_b;
 
  392     position_mouse(_cursor.
pos.x, _cursor.
pos.y);
 
  394   if (_cursor.
delta.x != 0 || _cursor.
delta.y) mouse_action = 
true;
 
  396   static int prev_mouse_z = 0;
 
  397   if (prev_mouse_z != mouse_z) {
 
  398     _cursor.
wheel = (prev_mouse_z - mouse_z) < 0 ? -1 : 1;
 
  399     prev_mouse_z = mouse_z;
 
  406   if ((key_shifts & KB_ALT_FLAG) && (key[KEY_ENTER] || key[KEY_F])) {
 
  407     ToggleFullScreen(!_fullscreen);
 
  408   } 
else if (keypressed()) {
 
  410     uint keycode = ConvertAllegroKeyIntoMy(&character);
 
  419 int _allegro_instance_count = 0;
 
  423   if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, NULL)) {
 
  424     DEBUG(driver, 0, 
"allegro: install_allegro failed '%s'", allegro_error);
 
  425     return "Failed to set up Allegro";
 
  427   _allegro_instance_count++;
 
  436   signal(SIGABRT, NULL);
 
  437   signal(SIGSEGV, NULL);
 
  448     return "Failed to set up Allegro video";
 
  451   set_close_button_callback(HandleExitGameRequest);
 
  458   if (--_allegro_instance_count == 0) allegro_exit();
 
  461 #if defined(UNIX) || defined(__OS2__) || defined(PSP) || defined(DOS) 
  462 # include <sys/time.h>  
  464 static uint32 GetTime()
 
  468   gettimeofday(&tim, NULL);
 
  469   return tim.tv_usec / 1000 + tim.tv_sec * 1000;
 
  472 static uint32 GetTime()
 
  474   return GetTickCount();
 
  481   uint32 cur_ticks = GetTime();
 
  482   uint32 last_cur_ticks = cur_ticks;
 
  488     uint32 prev_cur_ticks = cur_ticks; 
 
  492     if (_exit_game) 
return;
 
  499     if (key[KEY_TAB] && (key_shifts & KB_ALT_FLAG) == 0)
 
  502       if (!
_networking && _game_mode != GM_MENU) _fast_forward |= 2;
 
  503     } 
else if (_fast_forward & 2) {
 
  507     cur_ticks = GetTime();
 
  508     if (cur_ticks >= next_tick || (_fast_forward && !
_pause_mode) || cur_ticks < prev_cur_ticks) {
 
  510       last_cur_ticks = cur_ticks;
 
  520         (key[KEY_LEFT]  ? 1 : 0) |
 
  521         (key[KEY_UP]    ? 2 : 0) |
 
  522         (key[KEY_RIGHT] ? 4 : 0) |
 
  523         (key[KEY_DOWN]  ? 8 : 0);
 
  531       DrawSurfaceToScreen();
 
  536       DrawSurfaceToScreen();
 
  543   return CreateMainSurface(w, h);
 
  551   _fullscreen = fullscreen;
 
  564   return CreateMainSurface(_screen.width, _screen.height);