1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef TIA_FRAME_LAYOUT_DETECTOR |
19 | #define TIA_FRAME_LAYOUT_DETECTOR |
20 | |
21 | #include "AbstractFrameManager.hxx" |
22 | #include "FrameLayout.hxx" |
23 | |
24 | /** |
25 | * This frame manager performs frame layout autodetection. It counts the scanlines |
26 | * in each frame and assigns guesses the frame layout from this. |
27 | */ |
28 | class FrameLayoutDetector: public AbstractFrameManager { |
29 | public: |
30 | |
31 | FrameLayoutDetector(); |
32 | |
33 | public: |
34 | |
35 | /** |
36 | * Return the detected frame layout. |
37 | */ |
38 | FrameLayout detectedLayout() const; |
39 | |
40 | protected: |
41 | |
42 | /** |
43 | * Hook into vsync changes. |
44 | */ |
45 | void onSetVsync() override; |
46 | |
47 | /** |
48 | * Hook into reset. |
49 | */ |
50 | void onReset() override; |
51 | |
52 | /** |
53 | * Hook into line changes. |
54 | */ |
55 | void onNextLine() override; |
56 | |
57 | private: |
58 | |
59 | /** |
60 | * This frame manager only tracks frame boundaries, so we have only two states. |
61 | */ |
62 | enum class State { |
63 | // Wait for VSYNC to be enabled. |
64 | waitForVsyncStart, |
65 | |
66 | // Wait for VSYNC to be disabled. |
67 | waitForVsyncEnd |
68 | }; |
69 | |
70 | |
71 | private: |
72 | |
73 | /** |
74 | * Change state and change internal state accordingly. |
75 | */ |
76 | void setState(State state); |
77 | |
78 | /** |
79 | * Finalize the current frame and guess frame layout from the scanline count. |
80 | */ |
81 | void finalizeFrame(); |
82 | |
83 | private: |
84 | |
85 | /** |
86 | * The current state. |
87 | */ |
88 | State myState; |
89 | |
90 | /** |
91 | * The total number of frames detected as the respective frame layout. |
92 | */ |
93 | uInt32 myNtscFrames, myPalFrames; |
94 | |
95 | /** |
96 | * We count the number of scanlines we spend waiting for vsync to be |
97 | * toggled. If a threshold is exceeded, we force the transition. |
98 | */ |
99 | uInt32 myLinesWaitingForVsyncToStart; |
100 | |
101 | private: |
102 | |
103 | FrameLayoutDetector(const FrameLayoutDetector&) = delete; |
104 | FrameLayoutDetector(FrameLayoutDetector&&) = delete; |
105 | FrameLayoutDetector& operator=(const FrameLayoutDetector&) = delete; |
106 | FrameLayoutDetector& operator=(FrameLayoutDetector&&) = delete; |
107 | |
108 | }; |
109 | |
110 | #endif // TIA_FRAME_LAYOUT_DETECTOR |
111 | |