diff --git a/.gitmodules b/.gitmodules index 7b4acd7..28ebcdc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "externals/excmd"] - path = externals/excmd - url = https://github.com/exjam/excmd -[submodule "externals/fmt"] - path = externals/fmt - url = https://github.com/fmtlib/fmt -[submodule "externals/zlib"] - path = externals/zlib - url = https://github.com/madler/zlib.git +[submodule "tools/libraries/fmt"] + path = tools/libraries/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/.travis.yml b/.travis.yml index 12d5008..c3332a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,38 +3,47 @@ language: cpp matrix: include: - os: linux + sudo: required dist: trusty - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-6 - - zlib1g-dev - env: - - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6" - os: osx - osx_image: xcode8.3 + osx_image: xcode9.3 + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:cginternals/backports-ppa' + packages: + - gcc-7 + - g++-7 + - zlib1g-dev cache: directories: - "$HOME/.local" -before_install: - - eval "${MATRIX_EVAL}" - git: submodules: true -before_script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://freefr.dl.sourceforge.net/project/devkitpro/devkitPPC/devkitPPC_r29-1/devkitPPC_r29-1-x86_64-linux.tar.bz2 -O /tmp/devkitPPC.tar.bz2; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget https://freefr.dl.sourceforge.net/project/devkitpro/devkitPPC/devkitPPC_r29-1/devkitPPC_r29-1-x86_64-osx.tar.bz2 -O /tmp/devkitPPC.tar.bz2; fi - - tar -xjf /tmp/devkitPPC.tar.bz2 - - export DEVKITPPC=$PWD/devkitPPC +install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 90; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb -O /tmp/devkitpro-pacman.deb; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo dpkg -i /tmp/devkitpro-pacman.deb; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman-installer.pkg -O /tmp/devkitpro-pacman-installer.pkg; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo installer -pkg /tmp/devkitpro-pacman-installer.pkg -target /; fi + - yes | sudo dkp-pacman -Syu devkitPPC + - export DEVKITPPC=/opt/devkitpro/devkitPPC script: - cd "$TRAVIS_BUILD_DIR" - - mkdir cbuild && cd cbuild - - cmake -DCMAKE_INSTALL_PREFIX=/tmp/wut_install ../ - - make -j4 - - make install + - mkdir build && cd build + - cmake -DCMAKE_INSTALL_PREFIX=wut_install ../ + - make -j4 install + - export WUT_ROOT=$PWD/wut_install + - cd ../ + - cd samples/helloworld + - mkdir build && cd build + - chmod +x $WUT_ROOT/bin/wut-elf2rpl + - cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$WUT_ROOT/samples ../ + - make -j4 VERBOSE=TRUE install diff --git a/CMakeLists.txt b/CMakeLists.txt index 73b0481..27d9429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,7 @@ cmake_minimum_required(VERSION 3.2) -project(wut) +project(wut2) include(ExternalProject) -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - set(DEVKITPPC $ENV{DEVKITPPC} CACHE STRING "Path to devkitPPC install") # Check for DEVKITPPC @@ -11,19 +9,42 @@ if(NOT DEVKITPPC) message(FATAL_ERROR "You must have defined DEVKITPPC before calling cmake.") endif() -add_subdirectory(src) -add_subdirectory(externals) -add_subdirectory(tools) +set(WUT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) +set(WUT_TOOLCHAIN "${CMAKE_CURRENT_SOURCE_DIR}/share/wut.toolchain.cmake") +set(WUT_STAGING "${CMAKE_BINARY_DIR}/staging") + +externalproject_add(tools + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tools" + INSTALL_DIR "${WUT_STAGING}" + CMAKE_CACHE_ARGS + -DCMAKE_C_COMPILER:string=${CMAKE_C_COMPILER} + -DCMAKE_C_FLAGS:string=${CMAKE_C_FLAGS} + -DCMAKE_CXX_COMPILER:string=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_FLAGS:string=${CMAKE_CXX_FLAGS} + -DCMAKE_INSTALL_PREFIX:string= + BUILD_ALWAYS 1) +externalproject_get_property(tools BINARY_DIR) +set(TOOLS_BINARY_DIR ${BINARY_DIR}) + +set(WUT_RPLGEN "${TOOLS_BINARY_DIR}/bin/wut-rplgen") + +externalproject_add(cafe + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cafe" + INSTALL_DIR "${WUT_STAGING}" + CMAKE_CACHE_ARGS + -DWUT_RPLGEN:filepath=${WUT_RPLGEN} + -DWUT_ROOT:filepath=${WUT_ROOT} + -DCMAKE_TOOLCHAIN_FILE:filepath=${WUT_TOOLCHAIN} + -DCMAKE_INSTALL_PREFIX:string= + DEPENDS tools + BUILD_ALWAYS 1) install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/" - DESTINATION "${CMAKE_INSTALL_PREFIX}/include" - FILES_MATCHING PATTERN "*.h*") + DESTINATION "${CMAKE_INSTALL_PREFIX}/include" + FILES_MATCHING PATTERN "*.h*") -install(DIRECTORY "${CMAKE_SOURCE_DIR}/cmake/" - DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake") - -install(DIRECTORY "${CMAKE_SOURCE_DIR}/rules/" - DESTINATION "${CMAKE_INSTALL_PREFIX}/rules") +install(DIRECTORY "${CMAKE_SOURCE_DIR}/share/" + DESTINATION "${CMAKE_INSTALL_PREFIX}/share") install(DIRECTORY "${CMAKE_BINARY_DIR}/staging/" - DESTINATION "${CMAKE_INSTALL_PREFIX}") + DESTINATION "${CMAKE_INSTALL_PREFIX}") diff --git a/README.md b/README.md index 3e21250..fdfb859 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,18 @@ -[![Build status](https://ci.appveyor.com/api/projects/status/rjmwygepioxdx1fs/branch/master?svg=true)](https://ci.appveyor.com/project/exjam/wut/branch/master) [![Build Status](https://travis-ci.org/decaf-emu/wut.svg?branch=master)](https://travis-ci.org/decaf-emu/wut) +[![Build status](https://ci.appveyor.com/api/projects/status/rjmwygepioxdx1fs/branch/rewrite?svg=true)](https://ci.appveyor.com/project/exjam/wut/branch/rewrite) [![Build Status](https://travis-ci.org/decaf-emu/wut.svg?branch=rewrite)](https://travis-ci.org/decaf-emu/wut) # wut Let's try make a Wii U Toolchain / SDK for creating rpx/rpl. Licensed under the terms of the GNU General Public License, version 2 or later (GPLv2+). -Doxygen output can be found at https://decaf-emu.github.io/wut +## Rewrite +This branch is an WIP experimental rewrite to simplify how elf2rpl works and hopefully make it more correct for more advanced C++ programs. -If you are looking for the old Makefile based wut, that can be found on the [legacy-make](https://github.com/decaf-emu/wut/tree/legacy-make) branch. +## TODO: +- Bring back the old tools (readrpl etc) +- newlib / devoptab -## Binaries -The latest Windows AppVeyor build is available from: -- https://ci.appveyor.com/api/projects/exjam/wut/artifacts/build/install/wut.zip?branch=master - -## Requirements -- Tested on Linux, OS X, Windows -- [devkitPPC](https://devkitpro.org/wiki/Getting_Started/devkitPPC) -- CMake -- Make - -## Linux / OS X +## Linux Requires CMake + Make + [devkitPPC](https://devkitpro.org/wiki/Getting_Started/devkitPPC) + libzdev ``` @@ -27,40 +20,17 @@ export DEVKITPPC= git clone --recursive https://github.com/decaf-emu/wut.git cd wut mkdir build && cd build -cmake -DCMAKE_INSTALL_PREFIX=install ../ +cmake -DCMAKE_INSTALL_PREFIX=/path/to/install ../ make make install -export WUT_ROOT=$PWD/install +export WUT_ROOT=/path/to/install ``` -Then for any wut project you want to build you must use the wut-toolchain.cmake script: +Then for any wut project you want to build you must use the wut.toolchain.cmake script: ``` cd ../samples/helloworld mkdir build && cd build -cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/cmake/wut-toolchain.cmake ../ -make -``` - -## Windows -Requires [Windows CMake](https://cmake.org/download/) + [Windows Make](http://gnuwin32.sourceforge.net/packages/make.htm) + [devkitPPC](https://devkitpro.org/wiki/Getting_Started/devkitPPC) + Visual Studio. - -``` -set DEVKITPPC= -git clone --recursive https://github.com/decaf-emu/wut.git -cd wut -mkdir build && cd build -cmake -DCMAKE_INSTALL_PREFIX=install -G "Visual Studio 15 2017" ../ -msbuild INSTALL.vcxproj /p:Configuration=Release /p:Platform=Win32 -set WUT_ROOT=%CD%\install -``` - -Then for any wut project you want to build you must use Unix Makefiles with the wut-toolchain.cmake script: - -``` -cd ..\samples\helloworld -mkdir build -cd build -cmake -DCMAKE_TOOLCHAIN_FILE=%WUT_ROOT%\cmake\wut-toolchain.cmake -G "Unix Makefiles" ../ +cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake ../ make ``` diff --git a/appveyor.yml b/appveyor.yml index 085c735..b298b23 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,34 +5,9 @@ version: 1.0.{build} image: Visual Studio 2017 platform: - - x86 + - x64 configuration: - Release -install: - - appveyor DownloadFile https://kent.dl.sourceforge.net/project/gnuwin32/make/3.81/make-3.81-bin.zip - - 7z x make-3.81-bin.zip -oC:\make - - appveyor DownloadFile https://netix.dl.sourceforge.net/project/gnuwin32/make/3.81/make-3.81-dep.zip - - 7z x make-3.81-dep.zip -oC:\make - - set PATH=%PATH%;C:/make/bin - - appveyor DownloadFile https://netcologne.dl.sourceforge.net/project/devkitpro/devkitPPC/devkitPPC_r29-1/devkitPPC_r29-1-win32.exe - - 7z x devkitPPC_r29-1-win32.exe -oC:\ -y - - set DEVKITPPC=C:/devkitPPC - - git submodule update --init --recursive - -before_build: - - mkdir build - - cd build - - cmake -DCMAKE_INSTALL_PREFIX=install -G "Visual Studio 15 2017" ../ - -build_script: - - msbuild INSTALL.vcxproj /p:Configuration=Release /p:Platform=Win32 - -after_build: - - cd install - - 7z a wut.zip . - -artifacts: - - path: build\install\wut.zip - name: wut +build: off diff --git a/cafe/CMakeLists.txt b/cafe/CMakeLists.txt new file mode 100644 index 0000000..a7547ec --- /dev/null +++ b/cafe/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.2) +project(cafe C CXX) +enable_language(ASM) + +macro(add_cafe_library target) + add_custom_command( + OUTPUT ${target}.s + COMMAND ${WUT_RPLGEN} ${CMAKE_CURRENT_SOURCE_DIR}/${target}/exports.def ${target}.s + DEPENDS ${target}/exports.def) + + add_library(${target} STATIC ${target}.s) + install(TARGETS ${target} ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") +endmacro() + +add_cafe_library(coreinit) +add_cafe_library(gx2) +add_cafe_library(nn_ac) +add_cafe_library(nsysnet) +add_cafe_library(proc_ui) +add_cafe_library(sndcore2) +add_cafe_library(sysapp) +add_cafe_library(vpad) diff --git a/cafe/coreinit/exports.def b/cafe/coreinit/exports.def new file mode 100644 index 0000000..a0e0ea8 --- /dev/null +++ b/cafe/coreinit/exports.def @@ -0,0 +1,409 @@ +:NAME coreinit +:TEXT + +// coreinit/alarm.h +OSCancelAlarm +OSCancelAlarms +OSCreateAlarm +OSCreateAlarmEx +OSGetAlarmUserData +OSInitAlarmQueue +OSInitAlarmQueueEx +OSSetAlarm +OSSetPeriodicAlarm +OSSetAlarmTag +OSSetAlarmUserData +OSWaitAlarm + +// coreinit/atomic.h +OSCompareAndSwapAtomic +OSCompareAndSwapAtomicEx +OSSwapAtomic +OSAddAtomic +OSAndAtomic +OSOrAtomic +OSXorAtomic +OSTestAndClearAtomic +OSTestAndSetAtomic + +// coreinit/atomic64.h +OSGetAtomic64 +OSSetAtomic64 +OSCompareAndSwapAtomic64 +OSCompareAndSwapAtomicEx64 +OSSwapAtomic64 +OSAddAtomic64 +OSAndAtomic64 +OSOrAtomic64 +OSXorAtomic64 +OSTestAndClearAtomic64 +OSTestAndSetAtomic64 + +// coreinit/baseheap.h +MEMGetArena +MEMGetBaseHeapHandle +MEMSetBaseHeapHandle + +// coreinit/blockheap.h +MEMInitBlockHeap +MEMDestroyBlockHeap +MEMAddBlockHeapTracking +MEMAllocFromBlockHeapAt +MEMAllocFromBlockHeapEx +MEMFreeToBlockHeap +MEMGetAllocatableSizeForBlockHeapEx +MEMGetTrackingLeftInBlockHeap +MEMGetTotalFreeSizeForBlockHeap + +// coreinit/cache.h +DCInvalidateRange +DCFlushRange +DCStoreRange +DCFlushRangeNoSync +DCStoreRangeNoSync +DCZeroRange +DCTouchRange +ICInvalidateRange + +// coreinit/condition.h +OSInitCond +OSInitCondEx +OSWaitCond +OSSignalCond + +// coreinit/core.h +OSGetCoreCount +OSGetCoreId +OSGetMainCoreId +OSIsMainCore + +// coreinit/coroutine.h +OSInitCoroutine +OSLoadCoroutine +OSSaveCoroutine +OSSwitchCoroutine + +// coreinit/debug.h +OSConsoleWrite +OSReport +OSPanic +OSFatal +OSGetSymbolName +OSGetUPID +DisassemblePPCRange + +// coreinit/dynload.h +OSDynLoad_SetAllocator +OSDynLoad_GetAllocator +OSDynLoad_Acquire +OSDynLoad_FindExport +OSDynLoad_Release + +// coreinit/event.h +OSInitEvent +OSInitEventEx +OSSignalEvent +OSSignalEventAll +OSWaitEvent +OSResetEvent +OSWaitEventWithTimeout + +// coreinit/exception.h +OSSetExceptionCallback +OSSetExceptionCallbackEx + +// coreinit/exit.h +exit +_Exit + +// coreinit/expandedheap.h +MEMCreateExpHeapEx +MEMDestroyExpHeap +MEMAllocFromExpHeapEx +MEMFreeToExpHeap +MEMSetAllocModeForExpHeap +MEMGetAllocModeForExpHeap +MEMAdjustExpHeap +MEMResizeForMBlockExpHeap +MEMGetTotalFreeSizeForExpHeap +MEMGetAllocatableSizeForExpHeapEx +MEMSetGroupIDForExpHeap +MEMGetGroupIDForExpHeap +MEMGetSizeForMBlockExpHeap +MEMGetGroupIDForMBlockExpHeap +MEMGetAllocDirForMBlockExpHeap + +// coreinit/fastcondition.h +OSFastCond_Init +OSFastCond_Wait +OSFastCond_Signal + +// coreinit/fastmutex.h +OSFastMutex_Init +OSFastMutex_Lock +OSFastMutex_Unlock +OSFastMutex_TryLock + +// coreinit/filesystem.h +FSInit +FSShutdown +FSAddClient +FSDelClient +FSGetClientNum +FSInitCmdBlock +FSSetCmdPriority +FSSetStateChangeNotification +FSGetCwd +FSChangeDir +FSChangeDirAsync +FSChangeMode +FSChangeModeAsync +FSGetFreeSpaceSize +FSGetFreeSpaceSizeAsync +FSGetStat +FSGetStatAsync +FSRemove +FSRemoveAsync +FSOpenFile +FSOpenFileAsync +FSCloseFile +FSCloseFileAsync +FSOpenDir +FSOpenDirAsync +FSMakeDir +FSMakeDirAsync +FSReadDir +FSReadDirAsync +FSRewindDir +FSCloseDir +FSCloseDirAsync +FSGetStatFile +FSGetStatFileAsync +FSReadFile +FSReadFileAsync +FSReadFileWithPos +FSReadFileWithPosAsync +FSWriteFile +FSWriteFileAsync +FSWriteFileWithPos +FSWriteFileWithPosAsync +FSGetPosFile +FSGetPosFileAsync +FSSetPosFile +FSSetPosFileAsync +FSFlushFile +FSFlushFileAsync +FSTruncateFile +FSTruncateFileAsync +FSRename +FSRenameAsync +FSGetVolumeState +FSGetLastErrorCodeForViewer +FSGetMountSource +FSMount +FSUnmount +FSBindMount +FSBindUnmount + +// coreinit/foreground.h +OSEnableForegroundExit +OSReleaseForeground +OSSavesDone_ReadyToRelease + +// coreinit/frameheap.h +MEMCreateFrmHeapEx +MEMDestroyFrmHeap +MEMAllocFromFrmHeapEx +MEMFreeToFrmHeap +MEMRecordStateForFrmHeap +MEMFreeByStateToFrmHeap +MEMAdjustFrmHeap +MEMResizeForMBlockFrmHeap +MEMGetAllocatableSizeForFrmHeapEx + +// coreinit/ios.h +IOS_Open +IOS_OpenAsync +IOS_Close +IOS_CloseAsync +IOS_Ioctl +IOS_IoctlAsync +IOS_Ioctlv +IOS_IoctlvAsync + +// coreinit/mcp.h +MCP_Open +MCP_Close +MCP_InstallSetTargetDevice +MCP_InstallGetTargetDevice +MCP_InstallSetTargetUsb +MCP_InstallGetInfo +MCP_InstallTitleAsync +MCP_InstallGetProgress +MCP_InstallTitleAbort +MCP_DeleteTitleAsync +MCP_DeviceList +MCP_FullDeviceList + +// coreinit/memheap.h +MEMDumpHeap +MEMFindContainHeap +MEMGetFillValForHeap +MEMSetFillValForHeap + +// coreinit/memlist.h +MEMInitList +MEMAppendListObject +MEMPrependListObject +MEMInsertListObject +MEMRemoveListObject +MEMGetNextListObject +MEMGetPrevListObject +MEMGetNthListObject + +// coreinit/memory.h +OSBlockMove +OSBlockSet +OSEffectiveToPhysical +OSAllocFromSystem +OSFreeToSystem + +// coreinit/messagequeue.h +OSInitMessageQueue +OSInitMessageQueueEx +OSSendMessage +OSReceiveMessage +OSPeekMessage +OSGetSystemMessageQueue + +// coreinit/mutex.h +OSInitMutex +OSInitMutexEx +OSLockMutex +OSUnlockMutex +OSTryLockMutex + +// coreinit/rendezvous.h +OSInitRendezvous +OSWaitRendezvous +OSWaitRendezvousWithTimeout + +// coreinit/screen.h +OSScreenInit +OSScreenShutdown +OSScreenGetBufferSizeEx +OSScreenSetBufferEx +OSScreenClearBufferEx +OSScreenFlipBuffersEx +OSScreenPutFontEx +OSScreenPutPixelEx +OSScreenEnableEx + +// coreinit/semaphore.h +OSInitSemaphore +OSInitSemaphoreEx +OSGetSemaphoreCount +OSSignalSemaphore +OSWaitSemaphore +OSTryWaitSemaphore + +// coreinit/spinlock.h +OSInitSpinLock +OSAcquireSpinLock +OSTryAcquireSpinLock +OSTryAcquireSpinLockWithTimeout +OSReleaseSpinLock +OSUninterruptibleSpinLock_Acquire +OSUninterruptibleSpinLock_TryAcquire +OSUninterruptibleSpinLock_TryAcquireWithTimeout +OSUninterruptibleSpinLock_Release + +// coreinit/systeminfo.h +OSGetSystemInfo +OSEnableHomeButtonMenu +OSIsHomeButtonMenuEnabled + +// coreinit/taskqueue.h +MPInitTaskQ +MPTermTaskQ +MPGetTaskQInfo +MPStartTaskQ +MPStopTaskQ +MPResetTaskQ +MPEnqueTask +MPDequeTask +MPDequeTasks +MPWaitTaskQ +MPWaitTaskQWithTimeout +MPPrintTaskQStats +MPInitTask +MPTermTask +MPGetTaskInfo +MPGetTaskUserData +MPSetTaskUserData +MPRunTasksFromTaskQ +MPRunTask + +// coreinit/thread.h +OSCancelThread +OSCheckActiveThreads +OSCheckThreadStackUsage +OSClearThreadStackUsage +OSContinueThread +OSCreateThread +OSDetachThread +OSExitThread +OSGetActiveThreadLink +OSGetCurrentThread +OSGetDefaultThread +OSGetStackPointer +OSGetThreadAffinity +OSGetThreadName +OSGetThreadPriority +OSGetThreadSpecific +OSIsThreadSuspended +OSIsThreadTerminated +OSJoinThread +OSResumeThread +OSRunThread +OSSetThreadAffinity +OSSetThreadCancelState +OSSetThreadCleanupCallback +OSSetThreadDeallocator +OSSetThreadName +OSSetThreadPriority +OSSetThreadRunQuantum +OSSetThreadSpecific +OSSetThreadStackUsage +OSSleepThread +OSSleepTicks +OSSuspendThread +OSTestThreadCancel +OSWakeupThread +OSYieldThread + +// coreinit/threadqueue.h +OSInitThreadQueue +OSInitThreadQueueEx + +// coreinit/time.h +OSGetTime +OSGetSystemTime +OSGetTick +OSGetSystemTick +OSCalendarTimeToTicks +OSTicksToCalendarTime + +// coreinit/unitheap.h +MEMCreateUnitHeapEx +MEMDestroyUnitHeap +MEMAllocFromUnitHeap +MEMFreeToUnitHeap +MEMCountFreeBlockForUnitHeap +MEMCalcHeapSizeForUnitHeap + +// coreinit/title.h +OSGetTitleID + +// coreinit/internal.h +__os_snprintf diff --git a/cafe/gx2/exports.def b/cafe/gx2/exports.def new file mode 100644 index 0000000..6bdfba6 --- /dev/null +++ b/cafe/gx2/exports.def @@ -0,0 +1,246 @@ +:NAME gx2 +:TEXT + +// gx2/clear.h +GX2ClearColor +GX2ClearDepthStencilEx +GX2ClearBuffersEx +GX2SetClearDepth +GX2SetClearStencil +GX2SetClearDepthStencil + +// gx2/context.h +GX2SetupContextStateEx +GX2GetContextStateDisplayList +GX2SetContextState +GX2SetDefaultState + +// gx2/display.h +GX2SetTVEnable +GX2SetDRCEnable +GX2CalcTVSize +GX2SetTVBuffer +GX2SetTVScale +GX2CalcDRCSize +GX2SetDRCBuffer +GX2SetDRCScale +GX2GetSystemTVScanMode +GX2GetSystemDRCMode +GX2GetSystemDRCScanMode + +// gx2/displaylist.h +GX2BeginDisplayListEx +GX2EndDisplayList +GX2DirectCallDisplayList +GX2CallDisplayList +GX2GetDisplayListWriteStatus +GX2GetCurrentDisplayList +GX2CopyDisplayList + +// gx2/draw.h +GX2SetAttribBuffer +GX2DrawEx +GX2DrawEx2 +GX2DrawIndexedEx +GX2DrawIndexedEx2 +GX2DrawIndexedImmediateEx +GX2SetPrimitiveRestartIndex + +// gx2/event.h +GX2DrawDone +GX2WaitForVsync +GX2WaitForFlip +GX2SetEventCallback +GX2GetEventCallback +GX2GetRetiredTimeStamp +GX2GetLastSubmittedTimeStamp +GX2GetSwapStatus +GX2WaitTimeStamp + +// gx2/mem.h +GX2Invalidate + +// gx2/registers.h +GX2SetAAMask +GX2InitAAMaskReg +GX2GetAAMaskReg +GX2SetAAMaskReg +GX2SetAlphaTest +GX2InitAlphaTestReg +GX2GetAlphaTestReg +GX2SetAlphaTestReg +GX2SetAlphaToMask +GX2InitAlphaToMaskReg +GX2GetAlphaToMaskReg +GX2SetAlphaToMaskReg +GX2SetBlendConstantColor +GX2InitBlendConstantColorReg +GX2GetBlendConstantColorReg +GX2SetBlendConstantColorReg +GX2SetBlendControl +GX2InitBlendControlReg +GX2GetBlendControlReg +GX2SetBlendControlReg +GX2SetColorControl +GX2InitColorControlReg +GX2GetColorControlReg +GX2SetColorControlReg +GX2SetDepthOnlyControl +GX2SetDepthStencilControl +GX2InitDepthStencilControlReg +GX2GetDepthStencilControlReg +GX2SetDepthStencilControlReg +GX2SetStencilMask +GX2InitStencilMaskReg +GX2GetStencilMaskReg +GX2SetStencilMaskReg +GX2SetLineWidth +GX2InitLineWidthReg +GX2GetLineWidthReg +GX2SetLineWidthReg +GX2SetPointSize +GX2InitPointSizeReg +GX2GetPointSizeReg +GX2SetPointSizeReg +GX2SetPointLimits +GX2InitPointLimitsReg +GX2GetPointLimitsReg +GX2SetPointLimitsReg +GX2SetCullOnlyControl +GX2SetPolygonControl +GX2InitPolygonControlReg +GX2SetPolygonControlReg +GX2SetPolygonOffset +GX2InitPolygonOffsetReg +GX2GetPolygonOffsetReg +GX2SetPolygonOffsetReg +GX2SetScissor +GX2InitScissorReg +GX2GetScissorReg +GX2SetScissorReg +GX2SetTargetChannelMasks +GX2InitTargetChannelMasksReg +GX2GetTargetChannelMasksReg +GX2SetTargetChannelMasksReg +GX2SetViewport +GX2InitViewportReg +GX2GetViewportReg +GX2SetViewportReg + +// gx2/sampler.h +GX2InitSampler +GX2InitSamplerBorderType +GX2InitSamplerClamping +GX2InitSamplerDepthCompare +GX2InitSamplerFilterAdjust +GX2InitSamplerLOD +GX2InitSamplerLODAdjust +GX2InitSamplerRoundingMode +GX2InitSamplerXYFilter +GX2InitSamplerZMFilter + +// gx2/state.h +GX2Flush +GX2Init +GX2Shutdown +GX2ResetGPU + +// gx2/shader.h +GX2CalcGeometryShaderInputRingBufferSize +GX2CalcGeometryShaderOutputRingBufferSize +GX2CalcFetchShaderSizeEx +GX2InitFetchShaderEx +GX2SetFetchShader +GX2SetVertexShader +GX2SetPixelShader +GX2SetGeometryShader +GX2SetVertexSampler +GX2SetPixelSampler +GX2SetGeometrySampler +GX2SetVertexUniformReg +GX2SetPixelUniformReg +GX2SetVertexUniformBlock +GX2SetPixelUniformBlock +GX2SetGeometryUniformBlock +GX2SetShaderModeEx +GX2SetStreamOutEnable +GX2SetGeometryShaderInputRingBuffer +GX2SetGeometryShaderOutputRingBuffer +GX2GetPixelShaderGPRs +GX2GetPixelShaderStackEntries +GX2GetVertexShaderGPRs +GX2GetVertexShaderStackEntries +GX2GetGeometryShaderGPRs +GX2GetGeometryShaderStackEntries + +// gx2/surface.h +GX2CalcColorBufferAuxInfo +GX2CalcSurfaceSizeAndAlignment +GX2CalcDepthBufferHiZInfo +GX2SetColorBuffer +GX2SetDepthBuffer +GX2InitColorBufferRegs +GX2InitDepthBufferRegs +GX2InitDepthBufferHiZEnable +GX2GetSurfaceSwizzle +GX2SetSurfaceSwizzle +GX2CopySurface + +// gx2/swap.h +GX2CopyColorBufferToScanBuffer +GX2SwapScanBuffers +GX2GetLastFrame +GX2GetLastFrameGamma +GX2GetSwapInterval +GX2SetSwapInterval + +// gx2/tessellation.h +GX2SetTessellation +GX2SetMinTessellationLevel +GX2SetMaxTessellationLevel + +// gx2/temp.h +GX2TempGetGPUVersion + +// gx2/texture.h +GX2InitTextureRegs +GX2SetPixelTexture +GX2SetVertexTexture +GX2SetGeometryTexture + +// gx2r/buffer.h +GX2RBufferExists +GX2RCreateBuffer +GX2RCreateBufferUserMemory +GX2RDestroyBufferEx +GX2RGetBufferAlignment +GX2RGetBufferAllocationSize +GX2RInvalidateBuffer +GX2RLockBufferEx +GX2RUnlockBufferEx +GX2RSetVertexUniformBlock +GX2RSetPixelUniformBlock +GX2RSetGeometryUniformBlock + +// gx2r/displaylist.h +GX2RBeginDisplayListEx +GX2REndDisplayList +GX2RCallDisplayList +GX2RDirectCallDisplayList + +// gx2r/draw.h +GX2RSetAttributeBuffer +GX2RDrawIndexed + +// gx2r/mem.h +GX2RInvalidateMemory +GX2RIsUserMemory +GX2RSetAllocator + +// gx2r/surface.h +GX2RCreateSurface +GX2RCreateSurfaceUserMemory +GX2RDestroySurfaceEx +GX2RInvalidateSurface +GX2RLockSurfaceEx +GX2RUnlockSurfaceEx diff --git a/cafe/nn_ac/exports.def b/cafe/nn_ac/exports.def new file mode 100644 index 0000000..e1d5b86 --- /dev/null +++ b/cafe/nn_ac/exports.def @@ -0,0 +1,9 @@ +:NAME nn_ac +:TEXT + +// nn_ac/nn_ac.h +ACInitialize +ACFinalize +ACGetStartupId +ACConnectWithConfigId +ACGetAssignedAddress diff --git a/cafe/nsysnet/exports.def b/cafe/nsysnet/exports.def new file mode 100644 index 0000000..b4da7b5 --- /dev/null +++ b/cafe/nsysnet/exports.def @@ -0,0 +1,38 @@ +:NAME nsysnet +:TEXT + +// nsysnet/socket.h +socket_lib_init +socket_lib_finish +socket +socketclose +connect +bind +listen +accept +send +recv +sendto +setsockopt +recvfrom +recvfrom_ex +recvfrom_multi +sendto_multi +sendto_multi_ex +shutdown +inet_aton +inet_ntoa +inet_ntoa_r +inet_ntop +inet_pton +getpeername +getsockname +getsockopt +select +setsocklibopt +getsocklibopt +ntohl +htonl +ntohs +htons +socketlasterr diff --git a/cafe/proc_ui/exports.def b/cafe/proc_ui/exports.def new file mode 100644 index 0000000..8b80547 --- /dev/null +++ b/cafe/proc_ui/exports.def @@ -0,0 +1,19 @@ +:NAME proc_ui +:TEXT + +// procui/procui.h +ProcUICalcMemorySize +ProcUIClearCallbacks +ProcUIDrawDoneRelease +ProcUIInForeground +ProcUIInShutdown +ProcUIInit +ProcUIInitEx +ProcUIIsRunning +ProcUIProcessMessages +ProcUIRegisterCallback +ProcUIRegisterCallbackCore +ProcUISetSaveCallback +ProcUIShutdown +ProcUISubProcessMessages + diff --git a/cafe/sndcore2/exports.def b/cafe/sndcore2/exports.def new file mode 100644 index 0000000..4740269 --- /dev/null +++ b/cafe/sndcore2/exports.def @@ -0,0 +1,68 @@ +:NAME sndcore2 +:TEXT + +// sndcore2/core.h +AXInit +AXInitWithParams +AXIsInit +AXInitProfile +AXGetSwapProfile +AXSetDefaultMixerSelect +AXRegisterAppFrameCallback +AXGetInputSamplesPerFrame +AXGetInputSamplesPerSec +AXQuit + +// sndcore2/device.h +AXGetDeviceMode +AXGetDeviceFinalMixCallback +AXRegisterDeviceFinalMixCallback +AXGetAuxCallback +AXRegisterAuxCallback +AXSetDeviceLinearUpsampler +AXSetDeviceCompressor +AXSetDeviceUpsampleStage +AXSetDeviceVolume + +// sndcore2/drcvs.h +AXGetDRCVSMode +AXSetDRCVSMode +AXSetDRCVSDownmixBalance +AXSetDRCVSLC +AXSetDRCVSLimiter +AXSetDRCVSLimiterThreshold +AXSetDRCVSOutputGain +AXSetDRCVSSpeakerPosition +AXSetDRCVSSurroundDepth +AXSetDRCVSSurroundLevelGain + +// sndcore2/voice.h +AXAcquireVoice +AXAcquireVoiceEx +AXCheckVoiceOffsets +AXFreeVoice +AXGetMaxVoices +AXGetVoiceCurrentOffsetEx +AXGetVoiceLoopCount +AXGetVoiceOffsets +AXIsVoiceRunning +AXSetVoiceAdpcm +AXSetVoiceAdpcmLoop +AXSetVoiceCurrentOffset +AXSetVoiceDeviceMix +AXSetVoiceEndOffset +AXSetVoiceEndOffsetEx +AXSetVoiceInitialTimeDelay +AXSetVoiceLoopOffset +AXSetVoiceLoopOffsetEx +AXSetVoiceLoop +AXSetVoiceOffsets +AXSetVoicePriority +AXSetVoiceRmtIIRCoefs +AXSetVoiceSrc +AXSetVoiceSrcRatio +AXSetVoiceSrcType +AXSetVoiceState +AXSetVoiceType +AXSetVoiceVe +AXSetVoiceVeDelta diff --git a/cafe/sysapp/exports.def b/cafe/sysapp/exports.def new file mode 100644 index 0000000..102e829 --- /dev/null +++ b/cafe/sysapp/exports.def @@ -0,0 +1,18 @@ +:NAME sysapp +:TEXT + +// sysapp/switch.h +SYSSwitchToSyncControllerOnHBM +SYSSwitchToEManual +SYSSwitchToEShop +_SYSSwitchToMainApp +SYSSwitchToBrowserForViewer + +// sysapp/launch.h +SYSRelaunchTitle +SYSLaunchMenu +SYSLaunchTitle +_SYSLaunchMiiStudio +_SYSLaunchSettings +_SYSLaunchParental +_SYSLaunchNotifications diff --git a/cafe/vpad/exports.def b/cafe/vpad/exports.def new file mode 100644 index 0000000..68b342d --- /dev/null +++ b/cafe/vpad/exports.def @@ -0,0 +1,8 @@ +:NAME vpad +:TEXT + +// vpad/input.h +VPADInit +VPADShutdown +VPADRead +VPADGetTPCalibratedPoint diff --git a/cmake/wut-toolchain.cmake b/cmake/wut-toolchain.cmake deleted file mode 100644 index 9da8b42..0000000 --- a/cmake/wut-toolchain.cmake +++ /dev/null @@ -1,97 +0,0 @@ -set(DEVKITPPC $ENV{DEVKITPPC} CACHE STRING "Path to devkitPPC install") -set(WUT_ROOT $ENV{WUT_ROOT} CACHE STRING "Path to wut install") - -# Check for DEVKITPPC -if(NOT DEVKITPPC) - message(FATAL_ERROR "You must have defined DEVKITPPC before calling cmake.") -endif() - -if(NOT WUT_ROOT) - # Let's try find it! - if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake") - # ./ for wut/CMakeLists.txt - set(FIND_WUT_ROOT ${CMAKE_SOURCE_DIR}) - elseif(EXISTS "${CMAKE_SOURCE_DIR}/../cmake/wut-toolchain.cmake") - # ../ for wut/rpl/CMakeLists.txt - set(FIND_WUT_ROOT "${CMAKE_SOURCE_DIR}/..") - elseif(EXISTS "${CMAKE_TOOLCHAIN_FILE}") - # We're a toolchain file installed in WUT_ROOT/cmake - set(FIND_WUT_ROOT "${CMAKE_TOOLCHAIN_FILE}/..") - endif() -endif() - -if(NOT WUT_ROOT) - message(FATAL_ERROR "You must have defined WUT_ROOT before calling cmake.") -endif() - -# Set it in ENV to make sure it gets passed around, cmake is a bit odd like that. -set(ENV{WUT_ROOT} ${WUT_ROOT}) -set(ENV{DEVKITPPC} ${DEVKITPPC}) - -set(CMAKE_SYSTEM_NAME Generic) - -if(WIN32) - # Because "Unix Makefiles" generator does not set this, even if on Windows - set(CMAKE_EXECUTABLE_SUFFIX ".exe") -endif() - -set(CMAKE_C_COMPILER "${DEVKITPPC}/bin/powerpc-eabi-gcc${CMAKE_EXECUTABLE_SUFFIX}") -set(CMAKE_CXX_COMPILER "${DEVKITPPC}/bin/powerpc-eabi-g++${CMAKE_EXECUTABLE_SUFFIX}") - -set(CMAKE_FIND_ROOT_PATH ${DEVKITPPC}) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - -set(DEVKIT_COMPILE_FLAGS "-mcpu=750 -meabi -mhard-float -mno-sdata") -set(DEVKIT_LINKER_FLAGS "-nostartfiles \"-L${DEVKITPPC}/lib\"") - -set(RPX_COMPILE_FLAGS "${DEVKIT_COMPILE_FLAGS}") - -set(RPX_LINKER_FLAGS "\ - ${DEVKIT_LINKER_FLAGS} \ - -pie -fPIE -z common-page-size=64 -z max-page-size=64 -T \"${WUT_ROOT}/rules/rpl.ld\"\ - \"-L${WUT_ROOT}/lib\" -Wl,-wrap,__eabi") - -set(ELF_TO_RPL ${WUT_ROOT}/bin/elf2rpl${CMAKE_EXECUTABLE_SUFFIX}) - -if(CMAKE_INCLUDE_PATH) -set(RPX_COMPILE_FLAGS "\ - ${RPX_COMPILE_FLAGS} \ - \"-I${CMAKE_INCLUDE_PATH}\"") -endif() - -if(CMAKE_LIBRARY_PATH) -set(RPX_LINKER_FLAGS "\ - ${RPX_LINKER_FLAGS} \ - \"-L${CMAKE_LIBRARY_PATH}\"") -endif() - -macro(add_rpx target) - add_executable(${ARGV}) - set_target_properties(${target} PROPERTIES - COMPILE_FLAGS "${RPX_COMPILE_FLAGS}" - LINK_FLAGS "${RPX_LINKER_FLAGS}") - - target_include_directories(${target} PRIVATE "${WUT_ROOT}/include") - target_link_libraries(${target} crt) - - add_custom_command(TARGET ${target} POST_BUILD - COMMAND "${ELF_TO_RPL}" "$" "$.rpx" - COMMENT "Converting $ to rpx") -endmacro() - -macro(add_rpx_lite target) - add_executable(${ARGV}) - set_target_properties(${target} PROPERTIES - COMPILE_FLAGS "${RPX_COMPILE_FLAGS}" - LINK_FLAGS "${RPX_LINKER_FLAGS}") - - target_include_directories(${target} PRIVATE "${WUT_ROOT}/include") - target_link_libraries(${target} crt-lite) - - add_custom_command(TARGET ${target} POST_BUILD - COMMAND "${ELF_TO_RPL}" "$" "$.rpx" - COMMENT "Converting $ to rpx") -endmacro() diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt deleted file mode 100644 index c078e31..0000000 --- a/externals/CMakeLists.txt +++ /dev/null @@ -1,92 +0,0 @@ -project(libraries) -include(ExternalProject) - -# fmtlib -set(FMTLIB_DIR "fmt") -externalproject_add(fmtlib - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FMTLIB_DIR}" - CMAKE_CACHE_ARGS - -DCMAKE_C_COMPILER:string=${CMAKE_C_COMPILER} - -DCMAKE_C_FLAGS:string=${CMAKE_C_FLAGS} - -DCMAKE_CXX_COMPILER:string=${CMAKE_CXX_COMPILER} - -DCMAKE_CXX_FLAGS:string=${CMAKE_CXX_FLAGS} - -DFMT_DOC:string=off - -DFMT_INSTALL:string=off - -DFMT_TEST:string=off - INSTALL_COMMAND "") -externalproject_get_property(fmtlib BINARY_DIR) -set_target_properties(fmtlib PROPERTIES FOLDER libraries) - -if(MSVC) - set(FMTLIB_IMPORTED_LOCATION - IMPORTED_LOCATION_DEBUG "${BINARY_DIR}/fmt/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}fmt${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_RELEASE "${BINARY_DIR}/fmt/Release/${CMAKE_FIND_LIBRARY_PREFIXES}fmt${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_RELWITHDEBINFO "${BINARY_DIR}/fmt/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}fmt${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_MINSIZEREL "${BINARY_DIR}/fmt/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}fmt${CMAKE_FIND_LIBRARY_SUFFIXES}") -else() - set(FMTLIB_IMPORTED_LOCATION - IMPORTED_LOCATION "${BINARY_DIR}/fmt/${CMAKE_FIND_LIBRARY_PREFIXES}fmt.a") -endif() - -add_library(fmtlib_import STATIC IMPORTED GLOBAL) -add_dependencies(fmtlib_import fmtlib) -set_target_properties(fmtlib_import PROPERTIES ${FMTLIB_IMPORTED_LOCATION}) - -add_library(fmtlib_final INTERFACE) -target_include_directories(fmtlib_final INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/${FMTLIB_DIR}") -target_link_libraries(fmtlib_final INTERFACE fmtlib_import) -set(FMTLIB_LINK fmtlib_final PARENT_SCOPE) - -# excmd -set(EXCMD_DIR "excmd") -add_library(excmd INTERFACE) -target_include_directories(excmd INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/${EXCMD_DIR}/src") -set(EXCMD_LINK excmd PARENT_SCOPE) - -# zlib -find_package(ZLIB QUIET) - -if(NOT ZLIB_FOUND) - set(ZLIB_DIR "zlib") - externalproject_add(zlib - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_DIR}" - PATCH_COMMAND ${CMAKE_COMMAND} -E remove /zconf.h - CMAKE_CACHE_ARGS - -DCMAKE_C_COMPILER:string=${CMAKE_C_COMPILER} - -DCMAKE_C_FLAGS:string=${CMAKE_C_FLAGS} - -DCMAKE_CXX_COMPILER:string=${CMAKE_CXX_COMPILER} - -DCMAKE_CXX_FLAGS:string=${CMAKE_CXX_FLAGS} - -DBUILD_SHARED_LIBS:string=off - INSTALL_COMMAND "" - ) - externalproject_get_property(zlib BINARY_DIR) - externalproject_add_step(zlib - copy_to_binary - DEPENDEES build - DEPENDERS install - COMMAND ${CMAKE_COMMAND} -E copy_directory "${BINARY_DIR}/$(Configuration)" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(Configuration)") - set_target_properties(zlib PROPERTIES FOLDER libraries) - - if(MSVC) - set(ZLIB_IMPORTED_LOCATION - IMPORTED_LOCATION_DEBUG "${BINARY_DIR}/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}zlibstaticd${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_RELEASE "${BINARY_DIR}/Release/${CMAKE_FIND_LIBRARY_PREFIXES}zlibstatic${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_RELWITHDEBINFO "${BINARY_DIR}/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}zlibstatic${CMAKE_FIND_LIBRARY_SUFFIXES}" - IMPORTED_LOCATION_MINSIZEREL "${BINARY_DIR}/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}zlibstatic${CMAKE_FIND_LIBRARY_SUFFIXES}") - else() - set(ZLIB_IMPORTED_LOCATION - IMPORTED_LOCATION "${BINARY_DIR}/${CMAKE_FIND_LIBRARY_PREFIXES}z.a") - endif() - - add_library(zlib_import STATIC IMPORTED GLOBAL) - add_dependencies(zlib_import zlib) - set_target_properties(zlib_import PROPERTIES ${ZLIB_IMPORTED_LOCATION}) - - set(ZLIB_LIBRARIES zlib_import) - set(ZLIB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_DIR} ${BINARY_DIR}) -endif() - -add_library(zlib_final INTERFACE) -target_include_directories(zlib_final INTERFACE ${ZLIB_INCLUDE_DIRS}) -target_link_libraries(zlib_final INTERFACE ${ZLIB_LIBRARIES}) -set(ZLIB_LINK zlib_final PARENT_SCOPE) diff --git a/externals/excmd b/externals/excmd deleted file mode 160000 index c2e8d49..0000000 --- a/externals/excmd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c2e8d492b02d51441bda2d5b6cc039843894d08b diff --git a/externals/fmt b/externals/fmt deleted file mode 160000 index 3983438..0000000 --- a/externals/fmt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 398343897f98b88ade80bbebdcbe82a36c65a980 diff --git a/externals/zlib b/externals/zlib deleted file mode 160000 index 5089329..0000000 --- a/externals/zlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 50893291621658f355bc5b4d450a8d06a563053d diff --git a/rules/rpl.ld b/rules/rpl.ld deleted file mode 100644 index 1f95e37..0000000 --- a/rules/rpl.ld +++ /dev/null @@ -1,259 +0,0 @@ -OUTPUT_FORMAT("elf32-powerpc") -OUTPUT_ARCH(powerpc:common) - -EXTERN(_start) -ENTRY(_start) - -MEMORY { - system (rwx) : ORIGIN = 0x01000000, LENGTH = 32M - code (rwx) : ORIGIN = 0x02000000, LENGTH = 224M - data (rw) : ORIGIN = 0x10000000, LENGTH = 800M - load (rwx) : ORIGIN = 0xC0000000, LENGTH = 128M -} - -PHDRS { - hdr_text PT_LOAD FILEHDR PHDRS FLAGS(0x01 | 0x04); - hdr_data PT_LOAD FLAGS(0x02 | 0x04); - hdr_srodata PT_LOAD FLAGS(0x04); - hdr_sdata PT_LOAD FLAGS(0x02 | 0x04); -} - -SECTIONS { - . = ORIGIN(code); - - .syscall ALIGN(32) : { *(.syscall) } : hdr_text - - /* Standard code section */ - .text ALIGN(32) : { - /* .init */ - KEEP( *(.crt0) ) - KEEP( *(.init) ) - . = ALIGN(4); - - /* .text */ - *(.text) - *(.text.*) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.glue_7) - *(.glue_7t) - *(.stub) - *(.gnu.warning) - *(.gnu.linkonce.t*) - . = ALIGN(4); - - *(.rplTramp.text) - *(SORT(.rplTramp.text.*)) - . = ALIGN(4); - - /* .fini */ - KEEP( *(.fini) ) - . = ALIGN(4); - - } : hdr_text - - /* Standard data sections */ - . = ORIGIN(data); - - .data ALIGN(256) : { - *(.data) - *(.data.*) - *(.eh_frame) - *(.eh_frame_hdr) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - - . = ALIGN(32); - __sdata_start = .; - *(.sdata) - *(.sdata.*) - __sdata_end = .; - - . = ALIGN(32); - __sdata2_start = .; - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - __sdata2_end = .; - } : hdr_sdata - - .tdata ALIGN(256) : - { - __tdata_lma = .; - *(.tdata) - *(.tdata.*) - *(.gnu.linkonce.td.*) - . = ALIGN(4); - __tdata_lma_end = .; - } : hdr_data - - .preinit_array ALIGN(256) : - { - PROVIDE (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE (__preinit_array_end = .); - } : hdr_data - - .init_array ALIGN(256) : - { - PROVIDE (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE (__init_array_end = .); - } : hdr_data - - .fini_array ALIGN(256) : - { - PROVIDE (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE (__fini_array_end = .); - } : hdr_data - - .ctors ALIGN(256) : - { - KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */ - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } : hdr_data - - .dtors ALIGN(256) : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } : hdr_data - - .jcr ALIGN(256) : - { - KEEP (*(.jcr)) - } : hdr_data - - __bss_start = .; - .bss ALIGN(256) : - { - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b*) - *(COMMON) - . = ALIGN(32); - - __sbss_start = .; - *(.sbss) - *(.sbss.*) - __sbss_end = .; - . = ALIGN(32); - - __sbss2_start = .; - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - __sbss2_end = .; - . = ALIGN(32); - - /* Reserve space for the TLS segment of the main thread */ - __tls_start = .; - - __tbss_start = .; - *(.tbss) - *(.tbss.*) - *(.gnu.linkonce.tb.*) - *(.tcommon) - __tbss_end = .; - - . += + SIZEOF(.tdata); - __tls_end = .; - . = ALIGN(32); - } : hdr_data - __bss_end = .; - - /* System stuff is for our elf2rpl converter to go through */ - . = ORIGIN(system); - - /* Contains the name of RPLs, referenced by .lib.rplLibs */ - .rodata.rplNames ALIGN(32) : { - *(.rodata.rplNames) - } : hdr_data - - /* - * List of RPL libraries to import, in format: - * uint32_t nameAddress -> .rodata.rplNames - * uint32_t firstFuncEntry -> .data.rplFuncStubs - */ - .lib.rplLibs ALIGN(32) : { - *(.lib.rplLibs) - KEEP (*(.lib.rplLibs*)) - } - - /* - * List of functions an RPL exports, in format: - * uint32_t trampAddress - */ - .data.rplFuncStubs ALIGN(32) : { - *(.data.rplFuncStubs) - } - - /* Required compiler trash */ - .fixup ALIGN(32) : { *(.fixup*) } - .got ALIGN(32) : { *(.got*) } - .gcc_except_table ALIGN(32) : { *(.gcc_except_table*) } - .hash ALIGN(32) : { *(.hash) } - .dynsym ALIGN(32) : { *(.dynsym) } - - /* Put all dynamic loader relocations into one section */ - .rela.dyn ALIGN(32) : { - *(.rela.dyn) - *(.rela.data.rplFuncStubs) - *(.rela.lib.rplLibs) - } - - /* Relocations for .rodata sections */ - .rela.rodata ALIGN(32) : - { - *(.rela.rodata .rela.rodata.*) - } - - /* Relocations for .text sections */ - .rela.text ALIGN(32) : - { - *(.rela.text .rela.text.*) - *(.rela.rplTramp.text) - } - - /* Relocations for .data sections */ - .rela.data ALIGN(32) : - { - *(.rela.data .rela.data.*) - } - - /* Relocations for .bss sections */ - .rela.bss ALIGN(32) : - { - *(.rela.bss .rela.bss.*) - } - - /* Symbol tables */ - .shstrtab ALIGN(32) : { *(.shstrtab) } - .symtab ALIGN(32) : { *(.symtab) } - .strtab ALIGN(32) : { *(.strtab) } - - /DISCARD/ : { - *(.interp) - *(.dynstr) - *(.dynamic) - *(.comment) - } - - __SDATA_START__ = __sdata_start; - __SBSS_END__ = __sbss_end; - - __SDATA2_START__ = __sdata2_start; - __SBSS2_END__ = __sbss2_end; - - _SDA_BASE_ = __sbss_end; - _SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2); -} diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt deleted file mode 100644 index 1b85c9e..0000000 --- a/samples/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(samples) - -add_subdirectory(helloworld) -add_subdirectory(pong) -add_subdirectory(gx2) diff --git a/samples/gx2/CMakeLists.txt b/samples/gx2/CMakeLists.txt deleted file mode 100644 index e5854f1..0000000 --- a/samples/gx2/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(samples-gx2) - -add_subdirectory(triangle) diff --git a/samples/gx2/content/pos_col_shader.gsh b/samples/gx2/content/pos_col_shader.gsh deleted file mode 100644 index e1c4694..0000000 Binary files a/samples/gx2/content/pos_col_shader.gsh and /dev/null differ diff --git a/samples/gx2/content/pos_col_shader.psh b/samples/gx2/content/pos_col_shader.psh deleted file mode 100644 index 75c6832..0000000 --- a/samples/gx2/content/pos_col_shader.psh +++ /dev/null @@ -1,7 +0,0 @@ -; $MODE = "UniformRegister" -; $NUM_SPI_PS_INPUT_CNTL = 1 -; $SPI_PS_INPUT_CNTL[0].SEMANTIC = 0 -; $SPI_PS_INPUT_CNTL[0].DEFAULT_VAL = 1 - -00 EXP_DONE: PIX0, R0.xyzw -END_OF_PROGRAM diff --git a/samples/gx2/content/pos_col_shader.vsh b/samples/gx2/content/pos_col_shader.vsh deleted file mode 100644 index 8ca0dea..0000000 --- a/samples/gx2/content/pos_col_shader.vsh +++ /dev/null @@ -1,14 +0,0 @@ -; $MODE = "UniformRegister" -; $ATTRIB_VARS[0].name = "aColour" -; $ATTRIB_VARS[0].type = "Float4" -; $ATTRIB_VARS[0].location = 0 -; $ATTRIB_VARS[1].name = "aPosition" -; $ATTRIB_VARS[1].type = "Float4" -; $ATTRIB_VARS[1].location = 1 -; $NUM_SPI_VS_OUT_ID = 1 -; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0 - -00 CALL_FS NO_BARRIER -01 EXP_DONE: POS0, R2.xyzw -02 EXP_DONE: PARAM0, R1.xyzw NO_BARRIER -END_OF_PROGRAM diff --git a/samples/gx2/triangle/CMakeLists.txt b/samples/gx2/triangle/CMakeLists.txt deleted file mode 100644 index a86a9fd..0000000 --- a/samples/gx2/triangle/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(samples-gx2-triangle) - -file(GLOB_RECURSE SOURCE_FILES src/*.c) -file(GLOB_RECURSE HEADER_FILES src/*.h) - -add_rpx_lite(triangle ${SOURCE_FILES} ${HEADER_FILES}) -target_link_libraries(triangle - whb - coreinit - defaultheap - gx2 - gfd - nsysnet - proc_ui - sysapp) diff --git a/samples/gx2/triangle/src/main.c b/samples/gx2/triangle/src/main.c deleted file mode 100644 index e0bd431..0000000 --- a/samples/gx2/triangle/src/main.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static const float sPositionData[] = -{ - 0.0f, -0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 0.0f -}; - -static const float sColourData[] = -{ - 1.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 1.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 1.0f -}; - -int main(int argc, char **argv) -{ - GX2RBuffer positionBuffer = { 0 }; - GX2RBuffer colourBuffer = { 0 }; - WHBGfxShaderGroup group = { 0 }; - void *buffer = NULL; - char *gshFileData = NULL; - char *sdRootPath = NULL; - char path[256]; - int result = 0; - - WHBLogUdpInit(); - WHBProcInit(); - WHBGfxInit(); - - if (!WHBMountSdCard()) { - result = -1; - goto exit; - } - - sdRootPath = WHBGetSdCardMountPath(); - sprintf(path, "%s/shaders/pos_colour.gsh", sdRootPath); - - gshFileData = WHBReadWholeFile(path, NULL); - if (!WHBGfxLoadGFDShaderGroup(&group, 0, gshFileData)) { - result = -1; - WHBLogPrintf("WHBGfxLoadGFDShaderGroup returned FALSE"); - goto exit; - } - - WHBGfxInitShaderAttribute(&group, "aColour", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32); - WHBGfxInitShaderAttribute(&group, "aPosition", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32); - WHBGfxInitFetchShader(&group); - - WHBFreeWholeFile(gshFileData); - gshFileData = NULL; - - positionBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; - positionBuffer.elemSize = 4 * 4; - positionBuffer.elemCount = 3; - GX2RCreateBuffer(&positionBuffer); - buffer = GX2RLockBufferEx(&positionBuffer, 0); - memcpy(buffer, sPositionData, positionBuffer.elemSize * positionBuffer.elemCount); - GX2RUnlockBufferEx(&positionBuffer, 0); - - colourBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; - colourBuffer.elemSize = 4 * 4; - colourBuffer.elemCount = 3; - GX2RCreateBuffer(&colourBuffer); - buffer = GX2RLockBufferEx(&colourBuffer, 0); - memcpy(buffer, sColourData, colourBuffer.elemSize * colourBuffer.elemCount); - GX2RUnlockBufferEx(&colourBuffer, 0); - - WHBLogPrintf("Begin rendering..."); - while (WHBProcIsRunning()) { - WHBGfxBeginRender(); - - WHBGfxBeginRenderTV(); - GX2SetFetchShader(&group.fetchShader); - GX2SetVertexShader(group.vertexShader); - GX2SetPixelShader(group.pixelShader); - GX2RSetAttributeBuffer(&colourBuffer, 0, colourBuffer.elemSize, 0); - GX2RSetAttributeBuffer(&positionBuffer, 1, positionBuffer.elemSize, 0); - GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, 3, 0, 1); - WHBGfxFinishRenderTV(); - - WHBGfxBeginRenderDRC(); - GX2SetFetchShader(&group.fetchShader); - GX2SetVertexShader(group.vertexShader); - GX2SetPixelShader(group.pixelShader); - GX2RSetAttributeBuffer(&colourBuffer, 0, colourBuffer.elemSize, 0); - GX2RSetAttributeBuffer(&positionBuffer, 1, positionBuffer.elemSize, 0); - GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLES, 3, 0, 1); - WHBGfxFinishRenderDRC(); - - WHBGfxFinishRender(); - } - -exit: - WHBLogPrintf("Exiting..."); - GX2RDestroyBufferEx(&positionBuffer, 0); - GX2RDestroyBufferEx(&colourBuffer, 0); - WHBUnmountSdCard(); - WHBGfxShutdown(); - WHBProcShutdown(); - WHBLogUdpDeinit(); - return result; -} diff --git a/samples/helloworld/CMakeLists.txt b/samples/helloworld/CMakeLists.txt index e360f1e..85459a5 100644 --- a/samples/helloworld/CMakeLists.txt +++ b/samples/helloworld/CMakeLists.txt @@ -1,8 +1,12 @@ cmake_minimum_required(VERSION 3.2) project(helloworld) +include("${WUT_ROOT}/share/wut.cmake" REQUIRED) -add_rpx(helloworld src/main.c) +add_executable(helloworld main.cpp) target_link_libraries(helloworld - coreinit - proc_ui - sysapp) + coreinit + proc_ui + sysapp) +wut_create_rpx(helloworld.rpx helloworld) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/helloworld.rpx DESTINATION "${CMAKE_INSTALL_PREFIX}") diff --git a/samples/helloworld/src/main.c b/samples/helloworld/main.cpp similarity index 77% rename from samples/helloworld/src/main.c rename to samples/helloworld/main.cpp index 8627186..47cbc96 100644 --- a/samples/helloworld/src/main.c +++ b/samples/helloworld/main.cpp @@ -4,8 +4,10 @@ #include #include #include +#include bool isAppRunning = true; +std::string testStr = "Initial Value"; static void SaveCallback() @@ -22,14 +24,17 @@ AppRunning() ProcUIStatus status = ProcUIProcessMessages(true); if (status == PROCUI_STATUS_EXITING) { - // Being closed, deinit, free, and prepare to exit - isAppRunning = false; - ProcUIShutdown(); + // Being closed, deinit, free, and prepare to exit + testStr = "PROCUI_STATUS_EXITING"; + isAppRunning = false; + ProcUIShutdown(); } else if (status == PROCUI_STATUS_RELEASE_FOREGROUND) { - // Free up MEM1 to next foreground app, deinit screen, etc. - ProcUIDrawDoneRelease(); + // Free up MEM1 to next foreground app, deinit screen, etc. + testStr = "PROCUI_STATUS_RELEASE_FOREGROUND"; + ProcUIDrawDoneRelease(); } else if(status == PROCUI_STATUS_IN_FOREGROUND) { // Executed while app is in foreground + testStr = "PROCUI_STATUS_IN_FOREGROUND"; } } @@ -39,7 +44,7 @@ AppRunning() static int CoreEntryPoint(int argc, const char **argv) { - OSReport("Hello world from %s", argv[0]); + OSReport("Hello world from %s %s", argv[0], testStr.c_str()); return argc; } diff --git a/samples/pong/CMakeLists.txt b/samples/pong/CMakeLists.txt deleted file mode 100644 index a505db8..0000000 --- a/samples/pong/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(pong) - -include($ENV{WUT_ROOT}/cmake/wut-toolchain.cmake) - -file(GLOB_RECURSE SOURCE_FILES src/*.c) -file(GLOB_RECURSE HEADER_FILES src/*.h) - -add_rpx(pong ${SOURCE_FILES} ${HEADER_FILES}) -target_link_libraries(pong - coreinit - proc_ui - vpad) diff --git a/samples/pong/src/draw.c b/samples/pong/src/draw.c deleted file mode 100755 index 113557f..0000000 --- a/samples/pong/src/draw.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "draw.h" - -#include -#include - -void *screenBuffer; - -void flipBuffers() -{ - //Grab the buffer size for each screen (TV and gamepad) - int buf0_size = OSScreenGetBufferSizeEx(0); - int buf1_size = OSScreenGetBufferSizeEx(1); - - //Flush the cache - DCFlushRange((void *)screenBuffer + buf0_size, buf1_size); - DCFlushRange((void *)screenBuffer, buf0_size); - - //Flip the buffer - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); -} - -void drawString(int x, int y, char * string) -{ - OSScreenPutFontEx(0, x, y, string); - OSScreenPutFontEx(1, x, y, string); -} - -void fillScreen(char r,char g,char b,char a) -{ - uint32_t num = (r << 24) | (g << 16) | (b << 8) | a; - OSScreenClearBufferEx(0, num); - OSScreenClearBufferEx(1, num); -} - -//Rendering in -void drawPixel(int x, int y, char r, char g, char b, char a) -{ - uint32_t num = (r << 24) | (g << 16) | (b << 8) | a; - OSScreenPutPixelEx(0,x*2,y*2,num); - OSScreenPutPixelEx(1,x*2,y*2,num); - OSScreenPutPixelEx(0,x*2+1,y*2,num); - OSScreenPutPixelEx(1,x*2+1,y*2,num); - OSScreenPutPixelEx(0,x*2,y*2+1,num); - OSScreenPutPixelEx(1,x*2,y*2+1,num); - OSScreenPutPixelEx(0,x*2+1,y*2+1,num); - OSScreenPutPixelEx(1,x*2+1,y*2+1,num); - //Code to write to framebuffer directly. For some reason this is only writing to one of the framebuffers when calling flipBuffers. Should provide speedup but needs investigation. - /* - int buf0_size = OSScreenGetBufferSizeEx(0); - int height = 1024; - int width = 1280; - char *screen = (void *)screenBuffer; - uint32_t v=(x + y*width)*4; - screen[v]=r; - screen[v+1]=g; - screen[v+2]=b; - screen[v+3]=a; - - height = 480; - width = 896; - char *screen2 = (void *)screenBuffer + buf0_size; - v=(x + y*width)*4; - screen2[v]=r; - screen2[v+1]=g; - screen2[v+2]=b; - screen2[v+3]=a; - */ -} - -void drawLine(int x1, int y1, int x2, int y2, char r, char g, char b, char a) -{ - - int x, y; - if (x1 == x2){ - if (y1 < y2) for (y = y1; y <= y2; y++) drawPixel(x1, y, r, g, b, a); - else for (y = y2; y <= y1; y++) drawPixel(x1, y, r, g, b, a); - } - else { - if (x1 < x2) for (x = x1; x <= x2; x++) drawPixel(x, y1, r, g, b, a); - else for (x = x2; x <= x1; x++) drawPixel(x, y1, r, g, b, a); - } -} - -void drawRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a) -{ - drawLine(x1, y1, x2, y1, r, g, b, a); - drawLine(x2, y1, x2, y2, r, g, b, a); - drawLine(x1, y2, x2, y2, r, g, b, a); - drawLine(x1, y1, x1, y2, r, g, b, a); -} - -void drawFillRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a) -{ - int X1, X2, Y1, Y2, i, j; - - if (x1 < x2){ - X1 = x1; - X2 = x2; - } - else { - X1 = x2; - X2 = x1; - } - - if (y1 < y2){ - Y1 = y1; - Y2 = y2; - } - else { - Y1 = y2; - Y2 = y1; - } - for (i = X1; i <= X2; i++){ - for (j = Y1; j <= Y2; j++){ - drawPixel(i, j, r, g, b, a); - } - } -} - -void drawCircle(int xCen, int yCen, int radius, char r, char g, char b, char a) -{ - int x = 0; - int y = radius; - int p = (5 - radius * 4) / 4; - drawCircleCircum(xCen, yCen, x, y, r, g, b, a); - while (x < y){ - x++; - if (p < 0){ - p += 2 * x + 1; - } - else{ - y--; - p += 2 * (x - y) + 1; - } - drawCircleCircum(xCen, yCen, x, y, r, g, b, a); - } -} - -void drawFillCircle(int xCen, int yCen, int radius, char r, char g, char b, char a) -{ - drawCircle(xCen, yCen, radius, r, g, b, a); - int x, y; - for (y = -radius; y <= radius; y++){ - for (x = -radius; x <= radius; x++) - if (x*x + y*y <= radius*radius + radius * .8f) - drawPixel(xCen + x, yCen + y, r, g, b, a); - } -} - -void drawCircleCircum(int cx, int cy, int x, int y, char r, char g, char b, char a) -{ - - if (x == 0){ - drawPixel(cx, cy + y, r, g, b, a); - drawPixel(cx, cy - y, r, g, b, a); - drawPixel(cx + y, cy, r, g, b, a); - drawPixel(cx - y, cy, r, g, b, a); - } - if (x == y){ - drawPixel(cx + x, cy + y, r, g, b, a); - drawPixel(cx - x, cy + y, r, g, b, a); - drawPixel(cx + x, cy - y, r, g, b, a); - drawPixel(cx - x, cy - y, r, g, b, a); - } - if (x < y){ - drawPixel(cx + x, cy + y, r, g, b, a); - drawPixel(cx - x, cy + y, r, g, b, a); - drawPixel(cx + x, cy - y, r, g, b, a); - drawPixel(cx - x, cy - y, r, g, b, a); - drawPixel(cx + y, cy + x, r, g, b, a); - drawPixel(cx - y, cy + x, r, g, b, a); - drawPixel(cx + y, cy - x, r, g, b, a); - drawPixel(cx - y, cy - x, r, g, b, a); - } -} diff --git a/samples/pong/src/draw.h b/samples/pong/src/draw.h deleted file mode 100755 index 5f5a880..0000000 --- a/samples/pong/src/draw.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DRAW_H -#define DRAW_H -#include -#include - -void *screenBuffer; - -//Function declarations for my graphics library -void flipBuffers(); -void fillScreen(char r, char g, char b, char a); -void drawString(int x, int y, char * string); -void drawPixel(int x, int y, char r, char g, char b, char a); -void drawLine(int x1, int y1, int x2, int y2, char r, char g, char b, char a); -void drawRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a); -void drawFillRect(int x1, int y1, int x2, int y2, char r, char g, char b, char a); -void drawCircle(int xCen, int yCen, int radius, char r, char g, char b, char a); -void drawFillCircle(int xCen, int yCen, int radius, char r, char g, char b, char a); -void drawCircleCircum(int cx, int cy, int x, int y, char r, char g, char b, char a); -#endif /* DRAW_H */ diff --git a/samples/pong/src/memory.c b/samples/pong/src/memory.c deleted file mode 100644 index 2d83baf..0000000 --- a/samples/pong/src/memory.c +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#include -#include -#include -#include -#include -#include "memory.h" - -#define MEMORY_ARENA_1 0 -#define MEMORY_ARENA_2 1 -#define MEMORY_ARENA_3 2 -#define MEMORY_ARENA_4 3 -#define MEMORY_ARENA_5 4 -#define MEMORY_ARENA_6 5 -#define MEMORY_ARENA_7 6 -#define MEMORY_ARENA_8 7 -#define MEMORY_ARENA_FG_BUCKET 8 - -static void *mem1_heap; -static void *bucket_heap; - -void memoryInitialize(void) -{ - void *mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); - unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); - void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); - if(mem1_memory) - mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); - - void *bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); - unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); - void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); - if(bucket_memory) - bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); -} - -void memoryRelease(void) -{ - MEMDestroyExpHeap(mem1_heap); - MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3); - mem1_heap = NULL; - - MEMDestroyExpHeap(bucket_heap); - MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3); - bucket_heap = NULL; -} - -//!------------------------------------------------------------------------------------------- -//! some wrappers -//!------------------------------------------------------------------------------------------- -void * MEM2_alloc(unsigned int size, unsigned int align) -{ - return memalign(align, size); -} - -void MEM2_free(void *ptr) -{ - free(ptr); -} - -void * MEM1_alloc(unsigned int size, unsigned int align) -{ - if (align < 4) - align = 4; - return MEMAllocFromExpHeapEx(mem1_heap, size, align); -} - -void MEM1_free(void *ptr) -{ - MEMFreeToExpHeap(mem1_heap, ptr); -} - -void * MEMBucket_alloc(unsigned int size, unsigned int align) -{ - if (align < 4) - align = 4; - return MEMAllocFromExpHeapEx(bucket_heap, size, align); -} - -void MEMBucket_free(void *ptr) -{ - MEMFreeToExpHeap(bucket_heap, ptr); -} diff --git a/samples/pong/src/memory.h b/samples/pong/src/memory.h deleted file mode 100644 index 59764d0..0000000 --- a/samples/pong/src/memory.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#ifndef __MEMORY_H_ -#define __MEMORY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -void memoryInitialize(void); -void memoryRelease(void); - -void * MEM2_alloc(unsigned int size, unsigned int align); -void MEM2_free(void *ptr); - -void * MEM1_alloc(unsigned int size, unsigned int align); -void MEM1_free(void *ptr); - -void * MEMBucket_alloc(unsigned int size, unsigned int align); -void MEMBucket_free(void *ptr); - -#ifdef __cplusplus -} -#endif - -#endif // __MEMORY_H_ diff --git a/samples/pong/src/pong.c b/samples/pong/src/pong.c deleted file mode 100755 index b3c58a7..0000000 --- a/samples/pong/src/pong.c +++ /dev/null @@ -1,425 +0,0 @@ -#include "pong.h" - -#include -#include - -//Sets a collsion box. -int collisionBox(int box1x, int box1y, int width1, int height1, int box2x, int box2y, int width2, int height2){ - int corner1x = box1x + width1; - int corner1y = box1y - height1; - int corner2x = box2x + width2; - int corner2y = box2y - height2; - - if (abs(box1x - corner2x)< 2 || abs(corner1x - box2x)< 2){ - if ((box1y >= corner2y && box1y <= box2y) || (corner1y >= corner2y && corner1y <= box2y))return 1; - - } - - if (abs(box1y - corner2y) < 2 || abs(corner1y - box2y) < 2){ - if ((box1x <= corner2x && box1x >= box2x) || (corner1x <= corner2x && corner1x >= box2x))return 2; - } - - - - return 0; -} - -//Updates player1 location -void p1Move(struct pongGlobals *myPongGlobals) { - - if ((myPongGlobals->button & VPAD_BUTTON_LEFT) && myPongGlobals->p1X > myPongGlobals->xMinBoundry) { - - //Trigger render flag - myPongGlobals->renderP1Flag = 1; - - //Update player location - myPongGlobals->p1X--; - - } - - if ((myPongGlobals->button & VPAD_BUTTON_RIGHT) && myPongGlobals->p1X+myPongGlobals->p1X_size < myPongGlobals->xMaxBoundry/4) { - - myPongGlobals->p1X++; - //Trigger render flag - myPongGlobals->renderP1Flag = 1; - } - - if ((myPongGlobals->button & VPAD_BUTTON_UP) && myPongGlobals->p1Y-myPongGlobals->p1Y_size > myPongGlobals->yMinBoundry) { - - //Trigger render flag - myPongGlobals->renderP1Flag = 1; - - //Update player location - myPongGlobals->p1Y--; - - } - if ((myPongGlobals->button & VPAD_BUTTON_DOWN) && myPongGlobals->p1Y < myPongGlobals->yMaxBoundry) { - - myPongGlobals->p1Y++; - //Trigger render flag - myPongGlobals->renderP1Flag = 1; - } - -}; - -//Updates player1 location -void p2Move(struct pongGlobals *myPongGlobals) { - - if ((myPongGlobals->button & VPAD_BUTTON_Y) && myPongGlobals->p2X > myPongGlobals->xMaxBoundry-myPongGlobals->xMaxBoundry/4) { - - //Trigger render flag - myPongGlobals->renderP2Flag = 1; - - //Update player location - myPongGlobals->p2X--; - - } - - if ((myPongGlobals->button & VPAD_BUTTON_A) && myPongGlobals->p2X+myPongGlobals->p2X_size < myPongGlobals->xMaxBoundry) { - - myPongGlobals->p2X++; - //Trigger render flag - myPongGlobals->renderP2Flag = 1; - } - - if ((myPongGlobals->button & VPAD_BUTTON_X) && myPongGlobals->p2Y-myPongGlobals->p2Y_size > myPongGlobals->yMinBoundry) { - - //Trigger render flag - myPongGlobals->renderP2Flag = 1; - - //Update player location - myPongGlobals->p2Y--; - - } - if ((myPongGlobals->button & VPAD_BUTTON_B) && myPongGlobals->p2Y < myPongGlobals->yMaxBoundry) { - - myPongGlobals->p2Y++; - //Trigger render flag - myPongGlobals->renderP2Flag = 1; - } - -}; - -//Physics for ball -void moveBall(struct pongGlobals *myPongGlobals) { - int jump = 1; - - //Don't move at all - if (myPongGlobals->flag)jump = 4; - - switch (myPongGlobals->direction) { - case 1: - myPongGlobals->ballX -= jump; //down left - myPongGlobals->ballY += jump; - break; - case 3: - myPongGlobals->ballX += jump; //down right - myPongGlobals->ballY += jump; - break; - case 2: - myPongGlobals->ballX += jump; //up right - myPongGlobals->ballY -= jump; - break; - case 0: - myPongGlobals->ballX -= jump; //up left - myPongGlobals->ballY -= jump; - break; - default: - break; - - } - - myPongGlobals->flag = 0; -}; - -//Checks for collsions -void checkCollision(struct pongGlobals *myPongGlobals) { - int old; - old = myPongGlobals->direction; - - if (myPongGlobals->ballY-myPongGlobals->ballY_size < myPongGlobals->yMinBoundry) { - myPongGlobals->direction ^= 1; - } - - /* - if (myPongGlobals->ballX < myPongGlobals->xMinBoundry) { - myPongGlobals->direction ^= 2; - } - - if (myPongGlobals->ballX > myPongGlobals->xMaxBoundry) { - myPongGlobals->direction ^= 2; - } - */ - - if (myPongGlobals->ballY > myPongGlobals->yMaxBoundry) { - myPongGlobals->direction ^= 1; - } - - //if (myPongGlobals->ballX < myPongGlobals->p1X+myPongGlobals->p1X_size+2) - { - //Check p1 collision - if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p1X, myPongGlobals->p1Y_old, myPongGlobals->p1X_size, myPongGlobals->p1Y_size) == 1) { - myPongGlobals->direction ^= 2; - } - else if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p1X, myPongGlobals->p1Y, myPongGlobals->p1X_size, myPongGlobals->p1Y_size) == 2) - { - myPongGlobals->direction ^= 1; - - } - } - //if (myPongGlobals->ballX+myPongGlobals->ballX_size > myPongGlobals->p2X-2) - { - //Check p2 collision - if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X_size, myPongGlobals->p2Y_size) == 1) { - myPongGlobals->direction ^= 2; - } - else if (collisionBox(myPongGlobals->ballX, myPongGlobals->ballY, myPongGlobals->ballX_size, myPongGlobals->ballY_size, myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X_size, myPongGlobals->p2Y_size) == 2) - { - myPongGlobals->direction ^= 1; - - } - } - if ((myPongGlobals->direction ^ old) != 0)myPongGlobals->flag = 1; - - if (myPongGlobals->ballX+myPongGlobals->ballX_size >= myPongGlobals->xMaxBoundry) - { - myPongGlobals->score1++; - checkWin(myPongGlobals); - } - - if (myPongGlobals->ballX <= myPongGlobals->xMinBoundry) - { - myPongGlobals->score2++; - checkWin(myPongGlobals); - } - -}; - -//Checks to see if we have meet the requirements for entering the win state -void checkWin(struct pongGlobals *myPongGlobals) { - if (myPongGlobals->score1 > myPongGlobals->scoreWin) { - myPongGlobals->score1 = 0; - myPongGlobals->renderWinFlag = 1; - myPongGlobals->winningPlayer = 1; - } - - if (myPongGlobals->score2 > myPongGlobals->scoreWin) { - myPongGlobals->score2 = 0; - myPongGlobals->renderWinFlag = 1; - myPongGlobals->winningPlayer = 2; - } - reset(myPongGlobals); - -}; - -//Render function for ball and updates player and balls new locations. -void renderBall(struct pongGlobals *myPongGlobals) { - drawFillRect(myPongGlobals->ballX_old, myPongGlobals->ballY_old - myPongGlobals->ballY_size, myPongGlobals->ballX_old + myPongGlobals->ballX_size, myPongGlobals->ballY_old, myPongGlobals->ballTrailColorR,myPongGlobals->ballTrailColorG,myPongGlobals->ballTrailColorB, 0); - drawFillRect(myPongGlobals->ballX, myPongGlobals->ballY - myPongGlobals->ballY_size, myPongGlobals->ballX + myPongGlobals->ballX_size, myPongGlobals->ballY, myPongGlobals->ballColorR, myPongGlobals->ballColorG, myPongGlobals->ballColorB, 0); -}; - -void render(struct pongGlobals *myPongGlobals) -{ - for (int ii = 0; ii < 2; ii++) - { - if (myPongGlobals->renderResetFlag) - { - renderReset(myPongGlobals); - } - if (myPongGlobals->renderScoreFlag) - { - renderScore(myPongGlobals); - } - - if (myPongGlobals->renderBallFlag) - { - renderBall(myPongGlobals); - } - - if (myPongGlobals->renderWinFlag) - { - renderWin(myPongGlobals); - } - - if (myPongGlobals->renderP1Flag) - { - renderP1(myPongGlobals); - } - - if (myPongGlobals->renderP2Flag) - { - renderP2(myPongGlobals); - } - flipBuffers(); - } - - resetRenderFlags(myPongGlobals); - - -} - -void resetRenderFlags(struct pongGlobals *myPongGlobals) -{ - myPongGlobals->renderResetFlag = 0; - myPongGlobals->renderBallFlag = 0; - myPongGlobals->renderWinFlag = 0; - myPongGlobals->renderP1Flag = 0; - myPongGlobals->renderP2Flag = 0; - myPongGlobals->renderScoreFlag=0; - -} - -void updatePosition(struct pongGlobals *myPongGlobals) -{ - myPongGlobals->p1X_old = myPongGlobals->p1X; - myPongGlobals->p1Y_old = myPongGlobals->p1Y; - myPongGlobals->p2X_old = myPongGlobals->p2X; - myPongGlobals->p2Y_old = myPongGlobals->p2Y; - myPongGlobals->ballX_old = myPongGlobals->ballX; - myPongGlobals->ballY_old = myPongGlobals->ballY; -} - -//Reset the game -void reset(struct pongGlobals *myPongGlobals) { - //Set global variables to default state - myPongGlobals->ballX = myPongGlobals->ballX_default; - myPongGlobals->ballY = myPongGlobals->ballY_default; - myPongGlobals->p1X = myPongGlobals->p1X_default; - myPongGlobals->p1Y = myPongGlobals->p1Y_default; - myPongGlobals->p1X_old = myPongGlobals->p1X; - myPongGlobals->p1Y_old = myPongGlobals->p1Y; - myPongGlobals->p2X = myPongGlobals->p2X_default; - myPongGlobals->p2Y = myPongGlobals->p2Y_default; - myPongGlobals->p2X_old = myPongGlobals->p2X; - myPongGlobals->p2Y_old = myPongGlobals->p2Y; - myPongGlobals->ballX_old = myPongGlobals->ballX; - myPongGlobals->ballY_old = myPongGlobals->ballY; - myPongGlobals->direction = (myPongGlobals->count & 3); - myPongGlobals->button = 0; - - //Set flag to render reset screen; - myPongGlobals->renderResetFlag = 1; - myPongGlobals->renderScoreFlag = 1; - -}; - -void renderScore(struct pongGlobals *myPongGlobals) -{ - char output1[255]; - __os_snprintf(output1, 255, "%d", myPongGlobals->score1); - drawString(myPongGlobals->score1X, myPongGlobals->score1Y, output1); - char output2[255]; - __os_snprintf(output2, 255, "%d", myPongGlobals->score2); - drawString(myPongGlobals->score2X, myPongGlobals->score2Y, output2); - -} - -void renderReset(struct pongGlobals *myPongGlobals) -{ - fillScreen(myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB,0); - renderInitialPlayers(myPongGlobals); -} - -//Sleeping function to kill time. Should probably update this to use tick. -void wait(int t) { - int i = 0; - int j = 0; - int z = 0; - - for (i = 0; i < t; i++) { - for (j = 0; j < t; j++) { - z = i / 33; - } - } - -}; - - -//Draws the win screen. -void renderWin(struct pongGlobals *myPongGlobals) { - if (myPongGlobals->winningPlayer == 1) { - char p1win[255]; - __os_snprintf(p1win, 255, "Player 1 Wins!"); - drawString(myPongGlobals->winX, myPongGlobals->winY, p1win); - } - if (myPongGlobals->winningPlayer == 2) { - char p2win[255]; - __os_snprintf(p2win, 255, "Player 2 Wins!"); - drawString(myPongGlobals->winX, myPongGlobals->winY, p2win); - } -}; - -//Draws the inital player paddles and ball. -void renderInitialPlayers(struct pongGlobals *myPongGlobals) { - drawFillRect(myPongGlobals->p1X_old, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - - drawFillRect(myPongGlobals->p2X_old, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - drawFillRect(myPongGlobals->ballX_old, myPongGlobals->ballY_old - myPongGlobals->ballY_size, myPongGlobals->ballX_old + myPongGlobals->ballX_size, myPongGlobals->ballY_old, myPongGlobals->ballColorR, myPongGlobals->ballColorG, myPongGlobals->ballColorB, 0); - - char credits[255]; - __os_snprintf(credits, 255, "Pong by Relys!"); - drawString(myPongGlobals->winX, myPongGlobals->winY+1, credits); -}; - -//Draws player1's paddle -void renderP1(struct pongGlobals *myPongGlobals) { - //move up - if (myPongGlobals->p1Y_old>myPongGlobals->p1Y) - { - drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - - drawLine(myPongGlobals->p1X, myPongGlobals->p1Y - myPongGlobals->p1Y_size, myPongGlobals->p1X + myPongGlobals->p1X_size, myPongGlobals->p1Y - myPongGlobals->p1Y_size, myPongGlobals->paddleColorR,myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - } - //Move down - if(myPongGlobals->p1Y_oldp1Y) - { - drawLine(myPongGlobals->p1X, myPongGlobals->p1Y, myPongGlobals->p1X + myPongGlobals->p1X_size, myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->p1X_old + myPongGlobals->p1X_size, myPongGlobals->p1Y_old - myPongGlobals->p1Y_size, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - } - - //Move right - if(myPongGlobals->p1X_oldp1X) - { - drawLine(myPongGlobals->p1X_old, myPongGlobals->p1Y_old-myPongGlobals->p1Y_size, myPongGlobals->p1X_old , myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - drawLine(myPongGlobals->p1X+myPongGlobals->p1X_size, myPongGlobals->p1Y-myPongGlobals->p1Y_size, myPongGlobals->p1X+myPongGlobals->p1X_size, myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - } - - //Move left - if(myPongGlobals->p1X_old>myPongGlobals->p1X) - { - drawLine(myPongGlobals->p1X, myPongGlobals->p1Y-myPongGlobals->p1Y_size, myPongGlobals->p1X , myPongGlobals->p1Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - drawLine(myPongGlobals->p1X_old+myPongGlobals->p1X_size, myPongGlobals->p1Y_old-myPongGlobals->p1Y_size, myPongGlobals->p1X_old+myPongGlobals->p1X_size, myPongGlobals->p1Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - } -} - -//Draws player2's paddle -void renderP2(struct pongGlobals *myPongGlobals) { - //move up - if (myPongGlobals->p2Y_old>myPongGlobals->p2Y) - { - drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - - drawLine(myPongGlobals->p2X, myPongGlobals->p2Y - myPongGlobals->p2Y_size, myPongGlobals->p2X + myPongGlobals->p2X_size, myPongGlobals->p2Y - myPongGlobals->p2Y_size, myPongGlobals->paddleColorR,myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - } - //Move down - if(myPongGlobals->p2Y_oldp2Y) - { - drawLine(myPongGlobals->p2X, myPongGlobals->p2Y, myPongGlobals->p2X + myPongGlobals->p2X_size, myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->p2X_old + myPongGlobals->p2X_size, myPongGlobals->p2Y_old - myPongGlobals->p2Y_size, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - } - - //Move right - if(myPongGlobals->p2X_oldp2X) - { - drawLine(myPongGlobals->p2X_old, myPongGlobals->p2Y_old-myPongGlobals->p2Y_size, myPongGlobals->p2X_old , myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - drawLine(myPongGlobals->p2X+myPongGlobals->p2X_size, myPongGlobals->p2Y-myPongGlobals->p2Y_size, myPongGlobals->p2X+myPongGlobals->p2X_size, myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - } - - //Move left - if(myPongGlobals->p2X_old>myPongGlobals->p2X) - { - drawLine(myPongGlobals->p2X, myPongGlobals->p2Y-myPongGlobals->p2Y_size, myPongGlobals->p2X , myPongGlobals->p2Y, myPongGlobals->paddleColorR, myPongGlobals->paddleColorG, myPongGlobals->paddleColorB, 0); - drawLine(myPongGlobals->p2X_old+myPongGlobals->p2X_size, myPongGlobals->p2Y_old-myPongGlobals->p2Y_size, myPongGlobals->p2X_old+myPongGlobals->p2X_size, myPongGlobals->p2Y_old, myPongGlobals->backgroundColorR, myPongGlobals->backgroundColorG, myPongGlobals->backgroundColorB, 0); - } - -} diff --git a/samples/pong/src/pong.h b/samples/pong/src/pong.h deleted file mode 100755 index 4d0138d..0000000 --- a/samples/pong/src/pong.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PONG_H -#define PONG_H -#include -#include -//Using modified version of draw to render at twice the scale to improve framerate -#include "draw.h" -//Struct for global variables for pong -struct pongGlobals{ - //Flag for restarting the entire game. - int restart; - - //Gameplay boundry - int xMinBoundry; - int xMaxBoundry; - int yMinBoundry; - int yMaxBoundry; - int scale; - int score1X; - int score2X; - int score1Y; - int score2Y; - int winX; - int winY; - - //Globals for ball location and movement dx/dy - int ballX; - int ballX_old; - int ballY; - int ballY_old; - int ballX_size; - int ballY_size; - - //Globals for player1 location and movement dx/dy - int p1X; - int p1X_old; - int p1Y; - int p1Y_old; - int p1X_size; - int p1Y_size; - - //Globals for player2 location and movement dx/dy - int p2X; - int p2X_old; - int p2Y; - int p2Y_old; - int p2X_size; - int p2Y_size; - - int p1X_default; - int p2X_default; - int ballX_default; - int p1Y_default; - int p2Y_default; - int ballY_default; - - //Game engine globals - int direction; - uint32_t button; - int paddleColorR; - int paddleColorG; - int paddleColorB; - int ballColorR; - int ballColorG; - int ballColorB; - int ballTrailColorR; - int ballTrailColorG; - int ballTrailColorB; - int backgroundColorR; - int backgroundColorG; - int backgroundColorB; - int count; - - int score1; - int score2; - int scoreWin; - - int flag; - - int winningPlayer; - - int renderP1Flag; - int renderP2Flag; - - int renderResetFlag; - int renderBallFlag; - int renderWinFlag; - int renderScoreFlag; -}; - -//Function declarations for pong functions. -void renderP2(struct pongGlobals *myPongGlobals); -void renderP1(struct pongGlobals *myPongGlobals); -void renderInitialPlayers(struct pongGlobals *myPongGlobals); -void renderWin(struct pongGlobals *myPongGlobals); -void wait(int t); -void renderReset(struct pongGlobals *myPongGlobals); -void renderScore(struct pongGlobals *myPongGlobals); -void reset(struct pongGlobals *myPongGlobals); -void updatePosition(struct pongGlobals *myPongGlobals); -void resetRenderFlags(struct pongGlobals *myPongGlobals); -void render(struct pongGlobals *myPongGlobals); -void renderBall(struct pongGlobals *myPongGlobals); -void checkWin(struct pongGlobals *myPongGlobals); -void checkCollision(struct pongGlobals *myPongGlobals); -void moveBall(struct pongGlobals *myPongGlobals); -void p2Move(struct pongGlobals *myPongGlobals); -void p1Move(struct pongGlobals *myPongGlobals); -int collisionBox(int box1x, int box1y, int width1, int height1, int box2x, int box2y, int width2, int height2); -#endif /* PONG_H */ diff --git a/samples/pong/src/program.c b/samples/pong/src/program.c deleted file mode 100755 index 0fa69d6..0000000 --- a/samples/pong/src/program.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "program.h" - -#include -#include -#include -#include -#include -#include -#include -#include "memory.h" - -char log_buf[0x400]; - -bool isAppRunning = true; -bool initialized = false; - -void screenInit() -{ - //Grab the buffer size for each screen (TV and gamepad) - int buf0_size = OSScreenGetBufferSizeEx(0); - int buf1_size = OSScreenGetBufferSizeEx(1); - __os_snprintf(log_buf, 0x400, "Screen sizes %x, %x\n", buf0_size, buf1_size); - OSReport(log_buf); - - //Set the buffer area. - screenBuffer = MEM1_alloc(buf0_size + buf1_size, 0x40); - __os_snprintf(log_buf, 0x400, "Allocated screen buffers at %x\n", screenBuffer); - OSReport(log_buf); - - OSScreenSetBufferEx(0, screenBuffer); - OSScreenSetBufferEx(1, (screenBuffer + buf0_size)); - OSReport("Set screen buffers\n"); - - OSScreenEnableEx(0, 1); - OSScreenEnableEx(1, 1); - - //Clear both framebuffers. - for (int ii = 0; ii < 2; ii++) - { - fillScreen(0,0,0,0); - flipBuffers(); - } -} - -void screenDeinit() -{ - for(int ii = 0; ii < 2; ii++) - { - fillScreen(0,0,0,0); - flipBuffers(); - } - - MEM1_free(screenBuffer); -} - -void SaveCallback() -{ - OSSavesDone_ReadyToRelease(); // Required -} - -bool AppRunning() -{ - if(!OSIsMainCore()) - { - ProcUISubProcessMessages(true); - } - else - { - ProcUIStatus status = ProcUIProcessMessages(true); - - if(status == PROCUI_STATUS_EXITING) - { - // Being closed, deinit things and prepare to exit - isAppRunning = false; - - if(initialized) - { - initialized = false; - screenDeinit(); - memoryRelease(); - } - - ProcUIShutdown(); - } - else if(status == PROCUI_STATUS_RELEASE_FOREGROUND) - { - // Free up MEM1 to next foreground app, etc. - initialized = false; - - screenDeinit(); - memoryRelease(); - ProcUIDrawDoneRelease(); - } - else if(status == PROCUI_STATUS_IN_FOREGROUND) - { - // Reallocate MEM1, reinit screen, etc. - if(!initialized) - { - initialized = true; - - memoryInitialize(); - screenInit(); - } - } - } - - return isAppRunning; -} - -int main(int argc, char **argv) -{ - OSScreenInit(); - OSReport("Screen initted\n"); - - ProcUIInit(&SaveCallback); - - /****************************> Globals <****************************/ - struct pongGlobals myPongGlobals; - //Flag for restarting the entire game. - myPongGlobals.restart = 1; - //scale of game - myPongGlobals.scale=1; - //Default locations for paddles and ball location and movement dx/dy - myPongGlobals.p1X_default=40*myPongGlobals.scale; - myPongGlobals.p2X_default=340*myPongGlobals.scale; - myPongGlobals.ballX_default=200*myPongGlobals.scale; - myPongGlobals.p1Y_default=150*myPongGlobals.scale; - myPongGlobals.p2Y_default=150*myPongGlobals.scale; - myPongGlobals.ballY_default=120*myPongGlobals.scale; - //Sizes of objects - myPongGlobals.p1X_size=20*myPongGlobals.scale; - myPongGlobals.p1Y_size=60*myPongGlobals.scale; - myPongGlobals.ballX_size=8*myPongGlobals.scale; - myPongGlobals.ballY_size=8*myPongGlobals.scale; - myPongGlobals.p2X_size=20*myPongGlobals.scale; - myPongGlobals.p2Y_size=60*myPongGlobals.scale; - //Boundry of play area (screen) - myPongGlobals.xMinBoundry=0*myPongGlobals.scale; - myPongGlobals.xMaxBoundry=400*myPongGlobals.scale; - myPongGlobals.yMinBoundry=0*myPongGlobals.scale; - myPongGlobals.yMaxBoundry=240*myPongGlobals.scale; - - myPongGlobals.winX=11*2*myPongGlobals.scale; - myPongGlobals.winY=5*2*myPongGlobals.scale; - myPongGlobals.score1X=13*2*myPongGlobals.scale; - myPongGlobals.score2X=15*2*myPongGlobals.scale; - myPongGlobals.score1Y=0*myPongGlobals.scale; - myPongGlobals.score2Y=0*myPongGlobals.scale; - //Game engine globals - myPongGlobals.direction = 1; - myPongGlobals.button = 0; - myPongGlobals.paddleColorR=0xFF; - myPongGlobals.paddleColorG=0x00; - myPongGlobals.paddleColorB=0x00; - myPongGlobals.ballColorR=0x00; - myPongGlobals.ballColorG=0xFF; - myPongGlobals.ballColorB=0x00; - myPongGlobals.ballTrailColorR=0x00; - myPongGlobals.ballTrailColorG=0x00; - myPongGlobals.ballTrailColorB=0xFF; - myPongGlobals.backgroundColorR=0x00; - myPongGlobals.backgroundColorG=0x00; - myPongGlobals.backgroundColorB=0x00; - myPongGlobals.count = 0; - //Keep track of score - myPongGlobals.score1 = 0; - myPongGlobals.score2 = 0; - myPongGlobals.scoreWin = 9; - //Game engine globals - myPongGlobals.direction = 1; - myPongGlobals.button = 0; - myPongGlobals.paddleColorR=0xFF; - myPongGlobals.paddleColorG=0x00; - myPongGlobals.paddleColorB=0x00; - myPongGlobals.ballColorR=0x00; - myPongGlobals.ballColorG=0xFF; - myPongGlobals.ballColorB=0x00; - myPongGlobals.ballTrailColorR=0x00; - myPongGlobals.ballTrailColorG=0x00; - myPongGlobals.ballTrailColorB=0xFF; - myPongGlobals.backgroundColorR=0x00; - myPongGlobals.backgroundColorG=0x00; - myPongGlobals.backgroundColorB=0x00; - myPongGlobals.count = 0; - //Keep track of score - myPongGlobals.score1 = 0; - myPongGlobals.scoreWin = 9; - //Used for collision - myPongGlobals.flag = 0; - - //Flag to determine if p1 should be rendered along with p1's movement direction - myPongGlobals.renderP1Flag = 0; - //Flags for render states - myPongGlobals.renderResetFlag = 0; - myPongGlobals.renderBallFlag = 0; - myPongGlobals.renderWinFlag = 0; - myPongGlobals.renderScoreFlag = 0; - OSReport("Globals initialized\n"); - - /****************************> VPAD Loop <****************************/ - int error; - VPADStatus vpad_data; - while (AppRunning()) - { - if(!initialized) continue; - - VPADRead(0, &vpad_data, 1, &error); - //Get the status of the gamepad - myPongGlobals.button = vpad_data.hold; - //If the game has been restarted, reset the game (we do this one time in the beginning to set everything up) - if (myPongGlobals.restart == 1) - { - OSReport("Game reset\n"); - reset(&myPongGlobals); - myPongGlobals.restart = 0; - } - //Set old positions. - updatePosition(&myPongGlobals); - - //Update location of player1 and 2 paddles - p1Move(&myPongGlobals); - p2Move(&myPongGlobals); - - //Update location of the ball - moveBall(&myPongGlobals); - //Check if their are any collisions between the ball and the paddles. - checkCollision(&myPongGlobals); - //Render the scene - myPongGlobals.renderBallFlag = 1; - render(&myPongGlobals); - - //Increment the counter (used for physicals calcuations) - myPongGlobals.count+=1; - } - - return 0; -} diff --git a/samples/pong/src/program.h b/samples/pong/src/program.h deleted file mode 100755 index e2cf2fa..0000000 --- a/samples/pong/src/program.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PROGRAM_H -#define PROGRAM_H - -//Using modified version of draw to render at twice the scale to improve framerate -#include "draw.h" - -#include "pong.h" - -void _entryPoint(); - -#endif /* PROGRAM_H */ diff --git a/share/wut.cmake b/share/wut.cmake new file mode 100644 index 0000000..27bdb61 --- /dev/null +++ b/share/wut.cmake @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.2) + +macro(wut_create_rpx target source) + add_custom_target(${target} ALL + COMMAND ${WUT_ELF2RPL} ${source} ${target} + DEPENDS ${source} + COMMENT "Converting to RPX ${target}" + ) + add_dependencies(${target} ${source}) +endmacro(wut_create_rpx) diff --git a/share/wut.ld b/share/wut.ld new file mode 100644 index 0000000..30479ac --- /dev/null +++ b/share/wut.ld @@ -0,0 +1,130 @@ +OUTPUT_FORMAT("elf32-powerpc") +OUTPUT_ARCH(powerpc:common) + +MEMORY { + relmem (rw) : ORIGIN = 0x00000000, LENGTH = 32M + codemem (rwx) : ORIGIN = 0x02000000, LENGTH = 224M + datamem (rw) : ORIGIN = 0x10000000, LENGTH = 800M + loadmem (rwx) : ORIGIN = 0xC0000000, LENGTH = 128M +} + +EXTERN(main) +ENTRY(main) + +SECTIONS +{ + . = ORIGIN(codemem); + .syscall ALIGN(32) : { + *(.syscall .syscall.*) + } > codemem + + .text ALIGN(32) : { + *(.text .text.*) + *(.init) + *(.fini) + } > codemem + + . = ORIGIN(datamem); + .rodata ALIGN(32) : { + *(.rodata .rodata.*) + *(.ctors) + *(.dtors) + *(.init_array) + *(.fini_array) + *(.jcr) + *(.gcc_except_table .gcc_except_table.*) + *(.eh_frame_hdr) + *(.eh_frame) + *(.got) + *(.got1) + *(.got2) + *(.tm_clone_table) + } > datamem + + .data ALIGN(32) : { + *(.data .data.*) + + . = ALIGN(32); + __sdata_start = .; + *(.sdata .sdata.*) + __sdata_end = .; + + . = ALIGN(32); + __sdata2_start = .; + *(.sdata2 .sdata2.*) + __sdata2_end = .; + } > datamem + + __bss_start = .; + .bss ALIGN(64) : { + *(.bss .bss.*) + + . = ALIGN(64); + __sbss_start = .; + *(.sbss .sbss.*) + __sbss_end = .; + + . = ALIGN(64); + __sbss2_start = .; + *(.sbss2 .sbss2.*) + __sbss2_end = .; + } + __bss_end = .; + + . = ORIGIN(relmem); + .rela.text ALIGN(4) : { + *(.rela.text .rela.text.*) + *(.rela.init) + *(.rela.fini) + } > relmem + .rela.data ALIGN(4) : { + *(.rela.data .rela.data.*) + *(.rela.sdata) + *(.rela.sdata2) + *(.rela.init_array) + *(.rela.fini_array) + *(.rela.gcc_except_table .rela.gcc_except_table.*) + *(.rela.eh_frame) + *(.rela.got2) + } > relmem + .rela.rodata ALIGN(4) : { + *(.rela.rodata .rela.rodata.*) + } > relmem + + . = ORIGIN(loadmem); + .fimport_coreinit ALIGN(16) : { + *(.fimport_coreinit) + } > loadmem + .fimport_proc_ui ALIGN(16) : { + *(.fimport_proc_ui) + } > loadmem + .fimport_sysapp ALIGN(16) : { + *(.fimport_sysapp) + } > loadmem + + .symtab ALIGN(4) : { + *(.symtab) + } > loadmem + .strtab ALIGN(1) : { + *(.strtab) + } > loadmem + .shstrtab ALIGN(1) : { + *(.shstrtab) + } > loadmem + + __SDATA_START__ = __sdata_start; + __SBSS_END__ = __sbss_end; + + __SDATA2_START__ = __sdata2_start; + __SBSS2_END__ = __sbss2_end; + + _SDA_BASE_ = __sbss_end; + _SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2); + + /DISCARD/ : { + *(.comment) + *(.fixup) + *(.gnu.attributes) + *(.abs) + } +} diff --git a/share/wut.toolchain.cmake b/share/wut.toolchain.cmake new file mode 100644 index 0000000..a1cf6fb --- /dev/null +++ b/share/wut.toolchain.cmake @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.2) + +set(CMAKE_SYSTEM_PROCESSOR "ppc") +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) + +set(DEVKITPPC $ENV{DEVKITPPC} CACHE STRING "Path to devkitPPC install") +set(WUT_ROOT $ENV{WUT_ROOT} CACHE STRING "Path to wut install") + +if(NOT DEVKITPPC) + message(FATAL_ERROR "You must have defined DEVKITPPC before calling cmake.") +endif() + +if(NOT WUT_ROOT) + get_filename_component(WUT_ROOT ${CMAKE_CURRENT_LIST_DIR} DIRECTORY) +endif() + +set(CMAKE_ASM_COMPILER "${DEVKITPPC}/bin/powerpc-eabi-gcc" CACHE PATH "") +set(CMAKE_C_COMPILER "${DEVKITPPC}/bin/powerpc-eabi-gcc" CACHE PATH "") +set(CMAKE_CXX_COMPILER "${DEVKITPPC}/bin/powerpc-eabi-g++" CACHE PATH "") +set(CMAKE_LINKER "${DEVKITPPC}/bin/powerpc-eabi-ld" CACHE PATH "") +set(CMAKE_AR "${DEVKITPPC}/bin/powerpc-eabi-ar" CACHE PATH "") + +set(WUT_C_FLAGS "-mcpu=750 -meabi -mhard-float -Wl,-q \"-I${WUT_ROOT}/include\"") +set(CMAKE_C_FLAGS "${WUT_C_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS "${WUT_C_FLAGS}" CACHE STRING "") +set(CMAKE_ASM_FLAGS "${WUT_C_FLAGS}" CACHE STRING "") +set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc -T \"${WUT_ROOT}/share/wut.ld\" \"-L${WUT_ROOT}/lib\"" CACHE STRING "") + +# Setup root to exclude host system headers + libraries +set(CMAKE_FIND_ROOT_PATH "${DEVKITPPC}" "${WUT_ROOT}/bin" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Tools +set(WUT_ELF2RPL "${WUT_ROOT}/bin/wut-elf2rpl${CMAKE_EXECUTABLE_SUFFIX}" CACHE PATH "") + +# Flags +set(WUT TRUE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index a93a837..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,96 +0,0 @@ -externalproject_add(crt - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/crt" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -externalproject_add(crt-lite - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/crt-lite" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -externalproject_add(rpl - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/rpl" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -externalproject_add(libdefaultheap - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/libdefaultheap" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -externalproject_add(libgfd - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/libgfd" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -externalproject_add(libwhb - SOURCE_DIR "${CMAKE_SOURCE_DIR}/src/libwhb" - CMAKE_GENERATOR "Unix Makefiles" - INSTALL_DIR "${CMAKE_BINARY_DIR}/staging" - CMAKE_CACHE_ARGS - -DDEVKITPPC:string=${DEVKITPPC} - -DWUT_ROOT:string=${CMAKE_SOURCE_DIR} - -DCMAKE_INSTALL_PREFIX:string= - -DCMAKE_TOOLCHAIN_FILE:string=${CMAKE_SOURCE_DIR}/cmake/wut-toolchain.cmake) - -# We must force build because changes are not detected with ExternalProject... -externalproject_add_step(crt forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of crt" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) - -externalproject_add_step(crt-lite forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of crt-lite" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) - -externalproject_add_step(rpl forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of rpl" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) - -externalproject_add_step(libdefaultheap forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of libdefaultheap" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) - -externalproject_add_step(libgfd forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of libgfd" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) - -externalproject_add_step(libwhb forcebuild - COMMAND ${CMAKE_COMMAND} -E echo "Force build of libwhb" - DEPENDEES "configure" - DEPENDERS "build" - ALWAYS 1) diff --git a/src/crt-lite/CMakeLists.txt b/src/crt-lite/CMakeLists.txt deleted file mode 100644 index 9fa0432..0000000 --- a/src/crt-lite/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(wut-crt-lite) - -set_property(SOURCE crt0.S PROPERTY LANGUAGE C) - -add_library(crt-lite - crt0.S) -set_target_properties(crt-lite PROPERTIES - COMPILE_FLAGS "-fno-builtin -ffreestanding" - LINKER_FLAGS "-fPIC") -target_include_directories(crt-lite PRIVATE "../../include") - -install(TARGETS crt-lite ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") diff --git a/src/crt-lite/crt0.S b/src/crt-lite/crt0.S deleted file mode 100644 index 6570105..0000000 --- a/src/crt-lite/crt0.S +++ /dev/null @@ -1,15 +0,0 @@ -.extern main -.extern exit - -.global _start -_start: - bl main - b exit - -.global __wrap___eabi -__wrap___eabi: - blr - -.global __init -__init: - blr diff --git a/src/crt/CMakeLists.txt b/src/crt/CMakeLists.txt deleted file mode 100644 index dc803af..0000000 --- a/src/crt/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(wut-crt) - -set_property(SOURCE crt0.S PROPERTY LANGUAGE C) - -add_library(crt - crt0.S - fs_dev.c - newlib.c) -set_target_properties(crt PROPERTIES - COMPILE_FLAGS "-fno-builtin -ffreestanding" - LINKER_FLAGS "-fPIC") -target_include_directories(crt PRIVATE "../../include") - -install(TARGETS crt ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") diff --git a/src/crt/crt0.S b/src/crt/crt0.S deleted file mode 100644 index 92e64fb..0000000 --- a/src/crt/crt0.S +++ /dev/null @@ -1,27 +0,0 @@ -.extern main -.extern exit -.extern __init_wut_newlibc - -.global _start -_start: - stwu 1, -0x8(1) - stw 3, 0(1) - stw 4, 4(1) - bl __init_wut_newlibc - bl fsDevInit - lwz 3, 0(1) - lwz 4, 4(1) - bl main - stw 3, 0(1) - bl fsDevExit - lwz 3, 0(1) - addi 1, 1, 0x8 - b exit - -.global __wrap___eabi -__wrap___eabi: - blr - -.global __init -__init: - blr diff --git a/src/crt/fs_dev.c b/src/crt/fs_dev.c deleted file mode 100644 index 401c4af..0000000 --- a/src/crt/fs_dev.c +++ /dev/null @@ -1,1128 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int fs_translate_error(FSStatus error); - -static int fs_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode); -static int fs_close(struct _reent *r, void *fd); -static ssize_t fs_write(struct _reent *r, void *fd, const char *ptr, size_t len); -static ssize_t fs_write_safe(struct _reent *r, void *fd, const char *ptr, size_t len); -static ssize_t fs_read(struct _reent *r, void *fd, char *ptr, size_t len); -static off_t fs_seek(struct _reent *r, void *fd, off_t pos, int dir); -static int fs_fstat(struct _reent *r, void *fd, struct stat *st); -static int fs_stat(struct _reent *r, const char *file, struct stat *st); -static int fs_link(struct _reent *r, const char *existing, const char *newLink); -static int fs_unlink(struct _reent *r, const char *name); -static int fs_chdir(struct _reent *r, const char *name); -static int fs_rename(struct _reent *r, const char *oldName, const char *newName); -static int fs_mkdir(struct _reent *r, const char *path, int mode); -static DIR_ITER* fs_diropen(struct _reent *r, DIR_ITER *dirState, const char *path); -static int fs_dirreset(struct _reent *r, DIR_ITER *dirState); -static int fs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat); -static int fs_dirclose(struct _reent *r, DIR_ITER *dirState); -static int fs_statvfs(struct _reent *r, const char *path, struct statvfs *buf); -static int fs_ftruncate(struct _reent *r, void *fd, off_t len); -static int fs_fsync(struct _reent *r, void *fd); -static int fs_chmod(struct _reent *r, const char *path, mode_t mode); -static int fs_fchmod(struct _reent *r, void *fd, mode_t mode); -static int fs_rmdir(struct _reent *r, const char *name); - -/** - * Open file struct - */ -typedef struct -{ - //! FS handle - FSFileHandle fd; - - //! Flags used in open(2) - int flags; - - //! Current file offset - uint32_t offset; -} fs_file_t; - -// "wiiu" -#define FS_DIRITER_MAGIC 0x77696975 - -/** - * Open directory struct - */ -typedef struct -{ - //! Should be set to FS_DIRITER_MAGIC - u32 magic; - - //! FS handle - FSDirectoryHandle fd; - - //! Temporary storage for reading entries - FSDirectoryEntry entry_data; -} fs_dir_t; - -/** - * Wii U FS devoptab - */ -static devoptab_t -fs_devoptab = -{ - .name = "fs", - .structSize = sizeof(fs_file_t), - .open_r = fs_open, - .close_r = fs_close, - .write_r = fs_write_safe, - .read_r = fs_read, - .seek_r = fs_seek, - .fstat_r = fs_fstat, - .stat_r = fs_stat, - .link_r = fs_link, - .unlink_r = fs_unlink, - .chdir_r = fs_chdir, - .rename_r = fs_rename, - .mkdir_r = fs_mkdir, - .dirStateSize = sizeof(fs_dir_t), - .diropen_r = fs_diropen, - .dirreset_r = fs_dirreset, - .dirnext_r = fs_dirnext, - .dirclose_r = fs_dirclose, - .statvfs_r = fs_statvfs, - .ftruncate_r = fs_ftruncate, - .fsync_r = fs_fsync, - .deviceData = NULL, - .chmod_r = fs_chmod, - .fchmod_r = fs_fchmod, - //.rmdir_r = fs_rmdir, -}; - -FSClient * -fsClient = NULL; - -static bool fsInitialised = false; - -/* Initialize device */ -FSStatus -fsDevInit() -{ - FSStatus rc = 0; - - if (fsInitialised) { - return rc; - } - - fsClient = memalign(0x20, sizeof(FSClient)); - FSCmdBlock fsCmd; - FSMountSource mountSource; - char mountPath[0x80]; - char workDir[0x83]; - - FSInit(); - rc = FSAddClient(fsClient, -1); - - if (rc < 0) { - free(fsClient); - return rc; - } - - FSInitCmdBlock(&fsCmd); - - if (rc >= 0) { - int dev = AddDevice(&fs_devoptab); - - if(dev != -1) { - setDefaultDevice(dev); - fsInitialised = true; - - // Mount the SD card - rc = FSGetMountSource(fsClient, &fsCmd, FS_MOUNT_SOURCE_SD, &mountSource, -1); - - if (rc < 0) { - return rc; - } - - rc = FSMount(fsClient, &fsCmd, &mountSource, mountPath, 0x80, -1); - - if (rc >= 0) { - // chdir to SD root for general use - strcpy(workDir, "fs:"); - strcat(workDir, mountPath); - chdir(workDir); - } - } else { - FSDelClient(fsClient, -1); - free(fsClient); - return dev; - } - } - - return rc; -} - -static char* -fs_fixpath(struct _reent *r, - const char *path) -{ - char *p = strchr(path, ':')+1; - - if(!strchr(path, ':')) { - p = (char*)path; - } - - if (strlen(p) > PATH_MAX) { - r->_errno = ENAMETOOLONG; - return NULL; - } - - char *__fixedpath = memalign(0x40, PATH_MAX+1); - - if (__fixedpath == NULL) { - return NULL; - } - - // cwd is handled by coreinit, so just strip the 'fs:' if it exists - strcpy(__fixedpath, p); - - return __fixedpath; -} - -void -fsWriteSafe(bool enable) -{ - if (enable) { - fs_devoptab.write_r = fs_write_safe; - } else { - fs_devoptab.write_r = fs_write; - } -} - -FSStatus -fsDevExit() -{ - FSStatus rc = 0; - - if (!fsInitialised) { - return rc; - } - - FSDelClient(fsClient, -1); - free(fsClient); - return rc; -} - -static int -fs_open(struct _reent *r, - void *fileStruct, - const char *path, - int flags, - int mode) -{ - FSFileHandle fd; - FSStatus rc; - - if (path == NULL) { - return -1; - } - - char *path_fixed = fs_fixpath(r,path); - if (!path_fixed) { - r->_errno = ENOMEM; - return -1; - } - - // Get pointer to our data - fs_file_t *file = (fs_file_t*)fileStruct; - const char *fs_mode; - - // Map flags to open modes - if (flags == 0) { - fs_mode = "r"; - } else if (flags == 2) { - fs_mode = "r+"; - } else if (flags == 0x601) { - fs_mode = "w"; - } else if(flags == 0x602) { - fs_mode = "w+"; - } else if(flags == 0x209) { - fs_mode = "a"; - } else if(flags == 0x20A) { - fs_mode = "a+"; - } else { - free(path_fixed); - r->_errno = EINVAL; - return -1; - } - - // Set attributes - /* - if(!(mode & S_IWUSR)) { - attributes |= FS_ATTRIBUTE_READONLY; - } - */ - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // Open the file - rc = FSOpenFile(fsClient, &fsCmd, path_fixed, fs_mode, &fd, -1); - - if (rc >= 0) { - file->fd = fd; - file->flags = (flags & (O_ACCMODE|O_APPEND|O_SYNC)); - FSGetPosFile(fsClient, &fsCmd, fd, &file->offset, -1); - free(path_fixed); - return 0; - } - - free(path_fixed); - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_close(struct _reent *r, - void *fd) -{ - FSStatus rc; - fs_file_t *file = (fs_file_t*)fd; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSCloseFile(fsClient, &fsCmd, file->fd, -1); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static ssize_t -fs_write(struct _reent *r, - void *fd, - const char *ptr, - size_t len) -{ - FSStatus rc; - u32 bytes, bytesWritten = 0; - fs_file_t *file = (fs_file_t*)fd; - - // Check that the file was opened with write access - if ((file->flags & O_ACCMODE) == O_RDONLY) { - r->_errno = EBADF; - return -1; - } - - // Copy to internal buffer and write in chunks. - u8 *tmp_buffer = memalign(0x40, 8192); - - while(len > 0) { - size_t toWrite = len; - - if (toWrite > 8192) { - toWrite = 8192; - } - - // Copy to internal buffer - memcpy(tmp_buffer, ptr, toWrite); - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // Write the data - rc = FSWriteFile(fsClient, &fsCmd, tmp_buffer, 1, toWrite, file->fd, 0, -1); - - if(rc < 0) { - free(tmp_buffer); - - // Return partial transfer - if (bytesWritten > 0) { - return bytesWritten; - } - - r->_errno = fs_translate_error(rc); - return -1; - } else { - bytes = rc; - } - - file->offset += bytes; - bytesWritten += bytes; - ptr += bytes; - len -= bytes; - } - - free(tmp_buffer); - return bytesWritten; -} - -static ssize_t -fs_write_safe(struct _reent *r, - void *fd, - const char *ptr, - size_t len) -{ - FSStatus rc; - u32 bytes, bytesWritten = 0; - fs_file_t *file = (fs_file_t*)fd; - - // Check that the file was opened with write access - if ((file->flags & O_ACCMODE) == O_RDONLY) { - r->_errno = EBADF; - return -1; - } - - // Copy to internal buffer and write in chunks. - u8 *tmp_buffer = memalign(0x40, 8192); - - while(len > 0) { - size_t toWrite = len; - - if (toWrite > 8192) { - toWrite = 8192; - } - - // Copy to internal buffer - memcpy(tmp_buffer, ptr, toWrite); - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // Write the data - rc = FSWriteFile(fsClient, &fsCmd, tmp_buffer, 1, toWrite, file->fd, 0, -1); - - if (rc < 0) { - free(tmp_buffer); - - // Return partial transfer - if (bytesWritten > 0) { - return bytesWritten; - } - - r->_errno = fs_translate_error(rc); - return -1; - } else { - bytes = rc; - } - - file->offset += bytes; - bytesWritten += bytes; - ptr += bytes; - len -= bytes; - } - - free(tmp_buffer); - return bytesWritten; -} - -static ssize_t -fs_read(struct _reent *r, - void *fd, - char *ptr, - size_t len) -{ - FSStatus rc; - u32 bytes, bytesRead = 0; - fs_file_t *file = (fs_file_t*)fd; - - // Check that the file was opened with read access - if ((file->flags & O_ACCMODE) == O_WRONLY) { - r->_errno = EBADF; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - FSStat fsstat; - rc = FSGetStatFile(fsClient, &fsCmd, file->fd, &fsstat, -1); - - if(rc < 0) { - r->_errno = fs_translate_error(rc); - return -1; - } - - // Copy to internal buffer and read in chunks. - u8 *tmp_buffer = memalign(0x40, 8192); - - while(len > 0) { - size_t toRead = len; - - if (toRead > 8192) { - toRead = 8192; - } - - // Write the data - rc = FSReadFile(fsClient, &fsCmd, tmp_buffer, 1, toRead, file->fd, 0, -1); - - if(rc <= 0) - { - free(tmp_buffer); - - // Return partial transfer - if (bytesRead > 0) { - return bytesRead; - } - - r->_errno = fs_translate_error(rc); - return -1; - } else { - bytes = rc; - } - - // Copy to internal buffer - memcpy(ptr, tmp_buffer, bytes); - - file->offset += bytes; - bytesRead += bytes; - ptr += bytes; - len -= bytes; - } - - free(tmp_buffer); - return bytesRead; -} - -static off_t -fs_seek(struct _reent *r, - void *fd, - off_t pos, - int whence) -{ - FSStatus rc; - u64 offset; - fs_file_t *file = (fs_file_t*)fd; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - FSStat fsstat; - rc = FSGetStatFile(fsClient, &fsCmd, file->fd, &fsstat, -1); - - if (rc < 0) { - r->_errno = fs_translate_error(rc); - return -1; - } - - // Find the offset to see from - switch(whence) { - // Set absolute position; start offset is 0 - case SEEK_SET: - offset = 0; - break; - - // Set position relative to the current position - case SEEK_CUR: - offset = file->offset; - break; - - // Set position relative to the end of the file - case SEEK_END: - offset = fsstat.size; - break; - - // An invalid option was provided - default: - r->_errno = EINVAL; - return -1; - } - - // TODO: A better check that prevents overflow. - if(pos < 0 && offset < -pos) { - // Don't allow seek to before the beginning of the file - r->_errno = EINVAL; - return -1; - } - - // Update the current offset - file->offset = offset + pos; - FSStatus result = FSSetPosFile(fsClient, &fsCmd, file->fd, file->offset, -1); - - if (result < 0) { - return result; - } - - return file->offset; -} - -static int -fs_fstat(struct _reent *r, - void *fd, - struct stat *st) -{ - FSStatus rc; - FSStat fsstat; - fs_file_t *file = (fs_file_t*)fd; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSGetStatFile(fsClient, &fsCmd, file->fd, &fsstat, -1); - - if (rc >= 0) { - memset(st, 0, sizeof(struct stat)); - st->st_size = fsstat.size; - st->st_uid = fsstat.owner; - st->st_gid = fsstat.group; - st->st_nlink = 1; - st->st_mode = fsstat.mode; - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_stat(struct _reent *r, - const char *file, - struct stat *st) -{ - int fd; - FSStatus rc; - - if (file == NULL) { - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // First try open as file - rc = FSOpenFile(fsClient, &fsCmd, file, "r", (FSFileHandle*)&fd, -1); - - if (rc >= 0) { - fs_file_t tmpfd = { .fd = fd }; - rc = fs_fstat(r, &tmpfd, st); - FSCloseFile(fsClient, &fsCmd, fd, -1); - return rc; - } - - // File failed, so lets try open as directory - rc = FSOpenDir(fsClient, &fsCmd, file, (FSDirectoryHandle*)&fd, -1); - - if (rc >= 0) { - memset(st, 0, sizeof(struct stat)); - st->st_nlink = 1; - st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO; - FSCloseDir(fsClient, &fsCmd, fd, -1); - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_link(struct _reent *r, - const char *existing, - const char *newLink) -{ - r->_errno = ENOSYS; - return -1; -} - -static int -fs_unlink(struct _reent *r, - const char *name) -{ - FSStatus rc; - - if (name == NULL) { - return -1; - } - - char *path_fix = fs_fixpath(r, name); - - if (!path_fix) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSRemove(fsClient, &fsCmd, path_fix, -1); - free(path_fix); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_chdir(struct _reent *r, - const char *name) -{ - FSStatus rc; - - if (name == NULL) { - return -1; - } - - char *path = fs_fixpath(r, name); - - if (!path) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSChangeDir(fsClient, &fsCmd, path, -1); - free(path); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_rename(struct _reent *r, - const char *oldName, - const char *newName) -{ - FSStatus rc; - - if (oldName == NULL) { - return -1; - } - - if (newName == NULL) { - return -1; - } - - char *path_old = fs_fixpath(r, oldName); - - if (!path_old) { - r->_errno = ENOMEM; - return -1; - } - - char *path_new = fs_fixpath(r, newName); - - if (!path_new) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSRename(fsClient, &fsCmd, path_old, path_new, -1); - free(path_old); - free(path_new); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_mkdir(struct _reent *r, - const char *path, - int mode) -{ - FSError rc; - - if (path == NULL) { - return -1; - } - - char *path_fix = fs_fixpath(r, path); - - if (!path_fix) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // TODO: Use mode to set directory attributes. - rc = FSMakeDir(fsClient, &fsCmd, path_fix, -1); - free(path_fix); - - if (rc == FS_ERROR_ALREADY_EXISTS) { - r->_errno = EEXIST; - return -1; - } else if(rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static DIR_ITER* -fs_diropen(struct _reent *r, - DIR_ITER *dirState, - const char *path) -{ - FSDirectoryHandle fd; - FSStatus rc; - - if (path == NULL) { - return NULL; - } - - char *path_fixed = fs_fixpath(r,path); - - if (!path_fixed) { - r->_errno = ENOMEM; - return NULL; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - fs_dir_t *dir = (fs_dir_t*)(dirState->dirStruct); - rc = FSOpenDir(fsClient, &fsCmd, path_fixed, &fd, -1); - - if (rc >= 0) { - dir->magic = FS_DIRITER_MAGIC; - dir->fd = fd; - memset(&dir->entry_data, 0, sizeof(dir->entry_data)); - free(path_fixed); - return dirState; - } - - free(path_fixed); - r->_errno = fs_translate_error(rc); - return NULL; -} - -static int -fs_dirreset(struct _reent *r, - DIR_ITER *dirState) -{ - FSStatus rc; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - fs_dir_t *dir = (fs_dir_t*)(dirState->dirStruct); - rc = FSRewindDir(fsClient, &fsCmd, dir->fd, -1); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_dirnext(struct _reent *r, - DIR_ITER *dirState, - char *filename, - struct stat *filestat) -{ - FSStatus rc; - fs_dir_t *dir = (fs_dir_t*)(dirState->dirStruct); - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // Fetch the next dir - memset(&dir->entry_data, 0, sizeof(dir->entry_data)); - rc = FSReadDir(fsClient, &fsCmd, dir->fd, &dir->entry_data, -1); - - if (rc < 0) { - // There are no more entries; ENOENT signals end-of-directory - r->_errno = ENOENT; - return -1; - } - - if (rc >= 0) { - memset(filestat, 0, sizeof(struct stat)); - - // Fill in the stat info - filestat->st_ino = 0; - - if (dir->entry_data.info.flags & FS_STAT_DIRECTORY) { - filestat->st_mode = S_IFDIR; - } else { - filestat->st_mode = S_IFREG; - } - - filestat->st_uid = dir->entry_data.info.owner; - filestat->st_gid = dir->entry_data.info.group; - filestat->st_size = dir->entry_data.info.size; - - memset(filename, 0, NAME_MAX); - strcpy(filename, dir->entry_data.name); - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_dirclose(struct _reent *r, - DIR_ITER *dirState) -{ - FSStatus rc; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - fs_dir_t *dir = (fs_dir_t*)(dirState->dirStruct); - rc = FSCloseDir(fsClient, &fsCmd, dir->fd, -1); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_statvfs(struct _reent *r, - const char *path, - struct statvfs *buf) -{ - FSStatus rc; - bool writable = false; - char *path_fix = fs_fixpath(r, path); - - if (!path_fix) { - r->_errno = ENOMEM; - return -1; - } - - //TODO: FSGetFileSystemInfo - - free(path_fix); - r->_errno = ENOSYS; - return -1; -} - -static int -fs_ftruncate(struct _reent *r, - void *fd, - off_t len) -{ - FSStatus rc; - fs_file_t *file = (fs_file_t*)fd; - - // Make sure length is non-negative - if (len < 0) { - r->_errno = EINVAL; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - // Set the new file size - rc = FSSetPosFile(fsClient, &fsCmd, file->fd, len, -1); - - if (rc >= 0) { - return 0; - } - - rc = FSTruncateFile(fsClient, &fsCmd, file->fd, -1); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_fsync(struct _reent *r, - void *fd) -{ - FSStatus rc; - fs_file_t *file = (fs_file_t*)fd; - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSFlushFile(fsClient, &fsCmd, file->fd, -1); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_chmod(struct _reent *r, - const char *path, - mode_t mode) -{ - FSStatus rc; - char *path_fix = fs_fixpath(r, path); - - if (!path_fix) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSChangeMode(fsClient, &fsCmd, path_fix, (FSMode)mode, -1); - free(path_fix); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -static int -fs_fchmod(struct _reent *r, - void *fd, - mode_t mode) -{ - //TODO: FSChangeMode and FSStatFile? - - r->_errno = ENOSYS; - return -1; -} - -static int -fs_rmdir(struct _reent *r, - const char *name) -{ - FSStatus rc; - - if (name == NULL) { - return -1; - } - - char *path_fix = fs_fixpath(r, name); - - if (!path_fix) { - r->_errno = ENOMEM; - return -1; - } - - // Set up command block - FSCmdBlock fsCmd; - FSInitCmdBlock(&fsCmd); - - rc = FSRemove(fsClient, &fsCmd, path_fix, -1); - free(path_fix); - - if (rc >= 0) { - return 0; - } - - r->_errno = fs_translate_error(rc); - return -1; -} - -int -fs_getmtime(const char *name, - u64 *mtime) -{ - // TODO: Last modified time can probably be get via FSGetStatFile - return -1; -} - -// Error map -typedef struct -{ - //! Error from FS service - FSStatus fs_error; - - //! POSIX errno - int error; -} error_map_t; - -// Error table -static const error_map_t -error_table[] = -{ - // NOTE: Keep this list sorted! - { FS_STATUS_CANCELLED, EINVAL, }, - { FS_STATUS_EXISTS, EEXIST, }, - { FS_STATUS_NOT_FOUND, ENOENT, }, - { FS_STATUS_STORAGE_FULL, ENOSPC, }, - { FS_ERROR_INVALID_PATH, ENAMETOOLONG, }, -}; - -static const size_t -num_errors = sizeof(error_table)/sizeof(error_table[0]); - -static int -error_cmp(const void *p1, const void *p2) -{ - const error_map_t *lhs = (const error_map_t*)p1; - const error_map_t *rhs = (const error_map_t*)p2; - - if ((u32)lhs->fs_error < (u32)rhs->fs_error) { - return -1; - } else if((u32)lhs->fs_error > (u32)rhs->fs_error) { - return 1; - } - - return 0; -} - -static int -fs_translate_error(FSStatus error) -{ - error_map_t key = { .fs_error = error }; - const error_map_t *rc = bsearch(&key, error_table, num_errors, - sizeof(error_map_t), error_cmp); - - if (rc != NULL) { - return rc->error; - } - - return (int)error; -} diff --git a/src/crt/newlib.c b/src/crt/newlib.c deleted file mode 100644 index 5b12428..0000000 --- a/src/crt/newlib.c +++ /dev/null @@ -1,170 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static OSMutex sMallocMutex; -static uint8_t *sHeapBase = NULL; -static uint32_t sHeapMaxSize = 0; -static volatile uint32_t sHeapSize = 0; - -void -__init_wut_newlibc(); - -static void *__libwut_sbrk_r(struct _reent *r, - ptrdiff_t incr) -{ - uint32_t oldSize, newSize; - - do { - oldSize = sHeapSize; - newSize = oldSize + incr; - - if (newSize > sHeapMaxSize) { - r->_errno = ENOMEM; - return (void *)-1; - } - } while (!OSCompareAndSwapAtomic(&sHeapSize, oldSize, newSize)); - - return sHeapBase + oldSize; -} - -static int __libwut_lock_init(int *lock, - int recursive) -{ - OSMutex *mutex = NULL; - if (!lock) { - return -1; - } - - mutex = (OSMutex *)malloc(sizeof(OSMutex)); - if (!mutex) { - return -1; - } - - OSInitMutex(mutex); - *lock = (int)mutex; - return 0; -} - -static int __libwut_lock_close(int *lock) -{ - if (!lock || *lock == 0) { - return -1; - } - - free((void *)*lock); - *lock = 0; - return 0; -} - -static int __libwut_lock_acquire(int *lock) -{ - OSMutex *mutex = (OSMutex *)*lock; - if (!lock || *lock == 0) { - return -1; - } - - OSLockMutex(mutex); - return 0; -} - -static int __libwut_lock_release(int *lock) -{ - OSMutex *mutex = (OSMutex *)*lock; - if (!lock || *lock == 0) { - return -1; - } - - OSUnlockMutex(mutex); - return 0; -} - -static void __libwut_malloc_lock(struct _reent *r) -{ - OSLockMutex(&sMallocMutex); -} - -static void __libwut_malloc_unlock(struct _reent *r) -{ - OSUnlockMutex(&sMallocMutex); -} - -static void __libwut_exit(int code) -{ - exit(code); -} - -static int __libwut_gettod_r(struct _reent *ptr, struct timeval *tp, struct timezone *tz) -{ - OSCalendarTime tm; - OSTicksToCalendarTime(OSGetTime(), &tm); - - if (tp != NULL) { - tp->tv_sec = tm.tm_sec; - tp->tv_usec = tm.tm_usec + tm.tm_msec * 1000; - } - - if (tz != NULL) { - tz->tz_minuteswest = 0; - tz->tz_dsttime = 0; - } - - return 0; -} - -static void -__init_malloc_lock() -{ - OSInitMutex(&sMallocMutex); -} - -static void -__init_libc_heap() -{ - MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2); - uint32_t freeSize = MEMGetAllocatableSizeForExpHeapEx(heap, 0x1000); - - sHeapMaxSize = (uint32_t)(0.9f * (float)freeSize) & ~0xFFF; - sHeapBase = (uint8_t *)MEMAllocFromExpHeapEx(heap, sHeapMaxSize, 0x1000); - sHeapSize = 0; -} - -static void -__free_libc_heap() -{ - MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2); - MEMFreeToExpHeap(heap, sHeapBase); -} - -static void -__init_syscall_array() -{ - __syscalls.sbrk_r = __libwut_sbrk_r; - __syscalls.lock_init = __libwut_lock_init; - __syscalls.lock_close = __libwut_lock_close; - __syscalls.lock_acquire = __libwut_lock_acquire; - __syscalls.lock_release = __libwut_lock_release; - __syscalls.malloc_lock = __libwut_malloc_lock; - __syscalls.malloc_unlock = __libwut_malloc_unlock; - __syscalls.exit = __libwut_exit; - __syscalls.gettod_r = __libwut_gettod_r; -} - -void -__init_wut_newlibc() -{ - __init_libc_heap(); - __init_malloc_lock(); - __init_syscall_array(); -} diff --git a/src/libdefaultheap/CMakeLists.txt b/src/libdefaultheap/CMakeLists.txt deleted file mode 100644 index 3fb3a2c..0000000 --- a/src/libdefaultheap/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(libdefaultheap) - -file(GLOB_RECURSE SOURCE_FILES *.c) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_library(defaultheap STATIC ${SOURCE_FILES} ${HEADER_FILES}) - -target_include_directories(defaultheap PRIVATE "../../include") -target_include_directories(defaultheap PUBLIC "include") - -install(TARGETS defaultheap - ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/include" - FILES_MATCHING PATTERN "*.h*") diff --git a/src/libdefaultheap/include/defaultheap.h b/src/libdefaultheap/include/defaultheap.h deleted file mode 100644 index f4f0be1..0000000 --- a/src/libdefaultheap/include/defaultheap.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void * -MEMAllocFromDefaultHeap(uint32_t size); - -void * -MEMAllocFromDefaultHeapEx(uint32_t size, - int32_t alignment); - -void -MEMFreeToDefaultHeap(void *block); - -#ifdef __cplusplus -} -#endif diff --git a/src/libdefaultheap/src/defaultheap.c b/src/libdefaultheap/src/defaultheap.c deleted file mode 100644 index ef330d2..0000000 --- a/src/libdefaultheap/src/defaultheap.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "defaultheap.h" -#include - -typedef void *(*MEMAllocFromDefaultHeapFn)(uint32_t size); -typedef void *(*MEMAllocFromDefaultHeapExFn)(uint32_t size, int32_t alignment); -typedef void (*MEMFreeToDefaultHeapFn)(void *block); - -static OSDynLoadModule sCoreinitHandle = 0; -static MEMAllocFromDefaultHeapFn *MEMAllocFromDefaultHeapPtr = NULL; -static MEMAllocFromDefaultHeapExFn *MEMAllocFromDefaultHeapExPtr = NULL; -static MEMFreeToDefaultHeapFn *MEMFreeToDefaultHeapPtr = NULL; - -void * -MEMAllocFromDefaultHeap(uint32_t size) -{ - if (!sCoreinitHandle) { - if (OSDynLoad_Acquire("coreinit.rpl", &sCoreinitHandle)) { - return NULL; - } - } - - if (!MEMAllocFromDefaultHeapPtr) { - if (OSDynLoad_FindExport(sCoreinitHandle, - TRUE, - "MEMAllocFromDefaultHeap", - (void **)&MEMAllocFromDefaultHeapPtr)) { - return NULL; - } - } - - return (**MEMAllocFromDefaultHeapPtr)(size); -} - -void * -MEMAllocFromDefaultHeapEx(uint32_t size, - int32_t alignment) -{ - if (!sCoreinitHandle) { - if (OSDynLoad_Acquire("coreinit.rpl", &sCoreinitHandle)) { - return NULL; - } - } - - if (!MEMAllocFromDefaultHeapExPtr) { - if (OSDynLoad_FindExport(sCoreinitHandle, - TRUE, - "MEMAllocFromDefaultHeapEx", - (void **)&MEMAllocFromDefaultHeapExPtr)) { - return NULL; - } - } - - return (**MEMAllocFromDefaultHeapExPtr)(size, alignment); -} - -void -MEMFreeToDefaultHeap(void *block) -{ - if (!sCoreinitHandle) { - if (OSDynLoad_Acquire("coreinit.rpl", &sCoreinitHandle)) { - return; - } - } - - if (!MEMFreeToDefaultHeapPtr) { - if (OSDynLoad_FindExport(sCoreinitHandle, - TRUE, - "MEMFreeToDefaultHeap", - (void **)&MEMFreeToDefaultHeapPtr)) { - return; - } - } - - (**MEMFreeToDefaultHeapPtr)(block); -} diff --git a/src/libgfd/CMakeLists.txt b/src/libgfd/CMakeLists.txt deleted file mode 100644 index c255490..0000000 --- a/src/libgfd/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(libgfd) - -file(GLOB_RECURSE SOURCE_FILES *.c) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_library(gfd STATIC ${SOURCE_FILES} ${HEADER_FILES}) - -target_include_directories(gfd PRIVATE "../../include") -target_include_directories(gfd PUBLIC "include") - -install(TARGETS gfd - ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/include" - FILES_MATCHING PATTERN "*.h*") diff --git a/src/libgfd/include/gfd.h b/src/libgfd/include/gfd.h deleted file mode 100644 index b0758b2..0000000 --- a/src/libgfd/include/gfd.h +++ /dev/null @@ -1,207 +0,0 @@ -#pragma once -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct GFDHeader GFDHeader; -typedef struct GFDBlockHeader GFDBlockHeader; -typedef struct GFDRelocationHeader GFDRelocationHeader; - -#define GFD_HEADER_MAGIC (0x47667832) -#define GFD_BLOCK_HEADER_MAGIC (0x424C4B7B) -#define GFD_RELOCATION_HEADER_MAGIC (0x7D424C4B) - -#define GFD_FILE_VERSION_MAJOR (7) -#define GFD_FILE_VERSION_MINOR (1) -#define GFD_BLOCK_VERSION_MAJOR (1) - -#define GFD_PATCH_MASK (0xFFF00000) -#define GFD_PATCH_DATA (0xD0600000) -#define GFD_PATCH_TEXT (0xCA700000) - -typedef enum GFDBlockType -{ - GFD_BLOCK_END_OF_FILE = 1, - GFD_BLOCK_PADDING = 2, - GFD_BLOCK_VERTEX_SHADER_HEADER = 3, - GFD_BLOCK_VERTEX_SHADER_PROGRAM = 5, - GFD_BLOCK_PIXEL_SHADER_HEADER = 6, - GFD_BLOCK_PIXEL_SHADER_PROGRAM = 7, - GFD_BLOCK_GEOMETRY_SHADER_HEADER = 8, - GFD_BLOCK_GEOMETRY_SHADER_PROGRAM = 9, - GFD_BLOCK_GEOMETRY_SHADER_COPY_PROGRAM = 10, - GFD_BLOCK_TEXTURE_HEADER = 11, - GFD_BLOCK_TEXTURE_IMAGE = 12, - GFD_BLOCK_TEXTURE_MIPMAP = 13, - GFD_BLOCK_COMPUTE_SHADER_HEADER = 14, - GFD_BLOCK_COMPUTE_SHADER_PROGRAM = 15, -} GFDBlockType; - -struct GFDHeader -{ - uint32_t magic; - uint32_t headerSize; - uint32_t majorVersion; - uint32_t minorVersion; - uint32_t gpuVersion; - uint32_t align; - uint32_t unk1; - uint32_t unk2; -}; -CHECK_OFFSET(GFDHeader, 0x00, magic); -CHECK_OFFSET(GFDHeader, 0x04, headerSize); -CHECK_OFFSET(GFDHeader, 0x08, majorVersion); -CHECK_OFFSET(GFDHeader, 0x0C, minorVersion); -CHECK_OFFSET(GFDHeader, 0x10, gpuVersion); -CHECK_OFFSET(GFDHeader, 0x14, align); -CHECK_OFFSET(GFDHeader, 0x18, unk1); -CHECK_OFFSET(GFDHeader, 0x1C, unk2); -CHECK_SIZE(GFDHeader, 0x20); - -struct GFDBlockHeader -{ - uint32_t magic; - uint32_t headerSize; - uint32_t majorVersion; - uint32_t minorVersion; - GFDBlockType type; - uint32_t dataSize; - uint32_t id; - uint32_t index; -}; -CHECK_OFFSET(GFDBlockHeader, 0x00, magic); -CHECK_OFFSET(GFDBlockHeader, 0x04, headerSize); -CHECK_OFFSET(GFDBlockHeader, 0x08, majorVersion); -CHECK_OFFSET(GFDBlockHeader, 0x0C, minorVersion); -CHECK_OFFSET(GFDBlockHeader, 0x10, type); -CHECK_OFFSET(GFDBlockHeader, 0x14, dataSize); -CHECK_OFFSET(GFDBlockHeader, 0x18, id); -CHECK_OFFSET(GFDBlockHeader, 0x1C, index); -CHECK_SIZE(GFDHeader, 0x20); - -struct GFDRelocationHeader -{ - uint32_t magic; - uint32_t headerSize; - uint32_t unk1; - uint32_t dataSize; - uint32_t dataOffset; - uint32_t textSize; - uint32_t textOffset; - uint32_t patchBase; - uint32_t patchCount; - uint32_t patchOffset; -}; -CHECK_OFFSET(GFDRelocationHeader, 0x00, magic); -CHECK_OFFSET(GFDRelocationHeader, 0x04, headerSize); -CHECK_OFFSET(GFDRelocationHeader, 0x08, unk1); -CHECK_OFFSET(GFDRelocationHeader, 0x0C, dataSize); -CHECK_OFFSET(GFDRelocationHeader, 0x10, dataOffset); -CHECK_OFFSET(GFDRelocationHeader, 0x14, textSize); -CHECK_OFFSET(GFDRelocationHeader, 0x18, textOffset); -CHECK_OFFSET(GFDRelocationHeader, 0x1C, patchBase); -CHECK_OFFSET(GFDRelocationHeader, 0x20, patchCount); -CHECK_OFFSET(GFDRelocationHeader, 0x24, patchOffset); -CHECK_SIZE(GFDRelocationHeader, 0x28); - -char * -GFDGetLastErrorString(); - -uint32_t -GFDGetGeometryShaderCount(const void *file); - -uint32_t -GFDGetGeometryShaderHeaderSize(uint32_t index, - const void *file); - -uint32_t -GFDGetGeometryShaderProgramSize(uint32_t index, - const void *file); - -uint32_t -GFDGetGeometryShaderCopyProgramSize(uint32_t index, - const void *file); - -BOOL -GFDGetGeometryShader(GX2GeometryShader *shader, - void *program, - void *copyProgram, - uint32_t index, - const void *file); - -uint32_t -GFDGetPixelShaderCount(const void *file); - -uint32_t -GFDGetPixelShaderHeaderSize(uint32_t index, - const void *file); - -uint32_t -GFDGetPixelShaderProgramSize(uint32_t index, - const void *file); - -BOOL -GFDGetPixelShader(GX2PixelShader *shader, - void *program, - uint32_t index, - const void *file); - -uint32_t -GFDGetVertexShaderCount(const void *file); - -uint32_t -GFDGetVertexShaderHeaderSize(uint32_t index, - const void *file); - -uint32_t -GFDGetVertexShaderProgramSize(uint32_t index, - const void *file); - -BOOL -GFDGetVertexShader(GX2VertexShader *shader, - void *program, - uint32_t index, - const void *file); - -uint32_t -GFDGetTextureCount(const void *file); - -uint32_t -GFDGetTextureHeaderSize(uint32_t index, - const void *file); - -uint32_t -GFDGetTextureImageSize(uint32_t index, - const void *file); - -uint32_t -GFDGetTextureMipImageSize(uint32_t index, - const void *file); - -uint32_t -GFDGetTextureAlignmentSize(uint32_t index, - const void *file); - -BOOL -GFDGetTexture(GX2Texture *texture, - void *image, - void *mipmap, - uint32_t index, - const void *file); - -BOOL -GFDGetGX2RTexture(GX2Texture *texture, - uint32_t index, - const void *file); - -const GX2Texture * -GFDGetTexturePointer(uint32_t index, - const void *file); - -#ifdef __cplusplus -} -#endif diff --git a/src/libgfd/src/gfd.c b/src/libgfd/src/gfd.c deleted file mode 100644 index a934f83..0000000 --- a/src/libgfd/src/gfd.c +++ /dev/null @@ -1,880 +0,0 @@ -#include "gfd.h" - -#include -#include -#include -#include -#include - -// #define CHECK_GPU_VERSION - -static uint32_t _GFDCleanTag(uint32_t tag); -static BOOL _GFDCheckTagDAT(uint32_t tag); -static BOOL _GFDCheckTagSTR(uint32_t tag); -static BOOL _GFDRelocateBlock(const GFDBlockHeader *blockHeader, void *dst); -static BOOL _GFDRelocateBlockEx(const GFDRelocationHeader *relocationHeader, const uint32_t *patchTable, uint8_t *dst); -static uint32_t _GFDGetBlockDataSize(GFDBlockType type, uint32_t index, const void *file); -static uint32_t _GFDGetBlockCount(GFDBlockType type, const void *file); -static BOOL _GFDCheckBlockHeaderMagicVersions(const GFDBlockHeader *header); -static BOOL _GFDCheckHeaderVersions(const void *file); -static BOOL _GFDGetHeaderVersions(uint32_t *majorVersion, uint32_t *minorVersion, uint32_t *gpuVersion, const void *file); -static BOOL _GFDGetBlockPointer(GFDBlockType type, uint32_t index, void *file, GFDBlockHeader **blockHeaderOut, void **blockDataOut); -static BOOL _GFDGetBlockPointerConst(GFDBlockType type, uint32_t index, const void *file, const GFDBlockHeader **blockHeaderOut, const void **blockDataOut); - -static char -sLastError[1024] = { 0 }; - -static void -setLastError(const char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - vsnprintf(sLastError, 1024, fmt, va); - va_end(va); -} - -char * -GFDGetLastErrorString() -{ - return sLastError; -} - -static BOOL -_GFDGetHeaderVersions(uint32_t *majorVersion, - uint32_t *minorVersion, - uint32_t *gpuVersion, - const void *file) -{ - GFDHeader *header = (GFDHeader *)file; - *majorVersion = 0; - *minorVersion = 0; - *gpuVersion = 0; - - if (header->magic != GFD_HEADER_MAGIC) { - setLastError("%s: header->magic %08X != %08X GFD_HEADER_MAGIC", __FUNCTION__, header->magic, GFD_HEADER_MAGIC); - return FALSE; - } - - *majorVersion = header->majorVersion; - *minorVersion = header->minorVersion; - *gpuVersion = header->gpuVersion; - return TRUE; -} - -static BOOL -_GFDCheckHeaderVersions(const void *file) -{ - uint32_t majorVersion, minorVersion, gpuVersion; - - if (!_GFDGetHeaderVersions(&majorVersion, &minorVersion, &gpuVersion, file)) { - return FALSE; - } - - if (majorVersion != GFD_FILE_VERSION_MAJOR) { - setLastError("%s: majorVersion %d != %d GFD_FILE_VERSION_MAJOR", __FUNCTION__, majorVersion, GFD_FILE_VERSION_MAJOR); - return FALSE; - } - - if (minorVersion != GFD_FILE_VERSION_MINOR) { - setLastError("%s: minorVersion %d != %d GFD_FILE_VERSION_MINOR", __FUNCTION__, minorVersion, GFD_FILE_VERSION_MINOR); - return FALSE; - } - -#ifdef CHECK_GPU_VERSION - if (gpuVersion != GX2TempGetGPUVersion()) { - setLastError("%s: gpuVersion %d != %d GX2TempGetGPUVersion()", __FUNCTION__, gpuVersion, GX2TempGetGPUVersion()); - return FALSE; - } -#endif - - return TRUE; -} - -static BOOL -_GFDCheckBlockHeaderMagicVersions(const GFDBlockHeader *header) -{ - if (header->magic != GFD_BLOCK_HEADER_MAGIC) { - setLastError("%s: header->magic %08X != GFD_BLOCK_HEADER_MAGIC", __FUNCTION__, header->magic); - return FALSE; - } - - if (header->majorVersion != GFD_BLOCK_VERSION_MAJOR) { - setLastError("%s: header->majorVersion %d != GFD_BLOCK_VERSION_MAJOR", __FUNCTION__, header->majorVersion); - return FALSE; - } - - return TRUE; -} - -static uint32_t -_GFDGetBlockCount(GFDBlockType type, - const void *file) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t count = 0; - - if (!file) { - return 0; - } - - if (!_GFDCheckHeaderVersions(file)) { - return 0; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - if (blockHeader->type == type) { - count++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - ptr += blockHeader->headerSize + blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - return count; -} - -static uint32_t -_GFDGetBlockDataSize(GFDBlockType type, - uint32_t index, - const void *file) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t count = 0; - - if (!file) { - return 0; - } - - if (!_GFDCheckHeaderVersions(file)) { - return 0; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - if (blockHeader->type == type) { - if (count == index) { - return blockHeader->dataSize; - } - - count++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - ptr += blockHeader->headerSize + blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - return 0; -} - -static BOOL -_GFDGetBlockPointerConst(GFDBlockType type, - uint32_t index, - const void *file, - const GFDBlockHeader **blockHeaderOut, - const void **blockDataOut) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t count = 0; - - if (!file) { - return FALSE; - } - - if (!_GFDCheckHeaderVersions(file)) { - return FALSE; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - if (blockHeader->type == type) { - if (count == index) { - *blockHeaderOut = blockHeader; - *blockDataOut = ptr + blockHeader->headerSize; - return TRUE; - } - - count++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - ptr += blockHeader->headerSize + blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - return FALSE; -} - -static BOOL -_GFDGetBlockPointer(GFDBlockType type, - uint32_t index, - void *file, - GFDBlockHeader **blockHeaderOut, - void **blockDataOut) -{ - uint8_t *ptr = (uint8_t *)file; - GFDHeader *fileHeader = (GFDHeader *)file; - GFDBlockHeader *blockHeader; - uint32_t count = 0; - - if (!file) { - return FALSE; - } - - if (!_GFDCheckHeaderVersions(file)) { - return FALSE; - } - - ptr += fileHeader->headerSize; - blockHeader = (GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - if (blockHeader->type == type) { - if (count == index) { - *blockHeaderOut = blockHeader; - *blockDataOut = ptr + blockHeader->headerSize; - - if (type == GFD_BLOCK_VERTEX_SHADER_HEADER - || type == GFD_BLOCK_PIXEL_SHADER_HEADER - || type == GFD_BLOCK_GEOMETRY_SHADER_HEADER - || type == GFD_BLOCK_COMPUTE_SHADER_HEADER) { - _GFDRelocateBlock(blockHeader, blockHeader); - } - - return TRUE; - } - - count++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - ptr += blockHeader->headerSize + blockHeader->dataSize; - blockHeader = (GFDBlockHeader *)ptr; - } - - return FALSE; -} - -static uint32_t -_GFDCleanTag(uint32_t tag) -{ - return tag & ~GFD_PATCH_MASK; -} - -static BOOL -_GFDCheckTagDAT(uint32_t tag) -{ - return (tag & GFD_PATCH_MASK) == GFD_PATCH_DATA; -} - -static BOOL -_GFDCheckTagSTR(uint32_t tag) -{ - return (tag & GFD_PATCH_MASK) == GFD_PATCH_TEXT; -} - -// This method differs from the official because they made poor design decisions. -static BOOL -_GFDRelocateBlockEx(const GFDRelocationHeader *relocationHeader, - const uint32_t *patchTable, - uint8_t *dst) -{ - uint32_t patchOffset = _GFDCleanTag(relocationHeader->patchOffset); - uint32_t i; - - for (i = 0; i < relocationHeader->patchCount; ++i) { - uint32_t *target; - uint32_t offset = patchTable[i]; - - if (offset == 0) { - continue; - } - - if (!_GFDCheckTagDAT(offset) && !_GFDCheckTagSTR(offset)) { - setLastError("%s: !_GFDCheckTagDAT(offset = %08X) && !_GFDCheckTagSTR(offset = %08X)", __FUNCTION__, offset, offset); - return FALSE; - } - - target = (uint32_t *)(dst + _GFDCleanTag(offset)); - - if (!_GFDCheckTagDAT(*target) && !_GFDCheckTagSTR(*target)) { - setLastError("%s: !_GFDCheckTagDAT(*target = %08X) && !_GFDCheckTagSTR(*target = %08X)", __FUNCTION__, *target, *target); - return FALSE; - } - - *target = (uintptr_t)(dst + _GFDCleanTag(*target)); - } - - return TRUE; -} - -static BOOL -_GFDRelocateBlock(const GFDBlockHeader *blockHeader, - void *dst) -{ - const uint8_t *blockData = ((const uint8_t *)blockHeader) + blockHeader->headerSize; - const GFDRelocationHeader *relocationHeader; - const uint32_t *patchTable; - - if (!blockHeader || !dst) { - return FALSE; - } - - relocationHeader = (const GFDRelocationHeader *)(blockData - + blockHeader->dataSize - - sizeof(GFDRelocationHeader)); - - if (relocationHeader->magic != GFD_RELOCATION_HEADER_MAGIC) { - setLastError("%s: relocationHeader->magic %08X != GFD_RELOCATION_HEADER_MAGIC", __FUNCTION__, relocationHeader->magic); - return FALSE; - } - - if (!_GFDCheckTagDAT(relocationHeader->patchOffset)) { - setLastError("%s: !_GFDCheckTagDAT(relocationHeader->patchOffset = %08X)", __FUNCTION__, relocationHeader->patchOffset); - return FALSE; - } - - patchTable = (const uint32_t *)(blockData + _GFDCleanTag(relocationHeader->patchOffset)); - return _GFDRelocateBlockEx(relocationHeader, patchTable, (uint8_t *)dst); -} - -static BOOL -_GFDCheckShaderAlign(void *program) -{ - return (((uintptr_t)program) & (GX2_SHADER_PROGRAM_ALIGNMENT - 1)) == 0; -} - -static BOOL -_GFDGetGenericBlock(GFDBlockType blockTypeHeader, - void *header, - GFDBlockType blockTypeProgram1, - void **outProgramPtr1, - void *program1, - GFDBlockType blockTypeProgram2, - void **outProgramPtr2, - void *program2, - uint32_t index, - const void *file) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t headerCount = 0; - uint32_t program1Count = 0; - uint32_t program2Count = 0; - BOOL result = FALSE; - - if (!header || !file) { - return FALSE; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - ptr += blockHeader->headerSize; - - if (blockHeader->type == blockTypeHeader) { - if (headerCount == index) { - memcpy(header, ptr, blockHeader->dataSize); - - // Process relocations for all headers except a texture header. - if (blockTypeHeader != GFD_BLOCK_TEXTURE_HEADER) { - if (!_GFDRelocateBlock(blockHeader, header)) { - return FALSE; - } - } - } - - headerCount++; - } else if (blockHeader->type == blockTypeProgram1) { - if (program1Count == index) { - *outProgramPtr1 = program1; - memcpy(program1, ptr, blockHeader->dataSize); - } - - program1Count++; - } else if (program2 && blockHeader->type == blockTypeProgram2) { - if (program2Count == index) { - *outProgramPtr2 = program2; - memcpy(program2, ptr, blockHeader->dataSize); - } - - program2Count++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - if (headerCount > index && program1Count > index) { - if (!program2 || program2Count > index) { - result = TRUE; - break; - } - } - - ptr += blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - return result; -} -/* -BOOL -GFDGetVertexShader(GX2VertexShader *shader, - void *program, - uint32_t index, - const void *file) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t headerCount = 0; - uint32_t programCount = 0; - BOOL result = FALSE; - - if (!shader || !program || !file) { - return FALSE; - } - - if ((uintptr_t)program & (GX2_SHADER_PROGRAM_ALIGNMENT - 1)) { - return FALSE; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - ptr += blockHeader->headerSize; - - if (blockHeader->type == GFD_BLOCK_VERTEX_SHADER_HEADER) { - if (headerCount == index) { - if (blockHeader->dataSize < sizeof(GX2VertexShader)) { - return FALSE; - } - - memcpy(shader, ptr, sizeof(GX2VertexShader)); - - if (!_GFDRelocateBlock(blockHeader, shader)) { - return FALSE; - } - } - - headerCount++; - } else if (blockHeader->type == GFD_BLOCK_VERTEX_SHADER_PROGRAM) { - if (programCount == index) { - shader->program = program; - memcpy(program, ptr, blockHeader->dataSize); - } - - programCount++; - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - if (headerCount > index && programCount > index) { - result = TRUE; - break; - } - - ptr += blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - return result; -} -*/ - -uint32_t -GFDGetComputeShaderCount(const void *file) -{ - return _GFDGetBlockCount(GFD_BLOCK_COMPUTE_SHADER_HEADER, - file); -} - -uint32_t -GFDGetComputeShaderHeaderSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_COMPUTE_SHADER_HEADER, - index, - file); -} - -uint32_t -GFDGetComputeShaderProgramSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_COMPUTE_SHADER_PROGRAM, - index, - file); -} - -/* -BOOL -GFDGetComputeShader(GX2ComputeShader *shader, - void *program, - uint32_t index, - const void *file) -{ - return _GFDGetGenericBlock(GFD_BLOCK_COMPUTE_SHADER_HEADER, - shader, - GFD_BLOCK_COMPUTE_SHADER_PROGRAM, - &shader->program, - program, - 0, - NULL, - NULL, - index, - file); -} -*/ - -uint32_t -GFDGetGeometryShaderCount(const void *file) -{ - return _GFDGetBlockCount(GFD_BLOCK_GEOMETRY_SHADER_HEADER, - file); -} - -uint32_t -GFDGetGeometryShaderHeaderSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_GEOMETRY_SHADER_HEADER, - index, - file); -} - -uint32_t -GFDGetGeometryShaderProgramSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_GEOMETRY_SHADER_PROGRAM, - index, - file); -} - -uint32_t -GFDGetGeometryShaderCopyProgramSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_GEOMETRY_SHADER_COPY_PROGRAM, - index, - file); -} - -BOOL -GFDGetGeometryShader(GX2GeometryShader *shader, - void *program, - void *copyProgram, - uint32_t index, - const void *file) -{ - if (!_GFDCheckShaderAlign(program) || !_GFDCheckShaderAlign(copyProgram)) { - return FALSE; - } - - return _GFDGetGenericBlock(GFD_BLOCK_GEOMETRY_SHADER_HEADER, - shader, - GFD_BLOCK_GEOMETRY_SHADER_PROGRAM, - &shader->program, - program, - GFD_BLOCK_GEOMETRY_SHADER_COPY_PROGRAM, - &shader->vertexProgram, - copyProgram, - index, - file); -} - -uint32_t -GFDGetPixelShaderCount(const void *file) -{ - return _GFDGetBlockCount(GFD_BLOCK_PIXEL_SHADER_HEADER, - file); -} - -uint32_t -GFDGetPixelShaderHeaderSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_PIXEL_SHADER_HEADER, - index, - file); -} - -uint32_t -GFDGetPixelShaderProgramSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_PIXEL_SHADER_PROGRAM, - index, - file); -} - -BOOL -GFDGetPixelShader(GX2PixelShader *shader, - void *program, - uint32_t index, - const void *file) -{ - if (!_GFDCheckShaderAlign(program)) { - return FALSE; - } - - return _GFDGetGenericBlock(GFD_BLOCK_PIXEL_SHADER_HEADER, - shader, - GFD_BLOCK_PIXEL_SHADER_PROGRAM, - &shader->program, - program, - 0, - NULL, - NULL, - index, - file); -} - -uint32_t -GFDGetVertexShaderCount(const void *file) -{ - return _GFDGetBlockCount(GFD_BLOCK_VERTEX_SHADER_HEADER, - file); -} - -uint32_t -GFDGetVertexShaderHeaderSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_VERTEX_SHADER_HEADER, - index, - file); -} - -uint32_t -GFDGetVertexShaderProgramSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_VERTEX_SHADER_PROGRAM, - index, - file); -} - -BOOL -GFDGetVertexShader(GX2VertexShader *shader, - void *program, - uint32_t index, - const void *file) -{ - return _GFDGetGenericBlock(GFD_BLOCK_VERTEX_SHADER_HEADER, - shader, - GFD_BLOCK_VERTEX_SHADER_PROGRAM, - &shader->program, - program, - 0, - NULL, - NULL, - index, - file); -} - -uint32_t -GFDGetTextureCount(const void *file) -{ - return _GFDGetBlockCount(GFD_BLOCK_TEXTURE_HEADER, - file); -} - -uint32_t -GFDGetTextureHeaderSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_TEXTURE_HEADER, - index, - file); -} - -uint32_t -GFDGetTextureImageSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_TEXTURE_IMAGE, - index, - file); -} - -uint32_t -GFDGetTextureMipImageSize(uint32_t index, - const void *file) -{ - return _GFDGetBlockDataSize(GFD_BLOCK_TEXTURE_MIPMAP, - index, - file); -} - -uint32_t -GFDGetTextureAlignmentSize(uint32_t index, - const void *file) -{ - const GFDBlockHeader *blockHeader; - const GX2Texture *texture; - - if (!_GFDGetBlockPointerConst(GFD_BLOCK_TEXTURE_HEADER, - index, - file, - &blockHeader, - (const void **)&texture)) { - return 0; - } - - return texture->surface.alignment; -} - -BOOL -GFDGetTexture(GX2Texture *texture, - void *image, - void *mipmap, - uint32_t index, - const void *file) -{ - return _GFDGetGenericBlock(GFD_BLOCK_TEXTURE_HEADER, - texture, - GFD_BLOCK_TEXTURE_IMAGE, - &texture->surface.image, - image, - GFD_BLOCK_TEXTURE_MIPMAP, - &texture->surface.mipmaps, - mipmap, - index, - file); -} - -BOOL -GFDGetGX2RTexture(GX2Texture *texture, - uint32_t index, - const void *file) -{ - const uint8_t *ptr = (const uint8_t *)file; - const GFDHeader *fileHeader = (const GFDHeader *)file; - const GFDBlockHeader *blockHeader; - uint32_t headerCount = 0; - BOOL created = FALSE; - - if (!texture || !file) { - return FALSE; - } - - ptr += fileHeader->headerSize; - blockHeader = (const GFDBlockHeader *)ptr; - - while (_GFDCheckBlockHeaderMagicVersions(blockHeader)) { - ptr += blockHeader->headerSize; - - if (blockHeader->type == GFD_BLOCK_TEXTURE_HEADER) { - if (headerCount == index) { - if (blockHeader->dataSize < sizeof(GX2Texture)) { - goto error; - } - - memcpy(texture, ptr, sizeof(GX2Texture)); - - texture->surface.image = NULL; - texture->surface.mipmaps = NULL; - - GX2RCreateSurface(&texture->surface, - GX2R_RESOURCE_BIND_TEXTURE - | GX2R_RESOURCE_USAGE_CPU_WRITE - | GX2R_RESOURCE_USAGE_GPU_READ); - - created = TRUE; - } else if (created) { - break; - } - - headerCount++; - } else if (blockHeader->type == GFD_BLOCK_TEXTURE_IMAGE) { - if (created) { - void *image = GX2RLockSurfaceEx(&texture->surface, 0, 0); - if (!image) { - goto error; - } - - memcpy(image, ptr, blockHeader->dataSize); - GX2RUnlockSurfaceEx(&texture->surface, 0, - GX2R_RESOURCE_DISABLE_CPU_INVALIDATE - | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE); - } - } else if (blockHeader->type == GFD_BLOCK_TEXTURE_MIPMAP) { - if (created) { - void *mipmap = GX2RLockSurfaceEx(&texture->surface, -1, 0); - if (!mipmap) { - goto error; - } - - memcpy(mipmap, ptr, blockHeader->dataSize); - GX2RUnlockSurfaceEx(&texture->surface, -1, - GX2R_RESOURCE_DISABLE_CPU_INVALIDATE - | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE); - } - } else if (blockHeader->type == GFD_BLOCK_END_OF_FILE) { - break; - } - - ptr += blockHeader->dataSize; - blockHeader = (const GFDBlockHeader *)ptr; - } - - if (created && (texture->surface.image || texture->surface.mipmaps)) { - if (texture->surface.image) { - GX2RInvalidateSurface(&texture->surface, 0, 0); - } - - if (texture->surface.mipmaps) { - GX2RInvalidateSurface(&texture->surface, -1, 0); - } - - return TRUE; - } - -error: - GX2RDestroySurfaceEx(&texture->surface, 0); - return FALSE; -} - -const GX2Texture * -GFDGetTexturePointer(uint32_t index, - const void *file) -{ - const GFDBlockHeader *blockHeader; - const GX2Texture *texture; - - if (!_GFDGetBlockPointerConst(GFD_BLOCK_TEXTURE_HEADER, - index, - file, - &blockHeader, - (const void **)&texture)) { - return NULL; - } - - if (blockHeader->dataSize < sizeof(GX2Texture)) { - return NULL; - } - - return texture; -} diff --git a/src/libwhb/CMakeLists.txt b/src/libwhb/CMakeLists.txt deleted file mode 100644 index d89472f..0000000 --- a/src/libwhb/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(libwhb) - -file(GLOB_RECURSE SOURCE_FILES *.c) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_library(whb STATIC ${SOURCE_FILES} ${HEADER_FILES}) - -target_include_directories(whb PRIVATE "../../include") -target_include_directories(whb PRIVATE "../libdefaultheap/include") -target_include_directories(whb PRIVATE "../libgfd/include") -target_include_directories(whb PUBLIC "include") - -install(TARGETS whb - ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ - DESTINATION "${CMAKE_INSTALL_PREFIX}/include" - FILES_MATCHING PATTERN "*.h*") - diff --git a/src/libwhb/include/whb/align.h b/src/libwhb/include/whb/align.h deleted file mode 100644 index 221e33a..0000000 --- a/src/libwhb/include/whb/align.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_align Align - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define WHBAlignUp(val, align) ((val + align - 1) & ~(align - 1)) - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/commandserver.h b/src/libwhb/include/whb/commandserver.h deleted file mode 100644 index 59f5d3f..0000000 --- a/src/libwhb/include/whb/commandserver.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_commandserver Network Command Server - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define WHB_SERVER_BUFFER_SIZE 1024 - -BOOL -WHBCommandServerInit(); - -void -WHBCommandServerStop(); - -BOOL -WHBCommandServerListen(char * stringLocation); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/crash.h b/src/libwhb/include/whb/crash.h deleted file mode 100644 index dd255f9..0000000 --- a/src/libwhb/include/whb/crash.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_crash Crash Handler - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL -WHBInitCrashHandler(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/file.h b/src/libwhb/include/whb/file.h deleted file mode 100644 index 914ccd2..0000000 --- a/src/libwhb/include/whb/file.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_file Filesystem - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum WHBFileError -{ - WHB_FILE_OK = 0, - WHB_FILE_FATAL_ERROR = -1, -} WHBFileError; - -int32_t -WHBOpenFile(const char *path, - const char *mode); - -uint32_t -WHBGetFileSize(int32_t handle); - -uint32_t -WHBReadFile(int32_t handle, - void *buf, - uint32_t size, - uint32_t count); - -int32_t -WHBCloseFile(int32_t handle); - -char * -WHBReadWholeFile(const char *path, - uint32_t *outSize); - -void -WHBFreeWholeFile(char *file); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/gfx.h b/src/libwhb/include/whb/gfx.h deleted file mode 100644 index fba9597..0000000 --- a/src/libwhb/include/whb/gfx.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once -#include -#include -#include - -/** - * \defgroup whb_gfx Graphics - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct WHBGfxShaderGroup WHBGfxShaderGroup; - -struct WHBGfxShaderGroup -{ - GX2FetchShader fetchShader; - void *fetchShaderProgram; - GX2PixelShader *pixelShader; - GX2VertexShader *vertexShader; - uint32_t numAttributes; - GX2AttribStream attributes[16]; -}; - -BOOL -WHBGfxInit(); - -void -WHBGfxShutdown(); - -void -WHBGfxBeginRender(); - -void -WHBGfxFinishRender(); - -void -WHBGfxBeginRenderDRC(); - -void -WHBGfxFinishRenderDRC(); - -void -WHBGfxBeginRenderTV(); - -void -WHBGfxFinishRenderTV(); - -GX2PixelShader * -WHBGfxLoadGFDPixelShader(uint32_t index, - const void *file); - -BOOL -WHBGfxFreePixelShader(GX2PixelShader *shader); - -GX2VertexShader * -WHBGfxLoadGFDVertexShader(uint32_t index, - const void *file); - -BOOL -WHBGfxFreeVertexShader(GX2VertexShader *shader); - -BOOL -WHBGfxLoadGFDShaderGroup(WHBGfxShaderGroup *group, - uint32_t index, - const void *file); - -BOOL -WHBGfxInitShaderAttribute(WHBGfxShaderGroup *group, - const char *name, - uint32_t buffer, - uint32_t offset, - GX2AttribFormat format); - -BOOL -WHBGfxInitFetchShader(WHBGfxShaderGroup *group); - -BOOL -WHBGfxFreeShaderGroup(WHBGfxShaderGroup *group); - -GX2Texture * -WHBGfxLoadGFDTexture(uint32_t index, - const void *file); - -BOOL -WHBGfxFreeTexture(GX2Texture *texture); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/libmanager.h b/src/libwhb/include/whb/libmanager.h deleted file mode 100644 index d088997..0000000 --- a/src/libwhb/include/whb/libmanager.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -/** - * \defgroup whb_socketinit Socket Library Initialization Manager - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Socket Library (nsysnet.rpl) - */ - -void -WHBInitializeSocketLibrary(); - -void -WHBDeinitializeSocketLibrary(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/log.h b/src/libwhb/include/whb/log.h deleted file mode 100644 index f2c1964..0000000 --- a/src/libwhb/include/whb/log.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_log Logger - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*LogHandlerFn)(const char *msg); - -BOOL -WHBAddLogHandler(LogHandlerFn fn); - -BOOL -WHBRemoveLogHandler(LogHandlerFn fn); - -BOOL -WHBLogWrite(const char *str); - -BOOL -WHBLogPrint(const char *str); - -BOOL -WHBLogWritef(const char *fmt, ...); - -BOOL -WHBLogPrintf(const char *fmt, ...); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/log_cafe.h b/src/libwhb/include/whb/log_cafe.h deleted file mode 100644 index 023b5fe..0000000 --- a/src/libwhb/include/whb/log_cafe.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_log_cafe Cafe OS System Log Output - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL -WHBLogCafeInit(); - -BOOL -WHBLogCafeDeinit(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/log_udp.h b/src/libwhb/include/whb/log_udp.h deleted file mode 100644 index 00900c6..0000000 --- a/src/libwhb/include/whb/log_udp.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_log_udp UDP Log Output - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL -WHBLogUdpInit(); - -BOOL -WHBLogUdpDeinit(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/proc.h b/src/libwhb/include/whb/proc.h deleted file mode 100644 index b07cd57..0000000 --- a/src/libwhb/include/whb/proc.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_proc ProcUI Utilities - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -void -WHBProcInit(); - -void -WHBProcShutdown(); - -void -WHBProcStopRunning(); - -BOOL -WHBProcIsRunning(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/include/whb/sdcard.h b/src/libwhb/include/whb/sdcard.h deleted file mode 100644 index bee1a8c..0000000 --- a/src/libwhb/include/whb/sdcard.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include - -/** - * \defgroup whb_sdcard SDCard Access - * \ingroup whb - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL -WHBMountSdCard(); - -char * -WHBGetSdCardMountPath(); - -BOOL -WHBUnmountSdCard(); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/src/libwhb/src/commandserver.c b/src/libwhb/src/commandserver.c deleted file mode 100644 index a2c1831..0000000 --- a/src/libwhb/src/commandserver.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#define SERVER_PORT 4406 - -int -sSocket = -1; - -int -sClient = -1; - -struct sockaddr_in -sAddr; - -static inline void -closeSocket(const char * funcName) -{ - int ret = socketclose(sSocket); - if(ret < 0) { - WHBLogPrintf("%s: Error occurred closing socket: %d", funcName, socketlasterr()); - } - else { - sSocket = -1; - } -} - -static inline void -closeClient(const char * funcName) -{ - int ret = socketclose(sClient); - if(ret < 0) { - WHBLogPrintf("%s: Error occurred closing client socket: %d", funcName, socketlasterr()); - } - else { - sClient = -1; - } -} - -BOOL -WHBCommandServerInit() -{ - int ret = 0; - - if(sSocket >= 0) { - WHBLogPrintf("%s: Command server is already running.", __FUNCTION__); - return TRUE; - } - - WHBInitializeSocketLibrary(); - - sSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(sSocket < 0) { - WHBLogPrintf("%s: Error occurred while creating socket: %d", __FUNCTION__, socketlasterr()); - sSocket = -1; - return FALSE; - } - - memset(&sAddr, 0, sizeof(struct sockaddr_in)); - sAddr.sin_family = AF_INET; - sAddr.sin_port = htons(SERVER_PORT); - sAddr.sin_addr.s_addr = htonl(INADDR_ANY); - - ret = bind(sSocket, (struct sockaddr *)&sAddr, sizeof(struct sockaddr_in)); - if(ret < 0) { - WHBLogPrintf("%s: Error occurred while binding to socket: %d", __FUNCTION__, socketlasterr()); - closeSocket(__FUNCTION__); - return FALSE; - } - - ret = listen(sSocket, 3); - if(ret < 0) { - WHBLogPrintf("%s: Error occurred while setting socket to listen mode: %d", __FUNCTION__, socketlasterr()); - closeSocket(__FUNCTION__); - return FALSE; - } - - return TRUE; -} - -void -WHBCommandServerStop() -{ - if(sSocket < 0) { - WHBLogPrintf("%s: Socket is already closed.", __FUNCTION__); - return; - } - - if(sClient >= 0) { - closeClient(__FUNCTION__); - } - closeSocket(__FUNCTION__); - WHBDeinitializeSocketLibrary(); -} - -BOOL -WHBCommandServerListen(char * stringLocation) -{ - char buffer[WHB_SERVER_BUFFER_SIZE]; - memset(buffer, 0, WHB_SERVER_BUFFER_SIZE); - - int ret; - struct sockaddr_in sClientAddr; - socklen_t sClientAddrLen = sizeof(struct sockaddr_in); - - if(sSocket < 0) { - WHBLogPrintf("%s: Socket is not open. Please run WHBCommandServerInit() first.", __FUNCTION__); - return FALSE; - } - - if(sClient < 0) { - sClient = accept(sSocket, (struct sockaddr *)&sClientAddr, &sClientAddrLen); - if(sClient < 0) { - WHBLogPrintf("%s: Error occurred while accepting a client connection: %d", __FUNCTION__, socketlasterr()); - return FALSE; - } - } - - ret = recv(sClient, buffer, WHB_SERVER_BUFFER_SIZE, 0); - if(ret < 0) { - WHBLogPrintf("%s: Error occurred while receiving data from client: %d", __FUNCTION__, socketlasterr()); - closeClient(__FUNCTION__); - return FALSE; - } - if(ret == 0) { - WHBLogPrintf("%s: Remote socket was closed. Closing client connection...", __FUNCTION__); - closeClient(__FUNCTION__); - return FALSE; - } - - memcpy(stringLocation, buffer, WHB_SERVER_BUFFER_SIZE); - return TRUE; -} diff --git a/src/libwhb/src/crash.c b/src/libwhb/src/crash.c deleted file mode 100644 index 85f5b14..0000000 --- a/src/libwhb/src/crash.c +++ /dev/null @@ -1,258 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_DISASSEMBLY_SIZE (4096) -#define LOG_STACK_TRACE_SIZE (4096) -#define LOG_REGISTER_SIZE (4096) - -#define THREAD_STACK_SIZE (4096) - -static const char * -sCrashType = NULL; - -static char -sDisassemblyBuffer[LOG_DISASSEMBLY_SIZE]; - -static uint32_t -sDisassemblyLength = 0; - -static char -sStackTraceBuffer[LOG_STACK_TRACE_SIZE]; - -static uint32_t -sStackTraceLength = 0; - -static char -sRegistersBuffer[LOG_REGISTER_SIZE]; - -static uint32_t -sRegistersLength = 0; - -static uint8_t -sCrashThreadStack[THREAD_STACK_SIZE]; - -static OSThread __attribute__((aligned(8))) -sCrashThread; - -static int -crashReportThread(int argc, const char **argv) -{ - // Log crash dump - WHBLogPrint(sRegistersBuffer); - WHBLogPrint(sDisassemblyBuffer); - WHBLogPrint(sStackTraceBuffer); - - // TODO: Save crash dump to SD card? - return 0; -} - -static void -disassemblyPrintCallback(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - sDisassemblyLength += vsprintf(sDisassemblyBuffer + sDisassemblyLength, fmt, args); - sDisassemblyBuffer[sDisassemblyLength] = 0; - va_end(args); -} - -static void -getDisassembly(OSContext *context) -{ - sDisassemblyLength = 0; - sDisassemblyBuffer[0] = 0; - - if (context->srr0 > 16) { - DisassemblePPCRange((void *)(context->srr0 - 16), - (void *)(context->srr0 + 16), - disassemblyPrintCallback, - OSGetSymbolName, - DISASSEMBLE_PPC_FLAGS_NONE); - } -} - -static void -getStackTrace(OSContext *context) -{ - int i; - uint32_t *stackPtr; - char name[256]; - - sStackTraceLength = 0; - sStackTraceBuffer[0] = 0; - stackPtr = (uint32_t *)context->gpr[1]; - - sStackTraceLength += sprintf(sStackTraceBuffer + sStackTraceLength, "Address: Back Chain LR Save\n"); - - for (i = 0; i < 16; ++i) { - uint32_t addr; - - if (!stackPtr || (uintptr_t)stackPtr == 0x1 || (uintptr_t)stackPtr == 0xFFFFFFFF) { - break; - } - - sStackTraceLength += sprintf(sStackTraceBuffer + sStackTraceLength, "0x%08x: 0x%08x 0x%08x", stackPtr, stackPtr[0], stackPtr[1]); - - addr = OSGetSymbolName(stackPtr[1], name, sizeof(name)); - if (addr) { - sStackTraceLength += sprintf(sStackTraceBuffer + sStackTraceLength, " %s+0x%x", name, stackPtr[1] - addr); - } - - sStackTraceLength += sprintf(sStackTraceBuffer + sStackTraceLength, "\n"); - stackPtr = (uint32_t *)*stackPtr; - } - - sStackTraceBuffer[sStackTraceLength] = 0; -} - -static void -writeRegister(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - sRegistersLength += vsprintf(sRegistersBuffer + sRegistersLength, fmt, args); - sRegistersBuffer[sRegistersLength] = 0; - va_end(args); -} - -static void -getRegisters(OSContext *context) -{ - OSTime tbr = OSGetSystemTime(); - uint32_t addr; - char name[256]; - int i; - uint64_t *fpr, *psf; - - sRegistersLength = 0; - sRegistersBuffer[sRegistersLength] = 0; - - writeRegister("--Proc%d-Core%u--------- OSContext 0x%p --------------------\n\n", - OSGetUPID(), OSGetCoreId(), context); - writeRegister("tag1 = 0x%08X (expecting 0x%08X)\n", - (uint32_t)(context->tag >> 32), (uint32_t)(OS_CONTEXT_TAG >> 32)); - writeRegister("tag2 = 0x%08X (expecting 0x%08X)\n", - (uint32_t)(context->tag & 0xFFFFFFFF), (uint32_t)(OS_CONTEXT_TAG & 0xFFFFFFFF)); - writeRegister("TBR = 0x%08X_%08X\n", - (uint32_t)(tbr >> 32), (uint32_t)(tbr & 0xFFFFFFFF)); - writeRegister("CR = 0x%08X\n", context->cr); - writeRegister("CTR = 0x%08X\n", context->ctr); - - writeRegister("LR = 0x%08X", context->lr); - addr = OSGetSymbolName(context->lr, name, sizeof(name)); - if (addr) { - writeRegister(" %s+0x%X", name, context->lr - addr); - } - writeRegister("\n"); - - writeRegister("SRR0 = 0x%08X", context->srr0); - addr = OSGetSymbolName(context->srr0, name, sizeof(name)); - if (addr) { - writeRegister(" %s+0x%X", name, context->srr0 - addr); - } - writeRegister("\n"); - - writeRegister("SRR1 = 0x%08X\n", context->srr1); - writeRegister("state = 0x%04X\n", context->state); - - for (i = 0; i < 16; ++i) { - writeRegister("r%-2d = 0x%08x (%14d) r%-2d = 0x%08x (%14d)\n", - i, context->gpr[i], context->gpr[i], - i + 16, context->gpr[i + 16], context->gpr[i + 16]); - } - - writeRegister("\n--GQRs----------\n"); - for (i = 0; i < 4; ++i) { - writeRegister("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", - i, context->gqr[i], context->gqr[i], - i + 4, context->gqr[i + 4], context->gqr[i + 4]); - } - - writeRegister("\n--Per-core OSContext runtime ----\n"); - for (i = 0; i < 3; ++i) { - writeRegister("coretime[%d] = 0x%016llX ticks, %lld second(s) elapsed\n", - i, context->coretime[i], context->coretime[i] / OSOneSecond); - } - - writeRegister("\n--FPRs----------\n"); - fpr = (uint64_t *)context->fpr; - for (i = 0; i < 16; ++i) { - writeRegister("fr%d \t= 0x%16.16llx \t fr%d \t= 0x%16.16llx\n", - i, fpr[i], - i + 16, fpr[i + 16]); - } - - writeRegister("\n\n--PSFs----------\n"); - psf = (uint64_t *)context->psf; - for (i = 0; i < 16; ++i) { - writeRegister("ps%d \t= 0x%16.16llx \t ps%d \t= 0x%16.16llx\n", - i, psf[i], - i + 16, psf[i + 16]); - } -} - -static BOOL -handleException(const char *type, - OSContext *context) -{ - sCrashType = type; - getDisassembly(context); - getStackTrace(context); - getRegisters(context); - - OSCreateThread(&sCrashThread, - crashReportThread, - 0, - NULL, - sCrashThreadStack + THREAD_STACK_SIZE, - THREAD_STACK_SIZE, - 16, - 0); - - OSResumeThread(&sCrashThread); - OSSuspendThread((OSThread *)context); - return TRUE; -} - -static BOOL -handleAlignment(OSContext *context) -{ - return handleException("ALIGNMENT", context); -} - -static BOOL -handleDSI(OSContext *context) -{ - return handleException("DSI", context); -} - -static BOOL -handleISI(OSContext *context) -{ - return handleException("ISI", context); -} - -static BOOL -handleProgram(OSContext *context) -{ - return handleException("PROGRAM", context); -} - -BOOL -WHBInitCrashHandler() -{ - OSSetExceptionCallback(OS_EXCEPTION_TYPE_ALIGNMENT, handleAlignment); - OSSetExceptionCallback(OS_EXCEPTION_TYPE_DSI, handleDSI); - OSSetExceptionCallback(OS_EXCEPTION_TYPE_ISI, handleISI); - OSSetExceptionCallback(OS_EXCEPTION_TYPE_PROGRAM, handleProgram); - return TRUE; -} diff --git a/src/libwhb/src/file.c b/src/libwhb/src/file.c deleted file mode 100644 index d02926d..0000000 --- a/src/libwhb/src/file.c +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include -#include -#include -#include - -static BOOL -sInitialised = FALSE; - -static FSClient -sClient; - -static BOOL -InitFileSystem() -{ - if (!sInitialised) { - FSInit(); - - if (FSAddClient(&sClient, -1) != FS_STATUS_OK) { - return FALSE; - } - - sInitialised = TRUE; - } - - return TRUE; -} - -int32_t -WHBOpenFile(const char *path, - const char *mode) -{ - FSCmdBlock cmd; - FSStatus result; - FSFileHandle handle; - char tmp[256]; - tmp[0] = 0; - - if (!InitFileSystem()) { - return WHB_FILE_FATAL_ERROR; - } - - if (path[0] != '/') { - strcat(tmp, "/vol/content/"); - strcat(tmp, path); - } else { - strcat(tmp, path); - } - - FSInitCmdBlock(&cmd); - result = FSOpenFile(&sClient, &cmd, tmp, mode, &handle, -1); - if (result < 0) { - WHBLogPrintf("%s: FSOpenFile error %d", __FUNCTION__, result); - return WHB_FILE_FATAL_ERROR; - } - - return (int32_t)handle; -} - -uint32_t -WHBGetFileSize(int32_t handle) -{ - FSCmdBlock cmd; - FSStatus result; - FSStat stat; - FSInitCmdBlock(&cmd); - result = FSGetStatFile(&sClient, &cmd, (FSFileHandle)handle, &stat, -1); - if (result < 0) { - WHBLogPrintf("%s: FSGetStatFile error %d", __FUNCTION__, result); - return 0; - } - - return stat.size; -} - -uint32_t -WHBReadFile(int32_t handle, - void *buf, - uint32_t size, - uint32_t count) -{ - FSCmdBlock cmd; - FSStatus result; - FSInitCmdBlock(&cmd); - result = FSReadFile(&sClient, &cmd, buf, size, count, (FSFileHandle)handle, 0, -1); - if (result < 0) { - WHBLogPrintf("%s: FSReadFile error %d", __FUNCTION__, result); - return 0; - } - - return (uint32_t)result; -} - -int32_t -WHBCloseFile(int32_t handle) -{ - FSCmdBlock cmd; - FSStatus result; - FSInitCmdBlock(&cmd); - result = FSCloseFile(&sClient, &cmd, (FSFileHandle)handle, -1); - if (result != FS_STATUS_OK) { - WHBLogPrintf("%s: FSCloseFile error %d", __FUNCTION__, result); - return WHB_FILE_FATAL_ERROR; - } - - return WHB_FILE_OK; -} - -char * -WHBReadWholeFile(const char *path, - uint32_t *outSize) -{ - int32_t handle; - uint32_t size; - char *buf = NULL; - handle = WHBOpenFile(path, "r"); - if (handle == WHB_FILE_FATAL_ERROR) { - WHBLogPrintf("%s: WHBOpenFile failed", __FUNCTION__); - return NULL; - } - - size = WHBGetFileSize(handle); - if (size == 0) { - goto error; - } - - buf = MEMAllocFromDefaultHeapEx(size, 64); - if (!buf) { - WHBLogPrintf("%s: MEMAllocFromDefaultHeapEx(0x%X, 64) failed", __FUNCTION__, size); - goto error; - } - - if (WHBReadFile(handle, buf, 1, size) != size) { - goto error; - } - - if (outSize) { - *outSize = size; - } - - WHBCloseFile(handle); - return buf; - -error: - if (buf) { - MEMFreeToDefaultHeap(buf); - } - - WHBCloseFile(handle); - return NULL; -} - -void -WHBFreeWholeFile(char *file) -{ - MEMFreeToDefaultHeap(file); -} diff --git a/src/libwhb/src/gfx.c b/src/libwhb/src/gfx.c deleted file mode 100644 index a0c2020..0000000 --- a/src/libwhb/src/gfx.c +++ /dev/null @@ -1,520 +0,0 @@ -#include "gfx_heap.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WHB_GFX_COMMAND_BUFFER_POOL_SIZE (0x400000) - -static void * -sCommandBufferPool = NULL; - -static GX2DrcRenderMode -sDrcRenderMode; - -static void * -sDrcScanBuffer = NULL; - -static uint32_t -sDrcScanBufferSize = 0; - -static GX2SurfaceFormat -sDrcSurfaceFormat; - -static GX2TVRenderMode -sTvRenderMode; - -static void * -sTvScanBuffer = NULL; - -static uint32_t -sTvScanBufferSize = 0; - -static GX2SurfaceFormat -sTvSurfaceFormat; - -static GX2ColorBuffer -sTvColourBuffer = { 0 }; - -static GX2DepthBuffer -sTvDepthBuffer = { 0 }; - -static GX2ColorBuffer -sDrcColourBuffer = { 0 }; - -static GX2DepthBuffer -sDrcDepthBuffer = { 0 }; - -static GX2ContextState * -sTvContextState = NULL; - -static GX2ContextState * -sDrcContextState = NULL; - -static BOOL -sGpuTimedOut = FALSE; - -static void * -GfxGX2RAlloc(GX2RResourceFlags flags, - uint32_t size, - uint32_t alignment) -{ - // Color, depth, scan buffers all belong in MEM1 - if ((flags & (GX2R_RESOURCE_BIND_COLOR_BUFFER - | GX2R_RESOURCE_BIND_DEPTH_BUFFER - | GX2R_RESOURCE_BIND_SCAN_BUFFER - | GX2R_RESOURCE_USAGE_FORCE_MEM1)) - && !(flags & GX2R_RESOURCE_USAGE_FORCE_MEM2)) { - return GfxHeapAllocMEM1(size, alignment); - } else { - return GfxHeapAllocMEM2(size, alignment); - } -} - -static void -GfxGX2RFree(GX2RResourceFlags flags, void *block) -{ - if ((flags & (GX2R_RESOURCE_BIND_COLOR_BUFFER - | GX2R_RESOURCE_BIND_DEPTH_BUFFER - | GX2R_RESOURCE_BIND_SCAN_BUFFER - | GX2R_RESOURCE_USAGE_FORCE_MEM1)) - && !(flags & GX2R_RESOURCE_USAGE_FORCE_MEM2)) { - return GfxHeapFreeMEM1(block); - } else { - return GfxHeapFreeMEM2(block); - } -} - -static void -GfxInitTvColourBuffer(GX2ColorBuffer *cb, - uint32_t width, - uint32_t height, - GX2SurfaceFormat format, - GX2AAMode aa) -{ - memset(cb, 0, sizeof(GX2ColorBuffer)); - cb->surface.use = GX2_SURFACE_USE_TEXTURE_COLOR_BUFFER_TV; - cb->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; - cb->surface.width = width; - cb->surface.height = height; - cb->surface.depth = 1; - cb->surface.mipLevels = 1; - cb->surface.format = format; - cb->surface.aa = aa; - cb->surface.tileMode = GX2_TILE_MODE_DEFAULT; - cb->viewNumSlices = 1; - GX2CalcSurfaceSizeAndAlignment(&cb->surface); - GX2InitColorBufferRegs(cb); -} - -static void -GfxInitDepthBuffer(GX2DepthBuffer *db, - uint32_t width, - uint32_t height, - GX2SurfaceFormat format, - GX2AAMode aa) -{ - memset(db, 0, sizeof(GX2DepthBuffer)); - - if (format == GX2_SURFACE_FORMAT_UNORM_R24_X8 || format == GX2_SURFACE_FORMAT_FLOAT_D24_S8) { - db->surface.use = GX2_SURFACE_USE_DEPTH_BUFFER; - } else { - db->surface.use = GX2_SURFACE_USE_DEPTH_BUFFER | GX2_SURFACE_USE_TEXTURE; - } - - db->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D; - db->surface.width = width; - db->surface.height = height; - db->surface.depth = 1; - db->surface.mipLevels = 1; - db->surface.format = format; - db->surface.aa = aa; - db->surface.tileMode = GX2_TILE_MODE_DEFAULT; - db->viewNumSlices = 1; - db->depthClear = 1.0f; - GX2CalcSurfaceSizeAndAlignment(&db->surface); - GX2InitDepthBufferRegs(db); -} - -static uint32_t -GfxProcCallbackAcquired(void *context) -{ - if (!GfxHeapInitMEM1()) { - WHBLogPrintf("%s: GfxHeapInitMEM1 failed", __FUNCTION__); - goto error; - } - - if (!GfxHeapInitForeground()) { - WHBLogPrintf("%s: GfxHeapInitForeground failed", __FUNCTION__); - goto error; - } - - // Allocate TV scan buffer. - sTvScanBuffer = GfxHeapAllocForeground(sTvScanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT); - if (!sTvScanBuffer) { - WHBLogPrintf("%s: sTvScanBuffer = GfxHeapAllocForeground(0x%X, 0x%X) failed", - __FUNCTION__, - sTvScanBufferSize, - GX2_SCAN_BUFFER_ALIGNMENT); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvScanBuffer, sTvScanBufferSize); - GX2SetTVBuffer(sTvScanBuffer, sTvScanBufferSize, sTvRenderMode, sTvSurfaceFormat, GX2_BUFFERING_MODE_DOUBLE); - - // Allocate TV colour buffer. - sTvColourBuffer.surface.image = GfxHeapAllocMEM1(sTvColourBuffer.surface.imageSize, sTvColourBuffer.surface.alignment); - if (!sTvColourBuffer.surface.image) { - WHBLogPrintf("%s: sTvColourBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed", - __FUNCTION__, - sTvColourBuffer.surface.imageSize, - sTvColourBuffer.surface.alignment); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvColourBuffer.surface.image, sTvColourBuffer.surface.imageSize); - - // Allocate TV depth buffer. - sTvDepthBuffer.surface.image = GfxHeapAllocMEM1(sTvDepthBuffer.surface.imageSize, sTvDepthBuffer.surface.alignment); - if (!sTvDepthBuffer.surface.image) { - WHBLogPrintf("%s: sTvDepthBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed", - __FUNCTION__, - sTvDepthBuffer.surface.imageSize, - sTvDepthBuffer.surface.alignment); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvDepthBuffer.surface.image, sTvDepthBuffer.surface.imageSize); - - // Allocate DRC scan buffer. - sDrcScanBuffer = GfxHeapAllocForeground(sDrcScanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT); - if (!sDrcScanBuffer) { - WHBLogPrintf("%s: sDrcScanBuffer = GfxHeapAllocForeground(0x%X, 0x%X) failed", - __FUNCTION__, - sDrcScanBufferSize, - GX2_SCAN_BUFFER_ALIGNMENT); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcScanBuffer, sDrcScanBufferSize); - GX2SetDRCBuffer(sDrcScanBuffer, sDrcScanBufferSize, sDrcRenderMode, sDrcSurfaceFormat, GX2_BUFFERING_MODE_DOUBLE); - - // Allocate DRC colour buffer. - sDrcColourBuffer.surface.image = GfxHeapAllocMEM1(sDrcColourBuffer.surface.imageSize, sDrcColourBuffer.surface.alignment); - if (!sDrcColourBuffer.surface.image) { - WHBLogPrintf("%s: sDrcColourBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed", - __FUNCTION__, - sDrcColourBuffer.surface.imageSize, - sDrcColourBuffer.surface.alignment); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcColourBuffer.surface.image, sDrcColourBuffer.surface.imageSize); - - // Allocate DRC depth buffer. - sDrcDepthBuffer.surface.image = GfxHeapAllocMEM1(sDrcDepthBuffer.surface.imageSize, sDrcDepthBuffer.surface.alignment); - if (!sDrcDepthBuffer.surface.image) { - WHBLogPrintf("%s: sDrcDepthBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed", - __FUNCTION__, - sDrcDepthBuffer.surface.imageSize, - sDrcDepthBuffer.surface.alignment); - goto error; - } - GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcDepthBuffer.surface.image, sDrcDepthBuffer.surface.imageSize); - return 0; - -error: - return -1; -} - -static uint32_t -GfxProcCallbackReleased(void *context) -{ - GX2DrawDone(); - - if (sTvScanBuffer) { - GfxHeapFreeForeground(sTvScanBuffer); - sTvScanBuffer = NULL; - } - - if (sTvColourBuffer.surface.image) { - GfxHeapFreeMEM1(sTvColourBuffer.surface.image); - sTvColourBuffer.surface.image = NULL; - } - - if (sTvDepthBuffer.surface.image) { - GfxHeapFreeMEM1(sTvDepthBuffer.surface.image); - sTvDepthBuffer.surface.image = NULL; - } - - if (sDrcScanBuffer) { - GfxHeapFreeForeground(sDrcScanBuffer); - sDrcScanBuffer = NULL; - } - - if (sDrcColourBuffer.surface.image) { - GfxHeapFreeMEM1(sDrcColourBuffer.surface.image); - sDrcColourBuffer.surface.image = NULL; - } - - if (sDrcDepthBuffer.surface.image) { - GfxHeapFreeMEM1(sDrcDepthBuffer.surface.image); - sDrcDepthBuffer.surface.image = NULL; - } - - GfxHeapDestroyMEM1(); - GfxHeapDestroyForeground(); - return 0; -} - -BOOL -WHBGfxInit() -{ - uint32_t drcWidth, drcHeight; - uint32_t tvWidth, tvHeight; - uint32_t unk; - - sCommandBufferPool = GfxHeapAllocMEM2(WHB_GFX_COMMAND_BUFFER_POOL_SIZE, - GX2_COMMAND_BUFFER_ALIGNMENT); - if (!sCommandBufferPool) { - WHBLogPrintf("%s: failed to allocate command buffer pool", __FUNCTION__); - goto error; - } - - uint32_t initAttribs[] = { - GX2_INIT_CMD_BUF_BASE, (uintptr_t)sCommandBufferPool, - GX2_INIT_CMD_BUF_POOL_SIZE, WHB_GFX_COMMAND_BUFFER_POOL_SIZE, - GX2_INIT_ARGC, 0, - GX2_INIT_ARGV, 0, - GX2_INIT_END - }; - GX2Init(initAttribs); - - sDrcRenderMode = GX2GetSystemDRCScanMode(); - sTvSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; - sDrcSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; - - switch(GX2GetSystemTVScanMode()) - { - case GX2_TV_SCAN_MODE_480I: - case GX2_TV_SCAN_MODE_480P: - sTvRenderMode = GX2_TV_RENDER_MODE_WIDE_480P; - tvWidth = 854; - tvHeight = 480; - break; - case GX2_TV_SCAN_MODE_1080I: - case GX2_TV_SCAN_MODE_1080P: - sTvRenderMode = GX2_TV_RENDER_MODE_WIDE_1080P; - tvWidth = 1920; - tvHeight = 1080; - break; - case GX2_TV_SCAN_MODE_720P: - default: - sTvRenderMode = GX2_TV_RENDER_MODE_WIDE_720P; - tvWidth = 1280; - tvHeight = 720; - break; - } - - drcWidth = 854; - drcHeight = 480; - - // Setup TV and DRC buffers - they will be allocated in GfxProcCallbackAcquired. - GX2CalcTVSize(sTvRenderMode, sTvSurfaceFormat, GX2_BUFFERING_MODE_DOUBLE, &sTvScanBufferSize, &unk); - GfxInitTvColourBuffer(&sTvColourBuffer, tvWidth, tvHeight, sTvSurfaceFormat, GX2_AA_MODE1X); - GfxInitDepthBuffer(&sTvDepthBuffer, sTvColourBuffer.surface.width, sTvColourBuffer.surface.height, GX2_SURFACE_FORMAT_FLOAT_R32, sTvColourBuffer.surface.aa); - - GX2CalcDRCSize(sDrcRenderMode, sDrcSurfaceFormat, GX2_BUFFERING_MODE_DOUBLE, &sDrcScanBufferSize, &unk); - GfxInitTvColourBuffer(&sDrcColourBuffer, drcWidth, drcHeight, sDrcSurfaceFormat, GX2_AA_MODE1X); - GfxInitDepthBuffer(&sDrcDepthBuffer, sDrcColourBuffer.surface.width, sDrcColourBuffer.surface.height, GX2_SURFACE_FORMAT_FLOAT_R32, sDrcColourBuffer.surface.aa); - if (GfxProcCallbackAcquired(NULL) != 0) { - WHBLogPrintf("%s: GfxProcCallbackAcquired failed", __FUNCTION__); - goto error; - } - - GX2RSetAllocator(&GfxGX2RAlloc, &GfxGX2RFree); - ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, GfxProcCallbackAcquired, NULL, 100); - ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, GfxProcCallbackReleased, NULL, 100); - - // Initialise TV context state. - sTvContextState = GfxHeapAllocMEM2(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT); - if (!sTvContextState) { - WHBLogPrintf("%s: failed to allocate sTvContextState", __FUNCTION__); - goto error; - } - GX2SetupContextStateEx(sTvContextState, TRUE); - GX2SetContextState(sTvContextState); - GX2SetColorBuffer(&sTvColourBuffer, GX2_RENDER_TARGET_0); - GX2SetDepthBuffer(&sTvDepthBuffer); - GX2SetViewport(0, 0, (float)sTvColourBuffer.surface.width, (float)sTvColourBuffer.surface.height, 0.0f, 1.0f); - GX2SetScissor(0, 0, (float)sTvColourBuffer.surface.width, (float)sTvColourBuffer.surface.height); - GX2SetTVScale((float)sTvColourBuffer.surface.width, (float)sTvColourBuffer.surface.height); - - // Initialise DRC context state. - sDrcContextState = GfxHeapAllocMEM2(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT); - if (!sDrcContextState) { - WHBLogPrintf("%s: failed to allocate sDrcContextState", __FUNCTION__); - goto error; - } - GX2SetupContextStateEx(sDrcContextState, TRUE); - GX2SetContextState(sDrcContextState); - GX2SetColorBuffer(&sDrcColourBuffer, GX2_RENDER_TARGET_0); - GX2SetDepthBuffer(&sDrcDepthBuffer); - GX2SetViewport(0, 0, (float)sDrcColourBuffer.surface.width, (float)sDrcColourBuffer.surface.height, 0.0f, 1.0f); - GX2SetScissor(0, 0, (float)sDrcColourBuffer.surface.width, (float)sDrcColourBuffer.surface.height); - GX2SetDRCScale((float)sDrcColourBuffer.surface.width, (float)sDrcColourBuffer.surface.height); - - // Set 60fps VSync - GX2SetSwapInterval(1); - - return TRUE; - -error: - if (sCommandBufferPool) { - GfxHeapFreeMEM2(sCommandBufferPool); - sCommandBufferPool = NULL; - } - - if (sTvScanBuffer) { - GfxHeapFreeForeground(sTvScanBuffer); - sTvScanBuffer = NULL; - } - - if (sTvColourBuffer.surface.image) { - GfxHeapFreeMEM1(sTvColourBuffer.surface.image); - sTvColourBuffer.surface.image = NULL; - } - - if (sTvDepthBuffer.surface.image) { - GfxHeapFreeMEM1(sTvDepthBuffer.surface.image); - sTvDepthBuffer.surface.image = NULL; - } - - if (sTvContextState) { - GfxHeapFreeMEM2(sTvContextState); - sTvContextState = NULL; - } - - if (sDrcScanBuffer) { - GfxHeapFreeForeground(sDrcScanBuffer); - sDrcScanBuffer = NULL; - } - - if (sDrcColourBuffer.surface.image) { - GfxHeapFreeMEM1(sDrcColourBuffer.surface.image); - sDrcColourBuffer.surface.image = NULL; - } - - if (sDrcDepthBuffer.surface.image) { - GfxHeapFreeMEM1(sDrcDepthBuffer.surface.image); - sDrcDepthBuffer.surface.image = NULL; - } - - if (sDrcContextState) { - GfxHeapFreeMEM2(sDrcContextState); - sDrcContextState = NULL; - } - - return FALSE; -} - -void -WHBGfxShutdown() -{ - if (sGpuTimedOut) { - GX2ResetGPU(0); - sGpuTimedOut = FALSE; - } - - GfxProcCallbackReleased(NULL); - GX2RSetAllocator(NULL, NULL); - GX2Shutdown(); - - if (sTvContextState) { - GfxHeapFreeMEM2(sTvContextState); - sTvContextState = NULL; - } - - if (sDrcContextState) { - GfxHeapFreeMEM2(sDrcContextState); - sDrcContextState = NULL; - } - - if (sCommandBufferPool) { - GfxHeapFreeMEM2(sCommandBufferPool); - sCommandBufferPool = NULL; - } -} - -void -WHBGfxBeginRender() -{ - uint32_t swapCount, flipCount; - OSTime lastFlip, lastVsync; - uint32_t waitCount = 0; - - while (true) { - GX2GetSwapStatus(&swapCount, &flipCount, &lastFlip, &lastVsync); - - if (flipCount >= swapCount) { - break; - } - - if (waitCount >= 10) { - WHBLogPrint("WHBGfxBeginRender wait for swap timed out"); - sGpuTimedOut = TRUE; - break; - } - - waitCount++; - GX2WaitForVsync(); - } -} - -void -WHBGfxFinishRender() -{ - GX2SwapScanBuffers(); - GX2Flush(); - GX2DrawDone(); - GX2SetTVEnable(TRUE); - GX2SetDRCEnable(TRUE); -} - -void -WHBGfxBeginRenderDRC() -{ - GX2SetContextState(sDrcContextState); - GX2ClearColor(&sDrcColourBuffer, 0.0f, 1.0f, 0.0f, 1.0f); - GX2ClearDepthStencilEx(&sDrcDepthBuffer, sDrcDepthBuffer.depthClear, sDrcDepthBuffer.stencilClear, GX2_CLEAR_FLAGS_DEPTH | GX2_CLEAR_FLAGS_STENCIL); - GX2SetContextState(sDrcContextState); -} - -void -WHBGfxFinishRenderDRC() -{ - GX2CopyColorBufferToScanBuffer(&sDrcColourBuffer, GX2_SCAN_TARGET_DRC); -} - -void -WHBGfxBeginRenderTV() -{ - GX2SetContextState(sTvContextState); - GX2ClearColor(&sTvColourBuffer, 1.0f, 0.0f, 0.0f, 1.0f); - GX2ClearDepthStencilEx(&sTvDepthBuffer, sTvDepthBuffer.depthClear, sTvDepthBuffer.stencilClear, GX2_CLEAR_FLAGS_DEPTH | GX2_CLEAR_FLAGS_STENCIL); - GX2SetContextState(sTvContextState); -} - -void -WHBGfxFinishRenderTV() -{ - GX2CopyColorBufferToScanBuffer(&sTvColourBuffer, GX2_SCAN_TARGET_TV); -} diff --git a/src/libwhb/src/gfx_heap.c b/src/libwhb/src/gfx_heap.c deleted file mode 100644 index 9b726bb..0000000 --- a/src/libwhb/src/gfx_heap.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "gfx_heap.h" -#include -#include -#include -#include -#include - -static void * -sGfxHeapMEM1 = NULL; - -static void * -sGfxHeapForeground = NULL; - -#define GFX_FRAME_HEAP_TAG (0x123DECAF) - -BOOL -GfxHeapInitMEM1() -{ - MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); - uint32_t size; - void *base; - - if (!MEMRecordStateForFrmHeap(heap, GFX_FRAME_HEAP_TAG)) { - WHBLogPrintf("%s: MEMRecordStateForFrmHeap failed", __FUNCTION__); - return FALSE; - } - - size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4); - if (!size) { - WHBLogPrintf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0", __FUNCTION__); - return FALSE; - } - - base = MEMAllocFromFrmHeapEx(heap, size, 4); - if (!base) { - WHBLogPrintf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4) failed", __FUNCTION__, size); - return FALSE; - } - - sGfxHeapMEM1 = MEMCreateExpHeapEx(base, size, 0); - if (!sGfxHeapMEM1) { - WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0) failed", __FUNCTION__, base, size); - return FALSE; - } - - return TRUE; -} - -BOOL -GfxHeapDestroyMEM1() -{ - MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); - - if (sGfxHeapMEM1) { - MEMDestroyExpHeap(sGfxHeapMEM1); - sGfxHeapMEM1 = NULL; - } - - MEMFreeByStateToFrmHeap(heap, GFX_FRAME_HEAP_TAG); - return TRUE; -} - -BOOL -GfxHeapInitForeground() -{ - MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG); - uint32_t size; - void *base; - - size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4); - if (!size) { - WHBLogPrintf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4)", __FUNCTION__, size); - return FALSE; - } - - base = MEMAllocFromFrmHeapEx(heap, size, 4); - if (!base) { - WHBLogPrintf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0", __FUNCTION__); - return FALSE; - } - - sGfxHeapForeground = MEMCreateExpHeapEx(base, size, 0); - if (!sGfxHeapForeground) { - WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0)", __FUNCTION__, base, size); - return FALSE; - } - - return TRUE; -} - -BOOL -GfxHeapDestroyForeground() -{ - MEMHeapHandle foreground = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG); - - if (sGfxHeapForeground) { - MEMDestroyExpHeap(sGfxHeapForeground); - sGfxHeapForeground = NULL; - } - - MEMFreeToFrmHeap(foreground, MEM_FRAME_HEAP_FREE_ALL); - return TRUE; -} - -void * -GfxHeapAllocMEM1(uint32_t size, - uint32_t alignment) -{ - void *block; - - if (!sGfxHeapMEM1) { - return NULL; - } - - if (alignment < 4) { - alignment = 4; - } - - block = MEMAllocFromExpHeapEx(sGfxHeapMEM1, size, alignment); - return block; -} - -void -GfxHeapFreeMEM1(void *block) -{ - if (!sGfxHeapMEM1) { - return; - } - - MEMFreeToExpHeap(sGfxHeapMEM1, block); -} - -void * -GfxHeapAllocForeground(uint32_t size, - uint32_t alignment) -{ - void *block; - - if (!sGfxHeapForeground) { - return NULL; - } - - if (alignment < 4) { - alignment = 4; - } - - block = MEMAllocFromExpHeapEx(sGfxHeapForeground, size, alignment); - return block; -} - -void -GfxHeapFreeForeground(void *block) -{ - if (!sGfxHeapForeground) { - return; - } - - MEMFreeToExpHeap(sGfxHeapForeground, block); -} - -void * -GfxHeapAllocMEM2(uint32_t size, - uint32_t alignment) -{ - if (alignment < 4) { - alignment = 4; - } - - return MEMAllocFromDefaultHeapEx(size, alignment); -} - -void -GfxHeapFreeMEM2(void *block) -{ - MEMFreeToDefaultHeap(block); -} diff --git a/src/libwhb/src/gfx_heap.h b/src/libwhb/src/gfx_heap.h deleted file mode 100644 index 4d4debb..0000000 --- a/src/libwhb/src/gfx_heap.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include - -BOOL -GfxHeapInitMEM1(); - -BOOL -GfxHeapDestroyMEM1(); - -BOOL -GfxHeapInitForeground(); - -BOOL -GfxHeapDestroyForeground(); - -void * -GfxHeapAllocMEM1(uint32_t size, - uint32_t alignment); - -void -GfxHeapFreeMEM1(void *block); - -void * -GfxHeapAllocForeground(uint32_t size, - uint32_t alignment); - -void -GfxHeapFreeForeground(void *block); - -void * -GfxHeapAllocMEM2(uint32_t size, - uint32_t alignment); - -void -GfxHeapFreeMEM2(void *block); diff --git a/src/libwhb/src/gfx_shader.c b/src/libwhb/src/gfx_shader.c deleted file mode 100644 index eb57f7d..0000000 --- a/src/libwhb/src/gfx_shader.c +++ /dev/null @@ -1,299 +0,0 @@ -#include "gfx_heap.h" -#include -#include -#include -#include -#include -#include -#include -#include - -GX2PixelShader * -WHBGfxLoadGFDPixelShader(uint32_t index, - const void *file) -{ - uint32_t headerSize, programSize; - GX2PixelShader *shader = NULL; - void *program = NULL; - - if (index >= GFDGetPixelShaderCount(file)) { - WHBLogPrintf("%s: index %u >= %u GFDGetPixelShaderCount(file)", - __FUNCTION__, - index, - GFDGetPixelShaderCount(file)); - goto error; - } - - headerSize = GFDGetPixelShaderHeaderSize(index, file); - if (!headerSize) { - WHBLogPrintf("%s: headerSize == 0", __FUNCTION__); - goto error; - } - - programSize = GFDGetPixelShaderProgramSize(index, file); - if (!programSize) { - WHBLogPrintf("%s: programSize == 0", __FUNCTION__); - goto error; - } - - shader = (GX2PixelShader *)GfxHeapAllocMEM2(headerSize, 64); - if (!shader) { - WHBLogPrintf("%s: GfxHeapAllocMEM2(%u, 64) failed", __FUNCTION__, headerSize); - goto error; - } - - shader->gx2rBuffer.flags = GX2R_RESOURCE_BIND_SHADER_PROGRAM | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; - shader->gx2rBuffer.elemSize = programSize; - shader->gx2rBuffer.elemCount = 1; - shader->gx2rBuffer.buffer = NULL; - if (!GX2RCreateBuffer(&shader->gx2rBuffer)) { - WHBLogPrintf("%s: GX2RCreateBuffer failed with programSize = %u", __FUNCTION__, programSize); - goto error; - } - - program = GX2RLockBufferEx(&shader->gx2rBuffer, 0); - if (!program) { - WHBLogPrintf("%s: GX2RLockBufferEx failed", __FUNCTION__); - goto error; - } - - if (!GFDGetPixelShader(shader, program, index, file)) { - WHBLogPrintf("%s: GFDGetPixelShader failed", __FUNCTION__); - GX2RUnlockBufferEx(&shader->gx2rBuffer, GX2R_RESOURCE_DISABLE_CPU_INVALIDATE | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE); - goto error; - } - - GX2RUnlockBufferEx(&shader->gx2rBuffer, 0); - return shader; - -error: - if (shader) { - if (shader->gx2rBuffer.buffer) { - GX2RDestroyBufferEx(&shader->gx2rBuffer, 0); - } - - GfxHeapFreeMEM2(shader); - } - - return NULL; -} - -BOOL -WHBGfxFreePixelShader(GX2PixelShader *shader) -{ - if (shader->gx2rBuffer.buffer) { - GX2RDestroyBufferEx(&shader->gx2rBuffer, 0); - } - - GfxHeapFreeMEM2(shader); -} - -GX2VertexShader * -WHBGfxLoadGFDVertexShader(uint32_t index, - const void *file) -{ - uint32_t headerSize, programSize; - GX2VertexShader *shader = NULL; - void *program = NULL; - - if (index >= GFDGetVertexShaderCount(file)) { - WHBLogPrintf("%s: index %u >= %u GFDGetVertexShaderCount(file)", - __FUNCTION__, - index, - GFDGetVertexShaderCount(file)); - goto error; - } - - headerSize = GFDGetVertexShaderHeaderSize(index, file); - if (!headerSize) { - WHBLogPrintf("%s: headerSize == 0", __FUNCTION__); - goto error; - } - - programSize = GFDGetVertexShaderProgramSize(index, file); - if (!programSize) { - WHBLogPrintf("%s: programSize == 0", __FUNCTION__); - goto error; - } - - shader = (GX2VertexShader *)GfxHeapAllocMEM2(headerSize, 64); - if (!shader) { - WHBLogPrintf("%s: GfxHeapAllocMEM2(%u, 64) failed", __FUNCTION__, headerSize); - goto error; - } - - shader->gx2rBuffer.flags = GX2R_RESOURCE_BIND_SHADER_PROGRAM | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; - shader->gx2rBuffer.elemSize = programSize; - shader->gx2rBuffer.elemCount = 1; - shader->gx2rBuffer.buffer = NULL; - if (!GX2RCreateBuffer(&shader->gx2rBuffer)) { - WHBLogPrintf("%s: GX2RCreateBuffer failed with programSize = %u", __FUNCTION__, programSize); - goto error; - } - - program = GX2RLockBufferEx(&shader->gx2rBuffer, 0); - if (!program) { - WHBLogPrintf("%s: GX2RLockBufferEx failed", __FUNCTION__); - goto error; - } - - if (!GFDGetVertexShader(shader, program, index, file)) { - WHBLogPrintf("%s: GFDGetVertexShader failed", __FUNCTION__); - GX2RUnlockBufferEx(&shader->gx2rBuffer, GX2R_RESOURCE_DISABLE_CPU_INVALIDATE | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE); - goto error; - } - - GX2RUnlockBufferEx(&shader->gx2rBuffer, 0); - return shader; - -error: - if (shader) { - if (shader->gx2rBuffer.buffer) { - GX2RDestroyBufferEx(&shader->gx2rBuffer, 0); - } - - GfxHeapFreeMEM2(shader); - } - - return NULL; -} - -BOOL -WHBGfxFreeVertexShader(GX2VertexShader *shader) -{ - if (shader->gx2rBuffer.buffer) { - GX2RDestroyBufferEx(&shader->gx2rBuffer, 0); - } - - GfxHeapFreeMEM2(shader); -} - -BOOL -WHBGfxLoadGFDShaderGroup(WHBGfxShaderGroup *group, - uint32_t index, - const void *file) -{ - memset(group, 0, sizeof(WHBGfxShaderGroup)); - group->vertexShader = WHBGfxLoadGFDVertexShader(index, file); - group->pixelShader = WHBGfxLoadGFDPixelShader(index, file); - - if (!group->vertexShader || !group->pixelShader) { - // A shader group requires at least a vertex shader and a pixel shader. - WHBGfxFreeShaderGroup(group); - return FALSE; - } - - return TRUE; -} - -static uint32_t -GfxGetAttribFormatSel(GX2AttribFormat format) -{ - switch (format) { - case GX2_ATTRIB_FORMAT_UNORM_8: - case GX2_ATTRIB_FORMAT_UINT_8: - case GX2_ATTRIB_FORMAT_SNORM_8: - case GX2_ATTRIB_FORMAT_SINT_8: - case GX2_ATTRIB_FORMAT_FLOAT_32: - return LATTE_SQ_SEL_MASK(LATTE_SQ_SEL_X, LATTE_SQ_SEL_0, LATTE_SQ_SEL_0, LATTE_SQ_SEL_1); - case GX2_ATTRIB_FORMAT_UNORM_8_8: - case GX2_ATTRIB_FORMAT_UINT_8_8: - case GX2_ATTRIB_FORMAT_SNORM_8_8: - case GX2_ATTRIB_FORMAT_SINT_8_8: - case GX2_ATTRIB_FORMAT_FLOAT_32_32: - return LATTE_SQ_SEL_MASK(LATTE_SQ_SEL_X, LATTE_SQ_SEL_Y, LATTE_SQ_SEL_0, LATTE_SQ_SEL_1); - case GX2_ATTRIB_FORMAT_FLOAT_32_32_32: - return LATTE_SQ_SEL_MASK(LATTE_SQ_SEL_X, LATTE_SQ_SEL_Y, LATTE_SQ_SEL_Z, LATTE_SQ_SEL_1); - case GX2_ATTRIB_FORMAT_UNORM_8_8_8_8: - case GX2_ATTRIB_FORMAT_UINT_8_8_8_8: - case GX2_ATTRIB_FORMAT_SNORM_8_8_8_8: - case GX2_ATTRIB_FORMAT_SINT_8_8_8_8: - case GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32: - return LATTE_SQ_SEL_MASK(LATTE_SQ_SEL_X, LATTE_SQ_SEL_Y, LATTE_SQ_SEL_Z, LATTE_SQ_SEL_W); - break; - default: - return LATTE_SQ_SEL_MASK(LATTE_SQ_SEL_0, LATTE_SQ_SEL_0, LATTE_SQ_SEL_0, LATTE_SQ_SEL_1); - } -} - -static int32_t -GfxGetVertexAttribVarLocation(const GX2VertexShader* shader, - const char *name) -{ - uint32_t i; - - for (i = 0; i < shader->attribVarCount; ++i) { - if (strcmp(shader->attribVars[i].name, name) == 0) { - return shader->attribVars[i].location; - } - } - - return -1; -} - -BOOL -WHBGfxInitShaderAttribute(WHBGfxShaderGroup *group, - const char *name, - uint32_t buffer, - uint32_t offset, - GX2AttribFormat format) -{ - GX2AttribStream *attrib; - int32_t location; - - location = GfxGetVertexAttribVarLocation(group->vertexShader, name); - if (location == -1) { - return FALSE; - } - - attrib = &group->attributes[group->numAttributes++]; - attrib->location = location; - attrib->buffer = buffer; - attrib->offset = offset; - attrib->format = format; - attrib->type = GX2_ATTRIB_INDEX_PER_VERTEX; - attrib->aluDivisor = 0; - attrib->mask = GfxGetAttribFormatSel(format); - attrib->endianSwap = GX2_ENDIAN_SWAP_DEFAULT; - return TRUE; -} - -BOOL -WHBGfxInitFetchShader(WHBGfxShaderGroup *group) -{ - uint32_t size = GX2CalcFetchShaderSizeEx(group->numAttributes, - GX2_FETCH_SHADER_TESSELLATION_NONE, - GX2_TESSELLATION_MODE_DISCRETE); - group->fetchShaderProgram = GfxHeapAllocMEM2(size, GX2_SHADER_PROGRAM_ALIGNMENT); - - GX2InitFetchShaderEx(&group->fetchShader, - group->fetchShaderProgram, - group->numAttributes, - group->attributes, - GX2_FETCH_SHADER_TESSELLATION_NONE, - GX2_TESSELLATION_MODE_DISCRETE); - - GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, group->fetchShaderProgram, size); - return TRUE; -} - -BOOL -WHBGfxFreeShaderGroup(WHBGfxShaderGroup *group) -{ - if (group->fetchShaderProgram) { - GfxHeapFreeMEM2(group->fetchShaderProgram); - group->fetchShaderProgram = NULL; - } - - if (group->pixelShader) { - WHBGfxFreePixelShader(group->pixelShader); - group->pixelShader = NULL; - } - - if (group->vertexShader) { - WHBGfxFreeVertexShader(group->vertexShader); - group->vertexShader = NULL; - } - - return TRUE; -} diff --git a/src/libwhb/src/gfx_texture.c b/src/libwhb/src/gfx_texture.c deleted file mode 100644 index 6019a91..0000000 --- a/src/libwhb/src/gfx_texture.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "gfx_heap.h" -#include -#include -#include -#include -#include - -GX2Texture * -WHBGfxLoadGFDTexture(uint32_t index, - const void *file) -{ - uint32_t headerSize, imageSize; - GX2Texture *texture = NULL; - void *image = NULL; - - if (index >= GFDGetTextureCount(file)) { - WHBLogPrintf("%s: invalid GFD texture index %u", __FUNCTION__, index); - goto error; - } - - headerSize = GFDGetTextureHeaderSize(index, file); - imageSize = GFDGetTextureImageSize(index, file); - - if (!headerSize || !imageSize) { - goto error; - } - - texture = (GX2Texture *)GfxHeapAllocMEM2(headerSize, 64); - if (!texture) { - WHBLogPrintf("%s: GfxHeapAllocMEM2(0x%X, 64) failed", __FUNCTION__, headerSize); - goto error; - } - - if (!GFDGetGX2RTexture(texture, index, file)) { - goto error; - } - - return texture; - -error: - if (texture) { - GX2RDestroySurfaceEx(&texture->surface, 0); - GfxHeapFreeMEM2(texture); - } - - return NULL; -} - -BOOL -WHBGfxFreeTexture(GX2Texture *texture) -{ - GX2RDestroySurfaceEx(&texture->surface, 0); - GfxHeapFreeMEM2(texture); - return TRUE; -} diff --git a/src/libwhb/src/libmanager.c b/src/libwhb/src/libmanager.c deleted file mode 100644 index 3701b00..0000000 --- a/src/libwhb/src/libmanager.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/** - * Socket Library (nsysnet.rpl) - */ - -static BOOL -isSocketInitialized = FALSE; - -static unsigned int -numberOfSocketClients = 0; - -void -WHBInitializeSocketLibrary() -{ - if(!isSocketInitialized) { - isSocketInitialized = TRUE; - socket_lib_init(); - } - numberOfSocketClients++; -} - -void -WHBDeinitializeSocketLibrary() -{ - if(numberOfSocketClients > 0) { - numberOfSocketClients--; - } - if(isSocketInitialized && numberOfSocketClients == 0) { - isSocketInitialized = FALSE; - socket_lib_finish(); - } -} diff --git a/src/libwhb/src/log.c b/src/libwhb/src/log.c deleted file mode 100644 index eccd15e..0000000 --- a/src/libwhb/src/log.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include -#include -#include - -#define MAX_HANDLERS 16 -#define PRINTF_BUFFER_LENGTH 2048 - -static LogHandlerFn -sHandlers[MAX_HANDLERS] = { 0 }; - -static inline void -dispatchMessage(const char * str) -{ - int i; - for (i = 0; i < MAX_HANDLERS; ++i) { - if (sHandlers[i]) { - sHandlers[i](str); - } - } -} - -BOOL -WHBAddLogHandler(LogHandlerFn fn) -{ - int i; - - for (i = 0; i < MAX_HANDLERS; ++i) { - if (!sHandlers[i]) { - sHandlers[i] = fn; - return TRUE; - } - } - - return FALSE; -} - -BOOL -WHBRemoveLogHandler(LogHandlerFn fn) -{ - int i; - - for(i = 0; i < MAX_HANDLERS; ++i) { - if(sHandlers[i] == fn) { - sHandlers[i] = NULL; - return TRUE; - } - } - - return FALSE; -} - -BOOL -WHBLogWrite(const char *str) -{ - dispatchMessage(str); - return TRUE; -} - -BOOL -WHBLogPrint(const char *str) -{ - char *buf = MEMAllocFromDefaultHeapEx(PRINTF_BUFFER_LENGTH, 4); - if(!buf) { - return FALSE; - } - - snprintf(buf, PRINTF_BUFFER_LENGTH, "%s\n", str); - dispatchMessage(buf); - - MEMFreeToDefaultHeap(buf); - return TRUE; -} - -BOOL -WHBLogWritef(const char *fmt, ...) -{ - char *buf = MEMAllocFromDefaultHeapEx(PRINTF_BUFFER_LENGTH, 4); - va_list va; - - if (!buf) { - return FALSE; - } - - va_start(va, fmt); - vsnprintf(buf, PRINTF_BUFFER_LENGTH, fmt, va); - dispatchMessage(buf); - - MEMFreeToDefaultHeap(buf); - va_end(va); - return TRUE; -} - -BOOL -WHBLogPrintf(const char *fmt, ...) -{ - char *buf1 = MEMAllocFromDefaultHeapEx(PRINTF_BUFFER_LENGTH, 4); - char *buf2 = MEMAllocFromDefaultHeapEx(PRINTF_BUFFER_LENGTH, 4); - va_list va; - - if (!buf1) { - return FALSE; - } - - if(!buf2) { - MEMFreeToDefaultHeap(buf1); - return FALSE; - } - - va_start(va, fmt); - - vsnprintf(buf1, PRINTF_BUFFER_LENGTH, fmt, va); - snprintf(buf2, PRINTF_BUFFER_LENGTH, "%s\n", buf1); - dispatchMessage(buf2); - - MEMFreeToDefaultHeap(buf1); - MEMFreeToDefaultHeap(buf2); - va_end(va); - return TRUE; -} diff --git a/src/libwhb/src/log_cafe.c b/src/libwhb/src/log_cafe.c deleted file mode 100644 index 34d067e..0000000 --- a/src/libwhb/src/log_cafe.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -#include - -static void -cafeLogHandler(const char * msg) -{ - int length = strlen(msg); - - if(msg[length-1] != '\n') { - OSReport("%s\n", msg); - } - else { - OSReport(msg); - } -} - -BOOL -WHBLogCafeInit() -{ - return WHBAddLogHandler(cafeLogHandler); -} - -BOOL -WHBLogCafeDeinit() -{ - return WHBRemoveLogHandler(cafeLogHandler); -} diff --git a/src/libwhb/src/log_udp.c b/src/libwhb/src/log_udp.c deleted file mode 100644 index 2e5cd5e..0000000 --- a/src/libwhb/src/log_udp.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static int -sSocket = -1; - -static struct sockaddr_in -sSendAddr; - -#define SERVER_PORT 4405 - -static void -udpLogHandler(const char *msg) -{ - sendto(sSocket, - msg, - strlen(msg), - 0, - (struct sockaddr *)&sSendAddr, - sizeof(struct sockaddr_in)); -} - -BOOL -WHBLogUdpInit() -{ - int broadcastEnable = 1; - WHBInitializeSocketLibrary(); - - sSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sSocket < 0) { - return FALSE; - } - - setsockopt(sSocket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)); - - memset(&sSendAddr, 0, sizeof(struct sockaddr_in)); - sSendAddr.sin_family = AF_INET; - sSendAddr.sin_port = htons(SERVER_PORT); - sSendAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); - - return WHBAddLogHandler(udpLogHandler); -} - -BOOL -WHBLogUdpDeinit() -{ - if(shutdown(sSocket, SHUT_WR) != 0) { - return FALSE; - } - - WHBDeinitializeSocketLibrary(); - return WHBRemoveLogHandler(udpLogHandler); -} diff --git a/src/libwhb/src/proc.c b/src/libwhb/src/proc.c deleted file mode 100644 index 25ada6b..0000000 --- a/src/libwhb/src/proc.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HBL_TITLE_ID (0x0005000013374842) -#define MII_MAKER_JPN_TITLE_ID (0x000500101004A000) -#define MII_MAKER_USA_TITLE_ID (0x000500101004A100) -#define MII_MAKER_EUR_TITLE_ID (0x000500101004A200) - -static uint32_t -sMainCore; - -static BOOL -sRunning = FALSE; - -static BOOL -sFromHBL = FALSE; - -static ProcUICallback -sAcquireCallback = NULL; - -static uint32_t -procSaveCallback(void *context) -{ - OSSavesDone_ReadyToRelease(); - return 0; -} - - -static uint32_t -procHomeButtonDenied(void *context) -{ - if (sFromHBL) { - WHBProcStopRunning(); - } - - return 0; -} - -void -WHBProcInit() -{ - uint64_t titleID = OSGetTitleID(); - - // Homebrew Launcher does not like the standard ProcUI application loop, - // so instead we disable the home buttom menu and use the home button - // to trigger an exit. - if (titleID == HBL_TITLE_ID || - titleID == MII_MAKER_JPN_TITLE_ID || - titleID == MII_MAKER_USA_TITLE_ID || - titleID == MII_MAKER_EUR_TITLE_ID) { - // Important: OSEnableHomeButtonMenu must come before ProcUIInitEx. - OSEnableHomeButtonMenu(FALSE); - sFromHBL = TRUE; - } - - sMainCore = OSGetCoreId(); - sRunning = TRUE; - ProcUIInitEx(&procSaveCallback, NULL); - ProcUIRegisterCallback(PROCUI_CALLBACK_HOME_BUTTON_DENIED, &procHomeButtonDenied, NULL, 100); -} - -void -WHBProcShutdown() -{ - sRunning = FALSE; - - // If we're running from Homebrew Launcher we must do a SYSRelaunchTitle to - // correctly return to HBL. - if (sFromHBL) { - SYSRelaunchTitle(0, NULL); - } -} - -void -WHBProcStopRunning() -{ - sRunning = FALSE; -} - -BOOL -WHBProcIsRunning() -{ - ProcUIStatus status; - - if (sMainCore != OSGetCoreId()) { - ProcUISubProcessMessages(TRUE); - return sRunning; - } - - status = ProcUIProcessMessages(TRUE); - if (status == PROCUI_STATUS_EXITING) { - WHBProcStopRunning(); - } else if (status == PROCUI_STATUS_RELEASE_FOREGROUND) { - ProcUIDrawDoneRelease(); - } - - if (!sRunning) { - ProcUIShutdown(); - } - - return sRunning; -} diff --git a/src/libwhb/src/sdcard.c b/src/libwhb/src/sdcard.c deleted file mode 100644 index 83dfe52..0000000 --- a/src/libwhb/src/sdcard.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include - -static BOOL -sMounted = FALSE; - -static char -sMountPath[128] = { 0 }; - -static FSClient -sClient; - -BOOL -WHBMountSdCard() -{ - FSCmdBlock cmd; - FSMountSource mountSource; - FSStatus result; - - if (sMounted) { - return TRUE; - } - - FSInit(); - - result = FSAddClient(&sClient, -1); - if (result != FS_STATUS_OK) { - WHBLogPrintf("%s: FSAddClient error %d", __FUNCTION__, result); - return FALSE; - } - - FSInitCmdBlock(&cmd); - result = FSGetMountSource(&sClient, &cmd, FS_MOUNT_SOURCE_SD, &mountSource, -1); - if (result < 0) { - WHBLogPrintf("%s: FSGetMountSource error %d", __FUNCTION__, result); - goto fail; - } - - result = FSMount(&sClient, &cmd, &mountSource, sMountPath, sizeof(sMountPath), -1); - if (result < 0) { - WHBLogPrintf("%s: FSMount error %d", __FUNCTION__, result); - goto fail; - } - - sMounted = TRUE; - return TRUE; - -fail: - FSDelClient(&sClient, -1); - return FALSE; -} - -char * -WHBGetSdCardMountPath() -{ - return sMountPath; -} - -BOOL -WHBUnmountSdCard() -{ - FSCmdBlock cmd; - FSStatus result; - - if (!sMounted) { - return TRUE; - } - - FSInitCmdBlock(&cmd); - - result = FSUnmount(&sClient, &cmd, sMountPath, -1); - if (result < 0) { - WHBLogPrintf("%s: FSUnmount error %d", __FUNCTION__, result); - return FALSE; - } - - sMounted = FALSE; - return TRUE; -} diff --git a/src/rpl/CMakeLists.txt b/src/rpl/CMakeLists.txt deleted file mode 100644 index 30dd414..0000000 --- a/src/rpl/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(wut-libraries) - -set_property(SOURCE common/stub.S PROPERTY LANGUAGE C) - -set(WUT_RPL_COMPILE_FLAGS "-Wno-unused-variable -fno-builtin -ffreestanding") -set(WUT_RPL_LINKER_FLAGS "-nostdlib -nostartfiles") - -macro(add_wut_rpl target) - add_library(${target} - common/lib.c - common/stub.S - ${target}/config.h - ${target}/exports.h) - target_include_directories(${target} PRIVATE "common" "${target}") - set_target_properties(${target} PROPERTIES - COMPILE_FLAGS "${WUT_RPL_COMPILE_FLAGS}" - LINK_FLAGS "${WUT_RPL_LINKER_FLAGS}") - install(TARGETS ${target} ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") -endmacro() - -add_wut_rpl(coreinit) -add_wut_rpl(gx2) -add_wut_rpl(nsysnet) -add_wut_rpl(nn_ac) -add_wut_rpl(proc_ui) -add_wut_rpl(sndcore2) -add_wut_rpl(sysapp) -add_wut_rpl(vpad) diff --git a/src/rpl/common/lib.c b/src/rpl/common/lib.c deleted file mode 100644 index 97dec65..0000000 --- a/src/rpl/common/lib.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "config.h" - -// Get the start of the stubs -static const void *fstubBegin[0] __attribute__((section(".data.rplFuncStubs"))); - -#define EXPORT(name) \ - extern void *name; \ - const void *name##_stub __attribute__((section(".data.rplFuncStubs"))) = &name; \ - -#include "exports.h" - -// Get the end of the stubs -static const void *fstubEnd[0] __attribute__((section(".data.rplFuncStubs"))); - -// Create a header with the name and stub begin/end in -typedef struct -{ - const char *name; - const void *fstubBegin; - const void *fstubEnd; -} __attribute__((__packed__)) rpl_header; - -static const const char name[] __attribute__((section(".rodata.rplNames"))) = LIBRARY_NAME; - -static rpl_header header __attribute__((section(".lib.rplLibs"))) = { - name, - fstubBegin, - fstubEnd, -}; diff --git a/src/rpl/common/stub.S b/src/rpl/common/stub.S deleted file mode 100644 index c382136..0000000 --- a/src/rpl/common/stub.S +++ /dev/null @@ -1,13 +0,0 @@ -#include "config.h" - -#define EXPORT(name) \ -.align 2; \ -.section ".rplTramp.text","ax"; \ - .global name; \ - name: \ - lis %r0, name##_stub@h; \ - ori %r0, %r0, name##_stub@l; \ - mtctr %r0; \ - bctr; - -#include "exports.h" diff --git a/src/rpl/coreinit/config.h b/src/rpl/coreinit/config.h deleted file mode 100644 index d4cc3bd..0000000 --- a/src/rpl/coreinit/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "coreinit" diff --git a/src/rpl/coreinit/exports.h b/src/rpl/coreinit/exports.h deleted file mode 100644 index 512cc83..0000000 --- a/src/rpl/coreinit/exports.h +++ /dev/null @@ -1,406 +0,0 @@ -// coreinit/alarm.h -EXPORT(OSCancelAlarm); -EXPORT(OSCancelAlarms); -EXPORT(OSCreateAlarm); -EXPORT(OSCreateAlarmEx); -EXPORT(OSGetAlarmUserData); -EXPORT(OSInitAlarmQueue); -EXPORT(OSInitAlarmQueueEx); -EXPORT(OSSetAlarm); -EXPORT(OSSetPeriodicAlarm); -EXPORT(OSSetAlarmTag); -EXPORT(OSSetAlarmUserData); -EXPORT(OSWaitAlarm); - -// coreinit/atomic.h -EXPORT(OSCompareAndSwapAtomic); -EXPORT(OSCompareAndSwapAtomicEx); -EXPORT(OSSwapAtomic); -EXPORT(OSAddAtomic); -EXPORT(OSAndAtomic); -EXPORT(OSOrAtomic); -EXPORT(OSXorAtomic); -EXPORT(OSTestAndClearAtomic); -EXPORT(OSTestAndSetAtomic); - -// coreinit/atomic64.h -EXPORT(OSGetAtomic64); -EXPORT(OSSetAtomic64); -EXPORT(OSCompareAndSwapAtomic64); -EXPORT(OSCompareAndSwapAtomicEx64); -EXPORT(OSSwapAtomic64); -EXPORT(OSAddAtomic64); -EXPORT(OSAndAtomic64); -EXPORT(OSOrAtomic64); -EXPORT(OSXorAtomic64); -EXPORT(OSTestAndClearAtomic64); -EXPORT(OSTestAndSetAtomic64); - -// coreinit/baseheap.h -EXPORT(MEMGetArena); -EXPORT(MEMGetBaseHeapHandle); -EXPORT(MEMSetBaseHeapHandle); - -// coreinit/blockheap.h -EXPORT(MEMInitBlockHeap); -EXPORT(MEMDestroyBlockHeap); -EXPORT(MEMAddBlockHeapTracking); -EXPORT(MEMAllocFromBlockHeapAt); -EXPORT(MEMAllocFromBlockHeapEx); -EXPORT(MEMFreeToBlockHeap); -EXPORT(MEMGetAllocatableSizeForBlockHeapEx); -EXPORT(MEMGetTrackingLeftInBlockHeap); -EXPORT(MEMGetTotalFreeSizeForBlockHeap); - -// coreinit/cache.h -EXPORT(DCInvalidateRange); -EXPORT(DCFlushRange); -EXPORT(DCStoreRange); -EXPORT(DCFlushRangeNoSync); -EXPORT(DCStoreRangeNoSync); -EXPORT(DCZeroRange); -EXPORT(DCTouchRange); -EXPORT(ICInvalidateRange); - -// coreinit/condition.h -EXPORT(OSInitCond); -EXPORT(OSInitCondEx); -EXPORT(OSWaitCond); -EXPORT(OSSignalCond); - -// coreinit/core.h -EXPORT(OSGetCoreCount); -EXPORT(OSGetCoreId); -EXPORT(OSGetMainCoreId); -EXPORT(OSIsMainCore); - -// coreinit/coroutine.h -EXPORT(OSInitCoroutine); -EXPORT(OSLoadCoroutine); -EXPORT(OSSaveCoroutine); -EXPORT(OSSwitchCoroutine); - -// coreinit/debug.h -EXPORT(OSConsoleWrite); -EXPORT(OSReport); -EXPORT(OSPanic); -EXPORT(OSFatal); -EXPORT(OSGetSymbolName); -EXPORT(OSGetUPID); -EXPORT(DisassemblePPCRange); - -// coreinit/dynload.h -EXPORT(OSDynLoad_SetAllocator); -EXPORT(OSDynLoad_GetAllocator); -EXPORT(OSDynLoad_Acquire); -EXPORT(OSDynLoad_FindExport); -EXPORT(OSDynLoad_Release); - -// coreinit/event.h -EXPORT(OSInitEvent); -EXPORT(OSInitEventEx); -EXPORT(OSSignalEvent); -EXPORT(OSSignalEventAll); -EXPORT(OSWaitEvent); -EXPORT(OSResetEvent); -EXPORT(OSWaitEventWithTimeout); - -// coreinit/exception.h -EXPORT(OSSetExceptionCallback); -EXPORT(OSSetExceptionCallbackEx); - -// coreinit/exit.h -EXPORT(exit); -EXPORT(_Exit); - -// coreinit/expandedheap.h -EXPORT(MEMCreateExpHeapEx); -EXPORT(MEMDestroyExpHeap); -EXPORT(MEMAllocFromExpHeapEx); -EXPORT(MEMFreeToExpHeap); -EXPORT(MEMSetAllocModeForExpHeap); -EXPORT(MEMGetAllocModeForExpHeap); -EXPORT(MEMAdjustExpHeap); -EXPORT(MEMResizeForMBlockExpHeap); -EXPORT(MEMGetTotalFreeSizeForExpHeap); -EXPORT(MEMGetAllocatableSizeForExpHeapEx); -EXPORT(MEMSetGroupIDForExpHeap); -EXPORT(MEMGetGroupIDForExpHeap); -EXPORT(MEMGetSizeForMBlockExpHeap); -EXPORT(MEMGetGroupIDForMBlockExpHeap); -EXPORT(MEMGetAllocDirForMBlockExpHeap); - -// coreinit/fastcondition.h -EXPORT(OSFastCond_Init); -EXPORT(OSFastCond_Wait); -EXPORT(OSFastCond_Signal); - -// coreinit/fastmutex.h -EXPORT(OSFastMutex_Init); -EXPORT(OSFastMutex_Lock); -EXPORT(OSFastMutex_Unlock); -EXPORT(OSFastMutex_TryLock); - -// coreinit/filesystem.h -EXPORT(FSInit); -EXPORT(FSShutdown); -EXPORT(FSAddClient); -EXPORT(FSDelClient); -EXPORT(FSGetClientNum); -EXPORT(FSInitCmdBlock); -EXPORT(FSSetCmdPriority); -EXPORT(FSSetStateChangeNotification); -EXPORT(FSGetCwd); -EXPORT(FSChangeDir); -EXPORT(FSChangeDirAsync); -EXPORT(FSChangeMode); -EXPORT(FSChangeModeAsync); -EXPORT(FSGetFreeSpaceSize); -EXPORT(FSGetFreeSpaceSizeAsync); -EXPORT(FSGetStat); -EXPORT(FSGetStatAsync); -EXPORT(FSRemove); -EXPORT(FSRemoveAsync); -EXPORT(FSOpenFile); -EXPORT(FSOpenFileAsync); -EXPORT(FSCloseFile); -EXPORT(FSCloseFileAsync); -EXPORT(FSOpenDir); -EXPORT(FSOpenDirAsync); -EXPORT(FSMakeDir); -EXPORT(FSMakeDirAsync); -EXPORT(FSReadDir); -EXPORT(FSReadDirAsync); -EXPORT(FSRewindDir); -EXPORT(FSCloseDir); -EXPORT(FSCloseDirAsync); -EXPORT(FSGetStatFile); -EXPORT(FSGetStatFileAsync); -EXPORT(FSReadFile); -EXPORT(FSReadFileAsync); -EXPORT(FSReadFileWithPos); -EXPORT(FSReadFileWithPosAsync); -EXPORT(FSWriteFile); -EXPORT(FSWriteFileAsync); -EXPORT(FSWriteFileWithPos); -EXPORT(FSWriteFileWithPosAsync); -EXPORT(FSGetPosFile); -EXPORT(FSGetPosFileAsync); -EXPORT(FSSetPosFile); -EXPORT(FSSetPosFileAsync); -EXPORT(FSFlushFile); -EXPORT(FSFlushFileAsync); -EXPORT(FSTruncateFile); -EXPORT(FSTruncateFileAsync); -EXPORT(FSRename); -EXPORT(FSRenameAsync); -EXPORT(FSGetVolumeState); -EXPORT(FSGetLastErrorCodeForViewer); -EXPORT(FSGetMountSource); -EXPORT(FSMount); -EXPORT(FSUnmount); -EXPORT(FSBindMount); -EXPORT(FSBindUnmount); - -// coreinit/foreground.h -EXPORT(OSEnableForegroundExit); -EXPORT(OSReleaseForeground); -EXPORT(OSSavesDone_ReadyToRelease); - -// coreinit/frameheap.h -EXPORT(MEMCreateFrmHeapEx); -EXPORT(MEMDestroyFrmHeap); -EXPORT(MEMAllocFromFrmHeapEx); -EXPORT(MEMFreeToFrmHeap); -EXPORT(MEMRecordStateForFrmHeap); -EXPORT(MEMFreeByStateToFrmHeap); -EXPORT(MEMAdjustFrmHeap); -EXPORT(MEMResizeForMBlockFrmHeap); -EXPORT(MEMGetAllocatableSizeForFrmHeapEx); - -// coreinit/ios.h -EXPORT(IOS_Open); -EXPORT(IOS_OpenAsync); -EXPORT(IOS_Close); -EXPORT(IOS_CloseAsync); -EXPORT(IOS_Ioctl); -EXPORT(IOS_IoctlAsync); -EXPORT(IOS_Ioctlv); -EXPORT(IOS_IoctlvAsync); - -// coreinit/mcp.h -EXPORT(MCP_Open); -EXPORT(MCP_Close); -EXPORT(MCP_InstallSetTargetDevice); -EXPORT(MCP_InstallGetTargetDevice); -EXPORT(MCP_InstallSetTargetUsb); -EXPORT(MCP_InstallGetInfo); -EXPORT(MCP_InstallTitleAsync); -EXPORT(MCP_InstallGetProgress); -EXPORT(MCP_InstallTitleAbort); -EXPORT(MCP_DeleteTitleAsync); -EXPORT(MCP_DeviceList); -EXPORT(MCP_FullDeviceList); - -// coreinit/memheap.h -EXPORT(MEMDumpHeap); -EXPORT(MEMFindContainHeap); -EXPORT(MEMGetFillValForHeap); -EXPORT(MEMSetFillValForHeap); - -// coreinit/memlist.h -EXPORT(MEMInitList); -EXPORT(MEMAppendListObject); -EXPORT(MEMPrependListObject); -EXPORT(MEMInsertListObject); -EXPORT(MEMRemoveListObject); -EXPORT(MEMGetNextListObject); -EXPORT(MEMGetPrevListObject); -EXPORT(MEMGetNthListObject); - -// coreinit/memory.h -EXPORT(OSBlockMove); -EXPORT(OSBlockSet); -EXPORT(OSEffectiveToPhysical); -EXPORT(OSAllocFromSystem); -EXPORT(OSFreeToSystem); - -// coreinit/messagequeue.h -EXPORT(OSInitMessageQueue); -EXPORT(OSInitMessageQueueEx); -EXPORT(OSSendMessage); -EXPORT(OSReceiveMessage); -EXPORT(OSPeekMessage); -EXPORT(OSGetSystemMessageQueue); - -// coreinit/mutex.h -EXPORT(OSInitMutex); -EXPORT(OSInitMutexEx); -EXPORT(OSLockMutex); -EXPORT(OSUnlockMutex); -EXPORT(OSTryLockMutex); - -// coreinit/rendezvous.h -EXPORT(OSInitRendezvous); -EXPORT(OSWaitRendezvous); -EXPORT(OSWaitRendezvousWithTimeout); - -// coreinit/screen.h -EXPORT(OSScreenInit); -EXPORT(OSScreenShutdown); -EXPORT(OSScreenGetBufferSizeEx); -EXPORT(OSScreenSetBufferEx); -EXPORT(OSScreenClearBufferEx); -EXPORT(OSScreenFlipBuffersEx); -EXPORT(OSScreenPutFontEx); -EXPORT(OSScreenPutPixelEx); -EXPORT(OSScreenEnableEx); - -// coreinit/semaphore.h -EXPORT(OSInitSemaphore); -EXPORT(OSInitSemaphoreEx); -EXPORT(OSGetSemaphoreCount); -EXPORT(OSSignalSemaphore); -EXPORT(OSWaitSemaphore); -EXPORT(OSTryWaitSemaphore); - -// coreinit/spinlock.h -EXPORT(OSInitSpinLock); -EXPORT(OSAcquireSpinLock); -EXPORT(OSTryAcquireSpinLock); -EXPORT(OSTryAcquireSpinLockWithTimeout); -EXPORT(OSReleaseSpinLock); -EXPORT(OSUninterruptibleSpinLock_Acquire); -EXPORT(OSUninterruptibleSpinLock_TryAcquire); -EXPORT(OSUninterruptibleSpinLock_TryAcquireWithTimeout); -EXPORT(OSUninterruptibleSpinLock_Release); - -// coreinit/systeminfo.h -EXPORT(OSGetSystemInfo); -EXPORT(OSEnableHomeButtonMenu); -EXPORT(OSIsHomeButtonMenuEnabled); - -// coreinit/taskqueue.h -EXPORT(MPInitTaskQ); -EXPORT(MPTermTaskQ); -EXPORT(MPGetTaskQInfo); -EXPORT(MPStartTaskQ); -EXPORT(MPStopTaskQ); -EXPORT(MPResetTaskQ); -EXPORT(MPEnqueTask); -EXPORT(MPDequeTask); -EXPORT(MPDequeTasks); -EXPORT(MPWaitTaskQ); -EXPORT(MPWaitTaskQWithTimeout); -EXPORT(MPPrintTaskQStats); -EXPORT(MPInitTask); -EXPORT(MPTermTask); -EXPORT(MPGetTaskInfo); -EXPORT(MPGetTaskUserData); -EXPORT(MPSetTaskUserData); -EXPORT(MPRunTasksFromTaskQ); -EXPORT(MPRunTask); - -// coreinit/thread.h -EXPORT(OSCancelThread); -EXPORT(OSCheckActiveThreads); -EXPORT(OSCheckThreadStackUsage); -EXPORT(OSClearThreadStackUsage); -EXPORT(OSContinueThread); -EXPORT(OSCreateThread); -EXPORT(OSDetachThread); -EXPORT(OSExitThread); -EXPORT(OSGetActiveThreadLink); -EXPORT(OSGetCurrentThread); -EXPORT(OSGetDefaultThread); -EXPORT(OSGetStackPointer); -EXPORT(OSGetThreadAffinity); -EXPORT(OSGetThreadName); -EXPORT(OSGetThreadPriority); -EXPORT(OSGetThreadSpecific); -EXPORT(OSIsThreadSuspended); -EXPORT(OSIsThreadTerminated); -EXPORT(OSJoinThread); -EXPORT(OSResumeThread); -EXPORT(OSRunThread); -EXPORT(OSSetThreadAffinity); -EXPORT(OSSetThreadCancelState); -EXPORT(OSSetThreadCleanupCallback); -EXPORT(OSSetThreadDeallocator); -EXPORT(OSSetThreadName); -EXPORT(OSSetThreadPriority); -EXPORT(OSSetThreadRunQuantum); -EXPORT(OSSetThreadSpecific); -EXPORT(OSSetThreadStackUsage); -EXPORT(OSSleepThread); -EXPORT(OSSleepTicks); -EXPORT(OSSuspendThread); -EXPORT(OSTestThreadCancel); -EXPORT(OSWakeupThread); -EXPORT(OSYieldThread); - -// coreinit/threadqueue.h -EXPORT(OSInitThreadQueue); -EXPORT(OSInitThreadQueueEx); - -// coreinit/time.h -EXPORT(OSGetTime); -EXPORT(OSGetSystemTime); -EXPORT(OSGetTick); -EXPORT(OSGetSystemTick); -EXPORT(OSCalendarTimeToTicks); -EXPORT(OSTicksToCalendarTime); - -// coreinit/unitheap.h -EXPORT(MEMCreateUnitHeapEx); -EXPORT(MEMDestroyUnitHeap); -EXPORT(MEMAllocFromUnitHeap); -EXPORT(MEMFreeToUnitHeap); -EXPORT(MEMCountFreeBlockForUnitHeap); -EXPORT(MEMCalcHeapSizeForUnitHeap); - -// coreinit/title.h -EXPORT(OSGetTitleID); - -// coreinit/internal.h -EXPORT(__os_snprintf); diff --git a/src/rpl/gx2/config.h b/src/rpl/gx2/config.h deleted file mode 100644 index 9e7fa8d..0000000 --- a/src/rpl/gx2/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "gx2" diff --git a/src/rpl/gx2/exports.h b/src/rpl/gx2/exports.h deleted file mode 100644 index 39bcba1..0000000 --- a/src/rpl/gx2/exports.h +++ /dev/null @@ -1,243 +0,0 @@ -// gx2/clear.h -EXPORT(GX2ClearColor); -EXPORT(GX2ClearDepthStencilEx); -EXPORT(GX2ClearBuffersEx); -EXPORT(GX2SetClearDepth); -EXPORT(GX2SetClearStencil); -EXPORT(GX2SetClearDepthStencil); - -// gx2/context.h -EXPORT(GX2SetupContextStateEx); -EXPORT(GX2GetContextStateDisplayList); -EXPORT(GX2SetContextState); -EXPORT(GX2SetDefaultState); - -// gx2/display.h -EXPORT(GX2SetTVEnable); -EXPORT(GX2SetDRCEnable); -EXPORT(GX2CalcTVSize); -EXPORT(GX2SetTVBuffer); -EXPORT(GX2SetTVScale); -EXPORT(GX2CalcDRCSize); -EXPORT(GX2SetDRCBuffer); -EXPORT(GX2SetDRCScale); -EXPORT(GX2GetSystemTVScanMode); -EXPORT(GX2GetSystemDRCMode); -EXPORT(GX2GetSystemDRCScanMode); - -// gx2/displaylist.h -EXPORT(GX2BeginDisplayListEx); -EXPORT(GX2EndDisplayList); -EXPORT(GX2DirectCallDisplayList); -EXPORT(GX2CallDisplayList); -EXPORT(GX2GetDisplayListWriteStatus); -EXPORT(GX2GetCurrentDisplayList); -EXPORT(GX2CopyDisplayList); - -// gx2/draw.h -EXPORT(GX2SetAttribBuffer); -EXPORT(GX2DrawEx); -EXPORT(GX2DrawEx2); -EXPORT(GX2DrawIndexedEx); -EXPORT(GX2DrawIndexedEx2); -EXPORT(GX2DrawIndexedImmediateEx); -EXPORT(GX2SetPrimitiveRestartIndex); - -// gx2/event.h -EXPORT(GX2DrawDone); -EXPORT(GX2WaitForVsync); -EXPORT(GX2WaitForFlip); -EXPORT(GX2SetEventCallback); -EXPORT(GX2GetEventCallback); -EXPORT(GX2GetRetiredTimeStamp); -EXPORT(GX2GetLastSubmittedTimeStamp); -EXPORT(GX2GetSwapStatus); -EXPORT(GX2WaitTimeStamp); - -// gx2/mem.h -EXPORT(GX2Invalidate); - -// gx2/registers.h -EXPORT(GX2SetAAMask); -EXPORT(GX2InitAAMaskReg); -EXPORT(GX2GetAAMaskReg); -EXPORT(GX2SetAAMaskReg); -EXPORT(GX2SetAlphaTest); -EXPORT(GX2InitAlphaTestReg); -EXPORT(GX2GetAlphaTestReg); -EXPORT(GX2SetAlphaTestReg); -EXPORT(GX2SetAlphaToMask); -EXPORT(GX2InitAlphaToMaskReg); -EXPORT(GX2GetAlphaToMaskReg); -EXPORT(GX2SetAlphaToMaskReg); -EXPORT(GX2SetBlendConstantColor); -EXPORT(GX2InitBlendConstantColorReg); -EXPORT(GX2GetBlendConstantColorReg); -EXPORT(GX2SetBlendConstantColorReg); -EXPORT(GX2SetBlendControl); -EXPORT(GX2InitBlendControlReg); -EXPORT(GX2GetBlendControlReg); -EXPORT(GX2SetBlendControlReg); -EXPORT(GX2SetColorControl); -EXPORT(GX2InitColorControlReg); -EXPORT(GX2GetColorControlReg); -EXPORT(GX2SetColorControlReg); -EXPORT(GX2SetDepthOnlyControl); -EXPORT(GX2SetDepthStencilControl); -EXPORT(GX2InitDepthStencilControlReg); -EXPORT(GX2GetDepthStencilControlReg); -EXPORT(GX2SetDepthStencilControlReg); -EXPORT(GX2SetStencilMask); -EXPORT(GX2InitStencilMaskReg); -EXPORT(GX2GetStencilMaskReg); -EXPORT(GX2SetStencilMaskReg); -EXPORT(GX2SetLineWidth); -EXPORT(GX2InitLineWidthReg); -EXPORT(GX2GetLineWidthReg); -EXPORT(GX2SetLineWidthReg); -EXPORT(GX2SetPointSize); -EXPORT(GX2InitPointSizeReg); -EXPORT(GX2GetPointSizeReg); -EXPORT(GX2SetPointSizeReg); -EXPORT(GX2SetPointLimits); -EXPORT(GX2InitPointLimitsReg); -EXPORT(GX2GetPointLimitsReg); -EXPORT(GX2SetPointLimitsReg); -EXPORT(GX2SetCullOnlyControl); -EXPORT(GX2SetPolygonControl); -EXPORT(GX2InitPolygonControlReg); -EXPORT(GX2SetPolygonControlReg); -EXPORT(GX2SetPolygonOffset); -EXPORT(GX2InitPolygonOffsetReg); -EXPORT(GX2GetPolygonOffsetReg); -EXPORT(GX2SetPolygonOffsetReg); -EXPORT(GX2SetScissor); -EXPORT(GX2InitScissorReg); -EXPORT(GX2GetScissorReg); -EXPORT(GX2SetScissorReg); -EXPORT(GX2SetTargetChannelMasks); -EXPORT(GX2InitTargetChannelMasksReg); -EXPORT(GX2GetTargetChannelMasksReg); -EXPORT(GX2SetTargetChannelMasksReg); -EXPORT(GX2SetViewport); -EXPORT(GX2InitViewportReg); -EXPORT(GX2GetViewportReg); -EXPORT(GX2SetViewportReg); - -// gx2/sampler.h -EXPORT(GX2InitSampler); -EXPORT(GX2InitSamplerBorderType); -EXPORT(GX2InitSamplerClamping); -EXPORT(GX2InitSamplerDepthCompare); -EXPORT(GX2InitSamplerFilterAdjust); -EXPORT(GX2InitSamplerLOD); -EXPORT(GX2InitSamplerLODAdjust); -EXPORT(GX2InitSamplerRoundingMode); -EXPORT(GX2InitSamplerXYFilter); -EXPORT(GX2InitSamplerZMFilter); - -// gx2/state.h -EXPORT(GX2Flush); -EXPORT(GX2Init); -EXPORT(GX2Shutdown); -EXPORT(GX2ResetGPU); - -// gx2/shader.h -EXPORT(GX2CalcGeometryShaderInputRingBufferSize); -EXPORT(GX2CalcGeometryShaderOutputRingBufferSize); -EXPORT(GX2CalcFetchShaderSizeEx); -EXPORT(GX2InitFetchShaderEx); -EXPORT(GX2SetFetchShader); -EXPORT(GX2SetVertexShader); -EXPORT(GX2SetPixelShader); -EXPORT(GX2SetGeometryShader); -EXPORT(GX2SetVertexSampler); -EXPORT(GX2SetPixelSampler); -EXPORT(GX2SetGeometrySampler); -EXPORT(GX2SetVertexUniformReg); -EXPORT(GX2SetPixelUniformReg); -EXPORT(GX2SetVertexUniformBlock); -EXPORT(GX2SetPixelUniformBlock); -EXPORT(GX2SetGeometryUniformBlock); -EXPORT(GX2SetShaderModeEx); -EXPORT(GX2SetStreamOutEnable); -EXPORT(GX2SetGeometryShaderInputRingBuffer); -EXPORT(GX2SetGeometryShaderOutputRingBuffer); -EXPORT(GX2GetPixelShaderGPRs); -EXPORT(GX2GetPixelShaderStackEntries); -EXPORT(GX2GetVertexShaderGPRs); -EXPORT(GX2GetVertexShaderStackEntries); -EXPORT(GX2GetGeometryShaderGPRs); -EXPORT(GX2GetGeometryShaderStackEntries); - -// gx2/surface.h -EXPORT(GX2CalcColorBufferAuxInfo); -EXPORT(GX2CalcSurfaceSizeAndAlignment); -EXPORT(GX2CalcDepthBufferHiZInfo); -EXPORT(GX2SetColorBuffer); -EXPORT(GX2SetDepthBuffer); -EXPORT(GX2InitColorBufferRegs); -EXPORT(GX2InitDepthBufferRegs); -EXPORT(GX2InitDepthBufferHiZEnable); -EXPORT(GX2GetSurfaceSwizzle); -EXPORT(GX2SetSurfaceSwizzle); -EXPORT(GX2CopySurface); - -// gx2/swap.h -EXPORT(GX2CopyColorBufferToScanBuffer); -EXPORT(GX2SwapScanBuffers); -EXPORT(GX2GetLastFrame); -EXPORT(GX2GetLastFrameGamma); -EXPORT(GX2GetSwapInterval); -EXPORT(GX2SetSwapInterval); - -// gx2/tessellation.h -EXPORT(GX2SetTessellation); -EXPORT(GX2SetMinTessellationLevel); -EXPORT(GX2SetMaxTessellationLevel); - -// gx2/temp.h -EXPORT(GX2TempGetGPUVersion); - -// gx2/texture.h -EXPORT(GX2InitTextureRegs); -EXPORT(GX2SetPixelTexture); -EXPORT(GX2SetVertexTexture); -EXPORT(GX2SetGeometryTexture); - -// gx2r/buffer.h -EXPORT(GX2RBufferExists); -EXPORT(GX2RCreateBuffer); -EXPORT(GX2RCreateBufferUserMemory); -EXPORT(GX2RDestroyBufferEx); -EXPORT(GX2RGetBufferAlignment); -EXPORT(GX2RGetBufferAllocationSize); -EXPORT(GX2RInvalidateBuffer); -EXPORT(GX2RLockBufferEx); -EXPORT(GX2RUnlockBufferEx); -EXPORT(GX2RSetVertexUniformBlock); -EXPORT(GX2RSetPixelUniformBlock); -EXPORT(GX2RSetGeometryUniformBlock); - -// gx2r/displaylist.h -EXPORT(GX2RBeginDisplayListEx); -EXPORT(GX2REndDisplayList); -EXPORT(GX2RCallDisplayList); -EXPORT(GX2RDirectCallDisplayList); - -// gx2r/draw.h -EXPORT(GX2RSetAttributeBuffer); -EXPORT(GX2RDrawIndexed); - -// gx2r/mem.h -EXPORT(GX2RInvalidateMemory); -EXPORT(GX2RIsUserMemory); -EXPORT(GX2RSetAllocator); - -// gx2r/surface.h -EXPORT(GX2RCreateSurface); -EXPORT(GX2RCreateSurfaceUserMemory); -EXPORT(GX2RDestroySurfaceEx); -EXPORT(GX2RInvalidateSurface); -EXPORT(GX2RLockSurfaceEx); -EXPORT(GX2RUnlockSurfaceEx); diff --git a/src/rpl/nn_ac/config.h b/src/rpl/nn_ac/config.h deleted file mode 100644 index ffbd0fb..0000000 --- a/src/rpl/nn_ac/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "nn_ac" diff --git a/src/rpl/nn_ac/exports.h b/src/rpl/nn_ac/exports.h deleted file mode 100644 index b8fcb33..0000000 --- a/src/rpl/nn_ac/exports.h +++ /dev/null @@ -1,6 +0,0 @@ -// nn_ac/nn_ac.h -EXPORT(ACInitialize); -EXPORT(ACFinalize); -EXPORT(ACGetStartupId); -EXPORT(ACConnectWithConfigId); -EXPORT(ACGetAssignedAddress); diff --git a/src/rpl/nsysnet/config.h b/src/rpl/nsysnet/config.h deleted file mode 100644 index 3483aa4..0000000 --- a/src/rpl/nsysnet/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "nsysnet" diff --git a/src/rpl/nsysnet/exports.h b/src/rpl/nsysnet/exports.h deleted file mode 100644 index f4c7fcc..0000000 --- a/src/rpl/nsysnet/exports.h +++ /dev/null @@ -1,35 +0,0 @@ -// nsysnet/socket.h -EXPORT(socket_lib_init); -EXPORT(socket_lib_finish); -EXPORT(socket); -EXPORT(socketclose); -EXPORT(connect); -EXPORT(bind); -EXPORT(listen); -EXPORT(accept); -EXPORT(send); -EXPORT(recv); -EXPORT(sendto); -EXPORT(setsockopt); -EXPORT(recvfrom); -EXPORT(recvfrom_ex); -EXPORT(recvfrom_multi); -EXPORT(sendto_multi); -EXPORT(sendto_multi_ex); -EXPORT(shutdown); -EXPORT(inet_aton); -EXPORT(inet_ntoa); -EXPORT(inet_ntoa_r); -EXPORT(inet_ntop); -EXPORT(inet_pton); -EXPORT(getpeername); -EXPORT(getsockname); -EXPORT(getsockopt); -EXPORT(select); -EXPORT(setsocklibopt); -EXPORT(getsocklibopt); -EXPORT(ntohl); -EXPORT(htonl); -EXPORT(ntohs); -EXPORT(htons); -EXPORT(socketlasterr); diff --git a/src/rpl/proc_ui/config.h b/src/rpl/proc_ui/config.h deleted file mode 100644 index ee3f41c..0000000 --- a/src/rpl/proc_ui/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "proc_ui" diff --git a/src/rpl/proc_ui/exports.h b/src/rpl/proc_ui/exports.h deleted file mode 100644 index 8c58339..0000000 --- a/src/rpl/proc_ui/exports.h +++ /dev/null @@ -1,16 +0,0 @@ -// procui/procui.h -EXPORT(ProcUICalcMemorySize); -EXPORT(ProcUIClearCallbacks); -EXPORT(ProcUIDrawDoneRelease); -EXPORT(ProcUIInForeground); -EXPORT(ProcUIInShutdown); -EXPORT(ProcUIInit); -EXPORT(ProcUIInitEx); -EXPORT(ProcUIIsRunning); -EXPORT(ProcUIProcessMessages); -EXPORT(ProcUIRegisterCallback); -EXPORT(ProcUIRegisterCallbackCore); -EXPORT(ProcUISetSaveCallback); -EXPORT(ProcUIShutdown); -EXPORT(ProcUISubProcessMessages); - diff --git a/src/rpl/sndcore2/config.h b/src/rpl/sndcore2/config.h deleted file mode 100644 index 815c97d..0000000 --- a/src/rpl/sndcore2/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "sndcore2" diff --git a/src/rpl/sndcore2/exports.h b/src/rpl/sndcore2/exports.h deleted file mode 100644 index 3fd26c1..0000000 --- a/src/rpl/sndcore2/exports.h +++ /dev/null @@ -1,65 +0,0 @@ -// sndcore2/core.h -EXPORT(AXInit); -EXPORT(AXInitWithParams); -EXPORT(AXIsInit); -EXPORT(AXInitProfile); -EXPORT(AXGetSwapProfile); -EXPORT(AXSetDefaultMixerSelect); -EXPORT(AXRegisterAppFrameCallback); -EXPORT(AXGetInputSamplesPerFrame); -EXPORT(AXGetInputSamplesPerSec); -EXPORT(AXQuit); - -// sndcore2/device.h -EXPORT(AXGetDeviceMode); -EXPORT(AXGetDeviceFinalMixCallback); -EXPORT(AXRegisterDeviceFinalMixCallback); -EXPORT(AXGetAuxCallback); -EXPORT(AXRegisterAuxCallback); -EXPORT(AXSetDeviceLinearUpsampler); -EXPORT(AXSetDeviceCompressor); -EXPORT(AXSetDeviceUpsampleStage); -EXPORT(AXSetDeviceVolume); - -// sndcore2/drcvs.h -EXPORT(AXGetDRCVSMode); -EXPORT(AXSetDRCVSMode); -EXPORT(AXSetDRCVSDownmixBalance); -EXPORT(AXSetDRCVSLC); -EXPORT(AXSetDRCVSLimiter); -EXPORT(AXSetDRCVSLimiterThreshold); -EXPORT(AXSetDRCVSOutputGain); -EXPORT(AXSetDRCVSSpeakerPosition); -EXPORT(AXSetDRCVSSurroundDepth); -EXPORT(AXSetDRCVSSurroundLevelGain); - -// sndcore2/voice.h -EXPORT(AXAcquireVoice); -EXPORT(AXAcquireVoiceEx); -EXPORT(AXCheckVoiceOffsets); -EXPORT(AXFreeVoice); -EXPORT(AXGetMaxVoices); -EXPORT(AXGetVoiceCurrentOffsetEx); -EXPORT(AXGetVoiceLoopCount); -EXPORT(AXGetVoiceOffsets); -EXPORT(AXIsVoiceRunning); -EXPORT(AXSetVoiceAdpcm); -EXPORT(AXSetVoiceAdpcmLoop); -EXPORT(AXSetVoiceCurrentOffset); -EXPORT(AXSetVoiceDeviceMix); -EXPORT(AXSetVoiceEndOffset); -EXPORT(AXSetVoiceEndOffsetEx); -EXPORT(AXSetVoiceInitialTimeDelay); -EXPORT(AXSetVoiceLoopOffset); -EXPORT(AXSetVoiceLoopOffsetEx); -EXPORT(AXSetVoiceLoop); -EXPORT(AXSetVoiceOffsets); -EXPORT(AXSetVoicePriority); -EXPORT(AXSetVoiceRmtIIRCoefs); -EXPORT(AXSetVoiceSrc); -EXPORT(AXSetVoiceSrcRatio); -EXPORT(AXSetVoiceSrcType); -EXPORT(AXSetVoiceState); -EXPORT(AXSetVoiceType); -EXPORT(AXSetVoiceVe); -EXPORT(AXSetVoiceVeDelta); diff --git a/src/rpl/sysapp/config.h b/src/rpl/sysapp/config.h deleted file mode 100644 index 5d2d5d1..0000000 --- a/src/rpl/sysapp/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "sysapp" diff --git a/src/rpl/sysapp/exports.h b/src/rpl/sysapp/exports.h deleted file mode 100644 index 54efae3..0000000 --- a/src/rpl/sysapp/exports.h +++ /dev/null @@ -1,15 +0,0 @@ -// sysapp/switch.h -EXPORT(SYSSwitchToSyncControllerOnHBM); -EXPORT(SYSSwitchToEManual); -EXPORT(SYSSwitchToEShop); -EXPORT(_SYSSwitchToMainApp); -EXPORT(SYSSwitchToBrowserForViewer); - -// sysapp/launch.h -EXPORT(SYSRelaunchTitle); -EXPORT(SYSLaunchMenu); -EXPORT(SYSLaunchTitle); -EXPORT(_SYSLaunchMiiStudio); -EXPORT(_SYSLaunchSettings); -EXPORT(_SYSLaunchParental); -EXPORT(_SYSLaunchNotifications); diff --git a/src/rpl/vpad/config.h b/src/rpl/vpad/config.h deleted file mode 100644 index 72607da..0000000 --- a/src/rpl/vpad/config.h +++ /dev/null @@ -1 +0,0 @@ -#define LIBRARY_NAME "vpad" diff --git a/src/rpl/vpad/exports.h b/src/rpl/vpad/exports.h deleted file mode 100644 index 9d417d6..0000000 --- a/src/rpl/vpad/exports.h +++ /dev/null @@ -1,5 +0,0 @@ -// vpad/input.h -EXPORT(VPADInit); -EXPORT(VPADShutdown); -EXPORT(VPADRead); -EXPORT(VPADGetTPCalibratedPoint); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index c2f7b66..5dc7668 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,10 +1,21 @@ cmake_minimum_required(VERSION 3.2) -project(wut-tools) +project(tools) -set(CMAKE_CXX_STANDARD 14) -include_directories("common") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest") +elseif(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") +endif() + +add_subdirectory(libraries) +find_package(ZLIB REQUIRED) + +include_directories(common) add_subdirectory(elf2rpl) -add_subdirectory(readrpl) -add_subdirectory(implcheck) -add_subdirectory(udplogserver) +add_subdirectory(rplgen) diff --git a/tools/common/be_val.h b/tools/common/be_val.h deleted file mode 100644 index 846807b..0000000 --- a/tools/common/be_val.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include -#include -#include "utils.h" - -template -class be_val -{ -public: - static_assert(!std::is_array::value, "be_val invalid type: array"); - static_assert(!std::is_pointer::value, "be_val invalid type: pointer"); - static_assert(sizeof(Type) == 1 || sizeof(Type) == 2 || sizeof(Type) == 4 || sizeof(Type) == 8, "be_val invalid type size"); - - be_val() - { - } - - be_val(Type value) - { - *this = value; - } - - Type value() const - { - return byte_swap(mValue); - } - - operator Type() const - { - return value(); - } - - template std::enable_if_t::value, be_val&> - operator =(const Other &rhs) - { - mValue = byte_swap(static_cast(rhs)); - return *this; - } - - be_val &operator++() { *this = value() + 1; return *this; } - be_val &operator--() { *this = value() - 1; return *this; } - be_val operator--(int) { auto old = *this; *this = value() - 1; return old; } - be_val operator++(int) { auto old = *this; *this = value() + 1; return old; } - - template bool operator == (const Other &rhs) const { return value() == static_cast(rhs); } - template bool operator != (const Other &rhs) const { return value() != static_cast(rhs); } - template bool operator >= (const Other &rhs) const { return value() >= static_cast(rhs); } - template bool operator <= (const Other &rhs) const { return value() <= static_cast(rhs); } - template bool operator > (const Other &rhs) const { return value() > static_cast(rhs); } - template bool operator < (const Other &rhs) const { return value() < static_cast(rhs); } - - template be_val &operator+=(const Other &rhs) { *this = static_cast(value() + rhs); return *this; } - template be_val &operator-=(const Other &rhs) { *this = static_cast(value() - rhs); return *this; } - template be_val &operator*=(const Other &rhs) { *this = static_cast(value() * rhs); return *this; } - template be_val &operator/=(const Other &rhs) { *this = static_cast(value() / rhs); return *this; } - template be_val &operator%=(const Other &rhs) { *this = static_cast(value() % rhs); return *this; } - template be_val &operator|=(const Other &rhs) { *this = static_cast(value() | rhs); return *this; } - template be_val &operator&=(const Other &rhs) { *this = static_cast(value() & rhs); return *this; } - template be_val &operator^=(const Other &rhs) { *this = static_cast(value() ^ rhs); return *this; } - - template Type operator+(const Other &rhs) const { return static_cast(value() + rhs); } - template Type operator-(const Other &rhs) const { return static_cast(value() - rhs); } - template Type operator*(const Other &rhs) const { return static_cast(value() * rhs); } - template Type operator/(const Other &rhs) const { return static_cast(value() / rhs); } - template Type operator%(const Other &rhs) const { return static_cast(value() % rhs); } - template Type operator|(const Other &rhs) const { return static_cast(value() | rhs); } - template Type operator&(const Other &rhs) const { return static_cast(value() & rhs); } - template Type operator^(const Other &rhs) const { return static_cast(value() ^ rhs); } - -protected: - Type mValue {}; -}; diff --git a/tools/common/elf.h b/tools/common/elf.h index 17a77b7..e831413 100644 --- a/tools/common/elf.h +++ b/tools/common/elf.h @@ -1,6 +1,6 @@ #pragma once #include -#include "be_val.h" +#include "utils.h" #pragma pack(push, 1) @@ -87,7 +87,7 @@ enum SectionType : uint32_t // sh_type SHT_HIUSER = 0xffffffff // Highest type reserved for applications. }; -enum SymbolBinding : uint32_t // st_info >> 4 +enum SymbolBinding : uint32_t // st_info > 4 { STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def STB_GLOBAL = 1, // Global symbol, visible to all object files being combined @@ -181,10 +181,16 @@ enum RelocationType : uint32_t // r_info & 0xff R_PPC_TLSGD = 95, R_PPC_TLSLD = 96, R_PPC_EMB_SDA21 = 109, - R_PPC_REL16 = 249, - R_PPC_REL16_LO = 250, - R_PPC_REL16_HI = 251, - R_PPC_REL16_HA = 252, + R_PPC_EMB_RELSDA = 116, + R_PPC_DIAB_SDA21_LO = 180, + R_PPC_DIAB_SDA21_HI = 181, + R_PPC_DIAB_SDA21_HA = 182, + R_PPC_DIAB_RELSDA_LO = 183, + R_PPC_DIAB_RELSDA_HI = 184, + R_PPC_DIAB_RELSDA_HA = 185, + R_PPC_GHS_REL16_HA = 251, + R_PPC_GHS_REL16_HI = 252, + R_PPC_GHS_REL16_LO = 253, }; enum RplFileInfoFlag : uint32_t @@ -196,67 +202,67 @@ static const unsigned HeaderMagic = 0x7f454c46; struct Header { - be_val magic; // File identification. - be_val fileClass; // File class. - be_val encoding; // Data encoding. - be_val elfVersion; // File version. - be_val abi; // OS/ABI identification. (EABI_*) - be_val pad[7]; + uint32_t magic; // File identification. + uint8_t fileClass; // File class. + uint8_t encoding; // Data encoding. + uint8_t elfVersion; // File version. + uint16_t abi; // OS/ABI identification. (EABI_*) + uint8_t pad[7]; - be_val type; // Type of file (ET_*) - be_val machine; // Required architecture for this file (EM_*) - be_val version; // Must be equal to 1 - be_val entry; // Address to jump to in order to start program - be_val phoff; // Program header table's file offset, in bytes - be_val shoff; // Section header table's file offset, in bytes - be_val flags; // Processor-specific flags - be_val ehsize; // Size of ELF header, in bytes - be_val phentsize; // Size of an entry in the program header table - be_val phnum; // Number of entries in the program header table - be_val shentsize; // Size of an entry in the section header table - be_val shnum; // Number of entries in the section header table - be_val shstrndx; // Sect hdr table index of sect name string table + uint16_t type; // Type of file (ET_*) + uint16_t machine; // Required architecture for this file (EM_*) + uint32_t version; // Must be equal to 1 + uint32_t entry; // Address to jump to in order to start program + uint32_t phoff; // Program header table's file offset, in bytes + uint32_t shoff; // Section header table's file offset, in bytes + uint32_t flags; // Processor-specific flags + uint16_t ehsize; // Size of ELF header, in bytes + uint16_t phentsize; // Size of an entry in the program header table + uint16_t phnum; // Number of entries in the program header table + uint16_t shentsize; // Size of an entry in the section header table + uint16_t shnum; // Number of entries in the section header table + uint16_t shstrndx; // Sect hdr table index of sect name string table }; CHECK_SIZE(Header, 0x34); struct SectionHeader { - be_val name; // Section name (index into string table) - be_val type; // Section type (SHT_*) - be_val flags; // Section flags (SHF_*) - be_val addr; // Address where section is to be loaded - be_val offset; // File offset of section data, in bytes - be_val size; // Size of section, in bytes - be_val link; // Section type-specific header table index link - be_val info; // Section type-specific extra information - be_val addralign; // Section address alignment - be_val entsize; // Size of records contained within the section + uint32_t name; // Section name (index into string table) + uint32_t type; // Section type (SHT_*) + uint32_t flags; // Section flags (SHF_*) + uint32_t addr; // Address where section is to be loaded + uint32_t offset; // File offset of section data, in bytes + uint32_t size; // Size of section, in bytes + uint32_t link; // Section type-specific header table index link + uint32_t info; // Section type-specific extra information + uint32_t addralign; // Section address alignment + uint32_t entsize; // Size of records contained within the section }; CHECK_SIZE(SectionHeader, 0x28); struct Symbol { - be_val name; // Symbol name (index into string table) - be_val value; // Value or address associated with the symbol - be_val size; // Size of the symbol - be_val info; // Symbol's type and binding attributes - be_val other; // Must be zero; reserved - be_val shndx; // Which section (header table index) it's defined in (SHN_*) + uint32_t name; // Symbol name (index into string table) + uint32_t value; // Value or address associated with the symbol + uint32_t size; // Size of the symbol + uint8_t info; // Symbol's type and binding attributes + uint8_t other; // Must be zero; reserved + uint16_t shndx; // Which section (header table index) it's defined in (SHN_*) }; CHECK_SIZE(Symbol, 0x10); struct Rela { - be_val offset; - be_val info; - be_val addend; + uint32_t offset; + uint32_t info; + int32_t addend; }; CHECK_SIZE(Rela, 0x0C); struct RplImport { - be_val count; - be_val signature; + uint32_t count; + uint32_t signature; char name[1]; }; @@ -264,48 +270,48 @@ struct RplExport { struct Export { - be_val value; - be_val name; + uint32_t value; + uint32_t name; }; - be_val count; - be_val signature; + uint32_t count; + uint32_t signature; Export exports[1]; }; struct RplCrc { - be_val crc; + uint32_t crc; }; CHECK_SIZE(RplCrc, 0x04); struct RplFileInfo { - be_val version; - be_val textSize; - be_val textAlign; - be_val dataSize; - be_val dataAlign; - be_val loadSize; - be_val loadAlign; - be_val tempSize; - be_val trampAdjust; - be_val sdaBase; - be_val sda2Base; - be_val stackSize; - be_val filename; - be_val flags; - be_val heapSize; - be_val tagOffset; - be_val minVersion; - be_val compressionLevel; - be_val trampAddition; - be_val fileInfoPad; - be_val cafeSdkVersion; - be_val cafeSdkRevision; - be_val tlsModuleIndex; - be_val tlsAlignShift; - be_val runtimeFileInfoSize; + uint32_t version; + uint32_t textSize; + uint32_t textAlign; + uint32_t dataSize; + uint32_t dataAlign; + uint32_t loadSize; + uint32_t loadAlign; + uint32_t tempSize; + uint32_t trampAdjust; + uint32_t sdaBase; + uint32_t sda2Base; + uint32_t stackSize; + uint32_t filename; + uint32_t flags; + uint32_t heapSize; + uint32_t tagOffset; + uint32_t minVersion; + int32_t compressionLevel; + uint32_t trampAddition; + uint32_t fileInfoPad; + uint32_t cafeSdkVersion; + uint32_t cafeSdkRevision; + uint16_t tlsModuleIndex; + uint16_t tlsAlignShift; + uint32_t runtimeFileInfoSize; }; CHECK_SIZE(RplFileInfo, 0x60); diff --git a/tools/elf2rpl/CMakeLists.txt b/tools/elf2rpl/CMakeLists.txt index 85acccf..51176bc 100644 --- a/tools/elf2rpl/CMakeLists.txt +++ b/tools/elf2rpl/CMakeLists.txt @@ -1,12 +1,8 @@ -project(elf2rpl) +add_executable(wut-elf2rpl main.cpp) +target_include_directories(wut-elf2rpl PRIVATE + ${ZLIB_INCLUDE_DIR}) +target_link_libraries(wut-elf2rpl + fmt + ${ZLIB_LIBRARIES}) -file(GLOB_RECURSE SOURCE_FILES *.cpp) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_executable(elf2rpl ${SOURCE_FILES} ${HEADER_FILES}) -set_target_properties(elf2rpl PROPERTIES FOLDER tools) - -target_link_libraries(elf2rpl PRIVATE - ${ZLIB_LINK}) - -install(TARGETS elf2rpl RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") +install(TARGETS wut-elf2rpl RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/tools/elf2rpl/main.cpp b/tools/elf2rpl/main.cpp index 47d8331..efb9ffb 100644 --- a/tools/elf2rpl/main.cpp +++ b/tools/elf2rpl/main.cpp @@ -1,195 +1,199 @@ +#include "elf.h" +#include "utils.h" + #include +#include #include -#include -#include +#include +#include #include #include -#include #include -#include "elf.h" -#pragma pack(push, 1) - -struct RplLibsDef -{ - be_val name; - be_val stubStart; - be_val stubEnd; -}; - -#pragma pack(pop) - -static const uint32_t LoadAddress = 0x01000000u; -static const uint32_t CodeAddress = 0x02000000u; -static const uint32_t DataAddress = 0x10000000u; -static const uint32_t WiiuLoadAddress = 0xC0000000u; +constexpr auto CodeBaseAddress = 0x02000000; +constexpr auto DataBaseAddress = 0x10000000; +constexpr auto LoadBaseAddress = 0xC0000000; struct ElfFile { - struct Symbol + struct Section { + elf::SectionHeader header; std::string name; - uint32_t address; - uint32_t size; - elf::SymbolType type; - elf::SymbolBinding binding; - uint32_t outNamePos; - }; - - struct Relocation - { - uint32_t target; - elf::RelocationType type; - - Symbol *symbol; - uint32_t addend; - }; - - struct DataSection - { - std::string name; - uint32_t address; - elf::SectionType type; - elf::SectionFlags flags; - - // Data used if type == SHT_PROGBITS std::vector data; - - // Size used if type == SHT_NOBITS - uint32_t size; }; - struct RplImport - { - Symbol *trampSymbol; - Symbol *stubSymbol; - uint32_t stubAddr; - uint32_t trampAddr; - }; - - struct RplImportLibrary - { - std::string name; - std::vector> imports; - }; - - uint32_t entryPoint; - std::vector> dataSections; - std::vector> symbols; - std::vector> relocations; - std::vector> rplImports; + elf::Header header; + std::vector> sections; }; -struct InputSection +static void +byte_swap(elf::Header &header) { - elf::SectionHeader header; - std::vector data; -}; + header.magic = byte_swap(header.magic); + header.abi = byte_swap(header.abi); + header.type = byte_swap(header.type); + header.machine = byte_swap(header.machine); + header.version = byte_swap(header.version); + header.entry = byte_swap(header.entry); + header.phoff = byte_swap(header.phoff); + header.shoff = byte_swap(header.shoff); + header.flags = byte_swap(header.flags); + header.ehsize = byte_swap(header.ehsize); + header.phentsize = byte_swap(header.phentsize); + header.phnum = byte_swap(header.phnum); + header.shentsize = byte_swap(header.shentsize); + header.shnum = byte_swap(header.shnum); + header.shstrndx = byte_swap(header.shstrndx); +} -static ElfFile::Symbol * -findSymbol(ElfFile &file, uint32_t address) + +static void +byte_swap(elf::SectionHeader &header) { - for (auto &symbol : file.symbols) { - if (symbol->address == address && symbol->type != elf::STT_NOTYPE) { - return symbol.get(); + header.name = byte_swap(header.name); + header.type = byte_swap(header.type); + header.flags = byte_swap(header.flags); + header.addr = byte_swap(header.addr); + header.offset = byte_swap(header.offset); + header.size = byte_swap(header.size); + header.link = byte_swap(header.link); + header.info = byte_swap(header.info); + header.addralign = byte_swap(header.addralign); + header.entsize = byte_swap(header.entsize); +} + + +static void +byte_swap(elf::RplFileInfo &info) +{ + info.version = byte_swap(info.version); + info.textSize = byte_swap(info.textSize); + info.textAlign = byte_swap(info.textAlign); + info.dataSize = byte_swap(info.dataSize); + info.dataAlign = byte_swap(info.dataAlign); + info.loadSize = byte_swap(info.loadSize); + info.loadAlign = byte_swap(info.loadAlign); + info.tempSize = byte_swap(info.tempSize); + info.trampAdjust = byte_swap(info.trampAdjust); + info.sdaBase = byte_swap(info.sdaBase); + info.sda2Base = byte_swap(info.sda2Base); + info.stackSize = byte_swap(info.stackSize); + info.filename = byte_swap(info.filename); + info.flags = byte_swap(info.flags); + info.heapSize = byte_swap(info.heapSize); + info.tagOffset = byte_swap(info.tagOffset); + info.minVersion = byte_swap(info.minVersion); + info.compressionLevel = byte_swap(info.compressionLevel); + info.trampAddition = byte_swap(info.trampAddition); + info.fileInfoPad = byte_swap(info.fileInfoPad); + info.cafeSdkVersion = byte_swap(info.cafeSdkVersion); + info.cafeSdkRevision = byte_swap(info.cafeSdkRevision); + info.tlsModuleIndex = byte_swap(info.tlsModuleIndex); + info.tlsAlignShift = byte_swap(info.tlsAlignShift); + info.runtimeFileInfoSize = byte_swap(info.runtimeFileInfoSize); +} + +static int +getSectionIndex(ElfFile &file, const char *name) +{ + int index = 0; + for (const auto §ion : file.sections) { + if (section->name == name) { + return index; } + + ++index; } - for (auto &symbol : file.symbols) { - if (symbol->address == address) { - return symbol.get(); + return -1; +} + + +static ElfFile::Section * +getSectionByType(ElfFile &file, elf::SectionType type) +{ + for (const auto §ion : file.sections) { + if (section->header.type == type) { + return section.get(); } } return nullptr; } -static ElfFile::RplImport * -findImport(ElfFile &file, uint32_t address) + +static ElfFile::Section * +getSectionByName(ElfFile &file, const char *name) { - for (auto &lib : file.rplImports) { - for (auto &import : lib->imports) { - if (import->stubAddr == address || import->trampAddr == address) { - return import.get(); - } - } + auto index = getSectionIndex(file, name); + if (index == -1) { + return nullptr; } - return nullptr; + return file.sections[index].get(); } -template -static Type * -getLoaderDataPtr(std::vector &inSections, uint32_t address) + +// https://stackoverflow.com/a/16569749 +template +bool begins_with(const TContainer& input, const TContainer& match) { - for (auto §ion : inSections) { - auto start = section.header.addr; - auto end = start + section.data.size(); - - if (start <= address && end > address) { - auto offset = address - start; - return reinterpret_cast(section.data.data() + offset); - } - } - - return nullptr; + return input.size() >= match.size() + && std::equal(match.begin(), match.end(), input.begin()); } -static elf::Symbol * -getSectionSymbol(InputSection §ion, size_t index) -{ - auto symbols = reinterpret_cast(section.data.data()); - return &symbols[index]; -}; +/** + * Read the .elf file generated by compiler. + */ static bool -read(ElfFile &file, const std::string &filename) +readElf(ElfFile &file, const std::string &filename) { std::ifstream in { filename, std::ifstream::binary }; - std::vector inSections; - if (!in.is_open()) { - std::cout << "Could not open " << filename << " for reading" << std::endl; + fmt::print("Could not open {} for reading", filename); return false; } // Read header - elf::Header header; - in.read(reinterpret_cast(&header), sizeof(elf::Header)); + in.read(reinterpret_cast(&file.header), sizeof(elf::Header)); + byte_swap(file.header); - if (header.magic != elf::HeaderMagic) { - std::cout << "Invalid ELF magic header" << std::endl; + if (file.header.magic != elf::HeaderMagic) { + fmt::print("Invalid ELF magic header {:08X}", elf::HeaderMagic); return false; } - if (header.fileClass != elf::ELFCLASS32) { - std::cout << "Unexpected ELF file class" << std::endl; + if (file.header.fileClass != elf::ELFCLASS32) { + fmt::print("Unexpected ELF file class {}, expected {}", file.header.fileClass, elf::ELFCLASS32); return false; } - if (header.encoding != elf::ELFDATA2MSB) { - std::cout << "Unexpected ELF encoding" << std::endl; + if (file.header.encoding != elf::ELFDATA2MSB) { + fmt::print("Unexpected ELF encoding {}, expected {}", file.header.encoding, elf::ELFDATA2MSB); return false; } - if (header.machine != elf::EM_PPC) { - std::cout << "Unexpected ELF machine type" << std::endl; + if (file.header.machine != elf::EM_PPC) { + fmt::print("Unexpected ELF machine type {}, expected {}", file.header.machine, elf::EM_PPC); return false; } - if (header.elfVersion != elf::EV_CURRENT) { - std::cout << "Unexpected ELF version" << std::endl; + if (file.header.elfVersion != elf::EV_CURRENT) { + fmt::print("Unexpected ELF version {}, expected {}", file.header.elfVersion, elf::EV_CURRENT); return false; } - file.entryPoint = header.entry; - // Read section headers and data - in.seekg(static_cast(header.shoff)); - inSections.resize(header.shnum); + in.seekg(static_cast(file.header.shoff)); + + for (auto i = 0u; i < file.header.shnum; ++i) { + file.sections.emplace_back(std::make_unique()); + auto §ion = *file.sections.back(); - for (auto §ion : inSections) { in.read(reinterpret_cast(§ion.header), sizeof(elf::SectionHeader)); + byte_swap(section.header); if (!section.header.size || section.header.type == elf::SHT_NOBITS) { continue; @@ -202,993 +206,754 @@ read(ElfFile &file, const std::string &filename) in.seekg(pos); } - auto shStrTab = inSections[header.shstrndx].data.data(); + // Set section header names + auto shStrTab = file.sections[file.header.shstrndx]->data.data(); - // Process any loader relocations - for (auto §ion : inSections) { - if (section.header.type != elf::SHT_RELA) { - continue; - } - - auto name = std::string { shStrTab + section.header.name }; - - if (name.compare(".rela.dyn") != 0) { - continue; - } - - auto symSection = inSections[section.header.link]; - auto relas = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Rela); - - for (auto i = 0u; i < count; ++i) { - auto &rela = relas[i]; - auto index = rela.info >> 8; - auto symbol = getSectionSymbol(symSection, index); - auto addr = symbol->value + rela.addend; - - auto type = rela.info & 0xff; - auto ptr = getLoaderDataPtr(inSections, rela.offset); - - if (!ptr) { - std::cout << "Unexpected relocation offset in .rela.dyn section" << std::endl; - return false; - } - - switch (type) { - case elf::R_PPC_RELATIVE: - *ptr = byte_swap(addr); - break; - case elf::R_PPC_NONE: - // ignore padding - break; - default: - std::cout << "Unexpected relocation type in .rela.dyn section" << std::endl; - return false; - } - } + for (auto §ion : file.sections) { + section->name = shStrTab + section->header.name; } - // Read text/data sections - for (auto §ion : inSections) { - if (section.header.addr >= LoadAddress && section.header.addr < CodeAddress) { - // Skip any load sections - continue; - } + return true; +} - auto name = std::string { shStrTab + section.header.name }; - if (section.header.type == elf::SHT_PROGBITS) { - auto data = new ElfFile::DataSection(); - data->type = elf::SHT_PROGBITS; - data->flags = static_cast(section.header.flags.value()); - data->name = shStrTab + section.header.name; - data->address = section.header.addr; - data->data = section.data; - file.dataSections.emplace_back(data); - } else if (section.header.type == elf::SHT_NOBITS) { - auto bss = new ElfFile::DataSection(); - bss->type = elf::SHT_NOBITS; - bss->flags = static_cast(section.header.flags.value()); - bss->name = shStrTab + section.header.name; - bss->address = section.header.addr; - bss->size = section.header.size; - file.dataSections.emplace_back(bss); - } +/** + * Our linker script sometimes converts .bss from NOBITS to PROGBITS. + */ +static bool +fixBssNoBits(ElfFile &file) +{ + auto section = getSectionByName(file, ".bss"); + if (!section) { + return true; } - // Default symbols - auto symNull = new ElfFile::Symbol(); - symNull->address = 0; - symNull->size = 0; - symNull->type = elf::STT_NOTYPE; - symNull->binding = elf::STB_LOCAL; - file.symbols.emplace_back(symNull); - - auto symText = new ElfFile::Symbol(); - symText->name = "$TEXT"; - symText->address = CodeAddress; - symText->size = 0; - symText->type = elf::STT_SECTION; - symText->binding = elf::STB_LOCAL; - file.symbols.emplace_back(symText); - - auto symData = new ElfFile::Symbol(); - symData->name = "$DATA"; - symData->address = DataAddress; - symData->size = 0; - symData->type = elf::STT_SECTION; - symData->binding = elf::STB_LOCAL; - file.symbols.emplace_back(symData); - - auto symUndef = new ElfFile::Symbol(); - symUndef->name = "$UNDEF"; - symUndef->address = 0; - symUndef->size = 0; - symUndef->type = elf::STT_OBJECT; - symUndef->binding = elf::STB_GLOBAL; - file.symbols.emplace_back(symUndef); - - // Read symbols - for (auto §ion : inSections) { - if (section.header.type != elf::SHT_SYMTAB) { - continue; - } - - auto name = std::string { shStrTab + section.header.name }; - - if (name.compare(".symtab") != 0) { - std::cout << "Unexpected symbol section " << name << std::endl; + // Ensure there is actually all 0 in the .bss section + for (const auto c : section->data) { + if (c) { return false; } + } - auto strTab = inSections[section.header.link].data.data(); - auto symTab = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Symbol); + // Set type back to NOBITS + section->header.type = elf::SHT_NOBITS; + section->header.offset = 0; + section->data.clear(); + return true; +} - for (auto i = 0u; i < count; ++i) { - auto &sym = symTab[i]; - if (sym.value >= LoadAddress && sym.value < CodeAddress) { - // Skip any load symbols - continue; - } +/** + * Reorder sections index. + * + * Expected order: + * NULL section + * >.syscall >.text + * > .fexports + * > .rodata > .data > .module_id > .bss + * > .rela.fexports > .rela.text > .rela.rodata > .rela.data + * > {.fimport, .dimport } + * > .symtab > .strtab > .shstrtab + */ +static bool +reorderSectionIndex(ElfFile &file) +{ + // Create a map of new index -> old index + std::vector sectionMap; + sectionMap.push_back(0); - auto type = static_cast(sym.info & 0xF); - auto binding = static_cast((sym.info >> 4) & 0xF); + if (auto index = getSectionIndex(file, ".syscall"); index != -1) { + sectionMap.push_back(index); + } - if (type == elf::STT_NOTYPE && sym.value == 0) { - // Skip null symbol - continue; - } + if (auto index = getSectionIndex(file, ".text"); index != -1) { + sectionMap.push_back(index); + } - if (type == elf::STT_FILE || type == elf::STT_SECTION) { - // Skip file, section symbols - continue; - } + if (auto index = getSectionIndex(file, ".fexports"); index != -1) { + sectionMap.push_back(index); + } - auto symbol = new ElfFile::Symbol(); - symbol->name = strTab + sym.name; - symbol->address = sym.value; - symbol->size = sym.size; - symbol->type = type; - symbol->binding = binding; - file.symbols.emplace_back(symbol); + if (auto index = getSectionIndex(file, ".rodata"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".data"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".module_id"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".bss"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".rela.fexports"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".rela.text"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".rela.rodata"); index != -1) { + sectionMap.push_back(index); + } + + if (auto index = getSectionIndex(file, ".rela.data"); index != -1) { + sectionMap.push_back(index); + } + + // All .fimport_ and .dimport_ + for (auto index = 0u; index < file.sections.size(); ++index) { + const auto §ion = file.sections[index]; + if (begins_with(section->name, ".fimport_") || + begins_with(section->name, ".dimport_")) { + sectionMap.push_back(index); } } - // Read RPL imports - for (auto §ion : inSections) { - auto name = std::string { shStrTab + section.header.name }; - - if (name.compare(".lib.rplLibs") != 0) { - continue; - } - - auto rplTab = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(RplLibsDef); - - for (auto i = 0u; i < count; ++i) { - auto &rpl = rplTab[i]; - auto lib = new ElfFile::RplImportLibrary(); - lib->name = getLoaderDataPtr(inSections, rpl.name); - - for (auto stubAddr = rpl.stubStart; stubAddr < rpl.stubEnd; stubAddr += 4) { - auto import = new ElfFile::RplImport(); - import->trampAddr = byte_swap(*getLoaderDataPtr(inSections, stubAddr)); - import->stubAddr = stubAddr; - - // Get the tramp symbol - import->trampSymbol = findSymbol(file, import->trampAddr); - - // Create a new symbol to use for the import - auto stubSymbol = new ElfFile::Symbol(); - import->stubSymbol = stubSymbol; - stubSymbol->name = import->trampSymbol->name; - stubSymbol->address = 0; - stubSymbol->size = 0; - stubSymbol->binding = elf::STB_GLOBAL; - stubSymbol->type = elf::STT_FUNC; - file.symbols.emplace_back(stubSymbol); - - // Rename tramp symbol - import->trampSymbol->name += "_tramp"; - - lib->imports.emplace_back(import); - } - - file.rplImports.emplace_back(lib); - } + if (auto index = getSectionIndex(file, ".symtab"); index != -1) { + sectionMap.push_back(index); } - // Read relocations - for (auto §ion : inSections) { - if (section.header.type != elf::SHT_RELA) { - continue; - } - - auto name = std::string { shStrTab + section.header.name }; - - if (name.compare(".rela.dyn") == 0) { - // Skip dyn relocations - continue; - } - - auto symTab = reinterpret_cast(inSections[section.header.link].data.data()); - auto relTab = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Rela); - - for (auto i = 0u; i < count; ++i) { - auto relocation = new ElfFile::Relocation(); - auto &rela = relTab[i]; - - auto type = rela.info & 0xff; - auto index = rela.info >> 8; - auto &sym = symTab[index]; - auto symType = sym.info & 0xf; - - if (symType == elf::STT_SECTION && sym.value == CodeAddress) { - if (rela.offset < CodeAddress || rela.offset >= DataAddress) { - std::cout << "Unexpected symbol referenced in relocation section " << name << std::endl; - return false; - } - } - - auto addend = static_cast(rela.addend); - - if (auto import = findImport(file, addend)) { - relocation->symbol = import->stubSymbol; - relocation->addend = 0; - } else if (auto symbol = findSymbol(file, addend)) { - relocation->symbol = symbol; - relocation->addend = 0; - } else if (addend >= DataAddress && addend < WiiuLoadAddress) { - relocation->symbol = findSymbol(file, DataAddress); - relocation->addend = addend - DataAddress; - } else if (addend >= CodeAddress && addend < DataAddress) { - relocation->symbol = findSymbol(file, CodeAddress); - relocation->addend = addend - CodeAddress; - } else { - // If we can't find a proper symbol, write the addend in and hope for the best - auto ptr = getLoaderDataPtr(inSections, rela.offset); - *ptr = addend; - - std::cout << "Unexpected addend " << std::hex << addend << " referenced in relocation section " << name << ", continuing." << std::endl; - continue; - } - - relocation->target = rela.offset; - relocation->type = static_cast(type); - file.relocations.emplace_back(relocation); - } + if (auto index = getSectionIndex(file, ".strtab"); index != -1) { + sectionMap.push_back(index); } - // Read dyn relocations - for (auto §ion : inSections) { - if (section.header.type != elf::SHT_RELA) { + if (auto index = getSectionIndex(file, ".shstrtab"); index != -1) { + sectionMap.push_back(index); + } + + if (sectionMap.size() != file.sections.size()) { + fmt::print("Invalid section in elf file"); + return false; + } + + // Apply the new ordering + std::vector> newSections; + for (auto idx : sectionMap) { + newSections.emplace_back(std::move(file.sections[idx])); + } + + file.sections = std::move(newSections); + + // Now generate a reverse map, old index -> new index + std::vector mapOldToNew; + mapOldToNew.resize(file.sections.size()); + for (auto i = 0u; i < sectionMap.size(); ++i) { + mapOldToNew[sectionMap[i]] = i; + } + + // Map file header.shstrndx + file.header.shstrndx = mapOldToNew[file.header.shstrndx]; + + // Map section header.link + for (auto §ion : file.sections) { + section->header.link = mapOldToNew[section->header.link]; + } + + // Map relocation sections header.info + for (auto §ion : file.sections) { + if (section->header.type != elf::SHT_RELA) { continue; } - auto name = std::string { shStrTab + section.header.name }; + section->header.info = mapOldToNew[section->header.info]; + } - if (name.compare(".rela.dyn") != 0) { + // Map symbol.shndx + for (auto §ion : file.sections) { + if (section->header.type != elf::SHT_SYMTAB) { continue; } - auto symSection = inSections[section.header.link]; - auto relas = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Rela); - - for (auto i = 0u; i < count; ++i) { - auto relocation = new ElfFile::Relocation(); - auto &rela = relas[i]; - - auto type = rela.info & 0xff; - auto index = rela.info >> 8; - auto symbol = getSectionSymbol(symSection, index); - auto addr = symbol->value + rela.addend; - - if(type == elf::R_PPC_NONE) - { - // ignore padding - continue; + auto symbols = reinterpret_cast(section->data.data()); + auto numSymbols = section->data.size() / sizeof(elf::Symbol); + for (auto i = 0u; i < numSymbols; ++i) { + auto shndx = byte_swap(symbols[i].shndx); + if (shndx < elf::SHN_LORESERVE) { + symbols[i].shndx = byte_swap(mapOldToNew[shndx]); } - - if(index == 0) - { - auto addend = static_cast(rela.addend); - - if (auto import = findImport(file, addend)) { - relocation->symbol = import->stubSymbol; - relocation->addend = 0; - } else if (auto symbol = findSymbol(file, addend)) { - relocation->symbol = symbol; - relocation->addend = 0; - } else if (addr >= CodeAddress && addr < DataAddress) { - index = 1; - relocation->symbol = findSymbol(file, CodeAddress); - relocation->addend = rela.addend - CodeAddress; - } else if (addr >= DataAddress && addr < WiiuLoadAddress) { - index = 2; - relocation->symbol = findSymbol(file, DataAddress); - relocation->addend = rela.addend - DataAddress; - } else { - std::cout << "Unexpected symbol address in .rela.dyn section" << std::endl; - return false; - } - } - - switch (type) { - case elf::R_PPC_RELATIVE: - type = elf::R_PPC_ADDR32; - break; - default: - std::cout << "Unexpected relocation type in .rela.dyn section" << std::endl; - return false; - } - - relocation->target = rela.offset; - relocation->type = static_cast(type); - - // Scrap any compiler/linker garbage - if(relocation->target >= CodeAddress && relocation->target < WiiuLoadAddress) - file.relocations.emplace_back(relocation); } } return true; } -struct OutputSection -{ - std::string name; - elf::SectionHeader header; - std::vector data; - OutputSection *relocationSection = nullptr; - ElfFile::Symbol *sectionSymbol = nullptr; -}; - -template -SymbolIterator addSection(ElfFile &file, std::vector &outSections, SymbolIterator symbolIterator, OutputSection *section) -{ - auto sectionSymbol = new ElfFile::Symbol(); - sectionSymbol->name = section->name; - sectionSymbol->address = section->header.addr; - sectionSymbol->size = -1; - sectionSymbol->type = elf::STT_SECTION; - sectionSymbol->binding = elf::STB_LOCAL; - section->sectionSymbol = sectionSymbol; - outSections.push_back(section); - return file.symbols.insert(symbolIterator, std::unique_ptr { sectionSymbol }) + 1; -}; - -static uint32_t -getSectionIndex(std::vector &outSections, uint32_t address) -{ - for (auto i = 0u; i < outSections.size(); ++i) { - auto §ion = outSections[i]; - auto start = section->header.addr; - auto end = start + section->header.size; - - if (address >= start && address < end) { - return i; - } - } - - return -1; -} - -static uint32_t -getSectionIndex(std::vector &outSections, const std::string &name) -{ - for (auto i = 0u; i < outSections.size(); ++i) { - auto §ion = outSections[i]; - - if (section->name.compare(name) == 0) { - return i; - } - } - - return -1; -} +/** + * Generate SHT_RPL_FILEINFO section. + */ static bool -write(ElfFile &file, const std::string &filename) +generateFileInfoSection(ElfFile &file) { - std::vector outSections; - auto sectionSymbolItr = file.symbols.begin() + 4; - - // Create NULL section - auto nullSection = new OutputSection(); - memset(&nullSection->header, 0, sizeof(elf::SectionHeader)); - outSections.push_back(nullSection); - - // Create text/data sections - for (auto §ion : file.dataSections) { - auto out = new OutputSection(); - out->header.name = -1; - out->header.type = section->type; - out->header.flags = section->flags; - out->header.addr = section->address; - out->header.offset = -1; - - if (section->type == elf::SHT_NOBITS) { - out->header.size = section->size; - } else { - out->header.size = section->data.size(); - } - - out->header.link = 0; - out->header.info = 0; - - if (section->address == DataAddress) { - out->header.addralign = 4096; - out->header.flags |= elf::SHF_WRITE; // .rodata needs to be writable? - } else { - out->header.addralign = 256; - } - - out->header.entsize = 0; - - // Add section - out->name = section->name; - out->data = section->data; - sectionSymbolItr = addSection(file, outSections, sectionSymbolItr, out); - } - - // Create relocation sections - for (auto &relocation : file.relocations) { - OutputSection *targetSection = nullptr; - - for (auto §ion : outSections) { - auto start = section->header.addr; - auto end = start + section->header.size; - - if (relocation->target >= start && relocation->target < end) { - targetSection = section; - break; - } - } - - if (!targetSection) { - std::cout << "Error could not find section for relocation" << std::endl; - return false; - } - - if (!targetSection->relocationSection) { - // Create new relocation section - auto out = new OutputSection(); - out->header.name = -1; - out->header.type = elf::SHT_RELA; - out->header.flags = 0; - out->header.addr = 0; - out->header.offset = -1; - out->header.size = -1; - out->header.link = -1; - out->header.info = getSectionIndex(outSections, targetSection->header.addr); - out->header.addralign = 4; - out->header.entsize = sizeof(elf::Rela); - - // Add section - out->name = ".rela" + targetSection->name; - sectionSymbolItr = addSection(file, outSections, sectionSymbolItr, out); - targetSection->relocationSection = out; - } - } - - // Calculate sizes of symbol/string tables so RPL imports are placed after them - auto loadAddress = 0xC0000000; - auto predictStrTabSize = 1; - auto predictSymTabSize = 1; - auto predictShstrTabSize = 1; - - for (auto &symbol : file.symbols) { - predictStrTabSize += symbol->name.size() + 1; - predictSymTabSize += sizeof(elf::Symbol); - } - - for (auto §ion : outSections) { - predictShstrTabSize += section->name.size() + 1; - } - - predictStrTabSize = align_up(predictStrTabSize, 0x10); - predictSymTabSize = align_up(predictSymTabSize, 0x10); - predictShstrTabSize = align_up(predictShstrTabSize, 0x10); - loadAddress += predictStrTabSize + predictSymTabSize + predictShstrTabSize; - - // Create RPL import sections, .fimport_*, .dimport_* - for (auto &lib : file.rplImports) { - auto out = new OutputSection(); - out->header.name = -1; - out->header.type = elf::SHT_RPL_IMPORTS; - out->header.flags = elf::SHF_ALLOC | elf::SHF_EXECINSTR; - out->header.addr = loadAddress; - out->header.offset = -1; - out->header.link = 0; - out->header.info = 0; - out->header.addralign = 4; - out->header.entsize = 0; - out->name = ".fimport_" + lib->name; - - // Calculate size - auto nameSize = align_up(8 + lib->name.size(), 8); - auto stubSize = 8 + 8 * lib->imports.size(); - out->header.size = std::max(nameSize, stubSize); - out->data.resize(out->header.size); - - // Setup data - auto imports = reinterpret_cast(out->data.data()); - imports->count = lib->imports.size(); - imports->signature = crc32(0, Z_NULL, 0); - memcpy(imports->name, lib->name.data(), lib->name.size()); - imports->name[lib->name.size()] = 0; - - // Update address of import symbols - for (auto i = 0u; i < lib->imports.size(); ++i) { - lib->imports[i]->stubSymbol->address = loadAddress + 8 + i * 8; - } - - loadAddress = align_up(loadAddress + out->header.size, 4); - - // Add section - sectionSymbolItr = addSection(file, outSections, sectionSymbolItr, out); - } - - // Prune out unneeded symbols - for (auto i = 0u; i < file.symbols.size(); ++i) { - if (!file.symbols[i]->name.empty() && file.symbols[i]->type == elf::STT_NOTYPE && file.symbols[i]->size == 0) { - file.symbols.erase(file.symbols.begin() + i); - i--; - } - } - - // NOTICE: FROM NOW ON DO NOT MODIFY mSymbols - - // Convert relocations - for (auto &relocation : file.relocations) { - OutputSection *targetSection = nullptr; - - for (auto §ion : outSections) { - auto start = section->header.addr; - auto end = start + section->header.size; - - if (relocation->target >= start && relocation->target < end) { - targetSection = section; - break; - } - } - - if (!targetSection || !targetSection->relocationSection) { - std::cout << "Error could not find section for relocation" << std::endl; - return false; - } - - // Get address of relocation->target - auto relocationSection = targetSection->relocationSection; - - // Find symbol this relocation points to - auto itr = std::find_if(file.symbols.begin(), file.symbols.end(), [&relocation](auto &val) { - return val.get() == relocation->symbol; - }); - - auto idx = itr - file.symbols.begin(); - - // If the symbol doesn't exist but it is within DATA or TEXT, use those symbols + an addend - if (itr == file.symbols.end()) { - if (relocation->symbol->address >= CodeAddress && relocation->symbol->address < DataAddress) { - idx = 1; - relocation->addend = relocation->symbol->address - CodeAddress; - relocation->symbol = findSymbol(file, CodeAddress); - } else if (relocation->symbol->address >= DataAddress && relocation->symbol->address < WiiuLoadAddress) { - idx = 2; - relocation->addend = relocation->symbol->address - DataAddress; - relocation->symbol = findSymbol(file, DataAddress); - } else { - std::cout << "Could not find matching symbol for relocation" << std::endl; - return false; - } - } - - // Create relocation - elf::Rela rela; - rela.info = relocation->type | idx << 8; - - if(relocation->type == elf::R_PPC_RELATIVE) { - rela.info = elf::R_PPC_ADDR32 | idx << 8; - } - - rela.addend = relocation->addend; - rela.offset = relocation->target; - - // Append to relocation section data - char *relaData = reinterpret_cast(&rela); - relocationSection->data.insert(relocationSection->data.end(), relaData, relaData + sizeof(elf::Rela)); - } - - // String + Symbol sections - auto symTabSection = new OutputSection(); - auto strTabSection = new OutputSection(); - auto shStrTabSection = new OutputSection(); - - symTabSection->name = ".symtab"; - strTabSection->name = ".strtab"; - shStrTabSection->name = ".shstrtab"; - - auto symTabIndex = outSections.size(); - outSections.push_back(symTabSection); - - auto strTabIndex = outSections.size(); - outSections.push_back(strTabSection); - - auto shStrTabIndex = outSections.size(); - outSections.push_back(shStrTabSection); - - // Update relocation sections to link to symtab - for (auto §ion : outSections) { - if (section->header.type == elf::SHT_RELA) { - section->header.link = symTabIndex; - } - - if (section->header.type != elf::SHT_NOBITS) { - section->header.size = section->data.size(); - } - - if (section->sectionSymbol) { - section->sectionSymbol->address = section->header.addr; - section->sectionSymbol->size = section->header.size; - } - } - - // Create .strtab - strTabSection->header.name = 0; - strTabSection->header.type = elf::SHT_STRTAB; - strTabSection->header.flags = elf::SHF_ALLOC; - strTabSection->header.addr = 0; - strTabSection->header.offset = -1; - strTabSection->header.size = -1; - strTabSection->header.link = 0; - strTabSection->header.info = 0; - strTabSection->header.addralign = 1; - strTabSection->header.entsize = 0; - - // Add all symbol names to data, update symbol->outNamePos - strTabSection->data.push_back(0); - - for (auto &symbol : file.symbols) { - if (symbol->name.empty()) { - symbol->outNamePos = 0; - } else { - symbol->outNamePos = static_cast(strTabSection->data.size()); - std::copy(symbol->name.begin(), symbol->name.end(), std::back_inserter(strTabSection->data)); - strTabSection->data.push_back(0); - } - } - - // Create .symtab - symTabSection->header.name = 0; - symTabSection->header.type = elf::SHT_SYMTAB; - symTabSection->header.flags = elf::SHF_ALLOC; - symTabSection->header.addr = 0; - symTabSection->header.offset = -1; - symTabSection->header.size = -1; - symTabSection->header.link = strTabIndex; - symTabSection->header.info = 0; - symTabSection->header.addralign = 4; - symTabSection->header.entsize = sizeof(elf::Symbol); - - for (auto &symbol : file.symbols) { - elf::Symbol sym; - auto shndx = getSectionIndex(outSections, symbol->address); - - if (symbol->type == elf::STT_SECTION && symbol->address == 0) { - shndx = getSectionIndex(outSections, symbol->name); - } - - if (shndx == -1) { - std::cout << "Could not find section for symbol" << std::endl; - return false; - } - - sym.name = symbol->outNamePos; - sym.value = symbol->address; - sym.size = symbol->size; - sym.info = symbol->type | (symbol->binding << 4); - sym.other = 0; - sym.shndx = shndx; - - //Compound symbol crc into section crc - auto crcSection = outSections[shndx]; - if(crcSection->header.type == elf::SHT_RPL_IMPORTS && symbol->type != elf::STT_SECTION) { - auto rplImport = reinterpret_cast(crcSection->data.data()); - rplImport->signature = crc32(rplImport->signature, reinterpret_cast(strTabSection->data.data() + sym.name),strlen(strTabSection->data.data() + sym.name)+1); - } - - // Append to symtab data - char *symData = reinterpret_cast(&sym); - symTabSection->data.insert(symTabSection->data.end(), symData, symData + sizeof(elf::Symbol)); - } - - //Finish SHT_RPL_IMPORTS signatures - Bytef *zero_buffer = reinterpret_cast(calloc(0x10, 1)); - for (auto §ion : outSections) { - if(section->header.type == elf::SHT_RPL_IMPORTS) { - auto rplImport = reinterpret_cast(section->data.data()); - rplImport->signature = crc32(rplImport->signature, zero_buffer, 0xE); - } - } - free(zero_buffer); - - // Create .shstrtab - shStrTabSection->header.name = 0; - shStrTabSection->header.type = elf::SHT_STRTAB; - shStrTabSection->header.flags = elf::SHF_ALLOC; - shStrTabSection->header.addr = 0; - shStrTabSection->header.offset = -1; - shStrTabSection->header.size = -1; - shStrTabSection->header.link = 0; - shStrTabSection->header.info = 0; - shStrTabSection->header.addralign = 1; - shStrTabSection->header.entsize = 0; - - // Add all section header names to data, update section->header.name - shStrTabSection->data.push_back(0); - - for (auto §ion : outSections) { - if (section->name.empty()) { - section->header.name = 0; - } else { - section->header.name = shStrTabSection->data.size(); - std::copy(section->name.begin(), section->name.end(), std::back_inserter(shStrTabSection->data)); - shStrTabSection->data.push_back(0); - } - } - - loadAddress = 0xC0000000; - - // Update symtab, strtab, shstrtab section addresses - symTabSection->header.addr = loadAddress; - symTabSection->header.size = symTabSection->data.size(); - - loadAddress = align_up(symTabSection->header.addr + predictSymTabSize, 16); - strTabSection->header.addr = loadAddress; - strTabSection->header.size = strTabSection->data.size(); - - loadAddress = align_up(strTabSection->header.addr + predictStrTabSize, 16); - shStrTabSection->header.addr = loadAddress; - shStrTabSection->header.size = shStrTabSection->data.size(); - - // Create SHT_RPL_FILEINFO section - auto fileInfoSection = new OutputSection(); - fileInfoSection->header.name = 0; - fileInfoSection->header.type = elf::SHT_RPL_FILEINFO; - fileInfoSection->header.flags = 0; - fileInfoSection->header.addr = 0; - fileInfoSection->header.offset = -1; - fileInfoSection->header.size = -1; - fileInfoSection->header.link = 0; - fileInfoSection->header.info = 0; - fileInfoSection->header.addralign = 4; - fileInfoSection->header.entsize = 0; - - elf::RplFileInfo fileInfo; - fileInfo.version = 0xCAFE0402; - fileInfo.textSize = 0; - fileInfo.textAlign = 32; - fileInfo.dataSize = 0; - fileInfo.dataAlign = 4096; - fileInfo.loadSize = 0; - fileInfo.loadAlign = 4; - fileInfo.tempSize = 0; - fileInfo.trampAdjust = 0; - fileInfo.trampAddition = 0; - fileInfo.sdaBase = 0; - fileInfo.sda2Base = 0; - fileInfo.stackSize = 0x10000; - fileInfo.heapSize = 0x8000; - fileInfo.filename = 0; - fileInfo.flags = elf::RPL_IS_RPX; - fileInfo.minVersion = 0x5078; - fileInfo.compressionLevel = -1; - fileInfo.fileInfoPad = 0; - fileInfo.cafeSdkVersion = 0x51BA; - fileInfo.cafeSdkRevision = 0xCCD1; - fileInfo.tlsAlignShift = 0; - fileInfo.tlsModuleIndex = 0; - fileInfo.runtimeFileInfoSize = 0; - fileInfo.tagOffset = 0; + elf::RplFileInfo info; + info.version = 0xCAFE0402; + info.textSize = 0; + info.textAlign = 32; + info.dataSize = 0; + info.dataAlign = 4096; + info.loadSize = 0; + info.loadAlign = 4; + info.tempSize = 0; + info.trampAdjust = 0; + info.trampAddition = 0; + info.sdaBase = 0; + info.sda2Base = 0; + info.stackSize = 0x10000; + info.heapSize = 0x8000; + info.filename = 0; + info.flags = elf::RPL_IS_RPX; // TODO: Add .rpl support + info.minVersion = 0x5078; + info.compressionLevel = -1; + info.fileInfoPad = 0; + info.cafeSdkVersion = 0x51BA; + info.cafeSdkRevision = 0xCCD1; + info.tlsAlignShift = 0; + info.tlsModuleIndex = 0; + info.runtimeFileInfoSize = 0; + info.tagOffset = 0; // Count file info textSize, dataSize, loadSize - for (auto §ion : outSections) { + for (auto §ion : file.sections) { auto size = section->data.size(); if (section->header.type == elf::SHT_NOBITS) { size = section->header.size; } - if (section->header.addr >= CodeAddress && section->header.addr < DataAddress) { - auto val = section->header.addr.value() + section->header.size.value() - CodeAddress; - if(val > fileInfo.textSize) { - fileInfo.textSize = val; + if (section->header.addr >= CodeBaseAddress && + section->header.addr < DataBaseAddress) { + auto val = section->header.addr + section->header.size - CodeBaseAddress; + if (val > info.textSize) { + info.textSize = val; } - } else if (section->header.addr >= DataAddress && section->header.addr < WiiuLoadAddress) { - auto val = section->header.addr.value() + section->header.size.value() - DataAddress; - if(val > fileInfo.dataSize) { - fileInfo.dataSize = val; + } else if (section->header.addr >= DataBaseAddress && + section->header.addr < LoadBaseAddress) { + auto val = section->header.addr + section->header.size - DataBaseAddress; + if (val > info.dataSize) { + info.dataSize = val; } - } else if (section->header.addr >= WiiuLoadAddress) { - auto val = section->header.addr.value() + section->header.size.value() - WiiuLoadAddress; - if(val > fileInfo.loadSize) { - fileInfo.loadSize = val; + } else if (section->header.addr >= LoadBaseAddress) { + auto val = section->header.addr + section->header.size - LoadBaseAddress; + if (val > info.loadSize) { + info.loadSize = val; } - } else if (section->header.addr == 0 && section->header.type != elf::SHT_RPL_CRCS && section->header.type != elf::SHT_RPL_FILEINFO) { - fileInfo.tempSize += (size + 128); + } else if (section->header.addr == 0 && + section->header.type != elf::SHT_RPL_CRCS && + section->header.type != elf::SHT_RPL_FILEINFO) { + info.tempSize += (size + 128); } } - //TODO: These were calculated based on observation, however some games differ. - fileInfo.sdaBase = align_up(DataAddress + fileInfo.dataSize + fileInfo.heapSize, 64); - fileInfo.sda2Base = align_up(DataAddress + fileInfo.heapSize, 64); + byte_swap(info); - char *fileInfoData = reinterpret_cast(&fileInfo); - fileInfoSection->data.insert(fileInfoSection->data.end(), fileInfoData, fileInfoData + sizeof(elf::RplFileInfo)); + auto section = std::make_unique(); + section->header.name = 0; + section->header.type = elf::SHT_RPL_FILEINFO; + section->header.flags = 0; + section->header.addr = 0; + section->header.offset = -1; + section->header.size = -1; + section->header.link = 0; + section->header.info = 0; + section->header.addralign = 4; + section->header.entsize = 0; + section->data.insert(section->data.end(), + reinterpret_cast(&info), + reinterpret_cast(&info + 1)); + file.sections.emplace_back(std::move(section)); + return true; +} - // Create SHT_RPL_CRCS section - auto crcSection = new OutputSection(); - crcSection->header.name = 0; - crcSection->header.type = elf::SHT_RPL_CRCS; - crcSection->header.flags = 0; - crcSection->header.addr = 0; - crcSection->header.offset = -1; - crcSection->header.size = -1; - crcSection->header.link = 0; - crcSection->header.info = 0; - crcSection->header.addralign = 4; - crcSection->header.entsize = 4; - outSections.push_back(crcSection); - outSections.push_back(fileInfoSection); +/** + * Generate SHT_RPL_CRCS section. + */ +static bool +generateCrcSection(ElfFile &file) +{ + std::vector crcs; + for (auto §ion : file.sections) { + auto crc = uint32_t { 0u }; - std::vector sectionCRCs; - - for (auto §ion : outSections) { - auto crc = 0u; - - if (!section->data.empty()) { + if (section->data.size()) { crc = crc32(0, Z_NULL, 0); crc = crc32(crc, reinterpret_cast(section->data.data()), section->data.size()); } - sectionCRCs.push_back(byte_swap(crc)); + crcs.push_back(byte_swap(crc)); } - char *crcData = reinterpret_cast(sectionCRCs.data()); - crcSection->data.insert(crcSection->data.end(), crcData, crcData + sizeof(uint32_t) * sectionCRCs.size()); + auto section = std::make_unique(); + section->header.name = 0; + section->header.type = elf::SHT_RPL_CRCS; + section->header.flags = 0; + section->header.addr = 0; + section->header.offset = -1; + section->header.size = -1; + section->header.link = 0; + section->header.info = 0; + section->header.addralign = 4; + section->header.entsize = 4; + section->data.insert(section->data.end(), + reinterpret_cast(crcs.data()), + reinterpret_cast(crcs.data() + crcs.size())); + // Insert before FILEINFO + file.sections.insert(file.sections.end() - 1, std::move(section)); + return true; +} - // Update section sizes and offsets - auto shoff = align_up(sizeof(elf::Header), 64); - auto dataOffset = align_up(shoff + outSections.size() * sizeof(elf::SectionHeader), 64); - // Add CRC and FileInfo sections first - for (auto §ion : outSections) { - if (section->header.type != elf::SHT_RPL_CRCS && section->header.type != elf::SHT_RPL_FILEINFO) { - continue; - } - - if (section->header.type != elf::SHT_NOBITS) { - section->header.size = section->data.size(); - } - - if (!section->data.empty()) { - section->header.offset = dataOffset; - dataOffset = align_up(section->header.offset + section->data.size(), 64); - } else { - section->header.offset = 0; - } - } - - // Add data sections next - for (auto §ion : outSections) { - if(section->header.offset != -1) { - continue; - } - - if (section->header.addr < DataAddress || section->header.addr >= WiiuLoadAddress) { - continue; - } - - if (section->header.type != elf::SHT_NOBITS) { - section->header.size = section->data.size(); - } - - if (!section->data.empty()) { - section->header.offset = dataOffset; - dataOffset = align_up(section->header.offset + section->data.size(), 64); - } else { - section->header.offset = 0; - } - } - - // Add load sections next - for (auto §ion : outSections) { - if(section->header.offset != -1) { - continue; - } - - if (section->header.addr < WiiuLoadAddress) { - continue; - } - - if (section->header.type != elf::SHT_NOBITS) { - section->header.size = section->data.size(); - } - - if (!section->data.empty()) { - section->header.offset = dataOffset; - dataOffset = align_up(section->header.offset + section->data.size(), 64); - } else { - section->header.offset = 0; - } - } - - // Everything else - for (auto §ion : outSections) { - if(section->header.offset != -1) { - continue; - } - - if (section->header.type != elf::SHT_NOBITS) { - section->header.size = section->data.size(); - } - - if (!section->data.empty()) { - section->header.offset = dataOffset; - dataOffset = align_up(section->header.offset + section->data.size(), 64); - } else { - section->header.offset = 0; - } - } - - // Write to file - std::ofstream out { filename, std::ofstream::binary }; - std::vector padding; - - if (!out.is_open()) { - std::cout << "Could not open " << filename << " for writing" << std::endl; +static bool +getSymbol(ElfFile::Section §ion, size_t index, elf::Symbol &symbol) +{ + auto symbols = reinterpret_cast(section.data.data()); + auto numSymbols = section.data.size() / sizeof(elf::Symbol); + if (index >= numSymbols) { return false; } - elf::Header header; - header.magic = elf::HeaderMagic; - header.fileClass = 1; - header.encoding = elf::ELFDATA2MSB; - header.elfVersion = elf::EV_CURRENT; - header.abi = elf::EABI_CAFE; - memset(&header.pad, 0, 7); - header.type = 0xFE01; - header.machine = elf::EM_PPC; - header.version = 1; - header.entry = file.entryPoint; - header.phoff = 0; - header.phentsize = 0; - header.phnum = 0; - header.shoff = shoff; - header.shnum = outSections.size(); - header.shentsize = sizeof(elf::SectionHeader); - header.flags = 0; - header.ehsize = sizeof(elf::Header); - header.shstrndx = shStrTabIndex; - out.write(reinterpret_cast(&header), sizeof(elf::Header)); + symbol.name = byte_swap(symbols[index].name); + symbol.value = byte_swap(symbols[index].value); + symbol.size = byte_swap(symbols[index].size); + symbol.info = byte_swap(symbols[index].info); + symbol.other = byte_swap(symbols[index].other); + symbol.shndx = byte_swap(symbols[index].shndx); + return true; +} - // Write section headers - out.seekp(header.shoff.value()); - for (auto §ion : outSections) { - out.write(reinterpret_cast(§ion->header), sizeof(elf::SectionHeader)); +/** + * Fix relocations. + * + * The Wii U does not support every type of relocation. + */ +static bool +fixRelocations(ElfFile &file) +{ + std::set unsupportedTypes; + auto result = true; + + for (auto §ion : file.sections) { + std::vector newRelocations; + + if (section->header.type != elf::SHT_RELA) { + continue; + } + + // Clear flags + section->header.flags = 0; + + auto &symbolSection = file.sections[section->header.link]; + auto &targetSection = file.sections[section->header.info]; + + auto rels = reinterpret_cast(section->data.data()); + auto numRels = section->data.size() / sizeof(elf::Rela); + for (auto i = 0u; i < numRels; ++i) { + auto info = byte_swap(rels[i].info); + auto addend = byte_swap(rels[i].addend); + auto offset = byte_swap(rels[i].offset); + auto index = info >> 8; + auto type = info & 0xFF; + + switch (type) { + case elf::R_PPC_NONE: + case elf::R_PPC_ADDR32: + case elf::R_PPC_ADDR16_LO: + case elf::R_PPC_ADDR16_HI: + case elf::R_PPC_ADDR16_HA: + case elf::R_PPC_REL24: + case elf::R_PPC_REL14: + case elf::R_PPC_DTPMOD32: + case elf::R_PPC_DTPREL32: + case elf::R_PPC_EMB_SDA21: + case elf::R_PPC_EMB_RELSDA: + case elf::R_PPC_DIAB_SDA21_LO: + case elf::R_PPC_DIAB_SDA21_HI: + case elf::R_PPC_DIAB_SDA21_HA: + case elf::R_PPC_DIAB_RELSDA_LO: + case elf::R_PPC_DIAB_RELSDA_HI: + case elf::R_PPC_DIAB_RELSDA_HA: + // All valid relocations on Wii U, do nothing + break; + + /* + * Convert a R_PPC_REL32 into two GHS_REL16 + */ + case elf::R_PPC_REL32: + { + elf::Symbol symbol; + if (!getSymbol(*symbolSection, index, symbol)) { + fmt::print("ERROR: Could not find symbol {} for fixing a R_PPC_REL32 relocation", index); + result = false; + } else { + newRelocations.emplace_back(); + auto &newRel = newRelocations.back(); + + // Modify current relocation to R_PPC_GHS_REL16_LO + rels[i].info = byte_swap((index << 8) | elf::R_PPC_GHS_REL16_LO); + rels[i].addend = byte_swap(addend); + rels[i].offset = byte_swap(offset); + + // Create a R_PPC_GHS_REL16_HI + newRel.info = byte_swap((index << 8) | elf::R_PPC_GHS_REL16_HI); + newRel.addend = byte_swap(addend + 2); + newRel.offset = byte_swap(offset + 2); + } + + break; + } + + default: + // Only print error once per type + if (!unsupportedTypes.count(type)) { + fmt::print("ERROR: Unsupported relocation type {}", type); + unsupportedTypes.insert(type); + } + } + } + + + section->data.insert(section->data.end(), + reinterpret_cast(newRelocations.data()), + reinterpret_cast(newRelocations.data() + newRelocations.size())); } - // Write section data - for (auto §ion : outSections) { - if (!section->data.empty()) { - out.seekp(section->header.offset.value()); + return result && unsupportedTypes.size() == 0; +} + + +/** + * Fix file header to look like an RPL file! + */ +static bool +fixFileHeader(ElfFile &file) +{ + file.header.magic = elf::HeaderMagic; + file.header.fileClass = 1; + file.header.encoding = elf::ELFDATA2MSB; + file.header.elfVersion = elf::EV_CURRENT; + file.header.abi = elf::EABI_CAFE; + memset(&file.header.pad, 0, 7); + file.header.type = 0xFE01; + file.header.machine = elf::EM_PPC; + file.header.version = 1; + file.header.phoff = 0; + file.header.phentsize = 0; + file.header.phnum = 0; + file.header.shoff = align_up(sizeof(elf::Header), 64); + file.header.shnum = file.sections.size(); + file.header.shentsize = sizeof(elf::SectionHeader); + file.header.flags = 0; + file.header.ehsize = sizeof(elf::Header); + file.header.shstrndx = getSectionIndex(file, ".shstrtab"); + return true; +} + + +/** + * Fix the .addralign field for sections. + */ +static bool +fixSectionAlign(ElfFile &file) +{ + for (auto §ion : file.sections) { + if (section->header.type == elf::SHT_PROGBITS) { + section->header.addralign = 32; + } else if (section->header.type == elf::SHT_NOBITS) { + section->header.addralign = 64; + } else if (section->header.type == elf::SHT_RPL_IMPORTS) { + section->header.addralign = 4; + } + } + + return true; +} + +static bool +relocateSection(ElfFile &file, + ElfFile::Section §ion, + uint32_t newSectionAddress) +{ + auto sectionSize = section.data.size() ? section.data.size() : section.header.size; + auto oldSectionAddress = section.header.addr; + auto oldSectionAddressEnd = section.header.addr + sectionSize; + + // Relocate symbols pointing into this section + for (auto &symSection : file.sections) { + if (symSection->header.type != elf::SectionType::SHT_SYMTAB) { + continue; + } + + auto symbols = reinterpret_cast(symSection->data.data()); + auto numSymbols = symSection->data.size() / sizeof(elf::Symbol); + for (auto i = 0u; i < numSymbols; ++i) { + auto type = byte_swap(symbols[i].info) & 0xf; + auto value = byte_swap(symbols[i].value); + + // Only relocate data, func, section symbols + if (type != elf::STT_OBJECT && + type != elf::STT_FUNC && + type != elf::STT_SECTION) { + continue; + } + + if (value >= oldSectionAddress && value <= oldSectionAddressEnd) { + symbols[i].value = byte_swap((value - oldSectionAddress) + newSectionAddress); + } + } + } + + // Relocate relocations pointing into this section + for (auto &relaSection : file.sections) { + if (relaSection->header.type != elf::SectionType::SHT_RELA) { + continue; + } + + auto rela = reinterpret_cast(relaSection->data.data()); + auto numRelas = relaSection->data.size() / sizeof(elf::Rela); + for (auto i = 0u; i < numRelas; ++i) { + auto offset = byte_swap(rela[i].offset); + + if (offset >= oldSectionAddress && offset <= oldSectionAddressEnd) { + rela[i].offset = byte_swap((offset - oldSectionAddress) + newSectionAddress); + } + } + } + + section.header.addr = newSectionAddress; + return true; +} + + +/** + * Fix the loader virtual addresses. + * + * Linker script won't put symtab & strtab sections in our loader address, so + * we must fix that. + * + * Expected order: + * .fexports > .dexports > .symtab > .strtab > .shstrtab > {.fimport, .dimport} + */ +static bool +fixLoaderVirtualAddresses(ElfFile &file) +{ + auto addr = LoadBaseAddress; + + // All symbols pointing to this section require fixing + + if (auto section = getSectionByName(file, ".fexports")) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + addr += section->data.size(); + } + + if (auto section = getSectionByName(file, ".dexports")) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + addr += section->data.size(); + } + + if (auto section = getSectionByName(file, ".symtab")) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + section->header.flags |= elf::SHF_ALLOC; + addr += section->data.size(); + } + + if (auto section = getSectionByName(file, ".strtab")) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + section->header.flags |= elf::SHF_ALLOC; + addr += section->data.size(); + } + + if (auto section = getSectionByName(file, ".shstrtab")) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + section->header.flags |= elf::SHF_ALLOC; + addr += section->data.size(); + } + + for (auto §ion : file.sections) { + if (section->header.type == elf::SHT_RPL_IMPORTS) { + relocateSection(file, *section, + align_up(addr, section->header.addralign)); + addr += section->data.size(); + } + } + + return true; +} + + +/** + * Calculate section file offsets. + * + * Expected order: + * RPL_CRCS > RPL_FILEINFO > + * .rodata > .data > .module_id > + * .fexports > .dexports > + * .fimports > .dimports > + * .symtab > .strtab > .shstrtab > + * .syscall > .text > + * .rela.fexports > .rela.text > .rela.rodata > .rela.data + */ +static bool +calculateSectionOffsets(ElfFile &file) +{ + auto offset = file.header.shoff; + offset += align_up(file.sections.size() * sizeof(elf::SectionHeader), 64); + + if (auto section = getSectionByType(file, elf::SHT_RPL_CRCS)) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByType(file, elf::SHT_RPL_FILEINFO)) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".rodata")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".data")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->data.size(); + } + + if (auto section = getSectionByName(file, ".module_id")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".fexports")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".dexports")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + for (auto §ion : file.sections) { + if (section->header.type == elf::SHT_RPL_IMPORTS) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + } + + if (auto section = getSectionByName(file, ".symtab")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".strtab")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".shstrtab")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".syscall")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".text")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".rela.fexports")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".rela.text")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".rela.rodata")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + if (auto section = getSectionByName(file, ".rela.data")) { + section->header.offset = offset; + section->header.size = section->data.size(); + offset += section->header.size; + } + + return true; +} + + +/** + * Write out the final RPL. + */ +static bool +writeRpl(ElfFile &file, const std::string &filename) +{ + auto shoff = file.header.shoff; + + // Swap back file & section header to big endian before writing + byte_swap(file.header); + + for (auto §ion : file.sections) { + byte_swap(section->header); + } + + // Write the file out + std::ofstream out { filename, std::ofstream::binary }; + + if (!out.is_open()) { + fmt::print("Could not open {} for writing", filename); + return false; + } + + // Write file header + out.seekp(0, std::ios::beg); + out.write(reinterpret_cast(&file.header), sizeof(elf::Header)); + + // Write section headers + out.seekp(shoff, std::ios::beg); + for (const auto §ion : file.sections) { + out.write(reinterpret_cast(§ion->header), sizeof(elf::SectionHeader)); + } + + // Write sections + for (const auto §ion : file.sections) { + if (section->data.size()) { + out.seekp(byte_swap(section->header.offset), std::ios::beg); out.write(section->data.data(), section->data.size()); } } @@ -1196,22 +961,76 @@ write(ElfFile &file, const std::string &filename) return true; } -int main(int argc, char **argv) +int main(int argc, const char **argv) { if (argc < 3) { - std::cout << "Usage: " << argv[0] << " " << std::endl; + fmt::print("Usage: {} ", argv[0]); return -1; } + auto src = std::string { argv[1] }; + auto dst = std::string { argv[2] }; + + // Read elf into memory object! ElfFile elf; - auto src = argv[1]; - auto dst = argv[2]; - if (!read(elf, src)) { + if (!readElf(elf, src)) { + fmt::print("ERROR: readElf failed"); return -1; } - if (!write(elf, dst)) { + /* + * From here onwards file.header and section.header is in little endian, + * everything else remains in big endian! + */ + + if (!fixBssNoBits(elf)) { + fmt::print("ERROR: fixBssNoBits failed"); + return -1; + } + + if (!reorderSectionIndex(elf)) { + fmt::print("ERROR: reorderSectionIndex failed"); + return -1; + } + + if (!fixRelocations(elf)) { + fmt::print("ERROR: fixRelocations failed"); + return -1; + } + + if (!fixSectionAlign(elf)) { + fmt::print("ERROR: fixSectionAlign failed"); + return -1; + } + + if (!fixLoaderVirtualAddresses(elf)) { + fmt::print("ERROR: fixLoaderVirtualAddresses failed"); + return -1; + } + + if (!generateFileInfoSection(elf)) { + fmt::print("ERROR: generateFileInfoSection failed"); + return -1; + } + + if (!generateCrcSection(elf)) { + fmt::print("ERROR: generateCrcSection failed"); + return -1; + } + + if (!fixFileHeader(elf)) { + fmt::print("ERROR: fixFileHeader failed"); + return -1; + } + + if (!calculateSectionOffsets(elf)) { + fmt::print("ERROR: calculateSectionOffsets failed"); + return -1; + } + + if (!writeRpl(elf, dst)) { + fmt::print("ERROR: writeRpl failed"); return -1; } diff --git a/tools/implcheck/CMakeLists.txt b/tools/implcheck/CMakeLists.txt deleted file mode 100644 index 58d926a..0000000 --- a/tools/implcheck/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -project(implcheck) - -file(GLOB_RECURSE SOURCE_FILES *.cpp) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_executable(implcheck ${SOURCE_FILES} ${HEADER_FILES}) -set_target_properties(implcheck PROPERTIES FOLDER tools) - -target_link_libraries(implcheck PRIVATE - ${EXCMD_LINK} - ${FMTLIB_LINK} - ${ZLIB_LINK}) - -install(TARGETS implcheck RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/tools/implcheck/main.cpp b/tools/implcheck/main.cpp deleted file mode 100644 index dac6ce4..0000000 --- a/tools/implcheck/main.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "elf.h" - -struct Section -{ - elf::SectionHeader header; - std::vector data; -}; - -struct RplInfo -{ - std::set funcExports; - std::set dataExports; -}; - -struct ExportsInfo -{ - std::set funcExports; - std::set dataExports; -}; - -static bool -readSection(std::ifstream &fh, - elf::SectionHeader &header, - std::vector &data) -{ - // Read section header - fh.read(reinterpret_cast(&header), sizeof(elf::SectionHeader)); - - if (header.type == elf::SHT_NOBITS || !header.size) { - return true; - } - - // Read section data - if (header.flags & elf::SHF_DEFLATED) { - auto stream = z_stream {}; - auto ret = Z_OK; - - // Read the original size - fh.seekg(header.offset.value()); - be_val size = 0; - fh.read(reinterpret_cast(&size), sizeof(uint32_t)); - data.resize(size); - - // Inflate - memset(&stream, 0, sizeof(stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - ret = inflateInit(&stream); - - if (ret != Z_OK) { - std::cout << "Couldn't decompress .rpx section because inflateInit returned " << ret << std::endl; - data.clear(); - return false; - } else { - std::vector temp; - temp.resize(header.size - sizeof(uint32_t)); - fh.read(temp.data(), temp.size()); - - stream.avail_in = header.size; - stream.next_in = reinterpret_cast(temp.data()); - stream.avail_out = static_cast(data.size()); - stream.next_out = reinterpret_cast(data.data()); - - ret = inflate(&stream, Z_FINISH); - - if (ret != Z_OK && ret != Z_STREAM_END) { - std::cout << "Couldn't decompress .rpx section because inflate returned " << ret << std::endl; - data.clear(); - return false; - } - - inflateEnd(&stream); - } - } else { - data.resize(header.size); - fh.seekg(header.offset.value()); - fh.read(data.data(), header.size); - } - - return true; -} - -static void -readExports(RplInfo &info, const Section §ion) -{ - auto exports = reinterpret_cast(section.data.data()); - auto strTab = section.data.data(); - - for (auto i = 0u; i < exports->count; ++i) { - // TLS exports have the high bit set in name for some unknown reason... - auto name = strTab + (exports->exports[i].name & 0x7FFFFFFF); - auto value = exports->exports[i].value; - - if (value >= 0x10000000) { - info.dataExports.insert(name); - } else { - info.funcExports.insert(name); - } - } -} - -static bool -readRPL(RplInfo &info, std::ifstream &fh) -{ - elf::Header header; - fh.read(reinterpret_cast(&header), sizeof(elf::Header)); - - if (header.magic != elf::HeaderMagic) { - std::cout << "Invalid ELF magic header" << std::endl; - return false; - } - - // Read sections - auto sections = std::vector
{}; - - for (auto i = 0u; i < header.shnum; ++i) { - Section section; - fh.seekg(header.shoff + header.shentsize * i); - - if (!readSection(fh, section.header, section.data)) { - std::cout << "Error reading section " << i << std::endl; - return false; - } - - sections.push_back(section); - } - - // Find strtab - //auto shStrTab = reinterpret_cast(sections[header.shstrndx].data.data()); - - // Print section data - for (auto i = 0u; i < sections.size(); ++i) { - auto §ion = sections[i]; - - if (section.header.type == elf::SHT_RPL_EXPORTS) { - readExports(info, section); - } - } - - return true; -} - -static bool -readTextExports(ExportsInfo &info, std::ifstream &fh) -{ - std::string line; - - while (std::getline(fh, line)) { - if (line.find("EXPORT(") == 0) { - auto name = line.substr(strlen("EXPORT(")); - name = name.erase(name.find(')'), 2); - info.funcExports.insert(name); - } - } - - return true; -} - -int main(int argc, char **argv) -{ - excmd::parser parser; - excmd::option_state options; - using excmd::description; - using excmd::value; - - try { - parser.global_options() - .add_option("H,help", - description { "Show help." }) - .add_option("f,functions", - description { "Print unimplemented function exports." }) - .add_option("d,data", - description { "Print unimplemented data exports." }); - - parser.default_command() - .add_argument("rpl-path", - description { "Path to RPL file" }, - value {}) - .add_argument("exports-path", - description { "Path to exports.h file" }, - value {}); - - options = parser.parse(argc, argv); - } catch (excmd::exception ex) { - std::cout << "Error parsing options: " << ex.what() << std::endl; - return -1; - } - - if (options.empty() || options.has("help") || !options.has("rpl-path") || !options.has("exports-path")) { - std::cout << argv[0] << " rpl-path exports-path" << std::endl; - std::cout << parser.format_help(argv[0]); - return 0; - } - - auto rplPath = options.get("rpl-path"); - auto exportsPath = options.get("exports-path"); - - // Read RPL - std::ifstream fh { rplPath, std::ifstream::binary }; - - if (!fh.is_open()) { - std::cout << "Could not open " << rplPath << " for reading" << std::endl; - return -1; - } - - RplInfo rplInfo; - - if (!readRPL(rplInfo, fh)) { - std::cout << "Error reading " << rplPath << std::endl; - return -1; - } - - fh.close(); - - // Read exports - fh.open(exportsPath, std::ifstream::in); - - if (!fh.is_open()) { - std::cout << "Could not open " << exportsPath << " for reading" << std::endl; - return -1; - } - - ExportsInfo exportsInfo; - - if (!readTextExports(exportsInfo, fh)) { - std::cout << "Error reading " << exportsPath << std::endl; - return -1; - } - - fh.close(); - - // Check that we do not have any extra exports which are not exported from RPL. - std::set funcUnion, extraExports; - int result = 0; - - std::set_union(rplInfo.funcExports.begin(), rplInfo.funcExports.end(), - exportsInfo.funcExports.begin(), exportsInfo.funcExports.end(), - std::inserter(funcUnion, funcUnion.begin())); - - std::set_difference(funcUnion.begin(), funcUnion.end(), - rplInfo.funcExports.begin(), rplInfo.funcExports.end(), - std::inserter(extraExports, extraExports.begin())); - - if (!extraExports.empty()) { - std::cout << "Error: Exports found in exports.h which do not exist in rpl:" << std::endl; - - for (auto &name : extraExports) { - std::cout << " - " << name << std::endl; - } - - std::cout << std::endl; - result = -1; - } - - if (options.has("functions")) { - // Print implemented function exports - std::set intersection; - - std::set_intersection(rplInfo.funcExports.begin(), rplInfo.funcExports.end(), - exportsInfo.funcExports.begin(), exportsInfo.funcExports.end(), - std::inserter(intersection, intersection.begin())); - - if (!intersection.empty()) { - std::cout << "Implemented function exports:" << std::endl; - - for (auto &name : intersection) { - std::cout << " - " << name << std::endl; - } - - std::cout << std::endl; - } - - // Print unimplemented function exports - std::set difference; - - std::set_difference(rplInfo.funcExports.begin(), rplInfo.funcExports.end(), - exportsInfo.funcExports.begin(), exportsInfo.funcExports.end(), - std::inserter(difference, difference.begin())); - - if (!difference.empty()) { - std::cout << "Unimplemented function exports:" << std::endl; - - for (auto &name : difference) { - std::cout << " - " << name << std::endl; - } - - std::cout << std::endl; - } - } - - if (options.has("data")) { - // Print implemented data exports - std::set intersection; - - std::set_intersection(rplInfo.dataExports.begin(), rplInfo.dataExports.end(), - exportsInfo.dataExports.begin(), exportsInfo.dataExports.end(), - std::inserter(intersection, intersection.begin())); - - if (!intersection.empty()) { - std::cout << "Implemented data exports:" << std::endl; - - for (auto &name : intersection) { - std::cout << " - " << name << std::endl; - } - - std::cout << std::endl; - } - - // Print unimplemented data exports - std::set difference; - - std::set_difference(rplInfo.dataExports.begin(), rplInfo.dataExports.end(), - exportsInfo.dataExports.begin(), exportsInfo.dataExports.end(), - std::inserter(difference, difference.begin())); - - if (!difference.empty()) { - std::cout << "Unimplemented data exports:" << std::endl; - - for (auto &name : difference) { - std::cout << " - " << name << std::endl; - } - - std::cout << std::endl; - } - } - - return result; -} diff --git a/tools/libraries/CMakeLists.txt b/tools/libraries/CMakeLists.txt new file mode 100644 index 0000000..468fe7d --- /dev/null +++ b/tools/libraries/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(fmt) diff --git a/tools/libraries/fmt b/tools/libraries/fmt new file mode 160000 index 0000000..5386f1d --- /dev/null +++ b/tools/libraries/fmt @@ -0,0 +1 @@ +Subproject commit 5386f1df20392a08844f5034e8436c6ec7ce0b03 diff --git a/tools/readrpl/CMakeLists.txt b/tools/readrpl/CMakeLists.txt deleted file mode 100644 index 31a6b29..0000000 --- a/tools/readrpl/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -project(readrpl) - -file(GLOB_RECURSE SOURCE_FILES *.cpp) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_executable(readrpl ${SOURCE_FILES} ${HEADER_FILES}) -set_target_properties(readrpl PROPERTIES FOLDER tools) - -target_link_libraries(readrpl PRIVATE - ${EXCMD_LINK} - ${FMTLIB_LINK} - ${ZLIB_LINK}) - -install(TARGETS readrpl RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/tools/readrpl/main.cpp b/tools/readrpl/main.cpp deleted file mode 100644 index 836d6bb..0000000 --- a/tools/readrpl/main.cpp +++ /dev/null @@ -1,797 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "elf.h" - -struct Section -{ - elf::SectionHeader header; - std::vector data; -}; - -static std::string -formatET(uint32_t type) -{ - switch (type) { - case elf::ET_NONE: - return "ET_NONE"; - case elf::ET_REL: - return "ET_REL"; - case elf::ET_EXEC: - return "ET_EXEC"; - case elf::ET_DYN: - return "ET_DYN"; - case elf::ET_CORE: - return "ET_CORE"; - case elf::ET_CAFE_RPL: - return "ET_CAFE_RPL"; - default: - return ""; - } -} - -static std::string -formatEM(uint32_t machine) -{ - switch (machine) { - case elf::EM_PPC: - return "EM_PPC"; - default: - return ""; - } -} - -static std::string -formatEABI(uint32_t machine) -{ - switch (machine) { - case elf::EABI_CAFE: - return "EABI_CAFE"; - default: - return ""; - } -} - -static std::string -formatSHF(uint32_t flags) -{ - std::string result = ""; - - if (flags & elf::SHF_WRITE) { - result += "W"; - } - - if (flags & elf::SHF_ALLOC) { - result += "A"; - } - - if (flags & elf::SHF_EXECINSTR) { - result += "X"; - } - - if (flags & elf::SHF_DEFLATED) { - result += "Z"; - } - - return result; -} - -static std::string -formatSHT(uint32_t type) -{ - switch (type) { - case elf::SHT_NULL: - return "SHT_NULL"; - case elf::SHT_PROGBITS: - return "SHT_PROGBITS"; - case elf::SHT_SYMTAB: - return "SHT_SYMTAB"; - case elf::SHT_STRTAB: - return "SHT_STRTAB"; - case elf::SHT_RELA: - return "SHT_RELA"; - case elf::SHT_HASH: - return "SHT_HASH"; - case elf::SHT_DYNAMIC: - return "SHT_DYNAMIC"; - case elf::SHT_NOTE: - return "SHT_NOTE"; - case elf::SHT_NOBITS: - return "SHT_NOBITS"; - case elf::SHT_REL: - return "SHT_REL"; - case elf::SHT_SHLIB: - return "SHT_SHLIB"; - case elf::SHT_DYNSYM: - return "SHT_DYNSYM"; - case elf::SHT_INIT_ARRAY: - return "SHT_INIT_ARRAY"; - case elf::SHT_FINI_ARRAY: - return "SHT_FINI_ARRAY"; - case elf::SHT_PREINIT_ARRAY: - return "SHT_PREINIT_ARRAY"; - case elf::SHT_GROUP: - return "SHT_GROUP"; - case elf::SHT_SYMTAB_SHNDX: - return "SHT_SYMTAB_SHNDX"; - case elf::SHT_LOPROC: - return "SHT_LOPROC"; - case elf::SHT_HIPROC: - return "SHT_HIPROC"; - case elf::SHT_LOUSER: - return "SHT_LOUSER"; - case elf::SHT_RPL_EXPORTS: - return "SHT_RPL_EXPORTS"; - case elf::SHT_RPL_IMPORTS: - return "SHT_RPL_IMPORTS"; - case elf::SHT_RPL_CRCS: - return "SHT_RPL_CRCS"; - case elf::SHT_RPL_FILEINFO: - return "SHT_RPL_FILEINFO"; - case elf::SHT_HIUSER: - return "SHT_HIUSER"; - default: - return fmt::format("__UNK_{:08X}", type); - } -} - -static std::string -formatHeader(elf::Header &header) -{ - fmt::MemoryWriter out; - out.write("ElfHeader\n"); - out.write(" magic = 0x{:08X}\n", header.magic); - out.write(" fileClass = {}\n", static_cast(header.fileClass)); - out.write(" encoding = {}\n", static_cast(header.encoding)); - out.write(" elfVersion = {}\n", static_cast(header.elfVersion)); - out.write(" abi = {} 0x{:04x}\n", formatEABI(header.abi), header.abi); - - out.write(" type = {} 0x{:04X}\n", formatET(header.type), header.type); - out.write(" machine = {} {}\n", formatEM(header.machine), header.machine); - out.write(" version = 0x{:X}\n", header.version); - out.write(" entry = 0x{:08X}\n", static_cast(header.entry)); - out.write(" phoff = 0x{:X}\n", header.phoff); - out.write(" shoff = 0x{:X}\n", header.shoff); - out.write(" flags = 0x{:X}\n", header.flags); - out.write(" ehsize = {}\n", header.ehsize); - out.write(" phentsize = {}\n", header.phentsize); - out.write(" phnum = {}\n", header.phnum); - out.write(" shentsize = {}\n", header.shentsize); - out.write(" shnum = {}\n", header.shnum); - out.write(" shstrndx = {}\n", header.shstrndx); - - return out.str(); -} - -static std::string -formatSectionSummary(std::vector
§ions, const char *shStrTab) -{ - fmt::MemoryWriter out; - out.write("Sections:\n"); - out.write(" {:<4} {:<20} {:<16} {:<8} {:<6} {:<6} {:<2} {:<4} {:<2} {:<4} {:<5}\n", - "[Nr]", "Name", "Type", "Addr", "Off", "Size", "ES", "Flag", "Lk", "Info", "Align"); - - for (auto i = 0u; i < sections.size(); ++i) { - auto §ion = sections[i]; - auto name = shStrTab + section.header.name; - auto type = formatSHT(section.header.type); - auto flags = formatSHF(section.header.flags); - - out.write(" [{:>2}] {:<20} {:<16} {:08X} {:06X} {:06X} {:02X} {:>4} {:>2} {:>4} {:>5}\n", - i, - name, - type, - static_cast(section.header.addr), - section.header.offset, - section.header.size, - section.header.entsize, - flags, - section.header.link, - section.header.info, - section.header.addralign); - } - - return out.str(); -} - -static void -formatFileInfo(fmt::MemoryWriter &out, Section §ion) -{ - auto &info = *reinterpret_cast(section.data.data()); - auto filename = section.data.data() + info.filename; - - out.write(" version = 0x{:08X}\n", static_cast(info.version)); - out.write(" textSize = 0x{:08X}\n", info.textSize); - out.write(" textAlign = 0x{:X}\n", info.textAlign); - out.write(" dataSize = 0x{:08X}\n", info.dataSize); - out.write(" dataAlign = 0x{:X}\n", info.dataAlign); - out.write(" loadSize = 0x{:08X}\n", info.loadSize); - out.write(" loadAlign = 0x{:X}\n", info.loadAlign); - out.write(" tempSize = 0x{:X}\n", info.tempSize); - out.write(" trampAdjust = 0x{:X}\n", info.trampAdjust); - out.write(" trampAddition = 0x{:X}\n", info.trampAddition); - out.write(" sdaBase = 0x{:08X}\n", info.sdaBase); - out.write(" sda2Base = 0x{:08X}\n", info.sda2Base); - out.write(" stackSize = 0x{:08X}\n", info.stackSize); - out.write(" heapSize = 0x{:08X}\n", info.heapSize); - - if (info.filename) { - out.write(" filename = {}\n", filename); - } else { - out.write(" filename = 0\n"); - } - - out.write(" flags = 0x{:X}\n", info.flags); - out.write(" minSdkVersion = 0x{:08X}\n", static_cast(info.minVersion)); - out.write(" compressionLevel = {}\n", info.compressionLevel); - out.write(" fileInfoPad = 0x{:X}\n", info.fileInfoPad); - out.write(" sdkVersion = 0x{:X}\n", info.cafeSdkVersion); - out.write(" sdkRevision = 0x{:X}\n", info.cafeSdkRevision); - out.write(" tlsModuleIndex = 0x{:X}\n", info.tlsModuleIndex); - out.write(" tlsAlignShift = 0x{:X}\n", info.tlsAlignShift); - out.write(" runtimeFileInfoSize = 0x{:X}\n", info.runtimeFileInfoSize); - - if (info.tagOffset) { - const char *tags = section.data.data() + info.tagOffset; - out.write(" Tags:\n"); - - while (*tags) { - auto key = tags; - tags += strlen(tags) + 1; - auto value = tags; - tags += strlen(tags) + 1; - - out.write(" \"{}\" = \"{}\"\n", key, value); - } - } -} - -static std::string -formatRelType(uint32_t type) -{ - switch (type) { - case elf::R_PPC_NONE: - return "NONE"; - case elf::R_PPC_ADDR32: - return "ADDR32"; - case elf::R_PPC_ADDR24: - return "ADDR24"; - case elf::R_PPC_ADDR16: - return "ADDR16"; - case elf::R_PPC_ADDR16_LO: - return "ADDR16_LO"; - case elf::R_PPC_ADDR16_HI: - return "ADDR16_HI"; - case elf::R_PPC_ADDR16_HA: - return "ADDR16_HA"; - case elf::R_PPC_ADDR14: - return "ADDR14"; - case elf::R_PPC_ADDR14_BRTAKEN: - return "ADDR14_BRTAKEN"; - case elf::R_PPC_ADDR14_BRNTAKEN: - return "ADDR14_BRNTAKEN"; - case elf::R_PPC_REL24: - return "REL24"; - case elf::R_PPC_REL14: - return "REL14"; - case elf::R_PPC_REL14_BRTAKEN: - return "REL14_BRTAKEN"; - case elf::R_PPC_REL14_BRNTAKEN: - return "REL14_BRNTAKEN"; - case elf::R_PPC_GOT16: - return "GOT16"; - case elf::R_PPC_GOT16_LO: - return "GOT16_LO"; - case elf::R_PPC_GOT16_HI: - return "GOT16_HI"; - case elf::R_PPC_GOT16_HA: - return "GOT16_HA"; - case elf::R_PPC_PLTREL24: - return "PLTREL24"; - case elf::R_PPC_JMP_SLOT: - return "JMP_SLOT"; - case elf::R_PPC_RELATIVE: - return "RELATIVE"; - case elf::R_PPC_LOCAL24PC: - return "LOCAL24PC"; - case elf::R_PPC_REL32: - return "REL32"; - case elf::R_PPC_TLS: - return "TLS"; - case elf::R_PPC_DTPMOD32: - return "DTPMOD32"; - case elf::R_PPC_TPREL16: - return "TPREL16"; - case elf::R_PPC_TPREL16_LO: - return "TPREL16_LO"; - case elf::R_PPC_TPREL16_HI: - return "TPREL16_HI"; - case elf::R_PPC_TPREL16_HA: - return "TPREL16_HA"; - case elf::R_PPC_TPREL32: - return "TPREL32"; - case elf::R_PPC_DTPREL16: - return "DTPREL16"; - case elf::R_PPC_DTPREL16_LO: - return "DTPREL16_LO"; - case elf::R_PPC_DTPREL16_HI: - return "DTPREL16_HI"; - case elf::R_PPC_DTPREL16_HA: - return "DTPREL16_HA"; - case elf::R_PPC_DTPREL32: - return "DTPREL32"; - case elf::R_PPC_GOT_TLSGD16: - return "GOT_TLSGD16"; - case elf::R_PPC_GOT_TLSGD16_LO: - return "GOT_TLSGD16_LO"; - case elf::R_PPC_GOT_TLSGD16_HI: - return "GOT_TLSGD16_HI"; - case elf::R_PPC_GOT_TLSGD16_HA: - return "GOT_TLSGD16_HA"; - case elf::R_PPC_GOT_TLSLD16: - return "GOT_TLSLD16"; - case elf::R_PPC_GOT_TLSLD16_LO: - return "GOT_TLSLD16_LO"; - case elf::R_PPC_GOT_TLSLD16_HI: - return "GOT_TLSLD16_HI"; - case elf::R_PPC_GOT_TLSLD16_HA: - return "GOT_TLSLD16_HA"; - case elf::R_PPC_GOT_TPREL16: - return "GOT_TPREL16"; - case elf::R_PPC_GOT_TPREL16_LO: - return "GOT_TPREL16_LO"; - case elf::R_PPC_GOT_TPREL16_HI: - return "GOT_TPREL16_HI"; - case elf::R_PPC_GOT_TPREL16_HA: - return "GOT_TPREL16_HA"; - case elf::R_PPC_GOT_DTPREL16: - return "GOT_DTPREL16"; - case elf::R_PPC_GOT_DTPREL16_LO: - return "GOT_DTPREL16_LO"; - case elf::R_PPC_GOT_DTPREL16_HI: - return "GOT_DTPREL16_HI"; - case elf::R_PPC_GOT_DTPREL16_HA: - return "GOT_DTPREL16_HA"; - case elf::R_PPC_TLSGD: - return "TLSGD"; - case elf::R_PPC_TLSLD: - return "TLSLD"; - case elf::R_PPC_EMB_SDA21: - return "EMB_SDA21"; - case elf::R_PPC_REL16: - return "REL16"; - case elf::R_PPC_REL16_LO: - return "REL16_LO"; - case elf::R_PPC_REL16_HI: - return "REL16_HI"; - case elf::R_PPC_REL16_HA: - return "REL16_HA"; - default: - return fmt::format("__UNK_{:02X}", type); - } -} - -static std::string -formatSymType(uint32_t type) -{ - switch (type) { - case elf::STT_NOTYPE: - return "NOTYPE"; - case elf::STT_OBJECT: - return "OBJECT"; - case elf::STT_FUNC: - return "FUNC"; - case elf::STT_SECTION: - return "SECTION"; - case elf::STT_FILE: - return "FILE"; - case elf::STT_COMMON: - return "COMMON"; - case elf::STT_TLS: - return "TLS"; - case elf::STT_LOOS: - return "LOOS"; - case elf::STT_HIOS: - return "HIOS"; - case elf::STT_GNU_IFUNC: - return "GNU_IFUNC"; - default: - return fmt::format("__UNK_{:02X}", type); - } -} - -static std::string -formatSymBinding(uint32_t type) -{ - switch (type) { - case elf::STB_LOCAL: - return "LOCAL"; - case elf::STB_GLOBAL: - return "GLOBAL"; - case elf::STB_WEAK: - return "WEAK"; - case elf::STB_GNU_UNIQUE: - return "UNIQUE"; - default: - return fmt::format("__UNK_{:02X}", type); - } -} - -static std::string -formatSymShndx(uint32_t type) -{ - switch (type) { - case elf::SHN_UNDEF: - return "UND"; - case elf::SHN_ABS: - return "ABS"; - case elf::SHN_COMMON: - return "CMN"; - case elf::SHN_XINDEX: - return "UND"; - default: - return fmt::format("{}", type); - } -} - -static void -formatRela(fmt::MemoryWriter &out, std::vector
§ions, const char *shStrTab, Section §ion) -{ - out.write(" {:<8} {:<8} {:<16} {:<8} {}\n", "Offset", "Info", "Type", "Value", "Name + Addend"); - - auto &symSec = sections[section.header.link]; - auto symbols = reinterpret_cast(symSec.data.data()); - auto &symStrTab = sections[symSec.header.link]; - - auto relas = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Rela); - - for (auto i = 0u; i < count; ++i) { - auto &rela = relas[i]; - - auto index = rela.info >> 8; - auto type = rela.info & 0xff; - auto typeName = formatRelType(type); - - auto symbol = symbols[index]; - auto name = reinterpret_cast(symStrTab.data.data()) + symbol.name; - - out.write(" {:08X} {:08X} {:<16} {:08X} {} + {:X}\n", - static_cast(rela.offset), - rela.info, - typeName, - static_cast(symbol.value), - name, - static_cast(rela.addend)); - } -} - -static void -formatSymTab(fmt::MemoryWriter &out, std::vector
§ions, Section §ion) -{ - auto strTab = reinterpret_cast(sections[section.header.link].data.data()); - - out.write(" {:<4} {:<8} {:<6} {:<8} {:<8} {:<3} {}\n", - "Num", "Value", "Size", - "Type", "Bind", - "Ndx", "Name"); - - auto id = 0u; - auto symbols = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::Symbol); - - for (auto i = 0u; i < count; ++i) { - auto &symbol = symbols[i]; - - auto name = strTab + symbol.name; - auto binding = symbol.info >> 4; - auto type = symbol.info & 0xf; - auto typeName = formatSymType(type); - auto bindingName = formatSymBinding(binding); - auto ndx = formatSymShndx(symbol.shndx); - - out.write(" {:>4} {:08X} {:>6} {:<8} {:<8} {:>3} {}\n", - id, static_cast(symbol.value), symbol.size, typeName, bindingName, ndx, name); - - ++id; - } -} - -static void -formatRplImports(fmt::MemoryWriter &out, std::vector
§ions, uint32_t index, Section §ion) -{ - auto import = reinterpret_cast(section.data.data()); - - out.write(" name = {}\n", import->name); - out.write(" signature = 0x{:08X}\n", static_cast(import->signature)); - out.write(" count = {}\n", import->count); - - if (import->count) { - for (auto &symSection : sections) { - if (symSection.header.type != elf::SHT_SYMTAB) { - continue; - } - - auto symbols = reinterpret_cast(symSection.data.data()); - auto count = symSection.data.size() / sizeof(elf::Symbol); - auto strTab = reinterpret_cast(sections[symSection.header.link].data.data()); - - for (auto i = 0u; i < count; ++i) { - auto &symbol = symbols[i]; - - if (symbol.shndx == index) { - out.write(" {}\n", strTab + symbol.name); - } - } - } - } -} - -static void -formatRplCrcs(fmt::MemoryWriter &out, std::vector
§ions, const char *shStrTab, Section §ion) -{ - auto crcs = reinterpret_cast(section.data.data()); - auto count = section.data.size() / sizeof(elf::RplCrc); - - for (auto i = 0u; i < count; ++i) { - auto name = shStrTab + sections[i].header.name; - out.write(" [{:>2}] 0x{:08X} {}\n", i, static_cast(crcs[i].crc), name); - } -} - -static void -formatRplExports(fmt::MemoryWriter &out, Section §ion) -{ - auto exports = reinterpret_cast(section.data.data()); - auto strTab = section.data.data(); - - out.write(" signature = 0x{:08X}\n", static_cast(exports->signature)); - out.write(" count = {}\n", exports->count); - - for (auto i = 0u; i < exports->count; ++i) { - // TLS exports have the high bit set in name for some unknown reason... - auto name = strTab + (exports->exports[i].name & 0x7FFFFFFF); - auto value = exports->exports[i].value; - - out.write(" 0x{:08X} {}\n", static_cast(value), name); - } -} - -bool readSection(std::ifstream &fh, elf::SectionHeader &header, std::vector &data) -{ - // Read section header - fh.read(reinterpret_cast(&header), sizeof(elf::SectionHeader)); - - if (header.type == elf::SHT_NOBITS || !header.size) { - return true; - } - - // Read section data - if (header.flags & elf::SHF_DEFLATED) { - auto stream = z_stream {}; - auto ret = Z_OK; - - // Read the original size - fh.seekg(header.offset.value()); - be_val size = 0; - fh.read(reinterpret_cast(&size), sizeof(uint32_t)); - data.resize(size); - - // Inflate - memset(&stream, 0, sizeof(stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - - ret = inflateInit(&stream); - - if (ret != Z_OK) { - std::cout << "Couldn't decompress .rpx section because inflateInit returned " << ret << std::endl; - data.clear(); - return false; - } else { - std::vector temp; - temp.resize(header.size-sizeof(uint32_t)); - fh.read(temp.data(), temp.size()); - - stream.avail_in = header.size; - stream.next_in = reinterpret_cast(temp.data()); - stream.avail_out = static_cast(data.size()); - stream.next_out = reinterpret_cast(data.data()); - - ret = inflate(&stream, Z_FINISH); - - if (ret != Z_OK && ret != Z_STREAM_END) { - std::cout << "Couldn't decompress .rpx section because inflate returned " << ret << std::endl; - data.clear(); - return false; - } - - inflateEnd(&stream); - } - } else { - data.resize(header.size); - fh.seekg(header.offset.value()); - fh.read(data.data(), header.size); - } - - return true; -} - -int main(int argc, char **argv) -{ - excmd::parser parser; - excmd::option_state options; - using excmd::description; - using excmd::value; - - try { - parser.global_options() - .add_option("H,help", - description { "Show help." }) - .add_option("a,all", - description { "Equivalent to: -h -S -s -r -i -x -c -f" }) - .add_option("h,file-header", - description { "Display the ELF file header" }) - .add_option("S,sections", - description { "Display the sections' header" }) - .add_option("s,symbols", - description { "Display the symbol table" }) - .add_option("r,relocs", - description { "Display the relocations" }) - .add_option("i,imports", - description { "Display the RPL imports" }) - .add_option("x,exports", - description { "Display the RPL exports" }) - .add_option("c,crc", - description { "Display the RPL crc" }) - .add_option("f,file-info", - description { "Display the RPL file info" }); - - parser.default_command() - .add_argument("path", - description { "Path to RPL file" }, - value {}); - - options = parser.parse(argc, argv); - } catch (excmd::exception ex) { - std::cout << "Error parsing options: " << ex.what() << std::endl; - return -1; - } - - if (options.empty() || options.has("help") || !options.has("path")) { - std::cout << argv[0] << " path" << std::endl; - std::cout << parser.format_help(argv[0]) << std::endl; - return 0; - } - - auto all = options.has("all"); - - auto dumpElfHeader = all || options.has("file-header"); - auto dumpSectionSummary = all || options.has("sections"); - auto dumpSectionRela = all || options.has("relocs"); - auto dumpSectionSymtab = all || options.has("symbols"); - auto dumpSectionRplExports = all || options.has("exports"); - auto dumpSectionRplImports = all || options.has("imports"); - auto dumpSectionRplCrcs = all || options.has("crc"); - auto dumpSectionRplFileinfo = all || options.has("file-info"); - auto path = options.get("path"); - - // If no options are set (other than "path"), let's default to a summary - if (options.set_options.size() == 1) { - dumpElfHeader = true; - dumpSectionSummary = true; - dumpSectionRplFileinfo = true; - } - - // Read file - std::ifstream fh { path, std::ifstream::binary }; - - if (!fh.is_open()) { - std::cout << "Could not open " << path << " for reading" << std::endl; - return -1; - } - - elf::Header header; - fh.read(reinterpret_cast(&header), sizeof(elf::Header)); - - if (header.magic != elf::HeaderMagic) { - std::cout << "Invalid ELF magic header" << std::endl; - return -1; - } - - // Read sections - auto sections = std::vector
{}; - - for (auto i = 0u; i < header.shnum; ++i) { - Section section; - fh.seekg(header.shoff + header.shentsize * i); - - if (!readSection(fh, section.header, section.data)) { - std::cout << "Error reading section " << i << std::endl; - return -1; - } - - sections.push_back(section); - } - - // Find strtab - auto shStrTab = reinterpret_cast(sections[header.shstrndx].data.data()); - - // Format shit - if (dumpElfHeader) { - std::cout << formatHeader(header) << std::endl; - } - - if (dumpSectionSummary) { - std::cout << formatSectionSummary(sections, shStrTab) << std::endl; - } - - // Print section data - for (auto i = 0u; i < sections.size(); ++i) { - fmt::MemoryWriter out; - auto §ion = sections[i]; - auto name = shStrTab + section.header.name; - out.write("Section {}: {}, {}, {} bytes\n", i, formatSHT(section.header.type), name, section.data.size()); - - switch (section.header.type) { - case elf::SHT_NULL: - case elf::SHT_NOBITS: - // Print nothing - break; - case elf::SHT_RELA: - if (!dumpSectionRela) { - continue; - } - - formatRela(out, sections, shStrTab, section); - break; - case elf::SHT_SYMTAB: - if (!dumpSectionSymtab) { - continue; - } - - formatSymTab(out, sections, section); - break; - case elf::SHT_STRTAB: - break; - case elf::SHT_PROGBITS: - break; - case elf::SHT_RPL_EXPORTS: - if (!dumpSectionRplExports) { - continue; - } - - formatRplExports(out, section); - break; - case elf::SHT_RPL_IMPORTS: - if (!dumpSectionRplImports) { - continue; - } - - formatRplImports(out, sections, i, section); - break; - case elf::SHT_RPL_CRCS: - if (!dumpSectionRplCrcs) { - continue; - } - - formatRplCrcs(out, sections, shStrTab, section); - break; - case elf::SHT_RPL_FILEINFO: - if (!dumpSectionRplFileinfo) { - continue; - } - - formatFileInfo(out, section); - break; - } - - std::cout << out.str() << std::endl; - } - - return 0; -} diff --git a/tools/rplgen/CMakeLists.txt b/tools/rplgen/CMakeLists.txt new file mode 100644 index 0000000..4e4f5bf --- /dev/null +++ b/tools/rplgen/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable(wut-rplgen rplgen.cpp) +target_include_directories(wut-rplgen PRIVATE + ${ZLIB_INCLUDE_DIR}) +target_link_libraries(wut-rplgen + ${ZLIB_LIBRARIES}) + +install(TARGETS wut-rplgen RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/tools/rplgen/rplgen.cpp b/tools/rplgen/rplgen.cpp new file mode 100644 index 0000000..138fc7c --- /dev/null +++ b/tools/rplgen/rplgen.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// trim from start +// Taken from https://stackoverflow.com/a/217605 +static inline void ltrim(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { + return !std::isspace(ch); + })); +} + +// trim from end (in place) +static inline void rtrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { + return !std::isspace(ch); + }).base(), s.end()); +} + +// trim from both ends +static inline void +trim(std::string &s) +{ + ltrim(s); + rtrim(s); +} + +uint32_t +byte_swap(uint32_t v) +{ + return ((v >> 24) & 0xff) | + ((v << 8) & 0xff0000) | + ((v >> 8) & 0xff00) | + ((v << 24) & 0xff000000); +} + +enum class ReadMode +{ + INVALID, + TEXT, + DATA +}; + +void +writeExports(std::ofstream &out, + const std::string &moduleName, + bool isData, + const std::vector &exports) +{ + // Align module name up to 8 bytes + auto moduleNameSize = (moduleName.length() + 1 + 7) & ~7; + + // Calculate the data block size + auto exportSecSize = exports.size() * 8; + + if (exportSecSize < moduleNameSize) { + exportSecSize = moduleNameSize; + } + + // Calculate export hash + uint32_t exportsHash = crc32(0, Z_NULL, 0); + + for (auto &exp : exports) { + exportsHash = crc32(exportsHash, reinterpret_cast(exp.data()), exp.size() + 1); + } + + std::array extraHashBytes; + extraHashBytes.fill(0); + exportsHash = crc32(exportsHash, extraHashBytes.data(), extraHashBytes.size()); + + // Setup section data + std::vector secData; + secData.resize(exportSecSize / 4, 0); + memcpy(secData.data(), moduleName.c_str(), moduleName.length()); + + out << std::endl; + + if (isData) { + out << ".section .dimport_"; + } else { + out << ".section .fimport_"; + } + + out << moduleName << ", \"ax\", @0x80000002" << std::endl; + out << ".align 4" << std::endl; + out << std::endl; + + out << ".long " << exports.size() << std::endl; + out << ".long 0x" << std::hex << exportsHash << std::endl; + out << std::endl; + + const char *type = isData ? "@object" : "@function"; + + for (auto i = 0; i < exportSecSize / 8; ++i) { + if (i < exports.size()) { + out << ".global " << exports[i] << std::endl; + out << ".type " << exports[i] << ", " << type << std::endl; + out << exports[i] << ":" << std::endl; + } + + out << ".long 0x" << std::hex << byte_swap(secData[i * 2 + 0]) << std::endl; + out << ".long 0x" << std::hex << byte_swap(secData[i * 2 + 1]) << std::endl; + out << std::endl; + } +} + +int main(int argc, char **argv) +{ + std::string moduleName; + std::vector funcExports, dataExports; + ReadMode readMode = ReadMode::INVALID; + + if (argc < 3) { + std::cout << argv[0] << " " << std::endl; + return 0; + } + + { + std::ifstream in; + in.open(argv[1]); + + if (!in.is_open()) { + std::cout << "Could not open file " << argv[1] << " for reading" << std::endl; + return -1; + } + + std::string line; + while (std::getline(in, line)) { + // Trim comments + std::size_t commentOffset = line.find("//"); + if (commentOffset != std::string::npos) { + line = line.substr(0, commentOffset); + } + + // Trim whitespace + trim(line); + + // Skip blank lines + if (line.length() == 0) { + continue; + } + + // Look for section headers + if (line[0] == ':') { + if (line.substr(1) == "TEXT") { + readMode = ReadMode::TEXT; + } else if (line.substr(1) == "DATA") { + readMode = ReadMode::DATA; + } else if (line.substr(1, 4) == "NAME") { + moduleName = line.substr(6); + } else { + std::cout << "Unexpected section type" << std::endl; + return -1; + } + continue; + } + + if (readMode == ReadMode::TEXT) { + funcExports.push_back(line); + } else if (readMode == ReadMode::DATA) { + dataExports.push_back(line); + } else { + std::cout << "Unexpected section data" << std::endl; + return -1; + } + } + } + + { + std::ofstream out; + out.open(argv[2]); + + if (!out.is_open()) { + std::cout << "Could not open file " << argv[2] << " for writing" << std::endl; + return -1; + } + + if (funcExports.size() > 0) { + writeExports(out, moduleName, false, funcExports); + } + + if (dataExports.size() > 0) { + writeExports(out, moduleName, true, dataExports); + } + } + + return 0; +} diff --git a/tools/udplogserver/CMakeLists.txt b/tools/udplogserver/CMakeLists.txt deleted file mode 100644 index 5ae37d8..0000000 --- a/tools/udplogserver/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -project(udplogserver) - -file(GLOB_RECURSE SOURCE_FILES *.cpp) -file(GLOB_RECURSE HEADER_FILES *.h) - -add_executable(udplogserver ${SOURCE_FILES} ${HEADER_FILES}) -set_target_properties(udplogserver PROPERTIES FOLDER tools) - -if (MSVC) - target_link_libraries(udplogserver PRIVATE ws2_32) -endif() - -install(TARGETS udplogserver RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/tools/udplogserver/main.cpp b/tools/udplogserver/main.cpp deleted file mode 100644 index fdec456..0000000 --- a/tools/udplogserver/main.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#include -#include -#endif - -#include -#include -#include - -#define SERVER_PORT 4405 - -int main(int argc, char **argv) -{ - struct sockaddr_in addr; - unsigned short port = SERVER_PORT; - - if (argc == 2) { - port = atoi(argv[1]); - } - -#ifdef _WIN32 - WSADATA wsaData; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR) { - return -1; - } -#endif - - // Create socket - auto fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#ifdef _WIN32 - if (fd == INVALID_SOCKET) { - WSACleanup(); -#else - if (fd < 0) { -#endif - return -1; - } - - // Set non blocking -#ifdef _WIN32 - u_long mode = 1; - ioctlsocket(fd, FIONBIO, &mode); -#else - int flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); -#endif - - // Bind socket - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { -#ifdef _WIN32 - closesocket(fd); - WSACleanup(); -#else - close(fd); -#endif - return -1; - } - - // Receive data - char buffer[2048]; - bool running = true; - - while (running) { - fd_set fdsRead; - FD_ZERO(&fdsRead); - FD_SET(fd, &fdsRead); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 10000; - - if (select(fd + 1, &fdsRead, NULL, NULL, &tv) == 1) { - struct sockaddr_in from; -#ifdef _WIN32 - int fromLen = sizeof(from); -#else - socklen_t fromLen = sizeof(from); -#endif - int recvd = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr *) &from, &fromLen); - - if (recvd > 0) { - buffer[recvd] = 0; - std::cout << buffer; - std::cout.flush(); - } - } - } - -#ifdef _WIN32 - closesocket(fd); - WSACleanup(); -#else - close(fd); -#endif - return 0; -}