diff --git a/source/text.cpp b/source/draw.cpp similarity index 60% rename from source/text.cpp rename to source/draw.cpp index 1dcf8aa..0d0cdce 100644 --- a/source/text.cpp +++ b/source/draw.cpp @@ -1,13 +1,20 @@ -#include -#include -#include +#include "draw.h" + +#include +#include +#include + #include <3ds.h> -#include "text.h" #include "font.h" -//this code is not meant to be readable -int drawCharacter(u8* fb, font_s* font, char c, s16 x, s16 y, u16 w, u16 h) +Rect GetScreenSize(gfxScreen_t screen) +{ + return { (screen == GFX_TOP) ? 400 : 320, 240 }; +} + +// This code is not meant to be readable -- Smea +int DrawCharacter(u8* fb, font_s* font, char c, s16 x, s16 y, u16 w, u16 h) { Glyph* cd = &font->desc[(int)c]; @@ -52,7 +59,7 @@ int drawCharacter(u8* fb, font_s* font, char c, s16 x, s16 y, u16 w, u16 h) return cd->xa; } -void drawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h) +void DrawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h) { if (!f || !fb) return; @@ -60,7 +67,7 @@ void drawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, int dx = 0, dy = 0; for (const char& c : str) { - dx += drawCharacter(fb, f, c, x + dx, y + dy, w, h); + dx += DrawCharacter(fb, f, c, x + dx, y + dy, w, h); if (c == '\n') { dx = 0; dy -= f->height; @@ -68,7 +75,7 @@ void drawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, } } -void gfxDrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* font, const std::string& str, s16 x, s16 y) +void DrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* font, const std::string& str, s16 x, s16 y) { if (!font) font = &fontDefault; @@ -76,5 +83,16 @@ void gfxDrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* font, const std:: u16 fbWidth, fbHeight; u8* fbAdr = gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); - drawString(fbAdr, font, str, y, x, fbHeight, fbWidth); + DrawString(fbAdr, font, str, y, x, fbHeight, fbWidth); +} + +void FillScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b) +{ + Rect screen_size = GetScreenSize(screen); + u8* fb_addr = gfxGetFramebuffer(screen, GFX_LEFT, nullptr, nullptr); + for (int i = 0; i < screen_size.w * screen_size.h * 3; i += 3) { + fb_addr[i] = bg_b; + fb_addr[i+1] = bg_g; + fb_addr[i+2] = bg_r; + } } diff --git a/source/draw.h b/source/draw.h new file mode 100644 index 0000000..c2b78ad --- /dev/null +++ b/source/draw.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include <3ds.h> + +#include "font.h" + +struct Rect { + int w, h; +}; + +Rect GetScreenSize(gfxScreen_t screen); + +int DrawCharacter(u8* fb, font_s* f, char c, s16 x, s16 y, u16 w, u16 h); +void DrawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h); +void DrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* f, const std::string& str, s16 x, s16 y); +void FillScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b); diff --git a/source/main.cpp b/source/main.cpp index 91d8edf..b39d285 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -19,18 +19,19 @@ int main(int argc, char** argv) gfxInit(); gfxSet3D(false); fsInit(); + InitOutput(); ClearScreens(); Print(GFX_TOP, "Press A to begin...\n"); while (aptMainLoop()) { - DrawFrames(); + DrawBuffers(); hidScanInput(); if (hidKeysDown() & KEY_START) { break; } else if (hidKeysDown() & KEY_A) { - ClearScreen(GFX_TOP); + ClearScreens(); if (test_counter < (sizeof(tests) / sizeof(tests[0]))) { tests[test_counter](); @@ -39,7 +40,7 @@ int main(int argc, char** argv) break; } - Print(GFX_TOP, "\n"); + Log(GFX_TOP, "\n"); Print(GFX_TOP, "Press A to continue...\n"); } @@ -47,6 +48,8 @@ int main(int argc, char** argv) } ClearScreens(); + + DeinitOutput(); fsExit(); gfxExit(); hidExit(); diff --git a/source/output.cpp b/source/output.cpp index f6ecb43..aa9c937 100644 --- a/source/output.cpp +++ b/source/output.cpp @@ -1,12 +1,15 @@ +#include <3ds.h> + #include "output.h" #include +#include -#include <3ds.h> - -#include "text.h" +#include "draw.h" #include "common/string_funcs.h" +static FILE* log_file; + static std::string buffer_top; static std::string buffer_bottom; @@ -19,51 +22,71 @@ static std::string& GetTextBuffer(gfxScreen_t screen) return buffer_top; } -static void DrawFrame(gfxScreen_t screen, char b, char g, char r) +static void DrawBuffer(gfxScreen_t screen) { - int screen_height = 240; - int screen_width = (screen == GFX_TOP) ? 400 : 320; + Rect screen_size = GetScreenSize(screen); std::string& text_buffer = GetTextBuffer(screen); - u8* fb_addr = gfxGetFramebuffer(screen, GFX_LEFT, nullptr, nullptr); - for (int i = 0; i < screen_width * screen_height * 3; i += 3) { - fb_addr[i] = b; - fb_addr[i+1] = g; - fb_addr[i+2] = r; - } - int lines = Common::CountLines(text_buffer); - while (lines > (screen_height / fontDefault.height - 3)) { + while (lines > (screen_size.h / fontDefault.height - 3)) { Common::DeleteFirstLine(&text_buffer); lines--; } - gfxDrawText(screen, GFX_LEFT, nullptr, text_buffer, screen_height - fontDefault.height * 3, 10); + DrawText(screen, GFX_LEFT, nullptr, text_buffer, screen_size.h - fontDefault.height * 3, 10); } -void DrawFrames() +void InitOutput() { - DrawFrame(GFX_TOP, 0x88, 0x66, 0x00); - DrawFrame(GFX_BOTTOM, 0x00, 0x00, 0x00); + sdmcInit(); + log_file = fopen("hwtest_log.txt", "w"); +} + +void DrawBuffers() +{ + FillScreen(GFX_TOP, 0x00, 0x66, 0x88); + DrawBuffer(GFX_TOP); + + FillScreen(GFX_BOTTOM, 0x00, 0x00, 0x00); + DrawBuffer(GFX_BOTTOM); + gfxFlushBuffers(); gfxSwapBuffers(); } +void ClearScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b) +{ + FillScreen(screen, bg_r, bg_g, bg_b); + GetTextBuffer(screen).clear(); + gfxFlushBuffers(); + gfxSwapBuffers(); +} + +void ClearScreens() +{ + ClearScreen(GFX_TOP, 0x00, 0x66, 0x88); + ClearScreen(GFX_BOTTOM, 0x00, 0x00, 0x00); +} + void Print(gfxScreen_t screen, const std::string& text) { GetTextBuffer(screen) += text; + DrawBuffers(); +} + +void Log(gfxScreen_t screen, const std::string& text) +{ + Print(screen, text); + LogToFile(text); +} + +void LogToFile(const std::string& text) +{ svcOutputDebugString(text.c_str(), text.length()); - - DrawFrames(); + fprintf(log_file, "%s", text.c_str()); } -void ClearScreen(gfxScreen_t screen) +void DeinitOutput() { - GetTextBuffer(screen).clear(); - DrawFrames(); -} - -void ClearScreens() -{ - ClearScreen(GFX_TOP); - ClearScreen(GFX_BOTTOM); + fclose(log_file); + sdmcExit(); } diff --git a/source/output.h b/source/output.h index 5219bcd..8c59056 100644 --- a/source/output.h +++ b/source/output.h @@ -1,9 +1,23 @@ #pragma once -#include <3ds.h> #include -void DrawFrames(); +#include <3ds.h> + +void InitOutput(); + +void DrawBuffers(); + +/// Prints `text` to `screen`. void Print(gfxScreen_t screen, const std::string& text); -void ClearScreen(gfxScreen_t screen); + +/// Prints `text` to `screen`, and logs it in the log file. +void Log(gfxScreen_t screen, const std::string& text); + +/// Logs `text` to the log file. +void LogToFile(const std::string& text); + +void ClearScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b); void ClearScreens(); + +void DeinitOutput(); diff --git a/source/tests/test.cpp b/source/tests/test.cpp index 4a92cab..03df339 100644 --- a/source/tests/test.cpp +++ b/source/tests/test.cpp @@ -5,7 +5,13 @@ #include "output.h" #include "common/string_funcs.h" +void SoftAssertLog(const std::string& function, int line, const std::string& condition) +{ + LogToFile(Common::FormatString("SOFTASSERT FAILURE: `%s`\n", condition.c_str())); + LogToFile(Common::FormatString(" At `%s` L%i\n", function.c_str(), line)); +} + void PrintSuccess(const std::string& group, const std::string& name, bool val) { - Print(GFX_TOP, Common::FormatString("%s: %s - %s\n", group.c_str(), name.c_str(), val ? "SUCCESS" : "FAILURE")); + Log(GFX_TOP, Common::FormatString("%s: [%s] %s\n", val ? "SUCCESS" : "FAILURE", group.c_str(), name.c_str())); } diff --git a/source/tests/test.h b/source/tests/test.h index c50c20e..e0e1080 100644 --- a/source/tests/test.h +++ b/source/tests/test.h @@ -4,8 +4,16 @@ typedef void (*TestCaller)(void); +void SoftAssertLog(const std::string& function, int line, const std::string& condition); + // If the condition fails, return false -#define SoftAssert(cond) do { if (!(cond)) { return false; } } while (0) +#define SoftAssert(cond) \ + do { \ + if (!(cond)) { \ + SoftAssertLog(__PRETTY_FUNCTION__, __LINE__, #cond); \ + return false; \ + } \ + } while (0) void PrintSuccess(const std::string& group, const std::string& name, bool val); diff --git a/source/text.h b/source/text.h deleted file mode 100644 index 719d5c3..0000000 --- a/source/text.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -#include "font.h" - -int drawCharacter(u8* fb, font_s* f, char c, s16 x, s16 y, u16 w, u16 h); -void drawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h); -void gfxDrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* f, const std::string& str, s16 x, s16 y);