diff --git a/src/Bob.cpp b/src/Bob.cpp index 7d2bf66..d9a0562 100644 --- a/src/Bob.cpp +++ b/src/Bob.cpp @@ -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; diff --git a/src/Bob.hpp b/src/Bob.hpp index ae0f4b6..3b4359e 100644 --- a/src/Bob.hpp +++ b/src/Bob.hpp @@ -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; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d6e8c2..c0a9339 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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}) \ No newline at end of file diff --git a/src/Events.cpp b/src/Events.cpp index 4b2ae19..086cce4 100644 --- a/src/Events.cpp +++ b/src/Events.cpp @@ -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; @@ -33,4 +33,15 @@ Uint32 register_events(Uint32 n) if (base_event == ((Uint32) - 1)) 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(data1); + event.user.data2 = data2; + SDL_PushEvent(&event); } \ No newline at end of file diff --git a/src/Events.hpp b/src/Events.hpp index 38984a1..c996cf2 100644 --- a/src/Events.hpp +++ b/src/Events.hpp @@ -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 \ No newline at end of file diff --git a/src/Gameplay.cpp b/src/Gameplay.cpp index 3922a24..e760f68 100644 --- a/src/Gameplay.cpp +++ b/src/Gameplay.cpp @@ -1,5 +1,7 @@ #include "Gameplay.hpp" +static std::vector::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 Field::field_to_polygon(const Layout *layout) const return corners; } +std::vector Field::field_to_polygon_sdl(const Layout *layout) const +{ + std::vector 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 Field::field_to_polygon_normalized(const Layout *layout) const { std::vector corners; @@ -127,73 +150,6 @@ std::vector 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 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(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 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 polygon = some_field.field_to_polygon_normalized(this->layout); - assert(polygon.size() > 5); - Sint16 x[6]; - Sint16 y[6]; + std::vector norm_polygon = some_field.field_to_polygon_normalized(this->layout); for (std::pair 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 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); + } + /*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(this->renderer->get_renderer(), vx, vy, 6, 0x77, 0x77, 0x77, 0x77); + } } - const SDL_Color color = {0xff, 0xff, 0xff, 0xff}; - polygonRGBA(renderer, x, y, 6, color.r, color.g, color.b, color.a); - if (elem.first == this->marker->get_field()) - { - filledPolygonRGBA(renderer, x, y, 6, 0x77, 0x77, 0x77, 0x22); - } - 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 : this->fields) + { + field.second->regenerate_resources(); + } + } break; } for (auto elem : this->fields) @@ -432,28 +501,27 @@ 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}; + p.x = m.x; + p.y = m.y; + FieldMeta *n_marker = this->point_to_field(p); + if (n_marker != nullptr) { - SDL_Point m = {0, 0}; - SDL_GetMouseState(&(m.x), &(m.y)); - Point p = {0.0, 0.0}; - p.x = m.x; - p.y = m.y; - FieldMeta *n_marker = this->point_to_field(p); - if (n_marker != nullptr) - { - this->marker = n_marker; - n_marker->trigger_event(BOB_MARKERUPDATE, 0); - } - else - { - marker->trigger_event(BOB_MARKERUPDATE, 1); - } + this->marker = n_marker; + trigger_event(BOB_MARKERUPDATE, 0, (void *) n_marker, nullptr); } + else + { + trigger_event(BOB_MARKERUPDATE, 1, (void *) marker, nullptr); + } + this->changed = true; } FieldMeta *HexagonGrid::point_to_field(const Point p) @@ -503,4 +571,10 @@ void HexagonGrid::update_dimensions(SDL_Point dimensions) 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; } \ No newline at end of file diff --git a/src/Gameplay.hpp b/src/Gameplay.hpp index f689229..961403a 100644 --- a/src/Gameplay.hpp +++ b/src/Gameplay.hpp @@ -22,6 +22,7 @@ #include #include #include "Events.hpp" +#include "Wrapper.hpp" SDL_Point operator+(SDL_Point left, SDL_Point right); @@ -299,6 +300,8 @@ struct Field std::vector field_to_polygon(const Layout *layout) const; + std::vector 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 players; + static std::vector::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 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 fields = std::unordered_map(); 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 fields; Layout *layout; FieldMeta *marker; @@ -682,5 +693,6 @@ private: Sint16 radius; }; +bool inside_target(const SDL_Rect *target, const SDL_Point *position); #endif diff --git a/src/Gui.cpp b/src/Gui.cpp index bb71e23..35fe44c 100644 --- a/src/Gui.cpp +++ b/src/Gui.cpp @@ -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,22 +73,13 @@ void FieldBox::handle_event(const SDL_Event *event) } else if (event->type == BOB_MARKERUPDATE) { - if (event->user.code == 0) - { - if (!Timer::MOUSE_LOCKED) - { - SDL_Point mouse; - SDL_GetMouseState(&mouse.x, &mouse.y); - this->update_position(mouse); - this->field = static_cast(event->user.data1); - } - this->visible = true; - } - else if (!Timer::MOUSE_LOCKED) - { - this->visible = false; - } + FieldMeta *field_update = reinterpret_cast(event->user.data1); + this->field = field_update; this->update(); + SDL_Point mouse; + SDL_GetMouseState(&mouse.x, &mouse.y); + this->update_position(mouse); + this->visible = true; } } @@ -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 (event->type == BOB_FIELDUPDATEEVENT) + if (this->visible) { - // mark updates active / inactive - this->field = static_cast(event->user.data1); - UpgradeFlags updated_upgrades = this->field->get_upgrades(); - for (auto upgrade : this->upgrades) + if (event->type == BOB_FIELDUPDATEEVENT) { - Upgrade up = upgrade->get_upgrade(); - bool active = updated_upgrades[up]; - upgrade->set_active(active); + this->update_upgrade_boxes(); } - } - else if (this->visible) - { - if (event->type == SDL_MOUSEBUTTONDOWN) + else 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(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; } \ No newline at end of file diff --git a/src/Gui.hpp b/src/Gui.hpp index 10f871d..a81941a 100644 --- a/src/Gui.hpp +++ b/src/Gui.hpp @@ -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 upgrades; UpgradeButtonBox *marked_upgrade;