Skip to content

Commit

Permalink
[3DS] Initial 3DS port
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHuu committed Aug 11, 2024
1 parent 361eca4 commit 55c053e
Show file tree
Hide file tree
Showing 12 changed files with 466 additions and 1 deletion.
55 changes: 55 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,58 @@ if(DETHRACE_INSTALL)

include(CPack)
endif()

if (NINTENDO_3DS)
set(APP_TITLE "${PROJECT_NAME}")
set(APP_DESCRIPTION "${PROJECT_NAME} port for 3DS")
set(APP_AUTHOR "dethrace-labs")
set(APP_UNIQUE_ID "0xF02F6")
set(APP_ICON "${PROJECT_SOURCE_DIR}/packaging/ctr/icon.png")
set(APP_BANNER "${PROJECT_SOURCE_DIR}/packaging/ctr/banner.png")
set(APP_AUDIO "${PROJECT_SOURCE_DIR}/packaging/ctr/audio_silent.wav")
set(APP_ROMFS_DIR "${PROJECT_SOURCE_DIR}/packaging/ctr/romfs")
set(APP_RSF "${PROJECT_SOURCE_DIR}/packaging/ctr/template.rsf")

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.3dsx
COMMAND 3dsxtool ${PROJECT_NAME}.elf ${PROJECT_NAME}${ROM}.3dsx
--romfs=${APP_ROMFS_DIR}
--smdh=${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.smdh
DEPENDS ${PROJECT_NAME} ${PROJECT_NAME}.smdh
)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.cia
COMMAND makerom -f cia
-target t
-exefslogo
-o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.cia
-elf ${PROJECT_NAME}.elf
-rsf ${APP_RSF}
-DAPP_TITLE=${APP_TITLE}
-DAPP_UNIQUE_ID=${APP_UNIQUE_ID}
-DAPP_ROMFS_DIR=${APP_ROMFS_DIR}
-banner ${PROJECT_NAME}.bnr
-icon ${PROJECT_NAME}.smdh
DEPENDS ${PROJECT_NAME} ${APP_RSF} ${PROJECT_NAME}.smdh ${PROJECT_NAME}.bnr
)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.smdh
COMMAND bannertool makesmdh -o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.smdh
-s ${APP_TITLE}
-l ${APP_DESCRIPTION}
-p ${APP_AUTHOR}
-i ${APP_ICON}

OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.bnr
COMMAND bannertool makebanner -o ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.bnr
-i ${APP_BANNER}
-a ${APP_AUDIO}
)

add_custom_target( N3DS ALL
DEPENDS ${PROJECT_NAME}.3dsx
${PROJECT_NAME}.cia
)
endif ()
2 changes: 2 additions & 0 deletions lib/miniaudio/include/miniaudio/miniaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -16116,9 +16116,11 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority
#endif
} else if (priority == ma_thread_priority_realtime) {
#ifdef SCHED_FIFO
#ifndef __3DS__
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0) {
scheduler = SCHED_FIFO;
}
#endif
#endif
#ifdef MA_LINUX
} else {
Expand Down
Binary file added packaging/ctr/audio_silent.wav
Binary file not shown.
Binary file added packaging/ctr/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packaging/ctr/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packaging/ctr/romfs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
219 changes: 219 additions & 0 deletions packaging/ctr/template.rsf
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
BasicInfo:
Title : $(APP_TITLE)
ProductCode : $(APP_PRODUCT_CODE)
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem

RomFs:
# Specifies the root path of the read only file system to include in the ROM.
RootPath : $(APP_ROMFS)

TitleInfo:
Category : Application
UniqueId : $(APP_UNIQUE_ID)

Option:
UseOnSD : true # true if App is to be installed to SD
FreeProductCode : true # Removes limitations on ProductCode
MediaFootPadding : false # If true CCI files are created with padding
EnableCrypt : false # Enables encryption for NCCH and CIA
EnableCompress : false # Compresses where applicable (currently only exefs:/.code)

AccessControlInfo:
CoreVersion : 2

# Exheader Format Version
DescVersion : 2

# Minimum Required Kernel Version (below is for 4.5.0)
ReleaseKernelMajor : "02"
ReleaseKernelMinor : "33"

# ExtData
UseExtSaveData : false # enables ExtData
#ExtSaveDataId : 0x300 # only set this when the ID is different to the UniqueId

# FS:USER Archive Access Permissions
# Uncomment as required
FileSystemAccess:
#- CategorySystemApplication
#- CategoryHardwareCheck
- CategoryFileSystemTool
#- Debug
#- TwlCardBackup
#- TwlNandData
#- Boss
- DirectSdmc
#- Core
#- CtrNandRo
#- CtrNandRw
#- CtrNandRoWrite
#- CategorySystemSettings
#- CardBoard
#- ExportImportIvs
#- DirectSdmcWrite
#- SwitchCleanup
#- SaveDataMove
#- Shop
#- Shell
#- CategoryHomeMenu

# Process Settings
MemoryType : Application # Application/System/Base
SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB
IdealProcessor : 0
AffinityMask : 1
Priority : 16
MaxCpu : 0x9E # Default
HandleTableSize : 0x200
DisableDebug : false
EnableForceDebug : false
CanWriteSharedPage : true
CanUsePrivilegedPriority : false
CanUseNonAlphabetAndNumber : true
PermitMainFunctionArgument : true
CanShareDeviceMemory : true
RunnableOnSleep : false
SpecialMemoryArrange : true

# New3DS Exclusive Process Settings
SystemModeExt : $(APP_SYSTEM_MODE_EXT) # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
CpuSpeed : 804MHz # 256MHz(Default)/804MHz
EnableL2Cache : true # false(default)/true
CanAccessCore2 : true

# Virtual Address Mappings
IORegisterMapping:
- 1ff00000-1ff7ffff # DSP memory
MemoryMapping:
- 1f000000-1f5fffff:r # VRAM

# Accessible SVCs, <Name>:<ID>
SystemCallAccess:
ArbitrateAddress: 34
Backdoor: 123
Break: 60
CancelTimer: 28
ClearEvent: 25
ClearTimer: 29
CloseHandle: 35
ConnectToPort: 45
ControlMemory: 1
ControlProcessMemory: 112
CreateAddressArbiter: 33
CreateEvent: 23
CreateMemoryBlock: 30
CreateMutex: 19
CreateSemaphore: 21
CreateThread: 8
CreateTimer: 26
DuplicateHandle: 39
ExitProcess: 3
ExitThread: 9
GetCurrentProcessorNumber: 17
GetHandleInfo: 41
GetProcessId: 53
GetProcessIdOfThread: 54
GetProcessIdealProcessor: 6
GetProcessInfo: 43
GetResourceLimit: 56
GetResourceLimitCurrentValues: 58
GetResourceLimitLimitValues: 57
GetSystemInfo: 42
GetSystemTick: 40
GetThreadContext: 59
GetThreadId: 55
GetThreadIdealProcessor: 15
GetThreadInfo: 44
GetThreadPriority: 11
MapMemoryBlock: 31
OutputDebugString: 61
QueryMemory: 2
ReleaseMutex: 20
ReleaseSemaphore: 22
SendSyncRequest1: 46
SendSyncRequest2: 47
SendSyncRequest3: 48
SendSyncRequest4: 49
SendSyncRequest: 50
SetThreadPriority: 12
SetTimer: 27
SignalEvent: 24
SleepThread: 10
UnmapMemoryBlock: 32
WaitSynchronization1: 36
WaitSynchronizationN: 37

# Service List
# Maximum 34 services (32 if firmware is prior to 9.6.0)
ServiceAccessControl:
- APT:U
- ac:u
- am:net
- boss:U
- cam:u
- cecd:u
- cfg:nor
- cfg:u
- csnd:SND
- dsp::DSP
- frd:u
- fs:USER
- gsp::Gpu
- hid:USER
- http:C
- ir:rst
- ir:u
- ir:USER
- mic:u
- ndm:u
- news:u
- nwm::UDS
- ptm:u
- pxi:dev
- soc:U
- ssl:C
- y2r:u


SystemControlInfo:
SaveDataSize: 0KB # Change if the app uses savedata
RemasterVersion: 2
StackSize: 0x40000

# Modules that run services listed above should be included below
# Maximum 48 dependencies
# <module name>:<module titleid>
Dependency:
ac: 0x0004013000002402
act: 0x0004013000003802
am: 0x0004013000001502
boss: 0x0004013000003402
camera: 0x0004013000001602
cecd: 0x0004013000002602
cfg: 0x0004013000001702
codec: 0x0004013000001802
csnd: 0x0004013000002702
dlp: 0x0004013000002802
dsp: 0x0004013000001a02
friends: 0x0004013000003202
gpio: 0x0004013000001b02
gsp: 0x0004013000001c02
hid: 0x0004013000001d02
http: 0x0004013000002902
i2c: 0x0004013000001e02
ir: 0x0004013000003302
mcu: 0x0004013000001f02
mic: 0x0004013000002002
ndm: 0x0004013000002b02
news: 0x0004013000003502
nfc: 0x0004013000004002
nim: 0x0004013000002c02
nwm: 0x0004013000002d02
pdn: 0x0004013000002102
ps: 0x0004013000003102
ptm: 0x0004013000002202
qtm: 0x0004013020004202
ro: 0x0004013000003702
socket: 0x0004013000002e02
spi: 0x0004013000002302
ssl: 0x0004013000002f02
4 changes: 4 additions & 0 deletions src/harness/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ elseif(APPLE)
target_sources(harness PRIVATE
os/macos.c
)
elseif(NINTENDO_3DS)
target_sources(harness PRIVATE
os/ctr.c
)
else()
target_sources(harness PRIVATE
os/linux.c
Expand Down
5 changes: 5 additions & 0 deletions src/harness/audio/miniaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#include "harness/os.h"
#include "harness/trace.h"

#ifdef __3DS__
#define MA_NO_PTHREAD_IN_HEADER
#define MA_NO_RUNTIME_LINKING
#endif

// Must come before miniaudio.h
#define STB_VORBIS_HEADER_ONLY
#include "stb/stb_vorbis.c"
Expand Down
14 changes: 14 additions & 0 deletions src/harness/harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <string.h>
#include <sys/stat.h>

#ifdef __3DS__
#include <3ds.h>
#endif

br_pixelmap* palette;
uint32_t* screen_buffer;

Expand Down Expand Up @@ -166,15 +170,25 @@ void Harness_Init(int* argc, char* argv[]) {

Harness_ProcessCommandLine(argc, argv);

#ifdef __3DS__
osSetSpeedupEnable(true);
gfxInitDefault();
consoleInit(GFX_BOTTOM, NULL);
chdir("sdmc:/CARMA/");
char* root_dir = NULL;
#else
if (harness_game_config.install_signalhandler) {
OS_InstallSignalHandler(argv[0]);
}

char* root_dir = getenv("DETHRACE_ROOT_DIR");
#endif
if (root_dir != NULL) {
LOG_INFO("DETHRACE_ROOT_DIR is set to '%s'", root_dir);
} else {
#ifndef __3DS__
root_dir = OS_GetWorkingDirectory(argv[0]);
#endif
}
// if root_dir is null or empty, no need to chdir
if (root_dir != NULL && root_dir[0] != '\0') {
Expand Down
27 changes: 27 additions & 0 deletions src/harness/os/ctr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#define _GNU_SOURCE
#include <limits.h>
#include <stdio.h>

void resolve_full_path(char* path, const char* argv0) {
return;
}

FILE* OS_fopen(const char* pathname, const char* mode) {
FILE* f = fopen(pathname, mode);
if (f != NULL) {
return f;
}
return NULL;
}

size_t OS_ConsoleReadPassword(char* pBuffer, size_t pBufferLen) {
return 0;
}

char* OS_Basename(const char* path) {
return "";
}

char* OS_GetWorkingDirectory(char* argv0) {
return "";
}
Loading

0 comments on commit 55c053e

Please sign in to comment.