354 lines
7.2 KiB
C
354 lines
7.2 KiB
C
// Emacs style mode select -*- C++ -*-
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Id:$
|
|
//
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
//
|
|
// This source is available for distribution and/or modification
|
|
// only under the terms of the DOOM Source Code License as
|
|
// published by id Software. All rights reserved.
|
|
//
|
|
// The source is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
|
// for more details.
|
|
//
|
|
// $Log:$
|
|
//
|
|
// DESCRIPTION:
|
|
// DOOM graphics stuff for fbdev on Frosted
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static const char
|
|
rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
|
|
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <stdarg.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <netinet/in.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
|
|
#include "doomstat.h"
|
|
#include "i_system.h"
|
|
#include "v_video.h"
|
|
#include "m_argv.h"
|
|
#include "d_main.h"
|
|
|
|
#include "doomdef.h"
|
|
|
|
struct color {
|
|
uint32_t b:8;
|
|
uint32_t g:8;
|
|
uint32_t r:8;
|
|
uint32_t a:8;
|
|
};
|
|
|
|
struct color colors[256];
|
|
|
|
/* framebuffer file descriptor */
|
|
int fd_fb = 0;
|
|
|
|
int X_width;
|
|
int X_height;
|
|
|
|
|
|
void I_ShutdownGraphics(void)
|
|
{
|
|
printf("I_ShutdownGraphics\n");
|
|
// Always be sure to clean up
|
|
//SDL_Quit();
|
|
close(fd_fb);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// I_StartFrame
|
|
//
|
|
void I_StartFrame (void)
|
|
{
|
|
// er?
|
|
|
|
}
|
|
|
|
void I_GetEvent(void)
|
|
{
|
|
/*
|
|
event_t event;
|
|
|
|
// put event-grabbing stuff in here
|
|
XNextEvent(X_display, &X_event);
|
|
switch (X_event.type)
|
|
{
|
|
case KeyPress:
|
|
event.type = ev_keydown;
|
|
event.data1 = xlatekey();
|
|
D_PostEvent(&event);
|
|
// fprintf(stderr, "k");
|
|
break;
|
|
case KeyRelease:
|
|
event.type = ev_keyup;
|
|
event.data1 = xlatekey();
|
|
D_PostEvent(&event);
|
|
// fprintf(stderr, "ku");
|
|
break;
|
|
case ButtonPress:
|
|
event.type = ev_mouse;
|
|
event.data1 =
|
|
(X_event.xbutton.state & Button1Mask)
|
|
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
|
|
| (X_event.xbutton.state & Button3Mask ? 4 : 0)
|
|
| (X_event.xbutton.button == Button1)
|
|
| (X_event.xbutton.button == Button2 ? 2 : 0)
|
|
| (X_event.xbutton.button == Button3 ? 4 : 0);
|
|
event.data2 = event.data3 = 0;
|
|
D_PostEvent(&event);
|
|
// fprintf(stderr, "b");
|
|
break;
|
|
case ButtonRelease:
|
|
event.type = ev_mouse;
|
|
event.data1 =
|
|
(X_event.xbutton.state & Button1Mask)
|
|
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
|
|
| (X_event.xbutton.state & Button3Mask ? 4 : 0);
|
|
// suggest parentheses around arithmetic in operand of |
|
|
event.data1 =
|
|
event.data1
|
|
^ (X_event.xbutton.button == Button1 ? 1 : 0)
|
|
^ (X_event.xbutton.button == Button2 ? 2 : 0)
|
|
^ (X_event.xbutton.button == Button3 ? 4 : 0);
|
|
event.data2 = event.data3 = 0;
|
|
D_PostEvent(&event);
|
|
// fprintf(stderr, "bu");
|
|
break;
|
|
case MotionNotify:
|
|
event.type = ev_mouse;
|
|
event.data1 =
|
|
(X_event.xmotion.state & Button1Mask)
|
|
| (X_event.xmotion.state & Button2Mask ? 2 : 0)
|
|
| (X_event.xmotion.state & Button3Mask ? 4 : 0);
|
|
event.data2 = (X_event.xmotion.x - lastmousex) << 2;
|
|
event.data3 = (lastmousey - X_event.xmotion.y) << 2;
|
|
|
|
if (event.data2 || event.data3)
|
|
{
|
|
lastmousex = X_event.xmotion.x;
|
|
lastmousey = X_event.xmotion.y;
|
|
if (X_event.xmotion.x != X_width/2 &&
|
|
X_event.xmotion.y != X_height/2)
|
|
{
|
|
D_PostEvent(&event);
|
|
// fprintf(stderr, "m");
|
|
mousemoved = false;
|
|
} else
|
|
{
|
|
mousemoved = true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Expose:
|
|
case ConfigureNotify:
|
|
break;
|
|
|
|
default:
|
|
if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
|
|
break;
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
//
|
|
// I_StartTic
|
|
//
|
|
void I_StartTic (void)
|
|
{
|
|
|
|
return;
|
|
|
|
/*
|
|
|
|
if (!X_display)
|
|
return;
|
|
|
|
while (XPending(X_display))
|
|
I_GetEvent();
|
|
|
|
// Warp the pointer back to the middle of the window
|
|
// or it will wander off - that is, the game will
|
|
// loose input focus within X11.
|
|
if (grabMouse)
|
|
{
|
|
if (!--doPointerWarp)
|
|
{
|
|
XWarpPointer( X_display,
|
|
None,
|
|
X_mainWindow,
|
|
0, 0,
|
|
0, 0,
|
|
X_width/2, X_height/2);
|
|
|
|
doPointerWarp = POINTER_WARP_COUNTDOWN;
|
|
}
|
|
}
|
|
|
|
mousemoved = false;
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// I_UpdateNoBlit
|
|
//
|
|
void I_UpdateNoBlit (void)
|
|
{
|
|
// what is this?
|
|
}
|
|
|
|
//
|
|
// I_FinishUpdate
|
|
//
|
|
#define FB_WIDTH (480)
|
|
#define FB_HEIGHT (272)
|
|
#define FB_BPP_RGB565 (16)
|
|
|
|
unsigned char line_out[FB_WIDTH * (FB_BPP_RGB565/8)];
|
|
|
|
void cmap_to_rgb565(uint16_t * out, uint8_t * in, int in_pixels)
|
|
{
|
|
int i;
|
|
struct color c;
|
|
uint16_t r, g, b;
|
|
|
|
for (i = 0; i < in_pixels; i++)
|
|
{
|
|
c = colors[*in];
|
|
r = ((uint16_t)(c.r >> 3)) << 11;
|
|
g = ((uint16_t)(c.g >> 2)) << 5;
|
|
b = ((uint16_t)(c.b >> 3)) << 0;
|
|
*out = (r | g | b);
|
|
|
|
in++;
|
|
out++;
|
|
}
|
|
}
|
|
|
|
void I_FinishUpdate (void)
|
|
{
|
|
unsigned char *line_in;
|
|
static int lasttic;
|
|
int tics;
|
|
int i;
|
|
int y;
|
|
|
|
// draws little dots on the bottom of the screen
|
|
if (devparm)
|
|
{
|
|
i = I_GetTime();
|
|
tics = i - lasttic;
|
|
lasttic = i;
|
|
if (tics > 20) tics = 20;
|
|
|
|
for (i=0 ; i<tics*2 ; i+=2)
|
|
screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
|
|
for ( ; i<20*2 ; i+=2)
|
|
screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
|
|
}
|
|
|
|
/* DRAW SCREEN */
|
|
line_in = (unsigned char *) screens[0];
|
|
lseek(fd_fb, 0, SEEK_SET);
|
|
y = SCREENHEIGHT;
|
|
|
|
#define CMAP256
|
|
|
|
#ifdef CMAP256
|
|
while (y--)
|
|
{
|
|
write(fd_fb, line_in, FB_WIDTH); /* FB_WIDTH is bigger then Doom SCREENWIDTH... */
|
|
line_in += SCREENWIDTH;
|
|
}
|
|
#else
|
|
while (y--)
|
|
{
|
|
cmap_to_rgb565(line_out, line_in, SCREENWIDTH);
|
|
write(fd_fb, line_out, FB_WIDTH * (FB_BPP_RGB565/8));
|
|
line_in += SCREENWIDTH;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
//
|
|
// I_ReadScreen
|
|
//
|
|
void I_ReadScreen (byte* scr)
|
|
{
|
|
/* Our framebuffer is not the same resolution, so makes reading difficult */
|
|
//lseek(fd_fb, 0, SEEK_SET);
|
|
//int left = SCREENWIDTH * SCREENHEIGHT;
|
|
//while (left)
|
|
//{
|
|
// int rd = read(fd_fb, scr, left);
|
|
// if (rd > 0)
|
|
// left -= rd;
|
|
//}
|
|
memcpy(scr, screens[0], SCREENWIDTH * SCREENHEIGHT);
|
|
}
|
|
|
|
|
|
//
|
|
// I_SetPalette
|
|
//
|
|
void I_SetPalette (byte* palette)
|
|
{
|
|
//printf("I_SetPalette\n");
|
|
|
|
for (int i=0; i<256; ++i ) {
|
|
colors[i].a = 0;
|
|
colors[i].r = gammatable[usegamma][*palette++];
|
|
colors[i].g = gammatable[usegamma][*palette++];
|
|
colors[i].b = gammatable[usegamma][*palette++];
|
|
}
|
|
|
|
/* Set new color map in kernel framebuffer driver */
|
|
ioctl(fd_fb, IOCTL_FB_PUTCMAP, colors);
|
|
}
|
|
|
|
void I_InitGraphics(void)
|
|
{
|
|
unsigned char * screen_pixels;
|
|
|
|
X_width = SCREENWIDTH;
|
|
X_height = SCREENHEIGHT;
|
|
|
|
printf("I_InitGraphics: w x h: %d x %d\n", X_width, X_height);
|
|
|
|
/* Open fbdev file descriptor */
|
|
fd_fb = open("/dev/fb0", O_RDWR);
|
|
if (fd_fb < 0)
|
|
{
|
|
printf("Could not open /dev/fb0");
|
|
exit(-1);
|
|
}
|
|
|
|
/* Allocate screen to draw to */
|
|
screen_pixels = malloc(X_width * X_height);
|
|
|
|
screens[0] = (unsigned char *)screen_pixels;
|
|
}
|
|
|
|
|