diff --git a/font.png b/font.png new file mode 100644 index 0000000..fa3849a Binary files /dev/null and b/font.png differ diff --git a/source/main.cpp b/source/main.cpp index c30276c..56379ec 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -17,6 +17,7 @@ int main(int argc, char *argv[]) { m6502dis::symbols::load(); atari2600::init(); atari2600::pause(); + m6502debugger::init(); m6502debugger::show(); int wait = 16; diff --git a/source/ui.cpp b/source/ui.cpp index 4e3abae..e4a56f7 100644 --- a/source/ui.cpp +++ b/source/ui.cpp @@ -33,7 +33,7 @@ namespace ui SDL_Texture * createtexture(SDL_Renderer *renderer) { - SDL_Surface *bmp_surface = SDL_LoadBMP("font.bmp"); + SDL_Surface *bmp_surface = SDL_LoadPNG("font.png"); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, bmp_surface); SDL_DestroySurface(bmp_surface); SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST); diff --git a/source/ui/context.cpp b/source/ui/context.cpp new file mode 100644 index 0000000..9a3346b --- /dev/null +++ b/source/ui/context.cpp @@ -0,0 +1,126 @@ +#include "context.h" + +#define CHR_W 6 +#define CHR_H 13 + +namespace ui +{ + Context::Context(SDL_Window *window) + { + this->win = window; + this->ren = SDL_CreateRenderer(this->win, NULL); + this->fontTex = LoadTexture("font.png"); + + this->offsetX = this->offsetY = 0; + } + + Context::~Context() + { + SDL_DestroyRenderer(this->ren); + SDL_DestroyTexture(this->fontTex); + } + + SDL_Texture *Context::CreateTexture(int width, int height) + { + SDL_Texture *texture = SDL_CreateTexture(this->ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + return texture; + } + + SDL_Texture *Context::LoadTexture(const char* filename) + { + SDL_Surface *bmp_surface = SDL_LoadPNG(filename); + SDL_Texture *texture = SDL_CreateTextureFromSurface(this->ren, bmp_surface); + SDL_DestroySurface(bmp_surface); + SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + return texture; + } + + void Context::SetOffset(int x, int y) + { + this->offsetX = x; + this->offsetY = y; + } + + void Context::IncOffset(int x, int y) + { + this->offsetX += x; + this->offsetY += y; + } + + int Context::GetOffsetX() + { + return this->offsetX; + } + + int Context::GetOffsetY() + { + return this->offsetY; + } + + void Context::PushOffset() + { + this->offsetStack.push({this->offsetX, this->offsetY}); + } + + void Context::PopOffset() + { + this->offsetX = this->offsetStack.top().first; + this->offsetY = this->offsetStack.top().second; + this->offsetStack.pop(); + } + + void Context::ClearOffsetStack() + { + this->offsetStack = std::stack>(); + } + + bool Context::IsMouseInside(int x, int y, int w, int h) + { + float tmpf_x, tmpf_y; + SDL_GetMouseState(&tmpf_x, &tmpf_y); + + const int tmp_x = int(tmpf_x) + this->offsetX; + const int tmp_y = int(tmpf_y) + this->offsetY; + + return ( (tmp_x >= x) && (tmp_x < x+w) && (tmp_y >= y) && (tmp_y < y+h) ); + } + + void Context::DrawRect(int x, int y, int w, int h, uint32_t color) + { + SDL_FRect rect {float(this->offsetX+x), float(this->offsetY+y), float(w), float(h)}; + SDL_SetRenderDrawColor(this->ren, (color>>16)&0xff, (color>>8)&0xff, color&0xff, (color>>24)&0xff); + SDL_RenderRect(this->ren, &rect); + } + + void Context::FillRect(int x, int y, int w, int h, uint32_t color) + { + SDL_FRect rect {float(this->offsetX+x), float(this->offsetY+y), float(w), float(h)}; + SDL_SetRenderDrawColor(this->ren, (color>>16)&0xff, (color>>8)&0xff, color&0xff, (color>>24)&0xff); + SDL_RenderFillRect(this->ren, &rect); + } + + void Context::DrawLine(int x1, int y1, int x2, int y2, uint32_t color) + { + SDL_SetRenderDrawColor(this->ren, (color>>16)&0xff, (color>>8)&0xff, color&0xff, (color>>24)&0xff); + SDL_RenderLine(this->ren, float(this->offsetX+x1), float(this->offsetY+y1), float(this->offsetX+x2), float(this->offsetY+y2)); + } + + void Context::DrawChar(int x, int y, char chr, uint32_t color=0xffffffff) + { + if (color != 255) SDL_SetRenderDrawColor(this->ren, (color>>16)&0xff, (color>>8)&0xff, color&0xff, (color>>24)&0xff); + if (chr==32) return; + if (chr<32 || chr>127) chr = '.'; + SDL_FRect src {float((chr-32)&0xf)*CHR_W, float((chr-32)>>4)*CHR_H, float(CHR_W), float(CHR_H)}; + SDL_FRect dst {float(this->offsetX+x), float(this->offsetY+y), float(CHR_W), float(CHR_H)}; + SDL_RenderTexture(ren, this->fontTex, &src, &dst); + } + + void Context::DrawText(int x, int y, const char *text, uint32_t color) + { + SDL_SetTextureColorMod(this->fontTex, (color>>16)&0xff, (color>>8)&0xff, color&0xff); + for (int i=0; i<(int)strlen(text);++i) if (text[i]!=32) DrawChar(x+i*CHR_W, y, text[i]); + } +} \ No newline at end of file diff --git a/source/ui/context.h b/source/ui/context.h new file mode 100644 index 0000000..af29ff1 --- /dev/null +++ b/source/ui/context.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include + +namespace ui +{ + class Context { + public: + Context(SDL_Window *window); + ~Context(); + + SDL_Texture * CreateTexture(int width, int height); + SDL_Texture * LoadTexture(const char* filename); + + void SetOffset(int x, int y); + void IncOffset(int x, int y); + int GetOffsetX(); + int GetOffsetY(); + void PushOffset(); + void PopOffset(); + void ClearOffsetStack(); + + bool IsMouseInside(int x, int y, int w, int h); + + void DrawRect(int x, int y, int w, int h, uint32_t color); + void FillRect(int x, int y, int w, int h, uint32_t color); + void DrawLine(int x1, int y1, int x2, int y2, uint32_t color); + void DrawChar(int x, int y, char chr, uint32_t color=0xffffffff); + void DrawText(int x, int y, const char *text, uint32_t color); + + protected: + SDL_Window *win; + SDL_Renderer *ren; + SDL_Texture *fontTex; + + int offsetX, offsetY; + std::stack> offsetStack; + }; +} diff --git a/source/ui/window.cpp b/source/ui/window.cpp new file mode 100644 index 0000000..f0d7c1e --- /dev/null +++ b/source/ui/window.cpp @@ -0,0 +1,50 @@ +#include "window.h" + +namespace ui +{ + Window::Window(const char *title, int width, int height) + { + this->win = SDL_CreateWindow(title, width, height, 0); + this->context = new Context(this->win); + + windows.push_back({SDL_GetWindowID(this->win), this}); + + float x, y; + SDL_GetMouseState(&x, &y); + input.mouse.x = int(x); + input.mouse.y = int(y); + } + + Window::~Window() + { + for (size_t i=0; icontext; + SDL_DestroyWindow(this->win); + } + + bool Window::HandleEvents(SDL_Event *e) + { + switch (e->type) { + case SDL_EVENT_MOUSE_MOTION: + input.mouse.x = e->motion.x; + input.mouse.y = e->motion.y; + + // ... + + default: break; + } + } + + + /* MÈTODES ESTATICS */ + /* ================ */ + + std::vector> Window::windows; + + void Window::DistributeEvent(SDL_Event *e) + { + uint32_t id = SDL_GetWindowID(SDL_GetWindowFromEvent(e)); + for (auto window : Window::windows) if (window.first == id) window.second->HandleEvents(e); + } +} \ No newline at end of file diff --git a/source/ui/window.h b/source/ui/window.h new file mode 100644 index 0000000..bc8c876 --- /dev/null +++ b/source/ui/window.h @@ -0,0 +1,38 @@ +#pragma once +#include "context.h" +#include + +namespace ui +{ + enum MouseButton { mbLeft = 0, mbMiddle = 1, mbRight = 2 }; + enum MouseButtonState { mbsReleased, mbsDown, mbsPressed, mbsUp }; + struct Input { + struct { + int x, y; + MouseButtonState buttons[3] = {mbsReleased, mbsReleased, mbsReleased}; + } mouse; + struct { + uint8_t keyDown = 0; + uint8_t keyUp = 0; + const bool *keys; + } keyboard; + }; + + class Window { + public: + + Window(const char *title, int width, int height); + ~Window(); + + bool HandleEvents(SDL_Event *e); + + static void DistributeEvent(SDL_Event *e); + + protected: + SDL_Window *win; + Context *context; + Input input; + + static std::vector> windows; + }; +} \ No newline at end of file