From 302d0425e0c29dcad25edc3ced9515b05dd64c46 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 29 Sep 2017 23:25:34 +0100 Subject: [PATCH] Incinerated WinCE --- src/Makefile.cfg | 12 - src/d_clisrv.c | 2 - src/d_main.c | 21 +- src/d_netfil.c | 10 +- src/doomdef.h | 17 +- src/doomtype.h | 13 +- src/filesrch.c | 64 +- src/i_tcp.c | 7 +- src/lzf.c | 2 +- src/m_fixed.h | 5 - src/md5.c | 4 +- src/mserv.c | 16 +- src/p_setup.c | 2 +- src/p_spec.c | 4 - src/r_data.c | 2 +- src/s_sound.c | 12 +- src/screen.h | 8 +- src/sdl12/Makefile.cfg | 4 - src/sdl12/SDL_main/SDL_win32_main.c | 74 +- src/sdl12/SRB2CE/Makefile.cfg | 12 - src/sdl12/SRB2CE/SRB2CE.zip | Bin 34234 -> 0 bytes src/sdl12/SRB2CE/cehelp.c | 446 ---- src/sdl12/SRB2CE/cehelp.h | 63 - src/sdl12/endtxt.c | 2 - src/sdl12/i_cdmus.c | 4 - src/sdl12/i_main.c | 10 +- src/sdl12/i_system.c | 70 +- src/sdl12/i_video.c | 54 +- src/sdl12/sdl_sound.c | 13 +- src/w_wad.c | 4 - src/win32ce/GameX.h | 174 -- src/win32ce/SRB2CE.zip | Bin 34234 -> 0 bytes src/win32ce/Srb2win.ico | Bin 372798 -> 0 bytes src/win32ce/afxres.h | 17 - src/win32ce/gapi_c.cpp | 129 - src/win32ce/gapi_c.h | 12 - src/win32ce/gxgapilib.c | 636 ----- src/win32ce/gxgapilib.h | 81 - src/win32ce/midstuff.h | 150 -- src/win32ce/resource.h | 18 - src/win32ce/win_cd.c | 529 ---- src/win32ce/win_dbg.c | 629 ----- src/win32ce/win_dbg.h | 54 - src/win32ce/win_dll.c | 164 -- src/win32ce/win_dll.h | 31 - src/win32ce/win_file.c | 123 - src/win32ce/win_file.h | 19 - src/win32ce/win_main.c | 539 ---- src/win32ce/win_main.h | 55 - src/win32ce/win_net.c | 39 - src/win32ce/win_snd.c | 2406 ------------------ src/win32ce/win_sys.c | 3542 --------------------------- src/win32ce/win_vid.c | 865 ------- src/win32ce/wince_stuff.c | 135 - src/win32ce/wince_stuff.h | 17 - 55 files changed, 52 insertions(+), 11269 deletions(-) delete mode 100644 src/sdl12/SRB2CE/Makefile.cfg delete mode 100644 src/sdl12/SRB2CE/SRB2CE.zip delete mode 100644 src/sdl12/SRB2CE/cehelp.c delete mode 100644 src/sdl12/SRB2CE/cehelp.h delete mode 100644 src/win32ce/GameX.h delete mode 100644 src/win32ce/SRB2CE.zip delete mode 100644 src/win32ce/Srb2win.ico delete mode 100644 src/win32ce/afxres.h delete mode 100644 src/win32ce/gapi_c.cpp delete mode 100644 src/win32ce/gapi_c.h delete mode 100644 src/win32ce/gxgapilib.c delete mode 100644 src/win32ce/gxgapilib.h delete mode 100644 src/win32ce/midstuff.h delete mode 100644 src/win32ce/resource.h delete mode 100644 src/win32ce/win_cd.c delete mode 100644 src/win32ce/win_dbg.c delete mode 100644 src/win32ce/win_dbg.h delete mode 100644 src/win32ce/win_dll.c delete mode 100644 src/win32ce/win_dll.h delete mode 100644 src/win32ce/win_file.c delete mode 100644 src/win32ce/win_file.h delete mode 100644 src/win32ce/win_main.c delete mode 100644 src/win32ce/win_main.h delete mode 100644 src/win32ce/win_net.c delete mode 100644 src/win32ce/win_snd.c delete mode 100644 src/win32ce/win_sys.c delete mode 100644 src/win32ce/win_vid.c delete mode 100644 src/win32ce/wince_stuff.c delete mode 100644 src/win32ce/wince_stuff.h diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 5973648a0..41c5c5238 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -210,7 +210,6 @@ endif #indicate platform and what interface use with -ifndef WINCE ifndef LINUX ifndef FREEBSD ifndef CYGWIN32 @@ -224,7 +223,6 @@ endif endif endif endif -endif #determine the interface directory (where you put all i_*.c) i_cdmus_o=$(OBJDIR)/i_cdmus.o @@ -317,16 +315,6 @@ ifdef MINGW NASMFORMAT=win32 OBJDIR:=$(OBJDIR)/Mingw BIN:=$(BIN)/Mingw -else -ifdef WINCE - INTERFACE=sdl12 - NONX86=1 - PREFIX?=arm-wince-pe - SDL=1 - SDL12=1 - OBJDIR:=$(OBJDIR)/WinCE - BIN:=$(BIN)/WinCE -endif endif endif endif diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 81b84a54d..df2bea972 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -10,9 +10,7 @@ /// \file d_clisrv.c /// \brief SRB2 Network game communication and protocol, all OS independent parts. -#if !defined (UNDER_CE) #include -#endif #ifdef __GNUC__ #include //for unlink #endif diff --git a/src/d_main.c b/src/d_main.c index 2b3ffc0db..5d0dfab37 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -30,14 +30,12 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 #include #include #endif -#if !defined (UNDER_CE) #include -#endif #include "doomdef.h" #include "am_map.h" @@ -800,11 +798,9 @@ static void IdentifyVersion(void) } else { -#ifndef _WIN32_WCE if (getcwd(srb2path, 256) != NULL) srb2waddir = srb2path; else -#endif { srb2waddir = "."; } @@ -953,7 +949,7 @@ void D_SRB2Main(void) boolean autostart = false; // keep error messages until the final flush(stderr) -#if !defined (PC_DOS) && !defined (_WIN32_WCE) && !defined(NOTERMIOS) +#if !defined (PC_DOS) && !defined(NOTERMIOS) if (setvbuf(stderr, NULL, _IOFBF, 1000)) I_OutputMsg("setvbuf didnt work\n"); #endif @@ -975,11 +971,11 @@ void D_SRB2Main(void) // identify the main IWAD file to use IdentifyVersion(); -#if !defined (_WIN32_WCE) && !defined(NOTERMIOS) +#if !defined(NOTERMIOS) setbuf(stdout, NULL); // non-buffered output #endif -#if defined (_WIN32_WCE) //|| defined (_DEBUG) +#if 0 //defined (_DEBUG) devparm = M_CheckParm("-nodebug") == 0; #else devparm = M_CheckParm("-debug") != 0; @@ -1007,11 +1003,6 @@ void D_SRB2Main(void) { #if ((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) I_Error("Please set $HOME to your home directory\n"); -#elif defined (_WIN32_WCE) && 0 - if (dedicated) - snprintf(configfile, sizeof configfile, "/Storage Card/SRB2DEMO/d"CONFIGFILENAME); - else - snprintf(configfile, sizeof configfile, "/Storage Card/SRB2DEMO/"CONFIGFILENAME); #else if (dedicated) snprintf(configfile, sizeof configfile, "d"CONFIGFILENAME); @@ -1419,14 +1410,14 @@ const char *D_Home(void) userhome = M_GetNextParm(); else { -#if !((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__APPLE__) && !defined(_WIN32_WCE) +#if !((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__APPLE__) if (FIL_FileOK(CONFIGFILENAME)) usehome = false; // Let's NOT use home else #endif userhome = I_GetEnv("HOME"); //Alam: my new HOME for srb2 } -#if defined (_WIN32) && !defined(_WIN32_WCE) //Alam: only Win32 have APPDATA and USERPROFILE +#ifdef _WIN32 //Alam: only Win32 have APPDATA and USERPROFILE if (!userhome && usehome) //Alam: Still not? { char *testhome = NULL; diff --git a/src/d_netfil.c b/src/d_netfil.c index 9518433de..90e03041f 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -11,21 +11,17 @@ /// \brief Transfer a file using HSendPacket. #include -#ifndef _WIN32_WCE #ifdef __OS2__ #include #endif // __OS2__ #include -#endif -#if !defined (UNDER_CE) #include -#endif -#if ((defined (_WIN32) && !defined (_WIN32_WCE)) || defined (__DJGPP__)) +#if defined (_WIN32) || defined (__DJGPP__) #include #include -#elif !defined (_WIN32_WCE) +#else #include #include #include @@ -34,7 +30,7 @@ #ifdef __GNUC__ #include #include -#elif defined (_WIN32) && !defined (_WIN32_WCE) +#elif defined (_WIN32) #include #endif #ifdef __DJGPP__ diff --git a/src/doomdef.h b/src/doomdef.h index 892130f06..a49fb0207 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -28,13 +28,11 @@ // Use Mixer interface? #ifdef HAVE_MIXER - //#if !defined(_WIN32_WCE) #define SOUND SOUND_MIXER #define NOHS // No HW3SOUND #ifdef HW3SOUND #undef HW3SOUND #endif - //#endif #endif // Use generic SDL interface. @@ -70,7 +68,7 @@ #endif #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #define ASMCALL __cdecl #else #define ASMCALL @@ -87,13 +85,6 @@ // warning C4152: nonstandard extension, function/data pointer conversion in expression // warning C4213: nonstandard extension used : cast on l-value -#if defined (_WIN32_WCE) && defined (DEBUG) && defined (ARM) -#if defined (ARMV4) || defined (ARMV4I) -//#pragma warning(disable : 1166) -// warning LNK1166: cannot adjust code at offset= -#endif -#endif - #include "doomtype.h" @@ -110,13 +101,11 @@ #include #endif -#if !defined (_WIN32_WCE) #include #include -#endif #include -#if (defined (_WIN32) && !defined (_WIN32_WCE)) || defined (__DJGPP__) +#if defined (_WIN32) || defined (__DJGPP__) #include #endif @@ -381,13 +370,11 @@ enum { }; // Name of local directory for config files and savegames -#if !defined(_WIN32_WCE) #if (((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)) && !defined (__CYGWIN__)) && !defined (__APPLE__) #define DEFAULTDIR ".srb2" #else #define DEFAULTDIR "srb2" #endif -#endif #include "g_state.h" diff --git a/src/doomtype.h b/src/doomtype.h index 796a5ca29..4af899ed0 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -17,7 +17,7 @@ #ifndef __DOOMTYPE__ #define __DOOMTYPE__ -#if defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__)) +#ifdef _WIN32 //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H #include @@ -107,15 +107,6 @@ typedef long ssize_t; #undef strnicmp #define strnicmp(x,y,n) strncasecmp(x,y,n) #endif -#ifdef _WIN32_WCE -#ifndef __GNUC__ - #define stricmp(x,y) _stricmp(x,y) - #define strnicmp _strnicmp -#endif - #define strdup _strdup - #define strupr _strupr - #define strlwr _strlwr -#endif #if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap #define true 1 @@ -167,7 +158,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); //faB: clean that up !! #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward #include "stdbool.h" - #elif defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__)) + #elif defined (_WIN32) #define false FALSE // use windows types #define true TRUE #define boolean BOOL diff --git a/src/filesrch.c b/src/filesrch.c index 1f159d5c0..b4a995154 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -21,11 +21,7 @@ #define RPC_NO_WINDOWS_H #include #endif -#ifdef _WIN32_WCE -#include "sdl12/SRB2CE/cehelp.h" -#else #include -#endif #include #include "filesrch.h" @@ -34,7 +30,7 @@ #include "z_zone.h" #include "m_menu.h" // Addons_option_Onchange -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) +#if defined (_WIN32) && defined (_MSC_VER) #include #include @@ -338,63 +334,6 @@ UINT8 refreshdirmenu = 0; size_t packetsizetally = 0; size_t mainwadstally = 0; -#ifdef _WIN32_WCE -filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, - boolean completepath, int maxsearchdepth) -{ -#ifdef __GNUC__ -//NONE? - startpath = filename = NULL; - wantedmd5sum = NULL; - maxsearchdepth = 0; - completepath = false; -#else - WIN32_FIND_DATA dta; - HANDLE searchhandle = INVALID_HANDLE_VALUE; - const wchar_t wm[4] = L"*.*"; - - //if (startpath) SetCurrentDirectory(startpath); - if (FIL_ReadFileOK(filename)) - { - // checkfilemd5 returns an FS_* value, either FS_FOUND or FS_MD5SUMBAD - return checkfilemd5(filename, wantedmd5sum); - } - ZeroMemory(&dta,sizeof (dta)); - if (maxsearchdepth) - searchhandle = FindFirstFile(wm,&dta); - if (searchhandle != INVALID_HANDLE_VALUE) - { - do - { - if ((dta.cFileName[0]!='.') && (dta.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - //if (SetCurrentDirectory(dta.cFileName)) - { // can fail if we haven't the right - filestatus_t found; - found = filesearch(filename,NULL,wantedmd5sum,completepath,maxsearchdepth-1); - //SetCurrentDirectory(".."); - if (found == FS_FOUND || found == FS_MD5SUMBAD) - { - if (completepath) - strcatbf(filename,(char *)dta.cFileName,"\\"); - FindClose(searchhandle); - return found; - } - } - } - } while (FindNextFile(searchhandle,&dta)==0); - FindClose(searchhandle); - } -#endif - return FS_NOTFOUND; -} - -boolean preparefilemenu(boolean samedepth) -{ - (void)samedepth; - return false; -} -#else filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth) { filestatus_t retval = FS_NOTFOUND; @@ -747,4 +686,3 @@ boolean preparefilemenu(boolean samedepth) return true; } -#endif diff --git a/src/i_tcp.c b/src/i_tcp.c index 9254f5b45..3bbebadf2 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -27,7 +27,7 @@ #define HAVE_IPV6 #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #define USE_WINSOCK #if defined (_WIN64) || defined (HAVE_IPV6) #define USE_WINSOCK2 @@ -164,11 +164,6 @@ static UINT8 UPNP_support = TRUE; // winsock stuff (in winsock a socket is not a file) #define ioctl ioctlsocket #define close closesocket - - #ifdef _WIN32_WCE - #include "sdl12/SRB2CE/cehelp.h" - #endif - #endif #include "i_addrinfo.h" diff --git a/src/lzf.c b/src/lzf.c index ce2bdafc7..f81c3ee0a 100644 --- a/src/lzf.c +++ b/src/lzf.c @@ -157,7 +157,7 @@ typedef const u8 *LZF_STATE[1 << (HLOG)]; * lzfP.h ends here. lzf_d.c follows. */ -#if AVOID_ERRNO || defined(_WIN32_WCE) +#if AVOID_ERRNO # define SET_ERRNO(n) #else # include diff --git a/src/m_fixed.h b/src/m_fixed.h index 773823988..8050324db 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -20,11 +20,6 @@ #include #endif -// Was this just for the #define USEASM? -//#ifdef _WIN32_WCE -//#include "sdl12/SRB2CE/cehelp.h" -//#endif - /*! \brief bits of the fraction */ diff --git a/src/md5.c b/src/md5.c index 8031650e6..66d563666 100644 --- a/src/md5.c +++ b/src/md5.c @@ -19,9 +19,7 @@ #endif #include -#ifndef _WIN32_WCE #include -#endif #ifdef _MSC_VER #pragma warning(disable : 4127) #endif @@ -30,7 +28,7 @@ #include #else #ifndef HAVE_MEMCPY - #if !((defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__)) && !defined (__APPLE__) + #if !(defined (_WIN32) && !defined (__CYGWIN__)) && !defined (__APPLE__) #define memcpy(d, s, n) bcopy ((s), (d), (n)) #endif #endif diff --git a/src/mserv.c b/src/mserv.c index deda97a5f..efbf89359 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -16,9 +16,7 @@ #include #endif -#if !defined (UNDER_CE) #include -#endif #if (defined (NOMD5) || defined (NOMSERV)) && !defined (NONET) #define NONET @@ -30,7 +28,7 @@ #define HAVE_IPV6 #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #define RPC_NO_WINDOWS_H #ifdef HAVE_IPV6 #include @@ -55,7 +53,7 @@ #include // timeval,... (TIMEOUT) #include -#endif // _WIN32/_WIN32_WCE +#endif // _WIN32 #ifdef __OS2__ #include @@ -76,10 +74,6 @@ #include "m_argv.h" // Alam is going to kill me <3 #include "m_misc.h" // GetRevisionString() -#ifdef _WIN32_WCE -#include "sdl12/SRB2CE/cehelp.h" -#endif - #include "i_addrinfo.h" // ================================ DEFINITIONS =============================== @@ -168,13 +162,13 @@ typedef struct #endif // win32 or djgpp -#if defined (_WIN32) || defined (_WIN32_WCE) || defined (__DJGPP__) +#if defined (_WIN32) || defined (__DJGPP__) #define ioctl ioctlsocket #define close closesocket #ifdef WATTCP #define strerror strerror_s #endif -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #undef errno #define errno h_errno // some very strange things happen when not using h_error #endif @@ -200,7 +194,7 @@ static enum { MSCS_NONE, MSCS_WAITING, MSCS_REGISTERED, MSCS_FAILED } con_state static INT32 msnode = -1; UINT16 current_port = 0; -#if (defined (_WIN32) || defined (_WIN32_WCE) || defined (_WIN32)) && !defined (NONET) +#if defined (_WIN32) && !defined (NONET) typedef SOCKET SOCKET_TYPE; #define BADSOCKET INVALID_SOCKET #define ERRSOCKET (SOCKET_ERROR) diff --git a/src/p_setup.c b/src/p_setup.c index 60f456ce3..83c9348c9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -65,7 +65,7 @@ #include "lua_script.h" #include "lua_hook.h" -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #include #include #endif diff --git a/src/p_spec.c b/src/p_spec.c index e06926f30..03643a708 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -40,11 +40,7 @@ #endif // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog -#ifdef _WIN32_WCE -#define AVOID_ERRNO -#else #include -#endif mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs diff --git a/src/r_data.c b/src/r_data.c index 791d90d94..c578012d1 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -25,7 +25,7 @@ #include "v_video.h" // pMasterPalette #include "dehacked.h" -#if defined (_WIN32) || defined (_WIN32_WCE) +#ifdef _WIN32 #include // alloca(sizeof) #endif diff --git a/src/s_sound.c b/src/s_sound.c index a34b6362f..4d041dae4 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -62,9 +62,7 @@ consvar_t sndserver_arg = {"sndserver_arg", "-quiet", CV_SAVE, NULL, 0, NULL, NU #define SURROUND #endif -#if defined (_WIN32_WCE) -consvar_t cv_samplerate = {"samplerate", "11025", 0, CV_Unsigned, NULL, 11025, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? -#elif defined(_WINDOWS) +#ifdef _WINDOWS consvar_t cv_samplerate = {"samplerate", "44100", 0, CV_Unsigned, NULL, 44100, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? #else consvar_t cv_samplerate = {"samplerate", "22050", 0, CV_Unsigned, NULL, 22050, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking? @@ -91,11 +89,7 @@ static void Captioning_OnChange(void) consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_OnOff, Captioning_OnChange, 0, NULL, NULL, 0, 0, NULL}; // number of channels available -#if defined (_WIN32_WCE) -consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; -#else consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; -#endif static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1377,10 +1371,6 @@ static boolean S_DigMusic(const char *mname, boolean looping) void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) { -#if defined (_WIN32_WCE) - S_ClearSfx(); -#endif - if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled)) return; diff --git a/src/screen.h b/src/screen.h index 80bbb4146..4d4fbb88b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -15,20 +15,16 @@ #include "command.h" -#if (defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__) -#if defined (_WIN32_WCE) && defined (__GNUC__) -#include -#else +#if defined (_WIN32) && !defined (__CYGWIN__) #define RPC_NO_WINDOWS_H #include -#endif #define DNWH HWND #else #define DNWH void * // unused in DOS version #endif // quickhack for V_Init()... to be cleaned up -#if defined (_WIN32_WCE) || defined (NOPOSTPROCESSING) +#ifdef NOPOSTPROCESSING #define NUMSCREENS 2 #else #define NUMSCREENS 5 diff --git a/src/sdl12/Makefile.cfg b/src/sdl12/Makefile.cfg index a29b95d6b..2366a5ac2 100644 --- a/src/sdl12/Makefile.cfg +++ b/src/sdl12/Makefile.cfg @@ -14,10 +14,6 @@ ifdef PANDORA include sdl12/SRB2Pandora/Makefile.cfg endif #ifdef PANDORA -ifdef WINCE -include sdl12/SRB2CE/Makefile.cfg -endif #ifef WINCE - ifdef CYGWIN32 include sdl12/MakeCYG.cfg endif #ifdef CYGWIN32 diff --git a/src/sdl12/SDL_main/SDL_win32_main.c b/src/sdl12/SDL_main/SDL_win32_main.c index 46b20d0bd..6f3ae370f 100644 --- a/src/sdl12/SDL_main/SDL_win32_main.c +++ b/src/sdl12/SDL_main/SDL_win32_main.c @@ -13,17 +13,8 @@ #include /* For _alloca() */ #include - -#ifdef _WIN32_WCE -# define DIR_SEPERATOR TEXT("\\") -# define _tgetcwd(str,len) wcscpy(str,TEXT("")) -# define setbuf(f,b) -# define setvbuf(w,x,y,z) -# define _tremove(x) DeleteFile(x) -#else # define DIR_SEPERATOR TEXT("/") # include -#endif /* Include the SDL main definition header */ #ifdef _MSC_VER @@ -44,45 +35,14 @@ #endif /* main */ /* The standard output files */ -//#ifdef _WIN32_WCE -//#define STDOUT_FILE TEXT("/Storage Card/SRB2DEMO/stdout.txt") -//#define STDERR_FILE TEXT("/Storage Card/SRB2DEMO/stderr.txt") -//#else #define STDOUT_FILE TEXT("stdout.txt") #define STDERR_FILE TEXT("stderr.txt") -//#endif #ifndef NO_STDIO_REDIRECT static TCHAR stdoutPath[MAX_PATH]; static TCHAR stderrPath[MAX_PATH]; #endif -#if defined(_WIN32_WCE) && _WIN32_WCE < 300 -/* seems to be undefined in Win CE although in online help */ -#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) - -/* seems to be undefined in Win CE although in online help */ -char *strrchr(char *str, int c) -{ - char *p; - - /* Skip to the end of the string */ - p=str; - while (*p) - p++; - - /* Look for the given character */ - while ( (p >= str) && (*p != (CHAR)c) ) - p--; - - /* Return NULL if character not found */ - if ( p < str ) { - p = NULL; - } - return p; -} -#endif /* _WIN32_WCE < 300 */ - /* Parse a command line buffer into arguments */ static int ParseCommandLine(char *cmdline, char **argv) { @@ -191,7 +151,7 @@ static void __cdecl cleanup_output(void) #endif } -#if defined(_MSC_VER) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) /* The VC++ compiler needs main defined */ #define console_main main #endif @@ -268,23 +228,14 @@ int console_main(int argc, char *argv[]) } /* This is where execution begins [windowed apps] */ -#ifdef _WIN32_WCE -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) -#else int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) -#endif { HINSTANCE handle; int Result = -1; char **argv; int argc; LPSTR cmdline; -#ifdef _WIN32_WCE - size_t nLen; - LPTSTR bufp; -#else LPSTR bufp; -#endif #ifndef NO_STDIO_REDIRECT FILE *newfp; #endif @@ -307,7 +258,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) /* Redirect standard input and standard output */ newfp = _tfreopen(stdoutPath, TEXT("w"), stdout); -#ifndef _WIN32_WCE if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stdout) stdout = _tfopen(stdoutPath, TEXT("w")); @@ -318,13 +268,11 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) } #endif } -#endif /* _WIN32_WCE */ _tgetcwd( stderrPath, sizeof( stderrPath ) ); _tcscat( stderrPath, DIR_SEPERATOR STDERR_FILE ); newfp = _tfreopen(stderrPath, TEXT("w"), stderr); -#ifndef _WIN32_WCE if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stderr) stderr = _tfopen(stderrPath, TEXT("w")); @@ -335,26 +283,11 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) } #endif } -#endif /* _WIN32_WCE */ setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ setbuf(stderr, NULL); /* No buffering */ #endif /* !NO_STDIO_REDIRECT */ -#ifdef _WIN32_WCE - nLen = wcslen(szCmdLine)+128+1; - bufp = (wchar_t *)alloca(nLen*2); - wcscpy (bufp, TEXT("\"")); - GetModuleFileName(NULL, bufp+1, 128-3); - wcscpy (bufp+wcslen(bufp), TEXT("\" ")); - wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); - nLen = wcslen(bufp)+1; - cmdline = (char *)alloca(nLen); - if ( cmdline == NULL ) { - return OutOfMemory(); - } - WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); -#else szCmdLine = NULL; /* Grab the command line (use alloca() on Windows) */ bufp = GetCommandLineA(); @@ -363,7 +296,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) return OutOfMemory(); } strcpy(cmdline, bufp); -#endif /* Parse it into argv and argc */ argc = ParseCommandLine(cmdline, NULL); @@ -382,18 +314,14 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) #endif /* Run the main program (after a little SDL initialization) */ -#ifndef _WIN32_WCE __try -#endif { Result = console_main(argc, argv); } -#ifndef _WIN32_WCE __except ( RecordExceptionInfo(GetExceptionInformation())) { SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here. } -#endif #ifdef BUGTRAP } /* BT failure clause. */ diff --git a/src/sdl12/SRB2CE/Makefile.cfg b/src/sdl12/SRB2CE/Makefile.cfg deleted file mode 100644 index 8d4ae3e48..000000000 --- a/src/sdl12/SRB2CE/Makefile.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile.cfg for WinCE with GCC -# - -OPTS+=-D_WIN32_WCE -D_UNICODE -SDL_CFLAGS?= -SDL_LDFLAGS?= -NOHS=1 -NOHW=1 -NONET=1 -NOMIXER=1 -NOPNG=1 diff --git a/src/sdl12/SRB2CE/SRB2CE.zip b/src/sdl12/SRB2CE/SRB2CE.zip deleted file mode 100644 index 3ac8530dcb124cbda512a7d469da933c3fc974bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34234 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 HAkhB;OHxy? diff --git a/src/sdl12/SRB2CE/cehelp.c b/src/sdl12/SRB2CE/cehelp.c deleted file mode 100644 index 7c5efdee9..000000000 --- a/src/sdl12/SRB2CE/cehelp.c +++ /dev/null @@ -1,446 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2004 by Sonic Team Jr. -// -// 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: -// stub and replacement "ANSI" C functions for use under Windows CE -// -//----------------------------------------------------------------------------- - -#include "../../doomdef.h" -#include "cehelp.h" - -#define _SEC_IN_MINUTE 60 -#define _SEC_IN_HOUR 3600 -#define _SEC_IN_DAY 86400 - -static const int DAYS_IN_MONTH[12] = -{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) - -static const int _DAYS_BEFORE_MONTH[12] = -{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - -#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) -#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) - -char *strerror(int ecode) -{ - static char buff[1024 + 1]; - DWORD dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buff[0], 1024, NULL); - return buff; -} - -int unlink( const char *filename ) -{ - return remove(filename); -} - -int remove( const char *path ) -{ - return DeleteFileA(path)-1; -} - -int rename( const char *oldname, const char *newname ) -{ - return MoveFileA(oldname, newname)!=0; -} - -static inline void STToTM(const SYSTEMTIME *st, struct tm *tm) -{ - if (!st || !tm) return; - tm->tm_sec = st->wSecond; - tm->tm_min = st->wMinute; - tm->tm_hour = st->wHour; - tm->tm_mday = st->wDay; - tm->tm_mon = st->wMonth - 1; - tm->tm_year = st->wYear - 1900; - tm->tm_wday = st->wDayOfWeek; - tm->tm_yday = 0; - tm->tm_isdst = 0; -} - -time_t time(time_t *T) -{ - time_t returntime; - SYSTEMTIME st; - struct tm stft; - GetSystemTime(&st); - STToTM(&st,&stft); - returntime = mktime(&stft); - if (T) *T = returntime; - return returntime; -} - -static inline UINT64 TTtoFT(const time_t wt, FILETIME *ft) -{ - UINT64 temptime = wt; // FILETIME: 1/(10^7) secs since January 1, 1601 - temptime *= 10000000; // time_t : 1 secs since January 1, 1970 - // 369 years * 365 days * 24 hours * 60 mins * 60 secs * 10 - // 123 leaps days * 24 hours * 60 mins * 60 secs * 10 - temptime += 116444736000000000; - if (ft) CopyMemory(ft,&temptime,sizeof (ULARGE_INTEGER)); - return temptime; -} - -static struct tm cehelptm; - -struct tm * localtime(const time_t *CLOCK) -{ - SYSTEMTIME st; - FILETIME stft; - UINT64 ftli = 0; - if (CLOCK) ftli = TTtoFT(*CLOCK, &stft); - if (ftli) - FileTimeToSystemTime(&stft,&st); - else - GetSystemTime(&st); - STToTM(&st,&cehelptm); - if (st.wYear >= 1970) - return &cehelptm; - else - return NULL; -} - -static void validate_structure (struct tm *tim_p) // from newlib -{ - div_t res; - int days_in_feb = 28; - - /* calculate time & date to account for out of range values */ - if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) - { - res = div (tim_p->tm_sec, 60); - tim_p->tm_min += res.quot; - if ((tim_p->tm_sec = res.rem) < 0) - { - tim_p->tm_sec += 60; - --tim_p->tm_min; - } - } - - if (tim_p->tm_min < 0 || tim_p->tm_min > 59) - { - res = div (tim_p->tm_min, 60); - tim_p->tm_hour += res.quot; - if ((tim_p->tm_min = res.rem) < 0) - { - tim_p->tm_min += 60; - --tim_p->tm_hour; - } - } - - if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) - { - res = div (tim_p->tm_hour, 24); - tim_p->tm_mday += res.quot; - if ((tim_p->tm_hour = res.rem) < 0) - { - tim_p->tm_hour += 24; - --tim_p->tm_mday; - } - } - - if (tim_p->tm_mon > 11) - { - res = div (tim_p->tm_mon, 12); - tim_p->tm_year += res.quot; - if ((tim_p->tm_mon = res.rem) < 0) - { - tim_p->tm_mon += 12; - --tim_p->tm_year; - } - } - - if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) - days_in_feb = 29; - - if (tim_p->tm_mday <= 0) - { - while (tim_p->tm_mday <= 0) - { - if (--tim_p->tm_mon == -1) - { - tim_p->tm_year--; - tim_p->tm_mon = 11; - days_in_feb = - ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? - 29 : 28); - } - tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); - } - } - else - { - while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) - { - tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); - if (++tim_p->tm_mon == 12) - { - tim_p->tm_year++; - tim_p->tm_mon = 0; - days_in_feb = - ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? - 29 : 28); - } - } - } -} - -time_t mktime (struct tm *tim_p) // from newlib -{ - time_t tim = 0; - long days = 0; - int year; - - /* validate structure */ - validate_structure (tim_p); - - /* compute hours, minutes, seconds */ - tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + - (tim_p->tm_hour * _SEC_IN_HOUR); - - /* compute days in year */ - days += tim_p->tm_mday - 1; - days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; - if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) - days++; - - /* compute day of the year */ - tim_p->tm_yday = days; - - if (tim_p->tm_year > 10000 - || tim_p->tm_year < -10000) - { - return (time_t) -1; - } - - /* compute days in other years */ - if (tim_p->tm_year > 70) - { - for (year = 70; year < tim_p->tm_year; year++) - days += _DAYS_IN_YEAR (year); - } - else if (tim_p->tm_year < 70) - { - for (year = 69; year > tim_p->tm_year; year--) - days -= _DAYS_IN_YEAR (year); - days -= _DAYS_IN_YEAR (year); - } - - /* compute day of the week */ - if ((tim_p->tm_wday = (days + 4) % 7) < 0) - tim_p->tm_wday += 7; - - /* compute total seconds */ - tim += (days * _SEC_IN_DAY); - - return tim; -} - -#undef WINAPI -#define WINAPI __stdcall //__delcspec(dllexport) - -#ifdef _MSC_VER -//#pragma warning(disable : 4273) -#endif - - -static __forceinline int STRtoWSTR(LPCSTR lpMultiByteStr, int cchMultiByte, - LPWSTR lpWideCharStr, int cchWideChar) -{ - return MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpMultiByteStr, - cchMultiByte,lpWideCharStr,cchWideChar); -} - -static __forceinline int WSTRtoSTR(LPCWSTR lpWideCharStr, int cchWideChar, - LPSTR lpMultiByteStr, int cbMultiByte) -{ - return WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK|WC_SEPCHARS, - lpWideCharStr,cchWideChar,lpMultiByteStr,cbMultiByte,NULL,NULL); -} - -DWORD WINAPI FormatMessageA( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - LPSTR lpBuffer, - DWORD nSize, - va_list *Arguments) -{ - const int nSizeW = STRtoWSTR(lpBuffer,nSize,NULL,0); - int nSizeF = 0; - LPWSTR lpBufferW = alloca(sizeof (wchar_t)*nSizeW); - LPWSTR lpSourceW = NULL; - - if (!lpBufferW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - ZeroMemory(lpBuffer,nSize); - return nSizeF; - } - - if (dwFlags & FORMAT_MESSAGE_FROM_STRING) - { - const int sLen = STRtoWSTR(lpSource, -1, NULL, 0); - lpSourceW = alloca(sizeof (wchar_t)*sLen); - - if (lpSourceW) - STRtoWSTR(lpSource, -1, lpSourceW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return nSizeF; - } - } - - if (lpSourceW) - nSizeF = FormatMessageW(dwFlags, lpSourceW, dwMessageId, dwLanguageId, - lpBufferW, nSizeW, Arguments); - else - nSizeF = FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, - lpBufferW, nSizeW, Arguments); - - return WSTRtoSTR(lpBufferW, nSizeF, lpBuffer, nSize); -} - -BOOL WINAPI DeleteFileA( - LPCSTR lpFileName) -{ - const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); - LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpFileNameW) - STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - return DeleteFileW(lpFileNameW); -} - -BOOL WINAPI MoveFileA( - LPCSTR lpExistingFileName, - LPCSTR lpNewFileName -) -{ - const int sLen1 = STRtoWSTR(lpExistingFileName, -1, NULL, 0); - LPWSTR lpExistingFileNameW = alloca(sizeof (wchar_t)*sLen1); - - const int sLen2 = STRtoWSTR(lpNewFileName, -1, NULL, 0); - LPWSTR lpNewFileNameW = alloca(sizeof (wchar_t)*sLen2); - - - if (!lpExistingFileNameW || !lpNewFileNameW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - STRtoWSTR(lpExistingFileName, -1, lpExistingFileNameW, sLen1); - STRtoWSTR(lpNewFileName, -1, lpNewFileNameW, sLen2); - - return MoveFileW(lpExistingFileNameW, lpNewFileNameW); -} - - -HANDLE WINAPI CreateFileA( - LPCSTR lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile) -{ - const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); - LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpFileNameW) - STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return INVALID_HANDLE_VALUE; - } - - return CreateFileW(lpFileNameW, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); -} - -BOOL WINAPI CreateDirectoryA( - LPCSTR lpPathName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) -{ - const int sLen = STRtoWSTR(lpPathName, -1, NULL, 0); - LPWSTR lpPathNameW = alloca(sizeof (wchar_t)*sLen); - - if (lpPathNameW) - STRtoWSTR(lpPathName, -1, lpPathNameW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - return CreateDirectoryW(lpPathNameW, lpSecurityAttributes); -} - -int WINAPI MessageBoxA( - HWND hWnd , - LPCSTR lpText, - LPCSTR lpCaption, - UINT uType) -{ - const int sLen1 = STRtoWSTR(lpText, -1, NULL, 0); - LPWSTR lpTextW = alloca(sizeof (wchar_t)*sLen1); - - const int sLen2 = STRtoWSTR(lpCaption, -1, NULL, 0); - LPWSTR lpCaptionW = alloca(sizeof (wchar_t)*sLen2); - - - if (!lpTextW || !lpCaptionW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - - STRtoWSTR(lpText, -1, lpTextW, sLen1); - STRtoWSTR(lpCaption, -1, lpCaptionW, sLen2); - - return MessageBoxW(hWnd, lpTextW, lpCaptionW, uType); -} - -VOID WINAPI OutputDebugStringA( - LPCSTR lpOutputString) -{ - const int sLen = STRtoWSTR(lpOutputString, -1, NULL, 0); - LPWSTR lpOutputStringW = alloca(sizeof (wchar_t)*sLen); - - if (lpOutputStringW) - STRtoWSTR(lpOutputString, -1, lpOutputStringW, sLen); - else - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return; - } - - OutputDebugStringW(lpOutputStringW); -} diff --git a/src/sdl12/SRB2CE/cehelp.h b/src/sdl12/SRB2CE/cehelp.h deleted file mode 100644 index bc265b058..000000000 --- a/src/sdl12/SRB2CE/cehelp.h +++ /dev/null @@ -1,63 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 2004 by Sonic Team Jr. -// -// 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: -// stub and replacement "ANSI" C functions for use under Windows CE -// -//----------------------------------------------------------------------------- - -#ifndef __I_WINCE__ -#define __I_WINCE__ - -#ifdef USEASMCE -#define USEASM // Remline if NASM doesn't work on x86 targets -#endif - -char *strerror(int ecode); -int access(const char *path, int amode); -int unlink( const char *filename ); -int remove( const char *path ); -int rename( const char *oldname, const char *newname ); -//CreateDirectoryEx( const char *currectpath, const char *path,SECURITY_ATTRIBUTES) - -#ifndef _TIME_T_DEFINED -typedef long time_t; /* time value */ -#define _TIME_T_DEFINED /* avoid multiple def's of time_t */ -#endif - -time_t time(time_t *T); - -#ifndef __GNUC__ -#ifndef _TM_DEFINED -struct tm { - int tm_sec; /* seconds after the minute - [0,59] */ - int tm_min; /* minutes after the hour - [0,59] */ - int tm_hour; /* hours since midnight - [0,23] */ - int tm_mday; /* day of the month - [1,31] */ - int tm_mon; /* months since January - [0,11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday - [0,6] */ - int tm_yday; /* days since January 1 - [0,365] */ - int tm_isdst; /* daylight savings time flag */ - }; -#define _TM_DEFINED -#endif - -struct tm * localtime(const time_t *CLOCK); - -time_t mktime (struct tm *tim_p); -#endif - -#endif diff --git a/src/sdl12/endtxt.c b/src/sdl12/endtxt.c index f8e315591..1e72ca9a8 100644 --- a/src/sdl12/endtxt.c +++ b/src/sdl12/endtxt.c @@ -33,7 +33,6 @@ void ShowEndTxt(void) { -#ifndef _WIN32_WCE INT32 i; UINT16 j, att = 0; INT32 nlflag = 1; @@ -232,5 +231,4 @@ void ShowEndTxt(void) printf("\n"); Z_Free(data); -#endif } diff --git a/src/sdl12/i_cdmus.c b/src/sdl12/i_cdmus.c index 805e6f498..27b664887 100644 --- a/src/sdl12/i_cdmus.c +++ b/src/sdl12/i_cdmus.c @@ -19,10 +19,6 @@ #ifdef HAVE_SDL -#if defined (_WIN32_WCE) -#define NOSDLCD -#endif - #include #ifndef NOSDLCD diff --git a/src/sdl12/i_main.c b/src/sdl12/i_main.c index 2a0ea785a..7d14ca9e5 100644 --- a/src/sdl12/i_main.c +++ b/src/sdl12/i_main.c @@ -58,7 +58,7 @@ FILE *logstream = NULL; typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 static inline VOID MakeCodeWritable(VOID) { #ifdef USEASM // Disable write-protection of code segment @@ -121,9 +121,7 @@ int main(int argc, char **argv) logdir = D_Home(); #ifdef LOGMESSAGES -#if defined(_WIN32_WCE) - logstream = fopen(va("%s.log",argv[0]), "a"); -#elif defined (DEFAULTDIR) +#ifdef DEFAULTDIR if (logdir) logstream = fopen(va("%s/"DEFAULTDIR"/srb2log.txt",logdir), "a"); else @@ -134,7 +132,6 @@ int main(int argc, char **argv) //I_OutputMsg("I_StartupSystem() ...\n"); I_StartupSystem(); #ifdef _WIN32 -#ifndef _WIN32_WCE { p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent"); if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) @@ -146,11 +143,8 @@ int main(int argc, char **argv) LoadLibraryA("exchndl.dll"); } } -#endif prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); -#ifndef _WIN32_WCE MakeCodeWritable(); -#endif #endif // startup SRB2 CONS_Printf("%s", M_GetText("Setting up SRB2...\n")); diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index a907c7f90..e759449a7 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -20,15 +20,12 @@ /// \file /// \brief SRB2 system stuff for SDL -#ifndef _WIN32_WCE #include -#endif #ifdef _WIN32 #define RPC_NO_WINDOWS_H #include #include "../doomtype.h" -#ifndef _WIN32_WCE typedef BOOL (WINAPI *p_GetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); typedef DWORD (WINAPI *p_timeGetTime) (void); @@ -39,7 +36,6 @@ typedef HANDLE (WINAPI *p_GetCurrentProcess) (VOID); typedef BOOL (WINAPI *p_GetProcessAffinityMask) (HANDLE, PDWORD_PTR, PDWORD_PTR); typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #endif -#endif #include #include #include @@ -53,7 +49,7 @@ typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #endif #include -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 #include #endif @@ -111,7 +107,7 @@ typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #include #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 #define HAVE_MUMBLE #define WINMUMBLE #elif defined (HAVE_SHM) @@ -119,10 +115,6 @@ typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #endif #endif // NOMUMBLE -#ifdef _WIN32_WCE -#include "SRB2CE/cehelp.h" -#endif - #ifndef O_BINARY #define O_BINARY 0 #endif @@ -136,11 +128,6 @@ typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #define DEFAULTSEARCHPATH1 "/usr/local/games" #define DEFAULTSEARCHPATH2 "/usr/games" #define DEFAULTSEARCHPATH3 "/usr/local" -#elif defined (_WIN32_WCE) -#define NOCWD -#define NOHOME -#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2DEMO" -#define DEFAULTSEARCHPATH1 "\\Storage Card" #elif defined (_WIN32) #define DEFAULTWADLOCATION1 "c:\\games\\srb2" #define DEFAULTWADLOCATION2 "\\games\\srb2" @@ -275,7 +262,7 @@ static void signal_handler(INT32 num) } #endif -#if defined (NDEBUG) && !defined (_WIN32_WCE) +#if defined (NDEBUG) FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { signal(num, SIG_DFL); //default signal action @@ -495,7 +482,7 @@ void I_GetConsoleEvents(void) (void)d; } -#elif defined (_WIN32) && !defined (_WIN32_WCE) +#elif defined (_WIN32) static BOOL I_ReadyConsole(HANDLE ci) { DWORD gotinput; @@ -709,7 +696,7 @@ void I_OutputMsg(const char *fmt, ...) } #endif -#if defined (_WIN32) && !defined(_WIN32_WCE) +#ifdef _WIN32 #ifdef DEBUGFILE if (debugfile != stderr) #endif @@ -1966,7 +1953,7 @@ ticcmd_t *I_BaseTiccmd2(void) return &emptycmd2; } -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 static HMODULE winmm = NULL; static DWORD starttickcount = 0; // hack for win2k time bug static p_timeGetTime pfntimeGetTime = NULL; @@ -2045,12 +2032,7 @@ tic_t I_GetTime (void) ticks -= basetime; ticks = (ticks*TICRATE); - -#if 0 //#ifdef _WIN32_WCE - ticks = (ticks/10); -#else ticks = (ticks/1000); -#endif return (tic_t)ticks; } @@ -2061,7 +2043,7 @@ tic_t I_GetTime (void) // void I_StartupTimer(void) { -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 // for win2k time bug if (M_CheckParm("-gettickcount")) { @@ -2184,7 +2166,7 @@ static boolean shutdowning = false; void I_Error(const char *error, ...) { va_list argptr; -#if defined (MAC_ALERT) || defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__)) +#if defined (MAC_ALERT) || defined (_WIN32) char buffer[8192]; #endif @@ -2222,11 +2204,10 @@ void I_Error(const char *error, ...) va_end(argptr); // 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. MacShowAlert("Recursive Error", buffer, "Quit", NULL, NULL); -#elif defined (_WIN32) || (defined (_WIN32_WCE)) && !defined (__GNUC__) +#elif defined (_WIN32) va_start(argptr,error); vsprintf(buffer, error, argptr); va_end(argptr); -#ifndef _WIN32_WCE { HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); DWORD bytesWritten; @@ -2238,7 +2219,6 @@ void I_Error(const char *error, ...) WriteFile(co, buffer, (DWORD)strlen(buffer), &bytesWritten, NULL); } } -#endif OutputDebugStringA(buffer); MessageBoxA(vid.WndParent, buffer, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); #else @@ -2387,7 +2367,7 @@ void I_GetDiskFreeSpace(INT64 *freespace) } *freespace = stfs.f_bavail * stfs.f_bsize; #endif -#elif defined (_WIN32) && !defined (_WIN32_WCE) +#elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; ULARGE_INTEGER usedbytes, lfreespace; @@ -2418,7 +2398,6 @@ void I_GetDiskFreeSpace(INT64 *freespace) char *I_GetUserName(void) { -#if !defined (_WIN32_WCE) static char username[MAXPLAYERNAME]; char *p; #ifdef _WIN32 @@ -2450,7 +2429,6 @@ char *I_GetUserName(void) if (strcmp(username, "") != 0) return username; -#endif return NULL; // dummy for platform independent version } @@ -2459,7 +2437,7 @@ INT32 I_mkdir(const char *dirname, INT32 unixright) //[segabor] #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) return mkdir(dirname, unixright); -#elif defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__)) +#elif defined (_WIN32) UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... return CreateDirectoryA(dirname, NULL); #else @@ -2473,9 +2451,6 @@ char *I_GetEnv(const char *name) { #ifdef NEED_SDL_GETENV return SDL_getenv(name); -#elif defined(_WIN32_WCE) - (void)name; - return NULL; #else return getenv(name); #endif @@ -2485,8 +2460,6 @@ INT32 I_PutEnv(char *variable) { #ifdef NEED_SDL_GETENV return SDL_putenv(variable); -#elif defined(_WIN32_WCE) - return ((variable)?-1:0); #else return putenv(variable); #endif @@ -2597,15 +2570,6 @@ static const char *locateWad(void) if (((envstr = I_GetEnv("SRB2WADDIR")) != NULL) && isWadPathOk(envstr)) return envstr; -#if defined(_WIN32_WCE) - // examine argv[0] - strcpy(returnWadPath, myargv[0]); - pathonly(returnWadPath); - I_PutEnv(va("HOME=%s",returnWadPath)); - if (isWadPathOk(returnWadPath)) - return returnWadPath; -#endif - #ifndef NOCWD I_OutputMsg(",."); // examine current dir @@ -2703,9 +2667,9 @@ const char *I_LocateWad(void) if (waddir) { // change to the directory where we found srb2.srb -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 SetCurrentDirectoryA(waddir); -#elif !defined (_WIN32_WCE) +#else if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif @@ -2803,7 +2767,7 @@ UINT32 I_GetFreeMem(UINT32 *total) if (total) *total = totalKBytes << 10; return freeKBytes << 10; -#elif defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__)) +#elif defined (_WIN32) MEMORYSTATUS info; info.dwLength = sizeof (MEMORYSTATUS); @@ -2831,7 +2795,7 @@ UINT32 I_GetFreeMem(UINT32 *total) const CPUInfoFlags *I_CPUInfo(void) { -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 static CPUInfoFlags WIN_CPUInfo; SYSTEM_INFO SI; p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"); @@ -2892,7 +2856,7 @@ const CPUInfoFlags *I_CPUInfo(void) #endif } -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 static void CPUAffinity_OnChange(void); static consvar_t cv_cpuaffinity = {"cpuaffinity", "-1", CV_SAVE | CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -2935,7 +2899,7 @@ static void CPUAffinity_OnChange(void) void I_RegisterSysCommands(void) { -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 GetAffinityFuncs(); CV_RegisterVar(&cv_cpuaffinity); #endif diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index fa7e31e8d..1e6f76c10 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -18,10 +18,7 @@ /// \brief SRB2 graphics stuff for SDL #include - -#ifndef _WIN32_WCE #include -#endif #ifdef _MSC_VER #pragma warning(disable : 4214 4244) @@ -49,7 +46,7 @@ #ifdef HAVE_IMAGE #include "SDL_image.h" -#elseif !defined (_WIN32_WCE) +#else #define LOAD_XPM //I want XPM! #include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so #define HAVE_IMAGE //I have SDL_Image, sortof @@ -94,11 +91,7 @@ #endif // maximum number of windowed modes (see windowedModes[][]) -#if defined (_WIN32_WCE) -#define MAXWINMODES (1) -#else #define MAXWINMODES (27) -#endif /** \brief */ @@ -141,25 +134,16 @@ static SDL_Rect **modeList = NULL; static Uint8 BitsPerPixel = 16; static Uint16 realwidth = BASEVIDWIDTH; static Uint16 realheight = BASEVIDHEIGHT; -#ifdef _WIN32_WCE -static const Uint32 surfaceFlagsW = SDL_HWPALETTE; //Can't handle WinCE changing sides -#else static const Uint32 surfaceFlagsW = SDL_HWPALETTE/*|SDL_RESIZABLE*/; -#endif static const Uint32 surfaceFlagsF = SDL_HWPALETTE|SDL_FULLSCREEN; static SDL_bool mousegrabok = SDL_TRUE; #define HalfWarpMouse(x,y) SDL_WarpMouse((Uint16)(x/2),(Uint16)(y/2)) -#if defined (_WIN32_WCE) -static SDL_bool videoblitok = SDL_TRUE; -#else static SDL_bool videoblitok = SDL_FALSE; -#endif static SDL_bool exposevideo = SDL_FALSE; // windowed video modes from which to choose from. static INT32 windowedModes[MAXWINMODES][2] = { -#if !defined (_WIN32_WCE) {1920,1200}, // 1.60,6.00 {1680,1050}, // 1.60,5.25 {1600,1200}, // 1.33,5.00 @@ -186,17 +170,12 @@ static INT32 windowedModes[MAXWINMODES][2] = { 416, 312}, // 1.33,1.30 { 400, 300}, // 1.33,1.25 { 320, 240}, // 1.33,1.00 -#endif { 320, 200}, // 1.60,1.00 }; static void SDLSetMode(INT32 width, INT32 height, INT32 bpp, Uint32 flags) { const char *SDLVD = I_GetEnv("SDL_VIDEODRIVER"); -#ifdef _WIN32_WCE - if (bpp < 16) - bpp = 16; // 256 mode poo -#endif #ifdef FILTERS bpp = Setupf2x(width, height, bpp); #endif @@ -233,17 +212,6 @@ static INT32 SDLatekey(SDLKey sym) { INT32 rc = sym + 0x80; -#ifdef _WIN32_WCE - if (sym == SDLK_KP8) - sym = SDLK_UP; - else if (sym == SDLK_KP4) - sym = SDLK_LEFT; - else if (sym == SDLK_KP6) - sym = SDLK_RIGHT; - else if (sym == SDLK_KP2) - sym = SDLK_DOWN; -#endif - switch (sym) { case SDLK_LEFT: @@ -586,7 +554,6 @@ static void VID_Command_Info_f (void) static void VID_Command_ModeList_f(void) { -#if !defined (_WIN32_WCE) INT32 i; #ifdef HWRENDER if (rendermode == render_opengl) @@ -620,7 +587,6 @@ static void VID_Command_ModeList_f(void) modeList[modeNum]->h); } CONS_Printf("%s", M_GetText("None\n")); -#endif } static void VID_Command_Mode_f (void) @@ -641,7 +607,7 @@ static void VID_Command_Mode_f (void) setmodeneeded = modenum+1; // request vid mode change } -#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) +#ifdef RPC_NO_WINDOWS_H static VOID MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(hWnd); @@ -962,7 +928,6 @@ void I_GetEvent(void) SDLJoyRemap(&event); if (event.type != ev_console) D_PostEvent(&event); break; -#ifndef _WIN32_WCE case SDL_QUIT: if (!sdlquit) { @@ -970,8 +935,7 @@ void I_GetEvent(void) M_QuitResponse('y'); } break; -#endif -#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) +#ifdef RPC_NO_WINDOWS_H case SDL_SYSWMEVENT: MainWndproc(inputEvent.syswm.msg->hwnd, inputEvent.syswm.msg->msg, @@ -1492,9 +1456,7 @@ static void SDLWMSet(void) SetFocus(vid.WndParent); ShowWindow(vid.WndParent, SW_SHOW); } -#ifndef _WIN32_WCE SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); -#endif #endif SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE); } @@ -1513,9 +1475,6 @@ static void* SDLGetDirect(void) INT32 VID_SetMode(INT32 modeNum) { -#ifdef _WIN32_WCE - (void)modeNum; -#else SDLdoUngrabMouse(); vid.recalc = true; BitsPerPixel = (Uint8)cv_scr_depth.value; @@ -1614,7 +1573,6 @@ INT32 VID_SetMode(INT32 modeNum) #if 0 // broken if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) vid.height = (INT32)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match -#endif #endif I_StartupMouse(); @@ -1696,11 +1654,7 @@ void I_StartupGraphics(void) #endif // Window title -#ifdef _WIN32_WCE - SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2"); -#else SDL_WM_SetCaption("SRB2: Starting up", "SRB2"); -#endif // Window icon #ifdef HAVE_IMAGE @@ -1744,7 +1698,7 @@ void I_StartupGraphics(void) // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); -#if 1 //#ifdef _WIN32_WCE +#if 1 // vid.width = BASEVIDWIDTH; vid.height = BASEVIDHEIGHT; #else diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c index 232c73c44..a4b3635ca 100644 --- a/src/sdl12/sdl_sound.c +++ b/src/sdl12/sdl_sound.c @@ -49,7 +49,7 @@ #define MIX_CHANNELS 8 #endif -#if defined (_WIN32) && !defined (_WIN32_WCE) +#ifdef _WIN32 #include #elif defined (__GNUC__) #include @@ -85,19 +85,11 @@ // mixing buffer, and the samplerate of the raw data. // Needed for calling the actual sound output. -#if defined (_WIN32_WCE) -#define NUM_CHANNELS MIX_CHANNELS -#else #define NUM_CHANNELS MIX_CHANNELS*4 -#endif #define INDEXOFSFX(x) ((sfxinfo_t *)x - S_sfx) -#if defined (_WIN32_WCE) -static Uint16 samplecount = 512; //Alam: .5KB samplecount at 11025hz is 46.439909297052154195011337868481ms of buffer -#else static Uint16 samplecount = 1024; //Alam: 1KB samplecount at 22050hz is 46.439909297052154195011337868481ms of buffer -#endif typedef struct chan_struct { @@ -167,9 +159,6 @@ static SDL_bool canlooping = SDL_TRUE; #if SDL_MIXER_VERSION_ATLEAST(1,2,7) #define USE_RWOPS // ok, USE_RWOPS is in here -#if defined (_WIN32_WCE) //|| defined(_WIN32) -#undef USE_RWOPS -#endif #endif #if SDL_MIXER_VERSION_ATLEAST(1,2,10) diff --git a/src/w_wad.c b/src/w_wad.c index 22e1836c7..2aa0a6316 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -18,11 +18,7 @@ #define ZWAD #ifdef ZWAD -#ifdef _WIN32_WCE -#define AVOID_ERRNO -#else #include -#endif #include "lzf.h" #endif diff --git a/src/win32ce/GameX.h b/src/win32ce/GameX.h deleted file mode 100644 index 241fdd5be..000000000 --- a/src/win32ce/GameX.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - - GameX - WindowsCE Game Library for High Performance. - - Copyright (C) 1999 Hayes C. Haugen, all rights reserved. - - */ - -/* - * Need better way for host app to keep track of direct vs blit - drawing. Right now GetFBAddress() is the way to do it. - - - */ - - -#pragma once -#include // For VK codes. - -// Defines - -// display property flags - -const unsigned long kfDPGrey = 0x0001; -const unsigned long kfDPGrey2Bit = 0x0002; -const unsigned long kfDPGrey4Bit = 0x0004; -const unsigned long kfDPColor = 0x0008; -const unsigned long kfDPColor8Bit = 0x0010; -const unsigned long kfDPColor16Bit = 0x0020; -const unsigned long kfDPColor24Bit = 0x0040; -const unsigned long kfDPColor32Bit = 0x0080; -const unsigned long kfDPFormatNormal = 0x0100; // fb start is upper left, inc goes across -const unsigned long kfDPFormatRot270 = 0x0200; // fb start is lower left, inc goes up - -// Machine property flags - -const unsigned long kfMPPSPC = 0x0001; // Palm Sized PC - 240 x 320 -const unsigned long kfMPPSPC1 = 0x0002; // 1st gen pspc -const unsigned long kfMPPSPC2 = 0x0004; // Wyverns -const unsigned long kfMPHPC = 0x0008; // Handheld PC -const unsigned long kfMPHPC1 = 0x0010; // HPC 1, 480 x 240 -const unsigned long kfMPHPC2 = 0x0020; // HPC 2, 640 x 240 -const unsigned long kfMPHPC3 = 0x0040; // HPC Pro, 640 x 240, big keys -const unsigned long kfMPPro = 0x0080; // -const unsigned long kfMPAutoPC = 0x0100; -const unsigned long kfMPHasKeyboard = 0x0200; -const unsigned long kfMPHasMouse = 0x0400; -const unsigned long kfMPHasRumble = 0x0800; -const unsigned long kfMPHasTouch = 0x1000; - -// Rotations - -const int kiRotate0 = 0; // no rotation -const int kiRotate90 = 1; // 90 degrees clockwise -const int kiRotate180 = 2; // 180 degrees clockwise (upside down, Rotate 0 flipped) -const int kiRotate270 = 3; // 270 degrees clockwise (Rotate 1 flipped) - -class GameX { -public: - HWND SetButtonNotificationWindow(HWND hWnd); - GameX(); - ~GameX(); - - bool OpenGraphics(); - bool OpenSound(); - bool OpenButtons(HWND hwndButtonNotify); // Window that will get button messages or NULL if you just want to use GetAsyncKeyState(); - bool CloseGraphics(); - bool CloseSound(); - bool CloseButtons(); - - bool IsColor(); - bool IsPSPC(); - bool IsHPC(); - bool IsHPCPro(); - bool HasMouse(); - bool HasKeyboard(); // better than inferring from hpc/pspc/etc. - bool HasRumble(); - bool HasTouch(); // for completeness. At least 1 doesn't. - - int IsForeground(); - bool Suspend(); // release buttons, don't draw, etc. - bool Resume(); // regrab buttons, etc. - - bool BeginDraw(); - bool EndDraw(); - bool FindFrameBuffer(); - void * GetFBAddress(); // simple way to get things that makes code - long GetFBModulo(); // more readable. - long GetFBBpp(); - bool GetScreenRect(RECT * prc); - unsigned long GetDisplayProperties(); - - bool GetButton(int VK); // buttons init themselves on first button call?? - unsigned short GetDefaultButtonID(long id, long rotate); // gets the best button for use as specified by need and rotation - bool ReleaseButton(int VK); - bool BeginDetectButtons(); // grabs all buttons so user can indicate a button in a config dialog - bool EndDetectButtons(); // releases all buttons (except GetButton() ones) - - bool Rumble(); - bool Backlight(bool fOn); -private: -// LRESULT CALLBACK TaskBarWndProc(HWND hWnd, UINT message, WPARAM uParam, LPARAM lParam); - -private: - int m_iMP; // index into amp table for current machine. - void * m_pvFrameBuffer; - long m_cbFBModulo; // count of bytes to next line - unsigned long m_ffMachineProperties; - unsigned long m_ffDisplayProperties; - int m_cBitsPP; - - long m_dwPrevMode; // for Begin/EndDraw() - bool m_fActive; // true if active (resume), false if inactive (suspend). - - HWND m_hwndTaskbar; // Taskbar is official cap, change TaskBar's -}; - - -/* - -kmtCasioE10 -kmtCasioE11 -kmtCasioE15 -kmtCasioE55 -kmtCasioE100 -kmtLGPhenomII - -stuff for memory size and presence/absence of CF - -// Rotations that make sense for this device or default rotation: - -Rotate0 // no rotation -Rotate1 // 90 degrees clockwise -Rotate2 // 180 degrees clockwise (upside down, Rotate 0 flipped) -Rotate3 // 270 degrees clockwise (Rotate 1 flipped) - -kmtAccessNone // no direct framebuffer access -kmtAccess1 // write to fixed address -kmtAccess2 // find framebuffer memory aperture in GWES.EXE memory space. - -OriginUpperLeft -OriginUpperRight -OriginLowerRight -OriginLowerLeft - -MappedHorizontal // increasing fb address goes across screen -MappedVertical // increasing fb address goes up/down screen (Compaq) - -A machine entry: -=========================================== - machine kmtCasioE10, - type kmtPSPC | kmtPSPC1, - displaytype kmtGrey | kmtGrey2Bit | kmtAccess1, - pvFrameBuffer 0xAA000000, - cbFBModulo 1024 // count of bytes to next line - cbppFB 2, // bits per pixel - cxDisp 240, - cyDisp 320, - format OriginUpperLeft, MappedHorizontal - - rotate0 // for rotate mode 0, these are the best keys - vkUp VK_UP - vkDown VK_DOWN - vkLeft 0xC1 - vkRight 0xC2 - vkA 0xC3 - vkB 0 - rotate1 - vkUp 0xC1 - vkDown 0xC2 - vkLeft VK_DOWN - ... - ...*/ - diff --git a/src/win32ce/SRB2CE.zip b/src/win32ce/SRB2CE.zip deleted file mode 100644 index 3ac8530dcb124cbda512a7d469da933c3fc974bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34234 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 HAkhB;OHxy? diff --git a/src/win32ce/Srb2win.ico b/src/win32ce/Srb2win.ico deleted file mode 100644 index 700276fd4b9ac2810a6981eb054921f3708c702b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372798 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 G1OE?SzcGja diff --git a/src/win32ce/afxres.h b/src/win32ce/afxres.h deleted file mode 100644 index 7f5245404..000000000 --- a/src/win32ce/afxres.h +++ /dev/null @@ -1,17 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief needed if mfc not installed (if I remember well) diff --git a/src/win32ce/gapi_c.cpp b/src/win32ce/gapi_c.cpp deleted file mode 100644 index 60c7adfa2..000000000 --- a/src/win32ce/gapi_c.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include - -#define _USE_GAPI_ - - -#ifndef _USE_GAPI_ - #include "GameX.h" - -struct GXDisplayProperties -{ - DWORD cxWidth; - DWORD cyHeight; - long cbxPitch; - long cbyPitch; - long cBPP; - DWORD ffFormat; -}; - -#define kfPalette 0x10 // Pixel values are indexes into a palette -#define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel - - - GameX* gx = new GameX; -#else - #include "gx.h" -#endif - -extern "C" -{ - #include "gapi_c.h" -} - -extern "C" int GXOPENDISPLAY(HWND hWnd, DWORD dwFlags) -{ - #ifndef _USE_GAPI_ - if(!gx) - return 0; - - //gx->OpenSound(); - if(!gx->OpenGraphics()) - { - delete gx; - gx = 0; - return 0; - } - - return TRUE; - - #else - return GXOpenDisplay(hWnd,dwFlags); - #endif -} - -extern "C" int GXCLOSEDISPLAY() -{ - #ifndef _USE_GAPI_ - gx->CloseGraphics(); - return TRUE; - #else - return GXCloseDisplay(); - #endif -} - -extern "C" void * GXBEGINDRAW() -{ - #ifndef _USE_GAPI_ - if(gx->BeginDraw()) - return gx->GetFBAddress(); - - return NULL; - #else - return GXBeginDraw(); - #endif -} - -extern "C" int GXENDDRAW() -{ - #ifndef _USE_GAPI_ - return gx->EndDraw(); - #else - return GXEndDraw(); - #endif - -} - -extern "C" struct GXDisplayProperties GXGETDISPLAYPROPERTIES() -{ - #ifndef _USE_GAPI_ - RECT r; - GXDisplayProperties gxdp; - - gxdp.cbyPitch = gx->GetFBModulo(); - gxdp.cBPP = gx->GetFBBpp(); - gxdp.cbxPitch = (gxdp.cBPP >> 3); - - gx->GetScreenRect(&r); - gxdp.cxWidth = (r.right - r.left); - gxdp.cyHeight = (r.bottom - r.top); - - if(gxdp.cBPP = 16) - gxdp.ffFormat = kfDirect565; - else if(gxdp.cBPP = 8) - gxdp.ffFormat = kfPalette; - - return gxdp; - - #else - return GXGetDisplayProperties(); - #endif -} - -extern "C" int GXSUSPEND() -{ - #ifndef _USE_GAPI_ - return gx->Suspend(); - #else - return GXSuspend(); - #endif -} - -extern "C" int GXRESUME() -{ - #ifndef _USE_GAPI_ - return gx->Resume(); - #else - return GXResume(); - #endif -} \ No newline at end of file diff --git a/src/win32ce/gapi_c.h b/src/win32ce/gapi_c.h deleted file mode 100644 index 40e7799ff..000000000 --- a/src/win32ce/gapi_c.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef GAPI_H -#define GAPI_H - -int GXOPENDISPLAY(HWND hWnd, DWORD dwFlags); -int GXCLOSEDISPLAY(); -void * GXBEGINDRAW(); -int GXENDDRAW(); -struct GXDisplayProperties GXGETDISPLAYPROPERTIES(); -int GXSUSPEND(); -int GXRESUME(); - -#endif \ No newline at end of file diff --git a/src/win32ce/gxgapilib.c b/src/win32ce/gxgapilib.c deleted file mode 100644 index 8ff57092d..000000000 --- a/src/win32ce/gxgapilib.c +++ /dev/null @@ -1,636 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief Zak Larue-Buckley's GX and GAPI library v1.0 - -#include "../doomdef.h" -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include -#include -#include "../i_system.h" -#include "dx_error.h" - -#include "fabdxlib.h" - -#define NT4COMPAT //always defined, always compatible - - -// globals - -IDirectDraw2* DDr2 = NULL; -IDirectDrawSurface* ScreenReal = NULL; // DirectDraw primary surface -IDirectDrawSurface* ScreenVirtual = NULL; // DirectDraw back surface -IDirectDrawPalette* DDPalette = NULL; // The primary surface palette -static IDirectDrawClipper *windclip = NULL; // clipper for windowed mode - -BOOL bAppFullScreen; // true for fullscreen exclusive mode, - -int windowPosX = 0; // current position in windowed mode -int windowPosY = 0; - -int ScreenWidth; -int ScreenHeight; -BOOL ScreenLocked; // Screen surface is being locked -int ScreenPitch; // offset from one line to the next -LPBYTE ScreenPtr; // memory of the surface - - -// -// CreateNewSurface -// -static inline IDirectDrawSurface* CreateNewSurface(int dwWidth, - int dwHeight, - int dwSurfaceCaps) -{ - DDSURFACEDESC ddsd; - HRESULT hr; - LPDIRECTDRAWSURFACE psurf; - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; - - ddsd.ddsCaps.dwCaps = dwSurfaceCaps; - - ddsd.dwHeight = dwHeight; - ddsd.dwWidth = dwWidth; - - hr = IDirectDraw2_CreateSurface (DDr2, &ddsd, &psurf, NULL); - - if (hr == DD_OK) - { - //DDCOLORKEY ddck; - IDirectDrawSurface_Restore(psurf); - - //hr = IDirectDrawSurface_GetColorKey(DDCKEY_SRCBLT, &ddck); - //psurf->SetColorKey(DDCKEY_SRCBLT, &ddck); - } - else - psurf = NULL; - - return psurf; -} - -// -// wow! from 320x200x8 up to 1600x1200x32 thanks Banshee! :) -// -static HRESULT WINAPI myEnumModesCallback (LPDDSURFACEDESC surf, LPVOID lpContext) -{ - APPENUMMODESCALLBACK pfnContext = lpContext; - - if (pfnContext) pfnContext(surf->dwWidth, - surf->dwHeight,surf->ddpfPixelFormat. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(1). -#endif - dwRGBBitCount - ); - - /*CONS_Printf ("%dx%dx%d bpp %d refresh\n", - surf->dwWidth, - surf->dwHeight, - surf->ddpfPixelFormat.dwRGBBitCount, - surf->dwRefreshRate);*/ - - return DDENUMRET_OK; -} - - -// -// Application call here to enumerate display modes -// -BOOL EnumDirectDrawDisplayModes (APPENUMMODESCALLBACK appFunc) -{ - LPVOID lpappFunc = appFunc; - - if (DDr2 == NULL) - return FALSE; - - // enumerate display modes - // Carl: DirectX 3.x apparently does not support VGA modes. Who cares. :) - // faB: removed DDEDM_REFRESHRATES, detects too many modes, plus we don't care of refresh rate. - if (bDX0300) - IDirectDraw2_EnumDisplayModes (DDr2, 0 /*| DDEDM_REFRESHRATES*/, - NULL, lpappFunc, myEnumModesCallback); - else - IDirectDraw2_EnumDisplayModes (DDr2, DDEDM_STANDARDVGAMODES /*| DDEDM_REFRESHRATES*/, - NULL, lpappFunc, myEnumModesCallback); - return TRUE; -} - - -// -// Create the DirectDraw object for later -// -BOOL CreateDirectDrawInstance (VOID) -{ - HRESULT hr; - IDirectDraw* DDr; - IDirectDraw** rp = &DDr; - IDirectDraw2** rp2 = &DDr2; - LPVOID *tp = (LPVOID *)rp2; - - // - // create an instance of DirectDraw object - // - if (FAILED(hr = DirectDrawCreate(NULL, rp, NULL))) - I_Error("DirectDrawCreate FAILED: %s", DXErrorToString(hr)); - - // change interface to IDirectDraw2 - if (FAILED(hr = IDirectDraw_QueryInterface (DDr, &IID_IDirectDraw2, tp))) - I_Error("Failed to query DirectDraw2 interface: %s", DXErrorToString(hr)); - - // release the interface we don't need - IDirectDraw_Release (DDr); - return TRUE; -} - - -// -// - returns true if DirectDraw was initialized properly -// -int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr) -{ - DDSURFACEDESC ddsd; // DirectDraw surface description for allocating - DDSCAPS ddscaps; - HRESULT ddrval; - - DWORD dwStyle; - RECT rect; - - // enumerate directdraw devices - //if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL))) - // I_Error("Error with DirectDrawEnumerate"); - - if (!DDr2) - CreateDirectDrawInstance(); - - // remember what screen mode we are in - bAppFullScreen = fullScr; - ScreenHeight = height; - ScreenWidth = width; - - if (bAppFullScreen) - { - // Change window attributes - dwStyle = WS_POPUP | WS_VISIBLE; - SetWindowLong (appWin, GWL_STYLE, dwStyle); - SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | - SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); - - // Get exclusive mode - ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE | - DDSCL_FULLSCREEN | - DDSCL_ALLOWREBOOT); - if (ddrval != DD_OK) - I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval)); - - // Switch from windows desktop to fullscreen - -#ifdef NT4COMPAT - ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0); -#else - ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE); -#endif - if (ddrval != DD_OK) - I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval)); - - // This is not really needed, except in certain cases. One case - // is while using MFC. When the desktop is initally at 16bpp, a mode - // switch to 8bpp somehow causes the MFC window to not fully initialize - // and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will - // ensure that the window is initialized properly after a mode switch. - - ShowWindow(appWin, SW_SHOW); - - // Create the primary surface with 1 back buffer. Always zero the - // DDSURFACEDESC structure and set the dwSize member! - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - - // for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to - // the visible surface, in both cases we have a visible (or 'real') surface, and a hidden - // (or 'virtual', or 'backbuffer') surface. - ddsd.dwBackBufferCount = 1; - - ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); - if (ddrval != DD_OK) - I_Error("CreateSurface Primary Screen FAILED"); - - // Get a pointer to the back buffer - - ddscaps.dwCaps = DDSCAPS_BACKBUFFER; - ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual); - if (ddrval != DD_OK) - I_Error("GetAttachedSurface FAILED"); - } - else - { - rect.top = 0; - rect.left = 0; - rect.bottom = height-1; - rect.right = width-1; - - // Change window attributes - - dwStyle = GetWindowStyle(appWin); - dwStyle &= ~WS_POPUP; - dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; - - SetWindowLong(appWin, GWL_STYLE, dwStyle); - - // Resize the window so that the client area is the requested width/height - - AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL, - GetWindowExStyle(appWin)); - - // Just in case the window was moved off the visible area of the - // screen. - - SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left, - rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | - SWP_NOACTIVATE); - - SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); - - // Exclusive mode is normal since it's in windowed mode and needs - // to cooperate with GDI - - ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL); - if (ddrval != DD_OK) - I_Error("SetCooperativeLevel FAILED"); - - // Always zero the DDSURFACEDESC structure and set the dwSize member! - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - // Create the primary surface - - ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); - if (ddrval != DD_OK) - I_Error("CreateSurface Primary Screen FAILED"); - - // Create a back buffer for offscreen rendering, this will be used to - // blt to the primary - - ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN | - DDSCAPS_SYSTEMMEMORY); - if (ScreenVirtual == NULL) - I_Error("CreateSurface Secondary Screen FAILED"); - - /// \todo get the desktop bit depth, and build a lookup table - /// for quick conversions of 8bit color indexes 0-255 to desktop colors - /// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format - /// when blit virtual to real, convert pixels through lookup table.. - - // Use a clipper object for clipping when in windowed mode - // (make sure our drawing doesn't affect other windows) - - ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0); - if (ddrval != DD_OK) - I_Error("CreateClipper FAILED"); - - // Associate the clipper with the window. - ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin); - if (ddrval != DD_OK) - I_Error("Clipper -> SetHWnd FAILED"); - - // Attach the clipper to the surface. - ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip); - if (ddrval != DD_OK) - I_Error("PrimaryScreen -> SetClipperClipper FAILED"); - } - - return TRUE; -} - - -// -// Free all memory -// -VOID CloseDirectDraw (VOID) -{ - ReleaseChtuff(); - if (DDr2) - { - IDirectDraw2_Release(DDr2); - DDr2 = NULL; - } -} - - -// -// Release DirectDraw stuff before display mode change -// -VOID ReleaseChtuff (VOID) -{ - if (!DDr2) - return; - if (windclip) - { - IDirectDrawClipper_Release(windclip); - windclip = NULL; - } - if (DDPalette) - { - IDirectDrawPalette_Release(DDPalette); - DDPalette = NULL; - } - // If the app is fullscreen, the back buffer is attached to the - // primary. Releasing the primary buffer will also release any - // attached buffers, so explicitly releasing the back buffer is not - // necessary. - - if (!bAppFullScreen && ScreenVirtual) - { - IDirectDrawSurface_Release(ScreenVirtual); // release hidden surface - ScreenVirtual = NULL; - } - if (ScreenReal) - { - IDirectDrawSurface_Release(ScreenReal); // and attached backbuffers for bAppFullScreen mode - ScreenReal = NULL; - } -} - - -// -// Clear the surface to color -// -VOID ClearSurface(IDirectDrawSurface* surface, int color) -{ - DDBLTFX ddbltfx; - - // Use the blter to do a color fill to clear the back buffer - ddbltfx.dwSize = sizeof (ddbltfx); - ddbltfx. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(5). -#endif - dwFillColor = color; - IDirectDrawSurface_Blt(surface,NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - -} - -// -// Flip the real page with virtual page -// - in bAppFullScreen mode, do page flipping -// - in windowed mode, copy the hidden surface to the visible surface -// -// waitflip : if not 0, wait for page flip to end -BOOL ScreenFlip(int waitflip) -{ - HRESULT hr; - RECT rect; - - waitflip = 0; - if (bAppFullScreen) - { - //hr = IDirectDrawSurface_GetFlipStatus (ScreenReal, DDGFS_); - - // In full-screen exclusive mode, do a hardware flip. - hr = IDirectDrawSurface_Flip(ScreenReal, NULL, DDFLIP_WAIT); //return immediately - - // If the surface was lost, restore it. - if (hr == DDERR_SURFACELOST) - { - IDirectDrawSurface_Restore(ScreenReal); - - // The restore worked, so try the flip again. - hr = IDirectDrawSurface_Flip(ScreenReal, 0, DDFLIP_WAIT); - } - } - else - { - rect.left = windowPosX; - rect.top = windowPosY; - rect.right = windowPosX + ScreenWidth - 1; - rect.bottom = windowPosY + ScreenHeight - 1; - - // Copy the back buffer to front. - hr = IDirectDrawSurface_Blt(ScreenReal, &rect, ScreenVirtual, 0, DDBLT_WAIT, 0); - - if (hr != DD_OK) - { - // If the surfaces were lost, restore them. - if (IDirectDrawSurface_IsLost(ScreenReal) == DDERR_SURFACELOST) - IDirectDrawSurface_Restore(ScreenReal); - - if (IDirectDrawSurface_IsLost(ScreenVirtual) == DDERR_SURFACELOST) - IDirectDrawSurface_Restore(ScreenVirtual); - - // Retry the copy. - hr = IDirectDrawSurface_Blt(ScreenReal,&rect, ScreenVirtual, 0, DDBLT_WAIT, 0); - } - } - - if (hr != DD_OK) - I_Error("ScreenFlip() : couldn't Flip surfaces"); - - return FALSE; -} - -// -// Print a text to the surface -// -VOID TextPrint(int x, int y, LPCSTR message) -{ - HRESULT hr; - HDC hdc = NULL; - - // Get the device context handle. - hr = IDirectDrawSurface_GetDC(ScreenVirtual,&hdc); - if (hr != DD_OK) - return; - - // Write the message. - SetBkMode(hdc, TRANSPARENT); - SetTextColor(hdc, RGB(255, 255, 255)); - TextOutA(hdc, x, y, message, (int)strlen(message)); - - // Release the device context. - hr = IDirectDrawSurface_ReleaseDC(ScreenVirtual,hdc); -} - -// -// Lock surface before multiple drawings by hand, for speed -// -boolean LockScreen(VOID) -{ - DDSURFACEDESC ddsd; - HRESULT ddrval; - - ZeroMemory(&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - - // attempt to Lock the surface - ddrval = IDirectDrawSurface_Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL); - - // Always, always check for errors with DirectX! - // If the surface was lost, restore it. - if (ddrval == DDERR_SURFACELOST) - { - ddrval = IDirectDrawSurface_Restore(ScreenReal); - - // now retry to get the lock - ddrval = IDirectDrawSurface_Lock(ScreenVirtual, NULL, &ddsd, DDLOCK_WAIT, NULL); - } - - if (ddrval == DD_OK) - { - ScreenLocked = TRUE; - ScreenPtr = (LPBYTE)ddsd.lpSurface; - ScreenPitch = ddsd. -#ifdef DUMMYUNIONNAMEN - DUMMYUNIONNAMEN(1). -#endif - lPitch; - } - else - { - ScreenLocked = FALSE; - ScreenPtr = NULL; - ScreenPitch = 0; - //I_Error("LockScreen() : couldn't restore the surface."); - return false; - } - return true; -} - -// -// Unlock surface -// -VOID UnlockScreen(VOID) -{ - if (DD_OK != IDirectDrawSurface_Unlock(ScreenVirtual,NULL)) - I_Error("Couldn't UnLock the renderer!"); - - ScreenLocked = FALSE; - ScreenPtr = NULL; - ScreenPitch = 0; -} - -// Blit virtual screen to real screen -//faB: note: testing 14/03/1999, see if it is faster than memcopy of virtual to -/* -static LPDIRECTDRAWSURFACE lpDDS = NULL; -VOID BlitScreen(VOID) -{ - HRESULT hr; - - if (!lpDDS) - I_Error("lpDDS NULL"); - - hr = IDirectDrawSurface_BltFast(ScreenVirtual, - 0, 0, // Upper left xy of destination - lpDDS, // Source surface - NULL, // Source rectangle = entire surface - DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); - if (FAILED(hr)) - I_Error("BltFast FAILED"); -} - -VOID MakeScreen(int width, int height, BYTE* lpSurface) -{ - HRESULT hr; - DDSURFACEDESC ddsd; - - // Initialize the surface description. - ZeroMemory (&ddsd, sizeof ddsd); - ZeroMemory (&ddsd.ddpfPixelFormat, sizeof (DDPIXELFORMAT)); - ddsd.dwSize = sizeof ddsd; - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | //DDSD_LPSURFACE | - DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_CAPS; - ddsd.dwWidth = width; - ddsd.dwHeight= height; - ddsd.lPitch = width; - ddsd.lpSurface = lpSurface; - ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; - - // Set up the pixel format for 8-bit - ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags= DDPF_RGB | DDPF_PALETTEINDEXED8; - ddsd.ddpfPixelFormat.dwRGBBitCount = 8; - - // - ddsd.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8; - ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000; - ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00; - ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF; - - // Create the surface - hr = IDirectDraw2_CreateSurface(DDr2, &ddsd, &lpDDS, NULL); - if (FAILED(hr)) - I_Error("MakeScreen FAILED: %s",DDError(hr)); - //ddsd.lpSurface = lpSurface; -} -*/ - -// -// Create a palette object -// -VOID CreateDDPalette (PALETTEENTRY* colorTable) -{ - HRESULT ddrval; - ddrval = IDirectDraw2_CreatePalette(DDr2,DDPCAPS_8BIT|DDPCAPS_ALLOW256, colorTable, &DDPalette, NULL); - if (ddrval != DD_OK) - I_Error("couldn't CreatePalette"); -}; - - -// -// Free the palette object -// -VOID DestroyDDPalette (VOID) -{ - if (DDPalette) - { - IDirectDrawPalette_Release(DDPalette); - DDPalette = NULL; - } -} - -// -// Set a a full palette of 256 PALETTEENTRY entries -// -VOID SetDDPalette(PALETTEENTRY* pal) -{ - // create palette first time - if (DDPalette == NULL) - CreateDDPalette(pal); - else - IDirectDrawPalette_SetEntries(DDPalette, 0, 0, 256, pal); - // setting the same palette to the same surface again does not increase - // the reference count - IDirectDrawSurface_SetPalette(ScreenReal, DDPalette); -} - -// -// Wait for vsync, gross -// -VOID WaitVbl(VOID) -{ - IDirectDraw2_WaitForVerticalBlank(DDr2, DDWAITVB_BLOCKBEGIN, NULL); -} diff --git a/src/win32ce/gxgapilib.h b/src/win32ce/gxgapilib.h deleted file mode 100644 index 189cc15b8..000000000 --- a/src/win32ce/gxgapilib.h +++ /dev/null @@ -1,81 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief Zak Larue-Buckley's GX and GAPI library v1.0 - -#ifndef _H_GXGAPILIB_ -#define _H_GXGAPILIB_ - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include -#ifdef __MINGW32__ -//#define NONAMELESSUNION -#endif -#ifdef _MSC_VER -#pragma warning(disable : 4201) -#endif -#include -#if (defined (DIRECTDRAW_VERSION) && (DIRECTDRAW_VERSION >= 0x0700)) -#undef DUMMYUNIONNAMEN -#endif -// format of function in app called with width,height -typedef BOOL (*APPENUMMODESCALLBACK)(int width, int height, int bpp); - - -// globals -extern IDirectDraw2* DDr2; -extern IDirectDrawSurface* ScreenReal; -extern IDirectDrawSurface* ScreenVirtual; -extern IDirectDrawPalette* DDPalette; - -extern BOOL bAppFullScreen; // main code might need this to know the current - // fullscreen or windowed state - -extern int windowPosX; // current position in windowed mode -extern int windowPosY; - -extern int ScreenWidth; -extern int ScreenHeight; -extern BOOL ScreenLocked; // Screen surface is being locked -extern int ScreenPitch; // offset from one line to the next -extern LPBYTE ScreenPtr; // memory of the surface - -extern BOOL bDX0300; - -BOOL EnumDirectDrawDisplayModes (APPENUMMODESCALLBACK appFunc); -BOOL CreateDirectDrawInstance (VOID); - -int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr); -VOID CloseDirectDraw (VOID); - -VOID ReleaseChtuff (VOID); - -VOID ClearSurface (IDirectDrawSurface* surface, int color); -BOOL ScreenFlip (int wait); -VOID TextPrint (int x, int y, LPCSTR message); - -VOID CreateDDPalette (PALETTEENTRY* colorTable); -VOID DestroyDDPalette (VOID); -VOID SetDDPalette (PALETTEENTRY* pal); - -VOID WaitVbl (VOID); - -boolean LockScreen (VOID); -VOID UnlockScreen (VOID); - - -#endif /* _H_FABDXLIB_ */ diff --git a/src/win32ce/midstuff.h b/src/win32ce/midstuff.h deleted file mode 100644 index 08ee80add..000000000 --- a/src/win32ce/midstuff.h +++ /dev/null @@ -1,150 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief MIDI structures and definitions -/// used by the MSTREAM sample application in -/// converting a MID file to a MIDI stream for -/// playback using the midiStream API. -/// Inpired by DirectX5 SDK examples - -#ifndef __MIDSTUFF_H__ -#define __MIDSTUFF_H__ - -// MIDI file constants -// -#define MThd 0x6468544D // Start of file -#define MTrk 0x6B72544D // Start of track - -#define MIDI_SYSEX ((BYTE)0xF0) // SysEx begin -#define MIDI_SYSEXEND ((BYTE)0xF7) // SysEx begin -#define MIDI_META ((BYTE)0xFF) // Meta event begin -#define MIDI_META_TEMPO ((BYTE)0x51) // Tempo change -#define MIDI_META_EOT ((BYTE)0x2F) // End-of-track - -#define MIDI_NOTEOFF ((BYTE)0x80) // + note + velocity -#define MIDI_NOTEON ((BYTE)0x90) // + note + velocity -#define MIDI_POLYPRESS ((BYTE)0xA0) // + pressure (2 bytes) -#define MIDI_CTRLCHANGE ((BYTE)0xB0) // + ctrlr + value -#define MIDI_PRGMCHANGE ((BYTE)0xC0) // + new patch -#define MIDI_CHANPRESS ((BYTE)0xD0) // + pressure (1 byte) -#define MIDI_PITCHBEND ((BYTE)0xE0) // + pitch bend (2 bytes) - -#define NUM_CHANNELS 16 - -#define MIDICTRL_VOLUME ((BYTE)0x07) -#define MIDICTRL_VOLUME_LSB ((BYTE)0x27) -#define MIDICTRL_PAN ((BYTE)0x0A) - -#define MIDIEVENT_CHANNEL(dw) (dw & 0x0000000F) -#define MIDIEVENT_TYPE(dw) (dw & 0x000000F0) -#define MIDIEVENT_DATA1(dw) ((dw & 0x0000FF00) >> 8) -#define MIDIEVENT_VOLUME(dw) ((dw & 0x007F0000) >> 16) - -// Macros for swapping hi/lo-endian data -// -#define WORDSWAP(w) (((w) >> 8) | \ - (((w) << 8) & 0xFF00)) - -#define DWORDSWAP(dw) (((dw) >> 24) | \ - (((dw) >> 8) & 0x0000FF00) | \ - (((dw) << 8) & 0x00FF0000) | \ - (((dw) << 24) & 0xFF000000)) - -// In debug builds, TRACKERR will show us where the parser died -// -//#define TRACKERR(p,sz) ShowTrackError(p,sz); -#define TRACKERR(p,sz) - - -// Make a little distinction here so the various structure members are a bit -// more clearly labelled -- we have offsets and byte counts to keep track of -// that deal with both in-memory buffers and the file on disk - -#define FILEOFF DWORD - - -// These structures are stored in MIDI files; they need to be byte aligned. -// -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -// Chunk header. dwTag is either MTrk or MThd. -// -typedef struct -{ - DWORD dwTag; // Type - DWORD dwChunkLength; // Length (hi-lo) -} ATTRPACK MIDICHUNK; - -// Contents of MThd chunk. -typedef struct -{ - WORD wFormat; // Format (hi-lo) - WORD wTrackCount; // # tracks (hi-lo) - WORD wTimeDivision; // Time division (hi-lo) -} ATTRPACK MIDIFILEHDR; - -#if defined(_MSC_VER) -#pragma pack() // End of need for byte-aligned structures -#endif - - -// Temporary event structure which stores event data until we're ready to -// dump it into a stream buffer -// -typedef struct -{ - DWORD tkEvent; // Absolute time of event - BYTE byShortData[4]; // Event type and parameters if channel msg - DWORD dwEventLength; // Length of data which follows if meta or sysex - LPBYTE pLongData; // -> Event data if applicable -} TEMPEVENT, *PTEMPEVENT; - -#define ITS_F_ENDOFTRK 0x00000001 - -// Description of a track open for read -// -typedef struct -{ - DWORD fdwTrack; // Track status - DWORD dwTrackLength; // Total bytes in track - DWORD dwLeftInBuffer; // Bytes left unread in track buffer - LPBYTE pTrackStart; // -> start of track data buffer - LPBYTE pTrackCurrent; // -> next byte to read in buffer - DWORD tkNextEventDue; // Absolute time of next event in track - BYTE byRunningStatus;// Running status from last channel msg - - FILEOFF foTrackStart; // Start of track -- used for walking the file - FILEOFF foNextReadStart;// File offset of next read from disk - DWORD dwLeftOnDisk; // Bytes left unread on disk -#ifdef DEBUG - DWORD nTrack; // # of this track for debugging -#endif -} INTRACKSTATE, *PINTRACKSTATE; - -// Description of the input MIDI file -// -typedef struct -{ - DWORD cbFileLength; // Total bytes in file - DWORD dwTimeDivision; // Original time division - DWORD dwFormat; // Original format - DWORD dwTrackCount; // Track count (specifies pitsTracks size) - INTRACKSTATE *pitsTracks; // -> array of tracks in this file -} INFILESTATE, *PINFILESTATE; - -#endif //__MIDSTUFF_H__ diff --git a/src/win32ce/resource.h b/src/win32ce/resource.h deleted file mode 100644 index a712f14d6..000000000 --- a/src/win32ce/resource.h +++ /dev/null @@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Srb2win.rc -// -#define IDI_DLICON1 101 -#define IDC_DLCURSOR1 103 -#define IDI_ICON1 106 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 114 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/win32ce/win_cd.c b/src/win32ce/win_cd.c deleted file mode 100644 index 2b1a8be9a..000000000 --- a/src/win32ce/win_cd.c +++ /dev/null @@ -1,529 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief cd music interface (uses MCI). - -#include "../doomdef.h" -#include "win_main.h" -#include - -#include "../command.h" -#include "../doomtype.h" -#include "../i_sound.h" -#include "../i_system.h" - -#include "../s_sound.h" - -#define MAX_CD_TRACKS 255 - -typedef struct { - BOOL IsAudio; - DWORD Start, End; - DWORD Length; // minutes -} CDTrack; - -// ------- -// private -// ------- -static CDTrack m_nTracks[MAX_CD_TRACKS]; -static int m_nTracksCount; // up to MAX_CD_TRACKS -static MCI_STATUS_PARMS m_MCIStatus; -static MCI_OPEN_PARMS m_MCIOpen; - -// ------ -// protos -// ------ -static void Command_Cd_f (void); - - -// ------------------- -// MCIErrorMessageBox -// Retrieve error message corresponding to return value from -// mciSendCommand() or mciSenString() -// ------------------- -static VOID MCIErrorMessageBox (MCIERROR iErrorCode) -{ - char szErrorText[128]; - if (!mciGetErrorStringA (iErrorCode, szErrorText, sizeof (szErrorText))) - wsprintfA(szErrorText,"MCI CD Audio Unknow Error #%d\n", iErrorCode); - CONS_Printf (szErrorText); - /*MessageBox (GetActiveWindow(), szTemp+1, "LEGACY", - MB_OK | MB_ICONSTOP);*/ -} - - -// -------- -// CD_Reset -// -------- -static void CD_Reset (void) -{ - // no win32 equivalent - //faB: for DOS, some odd drivers like to be reset sometimes.. useless in MCI I guess -} - - -// ---------------- -// CD_ReadTrackInfo -// Read in number of tracks, and length of each track in minutes/seconds -// returns true if error -// ---------------- -static BOOL CD_ReadTrackInfo (void) -{ - int i; - int nTrackLength; - MCIERROR iErr; - - m_nTracksCount = 0; - - m_MCIStatus.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - m_nTracksCount = (int)m_MCIStatus.dwReturn; - if (m_nTracksCount > MAX_CD_TRACKS) - m_nTracksCount = MAX_CD_TRACKS; - - for (i = 0; i < m_nTracksCount; i++) - { - m_MCIStatus.dwTrack = (DWORD)(i+1); - m_MCIStatus.dwItem = MCI_STATUS_LENGTH; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_TRACK|MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - nTrackLength = (DWORD)(MCI_MSF_MINUTE(m_MCIStatus.dwReturn)*60 + MCI_MSF_SECOND(m_MCIStatus.dwReturn)); - m_nTracks[i].Length = nTrackLength; - - m_MCIStatus.dwItem = MCI_CDA_STATUS_TYPE_TRACK; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_STATUS, MCI_TRACK|MCI_STATUS_ITEM|MCI_WAIT, (DWORD_PTR)&m_MCIStatus); - if (iErr) - { - MCIErrorMessageBox (iErr); - return FALSE; - } - m_nTracks[i].IsAudio = (m_MCIStatus.dwReturn == MCI_CDA_TRACK_AUDIO); - } - - return TRUE; -} - - -// ------------ -// CD_TotalTime -// returns total time for all audio tracks in seconds -// ------------ -static int CD_TotalTime (void) -{ - int nTotalLength = 0; - int nTrack; - for (nTrack = 0; nTrack < m_nTracksCount; nTrack++) - { - if (m_nTracks[nTrack].IsAudio) - nTotalLength = nTotalLength + m_nTracks[nTrack].Length; - } - return nTotalLength; -} - - -//====================================================================== -// CD AUDIO MUSIC SUBSYSTEM -//====================================================================== - -UINT8 cdaudio_started = 0; // for system startup/shutdown - -static boolean cdPlaying = false; -static int cdPlayTrack; // when cdPlaying is true -static boolean cdLooping = false; -static UINT8 cdRemap[MAX_CD_TRACKS]; -static boolean cdEnabled = true; // cd info available -static boolean cdValid; // true when last cd audio info was ok -static boolean wasPlaying; -//static int cdVolume = 0; // current cd volume (0-31) - -// 0-31 like Music & Sfx, though CD hardware volume is 0-255. -consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; - -// allow Update for next/loop track -// some crap cd drivers take up to -// a second for a simple 'busy' check.. -// (on those Update can be disabled) -consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; - -// hour,minutes,seconds -static char *hms(int seconds) -{ - int hours, minutes; - static char s[9]; - - minutes = seconds / 60; - seconds %= 60; - hours = minutes / 60; - minutes %= 60; - if (hours > 0) - sprintf (s, "%d:%02d:%02d", hours, minutes, seconds); - else - sprintf (s, "%2d:%02d", minutes, seconds); - return s; -} - -static void Command_Cd_f (void) -{ - LPCSTR s; - int i,j; - - if (!cdaudio_started) - return; - - if (COM_Argc()<2) - { - CONS_Printf ("cd [on] [off] [remap] [reset] [open]\n" - " [info] [play ] [loop ]\n" - " [stop] [resume]\n"); - return; - } - - s = COM_Argv(1); - - // activate cd music - if (!strncmp(s,"on",2)) - { - cdEnabled = true; - return; - } - - // stop/deactivate cd music - if (!strncmp(s,"off",3)) - { - if (cdPlaying) - I_StopCD (); - cdEnabled = false; - return; - } - - // remap tracks - if (!strncmp(s,"remap",5)) - { - i = (int)COM_Argc() - 2; - if (i <= 0) - { - CONS_Printf ("CD tracks remapped in that order :\n"); - for (j = 1; j < MAX_CD_TRACKS; j++) - if (cdRemap[j] != j) - CONS_Printf (" %2d -> %2d\n", j, cdRemap[j]); - return; - } - for (j = 1; j <= i; j++) - cdRemap[j] = (UINT8)atoi (COM_Argv (j+1)); - return; - } - - // reset the CD driver, useful on some odd cd's - if (!strncmp(s,"reset",5)) - { - cdEnabled = true; - if (cdPlaying) - I_StopCD (); - for (i = 0; i < MAX_CD_TRACKS; i++) - cdRemap[i] = (UINT8)i; - CD_Reset(); - cdValid = CD_ReadTrackInfo(); - return; - } - - // any other command is not allowed until we could retrieve cd information - if (!cdValid) - { - CONS_Printf ("CD is not ready.\n"); - return; - } - - /* faB: not with MCI, didn't find it, useless anyway - if (!strncmp(s,"open",4)) - { - if (cdPlaying) - I_StopCD (); - bcd_open_door(); - cdValid = false; - return; - }*/ - - if (!strncmp(s,"info",4)) - { - if (!CD_ReadTrackInfo()) - { - cdValid = false; - return; - } - - cdValid = true; - - if (m_nTracksCount <= 0) - CONS_Printf ("No audio tracks\n"); - else - { - // display list of tracks - // highlight current playing track - for (i = 0; i < m_nTracksCount; i++) - { - CONS_Printf("%s%2d. %s %s\n", - cdPlaying && (cdPlayTrack == i) ? "\2 " : " ", - i+1, m_nTracks[i].IsAudio ? "audio" : "data ", - hms(m_nTracks[i].Length)); - } - CONS_Printf ("\2Total time : %s\n", hms(CD_TotalTime())); - } - if (cdPlaying) - { - CONS_Printf ("%s track : %d\n", cdLooping ? "looping" : "playing", - cdPlayTrack); - } - return; - } - - if (!strncmp(s,"play",4)) - { - I_PlayCD ((UINT8)atoi(COM_Argv (2)), false); - return; - } - - if (!strncmp(s,"stop",4)) - { - I_StopCD (); - return; - } - - if (!strncmp(s,"loop",4)) - { - I_PlayCD ((UINT8)atoi(COM_Argv (2)), true); - return; - } - - if (!strncmp(s,"resume",4)) - { - I_ResumeCD (); - return; - } - - CONS_Printf ("cd command '%s' unknown\n", s); -} - - -// ------------ -// I_ShutdownCD -// Shutdown CD Audio subsystem, release whatever was allocated -// ------------ -void I_ShutdownCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started) - return; - - CONS_Printf("I_ShutdownCD()\n"); - - I_StopCD(); - - // closes MCI CD - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_CLOSE, 0, 0); - if (iErr) - MCIErrorMessageBox (iErr); -} - - -// -------- -// I_InitCD -// Init CD Audio subsystem -// -------- -void I_InitCD (void) -{ - MCI_SET_PARMS mciSet; - MCIERROR iErr; - int i; - - // We don't have an open device yet - m_MCIOpen.wDeviceID = 0; - m_nTracksCount = 0; - - cdaudio_started = false; - - m_MCIOpen.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO; - iErr = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, (DWORD_PTR)&m_MCIOpen); - if (iErr) - { - MCIErrorMessageBox (iErr); - return; - } - - // Set the time format to track/minute/second/frame (TMSF). - mciSet.dwTimeFormat = MCI_FORMAT_TMSF; - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&mciSet); - if (iErr) - { - MCIErrorMessageBox (iErr); - mciSendCommand(m_MCIOpen.wDeviceID, MCI_CLOSE, 0, 0); - return; - } - - I_AddExitFunc (I_ShutdownCD); - cdaudio_started = true; - - CONS_Printf("I_InitCD: Init CD audio\n"); - - // last saved in config.cfg - i = cd_volume.value; - //I_SetVolumeCD (0); // initialize to 0 for some odd cd drivers - I_SetVolumeCD (i); // now set the last saved volume - - for (i = 0; i < MAX_CD_TRACKS; i++) - cdRemap[i] = (UINT8)i; - - if (!CD_ReadTrackInfo()) - { - CONS_Printf("\2I_InitCD: no CD in player.\n"); - cdEnabled = false; - cdValid = false; - } - else - { - cdEnabled = true; - cdValid = true; - } - - COM_AddCommand ("cd", Command_Cd_f); -} - - - -// loop/go to next track when track is finished (if cd_update var is true) -// update the volume when it has changed (from console/menu) -void I_UpdateCD (void) -{ - /// \todo check for cd change and restart music ? -} - - -// -void I_PlayCD (UINT8 nTrack, UINT8 bLooping) -{ - MCI_PLAY_PARMS mciPlay; - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - //faB: try again if it didn't work (just free the user of typing 'cd reset' command) - if (!cdValid) - cdValid = CD_ReadTrackInfo(); - if (!cdValid) - return; - - // tracks start at 0 in the code.. - nTrack--; - if (nTrack < 0 || nTrack >= m_nTracksCount) - nTrack = nTrack % m_nTracksCount; - - nTrack = cdRemap[nTrack]; - - if (cdPlaying) - { - if (cdPlayTrack == nTrack) - return; - I_StopCD (); - } - - cdPlayTrack = nTrack; - - if (!m_nTracks[nTrack].IsAudio) - { - //CONS_Printf ("\2CD Play: not an audio track\n"); // Tails 03-25-2001 - return; - } - - cdLooping = bLooping; - - //faB: stop MIDI music, MIDI music will restart if volume is upped later - cv_digmusicvolume.value = 0; - cv_midimusicvolume.value = 0; - I_StopSong (0); - - //faB: I don't use the notify message, I'm trying to minimize the delay - mciPlay.dwCallback = (DWORD_PTR)((size_t)hWndMain); - mciPlay.dwFrom = MCI_MAKE_TMSF(nTrack+1, 0, 0, 0); - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_PLAY, MCI_FROM|MCI_NOTIFY, (DWORD_PTR)&mciPlay); - if (iErr) - { - MCIErrorMessageBox (iErr); - cdValid = false; - cdPlaying = false; - return; - } - - cdPlaying = true; -} - - -// pause cd music -void I_StopCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_PAUSE, MCI_WAIT, 0); - if (iErr) - MCIErrorMessageBox (iErr); - else - { - wasPlaying = cdPlaying; - cdPlaying = false; - } -} - - -// continue after a pause -void I_ResumeCD (void) -{ - MCIERROR iErr; - - if (!cdaudio_started || !cdEnabled) - return; - - if (!cdValid) - return; - - if (!wasPlaying) - return; - - iErr = mciSendCommand(m_MCIOpen.wDeviceID, MCI_RESUME, MCI_WAIT, 0); - if (iErr) - MCIErrorMessageBox (iErr); - else - cdPlaying = true; -} - - -// volume : logical cd audio volume 0-31 (hardware is 0-255) -int I_SetVolumeCD (int volume) -{ - (void)volume; - return 1; -} diff --git a/src/win32ce/win_dbg.c b/src/win32ce/win_dbg.c deleted file mode 100644 index 9cfe77636..000000000 --- a/src/win32ce/win_dbg.c +++ /dev/null @@ -1,629 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief Sources from GameDeveloper magazine article, January 1998, by Bruce Dawson. -/// this source file contains the exception handler for recording error -/// information after crashes. - -#include -#include "win_main.h" -#include "../doomdef.h" //just for VERSION -#include "win_dbg.h" -#include "../m_argv.h" //print the parameter in the log - - -#define NumCodeBytes 16 // Number of code bytes to record. -#define MaxStackDump 2048 // Maximum number of DWORDS in stack dumps. -#define StackColumns 8 // Number of columns in stack dump. - -#define ONEK 1024 -#define SIXTYFOURK (64*ONEK) -#define ONEM (ONEK*ONEK) -#define ONEG (ONEK*ONEK*ONEK) - - -// -------------------------------------------------------------------------- -// return a description for an ExceptionCode -// -------------------------------------------------------------------------- -static LPCSTR GetExceptionDescription (DWORD ExceptionCode) -{ - unsigned int i; - - struct ExceptionNames - { - DWORD ExceptionCode; - LPCSTR ExceptionName; - }; - - struct ExceptionNames ExceptionMap[] = - { - {EXCEPTION_ACCESS_VIOLATION, "an Access Violation"}, - {EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "a Array Bounds Exceeded"}, - {EXCEPTION_BREAKPOINT, "a Breakpoint"}, - {EXCEPTION_DATATYPE_MISALIGNMENT, "a Datatype Misalignment"}, - {EXCEPTION_FLT_DENORMAL_OPERAND, "a Float Denormal Operand"}, - {EXCEPTION_FLT_DIVIDE_BY_ZERO, "a Float Divide By Zero"}, - {EXCEPTION_FLT_INEXACT_RESULT, "a Float Inexact Result"}, - {EXCEPTION_FLT_INVALID_OPERATION, "a Float Invalid Operation"}, - {EXCEPTION_FLT_OVERFLOW, "a Float Overflow"}, - {EXCEPTION_FLT_STACK_CHECK, "a Float Stack Check"}, - {EXCEPTION_FLT_UNDERFLOW, "a Float Underflow"}, - {EXCEPTION_ILLEGAL_INSTRUCTION, "an Illegal Instruction"}, - {EXCEPTION_IN_PAGE_ERROR, "an In Page Error"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "an Integer Divide By Zero"}, - {EXCEPTION_INT_OVERFLOW, "an Integer Overflow"}, - {EXCEPTION_INVALID_DISPOSITION, "an Invalid Disposition"}, - {EXCEPTION_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception"}, - {EXCEPTION_PRIV_INSTRUCTION, "a Privileged Instruction"}, - {EXCEPTION_SINGLE_STEP, "a Single Step"}, - {EXCEPTION_STACK_OVERFLOW, "a Stack Overflow"}, - {0x40010005, "a Control-C"}, - {0x40010008, "a Control-Break"}, - {0xc0000006, "an In Page Error"}, - {0xc0000017, "a No Memory"}, - {0xc000001d, "an Illegal Instruction"}, - {0xc0000025, "a Noncontinuable Exception"}, - {0xc0000142, "a DLL Initialization Failed"}, - {0xe06d7363, "a Microsoft C++ Exception"}, - }; - - for (i = 0; i < (sizeof (ExceptionMap) / sizeof (ExceptionMap[0])); i++) - if (ExceptionCode == ExceptionMap[i].ExceptionCode) - return ExceptionMap[i].ExceptionName; - - return "Unknown exception type"; -} - - -// -------------------------------------------------------------------------- -// Directly output a formatted string to the errorlog file, using win32 funcs -// -------------------------------------------------------------------------- -static VOID FPrintf (HANDLE fileHandle, LPCSTR lpFmt, ...) -{ - CHAR str[1999]; - va_list arglist; - DWORD bytesWritten; - - va_start (arglist, lpFmt); - vsprintf (str, lpFmt, arglist); - va_end (arglist); - - WriteFile (fileHandle, str, (DWORD)strlen(str), &bytesWritten, NULL); -} - -// -------------------------------------------------------------------------- -// Print the specified FILETIME to output in a human readable format, -// without using the C run time. -// -------------------------------------------------------------------------- -static VOID PrintTime (LPSTR output, FILETIME TimeToPrint) -{ - WORD Date, Time; - if (FileTimeToLocalFileTime (&TimeToPrint, &TimeToPrint) && - FileTimeToDosDateTime (&TimeToPrint, &Date, &Time)) - { - // What a silly way to print out the file date/time. - wsprintfA(output, "%d/%d/%d %02d:%02d:%02d", - (Date / 32) & 15, Date & 31, (Date / 512) + 1980, - (Time / 2048), (Time / 32) & 63, (Time & 31) * 2); - } - else - output[0] = 0; -} - - -static LPTSTR GetFilePart(LPTSTR source) -{ - LPTSTR result = _tcsrchr(source, '\\'); - if (result) - result++; - else - result = source; - return result; -} - -// -------------------------------------------------------------------------- -// Print information about a code module (DLL or EXE) such as its size, -// location, time stamp, etc. -// -------------------------------------------------------------------------- -static VOID ShowModuleInfo(HANDLE LogFile, HMODULE ModuleHandle) -{ - CHAR ModName[MAX_PATH]; - IMAGE_DOS_HEADER *DosHeader; - IMAGE_NT_HEADERS *NTHeader; - HANDLE ModuleFile; - CHAR TimeBuffer[100] = ""; - DWORD FileSize = 0; -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - if (GetModuleFileNameA(ModuleHandle, ModName, sizeof (ModName)) > 0) - { - // If GetModuleFileName returns greater than zero then this must - // be a valid code module address. Therefore we can try to walk - // our way through its structures to find the link time stamp. - DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle; - if (IMAGE_DOS_SIGNATURE != DosHeader->e_magic) - return; - NTHeader = (IMAGE_NT_HEADERS*)((char *)DosHeader - + DosHeader->e_lfanew); - if (IMAGE_NT_SIGNATURE != NTHeader->Signature) - return; - // Open the code module file so that we can get its file date - // and size. - ModuleFile = CreateFileA(ModName, GENERIC_READ, - FILE_SHARE_READ, 0, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0); - if (ModuleFile != INVALID_HANDLE_VALUE) - { - FILETIME LastWriteTime; - FileSize = GetFileSize(ModuleFile, 0); - if (GetFileTime(ModuleFile, 0, 0, &LastWriteTime)) - { - wsprintfA(TimeBuffer, " - file date is "); - PrintTime(TimeBuffer + strlen(TimeBuffer), LastWriteTime); - } - CloseHandle(ModuleFile); - } - FPrintf (LogFile, "%s, loaded at 0x%08x - %d bytes - %08x%s\r\n", - ModName, ModuleHandle, FileSize, - NTHeader->FileHeader.TimeDateStamp, TimeBuffer); - } - } - // Handle any exceptions by continuing from this point. -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - } -} - -// -------------------------------------------------------------------------- -// Scan memory looking for code modules (DLLs or EXEs). VirtualQuery is used -// to find all the blocks of address space that were reserved or committed, -// and ShowModuleInfo will display module information if they are code -// modules. -// -------------------------------------------------------------------------- -static VOID RecordModuleList(HANDLE LogFile) -{ - SYSTEM_INFO SystemInfo; - size_t PageSize; - size_t NumPages; - size_t pageNum = 0; - LPVOID LastAllocationBase = 0; - - FPrintf (LogFile, "\r\n" - "\tModule list: names, addresses, sizes, time stamps " - "and file times:\r\n"); - - // Set NumPages to the number of pages in the 4GByte address space, - // while being careful to avoid overflowing ints. - GetSystemInfo(&SystemInfo); - PageSize = SystemInfo.dwPageSize; - NumPages = 4 * (unsigned int)(ONEG / PageSize); - while (pageNum < NumPages) - { - MEMORY_BASIC_INFORMATION MemInfo; - if (VirtualQuery((LPVOID)(pageNum * PageSize), &MemInfo, - sizeof (MemInfo))) - { - if (MemInfo.RegionSize > 0) - { - // Adjust the page number to skip over this block of memory. - pageNum += MemInfo.RegionSize / PageSize; - if (MemInfo.State == MEM_COMMIT && MemInfo.AllocationBase > - LastAllocationBase) - { - // Look for new blocks of committed memory, and try - // recording their module names - this will fail - // gracefully if they aren't code modules. - LastAllocationBase = MemInfo.AllocationBase; - ShowModuleInfo(LogFile, (HMODULE)LastAllocationBase); - } - } - else - pageNum += SIXTYFOURK / PageSize; - } - else - pageNum += SIXTYFOURK / PageSize; - // If VirtualQuery fails we advance by 64K because that is the - // granularity of address space doled out by VirtualAlloc(). - } -} - - -// -------------------------------------------------------------------------- -// Record information about the user's system, such as processor type, amount -// of memory, etc. -// -------------------------------------------------------------------------- -static VOID RecordSystemInformation(HANDLE fileHandle) -{ - FILETIME CurrentTime; - CHAR TimeBuffer[100]; - CHAR ModuleName[MAX_PATH]; - CHAR UserName[200]; - DWORD UserNameSize; - SYSTEM_INFO SystemInfo; - MEMORYSTATUS MemInfo; - - GetSystemTimeAsFileTime (&CurrentTime); - PrintTime (TimeBuffer, CurrentTime); - FPrintf(fileHandle, "Error occurred at %s.\r\n", TimeBuffer); - - if (GetModuleFileNameA(NULL, ModuleName, sizeof (ModuleName)) <= 0) - strcpy (ModuleName, "Unknown"); - UserNameSize = sizeof (UserName); - if (!GetUserNameA(UserName, &UserNameSize)) - strcpy (UserName, "Unknown"); - FPrintf(fileHandle, "%s, run by %s.\r\n", ModuleName, UserName); - - GetSystemInfo (&SystemInfo); - FPrintf (fileHandle, "%d processor(s), type %d %d.%d.\r\n" - "Program Memory from 0x%p to 0x%p\r\n", - SystemInfo.dwNumberOfProcessors, - SystemInfo.dwProcessorType, - SystemInfo.wProcessorLevel, - SystemInfo.wProcessorRevision, - SystemInfo.lpMinimumApplicationAddress, - SystemInfo.lpMaximumApplicationAddress); - - MemInfo.dwLength = sizeof (MemInfo); - GlobalMemoryStatus(&MemInfo); - // Print out the amount of physical memory, rounded up. - FPrintf(fileHandle, "%d MBytes physical memory.\r\n", (MemInfo.dwTotalPhys + - ONEM - 1) / ONEM); -} - -// -------------------------------------------------------------------------- -// What we do here is trivial : open a file, write out the register information -// from the PEXCEPTION_POINTERS structure, then return EXCEPTION_CONTINUE_SEARCH -// whose magic value tells Win32 to proceed with its normal error handling -// mechanism. This is important : an error dialog will popup if possible and -// the debugger will hopefully coexist peacefully with the structured exception -// handler. -// -------------------------------------------------------------------------- -int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPSTR lpCmdLine*/) -{ - PEXCEPTION_RECORD Exception; - PCONTEXT Context; - TCHAR ModuleName[MAX_PATH]; - TCHAR FileName[MAX_PATH] = TEXT("Unknown"); - LPTSTR FilePart, lastperiod; - TCHAR CrashModulePathName[MAX_PATH]; - LPCTSTR CrashModuleFileName = TEXT("Unknown"); - MEMORY_BASIC_INFORMATION MemInfo; - static int BeenHere = false; - HANDLE fileHandle; - UINT8 *code; - int codebyte,i; - - if (data) - { - Exception = data->ExceptionRecord; - Context = data->ContextRecord; - } - else - { - return EXCEPTION_CONTINUE_SEARCH; - } - - if (BeenHere) // Going recursive! That must mean this routine crashed! - return EXCEPTION_CONTINUE_SEARCH; - BeenHere = true; - - // Create a filename to record the error information to. - // Store it in the executable directory. - if (GetModuleFileName(NULL, ModuleName, sizeof (ModuleName)) <= 0) - ModuleName[0] = 0; - FilePart = GetFilePart(ModuleName); - - // Extract the file name portion and remove it's file extension. We'll - // use that name shortly. - lstrcpy (FileName, FilePart); - lastperiod = _tcsrchr (FileName, '.'); - if (lastperiod) - lastperiod[0] = 0; - // Replace the executable filename with our error log file name. - lstrcpy (FilePart, TEXT("errorlog.txt")); - fileHandle = CreateFile (ModuleName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); - if (fileHandle == INVALID_HANDLE_VALUE) - { - OutputDebugString (TEXT("Error creating exception report")); - return EXCEPTION_CONTINUE_SEARCH; - } - - // Append to the error log. - SetFilePointer (fileHandle, 0, 0, FILE_END); - - // Print out some blank lines to separate this error log from any previous ones. - FPrintf (fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails - FPrintf (fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails - FPrintf (fileHandle, "\r\n\r\n\r\n\r\n"); - FPrintf (fileHandle, "SRB2 %s -ERROR LOG-\r\n\r\n", VERSIONSTRING); - FPrintf (fileHandle, "\r\n"); - // VirtualQuery can be used to get the allocation base associated with a - // code address, which is the same as the ModuleHandle. This can be used - // to get the filename of the module that the crash happened in. - if (VirtualQuery ((LPVOID)(size_t)Context->Eip, &MemInfo, sizeof (MemInfo)) && - GetModuleFileName ((HMODULE)MemInfo.AllocationBase, - CrashModulePathName, - sizeof (CrashModulePathName)) > 0) - CrashModuleFileName = GetFilePart(CrashModulePathName); - - // Print out the beginning of the error log in a Win95 error window - // compatible format. - FPrintf (fileHandle, "%s caused an %s in module %s at %04x:%08x.\r\n", - FileName, GetExceptionDescription(Exception->ExceptionCode), - CrashModuleFileName, Context->SegCs, Context->Eip); - //if (&Message = Null) - FPrintf (fileHandle, "Exception handler called in %s.\r\n", "main thread"); - //else - //FPrintf (fileHandle, "Exception handler called in %s.\r\n", Message); - - RecordSystemInformation (fileHandle); - - // If the exception was an access violation, print out some additional - // information, to the error log and the debugger. - if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION && - Exception->NumberParameters >= 2) - { - TCHAR DebugMessage[1000]; - LPCTSTR readwrite = TEXT("Read from"); - if (Exception->ExceptionInformation[0]) - readwrite = TEXT("Write to"); - wsprintf(DebugMessage, TEXT("%s location %08x caused an access violation.\r\n"), - readwrite, Exception->ExceptionInformation[1]); -#ifdef _DEBUG - // The VisualC++ debugger doesn't actually tell you whether a read - // or a write caused the access violation, nor does it tell what - // address was being read or written. So I fixed that. - OutputDebugString(TEXT("Exception handler: ")); - OutputDebugString(DebugMessage); -#endif - FPrintf(fileHandle, "%s", DebugMessage); - } - - FPrintf(fileHandle, "\r\n"); - - // Print out the register values in a Win95 error window compatible format. - if ((Context->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL) - { - FPrintf (fileHandle, "Registers:\r\n"); - FPrintf (fileHandle, "EAX=%.8lx CS=%.4x EIP=%.8lx EFLGS=%.8lx\r\n", - Context->Eax,Context->SegCs,Context->Eip,Context->EFlags); - FPrintf (fileHandle, "EBX=%.8lx SS=%.4x ESP=%.8lx EBP=%.8lx\r\n", - Context->Ebx,Context->SegSs,Context->Esp,Context->Ebp); - FPrintf (fileHandle, "ECX=%.8lx DS=%.4x ESI=%.8lx FS=%.4x\r\n", - Context->Ecx,Context->SegDs,Context->Esi,Context->SegFs); - FPrintf (fileHandle, "EDX=%.8lx ES=%.4x EDI=%.8lx GS=%.4x\r\n", - Context->Edx,Context->SegEs,Context->Edi,Context->SegGs); - } - - // moved down because it was causing the printout to stop - FPrintf (fileHandle, "Command Line parameters: "); - for (i = 1;i < myargc;i++) - FPrintf (fileHandle, "%s ", myargv[i]); - - FPrintf (fileHandle, "Bytes at CS : EIP:\r\n"); - - // Print out the bytes of code at the instruction pointer. Since the - // crash may have been caused by an instruction pointer that was bad, - // this code needs to be wrapped in an exception handler, in case there - // is no memory to read. If the dereferencing of code[] fails, the - // exception handler will print '??'. - code = (UINT8 *)(size_t)Context->Eip; - for (codebyte = 0; codebyte < NumCodeBytes; codebyte++) - { -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - FPrintf (fileHandle, "%02x ", code[codebyte]); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - FPrintf (fileHandle, "?? "); - } - } - - // Time to print part or all of the stack to the error log. This allows - // us to figure out the call stack, parameters, local variables, etc. - FPrintf (fileHandle, "\r\n" - "Stack dump:\r\n"); -#ifdef NO_SEH_MINGW - __try1(EXCEPTION_EXECUTE_HANDLER) -#else - __try -#endif - { - // Esp contains the bottom of the stack, or at least the bottom of - // the currently used area. - DWORD* pStack = (DWORD *)(size_t)Context->Esp; - DWORD* pStackTop = NULL; - size_t Count = 0; - TCHAR buffer[1000] = TEXT(""); - const int safetyzone = 50; - LPTSTR nearend = buffer + sizeof (buffer) - safetyzone*sizeof (TCHAR); - LPTSTR output = buffer; - const void *Suffix; - - // Load the top (highest address) of the stack from the - // thread information block. It will be found there in - // Win9x and Windows NT. -#ifdef __GNUC__ - __asm__("movl %%fs : 4, %%eax": "=a"(pStackTop)); -#else - __asm - { - mov eax, fs:[4] - mov pStackTop, eax - } -#endif - if (pStackTop == NULL) - goto StackSkip; - else if (pStackTop > pStack + MaxStackDump) - pStackTop = pStack + MaxStackDump; - // Too many calls to WriteFile can take a long time, causing - // confusing delays when programs crash. Therefore I implemented - // simple buffering for the stack dumping code instead of calling - // FPrintf directly. - while (pStack + 1 <= pStackTop) - { - if ((Count % StackColumns) == 0) - output += wsprintf(output, TEXT("%08x: "), pStack); - if ((++Count % StackColumns) == 0 || pStack + 2 > pStackTop) - Suffix = TEXT("\r\n"); - else - Suffix = TEXT(" "); - output += wsprintf(output, TEXT("%08x%s"), *pStack, Suffix); - pStack++; - // Check for when the buffer is almost full, and flush it to disk. - if (output > nearend) - { - FPrintf (fileHandle, "%s", buffer); - buffer[0] = 0; - output = buffer; - } - } - // Print out any final characters from the cache. - StackSkip: - FPrintf (fileHandle, "%s", buffer); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except(EXCEPTION_EXECUTE_HANDLER) -#endif - { - FPrintf(fileHandle, "Exception encountered during stack dump.\r\n"); - } - - RecordModuleList (fileHandle); - - CloseHandle (fileHandle); - - // Return the magic value which tells Win32 that this handler didn't - // actually handle the exception - so that things will proceed as per - // normal. - //BP: should put message for end user to send this file to fix any bug - return EXCEPTION_CONTINUE_SEARCH; -} - - /* - // - //FPrintf ("e-mail this file to legacy@newdoom.com, so that we can fix the problem.\r\n\r\n"); - - FPrintf ("Exception handler called in %s.\r\n", Message); - - GetSystemTime (&systemTime); - FPrintf ("Error occured at %02d/%02d/%04d %02d:%02d:%02d.\r\n", - systemTime.wMonth, systemTime.wDay, systemTime.wYear, - systemTime.wHour, systemTime.wMinute, systemTime.wSecond); - - - FPrintf ("%s\r\n", filename); - FPrintf ("Cmd-line: %s\r\n", lpCmdLine); - - // Nested exceptions can occur, get info for each one - - nER = 1; - while (ER) - { - if (nER++>1) - FPrintf ("Exception Record %d.\r\n", nER); - - FPrintf ("application caused an %s", GetExceptionCodeStr(Exception->ExceptionCode)); - - if (Context->ContextFlags & CONTEXT_CONTROL) - FPrintf (" at %.4x:%.8x.\r\n", Context->SegCs, Context->Eip); - - // in case of.. - if (Context->Eip != (unsigned long)Exception->ExceptionAddress) - FPrintf ("Exception Address = %.8x\r\n", Exception->ExceptionAddress); - - if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - { - FPrintf ("\r\n%s location 0x%x caused an access violation.\r\n", - (Exception->ExceptionInformation[0] ? "Write to" : "Read from"), - Exception->ExceptionInformation[1]); - } - - ER = Exception->ExceptionRecord; - } - - - if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) - { - FPrintf ("\r\nDebug Registers:\r\n"); - FPrintf ("Dr0=%.8x Dr1=%.8x Dr2=%.8x\r\n" - "Dr3=%.8x Dr6=%.8x Dr7=%.8x\r\n", - Context->Dr0, Context->Dr1, Context->Dr2, - Context->Dr3, Context->Dr6, Context->Dr7); - } - - if (Context->ContextFlags & CONTEXT_FLOATING_POINT) - { - FPrintf ("\r\nFloating Save Area:\r\n"); - FPrintf ("ControlWord =%.8x TagWord =%.8x ErrorSelector=%.8x DataSelector =%.8x\r\n" - "StatusWord =%.8x ErrorOffset =%.8x DataOffset =%.8x Cr0NpxState =%.8x\r\n", - Context->FloatSave.ControlWord, Context->FloatSave.TagWord, Context->FloatSave.ErrorSelector, Context->FloatSave.DataSelector, - Context->FloatSave.StatusWord, Context->FloatSave.ErrorOffset, Context->FloatSave.DataOffset, Context->FloatSave.Cr0NpxState - ); - - //BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; - } - - - // in case of... - if ((Context->ContextFlags & CONTEXT_FULL) != CONTEXT_FULL) - { - if (!(Context->ContextFlags & CONTEXT_SEGMENTS)) - FPrintf ("Note! GS,FS,ES,DS are unspecified\r\n"); - if (!(Context->ContextFlags & CONTEXT_INTEGER)) - FPrintf ("Note! EDI,ESI,EBX,EDX,ECX,EAX are unspecified\r\n"); - if (!(Context->ContextFlags & CONTEXT_CONTROL)) - FPrintf ("Note! EBP,CS : EIP,EFlags,SS : ESP are unspecified\r\n"); - } - - FPrintf ("\r\nBytes at CS : EIP:\r\n"); - ucptr = (UINT8 *)Context->Eip; - for (i = 0; i < 16; i++) - FPrintf ("%.2x ", *ucptr++); - - FPrintf ("\r\n\r\nStack dump:\r\n"); - ulptr = (unsigned long*)Context->Esp; - for (i = 0; i < 16; i++) - FPrintf ("%.8x ", *ulptr++); - - //FPrintf ("Bytes at CS : EIP:\r\n"); - //FPrintf ("%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x "); - - for (i = 0; i < 16; i++) - { - FPrintf ("%x - } -*/ diff --git a/src/win32ce/win_dbg.h b/src/win32ce/win_dbg.h deleted file mode 100644 index acee896e6..000000000 --- a/src/win32ce/win_dbg.h +++ /dev/null @@ -1,54 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief exception handler - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include - -// called in the exception filter of the __try block, writes all useful debugging information -// to a file, using only win32 functions in case the C runtime is in a bad state. -int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPSTR lpCmdLine*/); - -#ifdef __MINGW32__ - -#include - -#ifndef TRYLEVEL_NONE - -#define NO_SEH_MINGW //Alam:? -FUNCINLINE static ATTRINLINE struct _EXCEPTION_POINTERS *GetExceptionInformation(VOID) -{ - LPVOID SEHINFO = NULL; - //__asm__("movl -20(%%ebp), %%eax": "=a"(SEHINFO)); - return SEHINFO; -} - -//Alam_GBC: use __try1(seh) -#ifndef __try -#define __try -#endif //__try - -//#undef NO_SEH_MINGW //Alam: win_dbg's code not working with MINGW -//Alam_GBC: use __except1 -#ifndef __except -#define __except(x) if (0) -#endif //__except - -#endif // !__TRYLEVEL_NONE - -#endif // __MINGW32__ diff --git a/src/win32ce/win_dll.c b/src/win32ce/win_dll.c deleted file mode 100644 index 8b88f84dd..000000000 --- a/src/win32ce/win_dll.c +++ /dev/null @@ -1,164 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief load and initialise the 3D driver DLL - -#include "../doomdef.h" -#ifdef HWRENDER -#include "../hardware/hw_drv.h" // get the standard 3D Driver DLL exports prototypes -#endif - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" // get the 3D sound driver DLL export prototypes -#endif - -#include "win_dll.h" -#include "win_main.h" // I_GetLastErrorMsgBox() - -#if defined(HWRENDER) || defined(HW3SOUND) -typedef struct loadfunc_s { - LPCSTR fnName; - LPVOID fnPointer; -} loadfunc_t; - -// -------------------------------------------------------------------------- -// Load a DLL, returns the HMODULE handle or NULL -// -------------------------------------------------------------------------- -static inline HMODULE LoadDLL (LPCSTR dllName, loadfunc_t *funcTable) -{ - LPVOID funcPtr; - loadfunc_t *loadfunc; - HMODULE hModule; - - if ((hModule = LoadLibraryA(dllName)) != NULL) - { - // get function pointers for all functions we use - for (loadfunc = funcTable; loadfunc->fnName != NULL; loadfunc++) - { - funcPtr = GetProcAddress(hModule, loadfunc->fnName); - if (!funcPtr) { - //I_GetLastErrorMsgBox (); - MessageBoxA(NULL, va("The '%s' haven't the good specification (function %s missing)\n\n" - "You must use dll from the same zip of this exe\n", dllName, loadfunc->fnName), - "Error", MB_OK|MB_ICONINFORMATION); - return FALSE; - } - // store function address - *((LPVOID*)loadfunc->fnPointer) = funcPtr; - } - } - else - { - MessageBoxA(NULL, va("LoadLibrary() FAILED : couldn't load '%s'\r\n", dllName), "Warning", MB_OK|MB_ICONINFORMATION); - //I_GetLastErrorMsgBox (); - } - - return hModule; -} - - -// -------------------------------------------------------------------------- -// Unload the DLL -// -------------------------------------------------------------------------- -static inline VOID UnloadDLL (HMODULE* pModule) -{ - if (FreeLibrary(*pModule)) - *pModule = NULL; - else - I_GetLastErrorMsgBox (); -} -#endif - -// ========================================================================== -// STANDARD 3D DRIVER DLL FOR DOOM LEGACY -// ========================================================================== - -// note : the 3D driver loading should be put somewhere else.. - -#ifdef HWRENDER -static HMODULE hwdModule = NULL; - -static loadfunc_t hwdFuncTable[] = { - {"_Init@4", &hwdriver.pfnInit}, - {"_Shutdown@0", &hwdriver.pfnShutdown}, - {"_GetModeList@8", &hwdriver.pfnGetModeList}, - {"_SetPalette@8", &hwdriver.pfnSetPalette}, - {"_FinishUpdate@4", &hwdriver.pfnFinishUpdate}, - {"_Draw2DLine@12", &hwdriver.pfnDraw2DLine}, - {"_DrawPolygon@16", &hwdriver.pfnDrawPolygon}, - {"_SetBlend@4", &hwdriver.pfnSetBlend}, - {"_ClearBuffer@12", &hwdriver.pfnClearBuffer}, - {"_SetTexture@4", &hwdriver.pfnSetTexture}, - {"_ReadRect@24", &hwdriver.pfnReadRect}, - {"_GClipRect@20", &hwdriver.pfnGClipRect}, - {"_ClearMipMapCache@0",&hwdriver.pfnClearMipMapCache}, - {"_SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"_DrawMD2@16", &hwdriver.pfnDrawMD2}, - {"_SetTransform@4", &hwdriver.pfnSetTransform}, - {"_GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, - {"_GetRenderVersion@0",&hwdriver.pfnGetRenderVersion}, - {NULL,NULL} -}; - -BOOL Init3DDriver (LPCSTR dllName) -{ - hwdModule = LoadDLL(dllName, hwdFuncTable); - return (hwdModule != NULL); -} - -VOID Shutdown3DDriver (VOID) -{ - UnloadDLL(&hwdModule); -} -#endif - -#ifdef HW3SOUND -static HMODULE hwsModule = NULL; - -static loadfunc_t hwsFuncTable[] = { - {"_Startup@8", &hw3ds_driver.pfnStartup}, - {"_Shutdown@0", &hw3ds_driver.pfnShutdown}, - {"_AddSfx@4", &hw3ds_driver.pfnAddSfx}, - {"_AddSource@8", &hw3ds_driver.pfnAddSource}, - {"_StartSource@4", &hw3ds_driver.pfnStartSource}, - {"_StopSource@4", &hw3ds_driver.pfnStopSource}, - {"_GetHW3DSVersion@0", &hw3ds_driver.pfnGetHW3DSVersion}, - {"_BeginFrameUpdate@0", &hw3ds_driver.pfnBeginFrameUpdate}, - {"_EndFrameUpdate@0", &hw3ds_driver.pfnEndFrameUpdate}, - {"_IsPlaying@4", &hw3ds_driver.pfnIsPlaying}, - {"_UpdateListener@8", &hw3ds_driver.pfnUpdateListener}, - {"_UpdateSourceParms@12", &hw3ds_driver.pfnUpdateSourceParms}, - {"_SetCone@8", &hw3ds_driver.pfnSetCone}, - {"_SetGlobalSfxVolume@4", &hw3ds_driver.pfnSetGlobalSfxVolume}, - {"_Update3DSource@8", &hw3ds_driver.pfnUpdate3DSource}, - {"_ReloadSource@8", &hw3ds_driver.pfnReloadSource}, - {"_KillSource@4", &hw3ds_driver.pfnKillSource}, - {"_KillSfx@4", &hw3ds_driver.pfnKillSfx}, - {"_GetHW3DSTitle@8", &hw3ds_driver.pfnGetHW3DSTitle}, - {NULL, NULL} -}; - -BOOL Init3DSDriver(LPCSTR dllName) -{ - hwsModule = LoadDLL(dllName, hwsFuncTable); - return (hwsModule != NULL); -} - -VOID Shutdown3DSDriver (VOID) -{ - UnloadDLL(&hwsModule); -} -#endif diff --git a/src/win32ce/win_dll.h b/src/win32ce/win_dll.h deleted file mode 100644 index b4b259587..000000000 --- a/src/win32ce/win_dll.h +++ /dev/null @@ -1,31 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief load/unload a DLL at run-time - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include - -#ifdef HWRENDER -BOOL Init3DDriver (LPCSTR dllName); -VOID Shutdown3DDriver (VOID); -#endif - -#ifdef HW3SOUND -BOOL Init3DSDriver(LPCSTR dllName); -VOID Shutdown3DSDriver(VOID); -#endif diff --git a/src/win32ce/win_file.c b/src/win32ce/win_file.c deleted file mode 100644 index f9f621011..000000000 --- a/src/win32ce/win_file.c +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include -#include "win_file.h" - - -int FileAccess(LPCTSTR FileName, DWORD mode) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - if (hFile == INVALID_HANDLE_VALUE) - return -1; - else - { - FileClose(hFile); - return 0; - } -} - -HANDLE FileCreate(LPCTSTR FileName) -{ - HANDLE hFile; - - if (FileAccess( FileName, 0) == 0) - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - else - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - - return hFile; -} - -void FileClose(HANDLE hFile) -{ - CloseHandle(hFile); -} - -DWORD FileLength(HANDLE hFile) -{ - return GetFileSize(hFile, NULL); -} - -HANDLE FileOpen(LPCTSTR FileName) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - return hFile; -} - -HANDLE FileAppend(LPCTSTR FileName) -{ - HANDLE hFile; - - hFile = CreateFile( FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - FileSeek(hFile, 0, FILE_END ); - - return hFile; -} - -DWORD FileRead(HANDLE hFile, LPVOID data, DWORD size) -{ - DWORD readin = 0; - - ReadFile(hFile, data, size, &readin, NULL); - - return readin; -} - -DWORD FileSeek(HANDLE hFile, LONG distance, DWORD method) -{ - DWORD position; - - position = SetFilePointer(hFile, distance, NULL, method); - - return position; -} - -DWORD FileWrite(HANDLE hFile, LPCVOID data, DWORD size) -{ - DWORD written = 0; - - WriteFile(hFile, data, size, &written, NULL); - - return written; -} - -//These functions are provided as CRT replacements. (missing from WinCE) - -int access(char* file,int type) -{ - FILE* file_access = 0; - - file_access = fopen(file,"rb"); - - if(file_access) - { - fclose(file_access); - return 0; - } - - return -1; -} - -unsigned int file_len(char* file) -{ - FILE* file_access; - unsigned int len = 0; - - file_access = fopen(file,"rb"); - - if(!file_access) - return 0; - - fseek(file_access,0,SEEK_END); - - len = ftell(file_access); - - fclose(file_access); - - return len; -} diff --git a/src/win32ce/win_file.h b/src/win32ce/win_file.h deleted file mode 100644 index d1dc5e9c7..000000000 --- a/src/win32ce/win_file.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FILE_H -#define FILE_H - -// New File I/O functions - -int FileAccess(LPCTSTR, DWORD); -HANDLE FileAppend(LPCTSTR FileName); -void FileClose(HANDLE); -HANDLE FileCreate(LPCTSTR); -DWORD FileLength(HANDLE); -HANDLE FileOpen(LPCTSTR); -DWORD FileRead(HANDLE, LPCVOID, DWORD); -DWORD FileSeek(HANDLE hFile, LONG distance, DWORD method); -DWORD FileWrite(HANDLE, LPCVOID, DWORD); - -int access(char* file,int type); -unsigned int file_len(char* file); - -#endif \ No newline at end of file diff --git a/src/win32ce/win_main.c b/src/win32ce/win_main.c deleted file mode 100644 index a8a5c7cf2..000000000 --- a/src/win32ce/win_main.c +++ /dev/null @@ -1,539 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 WinMain Entry Point -/// -/// Win32 Sonic Robo Blast 2 -/// -/// NOTE: -/// To compile WINDOWS SRB2 version : define a '_WINDOWS' symbol. -/// to do this go to Project/Settings/ menu, click C/C++ tab, in -/// 'Preprocessor definitions:' add '_WINDOWS' - -#include "../doomdef.h" -#include - -#include "../doomstat.h" // netgame -#include "resource.h" - -#include "../m_argv.h" -#include "../d_main.h" -#include "../i_system.h" - -#include "../keys.h" //hack quick test - -#include "../console.h" - -#include "fabdxlib.h" -#include "win_main.h" -#include "win_dbg.h" -#include "../i_sound.h" // midi pause/unpause -#include "../g_input.h" // KEY_MOUSEWHEELxxx - -// MSWheel support for Win95/NT3.51 -#include - -#ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 523 -#endif -#ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 524 -#endif -#ifndef MK_XBUTTON1 -#define MK_XBUTTON1 32 -#endif -#ifndef MK_XBUTTON2 -#define MK_XBUTTON2 64 -#endif - -typedef BOOL (WINAPI *MyFunc)(VOID); - -HINSTANCE myInstance = NULL; -HWND hWndMain = NULL; -static HCURSOR windowCursor = NULL; // main window cursor - -boolean appActive = false; // app window is active - -#ifdef LOGMESSAGES -// this is were I log debug text, cons_printf, I_error ect for window port debugging -HANDLE logstream; -#endif - -BOOL nodinput = FALSE; - -static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - event_t ev; //Doom input event - int mouse_keys; - - // judgecutor: - // Response MSH Mouse Wheel event - - if (message == MSHWheelMessage) - { - message = WM_MOUSEWHEEL; - if (win9x) - wParam <<= 16; - } - - - switch (message) - { - case WM_CREATE: - nodinput = M_CheckParm("-nodinput"); - break; - - case WM_ACTIVATEAPP: // Handle task switching - appActive = (int)wParam; - // pause music when alt-tab - if (appActive && !paused) - I_ResumeSong(0); - else if (!paused) - I_PauseSong(0); - { - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - if (ci != INVALID_HANDLE_VALUE && GetFileType(ci) == FILE_TYPE_CHAR) - appActive = true; - } - InvalidateRect (hWnd, NULL, TRUE); - break; - - //for MIDI music - case WM_MSTREAM_UPDATEVOLUME: - I_SetMidiChannelVolume((DWORD)wParam, dwVolumePercent); - break; - - case WM_PAINT: - if (!appActive && !bAppFullScreen && !netgame) - // app becomes inactive (if windowed) - { - // Paint "Game Paused" in the middle of the screen - PAINTSTRUCT ps; - RECT rect; - HDC hdc = BeginPaint (hWnd, &ps); - GetClientRect (hWnd, &rect); - DrawText (hdc, TEXT("Game Paused"), -1, &rect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER); - EndPaint (hWnd, &ps); - return 0; - } - break; - - //case WM_RBUTTONDOWN: - //case WM_LBUTTONDOWN: - - case WM_MOVE: - if (bAppFullScreen) - { - SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - return 0; - } - else - { - windowPosX = (SHORT) LOWORD(lParam); // horizontal position - windowPosY = (SHORT) HIWORD(lParam); // vertical position - break; - } - break; - - // This is where switching windowed/fullscreen is handled. DirectDraw - // objects must be destroyed, recreated, and artwork reloaded. - - case WM_DISPLAYCHANGE: - case WM_SIZE: - break; - - case WM_SETCURSOR: - if (bAppFullScreen) - SetCursor(NULL); - else - SetCursor(windowCursor); - return TRUE; - - case WM_KEYUP: - ev.type = ev_keyup; - goto handleKeyDoom; - break; - - case WM_KEYDOWN: - ev.type = ev_keydown; - - handleKeyDoom: - ev.data1 = 0; - if (wParam == VK_PAUSE) - // intercept PAUSE key - { - ev.data1 = KEY_PAUSE; - } - else if (!keyboard_started) - // post some keys during the game startup - // (allow escaping from network synchronization, or pressing enter after - // an error message in the console) - { - switch (wParam) - { - case VK_ESCAPE: ev.data1 = KEY_ESCAPE; break; - case VK_RETURN: ev.data1 = KEY_ENTER; break; - default: ev.data1 = MapVirtualKey((DWORD)wParam,2); // convert in to char - } - } - - if (ev.data1) - D_PostEvent (&ev); - - return 0; - break; - - // judgecutor: - // Handle mouse events - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - case WM_MOUSEMOVE: - if (nodinput) - { - mouse_keys = 0; - if (wParam & MK_LBUTTON) - mouse_keys |= 1; - if (wParam & MK_RBUTTON) - mouse_keys |= 2; - if (wParam & MK_MBUTTON) - mouse_keys |= 4; - if (wParam & MK_XBUTTON1) - mouse_keys |= 8; - if (wParam & MK_XBUTTON2) - mouse_keys |= 16; - I_GetSysMouseEvents(mouse_keys); - } - break; - - - case WM_MOUSEWHEEL: - //CONS_Printf("MW_WHEEL dispatched.\n"); - ev.type = ev_keydown; - if ((INT16)HIWORD(wParam) > 0) - ev.data1 = KEY_MOUSEWHEELUP; - else - ev.data1 = KEY_MOUSEWHEELDOWN; - D_PostEvent(&ev); - break; - - case WM_SETTEXT: - COM_BufAddText((LPCSTR)lParam); - return TRUE; - break; - - case WM_CLOSE: - PostQuitMessage(0); //to quit while in-game - ev.data1 = KEY_ESCAPE; //to exit network synchronization - ev.type = ev_keydown; - D_PostEvent (&ev); - return 0; - case WM_DESTROY: - //faB: main app loop will exit the loop and proceed with I_Quit() - PostQuitMessage(0); - break; - - default: - break; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} - - -static inline VOID OpenTextConsole(void) -{ - HANDLE ci, co; - const BOOL tco = M_CheckParm("-console") != 0; - dedicated = M_CheckParm("-dedicated") != 0; - if (!(dedicated || tco)) - return; - FreeConsole(); - AllocConsole(); //Let get the real console HANDLE, because Mingw's Bash is bad! - ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (ci != (HANDLE)-1) - { - const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT; - SetStdHandle(STD_INPUT_HANDLE,ci); - if(GetFileType(ci) == FILE_TYPE_CHAR) - SetConsoleMode(ci,CM); //default mode but no ENABLE_MOUSE_INPUT - } - if(co != (HANDLE)-1) - { - SetStdHandle(STD_OUTPUT_HANDLE,co); - SetStdHandle(STD_ERROR_HANDLE,co); //maybe logstream? - } -} - -// -// Do that Windows initialization stuff... -// -static HWND OpenMainWindow (HINSTANCE hInstance, int nCmdShow, LPSTR wTitle) -{ - HWND hWnd; - WNDCLASS wc; - - // Set up and register window class - nCmdShow = 0; - wc.style = CS_HREDRAW | CS_VREDRAW /*| CS_DBLCLKS*/; - wc.lpfnWndProc = MainWndproc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DLICON1)); - windowCursor = LoadCursor(NULL, IDC_WAIT); //LoadCursor(hInstance, MAKEINTRESOURCE(IDC_DLCURSOR1)); - wc.hCursor = windowCursor; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = TEXT("SRB2WC"); - if (!RegisterClass(&wc)) - return (HANDLE)-1; - - // Create a window - // CreateWindowEx - seems to create just the interior, not the borders - - hWnd = CreateWindowExA( -#ifdef _DEBUG - 0, //ExStyle -#else - dedicated ? 0:WS_EX_TOPMOST, //ExStyle -#endif - "SRB2WC", //Classname - wTitle, //Windowname - WS_CAPTION|WS_POPUP|WS_SYSMENU, //dwStyle //WS_VISIBLE|WS_POPUP for bAppFullScreen - 0, - 0, - dedicated ? 0:BASEVIDWIDTH, //GetSystemMetrics(SM_CXSCREEN), - dedicated ? 0:BASEVIDHEIGHT, //GetSystemMetrics(SM_CYSCREEN), - NULL, //hWnd Parent - NULL, //hMenu Menu - hInstance, - NULL); - - return hWnd; -} - - -static inline BOOL tlErrorMessage(const TCHAR *err) -{ - /* make the cursor visible */ - SetCursor(LoadCursor(NULL, IDC_ARROW)); - - // - // warn user if there is one - // - printf("Error %s..\n", err); - fflush(stdout); - - MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK); - return FALSE; -} - - -// ------------------ -// Command line stuff -// ------------------ -#define MAXCMDLINEARGS 64 -static char * myWargv[MAXCMDLINEARGS+1]; -static char myCmdline[512]; - -static VOID GetArgcArgv (LPSTR cmdline) -{ - LPSTR token; - size_t i = 0, len; - char cSep = ' '; - BOOL bCvar = FALSE, prevCvar = FALSE; - - // split arguments of command line into argv - strncpy (myCmdline, cmdline, 511); // in case window's cmdline is in protected memory..for strtok - len = strlen (myCmdline); - - myargc = 0; - while (myargc < MAXCMDLINEARGS) - { - // get token - while (myCmdline[i] == cSep) - i++; - if (i >= len) - break; - token = myCmdline + i; - if (myCmdline[i] == '"') - { - cSep = '"'; - i++; - if (!prevCvar) //cvar leave the "" in - token++; - } - else - cSep = ' '; - - //cvar - if (myCmdline[i] == '+' && cSep == ' ') //a + begins a cvarname, but not after quotes - bCvar = TRUE; - else - bCvar = FALSE; - - while (myCmdline[i] && - myCmdline[i] != cSep) - i++; - - if (myCmdline[i] == '"') - { - cSep = ' '; - if (prevCvar) - i++; // get ending " quote in arg - } - - prevCvar = bCvar; - - if (myCmdline + i > token) - { - myWargv[myargc++] = token; - } - - if (!myCmdline[i] || i >= len) - break; - - myCmdline[i++] = '\0'; - } - myWargv[myargc] = NULL; - - // m_argv.c uses myargv[], we used myWargv because we fill the arguments ourselves - // and myargv is just a pointer, so we set it to point myWargv - myargv = myWargv; -} - - -static inline VOID MakeCodeWritable(VOID) -{ -#ifdef USEASM - // Disable write-protection of code segment - DWORD OldRights; - BYTE *pBaseOfImage = (BYTE *)GetModuleHandle(NULL); - IMAGE_OPTIONAL_HEADER *pHeader = (IMAGE_OPTIONAL_HEADER *) - (pBaseOfImage + ((IMAGE_DOS_HEADER*)pBaseOfImage)->e_lfanew + - sizeof (IMAGE_NT_SIGNATURE) + sizeof (IMAGE_FILE_HEADER)); - if (!VirtualProtect(pBaseOfImage+pHeader->BaseOfCode,pHeader->SizeOfCode,PAGE_EXECUTE_READWRITE,&OldRights)) - I_Error("Could not make code writable\n"); -#endif -} - - - - -// ----------------------------------------------------------------------------- -// HandledWinMain : called by exception handler -// ----------------------------------------------------------------------------- -static int WINAPI HandledWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - int i; - LPSTR args; - - lpCmdLine = NULL; - hPrevInstance = NULL; -#ifdef LOGMESSAGES - // DEBUG!!! - set logstream to NULL to disable debug log - logstream = INVALID_HANDLE_VALUE; - - logstream = CreateFile (TEXT("log.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); //file flag writethrough? -#endif - - // fill myargc,myargv for m_argv.c retrieval of cmdline arguments - CONS_Printf("GetArgcArgv() ...\n"); - args = GetCommandLineA(); - CONS_Printf("lpCmdLine is '%s'\n", args); - GetArgcArgv(args); - // Create a text console window - OpenTextConsole(); - - CONS_Printf("Myargc: %d\n", myargc); - for (i = 0; i < myargc; i++) - CONS_Printf("myargv[%d] : '%s'\n", i, myargv[i]); - - // store for later use, will we need it ? - myInstance = hInstance; - - // open a dummy window, both OpenGL and DirectX need one. - if ((hWndMain = OpenMainWindow(hInstance,nCmdShow, - va("SRB2 "VERSIONSTRING))) == (HANDLE)-1) - { - tlErrorMessage(TEXT("Couldn't open window")); - return FALSE; - } - - // currently starts DirectInput - CONS_Printf("I_StartupSystem() ...\n"); - I_StartupSystem(); - MakeCodeWritable(); - - // startup SRB2 - CONS_Printf("D_SRB2Main() ...\n"); - D_SRB2Main(); - CONS_Printf("Entering main app loop...\n"); - // never return - D_SRB2Loop(); - - // back to Windoze - return 0; -} - -// ----------------------------------------------------------------------------- -// Exception handler calls WinMain for catching exceptions -// ----------------------------------------------------------------------------- -int WINAPI WinMain (HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - int Result = -1; -#if 1 - HMODULE h = GetModuleHandleA("kernel32.dll"); - MyFunc pfnIsDebuggerPresent = NULL; - if (h) - pfnIsDebuggerPresent = (MyFunc)GetProcAddress(h,"IsDebuggerPresent"); - if (!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) - LoadLibrary("exchndl.dll"); -#endif -#ifdef NO_SEH_MINGW - __try1(RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/)) -#else - __try -#endif - { - Result = HandledWinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow); - } -#ifdef NO_SEH_MINGW - __except1 -#else - __except (RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/)) -#endif - { - SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here. - } - - return Result; -} diff --git a/src/win32ce/win_main.h b/src/win32ce/win_main.h deleted file mode 100644 index fef25327d..000000000 --- a/src/win32ce/win_main.h +++ /dev/null @@ -1,55 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 Sharing - -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include -#include - -extern HINSTANCE myInstance; -extern HWND hWndMain; - -// debugging CONS_Printf to file -#ifdef LOGMESSAGES -extern HANDLE logstream; -#endif -extern int appActive; - -// the MIDI callback is another thread, and Midi volume is delayed here in window proc -VOID I_SetMidiChannelVolume(DWORD dwChannel, DWORD dwVolumePercent); -extern DWORD dwVolumePercent; - -VOID I_GetSysMouseEvents(int mouse_state); -extern unsigned int MSHWheelMessage; - -extern BOOL nodinput; -extern BOOL win9x; - -//faB: midi channel Volume set is delayed by the MIDI stream callback thread, see win_snd.c -#define WM_MSTREAM_UPDATEVOLUME (WM_USER + 101) - -// defined in win_sys.c -VOID I_BeginProfile(VOID); //for timing code -DWORD I_EndProfile(VOID); - -VOID I_GetLastErrorMsgBox(VOID); -VOID I_LoadingScreen (LPCSTR msg); - -void I_RestartSysMouse(void); -void I_DoStartupMouse(void); -BOOL I_SaveMemToFile(const void *pData, size_t iLength, const char *sFileName); diff --git a/src/win32ce/win_net.c b/src/win32ce/win_net.c deleted file mode 100644 index dac1bed53..000000000 --- a/src/win32ce/win_net.c +++ /dev/null @@ -1,39 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief Win32 network interface - -#include "../doomdef.h" -#include "../m_argv.h" -#include "../i_net.h" - -// -// NETWORKING -// - -// -// I_InitNetwork -// -boolean I_InitNetwork (void) -{ - if (M_CheckParm ("-net")) - { - I_Error("The Win32 version of SRB2 doesn't work with external drivers like ipxsetup, sersetup, or doomatic\n" - "Read the documentation about \"-server\" and \"-connect\" parameters or just use the launcher\n"); - } - - return false; -} diff --git a/src/win32ce/win_snd.c b/src/win32ce/win_snd.c deleted file mode 100644 index f9c652178..000000000 --- a/src/win32ce/win_snd.c +++ /dev/null @@ -1,2406 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief interface level code for sound -/// -/// Uses the midiStream* Win32 functions to play MIDI data -/// with low latency and low processor overhead. -#include "../doomdef.h" - -#include "win_main.h" -#include -#define DIRECTSOUND_VERSION 0x0600 /* version 6.0 */ -#define DIRECTINPUT_VERSION 0x0700 -#define DXVERSION_NTCOMPATIBLE 0x0300 -#ifdef _MSC_VER -#pragma warning(disable : 4201) -#endif -#include - -#include "../command.h" -#include "../i_sound.h" -#include "../s_sound.h" -#include "../i_system.h" -#include "../m_argv.h" -#include "../w_wad.h" -#include "../z_zone.h" -#include "../doomstat.h" - -#include "dx_error.h" - -#include "mid2strm.h" - -#ifdef HW3SOUND -#include "../hardware/hw3dsdrv.h" -#include "../hardware/hw3sound.h" -#include "win_dll.h" -#endif - -#ifndef SURROUND -#define SURROUND // comment out this to disable the SurroundSound code -#endif - -#ifdef SURROUND -ATTRNOINLINE static FUNCNOINLINE void CopyAndInvertMemory(void *dest, void *src, int bytes); //Can't inline ASM that haves lables -#endif - -#define FMODSOUND // comment out this to disable MOD/IT/MP3/OGG music playback - -/////////////////////////////////////////////////////////// -#ifdef FMODSOUND -#ifdef __MINGW32__ -#include -#else -#include -#endif -#ifdef FSOUND_INIT_DONTLATENCYADJUST //Alam: why didn't I think about this before? :) -#define FSOUND_Stream_OpenFile(name,mode,length) FSOUND_Stream_Open(name,mode,0,length) -#else -#define FSOUND_INIT_DONTLATENCYADJUST 0 -#endif -#ifdef __MINGW32__ -#include -#else -#include /* optional */ -#endif -//#include -#endif -///////////////////////////////////////////////////////// - -//#define TESTCODE // remove this for release version - -/* briefly described here for convenience: -typedef struct { - WORD wFormatTag; // WAVE_FORMAT_PCM is the only format accepted for DirectSound: - // this tag indicates Pulse Code Modulation (PCM), an uncompressed format - // in which each samples represents the amplitude of the signal at the time - // of sampling. - WORD nChannels; // either one (mono) or two (stereo) - DWORD nSamplesPerSec; // the sampling rate, or frequency, in hertz. - // Typical values are 11,025, 22,050, and 44,100 - DWORD nAvgBytesPerSec; // nAvgBytesPerSec is the product of nBlockAlign and nSamplesPerSec - WORD nBlockAlign; // the number of bytes required for each complete sample, for PCM formats - // is equal to (wBitsPerSample * nChannels / 8). - WORD wBitsPerSample; // gives the size of each sample, generally 8 or 16 bits - WORD cbSize; // cbSize gives the size of any extra fields required to describe a - // specialized wave format. This member is always zero for PCM formats. -} WAVEFORMATEX; -*/ - -// Tails 11-21-2002 -#ifdef FMODSOUND -static FMUSIC_MODULE *mod = NULL; -static int fsoundchannel = -1; -static int fsoundfreq = 0; -static int fmodvol = 127; -static FSOUND_STREAM *fmus = NULL; -#endif - -// -------------------------------------------------------------------------- -// DirectSound stuff -// -------------------------------------------------------------------------- -static LPDIRECTSOUND DSnd = NULL; -static LPDIRECTSOUNDBUFFER DSndPrimary = NULL; ; - -// Stack sounds means sounds put on top of each other, since DirectSound can't play -// the same sound buffer at different locations at the same time, we need to dupli- -// cate existing buffers to play multiple instances of the same sound in the same -// time frame. A duplicate sound is freed when it is no more used. The priority that -// comes from the s_sound engine, is kept so that the lowest priority sounds are -// stopped to make place for the new sound, unless the new sound has a lower priority -// than all playing sounds, in which case the sound is not started. -#define MAXSTACKSOUNDS 32 // this is the absolute number of sounds that - // can play simultaneously, whatever the value - // of cv_numChannels -typedef struct { - LPDIRECTSOUNDBUFFER lpSndBuf; -#ifdef SURROUND - // judgecutor: - // Need for produce surround sound - LPDIRECTSOUNDBUFFER lpSurround; -#endif - int priority; - boolean duplicate; -} StackSound_t; -static StackSound_t StackSounds[MAXSTACKSOUNDS]; - -// -------------------------------------------------------------------------- -// Fill the DirectSoundBuffer with data from a sample, made separate so that -// sound data cna be reloaded if a sound buffer was lost. -// -------------------------------------------------------------------------- -static boolean CopySoundData (LPDIRECTSOUNDBUFFER dsbuffer, LPBYTE data, DWORD length) -{ - LPVOID lpvAudio1; // receives address of lock start - DWORD dwBytes1; // receives number of bytes locked - LPVOID lpvAudio2; // receives address of lock start - DWORD dwBytes2; // receives number of bytes locked - HRESULT hr; - - // Obtain memory address of write block. - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - - // If DSERR_BUFFERLOST is returned, restore and retry lock. - if (hr == DSERR_BUFFERLOST) - { - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (FAILED (hr)) - I_Error("Restore fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - if (FAILED (hr)) - I_Error("Lock fail(2) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - } - else - if (FAILED (hr)) - I_Error("Lock fail(1) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - // copy wave data into the buffer (note: dwBytes1 should equal to dsbdesc->dwBufferBytes ...) - CopyMemory (lpvAudio1, data, dwBytes1); - - if (dwBytes2 && lpvAudio2) - CopyMemory(lpvAudio2, data+dwBytes1, dwBytes2); - - // finally, unlock the buffer - hr = IDirectSoundBuffer_Unlock (dsbuffer, lpvAudio1, dwBytes1, lpvAudio2, dwBytes2); - - if (FAILED (hr)) - I_Error("Unlock fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - return true; -} - -#ifdef SURROUND -// judgecutor: -// Hmmm... May be this function is not too good... -static void CopyAndInvertMemory(void *dest, void *src, int bytes) -{ -#ifdef __GNUC__ - __asm__("CAIM:;lodsb;neg %%al;stosb;loop CAIM;"::"c"(bytes),"D"(dest),"S"(src): "memory","cc"); -#else - _asm - { - push esi - push edi - push ecx - mov ecx,bytes - mov esi,src - mov edi,dest -a: - lodsb - neg al - stosb - loop a - pop ecx - pop edi - pop esi - } -#endif -} - -// judgecutor: -// Like normal CopySoundData but sound data will be inverted -static boolean CopyAndInvertSoundData(LPDIRECTSOUNDBUFFER dsbuffer, LPBYTE data, DWORD length) -{ - LPVOID lpvAudio1 = NULL; // receives address of lock start - DWORD dwBytes1 = 0; // receives number of bytes locked - LPVOID lpvAudio2 = NULL; - DWORD dwBytes2 = 0; - HRESULT hr; - - // Obtain memory address of write block. - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - - // If DSERR_BUFFERLOST is returned, restore and retry lock. - if (hr == DSERR_BUFFERLOST) - { - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (FAILED (hr)) - I_Error("CopyAndInvert: Restore fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - hr = IDirectSoundBuffer_Lock (dsbuffer, 0, length, &lpvAudio1, &dwBytes1, &lpvAudio2, &dwBytes2, 0); - if (FAILED (hr)) - I_Error("CopyAndInvert: Lock fail(2) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - } else if (FAILED (hr)) - I_Error("CopyAndInvetrt: Lock fail(1) on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - // copy wave data into the buffer (note: dwBytes1 should equal to dsbdesc->dwBufferBytes ...) - CopyAndInvertMemory (lpvAudio1, data, dwBytes1); - - if (dwBytes2 && lpvAudio2) - CopyAndInvertMemory(lpvAudio2, data+dwBytes1, dwBytes2); - - hr = IDirectSoundBuffer_Unlock (dsbuffer, lpvAudio1, dwBytes1, lpvAudio2, dwBytes2); - if (FAILED (hr)) - I_Error("CopyAndInvert: Unlock fail on %x, %s\n",dsbuffer,DXErrorToString(hr)); - - return false; -} -#endif - -static DWORD sound_buffer_flags = DSBCAPS_CTRLPAN | - DSBCAPS_CTRLVOLUME | - DSBCAPS_STICKYFOCUS | - //DSBCAPS_LOCSOFTWARE | - DSBCAPS_STATIC; - -// -------------------------------------------------------------------------- -// raw2DS : convert a raw sound data, returns a LPDIRECTSOUNDBUFFER -// -------------------------------------------------------------------------- -// dsdata points a 4 UINT16 header: -// +0 : value 3 what does it mean? -// +2 : sample rate, either 11025 or 22050. -// +4 : number of samples, each sample is a single byte since it's 8bit -// +6 : value 0 -// -#ifdef SURROUND -// judgecutor: -// We need an another function definition for supporting the surround sound -// Invert just cause to copy an inverted sound data -static LPDIRECTSOUNDBUFFER raw2DS(LPBYTE *dsdata, size_t len, UINT8 invert) -#else -static LPDIRECTSOUNDBUFFER raw2DS(LPBYTE *dsdata, size_t len) -#endif -{ - HRESULT hr; - WAVEFORMATEX wfm; - DSBUFFERDESC dsbdesc; - LPDIRECTSOUNDBUFFER dsbuffer; - - // initialise WAVEFORMATEX structure describing the wave format - ZeroMemory (&wfm, sizeof (WAVEFORMATEX)); - wfm.wFormatTag = WAVE_FORMAT_PCM; - wfm.nChannels = 1; - wfm.nSamplesPerSec = (dsdata[3]<<8)+dsdata[2]; //mostly 11025, but some at 22050. - wfm.wBitsPerSample = 8; - wfm.nBlockAlign = (WORD)(wfm.wBitsPerSample / 8 * wfm.nChannels); - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign; - - // Set up DSBUFFERDESC structure. - ZeroMemory (&dsbdesc, sizeof (DSBUFFERDESC)); - dsbdesc.dwSize = sizeof (DSBUFFERDESC); -/* dsbdesc.dwFlags = DSBCAPS_CTRLPAN | - DSBCAPS_CTRLVOLUME | - DSBCAPS_STICKYFOCUS | - //DSBCAPS_LOCSOFTWARE | - DSBCAPS_STATIC - | DSBCAPS_CTRLFREQUENCY; // This one for pitching -*/ - dsbdesc.dwFlags = sound_buffer_flags; - dsbdesc.dwBufferBytes = len-8; - dsbdesc.lpwfxFormat = &wfm; // pointer to WAVEFORMATEX structure - - // Create the sound buffer - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &dsbuffer, NULL); - - if (hr == DSERR_CONTROLUNAVAIL) - { - CONS_Printf("\tSoundBufferCreate error - a buffer control is not available.\n\tTrying to disable frequency control.\n"); - - sound_buffer_flags &= ~DSBCAPS_CTRLFREQUENCY; - dsbdesc.dwFlags = sound_buffer_flags; - - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &dsbuffer, NULL); - } - - if (FAILED(hr)) - I_Error("CreateSoundBuffer() FAILED: %s\n", DXErrorToString(hr)); - -#ifdef SURROUND - if (invert) - // just invert a sound data for producing the surround sound - CopyAndInvertSoundData(dsbuffer, (LPBYTE)dsdata + 8, dsbdesc.dwBufferBytes); - else - // Do a normal operation -#endif - // fill the DirectSoundBuffer waveform data - CopySoundData (dsbuffer, (LPBYTE)dsdata + 8, dsbdesc.dwBufferBytes); - - return dsbuffer; -} - - -// -------------------------------------------------------------------------- -// This function loads the sound data from the WAD lump, for single sound. -// -------------------------------------------------------------------------- -void *I_GetSfx (sfxinfo_t * sfx) -{ - LPBYTE dssfx; - - if (sfx->lumpnum < 0) - sfx->lumpnum = S_GetSfxLumpNum (sfx); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_GetSfx(sfx); -#endif - - sfx->length = W_LumpLength (sfx->lumpnum); - - // PU_CACHE because the data is copied to the DIRECTSOUNDBUFFER, the one here will not be used - dssfx = (LPBYTE) W_CacheLumpNum (sfx->lumpnum, PU_CACHE); - -#ifdef SURROUND - // Make a normal (not inverted) sound buffer - return (void *)raw2DS (dssfx, sfx->length, FALSE); -#else - // return the LPDIRECTSOUNDBUFFER, which will be stored in S_sfx[].data - return (void *)raw2DS (dssfx, sfx->length); -#endif -} - - -// -------------------------------------------------------------------------- -// Free all allocated resources for a single sound -// -------------------------------------------------------------------------- -void I_FreeSfx (sfxinfo_t *sfx) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - - if (sfx->lumpnum < 0) - return; - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_FreeSfx(sfx); - } - else -#endif - { - //CONS_Printf("I_FreeSfx(%d)\n", sfx->lumpnum); - - // free DIRECTSOUNDBUFFER - dsbuffer = (LPDIRECTSOUNDBUFFER) sfx->data; - if (dsbuffer) - { - size_t i; - for (i = 0; i < MAXSTACKSOUNDS; i++) - { - if (StackSounds[i].lpSndBuf == dsbuffer) - { - StackSounds[i].lpSndBuf = NULL; -#ifdef SURROUND - if (StackSounds[i].lpSurround) - { - IDirectSoundBuffer_Stop(StackSounds[i].lpSurround); - IDirectSoundBuffer_Release(StackSounds[i].lpSurround); - } - StackSounds[i].lpSurround = NULL; -#endif - } - } - IDirectSoundBuffer_Stop (dsbuffer); - IDirectSoundBuffer_Release (dsbuffer); - } - } - sfx->data = NULL; - sfx->lumpnum = -1; -} - - -// -------------------------------------------------------------------------- -// Set the global volume for sound effects -// -------------------------------------------------------------------------- -void I_SetSfxVolume(INT32 volume) -{ - int vol; - HRESULT hr; - - if (nosound || !sound_started) - return; - - // use the last quarter of volume range - if (volume) - vol = (volume * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / 31 + - (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)); - else - vol = DSBVOLUME_MIN; // make sure 0 is silence - //CONS_Printf("setvolume to %d\n", vol); - hr = IDirectSoundBuffer_SetVolume (DSndPrimary, vol); - //if (FAILED(hr)) - // CONS_Printf("setvolumne failed\n"); -} - - -// -------------------------------------------------------------------------- -// Update the volume for a secondary buffer, make sure it was created with -// DSBCAPS_CTRLVOLUME -// -------------------------------------------------------------------------- -static void I_UpdateSoundVolume (LPDIRECTSOUNDBUFFER lpSnd, int volume) -{ - HRESULT hr; - volume = (volume * ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)) / 256 + - (DSBVOLUME_MAX - ((DSBVOLUME_MAX-DSBVOLUME_MIN)/4)); - hr = IDirectSoundBuffer_SetVolume (lpSnd, volume); - //if (FAILED(hr)) - // CONS_Printf("\2SetVolume FAILED\n"); -} - - -// -------------------------------------------------------------------------- -// Update the panning for a secondary buffer, make sure it was created with -// DSBCAPS_CTRLPAN -// -------------------------------------------------------------------------- -#define DSBPAN_RANGE (DSBPAN_RIGHT-(DSBPAN_LEFT)) -#define SEP_RANGE 256 //Doom sounds pan range 0-255 (128 is centre) -static void I_UpdateSoundPanning (LPDIRECTSOUNDBUFFER lpSnd, int sep) -{ - HRESULT hr; - hr = IDirectSoundBuffer_SetPan (lpSnd, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT); - //if (FAILED(hr)) - // CONS_Printf("SetPan FAILED for sep %d pan %d\n", sep, (sep * DSBPAN_RANGE)/SEP_RANGE - DSBPAN_RIGHT); -} - -// search a free slot in the stack, free it if needed -static int GetFreeStackNum(int newpriority) -{ - int lowestpri = 256,lowestprihandle = 0; - int i; - // DirectSound can't play multiple instances of the same sound buffer - // unless they are duplicated, so if the sound buffer is in use, make a duplicate - for (i = 0; i < MAXSTACKSOUNDS; i++) - { - // find a free 'playing sound slot' to use - if (StackSounds[i].lpSndBuf == NULL) - { - //CONS_Printf("\t\tfound free slot %d\n", i); - return i; - } - else if (!I_SoundIsPlaying(i)) // check for sounds that finished playing, and can be freed - { - //CONS_Printf("\t\tfinished sound in slot %d\n", i); - //stop sound and free the 'slot' - I_StopSound (i); - // we can use this one since it's now freed - return i; - } - else if (StackSounds[i].priority < lowestpri) //remember lowest priority sound - { - lowestpri = StackSounds[i].priority; - lowestprihandle = i; - } - } - - // the maximum of sounds playing at the same time is reached, if we have at least - // one sound playing with a lower priority, stop it and replace it with the new one - - //CONS_Printf("\t\tall slots occupied..\n"); - if (newpriority >= lowestpri) - { - I_StopSound (lowestprihandle); - return lowestprihandle; - //CONS_Printf(" kicking out lowest priority slot: %d pri: %d, my priority: %d\n", - // handle, lowestpri, priority); - } - - return -1; -} - -#ifdef SURROUND -static LPDIRECTSOUNDBUFFER CreateInvertedSound(int id) -{ - lumpnnum_t lumpnum; - LBYPTE dsdata; - - lumpnum = S_sfx[id].lumpnum; - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - return raw2DS(dsdata, S_sfx[id].length, TRUE); -} -#endif - -// Calculate internal pitch from Doom pitch -#if 0 -static float recalc_pitch(int doom_pitch) -{ - return doom_pitch < NORMAL_PITCH ? - (float)(doom_pitch + NORMAL_PITCH) / (NORMAL_PITCH * 2) - :(float)doom_pitch / (float)NORMAL_PITCH; -} -#endif - -// -------------------------------------------------------------------------- -// Start the given S_sfx[id] sound with given properties (panning, volume..) -// -------------------------------------------------------------------------- -INT32 I_StartSound (sfxenum_t id, - INT32 vol, - INT32 sep, - INT32 pitch, - INT32 priority) -{ - HRESULT hr; - LPDIRECTSOUNDBUFFER dsbuffer; - DWORD dwStatus; - int handle; - int i; - //DWORD freq; -#ifdef SURROUND - LPDIRECTSOUNDBUFFER dssurround; -#endif - - if (nosound) - return -1; - - //CONS_Printf("I_StartSound:\n\t\tS_sfx[%d]\n", id); - handle = GetFreeStackNum(priority); - if (handle < 0) - return -1; - - //CONS_Printf("\t\tusing handle %d\n", handle); - - // if the original buffer is playing, duplicate it (DirectSound specific) - // else, use the original buffer - dsbuffer = (LPDIRECTSOUNDBUFFER) S_sfx[id].data; - IDirectSoundBuffer_GetStatus (dsbuffer, &dwStatus); - if (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) - { - //CONS_Printf("\t\toriginal sound S_sfx[%d] is playing, duplicating.. ", id); - hr = IDirectSound_DuplicateSoundBuffer(DSnd, (LPDIRECTSOUNDBUFFER) S_sfx[id].data, &dsbuffer); - if (FAILED(hr)) - { - //CONS_Printf("Cound't duplicate sound buffer\n"); - // re-use the original then.. - dsbuffer = (LPDIRECTSOUNDBUFFER) S_sfx[id].data; - // clean up stacksounds info - for (i = 0; i < MAXSTACKSOUNDS; i++) - if (handle != i && - StackSounds[i].lpSndBuf == dsbuffer) - { - StackSounds[i].lpSndBuf = NULL; - } - } - // stop the duplicate or the re-used original - IDirectSoundBuffer_Stop (dsbuffer); - } - - //judgecutor: Sound pitching -#if 0 - if (cv_rndsoundpitch.value) - { - // At first reset the buffer back to original frequency - hr = IDirectSoundBuffer_SetFrequency(dsbuffer, DSBFREQUENCY_ORIGINAL); - if (SUCCEEDED (hr)) - { - - IDirectSoundBuffer_GetFrequency(dsbuffer, &freq); - - // Now pitch it - freq *= recalc_pitch(pitch); - IDirectSoundBuffer_SetFrequency(dsbuffer, freq); - } - else - cv_rndsoundpitch = 0; - } -#else - pitch = 0; -#endif - // store information on the playing sound - StackSounds[handle].lpSndBuf = dsbuffer; - StackSounds[handle].priority = priority; - StackSounds[handle].duplicate = (dsbuffer != (LPDIRECTSOUNDBUFFER)S_sfx[id].data); - - //CONS_Printf("StackSounds[%d].lpSndBuf is %s\n", handle, StackSounds[handle].lpSndBuf == NULL ? "Null":"valid"); - //CONS_Printf("StackSounds[%d].priority is %d\n", handle, StackSounds[handle].priority); - //CONS_Printf("StackSounds[%d].duplicate is %s\n", handle, StackSounds[handle].duplicate ? "TRUE":"FALSE"); - - I_UpdateSoundVolume (dsbuffer, vol); - -#ifdef SURROUND - // Prepare the surround sound buffer - // Use a normal sound data for the left channel (with pan == 0) - // and an inverted sound data for the right channel (with pan == 255) - - dssurround = CreateInvertedSound(id); - - // Surround must be pitched too -#if 0 - if (cv_rndsoundpitch.value) - IDirectSoundBuffer_SetFrequency(dssurround, freq); -#endif - if (sep == -128) - { - I_UpdateSoundPanning(dssurround, 255); - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundPanning(dsbuffer, 0); - IDirectSoundBuffer_SetCurrentPosition(dssurround, 0); - } - else - // Perform normal operation -#endif - - I_UpdateSoundPanning (dsbuffer, sep); - - IDirectSoundBuffer_SetCurrentPosition (dsbuffer, 0); - - hr = IDirectSoundBuffer_Play (dsbuffer, 0, 0, 0); - if (hr == DSERR_BUFFERLOST) - { - //CONS_Printf("buffer lost\n"); - // restores the buffer memory and all other settings for the buffer - hr = IDirectSoundBuffer_Restore (dsbuffer); - if (SUCCEEDED (hr)) - { - LPBYTE dsdata; - // reload sample data here - int lumpnum = S_sfx[id].lumpnum; - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - - // Well... Data lenght must be -8!!! - CopySoundData (dsbuffer, dsdata + 8, S_sfx[id].length - 8); - - // play - hr = IDirectSoundBuffer_Play (dsbuffer, 0, 0, 0); - } - else - I_Error("I_StartSound : ->Restore FAILED, %s",DXErrorToString(hr)); - } - -#ifdef SURROUND - if (sep == -128) - { - hr = IDirectSoundBuffer_Play (dssurround, 0, 0, 0); - //CONS_Printf("Surround playback\n"); - if (hr == DSERR_BUFFERLOST) - { - // restores the buffer memory and all other settings for the surround buffer - hr = IDirectSoundBuffer_Restore (dssurround); - if (SUCCEEDED (hr)) - { - LPBYTE dsdata; - lumpnumt_t lumpnum = S_sfx[id].lumpnum; - - if (lumpnum < 0) - lumpnum = S_GetSfxLumpNum (&S_sfx[id]); - dsdata = W_CacheLumpNum (lumpnum, PU_CACHE); - CopyAndInvertSoundData (dssurround, (LPBYTE)dsdata + 8, S_sfx[id].length - 8); - - hr = IDirectSoundBuffer_Play (dssurround, 0, 0, 0); - } - else - I_Error("I_StartSound : ->Restore FAILED, %s",DXErrorToString(hr)); - } - } - StackSounds[handle].lpSurround = dssurround; -#endif - - // Returns a handle - return handle; -} - - -// -------------------------------------------------------------------------- -// Stop a sound if it is playing, -// free the corresponding 'playing sound slot' in StackSounds[] -// -------------------------------------------------------------------------- -void I_StopSound (INT32 handle) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - HRESULT hr; - - if (nosound || handle < 0) - return; - - //CONS_Printf("I_StopSound (%d)\n", handle); - - dsbuffer = StackSounds[handle].lpSndBuf; - hr = IDirectSoundBuffer_Stop (dsbuffer); - - // free duplicates of original sound buffer (DirectSound hassles) - if (StackSounds[handle].duplicate) - { - //CONS_Printf("\t\trelease a duplicate..\n"); - IDirectSoundBuffer_Release (dsbuffer); - } - -#ifdef SURROUND - // Stop and release the surround sound buffer - dsbuffer = StackSounds[handle].lpSurround; - if (dsbuffer != NULL) - { - IDirectSoundBuffer_Stop(dsbuffer); - IDirectSoundBuffer_Release(dsbuffer); - } - StackSounds[handle].lpSurround = NULL; -#endif - - StackSounds[handle].lpSndBuf = NULL; -} - - -// -------------------------------------------------------------------------- -// Returns whether the sound is currently playing or not -// -------------------------------------------------------------------------- -INT32 I_SoundIsPlaying(INT32 handle) -{ - LPDIRECTSOUNDBUFFER dsbuffer; - DWORD dwStatus; - - if (nosound || handle == -1) - return FALSE; - - dsbuffer = StackSounds[handle].lpSndBuf; - if (dsbuffer) - { - IDirectSoundBuffer_GetStatus (dsbuffer, &dwStatus); - if (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) - return TRUE; - } - - return FALSE; -} - - -// -------------------------------------------------------------------------- -// Update properties of a sound currently playing -// -------------------------------------------------------------------------- -void I_UpdateSoundParams(INT32 handle, - INT32 vol, - INT32 sep, - INT32 pitch) -{ - LPDIRECTSOUNDBUFFER dsbuffer; -#ifdef SURROUND - LPDIRECTSOUNDBUFFER dssurround; - DWORD dwStatus; - DWORD pos; - boolean surround_inuse = FALSE; -#endif - - if (nosound) - return; - - pitch = 0; /// \todo pitch setup - dsbuffer = StackSounds[handle].lpSndBuf; - -#ifdef SURROUND - if (dsbuffer == NULL) - return; - - dssurround = StackSounds[handle].lpSurround; - if (dssurround) - { - IDirectSoundBuffer_GetStatus(dssurround, &dwStatus); - surround_inuse = (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)); - } - // If pan changed to stereo... - if (sep != -128) - { - if (surround_inuse) - { - IDirectSoundBuffer_Stop(dssurround); - surround_inuse = FALSE; - } - } - else if (!surround_inuse) // Just update volumes and start the surround if need - { - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundPanning(dsbuffer, 0); - IDirectSoundBuffer_GetCurrentPosition(dsbuffer, &pos, NULL); - IDirectSoundBuffer_SetCurrentPosition(dssurround, pos); - IDirectSoundBuffer_Play(dssurround, 0, 0, 0); - surround_inuse = TRUE; - } - else - I_UpdateSoundVolume(dssurround, vol); - I_UpdateSoundVolume(dsbuffer, vol); - - if (!surround_inuse) - I_UpdateSoundPanning(dsbuffer, sep); -#else - if (dsbuffer) - { - I_UpdateSoundVolume (dsbuffer, vol); - I_UpdateSoundPanning (dsbuffer, sep); - } -#endif -} - - -// -// Shutdown DirectSound -// -void I_ShutdownSound(void) -{ - int i; - - CONS_Printf("I_ShutdownSound()\n"); - -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_Shutdown(); - Shutdown3DSDriver(); - return; - } -#endif - // release any temporary 'duplicated' secondary buffers - for (i = 0; i < MAXSTACKSOUNDS; i++) - if (StackSounds[i].lpSndBuf) - // stops the sound and release it if it is a duplicate - I_StopSound (i); - - if (DSnd) - { - IDirectSound_Release(DSnd); - DSnd = NULL; - } -} - - -// ========================================================================== -// Startup DirectSound -// ========================================================================== -void I_StartupSound(void) -{ - HRESULT hr; - LPDIRECTSOUNDBUFFER lpDsb; - DSBUFFERDESC dsbdesc; - WAVEFORMATEX wfm; - int cooplevel; - int frequency; - -#ifdef HW3SOUND - const char *sdrv_name = NULL; - snddev_t snddev; -#endif - - sound_started = false; - - if (dedicated) - return; - - if (nosound) - return; - - // Secure and configure sound device first. - CONS_Printf("I_StartupSound: "); - - // frequency of primary buffer may be set at cmd-line - if (M_CheckParm ("-freq") && M_IsNextParm()) - { - frequency = atoi(M_GetNextParm()); - CONS_Printf(" requested frequency of %d hz\n", frequency); - CV_SetValue(&cv_samplerate,frequency); - } - else - frequency = cv_samplerate.value; - - // Set cooperative level - // Cooperative sound with other applications can be requested at cmd-line - if (M_CheckParm("-coopsound")) - cooplevel = DSSCL_PRIORITY; - else - cooplevel = DSSCL_EXCLUSIVE; - -#ifdef HW3SOUND - if (M_CheckParm("-ds3d")) - { - hws_mode = HWS_DS3D; - sdrv_name = "s_ds3d.dll"; - } -#if 1 - else if (M_CheckParm("-fmod3d")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } -#else - else if (M_CheckParm("-sounddriver") && M_IsNextParm()) - { - hws_mode = HWS_OTHER; - sdrv_name = M_GetNextParm(); - } - else if (!M_CheckParm("-nosd")) - { - hws_mode = HWS_FMOD3D; - sdrv_name = "s_fmod.dll"; - } -#endif - - // There must be further sound drivers (such as A3D and EAX)!!! - - if (hws_mode != HWS_DEFAULT_MODE && sdrv_name != NULL) - { - if (Init3DSDriver(sdrv_name)) - { - //nosound = true; - snddev.sample_rate = frequency; - snddev.bps = 16; - snddev.numsfxs = NUMSFX; - snddev.cooplevel = cooplevel; - snddev.hWnd = hWndMain; - if (HW3S_Init(I_Error, &snddev)) - { - CONS_Printf("Using external sound driver %s\n", sdrv_name); - I_AddExitFunc(I_ShutdownSound); - return; - } - // Falls back to default sound system - CONS_Printf("Not using external sound driver %s\n", sdrv_name); - HW3S_Shutdown(); - Shutdown3DSDriver(); - } - hws_mode = HWS_DEFAULT_MODE; - } -#endif - - // Create DirectSound, use the default sound device - hr = DirectSoundCreate(NULL, &DSnd, NULL); - if (FAILED(hr)) - { - CONS_Printf(" DirectSoundCreate FAILED\n" - " there is no sound device or the sound device is under\n" - " the control of another application\n"); - nosound = true; - return; - } - - // register exit code, now that we have at least DirectSound to close - I_AddExitFunc(I_ShutdownSound); - hr = IDirectSound_SetCooperativeLevel (DSnd, hWndMain, cooplevel); - if (FAILED(hr)) - { - CONS_Printf(" SetCooperativeLevel FAILED\n"); - nosound = true; - return; - } - - // Set up DSBUFFERDESC structure. - ZeroMemory (&dsbdesc, sizeof (DSBUFFERDESC)); - dsbdesc.dwSize = sizeof (DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | - DSBCAPS_CTRLVOLUME; - dsbdesc.dwBufferBytes = 0; // Must be 0 for primary buffer - dsbdesc.lpwfxFormat = NULL; // Must be NULL for primary buffer - - // Set up structure for the desired format - ZeroMemory (&wfm, sizeof (WAVEFORMATEX)); - wfm.wFormatTag = WAVE_FORMAT_PCM; - wfm.nChannels = 2; //STEREO SOUND! - wfm.nSamplesPerSec = frequency; - wfm.wBitsPerSample = 16; - wfm.nBlockAlign = (WORD)(wfm.wBitsPerSample / 8 * wfm.nChannels); - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign; - - // Gain access to the primary buffer - hr = IDirectSound_CreateSoundBuffer (DSnd, &dsbdesc, &lpDsb, NULL); - if (FAILED(hr)) - { - CONS_Printf("CreateSoundBuffer FAILED: %s (ErrNo %d)\n", DXErrorToString(hr), hr); - nosound = true; - return; - } - - // Set the primary buffer to the desired format, - // but only if we are allowed to do it - if (cooplevel >= DSSCL_PRIORITY) - { - if (SUCCEEDED (hr)) - { - // Set primary buffer to the desired format. If this fails, - // we'll just ignore and go with the default. - hr = IDirectSoundBuffer_SetFormat (lpDsb, &wfm); - if (FAILED(hr)) - CONS_Printf("I_StartupSound : couldn't set primary buffer format.\n"); - else - CV_SetValue(&cv_samplerate,wfm.nSamplesPerSec); - } - // move any on-board sound memory into a contiguous block - // to make the largest portion of free memory available. - - CONS_Printf(" Compacting onboard sound-memory..."); - hr = IDirectSound_Compact (DSnd); - CONS_Printf(" %s\n", SUCCEEDED(hr) ? "Done\n" : "Failed\n")); - } - - // set the primary buffer to play continuously, for performance - // "... this method will ensure that the primary buffer is playing even when no secondary - // buffers are playing; in that case, silence will be played. This can reduce processing - // overhead when sounds are started and stopped in sequence, because the primary buffer - // will be playing continuously rather than stopping and starting between secondary buffers." - hr = IDirectSoundBuffer_Play (lpDsb, 0, 0, DSBPLAY_LOOPING); - if (FAILED (hr)) - CONS_Printf(" Primary buffer continuous play FAILED\n"); - -#ifdef DEBUGSOUND - { - DSCAPS DSCaps; - DSCaps.dwSize = sizeof (DSCAPS); - hr = IDirectSound_GetCaps (DSnd, &DSCaps); - if (SUCCEEDED (hr)) - { - if (DSCaps.dwFlags & DSCAPS_CERTIFIED) - CONS_Printf("This driver has been certified by Microsoft\n"); - if (DSCaps.dwFlags & DSCAPS_EMULDRIVER) - CONS_Printf("No driver with DirectSound support installed (no hardware mixing)\n"); - if (DSCaps.dwFlags & DSCAPS_PRIMARY16BIT) - CONS_Printf("Supports 16-bit primary buffer\n"); - if (DSCaps.dwFlags & DSCAPS_PRIMARY8BIT) - CONS_Printf("Supports 8-bit primary buffer\n"); - if (DSCaps.dwFlags & DSCAPS_SECONDARY16BIT) - CONS_Printf("Supports 16-bit, hardware-mixed secondary buffers\n"); - if (DSCaps.dwFlags & DSCAPS_SECONDARY8BIT) - CONS_Printf("Supports 8-bit, hardware-mixed secondary buffers\n"); - - CONS_Printf("Maximum number of hardware buffers: %d\n", DSCaps.dwMaxHwMixingStaticBuffers); - CONS_Printf("Size of total hardware memory: %d\n", DSCaps.dwTotalHwMemBytes); - CONS_Printf("Size of free hardware memory= %d\n", DSCaps.dwFreeHwMemBytes); - CONS_Printf("Play Cpu Overhead (%% cpu cycles): %d\n", DSCaps.dwPlayCpuOverheadSwBuffers); - } - else - CONS_Printf(" couldn't get sound device caps.\n"); - } -#endif - - // save pointer to the primary DirectSound buffer for volume changes - DSndPrimary = lpDsb; - - ZeroMemory (StackSounds, sizeof (StackSounds)); - - CONS_Printf("sound initialised.\n"); - sound_started = true; -} - - -// ========================================================================== -// -// MUSIC API using MidiStream -// -// ========================================================================== - -#define SPECIAL_HANDLE_CLEANMIDI -1999 // tell I_StopSong() to do a full (slow) midiOutReset() on exit - -static BOOL bMusicStarted; - -static UINT uMIDIDeviceID, uCallbackStatus; -static HMIDISTRM hStream; -static HANDLE hBufferReturnEvent; // for synch between the callback thread and main program thread - // (we need to synch when we decide to stop/free stream buffers) - -static int nCurrentBuffer = 0, nEmptyBuffers; - -static BOOL bBuffersPrepared = FALSE; -static DWORD dwVolCache[MAX_MIDI_IN_TRACKS]; - DWORD dwVolumePercent; // accessed by win_main.c - - // this is accessed by mid2strm.c conversion code - BOOL bMidiLooped = FALSE; -static BOOL bMidiPlaying = FALSE; -static BOOL bMidiPaused = FALSE; -static CONVERTINFO ciStreamBuffers[NUM_STREAM_BUFFERS]; - -#define STATUS_KILLCALLBACK 100 // Signals that the callback should die -#define STATUS_CALLBACKDEAD 200 // Signals callback is done processing -#define STATUS_WAITINGFOREND 300 // Callback's waiting for buffers to play - -#define DEBUG_CALLBACK_TIMEOUT 2000 // Wait 2 seconds for callback - // faB: don't freeze the main code if we debug.. - -#define VOL_CACHE_INIT 127 // for dwVolCache[] - -static BOOL bMidiCanSetVolume; // midi caps - -static void Mid2StreamFreeBuffers(void); -static void CALLBACK MidiStreamCallback (HMIDIIN hMidi, UINT uMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2); -static BOOL StreamBufferSetup(LPBYTE pMidiData, size_t iMidiSize); - -// ------------------- -// MidiErrorMessageBox -// Calls the midiOutGetErrorText() function and displays the text which -// corresponds to a midi subsystem error code. -// ------------------- -static void MidiErrorMessageBox(MMRESULT mmr) -{ - char szTemp[256] = ""; - - /*szTemp[0] = '\2'; //white text to stand out*/ - if((MMSYSERR_NOERROR == midiOutGetErrorTextA(mmr, szTemp/*+1*/, sizeof (szTemp))) && *szTemp) - CONS_Printf("%s\n",szTemp); - /*MessageBox (GetActiveWindow(), szTemp+1, "LEGACY", - MB_OK | MB_ICONSTOP);*/ - //wsprintf(szDebug, "Midi subsystem error: %s", szTemp); -} - - -// ---------------- -// I_InitAudioMixer -// ---------------- -#ifdef TESTCODE -void I_InitAudioMixer (void) -{ - UINT cMixerDevs = mixerGetNumDevs(); - CONS_Printf("%d mixer devices available\n", cMixerDevs); -} -#endif - -// ----------- -// I_InitDigMusic -// Startup Digital device for streaming output -// ----------- -void I_InitDigMusic(void) -{ - if (dedicated) - nodigimusic = true; - else - CONS_Printf("I_InitDigMusic()\n"); - -#ifdef FMODSOUND - if (!nodigimusic) - { - // Tails 11-21-2002 - if (FSOUND_GetVersion() < FMOD_VERSION) - { - //I_Error("FMOD Error : You are using the wrong DLL version!\nYou should be using FMOD %s\n", "FMOD_VERSION"); - CONS_Printf("FMOD Error : You are using the wrong DLL version!\nYou should be using FMOD %s\n", "FMOD_VERSION"); - nodigimusic = true; - } - - /* - INITIALIZE - */ -#if 1 - if (!FSOUND_SetHWND(hWndMain)) - { -// I_Error("FMOD(Init,FSOUND_SetHWND): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND); - } - //else -#endif - - if (!FSOUND_Init(44100, 32, FSOUND_INIT_DONTLATENCYADJUST)) - { - //I_Error("FMOD(Init,FSOUND_Init): %s\n", FMOD_ErrorString(FSOUND_GetError())); - CONS_Printf("FMOD(Init,FSOUND_Init): %s\n", FMOD_ErrorString(FSOUND_GetError())); - nodigimusic = true; - } - else - I_AddExitFunc(I_ShutdownDigMusic); - } -#endif -} - -// ----------- -// I_InitMIDIMusic -// Startup Midi device for streaming output -// ----------- -void I_InitMIDIMusic(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - UINT cMidiDevs; - MIDIOUTCAPS MidiOutCaps; - const char *szTechnology; - - bMusicStarted = false; - - if (dedicated) - nomidimusic = true; - else - CONS_Printf("I_InitMIDIMusic()\n"); - - if (nomidimusic) - return; - - // check out number of MIDI devices available - // - cMidiDevs = midiOutGetNumDevs(); - if (!cMidiDevs) - { - CONS_Printf("No MIDI devices available, music is disabled\n"); - nomidimusic = true; - return; - } -#ifdef DEBUGMIDISTREAM - else - { - CONS_Printf("%d MIDI devices available\n", cMidiDevs); - } -#endif - - if (M_CheckParm("-winmidi") && M_IsNextParm()) - uMIDIDeviceID = atoi(M_GetNextParm()); - else - uMIDIDeviceID = MIDI_MAPPER; - - // get MIDI device caps - // - if ((mmrRetVal = midiOutGetDevCaps (uMIDIDeviceID, &MidiOutCaps, sizeof (MIDIOUTCAPS))) != - MMSYSERR_NOERROR) - { - CONS_Printf("midiOutGetCaps FAILED : \n"); - MidiErrorMessageBox (mmrRetVal); - } - else - { - CONS_Printf("MIDI product name: %s\n", MidiOutCaps.szPname); - switch (MidiOutCaps.wTechnology) - { - case MOD_FMSYNTH: szTechnology = "FM Synth"; break; - case MOD_MAPPER: szTechnology = "Microsoft MIDI Mapper"; break; - case MOD_MIDIPORT: szTechnology = "MIDI hardware port"; break; - case MOD_SQSYNTH: szTechnology = "Square wave synthesizer"; break; - case MOD_SYNTH: szTechnology = "Synthesizer"; break; - default: szTechnology = "unknown"; break; - } - CONS_Printf("MIDI technology: %s\n", szTechnology); - CONS_Printf("MIDI caps:\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_CACHE) - CONS_Printf("-Patch caching\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_LRVOLUME) - CONS_Printf("-Separate left and right volume control\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_STREAM) - CONS_Printf("-Direct support for midiStreamOut()\n"); - if (MidiOutCaps.dwSupport & MIDICAPS_VOLUME) - CONS_Printf("-Volume control\n"); - bMidiCanSetVolume = ((MidiOutCaps.dwSupport & MIDICAPS_VOLUME)!=0); - } - -#ifdef TESTCODE - I_InitAudioMixer (); -#endif - - // ---------------------------------------------------------------------- - // Midi2Stream initialization - // ---------------------------------------------------------------------- - - // create event for synch'ing the callback thread to main program thread - // when we will need it - hBufferReturnEvent = CreateEvent(NULL, FALSE, FALSE, - TEXT("SRB2 Midi Playback: Wait For Buffer Return")); - - if (!hBufferReturnEvent) - { - I_GetLastErrorMsgBox(); - nomidimusic = true; - return; - } - - if ((mmrRetVal = midiStreamOpen(&hStream, - &uMIDIDeviceID, - (DWORD)1, (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, - CALLBACK_FUNCTION /*CALLBACK_NULL*/)) != MMSYSERR_NOERROR) - { - CONS_Printf("I_RegisterSong: midiStreamOpen FAILED\n"); - MidiErrorMessageBox(mmrRetVal); - nomidimusic = true; - return; - } - - // stream buffers are initially unallocated (set em NULL) - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - ZeroMemory (&ciStreamBuffers[idx].mhBuffer, sizeof (MIDIHDR)); - // ---------------------------------------------------------------------- - - // register exit code - I_AddExitFunc(I_ShutdownMIDIMusic); - - bMusicStarted = true; -} - -// --------------- -// I_InitMusic -// --------------- -void I_InitMusic(void) -{ - I_InitDigMusic(); - I_InitMIDIMusic(); -} - -// --------------- -// I_ShutdownDigMusic -// --------------- -void I_ShutdownDigMusic(void) -{ - CONS_Printf("I_ShutdownDigMusic: \n"); - -#ifdef FMODSOUND - if (!nodigimusic && FSOUND_GetError() != FMOD_ERR_UNINITIALIZED) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Shutdown,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Shutdown,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Shutdown,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Shutdown,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FSOUND_Stream_Close(fmus)) - if (devparm) CONS_Printf("FMOD(Shutdown,FSOUND_Stream_Close): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - FSOUND_Close(); - remove("fmod.tmp"); // Delete the temp file - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Shutdown,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Shutdown,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -#endif -} - -// --------------- -// I_ShutdownMIDIMusic -// --------------- -void I_ShutdownMIDIMusic(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - HGLOBAL lp = NULL; - - CONS_Printf("I_ShutdownMIDIMusic: \n"); - - if (nomidimusic) - return; - - if (!bMusicStarted) - return; - - if (hStream) - { - I_StopSong (SPECIAL_HANDLE_CLEANMIDI); - } - - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - - // Free our stream buffers - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - if (ciStreamBuffers[idx].mhBuffer.lpData) - { - //GlobalFreePtr(ciStreamBuffers[idx].mhBuffer.lpData); - lp = GlobalPtrHandle(ciStreamBuffers[idx].mhBuffer.lpData); - GlobalUnlock(lp); - GlobalFree(lp); - ciStreamBuffers[idx].mhBuffer.lpData = NULL; - } - } - - if (hStream) - { - if ((mmrRetVal = midiStreamClose(hStream)) != MMSYSERR_NOERROR) - MidiErrorMessageBox(mmrRetVal); - hStream = NULL; - } - - CloseHandle(hBufferReturnEvent); - - bMusicStarted = false; -} - -// --------------- -// I_ShutdownMusic -// --------------- -void I_ShutdownMusic(void) -{ - if (!nodigimusic) - I_ShutdownDigMusic(); - - if (!nomidimusic) - I_ShutdownMIDIMusic(); -} - -// -------------------- -// SetAllChannelVolumes -// Given a percent in tenths of a percent, sets volume on all channels to -// reflect the new value. -// -------------------- -static void SetAllChannelVolumes(DWORD dwVolumePercent) -{ - DWORD dwEvent, dwStatus, dwVol, idx; - MMRESULT mmrRetVal; - - if (!bMidiPlaying) - return; - - for (idx = 0, dwStatus = MIDI_CTRLCHANGE; idx < MAX_MIDI_IN_TRACKS; idx++, dwStatus++) - { - dwVol = (dwVolCache[idx] * dwVolumePercent) / 1000; - //CONS_Printf("channel %d vol %d\n", idx, dwVol); - dwEvent = dwStatus | ((DWORD)MIDICTRL_VOLUME << 8) - | ((DWORD)dwVol << 16); - if ((mmrRetVal = midiOutShortMsg((HMIDIOUT)hStream, dwEvent)) - != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - } -} - - -// ---------------- -// I_SetMusicVolume -// Set the midi output volume -// ---------------- -void I_SetMIDIMusicVolume(INT32 volume) -{ - MMRESULT mmrRetVal; - int iVolume; - - if (nomidimusic) - return; - - if (bMidiCanSetVolume) - { - // method A - // current volume is 0-31, we need 0-0xFFFF in each word (left/right channel) - iVolume = (volume << 11) | (volume << 27); - if ((mmrRetVal = midiOutSetVolume ((HMIDIOUT)(size_t)uMIDIDeviceID, iVolume)) != MMSYSERR_NOERROR) - { - CONS_Printf("I_SetMusicVolume: couldn't set volume\n"); - MidiErrorMessageBox(mmrRetVal); - } - } - else - { - // method B - dwVolumePercent = (volume * 1000) / 32; - SetAllChannelVolumes (dwVolumePercent); - } -} - -void I_SetDigMusicVolume(INT32 volume) -{ -#ifdef FMODSOUND - if (volume != -1) - fmodvol = (volume<<3)+(volume>>2); - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Volume,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_GetType(mod) != FMUSIC_TYPE_NONE) - { - if (!FMUSIC_SetMasterVolume(mod, fmodvol) && devparm) - CONS_Printf("FMOD(Volume,FMUSIC_SetMasterVolume): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - } - else if (devparm) - CONS_Printf("FMOD(Volume,FMUSIC_GetType): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (!FSOUND_SetVolume(fsoundchannel, fmodvol)) - if (devparm) CONS_Printf("FMOD(Volume,FSOUND_SetVolume): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#else - (void)volume; -#endif -} - - -// ---------- -// I_PlaySong -// Note: doesn't use the handle, would be useful to switch between mid's after -// some trigger (would do several RegisterSong, then PlaySong the chosen one) -// ---------- -boolean I_PlaySong(INT32 handle, INT32 bLooping) -{ - MMRESULT mmrRetVal; - - if (nomidimusic) - return false; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_PlaySong: looping %d\n", bLooping); -#endif - - // unpause the song first if it was paused - if (bMidiPaused) - I_PauseSong(handle); - - // Clear the status of our callback so it will handle - // MOM_DONE callbacks once more - uCallbackStatus = 0; - bMidiPlaying = FALSE; - if ((mmrRetVal = midiStreamRestart(hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - midiStreamClose(hStream); - //I_Error("I_PlaySong: midiStreamRestart error"); - midiStreamOpen(&hStream, &uMIDIDeviceID, (DWORD)1, - (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, CALLBACK_FUNCTION /*CALLBACK_NULL*/); - } - else bMidiPlaying = TRUE; - bMidiLooped = bLooping; - return bMidiPlaying; -} - - -// ----------- -// I_PauseSong -// calls midiStreamPause() to pause the midi playback -// ----------- -void I_PauseSong (INT32 handle) -{ - (void)handle; -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Pause,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (!FMUSIC_GetPaused(mod)) - if (!FMUSIC_SetPaused(mod, true)) - if (devparm) CONS_Printf("FMOD(Pause,FMUSIC_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus) - { - if (!FSOUND_GetPaused(fsoundchannel)) - if (!FSOUND_SetPaused(fsoundchannel, true)) - if (devparm) CONS_Printf("FMOD(Pause,FSOUND_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#endif - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_PauseSong: \n"); -#endif - - if (!bMidiPaused) - { - midiStreamPause(hStream); - bMidiPaused = true; - } -} - - -// ------------ -// I_ResumeSong -// un-pause the midi song with midiStreamRestart -// ------------ -void I_ResumeSong (INT32 handle) -{ - (void)handle; -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Resume,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod != NULL) - { - if (FMUSIC_GetPaused(mod)) - if (!FMUSIC_SetPaused(mod, false)) - if (devparm) CONS_Printf("FMOD(Resume,FMUSIC_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - if (fmus != NULL) - { - if (FSOUND_GetPaused(fsoundchannel)) - if (!FSOUND_SetPaused(fsoundchannel, false)) - if (devparm) CONS_Printf("FMOD(Resume,FSOUND_SetPaused): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } -#endif - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_ResumeSong: \n"); -#endif - - if (bMidiPaused) - { - midiStreamRestart(hStream); - bMidiPaused = false; - } -} - - -// ---------- -// I_StopSong -// ---------- -// faB: -1999 is a special handle here, it means we stop the midi when exiting -// Legacy, this will do a midiOutReset() for a more 'sure' midi off. -void I_StopSong(INT32 handle) -{ - MMRESULT mmrRetVal; - - if (nomidimusic) - return; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_StopSong: \n"); -#endif - - if (bMidiPlaying || (uCallbackStatus != STATUS_CALLBACKDEAD)) - { - bMidiPlaying = bMidiPaused = FALSE; - if (uCallbackStatus != STATUS_CALLBACKDEAD && - uCallbackStatus != STATUS_WAITINGFOREND) - uCallbackStatus = STATUS_KILLCALLBACK; - - //CONS_Printf("a: %d\n",I_GetTime()); - if ((mmrRetVal = midiStreamStop(hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - - //faB: if we don't call midiOutReset() seems we have to stop the buffers - // ourselves (or it doesn't play anymore) - if (!bMidiPaused && (handle != SPECIAL_HANDLE_CLEANMIDI)) - { - midiStreamPause(hStream); - } - //CONS_Printf("b: %d\n",I_GetTime()); - else - //faB: this damn call takes 1 second and a half !!! still do it on exit - // to be sure everything midi is cleaned as much as possible - if (handle == SPECIAL_HANDLE_CLEANMIDI) - { - if ((mmrRetVal = midiOutReset((HMIDIOUT)hStream)) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return; - } - } - //CONS_Printf("c: %d\n",I_GetTime()); - - // Wait for the callback thread to release this thread, which it will do by - // calling SetEvent() once all buffers are returned to it - if ((devparm) - && (WaitForSingleObject(hBufferReturnEvent, DEBUG_CALLBACK_TIMEOUT) - == WAIT_TIMEOUT)) - { - // Note, this is a risky move because the callback may be genuinely busy, but - // when we're debugging, it's safer and faster than freezing the application, - // which leaves the MIDI device locked up and forces a system reset... - CONS_Printf("Timed out waiting for MIDI callback\n"); - uCallbackStatus = STATUS_CALLBACKDEAD; - } - //CONS_Printf("d: %d\n",I_GetTime()); - } - - if (uCallbackStatus == STATUS_CALLBACKDEAD) - { - uCallbackStatus = 0; - Mid2StreamConverterCleanup(); - Mid2StreamFreeBuffers(); - //faB: we could close the stream here and re-open later to avoid - // a little quirk in mmsystem (see DirectX6 mstream note) - midiStreamClose(hStream); - midiStreamOpen(&hStream, &uMIDIDeviceID, (DWORD)1, - (DWORD_PTR)MidiStreamCallback/*NULL*/, - (DWORD)0, CALLBACK_FUNCTION /*CALLBACK_NULL*/); - } -} - -void I_StopDigSong(void) -{ -#ifdef FMODSOUND - if (!nodigimusic) - { - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_INVALID_PARAM && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) - if (devparm) CONS_Printf("FMOD(Stop,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - { - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Stop,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - { - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Stop,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Stop,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Stop,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -#endif -} - -void I_UnRegisterSong(INT32 handle) -{ - handle = 0; - if (nomidimusic) - return; - - //faB: we might free here whatever is allocated per-music - // (but we don't cause I hate malloc's) - Mid2StreamConverterCleanup(); - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_UnregisterSong: \n"); -#endif -} - -int I_SetSongSpeed(unsigned int speed) -{ -#ifdef FMODSOUND - if (music_disabled || nodigimusic) - return 0; //there no music or FMOD is not loaded - - if((!fmus || !FSOUND_IsPlaying(fsoundchannel)) && (!mod || !FMUSIC_IsPlaying(mod))) - return 0; //there no FMOD music playing - - if (speed == 0) - return 1; //yes, we can set the speed - - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel) - && !FSOUND_SetFrequency(fsoundchannel,(int)(((float)speed*(float)fsoundfreq)/100.0f))) - { - if (devparm) - CONS_Printf("FMOD(ChangeSpeed,FSOUND_SetFrequency): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - return 1; - } - else if (mod) - { - if (FMUSIC_IsPlaying(mod) - && !FMUSIC_SetMasterSpeed(mod,(float)speed/100.0f)) - { - if (devparm) - CONS_Printf("FMOD(ChangeSpeed,FMUSIC_SetMasterSpeed): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - return 1; - } -#else - (void)speed; -#endif - return 0; -} - -// Special FMOD support Tails 11-21-2002 -boolean I_StartDigSong(const char *musicname, INT32 looping) -{ -#ifdef FMODSOUND - char filename[9]; - void *data; - int lumpnum; - - if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_CHANNEL_ALLOC && - FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER && FSOUND_GetError() != FMOD_ERR_INVALID_PARAM) - if (devparm) CONS_Printf("FMOD(Start,Unknown): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - if (fmus) - { - if (FSOUND_IsPlaying(fsoundchannel)) - if (!FSOUND_Stream_Stop(fmus)) - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Stop): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FSOUND_Stream_Close(fmus)) - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Close): %s\n", FMOD_ErrorString(FSOUND_GetError())); - fsoundchannel = -1; - fmus = NULL; - } - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - mod = NULL; - } - //if (!FSOUND_StopSound(FSOUND_ALL)) - //if (FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Start,FSOUND_StopSound): %s\n", FMOD_ErrorString(FSOUND_GetError())); - //FMUSIC_StopAllSongs(); - //if (FSOUND_GetError() != FMOD_ERR_NONE && FSOUND_GetError() != FMOD_ERR_MEDIAPLAYER) CONS_Printf("FMOD(Start,FMUSIC_StopAllSongs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - // Create the filename we need - sprintf(filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - if (lumpnum == -1) - { - // Graue 02-29-2004: don't worry about missing music, there might still be a MIDI - return false; // No music found. Oh well! - } - - data = W_CacheLumpName (filename, PU_CACHE); - - I_SaveMemToFile (data, W_LumpLength(lumpnum), "fmod.tmp"); - - Z_Free(data); - - mod = FMUSIC_LoadSong("fmod.tmp"); - - if (FSOUND_GetError() != FMOD_ERR_NONE) - { - if (FSOUND_GetError() != FMOD_ERR_FILE_FORMAT) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_LoadSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - - if (mod) - { - if (FMUSIC_IsPlaying(mod)) - if (!FMUSIC_StopSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_StopSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - if (!FMUSIC_FreeSong(mod)) - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_FreeSong): %s\n", FMOD_ErrorString(FSOUND_GetError())); - mod = NULL; - } - } - - if (mod) - { - if (!FMUSIC_SetLooping(mod, (signed char)looping)) - { - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_SetLooping): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } -// else if (FMUSIC_GetType(mod) == FMUSIC_TYPE_MOD || FMUSIC_GetType(mod) == FMUSIC_TYPE_S3M) -// { -// if (!FMUSIC_SetPanSeperation(mod, 0.85f)) /* 15% crossover */ -// CONS_Printf("FMOD(Start,FMUSIC_SetPanSeperation): %s\n", FMOD_ErrorString(FSOUND_GetError())); -// } - else if (!FMUSIC_SetPanSeperation(mod, 0.0f)) - { - if (devparm) CONS_Printf("FMOD(Start,FMUSIC_SetPanSeperation): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - } - else - { - fmus = FSOUND_Stream_OpenFile("fmod.tmp", ((looping) ? (FSOUND_LOOP_NORMAL) : (0)),0); - if (fmus == NULL) - { - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_Open): %s\n", FMOD_ErrorString(FSOUND_GetError())); - return false; - } - } - - // Scan the Ogg Vorbis file for the COMMENT= field for a custom loop point - if (fmus && looping) - { - int scan; - char *dataum; - char looplength[64]; - unsigned int loopstart = 0; - int newcount = 0; - const int freq = 44100; - int lumplength = W_LumpLength(lumpnum); - int length = FSOUND_Stream_GetLengthMs(fmus); - - if (length == 0) - { - if (devparm) CONS_Printf("FMOD(Start,FSOUND_Stream_GetLengthMs): %s\n", FMOD_ErrorString(FSOUND_GetError())); - } - else - { - //freq = FSOUND_GetFrequency(fsoundchannel); - - data = W_CacheLumpName (filename, PU_CACHE); - - dataum = (char *)data; - - for (scan = 0;scan < lumplength; scan++) - { - if (*dataum++ == 'C'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'E'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '='){ - if (*dataum++ == 'L'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'I'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '=') - { - - while (*dataum != 1 && newcount != 63) - { - looplength[newcount++] = *dataum++; - } - - looplength[newcount] = '\n'; - - loopstart = atoi(looplength); - } - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - } - - Z_Free(data); - } - - if (loopstart > 0) - { - const unsigned int loopend = (unsigned int)((freq/1000.0f)*length-(freq/1000.0f)); - //const unsigned int loopend = (((freq/2)*length)/500)-8; - if (!FSOUND_Stream_SetLoopPoints(fmus, loopstart, loopend) && devparm) - CONS_Printf("FMOD(Start,FSOUND_Stream_SetLoopPoints): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - } - } - - /* - PLAY SONG - */ - if (mod) - { - if (FMUSIC_PlaySong(mod)) - { - fsoundchannel = -1; - I_SetDigMusicVolume(-1); - return true; - } - else - { - if (devparm) - CONS_Printf("FMOD(Start,FMUSIC_PlaySong): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - } - if (fmus) - { - fsoundchannel = FSOUND_Stream_PlayEx(FSOUND_FREE, fmus, NULL, TRUE); - - if (fsoundchannel == -1) - { - if (devparm) - CONS_Printf("FMOD(Start,FSOUND_Stream_PlayEx): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - else if (!FSOUND_SetPaused(fsoundchannel, FALSE)) - { - if (devparm) - CONS_Printf("FMOD(Start,FSOUND_SetPaused): %s\n", - FMOD_ErrorString(FSOUND_GetError())); - return false; - } - - I_SetDigMusicVolume(-1); - fsoundfreq = FSOUND_GetFrequency(fsoundchannel); - return true; - } -#else - (void)musicname; - (void)looping; -#endif - return false; - -///////////////////////////////////////////////////////////////////////////////// -} - -// -------------- -// I_RegisterSong -// Prepare a song for playback -// - setup midi stream buffers, and activate the callback procedure -// which will continually fill the buffers with new data -// -------------- - -INT32 I_RegisterSong(void *data, int len) -{ - char *pMidiFileData = NULL; // MIDI music buffer to be played or NULL - - if (nomidimusic) - return 1; - if (!data || !len) - return 0; - -#ifdef DEBUGMIDISTREAM - CONS_Printf("I_RegisterSong: \n"); -#endif - // check for MID format file - if (!memcmp(data, "MThd", 4)) - pMidiFileData = data; - else - { - CONS_Printf("Music lump is not MID music format\n"); - return 0; - } - -#ifdef DEBUGMIDISTREAM - I_SaveMemToFile(pMidiFileData, len, "debug.mid"); -#endif - - // setup midi stream buffer - if (StreamBufferSetup((LPBYTE)pMidiFileData, len)) - { - Mid2StreamConverterCleanup(); - I_Error("I_RegisterSong: StreamBufferSetup FAILED"); - } - - return 1; -} - -// ----------------- -// StreamBufferSetup -// This function uses the filename stored in the global character array to -// open a MIDI file. Then it goes about converting at least the first part of -// that file into a midiStream buffer for playback. -// ----------------- - -// ----------------- -// StreamBufferSetup -// - returns TRUE if a problem occurs -// ----------------- -static BOOL StreamBufferSetup(LPBYTE pMidiData, size_t iMidiSize) -{ - MMRESULT mmrRetVal; - MIDIPROPTIMEDIV mptd; - BOOL bFoundEnd = FALSE; - int dwConvertFlag, nChkErr, idx; - -#ifdef DEBUGMIDISTREAM - if (hStream == NULL) - I_Error("StreamBufferSetup: hStream is NULL!"); -#endif - - // pause midi stream before manipulating the buffers - midiStreamPause(hStream); - - // allocate the stream buffers (only once) - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - ciStreamBuffers[idx].mhBuffer.dwBufferLength = OUT_BUFFER_SIZE; - if (!ciStreamBuffers[idx].mhBuffer.lpData) - { - ciStreamBuffers[idx].mhBuffer.lpData = GlobalAllocPtr(GHND, OUT_BUFFER_SIZE); - if (!ciStreamBuffers[idx].mhBuffer.lpData) - return FALSE; - } - } - - // returns TRUE in case of conversion error - if (Mid2StreamConverterInit(pMidiData, iMidiSize)) - return TRUE; - - // Initialize the volume cache array to some pre-defined value - for (idx = 0; idx < MAX_MIDI_IN_TRACKS; idx++) - dwVolCache[idx] = VOL_CACHE_INIT; - - mptd.cbStruct = sizeof (mptd); - mptd.dwTimeDiv = ifs.dwTimeDivision; - if ((mmrRetVal = midiStreamProperty(hStream, (LPBYTE)&mptd, MIDIPROP_SET|MIDIPROP_TIMEDIV)) - != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return TRUE; - } - - nEmptyBuffers = 0; - dwConvertFlag = CONVERTF_RESET; - - for (nCurrentBuffer = 0; nCurrentBuffer < NUM_STREAM_BUFFERS; nCurrentBuffer++) - { - // Tell the converter to convert up to one entire buffer's length of output - // data. Also, set a flag so it knows to reset any saved state variables it - // may keep from call to call. - ciStreamBuffers[nCurrentBuffer].dwStartOffset = 0; - ciStreamBuffers[nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE; - ciStreamBuffers[nCurrentBuffer].tkStart = 0; - ciStreamBuffers[nCurrentBuffer].bTimesUp = FALSE; - - if ((nChkErr = Mid2StreamConvertToBuffer(dwConvertFlag, &ciStreamBuffers[nCurrentBuffer])) - != CONVERTERR_NOERROR) - { - if (nChkErr == CONVERTERR_DONE) - bFoundEnd = TRUE; - else - { - CONS_Printf("StreamBufferSetup: initial conversion pass failed\n"); - return TRUE; - } - } - ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded - = ciStreamBuffers[nCurrentBuffer].dwBytesRecorded; - - if (!bBuffersPrepared) - { - if ((mmrRetVal = midiOutPrepareHeader((HMIDIOUT)hStream, - &ciStreamBuffers[nCurrentBuffer].mhBuffer, sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - return TRUE; - } - } - if ((mmrRetVal = midiStreamOut(hStream, &ciStreamBuffers[nCurrentBuffer].mhBuffer, - sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - break; - } - dwConvertFlag = 0; - - if (bFoundEnd) - break; - } - - bBuffersPrepared = TRUE; - nCurrentBuffer = 0; - - // MIDI volume - dwVolumePercent = (cv_midimusicvolume.value * 1000) / 32; - if (hStream) - SetAllChannelVolumes(dwVolumePercent); - - return FALSE; -} - -// ---------------- -// SetChannelVolume -// Call here delayed by MIDI stream callback, to adapt the volume event of the -// midi stream to our own set volume percentage. -// ---------------- -void I_SetMidiChannelVolume(DWORD dwChannel, DWORD dwVolumePercent) -{ - DWORD dwEvent, dwVol; - MMRESULT mmrRetVal; - - if (!bMidiPlaying) - return; - - dwVol = (dwVolCache[dwChannel] * dwVolumePercent) / 1000; - dwEvent = MIDI_CTRLCHANGE|dwChannel|((DWORD)MIDICTRL_VOLUME << 8)|((DWORD)dwVol << 16); - if ((mmrRetVal = midiOutShortMsg((HMIDIOUT)hStream, dwEvent)) != MMSYSERR_NOERROR) - { -#ifdef DEBUGMIDISTREAM - MidiErrorMessageBox(mmrRetVal); -#endif - return; - } -} - -// ------------------ -// MidiStreamCallback -// This is the callback handler which continually refills MIDI data buffers -// as they're returned to us from the audio subsystem. -// ------------------ -static void CALLBACK MidiStreamCallback(HMIDIIN hMidi, UINT uMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2) -{ - MMRESULT mmrRetVal; - int nChkErr; - MIDIEVENT* pme; - MIDIHDR* pmh; - - hMidi = NULL; - dwParam1 = dwParam2 = dwInstance = 0; - switch (uMsg) - { - case MOM_DONE: - // dwParam1 is LPMIDIHDR - if (uCallbackStatus == STATUS_CALLBACKDEAD) - return; - - nEmptyBuffers++; - - // we reached end of song, but we wait until all the buffers are returned - if (uCallbackStatus == STATUS_WAITINGFOREND) - { - if (nEmptyBuffers < NUM_STREAM_BUFFERS) - return; - else - { - // stop the song when end reached (was not looping) - uCallbackStatus = STATUS_CALLBACKDEAD; - SetEvent(hBufferReturnEvent); - I_StopSong(0); - return; - } - } - - // This flag is set whenever the callback is waiting for all buffers to come back. - if (uCallbackStatus == STATUS_KILLCALLBACK) - { - // Count NUM_STREAM_BUFFERS-1 being returned for the last time - if (nEmptyBuffers < NUM_STREAM_BUFFERS) - return; - // Then send a stop message when we get the last buffer back... - else - { - // Change the status to callback dead - uCallbackStatus = STATUS_CALLBACKDEAD; - SetEvent(hBufferReturnEvent); - return; - } - } - - dwProgressBytes += ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded; - - // ------------------------------------------------- - // Fill an available buffer with audio data again... - // ------------------------------------------------- - - if (bMidiPlaying && nEmptyBuffers) - { - ciStreamBuffers[nCurrentBuffer].dwStartOffset = 0; - ciStreamBuffers[nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE; - ciStreamBuffers[nCurrentBuffer].tkStart = 0; - ciStreamBuffers[nCurrentBuffer].dwBytesRecorded = 0; - ciStreamBuffers[nCurrentBuffer].bTimesUp = FALSE; - - if ((nChkErr = Mid2StreamConvertToBuffer(0, &ciStreamBuffers[nCurrentBuffer])) - != CONVERTERR_NOERROR) - { - if (nChkErr == CONVERTERR_DONE) - { - // Don't include this one in the count - uCallbackStatus = STATUS_WAITINGFOREND; - return; - } - else - { - // We're not in the main thread, so we can't call I_Error() now. - // Log the error message out, and post exit message. - CONS_Printf("MidiStreamCallback(): conversion pass failed!\n"); - PostMessage(hWndMain, WM_CLOSE, 0, 0); - return; - } - } - - ciStreamBuffers[nCurrentBuffer].mhBuffer.dwBytesRecorded - = ciStreamBuffers[nCurrentBuffer].dwBytesRecorded; - - if ((mmrRetVal = midiStreamOut(hStream, &ciStreamBuffers[nCurrentBuffer].mhBuffer, - sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - Mid2StreamConverterCleanup(); - return; - } - - nCurrentBuffer = (nCurrentBuffer + 1) % NUM_STREAM_BUFFERS; - nEmptyBuffers--; - } - - break; - case MOM_POSITIONCB: - pmh = (MIDIHDR*)(size_t)dwParam1; - pme = (MIDIEVENT*)(pmh->lpData + pmh->dwOffset); - if (MIDIEVENT_TYPE(pme->dwEvent) == MIDI_CTRLCHANGE) - { -#ifdef DEBUGMIDISTREAM - if (MIDIEVENT_DATA1(pme->dwEvent) == MIDICTRL_VOLUME_LSB) - { - CONS_Printf("Got an LSB volume event\n"); - PostMessage(hWndMain, WM_CLOSE, 0, 0); // can't I_Error() here - break; - } -#endif - // this is meant to respond to our own intention, from mid2strm.c - if (MIDIEVENT_DATA1(pme->dwEvent) != MIDICTRL_VOLUME) - break; - - // Mask off the channel number and cache the volume data byte - dwVolCache[MIDIEVENT_CHANNEL(pme->dwEvent)] = MIDIEVENT_VOLUME(pme->dwEvent); - // call SetChannelVolume() later to adjust MIDI volume control message to our - // own current volume level. - PostMessage(hWndMain, WM_MSTREAM_UPDATEVOLUME, - MIDIEVENT_CHANNEL(pme->dwEvent), 0L); - } - break; - default: - break; - } - - return; -} - -// --------------------- -// Mid2StreamFreeBuffers -// This function unprepares and frees all our buffers -- something we must -// do to work around a bug in MMYSYSTEM that prevents a device from playing -// back properly unless it is closed and reopened after each stop. -// --------------------- -static void Mid2StreamFreeBuffers(void) -{ - DWORD idx; - MMRESULT mmrRetVal; - - if (bBuffersPrepared) - { - for (idx = 0; idx < NUM_STREAM_BUFFERS; idx++) - { - if ((mmrRetVal = midiOutUnprepareHeader((HMIDIOUT)hStream, - &ciStreamBuffers[idx].mhBuffer, sizeof (MIDIHDR))) != MMSYSERR_NOERROR) - { - MidiErrorMessageBox(mmrRetVal); - } - } - bBuffersPrepared = FALSE; - } - - // Don't free the stream buffers here, but rather allocate them once at startup, - // and free them at shutdown. -} diff --git a/src/win32ce/win_sys.c b/src/win32ce/win_sys.c deleted file mode 100644 index 3b6a47258..000000000 --- a/src/win32ce/win_sys.c +++ /dev/null @@ -1,3542 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief win32 system i/o -/// -/// Startup & Shutdown routines for music,sound,timer,keyboard,... -/// Signal handler to trap errors and exit cleanly. - -#include "../doomdef.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../m_misc.h" -#include "../i_video.h" -#include "../i_sound.h" -#include "../i_system.h" - -#include "../d_net.h" -#include "../g_game.h" - -#include "../d_main.h" - -#include "../m_argv.h" - -#include "../w_wad.h" -#include "../z_zone.h" -#include "../g_input.h" - -#include "../keys.h" - -#include "../screen.h" - -// Wheel support for Win95/WinNT3.51 -#include - -// Taken from Win98/NT4.0 -#ifndef SM_MOUSEWHEELPRESENT -#define SM_MOUSEWHEELPRESENT 75 -#endif - -#ifndef MSH_MOUSEWHEEL -#ifdef UNICODE -#define MSH_MOUSEWHEEL L"MSWHEEL_ROLLMSG" -#else -#define MSH_MOUSEWHEEL "MSWHEEL_ROLLMSG" -#endif -#endif - -#include "win_main.h" -#include "../i_joy.h" - -#define DIRECTINPUT_VERSION 0x700 -// Force dinput.h to generate old DX3 headers. -#define DXVERSION_NTCOMPATIBLE 0x0300 -#include - -#include "fabdxlib.h" - -#ifdef __DEBUG__ -#undef NDEBUG -#endif - -/// \brief max number of joystick buttons -#define JOYBUTTONS_MAX 32 // rgbButtons[32] -/// \brief max number of joystick button events -#define JOYBUTTONS_MIN min((JOYBUTTONS),(JOYBUTTONS_MAX)) - -/// \brief max number of joysick axies -#define JOYAXISSET_MAX 4 // (lX, lY), (lZ,lRx), (lRy, lRz), rglSlider[2] is very diff -/// \brief max number ofjoystick axis events -#define JOYAXISSET_MIN min((JOYAXISSET),(JOYAXISSET_MAX)) - -/// \brief max number of joystick hats -#define JOYHATS_MAX 4 // rgdwPOV[4]; -/// \brief max number of joystick hat events -#define JOYHATS_MIN min((JOYHATS),(JOYHATS_MAX)) - -/// \brief max number of mouse buttons -#define MOUSEBUTTONS_MAX 8 // 8 bit of BYTE and DIMOFS_BUTTON7 -/// \brief max number of muse button events -#define MOUSEBUTTONS_MIN min((MOUSEBUTTONS),(MOUSEBUTTONS_MAX)) - -// ================== -// DIRECT INPUT STUFF -// ================== -BOOL bDX0300; // if true, we created a DirectInput 0x0300 version -static LPDIRECTINPUT lpDI = NULL; -static LPDIRECTINPUTDEVICE lpDIK = NULL; // Keyboard -static LPDIRECTINPUTDEVICE lpDIM = NULL; // mice -static LPDIRECTINPUTDEVICE lpDIJ = NULL; // joystick 1P -static LPDIRECTINPUTEFFECT lpDIE[NumberofForces]; // joystick 1Es -static LPDIRECTINPUTDEVICE2 lpDIJA = NULL; // joystick 1I -static LPDIRECTINPUTDEVICE lpDIJ2 = NULL; // joystick 2P -static LPDIRECTINPUTEFFECT lpDIE2[NumberofForces]; // joystick 1Es -static LPDIRECTINPUTDEVICE2 lpDIJ2A = NULL;// joystick 2I - -// Do not execute cleanup code more than once. See Shutdown_xxx() routines. -UINT8 graphics_started = 0; -UINT8 keyboard_started = 0; -UINT8 sound_started = 0; -static boolean mouse_enabled = false; -static boolean joystick_detected = false; -static boolean joystick2_detected = false; - -static void I_ShutdownKeyboard(void); -static void I_GetKeyboardEvents(void); -static void I_ShutdownJoystick(void); -static void I_ShutdownJoystick2 (void); - -static boolean entering_con_command = false; - -// -// Why would this be system specific?? hmmmm.... -// -// it is for virtual reality system, next incoming feature :) -static ticcmd_t emptycmd; -ticcmd_t *I_BaseTiccmd(void) -{ - return &emptycmd; -} - -static ticcmd_t emptycmd2; -ticcmd_t *I_BaseTiccmd2(void) -{ - return &emptycmd2; -} - -// Allocates the base zone memory, -// this function returns a valid pointer and size, -// else it should interrupt the program immediately. -// -// now checks if mem could be allocated, this is still -// prehistoric... there's a lot to do here: memory locking, detection -// of win95 etc... -// - -BOOL win9x; - -/** \brief WinNT system platform -*/ -static BOOL winnt; - -static void I_DetectWin9x(void) -{ - OSVERSIONINFO osvi; - - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - GetVersionEx(&osvi); - - winnt = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); - // 95 or 98 what the hell - win9x = true; -} - -// return free and total memory in the system -UINT32 I_GetFreeMem(UINT32* total) -{ - MEMORYSTATUS info; - - info.dwLength = sizeof (MEMORYSTATUS); - GlobalMemoryStatus(&info); - if (total) - *total = (ULONG)info.dwTotalPhys; - return (ULONG)info.dwAvailPhys; -} - -// --------- -// I_Profile -// Two little functions to profile our code using the high resolution timer -// --------- -static LARGE_INTEGER ProfileCount; -void I_BeginProfile(void) -{ - if (!QueryPerformanceCounter(&ProfileCount)) - I_Error("I_BeginProfile failed"); // can't profile without the high res timer -} - -// we're supposed to use this to measure very small amounts of time, -// that's why we return a DWORD and not a 64bit value -DWORD I_EndProfile(void) -{ - LARGE_INTEGER CurrTime; - DWORD ret; - if (!QueryPerformanceCounter (&CurrTime)) - I_Error("I_EndProfile failed"); - if (CurrTime.QuadPart - ProfileCount.QuadPart > (LONGLONG)0xFFFFFFFFUL) - I_Error("I_EndProfile overflow"); - ret = (DWORD)(CurrTime.QuadPart - ProfileCount.QuadPart); - // we can call I_EndProfile() several time, I_BeginProfile() need be called just once - ProfileCount = CurrTime; - - return ret; -} - -// --------- -// I_GetTime -// Use the High Resolution Timer if available, -// else use the multimedia timer which has 1 millisecond precision on Windowz 95, -// but lower precision on Windows NT -// --------- -static long hacktics = 0; // used locally for keyboard repeat keys -static DWORD starttickcount = 0; // hack for win2k time bug - -tic_t I_GetTime(void) -{ - tic_t newtics = 0; - - if (!starttickcount) // high precision timer - { - LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available - static LARGE_INTEGER basetime = {{0, 0}}; - - // use this if High Resolution timer is found - static LARGE_INTEGER frequency; - - if (!basetime.LowPart) - { - if (!QueryPerformanceFrequency(&frequency)) - frequency.QuadPart = 0; - else - QueryPerformanceCounter(&basetime); - } - - if (frequency.LowPart && QueryPerformanceCounter(&currtime)) - { - newtics = (int)((currtime.QuadPart - basetime.QuadPart) * TICRATE - / frequency.QuadPart); - } - else - { - currtime.LowPart = timeGetTime(); - if (!basetime.LowPart) - basetime.LowPart = currtime.LowPart; - newtics = ((currtime.LowPart - basetime.LowPart)/(1000/TICRATE)); - } - } - else - newtics = (GetTickCount() - starttickcount)/(1000/TICRATE); - - hacktics = newtics; // a local counter for keyboard repeat key - return newtics; -} - - -void I_Sleep(void) -{ - if (cv_sleep.value != -1) - Sleep(cv_sleep.value); -} - - -// should move to i_video -void I_WaitVBL(INT32 count) -{ - count = 0; -} - -// this is probably to activate the 'loading' disc icon -// it should set a flag, that I_FinishUpdate uses to know -// whether it draws a small 'loading' disc icon on the screen or not -// -// also it should explicitly draw the disc because the screen is -// possibly not refreshed while loading -// -void I_BeginRead(void) {} - -// see above, end the 'loading' disc icon, set the flag false -// -void I_EndRead(void) {} - -// =========================================================================================== -// EVENTS -// =========================================================================================== -static inline BOOL I_ReadyConsole(HANDLE ci) -{ - DWORD gotinput; - if (ci == (HANDLE)-1) return FALSE; - if (WaitForSingleObject(ci,0) != WAIT_OBJECT_0) return FALSE; - if (GetFileType(ci) != FILE_TYPE_CHAR) return FALSE; - return (GetNumberOfConsoleInputEvents(ci, &gotinput) && gotinput); -} - -static inline VOID I_GetConsoleEvents(VOID) -{ - event_t ev = {0,0,0,0}; - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO CSBI; - INPUT_RECORD input; - DWORD t; - - while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) - { - memset(&ev,0x00,sizeof (ev)); - switch (input.EventType) - { - case KEY_EVENT: - if (input.Event.KeyEvent.bKeyDown) - { - ev.type = ev_console; - entering_con_command = true; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_ESCAPE: - case VK_TAB: - ev.data1 = KEY_NULL; - break; - case VK_SHIFT: - ev.data1 = KEY_SHIFT; - break; - case VK_RETURN: - entering_con_command = false; - // Fall through. - default: - ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char - } - if (co != (HANDLE)-1 && GetFileType(co) == FILE_TYPE_CHAR) - { - if (ev.data1 && ev.data1 != KEY_SHIFT) - { -#ifdef _UNICODE - WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); -#else - WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1, &t, NULL); -#endif - } - if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK - && GetConsoleScreenBufferInfo(co,&CSBI)) - { - WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); - } - } - } - else - { - ev.type = ev_keyup; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_SHIFT: - ev.data1 = KEY_SHIFT; - break; - default: - break; - } - } - if (ev.data1) D_PostEvent(&ev); - break; - case MOUSE_EVENT: - case WINDOW_BUFFER_SIZE_EVENT: - case MENU_EVENT: - case FOCUS_EVENT: - break; - } - } -} - -// ---------- -// I_GetEvent -// Post new events for all sorts of user-input -// ---------- -void I_GetEvent(void) -{ - I_GetConsoleEvents(); - I_GetKeyboardEvents(); - I_GetMouseEvents(); - I_GetJoystickEvents(); - I_GetJoystick2Events(); -} - -// ---------- -// I_OsPolling -// ---------- -void I_OsPolling(void) -{ - MSG msg; - HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - - // we need to dispatch messages to the window - // so the window procedure can respond to messages and PostEvent() for keys - // during D_SRB2Main startup. - // this one replaces the main loop of windows since I_OsPolling is called in the main loop - do - { - while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) - { - if (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else // winspec : this is quit message - I_Quit(); - } - if (!appActive && !netgame && !I_ReadyConsole(ci)) - WaitMessage(); - } while (!appActive && !netgame && !I_ReadyConsole(ci)); - - // this is called by the network synchronization, - // check keys and allow escaping - I_GetEvent(); - - // reset "emulated keys" - gamekeydown[KEY_MOUSEWHEELUP] = 0; - gamekeydown[KEY_MOUSEWHEELDOWN] = 0; -} - -// =========================================================================================== -// TIMER -// =========================================================================================== - -static void I_ShutdownTimer(void) -{ - timeEndPeriod(1); -} - -// -// Installs the timer interrupt handler with timer speed as TICRATE. -// -#define TIMER_ID 1 -#define TIMER_RATE (1000/TICRATE) -void I_StartupTimer(void) -{ - // for win2k time bug - if (M_CheckParm("-gettickcount")) - { - starttickcount = GetTickCount(); - CONS_Printf("Using GetTickCount()\n"); - } - timeBeginPeriod(1); - I_AddExitFunc(I_ShutdownTimer); -} - -// =========================================================================================== -// EXIT CODE, ERROR HANDLING -// =========================================================================================== - -static int errorcount = 0; // phuck recursive errors -static int shutdowning = false; - -// -// Used to trap various signals, to make sure things get shut down cleanly. -// -#ifdef NDEBUG -static void signal_handler(int num) -{ - //static char msg[] = "oh no! back to reality!\r\n"; - const char *sigmsg; - char sigdef[64]; - - D_QuitNetGame(); // Fix server freezes - I_ShutdownSystem(); - - switch (num) - { - case SIGINT: - sigmsg = "interrupt"; - break; - case SIGILL: - sigmsg = "illegal instruction - invalid function image"; - break; - case SIGFPE: - sigmsg = "floating point exception"; - break; - case SIGSEGV: - sigmsg = "segment violation"; - break; - case SIGTERM: - sigmsg = "software termination signal from kill"; - break; - case SIGBREAK: - sigmsg = "Ctrl-Break sequence"; - break; - case SIGABRT: - sigmsg = "abnormal termination triggered by abort call"; - break; - default: - sprintf(sigdef, "signal number %d", num); - sigmsg = sigdef; - } - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - I_OutputMsg("signal_handler() error: %s\r\n", sigmsg); - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - - MessageBoxA(hWndMain, va("signal_handler(): %s", sigmsg), "SRB2 error", MB_OK|MB_ICONERROR); - - signal(num, SIG_DFL); // default signal action - raise(num); -} -#endif - -// -// put an error message (with format) on stderr -// -void I_OutputMsg(const char *fmt, ...) -{ - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD bytesWritten; - va_list argptr; - char txt[8192]; - - va_start(argptr,fmt); - vsprintf(txt, fmt, argptr); - va_end(argptr); - - OutputDebugStringA(txt); - if (co != (HANDLE)-1) - { - if (GetFileType(co) == FILE_TYPE_CHAR) - { - static COORD coordNextWrite = {0,0}; - char *oldLines = NULL; - DWORD oldLength = 0; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - // Save the lines that we're going to obliterate. - GetConsoleScreenBufferInfo(co, &csbi); - oldLength = csbi.dwSize.X * (csbi.dwCursorPosition.Y - coordNextWrite.Y) + csbi.dwCursorPosition.X - coordNextWrite.X; - - if(oldLength > 0) - { - char *blank = malloc(oldLength); - oldLines = malloc(oldLength); - if(!oldLines || !blank) return; - - ReadConsoleOutputCharacterA(co, oldLines, oldLength, coordNextWrite, &bytesWritten); - - // Move to where we what to print - which is where we would've been, - // had console input not been in the way, - SetConsoleCursorPosition(co, coordNextWrite); - - // Blank out. - memset(blank, ' ', oldLength); - WriteConsoleA(co, blank, oldLength, &bytesWritten, NULL); - free(blank); - - // And back to where we want to print again. - SetConsoleCursorPosition(co, coordNextWrite); - } - - // Actually write the string now! - WriteConsoleA(co, txt, (DWORD)strlen(txt), &bytesWritten, NULL); - - // Next time, output where we left off. - GetConsoleScreenBufferInfo(co, &csbi); - coordNextWrite = csbi.dwCursorPosition; - - // Restore what was overwritten. - if(oldLines && entering_con_command) - { - WriteConsoleA(co, oldLines, oldLength, &bytesWritten, NULL); - free(oldLines); - } - } - else // Redirected to a file. - WriteFile(co, txt, (DWORD)strlen(txt), &bytesWritten, NULL); - } - -#ifdef LOGMESSAGES - if (logstream != (HANDLE)-1) - WriteFile (logstream, txt, (DWORD)strlen(txt), &bytesWritten, NULL); -#endif -} - -// display error messy after shutdowngfx -// -void I_Error(const char *error, ...) -{ - va_list argptr; - char txt[8192]; - - // added 11-2-98 recursive error detecting - if (shutdowning) - { - errorcount++; - // try to shutdown each subsystem separately - if (errorcount == 5) - I_ShutdownGraphics(); - if (errorcount == 6) - I_ShutdownSystem(); - if (errorcount == 7) - { - M_SaveConfig(NULL); - G_SaveGameData(); - } - if (errorcount > 20) - { - // Don't print garbage - va_start(argptr,error); - vsprintf(txt, error, argptr); - va_end(argptr); - - MessageBoxA(hWndMain, txt, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); - exit(-1); // recursive errors detected - } - } - shutdowning = true; - - // put message to stderr - va_start(argptr, error); - wvsprintfA(txt, error, argptr); - va_end(argptr); - - CONS_Printf("I_Error(): %s\n", txt); - - // uncomment this line to print to stderr as well - //wsprintf(stderr, "I_Error(): %s\n", txt); - - // saving one time is enough! - if (!errorcount) - { - M_SaveConfig(NULL); // save game config, cvars.. - G_SaveGameData(); - } - - // save demo, could be useful for debug - // NOTE: demos are normally not saved here. - if (demorecording) - G_CheckDemoStatus(); - - D_QuitNetGame(); - - // shutdown everything that was started - I_ShutdownSystem(); - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - - MessageBoxA(hWndMain, txt, "SRB2 Error", MB_OK|MB_ICONERROR); - - exit(-1); -} - -static inline VOID ShowEndTxt(HANDLE co) -{ - int i; - UINT16 j, att = 0; - int nlflag = 1; - CONSOLE_SCREEN_BUFFER_INFO backupcon; - COORD resizewin = {80,-1}; - DWORD bytesWritten; - CHAR let = 0; - UINT16 *text; - void *data; - int endoomnum = W_GetNumForName("ENDOOM"); - //HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); - - /* get the lump with the text */ - data = text = W_CacheLumpNum(endoomnum, PU_CACHE); - - backupcon.wAttributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; // Just in case - GetConsoleScreenBufferInfo(co, &backupcon); //Store old state - resizewin.Y = backupcon.dwSize.Y; - if (backupcon.dwSize.X < resizewin.X) - SetConsoleScreenBufferSize(co, resizewin); - - for (i = 1; i <= 80*25; i++) // print 80x25 text and deal with the attributes too - { - j = (UINT16)(*text >> 8); // attribute first - if (j != att) // attribute changed? - { - att = j; // save current attribute - SetConsoleTextAttribute(co, j); //set fg and bg color for buffer - } - - let = (char)(*text++ & 0xff); // now the text - WriteConsoleA(co, &let, 1, &bytesWritten, NULL); - - if (nlflag && !(i % 80) && backupcon.dwSize.X > resizewin.X) // do we need a nl? - { - att = backupcon.wAttributes; - SetConsoleTextAttribute(co, att); // all attributes off - WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); - } - } - SetConsoleTextAttribute(co, backupcon.wAttributes); // all attributes off - //if (nlflag) - // WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); - - getchar(); //pause! - - Z_Free(data); -} - - -// -// I_Quit: shutdown everything cleanly, in reverse order of Startup. -// -void I_Quit(void) -{ - HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - // when recording a demo, should exit using 'q', - // but sometimes we forget and use Alt+F4, so save here too. - if (demorecording) - G_CheckDemoStatus(); - - M_SaveConfig(NULL); // save game config, cvars.. - G_SaveGameData(); - - // maybe it needs that the ticcount continues, - // or something else that will be finished by I_ShutdownSystem(), - // so do it before. - D_QuitNetGame(); - - // shutdown everything that was started - I_ShutdownSystem(); - - if (shutdowning || errorcount) - I_Error("Error detected (%d)", errorcount); - -#ifdef LOGMESSAGES - if (logstream != INVALID_HANDLE_VALUE) - { - I_OutputMsg("I_Quit(): end of logstream.\r\n"); - CloseHandle(logstream); - logstream = INVALID_HANDLE_VALUE; - } -#endif - if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM")!=-1 - && co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR) - { - printf("\r"); - ShowEndTxt(co); - } - fflush(stderr); - exit(0); -} - -// -------------------------------------------------------------------------- -// I_ShowLastError -// Displays a GetLastError() error message in a MessageBox -// -------------------------------------------------------------------------- -void I_GetLastErrorMsgBox(void) -{ - LPSTR lpMsgBuf = NULL; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - lpMsgBuf, 0, NULL); - - // Display the string. - MessageBoxA(NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION); - - // put it in console too and log if any - CONS_Printf("Error: %s\n", lpMsgBuf); - - // Free the buffer. - LocalFree(lpMsgBuf); -} - -// =========================================================================================== -// CLEAN STARTUP & SHUTDOWN HANDLING, JUST CLOSE EVERYTHING YOU OPENED. -// =========================================================================================== -// -// -static quitfuncptr quit_funcs[MAX_QUIT_FUNCS] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -// Adds a function to the list that need to be called by I_SystemShutdown(). -// -void I_AddExitFunc(void (*func)()) -{ - int c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (!quit_funcs[c]) - { - quit_funcs[c] = func; - break; - } - } -} - -// Removes a function from the list that need to be called by I_SystemShutdown(). -// -void I_RemoveExitFunc(void (*func)()) -{ - int c; - - for (c = 0; c < MAX_QUIT_FUNCS; c++) - { - if (quit_funcs[c] == func) - { - while (c < MAX_QUIT_FUNCS - 1) - { - quit_funcs[c] = quit_funcs[c+1]; - c++; - } - quit_funcs[MAX_QUIT_FUNCS-1] = NULL; - break; - } - } -} - -// =========================================================================================== -// DIRECT INPUT HELPER CODE -// =========================================================================================== - -// Create a DirectInputDevice interface, -// create a DirectInputDevice2 interface if possible -static void CreateDevice2(LPDIRECTINPUT di, REFGUID pguid, LPDIRECTINPUTDEVICE* lpDEV, - LPDIRECTINPUTDEVICE2* lpDEV2) -{ - HRESULT hr, hr2; - LPDIRECTINPUTDEVICE lpdid1; - LPDIRECTINPUTDEVICE2 lpdid2 = NULL; - - hr = IDirectInput_CreateDevice(di, pguid, &lpdid1, NULL); - - if (SUCCEEDED(hr)) - { - // get Device2 but only if we are not in DirectInput version 3 - if (!bDX0300 && lpDEV2) - { - LPDIRECTINPUTDEVICE2 *rp = &lpdid2; - LPVOID *tp = (LPVOID *)rp; - hr2 = IDirectInputDevice_QueryInterface(lpdid1, &IID_IDirectInputDevice2, tp); - if (FAILED(hr2)) - { - CONS_Printf("\2Could not create IDirectInput device 2"); - lpdid2 = NULL; - } - } - } - else - I_Error("Could not create IDirectInput device"); - - *lpDEV = lpdid1; - if (lpDEV2) // only if we requested it - *lpDEV2 = lpdid2; -} - -// =========================================================================================== -// DIRECT INPUT MOUSE -// =========================================================================================== - -#define DI_MOUSE_BUFFERSIZE 16 // number of data elements in mouse buffer - -// -// Initialise the mouse. -// -static void I_ShutdownMouse(void); - -void I_StartupMouse(void) -{ - // this gets called when cv_usemouse is initted - // for the win32 version, we want to startup the mouse later -} - -static HANDLE mouse2filehandle = INVALID_HANDLE_VALUE; - -static void I_ShutdownMouse2(void) -{ - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - event_t event; - int i; - - SetCommMask(mouse2filehandle, 0); - - EscapeCommFunction(mouse2filehandle, CLRDTR); - EscapeCommFunction(mouse2filehandle, CLRRTS); - - PurgeComm(mouse2filehandle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); - - CloseHandle(mouse2filehandle); - - // emulate the up of all mouse buttons - for (i = 0; i < MOUSEBUTTONS; i++) - { - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; - D_PostEvent(&event); - } - - mouse2filehandle = INVALID_HANDLE_VALUE; - } -} - -#define MOUSECOMBUFFERSIZE 256 -static int handlermouse2x, handlermouse2y, handlermouse2buttons; - -static void I_PoolMouse2(void) -{ - UINT8 buffer[MOUSECOMBUFFERSIZE]; - COMSTAT ComStat; - DWORD dwErrorFlags, dwLength; - char dx, dy; - - static int bytenum; - static UINT8 combytes[4]; - DWORD i; - - ClearCommError(mouse2filehandle, &dwErrorFlags, &ComStat); - dwLength = min(MOUSECOMBUFFERSIZE, ComStat.cbInQue); - - if (dwLength > 0) - { - if (!ReadFile(mouse2filehandle, buffer, dwLength, &dwLength, NULL)) - { - CONS_Printf("\2Read Error on secondary mouse port\n"); - return; - } - - // parse the mouse packets - for (i = 0; i < dwLength; i++) - { - if ((buffer[i] & 64) == 64) - bytenum = 0; - - if (bytenum < 4) - combytes[bytenum] = buffer[i]; - bytenum++; - - if (bytenum == 1) - { - handlermouse2buttons &= ~3; - handlermouse2buttons |= ((combytes[0] & (32+16)) >>4); - } - else if (bytenum == 3) - { - dx = (char)((combytes[0] & 3) << 6); - dy = (char)((combytes[0] & 12) << 4); - dx = (char)(dx + combytes[1]); - dy = (char)(dy + combytes[2]); - handlermouse2x += dx; - handlermouse2y += dy; - } - else if (bytenum == 4) // fourth byte (logitech mouses) - { - if (buffer[i] & 32) - handlermouse2buttons |= 4; - else - handlermouse2buttons &= ~4; - } - } - } -} - -// secondary mouse doesn't use DirectX, therefore forget all about grabbing, acquire, etc. -void I_StartupMouse2(void) -{ - DCB dcb; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - I_ShutdownMouse2(); - - if (!cv_usemouse2.value) - return; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - // COM file handle - mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ|GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (mouse2filehandle == INVALID_HANDLE_VALUE) - { - int e = GetLastError(); - if (e == 5) - CONS_Printf("\2Can't open %s: Access denied\n" - "The port is probably already used by another device (mouse, modem,...)\n", - cv_mouse2port.string); - else - CONS_Printf("\2Can't open %s: error %d\n", cv_mouse2port.string, e); - return; - } - } - - // buffers - SetupComm(mouse2filehandle, MOUSECOMBUFFERSIZE, MOUSECOMBUFFERSIZE); - - // purge buffers - PurgeComm(mouse2filehandle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); - - // setup port to 1200 7N1 - dcb.DCBlength = sizeof (DCB); - - GetCommState(mouse2filehandle, &dcb); - - dcb.BaudRate = CBR_1200; - dcb.ByteSize = 7; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - - dcb.fBinary = dcb.fParity = TRUE; - - SetCommState(mouse2filehandle, &dcb); - - I_AddExitFunc(I_ShutdownMouse2); -} - -#define MAX_MOUSE_BTNS 5 -static int center_x, center_y; -static int old_mparms[3], new_mparms[3] = {0, 0, 1}; -static boolean restore_mouse = FALSE; -static int old_mouse_state = 0; -unsigned int MSHWheelMessage = 0; - -static void I_DoStartupSysMouse(void) -{ - boolean valid; - RECT w_rect; - - valid = SystemParametersInfo(SPI_GETMOUSE, 0, old_mparms, 0); - if (valid) - { - new_mparms[2] = old_mparms[2]; - restore_mouse = SystemParametersInfo(SPI_SETMOUSE, 0, new_mparms, 0); - } - - if (bAppFullScreen) - { - w_rect.top = 0; - w_rect.left = 0; - } - else - { - w_rect.top = windowPosY; - w_rect.left = windowPosX; - } - - w_rect.bottom = w_rect.top + VIDHEIGHT; - w_rect.right = w_rect.left + VIDWIDTH; - center_x = w_rect.left + (VIDWIDTH >> 1); - center_y = w_rect.top + (VIDHEIGHT >> 1); - SetCursor(NULL); - SetCursorPos(center_x, center_y); - SetCapture(hWndMain); - ClipCursor(&w_rect); -} - -static void I_ShutdownSysMouse(void) -{ - if (restore_mouse) - SystemParametersInfo(SPI_SETMOUSE, 0, old_mparms, 0); - ClipCursor(NULL); - ReleaseCapture(); -} - -void I_RestartSysMouse(void) -{ - if (nodinput) - { - I_ShutdownSysMouse(); - I_DoStartupSysMouse(); - } -} - -void I_GetSysMouseEvents(int mouse_state) -{ - int i; - event_t event; - int xmickeys = 0, ymickeys = 0; - POINT c_pos; - - for (i = 0; i < MAX_MOUSE_BTNS; i++) - { - // check if button pressed - if ((mouse_state & (1 << i)) && !(old_mouse_state & (1 << i))) - { - event.type = ev_keydown; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - // check if button released - if (!(mouse_state & (1 << i)) && (old_mouse_state & (1 << i))) - { - event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - } - old_mouse_state = mouse_state; - - // proceed mouse movements - GetCursorPos(&c_pos); - xmickeys = c_pos.x - center_x; - ymickeys = c_pos.y - center_y; - - if (xmickeys || ymickeys) - { - event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; - D_PostEvent(&event); - SetCursorPos(center_x, center_y); - } -} - -// This is called just before entering the main game loop, -// when we are going fullscreen and the loading screen has finished. -void I_DoStartupMouse(void) -{ - DIPROPDWORD dip; - - // mouse detection may be skipped by setting usemouse false - if (!cv_usemouse.value || M_CheckParm("-nomouse")) - { - mouse_enabled = false; - return; - } - - if (nodinput) - { - CONS_Printf("\tMouse will not use DirectInput.\n"); - // System mouse input will be initiated by VID_SetMode - I_AddExitFunc(I_ShutdownMouse); - - MSHWheelMessage = RegisterWindowMessage(MSH_MOUSEWHEEL); - } - else if (!lpDIM) // acquire the mouse only once - { - CreateDevice2(lpDI, &GUID_SysMouse, &lpDIM, NULL); - - if (lpDIM) - { - if (FAILED(IDirectInputDevice_SetDataFormat(lpDIM, &c_dfDIMouse))) - I_Error("Couldn't set mouse data format"); - - // create buffer for buffered data - dip.diph.dwSize = sizeof (dip); - dip.diph.dwHeaderSize = sizeof (dip.diph); - dip.diph.dwObj = 0; - dip.diph.dwHow = DIPH_DEVICE; - dip.dwData = DI_MOUSE_BUFFERSIZE; - if (FAILED(IDirectInputDevice_SetProperty(lpDIM, DIPROP_BUFFERSIZE, &dip.diph))) - I_Error("Couldn't set mouse buffer size"); - - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIM, hWndMain, - DISCL_EXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("Couldn't set mouse coop level"); - } - I_AddExitFunc(I_ShutdownMouse); - } - else - I_Error("Couldn't create mouse input"); - } - - // if re-enabled while running, just set mouse_enabled true again, - // do not acquire the mouse more than once - mouse_enabled = true; -} - -// -// Shutdown Mouse DirectInput device -// -static void I_ShutdownMouse(void) -{ - int i; - event_t event; - - CONS_Printf("I_ShutdownMouse()\n"); - - if (lpDIM) - { - IDirectInputDevice_Unacquire(lpDIM); - IDirectInputDevice_Release(lpDIM); - lpDIM = NULL; - } - - // emulate the up of all mouse buttons - for (i = 0; i < MOUSEBUTTONS; i++) - { - event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; - D_PostEvent(&event); - } - if (nodinput) - I_ShutdownSysMouse(); - - mouse_enabled = false; -} - -// -// Get buffered data from the mouse -// -void I_GetMouseEvents(void) -{ - DIDEVICEOBJECTDATA rgdod[DI_MOUSE_BUFFERSIZE]; - DWORD dwItems, d; - HRESULT hr; - - event_t event; - int xmickeys, ymickeys; - - if (mouse2filehandle != INVALID_HANDLE_VALUE) - { - //mouse movement - static UINT8 lastbuttons2 = 0; - - I_PoolMouse2(); - // post key event for buttons - if (handlermouse2buttons != lastbuttons2) - { - int i, j = 1, k; - k = handlermouse2buttons ^ lastbuttons2; // only changed bit to 1 - lastbuttons2 = (UINT8)handlermouse2buttons; - - for (i = 0; i < MOUSEBUTTONS; i++, j <<= 1) - if (k & j) - { - if (handlermouse2buttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; - D_PostEvent(&event); - } - } - - if (handlermouse2x || handlermouse2y) - { - event.type = ev_mouse2; - event.data1 = 0; - event.data2 = handlermouse2x<<1; - event.data3 = -handlermouse2y<<1; - handlermouse2x = 0; - handlermouse2y = 0; - - D_PostEvent(&event); - } - } - - if (!mouse_enabled || nodinput) - return; - -getBufferedData: - dwItems = DI_MOUSE_BUFFERSIZE; - hr = IDirectInputDevice_GetDeviceData(lpDIM, sizeof (DIDEVICEOBJECTDATA), rgdod, &dwItems, 0); - - // If data stream was interrupted, reacquire the device and try again. - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - hr = IDirectInputDevice_Acquire(lpDIM); - if (SUCCEEDED(hr)) - goto getBufferedData; - } - - // We got buffered input, act on it - if (SUCCEEDED(hr)) - { - xmickeys = ymickeys = 0; - - // dwItems contains number of elements read (could be 0) - for (d = 0; d < dwItems; d++) - { - if (rgdod[d].dwOfs >= DIMOFS_BUTTON0 && - rgdod[d].dwOfs < DIMOFS_BUTTON0 + MOUSEBUTTONS) - { - if (rgdod[d].dwData & 0x80) // Button down - event.type = ev_keydown; - else - event.type = ev_keyup; // Button up - - event.data1 = rgdod[d].dwOfs - DIMOFS_BUTTON0 + KEY_MOUSE1; - D_PostEvent(&event); - } - else if (rgdod[d].dwOfs == DIMOFS_X) - xmickeys += rgdod[d].dwData; - else if (rgdod[d].dwOfs == DIMOFS_Y) - ymickeys += rgdod[d].dwData; - - else if (rgdod[d].dwOfs == DIMOFS_Z) - { - // z-axes the wheel - if ((int)rgdod[d].dwData > 0) - event.data1 = KEY_MOUSEWHEELUP; - else - event.data1 = KEY_MOUSEWHEELDOWN; - event.type = ev_keydown; - D_PostEvent(&event); - } - - } - - if (xmickeys || ymickeys) - { - event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; - D_PostEvent(&event); - } - } -} - -// =========================================================================================== -// DIRECT INPUT JOYSTICK -// =========================================================================================== - -struct DIJoyInfo_s -{ - BYTE X,Y,Z,Rx,Ry,Rz,U,V; - LONG ForceAxises; -}; -typedef struct DIJoyInfo_s DIJoyInfo_t; - -// private info - static BYTE iJoyNum; // used by enumeration - static DIJoyInfo_t JoyInfo; - static BYTE iJoy2Num; - static DIJoyInfo_t JoyInfo2; - -//----------------------------------------------------------------------------- -// Name: EnumAxesCallback() -// Desc: Callback function for enumerating the axes on a joystick and counting -// each force feedback enabled axis -//----------------------------------------------------------------------------- -static BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, - VOID* pContext) -{ - DWORD* pdwNumForceFeedbackAxis = (DWORD*) pContext; - - if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) - (*pdwNumForceFeedbackAxis)++; - - return DIENUM_CONTINUE; -} - - -static HRESULT SetupForceTacile(LPDIRECTINPUTDEVICE2 DJI, LPDIRECTINPUTEFFECT *DJE, DWORD FFAXIS, FFType EffectType,REFGUID EffectGUID) -{ - HRESULT hr; - DIEFFECT eff; - DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; - LONG rglDirection[2] = { 0, 0 }; - DICONSTANTFORCE cf = { 0 }; // LONG lMagnitude - DIRAMPFORCE rf = {0,0}; // LONG lStart, lEnd; - DIPERIODIC pf = {0,0,0,0}; - ZeroMemory(&eff, sizeof (eff)); - if (FFAXIS > 2) - FFAXIS = 2; //up to 2 FFAXIS - eff.dwSize = sizeof (DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; // Cartesian and data format offsets - eff.dwDuration = INFINITE; - eff.dwSamplePeriod = 0; - eff.dwGain = DI_FFNOMINALMAX; - eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.dwTriggerRepeatInterval = 0; - eff.cAxes = FFAXIS; - eff.rgdwAxes = rgdwAxes; - eff.rglDirection = rglDirection; - eff.lpEnvelope = NULL; - eff.lpvTypeSpecificParams = NULL; - if (EffectType == ConstantForce) - { - eff.cbTypeSpecificParams = sizeof (cf); - eff.lpvTypeSpecificParams = &cf; - } - else if (EffectType == RampForce) - { - eff.cbTypeSpecificParams = sizeof (rf); - eff.lpvTypeSpecificParams = &rf; - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType) - { - eff.cbTypeSpecificParams = sizeof (pf); - eff.lpvTypeSpecificParams = &pf; - } -#if (DIRECTINPUT_VERSION >= 0x0600) - //eff.dwStartDelay = 0; -#endif - - // Create the prepared effect - if (FAILED(hr = IDirectInputDevice2_CreateEffect(DJI, EffectGUID, - &eff, DJE, NULL))) - { - return hr; - } - - if (NULL == *DJE) - return E_FAIL; - - return hr; -} - -static BOOL CALLBACK DIEnumEffectsCallback1(LPCDIEFFECTINFO pdei, LPVOID pvRef) -{ - LPDIRECTINPUTEFFECT *DJE = pvRef; - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_CONSTANTFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJA,DJE, JoyInfo.ForceAxises, ConstantForce, &pdei->guid))) - return DIENUM_STOP; - } - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_RAMPFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJA,DJE, JoyInfo.ForceAxises, RampForce, &pdei->guid))) - return DIENUM_STOP; - } - return DIENUM_CONTINUE; -} - -static BOOL CALLBACK DIEnumEffectsCallback2(LPCDIEFFECTINFO pdei, LPVOID pvRef) -{ - LPDIRECTINPUTEFFECT *DJE = pvRef; - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_CONSTANTFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJ2A,DJE, JoyInfo2.ForceAxises, ConstantForce, &pdei->guid))) - return DIENUM_STOP; - } - if (DIEFT_GETTYPE(pdei->dwEffType) == DIEFT_RAMPFORCE) - { - if (SUCCEEDED(SetupForceTacile(lpDIJ2A,DJE, JoyInfo2.ForceAxises, RampForce, &pdei->guid))) - return DIENUM_STOP; - } - return DIENUM_CONTINUE; -} - -static REFGUID DIETable[] = -{ - &GUID_ConstantForce, //ConstantForce - &GUID_RampForce, //RampForce - &GUID_Square, //SquareForce - &GUID_Sine, //SineForce - &GUID_Triangle, //TriangleForce - &GUID_SawtoothUp, //SawtoothUpForce - &GUID_SawtoothDown, //SawtoothDownForce - (REFGUID)-1, //NumberofForces -}; - -static HRESULT SetupAllForces(LPDIRECTINPUTDEVICE2 DJI, LPDIRECTINPUTEFFECT DJE[], DWORD FFAXIS) -{ - FFType ForceType = EvilForce; - if (DJI == lpDIJA) - { - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback1,&DJE[ConstantForce],DIEFT_CONSTANTFORCE); - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback1,&DJE[RampForce],DIEFT_RAMPFORCE); - } - else if (DJI == lpDIJA) - { - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback2,&DJE[ConstantForce],DIEFT_CONSTANTFORCE); - IDirectInputDevice2_EnumEffects(DJI,DIEnumEffectsCallback2,&DJE[RampForce],DIEFT_RAMPFORCE); - } - for (ForceType = SquareForce; ForceType > NumberofForces && DIETable[ForceType] != (REFGUID)-1; ForceType++) - if (DIETable[ForceType]) - SetupForceTacile(DJI,&DJE[ForceType], FFAXIS, ForceType, DIETable[ForceType]); - return S_OK; -} - -static void LimitEffect(LPDIEFFECT eff, FFType EffectType) -{ - LPDICONSTANTFORCE pCF = eff->lpvTypeSpecificParams; - LPDIPERIODIC pDP= eff->lpvTypeSpecificParams; - if (eff->rglDirection) - { - } -/* if (eff->dwDuration != INFINITE && eff->dwDuration < 0) - { - eff->dwDuration = 0; - }*/ - if (eff->dwGain != 0) - { - if (eff->dwGain > DI_FFNOMINALMAX) - eff->dwGain = DI_FFNOMINALMAX; - //else if (eff->dwGain < -DI_FFNOMINALMAX) - // eff->dwGain = DI_FFNOMINALMAX; - } - if (EffectType == ConstantForce && pCF->lMagnitude) - { - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType && pDP) - { - } - -} - -static HRESULT SetForceTacile(LPDIRECTINPUTEFFECT SDIE, const JoyFF_t *FF,DWORD FFAXIS, FFType EffectType) -{ - DIEFFECT eff; - HRESULT hr; - LONG Magnitude; - LONG rglDirection[2] = { 0, 0 }; - DICONSTANTFORCE cf = { 0 }; // LONG lMagnitude - DIRAMPFORCE rf = {0,0}; // LONG lStart, lEnd; - DIPERIODIC pf = {0,0,0,0}; - if (!FF) - IDirectInputEffect_Stop(SDIE); - Magnitude = FF->Magnitude; - ZeroMemory(&eff, sizeof (eff)); - eff.dwSize = sizeof (eff); - //DIEP_START - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; // Cartesian and data format offsets - //DIEP_DURATION - eff.dwDuration = FF->Duration; - //DIEP_GAIN - eff.dwGain = FF->Gain; - //DIEP_DIRECTION - eff.rglDirection = rglDirection; - //DIEP_TYPESPECIFICPARAMS - if (FFAXIS > 1) - { - double dMagnitude; - dMagnitude = (double)Magnitude; - dMagnitude = hypot(dMagnitude, dMagnitude); - Magnitude = (DWORD)dMagnitude; - rglDirection[0] = FF->ForceX; - rglDirection[1] = FF->ForceY; - } - if (EffectType == ConstantForce) - { - cf.lMagnitude = Magnitude; - eff.cbTypeSpecificParams = sizeof (cf); - eff.lpvTypeSpecificParams = &cf; - } - else if (EffectType == RampForce) - { - rf.lStart = FF->Start; - rf.lEnd = FF->End; - eff.cbTypeSpecificParams = sizeof (rf); - eff.lpvTypeSpecificParams = &rf; - } - else if (EffectType >= SquareForce && SawtoothDownForce >= EffectType) - { - pf.dwMagnitude = Magnitude; - pf.lOffset = FF->Offset; - pf.dwPhase = FF->Phase; - pf.dwPeriod = FF->Period; - eff.cbTypeSpecificParams = sizeof (pf); - eff.lpvTypeSpecificParams = &pf; - } - - LimitEffect(&eff, EffectType); - - hr = IDirectInputEffect_SetParameters(SDIE, &eff, - DIEP_START|DIEP_DURATION|DIEP_GAIN|DIEP_DIRECTION|DIEP_TYPESPECIFICPARAMS); - return hr; -} - -void I_Tactile(FFType Type, const JoyFF_t *Effect) -{ - if (!lpDIJA) return; - if (FAILED(IDirectInputDevice2_Acquire(lpDIJA))) - return; - if (Type == EvilForce) - IDirectInputDevice2_SendForceFeedbackCommand(lpDIJA,DISFFC_STOPALL); - if (Type <= EvilForce || Type > NumberofForces || !lpDIE[Type]) - return; - SetForceTacile(lpDIE[Type], Effect, JoyInfo.ForceAxises, Type); -} - -void I_Tactile2(FFType Type, const JoyFF_t *Effect) -{ - if (!lpDIJ2A) return; - if (FAILED(IDirectInputDevice2_Acquire(lpDIJ2A))) - return; - if (Type == EvilForce) - IDirectInputDevice2_SendForceFeedbackCommand(lpDIJ2A,DISFFC_STOPALL); - if (Type <= EvilForce || Type > NumberofForces || !lpDIE2[Type]) - return; - SetForceTacile(lpDIE2[Type],Effect, JoyInfo2.ForceAxises, Type); -} - -// ------------------ -// SetDIDwordProperty (HELPER) -// Set a DWORD property on a DirectInputDevice. -// ------------------ -static HRESULT SetDIDwordProperty(LPDIRECTINPUTDEVICE pdev, - REFGUID guidProperty, - DWORD dwObject, - DWORD dwHow, - DWORD dwValue) -{ - DIPROPDWORD dipdw; - - dipdw.diph.dwSize = sizeof (dipdw); - dipdw.diph.dwHeaderSize = sizeof (dipdw.diph); - dipdw.diph.dwObj = dwObject; - dipdw.diph.dwHow = dwHow; - dipdw.dwData = dwValue; - - return IDirectInputDevice_SetProperty(pdev, guidProperty, &dipdw.diph); -} - - -// --------------- -// DIEnumJoysticks -// There is no such thing as a 'system' joystick, contrary to mouse, -// we must enumerate and choose one joystick device to use -// --------------- -static BOOL CALLBACK DIEnumJoysticks (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //cv_usejoystick -{ - LPDIRECTINPUTDEVICE pdev; - DIPROPRANGE diprg; - DIDEVCAPS caps; - BOOL bUseThisOne = FALSE; - - iJoyNum++; - - //faB: if cv holds a string description of joystick, the value from atoi() is 0 - // else, the value was probably set by user at console to one of the previously - // enumerated joysticks - if (((consvar_t *)pvRef)->value == iJoyNum -#ifndef _UNICODE - || !lstrcmpA(((consvar_t *)pvRef)->string, lpddi->tszProductName) -#endif - ) - bUseThisOne = TRUE; - - //CONS_Printf(" cv joy is %s\n", ((consvar_t *)pvRef)->string); - - // print out device name - CONS_Printf("%c%d: %s\n", - (bUseThisOne) ? '\2' : ' ', // show name in white if this is the one we will use - iJoyNum, - //(GET_DIDEVICE_SUBTYPE(lpddi->dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD) ? "Gamepad " : "Joystick", - lpddi->tszProductName); //, lpddi->tszInstanceName); - - // use specified joystick (cv_usejoystick.value in pvRef) - if (!bUseThisOne) - return DIENUM_CONTINUE; - - ((consvar_t *)pvRef)->value = iJoyNum; - if (IDirectInput_CreateDevice (lpDI, &lpddi->guidInstance, - &pdev, NULL) != DI_OK) - { - // if it failed, then we can't use this joystick for some - // bizarre reason. (Maybe the user unplugged it while we - // were in the middle of enumerating it.) So continue enumerating - CONS_Printf("DIEnumJoysticks(): CreateDevice FAILED\n"); - return DIENUM_CONTINUE; - } - - // get the Device capabilities - // - caps.dwSize = sizeof (DIDEVCAPS_DX3); - if (FAILED(IDirectInputDevice_GetCapabilities (pdev, &caps))) - { - CONS_Printf("DIEnumJoysticks(): GetCapabilities FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - if (!(caps.dwFlags & DIDC_ATTACHED)) // should be, since we enumerate only attached devices - return DIENUM_CONTINUE; - - Joystick.bJoyNeedPoll = ((caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0); - - if (caps.dwFlags & DIDC_FORCEFEEDBACK) - JoyInfo.ForceAxises = 0; - else - JoyInfo.ForceAxises = -1; - - Joystick.bGamepadStyle = (GET_DIDEVICE_SUBTYPE(caps.dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD); - //DEBUG CONS_Printf("Gamepad: %d\n", Joystick.bGamepadStyle); - - - CONS_Printf("Capabilities: %d axes, %d buttons, %d POVs, poll %d, Gamepad %d\n", - caps.dwAxes, caps.dwButtons, caps.dwPOVs, Joystick.bJoyNeedPoll, Joystick.bGamepadStyle); - - // Set the data format to "simple joystick" - a predefined data format - // - // A data format specifies which controls on a device we - // are interested in, and how they should be reported. - // - // This tells DirectInput that we will be passing a - // DIJOYSTATE structure to IDirectInputDevice::GetDeviceState. - if (IDirectInputDevice_SetDataFormat (pdev, &c_dfDIJoystick) != DI_OK) - { - CONS_Printf("DIEnumJoysticks(): SetDataFormat FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // Set the cooperativity level to let DirectInput know how - // this device should interact with the system and with other - // DirectInput applications. - if (IDirectInputDevice_SetCooperativeLevel (pdev, hWndMain, - DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) - { - CONS_Printf("DIEnumJoysticks(): SetCooperativeLevel FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // set the range of the joystick axis - diprg.diph.dwSize = sizeof (DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof (DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -JOYAXISRANGE; // value for extreme left - diprg.lMax = +JOYAXISRANGE; // value for extreme right - - diprg.diph.dwObj = DIJOFS_X; // set the x-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //goto SetPropFail; - JoyInfo.X = FALSE; - } - else JoyInfo.X = TRUE; - - diprg.diph.dwObj = DIJOFS_Y; // set the y-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { -//SetPropFail: -// CONS_Printf("DIEnumJoysticks(): SetProperty FAILED\n"); -// IDirectInputDevice_Release (pdev); -// return DIENUM_CONTINUE; - JoyInfo.Y = FALSE; - } - else JoyInfo.Y = TRUE; - - diprg.diph.dwObj = DIJOFS_Z; // set the z-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_Z not found\n"); - JoyInfo.Z = FALSE; - } - else JoyInfo.Z = TRUE; - - diprg.diph.dwObj = DIJOFS_RX; // set the x-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RX (x-rudder) not found\n"); - JoyInfo.Rx = FALSE; - } - else JoyInfo.Rx = TRUE; - - diprg.diph.dwObj = DIJOFS_RY; // set the y-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RY (y-rudder) not found\n"); - JoyInfo.Ry = FALSE; - } - else JoyInfo.Ry = TRUE; - - diprg.diph.dwObj = DIJOFS_RZ; // set the z-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (z-rudder) not found\n"); - JoyInfo.Rz = FALSE; - } - else JoyInfo.Rz = TRUE; - diprg.diph.dwObj = DIJOFS_SLIDER(0); // set the x-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (x-misc) not found\n"); - JoyInfo.U = FALSE; - } - else JoyInfo.U = TRUE; - - diprg.diph.dwObj = DIJOFS_SLIDER(1); // set the y-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (y-misc) not found\n"); - JoyInfo.V = FALSE; - } - else JoyInfo.V = TRUE; - - // set X axis dead zone to 25% (to avoid accidental turning) - if (!Joystick.bGamepadStyle) - { - if (JoyInfo.X) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_X, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for X DEAD ZONE"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Y) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Y, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for Y DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Z) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Z, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for Z DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Rx) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RX, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RX DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Ry) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RY, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RY DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.Rz) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RZ, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for RZ DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.U) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(0), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for U DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo.V) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(1), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks(): couldn't SetProperty for V DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - } - - // query for IDirectInputDevice2 - we need this to poll the joystick - if (bDX0300) - { - FFType i = EvilForce; - // we won't use the poll - lpDIJA = NULL; - for (i = 0; i > NumberofForces; i++) - lpDIE[i] = NULL; - } - else - { - LPDIRECTINPUTDEVICE2 *rp = &lpDIJA; - LPVOID *tp = (LPVOID *)rp; - if (FAILED(IDirectInputDevice_QueryInterface(pdev, &IID_IDirectInputDevice2, tp))) - { - CONS_Printf("DIEnumJoysticks(): QueryInterface FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - if (lpDIJA && JoyInfo.ForceAxises != -1) - { - // Since we will be playing force feedback effects, we should disable the - // auto-centering spring. - if (FAILED(SetDIDwordProperty(pdev, DIPROP_AUTOCENTER, 0, DIPH_DEVICE, FALSE))) - { - //NOP - } - - // Enumerate and count the axes of the joystick - if (FAILED(IDirectInputDevice_EnumObjects(pdev, EnumAxesCallback, - (VOID*)&JoyInfo.ForceAxises, DIDFT_AXIS))) - { - JoyInfo.ForceAxises = -1; - } - else - { - SetupAllForces(lpDIJA,lpDIE,JoyInfo.ForceAxises); - } - } - } - - // we successfully created an IDirectInputDevice. So stop looking - // for another one. - lpDIJ = pdev; - return DIENUM_STOP; -} - -// -------------- -// I_InitJoystick -// This is called everytime the 'use_joystick' variable changes -// It is normally called at least once at startup when the config is loaded -// -------------- -void I_InitJoystick(void) -{ - HRESULT hr; - - // cleanup - I_ShutdownJoystick(); - - //joystick detection can be skipped by setting use_joystick to 0 - if (M_CheckParm("-nojoy")) - { - CONS_Printf("Joystick disabled\n"); - return; - } - else - // don't do anything at the registration of the joystick cvar, - // until config is loaded - if (!lstrcmpA(cv_usejoystick.string, "0")) - return; - - // acquire the joystick only once - if (!lpDIJ) - { - joystick_detected = false; - - CONS_Printf("Looking for joystick devices:\n"); - iJoyNum = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, DIEnumJoysticks, - (void *)&cv_usejoystick, // our user parameter is joystick number - DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - { - CONS_Printf("\nI_InitJoystick(): EnumDevices FAILED\n"); - cv_usejoystick.value = 0; - return; - } - - if (!lpDIJ) - { - if (!iJoyNum) - CONS_Printf("none found\n"); - else - { - CONS_Printf("none used\n"); - if (cv_usejoystick.value > 0 && cv_usejoystick.value > iJoyNum) - { - CONS_Printf("\2Set the use_joystick variable to one of the" - " enumerated joystick numbers\n"); - } - } - cv_usejoystick.value = 0; - return; - } - - I_AddExitFunc(I_ShutdownJoystick); - - // set coop level - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIJ, hWndMain, - DISCL_NONEXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("I_InitJoystick: SetCooperativeLevel FAILED"); - } - } - else - CONS_Printf("Joystick already initialized\n"); - - // we don't unacquire joystick, so let's just pretend we re-acquired it - joystick_detected = true; -} -//Joystick 2 - -// --------------- -// DIEnumJoysticks2 -// There is no such thing as a 'system' joystick, contrary to mouse, -// we must enumerate and choose one joystick device to use -// --------------- -static BOOL CALLBACK DIEnumJoysticks2 (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //cv_usejoystick -{ - LPDIRECTINPUTDEVICE pdev; - DIPROPRANGE diprg; - DIDEVCAPS caps; - BOOL bUseThisOne = FALSE; - - iJoy2Num++; - - //faB: if cv holds a string description of joystick, the value from atoi() is 0 - // else, the value was probably set by user at console to one of the previsouly - // enumerated joysticks - if (((consvar_t *)pvRef)->value == iJoy2Num -#ifndef _UNICODE - || !lstrcmpA(((consvar_t *)pvRef)->string, lpddi->tszProductName) -#endif - ) - bUseThisOne = TRUE; - - //CONS_Printf(" cv joy2 is %s\n", ((consvar_t *)pvRef)->string); - - // print out device name - CONS_Printf("%c%d: %s\n", - (bUseThisOne) ? '\2' : ' ', // show name in white if this is the one we will use - iJoy2Num, - //(GET_DIDEVICE_SUBTYPE(lpddi->dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD) ? "Gamepad " : "Joystick", - lpddi->tszProductName); //, lpddi->tszInstanceName); - - // use specified joystick (cv_usejoystick.value in pvRef) - if (!bUseThisOne) - return DIENUM_CONTINUE; - - ((consvar_t *)pvRef)->value = iJoy2Num; - if (IDirectInput_CreateDevice (lpDI, &lpddi->guidInstance, - &pdev, NULL) != DI_OK) - { - // if it failed, then we can't use this joystick for some - // bizarre reason. (Maybe the user unplugged it while we - // were in the middle of enumerating it.) So continue enumerating - CONS_Printf("DIEnumJoysticks2(): CreateDevice FAILED\n"); - return DIENUM_CONTINUE; - } - - - // get the Device capabilities - // - caps.dwSize = sizeof (DIDEVCAPS_DX3); - if (FAILED(IDirectInputDevice_GetCapabilities (pdev, &caps))) - { - CONS_Printf("DIEnumJoysticks2(): GetCapabilities FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - if (!(caps.dwFlags & DIDC_ATTACHED)) // should be, since we enumerate only attached devices - return DIENUM_CONTINUE; - - Joystick2.bJoyNeedPoll = ((caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0); - - if (caps.dwFlags & DIDC_FORCEFEEDBACK) - JoyInfo2.ForceAxises = 0; - else - JoyInfo2.ForceAxises = -1; - - Joystick2.bGamepadStyle = (GET_DIDEVICE_SUBTYPE(caps.dwDevType) == DIDEVTYPEJOYSTICK_GAMEPAD); - //DEBUG CONS_Printf("Gamepad: %d\n", Joystick2.bGamepadStyle); - - - CONS_Printf("Capabilities: %d axes, %d buttons, %d POVs, poll %d, Gamepad %d\n", - caps.dwAxes, caps.dwButtons, caps.dwPOVs, Joystick2.bJoyNeedPoll, Joystick2.bGamepadStyle); - - - // Set the data format to "simple joystick" - a predefined data format - // - // A data format specifies which controls on a device we - // are interested in, and how they should be reported. - // - // This tells DirectInput that we will be passing a - // DIJOYSTATE structure to IDirectInputDevice::GetDeviceState. - if (IDirectInputDevice_SetDataFormat (pdev, &c_dfDIJoystick) != DI_OK) - { - CONS_Printf("DIEnumJoysticks2(): SetDataFormat FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // Set the cooperativity level to let DirectInput know how - // this device should interact with the system and with other - // DirectInput applications. - if (IDirectInputDevice_SetCooperativeLevel (pdev, hWndMain, - DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) - { - CONS_Printf("DIEnumJoysticks2(): SetCooperativeLevel FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - // set the range of the joystick axis - diprg.diph.dwSize = sizeof (DIPROPRANGE); - diprg.diph.dwHeaderSize = sizeof (DIPROPHEADER); - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = -JOYAXISRANGE; // value for extreme left - diprg.lMax = +JOYAXISRANGE; // value for extreme right - - diprg.diph.dwObj = DIJOFS_X; // set the x-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //goto SetPropFail; - JoyInfo2.X = FALSE; - } - else JoyInfo2.X = TRUE; - - diprg.diph.dwObj = DIJOFS_Y; // set the y-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { -//SetPropFail: -// CONS_Printf("DIEnumJoysticks(): SetProperty FAILED\n"); -// IDirectInputDevice_Release (pdev); -// return DIENUM_CONTINUE; - JoyInfo2.Y = FALSE; - } - else JoyInfo2.Y = TRUE; - - diprg.diph.dwObj = DIJOFS_Z; // set the z-axis range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_Z not found\n"); - JoyInfo2.Z = FALSE; - } - else JoyInfo2.Z = TRUE; - - diprg.diph.dwObj = DIJOFS_RX; // set the x-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RX (x-rudder) not found\n"); - JoyInfo2.Rx = FALSE; - } - else JoyInfo2.Rx = TRUE; - - diprg.diph.dwObj = DIJOFS_RY; // set the y-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RY (y-rudder) not found\n"); - JoyInfo2.Ry = FALSE; - } - else JoyInfo2.Ry = TRUE; - - diprg.diph.dwObj = DIJOFS_RZ; // set the z-rudder range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (z-rudder) not found\n"); - JoyInfo2.Rz = FALSE; - } - else JoyInfo2.Rz = TRUE; - diprg.diph.dwObj = DIJOFS_SLIDER(0); // set the x-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (x-misc) not found\n"); - JoyInfo2.U = FALSE; - } - else JoyInfo2.U = TRUE; - - diprg.diph.dwObj = DIJOFS_SLIDER(1); // set the y-misc range - if (FAILED(IDirectInputDevice_SetProperty(pdev, DIPROP_RANGE, &diprg.diph))) - { - //CONS_Printf("DIJOFS_RZ (y-misc) not found\n"); - JoyInfo2.V = FALSE; - } - else JoyInfo2.V = TRUE; - - // set X axis dead zone to 25% (to avoid accidental turning) - if (!Joystick2.bGamepadStyle) - { - if (JoyInfo2.X) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_X, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for X DEAD ZONE"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Y) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Y, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for Y DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Z) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_Z, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for Z DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Rx) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RX, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RX DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Ry) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RY, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RY DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.Rz) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_RZ, - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for RZ DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.U) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(0), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for U DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - if (JoyInfo2.V) - if (FAILED(SetDIDwordProperty (pdev, DIPROP_DEADZONE, DIJOFS_SLIDER(1), - DIPH_BYOFFSET, 2500))) - { - CONS_Printf("DIEnumJoysticks2(): couldn't SetProperty for V DEAD ZONE\n"); - //IDirectInputDevice_Release (pdev); - //return DIENUM_CONTINUE; - } - } - - // query for IDirectInputDevice2 - we need this to poll the joystick - if (bDX0300) - { - FFType i = EvilForce; - // we won't use the poll - lpDIJA = NULL; - for (i = 0; i > NumberofForces; i++) - lpDIE[i] = NULL; - } - else - { - LPDIRECTINPUTDEVICE2 *rp = &lpDIJ2A; - LPVOID *tp = (LPVOID *)rp; - if (FAILED(IDirectInputDevice_QueryInterface(pdev, &IID_IDirectInputDevice2, tp))) - { - CONS_Printf("DIEnumJoysticks2(): QueryInterface FAILED\n"); - IDirectInputDevice_Release (pdev); - return DIENUM_CONTINUE; - } - - if (lpDIJ2A && JoyInfo2.ForceAxises != -1) - { - // Since we will be playing force feedback effects, we should disable the - // auto-centering spring. - if (FAILED(SetDIDwordProperty(pdev, DIPROP_AUTOCENTER, 0, DIPH_DEVICE, FALSE))) - { - //NOP - } - - // Enumerate and count the axes of the joystick - if (FAILED(IDirectInputDevice_EnumObjects(pdev, EnumAxesCallback, - (VOID*)&JoyInfo2.ForceAxises, DIDFT_AXIS))) - { - JoyInfo2.ForceAxises = -1; - } - else - { - SetupAllForces(lpDIJ2A,lpDIE2,JoyInfo2.ForceAxises); - } - } - } - - // we successfully created an IDirectInputDevice. So stop looking - // for another one. - lpDIJ2 = pdev; - return DIENUM_STOP; -} - - -// -------------- -// I_InitJoystick2 -// This is called everytime the 'use_joystick2' variable changes -// It is normally called at least once at startup when the config is loaded -// -------------- -void I_InitJoystick2 (void) -{ - HRESULT hr; - - // cleanup - I_ShutdownJoystick2 (); - - joystick2_detected = false; - - // joystick detection can be skipped by setting use_joystick to 0 - if (M_CheckParm("-nojoy")) - { - CONS_Printf("Joystick2 disabled\n"); - return; - } - else - // don't do anything at the registration of the joystick cvar, - // until config is loaded - if (!lstrcmpA(cv_usejoystick2.string, "0")) - return; - - // acquire the joystick only once - if (!lpDIJ2) - { - joystick2_detected = false; - - CONS_Printf("Looking for joystick devices:\n"); - iJoy2Num = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticks2, - (void *)&cv_usejoystick2, // our user parameter is joystick number - DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - { - CONS_Printf("\nI_InitJoystick2(): EnumDevices FAILED\n"); - cv_usejoystick2.value = 0; - return; - } - - if (!lpDIJ2) - { - if (iJoy2Num == 0) - CONS_Printf("none found\n"); - else - { - CONS_Printf("none used\n"); - if (cv_usejoystick2.value > 0 && - cv_usejoystick2.value > iJoy2Num) - { - CONS_Printf("\2Set the use_joystick2 variable to one of the" - " enumerated joysticks number\n"); - } - } - cv_usejoystick2.value = 0; - return; - } - - I_AddExitFunc (I_ShutdownJoystick2); - - // set coop level - if (FAILED(IDirectInputDevice_SetCooperativeLevel (lpDIJ2, hWndMain, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND))) - I_Error("I_InitJoystick2: SetCooperativeLevel FAILED"); - - // later - //if (FAILED(IDirectInputDevice_Acquire (lpDIJ2))) - // I_Error("Couldn't acquire Joystick2"); - - joystick2_detected = true; - } - else - CONS_Printf("Joystick2 already initialized\n"); - - //faB: we don't unacquire joystick, so let's just pretend we re-acquired it - joystick2_detected = true; -} - -/** \brief Joystick 1 buttons states -*/ -static INT64 lastjoybuttons = 0; - -/** \brief Joystick 1 hats state -*/ -static INT64 lastjoyhats = 0; - -static void I_ShutdownJoystick(void) -{ - int i; - event_t event; - - lastjoybuttons = lastjoyhats = 0; - - event.type = ev_keyup; - - // emulate the up of all joystick buttons - for (i = 0;i < JOYBUTTONS;i++) - { - event.data1 = KEY_JOY1+i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i = 0;i < JOYHATS*4;i++) - { - event.data1 = KEY_HAT1+i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick; - for (i = 0;i < JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - if (joystick_detected) - CONS_Printf("I_ShutdownJoystick()\n"); - - for (i = 0; i > NumberofForces; i++) - { - if (lpDIE[i]) - { - IDirectInputEffect_Release(lpDIE[i]); - lpDIE[i] = NULL; - - } - } - if (lpDIJ) - { - IDirectInputDevice_Unacquire(lpDIJ); - IDirectInputDevice_Release(lpDIJ); - lpDIJ = NULL; - } - if (lpDIJA) - { - IDirectInputDevice2_Release(lpDIJA); - lpDIJA = NULL; - } - joystick_detected = false; -} - -/** \brief Joystick 2 buttons states -*/ -static INT64 lastjoy2buttons = 0; - -/** \brief Joystick 2 hats state -*/ -static INT64 lastjoy2hats = 0; - -static void I_ShutdownJoystick2(void) -{ - int i; - event_t event; - - lastjoy2buttons = lastjoy2hats = 0; - - event.type = ev_keyup; - - // emulate the up of all joystick buttons - for (i = 0;i < JOYBUTTONS;i++) - { - event.data1 = KEY_2JOY1+i; - D_PostEvent(&event); - } - - // emulate the up of all joystick hats - for (i = 0;i < JOYHATS*4;i++) - { - event.data1 = KEY_2HAT1+i; - D_PostEvent(&event); - } - - // reset joystick position - event.type = ev_joystick2; - for (i = 0;i < JOYAXISSET; i++) - { - event.data1 = i; - D_PostEvent(&event); - } - - if (joystick2_detected) - CONS_Printf("I_ShutdownJoystick2()\n"); - - for (i = 0; i > NumberofForces; i++) - { - if (lpDIE2[i]) - { - IDirectInputEffect_Release(lpDIE2[i]); - lpDIE2[i] = NULL; - } - } - if (lpDIJ2) - { - IDirectInputDevice_Unacquire(lpDIJ2); - IDirectInputDevice_Release(lpDIJ2); - lpDIJ2 = NULL; - } - if (lpDIJ2A) - { - IDirectInputDevice2_Release(lpDIJ2A); - lpDIJ2A = NULL; - } - joystick2_detected = false; -} - -// ------------------- -// I_GetJoystickEvents -// Get current joystick axis and button states -// ------------------- -void I_GetJoystickEvents(void) -{ - HRESULT hr; - DIJOYSTATE js; // DirectInput joystick state - int i; - INT64 joybuttons = 0; - INT64 joyhats = 0; - event_t event; - - if (!lpDIJ) - return; - - // if input is lost then acquire and keep trying - for (;;) - { - // poll the joystick to read the current state - // if the device doesn't require polling, this function returns almost instantly - if (lpDIJA) - { - hr = IDirectInputDevice2_Poll(lpDIJA); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - goto acquire; - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents(): Poll FAILED\n"); - return; - } - } - - // get the input's device state, and put the state in dims - hr = IDirectInputDevice_GetDeviceState(lpDIJ, sizeof (DIJOYSTATE), &js); - - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // DirectInput is telling us that the input stream has - // been interrupted. We aren't tracking any state - // between polls, so we don't have any special reset - // that needs to be done. We just re-acquire and - // try again. - goto acquire; - } - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents(): GetDeviceState FAILED\n"); - return; - } - - break; -acquire: - if (FAILED(IDirectInputDevice_Acquire(lpDIJ))) - return; - } - - // look for as many buttons as g_input code supports, we don't use the others - for (i = JOYBUTTONS_MIN - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (js.rgbButtons[i]) - joybuttons |= 1; - } - - for (i = JOYHATS_MIN -1; i >=0; i--) - { - if (js.rgdwPOV[i] != 0xffff && js.rgdwPOV[i] != 0xffffffff) - { - if (js.rgdwPOV[i] > 270 * DI_DEGREES || js.rgdwPOV[i] < 90 * DI_DEGREES) - joyhats |= 1<<(0 + 4*i); // UP - else if (js.rgdwPOV[i] > 90 * DI_DEGREES && js.rgdwPOV[i] < 270 * DI_DEGREES) - joyhats |= 1<<(1 + 4*i); // DOWN - if (js.rgdwPOV[i] > 0 * DI_DEGREES && js.rgdwPOV[i] < 180 * DI_DEGREES) - joyhats |= 1<<(3 + 4*i); // LEFT - else if (js.rgdwPOV[i] > 180 * DI_DEGREES && js.rgdwPOV[i] < 360 * DI_DEGREES) - joyhats |= 1<<(2 + 4*i); // RIGHT - } - } - - if (joybuttons != lastjoybuttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoybuttons; - lastjoybuttons = joybuttons; - - for (i = 0; i < JOYBUTTONS && i < JOYBUTTONS_MAX; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_JOY1 + i; - D_PostEvent(&event); - } - } - } - - if (joyhats != lastjoyhats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoyhats; - lastjoyhats = joyhats; - - for (i = 0; i < JOYHATS*4 && i < JOYHATS_MAX*4; i++, j <<= 1) - { - if (newhats & j) // button changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_HAT1 + i; - D_PostEvent(&event); - } - } - - } - - // send joystick axis positions - event.type = ev_joystick; - event.data1 = event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.X) - { - if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Y) - { - if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.X) event.data2 = js.lX; // x axis - if (JoyInfo.Y) event.data3 = js.lY; // y axis - } - - D_PostEvent(&event); -#if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.Z) - { - if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Rx) - { - if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.Z) event.data2 = js.lZ; // z axis - if (JoyInfo.Rx) event.data3 = js.lRx; // rx axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; - - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.Rx) - { - if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.Rz) - { - if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo.Rz) event.data3 = js.lRz; // rz axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; - if (Joystick.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo.U) - { - if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo.V) - { - if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo.V) event.data3 = js.rglSlider[1]; // V axis - } - D_PostEvent(&event); -#endif -} - -// ------------------- -// I_GetJoystickEvents -// Get current joystick axis and button states -// ------------------- -void I_GetJoystick2Events(void) -{ - HRESULT hr; - DIJOYSTATE js; // DirectInput joystick state - int i; - INT64 joybuttons = 0; - INT64 joyhats = 0; - event_t event; - - if (!lpDIJ2) - return; - - // if input is lost then acquire and keep trying - for (;;) - { - // poll the joystick to read the current state - // if the device doesn't require polling, this function returns almost instantly - if (lpDIJ2A) - { - hr = IDirectInputDevice2_Poll(lpDIJ2A); - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - goto acquire; - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystick2Events(): Poll FAILED\n"); - return; - } - } - - // get the input's device state, and put the state in dims - hr = IDirectInputDevice_GetDeviceState(lpDIJ2, sizeof (DIJOYSTATE), &js); - - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // DirectInput is telling us that the input stream has - // been interrupted. We aren't tracking any state - // between polls, so we don't have any special reset - // that needs to be done. We just re-acquire and - // try again. - goto acquire; - } - else if (FAILED(hr)) - { - CONS_Printf("I_GetJoystickEvents2(): GetDeviceState FAILED\n"); - return; - } - - break; -acquire: - if (FAILED(IDirectInputDevice_Acquire(lpDIJ2))) - return; - } - - // look for as many buttons as g_input code supports, we don't use the others - for (i = JOYBUTTONS_MIN - 1; i >= 0; i--) - { - joybuttons <<= 1; - if (js.rgbButtons[i]) - joybuttons |= 1; - } - - for (i = JOYHATS_MIN -1; i >=0; i--) - { - if (js.rgdwPOV[i] != 0xffff && js.rgdwPOV[i] != 0xffffffff) - { - if (js.rgdwPOV[i] > 270 * DI_DEGREES || js.rgdwPOV[i] < 90 * DI_DEGREES) - joyhats |= 1<<(0 + 4*i); // UP - else if (js.rgdwPOV[i] > 90 * DI_DEGREES && js.rgdwPOV[i] < 270 * DI_DEGREES) - joyhats |= 1<<(1 + 4*i); // DOWN - if (js.rgdwPOV[i] > 0 * DI_DEGREES && js.rgdwPOV[i] < 180 * DI_DEGREES) - joyhats |= 1<<(3 + 4*i); // LEFT - else if (js.rgdwPOV[i] > 180 * DI_DEGREES && js.rgdwPOV[i] < 360 * DI_DEGREES) - joyhats |= 1<<(2 + 4*i); // RIGHT - } - } - - if (joybuttons != lastjoy2buttons) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newbuttons = joybuttons ^ lastjoy2buttons; - lastjoy2buttons = joybuttons; - - for (i = 0; i < JOYBUTTONS && i < JOYBUTTONS_MAX; i++, j <<= 1) - { - if (newbuttons & j) // button changed state? - { - if (joybuttons & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2JOY1 + i; - D_PostEvent(&event); - } - } - } - - if (joyhats != lastjoy2hats) - { - INT64 j = 1; // keep only bits that changed since last time - INT64 newhats = joyhats ^ lastjoy2hats; - lastjoy2hats = joyhats; - - for (i = 0; i < JOYHATS*4 && i < JOYHATS_MAX*4; i++, j <<= 1) - { - if (newhats & j) // button changed state? - { - if (joyhats & j) - event.type = ev_keydown; - else - event.type = ev_keyup; - event.data1 = KEY_2HAT1 + i; - D_PostEvent(&event); - } - } - - } - - // send joystick axis positions - event.type = ev_joystick2; - event.data1 = event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.X) - { - if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Y) - { - if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.X) event.data2 = js.lX; // x axis - if (JoyInfo2.Y) event.data3 = js.lY; // y axis - } - - D_PostEvent(&event); -#if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.Z) - { - if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Rx) - { - if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.Z) event.data2 = js.lZ; // z axis - if (JoyInfo2.Rx) event.data3 = js.lRx; // rx axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; - - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.Rx) - { - if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.Rz) - { - if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo2.Rz) event.data3 = js.lRz; // rz axis - } - - D_PostEvent(&event); -#endif -#if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; - if (Joystick2.bGamepadStyle) - { - // gamepad control type, on or off, live or die - if (JoyInfo2.U) - { - if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; - else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; - } - if (JoyInfo2.V) - { - if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; - else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; - } - } - else - { - // analog control style, just send the raw data - if (JoyInfo2.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo2.V) event.data3 = js.rglSlider[1]; // V axis - } - D_PostEvent(&event); -#endif -} - -static int numofjoy = 0; -static char joyname[MAX_PATH]; -static int needjoy = -1; - -static BOOL CALLBACK DIEnumJoysticksCount (LPCDIDEVICEINSTANCE lpddi, - LPVOID pvRef) //joyname -{ - numofjoy++; - if (needjoy == numofjoy && pvRef && pvRef == (void *)joyname && lpddi - && lpddi->tszProductName) - { - sprintf(joyname,"%s",lpddi->tszProductName); - return DIENUM_STOP; - } - //else if (devparm) CONS_Printf("DIEnumJoysticksCount need help!"); - return DIENUM_CONTINUE; -} - -INT32 I_NumJoys(void) -{ - HRESULT hr; - needjoy = -1; - numofjoy = 0; - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticksCount, (void *)&numofjoy, DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - CONS_Printf("\nI_NumJoys(): EnumDevices FAILED\n"); - return numofjoy; - -} - -const char *I_GetJoyName(INT32 joyindex) -{ - HRESULT hr; - needjoy = joyindex; - numofjoy = 0; - ZeroMemory(joyname,sizeof (joyname)); - hr = IDirectInput_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, - DIEnumJoysticksCount, (void *)joyname, DIEDFL_ATTACHEDONLY); - if (FAILED(hr)) - CONS_Printf("\nI_GetJoyName(): EnumDevices FAILED\n"); - if (joyname[0] == 0) return NULL; - return joyname; -} - -// =========================================================================================== -// DIRECT INPUT KEYBOARD -// =========================================================================================== - -static UINT8 ASCIINames[256] = -{ - // 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_MINUS,KEY_EQUALS,KEY_BACKSPACE, KEY_TAB, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', KEY_ENTER,KEY_CTRL,'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', KEY_SHIFT, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', KEY_SHIFT, '*', - KEY_ALT,KEY_SPACE,KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, - KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,KEY_NUMLOCK,KEY_SCROLLLOCK,KEY_KEYPAD7, - KEY_KEYPAD8,KEY_KEYPAD9,KEY_MINUSPAD,KEY_KEYPAD4,KEY_KEYPAD5,KEY_KEYPAD6,KEY_PLUSPAD,KEY_KEYPAD1, - KEY_KEYPAD2,KEY_KEYPAD3,KEY_KEYPAD0,KEY_KPADDEL,0,0,0, KEY_F11, - KEY_F12,0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - - 0, 0, 0, 0, 0, 0, 0, 0, // 0x80 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, KEY_ENTER,KEY_CTRL, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, KEY_KPADDEL, 0,KEY_KPADSLASH,0, 0, - KEY_ALT,0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, KEY_HOME, // 0xc0 - KEY_UPARROW,KEY_PGUP,0,KEY_LEFTARROW,0,KEY_RIGHTARROW,0,KEY_END, - KEY_DOWNARROW,KEY_PGDN, KEY_INS,KEY_DEL,0,0,0,0, - 0, 0, 0,KEY_LEFTWIN,KEY_RIGHTWIN,KEY_MENU, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -// Return a key that has been pushed, or 0 (replace getchar() at game startup) -// -INT32 I_GetKey(void) -{ - event_t *ev; - - if (eventtail != eventhead) - { - ev = &events[eventtail]; - eventtail = (eventtail+1) & (MAXEVENTS-1); - if (ev->type == ev_keydown || ev->type == ev_console) - return ev->data1; - else - return 0; - } - return 0; -} - -// ----------------- -// I_StartupKeyboard -// Installs DirectInput keyboard -// ----------------- -#define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer - -void I_StartupKeyboard(void) -{ - DIPROPDWORD dip; - - if (dedicated) - return; - - // make sure the app window has the focus or DirectInput acquire keyboard won't work - if (hWndMain) - { - SetFocus(hWndMain); - ShowWindow(hWndMain, SW_SHOW); - UpdateWindow(hWndMain); - } - - // detect error - if (lpDIK) - { - CONS_Printf("\2I_StartupKeyboard(): called twice\n"); - return; - } - - CreateDevice2(lpDI, &GUID_SysKeyboard, &lpDIK, NULL); - - if (lpDIK) - { - if (FAILED(IDirectInputDevice_SetDataFormat(lpDIK, &c_dfDIKeyboard))) - I_Error("Couldn't set keyboard data format"); - - // create buffer for buffered data - dip.diph.dwSize = sizeof (dip); - dip.diph.dwHeaderSize = sizeof (dip.diph); - dip.diph.dwObj = 0; - dip.diph.dwHow = DIPH_DEVICE; - dip.dwData = DI_KEYBOARD_BUFFERSIZE; - if (FAILED(IDirectInputDevice_SetProperty(lpDIK, DIPROP_BUFFERSIZE, &dip.diph))) - I_Error("Couldn't set keyboard buffer size"); - - if (FAILED(IDirectInputDevice_SetCooperativeLevel(lpDIK, hWndMain, - DISCL_NONEXCLUSIVE|DISCL_FOREGROUND))) - { - I_Error("Couldn't set keyboard coop level"); - } - } - else - I_Error("Couldn't create keyboard input"); - - I_AddExitFunc(I_ShutdownKeyboard); - hacktics = 0; // see definition - keyboard_started = true; -} - -// ------------------ -// I_ShutdownKeyboard -// Release DirectInput keyboard. -// ------------------ -static void I_ShutdownKeyboard(void) -{ - if (!keyboard_started) - return; - - CONS_Printf("I_ShutdownKeyboard()\n"); - - if (lpDIK) - { - IDirectInputDevice_Unacquire(lpDIK); - IDirectInputDevice_Release(lpDIK); - lpDIK = NULL; - } - - keyboard_started = false; -} - -// ------------------- -// I_GetKeyboardEvents -// Get buffered data from the keyboard -// ------------------- -static void I_GetKeyboardEvents(void) -{ - static boolean KeyboardLost = false; - - // simply repeat the last pushed key every xx tics, - // make more user friendly input for Console and game Menus -#define KEY_REPEAT_DELAY (TICRATE/17) // TICRATE tics, repeat every 1/3 second - static long RepeatKeyTics = 0; - static int RepeatKeyCode; - - DIDEVICEOBJECTDATA rgdod[DI_KEYBOARD_BUFFERSIZE]; - DWORD dwItems, d; - HRESULT hr; - int ch; - - event_t event; - ZeroMemory(&event,sizeof (event)); - - if (!keyboard_started) - return; - - if (!appActive && RepeatKeyCode) // Stop when lost focus - { - event.type = ev_keyup; - event.data1 = RepeatKeyCode; - D_PostEvent(&event); - RepeatKeyCode = 0; - } -getBufferedData: - dwItems = DI_KEYBOARD_BUFFERSIZE; - hr = IDirectInputDevice_GetDeviceData(lpDIK, sizeof (DIDEVICEOBJECTDATA), rgdod, &dwItems, 0); - - // If data stream was interrupted, reacquire the device and try again. - if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED) - { - // why it succeeds to acquire just after I don't understand.. so I set the flag BEFORE - KeyboardLost = true; - - hr = IDirectInputDevice_Acquire(lpDIK); - if (SUCCEEDED(hr)) - goto getBufferedData; - return; - } - - // we lost data, get device actual state to recover lost information - if (hr == DI_BUFFEROVERFLOW) - { - /// \note either uncomment or delete block - //I_Error("DI buffer overflow (keyboard)"); - //I_RecoverKeyboardState (); - - //hr = IDirectInputDevice_GetDeviceState (lpDIM, sizeof (keys), &diMouseState); - } - - // We got buffered input, act on it - if (SUCCEEDED(hr)) - { - // if we previously lost keyboard data, recover its current state - if (KeyboardLost) - { - /// \bug hack simply clears the keys so we don't have the last pressed keys - /// still active.. to have to re-trigger it is not much trouble for the user. - ZeroMemory(gamekeydown, NUMKEYS); - KeyboardLost = false; - } - - // dwItems contains number of elements read (could be 0) - for (d = 0; d < dwItems; d++) - { - // dwOfs member is DIK_* value - // dwData member 0x80 bit set press down, clear is release - - if (rgdod[d].dwData & 0x80) - event.type = ev_keydown; - else - event.type = ev_keyup; - - ch = rgdod[d].dwOfs & UINT8_MAX; - if (ASCIINames[ch]) - event.data1 = ASCIINames[ch]; - else - event.data1 = 0x80; - - D_PostEvent(&event); - } - - // Key Repeat - if (dwItems) - { - // new key events, so stop repeating key - RepeatKeyCode = 0; - // delay is tripled for first repeating key - RepeatKeyTics = hacktics + (KEY_REPEAT_DELAY*2); - if (event.type == ev_keydown) // use the last event! - RepeatKeyCode = event.data1; - } - else - { - // no new keys, repeat last pushed key after some time - if (RepeatKeyCode && hacktics - RepeatKeyTics > KEY_REPEAT_DELAY) - { - event.type = ev_keydown; - event.data1 = RepeatKeyCode; - D_PostEvent(&event); - - RepeatKeyTics = hacktics; - } - } - } -} - -// -// Closes DirectInput -// -static void I_ShutdownDirectInput(void) -{ - if (lpDI) - IDirectInput_Release(lpDI); - lpDI = NULL; -} - -// This stuff should get rid of the exception and page faults when -// SRB2 bugs out with an error. Now it should exit cleanly. -// -INT32 I_StartupSystem(void) -{ - HRESULT hr; - - // some 'more global than globals' things to initialize here ? - graphics_started = keyboard_started = sound_started = cdaudio_started = false; - - I_DetectWin9x(); - - // check for OS type and version here? -#ifdef NDEBUG - signal(SIGABRT, signal_handler); - signal(SIGFPE, signal_handler); - signal(SIGILL, signal_handler); - signal(SIGSEGV, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); -#endif - - // create DirectInput - so that I_StartupKeyboard/Mouse can be called later on - // from D_SRB2Main just like DOS version - hr = DirectInputCreate(myInstance, DIRECTINPUT_VERSION, &lpDI, NULL); - - if (SUCCEEDED(hr)) - bDX0300 = FALSE; - else - { - // try opening DirectX3 interface for NT compatibility - hr = DirectInputCreate(myInstance, DXVERSION_NTCOMPATIBLE, &lpDI, NULL); - - if (FAILED(hr)) - { - const char *sErr; - switch (hr) - { - case DIERR_BETADIRECTINPUTVERSION: - sErr = "DIERR_BETADIRECTINPUTVERSION"; - break; - case DIERR_INVALIDPARAM: - sErr = "DIERR_INVALIDPARAM"; - break; - case DIERR_OLDDIRECTINPUTVERSION : - sErr = "DIERR_OLDDIRECTINPUTVERSION"; - break; - case DIERR_OUTOFMEMORY: - sErr = "DIERR_OUTOFMEMORY"; - break; - default: - sErr = "UNKNOWN"; - break; - } - I_Error("Couldn't create DirectInput (reason: %s)", sErr); - } - else - CONS_Printf("\2Using DirectX3 interface\n"); - - // only use DirectInput3 compatible structures and calls - bDX0300 = TRUE; - } - I_AddExitFunc(I_ShutdownDirectInput); - return 0; -} - -// Closes down everything. This includes restoring the initial -// palette and video mode, and removing whatever mouse, keyboard, and -// timer routines have been installed. -// -/// \bug doesn't restore wave/midi device volume -// -// Shutdown user funcs are effectively called in reverse order. -// -void I_ShutdownSystem(void) -{ - int c; - - for (c = MAX_QUIT_FUNCS - 1; c >= 0; c--) - if (quit_funcs[c]) - (*quit_funcs[c])(); -} - -// --------------- -// I_SaveMemToFile -// Save as much as iLength bytes starting at pData, to -// a new file of given name. The file is overwritten if it is present. -// --------------- -BOOL I_SaveMemToFile(const void *pData, size_t iLength, const char *sFileName) -{ - HANDLE fileHandle; - DWORD bytesWritten; - - fileHandle = CreateFileA(sFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, NULL); - if (fileHandle == (HANDLE)-1) - { - CONS_Printf("SaveMemToFile: Error opening file %s",sFileName); - return FALSE; - } - WriteFile(fileHandle, pData, (DWORD)iLength, &bytesWritten, NULL); - CloseHandle(fileHandle); - return TRUE; -} - -// my god how win32 suck -typedef BOOL (WINAPI *MyFunc)(LPCSTR RootName, PULARGE_INTEGER pulA, PULARGE_INTEGER pulB, PULARGE_INTEGER pulFreeBytes); - -void I_GetDiskFreeSpace(INT64* freespace) -{ - static MyFunc pfnGetDiskFreeSpaceEx = NULL; - static boolean testwin95 = false; - ULARGE_INTEGER usedbytes, lfrespace; - - if (!testwin95) - { - HMODULE h = GetModuleHandleA("kernel32.dll"); - - if (h) - pfnGetDiskFreeSpaceEx = (MyFunc)GetProcAddress(h, "GetDiskFreeSpaceExA"); - testwin95 = true; - } - if (pfnGetDiskFreeSpaceEx) - { - if (pfnGetDiskFreeSpaceEx(NULL, &lfreespace, &usedbytes, NULL)) - *freespace = lfreespace.QuadPart; - else - *freespace = INT32_MAX; - } - else - { - DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; - GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, - &NumberOfFreeClusters, &TotalNumberOfClusters); - *freespace = BytesPerSector * SectorsPerCluster * NumberOfFreeClusters; - } -} - -char *I_GetUserName(void) -{ - static char username[MAXPLAYERNAME+1]; - char *p; - DWORD i = MAXPLAYERNAME; - - if (!GetUserNameA(username, &i)) - { - p = getenv("USER"); - if (!p) - { - p = getenv("user"); - if (!p) - { - p = getenv("USERNAME"); - if (!p) - { - p = getenv("username"); - if (!p) - { - return NULL; - } - } - } - } - strncpy(username, p, MAXPLAYERNAME); - } - - if (!strlen(username)) - return NULL; - return username; -} - -INT32 I_mkdir(const char *dirname, INT32 unixright) -{ - (void)unixright; /// \todo should implement ntright under nt... - return CreateDirectoryA(dirname, NULL); -} - -char * I_GetEnv(const char *name) -{ - return getenv(name); -} - -INT32 I_PutEnv(char *variable) -{ - return putenv(variable); -} - -INT32 I_ClipboardCopy(const char *data, size_t size) -{ - (void)data; - (void)size; - return -1; -} - -char *I_ClipboardPaste(void) -{ - return NULL; -} - -typedef BOOL (WINAPI *MyFunc3) (DWORD); - -const CPUInfoFlags *I_CPUInfo(void) -{ - static CPUInfoFlags WIN_CPUInfo; - static MyFunc3 pfnCPUID = NULL; - SYSTEM_INFO SI; - HMODULE h = GetModuleHandleA("kernel32.dll"); - - if (h) - pfnCPUID = (MyFunc3)GetProcAddress(h, "IsProcessorFeaturePresent"); - ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); - if(pfnCPUID) - { - WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA - WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED - WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE - WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK - WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS - WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE - WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED - WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE - //WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE - WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED - WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128 - WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128 - WIN_CPUInfo.PFC = pfnCPUID(15); //PF_CHANNELS_ENABLED - } - GetSystemInfo(&SI); - WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors; - WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64 - WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664 - return &WIN_CPUInfo; -} - -UINT64 I_FileSize(const char *filename) -{ - HANDLE fileHandle; - DWORD dwSizeHigh, dwSizeLow; - UINT64 fileSize = (UINT64)-1; - - fileHandle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - 0, NULL); - if (fileHandle == (HANDLE)-1) - goto erroropening; - dwSizeLow = GetFileSize(fileHandle,&dwSizeHigh); - if (dwSizeLow == 0xFFFFFFFF && GetLastError() != NO_ERROR) - goto errorsizing; - fileSize = ((UINT64)(dwSizeHigh)<<32) + dwSizeLow; -errorsizing: - CloseHandle(fileHandle); -erroropening: - return fileSize; -} diff --git a/src/win32ce/win_vid.c b/src/win32ce/win_vid.c deleted file mode 100644 index 4724ca40d..000000000 --- a/src/win32ce/win_vid.c +++ /dev/null @@ -1,865 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief win32 video driver for Doom Legacy - -#include "../doomdef.h" - -#include -#include - -#include "../d_clisrv.h" -#include "../i_system.h" -#include "../m_argv.h" -#include "../v_video.h" -#include "../st_stuff.h" -#include "../i_video.h" -#include "../z_zone.h" -#include "fabdxlib.h" - -#include "win_main.h" -#include "../command.h" -#include "../screen.h" - -#ifdef HWRENDER -#include "win_dll.h" // loading the render DLL -#include "../hardware/hw_drv.h" // calling driver init & shutdown -#include "../hardware/hw_main.h" // calling HWR module init & shutdown -#endif - -// ------- -// Globals -// ------- - -// this is the CURRENT rendermode!! very important: used by w_wad, and much other code -rendermode_t rendermode = render_soft; - -// synchronize page flipping with screen refresh -consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -boolean highcolor; - -static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces -static BITMAPINFO* bmiMain = NULL; -static HDC hDCMain = NULL; - -// ----------------- -// Video modes stuff -// ----------------- - -#define MAX_EXTRA_MODES 36 -static vmode_t extra_modes[MAX_EXTRA_MODES] = {{NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0}}; -static char names[MAX_EXTRA_MODES][10]; - -static int numvidmodes; // total number of DirectDraw display modes -static vmode_t *pvidmodes; // start of videomodes list. -static vmode_t *pcurrentmode; // the current active videomode. -static BOOL bWinParm; -static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode); - -// this holds description of the startup video mode, -// the resolution is 320x200, windowed on the desktop -#define NUMSPECIALMODES 1 -static char winmode1[] ="320x200W"; // W to make sure it's the windowed mode -static vmode_t specialmodes[NUMSPECIALMODES] = -{ - { - NULL, - winmode1, // hehe - 320, 200, //(200.0/320.0)*(320.0/240.0), - 320, 1, // rowbytes, bytes per pixel - 1, 2, // windowed (TRUE), numpages - NULL, - VID_SetWindowedDisplayMode, 0 - } -}; - -// ------ -// Protos -// ------ -static void VID_Command_NumModes_f(void); -static void VID_Command_ModeInfo_f(void); -static void VID_Command_ModeList_f(void); -static void VID_Command_Mode_f(void); -static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode); -static vmode_t *VID_GetModePtr(int modenum); -static void VID_Init(void); -static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid); - -// ----------------- -// I_StartupGraphics -// Initialize video mode, setup dynamic screen size variables, -// and allocate screens. -// ----------------- -void I_StartupGraphics(void) -{ - if (graphics_started) - return; - -#ifdef HWRENDER - if (M_CheckParm("-opengl")) - rendermode = render_opengl; - else - rendermode = render_soft; -#endif - - if (dedicated) - rendermode = render_none; - else - VID_Init(); - - // register exit code for graphics - I_AddExitFunc(I_ShutdownGraphics); - if (!dedicated) graphics_started = true; -} - -// ------------------ -// I_ShutdownGraphics -// Close the screen, restore previous video mode. -// ------------------ -void I_ShutdownGraphics(void) -{ - if (!graphics_started) - return; - - CONS_Printf("I_ShutdownGraphics()\n"); - - //FreeConsole(); - - // release windowed startup stuff - if (hDCMain) - { - ReleaseDC(hWndMain, hDCMain); - hDCMain = NULL; - } - if (bmiMain) - { - GlobalFree(bmiMain); - bmiMain = NULL; - } - -#ifdef HWRENDER - if (rendermode != render_soft) - { - HWR_Shutdown(); // free stuff from the hardware renderer - HWD.pfnShutdown(); // close 3d card display - Shutdown3DDriver(); // free the driver DLL - } -#endif - - // free the last video mode screen buffers - if (vid.buffer) - { - GlobalFree(vid.buffer); - vid.buffer = NULL; - } - -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - CloseDirectDraw(); - - graphics_started = false; -} - -// -------------- -// I_UpdateNoBlit -// -------------- -void I_UpdateNoBlit(void) -{ - // what is this? -} - -// -------------- -// I_FinishUpdate -// -------------- -void I_FinishUpdate(void) -{ - int i; - - if (rendermode == render_none) - return; - - // draw captions if enabled - if (cv_closedcaptioning.value) - SCR_ClosedCaptions(); - - // display a graph of ticrate - if (cv_ticrate.value) - SCR_DisplayTicRate(); - - // - if (bDIBMode) - { - // paranoia - if (!hDCMain || !bmiMain || !vid.buffer) - return; - // main game loop, still in a window (-win parm) - SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain, - DIB_RGB_COLORS); - } - else -#ifdef HWRENDER - if (rendermode != render_soft) - HWD.pfnFinishUpdate(cv_vidwait.value); - else -#endif - { - // DIRECT DRAW - // copy virtual screen to real screen - // can fail when not active (alt-tab) - if (LockScreen()) - { - /// \todo use directX blit here!!? a blit might use hardware with access - /// to main memory on recent hardware, and software blit of directX may be - /// optimized for p2 or mmx?? - VID_BlitLinearScreen(screens[0], ScreenPtr, vid.width*vid.bpp, vid.height, - vid.width*vid.bpp, ScreenPitch); - - UnlockScreen(); - - // swap screens - ScreenFlip(cv_vidwait.value); - } - } -} - -// -// This is meant to be called only by CONS_Printf() while game startup -// -void I_LoadingScreen(LPCSTR msg) -{ - RECT rect; - - // paranoia - if (!hDCMain || !bmiMain || !vid.buffer) - return; - - GetClientRect(vid.WndParent, &rect); - - SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain, DIB_RGB_COLORS); - - if (msg) - { - if (rect.bottom - rect.top > 32) - rect.top = rect.bottom - 32; // put msg on bottom of window - SetBkMode(hDCMain, TRANSPARENT); - SetTextColor(hDCMain, RGB(0x00, 0x00, 0x00)); - DrawTextA(hDCMain, msg, -1, &rect, DT_WORDBREAK|DT_CENTER); - } -} - -// ------------ -// I_ReadScreen -// ------------ -void I_ReadScreen(UINT8 *scr) -{ - // DEBUGGING - if (rendermode != render_soft) - I_Error("I_ReadScreen: called while in non-software mode"); - VID_BlitLinearScreen(screens[0], scr, vid.width*vid.bpp, vid.height, vid.width*vid.bpp, - vid.rowbytes); -} - -// ------------ -// I_SetPalette -// ------------ -void I_SetPalette(RGBA_t *palette) -{ - int i; - - if (bDIBMode) - { - // set palette in RGBQUAD format, NOT THE SAME ORDER as PALETTEENTRY, grmpf! - RGBQUAD *pColors; - pColors = (RGBQUAD *)((char *)bmiMain + bmiMain->bmiHeader.biSize); - ZeroMemory(pColors, sizeof (RGBQUAD)*256); - for (i = 0; i < 256; i++, pColors++, palette++) - { - pColors->rgbRed = palette->s.red; - pColors->rgbGreen = palette->s.green; - pColors->rgbBlue = palette->s.blue; - } - } - else -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - { - PALETTEENTRY mainpal[256]; - - // this clears the 'flag' for each color in palette - ZeroMemory(mainpal, sizeof mainpal); - - // set palette in PALETTEENTRY format - for (i = 0; i < 256; i++, palette++) - { - mainpal[i].peRed = palette->s.red; - mainpal[i].peGreen = palette->s.green; - mainpal[i].peBlue = palette->s.blue; - } - SetDDPalette(mainpal); // set DirectDraw palette - } -} - -// -// return number of video modes in pvidmodes list -// -INT32 VID_NumModes(void) -{ - return numvidmodes - NUMSPECIALMODES; //faB: dont accept the windowed mode 0 -} - -// return a video mode number from the dimensions -// returns any available video mode if the mode was not found -INT32 VID_GetModeForSize(INT32 w, INT32 h) -{ - vmode_t *pv = pvidmodes; - int modenum = 0; - - // skip the special modes so that it finds only fullscreen modes - for (; pv && modenum < NUMSPECIALMODES; pv = pv->pnext, ++modenum); - for (; pv; pv = pv->pnext, ++modenum) - if (pv->width == (unsigned)w && pv->height == (unsigned)h) - return modenum; - - // if not found, return the first mode available, - // preferably a full screen mode (all modes after the 'specialmodes') - if (numvidmodes > NUMSPECIALMODES) - return NUMSPECIALMODES; // use first full screen mode - - return 0; // no fullscreen mode, use windowed mode -} - -// -// Enumerate DirectDraw modes available -// -static int nummodes = 0; -static BOOL GetExtraModesCallback(int width, int height, int bpp) -{ - CONS_Printf("mode %d x %d x %d bpp\n", width, height, bpp); - - // skip all unwanted modes - if (highcolor && bpp != 15) - goto skip; - if (!highcolor && bpp != 8) - goto skip; - - if (bpp > 16 || width > MAXVIDWIDTH || height > MAXVIDHEIGHT) - goto skip; - - // check if we have space for this mode - if (nummodes >= MAX_EXTRA_MODES) - { - CONS_Printf("mode skipped (too many)\n"); - return FALSE; - } - - // store mode info - extra_modes[nummodes].pnext = &extra_modes[nummodes+1]; - memset(names[nummodes], 0, 10); - snprintf(names[nummodes], 9, "%dx%d", width, height); - - extra_modes[nummodes].name = names[nummodes]; - extra_modes[nummodes].width = width; - extra_modes[nummodes].height = height; - - // exactly, the current FinishUdpate() gets the rowbytes itself after locking the video buffer - // so for now we put anything here - extra_modes[nummodes].rowbytes = width; - extra_modes[nummodes].windowed = false; - extra_modes[nummodes].misc = 0; // unused - extra_modes[nummodes].pextradata = NULL; - extra_modes[nummodes].setmode = VID_SetDirectDrawMode; - - extra_modes[nummodes].numpages = 2; // double-buffer (but this value is unused) - - extra_modes[nummodes].bytesperpixel = (bpp+1)>>3; - - nummodes++; -skip: - return TRUE; -} - -// -// Collect info about DirectDraw display modes we use -// -static inline void VID_GetExtraModes(void) -{ - nummodes = 0; - EnumDirectDrawDisplayModes(GetExtraModesCallback); - - // add the extra modes (not 320x200) at the start of the mode list (if there are any) - if (nummodes) - { - extra_modes[nummodes-1].pnext = NULL; - pvidmodes = &extra_modes[0]; - numvidmodes += nummodes; - } -} - -// --------------- -// WindowMode_Init -// Add windowed modes to the start of the list, -// mode 0 is used for windowed console startup (works on all computers with no DirectX) -// --------------- -static void WindowMode_Init(void) -{ - specialmodes[NUMSPECIALMODES-1].pnext = pvidmodes; - pvidmodes = &specialmodes[0]; - numvidmodes += NUMSPECIALMODES; -} - -// ************************************************************************************* -// VID_Init -// Initialize Video modes subsystem -// ************************************************************************************* -static void VID_Init(void) -{ - vmode_t *pv; - int iMode; - - // if '-win' is specified on the command line, do not add DirectDraw modes - bWinParm = M_CheckParm("-win"); - - COM_AddCommand("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand("vid_modeinfo", VID_Command_ModeInfo_f); - COM_AddCommand("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand("vid_mode", VID_Command_Mode_f); - - CV_RegisterVar(&cv_vidwait); - CV_RegisterVar(&cv_stretch); - - // setup the videmodes list, - // note that mode 0 must always be VGA mode 0x13 - pvidmodes = pcurrentmode = NULL; - numvidmodes = 0; - - // store the main window handle in viddef struct - SetWindowPos(hWndMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_NOMOVE); - vid.WndParent = hWndMain; - vid.buffer = NULL; - - // we startup in windowed mode using DIB bitmap - // we will use DirectDraw when switching fullScreen and entering main game loop - bDIBMode = TRUE; - bAppFullScreen = FALSE; - -#ifdef HWRENDER - // initialize the appropriate display device - if (rendermode != render_soft) - { - const char *drvname = NULL; - - switch (rendermode) - { - case render_opengl: - drvname = "r_opengl.dll"; - break; - default: - I_Error("Unknown hardware render mode"); - } - - // load the DLL - if (drvname && Init3DDriver(drvname)) - { - int hwdversion = HWD.pfnGetRenderVersion(); - if (hwdversion != VERSION) - CONS_Printf("WARNING: This r_opengl version is not supported, use it at your own risk.\n"); - - // perform initialisations - HWD.pfnInit(I_Error); - // get available display modes for the device - HWD.pfnGetModeList(&pvidmodes, &numvidmodes); - } - else - { - switch (rendermode) - { - case render_opengl: - I_Error("Error initializing OpenGL"); - default: - break; - } - rendermode = render_soft; - } - } - - if (rendermode == render_soft) -#endif - if (!bWinParm) - { - if (!CreateDirectDrawInstance()) - I_Error("Error initializing DirectDraw"); - // get available display modes for the device - VID_GetExtraModes(); - } - - // the game boots in 320x200 standard VGA, but - // we need a highcolor mode to run the game in highcolor - if (highcolor && !numvidmodes) - I_Error("Cannot run in highcolor - No 15bit highcolor DirectX video mode found."); - - // add windowed mode at the start of the list, very important! - WindowMode_Init(); - - if (!numvidmodes) - I_Error("No display modes available."); - - // DEBUG - for (iMode = 0, pv = pvidmodes; pv; pv = pv->pnext, iMode++) - CONS_Printf("#%02d: %dx%dx%dbpp (desc: '%s')\n", iMode, pv->width, pv->height, - pv->bytesperpixel, pv->name); - - // set the startup screen in a window - VID_SetMode(0); -} - -// -------------------------- -// VID_SetWindowedDisplayMode -// Display the startup 320x200 console screen into a window on the desktop, -// switching to fullscreen display only when we will enter the main game loop. -// - we can display error message boxes for startup errors -// - we can set the last used resolution only once, when entering the main game loop -// -------------------------- -static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode) -{ - int iScrWidth, iScrHeight, iWinWidth, iWinHeight; - - pcurrentmode = NULL; -#ifdef DEBUG - CONS_Printf("VID_SetWindowedDisplayMode()\n"); -#endif - - lvid->u.numpages = 1; // not used - lvid->direct = NULL; // DOS remains - lvid->buffer = NULL; - - // allocate screens - if (!VID_FreeAndAllocVidbuffer(lvid)) - return -1; - - // lvid->buffer should be NULL here! - - bmiMain = (void *)GlobalAlloc(GPTR, sizeof (BITMAPINFO) + (sizeof (RGBQUAD)*256)); - if (!bmiMain) - I_Error("VID_SWDM(): No mem"); - - // setup a BITMAPINFO to allow copying our video buffer to the desktop, - // with color conversion as needed - bmiMain->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); - bmiMain->bmiHeader.biWidth = lvid->width; - bmiMain->bmiHeader.biHeight= -(lvid->height); - bmiMain->bmiHeader.biPlanes = 1; - bmiMain->bmiHeader.biBitCount = 8; - bmiMain->bmiHeader.biCompression = BI_RGB; - - // center window on the desktop - iScrWidth = GetSystemMetrics(SM_CXFULLSCREEN); - iScrHeight = GetSystemMetrics(SM_CYFULLSCREEN); - - iWinWidth = lvid->width; - iWinWidth += GetSystemMetrics(SM_CXFIXEDFRAME) * 2; - - iWinHeight = lvid->height; - iWinHeight += GetSystemMetrics(SM_CYCAPTION); - iWinHeight += GetSystemMetrics(SM_CYFIXEDFRAME) * 2; - - if (devparm) - MoveWindow(hWndMain, (iScrWidth - iWinWidth), (iScrHeight - iWinHeight), iWinWidth, iWinHeight, TRUE); - else - MoveWindow(hWndMain, (iScrWidth - iWinWidth)>>1, (iScrHeight - iWinHeight)>>1, iWinWidth, iWinHeight, TRUE); - - SetFocus(hWndMain); - ShowWindow(hWndMain, SW_SHOW); - - hDCMain = GetDC(hWndMain); - if (!hDCMain) - I_Error("VID_SWDM(): GetDC FAILED"); - - return 1; -} - -// ======================================================================== -// Returns a vmode_t from the video modes list, given a video mode number. -// ======================================================================== -vmode_t *VID_GetModePtr(int modenum) -{ - vmode_t *pv; - - pv = pvidmodes; - if (!pv) - I_Error("VID_error: No video mode found\n"); - - while (modenum--) - { - pv = pv->pnext; - if (!pv) - I_Error("VID_error: Mode not available\n"); - } - return pv; -} - -// -// return the name of a video mode -// -const char *VID_GetModeName(INT32 modenum) -{ - return (VID_GetModePtr(modenum))->name; -} - -// ======================================================================== -// Sets a video mode -// ======================================================================== -INT32 VID_SetMode(INT32 modenum) -{ - int stat; - vmode_t *pnewmode; - vmode_t *poldmode; - - if (dedicated) - return 0; - - CONS_Printf("VID_SetMode(%d)\n", modenum); - - // if mode 0 (windowed) we must not be fullscreen already, - // if other mode, check it is not mode 0 and existing - if (modenum >= numvidmodes) - { - if (!pcurrentmode) - modenum = 0; // revert to the default base vid mode - else - I_Error("Unknown video mode: %d\n", modenum); - } - else if (bAppFullScreen && modenum < NUMSPECIALMODES) - I_Error("Tried to switch from fullscreen back to windowed mode %d\n", modenum); - - pnewmode = VID_GetModePtr(modenum); - - // dont switch to the same display mode - if (pnewmode == pcurrentmode) - return 1; - - // initialize the new mode - poldmode = pcurrentmode; - pcurrentmode = pnewmode; - - // initialize vidbuffer size for setmode - vid.width = pcurrentmode->width; - vid.height = pcurrentmode->height; - vid.rowbytes = pcurrentmode->rowbytes; - vid.bpp = pcurrentmode->bytesperpixel; - if (modenum) // if not 320x200 windowed mode, it's actually a hack - { - if (rendermode == render_opengl) - { - // don't accept depth < 16 for OpenGL mode (too much ugly) - if (cv_scr_depth.value < 16) - CV_SetValue(&cv_scr_depth, 16); - vid.bpp = cv_scr_depth.value/8; - vid.u.windowed = (bWinParm || !cv_fullscreen.value); - pcurrentmode->bytesperpixel = vid.bpp; - pcurrentmode->windowed = vid.u.windowed; - } - } - - stat = (*pcurrentmode->setmode)(&vid, pcurrentmode); - - if (stat == -1) - I_Error("Not enough mem for VID_SetMode\n"); - else if (stat == -2) - I_Error("Couldn't set video mode because it failed the test\n"); - else if (stat == -3) - I_Error("Couldn't set video mode because it failed the change?\n"); - else if (!stat) - I_Error("Couldn't set video mode %d (%dx%d %d bits)\n", modenum, vid.width, vid.height, (vid.bpp*8));// hardware could not setup mode - else - CONS_Printf(M_GetText("Mode changed to %d (%s)\n"), modenum, pcurrentmode->name); - - vid.modenum = modenum; - - // tell game engine to recalc all tables and realloc buffers based on new values - vid.recalc = 1; - - if (modenum < NUMSPECIALMODES) - { - // we are in startup windowed mode - bAppFullScreen = FALSE; - bDIBMode = TRUE; - } - else - { - // we switch to fullscreen - bAppFullScreen = TRUE; - bDIBMode = FALSE; -#ifdef HWRENDER - if (rendermode != render_soft) - { - // purge all patch graphics stored in software format - //Z_FreeTags (PU_PURGELEVEL, PU_PURGELEVEL+100); - HWR_Startup(); - } -#endif - } - - I_RestartSysMouse(); - return 1; -} - -// ======================================================================== -// Free the video buffer of the last video mode, -// allocate a new buffer for the video mode to set. -// ======================================================================== -static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid) -{ - const DWORD vidbuffersize = (lvid->width * lvid->height * lvid->bpp * NUMSCREENS); - - // free allocated buffer for previous video mode - if (lvid->buffer) - GlobalFree(lvid->buffer); - - // allocate & clear the new screen buffer - lvid->buffer = GlobalAlloc(GPTR, vidbuffersize); - if (!lvid->buffer) - return FALSE; - - ZeroMemory(lvid->buffer, vidbuffersize); -#ifdef DEBUG - CONS_Printf("VID_FreeAndAllocVidbuffer done, vidbuffersize: %x\n",vidbuffersize); -#endif - return TRUE; -} - -// ======================================================================== -// Set video mode routine for DirectDraw display modes -// Out: 1 ok, -// 0 hardware could not set mode, -// -1 no mem -// ======================================================================== -static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode) -{ - pcurrentmode = NULL; -#ifdef DEBUG - CONS_Printf("VID_SetDirectDrawMode...\n"); -#endif - - // DD modes do double-buffer page flipping, but the game engine doesn't need this.. - lvid->u.numpages = 2; - - // release ddraw surfaces etc.. - ReleaseChtuff(); - - // clean up any old vid buffer lying around, alloc new if needed - if (!VID_FreeAndAllocVidbuffer(lvid)) - return -1; // no mem - - // should clear video mem here - - // note use lvid->bpp instead of 8...will this be needed? will we support other than 256color - // in software ? - if (!InitDirectDrawe(hWndMain, lvid->width, lvid->height, 8, TRUE)) // TRUE currently always full screen - return 0; // could not set mode - - // this is NOT used with DirectDraw modes, game engine should never use this directly - // but rather render to memory bitmap buffer - lvid->direct = NULL; - - if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) - vid.height = (int)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match - - return 1; -} - -// ======================================================================== -// VIDEO MODE CONSOLE COMMANDS -// ======================================================================== - -// vid_nummodes -// -static void VID_Command_NumModes_f(void) -{ - CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); -} - -// vid_modeinfo -// -static void VID_Command_ModeInfo_f(void) -{ - vmode_t *pv; - int modenum; - - if (COM_Argc() != 2) - modenum = vid.modenum; // describe the current mode - else - modenum = atoi(COM_Argv(1)); // the given mode number - - if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0 - { - CONS_Printf(M_GetText("Video mode not present\n")); - return; - } - - pv = VID_GetModePtr(modenum); - - CONS_Printf("%s\n", VID_GetModeName(modenum)); - CONS_Printf(M_GetText("width: %d\nheight: %d\n"), - pv->width, pv->height); - if (rendermode == render_soft) - CONS_Printf(M_GetText("bytes per scanline: %d\nbytes per pixel: %d\nnumpages: %d\n"), - pv->rowbytes, pv->bytesperpixel, pv->numpages); -} - -// vid_modelist -// -static void VID_Command_ModeList_f(void) -{ - int i, nummodes; - const char *pinfo; - vmode_t *pv; - - nummodes = VID_NumModes(); - for (i = NUMSPECIALMODES; i <= nummodes; i++) - { - pv = VID_GetModePtr(i); - pinfo = VID_GetModeName(i); - - if (pv->bytesperpixel == 1) - CONS_Printf("%d: %s\n", i, pinfo); - else - CONS_Printf("%d: %s (hicolor)\n", i, pinfo); - } -} - -// vid_mode -// -static void VID_Command_Mode_f(void) -{ - int modenum; - - if (COM_Argc() != 2) - { - CONS_Printf(M_GetText("vid_mode : set video mode, current video mode %i\n"), vid.modenum); - return; - } - - modenum = atoi(COM_Argv(1)); - - if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0 - CONS_Printf(M_GetText("Video mode not present\n")); - else - setmodeneeded = modenum + 1; // request vid mode change -} diff --git a/src/win32ce/wince_stuff.c b/src/win32ce/wince_stuff.c deleted file mode 100644 index eb02e8ae2..000000000 --- a/src/win32ce/wince_stuff.c +++ /dev/null @@ -1,135 +0,0 @@ -//It's 4am and im writing replacement string functions.... - -#include -#include -#include "wince_stuff.h" - -char* _strlwr( char *string ) -{ - int i; - - if(!string) - return NULL; - - for(i=0 ; i < strlen(string); i++) - { - if((*(string + i) >= 65) && (*(string + i) <= 90)) - *(string+i) = *(string+i) + 32; - } - - return string; -} - -int _strnicmp(const char *first,const char *last, size_t count ) -{ - int f, l; - - do - { - if ( ((f = (unsigned char)(*(first++))) >= 'A') && (f <= 'Z') ) - f -= 'A' - 'a'; - - if ( ((l = (unsigned char)(*(last++))) >= 'A') && (l <= 'Z') ) - l -= 'A' - 'a'; - - } while ( --count && f && (f == l) ); - - return ( f - l ); -} - - -int _stricmp( const char *dst, const char *src ) -{ - int f, l; - - do - { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) - f -= 'A' - 'a'; - - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) - l -= 'A' - 'a'; - - } while ( f && (f == l) ); - - return(f - l); -} - - -char* _strupr( char *string ) -{ - int i; - - if(!string) - return NULL; - - for(i=0 ; i < strlen(string); i++) - { - if((*(string + i) >= 97) && (*(string + i) <= 122)) - *(string + i) = *(string + i) - 32; - } - - return string; -} - - - - -int isprint( int c ) -{ - if(c <= 31) - return FALSE; - - return TRUE; -} - - - -char* _strdup (const char * string) -{ - char *memory = NULL; - - if (!string) - return(NULL); - - if (memory = malloc(strlen(string) + 1)) - return(strcpy(memory,string)); - - return(NULL); -} - - - -char* strrchr (const char * string,int ch) -{ - char *start = (char *)string; - - while (*string++) /* find end of string */ - ; - /* search towards front */ - while (--string != start && *string != (char)ch) - ; - - if (*string == (char)ch) /* char found ? */ - return( (char *)string ); - - return(NULL); -} - -char* GetMyCWD(void) -{ - TCHAR fn[MAX_PATH]; - char* my_cwd,*p; - - GetModuleFileName(NULL,fn,MAX_PATH); - - my_cwd = (char*)malloc(MAX_PATH*sizeof(char)); - - WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR | WC_SEPCHARS, fn, -1, my_cwd, MAX_PATH, NULL, NULL); - p = strrchr(my_cwd,'\\'); - - if(p) - *(p+1) = '\0'; - - return my_cwd; -} diff --git a/src/win32ce/wince_stuff.h b/src/win32ce/wince_stuff.h deleted file mode 100644 index 5eab74848..000000000 --- a/src/win32ce/wince_stuff.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WINCE_STUFF_H -#define WINCE_STUFF_H - -/* -char* _strlwr(char *string); -int _strnicmp(const char *string1,const char *string2, size_t count ); -int _stricmp( const char *string1, const char *string2 ); -char* _strupr( char *string ); - -char *_strdup( const char *strSource ); -char *strrchr( const char *string, int c ); - -int isprint( int c ); -*/ -char* GetMyCWD(void); - -#endif \ No newline at end of file