1 /*
2 *
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
7 *
8 * See LICENSING which should be included
9 * along with this file for more details
10 *
11 */
12
13 #include "area.h"
14 #include "audio.h"
15 #include "bitmap.h"
16 #include "feio.h"
17 #include "felist.h"
18 #include "game.h"
19 #include "graphics.h"
20 #include "iconf.h"
21 #include "igraph.h"
22 #include "save.h"
23 #include "stack.h"
24 #include "whandler.h"
25 #include "bugworkaround.h"
26 #include "sfx.h"
27
28 stringoption ivanconfig::DefaultName( "DefaultName",
29 "Player's default name",
30 "Pick a character name for all your future games. When left empty, the game will generate a random name if a random name generator pattern is configured, or otherwise ask you to pick a name whenever you start a new game.",
31 "",
32 &configsystem::NormalStringDisplayer,
33 &DefaultNameChangeInterface);
34 stringoption ivanconfig::FantasyNamePattern("FantasyNamePattern",
35 "Random name generator pattern",
36 "Set a pattern for the random fantasy name generator. See MANUAL for further information and pattern examples.", // TODO: this above
37 "!ss !sV",
38 &configsystem::NormalStringDisplayer,
39 &FantasyNameChangeInterface);
40 stringoption ivanconfig::DefaultPetName( "DefaultPetName",
41 "Starting pet's default name",
42 "Choose a name for your puppy.",
43 CONST_S("Kenny"),
44 &configsystem::NormalStringDisplayer,
45 &DefaultPetNameChangeInterface);
46 stringoption ivanconfig::SelectedBkgColor("SelectedBkgColor",
47 "Highlight color of selected entry",
48 "Choose the RGB code of a color used to highlight the selected entry in a menu.",
49 "8,8,8",
50 &configsystem::NormalStringDisplayer,
51 &SelectedBkgColorChangeInterface,
52 &SelectedBkgColorChanger);
53 stringoption ivanconfig::AutoPickUpMatching("AutoPickUpMatching",
54 "Auto pick up regex",
55 "Automatically pick up items according to a regular expression. To disable something, you can invalidate it with '_' without removing it from the expression (eg. '_dagger'). To disable everything at once, begin this config option with '!'. Due to current constraints on length of options, editing is easier to do externally for now.", //TODO if multiline text editing is implemented, remove the last help statement.
56 "!((book|can|dagger|grenade|horn of|kiwi|key|ring|scroll|wand|whistle)|^(?:(?!(broken|empty)).)*(bottle|vial)|sol stone)",
57 &configsystem::NormalStringDisplayer,
58 &AutoPickUpMatchingChangeInterface,
59 &AutoPickUpMatchingChanger);
60 numberoption ivanconfig::AutoSaveInterval("AutoSaveInterval",
61 "Autosave interval",
62 "Automatically backs up your game in case of a crash.",
63 100,
64 &AutoSaveIntervalDisplayer,
65 &AutoSaveIntervalChangeInterface,
66 &AutoSaveIntervalChanger);
67 scrollbaroption ivanconfig::Contrast( "Contrast",
68 "Contrast",
69 "",
70 100,
71 &ContrastDisplayer,
72 &ContrastChangeInterface,
73 &ContrastChanger,
74 &ContrastHandler);
75 cycleoption ivanconfig::HitIndicator( "HitIndicator",
76 "Show successful hit",
77 "",
78 0, 5,
79 &HitIndicatorDisplayer);
80 cycleoption ivanconfig::HoldPosMaxDist( "HoldPosMaxDist",
81 "Pets stay put when not following",
82 "If pets are set not to follow the player, they will move around from their spot no further than the maximum specified distance. If a pet set to be following loses track of the player, it will stay near the last position where it was still able to follow the player.",
83 0, 7,
84 &HoldPosMaxDistDisplayer);
85 cycleoption ivanconfig::ShowItemsAtPlayerSquare("ShowItemsAtPlayerSquare",
86 "Show items at player's square",
87 "",
88 0, 12,
89 &ShowItemsAtPlayerSquareDisplayer,
90 &configsystem::NormalCycleChangeInterface,
91 &ShowItemsAtPlayerSquareChanger);
92 cycleoption ivanconfig::ShowMap( "ShowMap",
93 "Map preferences",
94 "",
95 0, 5,
96 &ShowMapDisplayer);
97 cycleoption ivanconfig::RotateTimesPerSquare("RotateTimesPerSquare",
98 "Thrown weapons rotate",
99 "Select how many times per square should the animation rotate a thrown weapon.",
100 0, 6,
101 &RotateTimesPerSquareDisplayer);
102 numberoption ivanconfig::WindowWidth( "WindowWidth",
103 "* Window width in pixels",
104 "Choose the width of the game window, with a minimum of 640 pixels. Requires restarting the game to take effect.",
105 800, //default will be vanilla, but mininum still can be 640
106 &WindowWidthDisplayer,
107 &WindowWidthChangeInterface,
108 &WindowWidthChanger);
109 numberoption ivanconfig::WindowHeight( "WindowHeight",
110 "* Window height in pixels",
111 "Choose the height of the game window, with a minimum of 480 pixels. Requires restarting the game to take effect.",
112 600, //default will be vanilla, but mininum still can be 480
113 &WindowHeightDisplayer,
114 &WindowHeightChangeInterface,
115 &WindowHeightChanger);
116 numberoption ivanconfig::StackListPageLength("StackListPageLength",
117 "Page length in entries for non-selectable menus",
118 "Choose how many entries will be displayed per page for non-selectable menus, such as when viewing your inventory. Note that selecting too many entries for the height of your screen may result in the menu being drawn partially off-screen.",
119 stack::GetDefaultPageLength(),
120 &StackListPageLengthDisplayer,
121 &StackListPageLengthChangeInterface,
122 &StackListPageLengthChanger);
123 cycleoption ivanconfig::GoOnStopMode( "GoOnStopMode",
124 "Fastwalk stop mode",
125 "",
126 0, 4,
127 &GoOnStopModeDisplayer);
128 numberoption ivanconfig::FrameSkip( "FrameSkip",
129 "Frame skip (assures responsiveness)",
130 "",
131 0,
132 &FrameSkipDisplayer,
133 &FrameSkipChangeInterface,
134 &FrameSkipChanger);
135 truthoption ivanconfig::AllowMouseOnFelist("AllowMouseOnFelist",
136 "Enable mouse cursor on lists",
137 "",
138 false,
139 &configsystem::NormalTruthDisplayer,
140 &configsystem::NormalTruthChangeInterface,
141 &AllowMouseOnFelistChanger);
142 truthoption ivanconfig::ShowMapAtDetectMaterial("ShowMapAtDetectMaterial",
143 "Show map while detecting material",
144 "",
145 false);
146 truthoption ivanconfig::AutoPickupThrownItems("AutoPickupThrownItems",
147 "Auto pick up thrown weapons",
148 "Automatically annotate any thrown weapon and pick it up without loosing a turn when you step on its square.",
149 true);
150 truthoption ivanconfig::TransparentMapLM( "TransparentMapLM",
151 "Show transparent map in look mode",
152 "Show transparent map of the whole level when in look mode.",
153 true);
154 truthoption ivanconfig::AllowImportOldSavegame("AllowImportOldSavegame",
155 "Import old savegames (v131 up, experimental)",
156 "",
157 false);
158 truthoption ivanconfig::WaitNeutralsMoveAway("WaitNeutralsMoveAway",
159 "Wait until neutral NPCs move from your path",
160 "When you try to move in a direction that is blocked by a neutral NPC, skip turns until the path is clear. Will not skip turns if the NPC doesn't move from their square, or if there are hostiles nearby.",
161 false);
162 truthoption ivanconfig::AllWeightIsRelevant("AllWeightIsRelevant",
163 "Only pile items with equal weight on lists", //clutter are useful now for crafting so their weight matters...
164 "",
165 false);
166 truthoption ivanconfig::ShowVolume( "ShowVolume",
167 "Show item volume in cm3",
168 "",
169 false);
170 truthoption ivanconfig::EnhancedLights( "EnhancedLights",
171 "Allow distant lights to be seen",
172 "",
173 true);
174 truthoption ivanconfig::HideWeirdHitAnimationsThatLookLikeMiss("HideWeirdHitAnimationsThatLookLikeMiss",
175 "Hide hit animations that look like miss",
176 "",
177 true);
178 truthoption ivanconfig::UseLightEmiterBasedOnVolume("UseLightEmiterBasedOnVolume",
179 "Small light sources emit less light",
180 "This experimental feature still has bugs that happen when splitting rocks etc. Most are fixed after restarting the game.",
181 false);
182 truthoption ivanconfig::ShowFullDungeonName("ShowFullDungeonName",
183 "Show full name of current dungeon",
184 "",
185 false);
186 truthoption ivanconfig::ShowGodInfo( "ShowGodInfo",
187 "Show extra info about gods when praying",
188 "Remember the last response to a prayer for each god.",
189 false);
190 truthoption ivanconfig::CenterOnPlayerAfterLook("CenterOnPlayerAfterLook",
191 "Center camera on player after exiting look mode",
192 "Always center the displayed region of the dungeon back on player after exiting look mode.",
193 false);
194 truthoption ivanconfig::WarnAboutDanger( "WarnAboutVeryDangerousMonsters",
195 "Warn about very dangerous monsters",
196 "Display a warning prompt when you encounter an unusually dangerous monster.",
197 true);
198 truthoption ivanconfig::AutoDropLeftOvers("AutoDropLeftOvers",
199 "Drop food leftovers automatically",
200 "",
201 true);
202 truthoption ivanconfig::LookZoom( "LookZoom",
203 "Zoom in look mode",
204 "",
205 false);
206 truthoption ivanconfig::AltAdentureInfo( "AltAdentureInfo",
207 "Enhanced message review mode after death",
208 "",
209 false);
210 truthoption ivanconfig::DescriptiveHP( "DescriptiveHP",
211 "Use health level descriptions",
212 "Display description of your relative health rather than numeric value of your hit points.",
213 false);
214 truthoption ivanconfig::StartWithNoPet( "StartWithNoPet",
215 "Start with no pet",
216 "Do not start the game with a puppy.",
217 false);
218 cycleoption ivanconfig::MemorizeEquipmentMode("MemorizeEquipmentMode",
219 "NPCs restore equipped items after polymorph",
220 "",
221 2, 3,
222 &MemorizeEquipmentModeDisplayer);
223 truthoption ivanconfig::XBRZScale( "XBRZScale",
224 "Use xBRZScale to stretch graphics",
225 "",
226 false,
227 &configsystem::NormalTruthDisplayer,
228 &configsystem::NormalTruthChangeInterface,
229 &XBRZScaleChanger);
230 numberoption ivanconfig::XBRZSquaresAroundPlayer("XBRZSquaresAroundPlayer",
231 "Stretch squares around player with xBRZ",
232 "",
233 3,
234 &XBRZSquaresAroundPlayerDisplayer,
235 &XBRZSquaresAroundPlayerChangeInterface,
236 &XBRZSquaresAroundPlayerChanger);
237 cycleoption ivanconfig::DungeonGfxScale( "DungeonGfxScale",
238 "* Select graphics scaling factor",
239 "",
240 1, 6, //from 1 to 6 (max xbrz) where 1 is no scale
241 &DungeonGfxScaleDisplayer,
242 &DungeonGfxScaleChangeInterface,
243 &DungeonGfxScaleChanger);
244 cycleoption ivanconfig::FontGfx( "FontGfx",
245 "* Select font",
246 "Select your favorite from the available fonts.",
247 1, 3, //from 1 to 3 (three options available)
248 &FontGfxDisplayer,
249 &FontGfxChangeInterface,
250 &FontGfxChanger);
251 cycleoption ivanconfig::DistLimitMagicMushrooms("DistLimitMagicMushrooms",
252 "Breeders' active range",
253 "Select the maximum distance where breeding monsters will spawn more of their own. This option can be used to prevent lag from high number of creatures on slow computers, but may impact the intended game balance negatively.",
254 0, 5,
255 &DistLimitMagicMushroomsDisplayer);
256 cycleoption ivanconfig::SaveGameSortMode( "SaveGameSortMode",
257 "Sort savegame files by dungeon IDs",
258 "Savegame selection menu will be sorted according to the chosen criterion.",
259 0, 4,
260 &SaveGameSortModeDisplayer,
261 &configsystem::NormalCycleChangeInterface,
262 &SaveGameSortModeChanger);
263 cycleoption ivanconfig::SilhouetteScale( "SilhouetteScale",
264 "Silhouette scaling factor",
265 "Select scaling factor for silhouette, 1x to disable (no scaling).",
266 1, 6, //from 1 to 6 (max xbrz) where 1 is no scale
267 &SilhouetteScaleDisplayer,
268 &SilhouetteScaleChangeInterface,
269 &SilhouetteScaleChanger);
270 cycleoption ivanconfig::AltSilhouette( "AltSilhouette",
271 "Alternative silhouette mode",
272 "",
273 0, 7,
274 &AltSilhouetteDisplayer);
275 cycleoption ivanconfig::AltSilhouettePreventColorGlitch("AltSilhouettePreventColorGlitch",
276 "Alternative silhouette background",
277 "",
278 2, 3,
279 &AltSilhouettePreventColorGlitchDisplayer);
280 cycleoption ivanconfig::DirectionKeyMap( "DirectionKeyMap",
281 "Movement control scheme",
282 "Select a pre-defined keybinding scheme for the movement of your character. Normal scheme uses NumPad, or arrow keys along with Home, End, PgUp and PgDn for diagonal directions. Alternative scheme is better suited for laptops and uses number and letter keys on the main keyboard. NetHack scheme uses vi keys. After you select a movement control scheme, you may also check the in game keybindings help to see the currently active movement keys. Any other command keys may be auto changed also to not conflict with this movement keys choice.",
283 DIR_NORM, 3, // {default value, number of options to cycle through}
284 &DirectionKeyMapDisplayer);
285 truthoption ivanconfig::SetupCustomKeys( "SetupCustomKeys",
286 "Custom command and movement", //TODO all keys one day, and let it work on main menu
287 "Lets you assign any command to any key binding of your preference. The default keys here will be from the control scheme option above. Only changed keybindings will be saved at the new config file. This global configuration won't work at main menu, load/start some game.",
288 false,
289 &configsystem::NormalTruthDisplayer,
290 &configsystem::NormalTruthChangeInterface,
291 &SetupCustomKeysChanger);
292 truthoption ivanconfig::SmartOpenCloseApply("SmartOpenCloseApply",
293 "Smart open/close/apply behavior",
294 "Automatically try to open doors when you walk into them, and don't ask for the target of close/apply actions when only one viable target is present.",
295 true);
296 truthoption ivanconfig::BeNice( "BeNice",
297 "Be nice to pets",
298 "Don't let your sadistic tendencies hurt your pets.",
299 true);
300 cycleoption ivanconfig::AltListItemPos( "AltListItemPos",
301 "Use alternative position of stretched lists",
302 "",
303 0, 3,
304 &AltListItemPosDisplayer);
305 numberoption ivanconfig::AltListItemWidth("AltListItemWidth",
306 "List width for alternative stretched lists",
307 "",
308 game::getDefaultItemsListWidth(),
309 &AltListItemWidthDisplayer,
310 &AltListItemWidthChangeInterface,
311 &AltListItemWidthChanger);
312 scrollbaroption ivanconfig::Volume( "Volume",
313 "Music Volume",
314 "Select volume for game MIDI music",
315 127,
316 &VolumeDisplayer,
317 &VolumeChangeInterface,
318 &VolumeChanger,
319 &VolumeHandler);
320 scrollbaroption ivanconfig::SfxVolume( "SfxVolume",
321 "Soud Effects (SFX) Volume",
322 "Select volume for sound effects",
323 127,
324 &SfxVolumeDisplayer,
325 &SfxVolumeChangeInterface,
326 &SfxVolumeChanger,
327 &SfxVolumeHandler);
328
329 cycleoption ivanconfig::MIDIOutputDevice( "MIDIOutputDevice",
330 "Use MIDI soundtrack",
331 "Select an output device for the game music, or disable soundtrack.",
332 0, 0, // {default value, number of options to cycle through}
333 &MIDIOutputDeviceDisplayer);
334 cycleoption ivanconfig::LandTypeConfig("LandTypeConfig",
335 "What land shapes to generate",
336 "Choose whether to generate continents or pangea. If Pangea is selected, the generator will make all locations reachable from the same landmass.",
337 0, 2,
338 &LandTypeConfigDisplayer);
339 cycleoption ivanconfig::WorldSizeConfig("WorldSizeConfig",
340 "Size of the world map",
341 "Select a world size.",
342 2, 7,
343 &WorldSizeConfigDisplayer);
344 cycleoption ivanconfig::WorldShapeConfig("WorldShapeConfig",
345 "Shape of the world",
346 "This affects the player's movement around the world. Pancake worlds are flat, and the player cannot cross the edges of the world map. Brandy snap worlds are like a cylinder, the world map wraps around the horizontal axis. Doughnut worlds are shaped like a torus, the player can wrap around the horizontal and vertical axes.",
347 0, 3,
348 &WorldShapeConfigDisplayer);
349 numberoption ivanconfig::WorldSeedConfig("WorldSeedConfig",
350 "Select a world seed",
351 "0 gives a random world seed, else select a new one at your own risk. If a world cannot be generated with the given seed after a finite number of attempts, you will get a message saying the world generator encountered a bad seed, what that seed was, and a new world will be generated from a random seed instead of the one specified here.",
352 0,
353 &WorldSeedConfigDisplayer,
354 &WorldSeedConfigChangeInterface,
355 &WorldSeedConfigChanger);
356
357 #ifndef __DJGPP__
358 cycleoption ivanconfig::GraphicsScale( "GraphicsScale",
359 "Select window scaling factor",
360 "",
361 1, 2,
362 &GraphicsScaleDisplayer,
363 &GraphicsScaleChangeInterface,
364 &GraphicsScaleChanger);
365 truthoption ivanconfig::FullScreenMode( "FullScreenMode",
366 "Full screen mode",
367 "Display the game in full screen mode.",
368 false,
369 &configsystem::NormalTruthDisplayer,
370 &configsystem::NormalTruthChangeInterface,
371 &FullScreenModeChanger);
372 cycleoption ivanconfig::ScalingQuality( "ScalingQuality",
373 "* Scaling quality",
374 "",
375 0, 2,
376 &ScalingQualityDisplayer);
377 truthoption ivanconfig::UseExtraMenuGraphics("UseExtraMenuGraphics",
378 "Use extra main menu graphics",
379 "Add changing graphics and sounds to the main menu.",
380 false,
381 &configsystem::NormalTruthDisplayer,
382 &configsystem::NormalTruthChangeInterface,
383 &UseExtraMenuGraphicsChanger);
384 #endif
385 col24 ivanconfig::ContrastLuminance = NORMAL_LUMINANCE;
386 truthoption ivanconfig::PlaySounds( "PlaySounds",
387 "Use sound effects",
388 "Use sound effects for combat, explosions and more.",
389 true);
390 truthoption ivanconfig::ShowTurn( "ShowTurn",
391 "Show game turn on message log",
392 "Add a game turn number to each action described in the message log.",
393 false);
394 truthoption ivanconfig::OutlinedGfx( "OutlinedGfx",
395 "* Use outlined graphics",
396 "The game graphics will be outlined in black for better differentiation.",
397 false);
398
GetQuestionPos()399 v2 ivanconfig::GetQuestionPos() { return game::IsRunning() ? v2(16, 6) : v2(30, 30); }
BackGroundDrawer()400 void ivanconfig::BackGroundDrawer() { game::DrawEverythingNoBlit(); }
401
XBRZSquaresAroundPlayerDisplayer(const numberoption * O,festring & Entry)402 void ivanconfig::XBRZSquaresAroundPlayerDisplayer(const numberoption* O, festring& Entry)
403 {
404 Entry << O->Value << " squares";
405 }
406
AltListItemWidthDisplayer(const numberoption * O,festring & Entry)407 void ivanconfig::AltListItemWidthDisplayer(const numberoption* O, festring& Entry)
408 {
409 Entry << O->Value << " pixels";
410 }
411
FrameSkipDisplayer(const numberoption * O,festring & Entry)412 void ivanconfig::FrameSkipDisplayer(const numberoption* O, festring& Entry)
413 {
414 Entry << O->Value;
415 if(O->Value==-2)Entry << " = wait" ;
416 if(O->Value==-1)Entry << " = auto" ;
417 if(O->Value>= 0)Entry << " frames";
418 }
419
DistLimitMagicMushroomsDisplayer(const cycleoption * O,festring & Entry)420 void ivanconfig::DistLimitMagicMushroomsDisplayer(const cycleoption* O, festring& Entry)
421 {
422 if(O->Value == 0)
423 Entry << "everywhere";
424 else if(O->Value == 1)
425 Entry << "close";
426 else if(O->Value == 2)
427 Entry << "near";
428 else if(O->Value == 3)
429 Entry << "medium";
430 else if(O->Value == 4)
431 Entry << "far";
432 else
433 Entry << O->Value;
434 }
435
StackListPageLengthDisplayer(const numberoption * O,festring & Entry)436 void ivanconfig::StackListPageLengthDisplayer(const numberoption* O, festring& Entry)
437 {
438 Entry << O->Value << " entries";
439 }
440
WindowHeightDisplayer(const numberoption * O,festring & Entry)441 void ivanconfig::WindowHeightDisplayer(const numberoption* O, festring& Entry)
442 {
443 Entry << O->Value << " pixels";
444 }
445
AltSilhouettePreventColorGlitchDisplayer(const cycleoption * O,festring & Entry)446 void ivanconfig::AltSilhouettePreventColorGlitchDisplayer(const cycleoption* O, festring& Entry)
447 {
448 switch(O->Value){
449 case 0: Entry << "transparent";break;
450 case 1: Entry << "dark";break;
451 case 2: Entry << "alignment";break;
452 }
453 }
454
RotateTimesPerSquareDisplayer(const cycleoption * O,festring & Entry)455 void ivanconfig::RotateTimesPerSquareDisplayer(const cycleoption* O, festring& Entry)
456 {
457 switch(O->Value){
458 case 0: Entry << "disabled";break;
459 case 1: Entry << "x1";break;
460 case 2: Entry << "x2";break;
461 case 3: Entry << "x3";break;
462 case 4: Entry << "x4";break;
463 case 5: Entry << "dynamic";break;
464 }
465 }
466
HoldPosMaxDistDisplayer(const cycleoption * O,festring & Entry)467 void ivanconfig::HoldPosMaxDistDisplayer(const cycleoption* O, festring& Entry)
468 {
469 if(O->Value>0)
470 Entry << O->Value << " squares";
471 else
472 Entry << "disabled";
473 }
474
HitIndicatorDisplayer(const cycleoption * O,festring & Entry)475 void ivanconfig::HitIndicatorDisplayer(const cycleoption* O, festring& Entry)
476 {
477 switch(O->Value){
478 case 0: Entry << "disabled";break;
479 case 1: Entry << "immersive";break;
480 case 2: Entry << "indicator";break;
481 case 3: Entry << "indicator + color";break;
482 case 4: Entry << "dynamic";break;
483 }
484 }
485
GoOnStopModeDisplayer(const cycleoption * O,festring & Entry)486 void ivanconfig::GoOnStopModeDisplayer(const cycleoption* O, festring& Entry)
487 {
488 switch(O->Value){
489 case 0:Entry << "everything";break;
490 case 1:Entry << "ignore useless";break;
491 case 2:Entry << "ignore cheap";break;
492 case 3:Entry << "ignore encumbering";break;
493 }
494 }
495
ShowMapDisplayer(const cycleoption * O,festring & Entry)496 void ivanconfig::ShowMapDisplayer(const cycleoption* O, festring& Entry)
497 {
498 switch(O->Value){
499 case 0:Entry << "vanilla";break; //mmm... just not using xBRZ
500 case 1:Entry << "xBRZ";break;
501 case 2:Entry << "immersive 1";break;
502 case 3:Entry << "immersive 2";break;
503 case 4:Entry << "immersive 3";break;
504 }
505 }
506
ShowItemsAtPlayerSquareDisplayer(const cycleoption * O,festring & Entry)507 void ivanconfig::ShowItemsAtPlayerSquareDisplayer(const cycleoption* O, festring& Entry)
508 {
509 if(O->Value>=10){
510 Entry << "Use corners if NPC";
511 if(O->Value==11)Entry << "+Items";
512 Entry << " above";
513 return;
514 }
515
516 int iCode = game::ItemUnderCode(O->Value);
517
518 if(iCode==0){
519 Entry << "disabled";
520 }else
521 if(iCode==1){
522 Entry << "above head";
523 }else{
524 switch(game::ItemUnderCorner(iCode)){
525 case 0:Entry << "upper left";break;
526 case 1:Entry << "upper right";break;
527 case 2:Entry << "lower left";break;
528 case 3:Entry << "lower right";break;
529 }
530
531 // Entry << ",";
532 // Entry << "x" << game::ItemUnderZoom(O->Value);
533
534 Entry << ", ";
535 Entry << (game::ItemUnderHV(iCode) ? "horizontal" : "vertical");
536 }
537 }
538
WindowWidthDisplayer(const numberoption * O,festring & Entry)539 void ivanconfig::WindowWidthDisplayer(const numberoption* O, festring& Entry)
540 {
541 Entry << O->Value << " pixels";
542 }
543
AutoSaveIntervalDisplayer(const numberoption * O,festring & Entry)544 void ivanconfig::AutoSaveIntervalDisplayer(const numberoption* O, festring& Entry)
545 {
546 if(O->Value)
547 {
548 Entry << O->Value << " turn";
549
550 if(O->Value != 1)
551 Entry << 's';
552 }
553 else
554 Entry << "disabled";
555 }
556
ContrastDisplayer(const numberoption * O,festring & Entry)557 void ivanconfig::ContrastDisplayer(const numberoption* O, festring& Entry)
558 {
559 Entry << O->Value << "/100";
560 }
561
VolumeDisplayer(const numberoption * O,festring & Entry)562 void ivanconfig::VolumeDisplayer(const numberoption* O, festring& Entry)
563 {
564 Entry << O->Value << "/127";
565 }
SfxVolumeDisplayer(const numberoption * O,festring & Entry)566 void ivanconfig::SfxVolumeDisplayer(const numberoption* O, festring& Entry)
567 {
568 Entry << O->Value << "/127";
569 }
570
AltSilhouetteDisplayer(const cycleoption * O,festring & Entry)571 void ivanconfig::AltSilhouetteDisplayer(const cycleoption* O, festring& Entry)
572 {
573 switch(O->Value){
574 case 0: Entry << "no" ; break;
575 case 1: Entry << "short" ; break;
576 case 2: Entry << "tall" ; break;
577 case 3: Entry << "breathing" ; break;
578 case 4: Entry << "breathSlower"; break;
579 case 5: Entry << "breathSlower+"; break;
580 case 6: Entry << "breathSlower++"; break;
581 }
582 }
583
DirectionKeyMapDisplayer(const cycleoption * O,festring & Entry)584 void ivanconfig::DirectionKeyMapDisplayer(const cycleoption* O, festring& Entry)
585 {
586 switch(O->Value)
587 {
588 case DIR_NORM:
589 Entry << CONST_S("Normal");
590 break;
591 case DIR_ALT:
592 Entry << CONST_S("Alternative");
593 break;
594 case DIR_HACK:
595 Entry << CONST_S("NetHack");
596 break;
597 }
598 }
599
MIDIOutputDeviceDisplayer(const cycleoption * O,festring & Entry)600 void ivanconfig::MIDIOutputDeviceDisplayer(const cycleoption* O, festring& Entry)
601 {
602 std::vector<std::string> devicenames;
603 int NumDevices = audio::GetMIDIOutputDevices(devicenames);
604 MIDIOutputDevice.CycleCount = NumDevices+1;
605
606 if(O->Value && O->Value <= devicenames.size())
607 {
608 const char *cstr = devicenames[O->Value - 1].c_str();
609 Entry << cstr;
610
611 audio::ChangeMIDIOutputDevice(O->Value);
612 VolumeChanger(&Volume, GetVolume());
613 }
614 else
615 {
616 audio::ChangeMIDIOutputDevice(0);
617 Entry << CONST_S("no");
618 }
619 }
620
clearToBackgroundAfterChangeInterface()621 void clearToBackgroundAfterChangeInterface(){
622 if(game::IsRunning())
623 igraph::BlitBackGround(
624 v2(16,6),
625 v2(game::GetMaxScreenXSize() << 4, 23)
626 );
627 }
628
GraphicsScaleChangeInterface(cycleoption * O)629 truth ivanconfig::GraphicsScaleChangeInterface(cycleoption* O)
630 {
631 O->ChangeValue(O->Value % O->CycleCount + 1);
632 clearToBackgroundAfterChangeInterface();
633 return true;
634 }
635
SilhouetteScaleChangeInterface(cycleoption * O)636 truth ivanconfig::SilhouetteScaleChangeInterface(cycleoption* O)
637 {
638 O->ChangeValue(O->Value % O->CycleCount + 1);
639 clearToBackgroundAfterChangeInterface();
640 return true;
641 }
642
DungeonGfxScaleChangeInterface(cycleoption * O)643 truth ivanconfig::DungeonGfxScaleChangeInterface(cycleoption* O)
644 {
645 O->ChangeValue(O->Value % O->CycleCount + 1);
646 clearToBackgroundAfterChangeInterface();
647 return true;
648 }
649
FontGfxChangeInterface(cycleoption * O)650 truth ivanconfig::FontGfxChangeInterface(cycleoption* O)
651 {
652 O->ChangeValue(O->Value % O->CycleCount + 1);
653 clearToBackgroundAfterChangeInterface();
654 return true;
655 }
656
657
FantasyNameChangeInterface(stringoption * O)658 truth ivanconfig::FantasyNameChangeInterface(stringoption* O)
659 {
660 festring String;
661 if(O)String<<O->Value;
662
663 if(iosystem::StringQuestion(String, CONST_S("Set name generator pattern (recommended \"!ss !sV\"):"),
664 GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
665 O->ChangeValue(String);
666
667 clearToBackgroundAfterChangeInterface();
668
669 return false;
670 }
671
DefaultNameChangeInterface(stringoption * O)672 truth ivanconfig::DefaultNameChangeInterface(stringoption* O)
673 {
674 festring String;
675 if(O)String<<O->Value;
676
677 if(iosystem::StringQuestion(String, CONST_S("Set new default name (1-20 letters):"),
678 GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
679 O->ChangeValue(String);
680
681 clearToBackgroundAfterChangeInterface();
682
683 return false;
684 }
685
SelectedBkgColorChangeInterface(stringoption * O)686 truth ivanconfig::SelectedBkgColorChangeInterface(stringoption* O)
687 {
688 festring String;
689 if(O)String<<O->Value;
690
691 if(iosystem::StringQuestion(String, CONST_S("Set new RGB color (8 to 200 for each value, default \"8,8,8\"), or leave empty to disable:"),
692 GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
693 O->ChangeValue(String);
694
695 clearToBackgroundAfterChangeInterface();
696
697 return false;
698 }
699
AutoPickUpMatchingChangeInterface(stringoption * O)700 truth ivanconfig::AutoPickUpMatchingChangeInterface(stringoption* O)
701 {
702 festring String;
703 if(O)String<<O->Value;
704
705 if(iosystem::StringQuestion(String, CONST_S("What items do you want to automatically pick up?"),
706 GetQuestionPos(), WHITE, 0, 200, !game::IsRunning(), true) == NORMAL_EXIT) //TODO should have no limit? but crashes if going beyond screen limit...
707 O->ChangeValue(String);
708
709 clearToBackgroundAfterChangeInterface();
710
711 return false;
712 }
713
DefaultPetNameChangeInterface(stringoption * O)714 truth ivanconfig::DefaultPetNameChangeInterface(stringoption* O)
715 {
716 festring String;
717 if(O)String<<O->Value;
718
719 if(iosystem::StringQuestion(String, CONST_S("Set new default name for the starting pet (1-20 letters):"),
720 GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
721 O->ChangeValue(String);
722
723 clearToBackgroundAfterChangeInterface();
724
725 return false;
726 }
727
XBRZSquaresAroundPlayerChangeInterface(numberoption * O)728 truth ivanconfig::XBRZSquaresAroundPlayerChangeInterface(numberoption* O)
729 {
730 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set how many squares around player to use xBRZ at (0 for whole dungeon):"),
731 GetQuestionPos(), WHITE, !game::IsRunning()));
732 clearToBackgroundAfterChangeInterface();
733 return false;
734 }
735
AltListItemWidthChangeInterface(numberoption * O)736 truth ivanconfig::AltListItemWidthChangeInterface(numberoption* O)
737 {
738 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new item list width:"),
739 GetQuestionPos(), WHITE, !game::IsRunning()));
740 clearToBackgroundAfterChangeInterface();
741 return false;
742 }
743
FrameSkipChangeInterface(numberoption * O)744 truth ivanconfig::FrameSkipChangeInterface(numberoption* O)
745 {
746 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set frame skip (-2 = wait, -1 = auto, or 0 to 100):"),
747 GetQuestionPos(), WHITE, !game::IsRunning()));
748 clearToBackgroundAfterChangeInterface();
749 return false;
750 }
751
StackListPageLengthChangeInterface(numberoption * O)752 truth ivanconfig::StackListPageLengthChangeInterface(numberoption* O)
753 {
754 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new length of list pages (in entries):"),
755 GetQuestionPos(), WHITE, !game::IsRunning()));
756 clearToBackgroundAfterChangeInterface();
757 return false;
758 }
759
WindowHeightChangeInterface(numberoption * O)760 truth ivanconfig::WindowHeightChangeInterface(numberoption* O)
761 {
762 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new window height (from 480 to your monitor screen max height):"),
763 GetQuestionPos(), WHITE, !game::IsRunning()));
764 clearToBackgroundAfterChangeInterface();
765 return false;
766 }
767
WindowWidthChangeInterface(numberoption * O)768 truth ivanconfig::WindowWidthChangeInterface(numberoption* O)
769 {
770 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new window width (from 640 to your monitor screen max width):"),
771 GetQuestionPos(), WHITE, !game::IsRunning()));
772 clearToBackgroundAfterChangeInterface();
773 return false;
774 }
775
AutoSaveIntervalChangeInterface(numberoption * O)776 truth ivanconfig::AutoSaveIntervalChangeInterface(numberoption* O)
777 {
778 O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new autosave interval (1-50000 turns, 0 for never):"),
779 GetQuestionPos(), WHITE, !game::IsRunning()));
780
781 clearToBackgroundAfterChangeInterface();
782
783 return false;
784 }
785
ContrastChangeInterface(numberoption * O)786 truth ivanconfig::ContrastChangeInterface(numberoption* O)
787 {
788 iosystem::ScrollBarQuestion(CONST_S("Set new contrast value (0-200, '<' and '>' move the slider):"),
789 GetQuestionPos(), O->Value, 5, 0, 200, O->Value, WHITE, LIGHT_GRAY, DARK_GRAY,
790 game::GetMoveCommandKey(KEY_LEFT_INDEX), game::GetMoveCommandKey(KEY_RIGHT_INDEX),
791 !game::IsRunning(), static_cast<scrollbaroption*>(O)->BarHandler);
792
793 clearToBackgroundAfterChangeInterface();
794
795 return false;
796 }
797
VolumeChangeInterface(numberoption * O)798 truth ivanconfig::VolumeChangeInterface(numberoption* O)
799 {
800 iosystem::ScrollBarQuestion(CONST_S("Set new volume value (0-127, '<' and '>' move the slider):"),
801 GetQuestionPos(), O->Value, 5, 0, 127, O->Value, WHITE, LIGHT_GRAY, DARK_GRAY,
802 game::GetMoveCommandKey(KEY_LEFT_INDEX), game::GetMoveCommandKey(KEY_RIGHT_INDEX),
803 !game::IsRunning(), static_cast<scrollbaroption*>(O)->BarHandler);
804
805 clearToBackgroundAfterChangeInterface();
806
807 return false;
808 }
SfxVolumeChangeInterface(numberoption * O)809 truth ivanconfig::SfxVolumeChangeInterface(numberoption* O)
810 {
811 iosystem::ScrollBarQuestion(CONST_S("Set new SFX volume value (0-127, '<' and '>' move the slider):"),
812 GetQuestionPos(), O->Value, 5, 0, 127, O->Value, WHITE, LIGHT_GRAY, DARK_GRAY,
813 game::GetMoveCommandKey(KEY_LEFT_INDEX), game::GetMoveCommandKey(KEY_RIGHT_INDEX),
814 !game::IsRunning(), static_cast<scrollbaroption*>(O)->BarHandler);
815
816 clearToBackgroundAfterChangeInterface();
817
818 return false;
819 }
820
XBRZSquaresAroundPlayerChanger(numberoption * O,long What)821 void ivanconfig::XBRZSquaresAroundPlayerChanger(numberoption* O, long What)
822 {
823 if(What < 0) What = 0;
824 O->Value = What;
825 }
826
AltListItemWidthChanger(numberoption * O,long What)827 void ivanconfig::AltListItemWidthChanger(numberoption* O, long What)
828 {
829 if(What < 400) What = 400; //TODO find the best quality minimum value
830 O->Value = What;
831 }
832
FrameSkipChanger(numberoption * O,long What)833 void ivanconfig::FrameSkipChanger(numberoption* O, long What)
834 {
835 if(What < -2) What = -2;
836 if(What > 100) What = 100;
837
838 if(O!=NULL)O->Value = What;
839
840 globalwindowhandler::SetAddFrameSkip(What);
841 }
842
StackListPageLengthChanger(numberoption * O,long What)843 void ivanconfig::StackListPageLengthChanger(numberoption* O, long What)
844 {
845 if(What < stack::GetDefaultPageLength()) What = stack::GetDefaultPageLength();
846 if(O!=NULL)O->Value = What;
847
848 stack::SetStandardPageLength(What);
849 }
850
WindowHeightChanger(numberoption * O,long What)851 void ivanconfig::WindowHeightChanger(numberoption* O, long What)
852 {
853 if(What < 480) What = 480;
854 O->Value = What;
855 }
856
ShowItemsAtPlayerSquareChanger(cycleoption * O,long What)857 void ivanconfig::ShowItemsAtPlayerSquareChanger(cycleoption* O, long What)
858 {
859 // if(What==1 && GetStartingDungeonGfxScale()<3){ //above head asked
860 // What=2; //upgrade to 1st corner
861 // }
862
863 O->Value = What;
864 }
865
WindowWidthChanger(numberoption * O,long What)866 void ivanconfig::WindowWidthChanger(numberoption* O, long What)
867 {
868 if(What < 640) What = 640;
869 O->Value = What;
870 }
871
SelectedBkgColorChanger(stringoption * O,cfestring & What)872 void ivanconfig::SelectedBkgColorChanger(stringoption* O, cfestring& What)
873 {
874 if(!What.IsEmpty()){
875 int RGB[3]={1,1,1}, j=0;
876 std::string sC;
877 for(int i=0;i<What.GetSize();i++){
878 if(j==3)return; //wrong usage detected
879
880 if(What[i]>=0x30 && What[i]<=0x39) //0-9
881 sC+=What[i];
882 else{
883 if(What[i]!=',') //wrong usage detected
884 return;
885 }
886
887 if(What[i]==',' || i==What.GetSize()-1){
888 RGB[j]=std::stol(sC);
889 if(RGB[j]<8)return; //0,0,0 makes xBRZ not work well. 8,8,8 is min to have col16 not 0,0,0 (it is less bits than col24 per component)
890 if(RGB[j]>200)return; //if all too high will prevent reading white text
891 j++;
892 sC="";
893 }
894 }
895
896 if(j!=3)return; //wrong usage detected
897
898 felist::SetSelectedBkgColor(MakeRGB16(RGB[0],RGB[1],RGB[2]));
899 }else{
900 felist::SetSelectedBkgColor(TRANSPARENT_COLOR);
901 }
902
903 if(O!=NULL){
904 O->Value.Empty();
905 O->Value<<What;
906 }
907 }
908
AutoPickUpMatchingChanger(stringoption * O,cfestring & What)909 void ivanconfig::AutoPickUpMatchingChanger(stringoption* O, cfestring& What)
910 {
911 if(O!=NULL){
912 O->Value.Empty();
913 O->Value<<What;
914 game::UpdateAutoPickUpMatching();
915 }
916 }
917
AutoSaveIntervalChanger(numberoption * O,long What)918 void ivanconfig::AutoSaveIntervalChanger(numberoption* O, long What)
919 {
920 if(What < 0) What = 0;
921 if(What > 50000) What = 50000;
922 O->Value = What;
923 }
924
ContrastChanger(numberoption * O,long What)925 void ivanconfig::ContrastChanger(numberoption* O, long What)
926 {
927 if(What < 0) What = 0;
928 if(What > 200) What = 200;
929 O->Value = What;
930
931 CalculateContrastLuminance();
932 }
933
VolumeChanger(numberoption * O,long What)934 void ivanconfig::VolumeChanger(numberoption* O, long What)
935 {
936 if(What < 0) What = 0;
937 if(What > 127) What = 127;
938 O->Value = What;
939
940 audio::SetVolumeLevel(What);
941 }
942
SfxVolumeChanger(numberoption * O,long What)943 void ivanconfig::SfxVolumeChanger(numberoption* O, long What)
944 {
945 if(What < 0) What = 0;
946 if(What > 127) What = 127;
947 O->Value = What;
948 }
949
WorldSizeConfigDisplayer(const cycleoption * O,festring & Entry)950 void ivanconfig::WorldSizeConfigDisplayer(const cycleoption* O, festring& Entry)
951 {
952 if(O->Value == 0)
953 Entry << "Huge (128x128)";
954 else if(O->Value == 1)
955 Entry << "Large (96x96)";
956 else if(O->Value == 2)
957 Entry << "Medium (64x64)";
958 else if(O->Value == 3)
959 Entry << "Small (49x49)";
960 else if(O->Value == 4)
961 Entry << "Tiny (32x32)";
962 else if(O->Value == 5)
963 Entry << "One screen (42x26)";
964 else if(O->Value == 6)
965 Entry << "Four screens (84x52)";
966 else
967 Entry << O->Value;
968 }
969
LandTypeConfigDisplayer(const cycleoption * O,festring & Entry)970 void ivanconfig::LandTypeConfigDisplayer(const cycleoption* O, festring& Entry)
971 {
972 if(O->Value == 0)
973 Entry << "Pangea";
974 else if(O->Value == 1)
975 Entry << "Continents";
976 else
977 Entry << O->Value;
978 }
979
WorldShapeConfigDisplayer(const cycleoption * O,festring & Entry)980 void ivanconfig::WorldShapeConfigDisplayer(const cycleoption* O, festring& Entry)
981 {
982 if(O->Value == 0)
983 Entry << "Pancake (flat)";
984 else if(O->Value == 1)
985 Entry << "Brandy snap (cylinder)";
986 else if(O->Value == 2)
987 Entry << "Doughnut (torus)";
988 else
989 Entry << O->Value;
990 }
991
GetWorldSizeConfig()992 v2 ivanconfig::GetWorldSizeConfig()
993 {
994 v2 WorldSize = v2(49, 49);
995
996 if(WorldSizeConfig.Value == HUGE_WORLD)
997 WorldSize = v2(128, 128);
998 else if(WorldSizeConfig.Value == LARGE_WORLD)
999 WorldSize = v2(96, 96);
1000 else if(WorldSizeConfig.Value == SMALL_WORLD)
1001 WorldSize = v2(49, 49);
1002 else if(WorldSizeConfig.Value == TINY_WORLD)
1003 WorldSize = v2(32, 32);
1004 else if(WorldSizeConfig.Value == ONE_SCREEN_WORLD)
1005 WorldSize = v2(42, 26);
1006 else if(WorldSizeConfig.Value == FOUR_SCREEN_WORLD)
1007 WorldSize = v2(84, 52);
1008 else
1009 WorldSize = v2(49, 49); //SMALL_WORLD
1010
1011 return WorldSize;
1012 }
1013
WorldSeedConfigDisplayer(const numberoption * O,festring & Entry)1014 void ivanconfig::WorldSeedConfigDisplayer(const numberoption* O, festring& Entry)
1015 {
1016 Entry << O->Value << "/2147483647";
1017 }
1018
WorldSeedConfigChangeInterface(numberoption * O)1019 truth ivanconfig::WorldSeedConfigChangeInterface(numberoption* O)
1020 {
1021 O->ChangeValue(iosystem::NumberQuestion(CONST_S("0 gives random world seed, else select new one at your own risk."), GetQuestionPos(), WHITE, !game::IsRunning()));
1022 clearToBackgroundAfterChangeInterface();
1023 return false;
1024 }
1025
WorldSeedConfigChanger(numberoption * O,long What)1026 void ivanconfig::WorldSeedConfigChanger(numberoption* O, long What)
1027 {
1028 if(What < -1)
1029 What = 0;
1030
1031 O->Value = What;
1032 }
1033
1034 #ifndef __DJGPP__
1035
GraphicsScaleDisplayer(const cycleoption * O,festring & Entry)1036 void ivanconfig::GraphicsScaleDisplayer(const cycleoption* O, festring& Entry)
1037 {
1038 Entry << O->Value << 'x';
1039 }
1040
GraphicsScaleChanger(cycleoption * O,long What)1041 void ivanconfig::GraphicsScaleChanger(cycleoption* O, long What)
1042 {
1043 O->Value = What;
1044 graphics::SetScale(What);
1045 }
1046
SilhouetteScaleDisplayer(const cycleoption * O,festring & Entry)1047 void ivanconfig::SilhouetteScaleDisplayer(const cycleoption* O, festring& Entry)
1048 {
1049 Entry << O->Value << 'x';
1050 }
1051
AltListItemPosDisplayer(const cycleoption * O,festring & Entry)1052 void ivanconfig::AltListItemPosDisplayer(const cycleoption* O, festring& Entry)
1053 {
1054 switch(O->Value){
1055 case 0:Entry << "disabled";break; //do not show
1056 case 1:Entry << "no";break; //default pos
1057 case 2:Entry << "yes";break; //alt pos
1058 }
1059 }
1060
SaveGameSortModeDisplayer(const cycleoption * O,festring & Entry)1061 void ivanconfig::SaveGameSortModeDisplayer(const cycleoption* O, festring& Entry)
1062 {
1063 switch(O->Value){
1064 case 0: Entry << "newest first";break;
1065 case 1: Entry << "newest first + progress";break;
1066 case 2: Entry << "alphanumeric";break;
1067 case 3: Entry << "alphanumeric + progress";break;
1068 }
1069 }
1070
MemorizeEquipmentModeDisplayer(const cycleoption * O,festring & Entry)1071 void ivanconfig::MemorizeEquipmentModeDisplayer(const cycleoption* O, festring& Entry)
1072 {
1073 switch(O->Value){
1074 case 0:Entry << "disabled";break; //do not show
1075 case 1:Entry << "only pet";break; //default pos
1076 case 2:Entry << "everyone";break; //alt pos
1077 }
1078 }
1079
DungeonGfxScaleDisplayer(const cycleoption * O,festring & Entry)1080 void ivanconfig::DungeonGfxScaleDisplayer(const cycleoption* O, festring& Entry)
1081 {
1082 Entry << O->Value << 'x';
1083 }
1084
FontGfxDisplayer(const cycleoption * O,festring & Entry)1085 void ivanconfig::FontGfxDisplayer(const cycleoption* O, festring& Entry)
1086 {
1087 Entry << O->Value;
1088 }
1089
SilhouetteScaleChanger(cycleoption * O,long What)1090 void ivanconfig::SilhouetteScaleChanger(cycleoption* O, long What)
1091 {
1092 O->Value = What;
1093 }
1094
SaveGameSortModeChanger(cycleoption * O,long What)1095 void ivanconfig::SaveGameSortModeChanger(cycleoption* O, long What)
1096 {
1097 if(O!=NULL)O->Value = What;
1098
1099 iosystem::SetSaveGameSortMode(What);
1100 }
1101
DungeonGfxScaleChanger(cycleoption * O,long What)1102 void ivanconfig::DungeonGfxScaleChanger(cycleoption* O, long What)
1103 {
1104 O->Value = What;
1105 }
1106
FontGfxChanger(cycleoption * O,long What)1107 void ivanconfig::FontGfxChanger(cycleoption* O, long What)
1108 {
1109 O->Value = What;
1110 }
1111
SetupCustomKeysChanger(truthoption * O,truth What)1112 void ivanconfig::SetupCustomKeysChanger(truthoption* O, truth What)
1113 {
1114 if(game::IsRunning() || !What){
1115 O->Value = What;
1116 if(O->Value)
1117 game::ConfigureCustomKeys();
1118 }
1119 }
1120
XBRZScaleChanger(truthoption * O,truth What)1121 void ivanconfig::XBRZScaleChanger(truthoption* O, truth What)
1122 {
1123 O->Value = What;
1124
1125 game::UpdateSRegionsXBRZ();
1126 }
1127
AllowMouseOnFelistChanger(truthoption * O,truth What)1128 void ivanconfig::AllowMouseOnFelistChanger(truthoption* O, truth What)
1129 {
1130 if(O!=NULL)O->Value = What;
1131 felist::SetAllowMouse(What);
1132 graphics::SetAllowMouseInFullScreen(What);
1133 }
1134
UseExtraMenuGraphicsChanger(truthoption * O,truth What)1135 void ivanconfig::UseExtraMenuGraphicsChanger(truthoption* O, truth What)
1136 {
1137 if(O!=NULL)O->Value = What;
1138 felist::SetAllowMouse(What);
1139 graphics::SetAllowMouseInFullScreen(What);
1140 }
1141
FullScreenModeChanger(truthoption *,truth)1142 void ivanconfig::FullScreenModeChanger(truthoption*, truth)
1143 {
1144 graphics::SwitchMode();
1145 }
1146
ScalingQualityDisplayer(const cycleoption * O,festring & Entry)1147 void ivanconfig::ScalingQualityDisplayer(const cycleoption* O, festring& Entry)
1148 {
1149 switch(O->Value){
1150 case 0: Entry << "pixelated"; break;
1151 case 1: Entry << "smooth"; break;
1152 }
1153 }
1154
1155 #endif
1156
Show()1157 void ivanconfig::Show()
1158 {
1159 game::SRegionAroundDeny();
1160 configsystem::Show(&BackGroundDrawer, &game::SetStandardListAttributes, game::IsRunning());
1161 game::SRegionAroundAllow();
1162 }
1163
ContrastHandler(long Value)1164 void ivanconfig::ContrastHandler(long Value)
1165 {
1166 ContrastChanger(&Contrast, Value);
1167
1168 if(game::IsRunning())
1169 {
1170 game::GetCurrentArea()->SendNewDrawRequest();
1171 game::DrawEverythingNoBlit();
1172 }
1173 }
1174
VolumeHandler(long Value)1175 void ivanconfig::VolumeHandler(long Value)
1176 {
1177 VolumeChanger(&Volume, Value);
1178
1179 if(game::IsRunning())
1180 {
1181 game::GetCurrentArea()->SendNewDrawRequest();
1182 game::DrawEverythingNoBlit();
1183 }
1184 }
SfxVolumeHandler(long Value)1185 void ivanconfig::SfxVolumeHandler(long Value)
1186 {
1187 SfxVolumeChanger(&SfxVolume, Value);
1188
1189 soundeffects::SetSfxVolume(SfxVolume.Value);
1190
1191 if(game::IsRunning())
1192 {
1193 game::GetCurrentArea()->SendNewDrawRequest();
1194 game::DrawEverythingNoBlit();
1195 }
1196 }
1197
1198 #ifndef __DJGPP__
1199
SwitchModeHandler()1200 void ivanconfig::SwitchModeHandler()
1201 {
1202 FullScreenMode.Value = !FullScreenMode.Value;
1203 Save();
1204 }
1205
1206 #endif
1207
CalculateContrastLuminance()1208 void ivanconfig::CalculateContrastLuminance()
1209 {
1210 int Element = Min<long>((GetContrast() << 7) / 100, 255);
1211 ContrastLuminance = MakeRGB24(Element, Element, Element);
1212 }
1213
1214 // TODO keep initializing with invalid values (where possible) so if they are used before cfg file loading it will show errors clearly?
1215 int ivanconfig::iStartingWindowWidth=-1;
1216 int ivanconfig::iStartingWindowHeight=-1;
1217 int ivanconfig::iStartingDungeonGfxScale=-1;
1218 int ivanconfig::iStartingFontGfx=-1;
1219 bool ivanconfig::bStartingOutlinedGfx=false;
Initialize()1220 void ivanconfig::Initialize()
1221 {
1222 festring fsCategory;
1223
1224 fsCategory="General Setup";
1225 configsystem::AddOption(fsCategory,&DefaultName);
1226 configsystem::AddOption(fsCategory,&FantasyNamePattern);
1227 configsystem::AddOption(fsCategory,&DefaultPetName);
1228 configsystem::AddOption(fsCategory,&StartWithNoPet);
1229 configsystem::AddOption(fsCategory,&AutoSaveInterval);
1230 configsystem::AddOption(fsCategory,&AltAdentureInfo);
1231
1232 fsCategory="Gameplay Options";
1233 configsystem::AddOption(fsCategory,&BeNice);
1234 configsystem::AddOption(fsCategory,&HoldPosMaxDist);
1235 //configsystem::AddOption(fsCategory,&MemorizeEquipmentMode); // Let everyone retore equipped items on unpolymorph.
1236 configsystem::AddOption(fsCategory,&WarnAboutDanger);
1237 configsystem::AddOption(fsCategory,&AutoDropLeftOvers);
1238 configsystem::AddOption(fsCategory,&SmartOpenCloseApply);
1239 configsystem::AddOption(fsCategory,&CenterOnPlayerAfterLook);
1240 configsystem::AddOption(fsCategory,&DescriptiveHP);
1241 configsystem::AddOption(fsCategory,&ShowGodInfo); //gameplay change in a sense that, to remember what each god is about may be a challenge on itself :)
1242 configsystem::AddOption(fsCategory,&ShowMapAtDetectMaterial);
1243 configsystem::AddOption(fsCategory,&GoOnStopMode);
1244 configsystem::AddOption(fsCategory,&WaitNeutralsMoveAway);
1245 configsystem::AddOption(fsCategory,&AllWeightIsRelevant);
1246 configsystem::AddOption(fsCategory,&ShowVolume);
1247 configsystem::AddOption(fsCategory,&EnhancedLights);
1248 configsystem::AddOption(fsCategory,&DistLimitMagicMushrooms);
1249 configsystem::AddOption(fsCategory,&AutoPickupThrownItems);
1250 configsystem::AddOption(fsCategory,&AutoPickUpMatching);
1251
1252 fsCategory="Game Window";
1253 configsystem::AddOption(fsCategory,&Contrast);
1254 configsystem::AddOption(fsCategory,&WindowWidth);
1255 configsystem::AddOption(fsCategory,&WindowHeight);
1256 #ifndef __DJGPP__
1257 configsystem::AddOption(fsCategory,&GraphicsScale);
1258 configsystem::AddOption(fsCategory,&FullScreenMode);
1259 #endif
1260
1261 fsCategory="Graphics";
1262 #ifndef __DJGPP__
1263 configsystem::AddOption(fsCategory,&ScalingQuality);
1264 #endif
1265 configsystem::AddOption(fsCategory,&LookZoom);
1266 configsystem::AddOption(fsCategory,&XBRZScale);
1267 configsystem::AddOption(fsCategory,&XBRZSquaresAroundPlayer);
1268 configsystem::AddOption(fsCategory,&SilhouetteScale);
1269 configsystem::AddOption(fsCategory,&AltSilhouette);
1270 configsystem::AddOption(fsCategory,&AltSilhouettePreventColorGlitch);
1271 configsystem::AddOption(fsCategory,&AltListItemPos);
1272 configsystem::AddOption(fsCategory,&AltListItemWidth);
1273 configsystem::AddOption(fsCategory,&StackListPageLength);
1274 configsystem::AddOption(fsCategory,&DungeonGfxScale);
1275 configsystem::AddOption(fsCategory,&FontGfx);
1276 configsystem::AddOption(fsCategory,&OutlinedGfx);
1277 configsystem::AddOption(fsCategory,&FrameSkip);
1278 configsystem::AddOption(fsCategory,&ShowItemsAtPlayerSquare);
1279 configsystem::AddOption(fsCategory,&RotateTimesPerSquare);
1280 configsystem::AddOption(fsCategory,&HitIndicator);
1281 configsystem::AddOption(fsCategory,&ShowMap);
1282 configsystem::AddOption(fsCategory,&TransparentMapLM);
1283 configsystem::AddOption(fsCategory,&UseExtraMenuGraphics);
1284
1285 fsCategory="Sounds";
1286 configsystem::AddOption(fsCategory,&PlaySounds);
1287
1288 std::vector<std::string> DeviceNames;
1289 int NumDevices = audio::GetMIDIOutputDevices(DeviceNames);
1290 MIDIOutputDevice.Value = 0;
1291 if( NumDevices )
1292 {
1293 MIDIOutputDevice.Value = 1;
1294 }
1295 MIDIOutputDevice.CycleCount = NumDevices+1;
1296
1297 configsystem::AddOption(fsCategory,&MIDIOutputDevice);
1298 configsystem::AddOption(fsCategory,&Volume);
1299 configsystem::AddOption(fsCategory,&SfxVolume);
1300
1301 fsCategory="Input and Interface";
1302 configsystem::AddOption(fsCategory,&DirectionKeyMap);
1303 configsystem::AddOption(fsCategory,&SetupCustomKeys);
1304 configsystem::AddOption(fsCategory,&SaveGameSortMode);
1305 configsystem::AddOption(fsCategory,&ShowTurn);
1306 configsystem::AddOption(fsCategory,&ShowFullDungeonName);
1307 configsystem::AddOption(fsCategory,&SelectedBkgColor);
1308 configsystem::AddOption(fsCategory,&AllowMouseOnFelist);
1309
1310 fsCategory="Advanced Options";
1311 configsystem::AddOption(fsCategory,&AllowImportOldSavegame);
1312 configsystem::AddOption(fsCategory,&HideWeirdHitAnimationsThatLookLikeMiss);
1313 configsystem::AddOption(fsCategory,&UseLightEmiterBasedOnVolume);
1314
1315 fsCategory="World Generation";
1316 configsystem::AddOption(fsCategory, &WorldSizeConfig);
1317 configsystem::AddOption(fsCategory, &LandTypeConfig);
1318 configsystem::AddOption(fsCategory, &WorldShapeConfig);
1319 configsystem::AddOption(fsCategory, &WorldSeedConfig);
1320
1321 //World shape: Flat, [Horizontal Wrap (cylinder)]
1322 // Alt names for world shape: pancake (flat), doughnut (torus), brandy snap (cylinder).
1323
1324 /********************************
1325 * LOAD AND APPLY some SETTINGS *
1326 ********************************/
1327 #if defined(WIN32) || defined(__DJGPP__)
1328 configsystem::SetConfigFileName(GetUserDataDir() + "ivan.cfg");
1329 #else
1330 configsystem::SetConfigFileName(GetUserDataDir() + "ivan.conf");
1331 #endif
1332
1333 configsystem::Load();
1334
1335 iStartingWindowWidth = WindowWidth.Value;
1336 iStartingWindowHeight = WindowHeight.Value;
1337 iStartingDungeonGfxScale = DungeonGfxScale.Value;
1338 iStartingFontGfx = FontGfx.Value;
1339 bStartingOutlinedGfx = OutlinedGfx.Value;
1340
1341 CalculateContrastLuminance();
1342 audio::ChangeMIDIOutputDevice(MIDIOutputDevice.Value);
1343 audio::SetVolumeLevel(Volume.Value);
1344
1345 if(ivanconfig::IsSetupCustomKeys())
1346 game::LoadCustomCommandKeys();
1347
1348 //TODO re-use changer methods for above configs too to avoid duplicating the algo?
1349 FrameSkipChanger(NULL,FrameSkip.Value);
1350 StackListPageLengthChanger(NULL, StackListPageLength.Value);
1351 SaveGameSortModeChanger(NULL, SaveGameSortMode.Value);
1352 SelectedBkgColorChanger(NULL, SelectedBkgColor.Value);
1353 AutoPickUpMatchingChanger(NULL, AutoPickUpMatching.Value);
1354 AllowMouseOnFelistChanger(NULL, AllowMouseOnFelist.Value);
1355 UseExtraMenuGraphicsChanger(NULL, UseExtraMenuGraphics.Value);
1356
1357 #ifndef NOSOUND
1358 soundeffects::SetEnableSfx(PlaySounds.Value);
1359 soundeffects::SetSfxVolume(SfxVolume.Value);
1360 soundeffects::SetDataDir(game::GetDataDir());
1361 #endif
1362 }
1363