#include <3ds.h>
#include <citro3d.h>
#include <stdio.h>
#include <malloc.h>
#include <sys/iosupport.h>
#include "c3d_console.h"
#define CONSOLE_TEXTURE_TRANSFER_FLAGS \
(GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | \
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) | \
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
extern ssize_t con_write(struct _reent *r,int fd,const char *ptr, size_t len);
extern u8 default_font_bin[ ];
static u16* ConsoleBuffer240x320 = NULL;
static u16* ConsoleTextureBuffer = NULL;
C3D_Tex ConsoleTexture;
static PrintConsole C3DConsole = {
{
default_font_bin,
0,
256
},
NULL,
0,
0,
0,
0,
40,
30,
0,
0,
40,
30,
3,
7,
0,
0,
0,
false
};
static const devoptab_t MyDevOpTab = {
"con",
0,
NULL,
NULL,
con_write,
NULL,
NULL,
NULL
};
void C3D_ConsoleFree( void ) {
if ( ConsoleBuffer240x320 )
free( ConsoleBuffer240x320 );
if ( ConsoleTextureBuffer )
linearFree( ConsoleTextureBuffer );
ConsoleBuffer240x320 = NULL;
ConsoleTextureBuffer = NULL;
}
int C3D_ConsoleInit( void ) {
int i = 0;
ConsoleBuffer240x320 = ( u16* ) malloc( 240 * 320 * 2 );
ConsoleTextureBuffer = ( u16* ) linearMemAlign( 256 * 512 * 2, 0x80 );
if ( ConsoleBuffer240x320 && ConsoleTextureBuffer ) {
C3D_TexInit( &ConsoleTexture, 256, 512, GPU_RGB565 );
devoptab_list[ STD_OUT ] = &MyDevOpTab;
devoptab_list[ STD_ERR ] = &MyDevOpTab;
setvbuf( stdout, NULL, _IONBF, 0 );
setvbuf( stderr, NULL, _IONBF, 0 );
C3DConsole.frameBuffer = ConsoleBuffer240x320;
C3DConsole.consoleInitialised = true;
consoleSelect( &C3DConsole );
consoleSetWindow( &C3DConsole, 0, 0, 320 / 8, 240 / 8 );
consoleClear( );
/*
* BUGBUGBUG:
* First 2 lines don't exist?
* So it's like the window is actually 40x28 for some reason.
*/
for ( i = 0; i <= 29; i++ ) {
printf( "line %d\n", i );
}
return 1;
}
C3D_ConsoleFree( );
return 0;
}
void C3D_ConsoleUpdate( void ) {
u16* Src = ( u16* ) ConsoleBuffer240x320;
u16* Dst = ( u16* ) ConsoleTextureBuffer;
int x = 0;
int y = 0;
/*
* TODO:
* Speed up later, this is gonna be slow as BALLS.
*/
for ( y = 0; y < 320; y++ ) {
for ( x = 0; x < 240; x++ ) {
Dst[ x + ( y * 256 ) ] = Src[ x + ( y * 240 ) ];
}
}
GSPGPU_FlushDataCache( ConsoleTextureBuffer, 256 * 512 * 2 );
GX_DisplayTransfer( ( u32* ) ConsoleTextureBuffer, GX_BUFFER_DIM( 256, 512 ), ( u32* ) ConsoleTexture.data, GX_BUFFER_DIM( 256, 512 ), CONSOLE_TEXTURE_TRANSFER_FLAGS );
gspWaitForPPF( );
}
void C3D_ConsoleDraw( void ) {
C3D_TexBind( 0, &ConsoleTexture );
/*
* Sorcery!
* I don't know it either.
*/
C3D_ImmDrawBegin( GPU_TRIANGLES );
// 1st triangle
C3D_ImmSendAttrib( 0, 0, 0.5, 0.0 );
C3D_ImmSendAttrib( 1.0, 0.0, 0.0, 0.0 );
C3D_ImmSendAttrib( 512, 256, 0.5, 0.0 );
C3D_ImmSendAttrib( 0.0, 1.0, 0.0, 0.0 );
C3D_ImmSendAttrib( 512, 0, 0.5, 0.0 );
C3D_ImmSendAttrib( 1.0, 1.0, 0.0, 0.0 );
// 2nd triangle
C3D_ImmSendAttrib( 0, 0, 0.5, 0.0 );
C3D_ImmSendAttrib( 1.0, 0.0, 0.0, 0.0 );
C3D_ImmSendAttrib( 0, 256, 0.5, 0.0 );
C3D_ImmSendAttrib( 0.0, 0.0, 0.0, 0.0 );
C3D_ImmSendAttrib( 512, 256, 0.5, 0.0 );
C3D_ImmSendAttrib( 0.0, 1.0, 0.0, 0.0 );
C3D_ImmDrawEnd( );
}