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

📄 sdl_dx5events.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/

#ifdef SAVE_RCSID
static char rcsid =
 "@(#) $Id: SDL_dx5events.c,v 1.4 2002/04/22 21:38:05 wmay Exp $";
#endif

/* CAUTION!!!!  If you modify this file, check ../windib/SDL_sysevents.c */

#include "directx.h"

#include <stdio.h>
#include "SDL_events.h"
#include "SDL_video.h"
#include "SDL_error.h"
#include "SDL_syswm.h"
#include "SDL_sysevents.h"
#include "SDL_events_c.h"
#include "SDL_lowvideo.h"
#include "SDL_dx5video.h"

#ifndef WM_APP
#define WM_APP	0x8000
#endif

/* The keyboard and mouse device input */
#define MAX_INPUTS	16		/* Maximum of 16-1 input devices */
#define INPUT_QSIZE	32		/* Buffer up to 32 input messages */

static LPDIRECTINPUT dinput = NULL;
static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
static HANDLE               SDL_DIevt[MAX_INPUTS];
static void (*SDL_DIfun[MAX_INPUTS])(const int, DIDEVICEOBJECTDATA *);
static int SDL_DIndev = 0;
static int mouse_lost;
static int mouse_pressed;

/* The translation table from a DirectInput scancode to an SDL keysym */
static SDLKey DIK_keymap[256];
static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed);

/* DJM: If the user setup the window for us, we want to save his window proc,
   and give him a chance to handle some messages. */
static WNDPROC userWindowProc = NULL;

/* Convert a DirectInput return code to a text message */
static void SetDIerror(char *function, int code)
{
	static char *error;
	static char  errbuf[BUFSIZ];

	errbuf[0] = 0;
	switch (code) {
                case DIERR_GENERIC:
                        error = "Undefined error!";
                        break;
		case DIERR_OLDDIRECTINPUTVERSION:
			error = "Your version of DirectInput needs upgrading";
			break;
		case DIERR_INVALIDPARAM:
                        error = "Invalid parameters";
                        break;
                case DIERR_OUTOFMEMORY:
                        error = "Out of memory";
                        break;
		case DIERR_DEVICENOTREG:
			error = "Device not registered";
			break;
		case DIERR_NOINTERFACE:
			error = "Interface not supported";
			break;
		case DIERR_NOTINITIALIZED:
			error = "Device not initialized";
			break;
		default:
			sprintf(errbuf, "%s: Unknown DirectInput error: 0x%x",
								function, code);
			break;
	}
	if ( ! errbuf[0] ) {
		sprintf(errbuf, "%s: %s", function, error);
	}
	SDL_SetError("%s", errbuf);
	return;
}

/* Initialize DirectInput
   Note:  If NONEXCLUSIVE access is requested for the devices, normal 
          windows input messages will continue to be generated for that
          input device, in addition to DirectInput messages.
 */
static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *events);
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *events);
struct {
	char *name;
	REFGUID guid;
	LPCDIDATAFORMAT format;
	DWORD win_level;
	DWORD raw_level;
	void (*fun)(const int numevents, DIDEVICEOBJECTDATA *events);
} inputs[] = {
	{ "keyboard",
		&GUID_SysKeyboard, &c_dfDIKeyboard,
		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
	{ "mouse",
		&GUID_SysMouse, &c_dfDIMouse,
		(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
		(DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse },
	{ NULL, NULL, NULL, 0, 0, NULL }
};
	
static int DX5_DInputInit(_THIS)
{
	int         i;
	LPDIRECTINPUTDEVICE device;
	HRESULT     result;
	DIPROPDWORD dipdw;

	/* Create the DirectInput object */
	result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
							&dinput, NULL);
	if ( result != DI_OK ) {
		SetDIerror("DirectInputCreate", result);
		return(-1);
	}

	/* Create all of our registered input devices */
	SDL_DIndev = 0;
	for ( i=0; inputs[i].name; ++i ) {
		/* Create the DirectInput device */
		result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
								&device, NULL);
		if ( result != DI_OK ) {
			SetDIerror("DirectInput::CreateDevice", result);
			return(-1);
		}
		result = IDirectInputDevice_QueryInterface(device,
			&IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
		IDirectInputDevice_Release(device);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::QueryInterface", result);
			return(-1);
		}
		result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
					SDL_Window, inputs[i].win_level);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetCooperativeLevel",
									result);
			return(-1);
		}
		result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
							inputs[i].format);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetDataFormat", result);
			return(-1);
		}

		/* Set buffered input -- we aren't polling */
		memset(&dipdw, 0, sizeof(dipdw));
		dipdw.diph.dwSize = sizeof(dipdw);
		dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
		dipdw.diph.dwObj = 0;
		dipdw.diph.dwHow = DIPH_DEVICE;
		dipdw.dwData = INPUT_QSIZE;
		result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
						DIPROP_BUFFERSIZE, &dipdw.diph);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetProperty", result);
			return(-1);
		}

		/* Create an event to be signaled when input is ready */
		SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
		if ( SDL_DIevt[i] == NULL ) {
			SDL_SetError("Couldn't create DirectInput event");
			return(-1);
		}
		result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
								SDL_DIevt[i]);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetEventNotification",
									result);
			return(-1);
		}
		SDL_DIfun[i] = inputs[i].fun;

		/* Acquire the device for input */
		IDirectInputDevice2_Acquire(SDL_DIdev[i]);

		/* Increment the number of devices we have */
		++SDL_DIndev;
	}
	mouse_pressed = 0;

	/* DirectInput is ready! */
	return(0);
}

/* Change cooperative level based on whether or not we are fullscreen */
void DX5_DInputReset(_THIS, int fullscreen)
{
	DWORD level;
	int i;
	HRESULT result;

	for ( i=0; i<MAX_INPUTS; ++i ) {
		if ( SDL_DIdev[i] != NULL ) {
			if ( fullscreen ) {
				level = inputs[i].raw_level;
			} else {
				level = inputs[i].win_level;
			}
			IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
			result = IDirectInputDevice2_SetCooperativeLevel(
					SDL_DIdev[i], SDL_Window, level);
			IDirectInputDevice2_Acquire(SDL_DIdev[i]);
			if ( result != DI_OK ) {
				SetDIerror(
			"DirectInputDevice::SetCooperativeLevel", result);
			}
		}
	}
	mouse_lost = 1;
}

/* Clean up DirectInput */
static void DX5_DInputQuit(_THIS)
{
	int i;

	if ( dinput != NULL ) {
		/* Close and release all DirectInput devices */
		for ( i=0; i<MAX_INPUTS; ++i ) {
			if ( SDL_DIdev[i] != NULL ) {
				IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
				IDirectInputDevice2_SetEventNotification(
							SDL_DIdev[i], NULL);
				if ( SDL_DIevt[i] != NULL ) {
					CloseHandle(SDL_DIevt[i]);
					SDL_DIevt[i] = NULL;
				}
				IDirectInputDevice2_Release(SDL_DIdev[i]);
				SDL_DIdev[i] = NULL;
			}
		}
		/* Release DirectInput */
		IDirectInput_Release(dinput);
		dinput = NULL;
	}
}

/* Flag to tell SDL whether or not we queued an event */
static int posted = 0;

/* Input event handler functions */
static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *keybuf)
{
	int i;
	SDL_keysym keysym;

	/* Translate keyboard messages */
	for ( i=0; i<numevents; ++i ) {
		if ( keybuf[i].dwData & 0x80 ) {
			posted = SDL_PrivateKeyboard(SDL_PRESSED,
				    TranslateKey(keybuf[i].dwOfs, &keysym, 1));
		} else {
			posted = SDL_PrivateKeyboard(SDL_RELEASED,
				    TranslateKey(keybuf[i].dwOfs, &keysym, 0));
		}
	}
}
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
{
	int i;
	Sint16 xrel, yrel;
	Uint8 state;
	Uint8 button;

	/* If we are in windowed mode, Windows is taking care of the mouse */
	if (  (SDL_PublicSurface->flags & SDL_OPENGL) ||
	     !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
		return;
	}

	/* If the mouse was lost, regain some sense of mouse state */
	if ( mouse_lost ) {
		POINT mouse_pos;
		Uint8 old_state;
		Uint8 new_state;

		/* Set ourselves up with the current cursor position */
		GetCursorPos(&mouse_pos);
		ScreenToClient(SDL_Window, &mouse_pos);
		posted = SDL_PrivateMouseMotion(0, 0,
				(Sint16)mouse_pos.x, (Sint16)mouse_pos.y);

		/* Check for mouse button changes */
		old_state = SDL_GetMouseState(NULL, NULL);
		new_state = 0;
		{ /* Get the new DirectInput button state for the mouse */
			DIMOUSESTATE distate;
			HRESULT result;

			result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
						sizeof(distate), &distate);
			if ( result != DI_OK ) {
				/* Try again next time */
				SetDIerror(
				"IDirectInputDevice2::GetDeviceState", result);
				return;
			}
			for ( i=3; i>=0; --i ) {
				if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
					new_state |= 0x01;
				}
				new_state <<= 1;
			}
		}
		for ( i=0; i<8; ++i ) {
			if ( (old_state&0x01) != (new_state&0x01) ) {
				button = (Uint8)(i+1);
				/* Button #2 on two button mice is button 3
				   (the middle button is button 2)
				 */
				if ( button == 2 ) {
					button = 3;
				} else
				if ( button == 3 ) {
					button = 2;
				}
				if ( new_state & 0x01 ) {
					/* Grab mouse so we get mouse-up */
					if ( ++mouse_pressed > 0 ) {
						SetCapture(SDL_Window);
					}
					state = SDL_PRESSED;
				} else {
					/* Release mouse after all mouse-ups */
					if ( --mouse_pressed <= 0 ) {
						ReleaseCapture();
						mouse_pressed = 0;
					}
					state = SDL_RELEASED;
				}
				posted = SDL_PrivateMouseButton(state, button,
									0, 0);
			}
			old_state >>= 1;
			new_state >>= 1;
		}
		mouse_lost = 0;
		return;
	}

	/* Translate mouse messages */
	xrel = 0;
	yrel = 0;
	for ( i=0; i<(int)numevents; ++i ) {
		switch (ptrbuf[i].dwOfs) {
			case DIMOFS_X:
				xrel += (Sint16)ptrbuf[i].dwData;
				break;
			case DIMOFS_Y:
				yrel += (Sint16)ptrbuf[i].dwData;
				break;
			case DIMOFS_Z:
				if ( xrel || yrel ) {
					posted = SDL_PrivateMouseMotion(
							0, 1, xrel, yrel);
					xrel = 0;
					yrel = 0;
				}
				if((int)ptrbuf[i].dwData > 0)
					button = 4;
				else
					button = 5;
					posted = SDL_PrivateMouseButton(
						SDL_PRESSED, button, 0, 0);
				posted |= SDL_PrivateMouseButton(
						SDL_RELEASED, button, 0, 0);
				break;
			case DIMOFS_BUTTON0:
			case DIMOFS_BUTTON1:
			case DIMOFS_BUTTON2:
			case DIMOFS_BUTTON3:
				if ( xrel || yrel ) {
					posted = SDL_PrivateMouseMotion(
							0, 1, xrel, yrel);
					xrel = 0;
					yrel = 0;
				}
				button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;

⌨️ 快捷键说明

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