McRogueFace Python API (McRFPy_API) demo class
This commit is contained in:
parent
a6f59085eb
commit
6a2c3c6c36
|
@ -15,10 +15,26 @@ std::wstring executable_path()
|
|||
|
||||
}
|
||||
|
||||
std::wstring executable_filename()
|
||||
{
|
||||
auto exec_path = std::filesystem::canonical("/proc/self/exe");
|
||||
return exec_path.wstring();
|
||||
}
|
||||
|
||||
std::wstring working_path()
|
||||
{
|
||||
auto cwd = std::filesystem::current_path();
|
||||
return cwd.wstring();
|
||||
}
|
||||
|
||||
std::string narrow_string(std::wstring convertme)
|
||||
{
|
||||
//setup converter
|
||||
using convert_type = std::codecvt_utf8<wchar_t>;
|
||||
std::wstring_convert<convert_type, wchar_t> converter;
|
||||
|
||||
//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
|
||||
return converter.to_bytes(convertme);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,3 +8,9 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
// wstring<->string conversion
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <filesystem>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "MenuScene.h"
|
||||
#include "UITestScene.h"
|
||||
#include "ActionCode.h"
|
||||
#include "McRFPy_API.h"
|
||||
|
||||
GameEngine::GameEngine()
|
||||
{
|
||||
|
@ -14,6 +15,10 @@ GameEngine::GameEngine()
|
|||
scenes["menu"] = new MenuScene(this);
|
||||
//std::cout << "Constructed MenuScene" <<std::endl;
|
||||
scenes["play"] = new UITestScene(this);
|
||||
//api = new McRFPy_API(this);
|
||||
McRFPy_API::game = this;
|
||||
McRFPy_API::api_init();
|
||||
McRFPy_API::executePyString("import mcrfpy");
|
||||
}
|
||||
|
||||
Scene* GameEngine::currentScene() { return scenes[scene]; }
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Entity.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Scene.h"
|
||||
#include "McRFPy_API.h"
|
||||
|
||||
class GameEngine
|
||||
{
|
||||
|
@ -15,6 +16,7 @@ class GameEngine
|
|||
bool paused = false;
|
||||
int currentFrame = 0;
|
||||
sf::View visible;
|
||||
//McRFPy_API* api;
|
||||
|
||||
public:
|
||||
GameEngine();
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#include "McRFPy_API.h"
|
||||
#include "platform.h"
|
||||
#include "GameEngine.h"
|
||||
|
||||
static PyMethodDef mcrfpyMethods[] = {
|
||||
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
|
||||
"Draw a sprite (index, x, y)"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyModuleDef mcrfpyModule = {
|
||||
PyModuleDef_HEAD_INIT, "mcrfpy", NULL, -1, mcrfpyMethods,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
// Module initializer fn, passed to PyImport_AppendInittab
|
||||
PyObject* PyInit_mcrfpy()
|
||||
{
|
||||
return PyModule_Create(&mcrfpyModule);
|
||||
}
|
||||
|
||||
// init_python - configure interpreter details here
|
||||
PyStatus init_python(const char *program_name)
|
||||
{
|
||||
PyStatus status;
|
||||
|
||||
//**preconfig to establish locale**
|
||||
PyPreConfig preconfig;
|
||||
PyPreConfig_InitIsolatedConfig(&preconfig);
|
||||
preconfig.utf8_mode = 1;
|
||||
|
||||
status = Py_PreInitialize(&preconfig);
|
||||
if (PyStatus_Exception(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
PyConfig config;
|
||||
PyConfig_InitIsolatedConfig(&config);
|
||||
config.dev_mode = 0;
|
||||
|
||||
PyConfig_SetBytesString(&config, &config.home,
|
||||
narrow_string(executable_path() + L"/Python311").c_str());
|
||||
|
||||
status = PyConfig_SetBytesString(&config, &config.program_name,
|
||||
program_name);
|
||||
|
||||
// under Windows, the search paths are correct; under Linux, they need manual insertion
|
||||
#if __PLATFORM_SET_PYTHON_SEARCH_PATHS == 1
|
||||
config.module_search_paths_set = 1;
|
||||
|
||||
// search paths for python libs/modules/scripts
|
||||
const wchar_t* str_arr[] = {
|
||||
L"/scripts",
|
||||
L"/Python311/lib.linux-x86_64-3.11",
|
||||
L"/Python311",
|
||||
L"/Python311/Lib",
|
||||
L"/venv/lib/python3.11/site-packages"
|
||||
};
|
||||
|
||||
|
||||
for(auto s : str_arr) {
|
||||
status = PyWideStringList_Append(&config.module_search_paths, (executable_path() + s).c_str());
|
||||
if (PyStatus_Exception(status)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
return status;
|
||||
}
|
||||
|
||||
void McRFPy_API::setSpriteTexture(int ti)
|
||||
{
|
||||
int tx = ti % texture_width, ty = ti / texture_width;
|
||||
sprite.setTextureRect(sf::IntRect(
|
||||
tx * texture_size,
|
||||
ty * texture_size,
|
||||
texture_size, texture_size));
|
||||
}
|
||||
|
||||
// functionality
|
||||
void McRFPy_API::drawSprite(int tex_index, int grid_x, int grid_y)
|
||||
{
|
||||
setSpriteTexture(tex_index);
|
||||
sprite.setPosition(
|
||||
sf::Vector2f(grid_x * texture_size,
|
||||
grid_y * texture_size)
|
||||
);
|
||||
game->getWindow().draw(sprite);
|
||||
}
|
||||
|
||||
// python connection
|
||||
PyObject* McRFPy_API::_drawSprite(PyObject *self, PyObject *args)
|
||||
{
|
||||
int ti, gx, gy;
|
||||
if (!PyArg_ParseTuple(args, "iii", &ti, &gx, &gy)) return NULL;
|
||||
drawSprite(ti, gx, gy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void McRFPy_API::api_init() {
|
||||
|
||||
// initialization time build of Py API elements
|
||||
/*
|
||||
mcrfpyMethodsVector.push_back(
|
||||
{"drawSprite", _drawSprite, METH_VARARGS,
|
||||
"Draw a sprite (index, x, y)"}
|
||||
);
|
||||
mcrfpyMethodsVector.push_back(
|
||||
{NULL, NULL, 0, NULL}
|
||||
);
|
||||
mcrfpyMethods = &mcrfpyMethodsVector[0];
|
||||
*/
|
||||
|
||||
// build API exposure before python initialization
|
||||
PyImport_AppendInittab("mcrfpy", PyInit_mcrfpy);
|
||||
// use full path version of argv[0] from OS to init python
|
||||
init_python(narrow_string(executable_filename()).c_str());
|
||||
|
||||
texture.loadFromFile("./assets/kenney_tinydungeon.png");
|
||||
//texture_size = 16, texture_width = 12, texture_height= 11;
|
||||
//texture_sprite_count = texture_width * texture_height;
|
||||
texture.setSmooth(false);
|
||||
|
||||
sprite.setTexture(texture);
|
||||
sprite.setScale(sf::Vector2f(4.0f, 4.0f));
|
||||
setSpriteTexture(0);
|
||||
}
|
||||
|
||||
void McRFPy_API::executeScript(std::string filename)
|
||||
{
|
||||
FILE* PScriptFile = fopen(filename.c_str(), "r");
|
||||
if(PScriptFile) {
|
||||
PyRun_SimpleFile(PScriptFile, filename.c_str());
|
||||
fclose(PScriptFile);
|
||||
}
|
||||
}
|
||||
|
||||
void McRFPy_API::executePyString(std::string pycode)
|
||||
{
|
||||
PyRun_SimpleString(pycode.c_str());
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "Entity.h"
|
||||
//#include "EntityManager.h"
|
||||
//#include "Scene.h"
|
||||
//#include "GameEngine.h" // can't - need forward declaration
|
||||
//#include "ActionCode.h"
|
||||
#include "Python.h"
|
||||
|
||||
class GameEngine; // forward declared (circular members)
|
||||
|
||||
class McRFPy_API
|
||||
{
|
||||
private:
|
||||
static const int texture_size = 16, // w & h (pixels) of one sprite in the tex
|
||||
texture_width = 12, texture_height = 11, // w & h sprite/frame count
|
||||
texture_sprite_count = 11 * 12; // t_width * t_height, minus blanks?
|
||||
|
||||
// TODO: this is wrong, load resources @ GameEngineSprite sprite;
|
||||
// sf::Texture texture;
|
||||
|
||||
//std::vector<PyMethodDef> mcrfpyMethodsVector;
|
||||
//static PyObject* PyInit_mcrfpy();
|
||||
|
||||
McRFPy_API();
|
||||
|
||||
public:
|
||||
inline static sf::Sprite sprite;
|
||||
inline static sf::Texture texture;
|
||||
static void setSpriteTexture(int);
|
||||
inline static GameEngine* game;
|
||||
static void api_init();
|
||||
// Python API functionality - use mcrfpy.* in scripts
|
||||
static PyObject* _drawSprite(PyObject*, PyObject*);
|
||||
|
||||
// McRFPy_API(GameEngine*);
|
||||
|
||||
// API functionality - use from C++ directly
|
||||
|
||||
//void spawnEntity(int tex_index, int grid_x, int grid_y, PyObject* script);
|
||||
|
||||
// test function, do not use in production
|
||||
static void drawSprite(int tex_index, int grid_x, int grid_y);
|
||||
|
||||
static void executeScript(std::string);
|
||||
static void executePyString(std::string);
|
||||
};
|
||||
|
||||
/*
|
||||
static PyMethodDef mcrfpyMethods[] = {
|
||||
{"drawSprite", McRFPy_API::_drawSprite, METH_VARARGS,
|
||||
"Draw a sprite (index, x, y)"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static PyModuleDef mcrfpyModule = {
|
||||
PyModuleDef_HEAD_INIT, "mcrfpy", NULL, -1, mcrfpyMethods,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
// Module initializer fn, passed to PyImport_AppendInittab
|
||||
PyObject* PyInit_mcrfpy()
|
||||
{
|
||||
return PyModule_Create(&mcrfpyModule);
|
||||
}
|
||||
*/
|
|
@ -285,6 +285,13 @@ void UITestScene::sRender()
|
|||
|
||||
}
|
||||
|
||||
// test Python sprite code
|
||||
McRFPy_API::executePyString("mcrfpy.drawSprite(123, 10, 10)");
|
||||
McRFPy_API::executePyString("mcrfpy.drawSprite(121, 15, 15)");
|
||||
|
||||
//game->api->executePyString("mcrfpy.drawSprite(123, 10, 10)")
|
||||
//game->api->executePyString("mcrfpy.drawSprite(121, 15, 15)")
|
||||
|
||||
// draw test sprite on top of everything
|
||||
game->getWindow().draw(test_sprite);
|
||||
|
||||
|
|
Loading…
Reference in New Issue