diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-09-12 06:15:16 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-09-12 06:15:16 +0400 |
commit | 0dea748e01dab697d2f8ac245bbd5e925cd732ce (patch) | |
tree | 4699d5a262f3ff2a78643fd35243f0225b9397b3 /source/gameengine | |
parent | 75841bc97f82836e7af5524b79220b984da3b4f8 (diff) |
save and load configuration actuator, (option in game actuator menu)
saves a marshal'd GameLogic.globalDict to the blendfile path with the blend extension replaced with bgeconf
Use this in YoFrankie to save keyboard layout and graphics quality settings.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Converter/KX_ConvertActuators.cpp | 10 | ||||
-rw-r--r-- | source/gameengine/GamePlayer/ghost/GPG_Application.cpp | 47 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameActuator.cpp | 66 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameActuator.h | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 65 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.h | 4 |
6 files changed, 154 insertions, 40 deletions
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 3142f7652de..799506aecaa 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -876,6 +876,16 @@ void BL_ConvertActuators(char* maggiename, mode = KX_GameActuator::KX_GAME_QUIT; break; } + case ACT_GAME_SAVECFG: + { + mode = KX_GameActuator::KX_GAME_SAVECFG; + break; + } + case ACT_GAME_LOADCFG: + { + mode = KX_GameActuator::KX_GAME_LOADCFG; + break; + } default: ; /* flag error */ } diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index f35e2894f65..0287178004d 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -98,7 +98,6 @@ extern "C" #include "GHOST_IEventConsumer.h" #include "GHOST_IWindow.h" #include "GHOST_Rect.h" -#include "marshal.h" static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time); @@ -685,15 +684,7 @@ bool GPG_Application::startEngine(void) initMathutils(); /* Restore the dict */ - if (m_pyGlobalDictString) { - PyObject* pyGlobalDict = PyMarshal_ReadObjectFromString(m_pyGlobalDictString, m_pyGlobalDictString_Length); - if (pyGlobalDict) { - PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module. - } else { - PyErr_Clear(); - printf("Error could not marshall string\n"); - } - } + loadGamePythonConfig(m_pyGlobalDictString, m_pyGlobalDictString_Length); m_sceneconverter->ConvertScene( startscenename, @@ -731,36 +722,12 @@ bool GPG_Application::startEngine(void) void GPG_Application::stopEngine() { // get the python dict and convert to a string for future use - { - SetPyGlobalDictMarshal(NULL, 0); - - PyObject* gameLogic = PyImport_ImportModule("GameLogic"); - if (gameLogic) { - PyObject* pyGlobalDict = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module - if (pyGlobalDict) { -#ifdef Py_MARSHAL_VERSION - PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString( pyGlobalDict, 2); // Py_MARSHAL_VERSION == 2 as of Py2.5 -#else - PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString( pyGlobalDict ); -#endif - if (pyGlobalDictMarshal) { - m_pyGlobalDictString_Length = PyString_Size(pyGlobalDictMarshal); - // for testing only - // PyObject_Print(pyGlobalDictMarshal, stderr, 0); - m_pyGlobalDictString = static_cast<char *> (malloc(m_pyGlobalDictString_Length)); - memcpy(m_pyGlobalDictString, PyString_AsString(pyGlobalDictMarshal), m_pyGlobalDictString_Length); - } else { - printf("Error, GameLogic.globalDict could not be marshal'd\n"); - } - Py_DECREF(gameLogic); - } else { - printf("Error, GameLogic.globalDict was removed\n"); - } - } else { - printf("Error, GameLogic failed to import GameLogic.globalDict will be lost\n"); - } - } - + char *marshal_buffer; + m_pyGlobalDictString_Length = saveGamePythonConfig(&marshal_buffer); + if (m_pyGlobalDictString_Length) { + m_pyGlobalDictString = static_cast<char *> (malloc(m_pyGlobalDictString_Length)); + memcpy(m_pyGlobalDictString, marshal_buffer, m_pyGlobalDictString_Length); + } // when exiting the mainloop exitGamePythonScripting(); diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index fcd32d5f4fe..91ddbbbfbc9 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -34,6 +34,7 @@ //#include <iostream> #include "KX_Scene.h" #include "KX_KetsjiEngine.h" +#include "KX_PythonInit.h" /* for config load/saving */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -125,6 +126,71 @@ bool KX_GameActuator::Update() } break; } + case KX_GAME_SAVECFG: + { + if (m_ketsjiengine) + { + char mashal_path[512]; + char *marshal_buffer = NULL; + int marshal_length; + FILE *fp = NULL; + + pathGamePythonConfig(mashal_path); + marshal_length = saveGamePythonConfig(&marshal_buffer); + + if (marshal_length && marshal_buffer) { + fp = fopen(mashal_path, "wb"); + if (fp) { + if (fwrite(marshal_buffer, 1, marshal_length, fp) != marshal_length) { + printf("Warning: could not write marshal data\n"); + } + fclose(fp); + } else { + printf("Warning: could not open marshal file\n"); + } + } else { + printf("Warning: could not create marshal buffer\n"); + } + } + break; + } + case KX_GAME_LOADCFG: + { + if (m_ketsjiengine) + { + char mashal_path[512]; + char *marshal_buffer; + int marshal_length; + FILE *fp = NULL; + int result; + + pathGamePythonConfig(mashal_path); + + fp = fopen(mashal_path, "rb"); + if (fp) { + // obtain file size: + fseek (fp , 0 , SEEK_END); + marshal_length = ftell(fp); + rewind(fp); + + marshal_buffer = (char*) malloc (sizeof(char)*marshal_length); + + result = fread (marshal_buffer, 1, marshal_length, fp); + + if (result == marshal_length) { + loadGamePythonConfig(marshal_buffer, marshal_length); + } else { + printf("warning: could not read all of '%s'\n", mashal_path); + } + + free(marshal_buffer); + fclose(fp); + } else { + printf("warning: could not open '%s'\n", mashal_path); + } + } + break; + } default: ; /* do nothing? this is an internal error !!! */ } diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index 8565dc46caa..bb3448995dc 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -54,6 +54,8 @@ protected: KX_GAME_START, KX_GAME_RESTART, KX_GAME_QUIT, + KX_GAME_SAVECFG, + KX_GAME_LOADCFG, KX_GAME_MAX }; diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index eb0052d71ff..5742c530f6d 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -74,6 +74,8 @@ extern "C" { #include "Mathutils.h" // Blender.Mathutils module copied here so the blenderlayer can use. } +#include "marshal.h" /* python header for loading/saving dicts */ + #include "PHY_IPhysicsEnvironment.h" // FIXME: Enable for access to blender python modules. This is disabled because // python has dependencies on a lot of other modules and is a pain to link. @@ -1319,3 +1321,66 @@ class KX_Scene* PHY_GetActiveScene() { return gp_KetsjiScene; } + +// utility function for loading and saving the globalDict +int saveGamePythonConfig( char **marshal_buffer) +{ + int marshal_length = 0; + PyObject* gameLogic = PyImport_ImportModule("GameLogic"); + if (gameLogic) { + PyObject* pyGlobalDict = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module + if (pyGlobalDict) { +#ifdef Py_MARSHAL_VERSION + PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString( pyGlobalDict, 2); // Py_MARSHAL_VERSION == 2 as of Py2.5 +#else + PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString( pyGlobalDict ); +#endif + if (pyGlobalDictMarshal) { + marshal_length= PyString_Size(pyGlobalDictMarshal); + // for testing only + // PyObject_Print(pyGlobalDictMarshal, stderr, 0); + *marshal_buffer = PyString_AsString(pyGlobalDictMarshal); + } else { + printf("Error, GameLogic.globalDict could not be marshal'd\n"); + } + Py_DECREF(gameLogic); + } else { + printf("Error, GameLogic.globalDict was removed\n"); + } + } else { + printf("Error, GameLogic failed to import GameLogic.globalDict will be lost\n"); + } + return marshal_length; +} + +int loadGamePythonConfig(char *marshal_buffer, int marshal_length) +{ + PyObject* gameLogic = PyImport_ImportModule("GameLogic"); + /* Restore the dict */ + if (marshal_buffer) { + PyObject* pyGlobalDict = PyMarshal_ReadObjectFromString(marshal_buffer, marshal_length); + if (pyGlobalDict) { + PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module. + return 1; + } else { + PyErr_Clear(); + printf("Error could not marshall string\n"); + } + } else { + printf("Error, GameLogic failed to import GameLogic.globalDict will be lost\n"); + } + return 0; +} + +void pathGamePythonConfig( char *path ) +{ + int len = strlen(G.sce); + + strncpy(path, G.sce, sizeof(G.sce)); + /* replace extension */ + if (BLI_testextensie(path, ".blend")) { + strcpy(path+(len-6), ".bgeconf"); + } else { + strcpy(path+len, ".bgeconf"); + } +} diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 388d073c6db..28d9d72a4c3 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -49,6 +49,10 @@ void exitGamePlayerPythonScripting(); PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level); void exitGamePythonScripting(); +void pathGamePythonConfig( char *path ); +int saveGamePythonConfig( char **marshal_buffer); +int loadGamePythonConfig(char *marshal_buffer, int marshal_length); + void PHY_SetActiveScene(class KX_Scene* scene); class KX_Scene* PHY_GetActiveScene(); #include "MT_Vector3.h" |