Now Progressive Scan actually works for those games that really depend on this setting (Try Mario Kart Wii)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4798 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2010-01-09 17:11:59 +00:00
parent 81afdbe4f4
commit f472e2904d
10 changed files with 361 additions and 333 deletions

View File

@ -166,7 +166,7 @@ bool CBoot::BootUp()
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
g_symbolDB.Clear();
VideoInterface::PreInit(_StartupPara.bNTSC);
VideoInterface::Preset(_StartupPara.bNTSC);
switch (_StartupPara.m_BootType)
{
// GCM and Wii

View File

@ -598,8 +598,7 @@ void VideoThrottle()
// When frame limit is NOT off
if (SConfig::GetInstance().m_Framelimit)
{
// a full screen scan consists of 2 fields
u32 frametime = DrawnVideo * 2 * 1000 / TargetVPS;
u32 frametime = DrawnVideo * 1000 / TargetVPS;
while ((u32)Timer.GetTimeDifference() < frametime)
Common::YieldCPU();
//Common::SleepCurrentThread(1);
@ -612,7 +611,7 @@ void VideoThrottle()
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
u32 VPS = DrawnVideo * 2 * 1000 / ElapseTime;
u32 VPS = DrawnVideo * 1000 / ElapseTime;
u32 Speed = VPS * 100 / VideoInterface::TargetRefreshRate;
// Settings are shown the same for both extended and summary info
@ -675,10 +674,8 @@ void VideoThrottle()
Common::AtomicStore(DrawnFrame, 0);
DrawnVideo = 0;
}
else
{
DrawnVideo++;
}
DrawnVideo++;
}
// Executed from GPU thread

View File

@ -106,11 +106,4 @@ namespace HW
WII_IPC_HLE_Interface::DoState(p);
}
}
// Restart Wiimote
void InitWiimote()
{
WII_IPCInterface::Init();
WII_IPC_HLE_Interface::Init();
}
}

View File

@ -26,7 +26,6 @@ namespace HW
void Init();
void Shutdown();
void DoState(PointerWrap &p);
void InitWiimote();
}
#endif

View File

@ -184,7 +184,7 @@ void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate)
void VICallback(u64 userdata, int cyclesLate)
{
VideoInterface::Update();
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI);
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_VI);
}
void SICallback(u64 userdata, int cyclesLate)
@ -295,7 +295,7 @@ void Init()
et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback);
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI);
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_VI);
CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP);
CoreTiming::ScheduleEvent(GetTicksPerSecond() / 60, et_SI);
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA);

View File

@ -30,277 +30,6 @@
namespace VideoInterface
{
// VI Internal Hardware Addresses
enum
{
VI_VERTICAL_TIMING = 0x00,
VI_CONTROL_REGISTER = 0x02,
VI_HORIZONTAL_TIMING_0_HI = 0x04,
VI_HORIZONTAL_TIMING_0_LO = 0x06,
VI_HORIZONTAL_TIMING_1_HI = 0x08,
VI_HORIZONTAL_TIMING_1_LO = 0x0a,
VI_VBLANK_TIMING_ODD_HI = 0x0c,
VI_VBLANK_TIMING_ODD_LO = 0x0e,
VI_VBLANK_TIMING_EVEN_HI = 0x10,
VI_VBLANK_TIMING_EVEN_LO = 0x12,
VI_BURST_BLANKING_ODD_HI = 0x14,
VI_BURST_BLANKING_ODD_LO = 0x16,
VI_BURST_BLANKING_EVEN_HI = 0x18,
VI_BURST_BLANKING_EVEN_LO = 0x1a,
VI_FB_LEFT_TOP_HI = 0x1c, // FB_LEFT_TOP is first half of XFB info
VI_FB_LEFT_TOP_LO = 0x1e,
VI_FB_RIGHT_TOP_HI = 0x20, // FB_RIGHT_TOP is only used in 3D mode
VI_FB_RIGHT_TOP_LO = 0x22,
VI_FB_LEFT_BOTTOM_HI = 0x24, // FB_LEFT_BOTTOM is second half of XFB info
VI_FB_LEFT_BOTTOM_LO = 0x26,
VI_FB_RIGHT_BOTTOM_HI = 0x28, // FB_RIGHT_BOTTOM is only used in 3D mode
VI_FB_RIGHT_BOTTOM_LO = 0x2a,
VI_VERTICAL_BEAM_POSITION = 0x2c,
VI_HORIZONTAL_BEAM_POSITION = 0x2e,
VI_PRERETRACE_HI = 0x30,
VI_PRERETRACE_LO = 0x32,
VI_POSTRETRACE_HI = 0x34,
VI_POSTRETRACE_LO = 0x36,
VI_DISPLAY_INTERRUPT_2_HI = 0x38,
VI_DISPLAY_INTERRUPT_2_LO = 0x3a,
VI_DISPLAY_INTERRUPT_3_HI = 0x3c,
VI_DISPLAY_INTERRUPT_3_LO = 0x3e,
VI_DISPLAY_LATCH_0_HI = 0x40,
VI_DISPLAY_LATCH_0_LO = 0x42,
VI_DISPLAY_LATCH_1_HI = 0x44,
VI_DISPLAY_LATCH_1_LO = 0x46,
VI_HSCALEW = 0x48,
VI_HSCALER = 0x4a,
VI_FILTER_COEF_0_HI = 0x4c,
VI_FILTER_COEF_0_LO = 0x4e,
VI_FILTER_COEF_1_HI = 0x50,
VI_FILTER_COEF_1_LO = 0x52,
VI_FILTER_COEF_2_HI = 0x54,
VI_FILTER_COEF_2_LO = 0x56,
VI_FILTER_COEF_3_HI = 0x58,
VI_FILTER_COEF_3_LO = 0x5a,
VI_FILTER_COEF_4_HI = 0x5c,
VI_FILTER_COEF_4_LO = 0x5e,
VI_FILTER_COEF_5_HI = 0x60,
VI_FILTER_COEF_5_LO = 0x62,
VI_FILTER_COEF_6_HI = 0x64,
VI_FILTER_COEF_6_LO = 0x66,
VI_UNK_AA_REG_HI = 0x68,
VI_UNK_AA_REG_LO = 0x6a,
VI_CLOCK = 0x6c,
VI_DTV_STATUS = 0x6e,
VI_FBWIDTH = 0x70,
VI_BORDER_BLANK_END = 0x72, // Only used in debug video mode
VI_BORDER_BLANK_START = 0x74, // Only used in debug video mode
VI_INTERLACE = 0x850, // ??? MYSTERY OLD CODE
};
union UVIVerticalTimingRegister
{
u16 Hex;
struct
{
unsigned EQU : 4; // Equalization pulse in half lines
unsigned ACV : 10; // Active video in lines per field (TODO: Does it indicate half-lines in progressive mode or 54 MHz mode?)
unsigned : 2;
};
UVIVerticalTimingRegister(u16 _hex) { Hex = _hex;}
UVIVerticalTimingRegister() { Hex = 0;}
};
union UVIDisplayControlRegister
{
u16 Hex;
struct
{
unsigned ENB : 1; // Enables video timing generation and data request
unsigned RST : 1; // Clears all data requests and puts VI into its idle state
unsigned NIN : 1; // 0: Interlaced, 1: Non-Interlaced: top field drawn at field rate and bottom field is not displayed
unsigned DLR : 1; // Selects 3D Display Mode
unsigned LE0 : 2; // Display Latch; 0: Off, 1: On for 1 field, 2: On for 2 fields, 3: Always on
unsigned LE1 : 2;
unsigned FMT : 2; // 0: NTSC, 1: PAL, 2: MPAL, 3: Debug
unsigned : 6;
};
UVIDisplayControlRegister(u16 _hex) { Hex = _hex;}
UVIDisplayControlRegister() { Hex = 0;}
};
union UVIHorizontalTiming0
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HLW : 9; // Halfline Width (W*16 = Width (720))
unsigned : 7;
unsigned HCE : 7; // Horizontal Sync Start to Color Burst End
unsigned : 1;
unsigned HCS : 7; // Horizontal Sync Start to Color Burst Start
unsigned : 1;
};
};
union UVIHorizontalTiming1
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HSY : 7; // Horizontal Sync Width
unsigned HBE640 : 9; // Horizontal Sync Start to horizontal blank end
unsigned : 1;
unsigned HBS640 : 9; // Half line to horizontal blanking start
unsigned : 6;
};
};
// Exists for both odd and even fields
union UVIVBlankTimingRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned PRB : 10; // Pre-blanking in half lines
unsigned : 6;
unsigned PSB : 10; // Post blanking in half lines
unsigned : 6;
};
};
// Exists for both odd and even fields
union UVIBurstBlankingRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned BS0 : 5; // Field x start to burst blanking start in halflines
unsigned BE0 : 11; // Field x start to burst blanking end in halflines
unsigned BS2 : 5; // Field x+2 start to burst blanking start in halflines
unsigned BE2 : 11; // Field x+2 start to burst blanking end in halflines
};
};
union UVIFBInfoRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
// TODO: mask out lower 9bits/align to 9bits???
unsigned FBB : 24; // Base address of the framebuffer in external mem
// POFF only seems to exist in the top reg. XOFF, unknown.
unsigned XOFF : 4; // Horizontal Offset of the left-most pixel within the first word of the fetched picture
unsigned POFF : 1; // Page offest: 1: fb address is (address>>5)
unsigned CLRPOFF : 3; // ? setting bit 31 clears POFF
};
};
// VI Interrupt Register
union UVIInterruptRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HCT : 11; // Horizontal Position
unsigned : 5;
unsigned VCT : 11; // Vertical Position
unsigned : 1;
unsigned IR_MASK : 1; // Interrupt Enable Bit
unsigned : 2;
unsigned IR_INT : 1; // Interrupt Status (1=Active) (Read to clear)
};
};
union UVILatchRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HCT : 11; // Horizontal Count
unsigned : 5;
unsigned VCT : 11; // Vertical Count
unsigned : 4;
unsigned TRG : 1; // Trigger Flag
};
};
union UVIHorizontalStepping
{
u16 Hex;
struct
{
unsigned FbSteps : 8;
unsigned FieldSteps : 8;
};
};
union UVIHorizontalScaling
{
u16 Hex;
struct
{
unsigned STP : 9; // Horizontal stepping size (U1.8 Scaler Value) (0x160 Works for 320)
unsigned : 3;
unsigned HS_EN : 1; // Enable Horizontal Scaling
unsigned : 3;
};
UVIHorizontalScaling(u16 _hex) { Hex = _hex;}
UVIHorizontalScaling() { Hex = 0;}
};
// Used for tables 0-2
union UVIFilterCoefTable3
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned Tap0 : 10;
unsigned Tap1 : 10;
unsigned Tap2 : 10;
unsigned : 2;
};
};
// Used for tables 3-6
union UVIFilterCoefTable4
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned Tap0 : 8;
unsigned Tap1 : 8;
unsigned Tap2 : 8;
unsigned Tap3 : 8;
};
};
struct SVIFilterCoefTables
{
UVIFilterCoefTable3 Tables02[3];
UVIFilterCoefTable4 Tables36[4];
};
// Debug video mode only, probably never used in dolphin...
union UVIBorderBlankRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HBE656 : 10; // Border Horizontal Blank End
unsigned : 11;
unsigned HBS656 : 10; // Border Horizontal Blank start
unsigned BRDR_EN : 1; // Border Enable
};
};
// STATE_TO_SAVE
// Registers listed in order:
@ -316,8 +45,8 @@ static UVIFBInfoRegister m_XFBInfoTop;
static UVIFBInfoRegister m_XFBInfoBottom;
static UVIFBInfoRegister m_3DFBInfoTop; // Start making your stereoscopic demos! :p
static UVIFBInfoRegister m_3DFBInfoBottom;
static u16 m_VBeamPos = 0;
static u16 m_HBeamPos = 0;
static u16 m_VBeamPos = 0; // 0: Inactive
static u16 m_HBeamPos = 0; // 0: Inactive
static UVIInterruptRegister m_InterruptRegister[4];
static UVILatchRegister m_LatchRegister[2];
static UVIHorizontalStepping m_HorizontalStepping;
@ -325,7 +54,7 @@ static UVIHorizontalScaling m_HorizontalScaling;
static SVIFilterCoefTables m_FilterCoefTables;
static u32 m_UnkAARegister = 0;// ??? 0x00FF0000
static u16 m_Clock = 0; // 0: 27MHz, 1: 54MHz
static u16 m_DTVStatus = 0; // Region char and component cable bit (only low 2bits are used?)
static u16 m_DTVStatus = 0; // Region char and component cable bit
static u16 m_FBWidth = 0; // Only correct when scaling is enabled?
static UVIBorderBlankRegister m_BorderHBlank;
// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
@ -371,7 +100,8 @@ void DoState(PointerWrap &p)
p.Do(s_lowerFieldBegin);
}
void PreInit(bool _bNTSC)
// Executed after Init, before game boot
void Preset(bool _bNTSC)
{
m_VerticalTimingRegister.EQU = 6;
@ -411,12 +141,16 @@ void PreInit(bool _bNTSC)
m_HorizontalStepping.FbSteps = 40;
m_HorizontalStepping.FieldSteps = 40;
m_Clock = 0;
m_HBeamPos = 1;
m_VBeamPos = 1;
// 54MHz, capable of progressive scan
m_Clock = 1;
// Say component cable is plugged
m_DTVStatus = 1;
UpdateTiming();
UpdateParameters();
}
void SetRegionReg(char _region)
@ -430,8 +164,7 @@ void Init()
m_InterruptRegister[i].Hex = 0;
m_DisplayControlRegister.Hex = 0;
UpdateTiming();
UpdateParameters();
}
void Read8(u8& _uReturnValue, const u32 _iAddress)
@ -547,8 +280,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
// RETRACE STUFF ...
case VI_PRERETRACE_HI:
_uReturnValue = m_InterruptRegister[0].Hi;
m_InterruptRegister[0].IR_INT = 0;
UpdateInterrupts();
return;
case VI_PRERETRACE_LO:
_uReturnValue = m_InterruptRegister[0].Lo;
@ -556,8 +287,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
case VI_POSTRETRACE_HI:
_uReturnValue = m_InterruptRegister[1].Hi;
m_InterruptRegister[1].IR_INT = 0;
UpdateInterrupts();
return;
case VI_POSTRETRACE_LO:
_uReturnValue = m_InterruptRegister[1].Lo;
@ -565,8 +294,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
case VI_DISPLAY_INTERRUPT_2_HI:
_uReturnValue = m_InterruptRegister[2].Hi;
m_InterruptRegister[2].IR_INT = 0;
UpdateInterrupts();
return;
case VI_DISPLAY_INTERRUPT_2_LO:
_uReturnValue = m_InterruptRegister[2].Lo;
@ -574,8 +301,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
case VI_DISPLAY_INTERRUPT_3_HI:
_uReturnValue = m_InterruptRegister[3].Hi;
m_InterruptRegister[3].IR_INT = 0;
UpdateInterrupts();
return;
case VI_DISPLAY_INTERRUPT_3_LO:
_uReturnValue = m_InterruptRegister[3].Lo;
@ -714,7 +439,7 @@ void Write16(const u16 _iValue, const u32 _iAddress)
UpdateInterrupts();
}
UpdateTiming();
UpdateParameters();
}
break;
@ -803,6 +528,7 @@ void Write16(const u16 _iValue, const u32 _iAddress)
// RETRACE STUFF ...
case VI_PRERETRACE_HI:
m_InterruptRegister[0].Hi = _iValue;
UpdateInterrupts();
break;
case VI_PRERETRACE_LO:
m_InterruptRegister[0].Lo = _iValue;
@ -810,6 +536,7 @@ void Write16(const u16 _iValue, const u32 _iAddress)
case VI_POSTRETRACE_HI:
m_InterruptRegister[1].Hi = _iValue;
UpdateInterrupts();
break;
case VI_POSTRETRACE_LO:
m_InterruptRegister[1].Lo = _iValue;
@ -817,6 +544,7 @@ void Write16(const u16 _iValue, const u32 _iAddress)
case VI_DISPLAY_INTERRUPT_2_HI:
m_InterruptRegister[2].Hi = _iValue;
UpdateInterrupts();
break;
case VI_DISPLAY_INTERRUPT_2_LO:
m_InterruptRegister[2].Lo = _iValue;
@ -824,6 +552,7 @@ void Write16(const u16 _iValue, const u32 _iAddress)
case VI_DISPLAY_INTERRUPT_3_HI:
m_InterruptRegister[3].Hi = _iValue;
UpdateInterrupts();
break;
case VI_DISPLAY_INTERRUPT_3_LO:
m_InterruptRegister[3].Lo = _iValue;
@ -981,25 +710,25 @@ u32 GetXFBAddressBottom()
return m_XFBInfoBottom.FBB;
}
void UpdateTiming()
void UpdateParameters()
{
switch (m_DisplayControlRegister.FMT)
{
case 0: // NTSC
case 2: // PAL-M
case 2: // PAL-M // AyuanX: LineCount doesn't look right for PAL-M
TargetRefreshRate = NTSC_FIELD_RATE;
TicksPerFrame = SystemTimers::GetTicksPerSecond() / (NTSC_FIELD_RATE / 2);
s_lineCount = m_DisplayControlRegister.NIN ? (NTSC_LINE_COUNT+1)/2 : NTSC_LINE_COUNT;
s_upperFieldBegin = NTSC_UPPER_BEGIN;
s_lowerFieldBegin = NTSC_LOWER_BEGIN;
TicksPerFrame = SystemTimers::GetTicksPerSecond() / NTSC_FIELD_RATE;
s_lineCount = m_DisplayControlRegister.NIN ? NTSC_LINE_COUNT : (NTSC_LINE_COUNT+1)/2;
//s_upperFieldBegin = NTSC_UPPER_BEGIN;
//s_lowerFieldBegin = NTSC_LOWER_BEGIN;
break;
case 1: // PAL
TargetRefreshRate = PAL_FIELD_RATE;
TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE / 2);
s_lineCount = m_DisplayControlRegister.NIN ? (PAL_LINE_COUNT+1)/2 : PAL_LINE_COUNT;
s_upperFieldBegin = PAL_UPPER_BEGIN;
s_lowerFieldBegin = PAL_LOWER_BEGIN;
TicksPerFrame = SystemTimers::GetTicksPerSecond() / PAL_FIELD_RATE;
s_lineCount = m_DisplayControlRegister.NIN ? PAL_LINE_COUNT : (PAL_LINE_COUNT+1)/2;
//s_upperFieldBegin = PAL_UPPER_BEGIN;
//s_lowerFieldBegin = PAL_LOWER_BEGIN;
break;
case 3: // Debug
@ -1016,7 +745,8 @@ int GetTicksPerLine()
{
if (s_lineCount == 0)
return 100000;
return TicksPerFrame / s_lineCount;
else
return TicksPerFrame / s_lineCount;
}
int GetTicksPerFrame()
@ -1053,8 +783,44 @@ static void EndField()
if (video->IsValid())
video->Video_EndField();
}
// AyuanX: No need to update per scan line, update per frame is good enough, and faster
// Purpose: Send VI interrupt when triggered
// Run when: When a frame is scaned (progressive/interlace)
void Update()
{
u16 NewVBeamPos;
if (m_DisplayControlRegister.NIN)
{
// Progressive
NewVBeamPos = s_lineCount + 1;
BeginField(FIELD_PROGRESSIVE);
}
else if (m_VBeamPos == s_lineCount)
{
// Interlace Upper
NewVBeamPos = s_lineCount * 2;
BeginField(FIELD_UPPER);
}
else
{
// Interlace Lower
NewVBeamPos = s_lineCount;
BeginField(FIELD_LOWER);
}
for (int i = 0; i < 4; i++)
{
if (m_VBeamPos <= m_InterruptRegister[i].VCT && m_InterruptRegister[i].VCT < NewVBeamPos)
m_InterruptRegister[i].IR_INT = 1;
}
UpdateInterrupts();
m_VBeamPos = (NewVBeamPos > s_lineCount) ? 1 : NewVBeamPos;
Core::VideoThrottle();
}
/*
// Purpose: Send VI interrupt when triggered
// Run when: When a line is scaned
void Update()
@ -1088,5 +854,6 @@ void Update()
BeginField(m_DisplayControlRegister.NIN ? FIELD_PROGRESSIVE : FIELD_LOWER);
}
*/
} // namespace

View File

@ -41,14 +41,285 @@ namespace VideoInterface
#define PAL_LINE_COUNT 625
// These line numbers indicate the beginning of the "active video" in a frame.
// A PAL frame has the upper field first followed by the lower field.
#define PAL_UPPER_BEGIN 23 // TODO: Actually 23.5!
#define PAL_UPPER_BEGIN 23
#define PAL_LOWER_BEGIN 336
// VI Internal Hardware Addresses
enum
{
VI_VERTICAL_TIMING = 0x00,
VI_CONTROL_REGISTER = 0x02,
VI_HORIZONTAL_TIMING_0_HI = 0x04,
VI_HORIZONTAL_TIMING_0_LO = 0x06,
VI_HORIZONTAL_TIMING_1_HI = 0x08,
VI_HORIZONTAL_TIMING_1_LO = 0x0a,
VI_VBLANK_TIMING_ODD_HI = 0x0c,
VI_VBLANK_TIMING_ODD_LO = 0x0e,
VI_VBLANK_TIMING_EVEN_HI = 0x10,
VI_VBLANK_TIMING_EVEN_LO = 0x12,
VI_BURST_BLANKING_ODD_HI = 0x14,
VI_BURST_BLANKING_ODD_LO = 0x16,
VI_BURST_BLANKING_EVEN_HI = 0x18,
VI_BURST_BLANKING_EVEN_LO = 0x1a,
VI_FB_LEFT_TOP_HI = 0x1c, // FB_LEFT_TOP is first half of XFB info
VI_FB_LEFT_TOP_LO = 0x1e,
VI_FB_RIGHT_TOP_HI = 0x20, // FB_RIGHT_TOP is only used in 3D mode
VI_FB_RIGHT_TOP_LO = 0x22,
VI_FB_LEFT_BOTTOM_HI = 0x24, // FB_LEFT_BOTTOM is second half of XFB info
VI_FB_LEFT_BOTTOM_LO = 0x26,
VI_FB_RIGHT_BOTTOM_HI = 0x28, // FB_RIGHT_BOTTOM is only used in 3D mode
VI_FB_RIGHT_BOTTOM_LO = 0x2a,
VI_VERTICAL_BEAM_POSITION = 0x2c,
VI_HORIZONTAL_BEAM_POSITION = 0x2e,
VI_PRERETRACE_HI = 0x30,
VI_PRERETRACE_LO = 0x32,
VI_POSTRETRACE_HI = 0x34,
VI_POSTRETRACE_LO = 0x36,
VI_DISPLAY_INTERRUPT_2_HI = 0x38,
VI_DISPLAY_INTERRUPT_2_LO = 0x3a,
VI_DISPLAY_INTERRUPT_3_HI = 0x3c,
VI_DISPLAY_INTERRUPT_3_LO = 0x3e,
VI_DISPLAY_LATCH_0_HI = 0x40,
VI_DISPLAY_LATCH_0_LO = 0x42,
VI_DISPLAY_LATCH_1_HI = 0x44,
VI_DISPLAY_LATCH_1_LO = 0x46,
VI_HSCALEW = 0x48,
VI_HSCALER = 0x4a,
VI_FILTER_COEF_0_HI = 0x4c,
VI_FILTER_COEF_0_LO = 0x4e,
VI_FILTER_COEF_1_HI = 0x50,
VI_FILTER_COEF_1_LO = 0x52,
VI_FILTER_COEF_2_HI = 0x54,
VI_FILTER_COEF_2_LO = 0x56,
VI_FILTER_COEF_3_HI = 0x58,
VI_FILTER_COEF_3_LO = 0x5a,
VI_FILTER_COEF_4_HI = 0x5c,
VI_FILTER_COEF_4_LO = 0x5e,
VI_FILTER_COEF_5_HI = 0x60,
VI_FILTER_COEF_5_LO = 0x62,
VI_FILTER_COEF_6_HI = 0x64,
VI_FILTER_COEF_6_LO = 0x66,
VI_UNK_AA_REG_HI = 0x68,
VI_UNK_AA_REG_LO = 0x6a,
VI_CLOCK = 0x6c,
VI_DTV_STATUS = 0x6e,
VI_FBWIDTH = 0x70,
VI_BORDER_BLANK_END = 0x72, // Only used in debug video mode
VI_BORDER_BLANK_START = 0x74, // Only used in debug video mode
//VI_INTERLACE = 0x850, // ??? MYSTERY OLD CODE
};
union UVIVerticalTimingRegister
{
u16 Hex;
struct
{
unsigned EQU : 4; // Equalization pulse in half lines
unsigned ACV : 10; // Active video in lines per field (seems always zero)
unsigned : 2;
};
UVIVerticalTimingRegister(u16 _hex) { Hex = _hex;}
UVIVerticalTimingRegister() { Hex = 0;}
};
union UVIDisplayControlRegister
{
u16 Hex;
struct
{
unsigned ENB : 1; // Enables video timing generation and data request
unsigned RST : 1; // Clears all data requests and puts VI into its idle state
unsigned NIN : 1; // 0: Interlaced, 1: Non-Interlaced: top field drawn at field rate and bottom field is not displayed
unsigned DLR : 1; // Selects 3D Display Mode
unsigned LE0 : 2; // Display Latch; 0: Off, 1: On for 1 field, 2: On for 2 fields, 3: Always on
unsigned LE1 : 2;
unsigned FMT : 2; // 0: NTSC, 1: PAL, 2: MPAL, 3: Debug
unsigned : 6;
};
UVIDisplayControlRegister(u16 _hex) { Hex = _hex;}
UVIDisplayControlRegister() { Hex = 0;}
};
union UVIHorizontalTiming0
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HLW : 9; // Halfline Width (W*16 = Width (720))
unsigned : 7;
unsigned HCE : 7; // Horizontal Sync Start to Color Burst End
unsigned : 1;
unsigned HCS : 7; // Horizontal Sync Start to Color Burst Start
unsigned : 1;
};
};
union UVIHorizontalTiming1
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HSY : 7; // Horizontal Sync Width
unsigned HBE640 : 9; // Horizontal Sync Start to horizontal blank end
unsigned : 1;
unsigned HBS640 : 9; // Half line to horizontal blanking start
unsigned : 6;
};
};
// Exists for both odd and even fields
union UVIVBlankTimingRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned PRB : 10; // Pre-blanking in half lines
unsigned : 6;
unsigned PSB : 10; // Post blanking in half lines
unsigned : 6;
};
};
// Exists for both odd and even fields
union UVIBurstBlankingRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned BS0 : 5; // Field x start to burst blanking start in halflines
unsigned BE0 : 11; // Field x start to burst blanking end in halflines
unsigned BS2 : 5; // Field x+2 start to burst blanking start in halflines
unsigned BE2 : 11; // Field x+2 start to burst blanking end in halflines
};
};
union UVIFBInfoRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
// TODO: mask out lower 9bits/align to 9bits???
unsigned FBB : 24; // Base address of the framebuffer in external mem
// POFF only seems to exist in the top reg. XOFF, unknown.
unsigned XOFF : 4; // Horizontal Offset of the left-most pixel within the first word of the fetched picture
unsigned POFF : 1; // Page offest: 1: fb address is (address>>5)
unsigned CLRPOFF : 3; // ? setting bit 31 clears POFF
};
};
// VI Interrupt Register
union UVIInterruptRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HCT : 11; // Horizontal Position
unsigned : 5;
unsigned VCT : 11; // Vertical Position
unsigned : 1;
unsigned IR_MASK : 1; // Interrupt Mask Bit
unsigned : 2;
unsigned IR_INT : 1; // Interrupt Status (1=Active, 0=Clear)
};
};
union UVILatchRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HCT : 11; // Horizontal Count
unsigned : 5;
unsigned VCT : 11; // Vertical Count
unsigned : 4;
unsigned TRG : 1; // Trigger Flag
};
};
union UVIHorizontalStepping
{
u16 Hex;
struct
{
unsigned FbSteps : 8;
unsigned FieldSteps : 8;
};
};
union UVIHorizontalScaling
{
u16 Hex;
struct
{
unsigned STP : 9; // Horizontal stepping size (U1.8 Scaler Value) (0x160 Works for 320)
unsigned : 3;
unsigned HS_EN : 1; // Enable Horizontal Scaling
unsigned : 3;
};
UVIHorizontalScaling(u16 _hex) { Hex = _hex;}
UVIHorizontalScaling() { Hex = 0;}
};
// Used for tables 0-2
union UVIFilterCoefTable3
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned Tap0 : 10;
unsigned Tap1 : 10;
unsigned Tap2 : 10;
unsigned : 2;
};
};
// Used for tables 3-6
union UVIFilterCoefTable4
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned Tap0 : 8;
unsigned Tap1 : 8;
unsigned Tap2 : 8;
unsigned Tap3 : 8;
};
};
struct SVIFilterCoefTables
{
UVIFilterCoefTable3 Tables02[3];
UVIFilterCoefTable4 Tables36[4];
};
// Debug video mode only, probably never used in dolphin...
union UVIBorderBlankRegister
{
u32 Hex;
struct { u16 Lo, Hi; };
struct
{
unsigned HBE656 : 10; // Border Horizontal Blank End
unsigned : 11;
unsigned HBS656 : 10; // Border Horizontal Blank start
unsigned BRDR_EN : 1; // Border Enable
};
};
// urgh, ugly externs.
extern u32 TargetRefreshRate;
// For BS2 HLE
void PreInit(bool _bNTSC);
void Preset(bool _bNTSC);
void SetRegionReg(char _region);
void Init();
@ -65,14 +336,14 @@ namespace VideoInterface
u8* GetXFBPointerTop();
u8* GetXFBPointerBottom();
// Update and draw framebuffer(s)
// Update and draw framebuffer
void Update();
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
// Change values pertaining to video mode
void UpdateTiming();
void UpdateParameters();
int GetTicksPerLine();
int GetTicksPerFrame();

View File

@ -539,16 +539,14 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
}
}
// Run from the CPU thread (from VideoInterface.cpp)
void Video_EndField()
{
if (s_PluginInitialized)
{
Common::AtomicStoreRelease(s_swapRequested, TRUE);
}
}
static struct

View File

@ -97,8 +97,10 @@ void WiimoteRecordingConfigDialog::CloseClick(wxCommandEvent& event)
switch(event.GetId())
{
case ID_CLOSE:
SetEvent(WiiMoteReal::g_StopThreadTemporary); //direct closing will result in crash @ReadWiimote, also dont try to waitforobject here, it will result in deadlock! because this thread is still needed to progress in the Readwiimote to get to the waitingobject @readwiimote itself.....
Close(); //Problem lies mainly in Readwiimote(), closing here leaves the thread readWiimote thread, trying to access vars which aint there anymore.
if (g_RealWiiMoteInitialized)
SetEvent(WiiMoteReal::g_StopThreadTemporary); //WiiMoteReal::SafecloseRemoteFunc over takes the closing of the Dlg
else
Close();
break;
case ID_APPLY:
SaveFile();

View File

@ -200,9 +200,10 @@ void handle_event(struct wiimote_t* wm)
m_RecordingConfigFrame->m_GaugeAccel[1]->SetValue(wm->accel.y);
m_RecordingConfigFrame->m_GaugeAccel[2]->SetValue(wm->accel.z);
int GNCx, GNCy, GNCz;
if(wm->exp.type == EXP_NUNCHUK) // Updating Nunchuck Gauges
{
{
m_RecordingConfigFrame->m_GaugeGForceNunchuk[0]->SetValue((int)floor((nc->gforce.x * 300) + 100.5));
m_RecordingConfigFrame->m_GaugeGForceNunchuk[1]->SetValue((int)floor((nc->gforce.y * 300) + 100.5));
m_RecordingConfigFrame->m_GaugeGForceNunchuk[2]->SetValue((int)floor((nc->gforce.z * 300) + 100.5));
@ -217,9 +218,9 @@ void handle_event(struct wiimote_t* wm)
float _GNCz = (float)(nc->accel.z - nc->accel_calib.cal_zero.z) / (float)nc->accel_calib.cal_g.z;
// Conver the data to integers
int GNCx = (int)(_GNCx * 100);
int GNCy = (int)(_GNCy * 100);
int GNCz = (int)(_GNCz * 100);
GNCx = (int)(_GNCx * 100);
GNCy = (int)(_GNCy * 100);
GNCz = (int)(_GNCz * 100);
}
@ -230,7 +231,7 @@ void handle_event(struct wiimote_t* wm)
// wxT("Current: %03u %03u %03u"), Gx, Gy, Gz));
if(m_RecordingConfigFrame->m_bRecording) {
if(wm->exp.type == EXP_NUNCHUK) {
if(wm->exp.type != EXP_NUNCHUK) {
DEBUG_LOG(WIIMOTE, "Wiiuse Recorded accel x, y, z: %03i %03i %03i", Gx, Gy, Gz);
}
else {