[Scummvm-git-logs] scummvm master -> 2a01424f0e94e40f697bf748fad6e69a3ee4baa3

fuzzie fuzzie at fuzzie.org
Fri Dec 9 09:35:27 CET 2016


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2a01424f0e ADL: Support wrapped sectors in NIB files.


Commit: 2a01424f0e94e40f697bf748fad6e69a3ee4baa3
    https://github.com/scummvm/scummvm/commit/2a01424f0e94e40f697bf748fad6e69a3ee4baa3
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-12-09T09:34:59+01:00

Commit Message:
ADL: Support wrapped sectors in NIB files.

Changed paths:
    engines/adl/disk.cpp


diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index d429556..0de740e 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -39,11 +39,13 @@ static Common::SeekableReadStream *readImage(const Common::String &filename) {
 	return f;
 }
 
+const uint trackLen = 256 * 26;
+
 // 4-and-4 encoding (odd-even)
-static uint8 read44(Common::SeekableReadStream &f) {
+static uint8 read44(byte *buffer, uint &pos) {
 	// 1s in the other fields, so we can just AND
-	uint8 ret = f.readByte();
-	return ((ret << 1) | 1) & f.readByte();
+	uint8 ret = buffer[pos++ % trackLen];
+	return ((ret << 1) | 1) & buffer[pos++ % trackLen];
 }
 
 static Common::SeekableReadStream *readImage_NIB(const Common::String &filename) {
@@ -70,15 +72,27 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 	uint8 volNo, track, sector;
 	bool newStyle;
 
-	while (f.pos() < f.size()) {
+	byte buffer[trackLen];
+	uint firstGoodTrackPos = 0;
+	uint pos = trackLen; // force read
+
+	while (true) {
+		if (pos >= trackLen+firstGoodTrackPos) {
+			if (f.pos() == f.size())
+				break;
+			f.read(buffer, sizeof(buffer));
+			firstGoodTrackPos = 0;
+			pos = 0;
+			sawAddress = false;
+		}
+
 		// Read until we find two sync bytes.
-		if (f.readByte() != 0xd5 || f.readByte() != 0xaa)
+		if (buffer[pos++ % trackLen] != 0xd5 || buffer[pos++ % trackLen] != 0xaa)
 			continue;
 
-		byte prologue = f.readByte();
+		byte prologue = buffer[pos++ % trackLen];
 
 		if (sawAddress && (prologue == 0xb5 || prologue == 0x96)) {
-			warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
 			sawAddress = false;
 		}
 
@@ -91,18 +105,24 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 				// Accept a DOS 3.3(?) header at the start.
 				if (prologue == 0x96) {
 					newStyle = true;
+				} else if (prologue == 0xad || prologue == 0xfd) {
+					sawAddress = false;
+					continue;
 				} else {
 					error("unknown NIB field prologue %02x", prologue);
 				}
 			}
 
-			volNo = read44(f);
-			track = read44(f);
-			sector = read44(f);
-			uint8 checksum = read44(f);
+			volNo = read44(buffer, pos);
+			track = read44(buffer, pos);
+			sector = read44(buffer, pos);
+			uint8 checksum = read44(buffer, pos);
 			if ((volNo ^ track ^ sector) != checksum)
 				error("invalid NIB checksum");
 
+			if (!firstGoodTrackPos)
+				firstGoodTrackPos = pos;
+
 			// Epilogue is de/aa plus a gap, but we don't care.
 			continue;
 		}
@@ -121,7 +141,13 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 
 			// 6-and-2 uses 342 on-disk bytes
 			byte inbuffer[342];
-			f.read(inbuffer, 342);
+			uint z = trackLen - (pos % trackLen);
+			if (z < 342) {
+				memcpy(inbuffer, buffer + (pos % trackLen), z);
+				memcpy(inbuffer + z, buffer, 342 - z);
+			} else
+				memcpy(inbuffer, buffer + (pos % trackLen), 342);
+			pos += 342;
 
 			byte oldVal = 0;
 			for (uint n = 0; n < 342; ++n) {
@@ -136,7 +162,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 				inbuffer[n] = oldVal;
 			}
 
-			byte checksum = f.readByte();
+			byte checksum = buffer[pos++ % trackLen];
 			if (checksum < 0x96 || oldVal != c_6and2_lookup[checksum - 0x96])
 				warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
 
@@ -156,7 +182,13 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 		} else {
 			// 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
 			byte inbuffer[410];
-			f.read(inbuffer, 410);
+			uint z = trackLen - (pos % trackLen);
+			if (z < 410) {
+				memcpy(inbuffer, buffer + (pos % trackLen), z);
+				memcpy(inbuffer + z, buffer, 410 - z);
+			} else
+				memcpy(inbuffer, buffer + (pos % trackLen), 410);
+			pos += 410;
 
 			bool truncated = false;
 			byte oldVal = 0;
@@ -166,7 +198,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 				if (inbuffer[n] == 0xd5) {
 					// Early end of block.
 					truncated = true;
-					f.seek(-(410 - n), SEEK_CUR);
+					pos -= (410 - n);
 					warning("NIB: early end of block @ 0x%x (%x, %x)", f.pos(), track, sector);
 					break;
 				}
@@ -175,7 +207,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 					// Badly-encoded nibbles, stop trying to decode here.
 					truncated = true;
 					warning("NIB: bad nibble %02x @ 0x%x (%x, %x)", inbuffer[n], f.pos(), track, sector);
-					f.seek(-(410 - n), SEEK_CUR);
+					pos -= (410 - n);
 					break;
 				}
 				// undo checksum
@@ -183,7 +215,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
 				inbuffer[n] = oldVal;
 			}
 			if (!truncated) {
-				byte checksum = f.readByte();
+				byte checksum = buffer[pos++ % trackLen];
 				if (checksum < 0xaa || oldVal != c_5and3_lookup[checksum - 0xaa])
 					warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
 			}





More information about the Scummvm-git-logs mailing list