This commit is contained in:
Maschell 2022-02-08 14:48:41 +01:00
parent 4993b321ce
commit 5a3bae8616
38 changed files with 603 additions and 1498 deletions

67
.clang-format Normal file
View File

@ -0,0 +1,67 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
CMakeLists.txt
*.wps
*.elf
.idea/
build/
cmake-build-debug/
__pycache__/

6
Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM wiiuenv/devkitppc:20211229
COPY --from=wiiuenv/wiiupluginsystem:20220123 /artifacts $DEVKITPRO
COPY --from=wiiuenv/libiosuhax:20220129 /artifacts $DEVKITPRO
WORKDIR project

142
Makefile Normal file
View File

@ -0,0 +1,142 @@
#-------------------------------------------------------------------------------
.SUFFIXES:
#-------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/wups/share/wups_rules
WUT_ROOT := $(DEVKITPRO)/wut
WUMS_ROOT := $(DEVKITPRO)/wums
#-------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#-------------------------------------------------------------------------------
TARGET := debugger
BUILD := build
SOURCES := src src/utils
DATA := data
INCLUDES := src
#-------------------------------------------------------------------------------
# options for code generation
#-------------------------------------------------------------------------------
CFLAGS := -Wall -O2 -ffunction-sections \
$(MACHDEP)
CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__
CXXFLAGS := $(CFLAGS)
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld -T$(WUMS_ROOT)/share/libkernel.ld $(WUPSSPECS)
ifeq ($(DEBUG),1)
CXXFLAGS += -DDEBUG -g
CFLAGS += -DDEBUG -g
endif
LIBS := -lwups -lwut -lkernel -lmappedmemory
#-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level
# containing include and lib
#-------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(WUPS_ROOT) $(WUMS_ROOT) $(WUT_ROOT) $(WUT_ROOT)/usr
#-------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#-------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#-------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#-------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#-------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#-------------------------------------------------------------------------------
export LD := $(CC)
#-------------------------------------------------------------------------------
else
#-------------------------------------------------------------------------------
export LD := $(CXX)
#-------------------------------------------------------------------------------
endif
#-------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean all
#-------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#-------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).wps $(TARGET).elf
#-------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#-------------------------------------------------------------------------------
# main targets
#-------------------------------------------------------------------------------
all : $(OUTPUT).wps
$(OUTPUT).wps : $(OUTPUT).elf
$(OUTPUT).elf : $(OFILES)
$(OFILES_SRC) : $(HFILES_BIN)
#-------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#-------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#-------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#-------------------------------------------------------------------------------
endif
#-------------------------------------------------------------------------------

View File

@ -1,16 +0,0 @@
import os
import subprocess
PPC_GCC = r"C:\devkitPro\devkitPPC\bin\powerpc-eabi-g++"
files = []
for dirname, subdirs, subfiles in os.walk("src"):
for filename in subfiles:
if filename.endswith(".cpp") or filename.endswith(".c") or \
filename.endswith(".S") or filename.endswith(".s"):
filepath = os.path.join(dirname, filename)
files.append(filepath)
args = "-O2 -Isrc -fno-exceptions -nostartfiles -T src/link.ld -Wl,-n -Wl,--gc-sections"
subprocess.call("%s %s %s" %(PPC_GCC, args, " ".join(files)))

View File

@ -1,248 +0,0 @@
#include "cafe/coreinit.h"
#include "hbl.h"
#include <cstddef>
#include <cstdint>
int (*OSDynLoad_Acquire)(const char *name, uint32_t *handle);
int (*OSDynLoad_FindExport)(uint32_t handle, bool isData, const char *name, void *ptr);
int (*OSDynLoad_GetModuleName)(uint32_t handle, char *name, int *size);
OSMutex *OSDynLoad_gLoaderLock;
bool (*OSIsDebuggerInitialized)();
void (*exit)(int result);
void (*_Exit)(int result);
void (*OSFatal)(const char *msg);
uint32_t (*OSGetSymbolName)(uint32_t addr, char *buffer, size_t bufsize);
void (*DisassemblePPCRange)(uint32_t start, uint32_t end, DisassemblyPrintFn printFunc, DisassemblyFindSymbolFn symFunc, DisassemblyFlags flags);
void (*DisassemblePPCOpcode)(uint32_t addr, void *buffer, size_t bufsize, DisassemblyFindSymbolFn symFunc, DisassemblyFlags flags);
int (*OSSetExceptionCallback)(OSExceptionType type, OSExceptionCallback callback);
int (*OSSetExceptionCallbackEx)(OSExceptionMode mode, OSExceptionType type, OSExceptionCallback callback);
void (*OSLoadContext)(OSContext *context);
int (*OSDisableInterrupts)();
void (*OSRestoreInterrupts)(int state);
void (*__OSLockScheduler)(void *);
void (*__OSUnlockScheduler)(void *);
void (*OSInitMutex)(OSMutex *mutex);
void (*OSLockMutex)(OSMutex *mutex);
void (*OSUnlockMutex)(OSMutex *mutex);
void (*OSInitMessageQueue)(OSMessageQueue *queue, OSMessage *messages, int count);
bool (*OSSendMessage)(OSMessageQueue *queue, OSMessage *message, OSMessageFlags flags);
bool (*OSReceiveMessage)(OSMessageQueue *queue, OSMessage *message, OSMessageFlags flags);
void (*OSCreateAlarm)(OSAlarm *alarm);
bool (*OSSetAlarm)(OSAlarm *alarm, uint64_t timeout, OSAlarmCallback callback);
void (*OSCancelAlarm)(OSAlarm *alarm);
bool (*OSWaitAlarm)(OSAlarm *alarm);
OSThread *(*OSGetCurrentThread)();
OSThread *(*OSGetDefaultThread)(int core);
bool (*OSCreateThread)(OSThread *thread, OSThreadFunc func, int argc, void *argv, void *stack, uint32_t stackSize, int priority, int attr);
int (*OSResumeThread)(OSThread *thread);
bool (*OSJoinThread)(OSThread *thread, int *result);
void (*OSExitThread)(int result);
const char *(*OSGetThreadName)(OSThread *thread);
void (*OSSetThreadName)(OSThread *thread, const char *name);
uint32_t (*OSGetThreadAffinity)(OSThread *thread);
int (*OSGetThreadPriority)(OSThread *thread);
OSSystemInfo *(*OSGetSystemInfo)();
void (*OSSleepTicks)(uint64_t ticks);
uint64_t (*OSGetTitleID)();
int (*OSGetMemBound)(OSMemoryType type, uint32_t *startPtr, uint32_t *sizePtr);
uint32_t (*OSEffectiveToPhysical)(uint32_t addr);
void (*OSScreenInit)();
uint32_t (*OSScreenGetBufferSizeEx)(int screen);
void (*OSScreenSetBufferEx)(int screen, void *buffer);
void (*OSScreenEnableEx)(int screen, bool enabled);
void (*OSScreenClearBufferEx)(int screen, uint32_t color);
void (*OSScreenFlipBuffersEx)(int screen);
void (*OSScreenPutPixelEx)(int screen, int x, int y, uint32_t color);
void (*OSScreenPutFontEx)(int screen, int x, int y, const char *text);
void (*DCFlushRange)(const void *buffer, uint32_t length);
void (*DCInvalidateRange)(const void *buffer, uint32_t length);
void (*ICInvalidateRange)(const void *buffer, uint32_t length);
int (*IOS_Open)(const char *path, int mode);
int (*IOS_Ioctl)(int fd, uint32_t request, const void *inptr, uint32_t inlen, void *outptr, uint32_t outlen);
int (*IOS_Close)(int fd);
int (*FSInit)();
int (*FSAddClient)(FSClient *client, uint32_t flags);
int (*FSInitCmdBlock)(FSCmdBlock *block);
int (*FSGetMountSource)(FSClient *client, FSCmdBlock *block, FSMountSourceType type, FSMountSource *source, uint32_t flags);
int (*FSMount)(FSClient *client, FSCmdBlock *block, FSMountSource *source, char *path, uint32_t bytes, uint32_t flags);
int (*FSMakeDir)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
int (*FSChangeDir)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
int (*FSGetCwd)(FSClient *client, FSCmdBlock *block, char *path, int length, uint32_t flags);
int (*FSOpenDir)(FSClient *client, FSCmdBlock *block, const char *path, int *handle, uint32_t flags);
int (*FSReadDir)(FSClient *client, FSCmdBlock *block, int handle, FSDirectoryEntry *entry, uint32_t flags);
int (*FSCloseDir)(FSClient *client, FSCmdBlock *block, int handle, uint32_t flags);
int (*FSOpenFile)(FSClient *client, FSCmdBlock *block, const char *path, const char *mode, int *handle, uint32_t flags);
int (*FSGetStatFile)(FSClient *client, FSCmdBlock *block, int handle, FSStat *stat, uint32_t flags);
int (*FSReadFile)(FSClient *client, FSCmdBlock *block, void *buffer, int size, int count, int handle, int flag, uint32_t flags);
int (*FSWriteFile)(FSClient *client, FSCmdBlock *block, const void *buffer, int size, int count, int handle, int flag, uint32_t flags);
int (*FSCloseFile)(FSClient *client, FSCmdBlock *block, int handle, uint32_t flags);
int (*FSGetStat)(FSClient *client, FSCmdBlock *block, const char *path, FSStat *stat, uint32_t flags);
int (*FSRename)(FSClient *client, FSCmdBlock *block, const char *oldPath, const char *newPath, uint32_t flags);
int (*FSRemove)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
int (*FSDelClient)(FSClient *client, uint32_t flags);
void (*FSShutdown)();
int (*MCP_Open)();
int (*MCP_GetDeviceId)(int handle, uint32_t *deviceId);
int (*MCP_TitleList)(int handle, uint32_t *count, MCPTitleListType *list, uint32_t size);
int (*MCP_TitleListByAppType)(int handle, uint32_t appType, uint32_t *count, MCPTitleListType *list, uint32_t size);
int (*MCP_TitleListByDevice)(int handle, const char *device, uint32_t *count, MCPTitleListType *list, uint32_t size);
void (*MCP_Close)(int handle);
void (*__KernelGetInfo)(KernelInfoType type, void *buffer, uint32_t size, uint32_t unk);
int (*snprintf)(char *str, size_t size, const char *format, ...);
void *(*MEMGetBaseHeapHandle)(int type);
uint32_t (*MEMGetAllocatableSizeForExpHeapEx)(void *handle, int alignment);
void *(**pMEMAllocFromDefaultHeap)(uint32_t size);
void *(**pMEMAllocFromDefaultHeapEx)(uint32_t size, int alignment);
void (**pMEMFreeToDefaultHeap)(void *ptr);
OSDynLoad_RPLInfo **pMainRPL;
OSDynLoad_RPLInfo **pFirstRPL;
OSThread **pThreadList;
void coreinitInitialize() {
*(uint32_t *) &OSDynLoad_Acquire = OS_SPECIFICS->OSDynLoad_Acquire;
*(uint32_t *) &OSDynLoad_FindExport = OS_SPECIFICS->OSDynLoad_FindExport;
uint32_t handle;
OSDynLoad_Acquire("coreinit.rpl", &handle);
OSDynLoad_FindExport(handle, false, "OSDynLoad_GetModuleName", &OSDynLoad_GetModuleName);
OSDynLoad_FindExport(handle, true, "OSDynLoad_gLoaderLock", &OSDynLoad_gLoaderLock);
OSDynLoad_FindExport(handle, false, "OSIsDebuggerInitialized", &OSIsDebuggerInitialized);
OSDynLoad_FindExport(handle, false, "exit", &exit);
OSDynLoad_FindExport(handle, false, "_Exit", &_Exit);
OSDynLoad_FindExport(handle, false, "OSFatal", &OSFatal);
OSDynLoad_FindExport(handle, false, "OSGetSymbolName", &OSGetSymbolName);
OSDynLoad_FindExport(handle, false, "DisassemblePPCRange", &DisassemblePPCRange);
OSDynLoad_FindExport(handle, false, "DisassemblePPCOpcode", &DisassemblePPCOpcode);
OSDynLoad_FindExport(handle, false, "OSSetExceptionCallback", &OSSetExceptionCallback);
OSDynLoad_FindExport(handle, false, "OSSetExceptionCallbackEx", &OSSetExceptionCallbackEx);
OSDynLoad_FindExport(handle, false, "OSLoadContext", &OSLoadContext);
OSDynLoad_FindExport(handle, false, "OSDisableInterrupts", &OSDisableInterrupts);
OSDynLoad_FindExport(handle, false, "OSRestoreInterrupts", &OSRestoreInterrupts);
OSDynLoad_FindExport(handle, false, "__OSLockScheduler", &__OSLockScheduler);
OSDynLoad_FindExport(handle, false, "__OSUnlockScheduler", &__OSUnlockScheduler);
OSDynLoad_FindExport(handle, false, "OSInitMutex", &OSInitMutex);
OSDynLoad_FindExport(handle, false, "OSLockMutex", &OSLockMutex);
OSDynLoad_FindExport(handle, false, "OSUnlockMutex", &OSUnlockMutex);
OSDynLoad_FindExport(handle, false, "OSInitMessageQueue", &OSInitMessageQueue);
OSDynLoad_FindExport(handle, false, "OSSendMessage", &OSSendMessage);
OSDynLoad_FindExport(handle, false, "OSReceiveMessage", &OSReceiveMessage);
OSDynLoad_FindExport(handle, false, "OSCreateAlarm", &OSCreateAlarm);
OSDynLoad_FindExport(handle, false, "OSSetAlarm", &OSSetAlarm);
OSDynLoad_FindExport(handle, false, "OSCancelAlarm", &OSCancelAlarm);
OSDynLoad_FindExport(handle, false, "OSWaitAlarm", &OSWaitAlarm);
OSDynLoad_FindExport(handle, false, "OSGetCurrentThread", &OSGetCurrentThread);
OSDynLoad_FindExport(handle, false, "OSGetDefaultThread", &OSGetDefaultThread);
OSDynLoad_FindExport(handle, false, "OSCreateThread", &OSCreateThread);
OSDynLoad_FindExport(handle, false, "OSResumeThread", &OSResumeThread);
OSDynLoad_FindExport(handle, false, "OSJoinThread", &OSJoinThread);
OSDynLoad_FindExport(handle, false, "OSExitThread", &OSExitThread);
OSDynLoad_FindExport(handle, false, "OSGetThreadName", &OSGetThreadName);
OSDynLoad_FindExport(handle, false, "OSSetThreadName", &OSSetThreadName);
OSDynLoad_FindExport(handle, false, "OSGetThreadAffinity", &OSGetThreadAffinity);
OSDynLoad_FindExport(handle, false, "OSGetThreadPriority", &OSGetThreadPriority);
OSDynLoad_FindExport(handle, false, "OSGetSystemInfo", &OSGetSystemInfo);
OSDynLoad_FindExport(handle, false, "OSSleepTicks", &OSSleepTicks);
OSDynLoad_FindExport(handle, false, "OSGetTitleID", &OSGetTitleID);
OSDynLoad_FindExport(handle, false, "OSGetMemBound", &OSGetMemBound);
OSDynLoad_FindExport(handle, false, "OSEffectiveToPhysical", &OSEffectiveToPhysical);
OSDynLoad_FindExport(handle, false, "OSScreenInit", &OSScreenInit);
OSDynLoad_FindExport(handle, false, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
OSDynLoad_FindExport(handle, false, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
OSDynLoad_FindExport(handle, false, "OSScreenEnableEx", &OSScreenEnableEx);
OSDynLoad_FindExport(handle, false, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(handle, false, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
OSDynLoad_FindExport(handle, false, "OSScreenPutPixelEx", &OSScreenPutPixelEx);
OSDynLoad_FindExport(handle, false, "OSScreenPutFontEx", &OSScreenPutFontEx);
OSDynLoad_FindExport(handle, false, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(handle, false, "DCInvalidateRange", &DCInvalidateRange);
OSDynLoad_FindExport(handle, false, "ICInvalidateRange", &ICInvalidateRange);
OSDynLoad_FindExport(handle, false, "IOS_Open", &IOS_Open);
OSDynLoad_FindExport(handle, false, "IOS_Ioctl", &IOS_Ioctl);
OSDynLoad_FindExport(handle, false, "IOS_Close", &IOS_Close);
OSDynLoad_FindExport(handle, false, "FSInit", &FSInit);
OSDynLoad_FindExport(handle, false, "FSAddClient", &FSAddClient);
OSDynLoad_FindExport(handle, false, "FSInitCmdBlock", &FSInitCmdBlock);
OSDynLoad_FindExport(handle, false, "FSGetMountSource", &FSGetMountSource);
OSDynLoad_FindExport(handle, false, "FSMount", &FSMount);
OSDynLoad_FindExport(handle, false, "FSMakeDir", &FSMakeDir);
OSDynLoad_FindExport(handle, false, "FSChangeDir", &FSChangeDir);
OSDynLoad_FindExport(handle, false, "FSGetCwd", &FSGetCwd);
OSDynLoad_FindExport(handle, false, "FSOpenDir", &FSOpenDir);
OSDynLoad_FindExport(handle, false, "FSReadDir", &FSReadDir);
OSDynLoad_FindExport(handle, false, "FSCloseDir", &FSCloseDir);
OSDynLoad_FindExport(handle, false, "FSOpenFile", &FSOpenFile);
OSDynLoad_FindExport(handle, false, "FSGetStatFile", &FSGetStatFile);
OSDynLoad_FindExport(handle, false, "FSReadFile", &FSReadFile);
OSDynLoad_FindExport(handle, false, "FSWriteFile", &FSWriteFile);
OSDynLoad_FindExport(handle, false, "FSCloseFile", &FSCloseFile);
OSDynLoad_FindExport(handle, false, "FSGetStat", &FSGetStat);
OSDynLoad_FindExport(handle, false, "FSRename", &FSRename);
OSDynLoad_FindExport(handle, false, "FSRemove", &FSRemove);
OSDynLoad_FindExport(handle, false, "FSDelClient", &FSDelClient);
OSDynLoad_FindExport(handle, false, "FSShutdown", &FSShutdown);
OSDynLoad_FindExport(handle, false, "MCP_Open", &MCP_Open);
OSDynLoad_FindExport(handle, false, "MCP_GetDeviceId", &MCP_GetDeviceId);
OSDynLoad_FindExport(handle, false, "MCP_TitleList", &MCP_TitleList);
OSDynLoad_FindExport(handle, false, "MCP_TitleListByAppType", &MCP_TitleListByAppType);
OSDynLoad_FindExport(handle, false, "MCP_TitleListByDevice", &MCP_TitleListByDevice);
OSDynLoad_FindExport(handle, false, "MCP_Close", &MCP_Close);
OSDynLoad_FindExport(handle, false, "__KernelGetInfo", &__KernelGetInfo);
OSDynLoad_FindExport(handle, false, "__os_snprintf", &snprintf);
OSDynLoad_FindExport(handle, false, "MEMGetBaseHeapHandle", &MEMGetBaseHeapHandle);
OSDynLoad_FindExport(handle, false, "MEMGetAllocatableSizeForExpHeapEx", &MEMGetAllocatableSizeForExpHeapEx);
OSDynLoad_FindExport(handle, true, "MEMAllocFromDefaultHeap", &pMEMAllocFromDefaultHeap);
OSDynLoad_FindExport(handle, true, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx);
OSDynLoad_FindExport(handle, true, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap);
pMainRPL = (OSDynLoad_RPLInfo **) 0x10081014;
pFirstRPL = (OSDynLoad_RPLInfo **) 0x10081018;
pThreadList = (OSThread **) 0x100567F8;
}

View File

@ -1,512 +0,0 @@
#pragma once
#include <cstddef>
#include <cstdint>
// Timers
#define OSTimerClockSpeed ((OSGetSystemInfo()->busClockSpeed) / 4)
#define OSSecondsToTicks(val) ((uint64_t) (val) * (uint64_t) OSTimerClockSpeed)
#define OSMillisecondsToTicks(val) (((uint64_t) (val) * (uint64_t) OSTimerClockSpeed) / 1000ull)
#define OSTicksToSeconds(val) ((uint64_t) (val) / (uint64_t) OSTimerClockSpeed)
#define OSTicksToMilliseconds(val) (((uint64_t) (val) *1000ull) / (uint64_t) OSTimerClockSpeed)
// Memory
enum OSMemoryType {
MEM1 = 1,
MEM2 = 2
};
// System
enum KernelInfoType {
TITLE_INFO = 0,
SYSTEM_INFO = 1,
PLATFORM_INFO = 2,
KERNEL_STATISTICS = 4,
PERFORMANCE_NUMBERS = 5,
PROCESS_INFO = 8,
CRASH_INFO = 11,
APP_CRASH_CONTROL = 12,
COS_REPORT_MASKS = 13,
CRASH_RECOVERY = 14,
CRASH_DETAIL_LEVEL = 15,
CRASH_DUMP_TYPE = 16,
SHUTDOWN_REASON = 17,
WRITE_GATHER_REGS = 18,
PROC_DATA_BOUNDS = 19
};
struct OSSystemInfo {
uint32_t busClockSpeed;
uint32_t coreClockSpeed;
int64_t baseTime;
char _10[0x10];
};
struct OSTitleInfo {
char _0[0xC];
uint32_t ramStart;
uint32_t ramEnd;
char _14[0x20];
uint32_t systemHeapSize;
char _38[0x40];
uint32_t textStart;
uint32_t _7C;
uint32_t textSize;
uint32_t dataStart;
uint32_t _88;
uint32_t dataSize;
uint32_t loadStart;
uint32_t _94;
uint32_t loadSize;
char _9C[0xC];
};
struct OSTitleInfoEx {
OSTitleInfo info;
uint64_t osVersionId;
};
// OSDynLoad
struct OSDynLoad_NotifyData {
const char *path;
uint32_t textAddr;
uint32_t textOffset;
uint32_t textSize;
uint32_t dataAddr;
uint32_t dataOffset;
uint32_t dataSize;
uint32_t readAddr;
uint32_t readOffset;
uint32_t readSize;
};
struct OSDynLoad_RPLInfo {
uint32_t handle;
uint32_t _4;
const char *name;
char _C[0x1C];
OSDynLoad_NotifyData *notifyData;
void *entryPoint;
char _30[0x24];
OSDynLoad_RPLInfo *next;
char _58[0x3C];
};
// Thread / mutex / context
struct OSThread;
struct OSMutex;
struct OSAlarm;
struct OSContext {
uint64_t tag;
uint32_t gpr[32];
uint32_t cr;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t srr0;
uint32_t srr1;
uint32_t dsisr;
uint32_t dar;
char _A8[0xC];
uint32_t fpscr;
double fpr[32];
uint16_t spinLockCount;
uint16_t state;
uint32_t gqr[8];
uint32_t _1DC;
double psf[32];
uint64_t coretime[3];
uint64_t starttime;
uint32_t error;
uint32_t _304;
uint32_t pmc1;
uint32_t pmc2;
uint32_t pmc3;
uint32_t pmc4;
uint32_t mmcr0;
uint32_t mmcr1;
};
struct OSThreadQueue {
OSThread *head;
OSThread *tail;
void *parent;
uint32_t _C;
};
struct OSThreadLink {
OSThread *next;
OSThread *prev;
};
struct OSMutexLink {
OSMutex *next;
OSMutex *prev;
};
struct OSMutexQueue {
OSMutex *head;
OSMutex *tail;
void *parent;
uint32_t _C;
};
struct OSMutex {
uint32_t tag;
const char *name;
uint32_t _8;
OSThreadQueue queue;
OSThread *thread;
int count;
OSMutexLink link;
};
typedef int (*OSThreadFunc)(int argc, void *argv);
struct OSThread {
OSContext context;
uint32_t tag;
uint8_t state;
uint8_t attr;
uint16_t id;
uint32_t suspendCounter;
int priority;
int basePriority;
int exitValue;
char _338[0x24];
OSThreadQueue *queue;
OSThreadLink link;
OSThreadQueue joinQueue;
OSMutex *mutex;
OSMutexQueue mutexQueue;
OSThreadLink activeLink;
void *stackBase;
void *stackEnd;
OSThreadFunc entryPoint;
char _3A0[0x57C - 0x3A0];
void *specific[0x10];
int type;
const char *name;
char _5C4[0x6A0 - 0x5C4];
};
// Messages
enum OSMessageFlags {
OS_MESSAGE_FLAGS_NONE = 0,
OS_MESSAGE_FLAGS_BLOCKING = 1
};
struct OSMessage {
uint32_t message;
uint32_t args[3];
};
struct OSMessageQueue {
uint32_t tag;
const char *name;
uint32_t _8;
OSThreadQueue sendQueue;
OSThreadQueue recvQueue;
OSMessage *messages;
uint32_t size;
uint32_t first;
uint32_t used;
};
// Alarms
struct OSAlarmQueue {
uint32_t tag;
const char *name;
uint32_t _8;
OSThreadQueue threadQueue;
OSAlarm *head;
OSAlarm *tail;
};
struct OSAlarmLink {
OSAlarm *prev;
OSAlarm *next;
};
typedef void (*OSAlarmCallback)(OSAlarm *alarm, OSContext *context);
struct OSAlarm {
uint32_t tag;
const char *name;
uint32_t _8;
OSAlarmCallback callback;
uint32_t group;
uint32_t _14;
uint64_t nextFire;
OSAlarmLink link;
uint64_t period;
uint64_t start;
void *userData;
uint32_t state;
OSThreadQueue threadQueue;
OSAlarmQueue *alarmQueue;
OSContext *context;
};
// PPC disassembly
typedef void (*DisassemblyPrintFn)(const char *fmt, ...);
typedef uint32_t (*DisassemblyFindSymbolFn)(uint32_t addr, char *buffer, size_t bufsize);
enum DisassemblyFlags {
DISASSEMBLY_FLAGS_NONE = 0,
DISASSEMBLY_FLAGS_SIMPLIFY = 1,
DISASSEMBLY_FLAGS_SPACE = 0x20,
DISASSEMBLY_FLAGS_PLAIN = 0x40,
DISASSEMBLY_FLAGS_NO_OPCODE = 0x80,
DISASSEMBLY_FLAGS_PRINT_SYMBOLS = 0x100
};
// Exceptions
enum OSExceptionMode {
OS_EXCEPTION_MODE_THREAD = 1,
OS_EXCEPTION_MODE_GLOBAL = 2,
OS_EXCEPTION_MODE_THREAD_ALL_CORES = 3,
OS_EXCEPTION_MODE_GLOBAL_ALL_CORES = 4
};
enum OSExceptionType {
OS_EXCEPTION_TYPE_DSI = 2,
OS_EXCEPTION_TYPE_ISI = 3,
OS_EXCEPTION_TYPE_PROGRAM = 6
};
typedef bool (*OSExceptionCallback)(OSContext *context);
// File system
enum FSMode {
FS_MODE_READ_OWNER = 0x400,
FS_MODE_WRITE_OWNER = 0x200,
FS_MODE_EXEC_OWNER = 0x100,
FS_MODE_READ_GROUP = 0x040,
FS_MODE_WRITE_GROUP = 0x020,
FS_MODE_EXEC_GROUP = 0x010,
FS_MODE_READ_OTHER = 0x004,
FS_MODE_WRITE_OTHER = 0x002,
FS_MODE_EXEC_OTHER = 0x001
};
enum FSStatFlags {
FS_STAT_DIRECTORY = 0x80000000
};
enum FSMountSourceType {
FS_MOUNT_SOURCE_SD = 0
};
struct FSClient {
char data[0x1700];
};
struct FSCmdBlock {
char data[0xA80];
};
struct FSMountSource {
char data[0x300];
};
struct __attribute__((packed)) FSStat {
FSStatFlags flags;
FSMode mode;
uint32_t owner;
uint32_t group;
uint32_t size;
char _14[0xC];
uint32_t entryId;
int64_t created;
int64_t modified;
char _34[0x30];
};
struct FSDirectoryEntry {
FSStat info;
char name[256];
};
// MCP
struct MCPTitleListType {
uint64_t titleId;
uint32_t _4;
char path[56];
uint32_t appType;
char _48[0xC];
uint8_t device;
char _55;
char indexedDevice[10];
uint8_t _60;
};
// Function pointers
extern int (*OSDynLoad_Acquire)(const char *name, uint32_t *handle);
extern int (*OSDynLoad_FindExport)(uint32_t handle, bool isData, const char *name, void *ptr);
extern int (*OSDynLoad_GetModuleName)(uint32_t handle, char *name, int *size);
extern OSMutex *OSDynLoad_gLoaderLock;
extern bool (*OSIsDebuggerInitialized)();
extern void (*exit)(int result);
extern void (*_Exit)(int result);
extern void (*OSFatal)(const char *msg);
extern uint32_t (*OSGetSymbolName)(uint32_t addr, char *buffer, size_t bufsize);
extern void (*DisassemblePPCRange)(uint32_t start, uint32_t end, DisassemblyPrintFn printFunc, DisassemblyFindSymbolFn symFunc, DisassemblyFlags flags);
extern void (*DisassemblePPCOpcode)(uint32_t addr, void *buffer, size_t bufsize, DisassemblyFindSymbolFn symFunc, DisassemblyFlags flags);
extern int (*OSSetExceptionCallback)(OSExceptionType type, OSExceptionCallback callback);
extern int (*OSSetExceptionCallbackEx)(OSExceptionMode mode, OSExceptionType type, OSExceptionCallback callback);
extern void (*OSLoadContext)(OSContext *context);
extern int (*OSDisableInterrupts)();
extern void (*OSRestoreInterrupts)(int state);
extern void (*__OSLockScheduler)(void *);
extern void (*__OSUnlockScheduler)(void *);
extern void (*OSInitMutex)(OSMutex *mutex);
extern void (*OSLockMutex)(OSMutex *mutex);
extern void (*OSUnlockMutex)(OSMutex *mutex);
extern void (*OSInitMessageQueue)(OSMessageQueue *queue, OSMessage *messages, int count);
extern bool (*OSSendMessage)(OSMessageQueue *queue, OSMessage *message, OSMessageFlags flags);
extern bool (*OSReceiveMessage)(OSMessageQueue *queue, OSMessage *message, OSMessageFlags flags);
extern void (*OSCreateAlarm)(OSAlarm *alarm);
extern bool (*OSSetAlarm)(OSAlarm *alarm, uint64_t timeout, OSAlarmCallback callback);
extern void (*OSCancelAlarm)(OSAlarm *alarm);
extern bool (*OSWaitAlarm)(OSAlarm *alarm);
extern OSThread *(*OSGetCurrentThread)();
extern OSThread *(*OSGetDefaultThread)(int core);
extern bool (*OSCreateThread)(OSThread *thread, OSThreadFunc func, int argc, void *argv, void *stack, uint32_t stackSize, int priority, int attr);
extern int (*OSResumeThread)(OSThread *thread);
extern bool (*OSJoinThread)(OSThread *thread, int *result);
extern void (*OSExitThread)(int result);
extern const char *(*OSGetThreadName)(OSThread *thread);
extern void (*OSSetThreadName)(OSThread *thread, const char *name);
extern uint32_t (*OSGetThreadAffinity)(OSThread *thread);
extern int (*OSGetThreadPriority)(OSThread *thread);
extern OSSystemInfo *(*OSGetSystemInfo)();
extern void (*OSSleepTicks)(uint64_t ticks);
extern uint64_t (*OSGetTitleID)();
extern int (*OSGetMemBound)(OSMemoryType type, uint32_t *startPtr, uint32_t *sizePtr);
extern uint32_t (*OSEffectiveToPhysical)(uint32_t addr);
extern void (*OSScreenInit)();
extern uint32_t (*OSScreenGetBufferSizeEx)(int screen);
extern void (*OSScreenSetBufferEx)(int screen, void *buffer);
extern void (*OSScreenEnableEx)(int screen, bool enabled);
extern void (*OSScreenClearBufferEx)(int screen, uint32_t color);
extern void (*OSScreenFlipBuffersEx)(int screen);
extern void (*OSScreenPutPixelEx)(int screen, int x, int y, uint32_t color);
extern void (*OSScreenPutFontEx)(int screen, int x, int y, const char *text);
extern void (*DCFlushRange)(const void *buffer, uint32_t length);
extern void (*DCInvalidateRange)(const void *buffer, uint32_t length);
extern void (*ICInvalidateRange)(const void *buffer, uint32_t length);
extern int (*IOS_Open)(const char *path, int mode);
extern int (*IOS_Ioctl)(int fd, uint32_t request, const void *inptr, uint32_t inlen, void *outptr, uint32_t outlen);
extern int (*IOS_Close)(int fd);
extern int (*FSInit)();
extern int (*FSAddClient)(FSClient *client, uint32_t flags);
extern int (*FSInitCmdBlock)(FSCmdBlock *block);
extern int (*FSGetMountSource)(FSClient *client, FSCmdBlock *block, FSMountSourceType type, FSMountSource *source, uint32_t flags);
extern int (*FSMount)(FSClient *client, FSCmdBlock *block, FSMountSource *source, char *path, uint32_t bytes, uint32_t flags);
extern int (*FSMakeDir)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
extern int (*FSChangeDir)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
extern int (*FSGetCwd)(FSClient *client, FSCmdBlock *block, char *path, int length, uint32_t flags);
extern int (*FSOpenDir)(FSClient *client, FSCmdBlock *block, const char *path, int *handle, uint32_t flags);
extern int (*FSReadDir)(FSClient *client, FSCmdBlock *block, int handle, FSDirectoryEntry *entry, uint32_t flags);
extern int (*FSCloseDir)(FSClient *client, FSCmdBlock *block, int handle, uint32_t flags);
extern int (*FSOpenFile)(FSClient *client, FSCmdBlock *block, const char *path, const char *mode, int *handle, uint32_t flags);
extern int (*FSGetStatFile)(FSClient *client, FSCmdBlock *block, int handle, FSStat *stat, uint32_t flags);
extern int (*FSReadFile)(FSClient *client, FSCmdBlock *block, void *buffer, int size, int count, int handle, int flag, uint32_t flags);
extern int (*FSWriteFile)(FSClient *client, FSCmdBlock *block, const void *buffer, int size, int count, int handle, int flag, uint32_t flags);
extern int (*FSCloseFile)(FSClient *client, FSCmdBlock *block, int handle, uint32_t flags);
extern int (*FSGetStat)(FSClient *client, FSCmdBlock *block, const char *path, FSStat *stat, uint32_t flags);
extern int (*FSRename)(FSClient *client, FSCmdBlock *block, const char *oldPath, const char *newPath, uint32_t flags);
extern int (*FSRemove)(FSClient *client, FSCmdBlock *block, const char *path, uint32_t flags);
extern int (*FSDelClient)(FSClient *client, uint32_t flags);
extern void (*FSShutdown)();
extern int (*MCP_Open)();
extern int (*MCP_GetDeviceId)(int handle, uint32_t *deviceId);
extern int (*MCP_TitleList)(int handle, uint32_t *count, MCPTitleListType *list, uint32_t size);
extern int (*MCP_TitleListByAppType)(int handle, uint32_t appType, uint32_t *count, MCPTitleListType *list, uint32_t size);
extern int (*MCP_TitleListByDevice)(int handle, const char *device, uint32_t *count, MCPTitleListType *list, uint32_t size);
extern void (*MCP_Close)(int handle);
extern void (*__KernelGetInfo)(KernelInfoType type, void *buffer, uint32_t size, uint32_t unk);
extern int (*snprintf)(char *str, size_t size, const char *format, ...);
extern void *(*MEMGetBaseHeapHandle)(int type);
extern uint32_t (*MEMGetAllocatableSizeForExpHeapEx)(void *handle, int alignment);
extern void *(**pMEMAllocFromDefaultHeap)(uint32_t size);
extern void *(**pMEMAllocFromDefaultHeapEx)(uint32_t size, int alignment);
extern void (**pMEMFreeToDefaultHeap)(void *ptr);
#define MEMAllocFromDefaultHeap (*pMEMAllocFromDefaultHeap)
#define MEMAllocFromDefaultHeapEx (*pMEMAllocFromDefaultHeapEx)
#define MEMFreeToDefaultHeap (*pMEMFreeToDefaultHeap)
// Internal
extern OSDynLoad_RPLInfo **pMainRPL;
extern OSDynLoad_RPLInfo **pFirstRPL;
extern OSThread **pThreadList;
#define MainRPL (*pMainRPL)
#define FirstRPL (*pFirstRPL)
#define ThreadList (*pThreadList)
void coreinitInitialize();

View File

@ -1,20 +0,0 @@
#include "cafe/coreinit.h"
#include <cstdint>
namespace nn::act {
uint32_t (*Initialize)();
uint8_t (*GetSlotNo)();
uint32_t (*GetPersistentIdEx)(uint8_t slot);
uint32_t (*Finalize)();
} // namespace nn::act
void nnactInitialize() {
uint32_t handle;
OSDynLoad_Acquire("nn_act.rpl", &handle);
OSDynLoad_FindExport(handle, false, "Initialize__Q2_2nn3actFv", &nn::act::Initialize);
OSDynLoad_FindExport(handle, false, "GetSlotNo__Q2_2nn3actFv", &nn::act::GetSlotNo);
OSDynLoad_FindExport(handle, false, "GetPersistentIdEx__Q2_2nn3actFUc", &nn::act::GetPersistentIdEx);
OSDynLoad_FindExport(handle, false, "Finalize__Q2_2nn3actFv", &nn::act::Finalize);
}

View File

@ -1,11 +0,0 @@
#include <cstdint>
namespace nn::act {
extern uint32_t (*Initialize)();
extern uint8_t (*GetSlotNo)();
extern uint32_t (*GetPersistentIdEx)(uint8_t slot);
extern uint32_t (*Finalize)();
} // namespace nn::act
void nnactInitialize();

View File

@ -1,18 +0,0 @@
#include "cafe/coreinit.h"
#include <cstdint>
int (*SAVEInit)();
int (*SAVEOpenFile)(FSClient *client, FSCmdBlock *block, uint8_t slot, const char *path, int *handle, uint32_t flags);
int (*SAVEGetSharedDataTitlePath)(uint64_t titleId, const char *path, char *outpath, uint32_t outlen);
void (*SAVEShutdown)();
void nnsaveInitialize() {
uint32_t handle;
OSDynLoad_Acquire("nn_save.rpl", &handle);
OSDynLoad_FindExport(handle, false, "SAVEInit", &SAVEInit);
OSDynLoad_FindExport(handle, false, "SAVEOpenFile", &SAVEOpenFile);
OSDynLoad_FindExport(handle, false, "SAVEGetSharedDataTitlePath", &SAVEGetSharedDataTitlePath);
OSDynLoad_FindExport(handle, false, "SAVEShutdown", &SAVEShutdown);
}

View File

@ -1,12 +0,0 @@
#pragma once
#include "cafe/coreinit.h"
#include <cstdint>
extern int (*SAVEInit)();
extern int (*SAVEOpenFile)(FSClient *client, FSCmdBlock *block, uint8_t slot, const char *path, int *handle, uint32_t flags);
extern int (*SAVEGetSharedDataTitlePath)(uint64_t titleId, const char *path, char *outpath, uint32_t outlen);
extern void (*SAVEShutdown)();
void nnsaveInitialize();

View File

@ -1,35 +0,0 @@
#include "cafe/nsysnet.h"
#include "cafe/coreinit.h"
#include <cstdint>
int (*socket_lib_init)();
int (*inet_aton)(const char *ip, uint32_t *addr);
int (*socket)(int domain, int type, int protocol);
int (*setsockopt)(int socket, int level, int optname, void *optval, int optlen);
int (*connect)(int socket, sockaddr *addr, int addrlen);
int (*bind)(int socket, sockaddr *addr, int addrlen);
int (*listen)(int socket, int backlog);
int (*accept)(int socket, sockaddr *addr, int *addrlen);
int (*send)(int socket, const void *buffer, int size, int flags);
int (*recv)(int socket, void *buffer, int size, int flags);
int (*socketclose)(int socket);
int (*socket_lib_finish)();
void nsysnetInitialize() {
uint32_t handle;
OSDynLoad_Acquire("nsysnet.rpl", &handle);
OSDynLoad_FindExport(handle, false, "socket_lib_init", &socket_lib_init);
OSDynLoad_FindExport(handle, false, "inet_aton", &inet_aton);
OSDynLoad_FindExport(handle, false, "socket", &socket);
OSDynLoad_FindExport(handle, false, "setsockopt", &setsockopt);
OSDynLoad_FindExport(handle, false, "connect", &connect);
OSDynLoad_FindExport(handle, false, "bind", &bind);
OSDynLoad_FindExport(handle, false, "listen", &listen);
OSDynLoad_FindExport(handle, false, "accept", &accept);
OSDynLoad_FindExport(handle, false, "send", &send);
OSDynLoad_FindExport(handle, false, "recv", &recv);
OSDynLoad_FindExport(handle, false, "socketclose", &socketclose);
OSDynLoad_FindExport(handle, false, "socket_lib_finish", &socket_lib_finish);
}

View File

@ -1,37 +0,0 @@
#pragma once
#include <cstdint>
#define AF_INET 2
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define SOL_SOCKET -1
#define SO_REUSEADDR 4
struct sockaddr {
uint16_t family;
uint16_t port;
uint32_t addr;
char zero[8];
};
extern int (*socket_lib_init)();
extern int (*inet_aton)(const char *ip, uint32_t *addr);
extern int (*socket)(int domain, int type, int protocol);
extern int (*setsockopt)(int socket, int level, int optname, void *optval, int optlen);
extern int (*connect)(int socket, sockaddr *addr, int addrlen);
extern int (*bind)(int socket, sockaddr *addr, int addrlen);
extern int (*listen)(int socket, int backlog);
extern int (*accept)(int socket, sockaddr *addr, int *addrlen);
extern int (*send)(int socket, const void *buffer, int size, int flags);
extern int (*recv)(int socket, void *buffer, int size, int flags);
extern int (*socketclose)(int socket);
extern int (*socket_lib_finish)();
void nsysnetInitialize();

View File

@ -1,20 +0,0 @@
#include "cafe/sysapp.h"
#include "cafe/coreinit.h"
bool (*SYSCheckTitleExists)(uint64_t titleId);
void (*SYSLaunchTitle)(uint64_t titleId);
void (*SYSLaunchMenu)();
void (*SYSLaunchTitleByPathFromLauncher)(const char *path, int len);
void sysappInitialize() {
uint32_t handle;
OSDynLoad_Acquire("sysapp.rpl", &handle);
OSDynLoad_FindExport(handle, false, "SYSCheckTitleExists", &SYSCheckTitleExists);
OSDynLoad_FindExport(handle, false, "SYSLaunchTitle", &SYSLaunchTitle);
OSDynLoad_FindExport(handle, false, "SYSLaunchMenu", &SYSLaunchMenu);
OSDynLoad_FindExport(handle, false, "_SYSLaunchTitleByPathFromLauncher", &SYSLaunchTitleByPathFromLauncher);
}

View File

@ -1,12 +0,0 @@
#pragma once
#include <cstdint>
extern bool (*SYSCheckTitleExists)(uint64_t titleId);
extern void (*SYSLaunchTitle)(uint64_t titleId);
extern void (*SYSLaunchMenu)();
extern void (*SYSLaunchTitleByPathFromLauncher)(const char *path, int len);
void sysappInitialize();

View File

@ -1,12 +0,0 @@
#include "cafe/vpad.h"
#include "cafe/coreinit.h"
void (*VPADRead)(int chan, VPADStatus *buffers, uint32_t count, int *error);
void vpadInitialize() {
uint32_t handle;
OSDynLoad_Acquire("vpad.rpl", &handle);
OSDynLoad_FindExport(handle, false, "VPADRead", &VPADRead);
}

View File

@ -1,89 +0,0 @@
#pragma once
#include <cstdint>
enum VPADButtons {
VPAD_BUTTON_A = 0x8000,
VPAD_BUTTON_B = 0x4000,
VPAD_BUTTON_X = 0x2000,
VPAD_BUTTON_Y = 0x1000,
VPAD_BUTTON_LEFT = 0x0800,
VPAD_BUTTON_RIGHT = 0x0400,
VPAD_BUTTON_UP = 0x0200,
VPAD_BUTTON_DOWN = 0x0100,
VPAD_BUTTON_ZL = 0x0080,
VPAD_BUTTON_ZR = 0x0040,
VPAD_BUTTON_L = 0x0020,
VPAD_BUTTON_R = 0x0010,
VPAD_BUTTON_PLUS = 0x0008,
VPAD_BUTTON_MINUS = 0x0004,
VPAD_BUTTON_HOME = 0x0002,
VPAD_BUTTON_SYNC = 0x0001,
VPAD_BUTTON_STICK_R = 0x00020000,
VPAD_BUTTON_STICK_L = 0x00040000,
VPAD_BUTTON_TV = 0x00010000
};
struct VPADVec2D {
float x;
float y;
};
struct VPADVec3D {
float x;
float y;
float z;
};
struct VPADDirection {
VPADVec3D x;
VPADVec3D y;
VPADVec3D z;
};
struct VPADTouchData {
uint16_t x;
uint16_t y;
uint16_t touched;
uint16_t validity;
};
struct VPADAccStatus {
VPADVec3D acc;
float magnitude;
float variation;
VPADVec2D vertical;
};
struct VPADStatus {
uint32_t hold;
uint32_t pressed;
uint32_t released;
VPADVec2D leftStick;
VPADVec2D rightStick;
VPADAccStatus accelerometer;
VPADVec3D gyro;
VPADVec3D angle;
uint8_t error;
uint8_t _51;
VPADTouchData tpNormal;
VPADTouchData tpFiltered1;
VPADTouchData tpFiltered2;
uint16_t _6A;
VPADDirection direction;
bool headphones;
VPADVec3D mag;
uint8_t volume;
uint8_t battery;
uint8_t micStatus;
uint8_t volumeEx;
char _A4[8];
};
extern void (*VPADRead)(int chan, VPADStatus *buffers, uint32_t count, int *error);
void vpadInitialize();

View File

@ -1,18 +1,22 @@
#include "cafe/coreinit.h"
#include "cafe/nsysnet.h"
#include "cafe/vpad.h"
#include "kernel.h"
#include "debugger.h" #include "debugger.h"
#include "exceptions.h" #include "exceptions.h"
#include "input.h" #include "input.h"
#include "logger.h"
#include "screen.h" #include "screen.h"
#include <coreinit/cache.h>
#include <coreinit/debug.h>
#include <coreinit/dynload.h>
#include <coreinit/exception.h>
#include <coreinit/memory.h>
#include <cstdio>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <malloc.h>
#include <vpad/input.h>
Debugger *debugger;
bool BreakPoint::isRange(uint32_t addr, uint32_t length) { bool BreakPoint::isRange(uint32_t addr, uint32_t length) const {
return address >= addr && address <= addr + length - 1; return address >= addr && address <= addr + length - 1;
} }
@ -125,7 +129,7 @@ void BreakPointMgr::read(void *buffer, uint32_t addr, uint32_t length) {
char *bufptr = (char *) buffer + offset; char *bufptr = (char *) buffer + offset;
if (bp->address > addr + length - 4) { if (bp->address > addr + length - 4) {
uint32_t value = bp->instruction; uint32_t value = bp->instruction;
for (int i = 0; i < length - offset; i++) { for (uint32_t i = 0; i < length - offset; i++) {
bufptr[i] = value >> 24; bufptr[i] = value >> 24;
value <<= 8; value <<= 8;
} }
@ -195,7 +199,7 @@ uint32_t BreakPointMgr::getInstr(uint32_t addr) {
void BreakPointMgr::clearSpecial(OSThread *thread) { void BreakPointMgr::clearSpecial(OSThread *thread) {
lock(); lock();
for (int i = 0; i < special.size(); i++) { for (size_t i = 0; i < special.size(); i++) {
SpecialBreakPoint *bp = special[i]; SpecialBreakPoint *bp = special[i];
if (bp->thread == thread) { if (bp->thread == thread) {
disable(bp); disable(bp);
@ -276,6 +280,7 @@ bool ExceptionState::isBreakpoint() {
} }
void ExceptionState::resume() { void ExceptionState::resume() {
DEBUG_FUNCTION_LINE("OSLoadContext");
OSLoadContext(&context); OSLoadContext(&context);
} }
@ -294,12 +299,11 @@ void ExceptionMgr::unlock() {
void ExceptionMgr::cleanup() { void ExceptionMgr::cleanup() {
OSMessage message; OSMessage message;
message.message = Debugger::STEP_CONTINUE; message.message = (void *) Debugger::STEP_CONTINUE;
lock(); lock();
for (int i = 0; i < list.size(); i++) { for (auto state : list) {
ExceptionState *state = list[i];
if (state->isPaused) { if (state->isPaused) {
OSSendMessage(&state->queue, &message, OS_MESSAGE_FLAGS_NONE); OSSendMessage(&state->queue, &message, OS_MESSAGE_FLAGS_NONE);
} }
@ -310,8 +314,7 @@ void ExceptionMgr::cleanup() {
ExceptionState *ExceptionMgr::find(OSThread *thread) { ExceptionState *ExceptionMgr::find(OSThread *thread) {
lock(); lock();
for (int i = 0; i < list.size(); i++) { for (auto state : list) {
ExceptionState *state = list[i];
if (state->thread == thread) { if (state->thread == thread) {
unlock(); unlock();
return state; return state;
@ -493,7 +496,7 @@ void StepMgr::adjustAddress(ExceptionState *state) {
bool Debugger::checkDataRead(uint32_t addr, uint32_t length) { bool Debugger::checkDataRead(uint32_t addr, uint32_t length) {
uint32_t memStart, memSize; uint32_t memStart, memSize;
OSGetMemBound(MEM2, &memStart, &memSize); OSGetMemBound(OS_MEM2, &memStart, &memSize);
uint32_t memEnd = memStart + memSize; uint32_t memEnd = memStart + memSize;
@ -502,7 +505,7 @@ bool Debugger::checkDataRead(uint32_t addr, uint32_t length) {
Debugger::StepCommand Debugger::notifyBreak(ExceptionState *state) { Debugger::StepCommand Debugger::notifyBreak(ExceptionState *state) {
OSMessage message; OSMessage message;
message.message = ExceptionState::PROGRAM; message.message = (void *) ExceptionState::PROGRAM;
message.args[0] = (uint32_t) &state->context; message.args[0] = (uint32_t) &state->context;
message.args[1] = sizeof(OSContext); message.args[1] = sizeof(OSContext);
message.args[2] = (uint32_t) state->thread; message.args[2] = (uint32_t) state->thread;
@ -511,7 +514,7 @@ Debugger::StepCommand Debugger::notifyBreak(ExceptionState *state) {
state->isPaused = true; state->isPaused = true;
OSReceiveMessage(&state->queue, &message, OS_MESSAGE_FLAGS_BLOCKING); OSReceiveMessage(&state->queue, &message, OS_MESSAGE_FLAGS_BLOCKING);
state->isPaused = false; state->isPaused = false;
return (StepCommand) message.message; return (StepCommand) (uint32_t) message.message;
} }
void Debugger::resumeBreakPoint(ExceptionState *state) { void Debugger::resumeBreakPoint(ExceptionState *state) {
@ -539,24 +542,28 @@ void Debugger::handleBreakPoint(ExceptionState *state) {
Screen screen; Screen screen;
screen.init(); screen.init();
screen.drawText( Screen::drawText(
0, 0, "Waiting for debugger connection.\n" 0, 0, "Waiting for debugger connection.\n"
"Press the home button to continue without debugger.\n" "Press the home button to continue without debugger.\n"
"You can still connect while the game is running."); "You can still connect while the game is running.");
screen.flip(); Screen::flip();
while (!connected) { while (!connected) {
uint32_t buttons = GetInput(VPAD_BUTTON_HOME); uint32_t buttons = GetInput(VPAD_BUTTON_HOME);
if (buttons) { if (buttons) {
DEBUG_FUNCTION_LINE("Pressed home");
state->context.srr0 += 4; state->context.srr0 += 4;
state->resume(); state->resume();
} }
} }
} }
DEBUG_FUNCTION_LINE("stepper.handleBreakPoint(state);");
stepper.handleBreakPoint(state); stepper.handleBreakPoint(state);
if (!connected) { if (!connected) {
DEBUG_FUNCTION_LINE("if (!connected) {");
handleFatalCrash(&state->context, state->type); handleFatalCrash(&state->context, state->type);
} }
@ -579,7 +586,7 @@ void Debugger::handleCrash(ExceptionState *state) {
stepper.adjustAddress(state); stepper.adjustAddress(state);
if (connected) { if (connected) {
OSMessage message; OSMessage message;
message.message = state->type; message.message = (void *) state->type;
message.args[0] = (uint32_t) &state->context; message.args[0] = (uint32_t) &state->context;
message.args[1] = sizeof(OSContext); message.args[1] = sizeof(OSContext);
message.args[2] = (uint32_t) state->thread; message.args[2] = (uint32_t) state->thread;
@ -628,7 +635,7 @@ void Debugger::exceptionHandler(OSContext *context, ExceptionState::Type type) {
debugger->handleException(context, type); debugger->handleException(context, type);
} }
bool Debugger::dsiHandler(OSContext *context) { BOOL Debugger::dsiHandler(OSContext *context) {
OSContext *info = new OSContext(); OSContext *info = new OSContext();
memcpy(info, context, sizeof(OSContext)); memcpy(info, context, sizeof(OSContext));
context->srr0 = (uint32_t) exceptionHandler; context->srr0 = (uint32_t) exceptionHandler;
@ -637,7 +644,7 @@ bool Debugger::dsiHandler(OSContext *context) {
return true; return true;
} }
bool Debugger::isiHandler(OSContext *context) { BOOL Debugger::isiHandler(OSContext *context) {
OSContext *info = new OSContext(); OSContext *info = new OSContext();
memcpy(info, context, sizeof(OSContext)); memcpy(info, context, sizeof(OSContext));
context->srr0 = (uint32_t) exceptionHandler; context->srr0 = (uint32_t) exceptionHandler;
@ -646,7 +653,7 @@ bool Debugger::isiHandler(OSContext *context) {
return true; return true;
} }
bool Debugger::programHandler(OSContext *context) { BOOL Debugger::programHandler(OSContext *context) {
OSContext *info = new OSContext(); OSContext *info = new OSContext();
memcpy(info, context, sizeof(OSContext)); memcpy(info, context, sizeof(OSContext));
context->srr0 = (uint32_t) exceptionHandler; context->srr0 = (uint32_t) exceptionHandler;
@ -664,13 +671,37 @@ void Debugger::cleanup() {
; ;
} }
extern "C" void OSRestoreInterrupts(int state);
extern "C" void __OSLockScheduler(void *);
extern "C" void __OSUnlockScheduler(void *);
extern "C" int OSDisableInterrupts();
static const char **commandNames = (const char *[]){
"COMMAND_CLOSE",
"COMMAND_READ",
"COMMAND_WRITE",
"COMMAND_WRITE_CODE",
"COMMAND_GET_MODULE_NAME",
"COMMAND_GET_MODULE_LIST",
"COMMAND_GET_THREAD_LIST",
"COMMAND_GET_STACK_TRACE",
"COMMAND_TOGGLE_BREAKPOINT",
"COMMAND_POKE_REGISTERS",
"COMMAND_RECEIVE_MESSAGES",
"COMMAND_SEND_MESSAGE"};
void Debugger::mainLoop(Client *client) { void Debugger::mainLoop(Client *client) {
while (true) { DEBUG_FUNCTION_LINE("About to enter mainLoop while");
while (!stopRunning) {
uint8_t cmd; uint8_t cmd;
if (!client->recvall(&cmd, 1)) return; if (!client->recvall(&cmd, 1)) return;
if (cmd == COMMAND_CLOSE) return; if (cmd <= 11) {
else if (cmd == COMMAND_READ) { DEBUG_FUNCTION_LINE("Recieved command %s %d", commandNames[cmd], cmd);
}
if (cmd == COMMAND_CLOSE) {
return;
} else if (cmd == COMMAND_READ) {
uint32_t addr, length; uint32_t addr, length;
if (!client->recvall(&addr, 4)) return; if (!client->recvall(&addr, 4)) return;
if (!client->recvall(&length, 4)) return; if (!client->recvall(&length, 4)) return;
@ -678,10 +709,10 @@ void Debugger::mainLoop(Client *client) {
char *buffer = new char[length]; char *buffer = new char[length];
breakpoints.read(buffer, addr, length); breakpoints.read(buffer, addr, length);
if (!client->sendall(buffer, length)) { if (!client->sendall(buffer, length)) {
delete buffer; delete[] buffer;
return; return;
} }
delete buffer; delete[] buffer;
} else if (cmd == COMMAND_WRITE) { } else if (cmd == COMMAND_WRITE) {
uint32_t addr, length; uint32_t addr, length;
if (!client->recvall(&addr, 4)) return; if (!client->recvall(&addr, 4)) return;
@ -694,47 +725,53 @@ void Debugger::mainLoop(Client *client) {
char *buffer = new char[length]; char *buffer = new char[length];
if (!client->recvall(buffer, length)) { if (!client->recvall(buffer, length)) {
delete buffer; delete[] buffer;
return; return;
} }
breakpoints.write(buffer, addr, length); breakpoints.write(buffer, addr, length);
delete buffer; delete[] buffer;
} else if (cmd == COMMAND_GET_MODULE_NAME) { } else if (cmd == COMMAND_GET_MODULE_NAME) {
char name[0x40]; char name[0x40];
int length = 0x40; int length = 0x40;
OSDynLoad_GetModuleName(-1, name, &length); OSDynLoad_GetModuleName(reinterpret_cast<OSDynLoad_Module>(-1), name, &length);
length = strlen(name); length = strlen(name);
if (!client->sendall(&length, 4)) return; if (!client->sendall(&length, 4)) return;
if (!client->sendall(name, length)) return; if (!client->sendall(name, length)) return;
} else if (cmd == COMMAND_GET_MODULE_LIST) { } else if (cmd == COMMAND_GET_MODULE_LIST) {
OSLockMutex(OSDynLoad_gLoaderLock); int num_rpls = OSDynLoad_GetNumberOfRPLs();
if (num_rpls == 0) {
return;
}
std::vector<OSDynLoad_NotifyData> rpls;
rpls.resize(num_rpls);
bool ret = OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data());
if (!ret) {
return;
}
char buffer[0x1000]; //This should be enough char buffer[0x1000]; //This should be enough
uint32_t offset = 0; uint32_t offset = 0;
OSDynLoad_RPLInfo *current = FirstRPL;
while (current) {
OSDynLoad_NotifyData *info = current->notifyData;
uint32_t namelen = strlen(current->name); for (auto &info : rpls) {
uint32_t namelen = strlen(info.name);
if (offset + 0x18 + namelen > 0x1000) { if (offset + 0x18 + namelen > 0x1000) {
break; break;
} }
auto *infobuf = (uint32_t *) (buffer + offset);
uint32_t *infobuf = (uint32_t *) (buffer + offset); infobuf[0] = info.textAddr;
infobuf[0] = info->textAddr; infobuf[1] = info.textSize;
infobuf[1] = info->textSize; infobuf[2] = info.dataAddr;
infobuf[2] = info->dataAddr; infobuf[3] = info.dataSize;
infobuf[3] = info->dataSize; infobuf[4] = (uint32_t) 0; // TODO: missing
infobuf[4] = (uint32_t) current->entryPoint; infobuf[5] = namelen;
infobuf[5] = namelen; memcpy(&infobuf[6], info.name, namelen);
memcpy(&infobuf[6], current->name, namelen); offset += 0x18 + strlen(info.name);
offset += 0x18 + namelen;
current = current->next;
} }
OSUnlockMutex(OSDynLoad_gLoaderLock); //OSUnlockMutex(OSDynLoad_gLoaderLock);
if (!client->sendall(&offset, 4)) return; if (!client->sendall(&offset, 4)) return;
if (!client->sendall(buffer, offset)) return; if (!client->sendall(buffer, offset)) return;
@ -758,9 +795,10 @@ void Debugger::mainLoop(Client *client) {
} }
int priority = current->basePriority; int priority = current->basePriority;
if (current->type == 1) { int type = *(uint32_t *) (current->__unk11);
if (type == 1) {
priority -= 0x20; priority -= 0x20;
} else if (current->type == 2) { } else if (type == 2) {
priority -= 0x40; priority -= 0x40;
} }
@ -768,7 +806,7 @@ void Debugger::mainLoop(Client *client) {
infobuf[0] = (uint32_t) current; infobuf[0] = (uint32_t) current;
infobuf[1] = current->attr & 7; infobuf[1] = current->attr & 7;
infobuf[2] = priority; infobuf[2] = priority;
infobuf[3] = (uint32_t) current->stackBase; infobuf[3] = (uint32_t) current->stackStart;
infobuf[4] = (uint32_t) current->stackEnd; infobuf[4] = (uint32_t) current->stackEnd;
infobuf[5] = (uint32_t) current->entryPoint; infobuf[5] = (uint32_t) current->entryPoint;
infobuf[6] = namelen; infobuf[6] = namelen;
@ -851,7 +889,7 @@ void Debugger::mainLoop(Client *client) {
OSMessage message; OSMessage message;
if (!client->recvall(&message, sizeof(OSMessage))) return; if (!client->recvall(&message, sizeof(OSMessage))) return;
OSThread *thread = (OSThread *) message.args[0]; auto *thread = (OSThread *) message.args[0];
exceptions.lock(); exceptions.lock();
ExceptionState *state = exceptions.find(thread); ExceptionState *state = exceptions.find(thread);
@ -859,30 +897,32 @@ void Debugger::mainLoop(Client *client) {
OSSendMessage(&state->queue, &message, OS_MESSAGE_FLAGS_NONE); OSSendMessage(&state->queue, &message, OS_MESSAGE_FLAGS_NONE);
} }
exceptions.unlock(); exceptions.unlock();
} else {
DEBUG_FUNCTION_LINE("Recieved unknown command %d", cmd);
} }
} }
} }
void Debugger::threadFunc() { void Debugger::threadFunc() {
int result = socket_lib_init(); DEBUG_FUNCTION_LINE("Hello from debugger thread :)!");
if (result < 0) {
OSFatal("Failed to initialize socket library");
}
OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_DSI, dsiHandler); OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_DSI, dsiHandler);
OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_ISI, isiHandler); OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_ISI, isiHandler);
OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_PROGRAM, programHandler); OSSetExceptionCallbackEx(OS_EXCEPTION_MODE_GLOBAL_ALL_CORES, OS_EXCEPTION_TYPE_PROGRAM, programHandler);
DEBUG_FUNCTION_LINE("Callback init done.!");
Server server; Server server;
Client client; Client client;
DEBUG_FUNCTION_LINE("Set initialized = true");
initialized = true; initialized = true;
while (true) { while (!stopRunning) {
if (!server.init(Socket::TCP)) continue; if (!server.init(Socket::TCP)) continue;
if (!server.bind(1560)) continue; if (!server.bind(1560)) continue;
if (!server.accept(&client)) continue; if (!server.accept(&client)) continue;
DEBUG_FUNCTION_LINE("Accepted a connection");
connected = true; connected = true;
mainLoop(&client); mainLoop(&client);
DEBUG_FUNCTION_LINE("Lets do some cleanup");
cleanup(); cleanup();
connected = false; connected = false;
client.close(); client.close();
@ -890,7 +930,8 @@ void Debugger::threadFunc() {
} }
} }
int Debugger::threadEntry(int argc, void *argv) { int Debugger::threadEntry(int argc, const char **argv) {
DEBUG_FUNCTION_LINE("threadEntry");
debugger->threadFunc(); debugger->threadFunc();
return 0; return 0;
} }
@ -900,25 +941,45 @@ void Debugger::start() {
connected = false; connected = false;
firstTrap = true; firstTrap = true;
DEBUG_FUNCTION_LINE("OSInitMessageQueue");
OSInitMessageQueue(&eventQueue, eventMessages, MESSAGE_COUNT); OSInitMessageQueue(&eventQueue, eventMessages, MESSAGE_COUNT);
DEBUG_FUNCTION_LINE("init breakpoints");
breakpoints.init(); breakpoints.init();
DEBUG_FUNCTION_LINE("init exceptions");
exceptions.init(); exceptions.init();
DEBUG_FUNCTION_LINE("init stepper");
stepper.init(); stepper.init();
serverThread = new OSThread();
char *stack = new char[0x8000];
DEBUG_FUNCTION_LINE("Alloc thread");
serverThread = (OSThread *) memalign(0x20, sizeof(OSThread));
DEBUG_FUNCTION_LINE("Alloc stack");
serverStack = (char *) memalign(0x20, STACK_SIZE);
DEBUG_FUNCTION_LINE("Create thread");
OSCreateThread( OSCreateThread(
serverThread, threadEntry, 0, 0, serverThread, threadEntry, 0, 0,
stack + STACK_SIZE, STACK_SIZE, serverStack + STACK_SIZE, STACK_SIZE,
0, 12); 0, 12);
DEBUG_FUNCTION_LINE("Set thread name");
OSSetThreadName(serverThread, "Debug Server"); OSSetThreadName(serverThread, "Debug Server");
DEBUG_FUNCTION_LINE("Resume thread");
OSResumeThread(serverThread); OSResumeThread(serverThread);
while (!initialized) { while (!initialized) {
DEBUG_FUNCTION_LINE("Wait for thread init");
OSSleepTicks(OSMillisecondsToTicks(20)); OSSleepTicks(OSMillisecondsToTicks(20));
} }
DEBUG_FUNCTION_LINE("Thread init done! Exit start()");
} }
Debugger *debugger; Debugger::~Debugger() {
stopRunning = true;
OSJoinThread(serverThread, nullptr);
free(serverStack);
serverStack = nullptr;
free(serverThread);
serverThread = nullptr;
}

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#include "cafe/coreinit.h"
#include "kernel.h" #include "kernel.h"
#include "socket.h" #include "socket.h"
#include <coreinit/messagequeue.h>
#include <coreinit/mutex.h>
#include <coreinit/thread.h>
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@ -14,6 +16,10 @@
#define TRAP 0x7FE00008 #define TRAP 0x7FE00008
extern OSThread **pThreadList;
#define ThreadList (*pThreadList)
template<int N> template<int N>
class Bits { class Bits {
public: public:
@ -26,7 +32,7 @@ public:
} }
private: private:
uint32_t value; uint32_t value{};
}; };
@ -42,14 +48,14 @@ public:
void resume(); void resume();
Type type; Type type;
OSContext context; OSContext context{};
OSThread *thread; OSThread *thread{};
OSMessageQueue queue; OSMessageQueue queue{};
OSMessage message; OSMessage message{};
bool isPaused; bool isPaused{};
}; };
@ -70,7 +76,7 @@ private:
class BreakPoint { class BreakPoint {
public: public:
bool isRange(uint32_t addr, uint32_t length); bool isRange(uint32_t addr, uint32_t length) const;
uint32_t address; uint32_t address;
uint32_t instruction; uint32_t instruction;
@ -91,7 +97,7 @@ public:
} }
T *alloc() { T *alloc() {
for (int i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
if (list[i].address == 0) { if (list[i].address == 0) {
return &list[i]; return &list[i];
} }
@ -105,7 +111,7 @@ public:
} }
T *find(uint32_t addr) { T *find(uint32_t addr) {
for (int i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
if (list[i].address == addr) { if (list[i].address == addr) {
return &list[i]; return &list[i];
} }
@ -114,17 +120,17 @@ public:
} }
T *findRange(uint32_t addr, uint32_t length, int *index) { T *findRange(uint32_t addr, uint32_t length, int *index) {
int i = *index; size_t i = *index;
while (i < size()) { while (i < size()) {
if (list[i].isRange(addr, length)) { if (list[i].isRange(addr, length)) {
*index = i + 1; *index = (int) i + 1;
return &list[i]; return &list[i];
} }
i++; i++;
} }
if (i > *index) { if ((int) i > *index) {
*index = i; *index = (int) i;
} }
return nullptr; return nullptr;
} }
@ -134,7 +140,7 @@ public:
} }
void cleanup() { void cleanup() {
for (int i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
if (list[i].address != 0) { if (list[i].address != 0) {
KernelWriteU32(list[i].address, list[i].instruction); KernelWriteU32(list[i].address, list[i].instruction);
list[i].address = 0; list[i].address = 0;
@ -176,7 +182,7 @@ private:
BreakPointList<BreakPoint> breakpoints; BreakPointList<BreakPoint> breakpoints;
BreakPointList<SpecialBreakPoint> special; BreakPointList<SpecialBreakPoint> special;
OSMutex mutex; OSMutex mutex{};
}; };
@ -194,7 +200,7 @@ private:
uint32_t *alloc(); uint32_t *alloc();
void free(int index); void free(int index);
void branchConditional(ExceptionState *state, uint32_t instruction, uint32_t target, bool checkCtr); static void branchConditional(ExceptionState *state, uint32_t instruction, uint32_t target, bool checkCtr);
OSMutex mutex; OSMutex mutex;
@ -212,6 +218,8 @@ public:
void start(); void start();
~Debugger();
private: private:
enum Command { enum Command {
COMMAND_CLOSE, COMMAND_CLOSE,
@ -228,10 +236,10 @@ private:
COMMAND_SEND_MESSAGE COMMAND_SEND_MESSAGE
}; };
static int threadEntry(int argc, void *argv); static int threadEntry(int argc, const char **argv);
static bool dsiHandler(OSContext *context); static BOOL dsiHandler(OSContext *context);
static bool isiHandler(OSContext *context); static BOOL isiHandler(OSContext *context);
static bool programHandler(OSContext *context); static BOOL programHandler(OSContext *context);
static void exceptionHandler(OSContext *context, ExceptionState::Type type); static void exceptionHandler(OSContext *context, ExceptionState::Type type);
void threadFunc(); void threadFunc();
@ -247,18 +255,20 @@ private:
bool checkDataRead(uint32_t addr, uint32_t length); bool checkDataRead(uint32_t addr, uint32_t length);
OSMessageQueue eventQueue; OSMessageQueue eventQueue{};
OSMessage eventMessages[MESSAGE_COUNT]; OSMessage eventMessages[MESSAGE_COUNT]{};
OSThread *serverThread; OSThread *serverThread{};
char *serverStack{};
BreakPointMgr breakpoints; BreakPointMgr breakpoints;
ExceptionMgr exceptions; ExceptionMgr exceptions;
StepMgr stepper; StepMgr stepper{};
bool initialized; bool stopRunning = false;
bool connected; bool initialized{};
bool firstTrap; bool connected{};
bool firstTrap{};
}; };
extern Debugger *debugger; extern "C" Debugger *debugger;

View File

@ -1,5 +1,9 @@
#include "cafe/coreinit.h"
#include <coreinit/context.h>
#include <coreinit/debug.h>
#include <coreinit/exception.h>
#include <cstdio>
void DumpContext(OSContext *context, const char *excType) { void DumpContext(OSContext *context, const char *excType) {
char buffer[1000]; char buffer[1000];
@ -28,17 +32,17 @@ void DumpContext(OSContext *context, const char *excType) {
OSFatal(buffer); OSFatal(buffer);
} }
bool DSIHandler(OSContext *context) { BOOL DSIHandler(OSContext *context) {
DumpContext(context, "A DSI"); DumpContext(context, "A DSI");
return false; return false;
} }
bool ISIHandler(OSContext *context) { BOOL ISIHandler(OSContext *context) {
DumpContext(context, "An ISI"); DumpContext(context, "An ISI");
return false; return false;
} }
bool ProgramHandler(OSContext *context) { BOOL ProgramHandler(OSContext *context) {
DumpContext(context, "A program"); DumpContext(context, "A program");
return false; return false;
} }

View File

@ -1,15 +0,0 @@
#pragma once
#include <cstdint>
#define MEM_BASE 0x800000
struct OsSpecifics {
uint32_t OSDynLoad_Acquire;
uint32_t OSDynLoad_FindExport;
};
#define OS_SPECIFICS ((OsSpecifics *) (MEM_BASE + 0x1500))
#define EXIT_SUCCESS 0
#define EXIT_RELAUNCH_ON_LOAD -3

View File

@ -1,21 +1,20 @@
#include "cafe/vpad.h"
#include <cstdint> #include <cstdint>
#include <vpad/input.h>
uint32_t GetInput(uint32_t mask) { uint32_t GetInput(uint32_t mask) {
VPADStatus input; VPADStatus input;
int error; VPADReadError error;
VPADRead(0, &input, 1, &error); VPADRead(VPAD_CHAN_0, &input, 1, &error);
return input.pressed & mask; return input.trigger & mask;
} }
uint32_t WaitInput(uint32_t mask) { uint32_t WaitInput(uint32_t mask) {
VPADStatus input; VPADStatus input;
int error; VPADReadError error;
while (true) { while (true) {
VPADRead(0, &input, 1, &error); VPADRead(VPAD_CHAN_0, &input, 1, &error);
if (input.pressed & mask) { if (input.trigger & mask) {
return input.pressed & mask; return input.trigger & mask;
} }
} }
} }

View File

@ -1,28 +0,0 @@
.global SCKernelCopyData
SCKernelCopyData:
// Disable data address translation
mfmsr %r6
li %r7, 0x10
andc %r6, %r6, %r7
mtmsr %r6
// Copy data
addi %r3, %r3, -1
addi %r4, %r4, -1
mtctr %r5
SCKernelCopyData_loop:
lbzu %r5, 1(%r4)
stbu %r5, 1(%r3)
bdnz SCKernelCopyData_loop
// Enable data address translation
ori %r6, %r6, 0x10
mtmsr %r6
blr
.global KernelCopyData
KernelCopyData:
li %r0, 0x2500
sc
blr

View File

@ -1,16 +1,7 @@
#include <coreinit/cache.h>
#include "cafe/coreinit.h" #include <coreinit/memorymap.h>
#include <cstdint> #include <cstdint>
#include <kernel/kernel.h>
#define KERN_SYSCALL_TBL1 0xFFE84C70 //Unknown
#define KERN_SYSCALL_TBL2 0xFFE85070 //Games
#define KERN_SYSCALL_TBL3 0xFFE85470 //Loader
#define KERN_SYSCALL_TBL4 0xFFEAAA60 //Home menu
#define KERN_SYSCALL_TBL5 0xFFEAAE60 //Browser
extern "C" void SCKernelCopyData(uint32_t dst, uint32_t src, uint32_t len);
extern "C" void KernelCopyData(uint32_t dst, uint32_t src, uint32_t len);
void KernelWrite(uint32_t addr, const void *data, uint32_t length) { void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
uint32_t dst = OSEffectiveToPhysical(addr); uint32_t dst = OSEffectiveToPhysical(addr);
@ -27,36 +18,3 @@ void KernelWriteU32(uint32_t addr, uint32_t value) {
DCFlushRange((void *) addr, 4); DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *) addr, 4); ICInvalidateRange((void *) addr, 4);
} }
/* Write a 32-bit word with kernel permissions */
void __attribute__((noinline)) kern_write(uint32_t addr, uint32_t value) {
asm volatile(
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12");
}
void PatchSyscall(int index, uint32_t addr) {
kern_write(KERN_SYSCALL_TBL1 + index * 4, addr);
kern_write(KERN_SYSCALL_TBL2 + index * 4, addr);
kern_write(KERN_SYSCALL_TBL3 + index * 4, addr);
kern_write(KERN_SYSCALL_TBL4 + index * 4, addr);
kern_write(KERN_SYSCALL_TBL5 + index * 4, addr);
}
void kernelInitialize() {
PatchSyscall(0x25, (uint32_t) SCKernelCopyData);
}

View File

@ -1,11 +1,6 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
void KernelWrite(uint32_t addr, const void *data, uint32_t length); void KernelWrite(uint32_t addr, const void *data, uint32_t length);
void KernelWriteU32(uint32_t addr, uint32_t value); void KernelWriteU32(uint32_t addr, uint32_t value);
void PatchSyscall(int index, void *ptr);
void kernelInitialize();

View File

@ -1,26 +0,0 @@
OUTPUT(diibugger.elf)
ENTRY(entryPoint)
SECTIONS {
. = 0x00802000;
.text : {
*(.text*);
}
.rodata : {
*(.rodata*);
}
.data : {
*(.data*);
*(.sdata*);
}
.bss : {
*(.bss*);
*(.sbss*);
}
/DISCARD/ : {
*(*);
}
}

36
src/logger.c Normal file
View File

@ -0,0 +1,36 @@
#ifdef DEBUG
#include <stdint.h>
#include <whb/log_cafe.h>
#include <whb/log_module.h>
#include <whb/log_udp.h>
uint32_t moduleLogInit = false;
uint32_t cafeLogInit = false;
uint32_t udpLogInit = false;
#endif // DEBUG
void initLogging() {
#ifdef DEBUG
if (!(moduleLogInit = WHBLogModuleInit())) {
cafeLogInit = WHBLogCafeInit();
udpLogInit = WHBLogUdpInit();
}
#endif // DEBUG
}
void deinitLogging() {
#ifdef DEBUG
if (moduleLogInit) {
WHBLogModuleDeinit();
moduleLogInit = false;
}
if (cafeLogInit) {
WHBLogCafeDeinit();
cafeLogInit = false;
}
if (udpLogInit) {
WHBLogUdpDeinit();
udpLogInit = false;
}
#endif // DEBUG
}

43
src/logger.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include <string.h>
#include <whb/log.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEBUG
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0)
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) \
do { \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0)
#else
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0)
#endif
void initLogging();
void deinitLogging();
#ifdef __cplusplus
}
#endif

View File

@ -1,87 +1,36 @@
#include "cafe/coreinit.h"
#include "cafe/nn_act.h"
#include "cafe/nn_save.h"
#include "cafe/nsysnet.h"
#include "cafe/sysapp.h"
#include "cafe/vpad.h"
#include "hbl.h"
#include "kernel.h"
#include "debugger.h" #include "debugger.h"
#include "exceptions.h" #include "exceptions.h"
#include "menu.h" #include "logger.h"
#include "patches.h" #include <coreinit/debug.h>
#include "screen.h" #include <wups.h>
OSThread **pThreadList;
bool GetTitleIdOnDisk(uint64_t *titleId) { WUPS_PLUGIN_NAME("Debugger");
MCPTitleListType title; WUPS_PLUGIN_DESCRIPTION("FTP Server");
uint32_t count = 0; WUPS_PLUGIN_VERSION("0.1");
WUPS_PLUGIN_AUTHOR("Kinnay");
WUPS_PLUGIN_LICENSE("GPL");
int handle = MCP_Open(); WUPS_USE_WUT_DEVOPTAB();
MCP_TitleListByDevice(handle, "odd", &count, &title, sizeof(title));
MCP_Close(handle);
if (count > 0) {
*titleId = title.titleId;
return true;
}
return false;
}
int MenuMain() {
Screen screen;
screen.init();
Menu menu(&screen);
Menu::Option result = menu.show();
if (result == Menu::Exit) return EXIT_SUCCESS;
else if (result == Menu::LaunchDisk) {
uint64_t titleId;
if (GetTitleIdOnDisk(&titleId)) {
SYSLaunchTitle(titleId);
} else {
menu.setMessage("Please insert a valid disk");
}
} else if (result == Menu::ReturnToMenu) {
SYSLaunchMenu();
}
return EXIT_RELAUNCH_ON_LOAD;
}
int DebuggerMain() {
ApplyPatches();
debugger = new Debugger();
debugger->start();
return EXIT_RELAUNCH_ON_LOAD;
}
bool firstRun = true;
int start() {
coreinitInitialize();
kernelInitialize();
vpadInitialize();
sysappInitialize();
nsysnetInitialize();
nnsaveInitialize();
nnactInitialize();
INITIALIZE_PLUGIN() {
InstallExceptionHandlers(); InstallExceptionHandlers();
}
int result; ON_APPLICATION_START() {
if (firstRun) { initLogging();
result = MenuMain(); DEBUG_FUNCTION_LINE("Started Debugger plugin");
} else { pThreadList = (OSThread **) 0x100567F8;
result = DebuggerMain(); debugger = new Debugger();
} DEBUG_FUNCTION_LINE("Created Debugger");
firstRun = false; debugger->start();
DEBUG_FUNCTION_LINE("Started Debugger thread");
return result;
} }
extern "C" int entryPoint() { ON_APPLICATION_REQUESTS_EXIT() {
return start(); DEBUG_FUNCTION_LINE("Deleting Debugger thread");
delete debugger;
DEBUG_FUNCTION_LINE("Deleted Debugger thread");
deinitLogging();
} }

View File

@ -1,28 +0,0 @@
#include "cafe/coreinit.h"
#include <cstddef>
void *operator new(size_t size) {
return MEMAllocFromDefaultHeap(size);
}
void *operator new[](size_t size) {
return MEMAllocFromDefaultHeap(size);
}
void *operator new(size_t size, int alignment) {
return MEMAllocFromDefaultHeapEx(size, alignment);
}
void *operator new[](size_t size, int alignment) {
return MEMAllocFromDefaultHeapEx(size, alignment);
}
void operator delete(void *ptr) {
MEMFreeToDefaultHeap(ptr);
}
void operator delete(void *ptr, size_t size) {
MEMFreeToDefaultHeap(ptr);
}

View File

@ -1,7 +0,0 @@
#pragma once
#include <cstddef>
void *operator new(size_t size, int alignment);
void *operator new[](size_t size, int alignment);

View File

@ -1,9 +1,8 @@
#include "menu.h" #include "menu.h"
#include "cafe/vpad.h"
#include "color.h" #include "color.h"
#include "input.h" #include "input.h"
#include "screen.h" #include <vpad/input.h>
Menu::Menu(Screen *screen) : screen(screen) { Menu::Menu(Screen *screen) : screen(screen) {
currentOption = LaunchDisk; currentOption = LaunchDisk;
@ -30,14 +29,14 @@ void Menu::setMessage(const char *message) {
void Menu::redraw() { void Menu::redraw() {
screen->clear(COLOR_BLUE); screen->clear(COLOR_BLUE);
screen->drawText(5, 5, "Wii U Debugger"); Screen::drawText(5, 5, "Wii U Debugger");
screen->drawText(5, 7, "Choose an option:"); Screen::drawText(5, 7, "Choose an option:");
screen->drawText(8, 9, "Install and launch disc"); Screen::drawText(8, 9, "Install and launch disc");
screen->drawText(8, 10, "Install and return to system menu"); Screen::drawText(8, 10, "Install and return to system menu");
screen->drawText(8, 11, "Exit without installing"); Screen::drawText(8, 11, "Exit without installing");
screen->drawText(5, 9 + currentOption, ">"); Screen::drawText(5, 9 + currentOption, ">");
if (message) { if (message) {
screen->drawText(5, 13, message); Screen::drawText(5, 13, message);
} }
screen->flip(); Screen::flip();
} }

View File

@ -5,11 +5,9 @@
class Menu { class Menu {
public: public:
enum Option { enum Option { LaunchDisk,
LaunchDisk, ReturnToMenu,
ReturnToMenu, Exit };
Exit
};
Menu(Screen *screen); Menu(Screen *screen);
Option show(); Option show();

View File

@ -1,56 +1,17 @@
#include "cafe/coreinit.h"
#include "kernel.h"
#include <cstdint> #include <cstdint>
#include <wups.h>
int OSSetExceptionCallback_Patch() { DECL_FUNCTION(int, OSSetExceptionCallback) {
return 0; return 0;
} }
DECL_FUNCTION(int, OSSetExceptionCallbackEx) {
int OSSetExceptionCallbackEx_Patch() {
return 0; return 0;
} }
DECL_FUNCTION(int, OSIsDebuggerInitialized) {
bool OSIsDebuggerInitialized_Patch() {
return true; return true;
} }
void Patch(void *funcPtr, void *patchPtr) {
OSDynLoad_NotifyData *sectionInfo = MainRPL->notifyData;
uint32_t func = (uint32_t) funcPtr; WUPS_MUST_REPLACE(OSSetExceptionCallback, WUPS_LOADER_LIBRARY_COREINIT, OSSetExceptionCallback);
uint32_t patch = (uint32_t) patchPtr; WUPS_MUST_REPLACE(OSSetExceptionCallbackEx, WUPS_LOADER_LIBRARY_COREINIT, OSSetExceptionCallbackEx);
if (func < 0x01800000) { //OS function (with trampoline) WUPS_MUST_REPLACE(OSIsDebuggerInitialized, WUPS_LOADER_LIBRARY_COREINIT, OSIsDebuggerInitialized);
for (uint32_t addr = sectionInfo->textAddr; addr < 0x10000000; addr += 4) {
uint32_t *instrs = (uint32_t *) addr;
if (instrs[0] == (0x3D600000 | (func >> 16)) && //lis r11, func@h
instrs[1] == (0x616B0000 | (func & 0xFFFF)) && //ori r11, r11, func@l
instrs[2] == 0x7D6903A6 && //mtctr r11
instrs[3] == 0x4E800420) //bctr
{
KernelWriteU32(addr, 0x3D600000 | (patch >> 16)); //lis r11, patch@h
KernelWriteU32(addr + 4, 0x616B0000 | (patch & 0xFFFF)); //ori r11, r11, patch@l
}
}
} else { //Dynamic function
for (uint32_t addr = sectionInfo->textAddr; addr < 0x10000000; addr += 4) {
uint32_t instr = *(uint32_t *) addr;
if ((instr & 0xFC000002) == 0x48000000) { //b or bl
if ((instr & 0x03FFFFFC) == func - addr) {
instr = instr & ~0x03FFFFFC;
instr |= patch;
instr |= 2; //Turn b/bl into ba/bla
KernelWriteU32(addr, instr);
}
}
}
}
}
void ApplyPatches() {
Patch((void *) OSSetExceptionCallback, (void *) OSSetExceptionCallback_Patch);
Patch((void *) OSSetExceptionCallbackEx, (void *) OSSetExceptionCallbackEx_Patch);
Patch((void *) OSIsDebuggerInitialized, (void *) OSIsDebuggerInitialized_Patch);
}

View File

@ -1,37 +1,38 @@
#include "screen.h" #include "screen.h"
#include "cafe/coreinit.h"
#include "memory.h"
Screen::Screen() : screenBuffer(0) {} #include <memory/mappedmemory.h>
Screen::Screen() : screenBuffer(nullptr) {}
Screen::~Screen() { Screen::~Screen() {
if (screenBuffer) { if (screenBuffer) {
operator delete(screenBuffer); MEMFreeToMappedMemory(screenBuffer);
screenBuffer = nullptr;
} }
} }
void Screen::init() { void Screen::init() {
OSScreenInit(); OSScreenInit();
uint32_t bufferSize0 = OSScreenGetBufferSizeEx(0); uint32_t bufferSize0 = OSScreenGetBufferSizeEx(SCREEN_TV);
uint32_t bufferSize1 = OSScreenGetBufferSizeEx(1); uint32_t bufferSize1 = OSScreenGetBufferSizeEx(SCREEN_DRC);
screenBuffer = operator new(bufferSize0 + bufferSize1, 0x40); screenBuffer = MEMAllocFromMappedMemoryForGX2Ex(bufferSize0 + bufferSize1, 0x100);
OSScreenSetBufferEx(0, screenBuffer); OSScreenSetBufferEx(SCREEN_TV, screenBuffer);
OSScreenSetBufferEx(1, (char *) screenBuffer + bufferSize0); OSScreenSetBufferEx(SCREEN_DRC, (char *) screenBuffer + bufferSize0);
OSScreenEnableEx(0, 1); OSScreenEnableEx(SCREEN_TV, 1);
OSScreenEnableEx(1, 1); OSScreenEnableEx(SCREEN_DRC, 1);
OSScreenClearBufferEx(0, 0); OSScreenClearBufferEx(SCREEN_TV, 0);
OSScreenClearBufferEx(1, 0); OSScreenClearBufferEx(SCREEN_DRC, 0);
OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(SCREEN_TV);
OSScreenFlipBuffersEx(1); OSScreenFlipBuffersEx(SCREEN_DRC);
} }
void Screen::clear(Display screen, uint32_t color) { void Screen::clear(OSScreenID screen, uint32_t color) {
OSScreenClearBufferEx(screen, color); OSScreenClearBufferEx(screen, color);
} }
void Screen::drawRect(Display screen, int x1, int y1, int x2, int y2, uint32_t color) { void Screen::drawRect(OSScreenID screen, int x1, int y1, int x2, int y2, uint32_t color) {
for (int x = x1; x < x2; x++) { for (int x = x1; x < x2; x++) {
OSScreenPutPixelEx(screen, x, y1, color); OSScreenPutPixelEx(screen, x, y1, color);
OSScreenPutPixelEx(screen, x, y2, color); OSScreenPutPixelEx(screen, x, y2, color);
@ -42,7 +43,7 @@ void Screen::drawRect(Display screen, int x1, int y1, int x2, int y2, uint32_t c
} }
} }
void Screen::fillRect(Display screen, int x1, int y1, int x2, int y2, uint32_t color) { void Screen::fillRect(OSScreenID screen, int x1, int y1, int x2, int y2, uint32_t color) {
for (int x = x1; x < x2; x++) { for (int x = x1; x < x2; x++) {
for (int y = y1; y < y2; y++) { for (int y = y1; y < y2; y++) {
OSScreenPutPixelEx(screen, x, y, color); OSScreenPutPixelEx(screen, x, y, color);
@ -50,11 +51,11 @@ void Screen::fillRect(Display screen, int x1, int y1, int x2, int y2, uint32_t c
} }
} }
void Screen::drawText(Display screen, int x, int y, const char *text) { void Screen::drawText(OSScreenID screen, int x, int y, const char *text) {
OSScreenPutFontEx(screen, x, y, text); OSScreenPutFontEx(screen, x, y, text);
} }
void Screen::flip(Display screen) { void Screen::flip(OSScreenID screen) {
OSScreenFlipBuffersEx(screen); OSScreenFlipBuffersEx(screen);
} }
@ -62,26 +63,26 @@ int Screen::convx(int x) { return x * 854 / 1280; }
int Screen::convy(int y) { return y * 480 / 720; } int Screen::convy(int y) { return y * 480 / 720; }
void Screen::clear(uint32_t color) { void Screen::clear(uint32_t color) {
clear(TV, color); clear(SCREEN_TV, color);
clear(DRC, color); clear(SCREEN_DRC, color);
} }
void Screen::drawRect(int x1, int y1, int x2, int y2, uint32_t color) { void Screen::drawRect(int x1, int y1, int x2, int y2, uint32_t color) {
drawRect(TV, x1, y1, x2, y2, color); drawRect(SCREEN_TV, x1, y1, x2, y2, color);
drawRect(DRC, convx(x1), convy(y1), convx(x2), convy(y2), color); drawRect(SCREEN_DRC, convx(x1), convy(y1), convx(x2), convy(y2), color);
} }
void Screen::fillRect(int x1, int y1, int x2, int y2, uint32_t color) { void Screen::fillRect(int x1, int y1, int x2, int y2, uint32_t color) {
fillRect(TV, x1, y1, x2, y2, color); fillRect(SCREEN_TV, x1, y1, x2, y2, color);
fillRect(DRC, convx(x1), convy(y1), convx(x2), convy(y2), color); fillRect(SCREEN_DRC, convx(x1), convy(y1), convx(x2), convy(y2), color);
} }
void Screen::drawText(int x, int y, const char *text) { void Screen::drawText(int x, int y, const char *text) {
drawText(TV, x, y, text); drawText(SCREEN_TV, x, y, text);
drawText(DRC, x, y, text); drawText(SCREEN_DRC, x, y, text);
} }
void Screen::flip() { void Screen::flip() {
flip(TV); flip(SCREEN_TV);
flip(DRC); flip(SCREEN_DRC);
} }

View File

@ -1,15 +1,11 @@
#pragma once #pragma once
#include <coreinit/screen.h>
#include <cstdint> #include <cstdint>
class Screen { class Screen {
public: public:
enum Display {
TV,
DRC
};
Screen(); Screen();
~Screen(); ~Screen();
@ -17,18 +13,18 @@ public:
void clear(uint32_t color); void clear(uint32_t color);
void drawRect(int x1, int y1, int x2, int y2, uint32_t color); void drawRect(int x1, int y1, int x2, int y2, uint32_t color);
void fillRect(int x1, int y1, int x2, int y2, uint32_t color); void fillRect(int x1, int y1, int x2, int y2, uint32_t color);
void drawText(int x, int y, const char *text); static void drawText(int x, int y, const char *text);
void flip(); static void flip();
void clear(Display screen, uint32_t color); static void clear(OSScreenID screen, uint32_t color);
void drawRect(Display screen, int x1, int y1, int x2, int y2, uint32_t color); static void drawRect(OSScreenID screen, int x1, int y1, int x2, int y2, uint32_t color);
void fillRect(Display screen, int x1, int y1, int x2, int y2, uint32_t color); static void fillRect(OSScreenID screen, int x1, int y1, int x2, int y2, uint32_t color);
void drawText(Display screen, int x, int y, const char *text); static void drawText(OSScreenID screen, int x, int y, const char *text);
void flip(Display screen); static void flip(OSScreenID screen);
private: private:
void *screenBuffer; void *screenBuffer;
int convx(int x); static int convx(int x);
int convy(int y); static int convy(int y);
}; };

View File

@ -1,13 +1,15 @@
#include "cafe/nsysnet.h"
#include "socket.h" #include "socket.h"
#include "logger.h"
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
Socket::Socket() : sock(-1) {} Socket::Socket() : sock(-1) {}
Socket::~Socket() { Socket::~Socket() {
if (sock >= 0) { if (sock >= 0) {
socketclose(sock); ::shutdown(sock, SHUT_RDWR);
::close(sock);
} }
} }
@ -22,14 +24,13 @@ bool Socket::init(Type type) {
bool Socket::close() { bool Socket::close() {
if (sock >= 0) { if (sock >= 0) {
int result = socketclose(sock); int result = ::close(sock);
sock = -1; sock = -1;
return result == 0; return result == 0;
} }
return true; return true;
} }
bool Client::sendall(const void *data, size_t length) { bool Client::sendall(const void *data, size_t length) {
size_t sent = 0; size_t sent = 0;
while (sent < length) { while (sent < length) {
@ -60,6 +61,12 @@ bool Client::recvall(void *data, size_t length) {
return true; return true;
} }
struct sockaddr_kinnay {
uint16_t family;
uint16_t port;
uint32_t addr;
char zero[8];
};
bool Server::bind(int port) { bool Server::bind(int port) {
uint32_t reuseaddr = 1; uint32_t reuseaddr = 1;
@ -69,28 +76,42 @@ bool Server::bind(int port) {
return false; return false;
} }
sockaddr serverAddr = {0};
/*
struct sockaddr_in bindAddress;
memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET;
bindAddress.sin_port = htons(port);
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
result = ::bind(sock, (struct sockaddr *) &bindAddress, 16);*/
sockaddr_kinnay serverAddr = {0};
serverAddr.family = AF_INET; serverAddr.family = AF_INET;
serverAddr.port = port; serverAddr.port = port;
serverAddr.addr = 0; serverAddr.addr = 0;
result = ::bind(sock, &serverAddr, 16); result = ::bind(sock, (const struct sockaddr *) &serverAddr, 16);
if (result < 0) { if (result < 0) {
DEBUG_FUNCTION_LINE("Bind was not successful");
close(); close();
return false; return false;
} }
DEBUG_FUNCTION_LINE("Bind was successful");
return true; return true;
} }
bool Server::accept(Client *client) { bool Server::accept(Client *client) {
int result = listen(sock, 1); int result = listen(sock, 1);
if (result < 0) { if (result < 0) {
DEBUG_FUNCTION_LINE("listen failed");
close(); close();
return false; return false;
} }
int fd = ::accept(sock, 0, 0); int fd = ::accept(sock, 0, 0);
if (fd < 0) { if (fd < 0) {
DEBUG_FUNCTION_LINE("accept failed");
close(); close();
return false; return false;
} }

View File

@ -5,10 +5,8 @@
class Socket { class Socket {
public: public:
enum Type { enum Type { TCP,
TCP, UDP };
UDP
};
Socket(); Socket();
~Socket(); ~Socket();