Merge pull request #31 from linkmauve/ctrulib-console
Remove any drawing code and move to ctrulib’s console module
This commit is contained in:
commit
951d2bed10
@ -19,31 +19,8 @@ std::string FormatString(const char* format, ...)
|
|||||||
|
|
||||||
std::string out_str(va_str);
|
std::string out_str(va_str);
|
||||||
free(va_str);
|
free(va_str);
|
||||||
|
|
||||||
return out_str;
|
return out_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CountLines(const std::string& str)
|
|
||||||
{
|
|
||||||
if (str.empty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1 + std::count_if(str.begin(), str.end(), [](char c) { return c == '\n'; });
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteFirstLine(std::string* str)
|
|
||||||
{
|
|
||||||
if (str->empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
size_t linebreak = str->find_first_of('\n');
|
|
||||||
|
|
||||||
if (linebreak == std::string::npos || linebreak + 1 > str->length()) {
|
|
||||||
*str = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*str = str->substr(linebreak + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,4 @@ namespace Common {
|
|||||||
|
|
||||||
std::string FormatString(const char* format, ...);
|
std::string FormatString(const char* format, ...);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of lines (broken by '\n') in the string
|
|
||||||
*/
|
|
||||||
int CountLines(const std::string& str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the first line (broken by '\n') from the string
|
|
||||||
*/
|
|
||||||
void DeleteFirstLine(std::string* str);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <3ds.h>
|
|
||||||
|
|
||||||
#include "font.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];
|
|
||||||
|
|
||||||
if (!cd->data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
x += cd->xo; y += font->height - cd->yo - cd->h;
|
|
||||||
|
|
||||||
if (x < 0 || x + cd->w >= w || y < -cd->h || y >= h + cd->h)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u8* charData = cd->data;
|
|
||||||
s16 cy = y, ch = cd->h, cyo = 0;
|
|
||||||
|
|
||||||
if (y < 0) {
|
|
||||||
cy = 0;
|
|
||||||
cyo = -y;
|
|
||||||
ch = cd->h-cyo;
|
|
||||||
} else if (y + ch > h) {
|
|
||||||
ch = h - y;
|
|
||||||
}
|
|
||||||
|
|
||||||
fb += (x * h + cy) * 3;
|
|
||||||
const u8 r = font->color[0];
|
|
||||||
const u8 g = font->color[1];
|
|
||||||
const u8 b = font->color[2];
|
|
||||||
|
|
||||||
for (int i = 0; i < cd->w; i++) {
|
|
||||||
charData += cyo;
|
|
||||||
for (int j = 0; j < ch; j++) {
|
|
||||||
u8 v = *(charData++);
|
|
||||||
if (v) {
|
|
||||||
fb[0] = (fb[0] * (0xFF - v) + (b * v)) >> 8;
|
|
||||||
fb[1] = (fb[1] * (0xFF - v) + (g * v)) >> 8;
|
|
||||||
fb[2] = (fb[2] * (0xFF - v) + (r * v)) >> 8;
|
|
||||||
}
|
|
||||||
fb += 3;
|
|
||||||
}
|
|
||||||
charData += (cd->h - (cyo + ch));
|
|
||||||
fb += (h - ch) * 3;
|
|
||||||
}
|
|
||||||
return cd->xa;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h)
|
|
||||||
{
|
|
||||||
if (!f || !fb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int dx = 0, dy = 0;
|
|
||||||
for (const char& c : str)
|
|
||||||
{
|
|
||||||
dx += DrawCharacter(fb, f, c, x + dx, y + dy, w, h);
|
|
||||||
if (c == '\n') {
|
|
||||||
dx = 0;
|
|
||||||
dy -= f->height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* font, const std::string& str, s16 x, s16 y)
|
|
||||||
{
|
|
||||||
if (!font)
|
|
||||||
font = &fontDefault;
|
|
||||||
|
|
||||||
u16 fbWidth, fbHeight;
|
|
||||||
u8* fbAdr = gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#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);
|
|
@ -1,9 +0,0 @@
|
|||||||
#include <3ds.h>
|
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
font_s fontDefault = {
|
|
||||||
font1Data,
|
|
||||||
font1Desc,
|
|
||||||
16,
|
|
||||||
{ 0xFF, 0xFF, 0xFF }
|
|
||||||
};
|
|
@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
struct Glyph {
|
|
||||||
// Glyph representation
|
|
||||||
char c;
|
|
||||||
|
|
||||||
// x and y origin of the character.
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
// width and height in pixels.
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
// x and y offset
|
|
||||||
int xo, yo;
|
|
||||||
|
|
||||||
// Pixels after this character to begin
|
|
||||||
// drawing the next one.
|
|
||||||
int xa;
|
|
||||||
|
|
||||||
// Glyph data.
|
|
||||||
u8* data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct font_s {
|
|
||||||
u8* data;
|
|
||||||
Glyph* desc;
|
|
||||||
u8 height;
|
|
||||||
u8 color[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern u8 font1Data[];
|
|
||||||
extern Glyph font1Desc[];
|
|
||||||
|
|
||||||
extern font_s fontDefault;
|
|
261
source/font1.cpp
261
source/font1.cpp
File diff suppressed because one or more lines are too long
@ -21,17 +21,18 @@ int main(int argc, char** argv)
|
|||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
InitOutput();
|
InitOutput();
|
||||||
|
|
||||||
ClearScreens();
|
consoleClear();
|
||||||
Print(GFX_TOP, "Press A to begin...\n");
|
Print("Press A to begin...\n");
|
||||||
|
|
||||||
while (aptMainLoop()) {
|
while (aptMainLoop()) {
|
||||||
DrawBuffers();
|
gfxFlushBuffers();
|
||||||
|
gfxSwapBuffers();
|
||||||
|
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
if (hidKeysDown() & KEY_START) {
|
if (hidKeysDown() & KEY_START) {
|
||||||
break;
|
break;
|
||||||
} else if (hidKeysDown() & KEY_A) {
|
} else if (hidKeysDown() & KEY_A) {
|
||||||
ClearScreens();
|
consoleClear();
|
||||||
|
|
||||||
if (test_counter < (sizeof(tests) / sizeof(tests[0]))) {
|
if (test_counter < (sizeof(tests) / sizeof(tests[0]))) {
|
||||||
tests[test_counter]();
|
tests[test_counter]();
|
||||||
@ -40,15 +41,15 @@ int main(int argc, char** argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(GFX_TOP, "\n");
|
Log("\n");
|
||||||
Print(GFX_TOP, "Press A to continue...\n");
|
Print("Press A to continue...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gspWaitForEvent(GSPEVENT_VBlank0, false);
|
gspWaitForEvent(GSPEVENT_VBlank0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearScreens();
|
consoleClear();
|
||||||
|
|
||||||
gfxExit();
|
gfxExit();
|
||||||
DeinitOutput();
|
DeinitOutput();
|
||||||
|
|
||||||
|
@ -2,80 +2,29 @@
|
|||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "draw.h"
|
//#include "common/string_funcs.h"
|
||||||
#include "common/string_funcs.h"
|
|
||||||
|
|
||||||
static FILE* log_file;
|
static FILE* log_file = nullptr;
|
||||||
|
|
||||||
static std::string buffer_top;
|
|
||||||
static std::string buffer_bottom;
|
|
||||||
|
|
||||||
static std::string& GetTextBuffer(gfxScreen_t screen)
|
|
||||||
{
|
|
||||||
switch (screen) {
|
|
||||||
case GFX_TOP: return buffer_top;
|
|
||||||
case GFX_BOTTOM: return buffer_bottom;
|
|
||||||
}
|
|
||||||
return buffer_top;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DrawBuffer(gfxScreen_t screen)
|
|
||||||
{
|
|
||||||
Rect screen_size = GetScreenSize(screen);
|
|
||||||
std::string& text_buffer = GetTextBuffer(screen);
|
|
||||||
|
|
||||||
int lines = Common::CountLines(text_buffer);
|
|
||||||
while (lines > (screen_size.h / fontDefault.height - 3)) {
|
|
||||||
Common::DeleteFirstLine(&text_buffer);
|
|
||||||
lines--;
|
|
||||||
}
|
|
||||||
DrawText(screen, GFX_LEFT, nullptr, text_buffer, screen_size.h - fontDefault.height * 3, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitOutput()
|
void InitOutput()
|
||||||
{
|
{
|
||||||
sdmcInit();
|
sdmcInit();
|
||||||
|
consoleInit(GFX_TOP, nullptr);
|
||||||
log_file = fopen("hwtest_log.txt", "w");
|
log_file = fopen("hwtest_log.txt", "w");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBuffers()
|
void Print(const std::string& text)
|
||||||
{
|
{
|
||||||
FillScreen(GFX_TOP, 0x00, 0x66, 0x88);
|
printf("%s", text.c_str());
|
||||||
DrawBuffer(GFX_TOP);
|
|
||||||
|
|
||||||
FillScreen(GFX_BOTTOM, 0x00, 0x00, 0x00);
|
|
||||||
DrawBuffer(GFX_BOTTOM);
|
|
||||||
|
|
||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
gfxSwapBuffers();
|
gfxSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b)
|
void Log(const std::string& text)
|
||||||
{
|
{
|
||||||
FillScreen(screen, bg_r, bg_g, bg_b);
|
Print(text);
|
||||||
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);
|
LogToFile(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,10 +32,12 @@ void LogToFile(const std::string& text)
|
|||||||
{
|
{
|
||||||
svcOutputDebugString(text.c_str(), text.length());
|
svcOutputDebugString(text.c_str(), text.length());
|
||||||
fprintf(log_file, "%s", text.c_str());
|
fprintf(log_file, "%s", text.c_str());
|
||||||
|
fflush(log_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeinitOutput()
|
void DeinitOutput()
|
||||||
{
|
{
|
||||||
fclose(log_file);
|
fclose(log_file);
|
||||||
|
log_file = nullptr;
|
||||||
sdmcExit();
|
sdmcExit();
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,13 @@
|
|||||||
|
|
||||||
void InitOutput();
|
void InitOutput();
|
||||||
|
|
||||||
void DrawBuffers();
|
|
||||||
|
|
||||||
/// Prints `text` to `screen`.
|
/// Prints `text` to `screen`.
|
||||||
void Print(gfxScreen_t screen, const std::string& text);
|
void Print(const std::string& text);
|
||||||
|
|
||||||
/// Prints `text` to `screen`, and logs it in the log file.
|
/// Prints `text` to `screen`, and logs it in the log file.
|
||||||
void Log(gfxScreen_t screen, const std::string& text);
|
void Log(const std::string& text);
|
||||||
|
|
||||||
/// Logs `text` to the log file.
|
/// Logs `text` to the log file.
|
||||||
void LogToFile(const std::string& text);
|
void LogToFile(const std::string& text);
|
||||||
|
|
||||||
void ClearScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b);
|
|
||||||
void ClearScreens();
|
|
||||||
|
|
||||||
void DeinitOutput();
|
void DeinitOutput();
|
||||||
|
@ -44,7 +44,7 @@ static void DisplayTransferAndWait(u32* input, u32* output, Dimensions input_dim
|
|||||||
GSPGPU_InvalidateDataCache(nullptr, (u8*)output, sizeof(u32));
|
GSPGPU_InvalidateDataCache(nullptr, (u8*)output, sizeof(u32));
|
||||||
Result res = GX_SetDisplayTransfer(nullptr, (u32*)input, input_dimensions.raw, (u32*)output, output_dimensions.raw, flags);
|
Result res = GX_SetDisplayTransfer(nullptr, (u32*)input, input_dimensions.raw, (u32*)output, output_dimensions.raw, flags);
|
||||||
if ((u32)res != 0) {
|
if ((u32)res != 0) {
|
||||||
Log(GFX_BOTTOM, Common::FormatString("Something went wrong: %u\r\n", (u32)res));
|
Log(Common::FormatString("Something went wrong: %u\n", (u32)res));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
@ -388,4 +388,4 @@ void TestAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
void SoftAssertLog(const std::string& function, int line, const std::string& condition)
|
void SoftAssertLog(const std::string& function, int line, const std::string& condition)
|
||||||
{
|
{
|
||||||
Log(GFX_TOP, Common::FormatString("SOFTASSERT FAILURE: `%s`\n", condition.c_str()));
|
Log(Common::FormatString("SOFTASSERT FAILURE: `%s`\n", condition.c_str()));
|
||||||
Log(GFX_TOP, Common::FormatString(" At `%s` L%i\n", function.c_str(), line));
|
Log(Common::FormatString(" At `%s` L%i\n", function.c_str(), line));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSuccess(const std::string& group, const std::string& name, bool val)
|
void PrintSuccess(const std::string& group, const std::string& name, bool val)
|
||||||
{
|
{
|
||||||
Log(GFX_TOP, Common::FormatString("%s: [%s] %s\n", val ? "SUCCESS" : "FAILURE", group.c_str(), name.c_str()));
|
Log(Common::FormatString("%s: [%s] %s\n", val ? "SUCCESS" : "FAILURE", group.c_str(), name.c_str()));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user