1 // This file is a part of Mesen
2 // It is a heavily modified version of the zmbv.h/cpp file found in DOSBox's code.
3 
4 /*
5  *  Copyright (C) 2002-2011  The DOSBox Team
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #pragma once
23 
24 #include "BaseCodec.h"
25 #include "miniz.h"
26 
27 #ifdef _MSC_VER
28 #define INLINE __forceinline
29 #else
30 #define INLINE inline
31 #endif
32 
33 typedef enum {
34 	ZMBV_FORMAT_NONE		= 0x00,
35 	ZMBV_FORMAT_1BPP		= 0x01,
36 	ZMBV_FORMAT_2BPP		= 0x02,
37 	ZMBV_FORMAT_4BPP		= 0x03,
38 	ZMBV_FORMAT_8BPP		= 0x04,
39 	ZMBV_FORMAT_15BPP	= 0x05,
40 	ZMBV_FORMAT_16BPP	= 0x06,
41 	ZMBV_FORMAT_24BPP	= 0x07,
42 	ZMBV_FORMAT_32BPP	= 0x08
43 } zmbv_format_t;
44 
45 class ZmbvCodec : public BaseCodec
46 {
47 private:
48 	struct FrameBlock {
49 		int start = 0;
50 		int dx = 0,dy = 0;
51 	};
52 	struct CodecVector {
53 		int x = 0,y = 0;
54 		int slot = 0;
55 	};
56 	struct KeyframeHeader {
57 		unsigned char high_version = 0;
58 		unsigned char low_version = 0;
59 		unsigned char compression = 0;
60 		unsigned char format = 0;
61 		unsigned char blockwidth = 0,blockheight = 0;
62 	};
63 
64 	struct {
65 		int		linesDone = 0;
66 		int		writeSize = 0;
67 		int		writeDone = 0;
68 		unsigned char	*writeBuf = nullptr;
69 	} compressInfo;
70 
71 	CodecVector VectorTable[512] = {};
72 	int VectorCount = 0;
73 
74 	unsigned char *oldframe=nullptr, *newframe=nullptr;
75 	unsigned char *buf1=nullptr, *buf2=nullptr, *work=nullptr;
76 	int bufsize = 0;
77 
78 	int blockcount = 0;
79 	FrameBlock * blocks = nullptr;
80 
81 	int workUsed = 0, workPos = 0;
82 
83 	int palsize = 0;
84 	char palette[256*4] = {};
85 	int height = 0, width = 0, pitch = 0;
86 	zmbv_format_t format = zmbv_format_t::ZMBV_FORMAT_NONE;
87 	int pixelsize = 0;
88 
89 	uint8_t* _buf = nullptr;
90 	uint32_t _bufSize = 0;
91 
92 	z_stream zstream = {};
93 
94 	// methods
95 	void FreeBuffers(void);
96 	void CreateVectorTable(void);
97 	bool SetupBuffers(zmbv_format_t format, int blockwidth, int blockheight);
98 
99 	template<class P> void AddXorFrame(void);
100 	template<class P> INLINE int PossibleBlock(int vx,int vy,FrameBlock * block);
101 	template<class P> INLINE int CompareBlock(int vx,int vy,FrameBlock * block);
102 	template<class P> INLINE void AddXorBlock(int vx,int vy,FrameBlock * block);
103 
104 	int NeededSize(int _width, int _height, zmbv_format_t _format);
105 
106 	void CompressLines(int lineCount, void *lineData[]);
107 	bool PrepareCompressFrame(int flags, zmbv_format_t _format, char * pal);
108 	int FinishCompressFrame(uint8_t** compressedData);
109 
110 public:
111 	ZmbvCodec();
112 	bool SetupCompress(int _width, int _height, uint32_t compressionLevel) override;
113 	int CompressFrame(bool isKeyFrame, uint8_t *frameData, uint8_t** compressedData) override;
114 	const char* GetFourCC() override;
115 };
116