OpenTTD Source: src/blitter/32bpp_sse2.cpp Source File

OpenTTD Source 15.3

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
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
23 Sprite *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 */
32bpp_sse2.hpp
SSE2 32 bpp blitter.
32bpp_sse_func.hpp
Functions related to SSE 32 bpp blitter.
Blitter_32bppBase::LookupColourInPalette
static Colour LookupColourInPalette(uint index)
Look up the colour in the current palette.
Definition 32bpp_base.hpp:36
SpriteAllocator
Interface for something that can allocate memory for a sprite.
Definition spriteloader.hpp:104
SpriteAllocator::Allocate
T * Allocate(size_t size)
Allocate memory for a sprite.
Definition spriteloader.hpp:115
SpriteCollMap
Map zoom level to data.
Definition spriteloader.hpp:34
SpriteType
SpriteType
Types of sprites that might be loaded.
Definition gfx_type.h:357
SpriteType::Font
@ Font
A sprite used for fonts.
PALETTE_ANIM_START
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:341
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
GUISettings::zoom_min
ZoomLevel zoom_min
minimum zoom out level
Definition settings_type.h:191
GUISettings::zoom_max
ZoomLevel zoom_max
maximum zoom out level
Definition settings_type.h:192
SpriteLoader::CommonPixel
Definition of a common pixel in OpenTTD's realm.
Definition spriteloader.hpp:48
SpriteLoader::Sprite
Structure for passing information from the sprite loader to the blitter.
Definition spriteloader.hpp:62
SpriteLoader::Sprite::width
uint16_t width
Width of the sprite.
Definition spriteloader.hpp:64
SpriteLoader::Sprite::data
SpriteLoader::CommonPixel * data
The sprite itself.
Definition spriteloader.hpp:68
SpriteLoader::Sprite::height
uint16_t height
Height of the sprite.
Definition spriteloader.hpp:63
Sprite
Data structure describing a sprite.
Definition spritecache_type.h:16
Sprite::width
uint16_t width
Width of the sprite.
Definition spritecache_type.h:18
Sprite::height
uint16_t height
Height of the sprite.
Definition spritecache_type.h:17
Sprite::y_offs
int16_t y_offs
Number of pixels to shift the sprite downwards.
Definition spritecache_type.h:20
Sprite::data
std::byte data[]
Sprite data.
Definition spritecache_type.h:21
Sprite::x_offs
int16_t x_offs
Number of pixels to shift the sprite to the right.
Definition spritecache_type.h:19
ZoomLevel
ZoomLevel
All zoom levels we know.
Definition zoom_type.h:20
ZoomLevel::Max
@ Max
Maximum zoom level.
ZoomLevel::Min
@ Min
Minimum zoom level.