mirror of https://github.com/ClassiCube/ClassiCube
GameCube: Migrate to libogc2
This commit is contained in:
parent
45d6bcb2a7
commit
29ea018a2e
|
|
@ -0,0 +1,52 @@
|
||||||
|
name: Build latest (GameCube)
|
||||||
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.ref }}-gc
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
timeout-minutes: 10
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/extremscorner/libogc2:latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Compile GameCube build
|
||||||
|
id: compile
|
||||||
|
run: |
|
||||||
|
make gamecube
|
||||||
|
|
||||||
|
|
||||||
|
- uses: ./.github/actions/upload_build
|
||||||
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
|
with:
|
||||||
|
SOURCE_FILE: 'ClassiCube-gc.dol'
|
||||||
|
DEST_NAME: 'ClassiCube-gc.dol'
|
||||||
|
|
||||||
|
- uses: ./.github/actions/upload_build
|
||||||
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
|
with:
|
||||||
|
SOURCE_FILE: 'ClassiCube-gc.elf'
|
||||||
|
DEST_NAME: 'ClassiCube-gc.elf'
|
||||||
|
|
||||||
|
|
||||||
|
- uses: ./.github/actions/notify_success
|
||||||
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
|
with:
|
||||||
|
DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
|
||||||
|
WORKFLOW_NAME: 'gc'
|
||||||
|
|
||||||
|
|
||||||
|
- uses: ./.github/actions/notify_failure
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
NOTIFY_MESSAGE: 'Failed to produce GameCube build'
|
||||||
|
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: Build latest (Wii/GameCube)
|
name: Build latest (Wii)
|
||||||
# trigger via either push to selected branches or on manual run
|
# trigger via either push to selected branches or on manual run
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -8,7 +8,7 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-wiigc
|
group: ${{ github.ref }}-wii
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
@ -19,11 +19,10 @@ jobs:
|
||||||
image: devkitpro/devkitppc:latest
|
image: devkitpro/devkitppc:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Compile Wii and GameCube build
|
- name: Compile Wii build
|
||||||
id: compile
|
id: compile
|
||||||
run: |
|
run: |
|
||||||
make wii
|
make wii
|
||||||
make gamecube
|
|
||||||
|
|
||||||
- name: Create Wii homebrew
|
- name: Create Wii homebrew
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -39,24 +38,12 @@ jobs:
|
||||||
SOURCE_FILE: 'ClassiCube-wii.dol'
|
SOURCE_FILE: 'ClassiCube-wii.dol'
|
||||||
DEST_NAME: 'ClassiCube-wii.dol'
|
DEST_NAME: 'ClassiCube-wii.dol'
|
||||||
|
|
||||||
- uses: ./.github/actions/upload_build
|
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
|
||||||
with:
|
|
||||||
SOURCE_FILE: 'ClassiCube-gc.dol'
|
|
||||||
DEST_NAME: 'ClassiCube-gc.dol'
|
|
||||||
|
|
||||||
- uses: ./.github/actions/upload_build
|
- uses: ./.github/actions/upload_build
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
with:
|
with:
|
||||||
SOURCE_FILE: 'ClassiCube-wii.elf'
|
SOURCE_FILE: 'ClassiCube-wii.elf'
|
||||||
DEST_NAME: 'ClassiCube-wii.elf'
|
DEST_NAME: 'ClassiCube-wii.elf'
|
||||||
|
|
||||||
- uses: ./.github/actions/upload_build
|
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
|
||||||
with:
|
|
||||||
SOURCE_FILE: 'ClassiCube-gc.elf'
|
|
||||||
DEST_NAME: 'ClassiCube-gc.elf'
|
|
||||||
|
|
||||||
- uses: ./.github/actions/upload_build
|
- uses: ./.github/actions/upload_build
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
with:
|
with:
|
||||||
|
|
@ -68,11 +55,11 @@ jobs:
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
with:
|
with:
|
||||||
DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
|
DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
|
||||||
WORKFLOW_NAME: 'wiigc'
|
WORKFLOW_NAME: 'wii'
|
||||||
|
|
||||||
|
|
||||||
- uses: ./.github/actions/notify_failure
|
- uses: ./.github/actions/notify_failure
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
NOTIFY_MESSAGE: 'Failed to produce Wii/Gamecube build'
|
NOTIFY_MESSAGE: 'Failed to produce Wii build'
|
||||||
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
||||||
|
|
@ -32,10 +32,10 @@ DEPFILES := $(OBJS:%.o=%.d)
|
||||||
# Code generation
|
# Code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
MACHDEP = -DGEKKO -mogc -mcpu=750 -meabi -mhard-float
|
MACHDEP = -DGEKKO -mogc -mcpu=750 -meabi -msdata=sysv -mhard-float
|
||||||
CFLAGS = -g -O2 -Wall $(MACHDEP) -I$(DEVKITPRO)/libogc/include -DPLAT_GAMECUBE
|
CFLAGS = -g -O2 -Wall $(MACHDEP) -I$(DEVKITPRO)/libogc2/gamecube/include -DPLAT_GAMECUBE
|
||||||
|
|
||||||
LDFLAGS = -g $(MACHDEP) -L$(DEVKITPRO)/libogc/lib/cube
|
LDFLAGS = -g $(MACHDEP) -L$(DEVKITPRO)/libogc2/gamecube/lib
|
||||||
# Additional libraries to link against
|
# Additional libraries to link against
|
||||||
LIBS = -lasnd -lbba -lfat -logc -lm
|
LIBS = -lasnd -lbba -lfat -logc -lm
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,9 +247,9 @@ Run `make wii`. You'll need [libogc](https://github.com/devkitPro/libogc)
|
||||||
|
|
||||||
#### GameCube
|
#### GameCube
|
||||||
|
|
||||||
Run `make gamecube`. You'll need [libogc](https://github.com/devkitPro/libogc)
|
Run `make gamecube`. You'll need [libogc2](https://github.com/extremscorner/libogc2)
|
||||||
|
|
||||||
**NOTE: It is highly recommended that you install the precompiled devkitpro packages from [here](https://devkitpro.org/wiki/Getting_Started) - you need the `gamecube-dev` group)**
|
**NOTE: It is highly recommended that you install the precompiled libogc2 packages from [here](https://github.com/extremscorner/pacman-packages#readme) - you need the `gamecube-dev` group)**
|
||||||
|
|
||||||
#### Nintendo DS/DSi
|
#### Nintendo DS/DSi
|
||||||
|
|
||||||
|
|
@ -454,8 +454,9 @@ Further information (e.g. style) for ClassiCube's source code can be found in th
|
||||||
* [libctru](https://github.com/devkitPro/libctru) - Backend for 3DS
|
* [libctru](https://github.com/devkitPro/libctru) - Backend for 3DS
|
||||||
* [citro3D](https://github.com/devkitPro/citro3d) - Rendering backend for 3DS
|
* [citro3D](https://github.com/devkitPro/citro3d) - Rendering backend for 3DS
|
||||||
* [Citra](https://github.com/citra-emu/citra) - Emulator used to test 3DS port
|
* [Citra](https://github.com/citra-emu/citra) - Emulator used to test 3DS port
|
||||||
* [libogc](https://github.com/devkitPro/libogc) - Backend for Wii and GameCube
|
* [libogc](https://github.com/devkitPro/libogc) - Backend for Wii
|
||||||
* [libfat](https://github.com/devkitPro/libfat) - Filesystem backend for Wii/GC
|
* [libogc2](https://github.com/extremscorner/libogc2) - Backend for GameCube
|
||||||
|
* [libdvm](https://github.com/devkitPro/libdvm) - Filesystem backend for Wii/GC
|
||||||
* [Dolphin](https://github.com/dolphin-emu/dolphin) - Emulator used to test Wii/GC port
|
* [Dolphin](https://github.com/dolphin-emu/dolphin) - Emulator used to test Wii/GC port
|
||||||
* [libdragon](https://github.com/DragonMinded/libdragon) - Backend for Nintendo 64
|
* [libdragon](https://github.com/DragonMinded/libdragon) - Backend for Nintendo 64
|
||||||
* [ares](https://github.com/ares-emulator/ares) - Emulator used to test Nintendo 64 port
|
* [ares](https://github.com/ares-emulator/ares) - Emulator used to test Nintendo 64 port
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ void MusicCallback(s32 voice) {
|
||||||
cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
|
cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
|
||||||
ctx->chanID = -1;
|
ctx->chanID = -1;
|
||||||
ctx->count = buffers;
|
ctx->count = buffers;
|
||||||
ctx->volume = 255;
|
ctx->volume = MAX_VOLUME;
|
||||||
ctx->bufHead = 0;
|
ctx->bufHead = 0;
|
||||||
ctx->makeAvailable = false;
|
ctx->makeAvailable = false;
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio_SetVolume(struct AudioContext* ctx, int volume) {
|
void Audio_SetVolume(struct AudioContext* ctx, int volume) {
|
||||||
ctx->volume = (volume / 100.0f) * 255;
|
ctx->volume = (volume / 100.0f) * MAX_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
|
cc_result Audio_QueueChunk(struct AudioContext* ctx, struct AudioChunk* chunk) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
#ifdef HW_RVL
|
||||||
static void LogOverEXI(char* msg, int len) {
|
static void LogOverEXI(char* msg, int len) {
|
||||||
u32 cmd = 0x80000000 | (0x800400 << 6); // write flag, UART base address
|
u32 cmd = 0x80000000 | (0x800400 << 6); // write flag, UART base address
|
||||||
|
|
||||||
|
|
@ -27,13 +28,16 @@ void Platform_Log(const char* msg, int len) {
|
||||||
|
|
||||||
LogOverEXI(tmp, len + 1);
|
LogOverEXI(tmp, len + 1);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
#define GCWII_EPOCH_ADJUST 946684800ULL // GameCube/Wii time epoch is year 2000, not 1970
|
void Platform_Log(const char* msg, int len) {
|
||||||
|
SYS_Report("%.*s\n", len, msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TimeMS DateTime_CurrentUTC(void) {
|
TimeMS DateTime_CurrentUTC(void) {
|
||||||
u64 raw = gettime();
|
struct timeval cur;
|
||||||
u64 secs = ticks_to_secs(raw);
|
gettimeofday(&cur, NULL);
|
||||||
return secs + UNIX_EPOCH_SECONDS + GCWII_EPOCH_ADJUST;
|
return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||||
|
|
@ -51,7 +55,11 @@ void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_uint64 Stopwatch_Measure(void) {
|
cc_uint64 Stopwatch_Measure(void) {
|
||||||
return gettime();
|
#ifdef HW_RVL
|
||||||
|
return SYS_Time();
|
||||||
|
#else
|
||||||
|
return __SYS_GetSystemTime();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||||
|
|
@ -123,12 +131,15 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall
|
||||||
DIR* dirPtr = opendir(str.buffer);
|
DIR* dirPtr = opendir(str.buffer);
|
||||||
if (!dirPtr) return errno;
|
if (!dirPtr) return errno;
|
||||||
|
|
||||||
// POSIX docs: "When the end of the directory is encountered, a null pointer is returned and errno is not changed."
|
|
||||||
// errno is sometimes leftover from previous calls, so always reset it before readdir gets called
|
|
||||||
errno = 0;
|
|
||||||
String_InitArray(path, pathBuffer);
|
String_InitArray(path, pathBuffer);
|
||||||
|
|
||||||
while ((entry = readdir(dirPtr))) {
|
do {
|
||||||
|
// POSIX docs: "When the end of the directory is encountered, a null pointer is returned and errno is not changed."
|
||||||
|
// errno is sometimes leftover from previous calls, so always reset it before readdir gets called
|
||||||
|
errno = 0;
|
||||||
|
entry = readdir(dirPtr);
|
||||||
|
if (!entry) continue;
|
||||||
|
|
||||||
path.length = 0;
|
path.length = 0;
|
||||||
String_Format1(&path, "%s/", dirPath);
|
String_Format1(&path, "%s/", dirPath);
|
||||||
|
|
||||||
|
|
@ -143,8 +154,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall
|
||||||
// TODO: fallback to stat when this fails
|
// TODO: fallback to stat when this fails
|
||||||
|
|
||||||
callback(&path, obj, is_dir);
|
callback(&path, obj, is_dir);
|
||||||
errno = 0;
|
} while (entry || errno == EOVERFLOW);
|
||||||
}
|
|
||||||
|
|
||||||
res = errno; // return code from readdir
|
res = errno; // return code from readdir
|
||||||
closedir(dirPtr);
|
closedir(dirPtr);
|
||||||
|
|
@ -216,13 +226,16 @@ void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char*
|
||||||
lwp_t* thread = (lwp_t*)Mem_Alloc(1, sizeof(lwp_t), "thread");
|
lwp_t* thread = (lwp_t*)Mem_Alloc(1, sizeof(lwp_t), "thread");
|
||||||
*handle = thread;
|
*handle = thread;
|
||||||
|
|
||||||
int res = LWP_CreateThread(thread, ExecThread, (void*)func, NULL, stackSize, 80);
|
int res = LWP_CreateThread(thread, ExecThread, (void*)func, NULL, stackSize, 64);
|
||||||
if (res) Process_Abort2(res, "Creating thread");
|
if (res) Process_Abort2(res, "Creating thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread_Detach(void* handle) {
|
void Thread_Detach(void* handle) {
|
||||||
// TODO: Leaks return value of thread ???
|
// TODO: Leaks return value of thread ???
|
||||||
lwp_t* ptr = (lwp_t*)handle;
|
lwp_t* ptr = (lwp_t*)handle;
|
||||||
|
#ifndef HW_RVL
|
||||||
|
LWP_DetachThread(*ptr);
|
||||||
|
#endif
|
||||||
Mem_Free(ptr);
|
Mem_Free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,6 +272,7 @@ void Mutex_Unlock(void* handle) {
|
||||||
if (res) Process_Abort2(res, "Unlocking mutex");
|
if (res) Process_Abort2(res, "Unlocking mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
// should really use a semaphore with max 1.. too bad no 'TimedWait' though
|
// should really use a semaphore with max 1.. too bad no 'TimedWait' though
|
||||||
struct WaitData {
|
struct WaitData {
|
||||||
cond_t cond;
|
cond_t cond;
|
||||||
|
|
@ -320,8 +334,8 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
ts.tv_sec = milliseconds / 1000;
|
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
||||||
ts.tv_nsec = milliseconds % 1000;
|
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
||||||
|
|
||||||
Mutex_Lock(&ptr->mutex);
|
Mutex_Lock(&ptr->mutex);
|
||||||
if (!ptr->signalled) {
|
if (!ptr->signalled) {
|
||||||
|
|
@ -331,6 +345,45 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
ptr->signalled = false;
|
ptr->signalled = false;
|
||||||
Mutex_Unlock(&ptr->mutex);
|
Mutex_Unlock(&ptr->mutex);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void* Waitable_Create(const char* name) {
|
||||||
|
sem_t* ptr = (sem_t*)Mem_Alloc(1, sizeof(sem_t), "waitable");
|
||||||
|
int res = LWP_SemInit(ptr, 0, 1);
|
||||||
|
if (res) Process_Abort2(res, "Creating waitable");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Free(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemDestroy(*ptr);
|
||||||
|
if (res) Process_Abort2(res, "Destroying waitable");
|
||||||
|
Mem_Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Signal(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemPost(*ptr);
|
||||||
|
if (res && res != EOVERFLOW) Process_Abort2(res, "Signalling event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_Wait(void* handle) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
int res = LWP_SemWait(*ptr);
|
||||||
|
if (res) Process_Abort2(res, "Event wait");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
|
sem_t* ptr = (sem_t*)handle;
|
||||||
|
struct timespec ts;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ts.tv_sec = milliseconds / TB_MSPERSEC;
|
||||||
|
ts.tv_nsec = (milliseconds % TB_MSPERSEC) * TB_NSPERMS;
|
||||||
|
|
||||||
|
res = LWP_SemTimedWait(*ptr, &ts);
|
||||||
|
if (res && res != ETIMEDOUT) Process_Abort2(res, "Event timed wait");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
|
|
@ -359,11 +412,11 @@ cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||||
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
struct sockaddr* raw = (struct sockaddr*)addr->data;
|
||||||
if (!net_supported) { *s = -1; return ERR_NO_NETWORKING; }
|
if (!net_supported) { *s = -1; return ERR_NO_NETWORKING; }
|
||||||
|
|
||||||
*s = net_socket(raw->sa_family, SOCK_STREAM, 0);
|
*s = net_socket(raw->sa_family, SOCK_STREAM, IPPROTO_IP);
|
||||||
if (*s < 0) return *s;
|
if (*s < 0) return *s;
|
||||||
|
|
||||||
if (nonblocking) {
|
if (nonblocking) {
|
||||||
int blocking_raw = -1; /* non-blocking mode */
|
int blocking_raw = 1; /* non-blocking mode */
|
||||||
net_ioctl(*s, FIONBIO, &blocking_raw);
|
net_ioctl(*s, FIONBIO, &blocking_raw);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@
|
||||||
#include <network.h>
|
#include <network.h>
|
||||||
#include <ogc/lwp.h>
|
#include <ogc/lwp.h>
|
||||||
#include <ogc/mutex.h>
|
#include <ogc/mutex.h>
|
||||||
#include <ogc/cond.h>
|
#include <ogc/semaphore.h>
|
||||||
#include <ogc/lwp_watchdog.h>
|
#include <ogc/system.h>
|
||||||
|
#include <ogc/timesupp.h>
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <ogc/exi.h>
|
|
||||||
|
|
||||||
const cc_result ReturnCode_FileShareViolation = 1000000000; /* TODO: not used apparently */
|
const cc_result ReturnCode_FileShareViolation = 1000000000; /* TODO: not used apparently */
|
||||||
const cc_result ReturnCode_FileNotFound = ENOENT;
|
const cc_result ReturnCode_FileNotFound = ENOENT;
|
||||||
|
|
@ -104,7 +104,7 @@ cc_result Socket_GetLastError(cc_socket s) {
|
||||||
u32 errSize = sizeof(error);
|
u32 errSize = sizeof(error);
|
||||||
|
|
||||||
/* https://stackoverflow.com/questions/29479953/so-error-value-after-successful-socket-operation */
|
/* https://stackoverflow.com/questions/29479953/so-error-value-after-successful-socket-operation */
|
||||||
net_getsockopt(s, SOL_SOCKET, SO_ERROR, &error, errSize);
|
net_getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errSize);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ static void InitSockets(void) {
|
||||||
char netmask[16] = {0};
|
char netmask[16] = {0};
|
||||||
char gateway[16] = {0};
|
char gateway[16] = {0};
|
||||||
|
|
||||||
int ret = if_config(localip, netmask, gateway, TRUE, 20);
|
int ret = if_config(localip, netmask, gateway, true);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
cc_string str; char buffer[256];
|
cc_string str; char buffer[256];
|
||||||
String_InitArray_NT(str, buffer);
|
String_InitArray_NT(str, buffer);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <ogc/lwp_watchdog.h>
|
#include <ogc/lwp_watchdog.h>
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <ogc/exi.h>
|
#include <ogc/exi.h>
|
||||||
|
#include <ogc/system.h>
|
||||||
#include <ogc/wiilaunch.h>
|
#include <ogc/wiilaunch.h>
|
||||||
|
|
||||||
const cc_result ReturnCode_FileShareViolation = 1000000000; /* TODO: not used apparently */
|
const cc_result ReturnCode_FileShareViolation = 1000000000; /* TODO: not used apparently */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue