mittorn
5 years ago
9 changed files with 639 additions and 33 deletions
@ -0,0 +1,296 @@
@@ -0,0 +1,296 @@
|
||||
#include "platform/platform.h" |
||||
#if XASH_VIDEO == VIDEO_FBDEV |
||||
#include "input.h" |
||||
#include "client.h" |
||||
#include "filesystem.h" |
||||
#include "vid_common.h" |
||||
#include <fcntl.h> |
||||
#include <errno.h> |
||||
|
||||
#include <linux/fb.h> |
||||
#include <sys/mman.h> |
||||
#include <sys/ioctl.h> |
||||
#ifdef __ANDROID__ |
||||
#include <linux/kd.h> |
||||
#else |
||||
#include <sys/kd.h> |
||||
#endif |
||||
|
||||
struct fb_s |
||||
{ |
||||
int fd, tty_fd; |
||||
void *map; |
||||
struct fb_var_screeninfo vinfo; |
||||
struct fb_fix_screeninfo finfo; |
||||
qboolean vsync; |
||||
int doublebuffer; |
||||
} fb; |
||||
|
||||
#define DEFAULT_FBDEV "/dev/fb0" |
||||
|
||||
/*
|
||||
======================== |
||||
Android_SwapBuffers |
||||
|
||||
Update screen. Use native EGL if possible |
||||
======================== |
||||
*/ |
||||
void GL_SwapBuffers( void ) |
||||
{ |
||||
} |
||||
|
||||
void FB_GetScreenRes(int *x, int *y) |
||||
{ |
||||
*x = fb.vinfo.xres; |
||||
*y = fb.vinfo.yres; |
||||
} |
||||
|
||||
qboolean R_Init_Video( const int type ) |
||||
{ |
||||
qboolean retval; |
||||
string fbdev = DEFAULT_FBDEV; |
||||
fb.fd = -1; |
||||
|
||||
VID_StartupGamma(); |
||||
|
||||
if( type != REF_SOFTWARE ) |
||||
return false; |
||||
|
||||
Sys_GetParmFromCmdLine( "-fbdev", fbdev ); |
||||
|
||||
fb.fd = open( fbdev, O_RDWR ); |
||||
|
||||
if( fb.fd < 0 ) |
||||
{ |
||||
Con_Printf( S_ERROR, "failed to open framebuffer device: %s\n", strerror(errno)); |
||||
} |
||||
|
||||
if( Sys_CheckParm( "-ttygfx" ) ) |
||||
fb.tty_fd = open( "/dev/tty", O_RDWR ); // only need this to set graphics mode, optional
|
||||
|
||||
ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.finfo); |
||||
ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.vinfo); |
||||
|
||||
if( !(retval = VID_SetMode()) ) |
||||
{ |
||||
return retval; |
||||
} |
||||
|
||||
host.renderinfo_changed = false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void R_Free_Video( void ) |
||||
{ |
||||
// VID_DestroyWindow ();
|
||||
|
||||
// R_FreeVideoModes();
|
||||
if( fb.doublebuffer ) |
||||
{ |
||||
fb.vinfo.yoffset = 0; |
||||
fb.vinfo.yres_virtual >>= 1; |
||||
ioctl( fb.fd, FBIOPAN_DISPLAY, &fb.vinfo ); |
||||
} |
||||
if( fb.map ) |
||||
munmap( fb.map, fb.finfo.smem_len ); |
||||
close( fb.fd ); |
||||
|
||||
fb.fd = -1; |
||||
fb.map = NULL; |
||||
|
||||
if( fb.tty_fd >= 0 ) |
||||
{ |
||||
ioctl( fb.tty_fd, KDSETMODE, KD_TEXT ); |
||||
close( fb.tty_fd ); |
||||
fb.tty_fd = -1; |
||||
} |
||||
|
||||
ref.dllFuncs.GL_ClearExtensions(); |
||||
} |
||||
|
||||
|
||||
qboolean VID_SetMode( void ) |
||||
{ |
||||
if( fb.tty_fd > 0 ) |
||||
ioctl( fb.tty_fd, KDSETMODE, KD_GRAPHICS ); |
||||
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
|
||||
|
||||
return true; |
||||
} |
||||
|
||||
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen ) |
||||
{ |
||||
FB_GetScreenRes( &width, &height ); |
||||
|
||||
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height); |
||||
|
||||
R_SaveVideoMode( width, height ); |
||||
|
||||
host.window_center_x = width / 2; |
||||
host.window_center_y = height / 2; |
||||
|
||||
refState.wideScreen = true; // V_AdjustFov will check for widescreen
|
||||
|
||||
return rserr_ok; |
||||
} |
||||
|
||||
int GL_SetAttribute( int attr, int val ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int GL_GetAttribute( int attr, int *val ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int R_MaxVideoModes( void ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
vidmode_t* R_GetVideoMode( int num ) |
||||
{ |
||||
return NULL; |
||||
} |
||||
|
||||
void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
|
||||
{ |
||||
return NULL; |
||||
} |
||||
|
||||
void GL_UpdateSwapInterval( void ) |
||||
{ |
||||
// disable VSync while level is loading
|
||||
if( cls.state < ca_active ) |
||||
{ |
||||
// setup fb vsync here
|
||||
fb.vsync = false; |
||||
SetBits( gl_vsync->flags, FCVAR_CHANGED ); |
||||
} |
||||
else if( FBitSet( gl_vsync->flags, FCVAR_CHANGED )) |
||||
{ |
||||
ClearBits( gl_vsync->flags, FCVAR_CHANGED ); |
||||
fb.vsync = true; |
||||
} |
||||
} |
||||
|
||||
void *SW_LockBuffer( void ) |
||||
{ |
||||
if( fb.vsync ) |
||||
{ |
||||
int stub = 0; |
||||
ioctl(fb.fd, FBIO_WAITFORVSYNC, &stub); |
||||
} |
||||
if( fb.doublebuffer ) |
||||
{ |
||||
static int page = 0; |
||||
page = !page; |
||||
fb.vinfo.yoffset = page * fb.vinfo.yres; |
||||
return fb.map + page * fb.doublebuffer; |
||||
} |
||||
else |
||||
return fb.map; |
||||
} |
||||
|
||||
void SW_UnlockBuffer( void ) |
||||
{ |
||||
// some single-buffer fb devices need this too
|
||||
ioctl(fb.fd, FBIOPAN_DISPLAY, &fb.vinfo); |
||||
} |
||||
|
||||
#define FB_BF_TO_MASK(x) (((1 << x.length) - 1) << (x.offset)) |
||||
|
||||
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b ) |
||||
{ |
||||
*bpp = fb.vinfo.bits_per_pixel >> 3; |
||||
*stride = fb.vinfo.xres_virtual; |
||||
*r = FB_BF_TO_MASK(fb.vinfo.red); |
||||
*g = FB_BF_TO_MASK(fb.vinfo.green); |
||||
*b = FB_BF_TO_MASK(fb.vinfo.blue); |
||||
|
||||
if( Sys_CheckParm("-doublebuffer") ) |
||||
{ |
||||
fb.doublebuffer = *bpp * *stride * fb.vinfo.yres; |
||||
fb.vinfo.yres_virtual = fb.vinfo.yres * 2; |
||||
if(ioctl (fb.fd, FBIOPUT_VSCREENINFO, &fb.vinfo )) |
||||
{ |
||||
fb.vinfo.transp.length = fb.vinfo.transp.offset = 0; |
||||
if( ioctl (fb.fd, FBIOPUT_VSCREENINFO, &fb.vinfo ) ) |
||||
{ |
||||
Con_Printf( S_ERROR "failed to enable double buffering!\n" ); |
||||
} |
||||
} |
||||
|
||||
ioctl( fb.fd, FBIOGET_FSCREENINFO, &fb.finfo ); |
||||
ioctl( fb.fd, FBIOGET_VSCREENINFO, &fb.vinfo ); |
||||
ioctl( fb.fd, FBIOPAN_DISPLAY, &fb.vinfo ); |
||||
|
||||
if( fb.finfo.smem_len < fb.doublebuffer * 2 ) |
||||
{ |
||||
Con_Printf( S_ERROR "not enough memory for double buffering, disabling!\n" ); |
||||
fb.doublebuffer = 0; |
||||
} |
||||
} |
||||
if( fb.map ) |
||||
munmap(fb.map, fb.finfo.smem_len); |
||||
fb.map = mmap(0, fb.finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0); |
||||
|
||||
if( !fb.map ) |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
// unrelated stubs
|
||||
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow ) |
||||
{ |
||||
|
||||
} |
||||
void Platform_GetClipboardText( char *buffer, size_t size ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void Platform_SetClipboardText( const char *buffer, size_t size ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void Platform_PreCreateMove( void ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
// will be implemented later
|
||||
void Platform_RunEvents( void ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void *Platform_GetNativeObject( const char *name ) |
||||
{ |
||||
return NULL; |
||||
} |
||||
|
||||
void Platform_GetMousePos( int *x, int *y ) |
||||
{ |
||||
*x = *y = 0; |
||||
} |
||||
|
||||
|
||||
void Platform_SetMousePos(int x, int y) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void Platform_Vibrate(float life, char flags) |
||||
{ |
||||
|
||||
} |
||||
int Platform_JoyInit( int numjoy ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
s_backend.c - sound hardware output |
||||
Copyright (C) 2009 Uncle Mike |
||||
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
*/ |
||||
|
||||
|
||||
#ifndef XASH_DEDICATED |
||||
#include "common.h" |
||||
#if XASH_SOUND == SOUND_NULL |
||||
|
||||
#include "sound.h" |
||||
|
||||
#define SAMPLE_16BIT_SHIFT 1 |
||||
#define SECONDARY_BUFFER_SIZE 0x10000 |
||||
|
||||
/*
|
||||
======================================================================= |
||||
Global variables. Must be visible to window-procedure function |
||||
so it can unlock and free the data block after it has been played. |
||||
======================================================================= |
||||
*/ |
||||
|
||||
dma_t dma; |
||||
|
||||
void S_Activate( qboolean active ) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/*
|
||||
================== |
||||
SNDDMA_Init |
||||
|
||||
Try to find a sound device to mix for. |
||||
Returns false if nothing is found. |
||||
================== |
||||
*/ |
||||
qboolean SNDDMA_Init( void ) |
||||
{ |
||||
Msg( "Audio is not enabled\n" ); |
||||
return false; |
||||
} |
||||
|
||||
/*
|
||||
============== |
||||
SNDDMA_GetDMAPos |
||||
|
||||
return the current sample position (in mono samples read) |
||||
inside the recirculating dma buffer, so the mixing code will know |
||||
how many sample are required to fill it up. |
||||
=============== |
||||
*/ |
||||
int SNDDMA_GetDMAPos( void ) |
||||
{ |
||||
return dma.samplepos; |
||||
} |
||||
|
||||
/*
|
||||
============== |
||||
SNDDMA_GetSoundtime |
||||
|
||||
update global soundtime |
||||
=============== |
||||
*/ |
||||
int SNDDMA_GetSoundtime( void ) |
||||
{ |
||||
static int buffers, oldsamplepos; |
||||
int samplepos, fullsamples; |
||||
|
||||
fullsamples = dma.samples / 2; |
||||
|
||||
// it is possible to miscount buffers
|
||||
// if it has wrapped twice between
|
||||
// calls to S_Update. Oh well.
|
||||
samplepos = SNDDMA_GetDMAPos(); |
||||
|
||||
if( samplepos < oldsamplepos ) |
||||
{ |
||||
buffers++; // buffer wrapped
|
||||
|
||||
if( paintedtime > 0x40000000 ) |
||||
{ |
||||
// time to chop things off to avoid 32 bit limits
|
||||
buffers = 0; |
||||
paintedtime = fullsamples; |
||||
S_StopAllSounds( true ); |
||||
} |
||||
} |
||||
|
||||
oldsamplepos = samplepos; |
||||
|
||||
return (buffers * fullsamples + samplepos / 2); |
||||
} |
||||
|
||||
/*
|
||||
============== |
||||
SNDDMA_BeginPainting |
||||
|
||||
Makes sure dma.buffer is valid |
||||
=============== |
||||
*/ |
||||
void SNDDMA_BeginPainting( void ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
/*
|
||||
============== |
||||
SNDDMA_Submit |
||||
|
||||
Send sound to device if buffer isn't really the dma buffer |
||||
Also unlocks the dsound buffer |
||||
=============== |
||||
*/ |
||||
void SNDDMA_Submit( void ) |
||||
{ |
||||
|
||||
} |
||||
|
||||
/*
|
||||
============== |
||||
SNDDMA_Shutdown |
||||
|
||||
Reset the sound device for exiting |
||||
=============== |
||||
*/ |
||||
void SNDDMA_Shutdown( void ) |
||||
{ |
||||
Con_Printf("Shutting down audio.\n"); |
||||
dma.initialized = false; |
||||
|
||||
if (dma.buffer) { |
||||
Z_Free(dma.buffer); |
||||
dma.buffer = NULL; |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
#endif |
Loading…
Reference in new issue