openMSX
LaserdiscPlayer.hh
Go to the documentation of this file.
1 #ifndef LASERDISCPLAYER_HH
2 #define LASERDISCPLAYER_HH
3 
5 #include "BooleanSetting.hh"
6 #include "RecordedCommand.hh"
7 #include "EmuTime.hh"
8 #include "Schedulable.hh"
9 #include "DynamicClock.hh"
10 #include "Filename.hh"
11 #include "OggReader.hh"
13 #include "EventListener.hh"
14 #include "ThrottleManager.hh"
15 #include "outer.hh"
16 #include <memory>
17 #include <optional>
18 
19 namespace openmsx {
20 
21 class PioneerLDControl;
22 class HardwareConfig;
23 class MSXMotherBoard;
24 class LDRenderer;
25 class RawFrame;
26 
28  , private EventListener
30 {
31 public:
32  LaserdiscPlayer(const HardwareConfig& hwConf,
33  PioneerLDControl& ldControl);
35 
36  // Called from CassettePort
37  [[nodiscard]] int16_t readSample(EmuTime::param time);
38 
39  // Called from PioneerLDControl
40  void setMuting(bool left, bool right, EmuTime::param time);
41  [[nodiscard]] bool extAck(EmuTime::param /*time*/) const { return ack; }
42  void extControl(bool bit, EmuTime::param time);
43  [[nodiscard]] const RawFrame* getRawFrame() const;
44 
45  template<typename Archive>
46  void serialize(Archive& ar, unsigned version);
47 
48  // video interface
49  [[nodiscard]] MSXMotherBoard& getMotherBoard() { return motherBoard; }
50 
51  enum RemoteState {
57  };
58 
59  enum PlayerState {
65  };
66 
67  enum SeekState {
72  };
73 
74  enum StereoMode {
77  STEREO
78  };
79 
83  };
84 private:
85  void setImageName(std::string newImage, EmuTime::param time);
86  [[nodiscard]] const Filename& getImageName() const { return oggImage; }
87  void autoRun();
88 
91  void play(EmuTime::param time);
92  void pause(EmuTime::param time);
93  void stop(EmuTime::param time);
94  void eject(EmuTime::param time);
95  void seekFrame(size_t frame, EmuTime::param time);
96  void stepFrame(bool forwards);
97  void seekChapter(int chapter, EmuTime::param time);
98 
99  // Control from MSX
100 
103  void scheduleDisplayStart(EmuTime::param time);
104  [[nodiscard]] bool isVideoOutputAvailable(EmuTime::param time);
105  void remoteButtonNEC(unsigned code, EmuTime::param time);
106  void submitRemote(RemoteProtocol protocol, unsigned code);
107  void setAck(EmuTime::param time, int wait);
108  [[nodiscard]] size_t getCurrentSample(EmuTime::param time);
109  void createRenderer();
110 
111  // SoundDevice
112  void generateChannels(float** buffers, unsigned num) override;
113  bool updateBuffer(unsigned length, float* buffer,
114  EmuTime::param time) override;
115  [[nodiscard]] float getAmplificationFactorImpl() const override;
116 
117  // Schedulable
118  struct SyncAck final : public Schedulable {
119  friend class LaserdiscPlayer;
120  explicit SyncAck(Scheduler& s) : Schedulable(s) {}
121  void executeUntil(EmuTime::param time) override {
122  auto& player = OUTER(LaserdiscPlayer, syncAck);
123  player.execSyncAck(time);
124  }
125  } syncAck;
126  struct SyncOdd final : public Schedulable {
127  friend class LaserdiscPlayer;
128  explicit SyncOdd(Scheduler& s) : Schedulable(s) {}
129  void executeUntil(EmuTime::param time) override {
130  auto& player = OUTER(LaserdiscPlayer, syncOdd);
131  player.execSyncFrame(time, true);
132  }
133  } syncOdd;
134  struct SyncEven final : public Schedulable {
135  friend class LaserdiscPlayer;
136  explicit SyncEven(Scheduler& s) : Schedulable(s) {}
137  void executeUntil(EmuTime::param time) override {
138  auto& player = OUTER(LaserdiscPlayer, syncEven);
139  player.execSyncFrame(time, false);
140  }
141  } syncEven;
142 
143  void execSyncAck(EmuTime::param time);
144  void execSyncFrame(EmuTime::param time, bool odd);
145  [[nodiscard]] EmuTime::param getCurrentTime() const { return syncAck.getCurrentTime(); }
146 
147  // EventListener
148  int signalEvent(const Event& event) noexcept override;
149 
150  // VideoSystemChangeListener interface:
151  void preVideoSystemChange() noexcept override;
152  void postVideoSystemChange() noexcept override;
153 
154  MSXMotherBoard& motherBoard;
155  PioneerLDControl& ldControl;
156 
157  struct Command final : RecordedCommand {
158  Command(CommandController& commandController,
159  StateChangeDistributor& stateChangeDistributor,
160  Scheduler& scheduler);
161  void execute(span<const TclObject> tokens, TclObject& result,
162  EmuTime::param time) override;
163  [[nodiscard]] std::string help(span<const TclObject> tokens) const override;
164  void tabCompletion(std::vector<std::string>& tokens) const override;
165  } laserdiscCommand;
166 
167  std::optional<OggReader> video;
168  Filename oggImage;
169  std::unique_ptr<LDRenderer> renderer;
170 
171  void nextFrame(EmuTime::param time);
172  void setFrameStep();
173  size_t currentFrame;
174  int frameStep;
175 
176  // Audio state
177  DynamicClock sampleClock;
178  EmuTime start;
179  size_t playingFromSample;
180  size_t lastPlayedSample;
181  bool muteLeft, muteRight;
182  StereoMode stereoMode;
183 
184  // Ext Control
185  RemoteState remoteState;
186  EmuTime remoteLastEdge;
187  unsigned remoteBitNr;
188  unsigned remoteBits;
189  bool remoteLastBit;
190  RemoteProtocol remoteProtocol;
191  unsigned remoteCode;
192  bool remoteExecuteDelayed;
193  // Number of v-blank since code was sent
194  int remoteVblanksBack;
195 
196  /* We need to maintain some state for seeking */
197  SeekState seekState;
198 
199  /* frame the MSX has requested to wait for */
200  size_t waitFrame;
201 
202  // pause playing back on reaching wait frame
203  bool stillOnWaitFrame;
204 
205  /* The specific frame or chapter we are seeking to */
206  int seekNum;
207 
208  // For ack
209  bool ack;
210 
211  // State of the video itself
212  bool seeking;
213 
214  PlayerState playerState;
215 
216  enum PlayingSpeed {
217  SPEED_STEP3 = -5, // Each frame is repeated 90 times
218  SPEED_STEP1 = -4, // Each frame is repeated 30 times
219  SPEED_1IN16 = -3, // Each frame is repeated 16 times
220  SPEED_1IN8 = -2, // Each frame is repeated 8 times
221  SPEED_1IN4 = -1, // Each frame is repeated 4 times
222  SPEED_1IN2 = 0,
223  SPEED_X1 = 1,
224  SPEED_X2 = 2,
225  SPEED_X3 = 3
226  };
227  int playingSpeed;
228 
229  // Loading indicator
230  BooleanSetting autoRunSetting;
231  LoadingIndicator loadingIndicator;
232  int sampleReads;
233 };
234 
236 
237 } // namespace openmsx
238 
239 #endif
This class represents a filename.
Definition: Filename.hh:18
void setMuting(bool left, bool right, EmuTime::param time)
int16_t readSample(EmuTime::param time)
void extControl(bool bit, EmuTime::param time)
MSXMotherBoard & getMotherBoard()
LaserdiscPlayer(const HardwareConfig &hwConf, PioneerLDControl &ldControl)
const RawFrame * getRawFrame() const
bool extAck(EmuTime::param) const
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:14
Definition: span.hh:126
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:343
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
#define OUTER(type, member)
Definition: outer.hh:41