the beginings of adding libchdr to pcsx2

in #programming2 months ago

following the post i made on github here https://github.com/PCSX2/pcsx2/issues/2584 I wish to explain how i came about with the code in better detail.

Header portion


#pragma once
#include "AsyncFileReader.h"
//include the core header of libchdr (found here https://github.com/rtissera/libchdr/blob/master/src/chd.h)
#include <chd.h>

class ChdrFileReader : public AsyncFileReader
{
    DeclareNoncopyableObject(ChdrFileReader);
public:
    virtual ~ChdrFileReader(void) { Close(); };

    static bool CanHandle(const wxString &fileName);
    bool Open(const wxString &fileName) override;

    int ReadSync(void *pBuffer, uint sector, uint count) override;

    void BeginRead(void *pBuffer, uint sector, uint count) override;
    int FinishRead(void) override;
    void CancelRead(void) override {};

    void Close(void) override;
    uint GetBlockSize() const;
    uint GetBlockCount(void) const override;
    ChdrFileReader(void);

private:
    chd_file *ChdrFile;
    const chd_header *ChdrHeader;
};

source file portion

#include "PrecompiledHeader.h"
#include "ChdrFileReader.h"

#include "CDVD/CompressedFileReaderUtils.h"

//check if file is a valid disk file based on its extension
bool ChdrFileReader::CanHandle(const wxString &fileName)
{
    if (!wxFileName::FileExists(fileName) || !fileName.Lower().EndsWith(L".chd")) {
        return false;
    }
    return true;
}
//attempt to open file and populate header struct with info
bool ChdrFileReader::Open(const wxString &fileName)
{
    Close();
    const chd_error error = chd_open(fileName, CHD_OPEN_READ, nullptr, &ChdrFile);
    if (error != CHDERR_NONE) {
        return false;
    }
    ChdrHeader = static_cast<chd_header *>(malloc(sizeof(chd_header)));
    const auto *const tempvar2 = chd_get_header(ChdrFile);
    memcpy(const_cast<chd_header *>( ChdrHeader), tempvar2, sizeof(chd_header));

    return true;
}
//this function is the main issue i had in the original post Im not sure how to handle the count
//see definition of chd_read here https://github.com/rtissera/libchdr/blob/master/src/chd.c#L1678
int ChdrFileReader::ReadSync(void *pBuffer, uint sector, uint count)
{
    return chd_read(ChdrFile, sector, pBuffer);
}
//async read
void ChdrFileReader::BeginRead(void *pBuffer, uint sector, uint count)
{
}
//end async read
int ChdrFileReader::FinishRead()
{
    return 0;
}
//close the file 
void ChdrFileReader::Close()
{
    chd_close(ChdrFile);
}
//return the size of each block of data in the chdr file
uint ChdrFileReader::GetBlockSize() const
{
    return ChdrHeader->hunkbytes;
}
//get number of blocks in chdr file
uint ChdrFileReader::GetBlockCount() const
{
    return ChdrHeader->hunkcount;
}
//construct class
ChdrFileReader::ChdrFileReader(void):
    ChdrFile(),ChdrHeader(0)
{

};

As shown in the code comments I am not sure how to handle count.
The reason for this is I dont have i guess the time to fully study the new format and see if its blocks are laid out logicly.
My first way I thought of implmenting the function fully was a loop where i increment the sector count until it reaches the value sector + count. But I believe this is a foolish idea because i could end up reading garbage past the end of the file or even reading the wrong locations.

Sort:  

I hope you will crack it soon. Only thing required is little effort and hang arounund with problem. We are looking for a people like you in our platform. Hopefully you will find brilliant mind there
Your post has been curated with @gitplait community account because this is the kind of publications we like to see in our community.

Join our Community on Hive and Chat with us on Discord.

This is true persistence is key. And i plan to get around to trying to finish it via a few methods. the loop looks appealing as a logic test.