the beginings of adding libchdr to pcsx2

avatar

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.



0
0
0.000
2 comments
avatar

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.

0
0
0.000
avatar

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.

0
0
0.000