1 #pragma once
2 
3 #include "stdafx.h"
4 #include <atomic>
5 #include "../Utilities/SimpleLock.h"
6 #include "VirtualFile.h"
7 
8 class BaseMapper;
9 class RewindManager;
10 class HistoryViewer;
11 class APU;
12 class CPU;
13 class PPU;
14 class MemoryManager;
15 class ControlManager;
16 class AutoSaveManager;
17 class HdPackBuilder;
18 class HdAudioDevice;
19 class SystemActionManager;
20 class Timer;
21 class CheatManager;
22 class SaveStateManager;
23 class VideoDecoder;
24 class VideoRenderer;
25 class DebugHud;
26 class SoundMixer;
27 class NotificationManager;
28 class Debugger;
29 class EmulationSettings;
30 class BatteryManager;
31 
32 struct HdPackData;
33 struct HashInfo;
34 struct RomInfo;
35 
36 enum class MemoryOperationType;
37 enum class NesModel;
38 enum class ScaleFilterType;
39 enum class ConsoleFeatures;
40 enum class DebugMemoryType;
41 enum class EventType;
42 enum class RamPowerOnState;
43 
44 class Console : public std::enable_shared_from_this<Console>
45 {
46 private:
47 	SimpleLock _runLock;
48 	SimpleLock _stopLock;
49 	SimpleLock _debuggerLock;
50 	atomic<uint32_t> _pauseCounter;
51 
52 	shared_ptr<RewindManager> _rewindManager;
53 	shared_ptr<HistoryViewer> _historyViewer;
54 
55 	shared_ptr<CPU> _cpu;
56 	shared_ptr<PPU> _ppu;
57 	shared_ptr<APU> _apu;
58 	shared_ptr<Debugger> _debugger;
59 	shared_ptr<BaseMapper> _mapper;
60 	shared_ptr<ControlManager> _controlManager;
61 	shared_ptr<MemoryManager> _memoryManager;
62 
63 	//Used by VS-DualSystem
64 	shared_ptr<Console> _master;
65 	shared_ptr<Console> _slave;
66 
67 	shared_ptr<BatteryManager> _batteryManager;
68 	shared_ptr<SystemActionManager> _systemActionManager;
69 
70 	shared_ptr<VideoDecoder> _videoDecoder;
71 	shared_ptr<VideoRenderer> _videoRenderer;
72 	unique_ptr<AutoSaveManager> _autoSaveManager;
73 	shared_ptr<SaveStateManager> _saveStateManager;
74 	shared_ptr<CheatManager> _cheatManager;
75 	shared_ptr<DebugHud> _debugHud;
76 	shared_ptr<SoundMixer> _soundMixer;
77 	shared_ptr<NotificationManager> _notificationManager;
78 	shared_ptr<EmulationSettings> _settings;
79 
80 	shared_ptr<HdPackBuilder> _hdPackBuilder;
81 	shared_ptr<HdPackData> _hdData;
82 	unique_ptr<HdAudioDevice> _hdAudioDevice;
83 
84 	NesModel _model;
85 
86 	string _romFilepath;
87 	string _patchFilename;
88 
89 	bool _paused = false;
90 	bool _stop = false;
91 	bool _running = false;
92 	int32_t _stopCode = 0;
93 
94 	bool _pauseOnNextFrameRequested = false;
95 	bool _resetRunTimers = false;
96 
97 	bool _disableOcNextFrame = false;
98 
99 	bool _initialized = false;
100 	std::thread::id _emulationThreadId;
101 
102 	void LoadHdPack(VirtualFile &romFile, VirtualFile &patchFile);
103 
104 	void UpdateNesModel(bool sendNotification);
105 	double GetFrameDelay();
106 	void DisplayDebugInformation(double lastFrame, double &lastFrameMin, double &lastFrameMax, double frameDurations[60]);
107 
108 	void ExportStub();
109 
110 public:
111 	Console(shared_ptr<Console> master = nullptr, EmulationSettings* initialSettings = nullptr);
112 	~Console();
113 
114 	void Init();
115 	void Release(bool forShutdown);
116 
117 	shared_ptr<BatteryManager> GetBatteryManager();
118 	shared_ptr<SaveStateManager> GetSaveStateManager();
119 	shared_ptr<VideoDecoder> GetVideoDecoder();
120 	shared_ptr<VideoRenderer> GetVideoRenderer();
121 	shared_ptr<DebugHud> GetDebugHud();
122 	shared_ptr<SoundMixer> GetSoundMixer();
123 	shared_ptr<NotificationManager> GetNotificationManager();
124 	EmulationSettings* GetSettings();
125 
126 	bool IsDualSystem();
127 	shared_ptr<Console> GetDualConsole();
128 	bool IsMaster();
129 
130 	void ProcessCpuClock();
131 	CPU* GetCpu();
132 	PPU* GetPpu();
133 	APU* GetApu();
134 	BaseMapper* GetMapper();
135 	ControlManager* GetControlManager();
136 	MemoryManager* GetMemoryManager();
137 	CheatManager* GetCheatManager();
138 	shared_ptr<RewindManager> GetRewindManager();
139 	HistoryViewer* GetHistoryViewer();
140 
141 	bool LoadMatchingRom(string romName, HashInfo hashInfo);
142 	string FindMatchingRom(string romName, HashInfo hashInfo);
143 
144 	bool Initialize(string romFile, string patchFile = "");
145 	bool Initialize(VirtualFile &romFile);
146 	bool Initialize(VirtualFile &romFile, VirtualFile &patchFile);
147 
148 	void SaveBatteries();
149 
150 	void Run();
151 	void ResetRunTimers();
152 	void Stop(int stopCode = 0);
153 
154 	int32_t GetStopCode();
155 
156 	void RunSingleFrame();
157 	void RunSlaveCpu();
158 	bool UpdateHdPackMode();
159 
160 	shared_ptr<SystemActionManager> GetSystemActionManager();
161 
162 	template<typename T>
GetSystemActionManager()163 	shared_ptr<T> GetSystemActionManager()
164 	{
165 		return std::dynamic_pointer_cast<T>(_systemActionManager);
166 	}
167 
168 	uint32_t GetDipSwitchCount();
169 	ConsoleFeatures GetAvailableFeatures();
170 	void InputBarcode(uint64_t barcode, uint32_t digitCount);
171 
172 	void LoadTapeFile(string filepath);
173 	void StartRecordingTapeFile(string filepath);
174 	void StopRecordingTapeFile();
175 	bool IsRecordingTapeFile();
176 	bool IsNsf();
177 
178 	std::thread::id GetEmulationThreadId();
179 
180 	void Reset(bool softReset = true);
181 	void PowerCycle();
182 	void ResetComponents(bool softReset);
183 
184 	//Used to pause the emu loop to perform thread-safe operations
185 	void Pause();
186 
187 	//Used to resume the emu loop after calling Pause()
188 	void Resume();
189 
190 	void BreakIfDebugging();
191 	shared_ptr<Debugger> GetDebugger(bool autoStart = true);
192 	void StopDebugger();
193 
194 	void SaveState(ostream &saveStream);
195 	void LoadState(istream &loadStream);
196 	void LoadState(istream &loadStream, uint32_t stateVersion);
197 	void LoadState(uint8_t *buffer, uint32_t bufferSize);
198 
199 	VirtualFile GetRomPath();
200 	VirtualFile GetPatchFile();
201 	RomInfo GetRomInfo();
202 	uint32_t GetFrameCount();
203 	NesModel GetModel();
204 
205 	uint32_t GetLagCounter();
206 	void ResetLagCounter();
207 
208 	bool IsRunning();
209 	bool IsExecutionStopped();
210 
211 	bool IsPaused();
212 	void PauseOnNextFrame();
213 
214 	void SetNextFrameOverclockStatus(bool disabled);
215 
216 	bool IsDebuggerAttached();
217 
218 	void InitializeRam(void* data, uint32_t length);
219 	static void InitializeRam(RamPowerOnState powerOnState, void* data, uint32_t length);
220 
221 	shared_ptr<HdPackData> GetHdData();
222 	bool IsHdPpu();
223 
224 	void StartRecordingHdPack(string saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize);
225 	void StopRecordingHdPack();
226 
227 	void CopyRewindData(shared_ptr<Console> sourceConsole);
228 
229 	uint8_t* GetRamBuffer(DebugMemoryType memoryType, uint32_t &size, int32_t &startAddr);
230 
231 	void DebugAddTrace(const char *log);
232 	void DebugProcessPpuCycle();
233 	void DebugProcessEvent(EventType type);
234 	void DebugProcessInterrupt(uint16_t cpuAddr, uint16_t destCpuAddr, bool forNmi);
235 	void DebugSetLastFramePpuScroll(uint16_t addr, uint8_t xScroll, bool updateHorizontalScrollOnly);
236 	bool DebugProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value);
237 	void DebugProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value);
238 	void DebugProcessVramWriteOperation(uint16_t addr, uint8_t &value);
239 };
240