- diff --git a/src/gui_graphics.cpp b/src/gui_graphics.cpp
- index c0528dc..f89756f 100644
- --- a/src/gui_graphics.cpp
- +++ b/src/gui_graphics.cpp
- @@ -29,6 +29,10 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl
- static Recolouring rc; // Only COL_RANGE_BROWN is modified each time.
- rc.Set(0, RecolourEntry(COL_RANGE_BROWN, colour));
- + _video.DrawRectangle(rect, _palette[GetColourRangeBase(colour) + 5]);
- + Rectangle32 inner_rect(rect.base.x + 1, rect.base.y + 1, rect.width - 2, rect.height - 2);
- + _video.FillSurface(_palette[GetColourRangeBase(colour) + 7], inner_rect);
- +/*
- Point32 pt = rect.base;
- _video.BlitImage(pt, spr_base[WBS_TOP_LEFT], rc, GS_NORMAL);
- int xleft = pt.x + spr_base[WBS_TOP_LEFT]->xoffset + spr_base[WBS_TOP_LEFT]->width;
- @@ -58,7 +62,7 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl
- 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);
- + _video.BlitImages(xleft, ytop, spr_base[WBS_MIDDLE_MIDDLE], numx, numy, rc); */
- }
- /**
- @@ -75,21 +79,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.
- }
- /**
- @@ -109,10 +106,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/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/video.cpp b/src/video.cpp
- index 748e120..68a344c 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*.
- @@ -188,7 +103,6 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size)
- 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,9 +353,6 @@ 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);
- MarkDisplayClean();
- @@ -485,24 +365,9 @@ void VideoSystem::FinishRepaint()
- */
- 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--;
- - }
- + SDL_Rect sdl_rect = {rect.base.x, rect.base.y, rect.width, rect.height};
- + SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour));
- + SDL_RenderFillRect(this->renderer, &sdl_rect);
- }
- /**
- @@ -645,171 +510,94 @@ void VideoSystem::BlitImage(int x, int y, const ImageData *img, const Recolourin
- }
- /**
- - * 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;
- - }
- -}
- -
- -/**
- * 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, GradientShift shift)
- {
- - uint32 *line_base = cr.address + x_base + cr.pitch * y_base;
- + std::vector<uint32> mem(spr->height * spr->width);
- ShiftFunc sf = GetGradientShiftFunc(shift);
- - int32 ypos = y_base;
- 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(sf(src[0]), sf(src[1]), sf(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(sf(src[0]), sf(src[1]), sf(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);
- + uint r = sf(GetR(recoloured));
- + uint g = sf(GetG(recoloured));
- + uint b = sf(GetB(recoloured));
- - 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) = MakeRGBA(r, g, b, opacity);
- xpos++;
- - src_base++;
- }
- break;
- }
- }
- }
- - line_base += cr.pitch;
- - ypos++;
- src += 2; // Skip the length word.
- }
- + return mem;
- }
- /**
- @@ -824,28 +612,32 @@ static void Blit32bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_ba
- */
- void VideoSystem::BlitImages(int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift)
- {
- - this->blit_rect.ValidateAddress();
- -
- x_base += spr->xoffset;
- y_base += spr->yoffset;
- - /* 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 (numx == 0 || numy == 0) return;
- +
- + if (spr->image == nullptr) {
- + std::vector<uint32> img;
- + if (GB(spr->flags, IFG_IS_8BPP, 1) != 0) {
- + img = Blit8bppImage(spr, recolour.GetPalette(shift));
- + } else {
- + img = Blit32bppImage(spr, recolour, shift);
- + }
- - 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};
- + // printf("sdl_rect: %i, %i, %i, %i\n", sdl_rect.x, sdl_rect.y, sdl_rect.w, sdl_rect.h);
- + SDL_RenderCopy(this->renderer, spr->image, nullptr, &sdl_rect);
- + }
- }
- }
- @@ -912,7 +704,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 +716,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 +735,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 +750,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 +761,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 = {rect.base.x, rect.base.y, rect.width, rect.height};
- + 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..2689030 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,8 +33,6 @@ enum Alignment {
- * Class representing the video system.
- */
- class VideoSystem {
- - friend class ClippedRectangle;
- -
- public:
- VideoSystem();
- ~VideoSystem();
- @@ -98,9 +75,6 @@ public:
- void MarkDisplayDirty();
- void MarkDisplayDirty(const Rectangle32 &rect);
- - void SetClippedRectangle(const ClippedRectangle &cr);
- - ClippedRectangle GetClippedRectangle();
- -
- 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);
- @@ -144,6 +118,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,8 +141,7 @@ 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).
- bool HandleEvent();
- diff --git a/src/viewport.cpp b/src/viewport.cpp
- index eae8aa3..9e80fd0 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);
- @@ -1406,19 +1406,12 @@ void Viewport::OnDraw()
- _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.SetClippedRectangle(cr);
- }
- /**
- 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();