Skip to content

Commit

Permalink
[#40] Track Map (Part 39: Minor improvements)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-nestorovic committed Oct 19, 2024
1 parent 3ae2c86 commit 6686126
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Main/src/CapsBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@
if (!params.verifyBadSectors) // remove Events that relate to Bad Sectors
for( auto i=nSectors; i>0; ){
const TPhysicalAddress chs={ cyl, head, ids[--i] };
if (dos->GetSectorStatus(chs)==CDos::TSectorStatus::BAD){
if (dos->GetSectorStatus(chs)==TSectorStatus::BAD){
peTrack.RemoveConsecutiveBeforeEnd( idEnds[i] );
peTrack.RemoveConsecutiveBeforeEnd( dataEnds[i] );
}
Expand Down
20 changes: 10 additions & 10 deletions Main/src/DialogVerification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@
CDos::CFatPath::PItem pItem; DWORD nItems;
for( rFatPath.GetItems(pItem,nItems); nItems--; pItem++ )
if (pItem->value) // if Sector cross-linked ...
dos->ModifyStdSectorStatus( pItem->chs, CDos::TSectorStatus::EMPTY ); // ... reverting its reservation, setting it Empty again
dos->ModifyStdSectorStatus( pItem->chs, TSectorStatus::EMPTY ); // ... reverting its reservation, setting it Empty again
}
} fatTransaction( vp.dos, fatPath );
// . checking that the File's FatPath is unique
Expand Down Expand Up @@ -443,7 +443,7 @@
}
}
// | reserving the found empty healthy Sector by marking it Bad so that it's excluded from available empty Sectors
if (vp.dos->ModifyStdSectorStatus( pItem->chs, CDos::TSectorStatus::BAD ))
if (vp.dos->ModifyStdSectorStatus( pItem->chs, TSectorStatus::BAD ))
pItem->value=1; // Sector succesfully reserved
else
return vp.TerminateAll(ERROR_NOT_SUPPORTED); // DOS unable to reserve the above Sector
Expand Down Expand Up @@ -583,10 +583,10 @@
TSectorId bufferId[(TSector)-1];
const TSector nSectors=vp.dos->GetListOfStdSectors( chs.cylinder, chs.head, bufferId );
// . verifying whether officially Occupied or Reserved Sectors are actually affiliated to any File
CDos::TSectorStatus statuses[(TSector)-1];
TSectorStatus statuses[(TSector)-1];
vp.dos->GetSectorStatuses( chs.cylinder, chs.head, nSectors, bufferId, statuses );
for( TSector s=0; s<nSectors; s++ )
if (statuses[s]==CDos::TSectorStatus::OCCUPIED || statuses[s]==CDos::TSectorStatus::RESERVED){
if (statuses[s]==TSectorStatus::OCCUPIED || statuses[s]==TSectorStatus::RESERVED){
// : checking preconditions
chs.sectorId=bufferId[s];
if (chs.sectorId.cylinder!=chs.cylinder
Expand Down Expand Up @@ -644,7 +644,7 @@
if (result==IDCANCEL)
return vp.CancelAll();
if (result==IDYES){
vp.dos->ModifyStdSectorStatus( chs, CDos::TSectorStatus::EMPTY );
vp.dos->ModifyStdSectorStatus( chs, TSectorStatus::EMPTY );
vp.fReport.CloseProblem(true);
}
break;
Expand All @@ -669,7 +669,7 @@
return vp.TerminateAll(ERROR_OPEN_FAILED); // errors shouldn't occur at this moment, but just to be sure
if (nItems!=1)
return vp.TerminateAll(ERROR_OPEN_FAILED); // errors shouldn't occur at this moment, but just to be sure
vp.dos->ModifyStdSectorStatus( pItem->chs, CDos::TSectorStatus::EMPTY );
vp.dos->ModifyStdSectorStatus( pItem->chs, TSectorStatus::EMPTY );
// : associating the lost Sector with the temporary File
pItem->chs=chs;
vp.dos->ModifyFileFatPath( file, fatPath );
Expand Down Expand Up @@ -697,19 +697,19 @@
TSectorId bufferId[(TSector)-1];
const TSector nSectors=vp.dos->GetListOfStdSectors( chs.cylinder, chs.head, bufferId );
// . determining whether the Track contains some Empty Sectors
CDos::TSectorStatus statuses[(TSector)-1];
TSectorStatus statuses[(TSector)-1];
vp.dos->GetSectorStatuses( chs.cylinder, chs.head, nSectors, bufferId, statuses );
bool trackContainsEmptySectors=false; // assumption
for( TSector s=0; s<nSectors; s++ )
trackContainsEmptySectors|=statuses[s]==CDos::TSectorStatus::EMPTY;
trackContainsEmptySectors|=statuses[s]==TSectorStatus::EMPTY;
// . if the Track contains no Empty Sectors, proceeding with the next Track
if (!trackContainsEmptySectors)
continue;
// . buffering Sectors from the same Track by the underlying Image, making them ready for IMMEDIATE usage
image->BufferTrackData( chs.cylinder, chs.head, Revolution::ANY_GOOD, bufferId, sectorIdAndPositionIdentity, nSectors );
// . determining healthiness of Empty Sectors
for( TSector s=0; s<nSectors; s++ )
if (statuses[s]==CDos::TSectorStatus::EMPTY){
if (statuses[s]==TSectorStatus::EMPTY){
chs.sectorId=bufferId[s];
if (!image->GetHealthySectorData(chs)){
const CString msg=Utils::SimpleFormat( _T("On %s, empty sector with %s is bad but is not marked so in the FAT."), chs.GetTrackIdDesc(vp.dos->formatBoot.nHeads), chs.sectorId.ToString() );
Expand All @@ -719,7 +719,7 @@
case IDNO:
continue;
}
vp.dos->ModifyStdSectorStatus( chs, CDos::TSectorStatus::BAD );
vp.dos->ModifyStdSectorStatus( chs, TSectorStatus::BAD );
vp.fReport.CloseProblem(true);
}
}
Expand Down
18 changes: 9 additions & 9 deletions Main/src/Dos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ reportError:Utils::Information(buf);
chs.sectorId=ids[--n];
d.dos->ModifyStdSectorStatus(
chs,
d.dos->image->GetHealthySectorData(chs) ? CDos::TSectorStatus::EMPTY : CDos::TSectorStatus::BAD
d.dos->image->GetHealthySectorData(chs) ? TSectorStatus::EMPTY : TSectorStatus::BAD
);
}

Expand Down Expand Up @@ -702,7 +702,7 @@ reportError:Utils::Information(buf);



CDos::TSectorStatus CDos::GetSectorStatus(RCPhysicalAddress chs) const{
TSectorStatus CDos::GetSectorStatus(RCPhysicalAddress chs) const{
// determines and returns the Status of the Sector on the specified PhysicalAddress
TSectorStatus result;
GetSectorStatuses( chs.cylinder, chs.head, 1, &chs.sectorId, &result );
Expand All @@ -712,13 +712,13 @@ reportError:Utils::Information(buf);
LPCTSTR CDos::GetSectorStatusText(RCPhysicalAddress chs) const{
// determines and returns the Status of the Sector on the specified PhysicalAddress
switch (GetSectorStatus(chs)){
case CDos::TSectorStatus::SYSTEM: return _T("System");
case CDos::TSectorStatus::UNAVAILABLE: return _T("Unavailable");
case CDos::TSectorStatus::SKIPPED: return _T("Skipped");
case CDos::TSectorStatus::BAD: return _T("Bad");
case CDos::TSectorStatus::OCCUPIED: return _T("Occupied");
case CDos::TSectorStatus::RESERVED: return _T("Reserved");
case CDos::TSectorStatus::EMPTY: return _T("Empty");
case TSectorStatus::SYSTEM: return _T("System");
case TSectorStatus::UNAVAILABLE: return _T("Unavailable");
case TSectorStatus::SKIPPED: return _T("Skipped");
case TSectorStatus::BAD: return _T("Bad");
case TSectorStatus::OCCUPIED: return _T("Occupied");
case TSectorStatus::RESERVED: return _T("Reserved");
case TSectorStatus::EMPTY: return _T("Empty");
default: return _T("Unknown");
}
}
Expand Down
11 changes: 0 additions & 11 deletions Main/src/Dos.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,6 @@
typedef PVOID PFile;
typedef LPCVOID PCFile;

typedef enum TSectorStatus:COLORREF{ // each value must be bigger than the biggest possible Sector length (typically 16384)
SYSTEM =0xff40ff, // e.g. reserved for root Directory
UNAVAILABLE =0x707070, // Sectors that are not included in FAT (e.g. beyond the FAT, or FAT Sector error)
SKIPPED =0xb8b8b8, // e.g. deleted Files in TR-DOS
BAD =0x0000ff,
OCCUPIED =0xffcc99,
RESERVED =0xffff99, // e.g. zero-length File in MDOS, or File with error during importing
EMPTY =0xffffff, // reported as unallocated
UNKNOWN =0x00ffff // any Sector whose ID doesn't match any ID from the standard format, e.g. ID={2,1,0,3} for an MDOS Sector
} *PSectorStatus;

typedef class CPathString sealed:protected CString{
mutable CString unicode;

Expand Down
2 changes: 1 addition & 1 deletion Main/src/Image_Dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
||
p.acceptance.anyErrorsOnUnknownSectors && !dp.dos->IsStdSector(p.chs)
||
p.acceptance.anyErrorsOnEmptySectors && dp.dos->GetSectorStatus(p.chs)==CDos::TSectorStatus::EMPTY
p.acceptance.anyErrorsOnEmptySectors && dp.dos->GetSectorStatus(p.chs)==TSectorStatus::EMPTY
)
)
){
Expand Down
52 changes: 33 additions & 19 deletions Main/src/ViewTrackMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,9 @@
longestTrackNanoseconds=nNanosecondsOnTrack;
outdated|=showTimed;
}
const Utils::TClientRect rc(m_hWnd);
if (outdated)
if (fitLongestTrackInWindow){
CRect rc;
GetClientRect(&rc);
zoomLengthFactor = showTimed
? TTrackLength::FromTime(longestTrackNanoseconds,nNanosecondsPerByte).GetZoomFactorToFitWidth(rc.Width())
: longestTrack.GetZoomFactorToFitWidth(rc.Width());
Expand All @@ -334,12 +333,10 @@
// - basic drawing
CClientDC dc(this);
OnPrepareDC(&dc);
CRect rc;
GetClientRect(&rc);
::SetBkMode(dc,TRANSPARENT);
const HGDIOBJ font0=::SelectObject(dc,Utils::CRideFont::Std);
TCHAR buf[16];
// : drawing Cylinder and Side numbers
// : drawing Cylinder and Head numbers
const int y=TRACK0_Y+trackNumber*TRACK_HEIGHT;
if (const THead head=ti.head)
::wsprintf(buf,_T("\t\t%d"),head);
Expand All @@ -354,15 +351,14 @@
const HGDIOBJ hBrush0=::SelectObject(dc,Utils::CRideBrush::White);
if (displayType==TDisplayType::STATUS){
// drawing Sector Statuses
CDos::TSectorStatus statuses[(TSector)-1];
TSectorStatus statuses[(TSector)-1];
DOS->GetSectorStatuses( ti.cylinder, ti.head, ti.nSectors, ti.bufferId, statuses );
for( TSector s=0; s<ti.nSectors; s++ ){
r.left=sectorStartPixels[s];
r.right=r.left+1+(ti.bufferLength[s]>>zoomLengthFactor); // "1+" = to correctly display a zero-length Sector
if (iScrollX<r.right || r.left<iScrollX+rc.Width()){
// Sector in horizontally visible part of the TrackMap
const CBrush brush(statuses[s]);
const HGDIOBJ hBrush0=::SelectObject(dc,brush);
const HGDIOBJ hBrush0=::SelectObject( dc, statusBrushes[statuses[s]] );
dc.Rectangle(&r);
if (showSectorNumbers) // drawing Sector numbers
::DrawText( dc, _itot(ti.bufferId[s].sector,buf,10),-1, &r, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
Expand Down Expand Up @@ -496,6 +492,20 @@
SetScrollPos( SB_VERT, iScrollY, FALSE );
// - updating the MainWindow's StatusBar
ResetStatusBarMessage();
// - creating StatusBrushes
static constexpr COLORREF StatusColors[]={
0xff40ff, // SYSTEM
0x707070, // UNAVAILABLE
0xb8b8b8, // SKIPPED
0x0000ff, // BAD
0xffcc99, // OCCUPIED
0xffff99, // RESERVED
0xffffff, // EMPTY
0x00ffff // UNKNOWN
};
static_assert( ARRAYSIZE(StatusColors)==ARRAYSIZE(statusBrushes), "" );
for( BYTE i=0; i<ARRAYSIZE(statusBrushes); i++ )
statusBrushes[i]=(HBRUSH)CBrush(StatusColors[i]).Detach();
// - creating RainbowBrushes, see "Using out-of-phase sine waves to make rainbows" at http://krazydad.com/tutorials/makecolors.php
for( int t=TRACK_MAP_COLORS_COUNT; t--; )
rainbowBrushes[t]=(HBRUSH)CBrush( RGB( 128 + 127*sin( (float)2*M_PI*t/TRACK_MAP_COLORS_COUNT ),
Expand Down Expand Up @@ -722,8 +732,12 @@
// - saving scrolling position for later
iScrollX=GetScrollPos(SB_HORZ);
iScrollY=GetScrollPos(SB_VERT);
// - disposing the RainbowPens (assuming that the FillerByte color is a stock object)
for( int t=TRACK_MAP_COLORS_COUNT; t--; ::DeleteObject(rainbowBrushes[t]) );
// - disposing the StatusBrushes
for each( HBRUSH hBrush in statusBrushes)
::DeleteObject(hBrush);
// - disposing the RainbowBrushes (assuming that the FillerByte color is a stock object)
for each( HBRUSH hBrush in rainbowBrushes)
::DeleteObject(hBrush);
// - base
EXCLUSIVELY_LOCK_IMAGE(*IMAGE);
__super::OnDestroy();
Expand Down Expand Up @@ -880,17 +894,17 @@
WORD bufferLength[(TSector)-1];
TSector nSectors=image->ScanTrack(cyl,head,nullptr,bufferId,bufferLength);
rsp.sectors.nTotally+=nSectors;
CDos::TSectorStatus statuses[(TSector)-1];
TSectorStatus statuses[(TSector)-1];
for( rsp.dos->GetSectorStatuses(cyl,head,nSectors,bufferId,statuses); nSectors--; )
switch (statuses[nSectors]){
case CDos::TSectorStatus::SYSTEM :rsp.sectors.nSystem++; break;
case CDos::TSectorStatus::BAD :rsp.sectors.nBad++; break;
case CDos::TSectorStatus::OCCUPIED :rsp.sectors.nOccupied++; break;
case CDos::TSectorStatus::RESERVED :rsp.sectors.nReserved++; break;
case CDos::TSectorStatus::EMPTY :rsp.sectors.nFree++; break;
case CDos::TSectorStatus::SKIPPED :
case CDos::TSectorStatus::UNAVAILABLE:rsp.sectors.nInaccessible++; break;
case CDos::TSectorStatus::UNKNOWN :rsp.sectors.nUnknown++; break;
case TSectorStatus::SYSTEM :rsp.sectors.nSystem++; break;
case TSectorStatus::BAD :rsp.sectors.nBad++; break;
case TSectorStatus::OCCUPIED :rsp.sectors.nOccupied++; break;
case TSectorStatus::RESERVED :rsp.sectors.nReserved++; break;
case TSectorStatus::EMPTY :rsp.sectors.nFree++; break;
case TSectorStatus::SKIPPED :
case TSectorStatus::UNAVAILABLE:rsp.sectors.nInaccessible++; break;
case TSectorStatus::UNKNOWN :rsp.sectors.nUnknown++; break;
#ifdef _DEBUG
default: ASSERT(FALSE); // unknown Status
#endif
Expand Down
12 changes: 12 additions & 0 deletions Main/src/ViewTrackMap.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#ifndef TRACKMAPVIEW_H
#define TRACKMAPVIEW_H

typedef enum TSectorStatus:BYTE{
SYSTEM, // e.g. reserved for root Directory
UNAVAILABLE,// Sectors that are not included in FAT (e.g. beyond the FAT, or FAT Sector error)
SKIPPED, // e.g. deleted Files in TR-DOS
BAD,
OCCUPIED,
RESERVED, // e.g. zero-length File in MDOS, or File with error during importing
EMPTY, // reported as unallocated
UNKNOWN // any Sector whose ID doesn't match any ID from the standard format, e.g. ID={2,1,0,3} for an MDOS Sector
} *PSectorStatus;

#define TRACK_MAP_TAB_LABEL _T("Track map")

#define TRACK_MAP_COLORS_COUNT 256
Expand Down Expand Up @@ -30,6 +41,7 @@
DATA_OK_ONLY=ID_TRACKMAP_DATA,
DATA_ALL =ID_TRACKMAP_BAD_DATA
} displayType;
HBRUSH statusBrushes[TSectorStatus::UNKNOWN+1];
HBRUSH rainbowBrushes[TRACK_MAP_COLORS_COUNT];
struct TTrackScanner sealed{
static UINT AFX_CDECL Thread(PVOID _pBackgroundAction);
Expand Down

0 comments on commit 6686126

Please sign in to comment.