From 4a328960a4d744c096d3c80df6bd29c352768b4b Mon Sep 17 00:00:00 2001 From: Toad King Date: Mon, 6 Aug 2012 22:30:18 -0400 Subject: [PATCH] (Wii) prepare RGUI/gx_video for in-game menu --- console/rgui/rgui.c | 46 ++++++++++++++-------------- console/rgui/rgui.h | 2 +- wii/driver.h | 2 +- wii/frontend/main.c | 12 ++++---- wii/gx_video.c | 73 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 98 insertions(+), 37 deletions(-) diff --git a/console/rgui/rgui.c b/console/rgui/rgui.c index 3dc8c363ef..408c0a27b2 100644 --- a/console/rgui/rgui.c +++ b/console/rgui/rgui.c @@ -35,7 +35,7 @@ extern char app_dir[PATH_MAX]; struct rgui_handle { - uint16_t *frame_buf; + uint32_t *frame_buf; size_t frame_buf_pitch; const uint8_t *font_buf; @@ -49,8 +49,8 @@ struct rgui_handle char path_buf[PATH_MAX]; - uint16_t font_white[256][FONT_HEIGHT][FONT_WIDTH]; - uint16_t font_green[256][FONT_HEIGHT][FONT_WIDTH]; + uint32_t font_white[256][FONT_HEIGHT][FONT_WIDTH]; + uint32_t font_green[256][FONT_HEIGHT][FONT_WIDTH]; }; static const char *rgui_device_lables[] = { @@ -89,8 +89,8 @@ static inline bool rgui_is_filebrowser_menu(rgui_file_type_t menu_type) return (menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE || menu_type == RGUI_SETTINGS_CORE); } -static void copy_glyph(uint16_t glyph_white[FONT_HEIGHT][FONT_WIDTH], - uint16_t glyph_green[FONT_HEIGHT][FONT_WIDTH], +static void copy_glyph(uint32_t glyph_white[FONT_HEIGHT][FONT_WIDTH], + uint32_t glyph_green[FONT_HEIGHT][FONT_WIDTH], const uint8_t *buf) { for (int y = 0; y < FONT_HEIGHT; y++) @@ -102,8 +102,8 @@ static void copy_glyph(uint16_t glyph_white[FONT_HEIGHT][FONT_WIDTH], ((uint32_t)buf[3 * (-y * 256 + x) + 1] << 8) | ((uint32_t)buf[3 * (-y * 256 + x) + 2] << 16); - glyph_white[y][x] = col == 0xff ? 0 : 0x7fff; - glyph_green[y][x] = col == 0xff ? 0 : (5 << 10) | (20 << 5) | (5 << 0); + glyph_white[y][x] = col == 0xff ? 0 : 0xffffffff; + glyph_green[y][x] = col == 0xff ? 0 : (255 << 24) | (40 << 16) | (160 << 8) | (40 << 0); } } } @@ -121,7 +121,7 @@ static void init_font(rgui_handle_t *rgui, const char *path) } rgui_handle_t *rgui_init(const char *base_path, - uint16_t *buf, size_t buf_pitch, + uint32_t *buf, size_t buf_pitch, const uint8_t *font_buf, rgui_folder_enum_cb_t folder_cb, void *userdata) { @@ -150,32 +150,32 @@ void rgui_free(rgui_handle_t *rgui) free(rgui); } -static uint16_t gray_filler(unsigned x, unsigned y) +static uint32_t gray_filler(unsigned x, unsigned y) { x >>= 1; y >>= 1; - uint16_t col = ((x + y) & 1) + 1; - col <<= 1; - return (col << 0) | (col << 5) | (col << 10); + unsigned col = ((x + y) & 1) + 1; + col <<= 4; + return (224 << 24) | (col << 16) | (col << 8) | (col << 0); } -static uint16_t green_filler(unsigned x, unsigned y) +static uint32_t green_filler(unsigned x, unsigned y) { x >>= 1; y >>= 1; - uint16_t col = ((x + y) & 1) + 1; - col <<= 1; - return (col << 0) | (col << 6) | (col << 10); + unsigned col = ((x + y) & 1) + 1; + col <<= 3; + return (224 << 24) | (col << 16) | (col << 10) | (col << 0); } -static void fill_rect(uint16_t *buf, unsigned pitch, +static void fill_rect(uint32_t *buf, unsigned pitch, unsigned x, unsigned y, unsigned width, unsigned height, - uint16_t (*col)(unsigned x, unsigned y)) + uint32_t (*col)(unsigned x, unsigned y)) { for (unsigned j = y; j < y + height; j++) for (unsigned i = x; i < x + width; i++) - buf[j * (pitch >> 1) + i] = col(i, j); + buf[j * (pitch >> 2) + i] = col(i, j); } static void blit_line(rgui_handle_t *rgui, @@ -187,12 +187,12 @@ static void blit_line(rgui_handle_t *rgui, { for (unsigned i = 0; i < FONT_WIDTH; i++) { - uint16_t col = green ? + uint32_t col = green ? rgui->font_green[(unsigned char)*message][j][i] : rgui->font_white[(unsigned char)*message][j][i]; if (col) - rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 1) + (x + i)] = col; + rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 2) + (x + i)] = col; } } @@ -511,7 +511,7 @@ static const char *rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t acti label = app_dir; const char *dir = 0; rgui_file_type_t menu_type = 0; - size_t directory_ptr; + size_t directory_ptr = 0; rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); if (rgui->need_refresh) @@ -588,7 +588,7 @@ const char *rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) bool found = false; const char *dir = 0; rgui_file_type_t menu_type = 0; - size_t directory_ptr; + size_t directory_ptr = 0; rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); if (menu_type == RGUI_SETTINGS || rgui_is_controller_menu(menu_type)) diff --git a/console/rgui/rgui.h b/console/rgui/rgui.h index 5e74acce10..c1875f0a6d 100644 --- a/console/rgui/rgui.h +++ b/console/rgui/rgui.h @@ -86,7 +86,7 @@ typedef bool (*rgui_folder_enum_cb_t)(const char *directory, #define RGUI_HEIGHT 240 rgui_handle_t *rgui_init(const char *base_path, - uint16_t *framebuf, size_t framebuf_pitch, + uint32_t *framebuf, size_t framebuf_pitch, const uint8_t *font_buf, rgui_folder_enum_cb_t folder_cb, void *userdata); diff --git a/wii/driver.h b/wii/driver.h index 4dcac411da..20cc5fc8c2 100644 --- a/wii/driver.h +++ b/wii/driver.h @@ -16,7 +16,7 @@ #ifndef WII_VIDEO_H__ #define WII_VIDEO_H__ -void wii_video_init(void); +void wii_video_init(uint32_t *menu_buffer); void wii_video_deinit(void); void wii_input_init(void); diff --git a/wii/frontend/main.c b/wii/frontend/main.c index 19588b01f7..1e7fd69bbf 100644 --- a/wii/frontend/main.c +++ b/wii/frontend/main.c @@ -44,7 +44,7 @@ FILE * log_fp; #endif -static uint16_t menu_framebuf[RGUI_WIDTH * RGUI_HEIGHT]; +static uint32_t menu_framebuf[RGUI_WIDTH * RGUI_HEIGHT]; char app_dir[PATH_MAX]; struct retro_system_info wii_core_info; @@ -181,9 +181,9 @@ static bool get_rom_path(rgui_handle_t *rgui) } const char *ret = rgui_iterate(rgui, action); - video_wii.frame(NULL, menu_framebuf, - RGUI_WIDTH, RGUI_HEIGHT, - RGUI_WIDTH * sizeof(uint16_t), NULL); + video_wii.frame(NULL, NULL, + 0, 0, + 0, NULL); if (ret) { @@ -242,7 +242,7 @@ int main(void) retro_get_system_info(&wii_core_info); RARCH_LOG("Core: %s\n", wii_core_info.library_name); - wii_video_init(); + wii_video_init(menu_framebuf); char tmp_path[PATH_MAX]; const char *extension = default_paths.executable_extension; @@ -262,7 +262,7 @@ int main(void) input_wii.post_init(); rgui_handle_t *rgui = rgui_init("", - menu_framebuf, RGUI_WIDTH * sizeof(uint16_t), + menu_framebuf, RGUI_WIDTH * sizeof(uint32_t), _binary_console_font_bmp_start, folder_cb, NULL); rgui_iterate(rgui, RGUI_ACTION_REFRESH); diff --git a/wii/gx_video.c b/wii/gx_video.c index 0f2d47665f..238463fc99 100644 --- a/wii/gx_video.c +++ b/wii/gx_video.c @@ -38,6 +38,14 @@ struct GXTexObj obj; } static g_tex ATTRIBUTE_ALIGN(32); +struct +{ + uint32_t data[240 * 320]; + GXTexObj obj; +} static menu_tex ATTRIBUTE_ALIGN(32); + +static uint32_t *menu_data; + static uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32); static uint8_t display_list[1024] ATTRIBUTE_ALIGN(32); static size_t display_list_size; @@ -120,6 +128,8 @@ static void init_vtx(GXRModeObj *mode) GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); GX_InvVtxCache(); + GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0); + GX_Flush(); } @@ -127,7 +137,8 @@ static void init_texture(unsigned width, unsigned height) { GX_InitTexObj(&g_tex.obj, g_tex.data, width, height, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObjLOD(&g_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1); - GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); + GX_InitTexObj(&menu_tex.obj, menu_tex.data, 320, 240, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjLOD(&menu_tex.obj, g_filter, g_filter, 0, 0, 0, GX_TRUE, GX_FALSE, GX_ANISO_1); GX_InvalidateTexAll(); } @@ -145,7 +156,7 @@ static void build_disp_list(void) display_list_size = GX_EndDispList(); } -void wii_video_init(void) +void wii_video_init(uint32_t *menu_buffer) { VIDEO_Init(); GXRModeObj *mode = VIDEO_GetPreferredMode(NULL); @@ -161,6 +172,7 @@ void wii_video_init(void) g_filter = true; g_vsync = true; + menu_data = menu_buffer; } void wii_video_deinit(void) @@ -289,6 +301,20 @@ static void update_texture_asm(const uint32_t *src, src += pitch; \ } +#define BLIT_16(x) \ +{ \ + block[0 + 0 ] = line[x][0]; \ + block[0 + 16] = line[x][1]; \ + block[1 + 0 ] = line[x][2]; \ + block[1 + 16] = line[x][3]; \ + block[2 + 0 ] = line[x][4]; \ + block[2 + 16] = line[x][5]; \ + block[3 + 0 ] = line[x][6]; \ + block[3 + 16] = line[x][7]; \ + block += 4; \ + line[x] += 8; \ +} + static void update_texture(const uint32_t *src, unsigned width, unsigned height, unsigned pitch) { @@ -317,8 +343,33 @@ static void update_texture(const uint32_t *src, } } + // TODO: only convert when menu is visible + { + uint16_t *block = (uint16_t *) menu_tex.data; + uint16_t *line[4]; + for (uint32_t y = 0; y < 240; y += 4) + { + // fetch the next 4 scanlines + line[0] = (uint16_t *) &menu_data[(y + 0) * 320]; + line[1] = (uint16_t *) &menu_data[(y + 1) * 320]; + line[2] = (uint16_t *) &menu_data[(y + 2) * 320]; + line[3] = (uint16_t *) &menu_data[(y + 3) * 320]; + + for (unsigned x = 0; x < 320; x += 4) + { + BLIT_16(0) + BLIT_16(1) + BLIT_16(2) + BLIT_16(3) + + block += 16; + } + } + } + init_texture(width, height); DCFlushRange(g_tex.data, sizeof(g_tex.data)); + DCFlushRange(menu_tex.data, sizeof(menu_tex.data)); GX_InvalidateTexAll(); } @@ -329,8 +380,8 @@ static bool wii_frame(void *data, const void *frame, (void)data; (void)msg; - if(!frame) - return true; + //if(!frame) + // return true; while (g_vsync && !g_draw_done) LWP_ThreadSleep(g_video_cond); @@ -338,8 +389,18 @@ static bool wii_frame(void *data, const void *frame, g_draw_done = false; g_current_framebuf ^= 1; update_texture(frame, width, height, pitch); - GX_CallDispList(display_list, display_list_size); - GX_DrawDone(); + if (frame) + { + GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); + GX_CallDispList(display_list, display_list_size); + GX_DrawDone(); + } + else // TODO: in-game menu still needs this + { + GX_LoadTexObj(&menu_tex.obj, GX_TEXMAP0); + GX_CallDispList(display_list, display_list_size); + GX_DrawDone(); + } GX_CopyDisp(g_framebuf[g_current_framebuf], GX_TRUE); GX_Flush();