2020-12-31 07:32:16 -08:00
|
|
|
// Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
|
|
|
|
|
|
|
#include "FaceParts.h"
|
|
|
|
#include "FileSystem.h"
|
|
|
|
#include "SDLWrappers.h"
|
|
|
|
#include "libs.h"
|
2019-01-02 08:59:07 -08:00
|
|
|
#include "utils.h"
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
static const int MAX_GENDERS = 6;
|
|
|
|
static const int MAX_RACES = 16;
|
|
|
|
static const int MAX_SPECIES = 10;
|
2019-01-02 08:59:07 -08:00
|
|
|
static const Uint32 GENDER_SHIFT = 0;
|
|
|
|
static const Uint32 GENDER_MASK = ((1u << MAX_GENDERS) - 1u) << GENDER_SHIFT;
|
|
|
|
static const Uint32 RACE_SHIFT = GENDER_SHIFT + MAX_GENDERS;
|
|
|
|
static const Uint32 RACE_MASK = ((1u << MAX_RACES) - 1u) << RACE_SHIFT;
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
static const Uint32 SPECIES_SHIFT = RACE_SHIFT + MAX_RACES;
|
2019-01-02 08:59:07 -08:00
|
|
|
static const Uint32 SPECIES_MASK = ((1u << MAX_SPECIES) - 1u) << SPECIES_SHIFT;
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
|
|
|
|
// You can never have too many static_asserts, right?
|
|
|
|
static_assert(((MAX_GENDERS + MAX_RACES + MAX_SPECIES) == 32), "unused bits in the face part selector");
|
|
|
|
static_assert(((GENDER_MASK | RACE_MASK | SPECIES_MASK) == UINT32_MAX), "unused bits in the face part selector");
|
|
|
|
static_assert(((GENDER_MASK & RACE_MASK) == 0u), "face part selector: overlap between gender and race mask");
|
|
|
|
static_assert(((GENDER_MASK & SPECIES_MASK) == 0u), "face part selector: overlap between gender and species mask");
|
|
|
|
static_assert(((RACE_MASK & SPECIES_MASK) == 0u), "face part selector: overlap between race and species mask");
|
|
|
|
|
|
|
|
struct Part {
|
|
|
|
Uint32 selector; // a bitmask indicating which species, races and genders can use this part
|
|
|
|
SDLSurfacePtr part;
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
Part() :
|
|
|
|
selector(0u) {}
|
|
|
|
Part(const Uint32 sel, SDLSurfacePtr im) :
|
|
|
|
selector(sel),
|
|
|
|
part(im) {}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SpeciesInfo {
|
|
|
|
int num_races;
|
|
|
|
int num_genders;
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
SpeciesInfo(int nraces, int ngenders) :
|
|
|
|
num_races(nraces),
|
|
|
|
num_genders(ngenders) {}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class PartDb {
|
|
|
|
public:
|
|
|
|
std::vector<SpeciesInfo> species;
|
|
|
|
|
|
|
|
std::vector<Part> heads;
|
|
|
|
std::vector<Part> eyes;
|
|
|
|
std::vector<Part> noses;
|
|
|
|
std::vector<Part> mouths;
|
|
|
|
std::vector<Part> hairstyles;
|
|
|
|
std::vector<Part> accessories;
|
|
|
|
std::vector<Part> clothes;
|
|
|
|
std::vector<Part> armour;
|
|
|
|
|
2014-09-15 14:45:41 -07:00
|
|
|
SDLSurfacePtr background_general;
|
|
|
|
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
void Clear();
|
|
|
|
void Scan();
|
2019-01-02 08:59:07 -08:00
|
|
|
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
private:
|
|
|
|
void ScanSpecies(const std::string &dir, int species_idx);
|
|
|
|
void ScanParts(std::vector<Part> &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix);
|
|
|
|
void ScanGenderedParts(std::vector<Part> &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix);
|
|
|
|
};
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
static Uint32 _make_selector(int species, int race, int gender)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
assert(species < MAX_SPECIES);
|
|
|
|
assert(race < MAX_RACES);
|
|
|
|
assert(gender < MAX_GENDERS);
|
|
|
|
|
|
|
|
Uint32 mask = 0u;
|
2019-01-02 08:59:07 -08:00
|
|
|
if (species < 0) {
|
|
|
|
mask |= SPECIES_MASK;
|
|
|
|
} else {
|
|
|
|
mask |= (1u << (species + SPECIES_SHIFT));
|
|
|
|
}
|
|
|
|
if (race < 0) {
|
|
|
|
mask |= RACE_MASK;
|
|
|
|
} else {
|
|
|
|
mask |= (1u << (race + RACE_SHIFT));
|
|
|
|
}
|
|
|
|
if (gender < 0) {
|
|
|
|
mask |= GENDER_MASK;
|
|
|
|
} else {
|
|
|
|
mask |= (1u << (gender + GENDER_SHIFT));
|
|
|
|
}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
static int _count_parts(const std::vector<Part> &parts, const Uint32 selector)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
int count = 0;
|
|
|
|
for (const auto &part : parts) {
|
|
|
|
if ((selector & part.selector) == selector) ++count;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
static SDL_Surface *_get_part(const std::vector<Part> &parts, const Uint32 selector, int index)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
for (const auto &part : parts) {
|
|
|
|
if ((selector & part.selector) == selector) {
|
2019-01-02 08:59:07 -08:00
|
|
|
if (!index) {
|
|
|
|
return part.part.Get();
|
|
|
|
}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
--index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _blit_image(SDL_Surface *target, SDL_Surface *source, int xoff, int yoff)
|
|
|
|
{
|
2014-09-15 14:45:41 -07:00
|
|
|
assert(target);
|
|
|
|
if (!source) return;
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
SDL_Rect destrec = { 0, 0, 0, 0 };
|
2015-11-29 08:11:42 -08:00
|
|
|
// if the source is the full size, then ignore the offset
|
|
|
|
if ((source->w == FaceParts::FACE_WIDTH) &&
|
2019-01-02 08:59:07 -08:00
|
|
|
(source->h == FaceParts::FACE_HEIGHT)) {
|
2015-11-29 08:11:42 -08:00
|
|
|
destrec.x = 0;
|
|
|
|
destrec.y = 0;
|
|
|
|
} else {
|
|
|
|
destrec.x = ((FaceParts::FACE_WIDTH - source->w) / 2) + xoff;
|
|
|
|
destrec.y = yoff;
|
|
|
|
}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
SDL_BlitSurface(source, 0, target, &destrec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PartDb *s_partdb;
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
namespace fs = FileSystem;
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void PartDb::Clear()
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
species.clear();
|
|
|
|
heads.clear();
|
|
|
|
eyes.clear();
|
|
|
|
noses.clear();
|
|
|
|
mouths.clear();
|
|
|
|
hairstyles.clear();
|
|
|
|
accessories.clear();
|
|
|
|
clothes.clear();
|
|
|
|
armour.clear();
|
|
|
|
}
|
|
|
|
|
2014-09-15 14:45:41 -07:00
|
|
|
static const char BACKGROUND_GENERAL_PATH[] = "facegen/backgrounds/general.png";
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void PartDb::Scan()
|
|
|
|
{
|
2019-06-17 15:14:27 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
Clear();
|
|
|
|
|
2014-09-15 14:45:41 -07:00
|
|
|
background_general = LoadSurfaceFromFile(BACKGROUND_GENERAL_PATH);
|
|
|
|
if (!background_general) {
|
|
|
|
Output("Failed to load image %s\n", BACKGROUND_GENERAL_PATH);
|
|
|
|
}
|
|
|
|
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
int species_count = 0;
|
|
|
|
const auto flags = fs::FileEnumerator::IncludeDirs | fs::FileEnumerator::ExcludeFiles;
|
|
|
|
for (fs::FileEnumerator dirs(fs::gameDataFiles, "facegen", flags); !dirs.Finished(); dirs.Next()) {
|
2014-09-15 14:45:17 -07:00
|
|
|
if (!starts_with(dirs.Current().GetName(), "species_"))
|
|
|
|
continue;
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
if (species_count >= MAX_SPECIES) {
|
|
|
|
Output("FaceParts: reached the limit on the number of species\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ScanSpecies(dirs.Current().GetPath(), species_count);
|
|
|
|
++species_count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void PartDb::ScanSpecies(const std::string &basedir, const int species_idx)
|
|
|
|
{
|
2019-06-17 15:14:27 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
int race_count = 0;
|
|
|
|
const auto flags = fs::FileEnumerator::IncludeDirs | fs::FileEnumerator::ExcludeFiles;
|
|
|
|
for (fs::FileEnumerator dirs(fs::gameDataFiles, basedir, flags); !dirs.Finished(); dirs.Next()) {
|
|
|
|
const std::string &path = dirs.Current().GetPath();
|
|
|
|
const std::string &name = dirs.Current().GetName();
|
|
|
|
|
|
|
|
if (name == "accessories") {
|
|
|
|
ScanParts(this->accessories, species_idx, -1, path, "acc_");
|
|
|
|
} else if (name == "clothes") {
|
|
|
|
ScanGenderedParts(this->clothes, species_idx, -1, path, "cloth_");
|
|
|
|
ScanParts(this->armour, species_idx, -1, path, "armour_");
|
|
|
|
} else if (starts_with(name, "race_")) {
|
|
|
|
if (race_count >= MAX_RACES) {
|
|
|
|
Output("FaceParts: reached the limit on the number of races\n");
|
|
|
|
continue; // continue to ensure 'accessories' and 'clothes' dirs can still be scanned
|
|
|
|
}
|
|
|
|
const int race_idx = race_count++;
|
|
|
|
|
|
|
|
ScanGenderedParts(this->heads, species_idx, race_idx, fs::JoinPath(path, "head"), "head_");
|
|
|
|
ScanGenderedParts(this->eyes, species_idx, race_idx, fs::JoinPath(path, "eyes"), "eyes_");
|
|
|
|
ScanGenderedParts(this->noses, species_idx, race_idx, fs::JoinPath(path, "nose"), "nose_");
|
|
|
|
ScanGenderedParts(this->mouths, species_idx, race_idx, fs::JoinPath(path, "mouth"), "mouth_");
|
|
|
|
ScanGenderedParts(this->hairstyles, species_idx, race_idx, fs::JoinPath(path, "hair"), "hair_");
|
|
|
|
} else {
|
|
|
|
Output("FaceParts: unknown directory '%s'\n", path.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
species.push_back(SpeciesInfo(race_count, 2)); // XXX currently we hardcode genders = 2
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void PartDb::ScanParts(std::vector<Part> &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix)
|
|
|
|
{
|
2019-06-17 15:14:27 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
const Uint32 selector = _make_selector(species_idx, race_idx, -1);
|
|
|
|
for (fs::FileEnumerator files(fs::gameDataFiles, path); !files.Finished(); files.Next()) {
|
|
|
|
const std::string &name = files.Current().GetName();
|
|
|
|
if (starts_with(name, prefix)) {
|
|
|
|
SDLSurfacePtr im = LoadSurfaceFromFile(files.Current().GetPath());
|
|
|
|
if (im) {
|
|
|
|
output.push_back(Part(selector, im));
|
|
|
|
} else {
|
|
|
|
Output("Failed to load image %s\n", files.Current().GetPath().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void PartDb::ScanGenderedParts(std::vector<Part> &output, const int species_idx, const int race_idx, const std::string &path, const char *prefix)
|
|
|
|
{
|
2019-06-17 15:14:27 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
const int prefix_len = strlen(prefix);
|
|
|
|
for (fs::FileEnumerator files(fs::gameDataFiles, path); !files.Finished(); files.Next()) {
|
|
|
|
const std::string &name = files.Current().GetName();
|
|
|
|
if (starts_with(name, prefix)) {
|
2015-11-29 08:08:48 -08:00
|
|
|
char *end = nullptr;
|
|
|
|
int gender_idx = strtol(name.c_str() + prefix_len, &end, 10);
|
|
|
|
Uint32 sel;
|
|
|
|
// HACK -- attempt to recognise `foo_3.png' style names
|
|
|
|
if (strcmp(end, ".png") == 0) {
|
|
|
|
sel = _make_selector(species_idx, race_idx, -1);
|
|
|
|
} else {
|
|
|
|
if (gender_idx < 0 || gender_idx >= MAX_GENDERS) {
|
|
|
|
Output("Gender out of range: %s\n", files.Current().GetPath().c_str());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
sel = _make_selector(species_idx, race_idx, gender_idx);
|
|
|
|
}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
|
|
|
|
SDLSurfacePtr im = LoadSurfaceFromFile(files.Current().GetPath());
|
|
|
|
if (im) {
|
|
|
|
output.push_back(Part(sel, im));
|
|
|
|
} else {
|
|
|
|
Output("Failed to load image %s\n", files.Current().GetPath().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const int FaceParts::FACE_WIDTH = 295;
|
|
|
|
const int FaceParts::FACE_HEIGHT = 285;
|
|
|
|
|
|
|
|
void FaceParts::Init()
|
|
|
|
{
|
2019-06-17 15:14:27 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
s_partdb = new PartDb;
|
|
|
|
s_partdb->Scan();
|
|
|
|
Output("Face Generation source images loaded.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void FaceParts::Uninit()
|
|
|
|
{
|
|
|
|
delete s_partdb;
|
|
|
|
s_partdb = nullptr;
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumSpecies()
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return s_partdb->species.size();
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumGenders(const int speciesIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
assert(speciesIdx >= 0 && speciesIdx < NumSpecies());
|
|
|
|
return s_partdb->species[speciesIdx].num_genders;
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumRaces(const int speciesIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
assert(speciesIdx >= 0 && speciesIdx < NumSpecies());
|
|
|
|
return s_partdb->species[speciesIdx].num_races;
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumHeads(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->heads, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumEyes(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->eyes, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumNoses(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->noses, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumMouths(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->mouths, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumHairstyles(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->hairstyles, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumClothes(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->clothes, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumAccessories(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->accessories, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
int FaceParts::NumArmour(const int speciesIdx, const int raceIdx, const int genderIdx)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
return _count_parts(s_partdb->armour, _make_selector(speciesIdx, raceIdx, genderIdx));
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
static void _pick(Random &rng, int &inout_value, const int limit)
|
|
|
|
{
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
assert(limit > 0);
|
|
|
|
// we always run the RNG, even if the result is not needed, because that way
|
|
|
|
// the output (index) for a particular component should be fixed for a given seed,
|
|
|
|
// independent of changes to other components
|
|
|
|
const Uint32 rng_value = (rng.Int32() % limit);
|
|
|
|
if (inout_value < 0) {
|
|
|
|
inout_value = rng_value;
|
|
|
|
assert(inout_value >= 0 && inout_value < limit);
|
|
|
|
} else {
|
2019-04-26 10:00:22 -07:00
|
|
|
inout_value = (inout_value % limit);
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-02 08:59:07 -08:00
|
|
|
void FaceParts::PickFaceParts(FaceDescriptor &inout_face, const Uint32 seed)
|
|
|
|
{
|
2019-10-13 08:09:07 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
Random rand(seed);
|
|
|
|
|
|
|
|
_pick(rand, inout_face.species, NumSpecies());
|
|
|
|
_pick(rand, inout_face.race, NumRaces(inout_face.species));
|
|
|
|
_pick(rand, inout_face.gender, NumGenders(inout_face.species));
|
|
|
|
|
|
|
|
const Uint32 selector = _make_selector(inout_face.species, inout_face.race, inout_face.gender);
|
|
|
|
|
|
|
|
_pick(rand, inout_face.head, _count_parts(s_partdb->heads, selector));
|
|
|
|
_pick(rand, inout_face.eyes, _count_parts(s_partdb->eyes, selector));
|
|
|
|
_pick(rand, inout_face.nose, _count_parts(s_partdb->noses, selector));
|
|
|
|
_pick(rand, inout_face.mouth, _count_parts(s_partdb->mouths, selector));
|
|
|
|
_pick(rand, inout_face.hairstyle, _count_parts(s_partdb->hairstyles, selector));
|
|
|
|
|
2019-05-19 07:32:24 -07:00
|
|
|
const bool has_accessories = (rand.Int32() & 1 || inout_face.accessories >= 0);
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
_pick(rand, inout_face.accessories, _count_parts(s_partdb->accessories, selector));
|
2019-01-02 08:59:07 -08:00
|
|
|
if (!has_accessories) {
|
|
|
|
inout_face.accessories = 0;
|
|
|
|
}
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
|
|
|
|
_pick(rand, inout_face.clothes, _count_parts(s_partdb->clothes, selector));
|
|
|
|
_pick(rand, inout_face.armour, _count_parts(s_partdb->armour, selector));
|
|
|
|
}
|
|
|
|
|
2019-04-26 10:00:22 -07:00
|
|
|
void FaceParts::BuildFaceImage(SDL_Surface *faceIm, const FaceDescriptor &face)
|
2019-01-02 08:59:07 -08:00
|
|
|
{
|
2019-10-13 08:09:07 -07:00
|
|
|
PROFILE_SCOPED()
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
const Uint32 selector = _make_selector(face.species, face.race, face.gender);
|
|
|
|
|
2014-09-15 14:45:41 -07:00
|
|
|
_blit_image(faceIm, s_partdb->background_general.Get(), 0, 0);
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
_blit_image(faceIm, _get_part(s_partdb->heads, selector, face.head), 0, 0);
|
2019-04-26 10:00:22 -07:00
|
|
|
if (!face.armour) {
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
_blit_image(faceIm, _get_part(s_partdb->clothes, selector, face.clothes), 0, 135);
|
|
|
|
}
|
|
|
|
_blit_image(faceIm, _get_part(s_partdb->eyes, selector, face.eyes), 0, 41);
|
|
|
|
_blit_image(faceIm, _get_part(s_partdb->noses, selector, face.nose), 1, 89);
|
|
|
|
_blit_image(faceIm, _get_part(s_partdb->mouths, selector, face.mouth), 0, 155);
|
2019-04-26 10:00:22 -07:00
|
|
|
if (!face.armour) {
|
rewrite FaceGenManager and rename it to 'FaceParts'
FaceParts improvements relative to FaceGenManager:
- Random face generation (part selection) is separated from display.
- Individual parts can be set manually with the remaining components
randomised. Part selection should be stable for a given seed, so
fixing one component and regenerating with the same seed should not
change the other components.
- Somewhat shorter, simpler code.
- The number of parts provided for males and females no longer has
to match.
- Any individual part image can be tied to some arbitrary combination
of species, races and genders (e.g., you could have some clothing
or some accessories [eg, tattoos] that are tied to a particular gender
or tied to a particular race/gender combination, etc, and other
items that can be used by any race and gender)
FaceParts also gets rid of the face backgrounds, because they're not
really necessary, the only backgrounds we currently have are ugly, and
it didn't make much sense to me that backgrounds are tied to particular
species (they should be tied to ships & stations, I think)
2014-09-14 07:30:56 -07:00
|
|
|
_blit_image(faceIm, _get_part(s_partdb->accessories, selector, face.accessories), 0, 0);
|
|
|
|
_blit_image(faceIm, _get_part(s_partdb->hairstyles, selector, face.hairstyle), 0, 0);
|
|
|
|
} else {
|
|
|
|
_blit_image(faceIm, _get_part(s_partdb->armour, selector, face.armour), 0, 0);
|
|
|
|
}
|
|
|
|
}
|