1 /** 2 * Copyright © Novelate 2020 3 * License: MIT (https://github.com/Novelate/NovelateEngine/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 * Website: https://novelate.com/ 6 * ------ 7 * Novelate is a free and open-source visual novel engine and framework written in the D programming language. 8 * It can be used freely for both personal and commercial projects. 9 * ------ 10 * Module Description: 11 * This module handles configurations for game compilation, deployment and also default configurations. 12 */ 13 module novelate.scripting.config; 14 15 import std.conv : to; 16 import std.array : split; 17 import std..string : isNumeric; 18 19 /// A value that may contain two different type values. Similar to a union except they're not combined data. 20 struct AltValue(T1,T2) 21 { 22 /// The first value. 23 T1 value1; 24 /// The second value. 25 T2 value2; 26 } 27 28 /// The compiled config for the game. 29 final class NovelateConfig 30 { 31 private: 32 /// The data folder. 33 string _dataFolder; 34 /// The save folder. 35 string _saveFolder; 36 /// The title of the game. 37 string _gameTitle; 38 /// The slogan of the game. 39 string _gameSlogan; 40 /// The description of the game. 41 string _gameDescription; 42 /// The about text of the game. 43 string[] _gameAbout; 44 /// The x coordinate for the menubox under the 800 resolution. 45 AltValue!(ptrdiff_t, string) _menuBox_X800; 46 /// The y coordinate for the menubox under the 800 resolution. 47 AltValue!(ptrdiff_t, string) _menuBox_Y800; 48 /// The x coordinate for the menubox under the 1024 resolution. 49 AltValue!(ptrdiff_t, string) _menuBox_X1024; 50 /// The y coordinate for the menubox under the 1024 resolution. 51 AltValue!(ptrdiff_t, string) _menuBox_Y1024; 52 /// The x coordinate for the menubox under the 1280 resolution. 53 AltValue!(ptrdiff_t, string) _menuBox_X1280; 54 /// The y coordinate for the menubox under the 1280 resolution. 55 AltValue!(ptrdiff_t, string) _menuBox_Y1280; 56 /// The menu text for the menu item: Play 57 NovelateMenuText _menuItem_Play; 58 /// The menu text for the menu item: Load 59 NovelateMenuText _menuItem_Load; 60 /// The menu text for the menu item: Save 61 NovelateMenuText _menuItem_Save; 62 /// The menu text for the menu item: About 63 NovelateMenuText _menuItem_About; 64 /// The menu text for the menu item: Characters 65 NovelateMenuText _menuItem_Characters; 66 /// The menu text for the menu item: Exit 67 NovelateMenuText _menuItem_Exit; 68 69 /// The menu title text. 70 NovelateMenuText _menuTitleText; 71 /// The menu title slogan. 72 NovelateMenuText _menuTitleSlogan; 73 74 /// The menu logo animation/image. 75 NovelateImageAnimation _menuLogoImage; 76 77 /// The x coordinate for the menu logo under the 800 resolution. 78 ptrdiff_t _menuLogoImageX800; 79 /// The y coordinate for the menu logo under the 800 resolution. 80 ptrdiff_t _menuLogoImageY800; 81 /// The x coordinate for the menu logo under the 1024 resolution. 82 ptrdiff_t _menuLogoImageX1024; 83 /// The y coordinate for the menu logo under the 1024 resolution. 84 ptrdiff_t _menuLogoImageY1024; 85 /// The x coordinate for the menu logo under the 1280 resolution. 86 ptrdiff_t _menuLogoImageX1280; 87 /// The y coordinate for the menu logo under the 1280 resolution. 88 ptrdiff_t _menuLogoImageY1280; 89 90 /// The menu music. 91 string _menuMusic; 92 93 /// The menu background animation/image. 94 NovelateImageAnimation _menuBackground; 95 96 /// The default font. 97 string _defaultFont; 98 /// The default font size. 99 uint _defaultFontSize; 100 /// The default dialogue color. 101 string _defaultDialogueColor; 102 /// The default dialogue background color. 103 string _defaultDialogueBackground; 104 /// The default dialogue border color. 105 string _defaultDialogueBorder; 106 /// The default dialogue background image/animation. 107 NovelateImageAnimation _defaultDialogueBackgroundImage; 108 /// The default dialogue padding. 109 size_t _defaultDialoguePadding; 110 /// The default dialogue margin. 111 size_t _defaultDialogueMargin; 112 /// The default dialogue height under the 800 resolution. 113 size_t _defaultDialogueHeight800; 114 /// The default dialogue height under the 1024 resolution. 115 size_t _defaultDialogueHeight1024; 116 /// The default dialogue height under the 1280 resolution. 117 size_t _defaultDialogueHeight1280; 118 /// The default dialogue name font size. 119 size_t _defaultDialogueNameFontSize; 120 /// The default dialogue text font size. 121 size_t _defaultDialogueTextFontSize; 122 /// The default dialogue name font. 123 string _defaultDialogueNameFont; 124 /// The default dialogue text font. 125 string _defaultDialogueTextFont; 126 127 /// The start scene. 128 string _startScene; 129 /// The credits video. 130 string _creditsVideo; 131 132 public: 133 final: 134 this() 135 { 136 _gameAbout = []; 137 138 _menuItem_Play = new NovelateMenuText("Play"); 139 _menuItem_Load = new NovelateMenuText("Load"); 140 _menuItem_Save = new NovelateMenuText("Save"); 141 _menuItem_About = new NovelateMenuText("About"); 142 _menuItem_Characters = new NovelateMenuText("Characters"); 143 _menuItem_Exit = new NovelateMenuText("Exit"); 144 145 _menuTitleText = new NovelateMenuText("Game Title"); 146 _menuTitleSlogan = new NovelateMenuText("Game Slogan"); 147 148 _defaultDialoguePadding = 8; 149 _defaultDialogueMargin = 8; 150 151 _defaultFontSize = 16; 152 } 153 154 @property 155 { 156 /// Gets the data folder. 157 string dataFolder() { return _dataFolder; } 158 /// Gets the save folder. 159 string saveFolder() { return _saveFolder; } 160 /// Gets the game title. 161 string gameTitle() { return _gameTitle; } 162 /// Gets the game slogan. 163 string gameSlogan() { return _gameSlogan; } 164 /// Gets the game description. 165 string gameDescription() { return _gameDescription; } 166 /// Gets the about text of the game. 167 string[] gameAbout() { return _gameAbout; } 168 /// Gets the x coordinate for the menubox under the 800 resolution. 169 AltValue!(ptrdiff_t, string) menuBox_X800() { return _menuBox_X800; } 170 /// Gets the y coordinate for the menubox under the 800 resolution. 171 AltValue!(ptrdiff_t, string) menuBox_Y800() { return _menuBox_Y800; } 172 /// Gets the x coordinate for the menubox under the 1024 resolution. 173 AltValue!(ptrdiff_t, string) menuBox_X1024() { return _menuBox_X1024; } 174 /// Gets the y coordinate for the menubox under the 1024 resolution. 175 AltValue!(ptrdiff_t, string) menuBox_Y1024() { return _menuBox_Y1024; } 176 /// Gets the x coordinate for the menubox under the 1280 resolution. 177 AltValue!(ptrdiff_t, string) menuBox_X1280() { return _menuBox_X1280; } 178 /// Gets the y coordinate for the menubox under the 1280 resolution. 179 AltValue!(ptrdiff_t, string) menuBox_Y1280() { return _menuBox_Y1280; } 180 /// Gets the menu text for the menu item: Play 181 NovelateMenuText menuItem_Play() { return _menuItem_Play; } 182 /// Gets the menu text for the menu item: Load 183 NovelateMenuText menuItem_Load() { return _menuItem_Load; } 184 /// Gets the menu text for the menu item: Save 185 NovelateMenuText menuItem_Save() { return _menuItem_Save; } 186 /// Gets the menu text for the menu item: About 187 NovelateMenuText menuItem_About() { return _menuItem_About; } 188 /// Gets the menu text for the menu item: Characters 189 NovelateMenuText menuItem_Characters() { return _menuItem_Characters; } 190 /// Gets the menu text for the menu item: Exit 191 NovelateMenuText menuItem_Exit() { return _menuItem_Exit; } 192 /// Gets the menu title text. 193 NovelateMenuText menuTitleText() { return _menuTitleText; } 194 /// Gets the menu title slogan. 195 NovelateMenuText menuTitleSlogan() { return _menuTitleSlogan; } 196 /// Gets the menu logo animation/image. 197 NovelateImageAnimation menuLogoImage() { return _menuLogoImage; } 198 /// Gets the x coordinate for the menu logo under the 800 resolution. 199 ptrdiff_t menuLogoImageX800() { return _menuLogoImageX800; } 200 /// Gets the y coordinate for the menu logo under the 800 resolution. 201 ptrdiff_t menuLogoImageY800() { return _menuLogoImageY800; } 202 /// Gets the x coordinate for the menu logo under the 1024 resolution. 203 ptrdiff_t menuLogoImageX1024() { return _menuLogoImageX1024; } 204 /// Gets the y coordinate for the menu logo under the 1024 resolution. 205 ptrdiff_t menuLogoImageY1024() { return _menuLogoImageY1024; } 206 /// Gets the x coordinate for the menu logo under the 1280 resolution. 207 ptrdiff_t menuLogoImageX1280() { return _menuLogoImageX1280; } 208 /// Gets the y coordinate for the menu logo under the 1280 resolution. 209 ptrdiff_t menuLogoImageY1280() { return _menuLogoImageY1280; } 210 /// Gets the menu music. 211 string menuMusic() { return _menuMusic; } 212 /// Gets the menu background animation/image. 213 NovelateImageAnimation menuBackground() { return _menuBackground; } 214 /// Gets the default font. 215 string defaultFont() { return _defaultFont; } 216 /// Gets the default font size. 217 uint defaultFontSize() { return _defaultFontSize; } 218 /// Gets the default dialogue color. 219 string defaultDialogueColor() { return _defaultDialogueColor; } 220 /// Gets the default dialogue background. 221 string defaultDialogueBackground() { return _defaultDialogueBackground; } 222 /// Gets the default dialogue border. 223 string defaultDialogueBorder() { return _defaultDialogueBorder; } 224 /// Gets the default dialogue background image/animation. 225 NovelateImageAnimation defaultDialogueBackgroundImage() { return _defaultDialogueBackgroundImage; } 226 /// Gets the default dialogue padding. 227 size_t defaultDialoguePadding() { return _defaultDialoguePadding; } 228 /// Gets the default dialogue margin. 229 size_t defaultDialogueMargin() { return _defaultDialogueMargin; } 230 /// Gets the default dialogue height under the 800 resolution. 231 size_t defaultDialogueHeight800() { return _defaultDialogueHeight800; } 232 /// Gets the default dialogue height under the 1024 resolution. 233 size_t defaultDialogueHeight1024() { return _defaultDialogueHeight1024; } 234 /// Gets the default dialogue height under the 1280 resolution. 235 size_t defaultDialogueHeight1280() { return _defaultDialogueHeight1280; } 236 /// Gets the default dialogue name font size. 237 size_t defaultDialogueNameFontSize() { return _defaultDialogueNameFontSize; } 238 /// Gets the default dialogue text font size. 239 size_t defaultDialogueTextFontSize() { return _defaultDialogueTextFontSize; } 240 /// Gets the default dialogue name font. 241 string defaultDialogueNameFont() { return _defaultDialogueNameFont; } 242 /// Gets the default dialogue text font. 243 string defaultDialogueTextFont() { return _defaultDialogueTextFont; } 244 /// Gets the start scene. 245 string startScene() { return _startScene; } 246 /// Gets the credits video. 247 string creditsVideo() { return _creditsVideo; } 248 } 249 250 package(novelate): 251 /** 252 * Sets a parsed configuration. Some configurations can be set to multiple values by setting them multiple times. 253 * Params: 254 * name = The name of the configuration to set. 255 * value = The value of the configuration to set. 256 */ 257 void setConfig(string name, string value) 258 { 259 switch (name) 260 { 261 case "DataFolder": _dataFolder = value; break; 262 case "SaveFolder": _saveFolder = value; break; 263 case "GameTitle": _gameTitle = value; break; 264 case "GameSlogan": _gameSlogan = value; break; 265 case "GameDescription": _gameDescription = value; break; 266 case "GameAbout": _gameAbout ~= value; break; 267 case "MenuItem_Play": _menuItem_Play = parseMenuItem(value, _menuItem_Play); break; 268 case "MenuItem_Load": _menuItem_Load = parseMenuItem(value, _menuItem_Load); break; 269 case "MenuItem_Save": _menuItem_Save = parseMenuItem(value, _menuItem_Save); break; 270 case "MenuItem_About": _menuItem_About = parseMenuItem(value, _menuItem_About); break; 271 case "MenuItem_Characters": _menuItem_Characters = parseMenuItem(value, _menuItem_Characters); break; 272 case "MenuItem_Exit": _menuItem_Exit = parseMenuItem(value, _menuItem_Exit); break; 273 case "MenuTitleText": _menuTitleText = parseMenuItem(value, _menuTitleText); break; 274 case "MenuTitleSlogan": _menuTitleSlogan = parseMenuItem(value, _menuTitleSlogan); break; 275 276 case "MenuBoxPosition_800": 277 { 278 auto pos = value.split(","); 279 280 if (pos[0].isNumeric) _menuBox_X800.value1 = to!ptrdiff_t(pos[0]); 281 else _menuBox_X800.value2 = pos[0]; 282 283 if (pos[1].isNumeric) _menuBox_Y800.value1 = to!ptrdiff_t(pos[1]); 284 else _menuBox_Y800.value2 = pos[1]; 285 break; 286 } 287 288 case "MenuBoxPosition_1024": 289 { 290 auto pos = value.split(","); 291 292 if (pos[0].isNumeric) _menuBox_X1024.value1 = to!ptrdiff_t(pos[0]); 293 else _menuBox_X1024.value2 = pos[0]; 294 295 if (pos[1].isNumeric) _menuBox_Y1024.value1 = to!ptrdiff_t(pos[1]); 296 else _menuBox_Y1024.value2 = pos[1]; 297 break; 298 } 299 300 case "MenuBoxPosition_1280": 301 { 302 auto pos = value.split(","); 303 304 if (pos[0].isNumeric) _menuBox_X1280.value1 = to!ptrdiff_t(pos[0]); 305 else _menuBox_X1280.value2 = pos[0]; 306 307 if (pos[1].isNumeric) _menuBox_Y1280.value1 = to!ptrdiff_t(pos[1]); 308 else _menuBox_Y1280.value2 = pos[1]; 309 break; 310 } 311 312 case "MenuLogoImageLocation_800": 313 { 314 auto pos = value.split(","); 315 316 _menuLogoImageX800 = to!ptrdiff_t(pos[0]); 317 _menuLogoImageY800 = to!ptrdiff_t(pos[1]); 318 break; 319 } 320 321 case "MenuLogoImageLocation_1024": 322 { 323 auto pos = value.split(","); 324 325 _menuLogoImageX1024 = to!ptrdiff_t(pos[0]); 326 _menuLogoImageY1024 = to!ptrdiff_t(pos[1]); 327 break; 328 } 329 330 case "MenuLogoImageLocation_1280": 331 { 332 auto pos = value.split(","); 333 334 _menuLogoImageX1280 = to!ptrdiff_t(pos[0]); 335 _menuLogoImageY1280 = to!ptrdiff_t(pos[1]); 336 break; 337 } 338 339 case "MenuMusic": _menuMusic = value; break; 340 341 case "MenuBackground": 342 { 343 if (!_menuBackground) 344 { 345 _menuBackground = new NovelateImageAnimation; 346 } 347 348 parseImageAnimationFrame(_menuBackground, value); 349 break; 350 } 351 352 case "MenuLogoImage": 353 { 354 if (!_menuLogoImage) 355 { 356 _menuLogoImage = new NovelateImageAnimation; 357 } 358 359 parseImageAnimationFrame(_menuLogoImage, value); 360 break; 361 } 362 363 case "DefaultFont": _defaultFont = value; break; 364 case "DefaultFontSize": _defaultFontSize = to!uint(value); break; 365 case "DefaultDialogueColor": _defaultDialogueColor = value; break; 366 case "DefaultDialogueBackground": _defaultDialogueBackground = value; break; 367 case "DefaultDialogueBorder": _defaultDialogueBorder = value; break; 368 case "DefaultDialogueBackgroundImage": 369 { 370 if (!_defaultDialogueBackgroundImage) 371 { 372 _defaultDialogueBackgroundImage = new NovelateImageAnimation; 373 } 374 375 parseImageAnimationFrame(_defaultDialogueBackgroundImage, value); 376 break; 377 } 378 case "DefaultDialoguePadding": _defaultDialoguePadding = to!size_t(value); break; 379 case "DefaultDialogueMargin": _defaultDialogueMargin = to!size_t(value); break; 380 case "DefaultDialogueHeight_800": _defaultDialogueHeight800 = to!size_t(value); break; 381 case "DefaultDialogueHeight_1024": _defaultDialogueHeight1024 = to!size_t(value); break; 382 case "DefaultDialogueHeight_1280": _defaultDialogueHeight1280 = to!size_t(value); break; 383 case "DefaultDialogueNameFontSize": _defaultDialogueNameFontSize = to!size_t(value); break; 384 case "DefaultDialogueTextFontSize": _defaultDialogueTextFontSize = to!size_t(value); break; 385 case "DefaultDialogueNameFont": _defaultDialogueNameFont = value; break; 386 case "DefaultDialogueTextFont": _defaultDialogueTextFont = value; break; 387 388 case "StartScene": _startScene = value; break; 389 case "CreditsVideo": _creditsVideo = value; break; 390 391 default: break; 392 } 393 } 394 } 395 396 /** 397 * Parses an image animation frame configuration. 398 * Params: 399 * animation = The animation object to add the frame to. 400 * value = The value of the frame configuration. 401 */ 402 private void parseImageAnimationFrame(NovelateImageAnimation animation, string value) 403 { 404 auto entryData = value.split("|"); 405 auto image = entryData[0]; 406 auto time = to!size_t(entryData[1]); 407 408 animation.add(new NovelateImageAnimationFrame(image, time)); 409 } 410 411 /** 412 * Parses a menu item configuration. 413 * Params: 414 * value = The value of the menu item configuration. 415 * refItem = The referenced menu item. Usually the old state of the menu item. 416 * Returns: 417 * Returns the parsed menu item configuration. 418 */ 419 private NovelateMenuText parseMenuItem(string value, NovelateMenuText refItem) 420 { 421 auto entryData = value.split("|"); 422 auto text = entryData[0]; 423 auto color = refItem.color; 424 auto font = refItem.font; 425 426 if (entryData.length >= 2) 427 { 428 color = entryData[1]; 429 } 430 431 if (entryData.length >= 3) 432 { 433 font = entryData[2]; 434 } 435 436 return new NovelateMenuText(text, color, font); 437 } 438 439 /// A menu text configuration. 440 final class NovelateMenuText 441 { 442 private: 443 /// The text. 444 string _text; 445 /// The color. 446 string _color; 447 /// The font. 448 string _font; 449 450 public: 451 /** 452 * Creates a new menu item text configuration. 453 * Params: 454 * text = The text. 455 * color = The color. 456 * font = The font. 457 */ 458 this(string text, string color = "255,255,255", string font = null) 459 { 460 _text = text; 461 _color = color; 462 _font = font; 463 } 464 465 @property 466 { 467 /// Gets the text. 468 string text() { return _text; } 469 /// Gets the color. 470 string color() { return _color; } 471 /// Gets the font. 472 string font() { return _font; } 473 } 474 } 475 476 /// An image animation configuration. 477 final class NovelateImageAnimation 478 { 479 private: 480 /// The frames of the image animation. 481 NovelateImageAnimationFrame[] _frames; 482 483 public: 484 /// Creates a new image animation configuration. 485 this() 486 { 487 _frames = []; 488 } 489 490 @property 491 { 492 /// Gets the frames. 493 NovelateImageAnimationFrame[] frames() { return _frames; } 494 } 495 496 /// Clears the frames of the image animation. 497 void clear() 498 { 499 _frames = []; 500 } 501 502 /** 503 * Adds an image animation frame. 504 * Params: 505 * frame = The frame to add. 506 */ 507 void add(NovelateImageAnimationFrame frame) 508 { 509 _frames ~= frame; 510 } 511 } 512 513 /// An image animation frame. 514 final class NovelateImageAnimationFrame 515 { 516 private: 517 /// The image. 518 string _image; 519 /// The next frame time. Generally only the first frame's time is used to be consistent. 520 size_t _nextFrameTime; 521 522 public: 523 final: 524 /** 525 * Creates an image animation frame. 526 * Params: 527 * image = The image of the animation frame. 528 * nextFrameTime = The next frame time. Generally only the first frame's time is used to be consistent. 529 */ 530 this(string image, size_t nextFrameTime) 531 { 532 _image = image; 533 _nextFrameTime = nextFrameTime; 534 } 535 536 @property 537 { 538 /// Gets the image. 539 string image() { return _image; } 540 541 /// Gets the next frame time. Generally only the first frame's time is used to be consistent. 542 size_t nextFrameTime() { return _nextFrameTime; } 543 } 544 } 545 546 /// The configuration. 547 private NovelateConfig _config; 548 549 public: 550 @property 551 { 552 /// Gets the configuration. 553 NovelateConfig config() 554 { 555 if (!_config) 556 { 557 _config = new NovelateConfig(); 558 } 559 560 return _config; 561 } 562 }