forked from audetto/AppleWin
/
Video.h
321 lines (267 loc) · 9.56 KB
/
Video.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#pragma once
// in Windows it seems that the ALPHA value is irrelevant
// we have selected 0xFF since it works everywhere
// Windows
// SDL (SDL_PIXELFORMAT_ARGB8888)
// Qt (QImage::Format_ARGB32_Premultiplied)
#define ALPHA 0xFF // fully opaque
#define ALPHA32_MASK (ALPHA << 24)
#define SETRGBCOLOR(r, g, b) {b, g, r, ALPHA} // to create a RGBQUAD
#define OPAQUE_BLACK (0 | ALPHA32_MASK) // Black is RGB 0 0 0
// Types ____________________________________________________________
// NOTE: KEEP IN SYNC: VideoType_e g_aVideoChoices g_apVideoModeDesc
// NOTE: Used/Serialized by: g_eVideoType
enum VideoType_e
{
VT_MONO_CUSTOM
, VT_COLOR_IDEALIZED // Color rendering from AppleWin 1.25 (GH#357)
, VT_COLOR_VIDEOCARD_RGB // Real RGB card rendering
, VT_COLOR_MONITOR_NTSC // NTSC or PAL
, VT_COLOR_TV
, VT_MONO_TV
, VT_MONO_AMBER
, VT_MONO_GREEN
, VT_MONO_WHITE
, NUM_VIDEO_MODES
, VT_DEFAULT = VT_COLOR_TV
};
extern TCHAR g_aVideoChoices[];
enum VideoStyle_e
{
VS_NONE=0,
VS_HALF_SCANLINES=1, // drop 50% scan lines for a more authentic look
VS_COLOR_VERTICAL_BLEND=2, // Color "TV Emu" rendering from AppleWin 1.25 (GH#616)
// VS_TEXT_OPTIMIZED=4,
};
enum VideoRefreshRate_e
{
VR_NONE,
VR_50HZ,
VR_60HZ
};
enum VideoFlag_e
{
VF_80COL = 0x00000001,
VF_DHIRES = 0x00000002,
VF_HIRES = 0x00000004,
VF_80STORE= 0x00000008,
VF_MIXED = 0x00000010,
VF_PAGE2 = 0x00000020,
VF_TEXT = 0x00000040,
VF_SHR = 0x00000080 // For VidHD's support for IIgs SHR video modes
};
enum AppleFont_e
{
// 40-Column mode is 1x Zoom (default)
// 80-Column mode is ~0.75x Zoom (7 x 16)
// Tiny mode is 0.5 zoom (7x8) for debugger
APPLE_FONT_WIDTH = 14, // in pixels
APPLE_FONT_HEIGHT = 16, // in pixels
// Each cell has a reserved aligned pixel area (grid spacing)
APPLE_FONT_CELL_WIDTH = 16,
APPLE_FONT_CELL_HEIGHT = 16,
// The bitmap contains 3 regions
// Each region is 256x256 pixels = 16x16 chars
APPLE_FONT_X_REGIONSIZE = 256, // in pixelx
APPLE_FONT_Y_REGIONSIZE = 256, // in pixels
// Starting Y offsets (pixels) for the regions
APPLE_FONT_Y_APPLE_2PLUS = 0, // ][+
APPLE_FONT_Y_APPLE_80COL = 256, // //e (inc. Mouse Text)
APPLE_FONT_Y_APPLE_40COL = 512, // ][
};
// turn on struct member padding
#pragma pack(push,1)
// TODO: Replace with WinGDI.h / RGBQUAD
struct bgra_t
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a; // reserved on Win32
};
struct WinBmpHeader_t
{
// BITMAPFILEHEADER // Addr Size
uint8_t nCookie[2] ; // 0x00 0x02 BM
uint32_t nSizeFile ; // 0x02 0x04 0 = ignore
uint16_t nReserved1 ; // 0x06 0x02
uint16_t nReserved2 ; // 0x08 0x02
uint32_t nOffsetData ; // 0x0A 0x04
// == 0x0D (14)
// BITMAPINFOHEADER
uint32_t nStructSize ; // 0x0E 0x04 biSize
uint32_t nWidthPixels ; // 0x12 0x04 biWidth
uint32_t nHeightPixels ; // 0x16 0x04 biHeight
uint16_t nPlanes ; // 0x1A 0x02 biPlanes
uint16_t nBitsPerPixel ; // 0x1C 0x02 biBitCount
uint32_t nCompression ; // 0x1E 0x04 biCompression 0 = BI_RGB
uint32_t nSizeImage ; // 0x22 0x04 0 = ignore
uint32_t nXPelsPerMeter ; // 0x26 0x04
uint32_t nYPelsPerMeter ; // 0x2A 0x04
uint32_t nPaletteColors ; // 0x2E 0x04
uint32_t nImportantColors; // 0x32 0x04
// == 0x28 (40)
// RGBQUAD
// pixelmap
};
struct WinCIEXYZ
{
uint32_t r; // fixed point 2.30
uint32_t g; // fixed point 2.30
uint32_t b; // fixed point 2.30
};
struct WinBmpHeader4_t
{
// BITMAPFILEHEADER // Addr Size
uint8_t nCookie[2] ; // 0x00 0x02 BM
uint32_t nSizeFile ; // 0x02 0x04 0 = ignore
uint16_t nReserved1 ; // 0x06 0x02
uint16_t nReserved2 ; // 0x08 0x02
uint32_t nOffsetData ; // 0x0A 0x04
// ==== 0x0D (14)
// BITMAPINFOHEADER
uint32_t nStructSize ; // 0x0E 0x04 biSize
uint32_t nWidthPixels ; // 0x12 0x04 biWidth
uint32_t nHeightPixels ; // 0x16 0x04 biHeight
uint16_t nPlanes ; // 0x1A 0x02 biPlanes
uint16_t nBitsPerPixel ; // 0x1C 0x02 biBitCount
uint32_t nCompression ; // 0x1E 0x04 biCompression 0 = BI_RGB
uint32_t nSizeImage ; // 0x22 0x04 0 = ignore
uint32_t nXPelsPerMeter ; // 0x26 0x04
uint32_t nYPelsPerMeter ; // 0x2A 0x04
uint32_t nPaletteColors ; // 0x2E 0x04
uint32_t nImportantColors; // 0x32 0x04
// ==== 0x28 (40)
//BITMAPV4HEADER new fields
uint32_t nRedMask ; // 0x36 0x04
uint32_t nGreenMask ; // 0x3A 0x04
uint32_t nBlueMask ; // 0x3E 0x04
uint32_t nAlphaMask ; // 0x42 0x04
uint32_t nType ; // 0x46 0x04
uint32_t Rx, Ry, Rz ; // 0x4A 0x0C
uint32_t Gx, Gy, Gz ; // 0x56 0x0C
uint32_t Bx, By, Bz ; // 0x62 0x0C
uint32_t nRedGamma ; // 0x6E 0x04
uint32_t nGreenGamma ; // 0x72 0x04
uint32_t nBlueGamma ; // 0x76 0x04
};
#pragma pack(pop)
//
class Video
{
public:
Video(void)
{
g_pFramebufferbits = NULL; // last drawn frame (initialized in WinVideoInitialize)
g_nAltCharSetOffset = 0;
g_uVideoMode = VF_TEXT;
g_eVideoType = VT_DEFAULT;
g_eVideoStyle = VS_HALF_SCANLINES;
g_bVideoScannerNTSC = true;
g_nMonochromeRGB = RGB(0xC0,0xC0,0xC0);
g_videoRomSize = 0;
g_videoRomRockerSwitch = false;
m_hasVidHD = false;
}
~Video(void){}
void Initialize(uint8_t* frameBuffer, bool resetState); // Do not call directly. Call FrameBase::Initialize()
void Destroy(void); // Call FrameBase::Destroy()
uint8_t* GetFrameBuffer(void) { return g_pFramebufferbits; }
// size of the video buffer stored in g_pFramebufferbits
UINT GetFrameBufferBorderlessWidth(void);
UINT GetFrameBufferBorderlessHeight(void);
UINT GetFrameBufferBorderWidth(void);
UINT GetFrameBufferBorderHeight(void);
UINT GetFrameBufferWidth(void);
UINT GetFrameBufferHeight(void);
UINT GetFrameBufferCentringOffsetX(void);
UINT GetFrameBufferCentringOffsetY(void);
int GetFrameBufferCentringValue(void);
COLORREF GetMonochromeRGB(void) { return g_nMonochromeRGB; }
void SetMonochromeRGB(COLORREF colorRef) { g_nMonochromeRGB = colorRef; }
void VideoReinitialize(bool bInitVideoScannerAddress);
void VideoResetState(void);
void VideoRefreshBuffer(uint32_t uRedrawWholeScreenVideoMode, bool bRedrawWholeScreen);
void ClearFrameBuffer(void);
void ClearSHRResidue(void);
enum VideoScanner_e {VS_FullAddr, VS_PartialAddrV, VS_PartialAddrH};
WORD VideoGetScannerAddress(DWORD nCycles, VideoScanner_e videoScannerAddr = VS_FullAddr);
bool VideoGetVblBarEx(const DWORD dwCyclesThisFrame);
bool VideoGetVblBar(const DWORD uExecutedCycles);
bool VideoGetSW80COL(void);
bool VideoGetSWDHIRES(void);
bool VideoGetSWHIRES(void);
bool VideoGetSW80STORE(void);
bool VideoGetSWMIXED(void);
bool VideoGetSWPAGE2(void);
bool VideoGetSWTEXT(void);
bool VideoGetSWAltCharSet(void);
void VideoSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void VideoLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
enum VideoScreenShot_e
{
SCREENSHOT_560x384 = 0,
SCREENSHOT_280x192
};
void Video_SetBitmapHeader(WinBmpHeader_t *pBmp, int nWidth, int nHeight, int nBitsPerPixel);
void Video_MakeScreenShot(FILE* pFile, const VideoScreenShot_e ScreenShotType);
BYTE VideoSetMode(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
bool ReadVideoRomFile(const char* pRomFile);
UINT GetVideoRom(const BYTE*& pVideoRom);
bool GetVideoRomRockerSwitch(void);
void SetVideoRomRockerSwitch(bool state);
bool IsVideoRom4K(void);
void Config_Load_Video(void);
void Config_Save_Video(void);
uint32_t GetVideoMode(void);
void SetVideoMode(uint32_t videoMode);
VideoType_e GetVideoType(void);
void SetVideoType(VideoType_e newVideoType);
void IncVideoType(void);
void DecVideoType(void);
VideoStyle_e GetVideoStyle(void);
void SetVideoStyle(VideoStyle_e newVideoStyle);
bool IsVideoStyle(VideoStyle_e mask);
VideoRefreshRate_e GetVideoRefreshRate(void);
void SetVideoRefreshRate(VideoRefreshRate_e rate);
const char* VideoGetAppWindowTitle(void);
const char* GetVideoChoices(void) { return g_aVideoChoices; }
bool HasVidHD(void) { return m_hasVidHD; }
void SetVidHD(bool hasVidHD) { m_hasVidHD = hasVidHD; }
static const UINT kVideoRomSize2K = 1024*2;
static const UINT kVideoRomSize4K = kVideoRomSize2K*2;
protected:
uint8_t *g_pFramebufferbits;
private:
void SetFrameBuffer(uint8_t* frameBuffer) { g_pFramebufferbits = frameBuffer; }
std::string VideoGetSnapshotStructName(void);
int g_nAltCharSetOffset;
uint32_t g_uVideoMode; // Current Video Mode (this is the last set one as it may change mid-scan line!)
DWORD g_eVideoType; // saved to Registry
VideoStyle_e g_eVideoStyle;
bool g_bVideoScannerNTSC; // NTSC video scanning (or PAL)
COLORREF g_nMonochromeRGB; // saved to Registry
bool m_hasVidHD;
static const int kVDisplayableScanLines = 192; // max displayable scanlines
static const UINT kVideoRomSize8K = kVideoRomSize4K*2;
static const UINT kVideoRomSize16K = kVideoRomSize8K*2;
static const UINT kVideoRomSizeMax = kVideoRomSize16K;
BYTE g_videoRom[kVideoRomSizeMax];
UINT g_videoRomSize;
bool g_videoRomRockerSwitch;
static const char g_aVideoChoices[];
static const char m_szModeDesc0[];
static const char m_szModeDesc1[];
static const char m_szModeDesc2[];
static const char m_szModeDesc3[];
static const char m_szModeDesc4[];
static const char m_szModeDesc5[];
static const char m_szModeDesc6[];
static const char m_szModeDesc7[];
static const char m_szModeDesc8[];
static const char* const g_apVideoModeDesc[NUM_VIDEO_MODES];
static const UINT kVideoHeightII = 192*2;
static const UINT kVideoHeightIIgs = 200*2;
static const UINT kVideoWidthII = 280*2;
static const UINT kVideoWidthIIgs = 320*2;
};