Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -1,9 +1,10 @@ *.a *.bundle *.dll *.dylib +*.map *.o *.orig *.so *~ .deps Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -19,10 +19,18 @@ CPP="$OBJCPP" CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS" OBJCFLAGS="$OBJCFLAGS -Wall -fexceptions -fobjc-exceptions -funwind-tables" OBJCFLAGS="$OBJCFLAGS -fconstant-string-class=OFConstantString" + +AC_ARG_WITH(wii, + AS_HELP_STRING([--with-wii], [build for Wii])) +AS_IF([test x"$with_wii" = x"yes"], [ + OBJCFLAGS="$OBJCFLAGS -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float" + LDFLAGS="$LDFLAGS -mrvl -mcpu=750 -meabi -mhard-float" + LIBS="-lfat -lwiiuse -lbte -logc" +]) AX_CHECK_COMPILER_FLAGS(-std=gnu99, [OBJCFLAGS="$OBJCFLAGS -std=gnu99"]) case $OBJC in *clang*) ;; @@ -813,10 +821,14 @@ ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$old_OBJCFLAGS" ]) ]) + +AS_IF([test x"$with_wii" = x"yes"], [ + AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$$(basename $@).map']) +]) AS_IF([test x"$cross_compiling" = x"yes"], [ AC_SUBST(BIN_PREFIX, "$host-") case "$host" in @@ -827,10 +839,22 @@ AC_SUBST(TESTS, "tests") AC_SUBST(TEST_LAUNCHER, "$WINE") ]) ;; esac + + AS_IF([test x"$with_wii" = x"yes"], [ + dnl Keep this lowercase, as WIILOAD is a variable used by + dnl wiiload and thus likely already set by the user to something + dnl that is not the path to the binary. + AC_CHECK_PROG(wiiload, wiiload, wiiload) + + AS_IF([test x"$wiiload" != x""], [ + AC_SUBST(TESTS, "tests") + AC_SUBST(TEST_LAUNCHER, "$wiiload") + ]) + ]) ], [ AC_SUBST(TESTS, "tests") ]) BUILDSYS_INIT Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -20,10 +20,11 @@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FORWARDING_S = @FORWARDING_S@ FOUNDATION_COMPAT_M = @FOUNDATION_COMPAT_M@ INSTANCE_M = @INSTANCE_M@ LOOKUP_S = @LOOKUP_S@ +MAP_LDFLAGS = @MAP_LDFLAGS@ OFBLOCKTESTS_M = @OFBLOCKTESTS_M@ OFHTTPCLIENTTESTS_M = @OFHTTPCLIENTTESTS_M@ OFPROCESS_M = @OFPROCESS_M@ OFSTREAMOBSERVER_KQUEUE_M = @OFSTREAMOBSERVER_KQUEUE_M@ OFSTREAMOBSERVER_POLL_M = @OFSTREAMOBSERVER_POLL_M@ Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -39,10 +39,16 @@ # include #endif #ifdef HAVE_GRP_H # include #endif + +#ifdef __wii__ +# define BOOL OGC_BOOL +# include +# undef BOOL +#endif #import "OFFile.h" #import "OFString.h" #import "OFArray.h" #ifdef OF_HAVE_THREADS @@ -131,21 +137,27 @@ return -1; } @implementation OFFile -#if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) + (void)initialize { if (self != [OFFile class]) return; +#if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) if (!of_mutex_new(&mutex)) @throw [OFInitializationFailedException exceptionWithClass: self]; -} +#endif + +#ifdef __wii__ + if (!fatInitDefault()) + @throw [OFInitializationFailedException + exceptionWithClass: self]; #endif +} + (instancetype)fileWithPath: (OFString*)path mode: (OFString*)mode { return [[[self alloc] initWithPath: path @@ -286,11 +298,11 @@ if ((dir = opendir([path cStringWithEncoding: OF_STRING_ENCODING_NATIVE])) == NULL) @throw [OFOpenFileFailedException exceptionWithClass: self path: path - mode: @"r"]; + mode: @"r"]; @try { while ((dirent = readdir(dir)) != NULL) { void *pool = objc_autoreleasePoolPush(); OFString *file; Index: src/of_asprintf.m ================================================================== --- src/of_asprintf.m +++ src/of_asprintf.m @@ -195,39 +195,48 @@ ctx->length_modifier = LENGTH_MODIFIER_L; } break; case 'j': -#ifndef _WIN32 - if (!append_subformat(ctx, ctx->format + ctx->i, 1)) +#if defined(_WIN32) + if (!append_subformat(ctx, "I64", 3)) + return false; +#elif defined(__wii__) + if (!append_subformat(ctx, "ll", 2)) return false; #else - if (!append_subformat(ctx, "I64", 3)) + if (!append_subformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->length_modifier = LENGTH_MODIFIER_J; break; case 'z': -#ifndef _WIN32 - if (!append_subformat(ctx, ctx->format + ctx->i, 1)) +#if defined(_WIN32) + if (!append_subformat(ctx, "I", 1)) + return false; +#elif defined(__wii__) + if (!append_subformat(ctx, "l", 1)) return false; #else - if (!append_subformat(ctx, "I", 1)) + if (!append_subformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->length_modifier = LENGTH_MODIFIER_Z; break; case 't': -#ifndef _WIN32 - if (!append_subformat(ctx, ctx->format + ctx->i, 1)) +#if defined(_WIN32) + if (!append_subformat(ctx, "I", 1)) + return false; +#elif defined(__wii__) + if (!append_subformat(ctx, "l", 1)) return false; #else - if (!append_subformat(ctx, "I", 1)) + if (!append_subformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->length_modifier = LENGTH_MODIFIER_T; Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -95,6 +95,7 @@ include ../buildsys.mk CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT LIBS := -L../src -lobjfw ${LIBS} +LDFLAGS += ${MAP_LDFLAGS} LD = ${OBJC} Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -18,10 +18,11 @@ #include #import "OFString.h" #import "OFStdIOStream.h" +#import "OFFile.h" #import "OFAutoreleasePool.h" #import "TestsAppDelegate.h" #ifdef _PSP @@ -28,10 +29,24 @@ # include # include # include PSP_MODULE_INFO("ObjFW Tests", 0, 0, 0); #endif + +#ifdef __wii__ +# define BOOL OGC_BOOL +# include +# include +# undef BOOL +#endif + +enum { + NO_COLOR, + RED, + GREEN, + YELLOW +}; int main(int argc, char *argv[]) { #ifdef OF_OBJFW_RUNTIME @@ -39,11 +54,56 @@ #endif /* We need deterministic hashes for tests */ of_hash_seed = 0; +#ifdef __wii__ + GXRModeObj *rmode; + void *xfb; + + VIDEO_Init(); + WPAD_Init(); + + rmode = VIDEO_GetPreferredMode(NULL); + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(xfb); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + + VIDEO_WaitVSync(); + if (rmode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); + + CON_InitEx(rmode, 10, 20, rmode->fbWidth - 10, rmode->xfbHeight - 20); + VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK); + + @try { + return of_application_main(&argc, &argv, + [TestsAppDelegate class]); + } @catch (id e) { + TestsAppDelegate *delegate = + [[OFApplication sharedApplication] delegate]; + OFString *string = [OFString stringWithFormat: + @"\nRuntime error: Unhandled exception:\n%@\n", e]; + + [delegate outputString: string + withColor: RED]; + [delegate outputString: @"Press home button to exit!\n" + withColor: NO_COLOR]; + for (;;) { + WPAD_ScanPads(); + + if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) + [OFApplication terminateWithStatus: 1]; + + VIDEO_WaitVSync(); + } + } +#else return of_application_main(&argc, &argv, [TestsAppDelegate class]); +#endif } @implementation TestsAppDelegate - (void)outputString: (OFString*)str withColor: (int)color @@ -70,18 +130,24 @@ pspDebugScreenSetXY(0, y); pspDebugScreenPrintData([str UTF8String], [str UTF8StringLength]); #elif defined(STDOUT) switch (color) { - case 0: - [of_stdout writeString: @"\r\033[K\033[1;33m"]; - break; - case 1: - [of_stdout writeString: @"\r\033[K\033[1;32m"]; - break; - case 2: - [of_stdout writeString: @"\r\033[K\033[1;31m"]; + case NO_COLOR: + [of_stdout writeString: @"\r\033[K"]; +# ifdef __wii__ + [of_stdout writeString: @"\033[37m"]; +# endif + break; + case RED: + [of_stdout writeString: @"\r\033[K\033[31;1m"]; + break; + case GREEN: + [of_stdout writeString: @"\r\033[K\033[32;1m"]; + break; + case YELLOW: + [of_stdout writeString: @"\r\033[K\033[33;1m"]; break; } [of_stdout writeString: str]; [of_stdout writeString: @"\033[m"]; @@ -94,39 +160,55 @@ inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self outputString: [OFString stringWithFormat: @"[%@] %@: testing...", module, test] - withColor: 0]; + withColor: YELLOW]; [pool release]; } - (void)outputSuccess: (OFString*)test inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self outputString: [OFString stringWithFormat: @"[%@] %@: ok\n", module, test] - withColor: 1]; + withColor: GREEN]; [pool release]; } - (void)outputFailure: (OFString*)test inModule: (OFString*)module { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; [self outputString: [OFString stringWithFormat: @"[%@] %@: failed\n", module, test] - withColor: 2]; + withColor: RED]; [pool release]; + +#ifdef __wii__ + [self outputString: @"Press A to continue!\n" + withColor: NO_COLOR]; + for (;;) { + WPAD_ScanPads(); + + if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A) + return; + + VIDEO_WaitVSync(); + } +#endif } - (void)applicationDidFinishLaunching { #ifdef _PSP pspDebugScreenInit(); #endif +#ifdef __wii__ + [OFFile changeToDirectoryAtPath: @"/objfw-tests"]; +#endif [self objectTests]; #ifdef OF_HAVE_BLOCKS [self blockTests]; #endif @@ -162,8 +244,21 @@ [self forwardingTests]; #ifdef OF_HAVE_PROPERTIES [self propertiesTests]; #endif +#ifdef __wii__ + [self outputString: @"Press home button to exit!\n" + withColor: NO_COLOR]; + for (;;) { + WPAD_ScanPads(); + + if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) + [OFApplication terminateWithStatus: _fails]; + + VIDEO_WaitVSync(); + } +#else [OFApplication terminateWithStatus: _fails]; +#endif } @end