#include "Python.h" #include "PyQuest.h" #include "quest.h" #include "driver.h" #include "config.h" #include "options.h" // Global variables: PyObject* PyEmulatorException; char PythonErrorString[2048]; extern GlobalQuestInfo* GlobalQ; extern core_options* PyMAMEOptions; /////////////////////////////////////////////////////////////////////////////////////// // The Python API starts here: static PyObject* ex_foo(PyObject* self, PyObject* args) { printf("Hello, world\n"); Py_INCREF(Py_None); return Py_None; } static PyObject* PyTest(PyObject* self, PyObject* args) { int DriverIndex; const game_driver* Driver; // printf("MAME driver list:\n"); for (DriverIndex = 0; ; DriverIndex++) { Driver = drivers[DriverIndex]; if (!Driver) { break; } printf("Driver #%d: %s\n", DriverIndex, Driver->name); } printf("-->Total games: %d\n", DriverIndex); Py_INCREF(Py_None); return Py_None; } // PlayGame(Name, Value) static PyObject* PySetOption(PyObject* self, PyObject* args) { char* OptionName; char* OptionValue; // if (!PyArg_ParseTuple(args, "ss", &OptionName, &OptionValue)) { return NULL; } //Result = SetOption(OptionName, OptionValue); options_set_string(PyMAMEOptions, OptionName, OptionValue, OPTION_PRIORITY_CMDLINE); //if (!Result) //{ // sprintf(PythonErrorString, "** Error: Option '%s' not known\n", OptionName); // ReportPythonError(); // return NULL; //} Py_INCREF(Py_None); return Py_None; } extern int* PyMAMEKeyConfig; // PlayGame(DriverName, [SaveFile], [QuestDefinition]) static PyObject* PyPlayGame(PyObject* self, PyObject* args) { char* DriverName; char* SaveFilePath = NULL; PyObject* PyQuest = NULL; QuestDefinition* Quest = NULL; PyObject* QuestResult; const game_driver* Driver; // if (!PyArg_ParseTuple(args, "s|sO", &DriverName, &SaveFilePath, &PyQuest)) { return NULL; } if (!DriverName || !DriverName[0]) { sprintf(PythonErrorString, "** Error: Null driver name passed to PyPlayGame!"); return NULL; } // Look up the driver: printf("Get driver: '%s'\n", DriverName); Driver = driver_get_name(DriverName); //DriverIndex = driver_get_index(DriverName); //printf("Driver index:%d\n", DriverIndex); if (!Driver) { sprintf(PythonErrorString, "** Error: Driver '%s' not known\n", DriverName); ReportPythonError(); printf("Reported - return null.\n"); return NULL; } printf("->Get driver '%s' -> %s\n", DriverName, Driver->name); // Parse the quest definition, if any: if (PyQuest) { Quest = GetQuestDefinitionFromPy(PyQuest); if (!Quest) { // What kind of crap are they trying to pass in here? return NULL; } } GlobalQ->CurrentQuest = Quest; FreeQuestResults(); DebugPrintQuest(GlobalQ->CurrentQuest, 0); printf("->PlayGameInternal()\n"); //InitializeQuestOptions(Quest, DriverIndex); PlayGameInternal(Driver, SaveFilePath, Quest); printf("Get quest result...\n"); QuestResult = PyGetQuestResults(GlobalQ->FirstResult); return QuestResult; } // 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"); } static PyObject* PySetKeyConfig(PyObject* self, PyObject* args) { PyObject* NewKeyConfig; PyObject* KeyEntry; int KeyIndex; if (!PyArg_ParseTuple(args, "O", &NewKeyConfig)) { return NULL; } // Remove OLD PyMAME key config: if (PyMAMEKeyConfig) { free(PyMAMEKeyConfig); } PyMAMEKeyConfig = NULL; // If they passed in None, return: if (NewKeyConfig == Py_None) { Py_INCREF(Py_None); return Py_None; } // Allocate the new PyMAME key config: PyMAMEKeyConfig = (int*)calloc(sizeof(int), evButtonConfigCount); if (!PySequence_Check(NewKeyConfig) || PySequence_Length(NewKeyConfig) < evButtonConfigCount) { sprintf(PythonErrorString, "** Error: Must pass in a sequence of length at least 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 { PyMAMEKeyConfig[KeyIndex] = PyInt_AsLong(KeyEntry); } Py_DECREF(KeyEntry); printf("PySetKeyConfig: PyMAMEKeyConfig[%d] = %d\n", KeyIndex, PyMAMEKeyConfig[KeyIndex]); } //OSDSetKeyConfig(KeyConfig); Py_INCREF(Py_None); return Py_None; } /////////////////////////////////////////////////////////////////////////////////////// // Module definition stuff: static PyMethodDef PyMAMEMethods[] = { {"foo", ex_foo, METH_VARARGS, "foo() doc string"}, {"PlayGame", PyPlayGame, METH_VARARGS, "Launch a game, by driver-name"}, {"SetOption", PySetOption, METH_VARARGS, "Set a configuration option"}, {"Test", PyTest, METH_VARARGS, "Test a single quest"}, {"SetKeyConfig", PySetKeyConfig, METH_VARARGS, "Set key-configuration"}, {NULL, NULL} }; PyMODINIT_FUNC initPyMAME(void) { PyObject* Module; // printf("->InitModule()\n"); Module = Py_InitModule("PyMAME", PyMAMEMethods); // Init quest options: printf("->InitQuestInfo()\n"); InitQuestInfo(); // Add the Error object: printf("->Add error object\n"); PyEmulatorException = PyErr_NewException("PyMAME.error", NULL, NULL); Py_INCREF(PyEmulatorException); PyModule_AddObject(Module, "error", PyEmulatorException); // Perform OS-specific setup: PyMAMESetup(); }