mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 09:06:55 -04:00
Running on gamecube kinda works now
This commit is contained in:
parent
54e1e47ada
commit
230611f736
@ -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)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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) { }
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user