1 /*
2 	NatFeat VDI driver
3 
4 	ARAnyM (C) 2005 Patrice Mandin
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with this program; if not, write to the Free Software
18 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #ifndef NFVDI_H
22 #define NFVDI_H
23 
24 /*--- Includes ---*/
25 
26 #include "SDL_compat.h"
27 
28 #include "nf_base.h"
29 #include "parameters.h"
30 
31 #include "../include/dirty_rects.h"
32 
33 /*--- Defines ---*/
34 
35 // The Atari structures offsets
36 #define MFDB_ADDRESS                0
37 #define MFDB_WIDTH                  4
38 #define MFDB_HEIGHT                 6
39 #define MFDB_WDWIDTH                8
40 #define MFDB_STAND                 10
41 #define MFDB_NPLANES               12
42 
43 /* gsx modes */
44 
45 #define MD_REPLACE      1
46 #define MD_TRANS        2
47 #define MD_XOR          3
48 #define MD_ERASE        4
49 
50 /* bit blt rules */
51 
52 #define ALL_WHITE        0
53 #define S_AND_D          1
54 #define S_AND_NOTD       2
55 #define S_ONLY           3
56 #define NOTS_AND_D       4
57 #define D_ONLY           5
58 #define S_XOR_D          6
59 #define S_OR_D           7
60 #define NOT_SORD         8
61 #define NOT_SXORD        9
62 #define D_INVERT        10
63 #define NOT_D			D_INVERT
64 #define S_OR_NOTD		11
65 #define NOT_S			12
66 #define NOTS_OR_D       13
67 #define NOT_SANDD       14
68 #define ALL_BLACK       15
69 
70 // This is supposed to be a fast 16x16/16 with 32 bit intermediate result
71 #define SMUL_DIV(x,y,z)	((short)(((x)*(long)(y))/(z)))
72 // Some other possible variants are
73 //#define SMUL_DIV(x,y,z)	((long)(y - y1) * (x2 - x1) / (y2 - y1))
74 //#define SMUL_DIV(x,y,z)	((short)(((short)(x)*(long)((short)(y)))/(short)(z)))
75 
76 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
77 
78 #define put_dtriplet(address, data) \
79 { \
80 	WriteInt8((address), ((data) >> 16) & 0xff); \
81 	WriteInt8((address) + 1, ((data) >> 8) & 0xff); \
82 	WriteInt8((address) + 2, (data) & 0xff); \
83 }
84 
85 #define get_dtriplet(address) \
86 	((ReadInt8((address)) << 16) | (ReadInt8((address) + 1) << 8) | ReadInt8((address) + 2))
87 
88 #else
89 
90 #define put_dtriplet(address, data) \
91 { \
92 	WriteInt8((address), (data) & 0xff); \
93 	WriteInt8((address) + 1, ((data) >> 8) & 0xff); \
94 	WriteInt8((address) + 2, ((data) >> 16) & 0xff); \
95 }
96 
97 #define get_dtriplet(address) \
98 	((ReadInt8((address) + 2) << 16) | (ReadInt8((address) + 1) << 8) | ReadInt8((address)))
99 
100 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
101 
102 /*--- Types ---*/
103 
104 /*--- Class ---*/
105 
106 class HostSurface;
107 
108 class VdiDriver : public NF_Base
109 {
110 public:
name()111 	const char *name() { return "fVDI"; }
isSuperOnly()112 	bool isSuperOnly() { return false; }
113 	int32 dispatch(uint32 fncode);
114 	void reset();
115 
116 	VdiDriver();
117 	virtual ~VdiDriver();
118 
119 	HostSurface *getSurface(void);
120 
121 protected:
122 	HostSurface *surface;
123 
124 	struct _Mouse {
125 		struct {
126 			uint16 x, y;
127 			uint16 width, height;
128 			uint32 background[16][16]; // The mouse background backup surface for FVDIDriver
129 			struct {
130 				uint32 foreground; // The mouse shape color for FVDIDriver
131 				uint32 background; // The mouse mask color for FVDIDriver
132 			} color;
133 		} storage;
134 		struct hotspot_ {
135 			int16  x, y;
136 		} hotspot;
137 		struct colors_ {
138 			int16  fgColorIndex, bgColorIndex;
139 		} colors;
140 
141 		uint16 mask[16];
142 		uint16 shape[16];
143 	} Mouse;
144 
145 	virtual void restoreMouseBackground(void);
146 	virtual void saveMouseBackground(int16 x, int16 y, int16 width, int16 height);
147 
148 	void setResolution(int32 width, int32 height, int32 depth);
149 	int32 getWidth(void);
150 	int32 getHeight(void);
151 	int32 getBpp(void);
152 	int32 blitArea(memptr vwk, memptr src, int32 sx, int32 sy, memptr dest,
153 			int32 dx, int32 dy, int32 w, int32 h, uint32 logOp);
154 
155 	virtual int32 openWorkstation(void);
156 	virtual int32 closeWorkstation(void);
157 	virtual int32 getPixel(memptr vwk, memptr src, int32 x, int32 y);
158 	virtual int32 putPixel(memptr vwk, memptr dst, int32 x, int32 y, uint32 color);
159 	virtual int32 drawMouse(memptr wk, int32 x, int32 y, uint32 mode,
160 		uint32 data, uint32 hot_x, uint32 hot_y, uint32 fgColor,
161 		uint32 bgColor, uint32 mouse_type);
162 	virtual int32 expandArea(memptr vwk, memptr src, int32 sx, int32 sy,
163 		memptr dest, int32 dx, int32 dy, int32 w, int32 h, uint32 logOp,
164 		uint32 fgColor, uint32 bgColor);
165 	virtual int32 fillArea(memptr vwk, uint32 x_, uint32 y_, int32 w,
166 		int32 h, memptr pattern_address, uint32 fgColor, uint32 bgColor,
167 		uint32 logOp, uint32 interior_style);
168 	virtual	void fillArea(uint32 x, uint32 y, uint32 w, uint32 h,
169 	                      uint16* pattern, uint32 fgColor, uint32 bgColor,
170 	                      uint32 logOp) = 0;
171 	virtual int32 drawLine(memptr vwk, uint32 x1_, uint32 y1_, uint32 x2_,
172 		uint32 y2_, uint32 pattern, uint32 fgColor, uint32 bgColor,
173 		uint32 logOp, memptr clip);
174 	virtual int32 fillPoly(memptr vwk, memptr points_addr, int n,
175 		memptr index_addr, int moves, memptr pattern_addr, uint32 fgColor,
176 		uint32 bgColor, uint32 logOp, uint32 interior_style, memptr clip);
177 	virtual int32 drawText(memptr vwk, memptr text, uint32 length,
178 		int32 dst_x, int32 dst_y, memptr font,
179 		uint32 w, uint32 h, uint32 fgColor, uint32 bgColor,
180 		uint32 logOp, memptr clip);
181 	virtual void getHwColor(uint16 index, uint32 red, uint32 green,
182 		uint32 blue, memptr hw_value);
183 	virtual void setColor(memptr vwk, uint32 paletteIndex, uint32 red,
184 		uint32 green, uint32 blue);
185 	virtual int32 getFbAddr(void);
186 
187 	/* Blit memory to screen */
188 	virtual int32 blitArea_M2S(memptr vwk, memptr src, int32 sx, int32 sy,
189 			memptr dest, int32 dx, int32 dy, int32 w, int32 h, uint32 logOp);
190 	/* Blit screen to screen */
191 	virtual int32 blitArea_S2S(memptr vwk, memptr src, int32 sx, int32 sy,
192 			memptr dest, int32 dx, int32 dy, int32 w, int32 h, uint32 logOp);
193 	/* Blit screen to memory */
194 	virtual int32 blitArea_S2M(memptr vwk, memptr src, int32 sx, int32 sy,
195 			memptr dest, int32 dx, int32 dy, int32 w, int32 h, uint32 logOp);
196 
197 	/* Inlinable functions */
198 	void chunkyToBitplane(uint8 *sdlPixelData, uint16 bpp, uint16 bitplaneWords[8]);
199 	uint32 applyBlitLogOperation(int logicalOperation, uint32 destinationData, uint32 sourceData);
200 
201 	// fillPoly helpers
202 	bool AllocIndices(int n);
203 	bool AllocCrossings(int n);
EnoughCrossings(int n)204 	bool EnoughCrossings(int n) { return n <= crossing_count; }
205 	bool AllocPoints(int n);
206 
207 	int16* alloc_index;
208 	int16* alloc_crossing;
209 	int16* alloc_point;
210 
211 	// A helper class to make it possible to access
212 	// points in a nicer way in fillPoly.
213 	class Points {
214 	  public:
Points(int16 * vector_)215 		explicit Points(int16* vector_) : vector(vector_) { }
~Points()216 		~Points() { }
217 		int16* operator[](int n) { return &vector[n * 2]; }
218 	  private:
219 		int16* vector;
220 	};
221 
222 private:
223 	SDL_Cursor *cursor;
224 
225 	int events, new_event, mouse_x, mouse_y, buttons, wheel, vblank;
226 
227 	/* Blit memory to memory */
228 	int32 blitArea_M2M(memptr vwk, memptr src, int32 sx, int32 sy,
229 			memptr dest, int32 dx, int32 dy, int32 w, int32 h, uint32 logOp);
230 
231 	int index_count;
232 	int crossing_count;
233 	int point_count;
234 };
235 
236 #endif /* NFVDI_H */
237