Loading

Paste #pvx32jf34

  1. diff --git a/src/gui_graphics.cpp b/src/gui_graphics.cpp
  2. index c0528dc..f89756f 100644
  3. --- a/src/gui_graphics.cpp
  4. +++ b/src/gui_graphics.cpp
  5. @@ -29,6 +29,10 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl
  6.     static Recolouring rc; // Only COL_RANGE_BROWN is modified each time.
  7.     rc.Set(0, RecolourEntry(COL_RANGE_BROWN, colour));
  8.  
  9. +   _video.DrawRectangle(rect, _palette[GetColourRangeBase(colour) + 5]);
  10. +   Rectangle32 inner_rect(rect.base.x + 1, rect.base.y + 1, rect.width - 2, rect.height - 2);
  11. +   _video.FillSurface(_palette[GetColourRangeBase(colour) + 7], inner_rect);
  12. +/*
  13.     Point32 pt = rect.base;
  14.     _video.BlitImage(pt, spr_base[WBS_TOP_LEFT], rc, GS_NORMAL);
  15.     int xleft = pt.x + spr_base[WBS_TOP_LEFT]->xoffset + spr_base[WBS_TOP_LEFT]->width;
  16. @@ -58,7 +62,7 @@ void DrawBorderSprites(const BorderSpriteData &bsd, bool pressed, const Rectangl
  17.     pt.x = rect.base.x + rect.width - 1;
  18.     _video.BlitVertical(ytop, numy, pt.x, spr_base[WBS_MIDDLE_RIGHT], rc);
  19.  
  20. -   _video.BlitImages(xleft, ytop, spr_base[WBS_MIDDLE_MIDDLE], numx, numy, rc);
  21. +   _video.BlitImages(xleft, ytop, spr_base[WBS_MIDDLE_MIDDLE], numx, numy, rc); */
  22.  }
  23.  
  24.  /**
  25. @@ -75,21 +79,14 @@ void OverlayShaded(const Rectangle32 &rect)
  26.     r.RestrictTo(0, 0, _video.GetXSize(), _video.GetYSize());
  27.     if (r.width == 0 || r.height == 0) return;
  28.  
  29. -   /* Set clipped area to the rectangle. */
  30. -   ClippedRectangle cr(_video.GetClippedRectangle());
  31. -   ClippedRectangle new_cr(cr, r.base.x, r.base.y, r.width, r.height);
  32. -   _video.SetClippedRectangle(new_cr);
  33. -
  34.     /* Align the disabled sprite so it becomes a continuous pattern. */
  35. -   int32 base_x = -(r.base.x % img->width);
  36. -   int32 base_y = -(r.base.y % img->height);
  37. +   int32 base_x = r.base.x - (r.base.x % img->width);
  38. +   int32 base_y = r.base.y - (r.base.y % img->height);
  39.     uint16 numx = (r.width + img->width - 1) / img->width;
  40.     uint16 numy = (r.height + img->height - 1) / img->height;
  41.  
  42.     static const Recolouring recolour; // Fixed recolouring mapping.
  43.     _video.BlitImages(base_x, base_y, img, numx, numy, recolour);
  44. -
  45. -   _video.SetClippedRectangle(cr); // Restore clipped area.
  46.  }
  47.  
  48.  /**
  49. @@ -109,10 +106,11 @@ void DrawString(StringID strid, uint8 colour, int x, int y, int width, Alignment
  50.     DrawText(strid, buffer, lengthof(buffer));
  51.     /** \todo Reduce the naiviness of this. */
  52.     if (outline) {
  53. -       _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y, width, align);
  54. -       _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y + 1, width, align);
  55. -       _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x - 1, y, width, align);
  56. -       _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y - 1, width, align);
  57. +//     _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y, width, align);
  58. +//     _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y + 1, width, align);
  59. +//     _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x - 1, y, width, align);
  60. +//     _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x, y - 1, width, align);
  61. +       _video.BlitText(buffer, MakeRGBA(0, 0, 0, OPAQUE), x + 1, y + 1, width, align);
  62.     }
  63.     _video.BlitText(buffer, _palette[colour], x, y, width, align);
  64.  }
  65. diff --git a/src/palette.h b/src/palette.h
  66. index 1e98317..fdc5122 100644
  67. --- a/src/palette.h
  68. +++ b/src/palette.h
  69. @@ -86,6 +86,8 @@ static inline uint32 SetA(uint32 rgba, uint8 opacity)
  70.     return rgba | opacity;
  71.  }
  72.  
  73. +#define SPLIT_RGBA(rgba) GetR(rgba), GetG(rgba), GetB(rgba), GetA(rgba)
  74. +
  75.  /** Names of colour ranges. */
  76.  enum ColourRange {
  77.     COL_RANGE_GREY,
  78. diff --git a/src/sprite_data.cpp b/src/sprite_data.cpp
  79. index 28b3ce0..5fd4389 100644
  80. --- a/src/sprite_data.cpp
  81. +++ b/src/sprite_data.cpp
  82. @@ -27,6 +27,7 @@ ImageData::ImageData()
  83.     this->height = 0;
  84.     this->table = nullptr;
  85.     this->data = nullptr;
  86. +   this->image = nullptr;
  87.  }
  88.  
  89.  ImageData::~ImageData()
  90. diff --git a/src/sprite_data.h b/src/sprite_data.h
  91. index 049990c..5987aa2 100644
  92. --- a/src/sprite_data.h
  93. +++ b/src/sprite_data.h
  94. @@ -12,6 +12,8 @@
  95.  #ifndef SPRITE_DATA_H
  96.  #define SPRITE_DATA_H
  97.  
  98. +#include <SDL.h>
  99. +
  100.  static const uint32 INVALID_JUMP = UINT32_MAX; ///< Invalid jump destination in image data.
  101.  
  102.  class RcdFileReader;
  103. @@ -42,6 +44,8 @@ public:
  104.     int16 yoffset; ///< Vertical offset of the image.
  105.     uint32 *table; ///< The jump table. For missing entries, #INVALID_JUMP is used.
  106.     uint8 *data;   ///< The image data itself.
  107. +
  108. +   mutable SDL_Texture *image;
  109.  };
  110.  
  111.  ImageData *LoadImage(RcdFileReader *rcd_file);
  112. diff --git a/src/video.cpp b/src/video.cpp
  113. index 748e120..68a344c 100644
  114. --- a/src/video.cpp
  115. +++ b/src/video.cpp
  116. @@ -31,100 +31,6 @@ void QuitProgram()
  117.     _finish = true;
  118.  }
  119.  
  120. -/** Default constructor of a clipped rectangle. */
  121. -ClippedRectangle::ClippedRectangle()
  122. -{
  123. -   this->absx = 0;
  124. -   this->absy = 0;
  125. -   this->width = 0;
  126. -   this->height = 0;
  127. -   this->address = nullptr; this->pitch = 0;
  128. -}
  129. -
  130. -/**
  131. - * Construct a clipped rectangle from coordinates.
  132. - * @param x Top-left x position.
  133. - * @param y Top-left y position.
  134. - * @param w Width.
  135. - * @param h Height.
  136. - */
  137. -ClippedRectangle::ClippedRectangle(uint16 x, uint16 y, uint16 w, uint16 h)
  138. -{
  139. -   this->absx = x;
  140. -   this->absy = y;
  141. -   this->width = w;
  142. -   this->height = h;
  143. -   this->address = nullptr; this->pitch = 0;
  144. -}
  145. -
  146. -/**
  147. - * Construct a clipped rectangle inside an existing one.
  148. - * @param cr Existing rectangle.
  149. - * @param x Top-left x position.
  150. - * @param y Top-left y position.
  151. - * @param w Width.
  152. - * @param h Height.
  153. - * @note %Rectangle is clipped to the old one.
  154. - */
  155. -ClippedRectangle::ClippedRectangle(const ClippedRectangle &cr, uint16 x, uint16 y, uint16 w, uint16 h)
  156. -{
  157. -   if (x >= cr.width || y >= cr.height) {
  158. -       this->absx = 0;
  159. -       this->absy = 0;
  160. -       this->width = 0;
  161. -       this->height = 0;
  162. -       this->address = nullptr; this->pitch = 0;
  163. -       return;
  164. -   }
  165. -   if (x + w > cr.width)  w = cr.width - x;
  166. -   if (y + h > cr.height) h = cr.height - y;
  167. -
  168. -   this->absx = cr.absx + x;
  169. -   this->absy = cr.absy + y;
  170. -   this->width = w;
  171. -   this->height = h;
  172. -   this->address = nullptr; this->pitch = 0;
  173. -}
  174. -
  175. -/**
  176. - * Copy constructor.
  177. - * @param cr Existing clipped rectangle.
  178. - */
  179. -ClippedRectangle::ClippedRectangle(const ClippedRectangle &cr)
  180. -{
  181. -   this->absx = cr.absx;
  182. -   this->absy = cr.absy;
  183. -   this->width = cr.width;
  184. -   this->height = cr.height;
  185. -   this->address = cr.address; this->pitch = cr.pitch;
  186. -}
  187. -
  188. -/**
  189. - * Assignment operator override.
  190. - * @param cr Existing clipped rectangle.
  191. - * @return The assigned value.
  192. - */
  193. -ClippedRectangle &ClippedRectangle::operator=(const ClippedRectangle &cr)
  194. -{
  195. -   if (this != &cr) {
  196. -       this->absx = cr.absx;
  197. -       this->absy = cr.absy;
  198. -       this->width = cr.width;
  199. -       this->height = cr.height;
  200. -       this->address = cr.address; this->pitch = cr.pitch;
  201. -   }
  202. -   return *this;
  203. -}
  204. -
  205. -/** Initialize the #address if not done already. */
  206. -void ClippedRectangle::ValidateAddress()
  207. -{
  208. -   if (this->address == nullptr) {
  209. -       this->pitch = _video.GetXSize();
  210. -       this->address = _video.mem + this->absx + this->absy * this->pitch;
  211. -   }
  212. -}
  213. -
  214.  /**
  215.   * Default constructor, does nothing, never goes wrong.
  216.   * Call #Initialize to initialize the system.
  217. @@ -165,9 +71,18 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size)
  218.         return err;
  219.     }
  220.  
  221. +   this->renderer = SDL_CreateRenderer(this->window, -1, 0);
  222. +   if (this->renderer == nullptr) {
  223. +       std::string err = "Could not create renderer: ";
  224. +       err += SDL_GetError();
  225. +       SDL_Quit();
  226. +       return err;
  227. +   }
  228. +   SDL_SetRenderDrawBlendMode(this->renderer, SDL_BLENDMODE_BLEND);
  229. +
  230.     this->GetResolutions();
  231.  
  232. -   this->SetResolution({800, 600}); // Allocates this->mem, return value is ignored.
  233. +   this->SetResolution({800, 600}); // return value is ignored.
  234.  
  235.     /* SDL_CreateRGBSurfaceFrom() pretends to use a void* for the data,
  236.      * but it's really treated as endian-specific uint32*.
  237. @@ -188,7 +103,6 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size)
  238.  
  239.     if (TTF_Init() != 0) {
  240.         SDL_Quit();
  241. -       delete[] this->mem;
  242.         std::string err = "TTF font initialization failed: ";
  243.         err += TTF_GetError();
  244.         return err;
  245. @@ -204,7 +118,6 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size)
  246.         err += TTF_GetError();
  247.         TTF_Quit();
  248.         SDL_Quit();
  249. -       delete[] this->mem;
  250.         return err;
  251.     }
  252.  
  253. @@ -230,43 +143,12 @@ bool VideoSystem::SetResolution(const Point32 &res)
  254.  {
  255.     if (this->initialized && this->GetXSize() == res.x && this->GetYSize() == res.y) return true;
  256.  
  257. -   /* Destroy old window, if it exists. */
  258. -   if (this->initialized) {
  259. -       delete[] mem;
  260. -       this->mem = nullptr;
  261. -       SDL_DestroyTexture(this->texture);
  262. -       this->texture = nullptr;
  263. -       SDL_DestroyRenderer(this->renderer);
  264. -       this->renderer = nullptr;
  265. -   }
  266. -
  267.     this->vid_width = res.x;
  268.     this->vid_height = res.y;
  269.     SDL_SetWindowSize(this->window, this->vid_width, this->vid_height);
  270.  
  271. -   this->renderer = SDL_CreateRenderer(this->window, -1, 0);
  272. -   if (this->renderer == nullptr) {
  273. -       SDL_Quit();
  274. -       fprintf(stderr, "Could not create renderer (%s)\n", SDL_GetError());
  275. -       return false;
  276. -   }
  277. -
  278. -   this->texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, this->vid_width, this->vid_height);
  279. -   if (this->texture == nullptr) {
  280. -       SDL_Quit();
  281. -       fprintf(stderr, "Could not create texture (%s)\n", SDL_GetError());
  282. -       return false;
  283. -   }
  284. -
  285. -   this->mem = new uint32[this->vid_width * this->vid_height];
  286. -   if (this->mem == nullptr) {
  287. -       SDL_Quit();
  288. -       fprintf(stderr, "Failed to obtain window display storage.\n");
  289. -       return false;
  290. -   }
  291. -
  292.     /* Update internal screen size data structures. */
  293. -   this->blit_rect = ClippedRectangle(0, 0, this->vid_width, this->vid_height);
  294. +   this->blit_rect = Rectangle32(0, 0, this->vid_width, this->vid_height);
  295.     Viewport *vp = GetViewport();
  296.     if (vp != nullptr) vp->SetSize(this->vid_width, this->vid_height);
  297.     _manager.RepositionAllWindows();
  298. @@ -314,18 +196,17 @@ void VideoSystem::MarkDisplayClean()
  299.   * Set the clipped area.
  300.   * @param cr New clipped blitting area.
  301.   */
  302. -void VideoSystem::SetClippedRectangle(const ClippedRectangle &cr)
  303. +void VideoSystem::SetClippedRectangle(const Rectangle32 &rect)
  304.  {
  305. -   this->blit_rect = cr;
  306. +   this->blit_rect = rect;
  307.  }
  308.  
  309.  /**
  310.   * Get the current clipped blitting area.
  311.   * @return Current clipped area.
  312.   */
  313. -ClippedRectangle VideoSystem::GetClippedRectangle()
  314. +Rectangle32 VideoSystem::GetClippedRectangle()
  315.  {
  316. -   this->blit_rect.ValidateAddress();
  317.     return this->blit_rect;
  318.  }
  319.  
  320. @@ -439,6 +320,9 @@ void VideoSystem::MainLoop()
  321.         if (_finish) break;
  322.  
  323.         uint32 now = SDL_GetTicks();
  324. +
  325. +       printf("%dms\n", now - start);
  326. +
  327.         if (now >= start) { // No wrap around.
  328.             now -= start;
  329.             if (now < FRAME_DELAY) SDL_Delay(FRAME_DELAY - now); // Too early, wait until next frame.
  330. @@ -458,7 +342,6 @@ void VideoSystem::Shutdown()
  331.         TTF_CloseFont(this->font);
  332.         TTF_Quit();
  333.         SDL_Quit();
  334. -       delete[] this->mem;
  335.         this->initialized = false;
  336.         this->dirty = false;
  337.     }
  338. @@ -470,9 +353,6 @@ void VideoSystem::Shutdown()
  339.   */
  340.  void VideoSystem::FinishRepaint()
  341.  {
  342. -   SDL_UpdateTexture(this->texture, nullptr, this->mem, this->GetXSize() * sizeof(uint32)); // Upload memory to the GPU.
  343. -   SDL_RenderClear(this->renderer);
  344. -   SDL_RenderCopy(this->renderer, this->texture, nullptr, nullptr);
  345.     SDL_RenderPresent(this->renderer);
  346.  
  347.     MarkDisplayClean();
  348. @@ -485,24 +365,9 @@ void VideoSystem::FinishRepaint()
  349.   */
  350.  void VideoSystem::FillSurface(uint32 colour, const Rectangle32 &rect)
  351.  {
  352. -   ClippedRectangle cr = this->GetClippedRectangle();
  353. -
  354. -   int x = Clamp((int)rect.base.x, 0, (int)cr.width);
  355. -   int w = Clamp((int)(rect.base.x + rect.width), 0, (int)cr.width);
  356. -   int y = Clamp((int)rect.base.y, 0, (int)cr.height);
  357. -   int h = Clamp((int)(rect.base.y + rect.height), 0, (int)cr.height);
  358. -
  359. -   w -= x;
  360. -   h -= y;
  361. -   if (w == 0 || h == 0) return;
  362. -
  363. -   uint32 *pixels_base = cr.address + x + y * cr.pitch;
  364. -   while (h > 0) {
  365. -       uint32 *pixels = pixels_base;
  366. -       for (int i = 0; i < w; i++) *pixels++ = colour;
  367. -       pixels_base += cr.pitch;
  368. -       h--;
  369. -   }
  370. +   SDL_Rect sdl_rect = {rect.base.x, rect.base.y, rect.width, rect.height};
  371. +   SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour));
  372. +   SDL_RenderFillRect(this->renderer, &sdl_rect);
  373.  }
  374.  
  375.  /**
  376. @@ -645,171 +510,94 @@ void VideoSystem::BlitImage(int x, int y, const ImageData *img, const Recolourin
  377.  }
  378.  
  379.  /**
  380. - * Blit a pixel to an area of \a numx times \a numy sprites.
  381. - * @param cr Clipped rectangle.
  382. - * @param scr_base Base address of the screen array.
  383. - * @param xmin Minimal x position.
  384. - * @param ymin Minimal y position.
  385. - * @param numx Number of horizontal count.
  386. - * @param numy Number of vertical count.
  387. - * @param width Width of an image.
  388. - * @param height Height of an image.
  389. - * @param colour Pixel value to blit.
  390. - * @note Function does not handle alpha blending of the new pixel with the background.
  391. - */
  392. -static void BlitPixel(const ClippedRectangle &cr, uint32 *scr_base,
  393. -       int32 xmin, int32 ymin, uint16 numx, uint16 numy, uint16 width, uint16 height, uint32 colour)
  394. -{
  395. -   const int32 xend = xmin + numx * width;
  396. -   const int32 yend = ymin + numy * height;
  397. -   while (ymin < yend) {
  398. -       if (ymin >= cr.height) return;
  399. -
  400. -       if (ymin >= 0) {
  401. -           uint32 *scr = scr_base;
  402. -           int32 x = xmin;
  403. -           while (x < xend) {
  404. -               if (x >= cr.width) break;
  405. -               if (x >= 0) *scr = colour;
  406. -
  407. -               x += width;
  408. -               scr += width;
  409. -           }
  410. -       }
  411. -       ymin += height;
  412. -       scr_base += height * cr.pitch;
  413. -   }
  414. -}
  415. -
  416. -/**
  417.   * Blit 8bpp images to the screen.
  418. - * @param cr Clipped rectangle to draw to.
  419. - * @param x_base Base X coordinate of the sprite data.
  420. - * @param y_base Base Y coordinate of the sprite data.
  421.   * @param spr The sprite to blit.
  422. - * @param numx Number of sprites to draw in horizontal direction.
  423. - * @param numy Number of sprites to draw in vertical direction.
  424.   * @param recoloured Shifted palette to use.
  425.   */
  426. -static void Blit8bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const uint8 *recoloured)
  427. +static std::vector<uint32> Blit8bppImage(const ImageData *spr, const uint8 *recoloured)
  428.  {
  429. -   uint32 *line_base = cr.address + x_base + cr.pitch * y_base;
  430. -   int32 ypos = y_base;
  431. -   for (int yoff = 0; yoff < spr->height; yoff++) {
  432. -       uint32 offset = spr->table[yoff];
  433. +   std::vector<uint32> mem(spr->height * spr->width);
  434. +   for (int ypos = 0; ypos < spr->height; ypos++) {
  435. +       uint32 offset = spr->table[ypos];
  436.         if (offset != INVALID_JUMP) {
  437. -           int32 xpos = x_base;
  438. -           uint32 *src_base = line_base;
  439. -           for (;;) {
  440. +           for (int xpos = 0;;) {
  441.                 uint8 rel_off = spr->data[offset];
  442.                 uint8 count   = spr->data[offset + 1];
  443.                 uint8 *pixels = &spr->data[offset + 2];
  444.                 offset += 2 + count;
  445.  
  446. -               xpos += rel_off & 127;
  447. -               src_base += rel_off & 127;
  448. -               while (count > 0) {
  449. -                   uint32 colour = _palette[recoloured[*pixels]];
  450. -                   BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour);
  451. +               xpos += rel_off & 0x7F;
  452. +               for (; count > 0; count--) {
  453. +                   mem.at(ypos * spr->width + xpos) = _palette[recoloured[*pixels]];
  454.                     pixels++;
  455.                     xpos++;
  456. -                   src_base++;
  457. -                   count--;
  458.                 }
  459. -               if ((rel_off & 128) != 0) break;
  460. +               if ((rel_off & 0x80) != 0) break;
  461.             }
  462.         }
  463. -       line_base += cr.pitch;
  464. -       ypos++;
  465.     }
  466. +   return mem;
  467.  }
  468.  
  469.  /**
  470.   * Blit 32bpp images to the screen.
  471. - * @param cr Clipped rectangle to draw to.
  472. - * @param x_base Base X coordinate of the sprite data.
  473. - * @param y_base Base Y coordinate of the sprite data.
  474.   * @param spr The sprite to blit.
  475. - * @param numx Number of sprites to draw in horizontal direction.
  476. - * @param numy Number of sprites to draw in vertical direction.
  477.   * @param recolour Sprite recolouring definition.
  478.   * @param shift Gradient shift.
  479.   */
  480. -static void Blit32bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift)
  481. +static std::vector<uint32> Blit32bppImage(const ImageData *spr, const Recolouring &recolour, GradientShift shift)
  482.  {
  483. -   uint32 *line_base = cr.address + x_base + cr.pitch * y_base;
  484. +   std::vector<uint32> mem(spr->height * spr->width);
  485.     ShiftFunc sf = GetGradientShiftFunc(shift);
  486. -   int32 ypos = y_base;
  487.     const uint8 *src = spr->data + 2; // Skip the length word.
  488. -   for (int yoff = 0; yoff < spr->height; yoff++) {
  489. -       int32 xpos = x_base;
  490. -       uint32 *src_base = line_base;
  491. -       for (;;) {
  492. +   for (int ypos = 0; ypos < spr->height; ypos++) {
  493. +       for (int xpos = 0;;) {
  494.             uint8 mode = *src++;
  495.             if (mode == 0) break;
  496. +           int len = mode & 0x3F;
  497.             switch (mode >> 6) {
  498.                 case 0: // Fully opaque pixels.
  499. -                   mode &= 0x3F;
  500. -                   for (; mode > 0; mode--) {
  501. -                       uint32 colour = MakeRGBA(sf(src[0]), sf(src[1]), sf(src[2]), OPAQUE);
  502. -                       BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour);
  503. +                   for (; len > 0; len--) {
  504. +                       mem.at(ypos * spr->width + xpos) = MakeRGBA(sf(src[0]), sf(src[1]), sf(src[2]), OPAQUE);
  505.                         xpos++;
  506. -                       src_base++;
  507.                         src += 3;
  508.                     }
  509.                     break;
  510.  
  511.                 case 1: { // Partial opaque pixels.
  512.                     uint8 opacity = *src++;
  513. -                   mode &= 0x3F;
  514. -                   for (; mode > 0; mode--) {
  515. -                       /* Cheat transparency a bit by just recolouring the previously drawn pixel */
  516. -                       uint32 old_pixel = *src_base;
  517. -
  518. -                       uint r = sf(src[0]) * opacity + GetR(old_pixel) * (256 - opacity);
  519. -                       uint g = sf(src[1]) * opacity + GetG(old_pixel) * (256 - opacity);
  520. -                       uint b = sf(src[2]) * opacity + GetB(old_pixel) * (256 - opacity);
  521. -
  522. -                       /* Opaque, but colour adjusted depending on the old pixel. */
  523. -                       uint32 ndest = MakeRGBA(r >> 8, g >> 8, b >> 8, OPAQUE);
  524. -                       BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, ndest);
  525. +                   for (; len > 0; len--) {
  526. +                       mem.at(ypos * spr->width + xpos) = MakeRGBA(sf(src[0]), sf(src[1]), sf(src[2]), opacity);
  527.                         xpos++;
  528. -                       src_base++;
  529.                         src += 3;
  530.                     }
  531.                     break;
  532.                 }
  533.                 case 2: // Fully transparent pixels.
  534. -                   xpos += mode & 0x3F;
  535. -                   src_base += mode & 0x3F;
  536. +                   xpos += len;
  537.                     break;
  538.  
  539.                 case 3: { // Recoloured pixels.
  540.                     uint8 layer = *src++;
  541.                     const uint32 *table = recolour.GetRecolourTable(layer - 1);
  542.                     uint8 opacity = *src++;
  543. -                   mode &= 0x3F;
  544. -                   for (; mode > 0; mode--) {
  545. -                       uint32 old_pixel = *src_base;
  546. +                   for (; len > 0; len--) {
  547.                         uint32 recoloured = table[*src++];
  548.  
  549. -                       uint r = sf(GetR(recoloured)) * opacity + GetR(old_pixel) * (256 - opacity);
  550. -                       uint g = sf(GetG(recoloured)) * opacity + GetG(old_pixel) * (256 - opacity);
  551. -                       uint b = sf(GetB(recoloured)) * opacity + GetB(old_pixel) * (256 - opacity);
  552. +                       uint r = sf(GetR(recoloured));
  553. +                       uint g = sf(GetG(recoloured));
  554. +                       uint b = sf(GetB(recoloured));
  555.  
  556. -                       uint32 colour = MakeRGBA(r >> 8, g >> 8, b >> 8, OPAQUE);
  557. -                       BlitPixel(cr, src_base, xpos, ypos, numx, numy, spr->width, spr->height, colour);
  558. +                       mem.at(ypos * spr->width + xpos) = MakeRGBA(r, g, b, opacity);
  559.                         xpos++;
  560. -                       src_base++;
  561.                     }
  562.                     break;
  563.                 }
  564.             }
  565.         }
  566. -       line_base += cr.pitch;
  567. -       ypos++;
  568.         src += 2; // Skip the length word.
  569.     }
  570. +   return mem;
  571.  }
  572.  
  573.  /**
  574. @@ -824,28 +612,32 @@ static void Blit32bppImages(const ClippedRectangle &cr, int32 x_base, int32 y_ba
  575.   */
  576.  void VideoSystem::BlitImages(int32 x_base, int32 y_base, const ImageData *spr, uint16 numx, uint16 numy, const Recolouring &recolour, GradientShift shift)
  577.  {
  578. -   this->blit_rect.ValidateAddress();
  579. -
  580.     x_base += spr->xoffset;
  581.     y_base += spr->yoffset;
  582.  
  583. -   /* Don't draw wildly outside the screen. */
  584. -   while (numx > 0 && x_base + spr->width < 0) {
  585. -       x_base += spr->width; numx--;
  586. -   }
  587. -   while (numx > 0 && x_base + (numx - 1) * spr->width >= this->blit_rect.width) numx--;
  588. -   if (numx == 0) return;
  589. +   if (numx == 0 || numy == 0) return;
  590. +
  591. +   if (spr->image == nullptr) {
  592. +       std::vector<uint32> img;
  593. +       if (GB(spr->flags, IFG_IS_8BPP, 1) != 0) {
  594. +           img = Blit8bppImage(spr, recolour.GetPalette(shift));
  595. +       } else {
  596. +           img = Blit32bppImage(spr, recolour, shift);
  597. +       }
  598.  
  599. -   while (numy > 0 && y_base + spr->height < 0) {
  600. -       y_base += spr->height; numy--;
  601. +       spr->image = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, spr->width, spr->height);
  602. +       SDL_UpdateTexture(spr->image, nullptr, img.data(), spr->width * sizeof(uint32));
  603. +       SDL_SetTextureBlendMode(spr->image, SDL_BLENDMODE_BLEND);
  604.     }
  605. -   while (numy > 0 && y_base + (numy - 1) * spr->height >= this->blit_rect.height) numy--;
  606. -   if (numy == 0) return;
  607.  
  608. -   if (GB(spr->flags, IFG_IS_8BPP, 1) != 0) {
  609. -       Blit8bppImages(this->blit_rect, x_base, y_base, spr, numx, numy, recolour.GetPalette(shift));
  610. -   } else {
  611. -       Blit32bppImages(this->blit_rect, x_base, y_base, spr, numx, numy, recolour, shift);
  612. +   assert(spr->image != nullptr);
  613. +
  614. +   for (int x = 0; x < numx; x++) {
  615. +       for (int y = 0; y < numy; y++) {
  616. +           SDL_Rect sdl_rect = {x_base + x * spr->width, y_base + y * spr->height, spr->width, spr->height};
  617. +       //  printf("sdl_rect: %i, %i, %i, %i\n", sdl_rect.x, sdl_rect.y, sdl_rect.w, sdl_rect.h);
  618. +           SDL_RenderCopy(this->renderer, spr->image, nullptr, &sdl_rect);
  619. +       }
  620.     }
  621.  }
  622.  
  623. @@ -912,7 +704,7 @@ void VideoSystem::GetNumberRangeSize(int64 smallest, int64 biggest, int *width,
  624.   */
  625.  void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width, Alignment align)
  626.  {
  627. -   SDL_Color col = {0, 0, 0}; // Font colour does not matter as only the bitmap is used.
  628. +   SDL_Color col = {SPLIT_RGBA(colour)};
  629.     SDL_Surface *surf = TTF_RenderUTF8_Solid(this->font, (const char *)text, col);
  630.     if (surf == nullptr) {
  631.         fprintf(stderr, "Rendering text failed (%s)\n", TTF_GetError());
  632. @@ -924,7 +716,10 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos,
  633.         return;
  634.     }
  635.  
  636. +   SDL_Texture *tex = SDL_CreateTextureFromSurface(this->renderer, surf);
  637. +
  638.     int real_w = std::min(surf->w, width);
  639. +
  640.     switch (align) {
  641.         case ALG_LEFT:
  642.             break;
  643. @@ -940,44 +735,10 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos,
  644.         default: NOT_REACHED();
  645.     }
  646.  
  647. -   this->blit_rect.ValidateAddress();
  648. -
  649. -   uint8 *src = ((uint8 *)surf->pixels);
  650. -   uint32 *dest = this->blit_rect.address + xpos + ypos * this->blit_rect.pitch;
  651. -   int h = surf->h;
  652. -   if (ypos < 0) {
  653. -       h += ypos;
  654. -       src  -= ypos * surf->pitch;
  655. -       dest -= ypos * this->blit_rect.pitch;
  656. -       ypos = 0;
  657. -   }
  658. -   while (h > 0) {
  659. -       if (ypos >= this->blit_rect.height) break;
  660. -       uint8 *src2 = src;
  661. -       uint32 *dest2 = dest;
  662. -       int w = real_w;
  663. -       int x = xpos;
  664. -       if (x < 0) {
  665. -           w += x;
  666. -           if (w <= 0) break;
  667. -           dest2 -= x;
  668. -           src2 -= x;
  669. -           x = 0;
  670. -       }
  671. -       while (w > 0) {
  672. -           if (x >= this->blit_rect.width) break;
  673. -           if (*src2 != 0) *dest2 = colour;
  674. -           src2++;
  675. -           dest2++;
  676. -           x++;
  677. -           w--;
  678. -       }
  679. -       ypos++;
  680. -       src  += surf->pitch;
  681. -       dest += this->blit_rect.pitch;
  682. -       h--;
  683. -   }
  684. +   SDL_Rect sdl_rect = {xpos, ypos, real_w, surf->h};
  685. +   SDL_RenderCopy(this->renderer, tex, nullptr, &sdl_rect);
  686.  
  687. +   SDL_DestroyTexture(tex);
  688.     SDL_FreeSurface(surf);
  689.  }
  690.  
  691. @@ -989,51 +750,8 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos,
  692.   */
  693.  void VideoSystem::DrawLine(const Point16 &start, const Point16 &end, uint32 colour)
  694.  {
  695. -   int16 dx, inc_x, dy, inc_y;
  696. -   if (start.x > end.x) {
  697. -       dx = start.x - end.x;
  698. -       inc_x = -1;
  699. -   } else {
  700. -       dx = end.x - start.x;
  701. -       inc_x = 1;
  702. -   }
  703. -   if (start.y > end.y) {
  704. -       dy = start.y - end.y;
  705. -       inc_y = -1;
  706. -   } else {
  707. -       dy = end.y - start.y;
  708. -       inc_y = 1;
  709. -   }
  710. -
  711. -   int16 step = std::min(dx, dy);
  712. -   int16 pos_x = start.x;
  713. -   int16 pos_y = start.y;
  714. -   int16 sum_x = 0;
  715. -   int16 sum_y = 0;
  716. -
  717. -   this->blit_rect.ValidateAddress();
  718. -   uint32 *dest = this->blit_rect.address + pos_x + pos_y * this->blit_rect.pitch;
  719. -
  720. -   for (;;) {
  721. -       /* Blit pixel. */
  722. -       if (pos_x >= 0 && pos_x < this->blit_rect.width && pos_y >= 0 && pos_y < this->blit_rect.height) {
  723. -           *dest = colour;
  724. -       }
  725. -       if (pos_x == end.x && pos_y == end.y) break;
  726. -
  727. -       sum_x += step;
  728. -       sum_y += step;
  729. -       if (sum_x >= dy) {
  730. -           pos_x += inc_x;
  731. -           dest += inc_x;
  732. -           sum_x -= dy;
  733. -       }
  734. -       if (sum_y >= dx) {
  735. -           pos_y += inc_y;
  736. -           dest += inc_y * this->blit_rect.pitch;
  737. -           sum_y -= dx;
  738. -       }
  739. -   }
  740. +   SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour));
  741. +   SDL_RenderDrawLine(this->renderer, start.x, start.y, end.x, end.y);
  742.  }
  743.  
  744.  /**
  745. @@ -1043,12 +761,7 @@ void VideoSystem::DrawLine(const Point16 &start, const Point16 &end, uint32 colo
  746.   */
  747.  void VideoSystem::DrawRectangle(const Rectangle32 &rect, uint32 colour)
  748.  {
  749. -   Point16 top_left    (static_cast<int16>(rect.base.x),                  static_cast<int16>(rect.base.y));
  750. -   Point16 top_right   (static_cast<int16>(rect.base.x + rect.width - 1), static_cast<int16>(rect.base.y));
  751. -   Point16 bottom_left (static_cast<int16>(rect.base.x),                  static_cast<int16>(rect.base.y + rect.height - 1));
  752. -   Point16 bottom_right(static_cast<int16>(rect.base.x + rect.width - 1), static_cast<int16>(rect.base.y + rect.height - 1));
  753. -   this->DrawLine(top_left, top_right, colour);
  754. -   this->DrawLine(top_left, bottom_left, colour);
  755. -   this->DrawLine(top_right, bottom_right, colour);
  756. -   this->DrawLine(bottom_left, bottom_right, colour);
  757. +   SDL_Rect sdl_rect = {rect.base.x, rect.base.y, rect.width, rect.height};
  758. +   SDL_SetRenderDrawColor(this->renderer, SPLIT_RGBA(colour));
  759. +   SDL_RenderDrawRect(this->renderer, &sdl_rect);
  760.  }
  761. diff --git a/src/video.h b/src/video.h
  762. index 6f435a9..2689030 100644
  763. --- a/src/video.h
  764. +++ b/src/video.h
  765. @@ -22,27 +22,6 @@ void QuitProgram();
  766.  
  767.  class ImageData;
  768.  
  769. -/** Clipped rectangle. */
  770. -class ClippedRectangle {
  771. -public:
  772. -   ClippedRectangle();
  773. -   ClippedRectangle(uint16 x, uint16 y, uint16 w, uint16 h);
  774. -   ClippedRectangle(const ClippedRectangle &cr, uint16 x, uint16 y, uint16 w, uint16 h);
  775. -
  776. -   ClippedRectangle(const ClippedRectangle &cr);
  777. -   ClippedRectangle &operator=(const ClippedRectangle &cr);
  778. -
  779. -   void ValidateAddress();
  780. -
  781. -   uint16 absx;     ///< Absolute X position in the screen of the top-left.
  782. -   uint16 absy;     ///< Absolute Y position in the screen of the top-left.
  783. -   uint16 width;    ///< Number of columns.
  784. -   uint16 height;   ///< Number of rows.
  785. -
  786. -   uint32 *address; ///< Base address. @note Call #ValidateAddress prior to use.
  787. -   int32 pitch;     ///< Pitch of a row in bytes. @note Call #ValidateAddress prior to use.
  788. -};
  789. -
  790.  /** How to align text during drawing. */
  791.  enum Alignment {
  792.     ALG_LEFT,   ///< Align to the left edge.
  793. @@ -54,8 +33,6 @@ enum Alignment {
  794.   * Class representing the video system.
  795.   */
  796.  class VideoSystem {
  797. -   friend class ClippedRectangle;
  798. -
  799.  public:
  800.     VideoSystem();
  801.     ~VideoSystem();
  802. @@ -98,9 +75,6 @@ public:
  803.     void MarkDisplayDirty();
  804.     void MarkDisplayDirty(const Rectangle32 &rect);
  805.  
  806. -   void SetClippedRectangle(const ClippedRectangle &cr);
  807. -   ClippedRectangle GetClippedRectangle();
  808. -
  809.     void FillSurface(uint32 colour, const Rectangle32 &rect);
  810.     void BlitImage(const Point32 &img_base, const ImageData *spr, const Recolouring &recolour, GradientShift shift);
  811.     void BlitImage(int x, int y, const ImageData *img, const Recolouring &recolour, GradientShift shift);
  812. @@ -144,6 +118,9 @@ public:
  813.         return this->font_height;
  814.     }
  815.  
  816. +   void SetClippedRectangle(const Rectangle32 &rect);
  817. +   Rectangle32 GetClippedRectangle();
  818. +
  819.     void GetTextSize(const uint8 *text, int *width, int *height);
  820.     void GetNumberRangeSize(int64 smallest, int64 biggest, int *width, int *height);
  821.     void BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width = 0x7FFF, Alignment align = ALG_LEFT);
  822. @@ -164,8 +141,7 @@ private:
  823.     SDL_Window *window;         ///< %Window of the application.
  824.     SDL_Renderer *renderer;     ///< GPU renderer to the application window.
  825.     SDL_Texture *texture;       ///< GPU Texture storage of the application window.
  826. -   uint32 *mem;                ///< Memory used for blitting the application display.
  827. -   ClippedRectangle blit_rect; ///< %Rectangle to blit in.
  828. +   Rectangle32 blit_rect;
  829.     Point16 digit_size;         ///< Size of largest digit (initially a zero-size).
  830.  
  831.     bool HandleEvent();
  832. diff --git a/src/viewport.cpp b/src/viewport.cpp
  833. index eae8aa3..9e80fd0 100644
  834. --- a/src/viewport.cpp
  835. +++ b/src/viewport.cpp
  836. @@ -1022,7 +1022,7 @@ void SpriteCollector::CollectVoxel(const Voxel *voxel, int xpos, int ypos, int z
  837.  
  838.         gslope = voxel->GetGroundSlope();
  839.     }
  840. -  
  841. +
  842.     /* Fences */
  843.     for (TileEdge edge = EDGE_BEGIN; edge < EDGE_COUNT; edge++) {
  844.         FenceType fence_type = voxel->GetFenceType(edge);
  845. @@ -1406,19 +1406,12 @@ void Viewport::OnDraw()
  846.  
  847.     _video.FillSurface(MakeRGBA(0, 0, 0, OPAQUE), this->rect); // Black background.
  848.  
  849. -   ClippedRectangle cr = _video.GetClippedRectangle();
  850. -   assert(this->rect.base.x >= 0 && this->rect.base.y >= 0);
  851. -   ClippedRectangle draw_rect(cr, this->rect.base.x, this->rect.base.y, this->rect.width, this->rect.height);
  852. -   _video.SetClippedRectangle(draw_rect);
  853. -
  854.     GradientShift gs = static_cast<GradientShift>(GS_LIGHT - _weather.GetWeatherType());
  855.     for (const auto &iter : collector.draw_images) {
  856.         const DrawData &dd = iter;
  857.         const Recolouring &rec = (dd.recolour == nullptr) ? recolour : *dd.recolour;
  858.         _video.BlitImage(dd.base, dd.sprite, rec, gs);
  859.     }
  860. -
  861. -   _video.SetClippedRectangle(cr);
  862.  }
  863.  
  864.  /**
  865. diff --git a/src/window.cpp b/src/window.cpp
  866. index 5fc0127..1eb9181 100644
  867. --- a/src/window.cpp
  868. +++ b/src/window.cpp
  869. @@ -986,12 +986,6 @@ void UpdateWindows()
  870.  {
  871.     if (!_video.DisplayNeedsRepaint()) return;
  872.  
  873. -   /* Until the entire background is covered by the main display, clean the entire display to ensure deleted
  874. -    * windows truly disappear (even if there is no other window behind it).
  875. -    */
  876. -   Rectangle32 rect(0, 0, _video.GetXSize(), _video.GetYSize());
  877. -   _video.FillSurface(MakeRGBA(0, 0, 0, OPAQUE), rect);
  878. -
  879.     Window *w = _manager.bottom;
  880.     while (w != nullptr) {
  881.         w->OnDraw();
  882.  

Comments