00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <errno.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include <vlc/vlc.h>
00032 #include <vlc/intf.h>
00033 #include <vlc/vout.h>
00034
00035 #ifndef __linux__
00036 # include <conio.h>
00037 #endif
00038 #include <glide.h>
00039 #include <linutil.h>
00040
00041 #define GLIDE_WIDTH 800
00042 #define GLIDE_HEIGHT 600
00043 #define GLIDE_BITS_PER_PLANE 16
00044 #define GLIDE_BYTES_PER_PIXEL 2
00045
00046
00047
00048
00049 static int Create ( vlc_object_t * );
00050 static void Destroy ( vlc_object_t * );
00051
00052 static int Init ( vout_thread_t * );
00053 static void End ( vout_thread_t * );
00054 static int Manage ( vout_thread_t * );
00055 static void Display ( vout_thread_t *, picture_t * );
00056
00057 static int OpenDisplay ( vout_thread_t * );
00058 static void CloseDisplay ( vout_thread_t * );
00059
00060
00061
00062
00063 vlc_module_begin();
00064 set_description( _("3dfx Glide video output") );
00065 set_capability( "video output", 20 );
00066 add_shortcut( "3dfx" );
00067 set_callbacks( Create, Destroy );
00068 vlc_module_end();
00069
00070
00071
00072
00073
00074
00075
00076 struct vout_sys_t
00077 {
00078 GrLfbInfo_t p_buffer_info;
00079
00080 uint8_t * pp_buffer[2];
00081 int i_index;
00082 };
00083
00084
00085
00086
00087
00088
00089 static int Create( vlc_object_t *p_this )
00090 {
00091 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00092
00093
00094 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
00095 if( p_vout->p_sys == NULL )
00096 {
00097 msg_Err( p_vout, "out of memory" );
00098 return( 1 );
00099 }
00100
00101
00102 if( OpenDisplay( p_vout ) )
00103 {
00104 msg_Err( p_vout, "cannot open display" );
00105 free( p_vout->p_sys );
00106 return( 1 );
00107 }
00108
00109 p_vout->pf_init = Init;
00110 p_vout->pf_end = End;
00111 p_vout->pf_manage = Manage;
00112 p_vout->pf_render = NULL;
00113 p_vout->pf_display = Display;
00114
00115 return( 0 );
00116 }
00117
00118
00119
00120
00121 static int Init( vout_thread_t *p_vout )
00122 {
00123 int i_index;
00124 picture_t *p_pic;
00125
00126
00127 p_vout->output.i_rmask = 0xf800;
00128 p_vout->output.i_gmask = 0x07e0;
00129 p_vout->output.i_bmask = 0x001f;
00130
00131 I_OUTPUTPICTURES = 0;
00132
00133 p_pic = NULL;
00134
00135
00136 for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
00137 {
00138 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
00139 {
00140 p_pic = p_vout->p_picture + i_index;
00141 break;
00142 }
00143 }
00144
00145 if( p_pic == NULL )
00146 {
00147 return -1;
00148 }
00149
00150
00151
00152 p_pic->i_planes = 1;
00153
00154 p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index];
00155 p_pic->p->i_lines = GLIDE_HEIGHT;
00156 p_pic->p->i_visible_lines = GLIDE_HEIGHT;
00157 p_pic->p->i_pitch = p_vout->p_sys->p_buffer_info.strideInBytes;
00158
00159 p_pic->p->i_pixel_pitch = GLIDE_BYTES_PER_PIXEL;
00160 p_pic->p->i_visible_pitch = GLIDE_WIDTH * GLIDE_BYTES_PER_PIXEL;
00161
00162 p_pic->i_status = DESTROYED_PICTURE;
00163 p_pic->i_type = DIRECT_PICTURE;
00164
00165 PP_OUTPUTPICTURE[ 0 ] = p_pic;
00166
00167 I_OUTPUTPICTURES = 1;
00168
00169 return 0;
00170 }
00171
00172
00173
00174
00175 static void End( vout_thread_t *p_vout )
00176 {
00177 ;
00178 }
00179
00180
00181
00182
00183
00184
00185 static void Destroy( vlc_object_t *p_this )
00186 {
00187 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00188 CloseDisplay( p_vout );
00189 free( p_vout->p_sys );
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 static int Manage( vout_thread_t *p_vout )
00199 {
00200 int buf;
00201
00202
00203 while( kbhit() )
00204 {
00205 buf = getch();
00206
00207 switch( (char)buf )
00208 {
00209 case 'q':
00210 p_vout->p_vlc->b_die = 1;
00211 break;
00212
00213 default:
00214 break;
00215 }
00216 }
00217
00218 return 0;
00219 }
00220
00221
00222
00223
00224 static void Display( vout_thread_t *p_vout, picture_t *p_pic )
00225
00226 {
00227 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
00228
00229 grBufferSwap( 0 );
00230
00231 if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
00232 GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
00233 &p_vout->p_sys->p_buffer_info) == FXFALSE )
00234 {
00235 msg_Err( p_vout, "cannot take 3dfx back buffer lock" );
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 static int OpenDisplay( vout_thread_t *p_vout )
00246 {
00247 static char version[80];
00248 GrHwConfiguration hwconfig;
00249 GrScreenResolution_t resolution = GR_RESOLUTION_800x600;
00250 GrLfbInfo_t p_front_buffer_info;
00251
00252 grGlideGetVersion( version );
00253 grGlideInit();
00254
00255 if( !grSstQueryHardware(&hwconfig) )
00256 {
00257 msg_Err( p_vout, "cannot get 3dfx hardware config" );
00258 return( 1 );
00259 }
00260
00261 grSstSelect( 0 );
00262 if( !grSstWinOpen( 0, resolution, GR_REFRESH_60Hz,
00263 GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ) )
00264 {
00265 msg_Err( p_vout, "cannot open 3dfx screen" );
00266 return( 1 );
00267 }
00268
00269
00270
00271
00272
00273 grRenderBuffer( GR_BUFFER_BACKBUFFER );
00274 grBufferClear( 0, 0, 0 );
00275 grRenderBuffer( GR_BUFFER_FRONTBUFFER );
00276 grBufferClear( 0, 0, 0 );
00277 grRenderBuffer( GR_BUFFER_BACKBUFFER );
00278
00279 p_vout->p_sys->p_buffer_info.size = sizeof( GrLfbInfo_t );
00280 p_front_buffer_info.size = sizeof( GrLfbInfo_t );
00281
00282
00283 if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER,
00284 GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
00285 &p_front_buffer_info) == FXFALSE )
00286 {
00287 msg_Err( p_vout, "cannot take 3dfx front buffer lock" );
00288 grGlideShutdown();
00289 return( 1 );
00290 }
00291 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER );
00292
00293 if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
00294 GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
00295 &p_vout->p_sys->p_buffer_info) == FXFALSE )
00296 {
00297 msg_Err( p_vout, "cannot take 3dfx back buffer lock" );
00298 grGlideShutdown();
00299 return( 1 );
00300 }
00301 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
00302
00303 grBufferClear( 0, 0, 0 );
00304
00305 p_vout->p_sys->pp_buffer[0] = p_vout->p_sys->p_buffer_info.lfbPtr;
00306 p_vout->p_sys->pp_buffer[1] = p_front_buffer_info.lfbPtr;
00307 p_vout->p_sys->i_index = 0;
00308
00309 return( 0 );
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 static void CloseDisplay( vout_thread_t *p_vout )
00319 {
00320
00321 grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
00322
00323
00324 grGlideShutdown();
00325 }
00326