1
0
mirror of https://github.com/lefticus/6502-cpp.git synced 2025-08-15 07:27:43 +00:00

Docs and cleanups of pong example

This commit is contained in:
Jason Turner
2016-09-20 15:14:10 -06:00
parent 9b204a4af0
commit 88d197e0d7

View File

@@ -61,24 +61,17 @@ namespace {
bool up,down,left,right,fire; bool up,down,left,right,fire;
}; };
///
/// New Code /// New Code
///
template<typename L1, typename L2, typename R1, typename R2> template<typename L1, typename L2, typename R1, typename R2>
auto operator+(std::pair<L1, L2> lhs, const std::pair<R1, R2> &rhs) auto operator+=(std::pair<L1&, L2&> lhs, const std::pair<R1, R2> &rhs)
{ {
lhs.first += rhs.first; lhs.first += rhs.first;
lhs.second += rhs.second; lhs.second += rhs.second;
return lhs; return lhs;
} }
template<typename L1, typename L2, typename R1, typename R2>
decltype(auto) operator+=(std::pair<L1, L2> &lhs, const std::pair<R1, R2> &rhs)
{
lhs.first += rhs.first;
lhs.second += rhs.second;
return (lhs);
}
template<typename L1, typename L2, typename R1, typename R2> template<typename L1, typename L2, typename R1, typename R2>
decltype(auto) operator*=(std::pair<L1, L2> &lhs, const std::pair<R1, R2> &rhs) decltype(auto) operator*=(std::pair<L1, L2> &lhs, const std::pair<R1, R2> &rhs)
{ {
@@ -119,6 +112,9 @@ namespace {
std::pair<volatile uint8_t &, volatile uint8_t &> pos; std::pair<volatile uint8_t &, volatile uint8_t &> pos;
uint8_t score = '0'; uint8_t score = '0';
}; };
///
/// End New Code
///
@@ -169,7 +165,8 @@ namespace {
template<uint8_t r, uint8_t g, uint8_t b, typename Colors> template<uint8_t r, uint8_t g, uint8_t b, typename Colors>
static auto nearest_color(const Colors &colors) static auto nearest_color(const Colors &colors)
{ {
return *std::min_element(std::begin(colors), std::end(colors), color_comparison<r,g,b>); return *std::min_element(std::begin(colors), std::end(colors),
color_comparison<r,g,b>);
} }
auto frame(Player &p1, Player &p2) auto frame(Player &p1, Player &p2)
@@ -206,14 +203,16 @@ namespace {
} }
template<typename ... D > template<typename ... D >
void write_multi_color_pixel(uint16_t loc, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, D ... d) void write_multi_color_pixel(uint16_t loc, uint8_t d1, uint8_t d2,
uint8_t d3, uint8_t d4, D ... d)
{ {
memory(loc) = (d1 << 6) | (d2 << 4) | (d3 << 2) | d4; memory(loc) = (d1 << 6) | (d2 << 4) | (d3 << 2) | d4;
write_multi_color_pixel(loc + 1, d...); write_multi_color_pixel(loc + 1, d...);
} }
template<typename ... D > template<typename ... D >
void write_pixel(uint16_t loc, bool d1, bool d2, bool d3, bool d4, bool d5, bool d6, bool d7, bool d8, D ... d) void write_pixel(uint16_t loc, bool d1, bool d2, bool d3, bool d4,
bool d5, bool d6, bool d7, bool d8, D ... d)
{ {
memory(loc) = (d1 << 7) | (d2 << 6) | (d3 << 5) | (d4 << 4) | (d5 << 3) | (d6 << 2) | (d7 << 1) | d8; memory(loc) = (d1 << 7) | (d2 << 6) | (d3 << 5) | (d4 << 4) | (d5 << 3) | (d6 << 2) | (d7 << 1) | d8;
write_pixel(loc + 1, d...); write_pixel(loc + 1, d...);
@@ -229,12 +228,15 @@ namespace {
} }
} }
///
/// New Code /// New Code
///
void enable_sprite(const uint8_t sprite_number, const uint8_t memory_loc, void enable_sprite(const uint8_t sprite_number, const uint8_t memory_loc,
const bool multicolor, const bool low_priority, const bool multicolor, const bool low_priority,
const bool double_width, const bool double_height) const bool double_width, const bool double_height)
{ {
memory(SPRITE_DATA_POINTERS + sprite_number) = SPRITE_STARTING_BANK + memory_loc; memory(SPRITE_DATA_POINTERS + sprite_number)
= SPRITE_STARTING_BANK + memory_loc;
set_bit(SPRITE_ENABLE_BITS, sprite_number, true); set_bit(SPRITE_ENABLE_BITS, sprite_number, true);
set_bit(SPRITE_EXPAND_HORIZONTAL, sprite_number, double_width); set_bit(SPRITE_EXPAND_HORIZONTAL, sprite_number, double_width);
set_bit(SPRITE_EXPAND_VERTICAL, sprite_number, double_height); set_bit(SPRITE_EXPAND_VERTICAL, sprite_number, double_height);
@@ -242,7 +244,6 @@ namespace {
set_bit(SPRITE_PRIORITY, sprite_number, low_priority); set_bit(SPRITE_PRIORITY, sprite_number, low_priority);
} }
auto sprite_collisions() { auto sprite_collisions() {
const auto collisions = memory(SPRITE_COLLISIONS); const auto collisions = memory(SPRITE_COLLISIONS);
@@ -251,6 +252,7 @@ namespace {
test_bit(collisions, 3),test_bit(collisions, 4),test_bit(collisions, 5), test_bit(collisions, 3),test_bit(collisions, 4),test_bit(collisions, 5),
test_bit(collisions, 6),test_bit(collisions, 7)); test_bit(collisions, 6),test_bit(collisions, 7));
} }
volatile uint8_t &sprite_1_color() volatile uint8_t &sprite_1_color()
{ {
return memory(SPRITE_1_COLOR); return memory(SPRITE_1_COLOR);
@@ -261,13 +263,17 @@ namespace {
return memory(SPRITE_2_COLOR); return memory(SPRITE_2_COLOR);
} }
std::pair<volatile uint8_t &, volatile uint8_t &> sprite_pos(const uint8_t sprite_num) std::pair<volatile uint8_t &, volatile uint8_t &>
sprite_pos(const uint8_t sprite_num)
{ {
return { return {
memory(SPRITE_POSITION_REGISTERS + sprite_num * 2), memory(SPRITE_POSITION_REGISTERS + sprite_num * 2),
memory(SPRITE_POSITION_REGISTERS + sprite_num * 2 + 1) memory(SPRITE_POSITION_REGISTERS + sprite_num * 2 + 1)
}; };
} }
///
/// End New Code
///
}; };
@@ -300,7 +306,6 @@ int main()
VIC_II vic; VIC_II vic;
vic.make_sprite(0, vic.make_sprite(0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -359,6 +364,9 @@ int main()
vic.sprite_2_color() = vic.nearest_color<0,255,0>(colors).num; // green vic.sprite_2_color() = vic.nearest_color<0,255,0>(colors).num; // green
///
/// Game Logic
///
std::pair<int8_t, int8_t> ball_velocity{1,1}; std::pair<int8_t, int8_t> ball_velocity{1,1};
const auto reset_ball = [&vic]{ const auto reset_ball = [&vic]{
@@ -371,30 +379,26 @@ int main()
Player p1(1, vic.sprite_pos(1), {15, 255/2}); Player p1(1, vic.sprite_pos(1), {15, 255/2});
Player p2(2, vic.sprite_pos(2), {255, 255/2}); Player p2(2, vic.sprite_pos(2), {255, 255/2});
///
// Game Loop /// Game Loop
///
while (true) { while (true) {
auto frame = vic.frame(p1, p2); auto frame = vic.frame(p1, p2);
if (const auto [s0, s1, s2, s3, s4, s5, s6, s7] = vic.sprite_collisions(); if (const auto [s0, s1, s2, s3, s4, s5, s6, s7] = vic.sprite_collisions();
s0 && (s1 || s2)) s0 && (s1 || s2))
{ {
auto &x_velocity = std::get<0>(ball_velocity); // ball hit paddle, invert ball x velocity
x_velocity *= -1; //invert ball x velocity ball_velocity *= std::make_pair(-1, 1);
// "bounce" ball out of collision area // "bounce" ball out of collision area
vic.sprite_pos(0).first += x_velocity; vic.sprite_pos(0) += std::make_pair(ball_velocity.first, 0);
} }
// Update paddle positions // Update paddle positions
p1.update_position(); p1.update_position();
p2.update_position(); p2.update_position();
// ball hit the top or bottom wall
if (const auto ball_y = vic.sprite_pos(0).second += std::get<1>(ball_velocity);
ball_y == 45 || ball_y == 235)
{
std::get<1>(ball_velocity) *= -1; // invert ball y velocity
}
const auto score = [reset_ball](auto &player){ const auto score = [reset_ball](auto &player){
// called when a player scores // called when a player scores
@@ -402,8 +406,12 @@ int main()
reset_ball(); reset_ball();
}; };
if (const auto ball_x = vic.sprite_pos(0).first += std::get<0>(ball_velocity); if (const auto [ball_x, ball_y] = vic.sprite_pos(0) += ball_velocity;
ball_x == 1) { ball_y == 45 || ball_y == 235)
{
// ball hit the top or bottom wall, invert ball y velocity
ball_velocity *= std::make_pair(1, -1);
} else if (ball_x == 1) {
// ball hit left wall, player 2 scored // ball hit left wall, player 2 scored
score(p2); score(p2);
} else if (ball_x == 255) { } else if (ball_x == 255) {