From c8c1792c3f83889e3f8da570e6c949a5430b5d2c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 17 Aug 2017 22:20:02 -0400 Subject: [PATCH] Made a first attempt at HFE support. --- Storage/Disk/Formats/HFE.cpp | 36 ++++++++++++++++++++++++++++++++++-- Storage/Disk/Formats/HFE.hpp | 1 + 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Storage/Disk/Formats/HFE.cpp b/Storage/Disk/Formats/HFE.cpp index 00c837669..38c624fb8 100644 --- a/Storage/Disk/Formats/HFE.cpp +++ b/Storage/Disk/Formats/HFE.cpp @@ -8,11 +8,20 @@ #include "HFE.hpp" +#include "../PCMTrack.hpp" + using namespace Storage::Disk; HFE::HFE(const char *file_name) : Storage::FileHolder(file_name) { - throw ErrorNotHFE; + if(!check_signature("HXCPICFE", 8)) throw ErrorNotHFE; + + if(fgetc(file_)) throw ErrorNotHFE; + track_count_ = (unsigned int)fgetc(file_); + head_count_ = (unsigned int)fgetc(file_); + + fseek(file_, 7, SEEK_CUR); + track_list_offset_ = (long)fgetc16le() << 9; } HFE::~HFE() { @@ -31,5 +40,28 @@ bool HFE::get_is_read_only() { } std::shared_ptr HFE::get_uncached_track_at_position(unsigned int head, unsigned int position) { - return nullptr; + // Get track position and length from the lookup table; data is then always interleaved + // based on an assumption of two heads. + fseek(file_, track_list_offset_ + position * 4, SEEK_SET); + + long track_offset = (long)fgetc16le() << 9; + uint16_t track_length = fgetc16le(); + + fseek(file_, track_offset, SEEK_SET); + if(head) fseek(file_, 256, SEEK_CUR); + + PCMSegment segment; + uint16_t side_length = track_length / 2; + segment.data.resize(side_length); + + uint16_t c = 0; + while(c < side_length) { + uint16_t length = (uint16_t)std::min(256, side_length - c); + fread(&segment.data[c], 1, length, file_); + c += length; + fseek(file_, 256, SEEK_CUR); + } + + std::shared_ptr track(new PCMTrack(segment)); + return track; } diff --git a/Storage/Disk/Formats/HFE.hpp b/Storage/Disk/Formats/HFE.hpp index 6dc2d4888..504140d9b 100644 --- a/Storage/Disk/Formats/HFE.hpp +++ b/Storage/Disk/Formats/HFE.hpp @@ -43,6 +43,7 @@ class HFE: public Disk, public Storage::FileHolder { unsigned int head_count_; unsigned int track_count_; + long track_list_offset_; }; }