mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
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:
parent
9b31fca76d
commit
dd3d2a073d
11 changed files with 2277 additions and 5 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
4
nq/source/.gitignore
vendored
4
nq/source/.gitignore
vendored
|
@ -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
|
||||||
|
|
|
@ -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
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
138
nq/source/fbset_modes_l.l
Normal 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
176
nq/source/fbset_modes_y.y
Normal 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
157
nq/source/in_fbdev.c
Normal 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
709
nq/source/vid_fbdev.c
Normal 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(¤t_mode, &var);
|
||||||
|
err = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &var);
|
||||||
|
if (err)
|
||||||
|
Sys_Error ("Video mode failed: %s\n", name);
|
||||||
|
ConvertToVideoMode(&var, ¤t_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)
|
||||||
|
{
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue