📄 win_sys.c
字号:
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
};
int pausepressed=0;
// Return a key that has been pushed, or 0
// (replace getchar() at game startup)
//
int I_GetKey (void)
{
event_t *ev;
if (eventtail != eventhead)
{
ev = &events[eventtail];
eventtail = (++eventtail)&(MAXEVENTS-1);
if (ev->type == ev_keydown)
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()
{
DIPROPDWORD dip;
//faB: make sure the app window has the focus or
// DirectInput acquire keyboard won't work
if ( hWndMain!=NULL )
{
SetFocus(hWndMain);
ShowWindow(hWndMain, SW_SHOW);
UpdateWindow(hWndMain);
}
//faB: detect error
if (lpDIK != NULL) {
CONS_Printf ("\2I_StartupKeyboard(): called twice\n");
return;
}
CreateDevice2 (lpDI, &GUID_SysKeyboard, &lpDIK, NULL);
if (lpDIK)
{
if (FAILED( lpDIK->lpVtbl->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( lpDIK->lpVtbl->SetProperty (lpDIK, DIPROP_BUFFERSIZE, &dip.diph)))
I_Error ("Couldn't set keyboard buffer size");
if (FAILED( lpDIK->lpVtbl->SetCooperativeLevel (lpDIK, hWndMain, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)))
I_Error ("Couldn't set keyboard coop level");
//faB: it seems to FAIL if the window doesn't have the focus
//BP: acquire it latter
//if (FAILED( lpDIK->lpVtbl->Acquire (lpDIK) ))
// I_Error ("Couldn't acquire keyboard\n");
}
else
I_Error ("Couldn't create keyboard input");
I_AddExitFunc (I_ShutdownKeyboard);
hacktics = 0; //faB: see definition
keyboard_started = true;
}
// ------------------
// I_ShutdownKeyboard
// Release DirectInput keyboard.
// ------------------
static void I_ShutdownKeyboard()
{
if (!keyboard_started)
return;
CONS_Printf ("I_ShutdownKeyboard()\n");
if ( lpDIK )
{
lpDIK->lpVtbl->Unacquire (lpDIK);
lpDIK->lpVtbl->Release (lpDIK);
lpDIK = NULL;
}
keyboard_started = false;
}
// -------------------
// I_GetKeyboardEvents
// Get buffered data from the keyboard
// -------------------
static void I_GetKeyboardEvents (void)
{
static boolean KeyboardLost = false;
//faB: 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 BYTE RepeatKeyCode;
DIDEVICEOBJECTDATA rgdod[DI_KEYBOARD_BUFFERSIZE];
DWORD dwItems;
DWORD d;
HRESULT hr;
int ch;
event_t event;
if (!keyboard_started)
return;
getBufferedData:
dwItems = DI_KEYBOARD_BUFFERSIZE;
hr = lpDIK->lpVtbl->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 = lpDIK->lpVtbl->Acquire (lpDIK);
if (SUCCEEDED(hr))
goto getBufferedData;
return;
}
// we lost data, get device actual state to recover lost information
if (hr==DI_BUFFEROVERFLOW)
{
//I_Error ("DI buffer overflow (keyboard)");
//I_RecoverKeyboardState ();
//hr = lpDIM->lpVtbl->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)
{
//faB: my current hack simply clear 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.
memset (gamekeydown, 0, sizeof(gamekeydown));
//CONS_Printf ("we lost it, we cleared stuff!\n");
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 & 0xFF;
if (ASCIINames[ch]!=0)
event.data1 = ASCIINames[ch];
else
event.data1 = ch + 0x80;
D_PostEvent(&event);
}
//
// Key Repeat
//
if (dwItems) {
// new key events, so stop repeating key
RepeatKeyCode = 0;
RepeatKeyTics = hacktics + (KEY_REPEAT_DELAY*2); //delay is trippled for first repeating key
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!=NULL)
lpDI->lpVtbl->Release (lpDI);
lpDI = NULL;
}
// This stuff should get rid of the exception and page faults when
// Doom bugs out with an error. Now it should exit cleanly.
//
int I_StartupSystem(void)
{
HRESULT hr;
// some 'more globals than globals' things to initialize here ?
graphics_started = false;
keyboard_started = false;
sound_started = false;
timer_started = false;
cdaudio_started = false;
I_DetectWin95 ();
// 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_DoomMain 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 ) )
{
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
// pallete and video mode, and removing whatever mouse, keyboard, and
// timer routines have been installed.
//
// NOTE : Shutdown user funcs. are effectively called in reverse order.
//
void I_ShutdownSystem()
{
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.
// ---------------
void I_SaveMemToFile (unsigned char* pData, unsigned long iLength, char* sFileName)
{
HANDLE fileHandle;
DWORD bytesWritten;
fileHandle = CreateFile (sFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
if (fileHandle == INVALID_HANDLE_VALUE)
{
I_Error ("SaveMemToFile");
}
WriteFile (fileHandle, pData, iLength, &bytesWritten, NULL);
CloseHandle (fileHandle);
}
// 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;
INT64 usedbytes;
if(!testwin95)
{
HINSTANCE h = LoadLibraryA("kernel32.dll");
if (h) {
pfnGetDiskFreeSpaceEx = (MyFunc)GetProcAddress(h,"GetDiskFreeSpaceExA");
FreeLibrary(h);
}
testwin95 = true;
}
if (pfnGetDiskFreeSpaceEx) {
if (!pfnGetDiskFreeSpaceEx(NULL,(PULARGE_INTEGER)freespace,(PULARGE_INTEGER)&usedbytes,NULL))
*freespace = MAXINT;
}
else
{
ULONG SectorsPerCluster, BytesPerSector, NumberOfFreeClusters;
ULONG TotalNumberOfClusters;
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
&NumberOfFreeClusters, &TotalNumberOfClusters);
*freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;
}
}
char *I_GetUserName(void)
{
static char username[MAXPLAYERNAME];
char *p;
int ret;
ULONG i=MAXPLAYERNAME;
ret = GetUserName(username,&i);
if(!ret)
{
if((p=getenv("USER"))==NULL)
if((p=getenv("user"))==NULL)
if((p=getenv("USERNAME"))==NULL)
if((p=getenv("username"))==NULL)
return NULL;
strncpy(username,p,MAXPLAYERNAME);
}
if( strcmp(username,"")==0 )
return NULL;
return username;
}
int I_mkdir(const char *dirname, int unixright)
{
return mkdir(dirname);
//TODO: should implement ntright under nt ...
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -