From 26e43bbcfd3b9cc0f82d2060b6d708bb013202b6 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Fri, 21 May 2021 13:30:57 -0700 Subject: [PATCH] ui: Include required interface data files in executable --- build.sh | 8 +-- ...ontroller-mask.png => controller_mask.png} | Bin data/{logo-sdf.png => logo_sdf.png} | Bin data/meson.build | 21 ++++++ data/{Roboto-Medium.ttf => roboto_medium.ttf} | Bin meson.build | 3 + scripts/pack-file.py | 61 ++++++++++++++++++ ui/xemu-custom-widgets.c | 8 ++- ui/xemu-hud.cc | 12 +++- ui/xemu-shaders.c | 25 ++++++- ui/xemu-shaders.h | 1 + ui/xemu.c | 4 +- 12 files changed, 129 insertions(+), 14 deletions(-) rename data/{controller-mask.png => controller_mask.png} (100%) rename data/{logo-sdf.png => logo_sdf.png} (100%) create mode 100644 data/meson.build rename data/{Roboto-Medium.ttf => roboto_medium.ttf} (100%) create mode 100755 scripts/pack-file.py diff --git a/build.sh b/build.sh index 41a05e80f0..e35d8494e9 100755 --- a/build.sh +++ b/build.sh @@ -11,7 +11,7 @@ package_windows() { mkdir -p dist cp build/qemu-system-i386.exe dist/xemu.exe cp build/qemu-system-i386w.exe dist/xemuw.exe - cp -r "${project_source_dir}/data" dist/ + # cp -r "${project_source_dir}/data" dist/ python3 "${project_source_dir}/get_deps.py" dist/xemu.exe dist strip dist/xemu.exe strip dist/xemuw.exe @@ -23,7 +23,7 @@ package_wincross() { mkdir -p dist cp build/qemu-system-i386.exe dist/xemu.exe cp build/qemu-system-i386w.exe dist/xemuw.exe - cp -r "${project_source_dir}/data" dist/ + # cp -r "${project_source_dir}/data" dist/ $STRIP dist/xemu.exe $STRIP dist/xemuw.exe } @@ -46,7 +46,7 @@ package_macos() { # Copy in runtime resources mkdir -p dist/xemu.app/Contents/Resources - cp -r "${project_source_dir}/data" dist/xemu.app/Contents/Resources + # cp -r "${project_source_dir}/data" dist/xemu.app/Contents/Resources # Generate icon file mkdir -p xemu.iconset @@ -96,7 +96,7 @@ package_linux() { rm -rf dist mkdir -p dist cp build/qemu-system-i386 dist/xemu - cp -r "${project_source_dir}/data" dist + # cp -r "${project_source_dir}/data" dist } postbuild='' diff --git a/data/controller-mask.png b/data/controller_mask.png similarity index 100% rename from data/controller-mask.png rename to data/controller_mask.png diff --git a/data/logo-sdf.png b/data/logo_sdf.png similarity index 100% rename from data/logo-sdf.png rename to data/logo_sdf.png diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 0000000000..785e335a40 --- /dev/null +++ b/data/meson.build @@ -0,0 +1,21 @@ +pfiles = [ + 'controller_mask.png', + 'logo_sdf.png', + 'xemu_64x64.png', + 'roboto_medium.ttf', +] + +libpfile_targets = [] + +foreach e : pfiles + t = custom_target('@0@.[ch]'.format(e), + output: ['@0@.c'.format(e), '@0@.h'.format(e)], + input: files('@0@'.format(e)), + command: [packfile, '@INPUT@', '@OUTPUT0@', '@OUTPUT1@']) + libpfile_targets += t[0] + genh += t[1] +endforeach + +libpfile = static_library('pdata', libpfile_targets, + name_suffix: 'fa') +common_ss.add(declare_dependency(link_whole: libpfile)) diff --git a/data/Roboto-Medium.ttf b/data/roboto_medium.ttf similarity index 100% rename from data/Roboto-Medium.ttf rename to data/roboto_medium.ttf diff --git a/meson.build b/meson.build index ddf6d711eb..f428487cd3 100644 --- a/meson.build +++ b/meson.build @@ -1687,6 +1687,8 @@ qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py', meson.source_root() / 'scripts/qapi-gen.py' ] +packfile = find_program('scripts/pack-file.py') + tracetool = [ python, files('scripts/tracetool.py'), '--backend=' + config_host['TRACE_BACKENDS'] @@ -1896,6 +1898,7 @@ subdir('qom') subdir('authz') subdir('crypto') subdir('ui') +subdir('data') if enable_modules diff --git a/scripts/pack-file.py b/scripts/pack-file.py new file mode 100755 index 0000000000..71be308d13 --- /dev/null +++ b/scripts/pack-file.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +import argparse +import sys +from io import StringIO +from typing import Union, TextIO +import os.path + +def encode_bytes(data: Union[bytes, bytearray], outfile: TextIO): + """ + Encode data as a string of C-style escape sequences + """ + for i,v in enumerate(data): + if i % 16 == 0: + outfile.write('\t"') + outfile.write('\\x%02x' % v) + if i % 16 == 15: + outfile.write('"\n') + if i % 16 != 15: + outfile.write('"') + +def encode_bytes_str(data: Union[bytes, bytearray]): + outfile = StringIO() + encode_bytes(data, outfile) + outfile.seek(0) + return outfile.read() + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('path') + ap.add_argument('cout') + ap.add_argument('hout') + args = ap.parse_args() + data = bytearray(open(args.path, 'rb').read()) + fname, _ = os.path.splitext(os.path.basename(args.path)) + ident = ''.join([c if c.isalnum() else '_' for c in fname]) + + with open(args.hout, 'w') as f: + f.write( +f'''\ +#ifndef DATA_{ident.upper()}_H +#define DATA_{ident.upper()}_H + +extern const unsigned int {ident}_size; +extern const unsigned char {ident}_data[]; + +#endif +''' + ) + + with open(args.cout, 'w') as f: + f.write( +f'''\ +const unsigned int {ident}_size = {len(data)}; +const unsigned char {ident}_data[] = +{encode_bytes_str(data)}; +''' + ) + +if __name__ == '__main__': + main() diff --git a/ui/xemu-custom-widgets.c b/ui/xemu-custom-widgets.c index 360fab5450..f31b4c5d12 100644 --- a/ui/xemu-custom-widgets.c +++ b/ui/xemu-custom-widgets.c @@ -24,7 +24,9 @@ #include "xemu-shaders.h" #include "xemu-custom-widgets.h" -#include "xemu-data.h" + +#include "data/controller_mask.png.h" +#include "data/logo_sdf.png.h" static struct decal_shader *s = NULL; static struct decal_shader *s_logo = NULL; @@ -67,9 +69,9 @@ void initialize_custom_ui_rendering(void) glGetIntegerv(GL_VIEWPORT, vp); glActiveTexture(GL_TEXTURE0); - g_ui_tex = load_texture_from_file(xemu_get_resource_path("controller-mask.png")); + g_ui_tex = load_texture_from_memory(controller_mask_data, controller_mask_size); s = create_decal_shader(SHADER_TYPE_MASK); - g_logo_tex = load_texture_from_file(xemu_get_resource_path("logo-sdf.png")); + g_logo_tex = load_texture_from_memory(logo_sdf_data, logo_sdf_size); s_logo = create_decal_shader(SHADER_TYPE_LOGO); controller_fbo = create_fbo(512, 512); logo_fbo = create_fbo(512, 512); diff --git a/ui/xemu-hud.cc b/ui/xemu-hud.cc index 3eb56ab1cf..1c9d19a85e 100644 --- a/ui/xemu-hud.cc +++ b/ui/xemu-hud.cc @@ -30,12 +30,13 @@ #include "xemu-custom-widgets.h" #include "xemu-monitor.h" #include "xemu-version.h" -#include "xemu-data.h" #include "xemu-net.h" #include "xemu-os-utils.h" #include "xemu-xbe.h" #include "xemu-reporting.h" +#include "data/roboto_medium.ttf.h" + #include "imgui/imgui.h" #include "imgui/backends/imgui_impl_sdl.h" #include "imgui/backends/imgui_impl_opengl3.h" @@ -926,7 +927,7 @@ public: if (ImGui::Button("Help", ImVec2(120*g_ui_scale, 0))) { xemu_open_web_browser("https://github.com/mborgerson/xemu/wiki/Networking"); } - + ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)*g_ui_scale); ImGui::SetItemDefaultFocus(); @@ -1796,12 +1797,17 @@ static void InitializeStyle() ImGuiIO& io = ImGui::GetIO(); io.Fonts->Clear(); - io.Fonts->AddFontFromFileTTF(xemu_get_resource_path("Roboto-Medium.ttf"), 16*g_ui_scale); + + ImFontConfig roboto_font_cfg = ImFontConfig(); + roboto_font_cfg.FontDataOwnedByAtlas = false; + io.Fonts->AddFontFromMemoryTTF((void*)roboto_medium_data, roboto_medium_size, 16*g_ui_scale, &roboto_font_cfg); + ImFontConfig font_cfg = ImFontConfig(); font_cfg.OversampleH = font_cfg.OversampleV = 1; font_cfg.PixelSnapH = true; font_cfg.SizePixels = 13.0f*g_ui_scale; g_fixed_width_font = io.Fonts->AddFontDefault(&font_cfg); + ImGui_ImplOpenGL3_CreateFontsTexture(); ImGuiStyle style; diff --git a/ui/xemu-shaders.c b/ui/xemu-shaders.c index 7ef314ec5f..9f43d06e4a 100644 --- a/ui/xemu-shaders.c +++ b/ui/xemu-shaders.c @@ -185,7 +185,7 @@ struct decal_shader *create_decal_shader(enum SHADER_TYPE type) return s; } -GLuint load_texture_from_file(const char *name) +static GLuint load_texture(unsigned char *data, int width, int height, int channels) { GLuint tex; glGenTextures(1, &tex); @@ -196,7 +196,12 @@ GLuint load_texture_from_file(const char *name) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + return tex; +} +GLuint load_texture_from_file(const char *name) +{ // Flip vertically so textures are loaded according to GL convention. stbi_set_flip_vertically_on_load(1); @@ -205,8 +210,22 @@ GLuint load_texture_from_file(const char *name) unsigned char *data = stbi_load(name, &width, &height, &channels, 4); assert(data != NULL); - // Upload texture data - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + GLuint tex = load_texture(data, width, height, channels); + stbi_image_free(data); + + return tex; +} + +GLuint load_texture_from_memory(const unsigned char *buf, unsigned int size) +{ + // Flip vertically so textures are loaded according to GL convention. + stbi_set_flip_vertically_on_load(1); + + int width, height, channels = 0; + unsigned char *data = stbi_load_from_memory(buf, size, &width, &height, &channels, 4); + assert(data != NULL); + + GLuint tex = load_texture(data, width, height, channels); stbi_image_free(data); return tex; diff --git a/ui/xemu-shaders.h b/ui/xemu-shaders.h index 6909b0577a..37cf340a01 100644 --- a/ui/xemu-shaders.h +++ b/ui/xemu-shaders.h @@ -75,6 +75,7 @@ struct decal_shader *create_decal_shader(enum SHADER_TYPE type); void delete_decal_shader(struct decal_shader *s); GLuint load_texture_from_file(const char *name); +GLuint load_texture_from_memory(const unsigned char *buf, unsigned int size); struct fbo *create_fbo(int width, int height); void render_to_default_fb(void); diff --git a/ui/xemu.c b/ui/xemu.c index 4d4ef72b3e..c615c8dcee 100644 --- a/ui/xemu.c +++ b/ui/xemu.c @@ -49,6 +49,8 @@ #include "xemu-shaders.h" #include "xemu-version.h" +#include "data/xemu_64x64.png.h" + #include "hw/xbox/smbus.h" // For eject, drive tray #include "hw/xbox/nv2a/nv2a.h" @@ -860,7 +862,7 @@ static void sdl2_display_very_early_init(DisplayOptions *o) int width, height, channels = 0; stbi_set_flip_vertically_on_load(0); - unsigned char *icon_data = stbi_load("./data/xemu_64x64.png", &width, &height, &channels, 4); + unsigned char *icon_data = stbi_load_from_memory(xemu_64x64_data, xemu_64x64_size, &width, &height, &channels, 4); if (icon_data) { SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(icon_data, width, height, 32, width*4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);