(GX) fix up bugs on switching screen resolution

change RGUI dimensions to display better with different resolutions
This commit is contained in:
Toad King 2012-09-11 23:33:44 -04:00
parent 0a5c5ca1c5
commit e8ad25aef3
5 changed files with 90 additions and 67 deletions

View File

@ -61,6 +61,7 @@ unsigned rgui_gx_resolutions[GX_RESOLUTIONS_LAST] = {
unsigned rgui_current_gx_resolution = GX_RESOLUTIONS_DEFAULT;
#endif
unsigned RGUI_WIDTH = 320;
unsigned RGUI_HEIGHT = 240;
struct rgui_handle
@ -214,7 +215,7 @@ static void fill_rect(uint16_t *buf, unsigned pitch,
{
for (unsigned j = y; j < y + height; j++)
for (unsigned i = x; i < x + width; i++)
buf[j * (pitch >> 2) + i] = col(i, j);
buf[j * (pitch >> 1) + i] = col(i, j);
}
static void blit_line(rgui_handle_t *rgui,
@ -231,7 +232,7 @@ static void blit_line(rgui_handle_t *rgui,
bool col = (rgui->font[FONT_OFFSET((unsigned char)*message) + offset] & rem);
if (col)
rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 2) + (x + i)] = green ?
rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 1) + (x + i)] = green ?
(3 << 0) | (10 << 4) | (3 << 8) | (7 << 12) : 0x7FFF;
}
}
@ -465,9 +466,9 @@ static void render_text(rgui_handle_t *rgui)
entry_title = path;
}
snprintf(message, sizeof(message), "%c %-*s %-*s\n",
snprintf(message, sizeof(message), "%c %-*.*s %-*s\n",
i == rgui->directory_ptr ? '>' : ' ',
TERM_WIDTH - (w + 1 + 2),
TERM_WIDTH - (w + 1 + 2), TERM_WIDTH - (w + 1 + 2),
entry_title,
w,
type_str);
@ -562,34 +563,21 @@ static void rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
#endif
#ifdef GEKKO
case RGUI_SETTINGS_VIDEO_RESOLUTION:
if (action == RGUI_ACTION_LEFT)
{
unsigned newHeight;
if (action == RGUI_ACTION_LEFT)
if(rgui_current_gx_resolution > 0)
{
if(rgui_current_gx_resolution > 0)
{
rgui_current_gx_resolution--;
gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution]);
}
rgui_current_gx_resolution--;
gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution]);
}
else if (action == RGUI_ACTION_RIGHT)
}
else if (action == RGUI_ACTION_RIGHT)
{
if(rgui_current_gx_resolution < GX_RESOLUTIONS_LAST - 1)
{
if(rgui_current_gx_resolution < GX_RESOLUTIONS_LAST - 1)
{
rgui_current_gx_resolution++;
gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution]);
}
rgui_current_gx_resolution++;
gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution]);
}
sscanf(gx_get_video_mode(), "%u", &newHeight);
if (newHeight > 300)
newHeight /= 2;
if (newHeight < 240)
RGUI_HEIGHT = newHeight;
else
RGUI_HEIGHT = 240;
}
break;
#endif
@ -951,6 +939,7 @@ void rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
void rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
{
rgui->frame_buf_pitch = RGUI_WIDTH * 2;
rgui_file_type_t type = 0;
const char *label = 0;
rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL);

View File

@ -104,7 +104,7 @@ typedef void (*rgui_file_enum_cb_t)(void *ctx,
typedef bool (*rgui_folder_enum_cb_t)(const char *directory,
rgui_file_enum_cb_t file_cb, void *userdata, void *ctx);
#define RGUI_WIDTH 320
extern unsigned RGUI_WIDTH;
extern unsigned RGUI_HEIGHT;
rgui_handle_t *rgui_init(const char *base_path,

View File

@ -396,7 +396,7 @@ static void menu_loop(void)
static void menu_init(void)
{
rgui = rgui_init("",
menu_framebuf, RGUI_WIDTH * sizeof(uint32_t),
menu_framebuf, RGUI_WIDTH * sizeof(uint16_t),
NULL /* _binary_console_font_bmp_start */, _binary_console_font_bin_start, folder_cb, NULL);
g_console.mode_switch = MODE_MENU;

View File

@ -85,6 +85,10 @@ static void retrace_callback(u32 retrace_count)
void gx_set_video_mode(unsigned lines)
{
VIDEO_SetBlack(true);
VIDEO_ClearFrameBuffer(&gx_mode, g_framebuf[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(&gx_mode, g_framebuf[1], COLOR_BLACK);
VIDEO_Flush();
gx_video_t *gx = (gx_video_t*)driver.video_data;
unsigned fbWidth = 640;
unsigned modetype;
@ -204,8 +208,18 @@ config:
gx->win_width = gx_mode.fbWidth;
gx->win_height = gx_mode.efbHeight;
gx->double_strike = modetype == VI_NON_INTERLACE;
gx->should_resize = true;
RGUI_HEIGHT = gx_mode.efbHeight / (gx->double_strike ? 1 : 2);
RGUI_HEIGHT &= ~3;
if (RGUI_HEIGHT > 240)
RGUI_HEIGHT = 240;
RGUI_WIDTH = gx_mode.fbWidth / 2;
RGUI_WIDTH &= ~3;
if (RGUI_WIDTH > 320)
RGUI_WIDTH = 320;
VIDEO_Configure(&gx_mode);
VIDEO_SetNextFramebuffer(g_framebuf[g_current_framebuf]);
VIDEO_SetPostRetraceCallback(retrace_callback);
@ -227,8 +241,6 @@ config:
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_InvalidateTexAll();
VIDEO_ClearFrameBuffer(&gx_mode, g_framebuf[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer(&gx_mode, g_framebuf[1], COLOR_BLACK);
g_current_framebuf = 0;
}
@ -264,6 +276,7 @@ static void setup_video_mode()
g_orientation = ORIENTATION_NORMAL;
LWP_InitQueue(&g_video_cond);
gx_mode = *VIDEO_GetPreferredMode(NULL);
gx_set_video_mode(0);
}
@ -308,6 +321,8 @@ static void init_vtx()
GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0);
memset(g_tex.data, 0, sizeof(g_tex.data));
DCFlushRange(g_tex.data, sizeof(g_tex.data));
init_texture(4, 4); // for menu texture
GX_Flush();
}
@ -527,32 +542,35 @@ static void update_texture(const uint32_t *src,
unsigned width, unsigned height, unsigned pitch)
{
gx_video_t *gx = (gx_video_t*)driver.video_data;
if (src)
{
#ifdef ASM_BLITTER
if (width && height && !(width & 3) && !(height & 3))
{
update_texture_asm(src, g_tex.data, width, height, pitch, 0x80008000U);
}
else
#endif
{
width &= ~15;
height &= ~3;
unsigned tmp_pitch = pitch >> 2;
unsigned width2 = width >> 1;
// Texture data is 4x4 tiled @ 15bpp.
// Use 32-bit to transfer more data per cycle.
const uint32_t *src2 = src;
uint32_t *dst = g_tex.data;
for (unsigned i = 0; i < height; i += 4, dst += 4 * width2)
if (width && height && !(width & 3) && !(height & 3))
{
// Set MSB to get full RGB555.
update_texture_asm(src, g_tex.data, width, height, pitch, 0x80008000U);
}
else
#endif
{
width &= ~15;
height &= ~3;
unsigned tmp_pitch = pitch >> 2;
unsigned width2 = width >> 1;
// Texture data is 4x4 tiled @ 15bpp.
// Use 32-bit to transfer more data per cycle.
const uint32_t *src2 = src;
uint32_t *dst = g_tex.data;
for (unsigned i = 0; i < height; i += 4, dst += 4 * width2)
{
// Set MSB to get full RGB555.
#define RGB15toRGB5A3(col) ((col) | 0x80008000u)
BLIT_LINE(0)
BLIT_LINE(2)
BLIT_LINE(4)
BLIT_LINE(6)
BLIT_LINE(0)
BLIT_LINE(2)
BLIT_LINE(4)
BLIT_LINE(6)
#undef RGB15toRGB5A3
}
}
}
@ -679,19 +697,21 @@ static void gx_resize(gx_video_t *gx)
guMtxConcat(m1, m2, m1);
GX_LoadPosMtxImm(m1, GX_PNMTX0);
init_texture(4, 4);
gx_old_width = gx_old_height = 0;
gx->should_resize = false;
}
static void gx_blit_line(unsigned x, unsigned y, const char *message)
{
gx_video_t *gx = (gx_video_t*)driver.video_data;
const GXColor b = {
.r = 0x00,
.g = 0x00,
.b = 0x00,
.a = 0xff
};
const GXColor w = {
.r = 0xff,
.g = 0xff,
@ -701,7 +721,11 @@ static void gx_blit_line(unsigned x, unsigned y, const char *message)
unsigned h;
for (h = 0; h < FONT_HEIGHT * 2; h++)
if (!*message)
return;
unsigned height = FONT_HEIGHT * (gx->double_strike ? 1 : 2);
for (h = 0; h < height; h++)
{
GX_PokeARGB(x, y + h, b);
GX_PokeARGB(x + 1, y + h, b);
@ -725,14 +749,22 @@ static void gx_blit_line(unsigned x, unsigned y, const char *message)
else
c = b;
GX_PokeARGB(x + (i * 2), y + (j * 2), c);
GX_PokeARGB(x + (i * 2) + 1, y + (j * 2), c);
GX_PokeARGB(x + (i * 2) + 1, y + (j * 2) + 1, c);
GX_PokeARGB(x + (i * 2), y + (j * 2) + 1, c);
if (!gx->double_strike)
{
GX_PokeARGB(x + (i * 2), y + (j * 2), c);
GX_PokeARGB(x + (i * 2) + 1, y + (j * 2), c);
GX_PokeARGB(x + (i * 2) + 1, y + (j * 2) + 1, c);
GX_PokeARGB(x + (i * 2), y + (j * 2) + 1, c);
}
else
{
GX_PokeARGB(x + (i * 2), y + j, c);
GX_PokeARGB(x + (i * 2) + 1, y + j, c);
}
}
}
for (unsigned h = 0; h < FONT_HEIGHT * 2; h++)
for (unsigned h = 0; h < height; h++)
{
GX_PokeARGB(x + (FONT_WIDTH * 2), y + h, b);
GX_PokeARGB(x + (FONT_WIDTH * 2) + 1, y + h, b);
@ -761,6 +793,11 @@ static bool gx_frame(void *data, const void *frame,
if(!frame && !menu_render)
return true;
if (!frame)
{
width = height = 4; // draw a black square in the background
}
gx->frame_count++;
if(should_resize)
@ -782,7 +819,7 @@ static bool gx_frame(void *data, const void *frame,
g_current_framebuf ^= 1;
update_texture(frame, width, height, pitch);
if (frame)
//if (frame)
{
GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0);
GX_CallDispList(display_list, display_list_size);
@ -805,22 +842,18 @@ static bool gx_frame(void *data, const void *frame,
gfx_window_title(fps_txt, sizeof(fps_txt));
gx_blit_line(x, y, fps_txt);
y += FONT_HEIGHT * 2;
y += FONT_HEIGHT * (gx->double_strike ? 1 : 2);
snprintf(mem1_txt, sizeof(mem1_txt), "MEM1: %8d / %8d", SYSMEM1_SIZE - SYS_GetArena1Size(), SYSMEM1_SIZE);
gx_blit_line(x, y, mem1_txt);
#ifdef HW_RVL
y += FONT_HEIGHT * 2;
y += FONT_HEIGHT * (gx->double_strike ? 1 : 2);
char mem2_txt[128];
snprintf(mem2_txt, sizeof(mem2_txt), "MEM2: %8d / %8d", gx_mem2_used(), gx_mem2_total());
gx_blit_line(x, y, mem2_txt);
#endif
}
#ifdef TAKE_EFB_SCREENSHOT_ON_EXIT
GX_CopyDisp(g_framebuf[g_current_framebuf], GX_FALSE);
#else
GX_CopyDisp(g_framebuf[g_current_framebuf], GX_TRUE);
#endif
GX_Flush();
VIDEO_SetNextFramebuffer(g_framebuf[g_current_framebuf]);
VIDEO_Flush();

View File

@ -21,6 +21,7 @@ typedef struct gx_video
bool menu_render;
bool should_resize;
bool keep_aspect;
bool double_strike;
uint32_t frame_count;
uint32_t *menu_data;
unsigned win_width;