mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
Merge pull request #1136 from camthehaxman/3ds-dualscreen
Dual screen mode for 3DS
This commit is contained in:
commit
164958df36
@ -286,6 +286,7 @@ typedef cc_uint8 cc_bool;
|
|||||||
#define CC_BUILD_BEARSSL
|
#define CC_BUILD_BEARSSL
|
||||||
#define CC_BUILD_LOWMEM
|
#define CC_BUILD_LOWMEM
|
||||||
#define CC_BUILD_CONSOLE
|
#define CC_BUILD_CONSOLE
|
||||||
|
#define CC_BUILD_TOUCH
|
||||||
#undef CC_BUILD_FREETYPE
|
#undef CC_BUILD_FREETYPE
|
||||||
#elif defined GEKKO
|
#elif defined GEKKO
|
||||||
#define CC_BUILD_GCWII
|
#define CC_BUILD_GCWII
|
||||||
|
@ -238,6 +238,9 @@ void Gfx_OnWindowResize(void);
|
|||||||
/* NOTE: Each line is separated by \n */
|
/* NOTE: Each line is separated by \n */
|
||||||
void Gfx_GetApiInfo(cc_string* info);
|
void Gfx_GetApiInfo(cc_string* info);
|
||||||
|
|
||||||
|
void Gfx_3DS_DrawToTopScreen(void);
|
||||||
|
void Gfx_3DS_DrawToBottomScreen(void);
|
||||||
|
|
||||||
/* Raises ContextLost event and updates state for lost contexts */
|
/* Raises ContextLost event and updates state for lost contexts */
|
||||||
void Gfx_LoseContext(const char* reason);
|
void Gfx_LoseContext(const char* reason);
|
||||||
/* Raises ContextRecreated event and restores internal state */
|
/* Raises ContextRecreated event and restores internal state */
|
||||||
|
@ -106,7 +106,8 @@ static void SwitchProgram(void) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------General---------------------------------------------------------*
|
*---------------------------------------------------------General---------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static C3D_RenderTarget* target;
|
static C3D_RenderTarget* topTarget;
|
||||||
|
static C3D_RenderTarget* bottomTarget;
|
||||||
|
|
||||||
static void AllocShaders(void) {
|
static void AllocShaders(void) {
|
||||||
Shader_Alloc(&shaders[0], coloured_shbin, coloured_shbin_size);
|
Shader_Alloc(&shaders[0], coloured_shbin, coloured_shbin_size);
|
||||||
@ -129,9 +130,16 @@ static void SetDefaultState(void) {
|
|||||||
|
|
||||||
static void InitCitro3D(void) {
|
static void InitCitro3D(void) {
|
||||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
|
||||||
C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
|
||||||
|
|
||||||
|
topTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
|
C3D_RenderTargetSetOutput(topTarget, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||||
|
|
||||||
|
// Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix
|
||||||
|
// can be used for both screens. The output is clipped to the actual screen width, anyway.
|
||||||
|
bottomTarget = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
|
C3D_RenderTargetSetOutput(bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||||
|
|
||||||
|
gfxSetDoubleBuffering(GFX_TOP, true);
|
||||||
SetDefaultState();
|
SetDefaultState();
|
||||||
AllocShaders();
|
AllocShaders();
|
||||||
}
|
}
|
||||||
@ -173,6 +181,14 @@ void Gfx_FreeState(void) {
|
|||||||
Gfx_DeleteTexture(&white_square);
|
Gfx_DeleteTexture(&white_square);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gfx_3DS_DrawToTopScreen(void) {
|
||||||
|
C3D_FrameDrawOn(topTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_3DS_DrawToBottomScreen(void) {
|
||||||
|
C3D_FrameDrawOn(bottomTarget);
|
||||||
|
}
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
@ -355,11 +371,12 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) {
|
|||||||
void Gfx_BeginFrame(void) {
|
void Gfx_BeginFrame(void) {
|
||||||
int flags = gfx_vsync ? C3D_FRAME_SYNCDRAW : 0;
|
int flags = gfx_vsync ? C3D_FRAME_SYNCDRAW : 0;
|
||||||
C3D_FrameBegin(flags);
|
C3D_FrameBegin(flags);
|
||||||
|
C3D_FrameDrawOn(topTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_Clear(void) {
|
void Gfx_Clear(void) {
|
||||||
C3D_RenderTargetClear(target, C3D_CLEAR_ALL, clear_color, 0);
|
C3D_RenderTargetClear(topTarget, C3D_CLEAR_ALL, clear_color, 0);
|
||||||
C3D_FrameDrawOn(target);
|
C3D_RenderTargetClear(bottomTarget, C3D_CLEAR_ALL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_EndFrame(void) {
|
void Gfx_EndFrame(void) {
|
||||||
|
52
src/Gui.c
52
src/Gui.c
@ -21,7 +21,9 @@
|
|||||||
struct _GuiData Gui;
|
struct _GuiData Gui;
|
||||||
struct Screen* Gui_Screens[GUI_MAX_SCREENS];
|
struct Screen* Gui_Screens[GUI_MAX_SCREENS];
|
||||||
static cc_uint8 priorities[GUI_MAX_SCREENS];
|
static cc_uint8 priorities[GUI_MAX_SCREENS];
|
||||||
|
#ifdef __3DS__
|
||||||
|
static struct Texture touchBgTex;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*----------------------------------------------------------Gui------------------------------------------------------------*
|
*----------------------------------------------------------Gui------------------------------------------------------------*
|
||||||
@ -32,10 +34,14 @@ static CC_NOINLINE int GetWindowScale(void) {
|
|||||||
|
|
||||||
/* Use larger UI scaling on mobile */
|
/* Use larger UI scaling on mobile */
|
||||||
/* TODO move this DPI scaling elsewhere.,. */
|
/* TODO move this DPI scaling elsewhere.,. */
|
||||||
|
#ifndef __3DS__
|
||||||
if (!Input_TouchMode) {
|
if (!Input_TouchMode) {
|
||||||
|
#endif
|
||||||
widthScale /= DisplayInfo.ScaleX;
|
widthScale /= DisplayInfo.ScaleX;
|
||||||
heightScale /= DisplayInfo.ScaleY;
|
heightScale /= DisplayInfo.ScaleY;
|
||||||
|
#ifndef __3DS__
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 1 + (int)(min(widthScale, heightScale));
|
return 1 + (int)(min(widthScale, heightScale));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,12 +143,16 @@ void Gui_LayoutAll(void) {
|
|||||||
struct Screen* s;
|
struct Screen* s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
for (i = 0; i < Gui.ScreensCount; i++)
|
for (i = 0; i < Gui.ScreensCount; i++)
|
||||||
{
|
{
|
||||||
s = Gui_Screens[i];
|
s = Gui_Screens[i];
|
||||||
s->VTABLE->Layout(s);
|
s->VTABLE->Layout(s);
|
||||||
s->dirty = true;
|
s->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui_RefreshAll(void) {
|
void Gui_RefreshAll(void) {
|
||||||
@ -152,10 +162,14 @@ void Gui_RefreshAll(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gui_Refresh(struct Screen* s) {
|
void Gui_Refresh(struct Screen* s) {
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
s->VTABLE->ContextLost(s);
|
s->VTABLE->ContextLost(s);
|
||||||
s->VTABLE->ContextRecreated(s);
|
s->VTABLE->ContextRecreated(s);
|
||||||
s->VTABLE->Layout(s);
|
s->VTABLE->Layout(s);
|
||||||
s->dirty = true;
|
s->dirty = true;
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Gui_AddCore(struct Screen* s, int priority) {
|
static void Gui_AddCore(struct Screen* s, int priority) {
|
||||||
@ -179,6 +193,8 @@ static void Gui_AddCore(struct Screen* s, int priority) {
|
|||||||
priorities[i] = priority;
|
priorities[i] = priority;
|
||||||
Gui.ScreensCount++;
|
Gui.ScreensCount++;
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
s->dirty = true;
|
s->dirty = true;
|
||||||
s->VTABLE->Init(s);
|
s->VTABLE->Init(s);
|
||||||
s->VTABLE->ContextRecreated(s);
|
s->VTABLE->ContextRecreated(s);
|
||||||
@ -189,6 +205,8 @@ static void Gui_AddCore(struct Screen* s, int priority) {
|
|||||||
{
|
{
|
||||||
s->VTABLE->HandlesPointerMove(s, i, Pointers[i].x, Pointers[i].y);
|
s->VTABLE->HandlesPointerMove(s, i, Pointers[i].x, Pointers[i].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns index of the given screen in the screens list, -1 if not */
|
/* Returns index of the given screen in the screens list, -1 if not */
|
||||||
@ -283,6 +301,12 @@ void Gui_RenderGui(double delta) {
|
|||||||
struct Screen* s;
|
struct Screen* s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
Texture_Render(&touchBgTex);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Draw back to front so highest priority screen is on top */
|
/* Draw back to front so highest priority screen is on top */
|
||||||
for (i = Gui.ScreensCount - 1; i >= 0; i--)
|
for (i = Gui.ScreensCount - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@ -292,6 +316,8 @@ void Gui_RenderGui(double delta) {
|
|||||||
if (s->dirty) { s->VTABLE->BuildMesh(s); s->dirty = false; }
|
if (s->dirty) { s->VTABLE->BuildMesh(s); s->dirty = false; }
|
||||||
s->VTABLE->Render(s, delta);
|
s->VTABLE->Render(s, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -449,22 +475,26 @@ int Screen_DoPointerDown(void* screen, int id, int x, int y) {
|
|||||||
struct Screen* s = (struct Screen*)screen;
|
struct Screen* s = (struct Screen*)screen;
|
||||||
struct Widget** widgets = s->widgets;
|
struct Widget** widgets = s->widgets;
|
||||||
int i, count = s->numWidgets;
|
int i, count = s->numWidgets;
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
/* iterate backwards (because last elements rendered are shown over others) */
|
/* iterate backwards (because last elements rendered are shown over others) */
|
||||||
for (i = count - 1; i >= 0; i--)
|
for (i = count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
struct Widget* w = widgets[i];
|
struct Widget* w = widgets[i];
|
||||||
if (!w || !Widget_Contains(w, x, y)) continue;
|
if (!w || !Widget_Contains(w, x, y)) continue;
|
||||||
if (w->flags & WIDGET_FLAG_DISABLED) return i;
|
if (w->flags & WIDGET_FLAG_DISABLED) break;
|
||||||
|
|
||||||
if (w->MenuClick) {
|
if (w->MenuClick) {
|
||||||
w->MenuClick(s, w);
|
w->MenuClick(s, w);
|
||||||
} else {
|
} else {
|
||||||
Elem_HandlesPointerDown(w, id, x, y);
|
Elem_HandlesPointerDown(w, id, x, y);
|
||||||
}
|
}
|
||||||
return i;
|
break;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Screen_Index(void* screen, void* widget) {
|
int Screen_Index(void* screen, void* widget) {
|
||||||
@ -568,7 +598,6 @@ static void TouchPngProcess(struct Stream* stream, const cc_string* name) {
|
|||||||
}
|
}
|
||||||
static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess };
|
static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess };
|
||||||
|
|
||||||
|
|
||||||
static void OnFontChanged(void* obj) { Gui_RefreshAll(); }
|
static void OnFontChanged(void* obj) { Gui_RefreshAll(); }
|
||||||
|
|
||||||
static void OnKeyPress(void* obj, int cp) {
|
static void OnKeyPress(void* obj, int cp) {
|
||||||
@ -612,6 +641,19 @@ static void OnInit(void) {
|
|||||||
TextureEntry_Register(&icons_entry);
|
TextureEntry_Register(&icons_entry);
|
||||||
TextureEntry_Register(&touch_entry);
|
TextureEntry_Register(&touch_entry);
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
struct Context2D ctx;
|
||||||
|
Context2D_Alloc(&ctx, 32, 32);
|
||||||
|
Gradient_Noise(&ctx, BitmapColor_RGB(0x40, 0x30, 0x20), 6, 0, 0, ctx.width, ctx.height);
|
||||||
|
Context2D_MakeTexture(&touchBgTex, &ctx);
|
||||||
|
Context2D_Free(&ctx);
|
||||||
|
// Tile the texture to fill the entire screen
|
||||||
|
int tilesX = (320 + ctx.width - 1) / ctx.width;
|
||||||
|
int tilesY = (240 + ctx.height - 1) / ctx.height;
|
||||||
|
touchBgTex.Width *= tilesX; touchBgTex.Height *= tilesY;
|
||||||
|
touchBgTex.uv.U2 *= tilesX; touchBgTex.uv.V2 *= tilesY;
|
||||||
|
#endif
|
||||||
|
|
||||||
Event_Register_(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
Event_Register_(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
||||||
Event_Register_(&GfxEvents.ContextLost, NULL, OnContextLost);
|
Event_Register_(&GfxEvents.ContextLost, NULL, OnContextLost);
|
||||||
Event_Register_(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
Event_Register_(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
||||||
|
@ -114,6 +114,7 @@ cc_bool Launcher_StartGame(const cc_string* user, const cc_string* mppass, const
|
|||||||
if (res) { Logger_SysWarn(res, "starting game"); return false; }
|
if (res) { Logger_SysWarn(res, "starting game"); return false; }
|
||||||
|
|
||||||
Launcher_ShouldExit = Platform_SingleProcess || Options_GetBool(LOPT_AUTO_CLOSE, false);
|
Launcher_ShouldExit = Platform_SingleProcess || Options_GetBool(LOPT_AUTO_CLOSE, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +236,8 @@ void Launcher_Run(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
Drawer2D_Component.Init();
|
Drawer2D_Component.Init();
|
||||||
SystemFonts_Component.Init();
|
SystemFonts_Component.Init();
|
||||||
Drawer2D.BitmappedText = false;
|
Drawer2D.BitmappedText = false;
|
||||||
@ -295,6 +298,8 @@ void Launcher_Run(void) {
|
|||||||
|
|
||||||
if (Window_Main.Exists) Window_RequestClose();
|
if (Window_Main.Exists) Window_RequestClose();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -527,17 +532,43 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2
|
|||||||
cc_string title = String_FromReadonly(text);
|
cc_string title = String_FromReadonly(text);
|
||||||
struct DrawTextArgs args;
|
struct DrawTextArgs args;
|
||||||
int x;
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
/* Skip dragging logo when very small window to save space */
|
/* Skip dragging logo when very small window to save space */
|
||||||
if (Window_Main.Height < 240) return;
|
if (Window_Main.Height < 240) return;
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
/* Put title on top screen */
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
struct Bitmap bmp;
|
||||||
|
struct Context2D topCtx;
|
||||||
|
|
||||||
|
ctx = &topCtx;
|
||||||
|
bmp.width = max(Window_Main.Width, 1);
|
||||||
|
bmp.height = max(Window_Main.Height, 1);
|
||||||
|
Window_AllocFramebuffer(&bmp);
|
||||||
|
Context2D_Wrap(ctx, &bmp);
|
||||||
|
Launcher_DrawBackgroundAll(ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
DrawTextArgs_Make(&args, &title, font, false);
|
DrawTextArgs_Make(&args, &title, font, false);
|
||||||
x = ctx->width / 2 - Drawer2D_TextWidth(&args) / 2;
|
x = ctx->width / 2 - Drawer2D_TextWidth(&args) / 2;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
// vertically center the title
|
||||||
|
y = ctx->height / 2 - Drawer2D_TextHeight(&args) / 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
Drawer2D.Colors['f'] = BITMAPCOLOR_BLACK;
|
Drawer2D.Colors['f'] = BITMAPCOLOR_BLACK;
|
||||||
Context2D_DrawText(ctx, &args, x + Display_ScaleX(4), Display_ScaleY(4));
|
Context2D_DrawText(ctx, &args, x + Display_ScaleX(4), y + Display_ScaleY(4));
|
||||||
Drawer2D.Colors['f'] = BITMAPCOLOR_WHITE;
|
Drawer2D.Colors['f'] = BITMAPCOLOR_WHITE;
|
||||||
Context2D_DrawText(ctx, &args, x, 0);
|
Context2D_DrawText(ctx, &args, x, y);
|
||||||
|
|
||||||
|
#ifdef __3DS__
|
||||||
|
Window_DrawFramebuffer((Rect2D){ 0, 0, bmp.width, bmp.height });
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher_MakeTitleFont(struct FontDesc* font) {
|
void Launcher_MakeTitleFont(struct FontDesc* font) {
|
||||||
|
@ -56,6 +56,10 @@ void Platform_Log(const char* msg, int len) {
|
|||||||
|
|
||||||
write(STDOUT_FILENO, msg, len);
|
write(STDOUT_FILENO, msg, len);
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
write(STDOUT_FILENO, "\n", 1);
|
||||||
|
|
||||||
|
// output to debug service (visible in Citra with log level set to "*:Debug", or on console via remote gdb)
|
||||||
|
svcOutputDebugString(msg, len);
|
||||||
|
svcOutputDebugString("\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
||||||
|
@ -202,9 +202,11 @@ static void HUDScreen_ContextRecreated(void* screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int HUDScreen_LayoutHotbar(void) {
|
static int HUDScreen_LayoutHotbar(void) {
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
struct HUDScreen* s = &HUDScreen_Instance;
|
struct HUDScreen* s = &HUDScreen_Instance;
|
||||||
s->hotbar.scale = Gui_GetHotbarScale();
|
s->hotbar.scale = Gui_GetHotbarScale();
|
||||||
Widget_Layout(&s->hotbar);
|
Widget_Layout(&s->hotbar);
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
return s->hotbar.height;
|
return s->hotbar.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +339,7 @@ static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) {
|
|||||||
/* Only top quarter of icons.png is used */
|
/* Only top quarter of icons.png is used */
|
||||||
static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/64.0f) };
|
static struct Texture tex = { 0, Tex_Rect(0,0,0,0), Tex_UV(0.0f,0.0f, 15/256.0f,15/64.0f) };
|
||||||
int extent;
|
int extent;
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
extent = (int)(CH_EXTENT * Gui_Scale(Window_Main.Height / 480.0f));
|
extent = (int)(CH_EXTENT * Gui_Scale(Window_Main.Height / 480.0f));
|
||||||
tex.x = (Window_Main.Width / 2) - extent;
|
tex.x = (Window_Main.Width / 2) - extent;
|
||||||
@ -345,6 +348,8 @@ static void HUDScreen_BuildCrosshairsMesh(struct VertexTextured** ptr) {
|
|||||||
tex.Width = extent * 2;
|
tex.Width = extent * 2;
|
||||||
tex.Height = extent * 2;
|
tex.Height = extent * 2;
|
||||||
Gfx_Make2DQuad(&tex, PACKEDCOL_WHITE, ptr);
|
Gfx_Make2DQuad(&tex, PACKEDCOL_WHITE, ptr);
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HUDScreen_BuildMesh(void* screen) {
|
static void HUDScreen_BuildMesh(void* screen) {
|
||||||
@ -369,6 +374,8 @@ static void HUDScreen_Render(void* screen, double delta) {
|
|||||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||||
if (Game_HideGui) return;
|
if (Game_HideGui) return;
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
Gfx_BindDynamicVb(s->vb);
|
Gfx_BindDynamicVb(s->vb);
|
||||||
if (Gui.ShowFPS) Widget_Render2(&s->line1, 4);
|
if (Gui.ShowFPS) Widget_Render2(&s->line1, 4);
|
||||||
@ -382,15 +389,18 @@ static void HUDScreen_Render(void* screen, double delta) {
|
|||||||
/* TODO swap these two lines back */
|
/* TODO swap these two lines back */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Gui_GetBlocksWorld()) return;
|
if (!Gui_GetBlocksWorld()) {
|
||||||
Gfx_BindDynamicVb(s->vb);
|
Gfx_BindDynamicVb(s->vb);
|
||||||
Widget_Render2(&s->hotbar, 12);
|
Widget_Render2(&s->hotbar, 12);
|
||||||
|
|
||||||
if (Gui.IconsTex && !tablist_active) {
|
if (Gui.IconsTex && !tablist_active) {
|
||||||
Gfx_BindTexture(Gui.IconsTex);
|
Gfx_BindTexture(Gui.IconsTex);
|
||||||
Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */
|
Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */
|
||||||
Gfx_DrawVb_IndexedTris(4);
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ScreenVTABLE HUDScreen_VTABLE = {
|
static const struct ScreenVTABLE HUDScreen_VTABLE = {
|
||||||
@ -494,6 +504,8 @@ static void TabListOverlay_Layout(void* screen) {
|
|||||||
int i, x, y, width = 0, height = 0;
|
int i, x, y, width = 0, height = 0;
|
||||||
int columns = Math_CeilDiv(s->usedCount, LIST_NAMES_PER_COLUMN);
|
int columns = Math_CeilDiv(s->usedCount, LIST_NAMES_PER_COLUMN);
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
for (i = 0; i < columns; i++)
|
for (i = 0; i < columns; i++)
|
||||||
{
|
{
|
||||||
width += TabListOverlay_GetColumnWidth(s, i);
|
width += TabListOverlay_GetColumnWidth(s, i);
|
||||||
@ -530,6 +542,8 @@ static void TabListOverlay_Layout(void* screen) {
|
|||||||
s->title.horAnchor = ANCHOR_CENTRE;
|
s->title.horAnchor = ANCHOR_CENTRE;
|
||||||
s->title.yOffset = s->y + paddingY / 2;
|
s->title.yOffset = s->y + paddingY / 2;
|
||||||
Widget_Layout(&s->title);
|
Widget_Layout(&s->title);
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TabListOverlay_AddName(struct TabListOverlay* s, EntityID id, int index) {
|
static void TabListOverlay_AddName(struct TabListOverlay* s, EntityID id, int index) {
|
||||||
@ -804,6 +818,9 @@ static void TabListOverlay_Render(void* screen, double delta) {
|
|||||||
PackedCol bottomCol = PackedCol_Make(50, 50, 50, 205);
|
PackedCol bottomCol = PackedCol_Make(50, 50, 50, 205);
|
||||||
|
|
||||||
if (Game_HideGui || !IsOnlyChatActive()) return;
|
if (Game_HideGui || !IsOnlyChatActive()) return;
|
||||||
|
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
Gfx_Draw2DGradient(s->x, s->y, s->width, s->height, topCol, bottomCol);
|
Gfx_Draw2DGradient(s->x, s->y, s->width, s->height, topCol, bottomCol);
|
||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
@ -818,6 +835,8 @@ static void TabListOverlay_Render(void* screen, double delta) {
|
|||||||
Gfx_DrawVb_IndexedTris_Range(4, offset);
|
Gfx_DrawVb_IndexedTris_Range(4, offset);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TabListOverlay_Free(void* screen) {
|
static void TabListOverlay_Free(void* screen) {
|
||||||
@ -1152,9 +1171,11 @@ static void ChatScreen_DrawChat(struct ChatScreen* s, double delta) {
|
|||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
if (!Input_TouchMode) return;
|
if (!Input_TouchMode) return;
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
Elem_Render(&s->more, delta);
|
Elem_Render(&s->more, delta);
|
||||||
Elem_Render(&s->send, delta);
|
Elem_Render(&s->send, delta);
|
||||||
Elem_Render(&s->cancel, delta);
|
Elem_Render(&s->cancel, delta);
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1218,6 +1239,8 @@ static void ChatScreen_BuildMesh(void* screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ChatScreen_Layout(void* screen) {
|
static void ChatScreen_Layout(void* screen) {
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
struct ChatScreen* s = (struct ChatScreen*)screen;
|
struct ChatScreen* s = (struct ChatScreen*)screen;
|
||||||
if (ChatScreen_ChatUpdateFont(s)) ChatScreen_Redraw(s);
|
if (ChatScreen_ChatUpdateFont(s)) ChatScreen_Redraw(s);
|
||||||
|
|
||||||
@ -1248,6 +1271,8 @@ static void ChatScreen_Layout(void* screen) {
|
|||||||
s->smallAnnouncement.yOffset = Window_Main.Height / 20;
|
s->smallAnnouncement.yOffset = Window_Main.Height / 20;
|
||||||
Widget_Layout(&s->smallAnnouncement);
|
Widget_Layout(&s->smallAnnouncement);
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
if (Window_Main.SoftKeyboard == SOFT_KEYBOARD_SHIFT) {
|
if (Window_Main.SoftKeyboard == SOFT_KEYBOARD_SHIFT) {
|
||||||
Widget_SetLocation(&s->send, ANCHOR_MAX, ANCHOR_MAX, 10, 60);
|
Widget_SetLocation(&s->send, ANCHOR_MAX, ANCHOR_MAX, 10, 60);
|
||||||
@ -1456,17 +1481,19 @@ static void ChatScreen_Init(void* screen) {
|
|||||||
|
|
||||||
static void ChatScreen_Render(void* screen, double delta) {
|
static void ChatScreen_Render(void* screen, double delta) {
|
||||||
struct ChatScreen* s = (struct ChatScreen*)screen;
|
struct ChatScreen* s = (struct ChatScreen*)screen;
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(TOP_SCREEN);
|
||||||
|
|
||||||
if (Game_HideGui && s->grabsInput) {
|
if (Game_HideGui && s->grabsInput) {
|
||||||
Elem_Render(&s->input.base, delta);
|
Elem_Render(&s->input.base, delta);
|
||||||
}
|
}
|
||||||
if (Game_HideGui) return;
|
if (!Game_HideGui) {
|
||||||
|
if (s->grabsInput && !Gui.ClassicChat) {
|
||||||
|
ChatScreen_DrawChatBackground(s);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->grabsInput && !Gui.ClassicChat) {
|
ChatScreen_DrawChat(s, delta);
|
||||||
ChatScreen_DrawChatBackground(s);
|
|
||||||
}
|
}
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
ChatScreen_DrawChat(s, delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ChatScreen_Free(void* screen) {
|
static void ChatScreen_Free(void* screen) {
|
||||||
|
@ -448,16 +448,21 @@ static void HotbarWidget_RenderEntries(struct HotbarWidget* w, int offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int HotbarWidget_Render2(void* widget, int offset) {
|
static int HotbarWidget_Render2(void* widget, int offset) {
|
||||||
|
enum Screen3DS scr = Window_3DS_SetRenderScreen(BOTTOM_SCREEN);
|
||||||
|
|
||||||
struct HotbarWidget* w = (struct HotbarWidget*)widget;
|
struct HotbarWidget* w = (struct HotbarWidget*)widget;
|
||||||
HotbarWidget_RenderOutline(w, offset );
|
HotbarWidget_RenderOutline(w, offset );
|
||||||
HotbarWidget_RenderEntries(w, offset + 8);
|
HotbarWidget_RenderEntries(w, offset + 8);
|
||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
if (!Input_TouchMode) return HOTBAR_MAX_VERTICES;
|
if (Input_TouchMode) {
|
||||||
w->ellipsisTex.x = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2;
|
w->ellipsisTex.x = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2;
|
||||||
w->ellipsisTex.y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2;
|
w->ellipsisTex.y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2;
|
||||||
Texture_Render(&w->ellipsisTex);
|
Texture_Render(&w->ellipsisTex);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Window_3DS_SetRenderScreen(scr);
|
||||||
return HOTBAR_MAX_VERTICES;
|
return HOTBAR_MAX_VERTICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/Window.h
10
src/Window.h
@ -233,4 +233,14 @@ void GLContext_SetFpsLimit(cc_bool vsync, float minFrameMs);
|
|||||||
/* Gets OpenGL context specific graphics information. */
|
/* Gets OpenGL context specific graphics information. */
|
||||||
void GLContext_GetApiInfo(cc_string* info);
|
void GLContext_GetApiInfo(cc_string* info);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum Screen3DS { TOP_SCREEN, BOTTOM_SCREEN };
|
||||||
|
#ifdef __3DS__
|
||||||
|
/* Selects which screen on the 3DS to render to. Returns the previous screen */
|
||||||
|
enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen);
|
||||||
|
#else
|
||||||
|
static inline
|
||||||
|
enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen) { return TOP_SCREEN; }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
|
||||||
static int touchActive, touchBegX, touchBegY;
|
|
||||||
static cc_bool launcherMode;
|
static cc_bool launcherMode;
|
||||||
static Result irrst_result;
|
static Result irrst_result;
|
||||||
|
static enum Screen3DS renderScreen = TOP_SCREEN;
|
||||||
|
|
||||||
struct _DisplayData DisplayInfo;
|
struct _DisplayData DisplayInfo;
|
||||||
struct _WindowData WindowInfo;
|
struct _WindowData WindowInfo;
|
||||||
@ -32,7 +32,7 @@ void Window_Init(void) {
|
|||||||
gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, false);
|
gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, false);
|
||||||
|
|
||||||
//gfxInit(GSP_RGBA8_OES,GSP_RGBA8_OES,false);
|
//gfxInit(GSP_RGBA8_OES,GSP_RGBA8_OES,false);
|
||||||
consoleInit(GFX_BOTTOM, NULL);
|
//consoleInit(GFX_BOTTOM, NULL);
|
||||||
|
|
||||||
u16 width, height;
|
u16 width, height;
|
||||||
gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height);
|
gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height);
|
||||||
@ -48,6 +48,7 @@ void Window_Init(void) {
|
|||||||
Window_Main.Focused = true;
|
Window_Main.Focused = true;
|
||||||
Window_Main.Exists = true;
|
Window_Main.Exists = true;
|
||||||
|
|
||||||
|
Input_SetTouchMode(true);
|
||||||
Input.Sources = INPUT_SOURCE_GAMEPAD;
|
Input.Sources = INPUT_SOURCE_GAMEPAD;
|
||||||
irrst_result = irrstInit();
|
irrst_result = irrstInit();
|
||||||
|
|
||||||
@ -58,6 +59,21 @@ void Window_Init(void) {
|
|||||||
|
|
||||||
void Window_Free(void) { irrstExit(); }
|
void Window_Free(void) { irrstExit(); }
|
||||||
|
|
||||||
|
enum Screen3DS Window_3DS_SetRenderScreen(enum Screen3DS screen) {
|
||||||
|
enum Screen3DS prev = renderScreen;
|
||||||
|
if (screen != prev)
|
||||||
|
{
|
||||||
|
renderScreen = screen;
|
||||||
|
DisplayInfo.Width = (screen == TOP_SCREEN) ? 400 : 320;
|
||||||
|
WindowInfo.Width = DisplayInfo.Width;
|
||||||
|
if (screen == TOP_SCREEN)
|
||||||
|
Gfx_3DS_DrawToTopScreen();
|
||||||
|
else
|
||||||
|
Gfx_3DS_DrawToBottomScreen();
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
void Window_Create2D(int width, int height) { launcherMode = true; }
|
void Window_Create2D(int width, int height) { launcherMode = true; }
|
||||||
void Window_Create3D(int width, int height) { launcherMode = false; }
|
void Window_Create3D(int width, int height) { launcherMode = false; }
|
||||||
|
|
||||||
@ -112,26 +128,26 @@ static void ProcessJoystickInput(circlePosition* pos, double delta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessTouchInput(int mods) {
|
static void ProcessTouchInput(int mods) {
|
||||||
|
static int currX, currY; // current touch position
|
||||||
touchPosition touch;
|
touchPosition touch;
|
||||||
hidTouchRead(&touch);
|
hidTouchRead(&touch);
|
||||||
touchActive = mods & KEY_TOUCH;
|
if (hidKeysDown() & KEY_TOUCH) { // stylus went down
|
||||||
|
currX = touch.px;
|
||||||
if (touchActive) {
|
currY = touch.py;
|
||||||
// rescale X from [0, bottom_FB_width) to [0, top_FB_width)
|
Input_AddTouch(0, currX, currY);
|
||||||
int x = touch.px * Window_Main.Width / GSP_SCREEN_HEIGHT_BOTTOM;
|
|
||||||
int y = touch.py;
|
|
||||||
Pointer_SetPosition(0, x, y);
|
|
||||||
}
|
}
|
||||||
// Set starting position for camera movement
|
else if (mods & KEY_TOUCH) { // stylus is down
|
||||||
if (hidKeysDown() & KEY_TOUCH) {
|
currX = touch.px;
|
||||||
touchBegX = touch.px;
|
currY = touch.py;
|
||||||
touchBegY = touch.py;
|
Input_UpdateTouch(0, currX, currY);
|
||||||
|
}
|
||||||
|
else if (hidKeysUp() & KEY_TOUCH) { // stylus was lifted
|
||||||
|
Input_RemoveTouch(0, currX, currY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window_ProcessEvents(double delta) {
|
void Window_ProcessEvents(double delta) {
|
||||||
hidScanInput();
|
hidScanInput();
|
||||||
/* TODO implement */
|
|
||||||
|
|
||||||
if (!aptMainLoop()) {
|
if (!aptMainLoop()) {
|
||||||
Window_Main.Exists = false;
|
Window_Main.Exists = false;
|
||||||
@ -142,7 +158,6 @@ void Window_ProcessEvents(double delta) {
|
|||||||
u32 mods = hidKeysDown() | hidKeysHeld();
|
u32 mods = hidKeysDown() | hidKeysHeld();
|
||||||
HandleButtons(mods);
|
HandleButtons(mods);
|
||||||
|
|
||||||
Input_SetNonRepeatable(CCMOUSE_L, mods & KEY_TOUCH);
|
|
||||||
ProcessTouchInput(mods);
|
ProcessTouchInput(mods);
|
||||||
|
|
||||||
if (Input.RawMode) {
|
if (Input.RawMode) {
|
||||||
@ -163,33 +178,29 @@ void Cursor_SetPosition(int x, int y) { } // Makes no sense for 3DS
|
|||||||
void Window_EnableRawMouse(void) { Input.RawMode = true; }
|
void Window_EnableRawMouse(void) { Input.RawMode = true; }
|
||||||
void Window_DisableRawMouse(void) { Input.RawMode = false; }
|
void Window_DisableRawMouse(void) { Input.RawMode = false; }
|
||||||
|
|
||||||
void Window_UpdateRawMouse(void) {
|
void Window_UpdateRawMouse(void) { }
|
||||||
if (!touchActive) return;
|
|
||||||
|
|
||||||
touchPosition touch;
|
|
||||||
hidTouchRead(&touch);
|
|
||||||
|
|
||||||
Event_RaiseRawMove(&PointerEvents.RawMoved,
|
|
||||||
touch.px - touchBegX, touch.py - touchBegY);
|
|
||||||
touchBegX = touch.px;
|
|
||||||
touchBegY = touch.py;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*------------------------------------------------------Framebuffer--------------------------------------------------------*
|
*------------------------------------------------------Framebuffer--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static struct Bitmap fb_bmp;
|
static struct Bitmap top_fb_bmp;
|
||||||
|
static struct Bitmap bottom_fb_bmp;
|
||||||
void Window_AllocFramebuffer(struct Bitmap* bmp) {
|
void Window_AllocFramebuffer(struct Bitmap* bmp) {
|
||||||
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
|
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
|
||||||
fb_bmp = *bmp;
|
if (renderScreen == TOP_SCREEN) {
|
||||||
|
top_fb_bmp = *bmp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bottom_fb_bmp = *bmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window_DrawFramebuffer(Rect2D r) {
|
void Window_DrawFramebuffer(Rect2D r) {
|
||||||
u16 width, height;
|
u16 width, height;
|
||||||
gfxSetDoubleBuffering(GFX_TOP, false);
|
gfxScreen_t screen = (renderScreen == TOP_SCREEN) ? GFX_TOP : GFX_BOTTOM;
|
||||||
u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &width, &height);
|
gfxSetDoubleBuffering(screen, false);
|
||||||
|
u8* fb = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height);
|
||||||
|
struct Bitmap *bmp = (renderScreen == TOP_SCREEN) ? &top_fb_bmp : &bottom_fb_bmp;
|
||||||
// SRC y = 0 to 240
|
// SRC y = 0 to 240
|
||||||
// SRC x = 0 to 400
|
// SRC x = 0 to 400
|
||||||
// DST X = 0 to 240
|
// DST X = 0 to 240
|
||||||
@ -198,7 +209,7 @@ void Window_DrawFramebuffer(Rect2D r) {
|
|||||||
for (int y = r.y; y < r.y + r.Height; y++)
|
for (int y = r.y; y < r.y + r.Height; y++)
|
||||||
for (int x = r.x; x < r.x + r.Width; x++)
|
for (int x = r.x; x < r.x + r.Width; x++)
|
||||||
{
|
{
|
||||||
BitmapCol color = Bitmap_GetPixel(&fb_bmp, x, y);
|
BitmapCol color = Bitmap_GetPixel(bmp, x, y);
|
||||||
int addr = (width - 1 - y + x * width) * 3; // TODO -1 or not
|
int addr = (width - 1 - y + x * width) * 3; // TODO -1 or not
|
||||||
fb[addr+0] = BitmapCol_B(color);
|
fb[addr+0] = BitmapCol_B(color);
|
||||||
fb[addr+1] = BitmapCol_G(color);
|
fb[addr+1] = BitmapCol_G(color);
|
||||||
@ -209,10 +220,12 @@ void Window_DrawFramebuffer(Rect2D r) {
|
|||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
//gfxSwapBuffers();
|
//gfxSwapBuffers();
|
||||||
// TODO: tearing??
|
// TODO: tearing??
|
||||||
|
/*
|
||||||
gfxSetDoubleBuffering(GFX_TOP, false);
|
gfxSetDoubleBuffering(GFX_TOP, false);
|
||||||
gfxScreenSwapBuffers(GFX_TOP, true);
|
gfxScreenSwapBuffers(GFX_TOP, true);
|
||||||
gfxSetDoubleBuffering(GFX_TOP, true);
|
gfxSetDoubleBuffering(GFX_TOP, true);
|
||||||
gfxScreenSwapBuffers(GFX_BOTTOM, true);
|
gfxScreenSwapBuffers(GFX_BOTTOM, true);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window_FreeFramebuffer(struct Bitmap* bmp) {
|
void Window_FreeFramebuffer(struct Bitmap* bmp) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user