10
10
// - Handles video context cleanup and setup
11
11
// - Loads textures with fallback options
12
12
// - Renders text using SDL_ttf
13
+ // - Settings are done via config.ini file.
13
14
// Dependencies:
14
15
// sudo apt-get install -y build-essential libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev libvlc-dev
15
16
// Compile:
27
28
#include < vector> // For std::vector
28
29
#include < string> // For std::string
29
30
#include < cstdlib> // For std::system
31
+ #include < fstream> // For file I/O operations
32
+ #include < map> // For std::map container
33
+
30
34
31
35
namespace fs = std::filesystem; // Alias for filesystem lib
32
36
33
37
// ------------------ Configuration Constants ------------------
34
38
35
- const std::string VPX_TABLES_PATH = " /home/tarso/Games/vpinball/build/tables/" ;
36
- const std::string VPX_EXECUTABLE_CMD = " /home/tarso/Games/vpinball/build/VPinballX_GL" ;
37
- const std::string VPX_SUB_CMD = " -Play" ;
38
- const std::string VPX_START_ARGS = " DRI_PRIME=1 gamemoderun" ;
39
- const std::string VPX_END_ARGS = " " ;
40
-
41
- const std::string DEFAULT_TABLE_IMAGE = " img/default_table.png" ;
42
- const std::string DEFAULT_BACKGLASS_IMAGE = " img/default_backglass.png" ;
43
- const std::string DEFAULT_DMD_IMAGE = " img/default_dmd.png" ;
44
- const std::string DEFAULT_WHEEL_IMAGE = " img/default_wheel.png" ;
45
-
46
- const std::string DEFAULT_TABLE_VIDEO = " img/default_table.mp4" ;
47
- const std::string DEFAULT_BACKGLASS_VIDEO = " img/default_backglass.mp4" ;
48
- const std::string DEFAULT_DMD_VIDEO = " img/default_dmd.mp4" ;
49
-
50
- const std::string CUSTOM_TABLE_IMAGE = " images/table.png" ;
51
- const std::string CUSTOM_BACKGLASS_IMAGE = " images/backglass.png" ;
52
- const std::string CUSTOM_DMD_IMAGE = " images/marquee.png" ;
53
- const std::string CUSTOM_WHEEL_IMAGE = " images/wheel.png" ;
54
-
55
- const std::string CUSTOM_TABLE_VIDEO = " video/table.mp4" ;
56
- const std::string CUSTOM_BACKGLASS_VIDEO = " video/backglass.mp4" ;
57
- const std::string CUSTOM_DMD_VIDEO = " video/dmd.mp4" ;
58
-
59
- const int MAIN_WINDOW_MONITOR = 1 ;
60
- const int MAIN_WINDOW_WIDTH = 1080 ;
61
- const int MAIN_WINDOW_HEIGHT = 1920 ;
62
- const int WHEEL_IMAGE_SIZE = 300 ;
63
- const int WHEEL_IMAGE_MARGIN = 24 ;
64
- const std::string FONT_PATH = " /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" ;
65
- const int FONT_SIZE = 28 ;
66
-
67
- const int SECOND_WINDOW_MONITOR = 0 ;
68
- const int SECOND_WINDOW_WIDTH = 1024 ;
69
- const int SECOND_WINDOW_HEIGHT = 1024 ;
70
- const int BACKGLASS_MEDIA_WIDTH = 1024 ;
71
- const int BACKGLASS_MEDIA_HEIGHT = 768 ;
72
- const int DMD_MEDIA_WIDTH = 1024 ;
73
- const int DMD_MEDIA_HEIGHT = 256 ;
74
-
75
- const int FADE_DURATION_MS = 300 ;
76
- const Uint8 FADE_TARGET_ALPHA = 128 ;
77
-
78
- const std::string TABLE_CHANGE_SOUND = " snd/table_change.mp3" ;
79
- const std::string TABLE_LOAD_SOUND = " snd/table_load.mp3" ;
39
+ // Configuration Variables (no longer const)
40
+ std::string VPX_TABLES_PATH;
41
+ std::string VPX_EXECUTABLE_CMD;
42
+ std::string VPX_SUB_CMD; // Not in config.ini, so we'll set a default later
43
+ std::string VPX_START_ARGS;
44
+ std::string VPX_END_ARGS;
45
+
46
+ std::string DEFAULT_TABLE_IMAGE; // Not in config.ini, set default later
47
+ std::string DEFAULT_BACKGLASS_IMAGE; // Not in config.ini
48
+ std::string DEFAULT_DMD_IMAGE; // Not in config.ini
49
+ std::string DEFAULT_WHEEL_IMAGE; // Not in config.ini
50
+ std::string DEFAULT_TABLE_VIDEO; // Not in config.ini
51
+ std::string DEFAULT_BACKGLASS_VIDEO; // Not in config.ini
52
+ std::string DEFAULT_DMD_VIDEO; // Not in config.ini
53
+
54
+ std::string CUSTOM_TABLE_IMAGE;
55
+ std::string CUSTOM_BACKGLASS_IMAGE;
56
+ std::string CUSTOM_DMD_IMAGE;
57
+ std::string CUSTOM_WHEEL_IMAGE;
58
+ std::string CUSTOM_TABLE_VIDEO;
59
+ std::string CUSTOM_BACKGLASS_VIDEO;
60
+ std::string CUSTOM_DMD_VIDEO;
61
+
62
+ int MAIN_WINDOW_MONITOR;
63
+ int MAIN_WINDOW_WIDTH;
64
+ int MAIN_WINDOW_HEIGHT;
65
+ int WHEEL_IMAGE_SIZE;
66
+ int WHEEL_IMAGE_MARGIN;
67
+ std::string FONT_PATH;
68
+ int FONT_SIZE;
69
+
70
+ int SECOND_WINDOW_MONITOR;
71
+ int SECOND_WINDOW_WIDTH;
72
+ int SECOND_WINDOW_HEIGHT;
73
+ int BACKGLASS_MEDIA_WIDTH;
74
+ int BACKGLASS_MEDIA_HEIGHT;
75
+ int DMD_MEDIA_WIDTH;
76
+ int DMD_MEDIA_HEIGHT;
77
+
78
+ int FADE_DURATION_MS; // Not in config.ini
79
+ Uint8 FADE_TARGET_ALPHA; // Not in config.ini
80
+ std::string TABLE_CHANGE_SOUND; // Not in config.ini
81
+ std::string TABLE_LOAD_SOUND; // Not in config.ini
80
82
81
83
// ------------------ Data Structures ------------------
82
84
@@ -292,6 +294,72 @@ void launchTable(const Table &table) {
292
294
std::system (command.c_str ());
293
295
}
294
296
297
+ // -------------------- Settings --------------------------
298
+
299
+ // Helper functions to get values with defaults
300
+ std::string get_string (const std::map<std::string, std::map<std::string, std::string>>& config,
301
+ const std::string& section, const std::string& key, const std::string& default_value) {
302
+ if (config.count (section) && config.at (section).count (key)) {
303
+ return config.at (section).at (key);
304
+ }
305
+ return default_value;
306
+ }
307
+
308
+ int get_int (const std::map<std::string, std::map<std::string, std::string>>& config,
309
+ const std::string& section, const std::string& key, int default_value) {
310
+ if (config.count (section) && config.at (section).count (key)) {
311
+ try {
312
+ return std::stoi (config.at (section).at (key));
313
+ } catch (const std::exception &) {
314
+ return default_value;
315
+ }
316
+ }
317
+ return default_value;
318
+ }
319
+
320
+ // Structure to hold all config data
321
+ std::map<std::string, std::map<std::string, std::string>> load_config (const std::string& filename) {
322
+ std::map<std::string, std::map<std::string, std::string>> config;
323
+ std::ifstream file (filename);
324
+ std::string current_section;
325
+
326
+ if (!file.is_open ()) {
327
+ std::cerr << " Could not open " << filename << " . Using defaults." << std::endl;
328
+ return config;
329
+ }
330
+
331
+ std::string line;
332
+ while (std::getline (file, line)) {
333
+ // Skip empty lines or comments
334
+ if (line.empty () || line[0 ] == ' ;' ) continue ;
335
+
336
+ // Check for section (e.g., [VPX])
337
+ if (line[0 ] == ' [' ) {
338
+ size_t end = line.find (' ]' );
339
+ if (end != std::string::npos) {
340
+ current_section = line.substr (1 , end - 1 );
341
+ config[current_section]; // Create section if it doesn't exist
342
+ }
343
+ continue ;
344
+ }
345
+
346
+ // Parse key=value pairs
347
+ size_t eq_pos = line.find (' =' );
348
+ if (eq_pos != std::string::npos && !current_section.empty ()) {
349
+ std::string key = line.substr (0 , eq_pos);
350
+ std::string value = line.substr (eq_pos + 1 );
351
+ // Remove any trailing or leading whitespace (basic cleanup)
352
+ key.erase (0 , key.find_first_not_of (" \t " ));
353
+ key.erase (key.find_last_not_of (" \t " ) + 1 );
354
+ value.erase (0 , value.find_first_not_of (" \t " ));
355
+ value.erase (value.find_last_not_of (" \t " ) + 1 );
356
+ config[current_section][key] = value;
357
+ }
358
+ }
359
+ file.close ();
360
+ return config;
361
+ }
362
+
295
363
// ------------------ Main Application ------------------
296
364
297
365
enum class TransitionState { IDLE, FADING_OUT, FADING_IN };
@@ -309,6 +377,57 @@ enum class TransitionState { IDLE, FADING_OUT, FADING_IN };
309
377
* @return int Returns 0 on successful execution, or 1 on failure.
310
378
*/
311
379
int main (int argc, char * argv[]) {
380
+ // ------------- Load the configuration --------------
381
+ auto config = load_config (" config.ini" );
382
+
383
+ // Assign VPX settings
384
+ VPX_TABLES_PATH = get_string (config, " VPX" , " TablesPath" , " /home/tarso/Games/vpinball/build/tables/" );
385
+ VPX_EXECUTABLE_CMD = get_string (config, " VPX" , " ExecutableCmd" , " /home/tarso/Games/vpinball/build/VPinballX_GL" );
386
+ VPX_SUB_CMD = " -Play" ; // Not in config, use hardcoded default
387
+ VPX_START_ARGS = get_string (config, " VPX" , " StartArgs" , " DRI_PRIME=1 gamemoderun" );
388
+ VPX_END_ARGS = get_string (config, " VPX" , " EndArgs" , " " );
389
+
390
+ // Assign CustomMedia settings
391
+ CUSTOM_TABLE_IMAGE = get_string (config, " CustomMedia" , " TableImage" , " images/table.png" );
392
+ CUSTOM_BACKGLASS_IMAGE = get_string (config, " CustomMedia" , " BackglassImage" , " images/backglass.png" );
393
+ CUSTOM_DMD_IMAGE = get_string (config, " CustomMedia" , " DmdImage" , " images/marquee.png" );
394
+ CUSTOM_WHEEL_IMAGE = get_string (config, " CustomMedia" , " WheelImage" , " images/wheel.png" );
395
+ CUSTOM_TABLE_VIDEO = get_string (config, " CustomMedia" , " TableVideo" , " video/table.mp4" );
396
+ CUSTOM_BACKGLASS_VIDEO = get_string (config, " CustomMedia" , " BackglassVideo" , " video/backglass.mp4" );
397
+ CUSTOM_DMD_VIDEO = get_string (config, " CustomMedia" , " DmdVideo" , " video/dmd.mp4" );
398
+
399
+ // Assign WindowSettings
400
+ MAIN_WINDOW_MONITOR = get_int (config, " WindowSettings" , " MainMonitor" , 1 );
401
+ MAIN_WINDOW_WIDTH = get_int (config, " WindowSettings" , " MainWidth" , 1080 );
402
+ MAIN_WINDOW_HEIGHT = get_int (config, " WindowSettings" , " MainHeight" , 1920 );
403
+ SECOND_WINDOW_MONITOR = get_int (config, " WindowSettings" , " SecondMonitor" , 0 );
404
+ SECOND_WINDOW_WIDTH = get_int (config, " WindowSettings" , " SecondWidth" , 1024 );
405
+ SECOND_WINDOW_HEIGHT = get_int (config, " WindowSettings" , " SecondHeight" , 1024 );
406
+
407
+ // Assign Font settings
408
+ FONT_PATH = get_string (config, " Font" , " Path" , " /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf" );
409
+ FONT_SIZE = get_int (config, " Font" , " Size" , 28 );
410
+
411
+ // Assign MediaDimensions
412
+ WHEEL_IMAGE_SIZE = get_int (config, " MediaDimensions" , " WheelImageSize" , 300 );
413
+ WHEEL_IMAGE_MARGIN = get_int (config, " MediaDimensions" , " WheelImageMargin" , 24 );
414
+ BACKGLASS_MEDIA_WIDTH = get_int (config, " MediaDimensions" , " BackglassWidth" , 1024 );
415
+ BACKGLASS_MEDIA_HEIGHT = get_int (config, " MediaDimensions" , " BackglassHeight" , 768 );
416
+ DMD_MEDIA_WIDTH = get_int (config, " MediaDimensions" , " DmdWidth" , 1024 );
417
+ DMD_MEDIA_HEIGHT = get_int (config, " MediaDimensions" , " DmdHeight" , 256 );
418
+
419
+ // Set defaults for variables not in config.ini
420
+ DEFAULT_TABLE_IMAGE = " img/default_table.png" ;
421
+ DEFAULT_BACKGLASS_IMAGE = " img/default_backglass.png" ;
422
+ DEFAULT_DMD_IMAGE = " img/default_dmd.png" ;
423
+ DEFAULT_WHEEL_IMAGE = " img/default_wheel.png" ;
424
+ DEFAULT_TABLE_VIDEO = " img/default_table.mp4" ;
425
+ DEFAULT_BACKGLASS_VIDEO = " img/default_backglass.mp4" ;
426
+ DEFAULT_DMD_VIDEO = " img/default_dmd.mp4" ;
427
+ FADE_DURATION_MS = 300 ;
428
+ FADE_TARGET_ALPHA = 128 ;
429
+ TABLE_CHANGE_SOUND = " snd/table_change.mp3" ;
430
+ TABLE_LOAD_SOUND = " snd/table_load.mp3" ;
312
431
313
432
// ------------------ Initialization ------------------
314
433
// ----- SDL init
0 commit comments