1 // Emacs style mode select -*- C++ -*-
2 //---------------------------------------------------------------------------
3 //
4 // $Id: vid_4bit.c,v 1.2 2003/03/26 14:58:34 fraggle Exp $
5 //
6 // Copyright(C) 2001-2003 Simon Howard
7 //
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 2 of the License, or (at your
11 // option) any later version. This program is distributed in the hope that
12 // it will be useful, but WITHOUT ANY WARRANTY; without even the implied
13 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 // the GNU General Public License for more details. You should have
15 // received a copy of the GNU General Public License along with this
16 // program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 // Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 //---------------------------------------------------------------------------
20 //
21 // 4-bit graphics routines for the psion screen
22 //
23 //---------------------------------------------------------------------------
24 
25 #include "video.h"
26 
27 #include "sw.h"
28 #include "swdisp.h"
29 #include "swground.h"
30 #include "swgrpha.h"
31 #include "swmain.h"
32 #include "swsymbol.h"
33 #include "swutil.h"
34 
35 // this should be in a header somewhere
36 #define SBAR_HGHT 19
37 
38 #define VRAMSIZE (SCR_HGHT * vid_pitch)
39 
40 static char *dispoff = NULL;           // current display offset
41 
42 unsigned char *vid_vram;
43 unsigned int vid_pitch;              // line length in bytes(not pixels)
44 
45 // sdh 28/10/2001: moved auxdisp here
46 
47 char *auxdisp = NULL;
48 
49 /*---------------------------------------------------------------------------
50 
51         Update display of ground.   Delete previous display of ground by
52         XOR graphics.
53 
54         Different routines are used to display/delete ground on colour
55         or monochrome systems.
56 
57 ---------------------------------------------------------------------------*/
58 
59 
Vid_DispGround(GRNDTYPE * gptr)60 void Vid_DispGround(GRNDTYPE *gptr)
61 {
62 	char *p = dispoff + (SCR_HGHT-1 - *gptr) * vid_pitch;
63 	int oldy = *gptr;
64 	int x;
65 
66 	for(x=SCR_WDTH; x; ++p) {
67 		if (oldy == *gptr) {
68 			*p ^= 0xf;
69 	//		p[vid_pitch] ^= 0xf;
70 		} else if (oldy < *gptr) {
71 			for(; oldy < *gptr; ++oldy) {
72 				*p ^= 0xf;
73 				p -= vid_pitch;
74 			}
75 		} else if (oldy > *gptr) {
76 			for (; oldy > *gptr; --oldy) {
77 				*p ^= 0xf;
78 				p += vid_pitch;
79 			}
80 		}
81 
82 		++gptr; --x;
83 
84 		if (oldy == *gptr) {
85 			*p ^= 0xf0;
86 	//		p[vid_pitch] ^= 0xf0;
87 		} else if (oldy < *gptr) {
88 			for(; oldy < *gptr; ++oldy) {
89 				*p ^= 0xf0;
90 				p -= vid_pitch;
91 			}
92 		} else if (oldy > *gptr) {
93 			for (; oldy > *gptr; --oldy) {
94 				*p ^= 0xf0;
95 				p += vid_pitch;
96 			}
97 		}
98 
99 		++gptr; --x;
100 	}
101 }
102 
103 
104 // sdh 28/10/2001: solid ground function
105 
Vid_DispGround_Solid(GRNDTYPE * gptr)106 void Vid_DispGround_Solid(GRNDTYPE * gptr)
107 {
108 	char *p = dispoff + (SCR_HGHT-SBAR_HGHT-1) * vid_pitch;
109 	int x;
110 
111 	for (x=0; x<SCR_WDTH; ++p) {
112 		char *p2;
113 		int i;
114 
115 		for (i=*gptr+1 - SBAR_HGHT, p2=p; i; --i) {
116 			*p2 ^= 0xf;
117 			p2 -= vid_pitch;
118 		}
119 
120 		++x; ++gptr;
121 
122 		for (i=*gptr+1 - SBAR_HGHT, p2=p; i; --i) {
123 			*p2 ^= 0xf0;
124 			p2 -= vid_pitch;
125 		}
126 
127 		++x; ++gptr;
128 	}
129 }
130 
131 
132 /*---------------------------------------------------------------------------
133 
134         External calls to display a point of a specified colour at a
135         specified position.   The point request may or may not ask for
136         collision detection by returning the old colour of the point.
137 
138         Different routines are used to display points on colour or
139         monochrome systems.
140 
141 ---------------------------------------------------------------------------*/
142 
Vid_PlotPixel(int x,int y,int clr)143 void Vid_PlotPixel(int x, int y, int clr)
144 {
145 	unsigned char *s = dispoff + (SCR_HGHT-1-y) * vid_pitch + (x >> 1);
146 
147 	clr = ~clr & 0x3;
148 	clr |= clr << 2;
149 
150 	if (x & 1) {
151 		*s = (*s & 0xf) | (clr << 4);
152 	} else {
153 		*s = (*s & 0xf0) | clr;
154 	}
155 }
156 
Vid_XorPixel(int x,int y,int clr)157 void Vid_XorPixel(int x, int y, int clr)
158 {
159 	unsigned char *s = dispoff + (SCR_HGHT-1-y) * vid_pitch + (x >> 1);
160 
161 	clr &= 0x3;
162 	clr |= clr << 2;
163 
164 	if (x & 1)
165 		*s ^= clr << 4;
166 	else
167 		*s ^= clr;
168 }
169 
Vid_GetPixel(int x,int y)170 int Vid_GetPixel(int x, int y)
171 {
172 	unsigned char *s = dispoff + (SCR_HGHT-1-y) * vid_pitch + (x >> 1);
173 
174 	if (x & 1)
175 		return (~*s >> 6) & 3;
176 	else
177 		return (~*s >> 2) & 3;
178 }
179 
180 
181 /*---------------------------------------------------------------------------
182 
183         Display an object's current symbol at a specified screen location
184         Collision detection may or may not be asked for.
185 
186         Different routines are used to display symbols on colour or
187         monochrome systems.
188 
189 ---------------------------------------------------------------------------*/
190 
191 // sdh 28/6/2002: move to new sopsym_t for sprites
192 // sdh 27/7/2002: removed collision detection code, this is now done
193 // independently of the drawing code (retcode)
194 
Vid_DispSymbol(int x,int y,sopsym_t * symbol,int clr)195 void Vid_DispSymbol(int x, int y, sopsym_t *symbol, int clr)
196 {
197 	unsigned char *s = dispoff + (SCR_HGHT-1-y) * vid_pitch + (x >> 1);
198 	unsigned char *data = symbol->data;
199 	int w, h;
200 
201 	if (symbol->h == 1 && symbol->w == 1) {
202 		Vid_XorPixel(x, y, clr);
203 		return;
204 	}
205 
206 	w = symbol->w;
207 	h = symbol->h;
208 
209 	if (h > y)
210 		h = y;
211 
212 	if (clr == 2) {
213 
214 		// inverted colour draw (for enemy planes)
215 
216 		for (y=0; y<h; ++y) {
217 			unsigned char *s2 = s;
218 
219 			for (x=0; x<w; x += 2) {
220 				int i;
221 
222 				i = *data++;
223 
224 				if (i)
225 					*s2 ^= (i | (i << 2)) ^ 0xf;
226 
227 				i = *data++;
228 
229 				if (i)
230 					*s2 ^= ((i << 6) | (i << 4)) ^ 0xf0;
231 
232 				++s2;
233 			}
234 
235 			s += vid_pitch;
236 		}
237 	} else {
238 
239 		// normal draw
240 
241 		for (y=0; y<h; ++y) {
242 			unsigned char *s2 = s;
243 
244 			for (x=0; x<w; x += 2) {
245 				int i;
246 
247 				i = *data++;
248 
249 				if (i)
250 					*s2 ^= (i << 2) | i;
251 
252 				i = *data++;
253 
254 				if (i)
255 					*s2 ^= (i << 6) | (i << 4);
256 
257 				++s2;
258 			}
259 
260 			s += vid_pitch;
261 		}
262 	}
263 }
264 
265 // sdh 28/6/2002: new function to draw filled boxes
266 
Vid_Box(int x,int y,int w,int h,int c)267 void Vid_Box(int x, int y, int w, int h, int c)
268 {
269 	unsigned char *s = dispoff + (SCR_HGHT-1-y) * vid_pitch + (x >> 1);
270 
271 	c = ~c & 0x3;
272 	c |= (c << 6) | (c << 4) | (c << 2);
273 	w >>= 1;
274 
275 	for (; h >= 0; --h, s += vid_pitch)
276 		memset(s, c, w);
277 }
278 
279 /*---------------------------------------------------------------------------
280 
281         External calls to specify current video ram as screen ram or
282         auxiliary screen area.
283 
284 ---------------------------------------------------------------------------*/
285 
Vid_SetBuf()286 void Vid_SetBuf()
287 {
288 	dispoff = vid_vram;
289 }
290 
Vid_SetBuf_Aux()291 void Vid_SetBuf_Aux()
292 {
293 	if (!auxdisp)
294 		auxdisp = malloc(VRAMSIZE);
295 
296 	dispoff = auxdisp;
297 }
298 
299 // sdh 28/10/2001: moved various auxdisp functions here:
300 
Vid_CopyBuf()301 void Vid_CopyBuf()
302 {
303 	memset(vid_vram, 0xff, VRAMSIZE);
304 	memcpy(vid_vram + ((SCR_HGHT-SBAR_HGHT) * vid_pitch),
305 	       auxdisp + ((SCR_HGHT-SBAR_HGHT) * vid_pitch),
306 	       SBAR_HGHT*vid_pitch);
307 }
308 
309 
Vid_ClearBuf()310 void Vid_ClearBuf()
311 {
312 	memset(vid_vram, 0xff, VRAMSIZE);
313 }
314 
Vid_ClearBuf_Aux()315 void Vid_ClearBuf_Aux()
316 {
317 	if (!auxdisp)
318 		auxdisp = malloc(VRAMSIZE);
319 
320 	memset(auxdisp, 0xff, VRAMSIZE);
321 }
322 
323 //---------------------------------------------------------------------------
324 //
325 // $Log: vid_4bit.c,v $
326 // Revision 1.2  2003/03/26 14:58:34  fraggle
327 // devfs support
328 // improved screen squishing for revo
329 //
330 // Revision 1.1.1.1  2003/02/14 19:03:39  fraggle
331 // Initial Sourceforge CVS import
332 //
333 //
334 // sdh 14/2/2003: change license header to GPL
335 // sdh 27/7/2002: remove collision detection code
336 // sdh 28/6/2002: move to sopsym_t for sprites
337 // sdh 25/04/2002: rename vid4_{pitch,vram} to vid_{pitch,vram}
338 // sdh 20/04/2002: psion framebuffer port
339 // sdh 26/03/2002: split off platform specific drawing functions here
340 //                 replaced amiga drawing functions with these generic
341 //                 8 bit ones
342 // sdh 28/10/2001: get_type/set_type removed
343 // sdh 28/10/2001: moved auxdisp and auxdisp functions here
344 // sdh 24/10/2001: fix auxdisp buffer
345 // sdh 21/10/2001: use new obtype_t and obstate_t
346 // sdh 21/10/2001: rearranged headers, added cvs tags
347 // sdh 21/10/2001: added #define for solid ground (sopwith 1 style)
348 // sdh 21/10/2001: reformatted with indent, adjusted some code by hand
349 //                 to make more readable
350 // sdh 19/10/2001: removed extern definitions, these are in headers now
351 //                 shuffled some functions round to shut up the compiler
352 // sdh 18/10/2001: converted all functions to ANSI-style arguments
353 //
354 // 87-03-09        Microsoft compiler.
355 // 85-11-05        Atari
356 // 84-06-13        PCjr Speed-up
357 // 84-02-21        Development
358 //
359 //---------------------------------------------------------------------------
360 
361