GTK: make OSD scalable (#769)
* gtk: make OSD scalable * Scale save slot indicator (oops), make text outlines look smoother, use larger font when not scaling * Save and load HUD layout, prefer raster font on low resolution, select vector font size close to raster one, make OSDCLASS::scale floating point * Build fix * Add reset HUD layout action, only require fontconfig if libagg is found. * Try another font in case we could not locate monospace * Detect screen bytes per pixel instead of hardcoding it, define AGG2D_USE_VECTORFONTS if fontconfig is found. * Different pixel formats are handled by different draw target implementations
This commit is contained in:
parent
6508c2b115
commit
45738beb88
|
@ -1370,6 +1370,17 @@ AGG2D_TEMPLATE void TAGG2D::text(double x, double y, const wchar_t* str, unsigne
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
AGG2D_TEMPLATE double TAGG2D::textWidth(const char* str)
|
||||
{
|
||||
return textWidth(str, (unsigned int)strlen(str));
|
||||
}
|
||||
|
||||
AGG2D_TEMPLATE void TAGG2D::text(double x, double y, const char* str, bool roundOff, double dx, double dy)
|
||||
{
|
||||
text(x, y, str, (unsigned int)strlen(str), roundOff, dx, dy);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -1945,11 +1956,11 @@ AGG2D_TEMPLATE void TAGG2D::render(FontRasterizer& ras, FontScanline& sl)
|
|||
{
|
||||
if(m_blendMode == BlendAlpha)
|
||||
{
|
||||
Agg2DRenderer::render(*this, m_renBase, m_renSolid, ras, sl);
|
||||
Agg2DRenderer<PixFormatSet, PixFormatSet>::render(*this, m_renBase, m_renSolid, ras, sl);
|
||||
}
|
||||
else
|
||||
{
|
||||
Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, ras, sl);
|
||||
Agg2DRenderer<PixFormatSet, PixFormatSet>::render(*this, m_renBaseComp, m_renSolidComp, ras, sl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,13 +50,23 @@ static s64 hudTimer;
|
|||
|
||||
static void SetHudDummy (HudCoordinates *hud)
|
||||
{
|
||||
hud->x=666;
|
||||
hud->y=666;
|
||||
hud->x=-666;
|
||||
hud->y=-666;
|
||||
}
|
||||
|
||||
static bool IsHudDummy (HudCoordinates *hud)
|
||||
{
|
||||
return (hud->x == 666 && hud->y == 666);
|
||||
return (hud->x == -666 && hud->y == -666);
|
||||
}
|
||||
|
||||
static int ScreenWidth()
|
||||
{
|
||||
return 256*osd->scale;
|
||||
}
|
||||
|
||||
static int ScreenHeight()
|
||||
{
|
||||
return 192*osd->scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -64,21 +74,47 @@ static T calcY(T y) // alters a GUI element y coordinate as necessary to obey sw
|
|||
{
|
||||
if(osd->singleScreen)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
if(y >= ScreenHeight())
|
||||
y -= ScreenHeight();
|
||||
if(osd->swapScreens)
|
||||
y += 192;
|
||||
y += ScreenHeight();
|
||||
}
|
||||
else if(osd->swapScreens)
|
||||
{
|
||||
if(y >= 192)
|
||||
y -= 192;
|
||||
if(y >= ScreenHeight())
|
||||
y -= ScreenHeight();
|
||||
else
|
||||
y += 192;
|
||||
y += ScreenHeight();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
static void RenderTextAutoVector(double x, double y, const std::string& str, bool shadow = true, double shadowOffset = 1.0)
|
||||
{
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
bool render_vect = false;
|
||||
if(osd)
|
||||
if(osd->useVectorFonts)
|
||||
render_vect = true;
|
||||
if(render_vect)
|
||||
{
|
||||
if(shadow)
|
||||
aggDraw.hud->renderVectorFontTextDropshadowed(x, y, str, shadowOffset);
|
||||
else
|
||||
aggDraw.hud->renderVectorFontText(x, y, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if(shadow)
|
||||
aggDraw.hud->renderTextDropshadowed(x, y, str);
|
||||
else
|
||||
aggDraw.hud->renderText(x, y, str);
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void EditHud(s32 x, s32 y, HudStruct *hudstruct) {
|
||||
|
||||
u32 i = 0;
|
||||
|
@ -108,8 +144,10 @@ void EditHud(s32 x, s32 y, HudStruct *hudstruct) {
|
|||
//sanity checks
|
||||
if(hud.x < 0) hud.x = 0;
|
||||
if(hud.y < 0) hud.y = 0;
|
||||
if(hud.x > 245)hud.x = 245; //margins
|
||||
if(hud.y > 384-16)hud.y = 384-16;
|
||||
if(hud.x > ScreenWidth()-11*osd->scale)
|
||||
hud.x = ScreenWidth()-11*osd->scale; //margins
|
||||
if(hud.y > ScreenHeight()*2-16*osd->scale)
|
||||
hud.y = ScreenHeight()*2-16*osd->scale;
|
||||
|
||||
if(hud.clicked)
|
||||
{
|
||||
|
@ -136,45 +174,47 @@ void HudClickRelease(HudStruct *hudstruct) {
|
|||
|
||||
void HudStruct::reset()
|
||||
{
|
||||
double sc=(osd ? osd->scale : 1.0);
|
||||
|
||||
FpsDisplay.x=0;
|
||||
FpsDisplay.y=5;
|
||||
FpsDisplay.xsize=166;
|
||||
FpsDisplay.ysize=10;
|
||||
FpsDisplay.y=5*sc;
|
||||
FpsDisplay.xsize=166*sc;
|
||||
FpsDisplay.ysize=10*sc;
|
||||
|
||||
FrameCounter.x=0;
|
||||
FrameCounter.y=25;
|
||||
FrameCounter.xsize=60;
|
||||
FrameCounter.ysize=10;
|
||||
FrameCounter.y=25*sc;
|
||||
FrameCounter.xsize=60*sc;
|
||||
FrameCounter.ysize=10*sc;
|
||||
|
||||
InputDisplay.x=0;
|
||||
InputDisplay.y=45;
|
||||
InputDisplay.xsize=220;
|
||||
InputDisplay.ysize=10;
|
||||
InputDisplay.y=45*sc;
|
||||
InputDisplay.xsize=220*sc;
|
||||
InputDisplay.ysize=10*sc;
|
||||
|
||||
GraphicalInputDisplay.x=8;
|
||||
GraphicalInputDisplay.y=328;
|
||||
GraphicalInputDisplay.xsize=102;
|
||||
GraphicalInputDisplay.ysize=50;
|
||||
GraphicalInputDisplay.x=8*sc;
|
||||
GraphicalInputDisplay.y=328*sc;
|
||||
GraphicalInputDisplay.xsize=102*sc;
|
||||
GraphicalInputDisplay.ysize=50*sc;
|
||||
|
||||
LagFrameCounter.x=0;
|
||||
LagFrameCounter.y=65;
|
||||
LagFrameCounter.xsize=30;
|
||||
LagFrameCounter.ysize=10;
|
||||
LagFrameCounter.y=65*sc;
|
||||
LagFrameCounter.xsize=30*sc;
|
||||
LagFrameCounter.ysize=10*sc;
|
||||
|
||||
Microphone.x=0;
|
||||
Microphone.y=85;
|
||||
Microphone.xsize=20;
|
||||
Microphone.ysize=10;
|
||||
Microphone.y=85*sc;
|
||||
Microphone.xsize=20*sc;
|
||||
Microphone.ysize=10*sc;
|
||||
|
||||
RTCDisplay.x=0;
|
||||
RTCDisplay.y=105;
|
||||
RTCDisplay.xsize=220;
|
||||
RTCDisplay.ysize=10;
|
||||
RTCDisplay.y=105*sc;
|
||||
RTCDisplay.xsize=220*sc;
|
||||
RTCDisplay.ysize=10*sc;
|
||||
|
||||
SavestateSlots.x = 8;
|
||||
SavestateSlots.y = 160;
|
||||
SavestateSlots.xsize = 240;
|
||||
SavestateSlots.ysize = 24;
|
||||
SavestateSlots.x = 8*sc;
|
||||
SavestateSlots.y = 160*sc;
|
||||
SavestateSlots.xsize = 240*sc;
|
||||
SavestateSlots.ysize = 24*sc;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define AGG_OSD_SETTING(which,comp) which.comp = GetPrivateProfileInt("HudEdit", #which "." #comp, which.comp, IniName);
|
||||
|
@ -186,6 +226,51 @@ void HudStruct::reset()
|
|||
clicked = false;
|
||||
}
|
||||
|
||||
void HudStruct::rescale(double oldScale, double newScale)
|
||||
{
|
||||
double sc=newScale/oldScale;
|
||||
|
||||
FpsDisplay.x*=sc;
|
||||
FpsDisplay.y*=sc;
|
||||
FpsDisplay.xsize*=sc;
|
||||
FpsDisplay.ysize*=sc;
|
||||
|
||||
FrameCounter.x*=sc;
|
||||
FrameCounter.y*=sc;
|
||||
FrameCounter.xsize*=sc;
|
||||
FrameCounter.ysize*=sc;
|
||||
|
||||
InputDisplay.x*=sc;
|
||||
InputDisplay.y*=sc;
|
||||
InputDisplay.xsize*=sc;
|
||||
InputDisplay.ysize*=sc;
|
||||
|
||||
GraphicalInputDisplay.x*=sc;
|
||||
GraphicalInputDisplay.y*=sc;
|
||||
GraphicalInputDisplay.xsize*=sc;
|
||||
GraphicalInputDisplay.ysize*=sc;
|
||||
|
||||
LagFrameCounter.x*=sc;
|
||||
LagFrameCounter.y*=sc;
|
||||
LagFrameCounter.xsize*=sc;
|
||||
LagFrameCounter.ysize*=sc;
|
||||
|
||||
Microphone.x*=sc;
|
||||
Microphone.y*=sc;
|
||||
Microphone.xsize*=sc;
|
||||
Microphone.ysize*=sc;
|
||||
|
||||
RTCDisplay.x*=sc;
|
||||
RTCDisplay.y*=sc;
|
||||
RTCDisplay.xsize*=sc;
|
||||
RTCDisplay.ysize*=sc;
|
||||
|
||||
SavestateSlots.x*=sc;
|
||||
SavestateSlots.y*=sc;
|
||||
SavestateSlots.xsize*=sc;
|
||||
SavestateSlots.ysize*=sc;
|
||||
}
|
||||
|
||||
static void joyFill(int n) {
|
||||
|
||||
bool pressedForGame = NDS_getFinalUserInput().buttons.array[n];
|
||||
|
@ -235,8 +320,8 @@ static void drawPad(double x, double y, double ratio) {
|
|||
// aligning to odd half-pixel boundaries prevents agg2d from blurring thin straight lines
|
||||
x = floor(x) + 0.5;
|
||||
y = floor(calcY(y)) + 0.5;
|
||||
double xc = 41 - 0.5;
|
||||
double yc = 20 - 0.5;
|
||||
double xc = 41*osd->scale - 0.5;
|
||||
double yc = 20*osd->scale - 0.5;
|
||||
|
||||
aggDraw.hud->lineColor(128,128,128,255);
|
||||
|
||||
|
@ -252,12 +337,12 @@ static void drawPad(double x, double y, double ratio) {
|
|||
aggDraw.hud->roundedRect (screenLeft, screenTop, screenRight, screenBottom, 1);
|
||||
|
||||
|
||||
joyEllipse(.89,.45,xc,yc,x,y,ratio,1,6);//B
|
||||
joyEllipse(.89,.22,xc,yc,x,y,ratio,1,3);//X
|
||||
joyEllipse(.83,.34,xc,yc,x,y,ratio,1,4);//Y
|
||||
joyEllipse(.95,.34,xc,yc,x,y,ratio,1,5);//A
|
||||
joyEllipse(.82,.716,xc,yc,x,y,ratio,.5,7);//Start
|
||||
joyEllipse(.82,.842,xc,yc,x,y,ratio,.5,8);//Select
|
||||
joyEllipse(.89,.45,xc,yc,x,y,ratio,osd->scale,6);//B
|
||||
joyEllipse(.89,.22,xc,yc,x,y,ratio,osd->scale,3);//X
|
||||
joyEllipse(.83,.34,xc,yc,x,y,ratio,osd->scale,4);//Y
|
||||
joyEllipse(.95,.34,xc,yc,x,y,ratio,osd->scale,5);//A
|
||||
joyEllipse(.82,.716,xc,yc,x,y,ratio,osd->scale * .5,7);//Start
|
||||
joyEllipse(.82,.842,xc,yc,x,y,ratio,osd->scale * .5,8);//Select
|
||||
|
||||
|
||||
double dpadPoints [][2] = {
|
||||
|
@ -311,29 +396,29 @@ static void drawPad(double x, double y, double ratio) {
|
|||
// touch pad
|
||||
{
|
||||
BOOL gameTouchOn = nds.isTouch;
|
||||
double gameTouchX = screenLeft+1 + (nds.scr_touchX * 0.0625) * (screenRight - screenLeft - 2) / 256.0;
|
||||
double gameTouchY = screenTop+1 + (nds.scr_touchY * 0.0625) * (screenBottom - screenTop - 2) / 192.0;
|
||||
double gameTouchX = screenLeft+1 + (nds.scr_touchX * osd->scale * 0.0625) * (screenRight - screenLeft - 2) / (double)ScreenWidth();
|
||||
double gameTouchY = screenTop+1 + (nds.scr_touchY * osd->scale * 0.0625) * (screenBottom - screenTop - 2) / (double)ScreenHeight();
|
||||
bool physicalTouchOn = NDS_getRawUserInput().touch.isTouch;
|
||||
double physicalTouchX = screenLeft+1 + (NDS_getRawUserInput().touch.touchX * 0.0625) * (screenRight - screenLeft - 2) / 256.0;
|
||||
double physicalTouchY = screenTop+1 + (NDS_getRawUserInput().touch.touchY * 0.0625) * (screenBottom - screenTop - 2) / 192.0;
|
||||
double physicalTouchX = screenLeft+1 + (NDS_getRawUserInput().touch.touchX * osd->scale * 0.0625) * (screenRight - screenLeft - 2) / (double)ScreenWidth();
|
||||
double physicalTouchY = screenTop+1 + (NDS_getRawUserInput().touch.touchY * osd->scale * 0.0625) * (screenBottom - screenTop - 2) / (double)ScreenHeight();
|
||||
if(gameTouchOn && physicalTouchOn && gameTouchX == physicalTouchX && gameTouchY == physicalTouchY)
|
||||
{
|
||||
aggDraw.hud->fillColor(0,0,0,255);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, ratio*0.37, ratio*0.37);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, osd->scale*ratio*0.37, osd->scale*ratio*0.37);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(physicalTouchOn)
|
||||
{
|
||||
aggDraw.hud->fillColor(0,0,0,128);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, ratio*0.5, ratio*0.5);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, osd->scale*ratio*0.5, osd->scale*ratio*0.5);
|
||||
aggDraw.hud->fillColor(0,255,0,255);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, ratio*0.37, ratio*0.37);
|
||||
aggDraw.hud->ellipse(physicalTouchX, physicalTouchY, osd->scale*ratio*0.37, osd->scale*ratio*0.37);
|
||||
}
|
||||
if(gameTouchOn)
|
||||
{
|
||||
aggDraw.hud->fillColor(255,0,0,255);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, ratio*0.37, ratio*0.37);
|
||||
aggDraw.hud->ellipse(gameTouchX, gameTouchY, osd->scale*ratio*0.37, osd->scale*ratio*0.37);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +465,7 @@ static void TextualInputDisplay() {
|
|||
std::string str(buttonChars+i, 2);
|
||||
str[1] = '\0';
|
||||
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
RenderTextAutoVector(x, calcY(Hud.InputDisplay.y), str, true, osd ? osd->scale : 1);
|
||||
}
|
||||
|
||||
// touch pad
|
||||
|
@ -396,7 +481,7 @@ static void TextualInputDisplay() {
|
|||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y), str);
|
||||
RenderTextAutoVector(x, calcY(Hud.InputDisplay.y), str, true, osd ? osd->scale : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -404,13 +489,13 @@ static void TextualInputDisplay() {
|
|||
{
|
||||
sprintf(str, "%d,%d", gameTouchX, gameTouchY);
|
||||
aggDraw.hud->lineColor(255,48,48,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)-(physicalTouchOn?8:0), str);
|
||||
RenderTextAutoVector(x, calcY(Hud.InputDisplay.y)-(physicalTouchOn?8:0), str, true, osd ? osd->scale : 1);
|
||||
}
|
||||
if(physicalTouchOn)
|
||||
{
|
||||
sprintf(str, "%d,%d", physicalTouchX, physicalTouchY);
|
||||
aggDraw.hud->lineColor(0,192,0,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x, calcY(Hud.InputDisplay.y)+(gameTouchOn?8:0), str);
|
||||
RenderTextAutoVector(x, calcY(Hud.InputDisplay.y)+(gameTouchOn?8:0), str, true, osd ? osd->scale : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -418,10 +503,10 @@ static void TextualInputDisplay() {
|
|||
|
||||
static void OSD_HandleTouchDisplay() {
|
||||
// note: calcY should not be used in this function.
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->lineWidth(osd->scale);
|
||||
|
||||
temptouch.X = NDS_getRawUserInput().touch.touchX >> 4;
|
||||
temptouch.Y = NDS_getRawUserInput().touch.touchY >> 4;
|
||||
temptouch.X = (NDS_getRawUserInput().touch.touchX >> 4) * osd->scale;
|
||||
temptouch.Y = (NDS_getRawUserInput().touch.touchY >> 4) * osd->scale;
|
||||
|
||||
if(touchshadow) {
|
||||
|
||||
|
@ -432,27 +517,27 @@ static void OSD_HandleTouchDisplay() {
|
|||
temptouch = touch[i];
|
||||
if(temptouch.X != 0 || temptouch.Y != 0) {
|
||||
aggDraw.hud->lineColor(0, 255, 0, touchalpha[i]);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
aggDraw.hud->line(temptouch.X - ScreenWidth(), temptouch.Y + ScreenHeight(), temptouch.X + ScreenWidth(), temptouch.Y + ScreenHeight()); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - ScreenWidth(), temptouch.X, temptouch.Y + ScreenHeight()*2); //vert
|
||||
aggDraw.hud->fillColor(0, 0, 0, touchalpha[i]);
|
||||
aggDraw.hud->rectangle(temptouch.X-1, temptouch.Y + 192-1, temptouch.X+1, temptouch.Y + 192+1);
|
||||
aggDraw.hud->rectangle(temptouch.X-1, temptouch.Y + ScreenHeight()-1, temptouch.X+1, temptouch.Y + ScreenHeight()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(NDS_getRawUserInput().touch.isTouch) {
|
||||
aggDraw.hud->lineColor(0, 255, 0, 128);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
aggDraw.hud->line(temptouch.X - ScreenWidth(), temptouch.Y + ScreenHeight(), temptouch.X + ScreenWidth(), temptouch.Y + ScreenHeight()); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - ScreenWidth(), temptouch.X, temptouch.Y + ScreenHeight()*2); //vert
|
||||
}
|
||||
|
||||
if(nds.isTouch)
|
||||
{
|
||||
temptouch.X = nds.scr_touchX / 16;
|
||||
temptouch.Y = nds.scr_touchY / 16;
|
||||
temptouch.X = nds.scr_touchX / 16 * osd->scale;
|
||||
temptouch.Y = nds.scr_touchY / 16 * osd->scale;
|
||||
aggDraw.hud->lineColor(255, 0, 0, 128);
|
||||
aggDraw.hud->line(temptouch.X - 256, temptouch.Y + 192, temptouch.X + 256, temptouch.Y + 192); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - 256, temptouch.X, temptouch.Y + 384); //vert
|
||||
aggDraw.hud->line(temptouch.X - ScreenWidth(), temptouch.Y + ScreenHeight(), temptouch.X + ScreenWidth(), temptouch.Y + ScreenHeight()); //horiz
|
||||
aggDraw.hud->line(temptouch.X, temptouch.Y - ScreenWidth(), temptouch.X, temptouch.Y + ScreenHeight()*2); //vert
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -476,24 +561,24 @@ static void DrawStateSlots(){
|
|||
|
||||
if(alpha!=0)
|
||||
{
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->lineWidth(osd->scale);
|
||||
aggDraw.hud->lineColor(0, 0, 0, alpha);
|
||||
aggDraw.hud->fillColor(255, 255, 255, alpha);
|
||||
|
||||
for ( int i = 0, xpos=0; i < 10; xpos=xpos+24) {
|
||||
for ( int i = 0, xpos=0; i < 10; xpos=xpos+24*osd->scale) {
|
||||
|
||||
int yheight=0;
|
||||
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, xloc + 22 + xpos, yloc + 20 + yheight+20, agg::rgba8(100,200,255,alpha), agg::rgba8(255,255,255,0));
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, xloc + 22*osd->scale + xpos, yloc + 20*osd->scale + yheight+20*osd->scale, agg::rgba8(100,200,255,alpha), agg::rgba8(255,255,255,0));
|
||||
|
||||
if(lastSaveState == i) {
|
||||
yheight = 5;
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, 22 + xloc + xpos, yloc + 20 + yheight+20, agg::rgba8(100,255,255,alpha), agg::rgba8(255,255,255,0));
|
||||
yheight = 5*osd->scale;
|
||||
aggDraw.hud->fillLinearGradient(xloc + xpos, yloc - yheight, 22*osd->scale + xloc + xpos, yloc + 20*osd->scale + yheight+20*osd->scale, agg::rgba8(100,255,255,alpha), agg::rgba8(255,255,255,0));
|
||||
}
|
||||
|
||||
aggDraw.hud->rectangle(xloc + xpos , yloc - yheight, xloc + 22 + xpos , yloc + 20 + yheight);
|
||||
aggDraw.hud->rectangle(xloc + xpos , yloc - yheight, xloc + 22*osd->scale + xpos , yloc + 20*osd->scale + yheight);
|
||||
snprintf(number, 10, "%d", i);
|
||||
aggDraw.hud->renderText(xloc + 1 + xpos + 4, yloc+4, std::string(number));
|
||||
RenderTextAutoVector(xloc + osd->scale + xpos + 4*osd->scale, yloc+4*osd->scale, std::string(number), true, osd->scale);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -511,10 +596,10 @@ static void DrawEditableElementIndicators()
|
|||
HudCoordinates &hud = Hud.hud(i);
|
||||
aggDraw.hud->fillColor(0,0,0,0);
|
||||
aggDraw.hud->lineColor(0,0,0,64);
|
||||
aggDraw.hud->lineWidth(2.0);
|
||||
aggDraw.hud->lineWidth(2.0*osd->scale);
|
||||
aggDraw.hud->rectangle(hud.x,calcY(hud.y),hud.x+hud.xsize+1.0,calcY(hud.y)+hud.ysize+1.0);
|
||||
aggDraw.hud->lineColor(255,hud.clicked?127:255,0,255);
|
||||
aggDraw.hud->lineWidth(1.0);
|
||||
aggDraw.hud->lineWidth(osd->scale);
|
||||
aggDraw.hud->rectangle(hud.x-0.5,calcY(hud.y)-0.5,hud.x+hud.xsize+0.5,calcY(hud.y)+hud.ysize+0.5);
|
||||
i++;
|
||||
}
|
||||
|
@ -624,9 +709,11 @@ OSDCLASS::OSDCLASS(u8 core)
|
|||
|
||||
singleScreen = false;
|
||||
swapScreens = false;
|
||||
|
||||
scale = 1.0;
|
||||
needUpdate = false;
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
useVectorFonts = false;
|
||||
#endif
|
||||
if (core==0)
|
||||
strcpy(name,"Core A");
|
||||
else
|
||||
|
@ -707,7 +794,7 @@ void OSDCLASS::update()
|
|||
for (int i=0; i < lastLineText; i++)
|
||||
{
|
||||
aggDraw.hud->lineColor(lineColor[i]);
|
||||
aggDraw.hud->renderTextDropshadowed(lineText_x,lineText_y+(i*16),lineText[i]);
|
||||
RenderTextAutoVector(lineText_x, lineText_y+(i*16), lineText[i], true, osd->scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -789,7 +876,7 @@ void OSDCLASS::addFixed(u16 x, u16 y, const char *fmt, ...)
|
|||
va_end(list);
|
||||
|
||||
aggDraw.hud->lineColor(255,255,255);
|
||||
aggDraw.hud->renderTextDropshadowed(x,calcY(y),msg);
|
||||
RenderTextAutoVector(x, calcY(y), msg, true, osd->scale);
|
||||
|
||||
needUpdate = true;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
|
||||
HudCoordinates &hud(int i) { return ((HudCoordinates*)this)[i]; }
|
||||
void reset();
|
||||
void rescale(double oldScale, double newScale);
|
||||
|
||||
int fps, fps3d, cpuload[2], cpuloopIterationCount;
|
||||
char rtcString[25];
|
||||
|
@ -111,6 +112,10 @@ public:
|
|||
char name[7]; // for debuging
|
||||
bool singleScreen;
|
||||
bool swapScreens;
|
||||
double scale;
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
bool useVectorFonts;
|
||||
#endif
|
||||
|
||||
OSDCLASS(u8 core);
|
||||
~OSDCLASS();
|
||||
|
|
|
@ -118,20 +118,17 @@ static void Agg_init_fonts()
|
|||
|
||||
AggDraw_Desmume aggDraw;
|
||||
|
||||
#if defined(WIN32) || defined(HOST_LINUX)
|
||||
T_AGG_RGBA agg_targetScreen(0, 256, 384, 1024);
|
||||
#else
|
||||
T_AGG_RGB555 agg_targetScreen(0, 256, 384, 1512);
|
||||
#endif
|
||||
T_AGG_RGBA agg_targetScreen_32bit(0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2, GPU_FRAMEBUFFER_NATIVE_WIDTH*4);
|
||||
T_AGG_RGB555 agg_targetScreen_16bit(0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2, GPU_FRAMEBUFFER_NATIVE_WIDTH*2);
|
||||
|
||||
static u32 luaBuffer[256*192*2];
|
||||
T_AGG_RGBA agg_targetLua((u8*)luaBuffer, 256, 384, 1024);
|
||||
static std::vector<u32> luaBuffer(GPU_FRAMEBUFFER_NATIVE_WIDTH*GPU_FRAMEBUFFER_NATIVE_HEIGHT*2);
|
||||
T_AGG_RGBA agg_targetLua((u8*)luaBuffer.data(), GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2, GPU_FRAMEBUFFER_NATIVE_WIDTH*4);
|
||||
|
||||
static u32 hudBuffer[256*192*2];
|
||||
T_AGG_RGBA agg_targetHud((u8*)hudBuffer, 256, 384, 1024);
|
||||
static std::vector<u32> hudBuffer(GPU_FRAMEBUFFER_NATIVE_WIDTH*GPU_FRAMEBUFFER_NATIVE_HEIGHT*2);
|
||||
T_AGG_RGBA agg_targetHud((u8*)hudBuffer.data(), GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2, GPU_FRAMEBUFFER_NATIVE_WIDTH*4);
|
||||
|
||||
static AggDrawTarget* targets[] = {
|
||||
&agg_targetScreen,
|
||||
&agg_targetScreen_32bit,
|
||||
&agg_targetHud,
|
||||
&agg_targetLua,
|
||||
};
|
||||
|
@ -139,6 +136,16 @@ static AggDrawTarget* targets[] = {
|
|||
void Agg_init()
|
||||
{
|
||||
Agg_init_fonts();
|
||||
switch(aggDraw.screenBytesPerPixel)
|
||||
{
|
||||
case 2:
|
||||
targets[0]=&agg_targetScreen_16bit;
|
||||
break;
|
||||
case 4:
|
||||
targets[0]=&agg_targetScreen_32bit;
|
||||
break;
|
||||
}
|
||||
|
||||
aggDraw.screen = targets[0];
|
||||
aggDraw.hud = targets[1];
|
||||
aggDraw.lua = targets[2];
|
||||
|
@ -149,19 +156,35 @@ void Agg_init()
|
|||
//and the more clever compositing isnt supported in non-windows
|
||||
#ifdef WIN32
|
||||
if(CommonSettings.single_core())
|
||||
aggDraw.hud = &agg_targetScreen;
|
||||
aggDraw.hud = aggDraw.screen;
|
||||
#else
|
||||
aggDraw.hud = &agg_targetScreen;
|
||||
aggDraw.hud = aggDraw.screen;
|
||||
#endif
|
||||
|
||||
aggDraw.hud->setFont("verdana18_bold");
|
||||
}
|
||||
|
||||
AggDraw_Desmume::AggDraw_Desmume()
|
||||
{
|
||||
screenBytesPerPixel = 4;
|
||||
}
|
||||
|
||||
void AggDraw_Desmume::setTarget(AggTarget newTarget)
|
||||
{
|
||||
target = targets[newTarget];
|
||||
}
|
||||
|
||||
void Agg_setCustomSize(int w, int h)
|
||||
{
|
||||
hudBuffer.resize(w*h);
|
||||
luaBuffer.resize(w*h);
|
||||
if(aggDraw.screen)
|
||||
aggDraw.screen->setDrawTargetDims(0, w, h, w*aggDraw.screenBytesPerPixel);
|
||||
if(aggDraw.hud)
|
||||
aggDraw.hud->setDrawTargetDims((u8*)hudBuffer.data(), w, h, w*4);
|
||||
if(aggDraw.lua)
|
||||
aggDraw.lua->setDrawTargetDims((u8*)luaBuffer.data(), w, h, w*4);
|
||||
}
|
||||
|
||||
|
||||
////temporary, just for testing the lib
|
||||
|
|
|
@ -243,6 +243,8 @@ public:
|
|||
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual void setDrawTargetDims(agg::int8u* buf, int width, int height, int stride) = 0;
|
||||
|
||||
virtual agg::rendering_buffer & buf() = 0;
|
||||
|
||||
//returns an image for this target. you must provide the pixel type, but if it is wrong,
|
||||
|
@ -408,6 +410,9 @@ public:
|
|||
virtual Agg2DBase::ImageResample imageResample() = 0;
|
||||
static const agg::int8u* lookupFont(const std::string& name);
|
||||
virtual void setFont(const std::string& name) = 0;
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
virtual void setVectorFont(const std::string& fileName, int size, bool bold) = 0;
|
||||
#endif
|
||||
virtual void renderText(double dstX, double dstY, const std::string& str) = 0;
|
||||
virtual void renderTextDropshadowed(double dstX, double dstY, const std::string& str)
|
||||
{
|
||||
|
@ -427,6 +432,30 @@ public:
|
|||
lineColor(lineColorOld);
|
||||
renderText(dstX,dstY,str);
|
||||
}
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
virtual void renderVectorFontText(double dstX, double dstY, const std::string& str) = 0;
|
||||
virtual void renderVectorFontTextDropshadowed(double dstX, double dstY, const std::string& str, double shadowOffset = 1.0)
|
||||
{
|
||||
shadowOffset*=0.5;
|
||||
AggColor lineColorOld = lineColor();
|
||||
if(lineColorOld.r+lineColorOld.g+lineColorOld.b<192)
|
||||
lineColor(255-lineColorOld.r,255-lineColorOld.g,255-lineColorOld.b);
|
||||
else
|
||||
lineColor(0,0,0);
|
||||
fillColor(lineColor());
|
||||
renderVectorFontText(dstX-shadowOffset,dstY-shadowOffset,str);
|
||||
renderVectorFontText(dstX,dstY-shadowOffset,str);
|
||||
renderVectorFontText(dstX+shadowOffset,dstY-shadowOffset,str);
|
||||
renderVectorFontText(dstX-shadowOffset,dstY,str);
|
||||
renderVectorFontText(dstX+shadowOffset,dstY,str);
|
||||
renderVectorFontText(dstX-shadowOffset,dstY+shadowOffset,str);
|
||||
renderVectorFontText(dstX,dstY+shadowOffset,str);
|
||||
renderVectorFontText(dstX+shadowOffset,dstY+shadowOffset,str);
|
||||
lineColor(lineColorOld);
|
||||
fillColor(lineColor());
|
||||
renderVectorFontText(dstX,dstY,str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Auxiliary
|
||||
|
@ -459,6 +488,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void setDrawTargetDims(agg::int8u* buf, int width, int height, int stride)
|
||||
{
|
||||
BASE::attach(buf,width,height,stride);
|
||||
|
||||
BASE::viewport(0, 0, width-1, height-1, 0, 0, width-1, height-1, TAGG2D::Anisotropic);
|
||||
}
|
||||
|
||||
virtual agg::rendering_buffer & buf() { dirty(); return BASE::buf(); } // buf() might not always require calling dirty()
|
||||
typename BASE::MyImage image() { return BASE::MyImage(buf()); }
|
||||
|
||||
|
@ -578,6 +614,9 @@ public:
|
|||
virtual void polyline(double* xy, int numPoints) {dirty(); BASE::polyline(xy, numPoints);};
|
||||
|
||||
virtual void setFont(const std::string& name) { BASE::font(lookupFont(name)); }
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
virtual void setVectorFont(const std::string& fileName, int size, bool bold) {BASE::font(fileName.c_str(), size, bold); }
|
||||
#endif
|
||||
virtual void renderText(double dstX, double dstY, const std::string& str) {
|
||||
dirty();
|
||||
int height = BASE::font()[0];
|
||||
|
@ -585,6 +624,13 @@ public:
|
|||
int offset = height-base*2;
|
||||
BASE::renderText(dstX, dstY + offset, str);
|
||||
}
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
virtual void renderVectorFontText(double dstX, double dstY, const std::string& str) {
|
||||
dirty();
|
||||
BASE::flipText(true);
|
||||
BASE::text(dstX, dstY + BASE::fontHeight(), str.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Path commands
|
||||
virtual void resetPath() {BASE::resetPath();};
|
||||
|
@ -659,15 +705,18 @@ enum AggTarget
|
|||
class AggDraw_Desmume : public AggDraw
|
||||
{
|
||||
public:
|
||||
AggDraw_Desmume();
|
||||
void setTarget(AggTarget newTarget);
|
||||
//void composite(void* dest);
|
||||
|
||||
AggDrawTarget *screen, *hud, *lua;
|
||||
int screenBytesPerPixel;
|
||||
};
|
||||
|
||||
extern AggDraw_Desmume aggDraw;
|
||||
|
||||
void Agg_init();
|
||||
void Agg_setCustomSize(int w, int h);
|
||||
|
||||
struct font_type
|
||||
{
|
||||
|
|
|
@ -97,6 +97,25 @@ void value<string>::save() {
|
|||
g_key_file_set_string(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData.c_str());
|
||||
}
|
||||
|
||||
/* class value<vector<int> > */
|
||||
|
||||
template<>
|
||||
void value<vector<int> >::load() {
|
||||
gsize l;
|
||||
int* val = g_key_file_get_integer_list(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), &l, NULL);
|
||||
if(val)
|
||||
{
|
||||
this->mData.resize(l);
|
||||
std::copy(val, val+l, this->mData.begin());
|
||||
g_free(val);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void value<vector<int> >::save() {
|
||||
g_key_file_set_integer_list(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData.data(), this->mData.size());
|
||||
}
|
||||
|
||||
/* class Config */
|
||||
|
||||
Config::Config()
|
||||
|
|
|
@ -49,6 +49,7 @@ OPT(hud_input, bool, false, HudDisplay, Input)
|
|||
OPT(hud_graphicalInput, bool, false, HudDisplay, GraphicalInput)
|
||||
OPT(hud_rtc, bool, false, HudDisplay, RTC)
|
||||
OPT(hud_mic, bool, false, HudDisplay, Mic)
|
||||
OPT(hud_layout, std::vector<int>, std::vector<int>(), HudDisplay, Layout)
|
||||
|
||||
/* Config */
|
||||
OPT(fpslimiter, bool, true, Config, FpsLimiter)
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include <SDL.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <vector>
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "firmware.h"
|
||||
|
@ -127,6 +130,15 @@ enum {
|
|||
SUB_OBJ
|
||||
};
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
#define VECTOR_FONT_BASE_SIZE 16
|
||||
|
||||
static FcConfig* fontConfig;
|
||||
static std::string vectorFontFile;
|
||||
|
||||
static std::string FindFontFile(const char* fontName, bool bold);
|
||||
#endif
|
||||
|
||||
gboolean EmuLoop(gpointer data);
|
||||
|
||||
static AVOutX264 avout_x264;
|
||||
|
@ -190,6 +202,9 @@ static void HudLagCounter(GSimpleAction *action, GVariant *parameter, gpointer u
|
|||
static void HudRtc(GSimpleAction *action, GVariant *parameter, gpointer user_data);
|
||||
static void HudMic(GSimpleAction *action, GVariant *parameter, gpointer user_data);
|
||||
static void HudEditor(GSimpleAction *action, GVariant *parameter, gpointer user_data);
|
||||
static void HudResetLayout(GSimpleAction *action, GVariant *parameter, gpointer user_data);
|
||||
static void HudSaveLayout();
|
||||
static void HudLoadLayout();
|
||||
#endif
|
||||
#ifdef DESMUME_GTK_FIRMWARE_BROKEN
|
||||
static void SelectFirmwareFile(GSimpleAction *action, GVariant *parameter, gpointer user_data);
|
||||
|
@ -247,6 +262,7 @@ static const GActionEntry app_entries[] = {
|
|||
{ "hud_rtc", HudRtc, NULL, "false" },
|
||||
{ "hud_mic", HudMic, NULL, "false" },
|
||||
{ "hud_editor", HudEditor, NULL, "false" },
|
||||
{ "hud_reset_layout", HudResetLayout},
|
||||
#endif
|
||||
|
||||
// Config
|
||||
|
@ -1449,7 +1465,7 @@ static void RedrawScreen() {
|
|||
GPU->GetDisplayInfo().isCustomSizeRequested ? (u16*)(GPU->GetDisplayInfo().masterCustomBuffer) : GPU->GetDisplayInfo().masterNativeBuffer16,
|
||||
(uint32_t *)video->GetSrcBufferPtr(), real_framebuffer_width * real_framebuffer_height * 2);
|
||||
#ifdef HAVE_LIBAGG
|
||||
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), real_framebuffer_width, real_framebuffer_height * 2, 1024 * gpu_scale_factor);
|
||||
aggDraw.hud->setDrawTargetDims((u8*)video->GetSrcBufferPtr(), real_framebuffer_width, real_framebuffer_height * 2, real_framebuffer_width * 4);
|
||||
osd->update();
|
||||
DrawHUD();
|
||||
osd->clear();
|
||||
|
@ -1471,33 +1487,33 @@ static gboolean rotoscaled_hudedit(gint x, gint y, gboolean start)
|
|||
devX = x;
|
||||
devY = y;
|
||||
cairo_matrix_transform_point(&nds_screen.topscreen_matrix, &devX, &devY);
|
||||
topX = devX;
|
||||
topY = devY;
|
||||
topX = devX * gpu_scale_factor;
|
||||
topY = devY * gpu_scale_factor;
|
||||
}
|
||||
|
||||
if (nds_screen.orientation != ORIENT_SINGLE || nds_screen.swap) {
|
||||
devX = x;
|
||||
devY = y;
|
||||
cairo_matrix_transform_point(&nds_screen.touch_matrix, &devX, &devY);
|
||||
botX = devX;
|
||||
botY = devY;
|
||||
botX = devX * gpu_scale_factor;
|
||||
botY = devY * gpu_scale_factor;
|
||||
}
|
||||
|
||||
if (topX >= 0 && topY >= 0 && topX < 256 && topY < 192) {
|
||||
if (topX >= 0 && topY >= 0 && topX < real_framebuffer_width && topY < real_framebuffer_height) {
|
||||
X = topX;
|
||||
Y = topY + (nds_screen.swap ? 192 : 0);
|
||||
Y = topY + (nds_screen.swap ? real_framebuffer_height : 0);
|
||||
startScreen = 0;
|
||||
} else if (botX >= 0 && botY >= 0 && botX < 256 && botY < 192) {
|
||||
} else if (botX >= 0 && botY >= 0 && botX < real_framebuffer_width && botY < real_framebuffer_height) {
|
||||
X = botX;
|
||||
Y = botY + (nds_screen.swap ? 0 : 192);
|
||||
Y = botY + (nds_screen.swap ? 0 : real_framebuffer_height);
|
||||
startScreen = 1;
|
||||
} else if (!start) {
|
||||
if (startScreen == 0) {
|
||||
X = CLAMP(topX, 0, 255);
|
||||
Y = CLAMP(topY, 0, 191) + (nds_screen.swap ? 192 : 0);
|
||||
X = CLAMP(topX, 0, real_framebuffer_width-1);
|
||||
Y = CLAMP(topY, 0, real_framebuffer_height-1) + (nds_screen.swap ? real_framebuffer_height : 0);
|
||||
} else {
|
||||
X = CLAMP(botX, 0, 255);
|
||||
Y = CLAMP(botY, 0, 191) + (nds_screen.swap ? 0 : 192);
|
||||
X = CLAMP(botX, 0, real_framebuffer_width-1);
|
||||
Y = CLAMP(botY, 0, real_framebuffer_height-1) + (nds_screen.swap ? 0 : real_framebuffer_height);
|
||||
}
|
||||
} else {
|
||||
LOG("TopX=%d, TopY=%d, BotX=%d, BotY=%d\n", topX, topY, botX, botY);
|
||||
|
@ -2098,6 +2114,7 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
|
|||
default:
|
||||
break;
|
||||
}
|
||||
double old_scale_factor = gpu_scale_factor;
|
||||
gpu_scale_factor = gtk_spin_button_get_value(wGPUScale);
|
||||
if(gpu_scale_factor < GPU_SCALE_FACTOR_MIN)
|
||||
gpu_scale_factor = GPU_SCALE_FACTOR_MIN;
|
||||
|
@ -2109,6 +2126,21 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
|
|||
real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT * gpu_scale_factor;
|
||||
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
|
||||
video->SetSourceSize(real_framebuffer_width, real_framebuffer_height * 2);
|
||||
#ifdef HAVE_LIBAGG
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
if(vectorFontFile.size() > 0)
|
||||
{
|
||||
aggDraw.hud->setVectorFont(vectorFontFile, VECTOR_FONT_BASE_SIZE * gpu_scale_factor, true);
|
||||
osd->useVectorFonts=(gpu_scale_factor >= 1.1);
|
||||
}
|
||||
else
|
||||
osd->useVectorFonts=false;
|
||||
#endif
|
||||
Agg_setCustomSize(real_framebuffer_width, real_framebuffer_height*2);
|
||||
osd->scale=gpu_scale_factor;
|
||||
Hud.rescale(old_scale_factor, gpu_scale_factor);
|
||||
HudSaveLayout();
|
||||
#endif
|
||||
CommonSettings.GFX3D_Renderer_TextureDeposterize = config.textureDeposterize = gtk_toggle_button_get_active(wPosterize);
|
||||
CommonSettings.GFX3D_Renderer_TextureSmoothing = config.textureSmoothing = gtk_toggle_button_get_active(wSmoothing);
|
||||
CommonSettings.GFX3D_Renderer_TextureScalingFactor = config.textureUpscale = scale;
|
||||
|
@ -2773,6 +2805,8 @@ static void ToggleHudDisplay(hud_display_enum hudId, gboolean active)
|
|||
break;
|
||||
case HUD_DISPLAY_EDITOR:
|
||||
HudEditorMode = active;
|
||||
if(!active)
|
||||
HudSaveLayout();
|
||||
break;
|
||||
default:
|
||||
g_printerr("Unknown HUD toggle %u!", hudId);
|
||||
|
@ -2799,6 +2833,60 @@ HudMacro(HudRtc, HUD_DISPLAY_RTC)
|
|||
HudMacro(HudMic, HUD_DISPLAY_MIC)
|
||||
HudMacro(HudEditor, HUD_DISPLAY_EDITOR)
|
||||
|
||||
static void HudResetLayout(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
Hud.reset();
|
||||
HudSaveLayout();
|
||||
}
|
||||
|
||||
static void HudSaveCoordsToVector(HudCoordinates* pCoords, int* pDest)
|
||||
{
|
||||
pDest[0]=pCoords->x;
|
||||
pDest[1]=pCoords->y;
|
||||
pDest[2]=pCoords->xsize;
|
||||
pDest[3]=pCoords->ysize;
|
||||
}
|
||||
|
||||
static void HudLoadCoordsFromVector(HudCoordinates* pCoords, int* pSrc)
|
||||
{
|
||||
pCoords->x=pSrc[0];
|
||||
pCoords->y=pSrc[1];
|
||||
pCoords->xsize=pSrc[2];
|
||||
pCoords->ysize=pSrc[3];
|
||||
}
|
||||
|
||||
static void HudSaveLayout()
|
||||
{
|
||||
std::vector<int> vec(8*4); //8 HudCoordinates
|
||||
HudSaveCoordsToVector(&Hud.SavestateSlots, vec.data());
|
||||
HudSaveCoordsToVector(&Hud.FpsDisplay, vec.data()+4);
|
||||
HudSaveCoordsToVector(&Hud.FrameCounter, vec.data()+8);
|
||||
HudSaveCoordsToVector(&Hud.InputDisplay, vec.data()+12);
|
||||
HudSaveCoordsToVector(&Hud.GraphicalInputDisplay, vec.data()+16);
|
||||
HudSaveCoordsToVector(&Hud.LagFrameCounter, vec.data()+20);
|
||||
HudSaveCoordsToVector(&Hud.Microphone, vec.data()+24);
|
||||
HudSaveCoordsToVector(&Hud.RTCDisplay, vec.data()+28);
|
||||
config.hud_layout=vec;
|
||||
}
|
||||
|
||||
static void HudLoadLayout()
|
||||
{
|
||||
std::vector<int> vec=config.hud_layout;
|
||||
if(vec.size()==8*4)
|
||||
{
|
||||
HudLoadCoordsFromVector(&Hud.SavestateSlots, vec.data());
|
||||
HudLoadCoordsFromVector(&Hud.FpsDisplay, vec.data()+4);
|
||||
HudLoadCoordsFromVector(&Hud.FrameCounter, vec.data()+8);
|
||||
HudLoadCoordsFromVector(&Hud.InputDisplay, vec.data()+12);
|
||||
HudLoadCoordsFromVector(&Hud.GraphicalInputDisplay, vec.data()+16);
|
||||
HudLoadCoordsFromVector(&Hud.LagFrameCounter, vec.data()+20);
|
||||
HudLoadCoordsFromVector(&Hud.Microphone, vec.data()+24);
|
||||
HudLoadCoordsFromVector(&Hud.RTCDisplay, vec.data()+28);
|
||||
}
|
||||
else
|
||||
Hud.reset();
|
||||
}
|
||||
|
||||
static void desmume_gtk_menu_view_hud(GtkApplication *app)
|
||||
{
|
||||
const struct {
|
||||
|
@ -2998,6 +3086,10 @@ common_gtk_main(GApplication *app, gpointer user_data)
|
|||
|
||||
/* Init the hud / osd stuff */
|
||||
#ifdef HAVE_LIBAGG
|
||||
SDL_DisplayMode cur_mode;
|
||||
if(!SDL_GetCurrentDisplayMode(0, &cur_mode))
|
||||
aggDraw.screenBytesPerPixel = SDL_BYTESPERPIXEL(cur_mode.format);
|
||||
|
||||
Desmume_InitOnce();
|
||||
Hud.reset();
|
||||
osd = new OSDCLASS(-1);
|
||||
|
@ -3067,6 +3159,20 @@ common_gtk_main(GApplication *app, gpointer user_data)
|
|||
g_printerr("Using %d threads for video filter.\n", CommonSettings.num_cores);
|
||||
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
|
||||
video = new VideoFilter(real_framebuffer_width, real_framebuffer_height * 2, VideoFilterTypeID_None, CommonSettings.num_cores);
|
||||
#ifdef HAVE_LIBAGG
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
if(vectorFontFile.size() > 0)
|
||||
{
|
||||
aggDraw.hud->setVectorFont(vectorFontFile, VECTOR_FONT_BASE_SIZE * gpu_scale_factor, true);
|
||||
osd->useVectorFonts=(gpu_scale_factor >= 1.1);
|
||||
}
|
||||
else
|
||||
osd->useVectorFonts=false;
|
||||
#endif
|
||||
Agg_setCustomSize(real_framebuffer_width, real_framebuffer_height*2);
|
||||
osd->scale=gpu_scale_factor;
|
||||
HudLoadLayout();
|
||||
#endif
|
||||
|
||||
/* Fetch the main elements from the window */
|
||||
GtkBuilder *builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/main.ui");
|
||||
|
@ -3601,7 +3707,9 @@ common_gtk_main(GApplication *app, gpointer user_data)
|
|||
|
||||
static void Teardown() {
|
||||
delete video;
|
||||
|
||||
#ifdef HAVE_LIBAGG
|
||||
HudSaveLayout();
|
||||
#endif
|
||||
config.save();
|
||||
avout_x264.end();
|
||||
avout_flac.end();
|
||||
|
@ -3644,10 +3752,46 @@ handle_open(GApplication *application,
|
|||
common_gtk_main(application, user_data);
|
||||
}
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
|
||||
static std::string FindFontFile(const char* fontName, bool bold)
|
||||
{
|
||||
std::string fontFile;
|
||||
FcPattern* pat = FcNameParse((const FcChar8*)fontName);
|
||||
if(bold)
|
||||
FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD);
|
||||
FcConfigSubstitute(fontConfig, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute(pat);
|
||||
|
||||
// find the font
|
||||
FcResult res;
|
||||
FcPattern* font = FcFontMatch(fontConfig, pat, &res);
|
||||
if (font)
|
||||
{
|
||||
FcChar8* file = NULL;
|
||||
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
|
||||
{
|
||||
// save the file to another std::string
|
||||
fontFile = (char*)file;
|
||||
}
|
||||
FcPatternDestroy(font);
|
||||
}
|
||||
FcPatternDestroy(pat);
|
||||
return fontFile;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
configured_features my_config;
|
||||
|
||||
#ifdef AGG2D_USE_VECTORFONTS
|
||||
fontConfig = FcInitLoadConfigAndFonts();
|
||||
vectorFontFile = FindFontFile("mono", true);
|
||||
if(!vectorFontFile.size())
|
||||
vectorFontFile = FindFontFile("sans", true);
|
||||
#endif
|
||||
// The global menu screws up the window size...
|
||||
unsetenv("UBUNTU_MENUPROXY");
|
||||
|
||||
|
|
|
@ -834,6 +834,10 @@
|
|||
<attribute name='label' translatable='yes'>_Editor mode</attribute>
|
||||
<attribute name='action'>app.hud_editor</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name='label' translatable='yes'>Reset layout</attribute>
|
||||
<attribute name='action'>app.hud_reset_layout</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id='hud_unsupported'>
|
||||
|
|
|
@ -20,6 +20,7 @@ dep_openal = dependency('openal', required: get_option('openal'))
|
|||
dep_alsa = dependency('alsa', required: false)
|
||||
dep_soundtouch = dependency('soundtouch', required: false)
|
||||
dep_agg = dependency('libagg', required: false)
|
||||
dep_fontconfig = dependency('fontconfig', required: false)
|
||||
|
||||
# XXX: something wrong with this one.
|
||||
#dep_lua = dependency('lua-5.1', required: false)
|
||||
|
@ -203,6 +204,11 @@ endif
|
|||
if dep_agg.found()
|
||||
dependencies += dep_agg
|
||||
add_global_arguments('-DHAVE_LIBAGG', language: ['c', 'cpp'])
|
||||
if dep_fontconfig.found()
|
||||
dependencies += dep_fontconfig
|
||||
add_global_arguments('-DAGG2D_USE_VECTORFONTS', language: ['c', 'cpp'])
|
||||
add_global_link_arguments('-laggfontfreetype', language: ['c', 'cpp'])
|
||||
endif
|
||||
libdesmume_src += [
|
||||
'../modules/osd/agg/aggdraw.cpp',
|
||||
'../modules/osd/agg/agg_osd.cpp',
|
||||
|
|
Loading…
Reference in New Issue