ReactOS build 61112

So I thought I’d look for the latest release build of ReactOS, and give it a whirl.  First I download 61112, and installed it on Qemu 1.7rc2 on OS X.  First I gave the VM a 500MB disk, and 500MB of ram… which led to the thing using the whole disk for paging and was terribly unstable, and all around no good.

So next I got smart, used 64MB of ram, and a 1Gig disk, installed then turned off swap.  Now it is more usable.  I thought I’d do something crazy, and install Visual C++ 4.0.  The installer works, except there is no progress, and it can’t create program groups.  No problem I think as it does the same thing on CrossOver(wine).  I download my QWDOS project with firefox, extract, and open the makefile and… all the menus are blanked out.  And dropping down to the CLI, although the installer ‘registered environment variables’ the compiler wasn’t in the path.  Clearly registry information is dropping.

NO Build for you!

NO Build for you!

So falling back to nmake I can at least compile my release build, and amazingly -it works!

QWDOS Win32 on ReactOS

QWDOS Win32 on ReactOS

So is it perfect? No far from it, but it certainly is a lot more usable than it was a year ago.

Qemu enters the 1.7 testing phase

I built 1.7rc2 on OSX, and I’ve only tested the x86 portion… x86_64 of course still fails on vista & friends… 2003 of course hangs at “starting windows” so no progress there.  I haven’t tried any MIPS, PowerPC, or SPARC things…

Also the Adlib/SoundBlaster is still broken in this release, there is a source change in adlib.c that has to be made.  Also I just noticed that IRQ sharing works in ISA mode again, so the Ne2000 can go back to 0x300 IRQ 9.

Also speaking of emulation, I was thinking of shoving a VAX-11/780 into the world for the heck of it.  Although I don’t think anyone would care.  I’ll have to dig out the source to 4.3 and give the shell the ability to add new users.  I wrote it once, and I fear I’ve lost those changes but it was cool for something back then.

Anyways post back here if you want an account on vax.superglobalmegacorp.com !

ReactOS gets a NTVDM

Really I saw it right here!  It is only in it’s beginning stages, but it can run some very simple COM programs.

I should also say, I ran a nightly build, and it is coming along much more than the last year.. I didn’t trap or anything messing around.  What I did do was run out of disk space with a large swap file, and downloading too much crap….

Raspberry Pi Floppy emulator

A good friend passed on this link.  And what an amazing thing!

Floppy interface board

So basically a Raspberry Pi (which can be had for sub $50 USD), running a bare metal program can emulate the control signals of an Amiga floppy drive.  It reads disk files from a flash card, and serves them to the Amiga.  It can even kickstart an Amiga 1000.

I know that floppy emulators have been an on/off hot topic, but this is pretty interesting!

And of course it has a DIY angle to it as well.

Here is a video of it in action:

 

VIM the Virtual Machine debugger

I stumbled across this site a while back, but could never get it to run.  From the description VIM is:

..(vim) is a debugger, I can’t let a bad program take out the interrupt vectors, DOS, or whatever. Hence the “Virtual” in the name — VIM takes whatever memory it can get, and sets up the interpreter to use a “virtual” processor. So, when the interpreter uses Interrupts, DOS, etc, it’s using the virtual copy, so that a bad program destroying them won’t hurt VIM, the real DOS, real interrupt vectors, etc.

Which is very cool, unlike traditional debuggers which try to hide in memory, VIM executes outside of memory and is then invisible.  Unfortunately it is rather tied to ANCIENT hardware.  And executes better on an 8088/8086/80286 processor.  I thought I could run it on Qemu, but it’ll trap on the BIOS as it’ll have instructions outside of VIM’s understanding.  However using PCem’s 80286 emulation it’ll run fine.

VIM running MS-DOS

VIM running MS-DOS

Another interesting thing about VIM, is that it includes the full source code, which is built with Aztec/C, however it doesn’t build cleanly as you have to finagle some of the assembly.

Running this on PCem is quite nice, as you can set it for a FAST 80286 computer, so it won’t take 10 minutes to boot a virtual copy of MS-DOS.

Is this useful? Well maybe if you feel the need to write an MS-DOS device driver, VIM can debug it.. but otherwise, it is an interesting fossil.

Linux on the VAX

I don’t know how I missed this thing!

$ cat lvax
load -r ka655.bin
set rq0 ra92
att rq0 /tmp/vmlinux.dsk
att xq dummy0
boot cpu
$ ./vax lvax

MicroVAX 3900 simulator V4.0-0 Beta git commit id: 55c5d205

KA655-B V5.3, VMB 2.7
Performing normal system tests.
40..39..38..37..36..35..34..33..32..31..30..29..28..27..26..25..
24..23..22..21..20..19..18..17..16..15..14..13..12..11..10..09..
08..07..06..05..04..03..
Tests completed.
>>>show dev
UQSSP Disk Controller 0 (772150)
-DUA0 (RA92)
-DUA1 (RD54)
-DUA2 (RD54)
-DUA3 (RX50)

UQSSP Tape Controller 0 (774500)
-MUA0 (TK50)
-MUA1 (TK50)
-MUA2 (TK50)
-MUA3 (TK50)

RLV12 Controller 0 (774400)
-DLA0 (RL01)
-DLA1 (RL01)
-DLA2 (RL01)
-DLA3 (RL01)

Ethernet Adapter 0 (774440)
-XQA0 (08-00-2B-AA-BB-CC)
>>>boot dua0:
(BOOT/R5:0 DUA0

2..
-DUA0
1..0..

CPU type:
80004A04KA650
Boot Head.S loaded at address 00004A00
rpb/bootr5/ap/sp 00000000 00000000 00000344 00004800
relocated at phys address 00100307
CPU type: 0A000006 sidex: 01530302

Starting VM
Linux/VAX (linux-vax@mithra.physics.montana.edu)
KA650 sidex = 01530302
RPB info: l_pfncnt: 00007f98, .l_vmb_version: 0a000207 .l_badpgs: 00000000
Physical memory: 00007f98 HW pagelets, 00000ff3 pages (16332KB)
CPU type: KA650, SID: 00000000
VM: mapped physical from 80000000 to 80ff3000, iomap from 80ff3000
VM: vmalloc from 810f3000 to 814f3000
VM: ptemap from 814f4000 to 837f4000 for 64 processes
calling start_kernel…

Linux version 2.4.16 (airlied@radon.limerick.parthus.com) (gcc version 2.95.2-linuxvax-dynamic-dev (CVS)) #28 Wed Feb 12 09:55:28 GMT 2003
kernel_cmd_line 80004a04
root=/dev/nfs ip=192.168.5.240:192.168.5.67:::vaxemu:eth0:none nfsroot=/mnt/redhat/vax_emu/vaxroot rw debug init=/bin/sh
VAXMM: Initialising mm layer for 64 tasks of size 64MB
VAXMM: system page table base 8020b800, length (bytes) 6fe80 length (ptes) 1bfa0
bootmap size = 00000200
calling free_bootmem(start=00001000, len=000ff000)
calling free_bootmem(start=0027c000, len=00d77000)
On node 0 totalpages: 4083
zone(0): 4083 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/nfs ip=192.168.5.240:192.168.5.67:::vaxemu:eth0:none nfsroot=/mnt/redhat/vax_emu/vaxroot rw debug init=/bin/sh
Calibrating delay loop… 23.29 BogoMIPS
Memory: 14556k/16332k available
Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes)
Inode-cache hash table entries: 1024 (order: 1, 8192 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with no serial options enabled
block: 64 slots per queue, batch=16
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
IO mapped phys addr 0x20088000, 0x0008 pages at virt 0x80ff3000 (IOMAP PTE index 0x0000)
ttyS0: Internal processor register console
IO mapped phys addr 0x20001000, 0x0001 pages at virt 0x80ffb000 (IOMAP PTE index 0x0008)
delqa qbus vector: 4 (0004, 0x0004)
Ethernet address in ROM: 08:00:2b:aa:bb:cc
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
eth0: resetting DELQA… done
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.5.240, mask=255.255.255.0, gw=255.255.255.255,
host=vaxemu, domain=, nis-domain=(none),
bootserver=192.168.5.67, rootserver=192.168.5.67, rootpath=
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Looking up port of RPC 100003/2 on 192.168.5.67

I’m amazed that it runs this far under SIMH.  Sadly though disks are not supported on any of the SIMH models, as Linux relies on certain CPU models:

  • VAXstation 3100m76 (KA43 CPU)
  • VAXstation 3100m38 (KA42 CPU)

The project has moved from sourceforge, to a dedicated server.  Sadly it seems that it has been a few years between updates, but I guess someone could carry the torch….

QuakeWorld Clients

I thought Id’ take a few hours to update some builds based on the latest QWDOS source.

So I spent a few hours updating some QuakeWorld clients.. for reproducibility sakes, I built out the MS-DOS one and that worked fine.  The OS/2 one ‘works’ but the keyboard isn’t working.  Not so sure why not.  The Win32 version works fine, although I’m building with Visual C++ 4.0, and no assembly or DirectX.  Just straight GDI.

Next will be Linux with svgalib.

So my work is here.  I could go more into how to build, but I don’t know if anyone cares.

Building a super stock QuakeWorld server for Linux

I know this may sound silly, but I’m a silly person.  And yes, QuakeWorld used to build cleanly and fine on Linux.  However it doesn’t anymore, things have changed a *LOT* in the world of Linux, since the birth of QuakeWorld in 1996.  A different LIBC standard or two, and all kinds of other changes in the compiler.  Not to mention I have a x86_64 machine, and I want a pure 32bit binary, so the best way to go about that is to setup a 32bit virtual machine, and build from there.  I know I could cross compile, but on the otherhand I don’t want to install all this kind of crap on my server if I don’t have to.  So there is all kinds of reasons why you may want to build your own.  Not to mention if you are running Linux, but on a non x86 platform.  I guess the Raspberry Pi would be a good choice now that it is over two million units sold.

The first thing you need of course is the source code to Quake, from iD (my mirror).  Next you’ll need a more up to date Makefile.  I used the one from the LinuxGL-QuakeWorld-mini-HOWTO.  Don’t worry about the client stuff, it doesn’t matter the first thing it does anyways is build the server.

For the sake of preserving it, here is the makefile:

#
# QuakeWorld Makefile for Linux 2.0
#
# Apr '98 by Zoid <zoid@idsoftware.com>
#
# GNU Make required
#
# ELF only
#

MAINDIR=.

BUILD_RELEASE_DIR=bin
CLIENT_DIR=$(MAINDIR)/client
SERVER_DIR=$(MAINDIR)/server

CC=gcc
BASE_CFLAGS=-Wall -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR)
RELEASE_CFLAGS=$(BASE_CFLAGS) -m486 -ffast-math -fexpensive-optimizations
GLCFLAGS=-DGLQUAKE -DGL_EXT_SHARED

LDFLAGS=-lm
XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext
GL_X11_LDFLAGS=-L/usr/X11R6/lib -lm -lGL -lX11 -lXext

DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
DO_O_CC=$(CC) -O $(CFLAGS) -o $@ -c $<
DO_GL_CC=$(CC) $(CFLAGS) $(GLCFLAGS) -o $@ -c $<
DO_SERVER_CC=$(CC) -DSERVERONLY $(CFLAGS) -o $@ -c $<

DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $<
DO_GL_AS=$(CC) $(CFLAGS) $(GLCFLAGS) -DELF -x assembler-with-cpp -o $@ -c $<

#############################################################################
# SETUP AND BUILD
#############################################################################

TARGETS=$(BUILDDIR)/qwsv #$(BUILDDIR)/glqwcl.glx $(BUILDDIR)/qwcl.x11

build_release:
  @-mkdir $(BUILD_RELEASE_DIR) \
    $(BUILD_RELEASE_DIR)/client \
    $(BUILD_RELEASE_DIR)/glclient \
    $(BUILD_RELEASE_DIR)/server
  $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)"

all: build_release

targets: $(TARGETS)

#############################################################################
# SERVER
#############################################################################

QWSV_OBJS = \
   $(BUILDDIR)/server/pr_cmds.o \
   $(BUILDDIR)/server/pr_edict.o \
   $(BUILDDIR)/server/pr_exec.o \
   $(BUILDDIR)/server/sv_init.o \
   $(BUILDDIR)/server/sv_main.o \
   $(BUILDDIR)/server/sv_nchan.o \
   $(BUILDDIR)/server/sv_ents.o \
   $(BUILDDIR)/server/sv_send.o \
   $(BUILDDIR)/server/sv_move.o \
   $(BUILDDIR)/server/sv_phys.o \
   $(BUILDDIR)/server/sv_user.o \
   $(BUILDDIR)/server/sv_ccmds.o \
   $(BUILDDIR)/server/world.o \
   $(BUILDDIR)/server/sys_unix.o \
   $(BUILDDIR)/server/model.o \
   $(BUILDDIR)/server/cmd.o \
   $(BUILDDIR)/server/common.o \
   $(BUILDDIR)/server/crc.o \
   $(BUILDDIR)/server/cvar.o \
   $(BUILDDIR)/server/mathlib.o \
   $(BUILDDIR)/server/md4.o \
   $(BUILDDIR)/server/zone.o \
   $(BUILDDIR)/server/pmove.o \
   $(BUILDDIR)/server/pmovetst.o \
   $(BUILDDIR)/server/net_chan.o \
   $(BUILDDIR)/server/net_udp.o

$(BUILDDIR)/qwsv : $(QWSV_OBJS)
  $(CC) $(CFLAGS) -o $@ $(QWSV_OBJS) $(LDFLAGS)

$(BUILDDIR)/server/pr_cmds.o :   $(SERVER_DIR)/pr_cmds.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/pr_edict.o :  $(SERVER_DIR)/pr_edict.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/pr_exec.o :   $(SERVER_DIR)/pr_exec.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_init.o :   $(SERVER_DIR)/sv_init.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_main.o :   $(SERVER_DIR)/sv_main.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_nchan.o :  $(SERVER_DIR)/sv_nchan.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_ents.o :   $(SERVER_DIR)/sv_ents.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_send.o :   $(SERVER_DIR)/sv_send.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_move.o :   $(SERVER_DIR)/sv_move.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_phys.o :   $(SERVER_DIR)/sv_phys.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_user.o :   $(SERVER_DIR)/sv_user.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sv_ccmds.o :  $(SERVER_DIR)/sv_ccmds.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/world.o :     $(SERVER_DIR)/world.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/sys_unix.o :  $(SERVER_DIR)/sys_unix.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/model.o :     $(SERVER_DIR)/model.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/cmd.o :       $(CLIENT_DIR)/cmd.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/common.o :    $(CLIENT_DIR)/common.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/crc.o :       $(CLIENT_DIR)/crc.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/cvar.o :      $(CLIENT_DIR)/cvar.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/mathlib.o :   $(CLIENT_DIR)/mathlib.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/md4.o :       $(CLIENT_DIR)/md4.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/zone.o :      $(CLIENT_DIR)/zone.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/pmove.o :     $(CLIENT_DIR)/pmove.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/pmovetst.o :  $(CLIENT_DIR)/pmovetst.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/net_chan.o :  $(CLIENT_DIR)/net_chan.c
  $(DO_SERVER_CC)

$(BUILDDIR)/server/net_udp.o :   $(CLIENT_DIR)/net_udp.c
  $(DO_SERVER_CC)

#############################################################################
# CLIENT
#############################################################################

QWCL_OBJS = \
  $(BUILDDIR)/client/cl_demo.o \
  $(BUILDDIR)/client/cl_ents.o \
  $(BUILDDIR)/client/cl_input.o \
  $(BUILDDIR)/client/cl_main.o \
  $(BUILDDIR)/client/cl_parse.o \
  $(BUILDDIR)/client/cl_pred.o \
  $(BUILDDIR)/client/cl_tent.o \
  $(BUILDDIR)/client/cl_cam.o \
  $(BUILDDIR)/client/cmd.o \
  $(BUILDDIR)/client/common.o \
  $(BUILDDIR)/client/console.o \
  $(BUILDDIR)/client/crc.o \
  $(BUILDDIR)/client/cvar.o \
  $(BUILDDIR)/client/d_edge.o \
  $(BUILDDIR)/client/d_fill.o \
  $(BUILDDIR)/client/d_init.o \
  $(BUILDDIR)/client/d_modech.o \
  $(BUILDDIR)/client/d_part.o \
  $(BUILDDIR)/client/d_polyse.o \
  $(BUILDDIR)/client/d_scan.o \
  $(BUILDDIR)/client/d_sky.o \
  $(BUILDDIR)/client/d_sprite.o \
  $(BUILDDIR)/client/d_surf.o \
  $(BUILDDIR)/client/d_vars.o \
  $(BUILDDIR)/client/d_zpoint.o \
  $(BUILDDIR)/client/draw.o \
  $(BUILDDIR)/client/keys.o \
  $(BUILDDIR)/client/mathlib.o \
  $(BUILDDIR)/client/md4.o \
  $(BUILDDIR)/client/menu.o \
  $(BUILDDIR)/client/model.o \
  $(BUILDDIR)/client/net_chan.o \
  $(BUILDDIR)/client/net_udp.o \
  $(BUILDDIR)/client/nonintel.o \
  $(BUILDDIR)/client/pmove.o \
  $(BUILDDIR)/client/pmovetst.o \
  $(BUILDDIR)/client/r_aclip.o \
  $(BUILDDIR)/client/r_alias.o \
  $(BUILDDIR)/client/r_bsp.o \
  $(BUILDDIR)/client/r_draw.o \
  $(BUILDDIR)/client/r_edge.o \
  $(BUILDDIR)/client/r_efrag.o \
  $(BUILDDIR)/client/r_light.o \
  $(BUILDDIR)/client/r_main.o \
  $(BUILDDIR)/client/r_misc.o \
  $(BUILDDIR)/client/r_part.o \
  $(BUILDDIR)/client/r_sky.o \
  $(BUILDDIR)/client/r_sprite.o \
  $(BUILDDIR)/client/r_surf.o \
  $(BUILDDIR)/client/r_vars.o \
  $(BUILDDIR)/client/sbar.o \
  $(BUILDDIR)/client/screen.o \
  $(BUILDDIR)/client/skin.o \
  $(BUILDDIR)/client/snd_dma.o \
  $(BUILDDIR)/client/snd_mem.o \
  $(BUILDDIR)/client/snd_mix.o \
  $(BUILDDIR)/client/view.o \
  $(BUILDDIR)/client/wad.o \
  $(BUILDDIR)/client/zone.o \
  $(BUILDDIR)/client/cd_linux.o \
  $(BUILDDIR)/client/sys_linux.o \
  $(BUILDDIR)/client/snd_linux.o \

  QWCL_AS_OBJS = \
  $(BUILDDIR)/client/d_copy.o \
  $(BUILDDIR)/client/d_draw.o \
  $(BUILDDIR)/client/d_draw16.o \
  $(BUILDDIR)/client/d_parta.o \
  $(BUILDDIR)/client/d_polysa.o \
  $(BUILDDIR)/client/d_scana.o \
  $(BUILDDIR)/client/d_spr8.o \
  $(BUILDDIR)/client/d_varsa.o \
  $(BUILDDIR)/client/math.o \
  $(BUILDDIR)/client/r_aclipa.o \
  $(BUILDDIR)/client/r_aliasa.o \
  $(BUILDDIR)/client/r_drawa.o \
  $(BUILDDIR)/client/r_edgea.o \
  $(BUILDDIR)/client/r_varsa.o \
  $(BUILDDIR)/client/snd_mixa.o \
  $(BUILDDIR)/client/surf16.o \
  $(BUILDDIR)/client/surf8.o \
  $(BUILDDIR)/client/sys_dosa.o

QWCL_X11_OBJS = $(BUILDDIR)/client/vid_x.o

$(BUILDDIR)/qwcl.x11 : $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS)
  $(CC) $(CFLAGS) -o $@ $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS) \
    $(LDFLAGS) $(XLDFLAGS)

$(BUILDDIR)/client/cl_demo.o :        $(CLIENT_DIR)/cl_demo.c
  $(DO_CC)

$(BUILDDIR)/client/cl_ents.o :        $(CLIENT_DIR)/cl_ents.c
  $(DO_CC)

$(BUILDDIR)/client/cl_input.o :       $(CLIENT_DIR)/cl_input.c
  $(DO_CC)

$(BUILDDIR)/client/cl_main.o :        $(CLIENT_DIR)/cl_main.c
  $(DO_CC)

$(BUILDDIR)/client/cl_parse.o :       $(CLIENT_DIR)/cl_parse.c
  $(DO_CC)

$(BUILDDIR)/client/cl_pred.o :        $(CLIENT_DIR)/cl_pred.c
  $(DO_CC)

$(BUILDDIR)/client/cl_tent.o :        $(CLIENT_DIR)/cl_tent.c
  $(DO_CC)

$(BUILDDIR)/client/cl_cam.o :         $(CLIENT_DIR)/cl_cam.c
  $(DO_CC)

$(BUILDDIR)/client/cmd.o :            $(CLIENT_DIR)/cmd.c
  $(DO_CC)

$(BUILDDIR)/client/common.o :         $(CLIENT_DIR)/common.c
  $(DO_CC)

$(BUILDDIR)/client/console.o :        $(CLIENT_DIR)/console.c
  $(DO_CC)

$(BUILDDIR)/client/crc.o :            $(CLIENT_DIR)/crc.c
  $(DO_CC)

$(BUILDDIR)/client/cvar.o :           $(CLIENT_DIR)/cvar.c
  $(DO_CC)

$(BUILDDIR)/client/d_edge.o :         $(CLIENT_DIR)/d_edge.c
  $(DO_CC)

$(BUILDDIR)/client/d_fill.o :         $(CLIENT_DIR)/d_fill.c
  $(DO_CC)

$(BUILDDIR)/client/d_init.o :         $(CLIENT_DIR)/d_init.c
  $(DO_CC)

$(BUILDDIR)/client/d_modech.o :       $(CLIENT_DIR)/d_modech.c
  $(DO_CC)

$(BUILDDIR)/client/d_part.o :         $(CLIENT_DIR)/d_part.c
  $(DO_CC)

$(BUILDDIR)/client/d_polyse.o :       $(CLIENT_DIR)/d_polyse.c
  $(DO_CC)

$(BUILDDIR)/client/d_scan.o :         $(CLIENT_DIR)/d_scan.c
  $(DO_CC)

$(BUILDDIR)/client/d_sky.o :          $(CLIENT_DIR)/d_sky.c
  $(DO_CC)

$(BUILDDIR)/client/d_sprite.o :       $(CLIENT_DIR)/d_sprite.c
  $(DO_CC)

$(BUILDDIR)/client/d_surf.o :         $(CLIENT_DIR)/d_surf.c
  $(DO_CC)

$(BUILDDIR)/client/d_vars.o :         $(CLIENT_DIR)/d_vars.c
  $(DO_CC)

$(BUILDDIR)/client/d_zpoint.o :       $(CLIENT_DIR)/d_zpoint.c
  $(DO_CC)

$(BUILDDIR)/client/draw.o :           $(CLIENT_DIR)/draw.c
  $(DO_CC)

$(BUILDDIR)/client/keys.o :           $(CLIENT_DIR)/keys.c
  $(DO_CC)

$(BUILDDIR)/client/mathlib.o :        $(CLIENT_DIR)/mathlib.c
  $(DO_CC)

$(BUILDDIR)/client/md4.o :            $(CLIENT_DIR)/md4.c
  $(DO_CC)

$(BUILDDIR)/client/menu.o :           $(CLIENT_DIR)/menu.c
  $(DO_CC)

$(BUILDDIR)/client/model.o :          $(CLIENT_DIR)/model.c
  $(DO_CC)

$(BUILDDIR)/client/net_chan.o :       $(CLIENT_DIR)/net_chan.c
  $(DO_CC)

$(BUILDDIR)/client/net_udp.o :        $(CLIENT_DIR)/net_udp.c
  $(DO_CC)

$(BUILDDIR)/client/nonintel.o :       $(CLIENT_DIR)/nonintel.c
  $(DO_CC)

$(BUILDDIR)/client/pmove.o :          $(CLIENT_DIR)/pmove.c
  $(DO_CC)

$(BUILDDIR)/client/pmovetst.o :       $(CLIENT_DIR)/pmovetst.c
  $(DO_CC)

$(BUILDDIR)/client/r_aclip.o :        $(CLIENT_DIR)/r_aclip.c
  $(DO_CC)

$(BUILDDIR)/client/r_alias.o :        $(CLIENT_DIR)/r_alias.c
  $(DO_CC)

$(BUILDDIR)/client/r_bsp.o :          $(CLIENT_DIR)/r_bsp.c
  $(DO_CC)

$(BUILDDIR)/client/r_draw.o :         $(CLIENT_DIR)/r_draw.c
  $(DO_CC)

$(BUILDDIR)/client/r_edge.o :         $(CLIENT_DIR)/r_edge.c
  $(DO_CC)

$(BUILDDIR)/client/r_efrag.o :        $(CLIENT_DIR)/r_efrag.c
  $(DO_CC)

$(BUILDDIR)/client/r_light.o :        $(CLIENT_DIR)/r_light.c
  $(DO_CC)

$(BUILDDIR)/client/r_main.o :         $(CLIENT_DIR)/r_main.c
  $(DO_CC)

$(BUILDDIR)/client/r_misc.o :         $(CLIENT_DIR)/r_misc.c
  $(DO_CC)

$(BUILDDIR)/client/r_part.o :         $(CLIENT_DIR)/r_part.c
  $(DO_CC)

$(BUILDDIR)/client/r_sky.o :          $(CLIENT_DIR)/r_sky.c
  $(DO_CC)

$(BUILDDIR)/client/r_sprite.o :       $(CLIENT_DIR)/r_sprite.c
  $(DO_CC)

$(BUILDDIR)/client/r_surf.o :         $(CLIENT_DIR)/r_surf.c
  $(DO_CC)

$(BUILDDIR)/client/r_vars.o :         $(CLIENT_DIR)/r_vars.c
  $(DO_CC)

$(BUILDDIR)/client/sbar.o :           $(CLIENT_DIR)/sbar.c
  $(DO_CC)

$(BUILDDIR)/client/screen.o :         $(CLIENT_DIR)/screen.c
  $(DO_CC)

$(BUILDDIR)/client/skin.o :           $(CLIENT_DIR)/skin.c
  $(DO_CC)

$(BUILDDIR)/client/snd_dma.o :        $(CLIENT_DIR)/snd_dma.c
  $(DO_CC)

$(BUILDDIR)/client/snd_mem.o :        $(CLIENT_DIR)/snd_mem.c
  $(DO_CC)

$(BUILDDIR)/client/snd_mix.o :        $(CLIENT_DIR)/snd_mix.c
  $(DO_CC)

$(BUILDDIR)/client/view.o :           $(CLIENT_DIR)/view.c
  $(DO_CC)

$(BUILDDIR)/client/wad.o :            $(CLIENT_DIR)/wad.c
  $(DO_CC)

$(BUILDDIR)/client/zone.o :           $(CLIENT_DIR)/zone.c
  $(DO_CC)

$(BUILDDIR)/client/cd_linux.o :       $(CLIENT_DIR)/cd_linux.c
  $(DO_CC)

$(BUILDDIR)/client/sys_linux.o :      $(CLIENT_DIR)/sys_linux.c
  $(DO_CC)

$(BUILDDIR)/client/snd_linux.o :      $(CLIENT_DIR)/snd_linux.c
  $(DO_CC)

$(BUILDDIR)/client/d_copy.o :         $(CLIENT_DIR)/d_copy.s
  $(DO_AS)

$(BUILDDIR)/client/d_draw.o :         $(CLIENT_DIR)/d_draw.s
  $(DO_AS)

$(BUILDDIR)/client/d_draw16.o :       $(CLIENT_DIR)/d_draw16.s
  $(DO_AS)

$(BUILDDIR)/client/d_parta.o :        $(CLIENT_DIR)/d_parta.s
  $(DO_AS)

$(BUILDDIR)/client/d_polysa.o :       $(CLIENT_DIR)/d_polysa.s
  $(DO_AS)

$(BUILDDIR)/client/d_scana.o :        $(CLIENT_DIR)/d_scana.s
  $(DO_AS)

$(BUILDDIR)/client/d_spr8.o :         $(CLIENT_DIR)/d_spr8.s
  $(DO_AS)

$(BUILDDIR)/client/d_varsa.o :        $(CLIENT_DIR)/d_varsa.s
  $(DO_AS)

$(BUILDDIR)/client/math.o :           $(CLIENT_DIR)/math.s
  $(DO_AS)

$(BUILDDIR)/client/r_aclipa.o :       $(CLIENT_DIR)/r_aclipa.s
  $(DO_AS)

$(BUILDDIR)/client/r_aliasa.o :       $(CLIENT_DIR)/r_aliasa.s
  $(DO_AS)

$(BUILDDIR)/client/r_drawa.o :        $(CLIENT_DIR)/r_drawa.s
  $(DO_AS)

$(BUILDDIR)/client/r_edgea.o :        $(CLIENT_DIR)/r_edgea.s
  $(DO_AS)

$(BUILDDIR)/client/r_varsa.o :        $(CLIENT_DIR)/r_varsa.s
  $(DO_AS)

$(BUILDDIR)/client/snd_mixa.o :       $(CLIENT_DIR)/snd_mixa.s
  $(DO_AS)

$(BUILDDIR)/client/surf16.o :         $(CLIENT_DIR)/surf16.s
  $(DO_AS)

$(BUILDDIR)/client/surf8.o :          $(CLIENT_DIR)/surf8.s
  $(DO_AS)

$(BUILDDIR)/client/sys_dosa.o :       $(CLIENT_DIR)/sys_dosa.s
  $(DO_AS)

$(BUILDDIR)/client/vid_x.o : $(CLIENT_DIR)/vid_x.c
  $(DO_CC)

#############################################################################
# GL CLIENT
#############################################################################

GLQWCL_OBJS = \
  $(BUILDDIR)/glclient/cl_demo.o \
  $(BUILDDIR)/glclient/cl_ents.o \
  $(BUILDDIR)/glclient/cl_input.o \
  $(BUILDDIR)/glclient/cl_main.o \
  $(BUILDDIR)/glclient/cl_parse.o \
  $(BUILDDIR)/glclient/cl_pred.o \
  $(BUILDDIR)/glclient/cl_tent.o \
  $(BUILDDIR)/glclient/cl_cam.o \
  $(BUILDDIR)/glclient/cmd.o \
  $(BUILDDIR)/glclient/common.o \
  $(BUILDDIR)/glclient/console.o \
  $(BUILDDIR)/glclient/crc.o \
  $(BUILDDIR)/glclient/cvar.o \
  $(BUILDDIR)/glclient/keys.o \
  $(BUILDDIR)/glclient/mathlib.o \
  $(BUILDDIR)/glclient/md4.o \
  $(BUILDDIR)/glclient/menu.o \
  $(BUILDDIR)/glclient/net_chan.o \
  $(BUILDDIR)/glclient/net_udp.o \
  $(BUILDDIR)/glclient/nonintel.o \
  $(BUILDDIR)/glclient/pmove.o \
  $(BUILDDIR)/glclient/pmovetst.o \
  $(BUILDDIR)/glclient/r_part.o \
  $(BUILDDIR)/glclient/sbar.o \
  $(BUILDDIR)/glclient/skin.o \
  $(BUILDDIR)/glclient/snd_dma.o \
  $(BUILDDIR)/glclient/snd_mem.o \
  $(BUILDDIR)/glclient/snd_mix.o \
  $(BUILDDIR)/glclient/view.o \
  $(BUILDDIR)/glclient/wad.o \
  $(BUILDDIR)/glclient/zone.o \
  $(BUILDDIR)/glclient/cd_linux.o \
  $(BUILDDIR)/glclient/sys_linux.o \
  $(BUILDDIR)/glclient/snd_linux.o \
  \
  $(BUILDDIR)/glclient/gl_draw.o \
  $(BUILDDIR)/glclient/gl_mesh.o \
  $(BUILDDIR)/glclient/gl_model.o \
  $(BUILDDIR)/glclient/gl_ngraph.o \
  $(BUILDDIR)/glclient/gl_refrag.o \
  $(BUILDDIR)/glclient/gl_rlight.o \
  $(BUILDDIR)/glclient/gl_rmain.o \
  $(BUILDDIR)/glclient/gl_rmisc.o \
  $(BUILDDIR)/glclient/gl_rsurf.o \
  $(BUILDDIR)/glclient/gl_screen.o \
  $(BUILDDIR)/glclient/gl_warp.o \
  \
  $(BUILDDIR)/glclient/math.o \
  $(BUILDDIR)/glclient/snd_mixa.o \
  $(BUILDDIR)/glclient/sys_dosa.o

GLQWCL_X11_OBJS = $(BUILDDIR)/glclient/gl_vidlinuxglx.o

$(BUILDDIR)/glqwcl.glx : $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS)
  $(CC) $(CFLAGS) -o $@ $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS) $(LDFLAGS) $(GL_X11_LDFLAGS)

$(BUILDDIR)/glclient/cl_demo.o :       $(CLIENT_DIR)/cl_demo.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_ents.o :       $(CLIENT_DIR)/cl_ents.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_input.o :      $(CLIENT_DIR)/cl_input.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_main.o :       $(CLIENT_DIR)/cl_main.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_parse.o :      $(CLIENT_DIR)/cl_parse.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_pred.o :       $(CLIENT_DIR)/cl_pred.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_tent.o :       $(CLIENT_DIR)/cl_tent.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cl_cam.o :        $(CLIENT_DIR)/cl_cam.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cmd.o :           $(CLIENT_DIR)/cmd.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/common.o :        $(CLIENT_DIR)/common.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/console.o :       $(CLIENT_DIR)/console.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/crc.o :           $(CLIENT_DIR)/crc.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cvar.o :          $(CLIENT_DIR)/cvar.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/keys.o :          $(CLIENT_DIR)/keys.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/mathlib.o :       $(CLIENT_DIR)/mathlib.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/md4.o :           $(CLIENT_DIR)/md4.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/menu.o :          $(CLIENT_DIR)/menu.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/net_chan.o :      $(CLIENT_DIR)/net_chan.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/net_udp.o :       $(CLIENT_DIR)/net_udp.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/nonintel.o :      $(CLIENT_DIR)/nonintel.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/pmove.o :         $(CLIENT_DIR)/pmove.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/pmovetst.o :      $(CLIENT_DIR)/pmovetst.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/r_part.o :        $(CLIENT_DIR)/r_part.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/sbar.o :          $(CLIENT_DIR)/sbar.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/screen.o :        $(CLIENT_DIR)/screen.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/skin.o :          $(CLIENT_DIR)/skin.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/snd_dma.o :       $(CLIENT_DIR)/snd_dma.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/snd_mem.o :       $(CLIENT_DIR)/snd_mem.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/snd_mix.o :       $(CLIENT_DIR)/snd_mix.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/view.o :          $(CLIENT_DIR)/view.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/wad.o :           $(CLIENT_DIR)/wad.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/zone.o :          $(CLIENT_DIR)/zone.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/cd_linux.o :      $(CLIENT_DIR)/cd_linux.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/sys_linux.o :     $(CLIENT_DIR)/sys_linux.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/snd_linux.o :     $(CLIENT_DIR)/snd_linux.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_draw.o :       $(CLIENT_DIR)/gl_draw.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_mesh.o :       $(CLIENT_DIR)/gl_mesh.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_model.o :      $(CLIENT_DIR)/gl_model.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_ngraph.o :     $(CLIENT_DIR)/gl_ngraph.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_refrag.o :     $(CLIENT_DIR)/gl_refrag.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rlight.o :     $(CLIENT_DIR)/gl_rlight.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rmain.o :      $(CLIENT_DIR)/gl_rmain.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rmisc.o :      $(CLIENT_DIR)/gl_rmisc.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rsurf.o :      $(CLIENT_DIR)/gl_rsurf.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_screen.o :     $(CLIENT_DIR)/gl_screen.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_vidlinux.o :   $(CLIENT_DIR)/gl_vidlinux.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_vidlinuxglx.o :   $(CLIENT_DIR)/gl_vidlinuxglx.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/gl_warp.o :       $(CLIENT_DIR)/gl_warp.c
  $(DO_GL_CC)

$(BUILDDIR)/glclient/math.o :          $(CLIENT_DIR)/math.s
  $(DO_GL_AS)

$(BUILDDIR)/glclient/snd_mixa.o :      $(CLIENT_DIR)/snd_mixa.s
  $(DO_GL_AS)

$(BUILDDIR)/glclient/sys_dosa.o :      $(CLIENT_DIR)/sys_dosa.s
  $(DO_GL_AS)

#############################################################################
# MISC
#############################################################################

clean:
  rm -fr bin/client
  rm -fr bin/glclient
  rm -fr bin/server

With that saved into a file, it is time to build.  Unzip the source code into a directory, and then from the QW directory run the new Makefile.  If your GCC is new enough it’ll complain about the -m486 directive.  Just remove that from the Makefile.  On my bare build system it compiles the server in a few seconds, but then fails to build the GLQuake client because I don’t have any OpenGL installed.  But again this is fine, I just want the server.

gcc -Wall -Dstricmp=strcasecmp -I./client -I./server -ffast-math -fexpensive-optimizations -o bin/qwsv bin/server/pr_cmds.o bin/server/pr_edict.o bin/server/pr_exec.o bin/server/sv_init.o bin/server/sv_main.o bin/server/sv_nchan.o bin/server/sv_ents.o bin/server/sv_send.o bin/server/sv_move.o bin/server/sv_phys.o bin/server/sv_user.o bin/server/sv_ccmds.o bin/server/world.o bin/server/sys_unix.o bin/server/model.o bin/server/cmd.o bin/server/common.o bin/server/crc.o bin/server/cvar.o bin/server/mathlib.o bin/server/md4.o bin/server/zone.o bin/server/pmove.o bin/server/pmovetst.o bin/server/net_chan.o bin/server/net_udp.o -lm
gcc -Wall -Dstricmp=strcasecmp -I./client -I./server -ffast-math -fexpensive-optimizations -DGLQUAKE -DGL_EXT_SHARED -o bin/glclient/cl_demo.o -c client/cl_demo.c
In file included from client/quakedef.h:76:0,
from client/cl_demo.c:21:
client/glquake.h:22:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:23:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:24:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:30:19: fatal error: GL/gl.h: No such file or directory
compilation terminated.
make[1]: *** [bin/glclient/cl_demo.o] Error 1
make[1]: Leaving directory `/root/QW’
make: *** [build_release] Error 2
root@debx867:~/QW#

And to verify the server:

root@debx867:~/QW# file bin/qwsv
bin/qwsv: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0xa074d1a1c7b941da5e3a774eebc70f969c3347c7, not stripped

Ok, all good!

Now for running the server, I place my qwsv binary into somewhere more ‘server’ like say /usr/local/quake

root@debx867:~/QW# mkdir /usr/local/quake
root@debx867:~/QW# cp bin/qwsv /usr/local/quake/

The next part is to copy in the pak0.pak & pak1.pak from your registered copy of Quake 1 into /usr/local/quake/id1.  You can always buy it on steam, although it is so old I’m sure you’ve already acquired a copy or two in the last few years.  Note that pak0.pak is the shareware portion of the datafile!  To be a server you require pak1.pak from the registered copy of Quake.  Although the source to the maps has been released, I’m pretty sure you will be missing all kinds of otherthings from pak1.pak.

Ok now with the pak’s in place, you need the QuakeWorld scripts in place.  Copy the ‘progs’ directory into the qw directory

root@debx867:/usr/local/quake# mkdir qw
root@debx867:/usr/local/quake# cp $HOME/QW/progs/* qw

Now with all of this in place it is enough to run the server!

root@debx867:/usr/local/quake# ./qwsv
Added packfile ./id1/pak0.pak (339 files)
Added packfile ./id1/pak1.pak (85 files)
PackFile: ./id1/pak1.pak : gfx/pop.lmp
Playing registered version.
IP address 127.0.1.1:27500
UDP Initialized
Exe: 20:05:14 Nov 18 2013
16.0 megabyte heap

Server Version 2.40 (Build 5451)

======== QuakeWorld Initialized ========
FindFile: can’t find server.cfg
couldn’t exec server.cfg
PackFile: ./id1/pak0.pak : maps/start.bsp
FindFile: ./qw/qwprogs.dat
PackFile: ./id1/pak0.pak : maps/start.bsp
Building PHS…
Average leafs visible / hearable / total: 111 / 239 / 1128
PackFile: ./id1/pak0.pak : progs/player.mdl
PackFile: ./id1/pak0.pak : progs/eyes.mdl
Updated needpass.

However you probably will want a server.cfg.  And incase the page goes offline here is a pretty basic config:

sv_gamedir qw
deathmatch 1
hostname  ”Your Quake DM Server”
serverinfo admin  ”your@email.com”
serverinfo url “http://www.yourwebsite.com”
rcon_password change_me
timelimit 10
fraglimit 20
pausable 0
samelevel 2
maxclients 16
map dm1
floodprot 4 8 30
floodprotmsg “You have activated the flood protection and will be silenced for 30 seconds”
maxspectators 2
allow_download 1
allow_download_skins 1
allow_download_models 1
allow_download_sounds 1
allow_download_maps 1

Naturally you may want to change things.  Save the config file into the id1 directory.

Now when it comes to running the server, the console will want to be interactive to the user.  If you nohup the process it’ll go bezerk. The best way to do this is with screen.  In my /etc/rc.local I add the following line:

screen -dmS quake /usr/local/quake/quake.sh

And of course the shell script is:

#!/bin/bash
cd /usr/local/quake
while true
do true
./qwsv
done

Very simple stuff.  If the server crashes or stops for any reason it’ll restart.

By default QuakeWorld will listen on UDP port 27500.  The next thing you’ll need is a client to test.  I’m kind of partial to the MS-DOS (qemu) and OS/2 clients.

QuakeWorld in action!

QuakeWorld in action!

And there we go, now you too can host your own QuakeWorld server.  And for those who can’t compiler, you can try my x86 binary here.

You may want to add your server to gametracker.com.  Or just join mine.