#include "Python.h" #include "NecroCore/quest.h" #include "NecroCore/PyQuest.h" #include "PyOSD.h" PyObject* PyEmulatorException; char PythonErrorString[2048]; extern GlobalQuestInfo* GlobalQ; extern PyObject* PyGetQuestResults(QuestResult* Head); extern void SetJoypadConfig(int* KeyConfig); static PyObject* ex_foo(PyObject* self, PyObject* args) { printf("Hello, world\n"); Py_INCREF(Py_None); return Py_None; } static PyObject* PyRun(PyObject* self, PyObject* args) { // Py_INCREF(Py_None); return Py_None; } static PyObject* PyTest(PyObject* self, PyObject* args) { // Py_INCREF(Py_None); return Py_None; } // Simple interface for error-reporting to Python callers: // Print an error to PythonErrorString, then call ReportPythonError(). void ReportPythonError() { printf("Report error:\n"); printf("String '%s'\n", PythonErrorString); printf("Exception: %d\n", PyEmulatorException); PyErr_SetString(PyEmulatorException, PythonErrorString); printf("Reported.\n"); } extern int* PyVBAKeyConfig; // Update the gamepad configuration static PyObject* PySetKeyConfig(PyObject* self, PyObject* args) { PyObject* NewKeyConfig; PyObject* KeyEntry; int KeyIndex; // if (!PyArg_ParseTuple(args, "O", &NewKeyConfig)) { return NULL; } if (!PySequence_Check(NewKeyConfig) || PySequence_Length(NewKeyConfig) < 10) { sprintf(PythonErrorString, "** Error: Must pass in a sequence of length 10 to SetKeyConfig!"); ReportPythonError(); return NULL; } for (KeyIndex = 0; KeyIndex < evButtonConfigCount; KeyIndex++) { KeyEntry = PySequence_GetItem(NewKeyConfig, KeyIndex); if (!PyInt_Check(KeyEntry)) { sprintf(PythonErrorString, "* Error in SetKeyConfig: Key %d isn't an int!", KeyIndex); ReportPythonError(); } else { printf("--SetPyVBAKeyConfig(%d, %d)\n", KeyIndex, PyInt_AsLong(KeyEntry)); SetNecroKeyConfig(KeyIndex, PyInt_AsLong(KeyEntry)); //PyVBAKeyConfig[KeyIndex] = PyInt_AsLong(KeyEntry); } Py_DECREF(KeyEntry); } // Propagate changes from PyVBAKeyConfig to internals: SetJoypadConfig(PyVBAKeyConfig); Py_INCREF(Py_None); return Py_None; } // PlayGame(DriverName, [SaveFile], [QuestDefinition]) static PyObject* PyPlayGame(PyObject* self, PyObject* args) { char* DriverName; char* PatchFilePath = NULL; char* SaveFilePath = NULL; PyObject* PyQuest = NULL; QuestDefinition* Quest = NULL; PyObject* QuestResult; PyObject* PatchFileNameObject = NULL; PyObject* SavePathObject = NULL; // printf("==>PyPlayGame\n"); if (!PyArg_ParseTuple(args, "s|OOO", &DriverName, &SavePathObject, &PyQuest, &PatchFileNameObject)) { return NULL; } if (!DriverName || !DriverName[0]) { sprintf(PythonErrorString, "** Error: Null driver name passed to PyPlayGame!"); return NULL; } GlobalQ->SaveFilePath[0] = '\0'; if (SavePathObject && PyString_Check(SavePathObject)) { SaveFilePath = PyString_AsString(SavePathObject); strncpy(GlobalQ->SaveFilePath, SaveFilePath, 2048); } // Parse the quest definition, if any: if (PyQuest && PyQuest != Py_None) { printf("==>GetQuestDefinitionFromPy\n"); Quest = GetQuestDefinitionFromPy(PyQuest); printf("<==GetQuestDefinitionFromPy\n"); if (!Quest) { // What kind of crap are they trying to pass in here? return NULL; } } GlobalQ->CurrentQuest = Quest; FreeQuestResults(); //InitializeQuestOptions(Quest, DriverIndex); printf("==>PlayGameInternal\n"); PlayGameInternal(DriverName, SaveFilePath, PatchFilePath, Quest); printf("<==PlayGameInternal\n"); printf("Get quest result...\n"); printf("==>PyGetQuestRecord\n"); QuestResult = PyGetQuestResults(GlobalQ->FirstResult); printf("<==PyGetQuestRecord\n"); printf("<==PyPlayGame\n"); return QuestResult; } static PyMethodDef PyVBAMethods[] = { {"foo", ex_foo, METH_VARARGS, "foo() doc string"}, {"PlayGame", PyPlayGame, METH_VARARGS, "Play a game"}, //{"Run", PyRun, METH_VARARGS, "Run quest CLI"}, //{"Test", PyTest, METH_VARARGS, "Test a single quest"}, //{"GetKeyConfig", PyGetKeyConfig, METH_VARARGS, "Get current key configuration"}, {"SetKeyConfig", PySetKeyConfig, METH_VARARGS, "Set new key configuration"}, {NULL, NULL} }; void PyVBASetup() { // init! } PyMODINIT_FUNC initPyVBA(void) { PyObject* Module; // Module = Py_InitModule("PyVBA", PyVBAMethods); printf("->InitQuestInfo()\n"); InitQuestInfo(); // Add the Error object: printf("->Add error object\n"); PyEmulatorException = PyErr_NewException("PyVBA.error", NULL, NULL); Py_INCREF(PyEmulatorException); PyModule_AddObject(Module, "error", PyEmulatorException); PyVBASetup(); }