-
Notifications
You must be signed in to change notification settings - Fork 149
/
Gfx.h
244 lines (216 loc) · 7.93 KB
/
Gfx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#pragma once
#include "Graphics/PaletteMap.h"
#include "ImageId.h"
#include "Types.hpp"
#include "Ui/Rect.h"
#include "Ui/UiTypes.hpp"
#include <array>
#include <cstdint>
#include <optional>
namespace OpenLoco
{
using PaletteIndex_t = uint8_t;
struct AdvancedColour;
enum class ExtColour : uint8_t;
}
namespace OpenLoco::Drawing
{
class SoftwareDrawingEngine;
}
namespace OpenLoco::Gfx
{
struct RenderTarget;
namespace G1ExpectedCount
{
constexpr uint32_t kDisc = 0x101A; // And GOG
constexpr uint32_t kSteam = 0x0F38;
constexpr uint32_t kObjects = 0x40000;
}
#pragma pack(push, 1)
struct G1Header
{
uint32_t numEntries;
uint32_t totalSize;
};
struct G1Element32
{
uint32_t offset; // 0x00
int16_t width; // 0x04
int16_t height; // 0x06
int16_t xOffset; // 0x08
int16_t yOffset; // 0x0A
uint16_t flags; // 0x0C
int16_t zoomOffset; // 0x0E
};
// A version that can be 64-bit when ready...
struct G1Element
{
uint8_t* offset = nullptr;
int16_t width = 0;
int16_t height = 0;
int16_t xOffset = 0;
int16_t yOffset = 0;
uint16_t flags = 0;
int16_t zoomOffset = 0;
G1Element() = default;
G1Element(const G1Element32& src)
: offset((uint8_t*)src.offset)
, width(src.width)
, height(src.height)
, xOffset(src.xOffset)
, yOffset(src.yOffset)
, flags(src.flags)
, zoomOffset(src.zoomOffset)
{
}
};
#pragma pack(pop)
struct ImageExtents
{
uint8_t width;
uint8_t heightNegative;
uint8_t heightPositive;
};
namespace G1ElementFlags
{
constexpr uint16_t hasTransparancy = 1 << 0; // Image data contains transparent sections (when not set data is plain bmp)
constexpr uint16_t unk1 = 1 << 1; // Unknown function not used on any entry
constexpr uint16_t isRLECompressed = 1 << 2; // Image data is encoded using CS's form of run length encoding
constexpr uint16_t isR8G8B8Palette = 1 << 3; // Image data is a sequence of palette entries R8G8B8
constexpr uint16_t hasZoomSprites = 1 << 4; // Use a different sprite for higher zoom levels
constexpr uint16_t noZoomDraw = 1 << 5; // Does not get drawn at higher zoom levels (only zoom 0)
constexpr uint16_t duplicatePrevious = 1 << 6; // Duplicates the previous element but with adjusted x/y offsets
}
namespace ImageIdFlags
{
constexpr uint32_t remap = 1 << 29;
constexpr uint32_t translucent = 1 << 30;
constexpr uint32_t remap2 = 1 << 31;
}
void loadG1();
void initialiseCharacterWidths();
void initialiseNoiseMaskMap();
/*
void clear(RenderTarget& rt, uint32_t fill);
void clearSingle(RenderTarget& rt, uint8_t paletteId);
int16_t clipString(int16_t width, char* string);
uint16_t getStringWidth(const char* buffer);
uint16_t getMaxStringWidth(const char* buffer);
Ui::Point drawString(RenderTarget& rt, int16_t x, int16_t y, AdvancedColour colour, void* str);
int16_t drawStringLeftWrapped(
RenderTarget& rt,
int16_t x,
int16_t y,
int16_t width,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringLeft(
RenderTarget& rt,
int16_t x,
int16_t y,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringLeft(
RenderTarget& rt,
Ui::Point* origin,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringLeftClipped(
RenderTarget& rt,
int16_t x,
int16_t y,
int16_t width,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringRight(
RenderTarget& rt,
int16_t x,
int16_t y,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringRightUnderline(
RenderTarget& rt,
int16_t x,
int16_t y,
AdvancedColour colour,
string_id stringId,
const void* args);
void drawStringLeftUnderline(
RenderTarget& rt,
int16_t x,
int16_t y,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringCentred(
RenderTarget& rt,
int16_t x,
int16_t y,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringCentredClipped(
RenderTarget& rt,
int16_t x,
int16_t y,
int16_t width,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
uint16_t drawStringCentredWrapped(
RenderTarget& rt,
Ui::Point& origin,
uint16_t width,
AdvancedColour colour,
string_id stringId,
const void* args = nullptr);
void drawStringCentredRaw(
RenderTarget& rt,
int16_t x,
int16_t y,
int16_t width,
AdvancedColour colour,
const void* args);
void drawStringYOffsets(RenderTarget& rt, const Ui::Point& loc, AdvancedColour colour, const void* args, const int8_t* yOffsets);
uint16_t getStringWidthNewLined(const char* buffer);
std::pair<uint16_t, uint16_t> wrapString(char* buffer, uint16_t stringWidth);
void fillRect(Gfx::RenderTarget& rt, int16_t left, int16_t top, int16_t right, int16_t bottom, uint32_t colour);
void drawRect(Gfx::RenderTarget& rt, int16_t x, int16_t y, uint16_t dx, uint16_t dy, uint32_t colour);
void fillRectInset(Gfx::RenderTarget& rt, int16_t left, int16_t top, int16_t right, int16_t bottom, uint32_t colour, uint8_t flags);
void drawRectInset(Gfx::RenderTarget& rt, int16_t x, int16_t y, uint16_t dx, uint16_t dy, uint32_t colour, uint8_t flags);
void drawLine(Gfx::RenderTarget& rt, int16_t left, int16_t top, int16_t right, int16_t bottom, uint32_t colour);
void drawImage(Gfx::RenderTarget* rt, int16_t x, int16_t y, uint32_t image);
void drawImage(Gfx::RenderTarget& rt, const Ui::Point& pos, const ImageId& image);
void drawImageSolid(Gfx::RenderTarget& rt, const Ui::Point& pos, const ImageId& image, PaletteIndex_t paletteIndex);
void drawImagePaletteSet(Gfx::RenderTarget& rt, const Ui::Point& pos, const ImageId& image, PaletteMap::View palette, const G1Element* noiseImage);
*/
[[nodiscard]] uint32_t recolour(uint32_t image);
[[nodiscard]] uint32_t recolour(uint32_t image, Colour colour);
[[nodiscard]] uint32_t recolour(uint32_t image, ExtColour colour);
[[nodiscard]] uint32_t recolour2(uint32_t image, Colour colour1, Colour colour2);
[[nodiscard]] uint32_t recolour2(uint32_t image, ColourScheme colourScheme);
[[nodiscard]] uint32_t recolourTranslucent(uint32_t image, ExtColour colour);
[[nodiscard]] ImageId applyGhostToImage(uint32_t imageIndex);
[[nodiscard]] constexpr uint32_t getImageIndex(uint32_t imageId) { return imageId & 0x7FFFF; }
// Invalidates the entire screen.
void invalidateScreen();
// Invalidate a region of the screen.
void invalidateRegion(int32_t left, int32_t top, int32_t right, int32_t bottom);
// Renders all invalidated regions the next frame.
void render();
// Renders a region of the screen.
void render(Ui::Rect rect);
void render(int16_t left, int16_t top, int16_t right, int16_t bottom);
// Renders all invalidated regions and processes new messages.
void renderAndUpdate();
G1Element* getG1Element(uint32_t id);
Drawing::SoftwareDrawingEngine& getDrawingEngine();
void loadCurrency();
void loadPalette();
ImageExtents getImagesMaxExtent(const ImageId baseImageId, const size_t numImages);
}