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

📄 i_pm.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INCL_WIN
#include "i_os2.h"

#include "i_system.h"
#include "doomdef.h"
#include "m_argv.h"
#include "d_main.h"
#include "keys.h"


/* Function prototypes
*/
MRESULT EXPENTRY DoomWindowProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
MRESULT EXPENTRY MyDlgProc ( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 );
void     DoomThread( void*);

/* Global definitions
*/
PWINDATA  pmData;

/*
 * Functions that query information about windows
 */

int      ScreenWidth() {
   return WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
}


int      ScreenHeight() {
   return WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
}

void     SnapWindow(WINDATA *this, LONG width, LONG height)
{
   LONG nheight, nwidth;

   if (this->ulWindowStyle != WS_DesktopDive)
      return;

   if (!height) {
      height = (width * this->ulHeight) / this->ulWidth;
   }

   nheight = height + WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER) * 2
		    + WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER) * 2
		    + WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
   nwidth = width + WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER) * 2;

   WinSetWindowPos( this->hwndFrame, HWND_TOP,
		   (ScreenWidth() - nwidth) / 2,
		   (ScreenHeight() - nheight) / 2,
		   nwidth, nheight,
		   SWP_SIZE | SWP_ACTIVATE | SWP_MOVE | SWP_SHOW);

} /* SnapWindow */


void     BlitThread( void* arg)
{
   ULONG    ulTime0, ulTime1;     // output buffer for DosQuerySysInfo
   ULONG    ulNumFrames=0;        // Frame counter
   ULONG    ulFramesToTime=32;     // Interval of frames to get time
   PWINDATA this = (PWINDATA) arg;

   while( !this->ulToEnd) {

         // skip if dive not enabled
      if (!this->hDive)
         continue;

         // skip if blit not enabled
      if (!this->fBlitReady)
         continue;

         // Check if it's time to start the blit-time counter.
      if (!ulNumFrames++ )
         DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulTime0, 4L );

         // blit image
      DiveBlitImage( this->hDive, this->ulImage2, DIVE_BUFFER_SCREEN);
         // reset blitting flag
      this->fBlitReady = FALSE;

         // skip if rating not enabled
      if (!this->fCheckFps)
         continue;

         // Check to see if we have enough frames for a fairly accurate read.
      if (ulNumFrames>=ulFramesToTime) {
            DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &ulTime1, 4L );
            ulTime1 -= ulTime0;
            if (ulTime1)
               sprintf( this->title, "(%d) %5.2f frames per second.",
                        ulFramesToTime,
                        (float)ulFramesToTime * 1000.0 / (float)ulTime1 );
            else
               sprintf( this->title, "(%d) Lots of frames per second.",
                        ulFramesToTime );
            WinPostMsg( this->hwndFrame, WM_COMMAND, (PVOID)ID_NEWTEXT, 0);
            ulNumFrames = 0;

            /* Adjust number of frames to time based on last set.
            */
            if ( ulTime1 < 250 )
               ulFramesToTime <<= 1;
            if ( ulTime1 > 3000 )
               ulFramesToTime >>= 1;
      }

         // Let other threads and processes have some time.
      DosSleep( 0);
   }
   return;
}


int      PostEvent( event_t* evt)
{
   APIRET rc;

      // request with 1s timeout
   rc = DosRequestMutexSem( pmData->hmtxEventSem, 100);
   if (rc==ERROR_TIMEOUT) {
      printf( "PostEvent: can't request semaphore\n");
      return 1;
   }

      // post of current event
   D_PostEvent( evt);

      // release resource
   rc = DosReleaseMutexSem( pmData->hmtxEventSem);

   return 0;
}


/*
 * This function translates OS/2 scan codes -> DOOM keys
 */

int PostCharEvent(WINDATA *this, PCHRMSG pchmsg)
{
   static event_t ev;

   memset( &ev, 0, sizeof( ev));

      // use last char, for keyup events
   if (this->last_char) {
      ev.type = ev_keyup;
      ev.data1 = this->last_char;
      PostEvent(&ev);
      this->last_char = 0;
   }

   memset( &ev, 0, sizeof( ev));
   ev.type = (pchmsg->fs & KC_KEYUP) ? ev_keyup : ev_keydown;

   if (pchmsg->fs & KC_VIRTUALKEY) {

         // process virtual keys
      switch( pchmsg->vkey) {

      case VK_INSERT:   ev.data1 = KEY_INS;  break;
      case VK_DELETE:   ev.data1 = KEY_DEL;  break;
      case VK_HOME:     ev.data1 = KEY_HOME;  break;
      case VK_END:      ev.data1 = KEY_END;  break;
      case VK_PAGEUP:   ev.data1 = KEY_PGUP;  break;
      case VK_PAGEDOWN: ev.data1 = KEY_PGDN;  break;

      case VK_LEFT:  ev.data1 = KEY_LEFTARROW;  break;
      case VK_RIGHT: ev.data1 = KEY_RIGHTARROW; break;
      case VK_UP:    ev.data1 = KEY_UPARROW;    break;
      case VK_DOWN:  ev.data1 = KEY_DOWNARROW;  break;
      case VK_ESC:   ev.data1 = KEY_ESCAPE;     break;
      case VK_NEWLINE:
      case VK_ENTER: ev.data1 = KEY_ENTER;      break;
      case VK_TAB:   ev.data1 = KEY_TAB;        break;
      case VK_SPACE:     ev.data1 = ' ';            break;
      case VK_BACKSPACE: ev.data1 = KEY_BACKSPACE;  break;
      case VK_PAUSE:
      case VK_NUMLOCK:ev.data1 = KEY_PAUSE;     break;
      case VK_CTRL:  ev.data1 = KEY_CTRL;       break;
      case VK_F1:
	  /* Hack! OS/2 grabs this key and only returns the keyup event */
	  ev.type = ev_keydown;
	  PostEvent(&ev);
	  ev.data1 = KEY_F1;
	  break;
      case VK_F2:    ev.data1 = KEY_F2;         break;
      case VK_F3:    ev.data1 = KEY_F3;         break;
      case VK_F4:    ev.data1 = KEY_F4;         break;
      case VK_F5:    ev.data1 = KEY_F5;         break;
      case VK_F6:
	  /* desktop -> fullscreen */
	  if (pchmsg->fs & KC_SHIFT) {
	     WinPostMsg( this->hwndClient, WM_COMMAND, (MPARAM)ID_FSMODE, 0 );
	     return 1;
	  }
          ev.data1 = KEY_F6;
          break;
      case VK_F7:
	  /* fullscreen -> desktop */
	  if (pchmsg->fs & KC_SHIFT) {
	     WinPostMsg( this->hwndClient, WM_COMMAND, (MPARAM)ID_DESKMODE, 0);		      	
	     return 1;
	  }
#ifdef USE_MOUSE
	  if (pchmsg->fs & KC_ALT) {
	      WinPostMsg( this->hwndClient, WM_COMMAND, (MPARAM)ID_SWMOUSE,
			  (MPARAM)FALSE );
	      return 1;
	  }
#endif
	  ev.data1 = KEY_F7;
	  break;
      case VK_F8:
	  /*  -> max desktop */
	  if (pchmsg->fs & KC_SHIFT) {
	     WinPostMsg( this->hwndClient, WM_COMMAND, (MPARAM)ID_MAXMODE, 0);		      	
	     return 1;
	  }
	  ev.data1 = KEY_F8;
	  break;
      case VK_F9:
	  if (pchmsg->fs & KC_SHIFT) {
	      WinPostMsg(this->hwndClient, WM_COMMAND, (MPARAM)ID_SNAP, 0);
	      return 1;
	  }
	  ev.data1 = KEY_F9;
	  break;
      case VK_F10:
	  if (pchmsg->fs & KC_SHIFT) {
	      WinPostMsg(this->hwndClient, WM_COMMAND, (MPARAM)ID_SNAP2, 0);
	      return 1;
	  }
	  ev.data1 = KEY_F10;
	  break;
      case VK_F11:
	  if (pchmsg->fs & KC_SHIFT) {
	     /* switch to largest conformant size */
	     WinSendMsg(this->hwndClient, WM_COMMAND, (MPARAM)ID_SNAPFULL, 0);
	     return 1;
	  }
	  ev.data1 = KEY_F11;
	  break;
      case VK_F12:   ev.data1 = KEY_F12;        break;
      default:
         return 0;
         break;
      }

      //printf( "virtualkey %x event %x\n", pchmsg->vkey, ev.data1);

   } else if (pchmsg->fs & KC_CHAR) {    // normal keys
      /* For usual keys no key up event is generated so we must remember
         the last key down event to send a key-up later */
      this->last_char = ev.data1 = tolower(pchmsg->chr) == '+' ? KEY_EQUALS : tolower( pchmsg->chr);
   } else {
      return 0;
   }

      // send event to Doom/2 thread
   if (ev.data1)
      PostEvent(&ev);

   return 1;
}

/*
 * This routine treats all the appl. defined commands for the DIVE window.
 */

MRESULT WindowCommands(WINDATA *this, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   BOOL  bHandled = TRUE;

   switch ((ULONG)mp1) {
   case ID_SNAP:
      SnapWindow(this, this->ulWidth, this->ulHeight);
      CONS_Printf("Switching to 1X window mode...\n");
      break;
   case ID_SNAP2:
      SnapWindow(this, this->ulWidth * 2, this->ulHeight * 2);
      CONS_Printf("Switching to 2X window mode...\n");
      break;
   case ID_SNAPFULL:
      SnapWindow(this, ScreenWidth(), 0);
      CONS_Printf("Switching to max screen width window mode...\n");
      break;
   case ID_DESKMODE:
      if (this->fFSBase && this->ulWindowStyle != WS_DesktopDive)
	 WinSendMsg( this->hwndFrame, WM_SetVideoMode,
		     (MPARAM)WS_DesktopDive, 0 );
      CONS_Printf("Switching to desktop mode...\n");
      break;
   case ID_FSMODE:
      if (this->fFSBase && this->ulWindowStyle != WS_FullScreenDive)

⌨️ 快捷键说明

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