Running on gamecube kinda works now

This commit is contained in:
UnknownShadow200 2023-06-03 16:55:46 +10:00
parent 54e1e47ada
commit 230611f736
5 changed files with 96 additions and 32 deletions

View File

@ -140,6 +140,10 @@ psp:
$(MAKE) ClassiCube.elf PLAT=psp $(MAKE) ClassiCube.elf PLAT=psp
3ds: 3ds:
$(MAKE) -f Makefile_3DS PLAT=3ds $(MAKE) -f Makefile_3DS PLAT=3ds
wii:
$(MAKE) -f Makefile_wii PLAT=wii
gamecube:
$(MAKE) -f Makefile_gamecube PLAT=gamecube
clean: clean:
$(DEL) $(OBJECTS) $(DEL) $(OBJECTS)

View File

@ -4,36 +4,43 @@ endif
include $(DEVKITARM)/3ds_rules include $(DEVKITARM)/3ds_rules
#---------------------------------------------------------------------------------
# configurable options
#---------------------------------------------------------------------------------
APP_ICON := $(CURDIR)"/../misc/CC_48x48.png" APP_ICON := $(CURDIR)"/../misc/CC_48x48.png"
APP_TITLE := ClassiCube APP_TITLE := ClassiCube
APP_DESCRIPTION := Simple block building sandbox APP_DESCRIPTION := Simple block building sandbox
APP_AUTHOR := UnknownShadow200 APP_AUTHOR := UnknownShadow200
TARGET := ClassiCube-3ds
#---------------------------------------------------------------------------------
# compilation options
#---------------------------------------------------------------------------------
CFILES := $(wildcard *.c) CFILES := $(wildcard *.c)
SFILES := $(wildcard *.s) SFILES := $(wildcard *.s)
PICAFILES := $(wildcard *.v.pica) PICAFILES := $(wildcard *.v.pica)
LIBS := -lcitro3d -lctru -lm
export LD := $(CC) export LD := $(CC)
OFILES_SOURCES := $(CFILES:.c=.o) $(SFILES:.s=.o)
OFILES_SHADERS := $(PICAFILES:.v.pica=.shbin.o)
DEPSDIR := $(CURDIR)/build DEPSDIR := $(CURDIR)/build
OFILES_SOURCES := $(CFILES:.c=.o) $(SFILES:.s=.o)
OFILES_SHADERS := $(PICAFILES:.v.pica=.shbin.o)
OFILES := $(OFILES_SHADERS) $(OFILES_SOURCES) OFILES := $(OFILES_SHADERS) $(OFILES_SOURCES)
INCLUDE := $(foreach dir,$(CTRULIB),-I$(dir)/include) INCLUDE := $(foreach dir,$(CTRULIB),-I$(dir)/include)
LIBPATHS := $(foreach dir,$(CTRULIB),-L$(dir)/lib) LIBPATHS := $(foreach dir,$(CTRULIB),-L$(dir)/lib)
_3DSXDEPS := $(if $(NO_SMDH),,$(CURDIR)/ClassiCube.smdh) _3DSXDEPS := $(if $(NO_SMDH),,$(CURDIR)/$(TARGET).smdh)
ifeq ($(strip $(NO_SMDH)),) ifeq ($(strip $(NO_SMDH)),)
export _3DSXFLAGS += --smdh=$(CURDIR)/ClassiCube.smdh export _3DSXFLAGS += --smdh=$(CURDIR)/$(TARGET).smdh
endif endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # code generation options
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
@ -43,19 +50,17 @@ CFLAGS := -g -Wall -O2 -mword-relocations -ffunction-sections \
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lcitro3d -lctru -lm
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
default: $(DEPSDIR) ClassiCube.3dsx default: $(DEPSDIR) $(TARGET).3dsx
clean: clean:
@rm $(OFILES) ClassiCube.3dsx ClassiCube.smdh ClassiCube.elf @rm $(OFILES) $(TARGET).3dsx $(TARGET).smdh $(TARGET).elf
ClassiCube.elf : $(OFILES) $(TARGET).elf : $(OFILES)
ClassiCube.3dsx : ClassiCube.elf $(_3DSXDEPS) $(TARGET).3dsx : $(TARGET).elf $(_3DSXDEPS)
Graphics_3DS.o : $(OFILES_SHADERS) Graphics_3DS.o : $(OFILES_SHADERS)

View File

@ -57,9 +57,22 @@ void Mem_Free(void* mem) {
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Logging/Time-------------------------------------------------------* *------------------------------------------------------Logging/Time-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#include <stdio.h>
// dolphin recognises this function name (if loaded as .elf), and will patch it
// to also log the message to dolphin's console at OSREPORT-HLE log level
void CC_NOINLINE __write_console(int fd, const char* msg, int len) {
write(STDOUT_FILENO, msg, len); // this can be intercepted by libogc debug console
}
void Platform_Log(const char* msg, int len) { void Platform_Log(const char* msg, int len) {
write(STDOUT_FILENO, msg, len); char buffer[256];
write(STDOUT_FILENO, "\n", 1); cc_string str = String_Init(buffer, 0, 254); // 2 characters (\n and \0)
String_AppendAll(&str, msg, len);
buffer[str.length + 0] = '\n';
buffer[str.length + 1] = '\0'; // needed to make Dolphin logger happy
__write_console(0, buffer, str.length + 1); // +1 for '\n'
// TODO: Just use printf("%s", somehow ???
} }
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000)) #define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
@ -382,6 +395,7 @@ union SocketAddress {
}; };
static int ParseHost(union SocketAddress* addr, const char* host) { static int ParseHost(union SocketAddress* addr, const char* host) {
#ifdef HW_RVL
struct hostent* res = net_gethostbyname(host); struct hostent* res = net_gethostbyname(host);
if (!res || res->h_addrtype != AF_INET) return false; if (!res || res->h_addrtype != AF_INET) return false;
@ -390,6 +404,10 @@ static int ParseHost(union SocketAddress* addr, const char* host) {
addr->v4.sin_addr = *(struct in_addr*)res->h_addr_list[0]; addr->v4.sin_addr = *(struct in_addr*)res->h_addr_list[0];
return true; return true;
#else
// DNS resolution not implemented in gamecube libbba
return false;
#endif
} }
static int ParseAddress(union SocketAddress* addr, const cc_string* address) { static int ParseAddress(union SocketAddress* addr, const cc_string* address) {
@ -407,7 +425,6 @@ int Socket_ValidAddress(const cc_string* address) {
cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bool nonblocking) { cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bool nonblocking) {
union SocketAddress addr; union SocketAddress addr;
cc_result res;
*s = -1; *s = -1;
if (!ParseAddress(&addr, address)) return ERR_INVALID_ARGUMENT; if (!ParseAddress(&addr, address)) return ERR_INVALID_ARGUMENT;
@ -423,20 +440,22 @@ cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bo
addr.v4.sin_family = AF_INET; addr.v4.sin_family = AF_INET;
addr.v4.sin_port = htons(port); addr.v4.sin_port = htons(port);
res = net_connect(*s, &addr.raw, sizeof(addr.v4)); int res = net_connect(*s, &addr.raw, sizeof(addr.v4));
return res == -1 ? errno : 0; return res < 0 ? res : 0;
} }
cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) { cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
int recvCount = net_recv(s, data, count, 0); int res = net_recv(s, data, count, 0);
if (recvCount != -1) { *modified = recvCount; return 0; } if (res < 0) { *modified = 0; return res; }
*modified = 0; return errno;
*modified = res; return 0;
} }
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) { cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
int sentCount = net_send(s, data, count, 0); int res = net_send(s, data, count, 0);
if (sentCount != -1) { *modified = sentCount; return 0; } if (res < 0) { *modified = 0; return res; }
*modified = 0; return errno;
*modified = res; return 0;
} }
void Socket_Close(cc_socket s) { void Socket_Close(cc_socket s) {
@ -444,6 +463,8 @@ void Socket_Close(cc_socket s) {
net_close(s); net_close(s);
} }
#ifdef HW_RVL
// libogc only implements net_poll for wii currently
static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) { static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) {
struct pollsd pfd; struct pollsd pfd;
int flags; int flags;
@ -452,11 +473,28 @@ static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) {
pfd.events = mode == SOCKET_POLL_READ ? POLLIN : POLLOUT; pfd.events = mode == SOCKET_POLL_READ ? POLLIN : POLLOUT;
if (net_poll(&pfd, 1, 0) == -1) { *success = false; return errno; } if (net_poll(&pfd, 1, 0) == -1) { *success = false; return errno; }
/* to match select, closed socket still counts as readable */ // to match select, closed socket still counts as readable
flags = mode == SOCKET_POLL_READ ? (POLLIN | POLLHUP) : POLLOUT; int flags = mode == SOCKET_POLL_READ ? (POLLIN | POLLHUP) : POLLOUT;
*success = (pfd.revents & flags) != 0; *success = (pfd.revents & flags) != 0;
return 0; return 0;
} }
#else
// libogc only implements net_select for gamecube currently
static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) {
fd_set set;
struct timeval time = { 0 };
int res; // number of 'ready' sockets
FD_ZERO(&set);
FD_SET(s, &set);
if (mode == SOCKET_POLL_READ) {
res = net_select(s + 1, &set, NULL, NULL, &time);
} else {
res = net_select(s + 1, NULL, &set, NULL, &time);
}
if (res < 0) { *success = false; return res; }
*success = FD_ISSET(s, &set) != 0; return 0;
}
#endif
cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) { cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) {
return Socket_Poll(s, SOCKET_POLL_READ, readable); return Socket_Poll(s, SOCKET_POLL_READ, readable);
@ -474,6 +512,23 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
net_getsockopt(s, SOL_SOCKET, SO_ERROR, &res, resultSize); net_getsockopt(s, SOL_SOCKET, SO_ERROR, &res, resultSize);
return res; return res;
} }
static void InitSockets(void) {
#ifdef HW_RVL
net_init();
#else
// https://github.com/devkitPro/wii-examples/blob/master/devices/network/sockettest/source/sockettest.c
char localip[16] = {0};
char gateway[16] = {0};
char netmask[16] = {0};
int ret = if_config(localip, netmask, gateway, TRUE, 20);
if (ret >= 0) {
Platform_Log3("Network ip: %c, gw: %c, mask %c", localip, gateway, netmask);
} else {
Platform_Log1("Network setup failed: %i", &ret);
}
#endif
}
/*########################################################################################################################* /*########################################################################################################################*
@ -539,7 +594,7 @@ void Platform_Init(void) {
fat_available = fatInitDefault(); fat_available = fatInitDefault();
if (fat_available) mkdir("sd:/ClassiCube", 0); // create root 'ClassiCube' directory if (fat_available) mkdir("sd:/ClassiCube", 0); // create root 'ClassiCube' directory
net_init(); InitSockets();
} }
void Platform_Free(void) { } void Platform_Free(void) { }

View File

@ -714,7 +714,7 @@ int SysFont_TextWidth(struct DrawTextArgs* args) {
void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) { void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) {
interop_SysTextDraw(args, bmp, x, y, shadow); interop_SysTextDraw(args, bmp, x, y, shadow);
} }
#elif defined CC_BUILD_PSP #elif defined CC_BUILD_PSP || defined CC_BUILD_GCWII
void SysFonts_Register(const cc_string* path) { } void SysFonts_Register(const cc_string* path) { }
const cc_string* SysFonts_UNSAFE_GetDefault(void) { return &String_Empty; } const cc_string* SysFonts_UNSAFE_GetDefault(void) { return &String_Empty; }

View File

@ -261,7 +261,7 @@ CC_NOINLINE void TextGroupWidget_RedrawAll(struct TextGroupWidget* w);
/* Typically only called in response to the ChatEvents.ColCodeChanged event. */ /* Typically only called in response to the ChatEvents.ColCodeChanged event. */
CC_NOINLINE void TextGroupWidget_RedrawAllWithCol(struct TextGroupWidget* w, char col); CC_NOINLINE void TextGroupWidget_RedrawAllWithCol(struct TextGroupWidget* w, char col);
/* Gets the text for the i'th line. */ /* Gets the text for the i'th line. */
static cc_string TextGroupWidget_UNSAFE_Get(struct TextGroupWidget* w, int i) { return w->GetLine(i); } static CC_INLINE cc_string TextGroupWidget_UNSAFE_Get(struct TextGroupWidget* w, int i) { return w->GetLine(i); }
typedef void (*SpecialInputAppendFunc)(void* userData, char c); typedef void (*SpecialInputAppendFunc)(void* userData, char c);