diff --git a/src/McRFPy_API.cpp b/src/McRFPy_API.cpp index 113c13a..51bd3c7 100644 --- a/src/McRFPy_API.cpp +++ b/src/McRFPy_API.cpp @@ -53,33 +53,29 @@ PyObject* PyInit_mcrfpy() return NULL; } - // This code runs, but Python segfaults when accessing the UIFrame type. - //std::cout << "Adding UIFrame object to module\n"; - PyModule_AddType(m, &mcrfpydef::PyColorType); - PyModule_AddType(m, &mcrfpydef::PyFontType); - PyModule_AddType(m, &mcrfpydef::PyUICaptionType); - PyModule_AddType(m, &mcrfpydef::PyTextureType); - PyModule_AddType(m, &mcrfpydef::PyUISpriteType); - - if (PyModule_AddType(m, &mcrfpydef::PyUIFrameType) < 0) + using namespace mcrfpydef; + PyTypeObject* pytypes[] = { + /*SFML exposed types*/ + &PyColorType, &PyFontType, &PyTextureType, + + /*UI widgets*/ + &PyUICaptionType, &PyUISpriteType, &PyUIFrameType, &PyUIEntityType, &PyUIGridType, + + /*game map & perspective data*/ + &PyUIGridPointType, &PyUIGridPointStateType, + + /*collections & iterators*/ + &PyUICollectionType, &PyUICollectionIterType, + &PyUIEntityCollectionType, &PyUIEntityCollectionIterType, + nullptr}; + int i = 0; + auto t = pytypes[i]; + while (t != nullptr) { - std::cout << "Error adding UIFrame type to module; aborting" << std::endl; - Py_DECREF(&mcrfpydef::PyUIFrameType); - return NULL; + PyType_Ready(t); + PyModule_AddType(m, t); + t = pytypes[i++]; } - PyModule_AddType(m, &mcrfpydef::PyUICollectionType); - PyModule_AddType(m, &mcrfpydef::PyUICollectionIterType); - - PyModule_AddType(m, &mcrfpydef::PyUIGridPointType); - PyModule_AddType(m, &mcrfpydef::PyUIGridPointStateType); - PyModule_AddType(m, &mcrfpydef::PyUIEntityType); - - PyModule_AddType(m, &mcrfpydef::PyUIEntityCollectionIterType); - PyModule_AddType(m, &mcrfpydef::PyUIEntityCollectionType); - - PyModule_AddType(m, &mcrfpydef::PyUIGridType); - - return m; } diff --git a/src/PyTexture.cpp b/src/PyTexture.cpp new file mode 100644 index 0000000..7ce1b7b --- /dev/null +++ b/src/PyTexture.cpp @@ -0,0 +1,63 @@ +#include "PyTexture.h" + + +PyTexture::PyTexture(std::string filename, int sprite_w, int sprite_h) +: source(filename), sprite_width(sprite_w), sprite_height(sprite_h) +{ + texture = sf::Texture(); + texture.loadFromFile(source); + auto size = texture.getSize(); + sheet_width = (size.x / sprite_width); + sheet_height = (size.y / sprite_height); + if (size.x % sprite_width != 0 || size.y % sprite_height != 0) + { + std::cout << "Warning: Texture `" << source << "` is not an even number of sprite widths or heights across." << std::endl + << "Sprite size given was " << sprite_w << "x" << sprite_h << "px but the file has a resolution of " << sheet_width << "x" << sheet_height << "px." << std::endl; + } +} + +sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos, sf::Vector2f s) +{ + int tx = index % sheet_width, ty = index / sheet_width; + auto ir = sf::IntRect(tx * sprite_width, ty * sprite_height, sprite_width, sprite_height); + auto sprite = sf::Sprite(texture, ir); + sprite.setPosition(pos); + sprite.setScale(s); + return sprite; +} + +PyObject* PyTexture::pyObject() +{ + PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyTextureType, 0); + try { + ((PyTextureObject*)obj)->data = shared_from_this(); + } + catch (std::bad_weak_ptr& e) + { + std::cout << "Bad weak ptr: shared_from_this() failed in PyTexture::pyObject(); did you create a PyTexture outside of std::make_shared? enjoy your segfault, soon!" << std::endl; + } + // TODO - shared_from_this will raise an exception if the object does not have a shared pointer. Constructor should be made private; write a factory function + return obj; +} + +Py_hash_t PyTexture::hash(PyObject* obj) +{ + auto self = (PyTextureObject*)obj; + return reinterpret_cast(self->data.get()); +} + +int PyTexture::init(PyTextureObject* self, PyObject* args, PyObject* kwds) +{ + static const char* keywords[] = { "filename", "sprite_width", "sprite_height", nullptr }; + char* filename; + int sprite_width, sprite_height; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "sii", const_cast(keywords), &filename, &sprite_width, &sprite_height)) + return -1; + self->data = std::make_shared(filename, sprite_width, sprite_height); + return 0; +} + +PyObject* PyTexture::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + return (PyObject*)type->tp_alloc(type, 0); +} diff --git a/src/PyTexture.h b/src/PyTexture.h new file mode 100644 index 0000000..eea1838 --- /dev/null +++ b/src/PyTexture.h @@ -0,0 +1,40 @@ +#pragma once +#include "Common.h" +#include "Python.h" + +class PyTexture; + +typedef struct { + PyObject_HEAD + std::shared_ptr data; +} PyTextureObject; + +class PyTexture : public std::enable_shared_from_this +{ +private: + sf::Texture texture; + std::string source; + int sheet_width, sheet_height; +public: + int sprite_width, sprite_height; // just use them read only, OK? + PyTexture(std::string filename, int sprite_w, int sprite_h); + sf::Sprite sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0)); + + PyObject* pyObject(); + static Py_hash_t hash(PyObject*); + static int init(PyTextureObject*, PyObject*, PyObject*); + static PyObject* pynew(PyTypeObject* type, PyObject* args=NULL, PyObject* kwds=NULL); +}; + +namespace mcrfpydef { + static PyTypeObject PyTextureType = { + .tp_name = "mcrfpy.Texture", + .tp_basicsize = sizeof(PyTextureObject), + .tp_itemsize = 0, + .tp_hash = PyTexture::hash, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = PyDoc_STR("SFML Texture Object"), + .tp_init = (initproc)PyTexture::init, + .tp_new = PyTexture::pynew, + }; +} diff --git a/src/UI.cpp b/src/UI.cpp index b2447cd..5d43918 100644 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -168,7 +168,8 @@ void UICaption::render(sf::Vector2f offset) } UISprite::UISprite() {} - +/* + // * tearing down the old IndexTexture way of life UISprite::UISprite(IndexTexture* _itex, int _sprite_index, float x = 0.0, float y = 0.0, float s = 1.0) : itex(_itex), sprite_index(_sprite_index) { @@ -186,6 +187,13 @@ UISprite::UISprite(IndexTexture* _itex, int _sprite_index, sf::Vector2f pos, flo sprite.setPosition(pos); sprite.setScale(sf::Vector2f(s, s)); } +*/ + +UISprite::UISprite(std::shared_ptr _ptex, int _sprite_index, sf::Vector2f _pos, float _scale) +: ptex(_ptex), sprite_index(_sprite_index) +{ + sprite = ptex->sprite(sprite_index, _pos, sf::Vector2f(_scale, _scale)); +} //void UISprite::update() //{ @@ -212,19 +220,55 @@ void UISprite::render(sf::Vector2f offset, sf::RenderTexture& target) sprite.move(-offset); } +/* void UISprite::setPosition(float x, float y) { setPosition(sf::Vector2f(x, y)); } +*/ void UISprite::setPosition(sf::Vector2f pos) { sprite.setPosition(pos); } -void UISprite::setScale(float s) +void UISprite::setScale(sf::Vector2f s) { - sprite.setScale(sf::Vector2f(s, s)); + sprite.setScale(s); +} + +void UISprite::setTexture(std::shared_ptr _ptex, int _sprite_index) +{ + ptex = _ptex; + if (_sprite_index != -1) // if you are changing textures, there's a good chance you need a new index too + sprite_index = _sprite_index; + sprite = ptex->sprite(sprite_index, sprite.getPosition(), sprite.getScale()); +} + +void UISprite::setSpriteIndex(int _sprite_index) +{ + sprite_index = _sprite_index; + sprite = ptex->sprite(sprite_index, sprite.getPosition(), sprite.getScale()); +} + +sf::Vector2f UISprite::getScale() +{ + return sprite.getScale(); +} + +sf::Vector2f UISprite::getPosition() +{ + return sprite.getPosition(); +} + +std::shared_ptr UISprite::getTexture() +{ + return ptex; +} + +int UISprite::getSpriteIndex() +{ + return sprite_index; } PyObjectsEnum UICaption::derived_type() @@ -258,9 +302,10 @@ UIGrid::UIGrid() { } -UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, float _x, float _y, float _w, float _h) +/* +UIGrid::UIGrid(int gx, int gy, std::shared_ptr _ptex, float _x, float _y, float _w, float _h) : grid_x(gx), grid_y(gy), - zoom(1.0f), center_x((gx/2) * _itex->grid_size), center_y((gy/2) * _itex->grid_size), + zoom(1.0f), center_x((gx/2) * _ptex->sheet_width), center_y((gy/2) * _ptex->sheet_height), itex(_itex), points(gx * gy) { // set up blank list of entities @@ -279,11 +324,12 @@ UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, float _x, float _y, float _w // textures are upside-down inside renderTexture output.setTexture(renderTexture.getTexture()); } +*/ -UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, sf::Vector2f _xy, sf::Vector2f _wh) +UIGrid::UIGrid(int gx, int gy, std::shared_ptr _ptex, sf::Vector2f _xy, sf::Vector2f _wh) : grid_x(gx), grid_y(gy), - zoom(1.0f), center_x((gx/2) * _itex->grid_size), center_y((gy/2) * _itex->grid_size), - itex(_itex), points(gx * gy) + zoom(1.0f), center_x((gx/2) * _ptex->sprite_width), center_y((gy/2) * _ptex->sprite_height), + ptex(_ptex), points(gx * gy) { // set up blank list of entities entities = std::make_shared>>(); @@ -296,7 +342,9 @@ UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, sf::Vector2f _xy, sf::Vector // create renderTexture with maximum theoretical size; sprite can resize to show whatever amount needs to be rendered renderTexture.create(1920, 1080); // TODO - renderTexture should be window size; above 1080p this will cause rendering errors - sprite.setTexture(_itex->texture); + //sprite.setTexture(_itex->texture); + sprite = ptex->sprite(0); + output.setTextureRect( sf::IntRect(0, 0, box.getSize().x, box.getSize().y)); @@ -310,11 +358,14 @@ void UIGrid::update() { } +/* void UIGrid::setSprite(int ti) { - int tx = ti % itex->grid_width, ty = ti / itex->grid_width; - sprite.setTextureRect(sf::IntRect(tx * itex->grid_size, ty * itex->grid_size, itex->grid_size, itex->grid_size)); + //int tx = ti % itex->grid_width, ty = ti / itex->grid_width; + // sprite.setTextureRect(sf::IntRect(tx * itex->grid_size, ty * itex->grid_size, itex->grid_size, itex->grid_size)); + sprite = ptex->sprite(ti); } +*/ void UIGrid::render(sf::Vector2f) { @@ -325,20 +376,20 @@ void UIGrid::render(sf::Vector2f) box.getSize().x, box.getSize().y)); renderTexture.clear(sf::Color(8, 8, 8, 255)); // TODO - UIGrid needs a "background color" field // sprites that are visible according to zoom, center_x, center_y, and box width - float center_x_sq = center_x / itex->grid_size; - float center_y_sq = center_y / itex->grid_size; + float center_x_sq = center_x / ptex->sprite_width; + float center_y_sq = center_y / ptex->sprite_height; - float width_sq = box.getSize().x / (itex->grid_size * zoom); - float height_sq = box.getSize().y / (itex->grid_size * zoom); + float width_sq = box.getSize().x / (ptex->sprite_width * zoom); + float height_sq = box.getSize().y / (ptex->sprite_height * zoom); float left_edge = center_x_sq - (width_sq / 2.0); float top_edge = center_y_sq - (height_sq / 2.0); int left_spritepixels = center_x - (box.getSize().x / 2.0 / zoom); int top_spritepixels = center_y - (box.getSize().y / 2.0 / zoom); - sprite.setScale(sf::Vector2f(zoom, zoom)); + //sprite.setScale(sf::Vector2f(zoom, zoom)); sf::RectangleShape r; // for colors and overlays - r.setSize(sf::Vector2f(itex->grid_size * zoom, itex->grid_size * zoom)); + r.setSize(sf::Vector2f(ptex->sprite_width * zoom, ptex->sprite_height * zoom)); r.setOutlineThickness(0); int x_limit = left_edge + width_sq + 2; @@ -358,12 +409,12 @@ void UIGrid::render(sf::Vector2f) y+=1) { auto pixel_pos = sf::Vector2f( - (x*itex->grid_size - left_spritepixels) * zoom, - (y*itex->grid_size - top_spritepixels) * zoom ); + (x*ptex->sprite_width - left_spritepixels) * zoom, + (y*ptex->sprite_height - top_spritepixels) * zoom ); auto gridpoint = at(std::floor(x), std::floor(y)); - sprite.setPosition(pixel_pos); + //sprite.setPosition(pixel_pos); r.setPosition(pixel_pos); r.setFillColor(gridpoint.color); @@ -373,7 +424,7 @@ void UIGrid::render(sf::Vector2f) // if discovered but not visible, set opacity to 90% // if not discovered... just don't draw it? if (gridpoint.tilesprite != -1) { - setSprite(gridpoint.tilesprite); + sprite = ptex->sprite(gridpoint.tilesprite, pixel_pos, sf::Vector2f(zoom, zoom)); //setSprite(gridpoint.tilesprite);; renderTexture.draw(sprite); } } @@ -386,10 +437,10 @@ void UIGrid::render(sf::Vector2f) //auto drawent = e->cGrid->indexsprite.drawable(); auto& drawent = e->sprite; //drawent.setScale(zoom, zoom); - drawent.setScale(zoom); + drawent.setScale(sf::Vector2f(zoom, zoom)); auto pixel_pos = sf::Vector2f( - (e->position.x*itex->grid_size - left_spritepixels) * zoom, - (e->position.y*itex->grid_size - top_spritepixels) * zoom ); + (e->position.x*ptex->sprite_width - left_spritepixels) * zoom, + (e->position.y*ptex->sprite_height - top_spritepixels) * zoom ); //drawent.setPosition(pixel_pos); //renderTexture.draw(drawent); drawent.render(pixel_pos, renderTexture); @@ -469,3 +520,8 @@ PyObjectsEnum UIGrid::derived_type() { return PyObjectsEnum::UIGRID; } + +std::shared_ptr UIGrid::getTexture() +{ + return ptex; +} diff --git a/src/UI.h b/src/UI.h index 7df7861..c45fe42 100644 --- a/src/UI.h +++ b/src/UI.h @@ -6,6 +6,7 @@ #include "Resources.h" #include #include "PyCallable.h" +#include "PyTexture.h" enum PyObjectsEnum : int { @@ -97,23 +98,36 @@ public: class UISprite: public UIDrawable { +private: + int sprite_index; + sf::Sprite sprite; +protected: + std::shared_ptr ptex; public: UISprite(); - UISprite(IndexTexture*, int, float, float, float); - UISprite(IndexTexture*, int, sf::Vector2f, float); + //UISprite(IndexTexture*, int, float, float, float); + //UISprite(IndexTexture*, int, sf::Vector2f, float); + UISprite(std::shared_ptr, int, sf::Vector2f, float); void update(); void render(sf::Vector2f) override final; virtual UIDrawable* click_at(sf::Vector2f point) override final; // 7DRL hack - TODO apply RenderTexture concept to all UIDrawables (via `sf::RenderTarget`) void render(sf::Vector2f, sf::RenderTexture&); - int /*texture_index,*/ sprite_index; - IndexTexture* itex; - //float x, y, scale; - sf::Sprite sprite; - void setPosition(float, float); + //IndexTexture* itex; + //sf::Vector2f pos; + //float scale; + //void setPosition(float, float); void setPosition(sf::Vector2f); - void setScale(float); + sf::Vector2f getPosition(); + void setScale(sf::Vector2f); + sf::Vector2f getScale(); + void setSpriteIndex(int); + int getSpriteIndex(); + + void setTexture(std::shared_ptr _ptex, int _sprite_index=-1); + std::shared_ptr getTexture(); + PyObjectsEnum derived_type() override final; // { return PyObjectsEnum::UISprite; }; }; @@ -155,22 +169,25 @@ public: class UIGrid: public UIDrawable { +private: + std::shared_ptr ptex; public: UIGrid(); - UIGrid(int, int, IndexTexture*, float, float, float, float); - UIGrid(int, int, IndexTexture*, sf::Vector2f, sf::Vector2f); + //UIGrid(int, int, IndexTexture*, float, float, float, float); + UIGrid(int, int, std::shared_ptr, sf::Vector2f, sf::Vector2f); void update(); void render(sf::Vector2f) override final; UIGridPoint& at(int, int); PyObjectsEnum derived_type() override final; - void setSprite(int); + //void setSprite(int); virtual UIDrawable* click_at(sf::Vector2f point) override final; int grid_x, grid_y; //int grid_size; // grid sizes are implied by IndexTexture now sf::RectangleShape box; float center_x, center_y, zoom; - IndexTexture* itex; + //IndexTexture* itex; + std::shared_ptr getTexture(); sf::Sprite sprite, output; sf::RenderTexture renderTexture; std::vector points; @@ -201,7 +218,7 @@ typedef struct { typedef struct { PyObject_HEAD std::shared_ptr data; - PyObject* texture; + //PyObject* texture; } PyUISpriteObject; typedef struct { @@ -225,13 +242,13 @@ typedef struct { typedef struct { PyObject_HEAD std::shared_ptr data; - PyObject* texture; + //PyObject* texture; } PyUIEntityObject; typedef struct { PyObject_HEAD std::shared_ptr data; - PyObject* texture; + //PyObject* texture; } PyUIGridObject; namespace mcrfpydef { @@ -1063,55 +1080,6 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c * */ - /* - * - * Begin PyTextureType defs - * - */ - - typedef struct { - PyObject_HEAD - std::shared_ptr data; - } PyTextureObject; - - static int PyTexture_init(PyTextureObject* self, PyObject* args, PyObject* kwds) - { - //std::cout << "Init called\n"; - static const char* keywords[] = { "filename", "grid_size", "grid_width", "grid_height", nullptr }; - char* filename; - int grid_size, grid_width, grid_height; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "siii", const_cast(keywords), &filename, &grid_size, &grid_width, &grid_height)) - { - return -1; - } - sf::Texture t = sf::Texture(); - t.loadFromFile((std::string)filename); - self->data = std::make_shared(t, grid_size, grid_width, grid_height); - return 0; - } - - static PyTypeObject PyTextureType = { - //PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "mcrfpy.Texture", - .tp_basicsize = sizeof(PyTextureObject), - .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = PyDoc_STR("SFML Texture Object"), - .tp_init = (initproc)PyTexture_init, - .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject* - { - PyTextureObject* self = (PyTextureObject*)type->tp_alloc(type, 0); - return (PyObject*)self; - } - }; - - /* - * - * End PyTextureType defs - * - */ - /* * * Begin template generation for PyUISpriteType @@ -1122,11 +1090,11 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c { auto member_ptr = reinterpret_cast(closure); if (member_ptr == 0) - return PyFloat_FromDouble(self->data->sprite.getPosition().x); + return PyFloat_FromDouble(self->data->getPosition().x); else if (member_ptr == 1) - return PyFloat_FromDouble(self->data->sprite.getPosition().y); + return PyFloat_FromDouble(self->data->getPosition().y); else if (member_ptr == 2) - return PyFloat_FromDouble(self->data->sprite.getScale().x); // scale X and Y are identical, presently + return PyFloat_FromDouble(self->data->getScale().x); // scale X and Y are identical, presently else { PyErr_SetString(PyExc_AttributeError, "Invalid attribute"); @@ -1153,11 +1121,11 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c return -1; } if (member_ptr == 0) //x - self->data->sprite.setPosition(val, self->data->sprite.getPosition().y); + self->data->setPosition(sf::Vector2f(val, self->data->getPosition().y)); else if (member_ptr == 1) //y - self->data->sprite.setPosition(self->data->sprite.getPosition().x, val); + self->data->setPosition(sf::Vector2f(self->data->getPosition().x, val)); else if (member_ptr == 2) // scale - self->data->sprite.setScale(sf::Vector2f(val, val)); + self->data->setScale(sf::Vector2f(val, val)); return 0; } @@ -1171,7 +1139,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c return nullptr; } - return PyLong_FromDouble(self->data->sprite_index); + return PyLong_FromDouble(self->data->getSpriteIndex()); } @@ -1188,14 +1156,15 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c PyErr_SetString(PyExc_TypeError, "Value must be an integer."); return -1; } - self->data->sprite_index = val; - self->data->sprite.setTextureRect(self->data->itex->spriteCoordinates(val)); + //self->data->sprite_index = val; + //self->data->sprite.setTextureRect(self->data->itex->spriteCoordinates(val)); + self->data->setSpriteIndex(val); return 0; } static PyObject* PyUISprite_get_texture(PyUISpriteObject* self, void* closure) { - return NULL; + return self->data->getTexture()->pyObject(); } static int PyUISprite_set_texture(PyUISpriteObject* self, PyObject* value, void* closure) @@ -1218,10 +1187,10 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c std::ostringstream ss; if (!self->data) ss << ""; else { - auto sprite = self->data->sprite; - ss << ""; + //auto sprite = self->data->sprite; + ss << ""; } std::string repr_str = ss.str(); return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); @@ -1248,17 +1217,17 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){ PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance"); return -1; - } else if (texture != NULL) + } /*else if (texture != NULL) // to be removed: UIObjects don't manage texture references { self->texture = texture; Py_INCREF(texture); } else { // default tex? - } + }*/ auto pytexture = (PyTextureObject*)texture; - self->data = std::make_shared(pytexture->data.get(), sprite_index, sf::Vector2f(x, y), scale); - self->data->sprite.setPosition(sf::Vector2f(x, y)); + self->data = std::make_shared(pytexture->data, sprite_index, sf::Vector2f(x, y), scale); + self->data->setPosition(sf::Vector2f(x, y)); return 0; } @@ -1272,7 +1241,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c { PyUISpriteObject* obj = (PyUISpriteObject*)self; // release reference to font object - if (obj->texture) Py_DECREF(obj->texture); + //if (obj->texture) Py_DECREF(obj->texture); obj->data.reset(); Py_TYPE(self)->tp_free(self); }, @@ -1548,7 +1517,7 @@ static PyObject* PyUIEntity_get_gridstate(PyUIEntityObject* self, void* closure) } static PyObject* PyUIEntity_get_spritenumber(PyUIEntityObject* self, void* closure) { - return PyLong_FromDouble(self->data->sprite.sprite_index); + return PyLong_FromDouble(self->data->sprite.getSpriteIndex()); } static int PyUIEntity_set_spritenumber(PyUIEntityObject* self, PyObject* value, void* closure) { @@ -1560,8 +1529,8 @@ static int PyUIEntity_set_spritenumber(PyUIEntityObject* self, PyObject* value, PyErr_SetString(PyExc_TypeError, "Value must be an integer."); return -1; } - self->data->sprite.sprite_index = val; - self->data->sprite.sprite.setTextureRect(self->data->sprite.itex->spriteCoordinates(val)); // TODO - I don't like ".sprite.sprite" in this stack of UIEntity.UISprite.sf::Sprite + //self->data->sprite.sprite_index = val; + self->data->sprite.setSpriteIndex(val); // todone - I don't like ".sprite.sprite" in this stack of UIEntity.UISprite.sf::Sprite return 0; } @@ -1648,11 +1617,12 @@ static int PyUIGrid_init(PyUIGridObject* self, PyObject* args, PyObject* kwds) { } PyTextureObject* pyTexture = reinterpret_cast(textureObj); // TODO (7DRL day 2, item 4.) use shared_ptr / PyTextureObject on UIGrid - IndexTexture* texture = pyTexture->data.get(); - + //IndexTexture* texture = pyTexture->data.get(); + // Initialize UIGrid //self->data = new UIGrid(grid_x, grid_y, texture, sf::Vector2f(box_x, box_y), sf::Vector2f(box_w, box_h)); - self->data = std::make_shared(grid_x, grid_y, texture, box_x, box_y, box_w, box_h); + self->data = std::make_shared(grid_x, grid_y, pyTexture->data, + sf::Vector2f(box_x, box_y), sf::Vector2f(box_w, box_h)); return 0; // Success } @@ -1770,6 +1740,12 @@ static PyObject* PyUIGrid_get_texture(PyUIGridObject* self, void* closure) { return self->texture; } */ +static PyObject* PyUIGrid_get_texture(PyUIGridObject* self, void* closure) { + //return self->data->getTexture()->pyObject(); + PyTextureObject* obj = (PyTextureObject*)((&PyTextureType)->tp_alloc(&PyTextureType, 0)); + obj->data = self->data->getTexture(); + return (PyObject*)obj; +} static PyObject* PyUIGrid_at(PyUIGridObject* self, PyObject* o) { @@ -1821,7 +1797,7 @@ static PyGetSetDef PyUIGrid_getsetters[] = { {"click", (getter)PyUIDrawable_get_click, (setter)PyUIDrawable_set_click, "Object called with (x, y, button) when clicked", (void*)PyObjectsEnum::UIGRID}, - //{"texture", (getter)PyUIGrid_get_texture, NULL, "Texture of the grid", NULL}, //TODO 7DRL-day2-item5 + {"texture", (getter)PyUIGrid_get_texture, NULL, "Texture of the grid", NULL}, //TODO 7DRL-day2-item5 {NULL} /* Sentinel */ }; @@ -1892,14 +1868,14 @@ static int PyUIEntity_init(PyUIEntityObject* self, PyObject* args, PyObject* kwd if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){ PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance"); return -1; - } else if (texture != NULL) + } /*else if (texture != NULL) // this section needs to go; texture isn't optional and isn't managed by the UI objects anymore { self->texture = texture; Py_INCREF(texture); } else { // default tex? - } + }*/ if (grid != NULL && !PyObject_IsInstance(grid, (PyObject*)&PyUIGridType)) { PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance"); @@ -1913,7 +1889,7 @@ static int PyUIEntity_init(PyUIEntityObject* self, PyObject* args, PyObject* kwd self->data = std::make_shared(*((PyUIGridObject*)grid)->data); // TODO - PyTextureObjects and IndexTextures are a little bit of a mess with shared/unshared pointers - self->data->sprite = UISprite(pytexture->data.get(), sprite_index, sf::Vector2f(0,0), 1.0); + self->data->sprite = UISprite(pytexture->data, sprite_index, sf::Vector2f(0,0), 1.0); self->data->position = sf::Vector2f(x, y); if (grid != NULL) { PyUIGridObject* pygrid = (PyUIGridObject*)grid; diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index ff70c53..9250402 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -61,15 +61,15 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) //ui_elements.push_back(&e1); //ui_elements.push_back(&e2); - t.loadFromFile("./assets/kenney_tinydungeon.png"); - t.setSmooth(false); - auto* indextex = new IndexTexture(t, 16, 12, 11); - Resources::game->textures.push_back(*indextex); - + //t.loadFromFile("./assets/kenney_tinydungeon.png"); + //t.setSmooth(false); + //auto* indextex = new IndexTexture(t, 16, 12, 11); + //Resources::game->textures.push_back(*indextex); + auto ptex = std::make_shared("./assets/kenney_tinydungeon.png", 16, 16); //std::cout << Resources::game->textures.size() << " textures loaded.\n"; - auto e3 = std::make_shared(); + auto e3 = std::make_shared(ptex, 84, sf::Vector2f(10, 10), 4.0); // Make UISprite more like IndexSprite: this is bad //e3->x = 10; e3->y = 10; @@ -79,19 +79,19 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) //e3->update(); // This goes to show how inconvenient the default constructor is. It should be removed - e3->itex = &Resources::game->textures[0]; - e3->sprite.setTexture(e3->itex->texture); - e3->sprite_index = 84; - e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index)); - e3->setPosition(10, 10); - e3->setScale(4.0f); + //e3->itex = &Resources::game->textures[0]; + //e3->sprite.setTexture(e3->itex->texture); + //e3->sprite_index = 84; + //e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index)); + //e3->setPosition(10, 10); + //e3->setScale(4.0f); e1aa->children->push_back(e3); auto e4 = std::make_shared( - indextex, //&Resources::game->textures[0], + ptex, //indextex, //&Resources::game->textures[0], 85, sf::Vector2f(90, 10), 4.0); e1aa->children->push_back(e4); //std::cout << "UISprite built: " << e4->sprite.getPosition().x << " " << e4->sprite.getPosition().y << " " << e4->sprite.getScale().x << " " << @@ -104,9 +104,9 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl; */ - // UIGrid test: (in grid cells) (in screen pixels) - // constructor args: w h texture x y w h - auto e5 = std::make_shared(4, 4, indextex, 550, 150, 200, 200); + // UIGrid test: (in grid cells) ( in screen pixels ) + // constructor args: w h texture x y w h + auto e5 = std::make_shared(4, 4, ptex, sf::Vector2f(550, 150), sf::Vector2f(200, 200)); e5->zoom=2.0; e5->points[0].color = sf::Color(255, 0, 0); e5->points[1].tilesprite = 1; @@ -125,7 +125,7 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) e5a->grid = e5; //auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); //e5a->sprite = e5as; // will copy constructor even exist for UISprite...? - e5a->sprite = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); + e5a->sprite = UISprite(ptex, 85, sf::Vector2f(0, 0), 1.0); e5a->position = sf::Vector2f(1, 0); e5->entities->push_back(e5a); diff --git a/src/scripts/cos_play.py b/src/scripts/cos_play.py index fef09c1..5cc9ffd 100644 --- a/src/scripts/cos_play.py +++ b/src/scripts/cos_play.py @@ -1,7 +1,7 @@ import mcrfpy mcrfpy.createScene("play") ui = mcrfpy.sceneUI("play") -t = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 12, 11) +t = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) # 12, 11) font = mcrfpy.Font("assets/JetbrainsMono.ttf") frame_color = (64, 64, 128) diff --git a/src/scripts/game.py b/src/scripts/game.py index 18e46d0..c022aca 100644 --- a/src/scripts/game.py +++ b/src/scripts/game.py @@ -3,9 +3,9 @@ import mcrfpy import cos_play # Universal stuff font = mcrfpy.Font("assets/JetbrainsMono.ttf") -texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 12, 11) -texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 12, 11) -texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 12, 11) +texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) +texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) +texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) # Test stuff mcrfpy.createScene("boom") @@ -125,7 +125,7 @@ stress_test() mcrfpy.createScene("loading") ui = mcrfpy.sceneUI("loading") #mcrfpy.setScene("loading") -logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1, 1) +logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) ui.append(logo_sprite) logo_sprite.click = lambda *args: mcrfpy.setScene("menu")