OpenTTD Source 20250312-master-gcdcc6b491d
company_manager_face.h
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#ifndef COMPANY_MANAGER_FACE_H
11#define COMPANY_MANAGER_FACE_H
12
13#include "core/random_func.hpp"
14#include "core/bitmath_func.hpp"
15#include "table/sprites.h"
16#include "company_type.h"
17
30
31
33 CMFV_GENDER,
34 CMFV_ETHNICITY,
35 CMFV_GEN_ETHN,
36 CMFV_HAS_MOUSTACHE,
37 CMFV_HAS_TIE_EARRING,
38 CMFV_HAS_GLASSES,
39 CMFV_EYE_COLOUR,
40 CMFV_CHEEKS,
41 CMFV_CHIN,
42 CMFV_EYEBROWS,
43 CMFV_MOUSTACHE,
44 CMFV_LIPS,
45 CMFV_NOSE,
46 CMFV_HAIR,
47 CMFV_COLLAR,
48 CMFV_JACKET,
49 CMFV_TIE_EARRING,
50 CMFV_GLASSES,
51 CMFV_END,
52};
54
55
57 uint8_t offset;
58 uint8_t length;
59 uint8_t valid_values[GE_END];
60 SpriteID first_sprite[GE_END];
61};
62
65 /* Index off len WM WF BM BF WM WF BM BF
66 * CMFV_GENDER */ { 0, 1, { 2, 2, 2, 2 }, { 0, 0, 0, 0 } },
67 /* CMFV_ETHNICITY */ { 1, 2, { 2, 2, 2, 2 }, { 0, 0, 0, 0 } },
68 /* CMFV_GEN_ETHN */ { 0, 3, { 4, 4, 4, 4 }, { 0, 0, 0, 0 } },
69 /* CMFV_HAS_MOUSTACHE */ { 3, 1, { 2, 0, 2, 0 }, { 0, 0, 0, 0 } },
70 /* CMFV_HAS_TIE_EARRING */ { 3, 1, { 0, 2, 0, 2 }, { 0, 0, 0, 0 } },
71 /* CMFV_HAS_GLASSES */ { 4, 1, { 2, 2, 2, 2 }, { 0, 0, 0, 0 } },
72 /* CMFV_EYE_COLOUR */ { 5, 2, { 3, 3, 1, 1 }, { 0, 0, 0, 0 } },
73 /* CMFV_CHEEKS */ { 0, 0, { 1, 1, 1, 1 }, { 0x325, 0x326, 0x390, 0x3B0 } },
74 /* CMFV_CHIN */ { 7, 2, { 4, 1, 2, 2 }, { 0x327, 0x327, 0x391, 0x3B1 } },
75 /* CMFV_EYEBROWS */ { 9, 4, { 12, 16, 11, 16 }, { 0x32B, 0x337, 0x39A, 0x3B8 } },
76 /* CMFV_MOUSTACHE */ { 13, 2, { 3, 0, 3, 0 }, { 0x367, 0, 0x397, 0 } },
77 /* CMFV_LIPS */ { 13, 4, { 12, 10, 9, 9 }, { 0x35B, 0x351, 0x3A5, 0x3C8 } },
78 /* CMFV_NOSE */ { 17, 3, { 8, 4, 4, 5 }, { 0x349, 0x34C, 0x393, 0x3B3 } },
79 /* CMFV_HAIR */ { 20, 4, { 9, 5, 5, 5 }, { 0x382, 0x38B, 0x3D4, 0x3D9 } },
80 /* CMFV_COLLAR */ { 26, 2, { 4, 4, 4, 4 }, { 0x36E, 0x37B, 0x36E, 0x37B } },
81 /* CMFV_JACKET */ { 24, 2, { 3, 3, 3, 3 }, { 0x36B, 0x378, 0x36B, 0x378 } },
82 /* CMFV_TIE_EARRING */ { 28, 3, { 6, 3, 6, 3 }, { 0x372, 0x37F, 0x372, 0x3D1 } },
83 /* CMFV_GLASSES */ { 31, 1, { 2, 2, 2, 2 }, { 0x347, 0x347, 0x3AE, 0x3AE } }
84};
86static_assert(lengthof(_cmf_info) == CMFV_END);
87
97{
98 assert(_cmf_info[cmfv].valid_values[ge] != 0);
99
100 return GB(cmf, _cmf_info[cmfv].offset, _cmf_info[cmfv].length);
101}
102
112{
113 assert(val < _cmf_info[cmfv].valid_values[ge]);
114
115 SB(cmf, _cmf_info[cmfv].offset, _cmf_info[cmfv].length, val);
116}
117
130{
131 int8_t val = GetCompanyManagerFaceBits(cmf, cmfv, ge) + amount; // the new value for the cmfv
132
133 /* scales the new value to the correct scope */
134 while (val < 0) {
135 val += _cmf_info[cmfv].valid_values[ge];
136 }
137 val %= _cmf_info[cmfv].valid_values[ge];
138
139 SetCompanyManagerFaceBits(cmf, cmfv, ge, val); // save the new value
140}
141
150{
151 return GB(cmf, _cmf_info[cmfv].offset, _cmf_info[cmfv].length) < _cmf_info[cmfv].valid_values[ge];
152}
153
163{
164 assert(val < (1U << _cmf_info[cmfv].length));
165
166 return (val * _cmf_info[cmfv].valid_values[ge]) >> _cmf_info[cmfv].length;
167}
168
175{
176 IncreaseCompanyManagerFaceBits(cmf, CMFV_ETHNICITY, GE_WM, 0); // scales the ethnicity
177
178 GenderEthnicity ge = (GenderEthnicity)GB(cmf, _cmf_info[CMFV_GEN_ETHN].offset, _cmf_info[CMFV_GEN_ETHN].length); // gender & ethnicity of the face
179
180 /* Is a male face with moustache. Need to reduce CPU load in the loop. */
181 bool is_moust_male = !HasBit(ge, GENDER_FEMALE) && GetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge) != 0;
182
183 for (CompanyManagerFaceVariable cmfv = CMFV_EYE_COLOUR; cmfv < CMFV_END; cmfv++) { // scales all other variables
184
185 /* The moustache variable will be scaled only if it is a male face with has a moustache */
186 if (cmfv != CMFV_MOUSTACHE || is_moust_male) {
187 IncreaseCompanyManagerFaceBits(cmf, cmfv, ge, 0);
188 }
189 }
190}
191
205{
206 cmf = randomizer.Next(); // random all company manager's face bits
207
208 /* scale ge: 0 == GE_WM, 1 == GE_WF, 2 == GE_BM, 3 == GE_BF (and maybe in future: ...) */
209 ge = (GenderEthnicity)((uint)ge % GE_END);
210
211 /* set the gender (and ethnicity) for the new company manager's face */
212 if (adv) {
213 SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, ge, ge);
214 } else {
215 SetCompanyManagerFaceBits(cmf, CMFV_GENDER, ge, HasBit(ge, GENDER_FEMALE));
216 }
217
218 /* scales all company manager's face bits to the correct scope */
220}
221
231{
232 assert(_cmf_info[cmfv].valid_values[ge] != 0);
233
234 return _cmf_info[cmfv].first_sprite[ge] + GB(cmf, _cmf_info[cmfv].offset, _cmf_info[cmfv].length);
235}
236
237void DrawCompanyManagerFace(CompanyManagerFace face, Colours colour, const Rect &r);
238
239#endif /* COMPANY_MANAGER_FACE_H */
Functions related to bit mathematics.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
uint GetCompanyManagerFaceBits(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge)
Make sure the table's size is right.
void SetCompanyManagerFaceBits(CompanyManagerFace &cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge, uint val)
Sets the company manager's face bits for the given company manager's face variable.
GenderEthnicity
The gender/race combinations that we have faces for.
@ GE_BM
A male of African origin (black)
@ GE_WF
A female of Caucasian origin (white)
@ GE_WM
A male of Caucasian origin (white)
@ ETHNICITY_BLACK
This bit set means black, otherwise white.
@ GE_BF
A female of African origin (black)
@ GENDER_FEMALE
This bit set means a female, otherwise male.
void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, Randomizer &randomizer)
Make a random new face.
void ScaleAllCompanyManagerFaceBits(CompanyManagerFace &cmf)
Scales all company manager's face bits to the correct scope.
CompanyManagerFaceVariable
Bitgroups of the CompanyManagerFace variable.
void DrawCompanyManagerFace(CompanyManagerFace face, Colours colour, const Rect &r)
Draws the face of a company manager's face.
uint ScaleCompanyManagerFaceValue(CompanyManagerFaceVariable cmfv, GenderEthnicity ge, uint val)
Scales a company manager's face bits variable to the correct scope.
bool AreCompanyManagerFaceBitsValid(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge)
Checks whether the company manager's face bits have a valid range.
static const CompanyManagerFaceBitsInfo _cmf_info[]
Lookup table for indices into the CompanyManagerFace, valid ranges and sprites.
void IncreaseCompanyManagerFaceBits(CompanyManagerFace &cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge, int8_t amount)
Increase/Decrease the company manager's face variable by the given amount.
SpriteID GetCompanyManagerFaceSprite(CompanyManagerFace cmf, CompanyManagerFaceVariable cmfv, GenderEthnicity ge)
Gets the sprite to draw for the given company manager's face variable.
Types related to companies.
uint32_t CompanyManagerFace
Company manager face bits, info see in company_manager_face.h.
#define DECLARE_ENUM_AS_BIT_SET(enum_type)
Operators to allow to work with enum as with type safe bit set in C++.
Definition enum_type.hpp:70
#define DECLARE_INCREMENT_DECREMENT_OPERATORS(enum_type)
For some enums it is useful to have pre/post increment/decrement operators.
Definition enum_type.hpp:63
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
Pseudo random number generator.
This file contains all sprite-related enums and defines.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:277
Information about the valid values of CompanyManagerFace bitgroups as well as the sprites to draw.
SpriteID first_sprite[GE_END]
The first sprite per gender/ethnicity.
uint8_t length
Number of bits used in the CompanyManagerFace.
uint8_t valid_values[GE_END]
The number of valid values per gender/ethnicity.
uint8_t offset
Offset in bits into the CompanyManagerFace.
Structure to encapsulate the pseudo random number generators.
uint32_t Next()
Generate the next pseudo random number.
Specification of a rectangle with absolute coordinates of all edges.