Browse Source

cmake: convert bmp images to c headers using python script

A pure CMake script was too slow
Anonymous Maarten 1 year ago
parent
commit
80da0cf06d
2 changed files with 76 additions and 1 deletions
  1. 37 0
      cmake/xxd.py
  2. 39 1
      test/CMakeLists.txt

+ 37 - 0
cmake/xxd.py

@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+import argparse
+import os
+import pathlib
+import re
+
+def main():
+    parser = argparse.ArgumentParser(allow_abbrev=False, description="Convert file into includable C header")
+    parser.add_argument("--in", "-i", type=pathlib.Path, metavar="INPUT", dest="input", required=True, help="Input file")
+    parser.add_argument("--out", "-o", type=pathlib.Path, metavar="OUTPUT", dest="output", required=True, help="Output header")
+    parser.add_argument("--columns", type=int, default=12, help="Column count")
+    args = parser.parse_args()
+
+    t = pathlib.Path()
+    varname, _ = re.subn("[^a-zA-Z0-9]", "_", str(args.input.name))
+
+    binary_data = args.input.open("rb").read()
+
+    with open(args.output, "w") as fout:
+        fout.write("unsigned char {}[] = {{\n".format(varname))
+        bytes_written = 0
+        while bytes_written < len(binary_data):
+            col = bytes_written % args.columns
+            if col == 0:
+                fout.write("  ")
+            column_data = binary_data[bytes_written:bytes_written+args.columns]
+            fout.write(", ".join("0x{:02x}".format(d) for d in column_data))
+            bytes_written += len(column_data)
+            if bytes_written < len(binary_data):
+                fout.write(",\n")
+            else:
+                fout.write("\n")
+        fout.write("}};\nunsigned int {}_len = {:d};\n".format(varname, len(binary_data)))
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 39 - 1
test/CMakeLists.txt

@@ -208,8 +208,46 @@ if(SDL3_TESTS_SUBPROJECT)
     endforeach()
 endif()
 
+set(gamepad_images
+    gamepad_axis_arrow.bmp
+    gamepad_axis.bmp
+    gamepad_back.bmp
+    gamepad_battery_empty.bmp
+    gamepad_battery_full.bmp
+    gamepad_battery_low.bmp
+    gamepad_battery_medium.bmp
+    gamepad_battery_unknown.bmp
+    gamepad_battery_wired.bmp
+    gamepad_button_background.bmp
+    gamepad_button.bmp
+    gamepad_button_small.bmp
+    gamepad_face_abxy.bmp
+    gamepad_face_bayx.bmp
+    gamepad_face_sony.bmp
+    gamepad_front.bmp
+    gamepad_touchpad.bmp
+)
+set(gamepad_image_headers)
+find_package(PythonInterp)
+if(PYTHONINTERP_FOUND AND NOT PYTHON_VERSION_STRING VERSION_LESS "3.2")
+    set(xxd "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/xxd.py")
+    foreach(bmp ${gamepad_images})
+        get_filename_component(bmp_we "${bmp}" NAME_WE)
+        set(intermediate "${CMAKE_CURRENT_BINARY_DIR}/${bmp_we}.h")
+        set(final "${CMAKE_CURRENT_SOURCE_DIR}/${bmp_we}.h")
+        # Don't add the 'final' headers to the output, to avoid marking them as GENERATED
+        # (generated files are removed when running the CLEAN target)
+        add_custom_command(OUTPUT "${intermediate}"
+            COMMAND "${PYTHON_EXECUTABLE}" "${xxd}" -i "${CMAKE_CURRENT_SOURCE_DIR}/${bmp}" "-o" "${intermediate}"
+            COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${intermediate}" "${final}"
+            DEPENDS "${xxd}" "${bmp}"
+        )
+        list(APPEND gamepad_image_headers "${intermediate}" "${final}")
+    endforeach()
+endif()
+
 add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c)
-add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c)
+add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers})
 add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c)
 add_sdl_test_executable(testgl SOURCES testgl.c)
 add_sdl_test_executable(testgles SOURCES testgles.c)