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

📄 win_sys.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    static char msg[] = "oh no! back to reality!\r\n";
    char*       sigmsg;
    char        sigdef[64];
        
    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)
    {
        FPrintf (logstream,"signal_handler() error: %s\n", sigmsg);
        CloseHandle (logstream);
        logstream = INVALID_HANDLE_VALUE;
    }
#endif    
    
    MessageBox(hWndMain,va("signal_handler() : %s",sigmsg),"Doom Legacy error",MB_OK|MB_ICONERROR);
        
    signal(num, SIG_DFL);               //default signal action
    raise(num);
}


//
// put an error message (with format) on stderr
//
void I_OutputMsg (char *error, ...)
{
    va_list     argptr;
    char        txt[512];
        
    va_start (argptr,error);
    vsprintf (txt,error,argptr);
    va_end (argptr);
        
    fprintf (stderr, "Error: %s\n", txt);
    // dont flush the message!

#ifdef LOGMESSAGES
    if (logstream != INVALID_HANDLE_VALUE)
        FPrintf (logstream,"%s", txt);
#endif
}


// display error messy after shutdowngfx
//
void I_Error (char *error, ...)
{
    va_list     argptr;
    char        txt[512];

    // added 11-2-98 recursive error detecting
    if(shutdowning)
    {
        errorcount++;
        // try to shutdown separetely eatch stuff
        if(errorcount==5)
            I_ShutdownGraphics();
        if(errorcount==6)
            I_ShutdownSystem();
        if(errorcount==7)
            M_SaveConfig (NULL);
        if(errorcount>20)
        {
            MessageBox(hWndMain,txt,"Doom Legacy Recursive Error",MB_OK|MB_ICONERROR);
            exit(-1);     // recursive errors detected
        }
    }
    shutdowning=true;
        
    // put message to stderr
    va_start (argptr,error);
    wvsprintf (txt, error, argptr);
    va_end (argptr);

    CONS_Printf("I_Error(): %s\n",txt);
    //wsprintf (stderr, "I_Error(): %s\n", txt);
        
    //added:18-02-98: save one time is enough!
    if (!errorcount)
    {
        M_SaveConfig (NULL);   //save game config, cvars..
    }
        
    //added:16-02-98: 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)
    {
        //FPrintf (logstream,"I_Error(): %s", txt);
        CloseHandle (logstream);
        logstream = INVALID_HANDLE_VALUE;
    }
#endif
    
    MessageBox (hWndMain, txt, "Doom Legacy Error", MB_OK|MB_ICONERROR);

    //getchar();
    exit (-1);
}


//
// I_Quit : shutdown everything cleanly, in reverse order of Startup.
//
void I_Quit (void)
{
    //added:16-02-98: when recording a demo, should exit using 'q' key,
    //        but sometimes we forget and use 'F10'.. so save here too.
    if (demorecording)
        G_CheckDemoStatus();
        
    M_SaveConfig (NULL);   //save game config, cvars..

    //TODO: do a nice ENDOOM for win32 ?
    //    endoom = W_CacheLumpName("ENDOOM",PU_CACHE);
        
    //added:03-01-98: maybe it needs that the ticcount continues,
    // or something else that will be finished by ShutdownSystem()
    // so I 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)
    {
        FPrintf (logstream,"I_Quit(): end of logstream.\n");
        CloseHandle (logstream);
        logstream = INVALID_HANDLE_VALUE;
    }
#endif

    // cause an error to test the exception handler
    //i = *((unsigned long *)0x181596);

    fflush(stderr);
    exit(0);
}


// --------------------------------------------------------------------------
// I_ShowLastError
// Displays a GetLastError() error message in a MessageBox
// --------------------------------------------------------------------------
void I_GetLastErrorMsgBox (void)
{
    LPVOID lpMsgBuf;

    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
    );

    // Display the string.
    MessageBox( 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.
// ===========================================================================================
//
//
#define MAX_QUIT_FUNCS     16

typedef void (*quitfuncptr)();

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;

    hr = di->lpVtbl->CreateDevice (di, pguid, &lpdid1, NULL);

    if (SUCCEEDED (hr))
    {
        // get Device2 but only if we are not in DirectInput version 3
        if ( !bDX0300 && ( lpDEV2 != NULL ) ) {
            hr2 = lpdid1->lpVtbl->QueryInterface (lpdid1, &IID_IDirectInputDevice2, (void**)&lpdid2);
            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 != NULL )   //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
}

HANDLE mouse2filehandle=0;

static void I_ShutdownMouse2 (void)
{
    if(mouse2filehandle)
    {
        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=0;
    }
}

#define MOUSECOMBUFFERSIZE 256
int handlermouse2x,handlermouse2y,handlermouse2buttons;

static void I_PoolMouse2(void)
{
    byte buffer[MOUSECOMBUFFERSIZE];
    COMSTAT    ComStat ;
    DWORD      dwErrorFlags;
    DWORD      dwLength;
    char       dx,dy;

    static int     bytenum;
    static byte    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 = ((combytes[0] &  3) << 6) + combytes[1];
                dy = ((combytes[0] & 12) << 4) + 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 don't use directX, therefore forget all about grabing, acquire, etc...
void I_StartupMouse2 (void)
{
    DCB        dcb ;

    if(mouse2filehandle)
        I_ShutdownMouse2();

    if(cv_usemouse2.value==0)
        return;

    if(!mouse2filehandle)
    {
        // COM file handle
        mouse2filehandle = CreateFile( cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE,
                                       0,                     // exclusive access
                                       NULL,                  // no security attrs
                                       OPEN_EXISTING,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -