Custom assert
From WiiBrew
Here is my custom assert
This code is for GX video only. note: after doing the below make sure you define USE_CUSTOM_ASSERT, i add -DUSE_CUSTOM_ASSERT in my makefile in the line with CFLAGS.
in your code define GXRModeObj *global_rmode; and set it to your rmode variable.
in assert.h there are two changes. The first is the prototype under the first extern "C"
the second is at bottom, the #ifdef USE_CUSTOM_ASSERT / #endif block
the below is my current assert.h, its found in devkitPro\devkitPPC\powerpc-gekko\include
since cassert includes assert.h you can include either one.
assert.h
/* assert.h */ #ifdef __cplusplus extern "C" { #endif void MyAssert__(const char *fn, long line); #include "_ansi.h" #undef assert #ifdef NDEBUG /* required by ANSI standard */ # define assert(__e) ((void)0) #else # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ __ASSERT_FUNC, #__e)) # ifndef __ASSERT_FUNC /* Use g++'s demangled names in C++. */ # if defined __cplusplus && defined __GNUC__ # define __ASSERT_FUNC __PRETTY_FUNCTION__ /* C99 requires the use of __func__, gcc also supports it. */ # elif defined __GNUC__ || __STDC_VERSION__ >= 199901L # define __ASSERT_FUNC __func__ /* failed to detect __func__ support. */ # else # define __ASSERT_FUNC ((char *) 0) # endif # endif /* !__ASSERT_FUNC */ #endif /* !NDEBUG */ void _EXFUN(__assert, (const char *, int, const char *) _ATTRIBUTE ((__noreturn__))); void _EXFUN(__assert_func, (const char *, int, const char *, const char *) _ATTRIBUTE ((__noreturn__))); #ifdef __cplusplus } #endif #ifdef USE_CUSTOM_ASSERT #undef assert #define assert(e) e ? (void)0 : MyAssert__(__FILE__, __LINE__); #endif
Thanks for dhewg for giving me this code. All i added was the extern "C" line.
log_console.h
/*------------------------------------------------------------- Copyright (C) 2008 dhewg This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------*/ #ifndef _LOG_CONSOLE_H_ #define _LOG_CONSOLE_H_ #include <gccore.h> #ifdef __cplusplus extern "C" { #endif void log_console_init(GXRModeObj *vmode, u16 logsize); void log_console_deinit(void); void log_console_enable_log(bool enable); void log_console_enable_video(bool enable); #ifdef __cplusplus } #endif #endif
I added everything after /* Mavakadachi */
log_console.c
/*------------------------------------------------------------- Copyright (C) 2008 dhewg This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------*/ #include <sys/iosupport.h> #include <reent.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "log_console.h" static bool gecko = false; static const devoptab_t *dot_video = NULL; static VIRetraceCallback rcb = NULL; static char **log = NULL; static u16 log_size = 0; static u16 log_next = 0; static bool log_active = true; static bool video_active = true; static int __out_write(struct _reent *r, int fd, const char *ptr, size_t len) { u16 l; if (!ptr || len <= 0) return -1; if (video_active) { dot_video->write_r(r, fd, ptr, len); } else { if (log_active) { l = (log_next + 1) % log_size; if (log[l]) free(log[l]); log[l] = strndup(ptr, len); log_next = l; } } if (gecko) usb_sendbuffer(1, ptr, len); return len; } const devoptab_t dot_out = { "stdout", // device name 0, // size of file structure NULL, // device open NULL, // device close __out_write,// device write NULL, // device read NULL, // device seek NULL, // device fstat NULL, // device stat NULL, // device link NULL, // device unlink NULL, // device chdir NULL, // device rename NULL, // device mkdir 0, // dirStateSize NULL, // device diropen_r NULL, // device dirreset_r NULL, // device dirnext_r NULL, // device dirclose_r NULL // device statvfs_r }; void log_console_init(GXRModeObj *vmode, u16 logsize) { u16 i; CON_InitEx(vmode, 20, 30, vmode->fbWidth - 40, vmode->xfbHeight - 60); rcb = VIDEO_SetPostRetraceCallback(NULL); VIDEO_SetPostRetraceCallback(rcb); gecko = usb_isgeckoalive(1); if (log_size && log) { for (i = 0; i < log_size; ++i) if (log[i]) free(log[i]); free(log); } log_size = logsize; log_next = 0; if (log_size) { log = (char **) malloc(log_size * sizeof(char *)); for (i = 0; i < log_size; ++i) log[i] = NULL; } log_active = log_size > 0; dot_video = devoptab_list[STD_OUT]; video_active = true; devoptab_list[STD_OUT] = &dot_out; devoptab_list[STD_ERR] = &dot_out; } void log_console_deinit(void) { u16 i; if (log_size && log) { for (i = 0; i < log_size; ++i) if (log[i]) free(log[i]); free(log); log = NULL; } log_size = 0; log_next = 0; devoptab_list[STD_OUT] = dot_video; devoptab_list[STD_ERR] = dot_video; VIDEO_SetPostRetraceCallback(rcb); dot_video = NULL; } void log_console_enable_log(bool enable) { if (!log_size) return; log_active = enable; } void log_console_enable_video(bool enable) { struct _reent *r = _REENT; u16 i, l; if (video_active == enable) return; video_active = enable; if (enable) VIDEO_SetPostRetraceCallback(rcb); else VIDEO_SetPostRetraceCallback(NULL); if (!enable || !log_size) return; for (i = 0; i < log_size; ++i) { l = (log_next + 1 + i) % log_size; if (log[l]) { dot_video->write_r(r, 0, log[l], strlen(log[l])); free(log[l]); log[l] = NULL; } } fflush(stdout); } /* Mavakadachi */ #include <wiiuse/wpad.h> extern GXRModeObj *global_rmode; void MyAssert__(const char *fn, long line) { log_console_init(global_rmode, 16); log_console_enable_video(1); log_console_enable_log(1); printf("Assert failed in file %s on line %d\n", fn, line); while (1) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0); VIDEO_Flush(); VIDEO_WaitVSync(); } }