This repository has been archived on 2024-09-18. You can view files and clone it, but cannot push or open issues or pull requests.
sdp-scheduler/emulator.cpp

253 lines
7.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by Владислав Остапов on 27.10.2022.
//
#include <cstring>
#include <iostream>
#include <libc.h>
#include "emulator.h"
#include "robot.h"
struct barrel barrels[BARRELS_COUNT];
struct robot_regs robot1;
struct robot_regs robot2;
char _scheduler_software_timer = 0;
char _scheduler_one_robot_mode = 1;
// кнопка загрузки в зоне 0, означает что барабан надо изъять из этой загрузки (а перед этим создать)
char button_load = 0;
char button_unload = 0;
char button_unload_end = 0;
char button_unload_remove = 0;
static const int ROWS = 10;
static const int COLS = 23 * 5 + 1;
static char buffer[ROWS][COLS];
static int current_tic = 0;
robot_code robot1_code{0, -1};
robot_code robot2_code{0, -1};
short robot1_lock_zone = 0;
short robot2_lock_zone = 0;
static int sock_fd;
static void send_str(const char* str) {
write(sock_fd, str, strlen(str));
}
static void image_init() {
// заполнение всего поля пробелами
memset(buffer, ' ', sizeof(buffer));
}
static void image_insert_sprite(int row, int col, const char* str, bool alpha = true) {
for (; row < ROWS; row++) {
for (int curr_col = col;; curr_col++) {
char src = *(str++);
// конец строки, заканчиваем рисовать
if (src == '\0') {
return;
}
// перевод строки, перевод на новую строку в этом спрайте
if (src == '\n') {
break;
}
// чтобы не рисовать мусор
if (src < ' ') {
src = ' ';
}
if (curr_col < COLS) {
// рисуем, остальные фрагменты будут отброшены
char frag = buffer[row][curr_col];
if (alpha) {
// этот режим позволяет пропускать изменение символа, если исходный символ пробел
if (src != ' ') {
frag = src;
}
} else {
frag = src;
}
buffer[row][curr_col] = frag;
}
}
}
}
static void image_draw_borders() {
// рамки ванн
// for (int i = 0; i < COLS; i += 5) {
// image_insert_sprite(5, i, "|\n|\n|");
// }
// рисование линий
for (int i = 0; i < ROWS - 1; i++) {
buffer[i][0] = '|';
buffer[i][COLS - 1] = '|';
}
memset(buffer[1], '=', sizeof(buffer[0]));
// рамки ванн
char tmp[24];
for (int i = 0, zone = 0; i < COLS; i += 5, zone++) {
sprintf(tmp, "|\n|\n+----+\n|\n|Z-%02d|", zone);
image_insert_sprite(5, i, tmp, false);
}
image_insert_sprite(8, 1, "LOAD LOAD DEFA W-1A W-1B ETCH ETCH W-2A W-2B "
" GAL GAL GAL GAL GAL GAL GAL GAL "
"W-3A W-3B PASS W-4A W-4B UNLD", true);
// счетчик тиков
sprintf(tmp, "tic: %d", current_tic);
image_insert_sprite(0, (int)(COLS - strlen(tmp) - 2), tmp, false);
}
static void showAll() {
// 10 строк, 10*(\sb%1d\s) = 40
// барабан хочу показывать так
//
// # Bx | Bx | Bx
// #time|time|time
//
image_init();
image_draw_borders();
char tmp[16];
// рисование бочек
for (int i = 0; i < BARRELS_COUNT; i++) {
const auto& b = barrels[i];
if (b.flags.is_exist) {
if (b.flags.is_up) {
sprintf(tmp, " B%d", i);
image_insert_sprite(4, (b.zone * 5) + 1, tmp);
} else {
sprintf(tmp, " B%d\n%04d", i, b.software_timer);
image_insert_sprite(5, (b.zone * 5) + 1, tmp);
}
}
}
// рисуем роботов
sprintf(tmp, "R1");
// image_insert_sprite(2 + (robot1.mz.is_up ? 0 : 2), (robot1.curr_zone * 5) + 2, tmp);
image_insert_sprite(2 + (robot1.mz.is_up ? 0 : 2),
(robot1.dx.current_zone * 5) + 2 + (robot1_offset_pos * 2),
tmp);
// sprintf(tmp, "R2");
// image_insert_sprite(3 + (robot2.mz.is_up ? 0 : 2), (robot2.curr_zone * 5) + 2, tmp);
for (const auto & r : buffer) {
write(sock_fd, r, COLS);
send_str("\n");
}
}
static void open_socket() {
sockaddr_in serv_addr{};
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
printf("\n Socket creation error \n");
exit(-1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(40000);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
exit(-1);
}
if (connect(sock_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
printf("Connection Failed \n");
exit(-1);
}
}
extern "C" struct barrel makeBarrel(short flags, short zone, short timer);
int main() {
open_socket();
// for (auto & b : barrels) {
// b.barrel_flags.is_exist = 1;
// b.software_timer = (short)(random() % 50);
// b.zone = (short) abs(random() % 20);
// }
barrels[5] = makeBarrel(1, 21, 3);
current_tic = 0;
const char* message = nullptr;
while (true) {
_scheduler_software_timer = 1;
robot_main();
scheduler_main();
send_str("\033c");
showAll();
if (message) {
std::cout << message << std::endl;
send_str(message);
send_str("\n");
message = nullptr;
}
send_str("cmd >> ");
std::string in;
while (true) {
char tmp[2] = {0, 0};
ssize_t res = read(sock_fd, tmp, 1);
if (res < 0) {
exit(-1);
}
if (res == 1) {
if (tmp[0] == '\n') {
break;
}
in.append(tmp);
}
}
if (in == "q") {
break;
}
if (in.empty()) {
// просто продолжаем циклы
message = "Continue...";
} else {
if (in == "u") {
button_unload = 1;
message = "Нажата кнопка выгрузки";
} else if (in == "1") {
button_unload_end = 1;
message = "Нажата кнопка загрузки 1";
} else if (in == "2") {
button_load = 1;
message = "Нажата кнопка загрузки 2";
} else {
message = "Неизвестная команда. q - выход, u - выгрузка, 1 - загрузка 1, 2 - загрузка 2";
}
}
current_tic++;
}
close(sock_fd);
return 0;
}