openttd updated to 1.5.0-beta2

--HG--
branch : openttd
This commit is contained in:
Pavel Stupnikov
2015-03-01 00:30:53 +03:00
parent 0abb47ce90
commit d201932121
682 changed files with 26103 additions and 16553 deletions

View File

@@ -1,4 +1,4 @@
/* $Id: gfx.cpp 26209 2014-01-02 22:41:58Z rubidium $ */
/* $Id: gfx.cpp 27167 2015-02-22 23:06:45Z frosch $ */
/*
* This file is part of OpenTTD.
@@ -26,8 +26,11 @@
#include "table/sprites.h"
#include "table/control_codes.h"
#include "safeguards.h"
byte _dirkeys; ///< 1 = left, 2 = up, 4 = right, 8 = down
bool _fullscreen;
byte _support8bpp;
CursorVars _cursor;
bool _ctrl_pressed; ///< Is Ctrl pressed?
bool _shift_pressed; ///< Is Shift pressed?
@@ -53,6 +56,8 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
static ReusableBuffer<uint8> _cursor_backup;
ZoomLevelByte _gui_zoom; ///< GUI Zoom level
/**
* The rect for repaint.
*
@@ -85,7 +90,7 @@ void GfxScroll(int left, int top, int width, int height, int xo, int yo)
blitter->ScrollBuffer(_screen.dst_ptr, left, top, width, height, xo, yo);
/* This part of the screen is now dirty. */
_video_driver->MakeDirty(left, top, width, height);
VideoDriver::GetInstance()->MakeDirty(left, top, width, height);
}
@@ -418,19 +423,21 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left,
NOT_REACHED();
}
TextColour colour = TC_BLACK;
bool draw_shadow = false;
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
const ParagraphLayouter::VisualRun *run = line->GetVisualRun(run_index);
const Font *f = (const Font*)run->GetFont();
FontCache *fc = f->fc;
TextColour colour = f->colour;
colour = f->colour;
SetColourRemap(colour);
DrawPixelInfo *dpi = _cur_dpi;
int dpi_left = dpi->left;
int dpi_right = dpi->left + dpi->width - 1;
bool draw_shadow = fc->GetDrawGlyphShadow() && colour != TC_BLACK;
draw_shadow = fc->GetDrawGlyphShadow() && (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK;
for (int i = 0; i < run->GetGlyphCount(); i++) {
GlyphID glyph = run->GetGlyphs()[i];
@@ -461,6 +468,11 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left,
if (truncation) {
int x = (_current_text_dir == TD_RTL) ? left : (right - 3 * dot_width);
for (int i = 0; i < 3; i++, x += dot_width) {
if (draw_shadow) {
SetColourRemap(TC_BLACK);
GfxMainBlitter(dot_sprite, x + 1, y + 1, BM_COLOUR_REMAP);
SetColourRemap(colour);
}
GfxMainBlitter(dot_sprite, x, y, BM_COLOUR_REMAP);
}
}
@@ -772,6 +784,21 @@ Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
return d;
}
/**
* Helper function to get the blitter mode for different types of palettes.
* @param pal The palette to get the blitter mode for.
* @return The blitter mode associated with the palette.
*/
static BlitterMode GetBlitterMode(PaletteID pal)
{
switch (pal) {
case PAL_NONE: return BM_NORMAL;
case PALETTE_CRASH: return BM_CRASH_REMAP;
case PALETTE_ALL_BLACK: return BM_BLACK_REMAP;
default: return BM_COLOUR_REMAP;
}
}
/**
* Draw a sprite in a viewport.
* @param img Image number to draw
@@ -787,8 +814,12 @@ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSpri
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_TRANSPARENT, sub, real_sprite);
} else if (pal != PAL_NONE) {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_COLOUR_REMAP, sub, real_sprite);
if (HasBit(pal, PALETTE_TEXT_RECOLOUR)) {
SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
} else {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
}
GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, GetBlitterMode(pal), sub, real_sprite);
} else {
GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite);
}
@@ -810,8 +841,12 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub,
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_TRANSPARENT, sub, real_sprite, zoom);
} else if (pal != PAL_NONE) {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_COLOUR_REMAP, sub, real_sprite, zoom);
if (HasBit(pal, PALETTE_TEXT_RECOLOUR)) {
SetColourRemap((TextColour)GB(pal, 0, PALETTE_WIDTH));
} else {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
}
GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, GetBlitterMode(pal), sub, real_sprite, zoom);
} else {
GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite, zoom);
}
@@ -1104,6 +1139,7 @@ void LoadStringWidthTable(bool monospace)
}
}
ClearFontCache();
ReInitAllWindows();
}
@@ -1176,7 +1212,7 @@ void UndrawMouseCursor()
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
_cursor.visible = false;
blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup.GetBuffer(), _cursor.draw_size.x, _cursor.draw_size.y);
_video_driver->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
VideoDriver::GetInstance()->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
}
}
@@ -1236,7 +1272,7 @@ void DrawMouseCursor()
_cur_dpi = &_screen;
DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x + _cursor.short_vehicle_offset, _cursor.pos.y);
_video_driver->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
VideoDriver::GetInstance()->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
_cursor.visible = true;
_cursor.dirty = false;
@@ -1260,7 +1296,7 @@ void RedrawScreenRect(int left, int top, int right, int bottom)
DrawOverlappedWindowForAll(left, top, right, bottom);
_video_driver->MakeDirty(left, top, right - left, bottom - top);
VideoDriver::GetInstance()->MakeDirty(left, top, right - left, bottom - top);
}
/**
@@ -1496,10 +1532,10 @@ void UpdateCursorSize()
CursorVars *cv = &_cursor;
const Sprite *p = GetSprite(GB(cv->sprite, 0, SPRITE_WIDTH), ST_NORMAL);
cv->size.y = UnScaleByZoom(p->height, ZOOM_LVL_GUI);
cv->size.x = UnScaleByZoom(p->width, ZOOM_LVL_GUI);
cv->offs.x = UnScaleByZoom(p->x_offs, ZOOM_LVL_GUI);
cv->offs.y = UnScaleByZoom(p->y_offs, ZOOM_LVL_GUI);
cv->size.y = UnScaleGUI(p->height);
cv->size.x = UnScaleGUI(p->width);
cv->offs.x = UnScaleGUI(p->x_offs);
cv->offs.y = UnScaleGUI(p->y_offs);
cv->dirty = true;
}
@@ -1567,14 +1603,61 @@ void SetAnimatedMouseCursor(const AnimCursor *table)
SwitchAnimatedCursor();
}
/**
* Update cursor position on mouse movement.
* @param x New X position.
* @param y New Y position.
* @param queued True, if the OS queues mouse warps after pending mouse movement events.
* False, if the warp applies instantaneous.
* @return true, if the OS cursor position should be warped back to this->pos.
*/
bool CursorVars::UpdateCursorPosition(int x, int y, bool queued_warp)
{
/* Detecting relative mouse movement is somewhat tricky.
* - There may be multiple mouse move events in the video driver queue (esp. when OpenTTD lags a bit).
* - When we request warping the mouse position (return true), a mouse move event is appended at the end of the queue.
*
* So, when this->fix_at is active, we use the following strategy:
* - The first movement triggers the warp to reset the mouse position.
* - Subsequent events have to compute movement relative to the previous event.
* - The relative movement is finished, when we receive the event matching the warp.
*/
if (x == this->pos.x && y == this->pos.y) {
/* Warp finished. */
this->queued_warp = false;
}
this->delta.x = x - (this->queued_warp ? this->last_position.x : this->pos.x);
this->delta.y = y - (this->queued_warp ? this->last_position.y : this->pos.y);
this->last_position.x = x;
this->last_position.y = y;
bool need_warp = false;
if (this->fix_at) {
if (!this->queued_warp && (this->delta.x != 0 || this->delta.y != 0)) {
/* Trigger warp. */
this->queued_warp = queued_warp;
need_warp = true;
}
} else if (this->pos.x != x || this->pos.y != y) {
this->queued_warp = false; // Cancel warping, we are no longer confining the position.
this->dirty = true;
this->pos.x = x;
this->pos.y = y;
}
return need_warp;
}
bool ChangeResInGame(int width, int height)
{
return (_screen.width == width && _screen.height == height) || _video_driver->ChangeResolution(width, height);
return (_screen.width == width && _screen.height == height) || VideoDriver::GetInstance()->ChangeResolution(width, height);
}
bool ToggleFullScreen(bool fs)
{
bool result = _video_driver->ToggleFullscreen(fs);
bool result = VideoDriver::GetInstance()->ToggleFullscreen(fs);
if (_fullscreen != fs && _num_resolutions == 0) {
DEBUG(driver, 0, "Could not find a suitable fullscreen resolution");
}