the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "Options.h"
3#include "KeyMapping.h"
4#include "LevelRenderer.h"
5#include "Textures.h"
6#include "..\Minecraft.World\net.minecraft.locale.h"
7#include "..\Minecraft.World\Language.h"
8#include "..\Minecraft.World\File.h"
9#include "..\Minecraft.World\BufferedReader.h"
10#include "..\Minecraft.World\DataInputStream.h"
11#include "..\Minecraft.World\InputStreamReader.h"
12#include "..\Minecraft.World\FileInputStream.h"
13#include "..\Minecraft.World\FileOutputStream.h"
14#include "..\Minecraft.World\DataOutputStream.h"
15#include "..\Minecraft.World\StringHelpers.h"
16
17// 4J - the Option sub-class used to be an java enumerated type, trying to emulate that functionality here
18const Options::Option Options::Option::options[17] =
19{
20 Options::Option(L"options.music", true, false),
21 Options::Option(L"options.sound", true, false),
22 Options::Option(L"options.invertMouse", false, true),
23 Options::Option(L"options.sensitivity", true, false),
24 Options::Option(L"options.renderDistance", false, false),
25 Options::Option(L"options.viewBobbing", false, true),
26 Options::Option(L"options.anaglyph", false, true),
27 Options::Option(L"options.advancedOpengl", false, true),
28 Options::Option(L"options.framerateLimit", false, false),
29 Options::Option(L"options.difficulty", false, false),
30 Options::Option(L"options.graphics", false, false),
31 Options::Option(L"options.ao", false, true),
32 Options::Option(L"options.guiScale", false, false),
33 Options::Option(L"options.fov", true, false),
34 Options::Option(L"options.gamma", true, false),
35 Options::Option(L"options.renderClouds",false, true),
36 Options::Option(L"options.particles", false, false),
37};
38
39const Options::Option *Options::Option::MUSIC = &Options::Option::options[0];
40const Options::Option *Options::Option::SOUND = &Options::Option::options[1];
41const Options::Option *Options::Option::INVERT_MOUSE = &Options::Option::options[2];
42const Options::Option *Options::Option::SENSITIVITY = &Options::Option::options[3];
43const Options::Option *Options::Option::RENDER_DISTANCE = &Options::Option::options[4];
44const Options::Option *Options::Option::VIEW_BOBBING = &Options::Option::options[5];
45const Options::Option *Options::Option::ANAGLYPH = &Options::Option::options[6];
46const Options::Option *Options::Option::ADVANCED_OPENGL = &Options::Option::options[7];
47const Options::Option *Options::Option::FRAMERATE_LIMIT = &Options::Option::options[8];
48const Options::Option *Options::Option::DIFFICULTY = &Options::Option::options[9];
49const Options::Option *Options::Option::GRAPHICS = &Options::Option::options[10];
50const Options::Option *Options::Option::AMBIENT_OCCLUSION = &Options::Option::options[11];
51const Options::Option *Options::Option::GUI_SCALE = &Options::Option::options[12];
52const Options::Option *Options::Option::FOV = &Options::Option::options[13];
53const Options::Option *Options::Option::GAMMA = &Options::Option::options[14];
54const Options::Option *Options::Option::RENDER_CLOUDS = &Options::Option::options[15];
55const Options::Option *Options::Option::PARTICLES = &Options::Option::options[16];
56
57
58const Options::Option *Options::Option::getItem(int id)
59{
60 return &options[id];
61}
62
63Options::Option::Option(const wstring& captionId, bool hasProgress, bool isBoolean) : _isProgress(hasProgress), _isBoolean(isBoolean), captionId(captionId)
64{
65}
66
67bool Options::Option::isProgress() const
68{
69 return _isProgress;
70}
71
72bool Options::Option::isBoolean() const
73{
74 return _isBoolean;
75}
76
77int Options::Option::getId() const
78{
79 return (int)(this-options);
80}
81
82wstring Options::Option::getCaptionId() const
83{
84 return captionId;
85}
86
87const wstring Options::RENDER_DISTANCE_NAMES[] =
88{
89 L"options.renderDistance.far", L"options.renderDistance.normal", L"options.renderDistance.short", L"options.renderDistance.tiny"
90};
91const wstring Options::DIFFICULTY_NAMES[] =
92{
93 L"options.difficulty.peaceful", L"options.difficulty.easy", L"options.difficulty.normal", L"options.difficulty.hard"
94};
95const wstring Options::GUI_SCALE[] =
96{
97 L"options.guiScale.auto", L"options.guiScale.small", L"options.guiScale.normal", L"options.guiScale.large"
98};
99const wstring Options::FRAMERATE_LIMITS[] =
100{
101 L"performance.max", L"performance.balanced", L"performance.powersaver"
102};
103
104const wstring Options::PARTICLES[] = {
105 L"options.particles.all", L"options.particles.decreased", L"options.particles.minimal"
106};
107
108// 4J added
109void Options::init()
110{
111 music = 1;
112 sound = 1;
113 sensitivity = 0.5f;
114 invertYMouse = false;
115 viewDistance = 0;
116 bobView = true;
117 anaglyph3d = false;
118 advancedOpengl = false;
119 framerateLimit = 0;
120 fancyGraphics = true;
121 ambientOcclusion = true;
122 renderClouds = true;
123 skin = L"Default";
124
125 keyUp = new KeyMapping(L"key.forward", Keyboard::KEY_W);
126 keyLeft = new KeyMapping(L"key.left", Keyboard::KEY_A);
127 keyDown = new KeyMapping(L"key.back", Keyboard::KEY_S);
128 keyRight = new KeyMapping(L"key.right", Keyboard::KEY_D);
129 keyJump = new KeyMapping(L"key.jump", Keyboard::KEY_SPACE);
130 keyBuild = new KeyMapping(L"key.inventory", Keyboard::KEY_E);
131 keyDrop = new KeyMapping(L"key.drop", Keyboard::KEY_Q);
132 keyChat = new KeyMapping(L"key.chat", Keyboard::KEY_T);
133 keySneak = new KeyMapping(L"key.sneak", Keyboard::KEY_LSHIFT);
134 keyAttack = new KeyMapping(L"key.attack", -100 + 0);
135 keyUse = new KeyMapping(L"key.use", -100 + 1);
136 keyPlayerList = new KeyMapping(L"key.playerlist", Keyboard::KEY_TAB);
137 keyPickItem = new KeyMapping(L"key.pickItem", -100 + 2);
138 keyToggleFog = new KeyMapping(L"key.fog", Keyboard::KEY_F);
139
140 keyMappings[0] = keyAttack;
141 keyMappings[1] = keyUse;
142 keyMappings[2] = keyUp;
143 keyMappings[3] = keyLeft;
144 keyMappings[4] = keyDown;
145 keyMappings[5] = keyRight;
146 keyMappings[6] = keyJump;
147 keyMappings[7] = keySneak;
148 keyMappings[8] = keyDrop;
149 keyMappings[9] = keyBuild;
150 keyMappings[10] = keyChat;
151 keyMappings[11] = keyPlayerList;
152 keyMappings[12] = keyPickItem;
153 keyMappings[13] = keyToggleFog;
154
155 minecraft = NULL;
156 //optionsFile = NULL;
157
158 difficulty = 2;
159 hideGui = false;
160 thirdPersonView = false;
161 renderDebug = false;
162 lastMpIp = L"";
163
164 isFlying = false;
165 smoothCamera = false;
166 fixedCamera = false;
167 flySpeed = 1;
168 cameraSpeed = 1;
169 guiScale = 0;
170 particles = 0;
171 fov = 0;
172 gamma = 0;
173}
174
175Options::Options(Minecraft *minecraft, File workingDirectory)
176{
177 init();
178 this->minecraft = minecraft;
179 optionsFile = File(workingDirectory, L"options.txt");
180}
181
182Options::Options()
183{
184 init();
185}
186
187wstring Options::getKeyDescription(int i)
188{
189 Language *language = Language::getInstance();
190 return language->getElement(keyMappings[i]->name);
191}
192
193wstring Options::getKeyMessage(int i)
194{
195 int key = keyMappings[i]->key;
196 if (key < 0) {
197 return I18n::get(L"key.mouseButton", key + 101);
198 } else {
199 return Keyboard::getKeyName(keyMappings[i]->key);
200 }
201}
202
203void Options::setKey(int i, int key)
204{
205 keyMappings[i]->key = key;
206 save();
207}
208
209void Options::set(const Options::Option *item, float fVal)
210{
211 if (item == Option::MUSIC)
212 {
213 music = fVal;
214#ifdef _XBOX
215 minecraft->soundEngine->updateMusicVolume(fVal*2.0f);
216#else
217 minecraft->soundEngine->updateMusicVolume(fVal);
218#endif
219 }
220 if (item == Option::SOUND)
221 {
222 sound = fVal;
223#ifdef _XBOX
224 minecraft->soundEngine->updateSoundEffectVolume(fVal*2.0f);
225#else
226 minecraft->soundEngine->updateSoundEffectVolume(fVal);
227#endif
228 }
229 if (item == Option::SENSITIVITY)
230 {
231 sensitivity = fVal;
232 }
233 if (item == Option::FOV)
234 {
235 fov = fVal;
236 }
237 if (item == Option::GAMMA)
238 {
239 gamma = fVal;
240 }
241}
242
243void Options::toggle(const Options::Option *option, int dir)
244{
245 if (option == Option::INVERT_MOUSE) invertYMouse = !invertYMouse;
246 if (option == Option::RENDER_DISTANCE) viewDistance = (viewDistance + dir) & 3;
247 if (option == Option::GUI_SCALE) guiScale = (guiScale + dir) & 3;
248 if (option == Option::PARTICLES) particles = (particles + dir) % 3;
249
250 // 4J-PB - changing
251 //if (option == Option::VIEW_BOBBING) bobView = !bobView;
252 if (option == Option::VIEW_BOBBING) ((dir==0)?bobView=false: bobView=true);
253 if (option == Option::RENDER_CLOUDS) renderClouds = !renderClouds;
254 if (option == Option::ADVANCED_OPENGL)
255 {
256 advancedOpengl = !advancedOpengl;
257 minecraft->levelRenderer->allChanged();
258 }
259 if (option == Option::ANAGLYPH)
260 {
261 anaglyph3d = !anaglyph3d;
262 minecraft->textures->reloadAll();
263 }
264 if (option == Option::FRAMERATE_LIMIT) framerateLimit = (framerateLimit + dir + 3) % 3;
265
266 // 4J-PB - Change for Xbox
267 //if (option == Option::DIFFICULTY) difficulty = (difficulty + dir) & 3;
268 if (option == Option::DIFFICULTY) difficulty = (dir) & 3;
269
270 app.DebugPrintf("Option::DIFFICULTY = %d",difficulty);
271
272 if (option == Option::GRAPHICS)
273 {
274 fancyGraphics = !fancyGraphics;
275 minecraft->levelRenderer->allChanged();
276 }
277 if (option == Option::AMBIENT_OCCLUSION)
278 {
279 ambientOcclusion = !ambientOcclusion;
280 minecraft->levelRenderer->allChanged();
281 }
282
283 // 4J-PB - don't do the file save on the xbox
284 // save();
285
286}
287
288float Options::getProgressValue(const Options::Option *item)
289{
290 if (item == Option::FOV) return fov;
291 if (item == Option::GAMMA) return gamma;
292 if (item == Option::MUSIC) return music;
293 if (item == Option::SOUND) return sound;
294 if (item == Option::SENSITIVITY) return sensitivity;
295 return 0;
296}
297
298bool Options::getBooleanValue(const Options::Option *item)
299{
300 // 4J - was a switch statement which we can't do with our Option:: pointer types
301 if( item == Option::INVERT_MOUSE) return invertYMouse;
302 if( item == Option::VIEW_BOBBING) return bobView;
303 if( item == Option::ANAGLYPH) return anaglyph3d;
304 if( item == Option::ADVANCED_OPENGL) return advancedOpengl;
305 if( item == Option::AMBIENT_OCCLUSION) return ambientOcclusion;
306 if( item == Option::RENDER_CLOUDS) return renderClouds;
307 return false;
308}
309
310wstring Options::getMessage(const Options::Option *item)
311{
312 // 4J TODO, should these wstrings append rather than add?
313
314 Language *language = Language::getInstance();
315 wstring caption = language->getElement(item->getCaptionId()) + L": ";
316
317 if (item->isProgress())
318 {
319 float progressValue = getProgressValue(item);
320
321 if (item == Option::SENSITIVITY)
322 {
323 if (progressValue == 0)
324 {
325 return caption + language->getElement(L"options.sensitivity.min");
326 }
327 if (progressValue == 1)
328 {
329 return caption + language->getElement(L"options.sensitivity.max");
330 }
331 return caption + _toString<int>((int) (progressValue * 200)) + L"%";
332 } else if (item == Option::FOV)
333 {
334 if (progressValue == 0)
335 {
336 return caption + language->getElement(L"options.fov.min");
337 }
338 if (progressValue == 1)
339 {
340 return caption + language->getElement(L"options.fov.max");
341 }
342 return caption + _toString<int>((int) (70 + progressValue * 40));
343 } else if (item == Option::GAMMA)
344 {
345 if (progressValue == 0)
346 {
347 return caption + language->getElement(L"options.gamma.min");
348 }
349 if (progressValue == 1)
350 {
351 return caption + language->getElement(L"options.gamma.max");
352 }
353 return caption + L"+" + _toString<int>((int) (progressValue * 100)) + L"%";
354 }
355 else
356 {
357 if (progressValue == 0)
358 {
359 return caption + language->getElement(L"options.off");
360 }
361 return caption + _toString<int>((int) (progressValue * 100)) + L"%";
362 }
363 } else if (item->isBoolean())
364 {
365
366 bool booleanValue = getBooleanValue(item);
367 if (booleanValue)
368 {
369 return caption + language->getElement(L"options.on");
370 }
371 return caption + language->getElement(L"options.off");
372 }
373 else if (item == Option::RENDER_DISTANCE)
374 {
375 return caption + language->getElement(RENDER_DISTANCE_NAMES[viewDistance]);
376 }
377 else if (item == Option::DIFFICULTY)
378 {
379 return caption + language->getElement(DIFFICULTY_NAMES[difficulty]);
380 }
381 else if (item == Option::GUI_SCALE)
382 {
383 return caption + language->getElement(GUI_SCALE[guiScale]);
384 }
385 else if (item == Option::PARTICLES)
386 {
387 return caption + language->getElement(PARTICLES[particles]);
388 }
389 else if (item == Option::FRAMERATE_LIMIT)
390 {
391 return caption + I18n::get(FRAMERATE_LIMITS[framerateLimit]);
392 }
393 else if (item == Option::GRAPHICS)
394 {
395 if (fancyGraphics)
396 {
397 return caption + language->getElement(L"options.graphics.fancy");
398 }
399 return caption + language->getElement(L"options.graphics.fast");
400 }
401
402 return caption;
403
404}
405
406void Options::load()
407{
408 // 4J - removed try/catch
409// try {
410 if (!optionsFile.exists()) return;
411 // 4J - was new BufferedReader(new FileReader(optionsFile));
412 BufferedReader *br = new BufferedReader(new InputStreamReader( new FileInputStream( optionsFile ) ) );
413
414 wstring line = L"";
415 while ((line = br->readLine()) != L"") // 4J - was check against NULL - do we need to distinguish between empty lines and a fail here?
416 {
417 // 4J - removed try/catch
418// try {
419 wstring cmds[2];
420 int splitpos = (int)line.find(L":");
421 if( splitpos == wstring::npos )
422 {
423 cmds[0] = line;
424 cmds[1] = L"";
425 }
426 else
427 {
428 cmds[0] = line.substr(0,splitpos);
429 cmds[1] = line.substr(splitpos,line.length()-splitpos);
430 }
431
432 if (cmds[0] == L"music") music = readFloat(cmds[1]);
433 if (cmds[0] == L"sound") sound = readFloat(cmds[1]);
434 if (cmds[0] == L"mouseSensitivity") sensitivity = readFloat(cmds[1]);
435 if (cmds[0] == L"fov") fov = readFloat(cmds[1]);
436 if (cmds[0] == L"gamma") gamma = readFloat(cmds[1]);
437 if (cmds[0] == L"invertYMouse") invertYMouse = cmds[1]==L"true";
438 if (cmds[0] == L"viewDistance") viewDistance = _fromString<int>(cmds[1]);
439 if (cmds[0] == L"guiScale") guiScale =_fromString<int>(cmds[1]);
440 if (cmds[0] == L"particles") particles = _fromString<int>(cmds[1]);
441 if (cmds[0] == L"bobView") bobView = cmds[1]==L"true";
442 if (cmds[0] == L"anaglyph3d") anaglyph3d = cmds[1]==L"true";
443 if (cmds[0] == L"advancedOpengl") advancedOpengl = cmds[1]==L"true";
444 if (cmds[0] == L"fpsLimit") framerateLimit = _fromString<int>(cmds[1]);
445 if (cmds[0] == L"difficulty") difficulty = _fromString<int>(cmds[1]);
446 if (cmds[0] == L"fancyGraphics") fancyGraphics = cmds[1]==L"true";
447 if (cmds[0] == L"ao") ambientOcclusion = cmds[1]==L"true";
448 if (cmds[0] == L"clouds") renderClouds = cmds[1]==L"true";
449 if (cmds[0] == L"skin") skin = cmds[1];
450 if (cmds[0] == L"lastServer") lastMpIp = cmds[1];
451
452 for (int i = 0; i < keyMappings_length; i++)
453 {
454 if (cmds[0] == (L"key_" + keyMappings[i]->name))
455 {
456 keyMappings[i]->key = _fromString<int>(cmds[1]);
457 }
458 }
459// } catch (Exception e) {
460// System.out.println("Skipping bad option: " + line);
461// }
462 }
463 //KeyMapping.resetMapping(); // 4J Not implemented
464 br->close();
465// } catch (Exception e) {
466// System.out.println("Failed to load options");
467// e.printStackTrace();
468// }
469
470}
471
472float Options::readFloat(wstring string)
473{
474 if (string == L"true") return 1;
475 if (string == L"false") return 0;
476 return _fromString<float>(string);
477}
478
479void Options::save()
480{
481 // 4J - try/catch removed
482// try {
483
484 // 4J - original used a PrintWriter & FileWriter, but seems a bit much implementing these just to do this
485 FileOutputStream fos = FileOutputStream(optionsFile);
486 DataOutputStream dos = DataOutputStream(&fos);
487// PrintWriter pw = new PrintWriter(new FileWriter(optionsFile));
488
489 dos.writeChars(L"music:" + _toString<float>(music) + L"\n");
490 dos.writeChars(L"sound:" + _toString<float>(sound) + L"\n");
491 dos.writeChars(L"invertYMouse:" + wstring(invertYMouse ? L"true" : L"false") + L"\n");
492 dos.writeChars(L"mouseSensitivity:" + _toString<float>(sensitivity));
493 dos.writeChars(L"fov:" + _toString<float>(fov));
494 dos.writeChars(L"gamma:" + _toString<float>(gamma));
495 dos.writeChars(L"viewDistance:" + _toString<int>(viewDistance));
496 dos.writeChars(L"guiScale:" + _toString<int>(guiScale));
497 dos.writeChars(L"particles:" + _toString<int>(particles));
498 dos.writeChars(L"bobView:" + wstring(bobView ? L"true" : L"false"));
499 dos.writeChars(L"anaglyph3d:" + wstring(anaglyph3d ? L"true" : L"false"));
500 dos.writeChars(L"advancedOpengl:" + wstring(advancedOpengl ? L"true" : L"false"));
501 dos.writeChars(L"fpsLimit:" + _toString<int>(framerateLimit));
502 dos.writeChars(L"difficulty:" + _toString<int>(difficulty));
503 dos.writeChars(L"fancyGraphics:" + wstring(fancyGraphics ? L"true" : L"false"));
504 dos.writeChars(L"ao:" + wstring(ambientOcclusion ? L"true" : L"false"));
505 dos.writeChars(L"clouds:" + _toString<bool>(renderClouds));
506 dos.writeChars(L"skin:" + skin);
507 dos.writeChars(L"lastServer:" + lastMpIp);
508
509 for (int i = 0; i < keyMappings_length; i++)
510 {
511 dos.writeChars(L"key_" + keyMappings[i]->name + L":" + _toString<int>(keyMappings[i]->key));
512 }
513
514 dos.close();
515// } catch (Exception e) {
516// System.out.println("Failed to save options");
517// e.printStackTrace();
518// }
519
520}
521
522bool Options::isCloudsOn()
523{
524 return viewDistance < 2 && renderClouds;
525}