View difference between Paste ID: NL0Zg8Kj and tg4tfUBP
SHOW: | | - or go back to the newest paste.
1
//EmulationStation, a graphical front-end for ROM browsing. Created by Alec "Aloshi" Lofquist.
2
//http://www.aloshi.com
3
4
#include <SDL.h>
5
#include <iostream>
6
#include <iomanip>
7
#include "Renderer.h"
8
#include "components/GuiGameList.h"
9
#include "SystemData.h"
10
#include <boost/filesystem.hpp>
11
#include "components/GuiDetectDevice.h"
12
#include "AudioManager.h"
13
#include "platform.h"
14
#include "Log.h"
15
#include "Window.h"
16
#include "EmulationStation.h"
17
#include "Settings.h"
18
19
#ifdef _RPI_
20
	#include <bcm_host.h>
21
#endif
22
23
#include <sstream>
24
25
namespace fs = boost::filesystem;
26
27
bool parseArgs(int argc, char* argv[], unsigned int* width, unsigned int* height)
28
{
29
	if(argc > 1)
30
	{
31
		for(int i = 1; i < argc; i++)
32
		{
33
			if(strcmp(argv[i], "-w") == 0)
34
			{
35
				*width = atoi(argv[i + 1]);
36
				i++; //skip the argument value
37
			}else if(strcmp(argv[i], "-h") == 0)
38
			{
39
				*height = atoi(argv[i + 1]);
40
				i++; //skip the argument value
41
			}else if(strcmp(argv[i], "--gamelist-only") == 0)
42
			{
43
				Settings::getInstance()->setBool("PARSEGAMELISTONLY", true);
44
			}else if(strcmp(argv[i], "--ignore-gamelist") == 0)
45
			{
46
				Settings::getInstance()->setBool("IGNOREGAMELIST", true);
47
			}else if(strcmp(argv[i], "--draw-framerate") == 0)
48
			{
49
				Settings::getInstance()->setBool("DRAWFRAMERATE", true);
50
			}else if(strcmp(argv[i], "--no-exit") == 0)
51
			{
52
				Settings::getInstance()->setBool("DONTSHOWEXIT", true);
53
			}else if(strcmp(argv[i], "--debug") == 0)
54
			{
55
				Settings::getInstance()->setBool("DEBUG", true);
56
				Log::setReportingLevel(LogDebug);
57
			}else if(strcmp(argv[i], "--dimtime") == 0)
58
			{
59
				Settings::getInstance()->setInt("DIMTIME", atoi(argv[i + 1]) * 1000);
60
				i++; //skip the argument value
61
			}else if(strcmp(argv[i], "--windowed") == 0)
62
			{
63
				Settings::getInstance()->setBool("WINDOWED", true);
64
			}else if(strcmp(argv[i], "--help") == 0)
65
			{
66
				std::cout << "EmulationStation, a graphical front-end for ROM browsing.\n";
67
				std::cout << "Command line arguments:\n";
68
				std::cout << "-w [width in pixels]		set screen width\n";
69
				std::cout << "-h [height in pixels]		set screen height\n";
70
				std::cout << "--gamelist-only			skip automatic game detection, only read from gamelist.xml\n";
71
				std::cout << "--ignore-gamelist		ignore the gamelist (useful for troubleshooting)\n";
72
				std::cout << "--draw-framerate		display the framerate\n";
73
				std::cout << "--no-exit			don't show the exit option in the menu\n";
74
				std::cout << "--debug				even more logging\n";
75
				std::cout << "--dimtime [seconds]		time to wait before dimming the screen (default 30, use 0 for never)\n";
76
77
				#ifdef USE_OPENGL_DESKTOP
78
					std::cout << "--windowed			not fullscreen\n";
79
				#endif
80
81
				std::cout << "--help				summon a sentient, angry tuba\n\n";
82
				std::cout << "More information available in README.md.\n";
83
				return false; //exit after printing help
84
			}
85
		}
86
	}
87
88
	return true;
89
}
90
91
bool verifyHomeFolderExists()
92
{
93
	//make sure the config directory exists
94
	std::string home = getHomePath();
95
	std::string configDir = home + "/.emulationstation";
96
	if(!fs::exists(configDir))
97
	{
98
		std::cout << "Creating config directory \"" << configDir << "\"\n";
99
		fs::create_directory(configDir);
100
		if(!fs::exists(configDir))
101
		{
102
			std::cerr << "Config directory could not be created!\n";
103
			return false;
104
		}
105
	}
106
107
	return true;
108
}
109
110
//called on exit, assuming we get far enough to have the log initialized
111
void onExit()
112
{
113
	Log::close();
114
115
	#ifdef _RPI_
116
		bcm_host_deinit();
117
	#endif
118
}
119
120
int main(int argc, char* argv[])
121
{
122
	unsigned int width = 0;
123
	unsigned int height = 0;
124
125
	if(!parseArgs(argc, argv, &width, &height))
126
		return 0;
127
128
	//if ~/.emulationstation doesn't exist and cannot be created, bail
129
	if(!verifyHomeFolderExists())
130
		return 1;
131
132
	#ifdef _RPI_
133
		bcm_host_init();
134
	#endif
135
136
	//start the logger
137
	Log::open();
138
	LOG(LogInfo) << "EmulationStation - " << PROGRAM_VERSION_STRING;
139
140
	//always close the log and deinit the BCM library on exit
141
	atexit(&onExit);
142
143
	Window window;
144
	if(!window.init(width, height))
145
	{
146
		LOG(LogError) << "Window failed to initialize!";
147
		return 1;
148
	}
149
150
	//dont generate joystick events while we're loading (hopefully fixes "automatically started emulator" bug)
151
	SDL_JoystickEventState(SDL_DISABLE);
152
153
	//try loading the system config file
154
	if(!SystemData::loadConfig(SystemData::getConfigPath(), true))
155
	{
156
		LOG(LogError) << "Error parsing system config file!";
157
		return 1;
158
	}
159
160
	//make sure it wasn't empty
161
	if(SystemData::sSystemVector.size() == 0)
162
	{
163
		LOG(LogError) << "No systems found! Does at least one system have a game present? (check that extensions match!)";
164
		return 1;
165
	}
166
167
	//choose which GUI to open depending on if an input configuration already exists
168
	if(fs::exists(InputManager::getConfigPath()))
169
	{
170
		GuiGameList::create(&window);
171
	}else{
172
		window.pushGui(new GuiDetectDevice(&window));
173
	}
174
175
	//generate joystick events since we're done loading
176
	SDL_JoystickEventState(SDL_ENABLE);
177
178
	bool sleeping = false;
179
	unsigned int timeSinceLastEvent = 0;
180
	int lastTime = 0;
181
	bool running = true;
182
	bool canAutoStart = true;
183
184
	while(running)
185
	{
186
		SDL_Event event;
187
		while(SDL_PollEvent(&event))
188
		{
189
			switch(event.type)
190
			{
191
				case SDL_JOYHATMOTION:
192
				case SDL_JOYBUTTONDOWN:
193
				case SDL_JOYBUTTONUP:
194
				case SDL_KEYDOWN:
195
				case SDL_KEYUP:
196
				case SDL_JOYAXISMOTION:
197
					if(window.getInputManager()->parseEvent(event))
198
					{
199
						sleeping = false;
200
						canAutoStart = false;
201
						timeSinceLastEvent = 0;
202
					}
203
					break;
204
				case SDL_USEREVENT:
205
					//try to poll input devices, but do not necessarily wake up...
206
					window.getInputManager()->parseEvent(event);
207
					break;
208
				case SDL_QUIT:
209
					running = false;
210
					break;
211
			}
212
		}
213
214
		if(sleeping)
215
		{
216
			lastTime = SDL_GetTicks();
217
			SDL_Delay(1); //this doesn't need to be accurate
218-
			if(canAutoStart && timeSinceLastEvent > 5000)
218+
219
		}
220-
				canAutoStart = false;  // only if you want ES to NOT auto start again after its auto-started emulator closes
220+
221-
				timeSinceLastEvent = 0;
221+
		if(canAutoStart && timeSinceLastEvent > 5000)
222-
				window.deinit();   // shut down the renderer/SDL
222+
223-
				system("/usr/bin/xbmc-standalone");   // (e.g. system("startx");)
223+
			canAutoStart = false;  // only if you want ES to NOT auto start again after its auto-started emulator closes
224-
				window.init();   // restart the renderer/SDL
224+
225
			window.deinit();   // shut down the renderer/SDL
226
			system("/usr/bin/xbmc-standalone");   // (e.g. system("startx");)
227
			window.init();   // restart the renderer/SDL
228
			continue;
229
		}
230
231
		int curTime = SDL_GetTicks();
232
		int deltaTime = curTime - lastTime;
233
		lastTime = curTime;
234
235
		//cap deltaTime at 1000
236
		if(deltaTime > 1000 || deltaTime < 0)
237
			deltaTime = 1000;
238
239
		window.update(deltaTime);
240
		Renderer::swapBuffers(); //swap here so we can read the last screen state during updates (see ImageComponent::copyScreen())
241
		window.render();
242
243
		//sleep if we're past our threshold
244
		//sleeping entails setting a flag to start skipping frames
245
		//and initially drawing a black semi-transparent rect to dim the screen
246
		timeSinceLastEvent += deltaTime;
247
		if(timeSinceLastEvent >= (unsigned int)Settings::getInstance()->getInt("DIMTIME") && Settings::getInstance()->getInt("DIMTIME") != 0)
248
		{
249
			sleeping = true;
250
			timeSinceLastEvent = 0;
251
			Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x000000A0);
252
			Renderer::swapBuffers();
253
		}
254
255
		Log::flush();
256
	}
257
258
	Renderer::deinit();
259
	SystemData::deleteSystems();
260
261
	std::cout << "EmulationStation cleanly shutting down...\n";
262
263
	return 0;
264
}