📄 theater.cpp
字号:
Register(VIP_HS_WINDOW_LIMIT, WIN_OPEN_LIMIT) >> 16));}// wait until horizontal scaler is lockedvoid CTheater::WaitHSYNC(){ for (int timeout = 0; timeout < 1000; timeout++) { if (Register(VIP_HS_PULSE_WIDTH, HS_GENLOCKED) != 0) return; snooze(20); } PRINT(("CTheater::WaitHSYNC() - wait for HSync locking time out!\n"));}// setup vertical sync and field detectorvoid CTheater::SetVSYNC(theater_standard standard){ static const uint16 vsync_int_trigger[] = { 0x2AA, 0x2AA, 0x353, 0x2AA, 0x353, 0x2B0, 0x353, 0x34D, 0x353 }; static const uint16 vsync_int_hold[] = { 0x017, 0x017, 0x01C, 0x017, 0x01C, 0x017, 0x01C, 0x01C, 0x01C }; // PAL value changed from 26b to 26d - else, odd/even field detection fails sometimes; // did the same for PAL N, PAL NC and SECAM static const uint16 vs_field_blank_start[] = { 0x206, 0x206, 0x206, 0x206, 0x26d, 0x26d, 0x26d, 0x206, 0x26d }; static const uint8 vs_field_blank_end[] = { 0x00a, 0x00a, 0x00a, 0x00a, 0x02a, 0x02a, 0x02a, 0x00a, 0x02a }; // NTSC value changed from 1 to 105 - else, odd/even fields were always swapped; // did the same for NTSC Japan, NTSC 443, PAL M and PAL 60 static const uint16 vs_field_id_location[] = { 0x105, 0x105, 0x105, 0x105, 0x1, 0x1, 0x1, 0x105, 0x1 }; static const uint16 vs_frame_total[] = { 0x217, 0x217, 0x217, 0x217, 0x27B, 0x27B, 0x27B, 0x217, 0x27B }; SetRegister(VIP_VS_DETECTOR_CNTL, VSYNC_INT_TRIGGER, vsync_int_trigger[standard] << 0); SetRegister(VIP_VS_DETECTOR_CNTL, VSYNC_INT_HOLD, (uint32)vsync_int_hold[standard] << 16); SetRegister(VIP_VS_BLANKING_CNTL, VS_FIELD_BLANK_START, vs_field_blank_start[standard] << 0); SetRegister(VIP_VS_BLANKING_CNTL, VS_FIELD_BLANK_END, (uint32)vs_field_blank_end[standard] << 16); SetRegister(VIP_VS_FRAME_TOTAL, VS_FRAME_TOTAL, vs_frame_total[standard]); SetRegister(VIP_VS_FIELD_ID_CNTL, VS_FIELD_ID_LOCATION, vs_field_id_location[standard] << 0); // auto-detect fields SetRegister(VIP_VS_COUNTER_CNTL, FIELD_DETECT_MODE, FIELD_DETECT_DETECTED); // don't flip fields SetRegister(VIP_VS_COUNTER_CNTL, FIELD_FLIP_EN, 0 ); PRINT(("CTheater::SetVSYNC(total=%d)\n", Register(VIP_VS_FRAME_TOTAL, VS_FRAME_TOTAL)));}// wait until a visible line is viewedvoid CTheater::WaitVSYNC(){ for (int timeout = 0; timeout < 1000; timeout++) { int lineCount = Register(VIP_VS_LINE_COUNT, VS_LINE_COUNT); if (lineCount > 1 && lineCount < 20) return; snooze(20); } PRINT(("CTheater::WaitVSYNC() - wait for VBI timed out!\n"));}// setup timing generatorvoid CTheater::SetSyncGenerator(theater_standard standard){ static const uint16 blank_int_start[] = { 0x031, 0x031, 0x046, 0x031, 0x046, 0x046, 0x046, 0x031, 0x046 }; static const uint8 blank_int_length[] = { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }; static const uint16 sync_tip_start[] = { 0x0372, 0x0372, 0x0453, 0x0371, 0x0453, 0x0379, 0x0453, 0x044B, 0x0453 }; static const uint8 sync_tip_length[] = { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }; static const uint8 uv_int_start[] = { 0x03B, 0x03B, 0x052, 0x03B, 0x052, 0x03B, 0x052, 0x03C, 0x068 }; static const uint8 u_int_length[] = { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }; static const uint8 v_int_length[] = { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }; // set blank interrupt position SetRegister(VIP_SG_BLACK_GATE, BLANK_INT_START, blank_int_start[standard] ); SetRegister(VIP_SG_BLACK_GATE, BLANK_INT_LENGTH, (uint32)blank_int_length[standard] << 8); SetRegister(VIP_SG_SYNCTIP_GATE, SYNC_TIP_START, sync_tip_start[standard]); SetRegister(VIP_SG_SYNCTIP_GATE, SYNC_TIP_LENGTH, (uint32)sync_tip_length[standard] << 12); SetRegister(VIP_SG_UVGATE_GATE, UV_INT_START, uv_int_start[standard] << 0); SetRegister(VIP_SG_UVGATE_GATE, U_INT_LENGTH, (uint32)u_int_length[standard] << 8); SetRegister(VIP_SG_UVGATE_GATE, V_INT_LENGTH, (uint32)v_int_length[standard] << 12); PRINT(("CTheater::SetSyncGenerator(black=%d/%d, synctip=%d/%d, uvgate=%d/%d-%d)\n", Register(VIP_SG_BLACK_GATE, BLANK_INT_START) >> 0, Register(VIP_SG_BLACK_GATE, BLANK_INT_LENGTH) >> 8, Register(VIP_SG_SYNCTIP_GATE, SYNC_TIP_START), Register(VIP_SG_SYNCTIP_GATE, SYNC_TIP_LENGTH) >> 12, Register(VIP_SG_UVGATE_GATE, UV_INT_START), Register(VIP_SG_UVGATE_GATE, U_INT_LENGTH) >> 8, Register(VIP_SG_UVGATE_GATE, V_INT_LENGTH) >> 12));}// setup input comb filter.// this is really ugly but I cannot find a schemevoid CTheater::SetCombFilter(theater_standard standard, theater_source source){ enum { _3Tap_2D_adaptive_Comb = 1, // composite _2Tap_C_combed_Y_Sub = 2, _2Tap_C_combed_Y_combed = 3, _3Tap_C_combed_Y_Sub = 4, _3Tap_C_combed_Y_combed = 5, YC_mode_Comb_filter_off = 6, // S-Video YC_mode_2Tap_YV_filter = 7, YC_mode_3Tap_YV_filter = 8 }; // make sure to keep bitfield in sync with register definition! // we could define each component as an uint8, but this would waste space // and would require an extra register-composition typedef struct { LBITFIELD32_12 ( comb_hck : 8, comb_vck : 8, comb_filter_en : 1, comb_adaptiv_en : 1, comb_bpfmuxsel : 3, comb_coutsel : 2, comb_sumdiff0sel : 1, comb_sumdiff1sel : 2, comb_yvlpfsel : 1, comb_dlylinesel : 2, comb_ydlyinsel : 2, comb_ysubbw : 1 ); } comb_cntl0; typedef struct { LBITFIELD32_7 ( comb_ydlyoutsel : 2, comb_coresize : 2, comb_ysuben : 1, comb_youtsel : 1, comb_syncpfsel : 2, comb_synclpfrst : 1, comb_debug : 1 ); } comb_cntl1; typedef struct { LBITFIELD32_4 ( comb_hyk0 : 8, comb_vyk0 : 8, comb_hyk1 : 8, comb_vyk1 : 8 ); } comb_cntl2; typedef struct { LBITFIELD32_2 ( comb_tap0length : 16, comb_tap1length : 12 ); } comb_line_length; typedef struct { const uint8 *types; const comb_cntl0 *cntl0; const comb_cntl1 *cntl1; const comb_cntl2 *cntl2; const comb_line_length *line_length; } comb_settings; static const uint8 comb_types_ntsc_m[] = { _3Tap_2D_adaptive_Comb, _2Tap_C_combed_Y_Sub, _2Tap_C_combed_Y_combed, _3Tap_C_combed_Y_Sub, _3Tap_C_combed_Y_combed, YC_mode_Comb_filter_off, YC_mode_2Tap_YV_filter, YC_mode_3Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_ntsc_m[] = { { 0x90, 0x80, 1, 1, 0, 2, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 3, 2, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 3, 2, 0, 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 2, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 1, 1, 0, 0 } }; static const comb_cntl1 comb_cntl1_ntsc_m[] = { { 0, 0, 1, 0, 0, 0, 0 }, { 2, 0, 1, 0, 0, 0, 0 }, { 3, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1, 0, 0 }, { 3, 0, 0, 0, 1, 0, 0 }, { 1, 0, 0, 0, 2, 0, 0 }, { 3, 0, 0, 0, 0, 0, 0 }, { 3, 0, 0, 0, 1, 0, 0 } }; static const comb_cntl2 comb_cntl2_ntsc_m[] = { { 0x10, 0x10, 0x16, 0x16 }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_ntsc_m[] = { { 0x38A, 0x718 }, { 0x38A, 0x718 }, { 0x38A, 0x718 }, { 0x38A, 0x718 }, { 0x38A, 0x718 }, { 0, 0 }, { 0x38A, 0 }, { 0x38A, 0x718 } }; static const uint8 comb_types_ntsc_433[] = { _2Tap_C_combed_Y_Sub, _2Tap_C_combed_Y_combed, _3Tap_C_combed_Y_Sub, _3Tap_C_combed_Y_combed, YC_mode_Comb_filter_off, YC_mode_2Tap_YV_filter, YC_mode_3Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_ntsc_433[] = { { 0, 0, 1, 0, 3, 2, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 3, 2, 0, 0, 0, 1, 1, 0 }, { 0, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 2, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 5, 2, 0, 0, 1, 1, 0, 0 } }; static const comb_cntl1 comb_cntl1_ntsc_433[] = { { 2, 0, 1, 0, 0, 0, 0 }, { 3, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1, 0, 0 }, { 3, 0, 0, 0, 1, 0, 0 }, { 1, 0, 0, 0, 2, 0, 0 }, { 3, 0, 0, 0, 0, 0, 0 }, { 3, 0, 0, 0, 1, 0, 0 } }; static const comb_cntl2 comb_cntl2_ntsc_433[] = { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_ntsc_433[] = { { 0x462, 0x8C9 }, { 0x462, 0x8C9 }, { 0x462, 0x8C9 }, { 0x462, 0x8C9 }, { 0, 0 }, { 0x462, 0x8C9 }, { 0x462, 0x8C9 } }; static const uint8 comb_types_pal_m[] = { _2Tap_C_combed_Y_Sub, YC_mode_2Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_pal_m[] = { { 0, 0, 1, 0, 4, 0, 1, 2, 0, 0, 2, 0 }, { 0, 0, 1, 0, 5, 0, 1, 2, 0, 0, 2, 0 } }; static const comb_cntl1 comb_cntl1_pal_m[] = { { 1, 0, 1, 1, 2, 0, 0 }, { 1, 0, 0, 1, 2, 0, 0 } }; static const comb_cntl2 comb_cntl2_pal_m[] = { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_pal_m[] = { { 0x389, 0 }, { 0x389, 0 } }; static const uint8 comb_types_pal_n[] = { _3Tap_2D_adaptive_Comb, _2Tap_C_combed_Y_Sub, YC_mode_2Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_pal_n[] = { { 0x90, 0x80, 1, 1, 0, 2, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 4, 0, 1, 2, 0, 0, 2, 0 }, { 0, 0, 1, 0, 5, 0, 1, 2, 0, 0, 2, 0 } }; static const comb_cntl1 comb_cntl1_pal_n[] = { { 0, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 1, 2, 0, 0 }, { 1, 0, 0, 1, 2, 0, 0 } }; static const comb_cntl2 comb_cntl2_pal_n[] = { { 0x10, 0x10, 0x16, 0x16 }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_pal_n[] = { { 0x46B, 0x8DA }, { 0x46C, 0 }, { 0x46C, 0 } }; static const uint8 comb_types_pal_nc[] = { _3Tap_2D_adaptive_Comb, _2Tap_C_combed_Y_Sub, YC_mode_2Tap_YV_filter, 0 }; // used to represent an N/A for easier copy'n'paste #define X 0 static const comb_cntl0 comb_cntl0_pal_nc[] = { { 0x90, 0x80, 1, 1, 0, 2, 0, 1, 0, 1, 0, 0 }, { X, X, 1, 0, 4, 0, 1, 2, 0, 0, 2, 0 }, { X, X, 1, 0, 5, 0, 1, 2, X, 0, 2, 0 } }; static const comb_cntl1 comb_cntl1_pal_nc[] = { { 0, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 1, 2, 0, 0 }, { 1, 0, 0, 1, 2, 0, 0 } }; static const comb_cntl2 comb_cntl2_pal_nc[] = { { 0x10, 0x10, 0x16, 0x16 }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_pal_nc[] = { { 0x391, 0x726 }, { 0x394, X }, { 0x394, X } }; static const uint8 comb_types_pal[] = { _3Tap_2D_adaptive_Comb, _2Tap_C_combed_Y_Sub, YC_mode_2Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_pal[] = { { 0x90, 0x80, 1, 1, 0, 2, 0, 1, 0, 1, 0, 0 }, { 0, 0, 1, 0, 4, 0, 1, 2, 0, 0, 2, 0 }, { 0, 0, 1, 0, 5, 0, 1, 2, X, 0, 2, 0 } }; static const comb_cntl1 comb_cntl1_pal[] = { { 0, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 1, 2, 0, 0 }, { 1, 0, 0, 1, 2, 0, 0 } }; static const comb_cntl2 comb_cntl2_pal[] = { { 2, 1, 8, 6 }, { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_pal[] = { { 0x46B, 0x8DA }, { 0x46C, X }, { 0x46C, X } }; static const uint8 comb_types_pal_60[] = { _2Tap_C_combed_Y_Sub, YC_mode_2Tap_YV_filter, 0 }; static const comb_cntl0 comb_cntl0_pal_60[] = { { 0, 0, 1, 0, 4, 0, 1, 2, 0, 0, 2, 0 }, { 0, 0, 1, 0, 5, 0, 1, 2, 0, 0, 2, 0 } }; static const comb_cntl1 comb_cntl1_pal_60[] = { { 1, 0, 1, 1, 2, 0, 0 }, { 1, 0, 0, 1, 2, 0, 0 } }; static const comb_cntl2 comb_cntl2_pal_60[] = { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF } }; static const comb_line_length comb_line_length_pal_60[] = { { 0x463, 0 }, { 0x463, 0 } }; static const uint8 comb_types_secam[] = { _2Tap_C_combed_Y_Sub, // could be another type, spec is unclear here YC_mode_2Tap_YV_filter, 0, }; static const comb_cntl0 comb_cntl0_secam[] = { { X, X, 0, 0, 4, X, X, X, X, 2, 2, 1 }, { X, X, 0, 0, 5, X, X, X, X, 2, 2, X } };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -