File diff r6178:fc8bd2bde93a → r6179:c0508e7aefec
src/gfx.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file gfx.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "functions.h"
 
#include "macros.h"
 
#include "spritecache.h"
 
#include "strings.h"
 
@@ -18,17 +20,17 @@
 
#include "debug.h"
 

	
 
#ifdef _DEBUG
 
bool _dbg_screen_rect;
 
#endif
 

	
 
byte _dirkeys;        // 1 = left, 2 = up, 4 = right, 8 = down
 
byte _dirkeys;        ///< 1 = left, 2 = up, 4 = right, 8 = down
 
bool _fullscreen;
 
CursorVars _cursor;
 
bool _ctrl_pressed;   // Is Ctrl pressed?
 
bool _shift_pressed;  // Is Shift pressed?
 
bool _ctrl_pressed;   ///< Is Ctrl pressed?
 
bool _shift_pressed;  ///< Is Shift pressed?
 
byte _fast_forward;
 
bool _left_button_down;
 
bool _left_button_clicked;
 
bool _right_button_down;
 
bool _right_button_clicked;
 
DrawPixelInfo _screen;
 
@@ -85,22 +87,22 @@ void GfxScroll(int left, int top, int wi
 
	if (_cursor.visible) UndrawMouseCursor();
 
	UndrawTextMessage();
 

	
 
	p = _screen.pitch;
 

	
 
	if (yo > 0) {
 
		// Calculate pointers
 
		/*Calculate pointers */
 
		dst = _screen.dst_ptr + (top + height - 1) * p + left;
 
		src = dst - yo * p;
 

	
 
		// Decrease height and increase top
 
		/* Decrease height and increase top */
 
		top += yo;
 
		height -= yo;
 
		assert(height > 0);
 

	
 
		// Adjust left & width
 
		/* Adjust left & width */
 
		if (xo >= 0) {
 
			dst += xo;
 
			left += xo;
 
			width -= xo;
 
		} else {
 
			src -= xo;
 
@@ -110,39 +112,39 @@ void GfxScroll(int left, int top, int wi
 
		for (ht = height; ht > 0; --ht) {
 
			memcpy(dst, src, width);
 
			src -= p;
 
			dst -= p;
 
		}
 
	} else {
 
		// Calculate pointers
 
		/* Calculate pointers */
 
		dst = _screen.dst_ptr + top * p + left;
 
		src = dst - yo * p;
 

	
 
		// Decrese height. (yo is <=0).
 
		/* Decrese height. (yo is <=0). */
 
		height += yo;
 
		assert(height > 0);
 

	
 
		// Adjust left & width
 
		/* Adjust left & width */
 
		if (xo >= 0) {
 
			dst += xo;
 
			left += xo;
 
			width -= xo;
 
		} else {
 
			src -= xo;
 
			width += xo;
 
		}
 

	
 
		// the y-displacement may be 0 therefore we have to use memmove,
 
		// because source and destination may overlap
 
		/* the y-displacement may be 0 therefore we have to use memmove,
 
		 * because source and destination may overlap */
 
		for (ht = height; ht > 0; --ht) {
 
			memmove(dst, src, width);
 
			src += p;
 
			dst += p;
 
		}
 
	}
 
	// This part of the screen is now dirty.
 
	/* This part of the screen is now dirty. */
 
	_video_driver->make_dirty(left, top, width, height);
 
}
 

	
 

	
 
void GfxFillRect(int left, int top, int right, int bottom, int color)
 
{
 
@@ -209,13 +211,13 @@ void GfxDrawLine(int x, int y, int x2, i
 
	int dy;
 
	int dx;
 
	int stepx;
 
	int stepy;
 
	int frac;
 

	
 
	// Check clipping first
 
	/* Check clipping first */
 
	{
 
		DrawPixelInfo *dpi = _cur_dpi;
 
		int t;
 

	
 
		if (x < dpi->left && x2 < dpi->left) return;
 

	
 
@@ -289,13 +291,13 @@ static int TruncateString(char *str, int
 

	
 
	for (ddd_pos = str; (c = Utf8Consume((const char **)&str)) != '\0'; ) {
 
		if (IsPrintable(c)) {
 
			w += GetCharacterWidth(size, c);
 

	
 
			if (w >= maxw) {
 
				// string got too big... insert dotdotdot
 
				/* string got too big... insert dotdotdot */
 
				ddd_pos[0] = ddd_pos[1] = ddd_pos[2] = '.';
 
				ddd_pos[3] = 0;
 
				return ddd_w;
 
			}
 
		} else {
 
			if (c == SCC_SETX) str++;
 
@@ -306,13 +308,13 @@ static int TruncateString(char *str, int
 
			} else if (c == SCC_BIGFONT) {
 
				size = FS_LARGE;
 
				ddd = GetCharacterWidth(size, '.') * 3;
 
			}
 
		}
 

	
 
		// Remember the last position where three dots fit.
 
		/* Remember the last position where three dots fit. */
 
		if (w + ddd < maxw) {
 
			ddd_w = w + ddd;
 
			ddd_pos = str;
 
		}
 
	}
 

	
 
@@ -1541,22 +1543,22 @@ void DoPaletteAnimations(void)
 
	uint i;
 
	uint j;
 

	
 
	d = &_cur_palette[217];
 
	memcpy(old_val, d, c * sizeof(*old_val));
 

	
 
	// Dark blue water
 
	/* Dark blue water */
 
	s = (_opt.landscape == LT_CANDY) ? ev->ac : ev->a;
 
	j = EXTR(320, 5);
 
	for (i = 0; i != 5; i++) {
 
		*d++ = s[j];
 
		j++;
 
		if (j == 5) j = 0;
 
	}
 

	
 
	// Glittery water
 
	/* Glittery water */
 
	s = (_opt.landscape == LT_CANDY) ? ev->bc : ev->b;
 
	j = EXTR(128, 15);
 
	for (i = 0; i != 5; i++) {
 
		*d++ = s[j];
 
		j += 3;
 
		if (j >= 15) j -= 15;
 
@@ -1567,22 +1569,22 @@ void DoPaletteAnimations(void)
 
	for (i = 0; i != 5; i++) {
 
		*d++ = s[j];
 
		j++;
 
		if (j == 5) j = 0;
 
	}
 

	
 
	// Oil refinery fire animation
 
	/* Oil refinery fire animation */
 
	s = ev->oil_ref;
 
	j = EXTR2(512, 7);
 
	for (i = 0; i != 7; i++) {
 
		*d++ = s[j];
 
		j++;
 
		if (j == 7) j = 0;
 
	}
 

	
 
	// Radio tower blinking
 
	/* Radio tower blinking */
 
	{
 
		byte i = (_timer_counter >> 1) & 0x7F;
 
		byte v;
 

	
 
		(v = 255, i < 0x3f) ||
 
		(v = 128, i < 0x4A || i >= 0x75) ||
 
@@ -1599,33 +1601,33 @@ void DoPaletteAnimations(void)
 
		d->r = v;
 
		d->g = 0;
 
		d->b = 0;
 
		d++;
 
	}
 

	
 
	// Handle lighthouse and stadium animation
 
	/* Handle lighthouse and stadium animation */
 
	s = ev->lighthouse;
 
	j = EXTR(256, 4);
 
	for (i = 0; i != 4; i++) {
 
		*d++ = s[j];
 
		j++;
 
		if (j == 4) j = 0;
 
	}
 

	
 
	// Animate water for old DOS graphics
 
	/* Animate water for old DOS graphics */
 
	if (_use_dos_palette) {
 
		// Dark blue water DOS
 
		/* Dark blue water DOS */
 
		s = (_opt.landscape == LT_CANDY) ? ev->ac : ev->a;
 
		j = EXTR(320, 5);
 
		for (i = 0; i != 5; i++) {
 
			*d++ = s[j];
 
			j++;
 
			if (j == 5) j = 0;
 
		}
 

	
 
		// Glittery water DOS
 
		/* Glittery water DOS */
 
		s = (_opt.landscape == LT_CANDY) ? ev->bc : ev->b;
 
		j = EXTR(128, 15);
 
		for (i = 0; i != 5; i++) {
 
			*d++ = s[j];
 
			j += 3;
 
			if (j >= 15) j -= 15;
 
@@ -1667,17 +1669,17 @@ byte GetCharacterWidth(FontSize size, WC
 
	return GetGlyphWidth(size, key);
 
}
 

	
 

	
 
void ScreenSizeChanged(void)
 
{
 
	// check the dirty rect
 
	/* check the dirty rect */
 
	if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
 
	if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;
 

	
 
	// screen size changed and the old bitmap is invalid now, so we don't want to undraw it
 
	/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
 
	_cursor.visible = false;
 
}
 

	
 
void UndrawMouseCursor(void)
 
{
 
	if (_cursor.visible) {
 
@@ -1698,13 +1700,13 @@ void DrawMouseCursor(void)
 
	int w;
 
	int h;
 

	
 
	/* Redraw mouse cursor but only when it's inside the window */
 
	if (!_cursor.in_window) return;
 

	
 
	// Don't draw the mouse cursor if it's already drawn
 
	/* Don't draw the mouse cursor if it's already drawn */
 
	if (_cursor.visible) {
 
		if (!_cursor.dirty) return;
 
		UndrawMouseCursor();
 
	}
 

	
 
	w = _cursor.size.x;
 
@@ -1728,19 +1730,19 @@ void DrawMouseCursor(void)
 
	if (h <= 0) return;
 
	_cursor.draw_pos.y = y;
 
	_cursor.draw_size.y = h;
 

	
 
	assert(w * h < (int)sizeof(_cursor_backup));
 

	
 
	// Make backup of stuff below cursor
 
	/* Make backup of stuff below cursor */
 
	memcpy_pitch(
 
		_cursor_backup,
 
		_screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch,
 
		_cursor.draw_size.x, _cursor.draw_size.y, _screen.pitch, _cursor.draw_size.x);
 

	
 
	// Draw cursor on screen
 
	/* Draw cursor on screen */
 
	_cur_dpi = &_screen;
 
	DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x, _cursor.pos.y);
 

	
 
	_video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y);
 

	
 
	_cursor.visible = true;
 
@@ -1803,35 +1805,35 @@ void DrawDirtyBlocks(void)
 
				int top;
 
				int right = x + 64;
 
				int bottom = y;
 
				byte *p = b;
 
				int h2;
 

	
 
				// First try coalescing downwards
 
				/* First try coalescing downwards */
 
				do {
 
					*p = 0;
 
					p += DIRTY_BYTES_PER_LINE;
 
					bottom += 8;
 
				} while (bottom != h && *p != 0);
 

	
 
				// Try coalescing to the right too.
 
				/* Try coalescing to the right too. */
 
				h2 = (bottom - y) >> 3;
 
				assert(h2 > 0);
 
				p = b;
 

	
 
				while (right != w) {
 
					byte *p2 = ++p;
 
					int h = h2;
 
					// Check if a full line of dirty flags is set.
 
					/* Check if a full line of dirty flags is set. */
 
					do {
 
						if (!*p2) goto no_more_coalesc;
 
						p2 += DIRTY_BYTES_PER_LINE;
 
					} while (--h != 0);
 

	
 
					// Wohoo, can combine it one step to the right!
 
					// Do that, and clear the bits.
 
					/* Wohoo, can combine it one step to the right!
 
					 * Do that, and clear the bits. */
 
					right += 64;
 

	
 
					h = h2;
 
					p2 = p;
 
					do {
 
						*p2 = 0;
 
@@ -2002,15 +2004,15 @@ void CursorTick(void)
 
	if (_cursor.animate_timeout != 0 && --_cursor.animate_timeout == 0)
 
		SwitchAnimatedCursor();
 
}
 

	
 
void SetMouseCursor(SpriteID sprite, SpriteID pal)
 
{
 
	// Turn off animation
 
	/* Turn off animation */
 
	_cursor.animate_timeout = 0;
 
	// Set cursor
 
	/* Set cursor */
 
	SetCursorSprite(sprite, pal);
 
}
 

	
 
void SetAnimatedMouseCursor(const AnimCursor *table)
 
{
 
	_cursor.animate_list = table;