diff --git a/gfx/drivers/wiiu_gfx.c b/gfx/drivers/wiiu_gfx.c index 189931af45..3ada394ce5 100644 --- a/gfx/drivers/wiiu_gfx.c +++ b/gfx/drivers/wiiu_gfx.c @@ -39,6 +39,8 @@ #define _1 0x05 #define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3)) +//#define GX2_CAN_ACCESS_DATA_SECTION + typedef struct { int width; @@ -87,9 +89,16 @@ typedef struct void* cmd_buffer; wiiu_render_mode_t render_mode; + video_viewport_t vp; int frames; OSTime last_vsync; bool vsync; + bool rgb32; + bool smooth; + unsigned rotation; + bool keep_aspect; + bool should_resize; + } wiiu_video_t; static const wiiu_render_mode_t wiiu_render_mode_map[] = @@ -106,15 +115,14 @@ static const wiiu_render_mode_t wiiu_render_mode_map[] = static wiiu_set_position(position_t* position, GX2ColorBuffer* draw_buffer, float x0, float y0, float x1, float y1) { - position[0].x = -1.0f; - position[0].y = -1.0f; - position[1].x = 1.0f; - position[1].y = -1.0f; - position[2].x = 1.0f; - position[2].y = 1.0f; - position[3].x = -1.0f; - position[3].y = 1.0f; - + position[0].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f; + position[0].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f; + position[1].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;; + position[1].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f; + position[2].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;; + position[2].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f; + position[3].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;; + position[3].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f; GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, position, 4 * sizeof(*position)); } @@ -132,6 +140,123 @@ static void wiiu_set_tex_coords(tex_coord_t* tex_coord, GX2Texture* texture, flo GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, tex_coord, 4 * sizeof(*tex_coord)); } +static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu) +{ + int x = 0; + int y = 0; + float width = wiiu->vp.full_width; + float height = wiiu->vp.full_height; + settings_t *settings = config_get_ptr(); + float desired_aspect = video_driver_get_aspect_ratio(); + + if(wiiu->rotation & 0x1) + desired_aspect = 1.0 / desired_aspect; + + if (settings->video.scale_integer) + { + video_viewport_get_scaled_integer(&wiiu->vp, wiiu->vp.full_width, + wiiu->vp.full_height, desired_aspect, wiiu->keep_aspect); + } + else if (wiiu->keep_aspect) + { +#if defined(HAVE_MENU) + if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) + { + struct video_viewport *custom = video_viewport_get_custom(); + + if (custom) + { + x = custom->x; + y = custom->y; + width = custom->width; + height = custom->height; + } + } + else +#endif + { + float delta; + float device_aspect = ((float)wiiu->vp.full_width) / wiiu->vp.full_height; + + if (fabsf(device_aspect - desired_aspect) < 0.0001f) + { + /* If the aspect ratios of screen and desired aspect + * ratio are sufficiently equal (floating point stuff), + * assume they are actually equal. + */ + } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0f) + / 2.0f + 0.5f; + x = (int)roundf(width * (0.5f - delta)); + width = (unsigned)roundf(2.0f * width * delta); + } + else + { + delta = (device_aspect / desired_aspect - 1.0f) + / 2.0f + 0.5f; + y = (int)roundf(height * (0.5f - delta)); + height = (unsigned)roundf(2.0f * height * delta); + } + } + + wiiu->vp.x = x; + wiiu->vp.y = y; + wiiu->vp.width = width; + wiiu->vp.height = height; + } + else + { + wiiu->vp.x = wiiu->vp.y = 0; + wiiu->vp.width = width; + wiiu->vp.height = height; + } + + + float scale_w = wiiu->color_buffer.surface.width / 854.0; + float scale_h = wiiu->color_buffer.surface.height / 480.0; + wiiu_set_position(wiiu->position, &wiiu->color_buffer, + wiiu->vp.x * scale_w, + wiiu->vp.y * scale_h, + (wiiu->vp.x + wiiu->vp.width) * scale_w, + (wiiu->vp.y + wiiu->vp.height) * scale_h); + + wiiu->should_resize = false; + DEBUG_LINE(); + +} + +static void wiiu_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) +{ + wiiu_video_t *wiiu = (wiiu_video_t*)data; + + switch (aspect_ratio_idx) + { + case ASPECT_RATIO_SQUARE: + video_driver_set_viewport_square_pixel(); + break; + + case ASPECT_RATIO_CORE: + video_driver_set_viewport_core(); + break; + + case ASPECT_RATIO_CONFIG: + video_driver_set_viewport_config(); + break; + + default: + break; + } + + video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value); + + if(!wiiu) + return; + + wiiu->keep_aspect = true; + wiiu->should_resize = true; +} static void* wiiu_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) @@ -208,15 +333,16 @@ static void* wiiu_gfx_init(const video_info_t* video, GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS); GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE); #if 1 - GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, - GX2_BLEND_COMBINE_MODE_ADD, + GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD, GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD); #else GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD, GX2_DISABLE, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD); #endif GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE); - +#ifdef GX2_CAN_ACCESS_DATA_SECTION + wiiu->shader = &tex_shader; +#else /* init shader */ // wiiu->shader = MEM2_alloc(sizeof(*wiiu->shader), GX2_VERTEX_BUFFER_ALIGNMENT); wiiu->shader = MEM2_alloc(sizeof(tex_shader), 0x1000); @@ -239,6 +365,7 @@ static void* wiiu_gfx_init(const video_info_t* video, memcpy(wiiu->shader->ps.samplerVars, tex_shader.ps.samplerVars, wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar)); +#endif wiiu->shader->fs.size = GX2CalcFetchShaderSizeEx(2, GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE); wiiu->shader->fs.program = MEM2_alloc(wiiu->shader->fs.size, GX2_SHADER_ALIGNMENT); GX2InitFetchShaderEx(&wiiu->shader->fs, (uint8_t*)wiiu->shader->fs.program, @@ -246,7 +373,6 @@ static void* wiiu_gfx_init(const video_info_t* video, (GX2AttribStream*)&wiiu->shader->attribute_stream, GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->fs.program, wiiu->shader->fs.size); - GX2SetVertexShader(&wiiu->shader->vs); GX2SetPixelShader(&wiiu->shader->ps); GX2SetFetchShader(&wiiu->shader->fs); @@ -325,9 +451,20 @@ static void* wiiu_gfx_init(const video_info_t* video, GX2SetTVEnable(GX2_ENABLE); GX2SetDRCEnable(GX2_ENABLE); - wiiu->vsync = video->vsync; + wiiu->keep_aspect = true; + wiiu->should_resize = true; + wiiu->smooth = video->smooth; + wiiu->vsync = video->vsync; GX2SetSwapInterval(!!video->vsync); + wiiu->vp.x = 0; + wiiu->vp.y = 0; + wiiu->vp.width = 854; + wiiu->vp.height = 480; + wiiu->vp.full_width = 854; + wiiu->vp.full_height = 480; + video_driver_set_size(&wiiu->vp.width, &wiiu->vp.height); + return wiiu; } static void wiiu_gfx_free(void* data) @@ -361,16 +498,17 @@ static void wiiu_gfx_free(void* data) MEMBucket_free(wiiu->tv_scan_buffer); MEMBucket_free(wiiu->drc_scan_buffer); + MEM2_free(wiiu->shader->fs.program); +#ifndef GX2_CAN_ACCESS_DATA_SECTION MEM2_free(wiiu->shader->vs.program); MEM2_free(wiiu->shader->vs.attribVars); MEM2_free(wiiu->shader->ps.program); MEM2_free(wiiu->shader->ps.samplerVars); - MEM2_free(wiiu->shader->fs.program); MEM2_free(wiiu->shader); - +#endif MEM2_free(wiiu->position); MEM2_free(wiiu->tex_coord); MEM2_free(wiiu->menu.position); @@ -435,6 +573,11 @@ static bool wiiu_gfx_frame(void* data, const void* frame, printf("\rfps: %8.8f frames : %5i", fps, wiiu->frames++); fflush(stdout); + + if (wiiu->should_resize) + wiiu_gfx_update_viewport(wiiu); + + GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f); /* can't call GX2ClearColor after GX2SetContextState for whatever reason */ GX2SetContextState(wiiu->ctx_state); @@ -472,7 +615,8 @@ static bool wiiu_gfx_frame(void* data, const void* frame, GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord); GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location); - GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location); + GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest, + wiiu->shader->sampler.location); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); @@ -545,15 +689,15 @@ static bool wiiu_gfx_set_shader(void* data, static void wiiu_gfx_set_rotation(void* data, unsigned rotation) { - (void)data; - (void)rotation; + wiiu_video_t* wiiu = (wiiu_video_t*) data; + wiiu->rotation = rotation; } static void wiiu_gfx_viewport_info(void* data, struct video_viewport* vp) { - (void)data; - (void)vp; + wiiu_video_t* wiiu = (wiiu_video_t*) data; + *vp = wiiu->vp; } static bool wiiu_gfx_read_viewport(void* data, uint8_t* buffer) @@ -564,37 +708,33 @@ static bool wiiu_gfx_read_viewport(void* data, uint8_t* buffer) return true; } -static uintptr_t wiiu_load_texture(void* video_data, void* data, +static uintptr_t wiiu_gfx_load_texture(void* video_data, void* data, bool threaded, enum texture_filter_type filter_type) { return 0; } -static void wiiu_unload_texture(void* data, uintptr_t handle) +static void wiiu_gfx_unload_texture(void* data, uintptr_t handle) { } -static void wiiu_set_filtering(void* data, unsigned index, bool smooth) +static void wiiu_gfx_set_filtering(void* data, unsigned index, bool smooth) { + wiiu_video_t* wiiu = (wiiu_video_t*) data; + wiiu->smooth = smooth; } -static void wiiu_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) -{ -} -static void wiiu_apply_state_changes(void* data) + +static void wiiu_gfx_apply_state_changes(void* data) { + wiiu_video_t* wiiu = (wiiu_video_t*)data; + + if (wiiu) + wiiu->should_resize = true; + } -static void wiiu_viewport_info(void* data, struct video_viewport* vp) -{ - vp->full_width = 800; - vp->full_height = 480; - vp->width = 800; - vp->height = 480; - vp->x = 0; - vp->y = 0; -} -static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32, +static void wiiu_gfx_set_texture_frame(void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) { int i; @@ -632,7 +772,7 @@ static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32, // wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height); } -static void wiiu_set_texture_enable(void* data, bool state, bool full_screen) +static void wiiu_gfx_set_texture_enable(void* data, bool state, bool full_screen) { (void) full_screen; wiiu_video_t* wiiu = (wiiu_video_t*) data; @@ -640,7 +780,7 @@ static void wiiu_set_texture_enable(void* data, bool state, bool full_screen) } -static void wiiu_set_osd_msg(void* data, const char* msg, +static void wiiu_gfx_set_osd_msg(void* data, const char* msg, const struct font_params* params, void* font) { } @@ -649,21 +789,21 @@ static void wiiu_set_osd_msg(void* data, const char* msg, static const video_poke_interface_t wiiu_poke_interface = { - wiiu_load_texture, - wiiu_unload_texture, + wiiu_gfx_load_texture, + wiiu_gfx_unload_texture, NULL, - wiiu_set_filtering, + wiiu_gfx_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ NULL, /* get_current_framebuffer */ NULL, - wiiu_set_aspect_ratio, - wiiu_apply_state_changes, + wiiu_gfx_set_aspect_ratio, + wiiu_gfx_apply_state_changes, #ifdef HAVE_MENU - wiiu_set_texture_frame, - wiiu_set_texture_enable, - wiiu_set_osd_msg, + wiiu_gfx_set_texture_frame, + wiiu_gfx_set_texture_enable, + wiiu_gfx_set_osd_msg, #endif NULL, NULL,