openMSX
LaserdiscPlayer.hh
Go to the documentation of this file.
1#ifndef LASERDISCPLAYER_HH
2#define LASERDISCPLAYER_HH
3
5#include "MSXMotherBoard.hh"
6#include "BooleanSetting.hh"
7#include "RecordedCommand.hh"
8#include "EmuTime.hh"
9#include "Schedulable.hh"
10#include "DynamicClock.hh"
11#include "Filename.hh"
12#include "OggReader.hh"
14#include "EventListener.hh"
15#include "ThrottleManager.hh"
16#include "outer.hh"
17#include <memory>
18#include <optional>
19
20namespace openmsx {
21
23class HardwareConfig;
24class LDRenderer;
25class RawFrame;
26
28 , private EventListener
30 , public MediaInfoProvider
31{
32public:
33 LaserdiscPlayer(const HardwareConfig& hwConf,
34 PioneerLDControl& ldControl);
36
37 // Called from CassettePort
38 [[nodiscard]] int16_t readSample(EmuTime::param time);
39
40 // Called from PioneerLDControl
41 void setMuting(bool left, bool right, EmuTime::param time);
42 [[nodiscard]] bool extAck(EmuTime::param /*time*/) const { return ack; }
43 void extControl(bool bit, EmuTime::param time);
44 [[nodiscard]] const RawFrame* getRawFrame() const;
45
46 template<typename Archive>
47 void serialize(Archive& ar, unsigned version);
48
49 // video interface
50 [[nodiscard]] MSXMotherBoard& getMotherBoard() { return motherBoard; }
51
52 // MediaInfoProvider
53 void getMediaInfo(TclObject& result) override;
54
62
63 enum class PlayerState {
64 STOPPED,
65 PLAYING,
67 PAUSED,
68 STILL
69 };
70
71 enum class SeekState {
72 NONE,
73 CHAPTER,
74 FRAME,
75 WAIT,
76 };
77
78 enum class StereoMode {
79 LEFT,
80 RIGHT,
81 STEREO
82 };
83
84 enum class RemoteProtocol {
85 NONE,
86 NEC,
87 };
88private:
89 std::string getStateString() const;
90 void setImageName(std::string newImage, EmuTime::param time);
91 [[nodiscard]] const Filename& getImageName() const { return oggImage; }
92 void autoRun();
93
96 void play(EmuTime::param time);
97 void pause(EmuTime::param time);
98 void stop(EmuTime::param time);
99 void eject(EmuTime::param time);
100 void seekFrame(size_t frame, EmuTime::param time);
101 void stepFrame(bool forwards);
102 void seekChapter(int chapter, EmuTime::param time);
103
104 // Control from MSX
105
108 void scheduleDisplayStart(EmuTime::param time);
109 [[nodiscard]] bool isVideoOutputAvailable(EmuTime::param time);
110 void remoteButtonNEC(uint8_t code, EmuTime::param time);
111 void submitRemote(RemoteProtocol protocol, uint8_t code);
112 void setAck(EmuTime::param time, int wait);
113 [[nodiscard]] size_t getCurrentSample(EmuTime::param time);
114 void createRenderer();
115
116 // SoundDevice
117 void generateChannels(std::span<float*> buffers, unsigned num) override;
118 bool updateBuffer(size_t length, float* buffer,
119 EmuTime::param time) override;
120 [[nodiscard]] float getAmplificationFactorImpl() const override;
121
122 // Schedulable
123 struct SyncAck final : public Schedulable {
124 friend class LaserdiscPlayer;
125 explicit SyncAck(Scheduler& s) : Schedulable(s) {}
126 void executeUntil(EmuTime::param time) override {
127 auto& player = OUTER(LaserdiscPlayer, syncAck);
128 player.execSyncAck(time);
129 }
130 } syncAck;
131 struct SyncOdd final : public Schedulable {
132 friend class LaserdiscPlayer;
133 explicit SyncOdd(Scheduler& s) : Schedulable(s) {}
134 void executeUntil(EmuTime::param time) override {
135 auto& player = OUTER(LaserdiscPlayer, syncOdd);
136 player.execSyncFrame(time, true);
137 }
138 } syncOdd;
139 struct SyncEven final : public Schedulable {
140 friend class LaserdiscPlayer;
141 explicit SyncEven(Scheduler& s) : Schedulable(s) {}
142 void executeUntil(EmuTime::param time) override {
143 auto& player = OUTER(LaserdiscPlayer, syncEven);
144 player.execSyncFrame(time, false);
145 }
146 } syncEven;
147
148 void execSyncAck(EmuTime::param time);
149 void execSyncFrame(EmuTime::param time, bool odd);
150 [[nodiscard]] EmuTime::param getCurrentTime() const { return syncAck.getCurrentTime(); }
151
152 // EventListener
153 bool signalEvent(const Event& event) override;
154
155 // VideoSystemChangeListener interface:
156 void preVideoSystemChange() noexcept override;
157 void postVideoSystemChange() noexcept override;
158
159 MSXMotherBoard& motherBoard;
160 PioneerLDControl& ldControl;
161
162 struct Command final : RecordedCommand {
163 Command(CommandController& commandController,
164 StateChangeDistributor& stateChangeDistributor,
165 Scheduler& scheduler);
166 void execute(std::span<const TclObject> tokens, TclObject& result,
167 EmuTime::param time) override;
168 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
169 void tabCompletion(std::vector<std::string>& tokens) const override;
170 } laserdiscCommand;
171
172 std::optional<OggReader> video;
173 Filename oggImage;
174 std::unique_ptr<LDRenderer> renderer;
175
176 void nextFrame(EmuTime::param time);
177 void setFrameStep();
178 size_t currentFrame;
179 int frameStep;
180
181 // Audio state
182 DynamicClock sampleClock{EmuTime::zero()};
183 EmuTime start = EmuTime::zero();
184 size_t playingFromSample;
185 size_t lastPlayedSample;
186 bool muteLeft = false, muteRight = false;
187 StereoMode stereoMode;
188
189 // Ext Control
190 RemoteState remoteState = RemoteState::IDLE;
191 EmuTime remoteLastEdge = EmuTime::zero();
192 unsigned remoteBitNr;
193 unsigned remoteBits;
194 bool remoteLastBit = false;
195 RemoteProtocol remoteProtocol = RemoteProtocol::NONE;
196 uint8_t remoteCode;
197 bool remoteExecuteDelayed;
198 // Number of v-blank since code was sent
199 int remoteVblanksBack;
200
201 /* We need to maintain some state for seeking */
202 SeekState seekState;
203
204 /* frame the MSX has requested to wait for */
205 size_t waitFrame;
206
207 // pause playing back on reaching wait frame
208 bool stillOnWaitFrame;
209
210 /* The specific frame or chapter we are seeking to */
211 int seekNum;
212
213 // For ack
214 bool ack = false;
215
216 // State of the video itself
217 bool seeking = false;
218
219 PlayerState playerState = PlayerState::STOPPED;
220
221 enum PlayingSpeed {
222 SPEED_STEP3 = -5, // Each frame is repeated 90 times
223 SPEED_STEP1 = -4, // Each frame is repeated 30 times
224 SPEED_1IN16 = -3, // Each frame is repeated 16 times
225 SPEED_1IN8 = -2, // Each frame is repeated 8 times
226 SPEED_1IN4 = -1, // Each frame is repeated 4 times
227 SPEED_1IN2 = 0,
228 SPEED_X1 = 1,
229 SPEED_X2 = 2,
230 SPEED_X3 = 3
231 };
232 int playingSpeed;
233
234 // Loading indicator
235 BooleanSetting autoRunSetting;
236 LoadingIndicator loadingIndicator;
237 int sampleReads = 0;
238};
239
241
242} // namespace openmsx
243
244#endif
This class represents a filename.
Definition Filename.hh:20
void setMuting(bool left, bool right, EmuTime::param time)
int16_t readSample(EmuTime::param time)
void extControl(bool bit, EmuTime::param time)
MSXMotherBoard & getMotherBoard()
const RawFrame * getRawFrame() const
bool extAck(EmuTime::param) const
void getMediaInfo(TclObject &result) override
This method gets called when information is required on the media inserted in the media slot of the p...
void serialize(Archive &ar, unsigned version)
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
Definition RawFrame.hh:16
Schedulable(const Schedulable &)=delete
This file implemented 3 utility functions:
Definition Autofire.cc:11
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event
Definition Event.hh:445
#define OUTER(type, member)
Definition outer.hh:42
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)