mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-16 11:09:16 +01:00
75d032161f
Fixes https://bugs.dolphin-emu.org/issues/10654. To quote the documenation file included with the program tgctogcm: "TGC's are miniaturized .gcm images with a 32kB header. The embedded gcm contains some bogus data, namely: -FST Location (0x424 in gcm) -DOL Location (0x420 in gcm) -FST File offsets (all files are offset/spoofed by a certain amount)" Dolphin has been handling the values at 0x420 and 0x424 by simply overwriting them with a working value (just like tgctogcm does), but it has used a different approach for the file offsets in the FST. Instead of changing the offsets that are stored in the FST, Dolphin changed where the files actually are placed on the virtual disc. My hope was that this would make the loading times more accurate to how they are when running a TGC file as part of a larger disc. However, there are TGC files where we would need to move files backwards on the disc in order to do this (this is what issue 10654 is about), so the approach we have been using is flawed. This change makes Dolphin overwrite offsets in the FST instead, like tgctogcm does. Other than making Dolphin handle the affected TGC files correctly, this change also makes it so that unnecessary padding data isn't written if you use Dolphin to convert a TGC file to an ISO file. This feature is not actually implemented in Dolphin as of now, but I'm planning to add it in the near future as part of a larger feature.
69 lines
1.4 KiB
C++
69 lines
1.4 KiB
C++
// Copyright 2016 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/File.h"
|
|
#include "DiscIO/Blob.h"
|
|
|
|
namespace DiscIO
|
|
{
|
|
static constexpr u32 TGC_MAGIC = 0xA2380FAE;
|
|
|
|
struct TGCHeader
|
|
{
|
|
u32 magic;
|
|
u32 unknown_1;
|
|
u32 tgc_header_size;
|
|
u32 disc_header_area_size;
|
|
|
|
u32 fst_real_offset;
|
|
u32 fst_size;
|
|
u32 fst_max_size;
|
|
u32 dol_real_offset;
|
|
|
|
u32 dol_size;
|
|
u32 file_area_real_offset;
|
|
u32 unknown_2;
|
|
u32 unknown_3;
|
|
|
|
u32 unknown_4;
|
|
u32 file_area_virtual_offset;
|
|
};
|
|
|
|
class TGCFileReader final : public BlobReader
|
|
{
|
|
public:
|
|
static std::unique_ptr<TGCFileReader> Create(File::IOFile file);
|
|
|
|
BlobType GetBlobType() const override { return BlobType::TGC; }
|
|
|
|
u64 GetRawSize() const override { return m_size; }
|
|
u64 GetDataSize() const override;
|
|
bool IsDataSizeAccurate() const override { return true; }
|
|
|
|
u64 GetBlockSize() const override { return 0; }
|
|
bool HasFastRandomAccessInBlock() const override { return true; }
|
|
|
|
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
|
|
|
|
private:
|
|
TGCFileReader(File::IOFile file);
|
|
|
|
File::IOFile m_file;
|
|
u64 m_size;
|
|
|
|
std::vector<u8> m_fst;
|
|
|
|
// Stored as big endian in memory, regardless of the host endianness
|
|
TGCHeader m_header = {};
|
|
};
|
|
|
|
} // namespace DiscIO
|