📄 win_sys.c
字号:
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: win_sys.c,v 1.17 2001/05/06 09:50:35 hurdler Exp $
//
// 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.
//
//
// $Log: win_sys.c,v $
// Revision 1.17 2001/05/06 09:50:35 hurdler
// fix dx8+ sdk compatibility
//
// Revision 1.16 2001/04/27 13:32:15 bpereira
// no message
//
// Revision 1.15 2001/01/25 22:15:45 bpereira
// added heretic support
//
// Revision 1.14 2001/01/21 04:33:35 judgecutor
// *** empty log message ***
//
// Revision 1.13 2001/01/06 22:21:08 judgecutor
// Added NoDirectInput mouse input
//
// Revision 1.12 2000/11/26 00:47:59 hurdler
// Please fix this so it works under ALL version of win32
//
// Revision 1.11 2000/10/23 19:25:50 judgecutor
// Fixed problem with mouse wheel event
//
// Revision 1.10 2000/10/21 08:43:32 bpereira
// no message
//
// Revision 1.9 2000/10/02 18:25:47 bpereira
// no message
//
// Revision 1.8 2000/09/28 20:57:22 bpereira
// no message
//
// Revision 1.7 2000/09/01 19:34:38 bpereira
// no message
//
// Revision 1.6 2000/08/10 19:58:05 bpereira
// no message
//
// Revision 1.5 2000/08/03 17:57:42 bpereira
// no message
//
// Revision 1.4 2000/04/23 16:19:52 bpereira
// no message
//
// Revision 1.3 2000/04/16 18:38:07 bpereira
// no message
//
// Revision 1.2 2000/02/27 00:42:12 hurdler
// fix CR+LF problem
//
// Revision 1.1.1.1 2000/02/22 20:32:33 hurdler
// Initial import into CVS (v1.29 pr3)
//
//
// DESCRIPTION:
// win32 system i/o
// Startup & Shutdown routines for music,sound,timer,keyboard,...
// Signal handler to trap errors and exit cleanly.
//
//-----------------------------------------------------------------------------
#include "../doomdef.h"
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <stdarg.h>
#include <direct.h>
#include "../m_misc.h"
#include "../i_video.h"
#include "../i_sound.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 "fabdxlib.h"
#include <mmsystem.h>
#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 <dinput.h>
// judgecutor: Wheel support for Win95/WinNT3.51
#include <zmouse.h>
// judgecutor: Taken from Win98/NT4.0
#ifndef SM_MOUSEWHEELPRESENT
#define SM_MOUSEWHEELPRESENT 75
#endif
// ==================
// DIRECT INPUT STUFF
// ==================
BOOL bDX0300; // if true, we created a DirectInput 0x0300 version
// faB: what a beautiful variable name, isn't it ?
static LPDIRECTINPUT lpDI = NULL;
static LPDIRECTINPUTDEVICE lpDIK = NULL; // Keyboard
static LPDIRECTINPUTDEVICE lpDIM = NULL; // mice
static LPDIRECTINPUTDEVICE lpDIJ = NULL; // joystick 1
static LPDIRECTINPUTDEVICE2 lpDIJ2 = NULL; // joystick 2
volatile tic_t ticcount; //returned by I_GetTime(), updated by timer interrupt
// Do not execute cleanup code more than once. See Shutdown_xxx() routines.
byte graphics_started=0;
byte keyboard_started=0;
byte sound_started=0;
boolean timer_started = false;
boolean mouse_enabled = false;
boolean joystick_detected;
void I_AddExitFunc(void (*func)());
void I_Quit (void);
void I_Error (char *error, ...);
void I_OutputMsg (char *error, ...);
void I_ShutdownSystem (void);
static void I_ShutdownKeyboard (void);
//
// Force feedback here ? :)
//
void I_Tactile ( int on, int off, int total )
{
// UNUSED.
on = off = total = 0;
}
//
// Why would this be system specific ?? hmmmm....
//
// BP: yes it is for virtual reality system, next incoming feature :)
ticcmd_t emptycmd;
ticcmd_t* I_BaseTiccmd(void)
{
return &emptycmd;
}
// Allocates the base zone memory,
// this function returns a valid pointer and size,
// else it should interrupt the program immediately.
//
//added:11-02-98: now checks if mem could be allocated, this is still
// prehistoric... there's a lot to do here: memory locking, detection
// of win95 etc...
//
boolean win95;
boolean winnt;
static void I_DetectWin95 (void)
{
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&osvi);
winnt = (osvi.dwPlatformId==VER_PLATFORM_WIN32_NT);
// 95 or 98 what the hell
win95 = true;
}
// return free and total memory in the system
ULONG I_GetFreeMem(ULONG *total)
{
MEMORYSTATUS info;
info.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus( &info );
if( total )
*total = info.dwTotalPhys;
return 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))
//can't profile without the high res timer
I_Error ("I_BeginProfile FAILED");
}
//faB: 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 Windowz NT
// ---------
static long hacktics = 0; //faB: used locally for keyboard repeat keys
int I_GetTime (void)
{
int newtics;
LARGE_INTEGER currtime; // use only LowPart if high resolution counter not available
static LARGE_INTEGER basetime = {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));
}
hacktics = newtics; //faB: just a local counter for keyboard repeat key
return newtics;
}
// should move to i_video
void I_WaitVBL(int count)
{
}
// Fab: 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) {}
// Fab: see above, end the 'loading' disc icon, set the flag false
//
void I_EndRead (void) {}
byte* I_AllocLow(int length)
{
byte* mem;
mem = (byte *)malloc (length);
memset (mem,0,length);
return mem;
}
// ===========================================================================================
// EVENTS
// ===========================================================================================
// ----------
// I_GetEvent
// Post new events for all sorts of user-input
// ----------
static void I_GetKeyboardEvents (void);
static void I_GetMouseEvents (void);
static void I_GetJoystickEvents (void);
void I_GetEvent (void)
{
I_GetKeyboardEvents ();
I_GetMouseEvents ();
I_GetJoystickEvents ();
}
// ----------
// I_OsPolling
// ----------
void I_OsPolling()
{
MSG msg;
//faB: we need to dispatch messages to the window
// so the window procedure can respond to messages and PostEvent() for keys
// during D_DoomMain startup.
// BP: this on replace 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)
WaitMessage();
} while(!appActive && !netgame);
// this is called by the network synchronization,
// check keys and allow escaping
I_GetEvent();
// reset "emalated keys"
gamekeydown[KEY_MOUSEWHEELUP] = 0;
gamekeydown[KEY_MOUSEWHEELDOWN] = 0;
}
// ===========================================================================================
// TIMER
// ===========================================================================================
//
// Timer user routine called at ticrate.
//
void winTimer (HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
ticcount++;
}
//added:08-01-98: we don't use allegro_exit() so we have to do it ourselves.
static UINT myTimer;
void I_ShutdownTimer (void)
{
//if (myTimer)
// KillTimer (hWndMain, myTimer);
timer_started = false;
}
//
// Installs the timer interrupt handler with timer speed as TICRATE.
//
#define TIMER_ID 1
#define TIMER_RATE (1000/TICRATE)
void I_StartupTimer(void)
{
ticcount = 0;
//if ( (myTimer =SetTimer (hWndMain, TIMER_ID, TIMER_RATE, winTimerISR)) == 0)
// I_Error("I_StartupTimer: could not install timer.");
//I_AddExitFunc(I_ShutdownTimer);
timer_started = true;
}
// ===========================================================================================
// EXIT CODE, ERROR HANDLING
// ===========================================================================================
int errorcount = 0; // phuck recursive errors
int shutdowning= false;
//
// Used to trap various signals, to make sure things get shut down cleanly.
//
static void signal_handler(int num)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -