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" 27 #include "../framerate_type.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;
58 static void DrawSurfaceToScreen()
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);
97 static void CheckPaletteAnim()
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);
141 GFX_MODE_LIST *mode_list = get_gfx_mode_list(gfx_driver->id);
142 if (mode_list == NULL) {
143 memcpy(
_resolutions, default_resolutions,
sizeof(default_resolutions));
148 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) {
156 for (j = 0; j < n; j++) {
170 destroy_gfx_mode_list(mode_list);
173 static void GetAvailableVideoMode(uint *w, uint *h)
188 if (newdelta < delta) {
197 static bool CreateMainSurface(uint w, uint h)
200 if (bpp == 0)
usererror(
"Can't use a blitter that blits 0 bpp for normal visuals");
201 set_color_depth(bpp);
203 GetAvailableVideoMode(&w, &h);
204 if (set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, w, h, 0, 0) != 0) {
205 DEBUG(driver, 0,
"Allegro: Couldn't allocate a window to draw on '%s'", allegro_error);
211 _allegro_screen = create_bitmap_ex(bpp, screen->cr - screen->cl, screen->cb - screen->ct);
212 _screen.width = _allegro_screen->w;
213 _screen.height = _allegro_screen->h;
214 _screen.pitch = ((byte*)screen->line[1] - (byte*)screen->line[0]) / (bpp / 8);
215 _screen.dst_ptr = _allegro_screen->line[0];
218 memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch);
222 _cursor.
pos.x = mouse_x;
223 _cursor.
pos.y = mouse_y;
230 seprintf(caption,
lastof(caption),
"OpenTTD %s", _openttd_revision);
231 set_window_title(caption);
233 enable_hardware_cursor();
234 select_mouse_cursor(MOUSE_CURSOR_ARROW);
235 show_mouse(_allegro_screen);
242 bool VideoDriver_Allegro::ClaimMousePointer()
244 select_mouse_cursor(MOUSE_CURSOR_NONE);
246 disable_hardware_cursor();
256 #define AS(x, z) {x, 0, z} 257 #define AM(x, y, z, w) {x, y - x, z} 261 AM(KEY_PGUP, KEY_PGDN, WKC_PAGEUP, WKC_PAGEDOWN),
263 AS(KEY_DOWN, WKC_DOWN),
264 AS(KEY_LEFT, WKC_LEFT),
265 AS(KEY_RIGHT, WKC_RIGHT),
267 AS(KEY_HOME, WKC_HOME),
268 AS(KEY_END, WKC_END),
270 AS(KEY_INSERT, WKC_INSERT),
271 AS(KEY_DEL, WKC_DELETE),
274 AM(KEY_A, KEY_Z,
'A',
'Z'),
275 AM(KEY_0, KEY_9,
'0',
'9'),
277 AS(KEY_ESC, WKC_ESC),
278 AS(KEY_PAUSE, WKC_PAUSE),
279 AS(KEY_BACKSPACE, WKC_BACKSPACE),
281 AS(KEY_SPACE, WKC_SPACE),
282 AS(KEY_ENTER, WKC_RETURN),
283 AS(KEY_TAB, WKC_TAB),
286 AM(KEY_F1, KEY_F12, WKC_F1, WKC_F12),
289 AM(KEY_0_PAD, KEY_9_PAD,
'0',
'9'),
290 AS(KEY_SLASH_PAD, WKC_NUM_DIV),
291 AS(KEY_ASTERISK, WKC_NUM_MUL),
292 AS(KEY_MINUS_PAD, WKC_NUM_MINUS),
293 AS(KEY_PLUS_PAD, WKC_NUM_PLUS),
294 AS(KEY_ENTER_PAD, WKC_NUM_ENTER),
295 AS(KEY_DEL_PAD, WKC_DELETE),
309 AS(KEY_TILDE, WKC_BACKQUOTE),
312 static uint32 ConvertAllegroKeyIntoMy(
WChar *character)
315 int unicode = ureadkey(&scancode);
320 for (map = _vk_mapping; map !=
endof(_vk_mapping); ++map) {
321 if ((uint)(scancode - map->vk_from) <= map->vk_count) {
322 key = scancode - map->vk_from + map->map_to;
327 if (key_shifts & KB_SHIFT_FLAG) key |= WKC_SHIFT;
328 if (key_shifts & KB_CTRL_FLAG) key |= WKC_CTRL;
329 if (key_shifts & KB_ALT_FLAG) key |= WKC_ALT;
331 DEBUG(driver, 0,
"Scancode character pressed %u", scancode);
332 DEBUG(driver, 0,
"Unicode character pressed %u", unicode);
335 *character = unicode;
339 static const uint LEFT_BUTTON = 0;
340 static const uint RIGHT_BUTTON = 1;
342 static void PollEvent()
346 bool mouse_action =
false;
349 static int prev_button_state;
350 if (prev_button_state != mouse_b) {
351 uint diff = prev_button_state ^ mouse_b;
355 if (
HasBit(mouse_b, button)) {
358 button = RIGHT_BUTTON;
359 ClrBit(diff, RIGHT_BUTTON);
381 }
else if (button == LEFT_BUTTON) {
384 }
else if (button == RIGHT_BUTTON) {
389 prev_button_state = mouse_b;
395 position_mouse(_cursor.
pos.x, _cursor.
pos.y);
397 if (_cursor.
delta.x != 0 || _cursor.
delta.y) mouse_action =
true;
399 static int prev_mouse_z = 0;
400 if (prev_mouse_z != mouse_z) {
401 _cursor.
wheel = (prev_mouse_z - mouse_z) < 0 ? -1 : 1;
402 prev_mouse_z = mouse_z;
409 if ((key_shifts & KB_ALT_FLAG) && (key[KEY_ENTER] || key[KEY_F])) {
410 ToggleFullScreen(!_fullscreen);
411 }
else if (keypressed()) {
413 uint keycode = ConvertAllegroKeyIntoMy(&character);
422 int _allegro_instance_count = 0;
426 if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, NULL)) {
427 DEBUG(driver, 0,
"allegro: install_allegro failed '%s'", allegro_error);
428 return "Failed to set up Allegro";
430 _allegro_instance_count++;
439 signal(SIGABRT, NULL);
440 signal(SIGSEGV, NULL);
451 return "Failed to set up Allegro video";
454 set_close_button_callback(HandleExitGameRequest);
461 if (--_allegro_instance_count == 0) allegro_exit();
464 #if defined(UNIX) || defined(__OS2__) || defined(DOS) 465 # include <sys/time.h> 467 static uint32 GetTime()
471 gettimeofday(&tim, NULL);
472 return tim.tv_usec / 1000 + tim.tv_sec * 1000;
475 static uint32 GetTime()
477 return GetTickCount();
484 uint32 cur_ticks = GetTime();
485 uint32 last_cur_ticks = cur_ticks;
491 uint32 prev_cur_ticks = cur_ticks;
495 if (_exit_game)
return;
502 if (key[KEY_TAB] && (key_shifts & KB_ALT_FLAG) == 0)
505 if (!
_networking && _game_mode != GM_MENU) _fast_forward |= 2;
506 }
else if (_fast_forward & 2) {
510 cur_ticks = GetTime();
511 if (cur_ticks >= next_tick || (_fast_forward && !
_pause_mode) || cur_ticks < prev_cur_ticks) {
513 last_cur_ticks = cur_ticks;
523 (key[KEY_LEFT] ? 1 : 0) |
524 (key[KEY_UP] ? 2 : 0) |
525 (key[KEY_RIGHT] ? 4 : 0) |
526 (key[KEY_DOWN] ? 8 : 0);
534 DrawSurfaceToScreen();
539 DrawSurfaceToScreen();
546 return CreateMainSurface(w, h);
554 _fullscreen = fullscreen;
567 return CreateMainSurface(_screen.width, _screen.height);
bool _networking
are we in networking mode?
void MakeDirty(int left, int top, int width, int height)
Mark a particular area dirty.
uint32 _realtime_tick
The real time in the game.
Point pos
logical mouse position
bool ChangeResolution(int w, int h)
Change the resolution of the window.
Factory for the allegro video driver.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
bool _right_button_down
Is right mouse button pressed?
Colour palette[256]
Current palette. Entry 0 has to be always fully transparent!
void MainLoop()
Perform the actual drawing.
Dimension _cur_resolution
The current resolution.
int _num_resolutions
The number of resolutions.
#define lastof(x)
Get the last element of an fixed size array.
How all blitters should look like.
virtual void PostResize()
Post resize event.
Palette animation should be done by video backend (8bpp only!)
bool _left_button_clicked
Is left mouse button clicked?
Base of the Allegro video driver.
bool _ctrl_pressed
Is Ctrl pressed?
bool _right_button_clicked
Is right mouse button clicked?
The blitter takes care of the palette animation.
virtual void PaletteAnimate(const Palette &palette)=0
Called when the 8bpp palette is changed; you should redraw all pixels on the screen that are equal to...
bool _left_button_down
Is left mouse button pressed?
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
int wheel
mouse wheel movement
bool UpdateCursorPosition(int x, int y, bool queued_warp)
Update cursor position on mouse movement.
bool AfterBlitterChange()
Callback invoked after the blitter was changed.
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
void HandleKeypress(uint keycode, WChar key)
Handle keyboard input.
byte _dirkeys
1 = left, 2 = up, 4 = right, 8 = down
void HandleMouseEvents()
Handle a mouse event from the video driver.
#define lengthof(x)
Return the length of an fixed size array.
PauseModeByte _pause_mode
The current pause mode.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
int first_dirty
The first dirty element.
bool ToggleFullscreen(bool fullscreen)
Change the full screen setting.
Palette _cur_palette
Current palette.
bool _shift_pressed
Is Shift pressed?
#define DEBUG(name, level,...)
Output a line of debugging information.
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
Dimension _resolutions[32]
List of resolutions.
virtual Blitter::PaletteAnimation UsePaletteAnimation()=0
Check if the blitter uses palette animation at all.
void HandleCtrlChanged()
State of CONTROL key has changed.
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
void Stop()
Stop this driver.
Specification of a rectangle with an absolute top-left coordinate and a (relative) width/height...
Speed of painting drawn video buffer.
void NetworkDrawChatMessage()
Draw the chat message-box.
#define endof(x)
Get the end element of an fixed size array.
virtual uint8 GetScreenDepth()=0
Get the screen depth this blitter works for.
const char * Start(const char *const *param)
Start this driver.
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview)
AirportSpec definition for airports with at least one depot.
bool _rightclick_emulate
Whether right clicking is emulated.
void GameSizeChanged()
Size of the application screen changed.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Point delta
relative mouse movement in this tick
int count_dirty
The number of dirty elements.
static T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
uint32 WChar
Type for wide characters, i.e.
Dimensions (a width and height) of a rectangle in 2D.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
void UpdateWindows()
Update the continuously changing contents of the windows, such as the viewports.