akmenu-next/arm9/source/gdi.cpp
2024-10-04 22:35:39 -07:00

673 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
gdi.cpp
Copyright (C) 2007 Acekard, www.acekard.com
Copyright (C) 2007-2009 somebody
Copyright (C) 2009 yellow wood goblin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include <cstdio>
#include "dbgtool.h"
#include "gdi.h"
#include "sprite.h"
#include "../../share/memtool.h"
#include "userinput.h"
#include "globalsettings.h"
#include "fontfactory.h"
static inline void dmaCopyWordsGdi(uint8 channel,const void* src,void* dest,uint32 size)
{
DC_FlushRange(src,size);
dmaCopyWords(channel,src,dest,size);
DC_InvalidateRange(dest,size);
}
#ifdef DEBUG
PrintConsole custom_console;
static void MyInitConsole(u16* aBufferSub1,u16* aBufferSub2)
{
custom_console=*consoleGetDefault();
custom_console.loadGraphics=false;
consoleInit(&custom_console, custom_console.bgLayer, BgType_Text4bpp, BgSize_T_256x256, custom_console.mapBase, custom_console.gfxBase, false, false);
custom_console.fontBgMap=aBufferSub1;
custom_console.fontBgGfx=aBufferSub2;
dmaCopy(custom_console.font.gfx, custom_console.fontBgGfx, custom_console.font.numChars * 64 / 2);
custom_console.fontCurPal = 15 << 12;
u16* palette = BG_PALETTE_SUB;
palette[1 * 16 - 15] = RGB15(0,0,0); //30 normal black
palette[2 * 16 - 15] = RGB15(15,0,0); //31 normal red
palette[3 * 16 - 15] = RGB15(0,15,0); //32 normal green
palette[4 * 16 - 15] = RGB15(15,15,0); //33 normal yellow
palette[5 * 16 - 15] = RGB15(0,0,15); //34 normal blue
palette[6 * 16 - 15] = RGB15(15,0,15); //35 normal magenta
palette[7 * 16 - 15] = RGB15(0,15,15); //36 normal cyan
palette[8 * 16 - 15] = RGB15(24,24,24); //37 normal white
palette[9 * 16 - 15] = RGB15(15,15,15); //40 bright black
palette[10 * 16 - 15] = RGB15(31,0,0); //41 bright red
palette[11 * 16 - 15] = RGB15(0,31,0); //42 bright green
palette[12 * 16 - 15] = RGB15(31,31,0); //43 bright yellow
palette[13 * 16 - 15] = RGB15(0,0,31); //44 bright blue
palette[14 * 16 - 15] = RGB15(31,0,31); //45 bright magenta
palette[15 * 16 - 15] = RGB15(0,31,31); //46 bright cyan
palette[16 * 16 - 15] = RGB15(31,31,31); //47 & 39 bright white
}
#endif
cGdi::cGdi()
{
_transColor=0;
_mainEngineLayer=MEL_UP;
_subEngineMode=SEM_TEXT;
_bufferMain2=NULL;
_bufferSub2=NULL;
#ifdef DEBUG
_bufferSub3=NULL;
#endif
_sprites=NULL;
}
cGdi::~cGdi()
{
if( NULL != _bufferMain2 )
delete[] _bufferMain2;
if( NULL != _bufferSub2 )
delete[] _bufferSub2;
#ifdef DEBUG
if( NULL != _bufferSub3 )
delete[] _bufferSub3;
#endif
if( NULL != _sprites )
delete[] _sprites;
}
void cGdi::init()
{
swapLCD();
activeFbMain();
activeFbSub();
cSprite::sysinit();
}
void cGdi::initBg(const std::string& aFileName)
{
_sprites=new cSprite[12];
_background=createBMP15FromFile(aFileName);
if(_background.width()<SCREEN_WIDTH&&_background.height()<SCREEN_WIDTH)
{
_background=createBMP15(SCREEN_WIDTH,SCREEN_HEIGHT);
zeroMemory(_background.buffer(),_background.height()*_background.pitch());
}
u32 pitch=_background.pitch()>>1;
for(size_t ii=0;ii<3;++ii)
{
for(size_t jj=0;jj<4;++jj)
{
size_t index=ii*4+jj;
_sprites[index].init(2+index);
_sprites[index].setSize(SS_SIZE_64);
_sprites[index].setPriority(3);
_sprites[index].setBufferOffset(32+index*64);
_sprites[index].setPosition(jj*64,ii*64);
for(size_t kk=0;kk<64;++kk)
{
for(size_t ll=0;ll<64;++ll)
{
((u16*)_sprites[index].buffer())[kk*64+ll]=((u16*)_background.buffer())[(kk+ii*64)*pitch+(ll+jj*64)];
}
}
_sprites[index].show();
}
}
}
void cGdi::swapLCD(void)
{
lcdSwap();
}
void cGdi::activeFbMain(void)
{
vramSetBankB( VRAM_B_MAIN_BG_0x06000000 );
vramSetBankD( VRAM_D_MAIN_BG_0x06020000 );
vramSetBankA( VRAM_A_MAIN_SPRITE_0x06400000 );
REG_BG2CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
REG_BG2PA = 1 << 8; // 2 =<3D>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
REG_BG2PD = 1 << 8; // 2 =<3D>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
REG_BG2PB = 0;
REG_BG2PC = 0;
REG_BG2Y = 0;
REG_BG2X = 0;
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY_2;
REG_BG3PA = 1 << 8; // 2 =<3D>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
REG_BG3PD = 1 << 8; // 2 =<3D>Ŵ<EFBFBD><C5B4><EFBFBD><EFBFBD><EFBFBD>
REG_BG3PB = 0;
REG_BG3PC = 0;
REG_BG3Y = 0;
REG_BG3X = 0;
_bufferMain1 = (u16 *)0x06000000;
_bufferMain2 = (u16 *)new u32[256*192];
_bufferMain3 = (u16 *)0x06020000;
setMainEngineLayer( MEL_UP );
zeroMemory( _bufferMain1, 0x20000 );
//fillMemory( _bufferMain3, 0x20000, 0x8f008f00 );
fillMemory( _bufferMain3, 0x20000, 0xffffffff );
REG_BLDCNT = BLEND_ALPHA | BLEND_DST_BG2 | BLEND_DST_BG3;
REG_BLDALPHA = (4 << 8) | 7;
swiWaitForVBlank(); //remove tearing at bottop screen
videoSetMode( MODE_5_2D
| DISPLAY_BG2_ACTIVE
| DISPLAY_BG3_ACTIVE
| DISPLAY_SPR_ACTIVE
| DISPLAY_SPR_1D_BMP_SIZE_128
| DISPLAY_SPR_1D_BMP );
}
void cGdi::activeFbSub(void)
{
#ifdef DEBUG
_bufferSub3 = (u16 *)new u32[0x1200];
MyInitConsole(_bufferSub3+0x2000,_bufferSub3);
#endif
// <20><><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>棬 128k
vramSetBankC( VRAM_C_SUB_BG_0x06200000 ); // 128k
// <20><>ʼ<EFBFBD><CABC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ģʽ
_subEngineMode = SEM_GRAPHICS;
//_subEngineMode = SEM_TEXT;
// BMP bg <20>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD> VRAM<41><4D>ַ 0x06200000 <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>3
REG_BG2CNT_SUB = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
REG_BG2PA_SUB = 1<<8;
REG_BG2PD_SUB = 1<<8;
REG_BG2PB_SUB = 0;
REG_BG2PC_SUB = 0;
REG_BG2Y_SUB = 0;
REG_BG2X_SUB = 0;
_bufferSub1 = (u16 *)0x06200000;
_bufferSub2 = (u16 *)new u32[256*192/2];
//fillMemory( _bufferSub2, 0x18000, 0xfc00fc00 );
//fillMemory( _bufferSub1, 0x18000, 0xfc00fc00 );
fillMemory( _bufferSub2, 0x18000, 0xffffffff );
fillMemory( _bufferSub1, 0x18000, 0xffffffff );
// text BG
// text bg <20><><EFBFBD><EFBFBD>ģռ<C4A3><D5BC> 32(<28>ֽ<EFBFBD>/<2F><>ģ) * 256(<28><>ascii<69><69>) = 8192 <20>ֽ<EFBFBD><D6BD>Դ棬
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾռ<CABE><D5BC> 32 x 32 * 2 = 2048 <20>ֽ<EFBFBD><D6BD>Դ<EFBFBD>
// <20><>ģ<EFBFBD><C4A3> block 8 <20><>ʼ = 0x06200000 + 8 * 0x4000 = 0x06220000
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2> block 72 <20><>ʼ = 0x06200000 + 72 * 0x800 = 0x06224000
// <20><><EFBFBD>ȼ<EFBFBD> 2
#ifdef DEBUG
BG_PALETTE_SUB[255] = RGB15(31,31,31); //by default font will be rendered with color 255
REG_BG0CNT_SUB = BG_TILE_BASE(0) | BG_MAP_BASE(8) | BG_PRIORITY_2;
#endif
swiWaitForVBlank(); //remove tearing at top screen
// ģʽ5<CABD><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BG<42><47>һ<EFBFBD><D2BB>BMP<4D><50>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>)<29><>bmp<6D><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>Ϲر<CFB9>
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );// | DISPLAY_BG2_ACTIVE );
}
void cGdi::drawLine( s16 x1, s16 y1, s16 x2, s16 y2, GRAPHICS_ENGINE engine )
{
if((x1==x2)&&(y1==y2)) return;
if(x1==x2) {
int ys,ye;
if(y1<y2) {
ys=y1;
ye=y2-1;
} else {
ys=y2+1;
ye=y1;
}
for(int py=ys;py<=ye;py++) {
drawPixel(x1,py,engine);
}
return;
}
if(y1==y2) {
int xs,xe;
if(x1<x2) {
xs=x1;
xe=x2-1;
} else {
xs=x2+1;
xe=x1;
}
//for(int px=xs;px<=xe;px++) {
// drawPixel(px,y1,engine);
// //SetPixel(px,y1,Color);
//}
if( GE_MAIN == engine )
fillRect( _penColor, _penColor, xs, y1, xe - xs + 1, 1, engine );
else
fillRect( _penColorSub, _penColorSub, xs, y1, xe - xs + 1, 1, engine );
return;
}
if(abs(x2-x1)>abs(y2-y1)) {
int px=0;
float py=0;
int xe=x2-x1;
float ye=y2-y1;
int xv;
float yv;
if(0<xe) {
xv=1;
} else {
xv=-1;
}
yv=ye/abs(xe);
while(px!=xe) {
drawPixel(x1+px,y1+(int)py,engine);
px+=xv;
py+=yv;
}
return;
}
else {
float px=0;
int py=0;
float xe=x2-x1;
int ye=y2-y1;
float xv;
int yv;
xv=xe/abs(ye);
if(0<ye) {
yv=1;
} else {
yv=-1;
}
while(py!=ye) {
//if(AALineFlag==false){
drawPixel(x1+(int)px,y1+py,engine);
//}else{
// int Alpha=(int)(px*32);
// if(Alpha<0){
// while(Alpha<=0) Alpha+=32;
// }else{
// while(32<=Alpha) Alpha-=32;
// }
// SetPixelAlpha(x1+(int)px+0,y1+py,Color,32-Alpha);
// SetPixelAlpha(x1+(int)px+1,y1+py,Color,Alpha);
//}
px+=xv;
py+=yv;
}
return;
}
}
void cGdi::frameRect( s16 x, s16 y, u16 w, u16 h, GRAPHICS_ENGINE engine )
{
drawLine( x, y, x + w - 1, y, engine );
drawLine( x + w - 1, y, x + w - 1, y + h - 1, engine );
drawLine( x + w - 1, y + h - 1, x, y + h - 1, engine );
drawLine( x, y + h - 1, x, y, engine );
}
void cGdi::frameRect( s16 x, s16 y, u16 w, u16 h, u16 thickness, GRAPHICS_ENGINE engine )
{
for(size_t ii=0;ii<thickness;++ii)
{
frameRect(x,y,w,h,engine);
if(h<=2||w<=2) break;
++x; ++y; w-=2; h-=2;
}
}
void cGdi::fillRect( u16 color1, u16 color2, s16 x, s16 y, u16 w, u16 h, GRAPHICS_ENGINE engine )
{
ALIGN(4) u16 color[2] = { BIT(15) | color1 , BIT(15) | color2 };
u16 * pSrc = (u16 *)color;
u16 * pDest = NULL;
if( GE_MAIN == engine )
pDest = _bufferMain2 + (y << 8) + x + _layerPitch;//_bufferMain2 + y * 256 + x + _layerPitch;
else
pDest = _bufferSub2 + (y << 8) + x; //_bufferSub2 + y * 256 + x;
bool destAligned = !(x & 1);
u16 destInc = 256 - w;
u16 halfWidth = w >> 1;
u16 remain = w & 1;
if( destAligned )
for( u32 i = 0; i < h; ++i ) {
swiFastCopy( pSrc, pDest, COPY_MODE_WORD | COPY_MODE_FILL | halfWidth );
pDest += halfWidth << 1;
if( remain )
*pDest++ = *pSrc;
pDest += destInc;
}
else
for( u32 i = 0; i < h; ++i ) {
for( u32 j = 0; j < w; ++j ) {
*pDest++ = pSrc[j&1];
}
pDest += destInc;
}
}
void cGdi::fillRectBlend( u16 color1, u16 color2, s16 x, s16 y, u16 w, u16 h, GRAPHICS_ENGINE engine, u16 opacity)
{
if(opacity==0) return;
if(opacity==100)
{
fillRect(color1,color2,x,y,w,h,engine);
return;
}
u16* pSrc=((GE_MAIN==engine)?(u16*)_background.buffer():_bufferSub2)+(y<<8)+x;
u16* pDest=((GE_MAIN==engine)?(_bufferMain2+_layerPitch):_bufferSub2)+(y<<8)+x;
u32 alpha=(opacity*32)/100;
u32 destInc=256-w;
for(u32 ii=0;ii<h;++ii)
{
for(u32 jj=0;jj<w;++jj)
{
u32 original=*pSrc++&0x7fff;
u32 color=(jj&1)?color2:color1;
u32 rb=((color&0x7c1f)*alpha+(original&0x7c1f)*(32-alpha))&0xf83e0;
u32 g=((color&0x3e0)*alpha+(original&0x3e0)*(32-alpha))&0x7c00;
*pDest++=((rb|g)>>5)|BIT(15);
}
pDest+=destInc;
pSrc+=destInc;
}
}
void cGdi::bitBlt( const void * src, s16 srcW, s16 srcH, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine )
{
if( destW <= 0 )
return;
u16 * pSrc = (u16 *)src;
u16 * pDest = NULL;
if( GE_MAIN == engine )
pDest = _bufferMain2 + (destY) * 256 + destX + _layerPitch;
else
pDest = _bufferSub2 + (destY) * 256 + destX;
bool destAligned = !(destX & 1);
if( destW > srcW )
destW = srcW;
if( destH > srcH )
destH = srcH;
u16 srcInc = srcW - destW;
u16 destInc = 256 - destW;
u16 destHalfWidth = destW >> 1;
u16 lineSize = destW << 1;
u16 remain = destW & 1;
if( destAligned ) {
for( u32 i = 0; i < destH; ++i ) {
dmaCopyWordsGdi( 3, pSrc, pDest, lineSize );
pDest += destHalfWidth << 1;
pSrc += destHalfWidth << 1;
if( remain )
*pDest++ = *pSrc++;
pDest += destInc;
pSrc += srcInc;
}
}
}
void cGdi::bitBlt( const void * src, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine )
{
//dbg_printf("x %d y %d w %d h %d\n", destX, destY, destW, destH );
u16 * pSrc = (u16 *)src;
u16 * pDest = NULL;
if( GE_MAIN == engine )
pDest = _bufferMain2 + (destY) * 256 + destX + _layerPitch;
else
pDest = _bufferSub2 + (destY) * 256 + destX;
u16 pitchPixel = (destW + (destW & 1));
u16 destInc = 256 - pitchPixel;
u16 halfPitch = pitchPixel >> 1;
u16 remain = pitchPixel & 1;
for( u16 i = 0; i < destH; ++i ) {
swiFastCopy( pSrc, pDest, COPY_MODE_WORD | COPY_MODE_COPY | halfPitch );
pDest += halfPitch << 1;
pSrc += halfPitch << 1;
if( remain )
*pDest++ = *pSrc++;
pDest += destInc;
}
}
// maskBlt ҪdestW<74><57>ż<EFBFBD><C5BC><EFBFBD><EFBFBD><EFBFBD>ٶȿ<D9B6><C8BF>Կ<EFBFBD>һ<EFBFBD><D2BB>
// <20><><EFBFBD><EFBFBD>ż<EFBFBD><C5BC>Ҳ<EFBFBD><D2B2><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> src <20><> pitch <20>ճ<EFBFBD>ż<EFBFBD><C5BC>
void cGdi::maskBlt( const void * src, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine )
{
//dbg_printf("x %d y %d w %d h %d\n", destX, destY, destW, destH );
u16 * pSrc = (u16 *)src;
u16 * pDest = NULL;
bool destAligned = !(destX & 1);
if( GE_MAIN == engine )
pDest = _bufferMain2 + (destY) * 256 + destX + _layerPitch;
else
pDest = _bufferSub2 + (destY) * 256 + destX;
u16 pitch = (destW + (destW & 1));
u16 destInc = 256 - pitch;
u16 halfPitch = pitch >> 1;
if( destAligned )
for( u32 i = 0; i < destH; ++i ) {
for( u32 j = 0; j < halfPitch; ++j ) {
if( ((*(u32 *)pSrc) & 0x80008000) == 0x80008000 ) {
*(u32 *)pDest = *(u32 *)pSrc;
pSrc += 2; pDest += 2;
}
else {
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pSrc++; pDest++;
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pSrc++; pDest++;
}
}
pDest += destInc;
}
else
for( u16 i = 0; i < destH; ++i ) {
for( u16 j = 0; j < pitch; ++j ) {
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pDest++; pSrc++;
}
pDest += destInc;
}
}
void cGdi::maskBlt( const void * src, s16 srcW, s16 srcH, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine )
{
if( destW <= 0 )
return;
u16 * pSrc = (u16 *)src;
u16 * pDest = NULL;
if( GE_MAIN == engine )
pDest = _bufferMain2 + (destY) * 256 + destX + _layerPitch;
else
pDest = _bufferSub2 + (destY) * 256 + destX;
bool destAligned = !(destX & 1);
if( destW > srcW )
destW = srcW;
if( destH > srcH )
destH = srcH;
u16 srcInc = srcW - destW;
u16 destInc = 256 - destW;
u16 destHalfWidth = destW >> 1;
u16 pitch = (destW + (destW & 1));
u16 remain = destW & 1;
if( destAligned ) {
for( u32 i = 0; i < destH; ++i ) {
for( u32 j = 0; j < destHalfWidth; ++j ) {
if( ((*(u32 *)pSrc) & 0x80008000) == 0x80008000 ) {
*(u32 *)pDest = *(u32 *)pSrc;
pSrc += 2; pDest += 2;
}
else {
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pSrc++; pDest++;
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pSrc++; pDest++;
}
}
if( remain )
*pDest++ = *pSrc++;
pDest += destInc;
pSrc += srcInc;
}
}
else
for( u16 i = 0; i < destH; ++i ) {
for( u16 j = 0; j < pitch; ++j ) {
if( *pSrc & 0x8000 )
*pDest = *pSrc;
pDest++; pSrc++;
}
pDest += destInc;
pSrc += srcInc;
}
}
void cGdi::textOutRect( s16 x, s16 y, u16 w, u16 h, const char * text, GRAPHICS_ENGINE engine )
{
const s16 originX=x,limitY=y+h-gs().fontHeight;
while(*text)
{
if('\r'==*text||'\n'==*text)
{
y+=gs().fontHeight; //FIXME
x=originX;
++text;
if(y>limitY) break;
}
else
{
u32 ww,add;
font().Info(text,&ww,&add);
if(x+(s16)ww<originX+w)
{
font().Draw((GE_MAIN==engine)?(_bufferMain2+_layerPitch):_bufferSub2,x,y,(const u8*)text,(GE_MAIN==engine)?_penColor:_penColorSub);
}
text+=add;
x+=ww;
}
}
}
void cGdi::present( GRAPHICS_ENGINE engine )
{
if( GE_MAIN == engine ) { // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//u16 * temp = _bufferMain1;
//_bufferMain1 = _bufferMain2;
//_bufferMain2 = temp;
//REG_BG2CNT ^= BG_BMP_BASE( 128 / 16 );
dmaCopyWordsGdi( 3, _bufferMain2 + _layerPitch,
_bufferMain1 + (_mainEngineLayer << 16), 256 * 192 * 2 );
fillMemory( (void *)(_bufferMain2 + _layerPitch), 256 * 192 * 2, 0 );
} else if ( GE_SUB == engine ) { // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( SEM_GRAPHICS == _subEngineMode )
dmaCopyWordsGdi( 3, (void *)_bufferSub2, (void *)_bufferSub1, 256 * 192 * 2 );
//else if( SEM_TEXT == _subEngineMode )
// dmaCopyWords( 3, (void *)_bufferSub3, (void *)_bufferSub1, 32768 );
fillMemory( (void *)_bufferSub2, 0x18000, 0xffffffff );
}
//dbg_printf( "\x1b[0;20%f\n", updateTimer() );
}
//special version for window switching
void cGdi::present(void)
{
swiWaitForVBlank();
dmaCopyWordsGdi(3,_bufferMain2,_bufferMain1,256*192*2);
dmaCopyWordsGdi(3,_bufferMain2+(256*192),_bufferMain1+(1<<16),256*192*2);
fillMemory((void *)_bufferMain2,256*192*4,0);
}
#ifdef DEBUG
void cGdi::switchSubEngineMode()
{
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ͻָ<CDBB><D6B8>ı<EFBFBD>ģʽ<C4A3><CABD><EFBFBD>ֳ<EFBFBD>
switch( _subEngineMode )
{
case SEM_GRAPHICS: // <20><>ǰ<EFBFBD><C7B0>ͼ<EFBFBD><CDBC>ģʽ<C4A3>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD>ͻָ<CDBB><D6B8>ղŵ<D5B2>text<78>ֳ<EFBFBD>
videoSetModeSub( MODE_5_2D | DISPLAY_BG0_ACTIVE );
custom_console.fontBgMap=(u16*)0x6204000;
custom_console.fontBgGfx=(u16*)0x6200000;
dmaCopyWordsGdi( 3, (void *)_bufferSub3, (void *)_bufferSub1, 0x4800 );
break;
case SEM_TEXT: // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD>е<EFBFBD>ͼ<EFBFBD><CDBC>ģʽ
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );
custom_console.fontBgMap=_bufferSub3+0x2000;
custom_console.fontBgGfx=_bufferSub3;
dmaCopyWordsGdi( 3, (void *)_bufferSub1, (void *)_bufferSub3, 0x4800 );
break;
};
_subEngineMode = (SUB_ENGINE_MODE)(_subEngineMode^1);
}
#endif