WiiU: Draw launcher output on both screens

This commit is contained in:
UnknownShadow200 2024-04-20 08:46:39 +10:00
parent 95d5cd5e09
commit 2c5d0f5e77
2 changed files with 62 additions and 36 deletions

View File

@ -40,11 +40,10 @@ static vdp1_cmdt_draw_mode_t _primitive_draw_mode = {
.raw = 0x0000
};
static struct {
int16_vec2_t points[4];
} _primitive;
static int16_vec2_t clear_points[4];
// TODO: how to use VDP1 erase ??
static void UpdateVDP1Env(void) {
vdp1_env_t env;
vdp1_env_default_init(&env);
@ -57,18 +56,19 @@ static void UpdateVDP1Env(void) {
vdp1_env_set(&env);
}
// TODO: should be SCREEN_WIDTH/2 instead ?
static void _primitive_init(void) {
_primitive.points[0].x = 0;
_primitive.points[0].y = SCREEN_WIDTH - 1;
clear_points[0].x = 0;
clear_points[0].y = SCREEN_WIDTH - 1;
_primitive.points[1].x = SCREEN_WIDTH - 1;
_primitive.points[1].y = SCREEN_HEIGHT - 1;
clear_points[1].x = SCREEN_WIDTH - 1;
clear_points[1].y = SCREEN_HEIGHT - 1;
_primitive.points[2].x = SCREEN_HEIGHT - 1;
_primitive.points[2].y = 0;
clear_points[2].x = SCREEN_HEIGHT - 1;
clear_points[2].y = 0;
_primitive.points[3].x = 0;
_primitive.points[3].y = 0;
clear_points[3].x = 0;
clear_points[3].y = 0;
}
static GfxResourceID white_square;
@ -403,7 +403,7 @@ void Gfx_BeginFrame(void) {
vdp1_cmdt_polygon_set(cmd);
vdp1_cmdt_color_set(cmd, RGB1555(1, R >> 3, G >> 3, B >> 3)); // TODO VDP1 erase
vdp1_cmdt_draw_mode_set(cmd, _primitive_draw_mode);
vdp1_cmdt_vtx_set(cmd, &_primitive.points[0]);
vdp1_cmdt_vtx_set(cmd, clear_points);
}
void Gfx_EndFrame(void) {

View File

@ -21,6 +21,7 @@
#include <vpad/input.h>
#include <whb/proc.h>
#include <padscore/kpad.h>
#include <avm/drc.h>
static cc_bool launcherMode;
struct _DisplayData DisplayInfo;
@ -28,7 +29,7 @@ struct _WindowData WindowInfo;
struct _WindowData Window_Alt;
cc_bool launcherTop;
void Window_Init(void) {
static void LoadTVDimensions(void) {
switch(GX2GetSystemTVScanMode())
{
case GX2_TV_SCAN_MODE_480I:
@ -47,7 +48,10 @@ void Window_Init(void) {
DisplayInfo.Height = 720;
break;
}
}
void Window_Init(void) {
LoadTVDimensions();
DisplayInfo.ScaleX = 1;
DisplayInfo.ScaleY = 1;
@ -72,10 +76,15 @@ void Window_Init(void) {
void Window_Free(void) { }
// OSScreen is always this buffer size, regardless of the current TV resolution
#define OSSCREEN_TV_WIDTH 1280
#define OSSCREEN_TV_HEIGHT 720
#define OSSCREEN_DRC_WIDTH 854
#define OSSCREEN_DRC_HEIGHT 480
void Window_Create2D(int width, int height) {
// well this works in CEMU at least
Window_Main.Width = 1280;
Window_Main.Height = 720;
Window_Main.Width = OSSCREEN_DRC_WIDTH;
Window_Main.Height = OSSCREEN_DRC_HEIGHT;
launcherMode = true;
}
@ -137,9 +146,14 @@ static void ProcessVpadTouch(VPADTouchData* data) {
// TODO rescale to main screen size
if (data->touched) {
int x = data->x, y = data->y;
int x = data->x;
int y = data->y;
Platform_Log2("TOUCH: %i, %i", &x, &y);
Input_AddTouch(0, data->x, data->y);
x = x * Window_Main.Width / 1280;
y = y * Window_Main.Height / 720;
Input_AddTouch(0, x, y);
} else if (was_touched) {
Input_RemoveTouch(0, Pointers[0].x, Pointers[0].y);
}
@ -189,31 +203,43 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
}
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
if (launcherTop) return; // TODO: Draw on DRC properly
/*for (int y = r.y; y < r.y + r.height; y++)
{
cc_uint32* src = bmp->scan0 + y * bmp->width;
for (int x = r.x; x < r.x + r.width; x++) {
OSScreenPutPixelEx(SCREEN_TV, x, y, src[x]);
}
}*/
#define TV_OFFSET_X (OSSCREEN_TV_WIDTH - OSSCREEN_DRC_WIDTH ) / 2
#define TV_OFFSET_Y (OSSCREEN_TV_HEIGHT - OSSCREEN_DRC_HEIGHT) / 2
static void DrawTVOutput(struct Bitmap* bmp) {
OSScreenClearBufferEx(SCREEN_TV, 0);
for (int y = 0; y < bmp->height; y++)
{
cc_uint32* src = bmp->scan0 + y * bmp->width;
for (int x = 0; x < bmp->width; x++) {
OSScreenPutPixelEx(SCREEN_TV, x, y, src[x]);
OSScreenPutPixelEx(SCREEN_TV, x + TV_OFFSET_X, y + TV_OFFSET_Y, src[x]);
}
}
//DCFlushRange(sBufferTV, sBufferSizeTV);
OSScreenFlipBuffersEx(SCREEN_TV);
OSScreenClearBufferEx(SCREEN_DRC, Launcher_Theme.BackgroundColor);
}
static void DrawDRCOutput(struct Bitmap* bmp) {
for (int y = 0; y < bmp->height; y++)
{
cc_uint32* src = bmp->scan0 + y * bmp->width;
for (int x = 0; x < bmp->width; x++) {
OSScreenPutPixelEx(SCREEN_DRC, x, y, src[x]);
}
}
OSScreenFlipBuffersEx(SCREEN_DRC);
}
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
if (launcherTop) return;
// Draw launcher output on both DRC and TV
// NOTE: Partial redraws produce bogus output, so always have to redraw all
DrawTVOutput(bmp);
DrawDRCOutput(bmp);
}
void Window_FreeFramebuffer(struct Bitmap* bmp) {
@ -257,4 +283,4 @@ cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
return ERR_NOT_SUPPORTED;
}
#endif
#endif