mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Eliminate Location in favour of Layout.
This commit is contained in:
@@ -110,7 +110,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ private:
|
||||
const Apple2EncoderProto& _config;
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(
|
||||
const Location& location,
|
||||
std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "fmt/format.h"
|
||||
#include "arch/c64/c64.pb.h"
|
||||
#include "lib/encoders/encoders.pb.h"
|
||||
#include "lib/layout.h"
|
||||
#include <ctype.h>
|
||||
#include "bytes.h"
|
||||
|
||||
@@ -18,29 +19,32 @@ static int encode_data_gcr(uint8_t data)
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
#define GCR_ENTRY(gcr, data) \
|
||||
case data: return gcr;
|
||||
#include "data_gcr.h"
|
||||
#undef GCR_ENTRY
|
||||
#define GCR_ENTRY(gcr, data) \
|
||||
case data: \
|
||||
return gcr;
|
||||
#include "data_gcr.h"
|
||||
#undef GCR_ENTRY
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, const std::vector<bool>& src)
|
||||
static void write_bits(
|
||||
std::vector<bool>& bits, unsigned& cursor, const std::vector<bool>& src)
|
||||
{
|
||||
for (bool bit : src) //Range-based for loop
|
||||
for (bool bit : src) // Range-based for loop
|
||||
{
|
||||
if (cursor < bits.size())
|
||||
bits[cursor++] = bit;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint64_t data, int width)
|
||||
static void write_bits(
|
||||
std::vector<bool>& bits, unsigned& cursor, uint64_t data, int width)
|
||||
{
|
||||
cursor += width;
|
||||
for (int i=0; i<width; i++)
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
unsigned pos = cursor - i - 1;
|
||||
unsigned pos = cursor - i - 1;
|
||||
if (pos < bits.size())
|
||||
bits[pos] = data & 1;
|
||||
data >>= 1;
|
||||
@@ -51,18 +55,17 @@ void bindump(std::ostream& stream, std::vector<bool>& buffer)
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
while ((pos < buffer.size()) and (pos <520))
|
||||
while ((pos < buffer.size()) and (pos < 520))
|
||||
{
|
||||
stream << fmt::format("{:5d} : ", pos);
|
||||
for (int i=0; i<40; i++)
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
if ((pos+i) < buffer.size())
|
||||
stream << fmt::format("{:01b}", (buffer[pos+i]));
|
||||
if ((pos + i) < buffer.size())
|
||||
stream << fmt::format("{:01b}", (buffer[pos + i]));
|
||||
else
|
||||
stream << "-- ";
|
||||
if ((((pos + i + 1) % 8) == 0) and i != 0)
|
||||
stream << " ";
|
||||
|
||||
}
|
||||
stream << std::endl;
|
||||
pos += 40;
|
||||
@@ -71,51 +74,51 @@ void bindump(std::ostream& stream, std::vector<bool>& buffer)
|
||||
static std::vector<bool> encode_data(uint8_t input)
|
||||
{
|
||||
/*
|
||||
* Four 8-bit data bytes are converted to four 10-bit GCR bytes at a time by
|
||||
* the 1541 DOS. RAM is only an 8-bit storage device though. This hardware
|
||||
* limitation prevents a 10-bit GCR byte from being stored in a single
|
||||
* memory location. Four 10-bit GCR bytes total 40 bits - a number evenly
|
||||
* divisible by our overriding 8-bit constraint. Commodore sub- divides the
|
||||
* 40 GCR bits into five 8-bit bytes to solve this dilemma. This explains
|
||||
* why four 8-bit data bytes are converted to GCR form at a time. The
|
||||
* following step by step example demonstrates how this bit manipulation is
|
||||
* performed by the DOS.
|
||||
*
|
||||
* STEP 1. Four 8-bit Data Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* STEP 2. Hexadecimal to Binary Conversion
|
||||
* 1. Binary Equivalents
|
||||
* $08 $10 $00 $12
|
||||
* 00001000 00010000 00000000 00010010
|
||||
*
|
||||
* STEP 3. Binary to GCR Conversion
|
||||
* 1. Four 8-bit Data Bytes
|
||||
* 00001000 00010000 00000000 00010010
|
||||
* 2. High and Low Nybbles
|
||||
* 0000 1000 0001 0000 0000 0000 0001 0010
|
||||
* 3. High and Low Nybble GCR Equivalents
|
||||
* 01010 01001 01011 01010 01010 01010 01011 10010
|
||||
* 4. Four 10-bit GCR Bytes
|
||||
* 0101001001 0101101010 0101001010 0101110010
|
||||
*
|
||||
* STEP 4. 10-bit GCR to 8-bit GCR Conversion
|
||||
* 1. Concatenate Four 10-bit GCR Bytes
|
||||
* 0101001001010110101001010010100101110010
|
||||
* 2. Five 8-bit Subdivisions
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
*
|
||||
* STEP 5. Binary to Hexadecimal Conversion
|
||||
* 1. Hexadecimal Equivalents
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
* $52 $56 $A5 $29 $72
|
||||
*
|
||||
* STEP 6. Four 8-bit Data Bytes are Recorded as Five 8-bit GCR Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* are recorded as
|
||||
* $52 $56 $A5 $29 $72
|
||||
*/
|
||||
* Four 8-bit data bytes are converted to four 10-bit GCR bytes at a time by
|
||||
* the 1541 DOS. RAM is only an 8-bit storage device though. This hardware
|
||||
* limitation prevents a 10-bit GCR byte from being stored in a single
|
||||
* memory location. Four 10-bit GCR bytes total 40 bits - a number evenly
|
||||
* divisible by our overriding 8-bit constraint. Commodore sub- divides the
|
||||
* 40 GCR bits into five 8-bit bytes to solve this dilemma. This explains
|
||||
* why four 8-bit data bytes are converted to GCR form at a time. The
|
||||
* following step by step example demonstrates how this bit manipulation is
|
||||
* performed by the DOS.
|
||||
*
|
||||
* STEP 1. Four 8-bit Data Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* STEP 2. Hexadecimal to Binary Conversion
|
||||
* 1. Binary Equivalents
|
||||
* $08 $10 $00 $12
|
||||
* 00001000 00010000 00000000 00010010
|
||||
*
|
||||
* STEP 3. Binary to GCR Conversion
|
||||
* 1. Four 8-bit Data Bytes
|
||||
* 00001000 00010000 00000000 00010010
|
||||
* 2. High and Low Nybbles
|
||||
* 0000 1000 0001 0000 0000 0000 0001 0010
|
||||
* 3. High and Low Nybble GCR Equivalents
|
||||
* 01010 01001 01011 01010 01010 01010 01011 10010
|
||||
* 4. Four 10-bit GCR Bytes
|
||||
* 0101001001 0101101010 0101001010 0101110010
|
||||
*
|
||||
* STEP 4. 10-bit GCR to 8-bit GCR Conversion
|
||||
* 1. Concatenate Four 10-bit GCR Bytes
|
||||
* 0101001001010110101001010010100101110010
|
||||
* 2. Five 8-bit Subdivisions
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
*
|
||||
* STEP 5. Binary to Hexadecimal Conversion
|
||||
* 1. Hexadecimal Equivalents
|
||||
* 01010010 01010110 10100101 00101001 01110010
|
||||
* $52 $56 $A5 $29 $72
|
||||
*
|
||||
* STEP 6. Four 8-bit Data Bytes are Recorded as Five 8-bit GCR Bytes
|
||||
* $08 $10 $00 $12
|
||||
*
|
||||
* are recorded as
|
||||
* $52 $56 $A5 $29 $72
|
||||
*/
|
||||
|
||||
std::vector<bool> output(10, false);
|
||||
uint8_t hi = 0;
|
||||
@@ -123,40 +126,40 @@ static std::vector<bool> encode_data(uint8_t input)
|
||||
uint8_t lo_GCR = 0;
|
||||
uint8_t hi_GCR = 0;
|
||||
|
||||
//Convert the byte in high and low nibble
|
||||
lo = input >> 4; //get the lo nibble shift the bits 4 to the right
|
||||
hi = input & 15; //get the hi nibble bij masking the lo bits (00001111)
|
||||
// Convert the byte in high and low nibble
|
||||
lo = input >> 4; // get the lo nibble shift the bits 4 to the right
|
||||
hi = input & 15; // get the hi nibble bij masking the lo bits (00001111)
|
||||
|
||||
|
||||
lo_GCR = encode_data_gcr(lo); //example value: 0000 GCR = 01010
|
||||
hi_GCR = encode_data_gcr(hi); //example value: 1000 GCR = 01001
|
||||
//output = [0,1,2,3,4,5,6,7,8,9]
|
||||
//value = [0,1,0,1,0,0,1,0,0,1]
|
||||
// 01010 01001
|
||||
lo_GCR = encode_data_gcr(lo); // example value: 0000 GCR = 01010
|
||||
hi_GCR = encode_data_gcr(hi); // example value: 1000 GCR = 01001
|
||||
// output = [0,1,2,3,4,5,6,7,8,9]
|
||||
// value = [0,1,0,1,0,0,1,0,0,1]
|
||||
// 01010 01001
|
||||
|
||||
int b = 4;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (i < 5) //01234
|
||||
{ //i = 0 op
|
||||
output[4-i] = (lo_GCR & 1); //01010
|
||||
if (i < 5) // 01234
|
||||
{ // i = 0 op
|
||||
output[4 - i] = (lo_GCR & 1); // 01010
|
||||
|
||||
//01010 -> & 00001 -> 00000 output[4] = 0
|
||||
//00101 -> & 00001 -> 00001 output[3] = 1
|
||||
//00010 -> & 00001 -> 00000 output[2] = 0
|
||||
//00001 -> & 00001 -> 00001 output[1] = 1
|
||||
//00000 -> & 00001 -> 00000 output[0] = 0
|
||||
// 01010 -> & 00001 -> 00000 output[4] = 0
|
||||
// 00101 -> & 00001 -> 00001 output[3] = 1
|
||||
// 00010 -> & 00001 -> 00000 output[2] = 0
|
||||
// 00001 -> & 00001 -> 00001 output[1] = 1
|
||||
// 00000 -> & 00001 -> 00000 output[0] = 0
|
||||
lo_GCR >>= 1;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
output[i+b] = (hi_GCR & 1); //01001
|
||||
//01001 -> & 00001 -> 00001 output[9] = 1
|
||||
//00100 -> & 00001 -> 00000 output[8] = 0
|
||||
//00010 -> & 00001 -> 00000 output[7] = 0
|
||||
//00001 -> & 00001 -> 00001 output[6] = 1
|
||||
//00000 -> & 00001 -> 00000 output[5] = 0
|
||||
output[i + b] = (hi_GCR & 1); // 01001
|
||||
// 01001 -> & 00001 -> 00001 output[9] = 1
|
||||
// 00100 -> & 00001 -> 00000 output[8] = 0
|
||||
// 00010 -> & 00001 -> 00000 output[7] = 0
|
||||
// 00001 -> & 00001 -> 00001 output[6] = 1
|
||||
// 00000 -> & 00001 -> 00000 output[5] = 0
|
||||
hi_GCR >>= 1;
|
||||
b = b-2;
|
||||
b = b - 2;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
@@ -165,59 +168,68 @@ static std::vector<bool> encode_data(uint8_t input)
|
||||
class Commodore64Encoder : public Encoder
|
||||
{
|
||||
public:
|
||||
Commodore64Encoder(const EncoderProto& config):
|
||||
Commodore64Encoder(const EncoderProto& config):
|
||||
Encoder(config),
|
||||
_config(config.c64())
|
||||
{}
|
||||
_config(config.c64())
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors, const Image& image) override
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
/* The format ID Character # 1 and # 2 are in the .d64 image only present
|
||||
* in track 18 sector zero which contains the BAM info in byte 162 and 163.
|
||||
* it is written in every header of every sector and track. headers are not
|
||||
* stored in a d64 disk image so we have to get it from track 18 which
|
||||
* contains the BAM.
|
||||
*/
|
||||
/* The format ID Character # 1 and # 2 are in the .d64 image only
|
||||
* present in track 18 sector zero which contains the BAM info in byte
|
||||
* 162 and 163. it is written in every header of every sector and track.
|
||||
* headers are not stored in a d64 disk image so we have to get it from
|
||||
* track 18 which contains the BAM.
|
||||
*/
|
||||
|
||||
const auto& sectorData = image.get(C64_BAM_TRACK, 0, 0); //Read de BAM to get the DISK ID bytes
|
||||
const auto& sectorData = image.get(
|
||||
C64_BAM_TRACK, 0, 0); // Read de BAM to get the DISK ID bytes
|
||||
if (sectorData)
|
||||
{
|
||||
ByteReader br(sectorData->data);
|
||||
br.seek(162); //goto position of the first Disk ID Byte
|
||||
br.seek(162); // goto position of the first Disk ID Byte
|
||||
_formatByte1 = br.read_8();
|
||||
_formatByte2 = br.read_8();
|
||||
}
|
||||
else
|
||||
_formatByte1 = _formatByte2 = 0;
|
||||
|
||||
double clockRateUs = clockPeriodForC64Track(location.logicalTrack);
|
||||
|
||||
double clockRateUs = clockPeriodForC64Track(layout->logicalTrack);
|
||||
int bitsPerRevolution = 200000.0 / clockRateUs;
|
||||
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
fillBitmapTo(bits, cursor, _config.post_index_gap_us() / clockRateUs, { true, false });
|
||||
fillBitmapTo(bits,
|
||||
cursor,
|
||||
_config.post_index_gap_us() / clockRateUs,
|
||||
{true, false});
|
||||
lastBit = false;
|
||||
|
||||
for (const auto& sector : sectors)
|
||||
writeSector(bits, cursor, sector);
|
||||
|
||||
if (cursor >= bits.size())
|
||||
Error() << fmt::format("track data overrun by {} bits", cursor - bits.size());
|
||||
fillBitmapTo(bits, cursor, bits.size(), { true, false });
|
||||
Error() << fmt::format(
|
||||
"track data overrun by {} bits", cursor - bits.size());
|
||||
fillBitmapTo(bits, cursor, bits.size(), {true, false});
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
fluxmap->appendBits(bits,
|
||||
calculatePhysicalClockPeriod(clockRateUs*1e3, 200e6));
|
||||
fluxmap->appendBits(
|
||||
bits, calculatePhysicalClockPeriod(clockRateUs * 1e3, 200e6));
|
||||
return fluxmap;
|
||||
}
|
||||
|
||||
private:
|
||||
void writeSector(std::vector<bool>& bits, unsigned& cursor, std::shared_ptr<const Sector> sector) const
|
||||
void writeSector(std::vector<bool>& bits,
|
||||
unsigned& cursor,
|
||||
std::shared_ptr<const Sector> sector) const
|
||||
{
|
||||
/* Source: http://www.unusedino.de/ec64/technical/formats/g64.html
|
||||
/* Source: http://www.unusedino.de/ec64/technical/formats/g64.html
|
||||
* 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR)
|
||||
* 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
|
||||
* 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read)
|
||||
@@ -225,23 +237,27 @@ private:
|
||||
* 5. Data block 55...4A (325 GCR bytes)
|
||||
* 6. Inter-sector gap 55 55 55 55...55 55 (4 to 12 bytes, never read)
|
||||
* 1. Header sync (SYNC for the next sector)
|
||||
*/
|
||||
if ((sector->status == Sector::OK) or (sector->status == Sector::BAD_CHECKSUM))
|
||||
*/
|
||||
if ((sector->status == Sector::OK) or
|
||||
(sector->status == Sector::BAD_CHECKSUM))
|
||||
{
|
||||
// There is data to encode to disk.
|
||||
if ((sector->data.size() != C64_SECTOR_LENGTH))
|
||||
Error() << fmt::format("unsupported sector size {} --- you must pick 256", sector->data.size());
|
||||
Error() << fmt::format(
|
||||
"unsupported sector size {} --- you must pick 256",
|
||||
sector->data.size());
|
||||
|
||||
// 1. Write header Sync (not GCR)
|
||||
for (int i=0; i<6; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_DATA_SYNC, 1*8); /* sync */
|
||||
for (int i = 0; i < 6; i++)
|
||||
write_bits(
|
||||
bits, cursor, C64_HEADER_DATA_SYNC, 1 * 8); /* sync */
|
||||
|
||||
// 2. Write Header info 10 GCR bytes
|
||||
/*
|
||||
* The 10 byte header info (#2) is GCR encoded and must be decoded to
|
||||
* it's normal 8 bytes to be understood. Once decoded, its breakdown is
|
||||
* as follows:
|
||||
*
|
||||
* The 10 byte header info (#2) is GCR encoded and must be decoded
|
||||
* to it's normal 8 bytes to be understood. Once decoded, its
|
||||
* breakdown is as follows:
|
||||
*
|
||||
* Byte $00 - header block ID ($08)
|
||||
* 01 - header block checksum 16 (EOR of $02-$05)
|
||||
* 02 - Sector
|
||||
@@ -250,11 +266,14 @@ private:
|
||||
* 05 - Format ID byte #1
|
||||
* 06-07 - $0F ("off" bytes)
|
||||
*/
|
||||
uint8_t encodedTrack = ((sector->logicalTrack) + 1); // C64 track numbering starts with 1. Fluxengine with 0.
|
||||
uint8_t encodedTrack =
|
||||
((sector->logicalTrack) +
|
||||
1); // C64 track numbering starts with 1. Fluxengine with 0.
|
||||
uint8_t encodedSector = sector->logicalSector;
|
||||
// uint8_t formatByte1 = C64_FORMAT_ID_BYTE1;
|
||||
// uint8_t formatByte2 = C64_FORMAT_ID_BYTE2;
|
||||
uint8_t headerChecksum = (encodedTrack ^ encodedSector ^ _formatByte1 ^ _formatByte2);
|
||||
uint8_t headerChecksum =
|
||||
(encodedTrack ^ encodedSector ^ _formatByte1 ^ _formatByte2);
|
||||
write_bits(bits, cursor, encode_data(C64_HEADER_BLOCK_ID));
|
||||
write_bits(bits, cursor, encode_data(headerChecksum));
|
||||
write_bits(bits, cursor, encode_data(encodedSector));
|
||||
@@ -265,22 +284,26 @@ private:
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
|
||||
// 3. Write header GAP not GCR
|
||||
for (int i=0; i<9; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_GAP, 1*8); /* header gap */
|
||||
for (int i = 0; i < 9; i++)
|
||||
write_bits(
|
||||
bits, cursor, C64_HEADER_GAP, 1 * 8); /* header gap */
|
||||
|
||||
// 4. Write Data sync not GCR
|
||||
for (int i=0; i<6; i++)
|
||||
write_bits(bits, cursor, C64_HEADER_DATA_SYNC, 1*8); /* sync */
|
||||
for (int i = 0; i < 6; i++)
|
||||
write_bits(
|
||||
bits, cursor, C64_HEADER_DATA_SYNC, 1 * 8); /* sync */
|
||||
|
||||
// 5. Write data block 325 GCR bytes
|
||||
/*
|
||||
* The 325 byte data block (#5) is GCR encoded and must be decoded to its
|
||||
* normal 260 bytes to be understood. The data block is made up of the following:
|
||||
*
|
||||
* The 325 byte data block (#5) is GCR encoded and must be decoded
|
||||
* to its normal 260 bytes to be understood. The data block is made
|
||||
* up of the following:
|
||||
*
|
||||
* Byte $00 - data block ID ($07)
|
||||
* 01-100 - 256 bytes data
|
||||
* 101 - data block checksum (EOR of $01-100)
|
||||
* 102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
|
||||
* 102-103 - $00 ("off" bytes, to make the sector size a
|
||||
* multiple of 5)
|
||||
*/
|
||||
|
||||
write_bits(bits, cursor, encode_data(C64_DATA_BLOCK_ID));
|
||||
@@ -290,29 +313,28 @@ private:
|
||||
for (i = 0; i < C64_SECTOR_LENGTH; i++)
|
||||
{
|
||||
uint8_t val = br.read_8();
|
||||
write_bits(bits, cursor, encode_data(val));
|
||||
write_bits(bits, cursor, encode_data(val));
|
||||
}
|
||||
write_bits(bits, cursor, encode_data(dataChecksum));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
write_bits(bits, cursor, encode_data(C64_PADDING));
|
||||
|
||||
//6. Write inter-sector gap 9 - 12 bytes nor gcr
|
||||
for (int i=0; i<9; i++)
|
||||
write_bits(bits, cursor, C64_INTER_SECTOR_GAP, 1*8); /* sync */
|
||||
|
||||
// 6. Write inter-sector gap 9 - 12 bytes nor gcr
|
||||
for (int i = 0; i < 9; i++)
|
||||
write_bits(
|
||||
bits, cursor, C64_INTER_SECTOR_GAP, 1 * 8); /* sync */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const Commodore64EncoderProto& _config;
|
||||
uint8_t _formatByte1;
|
||||
uint8_t _formatByte2;
|
||||
const Commodore64EncoderProto& _config;
|
||||
uint8_t _formatByte1;
|
||||
uint8_t _formatByte2;
|
||||
};
|
||||
|
||||
std::unique_ptr<Encoder> createCommodore64Encoder(const EncoderProto& config)
|
||||
{
|
||||
return std::unique_ptr<Encoder>(new Commodore64Encoder(config));
|
||||
return std::unique_ptr<Encoder>(new Commodore64Encoder(config));
|
||||
}
|
||||
|
||||
// vim: sw=4 ts=4 et
|
||||
|
||||
|
||||
@@ -107,15 +107,15 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
IbmEncoderProto::TrackdataProto trackdata;
|
||||
getEncoderTrackData(trackdata, location.logicalTrack, location.logicalSide);
|
||||
getEncoderTrackData(trackdata, layout->logicalTrack, layout->logicalSide);
|
||||
|
||||
auto trackLayout =
|
||||
Layout::getLayoutOfTrack(location.logicalTrack, location.logicalSide);
|
||||
Layout::getLayoutOfTrack(layout->logicalTrack, layout->logicalSide);
|
||||
|
||||
auto writeBytes = [&](const Bytes& bytes)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "image.h"
|
||||
#include "fmt/format.h"
|
||||
#include "lib/encoders/encoders.pb.h"
|
||||
#include "lib/layout.h"
|
||||
#include "arch/macintosh/macintosh.pb.h"
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -219,11 +220,11 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
double clockRateUs = clockRateUsForTrack(location.logicalTrack);
|
||||
double clockRateUs = clockRateUsForTrack(layout->logicalTrack);
|
||||
int bitsPerRevolution = 200000.0 / clockRateUs;
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "fmt/format.h"
|
||||
#include "arch/victor9k/victor9k.pb.h"
|
||||
#include "lib/encoders/encoders.pb.h"
|
||||
#include "lib/layout.h"
|
||||
#include <ctype.h>
|
||||
#include "bytes.h"
|
||||
|
||||
@@ -163,12 +164,12 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) override
|
||||
{
|
||||
Victor9kEncoderProto::TrackdataProto trackdata;
|
||||
getTrackFormat(trackdata, location.logicalTrack, location.logicalSide);
|
||||
getTrackFormat(trackdata, layout->logicalTrack, layout->logicalSide);
|
||||
|
||||
unsigned bitsPerRevolution = (trackdata.rotational_period_ms() * 1e3) /
|
||||
trackdata.clock_period_us();
|
||||
|
||||
@@ -60,19 +60,19 @@ std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
|
||||
return (decoder->second)(config);
|
||||
}
|
||||
|
||||
std::shared_ptr<const TrackDataFlux> Decoder::decodeToSectors(
|
||||
std::shared_ptr<const Fluxmap> fluxmap, const Location& location)
|
||||
std::shared_ptr<TrackDataFlux> Decoder::decodeToSectors(
|
||||
std::shared_ptr<const Fluxmap> fluxmap, std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
_trackdata = std::make_shared<TrackDataFlux>();
|
||||
_trackdata->fluxmap = fluxmap;
|
||||
_trackdata->location = location;
|
||||
_trackdata->layout = layout;
|
||||
|
||||
FluxmapReader fmr(*fluxmap);
|
||||
_fmr = &fmr;
|
||||
|
||||
auto newSector = [&]
|
||||
{
|
||||
_sector = std::make_shared<Sector>(location);
|
||||
_sector = std::make_shared<Sector>(layout, 0);
|
||||
_sector->status = Sector::MISSING;
|
||||
};
|
||||
|
||||
@@ -222,10 +222,10 @@ uint64_t Decoder::readRaw64()
|
||||
}
|
||||
|
||||
std::set<LogicalLocation> Decoder::requiredSectors(
|
||||
const Location& location) const
|
||||
std::shared_ptr<const Layout>& layout) const
|
||||
{
|
||||
const auto trackLayout =
|
||||
Layout::getLayoutOfTrackPhysical(location.physicalTrack, location.physicalSide);
|
||||
Layout::getLayoutOfTrackPhysical(layout->physicalTrack, layout->physicalSide);
|
||||
|
||||
std::set<LogicalLocation> results;
|
||||
for (unsigned sectorId : trackLayout->logicalSectorOrder)
|
||||
|
||||
@@ -49,9 +49,9 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
std::shared_ptr<const TrackDataFlux> decodeToSectors(
|
||||
std::shared_ptr<TrackDataFlux> decodeToSectors(
|
||||
std::shared_ptr<const Fluxmap> fluxmap,
|
||||
const Location& location);
|
||||
std::shared_ptr<const Layout>& location);
|
||||
|
||||
void pushRecord(
|
||||
const Fluxmap::Position& start, const Fluxmap::Position& end);
|
||||
@@ -89,7 +89,8 @@ public:
|
||||
return _fmr->getDuration();
|
||||
}
|
||||
|
||||
virtual std::set<LogicalLocation> requiredSectors(const Location& location) const;
|
||||
virtual std::set<LogicalLocation> requiredSectors(
|
||||
std::shared_ptr<const Layout>& location) const;
|
||||
|
||||
protected:
|
||||
virtual void beginTrack(){};
|
||||
|
||||
@@ -57,25 +57,23 @@ nanoseconds_t Encoder::calculatePhysicalClockPeriod(
|
||||
}
|
||||
|
||||
std::shared_ptr<const Sector> Encoder::getSector(
|
||||
const Location& location, const Image& image, unsigned sectorId)
|
||||
std::shared_ptr<const Layout>& layout, const Image& image, unsigned sectorId)
|
||||
{
|
||||
return image.get(location.logicalTrack, location.logicalSide, sectorId);
|
||||
return image.get(layout->logicalTrack, layout->logicalSide, sectorId);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const Sector>> Encoder::collectSectors(
|
||||
const Location& location, const Image& image)
|
||||
std::shared_ptr<const Layout>& trackLayout, const Image& image)
|
||||
{
|
||||
std::vector<std::shared_ptr<const Sector>> sectors;
|
||||
|
||||
const auto trackLayout =
|
||||
Layout::getLayoutOfTrack(location.logicalTrack, location.logicalSide);
|
||||
for (unsigned sectorId : trackLayout->diskSectorOrder)
|
||||
{
|
||||
const auto& sector = getSector(location, image, sectorId);
|
||||
const auto& sector = getSector(trackLayout, image, sectorId);
|
||||
if (!sector)
|
||||
Error() << fmt::format("sector {}.{}.{} is missing from the image",
|
||||
location.logicalTrack,
|
||||
location.logicalSide,
|
||||
trackLayout->logicalTrack,
|
||||
trackLayout->logicalSide,
|
||||
sectorId);
|
||||
sectors.push_back(sector);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
class EncoderProto;
|
||||
class Fluxmap;
|
||||
class Image;
|
||||
class Location;
|
||||
class Layout;
|
||||
class Sector;
|
||||
|
||||
class Encoder
|
||||
@@ -17,12 +17,12 @@ public:
|
||||
|
||||
public:
|
||||
virtual std::shared_ptr<const Sector> getSector(
|
||||
const Location& location, const Image& image, unsigned sectorId);
|
||||
std::shared_ptr<const Layout>&, const Image& image, unsigned sectorId);
|
||||
|
||||
virtual std::vector<std::shared_ptr<const Sector>> collectSectors(
|
||||
const Location& location, const Image& image);
|
||||
std::shared_ptr<const Layout>&, const Image& image);
|
||||
|
||||
virtual std::unique_ptr<Fluxmap> encode(const Location& location,
|
||||
virtual std::unique_ptr<Fluxmap> encode(std::shared_ptr<const Layout>& layout,
|
||||
const std::vector<std::shared_ptr<const Sector>>& sectors,
|
||||
const Image& image) = 0;
|
||||
|
||||
|
||||
34
lib/flux.h
34
lib/flux.h
@@ -6,6 +6,7 @@
|
||||
class Fluxmap;
|
||||
class Sector;
|
||||
class Image;
|
||||
class Layout;
|
||||
|
||||
struct Record
|
||||
{
|
||||
@@ -15,34 +16,9 @@ struct Record
|
||||
Bytes rawData;
|
||||
};
|
||||
|
||||
struct Location
|
||||
{
|
||||
unsigned physicalTrack;
|
||||
unsigned physicalSide;
|
||||
unsigned logicalTrack;
|
||||
unsigned logicalSide;
|
||||
unsigned groupSize;
|
||||
|
||||
bool operator==(const Location& other) const
|
||||
{
|
||||
return key() == other.key();
|
||||
}
|
||||
|
||||
bool operator<(const Location& other) const
|
||||
{
|
||||
return key() < other.key();
|
||||
}
|
||||
|
||||
private:
|
||||
std::tuple<unsigned, unsigned> key() const
|
||||
{
|
||||
return std::make_tuple(physicalTrack, physicalSide);
|
||||
}
|
||||
};
|
||||
|
||||
struct TrackDataFlux
|
||||
{
|
||||
Location location;
|
||||
std::shared_ptr<const Layout> layout;
|
||||
std::shared_ptr<const Fluxmap> fluxmap;
|
||||
std::vector<std::shared_ptr<const Record>> records;
|
||||
std::vector<std::shared_ptr<const Sector>> sectors;
|
||||
@@ -50,14 +26,14 @@ struct TrackDataFlux
|
||||
|
||||
struct TrackFlux
|
||||
{
|
||||
Location location;
|
||||
std::vector<std::shared_ptr<const TrackDataFlux>> trackDatas;
|
||||
std::shared_ptr<const Layout> layout;
|
||||
std::vector<std::shared_ptr<TrackDataFlux>> trackDatas;
|
||||
std::set<std::shared_ptr<const Sector>> sectors;
|
||||
};
|
||||
|
||||
struct DiskFlux
|
||||
{
|
||||
std::vector<std::shared_ptr<const TrackFlux>> tracks;
|
||||
std::vector<std::shared_ptr<TrackFlux>> tracks;
|
||||
std::shared_ptr<const Image> image;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "lib/flux.h"
|
||||
#include "lib/fluxsource/fluxsource.h"
|
||||
#include "lib/fluxmap.h"
|
||||
#include "lib/layout.h"
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
|
||||
@@ -40,6 +41,7 @@ class EmptyFluxSourceIterator : public FluxSourceIterator
|
||||
std::unique_ptr<const Fluxmap> next() override
|
||||
{
|
||||
Error() << "no flux to read";
|
||||
throw nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,7 +57,7 @@ public:
|
||||
{
|
||||
for (const auto& trackFlux : _flux.tracks)
|
||||
{
|
||||
if ((trackFlux->location.physicalTrack == physicalTrack) && (trackFlux->location.physicalSide == physicalSide))
|
||||
if ((trackFlux->layout->physicalTrack == physicalTrack) && (trackFlux->layout->physicalSide == physicalSide))
|
||||
return std::make_unique<MemoryFluxSourceIterator>(*trackFlux);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ unsigned Layout::remapSideLogicalToPhysical(unsigned lside)
|
||||
return lside ^ config.layout().swap_sides();
|
||||
}
|
||||
|
||||
std::set<Location> Layout::computeLocations()
|
||||
std::vector<std::shared_ptr<const Layout>> Layout::computeLocations()
|
||||
{
|
||||
std::set<unsigned> tracks;
|
||||
if (config.has_tracks())
|
||||
@@ -52,31 +52,15 @@ std::set<Location> Layout::computeLocations()
|
||||
else
|
||||
heads = iterate(0, config.layout().sides());
|
||||
|
||||
std::set<Location> locations;
|
||||
std::vector<std::shared_ptr<const Layout>> locations;
|
||||
for (unsigned logicalTrack : tracks)
|
||||
{
|
||||
for (unsigned logicalHead : heads)
|
||||
locations.insert(computeLocationFor(logicalTrack, logicalHead));
|
||||
locations.push_back(getLayoutOfTrack(logicalTrack, logicalHead));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
Location Layout::computeLocationFor(unsigned logicalTrack, unsigned logicalSide)
|
||||
{
|
||||
if ((logicalTrack < config.layout().tracks()) &&
|
||||
(logicalSide < config.layout().sides()))
|
||||
{
|
||||
return Location {.physicalTrack = remapTrackLogicalToPhysical(logicalTrack),
|
||||
.physicalSide = remapSideLogicalToPhysical(logicalSide),
|
||||
.logicalTrack = logicalTrack,
|
||||
.logicalSide = logicalSide,
|
||||
.groupSize = getTrackStep()};
|
||||
}
|
||||
|
||||
Error() << fmt::format(
|
||||
"track {}.{} is not part of the image", logicalTrack, logicalSide);
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, int>> Layout::getTrackOrdering(
|
||||
unsigned guessedTracks, unsigned guessedSides)
|
||||
{
|
||||
|
||||
25
lib/layout.h
25
lib/layout.h
@@ -29,15 +29,10 @@ public:
|
||||
static unsigned remapSidePhysicalToLogical(unsigned physicalSide);
|
||||
static unsigned remapSideLogicalToPhysical(unsigned logicalSide);
|
||||
|
||||
/* Computes a Location for a given logical track and side, which
|
||||
* contains the physical drive location and group size. */
|
||||
static Location computeLocationFor(
|
||||
unsigned logicalTrack, unsigned logicalSide);
|
||||
|
||||
/* Uses the layout and current track and heads settings to determine
|
||||
* which Locations are going to be read from or written to. 8/
|
||||
*/
|
||||
static std::set<Location> computeLocations();
|
||||
static std::vector<std::shared_ptr<const Layout>> computeLocations();
|
||||
|
||||
/* Returns a series of <track, side> pairs representing the filesystem
|
||||
* ordering of the disk, in logical numbers. */
|
||||
@@ -57,30 +52,30 @@ public:
|
||||
const SectorListProto& sectorsProto);
|
||||
|
||||
public:
|
||||
unsigned numTracks;
|
||||
unsigned numSides;
|
||||
unsigned numTracks = 0;
|
||||
unsigned numSides = 0;
|
||||
|
||||
/* The number of sectors in this track. */
|
||||
unsigned numSectors;
|
||||
unsigned numSectors = 0;
|
||||
|
||||
/* Physical location of this track. */
|
||||
unsigned physicalTrack;
|
||||
unsigned physicalTrack = 0;
|
||||
|
||||
/* Physical side of this track. */
|
||||
unsigned physicalSide;
|
||||
unsigned physicalSide = 0;
|
||||
|
||||
/* Logical location of this track. */
|
||||
unsigned logicalTrack;
|
||||
unsigned logicalTrack = 0;
|
||||
|
||||
/* Logical side of this track. */
|
||||
unsigned logicalSide;
|
||||
unsigned logicalSide = 0;
|
||||
|
||||
/* The number of physical tracks which need to be written for one logical
|
||||
* track. */
|
||||
unsigned groupSize;
|
||||
unsigned groupSize = 0;
|
||||
|
||||
/* Number of bytes in a sector. */
|
||||
unsigned sectorSize;
|
||||
unsigned sectorSize = 0;
|
||||
|
||||
/* Sector IDs in disk order. */
|
||||
std::vector<unsigned> diskSectorOrder;
|
||||
|
||||
@@ -154,8 +154,9 @@ static std::set<std::shared_ptr<const Sector>> collectSectors(
|
||||
return sector_set;
|
||||
}
|
||||
|
||||
BadSectorsState combineRecordAndSectors(
|
||||
TrackFlux& trackFlux, Decoder& decoder, const Location& location)
|
||||
BadSectorsState combineRecordAndSectors(TrackFlux& trackFlux,
|
||||
Decoder& decoder,
|
||||
std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
std::set<std::shared_ptr<const Sector>> track_sectors;
|
||||
|
||||
@@ -163,7 +164,7 @@ BadSectorsState combineRecordAndSectors(
|
||||
track_sectors.insert(
|
||||
trackdataflux->sectors.begin(), trackdataflux->sectors.end());
|
||||
|
||||
for (auto& logicalLocation : decoder.requiredSectors(trackFlux.location))
|
||||
for (auto& logicalLocation : decoder.requiredSectors(trackFlux.layout))
|
||||
{
|
||||
auto sector = std::make_shared<Sector>(logicalLocation);
|
||||
sector->status = Sector::MISSING;
|
||||
@@ -181,22 +182,22 @@ BadSectorsState combineRecordAndSectors(
|
||||
}
|
||||
|
||||
ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder,
|
||||
const Location& location,
|
||||
std::shared_ptr<const Layout>& layout,
|
||||
TrackFlux& trackFlux,
|
||||
Decoder& decoder)
|
||||
{
|
||||
ReadResult result = BAD_AND_CAN_NOT_RETRY;
|
||||
|
||||
for (unsigned offset = 0; offset < location.groupSize;
|
||||
for (unsigned offset = 0; offset < layout->groupSize;
|
||||
offset += config.drive().head_width())
|
||||
{
|
||||
auto& fluxSourceIterator = fluxSourceIteratorHolder.getIterator(
|
||||
location.physicalTrack + offset, location.physicalSide);
|
||||
layout->physicalTrack + offset, layout->physicalSide);
|
||||
if (!fluxSourceIterator.hasNext())
|
||||
continue;
|
||||
|
||||
Logger() << BeginReadOperationLogMessage{
|
||||
location.physicalTrack + offset, location.physicalSide};
|
||||
layout->physicalTrack + offset, layout->physicalSide};
|
||||
std::shared_ptr<const Fluxmap> fluxmap = fluxSourceIterator.next();
|
||||
// ->rescale(
|
||||
// 1.0 / config.flux_source().rescale());
|
||||
@@ -205,9 +206,9 @@ ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder,
|
||||
(int)(fluxmap->duration() / 1e6),
|
||||
fluxmap->bytes());
|
||||
|
||||
auto trackdataflux = decoder.decodeToSectors(fluxmap, location);
|
||||
auto trackdataflux = decoder.decodeToSectors(fluxmap, layout);
|
||||
trackFlux.trackDatas.push_back(trackdataflux);
|
||||
if (combineRecordAndSectors(trackFlux, decoder, location) ==
|
||||
if (combineRecordAndSectors(trackFlux, decoder, layout) ==
|
||||
HAS_NO_BAD_SECTORS)
|
||||
{
|
||||
result = GOOD_READ;
|
||||
@@ -222,18 +223,18 @@ ReadResult readGroup(FluxSourceIteratorHolder& fluxSourceIteratorHolder,
|
||||
}
|
||||
|
||||
void writeTracks(FluxSink& fluxSink,
|
||||
std::function<std::unique_ptr<const Fluxmap>(const Location& location)>
|
||||
producer,
|
||||
std::function<bool(const Location& location)> verifier,
|
||||
const std::set<Location>& locations)
|
||||
std::function<std::unique_ptr<const Fluxmap>(
|
||||
std::shared_ptr<const Layout>& layout)> producer,
|
||||
std::function<bool(std::shared_ptr<const Layout>& layout)> verifier,
|
||||
std::vector<std::shared_ptr<const Layout>>& layouts)
|
||||
{
|
||||
Logger() << BeginOperationLogMessage{"Encoding and writing to disk"};
|
||||
|
||||
int index = 0;
|
||||
for (const auto& location : locations)
|
||||
for (auto& layout : layouts)
|
||||
{
|
||||
Logger() << OperationProgressLogMessage{
|
||||
index * 100 / (unsigned)locations.size()};
|
||||
index * 100 / (unsigned)layouts.size()};
|
||||
index++;
|
||||
|
||||
testForEmergencyStop();
|
||||
@@ -241,22 +242,22 @@ void writeTracks(FluxSink& fluxSink,
|
||||
int retriesRemaining = config.decoder().retries();
|
||||
for (;;)
|
||||
{
|
||||
for (int offset = 0; offset < location.groupSize;
|
||||
for (int offset = 0; offset < layout->groupSize;
|
||||
offset += config.drive().head_width())
|
||||
{
|
||||
unsigned physicalTrack = location.physicalTrack + offset;
|
||||
unsigned physicalTrack = layout->physicalTrack + offset;
|
||||
|
||||
Logger() << BeginWriteOperationLogMessage{
|
||||
physicalTrack, location.physicalSide};
|
||||
physicalTrack, layout->physicalSide};
|
||||
|
||||
if (offset == config.drive().group_offset())
|
||||
{
|
||||
auto fluxmap = producer(location);
|
||||
auto fluxmap = producer(layout);
|
||||
if (!fluxmap)
|
||||
goto erase;
|
||||
|
||||
fluxSink.writeFlux(
|
||||
physicalTrack, location.physicalSide, *fluxmap);
|
||||
physicalTrack, layout->physicalSide, *fluxmap);
|
||||
Logger() << fmt::format("writing {0} ms in {1} bytes",
|
||||
int(fluxmap->duration() / 1e6),
|
||||
fluxmap->bytes());
|
||||
@@ -268,14 +269,14 @@ void writeTracks(FluxSink& fluxSink,
|
||||
|
||||
Fluxmap blank;
|
||||
fluxSink.writeFlux(
|
||||
physicalTrack, location.physicalSide, blank);
|
||||
physicalTrack, layout->physicalSide, blank);
|
||||
Logger() << "erased";
|
||||
}
|
||||
|
||||
Logger() << EndWriteOperationLogMessage();
|
||||
}
|
||||
|
||||
if (verifier(location))
|
||||
if (verifier(layout))
|
||||
break;
|
||||
|
||||
if (retriesRemaining == 0)
|
||||
@@ -293,20 +294,20 @@ void writeTracks(FluxSink& fluxSink,
|
||||
void writeTracks(FluxSink& fluxSink,
|
||||
Encoder& encoder,
|
||||
const Image& image,
|
||||
const std::set<Location>& locations)
|
||||
std::vector<std::shared_ptr<const Layout>>& layouts)
|
||||
{
|
||||
writeTracks(
|
||||
fluxSink,
|
||||
[&](const Location& location)
|
||||
[&](std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
auto sectors = encoder.collectSectors(location, image);
|
||||
return encoder.encode(location, sectors, image);
|
||||
auto sectors = encoder.collectSectors(layout, image);
|
||||
return encoder.encode(layout, sectors, image);
|
||||
},
|
||||
[](const auto&)
|
||||
{
|
||||
return true;
|
||||
},
|
||||
locations);
|
||||
layouts);
|
||||
}
|
||||
|
||||
void writeTracksAndVerify(FluxSink& fluxSink,
|
||||
@@ -314,22 +315,22 @@ void writeTracksAndVerify(FluxSink& fluxSink,
|
||||
FluxSource& fluxSource,
|
||||
Decoder& decoder,
|
||||
const Image& image,
|
||||
const std::set<Location>& locations)
|
||||
std::vector<std::shared_ptr<const Layout>>& locations)
|
||||
{
|
||||
writeTracks(
|
||||
fluxSink,
|
||||
[&](const Location& location)
|
||||
[&](std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
auto sectors = encoder.collectSectors(location, image);
|
||||
return encoder.encode(location, sectors, image);
|
||||
auto sectors = encoder.collectSectors(layout, image);
|
||||
return encoder.encode(layout, sectors, image);
|
||||
},
|
||||
[&](const Location& location)
|
||||
[&](std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
auto trackFlux = std::make_shared<TrackFlux>();
|
||||
trackFlux->location = location;
|
||||
trackFlux->layout = layout;
|
||||
FluxSourceIteratorHolder fluxSourceIteratorHolder(fluxSource);
|
||||
auto result = readGroup(
|
||||
fluxSourceIteratorHolder, location, *trackFlux, decoder);
|
||||
fluxSourceIteratorHolder, layout, *trackFlux, decoder);
|
||||
Logger() << TrackReadLogMessage{trackFlux};
|
||||
|
||||
if (result != GOOD_READ)
|
||||
@@ -339,7 +340,7 @@ void writeTracksAndVerify(FluxSink& fluxSink,
|
||||
}
|
||||
|
||||
Image wanted;
|
||||
for (const auto& sector : encoder.collectSectors(location, image))
|
||||
for (const auto& sector : encoder.collectSectors(layout, image))
|
||||
wanted
|
||||
.put(sector->logicalTrack,
|
||||
sector->logicalSide,
|
||||
@@ -380,7 +381,7 @@ void writeDiskCommand(const Image& image,
|
||||
FluxSink& fluxSink,
|
||||
Decoder* decoder,
|
||||
FluxSource* fluxSource,
|
||||
const std::set<Location>& locations)
|
||||
std::vector<std::shared_ptr<const Layout>>& locations)
|
||||
{
|
||||
if (fluxSource && decoder)
|
||||
writeTracksAndVerify(
|
||||
@@ -401,33 +402,35 @@ void writeDiskCommand(const Image& image,
|
||||
|
||||
void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink)
|
||||
{
|
||||
auto locations = Layout::computeLocations();
|
||||
writeTracks(
|
||||
fluxSink,
|
||||
[&](const Location& location)
|
||||
[&](std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
return fluxSource
|
||||
.readFlux(location.physicalTrack, location.physicalSide)
|
||||
.readFlux(layout->physicalTrack, layout->physicalSide)
|
||||
->next();
|
||||
},
|
||||
[](const auto&)
|
||||
{
|
||||
return true;
|
||||
},
|
||||
Layout::computeLocations());
|
||||
locations);
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackFlux> readAndDecodeTrack(
|
||||
FluxSource& fluxSource, Decoder& decoder, const Location& location)
|
||||
std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
|
||||
Decoder& decoder,
|
||||
std::shared_ptr<const Layout>& layout)
|
||||
{
|
||||
auto trackFlux = std::make_shared<TrackFlux>();
|
||||
trackFlux->location = location;
|
||||
trackFlux->layout = layout;
|
||||
|
||||
FluxSourceIteratorHolder fluxSourceIteratorHolder(fluxSource);
|
||||
int retriesRemaining = config.decoder().retries();
|
||||
for (;;)
|
||||
{
|
||||
auto result =
|
||||
readGroup(fluxSourceIteratorHolder, location, *trackFlux, decoder);
|
||||
readGroup(fluxSourceIteratorHolder, layout, *trackFlux, decoder);
|
||||
if (result == GOOD_READ)
|
||||
break;
|
||||
if (result == BAD_AND_CAN_NOT_RETRY)
|
||||
@@ -462,7 +465,7 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
|
||||
Logger() << BeginOperationLogMessage{"Reading and decoding disk"};
|
||||
auto locations = Layout::computeLocations();
|
||||
unsigned index = 0;
|
||||
for (const auto& location : locations)
|
||||
for (auto& layout : locations)
|
||||
{
|
||||
Logger() << OperationProgressLogMessage{
|
||||
index * 100 / (unsigned)locations.size()};
|
||||
@@ -470,14 +473,14 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
|
||||
|
||||
testForEmergencyStop();
|
||||
|
||||
auto trackFlux = readAndDecodeTrack(fluxSource, decoder, location);
|
||||
auto trackFlux = readAndDecodeTrack(fluxSource, decoder, layout);
|
||||
diskflux->tracks.push_back(trackFlux);
|
||||
|
||||
if (outputFluxSink)
|
||||
{
|
||||
for (const auto& data : trackFlux->trackDatas)
|
||||
outputFluxSink->writeFlux(location.physicalTrack,
|
||||
location.physicalSide,
|
||||
outputFluxSink->writeFlux(layout->physicalTrack,
|
||||
layout->physicalSide,
|
||||
*data->fluxmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Fluxmap;
|
||||
class Image;
|
||||
class ImageReader;
|
||||
class ImageWriter;
|
||||
class Location;
|
||||
class Layout;
|
||||
class TrackFlux;
|
||||
|
||||
extern void measureDiskRotation(
|
||||
@@ -19,15 +19,15 @@ extern void measureDiskRotation(
|
||||
|
||||
extern void writeTracks(FluxSink& fluxSink,
|
||||
const std::function<std::unique_ptr<const Fluxmap>(
|
||||
const Location& location)> producer,
|
||||
const std::set<Location>& locations);
|
||||
std::shared_ptr<const Layout>& layout)> producer,
|
||||
std::vector<std::shared_ptr<const Layout>>& locations);
|
||||
|
||||
extern void writeTracksAndVerify(FluxSink& fluxSink,
|
||||
Encoder& encoder,
|
||||
FluxSource& fluxSource,
|
||||
Decoder& decoder,
|
||||
const Image& image,
|
||||
const std::set<Location>& locations);
|
||||
std::vector<std::shared_ptr<const Layout>>& locations);
|
||||
|
||||
extern void fillBitmapTo(std::vector<bool>& bitmap,
|
||||
unsigned& cursor,
|
||||
@@ -39,7 +39,7 @@ extern void writeDiskCommand(const Image& image,
|
||||
FluxSink& fluxSink,
|
||||
Decoder* decoder,
|
||||
FluxSource* fluxSource,
|
||||
const std::set<Location>& locations);
|
||||
std::vector<std::shared_ptr<const Layout>>& locations);
|
||||
|
||||
extern void writeDiskCommand(const Image& image,
|
||||
Encoder& encoder,
|
||||
@@ -49,8 +49,9 @@ extern void writeDiskCommand(const Image& image,
|
||||
|
||||
extern void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink);
|
||||
|
||||
extern std::shared_ptr<TrackFlux> readAndDecodeTrack(
|
||||
FluxSource& fluxSource, Decoder& decoder, const Location& location);
|
||||
extern std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
|
||||
Decoder& decoder,
|
||||
std::shared_ptr<const Layout>& layout);
|
||||
|
||||
extern std::shared_ptr<const DiskFlux> readDiskCommand(
|
||||
FluxSource& fluxsource, Decoder& decoder);
|
||||
|
||||
@@ -10,10 +10,10 @@ Sector::Sector(const LogicalLocation& location):
|
||||
physicalSide(Layout::remapSideLogicalToPhysical(location.logicalSide))
|
||||
{}
|
||||
|
||||
Sector::Sector(const Location& location):
|
||||
LogicalLocation({ location.logicalTrack, location.logicalSide, 0 }),
|
||||
physicalTrack(location.physicalTrack),
|
||||
physicalSide(location.physicalSide)
|
||||
Sector::Sector(std::shared_ptr<const Layout>& layout, unsigned sectorId):
|
||||
LogicalLocation({ layout->logicalTrack, layout->logicalSide, sectorId }),
|
||||
physicalTrack(layout->physicalTrack),
|
||||
physicalSide(layout->physicalSide)
|
||||
{}
|
||||
|
||||
std::string Sector::statusToString(Status status)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "fluxmap.h"
|
||||
|
||||
class Record;
|
||||
class Location;
|
||||
class Layout;
|
||||
|
||||
struct LogicalLocation
|
||||
{
|
||||
@@ -65,9 +65,9 @@ struct Sector : public LogicalLocation
|
||||
|
||||
Sector() {}
|
||||
|
||||
Sector(const LogicalLocation& location);
|
||||
Sector(std::shared_ptr<const Layout>& layout, unsigned sectorId=0);
|
||||
|
||||
Sector(const Location& location);
|
||||
Sector(const LogicalLocation& location);
|
||||
|
||||
std::tuple<int, int, int, Status> key() const
|
||||
{
|
||||
|
||||
@@ -291,7 +291,8 @@ public:
|
||||
|
||||
auto& filename = path.back();
|
||||
if (filename.size() > 8)
|
||||
throw CannotWriteException("filename too long (eight characters maximum)");
|
||||
throw CannotWriteException(
|
||||
"filename too long (eight characters maximum)");
|
||||
|
||||
int sectorLength = (data.size() + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||
if (sectorLength > 0xff)
|
||||
|
||||
@@ -56,14 +56,14 @@ public:
|
||||
|
||||
void flushChanges() override
|
||||
{
|
||||
std::set<Location> locations;
|
||||
std::vector<std::shared_ptr<const Layout>> locations;
|
||||
|
||||
for (const auto& trackid : _changedTracks)
|
||||
{
|
||||
unsigned track = trackid.first;
|
||||
unsigned side = trackid.second;
|
||||
auto trackLayout = Layout::getLayoutOfTrack(track, side);
|
||||
locations.insert(Layout::computeLocationFor(track, side));
|
||||
locations.push_back(trackLayout);
|
||||
|
||||
/* If we don't have all the sectors of this track, we may need to
|
||||
* populate any non-changed sectors as we can only write a track at
|
||||
@@ -128,8 +128,8 @@ private:
|
||||
|
||||
void populateSectors(unsigned track, unsigned side)
|
||||
{
|
||||
auto location = Layout::computeLocationFor(track, side);
|
||||
auto trackdata = readAndDecodeTrack(*_fluxSource, *_decoder, location);
|
||||
auto layout = Layout::getLayoutOfTrack(track, side);
|
||||
auto trackdata = readAndDecodeTrack(*_fluxSource, *_decoder, layout);
|
||||
|
||||
for (const auto& sector : trackdata->sectors)
|
||||
*_loadedSectors.put(track, side, sector->logicalSector) = *sector;
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
void ShowProgressBar();
|
||||
void HideProgressBar();
|
||||
void SetProgress(int amount);
|
||||
void SetLeftLabel(const std::string& text);
|
||||
void SetLeftLabel(const std::string& text);
|
||||
void SetRightLabel(const std::string& text);
|
||||
|
||||
private:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "lib/flux.h"
|
||||
#include "lib/fluxmap.h"
|
||||
#include "lib/sector.h"
|
||||
#include "lib/layout.h"
|
||||
#include "lib/decoders/fluxmapreader.h"
|
||||
|
||||
DECLARE_COLOUR(BACKGROUND, 192, 192, 192);
|
||||
@@ -35,14 +36,18 @@ FluxViewerControl::FluxViewerControl(wxWindow* parent,
|
||||
SetDoubleBuffered(true);
|
||||
}
|
||||
|
||||
wxBEGIN_EVENT_TABLE(FluxViewerControl, wxPanel) EVT_PAINT(
|
||||
FluxViewerControl::OnPaint) EVT_MOUSEWHEEL(FluxViewerControl::OnMouseWheel)
|
||||
// clang-format off
|
||||
wxBEGIN_EVENT_TABLE(FluxViewerControl, wxPanel)
|
||||
EVT_PAINT(FluxViewerControl::OnPaint)
|
||||
EVT_MOUSEWHEEL(FluxViewerControl::OnMouseWheel)
|
||||
EVT_LEFT_DOWN(FluxViewerControl::OnMouseMotion)
|
||||
EVT_LEFT_UP(FluxViewerControl::OnMouseMotion)
|
||||
EVT_MOTION(FluxViewerControl::OnMouseMotion) EVT_CONTEXT_MENU(
|
||||
FluxViewerControl::OnContextMenu) wxEND_EVENT_TABLE()
|
||||
EVT_LEFT_UP(FluxViewerControl::OnMouseMotion)
|
||||
EVT_MOTION(FluxViewerControl::OnMouseMotion)
|
||||
EVT_CONTEXT_MENU(FluxViewerControl::OnContextMenu)
|
||||
wxEND_EVENT_TABLE();
|
||||
// clang-format on
|
||||
|
||||
void FluxViewerControl::SetScrollbar(wxScrollBar* scrollbar)
|
||||
void FluxViewerControl::SetScrollbar(wxScrollBar* scrollbar)
|
||||
{
|
||||
_scrollbar = scrollbar;
|
||||
_scrollbar->Bind(
|
||||
@@ -130,7 +135,7 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
|
||||
int x = -_scrollPosition / _nanosecondsPerPixel;
|
||||
nanoseconds_t fluxStartTime = 0;
|
||||
for (const auto& trackdata : _flux->trackDatas)
|
||||
for (auto& trackdata : _flux->trackDatas)
|
||||
{
|
||||
nanoseconds_t duration = trackdata->fluxmap->duration();
|
||||
int fw = duration / _nanosecondsPerPixel;
|
||||
@@ -224,7 +229,7 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
|
||||
dc.SetBackgroundMode(wxTRANSPARENT);
|
||||
dc.SetTextForeground(*wxBLACK);
|
||||
for (const auto& sector : trackdata->sectors)
|
||||
for (auto& sector : trackdata->sectors)
|
||||
{
|
||||
nanoseconds_t sr = sector->dataEndTime;
|
||||
if (!sr)
|
||||
@@ -261,7 +266,7 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
|
||||
dc.SetPen(FOREGROUND_PEN);
|
||||
dc.SetBrush(RECORD_BRUSH);
|
||||
for (const auto& record : trackdata->records)
|
||||
for (auto& record : trackdata->records)
|
||||
{
|
||||
int rp = record->startTime / _nanosecondsPerPixel;
|
||||
int rw = (record->endTime - record->startTime) /
|
||||
@@ -281,7 +286,7 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
text, {x + rp + BORDER, t2y - size.GetHeight() / 2});
|
||||
|
||||
if (_rightClicked && hovered)
|
||||
ShowRecordMenu(trackdata->location, record);
|
||||
ShowRecordMenu(trackdata->layout, record);
|
||||
}
|
||||
|
||||
/* Flux chart. */
|
||||
@@ -429,8 +434,8 @@ void FluxViewerControl::ShowSectorMenu(std::shared_ptr<const Sector> sector)
|
||||
PopupMenu(&menu, _mouseX, _mouseY);
|
||||
}
|
||||
|
||||
void FluxViewerControl::ShowRecordMenu(
|
||||
const Location& location, std::shared_ptr<const Record> record)
|
||||
void FluxViewerControl::ShowRecordMenu(std::shared_ptr<const ::Layout>& layout,
|
||||
std::shared_ptr<const Record> record)
|
||||
{
|
||||
wxMenu menu;
|
||||
|
||||
@@ -438,7 +443,7 @@ void FluxViewerControl::ShowRecordMenu(
|
||||
wxEVT_COMMAND_MENU_SELECTED,
|
||||
[&](wxCommandEvent&)
|
||||
{
|
||||
DisplayRawData(location, record);
|
||||
DisplayRawData(layout, record);
|
||||
},
|
||||
menu.Append(wxID_ANY, "Show record data")->GetId());
|
||||
|
||||
@@ -497,14 +502,14 @@ void FluxViewerControl::DisplayRawData(std::shared_ptr<const Sector> sector)
|
||||
TextViewerWindow::Create(this, title, s.str())->Show();
|
||||
}
|
||||
|
||||
void FluxViewerControl::DisplayRawData(
|
||||
const Location& location, std::shared_ptr<const Record> record)
|
||||
void FluxViewerControl::DisplayRawData(std::shared_ptr<const ::Layout>& layout,
|
||||
std::shared_ptr<const Record> record)
|
||||
{
|
||||
std::stringstream s;
|
||||
|
||||
auto title = fmt::format("Raw data for record c{}.h{} + {:.3f}ms",
|
||||
location.physicalTrack,
|
||||
location.physicalSide,
|
||||
layout->physicalTrack,
|
||||
layout->physicalSide,
|
||||
record->startTime / 1e6);
|
||||
s << title << "\n\n";
|
||||
hexdump(s, record->rawData);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef FLUXVIEWERCONTROL_H
|
||||
#define FLUXVIEWERCONTROL_H
|
||||
|
||||
#include "globals.h"
|
||||
#include "lib/globals.h"
|
||||
|
||||
class TrackFlux;
|
||||
class wxScrollBar;
|
||||
class wxScrollEvent;
|
||||
class Sector;
|
||||
class Record;
|
||||
class Location;
|
||||
class Layout;
|
||||
|
||||
class FluxViewerControl : public wxWindow
|
||||
{
|
||||
@@ -18,40 +18,42 @@ public:
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0);
|
||||
virtual ~FluxViewerControl() {}
|
||||
|
||||
public:
|
||||
void SetScrollbar(wxScrollBar* scrollbar);
|
||||
void SetFlux(std::shared_ptr<const TrackFlux> flux);
|
||||
void SetScrollbar(wxScrollBar* scrollbar);
|
||||
void SetFlux(std::shared_ptr<const TrackFlux> flux);
|
||||
|
||||
private:
|
||||
void UpdateScale();
|
||||
void ShowSectorMenu(std::shared_ptr<const Sector> sector);
|
||||
void ShowRecordMenu(const Location& location, std::shared_ptr<const Record> record);
|
||||
void DisplayDecodedData(std::shared_ptr<const Sector> sector);
|
||||
void DisplayRawData(std::shared_ptr<const Sector> sector);
|
||||
void DisplayRawData(const Location& location, std::shared_ptr<const Record> record);
|
||||
void UpdateScale();
|
||||
void ShowSectorMenu(std::shared_ptr<const Sector> sector);
|
||||
void ShowRecordMenu(std::shared_ptr<const ::Layout>& layout,
|
||||
std::shared_ptr<const Record> record);
|
||||
void DisplayDecodedData(std::shared_ptr<const Sector> sector);
|
||||
void DisplayRawData(std::shared_ptr<const Sector> sector);
|
||||
void DisplayRawData(std::shared_ptr<const ::Layout>& layout,
|
||||
std::shared_ptr<const Record> record);
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent&);
|
||||
void OnMouseWheel(wxMouseEvent&);
|
||||
void OnScrollbarChanged(wxScrollEvent&);
|
||||
void OnMouseMotion(wxMouseEvent&);
|
||||
void OnContextMenu(wxContextMenuEvent&);
|
||||
void OnPaint(wxPaintEvent&);
|
||||
void OnMouseWheel(wxMouseEvent&);
|
||||
void OnScrollbarChanged(wxScrollEvent&);
|
||||
void OnMouseMotion(wxMouseEvent&);
|
||||
void OnContextMenu(wxContextMenuEvent&);
|
||||
|
||||
private:
|
||||
wxScrollBar* _scrollbar;
|
||||
std::shared_ptr<const TrackFlux> _flux;
|
||||
nanoseconds_t _scrollPosition = 0;
|
||||
nanoseconds_t _totalDuration = 0;
|
||||
double _nanosecondsPerPixel = 0;
|
||||
std::vector<float> _densityMap;
|
||||
int _dragStartX = -1;
|
||||
nanoseconds_t _dragStartPosition = -1;
|
||||
int _mouseX = -1;
|
||||
int _mouseY = -1;
|
||||
bool _rightClicked = false;
|
||||
wxScrollBar* _scrollbar;
|
||||
std::shared_ptr<const TrackFlux> _flux;
|
||||
nanoseconds_t _scrollPosition = 0;
|
||||
nanoseconds_t _totalDuration = 0;
|
||||
double _nanosecondsPerPixel = 0;
|
||||
std::vector<float> _densityMap;
|
||||
int _dragStartX = -1;
|
||||
nanoseconds_t _dragStartPosition = -1;
|
||||
int _mouseX = -1;
|
||||
int _mouseY = -1;
|
||||
bool _rightClicked = false;
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "fluxviewerwindow.h"
|
||||
#include "fluxviewercontrol.h"
|
||||
#include "lib/flux.h"
|
||||
#include "lib/layout.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
FluxViewerWindow::FluxViewerWindow(
|
||||
@@ -14,8 +15,8 @@ FluxViewerWindow::FluxViewerWindow(
|
||||
fluxviewer->SetScrollbar(scrollbar);
|
||||
fluxviewer->SetFlux(flux);
|
||||
SetTitle(fmt::format("Flux for c{} h{}",
|
||||
flux->location.physicalTrack,
|
||||
flux->location.physicalSide));
|
||||
flux->layout->physicalTrack,
|
||||
flux->layout->physicalSide));
|
||||
}
|
||||
|
||||
void FluxViewerWindow::OnExit(wxCommandEvent& event)
|
||||
|
||||
@@ -14,8 +14,7 @@ private:
|
||||
void OnExit(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
std::shared_ptr<const TrackFlux> _flux;
|
||||
std::shared_ptr<const TrackFlux> _flux;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,37 +14,37 @@ wxDECLARE_EVENT(UPDATE_STATE_EVENT, wxCommandEvent);
|
||||
template <typename R>
|
||||
static inline R runOnUiThread(std::function<R()> callback)
|
||||
{
|
||||
R retvar;
|
||||
runOnUiThread(
|
||||
[&]() {
|
||||
retvar = callback();
|
||||
}
|
||||
);
|
||||
return retvar;
|
||||
R retvar;
|
||||
runOnUiThread(
|
||||
[&]()
|
||||
{
|
||||
retvar = callback();
|
||||
});
|
||||
return retvar;
|
||||
}
|
||||
|
||||
class FluxEngineApp : public wxApp, public wxThreadHelper
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
void RunOnWorkerThread(std::function<void()> callback);
|
||||
void RunOnWorkerThread(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
void OnExec(const ExecEvent& event);
|
||||
void OnExec(const ExecEvent& event);
|
||||
|
||||
public:
|
||||
bool IsWorkerThreadRunning() const;
|
||||
bool IsWorkerThreadRunning() const;
|
||||
|
||||
protected:
|
||||
virtual wxThread::ExitCode Entry();
|
||||
virtual wxThread::ExitCode Entry();
|
||||
|
||||
private:
|
||||
static wxWindow* CreateMainWindow();
|
||||
void SendUpdateEvent();
|
||||
static wxWindow* CreateMainWindow();
|
||||
void SendUpdateEvent();
|
||||
|
||||
private:
|
||||
std::function<void()> _callback;
|
||||
wxWindow* _mainWindow;
|
||||
std::function<void()> _callback;
|
||||
wxWindow* _mainWindow;
|
||||
};
|
||||
wxDECLARE_APP(FluxEngineApp);
|
||||
|
||||
@@ -54,4 +54,3 @@ wxDECLARE_APP(FluxEngineApp);
|
||||
static const wxPen name##_PEN(name##_COLOUR)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1063
src/gui/icon.png.h
1063
src/gui/icon.png.h
File diff suppressed because it is too large
Load Diff
647
src/gui/layout.h
647
src/gui/layout.h
@@ -50,122 +50,223 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class MainWindowGen : public wxFrame
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxMenuBar* menuBar;
|
||||
wxMenu* m_menu1;
|
||||
wxMenu* m_menu2;
|
||||
wxSimplebook* dataNotebook;
|
||||
wxScrolledWindow* idlePanel;
|
||||
wxStaticBitmap* applicationBitmap;
|
||||
wxStaticText* m_staticText61;
|
||||
wxRadioButton* realDiskRadioButton;
|
||||
wxPanel* realDiskRadioButtonPanel;
|
||||
wxComboBox* deviceCombo;
|
||||
wxChoice* driveChoice;
|
||||
wxCheckBox* highDensityToggle;
|
||||
wxCheckBox* fortyTrackDriveToggle;
|
||||
wxRadioButton* fluxImageRadioButton;
|
||||
wxPanel* fluxImageRadioButtonPanel;
|
||||
wxFilePickerCtrl* fluxImagePicker;
|
||||
wxRadioButton* diskImageRadioButton;
|
||||
wxPanel* diskImageRadioButtonPanel;
|
||||
wxFilePickerCtrl* diskImagePicker;
|
||||
wxStaticText* m_staticText23;
|
||||
wxPanel* m_panel11;
|
||||
wxChoice* formatChoice;
|
||||
wxButton* customConfigurationButton;
|
||||
wxStaticText* m_staticText19;
|
||||
wxButton* readButton;
|
||||
wxButton* writeButton;
|
||||
wxButton* browseButton;
|
||||
wxButton* formatButton;
|
||||
wxPanel* imagePanel;
|
||||
wxAuiToolBar* imagerToolbar;
|
||||
wxAuiToolBarItem* imagerBackTool;
|
||||
VisualisationControl* visualiser;
|
||||
wxButton* imagerSaveImageButton;
|
||||
wxButton* imagerSaveFluxButton;
|
||||
wxStaticText* m_staticText4;
|
||||
wxButton* imagerGoAgainButton;
|
||||
wxPanel* browsePanel;
|
||||
wxAuiToolBar* browserToolbar;
|
||||
wxAuiToolBarItem* browserBackTool;
|
||||
wxAuiToolBarItem* browserInfoTool;
|
||||
wxAuiToolBarItem* browserViewTool;
|
||||
wxAuiToolBarItem* browserSaveTool;
|
||||
wxAuiToolBarItem* browserMoreMenuButton;
|
||||
wxMenu* browserMoreMenu;
|
||||
wxMenuItem* browserAddMenuItem;
|
||||
wxMenuItem* browserNewDirectoryMenuItem;
|
||||
wxMenuItem* browserRenameMenuItem;
|
||||
wxMenuItem* browserDeleteMenuItem;
|
||||
wxAuiToolBarItem* browserFormatTool;
|
||||
wxDataViewCtrl* browserTree;
|
||||
wxDataViewColumn* m_dataViewColumn1;
|
||||
wxDataViewColumn* m_dataViewColumn2;
|
||||
wxDataViewColumn* m_dataViewColumn3;
|
||||
wxGauge* diskSpaceGauge;
|
||||
wxButton* browserDiscardButton;
|
||||
wxButton* browserCommitButton;
|
||||
wxStaticText* m_staticText12;
|
||||
|
||||
protected:
|
||||
wxMenuBar* menuBar;
|
||||
wxMenu* m_menu1;
|
||||
wxMenu* m_menu2;
|
||||
wxSimplebook* dataNotebook;
|
||||
wxScrolledWindow* idlePanel;
|
||||
wxStaticBitmap* applicationBitmap;
|
||||
wxStaticText* m_staticText61;
|
||||
wxRadioButton* realDiskRadioButton;
|
||||
wxPanel* realDiskRadioButtonPanel;
|
||||
wxComboBox* deviceCombo;
|
||||
wxChoice* driveChoice;
|
||||
wxCheckBox* highDensityToggle;
|
||||
wxCheckBox* fortyTrackDriveToggle;
|
||||
wxRadioButton* fluxImageRadioButton;
|
||||
wxPanel* fluxImageRadioButtonPanel;
|
||||
wxFilePickerCtrl* fluxImagePicker;
|
||||
wxRadioButton* diskImageRadioButton;
|
||||
wxPanel* diskImageRadioButtonPanel;
|
||||
wxFilePickerCtrl* diskImagePicker;
|
||||
wxStaticText* m_staticText23;
|
||||
wxPanel* m_panel11;
|
||||
wxChoice* formatChoice;
|
||||
wxButton* customConfigurationButton;
|
||||
wxStaticText* m_staticText19;
|
||||
wxButton* readButton;
|
||||
wxButton* writeButton;
|
||||
wxButton* browseButton;
|
||||
wxButton* formatButton;
|
||||
wxPanel* imagePanel;
|
||||
wxAuiToolBar* imagerToolbar;
|
||||
wxAuiToolBarItem* imagerBackTool;
|
||||
VisualisationControl* visualiser;
|
||||
wxButton* imagerSaveImageButton;
|
||||
wxButton* imagerSaveFluxButton;
|
||||
wxStaticText* m_staticText4;
|
||||
wxButton* imagerGoAgainButton;
|
||||
wxPanel* browsePanel;
|
||||
wxAuiToolBar* browserToolbar;
|
||||
wxAuiToolBarItem* browserBackTool;
|
||||
wxAuiToolBarItem* browserInfoTool;
|
||||
wxAuiToolBarItem* browserViewTool;
|
||||
wxAuiToolBarItem* browserSaveTool;
|
||||
wxAuiToolBarItem* browserMoreMenuButton;
|
||||
wxMenu* browserMoreMenu;
|
||||
wxMenuItem* browserAddMenuItem;
|
||||
wxMenuItem* browserNewDirectoryMenuItem;
|
||||
wxMenuItem* browserRenameMenuItem;
|
||||
wxMenuItem* browserDeleteMenuItem;
|
||||
wxAuiToolBarItem* browserFormatTool;
|
||||
wxDataViewCtrl* browserTree;
|
||||
wxDataViewColumn* m_dataViewColumn1;
|
||||
wxDataViewColumn* m_dataViewColumn2;
|
||||
wxDataViewColumn* m_dataViewColumn3;
|
||||
wxGauge* diskSpaceGauge;
|
||||
wxButton* browserDiscardButton;
|
||||
wxButton* browserCommitButton;
|
||||
wxStaticText* m_staticText12;
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnAboutMenuItem(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnExit(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnShowLogWindow(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnShowConfigWindow(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnConfigRadioButtonClicked(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnControlsChanged(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnControlsChanged(wxFileDirPickerEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnCustomConfigurationButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnReadButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnWriteButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowseButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnFormatButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBackButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnSaveImageButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnSaveFluxButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnImagerGoAgainButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserInfoButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserViewButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserSaveButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserAddMenuItem(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserNewDirectoryMenuItem(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserRenameMenuItem(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserDeleteMenuItem(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserFormatButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserBeginDrag(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserDrop(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserDropPossible(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserFilenameChanged(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserDirectoryExpanding(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserSelectionChanged(wxDataViewEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserDiscardButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnBrowserCommitButton(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnAboutMenuItem( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnShowLogWindow( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnShowConfigWindow( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnConfigRadioButtonClicked( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnControlsChanged( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnControlsChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
|
||||
virtual void OnCustomConfigurationButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnReadButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnWriteButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowseButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnFormatButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBackButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSaveImageButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSaveFluxButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnImagerGoAgainButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserInfoButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserViewButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserSaveButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserAddMenuItem( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserNewDirectoryMenuItem( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserRenameMenuItem( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserDeleteMenuItem( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserFormatButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserBeginDrag( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserDrop( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserDropPossible( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserFilenameChanged( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserDirectoryExpanding( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserSelectionChanged( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserDiscardButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnBrowserCommitButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
public:
|
||||
MainWindowGen(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("FluxEngine"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxSize(616, 607),
|
||||
long style = wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER |
|
||||
wxFULL_REPAINT_ON_RESIZE | wxTAB_TRAVERSAL);
|
||||
|
||||
~MainWindowGen();
|
||||
|
||||
public:
|
||||
|
||||
MainWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("FluxEngine"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 616,607 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
|
||||
|
||||
~MainWindowGen();
|
||||
|
||||
void browserMoreMenuButtonOnDropDownMenu( wxAuiToolBarEvent &event )
|
||||
{
|
||||
if ( event.IsDropDownClicked() )
|
||||
{
|
||||
browserToolbar->SetToolSticky( event.GetId(), true );
|
||||
wxRect rect = browserToolbar->GetToolRect( event.GetId() );
|
||||
wxPoint pt = browserToolbar->ClientToScreen( rect.GetBottomLeft() );
|
||||
pt = ScreenToClient( pt );
|
||||
browserToolbar->PopupMenu( browserMoreMenu, pt );
|
||||
browserToolbar->SetToolSticky( event.GetId(), false );
|
||||
}
|
||||
}
|
||||
|
||||
void browserMoreMenuButtonOnDropDownMenu(wxAuiToolBarEvent& event)
|
||||
{
|
||||
if (event.IsDropDownClicked())
|
||||
{
|
||||
browserToolbar->SetToolSticky(event.GetId(), true);
|
||||
wxRect rect = browserToolbar->GetToolRect(event.GetId());
|
||||
wxPoint pt = browserToolbar->ClientToScreen(rect.GetBottomLeft());
|
||||
pt = ScreenToClient(pt);
|
||||
browserToolbar->PopupMenu(browserMoreMenu, pt);
|
||||
browserToolbar->SetToolSticky(event.GetId(), false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -173,24 +274,32 @@ class MainWindowGen : public wxFrame
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class TextViewerWindowGen : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxTextCtrl* textControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
|
||||
protected:
|
||||
wxTextCtrl* textControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnClose(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
TextViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 208,143 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
|
||||
|
||||
~TextViewerWindowGen();
|
||||
public:
|
||||
TextViewerWindowGen(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxSize(208, 143),
|
||||
long style = wxCLOSE_BOX | wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX |
|
||||
wxMINIMIZE_BOX | wxRESIZE_BORDER);
|
||||
|
||||
~TextViewerWindowGen();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -198,25 +307,33 @@ class TextViewerWindowGen : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class FluxViewerWindowGen : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
FluxViewerControl* fluxviewer;
|
||||
wxScrollBar* scrollbar;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
|
||||
protected:
|
||||
FluxViewerControl* fluxviewer;
|
||||
wxScrollBar* scrollbar;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnClose(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
FluxViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,200 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
|
||||
|
||||
~FluxViewerWindowGen();
|
||||
public:
|
||||
FluxViewerWindowGen(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxSize(400, 200),
|
||||
long style = wxCLOSE_BOX | wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX |
|
||||
wxMINIMIZE_BOX | wxRESIZE_BORDER);
|
||||
|
||||
~FluxViewerWindowGen();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -224,26 +341,37 @@ class FluxViewerWindowGen : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class TextEditorWindowGen : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxTextCtrl* textControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2Save;
|
||||
wxButton* m_sdbSizer2Cancel;
|
||||
|
||||
protected:
|
||||
wxTextCtrl* textControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2Save;
|
||||
wxButton* m_sdbSizer2Cancel;
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnCancel(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
virtual void OnSave(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnSave( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
TextEditorWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
|
||||
|
||||
~TextEditorWindowGen();
|
||||
public:
|
||||
TextEditorWindowGen(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxCLOSE_BOX | wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX |
|
||||
wxMINIMIZE_BOX | wxRESIZE_BORDER);
|
||||
|
||||
~TextEditorWindowGen();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -251,27 +379,32 @@ class TextEditorWindowGen : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class FileViewerWindowGen : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxNotebook* m_notebook1;
|
||||
wxPanel* m_panel8;
|
||||
wxTextCtrl* textControl;
|
||||
wxPanel* m_panel7;
|
||||
wxTextCtrl* hexControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
|
||||
protected:
|
||||
wxNotebook* m_notebook1;
|
||||
wxPanel* m_panel8;
|
||||
wxTextCtrl* textControl;
|
||||
wxPanel* m_panel7;
|
||||
wxTextCtrl* hexControl;
|
||||
wxStdDialogButtonSizer* m_sdbSizer2;
|
||||
wxButton* m_sdbSizer2OK;
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
FileViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 408,269 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
|
||||
|
||||
~FileViewerWindowGen();
|
||||
public:
|
||||
FileViewerWindowGen(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxEmptyString,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxSize(408, 269),
|
||||
long style = wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxMINIMIZE_BOX |
|
||||
wxRESIZE_BORDER);
|
||||
|
||||
~FileViewerWindowGen();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -279,23 +412,26 @@ class FileViewerWindowGen : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class GetfileDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
public:
|
||||
wxTextCtrl* filenameText;
|
||||
wxFilePickerCtrl* targetFilePicker;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
public:
|
||||
wxTextCtrl* filenameText;
|
||||
wxFilePickerCtrl* targetFilePicker;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
GetfileDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Copy file off disk"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
~GetfileDialog();
|
||||
GetfileDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("Copy file off disk"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
|
||||
~GetfileDialog();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -303,24 +439,27 @@ class GetfileDialog : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class FileConflictDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxTextCtrl* oldNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxTextCtrl* oldNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
FileConflictDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Filename conflict"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
~FileConflictDialog();
|
||||
FileConflictDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("Filename conflict"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
|
||||
~FileConflictDialog();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -328,24 +467,27 @@ class FileConflictDialog : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class FileRenameDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
wxStaticText* m_staticText9;
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxTextCtrl* oldNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxTextCtrl* oldNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
FileRenameDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Rename or move file"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
~FileRenameDialog();
|
||||
FileRenameDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("Rename or move file"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
|
||||
~FileRenameDialog();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -353,22 +495,25 @@ class FileRenameDialog : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CreateDirectoryDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText9;
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText9;
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
public:
|
||||
wxTextCtrl* newNameText;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
CreateDirectoryDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Create new directory"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
~CreateDirectoryDialog();
|
||||
CreateDirectoryDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("Create new directory"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
|
||||
~CreateDirectoryDialog();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -376,22 +521,24 @@ class CreateDirectoryDialog : public wxDialog
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class FormatDialog : public wxDialog
|
||||
{
|
||||
private:
|
||||
private:
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText91;
|
||||
wxStaticText* m_staticText7;
|
||||
public:
|
||||
wxTextCtrl* volumeNameText;
|
||||
wxCheckBox* quickFormatCheckBox;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
public:
|
||||
wxTextCtrl* volumeNameText;
|
||||
wxCheckBox* quickFormatCheckBox;
|
||||
wxStdDialogButtonSizer* buttons_;
|
||||
wxButton* buttons_OK;
|
||||
wxButton* buttons_Cancel;
|
||||
|
||||
FormatDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Format disk"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
~FormatDialog();
|
||||
FormatDialog(wxWindow* parent,
|
||||
wxWindowID id = wxID_ANY,
|
||||
const wxString& title = wxT("Format disk"),
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
|
||||
~FormatDialog();
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "customstatusbar.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/environment.h"
|
||||
#include "lib/layout.h"
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/aboutdlg.h>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "flux.h"
|
||||
#include "sector.h"
|
||||
#include "image.h"
|
||||
#include "lib/layout.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#define BORDER 20
|
||||
@@ -194,8 +195,8 @@ void VisualisationControl::OnPaint(wxPaintEvent&)
|
||||
std::string logicalText = "logical: (none)";
|
||||
if (it != _tracks.end())
|
||||
logicalText = fmt::format("logical: {}.{}",
|
||||
it->second->location.logicalTrack,
|
||||
it->second->location.logicalSide);
|
||||
it->second->layout->logicalTrack,
|
||||
it->second->layout->logicalSide);
|
||||
|
||||
centreText(logicalText, h - 35);
|
||||
}
|
||||
@@ -271,7 +272,7 @@ void VisualisationControl::Clear()
|
||||
|
||||
void VisualisationControl::SetTrackData(std::shared_ptr<const TrackFlux> track)
|
||||
{
|
||||
key_t key = {track->location.physicalTrack, track->location.physicalSide};
|
||||
key_t key = {track->layout->physicalTrack, track->layout->physicalSide};
|
||||
_tracks[key] = track;
|
||||
_sectors.erase(key);
|
||||
for (auto& sector : track->sectors)
|
||||
@@ -285,8 +286,7 @@ void VisualisationControl::SetDiskData(std::shared_ptr<const DiskFlux> disk)
|
||||
_sectors.clear();
|
||||
for (const auto& track : disk->tracks)
|
||||
{
|
||||
key_t key = {
|
||||
track->location.physicalTrack, track->location.physicalSide};
|
||||
key_t key = {track->layout->physicalTrack, track->layout->physicalSide};
|
||||
_tracks[key] = track;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user