mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Modify atlas generator to output binary metadata
This commit is contained in:
parent
b1e83df521
commit
db24b5ac39
@ -1,5 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#define ATLAS_MAGIC ('A' + ('T' << 8) + ('L' << 16) | ('A' << 24))
|
||||
|
||||
// Metadata file structure v0:
|
||||
//
|
||||
// AtlasHeader
|
||||
// For each image:
|
||||
// AtlasImage
|
||||
// For each font:
|
||||
// AtlasFontHeader
|
||||
// For each range:
|
||||
// AtlasRange
|
||||
// For each char:
|
||||
// AtlasChar
|
||||
|
||||
typedef int ImageID;
|
||||
|
||||
struct AtlasChar {
|
||||
@ -19,6 +33,15 @@ struct AtlasCharRange {
|
||||
int start_index;
|
||||
};
|
||||
|
||||
struct AtlasFontHeader {
|
||||
float padding;
|
||||
float height;
|
||||
float ascend;
|
||||
float distslope;
|
||||
int numRanges;
|
||||
int numChars;
|
||||
};
|
||||
|
||||
struct AtlasFont {
|
||||
float padding;
|
||||
float height;
|
||||
@ -39,6 +62,19 @@ struct AtlasImage {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct AtlasImage2 {
|
||||
float u1, v1, u2, v2;
|
||||
int w, h;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
struct AtlasHeader {
|
||||
int magic;
|
||||
int version;
|
||||
int numFonts;
|
||||
int numImages;
|
||||
};
|
||||
|
||||
struct Atlas {
|
||||
const char *filename;
|
||||
const AtlasFont **fonts;
|
||||
|
@ -620,6 +620,58 @@ struct FontDesc {
|
||||
void OutputHeader(FILE *fil, int index) {
|
||||
fprintf(fil, "#define %s %i\n", name.c_str(), index);
|
||||
}
|
||||
|
||||
AtlasFontHeader GetHeader() {
|
||||
int numChars = 0;
|
||||
for (size_t r = 0; r < ranges.size(); r++) {
|
||||
numChars += ranges[r].end - ranges[r].start;
|
||||
}
|
||||
AtlasFontHeader header;
|
||||
header.padding = height - ascend - descend;
|
||||
header.height = ascend + descend;
|
||||
header.ascend = ascend;
|
||||
header.distslope = distmult / 256.0;
|
||||
header.numChars = numChars;
|
||||
header.numRanges = (int)ranges.size();
|
||||
return header;
|
||||
}
|
||||
|
||||
vector<AtlasCharRange> GetRanges() {
|
||||
int start_index = 0;
|
||||
vector<AtlasCharRange> out_ranges;
|
||||
for (size_t r = 0; r < ranges.size(); r++) {
|
||||
int first_char_id = ranges[r].start;
|
||||
int last_char_id = ranges[r].end;
|
||||
start_index += last_char_id - first_char_id;
|
||||
AtlasCharRange range;
|
||||
range.start = first_char_id;
|
||||
range.end = last_char_id;
|
||||
range.start_index = start_index;
|
||||
out_ranges.push_back(range);
|
||||
}
|
||||
return out_ranges;
|
||||
}
|
||||
|
||||
vector<AtlasChar> GetChars(float tw, float th, const vector<Data> &results) {
|
||||
vector<AtlasChar> chars;
|
||||
for (size_t r = 0; r < ranges.size(); r++) {
|
||||
for (int i = ranges[r].start; i < ranges[r].end; i++) {
|
||||
int idx = i - ranges[r].start + ranges[r].start_index;
|
||||
AtlasChar c;
|
||||
c.sx = results[idx].sx / tw; // sx, sy, ex, ey
|
||||
c.sy = results[idx].sy / th;
|
||||
c.ex = results[idx].ex / tw;
|
||||
c.ey = results[idx].ey / th;
|
||||
c.ox = results[idx].ox; // ox, oy
|
||||
c.oy = results[idx].oy + results[idx].voffset;
|
||||
c.wx = results[idx].wx; //wx
|
||||
c.pw = results[idx].ex - results[idx].sx; // pw, ph
|
||||
c.ph = results[idx].ey - results[idx].sy;
|
||||
chars.push_back(c);
|
||||
}
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
};
|
||||
|
||||
struct ImageDesc {
|
||||
@ -627,6 +679,22 @@ struct ImageDesc {
|
||||
Effect effect;
|
||||
int result_index;
|
||||
|
||||
AtlasImage2 ToAtlasImage2(float tw, float th, const vector<Data> &results) {
|
||||
AtlasImage2 img;
|
||||
int i = result_index;
|
||||
float toffx = 0.5f / tw;
|
||||
float toffy = 0.5f / th;
|
||||
img.u1 = results[i].sx / tw + toffx;
|
||||
img.v1 = results[i].sy / th + toffy;
|
||||
img.u2 = results[i].ex / tw - toffx;
|
||||
img.v2 = results[i].ey / th - toffy;
|
||||
img.w = results[i].ex - results[i].sx;
|
||||
img.h = results[i].ey - results[i].sy;
|
||||
strncpy(img.name, name.c_str(), sizeof(img.name));
|
||||
img.name[sizeof(img.name) - 1] = 0;
|
||||
return img;
|
||||
}
|
||||
|
||||
void OutputSelf(FILE *fil, float tw, float th, const vector<Data> &results) {
|
||||
int i = result_index;
|
||||
float toffx = 0.5f / tw;
|
||||
@ -800,6 +868,7 @@ int main(int argc, char **argv) {
|
||||
printf("Reading script %s\n", argv[1]);
|
||||
const char *atlas_name = argv[2];
|
||||
string image_name = string(atlas_name) + "_atlas.zim";
|
||||
string meta_name = string(atlas_name) + "_atlas.meta";
|
||||
out_prefix = argv[2];
|
||||
|
||||
map<string, FontReferenceList> fontRefs;
|
||||
@ -895,6 +964,36 @@ int main(int argc, char **argv) {
|
||||
printf("Writing .ZIM %ix%i RGBA4444...\n", dest.width(), dest.height());
|
||||
dest.SaveZIM(image_name.c_str(), ZIM_RGBA4444 | ZIM_ZLIB_COMPRESSED);
|
||||
}
|
||||
|
||||
// Save all the metadata.
|
||||
{
|
||||
FILE *meta = fopen(meta_name.c_str(), "wb");
|
||||
AtlasHeader header;
|
||||
header.magic = ATLAS_MAGIC;
|
||||
header.version = 0;
|
||||
header.numFonts = (int)fonts.size();
|
||||
header.numImages = (int)images.size();
|
||||
fwrite(&header, 1, sizeof(header), meta);
|
||||
// For each image
|
||||
for (int i = 0; i < (int)images.size(); i++) {
|
||||
auto &image = images[i];
|
||||
AtlasImage2 atlas_image = image.ToAtlasImage2(dest.width(), dest.height(), results);
|
||||
fwrite(&atlas_image, 1, sizeof(atlas_image), meta);
|
||||
}
|
||||
// For each font
|
||||
for (int i = 0; i < (int)fonts.size(); i++) {
|
||||
auto &font = fonts[i];
|
||||
font.ComputeHeight(results, distmult);
|
||||
AtlasFontHeader font_header = font.GetHeader();
|
||||
fwrite(&font_header, 1, sizeof(font_header), meta);
|
||||
auto ranges = font.GetRanges();
|
||||
fwrite(ranges.data(), sizeof(AtlasCharRange), ranges.size(), meta);
|
||||
auto chars = font.GetChars(dest.width(), dest.height(), results);
|
||||
fwrite(chars.data(), sizeof(AtlasChar), chars.size(), meta);
|
||||
}
|
||||
fclose(meta);
|
||||
}
|
||||
|
||||
// Also save PNG for debugging.
|
||||
printf("Writing .PNG %s\n", (image_name + ".png").c_str());
|
||||
dest.SavePNG((image_name + ".png").c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user