OpenTTD Source  20241125-master-g5b02f51e17
32bpp_sse2.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #ifdef WITH_SSE
11 
12 #include "../stdafx.h"
13 #include "../zoom_func.h"
14 #include "../settings_type.h"
15 #include "32bpp_sse2.hpp"
16 #include "32bpp_sse_func.hpp"
17 
18 #include "../safeguards.h"
19 
21 static FBlitter_32bppSSE2 iFBlitter_32bppSSE2;
22 
23 Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator)
24 {
25  /* First uint32_t of a line = the number of transparent pixels from the left.
26  * Second uint32_t of a line = the number of transparent pixels from the right.
27  * Then all RGBA then all MV.
28  */
29  ZoomLevel zoom_min = ZOOM_LVL_MIN;
30  ZoomLevel zoom_max = ZOOM_LVL_MIN;
31  if (sprite[ZOOM_LVL_MIN].type != SpriteType::Font) {
32  zoom_min = _settings_client.gui.zoom_min;
33  zoom_max = _settings_client.gui.zoom_max;
34  if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
35  }
36 
37  /* Calculate sizes and allocate. */
38  SpriteData sd;
39  memset(&sd, 0, sizeof(sd));
40  uint all_sprites_size = 0;
41  for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
42  const SpriteLoader::Sprite *src_sprite = &sprite[z];
43  sd.infos[z].sprite_width = src_sprite->width;
44  sd.infos[z].sprite_offset = all_sprites_size;
45  sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
46 
47  const uint rgba_size = sd.infos[z].sprite_line_size * src_sprite->height;
48  sd.infos[z].mv_offset = all_sprites_size + rgba_size;
49 
50  const uint mv_size = sizeof(MapValue) * src_sprite->width * src_sprite->height;
51  all_sprites_size += rgba_size + mv_size;
52  }
53 
54  Sprite *dst_sprite = allocator.Allocate<Sprite>(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size);
55  dst_sprite->height = sprite[ZOOM_LVL_MIN].height;
56  dst_sprite->width = sprite[ZOOM_LVL_MIN].width;
57  dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
58  dst_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
59  memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
60 
61  /* Copy colours and determine flags. */
62  bool has_remap = false;
63  bool has_anim = false;
64  bool has_translucency = false;
65  for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
66  const SpriteLoader::Sprite *src_sprite = &sprite[z];
67  const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
68  Colour *dst_rgba_line = (Colour *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].sprite_offset];
69  MapValue *dst_mv = (MapValue *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].mv_offset];
70  for (uint y = src_sprite->height; y != 0; y--) {
71  Colour *dst_rgba = dst_rgba_line + META_LENGTH;
72  for (uint x = src_sprite->width; x != 0; x--) {
73  if (src->a != 0) {
74  dst_rgba->a = src->a;
75  if (src->a != 0 && src->a != 255) has_translucency = true;
76  dst_mv->m = src->m;
77  if (src->m != 0) {
78  /* Do some accounting for flags. */
79  has_remap = true;
80  if (src->m >= PALETTE_ANIM_START) has_anim = true;
81 
82  /* Get brightest value (or default brightness if it's a black pixel). */
83  const uint8_t rgb_max = std::max({src->r, src->g, src->b});
84  dst_mv->v = (rgb_max == 0) ? Blitter_32bppBase::DEFAULT_BRIGHTNESS : rgb_max;
85 
86  /* Pre-convert the mapping channel to a RGB value. */
87  const Colour colour = AdjustBrightneSSE(Blitter_32bppBase::LookupColourInPalette(src->m), dst_mv->v);
88  dst_rgba->r = colour.r;
89  dst_rgba->g = colour.g;
90  dst_rgba->b = colour.b;
91  } else {
92  dst_rgba->r = src->r;
93  dst_rgba->g = src->g;
94  dst_rgba->b = src->b;
95  dst_mv->v = Blitter_32bppBase::DEFAULT_BRIGHTNESS;
96  }
97  } else {
98  dst_rgba->data = 0;
99  *(uint16_t*) dst_mv = 0;
100  }
101  dst_rgba++;
102  dst_mv++;
103  src++;
104  }
105 
106  /* Count the number of transparent pixels from the left. */
107  dst_rgba = dst_rgba_line + META_LENGTH;
108  uint32_t nb_pix_transp = 0;
109  for (uint x = src_sprite->width; x != 0; x--) {
110  if (dst_rgba->a == 0) nb_pix_transp++;
111  else break;
112  dst_rgba++;
113  }
114  (*dst_rgba_line).data = nb_pix_transp;
115 
116  Colour *nb_right = dst_rgba_line + 1;
117  dst_rgba_line = (Colour*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
118 
119  /* Count the number of transparent pixels from the right. */
120  dst_rgba = dst_rgba_line - 1;
121  nb_pix_transp = 0;
122  for (uint x = src_sprite->width; x != 0; x--) {
123  if (dst_rgba->a == 0) nb_pix_transp++;
124  else break;
125  dst_rgba--;
126  }
127  (*nb_right).data = nb_pix_transp;
128  }
129  }
130 
131  /* Store sprite flags. */
132  sd.flags = SF_NONE;
133  if (has_translucency) sd.flags |= SF_TRANSLUCENT;
134  if (!has_remap) sd.flags |= SF_NO_REMAP;
135  if (!has_anim) sd.flags |= SF_NO_ANIM;
136  memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
137 
138  return dst_sprite;
139 }
140 
141 #endif /* WITH_SSE */
SSE2 32 bpp blitter.
Functions related to SSE 32 bpp blitter.
static Colour LookupColourInPalette(uint index)
Look up the colour in the current palette.
Definition: 32bpp_base.hpp:37
Interface for something that can allocate memory for a sprite.
T * Allocate(size_t size)
Allocate memory for a sprite.
std::array< Sprite, ZOOM_LVL_END > SpriteCollection
Type defining a collection of sprites, one for each zoom level.
@ Font
A sprite used for fonts.
static constexpr uint8_t PALETTE_ANIM_START
Index in the _palettes array from which all animations are taking places (table/palettes....
Definition: gfx_type.h:294
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
GUISettings gui
settings related to the GUI
ZoomLevel zoom_min
minimum zoom out level
ZoomLevel zoom_max
maximum zoom out level
Definition of a common pixel in OpenTTD's realm.
uint8_t m
Remap-channel.
uint8_t b
Blue-channel.
uint8_t r
Red-channel.
uint8_t g
Green-channel.
uint8_t a
Alpha-channel.
Structure for passing information from the sprite loader to the blitter.
uint16_t width
Width of the sprite.
SpriteLoader::CommonPixel * data
The sprite itself.
uint16_t height
Height of the sprite.
Data structure describing a sprite.
Definition: spritecache.h:17
uint16_t width
Width of the sprite.
Definition: spritecache.h:19
uint16_t height
Height of the sprite.
Definition: spritecache.h:18
int16_t y_offs
Number of pixels to shift the sprite downwards.
Definition: spritecache.h:21
uint8_t data[]
Sprite data.
Definition: spritecache.h:22
int16_t x_offs
Number of pixels to shift the sprite to the right.
Definition: spritecache.h:20
Structure to access the alpha, red, green, and blue channels from a 32 bit number.
Definition: gfx_type.h:165
uint32_t data
Conversion of the channel information to a 32 bit number.
Definition: gfx_type.h:166
uint8_t a
colour channels in LE order
Definition: gfx_type.h:173
ZoomLevel
All zoom levels we know.
Definition: zoom_type.h:16
@ ZOOM_LVL_MAX
Maximum zoom level.
Definition: zoom_type.h:42
@ ZOOM_LVL_MIN
Minimum zoom level.
Definition: zoom_type.h:41