Move DVDInterface's pure (stateless) math code to a new file
This commit is contained in:
parent
f106ba70d4
commit
020618a427
|
@ -90,6 +90,7 @@ set(SRCS
|
|||
HW/DSPLLE/DSPLLE.cpp
|
||||
HW/DSPLLE/DSPLLETools.cpp
|
||||
HW/DVD/DVDInterface.cpp
|
||||
HW/DVD/DVDMath.cpp
|
||||
HW/DVD/DVDThread.cpp
|
||||
HW/DVD/FileMonitor.cpp
|
||||
HW/EXI/EXI_Channel.cpp
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
<ClCompile Include="HW\DSPLLE\DSPLLETools.cpp" />
|
||||
<ClCompile Include="HW\DSPLLE\DSPSymbols.cpp" />
|
||||
<ClCompile Include="HW\DVD\DVDInterface.cpp" />
|
||||
<ClCompile Include="HW\DVD\DVDMath.cpp" />
|
||||
<ClCompile Include="HW\DVD\DVDThread.cpp" />
|
||||
<ClCompile Include="HW\DVD\FileMonitor.cpp" />
|
||||
<ClCompile Include="HW\EXI\BBA-TAP\TAP_Win32.cpp" />
|
||||
|
@ -369,6 +370,7 @@
|
|||
<ClInclude Include="HW\DSPLLE\DSPLLETools.h" />
|
||||
<ClInclude Include="HW\DSPLLE\DSPSymbols.h" />
|
||||
<ClInclude Include="HW\DVD\DVDInterface.h" />
|
||||
<ClInclude Include="HW\DVD\DVDMath.h" />
|
||||
<ClInclude Include="HW\DVD\DVDThread.h" />
|
||||
<ClInclude Include="HW\DVD\FileMonitor.h" />
|
||||
<ClInclude Include="HW\EXI\BBA-TAP\TAP_Win32.h" />
|
||||
|
|
|
@ -347,6 +347,9 @@
|
|||
<ClCompile Include="HW\DVD\DVDInterface.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\DVD\DVDMath.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\DVD\DVDThread.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1003,6 +1006,9 @@
|
|||
<ClInclude Include="HW\DVD\DVDInterface.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\DVD\DVDMath.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\DVD\DVDThread.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\DI - Drive Interface</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
@ -13,12 +12,14 @@
|
|||
#include "Common/Align.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/HW/AudioInterface.h"
|
||||
#include "Core/HW/DVD/DVDInterface.h"
|
||||
#include "Core/HW/DVD/DVDMath.h"
|
||||
#include "Core/HW/DVD/DVDThread.h"
|
||||
#include "Core/HW/DVD/FileMonitor.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
|
@ -52,31 +53,6 @@ constexpr u64 DVD_ECC_BLOCK_SIZE = 16 * DVD_SECTOR_SIZE;
|
|||
// is already buffered. Measured in bytes per second.
|
||||
constexpr u64 BUFFER_TRANSFER_RATE = 32 * 1024 * 1024;
|
||||
|
||||
// The size of the first Wii disc layer in bytes (2294912 sectors per layer)
|
||||
constexpr u64 WII_DISC_LAYER_SIZE = 2294912 * DVD_SECTOR_SIZE;
|
||||
|
||||
// 24 mm
|
||||
constexpr double DVD_INNER_RADIUS = 0.024;
|
||||
// 58 mm
|
||||
constexpr double WII_DVD_OUTER_RADIUS = 0.058;
|
||||
// 38 mm
|
||||
constexpr double GC_DVD_OUTER_RADIUS = 0.038;
|
||||
|
||||
// Approximate read speeds at the inner and outer locations of Wii and GC
|
||||
// discs. These speeds are approximations of speeds measured on real Wiis.
|
||||
constexpr double GC_DISC_INNER_READ_SPEED = 1024 * 1024 * 2.1; // bytes/s
|
||||
constexpr double GC_DISC_OUTER_READ_SPEED = 1024 * 1024 * 3.325; // bytes/s
|
||||
constexpr double WII_DISC_INNER_READ_SPEED = 1024 * 1024 * 3.48; // bytes/s
|
||||
constexpr double WII_DISC_OUTER_READ_SPEED = 1024 * 1024 * 8.41; // bytes/s
|
||||
|
||||
// Experimentally measured seek constants. The time to seek appears to be
|
||||
// linear, but short seeks appear to be lower velocity.
|
||||
constexpr double SHORT_SEEK_MAX_DISTANCE = 0.001; // 1 mm
|
||||
constexpr double SHORT_SEEK_CONSTANT = 0.045; // seconds
|
||||
constexpr double SHORT_SEEK_VELOCITY_INVERSE = 50; // inverse: s/m
|
||||
constexpr double LONG_SEEK_CONSTANT = 0.085; // seconds
|
||||
constexpr double LONG_SEEK_VELOCITY_INVERSE = 4.5; // inverse: s/m
|
||||
|
||||
namespace DVDInterface
|
||||
{
|
||||
// internal hardware addresses
|
||||
|
@ -276,9 +252,6 @@ bool ExecuteReadCommand(u64 DVD_offset, u32 output_address, u32 DVD_length, u32
|
|||
u64 PackFinishExecutingCommandUserdata(ReplyType reply_type, DIInterruptType interrupt_type);
|
||||
|
||||
void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, ReplyType reply_type);
|
||||
double CalculatePhysicalDiscPosition(u64 offset);
|
||||
u64 CalculateSeekTime(u64 offset_from, u64 offset_to);
|
||||
u64 CalculateRawDiscReadTime(u64 offset, u64 length);
|
||||
|
||||
void DoState(PointerWrap& p)
|
||||
{
|
||||
|
@ -1191,6 +1164,8 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||
// places, the video before the save-file select screen lags.
|
||||
|
||||
const u64 current_time = CoreTiming::GetTicks();
|
||||
const u32 ticks_per_second = SystemTimers::GetTicksPerSecond();
|
||||
const bool wii_disc = s_inserted_volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
|
||||
|
||||
// Where the DVD read head is (usually parked at the end of the buffer,
|
||||
// unless we've interrupted it mid-buffer-read).
|
||||
|
@ -1300,14 +1275,18 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||
if (dvd_offset != head_position)
|
||||
{
|
||||
// Unbuffered seek+read
|
||||
ticks_until_completion += CalculateSeekTime(head_position, dvd_offset);
|
||||
ticks_until_completion += static_cast<u64>(
|
||||
ticks_per_second * DVDMath::CalculateSeekTime(head_position, dvd_offset));
|
||||
|
||||
DEBUG_LOG(DVDINTERFACE, "Seek+read 0x%" PRIx32 " bytes @ 0x%" PRIx64 " ticks=%" PRId64,
|
||||
chunk_length, offset, ticks_until_completion);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unbuffered read
|
||||
ticks_until_completion += CalculateRawDiscReadTime(dvd_offset, DVD_ECC_BLOCK_SIZE);
|
||||
ticks_until_completion +=
|
||||
static_cast<u64>(ticks_per_second * DVDMath::CalculateRawDiscReadTime(
|
||||
dvd_offset, DVD_ECC_BLOCK_SIZE, wii_disc));
|
||||
}
|
||||
|
||||
unbuffered_blocks++;
|
||||
|
@ -1350,8 +1329,10 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||
s_read_buffer_start_time = current_time + ticks_until_completion;
|
||||
s_read_buffer_end_time =
|
||||
s_read_buffer_start_time +
|
||||
CalculateRawDiscReadTime(s_read_buffer_start_offset,
|
||||
s_read_buffer_end_offset - s_read_buffer_start_offset);
|
||||
static_cast<u64>(ticks_per_second *
|
||||
DVDMath::CalculateRawDiscReadTime(
|
||||
s_read_buffer_start_offset,
|
||||
s_read_buffer_end_offset - s_read_buffer_start_offset, wii_disc));
|
||||
}
|
||||
|
||||
DEBUG_LOG(DVDINTERFACE, "Schedule reads: ECC blocks unbuffered=%d, buffered=%d, "
|
||||
|
@ -1360,124 +1341,4 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||
ticks_until_completion * 1000000 / SystemTimers::GetTicksPerSecond());
|
||||
}
|
||||
|
||||
// We can approximate the relationship between a byte offset on disc and its
|
||||
// radial distance from the center by using an approximation for the length of
|
||||
// a rolled material, which is the area of the material divided by the pitch
|
||||
// (ie: assume that you can squish and deform the area of the disc into a
|
||||
// rectangle as thick as the track pitch).
|
||||
//
|
||||
// In practice this yields good-enough numbers as a more exact formula
|
||||
// involving the integral over a polar equation (too complex to describe here)
|
||||
// or the approximation of a DVD as a set of concentric circles (which is a
|
||||
// better approximation, but makes futher derivations more complicated than
|
||||
// they need to be).
|
||||
//
|
||||
// From the area approximation, we end up with this formula:
|
||||
//
|
||||
// L = pi*(r.outer^2-r.inner^2)/pitch
|
||||
//
|
||||
// Where:
|
||||
// L = the data track's physical length
|
||||
// r.{inner,outer} = the inner/outer radii (24 mm and 58 mm)
|
||||
// pitch = the track pitch (.74 um)
|
||||
//
|
||||
// We can then use this equation to compute the radius for a given sector in
|
||||
// the disc by mapping it along the length to a linear position and inverting
|
||||
// the equation and solving for r.outer (using the DVD's r.inner and pitch)
|
||||
// given that linear position:
|
||||
//
|
||||
// r.outer = sqrt(L * pitch / pi + r.inner^2)
|
||||
//
|
||||
// Where:
|
||||
// L = the offset's linear position, as offset/density
|
||||
// r.outer = the radius for the offset
|
||||
// r.inner and pitch are the same as before.
|
||||
//
|
||||
// The data density of the disc is just the number of bytes addressable on a
|
||||
// DVD, divided by the spiral length holding that data. offset/density yields
|
||||
// the linear position for a given offset.
|
||||
//
|
||||
// When we put it all together and simplify, we can compute the radius for a
|
||||
// given byte offset as a drastically simplified:
|
||||
//
|
||||
// r = sqrt(offset/total_bytes*(r.outer^2-r.inner^2) + r.inner^2)
|
||||
double CalculatePhysicalDiscPosition(u64 offset)
|
||||
{
|
||||
// Just in case someone has an overly large disc image
|
||||
// that can't exist in reality...
|
||||
offset %= WII_DISC_LAYER_SIZE * 2;
|
||||
|
||||
// Assumption: the layout on the second disc layer is opposite of the first,
|
||||
// ie layer 2 starts where layer 1 ends and goes backwards.
|
||||
if (offset > WII_DISC_LAYER_SIZE)
|
||||
offset = WII_DISC_LAYER_SIZE * 2 - offset;
|
||||
|
||||
// The track pitch here is 0.74 um, but it cancels out and we don't need it
|
||||
|
||||
// Note that because Wii and GC discs have identical data densities
|
||||
// we can simply use the Wii numbers in both cases
|
||||
return std::sqrt(
|
||||
static_cast<double>(offset) / WII_DISC_LAYER_SIZE *
|
||||
(WII_DVD_OUTER_RADIUS * WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS * DVD_INNER_RADIUS) +
|
||||
DVD_INNER_RADIUS * DVD_INNER_RADIUS);
|
||||
}
|
||||
|
||||
// Returns the number of ticks to move the read head from one offset to
|
||||
// another, plus the number of ticks to read one ECC block immediately
|
||||
// afterwards. Based on hardware testing, this appears to be a function of the
|
||||
// linear distance between the radius of the first and second positions on the
|
||||
// disc, though the head speed varies depending on the length of the seek.
|
||||
u64 CalculateSeekTime(u64 offset_from, u64 offset_to)
|
||||
{
|
||||
const double position_from = CalculatePhysicalDiscPosition(offset_from);
|
||||
const double position_to = CalculatePhysicalDiscPosition(offset_to);
|
||||
|
||||
// Seek time is roughly linear based on head distance travelled
|
||||
const double distance = fabs(position_from - position_to);
|
||||
|
||||
double time_in_seconds;
|
||||
if (distance < SHORT_SEEK_MAX_DISTANCE)
|
||||
time_in_seconds = distance * SHORT_SEEK_VELOCITY_INVERSE + SHORT_SEEK_CONSTANT;
|
||||
else
|
||||
time_in_seconds = distance * LONG_SEEK_VELOCITY_INVERSE + LONG_SEEK_CONSTANT;
|
||||
|
||||
return static_cast<u64>(time_in_seconds * SystemTimers::GetTicksPerSecond());
|
||||
}
|
||||
|
||||
// Returns the number of ticks it takes to read an amount of data from a disc,
|
||||
// ignoring factors such as seek times. This is the streaming rate of the
|
||||
// drive and varies between ~3-8MiB/s for Wii discs. Note that there is technically
|
||||
// a DMA delay on top of this, but we model that as part of this read time.
|
||||
u64 CalculateRawDiscReadTime(u64 offset, u64 length)
|
||||
{
|
||||
// The Wii/GC have a CAV drive and the data has a constant pit length
|
||||
// regardless of location on disc. This means we can linearly interpolate
|
||||
// speed from the inner to outer radius. This matches a hardware test.
|
||||
// We're just picking a point halfway into the read as our benchmark for
|
||||
// read speed as speeds don't change materially in this small window.
|
||||
const double physical_offset = CalculatePhysicalDiscPosition(offset + length / 2);
|
||||
|
||||
double speed;
|
||||
if (s_inserted_volume->GetVolumeType() == DiscIO::Platform::WII_DISC)
|
||||
{
|
||||
speed = (physical_offset - DVD_INNER_RADIUS) / (WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
|
||||
(WII_DISC_OUTER_READ_SPEED - WII_DISC_INNER_READ_SPEED) +
|
||||
WII_DISC_INNER_READ_SPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = (physical_offset - DVD_INNER_RADIUS) / (GC_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
|
||||
(GC_DISC_OUTER_READ_SPEED - GC_DISC_INNER_READ_SPEED) +
|
||||
GC_DISC_INNER_READ_SPEED;
|
||||
}
|
||||
|
||||
DEBUG_LOG(DVDINTERFACE, "Read 0x%" PRIx64 " @ 0x%" PRIx64 " @%lf mm: %lf us, %lf MiB/s", length,
|
||||
offset, physical_offset * 1000, length / speed * 1000 * 1000, speed / 1024 / 1024);
|
||||
|
||||
// (ticks/second) / (bytes/second) * bytes = ticks
|
||||
const double ticks = static_cast<double>(SystemTimers::GetTicksPerSecond()) * length / speed;
|
||||
|
||||
return static_cast<u64>(ticks);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/HW/DVD/DVDMath.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
namespace DVDMath
|
||||
{
|
||||
// The size of the first Wii disc layer in bytes (2294912 sectors, 2048 bytes per sector)
|
||||
constexpr u64 WII_DISC_LAYER_SIZE = 0x118240000;
|
||||
|
||||
// 24 mm
|
||||
constexpr double DVD_INNER_RADIUS = 0.024;
|
||||
// 58 mm
|
||||
constexpr double WII_DVD_OUTER_RADIUS = 0.058;
|
||||
// 38 mm
|
||||
constexpr double GC_DVD_OUTER_RADIUS = 0.038;
|
||||
|
||||
// Approximate read speeds at the inner and outer locations of Wii and GC
|
||||
// discs. These speeds are approximations of speeds measured on real Wiis.
|
||||
constexpr double GC_DISC_INNER_READ_SPEED = 1024 * 1024 * 2.1; // bytes/s
|
||||
constexpr double GC_DISC_OUTER_READ_SPEED = 1024 * 1024 * 3.325; // bytes/s
|
||||
constexpr double WII_DISC_INNER_READ_SPEED = 1024 * 1024 * 3.48; // bytes/s
|
||||
constexpr double WII_DISC_OUTER_READ_SPEED = 1024 * 1024 * 8.41; // bytes/s
|
||||
|
||||
// Experimentally measured seek constants. The time to seek appears to be
|
||||
// linear, but short seeks appear to be lower velocity.
|
||||
constexpr double SHORT_SEEK_MAX_DISTANCE = 0.001; // 1 mm
|
||||
constexpr double SHORT_SEEK_CONSTANT = 0.045; // seconds
|
||||
constexpr double SHORT_SEEK_VELOCITY_INVERSE = 50; // inverse: s/m
|
||||
constexpr double LONG_SEEK_CONSTANT = 0.085; // seconds
|
||||
constexpr double LONG_SEEK_VELOCITY_INVERSE = 4.5; // inverse: s/m
|
||||
|
||||
// We can approximate the relationship between a byte offset on disc and its
|
||||
// radial distance from the center by using an approximation for the length of
|
||||
// a rolled material, which is the area of the material divided by the pitch
|
||||
// (ie: assume that you can squish and deform the area of the disc into a
|
||||
// rectangle as thick as the track pitch).
|
||||
//
|
||||
// In practice this yields good-enough numbers as a more exact formula
|
||||
// involving the integral over a polar equation (too complex to describe here)
|
||||
// or the approximation of a DVD as a set of concentric circles (which is a
|
||||
// better approximation, but makes futher derivations more complicated than
|
||||
// they need to be).
|
||||
//
|
||||
// From the area approximation, we end up with this formula:
|
||||
//
|
||||
// L = pi*(r.outer^2-r.inner^2)/pitch
|
||||
//
|
||||
// Where:
|
||||
// L = the data track's physical length
|
||||
// r.{inner,outer} = the inner/outer radii (24 mm and 58 mm)
|
||||
// pitch = the track pitch (.74 um)
|
||||
//
|
||||
// We can then use this equation to compute the radius for a given sector in
|
||||
// the disc by mapping it along the length to a linear position and inverting
|
||||
// the equation and solving for r.outer (using the DVD's r.inner and pitch)
|
||||
// given that linear position:
|
||||
//
|
||||
// r.outer = sqrt(L * pitch / pi + r.inner^2)
|
||||
//
|
||||
// Where:
|
||||
// L = the offset's linear position, as offset/density
|
||||
// r.outer = the radius for the offset
|
||||
// r.inner and pitch are the same as before.
|
||||
//
|
||||
// The data density of the disc is just the number of bytes addressable on a
|
||||
// DVD, divided by the spiral length holding that data. offset/density yields
|
||||
// the linear position for a given offset.
|
||||
//
|
||||
// When we put it all together and simplify, we can compute the radius for a
|
||||
// given byte offset as a drastically simplified:
|
||||
//
|
||||
// r = sqrt(offset/total_bytes*(r.outer^2-r.inner^2) + r.inner^2)
|
||||
double CalculatePhysicalDiscPosition(u64 offset)
|
||||
{
|
||||
// Just in case someone has an overly large disc image
|
||||
// that can't exist in reality...
|
||||
offset %= WII_DISC_LAYER_SIZE * 2;
|
||||
|
||||
// Assumption: the layout on the second disc layer is opposite of the first,
|
||||
// ie layer 2 starts where layer 1 ends and goes backwards.
|
||||
if (offset > WII_DISC_LAYER_SIZE)
|
||||
offset = WII_DISC_LAYER_SIZE * 2 - offset;
|
||||
|
||||
// The track pitch here is 0.74 um, but it cancels out and we don't need it
|
||||
|
||||
// Note that because Wii and GC discs have identical data densities
|
||||
// we can simply use the Wii numbers in both cases
|
||||
return std::sqrt(
|
||||
static_cast<double>(offset) / WII_DISC_LAYER_SIZE *
|
||||
(WII_DVD_OUTER_RADIUS * WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS * DVD_INNER_RADIUS) +
|
||||
DVD_INNER_RADIUS * DVD_INNER_RADIUS);
|
||||
}
|
||||
|
||||
// Returns the time in seconds to move the read head from one offset to
|
||||
// another, plus the number of ticks to read one ECC block immediately
|
||||
// afterwards. Based on hardware testing, this appears to be a function of the
|
||||
// linear distance between the radius of the first and second positions on the
|
||||
// disc, though the head speed varies depending on the length of the seek.
|
||||
double CalculateSeekTime(u64 offset_from, u64 offset_to)
|
||||
{
|
||||
const double position_from = CalculatePhysicalDiscPosition(offset_from);
|
||||
const double position_to = CalculatePhysicalDiscPosition(offset_to);
|
||||
|
||||
// Seek time is roughly linear based on head distance travelled
|
||||
const double distance = fabs(position_from - position_to);
|
||||
|
||||
if (distance < SHORT_SEEK_MAX_DISTANCE)
|
||||
return distance * SHORT_SEEK_VELOCITY_INVERSE + SHORT_SEEK_CONSTANT;
|
||||
else
|
||||
return distance * LONG_SEEK_VELOCITY_INVERSE + LONG_SEEK_CONSTANT;
|
||||
}
|
||||
|
||||
// Returns the time in seconds it takes to read an amount of data from a disc,
|
||||
// ignoring factors such as seek times. This is the streaming rate of the
|
||||
// drive and varies between ~3-8MiB/s for Wii discs. Note that there is technically
|
||||
// a DMA delay on top of this, but we model that as part of this read time.
|
||||
double CalculateRawDiscReadTime(u64 offset, u64 length, bool wii_disc)
|
||||
{
|
||||
// The Wii/GC have a CAV drive and the data has a constant pit length
|
||||
// regardless of location on disc. This means we can linearly interpolate
|
||||
// speed from the inner to outer radius. This matches a hardware test.
|
||||
// We're just picking a point halfway into the read as our benchmark for
|
||||
// read speed as speeds don't change materially in this small window.
|
||||
const double physical_offset = CalculatePhysicalDiscPosition(offset + length / 2);
|
||||
|
||||
double speed;
|
||||
if (wii_disc)
|
||||
{
|
||||
speed = (physical_offset - DVD_INNER_RADIUS) / (WII_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
|
||||
(WII_DISC_OUTER_READ_SPEED - WII_DISC_INNER_READ_SPEED) +
|
||||
WII_DISC_INNER_READ_SPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = (physical_offset - DVD_INNER_RADIUS) / (GC_DVD_OUTER_RADIUS - DVD_INNER_RADIUS) *
|
||||
(GC_DISC_OUTER_READ_SPEED - GC_DISC_INNER_READ_SPEED) +
|
||||
GC_DISC_INNER_READ_SPEED;
|
||||
}
|
||||
|
||||
DEBUG_LOG(DVDINTERFACE, "Read 0x%" PRIx64 " @ 0x%" PRIx64 " @%lf mm: %lf us, %lf MiB/s", length,
|
||||
offset, physical_offset * 1000, length / speed * 1000 * 1000, speed / 1024 / 1024);
|
||||
|
||||
return length / speed;
|
||||
}
|
||||
|
||||
} // namespace DVDMath
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
namespace DVDMath
|
||||
{
|
||||
double CalculatePhysicalDiscPosition(u64 offset);
|
||||
double CalculateSeekTime(u64 offset_from, u64 offset_to);
|
||||
double CalculateRawDiscReadTime(u64 offset, u64 length, bool wii_disc);
|
||||
|
||||
} // namespace DVDMath
|
Loading…
Reference in New Issue