From 45738beb88323248ba21817d6a81b51cf9e8fd9f Mon Sep 17 00:00:00 2001 From: Max Fedotov Date: Wed, 14 Feb 2024 11:20:57 +0300 Subject: [PATCH] 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 --- .../src/frontend/modules/osd/agg/agg2d.inl | 15 +- .../src/frontend/modules/osd/agg/agg_osd.cpp | 253 ++++++++++++------ .../src/frontend/modules/osd/agg/agg_osd.h | 9 +- .../src/frontend/modules/osd/agg/aggdraw.cpp | 47 +++- .../src/frontend/modules/osd/agg/aggdraw.h | 65 ++++- desmume/src/frontend/posix/gtk/config.cpp | 19 ++ desmume/src/frontend/posix/gtk/config_opts.h | 1 + desmume/src/frontend/posix/gtk/main.cpp | 172 +++++++++++- desmume/src/frontend/posix/gtk/menu.ui | 4 + desmume/src/frontend/posix/meson.build | 6 + 10 files changed, 470 insertions(+), 121 deletions(-) diff --git a/desmume/src/frontend/modules/osd/agg/agg2d.inl b/desmume/src/frontend/modules/osd/agg/agg2d.inl index 756d193b9..2f4ee6a5d 100644 --- a/desmume/src/frontend/modules/osd/agg/agg2d.inl +++ b/desmume/src/frontend/modules/osd/agg/agg2d.inl @@ -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::render(*this, m_renBase, m_renSolid, ras, sl); } else { - Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, ras, sl); + Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, ras, sl); } } diff --git a/desmume/src/frontend/modules/osd/agg/agg_osd.cpp b/desmume/src/frontend/modules/osd/agg/agg_osd.cpp index 06332ddab..5534ad0ab 100644 --- a/desmume/src/frontend/modules/osd/agg/agg_osd.cpp +++ b/desmume/src/frontend/modules/osd/agg/agg_osd.cpp @@ -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 @@ -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); } } } @@ -379,8 +464,8 @@ static void TextualInputDisplay() { // cast from char to std::string is a bit awkward 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; } diff --git a/desmume/src/frontend/modules/osd/agg/agg_osd.h b/desmume/src/frontend/modules/osd/agg/agg_osd.h index e62fcbd95..4077a1eb2 100644 --- a/desmume/src/frontend/modules/osd/agg/agg_osd.h +++ b/desmume/src/frontend/modules/osd/agg/agg_osd.h @@ -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]; @@ -92,7 +93,7 @@ class OSDCLASS private: u64 offset; u8 mode; - + u16 rotAngle; u16 lineText_x; @@ -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(); @@ -125,7 +130,7 @@ public: void addLine(const char* fmt, va_list args); void addFixed(u16 x, u16 y, const char *fmt, ...); void border(bool enabled); - + void SaveHudEditor(); }; diff --git a/desmume/src/frontend/modules/osd/agg/aggdraw.cpp b/desmume/src/frontend/modules/osd/agg/aggdraw.cpp index 4ec5e0403..50758c8f1 100644 --- a/desmume/src/frontend/modules/osd/agg/aggdraw.cpp +++ b/desmume/src/frontend/modules/osd/agg/aggdraw.cpp @@ -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 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 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 diff --git a/desmume/src/frontend/modules/osd/agg/aggdraw.h b/desmume/src/frontend/modules/osd/agg/aggdraw.h index 2cc385622..692334fcf 100644 --- a/desmume/src/frontend/modules/osd/agg/aggdraw.h +++ b/desmume/src/frontend/modules/osd/agg/aggdraw.h @@ -19,7 +19,7 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE. */ @@ -43,18 +43,18 @@ THE SOFTWARE. #include "agg_pixfmt_rgb.h" #include "agg_pixfmt_rgba.h" -#include "agg_pixfmt_rgb_packed.h" +#include "agg_pixfmt_rgb_packed.h" #include "agg2d.h" typedef agg::rgba8 AggColor; -namespace agg -{ - //NOTE - these blenders are necessary to change the rgb order from the defaults, which are incorrect for us - - //this custom blender does more correct blending math than the default - //which is necessary or else drawing transparent pixels on (31,31,31) will yield (30,30,30) +namespace agg +{ + //NOTE - these blenders are necessary to change the rgb order from the defaults, which are incorrect for us + + //this custom blender does more correct blending math than the default + //which is necessary or else drawing transparent pixels on (31,31,31) will yield (30,30,30) struct my_blender_rgb555_pre { typedef rgba8 color_type; @@ -242,6 +242,8 @@ public: bool empty; virtual void clear() = 0; + + virtual void setDrawTargetDims(agg::int8u* buf, int width, int height, int stride) = 0; virtual agg::rendering_buffer & buf() = 0; @@ -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 @@ -458,6 +487,13 @@ public: undirty(); } } + + 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 { diff --git a/desmume/src/frontend/posix/gtk/config.cpp b/desmume/src/frontend/posix/gtk/config.cpp index a0e593a5b..17a897563 100644 --- a/desmume/src/frontend/posix/gtk/config.cpp +++ b/desmume/src/frontend/posix/gtk/config.cpp @@ -97,6 +97,25 @@ void value::save() { g_key_file_set_string(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData.c_str()); } +/* class value > */ + +template<> +void value >::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 >::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() diff --git a/desmume/src/frontend/posix/gtk/config_opts.h b/desmume/src/frontend/posix/gtk/config_opts.h index 7481ab634..72f0f5249 100644 --- a/desmume/src/frontend/posix/gtk/config_opts.h +++ b/desmume/src/frontend/posix/gtk/config_opts.h @@ -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, std::vector(), HudDisplay, Layout) /* Config */ OPT(fpslimiter, bool, true, Config, FpsLimiter) diff --git a/desmume/src/frontend/posix/gtk/main.cpp b/desmume/src/frontend/posix/gtk/main.cpp index 1bf5bd492..f3e4c96d6 100644 --- a/desmume/src/frontend/posix/gtk/main.cpp +++ b/desmume/src/frontend/posix/gtk/main.cpp @@ -31,6 +31,9 @@ #include #include #include +#ifdef AGG2D_USE_VECTORFONTS +#include +#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 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 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"); diff --git a/desmume/src/frontend/posix/gtk/menu.ui b/desmume/src/frontend/posix/gtk/menu.ui index db28d2ae7..807efa898 100644 --- a/desmume/src/frontend/posix/gtk/menu.ui +++ b/desmume/src/frontend/posix/gtk/menu.ui @@ -834,6 +834,10 @@ _Editor mode app.hud_editor + + Reset layout + app.hud_reset_layout + diff --git a/desmume/src/frontend/posix/meson.build b/desmume/src/frontend/posix/meson.build index 89e0e4bef..13bf45a25 100644 --- a/desmume/src/frontend/posix/meson.build +++ b/desmume/src/frontend/posix/meson.build @@ -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',