diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f1d51d61e..354139be80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ project(${PROJECT}) add_definitions(-DORCT2_RESOURCE_DIR="${ORCT2_RESOURCE_DIR}") add_definitions(-DHAVE_CONFIG_H) add_definitions(-DCURL_STATICLIB) +add_definitions(-DUSE_LIBPNG) INCLUDE(FindPkgConfig) @@ -48,16 +49,9 @@ option(STATIC "Create a static build.") # Not required yet PKG_CHECK_MODULES(PNG libpng>=1.6) if (NOT PNG_FOUND) - PKG_CHECK_MODULES(PNG libpng16) + PKG_CHECK_MODULES(PNG REQUIRED libpng16) endif (NOT PNG_FOUND) -if (PNG_FOUND) - set (USE_LODEPNG FALSE) -else (PNG_FOUND) - set (USE_LODEPNG TRUE) - message("Falling back to deprecated Lodepng for PNG support. Please upgrade your system to libpng 1.6") -endif (PNG_FOUND) - # Handle creating the rct2 text and data files on OS X and Linux # See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values # were derived. @@ -109,16 +103,10 @@ set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG=${DEBUG_LEVEL}") -if (USE_LODEPNG) - set (LODEPNG_SOURCES "lib/lodepng/*.c") -else (USE_LODEPNG) - add_definitions(-DUSE_LIBPNG) -endif (USE_LODEPNG) - # include lib include_directories("lib/") # add source files -file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp" "lib/argparse/*.c" "lib/cutest/*.c" ${LODEPNG_SOURCES}) +file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp") if (APPLE) file(GLOB_RECURSE ORCT2_MM_SOURCES "src/*.m") set_source_files_properties(${ORCT2_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c -fmodules") @@ -225,7 +213,7 @@ endif (UNIX AND NOT APPLE) # libopenrct2.dll -> openrct2.dll set_target_properties(${PROJECT} PROPERTIES PREFIX "") -TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${ORCTLIBS_LIB} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${PNGLIBS}) +TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${PNGLIBS}) if (APPLE OR STATIC) FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 4fe426a7dc..55b21a6892 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */ = {isa = PBXBuildFile; fileRef = D46105CD1C38828D00DB1EE3 /* scenario_sources.c */; }; D4ABAB061C2F812B0080CAD9 /* news_options.c in Sources */ = {isa = PBXBuildFile; fileRef = D4ABAB051C2F812B0080CAD9 /* news_options.c */; }; D4B85B5B1C41C7F3005C568A /* cable_lift.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B85B591C41C7F3005C568A /* cable_lift.c */; }; + D4B8C2A81C41EADF00B006AC /* argparse.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B8C2A61C41EADF00B006AC /* argparse.c */; }; D4D4DF141C34697B0048BE43 /* image_io.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D4DF121C34697B0048BE43 /* image_io.c */; }; D4EC47DF1C26342F0024B507 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D61C26342F0024B507 /* addresses.c */; }; D4EC47E01C26342F0024B507 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D91C26342F0024B507 /* audio.c */; }; @@ -186,8 +187,6 @@ D4EC48D21C2634C70024B507 /* libSDL2.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D4EC48C61C2634870024B507 /* libSDL2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D4EC48D31C2634C70024B507 /* libSDL2_ttf.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D4EC48C71C2634870024B507 /* libSDL2_ttf.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D4EC48D41C2634C70024B507 /* libspeexdsp.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D4EC48C81C2634870024B507 /* libspeexdsp.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - D4EC48DF1C2634E90024B507 /* argparse.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC48D61C2634E90024B507 /* argparse.c */; }; - D4EC48E01C2634E90024B507 /* CuTest.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC48D91C2634E90024B507 /* CuTest.c */; }; D4EC48E61C2637710024B507 /* g2.dat in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E31C2637710024B507 /* g2.dat */; }; D4EC48E71C2637710024B507 /* language in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E41C2637710024B507 /* language */; }; D4EC48E81C2637710024B507 /* title in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E51C2637710024B507 /* title */; }; @@ -225,6 +224,8 @@ D4ABAB051C2F812B0080CAD9 /* news_options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = news_options.c; sourceTree = ""; }; D4B85B591C41C7F3005C568A /* cable_lift.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cable_lift.c; sourceTree = ""; }; D4B85B5A1C41C7F3005C568A /* cable_lift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cable_lift.h; sourceTree = ""; }; + D4B8C2A61C41EADF00B006AC /* argparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = argparse.c; sourceTree = ""; }; + D4B8C2A71C41EADF00B006AC /* argparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = argparse.h; sourceTree = ""; }; D4D4DF121C34697B0048BE43 /* image_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = image_io.c; path = src/image_io.c; sourceTree = ""; }; D4D4DF131C34697B0048BE43 /* image_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = image_io.h; path = src/image_io.h; sourceTree = ""; }; D4EC46D61C26342F0024B507 /* addresses.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = addresses.c; path = src/addresses.c; sourceTree = ""; }; @@ -544,11 +545,6 @@ D4EC48C61C2634870024B507 /* libSDL2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libSDL2.dylib; sourceTree = ""; }; D4EC48C71C2634870024B507 /* libSDL2_ttf.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libSDL2_ttf.dylib; sourceTree = ""; }; D4EC48C81C2634870024B507 /* libspeexdsp.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libspeexdsp.dylib; sourceTree = ""; }; - D4EC48D61C2634E90024B507 /* argparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = argparse.c; sourceTree = ""; }; - D4EC48D71C2634E90024B507 /* argparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = argparse.h; sourceTree = ""; }; - D4EC48D91C2634E90024B507 /* CuTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CuTest.c; sourceTree = ""; }; - D4EC48DA1C2634E90024B507 /* CuTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CuTest.h; sourceTree = ""; }; - D4EC48DB1C2634E90024B507 /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = license.txt; sourceTree = ""; }; D4EC48E31C2637710024B507 /* g2.dat */ = {isa = PBXFileReference; lastKnownFileType = file; name = g2.dat; path = data/g2.dat; sourceTree = SOURCE_ROOT; }; D4EC48E41C2637710024B507 /* language */ = {isa = PBXFileReference; lastKnownFileType = folder; name = language; path = data/language; sourceTree = SOURCE_ROOT; }; D4EC48E51C2637710024B507 /* title */ = {isa = PBXFileReference; lastKnownFileType = folder; name = title; path = data/title; sourceTree = SOURCE_ROOT; }; @@ -576,6 +572,7 @@ D41B72431C21015A0080A7B9 /* Sources */ = { isa = PBXGroup; children = ( + D4B8C2A51C41EADF00B006AC /* argparse */, D4EC46D81C26342F0024B507 /* audio */, D4EC46E51C26342F0024B507 /* core */, D4EC46F31C26342F0024B507 /* drawing */, @@ -646,22 +643,12 @@ name = Libraries; sourceTree = ""; }; - D41B740F1C2105B00080A7B9 /* Source Libraries */ = { - isa = PBXGroup; - children = ( - D4EC48D51C2634E90024B507 /* argparse */, - D4EC48D81C2634E90024B507 /* cutest */, - ); - name = "Source Libraries"; - sourceTree = ""; - }; D497D06F1C20FD52002BF46A = { isa = PBXGroup; children = ( D41B72431C21015A0080A7B9 /* Sources */, D497D07A1C20FD52002BF46A /* Resources */, D41B73ED1C21017D0080A7B9 /* Libraries */, - D41B740F1C2105B00080A7B9 /* Source Libraries */, D497D0791C20FD52002BF46A /* Products */, ); sourceTree = ""; @@ -686,6 +673,16 @@ path = OpenRCT2; sourceTree = ""; }; + D4B8C2A51C41EADF00B006AC /* argparse */ = { + isa = PBXGroup; + children = ( + D4B8C2A61C41EADF00B006AC /* argparse.c */, + D4B8C2A71C41EADF00B006AC /* argparse.h */, + ); + name = argparse; + path = src/argparse; + sourceTree = ""; + }; D4C1EDD01C266A0B00F71B63 /* data */ = { isa = PBXGroup; children = ( @@ -1132,27 +1129,6 @@ name = jansson; sourceTree = ""; }; - D4EC48D51C2634E90024B507 /* argparse */ = { - isa = PBXGroup; - children = ( - D4EC48D61C2634E90024B507 /* argparse.c */, - D4EC48D71C2634E90024B507 /* argparse.h */, - ); - name = argparse; - path = lib/argparse; - sourceTree = ""; - }; - D4EC48D81C2634E90024B507 /* cutest */ = { - isa = PBXGroup; - children = ( - D4EC48D91C2634E90024B507 /* CuTest.c */, - D4EC48DA1C2634E90024B507 /* CuTest.h */, - D4EC48DB1C2634E90024B507 /* license.txt */, - ); - name = cutest; - path = lib/cutest; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1377,7 +1353,6 @@ D4EC483E1C26342F0024B507 /* game_bottom_toolbar.c in Sources */, D4EC48731C26342F0024B507 /* banner.c in Sources */, D4EC47F51C26342F0024B507 /* chat.c in Sources */, - D4EC48E01C2634E90024B507 /* CuTest.c in Sources */, D4EC48591C26342F0024B507 /* server_list.c in Sources */, D4EC48001C26342F0024B507 /* window.c in Sources */, D4EC47F61C26342F0024B507 /* colour.c in Sources */, @@ -1400,7 +1375,6 @@ D4EC48301C26342F0024B507 /* changelog.c in Sources */, D4EC48521C26342F0024B507 /* publisher_credits.c in Sources */, D4EC485E1C26342F0024B507 /* staff.c in Sources */, - D4EC48DF1C2634E90024B507 /* argparse.c in Sources */, D4EC486F1C26342F0024B507 /* track_place.c in Sources */, D4EC48261C26342F0024B507 /* track_paint.c in Sources */, D4EC48601C26342F0024B507 /* staff_list.c in Sources */, @@ -1469,6 +1443,7 @@ D4EC483C1C26342F0024B507 /* finances.c in Sources */, D4EC47F01C26342F0024B507 /* supports.c in Sources */, D4EC47FC1C26342F0024B507 /* title_sequences.c in Sources */, + D4B8C2A81C41EADF00B006AC /* argparse.c in Sources */, D4EC48421C26342F0024B507 /* land.c in Sources */, D4EC48791C26342F0024B507 /* map_animation.c in Sources */, D4EC480D1C26342F0024B507 /* marketing.c in Sources */, diff --git a/SDL2.dll b/SDL2.dll deleted file mode 100644 index 18d707f481..0000000000 Binary files a/SDL2.dll and /dev/null differ diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index b275753414..6471f6ea13 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3331,7 +3331,7 @@ STR_3320 :Unable to save scenario file... STR_3321 :New objects installed successfully STR_3322 :{WINDOW_COLOUR_2}Objective: {BLACK}{STRINGID} STR_3323 :Missing object data, ID: -STR_3324 :Requires Add-On Pack: +STR_3324 :Requires Add-On Pack: {STRINGID} STR_3325 :Requires an Add-On Pack STR_3326 :{WINDOW_COLOUR_2}(no image) STR_3327 :Starting positions for people not set diff --git a/distribution/readme.txt b/distribution/readme.txt index 32b2e1094a..97e36f5d57 100644 --- a/distribution/readme.txt +++ b/distribution/readme.txt @@ -1,5 +1,5 @@ -Last updated: 2015-12-04 -Release version: 0.0.3-1-beta +Last updated: 2016-09-01 +Release version: 0.0.4.0-beta ------------------------------------------------------------------------ @@ -68,11 +68,10 @@ following information in your bug report: 3.0) Supported platforms ---- ------------------- -OpenRCT2 currently requires the original RollerCoaster Tycoon 2 binary. While -this is still the case, the only supported platform is Windows. OpenRCT2 can -still be played on other operating systems either via a virtual machine or a -compatibility layer application such as Wine. Further instructions can be found -on GitHub. +OpenRCT2 is currently supported on Windows XP and above, many distributions of +Linux and OSX 10.7. OpenRCT2 will only work on x86 architectures as the +original RollerCoaster Tycoon 2 binary is still required to run the game. +Further instructions can be found on GitHub. 4.0) Installing and running OpenRCT2 ---- ------------------------------ @@ -82,7 +81,7 @@ be installed, or you have downloaded an installer, which will automatically extract OpenRCT2 in the given directory. OpenRCT2 requires an installation of RollerCoaster Tycoon 2 (RCT2) to run. You -must have either installed the original RCT2 disc, the GOG version or the steam +must have either installed the original RCT2 disc, the GOG version or the Steam version. Alternatively you can manually specify the location of where your RCT2 data files are. These may be directly copied of the original disc and placed in a directory of your choice. @@ -105,7 +104,7 @@ the RCT2 install path. If you are running Windows and have set a DPI scale, OpenRCT2 might look blury. This is because OpenRCT2 currently uses the original RollerCoaster Tycoon 2 -binary as a application host. However you can manually configure this binary to +binary as an application host. However you can manually configure this binary to not be scaled. This will make the game more crisp, but may result in the interface being too small to see clearly and less ergonomic to use. To stop DPI scaling, right click the binary itself (openrct2.exe) in the install directory @@ -116,8 +115,9 @@ select properties. Select the compatibility tab, check If you wish to use Steam Overlay or capture game for video recording or streaming, you might have to enable hardware display in the options window. This will still render the graphics on the CPU but the pixel data will be -displayed using either DirectX or OpenGL. This might slow down the game but can -also make the game look smoother. +displayed using either DirectX or OpenGL. This may also enable vertical +synchronisation if supported by your graphics card and you have enabled +"Uncap FPS". 5.0) Development ---- ----------- @@ -148,12 +148,13 @@ the complete licence text, see the file 'licence.txt'. This licence applies to all files in this distribution, except as noted below. argparse | MIT licence. -CuTest | zlib licence. Jansson | MIT licence. libcURL | MIT (or Modified BSD-style) licence. libspeex | BSD-style license. -LodePNG | zlib licence. +libpng | libpng licence. SDL2 | zlib licence. +SDL2 TTF | zlib licence. +zlib | zlib licence. Licences for sub-libraries used by the above may vary. For more information, visit the libraries' respective official websites. diff --git a/distribution/windows/install.nsi b/distribution/windows/install.nsi index c0455e61a9..8b8917aef3 100644 --- a/distribution/windows/install.nsi +++ b/distribution/windows/install.nsi @@ -141,7 +141,6 @@ Section "!OpenRCT2" Section1 ; Copy executable File /oname=openrct2.exe ${BINARY_DIR}\openrct2.exe File /oname=openrct2.dll ${BINARY_DIR}\openrct2.dll - File /oname=SDL2.dll ${BINARY_DIR}\SDL2.dll ; Create the Registry Entries WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenRCT2" "Comments" "Visit ${APPURLLINK}" @@ -207,7 +206,6 @@ Section "Uninstall" Delete "$INSTDIR\contributors.md" Delete "$INSTDIR\openrct2.exe" Delete "$INSTDIR\openrct2.dll" - Delete "$INSTDIR\SDL2.dll" Delete "$INSTDIR\licence.txt" Delete "$INSTDIR\INSTALL.LOG" Delete "$INSTDIR\crash.log" diff --git a/libs.vcxproj b/libs.vcxproj deleted file mode 100644 index 0148b48b6e..0000000000 --- a/libs.vcxproj +++ /dev/null @@ -1,219 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Release XP - Win32 - - - Release with Tests - Win32 - - - - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB} - libs - - - - StaticLibrary - true - v140 - MultiByte - - - StaticLibrary - false - v140 - true - MultiByte - - - StaticLibrary - false - v140_xp - true - MultiByte - - - StaticLibrary - false - v140 - true - MultiByte - - - - - - - - - - - - - - - - - - - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ - lib\libcurl\include;lib\jansson;lib\cutest\CuTest.h;lib\SDL2_ttf\include;$(IncludePath) - lib\libcurl\lib;lib\SDL2_ttf\lib\x86;$(LibraryPath) - - - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ - lib\libcurl\include;lib\jansson;lib\cutest\CuTest.h;lib\SDL2_ttf\include;$(IncludePath) - lib\libcurl\lib;lib\SDL2_ttf\lib\x86;$(LibraryPath) - - - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ - lib\libcurl\include;lib\jansson;lib\cutest\CuTest.h;lib\SDL2_ttf\include;$(IncludePath) - lib\libcurl\lib;lib\SDL2_ttf\lib\x86;$(LibraryPath) - - - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\Release\ - lib\libcurl\include;lib\jansson;lib\cutest\CuTest.h;lib\SDL2_ttf\include;$(IncludePath) - lib\libcurl\lib;lib\SDL2_ttf\lib\x86;$(LibraryPath) - - - - Level3 - Disabled - true - MultiThreaded - 1Byte - _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;NS_ENABLE_THREADS;NS_ENABLE_SSL;DISABLE_MD5;%(PreprocessorDefinitions) - - - true - - - libcurl.lib;Ws2_32.lib;SDL2_ttf.lib;%(AdditionalDependencies) - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;NS_ENABLE_THREADS;NS_ENABLE_SSL;DISABLE_MD5;%(PreprocessorDefinitions) - MultiThreaded - 1Byte - - - - - true - true - true - - - libcurl.lib;Ws2_32.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;NS_ENABLE_THREADS;NS_ENABLE_SSL;DISABLE_MD5;%(PreprocessorDefinitions) - MultiThreaded - 1Byte - - - - - true - true - true - - - libcurl.lib;Ws2_32.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;NS_ENABLE_THREADS;NS_ENABLE_SSL;DISABLE_MD5;%(PreprocessorDefinitions) - MultiThreaded - 1Byte - - - - - true - true - true - - - libcurl.lib;Ws2_32.lib;SDL2_ttf.lib;%(AdditionalDependencies) - - - - - TurnOffAllWarnings - - - - - - - - - - - - - - - TurnOffAllWarnings - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs.vcxproj.filters b/libs.vcxproj.filters deleted file mode 100644 index cfa41aa854..0000000000 --- a/libs.vcxproj.filters +++ /dev/null @@ -1,124 +0,0 @@ - - - - - {f28d7721-061f-44b8-bbd5-42dc9483b387} - - - {69f22202-b887-4e7c-bf7c-eb581571398d} - - - {45966214-8043-431c-8eb3-920c00bf749d} - - - {7f953e55-d294-4158-b309-67f41fa82760} - - - {7b46a2d6-1095-4e7a-b98b-006b832ef7a1} - - - {16ee6cb9-307a-4e8a-8261-a69d91b17739} - - - {92e56bd7-37be-465c-9212-3b6cfb8cf7c9} - - - - - argparse - - - libspeex - - - lodepng - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - cutest - - - - - argparse - - - libspeex - - - libspeex - - - libspeex - - - libspeex - - - libspeex\speex - - - libspeex\speex - - - lodepng - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - jansson - - - - \ No newline at end of file diff --git a/libs.vcxproj.user b/libs.vcxproj.user deleted file mode 100644 index a11cd7f915..0000000000 --- a/libs.vcxproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - true - - \ No newline at end of file diff --git a/openrct2.sln b/openrct2.sln index b3adc8b5f0..e92027ef3a 100644 --- a/openrct2.sln +++ b/openrct2.sln @@ -5,32 +5,16 @@ VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openrct2", "openrct2.vcxproj", "{D24D94F6-2A74-480C-B512-629C306CE92F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libs", "libs.vcxproj", "{074DC930-05C6-4B7F-B5DD-DD237E6E44DB}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 - Release with Tests|Win32 = Release with Tests|Win32 - Release XP|Win32 = Release XP|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {D24D94F6-2A74-480C-B512-629C306CE92F}.Debug|Win32.ActiveCfg = Debug|Win32 {D24D94F6-2A74-480C-B512-629C306CE92F}.Debug|Win32.Build.0 = Debug|Win32 - {D24D94F6-2A74-480C-B512-629C306CE92F}.Release with Tests|Win32.ActiveCfg = Release with Tests|Win32 - {D24D94F6-2A74-480C-B512-629C306CE92F}.Release with Tests|Win32.Build.0 = Release with Tests|Win32 - {D24D94F6-2A74-480C-B512-629C306CE92F}.Release XP|Win32.ActiveCfg = Release XP|Win32 - {D24D94F6-2A74-480C-B512-629C306CE92F}.Release XP|Win32.Build.0 = Release XP|Win32 {D24D94F6-2A74-480C-B512-629C306CE92F}.Release|Win32.ActiveCfg = Release|Win32 {D24D94F6-2A74-480C-B512-629C306CE92F}.Release|Win32.Build.0 = Release|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Debug|Win32.ActiveCfg = Debug|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Debug|Win32.Build.0 = Debug|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release with Tests|Win32.ActiveCfg = Release with Tests|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release with Tests|Win32.Build.0 = Release with Tests|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release XP|Win32.ActiveCfg = Release XP|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release XP|Win32.Build.0 = Release XP|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release|Win32.ActiveCfg = Release|Win32 - {074DC930-05C6-4B7F-B5DD-DD237E6E44DB}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/openrct2.vcxproj b/openrct2.vcxproj index ae7900dc50..c390fa4819 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -3,7 +3,6 @@ - @@ -14,20 +13,13 @@ Release Win32 - - Release XP - Win32 - - - Release with Tests - Win32 - + @@ -117,9 +109,6 @@ - - - @@ -197,6 +186,7 @@ + @@ -294,16 +284,10 @@ - - - {074dc930-05c6-4b7f-b5dd-dd237e6e44db} - - {D24D94F6-2A74-480C-B512-629C306CE92F} openrct2 openrct2 - 10.0.10240.0 @@ -319,67 +303,35 @@ true MultiByte - - DynamicLibrary - false - v140_xp - true - MultiByte - - - DynamicLibrary - false - v140 - true - MultiByte - - - + - - - - - - - $(SolutionDir)lib;$(SolutionDir)lib\libspeex;$(SolutionDir)lib\sdl\include;$(SolutionDir)lib\libcurl\include;$(SolutionDir)lib\jansson;$(SolutionDir)lib\cutest;$(SolutionDir)lib\SDL2_ttf\include;$(IncludePath) - $(SolutionDir)lib\sdl\lib\x86;$(SolutionDir)lib\libcurl\lib;$(LibraryPath) + $(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(IncludePath) + $(SolutionDir)lib;$(LibraryPath) $(SolutionDir)bin\ $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ + - $(SolutionDir)lib;$(SolutionDir)lib\libspeex;$(SolutionDir)lib\sdl\include;$(SolutionDir)lib\libcurl\include;$(SolutionDir)lib\jansson;$(SolutionDir)lib\cutest;$(SolutionDir)lib\SDL2_ttf\include;$(IncludePath) - $(SolutionDir)lib\sdl\lib\x86;$(SolutionDir)lib\libcurl\lib;$(LibraryPath) + $(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(IncludePath) + $(SolutionDir)lib;$(LibraryPath) $(SolutionDir)bin\ $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ - - $(SolutionDir)lib;$(SolutionDir)lib\libspeex;$(SolutionDir)lib\sdl\include;$(SolutionDir)lib\libcurl\include;$(SolutionDir)lib\jansson;$(SolutionDir)lib\cutest;$(SolutionDir)lib\SDL2_ttf\include;$(IncludePath) - $(SolutionDir)lib\sdl\lib\x86;$(SolutionDir)lib\libcurl\lib;$(LibraryPath) - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\$(Configuration)\ - - - $(SolutionDir)lib;$(SolutionDir)lib\libspeex;$(SolutionDir)lib\sdl\include;$(SolutionDir)lib\libcurl\include;$(SolutionDir)lib\jansson;$(SolutionDir)lib\cutest;$(SolutionDir)lib\SDL2_ttf\include;$(IncludePath) - $(SolutionDir)lib\sdl\lib\x86;$(SolutionDir)lib\libcurl\lib;$(LibraryPath) - $(SolutionDir)bin\ - $(SolutionDir)obj\$(ProjectName)\Release\ - Level3 Disabled true 1Byte - $(OpenRCT2_DEFINES);DEBUG;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + $(OpenRCT2_DEFINES);DEBUG;USE_LIBPNG;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded true $(IntDir)\%(RelativeDir) @@ -388,7 +340,9 @@ true - winmm.lib;sdl2.lib;%(AdditionalDependencies) + openrct2-libs-vs2015.lib;imm32.lib;version.lib;winmm.lib;%(AdditionalDependencies) + UseFastLinkTimeCodeGeneration + /OPT:NOLBR /ignore:4099 %(AdditionalOptions) @@ -397,16 +351,14 @@ Full true true - - + MultiThreaded 1Byte 4013 - - + false - $(OpenRCT2_DEFINES);_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions) - $(IntDir)fake\%(RelativeDir) + $(OpenRCT2_DEFINES);USE_LIBPNG;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions) + $(IntDir)\%(RelativeDir) true Speed @@ -414,65 +366,10 @@ true true true - winmm.lib;sdl2.lib;%(AdditionalDependencies) - /ignore:4099 %(AdditionalOptions) - - - - - Level3 - Full - true - true - - - MultiThreaded - 1Byte - 4013 - - - false - $(OpenRCT2_DEFINES);DISABLE_NETWORK;DISABLE_HTTP;DISABLE_TWITCH;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions) - $(IntDir)fake\%(RelativeDir) - true - Speed - - - true - true - true - winmm.lib;sdl2.lib;%(AdditionalDependencies) - /ignore:4099 %(AdditionalOptions) - Windows - - - - - Level3 - Disabled - true - true - - - MultiThreaded - 1Byte - 4013 - - - false - $(OpenRCT2_DEFINES);_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;ENABLE_TESTS;%(PreprocessorDefinitions) - $(IntDir)fake\%(RelativeDir) - true - - - true - true - true - winmm.lib;sdl2.lib;%(AdditionalDependencies) + openrct2-libs-vs2015.lib;imm32.lib;version.lib;winmm.lib;%(AdditionalDependencies) /ignore:4099 %(AdditionalOptions) - - + diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters index 1e66838133..72b54f2aeb 100644 --- a/openrct2.vcxproj.filters +++ b/openrct2.vcxproj.filters @@ -56,6 +56,9 @@ {28a808eb-9017-44cc-939b-f828fd1e2e7d} + + {b1a4d0cf-f4a1-4a38-934c-369d4c129a85} + @@ -459,15 +462,6 @@ Source\Windows - - Test - - - Test\Management - - - Test\Ride - Source\Windows @@ -567,6 +561,9 @@ Source\Core + + Source\argparse + @@ -860,5 +857,8 @@ Source\Core + + Source\argparse + diff --git a/openrct2.vcxproj.user b/openrct2.vcxproj.user index fd6680fbf4..fb13b2fbe1 100644 --- a/openrct2.vcxproj.user +++ b/openrct2.vcxproj.user @@ -7,8 +7,6 @@ $(TargetDir)\openrct2.exe WindowsLocalDebugger $(TargetDir) - - $(TargetDir) diff --git a/scripts/linux/build.sh b/scripts/linux/build.sh index 049059f2fa..49d199fb99 100755 --- a/scripts/linux/build.sh +++ b/scripts/linux/build.sh @@ -7,52 +7,56 @@ mkdir -p $cachedir # Sets default target to "linux", if none specified TARGET=${TARGET-linux} +SYSTEM=$(uname -s) if [[ ! -d build ]]; then mkdir -p build fi -# keep in sync with version in install.sh -if [[ $(uname -s) == "Darwin" ]]; then - # keep in sync with version in Xcode project - sha256sum=6562ce9e1f37f125e3345bfd8b961777800436bf607b30dc7c964e0e6991ad2c -else - sha256sum=31c5e19d9f794bd5f0e75f20c2b4c3c4664d736b0a4d50c8cde14a9a9007b62d -fi -libVFile="./libversion" -libdir="./lib" -currentversion=0 -needsdownload="true" - -if [ -f $libVFile ]; then - while read line; do - currentversion=$line - continue - done < $libVFile -fi - -if [ "z$currentversion" == "z$sha256sum" ]; then - needsdownload="false" -fi - -if [ ! -d $libdir ]; then - needsdownload="true" -fi - -if [[ "$needsdownload" = "true" ]]; then - echo "Found library had sha256sum $currentversion, expected $sha256sum" - echo "New libraries need to be downloaded. Clearing cache and calling ./install.sh" - rm -rf ./lib - if [[ -f $cachedir/orctlibs.zip ]]; then - rm -rf $cachedir/orctlibs.zip +if [[ $TARGET != "linux" && $TARGET != "docker32" && $SYSTEM != "Darwin" ]]; then + # keep in sync with version in install.sh + if [[ $SYSTEM == "Darwin" ]]; then + # keep in sync with version in Xcode project + sha256sum=6562ce9e1f37f125e3345bfd8b961777800436bf607b30dc7c964e0e6991ad2c + else + sha256sum=31c5e19d9f794bd5f0e75f20c2b4c3c4664d736b0a4d50c8cde14a9a9007b62d fi - if [[ -d /usr/local/cross-tools/orctlibs ]]; then - sudo rm -rf /usr/local/cross-tools/orctlibs + libVFile="./libversion" + libdir="./lib" + currentversion=0 + needsdownload="true" + + if [ -f $libVFile ]; then + while read line; do + currentversion=$line + continue + done < $libVFile fi - if [[ -d $cachedir/orctlibs ]]; then - rm -rf $cachedir/orctlibs + + if [ "z$currentversion" == "z$sha256sum" ]; then + needsdownload="false" fi - scripts/linux/install.sh + + if [ ! -d $libdir ]; then + needsdownload="true" + fi + + if [[ "$needsdownload" = "true" ]]; then + echo "Found library had sha256sum $currentversion, expected $sha256sum" + echo "New libraries need to be downloaded. Clearing cache and calling ./install.sh" + rm -rf ./lib + if [[ -f $cachedir/orctlibs.zip ]]; then + rm -rf $cachedir/orctlibs.zip + fi + if [[ -d /usr/local/cross-tools/orctlibs ]]; then + sudo rm -rf /usr/local/cross-tools/orctlibs + fi + if [[ -d $cachedir/orctlibs ]]; then + rm -rf $cachedir/orctlibs + fi + scripts/linux/install.sh + fi +# if [[ $TARGET != "linux" && $TARGET != "docker32" && $SYSTEM != "Darwin" ]]; then fi pushd build diff --git a/scripts/linux/install.sh b/scripts/linux/install.sh index c0bde470cd..55806bbbdc 100755 --- a/scripts/linux/install.sh +++ b/scripts/linux/install.sh @@ -193,11 +193,14 @@ elif [[ $(uname) == "Linux" ]]; then fi fi -download_libs -calculate_sha256 "$cachedir/orctlibs.zip" > "$libVFile" -echo "Downloaded library with sha256sum: $(cat "$libVFile")" -# Local libs are required for all targets -install_local_libs +if [[ $TARGET == "windows" || $(uname -s) == "Darwin" ]]; then + download_libs + calculate_sha256 "$cachedir/orctlibs.zip" > "$libVFile" + echo "Downloaded library with sha256sum: $(cat "$libVFile")" + # Local libs are required for all targets + install_local_libs +# $TARGET == "windows" || $(uname -s) == "Darwin" +fi if [[ $TARGET == "windows" ]]; then download_sdl diff --git a/scripts/ps/install.ps1 b/scripts/ps/install.ps1 index e578c731bf..8ca77d1acf 100644 --- a/scripts/ps/install.ps1 +++ b/scripts/ps/install.ps1 @@ -13,13 +13,13 @@ $scriptsPath = Split-Path $Script:MyInvocation.MyCommand.Path Import-Module "$scriptsPath\common.psm1" -DisableNameChecking # Constants -$libsUrl = "https://openrct2.website/files/orctlibs-vs.zip" -$libsVersion = 4 +$libsUrl = "https://openrct2.website/files/openrct2-libs-vs2015.zip" +$libsVersion = 5 # Get paths $rootPath = Get-RootPath $libsPath = Join-Path $rootPath "lib" -$zipPath = Join-Path $libsPath "orctlibs.zip" +$zipPath = Join-Path $libsPath "openrct2-libs-vs2015.zip" $libsVersionPath = Join-Path $libsPath "libversion" # Check if we need to update the dependencies diff --git a/scripts/ps/publish.ps1 b/scripts/ps/publish.ps1 index 07b5f2580a..4e83208408 100644 --- a/scripts/ps/publish.ps1 +++ b/scripts/ps/publish.ps1 @@ -80,7 +80,6 @@ function Do-Package() Copy-Item -Force "$releaseDir\openrct2.exe" $tempDir -ErrorAction Stop Copy-Item -Force "$releaseDir\openrct2.dll" $tempDir -ErrorAction Stop Copy-Item -Force "$releaseDir\curl-ca-bundle.crt" $tempDir -ErrorAction Stop - Copy-Item -Force "$releaseDir\SDL2.dll" $tempDir -ErrorAction Stop Copy-Item -Force "$distDir\changelog.txt" $tempDir -ErrorAction Stop Copy-Item -Force "$distDir\known_issues.txt" $tempDir -ErrorAction Stop Copy-Item -Force "$distDir\readme.txt" $tempDir -ErrorAction Stop diff --git a/src/argparse/argparse.c b/src/argparse/argparse.c new file mode 100644 index 0000000000..e2e14d068f --- /dev/null +++ b/src/argparse/argparse.c @@ -0,0 +1,324 @@ +#include "argparse.h" + +#define OPT_UNSET 1 + +static const char * +prefix_skip(const char *str, const char *prefix) +{ + size_t len = strlen(prefix); + return strncmp(str, prefix, len) ? NULL : str + len; +} + +int +prefix_cmp(const char *str, const char *prefix) +{ + for (;; str++, prefix++) + if (!*prefix) + return 0; + else if (*str != *prefix) + return (unsigned char)*prefix - (unsigned char)*str; +} + +static void +argparse_error(struct argparse *this, const struct argparse_option *opt, + const char *reason) +{ + if (!strncmp(this->argv[0], "--", 2)) { + fprintf(stderr, "error: option `%s` %s\n", opt->long_name, reason); + exit(1); + } else { + fprintf(stderr, "error: option `%c` %s\n", opt->short_name, reason); + exit(1); + } +} + +static int +argparse_getvalue(struct argparse *this, const struct argparse_option *opt, + int flags) +{ + const char *s = NULL; + if (!opt->value) + goto skipped; + switch (opt->type) { + case ARGPARSE_OPT_BOOLEAN: + if (flags & OPT_UNSET) { + *(int *)opt->value = *(int *)opt->value - 1; + } else { + *(int *)opt->value = *(int *)opt->value + 1; + } + if (*(int *)opt->value < 0) { + *(int *)opt->value = 0; + } + break; + case ARGPARSE_OPT_BIT: + if (flags & OPT_UNSET) { + *(int *)opt->value &= ~opt->data; + } else { + *(int *)opt->value |= opt->data; + } + break; + case ARGPARSE_OPT_STRING: + if (this->optvalue) { + *(const char **)opt->value = this->optvalue; + this->optvalue = NULL; + } else if (this->argc > 1) { + this->argc--; + *(const char **)opt->value = *++this->argv; + } else { + argparse_error(this, opt, "requires a value"); + } + break; + case ARGPARSE_OPT_INTEGER: + if (this->optvalue) { + *(int *)opt->value = strtol(this->optvalue, (char **)&s, 0); + this->optvalue = NULL; + } else if (this->argc > 1) { + this->argc--; + *(int *)opt->value = strtol(*++this->argv, (char **)&s, 0); + } else { + argparse_error(this, opt, "requires a value"); + } + if (s[0] != '\0') + argparse_error(this, opt, "expects a numerical value"); + break; + default: + assert(0); + } + +skipped: + if (opt->callback) { + return opt->callback(this, opt); + } + + return 0; +} + +static void +argparse_options_check(const struct argparse_option *options) +{ + for (; options->type != ARGPARSE_OPT_END; options++) { + switch (options->type) { + case ARGPARSE_OPT_END: + case ARGPARSE_OPT_BOOLEAN: + case ARGPARSE_OPT_BIT: + case ARGPARSE_OPT_INTEGER: + case ARGPARSE_OPT_STRING: + case ARGPARSE_OPT_GROUP: + continue; + default: + fprintf(stderr, "wrong option type: %d", options->type); + break; + } + } +} + +static int +argparse_short_opt(struct argparse *this, const struct argparse_option *options) +{ + for (; options->type != ARGPARSE_OPT_END; options++) { + if (options->short_name == *this->optvalue) { + this->optvalue = this->optvalue[1] ? this->optvalue + 1 : NULL; + return argparse_getvalue(this, options, 0); + } + } + return -2; +} + +static int +argparse_long_opt(struct argparse *this, const struct argparse_option *options) +{ + for (; options->type != ARGPARSE_OPT_END; options++) { + const char *rest; + int opt_flags = 0; + if (!options->long_name) + continue; + + rest = prefix_skip(this->argv[0] + 2, options->long_name); + if (!rest) { + // Negation allowed? + if (options->flags & OPT_NONEG) { + continue; + } + // Only boolean/bit allow negation. + if (options->type != ARGPARSE_OPT_BOOLEAN && options->type != ARGPARSE_OPT_BIT) { + continue; + } + + if (!prefix_cmp(this->argv[0] + 2, "no-")) { + rest = prefix_skip(this->argv[0] + 2 + 3, options->long_name); + if (!rest) + continue; + opt_flags |= OPT_UNSET; + } else { + continue; + } + } + if (*rest) { + if (*rest != '=') + continue; + this->optvalue = rest + 1; + } + return argparse_getvalue(this, options, opt_flags); + } + return -2; +} + +int +argparse_init(struct argparse *this, struct argparse_option *options, + const char *const *usage, int flags) +{ + memset(this, 0, sizeof(*this)); + this->options = options; + this->usage = usage; + this->flags = flags; + return 0; +} + +int +argparse_parse(struct argparse *this, int argc, const char **argv) +{ + this->argc = argc - 1; + this->argv = argv + 1; + this->out = argv; + + argparse_options_check(this->options); + + for (; this->argc; this->argc--, this->argv++) { + const char *arg = this->argv[0]; + if (arg[0] != '-' || !arg[1]) { + if (this->flags & ARGPARSE_STOP_AT_NON_OPTION) { + goto end; + } + // if it's not option or is a single char '-', copy verbatimly + this->out[this->cpidx++] = this->argv[0]; + continue; + } + // short option + if (arg[1] != '-') { + this->optvalue = arg + 1; + switch (argparse_short_opt(this, this->options)) { + case -1: + break; + case -2: + goto unknown; + } + while (this->optvalue) { + switch (argparse_short_opt(this, this->options)) { + case -1: + break; + case -2: + goto unknown; + } + } + continue; + } + // if '--' presents + if (!arg[2]) { + this->argc--; + this->argv++; + break; + } + // long option + switch (argparse_long_opt(this, this->options)) { + case -1: + break; + case -2: + goto unknown; + } + continue; + +unknown: + fprintf(stderr, "error: unknown option `%s`\n", this->argv[0]); + argparse_usage(this); + exit(1); + } + +end: + memmove((void*)(this->out + this->cpidx), + this->argv, + this->argc * sizeof(*this->out)); + this->out[this->cpidx + this->argc] = NULL; + + return this->cpidx + this->argc; +} + +void +argparse_usage(struct argparse *this) +{ + fprintf(stdout, "Usage: %s\n", *this->usage++); + while (*this->usage && **this->usage) + fprintf(stdout, " or: %s\n", *this->usage++); + fputc('\n', stdout); + + const struct argparse_option *options; + + // figure out best width + size_t usage_opts_width = 0; + size_t len; + options = this->options; + for (; options->type != ARGPARSE_OPT_END; options++) { + len = 0; + if ((options)->short_name) { + len += 2; + } + if ((options)->short_name && (options)->long_name) { + len += 2; // separator ", " + } + if ((options)->long_name) { + len += strlen((options)->long_name) + 2; + } + if (options->type == ARGPARSE_OPT_INTEGER) { + len += strlen("="); + } else if (options->type == ARGPARSE_OPT_STRING) { + len += strlen("="); + } + len = ((len + 3) / 4) * 4; + if (usage_opts_width < len) { + usage_opts_width = len; + } + } + usage_opts_width += 4; // 4 spaces prefix + + options = this->options; + for (; options->type != ARGPARSE_OPT_END; options++) { + size_t pos = 0; + int pad = 0; + if (options->type == ARGPARSE_OPT_GROUP) { + fputc('\n', stdout); + pos += fprintf(stdout, "%s", options->help); + fputc('\n', stdout); + continue; + } + pos = fprintf(stdout, " "); + if (options->short_name) { + pos += fprintf(stdout, "-%c", options->short_name); + } + if (options->long_name && options->short_name) { + pos += fprintf(stdout, ", "); + } + if (options->long_name) { + pos += fprintf(stdout, "--%s", options->long_name); + } + if (options->type == ARGPARSE_OPT_INTEGER) { + pos += fprintf(stdout, "="); + } else if (options->type == ARGPARSE_OPT_STRING) { + pos += fprintf(stdout, "="); + } + if (pos <= usage_opts_width) { + pad = usage_opts_width - pos; + } else { + fputc('\n', stdout); + pad = usage_opts_width; + } + fprintf(stdout, "%*s%s\n", pad + 2, "", options->help); + } +} + +int +argparse_help_cb(struct argparse *this, const struct argparse_option *option) +{ + (void)option; + argparse_usage(this); + exit(0); + return 0; +} diff --git a/src/argparse/argparse.h b/src/argparse/argparse.h new file mode 100644 index 0000000000..350ee58df4 --- /dev/null +++ b/src/argparse/argparse.h @@ -0,0 +1,132 @@ +#ifndef ARGPARSE_H +#define ARGPARSE_H +/** + * Command-line arguments parsing library. + * + * This module is inspired by parse-options.c (git) and python's argparse + * module. + * + * Arguments parsing is common task in cli program, but traditional `getopt` + * libraries are not easy to use. This library provides high-level arguments + * parsing solutions. + * + * The program defines what arguments it requires, and `argparse` will figure + * out how to parse those out of `argc` and `argv`, it also automatically + * generates help and usage messages and issues errors when users give the + * program invalid arguments. + * + * Reserved namespaces: + * argparse + * OPT + * Author: Yecheng Fu + */ + +#include +#include +#include +#include +#include +#include + +struct argparse; +struct argparse_option; + +typedef int argparse_callback(struct argparse *this, + const struct argparse_option *option); + +enum argparse_flag { + ARGPARSE_STOP_AT_NON_OPTION = 1, +}; + +enum argparse_option_type { + /* special */ + ARGPARSE_OPT_END, + ARGPARSE_OPT_GROUP, + /* options with no arguments */ + ARGPARSE_OPT_BOOLEAN, + ARGPARSE_OPT_BIT, + /* options with arguments (optional or required) */ + ARGPARSE_OPT_INTEGER, + ARGPARSE_OPT_STRING, +}; + +enum argparse_option_flags { + OPT_NONEG = 1, /* Negation disabled. */ +}; + +/* + * Argparse option struct. + * + * `type`: + * holds the type of the option, you must have an ARGPARSE_OPT_END last in your + * array. + * + * `short_name`: + * the character to use as a short option name, '\0' if none. + * + * `long_name`: + * the long option name, without the leading dash, NULL if none. + * + * `value`: + * stores pointer to the value to be filled. + * + * `help`: + * the short help message associated to what the option does. + * Must never be NULL (except for ARGPARSE_OPT_END). + * + * `callback`: + * function is called when corresponding argument is parsed. + * + * `data`: + * associated data. Callbacks can use it like they want. + * + * `flags`: + * option flags. + * + */ +struct argparse_option { + enum argparse_option_type type; + const char short_name; + const char *long_name; + void *value; + const char *help; + argparse_callback *callback; + intptr_t data; + int flags; +}; + +/* + * argpparse + */ +struct argparse { + // user supplied + const struct argparse_option *options; + const char *const *usage; + int flags; + // internal context + int argc; + const char **argv; + const char **out; + int cpidx; + const char *optvalue; // current option value +}; + +// builtin callbacks +int argparse_help_cb(struct argparse *this, + const struct argparse_option *option); + +// builtin option macros +#define OPT_END() { ARGPARSE_OPT_END } +#define OPT_BOOLEAN(...) { ARGPARSE_OPT_BOOLEAN, __VA_ARGS__ } +#define OPT_BIT(...) { ARGPARSE_OPT_BIT, __VA_ARGS__ } +#define OPT_INTEGER(...) { ARGPARSE_OPT_INTEGER, __VA_ARGS__ } +#define OPT_STRING(...) { ARGPARSE_OPT_STRING, __VA_ARGS__ } +#define OPT_GROUP(h) { ARGPARSE_OPT_GROUP, 0, NULL, NULL, h, NULL } +#define OPT_HELP() OPT_BOOLEAN('h', "help", NULL, "show this help message and exit", argparse_help_cb) + +int argparse_init(struct argparse *this, struct argparse_option *options, + const char *const *usage, int flags); +int argparse_parse(struct argparse *this, int argc, const char **argv); +void argparse_usage(struct argparse *this); + +#endif diff --git a/src/cmdline.c b/src/cmdline.c index 003f6faba4..d2cb65b1fa 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -19,7 +19,7 @@ *****************************************************************************/ #include -#include +#include "argparse/argparse.h" #include "addresses.h" #include "cmdline.h" #include "interface/screenshot.h" @@ -108,7 +108,7 @@ int cmdline_run(const char **argv, int argc) */ int k=0; for (int i=0; i < argc; ++i) - if (strcmp(argv[k], "-NSDocumentRevisionsDebugMode") != 0) + if (strcmp(argv[k], "-NSDocumentRevisionsDebugMode") != 0 && strncmp(argv[k], "-psn_", 5) != 0) mutableArgv[k++] = (char *) argv[i]; argc = k; #else diff --git a/src/config.c b/src/config.c index 8ff2ccced9..3dacc4bf5f 100644 --- a/src/config.c +++ b/src/config.c @@ -331,6 +331,11 @@ static void rwopswritec(SDL_RWops *file, char c) SDL_RWwrite(file, &c, 1, 1); } +static void rwopswritestr(SDL_RWops *file, const char *str) +{ + SDL_RWwrite(file, str, strlen(str), 1); +} + static void rwopsprintf(SDL_RWops *file, const char *format, ...) { va_list args; @@ -344,6 +349,11 @@ static void rwopsprintf(SDL_RWops *file, const char *format, ...) va_end(args); } +static void rwopswritenewline(SDL_RWops *file) +{ + rwopswritestr(file, platform_get_new_line()); +} + void config_set_defaults() { int i, j; @@ -478,24 +488,24 @@ bool config_save(const utf8string path) config_section_definition *section = &_sectionDefinitions[i]; rwopswritec(file, '['); - SDL_RWwrite(file, section->section_name, strlen(section->section_name), 1); + rwopswritestr(file, section->section_name); rwopswritec(file, ']'); - rwopswritec(file, '\n'); + rwopswritenewline(file); for (j = 0; j < section->property_definitions_count; j++) { config_property_definition *property = §ion->property_definitions[j]; - SDL_RWwrite(file, property->property_name, strlen(property->property_name), 1); - SDL_RWwrite(file, " = ", 3, 1); + rwopswritestr(file, property->property_name); + rwopswritestr(file, " = "); value = (value_union*)((size_t)section->base_address + (size_t)property->offset); if (property->enum_definitions != NULL) config_write_enum(file, property->type, value, property->enum_definitions); else config_save_property_value(file, property->type, value); - rwopswritec(file, '\n'); + rwopswritenewline(file); } - rwopswritec(file, '\n'); + rwopswritenewline(file); } SDL_RWclose(file); @@ -506,8 +516,8 @@ static void config_save_property_value(SDL_RWops *file, uint8 type, value_union { switch (type) { case CONFIG_VALUE_TYPE_BOOLEAN: - if (value->value_boolean) SDL_RWwrite(file, "true", 4, 1); - else SDL_RWwrite(file, "false", 5, 1); + if (value->value_boolean) rwopswritestr(file, "true"); + else rwopswritestr(file, "false"); break; case CONFIG_VALUE_TYPE_UINT8: rwopsprintf(file, "%u", value->value_uint8); @@ -535,8 +545,9 @@ static void config_save_property_value(SDL_RWops *file, uint8 type, value_union break; case CONFIG_VALUE_TYPE_STRING: rwopswritec(file, '"'); - if (value->value_string != NULL) - SDL_RWwrite(file, value->value_string, strlen(value->value_string), 1); + if (value->value_string != NULL) { + rwopswritestr(file, value->value_string); + } rwopswritec(file, '"'); break; } @@ -728,7 +739,7 @@ static void config_write_enum(SDL_RWops *file, uint8 type, value_union *value, c uint32 enumValue = (value->value_uint32) & ((1 << (_configValueTypeSize[type] * 8)) - 1); while (enumDefinitions->key != NULL) { if (enumDefinitions->value.value_uint32 == enumValue) { - SDL_RWwrite(file, enumDefinitions->key, strlen(enumDefinitions->key), 1); + rwopswritestr(file, enumDefinitions->key); return; } enumDefinitions++; @@ -1231,15 +1242,15 @@ static bool themes_save(const_utf8string path, int preset) theme_section_definition *section = &_themeSectionDefinitions[i]; rwopswritec(file, '['); - SDL_RWwrite(file, section->section_name, strlen(section->section_name), 1); + rwopswritestr(file, section->section_name); rwopswritec(file, ']'); - rwopswritec(file, '\n'); + rwopswritenewline(file); for (j = 0; j < section->property_definitions_count; j++) { theme_property_definition *property = §ion->property_definitions[j]; - SDL_RWwrite(file, property->property_name, strlen(property->property_name), 1); - SDL_RWwrite(file, " = ", 3, 1); + rwopswritestr(file, property->property_name); + rwopswritestr(file, " = "); value = (value_union*)((size_t)&gConfigThemes.presets[preset] + (size_t)section->offset + (size_t)property->offset); @@ -1247,24 +1258,24 @@ static bool themes_save(const_utf8string path, int preset) config_write_enum(file, property->type, value, property->enum_definitions); else config_save_property_value(file, property->type, value); - rwopswritec(file, '\n'); + rwopswritenewline(file); } - rwopswritec(file, '\n'); + rwopswritenewline(file); } for (i = 0; i < (int)gNumThemeWindows; i++) { theme_section_definition *section = &_themeSectionDefinitions[0]; rwopswritec(file, '['); - SDL_RWwrite(file, gThemeWindowDefinitions[i].section_name, strlen(gThemeWindowDefinitions[i].section_name), 1); + rwopswritestr(file, gThemeWindowDefinitions[i].section_name); rwopswritec(file, ']'); - rwopswritec(file, '\n'); + rwopswritenewline(file); for (j = 0; j < section->property_definitions_count; j++) { theme_property_definition *property = §ion->property_definitions[j]; - SDL_RWwrite(file, property->property_name, strlen(property->property_name), 1); - SDL_RWwrite(file, " = ", 3, 1); + rwopswritestr(file, property->property_name); + rwopswritestr(file, " = "); value = (value_union*)((size_t)gConfigThemes.presets[preset].windows + (size_t)(sizeof(theme_window) * i) + (size_t)property->offset); @@ -1272,7 +1283,7 @@ static bool themes_save(const_utf8string path, int preset) config_write_enum(file, property->type, value, property->enum_definitions); else config_save_property_value(file, property->type, value); - rwopswritec(file, '\n'); + rwopswritenewline(file); } } @@ -1627,33 +1638,34 @@ void title_sequence_save_preset_script(int preset) switch (command->command) { case TITLE_SCRIPT_LOAD: if (command->saveIndex == 0xFF) - rwopsprintf(file, "LOAD \r\n"); + rwopsprintf(file, "LOAD "); else - rwopsprintf(file, "LOAD %s\r\n", gConfigTitleSequences.presets[preset].saves[command->saveIndex]); + rwopsprintf(file, "LOAD %s", gConfigTitleSequences.presets[preset].saves[command->saveIndex]); break; case TITLE_SCRIPT_LOCATION: - rwopsprintf(file, "LOCATION %i %i\r\n", command->x, command->y); + rwopsprintf(file, "LOCATION %i %i", command->x, command->y); break; case TITLE_SCRIPT_ROTATE: - rwopsprintf(file, "ROTATE %i\r\n", command->rotations); + rwopsprintf(file, "ROTATE %i", command->rotations); break; case TITLE_SCRIPT_ZOOM: - rwopsprintf(file, "ZOOM %i\r\n", command->zoom); + rwopsprintf(file, "ZOOM %i", command->zoom); break; case TITLE_SCRIPT_SPEED: - rwopsprintf(file, "SPEED %i\r\n", command->speed); + rwopsprintf(file, "SPEED %i", command->speed); break; case TITLE_SCRIPT_WAIT: - rwopsprintf(file, "WAIT %i\r\n\r\n", command->seconds); + rwopsprintf(file, "WAIT %i", command->seconds); + rwopswritenewline(file); break; case TITLE_SCRIPT_RESTART: - rwopsprintf(file, "RESTART\r\n"); + rwopsprintf(file, "RESTART"); break; case TITLE_SCRIPT_END: - rwopsprintf(file, "END\r\n"); + rwopsprintf(file, "END"); break; - } + rwopswritenewline(file); } SDL_RWclose(file); diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index d08d0a9c4a..d5369a1f9e 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -1835,6 +1835,10 @@ enum { STR_OBJECTIVE = 3322, + STR_MISSING_OBJECT_DATA_ID = 3323, + STR_REQUIRES_THE_FOLLOWING_ADDON_PACK = 3324, + STR_REQUIRES_AN_ADDON_PACK = 3325, + STR_PEEP_SPAWNS_NOT_SET = 3327, STR_CANT_ADVANCE_TO_NEXT_EDITOR_STAGE = 3328, STR_NO_PARK_ENTRANCES = 3329, diff --git a/src/object_list.c b/src/object_list.c index 5702007235..4a62fe98fc 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -484,16 +484,20 @@ void object_create_identifier_name(char* string_buffer, const rct_object_entry* * * rct2: 0x675827 */ -void set_load_objects_fail_reason(){ +void set_load_objects_fail_reason() +{ + rct_string_id expansionNameId; + rct_object_entry* object = RCT2_ADDRESS(0x13CE952, rct_object_entry); int expansion = (object->flags & 0xFF) >> 4; + if (expansion == 0 || expansion == 8 || RCT2_GLOBAL(0x9AB4C0, uint16) & (1 << expansion)){ char* string_buffer = RCT2_ADDRESS(0x9BC677, char); - format_string(string_buffer, 3323, 0); //Missing object data, ID: + format_string(string_buffer, STR_MISSING_OBJECT_DATA_ID, 0); object_create_identifier_name(string_buffer, object); RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; @@ -501,17 +505,23 @@ void set_load_objects_fail_reason(){ return; } - char* exapansion_name = &RCT2_ADDRESS(RCT2_ADDRESS_EXPANSION_NAMES, char)[128 * expansion]; - if (*exapansion_name == '\0'){ - RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; - RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3325; - return; + switch(expansion) { + case 1: // Wacky Worlds + expansionNameId = STR_OBJECT_FILTER_WW; + break; + case 2: // Time Twister + expansionNameId = STR_OBJECT_FILTER_TT; + break; + default: + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = STR_REQUIRES_AN_ADDON_PACK; + return; } char* string_buffer = RCT2_ADDRESS(0x9BC677, char); - format_string(string_buffer, 3324, 0); // Requires expansion pack - strcat(string_buffer, exapansion_name); + format_string(string_buffer, STR_REQUIRES_THE_FOLLOWING_ADDON_PACK, &expansionNameId); + RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165; } diff --git a/src/platform/platform.h b/src/platform/platform.h index 026e6df020..8b2b59acca 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -125,6 +125,7 @@ void platform_get_time(rct2_time *out_time); // Platform specific definitions void platform_get_exe_path(utf8 *outPath); +const char *platform_get_new_line(); char platform_get_path_separator(); bool platform_file_exists(const utf8 *path); bool platform_directory_exists(const utf8 *path); diff --git a/src/platform/posix.c b/src/platform/posix.c index 04c74fb054..cf9141a0fb 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -91,6 +91,11 @@ char platform_get_path_separator() return '/'; } +const char *platform_get_new_line() +{ + return "\n"; +} + bool platform_file_exists(const utf8 *path) { wchar_t *wPath = utf8_to_widechar(path); diff --git a/src/platform/windows.c b/src/platform/windows.c index 7069950c18..9709de3e46 100644 --- a/src/platform/windows.c +++ b/src/platform/windows.c @@ -148,6 +148,11 @@ char platform_get_path_separator() return '\\'; } +const char *platform_get_new_line() +{ + return "\r\n"; +} + bool platform_file_exists(const utf8 *path) { wchar_t *wPath = utf8_to_widechar(path); diff --git a/src/ride/ride.c b/src/ride/ride.c index f95f3001cb..dcb0462ddc 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -5766,95 +5766,115 @@ void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi */ void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) { - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - uint8 ride_id = *edx; - uint8 type = *ebx >> 8; - uint8 value = *edx >> 8; - int index = *edi; - if (index < 0) { + bool apply = (*ebx & GAME_COMMAND_FLAG_APPLY); + + uint8 ride_id = *edx; + uint8 type = *ebx >> 8; + uint8 value = *edx >> 8; + int index = *edi; + + if (index < 0) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } + + rct_ride *ride = GET_RIDE(ride_id); + if (ride->type == RIDE_TYPE_NULL) { + log_warning("Invalid game command, ride_id = %u", ride_id); + *ebx = MONEY32_UNDEFINED; + return; + } + + *ebx = 0; + switch(type) { + case 0: + if (index >= countof(ride->track_colour_main)) { log_warning("Invalid game command, index %d out of bounds", index); *ebx = MONEY32_UNDEFINED; return; } - rct_ride *ride = GET_RIDE(ride_id); - if (ride->type == RIDE_TYPE_NULL) { - log_warning("Invalid game command, ride_id = %u", ride_id); + if (apply) { + ride->track_colour_main[index] = value; + gfx_invalidate_screen(); + } + break; + case 1: + if (index >= countof(ride->track_colour_additional)) { + log_warning("Invalid game command, index %d out of bounds", index); *ebx = MONEY32_UNDEFINED; return; } - *ebx = 0; - switch(type){ - case 0: - if (index >= countof(ride->track_colour_main)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } - ride->track_colour_main[index] = value; - gfx_invalidate_screen(); - break; - case 1: - if (index >= countof(ride->track_colour_additional)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } - ride->track_colour_additional[index] = value; - gfx_invalidate_screen(); - break; - case 2: - if (index >= countof(ride->vehicle_colours)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } - *((uint8*)(&ride->vehicle_colours[index])) = value; - ride_update_vehicle_colours(ride_id); - break; - case 3: - if (index >= countof(ride->vehicle_colours)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } - *((uint8*)(&ride->vehicle_colours[index]) + 1) = value; - ride_update_vehicle_colours(ride_id); - break; - case 4: - if (index >= countof(ride->track_colour_supports)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } - ride->track_colour_supports[index] = value; - gfx_invalidate_screen(); - break; - case 5: - ride->colour_scheme_type &= ~(RIDE_COLOUR_SCHEME_DIFFERENT_PER_TRAIN | RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR); - ride->colour_scheme_type |= value; - for(int i = 1; i < countof(ride->vehicle_colours); i++){ - ride->vehicle_colours[i] = ride->vehicle_colours[0]; - ride->vehicle_colours_extended[i] = ride->vehicle_colours_extended[0]; - } - ride_update_vehicle_colours(ride_id); - break; - case 6: - ride->entrance_style = value; - RCT2_GLOBAL(0x01358840, uint8) = value; - gfx_invalidate_screen(); - break; - case 7: - if (index >= countof(ride->vehicle_colours_extended)) { - log_warning("Invalid game command, index %d out of bounds", index); - *ebx = MONEY32_UNDEFINED; - break; - } + if (apply) { + ride->track_colour_additional[index] = value; + gfx_invalidate_screen(); + } + break; + case 2: + if (index >= countof(ride->vehicle_colours)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } + if (apply) { + *((uint8*)(&ride->vehicle_colours[index])) = value; + ride_update_vehicle_colours(ride_id); + } + break; + case 3: + if (index >= countof(ride->vehicle_colours)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } + if (apply) { + *((uint8*)(&ride->vehicle_colours[index]) + 1) = value; + ride_update_vehicle_colours(ride_id); + } + break; + case 4: + if (index >= countof(ride->track_colour_supports)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } + if (apply) { + ride->track_colour_supports[index] = value; + gfx_invalidate_screen(); + } + break; + case 5: + if (apply) { + ride->colour_scheme_type &= ~(RIDE_COLOUR_SCHEME_DIFFERENT_PER_TRAIN | RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR); + ride->colour_scheme_type |= value; + for (int i = 1; i < countof(ride->vehicle_colours); i++) { + ride->vehicle_colours[i] = ride->vehicle_colours[0]; + ride->vehicle_colours_extended[i] = ride->vehicle_colours_extended[0]; + } + ride_update_vehicle_colours(ride_id); + } + break; + case 6: + if (apply) { + ride->entrance_style = value; + RCT2_GLOBAL(0x01358840, uint8) = value; + gfx_invalidate_screen(); + } + break; + case 7: + if (index >= countof(ride->vehicle_colours_extended)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } else { + if (apply) { ride->vehicle_colours_extended[index] = value; ride_update_vehicle_colours(ride_id); - break; + } } - window_invalidate_by_number(WC_RIDE, ride_id); + break; } + window_invalidate_by_number(WC_RIDE, ride_id); } /** diff --git a/src/windows/guest_list.c b/src/windows/guest_list.c index f4989979c0..46c3aa4cd1 100644 --- a/src/windows/guest_list.c +++ b/src/windows/guest_list.c @@ -572,10 +572,11 @@ static void window_guest_list_invalidate(rct_window *w) window_guest_list_widgets[WIDX_TITLE].right = w->width - 2; window_guest_list_widgets[WIDX_CLOSE].left = w->width - 13; window_guest_list_widgets[WIDX_CLOSE].right = w->width - 3; - window_guest_list_widgets[WIDX_GUEST_LIST].right = w->width - 4; window_guest_list_widgets[WIDX_GUEST_LIST].bottom = w->height - 15; window_guest_list_widgets[WIDX_PAGE_DROPDOWN].image = _window_guest_list_selected_page + 3440; + window_guest_list_widgets[WIDX_TRACKING].left = 321 - 350 + w->width; + window_guest_list_widgets[WIDX_TRACKING].right = 344 - 350 + w->width; } /** diff --git a/src/windows/staff_list.c b/src/windows/staff_list.c index d1c9fc1825..0a8d675814 100644 --- a/src/windows/staff_list.c +++ b/src/windows/staff_list.c @@ -104,26 +104,31 @@ enum WINDOW_STAFF_LIST_WIDGET_IDX { WIDX_STAFF_LIST_LIST, WIDX_STAFF_LIST_UNIFORM_COLOR_PICKER, WIDX_STAFF_LIST_HIRE_BUTTON, + WIDX_STAFF_LIST_QUICK_FIRE, WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON, WIDX_STAFF_LIST_MAP, - WIDX_STAFF_LIST_QUICK_FIRE, }; +#define WW 320 +#define WH 270 +#define MAX_WW 500 +#define MAX_WH 450 + static rct_widget window_staff_list_widgets[] = { - { WWT_FRAME, 0, 0, 319, 0, 269, 0x0FFFFFFFF, STR_NONE }, // panel / background - { WWT_CAPTION, 0, 1, 318, 1, 14, STR_STAFF, STR_WINDOW_TITLE_TIP }, // title bar - { WWT_CLOSEBOX, 0, 307, 317, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close button - { WWT_RESIZE, 1, 0, 319, 43, 269, 0x0FFFFFFFF, STR_NONE }, // tab content panel - { WWT_TAB, 1, 3, 33, 17, 43, 0x02000144E, STR_STAFF_HANDYMEN_TAB_TIP }, // handymen tab - { WWT_TAB, 1, 34, 64, 17, 43, 0x02000144E, STR_STAFF_MECHANICS_TAB_TIP }, // mechanics tab - { WWT_TAB, 1, 65, 95, 17, 43, 0x02000144E, STR_STAFF_SECURITY_TAB_TIP }, // security guards tab - { WWT_TAB, 1, 96, 126, 17, 43, 0x02000144E, STR_STAFF_ENTERTAINERS_TAB_TIP }, // entertainers tab - { WWT_SCROLL, 1, 3, 316, 72, 266, 3, STR_NONE }, // staff list - { WWT_COLORBTN, 1, 130, 141, 58, 69, STR_NONE, STR_UNIFORM_COLOUR_TIP }, // uniform color picker - { WWT_DROPDOWN_BUTTON, 0, 165, 309, 17, 29, STR_NONE, STR_HIRE_STAFF_TIP }, // hire button - { WWT_FLATBTN, 1, 267, 290, 46, 69, 5175, STR_SHOW_PATROL_AREA_TIP }, // show staff patrol area tool - { WWT_FLATBTN, 1, 291, 314, 46, 69, 5192, STR_SHOW_STAFF_ON_MAP_TIP }, // show staff on map button - { WWT_FLATBTN, 1, 243, 266, 46, 69, SPR_DEMOLISH, 5300 }, // quick fire staff + { WWT_FRAME, 0, 0, 319, 0, 269, 0x0FFFFFFFF, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 318, 1, 14, STR_STAFF, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 307, 317, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close button + { WWT_RESIZE, 1, 0, 319, 43, 269, 0x0FFFFFFFF, STR_NONE }, // tab content panel + { WWT_TAB, 1, 3, 33, 17, 43, 0x02000144E, STR_STAFF_HANDYMEN_TAB_TIP }, // handymen tab + { WWT_TAB, 1, 34, 64, 17, 43, 0x02000144E, STR_STAFF_MECHANICS_TAB_TIP }, // mechanics tab + { WWT_TAB, 1, 65, 95, 17, 43, 0x02000144E, STR_STAFF_SECURITY_TAB_TIP }, // security guards tab + { WWT_TAB, 1, 96, 126, 17, 43, 0x02000144E, STR_STAFF_ENTERTAINERS_TAB_TIP }, // entertainers tab + { WWT_SCROLL, 1, 3, 316, 72, 266, 3, STR_NONE }, // staff list + { WWT_COLORBTN, 1, 130, 141, 58, 69, STR_NONE, STR_UNIFORM_COLOUR_TIP }, // uniform color picker + { WWT_DROPDOWN_BUTTON, 0, WW - 155, WW - 11, 17, 29, STR_NONE, STR_HIRE_STAFF_TIP }, // hire button + { WWT_FLATBTN, 1, WW - 77, WW - 54, 46, 69, SPR_DEMOLISH, 5300 }, // quick fire staff + { WWT_FLATBTN, 1, WW - 53, WW - 30, 46, 69, 5175, STR_SHOW_PATROL_AREA_TIP }, // show staff patrol area tool + { WWT_FLATBTN, 1, WW - 29, WW - 6, 46, 69, 5192, STR_SHOW_STAFF_ON_MAP_TIP }, // show staff on map button { WIDGETS_END }, }; @@ -152,7 +157,7 @@ void window_staff_list_open() if (window != NULL) return; - window = window_create_auto_pos(320, 270, &window_staff_list_events, WC_STAFF_LIST, WF_10 | WF_RESIZABLE); + window = window_create_auto_pos(WW, WH, &window_staff_list_events, WC_STAFF_LIST, WF_10 | WF_RESIZABLE); window->widgets = window_staff_list_widgets; window->enabled_widgets = (1 << WIDX_STAFF_LIST_CLOSE) | @@ -171,10 +176,10 @@ void window_staff_list_open() window->list_information_type = 0; window_staff_list_widgets[WIDX_STAFF_LIST_UNIFORM_COLOR_PICKER].type = WWT_EMPTY; - window->min_width = 320; - window->min_height = 270; - window->max_width = 500; - window->max_height = 450; + window->min_width = WW; + window->min_height = WH; + window->max_width = MAX_WW; + window->max_height = MAX_WH; _quick_fire_mode = false; } @@ -240,8 +245,8 @@ static void window_staff_list_mouseup(rct_window *w, int widgetIndex) */ static void window_staff_list_resize(rct_window *w) { - w->min_width = 320; - w->min_height = 270; + w->min_width = WW; + w->min_height = WH; if (w->width < w->min_width) { w->width = w->min_width; window_invalidate(w); @@ -308,13 +313,11 @@ void window_staff_list_update(rct_window *w) } else { widget_invalidate(w, WIDX_STAFF_LIST_HANDYMEN_TAB + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)); RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS, uint16) |= (1 << 2); - FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->type == PEEP_TYPE_STAFF) { - peep->list_flags &= ~(PEEP_LIST_FLAGS_FLASHING); + FOR_ALL_STAFF(spriteIndex, peep) { + peep->list_flags &= ~(PEEP_LIST_FLAGS_FLASHING); - if (peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) { - peep->list_flags |= PEEP_LIST_FLAGS_FLASHING; - } + if (peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) { + peep->list_flags |= PEEP_LIST_FLAGS_FLASHING; } } } @@ -401,8 +404,8 @@ void window_staff_list_scrollgetsize(rct_window *w, int scrollIndex, int *width, rct_peep *peep; uint16 staffCount = 0; - FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) + FOR_ALL_STAFF(spriteIndex, peep) { + if (peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) staffCount++; } @@ -435,10 +438,7 @@ void window_staff_list_scrollmousedown(rct_window *w, int scrollIndex, int x, in rct_peep *peep; i = y / 10; - FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->type != PEEP_TYPE_STAFF) - continue; - + FOR_ALL_STAFF(spriteIndex, peep) { if (peep->staff_type != RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) continue; @@ -490,7 +490,7 @@ void window_staff_list_invalidate(rct_window *w) uint8 tabIndex = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); uint8 widgetIndex = tabIndex + 4; - w->pressed_widgets = pressed_widgets | (1 << widgetIndex); + w->pressed_widgets = pressed_widgets | (1ULL << widgetIndex); window_staff_list_widgets[WIDX_STAFF_LIST_HIRE_BUTTON].image = STR_HIRE_HANDYMAN + tabIndex; window_staff_list_widgets[WIDX_STAFF_LIST_UNIFORM_COLOR_PICKER].type = WWT_EMPTY; @@ -501,9 +501,9 @@ void window_staff_list_invalidate(rct_window *w) 0x600013C3; } if (_quick_fire_mode) - w->pressed_widgets |= (1 << WIDX_STAFF_LIST_QUICK_FIRE); + w->pressed_widgets |= (1ULL << WIDX_STAFF_LIST_QUICK_FIRE); else - w->pressed_widgets &= ~(1 << WIDX_STAFF_LIST_QUICK_FIRE); + w->pressed_widgets &= ~(1ULL << WIDX_STAFF_LIST_QUICK_FIRE); window_staff_list_widgets[WIDX_STAFF_LIST_BACKGROUND].right = w->width - 1; window_staff_list_widgets[WIDX_STAFF_LIST_BACKGROUND].bottom = w->height - 1; @@ -514,6 +514,14 @@ void window_staff_list_invalidate(rct_window *w) window_staff_list_widgets[WIDX_STAFF_LIST_CLOSE].right = w->width - 2 - 0x0B + 0x0A; window_staff_list_widgets[WIDX_STAFF_LIST_LIST].right = w->width - 4; window_staff_list_widgets[WIDX_STAFF_LIST_LIST].bottom = w->height - 0x0F; + window_staff_list_widgets[WIDX_STAFF_LIST_QUICK_FIRE].left = w->width - 77; + window_staff_list_widgets[WIDX_STAFF_LIST_QUICK_FIRE].right = w->width - 54; + window_staff_list_widgets[WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON].left = w->width - 53; + window_staff_list_widgets[WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON].right = w->width - 30; + window_staff_list_widgets[WIDX_STAFF_LIST_MAP].left = w->width - 29; + window_staff_list_widgets[WIDX_STAFF_LIST_MAP].right = w->width - 6; + window_staff_list_widgets[WIDX_STAFF_LIST_HIRE_BUTTON].left = w->width - 155; + window_staff_list_widgets[WIDX_STAFF_LIST_HIRE_BUTTON].right = w->width - 11; } /** @@ -591,7 +599,7 @@ void window_staff_list_paint(rct_window *w, rct_drawpixelinfo *dpi) if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) { RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint32) = RCT2_ADDRESS(0x00992A00, uint16)[selectedTab]; - gfx_draw_string_left(dpi, 1858, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, w->x + 0xA5, w->y + 0x20); + gfx_draw_string_left(dpi, 1858, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, w->x + w->width - 155, w->y + 0x20); } if (selectedTab < 3) { @@ -626,8 +634,8 @@ void window_staff_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int sc y = 0; i = 0; selectedTab = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); - FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == selectedTab) { + FOR_ALL_STAFF(spriteIndex, peep) { + if (peep->staff_type == selectedTab) { if (y > dpi->y + dpi->height) { break; } diff --git a/src/world/map.c b/src/world/map.c index 6d75247f9c..f407d0663f 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1601,7 +1601,8 @@ static money32 map_set_land_height(int flags, int x, int y, int height, int styl if(flags & GAME_COMMAND_FLAG_APPLY) { footpath_remove_litter(x, y, map_element_height(x, y)); - map_remove_walls_at(x, y, height * 8 - 16, height * 8 + 32); + if(!gCheatsDisableClearanceChecks) + map_remove_walls_at(x, y, height * 8 - 16, height * 8 + 32); } RCT2_GLOBAL(0x9E2E18, money32) += MONEY(20, 0); @@ -2498,7 +2499,8 @@ void game_command_set_water_height(int* eax, int* ebx, int* ecx, int* edx, int* if(*ebx & GAME_COMMAND_FLAG_APPLY){ int element_height = map_element_height(x, y); footpath_remove_litter(x, y, element_height); - map_remove_walls_at_z(x, y, element_height); + if(!gCheatsDisableClearanceChecks) + map_remove_walls_at_z(x, y, element_height); } rct_map_element* map_element = map_get_surface_element_at(x / 32, y / 32); diff --git a/test/management/finance_test.c b/test/management/finance_test.c deleted file mode 100644 index 0772dfb0ff..0000000000 --- a/test/management/finance_test.c +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2015 Marco Costa -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of OpenRCT2. -* -* OpenRCT2 is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "../../src/addresses.h" -#include "../../src/management/finance.h" -#include "../../src/openrct2.h" -#include "../../src/scenario.h" - -#include "finance_test.h" - -void test_finance_setup(CuTest* tc) { - test_load_scenario(tc, "Build your own Six Flags Park.SC6"); -} - -void test_finance_loan_increase(CuTest* tc) { - money32 initialCash = finance_get_current_cash(); - money32 initialLoan = finance_get_current_loan(); - - money32 newLoan = finance_get_maximum_loan(); - finance_set_loan(newLoan); - - money32 actual = finance_get_current_loan(); - CuAssertIntEquals(tc, newLoan, actual); - - money32 actualCash = finance_get_current_cash(); - CuAssertIntEquals(tc, initialCash + newLoan - initialLoan, actualCash); -} - -void test_finance_loan_pay_back(CuTest* tc) { - money32 initialCash = finance_get_current_cash(); - money32 initialLoan = finance_get_current_loan(); - - money32 newLoan = MONEY(0, 00); - finance_set_loan(newLoan); - - money32 actual = finance_get_current_loan(); - CuAssertIntEquals(tc, newLoan, actual); - - money32 actualCash = finance_get_current_cash(); - CuAssertIntEquals(tc, MONEY(0, 00), actualCash); -} - - diff --git a/test/management/finance_test.h b/test/management/finance_test.h deleted file mode 100644 index 482d31d390..0000000000 --- a/test/management/finance_test.h +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2015 Marco Costa -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of OpenRCT2. -* -* OpenRCT2 is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef _FINANCE_TEST_H_ -#define _FINANCE_TEST_H_ - -#include "../tests.h" - -void test_finance_setup(CuTest* tc); -void test_finance_loan_increase(CuTest* tc); -void test_finance_loan_pay_back(CuTest* tc); - -#endif diff --git a/test/ride/ride_ratings_test.c b/test/ride/ride_ratings_test.c deleted file mode 100644 index 9282d6be07..0000000000 --- a/test/ride/ride_ratings_test.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "../../src/ride/ride_ratings.h" -#include "../../src/localisation/localisation.h" - -#include "ride_ratings_test.h" - -void test_ride_ratings_setup(CuTest* tc) { - test_load_scenario(tc, "Six Flags Magic Mountain.SC6"); -} - -void test_ride_ratings(CuTest* tc) { - int i; - rct_ride *ride; - rating_tuple *rideRatings = malloc(256 * sizeof(rating_tuple)); - char rideName[256]; - char buffer[256]; - - // Store original ride ratings - FOR_ALL_RIDES(i, ride) - rideRatings[i] = ride->ratings; - - // Update all the ride ratings - // TODO use a better function that can just be called once for each ride - for (int i = 0; i < MAX_RIDES * 10; i++) - ride_ratings_update_all(); - - FOR_ALL_RIDES(i, ride) { - format_string(rideName, ride->name, &ride->name_arguments); - - sprintf(buffer, "[%s.excitement]", rideName); - CuAssertIntEquals_Msg(tc, buffer, rideRatings[i].excitement, ride->excitement); - sprintf(buffer, "[%s.intensity]", rideName); - CuAssertIntEquals_Msg(tc, buffer, rideRatings[i].intensity, ride->intensity); - sprintf(buffer, "[%s.nausea]", rideName); - CuAssertIntEquals_Msg(tc, buffer, rideRatings[i].nausea, ride->nausea); - } - - free(rideRatings); -} diff --git a/test/ride/ride_ratings_test.h b/test/ride/ride_ratings_test.h deleted file mode 100644 index ed19312ce8..0000000000 --- a/test/ride/ride_ratings_test.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _RIDE_RATINGS_TEST_H_ -#define _RIDE_RATINGS_TEST_H_ - -#include "../tests.h" - -void test_ride_ratings_setup(CuTest* tc); -void test_ride_ratings(CuTest* tc); - -#endif diff --git a/test/tests.c b/test/tests.c deleted file mode 100644 index 6963f14517..0000000000 --- a/test/tests.c +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2015 Marco Costa -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of OpenRCT2. -* -* OpenRCT2 is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#include "../src/openrct2.h" -#include "management/finance_test.h" -#include "ride/ride_ratings_test.h" - -int cmdline_for_test(const char **argv, int argc) -{ - // NOTE Currently all tests are running in a OpenRCT2 setup frame. Tests for the initialisation and disposing should be - // separate and independent. - - int numFailedTests; - - gOpenRCT2Headless = true; - if (openrct2_initialise()) { - numFailedTests = run_all_tests(); - - openrct2_dispose(); - } - return numFailedTests > 0 ? -1 : 1; -} - -CuSuite* new_suite(void) -{ - CuSuite* suite = CuSuiteNew(); - - // Test Finance - SUITE_ADD_TEST(suite, test_finance_setup); - SUITE_ADD_TEST(suite, test_finance_loan_increase); - SUITE_ADD_TEST(suite, test_finance_loan_pay_back); - - // Test Ride - SUITE_ADD_TEST(suite, test_ride_ratings_setup); - SUITE_ADD_TEST(suite, test_ride_ratings); - - // Future Tests: - // Test X - // SUITE_ADD_TEST(suite, test_X_setup); - // SUITE_ADD_TEST(suite, test_X_Y); - // SUITE_ADD_TEST(suite, test_X_Z); - - return suite; -} - -int run_all_tests(void) -{ - CuString *output = CuStringNew(); - CuSuite* suite = CuSuiteNew(); - - CuSuiteAddSuite(suite, new_suite()); - - CuSuiteRun(suite); - CuSuiteSummary(suite, output); - CuSuiteDetails(suite, output); - printf("Test results:\n%s\n", output->buffer); - - return suite->failCount; -} diff --git a/test/tests.h b/test/tests.h deleted file mode 100644 index 06619ec167..0000000000 --- a/test/tests.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2015 Marco Costa -* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. -* -* This file is part of OpenRCT2. -* -* OpenRCT2 is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. - -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. - -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*****************************************************************************/ - -#ifndef _TESTS_H_ -#define _TESTS_H_ - -#include -#include -#include "../src/common.h" - -int cmdline_for_test(const char **argv, int argc); -int run_all_tests(); - -// Test utilities - -#include "../src/scenario.h" - -static void test_load_scenario(CuTest* tc, const char* file_name) { - const scenario_index_entry* scenario = scenario_list_find_by_path(file_name); - if (scenario == NULL) { - CuFail(tc, "Could not load scenario"); - } - scenario_load_and_play_from_path(scenario->name); -} - -#endif