make -fbdev build again AND make nq-fbdev a new target.

moved fbset.h from qw/include to include so it can be shared by nq. it's in
include instead of include/QF because I don't see any need to isntall it.
This commit is contained in:
Bill Currie 2001-03-29 17:31:15 +00:00
parent 9b31fca76d
commit dd3d2a073d
11 changed files with 2277 additions and 5 deletions

View file

@ -378,7 +378,7 @@ HAVE_FBDEV=$withval, HAVE_FBDEV=auto)
if test "x$HAVE_FBDEV" != xno; then if test "x$HAVE_FBDEV" != xno; then
dnl We should still be able to compile it even if dnl We should still be able to compile it even if
dnl there is no fbdev support in the running kernel dnl there is no fbdev support in the running kernel
AC_CHECK_HEADERS(linux/fb.h fbset.h, HAVE_FBDEV=yes, HAVE_FBDEV=no) AC_CHECK_HEADERS(linux/fb.h, HAVE_FBDEV=yes, HAVE_FBDEV=no)
fi fi
AC_SUBST(HAVE_FBDEV) AC_SUBST(HAVE_FBDEV)

View file

@ -86,7 +86,7 @@ void VID_Update (vrect_t *rects);
// sets the mode; only used by the Quake engine for resetting to mode 0 (the // sets the mode; only used by the Quake engine for resetting to mode 0 (the
// base mode) on memory allocation failures // base mode) on memory allocation failures
int VID_SetMode (int modenum, unsigned char *palette); // int VID_SetMode (int modenum, unsigned char *palette);
// called only on Win32, when pause happens, so the mouse can be released // called only on Win32, when pause happens, so the mouse can be released
void VID_HandlePause (qboolean pause); void VID_HandlePause (qboolean pause);

View file

@ -7,7 +7,11 @@
.vimrc .vimrc
Makefile Makefile
Makefile.in Makefile.in
fbset_modes_l.c
fbset_modes_y.c
fbset_modes_y.h
nq-3dfx nq-3dfx
nq-fbdev
nq-glx nq-glx
nq-sdl nq-sdl
nq-sgl nq-sgl

View file

@ -35,9 +35,8 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_srcdir)/nq/include $(MGL_CFLAGS) $(SDL
bin_PROGRAMS = @NQ_TARGETS@ bin_PROGRAMS = @NQ_TARGETS@
EXTRA_PROGRAMS= nq-mgl nq-sdl \ EXTRA_PROGRAMS= nq-3dfx nq-fbdev nq-glx nq-mgl nq-sdl \
nq-svga nq-x11 nq-3dfx \ nq-sgl nq-svga nq-wgl nq-x11 nq-server
nq-glx nq-sgl nq-wgl nq-server
noinst_LIBRARIES= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a noinst_LIBRARIES= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
@ -156,6 +155,23 @@ soft_SOURCES= d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \
r_surf.c r_vars.c screen.c sw_model_alias.c sw_model_brush.c \ r_surf.c r_vars.c screen.c sw_model_alias.c sw_model_brush.c \
sw_model_sprite.c sw_view.c $(soft_ASM) sw_model_sprite.c sw_view.c $(soft_ASM)
#
# ... Linux FBDev
#
YFLAGS = -d
fbdev_SOURCES= fbset.c fbset_modes_y.y fbset_modes_l.l vid_fbdev.c in_fbdev.c
YACCLEX_CLEANFILES= fbset_modes_y.c fbset_modes_y.h fbset_modes_y.tab.h fbset_modes_l.c
EXTRA_nq_fbdev_SOURCES=fbset_modes_y.h
fbset_modes_y.o: fbset_modes_y.c
$(CC) $(INCLUDES) $(CFLAGS) -Wno-error -c fbset_modes_y.c
fbset_modes_l.o: fbset_modes_l.c
$(CC) $(INCLUDES) $(CFLAGS) -Wno-error -c fbset_modes_l.c
nq_fbdev_SOURCES= $(combined_SOURCES) $(soft_SOURCES) $(fbdev_SOURCES)
nq_fbdev_LDADD= $(client_LIBS)
nq_fbdev_DEPENDENCIES= $(client_LIB_DEPS)
# #
# ... SciTech MGL # ... SciTech MGL
# #

1071
nq/source/fbset.c Normal file

File diff suppressed because it is too large Load diff

138
nq/source/fbset_modes_l.l Normal file
View file

@ -0,0 +1,138 @@
/*
* Linux Frame Buffer Device Configuration
*
* © Copyright 1995-1998 by Geert Uytterhoeven
* (Geert.Uytterhoeven@cs.kuleuven.ac.be)
*
* --------------------------------------------------------------------------
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details.
*/
%{
#define YYSTYPE long
#include <string.h>
#include <stdlib.h>
#define Die Sys_Error
#include "fbset.h"
#include "fbset_modes_y.h"
struct keyword {
const char *name;
int token;
int value;
};
static struct keyword keywords[] = {
{ "mode", MODE, 0 },
{ "geometry", GEOMETRY, 0 },
{ "timings", TIMINGS, 0 },
{ "hsync", HSYNC, 0 },
{ "vsync", VSYNC, 0 },
{ "csync", CSYNC, 0 },
{ "gsync", GSYNC, 0 },
{ "extsync", EXTSYNC, 0 },
{ "bcast", BCAST, 0 },
{ "laced", LACED, 0 },
{ "double", DOUBLE, 0 },
{ "rgba", RGBA, 0 },
{ "nonstd", NONSTD, 0 },
{ "accel", ACCEL, 0 },
{ "grayscale", GRAYSCALE, 0 },
{ "endmode", ENDMODE, 0 },
{ "low", POLARITY, LOW },
{ "high", POLARITY, HIGH },
{ "false", BOOLEAN, FALSE },
{ "true", BOOLEAN, TRUE },
{ "", -1, 0 }
};
int line = 1;
void yyerror(const char *s)
{
Die("%s:%d: %s\n", Opt_modedb, line, s);
}
int yywrap(void)
{
return 1;
}
static int FindToken(const char *s)
{
int i;
for (i = 0; keywords[i].token > 0; i++)
if (!strcasecmp(s, keywords[i].name)) {
return keywords[i].token;
}
Die("%s:%d: Unknown keyword `%s'\n", Opt_modedb, line, s);
}
static const char *CopyString(const char *s)
{
int len;
char *s2;
len = strlen(s)-2;
if (!(s2 = malloc(len+1)))
Die("No memory\n");
strncpy(s2, s+1, len);
s2[len] = '\0';
return s2;
}
%}
keyword [a-zA-Z][a-zA-Z0-9]*
number [0-9]*
string \"[^\"\n]*\"
comment \#([^\n]*)
space [ \t]+
junk .
%%
{keyword} {
yylval = FindToken(yytext);
return yylval;
}
{number} {
yylval = strtoul(yytext, NULL, 0);
return NUMBER;
}
{string} {
yylval = (unsigned long)CopyString(yytext);
return STRING;
}
{comment}$ break;
{space} break;
\n {
line++;
break;
}
{junk} {
Die("%s:%d: Invalid token `%s'\n", Opt_modedb, line, yytext);
}
%%

176
nq/source/fbset_modes_y.y Normal file
View file

@ -0,0 +1,176 @@
/*
* Linux Frame Buffer Device Configuration
*
* © Copyright 1995-1998 by Geert Uytterhoeven
* (Geert.Uytterhoeven@cs.kuleuven.ac.be)
*
* --------------------------------------------------------------------------
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details.
*/
%{
#define YYSTYPE long
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Die Sys_Error
#include "fbset.h"
extern int yylex(void);
extern void yyerror(const char *s);
extern int line;
static struct VideoMode VideoMode;
static void ClearVideoMode(void)
{
memset(&VideoMode, 0, sizeof(VideoMode));
VideoMode.accel_flags = FB_ACCELF_TEXT;
}
%}
%start file
%token MODE GEOMETRY TIMINGS HSYNC VSYNC CSYNC GSYNC EXTSYNC BCAST LACED DOUBLE
RGBA NONSTD ACCEL GRAYSCALE
ENDMODE POLARITY BOOLEAN STRING NUMBER
%%
file : vmodes
;
vmodes : /* empty */
| vmodes vmode
;
vmode : MODE STRING geometry timings options ENDMODE
{
VideoMode.name = (char *)$2;
AddVideoMode(&VideoMode);
ClearVideoMode();
}
;
geometry : GEOMETRY NUMBER NUMBER NUMBER NUMBER NUMBER
{
ClearVideoMode();
VideoMode.xres = $2;
VideoMode.yres = $3;
VideoMode.vxres = $4;
VideoMode.vyres = $5;
VideoMode.depth = $6;
}
;
timings : TIMINGS NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
{
VideoMode.pixclock = $2;
VideoMode.left = $3;
VideoMode.right = $4;
VideoMode.upper = $5;
VideoMode.lower = $6;
VideoMode.hslen = $7;
VideoMode.vslen = $8;
}
;
options : /* empty */
| options hsync
| options vsync
| options csync
| options gsync
| options extsync
| options bcast
| options laced
| options double
| options rgba
| options nonstd
| options accel
| options grayscale
;
hsync : HSYNC POLARITY
{
VideoMode.hsync = $2;
}
;
vsync : VSYNC POLARITY
{
VideoMode.vsync = $2;
}
;
csync : CSYNC POLARITY
{
VideoMode.csync = $2;
}
;
gsync : GSYNC POLARITY
{
VideoMode.gsync = $2;
}
;
extsync : EXTSYNC BOOLEAN
{
VideoMode.extsync = $2;
}
;
bcast : BCAST BOOLEAN
{
VideoMode.bcast = $2;
}
;
laced : LACED BOOLEAN
{
VideoMode.laced = $2;
}
;
double : DOUBLE BOOLEAN
{
VideoMode.dblscan = $2;
}
;
rgba : RGBA STRING
{
makeRGBA(&VideoMode, (const char*)$2);
}
;
nonstd : NONSTD NUMBER
{
VideoMode.nonstd = $2;
}
;
accel : ACCEL BOOLEAN
{
VideoMode.accel_flags = $2;
}
;
grayscale : GRAYSCALE BOOLEAN
{
VideoMode.grayscale = $2;
}
;
%%

157
nq/source/in_fbdev.c Normal file
View file

@ -0,0 +1,157 @@
/*
in_fbdev.c
fix this!
Copyright (C) 1996-1997 Id Software, Inc.
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 2
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "client.h"
#include "QF/cvar.h"
#include "QF/keys.h"
cvar_t *_windowed_mouse;
int
fd_blocking (int fd, int on)
{
int x;
#if defined(_POSIX_SOURCE) || !defined(FIONBIO)
#if !defined(O_NONBLOCK)
# if defined(O_NDELAY)
# define O_NONBLOCK O_NDELAY
# endif
#endif
if ((x = fcntl(fd, F_GETFL, 0)) == -1)
return -1;
if (on)
x &= ~O_NONBLOCK;
else
x |= O_NONBLOCK;
return fcntl(fd, F_SETFL, x);
#else
x = !on;
return ioctl(fd, FIONBIO, &x);
#endif
}
static struct termios old_tty, new_tty;
static int tty_fd = 0;
void
IN_Init (void)
{
fd_blocking(0, 0);
tcgetattr(tty_fd, &old_tty);
new_tty = old_tty;
new_tty.c_cc[VMIN] = 1;
new_tty.c_cc[VTIME] = 0;
new_tty.c_lflag &= ~ICANON;
new_tty.c_iflag &= ~IXON;
tcsetattr(tty_fd, TCSADRAIN, &new_tty);
}
void
IN_Init_Cvars (void)
{
}
void
IN_Shutdown (void)
{
}
void
IN_SendKeyEvents (void)
{
int k, down;
char buf[4];
if (read(0, buf, 1) == 1) {
k = buf[0];
switch (k) {
case '\r':
case '\n':
k = K_ENTER;
break;
case '\033':
if (read(0, buf, 2) != 2)
break;
switch (buf[1]) {
case 'A':
k = K_UPARROW;
break;
case 'B':
k = K_DOWNARROW;
break;
case 'C':
k = K_RIGHTARROW;
break;
case 'D':
k = K_LEFTARROW;
break;
}
break;
}
down = 1;
Key_Event(k, -1, down);
Key_Event(k, -1, !down);
}
}
void
IN_Commands (void)
{
}
void
IN_Move (usercmd_t *cmd)
{
}
/*
IN_ModeChanged
*/
void
IN_ModeChanged (void)
{
}
void
IN_HandlePause (qboolean paused)
{
}

709
nq/source/vid_fbdev.c Normal file
View file

@ -0,0 +1,709 @@
/*
vid_fbdev.c
Linux FBDev video routines
based on vid_svgalib.c
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 1999-2000 Nelson Rush.
Copyright (C) 1999-2000 Marcus Sundberg [mackan@stacken.kth.se]
Copyright (C) 1999-2000 David Symonds [xoxus@usa.net]
Copyright (C) 1999,2000 contributors of the QuakeForge project
Please see the file "AUTHORS" for a list of contributors
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 2
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_IO_H
# include <sys/io.h>
#elif defined(HAVE_ASM_IO_H)
# include <asm/io.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/page.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "d_local.h"
#include "host.h"
#include "input.h"
#include "QF/qargs.h"
#include "QF/qendian.h"
#include "QF/sys.h"
#include "fbset.h"
unsigned short d_8to16table[256];
extern void ReadModeDB(void);
extern struct VideoMode *FindVideoMode(const char *name);
void ConvertFromVideoMode(const struct VideoMode *vmode,
struct fb_var_screeninfo *var);
void ConvertToVideoMode(const struct fb_var_screeninfo *var,
struct VideoMode *vmode);
extern struct VideoMode *VideoModes;
static struct VideoMode current_mode;
static char current_name[32];
static int num_modes;
static int fb_fd = -1;
static int tty_fd = 0;
static byte vid_current_palette[768];
static int fbdev_inited = 0;
static int fbdev_backgrounded = 0;
static int UseDisplay = 1;
static cvar_t *vid_mode;
static cvar_t *vid_redrawfull;
static cvar_t *vid_waitforrefresh;
static char *framebuffer_ptr;
static byte backingbuf[48 * 24];
void
D_BeginDirectRect (int x, int y, byte * pbitmap, int width, int height)
{
int i, j, reps, repshift, offset, off;
if (!fbdev_inited || !vid.direct || fbdev_backgrounded)
return;
if (vid.aspect > 1.5) {
reps = 2;
repshift = 1;
} else {
reps = 1;
repshift = 0;
}
for (i = 0; i < (height << repshift); i += reps) {
for (j = 0; j < reps; j++) {
offset = x + ((y << repshift) + i + j)
* vid.rowbytes;
off = offset % 0x10000;
memcpy (&backingbuf[(i + j) * 24], vid.direct + off, width);
memcpy (vid.direct + off,
&pbitmap[(i >> repshift) * width], width);
}
}
}
void
D_EndDirectRect (int x, int y, int width, int height)
{
int i, j, reps, repshift, offset, off;
if (!fbdev_inited || !vid.direct || fbdev_backgrounded)
return;
if (vid.aspect > 1.5) {
reps = 2;
repshift = 1;
} else {
reps = 1;
repshift = 0;
}
for (i = 0; i < (height << repshift); i += reps) {
for (j = 0; j < reps; j++) {
offset = x + ((y << repshift) + i + j)
* vid.rowbytes;
off = offset % 0x10000;
memcpy (vid.direct + off, &backingbuf[(i + j) * 24], width);
}
}
}
static void
VID_Gamma_f (void)
{
float gamma, f, inf;
unsigned char palette[768];
int i;
if (Cmd_Argc () == 2) {
gamma = atof (Cmd_Argv (1));
for (i = 0; i < 768; i++) {
f = pow ((host_basepal[i] + 1) / 256.0, gamma);
inf = f * 255 + 0.5;
if (inf < 0)
inf = 0;
if (inf > 255)
inf = 255;
palette[i] = inf;
}
VID_SetPalette (palette);
/* Force a surface cache flush */
vid.recalc_refdef = 1;
}
}
static void
VID_DescribeMode_f (void)
{
char *modestr;
struct VideoMode *vmode;
modestr = Cmd_Argv(1);
vmode = FindVideoMode(modestr);
if (!vmode) {
Con_Printf ("Invalid video mode: %s!\n", modestr);
return;
}
Con_Printf ("%s: %d x %d - %d bpp - %5.3f Hz\n", vmode->name,
vmode->xres, vmode->yres, vmode->depth, vmode->vrate);
}
static void
VID_DescribeModes_f (void)
{
struct VideoMode *vmode;
for (vmode = VideoModes; vmode; vmode = vmode->next) {
Con_Printf ("%s: %d x %d - %d bpp - %5.3f Hz\n", vmode->name,
vmode->xres, vmode->yres, vmode->depth, vmode->vrate);
}
}
/*
VID_NumModes
*/
static int
VID_NumModes (void)
{
struct VideoMode *vmode;
int i = 0;
for (vmode = VideoModes; vmode; vmode = vmode->next)
i++;
return i;
}
static void
VID_NumModes_f (void)
{
Con_Printf ("%d modes\n", VID_NumModes ());
}
int VID_SetMode (char *name, unsigned char *palette);
extern void fbset_main (int argc, char **argv);
static void
VID_fbset_f (void)
{
int i, argc;
char *argv[32];
argc = Cmd_Argc();
if (argc > 32)
argc = 32;
argv[0] = "vid_fbset";
for (i = 1; i < argc; i++) {
argv[i] = Cmd_Argv(i);
}
fbset_main(argc, argv);
}
static void
VID_Debug_f (void)
{
Con_Printf ("mode: %s\n", current_mode.name);
Con_Printf ("height x width: %d x %d\n", current_mode.xres, current_mode.yres);
Con_Printf ("bpp: %d\n", current_mode.depth);
Con_Printf ("vrate: %5.3f\n", current_mode.vrate);
Con_Printf ("vid.aspect: %f\n", vid.aspect);
}
static void
VID_InitModes (void)
{
ReadModeDB();
num_modes = VID_NumModes();
}
static char *
get_mode (char *name, int width, int height, int depth)
{
struct VideoMode *vmode;
for (vmode = VideoModes; vmode; vmode = vmode->next) {
if (name) {
if (!strcmp(vmode->name, name))
return name;
} else {
if (vmode->xres == width
&& vmode->yres == height
&& vmode->depth == depth)
return vmode->name;
}
}
Sys_Printf ("Mode %dx%d (%d bits) not supported\n",
width, height, depth);
return "640x480-60";
}
void
VID_InitBuffers (void)
{
int buffersize, zbuffersize, cachesize;
void *vid_surfcache;
// Calculate the sizes we want first
buffersize = vid.rowbytes * vid.height;
zbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
cachesize = D_SurfaceCacheForRes (vid.width, vid.height);
// Free the old screen buffer
if (vid.buffer) {
free (vid.buffer);
vid.conbuffer = vid.buffer = NULL;
}
// Free the old z-buffer
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = NULL;
}
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
// Allocate the new screen buffer
vid.conbuffer = vid.buffer = calloc (buffersize, 1);
if (!vid.conbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
// Allocate the new z-buffer
d_pzbuffer = calloc (zbuffersize, 1);
if (!d_pzbuffer) {
free (vid.buffer);
vid.conbuffer = vid.buffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (cachesize, 1);
if (!vid_surfcache) {
free (vid.buffer);
free (d_pzbuffer);
vid.conbuffer = vid.buffer = NULL;
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches (vid_surfcache, cachesize);
}
static unsigned char *fb_map_addr = 0;
static unsigned long fb_map_length = 0;
static struct fb_var_screeninfo orig_var;
void
VID_Shutdown (void)
{
Sys_Printf ("VID_Shutdown\n");
if (!fbdev_inited)
return;
if (munmap(fb_map_addr, fb_map_length) == -1) {
Sys_Printf("could not unmap framebuffer at %p: %s\n",
fb_map_addr, strerror(errno));
} else {
if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &orig_var))
Sys_Printf ("failed to get var screen info\n");
}
close(fb_fd);
if (UseDisplay) {
ioctl(tty_fd, KDSETMODE, KD_TEXT);
write(tty_fd, "\033]R", 3); /* reset palette */
}
fbdev_inited = 0;
}
void
VID_ShiftPalette (unsigned char *p)
{
VID_SetPalette (p);
}
static void
loadpalette (unsigned short *red, unsigned short *green, unsigned short *blue)
{
struct fb_cmap cmap;
cmap.len = 256;
cmap.red = red;
cmap.green = green;
cmap.blue = blue;
cmap.transp = NULL;
cmap.start = 0;
if (-1 == ioctl(fb_fd, FBIOPUTCMAP, (void *)&cmap))
Sys_Error("ioctl FBIOPUTCMAP %s\n", strerror(errno));
}
void
VID_SetPalette (byte * palette)
{
static unsigned short tmppalr[256], tmppalg[256], tmppalb[256];
unsigned short i, *tpr, *tpg, *tpb;
if (!fbdev_inited || fbdev_backgrounded || fb_fd < 0)
return;
memcpy (vid_current_palette, palette, sizeof (vid_current_palette));
if (current_mode.depth == 8) {
tpr = tmppalr;
tpg = tmppalg;
tpb = tmppalb;
for (i = 0; i < 256; i++) {
*tpr++ = (*palette++) << 8;
*tpg++ = (*palette++) << 8;
*tpb++ = (*palette++) << 8;
}
if (UseDisplay) {
loadpalette(tmppalr, tmppalg, tmppalb);
}
}
}
int
VID_SetMode (char *name, unsigned char *palette)
{
struct VideoMode *vmode;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
int err;
unsigned long smem_start, smem_offset;
vmode = FindVideoMode(name);
if (!vmode) {
Cvar_Set (vid_mode, current_mode.name);
// Con_Printf ("No such video mode: %s\n", name);
return 0;
}
current_mode = *vmode;
Cvar_Set (vid_mode, current_mode.name);
strncpy(current_name, current_mode.name, sizeof(current_name)-1);
current_name[31] = 0;
vid.width = vmode->xres;
vid.height = vmode->yres;
vid.rowbytes = vmode->xres * (vmode->depth >> 3);
vid.aspect = ((float) vid.height / (float) vid.width) * (320.0 / 240.0);
vid.colormap = (pixel_t *) host_colormap;
vid.fullbright = 256 - LittleLong (*((int *) vid.colormap + 2048));
vid.conrowbytes = vid.rowbytes;
vid.conwidth = vid.width;
vid.conheight = vid.height;
vid.numpages = 1;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
if (fb_map_addr) {
if (munmap(fb_map_addr, fb_map_length) == -1) {
Sys_Printf("could not unmap framebuffer at %p: %s\n",
fb_map_addr, strerror(errno));
}
}
ConvertFromVideoMode(&current_mode, &var);
err = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &var);
if (err)
Sys_Error ("Video mode failed: %s\n", name);
ConvertToVideoMode(&var, &current_mode);
current_mode.name = current_name;
VID_SetPalette (palette);
err = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix);
if (err)
Sys_Error ("Video mode failed: %s\n", name);
smem_start = (unsigned long)fix.smem_start & PAGE_MASK;
smem_offset = (unsigned long)fix.smem_start & ~PAGE_MASK;
fb_map_length = (smem_offset+fix.smem_len+~PAGE_MASK) & PAGE_MASK;
fb_map_addr = (char *)mmap(0, fb_map_length, PROT_WRITE, MAP_SHARED, fb_fd, 0);
if (!fb_map_addr)
Sys_Error ("This mode isn't hapnin'\n");
vid.direct = framebuffer_ptr = fb_map_addr;
// alloc screen buffer, z-buffer, and surface cache
VID_InitBuffers ();
if (!fbdev_inited) {
fbdev_inited = 1;
}
/* Force a surface cache flush */
vid.recalc_refdef = 1;
return 1;
}
static void
fb_switch_handler (int sig)
{
if (sig == SIGUSR1) {
fbdev_backgrounded = 1;
} else if (sig == SIGUSR2) {
fbdev_backgrounded = 2;
}
}
static void
fb_switch_release (void)
{
ioctl(tty_fd, VT_RELDISP, 1);
}
static void
fb_switch_acquire (void)
{
ioctl(tty_fd, VT_RELDISP, VT_ACKACQ);
}
static void
fb_switch_init (void)
{
struct sigaction act;
struct vt_mode vtmode;
memset(&act, 0, sizeof(act));
act.sa_handler = fb_switch_handler;
sigemptyset(&act.sa_mask);
sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0);
if (ioctl(tty_fd, VT_GETMODE, &vtmode)) {
Sys_Error("ioctl VT_GETMODE: %s\n", strerror(errno));
}
vtmode.mode = VT_PROCESS;
vtmode.waitv = 0;
vtmode.relsig = SIGUSR1;
vtmode.acqsig = SIGUSR2;
if (ioctl(tty_fd, VT_SETMODE, &vtmode)) {
Sys_Error("ioctl VT_SETMODE: %s\n", strerror(errno));
}
}
void
VID_Init (unsigned char *palette)
{
int w, h, d;
struct VideoMode *vmode;
char *modestr;
char *fbname;
// plugin_load("in_fbdev.so");
if (fbdev_inited)
return;
Cmd_AddCommand ("gamma", VID_Gamma_f, "No Description");
if (UseDisplay) {
fbname = getenv("FRAMEBUFFER");
if (!fbname)
fbname = "/dev/fb0";
fb_fd = open(fbname, O_RDWR);
if (fb_fd < 0)
Sys_Error ("failed to open fb device\n");
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &orig_var))
Sys_Error ("failed to get var screen info\n");
fb_switch_init();
VID_InitModes ();
Cmd_AddCommand ("vid_nummodes", VID_NumModes_f, "No Description");
Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f, "No Description");
Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f, "No Description");
Cmd_AddCommand ("vid_debug", VID_Debug_f, "No Description");
Cmd_AddCommand ("vid_fbset", VID_fbset_f, "No Description");
/* Interpret command-line params */
w = h = d = 0;
if (getenv ("GFBDEVMODE")) {
modestr = get_mode (getenv ("GFBDEVMODE"), w, h, d);
} else if (COM_CheckParm ("-mode")) {
modestr = get_mode (com_argv[COM_CheckParm ("-mode") + 1], w, h, d);
} else if (COM_CheckParm ("-w") || COM_CheckParm ("-h")
|| COM_CheckParm ("-d")) {
if (COM_CheckParm ("-w")) {
w = atoi (com_argv[COM_CheckParm ("-w") + 1]);
}
if (COM_CheckParm ("-h")) {
h = atoi (com_argv[COM_CheckParm ("-h") + 1]);
}
if (COM_CheckParm ("-d")) {
d = atoi (com_argv[COM_CheckParm ("-d") + 1]);
}
modestr = get_mode (0, w, h, d);
} else {
modestr = "640x480-60";
}
/* Set vid parameters */
vmode = FindVideoMode(modestr);
if (!vmode)
Sys_Error("no video mode %s\n", modestr);
current_mode = *vmode;
ioctl(tty_fd, KDSETMODE, KD_GRAPHICS);
VID_SetMode (current_mode.name, palette);
Con_CheckResize (); // Now that we have a window size, fix console
VID_SetPalette (palette);
}
}
void
VID_Init_Cvars ()
{
vid_mode = Cvar_Get ("vid_mode", "0", CVAR_NONE, "Sets the video mode");
vid_redrawfull = Cvar_Get ("vid_redrawfull", "0", CVAR_NONE,
"Redraw entire screen each frame instead of just dirty areas");
vid_waitforrefresh = Cvar_Get ("vid_waitforrefresh", "0", CVAR_ARCHIVE,
"Wait for vertical retrace before drawing next frame");
}
void
VID_Update (vrect_t *rects)
{
if (!fbdev_inited)
return;
if (fbdev_backgrounded) {
if (fbdev_backgrounded == 3) {
return;
} else if (fbdev_backgrounded == 2) {
fb_switch_acquire();
fbdev_backgrounded = 0;
VID_SetPalette(vid_current_palette);
} else if (fbdev_backgrounded == 1) {
fb_switch_release();
fbdev_backgrounded = 3;
return;
}
}
if (vid_waitforrefresh->int_val) {
// ???
}
if (vid_redrawfull->int_val) {
double *d = (double *)framebuffer_ptr, *s = (double *)vid.buffer;
double *ends = (double *)(vid.buffer + vid.height*vid.rowbytes);
while (s < ends)
*d++ = *s++;
} else {
while (rects) {
int height, width, lineskip, i, j, xoff, yoff;
double *d, *s;
height = rects->height;
width = rects->width / sizeof(double);
xoff = rects->x;
yoff = rects->y;
lineskip = (vid.width - (xoff + rects->width)) / sizeof(double);
d = (double *)(framebuffer_ptr + yoff * vid.rowbytes + xoff);
s = (double *)(vid.buffer + yoff * vid.rowbytes + xoff);
for (i = yoff; i < height; i++) {
for (j = xoff; j < width; j++)
*d++ = *s++;
d += lineskip;
s += lineskip;
}
rects = rects->pnext;
}
}
if (current_mode.name && strcmp(vid_mode->string, current_mode.name)) {
VID_SetMode (vid_mode->string, vid_current_palette);
}
}
void
VID_LockBuffer (void)
{
}
void
VID_UnlockBuffer (void)
{
}
void
VID_SetCaption (char *text)
{
}
void
VID_HandlePause (qboolean paused)
{
}

View file

@ -44,6 +44,7 @@
#elif defined(HAVE_ASM_IO_H) #elif defined(HAVE_ASM_IO_H)
# include <asm/io.h> # include <asm/io.h>
#endif #endif
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>