diff --git a/05_sdl_alapok/color.cpp b/05_sdl_alapok/color.cpp index 24f2cf6..65bb6f5 100644 --- a/05_sdl_alapok/color.cpp +++ b/05_sdl_alapok/color.cpp @@ -1,17 +1,39 @@ #include "color.h" +uint32_t Color::to_key() const { + uint32_t val = 0; + + val |= static_cast(r) << 24; + val |= static_cast(g) << 16; + val |= static_cast(b) << 8; + val |= static_cast(a) << 0; + + return val; +} + +void Color::from_key(const uint32_t key) { + r = key & 0xFFFF000000000000; + g = key & 0x0000FFFF00000000; + b = key & 0x00000000FFFF0000; + a = key & 0x000000000000FFFF; +} + Color::Color() { - r = 0; - g = 0; - b = 0; - a = 255; + r = 0; + g = 0; + b = 0; + a = 255; } Color::Color(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a) { - r = p_r; - g = p_g; - b = p_b; - a = p_a; + r = p_r; + g = p_g; + b = p_b; + a = p_a; +} + +Color::Color(const uint32_t key) { + from_key(key); } Color::~Color() { diff --git a/05_sdl_alapok/color.h b/05_sdl_alapok/color.h index 98a5f08..1530882 100644 --- a/05_sdl_alapok/color.h +++ b/05_sdl_alapok/color.h @@ -5,14 +5,18 @@ class Color { public: - Color(); - Color(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a = 255); - virtual ~Color(); + uint32_t to_key() const; + void from_key(const uint32_t key); - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; + Color(); + Color(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a = 255); + Color(const uint32_t key); + virtual ~Color(); + + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; }; #endif \ No newline at end of file diff --git a/05_sdl_alapok/compile.sh b/05_sdl_alapok/compile.sh index 04e7f4d..7a3773b 100755 --- a/05_sdl_alapok/compile.sh +++ b/05_sdl_alapok/compile.sh @@ -12,11 +12,11 @@ fi #g++ -Wall -g -c vector2.cpp -o obj/vector2.o #g++ -Wall -g -c vector3.cpp -o obj/vector3.o #g++ -Wall -g -c int_vector.cpp -o obj/int_vector.o -#g++ -Wall -g -c string.cpp -o obj/string.o g++ -Wall -g -c math.cpp -o obj/math.o g++ -Wall -g -c rect2.cpp -o obj/rect2.o g++ -Wall -g -c color.cpp -o obj/color.o +g++ -Wall -g -c string.cpp -o obj/string.o g++ -Wall -g $(sdl2-config --cflags) -c renderer.cpp -o obj/renderer.o g++ -Wall -g $(sdl2-config --cflags) -c image.cpp -o obj/image.o @@ -25,5 +25,5 @@ g++ -Wall -g $(sdl2-config --cflags) -c texture_editor.cpp -o obj/texture_editor g++ -Wall -g $(sdl2-config --cflags) -c main.cpp -o obj/main.o -g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/renderer.o obj/image.o obj/texture.o obj/texture_editor.o obj/main.o $(sdl2-config --libs) +g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/string.o obj/renderer.o obj/image.o obj/texture.o obj/texture_editor.o obj/main.o $(sdl2-config --libs) diff --git a/05_sdl_alapok/image.cpp b/05_sdl_alapok/image.cpp index e2b8c2f..cfad422 100644 --- a/05_sdl_alapok/image.cpp +++ b/05_sdl_alapok/image.cpp @@ -1 +1,232 @@ -#include "image.h" \ No newline at end of file +#include "image.h" + +#include + +void Image::create(const Uint32 flags, const int width, const int height) { + if (_surface) { + free(); + } + + //SDL_PIXELFORMAT_RGBA8888 SDL_pixels.h ból + SDL_CreateRGBSurfaceWithFormat(flags, width, height, 32, SDL_PIXELFORMAT_RGBA8888); +} + +void Image::enable_transparent_color(const Color &color) { + if (!SDL_SetColorKey(_surface, 1, color.to_key())) { + printf("enable_transparent_color error.\n"); + } +} + +void Image::disable_transparent_color() { + if (!SDL_SetColorKey(_surface, 0, 0)) { + printf("disable_transparent_color error.\n"); + } +} + +bool Image::has_transparent_color() { + return SDL_HasColorKey(_surface); +} +Color Image::get_transparent_color() { + uint32_t key; + + SDL_GetColorKey(_surface, &key); + + return Color(key); +} + +Color Image::get_color_mod() { + Uint8 r; + Uint8 g; + Uint8 b; + + SDL_GetSurfaceColorMod(_surface, &r, &g, &b); + + return Color(r, g, b); +} +void Image::set_color_mod(const Color &color) { + SDL_SetSurfaceColorMod(_surface, color.r, color.g, color.b); +} + +Color Image::get_alpha_mod() { + Uint8 a; + + SDL_GetSurfaceAlphaMod(_surface, &a); + + return a; +} +void Image::set_alpha_mod(const Uint8 alpha) { + SDL_SetSurfaceAlphaMod(_surface, alpha); +} + +SDL_BlendMode Image::get_blend_mode() { + SDL_BlendMode mode; + + SDL_GetSurfaceBlendMode(_surface, &mode); + + return mode; +} +void Image::set_blend_mode(const SDL_BlendMode mode) { + SDL_SetSurfaceBlendMode(_surface, mode); +} + +Rect2 Image::get_clip_rect() { + SDL_Rect r; + + SDL_GetClipRect(_surface, &r); + + Rect2 rect; + + rect.x = r.x; + rect.y = r.y; + rect.w = r.w; + rect.h = r.h; + + return rect; +} +void Image::set_clip_rect(const Rect2 &rect) { + SDL_Rect r; + + r.x = rect.x; + r.y = rect.y; + r.w = rect.w; + r.h = rect.h; + + SDL_SetClipRect(_surface, &r); +} + +void Image::duplicate(Image *into) { + if (into == nullptr) { + return; + } + + into->_surface = SDL_DuplicateSurface(_surface); +} + +void Image::fill_rect(const Rect2 &rect, const Color &color) { + SDL_Rect r; + + r.x = rect.x; + r.y = rect.y; + r.w = rect.w; + r.h = rect.h; + + SDL_FillRect(_surface, &r, color.to_key()); +} + +void Image::fill_rects(const Vector &rects, const Color &color) { + SDL_Rect *r = new SDL_Rect[rects.size()]; + + for (int i = 0; i < rects.size(); ++i) { + r[i].x = rects[i].x; + r[i].y = rects[i].y; + r[i].w = rects[i].w; + r[i].h = rects[i].h; + } + + SDL_FillRects(_surface, r, rects.size(), color.to_key()); + + delete[] r; +} + +void Image::set_pixel(const int x, const int y, const Color &color) { + if (_surface == nullptr) { + return; + } + + Uint32 *p = reinterpret_cast(_surface->pixels); + + p[x * _surface->w + y] = color.to_key(); +} + +Color Image::get_pixel(const int x, const int y) { + if (_surface == nullptr) { + return Color(); + } + + Uint32 *p = reinterpret_cast(_surface->pixels); + + return Color(p[x * _surface->w + y]); +} + +void Image::blit_surface(const Image &source, const Rect2 &srcrect, const Rect2 &dstrect) { + SDL_Rect sr; + + sr.x = srcrect.x; + sr.y = srcrect.y; + sr.w = srcrect.w; + sr.h = srcrect.h; + + SDL_Rect dr; + + dr.x = dstrect.x; + dr.y = dstrect.y; + dr.w = dstrect.w; + dr.h = dstrect.h; + + SDL_BlitSurface(source._surface, &sr, _surface, &dr); +} + +void Image::lock() { + SDL_LockSurface(_surface); +} +void Image::unlock() { + SDL_UnlockSurface(_surface); +} + +void Image::free() { + SDL_FreeSurface(_surface); + + _surface = nullptr; +} + +void Image::load_bmp(const String &file_name) { + if (_surface != nullptr) { + free(); + } + + _surface = SDL_LoadBMP(file_name.c_str()); + + if (_surface != nullptr && _surface->format->format != SDL_PIXELFORMAT_RGBA8888) { + //Nem ARGB8888 as formátum, konvertáljuk át + SDL_Surface *n = SDL_ConvertSurfaceFormat(_surface, SDL_PIXELFORMAT_RGBA8888, 0); + + free(); + + _surface = n; + } +} + +void Image::save_bmp(const String &file_name) { + SDL_SaveBMP(_surface, file_name.c_str()); +} + +Uint32 Image::get_width() const { + if (_surface == nullptr) { + return 0; + } + + return _surface->w; +} +Uint32 Image::get_height() const { + if (_surface == nullptr) { + return 0; + } + + return _surface->h; +} + +SDL_Surface *Image::get_surface() { + return _surface; +} + +Image::Image() { + _surface = nullptr; +} +Image::Image(const String &file_name) { + _surface = nullptr; + + load_bmp(file_name); +} +Image::~Image() { + free(); +} \ No newline at end of file diff --git a/05_sdl_alapok/image.h b/05_sdl_alapok/image.h index 3909524..08adfd2 100644 --- a/05_sdl_alapok/image.h +++ b/05_sdl_alapok/image.h @@ -13,7 +13,6 @@ public: void enable_transparent_color(const Color &color); void disable_transparent_color(); - void set_transparent_color(const Color &color); bool has_transparent_color(); Color get_transparent_color(); @@ -21,18 +20,15 @@ public: void set_color_mod(const Color &color); Color get_alpha_mod(); - void set_alpha_mod(const Color &color); + void set_alpha_mod(const Uint8 alpha); SDL_BlendMode get_blend_mode(); - void get_blend_mode(const SDL_BlendMode mode); + void set_blend_mode(const SDL_BlendMode mode); Rect2 get_clip_rect(); - void get_clip_rect(const Rect2 &mode); + void set_clip_rect(const Rect2 &rect); - Image *duplicate(); - - void convert(const SDL_PixelFormat *fmt, Uint32 flags); - void convert(Uint32 pixel_format, Uint32 flags); + void duplicate(Image *into); void fill_rect(const Rect2 &rect, const Color &color); void fill_rects(const Vector &rects, const Color &color); @@ -46,7 +42,8 @@ public: void free(); - void load_bmp(); + void load_bmp(const String &file_name); + void save_bmp(const String &file_name); Uint32 get_width() const; Uint32 get_height() const; @@ -54,6 +51,7 @@ public: SDL_Surface *get_surface(); Image(); + Image(const String &file_name); virtual ~Image(); private: diff --git a/05_sdl_alapok/main.cpp b/05_sdl_alapok/main.cpp index 9c4e7f6..fcfa7ff 100644 --- a/05_sdl_alapok/main.cpp +++ b/05_sdl_alapok/main.cpp @@ -1,43 +1,64 @@ #include +#include "image.h" #include "renderer.h" +#include +int main(int argv, char **args) { + Renderer r; -int main(int argv, char** args) { - Renderer r; + Image i("ti.bmp"); - r.set_draw_color(0, 0, 0, 255); - r.clear(); - r.present(); + i.lock(); + i.set_pixel(i.get_height() - 1, i.get_width() - 1, Color(0, 0, 255, 255)); + i.unlock(); - int rgb[] = { 203, 203, 203, // Gray - 254, 254, 31, // Yellow - 0, 255, 255, // Cyan - 0, 254, 30, // Green - 255, 16, 253, // Magenta - 253, 3, 2, // Red - 18, 14, 252, // Blue - 0, 0, 0 // Black - }; + SDL_Texture *t = SDL_CreateTextureFromSurface(r.get_renderer(), i.get_surface()); - SDL_Rect colorBar; - colorBar.x = 0; - colorBar.y = 0; - colorBar.w = 90; - colorBar.h = 480; + r.set_draw_color(0, 0, 0, 255); + r.clear(); - // Render a new color bar every 0.5 seconds - for ( int i = 0; i != sizeof rgb / sizeof *rgb; i += 3, colorBar.x += 90) - { - r.set_draw_color(rgb[i], rgb[i + 1], rgb[i + 2], 255); - r.draw_rect(colorBar); - r.present(); + SDL_Rect rs; + rs.x = 0; + rs.y = 0; + rs.w = i.get_width(); + rs.h = i.get_height(); - SDL_Delay(500); - } + SDL_RenderCopy(r.get_renderer(), t, &rs, &rs); - r.destroy(); - - SDL_Quit(); + r.present(); + + int rgb[] = { + 203, 203, 203, // Gray + 254, 254, 31, // Yellow + 0, 255, 255, // Cyan + 0, 254, 30, // Green + 255, 16, 253, // Magenta + 253, 3, 2, // Red + 18, 14, 252, // Blue + 0, 0, 0 // Black + }; + + SDL_Rect colorBar; + colorBar.x = 0; + colorBar.y = 0; + colorBar.w = 90; + colorBar.h = 480; + + // Render a new color bar every 0.5 seconds + for (int i = 0; i != sizeof rgb / sizeof *rgb; i += 3, colorBar.x += 90) { + r.set_draw_color(rgb[i], rgb[i + 1], rgb[i + 2], 255); + r.draw_rect(colorBar); + r.present(); + + SDL_Delay(500); + } + + SDL_DestroyTexture(t); + + i.free(); + r.destroy(); + + SDL_Quit(); } diff --git a/05_sdl_alapok/renderer.cpp b/05_sdl_alapok/renderer.cpp index 6ffb8b9..e6972a2 100644 --- a/05_sdl_alapok/renderer.cpp +++ b/05_sdl_alapok/renderer.cpp @@ -45,25 +45,25 @@ int Renderer::get_dpi() const { } int Renderer::get_size_w() const { - int w; - int h; + int w; + int h; - SDL_GetWindowSize(_window, &w, &h); + SDL_GetWindowSize(_window, &w, &h); - return w; + return w; } int Renderer::get_size_h() const { - int w; - int h; + int w; + int h; - SDL_GetWindowSize(_window, &w, &h); + SDL_GetWindowSize(_window, &w, &h); - return h; + return h; } void Renderer::get_size(int *w, int *h) const { - SDL_GetWindowSize(_window, w, h); + SDL_GetWindowSize(_window, w, h); } void Renderer::initialize() { @@ -93,6 +93,14 @@ void Renderer::destroy() { _renderer = nullptr; } +SDL_Window *Renderer::get_window() { + return _window; +} + +SDL_Renderer *Renderer::get_renderer() { + return _renderer; +} + Renderer::Renderer() { if (_singleton) { printf("Renderer::Renderer(): _singleton is not null!\n"); diff --git a/05_sdl_alapok/renderer.h b/05_sdl_alapok/renderer.h index 8c2dc99..9241442 100644 --- a/05_sdl_alapok/renderer.h +++ b/05_sdl_alapok/renderer.h @@ -1,29 +1,32 @@ #ifndef RENDERER_H #define RENDERER_H -#include "rect2.h" #include "color.h" +#include "rect2.h" #include class Renderer { public: - void present(); - void set_draw_color(const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a); - void set_draw_color(const Color &color); - void clear(); + void present(); + void set_draw_color(const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a); + void set_draw_color(const Color &color); + void clear(); - void draw_rect(const SDL_Rect &rect); - void draw_rect(const Rect2 &rect); + void draw_rect(const SDL_Rect &rect); + void draw_rect(const Rect2 &rect); - int get_dpi() const; - int get_size_w() const; - int get_size_h() const; - void get_size(int *w, int *h) const; + int get_dpi() const; + int get_size_w() const; + int get_size_h() const; + void get_size(int *w, int *h) const; void initialize(); void destroy(); + SDL_Window *get_window(); + SDL_Renderer *get_renderer(); + Renderer(); Renderer(unsigned int flags, unsigned int window_flags, int window_width = 640, int window_height = 480); virtual ~Renderer(); @@ -31,8 +34,8 @@ public: static Renderer *get_singleton(); private: - int _initial_window_width; - int _initial_window_height; + int _initial_window_width; + int _initial_window_height; unsigned int _flags; unsigned int _window_flags; @@ -40,7 +43,7 @@ private: SDL_Window *_window; SDL_Renderer *_renderer; - int _window_display_index; + int _window_display_index; static Renderer *_singleton; }; diff --git a/05_sdl_alapok/string.cpp b/05_sdl_alapok/string.cpp new file mode 100644 index 0000000..e4beb49 --- /dev/null +++ b/05_sdl_alapok/string.cpp @@ -0,0 +1,333 @@ +#include "string.h" + +#include + +void String::push_back(const char element) { + ensure_capacity(_size + 1); + + _data[_size++] = element; + _data[_size] = '\0'; +} + +void String::pop_back() { + if (_size == 0) { + return; + } + + --_size; + + _data[_size] = '\0'; +} + +void String::remove(const int index) { + _data[index] = _data[_size - 1]; + + --_size; + + _data[_size] = '\0'; +} + +void String::erase(const char element) { + int index = find(element); + + if (index != -1) { + remove(index); + } +} + +void String::clear() { + _size = 0; +} + +bool String::empty() const { + return _size == 0; +} + +char String::get(const int index) { + return _data[index]; +} + +const char String::get(const int index) const { + return _data[index]; +} + +void String::set(const int index, const char value) { + _data[index] = value; +} + +int String::size() const { + return _size; +} + +int String::capacity() const { + return _actual_size; +} + +void String::ensure_capacity(const int capacity) { + if (capacity <= _actual_size) { + return; + } + + int tsize = capacity + _grow_by; + + char *nd = new char[tsize]; + + for (int i = 0; i < _size; ++i) { + nd[i] = _data[i]; + } + + delete[] _data; + + _data = nd; +} + +void String::resize(const int s) { + ensure_capacity(s + 1); // +1 for the null terminator + + _size = s; + + _data[_size] = '\0'; +} + +void String::append_array(const String &other) { + ensure_capacity(_size + other._size + 1); // +1 for the null terminator + + for (int i = 0; i < other._size; ++i) { + _data[_size++] = other._data[i]; + } + + _data[_size] = '\0'; +} + +int String::find(const char val) const { + for (int i = 0; i < _size; ++i) { + if (_data[i] == val) { + return i; + } + } + + return -1; +} + +float String::to_float() { + return atof(c_str()); +} + +double String::to_double() { + return atof(c_str()); +} + +int String::to_int() { + return atoi(c_str()); +} + +uint32_t String::to_uint() { + return static_cast(atoll(c_str())); +} + +char *String::c_str() { + return _data; +} + +const char *String::c_str() const { + return _data; +} + +char *String::dataw() { + return _data; +} + +const char *String::data() const { + return _data; +} + +const char String::operator[](const int index) const { + return _data[index]; +} + +char String::operator[](const int index) { + return _data[index]; +} + +String &String::operator+=(const String &b) { + ensure_capacity(_size + b._size + 1); // +1 for the null terminator + + for (int i = 0; i < b._size; ++i) { + _data[_size++] = b._data[i]; + } + + return *this; +} + +String &String::operator+=(const char chr) { + push_back(chr); + + return *this; +} + +String &String::operator+=(const char *p_c_str) { + int i = 0; + while (p_c_str[i] != '\0') { + push_back(p_c_str[i]); + ++i; + } + + return *this; +} + +String operator+(String lhs, const String &rhs) { + lhs += rhs; + + return lhs; +} + +String operator+(String lhs, const char *rhs) { + lhs += rhs; + + return lhs; +} + +String operator+(String lhs, const char rhs) { + lhs += rhs; + + return lhs; +} + +bool operator==(const String &a, const String &b) { + if (a._size != b._size) { + return false; + } + + for (int i = 0; i < a._size; ++i) { + if (a[i] != b[i]) { + return false; + } + } + + return true; +} + +bool operator!=(const String &a, const String &b) { + return !(a == b); +} + +bool operator==(const String &a, const char *b) { + int i = 0; + while (b[i] != '\0' && i < a._size) { + if (a[i] != b[i]) { + return false; + } + + ++i; + } + + if (i != a._size) { + return false; + } + + return true; +} + +bool operator!=(const String &a, const char *b) { + return !(a == b); +} + +bool operator==(const char *b, const String &a) { + int i = 0; + while (b[i] != '\0' && i < a._size) { + if (a[i] != b[i]) { + return false; + } + + ++i; + } + + if (i != a._size) { + return false; + } + + return true; +} + +bool operator!=(const char *b, const String &a) { + return !(a == b); +} + +String::String() { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = 100; + + ensure_capacity(100); + + _data[0] = '\0'; +} + +String::String(const String &other) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = 100; + + //+1 for the null terminator in case its needed + ensure_capacity(other.size() + 1); + + for (int i = 0; i < other._size; ++i) { + _data[i] = other._data[i]; + } + + _data[other._size] = '\0'; +} + +String::String(const String &other, int grow_by) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = grow_by; + + //+1 for the null terminator in case its needed + ensure_capacity(other.size() + 1); + + for (int i = 0; i < other._size; ++i) { + _data[i] = other._data[i]; + } + + _data[_size] = '\0'; +} + +String::String(const char* p_c_str) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = 100; + + operator+=(p_c_str); +} + +String::String(const char* p_c_str, const int grow_by) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = grow_by; + + operator+=(p_c_str); +} + +String::String(int prealloc) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = 100; + + ensure_capacity(prealloc); +} + +String::String(int prealloc, int grow_by) { + _data = nullptr; + _actual_size = 0; + _size = 0; + _grow_by = grow_by; + + ensure_capacity(prealloc); +} diff --git a/05_sdl_alapok/string.h b/05_sdl_alapok/string.h new file mode 100644 index 0000000..e161b7c --- /dev/null +++ b/05_sdl_alapok/string.h @@ -0,0 +1,72 @@ +#ifndef STRING_H +#define STRING_H + +#include + +class String { + +public: + void push_back(const char element); + void pop_back(); + void remove(const int index); + void erase(const char element); + void clear(); + bool empty() const; + char get(const int index); + const char get(const int index) const; + void set(const int index, const char value); + + int size() const; + int capacity() const; + void ensure_capacity(const int capacity); + void resize(const int s); + void append_array(const String &other); + int find(const char val) const; + + float to_float(); + double to_double(); + int to_int(); + uint32_t to_uint(); + + char *c_str(); + const char *c_str() const; + + char *dataw(); + const char *data() const; + + const char operator[](const int index) const; + char operator[](const int index); + + String &operator+=(const String &b); + String &operator+=(const char chr); + String &operator+=(const char *p_c_str); + + friend String operator+(String lhs, const String &rhs); + friend String operator+(String lhs, const char *rhs); + friend String operator+(String lhs, const char rhs); + + friend bool operator==(const String &a, const String &b); + friend bool operator!=(const String &a, const String &b); + + friend bool operator==(const String &a, const char *b); + friend bool operator!=(const String &a, const char *b); + + friend bool operator==(const char *b, const String &a); + friend bool operator!=(const char *b, const String &a); + + String(); + String(const String &other); + String(const String &other, const int grow_by); + String(const char* p_c_str); + String(const char* p_c_str, const int grow_by); + String(const int prealloc); + String(const int prealloc, const int grow_by); + +private: + char *_data; + int _actual_size; + int _size; + int _grow_by; +}; + +#endif \ No newline at end of file diff --git a/05_sdl_alapok/ti.bmp b/05_sdl_alapok/ti.bmp new file mode 100644 index 0000000..e385247 Binary files /dev/null and b/05_sdl_alapok/ti.bmp differ diff --git a/06_sdl_motor.txt b/06_sdl_motor.txt index 4337096..73547dd 100644 --- a/06_sdl_motor.txt +++ b/06_sdl_motor.txt @@ -4,4 +4,4 @@ Textura Sprite - +Assets class