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:
parent
81afdbe4f4
commit
f472e2904d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -106,11 +106,4 @@ namespace HW
|
|||
WII_IPC_HLE_Interface::DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Restart Wiimote
|
||||
void InitWiimote()
|
||||
{
|
||||
WII_IPCInterface::Init();
|
||||
WII_IPC_HLE_Interface::Init();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace HW
|
|||
void Init();
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap &p);
|
||||
void InitWiimote();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue