Compare commits

...

32 Commits

Author SHA1 Message Date
Iain King-Speir
57f18833af Merge ed4eb8e1f7 into 7d1e88413f 2024-08-06 09:47:00 +00:00
Diomendius
ed4eb8e1f7 Use temporary staging dirs when building resources
This allows intermediate build artifacts to be cleaned up without
specifying them individually as BYPRODUCTS.

When building a data file <name>, all files are first built under
tmp/<name> before the target itself is moved from tmp/<name>/<name> to
Packaged/<name>.

add_house_file() could also be modified in this way, but it wouldn't
reduce the boilerplate by much, so it's probably not worth it.
2024-08-06 17:52:33 +12:00
Diomendius
c8e3e8683b Add deps in source tree to resource targets
This will make CMake rebuild resources if for instance the fonts are
updated.
2024-08-06 17:48:24 +12:00
Diomendius
ee60ef57a1 Generate Packaged/Houses dirs as dependencies
Uses add_custom_command() to add rules for generating these directories,
rather than creating them only when CMakeLists.txt runs. With this
change, you can manually delete Packaged from the build directory
without causing subsequent builds to fail.
2024-08-06 17:46:10 +12:00
Diomendius
2681ffc5c6 Update instructions in LINUX.txt 2024-08-06 16:03:16 +12:00
Diomendius
6a13e44dae Add Tools CMake build target
All the individual executables are marked EXCLUDE_FROM_ALL, but the
added Tools custom target is marked ALL. The only visible effect of this
is that ConvertColorCursors does not get built by default, since all the
other tools are dependencies for the Resources or Tools targets, which
are both built by default. Otherwise, the benefit is simply to keep the
dependency tree clean. Only three targets are built by default:
Aerofoil, its resources and the conversion tools. Everything else is
built to satisfy dependencies.
2024-08-06 16:03:16 +12:00
Diomendius
68db3cd83e Add Executable build target
This is meant as an alias to the name of the main executable, for
consistency with the Executable install component.
2024-08-06 16:03:16 +12:00
Diomendius
13f0874757 Enable CMake Release build type and LTO by default 2024-08-06 16:03:16 +12:00
Diomendius
660d79980a Add add_data_file() to CMakeLists.txt
This automatically cleans up artifacts specified as BYPRODUCTS after
running the commands.
2024-08-06 16:03:16 +12:00
Diomendius
f65d550300 Add houses to CMake 2024-08-06 16:03:16 +12:00
Diomendius
d9049f3c8a Add icons to CMake (commented-out)
These are only used on Windows and the converted files have been
committed to the repo, but this might be useful to someone.
2024-08-06 16:03:16 +12:00
Diomendius
8a5b50d98d Add Fonts.gpf to CMake 2024-08-06 16:03:13 +12:00
Diomendius
91e2f3b25f Add ApplicationResources.gpf to CMake 2024-08-06 01:34:53 +12:00
Diomendius
0ebdabc12f Add ConvertColorCursors to CMake, port to *nix
- Includes WindowsUnicodeToolShim.h.
- Replaces sprintf_s() with std::ostringstream.
- Replaces fopen_s() with fopen_utf8().
- Switches to the toolMain() wrapper, which is a no-op on except on
  Windows, where it should improve Unicode support, though I can't test
  that on my end.
- Replaces \ with / in paths, which should still be Windows-compatible.
2024-08-06 01:34:53 +12:00
Diomendius
8b916867d5 Add GenerateFonts to CMake, port to *nix
Removes unused Windows-specific headers and adds arguments to specify
source and output directories, which is necessary for out-of-tree
builds, which are necessary to avoid name collisions on platforms where
executables have no file extension (so, basically everything except
Windows).
2024-08-06 01:34:53 +12:00
Diomendius
a7f5b653fa Add GpFontHandler_FreeType2 to CMake
Also add stddef.h include to GpRenderedGlyphMetrics.h to make size_t
visible. Does MSVC provide size_t by default, or via stdint.h? This
prevents compilation and I can't see how this would have compiled on
Windows otherwise.
2024-08-06 01:34:53 +12:00
Diomendius
5c74c96771 Add unpacktool to CMake, port to *nix
- Adds missing includes, removes some unused ones.
- Removes unused Windows.h and shellapi.h includes.
- Uses / as path separator. This is portable and should still work fine
  on Windows.
2024-08-06 01:28:44 +12:00
Diomendius
e78d93437a Add HouseTool to CMake 2024-08-06 00:50:29 +12:00
Diomendius
c2753ec679 Add MiniRez to CMake
Also includes <algorithm> to provide std::find(). Evidently something in
Windows implicitly provides find(), but it was broken on Linux.
2024-08-06 00:50:09 +12:00
Diomendius
f27860776b Add MergeGPF to CMake 2024-08-06 00:32:23 +12:00
Diomendius
77fcc35726 Add FTagData to CMake, port to *nix 2024-08-06 00:32:23 +12:00
Diomendius
e2bb19709d Add MakeTimestamp to CMake, port to *nix 2024-08-06 00:32:22 +12:00
Diomendius
8b2db1b142 Fix equality test in gpr2gpa.cpp
I don't think this actually gets hit when converting the base Glider PRO
resources, but it's an obvious error that makes the condition always
true.
2024-08-06 00:32:22 +12:00
Diomendius
77009b08ca Avoid Clang c++11-narrowing error
Downgrades c++11-narrowing to a warning when compiling with Clang. A
better solution would be to fix the error, but this at least brings
Clang in line with the more permissive GCC, which treats this as a
warning by default.
2024-08-06 00:32:10 +12:00
Diomendius
7a81b2b396 Add gpr2gpa to CMake, port to *nix 2024-08-06 00:16:22 +12:00
Diomendius
e2da9bb7c5 Add hqx2gp to CMake 2024-08-06 00:16:22 +12:00
Diomendius
796b2880cf Add hqx2bin to CMake 2024-08-06 00:16:22 +12:00
Diomendius
c372fcb92d Add bin2gp to CMake 2024-08-06 00:16:22 +12:00
Diomendius
1e4ee9335e Add flattenmov to CMake 2024-08-06 00:16:22 +12:00
Diomendius
e2fcd7851d Add UnixUnicodeToolShim.cpp
This is the counterpart to WindowsUnicodeToolShim.cpp for *nix systems.
2024-08-06 00:16:22 +12:00
Diomendius
9aa82066f1 Refactor CMakeLists.txt
The BUILD_INTERFACE generator expression isn't actually useful as we
don't use export(). CMAKE_CURRENT_SOURCE_DIR is also unnecessary as
CMake treats relative paths as relative to the current source directory
(or the current binary directory for outputs).
2024-08-04 12:57:13 +12:00
Diomendius
de3fdeb7b1 Fix double-use of va_list in AppendFmt
AppendFmt calls vsnprintf twice, first to check the size of the
formatted string, then to write it for real, but it used the same
va_list for both calls, so the second call got an invalid va_list after
the first call had already consumed all its arguments.

This is UB and at least on Linux makes the second call print garbage. I
presume Windows implements va_list differently such that this somehow
worked correctly, because on Linux, all of the dialog items get parsed
into invalid JSON due to this bug, with lines like this (note the
missing second array element and closing bracket):
    "pos" : [ -55947262,
2024-08-04 12:57:13 +12:00
18 changed files with 752 additions and 110 deletions

View File

@@ -5,6 +5,28 @@ SET(EXECNAME "AerofoilX" CACHE STRING "Defines the exec name")
message(${CMAKE_BINARY_DIR})
# Use Release build type by default
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
message("Build type unspecified, using Release")
endif()
# Enable LTO by default if supported
if("${CMAKE_INTERPROCEDURAL_OPTIMIZATION}" STREQUAL "")
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORTED)
if(IPO_SUPPORTED)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION On)
message("Compiler supports LTO, enabling automatically")
endif()
endif()
# FIXME: Clang treats this as an error by default; fixing the source rather
# than downgrading the error to a warning would be a better solution.
add_compile_options(
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=c++11-narrowing>
)
find_package(SDL2 REQUIRED)
if(PLATFORM STREQUAL "MAC")
@@ -127,18 +149,18 @@ add_library(PortabilityLayer STATIC
)
target_include_directories(PortabilityLayer PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/zlib>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/MacRomanConversion>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/stb>
Common
GpCommon
PortabilityLayer
zlib
rapidjson/include
MacRomanConversion
stb
)
target_compile_options(PortabilityLayer PRIVATE -Wno-multichar)
target_link_libraries(PortabilityLayer zlib MacRomanConversion stb)
target_link_libraries(PortabilityLayer PRIVATE zlib MacRomanConversion stb)
add_library(GpShell STATIC
@@ -153,9 +175,9 @@ add_library(GpShell STATIC
)
target_include_directories(GpShell PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
Common
GpCommon
PortabilityLayer
)
add_library(GpApp STATIC
@@ -233,16 +255,15 @@ add_library(GpApp STATIC
target_compile_options(GpApp PRIVATE -Wno-multichar)
target_include_directories(GpApp PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
Common
GpCommon
PortabilityLayer
)
target_link_libraries(GpApp PortabilityLayer)
target_link_libraries(GpApp PRIVATE PortabilityLayer)
if(CMAKE_HOST_UNIX)
set(EXEC_SOURCES )
list(APPEND EXEC_SOURCES
set(EXEC_SOURCES
AerofoilPortable/GpSystemServices_POSIX.cpp
AerofoilPortable/GpThreadEvent_Cpp11.cpp
AerofoilPortable/GpAllocator_C.cpp
@@ -260,21 +281,20 @@ if(CMAKE_HOST_UNIX)
AerofoilX/GpFileSystem_X.cpp
)
set(EXEC_LIBS )
list(APPEND EXEC_LIBS
set(EXEC_LIBS
${SDL2_LIBRARIES}
GpApp
GpShell
PortabilityLayer
)
set(EXEC_INC_DIRS )
list(APPEND EXEC_INC_DIRS
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Common>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpCommon>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GpShell>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AerofoilSDL>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AerofoilPortable>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/PortabilityLayer>
set(EXEC_INC_DIRS
Common
GpCommon
GpShell
AerofoilSDL
AerofoilPortable
PortabilityLayer
${SDL2_INCLUDE_DIRS}
)
if(PLATFORM STREQUAL "MAC")
@@ -283,7 +303,7 @@ if(CMAKE_HOST_UNIX)
AerofoilMac/AerofoilMac/MacInit.mm
)
list(APPEND EXEC_INC_DIRS
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AerofoilMac/AerofoilMac>
AerofoilMac/AerofoilMac
)
list(APPEND EXEC_LIBS
"-framework Cocoa"
@@ -296,4 +316,418 @@ if(CMAKE_HOST_UNIX)
endif()
install (TARGETS ${EXECNAME})
add_executable(flattenmov EXCLUDE_FROM_ALL flattenmov/flattenmov.cpp AerofoilPortable/GpAllocator_C.cpp)
target_include_directories(flattenmov PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
)
target_link_libraries(flattenmov PortabilityLayer)
add_executable(bin2gp EXCLUDE_FROM_ALL bin2gp/bin2gp.cpp AerofoilPortable/GpAllocator_C.cpp)
target_include_directories(bin2gp PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
)
target_link_libraries(bin2gp PortabilityLayer)
add_executable(hqx2bin EXCLUDE_FROM_ALL hqx2bin/hqx2bin.cpp AerofoilPortable/GpAllocator_C.cpp)
target_include_directories(hqx2bin PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
)
target_link_libraries(hqx2bin PortabilityLayer)
add_executable(hqx2gp EXCLUDE_FROM_ALL
hqx2gp/hqx2gp.cpp
AerofoilPortable/GpAllocator_C.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(hqx2gp PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
WindowsUnicodeToolShim
)
target_link_libraries(hqx2gp PortabilityLayer)
add_executable(gpr2gpa EXCLUDE_FROM_ALL
gpr2gpa/gpr2gpa.cpp
gpr2gpa/macedec.cpp
AerofoilPortable/GpAllocator_C.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(gpr2gpa PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
MacRomanConversion
WindowsUnicodeToolShim
rapidjson/include
zlib
)
target_link_libraries(gpr2gpa PortabilityLayer MacRomanConversion zlib)
add_executable(MakeTimestamp EXCLUDE_FROM_ALL MakeTimestamp/MakeTimestamp.cpp)
target_include_directories(MakeTimestamp PRIVATE PortabilityLayer)
target_link_libraries(MakeTimestamp PortabilityLayer)
add_executable(FTagData EXCLUDE_FROM_ALL
FTagData/FTagData.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(FTagData PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
WindowsUnicodeToolShim
)
target_link_libraries(FTagData PortabilityLayer)
add_executable(MergeGPF EXCLUDE_FROM_ALL
MergeGPF/MergeGPF.cpp
AerofoilPortable/GpAllocator_C.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(MergeGPF PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
WindowsUnicodeToolShim
)
target_link_libraries(MergeGPF PortabilityLayer)
add_executable(MiniRez EXCLUDE_FROM_ALL MiniRez/MiniRez.cpp WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp)
target_include_directories(MiniRez PRIVATE
Common
GpCommon
PortabilityLayer
WindowsUnicodeToolShim
)
target_link_libraries(MiniRez PortabilityLayer)
add_executable(HouseTool EXCLUDE_FROM_ALL
HouseTool/HouseTool.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(HouseTool PRIVATE
Common
GpCommon
PortabilityLayer
MacRomanConversion
WindowsUnicodeToolShim
)
target_link_libraries(HouseTool PortabilityLayer MacRomanConversion)
add_executable(unpacktool EXCLUDE_FROM_ALL
unpacktool/ArchiveDescription.cpp
unpacktool/BWT.cpp
unpacktool/CompactProLZHDecompressor.cpp
unpacktool/CompactProLZHRLEDecompressor.cpp
unpacktool/CompactProParser.cpp
unpacktool/CompactProRLEDecompressor.cpp
unpacktool/CRC.cpp
unpacktool/CSInputBuffer.cpp
unpacktool/DecompressorProxyReader.cpp
unpacktool/LZSSDecompressor.cpp
unpacktool/LZW.cpp
unpacktool/LZWDecompressor.cpp
unpacktool/NullDecompressor.cpp
unpacktool/PrefixCode.cpp
unpacktool/RLE90Decompressor.cpp
unpacktool/StringCommon.cpp
unpacktool/StuffIt13Decompressor.cpp
unpacktool/StuffIt5Parser.cpp
unpacktool/StuffItArsenicDecompressor.cpp
unpacktool/StuffItCommon.cpp
unpacktool/StuffItHuffmanDecompressor.cpp
unpacktool/StuffItParser.cpp
unpacktool/unpacktool.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(unpacktool PRIVATE
Common
GpCommon
PortabilityLayer
MacRomanConversion
WindowsUnicodeToolShim
)
target_link_libraries(unpacktool PortabilityLayer MacRomanConversion)
find_package(Freetype)
if(FREETYPE_FOUND)
add_library(GpFontHandler_FreeType2 STATIC
GpFontHandler_FreeType2/GpFontHandler_FreeType2.cpp
)
target_include_directories(GpFontHandler_FreeType2 PRIVATE
Common
GpCommon
"${FREETYPE_INCLUDE_DIR_ft2build}"
)
target_link_libraries(GpFontHandler_FreeType2 PRIVATE Freetype::Freetype)
add_executable(GenerateFonts EXCLUDE_FROM_ALL
GenerateFonts/GenerateFonts.cpp
AerofoilPortable/GpAllocator_C.cpp
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(GenerateFonts PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
WindowsUnicodeToolShim
)
target_link_libraries(GenerateFonts PortabilityLayer GpFontHandler_FreeType2)
endif()
add_executable(ConvertColorCursors EXCLUDE_FROM_ALL
ConvertColorCursors/ConvertColorCursors.cpp
AerofoilPortable/GpAllocator_C.cpp
stb/stb_image_write.c
WindowsUnicodeToolShim/UnixUnicodeToolShim.cpp
)
target_include_directories(ConvertColorCursors PRIVATE
Common
GpCommon
PortabilityLayer
AerofoilPortable
stb
WindowsUnicodeToolShim
)
target_link_libraries(ConvertColorCursors PortabilityLayer)
add_custom_target(BuildDirs
BYPRODUCTS Packaged tmp
COMMAND "${CMAKE_COMMAND}" -E make_directory Packaged/Houses tmp
VERBATIM
)
set(DATA_FILES)
function(add_data_file NAME)
list(APPEND DATA_FILES "Packaged/${NAME}")
set(DATA_FILES "${DATA_FILES}" PARENT_SCOPE)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "")
set(TMPDIR "${CMAKE_CURRENT_BINARY_DIR}/tmp/${NAME}")
list(TRANSFORM ARG_UNPARSED_ARGUMENTS
REPLACE {TMPDIR} "${TMPDIR}"
)
add_custom_command(
OUTPUT "Packaged/${NAME}"
DEPENDS BuildDirs
COMMAND "${CMAKE_COMMAND}" -E make_directory "${TMPDIR}"
${ARG_UNPARSED_ARGUMENTS}
COMMAND "${CMAKE_COMMAND}" -E rename
"${TMPDIR}/${NAME}"
"${CMAKE_CURRENT_BINARY_DIR}/Packaged/${NAME}"
COMMAND "${CMAKE_COMMAND}" -E rm -r -- "${TMPDIR}"
VERBATIM
)
endfunction()
add_data_file(ApplicationResources.gpf
DEPENDS
MiniRez gpr2gpa FTagData MergeGPF "GliderProData/Glider PRO.r"
ApplicationResourcePatches/manifest.json DefaultTimestamp.timestamp
COMMAND MiniRez
"GliderProData/Glider PRO.r"
"{TMPDIR}/ApplicationResources.gpr"
COMMAND gpr2gpa
"{TMPDIR}/ApplicationResources.gpr"
DefaultTimestamp.timestamp
"{TMPDIR}/ApplicationResources.gpa"
-patch ApplicationResourcePatches/manifest.json
COMMAND FTagData
DefaultTimestamp.timestamp
"{TMPDIR}/ApplicationResources.gpf"
data ozm5 0 0 locked
COMMAND MergeGPF
"{TMPDIR}/ApplicationResources.gpf"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
file(GLOB_RECURSE FONT_DEPS RELATIVE "${CMAKE_SOURCE_DIR}" CONFIGURE_DEPENDS Resources/Fonts/*)
add_data_file(Fonts.gpf
DEPENDS GenerateFonts MiniRez gpr2gpa FTagData MergeGPF ${FONT_DEPS}
COMMAND GenerateFonts "${CMAKE_SOURCE_DIR}/Resources" {TMPDIR}
COMMAND MiniRez "${CMAKE_SOURCE_DIR}/Empty.r" {TMPDIR}/Fonts.gpr
COMMAND gpr2gpa
{TMPDIR}/Fonts.gpr
"${CMAKE_SOURCE_DIR}/DefaultTimestamp.timestamp"
{TMPDIR}/Fonts.gpa
-patch {TMPDIR}/FontCacheManifest.json
COMMAND FTagData
DefaultTimestamp.timestamp
{TMPDIR}/Fonts.gpf
data ozm5 0 0 locked
COMMAND MergeGPF {TMPDIR}/Fonts.gpf
)
# These files are committed to the repo and aren't currently useful on non-Windows systems anyway.
#file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Aerofoil/ConvertedResources)
#
#set(CONVERTED_ICONS
# Aerofoil/ConvertedResources/Large128.ico
# Aerofoil/ConvertedResources/Large129.ico
# Aerofoil/ConvertedResources/Large130.ico
# Aerofoil/ConvertedResources/Large131.ico
# Aerofoil/ConvertedResources/Large132.ico
# Aerofoil/ConvertedResources/Large133.ico
# Aerofoil/ConvertedResources/Small128.ico
# Aerofoil/ConvertedResources/Small129.ico
# Aerofoil/ConvertedResources/Small130.ico
# Aerofoil/ConvertedResources/Small133.ico
# )
#
#add_custom_command(
# OUTPUT ${CONVERTED_ICONS}
# DEPENDS ConvertColorCursors Packaged/ApplicationResources.gpr
# COMMAND ConvertColorCursors
# )
#add_custom_target(Icons DEPENDS ${CONVERTED_ICONS})
set(HOUSE_FILES)
function(add_house NAME)
cmake_parse_arguments(PARSE_ARGV 0 ARG
""
PATCH
""
)
if(ARG_PATCH)
set(PATCH_ARGS -patch "${CMAKE_SOURCE_DIR}/HousePatches/${ARG_PATCH}")
endif()
set(BASE_PATH "Packaged/Houses/${NAME}")
list(APPEND HOUSE_FILES "${BASE_PATH}.gpf")
set(BYPRODUCTS "${BASE_PATH}.gpr" "${BASE_PATH}.gpa" "${BASE_PATH}.gpd")
set(BINHEX_SRC "${CMAKE_SOURCE_DIR}/GliderProData/Houses/${NAME}.binhex")
set(TS "${CMAKE_SOURCE_DIR}/DefaultTimestamp.timestamp")
add_custom_command(
OUTPUT
"${BASE_PATH}.gpf"
BYPRODUCTS
${BYPRODUCTS}
DEPENDS hqx2gp gpr2gpa MergeGPF BuildDirs "${BINHEX_SRC}" "${TS}"
COMMAND hqx2gp
"${BINHEX_SRC}"
"${TS}"
"${BASE_PATH}"
COMMAND gpr2gpa
"${BASE_PATH}.gpr"
"${TS}"
"${BASE_PATH}.gpa"
${PATCH_ARGS}
${HOUSE_EXTRA_COMMANDS}
COMMAND MergeGPF
"${BASE_PATH}.gpf"
COMMAND "${CMAKE_COMMAND}" -E rm
${BYPRODUCTS}
VERBATIM
)
set(MOV_GPA_SRC "${CMAKE_SOURCE_DIR}/GliderProData/ConvertedMovies/${NAME}.mov.gpa")
if(EXISTS "${MOV_GPA_SRC}")
list(APPEND HOUSE_FILES "${BASE_PATH}.mov.gpf")
add_custom_command(
OUTPUT
"${BASE_PATH}.mov.gpf"
BYPRODUCTS
"${BASE_PATH}.mov.gpa"
DEPENDS FTagData MergeGPF BuildDirs "${MOV_GPA_SRC}" "${TS}"
COMMAND FTagData
"${TS}"
"${BASE_PATH}.mov.gpf"
MooV ozm5 0 0 locked
COMMAND "${CMAKE_COMMAND}" -E copy
-t "Packaged/Houses"
"${MOV_GPA_SRC}"
COMMAND MergeGPF
"${BASE_PATH}.mov.gpf"
COMMAND "${CMAKE_COMMAND}" -E rm
"${BASE_PATH}.mov.gpa"
VERBATIM
)
endif()
set(HOUSE_FILES "${HOUSE_FILES}" PARENT_SCOPE)
endfunction()
add_house("Art Museum")
add_house("California or Bust!")
set(HOUSE_EXTRA_COMMANDS
DEPENDS HouseTool
COMMAND HouseTool
patch "Packaged/Houses/Castle o' the Air.gpd" .firstRoom 77
)
add_house("Castle o' the Air")
unset(HOUSE_EXTRA_COMMANDS)
add_house("CD Demo House")
add_house("Davis Station")
add_house("Demo House")
add_house("Fun House")
add_house("Grand Prix" PATCH "GrandPrix.json")
add_house("ImagineHouse PRO II" PATCH "ImagineHousePROII.json")
add_house("In The Mirror" PATCH "InTheMirror.json")
add_house("Land of Illusion")
add_house("Leviathan" PATCH "Leviathan.json")
add_house("Metropolis")
add_house("Nemo's Market")
add_house("Rainbow's End" PATCH "RainbowsEnd.json")
add_house("Slumberland")
add_house("SpacePods")
add_house("Teddy World")
add_house("The Asylum Pro")
add_house("Titanic")
add_custom_target(Executable DEPENDS "${EXECNAME}")
add_custom_target(Resources ALL
DEPENDS
${DATA_FILES}
${HOUSE_FILES}
)
set(TOOL_EXES
flattenmov
bin2gp
hqx2bin
hqx2gp
MakeTimestamp
FTagData
gpr2gpa
unpacktool
MergeGPF
)
add_custom_target(Tools ALL DEPENDS ${TOOL_EXES})
list(TRANSFORM DATA_FILES PREPEND "${CMAKE_CURRENT_BINARY_DIR}/")
list(TRANSFORM HOUSE_FILES PREPEND "${CMAKE_CURRENT_BINARY_DIR}/")
install(TARGETS "${EXECNAME}" COMPONENT Executable)
install(FILES ${DATA_FILES} DESTINATION lib/aerofoil/Packaged COMPONENT Resources)
install(FILES ${HOUSE_FILES} DESTINATION lib/aerofoil/Packaged/Houses COMPONENT Resources)
install(TARGETS ${TOOL_EXES} DESTINATION lib/aerofoil/tools COMPONENT Tools)

View File

@@ -8,8 +8,11 @@
#include "QDStandardPalette.h"
#include "PLBigEndian.h"
#include "PLDrivers.h"
#include <assert.h>
#include "WindowsUnicodeToolShim.h"
#include <cassert>
#include <cstdio>
#include <sstream>
#include <string>
#include <vector>
@@ -92,12 +95,12 @@ void ConvertIconFamily(PortabilityLayer::ResourceFile *resFile, int32_t iconBitm
item.a = 0;
}
char outPath[256];
sprintf_s(outPath, "Aerofoil\\ConvertedResources\\%s%i.ico", prefix, resID);
std::string outPath = (
std::ostringstream() << "Aerofoil/ConvertedResources/" << prefix << resID << ".ico"
).str();
FILE *outF = nullptr;
errno_t outErr = fopen_s(&outF, outPath, "wb");
if (!outErr)
FILE *outF = fopen_utf8(outPath.c_str(), "wb");
if (outF)
{
IconDir iconDir;
iconDir.m_reserved = 0;
@@ -127,6 +130,8 @@ void ConvertIconFamily(PortabilityLayer::ResourceFile *resFile, int32_t iconBitm
fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF);
fclose(outF);
}
else
perror(outPath.c_str());
delete[] pixelData;
bwBlock.Dispose();
@@ -134,12 +139,14 @@ void ConvertIconFamily(PortabilityLayer::ResourceFile *resFile, int32_t iconBitm
}
}
int main(int argc, const char **argv)
int toolMain(int argc, const char **argv)
{
FILE *f = nullptr;
errno_t err = fopen_s(&f, "Packaged\\ApplicationResources.gpr", "rb");
if (err)
return err;
FILE *f = fopen_utf8("Packaged/ApplicationResources.gpr", "rb");
if (!f)
{
perror("Cannot open Packaged/ApplicationResources.gpr");
return -1;
}
PortabilityLayer::CFileStream stream(f);

View File

@@ -8,7 +8,7 @@ x64\Release\gpr2gpa.exe "Packaged\ApplicationResources.gpr" "DefaultTimestamp.ti
x64\Release\FTagData.exe "DefaultTimestamp.timestamp" "Packaged\ApplicationResources.gpf" data ozm5 0 0 locked
x64\Release\MergeGPF.exe "Packaged\ApplicationResources.gpf"
x64\Release\GenerateFonts.exe
x64\Release\GenerateFonts.exe Resources Packaged
x64\Release\MiniRez.exe "Empty.r" Packaged\Fonts.gpr
x64\Release\gpr2gpa.exe "Packaged\Fonts.gpr" "DefaultTimestamp.timestamp" "Packaged\Fonts.gpa" -patch "Packaged\FontCacheManifest.json"

View File

@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string>
#include <Windows.h>
#include "MacFileInfo.h"
#include "CFileStream.h"
#include "CombinedTimestamp.h"

View File

@@ -1,3 +1,7 @@
#include <algorithm>
#include <string>
#include <vector>
#include "FontFamily.h"
#include "FontManager.h"
#include "FontRenderer.h"
@@ -7,8 +11,6 @@
#include "GpAppInterface.h"
#include "GpDriverIndex.h"
#include "GpFontHandlerProperties.h"
#include "GpFileSystem_Win32.h"
#include "GpSystemServices_Win32.h"
#include "CFileStream.h"
#include "PLDrivers.h"
@@ -17,7 +19,11 @@
#include "WindowsUnicodeToolShim.h"
extern "C" __declspec(dllimport) IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
extern "C"
#ifdef _MSC_VER
__declspec(dllimport)
#endif
IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties);
class MemBufferStream final : public GpIOStream
{
@@ -168,6 +174,16 @@ bool KnownFontSpec::operator!=(const KnownFontSpec &other) const
int toolMain(int argc, const char **argv)
{
if (argc < 3)
{
fputs("Usage: GenerateFonts <resources dir> <output dir>\n", stderr);
return -1;
}
std::string resourcesDir(argv[1]);
resourcesDir += '/';
std::string outputDir(argv[2]);
outputDir += '/';
IGpAllocator *alloc = GpAllocator_C::GetInstance();
GpFontHandlerProperties fhProperties;
@@ -187,12 +203,13 @@ int toolMain(int argc, const char **argv)
std::vector<PortabilityLayer::RenderedFontCatalogRFontEntry> catalog;
std::vector<KnownFontSpec> fontSpecs;
FILE *manifestF = fopen_utf8("Packaged/FontCacheManifest.json", "wb");
std::string tmpPath(outputDir + "FontCacheManifest.json");
FILE *manifestF = fopen_utf8(tmpPath.c_str(), "wb");
fprintf(manifestF, "{\n");
fprintf(manifestF, "\t\"add\" :\n");
fprintf(manifestF, "\t{\n");
fprintf(manifestF, "\t\t\"RFCT/1000.bin\" : \"Packaged/FontCacheCatalog.bin\"");
fprintf(manifestF, "\t\t\"RFCT/1000.bin\" : \"%sFontCacheCatalog.bin\"", outputDir.c_str());
int numFontsEmitted = 0;
for (int presetIndex = 0; presetIndex < PortabilityLayer::FontPresets::kCount; presetIndex++)
@@ -220,8 +237,9 @@ int toolMain(int argc, const char **argv)
fontSpecs.push_back(spec);
std::string resPath = std::string("Resources/") + path;
FILE *fontFile = fopen_utf8(resPath.c_str(), "rb");
tmpPath = resourcesDir;
tmpPath += path;
FILE *fontFile = fopen_utf8(tmpPath.c_str(), "rb");
if (fontFile)
{
@@ -236,7 +254,7 @@ int toolMain(int argc, const char **argv)
{
char fontPath[1024];
sprintf(fontPath, "Packaged/CachedFont%i.bin", numFontsEmitted);
sprintf(fontPath, "%sCachedFont%i.bin", outputDir.c_str(), numFontsEmitted);
FILE *cachedFontF = fopen_utf8(fontPath, "wb");
PortabilityLayer::CFileStream cacheStream(cachedFontF);
@@ -290,7 +308,9 @@ int toolMain(int argc, const char **argv)
PortabilityLayer::RenderedFontCatalogHeader catHeader;
FILE *catF = fopen_utf8("Packaged/FontCacheCatalog.bin", "wb");
tmpPath = outputDir;
tmpPath += "FontCacheCatalog.bin";
FILE *catF = fopen_utf8(tmpPath.c_str(), "wb");
catHeader.m_version = PortabilityLayer::RenderedFontCatalogHeader::kVersion;
catHeader.m_pathsOffset = static_cast<uint32_t>(sizeof(PortabilityLayer::RenderedFontCatalogHeader) + paths.size() * sizeof(PortabilityLayer::RenderedFontCatalogPathEntry) + numFontsEmitted * sizeof(PortabilityLayer::RenderedFontCatalogRFontEntry));

View File

@@ -1,5 +1,6 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
struct GpRenderedGlyphMetrics

View File

@@ -1,18 +1,49 @@
Linux support is IN ALPHA and may or may not work. Only Cygwin has been
tested so far.
Linux support is IN ALPHA and may or may not work.
You can attempt the following:
- Install CMake (https://cmake.org/download/)
- Install SDL 2.0.12 or higher, or build it from the included source
- Run "cmake ." in the Aerofoil source directory
- Run "make install" to build the AerofoilX program
- Unzip the the Windows build
- Copy the "Packaged" and "Resources" directories from the Windows build into
the "lib" folder above the "bin" folder that the AerofoilX program installed
to. For example, if it installed to /usr/local/bin/, then the data files
should go in /usr/local/lib/aerofoil/
- Run AerofoilX
Use these basic steps to build and install Aerofoil:
- Ensure dependencies are installed - all of these are likely available from
your distribution's package manager:
- CMake 3.10 or later (https://cmake.org/download/)
- SDL 2.0.12 or later (https://libsdl.org)
- FreeType 2.10.1 or later (https://freetype.org/download.html)
- Change directory to the Aerofoil source root (the directory containing this file)
- Run "cmake -B build" to create a CMake build tree under "build"
- Run "cmake --build build" to build the AerofoilX program and its resources
- Run "cmake --install build" to install everything under /usr/local
- You can now run Aerofoil with the command "AerofoilX"
You can also build just the AerofoilX executable and use the prebuilt resources
from the Windows release:
- Follow the steps above, ignoring the FreeType dependency and stopping after
running "cmake -B build"
- Run "cmake --build build --target Executable" to build only the executable
- Run "cmake --install build --component Executable" to install AerofoilX in
/usr/local/bin
- Download the Windows build from
https://github.com/elasota/Aerofoil/releases/latest and unzip it
- Create the directory /usr/local/lib/aerofoil and copy the "Packaged"
directory from the Windows build into it
To install under a prefix other than /usr/local add
"-DCMAKE_INSTALL_PREFIX=<prefix>" to "cmake -B build"
Tools for converting Glider PRO houses are installed under
/usr/local/lib/aerofoil/tools, see Documentation/userhouses.txt for
instructions on how to use them.
The main AerofoilX executable, its required resources and the conversion tools
can be built and installed individually via these build targets and install
components:
- Executable
- Resources
- Tools
For instance, you can use
cmake --build build --target Executable Resources
to build only Aerofoil and its resources, and
cmake --install build --component Executable
cmake --install build --component Resources
to install them.
Please report any issues that you experience with this to the issue tracker on
GitHub.

View File

@@ -1,6 +1,13 @@
#ifdef _WIN32
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
#include <cstdint>
#else
#include <cstring>
#include <ctime>
#endif
#include <cstdio>
#include "CombinedTimestamp.h"
@@ -13,6 +20,7 @@ int main(int argc, const char **argv)
return -1;
}
#ifdef _WIN32
SYSTEMTIME epochStart;
epochStart.wYear = 1904;
epochStart.wMonth = 1;
@@ -34,13 +42,6 @@ int main(int argc, const char **argv)
int64_t currentTime64 = (static_cast<int64_t>(timestampFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(timestampFT.dwHighDateTime) << 32);
int64_t timeDelta = (currentTime64 - epochStart64) / 10000000;
FILE *f = nullptr;
if (fopen_s(&f, argv[1], "wb"))
{
fprintf(stderr, "Error opening output file");
return -1;
}
TIME_ZONE_INFORMATION tz;
GetTimeZoneInformation(&tz);
@@ -60,9 +61,36 @@ int main(int argc, const char **argv)
ts.m_localHour = localST.wHour;
ts.m_localMinute = localST.wMinute;
ts.m_localSecond = localST.wSecond;
#else
time_t currentTimeUnix = time(nullptr);
tm *currentTimeStruct = localtime(&currentTimeUnix);
if (currentTimeStruct == nullptr) {
fprintf(stderr, "Error converting system time to calendar format");
return -1;
}
PortabilityLayer::CombinedTimestamp ts;
ts.SetMacEpochTime(currentTimeUnix + ts.kMacEpochToUTC);
ts.SetLocalYear(currentTimeStruct->tm_year + 1900);
ts.m_localMonth = currentTimeStruct->tm_mon + 1;
ts.m_localDay = currentTimeStruct->tm_mday;
ts.m_localHour = currentTimeStruct->tm_hour;
ts.m_localMinute = currentTimeStruct->tm_min;
ts.m_localSecond = currentTimeStruct->tm_sec;
#endif
memset(ts.m_padding, 0, sizeof(ts.m_padding));
FILE *f = fopen(argv[1], "wb");
if (!f)
{
perror("Error opening output file");
return -1;
}
fwrite(&ts, sizeof(ts), 1, f);
fclose(f);

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <stdio.h>
#include <string>
#include <vector>

View File

@@ -0,0 +1,99 @@
#include "WindowsUnicodeToolShim.h"
#include <cstdio>
#include <cstring>
#include <string>
#include <utility>
#include <vector>
#include <dirent.h>
#include <sys/stat.h>
// Linux and macOS (and probably other non-Windows systems in general) do not
// have separate file system or command line APIs for different text encodings.
// On these systems UTF-8 is commonly the system encoding and, if so, argv will
// typically be UTF-8 encoded, though it is the calling process's responsibility
// to ensure this, as argv is passed verbatim as a sequence of byte strings.
//
// Filesystems on Unix-like systems are typically encoding-unaware, in which
// case the actual encoding used should match the system encoding, or else
// manual intervention is required.
//
// On macOS, HFS+ and APFS filenames are encoded as UTF-16 and UTF-8
// respectively, and the C filesystem API accepts UTF-8 strings. There are some
// gotchas relating to Unicode normalization, where HFS+ enforces a specific
// form of normalization at the filesystem layer but APFS does not, and using
// the C API to access the filesystem may avoid automatic normalization that
// higher-level macOS API functions may perform.
//
// In summary, text encoding is still a hairy problem on every computer system,
// though on the major non-Windows systems, assuming UTF-8 encoding is
// reasonable. For now, this header simply maps the WindowsUnicodeToolShim
// functions to their regular C API counterparts.
int toolMain(int argc, const char **argv);
int main(int argc, const char **argv) { return toolMain(argc, argv); }
FILE *fopen_utf8(const char *path, const char *options) { return fopen(path, options); }
int fputs_utf8(const char *str, FILE *f) { return fputs(str, f); }
int mkdir_utf8(const char *path) { return mkdir(path, 0777); }
void TerminateDirectoryPath(std::string &path)
{
const size_t len = path.length();
if (len == 0 || path[len - 1] != '/')
path.push_back('/');
}
void ScanDirectoryForExtension
(
std::vector<std::string> &outPaths,
const char *path,
const char *ending,
bool recursive
) {
DIR *dir = opendir(path);
if (!dir)
{
return;
}
size_t endingLen = strlen(ending);
dirent *ent;
while ((ent = readdir(dir)))
{
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
continue;
else if (recursive && ent->d_type == DT_DIR)
{
std::string tmpPath(path);
tmpPath.append("/");
tmpPath.append(ent->d_name);
ScanDirectoryForExtension(
outPaths,
tmpPath.c_str(),
ending,
recursive
);
}
else
{
size_t nameLen = strlen(ent->d_name);
if (endingLen <= nameLen && memcmp
(
ent->d_name + nameLen - endingLen,
ending,
endingLen
) == 0
) {
std::string tmpPath(path);
tmpPath.append("/");
tmpPath.append(ent->d_name);
outPaths.push_back(std::move(tmpPath));
}
}
}
closedir(dir);
}

View File

@@ -8,6 +8,7 @@ int mkdir_utf8(const char *path);
void TerminateDirectoryPath(std::string &path);
void ScanDirectoryForExtension(std::vector<std::string>& outPaths, const char *path, const char *ending, bool recursive);
#ifdef _WIN32
struct DirectoryScanContext;
struct DirectoryScanEntry
{
@@ -17,3 +18,11 @@ struct DirectoryScanEntry
DirectoryScanContext *opendir_utf8(const char *name);
DirectoryScanEntry *readdir_utf8(DirectoryScanContext *dir);
void closedir_utf8(DirectoryScanContext *context);
#else
inline int _fseeki64(FILE *stream, long offset, int whence) {
return fseek(stream, offset, whence);
}
inline long _ftelli64(FILE *stream) { return ftell(stream); };
#endif

View File

@@ -31,9 +31,9 @@
#include <stdio.h>
#include <string>
#include <sstream>
#include <utility>
#include <vector>
#include <algorithm>
#include "GpWindows.h"
enum AudioCompressionCodecID
{
@@ -98,6 +98,11 @@ void AppendFmt(std::vector<uint8_t> &array, const char *fmt, ...)
if (resultSize <= 0)
return;
// vsnprintf invalidates the va_list, so we need to
// reinit args so the next call doesn't print garbage.
va_end(args);
va_start(args, fmt);
size_t appendSize = static_cast<size_t>(resultSize);
if (SIZE_MAX == appendSize)
@@ -1466,7 +1471,7 @@ bool DecompressSound(int compressionID, int channelCount, const void *sndData, s
}
}
}
else if (compressionID = AudioCompressionCodecID_SixToOne)
else if (compressionID == AudioCompressionCodecID_SixToOne)
{
if (channelCount != 1)
{
@@ -2427,14 +2432,11 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
const size_t numRefs = typeList.m_numRefs;
{
char subName[256];
sprintf_s(subName, "%s", resTag.m_id);
PlannedEntry entry;
entry.m_name = subName;
entry.m_name = resTag.m_id;
entry.m_isDirectory = true;
contents.push_back(entry);
contents.push_back(std::move(entry));
}
for (size_t rlIndex = 0; rlIndex < numRefs; rlIndex++)
@@ -2453,14 +2455,15 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
if (typeList.m_resType == pictTypeID || typeList.m_resType == dateTypeID)
{
char resName[256];
sprintf_s(resName, "%s/%i.bmp", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".bmp"
).str();
if (ContainsName(reservedNames, resName))
if (ContainsName(reservedNames, resName.c_str()))
continue;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
if (ImportPICT(entry.m_uncompressedContents, resData, resSize, dumpqtDir, res.m_resID))
@@ -2470,14 +2473,15 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
}
else if (typeList.m_resType == sndTypeID)
{
char resName[256];
sprintf_s(resName, "%s/%i.wav", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".wav"
).str();
if (ContainsName(reservedNames, resName))
if (ContainsName(reservedNames, resName.c_str()))
continue;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
if (ImportSound(entry.m_uncompressedContents, resData, resSize, res.m_resID))
@@ -2487,14 +2491,15 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
}
else if (typeList.m_resType == indexStringTypeID)
{
char resName[256];
sprintf_s(resName, "%s/%i.txt", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".txt"
).str();
if (ContainsName(reservedNames, resName))
if (ContainsName(reservedNames, resName.c_str()))
continue;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
if (ImportIndexedString(entry.m_uncompressedContents, resData, resSize))
@@ -2502,14 +2507,15 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
}
else if (typeList.m_resType == ditlTypeID)
{
char resName[256];
sprintf_s(resName, "%s/%i.json", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".json"
).str();
if (ContainsName(reservedNames, resName))
if (ContainsName(reservedNames, resName.c_str()))
continue;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
if (ImportDialogItemTemplate(entry.m_uncompressedContents, resData, resSize))
@@ -2524,15 +2530,16 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
const IconTypeSpec &iconSpec = iconTypeSpecs[i];
if (typeList.m_resType == iconSpec.m_resTypeID)
{
char resName[256];
sprintf_s(resName, "%s/%i.bmp", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".bmp"
).str();
if (!ContainsName(reservedNames, resName))
if (!ContainsName(reservedNames, resName.c_str()))
{
isIcon = true;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
if (ImportIcon(entry.m_uncompressedContents, resData, resSize, iconSpec.m_width, iconSpec.m_height, iconSpec.m_bpp))
@@ -2545,15 +2552,16 @@ int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimes
if (!isIcon)
{
char resName[256];
sprintf_s(resName, "%s/%i.bin", resTag.m_id, static_cast<int>(res.m_resID));
std::string resName = (
std::ostringstream() << resTag.m_id << '/' << res.m_resID << ".bin"
).str();
if (ContainsName(reservedNames, resName))
if (ContainsName(reservedNames, resName.c_str()))
continue;
PlannedEntry entry;
entry.m_name = resName;
entry.m_name = std::move(resName);
entry.m_comment = resComment;
entry.m_uncompressedContents.resize(res.GetSize());

View File

@@ -1,5 +1,7 @@
#pragma once
#include <cstdint>
#include "IDecompressor.h"
class CompactProRLEDecompressor : public IDecompressor

View File

@@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstddef>
struct CSInputBuffer;

View File

@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
#include <cstddef>
#include <cstdint>
struct IFileReader
{

View File

@@ -1,3 +1,5 @@
#include <climits>
#include "PrefixCode.h"
struct XADCodeTreeNode

View File

@@ -1,5 +1,7 @@
#pragma once
#include <cstdint>
#include "IDecompressor.h"
class RLE90Decompressor : public IDecompressor

View File

@@ -28,9 +28,6 @@
#include <string.h>
#include <Windows.h>
#include <shellapi.h>
#include <string>
#include <vector>
@@ -387,7 +384,7 @@ int ExtractItem(int depth, const ArchiveItem &item, const std::string &dirPath,
{
mkdir_utf8(path.c_str());
path.append("\\");
path.append("/");
int returnCode = RecursiveExtractFiles(depth + 1, item.m_children, path, pathParanoid, reader, ts);
if (returnCode)