From 507ef27a610ab7ac39ec59df8db0b62bf3fe1966 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Sun, 18 Jun 2017 23:21:56 -0400 Subject: [PATCH] honor VO_CONTROL when calculating video resolution --- src/core/profiler.cc | 2 +- src/guest/pvr/pvr_regs.inc | 2 +- src/guest/pvr/pvr_types.h | 15 +++++++++++++++ src/guest/pvr/ta.c | 24 ++++++++++++++++-------- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/core/profiler.cc b/src/core/profiler.cc index f0f40cd3..17cded09 100644 --- a/src/core/profiler.cc +++ b/src/core/profiler.cc @@ -15,7 +15,7 @@ static struct { int aggregate[MICROPROFILE_MAX_COUNTERS]; int64_t last_aggregation; #else -/* avoid having an empty struct in c (only valid through GCC extension) */ + /* avoid having an empty struct in c (only valid through GCC extension) */ int dummy; #endif } prof; diff --git a/src/guest/pvr/pvr_regs.inc b/src/guest/pvr/pvr_regs.inc index 5d52c557..0d34c384 100644 --- a/src/guest/pvr/pvr_regs.inc +++ b/src/guest/pvr/pvr_regs.inc @@ -42,7 +42,7 @@ PVR_REG(0x005f80d8, SPG_LOAD, 0x01060359, union spg_load) PVR_REG(0x005f80dc, SPG_VBLANK, 0x01500104, union spg_vblank) PVR_REG(0x005f80e0, SPG_WIDTH, 0x07f1933f, uint32_t) PVR_REG(0x005f80e4, TEXT_CONTROL, 0x00000000, union text_control) -PVR_REG(0x005f80e8, VO_CONTROL, 0x00000108, uint32_t) +PVR_REG(0x005f80e8, VO_CONTROL, 0x00000108, union vo_control) PVR_REG(0x005f80ec, VO_STARTX, 0x0000009d, uint32_t) PVR_REG(0x005f80f0, VO_STARTY, 0x00000015, uint32_t) PVR_REG(0x005f80f4, SCALER_CTL, 0x00000400, union scaler_ctl) diff --git a/src/guest/pvr/pvr_types.h b/src/guest/pvr/pvr_types.h index 1cd7a7eb..ddbc0d44 100644 --- a/src/guest/pvr/pvr_types.h +++ b/src/guest/pvr/pvr_types.h @@ -156,6 +156,21 @@ union text_control { }; }; +union vo_control { + uint32_t full; + struct { + uint32_t hsync_pol : 1; + uint32_t vsync_pol : 1; + uint32_t blank_pol : 1; + uint32_t blank_video : 1; + uint32_t field_mode : 4; + uint32_t pixel_double : 1; + uint32_t : 7; + uint32_t pclk_delay : 6; + uint32_t : 10; + }; +}; + union scaler_ctl { uint32_t full; struct { diff --git a/src/guest/pvr/ta.c b/src/guest/pvr/ta.c index d960392f..5b22e857 100644 --- a/src/guest/pvr/ta.c +++ b/src/guest/pvr/ta.c @@ -362,16 +362,24 @@ static void ta_save_state(struct ta *ta, struct tile_context *ctx) { /* texture palette pixel format */ ctx->pal_pxl_format = pvr->PAL_RAM_CTRL->pixel_format; - /* save out video width / height in order to unproject the screen space - coaordinates */ - if ((pvr->SPG_CONTROL->NTSC || pvr->SPG_CONTROL->PAL) && - !pvr->SPG_CONTROL->interlace) { - ctx->video_width = 640; - ctx->video_height = 240; - } else { - /* VGA and interlaced mode both render at full resolution */ + /* save video resolution in order to unproject the screen space coordinates */ + int vga_mode = !pvr->SPG_CONTROL->NTSC && !pvr->SPG_CONTROL->PAL && + !pvr->SPG_CONTROL->interlace; + + if (vga_mode) { ctx->video_width = 640; ctx->video_height = 480; + } else { + ctx->video_width = 320; + ctx->video_height = 240; + } + + if (pvr->SPG_CONTROL->interlace) { + ctx->video_height *= 2; + } + + if (!pvr->VO_CONTROL->pixel_double) { + ctx->video_width *= 2; } /* scale_x signals to scale the framebuffer down by half. do so by scaling