add screen
This commit is contained in:
parent
65713e6b9f
commit
bc79410a77
3
Makefile
3
Makefile
@ -4,6 +4,9 @@ MAKEFLAGS += -j16
|
|||||||
CXXFLAGS := -std=c++23 -Wall -Wextra -pedantic-errors -fsanitize=address,undefined
|
CXXFLAGS := -std=c++23 -Wall -Wextra -pedantic-errors -fsanitize=address,undefined
|
||||||
LDFLAGS :=
|
LDFLAGS :=
|
||||||
|
|
||||||
|
CXXFLAGS += $(shell pkgconf sdl2 --cflags)
|
||||||
|
CXXFLAGS += $(shell pkgconf sdl2 --libs)
|
||||||
|
|
||||||
build_dir = build
|
build_dir = build
|
||||||
obj_dir = $(build_dir)/obj
|
obj_dir = $(build_dir)/obj
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
#include "builder.hpp"
|
#include "builder.hpp"
|
||||||
|
#include "screen.hpp"
|
||||||
|
#include <SDL2/SDL_main.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <print>
|
#include <print>
|
||||||
@ -9,6 +11,9 @@ using R = Reg;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
auto screen = Screen::create(4, 8 * 40, 8 * 24);
|
||||||
|
screen.value()->set_char(0, 'A');
|
||||||
|
|
||||||
constexpr R r0 = R::R0;
|
constexpr R r0 = R::R0;
|
||||||
constexpr R r1 = R::R1;
|
constexpr R r1 = R::R1;
|
||||||
constexpr R r2 = R::R2;
|
constexpr R r2 = R::R2;
|
||||||
|
|||||||
160
src/screen.cpp
Normal file
160
src/screen.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include "screen.hpp"
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_error.h>
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
#include <SDL2/SDL_video.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
using namespace vc5;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool sdl_is_initialized = false;
|
||||||
|
|
||||||
|
struct Char {
|
||||||
|
explicit constexpr Char(char ch, uint64_t data)
|
||||||
|
: ch(ch)
|
||||||
|
, data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
auto to_u64() const -> uint64_t
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ch;
|
||||||
|
uint64_t data;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto charset = std::array {
|
||||||
|
Char(' ', 0x0000000000000000),
|
||||||
|
Char('A', 0x66667E66667E1800),
|
||||||
|
Char('B', 0x7C7E667C667E7800),
|
||||||
|
Char('C', 0x3C7E6060607E3C00),
|
||||||
|
Char('D', 0x7C7E6666667E7C00),
|
||||||
|
Char('E', 0x7E7E607E607E7E00),
|
||||||
|
Char('F', 0x60607878607E7E00),
|
||||||
|
Char('G', 0x7E7E666E607E7E00),
|
||||||
|
Char('H', 0x6666667E7E666600),
|
||||||
|
Char('I', 0x7E7E1818187E7E00),
|
||||||
|
Char('J', 0x3C7E6606067E7E00),
|
||||||
|
Char('K', 0x666E7C7C6E666600),
|
||||||
|
Char('L', 0x7E7E606060606000),
|
||||||
|
Char('M', 0xC3C3C3C3DBFFE700),
|
||||||
|
Char('N', 0x6666666E7E766600),
|
||||||
|
Char('O', 0x3C66666666663C00),
|
||||||
|
Char('P', 0x60607C7E667C7C00),
|
||||||
|
Char('Q', 0x3F7E6E66667E3C00),
|
||||||
|
Char('R', 0x666C7C7E667E7C00),
|
||||||
|
Char('S', 0x3C66063C60663C00),
|
||||||
|
Char('T', 0x18181818187E7E00),
|
||||||
|
Char('U', 0x3C7E666666666600),
|
||||||
|
Char('V', 0x183C7E6666666600),
|
||||||
|
Char('W', 0xE7FFDBDBC3C3C300),
|
||||||
|
Char('X', 0x6666663C3C666600),
|
||||||
|
Char('Y', 0x181818183C666600),
|
||||||
|
Char('Z', 0x7E7E30180C7E7E00),
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Screen::create(int ch_size, int ch_width, int ch_height)
|
||||||
|
-> std::expected<std::unique_ptr<Screen>, std::string>
|
||||||
|
{
|
||||||
|
auto profile = ScreenProfile(ch_size, ch_width, ch_height);
|
||||||
|
auto [_0, _1, _2, px_width, px_height] = profile;
|
||||||
|
|
||||||
|
if (!sdl_is_initialized) {
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||||
|
return std::unexpected(SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Window* window;
|
||||||
|
SDL_Renderer* renderer;
|
||||||
|
|
||||||
|
if (SDL_CreateWindowAndRenderer(px_width, px_height, 0, &window, &renderer)
|
||||||
|
!= 0) {
|
||||||
|
return std::unexpected(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Texture* texture = SDL_CreateTexture(renderer,
|
||||||
|
SDL_PIXELFORMAT_RGBA32,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
px_width,
|
||||||
|
px_height);
|
||||||
|
|
||||||
|
if (texture == nullptr) {
|
||||||
|
return std::unexpected(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
|
return std::make_unique<Screen>(profile, window, renderer, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen::~Screen()
|
||||||
|
{
|
||||||
|
auto lock = std::lock_guard(mx);
|
||||||
|
|
||||||
|
SDL_DestroyTexture(m_texture);
|
||||||
|
SDL_DestroyRenderer(m_renderer);
|
||||||
|
SDL_DestroyWindow(m_window);
|
||||||
|
|
||||||
|
if (sdl_is_initialized) {
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Screen::set_char(uint16_t offset, uint8_t value)
|
||||||
|
-> std::expected<void, std::string>
|
||||||
|
{
|
||||||
|
auto lock = std::lock_guard(mx);
|
||||||
|
|
||||||
|
auto it = std::find_if(charset.begin(), charset.end(), [&](Char ch) {
|
||||||
|
return ch.ch == value;
|
||||||
|
});
|
||||||
|
Char my_char = *it;
|
||||||
|
|
||||||
|
SDL_Color* buffer;
|
||||||
|
int pitch;
|
||||||
|
int res = SDL_LockTexture(m_texture, NULL, (void**)&buffer, &pitch);
|
||||||
|
if (res != 0) {
|
||||||
|
return std::unexpected(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto [ch_size, ch_width, ch_height, px_width, px_height] = m_profile;
|
||||||
|
|
||||||
|
for (int ch_y = 0; ch_y < ch_height; ++ch_y) {
|
||||||
|
for (int ch_x = 0; ch_x < ch_width; ++ch_x) {
|
||||||
|
bool ch
|
||||||
|
= my_char.to_u64() >> (ch_y * ch_width + (ch_width - ch_x - 1))
|
||||||
|
& 1;
|
||||||
|
|
||||||
|
for (int px_y = 0; px_y < ch_size; ++px_y) {
|
||||||
|
for (int px_x = 0; px_x < ch_size; ++px_x) {
|
||||||
|
|
||||||
|
int x = (offset % ch_width * ch_size + ch_x) * px_width
|
||||||
|
+ px_x;
|
||||||
|
int y = (offset / ch_height * ch_size + ch_y) * px_height
|
||||||
|
+ px_y;
|
||||||
|
|
||||||
|
buffer[y * px_width + x] = ch
|
||||||
|
? SDL_Color { 0xff, 0xff, 0xff, 0xff }
|
||||||
|
: SDL_Color { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_UnlockTexture(m_texture);
|
||||||
|
SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
|
||||||
|
|
||||||
|
SDL_RenderPresent(m_renderer);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
61
src/screen.hpp
Normal file
61
src/screen.hpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <expected>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct SDL_Window;
|
||||||
|
struct SDL_Renderer;
|
||||||
|
struct SDL_Texture;
|
||||||
|
|
||||||
|
namespace vc5 {
|
||||||
|
|
||||||
|
struct ScreenProfile {
|
||||||
|
explicit ScreenProfile(int ch_size, int ch_width, int ch_height)
|
||||||
|
: ch_size(ch_size)
|
||||||
|
, ch_width(ch_width)
|
||||||
|
, ch_height(ch_height)
|
||||||
|
, px_width(ch_size * ch_width)
|
||||||
|
, px_height(ch_size * ch_height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ch_size;
|
||||||
|
int ch_width;
|
||||||
|
int ch_height;
|
||||||
|
int px_width;
|
||||||
|
int px_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Screen {
|
||||||
|
public:
|
||||||
|
static auto create(int ch_size, int ch_width, int ch_height)
|
||||||
|
-> std::expected<std::unique_ptr<Screen>, std::string>;
|
||||||
|
|
||||||
|
explicit Screen(ScreenProfile profile,
|
||||||
|
SDL_Window* window,
|
||||||
|
SDL_Renderer* renderer,
|
||||||
|
SDL_Texture* texture)
|
||||||
|
: m_profile(profile)
|
||||||
|
, m_window(window)
|
||||||
|
, m_renderer(renderer)
|
||||||
|
, m_texture(texture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~Screen();
|
||||||
|
|
||||||
|
auto set_char(uint16_t offset, uint8_t value)
|
||||||
|
-> std::expected<void, std::string>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mx;
|
||||||
|
|
||||||
|
ScreenProfile m_profile;
|
||||||
|
SDL_Window* m_window;
|
||||||
|
SDL_Renderer* m_renderer;
|
||||||
|
SDL_Texture* m_texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user