aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/facade/SDLContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/facade/SDLContext.cpp')
-rw-r--r--src/crepe/facade/SDLContext.cpp130
1 files changed, 81 insertions, 49 deletions
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index ad9f1f0..4cc2206 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -11,19 +11,17 @@
#include <cstddef>
#include <cstdint>
#include <functional>
-#include <iostream>
#include <memory>
#include <stdexcept>
#include "../api/Camera.h"
+#include "../api/Color.h"
#include "../api/Config.h"
#include "../api/Sprite.h"
#include "../api/Texture.h"
-#include "../manager/EventManager.h"
#include "../util/Log.h"
#include "SDLContext.h"
-#include "api/Color.h"
#include "types.h"
using namespace crepe;
@@ -215,11 +213,13 @@ MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) {
return MOUSE_BUTTON_LOOKUP_TABLE[sdl_button];
}
-void SDLContext::clear_screen() {
+void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); }
+void SDLContext::present_screen() {
SDL_SetRenderDrawColor(this->game_renderer.get(), 0, 0, 0, 255);
- SDL_RenderClear(this->game_renderer.get());
+ SDL_RenderFillRectF(this->game_renderer.get(), &black_bars[0]);
+ SDL_RenderFillRectF(this->game_renderer.get(), &black_bars[1]);
+ SDL_RenderPresent(this->game_renderer.get());
}
-void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); }
SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
return SDL_Rect{
@@ -229,40 +229,62 @@ SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
.h = sprite.mask.h,
};
}
-SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const vec2 & pos, const Camera & cam,
- const vec2 & cam_pos, const double & img_scale) const {
- int width = sprite.height * sprite.aspect_ratio;
- int height = sprite.height;
+SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const {
- width *= img_scale * cam.zoom;
- height *= img_scale * cam.zoom;
+ const Sprite::Data & data = ctx.sprite.data;
- return SDL_Rect{
- .x = static_cast<int>((pos.x - cam_pos.x + (cam.viewport_size.x / 2) - width / 2)),
- .y = static_cast<int>((pos.y - cam_pos.y + (cam.viewport_size.y / 2) - height / 2)),
- .w = width,
- .h = height,
+ vec2 size;
+ if (data.size.x == 0 && data.size.y != 0) {
+ size.x = data.size.y * ctx.sprite.aspect_ratio;
+ }
+ if (data.size.y == 0 && data.size.x != 0) {
+ size.y = data.size.x / ctx.sprite.aspect_ratio;
+ }
+
+ const CameraValues & cam = ctx.cam;
+
+ size *= cam.render_scale * ctx.img_scale * data.scale_offset;
+
+ vec2 screen_pos
+ = (ctx.pos + data.position_offset - cam.cam_pos + (cam.zoomed_viewport) / 2)
+ * cam.render_scale
+ - size / 2 + cam.bar_size;
+
+ return SDL_FRect{
+ .x = screen_pos.x,
+ .y = screen_pos.y,
+ .w = size.x,
+ .h = size.y,
};
}
void SDLContext::draw(const RenderContext & ctx) {
+ const Sprite::Data & data = ctx.sprite.data;
SDL_RendererFlip render_flip
- = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * ctx.sprite.flip.flip_x)
- | (SDL_FLIP_VERTICAL * ctx.sprite.flip.flip_y));
+ = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * data.flip.flip_x)
+ | (SDL_FLIP_VERTICAL * data.flip.flip_y));
SDL_Rect srcrect = this->get_src_rect(ctx.sprite);
- SDL_Rect dstrect
- = this->get_dst_rect(ctx.sprite, ctx.pos, ctx.cam, ctx.cam_pos, ctx.scale);
-
- this->set_color_texture(ctx.sprite.sprite_image, ctx.sprite.color);
- SDL_RenderCopyEx(this->game_renderer.get(), ctx.sprite.sprite_image.texture.get(),
- &srcrect, &dstrect, ctx.angle, NULL, render_flip);
+ SDL_FRect dstrect = this->get_dst_rect(SDLContext::DestinationRectangleData{
+ .sprite = ctx.sprite,
+ .cam = ctx.cam,
+ .pos = ctx.pos,
+ .img_scale = ctx.scale,
+ });
+
+ double angle = ctx.angle + data.angle_offset;
+
+ this->set_color_texture(ctx.sprite.texture, ctx.sprite.data.color);
+ SDL_RenderCopyExF(this->game_renderer.get(), ctx.sprite.texture.texture.get(), &srcrect,
+ &dstrect, angle, NULL, render_flip);
}
-void SDLContext::set_camera(const Camera & cam) {
+SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) {
+ const Camera::Data & cam_data = cam.data;
+ CameraValues ret_cam;
// resize window
int w, h;
SDL_GetWindowSize(this->game_window.get(), &w, &h);
@@ -270,42 +292,52 @@ void SDLContext::set_camera(const Camera & cam) {
SDL_SetWindowSize(this->game_window.get(), cam.screen.x, cam.screen.y);
}
- double screen_aspect = cam.screen.x / cam.screen.y;
- double viewport_aspect = cam.viewport_size.x / cam.viewport_size.y;
+ vec2 & zoomed_viewport = ret_cam.zoomed_viewport;
+ vec2 & bar_size = ret_cam.bar_size;
+ vec2 & render_scale = ret_cam.render_scale;
+
+ zoomed_viewport = cam.viewport_size * cam_data.zoom;
+ float screen_aspect = static_cast<float>(cam.screen.x) / cam.screen.y;
+ float viewport_aspect = zoomed_viewport.x / zoomed_viewport.y;
- SDL_Rect view;
// calculate black bars
if (screen_aspect > viewport_aspect) {
- // letterboxing
- view.h = cam.screen.y / cam.zoom;
- view.w = cam.screen.y * viewport_aspect;
- view.x = (cam.screen.x - view.w) / 2;
- view.y = 0;
- } else {
// pillarboxing
- view.h = cam.screen.x / viewport_aspect;
- view.w = cam.screen.x / cam.zoom;
- view.x = 0;
- view.y = (cam.screen.y - view.h) / 2;
+ float scale = cam.screen.y / zoomed_viewport.y;
+ float adj_width = zoomed_viewport.x * scale;
+ float bar_width = (cam.screen.x - adj_width) / 2;
+ this->black_bars[0] = {0, 0, bar_width, (float) cam.screen.y};
+ this->black_bars[1] = {(cam.screen.x - bar_width), 0, bar_width, (float) cam.screen.y};
+
+ bar_size = {bar_width, 0};
+ render_scale.x = render_scale.y = scale;
+ } else {
+ // letterboxing
+ float scale = cam.screen.x / (cam.viewport_size.x * cam_data.zoom);
+ float adj_height = cam.viewport_size.y * scale;
+ float bar_height = (cam.screen.y - adj_height) / 2;
+ this->black_bars[0] = {0, 0, (float) cam.screen.x, bar_height};
+ this->black_bars[1]
+ = {0, (cam.screen.y - bar_height), (float) cam.screen.x, bar_height};
+
+ bar_size = {0, bar_height};
+ render_scale.x = render_scale.y = scale;
}
- // set drawing area
- SDL_RenderSetViewport(this->game_renderer.get(), &view);
-
- SDL_RenderSetLogicalSize(this->game_renderer.get(), static_cast<int>(cam.viewport_size.x),
- static_cast<int>(cam.viewport_size.y));
- // set bg color
- SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g,
- cam.bg_color.b, cam.bg_color.a);
+ SDL_SetRenderDrawColor(this->game_renderer.get(), cam_data.bg_color.r, cam_data.bg_color.g,
+ cam_data.bg_color.b, cam_data.bg_color.a);
SDL_Rect bg = {
.x = 0,
.y = 0,
- .w = static_cast<int>(cam.viewport_size.x),
- .h = static_cast<int>(cam.viewport_size.y),
+ .w = cam.screen.x,
+ .h = cam.screen.y,
};
+
// fill bg color
SDL_RenderFillRect(this->game_renderer.get(), &bg);
+
+ return ret_cam;
}
uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); }