mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-07 08:39:24 +02:00
Refactor console device, see details:
- Added ConsoleRenderer interface, which abstracts all relevant operations needed to set up and write characters to a text mode display - ConsoleFont now has tileWidth/tileHeight parameters - PrintConsole now holds a pointer to a ConsoleRenderer - Added consoleExit for deinitializing the console - Added consoleUpdate for updating the display every frame - Corrected lots of obsolete/outdated comments - Separated console software renderer into its own file (console_sw.c) - Added getDefaultConsoleRenderer weak function, for selecting the default console renderer when none (NULL) is specified in PrintConsole - Software renderer now takes care of gfxInitDefault/gfxExit - All these changes are backwards compatible with older programs because: - gfxInitDefault has double-init protection - Old programs don't call consoleUpdate/Exit, but their implementation in the software renderer is identical to what old programs were already doing anyway
This commit is contained in:
parent
cc70f19e61
commit
1563df3921
@ -10,12 +10,9 @@
|
|||||||
*
|
*
|
||||||
* General usage is to initialize the console by:
|
* General usage is to initialize the console by:
|
||||||
* @code
|
* @code
|
||||||
* consoleDemoInit()
|
* consoleInit(NULL)
|
||||||
* @endcode
|
|
||||||
* or to customize the console usage by:
|
|
||||||
* @code
|
|
||||||
* consoleInit()
|
|
||||||
* @endcode
|
* @endcode
|
||||||
|
* optionally customizing the console usage by passing a pointer to a custom PrintConsole struct.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../../types.h"
|
#include "../../types.h"
|
||||||
@ -31,15 +28,27 @@
|
|||||||
#define CONSOLE_CYAN CONSOLE_ESC(36;1m)
|
#define CONSOLE_CYAN CONSOLE_ESC(36;1m)
|
||||||
#define CONSOLE_WHITE CONSOLE_ESC(37;1m)
|
#define CONSOLE_WHITE CONSOLE_ESC(37;1m)
|
||||||
|
|
||||||
/// A callback for printing a character.
|
// Forward declaration
|
||||||
typedef bool(*ConsolePrint)(void* con, int c);
|
typedef struct PrintConsole PrintConsole;
|
||||||
|
|
||||||
|
/// Renderer interface for the console.
|
||||||
|
typedef struct ConsoleRenderer
|
||||||
|
{
|
||||||
|
bool (*init)(PrintConsole* con);
|
||||||
|
void (*deinit)(PrintConsole* con);
|
||||||
|
void (*drawChar)(PrintConsole* con, int x, int y, int c);
|
||||||
|
void (*scrollWindow)(PrintConsole* con);
|
||||||
|
void (*flushAndSwap)(PrintConsole* con);
|
||||||
|
} ConsoleRenderer;
|
||||||
|
|
||||||
/// A font struct for the console.
|
/// A font struct for the console.
|
||||||
typedef struct ConsoleFont
|
typedef struct ConsoleFont
|
||||||
{
|
{
|
||||||
u16* gfx; ///< A pointer to the font graphics
|
const void* gfx; ///< A pointer to the font graphics
|
||||||
u16 asciiOffset; ///< Offset to the first valid character in the font table
|
u16 asciiOffset; ///< Offset to the first valid character in the font table
|
||||||
u16 numChars; ///< Number of characters in the font graphics
|
u16 numChars; ///< Number of characters in the font graphics
|
||||||
|
u16 tileWidth;
|
||||||
|
u16 tileHeight;
|
||||||
}ConsoleFont;
|
}ConsoleFont;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,10 +60,13 @@ typedef struct ConsoleFont
|
|||||||
* {
|
* {
|
||||||
* //Font:
|
* //Font:
|
||||||
* {
|
* {
|
||||||
* (u16*)default_font_bin, //font gfx
|
* default_font_bin, //font gfx
|
||||||
* 0, //first ascii character in the set
|
* 0, //first ascii character in the set
|
||||||
* 128, //number of characters in the font set
|
* 256, //number of characters in the font set
|
||||||
|
* 16, //tile width
|
||||||
|
* 16, //tile height
|
||||||
* },
|
* },
|
||||||
|
* NULL, //renderer
|
||||||
* 0,0, //cursorX cursorY
|
* 0,0, //cursorX cursorY
|
||||||
* 0,0, //prevcursorX prevcursorY
|
* 0,0, //prevcursorX prevcursorY
|
||||||
* 80, //console width
|
* 80, //console width
|
||||||
@ -64,18 +76,17 @@ typedef struct ConsoleFont
|
|||||||
* 80, //window width
|
* 80, //window width
|
||||||
* 45, //window height
|
* 45, //window height
|
||||||
* 3, //tab size
|
* 3, //tab size
|
||||||
* 0, //font character offset
|
* 7, // foreground color
|
||||||
* 0, //print callback
|
* 0, // background color
|
||||||
|
* 0, // flags
|
||||||
* false //console initialized
|
* false //console initialized
|
||||||
* };
|
* };
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
typedef struct PrintConsole
|
struct PrintConsole
|
||||||
{
|
{
|
||||||
ConsoleFont font; ///< Font of the console
|
ConsoleFont font; ///< Font of the console
|
||||||
|
ConsoleRenderer* renderer; ///< Renderer of the console
|
||||||
u32 *frameBuffer; ///< Framebuffer address
|
|
||||||
u32 *frameBuffer2; ///< Framebuffer address
|
|
||||||
|
|
||||||
int cursorX; ///< Current X location of the cursor (as a tile offset by default)
|
int cursorX; ///< Current X location of the cursor (as a tile offset by default)
|
||||||
int cursorY; ///< Current Y location of the cursor (as a tile offset by default)
|
int cursorY; ///< Current Y location of the cursor (as a tile offset by default)
|
||||||
@ -86,20 +97,18 @@ typedef struct PrintConsole
|
|||||||
int consoleWidth; ///< Width of the console hardware layer in characters
|
int consoleWidth; ///< Width of the console hardware layer in characters
|
||||||
int consoleHeight; ///< Height of the console hardware layer in characters
|
int consoleHeight; ///< Height of the console hardware layer in characters
|
||||||
|
|
||||||
int windowX; ///< Window X location in characters (not implemented)
|
int windowX; ///< Window X location in characters
|
||||||
int windowY; ///< Window Y location in characters (not implemented)
|
int windowY; ///< Window Y location in characters
|
||||||
int windowWidth; ///< Window width in characters (not implemented)
|
int windowWidth; ///< Window width in characters
|
||||||
int windowHeight; ///< Window height in characters (not implemented)
|
int windowHeight; ///< Window height in characters
|
||||||
|
|
||||||
int tabSize; ///< Size of a tab
|
int tabSize; ///< Size of a tab
|
||||||
int fg; ///< Foreground color
|
int fg; ///< Foreground color
|
||||||
int bg; ///< Background color
|
int bg; ///< Background color
|
||||||
int flags; ///< Reverse/bright flags
|
int flags; ///< Reverse/bright flags
|
||||||
|
|
||||||
ConsolePrint PrintChar; ///< Callback for printing a character. Should return true if it has handled rendering the graphics (else the print engine will attempt to render via tiles).
|
|
||||||
|
|
||||||
bool consoleInitialised; ///< True if the console is initialized
|
bool consoleInitialised; ///< True if the console is initialized
|
||||||
}PrintConsole;
|
};
|
||||||
|
|
||||||
#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text
|
#define CONSOLE_COLOR_BOLD (1<<0) ///< Bold text
|
||||||
#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text
|
#define CONSOLE_COLOR_FAINT (1<<1) ///< Faint text
|
||||||
@ -157,11 +166,24 @@ PrintConsole *consoleSelect(PrintConsole* console);
|
|||||||
*/
|
*/
|
||||||
PrintConsole* consoleInit(PrintConsole* console);
|
PrintConsole* consoleInit(PrintConsole* console);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialise the console.
|
||||||
|
* @param console A pointer to the console data to initialize (if it's NULL, the default console will be used).
|
||||||
|
*/
|
||||||
|
void consoleExit(PrintConsole* console);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the console, submitting a new frame to the display.
|
||||||
|
* @param console A pointer to the console data to initialize (if it's NULL, the default console will be used).
|
||||||
|
* @remark This function should be called periodically. Failure to call this function will result in lack of screen updating.
|
||||||
|
*/
|
||||||
|
void consoleUpdate(PrintConsole* console);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes debug console output on stderr to the specified device.
|
* @brief Initializes debug console output on stderr to the specified device.
|
||||||
* @param device The debug device (or devices) to output debug print statements to.
|
* @param device The debug device (or devices) to output debug print statements to.
|
||||||
*/
|
*/
|
||||||
void consoleDebugInit(debugDevice device);
|
void consoleDebugInit(debugDevice device);
|
||||||
|
|
||||||
/// Clears the screan by using iprintf("\x1b[2J");
|
/// Clears the screan by using printf("\x1b[2J");
|
||||||
void consoleClear(void);
|
void consoleClear(void);
|
||||||
|
@ -3,51 +3,21 @@
|
|||||||
#include <sys/iosupport.h>
|
#include <sys/iosupport.h>
|
||||||
#include "runtime/devices/console.h"
|
#include "runtime/devices/console.h"
|
||||||
#include "kernel/svc.h"
|
#include "kernel/svc.h"
|
||||||
#include "display/gfx.h"
|
|
||||||
|
|
||||||
#include "default_font_bin.h"
|
#include "default_font_bin.h"
|
||||||
|
|
||||||
//set up the palette for color printing
|
|
||||||
static u32 colorTable[] = {
|
|
||||||
RGBA8_MAXALPHA( 0, 0, 0), // black
|
|
||||||
RGBA8_MAXALPHA(128, 0, 0), // red
|
|
||||||
RGBA8_MAXALPHA( 0,128, 0), // green
|
|
||||||
RGBA8_MAXALPHA(128,128, 0), // yellow
|
|
||||||
RGBA8_MAXALPHA( 0, 0,128), // blue
|
|
||||||
RGBA8_MAXALPHA(128, 0,128), // magenta
|
|
||||||
RGBA8_MAXALPHA( 0,128,128), // cyan
|
|
||||||
RGBA8_MAXALPHA(192,192,192), // white
|
|
||||||
|
|
||||||
RGBA8_MAXALPHA(128,128,128), // bright black
|
|
||||||
RGBA8_MAXALPHA(255, 0, 0), // bright red
|
|
||||||
RGBA8_MAXALPHA( 0,255, 0), // bright green
|
|
||||||
RGBA8_MAXALPHA(255,255, 0), // bright yellow
|
|
||||||
RGBA8_MAXALPHA( 0, 0,255), // bright blue
|
|
||||||
RGBA8_MAXALPHA(255, 0,255), // bright magenta
|
|
||||||
RGBA8_MAXALPHA( 0,255,255), // bright cyan
|
|
||||||
RGBA8_MAXALPHA(255,255,255), // bright white
|
|
||||||
|
|
||||||
RGBA8_MAXALPHA( 0, 0, 0), // faint black
|
|
||||||
RGBA8_MAXALPHA( 64, 0, 0), // faint red
|
|
||||||
RGBA8_MAXALPHA( 0, 64, 0), // faint green
|
|
||||||
RGBA8_MAXALPHA( 64, 64, 0), // faint yellow
|
|
||||||
RGBA8_MAXALPHA( 0, 0, 64), // faint blue
|
|
||||||
RGBA8_MAXALPHA( 64, 0, 64), // faint magenta
|
|
||||||
RGBA8_MAXALPHA( 0, 64, 64), // faint cyan
|
|
||||||
RGBA8_MAXALPHA( 96, 96, 96), // faint white
|
|
||||||
};
|
|
||||||
|
|
||||||
//The below width/height is for 720p.
|
//The below width/height is for 720p.
|
||||||
PrintConsole defaultConsole =
|
static PrintConsole defaultConsole =
|
||||||
{
|
{
|
||||||
//Font:
|
//Font:
|
||||||
{
|
{
|
||||||
(u16*)default_font_bin, //font gfx
|
default_font_bin, //font gfx
|
||||||
0, //first ascii character in the set
|
0, //first ascii character in the set
|
||||||
256 //number of characters in the font set
|
256, //number of characters in the font set
|
||||||
|
16, //tile width
|
||||||
|
16, //tile height
|
||||||
},
|
},
|
||||||
(u32*)NULL,
|
NULL, //renderer
|
||||||
(u32*)NULL,
|
|
||||||
0,0, //cursorX cursorY
|
0,0, //cursorX cursorY
|
||||||
0,0, //prevcursorX prevcursorY
|
0,0, //prevcursorX prevcursorY
|
||||||
80, //console width
|
80, //console width
|
||||||
@ -60,18 +30,18 @@ PrintConsole defaultConsole =
|
|||||||
7, // foreground color
|
7, // foreground color
|
||||||
0, // background color
|
0, // background color
|
||||||
0, // flags
|
0, // flags
|
||||||
0, //print callback
|
|
||||||
false //console initialized
|
false //console initialized
|
||||||
};
|
};
|
||||||
|
|
||||||
PrintConsole currentCopy;
|
static PrintConsole currentCopy;
|
||||||
|
|
||||||
PrintConsole* currentConsole = ¤tCopy;
|
static PrintConsole* currentConsole = ¤tCopy;
|
||||||
|
|
||||||
PrintConsole* consoleGetDefault(void){return &defaultConsole;}
|
PrintConsole* consoleGetDefault(void){return &defaultConsole;}
|
||||||
|
|
||||||
void consolePrintChar(int c);
|
static void consoleNewRow(void);
|
||||||
void consoleDrawChar(int c);
|
static void consolePrintChar(int c);
|
||||||
|
static void consoleDrawChar(int c);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
static void consoleCls(char mode) {
|
static void consoleCls(char mode) {
|
||||||
@ -123,9 +93,6 @@ static void consoleCls(char mode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//gfxFlushBuffers();
|
|
||||||
//gfxSwapBuffers();
|
|
||||||
//gfxWaitForVsync();
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
static void consoleClearLine(char mode) {
|
static void consoleClearLine(char mode) {
|
||||||
@ -178,9 +145,6 @@ static void consoleClearLine(char mode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//gfxFlushBuffers();
|
|
||||||
//gfxSwapBuffers();
|
|
||||||
//gfxWaitForVsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -526,6 +490,8 @@ static const devoptab_t dotab_null = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ConsoleRenderer* getDefaultConsoleRenderer(void);
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
PrintConsole* consoleInit(PrintConsole* console) {
|
PrintConsole* consoleInit(PrintConsole* console) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
@ -549,23 +515,40 @@ PrintConsole* consoleInit(PrintConsole* console) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*currentConsole = defaultConsole;
|
*currentConsole = defaultConsole;
|
||||||
|
if (!console->renderer) {
|
||||||
|
console->renderer = getDefaultConsoleRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
console->consoleInitialised = 1;
|
if (console->renderer->init(console)) {
|
||||||
|
console->consoleInitialised = true;
|
||||||
gfxSetMode(GfxMode_TiledDouble);
|
|
||||||
|
|
||||||
console->frameBuffer = (u32*)gfxGetFramebuffer(NULL, NULL);
|
|
||||||
gfxSwapBuffers();
|
|
||||||
console->frameBuffer2 = (u32*)gfxGetFramebuffer(NULL, NULL);
|
|
||||||
|
|
||||||
//gfxFlushBuffers();
|
|
||||||
//gfxSwapBuffers();
|
|
||||||
//gfxWaitForVsync();
|
|
||||||
|
|
||||||
consoleCls('2');
|
consoleCls('2');
|
||||||
|
return console;
|
||||||
|
}
|
||||||
|
|
||||||
return currentConsole;
|
return currentConsole;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
void consoleExit(PrintConsole* console) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (!console) console = currentConsole;
|
||||||
|
|
||||||
|
if (console->consoleInitialised) {
|
||||||
|
console->renderer->deinit(console);
|
||||||
|
console->consoleInitialised = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
void consoleUpdate(PrintConsole* console) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (!console) console = currentConsole;
|
||||||
|
|
||||||
|
if (console->consoleInitialised) {
|
||||||
|
console->renderer->flushAndSwap(console);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
@ -610,99 +593,28 @@ void consoleSetFont(PrintConsole* console, ConsoleFont* font){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
static void newRow(void) {
|
void consoleNewRow(void) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
currentConsole->cursorY ++;
|
currentConsole->cursorY ++;
|
||||||
|
|
||||||
|
|
||||||
if(currentConsole->cursorY >= currentConsole->windowHeight) {
|
if(currentConsole->cursorY >= currentConsole->windowHeight) {
|
||||||
currentConsole->cursorY --;
|
currentConsole->cursorY --;
|
||||||
|
currentConsole->renderer->scrollWindow(currentConsole);
|
||||||
int i,j;
|
|
||||||
u32 x, y;
|
|
||||||
|
|
||||||
x = currentConsole->windowX * 16;
|
|
||||||
y = currentConsole->windowY * 16;
|
|
||||||
|
|
||||||
for (i=0; i<currentConsole->windowWidth*16; i++) {
|
|
||||||
u32 *from;
|
|
||||||
u32 *to;
|
|
||||||
for (j=0;j<(currentConsole->windowHeight-1)*16;j++) {
|
|
||||||
to = ¤tConsole->frameBuffer[gfxGetFramebufferDisplayOffset(x + i, y + j)];
|
|
||||||
from = ¤tConsole->frameBuffer[gfxGetFramebufferDisplayOffset(x + i, y + 16 + j)];
|
|
||||||
*to = *from;
|
|
||||||
to = ¤tConsole->frameBuffer2[gfxGetFramebufferDisplayOffset(x + i, y + j)];
|
|
||||||
from = ¤tConsole->frameBuffer2[gfxGetFramebufferDisplayOffset(x + i, y + 16 + j)];
|
|
||||||
*to = *from;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
consoleClearLine('2');
|
consoleClearLine('2');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void consoleDrawChar(int c) {
|
void consoleDrawChar(int c) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
c -= currentConsole->font.asciiOffset;
|
c -= currentConsole->font.asciiOffset;
|
||||||
if ( c < 0 || c > currentConsole->font.numChars ) return;
|
if ( c < 0 || c > currentConsole->font.numChars ) return;
|
||||||
|
|
||||||
u16 *fontdata = currentConsole->font.gfx + (16 * c);
|
currentConsole->renderer->drawChar(
|
||||||
|
currentConsole,
|
||||||
int writingColor = currentConsole->fg;
|
currentConsole->cursorX + currentConsole->windowX,
|
||||||
int screenColor = currentConsole->bg;
|
currentConsole->cursorY + currentConsole->windowY,
|
||||||
|
c);
|
||||||
if (currentConsole->flags & CONSOLE_COLOR_BOLD) {
|
|
||||||
writingColor += 8;
|
|
||||||
} else if (currentConsole->flags & CONSOLE_COLOR_FAINT) {
|
|
||||||
writingColor += 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentConsole->flags & CONSOLE_COLOR_REVERSE) {
|
|
||||||
int tmp = writingColor;
|
|
||||||
writingColor = screenColor;
|
|
||||||
screenColor = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 bg = colorTable[screenColor];
|
|
||||||
u32 fg = colorTable[writingColor];
|
|
||||||
|
|
||||||
u128 *tmp = (u128*)fontdata;
|
|
||||||
|
|
||||||
u128 bvaltop = tmp[0];
|
|
||||||
u128 bvalbtm = tmp[1];
|
|
||||||
|
|
||||||
if (currentConsole->flags & CONSOLE_UNDERLINE) bvalbtm |= (u128)0xffffULL << 7*16;
|
|
||||||
|
|
||||||
if (currentConsole->flags & CONSOLE_CROSSED_OUT) bvaltop |= (u128)0xffffULL << 7*16;
|
|
||||||
|
|
||||||
u16 mask = 0x8000;
|
|
||||||
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
int x = (currentConsole->cursorX + currentConsole->windowX) * 16;
|
|
||||||
int y = ((currentConsole->cursorY + currentConsole->windowY) *16 );
|
|
||||||
|
|
||||||
u32 *screen;
|
|
||||||
|
|
||||||
for (i=0;i<16;i++) {
|
|
||||||
for (j=0;j<8;j++) {
|
|
||||||
uint32_t screenOffset = gfxGetFramebufferDisplayOffset(x + i, y + j);
|
|
||||||
screen = ¤tConsole->frameBuffer[screenOffset];
|
|
||||||
if (bvaltop >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
|
||||||
screen = ¤tConsole->frameBuffer2[screenOffset];
|
|
||||||
if (bvaltop >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
|
||||||
|
|
||||||
screenOffset = gfxGetFramebufferDisplayOffset(x + i, y + j + 8);
|
|
||||||
screen = ¤tConsole->frameBuffer[screenOffset];
|
|
||||||
if (bvalbtm >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
|
||||||
screen = ¤tConsole->frameBuffer2[screenOffset];
|
|
||||||
if (bvalbtm >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
|
||||||
}
|
|
||||||
mask >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
@ -710,14 +622,10 @@ void consolePrintChar(int c) {
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
if (c==0) return;
|
if (c==0) return;
|
||||||
|
|
||||||
if(currentConsole->PrintChar)
|
|
||||||
if(currentConsole->PrintChar(currentConsole, c))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(currentConsole->cursorX >= currentConsole->windowWidth) {
|
if(currentConsole->cursorX >= currentConsole->windowWidth) {
|
||||||
currentConsole->cursorX = 0;
|
currentConsole->cursorX = 0;
|
||||||
|
|
||||||
newRow();
|
consoleNewRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
@ -730,7 +638,7 @@ void consolePrintChar(int c) {
|
|||||||
Reason: VT sequences are more specific to the task of cursor placement.
|
Reason: VT sequences are more specific to the task of cursor placement.
|
||||||
The special escape sequences \b \f & \v are archaic and non-portable.
|
The special escape sequences \b \f & \v are archaic and non-portable.
|
||||||
*/
|
*/
|
||||||
case 8:
|
case '\b':
|
||||||
currentConsole->cursorX--;
|
currentConsole->cursorX--;
|
||||||
|
|
||||||
if(currentConsole->cursorX < 0) {
|
if(currentConsole->cursorX < 0) {
|
||||||
@ -745,16 +653,13 @@ void consolePrintChar(int c) {
|
|||||||
consoleDrawChar(' ');
|
consoleDrawChar(' ');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case '\t':
|
||||||
currentConsole->cursorX += currentConsole->tabSize - ((currentConsole->cursorX)%(currentConsole->tabSize));
|
currentConsole->cursorX += currentConsole->tabSize - ((currentConsole->cursorX)%(currentConsole->tabSize));
|
||||||
break;
|
break;
|
||||||
case 10:
|
case '\n':
|
||||||
newRow();
|
consoleNewRow();
|
||||||
case 13:
|
case '\r':
|
||||||
currentConsole->cursorX = 0;
|
currentConsole->cursorX = 0;
|
||||||
//gfxFlushBuffers();
|
|
||||||
//gfxSwapBuffers();
|
|
||||||
//gfxWaitForVsync();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
consoleDrawChar(c);
|
consoleDrawChar(c);
|
||||||
@ -766,7 +671,7 @@ void consolePrintChar(int c) {
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void consoleClear(void) {
|
void consoleClear(void) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
iprintf("\x1b[2J");
|
printf("\x1b[2J");
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
@ -784,6 +689,3 @@ void consoleSetWindow(PrintConsole* console, int x, int y, int width, int height
|
|||||||
console->cursorY = 0;
|
console->cursorY = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
188
nx/source/runtime/devices/console_sw.c
Normal file
188
nx/source/runtime/devices/console_sw.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/iosupport.h>
|
||||||
|
#include "result.h"
|
||||||
|
#include "runtime/devices/console.h"
|
||||||
|
#include "display/gfx.h"
|
||||||
|
|
||||||
|
//set up the palette for color printing
|
||||||
|
static const u32 colorTable[] = {
|
||||||
|
RGBA8_MAXALPHA( 0, 0, 0), // black
|
||||||
|
RGBA8_MAXALPHA(128, 0, 0), // red
|
||||||
|
RGBA8_MAXALPHA( 0,128, 0), // green
|
||||||
|
RGBA8_MAXALPHA(128,128, 0), // yellow
|
||||||
|
RGBA8_MAXALPHA( 0, 0,128), // blue
|
||||||
|
RGBA8_MAXALPHA(128, 0,128), // magenta
|
||||||
|
RGBA8_MAXALPHA( 0,128,128), // cyan
|
||||||
|
RGBA8_MAXALPHA(192,192,192), // white
|
||||||
|
|
||||||
|
RGBA8_MAXALPHA(128,128,128), // bright black
|
||||||
|
RGBA8_MAXALPHA(255, 0, 0), // bright red
|
||||||
|
RGBA8_MAXALPHA( 0,255, 0), // bright green
|
||||||
|
RGBA8_MAXALPHA(255,255, 0), // bright yellow
|
||||||
|
RGBA8_MAXALPHA( 0, 0,255), // bright blue
|
||||||
|
RGBA8_MAXALPHA(255, 0,255), // bright magenta
|
||||||
|
RGBA8_MAXALPHA( 0,255,255), // bright cyan
|
||||||
|
RGBA8_MAXALPHA(255,255,255), // bright white
|
||||||
|
|
||||||
|
RGBA8_MAXALPHA( 0, 0, 0), // faint black
|
||||||
|
RGBA8_MAXALPHA( 64, 0, 0), // faint red
|
||||||
|
RGBA8_MAXALPHA( 0, 64, 0), // faint green
|
||||||
|
RGBA8_MAXALPHA( 64, 64, 0), // faint yellow
|
||||||
|
RGBA8_MAXALPHA( 0, 0, 64), // faint blue
|
||||||
|
RGBA8_MAXALPHA( 64, 0, 64), // faint magenta
|
||||||
|
RGBA8_MAXALPHA( 0, 64, 64), // faint cyan
|
||||||
|
RGBA8_MAXALPHA( 96, 96, 96), // faint white
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConsoleSwRenderer
|
||||||
|
{
|
||||||
|
ConsoleRenderer base;
|
||||||
|
u32 *frameBuffer; ///< Framebuffer address
|
||||||
|
u32 *frameBuffer2; ///< Framebuffer address
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ConsoleSwRenderer* ConsoleSwRenderer(PrintConsole* con)
|
||||||
|
{
|
||||||
|
return (struct ConsoleSwRenderer*)con->renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ConsoleSwRenderer_init(PrintConsole* con)
|
||||||
|
{
|
||||||
|
struct ConsoleSwRenderer* sw = ConsoleSwRenderer(con);
|
||||||
|
|
||||||
|
if (con->font.tileWidth != 16 || con->font.tileHeight != 16) {
|
||||||
|
// Only 16x16 tiles are supported for the font
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(gfxInitDefault())) {
|
||||||
|
// Graphics failed to initialize
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 width, height;
|
||||||
|
gfxGetFramebufferResolution(&width, &height);
|
||||||
|
if (con->consoleWidth > (width/16) || con->consoleHeight > (height/16)) {
|
||||||
|
// Unsupported console size
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxSetMode(GfxMode_TiledDouble);
|
||||||
|
sw->frameBuffer = (u32*)gfxGetFramebuffer(NULL, NULL);
|
||||||
|
gfxSwapBuffers();
|
||||||
|
sw->frameBuffer2 = (u32*)gfxGetFramebuffer(NULL, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConsoleSwRenderer_deinit(PrintConsole* con)
|
||||||
|
{
|
||||||
|
gfxExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConsoleSwRenderer_drawChar(PrintConsole* con, int x, int y, int c)
|
||||||
|
{
|
||||||
|
struct ConsoleSwRenderer* sw = ConsoleSwRenderer(con);
|
||||||
|
const u16 *fontdata = (const u16*)con->font.gfx + (16 * c);
|
||||||
|
|
||||||
|
int writingColor = con->fg;
|
||||||
|
int screenColor = con->bg;
|
||||||
|
|
||||||
|
if (con->flags & CONSOLE_COLOR_BOLD) {
|
||||||
|
writingColor += 8;
|
||||||
|
} else if (con->flags & CONSOLE_COLOR_FAINT) {
|
||||||
|
writingColor += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (con->flags & CONSOLE_COLOR_REVERSE) {
|
||||||
|
int tmp = writingColor;
|
||||||
|
writingColor = screenColor;
|
||||||
|
screenColor = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 bg = colorTable[screenColor];
|
||||||
|
u32 fg = colorTable[writingColor];
|
||||||
|
|
||||||
|
u128 *tmp = (u128*)fontdata;
|
||||||
|
|
||||||
|
u128 bvaltop = tmp[0];
|
||||||
|
u128 bvalbtm = tmp[1];
|
||||||
|
|
||||||
|
if (con->flags & CONSOLE_UNDERLINE) bvalbtm |= (u128)0xffffULL << 7*16;
|
||||||
|
|
||||||
|
if (con->flags & CONSOLE_CROSSED_OUT) bvaltop |= (u128)0xffffULL << 7*16;
|
||||||
|
|
||||||
|
u16 mask = 0x8000;
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
x *= 16;
|
||||||
|
y *= 16;
|
||||||
|
|
||||||
|
u32 *screen;
|
||||||
|
|
||||||
|
for (i=0;i<16;i++) {
|
||||||
|
for (j=0;j<8;j++) {
|
||||||
|
uint32_t screenOffset = gfxGetFramebufferDisplayOffset(x + i, y + j);
|
||||||
|
screen = &sw->frameBuffer[screenOffset];
|
||||||
|
if (bvaltop >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
||||||
|
screen = &sw->frameBuffer2[screenOffset];
|
||||||
|
if (bvaltop >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
||||||
|
|
||||||
|
screenOffset = gfxGetFramebufferDisplayOffset(x + i, y + j + 8);
|
||||||
|
screen = &sw->frameBuffer[screenOffset];
|
||||||
|
if (bvalbtm >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
||||||
|
screen = &sw->frameBuffer2[screenOffset];
|
||||||
|
if (bvalbtm >> (16*j) & mask) { *screen = fg; }else{ *screen = bg; }
|
||||||
|
}
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConsoleSwRenderer_scrollWindow(PrintConsole* con)
|
||||||
|
{
|
||||||
|
struct ConsoleSwRenderer* sw = ConsoleSwRenderer(con);
|
||||||
|
int i,j;
|
||||||
|
u32 x, y;
|
||||||
|
|
||||||
|
x = con->windowX * 16;
|
||||||
|
y = con->windowY * 16;
|
||||||
|
|
||||||
|
for (i=0; i<con->windowWidth*16; i++) {
|
||||||
|
u32 *from;
|
||||||
|
u32 *to;
|
||||||
|
for (j=0;j<(con->windowHeight-1)*16;j++) {
|
||||||
|
to = &sw->frameBuffer[gfxGetFramebufferDisplayOffset(x + i, y + j)];
|
||||||
|
from = &sw->frameBuffer[gfxGetFramebufferDisplayOffset(x + i, y + 16 + j)];
|
||||||
|
*to = *from;
|
||||||
|
to = &sw->frameBuffer2[gfxGetFramebufferDisplayOffset(x + i, y + j)];
|
||||||
|
from = &sw->frameBuffer2[gfxGetFramebufferDisplayOffset(x + i, y + 16 + j)];
|
||||||
|
*to = *from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConsoleSwRenderer_flushAndSwap(PrintConsole* con)
|
||||||
|
{
|
||||||
|
gfxFlushBuffers();
|
||||||
|
gfxSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ConsoleSwRenderer s_consoleSwRenderer =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ConsoleSwRenderer_init,
|
||||||
|
ConsoleSwRenderer_deinit,
|
||||||
|
ConsoleSwRenderer_drawChar,
|
||||||
|
ConsoleSwRenderer_scrollWindow,
|
||||||
|
ConsoleSwRenderer_flushAndSwap,
|
||||||
|
}, //base
|
||||||
|
NULL, //frameBuffer
|
||||||
|
NULL, //frameBuffer2
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((weak)) ConsoleRenderer* getDefaultConsoleRenderer(void)
|
||||||
|
{
|
||||||
|
return &s_consoleSwRenderer.base;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user