mirror of
https://github.com/lefticus/6502-cpp.git
synced 2025-01-02 12:30:58 +00:00
Basic two player pong working
This commit is contained in:
parent
68d93b0a1e
commit
70aa76dce9
68
pong2.cpp
68
pong2.cpp
@ -209,7 +209,7 @@ int main()
|
||||
0,0,2,2,1,1,1,1,2,2,0,0,
|
||||
0,0,2,2,2,1,1,2,2,2,0,0,
|
||||
0,0,0,2,2,2,2,2,2,0,0,0,
|
||||
0,0,0,2,2,2,2,2,2,0,0,0,
|
||||
0,0,0,0,2,2,2,2,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,
|
||||
@ -220,9 +220,9 @@ int main()
|
||||
|
||||
make_sprite(1,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,2,2,2,2,0,0,0,0,
|
||||
0,0,0,0,2,2,2,2,0,0,0,0,
|
||||
0,0,0,0,2,1,1,2,0,0,0,0,
|
||||
@ -236,24 +236,15 @@ int main()
|
||||
0,0,0,0,2,1,1,2,0,0,0,0,
|
||||
0,0,0,0,2,2,2,2,0,0,0,0,
|
||||
0,0,0,0,2,2,2,2,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,0,0,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,0,1,1,1,1,0,0,0,0
|
||||
);
|
||||
|
||||
enable_sprite(1, 1, true, false, true);
|
||||
enable_sprite(2, 1, true, false, true);
|
||||
|
||||
|
||||
// sprite doubling with set_bit seems to be not working?
|
||||
// this is a hack TODO fix
|
||||
// memory(SPRITE_EXPAND_VERTICAL) = 0xFF;
|
||||
|
||||
// start timer
|
||||
memory(56590) = 1;
|
||||
|
||||
|
||||
const auto joy = [](const uint8_t d){
|
||||
struct State{
|
||||
State(const uint8_t portdata)
|
||||
@ -313,8 +304,8 @@ int main()
|
||||
|
||||
|
||||
std::pair<int8_t, int8_t> ball_vec{1,1};
|
||||
uint8_t player1 = 0;
|
||||
uint8_t player2 = 0;
|
||||
uint8_t player1 = '0';
|
||||
uint8_t player2 = '0';
|
||||
|
||||
const auto reset_ball = [&]{
|
||||
sprite_x(0) = 255/2;
|
||||
@ -329,39 +320,46 @@ int main()
|
||||
sprite_x(2) = 255;
|
||||
sprite_y(2) = 150;
|
||||
|
||||
uint8_t num_volleys = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (memory(56325) == 0) {
|
||||
// Move ball
|
||||
const auto ball_x = sprite_x(0) += std::get<0>(ball_vec);
|
||||
const auto ball_y = sprite_y(0) += std::get<1>(ball_vec);
|
||||
if (memory(53266) == 245
|
||||
&& !test_bit(memory(53265),7)) {
|
||||
|
||||
if (const auto collisions = sprite_collisions();
|
||||
collisions.sprite0 && (collisions.sprite1 || collisions.sprite2)) {
|
||||
// ball hit a paddle
|
||||
std::get<0>(ball_vec) *= -1;
|
||||
collisions.sprite0 && (collisions.sprite1 || collisions.sprite2))
|
||||
{
|
||||
std::get<0>(ball_vec) *= -1; //invert ball x velocity
|
||||
// "bounce" vall out of collision area
|
||||
sprite_x(0) += std::get<0>(ball_vec);
|
||||
++num_volleys;
|
||||
}
|
||||
|
||||
// if (num_volleys == 10) {
|
||||
// std::get<0>(ball_vec) += 1;
|
||||
// }
|
||||
|
||||
const auto ball_x = sprite_x(0) += std::get<0>(ball_vec);
|
||||
const auto ball_y = sprite_y(0) += std::get<1>(ball_vec);
|
||||
|
||||
// Update paddle positions
|
||||
if (const auto joy = joy_port1(); joy.up)
|
||||
{
|
||||
++sprite_y(1);
|
||||
sprite_y(1) += 3;
|
||||
} else if (joy.down) {
|
||||
--sprite_y(1);
|
||||
sprite_y(1) -= 3;
|
||||
}
|
||||
|
||||
if (const auto joy = joy_port2(); joy.up)
|
||||
{
|
||||
++sprite_y(2);
|
||||
sprite_y(2) += 3;
|
||||
} else if (joy.down) {
|
||||
--sprite_y(2);
|
||||
sprite_y(2) -= 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ball hit the top or bottom wall
|
||||
if (ball_y == 30 || ball_y == 240) {
|
||||
if (ball_y == 45 || ball_y == 235) {
|
||||
std::get<1>(ball_vec) *= -1;
|
||||
}
|
||||
|
||||
@ -369,14 +367,14 @@ int main()
|
||||
// ball hit left wall, player 2 scored
|
||||
++player2;
|
||||
reset_ball();
|
||||
} else if (ball_x == 254) {
|
||||
} else if (ball_x == 255) {
|
||||
// ball hit right wall, player 1 scored
|
||||
++player1;
|
||||
reset_ball();
|
||||
}
|
||||
|
||||
display_int(10, 3, player1);
|
||||
display_int(30, 3, player2);
|
||||
display_int(10, 12, player1);
|
||||
display_int(30, 12, player2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
src/main.cpp
23
src/main.cpp
@ -82,11 +82,14 @@ Operand get_register(const int reg_num, const int offset = 0) {
|
||||
case 0x07: return Operand(Operand::Type::literal, "$fe"); // unused
|
||||
case 0x08: return Operand(Operand::Type::literal, "$22"); // unused
|
||||
case 0x09: return Operand(Operand::Type::literal, "$23"); // unused
|
||||
case 0x0A: return Operand(Operand::Type::literal, "$39"); // Current BASIC line number
|
||||
case 0x0B: return Operand(Operand::Type::literal, "$3a"); // Current BASIC line number
|
||||
case 0x10: return get_register(0x00 + offset);
|
||||
case 0x11: return get_register(0x02 + offset);
|
||||
case 0x12: return get_register(0x04 + offset);
|
||||
case 0x13: return get_register(0x06 + offset);
|
||||
case 0x14: return get_register(0x08 + offset);
|
||||
case 0x15: return get_register(0x0A + offset);
|
||||
};
|
||||
throw std::runtime_error("Unhandled register number: " + std::to_string(reg_num));
|
||||
}
|
||||
@ -415,6 +418,8 @@ struct i386 : ASMLine
|
||||
return Operand(Operand::Type::reg, 0x07);
|
||||
} else if (o == "%sil") {
|
||||
return Operand(Operand::Type::reg, 0x08);
|
||||
} else if (o == "%dil") {
|
||||
return Operand(Operand::Type::reg, 0x0A);
|
||||
} else if (o == "%ax" || o == "%eax") {
|
||||
return Operand(Operand::Type::reg, 0x10);
|
||||
} else if (o == "%bx" || o == "%ebx") {
|
||||
@ -425,6 +430,8 @@ struct i386 : ASMLine
|
||||
return Operand(Operand::Type::reg, 0x13);
|
||||
} else if (o == "%si" || o == "%esi") {
|
||||
return Operand(Operand::Type::reg, 0x14);
|
||||
} else if (o == "%di" || o == "%edi") {
|
||||
return Operand(Operand::Type::reg, 0x15);
|
||||
} else {
|
||||
throw std::runtime_error("Unknown register operand: '" + o + "'");
|
||||
}
|
||||
@ -579,6 +586,11 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
||||
instructions.emplace_back(mos6502::OpCode::clc);
|
||||
instructions.emplace_back(mos6502::OpCode::adc, Operand(o1.type, fixup_8bit_literal(o1.value)));
|
||||
instructions.emplace_back(mos6502::OpCode::sta, get_register(o2.reg_num));
|
||||
} else if (o1.type == Operand::Type::literal && o2.type == Operand::Type::literal) {
|
||||
instructions.emplace_back(mos6502::OpCode::lda, Operand(o1.type, fixup_8bit_literal(o1.value)));
|
||||
instructions.emplace_back(mos6502::OpCode::clc);
|
||||
instructions.emplace_back(mos6502::OpCode::adc, o2);
|
||||
instructions.emplace_back(mos6502::OpCode::sta, o2);
|
||||
} else if (o1.type == Operand::Type::reg && o2.type == Operand::Type::literal) {
|
||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num));
|
||||
instructions.emplace_back(mos6502::OpCode::clc);
|
||||
@ -648,6 +660,17 @@ void translate_instruction(std::vector<mos6502> &instructions, const i386::OpCod
|
||||
throw std::runtime_error("Cannot translate subb instruction");
|
||||
}
|
||||
break;
|
||||
case i386::OpCode::pushl:
|
||||
if (o1.type == Operand::Type::reg) {
|
||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num));
|
||||
instructions.emplace_back(mos6502::OpCode::pha);
|
||||
instructions.emplace_back(mos6502::OpCode::lda, get_register(o1.reg_num, 1));
|
||||
instructions.emplace_back(mos6502::OpCode::pha);
|
||||
} else {
|
||||
throw std::runtime_error("Cannot translate sbb instruction");
|
||||
}
|
||||
break;
|
||||
|
||||
case i386::OpCode::sbbb:
|
||||
// DEST <- (DEST – (SRC + CF))
|
||||
// o2 <- (o2 - (o1 + cf))
|
||||
|
Loading…
Reference in New Issue
Block a user