Added caching for the grid texture.

Modified the rendering of the grid texture to render only what fits within the presented rectangle.
This commit is contained in:
Tim Schubert 2016-01-27 02:41:18 +01:00
parent 7f21c3bb3f
commit 32eae1e97d
9 changed files with 296 additions and 285 deletions

View file

@ -82,14 +82,28 @@ void Game::handle_event(SDL_Event *event)
}
break;
default:
if (event->type == BOB_MARKERUPDATE || event->type == BOB_NEXTTURNEVENT ||
event->type == BOB_FIELDUPDATEEVENT || event->type == BOB_FIELDSELECTED
if (event->type == BOB_MARKERUPDATE
|| event->type == BOB_NEXTROUNDEVENT
|| event->type == BOB_FIELDUPDATEEVENT
|| event->type == BOB_FIELDSELECTEDEVENT
|| event->type == BOB_FIELDUPGRADEVENT)
{
this->grid->handle_event(event);
this->field_box->handle_event(event);
this->upgrade_box->handle_event(event);
}
else
{
if (event->type == BOB_NEXTTURNEVENT)
{
this->current_player++;
if (Player::current_player == Player::players.end())
{
Player::current_player = Player::players.begin();
trigger_event(BOB_NEXTROUNDEVENT, 0x0, (void *) *(Player::current_player), nullptr);
}
}
}
break;
}
}
@ -112,6 +126,7 @@ int Game::game_loop()
{
fps = frame_counter / (this->frame_timer->reset_timer() / 1000.0);
frame_counter = 0;
std::cout << fps << std::endl;
this->test_box->load_text(std::to_string(fps));
}
SDL_Event event;
@ -130,12 +145,12 @@ void Game::render()
{
try
{
this->renderer->set_draw_color({0x0, 0x0, 0x0, 0x0});
this->renderer->set_draw_color({0x0, 0x0, 0x0, 0xff});
this->renderer->clear();
this->grid->render(this->renderer);
this->test_box->render(this->renderer);
this->field_box->render(this->renderer);
this->upgrade_box->render(this->renderer);
this->grid->render(this->renderer->get_renderer());
this->renderer->present();
}
catch (const SDL_RendererException &err)
@ -175,7 +190,7 @@ int main(int, char **)
SDL_Rect bounds;
SDL_GetDisplayBounds(0, &bounds);
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, bounds.w, bounds.h};
Game *game = new Game(&window_dimensions, 6);
Game *game = new Game(&window_dimensions, 20);
int exit_status = 1;
exit_status = game->game_loop();
delete game;

View file

@ -23,7 +23,6 @@ public:
this->layout = new Layout(pointy_orientation, 20,
{window_dimensions->w / 2, window_dimensions->h / 2},
{0, 0, window_dimensions->w, window_dimensions->h});
this->grid = new HexagonGrid(size, this->layout);
for (int i = 0; i < 4; i++)
{
this->move[i] = false;
@ -36,6 +35,7 @@ public:
this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
| SDL_RENDERER_TARGETTEXTURE);
this->grid = new HexagonGrid(size, this->layout, this->renderer);
FieldMeta *center = this->grid->get_field({0, 0, 0});
this->field_box = new FieldBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center);
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 1, 1}, fg, this->font, center);
@ -70,6 +70,7 @@ public:
int game_loop();
private:
UpgradeBox *upgrade_box;
FieldBox *field_box;
TextBox *test_box;

View file

@ -1,2 +1,2 @@
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp Pixelmask.h)
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp Pixelmask.h Wrapper.hpp Wrapper.cpp)
target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES})

View file

@ -1,11 +1,11 @@
#include "Events.hpp"
const Uint32 BOB_NEXTTURNEVENT = register_events(1);
const Uint32 BOB_NEXTROUNDEVENT = register_events(1);
const Uint32 BOB_MARKERUPDATE = register_events(1);
const Uint32 BOB_FIELDUPDATEEVENT = register_events(1);
const Uint32 BOB_FIELDSELECTED = register_events(1);
const Uint32 BOB_FIELDSELECTEDEVENT = register_events(1);
const Uint32 BOB_FIELDUPGRADEVENT = register_events(1);
const Uint32 BOB_NEXTTURNEVENT = register_events(1);
bool Timer::MOUSE_LOCKED = false;
@ -34,3 +34,14 @@ Uint32 register_events(Uint32 n)
throw SDL_Exception("Failed to register events!");
return base_event;
}
void trigger_event(Uint32 type, Sint32 code, void *data1, void *data2)
{
SDL_Event event;
SDL_memset(&event, 0, sizeof(event)); /* or SDL_zero(event) */
event.type = type;
event.user.code = code;
event.user.data1 = static_cast<void *>(data1);
event.user.data2 = data2;
SDL_PushEvent(&event);
}

View file

@ -7,11 +7,12 @@
#ifndef _EVENT_TYPES
#define _EVENT_TYPES
extern const Uint32 BOB_NEXTTURNEVENT;
extern const Uint32 BOB_NEXTROUNDEVENT;
extern const Uint32 BOB_MARKERUPDATE;
extern const Uint32 BOB_FIELDUPDATEEVENT;
extern const Uint32 BOB_FIELDSELECTED;
extern const Uint32 BOB_FIELDSELECTEDEVENT;
extern const Uint32 BOB_FIELDUPGRADEVENT;
extern const Uint32 BOB_NEXTTURNEVENT;
#endif
Uint32 register_events(Uint32 n);
@ -43,4 +44,6 @@ struct FieldUpdate
Sint16 z;
};
void trigger_event(Uint32 type, Sint32 code, void *data1, void *data2);
#endif

View file

@ -1,5 +1,7 @@
#include "Gameplay.hpp"
static std::vector<Player *>::iterator Player::current_player = Player::players.end();
SDL_Point operator+(SDL_Point left, SDL_Point right)
{
return {left.x + right.x, left.y + right.y};
@ -116,6 +118,27 @@ std::vector<Point> Field::field_to_polygon(const Layout *layout) const
return corners;
}
std::vector<SDL_Point> Field::field_to_polygon_sdl(const Layout *layout) const
{
std::vector<SDL_Point> corners;
for (uint8_t i = 0; i < 6; i++)
{
Point center = this->field_to_point(layout);
Point offset = field_corner_offset(i, layout);
SDL_Point p;
p.x = (int) offset.x + center.x;
p.y = (int) offset.y + center.y;
corners.push_back(p);
}
Point center = this->field_to_point(layout);
Point offset = field_corner_offset(0, layout);
SDL_Point p;
p.x = (int) offset.x + center.x;
p.y = (int) offset.y + center.y;
corners.push_back(p);
return corners;
}
std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) const
{
std::vector<Point> corners;
@ -127,73 +150,6 @@ std::vector<Point> Field::field_to_polygon_normalized(const Layout *layout) cons
return corners;
}
void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
{
Point precise_location = this->field.field_to_point(layout);
SDL_Point location;
location.x = (int) precise_location.x;
location.y = (int) precise_location.y;
std::vector<Point> polygon = this->field.field_to_polygon(layout);
SDL_Color color = this->owner->get_color();
Sint16 vx[6];
Sint16 vy[6];
for (int i = 0; i < 6; i++)
{
vx[i] = (Sint16) polygon[i].x;
vy[i] = (Sint16) polygon[i].y;
}
if (this->owner->get_id().is_nil())
color = {0x77, 0x77, 0x77, 0x77};
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x22);
SDL_Color inverse;
inverse.r = (Uint8) (color.r + 0x77);
inverse.g = (Uint8) (color.g + 0x77);
inverse.b = (Uint8) (color.b + 0x77);
inverse.a = 0xff;
double resource_size = layout->size / 4;
if (this->resources_base.triangle > 0)
{
static const SDL_Point trigon[] = {{0, -1},
{-1, 1},
{1, 1}};
for (int i = 0; i < 3; i++)
{
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
}
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a);
}
if (this->resources_base.circle > 0)
{
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g,
inverse.b, inverse.a);
}
if (this->resources_base.square > 0)
{
static const SDL_Point square[] = {{-1, -1},
{-1, 1},
{1, 1},
{1, -1}};
for (int i = 0; i < 4; i++)
{
vx[i] = (Sint16) (location.x + square[i].x * resource_size);
vy[i] = (Sint16) (location.y + square[i].y * resource_size);
}
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a);
}
}
void FieldMeta::trigger_event(Uint32 type, Sint32 code)
{
SDL_Event event;
SDL_memset(&event, 0, sizeof(event)); /* or SDL_zero(event) */
event.type = type;
event.user.code = code;
event.user.data1 = static_cast<void *>(this);
event.user.data2 = 0;
SDL_PushEvent(&event);
}
void FieldMeta::regenerate_resources()
{
this->resources = resources_base;
@ -203,7 +159,7 @@ void FieldMeta::regenerate_resources()
this->resources *= 2;
if (this->upgrades[Regeneration_3])
this->resources *= 2;
this->trigger_event(BOB_FIELDUPDATEEVENT, 0);
trigger_event(BOB_FIELDUPDATEEVENT, 0, (void *) this, nullptr);
}
Resource HexagonGrid::get_resources_of_cluster(Cluster *cluster)
@ -237,7 +193,7 @@ bool FieldMeta::upgrade(Upgrade upgrade)
this->upgrades[upgrade] = true;
}
}
this->trigger_event(BOB_FIELDUPGRADEVENT, 0);
trigger_event(BOB_FIELDUPGRADEVENT, 0, (void *) this, nullptr);
return this->upgrades[upgrade];
}
@ -283,7 +239,6 @@ Cluster HexagonGrid::get_cluster(FieldMeta *field)
void FieldMeta::consume_resources(Resource costs)
{
this->resources -= costs;
this->trigger_event(BOB_FIELDUPDATEEVENT, 0);
}
Resource HexagonGrid::consume_resources_of_cluster(Cluster *cluster, Resource costs)
@ -295,6 +250,7 @@ Resource HexagonGrid::consume_resources_of_cluster(Cluster *cluster, Resource co
costs -= meta->get_resources();
meta->consume_resources(tmp);
}
trigger_event(BOB_FIELDUPDATEEVENT, 0, (void *) this, nullptr);
return costs; // > {0, 0, 0} means there were not enough resources
}
@ -335,35 +291,131 @@ bool Player::fight(FieldMeta *field)
void FieldMeta::handle_event(const SDL_Event *event)
{
if (event->type == BOB_NEXTTURNEVENT)
if (event->type == BOB_NEXTROUNDEVENT)
{
this->regenerate_resources();
}
}
bool HexagonGrid::render(SDL_Renderer *renderer)
void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
{
Point precise_location = this->field.field_to_point(layout);
SDL_Point location;
location.x = (int) precise_location.x;
location.y = (int) precise_location.y;
std::vector<Point> polygon = this->field.field_to_polygon(layout);
SDL_Color color = this->owner->get_color();
Sint16 vx[6];
Sint16 vy[6];
for (int i = 0; i < 6; i++)
{
vx[i] = (Sint16) polygon[i].x;
vy[i] = (Sint16) polygon[i].y;
}
if (this->owner->get_id().is_nil())
color = {0x77, 0x77, 0x77, 0xff};
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77);
SDL_Color inverse;
inverse.r = (Uint8) (color.r + 0x77);
inverse.g = (Uint8) (color.g + 0x77);
inverse.b = (Uint8) (color.b + 0x77);
inverse.a = 0xff;
double resource_size = layout->size / 4;
if (this->resources_base.triangle > 0)
{
static const SDL_Point trigon[] = {{0, -1},
{-1, 1},
{1, 1}};
for (int i = 0; i < 3; i++)
{
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
}
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a);
}
if (this->resources_base.circle > 0)
{
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g,
inverse.b, inverse.a);
}
if (this->resources_base.square > 0)
{
static const SDL_Point square[] = {{-1, -1},
{-1, 1},
{1, 1},
{1, -1}};
for (int i = 0; i < 4; i++)
{
vx[i] = (Sint16) (location.x + square[i].x * resource_size);
vy[i] = (Sint16) (location.y + square[i].y * resource_size);
}
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a);
}
}
void HexagonGrid::load()
{
if (this->texture == nullptr)
{
SDL_Rect db;
SDL_GetDisplayBounds(0, &db);
this->texture = SDL_CreateTexture(this->renderer->get_renderer(), SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, db.w, db.h);
}
this->renderer->set_target(this->texture);
renderer->set_draw_color({0x00, 0x00, 0x00, 0x00});
this->renderer->clear();
SDL_Rect bounds = this->layout->box;
bounds.x -= 4 * this->layout->size;
bounds.y -= 4 * this->layout->size;
bounds.w += 8 * this->layout->size;
bounds.h += 8 * this->layout->size;
renderer->set_draw_color({0xff, 0xff, 0xff, 0xff});
renderer->set_blend_mode(SDL_BLENDMODE_BLEND);
Field some_field = {0, 0, 0};
std::vector<Point> polygon = some_field.field_to_polygon_normalized(this->layout);
assert(polygon.size() > 5);
Sint16 x[6];
Sint16 y[6];
std::vector<Point> norm_polygon = some_field.field_to_polygon_normalized(this->layout);
for (std::pair<Field, FieldMeta *> const &elem : this->fields)
{
Field field = elem.first;
Point center = field.field_to_point(this->layout);
for (uint8_t i = 0; i < 6; i++)
SDL_Point i_c;
i_c.x = (int) center.x;
i_c.y = (int) center.y;
if (inside_target(&bounds, &i_c))
{
x[i] = (Sint16) (center.x + polygon[i].x);
y[i] = (Sint16) (center.y + polygon[i].y);
elem.second->load(this->renderer->get_renderer(), this->layout);
//std::vector<SDL_Point> polygon = field.field_to_polygon_sdl(this->layout);
Sint16 vx[6];
Sint16 vy[6];
for (int i = 0; i < 6; i++)
{
vx[i] = (Sint16) (center.x + norm_polygon[i].x);
vy[i] = (Sint16) (center.y + norm_polygon[i].y);
}
const SDL_Color color = {0xff, 0xff, 0xff, 0xff};
polygonRGBA(renderer, x, y, 6, color.r, color.g, color.b, color.a);
/*if (SDL_RenderDrawLines(renderer->get_renderer(), polygon.data(), 7) < 0)
{
throw SDL_RendererException();
}*/
polygonRGBA(renderer->get_renderer(), vx, vy, 6, 0xff, 0xff, 0xff, 0xff);
if (elem.first == this->marker->get_field())
{
filledPolygonRGBA(renderer, x, y, 6, 0x77, 0x77, 0x77, 0x22);
filledPolygonRGBA(this->renderer->get_renderer(), vx, vy, 6, 0x77, 0x77, 0x77, 0x77);
}
elem.second->render(renderer, this->layout);
}
return true;
}
this->renderer->set_target(nullptr);
}
void HexagonGrid::render(Renderer *renderer)
{
if (this->changed)
{
this->load();
this->changed = false;
}
//this->load();
renderer->copy(this->texture, &(this->layout->box), &(this->layout->box));
}
void HexagonGrid::handle_event(SDL_Event *event)
@ -380,9 +432,9 @@ void HexagonGrid::handle_event(SDL_Event *event)
{
this->layout->size = 20;
}
else if (old_size + scroll > 1000)
else if (old_size + scroll > 100)
{
this->layout->size = 1000;
this->layout->size = 100;
}
else
{
@ -390,7 +442,14 @@ void HexagonGrid::handle_event(SDL_Event *event)
}
this->move(((1.0 - (double) this->layout->size / old_size) * (mouse - old_origin)));
if (!on_rectangle(&layout->box))
{
this->layout->size -= scroll;
}
else
{
this->update_marker();
this->changed = true;
}
break;
case SDL_MOUSEMOTION:
if (this->panning)
@ -400,8 +459,8 @@ void HexagonGrid::handle_event(SDL_Event *event)
p.x = (int) marker_pos.x;
p.y = (int) marker_pos.y;
this->move(mouse - p);
this->changed = true;
}
this->update_marker();
break;
case SDL_MOUSEBUTTONDOWN:
switch (event->button.button)
@ -410,13 +469,23 @@ void HexagonGrid::handle_event(SDL_Event *event)
this->panning = !(this->panning);
break;
case SDL_BUTTON_RIGHT:
this->marker->trigger_event(BOB_FIELDSELECTED, 0);
trigger_event(BOB_FIELDSELECTEDEVENT, 0, (void *) this->marker, nullptr);
break;
case SDL_BUTTON_LEFT:
trigger_event(BOB_FIELDSELECTEDEVENT, 1, (void *) this->marker, nullptr);
break;
default:
break;
}
break;
default:
if (event->type == BOB_NEXTROUNDEVENT)
{
for (std::pair<Field, FieldMeta *> field : this->fields)
{
field.second->regenerate_resources();
}
}
break;
}
for (auto elem : this->fields)
@ -432,12 +501,11 @@ void HexagonGrid::move(SDL_Point m)
if (!on_rectangle(&layout->box))
this->layout->origin = this->layout->origin - m;
this->update_marker();
this->changed = true;
}
void HexagonGrid::update_marker()
{
if (!Timer::MOUSE_LOCKED)
{
SDL_Point m = {0, 0};
SDL_GetMouseState(&(m.x), &(m.y));
Point p = {0.0, 0.0};
@ -447,13 +515,13 @@ void HexagonGrid::update_marker()
if (n_marker != nullptr)
{
this->marker = n_marker;
n_marker->trigger_event(BOB_MARKERUPDATE, 0);
trigger_event(BOB_MARKERUPDATE, 0, (void *) n_marker, nullptr);
}
else
{
marker->trigger_event(BOB_MARKERUPDATE, 1);
}
trigger_event(BOB_MARKERUPDATE, 1, (void *) marker, nullptr);
}
this->changed = true;
}
FieldMeta *HexagonGrid::point_to_field(const Point p)
@ -504,3 +572,9 @@ Point HexagonGrid::field_to_point(FieldMeta *field)
{
return field->get_field().field_to_point(this->layout);
}
bool inside_target(const SDL_Rect *target, const SDL_Point *position)
{
return target->x < position->x && target->x + target->w > position->x && target->y < position->y &&
target->y + target->h > position->y;
}

View file

@ -22,6 +22,7 @@
#include <SDL2/SDL_render.h>
#include <SDL2/SDL2_gfxPrimitives.h>
#include "Events.hpp"
#include "Wrapper.hpp"
SDL_Point operator+(SDL_Point left, SDL_Point right);
@ -299,6 +300,8 @@ struct Field
std::vector<Point> field_to_polygon(const Layout *layout) const;
std::vector<SDL_Point> field_to_polygon_sdl(const Layout *layout) const;
static Field cubic_round(double x, double y, double z);
static Field hex_direction(Uint8 direction);
@ -540,6 +543,8 @@ public:
return !(*this == rhs);
}
static std::vector<Player *> players;
static std::vector<Player *>::iterator current_player;
private:
boost::uuids::uuid uuid;
SDL_Color color;
@ -580,7 +585,7 @@ public:
void set_owner(Player *player) { this->owner = player; }
void render(SDL_Renderer *renderer, Layout *layout);
void load(SDL_Renderer *renderer, Layout *layout);
Resource get_resources() { return this->resources; }
@ -596,8 +601,6 @@ public:
FieldMeta *get_neighbor(Uint8 direction);
void trigger_event(Uint32 type, Sint32 code);
private:
const Field field;
HexagonGrid *grid;
@ -614,9 +617,11 @@ typedef std::unordered_set<FieldMeta *> Cluster;
class HexagonGrid
{
public:
HexagonGrid(Sint16 grid_radius, Layout *layout_)
: layout(layout_), radius(grid_radius)
HexagonGrid(Sint16 grid_radius, Layout *layout_, Renderer *renderer_)
: layout(layout_), radius(grid_radius), renderer(renderer_)
{
this->texture = nullptr;
this->panning = false;
std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>();
this->default_player = new Player();
// first lower half, then upper half
@ -643,13 +648,16 @@ public:
delete elem.second;
}
delete this->default_player;
SDL_DestroyTexture(this->texture);
}
FieldMeta *get_neighbor(FieldMeta *field, Uint8 direction);
Cluster get_cluster(FieldMeta *field);
bool render(SDL_Renderer *renderer);
void render(Renderer *renderer);
void load();
Sint16 get_radius() { return radius * layout->size; }
@ -672,6 +680,9 @@ public:
void handle_event(SDL_Event *event);
private:
bool changed;
Renderer *renderer;
SDL_Texture *texture;
std::unordered_map<Field, FieldMeta *> fields;
Layout *layout;
FieldMeta *marker;
@ -682,5 +693,6 @@ private:
Sint16 radius;
};
bool inside_target(const SDL_Rect *target, const SDL_Point *position);
#endif

View file

@ -22,20 +22,29 @@ TTF_Font *load_font_from_file(std::string path_to_file, int size)
bool TextBox::load_text(std::string text)
{
const char *displayed_text = text.c_str();
SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100);
if (surface == nullptr)
SDL_Surface *text_surface = TTF_RenderUTF8_Blended_Wrapped(this->font, displayed_text, this->color, 100);
if (text_surface == nullptr)
{
SDL_FreeSurface(surface);
SDL_FreeSurface(text_surface);
throw SDL_TTFException();
}
this->dimensions.w = surface->w;
this->dimensions.h = surface->h;
this->dimensions.w = text_surface->w;
this->dimensions.h = text_surface->h;
SDL_Surface *surface = SDL_CreateRGBSurface(0, this->dimensions.w, this->dimensions.h, 32, rmask, gmask, bmask,
amask);
if (surface == nullptr
|| SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 255, 255, 255)) < 0
|| SDL_BlitSurface(text_surface, nullptr, surface, nullptr) < 0)
{
throw SDL_Exception("Failed to create background text_surface!");
}
if (this->texture != nullptr)
{
SDL_DestroyTexture(this->texture);
}
SDL_SetRenderTarget(this->renderer->get_renderer(), this->texture);
this->texture = SDL_CreateTextureFromSurface(this->renderer->get_renderer(), surface);
SDL_FreeSurface(text_surface);
SDL_FreeSurface(surface);
if (this->texture == nullptr)
{
@ -46,54 +55,6 @@ bool TextBox::load_text(std::string text)
return (this->texture != nullptr);
}
SDL_Point Window::toggle_fullscreen()
{
SDL_DisplayMode dm;
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(this->window), &dm);
if (!this->fullscreen)
{
this->fullscreen = true;
SDL_SetWindowSize(this->window, dm.w, dm.h);
SDL_SetWindowFullscreen(this->window, SDL_WINDOW_FULLSCREEN);
}
else
{
this->fullscreen = false;
SDL_SetWindowFullscreen(this->window, 0);
SDL_SetWindowSize(this->window, this->initial_dimensions->w, this->initial_dimensions->h);
SDL_SetWindowPosition(this->window, this->initial_dimensions->x, this->initial_dimensions->y);
}
SDL_Point window_size = {0, 0};
SDL_GetWindowSize(window, &(window_size.x), &(window_size.y));
return window_size;
}
bool inside_target(const SDL_Rect *target, const SDL_Point *position)
{
return target->x < position->x && target->x + target->w > position->x && target->y < position->y &&
target->y + target->h > position->y;
}
int Window::get_window_id()
{
return SDL_GetWindowID(this->window);
}
void Renderer::set_draw_color(SDL_Color color)
{
SDL_SetRenderDrawColor(this->renderer, color.r, color.g, color.b, color.a);
}
void Renderer::clear()
{
SDL_RenderClear(this->renderer);
}
void Renderer::present()
{
SDL_RenderPresent(this->renderer);
}
void Container::handle_event(SDL_Event *event)
{
for (auto box : this->elements)
@ -112,23 +73,14 @@ void FieldBox::handle_event(const SDL_Event *event)
}
else if (event->type == BOB_MARKERUPDATE)
{
if (event->user.code == 0)
{
if (!Timer::MOUSE_LOCKED)
{
FieldMeta *field_update = reinterpret_cast<FieldMeta *>(event->user.data1);
this->field = field_update;
this->update();
SDL_Point mouse;
SDL_GetMouseState(&mouse.x, &mouse.y);
this->update_position(mouse);
this->field = static_cast<FieldMeta *>(event->user.data1);
}
this->visible = true;
}
else if (!Timer::MOUSE_LOCKED)
{
this->visible = false;
}
this->update();
}
}
void FieldBox::update()
@ -153,27 +105,32 @@ void UpgradeButtonBox::set_active(bool state)
this->color.b = 0xff;
this->load_text(UPGRADE_NAMES.at(this->upgrade));
}
else
{
this->color = {0, 0, 0, 0xff};
this->load_text(UPGRADE_NAMES.at(this->upgrade));
}
}
void UpgradeBox::update_upgrade_boxes()
{
UpgradeFlags active_upgrades = this->field->get_upgrades();
for (int i = 0; i < NUM_UPGRADES; i++)
{
this->upgrades[i]->set_active(active_upgrades[i]);
}
}
void UpgradeBox::handle_event(const SDL_Event *event)
{
if (this->visible)
{
if (event->type == BOB_FIELDUPDATEEVENT)
{
// mark updates active / inactive
this->field = static_cast<FieldMeta *>(event->user.data1);
UpgradeFlags updated_upgrades = this->field->get_upgrades();
for (auto upgrade : this->upgrades)
{
Upgrade up = upgrade->get_upgrade();
bool active = updated_upgrades[up];
upgrade->set_active(active);
this->update_upgrade_boxes();
}
}
else if (this->visible)
else if (event->type == SDL_MOUSEBUTTONDOWN)
{
if (event->type == SDL_MOUSEBUTTONDOWN)
{
this->marked_upgrade->handle_event(event);
SDL_Point mouse;
SDL_GetMouseState(&mouse.x, &mouse.y);
if (!inside_target(&(this->dimensions), &mouse))
@ -181,6 +138,10 @@ void UpgradeBox::handle_event(const SDL_Event *event)
Timer::MOUSE_LOCKED = false;
this->set_visible(false);
}
else
{
this->marked_upgrade->handle_event(event);
}
}
else if (event->type == SDL_MOUSEMOTION && this->visible)
{
@ -209,16 +170,17 @@ void UpgradeBox::handle_event(const SDL_Event *event)
}
else // NOT visible
{
if (event->type == BOB_FIELDSELECTED)
if (event->type == BOB_FIELDSELECTEDEVENT)
{
FieldMeta *selected = static_cast<FieldMeta *>(event->user.data1);
if (selected != nullptr && event->user.code == 0x0)
if (selected != nullptr && event->user.code == 0x0 && !Timer::MOUSE_LOCKED)
{
Timer::MOUSE_LOCKED = true;
SDL_Point mouse;
SDL_GetMouseState(&mouse.x, &mouse.y);
this->update_position(mouse);
this->field = selected;
this->update_upgrade_boxes();
this->set_visible(true);
}
}
@ -263,19 +225,7 @@ void Box::render(Renderer *ext_renderer)
{
if (this->visible && this->texture != nullptr)
{
SDL_Color bg = {0xff, 0xff, 0xff, 0xff};
renderer->set_draw_color(bg);
if (SDL_SetRenderDrawBlendMode(ext_renderer->get_renderer(), SDL_BLENDMODE_NONE) < 0
|| SDL_RenderFillRect(ext_renderer->get_renderer(), &(this->dimensions)) < 0)
{
throw SDL_Exception("Failed to draw rectangle background!");
}
renderer->set_draw_color(this->color);
if (SDL_SetTextureBlendMode(this->texture, SDL_BLENDMODE_BLEND) < 0
|| SDL_RenderCopy(ext_renderer->get_renderer(), this->texture, nullptr, &(this->dimensions)) < 0)
{
throw SDL_RendererException();
}
ext_renderer->copy(this->texture, nullptr, &(this->dimensions));
}
}
@ -325,5 +275,5 @@ void UpgradeBox::set_visible(bool status)
void FieldBox::update_position(SDL_Point point)
{
this->dimensions.x = point.x;
this->dimensions.y = point.y - dimensions.h - 6;
this->dimensions.y = point.y - this->dimensions.h - 6;
}

View file

@ -12,71 +12,9 @@
#include "Exceptions.hpp"
#include "Gameplay.hpp"
#include "Events.hpp"
#include "Wrapper.hpp"
#include "Pixelmask.h"
SDL_Color operator!(const SDL_Color &color);
class Window
{
private:
SDL_Window *window;
const SDL_Rect *initial_dimensions;
bool fullscreen;
public:
Window(std::string title, SDL_Rect *dimensions, Uint32 flags)
{
this->window = SDL_CreateWindow(title.c_str(), dimensions->x, dimensions->y, dimensions->w, dimensions->h,
flags);
if (this->window == nullptr)
{
SDL_DestroyWindow(this->window);
throw SDL_WindowException();
}
this->initial_dimensions = dimensions;
}
~Window()
{
SDL_DestroyWindow(this->window);
}
SDL_Window *get_window() { return this->window; }
SDL_Point toggle_fullscreen();
int get_window_id();
};
class Renderer
{
public:
Renderer(Window *window, int index, Uint32 flags)
{
this->renderer = SDL_CreateRenderer(window->get_window(), index, flags);
if (renderer == nullptr)
{
SDL_DestroyRenderer(this->renderer);
throw SDL_RendererException();
}
}
~Renderer()
{
SDL_DestroyRenderer(this->renderer);
}
SDL_Renderer *get_renderer() { return this->renderer; }
void set_draw_color(SDL_Color color);
void clear();
void present();
private:
SDL_Renderer *renderer;
};
class Box
{
public:
@ -160,6 +98,11 @@ private:
bool active; // this upgrade has been unlocked
};
/*class NextTurnButtonBox : public TextBox
{
};
*/
class UpgradeBox : public Box
{
public:
@ -197,6 +140,8 @@ public:
void set_visible(bool status);
void update_upgrade_boxes();
private:
std::vector<UpgradeButtonBox *> upgrades;
UpgradeButtonBox *marked_upgrade;