Skip to content

Commit

Permalink
modernize vectgif
Browse files Browse the repository at this point in the history
  • Loading branch information
beardypig committed Oct 19, 2024
1 parent 6e67312 commit fa3c06e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 146 deletions.
3 changes: 2 additions & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"dependencies": [
"catch2",
"trompeloeil"
"trompeloeil",
"cxxopts"
]
}
5 changes: 4 additions & 1 deletion vectgif/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
find_package(cxxopts CONFIG REQUIRED)

add_executable(vectgif
main.cpp
gif.h
Expand All @@ -11,4 +13,5 @@ else()
set(LIBRETRO_SRC vectrexia_libretro)
endif()

target_link_libraries(vectgif ${LIBRETRO_SRC})
target_link_libraries(vectgif PRIVATE ${LIBRETRO_SRC})
target_link_libraries(vectgif PRIVATE cxxopts::cxxopts)
77 changes: 0 additions & 77 deletions vectgif/getopt.h

This file was deleted.

144 changes: 77 additions & 67 deletions vectgif/main.cpp
Original file line number Diff line number Diff line change
@@ -1,92 +1,102 @@
#include <cstdlib>
#include <memory>
#include <array>
#include <vector>
#include <iostream>
#include <fstream>
#include <string_view>
#include <format>
#include <optional>
#include <vectrexia.h>
#include "gif.h"
#include "getopt.h"
#include <cxxopts.hpp>

constexpr size_t ROM_SIZE = 65536;
constexpr size_t MAX_FILENAME_SIZE = 2000;

std::unique_ptr<Vectrex> vectrex = std::make_unique<Vectrex>();
std::array<uint8_t , FRAME_WIDTH * FRAME_HEIGHT * 4> gif_buffer{};
std::array<uint8_t, FRAME_WIDTH * FRAME_HEIGHT * 4> gif_buffer{};

int main(int argc, char *argv[])
{
int c = 0;
int ch = 0;
int r = 0;
long skipframes = 0;
long outframes = 1000;
FILE *romfile;
char giffilename[2000]{};
uint8_t rombuffer[65536]{};
GifWriter gw = {};

opterr = 0;
while ((c = getopt(argc, argv, "s:n:")) != -1) {
switch (c) {
case 's':skipframes = strtol(optarg, nullptr, 10);
break;
case 'n':outframes = strtol(optarg, nullptr, 10);
break;
default:abort();
long skipframes = 0;
long outframes = 1000;
std::array<uint8_t, ROM_SIZE> rombuffer{};
GifWriter gw{};

// Parse command line arguments using cxxopts
cxxopts::Options options("vectgif", "Generate a GIF from a Vectrex ROM");
options.add_options()
("s,skipframes", "Number of frames to skip", cxxopts::value<long>()->default_value("0"))
("n,outframes", "Number of output frames", cxxopts::value<long>()->default_value("1000"))
("rom", "ROM file", cxxopts::value<std::string>())
("gif", "GIF output file", cxxopts::value<std::string>()->default_value(""));

auto result = options.parse(argc, argv);

skipframes = result["skipframes"].as<long>();
outframes = result["outframes"].as<long>();

if (!result.count("rom")) {
std::cerr << "vectgif: usage: vectgif <rom> [gif]\n";
return 1;
}
}

auto nargs = (argc - optind);
if (nargs < 1 || nargs > 2) {
fprintf(stderr, "vectgif: usage: vectgif <rom> [gif]\n");
return 1;
}

// load the ROM file
printf("[ROM]: loading ROM \"%s\"\n", argv[optind]);
romfile = fopen(argv[optind], "rb");
std::string rom_filename = result["rom"].as<std::string>();
std::string giffilename;
if (result.count("gif") && !result["gif"].as<std::string>().empty()) {
giffilename = result["gif"].as<std::string>();
} else {
giffilename = std::format("{}.gif", rom_filename);
}

while( ( ch = fgetc(romfile) ) != EOF && r < 65536) {
rombuffer[r++] = static_cast<uint8_t>(ch);
}
fclose(romfile);
// Load the ROM file
std::ifstream romfile(rom_filename, std::ios::binary);
if (!romfile) {
std::cerr << "[ROM]: Failed to open ROM file " << rom_filename << "\n";
return 1;
}

printf("[ROM]: size = %d\n", r);
std::cout << std::format("[ROM]: loading ROM \"{}\"\n", rom_filename);
romfile.read(reinterpret_cast<char*>(rombuffer.data()), ROM_SIZE);
auto r = static_cast<size_t>(romfile.gcount());
romfile.close();

if (!vectrex->LoadCartridge(rombuffer, static_cast<size_t>(r))) {
printf("Failed to load the ROM file\n");
return 1;
}
std::cout << std::format("[ROM]: size = {}\n", r);

if (nargs == 1) {
snprintf(giffilename, sizeof(giffilename), "%s.gif", argv[optind]);
}
else {
snprintf(giffilename, sizeof(giffilename), "%s", argv[optind + 1]);
}
if (!vectrex->LoadCartridge(rombuffer.data(), r)) {
std::cerr << "Failed to load the ROM file\n";
return 1;
}

GifBegin(&gw, giffilename, FRAME_WIDTH, FRAME_HEIGHT, 2, 8, false);
GifBegin(&gw, giffilename.c_str(), FRAME_WIDTH, FRAME_HEIGHT, 2, 8, false);

vectrex->Reset();
vectrex->Reset();

vectrex->SetPlayerOne(0x80, 0x80, 1, 1, 1, 1);
vectrex->SetPlayerTwo(0x80, 0x80, 1, 1, 1, 1);
vectrex->SetPlayerOne(0x80, 0x80, 1, 1, 1, 1);
vectrex->SetPlayerTwo(0x80, 0x80, 1, 1, 1, 1);

for (int frame = 0; frame < outframes; frame++) {
for (int s = 0; s < skipframes+1; s++) {
vectrex->Run(30000);
}
for (int frame = 0; frame < outframes; frame++) {
for (int s = 0; s < skipframes + 1; s++) {
vectrex->Run(30000);
}

auto framebuffer = vectrex->getFramebuffer();
auto framebuffer = vectrex->getFramebuffer();

auto gb = gif_buffer.begin();
for (auto &fb : *framebuffer) {
*++gb = static_cast<uint8_t>(fb.value * 0xffu);
*++gb = static_cast<uint8_t>(fb.value * 0xffu);
*++gb = static_cast<uint8_t>(fb.value * 0xffu);
*++gb = static_cast<uint8_t>(fb.value * 0xffu);
}
GifWriteFrame(&gw, gif_buffer.data(), FRAME_WIDTH, FRAME_HEIGHT, 2);
if (frame % 100 == 0) {
printf("[VECTREX] frame = %d\n", frame);
auto gb = gif_buffer.begin();
for (const auto &fb : *framebuffer) {
*gb++ = static_cast<uint8_t>(fb.value * 0xffu);
*gb++ = static_cast<uint8_t>(fb.value * 0xffu);
*gb++ = static_cast<uint8_t>(fb.value * 0xffu);
*gb++ = static_cast<uint8_t>(fb.value * 0xffu);
}
GifWriteFrame(&gw, gif_buffer.data(), FRAME_WIDTH, FRAME_HEIGHT, 2);
if (frame % 100 == 0) {
std::cout << std::format("[VECTREX] frame = {}\n", frame);
}
}
}

GifEnd(&gw);
GifEnd(&gw);

return 0;
return 0;
}

0 comments on commit fa3c06e

Please sign in to comment.