ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_blit.cpp
Revision: 1.5
Committed: 2001-07-01T19:57:55Z (23 years ago) by cebix
Branch: MAIN
Changes since 1.4: +39 -2 lines
Log Message:
added support for 8-bit windowed modes on 16 and 32-bit screens (for the
games, man, the games! :-)

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * video_blit.cpp - Video/graphics emulation, blitters
3     *
4     * Basilisk II (C) 1997-2001 Christian Bauer
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     #include "sysdeps.h"
22 cebix 1.4 #include "video.h"
23 gbeauche 1.1
24     #include <stdio.h>
25     #include <stdlib.h>
26     #include <X11/Xlib.h>
27     #include <X11/Xutil.h>
28    
29     #ifdef ENABLE_VOSF
30     // Format of the target visual
31     struct VisualFormat {
32     int depth; // Screen depth
33     uint32 Rmask, Gmask, Bmask; // RGB mask values
34     uint32 Rshift, Gshift, Bshift; // RGB shift values
35     };
36     static VisualFormat visualFormat;
37    
38 cebix 1.5 // This holds the pixels values of the palette colors for 8->16/32-bit expansion
39     uint32 ExpandMap[256];
40    
41 gbeauche 1.1 /* -------------------------------------------------------------------------- */
42     /* --- Raw Copy / No conversion required --- */
43     /* -------------------------------------------------------------------------- */
44    
45     static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
46     {
47     // This function is likely to be inlined and/or highly optimized
48     memcpy(dest, source, length);
49     }
50    
51     /* -------------------------------------------------------------------------- */
52     /* --- RGB 555 --- */
53     /* -------------------------------------------------------------------------- */
54    
55     #ifdef WORDS_BIGENDIAN
56     # define FB_FUNC_NAME Blit_RGB555_OBO
57     #else
58     # define FB_FUNC_NAME Blit_RGB555_NBO
59     #endif
60    
61     #define FB_BLIT_1(dst, src) \
62     (dst = (((src) >> 8) & 0xff) | (((src) & 0xff) << 8))
63    
64     #define FB_BLIT_2(dst, src) \
65     (dst = (((src) >> 8) & 0x00ff00ff) | (((src) & 0x00ff00ff) << 8))
66    
67     #define FB_DEPTH 15
68     #include "video_blit.h"
69    
70     /* -------------------------------------------------------------------------- */
71     /* --- BGR 555 --- */
72     /* -------------------------------------------------------------------------- */
73    
74 gbeauche 1.2 #ifdef WORDS_BIGENDIAN
75    
76     // Native byte order
77    
78     #define FB_BLIT_1(dst, src) \
79     (dst = (((src) >> 10) & 0x001f) | ((src) & 0x03e0) | (((src) << 10) & 0x7c00))
80    
81     #define FB_BLIT_2(dst, src) \
82     (dst = (((src) >> 10) & 0x001f001f) | ((src) & 0x03e003e0) | (((src) << 10) & 0x7c007c00))
83    
84     #define FB_DEPTH 15
85     #define FB_FUNC_NAME Blit_BGR555_NBO
86     #include "video_blit.h"
87    
88     // Opposite byte order (untested)
89    
90     #define FB_BLIT_1(dst, src) \
91     (dst = (((src) >> 2) & 0x1f00) | (((src) >> 8) & 3) | (((src) << 8) & 0xe000) | (((src) << 2) & 0x7c))
92    
93     #define FB_BLIT_2(dst, src) \
94     (dst = (((src) >> 2) & 0x1f001f00) | (((src) >> 8) & 0x30003) | (((src) << 8) & 0xe000e000) | (((src) << 2) & 0x7c007c))
95    
96     #define FB_DEPTH 15
97     #define FB_FUNC_NAME Blit_BGR555_OBO
98     #include "video_blit.h"
99    
100     #else
101    
102     // Native byte order (untested)
103    
104     #define FB_BLIT_1(dst, src) \
105     (dst = (((src) >> 2) & 0x1f) | (((src) >> 8) & 0xe0) | (((src) << 8) & 0x0300) | (((src) << 2) & 0x7c00))
106    
107     #define FB_BLIT_2(dst, src) \
108     (dst = (((src) >> 2) & 0x1f001f) | (((src) >> 8) & 0xe000e0) | (((src) << 8) & 0x03000300) | (((src) << 2) & 0x7c007c00))
109    
110     #define FB_DEPTH 15
111     #define FB_FUNC_NAME Blit_BGR555_NBO
112     #include "video_blit.h"
113    
114     // Opposite byte order (untested)
115    
116     #define FB_BLIT_1(dst, src) \
117     (dst = (((src) << 6) & 0x1f00) | ((src) & 0xe003) | (((src) >> 6) & 0x7c))
118    
119     #define FB_BLIT_2(dst, src) \
120     (dst = (((src) << 6) & 0x1f001f00) | ((src) & 0xe003e003) | (((src) >> 6) & 0x7c007c))
121    
122     #define FB_DEPTH 15
123     #define FB_FUNC_NAME Blit_BGR555_OBO
124     #include "video_blit.h"
125    
126     #endif
127 gbeauche 1.1
128     /* -------------------------------------------------------------------------- */
129     /* --- RGB 565 --- */
130     /* -------------------------------------------------------------------------- */
131    
132     #ifdef WORDS_BIGENDIAN
133    
134     // Native byte order
135    
136     #define FB_BLIT_1(dst, src) \
137     (dst = (((src) & 0x1f) | (((src) << 1) & 0xffc0)))
138    
139     #define FB_BLIT_2(dst, src) \
140     (dst = (((src) & 0x001f001f) | (((src) << 1) & 0xffc0ffc0)))
141    
142     #define FB_DEPTH 16
143     #define FB_FUNC_NAME Blit_RGB565_NBO
144     #include "video_blit.h"
145    
146     // Opposite byte order
147    
148     #define FB_BLIT_1(dst, src) \
149     (dst = ((((src) >> 7) & 0xff) | (((src) << 9) & 0xc000) | (((src) << 8) & 0x1f00)))
150    
151     #define FB_BLIT_2(dst, src) \
152     (dst = ((((src) >> 7) & 0x00ff00ff) | (((src) << 9) & 0xc000c000) | (((src) << 8) & 0x1f001f00)))
153    
154     #define FB_DEPTH 16
155     #define FB_FUNC_NAME Blit_RGB565_OBO
156     #include "video_blit.h"
157    
158     #else
159    
160     // Native byte order
161    
162     #define FB_BLIT_1(dst, src) \
163     (dst = (((src) >> 8) & 0x001f) | (((src) << 9) & 0xfe00) | (((src) >> 7) & 0x01c0))
164    
165     // gb-- Disabled because I don't see any improvement
166     #if 0 && defined(__i386__) && defined(X86_ASSEMBLY)
167    
168     #define FB_BLIT_2(dst, src) \
169     __asm__ ( "movl %0,%%ebx\n\t" \
170     "movl %0,%%ebp\n\t" \
171     "andl $0x1f001f00,%%ebx\n\t" \
172     "andl $0x007f007f,%0\n\t" \
173     "andl $0xe000e000,%%ebp\n\t" \
174     "shrl $8,%%ebx\n\t" \
175     "shrl $7,%%ebp\n\t" \
176     "shll $9,%0\n\t" \
177     "orl %%ebx,%%ebp\n\t" \
178     "orl %%ebp,%0\n\t" \
179     : "=r" (dst) : "0" (src) : "ebx", "ebp", "cc" )
180    
181     #else
182    
183     #define FB_BLIT_2(dst, src) \
184     (dst = (((src) >> 8) & 0x001f001f) | (((src) << 9) & 0xfe00fe00) | (((src) >> 7) & 0x01c001c0))
185    
186     #endif
187    
188     #define FB_DEPTH 16
189     #define FB_FUNC_NAME Blit_RGB565_NBO
190     #include "video_blit.h"
191    
192     // Opposite byte order (untested)
193    
194     #define FB_BLIT_1(dst, src) \
195     (dst = (((src) & 0x1f00) | (((src) << 1) & 0xe0fe) | (((src) >> 15) & 1)))
196    
197     #define FB_BLIT_2(dst, src) \
198     (dst = (((src) & 0x1f001f00) | (((src) << 1) & 0xe0fee0fe) | (((src) >> 15) & 0x10001)))
199    
200     #define FB_DEPTH 16
201     #define FB_FUNC_NAME Blit_RGB565_OBO
202     #include "video_blit.h"
203    
204     #endif
205    
206     /* -------------------------------------------------------------------------- */
207     /* --- RGB 888 --- */
208     /* -------------------------------------------------------------------------- */
209    
210     #ifdef WORDS_BIGENDIAN
211     # define FB_FUNC_NAME Blit_RGB888_OBO
212     #else
213     # define FB_FUNC_NAME Blit_RGB888_NBO
214     #endif
215    
216     #define FB_BLIT_2(dst, src) \
217     (dst = (((src) >> 24) & 0xff) | (((src) >> 8) & 0xff00) | (((src) & 0xff00) << 8) | (((src) & 0xff) << 24))
218    
219     #define FB_DEPTH 24
220     #include "video_blit.h"
221    
222     /* -------------------------------------------------------------------------- */
223     /* --- BGR 888 --- */
224     /* -------------------------------------------------------------------------- */
225    
226 gbeauche 1.2 // Native byte order [BE] (untested)
227 gbeauche 1.1
228     #ifdef WORDS_BIGENDIAN
229    
230     #define FB_BLIT_2(dst, src) \
231     (dst = (((src) >> 16) & 0xff) | ((src) & 0xff00) | (((src) & 0xff) << 16))
232    
233     #define FB_FUNC_NAME Blit_BGR888_NBO
234     #define FB_DEPTH 24
235     #include "video_blit.h"
236    
237     #else
238    
239 gbeauche 1.2 // Opposite byte order [LE] (untested)
240    
241 gbeauche 1.1 #define FB_BLIT_2(dst, src) \
242     (dst = (((src) >> 16) & 0xff) | ((src) & 0xff0000) | (((src) & 0xff) << 16))
243    
244     #define FB_FUNC_NAME Blit_BGR888_OBO
245     #define FB_DEPTH 24
246     #include "video_blit.h"
247    
248     #endif
249    
250 gbeauche 1.2 // Opposite byte order [BE] (untested) / Native byte order [LE] (untested)
251 gbeauche 1.1
252     #ifdef WORDS_BIGENDIAN
253     # define FB_FUNC_NAME Blit_BGR888_OBO
254     #else
255     # define FB_FUNC_NAME Blit_BGR888_NBO
256     #endif
257    
258     #define FB_BLIT_2(dst, src) \
259     (dst = ((src) & 0xff00ff) | (((src) & 0xff00) << 16))
260    
261     #define FB_DEPTH 24
262     #include "video_blit.h"
263    
264     /* -------------------------------------------------------------------------- */
265 cebix 1.5 /* --- 8-bit indexed to 16-bit mode color expansion --- */
266     /* -------------------------------------------------------------------------- */
267    
268     static void Blit_Expand_8_To_16(uint8 * dest, const uint8 * p, uint32 length)
269     {
270     uint16 *q = (uint16 *)dest;
271     for (int i=0; i<length; i++)
272     *q++ = ExpandMap[*p++];
273     }
274    
275     /* -------------------------------------------------------------------------- */
276     /* --- 8-bit indexed to 32-bit mode color expansion --- */
277     /* -------------------------------------------------------------------------- */
278    
279     static void Blit_Expand_8_To_32(uint8 * dest, const uint8 * p, uint32 length)
280     {
281     uint32 *q = (uint32 *)dest;
282     for (int i=0; i<length; i++)
283     *q++ = ExpandMap[*p++];
284     }
285    
286     /* -------------------------------------------------------------------------- */
287 gbeauche 1.1 /* --- Blitters to the host frame buffer, or XImage buffer --- */
288     /* -------------------------------------------------------------------------- */
289    
290     // Function used to update the hosst frame buffer (DGA), or an XImage buffer (WIN)
291     // --> Shall be initialized only through the Screen_blitter_init() function
292     typedef void (*Screen_blit_func)(uint8 * dest, const uint8 * source, uint32 length);
293     Screen_blit_func Screen_blit = 0;
294    
295     // Structure used to match the adequate framebuffer update function
296     struct Screen_blit_func_info {
297     int depth; // Screen depth
298     uint32 Rmask; // Red mask
299     uint32 Gmask; // Green mask
300     uint32 Bmask; // Blue mask
301     Screen_blit_func handler_nbo; // Update function (native byte order)
302     Screen_blit_func handler_obo; // Update function (opposite byte order)
303     };
304    
305     // Table of visual formats supported and their respective handler
306     static Screen_blit_func_info Screen_blitters[] = {
307     #ifdef WORDS_BIGENDIAN
308     { 1, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // NT
309     { 8, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // OK (NBO)
310     { 15, 0x007c00, 0x0003e0, 0x00001f, Blit_Copy_Raw , Blit_RGB555_OBO }, // OK (OBO)
311 gbeauche 1.2 { 15, 0x00001f, 0x0003e0, 0x007c00, Blit_BGR555_NBO , Blit_BGR555_OBO }, // NT
312 gbeauche 1.1 { 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (OBO)
313     { 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_Copy_Raw , Blit_RGB888_OBO }, // OK (OBO)
314     { 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
315 gbeauche 1.2 { 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_Copy_Raw , Blit_RGB888_OBO }, // OK
316     { 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO } // OK
317 gbeauche 1.1 #else
318     { 1, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // NT
319     { 8, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // OK (NBO)
320     { 15, 0x007c00, 0x0003e0, 0x00001f, Blit_RGB555_NBO , Blit_Copy_Raw }, // OK (NBO)
321 gbeauche 1.2 { 15, 0x00001f, 0x0003e0, 0x007c00, Blit_BGR555_NBO , Blit_BGR555_OBO }, // NT
322 gbeauche 1.1 { 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (NBO)
323     { 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
324     { 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
325     { 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
326     { 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO } // NT
327     #endif
328     };
329    
330     // Initialize the framebuffer update function
331     // Returns FALSE, if the function was to be reduced to a simple memcpy()
332     // --> In that case, VOSF is not necessary
333 cebix 1.4 bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order, video_depth mac_depth)
334 gbeauche 1.1 {
335 gbeauche 1.3 #if REAL_ADDRESSING || DIRECT_ADDRESSING
336 cebix 1.4 if (mac_depth == VDEPTH_1BIT) {
337    
338     // 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines
339     Screen_blit = Blit_Copy_Raw;
340    
341     } else {
342    
343     visualFormat.depth = visual_info->depth;
344     visualFormat.Rmask = visual_info->red_mask;
345     visualFormat.Gmask = visual_info->green_mask;
346     visualFormat.Bmask = visual_info->blue_mask;
347 cebix 1.5
348 cebix 1.4 // Compute RGB shift values
349     visualFormat.Rshift = 0;
350     for (uint32 Rmask = visualFormat.Rmask; Rmask && ((Rmask & 1) != 1); Rmask >>= 1)
351     ++visualFormat.Rshift;
352     visualFormat.Gshift = 0;
353     for (uint32 Gmask = visualFormat.Gmask; Gmask && ((Gmask & 1) != 1); Gmask >>= 1)
354     ++visualFormat.Gshift;
355     visualFormat.Bshift = 0;
356     for (uint32 Bmask = visualFormat.Bmask; Bmask && ((Bmask & 1) != 1); Bmask >>= 1)
357     ++visualFormat.Bshift;
358 cebix 1.5
359     bool blitter_found = false;
360    
361     // 8-bit mode on 16/32-bit screen?
362     if (mac_depth == VDEPTH_8BIT && visualFormat.depth > 8) {
363     if (visual_info->depth <= 16) {
364     Screen_blit = Blit_Expand_8_To_16;
365     blitter_found = true;
366     } else {
367     Screen_blit = Blit_Expand_8_To_32;
368     blitter_found = true;
369     }
370     }
371 gbeauche 1.1
372 cebix 1.4 // Search for an adequate blit function
373     const int blitters_count = sizeof(Screen_blitters)/sizeof(Screen_blitters[0]);
374     for (int i = 0; !blitter_found && (i < blitters_count); i++) {
375     if ( (visualFormat.depth == Screen_blitters[i].depth)
376     && (visualFormat.Rmask == Screen_blitters[i].Rmask)
377     && (visualFormat.Gmask == Screen_blitters[i].Gmask)
378     && (visualFormat.Bmask == Screen_blitters[i].Bmask)
379     )
380     {
381     blitter_found = true;
382     Screen_blit = native_byte_order
383     ? Screen_blitters[i].handler_nbo
384     : Screen_blitters[i].handler_obo
385     ;
386     }
387 gbeauche 1.1 }
388    
389 cebix 1.4 // No appropriate blitter found, dump RGB mask values and abort()
390     if (!blitter_found) {
391     fprintf(stderr, "### No appropriate blitter found\n");
392     fprintf(stderr, "\tR/G/B mask values : 0x%06x, 0x%06x, 0x%06x (depth = %d)\n",
393     visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask, visualFormat.depth);
394     fprintf(stderr, "\tR/G/B shift values : %d/%d/%d\n",
395     visualFormat.Rshift, visualFormat.Gshift, visualFormat.Bshift);
396     abort();
397     }
398 gbeauche 1.1 }
399 gbeauche 1.3 #else
400     // The UAE memory handlers will blit correctly
401     // --> no need for specialised blitters here
402     Screen_blit = Blit_Copy_Raw;
403     #endif
404 gbeauche 1.1
405     // If the blitter simply reduces to a copy, we don't need VOSF in DGA mode
406     // --> In that case, we return FALSE
407     return (Screen_blit != Blit_Copy_Raw);
408     }
409     #endif /* ENABLE_VOSF */