Squashed commit of the following: [standardize_texture_handling]
closes #18 commitb114ec3085
Author: John McCardle <mccardle.john@gmail.com> Date: Thu Mar 21 22:22:35 2024 -0400 cleaning up for merge commitd7228172c4
Author: John McCardle <mccardle.john@gmail.com> Date: Thu Mar 21 21:39:15 2024 -0400 Messy, but monumental: PyTexture::pyObject works this also coincidentally fixes a weird bug I encountered while (mis?)using tp_alloc: by using PyType_GenericAlloc, I avoid the segfault that tp_alloc sometimes causes. See the horrible UIDrawable retrieval macro that I use in UI.h for a workaround that can probably be replaced with this technique commit2cf8f94310
Author: John McCardle <mccardle.john@gmail.com> Date: Wed Mar 20 21:16:52 2024 -0400 Radical new example pattern for exposing a C++ class to Python commit84a8886da2
Author: John McCardle <mccardle.john@gmail.com> Date: Sun Mar 17 16:29:33 2024 -0400 Fixed render issue with UIGrid / PyTexture: wasn't positioning or scaling properly after fetching sprite commit20f80c4114
Author: John McCardle <mccardle.john@gmail.com> Date: Sun Mar 17 16:23:52 2024 -0400 Fixed sprite indexing error in PyTexture; needs non-square sprite tests, but feeling confident! commitafd4ff1925
Author: John McCardle <mccardle.john@gmail.com> Date: Sat Mar 16 21:53:24 2024 -0400 good progress, we're building again. Issue with Grid (tile sprite) textures and I think the sprite indexes are being calculated wrong (x and y transposed?) commitbfd33102d1
Author: John McCardle <mccardle.john@gmail.com> Date: Sat Mar 16 14:52:35 2024 -0400 Squashed basically all the compile bugs in UISprite, but UIEntity and UIGrid use textures as well, so they need to be fixed too before the project will build again commit47d0e34a17
Author: John McCardle <mccardle.john@gmail.com> Date: Sat Mar 16 11:31:39 2024 -0400 Initial PyTexture class no testing done. should enable rectangular (non-square) textures "sprite" method; let's just overwrite sprites with texture coords Hoping to replace awful code like: `self->data->sprite.sprite.setTextureRect(self->data->sprite.itex->spriteCoordinates(val));` with something like: `self->data->sprite = self->data->texture->sprite(val);`
This commit is contained in:
parent
cdaf309272
commit
4ffe438d1b
|
@ -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);
|
||||
using namespace mcrfpydef;
|
||||
PyTypeObject* pytypes[] = {
|
||||
/*SFML exposed types*/
|
||||
&PyColorType, &PyFontType, &PyTextureType,
|
||||
|
||||
if (PyModule_AddType(m, &mcrfpydef::PyUIFrameType) < 0)
|
||||
/*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;
|
||||
}
|
||||
|
|
|
@ -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<Py_hash_t>(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<char**>(keywords), &filename, &sprite_width, &sprite_height))
|
||||
return -1;
|
||||
self->data = std::make_shared<PyTexture>(filename, sprite_width, sprite_height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* PyTexture::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
||||
{
|
||||
return (PyObject*)type->tp_alloc(type, 0);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "Python.h"
|
||||
|
||||
class PyTexture;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
std::shared_ptr<PyTexture> data;
|
||||
} PyTextureObject;
|
||||
|
||||
class PyTexture : public std::enable_shared_from_this<PyTexture>
|
||||
{
|
||||
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,
|
||||
};
|
||||
}
|
104
src/UI.cpp
104
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<PyTexture> _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<PyTexture> _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<PyTexture> 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<PyTexture> _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<PyTexture> _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<std::list<std::shared_ptr<UIEntity>>>();
|
||||
|
@ -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<PyTexture> UIGrid::getTexture()
|
||||
{
|
||||
return ptex;
|
||||
}
|
||||
|
|
160
src/UI.h
160
src/UI.h
|
@ -6,6 +6,7 @@
|
|||
#include "Resources.h"
|
||||
#include <list>
|
||||
#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<PyTexture> 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<PyTexture>, 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<PyTexture> _ptex, int _sprite_index=-1);
|
||||
std::shared_ptr<PyTexture> getTexture();
|
||||
|
||||
PyObjectsEnum derived_type() override final; // { return PyObjectsEnum::UISprite; };
|
||||
};
|
||||
|
||||
|
@ -155,22 +169,25 @@ public:
|
|||
|
||||
class UIGrid: public UIDrawable
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<PyTexture> 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<PyTexture>, 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<PyTexture> getTexture();
|
||||
sf::Sprite sprite, output;
|
||||
sf::RenderTexture renderTexture;
|
||||
std::vector<UIGridPoint> points;
|
||||
|
@ -201,7 +218,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
PyObject_HEAD
|
||||
std::shared_ptr<UISprite> data;
|
||||
PyObject* texture;
|
||||
//PyObject* texture;
|
||||
} PyUISpriteObject;
|
||||
|
||||
typedef struct {
|
||||
|
@ -225,13 +242,13 @@ typedef struct {
|
|||
typedef struct {
|
||||
PyObject_HEAD
|
||||
std::shared_ptr<UIEntity> data;
|
||||
PyObject* texture;
|
||||
//PyObject* texture;
|
||||
} PyUIEntityObject;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
std::shared_ptr<UIGrid> 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<IndexTexture> 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<char**>(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<IndexTexture>(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<long>(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 << "<Sprite (invalid internal object)>";
|
||||
else {
|
||||
auto sprite = self->data->sprite;
|
||||
ss << "<Sprite (x=" << sprite.getPosition().x << ", y=" << sprite.getPosition().y << ", " <<
|
||||
"scale=" << sprite.getScale().x << ", " <<
|
||||
"sprite_number=" << self->data->sprite_index << ")>";
|
||||
//auto sprite = self->data->sprite;
|
||||
ss << "<Sprite (x=" << self->data->getPosition().x << ", y=" << self->data->getPosition().y << ", " <<
|
||||
"scale=" << self->data->getScale().x << ", " <<
|
||||
"sprite_number=" << self->data->getSpriteIndex() << ")>";
|
||||
}
|
||||
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<UISprite>(pytexture->data.get(), sprite_index, sf::Vector2f(x, y), scale);
|
||||
self->data->sprite.setPosition(sf::Vector2f(x, y));
|
||||
self->data = std::make_shared<UISprite>(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<PyTextureObject*>(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<UIGrid>(grid_x, grid_y, texture, box_x, box_y, box_w, box_h);
|
||||
self->data = std::make_shared<UIGrid>(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<UIEntity>(*((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;
|
||||
|
|
|
@ -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<PyTexture>("./assets/kenney_tinydungeon.png", 16, 16);
|
||||
|
||||
//std::cout << Resources::game->textures.size() << " textures loaded.\n";
|
||||
auto e3 = std::make_shared<UISprite>();
|
||||
auto e3 = std::make_shared<UISprite>(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<UISprite>(
|
||||
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)
|
||||
// UIGrid test: (in grid cells) ( in screen pixels )
|
||||
// constructor args: w h texture x y w h
|
||||
auto e5 = std::make_shared<UIGrid>(4, 4, indextex, 550, 150, 200, 200);
|
||||
auto e5 = std::make_shared<UIGrid>(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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue