⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_sys.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
// 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 + -