Merge pull request #13 from turol/dos
DOS support with Allegro and DJGPP
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
|
*.exe
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
*.log
|
*.log
|
||||||
*.user
|
*.user
|
||||||
|
*~
|
||||||
.vs/
|
.vs/
|
||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
################################################################
|
||||||
|
#
|
||||||
|
# $Id:$
|
||||||
|
#
|
||||||
|
# $Log:$
|
||||||
|
#
|
||||||
|
|
||||||
|
.PHONY: all clean print
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
ifeq ($(V),1)
|
||||||
|
VB=''
|
||||||
|
else
|
||||||
|
VB=@
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CC:=i386-pc-msdosdjgpp-gcc
|
||||||
|
OPTFLAGS:=-O3
|
||||||
|
CFLAGS+=-std=gnu89
|
||||||
|
CFLAGS+=$(OPTFLAGS)
|
||||||
|
CFLAGS+=-Werror
|
||||||
|
CFLAGS+=-DDOOMGENERIC_RESX=320 -DDOOMGENERIC_RESY=200
|
||||||
|
CFLAGS+=-DFEATURE_SOUND=1
|
||||||
|
CFLAGS+=-DCMAP256
|
||||||
|
|
||||||
|
# link time optimization, no significant effect on performance
|
||||||
|
# CFLAGS+=-flto
|
||||||
|
# LDFLAGS+=-flto $(OPTFLAGS)
|
||||||
|
|
||||||
|
# debug
|
||||||
|
# CFLAGS+=-g
|
||||||
|
# LDFLAGS+=-g
|
||||||
|
|
||||||
|
LIBS+=-lalleg
|
||||||
|
#LIBS+=-lalld # debug library
|
||||||
|
|
||||||
|
# subdirectory for objects
|
||||||
|
OBJDIR:=djgpp
|
||||||
|
OUTPUT:=doomgen.exe
|
||||||
|
|
||||||
|
SRC_DOOM = dummy.o am_map.o doomdef.o doomstat.o dstrings.o d_event.o d_items.o d_iwad.o d_loop.o d_main.o d_mode.o d_net.o f_finale.o f_wipe.o g_game.o hu_lib.o hu_stuff.o info.o i_cdmus.o i_endoom.o i_joystick.o i_scale.o i_sound.o i_system.o i_timer.o memio.o m_argv.o m_bbox.o m_cheat.o m_config.o m_controls.o m_fixed.o m_menu.o m_misc.o m_random.o p_ceilng.o p_doors.o p_enemy.o p_floor.o p_inter.o p_lights.o p_map.o p_maputl.o p_mobj.o p_plats.o p_pspr.o p_saveg.o p_setup.o p_sight.o p_spec.o p_switch.o p_telept.o p_tick.o p_user.o r_bsp.o r_data.o r_draw.o r_main.o r_plane.o r_segs.o r_sky.o r_things.o sha1.o sounds.o statdump.o st_lib.o st_stuff.o s_sound.o tables.o v_video.o wi_stuff.o w_checksum.o w_file.o w_main.o w_wad.o z_zone.o w_file_stdc.o i_input.o i_video.o doomgeneric.o doomgeneric_allegro.o mus2mid.o i_allegromusic.o i_allegrosound.o
|
||||||
|
OBJS += $(addprefix $(OBJDIR)/, $(SRC_DOOM))
|
||||||
|
|
||||||
|
all: $(OUTPUT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJDIR)
|
||||||
|
rm -f $(OUTPUT)
|
||||||
|
rm -f $(OUTPUT).gdb
|
||||||
|
rm -f $(OUTPUT).map
|
||||||
|
|
||||||
|
$(OUTPUT): $(OBJS)
|
||||||
|
@echo [Linking $@]
|
||||||
|
$(VB)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) \
|
||||||
|
-o $(OUTPUT) $(LIBS)
|
||||||
|
|
||||||
|
$(OBJS): | $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
mkdir -p $(OBJDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c
|
||||||
|
@echo [Compiling $<]
|
||||||
|
$(VB)$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
print:
|
||||||
|
@echo OBJS: $(OBJS)
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "doomgeneric.h"
|
#include "doomgeneric.h"
|
||||||
|
|
||||||
uint32_t* DG_ScreenBuffer = 0;
|
pixel_t* DG_ScreenBuffer = NULL;
|
||||||
|
|
||||||
void M_FindResponseFile(void);
|
void M_FindResponseFile(void);
|
||||||
void D_DoomMain (void);
|
void D_DoomMain (void);
|
||||||
|
|||||||
@@ -4,11 +4,27 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef DOOMGENERIC_RESX
|
||||||
#define DOOMGENERIC_RESX 640
|
#define DOOMGENERIC_RESX 640
|
||||||
|
#endif // DOOMGENERIC_RESX
|
||||||
|
|
||||||
|
#ifndef DOOMGENERIC_RESY
|
||||||
#define DOOMGENERIC_RESY 400
|
#define DOOMGENERIC_RESY 400
|
||||||
|
#endif // DOOMGENERIC_RESY
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t* DG_ScreenBuffer;
|
#ifdef CMAP256
|
||||||
|
|
||||||
|
typedef uint8_t pixel_t;
|
||||||
|
|
||||||
|
#else // CMAP256
|
||||||
|
|
||||||
|
typedef uint32_t pixel_t;
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
|
|
||||||
|
extern pixel_t* DG_ScreenBuffer;
|
||||||
|
|
||||||
void doomgeneric_Create(int argc, char **argv);
|
void doomgeneric_Create(int argc, char **argv);
|
||||||
void doomgeneric_Tick();
|
void doomgeneric_Tick();
|
||||||
|
|||||||
@@ -0,0 +1,453 @@
|
|||||||
|
// doomgeneric for Allegro library
|
||||||
|
|
||||||
|
#include "doomkeys.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "i_video.h"
|
||||||
|
#include "m_argv.h"
|
||||||
|
#include "doomgeneric.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define ALLEGRO_NO_KEY_DEFINES 1
|
||||||
|
#include <allegro.h>
|
||||||
|
#undef uint32_t // ugly hack because Allegro is Old and doesn't know modern GCC has stdint.h
|
||||||
|
|
||||||
|
|
||||||
|
static bool videomode_set = false;
|
||||||
|
|
||||||
|
static BITMAP *temp_bitmap = NULL;
|
||||||
|
|
||||||
|
static PALETTE pal;
|
||||||
|
|
||||||
|
#define KEYQUEUE_SIZE 16
|
||||||
|
|
||||||
|
static volatile unsigned int s_KeyQueue[KEYQUEUE_SIZE];
|
||||||
|
static volatile unsigned int s_KeyQueueWriteIndex = 0;
|
||||||
|
static unsigned int s_KeyQueueReadIndex = 0;
|
||||||
|
|
||||||
|
static volatile unsigned int s_ticks = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void key_callback(int scancode) {
|
||||||
|
// this is in interrupt context, avoid heavy processing and be careful about volatile writes
|
||||||
|
s_KeyQueue[s_KeyQueueWriteIndex] = scancode;
|
||||||
|
s_KeyQueueWriteIndex = (s_KeyQueueWriteIndex + 1) % KEYQUEUE_SIZE;
|
||||||
|
}
|
||||||
|
END_OF_FUNCTION(key_callback);
|
||||||
|
|
||||||
|
|
||||||
|
void timer_callback(void) {
|
||||||
|
// also in interrupt context
|
||||||
|
s_ticks++;
|
||||||
|
}
|
||||||
|
END_OF_FUNCTION(timer_callback);
|
||||||
|
|
||||||
|
|
||||||
|
void DG_Init() {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
printf("Initializing Allegro\n");
|
||||||
|
|
||||||
|
result = allegro_init();
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
I_Error("Allegro init failed: %d %s\n", result, allegro_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
I_AtExit(allegro_exit, true);
|
||||||
|
|
||||||
|
LOCK_FUNCTION(key_callback);
|
||||||
|
LOCK_VARIABLE(s_KeyQueue);
|
||||||
|
LOCK_VARIABLE(s_KeyQueueWriteIndex);
|
||||||
|
LOCK_VARIABLE(s_KeyQueueReadIndex);
|
||||||
|
|
||||||
|
LOCK_FUNCTION(timer_callback);
|
||||||
|
LOCK_VARIABLE(s_ticks);
|
||||||
|
|
||||||
|
install_keyboard();
|
||||||
|
keyboard_lowlevel_callback = key_callback;
|
||||||
|
|
||||||
|
install_timer();
|
||||||
|
result = install_int(timer_callback, 1);
|
||||||
|
if (result < 0) {
|
||||||
|
I_Error("Unable to install timer: %d %s\n", result, allegro_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't set video mode yet so initialization messages stay on screen
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void back_to_text_mode(void) {
|
||||||
|
set_gfx_mode(GFX_TEXT, 80, 25, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DG_DrawFrame()
|
||||||
|
{
|
||||||
|
if (!DG_ScreenBuffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!videomode_set) {
|
||||||
|
int y;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
#ifdef CMAP256
|
||||||
|
set_color_depth(8);
|
||||||
|
#else // CMAP256
|
||||||
|
// does not seem to work on real DOS hardware
|
||||||
|
set_color_depth(32);
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
|
result = set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, DOOMGENERIC_RESX, DOOMGENERIC_RESY, 0, 0);
|
||||||
|
if (result < 0) {
|
||||||
|
I_Error("Failed to set video mode: %s\n", allegro_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register an exit handler to return to text mode
|
||||||
|
// while this is also done by allegro_exit handler registered earlier
|
||||||
|
// that's too late for ENDOOM screen to work correctly
|
||||||
|
I_AtExit(back_to_text_mode, true);
|
||||||
|
|
||||||
|
if (!screen) {
|
||||||
|
I_Error("screen is null\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_bitmap = create_bitmap(DOOMGENERIC_RESX, DOOMGENERIC_RESY);
|
||||||
|
if (!temp_bitmap) {
|
||||||
|
I_Error("Failed to create temp bitmap\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is an evil hack
|
||||||
|
// replace the internal line pointers with pointers into DG_ScreenBuffer
|
||||||
|
// this avoids some copying
|
||||||
|
// it might crash when freeing the bitmap but we never do
|
||||||
|
for (y = 0; y < DOOMGENERIC_RESY; y++) {
|
||||||
|
temp_bitmap->line[y] = (unsigned char *) &DG_ScreenBuffer[y * DOOMGENERIC_RESX];
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_bitmap(temp_bitmap);
|
||||||
|
|
||||||
|
videomode_set = true;
|
||||||
|
palette_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CMAP256
|
||||||
|
|
||||||
|
// changing palette implicitly waits for vsync
|
||||||
|
// TODO: should do it explicitly in case where we don't change palette
|
||||||
|
if (palette_changed) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
// allegro uses VGA range 0..63
|
||||||
|
pal[i].r = colors[i].r >> 2;
|
||||||
|
pal[i].g = colors[i].g >> 2;
|
||||||
|
pal[i].b = colors[i].b >> 2;
|
||||||
|
}
|
||||||
|
set_palette(pal);
|
||||||
|
|
||||||
|
palette_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
|
blit(temp_bitmap, screen, 0, 0, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DG_SleepMs(uint32_t ms)
|
||||||
|
{
|
||||||
|
rest(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DG_GetTicksMs()
|
||||||
|
{
|
||||||
|
return s_ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DG_GetKey(int *pressed, unsigned char *doomKey)
|
||||||
|
{
|
||||||
|
if (s_KeyQueueReadIndex == s_KeyQueueWriteIndex){
|
||||||
|
//key queue is empty
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
bool released;
|
||||||
|
short keyData = 0;
|
||||||
|
int scancode = s_KeyQueue[s_KeyQueueReadIndex];
|
||||||
|
s_KeyQueueReadIndex++;
|
||||||
|
s_KeyQueueReadIndex %= KEYQUEUE_SIZE;
|
||||||
|
|
||||||
|
released = scancode & 0x80;
|
||||||
|
*pressed = !released;
|
||||||
|
|
||||||
|
scancode = scancode & 0x7F;
|
||||||
|
|
||||||
|
switch (scancode) {
|
||||||
|
case __allegro_KEY_RIGHT:
|
||||||
|
keyData = KEY_RIGHTARROW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_LEFT:
|
||||||
|
keyData = KEY_LEFTARROW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_UP:
|
||||||
|
keyData = KEY_UPARROW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_DOWN:
|
||||||
|
keyData = KEY_DOWNARROW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_COMMA:
|
||||||
|
keyData = KEY_STRAFE_L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_STOP:
|
||||||
|
keyData = KEY_STRAFE_R;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_SPACE:
|
||||||
|
keyData = KEY_USE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_LCONTROL:
|
||||||
|
keyData = KEY_FIRE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_ESC:
|
||||||
|
keyData = KEY_ESCAPE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_ENTER:
|
||||||
|
keyData = KEY_ENTER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_TAB:
|
||||||
|
keyData = KEY_TAB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F1:
|
||||||
|
keyData = KEY_F1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F2:
|
||||||
|
keyData = KEY_F2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F3:
|
||||||
|
keyData = KEY_F3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F4:
|
||||||
|
keyData = KEY_F4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F5:
|
||||||
|
keyData = KEY_F5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F6:
|
||||||
|
keyData = KEY_F6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F7:
|
||||||
|
keyData = KEY_F7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F8:
|
||||||
|
keyData = KEY_F8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F9:
|
||||||
|
keyData = KEY_F9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F10:
|
||||||
|
keyData = KEY_F10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F11:
|
||||||
|
keyData = KEY_F11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_F12:
|
||||||
|
keyData = KEY_F12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_BACKSPACE:
|
||||||
|
keyData = KEY_BACKSPACE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_PAUSE:
|
||||||
|
keyData = KEY_PAUSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_EQUALS:
|
||||||
|
keyData = KEY_EQUALS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_MINUS:
|
||||||
|
keyData = KEY_MINUS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_LSHIFT:
|
||||||
|
case __allegro_KEY_RSHIFT:
|
||||||
|
keyData = KEY_RSHIFT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_RCONTROL:
|
||||||
|
keyData = KEY_RCTRL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_ALT:
|
||||||
|
keyData = KEY_RALT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_CAPSLOCK:
|
||||||
|
keyData = KEY_CAPSLOCK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_NUMLOCK:
|
||||||
|
keyData = KEY_NUMLOCK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_SCRLOCK:
|
||||||
|
keyData = KEY_SCRLCK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_PRTSCR:
|
||||||
|
keyData = KEY_PRTSCR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_HOME:
|
||||||
|
keyData = KEY_HOME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_END:
|
||||||
|
keyData = KEY_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_PGUP:
|
||||||
|
keyData = KEY_PGUP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_PGDN:
|
||||||
|
keyData = KEY_PGDN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_INSERT:
|
||||||
|
keyData = KEY_INS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_DEL:
|
||||||
|
keyData = KEY_DEL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_0_PAD:
|
||||||
|
keyData = KEYP_0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_1_PAD:
|
||||||
|
keyData = KEYP_1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_2_PAD:
|
||||||
|
keyData = KEYP_2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_3_PAD:
|
||||||
|
keyData = KEYP_3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_4_PAD:
|
||||||
|
keyData = KEYP_4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_5_PAD:
|
||||||
|
keyData = KEYP_5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_6_PAD:
|
||||||
|
keyData = KEYP_6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_7_PAD:
|
||||||
|
keyData = KEYP_7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_8_PAD:
|
||||||
|
keyData = KEYP_8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_9_PAD:
|
||||||
|
keyData = KEYP_9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_SLASH_PAD:
|
||||||
|
keyData = KEYP_DIVIDE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_PLUS_PAD:
|
||||||
|
keyData = KEYP_PLUS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_MINUS_PAD:
|
||||||
|
keyData = KEYP_MINUS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_ASTERISK:
|
||||||
|
keyData = KEYP_MULTIPLY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_DEL_PAD:
|
||||||
|
keyData = KEYP_PERIOD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_EQUALS_PAD:
|
||||||
|
keyData = KEYP_EQUALS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case __allegro_KEY_ENTER_PAD:
|
||||||
|
keyData = KEYP_ENTER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
keyData = scancode_to_ascii(scancode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyData != 0) {
|
||||||
|
*doomKey = keyData & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DG_SetWindowTitle(const char *title)
|
||||||
|
{
|
||||||
|
set_window_title(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
doomgeneric_Create(argc, argv);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
doomgeneric_Tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -83,7 +83,7 @@ typedef uint8_t byte;
|
|||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
|
|
||||||
#define DIR_SEPARATOR '\\'
|
#define DIR_SEPARATOR '\\'
|
||||||
#define DIR_SEPARATOR_S "\\"
|
#define DIR_SEPARATOR_S "\\"
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||||
|
// Copyright(C) 2005-2014 Simon Howard
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// System interface for music.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "doomtype.h"
|
||||||
|
#include "memio.h"
|
||||||
|
#include "mus2mid.h"
|
||||||
|
|
||||||
|
#include "deh_str.h"
|
||||||
|
#include "gusconf.h"
|
||||||
|
#include "i_sound.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "i_swap.h"
|
||||||
|
#include "m_argv.h"
|
||||||
|
#include "m_config.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
#include "sha1.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
|
#include <allegro/base.h>
|
||||||
|
#include <allegro/midi.h>
|
||||||
|
#include <allegro/sound.h>
|
||||||
|
#include <allegro/system.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXMIDLENGTH (96 * 1024)
|
||||||
|
#define MID_HEADER_MAGIC "MThd"
|
||||||
|
#define MUS_HEADER_MAGIC "MUS\x1a"
|
||||||
|
|
||||||
|
|
||||||
|
static boolean music_initialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
static boolean musicpaused = false;
|
||||||
|
static int current_music_volume;
|
||||||
|
|
||||||
|
|
||||||
|
// Currently playing music track.
|
||||||
|
MIDI *current_track_music = NULL;
|
||||||
|
|
||||||
|
// If true, the currently playing track is being played on loop.
|
||||||
|
static boolean current_track_loop;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Shutdown music
|
||||||
|
static void I_Allegro_ShutdownMusic(void)
|
||||||
|
{
|
||||||
|
// nothing here
|
||||||
|
// TODO: stop song?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize music subsystem
|
||||||
|
static boolean I_Allegro_InitMusic(void)
|
||||||
|
{
|
||||||
|
// nothing here, it's all done by I_Allegro_InitSound
|
||||||
|
music_initialized = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set music volume (0 - 127)
|
||||||
|
static void I_Allegro_SetMusicVolume(int volume)
|
||||||
|
{
|
||||||
|
int digivol = -1;
|
||||||
|
get_volume(&digivol, NULL);
|
||||||
|
// allegro range 0 - 255
|
||||||
|
set_volume(digivol, volume * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Start playing a mid
|
||||||
|
static void I_Allegro_PlaySong(void *handle, boolean looping)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_track_music = (MIDI *) handle;
|
||||||
|
current_track_loop = looping;
|
||||||
|
|
||||||
|
retval = play_midi(current_track_music, looping);
|
||||||
|
if (retval < 0) {
|
||||||
|
fprintf(stderr, "Error playing midi: %d \"%s\"\n", retval, allegro_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_PauseSong(void)
|
||||||
|
{
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicpaused = true;
|
||||||
|
|
||||||
|
midi_pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_ResumeSong(void)
|
||||||
|
{
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicpaused = false;
|
||||||
|
|
||||||
|
midi_resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_StopSong(void)
|
||||||
|
{
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_midi();
|
||||||
|
|
||||||
|
current_track_music = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_UnRegisterSong(void *handle)
|
||||||
|
{
|
||||||
|
MIDI *midi = (MIDI *) handle;
|
||||||
|
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy_midi(midi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Determine whether memory block is a .mid file
|
||||||
|
static boolean IsMid(byte *mem, int len)
|
||||||
|
{
|
||||||
|
return len > 4 && !memcmp(mem, "MThd", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static boolean ConvertMus(byte *musdata, int len, char *filename)
|
||||||
|
{
|
||||||
|
MEMFILE *instream;
|
||||||
|
MEMFILE *outstream;
|
||||||
|
void *outbuf;
|
||||||
|
size_t outbuf_len;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
instream = mem_fopen_read(musdata, len);
|
||||||
|
outstream = mem_fopen_write();
|
||||||
|
|
||||||
|
result = mus2mid(instream, outstream);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
mem_get_buf(outstream, &outbuf, &outbuf_len);
|
||||||
|
|
||||||
|
M_WriteFile(filename, outbuf, outbuf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_fclose(instream);
|
||||||
|
mem_fclose(outstream);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *I_Allegro_RegisterSong(void *data, int len)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
MIDI *music;
|
||||||
|
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = M_TempFile("doom.mid");
|
||||||
|
|
||||||
|
if (IsMid(data, len) && len < MAXMIDLENGTH)
|
||||||
|
{
|
||||||
|
M_WriteFile(filename, data, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Assume a MUS file and try to convert
|
||||||
|
ConvertMus(data, len, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the MIDI. In an ideal world we'd load it directly from memory but Allegro
|
||||||
|
// doesn't support that so we have to generate a temporary file.
|
||||||
|
|
||||||
|
music = load_midi(filename);
|
||||||
|
|
||||||
|
if (music == NULL)
|
||||||
|
{
|
||||||
|
// Failed to load
|
||||||
|
fprintf(stderr, "Error loading midi: %s\n", allegro_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the temporary MIDI file;
|
||||||
|
remove(filename);
|
||||||
|
|
||||||
|
free(filename);
|
||||||
|
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Is the song playing?
|
||||||
|
static boolean I_Allegro_MusicIsPlaying(void)
|
||||||
|
{
|
||||||
|
if (!music_initialized)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (current_track_music != NULL) && (midi_pos > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get position in substitute music track, in seconds since start of track.
|
||||||
|
static double GetMusicPosition(void)
|
||||||
|
{
|
||||||
|
return midi_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Poll music position; if we have passed the loop point end position
|
||||||
|
// then we need to go back.
|
||||||
|
static void I_Allegro_PollMusic(void)
|
||||||
|
{
|
||||||
|
// nothing here, allegro takes care of it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static snddevice_t music_allegro_devices[] =
|
||||||
|
{
|
||||||
|
SNDDEVICE_PAS,
|
||||||
|
SNDDEVICE_GUS,
|
||||||
|
SNDDEVICE_WAVEBLASTER,
|
||||||
|
SNDDEVICE_SOUNDCANVAS,
|
||||||
|
SNDDEVICE_GENMIDI,
|
||||||
|
SNDDEVICE_AWE32,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
music_module_t DG_music_module =
|
||||||
|
{
|
||||||
|
music_allegro_devices,
|
||||||
|
arrlen(music_allegro_devices),
|
||||||
|
I_Allegro_InitMusic,
|
||||||
|
I_Allegro_ShutdownMusic,
|
||||||
|
I_Allegro_SetMusicVolume,
|
||||||
|
I_Allegro_PauseSong,
|
||||||
|
I_Allegro_ResumeSong,
|
||||||
|
I_Allegro_RegisterSong,
|
||||||
|
I_Allegro_UnRegisterSong,
|
||||||
|
I_Allegro_PlaySong,
|
||||||
|
I_Allegro_StopSong,
|
||||||
|
I_Allegro_MusicIsPlaying,
|
||||||
|
I_Allegro_PollMusic,
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,433 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||||
|
// Copyright(C) 2005-2014 Simon Howard
|
||||||
|
// Copyright(C) 2008 David Flater
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// System interface for sound.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "deh_str.h"
|
||||||
|
#include "i_sound.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "i_swap.h"
|
||||||
|
#include "m_argv.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
|
||||||
|
#include <allegro/base.h>
|
||||||
|
#include <allegro/sound.h>
|
||||||
|
#include <allegro/system.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_CHANNELS 16
|
||||||
|
|
||||||
|
#define NUM_MIDI_CHANNELS 16
|
||||||
|
|
||||||
|
|
||||||
|
static boolean sound_initialized = false;
|
||||||
|
|
||||||
|
static sfxinfo_t *channels_playing[NUM_CHANNELS];
|
||||||
|
|
||||||
|
static int allegro_voices[NUM_CHANNELS];
|
||||||
|
|
||||||
|
static SAMPLE *dummy_sample = NULL;
|
||||||
|
|
||||||
|
static boolean use_sfx_prefix;
|
||||||
|
|
||||||
|
|
||||||
|
// We don't support libsamplerate with Allegro but these have to be here since
|
||||||
|
// other code requires them
|
||||||
|
int use_libsamplerate = 0;
|
||||||
|
|
||||||
|
// Scale factor used when converting libsamplerate floating point numbers
|
||||||
|
// to integers. Too high means the sounds can clip; too low means they
|
||||||
|
// will be too quiet. This is an amount that should avoid clipping most
|
||||||
|
// of the time: with all the Doom IWAD sound effects, at least. If a PWAD
|
||||||
|
// is used, clipping might occur.
|
||||||
|
|
||||||
|
float libsamplerate_scale = 0.65f;
|
||||||
|
|
||||||
|
|
||||||
|
// Load and convert a sound effect
|
||||||
|
// Returns true if successful
|
||||||
|
|
||||||
|
static boolean CacheSFX(sfxinfo_t *sfxinfo)
|
||||||
|
{
|
||||||
|
int lumpnum;
|
||||||
|
unsigned int lumplen;
|
||||||
|
int samplerate;
|
||||||
|
unsigned int length;
|
||||||
|
byte *data;
|
||||||
|
SAMPLE *sample;
|
||||||
|
|
||||||
|
// need to load the sound
|
||||||
|
|
||||||
|
lumpnum = sfxinfo->lumpnum;
|
||||||
|
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
lumplen = W_LumpLength(lumpnum);
|
||||||
|
|
||||||
|
// Check the header, and ensure this is a valid sound
|
||||||
|
|
||||||
|
if (lumplen < 8
|
||||||
|
|| data[0] != 0x03 || data[1] != 0x00)
|
||||||
|
{
|
||||||
|
// Invalid sound
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 16 bit sample rate field, 32 bit length field
|
||||||
|
|
||||||
|
samplerate = (data[3] << 8) | data[2];
|
||||||
|
length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
|
||||||
|
|
||||||
|
// If the header specifies that the length of the sound is greater than
|
||||||
|
// the length of the lump itself, this is an invalid sound lump
|
||||||
|
|
||||||
|
// We also discard sound lumps that are less than 49 samples long,
|
||||||
|
// as this is how DMX behaves - although the actual cut-off length
|
||||||
|
// seems to vary slightly depending on the sample rate. This needs
|
||||||
|
// further investigation to better understand the correct
|
||||||
|
// behavior.
|
||||||
|
|
||||||
|
if (length > lumplen - 8 || length <= 48)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The DMX sound library seems to skip the first 16 and last 16
|
||||||
|
// bytes of the lump - reason unknown.
|
||||||
|
|
||||||
|
data += 16;
|
||||||
|
length -= 32;
|
||||||
|
|
||||||
|
sample = create_sample(8, 0, samplerate, length);
|
||||||
|
if (sample == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(sample->data, data, length);
|
||||||
|
|
||||||
|
sfxinfo->driver_data = sample;
|
||||||
|
|
||||||
|
// don't need the original lump any more
|
||||||
|
|
||||||
|
W_ReleaseLumpNum(lumpnum);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void GetSfxLumpName(sfxinfo_t *sfx, char *buf, size_t buf_len)
|
||||||
|
{
|
||||||
|
// Linked sfx lumps? Get the lump number for the sound linked to.
|
||||||
|
|
||||||
|
if (sfx->link != NULL)
|
||||||
|
{
|
||||||
|
sfx = sfx->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doom adds a DS* prefix to sound lumps; Heretic and Hexen don't
|
||||||
|
// do this.
|
||||||
|
|
||||||
|
if (use_sfx_prefix)
|
||||||
|
{
|
||||||
|
M_snprintf(buf, buf_len, "ds%s", DEH_String(sfx->name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
M_StringCopy(buf, DEH_String(sfx->name), buf_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_PrecacheSounds(sfxinfo_t *sounds, int num_sounds)
|
||||||
|
{
|
||||||
|
char namebuf[9];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("I_Allegro_PrecacheSounds: Precaching all sound effects..");
|
||||||
|
|
||||||
|
for (i=0; i<num_sounds; ++i)
|
||||||
|
{
|
||||||
|
if ((i % 6) == 0)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSfxLumpName(&sounds[i], namebuf, sizeof(namebuf));
|
||||||
|
|
||||||
|
sounds[i].lumpnum = W_CheckNumForName(namebuf);
|
||||||
|
|
||||||
|
if (sounds[i].lumpnum != -1)
|
||||||
|
{
|
||||||
|
CacheSFX(&sounds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the raw data lump index
|
||||||
|
// for a given SFX name.
|
||||||
|
//
|
||||||
|
|
||||||
|
static int I_Allegro_GetSfxLumpNum(sfxinfo_t *sfx)
|
||||||
|
{
|
||||||
|
char namebuf[9];
|
||||||
|
|
||||||
|
GetSfxLumpName(sfx, namebuf, sizeof(namebuf));
|
||||||
|
|
||||||
|
return W_GetNumForName(namebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void I_Allegro_UpdateSoundParams(int handle, int vol, int sep)
|
||||||
|
{
|
||||||
|
int left, right;
|
||||||
|
|
||||||
|
if (!sound_initialized || handle < 0 || handle >= NUM_CHANNELS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels_playing[handle] == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
voice_set_volume(allegro_voices[handle], vol);
|
||||||
|
voice_set_pan(allegro_voices[handle], sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Starting a sound means adding it
|
||||||
|
// to the current list of active sounds
|
||||||
|
// in the internal channels.
|
||||||
|
// As the SFX info struct contains
|
||||||
|
// e.g. a pointer to the raw data,
|
||||||
|
// it is ignored.
|
||||||
|
// As our sound handling does not handle
|
||||||
|
// priority, it is ignored.
|
||||||
|
// Pitching (that is, increased speed of playback)
|
||||||
|
// is set, but currently not used by mixing.
|
||||||
|
//
|
||||||
|
|
||||||
|
static int I_Allegro_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep)
|
||||||
|
{
|
||||||
|
if (!sound_initialized || channel < 0 || channel >= NUM_CHANNELS)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release a sound effect if there is already one playing
|
||||||
|
// on this channel
|
||||||
|
if (channels_playing[channel]) {
|
||||||
|
voice_stop(allegro_voices[channel]);
|
||||||
|
channels_playing[channel] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the sound data
|
||||||
|
if (sfxinfo->driver_data == NULL)
|
||||||
|
{
|
||||||
|
if (!CacheSFX(sfxinfo))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(sfxinfo->driver_data);
|
||||||
|
|
||||||
|
// play sound
|
||||||
|
reallocate_voice(allegro_voices[channel], sfxinfo->driver_data);
|
||||||
|
voice_set_volume(allegro_voices[channel], vol);
|
||||||
|
voice_set_pan(allegro_voices[channel], sep);
|
||||||
|
voice_start(allegro_voices[channel]);
|
||||||
|
|
||||||
|
channels_playing[channel] = sfxinfo;
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_StopSound(int handle)
|
||||||
|
{
|
||||||
|
if (!sound_initialized || handle < 0 || handle >= NUM_CHANNELS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels_playing[handle] == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
voice_stop(allegro_voices[handle]);
|
||||||
|
channels_playing[handle] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static boolean I_Allegro_SoundIsPlaying(int handle)
|
||||||
|
{
|
||||||
|
int position;
|
||||||
|
|
||||||
|
if (!sound_initialized || handle < 0 || handle >= NUM_CHANNELS)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels_playing[handle] == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
position = voice_get_position(allegro_voices[handle]);
|
||||||
|
if (position < 0) {
|
||||||
|
// finished
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// still playing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Periodically called to update the sound system
|
||||||
|
//
|
||||||
|
|
||||||
|
static void I_Allegro_UpdateSound(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// loop through all channels which have sample, check if they're finished
|
||||||
|
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||||
|
if (channels_playing[i]) {
|
||||||
|
int position = voice_get_position(allegro_voices[i]);
|
||||||
|
if (position < 0) {
|
||||||
|
// finished
|
||||||
|
channels_playing[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void I_Allegro_ShutdownSound(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!sound_initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||||
|
if (channels_playing[i] != NULL) {
|
||||||
|
voice_stop(allegro_voices[i]);
|
||||||
|
channels_playing[i] = NULL;
|
||||||
|
}
|
||||||
|
deallocate_voice(allegro_voices[i]);
|
||||||
|
allegro_voices[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy_sample(dummy_sample);
|
||||||
|
dummy_sample = NULL;
|
||||||
|
|
||||||
|
remove_sound();
|
||||||
|
|
||||||
|
sound_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static boolean I_Allegro_InitSound(boolean _use_sfx_prefix)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
use_sfx_prefix = _use_sfx_prefix;
|
||||||
|
|
||||||
|
// No sounds yet
|
||||||
|
|
||||||
|
for (i=0; i<NUM_CHANNELS; ++i)
|
||||||
|
{
|
||||||
|
channels_playing[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
reserve_voices(NUM_CHANNELS, NUM_MIDI_CHANNELS);
|
||||||
|
|
||||||
|
i = install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, "allegro.cfg");
|
||||||
|
if (i < 0) {
|
||||||
|
printf("install_sound failed: %d \"%s\"\n", i, allegro_error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Allegro sound initialized\n");
|
||||||
|
|
||||||
|
printf("Mixer quality %d\n", get_mixer_quality());
|
||||||
|
printf("Mixer freq %d\n", get_mixer_frequency());
|
||||||
|
printf("Mixer bits %d\n", get_mixer_bits());
|
||||||
|
printf("Mixer channels %d\n", get_mixer_channels());
|
||||||
|
printf("Mixer voices %d\n", get_mixer_voices());
|
||||||
|
printf("Mixer buffer length %d\n", get_mixer_buffer_length());
|
||||||
|
|
||||||
|
// create a dummy sample used to create voices
|
||||||
|
dummy_sample = create_sample(8, 0, 11025, 8);
|
||||||
|
if (dummy_sample == NULL) {
|
||||||
|
printf("Failed to create sound sample: %s\n", allegro_error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||||
|
allegro_voices[i] = allocate_voice(dummy_sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
sound_initialized = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static snddevice_t sound_allegro_devices[] =
|
||||||
|
{
|
||||||
|
SNDDEVICE_SB,
|
||||||
|
SNDDEVICE_PAS,
|
||||||
|
SNDDEVICE_GUS,
|
||||||
|
SNDDEVICE_WAVEBLASTER,
|
||||||
|
SNDDEVICE_SOUNDCANVAS,
|
||||||
|
SNDDEVICE_AWE32,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
sound_module_t DG_sound_module =
|
||||||
|
{
|
||||||
|
sound_allegro_devices,
|
||||||
|
arrlen(sound_allegro_devices),
|
||||||
|
I_Allegro_InitSound,
|
||||||
|
I_Allegro_ShutdownSound,
|
||||||
|
I_Allegro_GetSfxLumpNum,
|
||||||
|
I_Allegro_UpdateSound,
|
||||||
|
I_Allegro_UpdateSoundParams,
|
||||||
|
I_Allegro_StartSound,
|
||||||
|
I_Allegro_StopSound,
|
||||||
|
I_Allegro_SoundIsPlaying,
|
||||||
|
I_Allegro_PrecacheSounds,
|
||||||
|
};
|
||||||
|
|
||||||
@@ -26,6 +26,12 @@
|
|||||||
#include "txt_main.h"
|
#include "txt_main.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
#include <go32.h>
|
||||||
|
#endif // __DJGPP__
|
||||||
|
|
||||||
|
|
||||||
#define ENDOOM_W 80
|
#define ENDOOM_W 80
|
||||||
#define ENDOOM_H 25
|
#define ENDOOM_H 25
|
||||||
|
|
||||||
@@ -76,6 +82,20 @@ void I_Endoom(byte *endoom_data)
|
|||||||
// Shut down text mode screen
|
// Shut down text mode screen
|
||||||
|
|
||||||
TXT_Shutdown();
|
TXT_Shutdown();
|
||||||
|
|
||||||
|
#elif defined(__DJGPP__)
|
||||||
|
|
||||||
|
int y;
|
||||||
|
|
||||||
|
// move cursor to bottom
|
||||||
|
// there's a direct call for moving cursor somewhere but this is simpler to write
|
||||||
|
for (y = 0; y < ENDOOM_H; y++) {
|
||||||
|
puts("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// allegro exit should have been run already and so we should be in text mode again
|
||||||
|
movedata(_my_ds(), (unsigned) endoom_data, _dos_ds, 0xB8000UL, ENDOOM_W * ENDOOM_H * 2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-19
@@ -18,7 +18,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef FEATURE_SOUND
|
#if defined(FEATURE_SOUND) && !defined(__DJGPP__)
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -60,24 +60,6 @@ static music_module_t *music_module = NULL;
|
|||||||
int snd_musicdevice = SNDDEVICE_SB;
|
int snd_musicdevice = SNDDEVICE_SB;
|
||||||
int snd_sfxdevice = SNDDEVICE_SB;
|
int snd_sfxdevice = SNDDEVICE_SB;
|
||||||
|
|
||||||
// Sound modules
|
|
||||||
|
|
||||||
extern void I_InitTimidityConfig(void);
|
|
||||||
#ifdef FEATURE_SOUND
|
|
||||||
extern sound_module_t* DG_sound_module;
|
|
||||||
extern music_module_t* DG_music_module;
|
|
||||||
#endif
|
|
||||||
extern sound_module_t sound_pcsound_module;
|
|
||||||
extern music_module_t music_opl_module;
|
|
||||||
|
|
||||||
// For OPL module:
|
|
||||||
|
|
||||||
extern int opl_io_port;
|
|
||||||
|
|
||||||
// For native music module:
|
|
||||||
|
|
||||||
extern char *timidity_cfg_path;
|
|
||||||
|
|
||||||
// DOS-specific options: These are unused but should be maintained
|
// DOS-specific options: These are unused but should be maintained
|
||||||
// so that the config file can be shared between chocolate
|
// so that the config file can be shared between chocolate
|
||||||
// doom and doom.exe
|
// doom and doom.exe
|
||||||
|
|||||||
@@ -234,5 +234,23 @@ extern char *snd_musiccmd;
|
|||||||
|
|
||||||
void I_BindSoundVariables(void);
|
void I_BindSoundVariables(void);
|
||||||
|
|
||||||
|
// Sound modules
|
||||||
|
|
||||||
|
void I_InitTimidityConfig(void);
|
||||||
|
#ifdef FEATURE_SOUND
|
||||||
|
extern sound_module_t DG_sound_module;
|
||||||
|
extern music_module_t DG_music_module;
|
||||||
|
#endif
|
||||||
|
extern sound_module_t sound_pcsound_module;
|
||||||
|
extern music_module_t music_opl_module;
|
||||||
|
|
||||||
|
// For OPL module:
|
||||||
|
|
||||||
|
extern int opl_io_port;
|
||||||
|
|
||||||
|
// For native music module:
|
||||||
|
|
||||||
|
extern char *timidity_cfg_path;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+18
-1
@@ -22,6 +22,19 @@
|
|||||||
|
|
||||||
#ifdef FEATURE_SOUND
|
#ifdef FEATURE_SOUND
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
|
||||||
|
|
||||||
|
#define SHORT(x) ((signed short) (x))
|
||||||
|
#define LONG(x) ((signed int) (x))
|
||||||
|
|
||||||
|
#define SYS_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
|
#else // __DJGPP__
|
||||||
|
|
||||||
|
|
||||||
#include <SDL_endian.h>
|
#include <SDL_endian.h>
|
||||||
|
|
||||||
// Endianess handling.
|
// Endianess handling.
|
||||||
@@ -55,7 +68,11 @@
|
|||||||
#define doom_wtohs(x) (short int)(x)
|
#define doom_wtohs(x) (short int)(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
|
||||||
|
#endif // __DJGPP__
|
||||||
|
|
||||||
|
|
||||||
|
#else // FEATURE_SOUND
|
||||||
|
|
||||||
#define SHORT(x) ((signed short) (x))
|
#define SHORT(x) ((signed short) (x))
|
||||||
#define LONG(x) ((signed int) (x))
|
#define LONG(x) ((signed int) (x))
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ void I_Quit (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(__MACOSX__)
|
#if !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__)
|
||||||
#define ZENITY_BINARY "/usr/bin/zenity"
|
#define ZENITY_BINARY "/usr/bin/zenity"
|
||||||
|
|
||||||
// returns non-zero if zenity is available
|
// returns non-zero if zenity is available
|
||||||
@@ -347,7 +347,7 @@ static int ZenityErrorBox(char *message)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !defined(_WIN32) && !defined(__MACOSX__) */
|
#endif /* !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__) */
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -448,6 +448,12 @@ void I_Error (char *error, ...)
|
|||||||
message,
|
message,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
#elif defined(__DJGPP__)
|
||||||
|
{
|
||||||
|
printf("%s\n", msgbuf);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
ZenityErrorBox(msgbuf);
|
ZenityErrorBox(msgbuf);
|
||||||
|
|||||||
+34
-8
@@ -75,15 +75,20 @@ static struct FB_ScreenInfo s_Fb;
|
|||||||
int fb_scaling = 1;
|
int fb_scaling = 1;
|
||||||
int usemouse = 0;
|
int usemouse = 0;
|
||||||
|
|
||||||
struct color {
|
|
||||||
uint32_t b:8;
|
#ifdef CMAP256
|
||||||
uint32_t g:8;
|
|
||||||
uint32_t r:8;
|
boolean palette_changed;
|
||||||
uint32_t a:8;
|
struct color colors[256];
|
||||||
};
|
|
||||||
|
#else // CMAP256
|
||||||
|
|
||||||
static struct color colors[256];
|
static struct color colors[256];
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
|
|
||||||
void I_GetEvent(void);
|
void I_GetEvent(void);
|
||||||
|
|
||||||
// The screen buffer; this is modified to draw things to the screen
|
// The screen buffer; this is modified to draw things to the screen
|
||||||
@@ -183,6 +188,13 @@ void I_InitGraphics (void)
|
|||||||
s_Fb.yres = DOOMGENERIC_RESY;
|
s_Fb.yres = DOOMGENERIC_RESY;
|
||||||
s_Fb.xres_virtual = s_Fb.xres;
|
s_Fb.xres_virtual = s_Fb.xres;
|
||||||
s_Fb.yres_virtual = s_Fb.yres;
|
s_Fb.yres_virtual = s_Fb.yres;
|
||||||
|
|
||||||
|
#ifdef CMAP256
|
||||||
|
|
||||||
|
s_Fb.bits_per_pixel = 8;
|
||||||
|
|
||||||
|
#else // CMAP256
|
||||||
|
|
||||||
s_Fb.bits_per_pixel = 32;
|
s_Fb.bits_per_pixel = 32;
|
||||||
|
|
||||||
s_Fb.blue.length = 8;
|
s_Fb.blue.length = 8;
|
||||||
@@ -195,6 +207,7 @@ void I_InitGraphics (void)
|
|||||||
s_Fb.red.offset = 16;
|
s_Fb.red.offset = 16;
|
||||||
s_Fb.transp.offset = 24;
|
s_Fb.transp.offset = 24;
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
printf("I_InitGraphics: framebuffer: x_res: %d, y_res: %d, x_virtual: %d, y_virtual: %d, bpp: %d\n",
|
printf("I_InitGraphics: framebuffer: x_res: %d, y_res: %d, x_virtual: %d, y_virtual: %d, bpp: %d\n",
|
||||||
s_Fb.xres, s_Fb.yres, s_Fb.xres_virtual, s_Fb.yres_virtual, s_Fb.bits_per_pixel);
|
s_Fb.xres, s_Fb.yres, s_Fb.xres_virtual, s_Fb.yres_virtual, s_Fb.bits_per_pixel);
|
||||||
@@ -277,10 +290,17 @@ void I_FinishUpdate (void)
|
|||||||
for (i = 0; i < fb_scaling; i++) {
|
for (i = 0; i < fb_scaling; i++) {
|
||||||
line_out += x_offset;
|
line_out += x_offset;
|
||||||
#ifdef CMAP256
|
#ifdef CMAP256
|
||||||
for (fb_scaling == 1) {
|
if (fb_scaling == 1) {
|
||||||
memcpy(line_out, line_in, SCREENWIDTH); /* fb_width is bigger than Doom SCREENWIDTH... */
|
memcpy(line_out, line_in, SCREENWIDTH); /* fb_width is bigger than Doom SCREENWIDTH... */
|
||||||
} else {
|
} else {
|
||||||
//XXX FIXME fb_scaling support!
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < SCREENWIDTH; j++) {
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < fb_scaling; k++) {
|
||||||
|
line_out[j * fb_scaling + k] = line_in[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
//cmap_to_rgb565((void*)line_out, (void*)line_in, SCREENWIDTH);
|
//cmap_to_rgb565((void*)line_out, (void*)line_in, SCREENWIDTH);
|
||||||
@@ -336,6 +356,12 @@ void I_SetPalette (byte* palette)
|
|||||||
colors[i].g = gammatable[usegamma][*palette++];
|
colors[i].g = gammatable[usegamma][*palette++];
|
||||||
colors[i].b = gammatable[usegamma][*palette++];
|
colors[i].b = gammatable[usegamma][*palette++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CMAP256
|
||||||
|
|
||||||
|
palette_changed = true;
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an RGB value, find the closest matching palette index.
|
// Given an RGB value, find the closest matching palette index.
|
||||||
|
|||||||
@@ -138,6 +138,14 @@ void I_EnableLoadingDisk(void);
|
|||||||
|
|
||||||
void I_EndRead (void);
|
void I_EndRead (void);
|
||||||
|
|
||||||
|
struct color {
|
||||||
|
uint32_t b:8;
|
||||||
|
uint32_t g:8;
|
||||||
|
uint32_t r:8;
|
||||||
|
uint32_t a:8;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern char *video_driver;
|
extern char *video_driver;
|
||||||
extern boolean screenvisible;
|
extern boolean screenvisible;
|
||||||
|
|
||||||
@@ -157,4 +165,11 @@ extern int aspect_ratio_correct;
|
|||||||
extern int show_diskicon;
|
extern int show_diskicon;
|
||||||
extern int diskicon_readbytes;
|
extern int diskicon_readbytes;
|
||||||
|
|
||||||
|
#ifdef CMAP256
|
||||||
|
|
||||||
|
extern boolean palette_changed;
|
||||||
|
extern struct color colors[256];
|
||||||
|
|
||||||
|
#endif // CMAP256
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ char *M_TempFile(char *s)
|
|||||||
{
|
{
|
||||||
char *tempdir;
|
char *tempdir;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__DJGPP__)
|
||||||
|
|
||||||
// Check the TEMP environment variable to find the location.
|
// Check the TEMP environment variable to find the location.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user