Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions core/include/retroforge/identification/ConsoleIdentifier.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include "retroforge/identification/IConsoleDetector.hpp"
#include "retroforge/io/BinaryFileReader.hpp"

#include <memory>

namespace retroforge::identification {

class ConsoleIdentifier {
public:
void register_detector(std::unique_ptr<IConsoleDetector> detector);
Console identify(retroforge::io::BinaryFileReader &leitor) const;

private:
static constexpr size_t TAMANHO_CABECALHO = 32;
std::vector<std::unique_ptr<IConsoleDetector>> detectores_;
};

} // namespace retroforge::identification
19 changes: 19 additions & 0 deletions core/include/retroforge/identification/IConsoleDetector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "retroforge/models/Console.hpp"

#include <cstdint>
#include <vector>

namespace retroforge::identification {

using retroforge::models::Console;

class IConsoleDetector {
public:
virtual ~IConsoleDetector() = default;
virtual bool matches(const std::vector<uint8_t> &cabecalho) const = 0;
virtual Console console() const = 0;
};

} // namespace retroforge::identification
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "retroforge/identification/IConsoleDetector.hpp"

namespace retroforge::identification::detectors {

class GameCubeDetector : public IConsoleDetector {
public:
bool matches(const std::vector<uint8_t> &cabecalho) const override;
Console console() const override { return Console::GameCube; }
};

} // namespace retroforge::identification::detectors
13 changes: 13 additions & 0 deletions core/include/retroforge/identification/detectors/Ps1Detector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "retroforge/identification/IConsoleDetector.hpp"

namespace retroforge::identification::detectors {

class Ps1Detector : public IConsoleDetector {
public:
bool matches(const std::vector<uint8_t> &cabecalho) const override;
Console console() const override { return Console::PS1; }
};

} // namespace retroforge::identification::detectors
10 changes: 5 additions & 5 deletions core/include/retroforge/io/BinaryFileReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
#include <string>
#include <vector>

namespace retroforge ::io {
namespace retroforge::io {

class BinaryFileReader {
public:
explicit BinaryFileReader(const std ::string &caminho);
explicit BinaryFileReader(const std::string &caminho);

std::vector<uint8_t> read_at(std ::streamoff offset, size_t quantidade);
std::vector<uint8_t> read_at(std::streamoff offset, size_t quantidade);

std::vector<uint8_t> read_next_chunk(size_t tamanho_maximo);

bool eof() const;
std ::uintmax_t tamanho_total() const { return tamanho_total_; }
std::uintmax_t tamanho_total() const { return tamanho_total_; }

private:
std::ifstream arquivo_;
std::uintmax_t tamanho_total_;
};
} // namespace retroforge::io
} // namespace retroforge::io
6 changes: 6 additions & 0 deletions core/include/retroforge/models/Console.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

namespace retroforge::models {

enum class Console { PS1, PS2, PSP, GameCube, Dreamcast, MegaDrive, SNES, Desconhecido };
} // namespace retroforge::models
2 changes: 1 addition & 1 deletion core/include/retroforge/process/ExternalProcessHandle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ class ExternalProcessHandle {

std::unique_ptr<FILE, FechadorDeProcesso> handle_;
};
} // namespace retroforge::process
} // namespace retroforge::process
21 changes: 21 additions & 0 deletions core/src/identification/ConsoleIdentifier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "retroforge/identification/ConsoleIdentifier.hpp"

namespace retroforge::identification {

void ConsoleIdentifier::register_detector(std::unique_ptr<IConsoleDetector> detector) {
detectores_.push_back(std::move(detector));
}

Console ConsoleIdentifier::identify(retroforge::io::BinaryFileReader &leitor) const {
auto cabecalho = leitor.read_at(0, TAMANHO_CABECALHO);

for (const auto &detector : detectores_) {
if (detector->matches(cabecalho)) {
return detector->console();
}
}

return Console::Desconhecido;
}

} // namespace retroforge::identification
21 changes: 21 additions & 0 deletions core/src/identification/detectors/GameCubeDetector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "retroforge/identification/detectors/GameCubeDetector.hpp"

namespace retroforge::identification::detectors {

bool GameCubeDetector::matches(const std::vector<uint8_t> &cabecalho) const {
constexpr size_t OFFSET_ASSINATURA = 0x1C;
constexpr uint32_t MAGIC_GAMECUBE = 0xC2339F3D;

if (cabecalho.size() < OFFSET_ASSINATURA + 4) {
return false;
}

uint32_t valor = (static_cast<uint32_t>(cabecalho[OFFSET_ASSINATURA]) << 24) |
(static_cast<uint32_t>(cabecalho[OFFSET_ASSINATURA + 1]) << 16) |
(static_cast<uint32_t>(cabecalho[OFFSET_ASSINATURA + 2]) << 8) |
(static_cast<uint32_t>(cabecalho[OFFSET_ASSINATURA + 3]));

return valor == MAGIC_GAMECUBE;
}

} // namespace retroforge::identification::detectors
22 changes: 22 additions & 0 deletions core/src/identification/detectors/Ps1Detector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "retroforge/identification/detectors/Ps1Detector.hpp"
#include <algorithm>
#include <string>

namespace retroforge::identification::detectors {

bool Ps1Detector::matches(const std::vector<uint8_t> &cabecalho) const {
if (cabecalho.empty()) {
return false;
}

std::string conteudo(cabecalho.begin(), cabecalho.end());

std::transform(conteudo.begin(), conteudo.end(), conteudo.begin(), ::toupper);

bool temFile = conteudo.find("FILE") != std::string::npos;
bool temMode2 = conteudo.find("MODE2/2352") != std::string::npos;

return temFile && temMode2;
}

} // namespace retroforge::identification::detectors
2 changes: 1 addition & 1 deletion core/src/io/BinaryFileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ std::vector<uint8_t> BinaryFileReader::read_next_chunk(size_t tamanho_maximo) {

bool BinaryFileReader::eof() const { return arquivo_.eof(); }

} // namespace retroforge::io
} // namespace retroforge::io
2 changes: 1 addition & 1 deletion core/src/process/ExternalProcessHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ bool ExternalProcessHandle::read_line(std::string &linha_destino) {
return true;
}

} // namespace retroforge::process
} // namespace retroforge::process
Loading