17 #include "../stdafx.h"
18 #include "../openttd.h"
19 #include "../gfx_func.h"
21 #include "../blitter/factory.hpp"
22 #include "../core/random_func.hpp"
23 #include "../core/math_func.hpp"
24 #include "../framerate_type.h"
25 #include "../progress.h"
26 #include "../thread.h"
27 #include "../window_func.h"
31 #include "../safeguards.h"
41 static BITMAP *_allegro_screen;
43 #define MAX_DIRTY_RECTS 100
45 static int _num_dirty_rects;
49 if (_num_dirty_rects < MAX_DIRTY_RECTS) {
50 _dirty_rects[_num_dirty_rects].x = left;
51 _dirty_rects[_num_dirty_rects].y = top;
52 _dirty_rects[_num_dirty_rects].width = width;
53 _dirty_rects[_num_dirty_rects].height = height;
62 int n = _num_dirty_rects;
66 if (n > MAX_DIRTY_RECTS) {
67 blit(_allegro_screen, screen, 0, 0, 0, 0, _allegro_screen->w, _allegro_screen->h);
71 for (
int i = 0; i < n; i++) {
72 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);
77 static void UpdatePalette(uint start, uint count)
81 uint end = start + count;
82 for (uint i = start; i != end; i++) {
89 set_palette_range(pal, start, end - 1, 1);
92 static void InitPalette()
94 UpdatePalette(0, 256);
121 static const Dimension default_resolutions[] = {
135 static void GetVideoModes()
139 set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
143 GFX_MODE_LIST *mode_list = get_gfx_mode_list(gfx_driver->id);
144 if (mode_list ==
nullptr) {
145 _resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions));
149 GFX_MODE *modes = mode_list->mode;
151 for (
int i = 0; modes[i].bpp != 0; i++) {
152 uint w = modes[i].width;
153 uint h = modes[i].height;
154 if (w < 640 || h < 480)
continue;
161 destroy_gfx_mode_list(mode_list);
164 static void GetAvailableVideoMode(uint *w, uint *h)
177 if (newdelta < delta) {
186 static bool CreateMainSurface(uint w, uint h)
189 if (bpp == 0)
usererror(
"Can't use a blitter that blits 0 bpp for normal visuals");
190 set_color_depth(bpp);
192 GetAvailableVideoMode(&w, &h);
193 if (set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, w, h, 0, 0) != 0) {
194 DEBUG(driver, 0,
"Allegro: Couldn't allocate a window to draw on '%s'", allegro_error);
200 _allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct);
201 _screen.width = _allegro_screen->w;
202 _screen.height = _allegro_screen->h;
203 _screen.pitch = ((
byte*)screen->line[1] - (
byte*)screen->line[0]) / (bpp / 8);
204 _screen.dst_ptr = _allegro_screen->line[0];
207 memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);
211 _cursor.
pos.x = mouse_x;
212 _cursor.
pos.y = mouse_y;
219 seprintf(caption,
lastof(caption),
"OpenTTD %s", _openttd_revision);
220 set_window_title(caption);
222 enable_hardware_cursor();
223 select_mouse_cursor(MOUSE_CURSOR_ARROW);
224 show_mouse(_allegro_screen);
231 bool VideoDriver_Allegro::ClaimMousePointer()
233 select_mouse_cursor(MOUSE_CURSOR_NONE);
235 disable_hardware_cursor();
241 std::vector<int> rates = {};
243 int refresh_rate = get_refresh_rate();
244 if (refresh_rate != 0) rates.push_back(refresh_rate);
249 struct AllegroVkMapping {
255 #define AS(x, z) {x, 0, z}
256 #define AM(x, y, z, w) {x, y - x, z}
258 static const AllegroVkMapping _vk_mapping[] = {
260 AM(KEY_PGUP, KEY_PGDN, WKC_PAGEUP, WKC_PAGEDOWN),
262 AS(KEY_DOWN, WKC_DOWN),
263 AS(KEY_LEFT, WKC_LEFT),
264 AS(KEY_RIGHT, WKC_RIGHT),
266 AS(KEY_HOME, WKC_HOME),
267 AS(KEY_END, WKC_END),
269 AS(KEY_INSERT, WKC_INSERT),
270 AS(KEY_DEL, WKC_DELETE),
273 AM(KEY_A, KEY_Z,
'A',
'Z'),
274 AM(KEY_0, KEY_9,
'0',
'9'),
276 AS(KEY_ESC, WKC_ESC),
277 AS(KEY_PAUSE, WKC_PAUSE),
278 AS(KEY_BACKSPACE, WKC_BACKSPACE),
280 AS(KEY_SPACE, WKC_SPACE),
281 AS(KEY_ENTER, WKC_RETURN),
282 AS(KEY_TAB, WKC_TAB),
285 AM(KEY_F1, KEY_F12, WKC_F1, WKC_F12),
288 AM(KEY_0_PAD, KEY_9_PAD,
'0',
'9'),
289 AS(KEY_SLASH_PAD, WKC_NUM_DIV),
290 AS(KEY_ASTERISK, WKC_NUM_MUL),
291 AS(KEY_MINUS_PAD, WKC_NUM_MINUS),
292 AS(KEY_PLUS_PAD, WKC_NUM_PLUS),
293 AS(KEY_ENTER_PAD, WKC_NUM_ENTER),
294 AS(KEY_DEL_PAD, WKC_DELETE),
308 AS(KEY_TILDE, WKC_BACKQUOTE),
311 static uint32 ConvertAllegroKeyIntoMy(
WChar *character)
314 int unicode = ureadkey(&scancode);
316 const AllegroVkMapping *map;
319 for (map = _vk_mapping; map !=
endof(_vk_mapping); ++map) {
320 if ((uint)(scancode - map->vk_from) <= map->vk_count) {
321 key = scancode - map->vk_from + map->map_to;
326 if (key_shifts & KB_SHIFT_FLAG) key |= WKC_SHIFT;
327 if (key_shifts & KB_CTRL_FLAG) key |= WKC_CTRL;
328 if (key_shifts & KB_ALT_FLAG) key |= WKC_ALT;
330 DEBUG(driver, 0,
"Scancode character pressed %u", scancode);
331 DEBUG(driver, 0,
"Unicode character pressed %u", unicode);
334 *character = unicode;
338 static const uint LEFT_BUTTON = 0;
339 static const uint RIGHT_BUTTON = 1;
345 bool mouse_action =
false;
348 static int prev_button_state;
349 if (prev_button_state != mouse_b) {
350 uint diff = prev_button_state ^ mouse_b;
354 if (
HasBit(mouse_b, button)) {
357 button = RIGHT_BUTTON;
358 ClrBit(diff, RIGHT_BUTTON);
380 }
else if (button == LEFT_BUTTON) {
383 }
else if (button == RIGHT_BUTTON) {
388 prev_button_state = mouse_b;
394 position_mouse(_cursor.
pos.x, _cursor.
pos.y);
396 if (_cursor.
delta.x != 0 || _cursor.
delta.y) mouse_action =
true;
398 static int prev_mouse_z = 0;
399 if (prev_mouse_z != mouse_z) {
400 _cursor.
wheel = (prev_mouse_z - mouse_z) < 0 ? -1 : 1;
401 prev_mouse_z = mouse_z;
408 if ((key_shifts & KB_ALT_FLAG) && (key[KEY_ENTER] || key[KEY_F])) {
409 ToggleFullScreen(!_fullscreen);
410 }
else if (keypressed()) {
412 uint keycode = ConvertAllegroKeyIntoMy(&character);
423 int _allegro_instance_count = 0;
427 if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno,
nullptr)) {
428 DEBUG(driver, 0,
"allegro: install_allegro failed '%s'", allegro_error);
429 return "Failed to set up Allegro";
431 _allegro_instance_count++;
442 signal(SIGABRT,
nullptr);
443 signal(SIGSEGV,
nullptr);
448 return "Failed to set up Allegro video";
451 set_close_button_callback(HandleExitGameRequest);
460 if (--_allegro_instance_count == 0) allegro_exit();
480 (key[KEY_LEFT] ? 1 : 0) |
481 (key[KEY_UP] ? 2 : 0) |
482 (key[KEY_RIGHT] ? 4 : 0) |
483 (key[KEY_DOWN] ? 8 : 0);
493 if (_exit_game)
break;
504 return CreateMainSurface(w, h);
509 _fullscreen = fullscreen;
521 return CreateMainSurface(_screen.width, _screen.height);