OpenTTD Source 20241224-master-gee860a5c8e
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(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.
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.
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 b
colour channels in BE order
Definition gfx_type.h:171
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