OpenTTD Source 15.0-beta2
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 uint all_sprites_size = 0;
40 for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
41 const SpriteLoader::Sprite *src_sprite = &sprite[z];
42 sd.infos[z].sprite_width = src_sprite->width;
43 sd.infos[z].sprite_offset = all_sprites_size;
44 sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32_t) * META_LENGTH;
45
46 const uint rgba_size = sd.infos[z].sprite_line_size * src_sprite->height;
47 sd.infos[z].mv_offset = all_sprites_size + rgba_size;
48
49 const uint mv_size = sizeof(MapValue) * src_sprite->width * src_sprite->height;
50 all_sprites_size += rgba_size + mv_size;
51 }
52
53 Sprite *dst_sprite = allocator.Allocate<Sprite>(sizeof(Sprite) + sizeof(SpriteData) + all_sprites_size);
54 dst_sprite->height = sprite[ZOOM_LVL_MIN].height;
55 dst_sprite->width = sprite[ZOOM_LVL_MIN].width;
56 dst_sprite->x_offs = sprite[ZOOM_LVL_MIN].x_offs;
57 dst_sprite->y_offs = sprite[ZOOM_LVL_MIN].y_offs;
58 memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
59
60 /* Copy colours and determine flags. */
61 bool has_remap = false;
62 bool has_anim = false;
63 bool has_translucency = false;
64 for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
65 const SpriteLoader::Sprite *src_sprite = &sprite[z];
66 const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
67 Colour *dst_rgba_line = (Colour *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].sprite_offset];
68 MapValue *dst_mv = (MapValue *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].mv_offset];
69 for (uint y = src_sprite->height; y != 0; y--) {
70 Colour *dst_rgba = dst_rgba_line + META_LENGTH;
71 for (uint x = src_sprite->width; x != 0; x--) {
72 if (src->a != 0) {
73 dst_rgba->a = src->a;
74 if (src->a != 0 && src->a != 255) has_translucency = true;
75 dst_mv->m = src->m;
76 if (src->m != 0) {
77 /* Do some accounting for flags. */
78 has_remap = true;
79 if (src->m >= PALETTE_ANIM_START) has_anim = true;
80
81 /* Get brightest value (or default brightness if it's a black pixel). */
82 const uint8_t rgb_max = std::max({src->r, src->g, src->b});
83 dst_mv->v = (rgb_max == 0) ? DEFAULT_BRIGHTNESS : rgb_max;
84
85 /* Pre-convert the mapping channel to a RGB value. */
86 const Colour colour = AdjustBrightneSSE(Blitter_32bppBase::LookupColourInPalette(src->m), dst_mv->v);
87 dst_rgba->r = colour.r;
88 dst_rgba->g = colour.g;
89 dst_rgba->b = colour.b;
90 } else {
91 dst_rgba->r = src->r;
92 dst_rgba->g = src->g;
93 dst_rgba->b = src->b;
94 dst_mv->v = DEFAULT_BRIGHTNESS;
95 }
96 } else {
97 dst_rgba->data = 0;
98 *(uint16_t*) dst_mv = 0;
99 }
100 dst_rgba++;
101 dst_mv++;
102 src++;
103 }
104
105 /* Count the number of transparent pixels from the left. */
106 dst_rgba = dst_rgba_line + META_LENGTH;
107 uint32_t nb_pix_transp = 0;
108 for (uint x = src_sprite->width; x != 0; x--) {
109 if (dst_rgba->a == 0) nb_pix_transp++;
110 else break;
111 dst_rgba++;
112 }
113 (*dst_rgba_line).data = nb_pix_transp;
114
115 Colour *nb_right = dst_rgba_line + 1;
116 dst_rgba_line = (Colour*) ((uint8_t*) dst_rgba_line + sd.infos[z].sprite_line_size);
117
118 /* Count the number of transparent pixels from the right. */
119 dst_rgba = dst_rgba_line - 1;
120 nb_pix_transp = 0;
121 for (uint x = src_sprite->width; x != 0; x--) {
122 if (dst_rgba->a == 0) nb_pix_transp++;
123 else break;
124 dst_rgba--;
125 }
126 (*nb_right).data = nb_pix_transp;
127 }
128 }
129
130 /* Store sprite flags. */
131 sd.flags = {};
132 if (has_translucency) sd.flags.Set(SpriteFlag::Translucent);
133 if (!has_remap) sd.flags.Set(SpriteFlag::NoRemap);
134 if (!has_anim) sd.flags.Set(SpriteFlag::NoAnim);
135 memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
136
137 return dst_sprite;
138}
139
140#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:330
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:58
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
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