Merge pull request #13 from turol/dos
DOS support with Allegro and DJGPP
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
*.o
|
||||
*.obj
|
||||
*.exe
|
||||
*.DS_Store
|
||||
*.log
|
||||
*.user
|
||||
*~
|
||||
.vs/
|
||||
Debug/
|
||||
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"
|
||||
|
||||
uint32_t* DG_ScreenBuffer = 0;
|
||||
pixel_t* DG_ScreenBuffer = NULL;
|
||||
|
||||
void M_FindResponseFile(void);
|
||||
void D_DoomMain (void);
|
||||
|
||||
@@ -4,11 +4,27 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef DOOMGENERIC_RESX
|
||||
#define DOOMGENERIC_RESX 640
|
||||
#endif // DOOMGENERIC_RESX
|
||||
|
||||
#ifndef DOOMGENERIC_RESY
|
||||
#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_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>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(__DJGPP__)
|
||||
|
||||
#define DIR_SEPARATOR '\\'
|
||||
#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"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <go32.h>
|
||||
#endif // __DJGPP__
|
||||
|
||||
|
||||
#define ENDOOM_W 80
|
||||
#define ENDOOM_H 25
|
||||
|
||||
@@ -76,6 +82,20 @@ void I_Endoom(byte *endoom_data)
|
||||
// Shut down text mode screen
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
+1
-19
@@ -18,7 +18,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef FEATURE_SOUND
|
||||
#if defined(FEATURE_SOUND) && !defined(__DJGPP__)
|
||||
#include <SDL_mixer.h>
|
||||
#endif
|
||||
|
||||
@@ -60,24 +60,6 @@ static music_module_t *music_module = NULL;
|
||||
int snd_musicdevice = 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
|
||||
// so that the config file can be shared between chocolate
|
||||
// doom and doom.exe
|
||||
|
||||
@@ -234,5 +234,23 @@ extern char *snd_musiccmd;
|
||||
|
||||
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
|
||||
|
||||
|
||||
+18
-1
@@ -22,6 +22,19 @@
|
||||
|
||||
#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>
|
||||
|
||||
// Endianess handling.
|
||||
@@ -55,7 +68,11 @@
|
||||
#define doom_wtohs(x) (short int)(x)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#endif // __DJGPP__
|
||||
|
||||
|
||||
#else // FEATURE_SOUND
|
||||
|
||||
#define SHORT(x) ((signed short) (x))
|
||||
#define LONG(x) ((signed int) (x))
|
||||
|
||||
@@ -264,7 +264,7 @@ void I_Quit (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(__MACOSX__)
|
||||
#if !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__)
|
||||
#define ZENITY_BINARY "/usr/bin/zenity"
|
||||
|
||||
// returns non-zero if zenity is available
|
||||
@@ -347,7 +347,7 @@ static int ZenityErrorBox(char *message)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !defined(_WIN32) && !defined(__MACOSX__) */
|
||||
#endif /* !defined(_WIN32) && !defined(__MACOSX__) && !defined(__DJGPP__) */
|
||||
|
||||
|
||||
//
|
||||
@@ -448,6 +448,12 @@ void I_Error (char *error, ...)
|
||||
message,
|
||||
NULL);
|
||||
}
|
||||
#elif defined(__DJGPP__)
|
||||
{
|
||||
printf("%s\n", msgbuf);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#else
|
||||
{
|
||||
ZenityErrorBox(msgbuf);
|
||||
|
||||
+34
-8
@@ -75,15 +75,20 @@ static struct FB_ScreenInfo s_Fb;
|
||||
int fb_scaling = 1;
|
||||
int usemouse = 0;
|
||||
|
||||
struct color {
|
||||
uint32_t b:8;
|
||||
uint32_t g:8;
|
||||
uint32_t r:8;
|
||||
uint32_t a:8;
|
||||
};
|
||||
|
||||
#ifdef CMAP256
|
||||
|
||||
boolean palette_changed;
|
||||
struct color colors[256];
|
||||
|
||||
#else // CMAP256
|
||||
|
||||
static struct color colors[256];
|
||||
|
||||
|
||||
#endif // CMAP256
|
||||
|
||||
|
||||
void I_GetEvent(void);
|
||||
|
||||
// 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.xres_virtual = s_Fb.xres;
|
||||
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.blue.length = 8;
|
||||
@@ -195,6 +207,7 @@ void I_InitGraphics (void)
|
||||
s_Fb.red.offset = 16;
|
||||
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",
|
||||
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++) {
|
||||
line_out += x_offset;
|
||||
#ifdef CMAP256
|
||||
for (fb_scaling == 1) {
|
||||
if (fb_scaling == 1) {
|
||||
memcpy(line_out, line_in, SCREENWIDTH); /* fb_width is bigger than Doom SCREENWIDTH... */
|
||||
} 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
|
||||
//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].b = gammatable[usegamma][*palette++];
|
||||
}
|
||||
|
||||
#ifdef CMAP256
|
||||
|
||||
palette_changed = true;
|
||||
|
||||
#endif // CMAP256
|
||||
}
|
||||
|
||||
// Given an RGB value, find the closest matching palette index.
|
||||
|
||||
@@ -138,6 +138,14 @@ void I_EnableLoadingDisk(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 boolean screenvisible;
|
||||
|
||||
@@ -157,4 +165,11 @@ extern int aspect_ratio_correct;
|
||||
extern int show_diskicon;
|
||||
extern int diskicon_readbytes;
|
||||
|
||||
#ifdef CMAP256
|
||||
|
||||
extern boolean palette_changed;
|
||||
extern struct color colors[256];
|
||||
|
||||
#endif // CMAP256
|
||||
|
||||
#endif
|
||||
|
||||
@@ -168,7 +168,7 @@ char *M_TempFile(char *s)
|
||||
{
|
||||
char *tempdir;
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(__DJGPP__)
|
||||
|
||||
// Check the TEMP environment variable to find the location.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user