mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-31 11:17:01 -07:00 
			
		
		
		
	formatspecs, making for much cleaner code. Reformatted everything. This actually happened in multiple steps but then I corrupted my local repository and I had to recover from the working tree.
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "globals.h"
 | |
| #include "decoders/decoders.h"
 | |
| #include "amiga.h"
 | |
| #include "bytes.h"
 | |
| #include "fmt/format.h"
 | |
| 
 | |
| uint32_t amigaChecksum(const Bytes& bytes)
 | |
| {
 | |
|     ByteReader br(bytes);
 | |
|     uint32_t checksum = 0;
 | |
| 
 | |
|     assert((bytes.size() & 3) == 0);
 | |
|     while (!br.eof())
 | |
|         checksum ^= br.read_be32();
 | |
| 
 | |
|     return checksum & 0x55555555;
 | |
| }
 | |
| 
 | |
| static uint8_t everyother(uint16_t x)
 | |
| {
 | |
|     /* aabb ccdd eeff gghh */
 | |
|     x &= 0x6666; /* 0ab0 0cd0 0ef0 0gh0 */
 | |
|     x >>= 1;     /* 00ab 00cd 00ef 00gh */
 | |
|     x |= x << 2; /* abab cdcd efef ghgh */
 | |
|     x &= 0x3c3c; /* 00ab cd00 00ef gh00 */
 | |
|     x >>= 2;     /* 0000 abcd 0000 efgh */
 | |
|     x |= x >> 4; /* 0000 abcd abcd efgh */
 | |
|     return x;
 | |
| }
 | |
| 
 | |
| Bytes amigaInterleave(const Bytes& input)
 | |
| {
 | |
|     Bytes output;
 | |
|     ByteWriter bw(output);
 | |
| 
 | |
|     /* Write all odd bits. (Numbering starts at 0...) */
 | |
| 
 | |
|     {
 | |
|         ByteReader br(input);
 | |
|         while (!br.eof())
 | |
|         {
 | |
|             uint16_t x = br.read_be16();
 | |
|             x &= 0xaaaa;       /* a0b0 c0d0 e0f0 g0h0 */
 | |
|             x |= x >> 1;       /* aabb ccdd eeff gghh */
 | |
|             x = everyother(x); /* 0000 0000 abcd efgh */
 | |
|             bw.write_8(x);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Write all even bits. */
 | |
| 
 | |
|     {
 | |
|         ByteReader br(input);
 | |
|         while (!br.eof())
 | |
|         {
 | |
|             uint16_t x = br.read_be16();
 | |
|             x &= 0x5555;       /* 0a0b 0c0d 0e0f 0g0h */
 | |
|             x |= x << 1;       /* aabb ccdd eeff gghh */
 | |
|             x = everyother(x); /* 0000 0000 abcd efgh */
 | |
|             bw.write_8(x);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return output;
 | |
| }
 | |
| 
 | |
| Bytes amigaDeinterleave(const uint8_t*& input, size_t len)
 | |
| {
 | |
|     assert(!(len & 1));
 | |
|     const uint8_t* odds = &input[0];
 | |
|     const uint8_t* evens = &input[len / 2];
 | |
|     Bytes output;
 | |
|     ByteWriter bw(output);
 | |
| 
 | |
|     for (size_t i = 0; i < len / 2; i++)
 | |
|     {
 | |
|         uint8_t o = *odds++;
 | |
|         uint8_t e = *evens++;
 | |
| 
 | |
|         /* This is the 'Interleave bits with 64-bit multiply' technique from
 | |
|          * http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
 | |
|          */
 | |
|         uint16_t result =
 | |
|             (((e * 0x0101010101010101ULL & 0x8040201008040201ULL) *
 | |
|                      0x0102040810204081ULL >>
 | |
|                  49) &
 | |
|                 0x5555) |
 | |
|             (((o * 0x0101010101010101ULL & 0x8040201008040201ULL) *
 | |
|                      0x0102040810204081ULL >>
 | |
|                  48) &
 | |
|                 0xAAAA);
 | |
| 
 | |
|         bw.write_be16(result);
 | |
|     }
 | |
| 
 | |
|     input += len;
 | |
|     return output;
 | |
| }
 | |
| 
 | |
| Bytes amigaDeinterleave(const Bytes& input)
 | |
| {
 | |
|     const uint8_t* ptr = input.cbegin();
 | |
|     return amigaDeinterleave(ptr, input.size());
 | |
| }
 |