Mesen-S/Core/Spc7110Decomp.h
2020-02-16 21:11:01 -05:00

58 lines
1.6 KiB
C++

#pragma once
#include "stdafx.h"
#include "../Utilities/ISerializable.h"
//Based on bsnes' code (by byuu)
//original implementation: neviksti
//optimized implementation: talarubi
class Spc7110;
class Spc7110Decomp : public ISerializable
{
private:
enum : uint32_t { MPS = 0, LPS = 1 };
enum : uint32_t { One = 0xAA, Half = 0x55, Max = 0xFF };
struct ModelState
{
uint8_t probability; //of the more probable symbol (MPS)
uint8_t next[2]; //next state after output {MPS, LPS}
};
static ModelState evolution[53];
struct Context
{
uint8_t prediction; //current model state
uint8_t swap; //if 1, exchange the role of MPS and LPS
};
Context _context[5][15]; //not all 75 contexts exists; this simplifies the code
Spc7110* _spc;
uint32_t _bpp; //bits per pixel (1bpp = 1; 2bpp = 2; 4bpp = 4)
uint32_t _offset; //SPC7110 data ROM read offset
uint32_t _bits; //bits remaining in input
uint16_t _range; //arithmetic range: technically 8-bits, but Max+1 = 256
uint16_t _input; //input data from SPC7110 data ROM
uint8_t _output;
uint64_t _pixels;
uint64_t _colormap; //most recently used list
uint32_t _result; //decompressed word after calling decode()
private:
uint8_t ReadByte();
uint32_t Deinterleave(uint64_t data, uint32_t bits);
uint64_t MoveToFront(uint64_t list, uint32_t nibble);
public:
Spc7110Decomp(Spc7110* spc);
virtual ~Spc7110Decomp();
void Initialize(uint32_t mode, uint32_t origin);
void Decode();
uint32_t GetResult();
uint8_t GetBpp();
void Serialize(Serializer& s) override;
};