From 3644ddc02f237d0e416c4bb392cee2490d6ebe1f Mon Sep 17 00:00:00 2001 From: olebeck <31539311+olebeck@users.noreply.github.com> Date: Sun, 10 Aug 2025 12:25:55 +0200 Subject: [PATCH] use SceAppSettings instead of custom ui --- CONFIG/vita/.gitignore | 1 - CONFIG/vita/CMakeLists.txt | 46 +- CONFIG/vita/cxml/config_plugin.xml | 276 +---- CONFIG/vita/cxml/locale/en.xml | 69 +- CONFIG/vita/cxml/settings.xml | 45 + CONFIG/vita/cxml/textures/shark.png | Bin 15334 -> 0 bytes CONFIG/vita/cxml/textures/tex_settings_bg.gim | Bin 9936 -> 0 bytes CONFIG/vita/include/fios2.h | 136 +++ CONFIG/vita/include/pafinc.h | 4 + CONFIG/vita/include/scetypes.h | 0 CONFIG/vita/iniparser_paf/src/dictionary.c | 381 +++++++ CONFIG/vita/iniparser_paf/src/dictionary.h | 170 ++++ CONFIG/vita/iniparser_paf/src/iniparser.c | 958 ++++++++++++++++++ CONFIG/vita/iniparser_paf/src/iniparser.h | 446 ++++++++ CONFIG/vita/iniparser_paf/src/pafstd.h | 44 + CONFIG/vita/src/app.cpp | 414 +++++++- CONFIG/vita/src/main.cpp | 9 +- 17 files changed, 2651 insertions(+), 348 deletions(-) delete mode 100644 CONFIG/vita/.gitignore create mode 100644 CONFIG/vita/cxml/settings.xml delete mode 100644 CONFIG/vita/cxml/textures/shark.png delete mode 100644 CONFIG/vita/cxml/textures/tex_settings_bg.gim create mode 100644 CONFIG/vita/include/fios2.h create mode 100644 CONFIG/vita/include/pafinc.h create mode 100644 CONFIG/vita/include/scetypes.h create mode 100644 CONFIG/vita/iniparser_paf/src/dictionary.c create mode 100644 CONFIG/vita/iniparser_paf/src/dictionary.h create mode 100644 CONFIG/vita/iniparser_paf/src/iniparser.c create mode 100644 CONFIG/vita/iniparser_paf/src/iniparser.h create mode 100644 CONFIG/vita/iniparser_paf/src/pafstd.h diff --git a/CONFIG/vita/.gitignore b/CONFIG/vita/.gitignore deleted file mode 100644 index f3d6549d..00000000 --- a/CONFIG/vita/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build/ \ No newline at end of file diff --git a/CONFIG/vita/CMakeLists.txt b/CONFIG/vita/CMakeLists.txt index ff3f500f..cb76332a 100644 --- a/CONFIG/vita/CMakeLists.txt +++ b/CONFIG/vita/CMakeLists.txt @@ -12,6 +12,27 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(ScePaf_External) +add_subdirectory(SceIniFileProcessor) + +add_library(iniparser_paf + iniparser_paf/src/dictionary.c + iniparser_paf/src/iniparser.c +) + +target_link_libraries(iniparser_paf + ScePafStdc_stub + SceLibKernel_stub + SceLibc_stub +) + +target_include_directories(iniparser_paf PUBLIC + iniparser_paf/src/ +) + +target_compile_options(iniparser_paf PRIVATE + -Wl,-q -Wall -fno-builtin -fshort-wchar -Wno-unused-function -Wno-sign-compare +) + add_executable(isle-config src/app.cpp src/main.cpp @@ -22,7 +43,7 @@ set_target_properties(isle-config PROPERTIES ) target_compile_options(isle-config PRIVATE - -fno-rtti -fno-exceptions -Wl,-q -Wall -fno-builtin -fshort-wchar -Wno-unused-function -Wno-sign-compare + -fno-rtti -fno-exceptions -Wl,-q -Wall -fno-builtin -fshort-wchar -Wno-unused-function -Wno-sign-compare -fno-use-cxa-atexit ) target_link_options(isle-config PRIVATE @@ -39,16 +60,23 @@ target_link_libraries(isle-config PRIVATE ScePafWidget_stub ScePafCommon_stub ScePafStdc_stub + SceAppSettings_stub + SceFios2_stub + + #Isle::iniparser + iniparser_paf ) -block() - vita_create_self(isle-config.self isle-config - CONFIG exports.yml - UNSAFE - STRIPPED - REL_OPTIMIZE - ) -endblock() +target_include_directories(isle-config PUBLIC + include +) + +vita_create_self(isle-config.self isle-config + CONFIG exports.yml + UNSAFE + STRIPPED + REL_OPTIMIZE +) include(${scepaf_external_SOURCE_DIR}/rco.cmake) make_rco(cxml/config_plugin.xml config_plugin.rco) diff --git a/CONFIG/vita/cxml/config_plugin.xml b/CONFIG/vita/cxml/config_plugin.xml index b0ea26d9..2f1df305 100644 --- a/CONFIG/vita/cxml/config_plugin.xml +++ b/CONFIG/vita/cxml/config_plugin.xml @@ -1,265 +1,16 @@ - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +--> - +--> - - - - - - - - - - \ No newline at end of file + diff --git a/CONFIG/vita/cxml/locale/en.xml b/CONFIG/vita/cxml/locale/en.xml index 79bb95af..9e5337eb 100644 --- a/CONFIG/vita/cxml/locale/en.xml +++ b/CONFIG/vita/cxml/locale/en.xml @@ -1,38 +1,51 @@ - - - - + + + + + + - - - + + + + + - + + + + + + - - - - + + + + - - - + + + + - - + + - - - - - - + + + + + + - + + + - - - - \ No newline at end of file + + + + + diff --git a/CONFIG/vita/cxml/settings.xml b/CONFIG/vita/cxml/settings.xml new file mode 100644 index 00000000..2271532e --- /dev/null +++ b/CONFIG/vita/cxml/settings.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CONFIG/vita/cxml/textures/shark.png b/CONFIG/vita/cxml/textures/shark.png deleted file mode 100644 index 58b96386644318f0f0de9fb705508bfe1012c882..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15334 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 diff --git a/CONFIG/vita/cxml/textures/tex_settings_bg.gim b/CONFIG/vita/cxml/textures/tex_settings_bg.gim deleted file mode 100644 index ee68e0ee3d0bfa9b79216d7f78250ff071349263..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9936 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 diff --git a/CONFIG/vita/include/fios2.h b/CONFIG/vita/include/fios2.h new file mode 100644 index 00000000..11c8133e --- /dev/null +++ b/CONFIG/vita/include/fios2.h @@ -0,0 +1,136 @@ +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct SceFiosBuffer { + void *pPtr; + size_t length; +} SceFiosBuffer; + +#define SCE_FIOS_THREAD_TYPES 3 + +typedef struct SceFiosParams +{ + uint32_t initialized : 1; + uint32_t paramsSize : 15; + uint32_t pathMax : 16; + uint32_t profiling; + uint32_t ioThreadCount; + uint32_t threadsPerScheduler; + uint32_t extraFlag1 : 1; + uint32_t extraFlags : 31; + uint32_t maxChunk; + uint8_t maxDecompressorThreadCount; + uint8_t reserved1; + uint8_t reserved2; + uint8_t reserved3; + intptr_t reserved4; + intptr_t reserved5; + SceFiosBuffer opStorage; + SceFiosBuffer fhStorage; + SceFiosBuffer dhStorage; + SceFiosBuffer chunkStorage; + void* pVprintf; + void* pMemcpy; + void* pProfileCallback; + int threadPriority[SCE_FIOS_THREAD_TYPES]; + int threadAffinity[SCE_FIOS_THREAD_TYPES]; + int threadStackSize[SCE_FIOS_THREAD_TYPES]; +} SceFiosParams; + +#define SCE_KERNEL_HIGHEST_PRIORITY_USER (64) +#define SCE_KERNEL_LOWEST_PRIORITY_USER (191) + +#define SCE_FIOS_IO_THREAD_DEFAULT_PRIORITY (SCE_KERNEL_HIGHEST_PRIORITY_USER+2) +#define SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_PRIORITY (SCE_KERNEL_LOWEST_PRIORITY_USER-2) +#define SCE_FIOS_CALLBACK_THREAD_DEFAULT_PRIORITY (SCE_KERNEL_HIGHEST_PRIORITY_USER+2) + +#define SCE_FIOS_THREAD_DEFAULT_AFFINITY SCE_KERNEL_CPU_MASK_USER_2 +#define SCE_FIOS_IO_THREAD_DEFAULT_AFFINITY SCE_FIOS_THREAD_DEFAULT_AFFINITY +#define SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_AFFINITY SCE_KERNEL_THREAD_CPU_AFFINITY_MASK_DEFAULT +#define SCE_FIOS_CALLBACK_THREAD_DEFAULT_AFFINITY SCE_FIOS_THREAD_DEFAULT_AFFINITY + +#define SCE_FIOS_IO_THREAD_DEFAULT_STACKSIZE (8*1024) +#define SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_STACKSIZE (16*1024) +#define SCE_FIOS_CALLBACK_THREAD_DEFAULT_STACKSIZE (8*1024) + +#define SCE_FIOS_PARAMS_INITIALIZER { 0, sizeof(SceFiosParams), 0, 0, \ + 2, 2, \ + 0, 0, \ + (256*1024), \ + 2, 0, 0, 0, 0, 0, \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \ + NULL, NULL, NULL, \ + { SCE_FIOS_IO_THREAD_DEFAULT_PRIORITY, SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_PRIORITY, SCE_FIOS_CALLBACK_THREAD_DEFAULT_PRIORITY }, \ + { SCE_FIOS_IO_THREAD_DEFAULT_AFFINITY, SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_AFFINITY, SCE_FIOS_CALLBACK_THREAD_DEFAULT_AFFINITY}, \ + { SCE_FIOS_IO_THREAD_DEFAULT_STACKSIZE, SCE_FIOS_DECOMPRESSOR_THREAD_DEFAULT_STACKSIZE, SCE_FIOS_CALLBACK_THREAD_DEFAULT_STACKSIZE}} + +#define SCE_FIOS_IO_THREAD 0 +#define SCE_FIOS_DECOMPRESSOR_THREAD 1 +#define SCE_FIOS_CALLBACK_THREAD 2 + +#define SCE_FIOS_FH_SIZE 80 +#define SCE_FIOS_DH_SIZE 80 +#define SCE_FIOS_OP_SIZE 168 +#define SCE_FIOS_CHUNK_SIZE 64 + +#define SCE_FIOS_ALIGN_UP(val,align) (((val) + ((align)-1)) & ~((align)-1)) + +#define SCE_FIOS_STORAGE_SIZE(num, size) \ + (((num) * (size)) + SCE_FIOS_ALIGN_UP(SCE_FIOS_ALIGN_UP((num), 8) / 8, 8)) + +#define SCE_FIOS_DH_STORAGE_SIZE(numDHs, pathMax) \ + SCE_FIOS_STORAGE_SIZE(numDHs, SCE_FIOS_DH_SIZE + pathMax) + +#define SCE_FIOS_FH_STORAGE_SIZE(numFHs,pathMax) \ + SCE_FIOS_STORAGE_SIZE(numFHs, SCE_FIOS_FH_SIZE + pathMax) + +#define SCE_FIOS_OP_STORAGE_SIZE(numOps,pathMax) \ + SCE_FIOS_STORAGE_SIZE(numOps, SCE_FIOS_OP_SIZE + pathMax) + +#define SCE_FIOS_CHUNK_STORAGE_SIZE(numChunks) \ + SCE_FIOS_STORAGE_SIZE(numChunks, SCE_FIOS_CHUNK_SIZE) + +int sceFiosInitialize(SceFiosParams* params); + + +typedef int64_t SceFiosTime; + +typedef int32_t SceFiosHandle; + +typedef SceFiosHandle SceFiosFH; + +typedef struct SceFiosOpenParams +{ + uint32_t openFlags:16; + uint32_t opFlags:16; + uint32_t reserved; + SceFiosBuffer buffer; +} SceFiosOpenParams; + +typedef struct SceFiosOpAttr +{ + SceFiosTime deadline; + void* pCallback; + void * pCallbackContext; + int32_t priority : 8; + uint32_t opflags : 24; + uint32_t userTag; + void * userPtr; + void * pReserved; +} SceFiosOpAttr; + + +int sceFiosFHOpenWithModeSync(const SceFiosOpAttr *pAttr, SceFiosFH *pOutFH, const char *pPath, const SceFiosOpenParams *pOpenParams, int32_t nativeMode); + + + +#ifdef __cplusplus +} +#endif diff --git a/CONFIG/vita/include/pafinc.h b/CONFIG/vita/include/pafinc.h new file mode 100644 index 00000000..5b4addf9 --- /dev/null +++ b/CONFIG/vita/include/pafinc.h @@ -0,0 +1,4 @@ +// clang-format off +#include +#include +// clang-format on \ No newline at end of file diff --git a/CONFIG/vita/include/scetypes.h b/CONFIG/vita/include/scetypes.h new file mode 100644 index 00000000..e69de29b diff --git a/CONFIG/vita/iniparser_paf/src/dictionary.c b/CONFIG/vita/iniparser_paf/src/dictionary.c new file mode 100644 index 00000000..38102dfa --- /dev/null +++ b/CONFIG/vita/iniparser_paf/src/dictionary.c @@ -0,0 +1,381 @@ +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.c + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ +#include "dictionary.h" + +#include "pafstd.h" + +/** Minimal allocated number of entries in a dictionary */ +#define DICTMINSZ 128 + +/*--------------------------------------------------------------------------- + Private functions + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char * xstrdup(const char * s) +{ + char * t ; + size_t len ; + if (!s) + return NULL ; + + len = strlen(s) + 1 ; + t = (char*) malloc(len) ; + if (t) { + memcpy(t, s, len) ; + } + return t ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Double the size of the dictionary + @param d Dictionary to grow + @return This function returns non-zero in case of failure + */ +/*--------------------------------------------------------------------------*/ +static int dictionary_grow(dictionary * d) +{ + char ** new_val ; + char ** new_key ; + unsigned * new_hash ; + + new_val = (char**) calloc(d->size * 2, sizeof *d->val); + new_key = (char**) calloc(d->size * 2, sizeof *d->key); + new_hash = (unsigned*) calloc(d->size * 2, sizeof *d->hash); + if (!new_val || !new_key || !new_hash) { + /* An allocation failed, leave the dictionary unchanged */ + if (new_val) + free(new_val); + if (new_key) + free(new_key); + if (new_hash) + free(new_hash); + return -1 ; + } + /* Initialize the newly allocated space */ + memcpy(new_val, d->val, d->size * sizeof(char *)); + memcpy(new_key, d->key, d->size * sizeof(char *)); + memcpy(new_hash, d->hash, d->size * sizeof(unsigned)); + /* Delete previous data */ + free(d->val); + free(d->key); + free(d->hash); + /* Actually update the dictionary */ + d->size *= 2 ; + d->val = new_val; + d->key = new_key; + d->hash = new_hash; + return 0 ; +} + +/*--------------------------------------------------------------------------- + Function codes + ---------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char * key) +{ + size_t len ; + unsigned hash ; + size_t i ; + + if (!key) + return 0 ; + + len = strlen(key); + for (hash=0, i=0 ; i>6) ; + } + hash += (hash <<3); + hash ^= (hash >>11); + hash += (hash <<15); + return hash ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary object. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*-------------------------------------------------------------------------*/ +dictionary * dictionary_new(size_t size) +{ + dictionary * d ; + + /* If no size was specified, allocate space for DICTMINSZ */ + if (sizesize = size ; + d->val = (char**) calloc(size, sizeof *d->val); + d->key = (char**) calloc(size, sizeof *d->key); + d->hash = (unsigned*) calloc(size, sizeof *d->hash); + if (!d->size || !d->val || !d->hash) { + free((void *) d->size); + free((void *) d->val); + free((void *) d->hash); + free(d); + d = NULL; + } + } + return d ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * d) +{ + size_t i ; + + if (d==NULL) return ; + for (i=0 ; isize ; i++) { + if (d->key[i]!=NULL) + free(d->key[i]); + if (d->val[i]!=NULL) + free(d->val[i]); + } + free(d->val); + free(d->key); + free(d->hash); + free(d); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * dictionary_get(const dictionary * d, const char * key, const char * def) +{ + unsigned hash ; + size_t i ; + + if(d == NULL || key == NULL) + return def ; + + hash = dictionary_hash(key); + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + return d->val[i] ; + } + } + } + return def ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * d, const char * key, const char * val) +{ + size_t i ; + unsigned hash ; + + if (d==NULL || key==NULL) return -1 ; + + /* Compute hash for this key */ + hash = dictionary_hash(key) ; + /* Find if value is already in dictionary */ + if (d->n>0) { + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (hash==d->hash[i]) { /* Same hash value */ + if (!strcmp(key, d->key[i])) { /* Same key */ + /* Found a value: modify and return */ + if (d->val[i]!=NULL) + free(d->val[i]); + d->val[i] = (val ? xstrdup(val) : NULL); + /* Value has been modified: return */ + return 0 ; + } + } + } + } + /* Add a new value */ + /* See if dictionary needs to grow */ + if (d->n==d->size) { + /* Reached maximum size: reallocate dictionary */ + if (dictionary_grow(d) != 0) + return -1; + } + + /* Insert key in the first empty slot. Start at d->n and wrap at + d->size. Because d->n < d->size this will necessarily + terminate. */ + for (i=d->n ; d->key[i] ; ) { + if(++i == d->size) i = 0; + } + /* Copy key */ + d->key[i] = xstrdup(key); + d->val[i] = (val ? xstrdup(val) : NULL) ; + d->hash[i] = hash; + d->n ++ ; + return 0 ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, const char * key) +{ + unsigned hash ; + size_t i ; + + if (key == NULL || d == NULL) { + return; + } + + hash = dictionary_hash(key); + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + /* Found key */ + break ; + } + } + } + if (i>=d->size) + /* Key not found */ + return ; + + free(d->key[i]); + d->key[i] = NULL ; + if (d->val[i]!=NULL) { + free(d->val[i]); + d->val[i] = NULL ; + } + d->hash[i] = 0 ; + d->n -- ; + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(const dictionary * d, FILE * out) +{ + size_t i ; + + if (d==NULL || out==NULL) return ; + if (d->n<1) { + fprintf(out, "empty dictionary\n"); + return ; + } + for (i=0 ; isize ; i++) { + if (d->key[i]) { + fprintf(out, "%20s\t[%s]\n", + d->key[i], + d->val[i] ? d->val[i] : "UNDEF"); + } + } + return ; +} diff --git a/CONFIG/vita/iniparser_paf/src/dictionary.h b/CONFIG/vita/iniparser_paf/src/dictionary.h new file mode 100644 index 00000000..31f639c5 --- /dev/null +++ b/CONFIG/vita/iniparser_paf/src/dictionary.h @@ -0,0 +1,170 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.h + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include "pafstd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + New types + ---------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dictionary object + + This object contains a list of string/string associations. Each + association is identified by a unique string key. Looking up values + in the dictionary is speeded up by the use of a (hopefully collision-free) + hash function. + */ +/*-------------------------------------------------------------------------*/ +typedef struct _dictionary_ { + unsigned n ; /** Number of entries in dictionary */ + size_t size ; /** Storage size */ + char ** val ; /** List of string values */ + char ** key ; /** List of string keys */ + unsigned * hash ; /** List of hash values for keys */ +} dictionary ; + + +/*--------------------------------------------------------------------------- + Function prototypes + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char * key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary object. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(size_t size); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * vd); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * dictionary_get(const dictionary * d, const char * key, const char * def); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * vd, const char * key, const char * val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, const char * key); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(const dictionary * d, FILE * out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/CONFIG/vita/iniparser_paf/src/iniparser.c b/CONFIG/vita/iniparser_paf/src/iniparser.c new file mode 100644 index 00000000..222ebab9 --- /dev/null +++ b/CONFIG/vita/iniparser_paf/src/iniparser.c @@ -0,0 +1,958 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.c + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ +/*---------------------------- Includes ------------------------------------*/ +#include +#include "pafstd.h" +#include +#include +#include "iniparser.h" + +/*---------------------------- Defines -------------------------------------*/ +#define ASCIILINESZ (1024) +#define INI_INVALID_KEY ((char*)-1) + +/*--------------------------------------------------------------------------- + Private to this module + ---------------------------------------------------------------------------*/ +/** + * This enum stores the status for each parsed line (internal use only). + */ +typedef enum _line_status_ { + LINE_UNPROCESSED, + LINE_ERROR, + LINE_EMPTY, + LINE_COMMENT, + LINE_SECTION, + LINE_VALUE +} line_status ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Convert a string to lowercase. + @param in String to convert. + @param out Output buffer. + @param len Size of the out buffer. + @return ptr to the out buffer or NULL if an error occured. + + This function convert a string into lowercase. + At most len - 1 elements of the input string will be converted. + */ +/*--------------------------------------------------------------------------*/ +static const char * strlwc(const char * in, char *out, unsigned len) +{ + unsigned i ; + + if (in==NULL || out == NULL || len==0) return NULL ; + i=0 ; + while (in[i] != '\0' && i < len-1) { + out[i] = (char)tolower((int)in[i]); + i++ ; + } + out[i] = '\0'; + return out ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char * xstrdup(const char * s) +{ + char * t ; + size_t len ; + if (!s) + return NULL ; + + len = strlen(s) + 1 ; + t = (char*) malloc(len) ; + if (t) { + memcpy(t, s, len) ; + } + return t ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Remove blanks at the beginning and the end of a string. + @param str String to parse and alter. + @return unsigned New size of the string. + */ +/*--------------------------------------------------------------------------*/ +static unsigned strstrip(char * s) +{ + char *last = NULL ; + char *dest = s; + + if (s==NULL) return 0; + + last = s + strlen(s); + while (isspace((unsigned char)*s) && *s) s++; + while (last > s) { + if (!isspace((unsigned char)*(last-1))) + break ; + last -- ; + } + *last = (char)0; + + memmove(dest,s,last - s + 1); + return last - s; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Default error callback for iniparser: wraps `fprintf(stderr, ...)`. + */ +/*--------------------------------------------------------------------------*/ +static int default_error_callback(const char *format, ...) +{ + int ret = 0; + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + return ret; +} + +static int (*iniparser_error_callback)(const char*, ...) = default_error_callback; + +/*-------------------------------------------------------------------------*/ +/** + @brief Configure a function to receive the error messages. + @param errback Function to call. + + By default, the error will be printed on stderr. If a null pointer is passed + as errback the error callback will be switched back to default. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_set_error_callback(int (*errback)(const char *, ...)) +{ + if (errback) { + iniparser_error_callback = errback; + } else { + iniparser_error_callback = default_error_callback; + } +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getnsec(const dictionary * d) +{ + size_t i ; + int nsec ; + + if (d==NULL) return -1 ; + nsec=0 ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + nsec ++ ; + } + } + return nsec ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +const char * iniparser_getsecname(const dictionary * d, int n) +{ + size_t i ; + int foundsec ; + + if (d==NULL || n<0) return NULL ; + foundsec=0 ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + foundsec++ ; + if (foundsec>n) + break ; + } + } + if (foundsec<=n) { + return NULL ; + } + return d->key[i] ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(const dictionary * d, FILE * f) +{ + size_t i ; + + if (d==NULL || f==NULL) return ; + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + if (d->val[i]!=NULL) { + fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); + } else { + fprintf(f, "[%s]=UNDEF\n", d->key[i]); + } + } + return ; +} + +static void escape_value(char *escaped, char *value) { + char c; + int v = 0; + int e = 0; + + if(!escaped || !value) + return; + + while((c = value[v]) != '\0') { + if(c == '\\' || c == '"') { + escaped[e] = '\\'; + e++; + } + escaped[e] = c; + v++; + e++; + } + escaped[e] = '\0'; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump_ini(const dictionary * d, FILE * f) +{ + size_t i ; + size_t nsec ; + const char * secname ; + char escaped[(ASCIILINESZ * 2) + 2] = ""; + + if (d==NULL || f==NULL) return ; + + nsec = iniparser_getnsec(d); + if (nsec<1) { + /* No section in file: dump all keys as they are */ + for (i=0 ; isize ; i++) { + if (d->key[i]==NULL) + continue ; + escape_value(escaped, d->val[i]); + fprintf(f, "%s = \"%s\"\n", d->key[i], escaped); + } + return ; + } + for (i=0 ; i sizeof(keym)) return; + + seclen = (int)strlen(s); + fprintf(f, "\n[%s]\n", s); + sprintf(keym, "%s:", s); + for (j=0 ; jsize ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) { + escape_value(escaped, d->val[j]); + fprintf(f, "%-30s = \"%s\"\n", d->key[j]+seclen+1, escaped); + } + } + fprintf(f, "\n"); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(const dictionary * d, const char * s) +{ + int seclen, nkeys ; + char keym[ASCIILINESZ+1]; + size_t j ; + + nkeys = 0; + + if (d==NULL) return nkeys; + if (! iniparser_find_entry(d, s)) return nkeys; + + seclen = (int)strlen(s); + strlwc(s, keym, sizeof(keym)); + keym[seclen] = ':'; + + for (j=0 ; jsize ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) + nkeys++; + } + + return nkeys; + +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @param keys Already allocated array to store the keys in + @return The pointer passed as `keys` argument or NULL in case of error + + This function queries a dictionary and finds all keys in a given section. + The keys argument should be an array of pointers which size has been + determined by calling `iniparser_getsecnkeys` function prior to this one. + + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + */ +/*--------------------------------------------------------------------------*/ +const char ** iniparser_getseckeys(const dictionary * d, const char * s, const char ** keys) +{ + size_t i, j, seclen ; + char keym[ASCIILINESZ+1]; + + if (d==NULL || keys==NULL) return NULL; + if (! iniparser_find_entry(d, s)) return NULL; + + seclen = strlen(s); + strlwc(s, keym, sizeof(keym)); + keym[seclen] = ':'; + + i = 0; + + for (j=0 ; jsize ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) { + keys[i] = d->key[j]; + i++; + } + } + + return keys; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * iniparser_getstring(const dictionary * d, const char * key, const char * def) +{ + const char * lc_key ; + const char * sval ; + char tmp_str[ASCIILINESZ+1]; + + if (d==NULL || key==NULL) + return def ; + + lc_key = strlwc(key, tmp_str, sizeof(tmp_str)); + sval = dictionary_get(d, lc_key, def); + return sval ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return long integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return strtol(str, NULL, 0); +} + +int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return strtoimax(str, NULL, 0); +} + +uint64_t iniparser_getuint64(const dictionary * d, const char * key, uint64_t notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return strtoumax(str, NULL, 0); +} + + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary * d, const char * key, int notfound) +{ + return (int)iniparser_getlongint(d, key, notfound); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(const dictionary * d, const char * key, double notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return atof(str); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(const dictionary * d, const char * key, int notfound) +{ + int ret ; + const char * c ; + + c = iniparser_getstring(d, key, INI_INVALID_KEY); + if (c==NULL || c==INI_INVALID_KEY) return notfound ; + if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { + ret = 1 ; + } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { + ret = 0 ; + } else { + ret = notfound ; + } + return ret; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(const dictionary * ini, const char * entry) +{ + int found=0 ; + if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { + found = 1 ; + } + return found ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, the entry is created. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, const char * entry, const char * val) +{ + char tmp_key[ASCIILINESZ+1] = {0}; + char tmp_val[ASCIILINESZ+1] = {0}; + size_t len; + + if(val) { + len = strlen(val); + len = len > ASCIILINESZ ? ASCIILINESZ : len; + memcpy(tmp_val, val, len) ; + val = tmp_val; + } + return dictionary_set(ini, strlwc(entry, tmp_key, sizeof(tmp_key)), val); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, const char * entry) +{ + char tmp_str[ASCIILINESZ+1]; + dictionary_unset(ini, strlwc(entry, tmp_str, sizeof(tmp_str))); +} + +static void parse_quoted_value(char *value, char quote) { + char c; + char *quoted; + int q = 0, v = 0; + int esc = 0; + + if(!value) + return; + + quoted = xstrdup(value); + + if(!quoted) { + iniparser_error_callback("iniparser: memory allocation failure\n"); + goto end_of_value; + } + + while((c = quoted[q]) != '\0') { + if(!esc) { + if(c == '\\') { + esc = 1; + q++; + continue; + } + + if(c == quote) { + goto end_of_value; + } + } + esc = 0; + value[v] = c; + v++; + q++; + } +end_of_value: + value[v] = '\0'; + free(quoted); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Load a single line from an INI file + @param input_line Input line, may be concatenated multi-line input + @param section Output space to store section + @param key Output space to store key + @param value Output space to store value + @return line_status value + */ +/*--------------------------------------------------------------------------*/ +static line_status iniparser_line( + const char * input_line, + char * section, + char * key, + char * value) +{ + line_status sta ; + char * line = NULL; + size_t len ; + int d_quote; + + line = xstrdup(input_line); + len = strstrip(line); + + sta = LINE_UNPROCESSED ; + if (len<1) { + /* Empty line */ + sta = LINE_EMPTY ; + } else if (line[0]=='#' || line[0]==';') { + /* Comment line */ + sta = LINE_COMMENT ; + } else if (line[0]=='[' && line[len-1]==']') { + /* Section name without opening square bracket */ + sscanf(line, "[%[^\n]", section); + len = strlen(section); + /* Section name without closing square bracket */ + if(section[len-1] == ']') + { + section[len-1] = '\0'; + } + strstrip(section); + strlwc(section, section, len); + sta = LINE_SECTION ; + } else if ((d_quote = sscanf (line, "%[^=] = \"%[^\n]\"", key, value)) == 2 + || sscanf (line, "%[^=] = '%[^\n]'", key, value) == 2) { + /* Usual key=value with quotes, with or without comments */ + strstrip(key); + strlwc(key, key, len); + if(d_quote == 2) + parse_quoted_value(value, '"'); + else + parse_quoted_value(value, '\''); + /* Don't strip spaces from values surrounded with quotes */ + sta = LINE_VALUE ; + } else if (sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { + /* Usual key=value without quotes, with or without comments */ + strstrip(key); + strlwc(key, key, len); + strstrip(value); + /* + * sscanf cannot handle '' or "" as empty values + * this is done here + */ + if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { + value[0]=0 ; + } + sta = LINE_VALUE ; + } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 + || sscanf(line, "%[^=] %[=]", key, value) == 2) { + /* + * Special cases: + * key= + * key=; + * key=# + */ + strstrip(key); + strlwc(key, key, len); + value[0]=0 ; + sta = LINE_VALUE ; + } else { + /* Generate syntax error */ + sta = LINE_ERROR ; + } + + free(line); + return sta ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param in File to read. + @param ininame Name of the ini file to read (only used for nicer error messages) + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the file to be read. It returns a dictionary object that should not + be accessed directly, but through accessor functions instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load_file(FILE * in, const char * ininame) +{ + char line [ASCIILINESZ+1] ; + char section [ASCIILINESZ+1] ; + char key [ASCIILINESZ+1] ; + char tmp [(ASCIILINESZ * 2) + 2] ; + char val [ASCIILINESZ+1] ; + + int last=0 ; + int len ; + int lineno=0 ; + int errs=0; + int mem_err=0; + + dictionary * dict ; + + dict = dictionary_new(0) ; + if (!dict) { + return NULL ; + } + + memset(line, 0, ASCIILINESZ); + memset(section, 0, ASCIILINESZ); + memset(key, 0, ASCIILINESZ); + memset(val, 0, ASCIILINESZ); + last=0 ; + + while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { + lineno++ ; + len = (int)strlen(line)-1; + if (len<=0) + continue; + /* Safety check against buffer overflows */ + if (line[len]!='\n' && !feof(in)) { + iniparser_error_callback( + "iniparser: input line too long in %s (%d)\n", + ininame, + lineno); + dictionary_del(dict); + return NULL ; + } + /* Get rid of \n and spaces at end of line */ + while ((len>=0) && + ((line[len]=='\n') || (isspace((unsigned char)line[len])))) { + line[len]=0 ; + len-- ; + } + if (len < 0) { /* Line was entirely \n and/or spaces */ + len = 0; + } + /* Detect multi-line */ + if (line[len]=='\\') { + /* Multi-line value */ + last=len ; + continue ; + } else { + last=0 ; + } + switch (iniparser_line(line, section, key, val)) { + case LINE_EMPTY: + case LINE_COMMENT: + break ; + + case LINE_SECTION: + mem_err = dictionary_set(dict, section, NULL); + break ; + + case LINE_VALUE: + sprintf(tmp, "%s:%s", section, key); + mem_err = dictionary_set(dict, tmp, val); + break ; + + case LINE_ERROR: + iniparser_error_callback( + "iniparser: syntax error in %s (%d):\n-> %s\n", + ininame, + lineno, + line); + errs++ ; + break; + + default: + break ; + } + memset(line, 0, ASCIILINESZ); + last=0; + if (mem_err<0) { + iniparser_error_callback("iniparser: memory allocation failure\n"); + break ; + } + } + if (errs) { + dictionary_del(dict); + dict = NULL ; + } + return dict ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame) +{ + FILE * in ; + dictionary * dict ; + + if ((in=fopen(ininame, "r"))==NULL) { + iniparser_error_callback("iniparser: cannot open %s\n", ininame); + return NULL ; + } + + dict = iniparser_load_file(in, ininame); + fclose(in); + + return dict ; +} + + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d) +{ + dictionary_del(d); +} diff --git a/CONFIG/vita/iniparser_paf/src/iniparser.h b/CONFIG/vita/iniparser_paf/src/iniparser.h new file mode 100644 index 00000000..d8026a81 --- /dev/null +++ b/CONFIG/vita/iniparser_paf/src/iniparser.h @@ -0,0 +1,446 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.h + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _INIPARSER_H_ +#define _INIPARSER_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include "dictionary.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*/ +/** + @brief Configure a function to receive the error messages. + @param errback Function to call. + + By default, the error will be printed on stderr. If a null pointer is passed + as errback the error callback will be switched back to default. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_set_error_callback(int (*errback)(const char *, ...)); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ + +int iniparser_getnsec(const dictionary * d); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ + +const char * iniparser_getsecname(const dictionary * d, int n); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + + All values are quoted, these charecters are escaped: + + - ' : the quote character (e.g. "String with \"Quotes\"") + - \ : the backslash character (e.g. "C:\\tmp") + + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dump_ini(const dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dumpsection_ini(const dictionary * d, const char * s, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(const dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(const dictionary * d, const char * s); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @param keys Already allocated array to store the keys in + @return The pointer passed as `keys` argument or NULL in case of error + + This function queries a dictionary and finds all keys in a given section. + The keys argument should be an array of pointers which size has been + determined by calling `iniparser_getsecnkeys` function prior to this one. + + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + */ +/*--------------------------------------------------------------------------*/ +const char ** iniparser_getseckeys(const dictionary * d, const char * s, const char ** keys); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * iniparser_getstring(const dictionary * d, const char * key, const char * def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary * d, const char * key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int64_t + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtoimax(), see the associated man page for overflow + handling. + + This function is usefull on 32bit architectures where `long int` is only + 32bit. + */ +/*--------------------------------------------------------------------------*/ +int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an uint64_t + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtoumax(), see the associated man page for overflow + handling. + + This function is usefull on 32bit architectures where `long int` is only + 32bit. + */ +/*--------------------------------------------------------------------------*/ +uint64_t iniparser_getuint64(const dictionary * d, const char * key, uint64_t notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(const dictionary * d, const char * key, double notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(const dictionary * d, const char * key, int notfound); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, the entry is created. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, const char * entry, const char * val); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, const char * entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(const dictionary * ini, const char * entry) ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + Iff the value is a quoted string it supports some escape sequences: + + - \" or ' : the quote character + (e.g. 'String with "Quotes"' or "String with 'Quotes'") + - \ : the backslash character (e.g. "C:\tmp") + + Escape sequences always start with a backslash. Additional escape sequences + might be added in the future. Backslash characters must be escaped. Any other + sequence then those outlined above is invalid and may lead to unpredictable + results. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param in File to read. + @param ininame Name of the ini file to read (only used for nicer error messages) + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the file to be read. It returns a dictionary object that should not + be accessed directly, but through accessor functions instead. + + Iff the value is a quoted string it supports some escape sequences: + + - \" or ' : the quote character + (e.g. 'String with "Quotes"' or "String with 'Quotes'") + - \ : the backslash character (e.g. "C:\tmp") + + Escape sequences always start with a backslash. Additional escape sequences + might be added in the future. Backslash characters must be escaped. Any other + sequence then those outlined above is invalid and may lead to unpredictable + results. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load_file(FILE * in, const char * ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/CONFIG/vita/iniparser_paf/src/pafstd.h b/CONFIG/vita/iniparser_paf/src/pafstd.h new file mode 100644 index 00000000..469cd561 --- /dev/null +++ b/CONFIG/vita/iniparser_paf/src/pafstd.h @@ -0,0 +1,44 @@ +#ifndef __PAFSTD__ +#define __PAFSTD__ + +#include +#include +#include +#include +#include +#include +#include + +#define malloc sce_paf_malloc +#define memcpy sce_paf_memcpy +#define memset sce_paf_memset +#define memmove sce_paf_memmove +#define free sce_paf_free +#define calloc sce_paf_calloc + +// _ctype_ isnt called that in scelibc, so just stub the functions that are needed + +inline int _is_space(char c) { + return (c == ' ' || c == '\f' || c == '\n' || + c == '\r' || c == '\t' || c == '\v'); +} + +inline int _to_lower(int c) { + if (c >= 'A' && c <= 'Z') { + return c + ('a' - 'A'); + } + return c; +} + +inline int _is_digit(int c) { + return (c >= '0' && c <= '9'); +} + +#undef isspace +#undef tolower +#undef isdigit +#define isspace _is_space +#define tolower _to_lower +#define isdigit _is_digit + +#endif \ No newline at end of file diff --git a/CONFIG/vita/src/app.cpp b/CONFIG/vita/src/app.cpp index a636e3c0..8b31547a 100644 --- a/CONFIG/vita/src/app.cpp +++ b/CONFIG/vita/src/app.cpp @@ -1,55 +1,395 @@ -// clang-format off -#include -#include -// clang-format on +#include "pafinc.h" +#include #include +#include +#include +#include +#include + +#include "fios2.h" +#include + +const char* g_iniPath = "ux0:data/isledecomp/isle/isle.ini"; paf::Framework* g_fw; -paf::ui::Scene* g_rootPage; -paf::Plugin* g_plugin; +paf::Plugin* g_configPlugin; +sce::AppSettings* g_appSettings; +sce::AppSettings::Interface* g_appSetIf; -void loadPluginCB(paf::Plugin* plugin) -{ - g_plugin = plugin; - plugin->SetLocale(Locale_EN); - paf::Plugin::PageOpenParam pageOpenParam; - pageOpenParam.option = paf::Plugin::PageOption_None; - paf::ui::Scene* pScene = plugin->PageOpen("page_main", pageOpenParam); - g_rootPage = pScene; +struct Config { + paf::string m_base_path; + paf::string m_cd_path; + paf::string m_save_path; + int m_transition_type; + int m_texture_quality; + int m_model_quality; + int m_touch_scheme; + bool m_wide_view_angle; + bool m_music; + bool m_3d_sound; + bool m_haptic; + bool m_draw_cursor; + bool m_texture_load; + paf::string m_texture_path; + float m_max_lod; + int m_max_actors; + float m_frame_delta; - const auto saveAndExitButton = static_cast(pScene->FindChild("save_exit_button")); - const auto startAndExitButton = static_cast(pScene->FindChild("start_game_button")); - const auto exitButton = static_cast(pScene->FindChild("exit_button")); + void Init() { + m_frame_delta = 10.0f; + m_transition_type = 3; // 3: Mosaic + m_wide_view_angle = true; + m_music = true; + m_3d_sound = true; + m_haptic = true; + m_touch_scheme = 2; + m_texture_load = true; + m_texture_path = "/textures/"; + m_model_quality = 2; + m_texture_quality = 1; + m_max_lod = 3.5f; + m_max_actors = 20; + } + + void LoadIni() { + dictionary* dict = iniparser_load(g_iniPath); + if (!dict) { + dict = dictionary_new(0); + } + +#define GET_INT(x, name) x = iniparser_getint(dict, name, x) +#define GET_FLOAT(x, name) x = iniparser_getdouble(dict, name, x) +#define GET_STRING(x, name) x = iniparser_getstring(dict, name, x.c_str()); sceClibPrintf("%s: %s\n", name, x.c_str()) +#define GET_BOOLEAN(x, name) x = iniparser_getboolean(dict, name, x) + + GET_STRING(m_base_path, "isle:diskpath"); + GET_STRING(m_cd_path, "isle:cdpath"); + GET_STRING(m_save_path, "isle:savepath"); + + //m_display_bit_depth = iniparser_getint(dict, "isle:Display Bit Depth", -1); + //GET_BOOLEAN(m_flip_surfaces, "isle:Flip Surfaces"); + //GET_BOOLEAN(m_full_screen, "isle:Full Screen"); + //GET_BOOLEAN(m_exclusive_full_screen, "isle:Exclusive Full Screen"); + GET_INT(m_transition_type, "isle:Transition Type"); + GET_INT(m_touch_scheme, "isle:Touch Scheme"); + //GET_BOOLEAN(m_3d_video_ram, "isle:Back Buffers in Video RAM"); + GET_BOOLEAN(m_wide_view_angle, "isle:Wide View Angle"); + GET_BOOLEAN(m_3d_sound, "isle:3DSound"); + GET_BOOLEAN(m_draw_cursor, "isle:Draw Cursor"); + GET_INT(m_model_quality, "isle:Island Quality"); + GET_INT(m_texture_quality, "isle:Island Texture"); + //GET_BOOLEAN(m_use_joystick, "isle:UseJoystick"); + GET_BOOLEAN(m_haptic, "isle:Haptic"); + GET_BOOLEAN(m_music, "isle:Music"); + //GET_INT(m_joystick_index, "isle:JoystickIndex"); + GET_FLOAT(m_max_lod, "isle:Max LOD"); + GET_INT(m_max_actors, "isle:Max Allowed Extras"); + GET_BOOLEAN(m_texture_load, "extensions:texture loader"); + GET_STRING(m_texture_path, "texture loader:texture path"); + //GET_INT(m_aspect_ratio, "isle:Aspect Ratio"); + //GET_INT(m_x_res, "isle:Horizontal Resolution"); + //GET_INT(m_y_res, "isle:Vertical Resolution"); + GET_FLOAT(m_frame_delta, "isle:Frame Delta"); +#undef GET_INT +#undef GET_FLOAT +#undef GET_STRING +#undef GET_BOOLEAN + iniparser_freedict(dict); + } + + bool SaveIni() { + dictionary* dict = dictionary_new(0); + + char buffer[128]; +#define SetIniBool(NAME, VALUE) iniparser_set(dict, NAME, VALUE ? "true" : "false") +#define SetIniInt(NAME, VALUE) { \ + sceClibPrintf(buffer, "%d", VALUE); \ + iniparser_set(dict, NAME, buffer); \ + } +#define SetIniFloat(NAME, VALUE) { \ + sceClibPrintf(buffer, "%f", VALUE); \ + iniparser_set(dict, NAME, buffer); \ + } +#define SetString(NAME, VALUE) iniparser_set(dict, NAME, VALUE) + + SetIniInt("isle:Display Bit Depth", 32); + SetIniBool("isle:Flip Surfaces", false); + SetIniBool("isle:Full Screen", true); + SetIniBool("isle:Exclusive Full Screen", true); + SetIniBool("isle:Wide View Angle", true); // option? + + SetIniInt("isle:Transition Type", m_transition_type); + SetIniInt("isle:Touch Scheme", m_touch_scheme); + + SetIniBool("isle:3DSound", m_3d_sound); + SetIniBool("isle:Music", m_music); + SetIniBool("isle:Haptic", m_haptic); + + SetIniBool("isle:UseJoystick", true); + SetIniInt("isle:JoystickIndex", 0); + SetIniBool("isle:Draw Cursor", m_draw_cursor); + + SetIniBool("extensions:texture loader", m_texture_load); + SetString("texture loader:texture path", m_texture_path.c_str()); + + SetIniBool("isle:Back Buffers in Video RAM", true); + + SetIniInt("isle:Island Quality", m_model_quality); + SetIniInt("isle:Island Texture", m_texture_quality); + + SetIniFloat("isle:Max LOD", m_max_lod); + SetIniInt("isle:Max Allowed Extras", m_max_actors); + + SetIniInt("isle:Aspect Ratio", 0); + SetIniInt("isle:Horizontal Resolution", 640); + SetIniInt("isle:Vertical Resolution", 480); + SetIniFloat("isle:Frame Delta", 10.0f); + +#undef SetIniBool +#undef SetIniInt +#undef SetIniFloat +#undef SetString + + FILE* fd = fopen(g_iniPath, "w"); + if(fd) { + iniparser_dump_ini(dict, fd); + } + iniparser_freedict(dict); + + return true; + } + + void ToSettings(sce::AppSettings* appSettings) { + appSettings->SetString("data_path", this->m_base_path.c_str()); + appSettings->SetString("save_path", this->m_save_path.c_str()); + } + + void FromSettings(sce::AppSettings* appSettings) { + + } +}; + +Config g_config; + +paf::Plugin* load_config_plugin(paf::Framework* paf_fw) { + paf::Plugin::InitParam pluginParam; + pluginParam.name = "config_plugin"; + pluginParam.caller_name = "__main__"; + pluginParam.resource_file = "app0:/config_plugin.rco"; + pluginParam.init_func = NULL; + pluginParam.start_func = NULL; + pluginParam.stop_func = NULL; + pluginParam.exit_func = NULL; + paf::Plugin::LoadSync(pluginParam); + return paf_fw->FindPlugin("config_plugin"); } -int paf_main(void) +int load_app_settings_plugin() { + paf::Plugin::InitParam pluginParam; + sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BXCE); + sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_INI_FILE_PROCESSOR); + sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_COMMON_GUI_DIALOG); + + pluginParam.name = "app_settings_plugin"; + pluginParam.resource_file = "vs0:vsh/common/app_settings_plugin.rco"; + pluginParam.caller_name = "__main__"; + pluginParam.set_param_func = sce::AppSettings::PluginSetParamCB; + pluginParam.init_func = sce::AppSettings::PluginInitCB; + pluginParam.start_func = sce::AppSettings::PluginStartCB; + pluginParam.stop_func = sce::AppSettings::PluginStopCB; + pluginParam.exit_func = sce::AppSettings::PluginExitCB; + pluginParam.module_file = "vs0:vsh/common/app_settings.suprx"; + pluginParam.draw_priority = 0x96; + paf::Plugin::LoadSync(pluginParam); + return 0; +} + +bool do_launch = false; + +void save_and_exit() { + g_config.FromSettings(g_appSettings); + g_config.SaveIni(); + g_fw->RequestShutdown(); +} + +void save_and_launch() { + g_config.FromSettings(g_appSettings); + g_config.SaveIni(); + g_fw->RequestShutdown(); + do_launch = true; +} + +void CBOnStartPageTransition(const char *elementId, int32_t type) { - paf::Framework::InitParam fwParam; + +} + +void CBOnPageActivate(const char *elementId, int32_t type) +{ + +} + +void CBOnPageDeactivate(const char *elementId, int32_t type) +{ + +} + +int32_t CBOnCheckVisible(const char *elementId, bool *pIsVisible) +{ + *pIsVisible = true; + return SCE_OK; +} + +int32_t CBOnPreCreate(const char *elementId, sce::AppSettings::Element *element) +{ + return SCE_OK; +} + +int32_t CBOnPostCreate(const char *elementId, paf::ui::Widget *widget) +{ + return SCE_OK; +} + +int32_t CBOnPress(const char *elementId, const char *newValue) +{ + if(sce_paf_strcmp(elementId, "save_exit_button") == 0) { + save_and_exit(); + return SCE_OK; + } + + if(sce_paf_strcmp(elementId, "save_launch_button") == 0) { + save_and_launch(); + return SCE_OK; + } + + sceClibPrintf("OnPress %s %s\n", elementId, newValue); + return SCE_OK; +} + +int32_t CBOnPress2(const char *elementId, const char *newValue) +{ + return SCE_OK; +} + +void CBOnTerm(int32_t result) +{ + sceKernelExitProcess(0); +} + +const wchar_t *CBOnGetString(const char *elementId) +{ + wchar_t* res = g_configPlugin->GetString(elementId); + if(res[0] != 0) { + return res; + } + return L"unknown string"; +} + +int32_t CBOnGetSurface(paf::graph::Surface **surf, const char *elementId) +{ + return SCE_OK; +} + +void open_settings() { + g_config.Init(); + g_config.LoadIni(); + g_config.ToSettings(g_appSettings); + + sce::AppSettings::InterfaceCallbacks ifCb; + ifCb.onStartPageTransitionCb = CBOnStartPageTransition; + ifCb.onPageActivateCb = CBOnPageActivate; + ifCb.onPageDeactivateCb = CBOnPageDeactivate; + ifCb.onCheckVisible = CBOnCheckVisible; + ifCb.onPreCreateCb = CBOnPreCreate; + ifCb.onPostCreateCb = CBOnPostCreate; + ifCb.onPressCb = CBOnPress; + ifCb.onPressCb2 = CBOnPress2; + ifCb.onTermCb = CBOnTerm; + ifCb.onGetStringCb = (sce::AppSettings::InterfaceCallbacks::GetStringCallback)CBOnGetString; + ifCb.onGetSurfaceCb = CBOnGetSurface; + + paf::wstring msg_save_exit(g_configPlugin->GetString("msg_save_exit")); + paf::wstring msg_save_launch(g_configPlugin->GetString("msg_save_launch")); + paf::wstring msg_exit(g_configPlugin->GetString("msg_exit")); + + paf::Plugin* appSetPlug = paf::Plugin::Find("app_settings_plugin"); + g_appSetIf = (sce::AppSettings::Interface *)appSetPlug->GetInterface(1); + g_appSetIf->Show(&ifCb); + g_appSetIf->AddFooterButton("save_exit_button", &msg_save_exit, 1); + g_appSetIf->AddFooterButton("save_launch_button", &msg_save_launch, 2); + g_appSetIf->ShowFooter(); +} + + +#define MAX_PATH_LENGTH 256 + +static int64_t g_OpStorage[SCE_FIOS_OP_STORAGE_SIZE(64, MAX_PATH_LENGTH) / sizeof(int64_t) + 1]; +static int64_t g_ChunkStorage[SCE_FIOS_CHUNK_STORAGE_SIZE(1024) / sizeof(int64_t) + 1]; +static int64_t g_FHStorage[SCE_FIOS_FH_STORAGE_SIZE(1024, MAX_PATH_LENGTH) / sizeof(int64_t) + 1]; +static int64_t g_DHStorage[SCE_FIOS_DH_STORAGE_SIZE(32, MAX_PATH_LENGTH) / sizeof(int64_t) + 1]; + +void init_fios2() { + sceSysmoduleLoadModule(SCE_SYSMODULE_FIOS2); + SceFiosParams params = SCE_FIOS_PARAMS_INITIALIZER; + params.opStorage.pPtr = g_OpStorage; + params.opStorage.length = sizeof(g_OpStorage); + params.chunkStorage.pPtr = g_ChunkStorage; + params.chunkStorage.length = sizeof(g_ChunkStorage); + params.fhStorage.pPtr = g_FHStorage; + params.fhStorage.length = sizeof(g_FHStorage); + params.dhStorage.pPtr = g_DHStorage; + params.dhStorage.length = sizeof(g_DHStorage); + params.pathMax = MAX_PATH_LENGTH; + + params.threadAffinity[SCE_FIOS_IO_THREAD] = 0x10000; + params.threadAffinity[SCE_FIOS_CALLBACK_THREAD] = 0; + params.threadAffinity[SCE_FIOS_DECOMPRESSOR_THREAD] = 0; + + params.threadPriority[SCE_FIOS_IO_THREAD] = 64; + params.threadPriority[SCE_FIOS_CALLBACK_THREAD] = 191; + params.threadPriority[SCE_FIOS_DECOMPRESSOR_THREAD] = 191; + int ret = sceFiosInitialize(¶ms); + if(ret < 0) { + sceClibPrintf("sceFiosInitialize: %08x\n", ret); + } +} + +int paf_main(void) { + init_fios2(); + + paf::Framework::InitParam fwParam; fwParam.mode = paf::Framework::Mode_Normal; - paf::Framework* paf_fw = new paf::Framework(fwParam); - if (paf_fw != NULL) { - g_fw = paf_fw; + paf::Framework* paf_fw = new paf::Framework(fwParam); + g_fw = paf_fw; - paf_fw->LoadCommonResourceSync(); + paf_fw->LoadCommonResourceSync(); + load_app_settings_plugin(); + paf::Plugin* configPlugin = load_config_plugin(paf_fw); + g_configPlugin = configPlugin; + configPlugin->SetLocale(Locale_EN); - paf::Plugin::InitParam pluginParam; + size_t fileSize = 0; + const char *mimeType = nullptr; + auto settingsXmlFile = configPlugin->GetResource()->GetFile("settings.xml", &fileSize, &mimeType); - pluginParam.name = "config_plugin"; - pluginParam.caller_name = "__main__"; - pluginParam.resource_file = "app0:/config_plugin.rco"; - pluginParam.init_func = NULL; - pluginParam.start_func = loadPluginCB; - pluginParam.stop_func = NULL; - pluginParam.exit_func = NULL; + sce::AppSettings::InitParam settingsParam; + settingsParam.xml_file = settingsXmlFile; + settingsParam.alloc_cb = sce_paf_malloc; + settingsParam.free_cb = sce_paf_free; + settingsParam.realloc_cb = sce_paf_realloc; + settingsParam.safemem_offset = 0; + settingsParam.safemem_size = 0x400; - paf::Plugin::LoadSync(pluginParam); - paf_fw->Run(); - } + sce::AppSettings::GetInstance(settingsParam, &g_appSettings); + g_appSettings->Initialize(); - sceClibPrintf("[SAMPLE] Failed to run PAF instance\n"); + open_settings(); + paf_fw->Run(); - exit(0); - return 0; + if(do_launch) { + sceAppMgrLoadExec("app0:/eboot.bin", NULL, NULL); + } + return 0; } diff --git a/CONFIG/vita/src/main.cpp b/CONFIG/vita/src/main.cpp index 10f1d1ac..0433fafa 100644 --- a/CONFIG/vita/src/main.cpp +++ b/CONFIG/vita/src/main.cpp @@ -1,7 +1,4 @@ -// clang-format off -#include -#include -// clang-format on +#include "pafinc.h" #include #include #include @@ -59,8 +56,8 @@ extern "C" int module_start(SceSize args, void* argp) ); } - paf_main(); - + res = paf_main(); + sceKernelExitProcess(res); return SCE_KERNEL_START_SUCCESS; }