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