📄 i_pm.c
字号:
#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 + -