1
0
mirror of https://github.com/lefticus/6502-cpp.git synced 2025-06-24 15:23:59 +00:00

Presentation code working

This commit is contained in:
Jason Turner
2021-08-31 17:57:08 -06:00
parent bda3c6a9fc
commit f410dfd38e
7 changed files with 227 additions and 102 deletions

View File

@ -1,7 +1,8 @@
#include <cstdint>
constexpr std::uint8_t uppercase[] = {
0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x62, 0x3C, 0x00,
namespace petscii {
constexpr static std::uint8_t uppercase[] = {
0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x62, 0x3C, 0x00,
0x18, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
@ -258,7 +259,8 @@ constexpr std::uint8_t uppercase[] = {
0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0,
};
constexpr std::uint8_t lowercase[] = { 0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x62, 0x3C, 0x00,
constexpr static std::uint8_t lowercase[] = {
0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x62, 0x3C, 0x00,
0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x3C, 0x60, 0x60, 0x60, 0x3C, 0x00,
@ -514,3 +516,5 @@ constexpr std::uint8_t lowercase[] = { 0x3C, 0x66, 0x6E, 0x6E, 0x60, 0x62, 0x3C,
0xE7, 0xE7, 0xE7, 0x07, 0x07, 0xFF, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 };
}

View File

@ -20,6 +20,9 @@ struct Joystick
[[nodiscard]] constexpr bool fire() const noexcept { return (state & 16) == 0; }
[[nodiscard]] constexpr bool right() const noexcept { return (state & 8) == 0; }
[[nodiscard]] constexpr bool down() const noexcept { return (state & 2) == 0; }
[[nodiscard]] constexpr bool operator==(const Joystick &other) const = default;
[[nodiscard]] constexpr bool operator!=(const Joystick &other) const = default;
};
struct Clock

View File

@ -161,42 +161,7 @@ struct GameState
}
};
static void puts(const geometry::point loc, const auto &range, const vicii::Colors color = vicii::Colors::white)
{
const auto offset = static_cast<std::uint16_t>(loc.y * 40 + loc.x);
const std::uint16_t start = 0x400 + offset;
std::copy(begin(range), end(range), &mos6502::memory_loc(start));
for (std::uint16_t color_loc = 0; color_loc < range.size(); ++color_loc) {
mos6502::poke(static_cast<std::uint16_t>(0xD800 + color_loc + offset), static_cast<std::uint8_t>(color));
}
}
static constexpr auto load_charset(const std::span<const std::uint8_t, 256 * 8> &bits)
{
std::array<petscii::Graphic<geometry::size{ 8, 8 }>, 256> results{};
for (std::size_t idx = 0; idx < 256; ++idx) {
petscii::Graphic<geometry::size{ 8, 8 }> glyph{};
for (std::uint8_t row = 0; row < 8; ++row) {
const auto input_row = bits[idx * 8 + row];
glyph[geometry::point{ 0, row }] = (0b1000'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0100'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0010'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0001'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0000'1000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0000'0100 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0000'0010 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 0, row }] = (0b0000'0001 & input_row) == 0 ? 0 : 1;
}
results[idx] = glyph;
}
return results;
}
template<geometry::size Size> static constexpr auto from_pixels_to_petscii(const petscii::Graphic<Size> &pixels)
{
@ -228,44 +193,6 @@ template<geometry::size Size> static constexpr auto from_pixels_to_petscii(const
return result;
}
template<geometry::size Size> static constexpr auto from_pixels_to_2x2(const petscii::Graphic<Size> &pixels)
{
petscii::Graphic<geometry::size{ Size.width / 2, Size.height / 2 }> result{};
using GlyphType = std::pair<petscii::Graphic<geometry::size{ 2, 2 }>, std::uint8_t>;
constexpr std::array<GlyphType, 17> lookup_map{ GlyphType{ { 0, 0, 0, 0 }, 32 },
GlyphType{ { 1, 0, 0, 0 }, 126 },
GlyphType{ { 0, 1, 0, 0 }, 124 },
GlyphType{ { 1, 1, 0, 0 }, 226 },
GlyphType{ { 0, 0, 1, 0 }, 123 },
GlyphType{ { 1, 0, 1, 0 }, 97 },
GlyphType{ { 0, 1, 1, 0 }, 255 },
GlyphType{ { 1, 1, 1, 0 }, 236 },
GlyphType{ { 0, 0, 0, 1 }, 108 },
GlyphType{ { 1, 0, 0, 1 }, 127 },
GlyphType{ { 0, 1, 0, 1 }, 225 },
GlyphType{ { 1, 1, 0, 1 }, 251 },
GlyphType{ { 0, 0, 1, 1 }, 98 },
GlyphType{ { 1, 0, 1, 1 }, 252 },
GlyphType{ { 0, 1, 1, 1 }, 254 },
GlyphType{ { 1, 1, 1, 1 }, 160 } };
for (uint8_t x = 0; x < pixels.width(); x += 2) {
for (uint8_t y = 0; y < pixels.height(); y += 2) {
for (const auto &glyph : lookup_map) {
if (pixels.match(glyph.first, x, y)) {
result(x / 2, y / 2) = glyph.second;
break;// go to next Y, we found our match
}
}
}
}
return result;
}
template<geometry::size Size> struct SimpleSprite
{
geometry::point location{};

View File

@ -2,6 +2,7 @@
#define INC_6502_C_GEOMETRY_HPP
#include <cstdint>
#include <compare>
namespace geometry {
struct point

View File

@ -4,6 +4,7 @@
#include "geometry.hpp"
#include <algorithm>
#include <array>
#include <span>
namespace petscii {
@ -40,7 +41,7 @@ template<geometry::size size_> struct Graphic
constexpr bool match(const auto &graphic, const geometry::point p) const
{
return match_count(graphic, p) == (graphic.width() * graphic.height());
return match_count(graphic, p) == (graphic.size().width * graphic.size().height);
}
};
@ -51,18 +52,99 @@ template<geometry::size size_> struct ColoredGraphic
};
[[nodiscard]] constexpr char charToPETSCII2(char c) noexcept
{
if (c >= 'a' && c <= 'z') { return c - 'a' + 1; }
if (c >= 'A' && c <= 'Z') { return c - 'A' + 65; }
if (c == '@') { return 0; }
return c;
}
[[nodiscard]] constexpr char charToPETSCII(char c) noexcept
{
if (c == '@') { return 0; }
if (c >= 'A' && c <= 'Z') { return c - 'A' + 1; }
return c;
}
template<std::size_t Size> constexpr auto PETSCII(const char (&value)[Size]) noexcept
template<std::size_t Size> consteval auto PETSCII2(const char (&value)[Size]) noexcept
{
std::array<char, Size - 1> result{};
std::transform(std::begin(value), std::prev(std::end(value)), std::begin(result), charToPETSCII2);
return result;
}
template<std::size_t Size> consteval auto PETSCII(const char (&value)[Size]) noexcept
{
std::array<char, Size - 1> result{};
std::transform(std::begin(value), std::prev(std::end(value)), std::begin(result), charToPETSCII);
return result;
}
static constexpr auto load_charset(std::span<const std::uint8_t, 256 * 8> bits)
{
std::array<petscii::Graphic<geometry::size{ 8, 8 }>, 256> results{};
for (std::size_t idx = 0; idx < 256; ++idx) {
petscii::Graphic<geometry::size{ 8, 8 }> glyph{};
for (std::uint8_t row = 0; row < 8; ++row) {
const auto input_row = bits[idx * 8 + row];
glyph[geometry::point{ 0, row }] = (0b1000'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 1, row }] = (0b0100'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 2, row }] = (0b0010'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 3, row }] = (0b0001'0000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 4, row }] = (0b0000'1000 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 5, row }] = (0b0000'0100 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 6, row }] = (0b0000'0010 & input_row) == 0 ? 0 : 1;
glyph[geometry::point{ 7, row }] = (0b0000'0001 & input_row) == 0 ? 0 : 1;
}
results[idx] = glyph;
}
return results;
}
template<geometry::size Size> static constexpr auto from_pixels_to_2x2(const petscii::Graphic<Size> &pixels)
{
petscii::Graphic<geometry::size{ Size.width / 2, Size.height / 2 }> result{};
using GlyphType = std::pair<petscii::Graphic<geometry::size{ 2, 2 }>, std::uint8_t>;
constexpr std::array<GlyphType, 17> lookup_map{ GlyphType{ { 0, 0, 0, 0 }, 32 },
GlyphType{ { 1, 0, 0, 0 }, 126 },
GlyphType{ { 0, 1, 0, 0 }, 124 },
GlyphType{ { 1, 1, 0, 0 }, 226 },
GlyphType{ { 0, 0, 1, 0 }, 123 },
GlyphType{ { 1, 0, 1, 0 }, 97 },
GlyphType{ { 0, 1, 1, 0 }, 255 },
GlyphType{ { 1, 1, 1, 0 }, 236 },
GlyphType{ { 0, 0, 0, 1 }, 108 },
GlyphType{ { 1, 0, 0, 1 }, 127 },
GlyphType{ { 0, 1, 0, 1 }, 225 },
GlyphType{ { 1, 1, 0, 1 }, 251 },
GlyphType{ { 0, 0, 1, 1 }, 98 },
GlyphType{ { 1, 0, 1, 1 }, 252 },
GlyphType{ { 0, 1, 1, 1 }, 254 },
GlyphType{ { 1, 1, 1, 1 }, 160 } };
for (uint8_t x = 0; x < pixels.size().width; x += 2) {
for (uint8_t y = 0; y < pixels.size().height; y += 2) {
for (const auto &glyph : lookup_map) {
if (pixels.match(glyph.first, {x, y})) {
result[geometry::point{static_cast<std::uint8_t>(x / 2), static_cast<std::uint8_t>(y / 2)}] = glyph.second;
break;// go to next Y, we found our match
}
}
}
}
return result;
}
}// namespace petscii

View File

@ -2,7 +2,10 @@
#define INC_6502_C_VICII_HPP
#include "6502.hpp"
#include "geometry.hpp"
#include <cstdint>
#include <algorithm>
#include <iterator>
namespace vicii {
enum struct Colors : std::uint8_t {
@ -29,7 +32,7 @@ enum struct Colors : std::uint8_t {
// static void increment_border_color() { mos6502::poke(0xd020, mos6502::peek(0xd020) + 1); }
static void putc(geometry::point location, std::uint8_t c, Colors color)
static inline void putc(geometry::point location, std::uint8_t c, Colors color)
{
const auto offset = static_cast<std::uint16_t>(location.y * 40 + location.x);
const auto start = static_cast<std::uint16_t>(0x400 + offset);
@ -37,20 +40,44 @@ static void putc(geometry::point location, std::uint8_t c, Colors color)
mos6502::poke(offset + 0xD800, static_cast<std::uint8_t>(color));
}
static std::uint8_t getc(geometry::point location)
static inline std::uint8_t getc(geometry::point location)
{
const auto start = static_cast<std::uint16_t>(0x400 + (location.y * 40 + location.x));
return mos6502::peek(start);
}
static void invertc(geometry::point location)
static inline void invertc(geometry::point location)
{
const auto start = static_cast<std::uint16_t>(0x400 + (location.y * 40 + location.x));
mos6502::memory_loc(start) += 128;
}
static inline void set_background(const vicii::Colors color) {
mos6502::poke(53280, static_cast<std::uint8_t>(color));
}
static void put_hex(geometry::point start, uint8_t value, Colors color)
static inline void set_border(const vicii::Colors color) {
mos6502::poke(53281, static_cast<std::uint8_t>(color));
}
static inline void puts(const geometry::point loc, const auto &range, const vicii::Colors color = vicii::Colors::white)
{
const auto offset = static_cast<std::uint16_t>(loc.y * 40 + loc.x);
const std::uint16_t start = 0x400 + offset;
using namespace std;
std::copy(begin(range), end(range), &mos6502::memory_loc(start));
for (std::uint16_t color_loc = 0; color_loc < size(range); ++color_loc) {
mos6502::poke(static_cast<std::uint16_t>(0xD800 + color_loc + offset), static_cast<std::uint8_t>(color));
}
}
static inline void put_hex(geometry::point start, uint8_t value, Colors color)
{
const auto put_nibble = [color](geometry::point location, std::uint8_t nibble) {
if (nibble <= 9) {
@ -64,18 +91,18 @@ static void put_hex(geometry::point start, uint8_t value, Colors color)
put_nibble(start , 0xF & (value >> 4));
}
static void put_hex(geometry::point location, std::uint16_t value, Colors color)
static inline void put_hex(geometry::point location, std::uint16_t value, Colors color)
{
put_hex(location, static_cast<std::uint8_t>(0xFF & (value >> 8)), color);
put_hex(location + geometry::point{ 2, 0 }, static_cast<std::uint8_t>(0xFF & value), color);
}
static void put_graphic(geometry::point location, const auto &graphic)
static inline void put_graphic(geometry::point location, const auto &graphic)
{
for (const auto &p : graphic.size()) { putc(p + location, graphic[p], Colors::white); }
}
static void put_graphic(geometry::point location, const auto &graphic) requires requires { graphic.colors[{0, 0}]; }
static inline void put_graphic(geometry::point location, const auto &graphic) requires requires { graphic.colors[{0, 0}]; }
{
for (const auto &p : graphic.data.size()) {
putc(p + location, graphic.data[p], static_cast<Colors>(graphic.colors[p]));
@ -83,7 +110,7 @@ static void put_graphic(geometry::point location, const auto &graphic) requires
}
static void cls()
static inline void cls()
{
for (std::uint16_t i = 0x400; i < 0x400 + 1000; ++i) { mos6502::poke(i, 32); }
}
@ -135,7 +162,7 @@ static void draw_hline(geometry::point begin, const geometry::point end, Colors
}
}
static void draw_box(geometry::rect geo, Colors color)
static inline void draw_box(geometry::rect geo, Colors color)
{
putc(geo.top_left(), 85, color);
putc(geo.top_right(), 73, color);
@ -149,7 +176,7 @@ static void draw_box(geometry::rect geo, Colors color)
draw_vline(geo.top_right() + geometry::point{ 0, 1 }, geo.bottom_right(), color);
}
void clear(geometry::rect box, Colors color) {
static inline void clear(geometry::rect box, Colors color) {
for (const auto &p : box.size()) {
putc(p + box.top_left(), ' ', color);
}