Loading
#openttdcoop - Paste
Archives
Trending
Docs
Login
ABAP
ActionScript
ActionScript 3
Ada
AIMMS3
ALGOL 68
Apache configuration
AppleScript
Apt sources
ARM ASSEMBLER
ASM
ASP
asymptote
Autoconf
Autohotkey
AutoIt
AviSynth
awk
BASCOM AVR
Bash
Basic4GL
BibTeX
BlitzBasic
bnf
Boo
Brainfuck
C
C#
C (LoadRunner)
C (Mac)
C (WinAPI)
C++
C++ (Qt)
C++ (WinAPI)
CAD DCL
CAD Lisp
CFDG
ChaiScript
Chapel
CIL
Clojure
CMake
COBOL
CoffeeScript
ColdFusion
CSS
Cuesheet
D
Dart
DCL
DCPU-16 Assembly
DCS
Delphi
Diff
DIV
DOS
dot
E
ECMAScript
Eiffel
eMail (mbox)
EPC
Erlang
Euphoria
EZT
F#
Falcon
FO (abas-ERP)
Formula One
Fortran
FreeBasic
FreeSWITCH
GADV 4CS
GAMBAS
GDB
genero
Genie
glSlang
GML
GNU/Octave
GNU Gettext
GNU make
Gnuplot
Go
Groovy
GwBasic
Haskell
Haxe
HicEst
HQ9+
HTML
HTML5
Icon
INI
Inno
INTERCAL
Io
ISPF Panel
J
Java
Java(TM) 2 Platform Standard Edition 5.0
Javascript
JCL
jQuery
KiXtart
KLone C
KLone C++
LaTeX
LDIF
Liberty BASIC
Lisp
LLVM Intermediate Representation
Locomotive Basic
Logtalk
LOLcode
Lotus Notes @Formulas
LotusScript
LScript
LSL2
Lua
MagikSF
MapBasic
Matlab M
Microchip Assembler
Microsoft Registry
mIRC Scripting
MMIX
Modula-2
Modula-3
MOS 6502 (6510) ACME Cross Assembler format
MOS 6502 (6510) Kick Assembler format
MOS 6502 (6510) TASM/64TASS 1.46 Assembler format
Motorola 68000 - HiSoft Devpac ST 2 Assembler format
Motorola 68000 Assembler
MXML
MySQL
Nagios
NetRexx
newlisp
nginx
Nimrod
NML NewGRF Meta Language
NSIS
Oberon-2
Objeck Programming Language
Objective-C
OCaml
OCaml (brief)
ooRexx
OpenBSD Packet Filter
OpenOffice.org Basic
Oracle 8 SQL
Oracle 11 SQL
Oxygene
OZ
ParaSail
PARI/GP
Pascal
PCRE
per
Perl
Perl 6
PHP
PHP (brief)
PIC16
Pike
Pixel Bender 1.0
PL/I
PL/SQL
PostgreSQL
PostScript
POVRAY
PowerBuilder
PowerShell
ProFTPd configuration
Progress
Prolog
PROPERTIES
ProvideX
Puppet
PureBasic
Python
Python for S60
q/kdb+
QBasic/QuickBASIC
QML
R / S+
Racket
Rails
RBScript
REBOL
rexx
robots.txt
RPM Specification File
Ruby
Rust
SAS
Scala
Scheme
SciLab
SCL
sdlBasic
Smalltalk
Smarty
SPARK
SPARQL
SQL
Squirrel Script
Squirrel Script with OpenTTD AI/GS
StandardML
StoneScript
SystemVerilog
T-SQL
TCL
Tera Term Macro
Text
thinBasic
TypoScript
Unicon (Unified Extended Dialect of Icon)
Uno Idl
Unreal Script
UPC
Urbi
Vala
vb.net
VBScript
Vedit macro language
Verilog
VHDL
Vim Script
Visual Basic
Visual Fox Pro
Visual Prolog
Whitespace
Whois (RPSL format)
Winbatch
X++
XBasic
XML
Xorg configuration
YAML
ZiLOG Z80 Assembler
ZXBasic
diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 8298f2d..c23a66c 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -108,7 +108,7 @@ void DropdownMenuWindow::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) for (auto const &item : this->items) { if (it == this->selected_index) { Rectangle32 r = {this->rect.base.x, y, static_cast<uint>(wid->pos.width - 1), static_cast<uint>(GetTextHeight())}; - _video.FillSurface(_palette[GetColourRangeBase(COL_RANGE_GREY) + 7], r); + _video.FillSurface(r, _palette[GetColourRangeBase(COL_RANGE_GREY) + 7]); } _video.BlitText(item.str, MakeRGBA(255, 255, 255, OPAQUE), this->rect.base.x, y, wid->pos.width); diff --git a/src/fence_gui.cpp b/src/fence_gui.cpp index 7532717..fbc9718 100644 --- a/src/fence_gui.cpp +++ b/src/fence_gui.cpp @@ -115,7 +115,7 @@ void FenceGui::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) const lines--; Recolouring recolouring; - _video.BlitImage(rect.x, rect.y - sprite->yoffset, sprite, recolouring, GS_NORMAL); + _video.BlitImage({rect.x, rect.y - sprite->yoffset}, sprite, recolouring); rect.y += sprite->height; } break; diff --git a/src/gui_graphics.cpp b/src/gui_graphics.cpp index c0528dc..a583266 100644 --- a/src/gui_graphics.cpp +++ b/src/gui_graphics.cpp @@ -30,12 +30,12 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl rc.Set(0, RecolourEntry(COL_RANGE_BROWN, colour)); Point32 pt = rect.base; - _video.BlitImage(pt, spr_base[WBS_TOP_LEFT], rc, GS_NORMAL); + _video.BlitImage(pt, spr_base[WBS_TOP_LEFT], rc); int xleft = pt.x + spr_base[WBS_TOP_LEFT]->xoffset + spr_base[WBS_TOP_LEFT]->width; int ytop = pt.y + spr_base[WBS_TOP_LEFT]->yoffset + spr_base[WBS_TOP_LEFT]->height; pt.x = rect.base.x + rect.width - 1; - _video.BlitImage(pt, spr_base[WBS_TOP_RIGHT], rc, GS_NORMAL); + _video.BlitImage(pt, spr_base[WBS_TOP_RIGHT], rc); int xright = pt.x + spr_base[WBS_TOP_RIGHT]->xoffset; uint16 numx = (xright - xleft) / spr_base[WBS_TOP_MIDDLE]->width; @@ -43,7 +43,7 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl pt.x = rect.base.x; pt.y = rect.base.y + rect.height - 1; - _video.BlitImage(pt, spr_base[WBS_BOTTOM_LEFT], rc, GS_NORMAL); + _video.BlitImage(pt, spr_base[WBS_BOTTOM_LEFT], rc); int ybot = pt.y + spr_base[WBS_BOTTOM_LEFT]->yoffset; uint16 numy = (ybot - ytop) / spr_base[WBS_MIDDLE_LEFT]->height; @@ -51,14 +51,15 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl pt.x = rect.base.x + rect.width - 1; pt.y = rect.base.y + rect.height - 1; - _video.BlitImage(pt, spr_base[WBS_BOTTOM_RIGHT], rc, GS_NORMAL); + _video.BlitImage(pt, spr_base[WBS_BOTTOM_RIGHT], rc); _video.BlitHorizontal(xleft, numx, pt.y, spr_base[WBS_BOTTOM_MIDDLE], rc); pt.x = rect.base.x + rect.width - 1; _video.BlitVertical(ytop, numy, pt.x, spr_base[WBS_MIDDLE_RIGHT], rc); - _video.BlitImages(xleft, ytop, spr_base[WBS_MIDDLE_MIDDLE], numx, numy, rc); + Rectangle32 inner_rect(xleft, ytop, numx, numy); + _video.FillSurface(inner_rect, rc.GetPalette(GS_NORMAL)[7]); } /** @@ -75,21 +76,14 @@ void OverlayShaded(const Rectangle32 &rect) r.RestrictTo(0, 0, _video.GetXSize(), _video.GetYSize()); if (r.width == 0 || r.height == 0) return; - /* Set clipped area to the rectangle. */ - ClippedRectangle cr(_video.GetClippedRectangle()); - ClippedRectangle new_cr(cr, r.base.x, r.base.y, r.width, r.height); - _video.SetClippedRectangle(new_cr); - /* Align the disabled sprite so it becomes a continuous pattern. */ - int32 base_x = -(r.base.x % img->width); - int32 base_y = -(r.base.y % img->height); + int32 base_x = r.base.x - (r.base.x % img->width); + int32 base_y = r.base.y - (r.base.y % img->height); uint16 numx = (r.width + img->width - 1) / img->width; uint16 numy = (r.height + img->height - 1) / img->height; static const Recolouring recolour; // Fixed recolouring mapping. - _video.BlitImages(base_x, base_y, img, numx, numy, recolour); - - _video.SetClippedRectangle(cr); // Restore clipped area. + _video.BlitImages({base_x, base_y}, img, numx, numy, recolour); } /** @@ -109,10 +103,11 @@ void DrawString(StringID strid, uint8 colour, int x, int y, int width, Alignment DrawText(strid, buffer, lengthof(buffer)); /** \todo Reduce the naiviness of this. */ if (outline) { - _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y, width, align); - _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y + 1, width, align); - _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x - 1, y, width, align); - _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y - 1, width, align); +// _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y, width, align); +// _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y + 1, width, align); +// _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x - 1, y, width, align); +// _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y - 1, width, align); + _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y + 1, width, align); } _video.BlitText(buffer, _palette[colour], x, y, width, align); } diff --git a/src/palette.h b/src/palette.h index 1e98317..fdc5122 100644 --- a/src/palette.h +++ b/src/palette.h @@ -86,6 +86,8 @@ static inline uint32 SetA(uint32 rgba, uint8 opacity) return rgba | opacity; } +#define SPLIT_RGBA(rgba) GetR(rgba), GetG(rgba), GetB(rgba), GetA(rgba) + /** Names of colour ranges. */ enum ColourRange { COL_RANGE_GREY, diff --git a/src/path_gui.cpp b/src/path_gui.cpp index cd808b0..d5beca9 100644 --- a/src/path_gui.cpp +++ b/src/path_gui.cpp @@ -225,7 +225,8 @@ void PathBuildGui::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) const if (img != nullptr) { int dx = (wid->pos.width - path_type_button_size.width) / 2; int dy = (wid->pos.height - path_type_button_size.height) / 2; - _video.BlitImage(GetWidgetScreenX(wid) + dx - path_type_button_size.base.x, GetWidgetScreenY(wid) + dy - path_type_button_size.base.y, img, recolour, GS_NORMAL); + Point32 pt(GetWidgetScreenX(wid) + dx - path_type_button_size.base.x, GetWidgetScreenY(wid) + dy - path_type_button_size.base.y); + _video.BlitImage(pt, img, recolour); } } break; @@ -239,7 +240,8 @@ void PathBuildGui::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) const if (img != nullptr) { int dx = (wid->pos.width - path_type_button_size.width) / 2; int dy = (wid->pos.height - path_type_button_size.height) / 2; - _video.BlitImage(GetWidgetScreenX(wid) + dx - path_type_button_size.base.x, GetWidgetScreenY(wid) + dy - path_type_button_size.base.y, img, recolour, GS_NORMAL); + Point32 pt(GetWidgetScreenX(wid) + dx - path_type_button_size.base.x, GetWidgetScreenY(wid) + dy - path_type_button_size.base.y); + _video.BlitImage(pt, img, recolour); } } break; diff --git a/src/ride_gui.cpp b/src/ride_gui.cpp index cfa2795..0ea21b1 100644 --- a/src/ride_gui.cpp +++ b/src/ride_gui.cpp @@ -221,9 +221,8 @@ void RideSelectGui::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) cons /* Display the selected shop in the ride select window. */ if (ride_type != nullptr && ride_type->kind == RTK_SHOP) { static const Recolouring recolour; // Never modified, display 'original' image in the GUI. - _video.BlitImage(this->GetWidgetScreenX(wid) + wid->pos.width / 2, - this->GetWidgetScreenY(wid) + 40, ride_type->GetView(_shop_placer.orientation), - recolour, GS_NORMAL); + Point32 pt(this->GetWidgetScreenX(wid) + wid->pos.width / 2, this->GetWidgetScreenY(wid) + 40); + _video.BlitImage(pt, ride_type->GetView(_shop_placer.orientation), recolour); } } break; diff --git a/src/sprite_data.cpp b/src/sprite_data.cpp index 28b3ce0..5fd4389 100644 --- a/src/sprite_data.cpp +++ b/src/sprite_data.cpp @@ -27,6 +27,7 @@ ImageData::ImageData() this->height = 0; this->table = nullptr; this->data = nullptr; + this->image = nullptr; } ImageData::~ImageData() diff --git a/src/sprite_data.h b/src/sprite_data.h index 049990c..5987aa2 100644 --- a/src/sprite_data.h +++ b/src/sprite_data.h @@ -12,6 +12,8 @@ #ifndef SPRITE_DATA_H #define SPRITE_DATA_H +#include <SDL.h> + static const uint32 INVALID_JUMP = UINT32_MAX; ///< Invalid jump destination in image data. class RcdFileReader; @@ -42,6 +44,8 @@ public: int16 yoffset; ///< Vertical offset of the image. uint32 *table; ///< The jump table. For missing entries, #INVALID_JUMP is used. uint8 *data; ///< The image data itself. + + mutable SDL_Texture *image; }; ImageData *LoadImage(RcdFileReader *rcd_file); diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index dbf13a5..5cd5eaf 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -103,7 +103,7 @@ void TerraformGui::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid) const base.x = this->GetWidgetScreenX(wid) + (wid->pos.width - dot->width) / 2; base.y = this->GetWidgetScreenY(wid) + (wid->pos.height - dot->height) / 2; - _video.BlitImage(base, dot, recolour, GS_NORMAL); + _video.BlitImage(base, dot, recolour); return; } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 590e9f8..51f49ae 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -368,14 +368,14 @@ void BottomToolbarWindow::DrawWidget(WidgetNumber wid_num, const BaseWidget *wid Viewport *vp = GetViewport(); int dir = (vp == nullptr) ? 0 : vp->orientation; const ImageData *img = _sprite_manager.GetTableSprite(SPR_GUI_COMPASS_START + dir); - if (img != nullptr) _video.BlitImage(GetWidgetScreenX(wid), GetWidgetScreenY(wid), img, recolour, GS_NORMAL); + if (img != nullptr) _video.BlitImage({GetWidgetScreenX(wid), GetWidgetScreenY(wid)}, img, recolour); break; } case BTB_WEATHER: { int spr = SPR_GUI_WEATHER_START + _weather.GetWeatherType(); const ImageData *img = _sprite_manager.GetTableSprite(spr); - if (img != nullptr) _video.BlitImage(GetWidgetScreenX(wid), GetWidgetScreenY(wid), img, recolour, GS_NORMAL); + if (img != nullptr) _video.BlitImage({GetWidgetScreenX(wid), GetWidgetScreenY(wid)}, img, recolour); break; } } diff --git a/src/video.cpp b/src/video.cpp index 748e120..204ef44 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -31,100 +31,6 @@ void QuitProgram() _finish = true; } -/** Default constructor of a clipped rectangle. */ -ClippedRectangle::ClippedRectangle() -{ - this->absx = 0; - this->absy = 0; - this->width = 0; - this->height = 0; - this->address = nullptr; this->pitch = 0; -} - -/** - * Construct a clipped rectangle from coordinates. - * @param x Top-left x position. - * @param y Top-left y position. - * @param w Width. - * @param h Height. - */ -ClippedRectangle::ClippedRectangle(uint16 x, uint16 y, uint16 w, uint16 h) -{ - this->absx = x; - this->absy = y; - this->width = w; - this->height = h; - this->address = nullptr; this->pitch = 0; -} - -/** - * Construct a clipped rectangle inside an existing one. - * @param cr Existing rectangle. - * @param x Top-left x position. - * @param y Top-left y position. - * @param w Width. - * @param h Height. - * @note %Rectangle is clipped to the old one. - */ -ClippedRectangle::ClippedRectangle(const ClippedRectangle &cr, uint16 x, uint16 y, uint16 w, uint16 h) -{ - if (x >= cr.width || y >= cr.height) { - this->absx = 0; - this->absy = 0; - this->width = 0; - this->height = 0; - this->address = nullptr; this->pitch = 0; - return; - } - if (x + w > cr.width) w = cr.width - x; - if (y + h > cr.height) h = cr.height - y; - - this->absx = cr.absx + x; - this->absy = cr.absy + y; - this->width = w; - this->height = h; - this->address = nullptr; this->pitch = 0; -} - -/** - * Copy constructor. - * @param cr Existing clipped rectangle. - */ -ClippedRectangle::ClippedRectangle(const ClippedRectangle &cr) -{ - this->absx = cr.absx; - this->absy = cr.absy; - this->width = cr.width; - this->height = cr.height; - this->address = cr.address; this->pitch = cr.pitch; -} - -/** - * Assignment operator override. - * @param cr Existing clipped rectangle. - * @return The assigned value. - */ -ClippedRectangle &ClippedRectangle::operator=(const ClippedRectangle &cr) -{ - if (this != &cr) { - this->absx = cr.absx; - this->absy = cr.absy; - this->width = cr.width; - this->height = cr.height; - this->address = cr.address; this->pitch = cr.pitch; - } - return *this; -} - -/** Initialize the #address if not done already. */ -void ClippedRectangle::ValidateAddress() -{ - if (this->address == nullptr) { - this->pitch = _video.GetXSize(); - this->address = _video.mem + this->absx + this->absy * this->pitch; - } -} - /** * Default constructor, does nothing, never goes wrong. * Call #Initialize to initialize the system. @@ -165,9 +71,18 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size) return err; } + this->renderer = SDL_CreateRenderer(this->window, -1, 0); + if (this->renderer == nullptr) { + std::string err = "Could not create renderer: "; + err += SDL_GetError(); + SDL_Quit(); + return err; + } + SDL_SetRenderDrawBlendMode(this->renderer, SDL_BLENDMODE_BLEND); + this->GetResolutions(); - this->SetResolution({800, 600}); // Allocates this->mem, return value is ignored. + this->SetResolution({800, 600}); // return value is ignored. /* SDL_CreateRGBSurfaceFrom() pretends to use a void* for the data, * but it's really treated as endian-specific uint32*. @@ -183,12 +98,11 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size) SDL_SetWindowIcon(this->window, icon); SDL_FreeSurface(icon); } else { - printf("Could not set window icon (%s)\n", SDL_GetError()); + fprintf(stderr, "Could not set window icon (%s)\n", SDL_GetError()); } if (TTF_Init() != 0) { SDL_Quit(); - delete[] this->mem; std::string err = "TTF font initialization failed: "; err += TTF_GetError(); return err; @@ -204,7 +118,6 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size) err += TTF_GetError(); TTF_Quit(); SDL_Quit(); - delete[] this->mem; return err; } @@ -230,43 +143,12 @@ bool VideoSystem::SetResolution(const Point32 &res) { if (this->initialized && this->GetXSize() == res.x && this->GetYSize() == res.y) return true; - /* Destroy old window, if it exists. */ - if (this->initialized) { - delete[] mem; - this->mem = nullptr; - SDL_DestroyTexture(this->texture); - this->texture = nullptr; - SDL_DestroyRenderer(this->renderer); - this->renderer = nullptr; - } - this->vid_width = res.x; this->vid_height = res.y; SDL_SetWindowSize(this->window, this->vid_width, this->vid_height); - this->renderer = SDL_CreateRenderer(this->window, -1, 0); - if (this->renderer == nullptr) { - SDL_Quit(); - fprintf(stderr, "Could not create renderer (%s)\n", SDL_GetError()); - return false; - } - - this->texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, this->vid_width, this->vid_height); - if (this->texture == nullptr) { - SDL_Quit(); - fprintf(stderr, "Could not create texture (%s)\n", SDL_GetError()); - return false; - } - - this->mem = new uint32[this->vid_width * this->vid_height]; - if (this->mem == nullptr) { - SDL_Quit(); - fprintf(stderr, "Failed to obtain window display storage.\n"); - return false; - } - /* Update internal screen size data structures. */ - this->blit_rect = ClippedRectangle(0, 0, this->vid_width, this->vid_height); + this->blit_rect = Rectangle32(0, 0, this->vid_width, this->vid_height); Viewport *vp = GetViewport(); if (vp != nullptr) vp->SetSize(this->vid_width, this->vid_height); _manager.RepositionAllWindows(); @@ -314,18 +196,17 @@ void VideoSystem::MarkDisplayClean() * Set the clipped area. * @param cr New clipped blitting area. */ -void VideoSystem::SetClippedRectangle(const ClippedRectangle &cr) +void VideoSystem::SetClippedRectangle(const Rectangle32 &rect) { - this->blit_rect = cr; + this->blit_rect = rect; } /** * Get the current clipped blitting area. * @return Current clipped area. */ -ClippedRectangle VideoSystem::GetClippedRectangle() +Rectangle32 VideoSystem::GetClippedRectangle() { - this->blit_rect.ValidateAddress(); return this->blit_rect; } @@ -439,6 +320,9 @@ void VideoSystem::MainLoop() if (_finish) break; uint32 now = SDL_GetTicks(); + + printf("%dms\n", now - start); + if (now >= start) { // No wrap around. now -= start; if (now < FRAME_DELAY) SDL_Delay(FRAME_DELAY - now); // Too early, wait until next frame. @@ -458,7 +342,6 @@ void VideoSystem::Shutdown() TTF_CloseFont(this->font); TTF_Quit(); SDL_Quit(); - delete[] this->mem; this->initialized = false; this->dirty = false; } @@ -470,11 +353,12 @@ void VideoSystem::Shutdown() */ void VideoSystem::FinishRepaint() { - SDL_UpdateTexture(this->texture, nullptr, this->mem, this->GetXSize() * sizeof(uint32)); // Upload memory to the GPU. - SDL_RenderClear(this->renderer); - SDL_RenderCopy(this->renderer, this->texture, nullptr, nullptr); SDL_RenderPresent(this->renderer); + /* Reset the renderer */ + SDL_SetRenderDrawColor(this->renderer, 0, 0, 0, 0); + SDL_RenderClear(this->renderer); + MarkDisplayClean(); } @@ -483,333 +367,96 @@ void VideoSystem::FinishRepaint() * @param colour Colour to fill with. * @param rect %Rectangle to fill. */ -void VideoSystem::FillSurface(uint32 colour, const Rectangle32 &rect) -{ - ClippedRectangle cr = this->GetClippedRectangle(); - - int x = Clamp((int)rect.base.x, 0, (int)cr.width); - int w = Clamp((int)(rect.base.x + rect.width), 0, (int)cr.width); - int y = Clamp((int)rect.base.y, 0, (int)cr.height); - int h = Clamp((int)(rect.base.y + rect.height), 0, (int)cr.height); - - w -= x; - h -= y; - if (w == 0 || h == 0) return; - - uint32 *pixels_base = cr.address + x + y * cr.pitch; - while (h > 0) { - uint32 *pixels = pixels_base; - for (int i = 0; i < w; i++) *pixels++ = colour; - pixels_base += cr.pitch; - h--; - } -} - -/** - * Blit pixels from the \a spr relative to #blit_rect into the area. - * @param img_base Coordinate of the sprite data. - * @param spr The sprite to blit. - * @param recolour Sprite recolouring definition. - * @param shift Gradient shift. - */ -void VideoSystem::BlitImage(const Point32 &img_base, const ImageData *spr, const Recolouring &recolour, GradientShift shift) +void VideoSystem::FillSurface(const Rectangle32 &rect, uint32 colour) { - this->BlitImage(img_base.x, img_base.y, spr, recolour, shift); -} - -static const int STEP_SIZE = 18; ///< Amount of colour shift for each gradient step. -typedef uint8 (*ShiftFunc)(uint8); ///< Type of the gradient shift function. - -/** - * Gradient shift function for #GS_NIGHT. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientNight(uint8 col) -{ - return (col <= 4 * STEP_SIZE) ? 0 : col - 4 * STEP_SIZE; -} - -/** - * Gradient shift function for #GS_VERY_DARK. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientVeryDark(uint8 col) -{ - return (col <= 3 * STEP_SIZE) ? 0 : col - 3 * STEP_SIZE; -} - -/** - * Gradient shift function for #GS_DARK - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientDark(uint8 col) -{ - return (col <= 2 * STEP_SIZE) ? 0 : col - 2 * STEP_SIZE; -} - -/** - * Gradient shift function for #GS_SLIGHTLY_DARK. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientSlightlyDark(uint8 col) -{ - return (col <= STEP_SIZE) ? 0 : col - STEP_SIZE; -} - -/** - * Gradient shift function for #GS_NORMAL. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientNormal(uint8 col) -{ - return col; -} - -/** - * Gradient shift function for #GS_SLIGHTLY_LIGHT. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientSlightlyLight(uint8 col) -{ - return (col >= 255 - STEP_SIZE) ? 255: col + STEP_SIZE; -} - -/** - * Gradient shift function for #GS_LIGHT. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientLight(uint8 col) -{ - return (col >= 255 - 2 * STEP_SIZE) ? 255: col + 2 * STEP_SIZE; -} - -/** - * Gradient shift function for #GS_VERY_LIGHT. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientVeryLight(uint8 col) -{ - return (col >= 255 - 3 * STEP_SIZE) ? 255: col + 3 * STEP_SIZE; -} - -/** - * Gradient shift function for #GS_DAY. - * @param col Input colour. - * @return Shifted result colour. - */ -static uint8 ShiftGradientDay(uint8 col) -{ - return (col >= 255 - 4 * STEP_SIZE) ? 255: col + 4 * STEP_SIZE; -} - -/** - * Select gradient shift function based on the \a shift. - * @param shift Desired amount of gradient shift. - * @return Recolour function implementing the shift. - */ -static ShiftFunc GetGradientShiftFunc(GradientShift shift) -{ - switch (shift) { - case GS_NIGHT: return ShiftGradientNight; - case GS_VERY_DARK: return ShiftGradientVeryDark; - case GS_DARK: return ShiftGradientDark; - case GS_SLIGHTLY_DARK: return ShiftGradientSlightlyDark; - case GS_NORMAL: return ShiftGradientNormal; - case GS_SLIGHTLY_LIGHT: return ShiftGradientSlightlyLight; - case GS_LIGHT: return ShiftGradientLight; - case GS_VERY_LIGHT: return ShiftGradientVeryLight; - case GS_DAY: return ShiftGradientDay; - default: NOT_REACHED(); - } -} - -/** - * Blit an image at the specified position (top-left position) relative to #blit_rect. - * @param x Horizontal position. - * @param y Vertical position. - * @param img The sprite image data to blit. - * @param recolour Sprite recolouring definition. - * @param shift Gradient shift. - */ -void VideoSystem::BlitImage(int x, int y, const ImageData *img, const Recolouring &recolour, GradientShift shift) -{ - this->BlitImages(x, y, img, 1, 1, recolour, shift); -} - -/** - * Blit a pixel to an area of \a numx times \a numy sprites. - * @param cr Clipped rectangle. - * @param scr_base Base address of the screen array. - * @param xmin Minimal x position. - * @param ymin Minimal y position. - * @param numx Number of horizontal count. - * @param numy Number of vertical count. - * @param width Width of an image. - * @param height Height of an image. - * @param colour Pixel value to blit. - * @note Function does not handle alpha blending of the new pixel with the background. - */ -static void BlitPixel(const ClippedRectangle &cr, uint32 *scr_base, - int32 xmin, int32 ymin, uint16 numx, uint16 numy, uint16 width, uint16 height, uint32 colour) -{ - const int32 xend = xmin + numx * width; - const int32 yend = ymin + numy * height; - while (ymin < yend) { - if (ymin >= cr.height) return; - - if (ymin >= 0) { - uint32 *scr = scr_base; - int32 x = xmin; - while (x < xend) { - if (x >= cr.width) break; - if (x >= 0) *scr = colour; - - x += width; - scr += width; - } - } - ymin += height; - scr_base += height * cr.pitch; - } + SDL_Rect sdl_rect = RectToSDLRect(rect); + SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour)); + SDL_RenderFillRect(this->renderer, &sdl_rect); } /** * Blit 8bpp images to the screen. - * @param cr Clipped rectangle to draw to. - * @param x_base Base X coordinate of the sprite data. - * @param y_base Base Y coordinate of the sprite data. * @param spr The sprite to blit. - * @param numx Number of sprites to draw in horizontal direction. - * @param numy Number of sprites to draw in vertical direction. * @param recoloured Shifted palette to use. */ -static void Blit8bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const uint8 *recoloured) +static std::vector<uint32> Blit8bppImage(const ImageData *spr, const uint8 *recoloured) { - uint32 *line_base = cr.address + x_base + cr.pitch * y_base; - int32 ypos = y_base; - for (int yoff = 0; yoff < spr->height; yoff++) { - uint32 offset = spr->table[yoff]; + std::vector<uint32> mem(spr->height * spr->width); + for (int ypos = 0; ypos < spr->height; ypos++) { + uint32 offset = spr->table[ypos]; if (offset != INVALID_JUMP) { - int32 xpos = x_base; - uint32 *src_base = line_base; - for (;;) { + for (int xpos = 0;;) { uint8 rel_off = spr->data[offset]; uint8 count = spr->data[offset + 1]; uint8 *pixels = &spr->data[offset + 2]; offset += 2 + count; - xpos += rel_off & 127; - src_base += rel_off & 127; - while (count > 0) { - uint32 colour = _palette[recoloured[*pixels]]; - BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour); + xpos += rel_off & 0x7F; + for (; count > 0; count--) { + mem.at(ypos * spr->width + xpos) = _palette[recoloured[*pixels]]; pixels++; xpos++; - src_base++; - count--; } - if ((rel_off & 128) != 0) break; + if ((rel_off & 0x80) != 0) break; } } - line_base += cr.pitch; - ypos++; } + return mem; } /** * Blit 32bpp images to the screen. - * @param cr Clipped rectangle to draw to. - * @param x_base Base X coordinate of the sprite data. - * @param y_base Base Y coordinate of the sprite data. * @param spr The sprite to blit. - * @param numx Number of sprites to draw in horizontal direction. - * @param numy Number of sprites to draw in vertical direction. * @param recolour Sprite recolouring definition. * @param shift Gradient shift. */ -static void Blit32bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift) +static std::vector<uint32> Blit32bppImage(const ImageData *spr, const Recolouring &recolour) { - uint32 *line_base = cr.address + x_base + cr.pitch * y_base; - ShiftFunc sf = GetGradientShiftFunc(shift); - int32 ypos = y_base; + std::vector<uint32> mem(spr->height * spr->width); const uint8 *src = spr->data + 2; // Skip the length word. - for (int yoff = 0; yoff < spr->height; yoff++) { - int32 xpos = x_base; - uint32 *src_base = line_base; - for (;;) { + for (int ypos = 0; ypos < spr->height; ypos++) { + for (int xpos = 0;;) { uint8 mode = *src++; if (mode == 0) break; + int len = mode & 0x3F; switch (mode >> 6) { case 0: // Fully opaque pixels. - mode &= 0x3F; - for (; mode > 0; mode--) { - uint32 colour = MakeRGBA(sf(src[0]), sf(src[1]), sf(src[2]), OPAQUE); - BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour); + for (; len > 0; len--) { + mem.at(ypos * spr->width + xpos) = MakeRGBA(src[0], src[1], src[2], OPAQUE); xpos++; - src_base++; src += 3; } break; case 1: { // Partial opaque pixels. uint8 opacity = *src++; - mode &= 0x3F; - for (; mode > 0; mode--) { - /* Cheat transparency a bit by just recolouring the previously drawn pixel */ - uint32 old_pixel = *src_base; - - uint r = sf(src[0]) * opacity + GetR(old_pixel) * (256 - opacity); - uint g = sf(src[1]) * opacity + GetG(old_pixel) * (256 - opacity); - uint b = sf(src[2]) * opacity + GetB(old_pixel) * (256 - opacity); - - /* Opaque, but colour adjusted depending on the old pixel. */ - uint32 ndest = MakeRGBA(r >> 8, g >> 8, b >> 8, OPAQUE); - BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, ndest); + for (; len > 0; len--) { + mem.at(ypos * spr->width + xpos) = MakeRGBA(src[0], src[1], src[2], opacity); xpos++; - src_base++; src += 3; } break; } case 2: // Fully transparent pixels. - xpos += mode & 0x3F; - src_base += mode & 0x3F; + xpos += len; break; case 3: { // Recoloured pixels. uint8 layer = *src++; const uint32 *table = recolour.GetRecolourTable(layer - 1); uint8 opacity = *src++; - mode &= 0x3F; - for (; mode > 0; mode--) { - uint32 old_pixel = *src_base; + for (; len > 0; len--) { uint32 recoloured = table[*src++]; - - uint r = sf(GetR(recoloured)) * opacity + GetR(old_pixel) * (256 - opacity); - uint g = sf(GetG(recoloured)) * opacity + GetG(old_pixel) * (256 - opacity); - uint b = sf(GetB(recoloured)) * opacity + GetB(old_pixel) * (256 - opacity); - - uint32 colour = MakeRGBA(r >> 8, g >> 8, b >> 8, OPAQUE); - BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour); + mem.at(ypos * spr->width + xpos) = SetA(recoloured, opacity); xpos++; - src_base++; } break; } } } - line_base += cr.pitch; - ypos++; src += 2; // Skip the length word. } + return mem; } /** @@ -822,30 +469,33 @@ static void Blit32bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_ba * @param recolour Sprite recolouring definition. * @param shift Gradient shift. */ -void VideoSystem::BlitImages(int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift) +void VideoSystem::BlitImages(const Point32 &img_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour) { - this->blit_rect.ValidateAddress(); + int x_base = img_base.x + spr->xoffset; + int y_base = img_base.y + spr->yoffset; - x_base += spr->xoffset; - y_base += spr->yoffset; + if (numx == 0 || numy == 0) return; - /* Don't draw wildly outside the screen. */ - while (numx > 0 && x_base + spr->width < 0) { - x_base += spr->width; numx--; - } - while (numx > 0 && x_base + (numx - 1) * spr->width >= this->blit_rect.width) numx--; - if (numx == 0) return; + if (spr->image == nullptr) { + std::vector<uint32> img; + if (GB(spr->flags, IFG_IS_8BPP, 1) != 0) { + img = Blit8bppImage(spr, recolour.GetPalette(GS_NORMAL)); + } else { + img = Blit32bppImage(spr, recolour); + } - while (numy > 0 && y_base + spr->height < 0) { - y_base += spr->height; numy--; + spr->image = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, spr->width, spr->height); + SDL_UpdateTexture(spr->image, nullptr, img.data(), spr->width * sizeof(uint32)); + SDL_SetTextureBlendMode(spr->image, SDL_BLENDMODE_BLEND); } - while (numy > 0 && y_base + (numy - 1) * spr->height >= this->blit_rect.height) numy--; - if (numy == 0) return; - if (GB(spr->flags, IFG_IS_8BPP, 1) != 0) { - Blit8bppImages(this->blit_rect, x_base, y_base, spr, numx, numy, recolour.GetPalette(shift)); - } else { - Blit32bppImages(this->blit_rect, x_base, y_base, spr, numx, numy, recolour, shift); + assert(spr->image != nullptr); + + for (int x = 0; x < numx; x++) { + for (int y = 0; y < numy; y++) { + SDL_Rect sdl_rect = {x_base + x * spr->width, y_base + y * spr->height, spr->width, spr->height}; + SDL_RenderCopy(this->renderer, spr->image, nullptr, &sdl_rect); + } } } @@ -912,7 +562,7 @@ void VideoSystem::GetNumberRangeSize(int64 smallest, int64 biggest, int *width, */ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width, Alignment align) { - SDL_Color col = {0, 0, 0}; // Font colour does not matter as only the bitmap is used. + SDL_Color col = {SPLIT_RGBA(colour)}; SDL_Surface *surf = TTF_RenderUTF8_Solid(this->font, (const char *)text, col); if (surf == nullptr) { fprintf(stderr, "Rendering text failed (%s)\n", TTF_GetError()); @@ -924,7 +574,10 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, return; } + SDL_Texture *tex = SDL_CreateTextureFromSurface(this->renderer, surf); + int real_w = std::min(surf->w, width); + switch (align) { case ALG_LEFT: break; @@ -940,44 +593,10 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, default: NOT_REACHED(); } - this->blit_rect.ValidateAddress(); - - uint8 *src = ((uint8 *)surf->pixels); - uint32 *dest = this->blit_rect.address + xpos + ypos * this->blit_rect.pitch; - int h = surf->h; - if (ypos < 0) { - h += ypos; - src -= ypos * surf->pitch; - dest -= ypos * this->blit_rect.pitch; - ypos = 0; - } - while (h > 0) { - if (ypos >= this->blit_rect.height) break; - uint8 *src2 = src; - uint32 *dest2 = dest; - int w = real_w; - int x = xpos; - if (x < 0) { - w += x; - if (w <= 0) break; - dest2 -= x; - src2 -= x; - x = 0; - } - while (w > 0) { - if (x >= this->blit_rect.width) break; - if (*src2 != 0) *dest2 = colour; - src2++; - dest2++; - x++; - w--; - } - ypos++; - src += surf->pitch; - dest += this->blit_rect.pitch; - h--; - } + SDL_Rect sdl_rect = {xpos, ypos, real_w, surf->h}; + SDL_RenderCopy(this->renderer, tex, nullptr, &sdl_rect); + SDL_DestroyTexture(tex); SDL_FreeSurface(surf); } @@ -989,51 +608,8 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, */ void VideoSystem::DrawLine(const Point16 &start, const Point16 &end, uint32 colour) { - int16 dx, inc_x, dy, inc_y; - if (start.x > end.x) { - dx = start.x - end.x; - inc_x = -1; - } else { - dx = end.x - start.x; - inc_x = 1; - } - if (start.y > end.y) { - dy = start.y - end.y; - inc_y = -1; - } else { - dy = end.y - start.y; - inc_y = 1; - } - - int16 step = std::min(dx, dy); - int16 pos_x = start.x; - int16 pos_y = start.y; - int16 sum_x = 0; - int16 sum_y = 0; - - this->blit_rect.ValidateAddress(); - uint32 *dest = this->blit_rect.address + pos_x + pos_y * this->blit_rect.pitch; - - for (;;) { - /* Blit pixel. */ - if (pos_x >= 0 && pos_x < this->blit_rect.width && pos_y >= 0 && pos_y < this->blit_rect.height) { - *dest = colour; - } - if (pos_x == end.x && pos_y == end.y) break; - - sum_x += step; - sum_y += step; - if (sum_x >= dy) { - pos_x += inc_x; - dest += inc_x; - sum_x -= dy; - } - if (sum_y >= dx) { - pos_y += inc_y; - dest += inc_y * this->blit_rect.pitch; - sum_y -= dx; - } - } + SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour)); + SDL_RenderDrawLine(this->renderer, start.x, start.y, end.x, end.y); } /** @@ -1043,12 +619,7 @@ void VideoSystem::DrawLine(const Point16 &start, const Point16 &end, uint32 colo */ void VideoSystem::DrawRectangle(const Rectangle32 &rect, uint32 colour) { - Point16 top_left (static_cast<int16>(rect.base.x), static_cast<int16>(rect.base.y)); - Point16 top_right (static_cast<int16>(rect.base.x + rect.width - 1), static_cast<int16>(rect.base.y)); - Point16 bottom_left (static_cast<int16>(rect.base.x), static_cast<int16>(rect.base.y + rect.height - 1)); - Point16 bottom_right(static_cast<int16>(rect.base.x + rect.width - 1), static_cast<int16>(rect.base.y + rect.height - 1)); - this->DrawLine(top_left, top_right, colour); - this->DrawLine(top_left, bottom_left, colour); - this->DrawLine(top_right, bottom_right, colour); - this->DrawLine(bottom_left, bottom_right, colour); + SDL_Rect sdl_rect = RectToSDLRect(rect); + SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour)); + SDL_RenderDrawRect(this->renderer, &sdl_rect); } diff --git a/src/video.h b/src/video.h index 6f435a9..2d6f81e 100644 --- a/src/video.h +++ b/src/video.h @@ -22,27 +22,6 @@ void QuitProgram(); class ImageData; -/** Clipped rectangle. */ -class ClippedRectangle { -public: - ClippedRectangle(); - ClippedRectangle(uint16 x, uint16 y, uint16 w, uint16 h); - ClippedRectangle(const ClippedRectangle &cr, uint16 x, uint16 y, uint16 w, uint16 h); - - ClippedRectangle(const ClippedRectangle &cr); - ClippedRectangle &operator=(const ClippedRectangle &cr); - - void ValidateAddress(); - - uint16 absx; ///< Absolute X position in the screen of the top-left. - uint16 absy; ///< Absolute Y position in the screen of the top-left. - uint16 width; ///< Number of columns. - uint16 height; ///< Number of rows. - - uint32 *address; ///< Base address. @note Call #ValidateAddress prior to use. - int32 pitch; ///< Pitch of a row in bytes. @note Call #ValidateAddress prior to use. -}; - /** How to align text during drawing. */ enum Alignment { ALG_LEFT, ///< Align to the left edge. @@ -54,15 +33,12 @@ enum Alignment { * Class representing the video system. */ class VideoSystem { - friend class ClippedRectangle; - public: VideoSystem(); ~VideoSystem(); std::string Initialize(const char *font_name, int font_size); bool SetResolution(const Point32 &res); - void GetResolutions(); void MainLoop(); void Shutdown(); @@ -98,12 +74,18 @@ public: void MarkDisplayDirty(); void MarkDisplayDirty(const Rectangle32 &rect); - void SetClippedRectangle(const ClippedRectangle &cr); - ClippedRectangle GetClippedRectangle(); + void FillSurface(const Rectangle32 &rect, uint32 colour); - void FillSurface(uint32 colour, const Rectangle32 &rect); - void BlitImage(const Point32 &img_base, const ImageData *spr, const Recolouring &recolour, GradientShift shift); - void BlitImage(int x, int y, const ImageData *img, const Recolouring &recolour, GradientShift shift); + /** + * Blit a single sprite. + * @param img_base Coordinates of the sprite data (relative to window). + * @param spr The sprite to blit. + * @param recolour Sprite recolouring definition. + */ + void BlitImage(const Point32 &img_base, const ImageData *spr, const Recolouring &recolour) + { + this->BlitImages(img_base, spr, 1, 1, recolour); + } /** * Blit a row of sprites. @@ -115,7 +97,7 @@ public: */ inline void BlitHorizontal(int32 xmin, uint16 numx, int32 y, const ImageData *spr, const Recolouring &recolour) { - this->BlitImages(xmin, y, spr, numx, 1, recolour); + this->BlitImages({xmin, y}, spr, numx, 1, recolour); } /** @@ -128,10 +110,10 @@ public: */ inline void BlitVertical(int32 ymin, uint16 numy, int32 x, const ImageData *spr, const Recolouring &recolour) { - this->BlitImages(x, ymin, spr, 1, numy, recolour); + this->BlitImages({x, ymin}, spr, 1, numy, recolour); } - void BlitImages(int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift = GS_NORMAL); + void BlitImages(const Point32 &img_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour); void FinishRepaint(); @@ -144,6 +126,9 @@ public: return this->font_height; } + void SetClippedRectangle(const Rectangle32 &rect); + Rectangle32 GetClippedRectangle(); + void GetTextSize(const uint8 *text, int *width, int *height); void GetNumberRangeSize(int64 smallest, int64 biggest, int *width, int *height); void BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width = 0x7FFF, Alignment align = ALG_LEFT); @@ -164,12 +149,20 @@ private: SDL_Window *window; ///< %Window of the application. SDL_Renderer *renderer; ///< GPU renderer to the application window. SDL_Texture *texture; ///< GPU Texture storage of the application window. - uint32 *mem; ///< Memory used for blitting the application display. - ClippedRectangle blit_rect; ///< %Rectangle to blit in. + Rectangle32 blit_rect; Point16 digit_size; ///< Size of largest digit (initially a zero-size). + void GetResolutions(); bool HandleEvent(); void MarkDisplayClean(); + + template<class PZ, class SZ> + SDL_Rect RectToSDLRect(const Rectangle<PZ, SZ> &rect) + { + SDL_Rect sdl_rect = {static_cast<int>(rect.base.x), static_cast<int>(rect.base.y), + static_cast<int>(rect.width), static_cast<int>(rect.height)}; + return sdl_rect; + } }; extern VideoSystem _video; diff --git a/src/viewport.cpp b/src/viewport.cpp index eae8aa3..bfead68 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1022,7 +1022,7 @@ void SpriteCollector::CollectVoxel(const Voxel *voxel, int xpos, int ypos, int z gslope = voxel->GetGroundSlope(); } - + /* Fences */ for (TileEdge edge = EDGE_BEGIN; edge < EDGE_COUNT; edge++) { FenceType fence_type = voxel->GetFenceType(edge); @@ -1404,21 +1404,14 @@ void Viewport::OnDraw() collector.Collect(this->additions_enabled && this->additions_displayed); static const Recolouring recolour; - _video.FillSurface(MakeRGBA(0, 0, 0, OPAQUE), this->rect); // Black background. - - ClippedRectangle cr = _video.GetClippedRectangle(); - assert(this->rect.base.x >= 0 && this->rect.base.y >= 0); - ClippedRectangle draw_rect(cr, this->rect.base.x, this->rect.base.y, this->rect.width, this->rect.height); - _video.SetClippedRectangle(draw_rect); - - GradientShift gs = static_cast<GradientShift>(GS_LIGHT - _weather.GetWeatherType()); for (const auto &iter : collector.draw_images) { const DrawData &dd = iter; const Recolouring &rec = (dd.recolour == nullptr) ? recolour : *dd.recolour; - _video.BlitImage(dd.base, dd.sprite, rec, gs); + _video.BlitImage(dd.base, dd.sprite, rec); } - _video.SetClippedRectangle(cr); + /// \todo Actually change brightness/darkness overlay depending on weather + _video.FillSurface(this->rect, MakeRGBA(0, 0, 0, 0)); } /** diff --git a/src/widget.cpp b/src/widget.cpp index 6139ada..a96c9e2 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -285,7 +285,7 @@ void LeafWidget::Draw(const GuiWindow *w) } else if ((this->flags & LWF_PRESSED) != 0) { spr_num += WCS_EMPTY_PRESSED; } - _video.BlitImage(left, top, _gui_sprites.radio_button.sprites[spr_num], rc, GS_NORMAL); + _video.BlitImage({left, top}, _gui_sprites.radio_button.sprites[spr_num], rc); return; } assert(this->wtype == WT_CLOSEBOX); @@ -305,7 +305,7 @@ void LeafWidget::Draw(const GuiWindow *w) int yoffset = top + (bottom - 1 - top - _gui_sprites.close_sprite->height) / 2; const ImageData *imgdata = _gui_sprites.close_sprite; - if (imgdata != nullptr) _video.BlitImage(xoffset + 1, yoffset + 1, imgdata, rc, GS_NORMAL); + if (imgdata != nullptr) _video.BlitImage({xoffset + 1, yoffset + 1}, imgdata, rc); /* Closebox is never shaded. */ } @@ -464,7 +464,7 @@ void DataWidget::Draw(const GuiWindow *w) int xoffset = left + (right + 1 - left - this->value_width) / 2 - rect.base.x; yoffset -= rect.base.y; const ImageData *imgdata = _sprite_manager.GetTableSprite(this->value); - if (imgdata != nullptr) _video.BlitImage(xoffset + pressed, yoffset + pressed, imgdata, rc, GS_NORMAL); + if (imgdata != nullptr) _video.BlitImage({xoffset + pressed, yoffset + pressed}, imgdata, rc); break; } @@ -477,7 +477,7 @@ void DataWidget::Draw(const GuiWindow *w) if (imgdata != nullptr) { int triangle_yoff = top + (bottom + 1 - top - imgrect.height) / 2 + pressed; - _video.BlitImage(right - imgrect.width + pressed, triangle_yoff, imgdata, rc, GS_NORMAL); + _video.BlitImage({right - imgrect.width + pressed, triangle_yoff}, imgdata, rc); } /* Note: Reusing the same string parameters from above */ if (this->value != STR_NULL) DrawString(w->TranslateStringNumber(this->value), TEXT_WHITE, left + pressed, yoffset + pressed, right - left - imgrect.width, align); @@ -553,12 +553,12 @@ void ScrollbarWidget::Draw(const GuiWindow *w) Point32 pos(w->GetWidgetScreenX(this), w->GetWidgetScreenY(this)); /* Draw left/up button. */ - _video.BlitImage(pos, imd[WLS_LEFT_BUTTON], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_LEFT_BUTTON], rc); if (this->wtype == WT_HOR_SCROLLBAR) pos.x += imd[WLS_LEFT_BUTTON]->width; if (this->wtype != WT_HOR_SCROLLBAR) pos.y += imd[WLS_LEFT_BUTTON]->height; /* Draw top/left underground. */ - _video.BlitImage(pos, imd[WLS_LEFT_BED], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_LEFT_BED], rc); if (this->wtype == WT_HOR_SCROLLBAR) pos.x += imd[WLS_LEFT_BED]->width; if (this->wtype != WT_HOR_SCROLLBAR) pos.y += imd[WLS_LEFT_BED]->height; @@ -578,7 +578,7 @@ void ScrollbarWidget::Draw(const GuiWindow *w) } /* Draw bottom/right underground. */ - _video.BlitImage(pos, imd[WLS_RIGHT_BED], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_RIGHT_BED], rc); if (this->wtype == WT_HOR_SCROLLBAR) { pos.x += imd[WLS_RIGHT_BED]->width; } else { @@ -586,7 +586,7 @@ void ScrollbarWidget::Draw(const GuiWindow *w) } /* Draw right/bottom button. */ - _video.BlitImage(pos, imd[WLS_RIGHT_BUTTON], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_RIGHT_BUTTON], rc); int start_edge, slider_length; this->CalculateSliderPosition(&start_edge, &slider_length); @@ -598,7 +598,7 @@ void ScrollbarWidget::Draw(const GuiWindow *w) } /* Draw top/left slider. */ - _video.BlitImage(pos, imd[WLS_LEFT_SLIDER], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_LEFT_SLIDER], rc); if (this->wtype == WT_HOR_SCROLLBAR) { pos.x += imd[WLS_LEFT_SLIDER]->width; } else { @@ -617,7 +617,7 @@ void ScrollbarWidget::Draw(const GuiWindow *w) } /* Draw bottom/right slider. */ - _video.BlitImage(pos, imd[WLS_RIGHT_SLIDER], rc, GS_NORMAL); + _video.BlitImage(pos, imd[WLS_RIGHT_SLIDER], rc); } /** diff --git a/src/window.cpp b/src/window.cpp index 5fc0127..1eb9181 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -986,12 +986,6 @@ void UpdateWindows() { if (!_video.DisplayNeedsRepaint()) return; - /* Until the entire background is covered by the main display, clean the entire display to ensure deleted - * windows truly disappear (even if there is no other window behind it). - */ - Rectangle32 rect(0, 0, _video.GetXSize(), _video.GetYSize()); - _video.FillSurface(MakeRGBA(0, 0, 0, OPAQUE), rect); - Window *w = _manager.bottom; while (w != nullptr) { w->OnDraw();
Mark as private
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
forever