]> git.sesse.net Git - vlc/blob - plugins/glide/vout_glide.c
* Fixed the BeOS compile typo.
[vlc] / plugins / glide / vout_glide.c
1 /*****************************************************************************
2  * vout_glide.c: 3dfx video output display method for 3dfx cards
3  *****************************************************************************
4  * Copyright (C) 2000, 2001 VideoLAN
5  * $Id: vout_glide.c,v 1.7 2001/05/30 17:03:12 sam Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #define MODULE_NAME glide
25 #include "modules_inner.h"
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <errno.h>                                                 /* ENOMEM */
33 #include <stdlib.h>                                                /* free() */
34 #include <string.h>                                            /* strerror() */
35
36 #ifndef __linux__
37 #include <conio.h>                                            /* for glide ? */
38 #endif
39 #include <glide.h>
40 #include <linutil.h>                            /* Glide kbhit() and getch() */
41
42 #include "config.h"
43 #include "common.h"
44 #include "threads.h"
45 #include "mtime.h"
46 #include "tests.h"
47
48 #include "video.h"
49 #include "video_output.h"
50
51 #include "intf_msg.h"
52 #include "interface.h"
53
54 #include "main.h"
55
56 #include "modules.h"
57 #include "modules_export.h"
58
59 #define GLIDE_WIDTH 800
60 #define GLIDE_HEIGHT 600
61 #define GLIDE_BITS_PER_PLANE 16
62 #define GLIDE_BYTES_PER_PIXEL 2
63
64 /*****************************************************************************
65  * vout_sys_t: Glide video output method descriptor
66  *****************************************************************************
67  * This structure is part of the video output thread descriptor.
68  * It describes the Glide specific properties of an output thread.
69  *****************************************************************************/
70 typedef struct vout_sys_s
71 {
72     GrLfbInfo_t                 p_buffer_info;           /* back buffer info */
73
74     /* Dummy video memory */
75     byte_t *                    p_video;                      /* base adress */
76     size_t                      i_page_size;                    /* page size */
77
78 } vout_sys_t;
79
80 /*****************************************************************************
81  * Local prototypes.
82  *****************************************************************************/
83 static int  vout_Probe     ( probedata_t *p_data );
84 static int  vout_Create    ( struct vout_thread_s * );
85 static int  vout_Init      ( struct vout_thread_s * );
86 static void vout_End       ( struct vout_thread_s * );
87 static void vout_Destroy   ( struct vout_thread_s * );
88 static int  vout_Manage    ( struct vout_thread_s * );
89 static void vout_Display   ( struct vout_thread_s * );
90
91 static int  GlideOpenDisplay   ( vout_thread_t *p_vout );
92 static void GlideCloseDisplay  ( vout_thread_t *p_vout );
93
94 /*****************************************************************************
95  * Functions exported as capabilities. They are declared as static so that
96  * we don't pollute the namespace too much.
97  *****************************************************************************/
98 void _M( vout_getfunctions )( function_list_t * p_function_list )
99 {
100     p_function_list->pf_probe = vout_Probe;
101     p_function_list->functions.vout.pf_create     = vout_Create;
102     p_function_list->functions.vout.pf_init       = vout_Init;
103     p_function_list->functions.vout.pf_end        = vout_End;
104     p_function_list->functions.vout.pf_destroy    = vout_Destroy;
105     p_function_list->functions.vout.pf_manage     = vout_Manage;
106     p_function_list->functions.vout.pf_display    = vout_Display;
107     p_function_list->functions.vout.pf_setpalette = NULL;
108 }
109
110 /*****************************************************************************
111  * vout_Probe: probe the video driver and return a score
112  *****************************************************************************
113  * This function tries to initialize SDL and returns a score to the
114  * plugin manager so that it can select the best plugin.
115  *****************************************************************************/
116 static int vout_Probe( probedata_t *p_data )
117 {
118     if( TestMethod( VOUT_METHOD_VAR, "glide" ) )
119     {
120         return( 999 );
121     }
122
123     /* We could do a grSstQueryBoards( GrHwConfiguration *hwConfig ) at
124      * this point, but if the user didn't configure his 3dfx card, we
125      * have great chances to segfault here. So we'd better assume
126      * everything is fine and worry only if we really need to use Glide */
127     return( 20 );
128 }
129
130 /*****************************************************************************
131  * vout_Create: allocates Glide video thread output method
132  *****************************************************************************
133  * This function allocates and initializes a Glide vout method.
134  *****************************************************************************/
135 int vout_Create( vout_thread_t *p_vout )
136 {
137     /* Allocate structure */
138     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
139     if( p_vout->p_sys == NULL )
140     {
141         intf_ErrMsg("error: %s", strerror(ENOMEM) );
142         return( 1 );
143     }
144
145     /* Open and initialize device */
146     if( GlideOpenDisplay( p_vout ) )
147     {
148         intf_ErrMsg("vout error: can't open display");
149         free( p_vout->p_sys );
150         return( 1 );
151     }
152
153     return( 0 );
154 }
155
156 /*****************************************************************************
157  * vout_Init: initialize Glide video thread output method
158  *****************************************************************************/
159 int vout_Init( vout_thread_t *p_vout )
160 {
161     return( 0 );
162 }
163
164 /*****************************************************************************
165  * vout_End: terminate Glide video thread output method
166  *****************************************************************************/
167 void vout_End( vout_thread_t *p_vout )
168 {
169     ;
170 }
171
172 /*****************************************************************************
173  * vout_Destroy: destroy Glide video thread output method
174  *****************************************************************************
175  * Terminate an output method created by vout_CreateOutputMethod
176  *****************************************************************************/
177 void vout_Destroy( vout_thread_t *p_vout )
178 {
179     GlideCloseDisplay( p_vout );
180     free( p_vout->p_sys );
181 }
182
183 /*****************************************************************************
184  * vout_Manage: handle Glide events
185  *****************************************************************************
186  * This function should be called regularly by video output thread. It manages
187  * console events. It returns a non null value on error.
188  *****************************************************************************/
189 int vout_Manage( vout_thread_t *p_vout )
190 {
191     int buf;
192
193     /* very Linux specific - see tlib.c in Glide for other versions */
194     while( kbhit() )
195     {
196         buf = getch();
197
198         switch( (char)buf )
199         {
200         case 'q':
201             p_main->p_intf->b_die = 1;
202             break;
203
204         default:
205             break;
206         }
207     }
208
209     return 0;
210 }
211
212 /*****************************************************************************
213  * vout_Display: displays previously rendered output
214  *****************************************************************************
215  * This function send the currently rendered image to Glide image, waits until
216  * it is displayed and switch the two rendering buffers, preparing next frame.
217  *****************************************************************************/
218 void vout_Display( vout_thread_t *p_vout )
219 {
220     grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
221
222     grBufferSwap( 0 );
223
224     if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
225                    GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
226                    &p_vout->p_sys->p_buffer_info) == FXFALSE )
227     {
228         intf_ErrMsg( "vout error: can't take 3dfx back buffer lock" );
229     }
230 }
231
232 /* following functions are local */
233
234 /*****************************************************************************
235  * GlideOpenDisplay: open and initialize 3dfx device
236  *****************************************************************************/
237
238 static int GlideOpenDisplay( vout_thread_t *p_vout )
239 {
240     static char version[80];
241     GrHwConfiguration hwconfig;
242     GrScreenResolution_t resolution = GR_RESOLUTION_800x600;
243     GrLfbInfo_t p_front_buffer_info;                    /* front buffer info */
244
245     p_vout->i_width =            GLIDE_WIDTH;
246     p_vout->i_height =           GLIDE_HEIGHT;
247     p_vout->i_screen_depth =     GLIDE_BITS_PER_PLANE;
248     p_vout->i_bytes_per_pixel =  GLIDE_BYTES_PER_PIXEL;
249     /* bytes per line value overriden later */
250     p_vout->i_bytes_per_line =   1024 * GLIDE_BYTES_PER_PIXEL;
251
252     p_vout->p_sys->i_page_size = GLIDE_WIDTH * GLIDE_HEIGHT
253                                   * GLIDE_BYTES_PER_PIXEL;
254
255     p_vout->i_red_mask =   0xf800;
256     p_vout->i_green_mask = 0x07e0;
257     p_vout->i_blue_mask =  0x001f;
258
259     /* Map two framebuffers a the very beginning of the fb */
260     p_vout->p_sys->p_video = malloc( p_vout->p_sys->i_page_size * 2 );
261     if( (int)p_vout->p_sys->p_video == -1 )
262     {
263         intf_ErrMsg( "vout error: can't map video memory (%s)",
264                      strerror(errno) );
265         return( 1 );
266     }
267
268     grGlideGetVersion( version );
269     grGlideInit();
270
271     if( !grSstQueryHardware(&hwconfig) )
272     {
273         intf_ErrMsg( "vout error: can't get 3dfx hardware config" );
274         return( 1 );
275     }
276
277     grSstSelect( 0 );
278     if( !grSstWinOpen(0, resolution, GR_REFRESH_60Hz,
279                         GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1) )
280     {
281         intf_ErrMsg( "vout error: can't open 3dfx screen" );
282         return( 1 );
283     }
284
285     /* disable dithering */
286     //grDitherMode( GR_DITHER_DISABLE );
287
288     /* clear both buffers */
289     grRenderBuffer( GR_BUFFER_BACKBUFFER );
290     grBufferClear( 0, 0, 0 );
291     grRenderBuffer( GR_BUFFER_FRONTBUFFER );
292     grBufferClear( 0, 0, 0 );
293     grRenderBuffer( GR_BUFFER_BACKBUFFER );
294
295     p_vout->p_sys->p_buffer_info.size = sizeof( GrLfbInfo_t );
296     p_front_buffer_info.size          = sizeof( GrLfbInfo_t );
297
298     /* lock the buffers to find their adresses */
299     if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER,
300                    GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
301                    &p_front_buffer_info) == FXFALSE )
302     {
303         intf_ErrMsg( "vout error: can't take 3dfx front buffer lock" );
304         grGlideShutdown();
305         return( 1 );
306     }
307     grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER );
308
309     if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
310                    GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
311                    &p_vout->p_sys->p_buffer_info) == FXFALSE )
312     {
313         intf_ErrMsg( "vout error: can't take 3dfx back buffer lock" );
314         grGlideShutdown();
315         return( 1 );
316     }
317     grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
318     
319     /* Get the number of bytes per line */
320     p_vout->i_bytes_per_line = p_vout->p_sys->p_buffer_info.strideInBytes;
321
322     grBufferClear( 0, 0, 0 );
323
324     /* Set and initialize buffers */
325     p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_buffer_info.lfbPtr,
326                                    p_front_buffer_info.lfbPtr );
327
328     return( 0 );
329 }
330
331 /*****************************************************************************
332  * GlideCloseDisplay: close and reset 3dfx device
333  *****************************************************************************
334  * Returns all resources allocated by GlideOpenDisplay and restore the original
335  * state of the device.
336  *****************************************************************************/
337 static void GlideCloseDisplay( vout_thread_t *p_vout )
338 {
339     /* unlock the hidden buffer */
340     grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
341
342     /* shutdown Glide */
343     grGlideShutdown();
344     free( p_vout->p_sys->p_video );
345 }
346