diff --git a/.gitignore b/.gitignore
index a4eab17..63640b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-/DJDM19
-/DMDM19
-/OCDM19
-/WCDM19
+.vscode
+build_dos
+build_linux
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9e4f65f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,105 @@
+CC := gcc
+CXX := g++
+DBGFLAGS := -g -DRANGECHECK -fsanitize=address -fsanitize=undefined
+#EXTRAFLAGS = $(DBGFLAGS)
+EXTRAFLAGS = -O2 -fomit-frame-pointer
+CFLAGS := -m32 -Wno-attributes -Wno-unused-result -DAPPVER_EXEDEF=DM19F2 -fno-pic -no-pie $(EXTRAFLAGS)
+COBJFLAGS := $(CFLAGS) -c
+AS := nasm
+
+SRC_DIR := src
+DOS_BUILD_DIR := build_dos
+LINUX_BUILD_DIR := build_linux
+
+define get-objects-from-dir
+$(patsubst $(1)/%.c,$(1)/%.o,$(wildcard $(1)/*.c)) \
+$(patsubst $(1)/%.asm,$(1)/%.o,$(wildcard $(1)/*.asm))
+endef
+
+define src-to-build
+$(patsubst %,$(1)/%,$(2))
+endef
+
+define _depend
+#!/bin/sh
+CC=$1
+DIR=$2
+shift 2
+case "$DIR" in
+"" | ".")
+$CC -MM -MG -c "$@" | sed -e 's@^\(.*\).o:@\\1.d \\1.o:@g'
+;;
+*)
+$CC -MM -MG -c "$@" | sed -e "s@^\(.*\).o:@$DIR\/\\1.d $DIR\/\\1.o:@g"
+;;
+esac
+endef
+export depend = $(value _depend)
+
+# Z_ZONE_OBJ = $(SRC_DIR)/z_zone/z_zone_asan.o
+Z_ZONE_OBJ = $(SRC_DIR)/z_zone/z_zone.o
+
+# Find all .o files
+DOOM_OBJS := $(call get-objects-from-dir,$(SRC_DIR)) $(Z_ZONE_OBJ)
+DOS_OBJS := $(call get-objects-from-dir,$(SRC_DIR)/dos)
+LINUX_OBJS := $(call get-objects-from-dir,$(SRC_DIR)/linux)
+
+ALL_DOS_OBJS := $(call src-to-build, $(DOS_BUILD_DIR), $(DOOM_OBJS) $(DOS_OBJS))
+ALL_LINUX_OBJS := $(call src-to-build, $(LINUX_BUILD_DIR), $(DOOM_OBJS) $(LINUX_OBJS))
+
+.PRECIOUS: $(DOS_BUILD_DIR)/%.d $(LINUX_BUILD_DIR)/%.d %/depend.sh
+
+%/depend.sh: Makefile | %/depend.sh.dir
+ @echo "$$depend" > $@
+ @chmod +x $@
+
+define make-rules
+$(1)/%.d: %.c $(1)/depend.sh | $(1)/%.dir
+ @$(1)/depend.sh $(CC) $$(@D) $(CFLAGS) $$< > $$@
+
+$(1)/%.d: %.asm | $(1)/%.dir
+ @touch $$@
+
+$(1)/%.o: %.c $(1)/%.d
+ @echo "Compiling $$<"
+ @$(CC) $(COBJFLAGS) -o $$@ $$<
+
+$(1)/%.o: %.cpp | $(1)/%.dir
+ @$(CXX) $(COBJFLAGS) -o $$@ $$<
+
+$(1)/%.s: %.c $(1)/%.d
+ @$(CC) $(COBJFLAGS) -S -o $$@ $$<
+
+$(1)/%.o: %.asm $(1)/%.d | $(1)/%.dir
+ @$(AS) $$< $(2) -o $$@
+endef
+
+$(eval $(call make-rules, $(DOS_BUILD_DIR), -f coff))
+$(eval $(call make-rules, $(LINUX_BUILD_DIR), -f elf))
+
+%.dir:
+ @mkdir -p $(dir $@)
+
+# Doom targets
+$(DOS_BUILD_DIR)/doom.exe: $(ALL_DOS_OBJS)
+ $(CXX) -o $@ $^ $(CFLAGS)
+
+$(LINUX_BUILD_DIR)/doom: $(ALL_LINUX_OBJS)
+ $(CXX) -o $@ $^ $(CFLAGS) -lX11
+
+
+.PHONY: debug
+debug: $(TARGET_DEBUG)
+
+.PHONY: clean
+clean:
+ @rm -rf $(DOS_BUILD_DIR)
+ @rm -rf $(LINUX_BUILD_DIR)
+
+# Include dependency files
+# This will include the dependency files generated by the depend.sh script
+# and will ensure that any change to headers will force correct rebuilding.
+# The wildcard function will expand to all .d files in the build directories
+# are present, which prevents make from trying to generate .d files that
+# don't exist.
+-include $(wildcard $(ALL_DOS_OBJS:.o=.d) $(ALL_LINUX_OBJS:.o=.d))
diff --git a/compdj.bat b/compdj.bat
deleted file mode 100644
index efa1fdf..0000000
--- a/compdj.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-if "%DJDIR%" == "" goto error
-
-mkdir DJDM19
-
-nasm a_mv_mix.asm -f coff
-nasm planar.asm -f coff
-
-set CFLAGS=-Ofast -march=i386 -flto -fwhole-program -fomit-frame-pointer -funroll-loops -fgcse-sm -fgcse-las -fipa-pta -mpreferred-stack-boundary=2 -Wno-attributes -Wpedantic
-@rem set CFLAGS=%CFLAGS% -Wall -Wextra
-
-set GLOBOBJS=dmx.c a_al_mid.c a_blast.c a_dma.c a_ll_man.c a_midi.c a_mpu401.c a_multiv.c a_music.c a_musmid.c a_mv_mix.o a_pcfx.c a_taskmn.c a_tsmapi.c i_main.c i_ibm.c i_sound.c planar.o tables.c f_finale.c d_main.c d_net.c g_game.c m_menu.c m_misc.c am_map.c p_ceilng.c p_doors.c p_enemy.c p_floor.c p_inter.c p_lights.c p_map.c p_maputl.c p_plats.c p_pspr.c p_setup.c p_sight.c p_spec.c p_switch.c p_mobj.c p_telept.c p_tick.c p_user.c r_bsp.c r_data.c r_draw.c r_main.c r_plane.c r_segs.c r_things.c w_wad.c wi_stuff.c v_video.c st_lib.c st_stuff.c hu_stuff.c hu_lib.c s_sound.c z_zone.c info.c sounds.c dutils.c
-gcc -DAPPVER_EXEDEF=DM19 %GLOBOBJS% %CFLAGS% -o DJDM19/djdoom.exe
-strip -s DJDM19/djdoom.exe
-stubedit DJDM19/djdoom.exe dpmi=CWSDPR0.EXE
-
-del a_mv_mix.o
-del planar.o
-
-goto end
-
-:error
-@echo Set the environment variables before running this script!
-
-:end
diff --git a/compdm.bat b/compdm.bat
deleted file mode 100644
index 46302ab..0000000
--- a/compdm.bat
+++ /dev/null
@@ -1,10 +0,0 @@
-mkdir DMDM19
-
-nasm a_mv_mix.asm -f obj
-nasm planar.asm -f obj
-
-set GLOBOBJS=dmx.c a_al_mid.c a_blast.c a_dma.c a_ll_man.c a_midi.c a_mpu401.c a_multiv.c a_music.c a_musmid.c a_mv_mix.obj a_pcfx.c a_taskmn.c a_tsmapi.c i_main.c i_ibm.c i_sound.c planar.obj tables.c f_finale.c d_main.c d_net.c g_game.c m_menu.c m_misc.c am_map.c p_ceilng.c p_doors.c p_enemy.c p_floor.c p_inter.c p_lights.c p_map.c p_maputl.c p_plats.c p_pspr.c p_setup.c p_sight.c p_spec.c p_switch.c p_mobj.c p_telept.c p_tick.c p_user.c r_bsp.c r_data.c r_draw.c r_main.c r_plane.c r_segs.c r_things.c w_wad.c wi_stuff.c v_video.c st_lib.c st_stuff.c hu_stuff.c hu_lib.c s_sound.c z_zone.c info.c sounds.c dutils.c
-dmc %GLOBOBJS% -mx X32.LIB -3 -o+all -DAPPVER_EXEDEF=DM19 -oDMDM19\dmdoom.exe
-
-del *.obj
-del dmdoom.map
diff --git a/compoc.bat b/compoc.bat
deleted file mode 100644
index 68d4433..0000000
--- a/compoc.bat
+++ /dev/null
@@ -1,18 +0,0 @@
-if "%LADSOFT%" == "" goto error
-
-mkdir OCDM19
-
-nasm a_mv_mix.asm -f obj
-nasm planar.asm -f obj
-
-set GLOBOBJS=dmx.c a_al_mid.c a_blast.c a_dma.c a_ll_man.c a_midi.c a_mpu401.c a_multiv.c a_music.c a_musmid.c a_mv_mix.obj a_pcfx.c a_taskmn.c a_tsmapi.c i_main.c i_ibm.c i_sound.c planar.obj tables.c f_finale.c d_main.c d_net.c g_game.c m_menu.c m_misc.c am_map.c p_ceilng.c p_doors.c p_enemy.c p_floor.c p_inter.c p_lights.c p_map.c p_maputl.c p_plats.c p_pspr.c p_setup.c p_sight.c p_spec.c p_switch.c p_mobj.c p_telept.c p_tick.c p_user.c r_bsp.c r_data.c r_draw.c r_main.c r_plane.c r_segs.c r_things.c w_wad.c wi_stuff.c v_video.c st_lib.c st_stuff.c hu_stuff.c hu_lib.c s_sound.c z_zone.c info.c sounds.c dutils.c
-cc386 %GLOBOBJS% /Wa /DAPPVER_EXEDEF=DM19 /oOCDM19\ocdoom.exe
-
-del *.obj
-
-goto end
-
-:error
-@echo Set the environment variables before running this script!
-
-:end
diff --git a/compwc.bat b/compwc.bat
deleted file mode 100644
index e17c679..0000000
--- a/compwc.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-if "%WATCOM%" == "" goto error
-
-mkdir WCDM19
-wmake -f makefile.wc WCDM19\wcdoom.exe
-del *.err
-goto end
-
-:error
-@echo Set the environment variables before running this script!
-
-:end
diff --git a/planar.asm b/planar.asm
deleted file mode 100644
index 43846a3..0000000
--- a/planar.asm
+++ /dev/null
@@ -1,562 +0,0 @@
-;
-; Copyright (C) 1993-1996 Id Software, Inc.
-; Copyright (C) 2023 Frenkel Smeijers
-;
-; 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, see .
-;
-
-cpu 386
-
-PLANEWIDTH equ 80
-
-SC_INDEX equ 0x3c4
-
-extern _dc_colormap
-extern _dc_x
-extern _dc_yl
-extern _dc_yh
-extern _dc_iscale
-extern _dc_texturemid
-extern _dc_source
-
-
-extern _ds_y
-extern _ds_x1
-extern _ds_x2
-extern _ds_colormap
-extern _ds_xfrac
-extern _ds_yfrac
-extern _ds_xstep
-extern _ds_ystep
-extern _ds_source
-
-extern _destview
-extern _centery
-
-
-;============================================================================
-;
-; unwound vertical scaling code
-;
-; eax light table pointer, 0 lowbyte overwritten
-; ebx all 0, low byte overwritten
-; ecx fractional step value
-; edx fractional scale value
-; esi start of source pixels
-; edi bottom pixel in screenbuffer to blit into
-;
-; ebx should be set to 0 0 0 dh to feed the pipeline
-;
-; The graphics wrap vertically at 128 pixels
-;============================================================================
-
-%ifidn __OUTPUT_FORMAT__, coff
-section .bss public class=DATA USE32
-%elifidn __OUTPUT_FORMAT__, obj
-section _BSS public class=DATA USE32
-%endif
-
-loopcount resd 1
-pixelcount resd 1
-
-;=================================
-
-
-%ifidn __OUTPUT_FORMAT__, coff
-section .text public class=CODE USE32
-%elifidn __OUTPUT_FORMAT__, obj
-section _TEXT public class=CODE USE32
-%endif
-
-;================
-;
-; R_DrawColumn
-;
-;================
-
-global _R_DrawColumnLow
-_R_DrawColumnLow:
- pushad
- mov ebp,[_dc_yl]
- cmp ebp,[_dc_yh]
- jg done
- lea edi,[ebp+ebp*4]
- shl edi,4
- mov ebx,[_dc_x]
- mov ecx,ebx
- shr ebx,1
- add edi,ebx
- add edi,[_destview]
- and ecx,1
- shl ecx,1
- mov eax,3
- shl eax,cl
- mov edx,SC_INDEX+1
- out dx,al
- jmp cdraw
-
-global _R_DrawColumn
-_R_DrawColumn:
- pushad
- mov ebp,[_dc_yl]
- cmp ebp,[_dc_yh]
- jg done
- lea edi,[ebp+ebp*4]
- shl edi,4
- mov ebx,[_dc_x]
- mov ecx,ebx
- shr ebx,2
- add edi,ebx
- add edi,[_destview]
- and ecx,3
- mov eax,1
- shl eax,cl
- mov edx,SC_INDEX+1
- out dx,al
-
-cdraw:
- mov eax,[_dc_yh]
- inc eax
- sub eax,ebp ; pixel count
- mov [pixelcount],eax ; save for final pixel
- js done ; nothing to scale
- shr eax,1 ; double pixel count
- mov [loopcount],eax
- mov ecx,[_dc_iscale]
- mov eax,[_centery]
- sub eax,ebp
- imul ecx
- mov ebp,[_dc_texturemid]
- sub ebp,eax
- shl ebp,9 ; 7 significant bits, 25 frac
- mov esi,[_dc_source]
- mov ebx,[_dc_iscale]
- shl ebx,9
- mov eax,patch1+2 ; convice nasm to modify code...
- mov [eax],ebx
- mov eax,patch2+2 ; convice nasm to modify code...
- mov [eax],ebx
-
-; eax aligned colormap
-; ebx aligned colormap
-; ecx,edx scratch
-; esi virtual source
-; edi moving destination pointer
-; ebp frac
-
- mov ecx,ebp ; begin calculating first pixel
- add ebp,ebx ; advance frac pointer
- shr ecx,25 ; finish calculation for first pixel
- mov edx,ebp ; begin calculating second pixel
- add ebp,ebx ; advance frac pointer
- shr edx,25 ; finish calculation for second pixel
- mov eax,[_dc_colormap]
- mov ebx,eax
- mov al,[esi+ecx] ; get first pixel
- mov bl,[esi+edx] ; get second pixel
- mov al,[eax] ; color translate first pixel
- mov bl,[ebx] ; color translate second pixel
-
- test [pixelcount],dword 0fffffffeh
- jnz doubleloop ; at least two pixels to map
- jmp checklast
-
-doubleloop:
- mov ecx,ebp ; begin calculating third pixel
-patch1:
- add ebp,12345678h ; advance frac pointer
- mov [edi],al ; write first pixel
- shr ecx,25 ; finish calculation for third pixel
- mov edx,ebp ; begin calculating fourth pixel
-patch2:
- add ebp,12345678h ; advance frac pointer
- mov [edi+PLANEWIDTH],bl ; write second pixel
- shr edx,25 ; finish calculation for fourth pixel
- mov al,[esi+ecx] ; get third pixel
- add edi,PLANEWIDTH*2 ; advance to third pixel destination
- mov bl,[esi+edx] ; get fourth pixel
- dec dword [loopcount] ; done with loop?
- mov al,[eax] ; color translate third pixel
- mov bl,[ebx] ; color translate fourth pixel
- jnz doubleloop
-checklast:
- test [pixelcount],dword 1
- jz done
- mov [edi],al
-
-done:
- popad
- ret
-
-
-;============================================================================
-;
-; unwound horizontal texture mapping code
-;
-; eax lighttable
-; ebx scratch register
-; ecx position 6.10 bits x, 6.10 bits y
-; edx step 6.10 bits x, 6.10 bits y
-; esi start of block
-; edi dest
-; ebp fff to mask bx
-;
-; ebp should by preset from ebx / ecx before calling
-;============================================================================
-
-%ifidn __OUTPUT_FORMAT__, coff
-section .bss
-%elifidn __OUTPUT_FORMAT__, obj
-section _BSS
-%endif
-
-dest resd 1
-endplane resd 1
-curplane resd 1
-frac resd 1
-fracstep resd 1
-fracpstep resd 1
-curx resd 1
-curpx resd 1
-endpx resd 1
-
-
-%ifidn __OUTPUT_FORMAT__, coff
-section .text
-%elifidn __OUTPUT_FORMAT__, obj
-section _TEXT
-%endif
-
-;================
-;
-; R_DrawSpan
-;
-; Horizontal texture mapping
-;
-;================
-
-global _R_DrawSpan
-_R_DrawSpan:
- pushad
-
- mov eax,[_ds_x1]
- mov [curx],eax
- mov ebx,eax
- and ebx,3
- mov [endplane],ebx
- mov [curplane],ebx
- shr eax,2
- mov ebp,[_ds_y]
- lea edi,[ebp+ebp*4]
- shl edi,4
- add edi,eax
- add edi,[_destview]
- mov [dest],edi
-
- mov ebx,[_ds_xfrac]
- shl ebx,10
- and ebx,0ffff0000h
- mov eax,[_ds_yfrac]
- shr eax,6
- and eax,0ffffh
- or ebx,eax
-
- mov [frac],ebx
-
- mov ebx,[_ds_xstep]
- shl ebx,10
- and ebx,0ffff0000h
- mov eax,[_ds_ystep]
- shr eax,6
- and eax,0ffffh
- or ebx,eax
-
- mov [fracstep],ebx
-
- shl ebx,2
- mov [fracpstep],ebx
- mov eax,hpatch1+2
- mov [eax],ebx
- mov eax,hpatch2+2
- mov [eax],ebx
- mov ecx,[curplane]
-hplane:
- mov eax,1
- shl eax,cl
- mov edx,SC_INDEX+1
- out dx,al
- mov eax,[_ds_x2]
- cmp eax,[curx]
- jb hdone
- sub eax,[curplane]
- js hdoneplane
- shr eax,2
- mov [endpx],eax
- dec eax
- js hfillone
- shr eax,1
- mov ebx,[curx]
- shr ebx,2
- cmp ebx,[endpx]
- jz hfillone
- mov [curpx],ebx
- inc ebx
- shr ebx,1
- inc eax
- sub eax,ebx
- js hdoneplane
- mov [loopcount],eax
- mov eax,[_ds_colormap]
- mov ebx,eax
- mov esi,[_ds_source]
- mov edi,[dest]
- mov ebp,[frac]
- test [curpx],dword 1
- jz hfill
- shld ecx,ebp,22
- shld ecx,ebp,6
- add ebp,[fracpstep]
- and ecx,0fffh
- mov al,[esi+ecx]
- mov dl,[eax]
- mov [edi],dl
- inc edi
- jz hdoneplane
-hfill:
- shld ecx,ebp,22
- shld ecx,ebp,6
- add ebp,[fracpstep]
- and ecx,0fffh
- shld edx,ebp,22
- shld edx,ebp,6
- add ebp,[fracpstep]
- and edx,0fffh
- mov al,[esi+ecx]
- mov bl,[esi+edx]
- mov dl,[eax]
- test [loopcount],dword 0ffffffffh
- jnz hdoubleloop
- jmp hchecklast
-hfillone:
- mov eax,[_ds_colormap]
- mov esi,[_ds_source]
- mov edi,[dest]
- mov ebp,[frac]
- shld ecx,ebp,22
- shld ecx,ebp,6
- and ecx,0fffh
- mov al,[esi+ecx]
- mov dl,[eax]
- mov [edi],dl
- jmp hdoneplane
-
-hdoubleloop:
- shld ecx,ebp,22
- mov dh,[ebx]
- shld ecx,ebp,6
-hpatch1:
- add ebp,12345678h
- and ecx,0fffh
- mov [edi],dx
- shld edx,ebp,22
- add edi,2
- shld edx,ebp,6
-hpatch2:
- add ebp,12345678h
- and edx,0fffh
- mov al,[esi+ecx]
- mov bl,[esi+edx]
- dec dword [loopcount]
- mov dl,[eax]
- jnz hdoubleloop
-hchecklast:
- test [endpx],dword 1
- jnz hdoneplane
- mov [edi],dl
-hdoneplane:
- mov ecx,[curplane]
- inc ecx
- and ecx,3
- jnz hskip
- inc dword [dest]
-hskip:
- cmp ecx,[endplane]
- jz hdone
- mov [curplane],ecx
- mov ebx,[frac]
- add ebx,[fracstep]
- mov [frac],ebx
- inc dword [curx]
- jmp hplane
-hdone:
- popad
- ret
-
-
-global _R_DrawSpanLow
-_R_DrawSpanLow:
- pushad
- mov eax,[_ds_x1]
- mov [curx],eax
- mov ebx,eax
- and ebx,1
- mov [endplane],ebx
- mov [curplane],ebx
- shr eax,1
- mov ebp,[_ds_y]
- lea edi,[ebp+ebp*4]
- shl edi,4
- add edi,eax
- add edi,[_destview]
- mov [dest],edi
-
- mov ebx,[_ds_xfrac]
- shl ebx,10
- and ebx,0ffff0000h
- mov eax,[_ds_yfrac]
- shr eax,6
- and eax,0ffffh
- or ebx,eax
-
- mov [frac],ebx
-
- mov ebx,[_ds_xstep]
- shl ebx,10
- and ebx,0ffff0000h
- mov eax,[_ds_ystep]
- shr eax,6
- and eax,0ffffh
- or ebx,eax
-
- mov [fracstep],ebx
-
- shl ebx,1
- mov [fracpstep],ebx
- mov eax,lpatch1+2
- mov [eax],ebx
- mov eax,lpatch2+2
- mov [eax],ebx
- mov ecx,[curplane]
-lplane:
- mov eax,3
- shl eax,cl
- shl eax,cl
- mov edx,SC_INDEX+1
- out dx,al
- mov eax,[_ds_x2]
- cmp eax,[curx]
- jb ldone
- sub eax,[curplane]
- js ldoneplane
- shr eax,1
- mov [endpx],eax
- dec eax
- js lfillone
- shr eax,1
- mov ebx,[curx]
- shr ebx,1
- cmp ebx,[endpx]
- jz lfillone
- mov [curpx],ebx
- inc ebx
- shr ebx,1
- inc eax
- sub eax,ebx
- js ldoneplane
- mov [loopcount],eax
- mov eax,[_ds_colormap]
- mov ebx,eax
- mov esi,[_ds_source]
- mov edi,[dest]
- mov ebp,[frac]
- test [curpx],dword 1
- jz lfill
- shld ecx,ebp,22
- shld ecx,ebp,6
- add ebp,[fracpstep]
- and ecx,0fffh
- mov al,[esi+ecx]
- mov dl,[eax]
- mov [edi],dl
- inc edi
- jz ldoneplane
-lfill:
- shld ecx,ebp,22
- shld ecx,ebp,6
- add ebp,[fracpstep]
- and ecx,0fffh
- shld edx,ebp,22
- shld edx,ebp,6
- add ebp,[fracpstep]
- and edx,0fffh
- mov al,[esi+ecx]
- mov bl,[esi+edx]
- mov dl,[eax]
- test [loopcount],dword 0ffffffffh
- jnz ldoubleloop
- jmp lchecklast
-lfillone:
- mov eax,[_ds_colormap]
- mov esi,[_ds_source]
- mov edi,[dest]
- mov ebp,[frac]
- shld ecx,ebp,22
- shld ecx,ebp,6
- and ecx,0fffh
- mov al,[esi+ecx]
- mov dl,[eax]
- mov [edi],dl
- jmp ldoneplane
-
-ldoubleloop:
- shld ecx,ebp,22
- mov dh,[ebx]
- shld ecx,ebp,6
-lpatch1:
- add ebp,12345678h
- and ecx,0fffh
- mov [edi],dx
- shld edx,ebp,22
- add edi,2
- shld edx,ebp,6
-lpatch2:
- add ebp,12345678h
- and edx,0fffh
- mov al,[esi+ecx]
- mov bl,[esi+edx]
- dec dword [loopcount]
- mov dl,[eax]
- jnz ldoubleloop
-lchecklast:
- test [endpx],dword 1
- jnz ldoneplane
- mov [edi],dl
-ldoneplane:
- mov ecx,[curplane]
- inc ecx
- and ecx,1
- jnz lskip
- inc dword [dest]
-lskip:
- cmp ecx,[endplane]
- jz ldone
- mov [curplane],ecx
- mov ebx,[frac]
- add ebx,[fracstep]
- mov [frac],ebx
- inc dword [curx]
- jmp lplane
-ldone:
- popad
- ret
diff --git a/setenvdj.bat b/setenvdj.bat
deleted file mode 100644
index cf20925..0000000
--- a/setenvdj.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-SET PATH=C:\Progs\nasm-2.16.01;%PATH%
-C:\Progs\djgpp\setenv.bat
diff --git a/setenvdm.bat b/setenvdm.bat
deleted file mode 100644
index 3a02feb..0000000
--- a/setenvdm.bat
+++ /dev/null
@@ -1 +0,0 @@
-SET PATH=C:\Progs\nasm-2.16.01;C:\Progs\DM\BIN;%PATH%
diff --git a/setenvoc.bat b/setenvoc.bat
deleted file mode 100644
index d80e42d..0000000
--- a/setenvoc.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-SET LADSOFT=C:\Progs\cc386
-SET PATH=C:\Progs\nasm-2.16.01;%LADSOFT%\bin;%PATH%
diff --git a/setenvwc.bat b/setenvwc.bat
deleted file mode 100644
index 74d6808..0000000
--- a/setenvwc.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-SET WATCOM=C:\DOS\PROGTAAL\WATCOM
-SET INCLUDE=%WATCOM%\H
-SET PATH=C:\Progs\nasm-2.16.01;%WATCOM%\BINNT64;%WATCOM%\BINNT;%PATH%
diff --git a/am_data.h b/src/am_data.h
similarity index 100%
rename from am_data.h
rename to src/am_data.h
diff --git a/am_map.c b/src/am_map.c
similarity index 100%
rename from am_map.c
rename to src/am_map.c
diff --git a/am_map.h b/src/am_map.h
similarity index 100%
rename from am_map.h
rename to src/am_map.h
diff --git a/compiler.h b/src/compiler.h
similarity index 91%
rename from compiler.h
rename to src/compiler.h
index 800c503..dc4e271 100644
--- a/compiler.h
+++ b/src/compiler.h
@@ -19,11 +19,14 @@
#ifndef __COMPILER__
#define __COMPILER__
+#if defined __GNUC__
+
#if defined __DJGPP__
//DJGPP
#include
#include
#include
+#include
#define mkdir(x) mkdir(x,0)
@@ -58,7 +61,33 @@ asm \
: "m" (OldInt.pm_offset) \
)
+#else
+
+#include
+#include
+
+#define mkdir(x) mkdir(x,0)
+
+static char* strupr(char* s)
+{
+ char* tmp = s;
+
+ for (;*tmp;++tmp) {
+ *tmp = toupper((unsigned char) *tmp);
+ }
+ return s;
+}
+
+static long filelength(int fd)
+{
+ struct stat st;
+ if (fstat(fd, &st) == -1)
+ return -1;
+ return st.st_size;
+}
+
+#endif
#elif defined __DMC__
//Digital Mars
@@ -152,26 +181,6 @@ typedef struct {
uint32_t reserved[3];
} __dpmi_free_mem_info;
-#if !defined C_ONLY
-#pragma aux FixedMul = \
- "imul ecx", \
- "shrd eax, edx, 16" \
- value [eax] \
- parm [eax] [ecx] \
- modify [edx]
-
-typedef int32_t fixed_t;
-fixed_t FixedDiv2 (fixed_t a, fixed_t b);
-#pragma aux FixedDiv2 = \
- "cdq", \
- "shld edx, eax, 16", \
- "shl eax, 16", \
- "idiv ecx" \
- value [eax] \
- parm [eax] [ecx] \
- modify [edx]
-#endif
-
#endif
diff --git a/d_chex.h b/src/d_chex.h
similarity index 100%
rename from d_chex.h
rename to src/d_chex.h
diff --git a/d_french.h b/src/d_french.h
similarity index 100%
rename from d_french.h
rename to src/d_french.h
diff --git a/d_main.c b/src/d_main.c
similarity index 95%
rename from d_main.c
rename to src/d_main.c
index 8c957da..da8896c 100644
--- a/d_main.c
+++ b/src/d_main.c
@@ -20,9 +20,12 @@
#include
#include
+#ifdef __linux__
+#else
#include
#include
#include
+#endif
#include "doomdef.h"
#include "soundst.h"
#include "dutils.h"
@@ -157,94 +160,6 @@ void D_ProcessEvents (void)
}
}
-/*
-================
-=
-= FixedMul and FixedDiv
-=
-================
-*/
-
-#if defined C_ONLY
-fixed_t FixedMul (fixed_t a, fixed_t b)
-{
- return ((int64_t) a * (int64_t) b) >> FRACBITS;
-}
-
-static fixed_t FixedDiv2 (fixed_t a, fixed_t b)
-{
- int64_t result = ((int64_t) a << FRACBITS) / b;
- return (fixed_t) result;
-}
-#else
-
-#if defined __DJGPP__
-fixed_t FixedMul(fixed_t a, fixed_t b)
-{
- asm
- (
- "imul %2 \n"
- "shrd $16, %%edx, %%eax"
- : "=a" (a)
- : "a" (a), "r" (b)
- : "edx"
- );
- return a;
-}
-
-static fixed_t FixedDiv2(fixed_t a, fixed_t b)
-{
- asm
- (
- "cdq \n"
- "shld $16, %%eax, %%edx \n"
- "shl $16, %%eax \n"
- "idiv %2"
- : "=a" (a)
- : "a" (a), "r" (b)
- : "edx"
- );
- return a;
-}
-
-#elif defined __DMC__ || defined __CCDL__
-fixed_t FixedMul(fixed_t a, fixed_t b)
-{
- asm
- {
- mov eax, [a]
- mov ecx, [b]
- imul ecx
- shrd eax, edx, 16
- };
- return _EAX;
-}
-
-static fixed_t FixedDiv2(fixed_t a, fixed_t b)
-{
- asm
- {
- mov eax, [a]
- mov ecx, [b]
- cdq
- shld edx, eax, 16
- shl eax, 16
- idiv ecx
- };
- return _EAX;
-}
-#endif
-
-#endif
-
-fixed_t FixedDiv (fixed_t a, fixed_t b)
-{
- if ( (abs(a)>>14) >= abs(b))
- return ((a ^ b) >> 31) ^ MAXINT;
- else
- return FixedDiv2 (a,b);
-}
-
/*
================
=
@@ -605,6 +520,21 @@ void D_StartTitle (void)
static char title[128]; // print title for every printed line
+#ifdef __linux__
+
+static void tprintf(char *msg, int32_t fgcolor, int32_t bgcolor) {
+ printf("\033[%d;%dm%s\033[0m", bgcolor, fgcolor, msg);
+}
+
+void mprintf(char *msg) {
+ int32_t x, y;
+ printf("%s", msg);
+
+ tprintf(title, FGCOLOR, BGCOLOR);
+}
+
+#else
+
static int32_t GetTextX(void)
{
union REGS regs;
@@ -676,6 +606,8 @@ void mprintf(char *msg)
SetTextPos(x, y);
}
+#endif
+
/*
===============
=
@@ -950,7 +882,6 @@ static void FindResponseFile (void)
void D_DoomMain (void)
{
- union REGS regs;
int32_t p;
char file[256];
@@ -1047,10 +978,12 @@ void D_DoomMain (void)
VERSION/100,VERSION%100);
}
+#ifndef __linux__
+ union REGS regs;
regs.h.ah = 0;
regs.h.al = 3;
int386 (0x10, ®s, ®s);
-
+#endif
tprintf (title, FGCOLOR, BGCOLOR);
#if (APPVER_DOOMREV < AV_DR_DM19)
@@ -1065,6 +998,10 @@ void D_DoomMain (void)
if (M_CheckParm("-cdrom"))
{
printf(D_CDROM);
+#ifdef __linux__
+ mkdir("/tmp/doomdata");
+ strcpy (basedefault,"/tmp/doomdata/default.cfg");
+#else
#if (APPVER_DOOMREV < AV_DR_DM1666E)
mkdir("c:doomdata");
#elif (APPVER_DOOMREV < AV_DR_DM17)
@@ -1073,6 +1010,7 @@ void D_DoomMain (void)
mkdir("c:\\doomdata");
#endif
strcpy (basedefault,"c:/doomdata/default.cfg");
+#endif
}
// turbo option
diff --git a/d_net.c b/src/d_net.c
similarity index 100%
rename from d_net.c
rename to src/d_net.c
diff --git a/dmx.h b/src/dmx.h
similarity index 99%
rename from dmx.h
rename to src/dmx.h
index f9ad4a1..93f306b 100644
--- a/dmx.h
+++ b/src/dmx.h
@@ -19,8 +19,6 @@
#ifndef _DMX_H_
#define _DMX_H_
-#include "a_tsmapi.h"
-
void MUS_PauseSong(int32_t handle);
void MUS_ResumeSong(int32_t handle);
void MUS_SetMasterVolume(int32_t volume);
diff --git a/doomdata.h b/src/doomdata.h
similarity index 98%
rename from doomdata.h
rename to src/doomdata.h
index 2a60754..1782620 100644
--- a/doomdata.h
+++ b/src/doomdata.h
@@ -142,10 +142,11 @@ typedef struct
typedef struct
{
char name[8];
- boolean masked;
+ int16_t masked;
+ int16_t masked2;
int16_t width;
int16_t height;
- void **columndirectory; // OBSOLETE
+ char columndirectory[4]; // OBSOLETE
int16_t patchcount;
mappatch_t patches[1];
} maptexture_t;
diff --git a/doomdef.h b/src/doomdef.h
similarity index 93%
rename from doomdef.h
rename to src/doomdef.h
index d2f20fb..2738734 100644
--- a/doomdef.h
+++ b/src/doomdef.h
@@ -50,7 +50,7 @@
// header generated by multigen utility
#include "info.h"
-extern byte *destview, *destscreen; // PC direct to screen pointers
+extern byte *destview, *destscreen, *screen; // PC direct to screen pointers
//
// most key data are simple ascii (uppercased)
@@ -640,8 +640,115 @@ extern boolean autostart;
*/
-fixed_t FixedMul (fixed_t a, fixed_t b);
-fixed_t FixedDiv (fixed_t a, fixed_t b);
+/*
+================
+=
+= FixedMul and FixedDiv
+=
+================
+*/
+
+#if defined C_ONLY
+static fixed_t FixedMul (fixed_t a, fixed_t b)
+{
+ return ((int64_t) a * (int64_t) b) >> FRACBITS;
+}
+
+static fixed_t FixedDiv2 (fixed_t a, fixed_t b)
+{
+ int64_t result = ((int64_t) a << FRACBITS) / b;
+ return (fixed_t) result;
+}
+#else
+
+#if defined __GNUC__
+
+inline static fixed_t FixedMul(fixed_t a, fixed_t b)
+{
+ asm
+ (
+ "imul %2 \n"
+ "shrd $16, %%edx, %%eax"
+ : "=a" (a)
+ : "a" (a), "r" (b)
+ : "edx"
+ );
+ return a;
+}
+
+inline static fixed_t FixedDiv2(fixed_t a, fixed_t b)
+{
+ asm
+ (
+ "cdq \n"
+ "shld $16, %%eax, %%edx \n"
+ "shl $16, %%eax \n"
+ "idiv %2"
+ : "=a" (a)
+ : "a" (a), "r" (b)
+ : "edx"
+ );
+ return a;
+}
+
+#elif defined __DMC__ || defined __CCDL__
+static fixed_t FixedMul(fixed_t a, fixed_t b)
+{
+ asm
+ {
+ mov eax, [a]
+ mov ecx, [b]
+ imul ecx
+ shrd eax, edx, 16
+ };
+ return _EAX;
+}
+
+static fixed_t FixedDiv2(fixed_t a, fixed_t b)
+{
+ asm
+ {
+ mov eax, [a]
+ mov ecx, [b]
+ cdq
+ shld edx, eax, 16
+ shl eax, 16
+ idiv ecx
+ };
+ return _EAX;
+}
+#else // WATCOM
+
+#pragma aux FixedMul = \
+ "imul ecx", \
+ "shrd eax, edx, 16" \
+ value [eax] \
+ parm [eax] [ecx] \
+ modify [edx]
+
+fixed_t FixedDiv2 (fixed_t a, fixed_t b);
+#pragma aux FixedDiv2 = \
+ "cdq", \
+ "shld edx, eax, 16", \
+ "shl eax, 16", \
+ "idiv ecx" \
+ value [eax] \
+ parm [eax] [ecx] \
+ modify [edx]
+
+
+#endif
+
+#endif
+
+static fixed_t FixedDiv (fixed_t a, fixed_t b)
+{
+ if ( (abs(a)>>14) >= abs(b))
+ return ((a ^ b) >> 31) ^ MAXINT;
+ else
+ return FixedDiv2 (a,b);
+}
+
#ifdef __BIG_ENDIAN__
int16_t ShortSwap(int16_t);
@@ -673,24 +780,10 @@ void *Z_Malloc (int32_t size, int32_t tag, void *ptr);
void Z_Free (void *ptr);
void Z_FreeTags (int32_t lowtag, int32_t hightag);
void Z_CheckHeap (void);
-void Z_ChangeTag2 (void *ptr, int32_t tag);
+void Z_ChangeTag2 (void *ptr, int32_t tag, const char* file, int line);
-typedef struct memblock_s
-{
- int32_t size; // including the header and possibly tiny fragments
- void **user; // NULL if a free block
- int32_t tag; // purgelevel
- int32_t id; // should be ZONEID
- struct memblock_s *next, *prev;
-} memblock_t;
-
-#define Z_ChangeTag(p,t) \
-{ \
-if (( (memblock_t *)( (byte *)(p) - sizeof(memblock_t)))->id!=0x1d4a11) \
- I_Error("Z_CT at "__FILE__":%i",__LINE__); \
-Z_ChangeTag2(p,t); \
-};
+#define Z_ChangeTag(p,t) Z_ChangeTag2(p,t, __FILE__, __LINE__)
//-------
//WADFILE
diff --git a/a_al_mid.c b/src/dos/a_al_mid.c
similarity index 99%
rename from a_al_mid.c
rename to src/dos/a_al_mid.c
index d92735f..b43e835 100644
--- a/a_al_mid.c
+++ b/src/dos/a_al_mid.c
@@ -32,10 +32,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_al_mid.h"
#include "a_ll_man.h"
+#define UNUSED(x) (x = x) // for pesky compiler / lint warnings
+
#define AL_MaxVolume 127
#define AL_DefaultChannelVolume 90
diff --git a/a_al_mid.h b/src/dos/a_al_mid.h
similarity index 97%
rename from a_al_mid.h
rename to src/dos/a_al_mid.h
index e9b42c8..2636183 100644
--- a/a_al_mid.h
+++ b/src/dos/a_al_mid.h
@@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __AL_MIDI_H
#define __AL_MIDI_H
+#include "../id_heads.h"
+
void AL_Shutdown(void);
void AL_Init(void);
void AL_NoteOff(int32_t channel, int32_t key, int32_t velocity);
diff --git a/a_blast.c b/src/dos/a_blast.c
similarity index 99%
rename from a_blast.c
rename to src/dos/a_blast.c
index 0660c52..1b478a0 100644
--- a/a_blast.c
+++ b/src/dos/a_blast.c
@@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_blast.h"
#include "a_dma.h"
diff --git a/a_blast.h b/src/dos/a_blast.h
similarity index 100%
rename from a_blast.h
rename to src/dos/a_blast.h
diff --git a/a_dma.c b/src/dos/a_dma.c
similarity index 99%
rename from a_dma.c
rename to src/dos/a_dma.c
index 2a61dbf..b6c9e7a 100644
--- a/a_dma.c
+++ b/src/dos/a_dma.c
@@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_dma.h"
#define DMA_MaxChannel 7
diff --git a/a_dma.h b/src/dos/a_dma.h
similarity index 100%
rename from a_dma.h
rename to src/dos/a_dma.h
diff --git a/a_inter.h b/src/dos/a_inter.h
similarity index 100%
rename from a_inter.h
rename to src/dos/a_inter.h
diff --git a/a_ll_man.c b/src/dos/a_ll_man.c
similarity index 98%
rename from a_ll_man.c
rename to src/dos/a_ll_man.c
index 91336ff..ce21467 100644
--- a/a_ll_man.c
+++ b/src/dos/a_ll_man.c
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_ll_man.h"
diff --git a/a_ll_man.h b/src/dos/a_ll_man.h
similarity index 100%
rename from a_ll_man.h
rename to src/dos/a_ll_man.h
diff --git a/a_midi.c b/src/dos/a_midi.c
similarity index 99%
rename from a_midi.c
rename to src/dos/a_midi.c
index 30fd04f..6a1cc1f 100644
--- a/a_midi.c
+++ b/src/dos/a_midi.c
@@ -31,8 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
-#include "dmx.h"
+#include "../id_heads.h"
+#include "../dmx.h"
#include "a_inter.h"
#include "a_midi.h"
#include "a_music.h"
diff --git a/a_midi.h b/src/dos/a_midi.h
similarity index 100%
rename from a_midi.h
rename to src/dos/a_midi.h
diff --git a/a_mpu401.c b/src/dos/a_mpu401.c
similarity index 99%
rename from a_mpu401.c
rename to src/dos/a_mpu401.c
index 475b20f..7e6a0a1 100644
--- a/a_mpu401.c
+++ b/src/dos/a_mpu401.c
@@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_mpu401.h"
#define MPU_NotFound -1
diff --git a/a_mpu401.h b/src/dos/a_mpu401.h
similarity index 100%
rename from a_mpu401.h
rename to src/dos/a_mpu401.h
diff --git a/a_multiv.c b/src/dos/a_multiv.c
similarity index 99%
rename from a_multiv.c
rename to src/dos/a_multiv.c
index fdca9b6..5751993 100644
--- a/a_multiv.c
+++ b/src/dos/a_multiv.c
@@ -32,8 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
-#include "dmx.h"
+#include "../id_heads.h"
+#include "../dmx.h"
#include "a_blast.h"
#include "a_dma.h"
#include "a_inter.h"
diff --git a/a_multiv.h b/src/dos/a_multiv.h
similarity index 100%
rename from a_multiv.h
rename to src/dos/a_multiv.h
diff --git a/a_music.c b/src/dos/a_music.c
similarity index 99%
rename from a_music.c
rename to src/dos/a_music.c
index 89829b5..880fd95 100644
--- a/a_music.c
+++ b/src/dos/a_music.c
@@ -29,8 +29,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
-#include "id_heads.h"
-#include "dmx.h"
+#include "../id_heads.h"
+#include "../dmx.h"
#include "a_al_mid.h"
#include "a_blast.h"
#include "a_midi.h"
diff --git a/a_music.h b/src/dos/a_music.h
similarity index 100%
rename from a_music.h
rename to src/dos/a_music.h
diff --git a/a_musmid.c b/src/dos/a_musmid.c
similarity index 99%
rename from a_musmid.c
rename to src/dos/a_musmid.c
index 2f7c638..3a51015 100644
--- a/a_musmid.c
+++ b/src/dos/a_musmid.c
@@ -17,7 +17,7 @@
// mus2mid.c - Ben Ryves 2006 - http://benryves.com - benryves@benryves.com
// Use to convert a MUS file into a single track, type 0 MIDI file.
-#include "id_heads.h"
+#include "../id_heads.h"
#define NUM_CHANNELS 16
diff --git a/a_mv_mix.asm b/src/dos/a_mv_mix.asm
similarity index 100%
rename from a_mv_mix.asm
rename to src/dos/a_mv_mix.asm
diff --git a/a_pcfx.c b/src/dos/a_pcfx.c
similarity index 99%
rename from a_pcfx.c
rename to src/dos/a_pcfx.c
index bfc51b0..1866e5e 100644
--- a/a_pcfx.c
+++ b/src/dos/a_pcfx.c
@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_inter.h"
#include "a_pcfx.h"
#include "a_taskmn.h"
diff --git a/a_pcfx.h b/src/dos/a_pcfx.h
similarity index 100%
rename from a_pcfx.h
rename to src/dos/a_pcfx.h
diff --git a/a_taskmn.c b/src/dos/a_taskmn.c
similarity index 99%
rename from a_taskmn.c
rename to src/dos/a_taskmn.c
index db91517..5257a32 100644
--- a/a_taskmn.c
+++ b/src/dos/a_taskmn.c
@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_inter.h"
#include "a_taskmn.h"
diff --git a/a_taskmn.h b/src/dos/a_taskmn.h
similarity index 100%
rename from a_taskmn.h
rename to src/dos/a_taskmn.h
diff --git a/a_tsmapi.c b/src/dos/a_tsmapi.c
similarity index 98%
rename from a_tsmapi.c
rename to src/dos/a_tsmapi.c
index 3e10f7e..1f482f0 100644
--- a/a_tsmapi.c
+++ b/src/dos/a_tsmapi.c
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//
-#include "id_heads.h"
+#include "../id_heads.h"
#include "a_taskmn.h"
#include "a_tsmapi.h"
diff --git a/a_tsmapi.h b/src/dos/a_tsmapi.h
similarity index 100%
rename from a_tsmapi.h
rename to src/dos/a_tsmapi.h
diff --git a/dmx.c b/src/dos/dmx.c
similarity index 99%
rename from dmx.c
rename to src/dos/dmx.c
index 98626f1..cef56fc 100644
--- a/dmx.c
+++ b/src/dos/dmx.c
@@ -17,8 +17,8 @@
// along with this program. If not, see .
//
-#include "id_heads.h"
-#include "dmx.h"
+#include "../id_heads.h"
+#include "../dmx.h"
#include "a_al_mid.h"
#include "a_blast.h"
#include "a_mpu401.h"
diff --git a/i_ibm.c b/src/dos/i_ibm.c
similarity index 99%
rename from i_ibm.c
rename to src/dos/i_ibm.c
index c8cbe0f..445667c 100644
--- a/i_ibm.c
+++ b/src/dos/i_ibm.c
@@ -21,8 +21,8 @@
#include
#include
#include
-#include "doomdef.h"
-#include "r_local.h"
+#include "../doomdef.h"
+#include "../r_local.h"
#define DPMI_INT 0x31
//#define NOTIMER
@@ -294,7 +294,8 @@ void I_SetPalette (byte *palette)
============================================================================
*/
-static byte *screen, *currentscreen;
+byte *screen;
+static byte *currentscreen;
byte *destscreen;
byte *destview __attribute__ ((externally_visible));
diff --git a/i_sound.c b/src/dos/i_sound.c
similarity index 99%
rename from i_sound.c
rename to src/dos/i_sound.c
index 7d7ee17..f5b08a0 100644
--- a/i_sound.c
+++ b/src/dos/i_sound.c
@@ -18,9 +18,11 @@
// I_SOUND.C
-#include "doomdef.h"
-#include "dmx.h"
-#include "sounds.h"
+#include "../doomdef.h"
+#include "a_tsmapi.h"
+
+#include "../dmx.h"
+#include "../sounds.h"
#define SND_TICRATE 140 // tic rate for updating sound
#define SND_MAXSONGS 40 // max number of songs in game
diff --git a/dstrings.h b/src/dstrings.h
similarity index 100%
rename from dstrings.h
rename to src/dstrings.h
diff --git a/dutils.c b/src/dutils.c
similarity index 100%
rename from dutils.c
rename to src/dutils.c
diff --git a/dutils.h b/src/dutils.h
similarity index 100%
rename from dutils.h
rename to src/dutils.h
diff --git a/f_finale.c b/src/f_finale.c
similarity index 100%
rename from f_finale.c
rename to src/f_finale.c
diff --git a/g_game.c b/src/g_game.c
similarity index 100%
rename from g_game.c
rename to src/g_game.c
diff --git a/gamever.h b/src/gamever.h
similarity index 100%
rename from gamever.h
rename to src/gamever.h
diff --git a/hu_lib.c b/src/hu_lib.c
similarity index 100%
rename from hu_lib.c
rename to src/hu_lib.c
diff --git a/hu_lib.h b/src/hu_lib.h
similarity index 100%
rename from hu_lib.h
rename to src/hu_lib.h
diff --git a/hu_stuff.c b/src/hu_stuff.c
similarity index 100%
rename from hu_stuff.c
rename to src/hu_stuff.c
diff --git a/hu_stuff.h b/src/hu_stuff.h
similarity index 100%
rename from hu_stuff.h
rename to src/hu_stuff.h
diff --git a/i_main.c b/src/i_main.c
similarity index 100%
rename from i_main.c
rename to src/i_main.c
diff --git a/id_heads.h b/src/id_heads.h
similarity index 100%
rename from id_heads.h
rename to src/id_heads.h
diff --git a/info.c b/src/info.c
similarity index 100%
rename from info.c
rename to src/info.c
diff --git a/info.h b/src/info.h
similarity index 100%
rename from info.h
rename to src/info.h
diff --git a/src/linux/dmx.c b/src/linux/dmx.c
new file mode 100644
index 0000000..c2b3c5c
--- /dev/null
+++ b/src/linux/dmx.c
@@ -0,0 +1,149 @@
+//
+// Copyright (C) 2005-2014 Simon Howard
+// Copyright (C) 2015-2017 Alexey Khokholov (Nuke.YKT)
+// Copyright (C) 2023-2025 Frenkel Smeijers
+//
+// 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, see .
+//
+
+#include "../id_heads.h"
+#include "../dmx.h"
+
+static void *mus_data = NULL;
+static uint8_t *mid_data = NULL;
+
+static int32_t mus_loop = 0;
+static int32_t dmx_mus_port = 0;
+static int32_t dmx_sdev = AHW_NONE;
+static int32_t dmx_mdev = AHW_NONE;
+static int32_t mus_rate = 140;
+static int32_t mus_mastervolume = 127;
+
+void MUS_PauseSong(int32_t handle)
+{
+ UNUSED(handle);
+}
+
+void MUS_ResumeSong(int32_t handle)
+{
+ UNUSED(handle);
+}
+
+void MUS_SetMasterVolume(int32_t volume)
+{
+ mus_mastervolume = volume;
+}
+
+int32_t MUS_RegisterSong(uint8_t *data)
+{
+
+ return 0;
+}
+
+void MUS_UnregisterSong(int32_t handle) {UNUSED(handle);}
+
+void MUS_StopSong(int32_t handle)
+{
+ UNUSED(handle);
+}
+
+void MUS_ChainSong(int32_t handle, int32_t to)
+{
+ mus_loop = (to == handle);
+}
+
+void MUS_PlaySong(int32_t handle, int32_t volume)
+{
+}
+
+
+int32_t SFX_PlayPatch(void *data, int32_t pitch, int32_t sep, int32_t volume, int32_t flags, int32_t priority)
+{
+ return -1;
+}
+
+void SFX_StopPatch(int32_t handle)
+{
+}
+
+int32_t SFX_Playing(int32_t handle)
+{
+ return false;
+}
+
+void SFX_SetOrigin(int32_t handle, int32_t pitch, int32_t sep, int32_t volume)
+{
+}
+
+
+int32_t ENS_Detect(void) {return -1;}
+int32_t CODEC_Detect(int32_t *sbPort, int32_t *sbDma) {UNUSED(sbPort); UNUSED(sbDma); return -1;}
+int32_t GF1_Detect(void) {return -1;}
+void GF1_SetMap(uint8_t *dmxlump, int32_t size) {UNUSED(dmxlump); UNUSED(size);}
+
+
+int32_t SB_Detect(int32_t *sbPort, int32_t *sbIrq, int32_t *sbDma, uint16_t *dspVersion)
+{
+
+ return 0;
+}
+
+void SB_SetCard(int32_t iBaseAddr, int32_t iIrq, int32_t iDma)
+{
+ UNUSED(iBaseAddr);
+ UNUSED(iIrq);
+ UNUSED(iDma);
+}
+
+
+int32_t AL_Detect(int32_t *wait, int32_t *type)
+{
+ UNUSED(wait);
+ UNUSED(type);
+ return -1;
+}
+
+void AL_SetCard(int32_t wait, void *data)
+{
+}
+
+
+int32_t MPU_Detect(int32_t *mPort, int32_t *type)
+{
+ UNUSED(type);
+
+ return -1;
+}
+
+void MPU_SetCard(int32_t mPort)
+{
+ dmx_mus_port = mPort;
+}
+
+
+int32_t DMX_Init(int32_t ticrate, int32_t maxsongs, uint32_t musicDevice, uint32_t sfxDevice)
+{
+ UNUSED(maxsongs);
+
+ return musicDevice | sfxDevice;
+}
+
+void DMX_DeInit(void)
+{
+}
+
+
+void WAV_PlayMode(int32_t channels, uint16_t sampleRate)
+{
+}
diff --git a/src/linux/i_linux.c b/src/linux/i_linux.c
new file mode 100644
index 0000000..937db54
--- /dev/null
+++ b/src/linux/i_linux.c
@@ -0,0 +1,1458 @@
+//
+// Copyright (C) 1993-1996 Id Software, Inc.
+// Copyright (C) 2023 Frenkel Smeijers
+//
+// 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, see .
+//
+
+// I_IBM.C
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "../doomdef.h"
+#include "../r_local.h"
+
+#define DPMI_INT 0x31
+#define NOTIMER
+
+void I_StartupSound (void);
+void I_ShutdownSound (void);
+
+void I_ShutdownTimer (void);
+
+static void DPMIInt (int32_t i);
+
+static void I_ReadMouse (void);
+static void I_InitDiskFlash (void);
+
+extern int32_t usemouse, usejoystick;
+
+Display* X_display=0;
+Window X_mainWindow;
+Colormap X_cmap;
+Visual* X_visual;
+GC X_gc;
+XEvent X_event;
+int X_screen;
+XVisualInfo X_visualinfo;
+XImage* image;
+int X_width;
+int X_height;
+
+
+
+/*
+=============================================================================
+
+ CONSTANTS
+
+=============================================================================
+*/
+
+#define SC_INDEX 0x3c4
+#define SC_RESET 0
+#define SC_CLOCK 1
+#define SC_MAPMASK 2
+#define SC_CHARMAP 3
+#define SC_MEMMODE 4
+
+#define CRTC_INDEX 0x3d4
+#define CRTC_H_TOTAL 0
+#define CRTC_H_DISPEND 1
+#define CRTC_H_BLANK 2
+#define CRTC_H_ENDBLANK 3
+#define CRTC_H_RETRACE 4
+#define CRTC_H_ENDRETRACE 5
+#define CRTC_V_TOTAL 6
+#define CRTC_OVERFLOW 7
+#define CRTC_ROWSCAN 8
+#define CRTC_MAXSCANLINE 9
+#define CRTC_CURSORSTART 10
+#define CRTC_CURSOREND 11
+#define CRTC_STARTHIGH 12
+#define CRTC_STARTLOW 13
+#define CRTC_CURSORHIGH 14
+#define CRTC_CURSORLOW 15
+#define CRTC_V_RETRACE 16
+#define CRTC_V_ENDRETRACE 17
+#define CRTC_V_DISPEND 18
+#define CRTC_OFFSET 19
+#define CRTC_UNDERLINE 20
+#define CRTC_V_BLANK 21
+#define CRTC_V_ENDBLANK 22
+#define CRTC_MODE 23
+#define CRTC_LINECOMPARE 24
+
+
+#define GC_INDEX 0x3ce
+#define GC_SETRESET 0
+#define GC_ENABLESETRESET 1
+#define GC_COLORCOMPARE 2
+#define GC_DATAROTATE 3
+#define GC_READMAP 4
+#define GC_MODE 5
+#define GC_MISCELLANEOUS 6
+#define GC_COLORDONTCARE 7
+#define GC_BITMASK 8
+
+#define STATUS_REGISTER_1 0x3da
+
+#define PEL_WRITE_ADR 0x3c8
+#define PEL_DATA 0x3c9
+
+static boolean grmode;
+
+//==================================================
+//
+// joystick vars
+//
+//==================================================
+
+static boolean joystickpresent;
+static uint32_t joystickx, joysticky;
+static boolean I_ReadJoystick (void) // returns false if not connected
+{
+ //TODO implement joystick support
+ return false;
+}
+
+
+//==================================================
+
+#define KEYBOARDINT 9
+
+static boolean mousepresent;
+
+//===============================
+
+static volatile int32_t ticcount;
+
+static boolean novideo; // if true, stay in text mode for debugging
+
+#define KBDQUESIZE 32
+static byte keyboardque[KBDQUESIZE];
+static int32_t kbdtail, kbdhead;
+
+#define KEY_LSHIFT 0xfe
+
+#define KEY_INS (0x80+0x52)
+#define KEY_DEL (0x80+0x53)
+#define KEY_PGUP (0x80+0x49)
+#define KEY_PGDN (0x80+0x51)
+#define KEY_HOME (0x80+0x47)
+#define KEY_END (0x80+0x4f)
+
+#define SC_RSHIFT 0x36
+#define SC_LSHIFT 0x2a
+
+byte scantokey[128] =
+ {
+// 0 1 2 3 4 5 6 7
+// 8 9 A B C D E F
+ 0 , 27, '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9, // 0
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+ 'o', 'p', '[', ']', 13 , KEY_RCTRL,'a', 's', // 1
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
+ 39 , '`', KEY_LSHIFT,92, 'z', 'x', 'c', 'v', // 2
+ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT,'*',
+ KEY_RALT,' ', 0 , KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3
+ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,0 , 0 , KEY_HOME,
+ KEY_UPARROW,KEY_PGUP,'-',KEY_LEFTARROW,'5',KEY_RIGHTARROW,'+',KEY_END, //4
+ KEY_DOWNARROW,KEY_PGDN,KEY_INS,KEY_DEL,0,0, 0, KEY_F11,
+ KEY_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
+ };
+
+//==========================================================================
+
+/*
+===================
+=
+= I_BaseTiccmd
+=
+===================
+*/
+
+typedef struct
+{
+ int32_t f_0; // interrupt
+ ticcmd_t f_4; // cmd
+} doomcontrol_t;
+
+static doomcontrol_t *doomcon;
+static ticcmd_t emptycmd;
+
+ticcmd_t *I_BaseTiccmd (void)
+{
+ if (!doomcon)
+ return &emptycmd;
+
+ DPMIInt (doomcon->f_0);
+ return &doomcon->f_4;
+}
+
+/*
+===================
+=
+= I_GetTime
+=
+= Returns time in 1/35th second tics.
+=
+===================
+*/
+
+#if defined NOTIMER
+#include
+static uint32_t basetime;
+
+void I_InitBaseTime(void)
+{
+ basetime = clock();
+}
+
+int32_t I_GetTime (void)
+{
+ uint32_t ticks = clock();
+
+ ticks -= basetime;
+
+ return (ticks * TICRATE) / CLOCKS_PER_SEC;
+}
+#else
+int32_t I_GetTime (void)
+{
+ return ticcount;
+}
+#endif
+
+/*
+===================
+=
+= I_WaitVBL
+=
+===================
+*/
+
+void I_WaitVBL (int32_t vbls)
+{
+}
+
+/*
+===================
+=
+= I_SetPalette
+=
+= Palette source must use 8 bit RGB elements.
+=
+===================
+*/
+
+uint32_t color_palette[256];
+
+void I_SetPalette (byte *palette)
+{
+ int32_t i;
+
+ if (novideo)
+ return;
+
+ I_WaitVBL (1);
+ for (i = 0; i < 256; i++)
+ {
+ uint32_t red = gammatable[usegamma][*palette++];
+ uint32_t green = gammatable[usegamma][*palette++];
+ uint32_t blue = gammatable[usegamma][*palette++];
+ color_palette[i] = (red << 16) | (green << 8) | blue | (0xffu << 24);
+ }
+}
+
+/*
+============================================================================
+
+ GRAPHICS MODE
+
+============================================================================
+*/
+
+byte *screen, *currentscreen;
+byte *destscreen;
+byte *destview __attribute__ ((externally_visible));
+
+/*
+===================
+=
+= I_UpdateBox
+=
+===================
+*/
+
+static void I_UpdateBox (int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ int32_t ofs;
+ byte *source;
+ int16_t *dest;
+ int32_t p,x1, x2;
+ int32_t srcdelta, destdelta;
+ int32_t wwide;
+
+#ifdef RANGECHECK
+ if (x < 0 || y < 0 || width <= 0 || height <= 0
+ || x + width > SCREENWIDTH || y + height > SCREENHEIGHT)
+ {
+ I_Error("Bad I_UpdateBox (%i, %i, %i, %i)", x, y, width, height);
+ }
+#endif
+
+ x1 = x>>3;
+ x2 = (x+width)>>3;
+ wwide = x2-x1+1;
+
+ ofs = y*SCREENWIDTH+(x1<<3);
+ srcdelta = SCREENWIDTH - (wwide<<3);
+ destdelta = PLANEWIDTH/2 - wwide;
+
+ for (p = 0 ; p < 4 ; p++)
+ {
+ source = screens[0] + ofs + p;
+ dest = (int16_t *)(destscreen + (ofs>>2) + (p << 16));
+ for (y=0 ; y voldupdatebox[BOXTOP]) ?
+ dirtybox[BOXTOP] : voldupdatebox[BOXTOP];
+ updatebox[BOXRIGHT] = (dirtybox[BOXRIGHT] > voldupdatebox[BOXRIGHT]) ?
+ dirtybox[BOXRIGHT] : voldupdatebox[BOXRIGHT];
+ updatebox[BOXBOTTOM] = (dirtybox[BOXBOTTOM] < voldupdatebox[BOXBOTTOM]) ?
+ dirtybox[BOXBOTTOM] : voldupdatebox[BOXBOTTOM];
+ updatebox[BOXLEFT] = (dirtybox[BOXLEFT] < voldupdatebox[BOXLEFT]) ?
+ dirtybox[BOXLEFT] : voldupdatebox[BOXLEFT];
+
+ updatebox[BOXTOP] = (updatebox[BOXTOP] > oldupdatebox[BOXTOP]) ?
+ updatebox[BOXTOP] : oldupdatebox[BOXTOP];
+ updatebox[BOXRIGHT] = (updatebox[BOXRIGHT] > oldupdatebox[BOXRIGHT]) ?
+ updatebox[BOXRIGHT] : oldupdatebox[BOXRIGHT];
+ updatebox[BOXBOTTOM] = (updatebox[BOXBOTTOM] < oldupdatebox[BOXBOTTOM]) ?
+ updatebox[BOXBOTTOM] : oldupdatebox[BOXBOTTOM];
+ updatebox[BOXLEFT] = (updatebox[BOXLEFT] < oldupdatebox[BOXLEFT]) ?
+ updatebox[BOXLEFT] : oldupdatebox[BOXLEFT];
+
+ memcpy (voldupdatebox, oldupdatebox, sizeof(oldupdatebox));
+ memcpy (oldupdatebox, dirtybox, sizeof(dirtybox));
+
+ if (updatebox[BOXTOP] >= updatebox[BOXBOTTOM])
+ I_UpdateBox (updatebox[BOXLEFT], updatebox[BOXBOTTOM],
+ updatebox[BOXRIGHT] - updatebox[BOXLEFT] + 1,
+ updatebox[BOXTOP] - updatebox[BOXBOTTOM] + 1);
+ M_ClearBox (dirtybox);
+}
+
+/*
+===================
+=
+= I_FinishUpdate
+=
+===================
+*/
+
+void I_FinishUpdate (void)
+{
+ static int32_t lasttic;
+ int32_t tics, i;
+
+ // draws little dots on the bottom of the screen
+ if (devparm)
+ {
+ tics = I_GetTime() - lasttic;
+ lasttic = I_GetTime();
+ if (tics > 20) tics = 20;
+
+ for (i=0 ; idata + i * image->bytes_per_line);
+ for (int j = 0; j < SCREENWIDTH / 4; j++) {
+ data[x++] = color_palette[src[j]];
+ data[x++] = color_palette[src[j + (1<<16)]];
+ data[x++] = color_palette[src[j + (2<<16)]];
+ data[x++] = color_palette[src[j + (3<<16)]];
+ }
+ }
+
+ XPutImage( X_display,
+ X_mainWindow,
+ X_gc,
+ image,
+ 0, 0,
+ 0, 0,
+ X_width, X_height );
+
+ // sync up with server
+ XSync(X_display, False);
+
+ destscreen += 0x4000;
+ if ( (int32_t)destscreen == (int32_t)(screen + 0xc000))
+ destscreen = screen;
+}
+
+
+
+/*
+===================
+=
+= I_InitGraphics
+=
+===================
+*/
+
+void I_InitGraphics (void)
+{
+
+ if (novideo)
+ return;
+ grmode = true;
+ screen = malloc((1<<16) * 4);
+ currentscreen = screen;
+ destscreen = screen + 0x4000;
+ I_SetPalette (W_CacheLumpName("PLAYPAL", PU_CACHE));
+ I_InitDiskFlash ();
+
+ char* displayname;
+ char* d;
+ int n;
+ int pnum;
+ int x=0;
+ int y=0;
+
+ // warning: char format, different type arg
+ char xsign=' ';
+ char ysign=' ';
+
+ int oktodraw;
+ unsigned long attribmask;
+ XSetWindowAttributes attribs;
+ XGCValues xgcvalues;
+ int valuemask;
+ static int firsttime=1;
+
+ X_width = SCREENWIDTH;
+ X_height = SCREENHEIGHT;
+
+ if (!firsttime) return;
+ firsttime = 0;
+
+ signal(SIGINT, (void (*)(int)) I_Quit);
+
+ displayname = 0;
+
+ // open the display
+ X_display = XOpenDisplay(displayname);
+ if (!X_display) {
+ if (displayname)
+ I_Error("Could not open display [%s]", displayname);
+ else
+ I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
+ }
+
+ // use the default visual
+ X_screen = DefaultScreen(X_display);
+ if (!XMatchVisualInfo(X_display, X_screen, 32, TrueColor, &X_visualinfo)) {
+ I_Error("xdoom currently only supports 32bit-color TrueColor screens");
+ }
+ X_visual = X_visualinfo.visual;
+
+ // create the colormap
+ X_cmap = XCreateColormap(X_display, RootWindow(X_display, X_screen), X_visual, AllocNone);
+
+ // setup attributes for main window
+ attribmask = CWEventMask | CWColormap | CWBorderPixel;
+ attribs.event_mask =
+ KeyPressMask
+ | KeyReleaseMask
+ // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
+ | ExposureMask;
+
+ attribs.colormap = X_cmap;
+ attribs.border_pixel = 0;
+
+ // create the main window
+ X_mainWindow = XCreateWindow( X_display,
+ RootWindow(X_display, X_screen),
+ x, y,
+ X_width, X_height,
+ 0, // borderwidth
+ 32, // depth
+ InputOutput,
+ X_visual,
+ attribmask,
+ &attribs );
+
+ // create the GC
+ valuemask = GCGraphicsExposures;
+ xgcvalues.graphics_exposures = False;
+ X_gc = XCreateGC( X_display,
+ X_mainWindow,
+ valuemask,
+ &xgcvalues );
+
+ // map the window
+ XMapWindow(X_display, X_mainWindow);
+
+ // wait until it is OK to draw
+ oktodraw = 0;
+ while (!oktodraw) {
+ XNextEvent(X_display, &X_event);
+ if (X_event.type == Expose
+ && !X_event.xexpose.count)
+ {
+ oktodraw = 1;
+ }
+ }
+
+ image = XCreateImage( X_display,
+ X_visual,
+ 32,
+ ZPixmap,
+ 0,
+ (char*)malloc(X_width * X_height * sizeof(uint32_t)),
+ X_width, X_height,
+ 32,
+ X_width * sizeof(uint32_t) );
+
+
+ screens[0] = (unsigned char *) (image->data);
+}
+
+/*
+===================
+=
+= I_ShutdownGraphics
+=
+===================
+*/
+
+static void I_ShutdownGraphics (void)
+{
+}
+
+/*
+===================
+=
+= I_ReadScreen
+=
+= Reads the screen currently displayed into a linear buffer.
+=
+===================
+*/
+
+void I_ReadScreen (byte *scr)
+{
+ int32_t p, i;
+ for (p = 0; p < 4; p++)
+ {
+ for (i = 0; i < SCREENWIDTH*SCREENHEIGHT/4; i++)
+ scr[i*4+p] = currentscreen[i + (p << 16)];
+ }
+}
+
+
+//===========================================================================
+
+/*
+===================
+=
+= I_StartTic
+=
+// called by D_DoomLoop
+// called before processing each tic in a frame
+// can call D_PostEvent
+// asyncronous interrupt functions should maintain private ques that are
+// read by the syncronous functions to be converted into events
+===================
+*/
+
+/*
+ OLD STARTTIC STUFF
+
+void I_StartTic (void)
+{
+ int32_t k;
+ event_t ev;
+
+
+ I_ReadMouse ();
+
+//
+// keyboard events
+//
+ while (kbdtail < kbdhead)
+ {
+ k = keyboardque[kbdtail&(KBDQUESIZE-1)];
+
+// if (k==14)
+// I_Error ("exited");
+
+ kbdtail++;
+
+ // extended keyboard shift key bullshit
+ if ( (k&0x7f)==KEY_RSHIFT )
+ {
+ if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
+ continue;
+ k &= 0x80;
+ k |= KEY_RSHIFT;
+ }
+
+ if (k==0xe0)
+ continue; // special / pause keys
+ if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1)
+ continue; // pause key bullshit
+
+ if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d)
+ {
+ ev.type = ev_keydown;
+ ev.data1 = KEY_PAUSE;
+ D_PostEvent (&ev);
+ continue;
+ }
+
+ if (k&0x80)
+ ev.type = ev_keyup;
+ else
+ ev.type = ev_keydown;
+ k &= 0x7f;
+
+ ev.data1 = k;
+ //ev.data1 = scantokey[k];
+
+ D_PostEvent (&ev);
+ }
+}
+*/
+
+#define SC_UPARROW 0x48
+#define SC_DOWNARROW 0x50
+#define SC_LEFTARROW 0x4b
+#define SC_RIGHTARROW 0x4d
+
+void I_StartTic (void)
+{
+ int32_t k;
+ event_t ev;
+
+
+ I_ReadMouse ();
+
+//
+// keyboard events
+//
+ while (kbdtail < kbdhead)
+ {
+ k = keyboardque[kbdtail&(KBDQUESIZE-1)];
+ kbdtail++;
+
+ // extended keyboard shift key bullshit
+ if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT )
+ {
+ if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
+ continue;
+ k &= 0x80;
+ k |= SC_RSHIFT;
+ }
+
+ if (k==0xe0)
+ continue; // special / pause keys
+ if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1)
+ continue; // pause key bullshit
+
+ if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d)
+ {
+ ev.type = ev_keydown;
+ ev.data1 = KEY_PAUSE;
+ D_PostEvent (&ev);
+ continue;
+ }
+
+ if (k&0x80)
+ ev.type = ev_keyup;
+ else
+ ev.type = ev_keydown;
+ k &= 0x7f;
+ switch (k)
+ {
+ case SC_UPARROW:
+ ev.data1 = KEY_UPARROW;
+ break;
+ case SC_DOWNARROW:
+ ev.data1 = KEY_DOWNARROW;
+ break;
+ case SC_LEFTARROW:
+ ev.data1 = KEY_LEFTARROW;
+ break;
+ case SC_RIGHTARROW:
+ ev.data1 = KEY_RIGHTARROW;
+ break;
+ default:
+ ev.data1 = scantokey[k];
+ break;
+ }
+ D_PostEvent (&ev);
+ }
+
+}
+
+
+/*
+============================================================================
+
+ TIMER INTERRUPT
+
+============================================================================
+*/
+
+/*
+================
+=
+= I_TimerISR
+=
+================
+*/
+
+void I_TimerISR (void)
+{
+ ticcount++;
+}
+
+/*
+============================================================================
+
+ KEYBOARD
+
+============================================================================
+*/
+
+static byte lastpress;
+
+/*
+===============
+=
+= I_StartupKeyboard
+=
+===============
+*/
+
+static boolean isKeyboardIsrSet = false;
+
+static void I_StartupKeyboard (void)
+{
+}
+
+
+static void I_ShutdownKeyboard (void)
+{
+}
+
+
+
+/*
+============================================================================
+
+ MOUSE
+
+============================================================================
+*/
+
+
+static boolean I_ResetMouse (void)
+{
+ return false;
+}
+
+
+
+/*
+================
+=
+= StartupMouse
+=
+================
+*/
+
+static void I_StartupMouse (void)
+{
+ //
+ // General mouse detection
+ //
+ mousepresent = false;
+ if ( M_CheckParm ("-nomouse") || !usemouse )
+ return;
+
+ if (I_ResetMouse ())
+ {
+ mousepresent = true;
+ printf("Mouse: detected\n");
+ } else
+ printf("Mouse: not present\n");
+}
+
+
+/*
+================
+=
+= ShutdownMouse
+=
+================
+*/
+
+static void I_ShutdownMouse (void)
+{
+ if (!mousepresent)
+ return;
+
+ I_ResetMouse ();
+}
+
+
+/*
+================
+=
+= I_ReadMouse
+=
+================
+*/
+
+static void I_ReadMouse (void)
+{
+ event_t ev;
+
+//
+// mouse events
+//
+ if (!mousepresent)
+ return;
+
+}
+
+/*
+============================================================================
+
+ JOYSTICK
+
+============================================================================
+*/
+
+static int32_t joyxl, joyxh, joyyl, joyyh;
+
+static boolean WaitJoyButton (void)
+{
+
+ return false;
+}
+
+
+
+/*
+===============
+=
+= I_StartupJoystick
+=
+===============
+*/
+
+static void I_StartupJoystick (void)
+{
+ int32_t centerx, centery;
+
+ joystickpresent = 0;
+ if ( M_CheckParm ("-nojoy") || !usejoystick )
+ return;
+
+ if (!I_ReadJoystick ())
+ {
+ joystickpresent = false;
+ printf ("joystick not found\n");
+ return;
+ }
+ printf ("joystick found\n");
+ joystickpresent = true;
+
+ printf ("CENTER the joystick and press button 1:");
+ if (!WaitJoyButton ())
+ return;
+ I_ReadJoystick ();
+ centerx = joystickx;
+ centery = joysticky;
+
+ printf ("\nPush the joystick to the UPPER LEFT corner and press button 1:");
+ if (!WaitJoyButton ())
+ return;
+ I_ReadJoystick ();
+ joyxl = (centerx + joystickx)/2;
+ joyyl = (centerx + joysticky)/2;
+
+ printf ("\nPush the joystick to the LOWER RIGHT corner and press button 1:");
+ if (!WaitJoyButton ())
+ return;
+ I_ReadJoystick ();
+ joyxh = (centerx + joystickx)/2;
+ joyyh = (centery + joysticky)/2;
+ printf ("\n");
+}
+
+/*
+===============
+=
+= I_StartFrame
+=
+===============
+*/
+
+void I_StartFrame (void)
+{
+ event_t ev;
+
+//
+// joystick events
+//
+ return;
+}
+
+
+
+/*
+============================================================================
+
+ DPMI STUFF
+
+============================================================================
+*/
+
+#if defined __WATCOMC__
+#define REALSTACKSIZE 1024
+
+static uint32_t realstackseg;
+#endif
+
+static void DPMIInt (int32_t i)
+{
+#if defined __DJGPP__
+ __dpmi_regs dpmiregs;
+
+ __dpmi_int(i, &dpmiregs);
+#elif defined __CCDL__
+ DPMI_REGS dpmiregs;
+
+ dpmi_simulate_real_interrupt(i, &dpmiregs);
+#elif defined __WATCOMC__
+ __dpmi_regs dpmiregs;
+ struct SREGS segregs;
+
+ dpmiregs.x.ss = realstackseg;
+ dpmiregs.x.sp = REALSTACKSIZE-4;
+
+ segread (&segregs);
+ regs.w.ax = 0x300;
+ regs.w.bx = i;
+ regs.w.cx = 0;
+ regs.x.edi = (uint32_t)&dpmiregs;
+ segregs.es = segregs.ds;
+ int386x( DPMI_INT, ®s, ®s, &segregs );
+#else
+ I_Error("TODO implement DPMIInt()");
+#endif
+}
+
+
+/*
+=============
+=
+= I_AllocLow
+=
+=============
+*/
+#if defined __WATCOMC__
+static byte *I_AllocLow (int32_t length)
+{
+ byte *mem;
+
+ // DPMI call 100h allocates DOS memory
+ regs.w.ax = 0x0100; // DPMI allocate DOS memory
+ regs.w.bx = (length+15) / 16;
+ int386( DPMI_INT, ®s, ®s);
+ if (regs.w.cflag != 0)
+ I_Error ("I_AllocLow: DOS alloc of %i failed, %i free",
+ length, regs.w.bx*16);
+
+
+ mem = (void *) ((regs.x.eax & 0xFFFF) << 4);
+
+ memset (mem,0,length);
+ return mem;
+}
+#endif
+
+
+/*
+==============
+=
+= I_StartupDPMI
+=
+==============
+*/
+
+static void I_StartupDPMI (void)
+{
+#if defined __DJGPP__
+ __djgpp_nearptr_enable();
+#elif defined __WATCOMC__
+//
+// allocate a decent stack for real mode ISRs
+//
+ realstackseg = (int32_t)I_AllocLow (REALSTACKSIZE) >> 4;
+#endif
+}
+
+
+
+//===========================================================================
+
+
+/*
+===============
+=
+= I_Init
+=
+= hook interrupts and set graphics mode
+=
+===============
+*/
+
+void I_Init (void)
+{
+ int32_t i;
+
+ novideo = M_CheckParm("novideo");
+ i = M_CheckParm("-control");
+ if (i)
+ {
+ doomcon = (doomcontrol_t*)atoi(myargv[i+1]);
+ printf("Using external control API\n");
+ }
+ printf ("I_StartupDPMI\n");
+ I_StartupDPMI ();
+ printf ("I_StartupMouse\n");
+ I_StartupMouse ();
+ printf ("I_StartupJoystick\n");
+ I_StartupJoystick ();
+ printf ("I_StartupKeyboard\n");
+ I_StartupKeyboard ();
+ printf ("I_StartupSound\n");
+ I_StartupSound ();
+}
+
+
+/*
+===============
+=
+= I_Shutdown
+=
+= return to default system state
+=
+===============
+*/
+
+static void I_Shutdown (void)
+{
+ I_ShutdownGraphics ();
+ I_ShutdownSound ();
+ I_ShutdownTimer ();
+ I_ShutdownMouse ();
+ I_ShutdownKeyboard ();
+}
+
+
+/*
+================
+=
+= I_Error
+=
+================
+*/
+
+void I_Error (char *error, ...)
+{
+ va_list argptr;
+#ifdef __DJGPP__
+
+ D_QuitNetGame ();
+ I_Shutdown ();
+#endif
+ va_start (argptr,error);
+ vprintf (error,argptr);
+ va_end (argptr);
+ printf ("\n");
+ exit (1);
+}
+
+/*
+===============
+=
+= I_Quit
+=
+= Shuts down net game, saves defaults, prints the exit text message,
+= goes to text mode, and exits.
+=
+===============
+*/
+
+void I_Quit (void)
+{
+ byte *scr;
+
+ if (demorecording)
+ G_CheckDemoStatus ();
+ else
+ D_QuitNetGame ();
+ M_SaveDefaults ();
+ scr = (byte *)W_CacheLumpName ("ENDOOM", PU_CACHE);
+ I_Shutdown ();
+ printf ("\n");
+ exit (0);
+}
+
+/*
+===============
+=
+= I_ZoneBase
+=
+===============
+*/
+
+#if defined __DJGPP__
+// nothing
+#elif defined __DMC__
+#define _go32_dpmi_remaining_physical_memory _memmax
+#elif defined __CCDL__
+static int32_t _go32_dpmi_remaining_physical_memory(void)
+{
+ DPMI_FREEMEM_INFO meminfo;
+
+ // There's a push/pop bug in CC386's dpmi_get_memory_info(), so we'll do it ourselves instead.
+ DPMI_FREEMEM_INFO *ptrmeminfo = &meminfo;
+ asm
+ {
+ mov edi, [ptrmeminfo]
+ mov eax, 0x500
+ int 0x31
+ }
+
+ return meminfo.largest_block;
+}
+#elif defined __WATCOMC__
+static int32_t _go32_dpmi_remaining_physical_memory(void)
+{
+ struct SREGS segregs;
+ __dpmi_free_mem_info meminfo;
+
+ regs.w.ax = 0x500; // get memory info
+ memset (&segregs,0,sizeof(segregs));
+ segregs.es = FP_SEG(&meminfo);
+ regs.x.edi = FP_OFF(&meminfo);
+ int386x( DPMI_INT, ®s, ®s, &segregs );
+ return meminfo.largest_available_free_block_in_bytes;
+}
+#else
+static int32_t _go32_dpmi_remaining_physical_memory(void)
+{
+ //TODO implement _go32_dpmi_remaining_physical_memory()
+ return 0x800000 + 0x20000;
+}
+#endif
+
+byte *I_ZoneBase (int32_t *size)
+{
+ int32_t heap;
+ byte *ptr;
+
+ heap = _go32_dpmi_remaining_physical_memory();
+ printf ("DPMI memory: %d kB", heap >> 10);
+
+ do
+ {
+ heap -= 0x20000; // leave 64k alone
+ if (heap > 0x800000)
+ heap = 0x800000;
+ ptr = malloc (heap);
+ } while (!ptr);
+
+ printf (", %d kB allocated for zone\n", heap >> 10);
+ if (heap < 0x180000)
+ {
+ printf ("\n");
+ printf ("Insufficient memory! You need to have at least 3.7 megabytes of total\n");
+#if APPVER_CHEX
+ printf ("free memory available for Chex(R) Quest. Reconfigure your CONFIG.SYS\n");
+ printf ("or AUTOEXEC.BAT to load fewer device drivers or TSR's. We recommend\n");
+ printf ("creating a custom boot menu item in your CONFIG.SYS for optimum play.\n");
+ printf ("Please consult your DOS manual (\"Making more memory available\") for\n");
+ printf ("information on how to free up more memory for Chex(R) Quest.\n\n");
+ printf ("Chex(R) Quest aborted.\n");
+ exit (1);
+#else
+ printf ("free memory available for DOOM to execute. Reconfigure your CONFIG.SYS\n");
+ printf ("or AUTOEXEC.BAT to load fewer device drivers or TSR's. We recommend\n");
+ printf ("creating a custom boot menu item in your CONFIG.SYS for optimum DOOMing.\n");
+ printf ("Please consult your DOS manual (\"Making more memory available\") for\n");
+ printf ("information on how to free up more memory for DOOM.\n\n");
+#if (APPVER_DOOMREV < AV_DR_DM1666E)
+ I_Error ("DOOM aborted.");
+#else
+ printf ("DOOM aborted.\n");
+ exit (1);
+#endif
+#endif // APPVER_CHEX
+ }
+
+ *size = heap;
+ return ptr;
+}
+
+/*
+=============================================================================
+
+ DISK ICON FLASHING
+
+=============================================================================
+*/
+
+static void I_InitDiskFlash (void)
+{
+ void *pic;
+ byte *temp;
+
+ if (M_CheckParm ("-cdrom"))
+ pic = W_CacheLumpName ("STCDROM",PU_CACHE);
+ else
+ pic = W_CacheLumpName ("STDISK",PU_CACHE);
+ temp = destscreen;
+ destscreen = screen + 0xc000;
+ V_DrawPatchDirect (SCREENWIDTH-16,SCREENHEIGHT-16,pic);
+ destscreen = temp;
+}
+
+// draw disk icon
+void I_BeginRead (void)
+{
+ byte *src,*dest;
+ int32_t y;
+
+ if (!grmode)
+ return;
+
+ // copy to backup
+ for (int i = 0; i < 4; i++) {
+ src = currentscreen + 184*PLANEWIDTH + 304/4 + (i << 16);
+ dest = screen + 0xc000 + 184*PLANEWIDTH + 288/4 + (i << 16);
+ for (y=0 ; y<16 ; y++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = src[3];
+ src += PLANEWIDTH;
+ dest += PLANEWIDTH;
+ }
+
+ // copy disk over
+ dest = currentscreen + 184*PLANEWIDTH + 304/4;
+ src = screen + 0xc000 + 184*PLANEWIDTH + 304/4;
+ for (y=0 ; y<16 ; y++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = src[3];
+ src += PLANEWIDTH;
+ dest += PLANEWIDTH;
+ }
+ }
+}
+
+// erase disk icon
+void I_EndRead (void)
+{
+ byte *src,*dest;
+ int32_t y;
+
+ if (!grmode)
+ return;
+
+ for (int i = 0; i < 4; i++) {
+ // copy disk over
+ dest = currentscreen + 184*PLANEWIDTH + 304/4 + (i << 16);
+ src = screen + 0xc000 + 184*PLANEWIDTH + 288/4 + (i << 16);
+ for (y=0 ; y<16 ; y++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = src[3];
+ src += PLANEWIDTH;
+ dest += PLANEWIDTH;
+ }
+ }
+}
+
+
+
+/*
+============================================================================
+
+ NETWORKING
+
+============================================================================
+*/
+
+/* // FUCKED LINES
+typedef struct
+{
+ char priv[508];
+} doomdata_t;
+*/ // FUCKED LINES
+
+#define DOOMCOM_ID 0x12345678l
+
+/* // FUCKED LINES
+typedef struct
+{
+ int32_t id;
+ int16_t intnum; // DOOM executes an int to execute commands
+
+// communication between DOOM and the driver
+ int16_t command; // CMD_SEND or CMD_GET
+ int16_t remotenode; // dest for send, set by get (-1 = no packet)
+ int16_t datalength; // bytes in doomdata to be sent
+
+// info common to all nodes
+ int16_t numnodes; // console is allways node 0
+ int16_t ticdup; // 1 = no duplication, 2-5 = dup for slow nets
+ int16_t extratics; // 1 = send a backup tic in every packet
+ int16_t deathmatch; // 1 = deathmatch
+ int16_t savegame; // -1 = new game, 0-5 = load savegame
+ int16_t episode; // 1-3
+ int16_t map; // 1-9
+ int16_t skill; // 1-5
+
+// info specific to this node
+ int16_t consoleplayer;
+ int16_t numplayers;
+ int16_t angleoffset; // 1 = left, 0 = center, -1 = right
+ int16_t drone; // 1 = drone
+
+// packet data to be sent
+ doomdata_t data;
+} doomcom_t;
+*/ // FUCKED LINES
+
+extern doomcom_t *doomcom;
+
+/*
+====================
+=
+= I_InitNetwork
+=
+====================
+*/
+
+void I_InitNetwork (void)
+{
+ int32_t i;
+
+ i = M_CheckParm ("-net");
+ if (!i)
+ {
+ //
+ // single player game
+ //
+ doomcom = malloc (sizeof (*doomcom) );
+ if (!doomcom)
+ I_Error("malloc() in I_InitNetwork() failed");
+ memset (doomcom, 0, sizeof(*doomcom) );
+ netgame = false;
+ doomcom->id = DOOMCOM_ID;
+ doomcom->numplayers = doomcom->numnodes = 1;
+ doomcom->deathmatch = false;
+ doomcom->consoleplayer = 0;
+ doomcom->ticdup = 1;
+ doomcom->extratics = 0;
+ return;
+ }
+
+ netgame = true;
+ doomcom = (doomcom_t *)atoi(myargv[i+1]);
+//DEBUG
+doomcom->skill = startskill;
+doomcom->episode = startepisode;
+doomcom->map = startmap;
+doomcom->deathmatch = deathmatch;
+
+}
+
+void I_NetCmd (void)
+{
+ if (!netgame)
+ I_Error ("I_NetCmd when not in netgame");
+ DPMIInt (doomcom->intnum);
+}
diff --git a/src/linux/i_sound.c b/src/linux/i_sound.c
new file mode 100644
index 0000000..48724fc
--- /dev/null
+++ b/src/linux/i_sound.c
@@ -0,0 +1,401 @@
+//
+// Copyright (C) 1993-1996 Id Software, Inc.
+// Copyright (C) 2023 Frenkel Smeijers
+//
+// 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, see .
+//
+
+// I_SOUND.C
+
+#include "../doomdef.h"
+#include "../dmx.h"
+#include "../sounds.h"
+
+#define SND_TICRATE 140 // tic rate for updating sound
+#define SND_MAXSONGS 40 // max number of songs in game
+#define SND_SAMPLERATE 11025 // sample rate of sound effects
+
+/*
+===============
+=
+= I_StartupTimer
+=
+===============
+*/
+
+static int32_t tsm_ID;
+
+static void I_StartupTimer (void)
+{
+ extern void I_InitBaseTime(void);
+ extern void I_TimerISR(void);
+
+ printf("I_StartupTimer()\n");
+
+ I_InitBaseTime();
+}
+
+void I_ShutdownTimer (void)
+{
+}
+
+/*
+ *
+ * SOUND HEADER & DATA
+ *
+ *
+ */
+
+// sound information
+#if (APPVER_DOOMREV < AV_DR_DM18)
+static const char snd_prefixen[] = { 'P', 'P', 'A', 'S', 'S', 'S', 'M',
+ 'M', 'M', 'S'};
+#else
+static const char snd_prefixen[] = { 'P', 'P', 'A', 'S', 'S', 'S', 'M',
+ 'M', 'M', 'S', 'S', 'S'};
+#endif
+
+typedef enum
+{
+ snd_none, // NO MUSIC / NO SOUND FX
+ snd_PC, // PC Speaker
+ snd_Adlib, // Adlib
+ snd_SB, // Sound Blaster
+ snd_PAS, // Pro Audio Spectrum
+ snd_GUS, // Gravis UltraSound
+ snd_MPU, // WaveBlaster
+ snd_MPU2, // Sound Canvas
+ snd_MPU3, // General MIDI
+ snd_AWE, // Sound Blaster AWE32
+#if (APPVER_DOOMREV >= AV_DR_DM18)
+ snd_ENS,
+ snd_CODEC,
+#endif
+ NUM_SCARDS
+} cardenum_t;
+
+int32_t snd_DesiredMusicDevice, snd_DesiredSfxDevice;
+static int32_t snd_MusicDevice; // current music card # (index to dmxCodes)
+static int32_t snd_SfxDevice; // current sfx card # (index to dmxCodes)
+static int32_t snd_MusicVolume; // maximum volume for music
+static int32_t dmxCodes[NUM_SCARDS]; // the dmx code for a given card
+
+int32_t snd_SBport, snd_SBirq, snd_SBdma; // sound blaster variables
+int32_t snd_Mport; // midi variables
+
+void I_PauseSong(int32_t handle)
+{
+ MUS_PauseSong(handle);
+}
+
+void I_ResumeSong(int32_t handle)
+{
+ MUS_ResumeSong(handle);
+}
+
+void I_SetMusicVolume(int32_t volume)
+{
+ MUS_SetMasterVolume(volume);
+ snd_MusicVolume = volume;
+}
+
+/*
+ *
+ * SONG API
+ *
+ */
+
+int32_t I_RegisterSong(void *data)
+{
+ return MUS_RegisterSong(data);
+}
+
+void I_UnRegisterSong(int32_t handle)
+{
+ MUS_UnregisterSong(handle);
+}
+
+// Stops a song. MUST be called before I_UnregisterSong().
+
+void I_StopSong(int32_t handle)
+{
+ MUS_StopSong(handle);
+
+ // Fucking kluge pause
+ {
+ int32_t s = I_GetTime();
+ while (I_GetTime() - s < 10)
+ {
+ }
+ }
+}
+
+void I_PlaySong(int32_t handle, boolean looping)
+{
+ MUS_ChainSong(handle, looping ? handle : -1);
+ MUS_PlaySong(handle, snd_MusicVolume);
+}
+
+/*
+ *
+ * SOUND FX API
+ *
+ */
+
+// Gets lump nums of the named sound. Returns pointer which will be
+// passed to I_StartSound() when you want to start an SFX. Must be
+// sure to pass this to UngetSoundEffect() so that they can be
+// freed!
+
+
+int32_t I_GetSfxLumpNum(sfxinfo_t *sound)
+{
+ char namebuf[9];
+
+ if (sound->link) sound = sound->link;
+ sprintf(namebuf, "d%c%s", snd_prefixen[snd_SfxDevice], sound->name);
+ return W_GetNumForName(namebuf);
+
+}
+
+int32_t I_StartSound (void *data, int32_t vol, int32_t sep, int32_t pitch)
+{
+ // hacks out certain PC sounds
+ if (snd_SfxDevice == snd_PC
+ && (data == S_sfx[sfx_posact].data
+ || data == S_sfx[sfx_bgact].data
+ || data == S_sfx[sfx_dmact].data
+ || data == S_sfx[sfx_dmpain].data
+ || data == S_sfx[sfx_popain].data
+ || data == S_sfx[sfx_sawidl].data)) return -1;
+
+ else
+ return SFX_PlayPatch(data, sep, pitch, vol, 0, 100);
+
+}
+
+void I_StopSound(int32_t handle)
+{
+ SFX_StopPatch(handle);
+}
+
+boolean I_SoundIsPlaying(int32_t handle)
+{
+ return SFX_Playing(handle) != 0;
+}
+
+void I_UpdateSoundParams(int32_t handle, int32_t vol, int32_t sep, int32_t pitch)
+{
+ SFX_SetOrigin(handle, pitch, sep, vol);
+}
+
+/*
+ *
+ * SOUND STARTUP STUFF
+ *
+ *
+ */
+
+//
+// Why PC's Suck, Reason #8712
+//
+
+static void I_sndArbitrateCards(void)
+{
+ // boolean gus, adlib, pc, sb, midi, ensoniq, codec;
+#if (APPVER_DOOMREV < AV_DR_DM18)
+ boolean gus, adlib, sb, midi;
+#else
+ boolean codec, ensoniq, gus, adlib, sb, midi;
+#endif
+ int32_t cardType, wait, dmxlump;
+
+ snd_MusicDevice = snd_DesiredMusicDevice;
+ snd_SfxDevice = snd_DesiredSfxDevice;
+
+ // check command-line parameters- overrides config file
+ //
+ if (M_CheckParm("-nosound")) snd_MusicDevice = snd_SfxDevice = snd_none;
+ if (M_CheckParm("-nosfx")) snd_SfxDevice = snd_none;
+ if (M_CheckParm("-nomusic")) snd_MusicDevice = snd_none;
+
+ if (snd_MusicDevice == snd_MPU2 || snd_MusicDevice == snd_MPU3)
+ snd_MusicDevice = snd_MPU;
+ else if (snd_MusicDevice == snd_SB || snd_MusicDevice == snd_PAS)
+ snd_MusicDevice = snd_Adlib;
+
+ // figure out what i've got to initialize
+ //
+ gus = snd_MusicDevice == snd_GUS || snd_SfxDevice == snd_GUS;
+ sb = snd_SfxDevice == snd_SB;
+#if (APPVER_DOOMREV >= AV_DR_DM18)
+ ensoniq = snd_SfxDevice == snd_ENS ;
+ codec = snd_SfxDevice == snd_CODEC ;
+#endif
+ adlib = snd_MusicDevice == snd_Adlib ;
+ midi = snd_MusicDevice == snd_MPU;
+
+#if (APPVER_DOOMREV >= AV_DR_DM18)
+ // initialize whatever i've got
+ //
+ if (ensoniq)
+ {
+ if (devparm)
+ printf("ENSONIQ\n");
+ if (ENS_Detect())
+ printf("Dude. The ENSONIQ ain't responding.\n");
+ }
+ if (codec)
+ {
+ if (devparm)
+ printf("CODEC p=0x%x, d=%d\n", snd_SBport, snd_SBdma);
+ if (CODEC_Detect(&snd_SBport, &snd_SBdma))
+ printf("CODEC. The CODEC ain't responding.\n");
+ }
+#endif
+ if (gus)
+ {
+ if (devparm)
+ printf("GUS\n");
+ fprintf(stderr, "GUS1\n");
+ if (GF1_Detect()) printf("Dude. The GUS ain't responding.\n");
+ else
+ {
+ fprintf(stderr, "GUS2\n");
+ if (commercial)
+ dmxlump = W_GetNumForName("dmxgusc");
+ else
+ dmxlump = W_GetNumForName("dmxgus");
+ GF1_SetMap(W_CacheLumpNum(dmxlump, PU_CACHE), lumpinfo[dmxlump].size);
+ }
+
+ }
+ if (sb)
+ {
+ if(devparm)
+ {
+ printf("cfg p=0x%x, i=%d, d=%d\n",
+ snd_SBport, snd_SBirq, snd_SBdma);
+ }
+ if (SB_Detect(&snd_SBport, &snd_SBirq, &snd_SBdma, 0))
+ {
+ printf("SB isn't responding at p=0x%x, i=%d, d=%d\n",
+ snd_SBport, snd_SBirq, snd_SBdma);
+ }
+ else SB_SetCard(snd_SBport, snd_SBirq, snd_SBdma);
+
+ if(devparm)
+ {
+ printf("SB_Detect returned p=0x%x,i=%d,d=%d\n",
+ snd_SBport, snd_SBirq, snd_SBdma);
+ }
+ }
+
+ if (adlib)
+ {
+ if(devparm)
+ printf("Adlib\n");
+ if (AL_Detect(&wait,0))
+ printf("Dude. The Adlib isn't responding.\n");
+ else
+ AL_SetCard(wait, W_CacheLumpName("genmidi", PU_STATIC));
+ }
+
+ if (midi)
+ {
+ if (devparm)
+ printf("Midi\n");
+ if (devparm)
+ printf("cfg p=0x%x\n", snd_Mport);
+
+ if (MPU_Detect(&snd_Mport, &cardType))
+ printf("The MPU-401 isn't reponding @ p=0x%x.\n", snd_Mport);
+ else MPU_SetCard(snd_Mport);
+ }
+
+}
+
+boolean I_IsAdlib(void)
+{
+ return snd_MusicDevice == snd_Adlib;
+}
+
+// inits all sound stuff
+
+void I_StartupSound (void)
+{
+ int32_t rc;
+
+ if (devparm)
+ printf("I_StartupSound: Hope you hear a pop.\n");
+
+ // initialize dmxCodes[]
+ dmxCodes[snd_none] = AHW_NONE;
+ dmxCodes[snd_PC] = AHW_PC_SPEAKER;
+ dmxCodes[snd_Adlib] = AHW_ADLIB;
+ dmxCodes[snd_SB] = AHW_SOUND_BLASTER;
+ dmxCodes[snd_PAS] = AHW_MEDIA_VISION;
+ dmxCodes[snd_GUS] = AHW_ULTRA_SOUND;
+ dmxCodes[snd_MPU] = AHW_MPU_401;
+ dmxCodes[snd_AWE] = AHW_AWE32;
+#if (APPVER_DOOMREV >= AV_DR_DM18)
+ dmxCodes[snd_ENS] = AHW_ENSONIQ;
+ dmxCodes[snd_CODEC] = AHW_CODEC;
+#endif
+
+ // inits sound library timer stuff
+ I_StartupTimer();
+
+ // pick the sound cards i'm going to use
+ //
+ I_sndArbitrateCards();
+
+ if (devparm)
+ {
+ printf(" Music device #%d & dmxCode=%d\n", snd_MusicDevice,
+ dmxCodes[snd_MusicDevice]);
+ printf(" Sfx device #%d & dmxCode=%d\n", snd_SfxDevice,
+ dmxCodes[snd_SfxDevice]);
+ }
+
+ // inits DMX sound library
+ printf(" calling DMX_Init\n");
+ rc = DMX_Init(SND_TICRATE, SND_MAXSONGS, dmxCodes[snd_MusicDevice],
+ dmxCodes[snd_SfxDevice]);
+
+ if (devparm)
+ printf(" DMX_Init() returned %d\n", rc);
+
+}
+
+// shuts down all sound stuff
+
+void I_ShutdownSound (void)
+{
+ S_PauseSound();
+
+ {
+ int32_t s = I_GetTime();
+ while (I_GetTime() - s < 30)
+ {
+ }
+ }
+
+ DMX_DeInit();
+}
+
+void I_SetChannels(int32_t channels)
+{
+ WAV_PlayMode(channels, SND_SAMPLERATE);
+}
diff --git a/m_menu.c b/src/m_menu.c
similarity index 99%
rename from m_menu.c
rename to src/m_menu.c
index 040b751..826de76 100644
--- a/m_menu.c
+++ b/src/m_menu.c
@@ -20,7 +20,6 @@
#include
#include
-#include
#include
#include "doomdef.h"
#include "r_local.h"
diff --git a/m_misc.c b/src/m_misc.c
similarity index 99%
rename from m_misc.c
rename to src/m_misc.c
index d7eaf81..c6a37c9 100644
--- a/m_misc.c
+++ b/src/m_misc.c
@@ -21,7 +21,6 @@
#include
#include
#include
-#include
#include "doomdef.h"
#include "hu_stuff.h"
#include "soundst.h"
@@ -47,7 +46,7 @@ int32_t M_CheckParm (char *check)
for (i = 1;i
+
#include "doomdef.h"
#include "p_local.h"
@@ -649,8 +651,11 @@ static void P_RunThinkers (void)
thinker_t *currentthinker;
currentthinker = thinkercap.next;
+ assert(((uint32_t)currentthinker & 3) == 0);
while (currentthinker != &thinkercap)
{
+ assert(((uint32_t)currentthinker & 3) == 0);
+ thinker_t *nextthinker = currentthinker->next;
if (currentthinker->function == (think_t)-1)
{ // time to remove it
currentthinker->next->prev = currentthinker->prev;
@@ -662,7 +667,7 @@ static void P_RunThinkers (void)
if (currentthinker->function)
currentthinker->function (currentthinker);
}
- currentthinker = currentthinker->next;
+ currentthinker = nextthinker;
}
}
diff --git a/p_user.c b/src/p_user.c
similarity index 100%
rename from p_user.c
rename to src/p_user.c
diff --git a/src/planar.asm b/src/planar.asm
new file mode 100644
index 0000000..ea4f21c
--- /dev/null
+++ b/src/planar.asm
@@ -0,0 +1,82 @@
+;
+; Copyright (C) 1993-1996 Id Software, Inc.
+; Copyright (C) 2023 Frenkel Smeijers
+;
+; 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, see .
+;
+
+cpu 386
+
+PLANEWIDTH equ 80
+
+%ifidn __OUTPUT_FORMAT__,elf
+section .note.GNU-stack noalloc noexec nowrite progbits
+%endif
+
+section .data
+
+extern _loop_count
+
+%ifidn __OUTPUT_FORMAT__,elf
+section .text
+%endif
+%ifidn __OUTPUT_FORMAT__, coff
+section .text public class=CODE USE32
+%elifidn __OUTPUT_FORMAT__, obj
+section _TEXT public class=CODE USE32
+%endif
+
+global _R_ScaleColumnAsm
+_R_ScaleColumnAsm:
+ add edi, PLANEWIDTH * 32
+%assign ROW 32
+%rep 32 / 2
+ lea ecx, [edx + ebx]
+ shr edx, 25
+ mov al, [esi + edx]
+ mov al, [eax]
+ mov [edi - PLANEWIDTH * ROW], al
+ lea edx, [ecx + ebx]
+ shr ecx, 25
+ mov al, [esi + ecx]
+ mov al, [eax]
+ mov [edi - PLANEWIDTH * ROW + PLANEWIDTH], al
+ %assign ROW ROW - 2
+ %endrep
+ dec dword [_loop_count]
+ jns _R_ScaleColumnAsm
+ ret
+
+global _R_ScaleRowAsm
+_R_ScaleRowAsm:
+ add edi, 32
+%assign COL 32
+%rep 32 / 2
+ lea ecx, [edx + ebx]
+ shr edx, 26
+ shld dx, cx, 6
+ mov al, [esi + edx]
+ mov al, [eax]
+ mov [edi - COL], al
+ lea edx, [ecx + ebx]
+ shr ecx, 26
+ shld cx, dx, 6
+ mov al, [esi + ecx]
+ mov al, [eax]
+ mov [edi - COL + 1], al
+ %assign COL COL - 2
+ %endrep
+ dec dword [_loop_count]
+ jns _R_ScaleRowAsm
+ ret
diff --git a/r_bsp.c b/src/r_bsp.c
similarity index 100%
rename from r_bsp.c
rename to src/r_bsp.c
diff --git a/r_data.c b/src/r_data.c
similarity index 99%
rename from r_data.c
rename to src/r_data.c
index 8de5611..2a37b1e 100644
--- a/r_data.c
+++ b/src/r_data.c
@@ -557,7 +557,7 @@ int32_t R_CheckTextureNumForName (char *name)
return 0;
for (i=0 ; iname, name, 8) )
+ if (!strncasecmp (textures[i]->name, name, 8) )
return i;
return -1;
diff --git a/r_draw.c b/src/r_draw.c
similarity index 79%
rename from r_draw.c
rename to src/r_draw.c
index f82cc23..24d1e45 100644
--- a/r_draw.c
+++ b/src/r_draw.c
@@ -20,8 +20,6 @@
// R_draw.c
-#include
-#include
#include "doomdef.h"
#include "r_local.h"
@@ -50,7 +48,7 @@ int32_t viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
==================
*/
-lighttable_t *dc_colormap __attribute__ ((externally_visible));
+lighttable_t *dc_colormap;
int32_t dc_x __attribute__ ((externally_visible));
int32_t dc_yl __attribute__ ((externally_visible));
int32_t dc_yh __attribute__ ((externally_visible));
@@ -58,12 +56,17 @@ fixed_t dc_iscale __attribute__ ((externally_visible));
fixed_t dc_texturemid __attribute__ ((externally_visible));
byte *dc_source __attribute__ ((externally_visible)); // first pixel in a column (possibly virtual)
-#if defined C_ONLY
+extern void R_ScaleColumnAsm() asm ("_R_ScaleColumnAsm");
+extern void R_ScaleRowAsm() asm("_R_ScaleRowAsm");
+
+void* call_dest asm("_call_dest");
+int32_t loop_count asm("_loop_count");
+
void R_DrawColumn (void)
{
int32_t count;
byte *dest;
- fixed_t frac, fracstep;
+ uint32_t frac, frac2, fracstep;
count = dc_yh - dc_yl;
if (count < 0)
@@ -74,22 +77,27 @@ void R_DrawColumn (void)
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
#endif
+#ifdef __DJGPP__
outp (SC_INDEX+1,1<<(dc_x&3));
- dest = destview + dc_yl*PLANEWIDTH + (dc_x>>2);
+ dest = destview + (dc_yl + (count & 31) + 1)*PLANEWIDTH + (dc_x>>2);
+#else
+ dest = destview + (dc_yl + (count & 31) + 1)*PLANEWIDTH + (dc_x>>2) + ((dc_x & 3) << 16);
+#endif
- fracstep = dc_iscale;
- frac = dc_texturemid + (dc_yl-centery)*fracstep;
-
- do
- {
- *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
- dest += PLANEWIDTH;
- frac += fracstep;
- } while (count--);
+ fracstep = dc_iscale << 9;
+ frac = frac2 = (dc_texturemid << 9) + (dc_yl-centery)*fracstep;
+
+ loop_count = count >> 5;
+ // add edi, 32 * 80 // 6 bytes
+ // 32 unrolled 17 byte sequence
+ call_dest = (char*)R_ScaleColumnAsm + 6 + 32 * 17 - 17 * ((count & 31) + 1);
+ lighttable_t *colormap = dc_colormap;
+ asm volatile("call *(_call_dest)": "+a"(colormap), "+c"(frac), "+d"(frac2): "D"(dest), "S"(dc_source), "b"(fracstep) : "memory");
}
void R_DrawColumnLow (void)
{
+#ifdef __DJGPP__
int32_t count;
byte *dest;
fixed_t frac, fracstep;
@@ -118,8 +126,8 @@ void R_DrawColumnLow (void)
dest += PLANEWIDTH;
frac += fracstep;
} while (count--);
-}
#endif
+}
#define FUZZTABLE 50
@@ -149,6 +157,7 @@ void R_DrawFuzzColumn (void)
I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
#endif
+#ifdef __DJGPP__
if (detailshift)
{
if (dc_x & 1)
@@ -169,6 +178,9 @@ void R_DrawFuzzColumn (void)
outp (SC_INDEX+1,1<<(dc_x&3));
dest = destview + dc_yl*PLANEWIDTH + (dc_x>>2);
}
+#else
+ dest = destview + dc_yl*PLANEWIDTH + (dc_x>>2) + ((dc_x & 3) << 16);
+#endif
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
@@ -210,6 +222,7 @@ void R_DrawTranslatedColumn (void)
I_Error ("R_DrawTranslatedColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
#endif
+#ifdef __DJGPP__
if (detailshift)
{
if (dc_x & 1)
@@ -224,6 +237,9 @@ void R_DrawTranslatedColumn (void)
outp (SC_INDEX+1,1<<(dc_x&3));
dest = destview + dc_yl*PLANEWIDTH + (dc_x>>2);
}
+#else
+ dest = destview + dc_yl*PLANEWIDTH + (dc_x>>2) + ((dc_x & 3) << 16);
+#endif
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
@@ -278,28 +294,24 @@ void R_InitTranslationTables (void)
================
*/
-int32_t ds_y __attribute__ ((externally_visible));
-int32_t ds_x1 __attribute__ ((externally_visible));
-int32_t ds_x2 __attribute__ ((externally_visible));
-lighttable_t *ds_colormap __attribute__ ((externally_visible));
-fixed_t ds_xfrac __attribute__ ((externally_visible));
-fixed_t ds_yfrac __attribute__ ((externally_visible));
-fixed_t ds_xstep __attribute__ ((externally_visible));
-fixed_t ds_ystep __attribute__ ((externally_visible));
-byte *ds_source __attribute__ ((externally_visible)); // start of a 64*64 tile image
-
-#if defined C_ONLY
+int32_t ds_y;
+int32_t ds_x1;
+int32_t ds_x2;
+lighttable_t *ds_colormap;
+fixed_t ds_xfrac;
+fixed_t ds_yfrac;
+fixed_t ds_xstep;
+fixed_t ds_ystep;
+byte *ds_source; // start of a 64*64 tile image
+
void R_DrawSpan (void)
{
- fixed_t xfrac;
- fixed_t yfrac;
+ fixed_t frac;
+ fixed_t dfrac;
byte* dest;
- int32_t spot;
- int32_t i;
- int32_t prt;
- int32_t dsp_x1;
- int32_t dsp_x2;
- int32_t countp;
+ int32_t dsp_x1;
+ int32_t dsp_x2;
+ int32_t countp;
#ifdef RANGECHECK
if (ds_x2 < ds_x1
@@ -312,39 +324,42 @@ void R_DrawSpan (void)
}
#endif
- for (i = 0; i < 4; i++)
- {
- dsp_x1 = (ds_x1-i)/4;
- if (dsp_x1*4+i= 0) {
- outp (SC_INDEX+1,1<>(16-6))&(63*64)) + ((xfrac>>16)&63);
-
- // Lookup pixel from flat texture tile,
- // re-index using light/colormap.
- *dest++ = ds_colormap[ds_source[spot]];
- // Next step in u,v.
- xfrac += ds_xstep*4;
- yfrac += ds_ystep*4;
- } while (countp--);
- }
+ frac = (((ds_xfrac - ds_xstep) >> 6) & 0xFFFF) | ((ds_yfrac << 10) & 0xFFFF0000);
+ dfrac = ((ds_xstep >> 6) & 0xFFFF) | ((ds_ystep << 10) & 0xFFFF0000);
+ lighttable_t *colormap = ds_colormap;
+ int count = ds_x2 - ds_x1;
+ if (count < 0) return;
+ #pragma GCC unroll 4
+ for (int i = 0; i < 4; i++) {
+ dsp_x1 = (unsigned)(ds_x1 + i) >> 2;
+ countp = (count - i ) >> 2;
+ if (countp < 0) break;
+
+ uint32_t plane = (ds_x1 + i) & 3;
+#ifdef __DJGPP__
+ outp (SC_INDEX + 1, 1 << plane);
+ dest = destview + ds_y*PLANEWIDTH + dsp_x1 + (countp & 31) + 1;
+#else
+ dest = destview + ds_y*PLANEWIDTH + dsp_x1 + (countp & 31) + 1 + (plane << 16);
+#endif
+
+ loop_count = countp >> 5;
+ // add edi, 32 // 3 bytes
+ // 32 unrolled 19 bytes sequence
+ call_dest = (char*)R_ScaleRowAsm + 3 + 32 * 19 - 19 * ((countp & 31) + 1);
+
+ dfrac <<= 2;
+ fixed_t frac2 = frac;
+ fixed_t frac3 = frac;
+ asm volatile("call *(_call_dest)": "+a"(colormap), "+c"(frac2), "+d"(frac3): "D"(dest), "S"(ds_source), "b"(dfrac) : "memory");
+ dfrac >>=2;
+ frac += dfrac;
}
}
void R_DrawSpanLow (void)
{
+#ifdef __DJGPP__
fixed_t xfrac;
fixed_t yfrac;
byte* dest;
@@ -416,8 +431,8 @@ void R_DrawSpanLow (void)
yfrac += ds_ystep*2;
} while (countp--);
}
-}
#endif
+}
@@ -504,6 +519,7 @@ void R_FillBackScreen (void)
V_DrawPatch (viewwindowx+scaledviewwidth, viewwindowy+viewheight, 1,
W_CacheLumpName ("brdr_br",PU_CACHE));
+#ifdef __DJGPP__
dest = (byte*)(0xac000 + __djgpp_conventional_base);
src = screens[1];
for (i = 0; i < 4; i++, src++)
@@ -513,6 +529,15 @@ void R_FillBackScreen (void)
for (j = 0; j < (SCREENHEIGHT-SBARHEIGHT)*SCREENWIDTH/4; j++)
dest[j] = src[j*4];
}
+#else
+ dest = 0xc000 + screen;
+ src = screens[1];
+ for (i = 0; i < 4; i++, src++)
+ {
+ for (j = 0; j < (SCREENHEIGHT-SBARHEIGHT)*SCREENWIDTH/4; j++)
+ dest[j + (i << 16)] = src[j*4];
+ }
+#endif
}
@@ -520,6 +545,7 @@ void R_VideoErase (uint32_t ofs, int32_t count)
{
int32_t i;
byte *src, *dest;
+#ifdef __DJGPP__
outp (SC_INDEX, SC_MAPMASK);
outp (SC_INDEX+1, 15);
outp (GC_INDEX, GC_MODE);
@@ -532,6 +558,14 @@ void R_VideoErase (uint32_t ofs, int32_t count)
}
outp (GC_INDEX, GC_MODE);
outp (GC_INDEX+1, inp (GC_INDEX+1)&~1);
+#else
+ src = (byte*)(screen + 0xc000 + (ofs>>2));
+ dest = destscreen+(ofs>>2);
+ for (int i = 0; i < 4; i++) {
+
+ memcpy (dest + (i << 16), src + (i << 16), count >> 2);
+ }
+#endif
}
diff --git a/r_local.h b/src/r_local.h
similarity index 100%
rename from r_local.h
rename to src/r_local.h
diff --git a/r_main.c b/src/r_main.c
similarity index 100%
rename from r_main.c
rename to src/r_main.c
diff --git a/r_plane.c b/src/r_plane.c
similarity index 100%
rename from r_plane.c
rename to src/r_plane.c
diff --git a/r_segs.c b/src/r_segs.c
similarity index 100%
rename from r_segs.c
rename to src/r_segs.c
diff --git a/r_things.c b/src/r_things.c
similarity index 99%
rename from r_things.c
rename to src/r_things.c
index fd2b8a5..6a1b39a 100644
--- a/r_things.c
+++ b/src/r_things.c
@@ -1,20 +1,20 @@
-//
-// Copyright (C) 1993-1996 Id Software, Inc.
-// Copyright (C) 2023 Frenkel Smeijers
-//
-// 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, see .
-//
+//
+// Copyright (C) 1993-1996 Id Software, Inc.
+// Copyright (C) 2023 Frenkel Smeijers
+//
+// 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, see .
+//
// R_things.c
#include "doomdef.h"
@@ -117,28 +117,29 @@ static void R_InstallSpriteLump (int32_t lump, uint32_t frame, uint32_t rotation
sprtemp[frame].flip[rotation] = (byte)flipped;
}
-/*
-=================
-=
+/*
+=================
+=
= R_InitSpriteDefs
=
= Pass a null terminated list of sprite names (4 chars exactly) to be used
= Builds the sprite rotation matrixes to account for horizontally flipped
= sprites. Will report an error if the lumps are inconsistant
-=
Only called at startup
+=
+Only called at startup
=
= Sprite lump names are 4 characters for the actor, a letter for the frame,
= and a number for the rotation, A sprite that is flippable will have an
= additional letter/number appended. The rotation character can be 0 to
= signify no rotations
-=================
-*/
-
-static void R_InitSpriteDefs (void)
-{
+=================
+*/
+
+static void R_InitSpriteDefs (void)
+{
int32_t i, l, intname, frame, rotation;
int32_t start, end;
- int32_t patched;
+ int32_t patched;
sprites = Z_Malloc(NUMSPRITES *sizeof(*sprites), PU_STATIC, NULL);
@@ -147,7 +148,7 @@ static void R_InitSpriteDefs (void)
// scan all the lump names for each of the names, noting the highest
// frame letter
-// Just compare 4 characters as ints
+// Just compare 4 characters as ints
for (i=0 ; itopdelta != 0xff ; )
+ for ( ; column->topdelta != 0xff ; )
{
// calculate unclipped screen coordinates for post
topscreen = sprtopscreen + spryscale*column->topdelta;
@@ -424,18 +425,18 @@ static void R_ProjectSprite (mobj_t *thing)
trx = thing->x - viewx;
try = thing->y - viewy;
- gxt = FixedMul(trx,viewcos);
- gyt = -FixedMul(try,viewsin);
- tz = gxt-gyt;
+ gxt = FixedMul(trx,viewcos);
+ gyt = -FixedMul(try,viewsin);
+ tz = gxt-gyt;
if (tz < MINZ)
return; // thing is behind view plane
xscale = FixedDiv(projection, tz);
- gxt = -FixedMul(trx,viewsin);
- gyt = FixedMul(try,viewcos);
- tx = -(gyt+gxt);
-
+ gxt = -FixedMul(trx,viewsin);
+ gyt = FixedMul(try,viewcos);
+ tx = -(gyt+gxt);
+
if (abs(tx)>(tz<<2))
return; // too far off the side
@@ -604,14 +605,14 @@ static void R_DrawPSprite (pspdef_t *psp)
//
tx = psp->sx-160*FRACUNIT;
- tx -= spriteoffset[lump];
- x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
- if (x1 > viewwidth)
- return; // off the right side
- tx += spritewidth[lump];
- x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
- if (x2 < 0)
- return; // off the left side
+ tx -= spriteoffset[lump];
+ x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
+ if (x1 > viewwidth)
+ return; // off the right side
+ tx += spritewidth[lump];
+ x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
+ if (x2 < 0)
+ return; // off the left side
//
// store information in a vissprite
@@ -695,56 +696,56 @@ static void R_DrawPlayerSprites (void)
=
========================
*/
-
-#define bcopyp(d, s, n) memcpy(d, s, (n) * sizeof(void *))
-
-// merge sort
-static void msort(vissprite_t **s, vissprite_t **t, int32_t n)
-{
- if (n >= 16)
- {
- int32_t n1 = n / 2, n2 = n - n1;
- vissprite_t **s1 = s, **s2 = s + n1, **d = t;
-
- msort(s1, t, n1);
- msort(s2, t, n2);
-
- while ((*s1)->scale > (*s2)->scale ? (*d++ = *s1++, --n1) : (*d++ = *s2++, --n2))
- ;
-
- if (n2)
- bcopyp(d, s2, n2);
- else
- bcopyp(d, s1, n1);
-
- bcopyp(s, t, n);
- }
- else
- {
- for (int32_t i = 1; i < n; i++)
- {
- vissprite_t *temp = s[i];
- if (s[i - 1]->scale < temp->scale)
- {
- int32_t j = i;
- while ((s[j] = s[j - 1])->scale < temp->scale && --j)
- ;
- s[j] = temp;
- }
- }
- }
-}
+
+#define bcopyp(d, s, n) memcpy(d, s, (n) * sizeof(void *))
+
+// merge sort
+static void msort(vissprite_t **s, vissprite_t **t, int32_t n)
+{
+ if (n >= 16)
+ {
+ int32_t n1 = n / 2, n2 = n - n1;
+ vissprite_t **s1 = s, **s2 = s + n1, **d = t;
+
+ msort(s1, t, n1);
+ msort(s2, t, n2);
+
+ while ((*s1)->scale > (*s2)->scale ? (*d++ = *s1++, --n1) : (*d++ = *s2++, --n2))
+ ;
+
+ if (n2)
+ bcopyp(d, s2, n2);
+ else
+ bcopyp(d, s1, n1);
+
+ bcopyp(s, t, n);
+ }
+ else
+ {
+ for (int32_t i = 1; i < n; i++)
+ {
+ vissprite_t *temp = s[i];
+ if (s[i - 1]->scale < temp->scale)
+ {
+ int32_t j = i;
+ while ((s[j] = s[j - 1])->scale < temp->scale && --j)
+ ;
+ s[j] = temp;
+ }
+ }
+ }
+}
static void R_SortVisSprites (void)
{
- int32_t i = num_vissprite;
-
- if (i)
- {
- while (--i >= 0)
- vissprite_ptrs[i] = vissprites + i;
-
- msort(vissprite_ptrs, vissprite_ptrs + num_vissprite, num_vissprite);
+ int32_t i = num_vissprite;
+
+ if (i)
+ {
+ while (--i >= 0)
+ vissprite_ptrs[i] = vissprites + i;
+
+ msort(vissprite_ptrs, vissprite_ptrs + num_vissprite, num_vissprite);
}
}
diff --git a/s_sound.c b/src/s_sound.c
similarity index 100%
rename from s_sound.c
rename to src/s_sound.c
diff --git a/sounds.c b/src/sounds.c
similarity index 100%
rename from sounds.c
rename to src/sounds.c
diff --git a/sounds.h b/src/sounds.h
similarity index 100%
rename from sounds.h
rename to src/sounds.h
diff --git a/soundst.h b/src/soundst.h
similarity index 100%
rename from soundst.h
rename to src/soundst.h
diff --git a/st_lib.c b/src/st_lib.c
similarity index 100%
rename from st_lib.c
rename to src/st_lib.c
diff --git a/st_lib.h b/src/st_lib.h
similarity index 100%
rename from st_lib.h
rename to src/st_lib.h
diff --git a/st_stuff.c b/src/st_stuff.c
similarity index 100%
rename from st_stuff.c
rename to src/st_stuff.c
diff --git a/st_stuff.h b/src/st_stuff.h
similarity index 100%
rename from st_stuff.h
rename to src/st_stuff.h
diff --git a/tables.c b/src/tables.c
similarity index 100%
rename from tables.c
rename to src/tables.c
diff --git a/v_video.c b/src/v_video.c
similarity index 94%
rename from v_video.c
rename to src/v_video.c
index 96c6b00..f57de57 100644
--- a/v_video.c
+++ b/src/v_video.c
@@ -15,43 +15,41 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
-
-// V_video.c
-#include
-#include
-#include "doomdef.h"
+// V_video.c
+
+#include "doomdef.h"
//
// Background and foreground screen numbers
//
#define BG 4
#define FG 0
-
-#define SC_INDEX 0x3c4
-
-byte *screens[5];
-int32_t dirtybox[4];
-
-
-
-byte gammatable[5][256] =
-{
-{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
-
-{2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,247,248,249,250,251,252,252,253,254,255},
-
-{4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,255},
-
-{8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,253,253,254,254,255},
-
-{16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,254,254,255,255}
-};
-
-
-
-int32_t usegamma;
-
+
+#define SC_INDEX 0x3c4
+
+byte *screens[5];
+int32_t dirtybox[4];
+
+
+
+byte gammatable[5][256] =
+{
+{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
+
+{2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,247,248,249,250,251,252,252,253,254,255},
+
+{4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,255},
+
+{8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,253,253,254,254,255},
+
+{16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,254,254,255,255}
+};
+
+
+
+int32_t usegamma;
+
/*
==================
=
@@ -94,8 +92,8 @@ void V_CopyRect (int32_t x, int32_t srcy, int32_t width, int32_t height, int32_t
src += SCREENWIDTH;
dest += SCREENWIDTH;
}
-}
-
+}
+
/*
==================
=
@@ -104,49 +102,50 @@ void V_CopyRect (int32_t x, int32_t srcy, int32_t width, int32_t height, int32_t
= Masks a column based masked pic to the screen.
=
==================
-*/
-
-void V_DrawPatch (int32_t x, int32_t y, int32_t scrn, patch_t *patch)
+*/
+
+void V_DrawPatch (int32_t x, int32_t y, int32_t scrn, patch_t *patch)
{
int32_t count,col;
column_t *column;
byte *desttop, *dest, *source;
- int32_t w;
-
- y -= SHORT(patch->topoffset);
+ int32_t w;
+
+ y -= SHORT(patch->topoffset);
x -= SHORT(patch->leftoffset);
-#ifdef RANGECHECK
- if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
|| (uint32_t)scrn>4)
- I_Error("Bad V_DrawPatch");
+#ifdef RANGECHECK
+ if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
+|| (uint32_t)scrn>4)
+ I_Error("Bad V_DrawPatch");
#endif
if (!scrn)
- V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height));
- col = 0;
- desttop = screens[scrn]+y*SCREENWIDTH+x;
-
+ V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height));
+ col = 0;
+ desttop = screens[scrn]+y*SCREENWIDTH+x;
+
w = SHORT(patch->width);
- for ( ; colcolumnofs[col]));
-
-// step through the posts in a column
-
- while (column->topdelta != 0xff )
- {
- source = (byte *)column + 3;
- dest = desttop + column->topdelta*SCREENWIDTH;
- count = column->length;
- while (count--)
- {
- *dest = *source++;
- dest += SCREENWIDTH;
- }
+ for ( ; colcolumnofs[col]));
+
+// step through the posts in a column
+
+ while (column->topdelta != 0xff )
+ {
+ source = (byte *)column + 3;
+ dest = desttop + column->topdelta*SCREENWIDTH;
+ count = column->length;
+ while (count--)
+ {
+ *dest = *source++;
+ dest += SCREENWIDTH;
+ }
column = (column_t *)( (byte *)column + column->length
-+ 4 );
- }
- }
-}
-
++ 4 );
+ }
+ }
+}
+
/*
==================
=
@@ -155,58 +154,59 @@ void V_DrawPatch (int32_t x, int32_t y, int32_t scrn, patch_t *patch)
= Masks a column based masked pic to the screen.
=
==================
-*/
-
-void V_DrawPatchFlipped (int32_t x, int32_t y, int32_t scrn, patch_t *patch)
+*/
+
+void V_DrawPatchFlipped (int32_t x, int32_t y, int32_t scrn, patch_t *patch)
{
int32_t count,col;
column_t *column;
byte *desttop, *dest, *source;
- int32_t w;
-
- y -= SHORT(patch->topoffset);
+ int32_t w;
+
+ y -= SHORT(patch->topoffset);
x -= SHORT(patch->leftoffset);
-#ifdef RANGECHECK
- if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
|| (uint32_t)scrn>4)
- I_Error("Bad V_DrawPatch");
+#ifdef RANGECHECK
+ if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
+|| (uint32_t)scrn>4)
+ I_Error("Bad V_DrawPatch");
#endif
if (!scrn)
- V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height));
- col = 0;
- desttop = screens[scrn]+y*SCREENWIDTH+x;
-
+ V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height));
+ col = 0;
+ desttop = screens[scrn]+y*SCREENWIDTH+x;
+
w = SHORT(patch->width);
- for ( ; colcolumnofs[w-1-col]));
-
-// step through the posts in a column
-
- while (column->topdelta != 0xff )
- {
- source = (byte *)column + 3;
- dest = desttop + column->topdelta*SCREENWIDTH;
- count = column->length;
- while (count--)
- {
- *dest = *source++;
- dest += SCREENWIDTH;
- }
+ for ( ; colcolumnofs[w-1-col]));
+
+// step through the posts in a column
+
+ while (column->topdelta != 0xff )
+ {
+ source = (byte *)column + 3;
+ dest = desttop + column->topdelta*SCREENWIDTH;
+ count = column->length;
+ while (count--)
+ {
+ *dest = *source++;
+ dest += SCREENWIDTH;
+ }
column = (column_t *)( (byte *)column + column->length
-+ 4 );
- }
- }
-}
-
-/*
-==================
-=
-= V_DrawPatchDirect
-=
-= Draws directly to the screen on the pc.
-=
-==================
-*/
++ 4 );
+ }
+ }
+}
+
+/*
+==================
+=
+= V_DrawPatchDirect
+=
+= Draws directly to the screen on the pc.
+=
+==================
+*/
void V_DrawPatchDirect (int32_t x, int32_t y, patch_t *patch)
{
@@ -217,7 +217,7 @@ void V_DrawPatchDirect (int32_t x, int32_t y, patch_t *patch)
y -= SHORT(patch->topoffset);
x -= SHORT(patch->leftoffset);
-#ifdef RANGECHECK
+#ifdef RANGECHECK
if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT)
I_Error ("Bad V_DrawPatchDirect");
#endif
@@ -228,7 +228,12 @@ void V_DrawPatchDirect (int32_t x, int32_t y, patch_t *patch)
w = SHORT(patch->width);
for ( col = 0 ; colcolumnofs[col]));
// step through the posts in a column
@@ -236,7 +241,7 @@ void V_DrawPatchDirect (int32_t x, int32_t y, patch_t *patch)
while (column->topdelta != 0xff )
{
source = (byte *)column + 3;
- dest = desttop + column->topdelta*SCREENWIDTH/4;
+ dest = desttop + column->topdelta*SCREENWIDTH/4 + plane;
count = column->length;
while (count--)
@@ -244,23 +249,22 @@ void V_DrawPatchDirect (int32_t x, int32_t y, patch_t *patch)
*dest = *source++;
dest += SCREENWIDTH/4;
}
- column = (column_t *)( (byte *)column + column->length
-+ 4 );
+ column = (column_t *)( (byte *)column + column->length + 4 );
}
if ( ((++x)&3) == 0 )
desttop++; // go to next byte, not next plane
}
-}
-
-/*
-==================
-=
-= V_DrawBlock
-=
-= Draw a linear block of pixels into the view buffer.
-=
-==================
-*/
+}
+
+/*
+==================
+=
+= V_DrawBlock
+=
+= Draw a linear block of pixels into the view buffer.
+=
+==================
+*/
void V_DrawBlock (byte *src)
{
@@ -276,20 +280,20 @@ void V_DrawBlock (byte *src)
src += SCREENWIDTH;
dest += SCREENWIDTH;
}
-}
-
-/*
-==================
-=
-= V_Init
-=
-==================
-*/
-
-void V_Init (void)
+}
+
+/*
+==================
+=
+= V_Init
+=
+==================
+*/
+
+void V_Init (void)
{
int32_t i;
for (i=0 ; i<4 ; i++)
- screens[i] = (byte *) Z_Malloc(SCREENWIDTH*SCREENHEIGHT, PU_STATIC, NULL);
-}
+ screens[i] = (byte *) Z_Malloc(SCREENWIDTH*SCREENHEIGHT, PU_STATIC, NULL);
+}
diff --git a/w_wad.c b/src/w_wad.c
similarity index 98%
rename from w_wad.c
rename to src/w_wad.c
index 5e8c1bb..377e96a 100644
--- a/w_wad.c
+++ b/src/w_wad.c
@@ -19,12 +19,14 @@
// W_wad.c
#include
-#include
#include
#include
#include "doomdef.h"
+#ifndef O_BINARY
+ #define O_BINARY 0 /* Define as 0 on platforms where it doesn't exist */
+#endif
//===============
// TYPES
@@ -140,7 +142,7 @@ static void W_AddFile (char *filename)
printf (" adding %s\n",filename);
startlump = numlumps;
- if (stricmp (filename+strlen(filename)-3 , "wad" ) )
+ if (strcasecmp (filename+strlen(filename)-3 , "wad" ) )
{
// single lump file
fileinfo = &singleinfo;
diff --git a/wi_data.h b/src/wi_data.h
similarity index 100%
rename from wi_data.h
rename to src/wi_data.h
diff --git a/wi_stuff.c b/src/wi_stuff.c
similarity index 100%
rename from wi_stuff.c
rename to src/wi_stuff.c
diff --git a/wi_stuff.h b/src/wi_stuff.h
similarity index 100%
rename from wi_stuff.h
rename to src/wi_stuff.h
diff --git a/z_zone.c b/src/z_zone/z_zone.c
similarity index 90%
rename from z_zone.c
rename to src/z_zone/z_zone.c
index f52bf52..9c1c31d 100644
--- a/z_zone.c
+++ b/src/z_zone/z_zone.c
@@ -18,7 +18,9 @@
// Z_zone.c
-#include "doomdef.h"
+#include
+
+#include "../doomdef.h"
/*
==============================================================================
@@ -38,6 +40,15 @@ automatically if needed
#define ZONEID 0x1d4a11
+typedef struct memblock_s
+{
+ int32_t size; // including the header and possibly tiny fragments
+ void **user; // NULL if a free block
+ int32_t tag; // purgelevel
+ int32_t id; // should be ZONEID
+ struct memblock_s *next, *prev;
+} memblock_t;
+
typedef struct
{
int32_t size; // total bytes malloced, including header
@@ -71,10 +82,13 @@ void Z_Init (void)
(memblock_t *)( (byte *)mainzone + sizeof(memzone_t) );
mainzone->blocklist.user = (void *)mainzone;
mainzone->blocklist.tag = PU_STATIC;
+ mainzone->blocklist.id = ZONEID;
mainzone->rover = block;
block->prev = block->next = &mainzone->blocklist;
block->user = NULL; // free block
+ block->tag = 0;
+ block->id = ZONEID;
block->size = mainzone->size - sizeof(memzone_t);
}
@@ -235,6 +249,7 @@ void Z_FreeTags (int32_t lowtag, int32_t hightag)
next = block->next; // get link before freeing
if (!block->user)
continue; // free block
+ if (block->id != ZONEID) I_Error ("Z_FreeTags: freed a pointer without ZONEID %x\n", block->id);
if (block->tag >= lowtag && block->tag <= hightag)
Z_Free ( (byte *)block+sizeof(memblock_t));
}
@@ -274,11 +289,14 @@ void Z_CheckHeap (void)
========================
*/
-void Z_ChangeTag2 (void *ptr, int32_t tag)
+void Z_ChangeTag2 (void *ptr, int32_t tag, const char* file, int line)
{
+
memblock_t *block;
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
+ if (block->id != ZONEID)
+ I_Error("Z_CT at %s:%i", file, line);
if (block->id != ZONEID)
I_Error ("Z_ChangeTag: freed a pointer without ZONEID");
if (tag >= PU_PURGELEVEL && (uint32_t)block->user < 0x100)
diff --git a/src/z_zone/z_zone_asan.cpp b/src/z_zone/z_zone_asan.cpp
new file mode 100644
index 0000000..9f01b47
--- /dev/null
+++ b/src/z_zone/z_zone_asan.cpp
@@ -0,0 +1,146 @@
+//
+// Copyright (C) 1993-1996 Id Software, Inc.
+// Copyright (C) 2023 Frenkel Smeijers
+//
+// 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, see .
+//
+
+// Z_zone.c
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+static std::unordered_map> memory_map;
+static std::unordered_map> user_map;
+
+extern "C" {
+
+void I_Error(const char* error, ...);
+
+void Z_Init (void) {}
+
+
+/*
+========================
+=
+= Z_Free
+=
+========================
+*/
+
+void Z_Free (void *ptr) {
+ if (!ptr) return;
+ auto user = user_map.find(ptr);
+ if (user == user_map.end()) I_Error("Z_Free: pointer not found in user_map");
+ if (user->second.first) {
+ *user->second.first = nullptr; // clear the user's mark
+ }
+ auto tag = user->second.second;
+ user_map.erase(user);
+ auto it = memory_map.find(tag);
+ if (it == memory_map.end()) {
+ I_Error("Z_Free: pointer not found in memory_map");
+ }
+ auto& ptrs = it->second;
+ auto ptr_it = std::find(ptrs.begin(), ptrs.end(), ptr);
+ if (ptr_it == ptrs.end()) {
+ I_Error("Z_Free: pointer not found in memory_map");
+ }
+ ptrs.erase(ptr_it);
+ std::free(ptr);
+}
+
+
+/*
+========================
+=
+= Z_Malloc
+=
+= You can pass a NULL user if the tag is < PU_PURGELEVEL
+========================
+*/
+
+void *Z_Malloc (int32_t size, int32_t tag, void **user)
+{
+ auto ptr = std::malloc(size);
+
+ memory_map[tag].push_back(ptr);
+ user_map[ptr] = {user, tag};
+ if (user) {
+ *user = ptr;
+ }
+ return ptr;
+}
+
+
+/*
+========================
+=
+= Z_FreeTags
+=
+========================
+*/
+
+void Z_FreeTags (int32_t lowtag, int32_t hightag)
+{
+ for (auto it = memory_map.begin(); it != memory_map.end(); ++it) {
+ if (it->first >= lowtag && it->first <= hightag) {
+ auto copied = it->second;
+ for (auto ptr : copied) {
+ Z_Free(ptr);
+ }
+ }
+ }
+}
+
+/*
+========================
+=
+= Z_CheckHeap
+=
+========================
+*/
+
+void Z_CheckHeap (void) {}
+
+
+/*
+========================
+=
+= Z_ChangeTag
+=
+========================
+*/
+
+#define PU_PURGELEVEL 100
+
+void Z_ChangeTag2 (void *ptr, int32_t tag, const char* file, int line)
+{
+ auto user = user_map.find(ptr);
+ if (user == user_map.end()) {
+ I_Error("Z_ChangeTag: pointer not found in user_map");
+ }
+ if (tag >= PU_PURGELEVEL && user->second.first == nullptr) {
+ I_Error("Z_ChangeTag: an owner is required for purgable blocks");
+ }
+ user->second.second = tag;
+}
+
+} // extern "C"
\ No newline at end of file
diff --git a/wcdoom.lnk b/wcdoom.lnk
deleted file mode 100644
index 07faea2..0000000
--- a/wcdoom.lnk
+++ /dev/null
@@ -1,80 +0,0 @@
-
-# wcdoom.EXE Linker directive file
-
-option quiet
-option map
-option stack=65536
-option stub=wstub
-option static
-debug all
-libpath %WATCOM%\lib386
-libpath %WATCOM%\lib386\dos
-lib noemu387.lib
-format os2 le
-name wcdoom
-alias MV_Mix8BitMono_=_MV_Mix8BitMono, MV_Mix8BitStereo_=_MV_Mix8BitStereo, MV_Mix16BitMono_=_MV_Mix16BitMono, MV_Mix16BitStereo_=_MV_Mix16BitStereo
-alias R_DrawColumn_=_R_DrawColumn, R_DrawColumnLow_=_R_DrawColumnLow, R_DrawSpan_=_R_DrawSpan, R_DrawSpanLow_=_R_DrawSpanLow
-
-file dmx.obj
-file a_al_mid.obj
-file a_blast.obj
-file a_dma.obj
-file a_ll_man.obj
-file a_midi.obj
-file a_mpu401.obj
-file a_multiv.obj
-file a_music.obj
-file a_musmid.obj
-file a_mv_mix.obj
-file a_pcfx.obj
-file a_taskmn.obj
-file a_tsmapi.obj
-file i_main.obj
-file i_ibm.obj
-file i_sound.obj
-file planar.obj
-file tables.obj
-file f_finale.obj
-file d_main.obj
-file d_net.obj
-file g_game.obj
-file m_menu.obj
-file m_misc.obj
-file am_map.obj
-file p_ceilng.obj
-file p_doors.obj
-file p_enemy.obj
-file p_floor.obj
-file p_inter.obj
-file p_lights.obj
-file p_map.obj
-file p_maputl.obj
-file p_plats.obj
-file p_pspr.obj
-file p_setup.obj
-file p_sight.obj
-file p_spec.obj
-file p_switch.obj
-file p_mobj.obj
-file p_telept.obj
-file p_tick.obj
-file p_user.obj
-file r_bsp.obj
-file r_data.obj
-file r_draw.obj
-file r_main.obj
-file r_plane.obj
-file r_segs.obj
-file r_things.obj
-file w_wad.obj
-file v_video.obj
-file z_zone.obj
-file st_stuff.obj
-file st_lib.obj
-file hu_stuff.obj
-file hu_lib.obj
-file wi_stuff.obj
-file s_sound.obj
-file sounds.obj
-file dutils.obj
-file info.obj