OpenTTD Source 20250522-master-g467f832c2f
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
21static FBlitter_32bppSSE2 iFBlitter_32bppSSE2;
22
23Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, 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 = ZoomLevel::Min;
30 ZoomLevel zoom_max = ZoomLevel::Min;
31 if (sprite_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 = ZoomLevel::Max;
35 }
36
37 /* Calculate sizes and allocate. */
38 SpriteData sd{};
39 uint all_sprites_size = 0;
40 for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
41 const SpriteLoader::Sprite *src_sprite = &sprite[z];
42 auto &info = sd.infos[z];
43 info.sprite_width = src_sprite->width;
44 info.sprite_offset = all_sprites_size;
45 info.sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
46
47 const uint rgba_size = info.sprite_line_size * src_sprite->height;
48 info.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 const auto &root_sprite = sprite.Root();
56 dst_sprite->height = root_sprite.height;
57 dst_sprite->width = root_sprite.width;
58 dst_sprite->x_offs = root_sprite.x_offs;
59 dst_sprite->y_offs = root_sprite.y_offs;
60 std::copy_n(reinterpret_cast<std::byte *>(&sd), sizeof(SpriteData), dst_sprite->data);
61
62 /* Copy colours and determine flags. */
63 bool has_remap = false;
64 bool has_anim = false;
65 bool has_translucency = false;
66 for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
67 const SpriteLoader::Sprite *src_sprite = &sprite[z];
68 const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
69 const auto &info = sd.infos[z];
70 Colour *dst_rgba_line = reinterpret_cast<Colour *>(&dst_sprite->data[sizeof(SpriteData) + info.sprite_offset]);
71 MapValue *dst_mv = reinterpret_cast<MapValue *>(&dst_sprite->data[sizeof(SpriteData) + info.mv_offset]);
72 for (uint y = src_sprite->height; y != 0; y--) {
73 Colour *dst_rgba = dst_rgba_line + META_LENGTH;
74 for (uint x = src_sprite->width; x != 0; x--) {
75 if (src->a != 0) {
76 dst_rgba->a = src->a;
77 if (src->a != 0 && src->a != 255) has_translucency = true;
78 dst_mv->m = src->m;
79 if (src->m != 0) {
80 /* Do some accounting for flags. */
81 has_remap = true;
82 if (src->m >= PALETTE_ANIM_START) has_anim = true;
83
84 /* Get brightest value (or default brightness if it's a black pixel). */
85 const uint8_t rgb_max = std::max({src->r, src->g, src->b});
86 dst_mv->v = (rgb_max == 0) ? DEFAULT_BRIGHTNESS : rgb_max;
87
88 /* Pre-convert the mapping channel to a RGB value. */
89 const Colour colour = AdjustBrightneSSE(Blitter_32bppBase::LookupColourInPalette(src->m), dst_mv->v);
90 dst_rgba->r = colour.r;
91 dst_rgba->g = colour.g;
92 dst_rgba->b = colour.b;
93 } else {
94 dst_rgba->r = src->r;
95 dst_rgba->g = src->g;
96 dst_rgba->b = src->b;
97 dst_mv->v = DEFAULT_BRIGHTNESS;
98 }
99 } else {
100 dst_rgba->data = 0;
101 *(uint16_t*) dst_mv = 0;
102 }
103 dst_rgba++;
104 dst_mv++;
105 src++;
106 }
107
108 /* Count the number of transparent pixels from the left. */
109 dst_rgba = dst_rgba_line + META_LENGTH;
110 uint32_t nb_pix_transp = 0;
111 for (uint x = src_sprite->width; x != 0; x--) {
112 if (dst_rgba->a == 0) nb_pix_transp++;
113 else break;
114 dst_rgba++;
115 }
116 (*dst_rgba_line).data = nb_pix_transp;
117
118 Colour *nb_right = dst_rgba_line + 1;
119 dst_rgba_line = reinterpret_cast<Colour *>(reinterpret_cast<std::byte *>(dst_rgba_line) + info.sprite_line_size);
120
121 /* Count the number of transparent pixels from the right. */
122 dst_rgba = dst_rgba_line - 1;
123 nb_pix_transp = 0;
124 for (uint x = src_sprite->width; x != 0; x--) {
125 if (dst_rgba->a == 0) nb_pix_transp++;
126 else break;
127 dst_rgba--;
128 }
129 (*nb_right).data = nb_pix_transp;
130 }
131 }
132
133 /* Store sprite flags. */
134 sd.flags = {};
135 if (has_translucency) sd.flags.Set(SpriteFlag::Translucent);
136 if (!has_remap) sd.flags.Set(SpriteFlag::NoRemap);
137 if (!has_anim) sd.flags.Set(SpriteFlag::NoAnim);
138 std::copy_n(reinterpret_cast<std::byte *>(&sd), sizeof(SpriteData), dst_sprite->data);
139
140 return dst_sprite;
141}
142
143#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.
Interface for something that can allocate memory for a sprite.
T * Allocate(size_t size)
Allocate memory for a sprite.
Map zoom level to data.
SpriteType
Types of sprites that might be loaded.
Definition gfx_type.h:352
@ 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:336
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:59
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.
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
std::byte 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
ZoomLevel
All zoom levels we know.
Definition zoom_type.h:16
@ Max
Maximum zoom level.
@ Min
Minimum zoom level.