diff -urN linuxdoom-1.10-orig/Makefile linuxdoom-1.10/Makefile --- linuxdoom-1.10-orig/Makefile Mon Dec 22 14:55:36 1997 +++ linuxdoom-1.10/Makefile Fri Feb 12 08:03:51 1999 @@ -7,8 +7,8 @@ CC= gcc # gcc or g++ CFLAGS=-g -Wall -DNORMALUNIX -DLINUX # -DUSEASM -LDFLAGS=-L/usr/X11R6/lib -LIBS=-lXext -lX11 -lnsl -lm +LDFLAGS= +LIBS=-lm -lkb # subdirectory for objects O=linux @@ -20,7 +20,7 @@ $(O)/dstrings.o \ $(O)/i_system.o \ $(O)/i_sound.o \ - $(O)/i_video.o \ + $(O)/fb_video.o \ $(O)/i_net.o \ $(O)/tables.o \ $(O)/f_finale.o \ diff -urN linuxdoom-1.10-orig/README.fb linuxdoom-1.10/README.fb --- linuxdoom-1.10-orig/README.fb Wed Dec 31 19:00:00 1969 +++ linuxdoom-1.10/README.fb Fri Feb 12 09:04:56 1999 @@ -0,0 +1,41 @@ +Doom 1.10 for the linux framebuffer +----------------------------------- + Release 12feb1999 +by Sam Creasey (sammy@users.qual.net) + +This is, basically, a port of Doom for the linux framebuffer device, +so that those of us who don't want to play their games in X can +actually have source code for something that runs on the console. + +It requires that a framebuffer device exist, either defined in the +enviornment variable FRAMEBUFFER or /dev/fd0 by default. The +framebuffer device must use a truecolor visual. (most, if not all, +15, 16, 24, or 32bpp modes should work.) + +It also requires libkb, which lives at +http://wildsau.idv.uni-linz.ac.at/mfx/libkb.html. It can also be +found at ftp://sunsite.unc.edu/pub/Linux/libs/ui/. For anyone who +needs to work with the linux console, it's a hell of a package, if +quite underdocumented. This port wouldn't have been possible without +it. + +It defaults to running at 320x200 in a window which will appear in the +corner of your screen. Changing the settings for multiply (near the +top of fb_video.c) will increase the resolution. (e.g. multiply=2 == +640x400, and so on). + +The code to draw the screens when multiplied could probably stand to +be a good bit prettier. + +There's also a problem with error messages, and other crap on the +screen causing the console to scroll. I have compensated for this, +but there's got to be a better way. + +GPM support could probably be added without a significant amount of +hassle, but I've never been a big fan of playing with the mouse, so +I'm not in any particular hurry to get there. + +The fb_video code is based on the gnome_video code from gnoom, a port +of Doom to gnome, originally by Alan Cox. + +Questions/Comments/Patches to: Sam Creasey (sammy@users.qual.net) diff -urN linuxdoom-1.10-orig/fb_video.c linuxdoom-1.10/fb_video.c --- linuxdoom-1.10-orig/fb_video.c Wed Dec 31 19:00:00 1969 +++ linuxdoom-1.10/fb_video.c Fri Feb 12 09:32:49 1999 @@ -0,0 +1,799 @@ +//----------------------------------------------------------------------------- +// +// This source module provides GNOME compatibility with Doom +// +// (c) 1997 Alan Cox +// +//----------------------------------------------------------------------------- +// Those days are long gone, however, as this puppy now provides an fb +// layer for use with doom. yeehaw. (c) 1999 Sam Creasey + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "doomstat.h" +#include "i_system.h" +#include "v_video.h" +#include "m_argv.h" +#include "d_main.h" + +#include "doomdef.h" + +#define POINTER_WARP_COUNTDOWN 1 + +int X_width=320; +int X_height=200; +static int X_depth; +static char *fbmem; +static struct fb_var_screeninfo varinfo; +static struct fb_fix_screeninfo fixinfo; +static int fbfd; + +// Fake mouse handling. +// This cannot work properly w/o DGA. +// Needs an invisible mouse cursor at least. +boolean grabMouse; +int doPointerWarp = POINTER_WARP_COUNTDOWN; + +// Blocky mode, +// replace each 320x200 pixel with multiply*multiply pixels. +// According to Dave Taylor, it still is a bonehead thing +// to use .... + +static int multiply=2; + +unsigned long long rgb_map[256]; + +// +// Translates the key currently in X_event +// + +int xlatekey(int ch) +{ + + switch(ch) { + case KB_SCAN_ENTER: + return KEY_ENTER; + case KB_SCAN_TAB: + return KEY_TAB; + case KB_SCAN_DELETE: + case KB_SCAN_BACKSPACE: + return KEY_BACKSPACE; + case KB_SCAN_MINUS: /* minus */ + return KEY_MINUS; + case KB_SCAN_EQUAL: + return KEY_EQUALS; + case KB_SCAN_LSHIFT: + case KB_SCAN_RSHIFT: + return KEY_RSHIFT; + case KB_SCAN_LCONTROL: + case KB_SCAN_RCONTROL: + return KEY_RCTRL; + case KB_SCAN_ALT: + case KB_SCAN_ALTGR: + return KEY_RALT; + case KB_SCAN_ESC: + return KEY_ESCAPE; + case KB_SCAN_LEFT: + return KEY_LEFTARROW; + case KB_SCAN_RIGHT: + return KEY_RIGHTARROW; + case KB_SCAN_UP: + return KEY_UPARROW; + case KB_SCAN_DOWN: + return KEY_DOWNARROW; + case KB_SCAN_SPACE: + return ' '; + case KB_SCAN_F1: + return KEY_F1; + case KB_SCAN_F2: + return KEY_F2; + case KB_SCAN_F3: + return KEY_F3; + case KB_SCAN_F4: + return KEY_F4; + case KB_SCAN_F5: + return KEY_F5; + case KB_SCAN_F6: + return KEY_F6; + case KB_SCAN_F7: + return KEY_F7; + case KB_SCAN_F8: + return KEY_F8; + case KB_SCAN_F9: + return KEY_F9; + case KB_SCAN_F10: + return KEY_F10; + case KB_SCAN_F11: + return KEY_F11; + case KB_SCAN_F12: + return KEY_F12; + default: + return tolower(kb_keyname(ch)[0]); + } +} + +void I_ShutdownGraphics(void) +{ + ; +} + + + +// +// I_StartFrame +// +void I_StartFrame (void) +{ + // er? + +} + +static int lastmousex = 0; +static int lastmousey = 0; +boolean mousemoved = false; +boolean shmFinished; + +kb_handler_callback_t I_GetEvent(int kevent) +{ + + event_t event; + + if(kevent & 0x80) { + event.type = ev_keyup; + event.data1 = xlatekey(kevent & 0x7f); + D_PostEvent(&event); + } else { + event.type = ev_keydown; + event.data1 = xlatekey(kevent); + D_PostEvent(&event); + } +#if 0 + 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; + } +#endif + + return; + +} + +#if 0 +Cursor createnullcursor +( Display* display, + Window root ) +{ +// +// Write me ;) +// +} +#endif + +// +// I_StartTic +// +// Start of a time tick. Empty any pending events through gtk_main_iteration +// (I hope thats right) then set things going. +// + +void I_StartTic (void) +{ + // 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 0 + if (grabMouse) + { + if (!--doPointerWarp) + { + XWarpPointer( X_display, + None, + X_mainWindow, + 0, 0, + 0, 0, + X_width/2, X_height/2); + + doPointerWarp = POINTER_WARP_COUNTDOWN; + } + } +#endif + + kb_update(); + mousemoved = false; + +} + + +// +// I_UpdateNoBlit +// +void I_UpdateNoBlit (void) +{ + // what is this? +} + +// +// I_FinishUpdate +// + +/* + * Called at the end of a rendering of a frame. + */ +void I_FinishUpdate (void) +{ + static int lasttic; + int tics; + int i; + // UNUSED static unsigned char *bigscreen=0; + + // 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 ; idata[i*X_width]; + + y = SCREENHEIGHT; + while (y--) + { + x = SCREENWIDTH; + do + { + fouripixels = *ilineptr++; + twoopixels = (fouripixels & 0xff000000) + | ((fouripixels>>8) & 0xffff00) + | ((fouripixels>>16) & 0xff); + twomoreopixels = ((fouripixels<<16) & 0xff000000) + | ((fouripixels<<8) & 0xffff00) + | (fouripixels & 0xff); +#ifdef __BIG_ENDIAN__ + *olineptrs[0]++ = twoopixels; + *olineptrs[1]++ = twoopixels; + *olineptrs[0]++ = twomoreopixels; + *olineptrs[1]++ = twomoreopixels; +#else + *olineptrs[0]++ = twomoreopixels; + *olineptrs[1]++ = twomoreopixels; + *olineptrs[0]++ = twoopixels; + *olineptrs[1]++ = twoopixels; +#endif + } while (x-=4); + olineptrs[0] += X_width/4; + olineptrs[1] += X_width/4; + } + + } + else if (multiply == 3) + { + unsigned int *olineptrs[3]; + unsigned int *ilineptr; + int x, y, i; + unsigned int fouropixels[3]; + unsigned int fouripixels; + + ilineptr = (unsigned int *) (screens[0]); + for (i=0 ; i<3 ; i++) + olineptrs[i] = (unsigned int *) &image->data[i*X_width]; + + y = SCREENHEIGHT; + while (y--) + { + x = SCREENWIDTH; + do + { + fouripixels = *ilineptr++; + fouropixels[0] = (fouripixels & 0xff000000) + | ((fouripixels>>8) & 0xff0000) + | ((fouripixels>>16) & 0xffff); + fouropixels[1] = ((fouripixels<<8) & 0xff000000) + | (fouripixels & 0xffff00) + | ((fouripixels>>8) & 0xff); + fouropixels[2] = ((fouripixels<<16) & 0xffff0000) + | ((fouripixels<<8) & 0xff00) + | (fouripixels & 0xff); +#ifdef __BIG_ENDIAN__ + *olineptrs[0]++ = fouropixels[0]; + *olineptrs[1]++ = fouropixels[0]; + *olineptrs[2]++ = fouropixels[0]; + *olineptrs[0]++ = fouropixels[1]; + *olineptrs[1]++ = fouropixels[1]; + *olineptrs[2]++ = fouropixels[1]; + *olineptrs[0]++ = fouropixels[2]; + *olineptrs[1]++ = fouropixels[2]; + *olineptrs[2]++ = fouropixels[2]; +#else + *olineptrs[0]++ = fouropixels[2]; + *olineptrs[1]++ = fouropixels[2]; + *olineptrs[2]++ = fouropixels[2]; + *olineptrs[0]++ = fouropixels[1]; + *olineptrs[1]++ = fouropixels[1]; + *olineptrs[2]++ = fouropixels[1]; + *olineptrs[0]++ = fouropixels[0]; + *olineptrs[1]++ = fouropixels[0]; + *olineptrs[2]++ = fouropixels[0]; +#endif + } while (x-=4); + olineptrs[0] += 2*X_width/4; + olineptrs[1] += 2*X_width/4; + olineptrs[2] += 2*X_width/4; + } + + } + else if (multiply == 4) + { + // Broken. Gotta fix this some day. + void Expand4(unsigned *, double *); + Expand4 ((unsigned *)(screens[0]), (double *) (image->data)); + } +#endif + + /* pallete conversion, copy 1/2/4 bytes as needed for our bit depth, + except that psuedocolor doesn't work yet */ + + { + int x,y; + int pixsize = X_depth / 8; + void *dptr= fbmem; + unsigned char *sptr=screens[0]; + int xgap = fixinfo.line_length - (X_width * pixsize); + + /* the screen might have been scrolled, so update */ + if(ioctl(fbfd, FBIOGET_VSCREENINFO, &varinfo) == -1) + I_Error("ioctl: FBIOGET_VSCREENINFO"); + + dptr += fixinfo.line_length*varinfo.yoffset; + + /* If there is an asm candidate its probably this one */ + + if(multiply==4) + { + void *dptrh=dptr; + void *dptrhm=dptrh+fixinfo.line_length; + void *dptrlm=dptrhm+fixinfo.line_length; + void *dptrl=dptrlm+fixinfo.line_length; + for(y=0;y>(8-varinfo.red.length); + int g=gammatable[usegamma][*palette++]>>(8-varinfo.green.length); + int b=gammatable[usegamma][*palette++]>>(8-varinfo.blue.length); + + rgb_map[i] = (r << varinfo.red.offset) | + (g << varinfo.green.offset) | (b << varinfo.blue.offset); + } + +} + +// +// I_SetPalette +// +void I_SetPalette (byte* palette) +{ + UploadNewPalette(palette); +} + +void I_InitGraphics(void) +{ + + static int firsttime=1; + char *fbdev; + int mapsize; + + if (!firsttime) + return; + firsttime = 0; + + if((fbdev = getenv("FRAMEBUFFER")) == NULL) + fbdev = strdup("/dev/fb0"); + + if((fbfd = open(fbdev, O_RDWR)) == -1) + I_Error("Unable to open framebuffer"); + + signal(SIGINT, (void (*)(int)) I_Quit); + + X_width = SCREENWIDTH * multiply; + X_height = SCREENHEIGHT * multiply; + + if(ioctl(fbfd, FBIOGET_VSCREENINFO, &varinfo) == -1) + I_Error("ioctl: FBIOGET_VSCREENINFO"); + + if((X_width > varinfo.xres) || (X_height > varinfo.yres)) + I_Error("Desired screen size greater than current resolution"); + + if(ioctl(fbfd, FBIOGET_FSCREENINFO, &fixinfo) == -1) + I_Error("ioctl: FBIOGET_FSCREENINFO"); + + if(fixinfo.visual != FB_VISUAL_TRUECOLOR) + { + I_Error("fbdoom currently only supports truecolor visuals"); + } + + + X_depth = varinfo.bits_per_pixel; + + mapsize = fixinfo.line_length*varinfo.yres_virtual; + fbmem = mmap(0, mapsize, + PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + + kb_install(0); + kb_handler_mediumraw_callback = I_GetEvent; + kb_update(); + + screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT); + +} + + +unsigned exptable[256]; + +void InitExpand (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + exptable[i] = i | (i<<8) | (i<<16) | (i<<24); +} + +double exptable2[256*256]; + +void InitExpand2 (void) +{ + int i; + int j; + // UNUSED unsigned iexp, jexp; + double* exp; + union + { + double d; + unsigned u[2]; + } pixel; + + printf ("building exptable2...\n"); + exp = exptable2; + for (i=0 ; i<256 ; i++) + { + pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24); + for (j=0 ; j<256 ; j++) + { + pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24); + *exp++ = pixel.d; + } + } + printf ("done.\n"); +} + +int inited; + +void +Expand4 +( unsigned* lineptr, + double* xline ) +{ + double dpixel; + unsigned x; + unsigned y; + unsigned fourpixels; + unsigned step; + double* exp; + + exp = exptable2; + if (!inited) + { + inited = 1; + InitExpand2 (); + } + + + step = 3*SCREENWIDTH/2; + + y = SCREENHEIGHT-1; + do + { + x = SCREENWIDTH; + + do + { + fourpixels = lineptr[0]; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); + xline[0] = dpixel; + xline[160] = dpixel; + xline[320] = dpixel; + xline[480] = dpixel; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); + xline[1] = dpixel; + xline[161] = dpixel; + xline[321] = dpixel; + xline[481] = dpixel; + + fourpixels = lineptr[1]; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); + xline[2] = dpixel; + xline[162] = dpixel; + xline[322] = dpixel; + xline[482] = dpixel; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); + xline[3] = dpixel; + xline[163] = dpixel; + xline[323] = dpixel; + xline[483] = dpixel; + + fourpixels = lineptr[2]; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); + xline[4] = dpixel; + xline[164] = dpixel; + xline[324] = dpixel; + xline[484] = dpixel; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); + xline[5] = dpixel; + xline[165] = dpixel; + xline[325] = dpixel; + xline[485] = dpixel; + + fourpixels = lineptr[3]; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); + xline[6] = dpixel; + xline[166] = dpixel; + xline[326] = dpixel; + xline[486] = dpixel; + + dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); + xline[7] = dpixel; + xline[167] = dpixel; + xline[327] = dpixel; + xline[487] = dpixel; + + lineptr+=4; + xline+=8; + } while (x-=16); + xline += step; + } while (y--); +} + + diff -urN linuxdoom-1.10-orig/s_sound.c linuxdoom-1.10/s_sound.c --- linuxdoom-1.10-orig/s_sound.c Mon Dec 22 16:01:29 1997 +++ linuxdoom-1.10/s_sound.c Fri Feb 12 09:05:51 1999 @@ -368,8 +368,8 @@ // cache data if necessary if (!sfx->data) { - fprintf( stderr, - "S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n"); +// fprintf( stderr, +// "S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n"); // DOS remains, 8bit handling //sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC);