add encode/decode options for bitmap fonts
This commit is contained in:
+1
-1
@@ -84,8 +84,8 @@ set(SOURCES
|
|||||||
src/FileContentsCache.cc
|
src/FileContentsCache.cc
|
||||||
src/FunctionCompiler.cc
|
src/FunctionCompiler.cc
|
||||||
src/GSLArchive.cc
|
src/GSLArchive.cc
|
||||||
src/GVMEncoder.cc
|
|
||||||
src/HTTPServer.cc
|
src/HTTPServer.cc
|
||||||
|
src/ImageEncoder.cc
|
||||||
src/IntegralExpression.cc
|
src/IntegralExpression.cc
|
||||||
src/IPFrameInfo.cc
|
src/IPFrameInfo.cc
|
||||||
src/IPStackSimulator.cc
|
src/IPStackSimulator.cc
|
||||||
|
|||||||
@@ -740,10 +740,11 @@ The data formats that newserv can convert to/from are:
|
|||||||
| PSO GC snapshot file | None | `decode-gci-snapshot` |
|
| PSO GC snapshot file | None | `decode-gci-snapshot` |
|
||||||
| Quest script (.bin) | `assemble-quest-script` | `disassemble-quest-script` |
|
| Quest script (.bin) | `assemble-quest-script` | `disassemble-quest-script` |
|
||||||
| Quest map (.dat) | None | `disassemble-quest-map` |
|
| Quest map (.dat) | None | `disassemble-quest-map` |
|
||||||
| AFS archive | None | `extract-afs` |
|
| AFS archive (.afs) | None | `extract-afs` |
|
||||||
| BML archive | None | `extract-bml` |
|
| BML archive (.bml) | None | `extract-bml` |
|
||||||
| GSL archive | `generate-gsl` | `extract-gsl` |
|
| GSL archive (.gsl) | `generate-gsl` | `extract-gsl` |
|
||||||
| GVM texture | `encode-gvm` | None |
|
| GVM texture (.gvm) | `encode-gvm` | None |
|
||||||
|
| Bitmap font (.fon) | `encode-bitmap-font` | `decode-bitmap-font` |
|
||||||
| Text archive | `encode-text-archive` | `decode-text-archive` |
|
| Text archive | `encode-text-archive` | `decode-text-archive` |
|
||||||
| Unicode text set | `encode-unicode-text-set` | `decode-unicode-text-set` |
|
| Unicode text set | `encode-unicode-text-set` | `decode-unicode-text-set` |
|
||||||
| Word Select data set | None | `decode-word-select-set` |
|
| Word Select data set | None | `decode-word-select-set` |
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "GVMEncoder.hh"
|
#include "ImageEncoder.hh"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <phosg/Encoding.hh>
|
#include <phosg/Encoding.hh>
|
||||||
#include <phosg/Image.hh>
|
#include <phosg/Image.hh>
|
||||||
#include <phosg/Strings.hh>
|
#include <phosg/Strings.hh>
|
||||||
@@ -34,7 +35,7 @@ struct GVRHeader {
|
|||||||
be_uint16_t height;
|
be_uint16_t height;
|
||||||
} __packed_ws__(GVRHeader, 0x10);
|
} __packed_ws__(GVRHeader, 0x10);
|
||||||
|
|
||||||
string encode_gvm(const phosg::Image& img, GVRDataFormat data_format, const std::string& internal_name, uint32_t global_index) {
|
string encode_gvm(const phosg::Image& img, GVRDataFormat data_format, const string& internal_name, uint32_t global_index) {
|
||||||
int8_t dimensions_field = -2;
|
int8_t dimensions_field = -2;
|
||||||
{
|
{
|
||||||
size_t h = img.get_height();
|
size_t h = img.get_height();
|
||||||
@@ -111,3 +112,48 @@ string encode_gvm(const phosg::Image& img, GVRDataFormat data_format, const std:
|
|||||||
|
|
||||||
return std::move(w.str());
|
return std::move(w.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const array<uint32_t, 4> fon_colors = {0x000000FF, 0x555555FF, 0xAAAAAAFF, 0xFFFFFFFF};
|
||||||
|
|
||||||
|
phosg::Image decode_fon(const string& data, size_t width) {
|
||||||
|
size_t num_pixels = data.size() * 4;
|
||||||
|
size_t height = num_pixels / width;
|
||||||
|
phosg::Image ret(width, height);
|
||||||
|
|
||||||
|
phosg::BitReader r(data);
|
||||||
|
for (size_t y = 0; y < height; y++) {
|
||||||
|
for (size_t x = 0; x < width; x++) {
|
||||||
|
ret.write_pixel(x, y, fon_colors[r.read(2)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t uabs(size_t a, size_t b) {
|
||||||
|
return (a > b) ? (a - b) : (b - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
string encode_fon(const phosg::Image& img) {
|
||||||
|
phosg::BitWriter w;
|
||||||
|
for (size_t y = 0; y < img.get_height(); y++) {
|
||||||
|
for (size_t x = 0; x < img.get_width(); x++) {
|
||||||
|
uint32_t color = img.read_pixel(x, y);
|
||||||
|
|
||||||
|
size_t result_delta = 0x400;
|
||||||
|
size_t result_index = 0;
|
||||||
|
for (size_t z = 0; z < 4; z++) {
|
||||||
|
size_t delta = uabs((fon_colors[z] >> 24) & 0xFF, (color >> 24) & 0xFF) +
|
||||||
|
uabs((fon_colors[z] >> 16) & 0xFF, (color >> 16) & 0xFF) +
|
||||||
|
uabs((fon_colors[z] >> 8) & 0xFF, (color >> 8) & 0xFF) +
|
||||||
|
uabs(fon_colors[z] & 0xFF, color & 0xFF);
|
||||||
|
if (delta < result_delta) {
|
||||||
|
result_delta = delta;
|
||||||
|
result_index = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.write(result_index & 2);
|
||||||
|
w.write(result_index & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w.str();
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ enum class GVRDataFormat : uint8_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string encode_gvm(const phosg::Image& img, GVRDataFormat data_format, const std::string& internal_name, uint32_t global_index);
|
std::string encode_gvm(const phosg::Image& img, GVRDataFormat data_format, const std::string& internal_name, uint32_t global_index);
|
||||||
|
phosg::Image decode_fon(const std::string& data, size_t width);
|
||||||
|
std::string encode_fon(const phosg::Image& img);
|
||||||
|
|
||||||
constexpr uint16_t encode_rgb565(uint8_t r, uint8_t g, uint8_t b) {
|
constexpr uint16_t encode_rgb565(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
return ((r << 8) & 0xF800) | ((g << 3) & 0x07E0) | ((b >> 3) & 0x001F);
|
return ((r << 8) & 0xF800) | ((g << 3) & 0x07E0) | ((b >> 3) & 0x001F);
|
||||||
+31
-1
@@ -29,9 +29,9 @@
|
|||||||
#include "DNSServer.hh"
|
#include "DNSServer.hh"
|
||||||
#include "DownloadSession.hh"
|
#include "DownloadSession.hh"
|
||||||
#include "GSLArchive.hh"
|
#include "GSLArchive.hh"
|
||||||
#include "GVMEncoder.hh"
|
|
||||||
#include "HTTPServer.hh"
|
#include "HTTPServer.hh"
|
||||||
#include "IPStackSimulator.hh"
|
#include "IPStackSimulator.hh"
|
||||||
|
#include "ImageEncoder.hh"
|
||||||
#include "Loggers.hh"
|
#include "Loggers.hh"
|
||||||
#include "NetworkAddresses.hh"
|
#include "NetworkAddresses.hh"
|
||||||
#include "PSOGCObjectGraph.hh"
|
#include "PSOGCObjectGraph.hh"
|
||||||
@@ -1120,6 +1120,36 @@ Action a_encode_gvm(
|
|||||||
write_output_data(args, encoded.data(), encoded.size(), "gvm");
|
write_output_data(args, encoded.data(), encoded.size(), "gvm");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Action a_decode_bitmap_font(
|
||||||
|
"decode-bitmap-font", "\
|
||||||
|
decode-bitmap-font --width=WIDTH [INPUT-FILENAME [OUTPUT-FILENAME]]\n\
|
||||||
|
Decode a 2-bit bitmap font file (.fon) into a BMP image. The --width\n\
|
||||||
|
option is required; if the output looks wrong, try increasing or\n\
|
||||||
|
decreasing this number. For S18all04.fon, the width should be 20.\n",
|
||||||
|
+[](phosg::Arguments& args) {
|
||||||
|
std::string data = read_input_data(args);
|
||||||
|
size_t width = args.get<size_t>("width");
|
||||||
|
std::string bmp_data = decode_fon(data, width).save(phosg::Image::Format::WINDOWS_BITMAP);
|
||||||
|
write_output_data(args, bmp_data.data(), bmp_data.size(), "bmp");
|
||||||
|
});
|
||||||
|
Action a_encode_bitmap_font(
|
||||||
|
"encode-bitmap-font", "\
|
||||||
|
encode-bitmap-font [INPUT-FILENAME [OUTPUT-FILENAME]]\n\
|
||||||
|
Encode an image in BMP or PPM/PNM format into a bitmap font file for use\n\
|
||||||
|
with the console PSO versions. The image dimensions must match the\n\
|
||||||
|
original fon\'s dimensions.\n",
|
||||||
|
+[](phosg::Arguments& args) {
|
||||||
|
const string& input_filename = args.get<string>(1, false);
|
||||||
|
phosg::Image img;
|
||||||
|
if (!input_filename.empty() && (input_filename != "-")) {
|
||||||
|
img = phosg::Image(input_filename);
|
||||||
|
} else {
|
||||||
|
img = phosg::Image(stdin);
|
||||||
|
}
|
||||||
|
string encoded = encode_fon(img);
|
||||||
|
write_output_data(args, encoded.data(), encoded.size(), "fon");
|
||||||
|
});
|
||||||
|
|
||||||
Action a_salvage_gci(
|
Action a_salvage_gci(
|
||||||
"salvage-gci", "\
|
"salvage-gci", "\
|
||||||
salvage-gci INPUT-FILENAME [--round2] [CRYPT-OPTION] [--bytes=SIZE]\n\
|
salvage-gci INPUT-FILENAME [--round2] [CRYPT-OPTION] [--bytes=SIZE]\n\
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "ChatCommands.hh"
|
#include "ChatCommands.hh"
|
||||||
#include "Compression.hh"
|
#include "Compression.hh"
|
||||||
#include "GVMEncoder.hh"
|
#include "ImageEncoder.hh"
|
||||||
#include "Loggers.hh"
|
#include "Loggers.hh"
|
||||||
#include "PSOProtocol.hh"
|
#include "PSOProtocol.hh"
|
||||||
#include "ReceiveCommands.hh"
|
#include "ReceiveCommands.hh"
|
||||||
|
|||||||
+1
-1
@@ -11,8 +11,8 @@
|
|||||||
#include "Compression.hh"
|
#include "Compression.hh"
|
||||||
#include "EventUtils.hh"
|
#include "EventUtils.hh"
|
||||||
#include "FileContentsCache.hh"
|
#include "FileContentsCache.hh"
|
||||||
#include "GVMEncoder.hh"
|
|
||||||
#include "IPStackSimulator.hh"
|
#include "IPStackSimulator.hh"
|
||||||
|
#include "ImageEncoder.hh"
|
||||||
#include "Loggers.hh"
|
#include "Loggers.hh"
|
||||||
#include "NetworkAddresses.hh"
|
#include "NetworkAddresses.hh"
|
||||||
#include "SendCommands.hh"
|
#include "SendCommands.hh"
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
#include <phosg/Random.hh>
|
#include <phosg/Random.hh>
|
||||||
|
|
||||||
#include "BattleParamsIndex.hh"
|
#include "BattleParamsIndex.hh"
|
||||||
#include "GVMEncoder.hh"
|
#include "ImageEncoder.hh"
|
||||||
#include "ItemData.hh"
|
#include "ItemData.hh"
|
||||||
#include "Loggers.hh"
|
#include "Loggers.hh"
|
||||||
#include "StaticGameData.hh"
|
#include "StaticGameData.hh"
|
||||||
|
|||||||
Reference in New Issue
Block a user