mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[ion] Simulator: key layouts assets are PNG instead of JPG IV (fix linux)
This commit is contained in:
committed by
EmilieNumworks
parent
1946c68ef8
commit
165b129385
@@ -27,20 +27,20 @@ endif
|
||||
|
||||
LDFLAGS += -ljpeg
|
||||
|
||||
jpg_assets = background horizontal_arrow vertical_arrow round small_squircle large_squircle
|
||||
assets = background.jpg horizontal_arrow.png vertical_arrow.png round.png small_squircle.png large_squircle.png
|
||||
|
||||
jpg_images = $(foreach i,$(jpg_assets),ion/src/simulator/assets/$(i).jpg)
|
||||
assets_paths = $(foreach i,$(assets),ion/src/simulator/assets/$(i))
|
||||
|
||||
$(eval $(call rule_for, \
|
||||
LINUX_ASSETS, \
|
||||
ion/src/simulator/linux/assets.s, \
|
||||
$(jpg_images), \
|
||||
$$(PYTHON) ion/src/simulator/linux/assets.py --files $(jpg_assets) --implementation $$@, \
|
||||
$(assets_paths), \
|
||||
$$(PYTHON) ion/src/simulator/linux/assets.py --files $(assets) --implementation $$@, \
|
||||
global \
|
||||
))
|
||||
|
||||
assets_address_ranges_declaration = $(foreach i,$(jpg_assets),extern unsigned char _ion_simulator_$(i)_start;)
|
||||
assets_address_ranges_declaration += $(foreach i,$(jpg_assets),extern unsigned char _ion_simulator_$(i)_end;)
|
||||
assets_address_ranges_definition = $(foreach i,$(jpg_assets), {"$(i).jpg", &_ion_simulator_$(i)_start, &_ion_simulator_$(i)_end},)
|
||||
assets_address_ranges_declaration = $(foreach i,$(assets),extern unsigned char _ion_simulator_$(basename $(i))_start;)
|
||||
assets_address_ranges_declaration += $(foreach i,$(assets),extern unsigned char _ion_simulator_$(basename $(i))_end;)
|
||||
assets_address_ranges_definition = $(foreach i,$(assets), {"$(i)", &_ion_simulator_$(basename $(i))_start, &_ion_simulator_$(basename $(i))_end},)
|
||||
|
||||
$(call object_for,ion/src/simulator/linux/images.cpp): CXXFLAGS += -DASSETS_ADDRESS_RANGES_DECLARATION='$(assets_address_ranges_declaration)' -DASSETS_ADDRESS_RANGES_DEFINITION='$(assets_address_ranges_definition)'
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
# This script generates a .s file representing jpg assets in order to access
|
||||
# This script generates a .s file representing assets in order to access
|
||||
# them from C code
|
||||
|
||||
import sys
|
||||
import re
|
||||
import argparse
|
||||
import io
|
||||
import os
|
||||
|
||||
parser = argparse.ArgumentParser(description="Process some jpg files.")
|
||||
parser.add_argument('--files', nargs='+', help='a list of jpg file names')
|
||||
parser = argparse.ArgumentParser(description="Process some asset files.")
|
||||
parser.add_argument('--files', nargs='+', help='a list of file names')
|
||||
parser.add_argument('--implementation', help='the .s file to generate')
|
||||
args = parser.parse_args()
|
||||
|
||||
def print_jpg(f, jpg):
|
||||
f.write(".global _ion_simulator_" + jpg + "_start\n")
|
||||
f.write(".global _ion_simulator_" + jpg + "_end\n")
|
||||
f.write("_ion_simulator_" + jpg + "_start:\n")
|
||||
f.write(" .incbin \"ion/src/simulator/assets/" + jpg + ".jpg\"\n")
|
||||
f.write("_ion_simulator_" + jpg + "_end:\n\n")
|
||||
def print_asset(f, asset):
|
||||
asset_basename = os.path.splitext(asset)[0]
|
||||
f.write(".global _ion_simulator_" + asset_basename + "_start\n")
|
||||
f.write(".global _ion_simulator_" + asset_basename + "_end\n")
|
||||
f.write("_ion_simulator_" + asset_basename + "_start:\n")
|
||||
f.write(" .incbin \"ion/src/simulator/assets/" + asset + "\"\n")
|
||||
f.write("_ion_simulator_" + asset_basename + "_end:\n\n")
|
||||
|
||||
def print(files, path):
|
||||
f = open(path, "w")
|
||||
for jpg in files:
|
||||
print_jpg(f, jpg)
|
||||
for asset in files:
|
||||
print_asset(f, asset)
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL.h>
|
||||
#include <jpeglib.h>
|
||||
#include <png.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef ASSETS_ADDRESS_RANGES_DECLARATION
|
||||
@@ -17,66 +18,152 @@ static struct {
|
||||
ASSETS_ADDRESS_RANGES_DEFINITION
|
||||
};
|
||||
|
||||
SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier, bool withTransparency, uint8_t alpha) {
|
||||
enum class AssetFormat {
|
||||
JPG,
|
||||
PNG
|
||||
};
|
||||
|
||||
png_size_t readSize = 0;
|
||||
|
||||
void ReadDataFromMemory(png_structp png, png_bytep outBytes, png_size_t byteSize) {
|
||||
png_voidp io = png_get_io_ptr(png);
|
||||
memcpy((char *)outBytes, (char *)io + readSize, byteSize);
|
||||
readSize += byteSize;
|
||||
}
|
||||
|
||||
bool readPNG(unsigned char * start, size_t size, unsigned char ** bitmapData, unsigned int * width, unsigned int * height, unsigned int * bytesPerPixel, Uint32 * pixelFormat) {
|
||||
readSize = 0;
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png) { return false; } // Memory failure
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (!info) {
|
||||
// Memory failure
|
||||
png_destroy_read_struct(&png, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
static constexpr size_t k_pngSignatureLength = 8;
|
||||
if(png_sig_cmp((png_const_bytep)start, 0, k_pngSignatureLength) != 0) { return false; } // Corrupted PNG
|
||||
|
||||
png_set_read_fn(png, start, ReadDataFromMemory);
|
||||
|
||||
png_read_info(png, info);
|
||||
|
||||
int bitDepth = 0;
|
||||
int colorType = -1;
|
||||
png_get_IHDR(png, info, width, height, &bitDepth, &colorType, nullptr, nullptr, nullptr);
|
||||
*bytesPerPixel = bitDepth*4/8;
|
||||
|
||||
*pixelFormat = SDL_PIXELFORMAT_ARGB8888;
|
||||
assert(colorType == PNG_COLOR_TYPE_RGB_ALPHA);
|
||||
|
||||
const png_uint_32 bytesPerRow = png_get_rowbytes(png, info);
|
||||
*bitmapData = new unsigned char[*height * bytesPerRow];
|
||||
unsigned char * rowData = *bitmapData;
|
||||
// read single row at a time
|
||||
for(unsigned int rowIndex = 0; rowIndex < *height; rowIndex++) {
|
||||
png_read_row(png, (png_bytep)rowData, nullptr);
|
||||
rowData += bytesPerRow;
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png, &info, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readJPG(const unsigned char * start, size_t size, unsigned char ** bitmapData, unsigned int * width, unsigned int * height, unsigned int * bytesPerPixel, Uint32 * pixelFormat) {
|
||||
*pixelFormat = SDL_PIXELFORMAT_RGB24;
|
||||
struct jpeg_decompress_struct info;
|
||||
struct jpeg_error_mgr err;
|
||||
info.err = jpeg_std_error(&err);
|
||||
|
||||
jpeg_create_decompress(&info);
|
||||
|
||||
unsigned char * jpegStart = nullptr;
|
||||
unsigned long jpegSize = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(resources_addresses)/sizeof(resources_addresses[0]); i++) {
|
||||
if (strcmp(identifier, resources_addresses[i].identifier) == 0) {
|
||||
jpegStart = resources_addresses[i].start;
|
||||
jpegSize = resources_addresses[i].end - resources_addresses[i].start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(jpegStart);
|
||||
jpeg_mem_src(&info, jpegStart, jpegSize);
|
||||
jpeg_mem_src(&info, start, size);
|
||||
|
||||
if (jpeg_read_header(&info, TRUE) != 1) {
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
jpeg_start_decompress(&info);
|
||||
|
||||
int width = info.output_width;
|
||||
int height = info.output_height;
|
||||
int bytesPerPixel = info.output_components;
|
||||
int bitsPerPixel = bytesPerPixel*8;
|
||||
|
||||
unsigned char * bitmapData = new unsigned char[height * width * bytesPerPixel];
|
||||
*width = info.output_width;
|
||||
*height = info.output_height;
|
||||
*bytesPerPixel = info.output_components;
|
||||
*bitmapData = new unsigned char[*height * *width * *bytesPerPixel];
|
||||
|
||||
while (info.output_scanline < info.output_height) {
|
||||
unsigned char * buffer_array[1];
|
||||
buffer_array[0] = bitmapData + info.output_scanline * width * bytesPerPixel;
|
||||
buffer_array[0] = *bitmapData + info.output_scanline * *width * *bytesPerPixel;
|
||||
jpeg_read_scanlines(&info, buffer_array, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&info);
|
||||
jpeg_destroy_decompress(&info);
|
||||
return true;
|
||||
}
|
||||
|
||||
Uint32 surfacePixelFormat = SDL_PIXELFORMAT_RGB24;
|
||||
assert(bytesPerPixel == SDL_BYTESPERPIXEL(surfacePixelFormat));
|
||||
SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier) {
|
||||
static constexpr const char * jpgExtension = ".jpg";
|
||||
static constexpr const char * pngExtension = ".png";
|
||||
|
||||
SDL_Surface * surface = SDL_CreateRGBSurfaceWithFormatFrom(
|
||||
bitmapData,
|
||||
width,
|
||||
height,
|
||||
bitsPerPixel,
|
||||
width * bytesPerPixel,
|
||||
surfacePixelFormat);
|
||||
unsigned char * assetStart = nullptr;
|
||||
unsigned long assertSize = 0;
|
||||
AssetFormat format;
|
||||
|
||||
SDL_SetColorKey(surface, withTransparency, SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF));
|
||||
SDL_SetSurfaceAlphaMod(surface, alpha);
|
||||
// Find the asset corresponding to identifier
|
||||
for (size_t i = 0; i < sizeof(resources_addresses)/sizeof(resources_addresses[0]); i++) {
|
||||
if (strcmp(identifier, resources_addresses[i].identifier) == 0) {
|
||||
if (strcmp(jpgExtension, identifier + strlen(identifier) - strlen(jpgExtension)) == 0) {
|
||||
format = AssetFormat::JPG;
|
||||
} else {
|
||||
assert(strcmp(pngExtension, identifier + strlen(identifier) - strlen(pngExtension)) == 0);
|
||||
format = AssetFormat::PNG;
|
||||
}
|
||||
assetStart = resources_addresses[i].start;
|
||||
assertSize = resources_addresses[i].end - resources_addresses[i].start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(assetStart);
|
||||
|
||||
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytesPerPixel;
|
||||
unsigned char * bitmapData;
|
||||
Uint32 pixelFormat;
|
||||
|
||||
switch (format) {
|
||||
case AssetFormat::JPG:
|
||||
if (!readJPG(assetStart, assertSize, &bitmapData, &width, &height, &bytesPerPixel, &pixelFormat)) {
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(format == AssetFormat::PNG);
|
||||
if (!readPNG(assetStart, assertSize, &bitmapData, &width, &height, &bytesPerPixel, &pixelFormat)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
assert(bytesPerPixel == SDL_BYTESPERPIXEL(pixelFormat));
|
||||
|
||||
SDL_Texture * texture = SDL_CreateTexture(
|
||||
renderer,
|
||||
pixelFormat,
|
||||
SDL_TEXTUREACCESS_STATIC,
|
||||
width,
|
||||
height
|
||||
);
|
||||
|
||||
SDL_UpdateTexture(
|
||||
texture,
|
||||
nullptr,
|
||||
bitmapData,
|
||||
width * bytesPerPixel
|
||||
);
|
||||
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
delete[] bitmapData;
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user