mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 06:10:03 -06:00
more work on OSD
This commit is contained in:
@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <queue>
|
#include <deque>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "OSD.h"
|
|
||||||
|
|
||||||
#include "libui/ui.h"
|
#include "libui/ui.h"
|
||||||
#include "../OpenGLSupport.h"
|
#include "../OpenGLSupport.h"
|
||||||
|
|
||||||
|
#include "OSD.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
extern int WindowWidth, WindowHeight;
|
extern int WindowWidth, WindowHeight;
|
||||||
@ -38,6 +38,9 @@ const u32 kOSDMargin = 6;
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Uint32 Timestamp;
|
Uint32 Timestamp;
|
||||||
|
char Text[256];
|
||||||
|
u32 Color;
|
||||||
|
|
||||||
u32 Width, Height;
|
u32 Width, Height;
|
||||||
u32* Bitmap;
|
u32* Bitmap;
|
||||||
|
|
||||||
@ -49,15 +52,28 @@ typedef struct
|
|||||||
|
|
||||||
} Item;
|
} Item;
|
||||||
|
|
||||||
std::queue<Item*> CurrentItems;
|
std::deque<Item*> ItemQueue;
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
bool Init(bool opengl)
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeInit()
|
void DeInit(bool opengl)
|
||||||
{
|
{
|
||||||
|
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
||||||
|
{
|
||||||
|
Item* item = *it;
|
||||||
|
|
||||||
|
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
||||||
|
if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
||||||
|
if (item->Bitmap) delete[] item->Bitmap;
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
ItemQueue.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,7 +158,7 @@ u32 RainbowColor(u32 inc)
|
|||||||
{
|
{
|
||||||
// inspired from Acmlmboard
|
// inspired from Acmlmboard
|
||||||
|
|
||||||
if (inc < 100) return 0xFFFF9BFF + (inc << 8);
|
if (inc < 100) return 0xFFFF9B9B + (inc << 8);
|
||||||
else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16);
|
else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16);
|
||||||
else if (inc < 300) return 0xFF9BFF9B + (inc-200);
|
else if (inc < 300) return 0xFF9BFF9B + (inc-200);
|
||||||
else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8);
|
else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8);
|
||||||
@ -156,10 +172,10 @@ void RenderText(u32 color, const char* text, Item* item)
|
|||||||
int breaks[64];
|
int breaks[64];
|
||||||
|
|
||||||
bool rainbow = (color == 0);
|
bool rainbow = (color == 0);
|
||||||
u32 rainbowinc = rand() % 600;
|
u32 rainbowinc = (text[0] * 17) % 600;
|
||||||
|
|
||||||
color |= 0xFF000000;
|
color |= 0xFF000000;
|
||||||
const u32 shadow = 0xC0000000;
|
const u32 shadow = 0xFE000000;
|
||||||
|
|
||||||
LayoutText(text, &w, &h, breaks);
|
LayoutText(text, &w, &h, breaks);
|
||||||
|
|
||||||
@ -257,49 +273,89 @@ void RenderText(u32 color, const char* text, Item* item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test(u32* berp)
|
|
||||||
{
|
|
||||||
Item barp;
|
|
||||||
RenderText(0x000000, "This is a test of OSD, it can display really long messages, like thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis. Also, pancakes are the best thing ever.", &barp);
|
|
||||||
|
|
||||||
for (int y = 0; y < barp.Height; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < barp.Width; x++)
|
|
||||||
{
|
|
||||||
u32 src = barp.Bitmap[(y*barp.Width)+x];
|
|
||||||
u32 dst = berp[((y+6)*256)+x+6];
|
|
||||||
|
|
||||||
u32 sR = (src >> 16) & 0xFF;
|
|
||||||
u32 sG = (src >> 8) & 0xFF;
|
|
||||||
u32 sB = (src ) & 0xFF;
|
|
||||||
u32 sA = (src >> 24) & 0xFF;
|
|
||||||
|
|
||||||
u32 dR = (dst >> 16) & 0xFF;
|
|
||||||
u32 dG = (dst >> 8) & 0xFF;
|
|
||||||
u32 dB = (dst ) & 0xFF;
|
|
||||||
|
|
||||||
dR = ((sR * sA) + (dR * (255-sA))) >> 8;
|
|
||||||
dG = ((sG * sA) + (dG * (255-sA))) >> 8;
|
|
||||||
dB = ((sB * sA) + (dB * (255-sA))) >> 8;
|
|
||||||
|
|
||||||
dst = (dR << 16) | (dG << 8) | dB;
|
|
||||||
|
|
||||||
berp[((y+6)*256)+x+6] = dst | 0xFF000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] barp.Bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AddMessage(u32 color, const char* text)
|
void AddMessage(u32 color, const char* text)
|
||||||
{
|
{
|
||||||
//
|
Item* item = new Item;
|
||||||
|
|
||||||
|
item->Timestamp = SDL_GetTicks();
|
||||||
|
strncpy(item->Text, text, 255); item->Text[255] = '\0';
|
||||||
|
item->Color = color;
|
||||||
|
item->Bitmap = NULL;
|
||||||
|
|
||||||
|
item->DrawBitmapLoaded = false;
|
||||||
|
item->GLTextureLoaded = false;
|
||||||
|
|
||||||
|
ItemQueue.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(bool opengl)
|
void WindowResized(bool opengl)
|
||||||
{
|
{
|
||||||
//
|
/*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
||||||
|
{
|
||||||
|
Item* item = *it;
|
||||||
|
|
||||||
|
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
||||||
|
//if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
||||||
|
|
||||||
|
item->DrawBitmapLoaded = false;
|
||||||
|
item->GLTextureLoaded = false;
|
||||||
|
|
||||||
|
if (item->Bitmap) delete[] item->Bitmap;
|
||||||
|
|
||||||
|
it++;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(bool opengl, uiAreaDrawParams* params)
|
||||||
|
{
|
||||||
|
Uint32 tick_now = SDL_GetTicks();
|
||||||
|
Uint32 tick_min = tick_now - 2500;
|
||||||
|
u32 y = kOSDMargin;
|
||||||
|
|
||||||
|
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
||||||
|
{
|
||||||
|
Item* item = *it;
|
||||||
|
|
||||||
|
if (item->Timestamp < tick_min)
|
||||||
|
{
|
||||||
|
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
||||||
|
if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
||||||
|
if (item->Bitmap) delete[] item->Bitmap;
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
ItemQueue.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item->Bitmap)
|
||||||
|
{
|
||||||
|
RenderText(item->Color, item->Text, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opengl)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!item->DrawBitmapLoaded)
|
||||||
|
{
|
||||||
|
item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1);
|
||||||
|
uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap);
|
||||||
|
item->DrawBitmapLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiRect rc_src = {0, 0, item->Width, item->Height};
|
||||||
|
uiRect rc_dst = {kOSDMargin, y, item->Width, item->Height};
|
||||||
|
|
||||||
|
uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += item->Height;
|
||||||
|
it++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,13 @@
|
|||||||
namespace OSD
|
namespace OSD
|
||||||
{
|
{
|
||||||
|
|
||||||
bool Init();
|
bool Init(bool opengl);
|
||||||
void DeInit();
|
void DeInit(bool opengl);
|
||||||
|
|
||||||
void test(u32* berp);
|
|
||||||
|
|
||||||
void AddMessage(u32 color, const char* text);
|
void AddMessage(u32 color, const char* text);
|
||||||
|
|
||||||
void Update(bool opengl);
|
void WindowResized(bool opengl);
|
||||||
|
void Update(bool opengl, uiAreaDrawParams* params);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ _UI_EXTERN void uiDrawSave(uiDrawContext *c);
|
|||||||
_UI_EXTERN void uiDrawRestore(uiDrawContext *c);
|
_UI_EXTERN void uiDrawRestore(uiDrawContext *c);
|
||||||
|
|
||||||
// bitmap API
|
// bitmap API
|
||||||
_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height);
|
_UI_EXTERN uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha);
|
||||||
_UI_EXTERN void uiDrawBitmapUpdate(uiDrawBitmap* bmp, const void* data);
|
_UI_EXTERN void uiDrawBitmapUpdate(uiDrawBitmap* bmp, const void* data);
|
||||||
_UI_EXTERN void uiDrawBitmapDraw(uiDrawContext* c, uiDrawBitmap* bmp, uiRect* srcrect, uiRect* dstrect, int filter);
|
_UI_EXTERN void uiDrawBitmapDraw(uiDrawContext* c, uiDrawBitmap* bmp, uiRect* srcrect, uiRect* dstrect, int filter);
|
||||||
_UI_EXTERN void uiDrawFreeBitmap(uiDrawBitmap* bmp);
|
_UI_EXTERN void uiDrawFreeBitmap(uiDrawBitmap* bmp);
|
||||||
|
@ -143,13 +143,13 @@ void uiDrawRestore(uiDrawContext *c)
|
|||||||
|
|
||||||
// bitmap API
|
// bitmap API
|
||||||
|
|
||||||
uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
|
uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha)
|
||||||
{
|
{
|
||||||
uiDrawBitmap* bmp;
|
uiDrawBitmap* bmp;
|
||||||
|
|
||||||
bmp = uiNew(uiDrawBitmap);
|
bmp = uiNew(uiDrawBitmap);
|
||||||
|
|
||||||
bmp->bmp = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
bmp->bmp = cairo_image_surface_create(alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
|
||||||
if (cairo_surface_status(bmp->bmp) != CAIRO_STATUS_SUCCESS)
|
if (cairo_surface_status(bmp->bmp) != CAIRO_STATUS_SUCCESS)
|
||||||
implbug("error creating bitmap: %s",
|
implbug("error creating bitmap: %s",
|
||||||
cairo_status_to_string(cairo_surface_status(bmp->bmp)));
|
cairo_status_to_string(cairo_surface_status(bmp->bmp)));
|
||||||
|
@ -522,7 +522,7 @@ void uiDrawRestore(uiDrawContext *c)
|
|||||||
|
|
||||||
// bitmap API
|
// bitmap API
|
||||||
|
|
||||||
uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
|
uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha)
|
||||||
{
|
{
|
||||||
uiDrawBitmap* bmp;
|
uiDrawBitmap* bmp;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -532,7 +532,8 @@ uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height)
|
|||||||
D2D1_BITMAP_PROPERTIES bp2 = D2D1::BitmapProperties();
|
D2D1_BITMAP_PROPERTIES bp2 = D2D1::BitmapProperties();
|
||||||
bp2.dpiX = 0;
|
bp2.dpiX = 0;
|
||||||
bp2.dpiY = 0;
|
bp2.dpiY = 0;
|
||||||
bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
|
bp2.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
alpha ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE);
|
||||||
|
|
||||||
//c->rt->BeginDraw();
|
//c->rt->BeginDraw();
|
||||||
|
|
||||||
|
@ -434,6 +434,8 @@ void GLScreen_DrawScreen()
|
|||||||
glDrawArrays(GL_TRIANGLES, 0, 4*3);
|
glDrawArrays(GL_TRIANGLES, 0, 4*3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSD::Update(true, NULL);
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
uiGLSwapBuffers(GLContext);
|
uiGLSwapBuffers(GLContext);
|
||||||
}
|
}
|
||||||
@ -948,7 +950,15 @@ int EmuThreadFunc(void* burp)
|
|||||||
NDS::DeInit();
|
NDS::DeInit();
|
||||||
Platform::LAN_DeInit();
|
Platform::LAN_DeInit();
|
||||||
|
|
||||||
if (Screen_UseGL) GLScreen_DeInit();
|
if (Screen_UseGL)
|
||||||
|
{
|
||||||
|
uiGLMakeContextCurrent(GLContext);
|
||||||
|
OSD::DeInit(true);
|
||||||
|
GLScreen_DeInit();
|
||||||
|
uiGLMakeContextCurrent(NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
OSD::DeInit(false);
|
||||||
|
|
||||||
return 44203;
|
return 44203;
|
||||||
}
|
}
|
||||||
@ -962,8 +972,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
|
|||||||
if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]);
|
if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]);
|
||||||
|
|
||||||
ScreenDrawInited = true;
|
ScreenDrawInited = true;
|
||||||
ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192);
|
ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256, 192, 0);
|
||||||
ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192);
|
ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int frontbuf = GPU::FrontBuffer;
|
int frontbuf = GPU::FrontBuffer;
|
||||||
@ -973,8 +983,6 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
|
|||||||
uiRect top = {0, 0, 256, 192};
|
uiRect top = {0, 0, 256, 192};
|
||||||
uiRect bot = {0, 0, 256, 192};
|
uiRect bot = {0, 0, 256, 192};
|
||||||
|
|
||||||
//OSD::test(GPU::Framebuffer[frontbuf][0]);
|
|
||||||
|
|
||||||
uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]);
|
uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]);
|
||||||
uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]);
|
uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]);
|
||||||
|
|
||||||
@ -987,6 +995,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
|
|||||||
uiDrawTransform(params->Context, &BottomScreenTrans);
|
uiDrawTransform(params->Context, &BottomScreenTrans);
|
||||||
uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1);
|
uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1);
|
||||||
uiDrawRestore(params->Context);
|
uiDrawRestore(params->Context);
|
||||||
|
|
||||||
|
OSD::Update(false, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* evt)
|
void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* evt)
|
||||||
@ -1118,7 +1128,8 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
|
|||||||
MicCommand |= 1;
|
MicCommand |= 1;
|
||||||
|
|
||||||
if (evt->Scancode == 0x57) // F11
|
if (evt->Scancode == 0x57) // F11
|
||||||
NDS::debug(0);
|
OSD::AddMessage(0, "OSD test");
|
||||||
|
//NDS::debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1374,15 +1385,17 @@ void OnAreaResize(uiAreaHandler* handler, uiArea* area, int width, int height)
|
|||||||
WindowWidth = width;
|
WindowWidth = width;
|
||||||
WindowHeight = height;
|
WindowHeight = height;
|
||||||
|
|
||||||
int max = uiWindowMaximized(MainWindow);
|
int ismax = uiWindowMaximized(MainWindow);
|
||||||
int min = uiWindowMinimized(MainWindow);
|
int ismin = uiWindowMinimized(MainWindow);
|
||||||
|
|
||||||
Config::WindowMaximized = max;
|
Config::WindowMaximized = ismax;
|
||||||
if (!max && !min)
|
if (!ismax && !ismin)
|
||||||
{
|
{
|
||||||
Config::WindowWidth = width;
|
Config::WindowWidth = width;
|
||||||
Config::WindowHeight = height;
|
Config::WindowHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSD::WindowResized(Screen_UseGL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2061,6 +2074,10 @@ void ApplyNewSettings(int type)
|
|||||||
if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
|
if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);
|
||||||
|
OSD::DeInit(Screen_UseGL);
|
||||||
|
if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
|
||||||
|
|
||||||
Screen_UseGL = usegl;
|
Screen_UseGL = usegl;
|
||||||
RecreateMainWindow(usegl);
|
RecreateMainWindow(usegl);
|
||||||
|
|
||||||
@ -2294,6 +2311,8 @@ void CreateMainWindow(bool opengl)
|
|||||||
RecreateMainWindow(false);
|
RecreateMainWindow(false);
|
||||||
Screen_UseGL = false;
|
Screen_UseGL = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OSD::Init(opengl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyMainWindow()
|
void DestroyMainWindow()
|
||||||
|
Reference in New Issue
Block a user