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 */
28class 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