mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 04:31:34 -10:00
* read access to controls * Early draft of checking keypresses in scpui * detangle some code and prepare it for API usage * API access to the core methods required * move these checks into the UI methods * comment * fix bugs * be smarter * Need this stuff, too * some more presets work * unify func naming scheme * cleanup and clarifications * get detect keypress working * allow searching and creating new presets based on current controls * address feedback * return nil if no preset is matched * use the builtin methods which do the same thing, but slightly cleaner * typo
243 lines
5.2 KiB
C++
243 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#include "cfile/cfile.h"
|
|
#include "controlconfig/controlsconfig.h"
|
|
#include "globalincs/pstypes.h"
|
|
#include "globalincs/vmallocator.h"
|
|
|
|
#include <jansson.h>
|
|
|
|
/** API for saving and loading player custom bindings, known as Presets
|
|
|
|
Init. If the player/preset dir doesn't exist. Create it, and print a help.txt with all enums (as strings) to label
|
|
the button names and action names.
|
|
|
|
Example output:
|
|
{
|
|
"actions": {
|
|
"TARGET_NEXT": {
|
|
"first": {
|
|
"cid": 0,
|
|
"flags": 0,
|
|
"btn": 0
|
|
},
|
|
"second": {
|
|
"cid": 0,
|
|
"flags": 0,
|
|
"btn": 0
|
|
}
|
|
},
|
|
"TARGET_PREV" : {
|
|
"first": {
|
|
"cid": 0,
|
|
"flags": 0,
|
|
"btn": 0
|
|
},
|
|
"second": {
|
|
"cid": 0,
|
|
"flags": 0,
|
|
"btn": 0
|
|
}
|
|
},
|
|
},
|
|
"version": 0
|
|
}
|
|
|
|
|
|
*/
|
|
namespace io {
|
|
namespace presets {
|
|
|
|
static const unsigned int PST_VERSION = 0;
|
|
static const unsigned int PST_FILE_ID = 0x5f545350; // "PST_" in file
|
|
|
|
enum class Section {
|
|
Invalid = -1,
|
|
Unnamed = 0,
|
|
|
|
// arrays
|
|
Actions,
|
|
|
|
// subsections
|
|
Primary,
|
|
Secondary
|
|
};
|
|
|
|
class PresetFileHandler {
|
|
public:
|
|
PresetFileHandler(CFILE* cfp, bool reading);
|
|
~PresetFileHandler();
|
|
|
|
/**
|
|
* begins writing to a section using the presets::Section as its name
|
|
* @param[in] s id of the section
|
|
*/
|
|
void beginSectionWrite(presets::Section s);
|
|
|
|
/**
|
|
* begins reading a section, if it exists
|
|
* @param[in] s id of the section
|
|
*/
|
|
bool beginSectionRead(presets::Section s);
|
|
|
|
/**
|
|
* Begins writing to an array using the presets::Section as its name
|
|
*
|
|
* @param[in] s id of the array
|
|
*/
|
|
void beginArrayWrite(presets::Section s);
|
|
|
|
/**
|
|
* Begins reading from an array
|
|
* @param[int] s id of the array
|
|
* @param[out] size the size of the array
|
|
*/
|
|
bool beginArrayRead(presets::Section s, size_t &size);
|
|
|
|
/**
|
|
* ends writing to a section
|
|
*/
|
|
void endSectionWrite();
|
|
|
|
/**
|
|
* ends reading a section
|
|
*/
|
|
void endSectionRead();
|
|
|
|
/**
|
|
* ends writing to an array.
|
|
*/
|
|
void endArrayWrite();
|
|
|
|
/**
|
|
* ends reading from an array
|
|
*/
|
|
void endArrayRead();
|
|
|
|
/**
|
|
* Writes a string with the given key name
|
|
*/
|
|
void writeString(const char* key, SCP_string s);
|
|
|
|
/**
|
|
* Reads a string with the given key name
|
|
*/
|
|
SCP_string readString(const char* key);
|
|
|
|
/**
|
|
* Writes an int with the given key name
|
|
*/
|
|
void writeInt(const char* key, int val);
|
|
|
|
/**
|
|
* Reads an int with the given key name
|
|
*/
|
|
int readInt(const char* key);
|
|
|
|
/**
|
|
* For writing, Flushes the buffers and dumps to file
|
|
*/
|
|
void flush();
|
|
|
|
/**
|
|
* Advances the array parser to the next element
|
|
*/
|
|
void nextArrayElement();
|
|
|
|
private:
|
|
CFILE* _cfp = nullptr;
|
|
|
|
json_t* _rootObj = nullptr;
|
|
|
|
json_t* _currentEl = nullptr;
|
|
|
|
/**
|
|
* BufferStack of all json elements being read/written
|
|
*/
|
|
SCP_vector<json_t*> _elementStack;
|
|
|
|
/**
|
|
* Stack to keep track of the heirachy/nesting. Back is immediate parent, Front is root
|
|
*/
|
|
SCP_vector<void*> _parentStack;
|
|
|
|
size_t _arrayIndex = INVALID_SIZE;
|
|
|
|
//void* _sectionIterator = nullptr; //!< Pointer to the current section/array we're in
|
|
|
|
private:
|
|
/**
|
|
* Pushes an element onto the elementStack
|
|
*/
|
|
void pushElement(json_t* el);
|
|
|
|
/**
|
|
* Pops an element off the elementStack
|
|
*/
|
|
json_t * popElement();
|
|
|
|
/**
|
|
* Used for optionals, checks if an element exists with the given name
|
|
* @return True if the element exists
|
|
* @return False otherwise
|
|
*/
|
|
bool exists(const char* name);
|
|
|
|
/**
|
|
* Throws an error if an element with the given name does not exist
|
|
*/
|
|
void ensureExists(const char* name);
|
|
|
|
/**
|
|
* Throws an error if an element with the given name exists
|
|
*/
|
|
void ensureNotExists(const char* name);
|
|
};
|
|
|
|
} // namespace presets
|
|
} // namespace io
|
|
|
|
/**
|
|
* @brief Saves the given preset to file.
|
|
* @param[in] preset The preset to save
|
|
* @param[in] overwrite If true, overwrite existing preset file which have the same name as the given preset
|
|
*
|
|
* @returns True if successful, or
|
|
* @returns False Preset does not have a name, or
|
|
* @returns False Preset file exists and overwrite == false, or
|
|
* @returns False Preset file .JSON could not be written
|
|
*/
|
|
bool save_preset_file(CC_preset preset, bool overwrite);
|
|
|
|
/**
|
|
* @brief Deletes the given preset to file.
|
|
* @param[in] preset The preset to delete
|
|
*
|
|
* @returns True if successful, or
|
|
* @returns False Preset is default, or
|
|
* @returns False Preset file is the currently selected preset
|
|
*/
|
|
bool delete_preset_file(CC_preset preset);
|
|
|
|
/**
|
|
* @brief Loads in all preset .json files from 'players/presets'
|
|
* @details If a preset file is unique, it is loaded into the game and available for use by the player. However, if
|
|
* a preset is a duplicate of another preset, it is ignored, and the player is warned of it
|
|
*
|
|
* @param[in] clone Used to check if we just cloned a particular preset and allows just that clone in without warning
|
|
*/
|
|
void load_preset_files(SCP_string clone = "");
|
|
|
|
/**
|
|
* @brief Checks if the given preset is a duplicate within Control_config_presets vector
|
|
* @returns iterator to the duplicate if found, or
|
|
* @returns iterator to Control_config_presets.end() otherwise
|
|
*/
|
|
SCP_vector<CC_preset>::iterator preset_find_duplicate(const CC_preset& new_preset);
|
|
|
|
|
|
/**
|
|
* @brief Returns true if a preset file with the given name exists.
|
|
*/
|
|
bool preset_file_exists(SCP_string name);
|