1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-21 05:53:02 +01:00

Merge pull request #4330 from marijnvdwerf/feature/paint-unit-test

Attempt to add unit testing for track drawing
This commit is contained in:
Ted John
2016-09-16 18:51:38 +01:00
committed by GitHub
21 changed files with 3468 additions and 19 deletions

View File

@@ -219,6 +219,7 @@ if (APPLE)
set_source_files_properties(${ORCT2_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c -fmodules")
endif (APPLE)
if (APPLE AND NOT USE_MMAP)
set(PIE_FLAG "-fno-pie")
else ()
@@ -340,6 +341,7 @@ endif (UNIX AND NOT APPLE)
# libopenrct2.dll -> openrct2.dll
set_target_properties(${PROJECT} PROPERTIES PREFIX "")
set_target_properties(${PROJECT} PROPERTIES COMPILE_FLAGS "-Wundef")
# Link shared libs first
TARGET_LINK_LIBRARIES(${PROJECT} ${GLLIBS})
@@ -363,6 +365,16 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/g2.dat" DESTINATION share/${PROJECT})
install(DIRECTORY data/ DESTINATION share/${PROJECT})
install(FILES ${DOC_FILES} DESTINATION share/doc/${PROJECT})
if (UNIX AND (NOT USE_MMAP) AND (NOT DISABLE_RCT2) AND (NOT FORCE64))
file(GLOB_RECURSE ORCT2_RIDE_SOURCES "src/ride/*/*.c")
file(GLOB_RECURSE ORCT2_RIDE_DEP_SOURCES "src/ride/ride_data.c" "src/ride/track_data.c" "src/ride/track_data_old.c" "src/ride/track_paint.c" "src/addresses.c" "src/diagnostic.c" "src/hook.c" "src/paint/map_element/map_element.c")
file(GLOB_RECURSE ORCT2_TESTPAINT_SOURCES "test/testpaint/*.c" "test/testpaint/*.cpp" "test/testpaint/*.h")
add_executable(testpaint EXCLUDE_FROM_ALL ${ORCT2_RIDE_SOURCES} ${ORCT2_RIDE_DEP_SOURCES} ${ORCT2_TESTPAINT_SOURCES} ${RCT2_SECTIONS})
set_target_properties(testpaint PROPERTIES COMPILE_FLAGS "-DNO_VEHICLES")
add_dependencies(testpaint segfiles)
endif ()
set(CPACK_PACKAGE_VERSION_MAJOR 0)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 5)

View File

@@ -17,11 +17,99 @@
008BF72C1CDAA5C30019A2AD /* track_design.c in Sources */ = {isa = PBXBuildFile; fileRef = 008BF7281CDAA5C30019A2AD /* track_design.c */; };
00EFEE721CF1D80B0035213B /* NetworkKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00EFEE701CF1D80B0035213B /* NetworkKey.cpp */; };
791166FB1D7486EF005912EA /* NetworkServerAdvertiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 791166F91D7486EF005912EA /* NetworkServerAdvertiser.cpp */; };
85060FD31D8C17CC00DFA2B3 /* track_data_old.c in Sources */ = {isa = PBXBuildFile; fileRef = 8594C05F1D885CF600235E93 /* track_data_old.c */; };
8594C0601D885CF600235E93 /* track_data_old.c in Sources */ = {isa = PBXBuildFile; fileRef = 8594C05F1D885CF600235E93 /* track_data_old.c */; };
85AFA2111D7DB83E00221B42 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85AFA20F1D7DB83E00221B42 /* main.cpp */; };
85B5C0B01D81D912001B99A8 /* intercept_2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85B5C0AF1D81D912001B99A8 /* intercept_2.cpp */; };
C612A8991D64825300B634CA /* vehicle_data.c in Sources */ = {isa = PBXBuildFile; fileRef = C612A8971D64825300B634CA /* vehicle_data.c */; };
C61FB7201CF6180C004CE991 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38BA1CF3006400659A24 /* libssl.dylib */; };
C61FB7211CF618BA004CE991 /* libssl.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38BA1CF3006400659A24 /* libssl.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
C61FB7241CF86356004CE991 /* NetworkUser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C61FB7221CF86356004CE991 /* NetworkUser.cpp */; };
C64FDA641D6D9A2100F259B9 /* air_powered_vertical_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BB1CDBC3B7009F9BFC /* air_powered_vertical_coaster.c */; };
C64FDA651D6D9A2100F259B9 /* bobsleigh_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BC1CDBC3B7009F9BFC /* bobsleigh_coaster.c */; };
C64FDA661D6D9A2100F259B9 /* compact_inverted_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BD1CDBC3B7009F9BFC /* compact_inverted_coaster.c */; };
C64FDA671D6D9A2100F259B9 /* corkscrew_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BE1CDBC3B7009F9BFC /* corkscrew_roller_coaster.c */; };
C64FDA681D6D9A2100F259B9 /* flying_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8BF1CDBC3B7009F9BFC /* flying_roller_coaster.c */; };
C64FDA691D6D9A2100F259B9 /* giga_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C01CDBC3B7009F9BFC /* giga_coaster.c */; };
C64FDA6A1D6D9A2100F259B9 /* heartline_twister_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C11CDBC3B7009F9BFC /* heartline_twister_coaster.c */; };
C64FDA6B1D6D9A2100F259B9 /* inverted_hairpin_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C21CDBC3B7009F9BFC /* inverted_hairpin_coaster.c */; };
C64FDA6C1D6D9A2100F259B9 /* inverted_impulse_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C31CDBC3B7009F9BFC /* inverted_impulse_coaster.c */; };
C64FDA6D1D6D9A2100F259B9 /* inverted_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C41CDBC3B7009F9BFC /* inverted_roller_coaster.c */; };
C64FDA6E1D6D9A2100F259B9 /* junior_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C51CDBC3B7009F9BFC /* junior_roller_coaster.c */; };
C64FDA6F1D6D9A2100F259B9 /* lay_down_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C61CDBC3B7009F9BFC /* lay_down_roller_coaster.c */; };
C64FDA701D6D9A2100F259B9 /* lim_launched_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C71CDBC3B7009F9BFC /* lim_launched_roller_coaster.c */; };
C64FDA711D6D9A2100F259B9 /* looping_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C81CDBC3B7009F9BFC /* looping_roller_coaster.c */; };
C64FDA721D6D9A2100F259B9 /* mine_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8C91CDBC3B7009F9BFC /* mine_ride.c */; };
C64FDA731D6D9A2100F259B9 /* mine_train_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CA1CDBC3B7009F9BFC /* mine_train_coaster.c */; };
C64FDA741D6D9A2100F259B9 /* mini_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CB1CDBC3B7009F9BFC /* mini_roller_coaster.c */; };
C64FDA751D6D9A2100F259B9 /* mini_suspended_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CC1CDBC3B7009F9BFC /* mini_suspended_coaster.c */; };
C64FDA761D6D9A2100F259B9 /* multi_dimension_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CD1CDBC3B7009F9BFC /* multi_dimension_roller_coaster.c */; };
C64FDA771D6D9A2100F259B9 /* reverse_freefall_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CE1CDBC3B7009F9BFC /* reverse_freefall_coaster.c */; };
C64FDA781D6D9A2100F259B9 /* reverser_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8CF1CDBC3B7009F9BFC /* reverser_roller_coaster.c */; };
C64FDA791D6D9A2100F259B9 /* side_friction_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D01CDBC3B7009F9BFC /* side_friction_roller_coaster.c */; };
C64FDA7A1D6D9A2100F259B9 /* spiral_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D11CDBC3B7009F9BFC /* spiral_roller_coaster.c */; };
C64FDA7B1D6D9A2100F259B9 /* stand_up_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D21CDBC3B7009F9BFC /* stand_up_roller_coaster.c */; };
C64FDA7C1D6D9A2100F259B9 /* steeplechase.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D31CDBC3B7009F9BFC /* steeplechase.c */; };
C64FDA7D1D6D9A2100F259B9 /* suspended_swinging_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D41CDBC3B7009F9BFC /* suspended_swinging_coaster.c */; };
C64FDA7E1D6D9A2100F259B9 /* twister_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D51CDBC3B7009F9BFC /* twister_roller_coaster.c */; };
C64FDA7F1D6D9A2100F259B9 /* vertical_drop_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D61CDBC3B7009F9BFC /* vertical_drop_roller_coaster.c */; };
C64FDA801D6D9A2100F259B9 /* virginia_reel.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D71CDBC3B7009F9BFC /* virginia_reel.c */; };
C64FDA811D6D9A2100F259B9 /* wild_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D81CDBC3B7009F9BFC /* wild_mouse.c */; };
C64FDA821D6D9A2100F259B9 /* wooden_roller_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8D91CDBC3B7009F9BFC /* wooden_roller_coaster.c */; };
C64FDA831D6D9A2100F259B9 /* wooden_wild_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8DA1CDBC3B7009F9BFC /* wooden_wild_mouse.c */; };
C64FDA841D6D9A2100F259B9 /* car_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8DC1CDBC3B7009F9BFC /* car_ride.c */; };
C64FDA851D6D9A2100F259B9 /* circus_show.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8DD1CDBC3B7009F9BFC /* circus_show.c */; };
C64FDA861D6D9A2100F259B9 /* crooked_house.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8DE1CDBC3B7009F9BFC /* crooked_house.c */; };
C64FDA871D6D9A2100F259B9 /* dodgems.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8DF1CDBC3B7009F9BFC /* dodgems.c */; };
C64FDA881D6D9A2100F259B9 /* ferris_wheel.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E01CDBC3B7009F9BFC /* ferris_wheel.c */; };
C64FDA891D6D9A2100F259B9 /* flying_saucers.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E11CDBC3B7009F9BFC /* flying_saucers.c */; };
C64FDA8A1D6D9A2100F259B9 /* ghost_train.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E21CDBC3B7009F9BFC /* ghost_train.c */; };
C64FDA8B1D6D9A2100F259B9 /* haunted_house.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E31CDBC3B7009F9BFC /* haunted_house.c */; };
C64FDA8C1D6D9A2100F259B9 /* maze.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E41CDBC3B7009F9BFC /* maze.c */; };
C64FDA8D1D6D9A2100F259B9 /* merry_go_round.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E51CDBC3B7009F9BFC /* merry_go_round.c */; };
C64FDA8E1D6D9A2100F259B9 /* mini_golf.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E61CDBC3B7009F9BFC /* mini_golf.c */; };
C64FDA8F1D6D9A2100F259B9 /* mini_helicopters.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E71CDBC3B7009F9BFC /* mini_helicopters.c */; };
C64FDA901D6D9A2100F259B9 /* monorail_cycles.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E81CDBC3B7009F9BFC /* monorail_cycles.c */; };
C64FDA911D6D9A2100F259B9 /* observation_tower.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8E91CDBC3B7009F9BFC /* observation_tower.c */; };
C64FDA921D6D9A2100F259B9 /* space_rings.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8EA1CDBC3B7009F9BFC /* space_rings.c */; };
C64FDA931D6D9A2100F259B9 /* spiral_slide.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8EB1CDBC3B7009F9BFC /* spiral_slide.c */; };
C64FDA941D6D9A2100F259B9 /* facility.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8ED1CDBC3B7009F9BFC /* facility.c */; };
C64FDA951D6D9A2100F259B9 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8EE1CDBC3B7009F9BFC /* misc.c */; };
C64FDA961D6D9A2100F259B9 /* shop.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8EF1CDBC3B7009F9BFC /* shop.c */; };
C64FDA971D6D9A2100F259B9 /* 3d_cinema.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F11CDBC3B7009F9BFC /* 3d_cinema.c */; };
C64FDA981D6D9A2100F259B9 /* enterprise.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F21CDBC3B7009F9BFC /* enterprise.c */; };
C64FDA991D6D9A2100F259B9 /* go_karts.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F31CDBC3B7009F9BFC /* go_karts.c */; };
C64FDA9A1D6D9A2100F259B9 /* launched_freefall.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F41CDBC3B7009F9BFC /* launched_freefall.c */; };
C64FDA9B1D6D9A2100F259B9 /* magic_carpet.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F51CDBC3B7009F9BFC /* magic_carpet.c */; };
C64FDA9C1D6D9A2100F259B9 /* motion_simulator.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F61CDBC3B7009F9BFC /* motion_simulator.c */; };
C64FDA9D1D6D9A2100F259B9 /* pirate_ship.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F71CDBC3B7009F9BFC /* pirate_ship.c */; };
C64FDA9E1D6D9A2100F259B9 /* roto_drop.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F81CDBC3B7009F9BFC /* roto_drop.c */; };
C64FDA9F1D6D9A2100F259B9 /* swinging_inverter_ship.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8F91CDBC3B7009F9BFC /* swinging_inverter_ship.c */; };
C64FDAA01D6D9A2100F259B9 /* top_spin.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8FA1CDBC3B7009F9BFC /* top_spin.c */; };
C64FDAA11D6D9A2100F259B9 /* twist.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8FB1CDBC3B7009F9BFC /* twist.c */; };
C64FDAA21D6D9A2100F259B9 /* chairlift.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8FD1CDBC3B7009F9BFC /* chairlift.c */; };
C64FDAA31D6D9A2100F259B9 /* lift.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8FE1CDBC3B7009F9BFC /* lift.c */; };
C64FDAA41D6D9A2100F259B9 /* minature_railway.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F8FF1CDBC3B7009F9BFC /* minature_railway.c */; };
C64FDAA51D6D9A2100F259B9 /* monorail.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9001CDBC3B7009F9BFC /* monorail.c */; };
C64FDAA61D6D9A2100F259B9 /* suspended_monorail.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9011CDBC3B7009F9BFC /* suspended_monorail.c */; };
C64FDAA71D6D9A2100F259B9 /* boat_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9031CDBC3B7009F9BFC /* boat_ride.c */; };
C64FDAA81D6D9A2100F259B9 /* dingy_slide.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9041CDBC3B7009F9BFC /* dingy_slide.c */; };
C64FDAA91D6D9A2100F259B9 /* log_flume.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9051CDBC3B7009F9BFC /* log_flume.c */; };
C64FDAAA1D6D9A2100F259B9 /* river_rafts.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9061CDBC3B7009F9BFC /* river_rafts.c */; };
C64FDAAB1D6D9A2100F259B9 /* river_rapids.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9071CDBC3B7009F9BFC /* river_rapids.c */; };
C64FDAAC1D6D9A2100F259B9 /* splash_boats.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9081CDBC3B7009F9BFC /* splash_boats.c */; };
C64FDAAD1D6D9A2100F259B9 /* submarine_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9091CDBC3B7009F9BFC /* submarine_ride.c */; };
C64FDAAE1D6D9A2100F259B9 /* water_coaster.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F90A1CDBC3B7009F9BFC /* water_coaster.c */; };
C64FDABC1D6D9C8800F259B9 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270CD1CC81B3200D84D28 /* addresses.c */; };
C64FDABE1D6D9CD900F259B9 /* ride_data.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271731CC81B3200D84D28 /* ride_data.c */; };
C64FDABF1D6D9CEA00F259B9 /* map_element.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F89B1CDBC37E009F9BFC /* map_element.c */; };
C64FDAC01D6D9E3B00F259B9 /* track_data.c in Sources */ = {isa = PBXBuildFile; fileRef = D442717B1CC81B3200D84D28 /* track_data.c */; };
C64FDAC21D6DA0B800F259B9 /* diagnostic.c in Sources */ = {isa = PBXBuildFile; fileRef = D44270FE1CC81B3200D84D28 /* diagnostic.c */; };
C64FDAC31D6DA41000F259B9 /* track_paint.c in Sources */ = {isa = PBXBuildFile; fileRef = D442717D1CC81B3200D84D28 /* track_paint.c */; };
C64FDAC51D6DA55E00F259B9 /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C64FDAC41D6DA55E00F259B9 /* compat.c */; };
C64FDAC81D6DA72400F259B9 /* intercept.c in Sources */ = {isa = PBXBuildFile; fileRef = C64FDAC71D6DA72400F259B9 /* intercept.c */; };
C64FDACA1D6DA92D00F259B9 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = C64FDAC91D6DA92D00F259B9 /* data.c */; };
C64FDACB1D6DBCC700F259B9 /* hook.c in Sources */ = {isa = PBXBuildFile; fileRef = D44271121CC81B3200D84D28 /* hook.c */; };
C650B2191CCABBDD00B4D91C /* S4Importer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C650B2151CCABBDD00B4D91C /* S4Importer.cpp */; };
C650B21A1CCABBDD00B4D91C /* tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C650B2171CCABBDD00B4D91C /* tables.cpp */; };
C650B21C1CCABC4400B4D91C /* ConvertCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C650B21B1CCABC4400B4D91C /* ConvertCommand.cpp */; };
@@ -356,6 +444,15 @@
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
C64FDA5B1D6D99F400F259B9 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
D41B74201C210B190080A7B9 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -397,10 +494,18 @@
791166F91D7486EF005912EA /* NetworkServerAdvertiser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkServerAdvertiser.cpp; sourceTree = "<group>"; };
791166FA1D7486EF005912EA /* NetworkServerAdvertiser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkServerAdvertiser.h; sourceTree = "<group>"; };
8594C05F1D885CF600235E93 /* track_data_old.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = track_data_old.c; sourceTree = "<group>"; };
85AFA20F1D7DB83E00221B42 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
85AFA2101D7DB83E00221B42 /* intercept.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intercept.h; sourceTree = "<group>"; };
85AFA2141D7DDFA100221B42 /* data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = data.h; sourceTree = "<group>"; };
85B5C0AF1D81D912001B99A8 /* intercept_2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intercept_2.cpp; sourceTree = "<group>"; };
C612A8971D64825300B634CA /* vehicle_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vehicle_data.c; sourceTree = "<group>"; };
C612A8981D64825300B634CA /* vehicle_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vehicle_data.h; sourceTree = "<group>"; };
C61FB7221CF86356004CE991 /* NetworkUser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkUser.cpp; sourceTree = "<group>"; usesTabs = 0; };
C61FB7231CF86356004CE991 /* NetworkUser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = NetworkUser.h; sourceTree = "<group>"; usesTabs = 0; };
C64FDA5D1D6D99F400F259B9 /* PaintTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = PaintTest; sourceTree = BUILT_PRODUCTS_DIR; };
C64FDAC41D6DA55E00F259B9 /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = "<group>"; };
C64FDAC71D6DA72400F259B9 /* intercept.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = intercept.c; sourceTree = "<group>"; };
C64FDAC91D6DA92D00F259B9 /* data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = data.c; sourceTree = "<group>"; };
C650B2151CCABBDD00B4D91C /* S4Importer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = S4Importer.cpp; sourceTree = "<group>"; usesTabs = 0; };
C650B2161CCABBDD00B4D91C /* S4Importer.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = S4Importer.h; sourceTree = "<group>"; usesTabs = 0; };
C650B2171CCABBDD00B4D91C /* tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tables.cpp; sourceTree = "<group>"; usesTabs = 0; };
@@ -1022,6 +1127,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C64FDA5A1D6D99F400F259B9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D497D0751C20FD52002BF46A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -1042,6 +1154,29 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8546F74A1D7E1D220004004C /* Tests */ = {
isa = PBXGroup;
children = (
C64FDA5E1D6D99F400F259B9 /* Paint */,
);
name = Tests;
sourceTree = "<group>";
};
C64FDA5E1D6D99F400F259B9 /* Paint */ = {
isa = PBXGroup;
children = (
C64FDAC41D6DA55E00F259B9 /* compat.c */,
C64FDAC91D6DA92D00F259B9 /* data.c */,
85AFA2141D7DDFA100221B42 /* data.h */,
85B5C0AF1D81D912001B99A8 /* intercept_2.cpp */,
C64FDAC71D6DA72400F259B9 /* intercept.c */,
85AFA2101D7DB83E00221B42 /* intercept.h */,
85AFA20F1D7DB83E00221B42 /* main.cpp */,
);
name = Paint;
path = test/testpaint;
sourceTree = "<group>";
};
C650B2141CCABBDD00B4D91C /* rct1 */ = {
isa = PBXGroup;
children = (
@@ -1940,6 +2075,7 @@
children = (
D41B72431C21015A0080A7B9 /* Sources */,
D497D07A1C20FD52002BF46A /* Resources */,
8546F74A1D7E1D220004004C /* Tests */,
D41B73ED1C21017D0080A7B9 /* Libraries */,
D497D0791C20FD52002BF46A /* Products */,
);
@@ -1950,6 +2086,7 @@
isa = PBXGroup;
children = (
D497D0781C20FD52002BF46A /* OpenRCT2.app */,
C64FDA5D1D6D99F400F259B9 /* PaintTest */,
);
name = Products;
sourceTree = "<group>";
@@ -2018,6 +2155,24 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C64FDA5C1D6D99F400F259B9 /* PaintTest */ = {
isa = PBXNativeTarget;
buildConfigurationList = C64FDA631D6D99F400F259B9 /* Build configuration list for PBXNativeTarget "PaintTest" */;
buildPhases = (
C64FDAC61D6DA64A00F259B9 /* Create Segment Files */,
C64FDA591D6D99F400F259B9 /* Sources */,
C64FDA5A1D6D99F400F259B9 /* Frameworks */,
C64FDA5B1D6D99F400F259B9 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = PaintTest;
productName = PaintTest;
productReference = C64FDA5D1D6D99F400F259B9 /* PaintTest */;
productType = "com.apple.product-type.tool";
};
D497D0771C20FD52002BF46A /* OpenRCT2 */ = {
isa = PBXNativeTarget;
buildConfigurationList = D497D0891C20FD53002BF46A /* Build configuration list for PBXNativeTarget "OpenRCT2" */;
@@ -2050,6 +2205,9 @@
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = OpenRCT2;
TargetAttributes = {
C64FDA5C1D6D99F400F259B9 = {
CreatedOnToolsVersion = 7.3.1;
};
D497D0771C20FD52002BF46A = {
CreatedOnToolsVersion = 7.2;
};
@@ -2069,6 +2227,7 @@
projectRoot = "";
targets = (
D497D0771C20FD52002BF46A /* OpenRCT2 */,
C64FDA5C1D6D99F400F259B9 /* PaintTest */,
);
};
/* End PBXProject section */
@@ -2090,6 +2249,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
C64FDAC61D6DA64A00F259B9 /* Create Segment Files */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/openrct2.exe",
);
name = "Create Segment Files";
outputPaths = (
"$(DERIVED_FILE_DIR)/openrct2_text",
"$(DERIVED_FILE_DIR)/openrct2_data",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "dd if=\"${SRCROOT}/openrct2.exe\" of=\"${DERIVED_FILE_DIR}/openrct2_text\" bs=4096 skip=1 count=1187\ndd if=\"${SRCROOT}/openrct2.exe\" of=\"${DERIVED_FILE_DIR}/openrct2_data\" bs=4096 skip=1188 count=318\ndd if=/dev/zero of=\"${DERIVED_FILE_DIR}/openrct2_data\" bs=4096 seek=318 count=2630 conv=notrunc\ndd if=\"${SRCROOT}/openrct2.exe\" of=\"${DERIVED_FILE_DIR}/openrct2_data\" bs=4096 skip=1506 seek=2948 count=1 conv=notrunc";
};
D40F4E1D1C2528D5009582C9 /* Create Segment Files */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -2186,6 +2362,101 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C64FDA591D6D99F400F259B9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C64FDACB1D6DBCC700F259B9 /* hook.c in Sources */,
C64FDAC31D6DA41000F259B9 /* track_paint.c in Sources */,
C64FDAC21D6DA0B800F259B9 /* diagnostic.c in Sources */,
C64FDAC01D6D9E3B00F259B9 /* track_data.c in Sources */,
C64FDABF1D6D9CEA00F259B9 /* map_element.c in Sources */,
C64FDABE1D6D9CD900F259B9 /* ride_data.c in Sources */,
C64FDABC1D6D9C8800F259B9 /* addresses.c in Sources */,
C64FDA641D6D9A2100F259B9 /* air_powered_vertical_coaster.c in Sources */,
C64FDA651D6D9A2100F259B9 /* bobsleigh_coaster.c in Sources */,
C64FDA661D6D9A2100F259B9 /* compact_inverted_coaster.c in Sources */,
C64FDA671D6D9A2100F259B9 /* corkscrew_roller_coaster.c in Sources */,
85AFA2111D7DB83E00221B42 /* main.cpp in Sources */,
C64FDA681D6D9A2100F259B9 /* flying_roller_coaster.c in Sources */,
C64FDA691D6D9A2100F259B9 /* giga_coaster.c in Sources */,
C64FDA6A1D6D9A2100F259B9 /* heartline_twister_coaster.c in Sources */,
C64FDA6B1D6D9A2100F259B9 /* inverted_hairpin_coaster.c in Sources */,
C64FDA6C1D6D9A2100F259B9 /* inverted_impulse_coaster.c in Sources */,
C64FDA6D1D6D9A2100F259B9 /* inverted_roller_coaster.c in Sources */,
C64FDA6E1D6D9A2100F259B9 /* junior_roller_coaster.c in Sources */,
C64FDA6F1D6D9A2100F259B9 /* lay_down_roller_coaster.c in Sources */,
C64FDA701D6D9A2100F259B9 /* lim_launched_roller_coaster.c in Sources */,
C64FDA711D6D9A2100F259B9 /* looping_roller_coaster.c in Sources */,
C64FDAC81D6DA72400F259B9 /* intercept.c in Sources */,
C64FDA721D6D9A2100F259B9 /* mine_ride.c in Sources */,
C64FDA731D6D9A2100F259B9 /* mine_train_coaster.c in Sources */,
C64FDA741D6D9A2100F259B9 /* mini_roller_coaster.c in Sources */,
C64FDA751D6D9A2100F259B9 /* mini_suspended_coaster.c in Sources */,
C64FDA761D6D9A2100F259B9 /* multi_dimension_roller_coaster.c in Sources */,
C64FDA771D6D9A2100F259B9 /* reverse_freefall_coaster.c in Sources */,
C64FDA781D6D9A2100F259B9 /* reverser_roller_coaster.c in Sources */,
C64FDA791D6D9A2100F259B9 /* side_friction_roller_coaster.c in Sources */,
C64FDACA1D6DA92D00F259B9 /* data.c in Sources */,
C64FDA7A1D6D9A2100F259B9 /* spiral_roller_coaster.c in Sources */,
C64FDA7B1D6D9A2100F259B9 /* stand_up_roller_coaster.c in Sources */,
C64FDA7C1D6D9A2100F259B9 /* steeplechase.c in Sources */,
C64FDA7D1D6D9A2100F259B9 /* suspended_swinging_coaster.c in Sources */,
C64FDA7E1D6D9A2100F259B9 /* twister_roller_coaster.c in Sources */,
C64FDA7F1D6D9A2100F259B9 /* vertical_drop_roller_coaster.c in Sources */,
C64FDA801D6D9A2100F259B9 /* virginia_reel.c in Sources */,
C64FDA811D6D9A2100F259B9 /* wild_mouse.c in Sources */,
C64FDA821D6D9A2100F259B9 /* wooden_roller_coaster.c in Sources */,
C64FDA831D6D9A2100F259B9 /* wooden_wild_mouse.c in Sources */,
C64FDA841D6D9A2100F259B9 /* car_ride.c in Sources */,
C64FDA851D6D9A2100F259B9 /* circus_show.c in Sources */,
C64FDA861D6D9A2100F259B9 /* crooked_house.c in Sources */,
85060FD31D8C17CC00DFA2B3 /* track_data_old.c in Sources */,
C64FDA871D6D9A2100F259B9 /* dodgems.c in Sources */,
C64FDA881D6D9A2100F259B9 /* ferris_wheel.c in Sources */,
C64FDA891D6D9A2100F259B9 /* flying_saucers.c in Sources */,
C64FDA8A1D6D9A2100F259B9 /* ghost_train.c in Sources */,
C64FDA8B1D6D9A2100F259B9 /* haunted_house.c in Sources */,
C64FDA8C1D6D9A2100F259B9 /* maze.c in Sources */,
C64FDA8D1D6D9A2100F259B9 /* merry_go_round.c in Sources */,
C64FDA8E1D6D9A2100F259B9 /* mini_golf.c in Sources */,
C64FDA8F1D6D9A2100F259B9 /* mini_helicopters.c in Sources */,
C64FDA901D6D9A2100F259B9 /* monorail_cycles.c in Sources */,
85B5C0B01D81D912001B99A8 /* intercept_2.cpp in Sources */,
C64FDA911D6D9A2100F259B9 /* observation_tower.c in Sources */,
C64FDA921D6D9A2100F259B9 /* space_rings.c in Sources */,
C64FDA931D6D9A2100F259B9 /* spiral_slide.c in Sources */,
C64FDA941D6D9A2100F259B9 /* facility.c in Sources */,
C64FDAC51D6DA55E00F259B9 /* compat.c in Sources */,
C64FDA951D6D9A2100F259B9 /* misc.c in Sources */,
C64FDA961D6D9A2100F259B9 /* shop.c in Sources */,
C64FDA971D6D9A2100F259B9 /* 3d_cinema.c in Sources */,
C64FDA981D6D9A2100F259B9 /* enterprise.c in Sources */,
C64FDA991D6D9A2100F259B9 /* go_karts.c in Sources */,
C64FDA9A1D6D9A2100F259B9 /* launched_freefall.c in Sources */,
C64FDA9B1D6D9A2100F259B9 /* magic_carpet.c in Sources */,
C64FDA9C1D6D9A2100F259B9 /* motion_simulator.c in Sources */,
C64FDA9D1D6D9A2100F259B9 /* pirate_ship.c in Sources */,
C64FDA9E1D6D9A2100F259B9 /* roto_drop.c in Sources */,
C64FDA9F1D6D9A2100F259B9 /* swinging_inverter_ship.c in Sources */,
C64FDAA01D6D9A2100F259B9 /* top_spin.c in Sources */,
C64FDAA11D6D9A2100F259B9 /* twist.c in Sources */,
C64FDAA21D6D9A2100F259B9 /* chairlift.c in Sources */,
C64FDAA31D6D9A2100F259B9 /* lift.c in Sources */,
C64FDAA41D6D9A2100F259B9 /* minature_railway.c in Sources */,
C64FDAA51D6D9A2100F259B9 /* monorail.c in Sources */,
C64FDAA61D6D9A2100F259B9 /* suspended_monorail.c in Sources */,
C64FDAA71D6D9A2100F259B9 /* boat_ride.c in Sources */,
C64FDAA81D6D9A2100F259B9 /* dingy_slide.c in Sources */,
C64FDAA91D6D9A2100F259B9 /* log_flume.c in Sources */,
C64FDAAA1D6D9A2100F259B9 /* river_rafts.c in Sources */,
C64FDAAB1D6D9A2100F259B9 /* river_rapids.c in Sources */,
C64FDAAC1D6D9A2100F259B9 /* splash_boats.c in Sources */,
C64FDAAD1D6D9A2100F259B9 /* submarine_ride.c in Sources */,
C64FDAAE1D6D9A2100F259B9 /* water_coaster.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D497D0741C20FD52002BF46A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -2518,6 +2789,112 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
C64FDA611D6D99F400F259B9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "-";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
"NO_VEHICLES=1",
);
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/libxc/include",
"$(SRCROOT)/libxc/include/SDL2",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/libxc/lib";
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_LDFLAGS = (
"-sectcreate",
rct2_text,
__text,
"$(DERIVED_FILE_DIR)/openrct2_text",
"-segaddr",
rct2_text,
0x401000,
"-segprot",
rct2_text,
rwx,
rx,
"-sectcreate",
rct2_data,
__data,
"$(DERIVED_FILE_DIR)/openrct2_data",
"-segaddr",
rct2_data,
0x8a4000,
"-segprot",
rct2_data,
rw,
rw,
"-segaddr",
__TEXT,
0x2000000,
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
C64FDA621D6D99F400F259B9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "-";
GCC_PREPROCESSOR_DEFINITIONS = (
OPENGL_NO_LINK,
"OPENRCT2_BUILD_INFO_HEADER=\"\\\"$(DERIVED_FILE_DIR)/gitversion.h\\\"\"",
"NO_VEHICLES=1",
);
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/libxc/include",
"$(SRCROOT)/libxc/include/SDL2",
);
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/libxc/lib";
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_LDFLAGS = (
"-sectcreate",
rct2_text,
__text,
"$(DERIVED_FILE_DIR)/openrct2_text",
"-segaddr",
rct2_text,
0x401000,
"-segprot",
rct2_text,
rwx,
rx,
"-sectcreate",
rct2_data,
__data,
"$(DERIVED_FILE_DIR)/openrct2_data",
"-segaddr",
rct2_data,
0x8a4000,
"-segprot",
rct2_data,
rw,
rw,
"-segaddr",
__TEXT,
0x2000000,
);
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
D497D0871C20FD53002BF46A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -2716,6 +3093,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C64FDA631D6D99F400F259B9 /* Build configuration list for PBXNativeTarget "PaintTest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C64FDA611D6D99F400F259B9 /* Debug */,
C64FDA621D6D99F400F259B9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D497D0731C20FD52002BF46A /* Build configuration list for PBXProject "OpenRCT2" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C64FDA5C1D6D99F400F259B9"
BuildableName = "PaintTest"
BlueprintName = "PaintTest"
ReferencedContainer = "container:OpenRCT2.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C64FDA5C1D6D99F400F259B9"
BuildableName = "PaintTest"
BlueprintName = "PaintTest"
ReferencedContainer = "container:OpenRCT2.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C64FDA5C1D6D99F400F259B9"
BuildableName = "PaintTest"
BlueprintName = "PaintTest"
ReferencedContainer = "container:OpenRCT2.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C64FDA5C1D6D99F400F259B9"
BuildableName = "PaintTest"
BlueprintName = "PaintTest"
ReferencedContainer = "container:OpenRCT2.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -13,10 +13,9 @@
<!-- Import custom build tasks -->
<Import Project="openrct2.targets" />
<!-- Import the C++ project for OpenRCT2 -->
<Import Project="openrct2.vcxproj" />
<PropertyGroup>
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
<Platform Condition="'$(PLATFORM)'==''">Win32</Platform>
<BUILD_SERVER Condition="'$(BUILD_SERVER)'==''">$(COMPUTERNAME)</BUILD_SERVER>
<GIT_COMMIT_SHA1_SHORT Condition="'$(GIT_COMMIT_SHA1)'!=''">$(GIT_COMMIT_SHA1.Substring(0, 7))</GIT_COMMIT_SHA1_SHORT>
@@ -36,12 +35,13 @@
<RootDir>$(MsBuildThisFileDirectory)</RootDir>
<DistDir>$(RootDir)distribution\</DistDir>
<ArtifactsDir>$(RootDir)artifacts\</ArtifactsDir>
<TargetDir>$(RootDir)bin\</TargetDir>
<NsisScript>$(DistDir)windows\install.nsi</NsisScript>
<OutputDll Condition="'$(Platform)'=='Win32'">$(TargetDir)openrct2.dll</OutputDll>
<OutputExe Condition="'$(Platform)'=='Win32'">$(TargetDir)openrct2.exe</OutputExe>
<OutputExe Condition="'$(Platform)'=='x64'">$(TargetPath)</OutputExe>
<OutputExe Condition="'$(Platform)'=='x64'">$(TargetDir)openrct2_x64.exe</OutputExe>
<OutputSegmentInfo Condition="'$(Platform)'=='x64'">$(TargetDir)openrct2_data</OutputSegmentInfo>
<g2Output>$(TargetDir)data\g2.dat</g2Output>
@@ -75,7 +75,7 @@
<ItemGroup Label="Symbol Items">
<SymbolItems Condition="'$(Platform)'=='Win32'" Include="$(OutputDll)" />
<SymbolItems Include="$(OutputExe)" />
<SymbolItems Include="$(TargetDir)$(TargetName).pdb" />
<SymbolItems Include="$([System.IO.Path]::ChangeExtension($(OutputExe), '.pdb'))" />
</ItemGroup>
<ItemGroup Label="Publish Items">
@@ -141,7 +141,7 @@
<WriteLinesToFile Lines="$(TargetLibsVersion)" File="$(LibsVersionPath)" Overwrite="true" />
</Target>
<Target Name="BeforeClean">
<Target Name="Clean">
<ItemGroup>
<CleanItems Condition="'$(Platform)'=='Win32'" Include="$(OutputExe)" />
<CleanItems Condition="'$(Platform)'=='x64'" Include="$(OutputSegmentInfo)" />
@@ -154,9 +154,10 @@
<Delete Files="@(CleanItems)" />
<Delete Files="%(SignItems.Identity).signed" />
<RemoveDir Directories="$(TargetDir)data" />
<MSBuild Projects="openrct2.sln" Targets="Clean" />
</Target>
<Target Name="BeforeBuild" BeforeTargets="InitializeBuildStatus" DependsOnTargets="CheckLibs">
<Target Name="BeforeBuild" BeforeTargets="Build;Rebuild" DependsOnTargets="CheckLibs">
<PropertyGroup>
<BuildString Condition="'$(GIT_COMMIT_SHA1_SHORT)'!=''">$(GIT_COMMIT_SHA1_SHORT)</BuildString>
<BuildString Condition="'$(GIT_BRANCH)'!=''">$(BuildString) ($(GIT_BRANCH))</BuildString>
@@ -169,6 +170,20 @@
<Message Condition="'$(BuildString)'!=''" Text="Building $(BuildString)" Importance="high" />
<Copy SourceFiles="@(CopyItems)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(DataItems)" DestinationFolder="$(TargetDir)data\%(RecursiveDir)" SkipUnchangedFiles="true" />
<!-- tests -->
<Copy SourceFiles="@(CopyItems)" DestinationFolder="$(TargetDir)testpaint\" />
</Target>
<Target Name="Build">
<MSBuild Projects="openrct2.sln" Targets="Build" />
</Target>
<Target Name="Rebuild">
<MSBuild Projects="openrct2.sln" Targets="Rebuild" />
</Target>
<Target Name="Test" DependsOnTargets="Build" Condition="'$(PLATFORM)'=='Win32'">
<Exec Command="$(TargetDir)testpaint\openrct2.exe" />
</Target>
<!-- Target to create the segment information x64 builds currently require -->

View File

@@ -5,6 +5,12 @@ VisualStudioVersion = 14.0.25420.1
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}") = "testpaint", "test\testpaint\testpaint.vcxproj", "{57E60BA1-FB76-4316-909E-C1449C142327}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2202A816-377D-4FA0-A7AF-7D4105F8A4FB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{480B577D-4E4A-4757-9A42-28A9AD33E6B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -21,8 +27,18 @@ Global
{D24D94F6-2A74-480C-B512-629C306CE92F}.Release|Win32.Build.0 = Release|Win32
{D24D94F6-2A74-480C-B512-629C306CE92F}.Release|x64.ActiveCfg = Release|x64
{D24D94F6-2A74-480C-B512-629C306CE92F}.Release|x64.Build.0 = Release|x64
{57E60BA1-FB76-4316-909E-C1449C142327}.Debug|Win32.ActiveCfg = Debug|Win32
{57E60BA1-FB76-4316-909E-C1449C142327}.Debug|Win32.Build.0 = Debug|Win32
{57E60BA1-FB76-4316-909E-C1449C142327}.Debug|x64.ActiveCfg = Debug|Win32
{57E60BA1-FB76-4316-909E-C1449C142327}.Release|Win32.ActiveCfg = Release|Win32
{57E60BA1-FB76-4316-909E-C1449C142327}.Release|Win32.Build.0 = Release|Win32
{57E60BA1-FB76-4316-909E-C1449C142327}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D24D94F6-2A74-480C-B512-629C306CE92F} = {2202A816-377D-4FA0-A7AF-7D4105F8A4FB}
{57E60BA1-FB76-4316-909E-C1449C142327} = {480B577D-4E4A-4757-9A42-28A9AD33E6B0}
EndGlobalSection
EndGlobal

View File

@@ -594,7 +594,7 @@ bool openrct2_setup_rct2_segment()
}
#if !defined(USE_MMAP)
// section: text
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC);
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC | PROT_WRITE);
if (err != 0)
{
perror("mprotect");

View File

@@ -4570,15 +4570,6 @@ TRACK_PAINT_FUNCTION get_track_paint_function_junior_rc(int trackType, int direc
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN:
return junior_rc_right_quarter_turn_3_tiles_25_deg_down_paint_setup;
case TRACK_ELEM_FLAT_TO_60_DEG_UP:
return junior_rc_flat_to_60_deg_up_paint_setup;
case TRACK_ELEM_60_DEG_UP_TO_FLAT:
return junior_rc_60_deg_up_to_flat_paint_setup;
case TRACK_ELEM_FLAT_TO_60_DEG_DOWN:
return junior_rc_flat_to_60_deg_down_paint_setup;
case TRACK_ELEM_60_DEG_DOWN_TO_FLAT:
return junior_rc_60_deg_down_to_flat_paint_setup;
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL:
return junior_rc_left_half_banked_helix_up_small_paint_setup;
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL:

View File

@@ -21,6 +21,7 @@
#include "../../paint/paint.h"
#include "../vehicle_paint.h"
#ifndef NO_VEHICLES
/**
*
* rct2: 0x006D4453
@@ -36,3 +37,4 @@ void vehicle_visual_reverser(int x, int imageDirection, int y, int z, rct_vehicl
gUnk9DE56C = y;
vehicle_visual_default(x, imageDirection, y, z, vehicle, vehicleEntry);
}
#endif

View File

@@ -3204,8 +3204,8 @@ static const uint32 _OldLaunchedFreefallTrackPaintFunctions[256] = {
0,
0,
0,
0,
0,
0x006FD1F8, // TRACK_ELEM_TOWER_BASE
0x006FD208, // TRACK_ELEM_TOWER_SECTION
0,
0,
0,

View File

@@ -183,6 +183,7 @@ static const uint32 river_rapids_track_pieces_25_deg_down_to_flat[][2] = {
{SPR_RIVER_RAPIDS_25_DEG_DOWN_TO_FLAT_SE_NW, SPR_RIVER_RAPIDS_25_DEG_DOWN_TO_FLAT_FRONT_SE_NW},
};
#ifndef NO_VEHICLES
/**
*
* rct2: 0x006D5889
@@ -248,6 +249,7 @@ void vehicle_visual_river_rapids(int x, int imageDirection, int y, int z, rct_ve
vehicle_visual_splash_effect(z, vehicle, vehicleEntry);
}
#endif
/** rct2: 0x00757650 */
static void paint_river_rapids_track_flat(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement)

View File

@@ -21,6 +21,7 @@
#include "../../paint/paint.h"
#include "../vehicle_paint.h"
#ifndef NO_VEHICLES
/**
*
* rct2: 0x006D4295
@@ -38,3 +39,4 @@ void vehicle_visual_splash_boats_or_water_coaster(int x, int imageDirection, int
gUnk9DE56C = vehicle->y;
vehicle_paint(vehicle, imageDirection);
}
#endif

View File

@@ -23,6 +23,7 @@
#include "../../paint/supports.h"
#include "../ride_data.h"
#ifndef NO_VEHICLES
/**
*
* rct2: 0x006D44D5
@@ -66,6 +67,7 @@ void vehicle_visual_submarine(int x, int imageDirection, int y, int z, rct_vehic
assert(vehicleEntry->effect_visual == 1);
}
#endif
static void submarine_ride_paint_track_station(uint8 rideIndex, uint8 trackSequence, uint8 direction, int height, rct_map_element * mapElement)
{

153
test/testpaint/compat.c Normal file
View File

@@ -0,0 +1,153 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include "../../src/config.h"
#include "../../src/object.h"
#include "../../src/interface/colour.h"
#include "../../src/interface/viewport.h"
#include "../../src/ride/ride.h"
#include "../../src/ride/track.h"
#include "../../src/world/sprite.h"
#include "../../src/paint/map_element/map_element.h"
#define RCT2_ADDRESS_SPRITE_LIST 0x010E63BC
#define gRideEntries RCT2_ADDRESS(RCT2_ADDRESS_RIDE_ENTRIES, rct_ride_entry*)
#define gCurrentRotation RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)
rct_map_element *gMapElements = (rct_map_element *) RCT2_ADDRESS_MAP_ELEMENTS;
rct_map_element **gMapElementTilePointers = (rct_map_element **) RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS;
rct_ride *gRideList = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride);
rct_sprite *sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite);
sint16 gMapSizeUnits;
sint16 gMapBaseZ;
bool gTrackDesignSaveMode = false;
uint8 gTrackDesignSaveRideIndex = 255;
const rct_xy16 TileDirectionDelta[] = {
{-32, 0},
{0, +32},
{+32, 0},
{0, -32},
{-32, +32},
{+32, +32},
{+32, -32},
{-32, -32}
};
uint8 get_current_rotation() {
return gCurrentRotation & 3;
}
const uint32 construction_markers[] = {
COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP, // White
2 << 19 | 0b110000 << 19 | IMAGE_TYPE_TRANSPARENT, // Translucent
};
int object_entry_group_counts[] = {
128, // rides
252, // small scenery
128, // large scenery
128, // walls
32, // banners
16, // paths
15, // path bits
19, // scenery sets
1, // park entrance
1, // water
1 // scenario text
};
general_configuration gConfigGeneral;
uint32 gCurrentViewportFlags = 0;
uint16 gMapSelectFlags;
uint16 gMapSelectType;
rct_xy16 gMapSelectPositionA;
rct_xy16 gMapSelectPositionB;
rct_xyz16 gMapSelectArrowPosition;
uint8 gMapSelectArrowDirection;
void entrance_paint(uint8 direction, int height, rct_map_element *map_element) { }
void banner_paint(uint8 direction, int height, rct_map_element *map_element) { }
void surface_paint(uint8 direction, uint16 height, rct_map_element *mapElement) { }
void path_paint(uint8 direction, uint16 height, rct_map_element *mapElement) { }
void scenery_paint(uint8 direction, int height, rct_map_element *mapElement) { }
void fence_paint(uint8 direction, int height, rct_map_element *mapElement) { }
void scenery_multiple_paint(uint8 direction, uint16 height, rct_map_element *mapElement) { }
rct_ride *get_ride(int index) {
if (index < 0 || index >= MAX_RIDES) {
log_error("invalid index %d for ride", index);
return NULL;
}
return &gRideList[index];
}
rct_ride_entry *get_ride_entry(int index) {
if (index < 0 || index >= object_entry_group_counts[OBJECT_TYPE_RIDE]) {
log_error("invalid index %d for ride type", index);
return NULL;
}
return gRideEntries[index];
}
rct_ride_entry *get_ride_entry_by_ride(rct_ride *ride) {
rct_ride_entry *type = get_ride_entry(ride->subtype);
if (type == NULL) {
log_error("Invalid ride subtype for ride");
}
return type;
}
rct_sprite *get_sprite(size_t sprite_idx) {
assert(sprite_idx < MAX_SPRITES);
return &sprite_list[sprite_idx];
}
int map_element_is_last_for_tile(const rct_map_element *element) {
return element->flags & MAP_ELEMENT_FLAG_LAST_TILE;
}
int map_element_get_type(const rct_map_element *element) {
return element->type & MAP_ELEMENT_TYPE_MASK;
}
int map_element_get_direction(const rct_map_element *element) {
return element->type & MAP_ELEMENT_DIRECTION_MASK;
}
rct_map_element *map_get_first_element_at(int x, int y) {
if (x < 0 || y < 0 || x > 255 || y > 255) {
log_error("Trying to access element outside of range");
return NULL;
}
return gMapElementTilePointers[x + y * 256];
}
int map_get_station(rct_map_element *mapElement) {
return (mapElement->properties.track.sequence & 0x70) >> 4;
}
bool ride_type_has_flag(int rideType, int flag)
{
return (RideProperties[rideType].flags & flag) != 0;
}
sint16 get_height_marker_offset()
{
return 0;
}

628
test/testpaint/data.c Normal file
View File

@@ -0,0 +1,628 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include "../../src/common.h"
const utf8string RideNames[91] = {
"SpiralRollerCoaster",
"StandUpRollerCoaster",
"SuspendedSwingingCoaster",
"InvertedRollerCoaster",
"JuniorRollerCoaster",
"MiniatureRailway",
"Monorail",
"MiniSuspendedCoaster",
"BoatRide",
"WoodenWildMouse",
"Steeplechase",
"CarRide",
"LaunchedFreefall",
"BobsleighCoaster",
"ObservationTower",
"LoopingRollerCoaster",
"DinghySlide",
"MineTrainCoaster",
"Chairlift",
"CorkscrewRollerCoaster",
"Maze",
"SpiralSlide",
"GoKarts",
"LogFlume",
"RiverRapids",
"Dodgems",
"PirateShip",
"SwingingInverterShip",
"FoodStall",
"1D",
"DrinkStall",
"1F",
"Shop",
"MerryGoRound",
"22",
"InformationKiosk",
"Toilets",
"FerrisWheel",
"MotionSimulator",
"3DCinema",
"TopSpin",
"SpaceRings",
"ReverseFreefallCoaster",
"Lift",
"VerticalDropRollerCoaster",
"CashMachine",
"Twist",
"HauntedHouse",
"FirstAid",
"CircusShow",
"GhostTrain",
"TwisterRollerCoaster",
"WoodenRollerCoaster",
"SideFrictionRollerCoaster",
"WildMouse",
"MultiDimensionRollerCoaster",
"MultiDimensionRollerCoasterAlt",
"FlyingRollerCoaster",
"FlyingRollerCoasterAlt",
"VirginiaReel",
"SplashBoats",
"MiniHelicopters",
"LayDownRollerCoaster",
"SuspendedMonorail",
"LayDownRollerCoasterAlt",
"ReverserRollerCoaster",
"HeartlineTwisterCoaster",
"MiniGolf",
"GigaCoaster",
"RoToDrop",
"FlyingSaucers",
"CrookedHouse",
"MonorailCycles",
"CompactInvertedCoaster",
"WaterCoaster",
"AirPoweredVerticalCoaster",
"InvertedHairpinCoaster",
"MagicCarpet",
"SubmarineRide",
"RiverRafts",
"50",
"Enterprise",
"52",
"53",
"54",
"55",
"InvertedImpulseCoaster",
"MiniRollerCoaster",
"MineRide",
"59",
"LimLaunchedRollerCoaster",
};
const utf8string TrackNames[256] = {
"Flat",
"EndStation",
"BeginStation",
"MiddleStation",
"25DegUp",
"60DegUp",
"FlatTo25DegUp",
"25DegUpTo60DegUp",
"60DegUpTo25DegUp",
"25DegUpToFlat",
"25DegDown",
"60DegDown",
"FlatTo25DegDown",
"25DegDownTo60DegDown",
"60DegDownTo25DegDown",
"25DegDownToFlat",
"LeftQuarterTurn5Tiles",
"RightQuarterTurn5Tiles",
"FlatToLeftBank",
"FlatToRightBank",
"LeftBankToFlat",
"RightBankToFlat",
"BankedLeftQuarterTurn5Tiles",
"BankedRightQuarterTurn5Tiles",
"LeftBankTo25DegUp",
"RightBankTo25DegUp",
"25DegUpToLeftBank",
"25DegUpToRightBank",
"LeftBankTo25DegDown",
"RightBankTo25DegDown",
"25DegDownToLeftBank",
"25DegDownToRightBank",
"LeftBank",
"RightBank",
"LeftQuarterTurn5Tiles25DegUp",
"RightQuarterTurn5Tiles25DegUp",
"LeftQuarterTurn5Tiles25DegDown",
"RightQuarterTurn5Tiles25DegDown",
"SBendLeft",
"SBendRight",
"LeftVerticalLoop",
"RightVerticalLoop",
"LeftQuarterTurn3Tiles",
"RightQuarterTurn3Tiles",
"LeftQuarterTurn3TilesBank",
"RightQuarterTurn3TilesBank",
"LeftQuarterTurn3Tiles25DegUp",
"RightQuarterTurn3Tiles25DegUp",
"LeftQuarterTurn3Tiles25DegDown",
"RightQuarterTurn3Tiles25DegDown",
"LeftQuarterTurn1Tile",
"RightQuarterTurn1Tile",
"LeftTwistDownToUp",
"RightTwistDownToUp",
"LeftTwistUpToDown",
"RightTwistUpToDown",
"HalfLoopUp",
"HalfLoopDown",
"LeftCorkscrewUp",
"RightCorkscrewUp",
"LeftCorkscrewDown",
"RightCorkscrewDown",
"FlatTo60DegUp",
"60DegUpToFlat",
"FlatTo60DegDown",
"60DegDownToFlat",
"TowerBase",
"TowerSection",
"FlatCovered",
"25DegUpCovered",
"60DegUpCovered",
"FlatTo25DegUpCovered",
"25DegUpTo60DegUpCovered",
"60DegUpTo25DegUpCovered",
"25DegUpToFlatCovered",
"25DegDownCovered",
"60DegDownCovered",
"FlatTo25DegDownCovered",
"25DegDownTo60DegDownCovered",
"60DegDownTo25DegDownCovered",
"25DegDownToFlatCovered",
"LeftQuarterTurn5TilesCovered",
"RightQuarterTurn5TilesCovered",
"SBendLeftCovered",
"SBendRightCovered",
"LeftQuarterTurn3TilesCovered",
"RightQuarterTurn3TilesCovered",
"LeftHalfBankedHelixUpSmall",
"RightHalfBankedHelixUpSmall",
"LeftHalfBankedHelixDownSmall",
"RightHalfBankedHelixDownSmall",
"LeftHalfBankedHelixUpLarge",
"RightHalfBankedHelixUpLarge",
"LeftHalfBankedHelixDownLarge",
"RightHalfBankedHelixDownLarge",
"LeftQuarterTurn1Tile60DegUp",
"RightQuarterTurn1Tile60DegUp",
"LeftQuarterTurn1Tile60DegDown",
"RightQuarterTurn1Tile60DegDown",
"Brakes",
"RotationControlToggle",
"Inverted90DegUpToFlatQuarterLoop_Maze",
"LeftQuarterBankedHelixLargeUp",
"RightQuarterBankedHelixLargeUp",
"LeftQuarterBankedHelixLargeDown",
"RightQuarterBankedHelixLargeDown",
"LeftQuarterHelixLargeUp",
"RightQuarterHelixLargeUp",
"LeftQuarterHelixLargeDown",
"RightQuarterHelixLargeDown",
"25DegUpLeftBanked",
"25DegUpRightBanked",
"Waterfall",
"Rapids",
"OnRidePhoto",
"25DegDownLeftBanked",
"25DegDownRightBanked",
"WaterSplash",
"FlatTo60DegUpLongBase",
"60DegUpToFlatLongBase",
"Whirlpool",
"FlatTo60DegDownLongBase",
"60DegUpToFlatLongBase122",
"CableLiftHill",
"ReverseWhoaBellySlope",
"ReverseWhoaBellyVertical",
"90DegUp",
"90DegDown",
"60DegUpTo90DegUp",
"90DegDownTo60DegDown",
"90DegUpTo60DegUp",
"60DegDownTo90DegDown",
"BrakeForDrop",
"LeftEighthToDiag",
"RightEighthToDiag",
"LeftEighthToOrthogonal",
"RightEighthToOrthogonal",
"LeftEighthBankToDiag",
"RightEighthBankToDiag",
"LeftEighthBankToOrthogonal",
"RightEighthBankToOrthogonal",
"DiagFlat",
"Diag25DegUp",
"Diag60DegUp",
"DiagFlatTo25DegUp",
"Diag25DegUpTo60DegUp",
"Diag60DegUpTo25DegUp",
"Diag25DegUpToFlat",
"Diag25DegDown",
"Diag60DegDown",
"DiagFlatTo25DegDown",
"Diag25DegDownTo60DegDown",
"Diag60DegDownTo25DegDown",
"Diag25DegDownToFlat",
"DiagFlatTo60DegUp",
"Diag60DegUpToFlat",
"DiagFlatTo60DegDown",
"Diag60DegDownToFlat",
"DiagFlatToLeftBank",
"DiagFlatToRightBank",
"DiagLeftBankToFlat",
"DiagRightBankToFlat",
"DiagLeftBankTo25DegUp",
"DiagRightBankTo25DegUp",
"Diag25DegUpToLeftBank",
"Diag25DegUpToRightBank",
"DiagLeftBankTo25DegDown",
"DiagRightBankTo25DegDown",
"Diag25DegDownToLeftBank",
"Diag25DegDownToRightBank",
"DiagLeftBank",
"DiagRightBank",
"LogFlumeReverser",
"SpinningTunnel",
"LeftBarrelRollUpToDown",
"RightBarrelRollUpToDown",
"LeftBarrelRollDownToUp",
"RightBarrelRollDownToUp",
"LeftBankToLeftQuarterTurn3Tiles25DegUp",
"RightBankToRightQuarterTurn3Tiles25DegUp",
"LeftQuarterTurn3Tiles25DegDownToLeftBank",
"RightQuarterTurn3Tiles25DegDownToRightBank",
"PoweredLift",
"LeftLargeHalfLoopUp",
"RightLargeHalfLoopUp",
"RightLargeHalfLoopDown",
"LeftLargeHalfLoopDown",
"LeftFlyerTwistUp",
"RightFlyerTwistUp",
"LeftFlyerTwistDown",
"RightFlyerTwistDown",
"FlyerHalfLoopUp",
"FlyerHalfLoopDown",
"LeftFlyerCorkscrewUp",
"RightFlyerCorkscrewUp",
"LeftFlyerCorkscrewDown",
"RightFlyerCorkscrewDown",
"HeartlineTransferUp",
"HeartlineTransferDown",
"LeftHeartlineRoll",
"RightHeartlineRoll",
"MiniGolfHoleA",
"MiniGolfHoleB",
"MiniGolfHoleC",
"MiniGolfHoleD",
"MiniGolfHoleE",
"MultidimInvertedFlatTo90DegQuarterLoopDown",
"90DegToInvertedFlatQuarterLoopUp",
"InvertedFlatTo90DegQuarterLoopDown",
"LeftCurvedLiftHill",
"RightCurvedLiftHill",
"LeftReverser",
"RightReverser",
"AirThrustTopCap",
"AirThrustVerticalDown",
"AirThrustVerticalDownToLevel",
"BlockBrakes",
"LeftBankedQuarterTurn3Tile25DegUp",
"RightBankedQuarterTurn3Tile25DegUp",
"LeftBankedQuarterTurn3Tile25DegDown",
"RightBankedQuarterTurn3Tile25DegDown",
"LeftBankedQuarterTurn5Tile25DegUp",
"RightBankedQuarterTurn5Tile25DegUp",
"LeftBankedQuarterTurn5Tile25DegDown",
"RightBankedQuarterTurn5Tile25DegDown",
"25DegUpToLeftBanked25DegUp",
"25DegUpToRightBanked25DegUp",
"LeftBanked25DegUpTo25DegUp",
"RightBanked25DegUpTo25DegUp",
"25DegDownToLeftBanked25DegDown",
"25DegDownToRightBanked25DegDown",
"LeftBanked25DegDownTo25DegDown",
"RightBanked25DegDownTo25DegDown",
"LeftBankedFlatToLeftBanked25DegUp",
"RightBankedFlatToRightBanked25DegUp",
"LeftBanked25DegUpToLeftBankedFlat",
"RightBanked25DegUpToRightBankedFlat",
"LeftBankedFlatToLeftBanked25DegDown",
"RightBankedFlatToRightBanked25DegDown",
"LeftBanked25DegDownToLeftBankedFlat",
"RightBanked25DegDownToRightBankedFlat",
"FlatToLeftBanked25DegUp",
"FlatToRightBanked25DegUp",
"LeftBanked25DegUpToFlat",
"RightBanked25DegUpToFlat",
"FlatToLeftBanked25DegDown",
"FlatToRightBanked25DegDown",
"LeftBanked25DegDownToFlat",
"RightBanked25DegDownToFlat",
"LeftQuarterTurn1Tile90DegUp",
"RightQuarterTurn1Tile90DegUp",
"LeftQuarterTurn1Tile90DegDown",
"RightQuarterTurn1Tile90DegDown",
"Multidim90DegUpToInvertedFlatQuarterLoop",
"MultidimFlatTo90DegDownQuarterLoop",
};
const utf8string FlatTrackNames[256] = {
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"1x4_A",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"2x2",
"4x4",
"",
"",
"",
"",
"1x5",
"",
"1x1_A",
"1x4_B",
"",
"1x1_B",
"1x4_C",
"3x3",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};

26
test/testpaint/data.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#ifndef _TEST_PAINT_DATA_H_
#define _TEST_PAINT_DATA_H_
#include "../../src/common.h"
extern const utf8string RideNames[91];
extern const utf8string TrackNames[256];
extern const utf8string FlatTrackNames[256];
#endif // #endif _TEST_PAINT_DATA_H_

747
test/testpaint/intercept.c Normal file
View File

@@ -0,0 +1,747 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include "intercept.h"
#include "../../src/paint/paint.h"
#include "../../src/paint/supports.h"
#include "../../src/ride/track_data.h"
#include "../../src/interface/viewport.h"
#include "../../src/hook.h"
static const uint32 DEFAULT_SCHEME_TRACK = COLOUR_GREY << 19 | COLOUR_WHITE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_SUPPORTS = COLOUR_LIGHT_BLUE << 19 | COLOUR_ICY_BLUE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_MISC = COLOUR_DARK_PURPLE << 19 | COLOUR_LIGHT_PURPLE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_3 = COLOUR_BRIGHT_PURPLE << 19 | COLOUR_DARK_BLUE << 24 | 0xA0000000;
extern const utf8string RideNames[91];
extern const utf8string TrackNames[256];
extern const utf8string FlatTrackNames[256];
enum
{
PAINT_98196C,
PAINT_98197C,
PAINT_98198C,
PAINT_98199C,
SUPPORTS_METAL_A,
SUPPORTS_METAL_B,
SUPPORTS_WOOD_A,
SUPPORTS_WOOD_B,
};
typedef struct
{
uint8 function;
struct paint
{
uint32 image_id;
rct_xy16 offset;
rct_xyz16 bound_box_length;
sint16 z_offset;
rct_xyz16 bound_box_offset;
uint32 rotation;
} paint;
struct supports
{
int type;
uint8 segment;
int special;
int height;
uint32 colour_flags;
} supports;
} function_call;
static uint8 callCount;
static bool assertFunctionCallEquals(function_call expected, function_call actual);
static function_call calls[256];
bool paint_attach_to_previous_ps(uint32 image_id, uint16 x, uint16 y) {
return false;
}
paint_struct *sub_98196C(
uint32 image_id,
sint8 x_offset, sint8 y_offset,
sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
sint16 z_offset,
uint32 rotation
) {
function_call call = {
.function = PAINT_98196C,
.paint = {
.image_id = image_id,
.offset = {x_offset, y_offset},
.bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z},
.z_offset = z_offset,
.rotation = rotation
},
};
calls[callCount] = call;
callCount++;
return NULL;
}
paint_struct *sub_98197C(
uint32 image_id,
sint8 x_offset, sint8 y_offset,
sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
sint16 z_offset,
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
function_call call = {
.function = PAINT_98197C,
.paint = {
.image_id = image_id,
.offset = {x_offset, y_offset},
.bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z},
.bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z},
.z_offset = z_offset,
.rotation = rotation,
},
};
calls[callCount] = call;
callCount++;
return NULL;
}
paint_struct *sub_98198C(
uint32 image_id,
sint8 x_offset, sint8 y_offset,
sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
sint16 z_offset,
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
function_call call = {
.function = PAINT_98198C,
.paint = {
.image_id = image_id,
.offset = {x_offset, y_offset},
.bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z},
.bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z},
.z_offset = z_offset,
.rotation = rotation,
},
};
calls[callCount] = call;
callCount++;
return NULL;
}
paint_struct *sub_98199C(
uint32 image_id,
sint8 x_offset, sint8 y_offset,
sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z,
sint16 z_offset,
sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z,
uint32 rotation
) {
function_call call = {
.function = PAINT_98199C,
.paint = {
.image_id = image_id,
.offset = {x_offset, y_offset},
.bound_box_length = {bound_box_length_x, bound_box_length_y, bound_box_length_z},
.bound_box_offset = {bound_box_offset_x, bound_box_offset_y, bound_box_offset_z},
.z_offset = z_offset,
.rotation = rotation,
},
};
calls[callCount] = call;
callCount++;
return NULL;
}
bool wooden_a_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags, bool *underground) {
function_call call = {
.function = SUPPORTS_WOOD_A,
.supports = {
.type = supportType,
.special = special,
.height = height,
.colour_flags = imageColourFlags,
}
};
calls[callCount] = call;
callCount++;
return false;
}
bool wooden_b_supports_paint_setup(int supportType, int special, int height, uint32 imageColourFlags) {
function_call call = {
.function = SUPPORTS_WOOD_B,
.supports = {
.type = supportType,
.special = special,
.height = height,
.colour_flags = imageColourFlags,
}
};
calls[callCount] = call;
callCount++;
return false;
}
bool metal_a_supports_paint_setup(int supportType, int segment, int special, int height, uint32 imageColourFlags) {
function_call call = {
.function = SUPPORTS_METAL_A,
.supports = {
.type = supportType,
.segment = segment,
.special = special,
.height = height,
.colour_flags = imageColourFlags,
}
};
calls[callCount] = call;
callCount++;
return false;
}
bool metal_b_supports_paint_setup(int supportType, uint8 segment, int special, int height, uint32 imageColourFlags) {
function_call call = {
.function = SUPPORTS_METAL_B,
.supports = {
.type = supportType,
.segment = segment,
.special = special,
.height = height,
.colour_flags = imageColourFlags,
}
};
calls[callCount] = call;
callCount++;
return false;
}
enum {
SPRITEGROUP_NONE,
SPRITEGROUP_FENCE_METAL_A, // 14568
SPRITEGROUP_FENCE_METAL_B, // 14990
SPRITEGROUP_FLOOR_CORK, // 22134
SPRITEGROUP_FENCE_ROPE, // 22138
};
static int getSpriteGroup(uint16 spriteIndex) {
if (spriteIndex >= 14568 && spriteIndex <= 14571) {
return SPRITEGROUP_FENCE_METAL_A;
}
if (spriteIndex >= 14990 && spriteIndex <= 14993) {
return SPRITEGROUP_FENCE_METAL_B;
}
if (spriteIndex >= 22134 && spriteIndex <= 22137) {
return SPRITEGROUP_FLOOR_CORK;
}
if (spriteIndex >= 22138 && spriteIndex <= 22141) {
return SPRITEGROUP_FENCE_ROPE;
}
return SPRITEGROUP_NONE;
}
static void canonicalizeFunctionCall(function_call *call) {
if (call->function != PAINT_98197C) return;
if (call->paint.offset.x != call->paint.bound_box_offset.x) return;
if (call->paint.offset.y != call->paint.bound_box_offset.y) return;
if (call->paint.z_offset != call->paint.bound_box_offset.z) return;
call->function = PAINT_98196C;
}
static bool assertFunctionCallEquals(function_call expected, function_call actual) {
canonicalizeFunctionCall(&actual);
canonicalizeFunctionCall(&expected);
if (expected.function != actual.function) {
return false;
}
uint8 function = expected.function;
if (function == SUPPORTS_WOOD_A || function == SUPPORTS_WOOD_B) {
if (expected.supports.type != actual.supports.type) return false;
if (expected.supports.special != actual.supports.special) return false;
if (expected.supports.height != actual.supports.height) return false;
if (expected.supports.colour_flags != actual.supports.colour_flags) return false;
return true;
}
if (function == SUPPORTS_METAL_A || function == SUPPORTS_METAL_B) {
if (expected.supports.type != actual.supports.type) return false;
if (expected.supports.segment != actual.supports.segment) return false;
if (expected.supports.special != actual.supports.special) return false;
if (expected.supports.height != actual.supports.height) return false;
if (expected.supports.colour_flags != actual.supports.colour_flags) return false;
return true;
}
if (expected.paint.image_id != actual.paint.image_id) {
int expectedSpriteGroup = getSpriteGroup(expected.paint.image_id & 0x7FFFF);
int actualSpriteGroup = getSpriteGroup(actual.paint.image_id & 0x7FFFF);
if (expectedSpriteGroup != actualSpriteGroup) return false;
if (expectedSpriteGroup == SPRITEGROUP_NONE) return false;
return true;
}
if (expected.paint.offset.x != actual.paint.offset.x) return false;
if (expected.paint.offset.y != actual.paint.offset.y) return false;
if (expected.paint.bound_box_length.x != actual.paint.bound_box_length.x) return false;
if (expected.paint.bound_box_length.y != actual.paint.bound_box_length.y) return false;
if (expected.paint.bound_box_length.z != actual.paint.bound_box_length.z) return false;
if (function != PAINT_98196C) {
if (expected.paint.bound_box_offset.x != actual.paint.bound_box_offset.x) return false;
if (expected.paint.bound_box_offset.y != actual.paint.bound_box_offset.y) return false;
if (expected.paint.bound_box_offset.z != actual.paint.bound_box_offset.z) return false;
}
if (expected.paint.z_offset != actual.paint.z_offset) return false;
if (expected.paint.rotation != actual.paint.rotation) return false;
return true;
}
static bool assertFunctionCallArrayEquals(function_call expected[], uint8 expectedCount, function_call actual[], uint8 actualCount) {
if (expectedCount != actualCount) {
return false;
}
for (int i = 0; i < expectedCount; i++) {
function_call expectedCall = expected[i];
function_call actualCall = actual[i];
if (!assertFunctionCallEquals(expectedCall, actualCall)) {
return false;
}
}
return true;
}
static void printImageId(uint32 input, utf8string *out) {
uint32 image = input & 0x7FFFF;
uint32 palette = input & ~0x7FFFF;
bool allocated = false;
utf8string paletteName;
if (palette == DEFAULT_SCHEME_TRACK)paletteName = "SCHEME_TRACK";
else if (palette == DEFAULT_SCHEME_SUPPORTS)paletteName = "SCHEME_SUPPORTS";
else if (palette == DEFAULT_SCHEME_MISC)paletteName = "SCHEME_MISC";
else if (palette == DEFAULT_SCHEME_3)paletteName = "SCHEME_3";
else {
paletteName = malloc(16);
sprintf(paletteName, "0x%08X", palette);
}
if (image == 0) {
sprintf(*out, "%s", paletteName);
} else if (image & 0x70000) {
sprintf(*out, "%s | vehicle.base_image_id + %d", paletteName, image & ~0x70000);
} else {
sprintf(*out, "%s | %d", paletteName, image);
}
}
static void printFunctionCall(utf8string *out, function_call call) {
utf8string imageId = malloc(64);
printImageId(call.supports.colour_flags, &imageId);
switch (call.function) {
case SUPPORTS_WOOD_A:
sprintf(*out, "wooden_a_supports_paint_setup(%d, %d, %d, %s)", call.supports.type, call.supports.special, call.supports.height, imageId);
return;
case SUPPORTS_WOOD_B:
sprintf(*out, "wooden_a_supports_paint_setup(%d, %d, %d, %s)", call.supports.type, call.supports.special, call.supports.height, imageId);
return;
case SUPPORTS_METAL_A:
sprintf(*out, "metal_a_supports_paint_setup(%d, %d, %d, %d, %s)", call.supports.type, call.supports.segment, call.supports.special, call.supports.height, imageId);
return;
case SUPPORTS_METAL_B:
sprintf(*out, "metal_b_supports_paint_setup(%d, %d, %d, %d, %s)", call.supports.type, call.supports.segment, call.supports.special, call.supports.height, imageId);
return;
}
utf8string name = "_default";
switch (call.function) {
case PAINT_98196C:
name = "sub_98196C";
break;
case PAINT_98197C:
name = "sub_98197C";
break;
case PAINT_98198C:
name = "sub_98198C";
break;
case PAINT_98199C:
name = "sub_98199C";
break;
}
int strlen;
printImageId(call.paint.image_id, &imageId);
strlen = sprintf(
*out,
"%s(%s, %d, %d, %d, %d, %d, %d, ",
name,
imageId,
call.paint.offset.x, call.paint.offset.y,
call.paint.bound_box_length.x, call.paint.bound_box_length.y, call.paint.bound_box_length.z,
call.paint.z_offset
);
if (call.function != PAINT_98196C) {
strlen += sprintf(
*out + strlen,
"%d, %d, %d, ",
call.paint.bound_box_offset.x, call.paint.bound_box_offset.y, call.paint.bound_box_offset.z
);
}
sprintf(*out + strlen, "%d)", call.paint.rotation);
}
static void printFunctionCallArray(utf8string *out, function_call calls[], uint8 count) {
for (int i = 0; i < count; i++) {
utf8string callOut = malloc(128);
printFunctionCall(&callOut, calls[i]);
sprintf(*out + strlen(*out), "%s\n", callOut);
}
}
int getTrackSequenceCount(uint8 rideType, uint8 trackType) {
int sequenceCount = 0;
const rct_preview_track **trackBlocks;
if (ride_type_has_flag(rideType, RIDE_TYPE_FLAG_FLAT_RIDE)) {
trackBlocks = FlatRideTrackBlocks;
} else {
trackBlocks = TrackBlocks;
}
for (int i = 0; i < 256; i++) {
if (trackBlocks[trackType][i].index == 0xFF) {
break;
}
sequenceCount++;
}
return sequenceCount;
}
bool rideSupportsTrackType(int rideType, int trackType)
{
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
if (newPaintGetter == NULL) {
return false;
}
if (newPaintGetter(trackType, 0) == NULL) {
return false;
}
if (RideTypeTrackPaintFunctionsOld[rideType][trackType] == 0) {
return false;
}
return true;
}
extern bool testSupportSegments(uint8 rideType, uint8 trackType);
extern bool testTunnels(uint8 rideType, uint8 trackType);
extern bool testVerticalTunnels(uint8 rideType, uint8 trackType);
static bool testTrackElement(uint8 rideType, uint8 trackType, utf8string *error) {
if (rideType == RIDE_TYPE_CHAIRLIFT) {
if (trackType == TRACK_ELEM_BEGIN_STATION || trackType == TRACK_ELEM_MIDDLE_STATION || trackType == TRACK_ELEM_END_STATION) {
// These rides chechk neighbouring tiles for tracks
sprintf(*error, "Skipped");
return false;
}
}
uint8 rideIndex = 0;
rct_map_element mapElement = { 0 };
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = 3;
g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = { 0 };
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2;
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK;
gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS;
gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC;
gTrackColours[SCHEME_3] = DEFAULT_SCHEME_3;
rct_drawpixelinfo dpi = {.zoom_level = 1};
unk_140E9A8 = &dpi;
rct_vehicle vehicle = { 0 };
rct_ride ride = { 0 };
rct_ride_entry rideEntry = { 0 };
rct_ride_entry_vehicle vehicleEntry = {.base_image_id = 0x70000};
rideEntry.vehicles[0] = vehicleEntry;
gRideList[0] = ride;
gRideEntries[0] = &rideEntry;
int height = 48;
sprintf(*error, "rct2: 0x%08X\n", RideTypeTrackPaintFunctionsOld[rideType][trackType]);
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
int sequenceCount = getTrackSequenceCount(rideType, trackType);
for (int currentRotation = 0; currentRotation < 4; currentRotation++) {
gCurrentRotation = currentRotation;
for (int direction = 0; direction < 4; direction++) {
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
RCT2_GLOBAL(0x009DE56A, sint16) = 64; // x
RCT2_GLOBAL(0x009DE56E, sint16) = 64; // y
gDidPassSurface = true; // Above surface
gSurfaceElement = &surfaceElement;
g141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2;
callCount = 0;
memset(&calls, 0, sizeof(calls));
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType];
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
rideType,
(int) trackDirectionList,
direction,
height,
(int) &mapElement,
rideIndex * sizeof(rct_ride),
trackSequence
);
// segment heights
// tunnels
uint8 oldCallCount = callCount;
function_call oldCalls[256];
memcpy(&oldCalls, &calls, sizeof(calls));
callCount = 0;
newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement);
uint8 newCallCount = callCount;
function_call newCalls[256];
memcpy(&newCalls, &calls, sizeof(calls));
if (!assertFunctionCallArrayEquals(oldCalls, oldCallCount, newCalls, newCallCount)) {
utf8string diff = malloc(2048);
sprintf(diff, "<<< EXPECTED\n");
printFunctionCallArray(&diff, oldCalls, oldCallCount);
sprintf(diff + strlen(diff), "====\n");
printFunctionCallArray(&diff, newCalls, newCallCount);
sprintf(diff + strlen(diff), ">>> ACTUAL\n");
if (oldCallCount != newCallCount) {
sprintf(*error + strlen(*error), "Call counts don't match (was %d, expected %d) [direction:%d trackSequence:%d]", newCallCount, oldCallCount, direction, trackSequence);
} else {
sprintf(*error + strlen(*error), "Calls don't match [direction:%d trackSequence:%d]", direction, trackSequence);
}
sprintf(*error + strlen(*error), "\n%s", diff);
free(diff);
return false;
}
}
}
}
sprintf(*error + strlen(*error), "");
bool segmentSuccess = testSupportSegments(rideType, trackType);
if (!segmentSuccess) {
return false;
}
bool tunnelSuccess = testTunnels(rideType, trackType);
if (!tunnelSuccess) {
return false;
}
bool verticalTunnelSuccess = testVerticalTunnels(rideType, trackType);
if (!verticalTunnelSuccess) {
return false;
}
return true;
}
bool rideIsImplemented(int rideType) {
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
return (newPaintGetter != 0);
}
bool testTrackPainting(int rideType, int trackType) {
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
if (newPaintGetter == NULL) {
return false;
}
if (newPaintGetter(trackType, 0) == NULL) {
return false;
}
utf8string error = malloc(2048);
bool success = testTrackElement(rideType, trackType, &error);
if (!success) {
printf("%s\n", error);
}
free(error);
return success;
}
static int intercept_draw_6c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp};
if ((ebp & 0x03) != get_current_rotation()) {
// Log error
log_error("Ebp is different from current rotation");
}
return (int) sub_98196C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, regs.ebp & 0x03);
}
static int intercept_draw_7c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp};
if ((ebp & 0x03) != get_current_rotation()) {
// Log error
log_error("Ebp is different from current rotation");
}
rct_xyz16 boundOffset = {
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, sint16)
};
return (int) sub_98197C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, boundOffset.x, boundOffset.y, boundOffset.z, regs.ebp & 0x03);
}
static int intercept_draw_9c(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .ecx = ecx, .edx = edx, .esi = esi, .edi = edi, .ebp = ebp};
if ((ebp & 0x03) != get_current_rotation()) {
// Log error
log_error("Ebp is different from current rotation");
}
rct_xyz16 boundOffset = {
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y, sint16),
RCT2_GLOBAL(RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z, sint16)
};
return (int) sub_98199C(ebx, regs.al, regs.cl, regs.di, regs.si, regs.ah, regs.dx, boundOffset.x, boundOffset.y, boundOffset.z, regs.ebp & 0x03);
}
static uint32 intercept_wooden_a_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp};
wooden_a_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp, NULL);
return 0;
}
static uint32 intercept_wooden_b_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp};
wooden_b_supports_paint_setup(regs.edi, (sint16) regs.ax, regs.dx, (uint32) regs.ebp);
return 0;
}
static uint32 intercept_metal_a_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp};
metal_a_supports_paint_setup(regs.edi, regs.ebx, (sint16) regs.ax, regs.dx, (uint32) regs.ebp);
return 0;
}
static uint32 intercept_metal_b_supports(uint32 eax, uint32 ebx, uint32 edx, uint32 edi, uint32 ebp) {
registers regs = {.eax =eax, .ebx = ebx, .edx = edx, .edi = edi, .ebp = ebp};
metal_b_supports_paint_setup(regs.edi, regs.ebx, (sint16) regs.ax, regs.dx, (uint32) regs.ebp);
return 0;
}
void initHooks() {
addhook(0x00686806, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x006869B2, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x00686B6F, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x00686D31, (int) intercept_draw_7c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x006861AC, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x00686337, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x006864D0, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x0068666B, (int) intercept_draw_6c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x006874B0, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x00687618, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x0068778C, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x00687902, (int) intercept_draw_9c, 0, (int[]) {EAX, EBX, ECX, EDX, ESI, EDI, EBP, END}, 0, EBP);
addhook(0x006629BC, (int) intercept_wooden_a_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX);
addhook(0x00662D5C, (int) intercept_wooden_b_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX);
addhook(0x00663105, (int) intercept_metal_a_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX);
addhook(0x00663584, (int) intercept_metal_b_supports, 0, (int[]) {EAX, EBX, EDX, EDI, EBP, END}, 0, EAX);
}

View File

@@ -0,0 +1,35 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#ifndef _TEST_PAINT_INTERCEPT_H_
#define _TEST_PAINT_INTERCEPT_H_
#include "../../src/common.h"
#define gRideEntries RCT2_ADDRESS(RCT2_ADDRESS_RIDE_ENTRIES, rct_ride_entry*)
#define gCurrentRotation RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)
bool testRide(int rideType);
void initHooks();
int getTrackSequenceCount(uint8 rideType, uint8 trackType);
bool rideIsImplemented(int rideType);
bool rideSupportsTrackType(int rideType, int trackType);
bool testTrackPainting(int rideType, int trackType);
bool testSupportSegments(uint8 rideType, uint8 trackType);
bool testTunnels(uint8 rideType, uint8 trackType);
bool testVerticalTunnels(uint8 rideType, uint8 trackType);
#endif // #endif _TEST_PAINT_INTERCEPT_H_

View File

@@ -0,0 +1,817 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include <vector>
#include <algorithm>
extern "C" {
#include "intercept.h"
#include "../../src/paint/paint.h"
#include "../../src/paint/supports.h"
#include "../../src/ride/track_data.h"
#include "../../src/interface/viewport.h"
#include "../../src/hook.h"
}
namespace Intercept2
{
static const uint32 DEFAULT_SCHEME_TRACK = COLOUR_GREY << 19 | COLOUR_WHITE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_SUPPORTS = COLOUR_LIGHT_BLUE << 19 | COLOUR_ICY_BLUE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_MISC = COLOUR_DARK_PURPLE << 19 | COLOUR_LIGHT_PURPLE << 24 | 0xA0000000;
static const uint32 DEFAULT_SCHEME_3 = COLOUR_BRIGHT_PURPLE << 19 | COLOUR_DARK_BLUE << 24 | 0xA0000000;
struct SegmentSupportCall
{
uint16 segments;
sint32 height;
sint16 slope;
};
struct SupportCall
{
sint32 height;
sint16 slope;
};
enum {
TUNNELCALL_SKIPPED,
TUNNELCALL_NONE,
TUNNELCALL_CALL,
};
struct TunnelCall {
uint8 call;
sint16 offset;
uint8 type;
};
static bool SortSegmentSupportCalls(SegmentSupportCall lhs, SegmentSupportCall rhs)
{
if (lhs.height != rhs.height) {
return lhs.height < rhs.height;
}
if (lhs.slope != rhs.slope) {
return lhs.slope < rhs.slope;
}
return lhs.segments < rhs.segments;
}
static std::vector<SegmentSupportCall> getSegmentCalls(support_height supports[9], uint8 rotation)
{
uint16 positionsRemaining = SEGMENTS_ALL;
for (int i = 0; i < 9; i++) {
if (supports[i].height == 0 && supports[i].slope == 0xFF) {
positionsRemaining &= ~segment_offsets[i];
}
}
std::vector<SegmentSupportCall> calls;
while (positionsRemaining != 0) {
SegmentSupportCall call = {0};
call.height = -1;
call.slope = -1;
support_height referenceSupport;
for (int i = 0; i < 9; i++) {
if (positionsRemaining & segment_offsets[i]) {
referenceSupport = supports[i];
if (supports[i].height != 0) {
call.height = supports[i].height;
}
if (supports[i].slope != 0xFF) {
call.slope = supports[i].slope;
}
break;
}
}
uint16 positionsMatched = 0;
for (int i = 0; i < 9; i++) {
if (supports[i].height == referenceSupport.height && supports[i].slope == referenceSupport.slope) {
positionsMatched |= segment_offsets[i];
}
}
positionsRemaining &= ~positionsMatched;
call.segments = paint_util_rotate_segments(positionsMatched, (4 - rotation) % 4);
calls.push_back(call);
}
if (calls.size() > 1) {
std::sort(calls.begin(), calls.end(), SortSegmentSupportCalls);
}
return calls;
}
static bool SegmentCallEquals(std::vector<SegmentSupportCall> lhs, std::vector<SegmentSupportCall> rhs)
{
if (lhs.size() != rhs.size()) return false;
for (size_t i = 0; i < lhs.size(); ++i) {
if (lhs[i].segments != rhs[i].segments)
return false;
if (lhs[i].height != rhs[i].height)
return false;
if (lhs[i].slope != rhs[i].slope)
return false;
}
return true;
}
static bool segmentCallsMatch(std::vector<SegmentSupportCall> tileSegmentSupportCalls[4])
{
std::vector<SegmentSupportCall> baseCallList = tileSegmentSupportCalls[0];
for (int i = 1; i < 4; i++) {
if (!SegmentCallEquals(baseCallList, tileSegmentSupportCalls[i])) {
return false;
}
}
return true;
}
static bool supportCallsMatch(SupportCall tileSupportCalls[4])
{
SupportCall baseCall = tileSupportCalls[0];
for (int i = 1; i < 4; i++) {
if (tileSupportCalls[i].height != baseCall.height) return false;
if (tileSupportCalls[i].slope != baseCall.slope) return false;
}
return true;
}
static void printSegmentSupports(utf8string * out, std::vector<SegmentSupportCall> segmentCalls)
{
for (auto &&call : segmentCalls) {
int segmentsPrinted = 0;
for (int i = 0; i < 9; i++) {
if (call.segments & segment_offsets[i]) {
if (segmentsPrinted > 0) {
sprintf(*out + strlen(*out), " | ");
}
sprintf(*out + strlen(*out), "SEGMENT_%02X", 0xB4 + 4 * i);
segmentsPrinted++;
}
}
if (call.height == 0xFFFF) {
sprintf(*out + strlen(*out), ", 0xFFFF");
} else {
sprintf(*out + strlen(*out), ", %d", call.height);
}
sprintf(*out + strlen(*out), ", 0x%02X\n", call.slope);
}
}
static bool tunnelCallsLineUp(TunnelCall tunnelCalls[4][4])
{
for (int side = 0; side < 4; ++side) {
TunnelCall * referenceCall = nullptr;
for (int direction = 0; direction < 4; ++direction) {
if (tunnelCalls[direction][side].call == TUNNELCALL_SKIPPED) {
continue;
}
if (referenceCall == nullptr) {
referenceCall = &tunnelCalls[direction][side];
continue;
}
if (referenceCall->call != tunnelCalls[direction][side].call) return false;
if (referenceCall->call == TUNNELCALL_CALL) {
if (referenceCall->type != tunnelCalls[direction][side].type) return false;
if (referenceCall->offset != tunnelCalls[direction][side].offset) return false;
}
}
}
return true;
}
static void getTunnelCallReferencePattern(TunnelCall tunnelCalls[4][4], TunnelCall (*out)[4])
{
for (int side = 0; side < 4; ++side) {
for (int direction = 0; direction < 4; ++direction) {
if (tunnelCalls[direction][side].call == TUNNELCALL_SKIPPED) {
continue;
}
(*out)[side].call = tunnelCalls[direction][side].call;
(*out)[side].type = tunnelCalls[direction][side].type;
(*out)[side].offset = tunnelCalls[direction][side].offset;
}
}
}
static utf8string getTunnelEdgeString(TunnelCall edge)
{
utf8string out = new utf8[6];
switch (edge.call) {
case TUNNELCALL_SKIPPED:
sprintf(out, "%s", " ");
break;
case TUNNELCALL_NONE:
sprintf(out, "%s", " - ");
break;
case TUNNELCALL_CALL:
if (edge.offset == 0) {
sprintf(out, " 0/%X ", edge.type);
} else {
utf8string offset = new utf8[3];
if (edge.offset < 0) {
sprintf(offset, "%d", edge.offset);
} else {
sprintf(offset, "+%d", edge.offset);
}
sprintf(out, "%3s/%X ", offset, edge.type);
delete[] offset;
}
break;
}
return out;
}
static void printTunnelCalls(TunnelCall tunnelCalls[4][4])
{
for (int direction = 0; direction < 4; ++direction) {
printf(" + ");
}
printf("\n");
for (int direction = 0; direction < 4; ++direction) {
utf8string tlEdge = getTunnelEdgeString(tunnelCalls[direction][2]);
utf8string trEdge = getTunnelEdgeString(tunnelCalls[direction][3]);
printf(" %s %s ", tlEdge, trEdge);
delete [] tlEdge;
delete [] trEdge;
}
printf("\n");
for (int direction = 0; direction < 4; ++direction) {
printf(" + + ");
}
printf("\n");
for (int direction = 0; direction < 4; ++direction) {
utf8string brEdge = getTunnelEdgeString(tunnelCalls[direction][0]);
utf8string blEdge = getTunnelEdgeString(tunnelCalls[direction][1]);
printf(" %s %s ", blEdge, brEdge);
delete [] blEdge;
delete [] brEdge;
}
printf("\n");
for (int direction = 0; direction < 4; ++direction) {
printf(" + ");
}
printf("\n");
for (int direction = 0; direction < 4; ++direction) {
printf(" direction %d ", direction);
}
printf("\n");
}
static bool testSupportSegments(uint8 rideType, uint8 trackType)
{
uint8 rideIndex = 0;
rct_map_element mapElement = {0};
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = 3;
g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = {0};
surfaceElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2;
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK;
gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS;
gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC;
gTrackColours[SCHEME_3] = DEFAULT_SCHEME_3;
rct_drawpixelinfo dpi = { 0 };
dpi.zoom_level = 1;
unk_140E9A8 = &dpi;
rct_vehicle vehicle = {0};
rct_ride ride = {0};
rct_ride_entry rideEntry = {0};
rct_ride_entry_vehicle vehicleEntry { 0 };
vehicleEntry.base_image_id = 0x70000;
rideEntry.vehicles[0] = vehicleEntry;
gRideList[0] = ride;
gRideEntries[0] = &rideEntry;
int height = 48;
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
int sequenceCount = getTrackSequenceCount(rideType, trackType);
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
std::vector<SegmentSupportCall> tileSegmentSupportCalls[4];
SupportCall tileGeneralSupportCalls[4];
for (int direction = 0; direction < 4; direction++) {
for (int s = 0; s < 9; ++s) {
gSupportSegments[s].height = 0;
gSupportSegments[s].slope = 0xFF;
}
gSupport.height = 0;
gSupport.slope = 0xFF;
g141E9DB = G141E9DB_FLAG_1 | G141E9DB_FLAG_2;
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType];
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
rideType,
(int) trackDirectionList,
direction,
height,
(int) &mapElement,
rideIndex * sizeof(rct_ride),
trackSequence
);
tileSegmentSupportCalls[direction] = getSegmentCalls(gSupportSegments, direction);
tileGeneralSupportCalls[direction].height = -1;
tileGeneralSupportCalls[direction].slope = -1;
if (gSupport.height != 0) {
tileGeneralSupportCalls[direction].height = gSupport.height;
}
if (gSupport.slope != 0xFF) {
tileGeneralSupportCalls[direction].height = gSupport.height;
}
}
if (!segmentCallsMatch(tileSegmentSupportCalls)) {
// TODO: if 3 directions do share the same mask, use that call list as a reference.
printf("Original segment calls didn't match. [trackSequence:%d]\n", trackSequence);
continue;
}
for (int direction = 0; direction < 4; direction++) {
for (int s = 0; s < 9; ++s) {
gSupportSegments[s].height = 0;
gSupportSegments[s].slope = 0xFF;
}
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement);
std::vector<SegmentSupportCall> newCalls = getSegmentCalls(gSupportSegments, direction);
if (!SegmentCallEquals(tileSegmentSupportCalls[0], newCalls)) {
// TODO put this into *error
utf8string diff = new utf8[2048];
sprintf(diff, "<<< EXPECTED\n");
printSegmentSupports(&diff, tileSegmentSupportCalls[0]);
sprintf(diff + strlen(diff), "====\n");
printSegmentSupports(&diff, newCalls);
sprintf(diff + strlen(diff), ">>> ACTUAL\n");
printf("Segment support heights didn't match. [direction:%d trackSequence:%d]\n", direction,
trackSequence);
printf("%s", diff);
delete[] diff;
return false;
}
}
if (!supportCallsMatch(tileGeneralSupportCalls)) {
// TODO: if 3 directions do share the output, use that.
printf("Original support calls didn't match. [trackSequence:%d]\n", trackSequence);
continue;
}
SupportCall referenceGeneralSupportCall = tileGeneralSupportCalls[0];
for (int direction = 0; direction < 4; direction++) {
gSupport.height = 0;
gSupport.slope = 0xFF;
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement);
if (referenceGeneralSupportCall.height != -1) {
if (gSupport.height != referenceGeneralSupportCall.height) {
printf("General support heights didn't match. (expected %d, actual: %d) [direction:%d trackSequence:%d]\n", referenceGeneralSupportCall.height,gSupport.height, direction,
trackSequence);
return false;
}
}
if (referenceGeneralSupportCall.slope != -1) {
if (gSupport.slope != referenceGeneralSupportCall.slope) {
printf("General support slopes didn't match. [direction:%d trackSequence:%d]\n", direction,
trackSequence);
return false;
}
}
}
}
return true;
}
static bool tunnelPatternsMatch(TunnelCall expected[4], TunnelCall actual[4])
{
for (int side = 0; side < 4; side++) {
if (expected[side].call != actual[side].call) return false;
if (expected[side].call == TUNNELCALL_CALL) {
if (expected[side].type != actual[side].type) return false;
if (expected[side].offset != actual[side].offset) return false;
}
}
return true;
}
static sint16 getTunnelOffset(uint32 baseHeight, tunnel_entry calls[3])
{
for (sint16 offset = -56; offset <= 56; offset += 8) {
if (calls[0].height != (baseHeight - 8 + offset) / 16) continue;
if (calls[1].height != (baseHeight + 0 + offset) / 16) continue;
if (calls[2].height != (baseHeight + 8 + offset) / 16) continue;
return offset;
}
log_error("Unknown tunnel height. (%d, %d, %d)", calls[0].height, calls[1].height, calls[2].height);
return 0;
}
static bool testTunnels(uint8 rideType, uint8 trackType)
{
uint8 rideIndex = 0;
rct_map_element mapElement = {0};
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = 3;
g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = {0};
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2;
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK;
gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS;
gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC;
gTrackColours[SCHEME_3] = DEFAULT_SCHEME_3;
rct_drawpixelinfo dpi { 0 };
dpi.zoom_level = 1;
unk_140E9A8 = &dpi;
rct_vehicle vehicle = {0};
rct_ride ride = {0};
rct_ride_entry rideEntry = {0};
rct_ride_entry_vehicle vehicleEntry { 0 };
vehicleEntry.base_image_id = 0x70000;
rideEntry.vehicles[0] = vehicleEntry;
gRideList[0] = ride;
gRideEntries[0] = &rideEntry;
int height = 48;
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
int sequenceCount = getTrackSequenceCount(rideType, trackType);
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
TunnelCall tileTunnelCalls[4][4];
for (int direction = 0; direction < 4; direction++) {
gLeftTunnelCount = 0;
gRightTunnelCount = 0;
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType];
for (int offset = -8; offset <= 8; offset += 8) {
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
rideType,
(int) trackDirectionList,
direction,
height + offset,
(int) &mapElement,
rideIndex * sizeof(rct_ride),
trackSequence
);
}
uint8 rightIndex = (4 - direction) % 4;
uint8 leftIndex = (rightIndex + 1) % 4;
for (int i = 0; i < 4; ++i) {
tileTunnelCalls[direction][i].call = TUNNELCALL_SKIPPED;
}
if (gRightTunnelCount == 0) {
tileTunnelCalls[direction][rightIndex].call = TUNNELCALL_NONE;
} else if (gRightTunnelCount == 3) {
tileTunnelCalls[direction][rightIndex].call = TUNNELCALL_CALL;
tileTunnelCalls[direction][rightIndex].offset = getTunnelOffset(height, gRightTunnels);
tileTunnelCalls[direction][rightIndex].type = gRightTunnels[0].type;
} else {
printf("Multiple tunnels on one side aren't supported.\n");
return false;
}
if (gLeftTunnelCount == 0) {
tileTunnelCalls[direction][leftIndex].call = TUNNELCALL_NONE;
} else if (gLeftTunnelCount == 3) {
tileTunnelCalls[direction][leftIndex].call = TUNNELCALL_CALL;
tileTunnelCalls[direction][leftIndex].offset = getTunnelOffset(height, gLeftTunnels);
tileTunnelCalls[direction][leftIndex].type = gLeftTunnels[0].type;
} else {
printf("Multiple tunnels on one side aren't supported.\n");
return false;
}
}
TunnelCall newTileTunnelCalls[4][4];
for (int direction = 0; direction < 4; direction++) {
gLeftTunnelCount = 0;
gRightTunnelCount = 0;
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
for (int offset = -8; offset <= 8; offset += 8) {
// TODO: move tunnel pushing to interface so we don't have to check the output 3 times
newPaintFunction(rideIndex, trackSequence, direction, height + offset, &mapElement);
}
uint8 rightIndex = (4 - direction) % 4;
uint8 leftIndex = (rightIndex + 1) % 4;
for (int i = 0; i < 4; ++i) {
newTileTunnelCalls[direction][i].call = TUNNELCALL_SKIPPED;
}
if (gRightTunnelCount == 0) {
newTileTunnelCalls[direction][rightIndex].call = TUNNELCALL_NONE;
} else if (gRightTunnelCount == 3) {
newTileTunnelCalls[direction][rightIndex].call = TUNNELCALL_CALL;
newTileTunnelCalls[direction][rightIndex].offset = getTunnelOffset(height, gRightTunnels);
newTileTunnelCalls[direction][rightIndex].type = gRightTunnels[0].type;
} else {
printf("Multiple tunnels on one side aren't supported.\n");
return false;
}
if (gLeftTunnelCount == 0) {
newTileTunnelCalls[direction][leftIndex].call = TUNNELCALL_NONE;
} else if (gLeftTunnelCount == 3) {
newTileTunnelCalls[direction][leftIndex].call = TUNNELCALL_CALL;
newTileTunnelCalls[direction][leftIndex].offset = getTunnelOffset(height, gLeftTunnels);
newTileTunnelCalls[direction][leftIndex].type = gLeftTunnels[0].type;
} else {
printf("Multiple tunnels on one side aren't supported.\n");
return false;
}
}
if (!tunnelCallsLineUp(tileTunnelCalls)) {
printf("Original tunnel calls don\'t line up. Skipping tunnel validation [trackSequence:%d].\n",
trackSequence);
printTunnelCalls(tileTunnelCalls);
if (!tunnelCallsLineUp(newTileTunnelCalls)) {
printf("Decompiled tunnel calls don\'t line up. [trackSequence:%d].\n", trackSequence);
printTunnelCalls(newTileTunnelCalls);
return false;
}
continue;
}
TunnelCall referencePattern[4];
getTunnelCallReferencePattern(tileTunnelCalls, &referencePattern);
TunnelCall actualPattern[4];
getTunnelCallReferencePattern(newTileTunnelCalls, &actualPattern);
if (!tunnelPatternsMatch(referencePattern, actualPattern)) {
printf("Tunnel calls don't match expected pattern. [trackSequence:%d]\n", trackSequence);
printf("expected:\n");
printTunnelCalls(tileTunnelCalls);
printf("actual:\n");
printTunnelCalls(newTileTunnelCalls);
return false;
}
}
return true;
}
static bool verticalTunnelHeightIsConsistent(uint8 heights[4])
{
for (int i = 1; i < 4; ++i) {
if (heights[i] != heights[0]) return false;
}
return true;
}
static void printRelativeHeight(utf8string out, sint16 height)
{
if (height == 0) {
sprintf(out, "height");
return;
}
if (height > 0) {
sprintf(out, "height + %d", height);
return;
}
if (height < 0) {
sprintf(out, "height - %d", int(abs(height)));
return;
}
}
static bool testVerticalTunnels(uint8 rideType, uint8 trackType)
{
uint8 rideIndex = 0;
rct_map_element mapElement = {0};
mapElement.flags |= MAP_ELEMENT_FLAG_LAST_TILE;
mapElement.properties.track.type = trackType;
mapElement.base_height = 3;
g_currently_drawn_item = &mapElement;
rct_map_element surfaceElement = {0};
surfaceElement.type = MAP_ELEMENT_TYPE_SURFACE;
surfaceElement.base_height = 2;
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_RIDE;
gTrackColours[SCHEME_TRACK] = DEFAULT_SCHEME_TRACK;
gTrackColours[SCHEME_SUPPORTS] = DEFAULT_SCHEME_SUPPORTS;
gTrackColours[SCHEME_MISC] = DEFAULT_SCHEME_MISC;
gTrackColours[SCHEME_3] = DEFAULT_SCHEME_3;
rct_drawpixelinfo dpi = { 0 };
dpi.zoom_level = 1;
unk_140E9A8 = &dpi;
rct_vehicle vehicle = {0};
rct_ride ride = {0};
rct_ride_entry rideEntry = {0};
rct_ride_entry_vehicle vehicleEntry = { 0 };
vehicleEntry.base_image_id = 0x70000;
rideEntry.vehicles[0] = vehicleEntry;
gRideList[0] = ride;
gRideEntries[0] = &rideEntry;
int height = 48;
TRACK_PAINT_FUNCTION_GETTER newPaintGetter = RideTypeTrackPaintFunctions[rideType];
int sequenceCount = getTrackSequenceCount(rideType, trackType);
for (int trackSequence = 0; trackSequence < sequenceCount; trackSequence++) {
uint8 verticalTunnelHeight[4];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[rideType][trackType];
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
rideType,
(int) trackDirectionList,
direction,
height,
(int) &mapElement,
rideIndex * sizeof(rct_ride),
trackSequence
);
verticalTunnelHeight[direction] = gVerticalTunnelHeight;
}
if (!verticalTunnelHeightIsConsistent(verticalTunnelHeight)) {
printf(
"Original vertical tunnel height is inconsistent, skipping test. [trackSequence:%d]\n",
trackSequence
);
continue;
}
uint8 referenceHeight = verticalTunnelHeight[0];
for (int direction = 0; direction < 4; direction++) {
gVerticalTunnelHeight = 0;
TRACK_PAINT_FUNCTION newPaintFunction = newPaintGetter(trackType, direction);
newPaintFunction(rideIndex, trackSequence, direction, height, &mapElement);
if (gVerticalTunnelHeight != referenceHeight) {
if (referenceHeight == 0) {
printf(
"Expected no vertical tunnel. [trackSequence:%d direction:%d]\n",
trackSequence,
direction
);
return false;
}
utf8string strExpectedTunnelHeight = new utf8[16];
utf8string strActualTunnelHeight = new utf8[16];
printRelativeHeight(strExpectedTunnelHeight, (referenceHeight * 16) - 48);
printRelativeHeight(strActualTunnelHeight, (gVerticalTunnelHeight * 16) - 48);
printf(
"Expected vertical tunnel height to be `%s`, was `%s`. [trackSequence:%d direction:%d]\n",
strExpectedTunnelHeight,
strActualTunnelHeight,
trackSequence,
direction
);
delete []strExpectedTunnelHeight;
delete []strActualTunnelHeight;
return false;
}
}
}
return true;
}
}
extern "C"
{
bool testSupportSegments(uint8 rideType, uint8 trackType)
{
return Intercept2::testSupportSegments(rideType, trackType);
}
bool testTunnels(uint8 rideType, uint8 trackType)
{
return Intercept2::testTunnels(rideType, trackType);
}
bool testVerticalTunnels(uint8 rideType, uint8 trackType)
{
return Intercept2::testVerticalTunnels(rideType, trackType);
}
}

332
test/testpaint/main.cpp Normal file
View File

@@ -0,0 +1,332 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include <algorithm>
#include <string>
#include <vector>
#if defined(__unix__)
#include <unistd.h>
#include <sys/mman.h>
#endif // defined(__unix__)
extern "C" {
#include "data.h"
#include "intercept.h"
#include "../../src/rct2.h"
#include "../../src/ride/ride.h"
#include "../../src/ride/ride_data.h"
#include "../../src/ride/track.h"
#include "../../src/ride/track_data.h"
}
typedef struct {
uint8 rideType;
std::vector<uint8> trackTypes;
} TestCase;
enum CLIColour {
RED,
GREEN,
};
bool gTestColor = true;
static bool CStringEquals(const char *lhs, const char *rhs) {
if (lhs == NULL) return rhs == NULL;
if (rhs == NULL) return false;
return strcmp(lhs, rhs) == 0;
}
static bool ShouldUseColor() {
if (gTestColor == false) {
return false;
}
const char* const term = getenv("TERM");
const bool term_supports_color =
CStringEquals(term, "xterm") ||
CStringEquals(term, "xterm-color") ||
CStringEquals(term, "xterm-256color") ||
CStringEquals(term, "screen") ||
CStringEquals(term, "screen-256color") ||
CStringEquals(term, "tmux") ||
CStringEquals(term, "tmux-256color") ||
CStringEquals(term, "rxvt-unicode") ||
CStringEquals(term, "rxvt-unicode-256color") ||
CStringEquals(term, "linux") ||
CStringEquals(term, "cygwin");
return term_supports_color;
}
static const char* GetAnsiColorCode(CLIColour color) {
switch (color) {
case RED: return "1";
case GREEN: return "2";
default: return NULL;
};
}
static void ColouredPrintF(CLIColour colour, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
if(!ShouldUseColor()) {
vprintf(fmt, args);
va_end(args);
return;
}
printf("\033[0;3%sm", GetAnsiColorCode(colour));
vprintf(fmt, args);
printf("\033[m");
va_end(args);
}
#if defined(__WINDOWS__)
int main(int argc, char *argv[]);
#define OPENRCT2_DLL_MODULE_NAME "openrct2.dll"
static HMODULE _dllModule = NULL;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
_dllModule = (HMODULE)hModule;
return TRUE;
}
__declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if (_dllModule == NULL) {
_dllModule = GetModuleHandleA(OPENRCT2_DLL_MODULE_NAME);
}
int gExitCode = main(0, NULL);
exit(gExitCode);
return gExitCode;
}
#endif
char *segments = (char *)(GOOD_PLACE_FOR_DATA_SEGMENT);
static uint32 sawyercoding_calculate_checksum(const uint8* buffer, size_t length)
{
size_t i;
uint32 checksum = 0;
for (i = 0; i < length; i++)
checksum += buffer[i];
return checksum;
}
/**
* Loads RCT2's data model and remaps the addresses.
* @returns true if the data integrity check succeeded, otherwise false.
*/
static bool openrct2_setup_rct2_segment()
{
// OpenRCT2 on Linux and macOS is wired to have the original Windows PE sections loaded
// necessary. Windows does not need to do this as OpenRCT2 runs as a DLL loaded from the Windows PE.
int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
int err = 0;
#if defined(__unix__)
int pageSize = getpagesize();
int numPages = (len + pageSize - 1) / pageSize;
unsigned char *dummy = (unsigned char *)malloc(numPages);
err = mincore((void *)segments, len, dummy);
bool pagesMissing = false;
if (err != 0)
{
err = errno;
#ifdef __LINUX__
// On Linux ENOMEM means all requested range is unmapped
if (err != ENOMEM)
{
pagesMissing = true;
perror("mincore");
}
#else
pagesMissing = true;
perror("mincore");
#endif // __LINUX__
} else {
for (int i = 0; i < numPages; i++)
{
if (dummy[i] != 1)
{
pagesMissing = true;
void *start = (void *)(segments + i * pageSize);
void *end = (void *)(segments + (i + 1) * pageSize - 1);
log_warning("required page %p - %p is not in memory!", start, end);
}
}
}
free(dummy);
if (pagesMissing)
{
log_error("At least one of required pages was not found in memory. This can cause segfaults later on.");
}
// section: text
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC | PROT_WRITE);
if (err != 0)
{
perror("mprotect");
}
// section: rw data
err = mprotect((void *)segments, 0x01429000 - 0x8a4000, PROT_READ | PROT_WRITE);
if (err != 0)
{
perror("mprotect");
}
#endif // defined(__unix__)
// Check that the expected data is at various addresses.
// Start at 0x9a6000, which is start of .data, to skip the region containing addresses to DLL
// calls, which can be changed by windows/wine loader.
const uint32 c1 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x009A6000 - 0x8a4000)), 0x009E0000 - 0x009A6000);
const uint32 c2 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x01428000 - 0x8a4000)), 0x014282BC - 0x01428000);
const uint32 exp_c1 = 10114815;
const uint32 exp_c2 = 23564;
if (c1 != exp_c1 || c2 != exp_c2) {
log_warning("c1 = %u, expected %u, match %d", c1, exp_c1, c1 == exp_c1);
log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2);
return false;
}
return true;
}
int main(int argc, char *argv[]) {
std::vector<TestCase> testCases;
for (int i = 0; i < argc; ++i) {
char *arg = argv[i];
if (strcmp(arg, "--gtest_color=no") == 0) {
gTestColor = false;
}
}
for (uint8 rideType = 0; rideType < 91; rideType++) {
if (!rideIsImplemented(rideType)) {
continue;
}
TestCase testCase = {0};
testCase.rideType = rideType;
if (ride_type_has_flag(rideType, RIDE_TYPE_FLAG_FLAT_RIDE)) {
testCase.trackTypes.push_back(RideConstructionDefaultTrackType[rideType]);
} else {
for (int trackType = 0; trackType < 256; trackType++) {
if (rideSupportsTrackType(rideType, trackType)) {
testCase.trackTypes.push_back(trackType);
}
}
}
testCases.push_back(testCase);
}
int testCaseCount = (int) testCases.size();
int testCount = 0;
for (auto &&tc : testCases) {
testCount += tc.trackTypes.size();
}
ColouredPrintF(CLIColour::GREEN, "[==========] ");
printf("Running %d tests from %d test cases.\n", testCount, testCaseCount);
ColouredPrintF(CLIColour::GREEN, "[----------] ");
printf("Global test environment set-up.\n");
openrct2_setup_rct2_segment();
initHooks();
int successCount = 0;
std::vector<utf8string> failures;
for (auto &&tc : testCases) {
const utf8string rideTypeName = RideNames[tc.rideType];
ColouredPrintF(CLIColour::GREEN, "[----------] ");
printf("%d tests from %s\n", (int)tc.trackTypes.size(), rideTypeName);
for (auto &&trackType : tc.trackTypes) {
utf8string trackTypeName;
if (ride_type_has_flag(tc.rideType, RIDE_TYPE_FLAG_FLAT_RIDE)) {
trackTypeName = FlatTrackNames[trackType];
} else {
trackTypeName = TrackNames[trackType];
}
ColouredPrintF(CLIColour::GREEN, "[ RUN ] ");
printf("%s.%s\n", rideTypeName, trackTypeName);
bool success = testTrackPainting(tc.rideType, trackType);
if (!success) {
utf8string testCaseName = new utf8[64];
sprintf(testCaseName, "%s.%s", rideTypeName, trackTypeName);
ColouredPrintF(CLIColour::RED, "[ FAILED ] ");
printf("%s (0 ms)\n", testCaseName);
failures.push_back(testCaseName);
} else {
ColouredPrintF(CLIColour::GREEN, "[ OK ] ");
printf("%s.%s (0 ms)\n", rideTypeName, trackTypeName);
successCount++;
}
}
ColouredPrintF(CLIColour::GREEN, "[----------] ");
printf("%d tests from %s (0 ms total)\n", (int)tc.trackTypes.size(), rideTypeName);
}
printf("\n");
ColouredPrintF(CLIColour::GREEN, "[----------] ");
printf("Global test environment tear-down\n");
ColouredPrintF(CLIColour::GREEN, "[==========] ");
printf("%d tests from %d test cases ran. (0 ms total).\n", testCount, testCaseCount);
ColouredPrintF(CLIColour::GREEN, "[ PASSED ] ");
printf("%d tests.\n", successCount);
if (failures.size() > 0) {
ColouredPrintF(CLIColour::RED, "[ FAILED ] ");
printf("%d tests, listed below:\n", (int)failures.size());
for (auto &&failure : failures) {
ColouredPrintF(CLIColour::RED, "[ FAILED ] ");
printf("%s\n", failure);
delete [] failure;
}
printf("\n");
printf("%d FAILED TESTS\n", (int)failures.size());
return 1;
}
return 0;
}

View File

@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{57E60BA1-FB76-4316-909E-C1449C142327}</ProjectGuid>
<RootNamespace>testpaint</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)bin\testpaint\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
<TargetName>openrct2</TargetName>
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)bin\testpaint\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
<TargetName>openrct2</TargetName>
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>$(OpenRCT2_DEFINES);DEBUG;NO_VEHICLES;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4200</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>$(OpenRCT2_DEFINES);NO_VEHICLES;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4200</DisableSpecificWarnings>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="data.h" />
<ClInclude Include="intercept.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="compat.c" />
<ClCompile Include="data.c" />
<ClCompile Include="intercept.c" />
<ClCompile Include="intercept_2.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="..\..\src\addresses.c" />
<ClCompile Include="..\..\src\diagnostic.c" />
<ClCompile Include="..\..\src\hook.c" />
<ClCompile Include="..\..\src\paint\map_element\map_element.c" />
<ClCompile Include="..\..\src\ride\coaster\air_powered_vertical_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\bobsleigh_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\compact_inverted_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\corkscrew_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\flying_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\giga_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\heartline_twister_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\inverted_hairpin_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\inverted_impulse_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\inverted_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\junior_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\lay_down_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\lim_launched_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\looping_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\mine_ride.c" />
<ClCompile Include="..\..\src\ride\coaster\mine_train_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\mini_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\mini_suspended_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\multi_dimension_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\reverser_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\reverse_freefall_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\side_friction_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\spiral_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\stand_up_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\steeplechase.c" />
<ClCompile Include="..\..\src\ride\coaster\suspended_swinging_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\twister_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\vertical_drop_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\virginia_reel.c" />
<ClCompile Include="..\..\src\ride\coaster\wild_mouse.c" />
<ClCompile Include="..\..\src\ride\coaster\wooden_roller_coaster.c" />
<ClCompile Include="..\..\src\ride\coaster\wooden_wild_mouse.c" />
<ClCompile Include="..\..\src\ride\gentle\car_ride.c" />
<ClCompile Include="..\..\src\ride\gentle\circus_show.c" />
<ClCompile Include="..\..\src\ride\gentle\crooked_house.c" />
<ClCompile Include="..\..\src\ride\gentle\dodgems.c" />
<ClCompile Include="..\..\src\ride\gentle\ferris_wheel.c" />
<ClCompile Include="..\..\src\ride\gentle\flying_saucers.c" />
<ClCompile Include="..\..\src\ride\gentle\ghost_train.c" />
<ClCompile Include="..\..\src\ride\gentle\haunted_house.c" />
<ClCompile Include="..\..\src\ride\gentle\maze.c" />
<ClCompile Include="..\..\src\ride\gentle\merry_go_round.c" />
<ClCompile Include="..\..\src\ride\gentle\mini_golf.c" />
<ClCompile Include="..\..\src\ride\gentle\mini_helicopters.c" />
<ClCompile Include="..\..\src\ride\gentle\monorail_cycles.c" />
<ClCompile Include="..\..\src\ride\gentle\observation_tower.c" />
<ClCompile Include="..\..\src\ride\gentle\space_rings.c" />
<ClCompile Include="..\..\src\ride\gentle\spiral_slide.c" />
<ClCompile Include="..\..\src\ride\ride_data.c" />
<ClCompile Include="..\..\src\ride\shops\facility.c" />
<ClCompile Include="..\..\src\ride\shops\misc.c" />
<ClCompile Include="..\..\src\ride\shops\shop.c" />
<ClCompile Include="..\..\src\ride\thrill\3d_cinema.c" />
<ClCompile Include="..\..\src\ride\thrill\enterprise.c" />
<ClCompile Include="..\..\src\ride\thrill\go_karts.c" />
<ClCompile Include="..\..\src\ride\thrill\launched_freefall.c" />
<ClCompile Include="..\..\src\ride\thrill\magic_carpet.c" />
<ClCompile Include="..\..\src\ride\thrill\motion_simulator.c" />
<ClCompile Include="..\..\src\ride\thrill\pirate_ship.c" />
<ClCompile Include="..\..\src\ride\thrill\roto_drop.c" />
<ClCompile Include="..\..\src\ride\thrill\swinging_inverter_ship.c" />
<ClCompile Include="..\..\src\ride\thrill\top_spin.c" />
<ClCompile Include="..\..\src\ride\thrill\twist.c" />
<ClCompile Include="..\..\src\ride\track_data.c" />
<ClCompile Include="..\..\src\ride\track_data_old.c" />
<ClCompile Include="..\..\src\ride\track_paint.c" />
<ClCompile Include="..\..\src\ride\transport\chairlift.c" />
<ClCompile Include="..\..\src\ride\transport\lift.c" />
<ClCompile Include="..\..\src\ride\transport\minature_railway.c" />
<ClCompile Include="..\..\src\ride\transport\monorail.c" />
<ClCompile Include="..\..\src\ride\transport\suspended_monorail.c" />
<ClCompile Include="..\..\src\ride\water\boat_ride.c" />
<ClCompile Include="..\..\src\ride\water\dingy_slide.c" />
<ClCompile Include="..\..\src\ride\water\log_flume.c" />
<ClCompile Include="..\..\src\ride\water\river_rafts.c" />
<ClCompile Include="..\..\src\ride\water\river_rapids.c" />
<ClCompile Include="..\..\src\ride\water\splash_boats.c" />
<ClCompile Include="..\..\src\ride\water\submarine_ride.c" />
<ClCompile Include="..\..\src\ride\water\water_coaster.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
</Project>