461 lines
16 KiB
C++
Executable File
461 lines
16 KiB
C++
Executable File
#include "Options.h"
|
|
#include "OptionStrings.h"
|
|
#include "Minecraft.h"
|
|
#include "../platform/log.h"
|
|
#include "../world/Difficulty.h"
|
|
#include <cmath>
|
|
#include <sstream>
|
|
/*static*/
|
|
bool Options::debugGl = false;
|
|
|
|
void Options::initDefaultValues() {
|
|
difficulty = Difficulty::NORMAL;
|
|
hideGui = false;
|
|
thirdPersonView = false;
|
|
renderDebug = false;
|
|
isFlying = false;
|
|
smoothCamera = true;
|
|
fixedCamera = false;
|
|
flySpeed = 1;
|
|
cameraSpeed = 1;
|
|
guiScale = 0;
|
|
|
|
useMouseForDigging = false;
|
|
destroyVibration = true;
|
|
isLeftHanded = false;
|
|
|
|
isJoyTouchArea = false;
|
|
|
|
music = 1;
|
|
sound = 1;
|
|
sensitivity = 0.5f;
|
|
invertYMouse = false;
|
|
viewDistance = 2;
|
|
bobView = true;
|
|
anaglyph3d = false;
|
|
limitFramerate = false;
|
|
fancyGraphics = true;//false;
|
|
ambientOcclusion = false;
|
|
if(minecraft->supportNonTouchScreen())
|
|
useTouchScreen = false;
|
|
else
|
|
useTouchScreen = true;
|
|
pixelsPerMillimeter = minecraft->platform()->getPixelsPerMillimeter();
|
|
//useMouseForDigging = true;
|
|
|
|
//skin = "Default";
|
|
username = "Steve";
|
|
serverVisible = true;
|
|
|
|
keyUp = KeyMapping("key.forward", Keyboard::KEY_W);
|
|
keyLeft = KeyMapping("key.left", Keyboard::KEY_A);
|
|
keyDown = KeyMapping("key.back", Keyboard::KEY_S);
|
|
keyRight = KeyMapping("key.right", Keyboard::KEY_D);
|
|
keyJump = KeyMapping("key.jump", Keyboard::KEY_SPACE);
|
|
keyBuild = KeyMapping("key.inventory", Keyboard::KEY_E);
|
|
keySneak = KeyMapping("key.sneak", Keyboard::KEY_LSHIFT);
|
|
#if defined(RPI) || defined(PLATFORM_GLFW)
|
|
keyCraft = KeyMapping("key.crafting", Keyboard::KEY_Q);
|
|
keyDrop = KeyMapping("key.drop", Keyboard::KEY_Q);
|
|
keyChat = KeyMapping("key.chat", Keyboard::KEY_T);
|
|
keyFog = KeyMapping("key.fog", Keyboard::KEY_F);
|
|
keyDestroy=KeyMapping("key.destroy", 88); // @todo @fix
|
|
keyUse = KeyMapping("key.use", Keyboard::KEY_U);
|
|
#endif
|
|
|
|
//const int Unused = 99999;
|
|
keyMenuNext = KeyMapping("key.menu.next", 40);
|
|
keyMenuPrevious = KeyMapping("key.menu.previous", 38);
|
|
keyMenuOk = KeyMapping("key.menu.ok", 13);
|
|
keyMenuCancel = KeyMapping("key.menu.cancel", 8);
|
|
|
|
int k = 0;
|
|
keyMappings[k++] = &keyUp;
|
|
keyMappings[k++] = &keyLeft;
|
|
keyMappings[k++] = &keyDown;
|
|
keyMappings[k++] = &keyRight;
|
|
keyMappings[k++] = &keyJump;
|
|
keyMappings[k++] = &keySneak;
|
|
keyMappings[k++] = &keyDrop;
|
|
keyMappings[k++] = &keyBuild;
|
|
keyMappings[k++] = &keyChat;
|
|
keyMappings[k++] = &keyFog;
|
|
keyMappings[k++] = &keyDestroy;
|
|
keyMappings[k++] = &keyUse;
|
|
|
|
keyMappings[k++] = &keyMenuNext;
|
|
keyMappings[k++] = &keyMenuPrevious;
|
|
keyMappings[k++] = &keyMenuOk;
|
|
keyMappings[k++] = &keyMenuCancel;
|
|
|
|
// "Polymorphism" at it's worst. At least it's better to have it here
|
|
// for now, then to have it spread all around the game code (even if
|
|
// it would be slightly better performance with it inlined. Should
|
|
// probably create separate subclasses (or read from file). @fix @todo.
|
|
#if defined(ANDROID) || defined(__APPLE__) || defined(RPI)
|
|
viewDistance = 2;
|
|
thirdPersonView = false;
|
|
useMouseForDigging = false;
|
|
fancyGraphics = false;
|
|
|
|
//renderDebug = true;
|
|
#if !defined(RPI)
|
|
keyUp.key = 19;
|
|
keyDown.key = 20;
|
|
keyLeft.key = 21;
|
|
keyRight.key = 22;
|
|
keyJump.key = 23;
|
|
keyUse.key = 103;
|
|
keyDestroy.key = 102;
|
|
keyCraft.key = 109;
|
|
|
|
keyMenuNext.key = 20;
|
|
keyMenuPrevious.key = 19;
|
|
keyMenuOk.key = 23;
|
|
keyMenuCancel.key = 4;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(RPI)
|
|
username = "StevePi";
|
|
sensitivity *= 0.4f;
|
|
useMouseForDigging = true;
|
|
#endif
|
|
}
|
|
|
|
const Options::Option
|
|
Options::Option::MUSIC (0, "options.music", true, false),
|
|
Options::Option::SOUND (1, "options.sound", true, false),
|
|
Options::Option::INVERT_MOUSE (2, "options.invertMouse", false, true),
|
|
Options::Option::SENSITIVITY (3, "options.sensitivity", true, false),
|
|
Options::Option::RENDER_DISTANCE (4, "options.renderDistance",false, false),
|
|
Options::Option::VIEW_BOBBING (5, "options.viewBobbing", false, true),
|
|
Options::Option::ANAGLYPH (6, "options.anaglyph", false, true),
|
|
Options::Option::LIMIT_FRAMERATE (7, "options.limitFramerate",false, true),
|
|
Options::Option::DIFFICULTY (8, "options.difficulty", false, false),
|
|
Options::Option::GRAPHICS (9, "options.graphics", false, false),
|
|
Options::Option::AMBIENT_OCCLUSION (10, "options.ao", false, true),
|
|
Options::Option::GUI_SCALE (11, "options.guiScale", false, false),
|
|
Options::Option::THIRD_PERSON (12, "options.thirdperson", false, true),
|
|
Options::Option::HIDE_GUI (13, "options.hidegui", false, true),
|
|
Options::Option::SERVER_VISIBLE (14, "options.servervisible", false, true),
|
|
Options::Option::LEFT_HANDED (15, "options.lefthanded", false, true),
|
|
Options::Option::USE_TOUCHSCREEN (16, "options.usetouchscreen", false, true),
|
|
Options::Option::USE_TOUCH_JOYPAD (17, "options.usetouchpad", false, true),
|
|
Options::Option::DESTROY_VIBRATION (18, "options.destroyvibration", false, true),
|
|
Options::Option::PIXELS_PER_MILLIMETER(19, "options.pixelspermilimeter", true, false);
|
|
|
|
/* private */
|
|
const float Options::SOUND_MIN_VALUE = 0.0f;
|
|
const float Options::SOUND_MAX_VALUE = 1.0f;
|
|
const float Options::MUSIC_MIN_VALUE = 0.0f;
|
|
const float Options::MUSIC_MAX_VALUE = 1.0f;
|
|
const float Options::SENSITIVITY_MIN_VALUE = 0.0f;
|
|
const float Options::SENSITIVITY_MAX_VALUE = 1.0f;
|
|
const float Options::PIXELS_PER_MILLIMETER_MIN_VALUE = 3.0f;
|
|
const float Options::PIXELS_PER_MILLIMETER_MAX_VALUE = 4.0f;
|
|
const int DIFFICULY_LEVELS[] = {
|
|
Difficulty::PEACEFUL,
|
|
Difficulty::NORMAL
|
|
};
|
|
|
|
/*private*/
|
|
const char* Options::RENDER_DISTANCE_NAMES[] = {
|
|
"options.renderDistance.far",
|
|
"options.renderDistance.normal",
|
|
"options.renderDistance.short",
|
|
"options.renderDistance.tiny"
|
|
};
|
|
|
|
/*private*/
|
|
const char* Options::DIFFICULTY_NAMES[] = {
|
|
"options.difficulty.peaceful",
|
|
"options.difficulty.easy",
|
|
"options.difficulty.normal",
|
|
"options.difficulty.hard"
|
|
};
|
|
|
|
/*private*/
|
|
const char* Options::GUI_SCALE[] = {
|
|
"options.guiScale.auto",
|
|
"options.guiScale.small",
|
|
"options.guiScale.normal",
|
|
"options.guiScale.large"
|
|
};
|
|
|
|
void Options::update()
|
|
{
|
|
viewDistance = 2;
|
|
StringVector optionStrings = optionsFile.getOptionStrings();
|
|
for (unsigned int i = 0; i < optionStrings.size(); i += 2) {
|
|
const std::string& key = optionStrings[i];
|
|
const std::string& value = optionStrings[i+1];
|
|
|
|
//LOGI("reading key: %s (%s)\n", key.c_str(), value.c_str());
|
|
|
|
// Multiplayer
|
|
if (key == OptionStrings::Multiplayer_Username) username = value;
|
|
if (key == OptionStrings::Multiplayer_ServerVisible) readBool(value, serverVisible);
|
|
|
|
// Controls
|
|
if (key == OptionStrings::Controls_Sensitivity) {
|
|
float sens;
|
|
if (readFloat(value, sens)) {
|
|
// sens is in range [0,1] with default/center at 0.5 (for aesthetics)
|
|
// We wanna map it to something like [0.3, 0.9] BUT keep 0.5 @ ~0.5...
|
|
sensitivity = 0.3f + std::pow(1.1f * sens, 1.3f) * 0.42f;
|
|
}
|
|
}
|
|
if (key == OptionStrings::Controls_InvertMouse) {
|
|
readBool(value, invertYMouse);
|
|
}
|
|
if (key == OptionStrings::Controls_IsLefthanded) {
|
|
readBool(value, isLeftHanded);
|
|
}
|
|
if (key == OptionStrings::Controls_UseTouchJoypad) {
|
|
readBool(value, isJoyTouchArea);
|
|
if (!minecraft->useTouchscreen())
|
|
isJoyTouchArea = false;
|
|
}
|
|
|
|
// Feedback
|
|
if (key == OptionStrings::Controls_FeedbackVibration)
|
|
readBool(value, destroyVibration);
|
|
|
|
// Graphics
|
|
if (key == OptionStrings::Graphics_Fancy) {
|
|
readBool(value, fancyGraphics);
|
|
}
|
|
if (key == OptionStrings::Graphics_LowQuality) {
|
|
bool isLow;
|
|
readBool(value, isLow);
|
|
if (isLow) {
|
|
viewDistance = 3;
|
|
fancyGraphics = false;
|
|
}
|
|
}
|
|
// Game
|
|
if (key == OptionStrings::Game_DifficultyLevel) {
|
|
readInt(value, difficulty);
|
|
// Only support peaceful and normal right now
|
|
if (difficulty != Difficulty::PEACEFUL && difficulty != Difficulty::NORMAL)
|
|
difficulty = Difficulty::NORMAL;
|
|
}
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
// if (minecraft->isSuperFast()) {
|
|
// viewDistance = (viewDistance>0)? --viewDistance : 0;
|
|
// }
|
|
// LOGI("Is this card super fast?: %d\n", viewDistance);
|
|
#endif
|
|
|
|
//LOGI("Lefty is: %d\n", isLeftHanded);
|
|
}
|
|
|
|
void Options::load()
|
|
{
|
|
int a = 0;
|
|
//try {
|
|
// if (!optionsFile.exists()) return;
|
|
// BufferedReader br = /*new*/ BufferedReader(/*new*/ FileReader(optionsFile));
|
|
// std::string line = "";
|
|
// while ((line = br.readLine()) != NULL) {
|
|
// std::string[] cmds = line.split(":");
|
|
// if (cmds[0].equals("music")) music = readFloat(cmds[1]);
|
|
// if (cmds[0].equals("sound")) sound = readFloat(cmds[1]);
|
|
// if (cmds[0].equals("mouseSensitivity")) sensitivity = readFloat(cmds[1]);
|
|
// if (cmds[0].equals("invertYMouse")) invertYMouse = cmds[1].equals("true");
|
|
// if (cmds[0].equals("viewDistance")) viewDistance = Integer.parseInt(cmds[1]);
|
|
// if (cmds[0].equals("guiScale")) guiScale = Integer.parseInt(cmds[1]);
|
|
// if (cmds[0].equals("bobView")) bobView = cmds[1].equals("true");
|
|
// if (cmds[0].equals("anaglyph3d")) anaglyph3d = cmds[1].equals("true");
|
|
// if (cmds[0].equals("limitFramerate")) limitFramerate = cmds[1].equals("true");
|
|
// if (cmds[0].equals("difficulty")) difficulty = Integer.parseInt(cmds[1]);
|
|
// if (cmds[0].equals("fancyGraphics")) fancyGraphics = cmds[1].equals("true");
|
|
// if (cmds[0].equals("ao")) ambientOcclusion = cmds[1].equals("true");
|
|
// if (cmds[0].equals("skin")) skin = cmds[1];
|
|
// if (cmds[0].equals("lastServer") && cmds.length >= 2) lastMpIp = cmds[1];
|
|
|
|
// for (int i = 0; i < keyMappings.length; i++) {
|
|
// if (cmds[0].equals("key_" + keyMappings[i].name)) {
|
|
// keyMappings[i].key = Integer.parseInt(cmds[1]);
|
|
// }
|
|
// }
|
|
// }
|
|
// br.close();
|
|
//} catch (Exception e) {
|
|
// System.out.println("Failed to load options");
|
|
// e.printStackTrace();
|
|
//}
|
|
}
|
|
|
|
void Options::save()
|
|
{
|
|
StringVector stringVec;
|
|
// Game
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Multiplayer_ServerVisible, serverVisible);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Game_DifficultyLevel, difficulty);
|
|
|
|
// Input
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_InvertMouse, invertYMouse);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_Sensitivity, sensitivity);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_IsLefthanded, isLeftHanded);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_UseTouchScreen, useTouchScreen);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_UseTouchJoypad, isJoyTouchArea);
|
|
addOptionToSaveOutput(stringVec, OptionStrings::Controls_FeedbackVibration, destroyVibration);
|
|
//
|
|
// static const Option MUSIC;
|
|
// static const Option SOUND;
|
|
// static const Option INVERT_MOUSE;
|
|
// static const Option SENSITIVITY;
|
|
// static const Option RENDER_DISTANCE;
|
|
// static const Option VIEW_BOBBING;
|
|
// static const Option ANAGLYPH;
|
|
// static const Option LIMIT_FRAMERATE;
|
|
// static const Option DIFFICULTY;
|
|
// static const Option GRAPHICS;
|
|
// static const Option AMBIENT_OCCLUSION;
|
|
// static const Option GUI_SCALE;
|
|
//
|
|
// static const Option THIRD_PERSON;
|
|
// static const Option HIDE_GUI;
|
|
//try {
|
|
// PrintWriter pw = /*new*/ PrintWriter(/*new*/ FileWriter(optionsFile));
|
|
|
|
// pw.println("music:" + music);
|
|
// pw.println("sound:" + sound);
|
|
// pw.println("invertYMouse:" + invertYMouse);
|
|
// pw.println("mouseSensitivity:" + sensitivity);
|
|
// pw.println("viewDistance:" + viewDistance);
|
|
// pw.println("guiScale:" + guiScale);
|
|
// pw.println("bobView:" + bobView);
|
|
// pw.println("anaglyph3d:" + anaglyph3d);
|
|
// pw.println("limitFramerate:" + limitFramerate);
|
|
// pw.println("difficulty:" + difficulty);
|
|
// pw.println("fancyGraphics:" + fancyGraphics);
|
|
// pw.println("ao:" + ambientOcclusion);
|
|
// pw.println("skin:" + skin);
|
|
// pw.println("lastServer:" + lastMpIp);
|
|
|
|
// for (int i = 0; i < keyMappings.length; i++) {
|
|
// pw.println("key_" + keyMappings[i].name + ":" + keyMappings[i].key);
|
|
// }
|
|
|
|
// pw.close();
|
|
//} catch (Exception e) {
|
|
// System.out.println("Failed to save options");
|
|
// e.printStackTrace();
|
|
//}
|
|
}
|
|
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, bool boolValue) {
|
|
std::stringstream ss;
|
|
ss << name << ":" << boolValue;
|
|
stringVector.push_back(ss.str());
|
|
}
|
|
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, float floatValue) {
|
|
std::stringstream ss;
|
|
ss << name << ":" << floatValue;
|
|
stringVector.push_back(ss.str());
|
|
}
|
|
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, int intValue) {
|
|
std::stringstream ss;
|
|
ss << name << ":" << intValue;
|
|
stringVector.push_back(ss.str());
|
|
}
|
|
|
|
std::string Options::getMessage( const Option* item )
|
|
{
|
|
return "Options::getMessage - Not implemented";
|
|
|
|
//Language language = Language.getInstance();
|
|
//std::string caption = language.getElement(item.getCaptionId()) + ": ";
|
|
|
|
//if (item.isProgress()) {
|
|
// float progressValue = getProgressValue(item);
|
|
|
|
// if (item == Option.SENSITIVITY) {
|
|
// if (progressValue == 0) {
|
|
// return caption + language.getElement("options.sensitivity.min");
|
|
// }
|
|
// if (progressValue == 1) {
|
|
// return caption + language.getElement("options.sensitivity.max");
|
|
// }
|
|
// return caption + (int) (progressValue * 200) + "%";
|
|
// } else {
|
|
// if (progressValue == 0) {
|
|
// return caption + language.getElement("options.off");
|
|
// }
|
|
// return caption + (int) (progressValue * 100) + "%";
|
|
// }
|
|
//} else if (item.isBoolean()) {
|
|
|
|
// bool booleanValue = getBooleanValue(item);
|
|
// if (booleanValue) {
|
|
// return caption + language.getElement("options.on");
|
|
// }
|
|
// return caption + language.getElement("options.off");
|
|
//} else if (item == Option.RENDER_DISTANCE) {
|
|
// return caption + language.getElement(RENDER_DISTANCE_NAMES[viewDistance]);
|
|
//} else if (item == Option.DIFFICULTY) {
|
|
// return caption + language.getElement(DIFFICULTY_NAMES[difficulty]);
|
|
//} else if (item == Option.GUI_SCALE) {
|
|
// return caption + language.getElement(GUI_SCALE[guiScale]);
|
|
//} else if (item == Option.GRAPHICS) {
|
|
// if (fancyGraphics) {
|
|
// return caption + language.getElement("options.graphics.fancy");
|
|
// }
|
|
// return caption + language.getElement("options.graphics.fast");
|
|
//}
|
|
|
|
//return caption;
|
|
}
|
|
|
|
/*static*/
|
|
bool Options::readFloat(const std::string& string, float& value) {
|
|
if (string == "true" || string == "YES") { value = 1; return true; }
|
|
if (string == "false" || string == "NO") { value = 0; return true; }
|
|
#ifdef _WIN32
|
|
if (sscanf_s(string.c_str(), "%f", &value))
|
|
return true;
|
|
#else
|
|
if (sscanf(string.c_str(), "%f", &value))
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
/*static*/
|
|
bool Options::readInt(const std::string& string, int& value) {
|
|
if (string == "true" || string == "YES") { value = 1; return true; }
|
|
if (string == "false" || string == "NO") { value = 0; return true; }
|
|
#ifdef _WIN32
|
|
if (sscanf_s(string.c_str(), "%d", &value))
|
|
return true;
|
|
#else
|
|
if (sscanf(string.c_str(), "%d", &value))
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
/*static*/
|
|
bool Options::readBool(const std::string& string, bool& value) {
|
|
std::string s = Util::stringTrim(string);
|
|
if (string == "true" || string == "1" || string == "YES") { value = true; return true; }
|
|
if (string == "false" || string == "0" || string == "NO") { value = false; return true; }
|
|
return false;
|
|
}
|
|
|
|
void Options::notifyOptionUpdate( const Option* option, bool value ) {
|
|
minecraft->optionUpdated(option, value);
|
|
}
|
|
|
|
void Options::notifyOptionUpdate( const Option* option, float value ) {
|
|
minecraft->optionUpdated(option, value);
|
|
}
|
|
|
|
void Options::notifyOptionUpdate( const Option* option, int value ) {
|
|
minecraft->optionUpdated(option, value);
|
|
}
|