diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4335d1d81..eae7e6bdb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Install dependencies run: | sudo apt update - sudo apt install -y $(cat .github/workflows/apt-deps.txt) + sudo apt install -y $(cat .github/workflows/apt-deps.txt) file - name: Install latest SDL run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" @@ -34,22 +34,22 @@ jobs: run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release + cmake --build build-cmake --config Release --target GenerateSohOtr -j cmake --build build-cmake --config Release -j - # Not building releases/artifacts for now - # (cd build-cmake && cpack -G External) - # mv README.md readme.txt - # mv build-cmake/*.appimage 2ship.appimage + (cd build-cmake && cpack -G External) + mv README.md readme.txt + mv build-cmake/*.appimage 2ship.appimage env: CC: gcc CXX: g++ - # - name: Upload build - # uses: actions/upload-artifact@v3 - # with: - # name: 2ship-linux-${{ matrix.archive-suffix }} - # path: | - # # 2ship.appimage - # readme.txt + - name: Upload build + uses: actions/upload-artifact@v4 + with: + name: 2ship-linux + path: | + 2ship.appimage + readme.txt # build-windows: # needs: generate-soh-otr-and-headers # runs-on: windows-latest @@ -122,17 +122,17 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Cache build folder - uses: actions/cache@v4 - with: - save-always: true - key: ${{ runner.os }}-self-build-${{ github.ref }}-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-self-build-${{ github.ref }} - ${{ runner.os }}-self-build- - path: | - build-windows - vcpkg + # - name: Cache build folder + # uses: actions/cache@v4 + # with: + # save-always: true + # key: ${{ runner.os }}-self-build-${{ github.ref }}-${{ github.sha }} + # restore-keys: | + # ${{ runner.os }}-self-build-${{ github.ref }} + # ${{ runner.os }}-self-build- + # path: | + # build-windows + # vcpkg - name: Configure Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1 - name: Copy Rom @@ -143,22 +143,16 @@ jobs: run: | set $env:PATH="$env:USERPROFILE/.cargo/bin;$env:PATH" cmake -S . -B build-windows -G Ninja -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE:STRING=Release - cmake --build build-windows --config Release --target ExtractAssetHeaders --parallel 10 + cmake --build build-windows --config Release --target GenerateSohOtr --parallel 10 cmake --build build-windows --config Release --parallel 10 - # Not building releases/artifacts for now - # mkdir 2ship-windows - # mv ./x64/Release/mm.exe ./2ship-windows/2ship.exe - # mkdir 2ship-windows/debug - # mkdir 2ship-windows/mods - # New-Item 2ship-windows/mods/custom_otr_files_go_here.txt -type file - # mv ./x64/Release/2ship.pdb ./2ship-windows/debug/2ship.pdb - # mv ./README.md ./2ship-windows/readme.txt - # mv ./build-windows/gamecontrollerdb.txt ./2ship-windows/gamecontrollerdb.txt - # mv ./x64/Release/assets ./2ship-windows - # mv ./soh.otr ./2ship-windows/soh.otr - # - name: Upload build - # uses: actions/upload-artifact@v4 - # with: - # name: 2ship-windows - # path: 2ship-windows + (cd build-windows && cpack) + cd .. + mv _packages/*.zip 2ship-windows.zip + - name: Unzip package + run: Expand-Archive -Path 2ship-windows.zip -DestinationPath 2ship-windows + - name: Upload build + uses: actions/upload-artifact@v4 + with: + name: 2ship-windows + path: 2ship-windows diff --git a/.github/workflows/pr-artifacts.yml b/.github/workflows/pr-artifacts.yml new file mode 100644 index 000000000..43b985b5d --- /dev/null +++ b/.github/workflows/pr-artifacts.yml @@ -0,0 +1,61 @@ +name: pr-artifacts + +on: + workflow_run: + workflows: [generate-builds] + types: + - completed + +jobs: + pr-artifacts: + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.event == 'pull_request' }} + steps: + - id: 'pr-number' + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + const {owner, repo} = context.repo; + const pullHeadSHA = '${{github.event.workflow_run.head_sha}}'; + const pullUserId = ${{github.event.sender.id}}; + const prNumber = await (async () => { + const pulls = await github.rest.pulls.list({owner, repo}); + for await (const {data} of github.paginate.iterator(pulls)) { + for (const pull of data) { + if (pull.head.sha === pullHeadSHA && pull.user.id === pullUserId) { + return pull.number; + } + } + } + })(); + + if (!prNumber) { + return core.error(`No matching pull request found`); + } + + return prNumber; + - id: 'artifacts-text' + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + + return allArtifacts.data.artifacts.reduce((acc, item) => { + if (item.name === "assets") return acc; + acc += ` + - [${item.name}.zip](https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/artifacts/${item.id}.zip)`; + return acc; + }, '### Build Artifacts'); + - id: 'add-to-pr' + uses: garrettjoecox/pr-section@3.1.0 + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' + pr-number: ${{ steps.pr-number.outputs.result }} + section-name: 'artifacts' + section-value: '${{ steps.artifacts-text.outputs.result }}' diff --git a/CMake/Packaging-2.cmake b/CMake/Packaging-2.cmake index c7b49ae92..38b4b7ac3 100644 --- a/CMake/Packaging-2.cmake +++ b/CMake/Packaging-2.cmake @@ -1,9 +1,9 @@ set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 0) -set(CPACK_COMPONENTS_ALL "2s2h" "extractor" "appimage") +set(CPACK_COMPONENTS_ALL "2s2h") -if (NOT CPACK_GENERATOR STREQUAL "External") - list(REMOVE_ITEM CPACK_COMPONENTS_ALL "appimage") +if (CPACK_GENERATOR STREQUAL "External") + list(APPEND CPACK_COMPONENTS_ALL "extractor" "appimage") endif() if (CPACK_GENERATOR MATCHES "DEB|RPM") diff --git a/CMakeLists.txt b/CMakeLists.txt index 65724a805..d52262995 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,20 +22,6 @@ endif() # Enable the Gfx debugger in LUS to use libgfxd from ZAPDTR set(GFX_DEBUG_DISASSEMBLER ON) -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") -include(CMake/automate-vcpkg.cmake) - -if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") - set(VCPKG_TRIPLET x86-windows-static) - set(VCPKG_TARGET_TRIPLET x86-windows-static) -elseif ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") - set(VCPKG_TRIPLET x64-windows-static) - set(VCPKG_TARGET_TRIPLET x64-windows-static) -endif() -vcpkg_bootstrap() -vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog) -endif() - ################################################################################ # Set target arch type if empty. Visual studio solution generator provides it. ################################################################################ @@ -51,6 +37,23 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") endif() endif() +################################################################################ +# VCPKG dependencies for Windows +################################################################################ +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") +include(CMake/automate-vcpkg.cmake) + +if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") + set(VCPKG_TRIPLET x86-windows-static) + set(VCPKG_TARGET_TRIPLET x86-windows-static) +elseif ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") + set(VCPKG_TRIPLET x64-windows-static) + set(VCPKG_TARGET_TRIPLET x64-windows-static) +endif() +vcpkg_bootstrap() +vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog) +endif() + ################################################################################ # Global configuration types ################################################################################ @@ -101,11 +104,11 @@ add_subdirectory(OTRExporter) add_subdirectory(mm) set_property(TARGET mm PROPERTY APPIMAGE_DESKTOP_FILE_TERMINAL YES) -set_property(TARGET mm PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/2s2h.desktop") +set_property(TARGET mm PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/mm/linux/2s2h.desktop") set_property(TARGET mm PROPERTY APPIMAGE_ICON_FILE "${CMAKE_BINARY_DIR}/2s2hIcon.png") if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") -install(PROGRAMS "${CMAKE_BINARY_DIR}/linux/appimage/s2sh.sh" DESTINATION . COMPONENT appimage) +install(PROGRAMS "${CMAKE_BINARY_DIR}/linux/2s2h.sh" DESTINATION . COMPONENT appimage) install(FILES "${CMAKE_SOURCE_DIR}/soh.otr" DESTINATION . COMPONENT ship) install(TARGETS ZAPD DESTINATION ./assets/extractor COMPONENT extractor) install(DIRECTORY "${CMAKE_SOURCE_DIR}/mm/assets/extractor/" DESTINATION ./assets/extractor COMPONENT extractor) @@ -162,13 +165,7 @@ add_custom_target( ) if(CMAKE_SYSTEM_NAME MATCHES "Linux") - find_package(ImageMagick COMPONENTS convert) - if (ImageMagick_FOUND) - execute_process ( - COMMAND ${ImageMagick_convert_EXECUTABLE} mm/macosx/2s2hIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/2s2hIcon.png - OUTPUT_VARIABLE outVar - ) - endif() +file(COPY ${CMAKE_SOURCE_DIR}/mm/linux/2s2hIcon.png DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif() if(CMAKE_SYSTEM_NAME MATCHES "Darwin") @@ -216,6 +213,8 @@ endif() if(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS") install(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION . COMPONENT 2s2h RENAME readme.txt ) +install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/mods\")" COMPONENT 2s2h) +install(CODE "file(TOUCH \"\${CMAKE_INSTALL_PREFIX}/mods/custom_mod_files_go_here.txt\")" COMPONENT 2s2h) endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/mm/CMakeLists.txt b/mm/CMakeLists.txt index d814aa874..36a71ec27 100644 --- a/mm/CMakeLists.txt +++ b/mm/CMakeLists.txt @@ -428,7 +428,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets . ) -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64") target_compile_definitions(${PROJECT_NAME} PRIVATE "$<$:" @@ -439,9 +439,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") "$<$:" "NDEBUG" ">" -# "$<$:ENABLE_CROWD_CONTROL>" + # "$<$:ENABLE_CROWD_CONTROL>" "INCLUDE_GAME_PRINTF;" - # "ENABLE_CROWD_CONTROL;" "UNICODE;" "_UNICODE" STORMLIB_NO_AUTO_LINK @@ -490,7 +489,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang") "$<$:" "NDEBUG" ">" -# "$<$:ENABLE_CROWD_CONTROL>" + # "$<$:ENABLE_CROWD_CONTROL>" "SPDLOG_ACTIVE_LEVEL=0;" "_CONSOLE;" "_CRT_SECURE_NO_WARNINGS;" @@ -717,7 +716,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") "glu32;" "SDL2::SDL2;" "SDL2::SDL2main;" - # "$<$:SDL2_net::SDL2_net-static>" + # "$<$:SDL2_net::SDL2_net-static>" "glfw;" "winmm;" "imm32;" @@ -777,11 +776,15 @@ if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS") INSTALL(TARGETS mm DESTINATION . COMPONENT 2s2h) endif() -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") INSTALL(FILES $ DESTINATION ./debug COMPONENT 2s2h) INSTALL(FILES ${CMAKE_BINARY_DIR}/mm/soh.otr DESTINATION . COMPONENT 2s2h) endif() +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/linux/2s2h.sh.in ${CMAKE_BINARY_DIR}/linux/2s2h.sh @ONLY) +endif() + find_program(CURL NAMES curl DOC "Path to the curl program. Used to download files.") execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt OUTPUT_VARIABLE RESULT) diff --git a/mm/linux/2s2h.desktop b/mm/linux/2s2h.desktop new file mode 100644 index 000000000..6815fb057 --- /dev/null +++ b/mm/linux/2s2h.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=2SHIP +Exec=2s2h.sh +Terminal=false +Icon=2s2hIcon +Type=Application +Categories=Game; +X-AppImage-Integrate=false diff --git a/mm/linux/2s2h.sh.in b/mm/linux/2s2h.sh.in new file mode 100644 index 000000000..6843de16b --- /dev/null +++ b/mm/linux/2s2h.sh.in @@ -0,0 +1,123 @@ +#!/bin/bash +HERE="$(dirname "$(readlink -f "${0}")")"/../.. + +export PATH="$HERE"/bin:"$HERE"/usr/bin:"$PATH" +export LD_LIBRARY_PATH="$HERE"/usr/lib:"$LD_LIBRARY_PATH" +export ZENITY=$(command -v zenity) + +if [ -z ${SHIP_HOME+x} ]; then +export SHIP_HOME=$PWD +fi + +if [ -z ${SHIP_BIN_DIR+x} ]; then +export SHIP_BIN_DIR="$HERE/usr/bin" +fi + +if [[ ! -e "$SHIP_HOME"/mods ]]; then + mkdir -p "$SHIP_HOME"/mods + touch "$SHIP_HOME"/mods/custom_mod_files_go_here.txt +fi + +while [[ (! -e "$SHIP_HOME"/mm.otr) ]]; do + for romfile in "$SHIP_HOME"/*.*64 + do + if [[ -e "$romfile" ]] || [[ -L "$romfile" ]]; then + export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)" + ln -s "$SHIP_BIN_DIR"/{assets,2s2h.elf,ZAPD} "$ASSETDIR" + export OLDPWD="$PWD" + mkdir -p "$ASSETDIR"/tmp + if [[ -e "$romfile" ]]; then + ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64 + else + ORIG_ROM_PATH=$(readlink "$romfile") + ln -s "$ORIG_ROM_PATH" "$ASSETDIR"/tmp/rom.z64 + fi + cd "$ASSETDIR" + ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') + + # Remap v64 and n64 hashes to their z64 hash equivalent + # ZAPD will handle converting the data into z64 format + case "$ROMHASH" in + ef6d7273a7bc1cbf778f9021753db5efddfe495e) # v64 + ROMHASH=7f5630dbc4d5d61d6276213210c4d5cdd83a47d6 + ;; + 991460c32f53c7bb0bc650baf5a40ffde6165840) # n64 + ROMHASH=7f5630dbc4d5d61d6276213210c4d5cdd83a47d6 + ;; + 22f8bfa1ab6c763013a3c2a568bb014395b12499) # v64 + ROMHASH=d6133ace5afaa0882cf214cf88daba39e266c078 + ;; + 1a26735c63cb3bdf5eb32d21acf774ee6724f227) # n64 + ROMHASH=d6133ace5afaa0882cf214cf88daba39e266c078 + ;; + 8c378b87c83b3f4de20b14accf91e7590399f5dc) # v64 + ROMHASH=9743aa026e9269b339eb0e3044cd5830a440c1fd + ;; + 8b0436e540b95a5353969d4ee360273cf33fb659) # n64 + ROMHASH=9743aa026e9269b339eb0e3044cd5830a440c1fd + ;; + esac + + case "$ROMHASH" in + 7f5630dbc4d5d61d6276213210c4d5cdd83a47d6) # uncompressed + if [[ ! -e "$SHIP_HOME"/mm.otr ]]; then + ROM=N64_US + else + continue + fi + ;; + d6133ace5afaa0882cf214cf88daba39e266c078) # compressed + if [[ ! -e "$SHIP_HOME"/mm.otr ]]; then + ROM=N64_US + else + continue + fi + ;; + 9743aa026e9269b339eb0e3044cd5830a440c1fd) # compressed + if [[ ! -e "$SHIP_HOME"/mm.otr ]]; then + ROM=GC_US + else + continue + fi + ;; + *) + echo -e "\n$romfile - $ROMHASH rom hash does not match\n" + continue;; + esac + if [[ ! -e "$SHIP_HOME"/mm.otr ]]; then + if [ -n "$ZENITY" ]; then + (echo "# 25%"; echo "25"; sleep 2; echo "# 50%"; echo "50"; sleep 3; echo "# 75%"; echo "75"; sleep 2; echo "# 100%"; echo "100"; sleep 3) | + zenity --progress --title="OTR Generating..." --timeout=10 --percentage=0 --icon-name=2s2h --window-icon=2s2h.png --height=80 --width=400 & + else + echo "Processing..." + fi + assets/extractor/ZAPD.out ed -eh -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR --otrfile mm.otr --portVer "@CMAKE_PROJECT_VERSION@" > /dev/null 2>&1 + cp "$ASSETDIR"/mm.otr "$SHIP_HOME" + fi + else + if [[ (! -e "$SHIP_HOME"/mm.otr) ]]; then + if [ -n "$ZENITY" ]; then + zenity --error --timeout=5 --text="Place ROM in $SHIP_HOME" --title="Missing ROM file" --width=500 --width=200 + else + echo -e "\nPlace ROM in this folder\n" + fi + exit + fi + fi + done + if [[ (! -e "$SHIP_HOME"/mm.otr) ]]; then + if [ -n "$ZENITY" ]; then + zenity --error --timeout=10 --text="No valid ROMs were provided, No OTR was generated." --title="Incorrect ROM file" --width=500 --width=200 + else + echo "No valid roms provided, no OTR was generated." + fi + rm -r "$ASSETDIR" + exit + else + (cd "$SHIP_BIN_DIR"; ./2s2h.elf) + exit + fi + rm -r "$ASSETDIR" +done + (cd "$SHIP_BIN_DIR"; ./2s2h.elf) +exit diff --git a/mm/linux/2s2hIcon.png b/mm/linux/2s2hIcon.png new file mode 100644 index 000000000..227a75008 Binary files /dev/null and b/mm/linux/2s2hIcon.png differ diff --git a/mm/linux/build.sh b/mm/linux/build.sh new file mode 100755 index 000000000..86f46fb90 --- /dev/null +++ b/mm/linux/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release +cmake --build build-cmake --config Release -- + +(cd build-cmake && cpack -G External) diff --git a/mm/src/code/main.c b/mm/src/code/main.c index 3f662e33d..208a93c38 100644 --- a/mm/src/code/main.c +++ b/mm/src/code/main.c @@ -1,3 +1,8 @@ +#ifdef _WIN32 +#include +#include +#endif + #include "audiomgr.h" #include "fault.h" #include "idle.h" @@ -50,6 +55,18 @@ void SDL_main(int argc, char** argv /* void* arg*/) { intptr_t sysHeap; s32 exit; s16* msg; + +// Attach console for windows so we can conditionally display it when running the extractor +#ifdef _WIN32 + AllocConsole(); + (void)freopen("CONIN$", "r", stdin); + (void)freopen("CONOUT$", "w", stdout); + (void)freopen("CONOUT$", "w", stderr); +#ifndef _DEBUG + ShowWindow(GetConsoleWindow(), SW_HIDE); +#endif +#endif // _WIN32 + InitOTR(); Heaps_Alloc(); @@ -123,4 +140,8 @@ void SDL_main(int argc, char** argv /* void* arg*/) { osDestroyThread(&gGraphThread); DeinitOTR(); + +#ifdef _WIN32 + FreeConsole(); +#endif }