Initial commit.
This commit is contained in:
79
code/win32/AutoVersion.h
Normal file
79
code/win32/AutoVersion.h
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef __AUTO_VERSION_HEADER
|
||||
#define __AUTO_VERSION_HEADER
|
||||
|
||||
#define VERSION_MAJOR_RELEASE 1
|
||||
#define VERSION_MINOR_RELEASE 0
|
||||
#define VERSION_EXTERNAL_BUILD 0
|
||||
#define VERSION_INTERNAL_BUILD 0
|
||||
|
||||
#define VERSION_STRING "1, 0, 0, 0"
|
||||
#define VERSION_STRING_DOTTED "1.0.0.0"
|
||||
|
||||
#define VERSION_BUILD_NUMBER 73
|
||||
|
||||
// BEGIN COMMENTS
|
||||
// 1.0.0.0 07/21/2003 16:09:23 jmonroe going gold
|
||||
// 0.0.12.0 07/20/2003 19:04:44 jmonroe build 0.12 for qa
|
||||
// 0.0.11.0 07/19/2003 15:30:08 jmonroe stuff
|
||||
// 0.0.11.0 07/17/2003 17:08:09 jmonroe build 0.11 for qa
|
||||
// 0.0.10.1 07/16/2003 17:33:28 mgummelt General Update With Latest Code
|
||||
// 0.0.10.0 07/16/2003 10:28:51 jmonroe new product id, remove outcast.roq at end, menu ignoreescape, eax looping sounds support chan_less_atten
|
||||
// 0.0.10.0 07/14/2003 19:04:42 jmonroe build 0.10 for qa
|
||||
// 0.0.9.0 07/12/2003 13:05:57 jmonroe increase numsnapshot ents
|
||||
// 0.0.9.0 07/11/2003 17:48:40 jmonroe buil 0.09 for qa
|
||||
// 0.0.8.4 07/11/2003 15:47:55 jmonroe weatherzone caching
|
||||
// 0.0.8.3 07/11/2003 12:05:44 mgummelt Lava & Acid fixes
|
||||
// 0.0.8.2 07/10/2003 17:26:42 mgummelt General Update with today's bug fixes
|
||||
// 0.0.8.1 07/09/2003 19:24:19 jmonroe eax voice stomp fix, increased weather zones, ...
|
||||
// 0.0.8.0 07/08/2003 17:28:27 jmonroe build 0.08 for qa
|
||||
// 0.0.7.2 07/07/2003 16:28:40 mgummelt Blaster Pistol alt-fire returns, Rancor spawnflags corrected
|
||||
// 0.0.7.1 07/07/2003 10:48:29 jmonroe load menu fixes, darkside autoload fix,...
|
||||
// 0.0.7.0 07/02/2003 19:31:37 jmonroe buil 7 for qa
|
||||
// 0.0.6.5 07/02/2003 18:17:17 mgummelt Boss balancing
|
||||
// 0.0.6.3 07/02/2003 01:34:48 jmonroe saber in moves menu
|
||||
// 0.0.6.2 06/30/2003 15:33:37 mgummelt Force Sight change (designers readme)
|
||||
// 0.0.6.1 06/29/2003 19:00:17 jmonroe vv merged, aev_soundchan
|
||||
// 0.0.6.0 06/28/2003 16:38:27 jmonroe eax update, force sight on key dudes
|
||||
// 0.0.6.0 06/26/2003 16:45:26 jmonroe qa build
|
||||
// 0.0.5.6 06/25/2003 21:22:38 mgummelt "redcrosshair" field on misc_model_breakables and func_breakables
|
||||
// 0.0.5.5 06/25/2003 18:31:52 mgummelt Force Visible on all applicable ents
|
||||
// 0.0.5.4 06/25/2003 10:45:12 jmonroe EAX 4.0
|
||||
// 0.0.5.3 06/24/2003 22:59:31 mgummelt Reborn tweaks
|
||||
// 0.0.5.2 06/24/2003 18:53:55 mgummelt New Reborn Master
|
||||
// 0.0.5.1 06/23/2003 20:47:44 jmonroe fix NULL NPC usage
|
||||
// 0.0.5.0 06/21/2003 13:04:27 jmonroe fix eweb crash
|
||||
// 0.0.4.2 06/18/2003 14:24:35 jmonroe script cmd SET_WEAPON now precaches weapon, gil's optimized dlights
|
||||
// 0.0.4.1 06/17/2003 19:04:28 mgummelt Various Force Power, saber move & Enemy Jedi tweaks
|
||||
// 0.0.4.0 06/16/2003 19:41:54 jmonroe bug stuff
|
||||
// 0.0.4.0 06/13/2003 23:52:36 jmonroe inc version to match qa beta
|
||||
// 0.0.2.6 06/12/2003 13:11:21 creed new z-far cull
|
||||
// 0.0.2.5 06/10/2003 17:02:17 creed targetJump & other navigation
|
||||
// 0.0.2.4 06/10/2003 11:18:58 jmonroe footstep sounds in per material
|
||||
// 0.0.2.3 06/10/2003 01:37:10 mgummelt helping with entity limit at spawntime
|
||||
// 0.0.2.2 06/09/2003 14:10:32 scork fix for asian languages being bust by bad font
|
||||
// 0.0.2.1 06/08/2003 17:57:11 mgummelt Area portal fix
|
||||
// 0.0.2.0 06/08/2003 14:02:03 mgummelt Force sight change
|
||||
// 0.0.2.0 06/08/2003 00:03:58 jmonroe CGEN_LIGHTING_DIFFUSE_ENTITY merges lightingdiffuse and entity color
|
||||
// 0.0.1.25 06/05/2003 20:51:30 mgummelt Saber pull-attacks done
|
||||
// 0.0.1.24 06/05/2003 18:11:06 mgummelt Both saber control schemes implemented
|
||||
// 0.0.1.23 05/30/2003 17:12:34 mgummelt Fixed Noghri and Sand Creature
|
||||
// 0.0.1.22 05/30/2003 12:15:37 mgummelt Saboteur change, new cultist
|
||||
// 0.0.1.21 05/29/2003 16:02:48 creed Fixes For Assassin, ST AI changes
|
||||
// 0.0.1.20 05/29/2003 12:00:18 mgummelt Navigation changes
|
||||
// 0.0.1.19 05/29/2003 11:08:06 mgummelt various tweaks
|
||||
// 0.0.1.18 05/28/2003 22:08:16 creed Boba Fett ++
|
||||
// 0.0.1.17 05/28/2003 20:38:33 mgummelt force grip and force sense changes
|
||||
// 0.0.1.15 05/28/2003 17:07:26 mgummelt tweaks of force drain, protect and absorb
|
||||
// 0.0.1.14 05/28/2003 14:48:57 mgummelt various saber & AI fixes
|
||||
// 0.0.1.13 05/27/2003 17:26:30 areis Ported Glow stuff from MP (with support for nVidia and ATI cards). Added solid flag for roffs (in behaved) and made tie-bombers explode with effect.
|
||||
// 0.0.1.12 05/27/2003 13:06:03 mgummelt Noghri stick weapon shoots a projectile, E-Web uses proper sounds
|
||||
// 0.0.1.7 05/19/2003 15:00:10 mgummelt adding random jedi, elder prisoners, jedi master
|
||||
// 0.0.1.6 05/19/2003 09:22:18 creed Weather Effects & Haz Trooper
|
||||
// 0.0.1.5 05/16/2003 18:55:10 creed New Wind Spawn Flags For Dusty Fog & 1/2 way through Haz Trooper Fixins
|
||||
// 0.0.1.4 05/15/2003 14:29:35 jmonroe misc_model_static stay around after a vid_start
|
||||
// 0.0.1.3 05/14/2003 17:53:44 mgummelt testing misc_model_breakable scaling
|
||||
// 0.0.1.2 05/13/2003 20:48:35 jmonroe vv post merge
|
||||
// 0.0.1.1 05/13/2003 14:17:20 scork ste test comment
|
||||
// END COMMENTS
|
||||
|
||||
#endif // __AUTO_VERSION_HEADER
|
||||
247
code/win32/FeelIt/FEELitIFR.h
Normal file
247
code/win32/FeelIt/FEELitIFR.h
Normal file
@@ -0,0 +1,247 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1999 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FEELitIFR.h
|
||||
|
||||
PURPOSE: Input/Output for IFR Files, FEELit version
|
||||
|
||||
STARTED:
|
||||
|
||||
NOTES/REVISIONS:
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined( _FEELIT2_H_)
|
||||
#define _FEELIT2_H_
|
||||
|
||||
#ifndef __FEELITAPI_INCLUDED__
|
||||
#error include 'dinput.h' before including this file for structures.
|
||||
#endif /* !__DINPUT_INCLUDED__ */
|
||||
|
||||
#define IFRAPI __stdcall
|
||||
|
||||
#if !defined(_FFCDLL_)
|
||||
#define DLLAPI __declspec(dllimport)
|
||||
#else
|
||||
#define DLLAPI __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
** CONSTANTS
|
||||
*/
|
||||
|
||||
/*
|
||||
** RT_FEELIT - Resource type for IFR projects stored as resources.
|
||||
** This is the resource type looked for by IFLoadProjectResource().
|
||||
*/
|
||||
#define RT_FEELIT ((LPCSTR)"FEELIT")
|
||||
|
||||
|
||||
/*
|
||||
** TYPES/STRUCTURES
|
||||
*/
|
||||
|
||||
/*
|
||||
** HIFRPROJECT - used to identify a loaded project as a whole.
|
||||
** individual objects within a project are uniquely referenced by name.
|
||||
** Created by the IFLoadProject*() functions and released by IFReleaseProject().
|
||||
*/
|
||||
typedef LPVOID HIFRPROJECT;
|
||||
|
||||
/*
|
||||
** IFREffect - contains the information needed to create a DI effect
|
||||
** using IDirectInputEffect::CreateEffect(). An array of pointers to these
|
||||
** structures is allocated and returned by IFCreateEffectStructs().
|
||||
*/
|
||||
typedef struct {
|
||||
GUID guid;
|
||||
LPFEELIT_EFFECT lpDIEffect;
|
||||
} IFREffect;
|
||||
|
||||
|
||||
/*
|
||||
** FUNCTION DECLARATIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
** IFLoadProjectResource() - Load a project from a resource.
|
||||
** hRsrcModule - handle of the module containing the project definition resource.
|
||||
** pRsrcName - name or MAKEINTRESOURCE(id) identifier of resource to load.
|
||||
** pDevice - device for which the project is being loaded. If NULL,
|
||||
** effects will be created generically, and IFCreateEffects() will fail.
|
||||
** Returns an identifier for the loaded project, or NULL if unsuccessful.
|
||||
*/
|
||||
DLLAPI
|
||||
HIFRPROJECT
|
||||
IFRAPI
|
||||
IFRLoadProjectResource(
|
||||
HMODULE hRsrcModule,
|
||||
LPCSTR pRsrcName,
|
||||
LPIFEELIT_DEVICE pDevice );
|
||||
|
||||
/*
|
||||
** IFLoadProjectPointer() - Load a project from a pointer.
|
||||
** pProject - points to a project definition.
|
||||
** pDevice - device for which the project is being loaded. If NULL,
|
||||
** effects will be created generically, and IFCreateEffects() will fail.
|
||||
** Returns an identifier for the loaded project, or NULL if unsuccessful.
|
||||
*/
|
||||
DLLAPI
|
||||
HIFRPROJECT
|
||||
IFRAPI
|
||||
IFRLoadProjectPointer(
|
||||
LPVOID pProject,
|
||||
LPIFEELIT_DEVICE pDevice );
|
||||
|
||||
/*
|
||||
** IFLoadProjectFile() - Load a project from a file.
|
||||
** pProjectFileName - points to a project file name.
|
||||
** pDevice - device for which the project is being loaded. If NULL,
|
||||
** effects will be created generically, and IFCreateEffects() will fail.
|
||||
** Returns an identifier for the loaded project, or NULL if unsuccessful.
|
||||
*/
|
||||
DLLAPI
|
||||
HIFRPROJECT
|
||||
IFRAPI
|
||||
IFRLoadProjectFile(
|
||||
LPCSTR pProjectFileName,
|
||||
LPIFEELIT_DEVICE pDevice );
|
||||
|
||||
/*
|
||||
** IFLoadProjectObjectPointer() - Load a project from a pointer to a single
|
||||
** object definition (usually used only by the editor).
|
||||
** pObject - points to an object definition.
|
||||
** pDevice - device for which the project is being loaded. If NULL,
|
||||
** effects will be created generically, and IFCreateEffects() will fail.
|
||||
** Returns an identifier for the loaded project, or NULL if unsuccessful.
|
||||
*/
|
||||
DLLAPI
|
||||
HIFRPROJECT
|
||||
IFRAPI
|
||||
IFRLoadProjectObjectPointer(
|
||||
LPVOID pObject,
|
||||
LPIFEELIT_DEVICE pDevice );
|
||||
|
||||
/*
|
||||
** IFReleaseProject() - Release a loaded project.
|
||||
** hProject - identifies the project to be released.
|
||||
** Returns TRUE if the project is released, FALSE if it is an invalid project.
|
||||
*/
|
||||
DLLAPI
|
||||
BOOL
|
||||
IFRAPI
|
||||
IFRReleaseProject(
|
||||
HIFRPROJECT hProject );
|
||||
|
||||
/*
|
||||
** IFCreateEffectStructs() - Create IFREffects for a named effect.
|
||||
** hProject - identifies the project containing the object.
|
||||
** pObjectName - name of the object for which to create structures.
|
||||
** pNumEffects - if not NULL will be set to a count of the IFREffect
|
||||
** structures in the array (not including the terminating NULL pointer.)
|
||||
** Returns a pointer to the allocated array of pointers to IFREffect
|
||||
** structures. The array is terminated with a NULL pointer. If the
|
||||
** function fails, a NULL pointer is returned.
|
||||
*/
|
||||
DLLAPI
|
||||
IFREffect **
|
||||
IFRAPI
|
||||
IFRCreateEffectStructs(
|
||||
HIFRPROJECT hProject,
|
||||
LPCSTR pObjectName,
|
||||
int *pNumEffects );
|
||||
|
||||
DLLAPI
|
||||
IFREffect **
|
||||
IFRAPI
|
||||
IFRCreateEffectStructsByIndex(
|
||||
HIFRPROJECT hProject,
|
||||
int nObjectIndex,
|
||||
int *pNumEffects );
|
||||
|
||||
DLLAPI
|
||||
LPCSTR
|
||||
IFRAPI
|
||||
IFRGetObjectNameByIndex(
|
||||
HIFRPROJECT hProject,
|
||||
int nObjectIndex );
|
||||
|
||||
/*
|
||||
** IFReleaseEffectStructs() - Release an array of IFREffects.
|
||||
** hProject - identifies the project for which the effects were created.
|
||||
** pEffects - points to the array of IFREffect pointers to be released.
|
||||
** Returns TRUE if the array is released, FALSE if it is an invalid array.
|
||||
*/
|
||||
DLLAPI
|
||||
BOOL
|
||||
IFRAPI
|
||||
IFRReleaseEffectStructs(
|
||||
HIFRPROJECT hProject,
|
||||
IFREffect **pEffects );
|
||||
|
||||
/*
|
||||
** IFCreateEffects() - Creates the DirectInput effects using
|
||||
** IDirectInput::CreateEffect().
|
||||
** hProject - identifies the project containing the object.
|
||||
** pObjectName - name of the object for which to create effects.
|
||||
** pNumEffects - if not NULL will be set to a count of the IDirectInputEffect
|
||||
** pointers in the array (not including the terminating NULL pointer.)
|
||||
** Returns a pointer to the allocated array of pointers to IDirectInputEffects.
|
||||
** The array is terminated with a NULL pointer. If the function fails,
|
||||
** a NULL pointer is returned.
|
||||
*/
|
||||
DLLAPI
|
||||
LPIFEELIT_EFFECT *
|
||||
IFRAPI
|
||||
IFRCreateEffects(
|
||||
HIFRPROJECT hProject,
|
||||
LPCSTR pObjectName,
|
||||
int *pNumEffects );
|
||||
|
||||
/*
|
||||
** IFReleaseEffects() - Releases an array of IDirectInputEffect structures.
|
||||
** hProject - identifies the project for which the effects were created.
|
||||
** pEffects - points to the array if IDirectInputEffect pointers to be released.
|
||||
** Returns TRUE if the array is released, FALSE if it is an invalid array.
|
||||
*/
|
||||
DLLAPI
|
||||
BOOL
|
||||
IFRAPI
|
||||
IFRReleaseEffects(
|
||||
HIFRPROJECT hProject,
|
||||
LPIFEELIT_EFFECT *pEffects );
|
||||
|
||||
DLLAPI
|
||||
BOOL
|
||||
IFRAPI
|
||||
DllMain(
|
||||
HINSTANCE hInstDLL,
|
||||
DWORD fdwReason,
|
||||
LPVOID lpvReserved );
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* !IForce2_h */
|
||||
78
code/win32/FeelIt/FFC.h
Normal file
78
code/win32/FeelIt/FFC.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997,8,9 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FFC.h
|
||||
|
||||
PURPOSE: Class Types for the Force Foundation Classes
|
||||
|
||||
STARTED: 10/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
|
||||
#include "FeelBox.h"
|
||||
#include "FeelCondition.h"
|
||||
#include "FeelConstant.h"
|
||||
#include "FeelDamper.h"
|
||||
#include "FeelDevice.h"
|
||||
#include "FeelDXDevice.h"
|
||||
#include "FeelEffect.h"
|
||||
#include "FeelEllipse.h"
|
||||
#include "FeelEnclosure.h"
|
||||
#include "FeelMouse.h"
|
||||
#include "FeelFriction.h"
|
||||
#include "FeelGrid.h"
|
||||
#include "FeelInertia.h"
|
||||
#include "FeelPeriodic.h"
|
||||
#include "FeelProjects.h"
|
||||
#include "FeelRamp.h"
|
||||
#include "FeelSpring.h"
|
||||
#include "FeelTexture.h"
|
||||
#include "FFCErrors.h"
|
||||
|
||||
|
||||
#endif // !defined(AFX_FFC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
code/win32/FeelIt/FFC10.dll
Normal file
BIN
code/win32/FeelIt/FFC10.dll
Normal file
Binary file not shown.
BIN
code/win32/FeelIt/FFC10.lib
Normal file
BIN
code/win32/FeelIt/FFC10.lib
Normal file
Binary file not shown.
BIN
code/win32/FeelIt/FFC10d.dll
Normal file
BIN
code/win32/FeelIt/FFC10d.dll
Normal file
Binary file not shown.
BIN
code/win32/FeelIt/FFC10d.lib
Normal file
BIN
code/win32/FeelIt/FFC10d.lib
Normal file
Binary file not shown.
171
code/win32/FeelIt/FFCErrors.h
Normal file
171
code/win32/FeelIt/FFCErrors.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1999 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FFCErrors.h
|
||||
|
||||
PURPOSE: Error codes returned in FFC; Error handling in FFC
|
||||
|
||||
STARTED: 2/28/99 by Jeff Mallett
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/6/99 jrm: Added user error handling control
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(FFCERRORS_H__INCLUDED_)
|
||||
#define FFCERRORS_H__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <winerror.h>
|
||||
#include "FeelBaseTypes.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Error Codes
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
FFC_ERR_OK = 0,
|
||||
|
||||
FFC_ERR_UNKNOWN_ERROR = 1,
|
||||
|
||||
FFC_ERR_ALLOCATION_FAILED = 2,
|
||||
FFC_ERR_INVALID_PARAMETER = 3,
|
||||
FFC_ERR_NULL_PARAMETER = 4,
|
||||
FFC_ERR_WRONG_FORM = 5,
|
||||
|
||||
FFC_ERR_DEVICE_IS_NULL = 6,
|
||||
FFC_ERR_INVALID_GUID = 7,
|
||||
FFC_ERR_EFFECT_NOT_INITIALIZED = 8,
|
||||
|
||||
FFC_ERR_CANT_INITIALIZE_DEVICE = 9,
|
||||
|
||||
FFC_ERR_CANT_CREATE_EFFECT = 10,
|
||||
FFC_ERR_CANT_CREATE_EFFECT_FROM_IFR = 11,
|
||||
FFC_ERR_NO_EFFECTS_FOUND = 12,
|
||||
FFC_ERR_EFFECT_IS_COMPOUND = 13,
|
||||
|
||||
FFC_ERR_PROJECT_ALREADY_OPEN = 14,
|
||||
FFC_ERR_PROJECT_NOT_OPEN = 15
|
||||
} FFC_ERROR_CODE;
|
||||
|
||||
typedef enum {
|
||||
FFC_OUTPUT_ERR_TO_DEBUG = 0x0001,
|
||||
FFC_OUTPUT_ERR_TO_DIALOG = 0x0002
|
||||
} FFC_ERROR_HANDLING_FLAGS;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// ------ PUBLIC MACROS ------
|
||||
//
|
||||
#define FFC_GET_LAST_ERROR CFFCErrors::GetLastErrorCode()
|
||||
#define FFC_SET_ERROR_HANDLING CFFCErrors::SetErrorHandling
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE MACROS ------
|
||||
//
|
||||
#if (FFC_VERSION >= 0x0110)
|
||||
#define FFC_SET_ERROR(err) CFFCErrors::SetErrorCode(err, __FILE__, __LINE__)
|
||||
#else
|
||||
#define FFC_SET_ERROR(err) CFFCErrors::SetErrorCode(err)
|
||||
#endif
|
||||
#define FFC_CLEAR_ERROR FFC_SET_ERROR(FFC_ERR_OK)
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* CFFCErrors
|
||||
*
|
||||
****************************************************************************/
|
||||
// All members are static. Don't bother instantiating an object of this class.
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFFCErrors
|
||||
{
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
static HRESULT
|
||||
GetLastErrorCode()
|
||||
{ return m_Err; }
|
||||
|
||||
static void
|
||||
SetErrorHandling(unsigned long dwFlags)
|
||||
{ m_dwErrHandlingFlags = dwFlags; }
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
// Internally used by FFC classes
|
||||
static void
|
||||
SetErrorCode(
|
||||
HRESULT err
|
||||
#if (FFC_VERSION >= 0x0110)
|
||||
, const char *sFile, int nLine
|
||||
#endif
|
||||
);
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
private:
|
||||
|
||||
static HRESULT m_Err;
|
||||
static unsigned long m_dwErrHandlingFlags;
|
||||
};
|
||||
|
||||
|
||||
#endif // FFCERRORS_H__INCLUDED_
|
||||
265
code/win32/FeelIt/FeelBaseTypes.h
Normal file
265
code/win32/FeelIt/FeelBaseTypes.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelBaseTypes.h
|
||||
|
||||
PURPOSE: Base Types for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 10/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
//#include <windows.h>
|
||||
#include "FeelitApi.h"
|
||||
|
||||
#ifndef FFC_VERSION
|
||||
#define FFC_VERSION 0x0100
|
||||
#endif
|
||||
|
||||
#if (FFC_VERSION >= 0x0110)
|
||||
#define FFC_START_DELAY
|
||||
#define FFC_EFFECT_CACHING
|
||||
#endif
|
||||
|
||||
// These are defined in FEELitAPI.h
|
||||
//
|
||||
// #define FEELIT_DEVICETYPE_DEVICE 1
|
||||
// #define FEELIT_DEVICETYPE_MOUSE 2
|
||||
// #define FEELIT_DEVICETYPE_HID 0x00010000
|
||||
//
|
||||
// Add define for DirectInput Device emulating FEELit Device
|
||||
#define FEELIT_DEVICETYPE_DIRECTINPUT 3
|
||||
|
||||
|
||||
//================================================================
|
||||
// TYPE WRAPPERS
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// FEEL --> FEELIT Wrappers
|
||||
//
|
||||
#define FEEL_DEVICETYPE_DEVICE FEELIT_DEVICETYPE_DEVICE
|
||||
#define FEEL_DEVICETYPE_MOUSE FEELIT_DEVICETYPE_MOUSE
|
||||
#define FEEL_DEVICETYPE_DIRECTINPUT FEELIT_DEVICETYPE_DIRECTINPUT
|
||||
|
||||
#define FEEL_EFFECT FEELIT_EFFECT
|
||||
#define LPFEEL_EFFECT LPFEELIT_EFFECT
|
||||
#define LPCFEEL_EFFECT LPCFEELIT_EFFECT
|
||||
|
||||
#define FEEL_CONDITION FEELIT_CONDITION
|
||||
#define LPFEEL_CONDITION LPFEELIT_CONDITION
|
||||
#define LPCFEEL_CONDITION LPCFEELIT_CONDITION
|
||||
|
||||
#define FEEL_TEXTURE FEELIT_TEXTURE
|
||||
#define LPFEEL_TEXTURE LPFEELIT_TEXTURE
|
||||
#define LPCFEEL_TEXTURE LPCFEELIT_TEXTURE
|
||||
|
||||
#define FEEL_PERIODIC FEELIT_PERIODIC
|
||||
#define LPFEEL_PERIODIC LPFEELIT_PERIODIC
|
||||
#define LPCFEEL_PERIODIC LPCFEELIT_PERIODIC
|
||||
|
||||
#define FEEL_CONSTANTFORCE FEELIT_CONSTANTFORCE
|
||||
#define LPFEEL_CONSTANTFORCE LPFEELIT_CONSTANTFORCE
|
||||
#define LPCFEEL_CONSTANTFORCE LPCFEELIT_CONSTANTFORCE
|
||||
|
||||
#define FEEL_RAMPFORCE FEELIT_RAMPFORCE
|
||||
#define LPFEEL_RAMPFORCE LPFEELIT_RAMPFORCE
|
||||
#define LPCFEEL_RAMPFORCE LPCFEELIT_RAMPFORCE
|
||||
|
||||
#define FEEL_ENVELOPE FEELIT_ENVELOPE
|
||||
#define LPFEEL_ENVELOPE LPFEELIT_ENVELOPE
|
||||
#define LPCFEEL_ENVELOPE LPCFEELIT_ENVELOPE
|
||||
|
||||
#define LPIFEEL_API LPIFEELIT
|
||||
#define LPIFEEL_EFFECT LPIFEELIT_EFFECT
|
||||
#define LPIFEEL_DEVICE LPIFEELIT_DEVICE
|
||||
|
||||
#define LPFEEL_DEVICEINSTANCE LPFEELIT_DEVICEINSTANCE
|
||||
#define LPCFEEL_DEVICEOBJECTINSTANCE LPCFEELIT_DEVICEOBJECTINSTANCE
|
||||
#define LPCFEEL_EFFECTINFO LPCFEELIT_EFFECTINFO
|
||||
|
||||
|
||||
#define FEEL_FPARAM_DURATION FEELIT_FPARAM_DURATION
|
||||
#define FEEL_FPARAM_SAMPLEPERIOD FEELIT_FPARAM_SAMPLEPERIOD
|
||||
#define FEEL_FPARAM_GAIN FEELIT_FPARAM_GAIN
|
||||
#define FEEL_FPARAM_TRIGGERBUTTON FEELIT_FPARAM_TRIGGERBUTTON
|
||||
#define FEEL_FPARAM_TRIGGERREPEATINTERVAL FEELIT_FPARAM_TRIGGERREPEATINTERVAL
|
||||
#define FEEL_FPARAM_AXES FEELIT_FPARAM_AXES
|
||||
#define FEEL_FPARAM_DIRECTION FEELIT_FPARAM_DIRECTION
|
||||
#define FEEL_FPARAM_ENVELOPE FEELIT_FPARAM_ENVELOPE
|
||||
#define FEEL_FPARAM_TYPESPECIFICPARAMS FEELIT_FPARAM_TYPESPECIFICPARAMS
|
||||
#define FEEL_FPARAM_ALLPARAMS FEELIT_FPARAM_ALLPARAMS
|
||||
#define FEEL_FPARAM_START FEELIT_FPARAM_START
|
||||
#define FEEL_FPARAM_NORESTART FEELIT_FPARAM_NORESTART
|
||||
#define FEEL_FPARAM_NODOWNLOAD FEELIT_FPARAM_NODOWNLOAD
|
||||
|
||||
#define FEEL_FEFFECT_OBJECTIDS FEELIT_FEFFECT_OBJECTIDS
|
||||
#define FEEL_FEFFECT_OBJECTOFFSETS FEELIT_FEFFECT_OBJECTOFFSETS
|
||||
#define FEEL_FEFFECT_CARTESIAN FEELIT_FEFFECT_CARTESIAN
|
||||
#define FEEL_FEFFECT_POLAR FEELIT_FEFFECT_POLAR
|
||||
#define FEEL_FEFFECT_SPHERICAL FEELIT_FEFFECT_SPHERICAL
|
||||
|
||||
#define FEEL_PARAM_NOTRIGGER FEELIT_PARAM_NOTRIGGER
|
||||
|
||||
#define FEEL_MOUSEOFFSET_XAXIS FEELIT_MOUSEOFFSET_XAXIS
|
||||
#define FEEL_MOUSEOFFSET_YAXIS FEELIT_MOUSEOFFSET_YAXIS
|
||||
#define FEEL_MOUSEOFFSET_ZAXIS FEELIT_MOUSEOFFSET_ZAXIS
|
||||
|
||||
//
|
||||
// FORCE --> FEELIT Wrappers
|
||||
//
|
||||
#define FORCE_EFFECT FEELIT_EFFECT
|
||||
#define LPFORCE_EFFECT LPFEELIT_EFFECT
|
||||
#define LPCFORCE_EFFECT LPCFEELIT_EFFECT
|
||||
|
||||
#define FORCE_CONDITION FEELIT_CONDITION
|
||||
#define LPFORCE_CONDITION LPFEELIT_CONDITION
|
||||
#define LPCFORCE_CONDITION LPCFEELIT_CONDITION
|
||||
|
||||
#define FORCE_TEXTURE FEELIT_TEXTURE
|
||||
#define LPFORCE_TEXTURE LPFEELIT_TEXTURE
|
||||
#define LPCFORCE_TEXTURE LPCFEELIT_TEXTURE
|
||||
|
||||
#define FORCE_PERIODIC FEELIT_PERIODIC
|
||||
#define LPFORCE_PERIODIC LPFEELIT_PERIODIC
|
||||
#define LPCFORCE_PERIODIC LPCFEELIT_PERIODIC
|
||||
|
||||
#define FORCE_CONSTANTFORCE FEELIT_CONSTANTFORCE
|
||||
#define LPFORCE_CONSTANTFORCE LPFEELIT_CONSTANTFORCE
|
||||
#define LPCFORCE_CONSTANTFORCE LPCFEELIT_CONSTANTFORCE
|
||||
|
||||
#define FORCE_RAMPFORCE FEELIT_RAMPFORCE
|
||||
#define LPFORCE_RAMPFORCE LPFEELIT_RAMPFORCE
|
||||
#define LPCFORCE_RAMPFORCE LPCFEELIT_RAMPFORCE
|
||||
|
||||
#define FORCE_ENVELOPE FEELIT_ENVELOPE
|
||||
#define LPFORCE_ENVELOPE LPFEELIT_ENVELOPE
|
||||
#define LPCFORCE_ENVELOPE LPCFEELIT_ENVELOPE
|
||||
|
||||
#define LPIFORCE_API LPIFEELIT
|
||||
#define LPIFORCE_EFFECT LPIFEELIT_EFFECT
|
||||
#define LPIFORCE_DEVICE LPIFEELIT_DEVICE
|
||||
|
||||
#define LPFORCE_DEVICEINSTANCE LPFEELIT_DEVICEINSTANCE
|
||||
#define LPCFORCE_DEVICEOBJECTINSTANCE LPCFEELIT_DEVICEOBJECTINSTANCE
|
||||
#define LPCFORCE_EFFECTINFO LPCFEELIT_EFFECTINFO
|
||||
|
||||
|
||||
#define FORCE_FPARAM_DURATION FEELIT_FPARAM_DURATION
|
||||
#define FORCE_FPARAM_SAMPLEPERIOD FEELIT_FPARAM_SAMPLEPERIOD
|
||||
#define FORCE_FPARAM_GAIN FEELIT_FPARAM_GAIN
|
||||
#define FORCE_FPARAM_TRIGGERBUTTON FEELIT_FPARAM_TRIGGERBUTTON
|
||||
#define FORCE_FPARAM_TRIGGERREPEATINTERVAL FEELIT_FPARAM_TRIGGERREPEATINTERVAL
|
||||
#define FORCE_FPARAM_AXES FEELIT_FPARAM_AXES
|
||||
#define FORCE_FPARAM_DIRECTION FEELIT_FPARAM_DIRECTION
|
||||
#define FORCE_FPARAM_ENVELOPE FEELIT_FPARAM_ENVELOPE
|
||||
#define FORCE_FPARAM_TYPESPECIFICPARAMS FEELIT_FPARAM_TYPESPECIFICPARAMS
|
||||
#define FORCE_FPARAM_ALLPARAMS FEELIT_FPARAM_ALLPARAMS
|
||||
#define FORCE_FPARAM_START FEELIT_FPARAM_START
|
||||
#define FORCE_FPARAM_NORESTART FEELIT_FPARAM_NORESTART
|
||||
#define FORCE_FPARAM_NODOWNLOAD FEELIT_FPARAM_NODOWNLOAD
|
||||
|
||||
#define FORCE_FEFFECT_OBJECTIDS FEELIT_FEFFECT_OBJECTIDS
|
||||
#define FORCE_FEFFECT_OBJECTOFFSETS FEELIT_FEFFECT_OBJECTOFFSETS
|
||||
#define FORCE_FEFFECT_CARTESIAN FEELIT_FEFFECT_CARTESIAN
|
||||
#define FORCE_FEFFECT_POLAR FEELIT_FEFFECT_POLAR
|
||||
#define FORCE_FEFFECT_SPHERICAL FEELIT_FEFFECT_SPHERICAL
|
||||
|
||||
#define FORCE_PARAM_NOTRIGGER FEELIT_PARAM_NOTRIGGER
|
||||
|
||||
#define FORCE_MOUSEOFFSET_XAXIS FEELIT_MOUSEOFFSET_XAXIS
|
||||
#define FORCE_MOUSEOFFSET_YAXIS FEELIT_MOUSEOFFSET_YAXIS
|
||||
#define FORCE_MOUSEOFFSET_ZAXIS FEELIT_MOUSEOFFSET_ZAXIS
|
||||
|
||||
|
||||
//================================================================
|
||||
// GUID WRAPPERS
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// Feel --> Feelit Wrappers
|
||||
//
|
||||
#define GUID_Feel_ConstantForce GUID_Feelit_ConstantForce
|
||||
#define GUID_Feel_RampForce GUID_Feelit_RampForce
|
||||
#define GUID_Feel_Square GUID_Feelit_Square
|
||||
#define GUID_Feel_Sine GUID_Feelit_Sine
|
||||
#define GUID_Feel_Triangle GUID_Feelit_Triangle
|
||||
#define GUID_Feel_SawtoothUp GUID_Feelit_SawtoothUp
|
||||
#define GUID_Feel_SawtoothDown GUID_Feelit_SawtoothDown
|
||||
#define GUID_Feel_Spring GUID_Feelit_Spring
|
||||
#define GUID_Feel_DeviceSpring GUID_Feelit_DeviceSpring
|
||||
#define GUID_Feel_Damper GUID_Feelit_Damper
|
||||
#define GUID_Feel_Inertia GUID_Feelit_Inertia
|
||||
#define GUID_Feel_Friction GUID_Feelit_Friction
|
||||
#define GUID_Feel_Texture GUID_Feelit_Texture
|
||||
#define GUID_Feel_Grid GUID_Feelit_Grid
|
||||
#define GUID_Feel_Enclosure GUID_Feelit_Enclosure
|
||||
#define GUID_Feel_Ellipse GUID_Feelit_Ellipse
|
||||
#define GUID_Feel_CustomForce GUID_Feelit_CustomForce
|
||||
|
||||
//
|
||||
// Force --> Feelit Wrappers
|
||||
//
|
||||
#define GUID_Force_ConstantForce GUID_Feelit_ConstantForce
|
||||
#define GUID_Force_RampForce GUID_Feelit_RampForce
|
||||
#define GUID_Force_Square GUID_Feelit_Square
|
||||
#define GUID_Force_Sine GUID_Feelit_Sine
|
||||
#define GUID_Force_Triangle GUID_Feelit_Triangle
|
||||
#define GUID_Force_SawtoothUp GUID_Feelit_SawtoothUp
|
||||
#define GUID_Force_SawtoothDown GUID_Feelit_SawtoothDown
|
||||
#define GUID_Force_Spring GUID_Feelit_Spring
|
||||
#define GUID_Force_Damper GUID_Feelit_Damper
|
||||
#define GUID_Force_Inertia GUID_Feelit_Inertia
|
||||
#define GUID_Force_Friction GUID_Feelit_Friction
|
||||
#define GUID_Force_Texture GUID_Feelit_Texture
|
||||
#define GUID_Force_Grid GUID_Feelit_Grid
|
||||
#define GUID_Force_Enclosure GUID_Feelit_Enclosure
|
||||
#define GUID_Force_Ellipse GUID_Feelit_Ellipse
|
||||
#define GUID_Force_CustomForce GUID_Feelit_CustomForce
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELBASETYPES_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
178
code/win32/FeelIt/FeelBox.h
Normal file
178
code/win32/FeelIt/FeelBox.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelBox.h
|
||||
|
||||
PURPOSE: Box Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 11/04/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
#include "FeelEnclosure.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
const POINT FEEL_BOX_MOUSE_POS_AT_START = { MAXLONG, MAXLONG };
|
||||
|
||||
#define FEEL_BOX_DEFAULT_STIFFNESS 5000
|
||||
#define FEEL_BOX_DEFAULT_WIDTH 10
|
||||
#define FEEL_BOX_DEFAULT_HEIGHT FEEL_ENCLOSURE_HEIGHT_AUTO
|
||||
#define FEEL_BOX_DEFAULT_WALL_WIDTH FEEL_ENCLOSURE_WALL_WIDTH_AUTO
|
||||
|
||||
#define FEEL_BOX_DEFAULT_CENTER_POINT FEEL_BOX_MOUSE_POS_AT_START
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_BOX_MOUSE_POS_AT_START FEEL_BOX_DEFAULT_STIFFNESS
|
||||
|
||||
#define FORCE_BOX_DEFAULT_STIFFNESS FEEL_BOX_DEFAULT_STIFFNESS
|
||||
#define FORCE_BOX_DEFAULT_WIDTH FEEL_BOX_DEFAULT_WIDTH
|
||||
#define FORCE_BOX_DEFAULT_HEIGHT FEEL_BOX_DEFAULT_HEIGHT
|
||||
#define FORCE_BOX_DEFAULT_WALL_WIDTH FEEL_BOX_DEFAULT_WALL_WIDTH
|
||||
|
||||
#define FORCE_BOX_DEFAULT_CENTER_POINT FEEL_BOX_DEFAULT_CENTER_POINT
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelBox
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelBox : public CFeelEnclosure
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelBox();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelBox();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
POINT pntCenter,
|
||||
LONG lStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwHeight = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
LPCRECT pRectOutside,
|
||||
LONG lStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwWidth = FEEL_ENCLOSURE_DEFAULT_WIDTH,
|
||||
DWORD dwHeight = FEEL_ENCLOSURE_DEFAULT_HEIGHT,
|
||||
LONG lStiffness = FEEL_BOX_DEFAULT_STIFFNESS,
|
||||
DWORD dwWallWidth = FEEL_BOX_DEFAULT_WALL_WIDTH,
|
||||
POINT pntCenter = FEEL_BOX_DEFAULT_CENTER_POINT,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LPCRECT pRectOutside,
|
||||
LONG lStiffness = FEEL_BOX_DEFAULT_STIFFNESS,
|
||||
DWORD dwWallWidth = FEEL_BOX_DEFAULT_WALL_WIDTH,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELBOX_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
184
code/win32/FeelIt/FeelCompoundEffect.h
Normal file
184
code/win32/FeelIt/FeelCompoundEffect.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1999 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelCompoundEffect.h
|
||||
|
||||
PURPOSE: Manages Compound Effects for Force Foundation Classes
|
||||
|
||||
STARTED: 2/24/99 by Jeff Mallett
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(__FEELCOMPOUNDEFFECT_H)
|
||||
#define __FEELCOMPOUNDEFFECT_H
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
#include "FeelitIFR.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelCompoundEffect
|
||||
//================================================================
|
||||
// Represents a compound effect, such as might be created in
|
||||
// I-FORCE Studio. Contains an array of effect objects.
|
||||
// Methods iterate over component effects, passing the message
|
||||
// to each one.
|
||||
// Also, has stuff for being used by CFeelProject:
|
||||
// * next pointer so can be put on a linked list
|
||||
// * force name
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelCompoundEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
protected:
|
||||
// Constructs a CFeelCompoundEffect
|
||||
// Don't try to construct a CFeelCompoundEffect yourself.
|
||||
// Instead let CFeelProject construct it for you.
|
||||
CFeelCompoundEffect(
|
||||
IFREffect **hEffects,
|
||||
long nEffects
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
~CFeelCompoundEffect();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
long
|
||||
GetNumberOfContainedEffects() const
|
||||
{ return m_nEffects; }
|
||||
|
||||
const char *
|
||||
GetName() const
|
||||
{ return m_lpszName; }
|
||||
|
||||
GENERIC_EFFECT_PTR
|
||||
GetContainedEffect(
|
||||
long index
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Start all the contained effects
|
||||
BOOL Start(
|
||||
DWORD dwIterations = 1,
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
|
||||
// Stop all the contained effects
|
||||
BOOL Stop();
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL initialize(
|
||||
CFeelDevice* pDevice,
|
||||
IFREffect **hEffects
|
||||
);
|
||||
|
||||
BOOL
|
||||
set_contained_effect(
|
||||
GENERIC_EFFECT_PTR pObject,
|
||||
int index = 0
|
||||
);
|
||||
|
||||
BOOL
|
||||
set_name(
|
||||
const char *lpszName
|
||||
);
|
||||
|
||||
void
|
||||
set_next(
|
||||
CFeelCompoundEffect *pNext
|
||||
)
|
||||
{ m_pNext = pNext; }
|
||||
|
||||
CFeelCompoundEffect *
|
||||
get_next() const
|
||||
{ return m_pNext; }
|
||||
|
||||
|
||||
//
|
||||
// FRIENDS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
friend class CFeelProject;
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
GENERIC_EFFECT_PTR *m_paEffects; // Array of force class object pointers
|
||||
long m_nEffects; // Number of effects in m_paEffects
|
||||
|
||||
private:
|
||||
|
||||
char *m_lpszName; // Name of the compound effect
|
||||
CFeelCompoundEffect *m_pNext; // Next compound effect in the project
|
||||
};
|
||||
|
||||
#endif
|
||||
345
code/win32/FeelIt/FeelCondition.h
Normal file
345
code/win32/FeelIt/FeelCondition.h
Normal file
@@ -0,0 +1,345 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelCondition.h
|
||||
|
||||
PURPOSE: Base Condition Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELCONDITION_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELCONDITION_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
const POINT FEEL_CONDITION_PT_NULL = { 0, 0 };
|
||||
|
||||
#define FEEL_CONDITION_DEFAULT_COEFFICIENT 2500
|
||||
#define FEEL_CONDITION_DEFAULT_SATURATION 10000
|
||||
#define FEEL_CONDITION_DEFAULT_DEADBAND 100
|
||||
#define FEEL_CONDITION_DEFAULT_CENTER_POINT FEEL_EFFECT_MOUSE_POS_AT_START
|
||||
#define FEEL_CONDITION_DEFAULT_DURATION INFINITE
|
||||
|
||||
typedef enum {
|
||||
FC_NULL = 0,
|
||||
FC_POSITIVE_COEFFICIENT,
|
||||
FC_NEGATIVE_COEFFICIENT,
|
||||
FC_POSITIVE_SATURATION,
|
||||
FC_NEGATIVE_SATURATION,
|
||||
FC_DEAD_BAND,
|
||||
FC_AXIS,
|
||||
FC_CENTER,
|
||||
FC_DIRECTION_X,
|
||||
FC_DIRECTION_Y,
|
||||
FC_ANGLE,
|
||||
FC_CONDITION_X,
|
||||
FC_CONDITION_Y
|
||||
} FC_ArgumentType;
|
||||
|
||||
#define FC_CONDITION FC_CONDITION_X
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_CONDITION_PT_NULL FEEL_CONDITION_PT_NULL
|
||||
|
||||
#define FORCE_CONDITION_DEFAULT_COEFFICIENT FEEL_CONDITION_DEFAULT_COEFFICIENT
|
||||
#define FORCE_CONDITION_DEFAULT_SATURATION FEEL_CONDITION_DEFAULT_SATURATION
|
||||
#define FORCE_CONDITION_DEFAULT_DEADBAND FEEL_CONDITION_DEFAULT_DEADBAND
|
||||
#define FORCE_CONDITION_DEFAULT_CENTER_POINT FEEL_CONDITION_DEFAULT_CENTER_POINT
|
||||
#define FORCE_CONDITION_DEFAULT_DURATION FEEL_CONDITION_DEFAULT_DURATION
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelCondition
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelCondition : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelCondition(
|
||||
const GUID& rguidEffect
|
||||
);
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelCondition();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
// Use this form for single-axis and dual-axis effects
|
||||
BOOL
|
||||
ChangeConditionParams(
|
||||
LPCFEELIT_CONDITION pConditionX,
|
||||
LPCFEELIT_CONDITION pConditionY
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
ChangeConditionParams(
|
||||
LPCFEELIT_CONDITION pCondition,
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
ChangeConditionParamsPolar(
|
||||
LPCFEELIT_CONDITION pCondition,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
ChangeConditionParams(
|
||||
LONG lPositiveCoefficient,
|
||||
LONG lNegativeCoefficient = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPositiveSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwNegativeSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDeadBand = FEEL_EFFECT_DONT_CHANGE,
|
||||
POINT pntCenter = FEEL_EFFECT_DONT_CHANGE_POINT,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
ChangeConditionParamsPolar(
|
||||
LONG lPositiveCoefficient,
|
||||
LONG lNegativeCoefficient,
|
||||
DWORD dwPositiveSaturation,
|
||||
DWORD dwNegativeSaturation,
|
||||
LONG lDeadBand,
|
||||
POINT pntCenter,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetCenter(
|
||||
POINT pntCenter
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeConditionParams2(
|
||||
FC_ArgumentType type,
|
||||
...
|
||||
);
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
const FEEL_EFFECT &effect
|
||||
);
|
||||
|
||||
// Use this form for single-axis and dual-axis effects
|
||||
BOOL
|
||||
InitCondition(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_CONDITION pConditionX,
|
||||
LPCFEELIT_CONDITION pConditionY,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitCondition(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_CONDITION pCondition,
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitConditionPolar(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_CONDITION pCondition,
|
||||
LONG lAngle,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
InitCondition(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lPositiveCoefficient = FEEL_CONDITION_DEFAULT_COEFFICIENT,
|
||||
LONG lNegativeCoefficient = FEEL_CONDITION_DEFAULT_COEFFICIENT,
|
||||
DWORD dwPositiveSaturation = FEEL_CONDITION_DEFAULT_SATURATION,
|
||||
DWORD dwNegativeSaturation = FEEL_CONDITION_DEFAULT_SATURATION,
|
||||
LONG lDeadBand = FEEL_CONDITION_DEFAULT_DEADBAND,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
POINT pntCenter = FEEL_CONDITION_DEFAULT_CENTER_POINT,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitConditionPolar(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lPositiveCoefficient = FEEL_CONDITION_DEFAULT_COEFFICIENT,
|
||||
LONG lNegativeCoefficient = FEEL_CONDITION_DEFAULT_COEFFICIENT,
|
||||
DWORD dwPositiveSaturation = FEEL_CONDITION_DEFAULT_SATURATION,
|
||||
DWORD dwNegativeSaturation = FEEL_CONDITION_DEFAULT_SATURATION,
|
||||
LONG lDeadBand = FEEL_CONDITION_DEFAULT_DEADBAND,
|
||||
POINT pntCenter = FEEL_CONDITION_DEFAULT_CENTER_POINT,
|
||||
LONG lAngle = FEEL_EFFECT_DEFAULT_ANGLE,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
|
||||
virtual BOOL
|
||||
#ifdef FFC_START_DELAY
|
||||
StartNow(
|
||||
#else
|
||||
Start(
|
||||
#endif
|
||||
DWORD dwIterations = 1,
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
convert_line_point_to_offset(
|
||||
POINT pntOnLine
|
||||
);
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfAxis,
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
LPCFEELIT_CONDITION pConditionX,
|
||||
LPCFEELIT_CONDITION pConditionY
|
||||
);
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfAxis,
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
LONG lPositiveCoefficient,
|
||||
LONG lNegativeCoefficient,
|
||||
DWORD dwPositiveSaturation,
|
||||
DWORD dwNegativeSaturation,
|
||||
LONG lDeadBand,
|
||||
POINT pntCenter
|
||||
);
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
FEEL_CONDITION m_aCondition[2];
|
||||
DWORD m_dwfAxis;
|
||||
BOOL m_bUseMousePosAtStart;
|
||||
|
||||
protected:
|
||||
BOOL m_bUseDeviceCoordinates;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelCondition::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Spring) ||
|
||||
IsEqualGUID(guid, GUID_Feel_DeviceSpring) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Damper) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Inertia) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Friction) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Texture) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Grid);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELCONDITION_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
193
code/win32/FeelIt/FeelConstant.h
Normal file
193
code/win32/FeelIt/FeelConstant.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelConstant.h
|
||||
|
||||
PURPOSE: Base Constant Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 11/03/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
const POINT FEEL_CONSTANT_DEFAULT_DIRECTION = { 1, 0 };
|
||||
#define FEEL_CONSTANT_DEFAULT_DURATION 1000 // Milliseconds
|
||||
#define FEEL_CONSTANT_DEFAULT_MAGNITUDE 5000
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_CONSTANT_DEFAULT_DIRECTION FEEL_CONSTANT_DEFAULT_DIRECTION
|
||||
#define FORCE_CONSTANT_DEFAULT_DURATION FEEL_CONSTANT_DEFAULT_DURATION
|
||||
#define FORCE_CONSTANT_DEFAULT_MAGNITUDE FEEL_CONSTANT_DEFAULT_MAGNITUDE
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelConstant
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelConstant : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelConstant();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelConstant();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagnitude = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
LONG lAngle,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagnitude = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y,
|
||||
DWORD dwDuration = FEEL_CONSTANT_DEFAULT_DURATION,
|
||||
LONG lMagnitude = FEEL_CONSTANT_DEFAULT_MAGNITUDE,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
virtual
|
||||
BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lArray = FEEL_EFFECT_DEFAULT_ANGLE,
|
||||
DWORD dwDuration = FEEL_CONSTANT_DEFAULT_DURATION,
|
||||
LONG lMagnitude = FEEL_CONSTANT_DEFAULT_MAGNITUDE,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
DWORD dwDuration,
|
||||
LONG lMagnitude,
|
||||
LPFEEL_ENVELOPE pEnvelope
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
FEEL_CONSTANTFORCE m_ConstantForce;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelConstant::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_ConstantForce);
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELCONSTANT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
126
code/win32/FeelIt/FeelDXDevice.h
Normal file
126
code/win32/FeelIt/FeelDXDevice.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelDXDevice.h
|
||||
|
||||
PURPOSE: Abstraction of DirectX Force Feedback device
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef FeelDXDevice_h
|
||||
#define FeelDXDevice_h
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelDevice.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelDXDevice
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelDXDevice : public CFeelDevice
|
||||
{
|
||||
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelDXDevice();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelDXDevice();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual LPIFEEL_API
|
||||
GetAPI()
|
||||
{ return (LPIFEEL_API) m_piApi; } // actually LPDIRECTINPUT
|
||||
|
||||
virtual LPIFEEL_DEVICE
|
||||
GetDevice()
|
||||
{ return (LPIFEEL_DEVICE) m_piDevice; } // actually LPDIRECTINPUTDEVICE2
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
HANDLE hinstApp,
|
||||
HANDLE hwndApp,
|
||||
LPDIRECTINPUT pDI = NULL,
|
||||
LPDIRECTINPUTDEVICE2 piDevice = NULL
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
reset();
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL m_bpDIPreExist;
|
||||
BOOL m_bpDIDevicePreExist;
|
||||
|
||||
LPDIRECTINPUT m_piApi;
|
||||
LPDIRECTINPUTDEVICE2 m_piDevice;
|
||||
};
|
||||
|
||||
#endif // ForceDXDevice_h
|
||||
177
code/win32/FeelIt/FeelDamper.h
Normal file
177
code/win32/FeelIt/FeelDamper.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997,8,9 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelDamper.h
|
||||
|
||||
PURPOSE: Feelit API Damper Effect Class
|
||||
|
||||
STARTED: 10/14/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelCondition.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_DAMPER_DEFAULT_VISCOSITY 2500
|
||||
#define FEEL_DAMPER_DEFAULT_SATURATION 10000
|
||||
#define FEEL_DAMPER_DEFAULT_MIN_VELOCITY 0
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_DAMPER_DEFAULT_VISCOSITY FEEL_DAMPER_DEFAULT_VISCOSITY
|
||||
#define FORCE_DAMPER_DEFAULT_SATURATION FEEL_DAMPER_DEFAULT_SATURATION
|
||||
#define FORCE_DAMPER_DEFAULT_MIN_VELOCITY FEEL_DAMPER_DEFAULT_MIN_VELOCITY
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelDamper
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelDamper : public CFeelCondition
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelDamper();
|
||||
|
||||
// Destructor
|
||||
virtual ~CFeelDamper();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
DWORD dwViscosity,
|
||||
DWORD dwSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwMinVelocity = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
DWORD dwViscosity,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwMinVelocity,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwViscosity = FEEL_DAMPER_DEFAULT_VISCOSITY,
|
||||
DWORD dwSaturation = FEEL_DAMPER_DEFAULT_SATURATION,
|
||||
DWORD dwMinVelocity = FEEL_DAMPER_DEFAULT_MIN_VELOCITY,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwViscosity,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwMinVelocity,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelDamper::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Damper);
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELDamper_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
196
code/win32/FeelIt/FeelDevice.h
Normal file
196
code/win32/FeelIt/FeelDevice.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelDevice.h
|
||||
|
||||
PURPOSE: Abstract Base Device Class for Force Foundation Classes
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
3/16/99 jrm: Made abstract. Moved functionality to CFeelMouse/CFeelDXDevice
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800 //[ 0x0300 | 0x0500 | 0x0700 | 0x0800 ]
|
||||
#include "dinput.h"
|
||||
#include "FeelBaseTypes.h"
|
||||
|
||||
#ifdef FFC_EFFECT_CACHING
|
||||
#include "FeelEffectSuite.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelDevice
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelDevice
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelDevice();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelDevice();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual LPIFEEL_API
|
||||
GetAPI()
|
||||
= 0; // pure virtual function
|
||||
|
||||
virtual LPIFEEL_DEVICE // Will actually return LPDIRECTINPUTDEVICE2 if non-FEELit
|
||||
GetDevice()
|
||||
= 0; // pure virtual function
|
||||
|
||||
DWORD
|
||||
GetDeviceType() const
|
||||
{ return m_dwDeviceType; }
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
static CFeelDevice *
|
||||
CreateDevice(HINSTANCE hinstApp, HWND hwndApp);
|
||||
|
||||
virtual BOOL
|
||||
ChangeScreenResolution(
|
||||
BOOL bAutoSet,
|
||||
DWORD dwXScreenSize = 0,
|
||||
DWORD dwYScreenSize = 0
|
||||
);
|
||||
|
||||
// The default state is using standard Win32 Mouse messages (e.g., WM_MOUSEMOVE)
|
||||
// and functions (e.g, GetCursorPos). Call only to switch to relative mode
|
||||
// if not using standard Win32 Mouse services (e.g., DirectInput) for mouse
|
||||
// input.
|
||||
BOOL
|
||||
UsesWin32MouseServices(
|
||||
BOOL bWin32MouseServ
|
||||
);
|
||||
|
||||
// Another syntax for SwitchToAbsoluteMode.
|
||||
// The default is Absolute mode. Call only to switch to Relative mode or
|
||||
// to switch back to Absolute mode.
|
||||
virtual BOOL
|
||||
SwitchToAbsoluteMode(
|
||||
BOOL bAbsMode
|
||||
);
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// CACHING
|
||||
//
|
||||
|
||||
#ifdef FFC_EFFECT_CACHING
|
||||
public:
|
||||
|
||||
void Cache_AddEffect(CFeelEffect *pFeelEffect);
|
||||
void Cache_RemoveEffect(const CFeelEffect *pFeelEffect);
|
||||
void Cache_SwapOutEffect();
|
||||
|
||||
protected:
|
||||
|
||||
void Cache_LoadEffectSuite(CFeelEffectSuite *pSuite, BOOL bCreateOnDevice);
|
||||
void Cache_UnloadEffectSuite(CFeelEffectSuite *pSuite, BOOL bUnloadFromDevice);
|
||||
|
||||
CEffectList m_Cache; // List of all effects created on device
|
||||
#endif
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
// Performs device preparation by setting the device's parameters
|
||||
virtual BOOL
|
||||
prepare_device();
|
||||
|
||||
virtual void
|
||||
reset()
|
||||
= 0; // pure virtual function
|
||||
|
||||
static BOOL CALLBACK
|
||||
enum_didevices_proc(
|
||||
LPDIDEVICEINSTANCE pForceDevInst,
|
||||
LPVOID pv
|
||||
);
|
||||
|
||||
static BOOL CALLBACK
|
||||
enum_devices_proc(
|
||||
LPFORCE_DEVICEINSTANCE pForceDevInst,
|
||||
LPVOID pv
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL m_bInitialized;
|
||||
DWORD m_dwDeviceType;
|
||||
GUID m_guidDevice;
|
||||
BOOL m_bGuidValid;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(AFX_FORCEDEVICE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
344
code/win32/FeelIt/FeelEffect.h
Normal file
344
code/win32/FeelIt/FeelEffect.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelEffect.h
|
||||
|
||||
PURPOSE: Base Effect Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID and feel_to_DI_GUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELEFFECT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELEFFECT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelDevice.h"
|
||||
class CFeelProject;
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_EFFECT_AXIS_X 1
|
||||
#define FEEL_EFFECT_AXIS_Y 2
|
||||
#define FEEL_EFFECT_AXIS_BOTH 3
|
||||
#define FEEL_EFFECT_AXIS_DIRECTIONAL 4
|
||||
#define FEEL_EFFECT_DONT_CHANGE MINLONG
|
||||
#define FEEL_EFFECT_DONT_CHANGE_PTR MAXDWORD
|
||||
const POINT FEEL_EFFECT_DONT_CHANGE_POINT = { 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
const POINT FEEL_EFFECT_MOUSE_POS_AT_START = { MAXLONG, MAXLONG };
|
||||
|
||||
#define FEEL_EFFECT_DEFAULT_ENVELOPE NULL
|
||||
#define FEEL_EFFECT_DEFAULT_DIRECTION_X 1
|
||||
#define FEEL_EFFECT_DEFAULT_DIRECTION_Y 1
|
||||
#define FEEL_EFFECT_DEFAULT_ANGLE 0
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_EFFECT_AXIS_X FEEL_EFFECT_AXIS_X
|
||||
#define FORCE_EFFECT_AXIS_Y FEEL_EFFECT_AXIS_Y
|
||||
#define FORCE_EFFECT_AXIS_BOTH FEEL_EFFECT_AXIS_BOTH
|
||||
#define FORCE_EFFECT_AXIS_DIRECTIONAL FEEL_EFFECT_AXIS_DIRECTIONAL
|
||||
#define FORCE_EFFECT_DONT_CHANGE FEEL_EFFECT_DONT_CHANGE
|
||||
#define FORCE_EFFECT_DONT_CHANGE_PTR FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
#define FORCE_EFFECT_DONT_CHANGE_POINT FEEL_EFFECT_DONT_CHANGE_POINT
|
||||
#define FORCE_EFFECT_MOUSE_POS_AT_START FEEL_EFFECT_MOUSE_POS_AT_START
|
||||
|
||||
#define FORCE_EFFECT_DEFAULT_ENVELOPE FEEL_EFFECT_DEFAULT_ENVELOPE
|
||||
#define FORCE_EFFECT_DEFAULT_DIRECTION_X FEEL_EFFECT_DEFAULT_DIRECTION_X
|
||||
#define FORCE_EFFECT_DEFAULT_DIRECTION_Y FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
#define FORCE_EFFECT_DEFAULT_ANGLE FEEL_EFFECT_DEFAULT_ANGLE
|
||||
|
||||
|
||||
|
||||
// GENERIC_EFFECT_PTR
|
||||
// This is really a pointer to a child of CFeelEffect.
|
||||
typedef class CFeelEffect * GENERIC_EFFECT_PTR;
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelEffect
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelEffect(
|
||||
const GUID& rguidEffect
|
||||
);
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelEffect();
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
LPIFEEL_EFFECT
|
||||
GetEffect()
|
||||
{ return m_piFeelitEffect; }
|
||||
|
||||
BOOL
|
||||
GetStatus(
|
||||
DWORD* pdwStatus
|
||||
)
|
||||
#if (FFC_VERSION >= 0x0110) || defined(FFC_EFFECT_CACHING)
|
||||
const
|
||||
#endif
|
||||
;
|
||||
|
||||
GUID
|
||||
GetGUID()
|
||||
{ return m_guidEffect; }
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID & /* guid */
|
||||
)
|
||||
{ return true; }
|
||||
|
||||
// Allocates an object of the correct FFC class from the given GUID
|
||||
static GENERIC_EFFECT_PTR
|
||||
NewObjectFromGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeBaseParams(
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR,
|
||||
DWORD dwSamplePeriod = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwGain = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTriggerButton = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTriggerRepeatInterval = FEEL_EFFECT_DONT_CHANGE
|
||||
#ifdef FFC_START_DELAY
|
||||
,DWORD dwStartDelay = FEEL_EFFECT_DONT_CHANGE
|
||||
#endif
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeBaseParamsPolar(
|
||||
LONG lAngle,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR,
|
||||
DWORD dwSamplePeriod = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwGain = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTriggerButton = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTriggerRepeatInterval = FEEL_EFFECT_DONT_CHANGE
|
||||
#ifdef FFC_START_DELAY
|
||||
,DWORD dwStartDelay = FEEL_EFFECT_DONT_CHANGE
|
||||
#endif
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeDirection(
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeDirection(
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetEnvelope(
|
||||
DWORD dwAttackLevel,
|
||||
DWORD dwAttackTime,
|
||||
DWORD dwFadeLevel,
|
||||
DWORD dwFadeTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SetEnvelope(
|
||||
LPFEEL_ENVELOPE pEnvelope
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
const FEEL_EFFECT &effect
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializeFromProject(
|
||||
CFeelProject &project,
|
||||
LPCSTR lpszEffectName,
|
||||
CFeelDevice* pDevice = NULL
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
Start(
|
||||
DWORD dwIterations = 1,
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
|
||||
#ifdef FFC_START_DELAY
|
||||
virtual BOOL
|
||||
StartNow(
|
||||
DWORD dwIterations = 1,
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
#endif
|
||||
|
||||
virtual BOOL
|
||||
Stop();
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// CACHING
|
||||
//
|
||||
|
||||
#ifdef FFC_EFFECT_CACHING
|
||||
|
||||
public:
|
||||
|
||||
BOOL GetIsPlaying() const;
|
||||
BOOL GetIsTriggered() const;
|
||||
short GetPriority() const { return m_Priority; }
|
||||
void SetPriority(short priority) { m_Priority = priority; }
|
||||
HRESULT Unload();
|
||||
void Reload();
|
||||
|
||||
public:
|
||||
|
||||
ECacheState m_CacheState; // effect's status in the cache
|
||||
BOOL m_bInCurrentSuite; // is the effect in the currently loaded suite?
|
||||
short m_Priority; // Priority within suite: higher number is higher priority
|
||||
DWORD m_dwLastStarted; // when last started (0 = never) or when param change made on device
|
||||
DWORD m_dwLastStopped; // when last stopped (0 = not since last start)
|
||||
DWORD m_dwLastLoaded; // when last loaded with CFeelEffectSuite::Load or Create
|
||||
|
||||
protected:
|
||||
|
||||
CFeelDevice *m_pFeelDevice; // ### Use instead of m_piFeelitDevice
|
||||
#endif
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
protected:
|
||||
|
||||
#ifdef FFC_EFFECT_CACHING
|
||||
public: // initalize needs to be called by CFeelDevice
|
||||
#endif
|
||||
BOOL
|
||||
initialize(
|
||||
CFeelDevice* pDevice
|
||||
);
|
||||
#ifdef FFC_EFFECT_CACHING
|
||||
protected:
|
||||
#endif
|
||||
|
||||
HRESULT
|
||||
set_parameters_on_device(
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
||||
void
|
||||
feel_to_DI_GUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
void
|
||||
reset();
|
||||
|
||||
void
|
||||
reset_effect_struct();
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
FEEL_EFFECT m_Effect;
|
||||
DWORD m_dwaAxes[2];
|
||||
LONG m_laDirections[2];
|
||||
|
||||
GUID m_guidEffect;
|
||||
BOOL m_bIsPlaying;
|
||||
DWORD m_dwDeviceType;
|
||||
LPIFEEL_DEVICE m_piFeelitDevice; // Might also be holding LPDIRECTINPUTDEVICE2
|
||||
LPIFEEL_EFFECT m_piFeelitEffect;
|
||||
DWORD m_cAxes; // Number of axes
|
||||
|
||||
#ifdef FFC_START_DELAY
|
||||
public:
|
||||
// Prevents access to dangling pointer when this is deleted
|
||||
// All relevent code may be removed when all hardware and drivers support start delay
|
||||
CFeelEffect **m_ppTimerRef; // pointer to pointer to this.
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#if (DIRECTINPUT_VERSION >= 0x0700)
|
||||
#define DIRECT_INPUT_STARTDELAY_SUPPORTED TRUE
|
||||
#else
|
||||
#define DIRECT_INPUT_STARTDELAY_SUPPORTED FALSE
|
||||
#endif /* DIRECTINPUT_VERSION >= 0x0700 */
|
||||
|
||||
#endif // !defined(AFX_FEELEFFECT_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
253
code/win32/FeelIt/FeelEllipse.h
Normal file
253
code/win32/FeelIt/FeelEllipse.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelEllipse.h
|
||||
|
||||
PURPOSE: Base Ellipse Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 10/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_ELLIPSE_DEFAULT_STIFFNESS 5000
|
||||
#define FEEL_ELLIPSE_DEFAULT_SATURATION 10000
|
||||
#define FEEL_ELLIPSE_DEFAULT_WIDTH 10
|
||||
#define FEEL_ELLIPSE_HEIGHT_AUTO MAXDWORD
|
||||
#define FEEL_ELLIPSE_DEFAULT_HEIGHT FEEL_ELLIPSE_HEIGHT_AUTO
|
||||
#define FEEL_ELLIPSE_WALL_WIDTH_AUTO MAXDWORD
|
||||
#define FEEL_ELLIPSE_DEFAULT_WALL_WIDTH FEEL_ELLIPSE_WALL_WIDTH_AUTO
|
||||
#define FEEL_ELLIPSE_DEFAULT_STIFFNESS_MASK FEELIT_FSTIFF_ANYWALL
|
||||
#define FEEL_ELLIPSE_DEFAULT_CLIPPING_MASK FEELIT_FCLIP_NONE
|
||||
|
||||
#define FEEL_ELLIPSE_DEFAULT_CENTER_POINT FEEL_EFFECT_MOUSE_POS_AT_START
|
||||
|
||||
//
|
||||
// FEEL --> FORCE Wrappers
|
||||
//
|
||||
#define FORCE_ELLIPSE_DEFAULT_STIFFNESS FEEL_ELLIPSE_DEFAULT_STIFFNESS
|
||||
#define FORCE_ELLIPSE_DEFAULT_SATURATION FEEL_ELLIPSE_DEFAULT_SATURATION
|
||||
#define FORCE_ELLIPSE_DEFAULT_WIDTH FEEL_ELLIPSE_DEFAULT_WIDTH
|
||||
#define FORCE_ELLIPSE_HEIGHT_AUTO FEEL_ELLIPSE_HEIGHT_AUTO
|
||||
#define FORCE_ELLIPSE_DEFAULT_HEIGHT FEEL_ELLIPSE_DEFAULT_HEIGHT
|
||||
#define FORCE_ELLIPSE_WALL_WIDTH_AUTO FEEL_ELLIPSE_WALL_WIDTH_AUTO
|
||||
#define FORCE_ELLIPSE_DEFAULT_WALL_WIDTH FEEL_ELLIPSE_DEFAULT_WALL_WIDTH
|
||||
#define FORCE_ELLIPSE_DEFAULT_STIFFNESS_MASK FEEL_ELLIPSE_DEFAULT_STIFFNESS_MASK
|
||||
#define FORCE_ELLIPSE_DEFAULT_CLIPPING_MASK FEEL_ELLIPSE_DEFAULT_CLIPPING_MASK
|
||||
|
||||
#define FORCE_ELLIPSE_DEFAULT_CENTER_POINT FEEL_ELLIPSE_DEFAULT_CENTER_POINT
|
||||
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelEllipse
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelEllipse : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelEllipse();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelEllipse();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
POINT pntCenter,
|
||||
DWORD dwWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwHeight = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwStiffnessMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwClippingMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
LPCRECT pRectOutside,
|
||||
LONG lStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwStiffnessMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwClippingMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetRect(
|
||||
LPCRECT pRect
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetCenter(
|
||||
POINT pntCenter
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetCenter(
|
||||
LONG x,
|
||||
LONG y
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwWidth = FEEL_ELLIPSE_DEFAULT_WIDTH,
|
||||
DWORD dwHeight = FEEL_ELLIPSE_DEFAULT_HEIGHT,
|
||||
LONG lStiffness = FEEL_ELLIPSE_DEFAULT_STIFFNESS,
|
||||
DWORD dwWallWidth = FEEL_ELLIPSE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwSaturation = FEEL_ELLIPSE_DEFAULT_SATURATION,
|
||||
DWORD dwStiffnessMask = FEEL_ELLIPSE_DEFAULT_STIFFNESS_MASK,
|
||||
DWORD dwClippingMask = FEEL_ELLIPSE_DEFAULT_CLIPPING_MASK,
|
||||
POINT pntCenter = FEEL_ELLIPSE_DEFAULT_CENTER_POINT,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LPCRECT pRectOutside,
|
||||
LONG lStiffness = FEEL_ELLIPSE_DEFAULT_STIFFNESS,
|
||||
DWORD dwWallWidth = FEEL_ELLIPSE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwSaturation = FEEL_ELLIPSE_DEFAULT_SATURATION,
|
||||
DWORD dwStiffnessMask = FEEL_ELLIPSE_DEFAULT_STIFFNESS_MASK,
|
||||
DWORD dwClippingMask = FEEL_ELLIPSE_DEFAULT_CLIPPING_MASK,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
virtual BOOL
|
||||
#ifdef FFC_START_DELAY
|
||||
StartNow(
|
||||
#else
|
||||
Start(
|
||||
#endif
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
LPCRECT pRectOutside,
|
||||
LONG lStiffness,
|
||||
DWORD dwWallWidth,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwStiffnessMask,
|
||||
DWORD dwClippingMask,
|
||||
CFeelEffect* pInsideEffect
|
||||
);
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
FEELIT_ELLIPSE m_ellipse;
|
||||
BOOL m_bUseMousePosAtStart;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelEllipse::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Ellipse);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELELLIPSE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
268
code/win32/FeelIt/FeelEnclosure.h
Normal file
268
code/win32/FeelIt/FeelEnclosure.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelEnclosure.h
|
||||
|
||||
PURPOSE: Base Enclosure Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 10/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
|
||||
#define FEEL_ENCLOSURE_DEFAULT_STIFFNESS 5000
|
||||
#define FEEL_ENCLOSURE_DEFAULT_SATURATION 10000
|
||||
#define FEEL_ENCLOSURE_DEFAULT_WIDTH 10
|
||||
#define FEEL_ENCLOSURE_HEIGHT_AUTO MAXDWORD
|
||||
#define FEEL_ENCLOSURE_DEFAULT_HEIGHT FEEL_ENCLOSURE_HEIGHT_AUTO
|
||||
#define FEEL_ENCLOSURE_WALL_WIDTH_AUTO MAXDWORD
|
||||
#define FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH FEEL_ENCLOSURE_WALL_WIDTH_AUTO
|
||||
#define FEEL_ENCLOSURE_DEFAULT_STIFFNESS_MASK FEELIT_FSTIFF_ANYWALL
|
||||
#define FEEL_ENCLOSURE_DEFAULT_CLIPPING_MASK FEELIT_FCLIP_NONE
|
||||
|
||||
#define FEEL_ENCLOSURE_DEFAULT_CENTER_POINT FEEL_EFFECT_MOUSE_POS_AT_START
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_ENCLOSURE_DEFAULT_STIFFNESS FEEL_ENCLOSURE_DEFAULT_STIFFNESS
|
||||
#define FORCE_ENCLOSURE_DEFAULT_SATURATION FEEL_ENCLOSURE_DEFAULT_SATURATION
|
||||
#define FORCE_ENCLOSURE_DEFAULT_WIDTH FEEL_ENCLOSURE_DEFAULT_WIDTH
|
||||
#define FORCE_ENCLOSURE_HEIGHT_AUTO FEEL_ENCLOSURE_HEIGHT_AUTO
|
||||
#define FORCE_ENCLOSURE_DEFAULT_HEIGHT FEEL_ENCLOSURE_DEFAULT_HEIGHT
|
||||
#define FORCE_ENCLOSURE_WALL_WIDTH_AUTO FEEL_ENCLOSURE_WALL_WIDTH_AUTO
|
||||
#define FORCE_ENCLOSURE_DEFAULT_WALL_WIDTH FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH
|
||||
#define FORCE_ENCLOSURE_DEFAULT_STIFFNESS_MASK FEEL_ENCLOSURE_DEFAULT_STIFFNESS_MASK
|
||||
#define FORCE_ENCLOSURE_DEFAULT_CLIPPING_MASK FEEL_ENCLOSURE_DEFAULT_CLIPPING_MASK
|
||||
|
||||
#define FORCE_ENCLOSURE_DEFAULT_CENTER_POINT FEEL_ENCLOSURE_DEFAULT_CENTER_POINT
|
||||
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelEnclosure
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelEnclosure : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelEnclosure();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelEnclosure();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
POINT pntCenter,
|
||||
DWORD dwWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwHeight = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lTopAndBottomWallStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lLeftAndRightWallStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTopAndBottomWallWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwLeftAndRightWallWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTopAndBottomWallSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwLeftAndRightWallSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwStiffnessMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwClippingMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
LPCRECT pRectOutside,
|
||||
LONG lTopAndBottomWallStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lLeftAndRightWallStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTopAndBottomWallWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwLeftAndRightWallWallWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwTopAndBottomWallSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwLeftAndRightWallSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwStiffnessMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwClippingMask = FEEL_EFFECT_DONT_CHANGE,
|
||||
CFeelEffect* pInsideEffect = (CFeelEffect*) FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetRect(
|
||||
LPCRECT pRect
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetCenter(
|
||||
POINT pntCenter
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
SetCenter(
|
||||
LONG x,
|
||||
LONG y
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwWidth = FEEL_ENCLOSURE_DEFAULT_WIDTH,
|
||||
DWORD dwHeight = FEEL_ENCLOSURE_DEFAULT_HEIGHT,
|
||||
LONG lTopAndBottomWallStiffness = FEEL_ENCLOSURE_DEFAULT_STIFFNESS,
|
||||
LONG lLeftAndRightWallStiffness = FEEL_ENCLOSURE_DEFAULT_STIFFNESS,
|
||||
DWORD dwTopAndBottomWallWallWidth = FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwLeftAndRightWallWallWidth = FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwTopAndBottomWallSaturation = FEEL_ENCLOSURE_DEFAULT_SATURATION,
|
||||
DWORD dwLeftAndRightWallSaturation = FEEL_ENCLOSURE_DEFAULT_SATURATION,
|
||||
DWORD dwStiffnessMask = FEEL_ENCLOSURE_DEFAULT_STIFFNESS_MASK,
|
||||
DWORD dwClippingMask = FEEL_ENCLOSURE_DEFAULT_CLIPPING_MASK,
|
||||
POINT pntCenter = FEEL_ENCLOSURE_DEFAULT_CENTER_POINT,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LPCRECT pRectOutside,
|
||||
LONG lTopAndBottomWallStiffness = FEEL_ENCLOSURE_DEFAULT_STIFFNESS,
|
||||
LONG lLeftAndRightWallStiffness = FEEL_ENCLOSURE_DEFAULT_STIFFNESS,
|
||||
DWORD dwTopAndBottomWallWallWidth = FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwLeftAndRightWallWallWidth = FEEL_ENCLOSURE_DEFAULT_WALL_WIDTH,
|
||||
DWORD dwTopAndBottomWallSaturation = FEEL_ENCLOSURE_DEFAULT_SATURATION,
|
||||
DWORD dwLeftAndRightWallSaturation = FEEL_ENCLOSURE_DEFAULT_SATURATION,
|
||||
DWORD dwStiffnessMask = FEEL_ENCLOSURE_DEFAULT_STIFFNESS_MASK,
|
||||
DWORD dwClippingMask = FEEL_ENCLOSURE_DEFAULT_CLIPPING_MASK,
|
||||
CFeelEffect* pInsideEffect = NULL
|
||||
);
|
||||
|
||||
|
||||
virtual BOOL
|
||||
#ifdef FFC_START_DELAY
|
||||
StartNow(
|
||||
#else
|
||||
Start(
|
||||
#endif
|
||||
DWORD dwFlags = 0
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
LPCRECT pRectOutside,
|
||||
LONG lTopAndBottomWallStiffness,
|
||||
LONG lLeftAndRightWallStiffness,
|
||||
DWORD dwTopAndBottomWallWallWidth,
|
||||
DWORD dwLeftAndRightWallWallWidth,
|
||||
DWORD dwTopAndBottomWallSaturation,
|
||||
DWORD dwLeftAndRightWallSaturation,
|
||||
DWORD dwStiffnessMask,
|
||||
DWORD dwClippingMask,
|
||||
CFeelEffect* pInsideEffect
|
||||
);
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
FEELIT_ENCLOSURE m_enclosure;
|
||||
BOOL m_bUseMousePosAtStart;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelEnclosure::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Enclosure);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELENCLOSURE_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
172
code/win32/FeelIt/FeelFriction.h
Normal file
172
code/win32/FeelIt/FeelFriction.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelFriction.h
|
||||
|
||||
PURPOSE: Feelit API Friction Effect Class
|
||||
|
||||
STARTED: 12/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelCondition.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_FRICTION_DEFAULT_COEFFICIENT 2500
|
||||
#define FEEL_FRICTION_DEFAULT_MIN_VELOCITY 0
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_FRICTION_DEFAULT_COEFFICIENT FEEL_FRICTION_DEFAULT_COEFFICIENT
|
||||
#define FORCE_FRICTION_DEFAULT_MIN_VELOCITY FEEL_FRICTION_DEFAULT_MIN_VELOCITY
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelFriction
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelFriction : public CFeelCondition
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelFriction();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelFriction();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwMinVelocity = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwMinVelocity,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwCoefficient = FEEL_FRICTION_DEFAULT_COEFFICIENT,
|
||||
DWORD dwMinVelocity = FEEL_FRICTION_DEFAULT_MIN_VELOCITY,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwMinVelocity,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelFriction::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Friction);
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELFriction_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
171
code/win32/FeelIt/FeelGrid.h
Normal file
171
code/win32/FeelIt/FeelGrid.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelGrid.h
|
||||
|
||||
PURPOSE: Feelit API Grid Effect Class
|
||||
|
||||
STARTED: 12/11/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelCondition.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_GRID_DEFAULT_HORIZ_OFFSET 0
|
||||
#define FEEL_GRID_DEFAULT_VERT_OFFSET 0
|
||||
#define FEEL_GRID_DEFAULT_HORIZ_SPACING 100
|
||||
#define FEEL_GRID_DEFAULT_VERT_SPACING 100
|
||||
#define FEEL_GRID_DEFAULT_NODE_STRENGTH 5000
|
||||
#define FEEL_GRID_DEFAULT_NODE_SATURATION 10000
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_GRID_DEFAULT_HORIZ_OFFSET FEEL_GRID_DEFAULT_HORIZ_OFFSET
|
||||
#define FORCE_GRID_DEFAULT_VERT_OFFSET FEEL_GRID_DEFAULT_VERT_OFFSET
|
||||
#define FORCE_GRID_DEFAULT_HORIZ_SPACING FEEL_GRID_DEFAULT_HORIZ_SPACING
|
||||
#define FORCE_GRID_DEFAULT_VERT_SPACING FEEL_GRID_DEFAULT_VERT_SPACING
|
||||
#define FORCE_GRID_DEFAULT_NODE_STRENGTH FEEL_GRID_DEFAULT_NODE_STRENGTH
|
||||
#define FORCE_GRID_DEFAULT_NODE_SATURATION FEEL_GRID_DEFAULT_NODE_SATURATION
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelGrid
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelGrid : public CFeelCondition
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelGrid();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelGrid();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
DWORD dwHorizSpacing,
|
||||
DWORD dwVertSpacing,
|
||||
LONG lHorizNodeStrength = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lVertNodeStrength = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwHorizOffset = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwVertOffset = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwHorizNodeSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwVertNodeSaturation = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwHorizSpacing = FEEL_GRID_DEFAULT_HORIZ_SPACING,
|
||||
DWORD dwVertSpacing = FEEL_GRID_DEFAULT_VERT_SPACING,
|
||||
LONG lHorizNodeStrength = FEEL_GRID_DEFAULT_NODE_STRENGTH,
|
||||
LONG lVertNodeStrength = FEEL_GRID_DEFAULT_NODE_STRENGTH,
|
||||
DWORD dwHorizOffset = FEEL_GRID_DEFAULT_HORIZ_OFFSET,
|
||||
DWORD dwVertOffset = FEEL_GRID_DEFAULT_VERT_OFFSET,
|
||||
DWORD dwHorizNodeSaturation = FEEL_GRID_DEFAULT_NODE_SATURATION,
|
||||
DWORD dwVertNodeSaturation = FEEL_GRID_DEFAULT_NODE_SATURATION
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelGrid::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Grid);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELGrid_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
178
code/win32/FeelIt/FeelInertia.h
Normal file
178
code/win32/FeelIt/FeelInertia.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelInertia.h
|
||||
|
||||
PURPOSE: Feelit API Inertia Effect Class
|
||||
|
||||
STARTED: 12/29/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelCondition.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_INERTIA_DEFAULT_COEFFICIENT 2500
|
||||
#define FEEL_INERTIA_DEFAULT_SATURATION 10000
|
||||
#define FEEL_INERTIA_DEFAULT_MIN_ACCELERATION 0
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_INERTIA_DEFAULT_COEFFICIENT FEEL_INERTIA_DEFAULT_COEFFICIENT
|
||||
#define FORCE_INERTIA_DEFAULT_SATURATION FEEL_INERTIA_DEFAULT_SATURATION
|
||||
#define FORCE_INERTIA_DEFAULT_MIN_ACCELERATION FEEL_INERTIA_DEFAULT_MIN_ACCELERATION
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelInertia
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelInertia : public CFeelCondition
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelInertia();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelInertia();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwMinAcceleration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwMinAcceleration,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwCoefficient = FEEL_INERTIA_DEFAULT_COEFFICIENT,
|
||||
DWORD dwSaturation = FEEL_INERTIA_DEFAULT_SATURATION,
|
||||
DWORD dwMinAcceleration = FEEL_INERTIA_DEFAULT_MIN_ACCELERATION,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwCoefficient,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwMinAcceleration,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelInertia::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Inertia);
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(AFX_FEELInertia_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
143
code/win32/FeelIt/FeelMouse.h
Normal file
143
code/win32/FeelIt/FeelMouse.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelMouse.h
|
||||
|
||||
PURPOSE: Abstraction of Feelit mouse device
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef FeelMouse_h
|
||||
#define FeelMouse_h
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelDevice.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelMouse
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelMouse : public CFeelDevice
|
||||
{
|
||||
|
||||
//
|
||||
// CONSTRUCTOR/DESCTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelMouse();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelMouse();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual LPIFEEL_API
|
||||
GetAPI()
|
||||
{ return m_piApi; }
|
||||
|
||||
virtual LPIFEEL_DEVICE
|
||||
GetDevice()
|
||||
{ return m_piDevice; }
|
||||
|
||||
BOOL
|
||||
HaveForceFeelitMouse()
|
||||
{ return m_piDevice != NULL; }
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Initialize(
|
||||
HANDLE hinstApp,
|
||||
HANDLE hwndApp,
|
||||
DWORD dwCooperativeFlag = FEELIT_FCOOPLEVEL_FOREGROUND
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
ChangeScreenResolution(
|
||||
BOOL bAutoSet,
|
||||
DWORD dwXScreenSize = 0,
|
||||
DWORD dwYScreenSize = 0
|
||||
);
|
||||
|
||||
// Another syntax for SwitchToAbsoluteMode.
|
||||
// The default is Absolute mode. Call only to switch to Relative mode or
|
||||
// to switch back to Absolute mode.
|
||||
virtual BOOL
|
||||
SwitchToAbsoluteMode(
|
||||
BOOL bAbsMode
|
||||
);
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
reset();
|
||||
|
||||
virtual BOOL
|
||||
prepare_device();
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
LPIFEEL_API m_piApi;
|
||||
LPIFEEL_DEVICE m_piDevice;
|
||||
};
|
||||
|
||||
#endif // ForceFeelitMouse_h
|
||||
227
code/win32/FeelIt/FeelPeriodic.h
Normal file
227
code/win32/FeelIt/FeelPeriodic.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelPeriodic.h
|
||||
|
||||
PURPOSE: Base Periodic Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 11/03/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_PERIODIC_DEFAULT_DURATION 1000 // Milliseconds
|
||||
#define FEEL_PERIODIC_DEFAULT_MAGNITUDE 5000
|
||||
#define FEEL_PERIODIC_DEFAULT_PERIOD 100 // Milliseconds
|
||||
#define FEEL_PERIODIC_DEFAULT_OFFSET 0
|
||||
#define FEEL_PERIODIC_DEFAULT_PHASE 0 // Degrees
|
||||
#define FEEL_PERIODIC_DEFAULT_DIRECTION_X 1 // Pixels
|
||||
#define FEEL_PERIODIC_DEFAULT_DIRECTION_Y 0 // Pixels
|
||||
#define FEEL_PERIODIC_DEFAULT_ANGLE 9000 // 100ths of degrees
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_PERIODIC_DEFAULT_DURATION FEEL_PERIODIC_DEFAULT_DURATION
|
||||
#define FORCE_PERIODIC_DEFAULT_MAGNITUDE FEEL_PERIODIC_DEFAULT_MAGNITUDE
|
||||
#define FORCE_PERIODIC_DEFAULT_PERIOD FEEL_PERIODIC_DEFAULT_PERIOD
|
||||
#define FORCE_PERIODIC_DEFAULT_OFFSET FEEL_PERIODIC_DEFAULT_OFFSET
|
||||
#define FORCE_PERIODIC_DEFAULT_PHASE FEEL_PERIODIC_DEFAULT_PHASE
|
||||
#define FORCE_PERIODIC_DEFAULT_DIRECTION_X FEEL_PERIODIC_DEFAULT_DIRECTION_X
|
||||
#define FORCE_PERIODIC_DEFAULT_DIRECTION_Y FEEL_PERIODIC_DEFAULT_DIRECTION_Y
|
||||
#define FORCE_PERIODIC_DEFAULT_ANGLE FEEL_PERIODIC_DEFAULT_ANGLE
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelPeriodic
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelPeriodic : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
// You may use this form if you will immediately initialize it
|
||||
// from an IFR file...
|
||||
CFeelPeriodic();
|
||||
|
||||
// Otherwise use this form...
|
||||
CFeelPeriodic(
|
||||
const GUID& rguidEffect
|
||||
);
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelPeriodic();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
DWORD dwMagnitude,
|
||||
DWORD dwPeriod = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lOffset = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPhase = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
DWORD dwMagnitude,
|
||||
DWORD dwPeriod = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lAngle = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lOffset = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPhase = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwMagnitude = FEEL_PERIODIC_DEFAULT_MAGNITUDE,
|
||||
DWORD dwPeriod = FEEL_PERIODIC_DEFAULT_PERIOD,
|
||||
DWORD dwDuration = FEEL_PERIODIC_DEFAULT_DURATION,
|
||||
LONG lDirectionX = FEEL_PERIODIC_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_PERIODIC_DEFAULT_DIRECTION_Y,
|
||||
LONG lOffset = FEEL_PERIODIC_DEFAULT_OFFSET,
|
||||
DWORD dwPhase = FEEL_PERIODIC_DEFAULT_PHASE,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
DWORD dwMagnitude = FEEL_PERIODIC_DEFAULT_MAGNITUDE,
|
||||
DWORD dwPeriod = FEEL_PERIODIC_DEFAULT_PERIOD,
|
||||
DWORD dwDuration = FEEL_PERIODIC_DEFAULT_DURATION,
|
||||
LONG lAngle = FEEL_PERIODIC_DEFAULT_ANGLE,
|
||||
LONG lOffset = FEEL_PERIODIC_DEFAULT_OFFSET,
|
||||
DWORD dwPhase = FEEL_PERIODIC_DEFAULT_PHASE,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
DWORD dwDuration,
|
||||
DWORD dwMagnitude,
|
||||
DWORD dwPeriod,
|
||||
LONG lOffset,
|
||||
DWORD dwPhase,
|
||||
LPFEEL_ENVELOPE pEnvelope
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
FEEL_PERIODIC m_Periodic;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelPeriodic::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Sine) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Square) ||
|
||||
IsEqualGUID(guid, GUID_Feel_Triangle) ||
|
||||
IsEqualGUID(guid, GUID_Feel_SawtoothUp) ||
|
||||
IsEqualGUID(guid, GUID_Feel_SawtoothDown);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELPERIODIC_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
302
code/win32/FeelIt/FeelProjects.h
Normal file
302
code/win32/FeelIt/FeelProjects.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1999 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelProjects.h
|
||||
|
||||
PURPOSE: CFeelProject
|
||||
Manages a set of forces in a project.
|
||||
There will be a project for each opened IFR file.
|
||||
CFeelProjects
|
||||
Manages a set of projects
|
||||
|
||||
STARTED: 2/22/99 by Jeff Mallett
|
||||
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __FEEL_PROJECTS_H
|
||||
#define __FEEL_PROJECTS_H
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
|
||||
#include "FFCErrors.h"
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelDevice.h"
|
||||
#include "FeelCompoundEffect.h"
|
||||
|
||||
class CFeelProjects;
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelProject
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelProject
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
CFeelProject() :
|
||||
m_hProj(NULL), m_pCreatedEffects(NULL),
|
||||
m_pNext(NULL), m_pDevice(NULL)
|
||||
{ }
|
||||
|
||||
~CFeelProject();
|
||||
|
||||
void
|
||||
Close();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
CFeelDevice*
|
||||
GetDevice() const
|
||||
{ return m_pDevice; }
|
||||
|
||||
BOOL
|
||||
GetIsOpen() const
|
||||
{ return m_hProj != NULL; }
|
||||
|
||||
CFeelCompoundEffect *
|
||||
GetCreatedEffect(
|
||||
LPCSTR lpszEffectName
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Start(
|
||||
LPCSTR lpszEffectName = NULL,
|
||||
DWORD dwIterations = 1,
|
||||
DWORD dwFlags = 0,
|
||||
CFeelDevice* pDevice = NULL
|
||||
);
|
||||
|
||||
BOOL
|
||||
Stop(
|
||||
LPCSTR lpszEffectName = NULL
|
||||
);
|
||||
|
||||
BOOL
|
||||
OpenFile(
|
||||
LPCSTR lpszFilePath,
|
||||
CFeelDevice *pDevice
|
||||
);
|
||||
|
||||
LoadProjectObjectPointer(
|
||||
BYTE *pMem,
|
||||
CFeelDevice *pDevice
|
||||
);
|
||||
|
||||
CFeelCompoundEffect *
|
||||
CreateEffect(
|
||||
LPCSTR lpszEffectName,
|
||||
CFeelDevice* pDevice = NULL
|
||||
);
|
||||
|
||||
CFeelCompoundEffect *
|
||||
CreateEffectByIndex(
|
||||
int nEffectIndex,
|
||||
CFeelDevice* pDevice = NULL
|
||||
);
|
||||
|
||||
CFeelCompoundEffect *
|
||||
AddEffect(
|
||||
LPCSTR lpszEffectName,
|
||||
GENERIC_EFFECT_PTR pObject
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
set_next(
|
||||
CFeelProject *pNext
|
||||
)
|
||||
{ m_pNext = pNext; }
|
||||
|
||||
CFeelProject *
|
||||
get_next() const
|
||||
{ return m_pNext; }
|
||||
|
||||
void
|
||||
append_effect_to_list(
|
||||
CFeelCompoundEffect* pEffect
|
||||
);
|
||||
|
||||
IFREffect **
|
||||
create_effect_structs(
|
||||
LPCSTR lpszEffectName,
|
||||
int &nEff
|
||||
);
|
||||
|
||||
IFREffect **
|
||||
create_effect_structs_by_index(
|
||||
int nEffectIndex,
|
||||
int &nEff
|
||||
);
|
||||
|
||||
BOOL
|
||||
release_effect_structs(
|
||||
IFREffect **hEffects
|
||||
);
|
||||
|
||||
//
|
||||
// FRIENDS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
friend BOOL
|
||||
CFeelEffect::InitializeFromProject(
|
||||
CFeelProject &project,
|
||||
LPCSTR lpszEffectName,
|
||||
CFeelDevice* pDevice /* = NULL */
|
||||
);
|
||||
|
||||
friend class CFeelProjects;
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
HIFRPROJECT m_hProj;
|
||||
CFeelCompoundEffect* m_pCreatedEffects;
|
||||
CFeelDevice* m_pDevice;
|
||||
|
||||
private:
|
||||
|
||||
CFeelProject* m_pNext;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelProjects
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelProjects
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
CFeelProjects() : m_pProjects(NULL) { }
|
||||
|
||||
~CFeelProjects();
|
||||
|
||||
void
|
||||
Close();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
CFeelProject *
|
||||
GetProject(
|
||||
int index = 0
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
BOOL
|
||||
Stop();
|
||||
|
||||
long
|
||||
OpenFile(
|
||||
LPCSTR lpszFilePath,
|
||||
CFeelDevice *pDevice
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
protected:
|
||||
|
||||
CFeelProject *m_pProjects;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __FEEL_PROJECTS_H
|
||||
194
code/win32/FeelIt/FeelRamp.h
Normal file
194
code/win32/FeelIt/FeelRamp.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelRamp.h
|
||||
|
||||
PURPOSE: Base Ramp Force Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 12/11/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_RAMP_DEFAULT_DURATION 1000 // Milliseconds
|
||||
#define FEEL_RAMP_DEFAULT_MAGNITUDE_START 0
|
||||
#define FEEL_RAMP_DEFAULT_MAGNITUDE_END 10000
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_RAMP_DEFAULT_DURATION FEEL_RAMP_DEFAULT_DURATION
|
||||
#define FORCE_RAMP_DEFAULT_MAGNITUDE_START FEEL_RAMP_DEFAULT_MAGNITUDE_START
|
||||
#define FORCE_RAMP_DEFAULT_MAGNITUDE_END FEEL_RAMP_DEFAULT_MAGNITUDE_END
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelRamp
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelRamp : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelRamp();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelRamp();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagStart = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagEnd = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
LONG lAngle,
|
||||
DWORD dwDuration = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagStart = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lMagEnd = FEEL_EFFECT_DONT_CHANGE,
|
||||
LPFEEL_ENVELOPE pEnvelope = (LPFEEL_ENVELOPE) FEEL_EFFECT_DONT_CHANGE_PTR
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y,
|
||||
DWORD dwDuration = FEEL_RAMP_DEFAULT_DURATION,
|
||||
LONG lMagStart = FEEL_RAMP_DEFAULT_MAGNITUDE_START,
|
||||
LONG lMagEnd = FEEL_RAMP_DEFAULT_MAGNITUDE_END,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lAngle = FEEL_EFFECT_DEFAULT_ANGLE,
|
||||
DWORD dwDuration = FEEL_RAMP_DEFAULT_DURATION,
|
||||
LONG lMagStart = FEEL_RAMP_DEFAULT_MAGNITUDE_START,
|
||||
LONG lMagEnd = FEEL_RAMP_DEFAULT_MAGNITUDE_END,
|
||||
LPFEEL_ENVELOPE pEnvelope = NULL
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
DWORD dwDuration,
|
||||
LONG lMagStart,
|
||||
LONG lMagEnd,
|
||||
LPFEEL_ENVELOPE pEnvelope
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
FEEL_RAMPFORCE m_RampForce;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelRamp::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_RampForce);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELRAMP_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
191
code/win32/FeelIt/FeelSpring.h
Normal file
191
code/win32/FeelIt/FeelSpring.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelSpring.h
|
||||
|
||||
PURPOSE: Feelit API Spring Class
|
||||
|
||||
STARTED: 10/10/97
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FEELSPRING_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FEELSPRING_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelCondition.h"
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
#define FEEL_SPRING_DEFAULT_STIFFNESS 2500
|
||||
#define FEEL_SPRING_DEFAULT_SATURATION 10000
|
||||
#define FEEL_SPRING_DEFAULT_DEADBAND 100
|
||||
#define FEEL_SPRING_DEFAULT_CENTER_POINT FEEL_EFFECT_MOUSE_POS_AT_START
|
||||
#define FEEL_SPRING_DEFAULT_DIRECTION_X 1
|
||||
#define FEEL_SPRING_DEFAULT_DIRECTION_Y 0
|
||||
#define FEEL_SPRING_DEFAULT_ANGLE 0
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_SPRING_DEFAULT_STIFFNESS FEEL_SPRING_DEFAULT_STIFFNESS
|
||||
#define FORCE_SPRING_DEFAULT_SATURATION FEEL_SPRING_DEFAULT_SATURATION
|
||||
#define FORCE_SPRING_DEFAULT_DEADBAND FEEL_SPRING_DEFAULT_DEADBAND
|
||||
#define FORCE_SPRING_DEFAULT_CENTER_POINT FEEL_SPRING_DEFAULT_CENTER_POINT
|
||||
#define FORCE_SPRING_DEFAULT_DIRECTION_X FEEL_SPRING_DEFAULT_DIRECTION_X
|
||||
#define FORCE_SPRING_DEFAULT_DIRECTION_Y FEEL_SPRING_DEFAULT_DIRECTION_Y
|
||||
#define FORCE_SPRING_DEFAULT_ANGLE FEEL_SPRING_DEFAULT_ANGLE
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelSpring
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelSpring : public CFeelCondition
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelSpring();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelSpring();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParameters(
|
||||
POINT pntCenter,
|
||||
LONG lStiffness = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwSaturation = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwDeadband = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
ChangeParametersPolar(
|
||||
POINT pntCenter,
|
||||
LONG lStiffness,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwDeadband,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
Initialize(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lStiffness = FEEL_SPRING_DEFAULT_STIFFNESS,
|
||||
DWORD dwSaturation = FEEL_SPRING_DEFAULT_SATURATION,
|
||||
DWORD dwDeadband = FEEL_SPRING_DEFAULT_DEADBAND,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
POINT pntCenter = FEEL_SPRING_DEFAULT_CENTER_POINT,
|
||||
LONG lDirectionX = FEEL_SPRING_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_SPRING_DEFAULT_DIRECTION_Y,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
virtual BOOL
|
||||
InitializePolar(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lStiffness,
|
||||
DWORD dwSaturation,
|
||||
DWORD dwDeadband,
|
||||
POINT pntCenter,
|
||||
LONG lAngle,
|
||||
BOOL bUseDeviceCoordinates = FALSE
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelSpring::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Spring);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FEELSPRING_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
|
||||
287
code/win32/FeelIt/FeelTexture.h
Normal file
287
code/win32/FeelIt/FeelTexture.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/**********************************************************************
|
||||
Copyright (c) 1997 Immersion Corporation
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation may be granted without fee;
|
||||
interested parties are encouraged to request permission from
|
||||
Immersion Corporation
|
||||
2158 Paragon Drive
|
||||
San Jose, CA 95131
|
||||
408-467-1900
|
||||
|
||||
IMMERSION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL IMMERSION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
FILE: FeelTexture.h
|
||||
|
||||
PURPOSE: Texture Class for Feelit API Foundation Classes
|
||||
|
||||
STARTED: 2/27/98
|
||||
|
||||
NOTES/REVISIONS:
|
||||
3/2/99 jrm (Jeff Mallett): Force-->Feel renaming
|
||||
3/2/99 jrm: Added GetIsCompatibleGUID
|
||||
3/15/99 jrm: __declspec(dllimport/dllexport) the whole class
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#if !defined(AFX_FeelTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
#define AFX_FeelTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_
|
||||
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef _FFCDLL_
|
||||
#define DLLFFC __declspec(dllimport)
|
||||
#else
|
||||
#define DLLFFC __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "FeelBaseTypes.h"
|
||||
#include "FeelEffect.h"
|
||||
|
||||
|
||||
|
||||
//================================================================
|
||||
// Constants
|
||||
//================================================================
|
||||
|
||||
const POINT FEEL_TEXTURE_PT_NULL = { 0, 0 };
|
||||
const POINT FEEL_TEXTURE_DEFAULT_OFFSET_POINT = { 0, 0};
|
||||
|
||||
#define FEEL_TEXTURE_DEFAULT_MAGNITUDE 5000
|
||||
#define FEEL_TEXTURE_DEFAULT_WIDTH 10
|
||||
#define FEEL_TEXTURE_DEFAULT_SPACING 20
|
||||
|
||||
//
|
||||
// FORCE --> FEEL Wrappers
|
||||
//
|
||||
#define FORCE_TEXTURE_PT_NULL FEEL_TEXTURE_PT_NULL
|
||||
#define FORCE_TEXTURE_DEFAULT_OFFSET_POINT FEEL_TEXTURE_DEFAULT_OFFSET_POINT
|
||||
|
||||
#define FORCE_TEXTURE_DEFAULT_MAGNITUDE FEEL_TEXTURE_DEFAULT_MAGNITUDE
|
||||
#define FORCE_TEXTURE_DEFAULT_WIDTH FEEL_TEXTURE_DEFAULT_WIDTH
|
||||
#define FORCE_TEXTURE_DEFAULT_SPACING FEEL_TEXTURE_DEFAULT_SPACING
|
||||
|
||||
|
||||
//================================================================
|
||||
// CFeelTexture
|
||||
//================================================================
|
||||
|
||||
//
|
||||
// ------ PUBLIC INTERFACE ------
|
||||
//
|
||||
|
||||
class DLLFFC CFeelTexture : public CFeelEffect
|
||||
{
|
||||
//
|
||||
// CONSTRUCTOR/DESTRUCTOR
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
CFeelTexture();
|
||||
|
||||
// Destructor
|
||||
virtual
|
||||
~CFeelTexture();
|
||||
|
||||
|
||||
//
|
||||
// ATTRIBUTES
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
virtual BOOL
|
||||
GetIsCompatibleGUID(
|
||||
GUID &guid
|
||||
);
|
||||
|
||||
// Use this form for single-axis and dual-axis effects
|
||||
BOOL
|
||||
ChangeTextureParams(
|
||||
LPCFEELIT_TEXTURE pTextureX,
|
||||
LPCFEELIT_TEXTURE pTextureY
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
ChangeTextureParams(
|
||||
LPCFEELIT_TEXTURE pTexture,
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
ChangeTextureParamsPolar(
|
||||
LPCFEELIT_TEXTURE pTexture,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
ChangeTextureParams(
|
||||
LONG lPosBumpMag = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPosBumpWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPosBumpSpacing = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lNegBumpMag = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwNegBumpWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwNegBumpSpacing = FEEL_EFFECT_DONT_CHANGE,
|
||||
POINT pntOffset = FEEL_EFFECT_DONT_CHANGE_POINT,
|
||||
LONG lDirectionX = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lDirectionY = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
ChangeTextureParamsPolar(
|
||||
LONG lPosBumpMag = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPosBumpWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwPosBumpSpacing = FEEL_EFFECT_DONT_CHANGE,
|
||||
LONG lNegBumpMag = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwNegBumpWidth = FEEL_EFFECT_DONT_CHANGE,
|
||||
DWORD dwNegBumpSpacing = FEEL_EFFECT_DONT_CHANGE,
|
||||
POINT pntOffset = FEEL_EFFECT_DONT_CHANGE_POINT,
|
||||
LONG lAngle = FEEL_EFFECT_DONT_CHANGE
|
||||
);
|
||||
|
||||
BOOL
|
||||
SetOffset(
|
||||
POINT pntOffset
|
||||
);
|
||||
|
||||
//
|
||||
// OPERATIONS
|
||||
//
|
||||
|
||||
public:
|
||||
|
||||
// Use this form for single-axis and dual-axis effects
|
||||
BOOL
|
||||
InitTexture(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_TEXTURE pTextureX,
|
||||
LPCFEELIT_TEXTURE pTextureY
|
||||
);
|
||||
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitTexture(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_TEXTURE pTexture,
|
||||
LONG lDirectionX,
|
||||
LONG lDirectionY
|
||||
);
|
||||
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitTexturePolar(
|
||||
CFeelDevice* pDevice,
|
||||
LPCFEELIT_TEXTURE pTexture,
|
||||
LONG lAngle
|
||||
);
|
||||
|
||||
|
||||
// Use this form for single-axis, dual-axis symetrical, or directional effects
|
||||
BOOL
|
||||
InitTexture(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lPosBumpMag = FEEL_TEXTURE_DEFAULT_MAGNITUDE,
|
||||
DWORD dwPosBumpWidth = FEEL_TEXTURE_DEFAULT_WIDTH,
|
||||
DWORD dwPosBumpSpacing = FEEL_TEXTURE_DEFAULT_SPACING,
|
||||
LONG lNegBumpMag = FEEL_TEXTURE_DEFAULT_MAGNITUDE,
|
||||
DWORD dwNegBumpWidth = FEEL_TEXTURE_DEFAULT_WIDTH,
|
||||
DWORD dwNegBumpSpacing = FEEL_TEXTURE_DEFAULT_SPACING,
|
||||
DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH,
|
||||
POINT pntOffset = FEEL_TEXTURE_DEFAULT_OFFSET_POINT,
|
||||
LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X,
|
||||
LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
);
|
||||
|
||||
// Use this form for directional effects
|
||||
BOOL
|
||||
InitTexturePolar(
|
||||
CFeelDevice* pDevice,
|
||||
LONG lPosBumpMag = FEEL_TEXTURE_DEFAULT_MAGNITUDE,
|
||||
DWORD dwPosBumpWidth = FEEL_TEXTURE_DEFAULT_WIDTH,
|
||||
DWORD dwPosBumpSpacing = FEEL_TEXTURE_DEFAULT_SPACING,
|
||||
LONG lNegBumpMag = FEEL_TEXTURE_DEFAULT_MAGNITUDE,
|
||||
DWORD dwNegBumpWidth = FEEL_TEXTURE_DEFAULT_WIDTH,
|
||||
DWORD dwNegBumpSpacing = FEEL_TEXTURE_DEFAULT_SPACING,
|
||||
POINT pntOffset = FEEL_TEXTURE_DEFAULT_OFFSET_POINT,
|
||||
LONG lAngle = FEEL_EFFECT_DEFAULT_ANGLE
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// ------ PRIVATE INTERFACE ------
|
||||
//
|
||||
|
||||
//
|
||||
// HELPERS
|
||||
//
|
||||
|
||||
protected:
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfAxis,
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
LPCFEELIT_TEXTURE pTextureX,
|
||||
LPCFEELIT_TEXTURE pTextureY
|
||||
);
|
||||
|
||||
BOOL
|
||||
set_parameters(
|
||||
DWORD dwfAxis,
|
||||
DWORD dwfCoordinates,
|
||||
LONG lDirection0,
|
||||
LONG lDirection1,
|
||||
LONG lPosBumpMag,
|
||||
DWORD dwPosBumpWidth,
|
||||
DWORD dwPosBumpSpacing,
|
||||
LONG lNegBumpMag,
|
||||
DWORD dwNegBumpWidth,
|
||||
DWORD dwNegBumpSpacing,
|
||||
POINT pntOffset
|
||||
);
|
||||
|
||||
//
|
||||
// INTERNAL DATA
|
||||
//
|
||||
|
||||
FEEL_TEXTURE m_aTexture[2];
|
||||
DWORD m_dwfAxis;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// INLINES
|
||||
//
|
||||
|
||||
inline BOOL
|
||||
CFeelTexture::GetIsCompatibleGUID(GUID &guid)
|
||||
{
|
||||
return IsEqualGUID(guid, GUID_Feel_Texture);
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_FeelTexture_H__135B88C4_4175_11D1_B049_0020AF30269A__INCLUDED_)
|
||||
1252
code/win32/FeelIt/FeelitAPI.h
Normal file
1252
code/win32/FeelIt/FeelitAPI.h
Normal file
File diff suppressed because it is too large
Load Diff
680
code/win32/FeelIt/fffx.cpp
Normal file
680
code/win32/FeelIt/fffx.cpp
Normal file
@@ -0,0 +1,680 @@
|
||||
// Filename:- fffx.cpp (Force-Feedback FX)
|
||||
//
|
||||
// (Function names with "_FF_" beginnings are my internal stuff only, "FF_" beginnings are for external stuff)
|
||||
//
|
||||
#define INITGUID // this will need removing if already defined in someone else's module. Only one must exist in whole game
|
||||
|
||||
#include "../../client/client.h"
|
||||
#include "../win_local.h"
|
||||
#include "ffc.h"
|
||||
#include "fffx_feel.h"
|
||||
|
||||
// these now MUST default to NULL...
|
||||
//
|
||||
CFeelDevice *g_pFeelDevice=NULL;
|
||||
CFeelProject *g_pFeelProject=NULL;
|
||||
CFeelSpring *g_pFeelSpring=NULL;
|
||||
|
||||
|
||||
ffFX_e ffFXLoaded[MAX_CONCURRENT_FFFXs];
|
||||
|
||||
//extern HINSTANCE global_hInstance;
|
||||
//extern HWND cl_hwnd;
|
||||
extern WinVars_t g_wv;
|
||||
|
||||
|
||||
extern cvar_t *in_joystick;
|
||||
cvar_t *use_ff;
|
||||
cvar_t *ff_defaultTension;
|
||||
|
||||
|
||||
void _FF_ClearUsageArray(void);
|
||||
void _FF_ClearFXSlot(int i);
|
||||
void _FF_ClearCreatePlayFXSlot(int iSlotNum, ffFX_e fffx);
|
||||
void _FF_CreatePlayFXSlot(int iSlotNum, ffFX_e fffx);
|
||||
void _FF_PlayFXSlot(int iSlotNum);
|
||||
|
||||
|
||||
|
||||
// externally accessed
|
||||
qboolean FF_IsAvailable(void)
|
||||
{
|
||||
return g_pFeelDevice?TRUE:FALSE;
|
||||
}
|
||||
|
||||
qboolean FF_IsMouse(void)
|
||||
{
|
||||
if (g_pFeelDevice && (g_pFeelDevice->GetDeviceType() == FEEL_DEVICETYPE_MOUSE))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// 4 semi-useful CMD functions...
|
||||
void CMD_FF_UseMouse(void)
|
||||
{
|
||||
FF_Init(TRUE);
|
||||
}
|
||||
|
||||
void CMD_FF_UseJoy(void)
|
||||
{
|
||||
FF_Init(FALSE);
|
||||
}
|
||||
|
||||
// arg = 0..3
|
||||
//
|
||||
void CMD_FF_Tension(void)
|
||||
{
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Com_Printf ("ff_tension <tension [0..3]> (default = 1)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int iTension = atoi(Cmd_Argv(1));
|
||||
if (iTension<0 || iTension>3)
|
||||
{
|
||||
Com_Printf ("ff_tension <tension [0..3]>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pFeelSpring)
|
||||
{
|
||||
Com_Printf(va("Setting tension %d\n",iTension));
|
||||
Cvar_Set(ff_defaultTension->name,va("%d",iTension));
|
||||
FF_SetTension(iTension);
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("No spring device\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* psName;
|
||||
ffFX_e eFXNum;
|
||||
}FFFX_LOOKUP;
|
||||
|
||||
#define FFFX_ENTRY(blah) {#blah,(ffFX_e)fffx_ ## blah}
|
||||
FFFX_LOOKUP FFFX_Lookup[fffx_NUMBEROF]=
|
||||
{
|
||||
FFFX_ENTRY( RandomNoise ),
|
||||
FFFX_ENTRY( AircraftCarrierTakeOff ), // this one is pointless / dumb
|
||||
FFFX_ENTRY( BasketballDribble ),
|
||||
FFFX_ENTRY( CarEngineIdle ),
|
||||
FFFX_ENTRY( ChainsawIdle ),
|
||||
FFFX_ENTRY( ChainsawInAction ),
|
||||
FFFX_ENTRY( DieselEngineIdle ),
|
||||
FFFX_ENTRY( Jump ),
|
||||
FFFX_ENTRY( Land ),
|
||||
FFFX_ENTRY( MachineGun ),
|
||||
FFFX_ENTRY( Punched ),
|
||||
FFFX_ENTRY( RocketLaunch ),
|
||||
FFFX_ENTRY( SecretDoor ),
|
||||
FFFX_ENTRY( SwitchClick ),
|
||||
FFFX_ENTRY( WindGust ),
|
||||
FFFX_ENTRY( WindShear ), // also pretty crap
|
||||
FFFX_ENTRY( Pistol ),
|
||||
FFFX_ENTRY( Shotgun ),
|
||||
FFFX_ENTRY( Laser1 ),
|
||||
FFFX_ENTRY( Laser2 ),
|
||||
FFFX_ENTRY( Laser3 ),
|
||||
FFFX_ENTRY( Laser4 ),
|
||||
FFFX_ENTRY( Laser5 ),
|
||||
FFFX_ENTRY( Laser6 ),
|
||||
FFFX_ENTRY( OutOfAmmo ),
|
||||
FFFX_ENTRY( LightningGun ),
|
||||
FFFX_ENTRY( Missile ),
|
||||
FFFX_ENTRY( GatlingGun ),
|
||||
FFFX_ENTRY( ShortPlasma ),
|
||||
FFFX_ENTRY( PlasmaCannon1 ),
|
||||
FFFX_ENTRY( PlasmaCannon2 ),
|
||||
FFFX_ENTRY( Cannon )
|
||||
};
|
||||
|
||||
void CMD_FF_Play(void)
|
||||
{
|
||||
if (Cmd_Argc() != 2 && Cmd_Argc() != 3)
|
||||
{
|
||||
Com_Printf ("ff_play <n> (where n = 0..%d) || ff_play name \"fxname\"\n",fffx_NUMBEROF-1);
|
||||
return;
|
||||
}
|
||||
|
||||
ffFX_e eFX = fffx_NULL;
|
||||
|
||||
if (!Q_stricmp(Cmd_Argv(1),"name"))
|
||||
{
|
||||
if (Cmd_Argc() != 3)
|
||||
{
|
||||
Com_Printf ("ff_play <n> (where n = 0..%d) || ff_play name \"fxname\"\n",0,fffx_NUMBEROF-1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i<fffx_NUMBEROF; i++)
|
||||
{
|
||||
if (!Q_stricmp(FFFX_Lookup[i].psName,Cmd_Argv(2)))
|
||||
{
|
||||
eFX = FFFX_Lookup[i].eFXNum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eFX = (ffFX_e) atoi(Cmd_Argv(1));
|
||||
}
|
||||
|
||||
if (eFX>=0 && eFX<fffx_NUMBEROF)
|
||||
{
|
||||
Com_Printf ("Playing FFFX # %d...(%s)\n",eFX,FFFX_Lookup[eFX].psName);
|
||||
FF_Play(eFX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// arg 0..n..10000
|
||||
void CMD_FF_Spring(void)
|
||||
{
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Com_Printf ("ff_spring <0..10000>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
long lSpring = atoi(Cmd_Argv(1));
|
||||
if (lSpring<0 || lSpring>10000)
|
||||
{
|
||||
Com_Printf ("ff_spring <0..10000>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pFeelSpring)
|
||||
{
|
||||
Com_Printf(va("Setting spring to %d\n",lSpring));
|
||||
FF_SetSpring(lSpring);
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("No spring device\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Called once only during .exe lifetime...
|
||||
//
|
||||
void FF_Init(qboolean bTryMouseFirst)
|
||||
{
|
||||
FF_Shutdown();
|
||||
|
||||
Cmd_AddCommand ("ff_usemouse", CMD_FF_UseMouse);
|
||||
Cmd_AddCommand ("ff_usejoy", CMD_FF_UseJoy);
|
||||
Cmd_AddCommand ("ff_tension", CMD_FF_Tension);
|
||||
Cmd_AddCommand ("ff_spring", CMD_FF_Spring);
|
||||
Cmd_AddCommand ("ff_play", CMD_FF_Play);
|
||||
|
||||
// ====================================
|
||||
|
||||
Com_Printf("\n" S_COLOR_CYAN "------- Force Feedback Initialization -------\n");
|
||||
|
||||
// for the moment default to OFF until usage tables are in...
|
||||
use_ff = Cvar_Get ("use_ff", "0", CVAR_ARCHIVE);
|
||||
ff_defaultTension = Cvar_Get ("ff_defaultTension", "1", CVAR_ARCHIVE);
|
||||
|
||||
// don't bother initializing if user specifically turned off force feedback...
|
||||
//
|
||||
if (!use_ff->value)
|
||||
{
|
||||
Com_Printf("...inhibited, not initializing\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf("Creating feedback device:\n");
|
||||
|
||||
if ( bTryMouseFirst )
|
||||
{
|
||||
CFeelMouse* m_pFeelMouse = new CFeelMouse;
|
||||
if (m_pFeelMouse)
|
||||
{
|
||||
if (m_pFeelMouse->Initialize( g_wv.hInstance, g_wv.hWnd))
|
||||
{
|
||||
g_pFeelDevice = m_pFeelMouse;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_pFeelMouse;
|
||||
m_pFeelMouse = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_pFeelDevice)
|
||||
{
|
||||
// try a general DI FF device...
|
||||
//
|
||||
CFeelDXDevice* m_pFeelDXDevice = new CFeelDXDevice;
|
||||
if (m_pFeelDXDevice)
|
||||
{
|
||||
if (m_pFeelDXDevice->Initialize( g_wv.hInstance, g_wv.hWnd))
|
||||
{
|
||||
g_pFeelDevice = m_pFeelDXDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_pFeelDXDevice;
|
||||
m_pFeelDXDevice = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// g_pFeelDevice = CFeelDevice::CreateDevice(g_wv.hInstance, g_wv.hWnd);
|
||||
if (!g_pFeelDevice)
|
||||
{
|
||||
Com_Printf("...no feedback devices found\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_FeelInitEffects();
|
||||
|
||||
for (int _i=0; _i<MAX_CONCURRENT_FFFXs; _i++)
|
||||
{
|
||||
ffFXLoaded[_i] = fffx_NULL;
|
||||
}
|
||||
|
||||
if (g_pFeelDevice->GetDeviceType() == FEEL_DEVICETYPE_MOUSE)
|
||||
{
|
||||
Com_Printf("...found FEELit Mouse\n");
|
||||
g_pFeelDevice->UsesWin32MouseServices(FALSE);
|
||||
}
|
||||
else if (g_pFeelDevice->GetDeviceType() == FEEL_DEVICETYPE_DIRECTINPUT)
|
||||
{
|
||||
Com_Printf("...found feedback device\n");
|
||||
g_pFeelSpring = new CFeelSpring;
|
||||
if (!g_pFeelSpring->Initialize( g_pFeelDevice,
|
||||
2000, //10000, // LONG lStiffness = FEEL_SPRING_DEFAULT_STIFFNESS
|
||||
10000, //5000, // DWORD dwSaturation = FEEL_SPRING_DEFAULT_SATURATION
|
||||
1000, //0, // DWORD dwDeadband = FEEL_SPRING_DEFAULT_DEADBAND // must be 0..n..10000
|
||||
FEEL_EFFECT_AXIS_BOTH, // DWORD dwfAxis = FEEL_EFFECT_AXIS_BOTH
|
||||
FEEL_SPRING_DEFAULT_CENTER_POINT, // POINT pntCenter = FEEL_SPRING_DEFAULT_CENTER_POINT
|
||||
FEEL_EFFECT_DEFAULT_DIRECTION_X, // LONG lDirectionX = FEEL_EFFECT_DEFAULT_DIRECTION_X
|
||||
FEEL_EFFECT_DEFAULT_DIRECTION_Y, // LONG lDirectionY = FEEL_EFFECT_DEFAULT_DIRECTION_Y
|
||||
TRUE // TRUE = rel coords, else screen coords // BOOL bUseDeviceCoordinates = FALSE
|
||||
)
|
||||
)
|
||||
{
|
||||
Com_Printf("...(no device return spring)\n");
|
||||
delete g_pFeelSpring;
|
||||
g_pFeelSpring = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("...device return spring ok\n");
|
||||
FF_SetTension(ff_defaultTension->integer); // 0..3
|
||||
}
|
||||
}// if (g_pFeelDevice->GetDeviceType() == FEEL_DEVICETYPE_DIRECTINPUT)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// call this at app shutdown... (or when switching controllers)
|
||||
//
|
||||
// (also called by FF_Init in case you're switching controllers so do everything
|
||||
// as if-protected)
|
||||
//
|
||||
void FF_Shutdown(void)
|
||||
{
|
||||
// note the check first before print, since this is called from the init code
|
||||
// as well, and it'd be weird to see the sutdown string first...
|
||||
//
|
||||
if (g_pFeelSpring || g_pFeelDevice)
|
||||
{
|
||||
Com_Printf("\n" S_COLOR_CYAN "------- Force Feedback Shutdown -------\n");
|
||||
}
|
||||
|
||||
if (g_pFeelSpring)
|
||||
{
|
||||
Com_Printf("...closing return spring\n");
|
||||
delete g_pFeelSpring;
|
||||
g_pFeelSpring = NULL;
|
||||
}
|
||||
|
||||
if (g_pFeelDevice)
|
||||
{
|
||||
Com_Printf("...closing feedback device\n");
|
||||
_FF_ClearUsageArray();
|
||||
delete g_pFeelDevice;
|
||||
g_pFeelDevice = NULL;
|
||||
}
|
||||
|
||||
Cmd_RemoveCommand ("ff_usemouse");
|
||||
Cmd_RemoveCommand ("ff_usejoy");
|
||||
Cmd_RemoveCommand ("ff_tension");
|
||||
Cmd_RemoveCommand ("ff_spring");
|
||||
Cmd_RemoveCommand ("ff_play");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void FF_EnsurePlaying(ffFX_e fffx)
|
||||
{
|
||||
if (fffx<0 || fffx>=fffx_NUMBEROF)
|
||||
return;
|
||||
|
||||
// if user has specifically turned off force feedback at command line,
|
||||
// or is not using the joystick as current input method (though this can be ignored because stick has a hands-on sensor),
|
||||
// then forget it...
|
||||
//
|
||||
if (!use_ff->value)
|
||||
return;
|
||||
|
||||
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
// Have we already got this FF FX loaded?
|
||||
//
|
||||
for (int i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i]==fffx)
|
||||
{
|
||||
// yes, is it playing now?
|
||||
//
|
||||
if (_FeelEffectPlaying(i))
|
||||
return;
|
||||
|
||||
_FF_PlayFXSlot(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if we got this far then it ain't even loaded, so...
|
||||
//
|
||||
FF_Play(fffx);
|
||||
|
||||
}// if (FF_IsAvailable())
|
||||
|
||||
}// void FF_EnsurePlaying(ffFX_e fffx)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// strictly speaking I suppose I should check that the current player is actually using a
|
||||
// joystick as his current input method before sending an FF FX to it, but considering the stick
|
||||
// will only move if he's holding it then he's daft to hold it and still use the keyboard or
|
||||
// something, so for now I'll just leave it in to avoid yet another IF statement...
|
||||
//
|
||||
// Since the joystick appears to run out of FX ram very quickly I'll have to use a sort of rolling
|
||||
// buffer principle I think...
|
||||
//
|
||||
// (watch the mid-func returns if you put anything at the end!)
|
||||
//
|
||||
void _FF_Play(ffFX_e fffx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (fffx<0 || fffx>=fffx_NUMBEROF)
|
||||
return;
|
||||
|
||||
// if user has specifically turned off force feedback at command line,
|
||||
// or is not using the joystick as current input method (though this can be ignored because stick has a hands-on sensor),
|
||||
// then forget it...
|
||||
//
|
||||
if (!use_ff->value)
|
||||
return;
|
||||
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
// first, search for an instance of this FF FX that's already loaded, if found, start it off again...
|
||||
//
|
||||
for (i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i]==fffx)
|
||||
{
|
||||
_FF_PlayFXSlot(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ok, so we didn't find one of these already here, so search for any FF FX that's loaded but
|
||||
// finished playing...
|
||||
//
|
||||
// (note that I prefer to re-use an existing one before looking for an empty slot so
|
||||
// there's less chance of the create call failing because of lack of j/s ram)
|
||||
//
|
||||
for (i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i] != fffx_NULL)
|
||||
{
|
||||
// slot has an effect, has it finished?
|
||||
//
|
||||
if (!_FeelEffectPlaying(i))
|
||||
{
|
||||
_FF_ClearCreatePlayFXSlot(i,fffx);
|
||||
return;
|
||||
}
|
||||
|
||||
}// if (lpDIEffectsCreated[i])
|
||||
}// for (i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
|
||||
// At this point we haven't found an existing one to re-start, and there are no dead ones to reclaim, so
|
||||
// we just look for an empty slot...
|
||||
//
|
||||
for (i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i] == fffx_NULL)
|
||||
{
|
||||
_FF_CreatePlayFXSlot(i,fffx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hmmm, we seem to have several FF FX's playing at once and we need another. Let's just trash one of the slots
|
||||
// and take it over anyway. I'll use the second slot in case the first is some sort of permanent engine throb
|
||||
// or similar...
|
||||
//
|
||||
_FF_ClearCreatePlayFXSlot(1,fffx);
|
||||
|
||||
}// if (FF_IsAvailable())
|
||||
|
||||
}// void FF_Play(ffFX_e fffx)
|
||||
|
||||
|
||||
// hack-wrapper around original play() function because the stick keeps going slack!
|
||||
//
|
||||
void FF_Play(ffFX_e fffx)
|
||||
{
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
_FF_Play(fffx);
|
||||
FF_SetTension(ff_defaultTension->integer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void _FF_ClearUsageArray(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
_FF_ClearFXSlot(i);
|
||||
}
|
||||
}
|
||||
|
||||
// called from more than one place, subroutinised to avoid bugs if method changes...
|
||||
//
|
||||
void _FF_ClearFXSlot(int i)
|
||||
{
|
||||
if (ffFXLoaded[i] != fffx_NULL)
|
||||
{
|
||||
_FeelClearEffect(i);
|
||||
}
|
||||
ffFXLoaded [i]=fffx_NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void _FF_ClearCreatePlayFXSlot(int iSlotNum, ffFX_e fffx)
|
||||
{
|
||||
// if this slot has a FF FX, zap it...
|
||||
//
|
||||
|
||||
if (ffFXLoaded[iSlotNum] != fffx_NULL)
|
||||
{
|
||||
// if playing, stop it...
|
||||
//
|
||||
if (_FeelEffectPlaying(iSlotNum))
|
||||
{
|
||||
if (!_FeelStopEffect(iSlotNum))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_FF_ClearFXSlot(iSlotNum); // so slot is left clear if err creating next ffFX_e
|
||||
_FF_CreatePlayFXSlot(iSlotNum,fffx);
|
||||
}
|
||||
|
||||
void _FF_CreatePlayFXSlot(int iSlotNum, ffFX_e fffx)
|
||||
{
|
||||
if (!_FeelCreateEffect(iSlotNum, fffx, g_pFeelDevice))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// effect created ok, so record it's type...
|
||||
//
|
||||
ffFXLoaded[iSlotNum]=fffx;
|
||||
//
|
||||
// ... and start it playing...
|
||||
//
|
||||
_FF_PlayFXSlot(iSlotNum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _FF_PlayFXSlot(int iSlotNum)
|
||||
{
|
||||
|
||||
#define FFFX_DURATION 1 // 1 = duration (repeat count?) (could be 'INFINITE')
|
||||
#define FFFX_FLAGS 0 // 0 = special flags
|
||||
|
||||
if (!_FeelStartEffect(iSlotNum, FFFX_DURATION, FFFX_FLAGS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FF_StopAll(void)
|
||||
{
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
for (int i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i] != fffx_NULL)
|
||||
{
|
||||
/*BOOL bRes = */_FeelStopEffect(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FF_Stop(ffFX_e fffx)
|
||||
{
|
||||
if (fffx<0 || fffx>=fffx_NUMBEROF)
|
||||
return;
|
||||
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
for (int i=0; i<MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
if (ffFXLoaded[i] == fffx)
|
||||
{
|
||||
/*BOOL bRes = */_FeelStopEffect(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 0..n..10000
|
||||
//
|
||||
qboolean FF_SetSpring(long lSpring)
|
||||
{
|
||||
static qboolean bFXPlaying = FALSE;
|
||||
|
||||
if (FF_IsAvailable())
|
||||
{
|
||||
// this plays a spring effect, and set the tension accordingly. Tension of 0 results in an effect-stop call
|
||||
//
|
||||
if (g_pFeelSpring)
|
||||
{
|
||||
if (lSpring)
|
||||
{
|
||||
if (!bFXPlaying && !g_pFeelSpring->Start())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
bFXPlaying = TRUE;
|
||||
|
||||
static POINT p={0,0};
|
||||
g_pFeelSpring->ChangeParameters(p, lSpring);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bFXPlaying && !g_pFeelSpring->Stop())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
bFXPlaying = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// tension is 0 (none) to 3 (max)...
|
||||
//
|
||||
qboolean FF_SetTension(int iTension)
|
||||
{
|
||||
static long lSpringValues[4] = {0, 1000, 5000, 10000};
|
||||
|
||||
if (iTension>3)
|
||||
iTension=3;
|
||||
if (iTension<0)
|
||||
iTension=0;
|
||||
|
||||
return FF_SetSpring(lSpringValues[iTension]);
|
||||
}
|
||||
|
||||
///////////////////////// eof //////////////////////////////
|
||||
|
||||
689
code/win32/FeelIt/fffx_feel.cpp
Normal file
689
code/win32/FeelIt/fffx_feel.cpp
Normal file
@@ -0,0 +1,689 @@
|
||||
// Filename:- fffx_Feel.cpp (Force-Feedback FX)
|
||||
|
||||
#include "../../client/client.h"
|
||||
//#include "stdafx.h"
|
||||
//#include "resource.h"
|
||||
#include "fffx_feel.h"
|
||||
|
||||
extern cvar_t* js_ffmult;
|
||||
|
||||
|
||||
#define MAX_EFFECTS_IN_COMPOUND 3 // This needs to be at least 3 for now. I can add array bounds checking later
|
||||
|
||||
CFeelEffect* g_pEffects[MAX_CONCURRENT_FFFXs][MAX_EFFECTS_IN_COMPOUND];
|
||||
|
||||
void _FeelInitEffects()
|
||||
{
|
||||
for (int i = 0; i < MAX_CONCURRENT_FFFXs; i++)
|
||||
{
|
||||
for (int j = 0; j < MAX_EFFECTS_IN_COMPOUND; j++)
|
||||
{
|
||||
g_pEffects[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL _FeelCreateEffect(int iSlotNum, ffFX_e fffx, CFeelDevice* pFeelDevice)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
FEELIT_ENVELOPE envelope;
|
||||
envelope.dwSize = sizeof(FEELIT_ENVELOPE);
|
||||
|
||||
switch (fffx)
|
||||
{
|
||||
case fffx_RandomNoise:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
7500 * js_ffmult->value, // magnitude
|
||||
95, // period
|
||||
10000, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_SawtoothDown);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
8300 * js_ffmult->value, // magnitude
|
||||
160, // period
|
||||
10000, // duration
|
||||
9000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][2] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][2]))->InitializePolar(pFeelDevice,
|
||||
8300 * js_ffmult->value, // magnitude
|
||||
34, // period
|
||||
10000, // duration
|
||||
31000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_AircraftCarrierTakeOff:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 600000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 750000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
2500, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_BasketballDribble:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 40000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 30000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
18000, // angle
|
||||
150, // duration
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_CarEngineIdle:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
2500 * js_ffmult->value, // magnitude
|
||||
50, // period
|
||||
10000, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_ChainsawIdle:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
3600 * js_ffmult->value, // magnitude
|
||||
60, // period
|
||||
1000, // duration
|
||||
9000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
4000 * js_ffmult->value, // magnitude
|
||||
100, // period
|
||||
1000, // duration
|
||||
18000, // angle
|
||||
4000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_ChainsawInAction:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
6700 * js_ffmult->value, // magnitude
|
||||
60, // period
|
||||
1000, // duration
|
||||
9000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
100, // period
|
||||
1000, // duration
|
||||
18000, // angle
|
||||
5000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][2] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][2]))->InitializePolar(pFeelDevice,
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
340, // period
|
||||
1000, // duration
|
||||
18000, // angle
|
||||
4000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_DieselEngineIdle:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_SawtoothDown);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
2000 * js_ffmult->value, // magnitude
|
||||
250, // period
|
||||
10000, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
4000 * js_ffmult->value, // magnitude
|
||||
125, // period
|
||||
10000, // duration
|
||||
18000, // angle
|
||||
1500, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Jump:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
500, // period
|
||||
300, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Land:
|
||||
envelope.dwAttackLevel = 6000;
|
||||
envelope.dwAttackTime = 200000;
|
||||
envelope.dwFadeLevel = 3000;
|
||||
envelope.dwFadeTime = 50000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
1000 * js_ffmult->value, // magnitude
|
||||
750, // period
|
||||
250, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_MachineGun:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
3500 * js_ffmult->value, // magnitude
|
||||
70, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
2500, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Punched:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 0;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 50000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
8000 * js_ffmult->value, // magnitude
|
||||
130, // period
|
||||
70, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_RocketLaunch:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 200000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 0;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
18000, // angle
|
||||
400, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 300000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 100000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
1000, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_SecretDoor:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 400000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 0;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
400, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_SwitchClick:
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
18000, // angle
|
||||
50, // duration
|
||||
7000 * js_ffmult->value, // magnitude
|
||||
NULL))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_WindGust:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
1000, // period
|
||||
500, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_WindShear:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 1500000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 500000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_SawtoothDown);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
80, // period
|
||||
2000, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Pistol:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
8500 * js_ffmult->value, // magnitude
|
||||
130, // period
|
||||
50, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Shotgun:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
100, // period
|
||||
100, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 100000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 100000;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
300, // duration
|
||||
7000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser1:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
18000, // angle
|
||||
2000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser2:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
3000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser3:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
9000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser4:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
7000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
9000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser5:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Laser6:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
25, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
2000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_OutOfAmmo:
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
18000, // angle
|
||||
10, // duration
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
NULL))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_LightningGun:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
1500 * js_ffmult->value, // magnitude
|
||||
250, // period
|
||||
1000, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
|
||||
success = FALSE;
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
50, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Missile:
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 500000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 200000;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
250, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_GatlingGun:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_SawtoothDown);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
100, // period
|
||||
1000, // duration
|
||||
0, // angle
|
||||
1000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_ShortPlasma:
|
||||
envelope.dwAttackLevel = 7000;
|
||||
envelope.dwAttackTime = 250000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 0;
|
||||
|
||||
g_pEffects[iSlotNum][0] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
250, // duration
|
||||
0, // magnitude
|
||||
&envelope))// envelope
|
||||
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 0;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 250000;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
30, // period
|
||||
250, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_PlasmaCannon1:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
5000 * js_ffmult->value, // magnitude
|
||||
500, // period
|
||||
400, // duration
|
||||
18000, // angle
|
||||
-5000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 250000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 0;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
6000 * js_ffmult->value, // magnitude
|
||||
30, // period
|
||||
250, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_PlasmaCannon2:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
4000 * js_ffmult->value, // magnitude
|
||||
1000, // period
|
||||
800, // duration
|
||||
18000, // angle
|
||||
-4000, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 500000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 0;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelPeriodic(GUID_Feel_Sine);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
8000 * js_ffmult->value, // magnitude
|
||||
35, // period
|
||||
500, // duration
|
||||
0, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
&envelope)) // envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
case fffx_Cannon:
|
||||
g_pEffects[iSlotNum][0] = new CFeelPeriodic(GUID_Feel_Square);
|
||||
if (!((CFeelPeriodic*)(g_pEffects[iSlotNum][0]))->InitializePolar(pFeelDevice,
|
||||
8000 * js_ffmult->value, // magnitude
|
||||
100, // period
|
||||
100, // duration
|
||||
18000, // angle
|
||||
0, // offset
|
||||
0, // phase
|
||||
NULL)) // envelope
|
||||
success = FALSE;
|
||||
|
||||
envelope.dwAttackLevel = 0;
|
||||
envelope.dwAttackTime = 100000;
|
||||
envelope.dwFadeLevel = 0;
|
||||
envelope.dwFadeTime = 100000;
|
||||
|
||||
g_pEffects[iSlotNum][1] = new CFeelConstant;
|
||||
if (!((CFeelConstant*)(g_pEffects[iSlotNum][1]))->InitializePolar(pFeelDevice,
|
||||
0, // angle
|
||||
300, // duration
|
||||
10000 * js_ffmult->value, // magnitude
|
||||
&envelope))// envelope
|
||||
success = FALSE;
|
||||
break;
|
||||
}// switch (fffx)
|
||||
|
||||
// if any effect in the compound failed to initialize, dump the lot
|
||||
if (!success)
|
||||
{
|
||||
for (int i = 0; i < MAX_EFFECTS_IN_COMPOUND; i++)
|
||||
{
|
||||
if (g_pEffects[iSlotNum][i])
|
||||
{
|
||||
delete g_pEffects[iSlotNum][i];
|
||||
g_pEffects[iSlotNum][i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL _FeelStartEffect(int iSlotNum, DWORD dwIterations, DWORD dwFlags)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
for (int i = 0; i < MAX_EFFECTS_IN_COMPOUND; i++)
|
||||
{
|
||||
if (g_pEffects[iSlotNum][i])
|
||||
{
|
||||
if (!g_pEffects[iSlotNum][i]->Start(dwIterations, dwFlags))
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL _FeelEffectPlaying(int iSlotNum)
|
||||
{
|
||||
DWORD dwFlags;
|
||||
dwFlags = 0;
|
||||
|
||||
// check to see if any effect within the compound is still playing
|
||||
for (int i = 0; i < MAX_EFFECTS_IN_COMPOUND; i++)
|
||||
{
|
||||
if (g_pEffects[iSlotNum][i])
|
||||
{
|
||||
g_pEffects[iSlotNum][i]->GetStatus(&dwFlags);
|
||||
if (dwFlags & FEELIT_FSTATUS_PLAYING)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL _FeelStopEffect(int iSlotNum)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
for (int i = 0; i < MAX_EFFECTS_IN_COMPOUND; i++)
|
||||
{
|
||||
if (g_pEffects[iSlotNum][i])
|
||||
{
|
||||
if (!g_pEffects[iSlotNum][i]->Stop())
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL _FeelClearEffect(int iSlotNum)
|
||||
{
|
||||
for (int i = 0; i < MAX_EFFECTS_IN_COMPOUND; i++)
|
||||
{
|
||||
if (g_pEffects[iSlotNum][i])
|
||||
{
|
||||
delete g_pEffects[iSlotNum][i];
|
||||
g_pEffects[iSlotNum][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
29
code/win32/FeelIt/fffx_feel.h
Normal file
29
code/win32/FeelIt/fffx_feel.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Filename:- fffx_Feel.h (Force-Feedback FX)
|
||||
// ADDED BY IMMRESION
|
||||
|
||||
#ifndef FFFX_FEEL_H
|
||||
#define FFFX_FEEL_H
|
||||
|
||||
#include "../../client/fffx.h"
|
||||
#include "ffc.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
/* These functions were created to make the code a little easier to read.
|
||||
* _FeelCreateEffect is quite long since it needs to create different
|
||||
* kinds of effects. When playing effects, the number of iterations
|
||||
* may not act as expected. I can't use CFeelCompound effects since I
|
||||
* don't have a Project (which requires an ifr file at this point). So,
|
||||
* I simulate compound effects with arrays. If an effect has multiple
|
||||
* CFeelEffect in it, each CFeelEffect will be started individually with
|
||||
* that number of iterations. The only case where this will act strange
|
||||
* is when the CFeelEffects have different durations.
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
void _FeelInitEffects();
|
||||
BOOL _FeelCreateEffect(int iSlotNum, ffFX_e fffx, CFeelDevice* pFeelDevice);
|
||||
BOOL _FeelStartEffect(int iSlotNum, DWORD dwIterations, DWORD dwFlags);
|
||||
BOOL _FeelEffectPlaying(int iSlotNum);
|
||||
BOOL _FeelStopEffect(int iSlotNum);
|
||||
BOOL _FeelClearEffect(int iSlotNum);
|
||||
|
||||
#endif // #ifndef FFFX_FEEL_H
|
||||
BIN
code/win32/background.bmp
Normal file
BIN
code/win32/background.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 193 KiB |
620
code/win32/bink.h
Normal file
620
code/win32/bink.h
Normal file
@@ -0,0 +1,620 @@
|
||||
#ifndef BINKH
|
||||
#define BINKH
|
||||
|
||||
#define BINKVERSION "1.0p"
|
||||
#define BINKDATE "2000-06-26"
|
||||
|
||||
#ifndef __RADRES__
|
||||
|
||||
#include "rad.h"
|
||||
|
||||
RADDEFSTART
|
||||
|
||||
typedef struct BINK PTR4* HBINK;
|
||||
|
||||
typedef s32 (RADLINK PTR4* BINKIOOPEN) (struct BINKIO PTR4* Bnkio, const char PTR4 *name, u32 flags);
|
||||
typedef u32 (RADLINK PTR4* BINKIOREADHEADER) (struct BINKIO PTR4* Bnkio, s32 Offset, void PTR4* Dest,u32 Size);
|
||||
typedef u32 (RADLINK PTR4* BINKIOREADFRAME) (struct BINKIO PTR4* Bnkio, u32 Framenum,s32 origofs,void PTR4* dest,u32 size);
|
||||
typedef u32 (RADLINK PTR4* BINKIOGETBUFFERSIZE)(struct BINKIO PTR4* Bnkio, u32 Size);
|
||||
typedef void (RADLINK PTR4* BINKIOSETINFO) (struct BINKIO PTR4* Bnkio, void PTR4* Buf,u32 Size,u32 FileSize,u32 simulate);
|
||||
typedef u32 (RADLINK PTR4* BINKIOIDLE) (struct BINKIO PTR4* Bnkio);
|
||||
typedef void (RADLINK PTR4* BINKIOCLOSE) (struct BINKIO PTR4* Bnkio);
|
||||
|
||||
typedef struct BINKIO {
|
||||
BINKIOREADHEADER ReadHeader;
|
||||
BINKIOREADFRAME ReadFrame;
|
||||
BINKIOGETBUFFERSIZE GetBufferSize;
|
||||
BINKIOSETINFO SetInfo;
|
||||
BINKIOIDLE Idle;
|
||||
BINKIOCLOSE Close;
|
||||
HBINK bink;
|
||||
volatile u32 ReadError;
|
||||
volatile u32 DoingARead;
|
||||
volatile u32 BytesRead;
|
||||
volatile u32 Working;
|
||||
volatile u32 TotalTime;
|
||||
volatile u32 ForegroundTime;
|
||||
volatile u32 IdleTime;
|
||||
volatile u32 ThreadTime;
|
||||
volatile u32 BufSize;
|
||||
volatile u32 BufHighUsed;
|
||||
volatile u32 CurBufSize;
|
||||
volatile u32 CurBufUsed;
|
||||
volatile u8 iodata[128];
|
||||
} BINKIO;
|
||||
|
||||
typedef s32 (RADLINK PTR4* BINKSNDOPEN) (struct BINKSND PTR4* BnkSnd, u32 freq, s32 bits, s32 chans, u32 flags, HBINK bink);
|
||||
typedef s32 (RADLINK PTR4* BINKSNDREADY) (struct BINKSND PTR4* BnkSnd);
|
||||
typedef s32 (RADLINK PTR4* BINKSNDLOCK) (struct BINKSND PTR4* BnkSnd, u8 PTR4* PTR4* addr, u32 PTR4* len);
|
||||
typedef s32 (RADLINK PTR4* BINKSNDUNLOCK) (struct BINKSND PTR4* BnkSnd, u32 filled);
|
||||
typedef void (RADLINK PTR4* BINKSNDVOLUME) (struct BINKSND PTR4* BnkSnd, s32 volume);
|
||||
typedef void (RADLINK PTR4* BINKSNDPAN) (struct BINKSND PTR4* BnkSnd, s32 pan);
|
||||
typedef s32 (RADLINK PTR4* BINKSNDONOFF) (struct BINKSND PTR4* BnkSnd, s32 status);
|
||||
typedef s32 (RADLINK PTR4* BINKSNDPAUSE) (struct BINKSND PTR4* BnkSnd, s32 status);
|
||||
typedef void (RADLINK PTR4* BINKSNDCLOSE) (struct BINKSND PTR4* BnkSnd);
|
||||
|
||||
typedef BINKSNDOPEN (RADLINK PTR4* BINKSNDSYSOPEN) (u32 param);
|
||||
|
||||
typedef struct BINKSND {
|
||||
BINKSNDREADY Ready;
|
||||
BINKSNDLOCK Lock;
|
||||
BINKSNDUNLOCK Unlock;
|
||||
BINKSNDVOLUME Volume;
|
||||
BINKSNDPAN Pan;
|
||||
BINKSNDPAUSE Pause;
|
||||
BINKSNDONOFF SetOnOff;
|
||||
BINKSNDCLOSE Close;
|
||||
u32 BestSizeIn16;
|
||||
u32 SoundDroppedOut;
|
||||
s32 OnOff;
|
||||
u32 Latency;
|
||||
u32 freq;
|
||||
s32 bits,chans;
|
||||
u8 snddata[128];
|
||||
} BINKSND;
|
||||
|
||||
typedef struct BINKRECT {
|
||||
s32 Left,Top,Width,Height;
|
||||
} BINKRECT;
|
||||
|
||||
#define BINKMAXDIRTYRECTS 8
|
||||
|
||||
typedef struct BUNDLEPOINTERS {
|
||||
void* typeptr;
|
||||
void* type16ptr;
|
||||
void* colorptr;
|
||||
void* bits2ptr;
|
||||
void* motionXptr;
|
||||
void* motionYptr;
|
||||
void* dctptr;
|
||||
void* mdctptr;
|
||||
void* patptr;
|
||||
} BUNDLEPOINTERS;
|
||||
|
||||
|
||||
typedef struct BINK {
|
||||
u32 Width; // Width (1 based, 640 for example)
|
||||
u32 Height; // Height (1 based, 480 for example)
|
||||
u32 Frames; // Number of frames (1 based, 100 = 100 frames)
|
||||
u32 FrameNum; // Frame to *be* displayed (1 based)
|
||||
u32 LastFrameNum; // Last frame decompressed or skipped (1 based)
|
||||
|
||||
u32 FrameRate; // Frame Rate Numerator
|
||||
u32 FrameRateDiv; // Frame Rate Divisor (frame rate=numerator/divisor)
|
||||
|
||||
u32 ReadError; // Non-zero if a read error has ocurred
|
||||
u32 OpenFlags; // flags used on open
|
||||
u32 BinkType; // Bink flags
|
||||
|
||||
u32 Size; // size of file
|
||||
u32 FrameSize; // The current frame's size in bytes
|
||||
u32 SndSize; // The current frame sound tracks' size in bytes
|
||||
|
||||
BINKRECT FrameRects[BINKMAXDIRTYRECTS];// Dirty rects from BinkGetRects
|
||||
s32 NumRects;
|
||||
|
||||
u32 PlaneNum; // which set of planes is current
|
||||
void PTR4* YPlane[2]; // pointer to the uncompressed Y (Cr and Cr follow)
|
||||
void PTR4* APlane[2]; // decompressed alpha plane (if present)
|
||||
u32 YWidth; // widths and heights of the video planes
|
||||
u32 YHeight;
|
||||
u32 UVWidth;
|
||||
u32 UVHeight;
|
||||
|
||||
void PTR4* MaskPlane; // pointer to the mask plane (Ywidth/16*Yheight/16)
|
||||
u32 MaskPitch; // Mask Pitch
|
||||
u32 MaskLength; // total length of the mask plane
|
||||
|
||||
u32 LargestFrameSize; // Largest frame size
|
||||
u32 InternalFrames; // how many frames were potentially compressed
|
||||
|
||||
s32 NumTracks; // how many tracks
|
||||
|
||||
u32 Highest1SecRate; // Highest 1 sec data rate
|
||||
u32 Highest1SecFrame; // Highest 1 sec data rate starting frame
|
||||
|
||||
s32 Paused; // is the bink movie paused?
|
||||
|
||||
u32 BackgroundThread; // handle to background thread
|
||||
|
||||
// everything below is for internal Bink use
|
||||
|
||||
void PTR4* compframe; // compressed frame data
|
||||
void PTR4* preloadptr; // preloaded compressed frame data
|
||||
u32* frameoffsets; // offsets of each of the frames
|
||||
|
||||
BINKIO bio; // IO structure
|
||||
u8 PTR4* ioptr; // io buffer ptr
|
||||
u32 iosize; // io buffer size
|
||||
u32 decompwidth; // width not include scaling
|
||||
u32 decompheight; // height not include scaling
|
||||
|
||||
s32 trackindex; // track index
|
||||
u32 PTR4* tracksizes; // largest single frame of track
|
||||
u32 PTR4* tracktypes; // type of each sound track
|
||||
s32 PTR4* trackIDs; // external track numbers
|
||||
|
||||
u32 numrects; // number of rects from BinkGetRects
|
||||
|
||||
u32 playedframes; // how many frames have we played
|
||||
u32 firstframetime; // very first frame start
|
||||
u32 startframetime; // start frame start
|
||||
u32 startblittime; // start of blit period
|
||||
u32 startsynctime; // start of synched time
|
||||
u32 startsyncframe; // frame of startsynctime
|
||||
u32 twoframestime; // two frames worth of time
|
||||
u32 entireframetime; // entire frame time
|
||||
|
||||
u32 slowestframetime; // slowest frame in ms
|
||||
u32 slowestframe; // slowest frame number
|
||||
u32 slowest2frametime; // second slowest frame in ms
|
||||
u32 slowest2frame; // second slowest frame
|
||||
|
||||
u32 soundon; // sound turned on?
|
||||
u32 videoon; // video turned on?
|
||||
|
||||
u32 totalmem; // total memory used
|
||||
u32 timevdecomp; // total time decompressing video
|
||||
u32 timeadecomp; // total time decompressing audio
|
||||
u32 timeblit; // total time blitting
|
||||
u32 timeopen; // total open time
|
||||
|
||||
u32 fileframerate; // frame rate originally in the file
|
||||
u32 fileframeratediv;
|
||||
|
||||
volatile u32 threadcontrol; // controls the background reading thread
|
||||
|
||||
u32 runtimeframes; // max frames for runtime analysis
|
||||
u32 runtimemoveamt; // bytes to move each frame
|
||||
u32 PTR4* rtframetimes; // start times for runtime frames
|
||||
u32 PTR4* rtadecomptimes; // decompress times for runtime frames
|
||||
u32 PTR4* rtvdecomptimes; // decompress times for runtime frames
|
||||
u32 PTR4* rtblittimes; // blit times for runtime frames
|
||||
u32 PTR4* rtreadtimes; // read times for runtime frames
|
||||
u32 PTR4* rtidlereadtimes; // idle read times for runtime frames
|
||||
u32 PTR4* rtthreadreadtimes;// thread read times for runtime frames
|
||||
|
||||
u32 lastblitflags; // flags used on last blit
|
||||
u32 lastdecompframe; // last frame number decompressed
|
||||
|
||||
u32 sndbufsize; // sound buffer size
|
||||
u8 PTR4* sndbuf; // sound buffer
|
||||
u8 PTR4* sndend; // end of the sound buffer
|
||||
u8 PTR4* sndwritepos; // current write position
|
||||
u8 PTR4* sndreadpos; // current read position
|
||||
u32 sndcomp; // sound compression handle
|
||||
u32 sndamt; // amount of sound currently in the buffer
|
||||
volatile u32 sndreenter; // re-entrancy check on the sound
|
||||
u32 sndconvert8; // convert back to 8-bit sound at runtime
|
||||
BINKSND bsnd; // SND structure
|
||||
u32 skippedlastblit; // skipped last frame?
|
||||
u32 skippedblits; // how many blits were skipped
|
||||
u32 soundskips; // number of sound stops
|
||||
u32 sndendframe; // frame number that the sound ends on
|
||||
u32 sndprime; // amount of data to prime the playahead
|
||||
u32 sndpad; // padded this much audio
|
||||
|
||||
BUNDLEPOINTERS bunp; // pointers to internal temporary memory
|
||||
} BINK;
|
||||
|
||||
|
||||
typedef struct BINKSUMMARY {
|
||||
u32 Width; // Width of frames
|
||||
u32 Height; // Height of frames
|
||||
u32 TotalTime; // total time (ms)
|
||||
u32 FileFrameRate; // frame rate
|
||||
u32 FileFrameRateDiv; // frame rate divisor
|
||||
u32 FrameRate; // frame rate
|
||||
u32 FrameRateDiv; // frame rate divisor
|
||||
u32 TotalOpenTime; // Time to open and prepare for decompression
|
||||
u32 TotalFrames; // Total Frames
|
||||
u32 TotalPlayedFrames; // Total Frames played
|
||||
u32 SkippedFrames; // Total number of skipped frames
|
||||
u32 SkippedBlits; // Total number of skipped blits
|
||||
u32 SoundSkips; // Total number of sound skips
|
||||
u32 TotalBlitTime; // Total time spent blitting
|
||||
u32 TotalReadTime; // Total time spent reading
|
||||
u32 TotalVideoDecompTime; // Total time spent decompressing video
|
||||
u32 TotalAudioDecompTime; // Total time spent decompressing audio
|
||||
u32 TotalIdleReadTime; // Total time spent reading while idle
|
||||
u32 TotalBackReadTime; // Total time spent reading in background
|
||||
u32 TotalReadSpeed; // Total io speed (bytes/second)
|
||||
u32 SlowestFrameTime; // Slowest single frame time (ms)
|
||||
u32 Slowest2FrameTime; // Second slowest single frame time (ms)
|
||||
u32 SlowestFrameNum; // Slowest single frame number
|
||||
u32 Slowest2FrameNum; // Second slowest single frame number
|
||||
u32 AverageDataRate; // Average data rate of the movie
|
||||
u32 AverageFrameSize; // Average size of the frame
|
||||
u32 HighestMemAmount; // Highest amount of memory allocated
|
||||
u32 TotalIOMemory; // Total extra memory allocated
|
||||
u32 HighestIOUsed; // Highest extra memory actually used
|
||||
u32 Highest1SecRate; // Highest 1 second rate
|
||||
u32 Highest1SecFrame; // Highest 1 second start frame
|
||||
} BINKSUMMARY;
|
||||
|
||||
|
||||
typedef struct BINKREALTIME {
|
||||
u32 FrameNum; // Current frame number
|
||||
u32 FrameRate; // frame rate
|
||||
u32 FrameRateDiv; // frame rate divisor
|
||||
u32 Frames; // frames in this sample period
|
||||
u32 FramesTime; // time is ms for these frames
|
||||
u32 FramesVideoDecompTime; // time decompressing these frames
|
||||
u32 FramesAudioDecompTime; // time decompressing these frames
|
||||
u32 FramesReadTime; // time reading these frames
|
||||
u32 FramesIdleReadTime; // time reading these frames at idle
|
||||
u32 FramesThreadReadTime; // time reading these frames in background
|
||||
u32 FramesBlitTime; // time blitting these frames
|
||||
u32 ReadBufferSize; // size of read buffer
|
||||
u32 ReadBufferUsed; // amount of read buffer currently used
|
||||
u32 FramesDataRate; // data rate for these frames
|
||||
} BINKREALTIME;
|
||||
|
||||
#define BINKMARKER1 'fKIB'
|
||||
#define BINKMARKER2 'gKIB' // new Bink files use this tag
|
||||
#define BINKMARKER3 'hKIB' // newer Bink files use this tag
|
||||
#define BINKMARKER4 'iKIB' // even newer Bink files use this tag
|
||||
|
||||
typedef struct BINKHDR {
|
||||
u32 Marker; // Bink marker
|
||||
u32 Size; // size of the file-8
|
||||
u32 Frames; // Number of frames (1 based, 100 = 100 frames)
|
||||
u32 LargestFrameSize; // Size in bytes of largest frame
|
||||
u32 InternalFrames; // Number of internal frames
|
||||
|
||||
u32 Width; // Width (1 based, 640 for example)
|
||||
u32 Height; // Height (1 based, 480 for example)
|
||||
u32 FrameRate; // frame rate
|
||||
u32 FrameRateDiv; // frame rate divisor (framerate/frameratediv=fps)
|
||||
|
||||
u32 Flags; // height compression options
|
||||
u32 NumTracks; // number of tracks
|
||||
} BINKHDR;
|
||||
|
||||
|
||||
//=======================================================================
|
||||
#define BINKFRAMERATE 0x00001000L // Override fr (call BinkFrameRate first)
|
||||
#define BINKPRELOADALL 0x00002000L // Preload the entire animation
|
||||
#define BINKSNDTRACK 0x00004000L // Set the track number to play
|
||||
#define BINKOLDFRAMEFORMAT 0x00008000L // using the old Bink frame format (internal use only)
|
||||
#define BINKRBINVERT 0x00010000L // use reversed R and B planes (internal use only)
|
||||
#define BINKGRAYSCALE 0x00020000L // Force Bink to use grayscale
|
||||
#define BINKNOMMX 0x00040000L // Don't use MMX
|
||||
#define BINKNOSKIP 0x00080000L // Don't skip frames if falling behind
|
||||
#define BINKALPHA 0x00100000L // Decompress alpha plane (if present)
|
||||
#define BINKNOFILLIOBUF 0x00200000L // Fill the IO buffer in SmackOpen
|
||||
#define BINKSIMULATE 0x00400000L // Simulate the speed (call BinkSim first)
|
||||
#define BINKFILEHANDLE 0x00800000L // Use when passing in a file handle
|
||||
#define BINKIOSIZE 0x01000000L // Set an io size (call BinkIOSize first)
|
||||
#define BINKIOPROCESSOR 0x02000000L // Set an io processor (call BinkIO first)
|
||||
#define BINKFROMMEMORY 0x04000000L // Use when passing in a pointer to the file
|
||||
#define BINKNOTHREADEDIO 0x08000000L // Don't use a background thread for IO
|
||||
|
||||
#define BINKSURFACEFAST 0x00000000L
|
||||
#define BINKSURFACESLOW 0x08000000L
|
||||
#define BINKSURFACEDIRECT 0x04000000L
|
||||
|
||||
#define BINKCOPYALL 0x80000000L // copy all pixels (not just changed)
|
||||
#define BINKCOPY2XH 0x10000000L // Force doubling height scaling
|
||||
#define BINKCOPY2XHI 0x20000000L // Force interleaving height scaling
|
||||
#define BINKCOPY2XW 0x30000000L // copy the width zoomed by two
|
||||
#define BINKCOPY2XWH 0x40000000L // copy the width and height zoomed by two
|
||||
#define BINKCOPY2XWHI 0x50000000L // copy the width and height zoomed by two
|
||||
#define BINKCOPY1XI 0x60000000L // copy the width and height zoomed by two
|
||||
#define BINKCOPYNOSCALING 0x70000000L // Force scaling off
|
||||
|
||||
//#define BINKALPHA 0x00100000L // Decompress alpha plane (if present)
|
||||
//#define BINKNOSKIP 0x00080000L // don't skip the blit if behind in sound
|
||||
//#define BINKNOMMX 0x00040000L // Don't skip frames if falling behind
|
||||
//#define BINKGRAYSCALE 0x00020000L // force Bink to use grayscale
|
||||
//#define BINKRBINVERT 0x00010000L // use reversed R and B planes
|
||||
|
||||
#define BINKSURFACE8P 0
|
||||
#define BINKSURFACE24 1
|
||||
#define BINKSURFACE24R 2
|
||||
#define BINKSURFACE32 3
|
||||
#define BINKSURFACE32R 4
|
||||
#define BINKSURFACE32A 5
|
||||
#define BINKSURFACE32RA 6
|
||||
#define BINKSURFACE4444 7
|
||||
#define BINKSURFACE5551 8
|
||||
#define BINKSURFACE555 9
|
||||
#define BINKSURFACE565 10
|
||||
#define BINKSURFACE655 11
|
||||
#define BINKSURFACE664 12
|
||||
#define BINKSURFACEYUY2 13
|
||||
#define BINKSURFACEUYVY 14
|
||||
#define BINKSURFACEYV12 15
|
||||
#define BINKSURFACEMASK 15
|
||||
|
||||
#define BINKGOTOQUICK 1
|
||||
|
||||
#define BINKGETKEYPREVIOUS 0
|
||||
#define BINKGETKEYNEXT 1
|
||||
#define BINKGETKEYCLOSEST 2
|
||||
#define BINKGETKEYNOTEQUAL 128
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#ifdef __RADMAC__
|
||||
#include <files.h>
|
||||
|
||||
#pragma export on
|
||||
|
||||
RADEXPFUNC HBINK RADEXPLINK BinkMacOpen(FSSpec* fsp,u32 flags);
|
||||
#endif
|
||||
|
||||
RADEXPFUNC void PTR4* RADEXPLINK BinkLogoAddress(void);
|
||||
|
||||
RADEXPFUNC void RADEXPLINK BinkSetError(const char PTR4* err);
|
||||
RADEXPFUNC char PTR4* RADEXPLINK BinkGetError(void);
|
||||
|
||||
RADEXPFUNC HBINK RADEXPLINK BinkOpen(const char PTR4* name,u32 flags);
|
||||
|
||||
RADEXPFUNC s32 RADEXPLINK BinkDoFrame(HBINK bnk);
|
||||
RADEXPFUNC void RADEXPLINK BinkNextFrame(HBINK bnk);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkWait(HBINK bnk);
|
||||
RADEXPFUNC void RADEXPLINK BinkClose(HBINK bnk);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkPause(HBINK bnk,s32 pause);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkCopyToBuffer(HBINK bnk,void* dest,s32 destpitch,u32 destheight,u32 destx,u32 desty,u32 flags);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkGetRects(HBINK bnk,u32 flags);
|
||||
RADEXPFUNC void RADEXPLINK BinkGoto(HBINK bnk,u32 frame,s32 flags); // use 1 for the first frame
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetKeyFrame(HBINK bnk,u32 frame,s32 flags);
|
||||
|
||||
RADEXPFUNC s32 RADEXPLINK BinkSetVideoOnOff(HBINK bnk,s32 onoff);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkSetSoundOnOff(HBINK bnk,s32 onoff);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetVolume(HBINK bnk,s32 volume);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetPan(HBINK bnk,s32 pan);
|
||||
RADEXPFUNC void RADEXPLINK BinkService(HBINK bink);
|
||||
|
||||
typedef struct BINKTRACK PTR4* HBINKTRACK;
|
||||
|
||||
typedef struct BINKTRACK
|
||||
{
|
||||
u32 Frequency;
|
||||
u32 Bits;
|
||||
u32 Channels;
|
||||
u32 MaxSize;
|
||||
|
||||
HBINK bink;
|
||||
u32 sndcomp;
|
||||
s32 trackindex;
|
||||
} BINKTRACK;
|
||||
|
||||
|
||||
RADEXPFUNC HBINKTRACK RADEXPLINK BinkOpenTrack(HBINK bnk,u32 trackindex);
|
||||
RADEXPFUNC void RADEXPLINK BinkCloseTrack(HBINKTRACK bnkt);
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetTrackData(HBINKTRACK bnkt,void PTR4* dest);
|
||||
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetTrackType(HBINK bnk,u32 trackindex);
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetTrackMaxSize(HBINK bnk,u32 trackindex);
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetTrackID(HBINK bnk,u32 trackindex);
|
||||
RADEXPFUNC u32 RADEXPLINK BinkGetTrackLargest(HBINK bnk,u32 trackindex);
|
||||
|
||||
RADEXPFUNC void RADEXPLINK BinkGetSummary(HBINK bnk,BINKSUMMARY PTR4* sum);
|
||||
RADEXPFUNC void RADEXPLINK BinkGetRealtime(HBINK bink,BINKREALTIME PTR4* run,u32 frames);
|
||||
|
||||
#define BINKNOSOUND 0xffffffff
|
||||
|
||||
RADEXPFUNC void RADEXPLINK BinkSetSoundTrack(u32 track);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetIO(BINKIOOPEN io);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetFrameRate(u32 forcerate,u32 forceratediv);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetSimulate(u32 sim);
|
||||
RADEXPFUNC void RADEXPLINK BinkSetIOSize(u32 iosize);
|
||||
|
||||
RADEXPFUNC s32 RADEXPLINK BinkSetSoundSystem(BINKSNDSYSOPEN open, u32 param);
|
||||
|
||||
#ifdef __RADWIN__
|
||||
|
||||
RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenDirectSound(u32 param); // don't call directly
|
||||
#define BinkSoundUseDirectSound(lpDS) BinkSetSoundSystem(BinkOpenDirectSound,(u32)lpDS)
|
||||
|
||||
RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenWaveOut(u32 param); // don't call directly
|
||||
#define BinkSoundUseWaveOut() BinkSetSoundSystem(BinkOpenWaveOut,0)
|
||||
|
||||
#define INCLUDE_MMSYSTEM_H
|
||||
#include "windows.h"
|
||||
#include "windowsx.h"
|
||||
|
||||
#ifdef __RADNT__ // to combat WIN32_LEAN_AND_MEAN
|
||||
#include "mmsystem.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __RADMAC__
|
||||
|
||||
RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenMiles(u32 param); // don't call directly
|
||||
#define BinkSoundUseMiles(hdigdriver) BinkSetSoundSystem(BinkOpenMiles,(u32)hdigdriver)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenSoundManager(u32 param); // don't call directly
|
||||
#define BinkSoundUseSoundManager() BinkSetSoundSystem(BinkOpenSoundManager,0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// The BinkBuffer API isn't currently implemented on DOS
|
||||
#if !defined(__RADDOS__)
|
||||
|
||||
//=========================================================================
|
||||
typedef struct BINKBUFFER * HBINKBUFFER;
|
||||
|
||||
#define BINKBUFFERSTRETCHXINT 0x80000000
|
||||
#define BINKBUFFERSTRETCHX 0x40000000
|
||||
#define BINKBUFFERSHRINKXINT 0x20000000
|
||||
#define BINKBUFFERSHRINKX 0x10000000
|
||||
#define BINKBUFFERSTRETCHYINT 0x08000000
|
||||
#define BINKBUFFERSTRETCHY 0x04000000
|
||||
#define BINKBUFFERSHRINKYINT 0x02000000
|
||||
#define BINKBUFFERSHRINKY 0x01000000
|
||||
#define BINKBUFFERSCALES 0xff000000
|
||||
#define BINKBUFFERRESOLUTION 0x00800000
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
#include <windows.h>
|
||||
#include <palettes.h>
|
||||
#include <qdoffscreen.h>
|
||||
|
||||
typedef struct BINKBUFFER {
|
||||
u32 Width;
|
||||
u32 Height;
|
||||
u32 WindowWidth;
|
||||
u32 WindowHeight;
|
||||
u32 SurfaceType;
|
||||
void* Buffer;
|
||||
s32 BufferPitch;
|
||||
u32 ScreenWidth;
|
||||
u32 ScreenHeight;
|
||||
u32 ScreenDepth;
|
||||
u32 ScaleFlags;
|
||||
|
||||
s32 destx,desty;
|
||||
s32 wndx,wndy;
|
||||
u32 wnd;
|
||||
|
||||
s32 noclipping;
|
||||
u32 type;
|
||||
s32 issoftcur;
|
||||
u32 cursorcount;
|
||||
|
||||
} BINKBUFFER;
|
||||
|
||||
|
||||
#define BINKBUFFERAUTO 0
|
||||
#define BINKBUFFERDIRECT 1
|
||||
#define BINKBUFFERGWORLD 2
|
||||
#define BINKBUFFERTYPEMASK 31
|
||||
|
||||
RADEXPFUNC HBINKBUFFER RADEXPLINK BinkBufferOpen( WindowPtr wnd, u32 width, u32 height, u32 bufferflags);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkGDSurfaceType( GDHandle gd );
|
||||
RADEXPFUNC s32 RADEXPLINK BinkIsSoftwareCursor(GDHandle gd);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkCheckCursor(WindowPtr wp,s32 x,s32 y,s32 w,s32 h);
|
||||
|
||||
#else
|
||||
|
||||
typedef struct BINKBUFFER {
|
||||
u32 Width;
|
||||
u32 Height;
|
||||
u32 WindowWidth;
|
||||
u32 WindowHeight;
|
||||
u32 SurfaceType;
|
||||
void* Buffer;
|
||||
s32 BufferPitch;
|
||||
s32 ClientOffsetX;
|
||||
s32 ClientOffsetY;
|
||||
u32 ScreenWidth;
|
||||
u32 ScreenHeight;
|
||||
u32 ScreenDepth;
|
||||
u32 ExtraWindowWidth;
|
||||
u32 ExtraWindowHeight;
|
||||
u32 ScaleFlags;
|
||||
u32 StretchWidth;
|
||||
u32 StretchHeight;
|
||||
|
||||
s32 surface;
|
||||
void* ddsurface;
|
||||
void* ddclipper;
|
||||
s32 destx,desty;
|
||||
s32 wndx,wndy;
|
||||
u32 wnd;
|
||||
s32 ddoverlay;
|
||||
s32 ddoffscreen;
|
||||
s32 lastovershow;
|
||||
|
||||
s32 issoftcur;
|
||||
u32 cursorcount;
|
||||
void* buffertop;
|
||||
u32 type;
|
||||
s32 noclipping;
|
||||
|
||||
s32 loadeddd;
|
||||
s32 loadedwin;
|
||||
|
||||
void* dibh;
|
||||
void* dibbuffer;
|
||||
s32 dibpitch;
|
||||
void* dibinfo;
|
||||
u32 dibdc;
|
||||
u32 diboldbitmap;
|
||||
|
||||
} BINKBUFFER;
|
||||
|
||||
|
||||
#define BINKBUFFERAUTO 0
|
||||
#define BINKBUFFERPRIMARY 1
|
||||
#define BINKBUFFERDIBSECTION 2
|
||||
#define BINKBUFFERYV12OVERLAY 3
|
||||
#define BINKBUFFERYUY2OVERLAY 4
|
||||
#define BINKBUFFERUYVYOVERLAY 5
|
||||
#define BINKBUFFERYV12OFFSCREEN 6
|
||||
#define BINKBUFFERYUY2OFFSCREEN 7
|
||||
#define BINKBUFFERUYVYOFFSCREEN 8
|
||||
#define BINKBUFFERRGBOFFSCREENVIDEO 9
|
||||
#define BINKBUFFERRGBOFFSCREENSYSTEM 10
|
||||
#define BINKBUFFERLAST 10
|
||||
#define BINKBUFFERTYPEMASK 31
|
||||
|
||||
RADEXPFUNC HBINKBUFFER RADEXPLINK BinkBufferOpen( HWND wnd, u32 width, u32 height, u32 bufferflags);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferSetHWND( HBINKBUFFER buf, HWND newwnd);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkDDSurfaceType(void PTR4* lpDDS);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkIsSoftwareCursor(void PTR4* lpDDSP,HCURSOR cur);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkCheckCursor(HWND wnd,s32 x,s32 y,s32 w,s32 h);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferSetDirectDraw(void PTR4* lpDirectDraw, void PTR4* lpPrimary);
|
||||
|
||||
#endif
|
||||
|
||||
RADEXPFUNC void RADEXPLINK BinkBufferClose( HBINKBUFFER buf);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferLock( HBINKBUFFER buf);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferUnlock( HBINKBUFFER buf);
|
||||
RADEXPFUNC void RADEXPLINK BinkBufferSetResolution( s32 w, s32 h, s32 bits);
|
||||
RADEXPFUNC void RADEXPLINK BinkBufferCheckWinPos( HBINKBUFFER buf, s32 PTR4* NewWindowX, s32 PTR4* NewWindowY);
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferSetOffset( HBINKBUFFER buf, s32 destx, s32 desty);
|
||||
RADEXPFUNC void RADEXPLINK BinkBufferBlit( HBINKBUFFER buf, BINKRECT PTR4* rects, u32 numrects );
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferSetScale( HBINKBUFFER buf, u32 w, u32 h);
|
||||
RADEXPFUNC char PTR4* RADEXPLINK BinkBufferGetDescription( HBINKBUFFER buf);
|
||||
RADEXPFUNC char PTR4* RADEXPLINK BinkBufferGetError();
|
||||
RADEXPFUNC s32 RADEXPLINK BinkBufferClear(HBINKBUFFER buf, u32 RGB);
|
||||
|
||||
RADEXPFUNC void RADEXPLINK BinkRestoreCursor(s32 checkcount);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
#pragma export off
|
||||
|
||||
#endif
|
||||
|
||||
RADDEFEND
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
BIN
code/win32/binkw32.lib
Normal file
BIN
code/win32/binkw32.lib
Normal file
Binary file not shown.
BIN
code/win32/clear.bmp
Normal file
BIN
code/win32/clear.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
172
code/win32/dbg_console_xbox.cpp
Normal file
172
code/win32/dbg_console_xbox.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: dbg_console_xbox.cpp
|
||||
//
|
||||
// Desc: Listens for string commands sent from a debug console on a
|
||||
// remote dev machine, and forwards them to the Q3 engine.
|
||||
//
|
||||
// Commands are sent from the remote debug console through the debug
|
||||
// channel to the debug monitor on the Xbox machine. The Xbox machine
|
||||
// receives the commands on a separate thread through a
|
||||
// registered command processor callback function. The callback
|
||||
// function will store commands in a buffer, and the app should
|
||||
// poll this buffer once per frame and then decipher and handle
|
||||
// the commands.
|
||||
//
|
||||
// Hist: 02.05.01 - Initial creation for March XDK release
|
||||
// 08.21.02 - Revision and code cleanup
|
||||
// 04.10.02 - Buthcered by BTO for use in JK3:JA
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <xtl.h>
|
||||
#include <xbdm.h>
|
||||
#include <stdio.h>
|
||||
#include "dbg_console_xbox.h"
|
||||
#include "../client/client.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
|
||||
// Command prefix for things sent across the dubg channel
|
||||
static const CHAR g_strDebugConsoleCommandPrefix[] = "XCMD";
|
||||
|
||||
|
||||
// Global buffer to receive remote commands from the debug console. Note that
|
||||
// since this data is accessed by the app's main thread, and the debug monitor
|
||||
// thread, we need to protect access with a critical section
|
||||
static CHAR g_strRemoteBuf[MAXRCMDLENGTH];
|
||||
|
||||
|
||||
// The critical section used to protect data that is shared between threads
|
||||
static CRITICAL_SECTION g_CriticalSection;
|
||||
|
||||
|
||||
// Temporary replacement for CRT string funcs, since
|
||||
// we can't call CRT functions on the debug monitor
|
||||
// thread right now.
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: dbgtolower()
|
||||
// Desc: Returns lowercase of char
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CHAR dbgtolower( CHAR ch )
|
||||
{
|
||||
if( ch >= 'A' && ch <= 'Z' )
|
||||
return ch - ( 'A' - 'a' );
|
||||
else
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: dbgstrnicmp()
|
||||
// Desc: Critical section safe string compare.
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL dbgstrnicmp( const CHAR* str1, const CHAR* str2, int n )
|
||||
{
|
||||
while( ( dbgtolower( *str1 ) == dbgtolower( *str2 ) ) && *str1 && n > 0 )
|
||||
{
|
||||
--n;
|
||||
++str1;
|
||||
++str2;
|
||||
}
|
||||
|
||||
return( n == 0 || dbgtolower( *str1 ) == dbgtolower( *str2 ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: dbgstrcpy()
|
||||
// Desc: Critical section safe string copy
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID dbgstrcpy( CHAR* strDest, const CHAR* strSrc )
|
||||
{
|
||||
while( ( *strDest++ = *strSrc++ ) != 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DebugConsoleCmdProcessor()
|
||||
// Desc: Command notification proc that is called by the Xbox debug monitor to
|
||||
// have us process a command. What we'll actually attempt to do is tell
|
||||
// it to make calls to us on a separate thread, so that we can just block
|
||||
// until we're able to process a command.
|
||||
//
|
||||
// Note: Do NOT include newlines in the response string! To do so will confuse
|
||||
// the internal WinSock networking code used by the debug monitor API.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT __stdcall DebugConsoleCmdProcessor( const CHAR* strCommand,
|
||||
CHAR* strResponse, DWORD dwResponseLen,
|
||||
PDM_CMDCONT pdmcc )
|
||||
{
|
||||
// Skip over the command prefix and the exclamation mark
|
||||
strCommand += strlen(g_strDebugConsoleCommandPrefix) + 1;
|
||||
|
||||
// Check if this is the initial connect signal
|
||||
if( dbgstrnicmp( strCommand, "__connect__", 11 ) )
|
||||
{
|
||||
// If so, respond that we're connected
|
||||
lstrcpynA( strResponse, "Connected.", dwResponseLen );
|
||||
return XBDM_NOERR;
|
||||
}
|
||||
|
||||
// g_strRemoteBuf needs to be protected by the critical section
|
||||
EnterCriticalSection( &g_CriticalSection );
|
||||
if( g_strRemoteBuf[0] )
|
||||
{
|
||||
// This means the application has probably stopped polling for debug commands
|
||||
dbgstrcpy( strResponse, "Cannot execute - previous command still pending" );
|
||||
}
|
||||
else
|
||||
{
|
||||
dbgstrcpy( g_strRemoteBuf, strCommand );
|
||||
}
|
||||
LeaveCriticalSection( &g_CriticalSection );
|
||||
|
||||
return XBDM_NOERR;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: DebugConsoleHandleCommands()
|
||||
// Desc: Poll routine called periodically (typically every frame) by the Xbox
|
||||
// app to see if there is a command waiting to be executed, and if so,
|
||||
// execute it.
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL DebugConsoleHandleCommands()
|
||||
{
|
||||
static BOOL bInitialized = FALSE;
|
||||
CHAR strLocalBuf[MAXRCMDLENGTH+1]; // local copy of command
|
||||
|
||||
// Initialize ourselves when we're first called.
|
||||
if( !bInitialized )
|
||||
{
|
||||
// Register our command handler with the debug monitor
|
||||
HRESULT hr = DmRegisterCommandProcessor( g_strDebugConsoleCommandPrefix,
|
||||
DebugConsoleCmdProcessor );
|
||||
if( FAILED(hr) )
|
||||
return FALSE;
|
||||
|
||||
// We'll also need a critical section to protect access to g_strRemoteBuf
|
||||
InitializeCriticalSection( &g_CriticalSection );
|
||||
|
||||
bInitialized = TRUE;
|
||||
}
|
||||
|
||||
// If there's nothing waiting, return.
|
||||
if( !g_strRemoteBuf[0] )
|
||||
return FALSE;
|
||||
|
||||
// Grab a local copy of the command received in the remote buffer
|
||||
EnterCriticalSection( &g_CriticalSection );
|
||||
|
||||
lstrcpyA( strLocalBuf, g_strRemoteBuf );
|
||||
g_strRemoteBuf[0] = 0;
|
||||
|
||||
LeaveCriticalSection( &g_CriticalSection );
|
||||
|
||||
Cbuf_ExecuteText( EXEC_APPEND, va("%s\n", strLocalBuf) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
34
code/win32/dbg_console_xbox.h
Normal file
34
code/win32/dbg_console_xbox.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: dbg_console_xbox.h
|
||||
//
|
||||
// Desc: Header file for communicating with a remote debug console. Please read
|
||||
// the comments in the dbg_console_xbox.cpp file for more info
|
||||
// on the API.
|
||||
//
|
||||
// This header defines the following arrays:
|
||||
//
|
||||
// g_RemoteCommands - This is the list of commands your application provides.
|
||||
// Note that "help" and "set" are provided automatically
|
||||
// This is implemented in DebugCmd.cpp
|
||||
//
|
||||
// g_RemoteVariables - This is a list of variables that your application
|
||||
// exposes. They can be examined and modified by the
|
||||
// remote debug console with the "set" command.
|
||||
// This is implemented in DebugChannel.cpp
|
||||
//
|
||||
// Hist: 02.05.01 - Initial creation for March XDK release
|
||||
// 08.21.02 - Revision and code cleanup
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef DEBUGCMD_H
|
||||
#define DEBUGCMD_H
|
||||
|
||||
#define MAXRCMDLENGTH 256 // Size of the remote cmd buffer
|
||||
|
||||
// Handle any remote commands that have been sent - this should be called
|
||||
// periodically by the application
|
||||
BOOL DebugConsoleHandleCommands();
|
||||
|
||||
#endif // DEBUGCMD_H
|
||||
|
||||
104
code/win32/game.rc
Normal file
104
code/win32/game.rc
Normal file
@@ -0,0 +1,104 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "AutoVersion.h"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_MAJOR_RELEASE,VERSION_MINOR_RELEASE,VERSION_EXTERNAL_BUILD,VERSION_INTERNAL_BUILD
|
||||
PRODUCTVERSION VERSION_MAJOR_RELEASE,VERSION_MINOR_RELEASE,VERSION_EXTERNAL_BUILD,VERSION_INTERNAL_BUILD
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Raven Software"
|
||||
VALUE "CompanyName", "Activision Inc"
|
||||
VALUE "FileDescription", "Jedi Academy Game DLL"
|
||||
VALUE "FileVersion", VERSION_STRING
|
||||
VALUE "InternalName", "ja game.dll"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2003"
|
||||
VALUE "OriginalFilename", "jagamex86.dll"
|
||||
VALUE "ProductName", "Jedi Knight®: Jedi Academy"
|
||||
VALUE "ProductVersion", VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
30
code/win32/glw_win.h
Normal file
30
code/win32/glw_win.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _WIN32
|
||||
# error You should not be including this file on this platform
|
||||
#endif
|
||||
|
||||
#ifndef __GLW_WIN_H__
|
||||
#define __GLW_WIN_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WNDPROC wndproc;
|
||||
|
||||
HDC hDC; // handle to device context
|
||||
HGLRC hGLRC; // handle to GL rendering context
|
||||
|
||||
HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
||||
|
||||
qboolean allowdisplaydepthchange;
|
||||
qboolean pixelFormatSet;
|
||||
|
||||
int desktopBitsPixel;
|
||||
int desktopWidth, desktopHeight;
|
||||
|
||||
qboolean cdsFullscreen;
|
||||
|
||||
FILE *log_fp;
|
||||
} glwstate_t;
|
||||
|
||||
extern glwstate_t glw_state;
|
||||
|
||||
#endif
|
||||
184
code/win32/glw_win_dx8.h
Normal file
184
code/win32/glw_win_dx8.h
Normal file
@@ -0,0 +1,184 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#ifndef __GLW_WIN_H__
|
||||
#define __GLW_WIN_H__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <d3d9.h>
|
||||
#ifdef _WIN32
|
||||
#include <d3dx9.h>
|
||||
#endif
|
||||
|
||||
#include "../renderer/qgl_console.h"
|
||||
#include "../game/q_shared.h"
|
||||
#include "../qcommon/qfiles.h"
|
||||
|
||||
#define GLW_MAX_TEXTURE_STAGES 2
|
||||
#define GLW_MAX_STRIPS 2048
|
||||
|
||||
|
||||
struct glwstate_t
|
||||
{
|
||||
// Interface to DX
|
||||
IDirect3DDevice9* device;
|
||||
|
||||
// Matrix stuff
|
||||
enum MatrixMode
|
||||
{
|
||||
MatrixMode_Model = 0,
|
||||
MatrixMode_Projection = 1,
|
||||
MatrixMode_Texture0 = 2,
|
||||
MatrixMode_Texture1 = 3,
|
||||
MatrixMode_Texture2 = 4,
|
||||
MatrixMode_Texture3 = 5,
|
||||
|
||||
Num_MatrixModes
|
||||
};
|
||||
|
||||
ID3DXMatrixStack* matrixStack[Num_MatrixModes];
|
||||
MatrixMode matrixMode;
|
||||
|
||||
// Current primitive mode (triangles/quads/strips)
|
||||
D3DPRIMITIVETYPE primitiveMode;
|
||||
|
||||
// Are we in a glBegin/glEnd block? (Used for sanity checks.)
|
||||
bool inDrawBlock;
|
||||
|
||||
// Texturing
|
||||
bool textureStageDirty[GLW_MAX_TEXTURE_STAGES];
|
||||
bool textureStageEnable[GLW_MAX_TEXTURE_STAGES];
|
||||
GLuint currentTexture[GLW_MAX_TEXTURE_STAGES];
|
||||
D3DTEXTUREOP textureEnv[GLW_MAX_TEXTURE_STAGES];
|
||||
|
||||
struct TextureInfo
|
||||
{
|
||||
IDirect3DTexture9* mipmap;
|
||||
D3DTEXTUREFILTERTYPE minFilter, mipFilter, magFilter;
|
||||
D3DTEXTUREADDRESS wrapU, wrapV;
|
||||
float anisotropy;
|
||||
|
||||
// I only need this for ONE texture, but it's easier than adding more hacks:
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef std::map<GLuint, TextureInfo> texturexlat_t;
|
||||
texturexlat_t textureXlat;
|
||||
|
||||
GLuint textureBindNum;
|
||||
|
||||
GLuint serverTU, clientTU;
|
||||
|
||||
// Pointers to various draw buffers
|
||||
const void* vertexPointer;
|
||||
const void* normalPointer;
|
||||
const void* texCoordPointer[GLW_MAX_TEXTURE_STAGES];
|
||||
const void* colorPointer;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
// Temporary storage used when rendering quads
|
||||
const void* vertexPointerBack;
|
||||
const void* normalPointerBack;
|
||||
const void* texCoordPointerBack[GLW_MAX_TEXTURE_STAGES];
|
||||
const void* colorPointerBack;
|
||||
#endif
|
||||
|
||||
// State of draw buffers
|
||||
bool colorArrayState;
|
||||
bool texCoordArrayState[GLW_MAX_TEXTURE_STAGES];
|
||||
bool vertexArrayState;
|
||||
bool normalArrayState;
|
||||
|
||||
// Stride of various draw buffers
|
||||
int vertexStride;
|
||||
int texCoordStride[GLW_MAX_TEXTURE_STAGES];
|
||||
int colorStride;
|
||||
int normalStride;
|
||||
|
||||
// Current number of verts in this packet
|
||||
int numVertices;
|
||||
|
||||
// Max verts allowed in this packet
|
||||
int maxVertices;
|
||||
|
||||
// Total verts to draw (may take multiple packets)
|
||||
int totalVertices;
|
||||
|
||||
// Current number of indices in this packet
|
||||
int numIndices;
|
||||
|
||||
// Max indices allowed in this packet
|
||||
int maxIndices;
|
||||
|
||||
// Total indices to draw
|
||||
int totalIndices;
|
||||
|
||||
// Culling
|
||||
bool cullEnable;
|
||||
D3DCULL cullMode;
|
||||
|
||||
// Viewport
|
||||
D3DVIEWPORT9 viewport;
|
||||
|
||||
// Clearing info
|
||||
D3DCOLOR clearColor;
|
||||
float clearDepth;
|
||||
int clearStencil;
|
||||
|
||||
// Widescreen mode
|
||||
bool isWidescreen;
|
||||
|
||||
// Global color
|
||||
D3DCOLOR currentColor;
|
||||
|
||||
// Scissoring
|
||||
bool scissorEnable;
|
||||
D3DRECT scissorBox;
|
||||
|
||||
// Directional Light
|
||||
D3DLIGHT9 dirLight;
|
||||
D3DMATERIAL9 mtrl;
|
||||
|
||||
// Description of current shader
|
||||
DWORD shaderMask;
|
||||
|
||||
// Should we reset matrices on next draw?
|
||||
bool matricesDirty[Num_MatrixModes];
|
||||
|
||||
// Render commands go here
|
||||
DWORD* drawArray;
|
||||
DWORD drawStride;
|
||||
|
||||
// This is designed to be an optimization for triangle strips
|
||||
// as well as making life easier for the flare effect
|
||||
GLushort strip_dest[SHADER_MAX_INDEXES];
|
||||
GLuint strip_lengths[GLW_MAX_STRIPS];
|
||||
GLsizei num_strip_lengths;
|
||||
|
||||
#ifdef _XBOX
|
||||
// class FlareEffect* flareEffect;
|
||||
class LightEffects* lightEffects;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern glwstate_t *glw_state;
|
||||
|
||||
void renderObject_HACK();
|
||||
void renderObject_Light( int numIndexes, const unsigned short *indexes );
|
||||
void renderObject_Shadow( int primType, int numIndexes, const unsigned short *indexes );
|
||||
void renderObject_Env();
|
||||
void renderObject_Bump();
|
||||
bool CreateVertexShader( const CHAR* strFilename, const DWORD* pdwVertexDecl, DWORD* pdwVertexShader );
|
||||
bool CreatePixelShader( const CHAR* strFilename, DWORD* pdwPixelShader );
|
||||
|
||||
#endif
|
||||
962
code/win32/rad.h
Normal file
962
code/win32/rad.h
Normal file
@@ -0,0 +1,962 @@
|
||||
#ifndef __RAD__
|
||||
#define __RAD__
|
||||
|
||||
#define RADCOPYRIGHT "Copyright (C) 1994-2000, RAD Game Tools, Inc."
|
||||
|
||||
#ifndef __RADRES__
|
||||
|
||||
// __RAD16__ means 16 bit code (Win16)
|
||||
// __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac)
|
||||
|
||||
// __RADDOS__ means DOS code (16 or 32 bit)
|
||||
// __RADWIN__ means Windows code (Win16, Win386, Win32s)
|
||||
// __RADWINEXT__ means Windows 386 extender (Win386)
|
||||
// __RADNT__ means Win32s code
|
||||
// __RADMAC__ means Macintosh
|
||||
|
||||
// __RADX86__ means Intel x86
|
||||
// __RADMMX__ means Intel x86 MMX instructions are allowed
|
||||
// __RAD68K__ means 68K
|
||||
// __RADPPC__ means PowerPC
|
||||
|
||||
// __RADLITTLEENDIAN__ means processor is little-endian (x86)
|
||||
// __RADBIGENDIAN__ means processor is big-endian (680x0, PPC)
|
||||
|
||||
// __RADALLOWINLINES__ means this compiler allows inline function declarations
|
||||
// use RADINLINE for the appropriate keyword
|
||||
|
||||
|
||||
#if (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc)
|
||||
|
||||
#define __RADMAC__
|
||||
#if defined(powerc) || defined(__powerc)
|
||||
#define __RADPPC__
|
||||
#else
|
||||
#define __RAD68K__
|
||||
#endif
|
||||
|
||||
#define __RAD32__
|
||||
|
||||
#define __RADBIGENDIAN__
|
||||
|
||||
#if defined(__MWERKS__)
|
||||
#if (defined(__cplusplus) || ! __option(only_std_keywords))
|
||||
#define __RADALLOWINLINES__
|
||||
#define RADINLINE inline
|
||||
#endif
|
||||
#elif defined(__MRC__)
|
||||
#if defined(__cplusplus)
|
||||
#define __RADALLOWINLINES__
|
||||
#define RADINLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define __RADX86__
|
||||
#define __RADMMX__
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define _WIN32
|
||||
#endif
|
||||
|
||||
#ifdef __DOS__
|
||||
#define __RADDOS__
|
||||
#endif
|
||||
|
||||
#ifdef __386__
|
||||
#define __RAD32__
|
||||
#endif
|
||||
|
||||
#ifdef _Windows //For Borland
|
||||
#ifdef __WIN32__
|
||||
#define WIN32
|
||||
#else
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS //For MS
|
||||
#ifndef _WIN32
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define __RADWIN__
|
||||
#define __RADNT__
|
||||
#define __RAD32__
|
||||
#else
|
||||
#ifdef __NT__
|
||||
#define __RADWIN__
|
||||
#define __RADNT__
|
||||
#define __RAD32__
|
||||
#else
|
||||
#ifdef __WINDOWS_386__
|
||||
#define __RADWIN__
|
||||
#define __RADWINEXT__
|
||||
#define __RAD32__
|
||||
#else
|
||||
#ifdef __WINDOWS__
|
||||
#define __RADWIN__
|
||||
#define __RAD16__
|
||||
#else
|
||||
#ifdef WIN32
|
||||
#define __RADWIN__
|
||||
#define __RADNT__
|
||||
#define __RAD32__
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define __RADLITTLEENDIAN__
|
||||
|
||||
// TODO - make sure these are set correctly for non-Mac versions
|
||||
#define __RADALLOWINLINES__
|
||||
#define RADINLINE __inline
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __RADALLOWINLINES__
|
||||
#define RADINLINE
|
||||
#endif
|
||||
|
||||
#if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__))
|
||||
#error RAD.H did not detect your platform. Define __DOS__, __WINDOWS__, WIN32, macintosh, or powerc.
|
||||
#endif
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
// this define is for CodeWarrior 11's stupid new libs (even though
|
||||
// we don't use longlong's).
|
||||
|
||||
#define __MSL_LONGLONG_SUPPORT__
|
||||
|
||||
#define RADLINK
|
||||
#define RADEXPLINK
|
||||
|
||||
#ifdef __CFM68K__
|
||||
#ifdef __RADINDLL__
|
||||
#define RADEXPFUNC RADDEFFUNC __declspec(export)
|
||||
#else
|
||||
#define RADEXPFUNC RADDEFFUNC __declspec(import)
|
||||
#endif
|
||||
#else
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#endif
|
||||
#define RADASMLINK
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __RADNT__
|
||||
#ifndef _WIN32
|
||||
#define _WIN32
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __RADWIN__
|
||||
#ifdef __RAD32__
|
||||
#ifdef __RADNT__
|
||||
|
||||
#define RADLINK __stdcall
|
||||
#define RADEXPLINK __stdcall
|
||||
|
||||
#ifdef __RADINEXE__
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#else
|
||||
#ifndef __RADINDLL__
|
||||
#define RADEXPFUNC RADDEFFUNC __declspec(dllimport)
|
||||
#ifdef __BORLANDC__
|
||||
#if __BORLANDC__<=0x460
|
||||
#undef RADEXPFUNC
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define RADEXPFUNC RADDEFFUNC __declspec(dllexport)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define RADLINK __pascal
|
||||
#define RADEXPLINK __far __pascal
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#endif
|
||||
#else
|
||||
#define RADLINK __pascal
|
||||
#define RADEXPLINK __far __pascal __export
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#endif
|
||||
#else
|
||||
#define RADLINK __pascal
|
||||
#define RADEXPLINK __pascal
|
||||
#define RADEXPFUNC RADDEFFUNC
|
||||
#endif
|
||||
|
||||
#define RADASMLINK __cdecl
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __RADWIN__
|
||||
#ifndef _WINDOWS
|
||||
#define _WINDOWS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define RADDEFFUNC extern "C"
|
||||
#define RADDEFSTART extern "C" {
|
||||
#define RADDEFEND }
|
||||
#else
|
||||
#define RADDEFFUNC
|
||||
#define RADDEFSTART
|
||||
#define RADDEFEND
|
||||
#endif
|
||||
|
||||
|
||||
RADDEFSTART
|
||||
|
||||
#define s8 signed char
|
||||
#define u8 unsigned char
|
||||
#define u32 unsigned long
|
||||
#define s32 signed long
|
||||
#define f32 float
|
||||
#define f64 double
|
||||
|
||||
#if defined(__MWERKS__) || defined(__MRC__)
|
||||
#define u64 unsigned long long
|
||||
#define s64 signed long long
|
||||
#else
|
||||
#define u64 unsigned __int64
|
||||
#define s64 signed __int64
|
||||
#endif
|
||||
|
||||
/* 32 bit implementations */
|
||||
|
||||
#ifdef __RAD32__
|
||||
#define PTR4
|
||||
|
||||
#define u16 unsigned short
|
||||
#define s16 signed short
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
#include <string.h>
|
||||
#include <MacTypes.h>
|
||||
#include <Memory.h>
|
||||
#include <OSUtils.h>
|
||||
#ifdef __MRC__
|
||||
#include "intrinsics.h"
|
||||
#endif
|
||||
|
||||
void radconv32a(void* p, u32 n);
|
||||
|
||||
u32 radloadu32(u32 a);
|
||||
|
||||
u32 radloadu32ptr(u32* p);
|
||||
|
||||
#define radstrcpy strcpy
|
||||
|
||||
#define radstrcat strcat
|
||||
|
||||
#define radmemcpy(dest,source,size) BlockMoveData((Ptr)(source),(Ptr)(dest),size)
|
||||
|
||||
#define radmemcpydb(dest,source,size) BlockMoveData((Ptr)(source),(Ptr)(dest),size)
|
||||
|
||||
#define radmemcmp memcmp
|
||||
|
||||
#define radmemset memset
|
||||
|
||||
#define radstrlen strlen
|
||||
|
||||
#define radstrchr strchr
|
||||
|
||||
#define radtoupper toupper
|
||||
|
||||
#define radstru32(s) ((u32)atol(s))
|
||||
|
||||
//s8 radstricmp(const void* s1,const void* s2);
|
||||
|
||||
#define radstrcmp strcmp
|
||||
|
||||
//char* radstrupr(void* s1);
|
||||
|
||||
//char* radstrlwr(void* s1);
|
||||
|
||||
u32 radsqr(u32 a);
|
||||
|
||||
u32 mult64anddiv(u32 m1,u32 m2,u32 d);
|
||||
|
||||
s32 radabs(s32 ab);
|
||||
|
||||
#define radabs32 radabs
|
||||
|
||||
//char* radstpcpy(void* dest,const void* source);
|
||||
|
||||
//char* radstpcpyrs(void* dest,const void* source);
|
||||
|
||||
void radmemset16(void* dest,u16 value,u32 size);
|
||||
|
||||
//void radmemset32(void* dest,u32 value,u32 size);
|
||||
|
||||
#define BreakPoint() DebugStr("\pBreakPoint() was called")
|
||||
|
||||
//u8 radinp(u16 p);
|
||||
|
||||
//void radoutp(u16 p,u8 v);
|
||||
|
||||
//u32 RADsqrt(u32 sq);
|
||||
|
||||
u32 RADCycleTimerAvail(void);
|
||||
|
||||
void RADCycleTimerStartAddr(u32* addr);
|
||||
|
||||
u32 RADCycleTimerDeltaAddr(u32* addr);
|
||||
|
||||
void RADCycleTimerStartAddr64(u64* addr);
|
||||
|
||||
void RADCycleTimerDeltaAddr64(u64* addr);
|
||||
|
||||
#define RADCycleTimerStart(var) RADCycleTimerStartAddr(&var)
|
||||
|
||||
#define RADCycleTimerDelta(var) RADCycleTimerDeltaAddr(&var)
|
||||
|
||||
#define RADCycleTimerStart64(var) RADCycleTimerStartAddr64(&var)
|
||||
|
||||
#define RADCycleTimerDelta64(var) RADCycleTimerDeltaAddr64(&var)
|
||||
|
||||
|
||||
#ifdef __RAD68K__
|
||||
#pragma parameter radconv32a(__A0,__D0)
|
||||
void radconv32a(void* p,u32 n) ={0x4A80,0x600C,0x2210,0xE059,0x4841,0xE059,0x20C1,0x5380,0x6EF2};
|
||||
// tst.l d0 bra.s @loope @loop: move.l (a0),d1 ror.w #8,d1 swap d1 ror.w #8,d1 move.l d1,(a0)+ sub.l #1,d0 bgt.s @loop @loope:
|
||||
#endif
|
||||
|
||||
#ifdef __RADALLOWINLINES__
|
||||
#if defined __RADPPC__ && defined(__MWERKS__) && (__MWERKS__ >= 0x2301) && 0
|
||||
u32 RADINLINE radloadu32(register u32 x) {
|
||||
register u32 t1, t2;
|
||||
asm { // x = aa bb cc dd
|
||||
rlwinm t1,x,24,0,23 // t1 = dd aa bb 00
|
||||
rlwinm t2,x,8,24,31 // t2 = 00 00 00 aa
|
||||
rlwimi t1,x,8, 8,15 // t1 = dd cc bb 00
|
||||
or x,t1,t2 // x = dd cc bb aa
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#else
|
||||
u32 RADINLINE radloadu32(register u32 x) {
|
||||
return (((x << 24) & 0xFF000000) |
|
||||
((x << 8) & 0x00FF0000) |
|
||||
((x >> 8) & 0x0000FF00) |
|
||||
((x >> 24) & 0x000000FF));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__RADPPC__) && (defined(__MWERKS__) || defined(__MRC__))
|
||||
#define radloadu32ptr(p) (u32) __lwbrx((p),0)
|
||||
#else
|
||||
#define radloadu32ptr(p) radloadu32(*(u32*)(p));
|
||||
#endif
|
||||
|
||||
#ifdef __RADALLOWINLINES__
|
||||
u32 RADINLINE radsqr(u32 a) { return(a*a); }
|
||||
#endif
|
||||
|
||||
#ifdef __RAD68K__
|
||||
#pragma parameter __D0 mult64anddiv(__D0,__D1,__D2)
|
||||
u32 mult64anddiv(u32 m1,u32 m2,u32 d) ={0x4C01,0x0C01,0x4C42,0x0C01};
|
||||
// muls.l d1,d1:d0 divs.l d2,d1:d0
|
||||
#endif
|
||||
|
||||
#if defined(__RADPPC__) && (defined(__MWERKS__) || defined(__MRC__))
|
||||
#define radabs(ab) __abs((s32)(ab))
|
||||
#elif defined(__RADALLOWINLINES__)
|
||||
s32 RADINLINE radabs(s32 ab) { return (ab < 0) ? -ab : ab; }
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define radconv32a(p,n) ((void)0)
|
||||
|
||||
#define radloadu32(a) ((u32)(a))
|
||||
|
||||
#define radloadu32ptr(p) *((u32*)(p))
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
|
||||
u32 radsqr(s32 a);
|
||||
#pragma aux radsqr = "mul eax" parm [eax] modify [EDX eax];
|
||||
|
||||
u32 mult64anddiv(u32 m1,u32 m2,u32 d);
|
||||
#pragma aux mult64anddiv = "mul ecx" "div ebx" parm [eax] [ecx] [ebx] modify [EDX eax];
|
||||
|
||||
s32 radabs(s32 ab);
|
||||
#pragma aux radabs = "test eax,eax" "jge skip" "neg eax" "skip:" parm [eax];
|
||||
|
||||
#define radabs32 radabs
|
||||
|
||||
u32 DOSOut(const char* str);
|
||||
#pragma aux DOSOut = "cld" "mov ecx,0xffffffff" "xor eax,eax" "mov edx,edi" "repne scasb" "not ecx" "dec ecx" "mov ebx,1" "mov ah,0x40" "int 0x21" parm [EDI] modify [EAX EBX ECX EDX EDI] value [ecx];
|
||||
|
||||
void DOSOutNum(const char* str,u32 len);
|
||||
#pragma aux DOSOutNum = "mov ah,0x40" "mov ebx,1" "int 0x21" parm [edx] [ecx] modify [eax ebx];
|
||||
|
||||
u32 ErrOut(const char* str);
|
||||
#pragma aux ErrOut = "cld" "mov ecx,0xffffffff" "xor eax,eax" "mov edx,edi" "repne scasb" "not ecx" "dec ecx" "xor ebx,ebx" "mov ah,0x40" "int 0x21" parm [EDI] modify [EAX EBX ECX EDX EDI] value [ecx];
|
||||
|
||||
void ErrOutNum(const char* str,u32 len);
|
||||
#pragma aux ErrOutNum = "mov ah,0x40" "xor ebx,ebx" "int 0x21" parm [edx] [ecx] modify [eax ebx];
|
||||
|
||||
void radmemset16(void* dest,u16 value,u32 size);
|
||||
#pragma aux radmemset16 = "cld" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,1" "rep stosd" "mov cl,bl" "and cl,1" "rep stosw" parm [EDI] [EAX] [ECX] modify [EAX EDX EBX ECX EDI];
|
||||
|
||||
void radmemset(void* dest,u8 value,u32 size);
|
||||
#pragma aux radmemset = "cld" "mov ah,al" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,2" "and bl,3" "rep stosd" "mov cl,bl" "rep stosb" parm [EDI] [AL] [ECX] modify [EAX EDX EBX ECX EDI];
|
||||
|
||||
void radmemset32(void* dest,u32 value,u32 size);
|
||||
#pragma aux radmemset32 = "cld" "rep stosd" parm [EDI] [EAX] [ECX] modify [EAX EDX EBX ECX EDI];
|
||||
|
||||
void radmemcpy(void* dest,const void* source,u32 size);
|
||||
#pragma aux radmemcpy = "cld" "mov bl,cl" "shr ecx,2" "rep movsd" "mov cl,bl" "and cl,3" "rep movsb" parm [EDI] [ESI] [ECX] modify [EBX ECX EDI ESI];
|
||||
|
||||
void __far *radfmemcpy(void __far* dest,const void __far* source,u32 size);
|
||||
#pragma aux radfmemcpy = "cld" "push es" "push ds" "mov es,cx" "mov ds,dx" "mov ecx,eax" "shr ecx,2" "rep movsd" "mov cl,al" "and cl,3" "rep movsb" "pop ds" "pop es" parm [CX EDI] [DX ESI] [EAX] modify [ECX EDI ESI] value [CX EDI];
|
||||
|
||||
void radmemcpydb(void* dest,const void* source,u32 size); //Destination bigger
|
||||
#pragma aux radmemcpydb = "std" "mov bl,cl" "lea esi,[esi+ecx-4]" "lea edi,[edi+ecx-4]" "shr ecx,2" "rep movsd" "and bl,3" "jz dne" "add esi,3" "add edi,3" "mov cl,bl" "rep movsb" "dne:" "cld" parm [EDI] [ESI] [ECX] modify [EBX ECX EDI ESI];
|
||||
|
||||
char* radstrcpy(void* dest,const void* source);
|
||||
#pragma aux radstrcpy = "cld" "mov edx,edi" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" parm [EDI] [ESI] modify [EAX EDX EDI ESI] value [EDX];
|
||||
|
||||
char __far* radfstrcpy(void __far* dest,const void __far* source);
|
||||
#pragma aux radfstrcpy = "cld" "push es" "push ds" "mov es,cx" "mov ds,dx" "mov edx,edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" "pop es" parm [CX EDI] [DX ESI] modify [EAX EDX EDI ESI] value [CX EDX];
|
||||
|
||||
char* radstpcpy(void* dest,const void* source);
|
||||
#pragma aux radstpcpy = "cld" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" "dec edi" parm [EDI] [ESI] modify [EAX EDI ESI] value [EDI];
|
||||
|
||||
char* radstpcpyrs(void* dest,const void* source);
|
||||
#pragma aux radstpcpyrs = "cld" "lp:" "mov al,[esi]" "inc esi" "mov [edi],al" "inc edi" "cmp al,0" "jne lp" "dec esi" parm [EDI] [ESI] modify [EAX EDI ESI] value [ESI];
|
||||
|
||||
u32 radstrlen(const void* dest);
|
||||
#pragma aux radstrlen = "cld" "mov ecx,0xffffffff" "xor eax,eax" "repne scasb" "not ecx" "dec ecx" parm [EDI] modify [EAX ECX EDI] value [ECX];
|
||||
|
||||
char* radstrcat(void* dest,const void* source);
|
||||
#pragma aux radstrcat = "cld" "mov ecx,0xffffffff" "mov edx,edi" "xor eax,eax" "repne scasb" "dec edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" \
|
||||
parm [EDI] [ESI] modify [EAX ECX EDI ESI] value [EDX];
|
||||
|
||||
char* radstrchr(const void* dest,char chr);
|
||||
#pragma aux radstrchr = "cld" "lp:" "lodsb" "cmp al,dl" "je fnd" "cmp al,0" "jnz lp" "mov esi,1" "fnd:" "dec esi" parm [ESI] [DL] modify [EAX ESI] value [esi];
|
||||
|
||||
s8 radmemcmp(const void* s1,const void* s2,u32 len);
|
||||
#pragma aux radmemcmp = "cld" "rep cmpsb" "setne al" "jbe end" "neg al" "end:" parm [EDI] [ESI] [ECX] modify [ECX EDI ESI];
|
||||
|
||||
s8 radstrcmp(const void* s1,const void* s2);
|
||||
#pragma aux radstrcmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,ah" "jne set" "cmp al,0" "je set" "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \
|
||||
parm [EDI] [ESI] modify [EAX EDI ESI];
|
||||
|
||||
s8 radstricmp(const void* s1,const void* s2);
|
||||
#pragma aux radstricmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" "cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \
|
||||
"inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \
|
||||
parm [EDI] [ESI] modify [EAX EDI ESI];
|
||||
|
||||
s8 radstrnicmp(const void* s1,const void* s2,u32 len);
|
||||
#pragma aux radstrnicmp = "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" "cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \
|
||||
"dec ecx" "jz set" "inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" \
|
||||
parm [EDI] [ESI] [ECX] modify [EAX ECX EDI ESI];
|
||||
|
||||
char* radstrupr(void* s1);
|
||||
#pragma aux radstrupr = "mov ecx,edi" "lp:" "mov al,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub [edi],32" "c1:" "inc edi" "cmp al,0" "jne lp" parm [EDI] modify [EAX EDI] value [ecx];
|
||||
|
||||
char* radstrlwr(void* s1);
|
||||
#pragma aux radstrlwr = "mov ecx,edi" "lp:" "mov al,[edi]" "cmp al,'A'" "jb c1" "cmp al,'Z'" "ja c1" "add [edi],32" "c1:" "inc edi" "cmp al,0" "jne lp" parm [EDI] modify [EAX EDI] value [ecx];
|
||||
|
||||
u32 radstru32(const void* dest);
|
||||
#pragma aux radstru32 = "cld" "xor ecx,ecx" "xor ebx,ebx" "xor edi,edi" "lodsb" "cmp al,45" "jne skip2" "mov edi,1" "jmp skip" "lp:" "mov eax,10" "mul ecx" "lea ecx,[eax+ebx]" \
|
||||
"skip:" "lodsb" "skip2:" "cmp al,0x39" "ja dne" "cmp al,0x30" "jb dne" "mov bl,al" "sub bl,0x30" "jmp lp" "dne:" "test edi,1" "jz pos" "neg ecx" "pos:" \
|
||||
parm [ESI] modify [EAX EBX EDX EDI ESI] value [ecx];
|
||||
|
||||
u16 GetDS();
|
||||
#pragma aux GetDS = "mov ax,ds" value [ax];
|
||||
|
||||
#ifdef __RADWINEXT__
|
||||
|
||||
#define _16To32(ptr16) ((void*)(((GetSelectorBase((u16)(((u32)(ptr16))>>16))+((u16)(u32)(ptr16)))-GetSelectorBase(GetDS()))))
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __RADWIN__
|
||||
#define int86 int386
|
||||
#define int86x int386x
|
||||
#endif
|
||||
|
||||
#define u32regs x
|
||||
#define u16regs w
|
||||
|
||||
#else
|
||||
|
||||
#define radstrcpy strcpy
|
||||
#define radstrcat strcat
|
||||
#define radmemcpy memcpy
|
||||
#define radmemcpydb memmove
|
||||
#define radmemcmp memcmp
|
||||
#define radmemset memset
|
||||
#define radstrlen strlen
|
||||
#define radstrchr strchr
|
||||
#define radtoupper toupper
|
||||
#define radstru32(s) ((u32)atol(s))
|
||||
#define radstricmp _stricmp
|
||||
#define radstrcmp strcmp
|
||||
#define radstrupr _strupr
|
||||
#define radstrlwr _strlwr
|
||||
#define BreakPoint() __asm {int 3}
|
||||
#define DOSOut(str)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#pragma warning( disable : 4035)
|
||||
|
||||
typedef char* RADPCHAR;
|
||||
|
||||
u32 __inline radsqr(u32 m) {
|
||||
__asm {
|
||||
mov eax,[m]
|
||||
mul eax
|
||||
}
|
||||
}
|
||||
|
||||
u32 __inline mult64anddiv(u32 m1,u32 m2, u32 d) {
|
||||
__asm {
|
||||
mov eax,[m1]
|
||||
mov ecx,[m2]
|
||||
mul ecx
|
||||
mov ecx,[d]
|
||||
div ecx
|
||||
}
|
||||
}
|
||||
|
||||
s32 __inline radabs(s32 ab) {
|
||||
__asm {
|
||||
mov eax,[ab]
|
||||
test eax,eax
|
||||
jge skip
|
||||
neg eax
|
||||
skip:
|
||||
}
|
||||
}
|
||||
|
||||
u8 __inline radinp(u16 p) {
|
||||
__asm {
|
||||
mov dx,[p]
|
||||
in al,dx
|
||||
}
|
||||
}
|
||||
|
||||
void __inline radoutp(u16 p,u8 v) {
|
||||
__asm {
|
||||
mov dx,[p]
|
||||
mov al,[v]
|
||||
out dx,al
|
||||
}
|
||||
}
|
||||
|
||||
RADPCHAR __inline radstpcpy(char* p1, char* p2) {
|
||||
__asm {
|
||||
mov edx,[p1]
|
||||
mov ecx,[p2]
|
||||
cld
|
||||
lp:
|
||||
mov al,[ecx]
|
||||
inc ecx
|
||||
mov [edx],al
|
||||
inc edx
|
||||
cmp al,0
|
||||
jne lp
|
||||
dec edx
|
||||
mov eax,edx
|
||||
}
|
||||
}
|
||||
|
||||
RADPCHAR __inline radstpcpyrs(char* p1, char* p2) {
|
||||
__asm {
|
||||
mov edx,[p1]
|
||||
mov ecx,[p2]
|
||||
cld
|
||||
lp:
|
||||
mov al,[ecx]
|
||||
inc ecx
|
||||
mov [edx],al
|
||||
inc edx
|
||||
cmp al,0
|
||||
jne lp
|
||||
dec ecx
|
||||
mov eax,ecx
|
||||
}
|
||||
}
|
||||
|
||||
void __inline radmemset16(void* dest,u16 value,u32 sizeb) {
|
||||
__asm {
|
||||
mov edi,[dest]
|
||||
mov ax,[value]
|
||||
mov ecx,[sizeb]
|
||||
shl eax,16
|
||||
cld
|
||||
mov ax,[value]
|
||||
mov bl,cl
|
||||
shr ecx,1
|
||||
rep stosd
|
||||
mov cl,bl
|
||||
and cl,1
|
||||
rep stosw
|
||||
}
|
||||
}
|
||||
|
||||
void __inline radmemset32(void* dest,u32 value,u32 sizeb) {
|
||||
__asm {
|
||||
mov edi,[dest]
|
||||
mov eax,[value]
|
||||
mov ecx,[sizeb]
|
||||
cld
|
||||
rep stosd
|
||||
}
|
||||
}
|
||||
|
||||
u32 __inline __stdcall RADsqrt(u32 sq) {
|
||||
__asm {
|
||||
fild dword ptr [sq]
|
||||
fsqrt
|
||||
fistp word ptr [sq]
|
||||
movzx eax,word ptr [sq]
|
||||
}
|
||||
}
|
||||
|
||||
u32 __inline RADCycleTimerAvail(void)
|
||||
{
|
||||
u32 rdtscavail=(u32)-1;
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
#ifdef __MWERKS__
|
||||
rdtsc
|
||||
#else
|
||||
#if _MSC_VER<=1100
|
||||
__emit 0xf
|
||||
__emit 0x31
|
||||
#else
|
||||
rdtsc
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
rdtscavail=1;
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
rdtscavail=(u32)-1;
|
||||
}
|
||||
return rdtscavail;
|
||||
}
|
||||
|
||||
void __inline RADCycleTimerStartAddr(u32* addr)
|
||||
{
|
||||
__asm {
|
||||
mov ecx,[addr]
|
||||
#ifdef __MWERKS__
|
||||
rdtsc
|
||||
#else
|
||||
#if _MSC_VER<=1100
|
||||
__emit 0xf
|
||||
__emit 0x31
|
||||
#else
|
||||
rdtsc
|
||||
#endif
|
||||
#endif
|
||||
mov [ecx],eax
|
||||
}
|
||||
}
|
||||
|
||||
u32 __inline RADCycleTimerDeltaAddr(u32* addr)
|
||||
{
|
||||
__asm {
|
||||
#ifdef __MWERKS__
|
||||
rdtsc
|
||||
#else
|
||||
#if _MSC_VER<=1100
|
||||
__emit 0xf
|
||||
__emit 0x31
|
||||
#else
|
||||
rdtsc
|
||||
#endif
|
||||
#endif
|
||||
mov ecx,[addr]
|
||||
mov edx,eax
|
||||
sub eax,[ecx]
|
||||
mov [ecx],eax
|
||||
}
|
||||
}
|
||||
|
||||
void __inline RADCycleTimerStartAddr64(u64* addr)
|
||||
{
|
||||
__asm {
|
||||
mov ecx,[addr]
|
||||
#ifdef __MWERKS__
|
||||
rdtsc
|
||||
#else
|
||||
#if _MSC_VER<=1100
|
||||
__emit 0xf
|
||||
__emit 0x31
|
||||
#else
|
||||
rdtsc
|
||||
#endif
|
||||
#endif
|
||||
mov [ecx],eax
|
||||
mov [ecx+4],edx
|
||||
}
|
||||
}
|
||||
|
||||
void __inline RADCycleTimerDeltaAddr64(u64* addr)
|
||||
{
|
||||
__asm {
|
||||
#ifdef __MWERKS__
|
||||
rdtsc
|
||||
#else
|
||||
#if _MSC_VER<=1100
|
||||
__emit 0xf
|
||||
__emit 0x31
|
||||
#else
|
||||
rdtsc
|
||||
#endif
|
||||
#endif
|
||||
mov ecx,[addr]
|
||||
sub eax,[ecx]
|
||||
sbb edx,[ecx+4]
|
||||
mov [ecx],eax
|
||||
mov [ecx+4],edx
|
||||
}
|
||||
}
|
||||
|
||||
#define RADCycleTimerStart(var) RADCycleTimerStartAddr(&var)
|
||||
#define RADCycleTimerDelta(var) RADCycleTimerDeltaAddr(&var)
|
||||
|
||||
#define RADCycleTimerStart64(var) RADCycleTimerStartAddr64(&var)
|
||||
#define RADCycleTimerDelta64(var) RADCycleTimerDeltaAddr64(&var)
|
||||
|
||||
#pragma warning( default : 4035)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define PTR4 __far
|
||||
|
||||
#define u16 unsigned int
|
||||
#define s16 signed int
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
|
||||
u32 radsqr(s32 a);
|
||||
#pragma aux radsqr = "shl edx,16" "mov dx,ax" "mov eax,edx" "xor edx,edx" "mul eax" "shld edx,eax,16" parm [dx ax] modify [DX ax] value [dx ax];
|
||||
|
||||
s16 radabs(s16 ab);
|
||||
#pragma aux radabs = "test ax,ax" "jge skip" "neg ax" "skip:" parm [ax] value [ax];
|
||||
|
||||
s32 radabs32(s32 ab);
|
||||
#pragma aux radabs32 = "test dx,dx" "jge skip" "neg dx" "neg ax" "sbb dx,0" "skip:" parm [dx ax] value [dx ax];
|
||||
|
||||
u32 DOSOut(const char far* dest);
|
||||
#pragma aux DOSOut = "cld" "and edi,0xffff" "mov dx,di" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "mov bx,1" "push ds" "push es" "pop ds" "mov ah,0x40" "int 0x21" "pop ds" "movzx eax,cx" "shr ecx,16" \
|
||||
parm [ES DI] modify [AX BX CX DX DI ES] value [CX AX];
|
||||
|
||||
void DOSOutNum(const char far* str,u16 len);
|
||||
#pragma aux DOSOutNum = "push ds" "mov ds,cx" "mov cx,bx" "mov ah,0x40" "mov bx,1" "int 0x21" "pop ds" parm [cx dx] [bx] modify [ax bx cx];
|
||||
|
||||
u32 ErrOut(const char far* dest);
|
||||
#pragma aux ErrOut = "cld" "and edi,0xffff" "mov dx,di" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "xor bx,bx" "push ds" "push es" "pop ds" "mov ah,0x40" "int 0x21" "pop ds" "movzx eax,cx" "shr ecx,16" \
|
||||
parm [ES DI] modify [AX BX CX DX DI ES] value [CX AX];
|
||||
|
||||
void ErrOutNum(const char far* str,u16 len);
|
||||
#pragma aux ErrOutNum = "push ds" "mov ds,cx" "mov cx,bx" "mov ah,0x40" "xor bx,bx" "int 0x21" "pop ds" parm [cx dx] [bx] modify [ax bx cx];
|
||||
|
||||
void radmemset(void far *dest,u8 value,u32 size);
|
||||
#pragma aux radmemset = "cld" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "mov ah,al" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,2" 0x67 "rep stosd" "mov cl,bl" "and cl,3" "rep stosb" parm [ES DI] [AL] [CX BX];
|
||||
|
||||
void radmemset16(void far* dest,u16 value,u32 size);
|
||||
#pragma aux radmemset16 = "cld" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "mov bx,ax" "shl eax,16" "mov ax,bx" "mov bl,cl" "shr ecx,1" "rep stosd" "mov cl,bl" "and cl,1" "rep stosw" parm [ES DI] [AX] [CX BX];
|
||||
|
||||
void radmemcpy(void far* dest,const void far* source,u32 size);
|
||||
#pragma aux radmemcpy = "cld" "push ds" "mov ds,dx" "and esi,0ffffh" "and edi,0ffffh" "shl ecx,16" "mov cx,bx" "shr ecx,2" 0x67 "rep movsd" "mov cl,bl" "and cl,3" "rep movsb" "pop ds" parm [ES DI] [DX SI] [CX BX] modify [CX SI DI ES];
|
||||
|
||||
s8 radmemcmp(const void far* s1,const void far* s2,u32 len);
|
||||
#pragma aux radmemcmp = "cld" "push ds" "mov ds,dx" "shl ecx,16" "mov cx,bx" "rep cmpsb" "setne al" "jbe end" "neg al" "end:" "pop ds" parm [ES DI] [DX SI] [CX BX] modify [CX SI DI ES];
|
||||
|
||||
char far* radstrcpy(void far* dest,const void far* source);
|
||||
#pragma aux radstrcpy = "cld" "push ds" "mov ds,dx" "and esi,0xffff" "and edi,0xffff" "mov dx,di" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" parm [ES DI] [DX SI] modify [AX DX DI SI ES] value [es dx];
|
||||
|
||||
char far* radstpcpy(void far* dest,const void far* source);
|
||||
#pragma aux radstpcpy = "cld" "push ds" "mov ds,dx" "and esi,0xffff" "and edi,0xffff" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "dec di" "pop ds" parm [ES DI] [DX SI] modify [DI SI ES] value [es di];
|
||||
|
||||
u32 radstrlen(const void far* dest);
|
||||
#pragma aux radstrlen = "cld" "and edi,0xffff" "mov ecx,0xffffffff" "xor eax,eax" 0x67 "repne scasb" "not ecx" "dec ecx" "movzx eax,cx" "shr ecx,16" parm [ES DI] modify [AX CX DI ES] value [CX AX];
|
||||
|
||||
char far* radstrcat(void far* dest,const void far* source);
|
||||
#pragma aux radstrcat = "cld" "and edi,0xffff" "mov ecx,0xffffffff" "and esi,0xffff" "push ds" "mov ds,dx" "mov dx,di" "xor eax,eax" 0x67 "repne scasb" "dec edi" "lp:" "lodsb" "stosb" "test al,0xff" "jnz lp" "pop ds" \
|
||||
parm [ES DI] [DX SI] modify [AX CX DI SI ES] value [es dx];
|
||||
|
||||
char far* radstrchr(const void far* dest,char chr);
|
||||
#pragma aux radstrchr = "cld" "lp:" 0x26 "lodsb" "cmp al,dl" "je fnd" "cmp al,0" "jnz lp" "xor ax,ax" "mov es,ax" "mov si,1" "fnd:" "dec si" parm [ES SI] [DL] modify [AX SI ES] value [es si];
|
||||
|
||||
s8 radstricmp(const void far* s1,const void far* s2);
|
||||
#pragma aux radstricmp = "and edi,0xffff" "push ds" "mov ds,dx" "and esi,0xffff" "lp:" "mov al,[esi]" "mov ah,[edi]" "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" \
|
||||
"cmp ah,'a'" "jb c2" "cmp ah,'z'" "ja c2" "sub ah,32" "c2:" "cmp al,ah" "jne set" "cmp al,0" "je set" \
|
||||
"inc esi" "inc edi" "jmp lp" "set:" "setne al" "jbe end" "neg al" "end:" "pop ds" \
|
||||
parm [ES DI] [DX SI] modify [AX DI SI];
|
||||
|
||||
u32 radstru32(const void far* dest);
|
||||
#pragma aux radstru32 = "cld" "xor ecx,ecx" "xor ebx,ebx" "xor edi,edi" 0x26 "lodsb" "cmp al,45" "jne skip2" "mov edi,1" "jmp skip" "lp:" "mov eax,10" "mul ecx" "lea ecx,[eax+ebx]" \
|
||||
"skip:" 0x26 "lodsb" "skip2:" "cmp al,0x39" "ja dne" "cmp al,0x30" "jb dne" "mov bl,al" "sub bl,0x30" "jmp lp" "dne:" "test edi,1" "jz pos" "neg ecx" "pos:" \
|
||||
"movzx eax,cx" "shr ecx,16" parm [ES SI] modify [AX BX DX DI SI] value [cx ax];
|
||||
|
||||
u32 mult64anddiv(u32 m1,u32 m2,u32 d);
|
||||
#pragma aux mult64anddiv = "shl ecx,16" "mov cx,ax" "shrd eax,edx,16" "mov ax,si" "mul ecx" "shl edi,16" "mov di,bx" "div edi" "shld edx,eax,16" "and edx,0xffff" "and eax,0xffff" parm [cx ax] [dx si] [di bx] \
|
||||
modify [ax bx cx dx si di] value [dx ax];
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
RADDEFEND
|
||||
|
||||
#define u32neg1 ((u32)(s32)-1)
|
||||
#define RAD_align(var) var; u8 junk##var[4-(sizeof(var)&3)];
|
||||
#define RAD_align_after(var) u8 junk##var[4-(sizeof(var)&3)]={0};
|
||||
#define RAD_align_init(var,val) var=val; u8 junk##var[4-(sizeof(var)&3)]={0};
|
||||
#define RAD_align_array(var,num) var[num]; u8 junk##var[4-(sizeof(var)&3)];
|
||||
#define RAD_align_string(var,str) char var[]=str; u8 junk##var[4-(sizeof(var)&3)]={0};
|
||||
|
||||
|
||||
typedef void PTR4* (RADLINK PTR4* RADMEMALLOC) (u32 bytes);
|
||||
typedef void (RADLINK PTR4* RADMEMFREE) (void PTR4* ptr);
|
||||
|
||||
#ifdef __RADMAC__
|
||||
#pragma export on
|
||||
#endif
|
||||
RADEXPFUNC void RADEXPLINK RADSetMemory(RADMEMALLOC a,RADMEMFREE f);
|
||||
#ifdef __RADMAC__
|
||||
#pragma export off
|
||||
#endif
|
||||
|
||||
RADEXPFUNC void PTR4* RADEXPLINK radmalloc(u32 numbytes);
|
||||
RADEXPFUNC void RADEXPLINK radfree(void PTR4* ptr);
|
||||
|
||||
#ifdef __RADDOS__
|
||||
|
||||
RADDEFSTART
|
||||
extern void* RADTimerSetupAddr;
|
||||
extern void* RADTimerReadAddr;
|
||||
extern void* RADTimerDoneAddr;
|
||||
RADDEFEND
|
||||
|
||||
typedef void RADEXPLINK (*RADTimerSetupType)(void);
|
||||
typedef u32 RADEXPLINK (*RADTimerReadType)(void);
|
||||
typedef void RADEXPLINK (*RADTimerDoneType)(void);
|
||||
|
||||
#define RADTimerSetup() ((RADTimerSetupType)(RADTimerSetupAddr))()
|
||||
#define RADTimerRead() ((RADTimerReadType)(RADTimerReadAddr))()
|
||||
#define RADTimerDone() ((RADTimerDoneType)(RADTimerDoneAddr))()
|
||||
|
||||
#else
|
||||
|
||||
#define RADTimerSetup()
|
||||
#define RADTimerDone()
|
||||
|
||||
#if (defined(__RAD16__) || defined(__RADWINEXT__))
|
||||
|
||||
#define RADTimerRead timeGetTime
|
||||
|
||||
#else
|
||||
|
||||
RADEXPFUNC u32 RADEXPLINK RADTimerRead(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
|
||||
char bkbhit();
|
||||
#pragma aux bkbhit = "mov ah,1" "int 0x16" "lahf" "shr eax,14" "and eax,1" "xor al,1" ;
|
||||
|
||||
char bgetch();
|
||||
#pragma aux bgetch = "xor ah,ah" "int 0x16" "test al,0xff" "jnz done" "mov al,ah" "or al,0x80" "done:" modify [AX];
|
||||
|
||||
void BreakPoint();
|
||||
#pragma aux BreakPoint = "int 3";
|
||||
|
||||
u8 radinp(u16 p);
|
||||
#pragma aux radinp = "in al,dx" parm [DX];
|
||||
|
||||
u8 radtoupper(u8 p);
|
||||
#pragma aux radtoupper = "cmp al,'a'" "jb c1" "cmp al,'z'" "ja c1" "sub al,32" "c1:" parm [al] value [al];
|
||||
|
||||
void radoutp(u16 p,u8 v);
|
||||
#pragma aux radoutp = "out dx,al" parm [DX] [AL];
|
||||
|
||||
#else
|
||||
|
||||
// for multi-processor machines
|
||||
|
||||
#ifdef __RADNT__
|
||||
#define LockedIncrement(var) __asm { lock inc [var] }
|
||||
#define LockedDecrement(var) __asm { lock dec [var] }
|
||||
void __inline LockedIncrementFunc(void PTR4* var) {
|
||||
__asm {
|
||||
mov eax,[var]
|
||||
lock inc [eax]
|
||||
}
|
||||
}
|
||||
|
||||
void __inline LockedDecrementFunc(void PTR4* var) {
|
||||
__asm {
|
||||
mov eax,[var]
|
||||
lock dec [eax]
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __RADMAC__
|
||||
|
||||
#define LockedIncrement(var) {++(var);}
|
||||
#define LockedDecrement(var) {--(var);}
|
||||
|
||||
#define LockedIncrementFunc(ptr) {++(*((u32*)(ptr)));}
|
||||
#define LockedDecrementFunc(ptr) {--(*((u32*)(ptr)));}
|
||||
|
||||
#else
|
||||
|
||||
#define LockedIncrement(var) __asm { inc [var] }
|
||||
#define LockedDecrement(var) __asm { dec [var] }
|
||||
void __inline LockedIncrementFunc(void PTR4* var) { __asm { mov eax,[var]
|
||||
inc [eax] } }
|
||||
void __inline LockedDecrementFunc(void PTR4* var) { __asm { mov eax,[var]
|
||||
dec [eax] } }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
21
code/win32/resource.h
Normal file
21
code/win32/resource.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by winquake.rc
|
||||
//
|
||||
#define IDS_STRING1 1
|
||||
#define IDI_ICON1 1
|
||||
#define IDB_BITMAP1 1
|
||||
#define IDB_BITMAP2 128
|
||||
#define IDC_CURSOR1 129
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1005
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
64
code/win32/shader_constants.h
Normal file
64
code/win32/shader_constants.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
//
|
||||
// ShaderConstants.h
|
||||
//
|
||||
// Definitions for various shader constants
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _SHADERCONSTANTS_H_
|
||||
#define _SHADERCONSTANTS_H_
|
||||
|
||||
#define CV_ZERO 0
|
||||
#define CV_ONE 1
|
||||
#define CV_HALF 2
|
||||
|
||||
#define CV_WORLDVIEWPROJ_0 4
|
||||
#define CV_WORLDVIEWPROJ_1 5
|
||||
#define CV_WORLDVIEWPROJ_2 6
|
||||
#define CV_WORLDVIEWPROJ_3 7
|
||||
|
||||
#define CV_WORLDVIEW_0 8
|
||||
#define CV_WORLDVIEW_1 9
|
||||
#define CV_WORLDVIEW_2 10
|
||||
#define CV_WORLDVIEW_3 11
|
||||
|
||||
#define CV_WORLDVIEWIT_0 12
|
||||
#define CV_WORLDVIEWIT_1 13
|
||||
#define CV_WORLDVIEWIT_2 14
|
||||
|
||||
#define CV_WORLD_0 15
|
||||
#define CV_WORLD_1 16
|
||||
#define CV_WORLD_2 17
|
||||
#define CV_WORLD_3 18
|
||||
|
||||
#define CV_VIEWINV_0 19
|
||||
#define CV_VIEWINV_1 20
|
||||
#define CV_VIEWINV_2 21
|
||||
#define CV_VIEWINV_3 22
|
||||
|
||||
#define CV_VIEW_0 23
|
||||
#define CV_VIEW_1 24
|
||||
#define CV_VIEW_2 25
|
||||
#define CV_VIEW_3 26
|
||||
|
||||
#define CV_LIGHT_COLOR 50
|
||||
#define CV_ONE_OVER_LIGHT_RANGE 51
|
||||
|
||||
#define CV_LIGHT_DIRECTION 52
|
||||
#define CV_LIGHT_POSITION 53
|
||||
|
||||
#define CV_CAMERA_DIRECTION 54
|
||||
|
||||
#define CV_EXTRUSION_LENGTH 55
|
||||
#define CV_SHADOW_FACTORS 56
|
||||
#define CV_SHADOW_PLANE 57
|
||||
|
||||
#define CV_VIEWPORT_OFFSETS 95
|
||||
|
||||
#define CP_AMBIENT_COLOR 0
|
||||
#define CP_DIFFUSE_COLOR 1
|
||||
#define CP_EXTRACT_CUTOFF 2
|
||||
#define CP_EXTRACT_SCALE 3
|
||||
|
||||
#endif
|
||||
85
code/win32/snd_fx_img.h
Normal file
85
code/win32/snd_fx_img.h
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum _DSP_IMAGE_image_FX_INDICES {
|
||||
GraphI3DL2_I3DL2Reverb = 0,
|
||||
GraphXTalk_XTalk = 1,
|
||||
GraphVoice_Voice_0 = 2,
|
||||
GraphVoice_Voice_1 = 3,
|
||||
GraphVoice_Voice_2 = 4,
|
||||
GraphVoice_Voice_3 = 5
|
||||
} DSP_IMAGE_image_FX_INDICES;
|
||||
|
||||
#define DSI3DL2_ENVIRONMENT_GraphI3DL2_I3DL2Reverb -1000, -100, 0.000000, 1.490000, 0.830000, -2602, 0.007000, 200, 0.011000, 100.000000, 100.000000, 5000.000000
|
||||
|
||||
typedef struct _GraphI3DL2_FX0_I3DL2Reverb_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[2]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[35]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphI3DL2_FX0_I3DL2Reverb_STATE, *LPGraphI3DL2_FX0_I3DL2Reverb_STATE;
|
||||
|
||||
typedef const GraphI3DL2_FX0_I3DL2Reverb_STATE *LPCGraphI3DL2_FX0_I3DL2Reverb_STATE;
|
||||
|
||||
typedef struct _GraphXTalk_FX0_XTalk_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[4]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[4]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphXTalk_FX0_XTalk_STATE, *LPGraphXTalk_FX0_XTalk_STATE;
|
||||
|
||||
typedef const GraphXTalk_FX0_XTalk_STATE *LPCGraphXTalk_FX0_XTalk_STATE;
|
||||
|
||||
typedef struct _GraphVoice_FX0_Voice_0_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphVoice_FX0_Voice_0_STATE, *LPGraphVoice_FX0_Voice_0_STATE;
|
||||
|
||||
typedef const GraphVoice_FX0_Voice_0_STATE *LPCGraphVoice_FX0_Voice_0_STATE;
|
||||
|
||||
typedef struct _GraphVoice_FX1_Voice_1_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphVoice_FX1_Voice_1_STATE, *LPGraphVoice_FX1_Voice_1_STATE;
|
||||
|
||||
typedef const GraphVoice_FX1_Voice_1_STATE *LPCGraphVoice_FX1_Voice_1_STATE;
|
||||
|
||||
typedef struct _GraphVoice_FX2_Voice_2_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphVoice_FX2_Voice_2_STATE, *LPGraphVoice_FX2_Voice_2_STATE;
|
||||
|
||||
typedef const GraphVoice_FX2_Voice_2_STATE *LPCGraphVoice_FX2_Voice_2_STATE;
|
||||
|
||||
typedef struct _GraphVoice_FX3_Voice_3_STATE {
|
||||
DWORD dwScratchOffset; // Offset in bytes, of scratch area for this FX
|
||||
DWORD dwScratchLength; // Length in DWORDS, of scratch area for this FX
|
||||
DWORD dwYMemoryOffset; // Offset in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwYMemoryLength; // Length in DSP WORDS, of Y memory area for this FX
|
||||
DWORD dwFlags; // FX bitfield for various flags. See xgpimage documentation
|
||||
DWORD dwInMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of input mixbins
|
||||
DWORD dwOutMixbinPtrs[1]; // XRAM offsets in DSP WORDS, of output mixbins
|
||||
} GraphVoice_FX3_Voice_3_STATE, *LPGraphVoice_FX3_Voice_3_STATE;
|
||||
|
||||
typedef const GraphVoice_FX3_Voice_3_STATE *LPCGraphVoice_FX3_Voice_3_STATE;
|
||||
BIN
code/win32/starwars.ico
Normal file
BIN
code/win32/starwars.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
33
code/win32/win_file.h
Normal file
33
code/win32/win_file.h
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#ifndef _WIN_FILE_
|
||||
#define _WIN_FILE_
|
||||
|
||||
typedef int wfhandle_t;
|
||||
|
||||
extern void WF_Init(void);
|
||||
extern void WF_Shutdown(void);
|
||||
extern wfhandle_t WF_Open(const char* name, bool read, bool aligned);
|
||||
extern void WF_Close(wfhandle_t handle);
|
||||
extern int WF_Read(void* buffer, int len, wfhandle_t handle);
|
||||
extern int WF_Write(const void* buffer, int len, wfhandle_t handle);
|
||||
extern int WF_Seek(int offset, int origin, wfhandle_t handle);
|
||||
extern int WF_Tell(wfhandle_t handle);
|
||||
extern int WF_Resize(int size, wfhandle_t handle);
|
||||
|
||||
int Sys_GetFileCode(const char *name);
|
||||
void Sys_InitFileCodes(void);
|
||||
void Sys_ShutdownFileCodes(void);
|
||||
|
||||
|
||||
#endif _WIN_FILE_
|
||||
171
code/win32/win_file_xbox.cpp
Normal file
171
code/win32/win_file_xbox.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#include "../game/q_shared.h"
|
||||
#include "win_file.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <Xtl.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct FileTable
|
||||
{
|
||||
bool m_bUsed;
|
||||
bool m_bErrorsFatal;
|
||||
HANDLE m_Handle;
|
||||
};
|
||||
|
||||
FileTable* s_FileTable = NULL;
|
||||
const int WF_MAX_OPEN_FILES = 8;
|
||||
|
||||
void WF_Init(void)
|
||||
{
|
||||
assert(!s_FileTable);
|
||||
|
||||
s_FileTable = new FileTable[WF_MAX_OPEN_FILES];
|
||||
|
||||
for (wfhandle_t i = 0; i < WF_MAX_OPEN_FILES; ++i)
|
||||
{
|
||||
s_FileTable[i].m_bUsed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WF_Shutdown(void)
|
||||
{
|
||||
assert(s_FileTable);
|
||||
|
||||
for (wfhandle_t i = 0; i < WF_MAX_OPEN_FILES; ++i)
|
||||
{
|
||||
if (s_FileTable[i].m_bUsed)
|
||||
{
|
||||
WF_Close(i);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] s_FileTable;
|
||||
s_FileTable = NULL;
|
||||
}
|
||||
|
||||
static wfhandle_t WF_GetFreeHandle(void)
|
||||
{
|
||||
for (int i = 0; i < WF_MAX_OPEN_FILES; ++i)
|
||||
{
|
||||
if (!s_FileTable[i].m_bUsed)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WF_Open(const char* name, bool read, bool aligned)
|
||||
{
|
||||
wfhandle_t handle = WF_GetFreeHandle();
|
||||
if (handle == -1) return -1;
|
||||
|
||||
s_FileTable[handle].m_Handle =
|
||||
CreateFile(name, read ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, 0,
|
||||
read ? OPEN_EXISTING : OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL |(aligned ? FILE_FLAG_NO_BUFFERING : 0) , 0);
|
||||
|
||||
if (s_FileTable[handle].m_Handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
s_FileTable[handle].m_bUsed = true;
|
||||
|
||||
// errors are fatal on game partition
|
||||
s_FileTable[handle].m_bErrorsFatal = (name[0] == 'D' || name[0] == 'd');
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void WF_Close(wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
CloseHandle(s_FileTable[handle].m_Handle);
|
||||
s_FileTable[handle].m_bUsed = false;
|
||||
}
|
||||
|
||||
int WF_Read(void* buffer, int len, wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
DWORD bytes;
|
||||
if (!ReadFile(s_FileTable[handle].m_Handle, buffer, len, &bytes, 0) &&
|
||||
s_FileTable[handle].m_bErrorsFatal)
|
||||
{
|
||||
#if defined(FINAL_BUILD)
|
||||
extern void ERR_DiscFail(bool);
|
||||
ERR_DiscFail(false);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int WF_Write(const void* buffer, int len, wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
DWORD bytes;
|
||||
WriteFile(s_FileTable[handle].m_Handle, buffer, len, &bytes, 0);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int WF_Seek(int offset, int origin, wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case SEEK_CUR: origin = FILE_CURRENT; break;
|
||||
case SEEK_END: origin = FILE_END; break;
|
||||
case SEEK_SET: origin = FILE_BEGIN; break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
return SetFilePointer(s_FileTable[handle].m_Handle, offset, 0, origin) < 0;
|
||||
}
|
||||
|
||||
int WF_Tell(wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
return SetFilePointer(s_FileTable[handle].m_Handle, 0, 0, FILE_CURRENT);
|
||||
}
|
||||
|
||||
int WF_Resize(int size, wfhandle_t handle)
|
||||
{
|
||||
assert(handle >= 0 && handle < WF_MAX_OPEN_FILES &&
|
||||
s_FileTable[handle].m_bUsed);
|
||||
|
||||
SetFilePointer(s_FileTable[handle].m_Handle, size, NULL, FILE_BEGIN);
|
||||
return SetEndOfFile(s_FileTable[handle].m_Handle);
|
||||
}
|
||||
350
code/win32/win_filecode.cpp
Normal file
350
code/win32/win_filecode.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
#include "../client/client.h"
|
||||
#include "../win32/win_local.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "../qcommon/fixedmap.h"
|
||||
#include "../zlib/zlib.h"
|
||||
#include "../qcommon/files.h"
|
||||
|
||||
/***********************************************
|
||||
*
|
||||
* WINDOWS/XBOX VERSION
|
||||
*
|
||||
* Build a translation table, CRC -> file name. We have the memory.
|
||||
*
|
||||
************************************************/
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(_XBOX)
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
char* name;
|
||||
int size;
|
||||
};
|
||||
static VVFixedMap< FileInfo, unsigned int >* s_Files = NULL;
|
||||
static byte* buffer;
|
||||
|
||||
HANDLE s_Mutex = INVALID_HANDLE_VALUE;
|
||||
|
||||
int _buildFileList(const char* path, bool insert, bool buildList)
|
||||
{
|
||||
WIN32_FIND_DATA data;
|
||||
char spec[MAX_OSPATH];
|
||||
int count = 0;
|
||||
|
||||
// Look for all files
|
||||
Com_sprintf(spec, sizeof(spec), "%s\\*.*", path);
|
||||
|
||||
HANDLE h = FindFirstFile(spec, &data);
|
||||
while (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
char full[MAX_OSPATH];
|
||||
Com_sprintf(full, sizeof(full), "%s\\%s", path, data.cFileName);
|
||||
|
||||
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
// Directory -- lets go recursive
|
||||
if (data.cFileName[0] != '.') {
|
||||
count += _buildFileList(full, insert, buildList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(insert || buildList)
|
||||
{
|
||||
// Regular file -- add it to the table
|
||||
strlwr(full);
|
||||
unsigned int code = crc32(0, (const byte *)full, strlen(full));
|
||||
|
||||
FileInfo info;
|
||||
info.name = CopyString(full);
|
||||
info.size = data.nFileSizeLow;
|
||||
|
||||
if(insert)
|
||||
{
|
||||
s_Files->Insert(info, code);
|
||||
}
|
||||
|
||||
if(buildList)
|
||||
{
|
||||
// get the length of the filename
|
||||
int len;
|
||||
len = strlen(info.name) + 1;
|
||||
|
||||
// save the file code
|
||||
*(int*)buffer = code;
|
||||
buffer += sizeof(code);
|
||||
|
||||
// save the name of the file
|
||||
strcpy((char*)buffer,info.name);
|
||||
buffer += len;
|
||||
|
||||
// save the size of the file
|
||||
*(int*)buffer = info.size;
|
||||
buffer += sizeof(info.size);
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// Continue the loop
|
||||
if (!FindNextFile(h, &data))
|
||||
{
|
||||
FindClose(h);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool _buildFileListFromSavedList(void)
|
||||
{
|
||||
// open the file up for reading
|
||||
FILE* in;
|
||||
extern const char *Sys_RemapPath( const char *filename );
|
||||
in = fopen( Sys_RemapPath( "xbx_filelist" ), "rb" );
|
||||
if(!in)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// read in the number of files
|
||||
int count;
|
||||
if(!(fread(&count,sizeof(count),1,in)))
|
||||
{
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate memory for a temp buffer
|
||||
byte* baseAddr;
|
||||
int bufferSize;
|
||||
bufferSize = count * ( 2 * sizeof(int) + MAX_OSPATH );
|
||||
buffer = (byte*)Z_Malloc(bufferSize,TAG_TEMP_WORKSPACE,qtrue,32);
|
||||
baseAddr = buffer;
|
||||
|
||||
// read the rest of the file into a big buffer
|
||||
if(!(fread(buffer,bufferSize,1,in)))
|
||||
{
|
||||
fclose(in);
|
||||
Z_Free(baseAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate some memory for s_Files
|
||||
s_Files = new VVFixedMap<FileInfo, unsigned int>(count);
|
||||
|
||||
// loop through all the files write out the codes
|
||||
int i;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
FileInfo info;
|
||||
unsigned int code;
|
||||
|
||||
// read the code for the file
|
||||
code = *(int*)buffer;
|
||||
buffer += sizeof(code);
|
||||
|
||||
// read the filename
|
||||
info.name = CopyString((char*)buffer);
|
||||
buffer += (strlen(info.name) + 1);
|
||||
|
||||
// read the size of the file
|
||||
info.size = *(int*)buffer;
|
||||
buffer += sizeof(info.size);
|
||||
|
||||
// save the data - optimization: don't check for dupes!
|
||||
s_Files->InsertUnsafe(info, code);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
Z_Free(baseAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sys_SaveFileCodes(void)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
// get the number of files
|
||||
int count;
|
||||
count = _buildFileList(Sys_Cwd(), false, false);
|
||||
|
||||
// open a file for writing
|
||||
FILE* out;
|
||||
out = fopen("d:\\xbx_filelist","wb");
|
||||
if(!out)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate a buffer for writing
|
||||
byte* baseAddr;
|
||||
int bufferSize;
|
||||
|
||||
bufferSize = sizeof(int) + ( count * ( 2 * sizeof(int) + MAX_OSPATH ) );
|
||||
baseAddr = (byte*)Z_Malloc(bufferSize,TAG_TEMP_WORKSPACE,qtrue,32);
|
||||
buffer = baseAddr;
|
||||
|
||||
// write the number of files to the buffer
|
||||
*(int*)buffer = count;
|
||||
buffer += sizeof(count);
|
||||
|
||||
// fill up the rest of the buffer
|
||||
ret = _buildFileList(Sys_Cwd(), false, true);
|
||||
|
||||
if(!ret)
|
||||
{
|
||||
// there was a problem
|
||||
fclose(out);
|
||||
Z_Free(baseAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// attempt to write out the data
|
||||
if(!(fwrite(baseAddr,bufferSize,1,out)))
|
||||
{
|
||||
// there was a problem
|
||||
fclose(out);
|
||||
Z_Free(baseAddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// everything went ok
|
||||
fclose(out);
|
||||
Z_Free(baseAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sys_InitFileCodes(void)
|
||||
{
|
||||
bool ret;
|
||||
int count = 0;
|
||||
|
||||
Z_PushNewDeleteTag( TAG_FILELIST );
|
||||
|
||||
// First: try to load an existing filecode cache
|
||||
ret = _buildFileListFromSavedList();
|
||||
|
||||
// if we had trouble building the list that way
|
||||
// we need to do it by searching the files
|
||||
if( !ret )
|
||||
{
|
||||
// There was no filelist cache, make one
|
||||
if( !Sys_SaveFileCodes() )
|
||||
Com_Error( ERR_DROP, "ERROR: Couldn't create filecode cache\n" );
|
||||
|
||||
// Now re-read it
|
||||
if( !_buildFileListFromSavedList() )
|
||||
Com_Error( ERR_DROP, "ERROR: Couldn't re-read filecode cache\n" );
|
||||
}
|
||||
s_Files->Sort();
|
||||
|
||||
Z_PopNewDeleteTag();
|
||||
|
||||
// make it thread safe
|
||||
s_Mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
}
|
||||
|
||||
void Sys_ShutdownFileCodes(void)
|
||||
{
|
||||
FileInfo* info = NULL;
|
||||
|
||||
info = s_Files->Pop();
|
||||
while(info)
|
||||
{
|
||||
Z_Free(info->name);
|
||||
info->name = NULL;
|
||||
info = s_Files->Pop();
|
||||
}
|
||||
|
||||
delete s_Files;
|
||||
s_Files = NULL;
|
||||
|
||||
CloseHandle(s_Mutex);
|
||||
}
|
||||
|
||||
int Sys_GetFileCode(const char* name)
|
||||
{
|
||||
WaitForSingleObject(s_Mutex, INFINITE);
|
||||
|
||||
// Get system level path
|
||||
char* osname = FS_BuildOSPathUnMapped(name);
|
||||
|
||||
// Generate hash for file name
|
||||
strlwr(osname);
|
||||
unsigned int code = crc32(0, (const byte *)osname, strlen(osname));
|
||||
|
||||
// Check if the file exists
|
||||
if (!s_Files->Find(code))
|
||||
{
|
||||
ReleaseMutex(s_Mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ReleaseMutex(s_Mutex);
|
||||
return code;
|
||||
}
|
||||
|
||||
const char* Sys_GetFileCodeName(int code)
|
||||
{
|
||||
WaitForSingleObject(s_Mutex, INFINITE);
|
||||
|
||||
FileInfo *entry = s_Files->Find(code);
|
||||
if (entry)
|
||||
{
|
||||
ReleaseMutex(s_Mutex);
|
||||
return entry->name;
|
||||
}
|
||||
|
||||
ReleaseMutex(s_Mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int Sys_GetFileCodeSize(int code)
|
||||
{
|
||||
WaitForSingleObject(s_Mutex, INFINITE);
|
||||
|
||||
FileInfo *entry = s_Files->Find(code);
|
||||
if (entry)
|
||||
{
|
||||
ReleaseMutex(s_Mutex);
|
||||
return entry->size;
|
||||
}
|
||||
|
||||
ReleaseMutex(s_Mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Quick function to re-scan for new files, update the filecode
|
||||
// table, and dump the new one to disk
|
||||
void Sys_FilecodeScan_f( void )
|
||||
{
|
||||
// Make an updated filecode cache
|
||||
if( !Sys_SaveFileCodes() )
|
||||
Com_Error( ERR_DROP, "ERROR: Couldn't create filecode cache\n" );
|
||||
|
||||
// Throw out our current list
|
||||
Sys_ShutdownFileCodes();
|
||||
|
||||
// Re-init, which should use the new list we just made
|
||||
Sys_InitFileCodes();
|
||||
}
|
||||
141
code/win32/win_gamma.cpp
Normal file
141
code/win32/win_gamma.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
** WIN_GAMMA.C
|
||||
*/
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "glw_win.h"
|
||||
#include "win_local.h"
|
||||
|
||||
static unsigned short s_oldHardwareGamma[3][256];
|
||||
|
||||
/*
|
||||
** WG_CheckHardwareGamma
|
||||
**
|
||||
** Determines if the underlying hardware supports the Win32 gamma correction API.
|
||||
*/
|
||||
void WG_CheckHardwareGamma( void )
|
||||
{
|
||||
HDC hDC;
|
||||
|
||||
glConfig.deviceSupportsGamma = qfalse;
|
||||
|
||||
if ( !r_ignorehwgamma->integer )
|
||||
{
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
glConfig.deviceSupportsGamma = GetDeviceGammaRamp( hDC, s_oldHardwareGamma );
|
||||
ReleaseDC( GetDesktopWindow(), hDC );
|
||||
|
||||
if ( glConfig.deviceSupportsGamma )
|
||||
{
|
||||
//
|
||||
// do a sanity check on the gamma values
|
||||
//
|
||||
if ( ( HIBYTE( s_oldHardwareGamma[0][255] ) <= HIBYTE( s_oldHardwareGamma[0][0] ) ) ||
|
||||
( HIBYTE( s_oldHardwareGamma[1][255] ) <= HIBYTE( s_oldHardwareGamma[1][0] ) ) ||
|
||||
( HIBYTE( s_oldHardwareGamma[2][255] ) <= HIBYTE( s_oldHardwareGamma[2][0] ) ) )
|
||||
{
|
||||
glConfig.deviceSupportsGamma = qfalse;
|
||||
VID_Printf( PRINT_WARNING, "WARNING: device has broken gamma support, generated gamma.dat\n" );
|
||||
}
|
||||
|
||||
//
|
||||
// make sure that we didn't have a prior crash in the game, and if so we need to
|
||||
// restore the gamma values to at least a linear value
|
||||
//
|
||||
if ( ( HIBYTE( s_oldHardwareGamma[0][181] ) == 255 ) )
|
||||
{
|
||||
int g;
|
||||
|
||||
VID_Printf( PRINT_WARNING, "WARNING: suspicious gamma tables, using linear ramp for restoration\n" );
|
||||
|
||||
for ( g = 0; g < 255; g++ )
|
||||
{
|
||||
s_oldHardwareGamma[0][g] = g << 8;
|
||||
s_oldHardwareGamma[1][g] = g << 8;
|
||||
s_oldHardwareGamma[2][g] = g << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_SetGamma
|
||||
**
|
||||
** This routine should only be called if glConfig.deviceSupportsGamma is TRUE
|
||||
*/
|
||||
void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) {
|
||||
unsigned short table[3][256];
|
||||
int i, j;
|
||||
int ret;
|
||||
OSVERSIONINFO vinfo;
|
||||
|
||||
if ( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer || !glw_state.hDC ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//mapGammaMax();
|
||||
|
||||
for ( i = 0; i < 256; i++ ) {
|
||||
table[0][i] = ( ( ( unsigned short ) red[i] ) << 8 ) | red[i];
|
||||
table[1][i] = ( ( ( unsigned short ) green[i] ) << 8 ) | green[i];
|
||||
table[2][i] = ( ( ( unsigned short ) blue[i] ) << 8 ) | blue[i];
|
||||
}
|
||||
|
||||
// Win2K puts this odd restriction on gamma ramps...
|
||||
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
||||
GetVersionEx( &vinfo );
|
||||
if ( vinfo.dwMajorVersion == 5 && vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
|
||||
Com_DPrintf( "performing W2K gamma clamp.\n" );
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
for ( i = 0 ; i < 128 ; i++ ) {
|
||||
if ( table[j][i] > ( (128+i) << 8 ) ) {
|
||||
table[j][i] = (128+i) << 8;
|
||||
}
|
||||
}
|
||||
if ( table[j][127] > 254<<8 ) {
|
||||
table[j][127] = 254<<8;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Com_DPrintf( "skipping W2K gamma clamp.\n" );
|
||||
}
|
||||
|
||||
// enforce constantly increasing
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
for ( i = 1 ; i < 256 ; i++ ) {
|
||||
if ( table[j][i] < table[j][i-1] ) {
|
||||
table[j][i] = table[j][i-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret = SetDeviceGammaRamp( glw_state.hDC, table );
|
||||
if ( !ret ) {
|
||||
Com_Printf( "SetDeviceGammaRamp failed.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** WG_RestoreGamma
|
||||
*/
|
||||
void WG_RestoreGamma( void )
|
||||
{
|
||||
if ( glConfig.deviceSupportsGamma )
|
||||
{
|
||||
HDC hDC;
|
||||
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
SetDeviceGammaRamp( hDC, s_oldHardwareGamma );
|
||||
ReleaseDC( GetDesktopWindow(), hDC );
|
||||
}
|
||||
}
|
||||
|
||||
73
code/win32/win_gamma_console.cpp
Normal file
73
code/win32/win_gamma_console.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
** WIN_GAMMA.C
|
||||
*/
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
//#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "../game/q_shared.h"
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "win_local.h"
|
||||
|
||||
#if defined(_XBOX)
|
||||
#include "glw_win_dx8.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** WG_CheckHardwareGamma
|
||||
**
|
||||
** Determines if the underlying hardware supports the Win32 gamma correction API.
|
||||
*/
|
||||
void WG_CheckHardwareGamma( void )
|
||||
{
|
||||
glConfig.deviceSupportsGamma = qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_SetGamma
|
||||
**
|
||||
** This routine should only be called if glConfig.deviceSupportsGamma is TRUE
|
||||
*/
|
||||
void GLimp_SetGamma( float g ) {
|
||||
#if defined(_GAMECUBE)
|
||||
GXGamma gamma = GX_GM_1_0;
|
||||
if (g >= 2.2f)
|
||||
{
|
||||
gamma = GX_GM_2_2;
|
||||
}
|
||||
else if (g >= 1.7f)
|
||||
{
|
||||
gamma = GX_GM_1_7;
|
||||
}
|
||||
GXSetDispCopyGamma(gamma);
|
||||
#elif defined(_XBOX)
|
||||
const int maxval = 255;
|
||||
|
||||
D3DGAMMARAMP ramp;
|
||||
for ( int i = 0; i < 256; i++ )
|
||||
{
|
||||
int inf;
|
||||
if ( g == 1 ) {
|
||||
inf = maxval * i / 255.0f;
|
||||
} else {
|
||||
inf = maxval * pow ( i/255.0f, 1.0f / g ) + 0.5f;
|
||||
}
|
||||
if (inf < 0) {
|
||||
inf = 0;
|
||||
}
|
||||
if (inf > maxval) {
|
||||
inf = maxval;
|
||||
}
|
||||
ramp.red[i] = inf;
|
||||
ramp.green[i] = inf;
|
||||
ramp.blue[i] = inf;
|
||||
}
|
||||
glw_state->device->SetGammaRamp(D3DSGR_CALIBRATE, &ramp);
|
||||
#endif
|
||||
}
|
||||
|
||||
1815
code/win32/win_glimp.cpp
Normal file
1815
code/win32/win_glimp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
261
code/win32/win_glimp_console.cpp
Normal file
261
code/win32/win_glimp_console.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
/*
|
||||
** WIN_GLIMP.C
|
||||
**
|
||||
** This file contains ALL Win32 specific stuff having to do with the
|
||||
** OpenGL refresh. When a port is being made the following functions
|
||||
** must be implemented by the port:
|
||||
**
|
||||
** GLimp_EndFrame
|
||||
** GLimp_Init
|
||||
** GLimp_LogComment
|
||||
** GLimp_Shutdown
|
||||
**
|
||||
** Note that the GLW_xxx functions are Windows specific GL-subsystem
|
||||
** related functions that are relevant ONLY to win_glimp.c
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "win_local.h"
|
||||
|
||||
#if defined(_WINDOWS) || defined(_XBOX)
|
||||
#include "glw_win_dx8.h"
|
||||
#elif defined(_GAMECUBE)
|
||||
#include "glw_win_gc.h"
|
||||
#endif
|
||||
|
||||
|
||||
extern void WG_CheckHardwareGamma( void );
|
||||
|
||||
static void GLW_InitExtensions( void );
|
||||
static int GLW_CreateWindow( void );
|
||||
|
||||
//
|
||||
// function declaration
|
||||
//
|
||||
void QGL_EnableLogging( qboolean enable );
|
||||
qboolean QGL_Init( const char *dllname );
|
||||
void QGL_Shutdown( void );
|
||||
void GLW_Init(int width, int height, int colorbits, qboolean cdsFullscreen);
|
||||
void GLW_Shutdown(void);
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
glwstate_t *glw_state = NULL;
|
||||
|
||||
|
||||
/*
|
||||
** GLW_CreateWindow
|
||||
**
|
||||
** Responsible for creating the Alchemy window and initializing the OpenGL driver.
|
||||
*/
|
||||
static qboolean GLW_CreateWindow( int width, int height, int colorbits, qboolean cdsFullscreen )
|
||||
{
|
||||
GLW_Init(width, height, colorbits, cdsFullscreen);
|
||||
IN_Init();
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//--------------------------------------------
|
||||
static void GLW_InitTextureCompression( void )
|
||||
{
|
||||
glConfig.textureCompression = TC_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
** GLW_InitExtensions
|
||||
*/
|
||||
static void GLW_InitExtensions( void )
|
||||
{
|
||||
// Select our tc scheme
|
||||
GLW_InitTextureCompression();
|
||||
|
||||
// GL_EXT_texture_env_add
|
||||
glConfig.textureEnvAddAvailable = qfalse;
|
||||
if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) )
|
||||
{
|
||||
glConfig.textureEnvAddAvailable = qtrue;
|
||||
}
|
||||
|
||||
// GL_EXT_texture_filter_anisotropic
|
||||
glConfig.textureFilterAnisotropicAvailable = qfalse;
|
||||
if ( strstr( glConfig.extensions_string, "EXT_texture_filter_anisotropic" ) )
|
||||
{
|
||||
glConfig.textureFilterAnisotropicAvailable = qtrue;
|
||||
}
|
||||
|
||||
// GL_EXT_clamp_to_edge
|
||||
glConfig.clampToEdgeAvailable = qfalse;
|
||||
if ( strstr( glConfig.extensions_string, "GL_EXT_texture_edge_clamp" ) )
|
||||
{
|
||||
glConfig.clampToEdgeAvailable = qtrue;
|
||||
}
|
||||
|
||||
// GL_ARB_multitexture
|
||||
if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
|
||||
{
|
||||
if ( qglActiveTextureARB )
|
||||
{
|
||||
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
|
||||
|
||||
if ( glConfig.maxActiveTextures < 2 )
|
||||
{
|
||||
qglMultiTexCoord2fARB = NULL;
|
||||
qglActiveTextureARB = NULL;
|
||||
qglClientActiveTextureARB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** GLW_LoadOpenGL
|
||||
**
|
||||
** GLimp_win.c internal function that attempts to load and use
|
||||
** a specific OpenGL DLL.
|
||||
*/
|
||||
static qboolean GLW_LoadOpenGL()
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
strlwr( strcpy( buffer, OPENGL_DRIVER_NAME ) );
|
||||
|
||||
//
|
||||
// load the driver and bind our function pointers to it
|
||||
//
|
||||
if ( QGL_Init( buffer ) )
|
||||
{
|
||||
GLW_CreateWindow(640, 480, 24, 1);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
QGL_Shutdown();
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** GLimp_EndFrame
|
||||
*/
|
||||
void GLimp_EndFrame (void)
|
||||
{
|
||||
// don't flip if drawing to front buffer
|
||||
// if ( stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static void GLW_StartOpenGL( void )
|
||||
{
|
||||
//
|
||||
// load and initialize the specific OpenGL driver
|
||||
//
|
||||
if ( !GLW_LoadOpenGL() )
|
||||
{
|
||||
Com_Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_Init
|
||||
**
|
||||
** This is the platform specific OpenGL initialization function. It
|
||||
** is responsible for loading OpenGL, initializing it, setting
|
||||
** extensions, creating a window of the appropriate size, doing
|
||||
** fullscreen manipulations, etc. Its overall responsibility is
|
||||
** to make sure that a functional OpenGL subsystem is operating
|
||||
** when it returns to the ref.
|
||||
*/
|
||||
void GLimp_Init( void )
|
||||
{
|
||||
// load appropriate DLL and initialize subsystem
|
||||
GLW_StartOpenGL();
|
||||
|
||||
// get our config strings
|
||||
glConfig.vendor_string = (const char *) qglGetString (GL_VENDOR);
|
||||
glConfig.renderer_string = (const char *) qglGetString (GL_RENDERER);
|
||||
glConfig.version_string = (const char *) qglGetString (GL_VERSION);
|
||||
glConfig.extensions_string = (const char *) qglGetString (GL_EXTENSIONS);
|
||||
|
||||
if (!glConfig.vendor_string || !glConfig.renderer_string || !glConfig.version_string || !glConfig.extensions_string)
|
||||
{
|
||||
Com_Error( ERR_FATAL, "GLimp_Init() - Invalid GL Driver\n" );
|
||||
}
|
||||
|
||||
// OpenGL driver constants
|
||||
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.maxTextureSize );
|
||||
// stubbed or broken drivers may have reported 0...
|
||||
if ( glConfig.maxTextureSize <= 0 )
|
||||
{
|
||||
glConfig.maxTextureSize = 0;
|
||||
}
|
||||
|
||||
GLW_InitExtensions();
|
||||
WG_CheckHardwareGamma();
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_Shutdown
|
||||
**
|
||||
** This routine does all OS specific shutdown procedures for the OpenGL
|
||||
** subsystem.
|
||||
*/
|
||||
void GLimp_Shutdown( void )
|
||||
{
|
||||
// FIXME: Brian, we need better fallbacks from partially initialized failures
|
||||
VID_Printf( PRINT_ALL, "Shutting down OpenGL subsystem\n" );
|
||||
|
||||
// Set the gamma back to normal
|
||||
// GLimp_SetGamma(1.f);
|
||||
|
||||
// kill input system (tied to window)
|
||||
IN_Shutdown();
|
||||
|
||||
// shutdown QGL subsystem
|
||||
GLW_Shutdown();
|
||||
QGL_Shutdown();
|
||||
|
||||
memset( &glConfig, 0, sizeof( glConfig ) );
|
||||
memset( &glState, 0, sizeof( glState ) );
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_LogComment
|
||||
*/
|
||||
void GLimp_LogComment( char *comment )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================
|
||||
|
||||
SMP acceleration
|
||||
|
||||
===========================================================
|
||||
*/
|
||||
|
||||
qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void *GLimp_RendererSleep( void ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void GLimp_FrontEndSleep( void ) {
|
||||
}
|
||||
|
||||
|
||||
void GLimp_WakeRenderer( void *data ) {
|
||||
}
|
||||
673
code/win32/win_highdynamicrange.cpp
Normal file
673
code/win32/win_highdynamicrange.cpp
Normal file
@@ -0,0 +1,673 @@
|
||||
//
|
||||
//
|
||||
// Win_HighDynamicRange.cpp
|
||||
//
|
||||
// High dynamic range effect
|
||||
//
|
||||
//
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "glw_win_dx8.h"
|
||||
#include "win_local.h"
|
||||
#include "win_highdynamicrange.h"
|
||||
#include "shader_constants.h"
|
||||
|
||||
#include <xgmath.h>
|
||||
#include <xgraphics.h>
|
||||
|
||||
extern const char *Sys_RemapPath( const char *filename );
|
||||
|
||||
VVHighDynamicRange HDREffect;
|
||||
|
||||
VVHighDynamicRange::VVHighDynamicRange()
|
||||
{
|
||||
m_bInitialized = false;
|
||||
|
||||
m_dwHotBlurPixelShader = 0;
|
||||
m_dwExtractHotPixelShader = 0;
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::Initialize()
|
||||
{
|
||||
// Create pixel shader
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\hotblur.xpu"), &m_dwHotBlurPixelShader)))
|
||||
return;
|
||||
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\extracthot.xpu"), &m_dwExtractHotPixelShader)))
|
||||
return;
|
||||
|
||||
// Get size of render target
|
||||
LPDIRECT3DSURFACE8 pRenderTarget;
|
||||
glw_state->device->GetRenderTarget( &pRenderTarget );
|
||||
D3DSURFACE_DESC descRenderTarget;
|
||||
pRenderTarget->GetDesc( &descRenderTarget );
|
||||
UINT Width = descRenderTarget.Width;
|
||||
UINT Height = descRenderTarget.Height;
|
||||
D3DFORMAT Format = descRenderTarget.Format;
|
||||
pRenderTarget->Release();
|
||||
|
||||
// Create extract hot text
|
||||
glw_state->device->CreateTexture( Width >> 1, Height >> 1, 1,
|
||||
D3DUSAGE_RENDERTARGET, Format,
|
||||
0, &m_rpHotImage);
|
||||
|
||||
// Make the size a factor of 2 smaller on each axis
|
||||
glw_state->device->CreateTexture( Width >> 1, Height >> 2, 1,
|
||||
D3DUSAGE_RENDERTARGET, Format,
|
||||
0, &m_rpBlur[0]);
|
||||
|
||||
glw_state->device->CreateTexture( Width >> 2, Height >> 2, 1,
|
||||
D3DUSAGE_RENDERTARGET, Format,
|
||||
0, &m_rpBlur[1]);
|
||||
|
||||
// Set bloom scale
|
||||
m_fBloomScale = 1.00f;
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::Render()
|
||||
{
|
||||
if(!m_bInitialized)
|
||||
return;
|
||||
|
||||
DWORD lighting, fog, srcblend, destblend, alphablend, zwrite, zenable;
|
||||
|
||||
glw_state->device->GetRenderState( D3DRS_LIGHTING, &lighting );
|
||||
glw_state->device->GetRenderState( D3DRS_FOGENABLE, &fog );
|
||||
glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend );
|
||||
glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend );
|
||||
glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend );
|
||||
glw_state->device->GetRenderState( D3DRS_ZWRITEENABLE, &zwrite );
|
||||
glw_state->device->GetRenderState( D3DRS_ZENABLE, &zenable );
|
||||
|
||||
HotBlur(); // Blur the hot values in the backbuffer
|
||||
DrawHotBlur(); // Draw blurred hot values, add to scene
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, lighting );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, fog );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend );
|
||||
glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, zwrite );
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, zenable );
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::DrawHotBlur()
|
||||
{
|
||||
if( !m_pBlur )
|
||||
return;
|
||||
|
||||
LPDIRECT3DTEXTURE8 pTexture = m_pBlur;
|
||||
|
||||
// Get size of backbuffer
|
||||
LPDIRECT3DSURFACE8 pRenderTarget;
|
||||
glw_state->device->GetRenderTarget( &pRenderTarget );
|
||||
D3DSURFACE_DESC descRenderTarget;
|
||||
pRenderTarget->GetDesc( &descRenderTarget );
|
||||
UINT Width = descRenderTarget.Width;
|
||||
UINT Height = descRenderTarget.Height;
|
||||
pRenderTarget->Release();
|
||||
|
||||
// Texture coordinates in linear format textures go from 0 to n-1 rather
|
||||
// than the 0 to 1 that is used for swizzled textures.
|
||||
D3DSURFACE_DESC desc;
|
||||
pTexture->GetLevelDesc( 0, &desc );
|
||||
struct BACKGROUNDVERTEX { D3DXVECTOR4 p; FLOAT tu, tv; } v[4];
|
||||
v[0].p = D3DXVECTOR4( -0.5f, -0.5f, 1.0f, 1.0f );
|
||||
v[0].tu = 0.0f; v[0].tv = 0.0f;
|
||||
v[1].p = D3DXVECTOR4( Width - 0.5f, -0.5f, 1.0f, 1.0f );
|
||||
v[1].tu = (float)desc.Width; v[1].tv = 0.0f;
|
||||
v[2].p = D3DXVECTOR4( -0.5f, Height - 0.5f, 1.0f, 1.0f );
|
||||
v[2].tu = 0.0f; v[2].tv = (float)desc.Height;
|
||||
v[3].p = D3DXVECTOR4( Width - 0.5f, Height - 0.5f, 1.0f, 1.0f );
|
||||
v[3].tu = (float)desc.Width; v[3].tv = (float)desc.Height;
|
||||
|
||||
// Set states
|
||||
glw_state->device->SetPixelShader( 0 );
|
||||
glw_state->device->SetTexture( 0, pTexture );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE2X );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAXMIPLEVEL, 0 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
|
||||
|
||||
XGCOLOR Blend(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
Blend*= r_hdrbloom->value;//m_fBloomScale; // adjust blend amount
|
||||
glw_state->device->SetRenderState( D3DRS_TEXTUREFACTOR, Blend );
|
||||
|
||||
// add if requested
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
|
||||
glw_state->device->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
|
||||
|
||||
// Render the screen-aligned quadrilateral
|
||||
glw_state->device->SetVertexShader( D3DFVF_XYZRHW|D3DFVF_TEX1 );
|
||||
glw_state->device->DrawVerticesUP( D3DPT_QUADSTRIP, 4, v, sizeof(BACKGROUNDVERTEX) );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, TRUE );
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::FilterCopy( LPDIRECT3DTEXTURE8 pTextureDst,
|
||||
LPDIRECT3DTEXTURE8 pTextureSrc,
|
||||
UINT nSample, FilterSample rSample[],
|
||||
UINT nSuperSampleX, UINT nSuperSampleY,
|
||||
bool bCrap,
|
||||
RECT* pRectDst, RECT* pRectSrc
|
||||
)
|
||||
{
|
||||
// Texture space pixel center == screen space pixel center
|
||||
glw_state->device->SetScreenSpaceOffset( -0.5f, -0.5f );
|
||||
|
||||
// Save current render target and depth buffer
|
||||
LPDIRECT3DSURFACE8 pRenderTarget, pZBuffer;
|
||||
glw_state->device->GetRenderTarget( &pRenderTarget );
|
||||
glw_state->device->GetDepthStencilSurface( &pZBuffer );
|
||||
|
||||
// Set destination as render target
|
||||
LPDIRECT3DSURFACE8 pSurface = NULL;
|
||||
pTextureDst->GetSurfaceLevel( 0, &pSurface );
|
||||
glw_state->device->SetRenderTarget( pSurface, NULL ); // no depth-buffering
|
||||
pSurface->Release();
|
||||
|
||||
// Get descriptions of source and destination
|
||||
D3DSURFACE_DESC descSrc;
|
||||
pTextureSrc->GetLevelDesc( 0, &descSrc );
|
||||
D3DSURFACE_DESC descDst;
|
||||
pTextureDst->GetLevelDesc( 0, &descDst );
|
||||
|
||||
// Setup rectangles if not specified on input
|
||||
RECT rectSrc = { 0, 0, descSrc.Width, descSrc.Height };
|
||||
if( pRectSrc == NULL ) pRectSrc = &rectSrc;
|
||||
RECT rectDst = { 0, 0, descDst.Width, descDst.Height };
|
||||
if( pRectDst == NULL )
|
||||
{
|
||||
// If the destination rectangle is not specified,
|
||||
// we change it to match the source rectangle
|
||||
rectDst.right = (pRectSrc->right - pRectSrc->left) / nSuperSampleX;
|
||||
rectDst.bottom = (pRectSrc->bottom - pRectSrc->top) / nSuperSampleY;
|
||||
pRectDst = &rectDst;
|
||||
}
|
||||
assert( (pRectDst->right - pRectDst->left) ==
|
||||
(pRectSrc->right - pRectDst->left) / (INT)nSuperSampleX );
|
||||
assert( (pRectDst->bottom - pRectDst->top) ==
|
||||
(pRectSrc->bottom - pRectDst->top) / (INT)nSuperSampleY );
|
||||
|
||||
//Set render state for filtering
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
||||
// On first rendering, copy new value over current render target contents
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
|
||||
// Setup subsequent renderings to add to previous value
|
||||
glw_state->device->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
|
||||
|
||||
// Set texture state
|
||||
for( UINT xx = 0; xx < 4; xx++)
|
||||
{
|
||||
// Use our source texture for all four stages
|
||||
glw_state->device->SetTexture( xx, pTextureSrc);
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
|
||||
// Pass texture coords without transformation
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
||||
|
||||
// Each texture has different tex coords
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_TEXCOORDINDEX, xx );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_MAXMIPLEVEL, 0 );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_COLORKEYOP, D3DTCOLORKEYOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_COLORSIGN, 0 );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_ALPHAKILL, D3DTALPHAKILL_DISABLE );
|
||||
}
|
||||
|
||||
// Use hot blur pixel shader
|
||||
if(bCrap)
|
||||
glw_state->device->SetPixelShader( m_dwExtractHotPixelShader );
|
||||
else
|
||||
glw_state->device->SetPixelShader( m_dwHotBlurPixelShader );
|
||||
|
||||
// For screen-space texture-mapped quadrilateral
|
||||
glw_state->device->SetVertexShader( D3DFVF_XYZRHW|D3DFVF_TEX4 );
|
||||
|
||||
// Prepare quadrilateral vertices
|
||||
float x0 = (float)pRectDst->left;
|
||||
float y0 = (float)pRectDst->top;
|
||||
float x1 = (float)pRectDst->right;
|
||||
float y1 = (float)pRectDst->bottom;
|
||||
struct Quad
|
||||
{
|
||||
float x, y, z, w1;
|
||||
struct uv
|
||||
{
|
||||
float u, v;
|
||||
}
|
||||
tex[4]; // each texture has different offset
|
||||
}
|
||||
aQuad[4] =
|
||||
{ // X Y Z 1/W u0 v0 u1 v1 u2 v2 u3 v3
|
||||
{x0, y0, 1.0f, 1.0f, }, // texture coords are set below
|
||||
{x1, y0, 1.0f, 1.0f, },
|
||||
{x0, y1, 1.0f, 1.0f, },
|
||||
{x1, y1, 1.0f, 1.0f, }
|
||||
};
|
||||
|
||||
// Set rendering to just the destination rect
|
||||
glw_state->device->SetScissors( 1, FALSE, (D3DRECT *)pRectDst );
|
||||
|
||||
// Draw a quad for each block of 4 filter coefficients
|
||||
float fOffsetScaleU = (float)nSuperSampleX; // offset for supersample
|
||||
float fOffsetScaleV = (float)nSuperSampleY;
|
||||
float u0 = (float)pRectSrc->left;
|
||||
float v0 = (float)pRectSrc->top;
|
||||
float u1 = (float)pRectSrc->right;
|
||||
float v1 = (float)pRectSrc->bottom;
|
||||
|
||||
|
||||
if( XGIsSwizzledFormat( descSrc.Format ) )
|
||||
{
|
||||
float fWidthScale = 1.f / (float)descSrc.Width;
|
||||
float fHeightScale = 1.f / (float)descSrc.Height;
|
||||
fOffsetScaleU *= fWidthScale;
|
||||
fOffsetScaleV *= fHeightScale;
|
||||
u0 *= fWidthScale;
|
||||
v0 *= fHeightScale;
|
||||
u1 *= fWidthScale;
|
||||
v1 *= fHeightScale;
|
||||
}
|
||||
|
||||
xx = 0; // current texture stage
|
||||
D3DCOLOR rColor[4];
|
||||
DWORD rPSInput[4];
|
||||
for( UINT iSample = 0; iSample < nSample; iSample++ )
|
||||
{
|
||||
// Set filter coefficients
|
||||
float fValue = rSample[iSample].fValue;
|
||||
if( fValue < 0.f )
|
||||
{
|
||||
rColor[xx] = D3DXCOLOR( -fValue, -fValue, -fValue, -fValue );
|
||||
rPSInput[xx] = PS_INPUTMAPPING_SIGNED_NEGATE |
|
||||
((xx % 2) ? PS_REGISTER_C1 : PS_REGISTER_C0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rColor[xx] = D3DXCOLOR( fValue, fValue, fValue, fValue );
|
||||
rPSInput[xx] = PS_INPUTMAPPING_SIGNED_IDENTITY |
|
||||
((xx % 2) ? PS_REGISTER_C1 : PS_REGISTER_C0);
|
||||
}
|
||||
|
||||
// Align supersamples with center of destination pixels
|
||||
float fOffsetX = rSample[iSample].fOffsetX;// * fOffsetScaleU;
|
||||
float fOffsetY = rSample[iSample].fOffsetY;// * fOffsetScaleV;
|
||||
aQuad[0].tex[xx].u = u0 + fOffsetX;
|
||||
aQuad[0].tex[xx].v = v0 + fOffsetY;
|
||||
aQuad[1].tex[xx].u = u1 + fOffsetX;
|
||||
aQuad[1].tex[xx].v = v0 + fOffsetY;
|
||||
aQuad[2].tex[xx].u = u0 + fOffsetX;
|
||||
aQuad[2].tex[xx].v = v1 + fOffsetY;
|
||||
aQuad[3].tex[xx].u = u1 + fOffsetX;
|
||||
aQuad[3].tex[xx].v = v1 + fOffsetY;
|
||||
|
||||
xx++; // Go to next stage
|
||||
if( xx == 4 || iSample == nSample - 1 ) // max texture stages or last sample
|
||||
{
|
||||
// Zero out unused texture stage coefficients
|
||||
// (Only for last filter sample, when number of samples is not divisible by 4)
|
||||
for( ; xx < 4; xx++)
|
||||
{
|
||||
glw_state->device->SetTexture( xx, NULL );
|
||||
rColor[xx] = 0;
|
||||
rPSInput[xx] = PS_INPUTMAPPING_UNSIGNED_IDENTITY | PS_REGISTER_ZERO;
|
||||
}
|
||||
|
||||
// Set coefficients
|
||||
glw_state->device->SetRenderState( D3DRS_PSCONSTANT0_0, rColor[0] );
|
||||
glw_state->device->SetRenderState( D3DRS_PSCONSTANT1_0, rColor[1] );
|
||||
glw_state->device->SetRenderState( D3DRS_PSCONSTANT0_1, rColor[2] );
|
||||
glw_state->device->SetRenderState( D3DRS_PSCONSTANT1_1, rColor[3] );
|
||||
|
||||
if(bCrap)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Remap coefficients to proper sign
|
||||
glw_state->device->SetRenderState(
|
||||
D3DRS_PSRGBINPUTS0,
|
||||
PS_COMBINERINPUTS( rPSInput[0] | PS_CHANNEL_RGB,
|
||||
PS_REGISTER_T0 | PS_CHANNEL_RGB |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY,
|
||||
rPSInput[1] | PS_CHANNEL_RGB,
|
||||
PS_REGISTER_T1 | PS_CHANNEL_RGB |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY ) );
|
||||
glw_state->device->SetRenderState(
|
||||
D3DRS_PSALPHAINPUTS0,
|
||||
PS_COMBINERINPUTS( rPSInput[0] | PS_CHANNEL_ALPHA,
|
||||
PS_REGISTER_T0 | PS_CHANNEL_ALPHA |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY,
|
||||
rPSInput[1] | PS_CHANNEL_ALPHA,
|
||||
PS_REGISTER_T1 | PS_CHANNEL_ALPHA |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY ) );
|
||||
glw_state->device->SetRenderState(
|
||||
D3DRS_PSRGBINPUTS1,
|
||||
PS_COMBINERINPUTS( rPSInput[2] | PS_CHANNEL_RGB,
|
||||
PS_REGISTER_T2 | PS_CHANNEL_RGB |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY,
|
||||
rPSInput[3] | PS_CHANNEL_RGB,
|
||||
PS_REGISTER_T3 | PS_CHANNEL_RGB |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY ) );
|
||||
glw_state->device->SetRenderState(
|
||||
D3DRS_PSALPHAINPUTS1,
|
||||
PS_COMBINERINPUTS( rPSInput[2] | PS_CHANNEL_ALPHA,
|
||||
PS_REGISTER_T2 | PS_CHANNEL_ALPHA |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY,
|
||||
rPSInput[3] | PS_CHANNEL_ALPHA,
|
||||
PS_REGISTER_T3 | PS_CHANNEL_ALPHA |
|
||||
PS_INPUTMAPPING_SIGNED_IDENTITY ) );
|
||||
}
|
||||
|
||||
// Draw the quad to filter the coefficients so far
|
||||
// One quad blends 4 textures
|
||||
glw_state->device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, aQuad, sizeof(Quad) );
|
||||
|
||||
// On subsequent renderings, add to what's in the render target
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
||||
xx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear texture stages
|
||||
for( xx=0; xx<4; xx++ )
|
||||
{
|
||||
glw_state->device->SetTexture( xx, NULL );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( xx, D3DTSS_MIPMAPLODBIAS, 0 );
|
||||
}
|
||||
|
||||
// Restore render target and zbuffer
|
||||
glw_state->device->SetRenderTarget( pRenderTarget, pZBuffer );
|
||||
|
||||
if( pRenderTarget )
|
||||
pRenderTarget->Release();
|
||||
|
||||
if( pZBuffer )
|
||||
pZBuffer->Release();
|
||||
|
||||
glw_state->device->SetScreenSpaceOffset( 0.0f, 0.0f );
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::ExtractHot( LPDIRECT3DTEXTURE8 pTextureDst,
|
||||
LPDIRECT3DTEXTURE8 pTextureSrc,
|
||||
UINT nSuperSampleX, UINT nSuperSampleY,
|
||||
RECT* pRectDst, RECT* pRectSrc )
|
||||
{
|
||||
// Texture space pixel center == screen space pixel center
|
||||
glw_state->device->SetScreenSpaceOffset( -0.5f, -0.5f );
|
||||
|
||||
// Save current render target and depth buffer
|
||||
LPDIRECT3DSURFACE8 pRenderTarget, pZBuffer;
|
||||
glw_state->device->GetRenderTarget( &pRenderTarget );
|
||||
glw_state->device->GetDepthStencilSurface( &pZBuffer );
|
||||
|
||||
// Surface that has the depth-buffer as data, used as an RGBA texture:
|
||||
D3DSurface zBufferSurface;
|
||||
D3DSURFACE_DESC descZ;
|
||||
pZBuffer->GetDesc( &descZ );
|
||||
XGSetSurfaceHeader( descZ.Width, descZ.Height, D3DFMT_LIN_A8R8G8B8, &zBufferSurface, pZBuffer->Data, descZ.Width * 4 );
|
||||
|
||||
// Set destination as render target
|
||||
LPDIRECT3DSURFACE8 pSurface = NULL;
|
||||
pTextureDst->GetSurfaceLevel( 0, &pSurface );
|
||||
glw_state->device->SetRenderTarget( pSurface, NULL ); // no depth-buffering
|
||||
pSurface->Release();
|
||||
|
||||
// Get descriptions of source and destination
|
||||
D3DSURFACE_DESC descSrc;
|
||||
pTextureSrc->GetLevelDesc( 0, &descSrc );
|
||||
D3DSURFACE_DESC descDst;
|
||||
pTextureDst->GetLevelDesc( 0, &descDst );
|
||||
|
||||
// Setup rectangles if not specified on input
|
||||
RECT rectSrc = { 0, 0, descSrc.Width, descSrc.Height };
|
||||
if( pRectSrc == NULL ) pRectSrc = &rectSrc;
|
||||
RECT rectDst = { 0, 0, descDst.Width, descDst.Height };
|
||||
if( pRectDst == NULL )
|
||||
{
|
||||
// If the destination rectangle is not specified,
|
||||
// we change it to match the source rectangle
|
||||
rectDst.right = (pRectSrc->right - pRectSrc->left) / nSuperSampleX;
|
||||
rectDst.bottom = (pRectSrc->bottom - pRectSrc->top) / nSuperSampleY;
|
||||
pRectDst = &rectDst;
|
||||
}
|
||||
assert( (pRectDst->right - pRectDst->left) ==
|
||||
(pRectSrc->right - pRectDst->left) / (INT)nSuperSampleX );
|
||||
assert( (pRectDst->bottom - pRectDst->top) ==
|
||||
(pRectSrc->bottom - pRectDst->top) / (INT)nSuperSampleY );
|
||||
|
||||
//Set render state for filtering
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
|
||||
// glw_state->device->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS ); // New
|
||||
// glw_state->device->SetRenderState( D3DRS_STENCILENABLE, FALSE ); // Stencil done in PS
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
|
||||
|
||||
// Put our original back buffer in texture 0, put the old Z/Stencil in texture 1:
|
||||
glw_state->device->SetTexture( 0, pTextureSrc );
|
||||
glw_state->device->SetTexture( 1, (LPDIRECT3DTEXTURE8)&zBufferSurface );
|
||||
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
||||
|
||||
// Pass texture coords without transformation
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
||||
|
||||
// Each texture has different tex coords
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSU,
|
||||
D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSV,
|
||||
D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAXMIPLEVEL, 0 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORKEYOP,
|
||||
D3DTCOLORKEYOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORSIGN, 0 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ALPHAKILL,
|
||||
D3DTALPHAKILL_DISABLE );
|
||||
|
||||
// Z/Stencil is similar, but we don't want any filtering, just sampling:
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ADDRESSU,
|
||||
D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ADDRESSV,
|
||||
D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MAXMIPLEVEL, 0 );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_POINT );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_POINT );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_COLORKEYOP,
|
||||
D3DTCOLORKEYOP_DISABLE );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_COLORSIGN, 0 );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ALPHAKILL,
|
||||
D3DTALPHAKILL_DISABLE );
|
||||
|
||||
// Use extract hot pixel shader
|
||||
glw_state->device->SetPixelShader( m_dwExtractHotPixelShader );
|
||||
|
||||
float CutoffScale[8];
|
||||
CutoffScale[0] = CutoffScale[1] = CutoffScale[2] = CutoffScale[3] = r_hdrcutoff->value;
|
||||
CutoffScale[4] = CutoffScale[5] = CutoffScale[6] = CutoffScale[7] = r_hdrcutoff->value / (1.0f - r_hdrcutoff->value);
|
||||
glw_state->device->SetPixelShaderConstant( CP_EXTRACT_CUTOFF, CutoffScale, 2 );
|
||||
|
||||
// For screen-space texture-mapped quadrilateral
|
||||
glw_state->device->SetVertexShader( D3DFVF_XYZRHW|D3DFVF_TEX1 );
|
||||
|
||||
// Prepare quadrilateral vertices
|
||||
float x0 = (float)pRectDst->left;
|
||||
float y0 = (float)pRectDst->top;
|
||||
float x1 = (float)pRectDst->right;
|
||||
float y1 = (float)pRectDst->bottom;
|
||||
struct Quad
|
||||
{
|
||||
float x, y, z, w1;
|
||||
struct uv
|
||||
{
|
||||
float u, v;
|
||||
}
|
||||
tex;
|
||||
}
|
||||
aQuad[4] =
|
||||
{ // X Y Z 1/W u0 v0 u1 v1 u2 v2 u3 v3
|
||||
{x0, y0, 1.0f, 1.0f, }, // texture coords are set below
|
||||
{x1, y0, 1.0f, 1.0f, },
|
||||
{x0, y1, 1.0f, 1.0f, },
|
||||
{x1, y1, 1.0f, 1.0f, }
|
||||
};
|
||||
|
||||
// Set rendering to just the destination rect
|
||||
glw_state->device->SetScissors( 1, FALSE, (D3DRECT *)pRectDst );
|
||||
|
||||
|
||||
// Draw a quad for each block of 4 filter coefficients
|
||||
float u0 = (float)pRectSrc->left;
|
||||
float v0 = (float)pRectSrc->top;
|
||||
float u1 = (float)pRectSrc->right;
|
||||
float v1 = (float)pRectSrc->bottom;
|
||||
|
||||
|
||||
if( XGIsSwizzledFormat( descSrc.Format ) )
|
||||
{
|
||||
float fWidthScale = 1.f / (float)descSrc.Width;
|
||||
float fHeightScale = 1.f / (float)descSrc.Height;
|
||||
u0 *= fWidthScale;
|
||||
v0 *= fHeightScale;
|
||||
u1 *= fWidthScale;
|
||||
v1 *= fHeightScale;
|
||||
}
|
||||
|
||||
aQuad[0].tex.u = u0;
|
||||
aQuad[0].tex.v = v0;
|
||||
aQuad[1].tex.u = u1;
|
||||
aQuad[1].tex.v = v0;
|
||||
aQuad[2].tex.u = u0;
|
||||
aQuad[2].tex.v = v1;
|
||||
aQuad[3].tex.u = u1;
|
||||
aQuad[3].tex.v = v1;
|
||||
|
||||
// Draw the quad
|
||||
glw_state->device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP,
|
||||
2, aQuad, sizeof(Quad) );
|
||||
|
||||
glw_state->device->SetTexture( 0, NULL );
|
||||
glw_state->device->SetTexture( 1, NULL );
|
||||
|
||||
// Restore render target and zbuffer
|
||||
glw_state->device->SetRenderTarget( pRenderTarget, pZBuffer );
|
||||
|
||||
if( pRenderTarget )
|
||||
pRenderTarget->Release();
|
||||
|
||||
if( pZBuffer )
|
||||
pZBuffer->Release();
|
||||
|
||||
glw_state->device->SetScreenSpaceOffset( 0.0f, 0.0f );
|
||||
|
||||
// Restore ztest?
|
||||
// glw_state->device->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
|
||||
}
|
||||
|
||||
|
||||
void VVHighDynamicRange::HotBlur()
|
||||
{
|
||||
// Make D3DTexture wrapper around current render target
|
||||
LPDIRECT3DSURFACE8 pRenderTarget;
|
||||
glw_state->device->GetRenderTarget( &pRenderTarget );
|
||||
D3DSURFACE_DESC descRenderTarget;
|
||||
pRenderTarget->GetDesc( &descRenderTarget );
|
||||
D3DTexture RenderTargetTexture;
|
||||
ZeroMemory( &RenderTargetTexture, sizeof(RenderTargetTexture) );
|
||||
XGSetTextureHeader( descRenderTarget.Width, descRenderTarget.Height,
|
||||
1, 0, descRenderTarget.Format, 0,
|
||||
&RenderTargetTexture, pRenderTarget->Data,
|
||||
descRenderTarget.Width * 4 );
|
||||
pRenderTarget->Release();
|
||||
|
||||
// Filters align to blurriest point in supersamples, on the pixel centers
|
||||
// This takes advantage of the bilinear filtering in the texture map lookup.
|
||||
FilterSample YFilter[] = // 1221 4-tap filter in Y
|
||||
{
|
||||
{ 2.0f/6.f, 0.0f, 1.0f },
|
||||
{ 1.0f/6.f, 0.0f, 3.0f },
|
||||
{ 2.0f/6.f, 0.0f, -1.0f },
|
||||
{ 1.0f/6.f, 0.0f, -3.0f },
|
||||
};
|
||||
FilterSample XFilter[] = // 1221 4-tap filter in X
|
||||
{
|
||||
{ 2.0f/6.f, 1.0f, 0.0f },
|
||||
{ 1.0f/6.f, 3.0f, 0.0f },
|
||||
{ 2.0f/6.f, -1.0f, 0.0f },
|
||||
{ 1.0f/6.f, -3.0f, 0.0f },
|
||||
};
|
||||
|
||||
D3DTexture *pTextureSrc;
|
||||
D3DTexture *pTextureDst;
|
||||
|
||||
pTextureDst = &RenderTargetTexture; // source is backbuffer
|
||||
|
||||
// extract "hot" portion of hte image with downsampling
|
||||
pTextureSrc = pTextureDst;
|
||||
pTextureDst = m_rpHotImage; // destination is blur texture
|
||||
ExtractHot( pTextureDst, pTextureSrc, 2, 2 );
|
||||
// ExtractHot( pTextureDst, pTextureSrc, 1, 1 );
|
||||
|
||||
// 2 passes: Vertical gaussian (1221) followed by
|
||||
// horizontal gaussian (1221), with 2x2 downsampling
|
||||
pTextureSrc = pTextureDst; // destination is next blur texture
|
||||
pTextureDst = m_rpBlur[0]; // destination is blur texture
|
||||
FilterCopy(pTextureDst, pTextureSrc, 4, YFilter, 1, 2, false);
|
||||
|
||||
pTextureSrc = pTextureDst; // source is previous blur texture
|
||||
pTextureDst = m_rpBlur[1]; // destination is next blur texture
|
||||
FilterCopy(pTextureDst, pTextureSrc, 4, XFilter, 2, 1, false);
|
||||
|
||||
m_pBlur = pTextureDst;
|
||||
}
|
||||
77
code/win32/win_highdynamicrange.h
Normal file
77
code/win32/win_highdynamicrange.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
//
|
||||
// Win_HighDynamicRange.h
|
||||
//
|
||||
// Declaration of high dynamic range effect class
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _WIN_HIGHDYNAMICRANGE_H_
|
||||
#define _WIN_HIGHDYNAMICRANGE_H_
|
||||
|
||||
struct FilterSample
|
||||
{
|
||||
float fValue; // coefficient
|
||||
float fOffsetX, fOffsetY; // subpixel offsets of supersamples in
|
||||
// destination coordinates
|
||||
};
|
||||
|
||||
|
||||
class VVHighDynamicRange
|
||||
{
|
||||
// The blur filters are multipass and need temporary space.
|
||||
#define BLUR_COUNT 2
|
||||
D3DTexture *m_rpHotImage; // hot image
|
||||
D3DTexture *m_rpBlur[BLUR_COUNT]; // bluring textures of decreasing size
|
||||
D3DTexture *m_pBlur; // current blur texture, set by Blur()
|
||||
|
||||
// Light blend intensity scale factor
|
||||
float m_fBloomScale;
|
||||
|
||||
// Pixel shader handles
|
||||
DWORD m_dwHotBlurPixelShader; // blur the hot image
|
||||
DWORD m_dwExtractHotPixelShader; // extract hot image
|
||||
|
||||
bool m_bInitialized;
|
||||
|
||||
// Filtering routine that draws the source texture multiple
|
||||
// times, with sub-pixel offsets and filter coefficients.
|
||||
void FilterCopy( LPDIRECT3DTEXTURE9 pTextureDst,
|
||||
LPDIRECT3DTEXTURE9 pTextureSrc,
|
||||
UINT nSample,
|
||||
FilterSample rSample[],
|
||||
UINT nSuperSampleX,
|
||||
UINT nSuperSampleY,
|
||||
bool bCrap,
|
||||
RECT *pRectDst = NULL, // The destination texture is
|
||||
// written only within this
|
||||
// region.
|
||||
RECT *pRectSrc = NULL );// The source texture is read
|
||||
// outside of this region by
|
||||
// the halfwidth of the
|
||||
// filter.
|
||||
|
||||
// extract hot image with downsamping
|
||||
void ExtractHot( LPDIRECT3DTEXTURE9 pTextureDst,
|
||||
LPDIRECT3DTEXTURE9 pTextureSrc,
|
||||
UINT nSuperSampleX, UINT nSuperSampleY,
|
||||
RECT* pRectDst = NULL,
|
||||
RECT* pRectSrc = NULL );
|
||||
|
||||
// Blur hot texture and set m_pBlur. Calls FilterCopy with
|
||||
// different filter coefficients and offsets
|
||||
void HotBlur();
|
||||
|
||||
// Demonstrate the inputs to the full high dynamic range effect.
|
||||
void DrawHotBlur(); // draw blurred "hot" texture
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual void Render();
|
||||
|
||||
VVHighDynamicRange();
|
||||
};
|
||||
|
||||
extern VVHighDynamicRange HDREffect;
|
||||
|
||||
#endif
|
||||
1147
code/win32/win_input.cpp
Normal file
1147
code/win32/win_input.cpp
Normal file
File diff suppressed because it is too large
Load Diff
101
code/win32/win_input.h
Normal file
101
code/win32/win_input.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef _WIN_INPUT_H_
|
||||
#define _WIN_INPUT_H_
|
||||
|
||||
bool IN_ControllersChanged(int inserted[], int removed[]);
|
||||
|
||||
#if defined (_XBOX ) || defined (_GAMECUBE)
|
||||
#define _USE_RUMBLE
|
||||
#endif
|
||||
|
||||
bool IN_AnyButtonPressed(void);
|
||||
|
||||
void IN_enableRumble( void );
|
||||
void IN_disableRumble( void );
|
||||
bool IN_usingRumble( void );
|
||||
|
||||
int IN_CreateRumbleScript(int controller, int numStates, bool deleteWhenFinished);
|
||||
void IN_DeleteRumbleScript(int whichScript);
|
||||
void IN_KillRumbleScript(int whichScript);
|
||||
void IN_ExecuteRumbleScript(int whichScript);
|
||||
|
||||
bool IN_AdvanceToNextState(int whichScript);
|
||||
|
||||
void IN_KillRumbleScripts(int controller);
|
||||
void IN_KillRumbleScripts( void );
|
||||
|
||||
#define IN_CMD_GOTO_XTIMES -5
|
||||
#define IN_CMD_GOTO -6
|
||||
|
||||
#define IN_CMD_DEC_ARG2 -7
|
||||
#define IN_CMD_INC_ARG2 -8
|
||||
#define IN_CMD_DEC_ARG1 -9
|
||||
#define IN_CMD_INC_ARG1 -10
|
||||
|
||||
#ifdef _XBOX
|
||||
#define IN_CMD_DEC_LEFT -70
|
||||
#define IN_CMD_DEC_RIGHT -71
|
||||
#define IN_CMD_INC_LEFT -72
|
||||
#define IN_CMD_INC_RIGHT -73
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (_XBOX) // ----- XBOX --------
|
||||
|
||||
int IN_AddRumbleState(int whichScript, int leftSpeed, int rightSpeed, int timeInMs);
|
||||
int IN_AddEffectFade4(int whichScript, int startLeft, int startRight, int endLeft, int endRight, int timeInMs);
|
||||
int IN_AddEffectFadeExp6(int whichScript, int startLeft, int startRight, int endLeft, int endRight, char factor, int timeInMs);
|
||||
|
||||
#elif defined (_GAMECUBE) // ---- GAME CUBE ----
|
||||
|
||||
#define IN_GCACTION_START 1
|
||||
#define IN_GCACTION_STOP 2
|
||||
#define IN_GCACTION_STOPHARD 3
|
||||
int IN_AddRumbleState(int whichScript, int action, int timeInMs, int arg = 0);
|
||||
|
||||
#endif // ------END IF-------
|
||||
|
||||
int IN_AddRumbleStateSpecial(int whichScript, int action, int arg1, int arg2);
|
||||
void IN_KillRumbleState(int whichScript, int index);
|
||||
|
||||
void IN_PauseRumbling(int controller);
|
||||
void IN_PauseRumbling( void );
|
||||
|
||||
void IN_UnPauseRumbling(int controller);
|
||||
void IN_UnPauseRumbling( void );
|
||||
|
||||
void IN_TogglePauseRumbling(int controller);
|
||||
void IN_TogglePauseRumbling( void );
|
||||
int IN_GetMainController();
|
||||
void IN_SetMainController(int id);
|
||||
|
||||
void IN_PadUnplugged(int controller);
|
||||
void IN_PadPlugged(int controller);
|
||||
|
||||
void IN_CommonJoyPress(int controller, fakeAscii_t button, bool pressed);
|
||||
void IN_CommonUpdate(void);
|
||||
|
||||
#define IN_MAX_JOYSTICKS 2
|
||||
// Stores gamepad joystick info
|
||||
struct JoystickInfo
|
||||
{
|
||||
bool valid;
|
||||
float x, y;
|
||||
};
|
||||
|
||||
// Stores gamepad id and joysick info
|
||||
struct PadInfo
|
||||
{
|
||||
JoystickInfo joyInfo[2];
|
||||
int padId;
|
||||
};
|
||||
|
||||
// Buffer for gamepad info
|
||||
extern PadInfo _padInfo;
|
||||
|
||||
bool IN_RumbleAdjust(int controller, int left, int right);
|
||||
void IN_RumbleInit (void);
|
||||
void IN_RumbleShutdown (void);
|
||||
void IN_RumbleFrame (void);
|
||||
|
||||
|
||||
#endif // END _WIN_INPUT_H_
|
||||
900
code/win32/win_input_console.cpp
Normal file
900
code/win32/win_input_console.cpp
Normal file
@@ -0,0 +1,900 @@
|
||||
// #include "../server/exe_headers.h"
|
||||
|
||||
#include "../client/client.h"
|
||||
//JLF
|
||||
#include "../client/client_ui.h"
|
||||
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
#ifdef _JK2MP
|
||||
#include "../ui/keycodes.h"
|
||||
#else
|
||||
#include "../client/keycodes.h"
|
||||
#endif
|
||||
|
||||
#include "win_local.h"
|
||||
#include "win_input.h"
|
||||
|
||||
cvar_t *inSplashMenu = NULL;
|
||||
cvar_t *controllerOut = NULL;
|
||||
|
||||
static void HandleDebugJoystickPress(fakeAscii_t button);
|
||||
|
||||
static bool _UIRunning = false;
|
||||
|
||||
static bool IN_ControllerMustBePlugged(int controller);
|
||||
|
||||
// By default, cheatpad is turned on except in final build. Just change
|
||||
// here to modify that.
|
||||
#ifndef FINAL_BUILD
|
||||
//#define DEBUG_CONTROLLER
|
||||
#endif
|
||||
|
||||
// Controller connection globals
|
||||
static signed char uiControllerNotification = -1;
|
||||
bool noControllersConnected = false;
|
||||
bool wasPlugged[4];
|
||||
|
||||
int mainControllerDelayedUnplug = 0;
|
||||
|
||||
PadInfo _padInfo; // gamepad thumbstick buffer
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* CHEAT FUNCTIONS
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
bool Cheat_God( void )
|
||||
{
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "god\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cheat_GiveAll( void )
|
||||
{
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "give all\n");
|
||||
}
|
||||
extern bool Cheat_ChangeSaber( void ); // In wp_saber.cpp
|
||||
|
||||
#include "../game/anims.h"
|
||||
#include "../cgame/cg_local.h"
|
||||
static bool isDeathAnimation( int anim )
|
||||
{
|
||||
switch( anim )
|
||||
{
|
||||
case BOTH_DEATH1: //# First Death anim
|
||||
case BOTH_DEATH2: //# Second Death anim
|
||||
case BOTH_DEATH3: //# Third Death anim
|
||||
case BOTH_DEATH4: //# Fourth Death anim
|
||||
case BOTH_DEATH5: //# Fifth Death anim
|
||||
case BOTH_DEATH6: //# Sixth Death anim
|
||||
case BOTH_DEATH7: //# Seventh Death anim
|
||||
case BOTH_DEATH8: //#
|
||||
case BOTH_DEATH9: //#
|
||||
case BOTH_DEATH10: //#
|
||||
case BOTH_DEATH11: //#
|
||||
case BOTH_DEATH12: //#
|
||||
case BOTH_DEATH13: //#
|
||||
case BOTH_DEATH14: //#
|
||||
case BOTH_DEATH14_UNGRIP: //# Desann's end death (cin #35)
|
||||
case BOTH_DEATH14_SITUP: //# Tavion sitting up after having been thrown (cin #23)
|
||||
case BOTH_DEATH15: //#
|
||||
case BOTH_DEATH16: //#
|
||||
case BOTH_DEATH17: //#
|
||||
case BOTH_DEATH18: //#
|
||||
case BOTH_DEATH19: //#
|
||||
case BOTH_DEATH20: //#
|
||||
case BOTH_DEATH21: //#
|
||||
case BOTH_DEATH22: //#
|
||||
case BOTH_DEATH23: //#
|
||||
case BOTH_DEATH24: //#
|
||||
case BOTH_DEATH25: //#
|
||||
case BOTH_DEATHFORWARD1: //# First Death in which they get thrown forward
|
||||
case BOTH_DEATHFORWARD2: //# Second Death in which they get thrown forward
|
||||
case BOTH_DEATHFORWARD3: //# Tavion's falling in cin# 23
|
||||
case BOTH_DEATHBACKWARD1: //# First Death in which they get thrown backward
|
||||
case BOTH_DEATHBACKWARD2: //# Second Death in which they get thrown backward
|
||||
case BOTH_DEATH1IDLE: //# Idle while close to death
|
||||
case BOTH_LYINGDEATH1: //# Death to play when killed lying down
|
||||
case BOTH_STUMBLEDEATH1: //# Stumble forward and fall face first death
|
||||
case BOTH_FALLDEATH1: //# Fall forward off a high cliff and splat death - start
|
||||
case BOTH_FALLDEATH1INAIR: //# Fall forward off a high cliff and splat death - loop
|
||||
case BOTH_FALLDEATH1LAND: //# Fall forward off a high cliff and splat death - hit bottom
|
||||
case BOTH_DEAD1: //# First Death finished pose
|
||||
case BOTH_DEAD2: //# Second Death finished pose
|
||||
case BOTH_DEAD3: //# Third Death finished pose
|
||||
case BOTH_DEAD4: //# Fourth Death finished pose
|
||||
case BOTH_DEAD5: //# Fifth Death finished pose
|
||||
case BOTH_DEAD6: //# Sixth Death finished pose
|
||||
case BOTH_DEAD7: //# Seventh Death finished pose
|
||||
case BOTH_DEAD8: //#
|
||||
case BOTH_DEAD9: //#
|
||||
case BOTH_DEAD10: //#
|
||||
case BOTH_DEAD11: //#
|
||||
case BOTH_DEAD12: //#
|
||||
case BOTH_DEAD13: //#
|
||||
case BOTH_DEAD14: //#
|
||||
case BOTH_DEAD15: //#
|
||||
case BOTH_DEAD16: //#
|
||||
case BOTH_DEAD17: //#
|
||||
case BOTH_DEAD18: //#
|
||||
case BOTH_DEAD19: //#
|
||||
case BOTH_DEAD20: //#
|
||||
case BOTH_DEAD21: //#
|
||||
case BOTH_DEAD22: //#
|
||||
case BOTH_DEAD23: //#
|
||||
case BOTH_DEAD24: //#
|
||||
case BOTH_DEAD25: //#
|
||||
case BOTH_DEADFORWARD1: //# First thrown forward death finished pose
|
||||
case BOTH_DEADFORWARD2: //# Second thrown forward death finished pose
|
||||
case BOTH_DEADBACKWARD1: //# First thrown backward death finished pose
|
||||
case BOTH_DEADBACKWARD2: //# Second thrown backward death finished pose
|
||||
case BOTH_LYINGDEAD1: //# Killed lying down death finished pose
|
||||
case BOTH_STUMBLEDEAD1: //# Stumble forward death finished pose
|
||||
case BOTH_FALLDEAD1LAND: //# Fall forward and splat death finished pose
|
||||
case BOTH_DEADFLOP1: //# React to being shot from First Death finished pose
|
||||
case BOTH_DEADFLOP2: //# React to being shot from Second Death finished pose
|
||||
case BOTH_DISMEMBER_HEAD1: //#
|
||||
case BOTH_DISMEMBER_TORSO1: //#
|
||||
case BOTH_DISMEMBER_LLEG: //#
|
||||
case BOTH_DISMEMBER_RLEG: //#
|
||||
case BOTH_DISMEMBER_RARM: //#
|
||||
case BOTH_DISMEMBER_LARM: //#
|
||||
case BOTH_DEATH_ROLL: //# Death anim from a roll
|
||||
case BOTH_DEATH_FLIP: //# Death anim from a flip
|
||||
case BOTH_DEATH_SPIN_90_R: //# Death anim when facing 90 degrees right
|
||||
case BOTH_DEATH_SPIN_90_L: //# Death anim when facing 90 degrees left
|
||||
case BOTH_DEATH_SPIN_180: //# Death anim when facing backwards
|
||||
case BOTH_DEATH_LYING_UP: //# Death anim when lying on back
|
||||
case BOTH_DEATH_LYING_DN: //# Death anim when lying on front
|
||||
case BOTH_DEATH_FALLING_DN: //# Death anim when falling on face
|
||||
case BOTH_DEATH_FALLING_UP: //# Death anim when falling on back
|
||||
case BOTH_DEATH_CROUCHED: //# Death anim when crouched
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cheat_WinLevel( void )
|
||||
{
|
||||
// Do not do this while any UI is active. It's dangerous:
|
||||
extern int Key_GetCatcher( void );
|
||||
if( Key_GetCatcher() == KEYCATCH_UI )
|
||||
return false;
|
||||
|
||||
// Also, don't do it during cutscenes:
|
||||
extern bool in_camera;
|
||||
if( in_camera || ( g_entities[0].client && isDeathAnimation(g_entities[0].client->ps.legsAnim)))
|
||||
return false;
|
||||
|
||||
|
||||
// All maps (except kor2) have a trigger item named end_level
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "use end_level\n" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef XBOX_DEMO
|
||||
bool Cheat_LevelSelect( void )
|
||||
{
|
||||
// Set cvar that enables the level select menu:
|
||||
Cvar_SetValue( "ui_levelselect", 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern bool Cheat_InfiniteForce( void ); // In wp_saber.cpp
|
||||
|
||||
#if YELLOW_MODE
|
||||
extern bool enableYellowMode;
|
||||
char yellowModeLevel = 0;
|
||||
bool enableYellowStage2 = false;
|
||||
|
||||
bool Cheat_Yellow_Stage2( void )
|
||||
{
|
||||
if(!enableYellowStage2)
|
||||
return false;
|
||||
|
||||
if(IN_GetMainController() != 0)
|
||||
return false;
|
||||
|
||||
if( g_entities[0].client && isDeathAnimation(g_entities[0].client->ps.legsAnim))
|
||||
enableYellowMode = true;
|
||||
else
|
||||
enableYellowMode = false;
|
||||
|
||||
return enableYellowMode;
|
||||
}
|
||||
|
||||
bool Cheat_Yellow_Stage1( void )
|
||||
{
|
||||
if(IN_GetMainController() != 1)
|
||||
return false;
|
||||
|
||||
if(yellowModeLevel == 0) // step one, in a cutscene
|
||||
{
|
||||
extern bool in_camera;
|
||||
if(in_camera)
|
||||
{
|
||||
yellowModeLevel++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( yellowModeLevel == 1 ) // step two, during the splash screen
|
||||
{
|
||||
if(inSplashMenu->integer)
|
||||
{
|
||||
yellowModeLevel++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( yellowModeLevel == 2 ) // step three, while force hud is active
|
||||
{
|
||||
if(cg.forceHUDActive)
|
||||
{
|
||||
yellowModeLevel++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(yellowModeLevel == 3) // eveything is ok, now reset and move to stage 2
|
||||
{
|
||||
enableYellowStage2 = true;
|
||||
yellowModeLevel = 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // YELLOW_MODE
|
||||
|
||||
bool Cheat_AllForce( void )
|
||||
{
|
||||
// Do not do this while the force config UI is running. That causes SERIOUS problems:
|
||||
extern bool UI_ForceConfigUIActive( void );
|
||||
if( UI_ForceConfigUIActive() )
|
||||
return false;
|
||||
|
||||
// Set all Light powers to level 3:
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "setForceHeal 3\nsetMindTrick 3\nsetForceProtect 3\nsetForceAbsorb 3\n" );
|
||||
// Set all Dark powers to level 3:
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "setForceGrip 3\nsetForceLightning 3\nsetForceRage 3\nsetForceDrain 3\n" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat_KungFoo( void )
|
||||
{
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "iknowkungfu\n");
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
//
|
||||
// CHEAT DATA
|
||||
//
|
||||
// Every cheat is a sequence of D-pad presses, performed while the right
|
||||
// thumbstick is being pressed. The cheat sequences are all length 6, and
|
||||
// each cheat is tied to a void (void) function. Mapping:
|
||||
// 5 - Up, 7 - Down, 8 - Left, 6 - Right
|
||||
typedef bool(*xcommandC_t)(void);
|
||||
struct cheat_t
|
||||
{
|
||||
fakeAscii_t buttons[6];
|
||||
xcommandC_t function;
|
||||
};
|
||||
|
||||
cheat_t cheats[] = {
|
||||
{ {A_JOY7, A_JOY5, A_JOY8, A_JOY6, A_JOY7, A_JOY5}, Cheat_God },
|
||||
//{ {A_JOY6, A_JOY6, A_JOY8, A_JOY8, A_JOY7, A_JOY5}, Cheat_GiveAll },
|
||||
{ {A_JOY7, A_JOY8, A_JOY5, A_JOY7, A_JOY6, A_JOY5}, Cheat_ChangeSaber },
|
||||
{ {A_JOY5, A_JOY5, A_JOY7, A_JOY7, A_JOY8, A_JOY6}, Cheat_WinLevel },
|
||||
#ifndef XBOX_DEMO
|
||||
{ {A_JOY6, A_JOY8, A_JOY6, A_JOY7, A_JOY6, A_JOY5}, Cheat_LevelSelect },
|
||||
#endif
|
||||
{ {A_JOY5, A_JOY7, A_JOY5, A_JOY8, A_JOY5, A_JOY6}, Cheat_InfiniteForce },
|
||||
{ {A_JOY8, A_JOY7, A_JOY6, A_JOY5, A_JOY7, A_JOY7}, Cheat_AllForce },
|
||||
// { {A_JOY8, A_JOY7, A_JOY6, A_JOY5, A_JOY7, A_JOY8}, Cheat_KungFoo },
|
||||
#if YELLOW_MODE
|
||||
{ {A_JOY5, A_JOY7, A_JOY5, A_JOY8, A_JOY6, A_JOY5}, Cheat_Yellow_Stage1 },
|
||||
{ {A_JOY5, A_JOY6, A_JOY8, A_JOY5, A_JOY7, A_JOY7}, Cheat_Yellow_Stage2 },
|
||||
#endif // YELLOW_MODE
|
||||
};
|
||||
|
||||
const int numCheats = sizeof(cheats) / sizeof(cheats[0]);
|
||||
|
||||
bool enteringCheat = false;
|
||||
int cheatLength = 0;
|
||||
fakeAscii_t curCheat[6];
|
||||
|
||||
|
||||
//If the Xbox white or black button was held for less than this amount of
|
||||
//time while a selection bar was up, the user wants to use the button rather
|
||||
//than reassign it.
|
||||
#define MAX_WB_HOLD_TIME 500
|
||||
|
||||
static fakeAscii_t UIJoy2Key(fakeAscii_t button)
|
||||
{
|
||||
switch(button) {
|
||||
// D-Pad
|
||||
case A_JOY7:
|
||||
return A_CURSOR_DOWN;
|
||||
case A_JOY5:
|
||||
return A_CURSOR_UP;
|
||||
case A_JOY6:
|
||||
return A_CURSOR_RIGHT;
|
||||
case A_JOY8:
|
||||
return A_CURSOR_LEFT;
|
||||
|
||||
// A and B
|
||||
case A_JOY15:
|
||||
return A_MOUSE1;
|
||||
case A_JOY14:
|
||||
return A_ESCAPE;
|
||||
|
||||
// X and Y
|
||||
case A_JOY16:
|
||||
return A_DELETE;
|
||||
case A_JOY13:
|
||||
return A_BACKSPACE;
|
||||
|
||||
// L and R triggers
|
||||
case A_JOY11:
|
||||
return A_PAGE_UP;
|
||||
case A_JOY12:
|
||||
return A_PAGE_DOWN;
|
||||
|
||||
// Start and Back
|
||||
case A_JOY4:
|
||||
return A_MOUSE1;
|
||||
case A_JOY1:
|
||||
return A_ESCAPE;
|
||||
|
||||
// White and Black
|
||||
case A_JOY9:
|
||||
return A_HOME;
|
||||
case A_JOY10:
|
||||
return A_END;
|
||||
|
||||
// Left and Right thumbstick - do nothing in the UI
|
||||
case A_JOY2:
|
||||
return A_SPACE;
|
||||
case A_JOY3:
|
||||
return A_SPACE;
|
||||
}
|
||||
|
||||
return A_SPACE; //Invalid button.
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
int button;
|
||||
bool pressed;
|
||||
} uiKeyQueue[2][5] = {0};
|
||||
int uiQueueLen[2] = {0};
|
||||
int uiLastKeyUpDown[2] = {0};
|
||||
int uiLastKeyLeftRight[2] = {0};
|
||||
|
||||
void IN_UIEmptyQueue()
|
||||
{
|
||||
/// If the ui is not running then this doesn't have any effect
|
||||
if (!_UIRunning)
|
||||
{
|
||||
uiQueueLen[0] = uiQueueLen[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// BTO - No CM, bypass that logic.
|
||||
// for (int i = 0; i < ClientManager::NumClients(); i++)
|
||||
for (int i = 0; i < 1; ++i)
|
||||
{
|
||||
// ClientManager::ActivateClient(i);
|
||||
int found = 0;
|
||||
int bCancel = 0;
|
||||
for (int j = 0; j < uiQueueLen[i]; j++)
|
||||
{
|
||||
switch (uiKeyQueue[i][j].button)
|
||||
{
|
||||
case A_CURSOR_DOWN:
|
||||
case A_CURSOR_UP:
|
||||
if ( found & 2 ) // Was a left/right key pressed already?
|
||||
bCancel = 1;
|
||||
found |= 1;
|
||||
break;
|
||||
case A_CURSOR_RIGHT:
|
||||
case A_CURSOR_LEFT:
|
||||
if ( found & 1 ) // Was an up/down key already pressed?
|
||||
bCancel = 1;
|
||||
found |= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bCancel) // was it cancelled?
|
||||
{
|
||||
for (int j = 0; j < uiQueueLen[i]; j++)
|
||||
{
|
||||
int time = Sys_Milliseconds();
|
||||
switch (uiKeyQueue[i][j].button)
|
||||
{
|
||||
case A_CURSOR_DOWN:
|
||||
case A_CURSOR_UP:
|
||||
if (uiLastKeyLeftRight[i])
|
||||
{
|
||||
if (uiLastKeyLeftRight[i] > time) // don't allow up/down till left/right has enough leway time
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uiLastKeyUpDown[i] = time + 150; /// 250 ms sound right?
|
||||
break;
|
||||
case A_CURSOR_LEFT:
|
||||
case A_CURSOR_RIGHT:
|
||||
if (uiLastKeyUpDown[i])
|
||||
{
|
||||
if (uiLastKeyUpDown[i] > time) // don't allow up/down till left/right has enough leway time
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uiLastKeyLeftRight[i] = time + 150; /// 250 ms sound right?
|
||||
break;
|
||||
}
|
||||
Sys_QueEvent(0, SE_KEY, uiKeyQueue[i][j].button, uiKeyQueue[i][j].pressed, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the queue
|
||||
uiQueueLen[0] = uiQueueLen[1] = 0;
|
||||
}
|
||||
|
||||
// extern void G_DemoKeypress();
|
||||
// extern void CG_SkipCredits(void);
|
||||
char lastControllerUsed = 0;
|
||||
|
||||
void IN_CommonJoyPress(int controller, fakeAscii_t button, bool pressed)
|
||||
{
|
||||
#ifdef XBOX_DEMO
|
||||
// Reset the demo timer so that we don't auto-reboot to CDX
|
||||
extern void Demo_TimerKeypress( void );
|
||||
Demo_TimerKeypress();
|
||||
#endif
|
||||
|
||||
lastControllerUsed = controller;
|
||||
|
||||
// Cheat system hooks. The right thumbstick button has to be held for a cheat:
|
||||
if (button == A_JOY3)
|
||||
{
|
||||
if (pressed)
|
||||
{
|
||||
// Just pressed the right thumstick in. Reset cheat detector
|
||||
enteringCheat = true;
|
||||
cheatLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enteringCheat = false;
|
||||
if (cheatLength == 6)
|
||||
{
|
||||
for( int i = 0; i < numCheats; ++i)
|
||||
{
|
||||
if( memcmp( &cheats[i].buttons[0], &curCheat[0], sizeof(curCheat) ) == 0 )
|
||||
{
|
||||
if(cheats[i].function())
|
||||
S_StartLocalSound( S_RegisterSound( "sound/vehicles/x-wing/s-foil" ), CHAN_AUTO );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enteringCheat && pressed)
|
||||
{
|
||||
// Handle all other buttons while entering a cheat
|
||||
if (cheatLength == 6 || (button != A_JOY5 && button != A_JOY6 && button != A_JOY7 && button != A_JOY8))
|
||||
{
|
||||
// If we press too many buttons, or anything but the D-pad, cancel entry:
|
||||
enteringCheat = false;
|
||||
cheatLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We pressed a d-pad button, we're entering a cheat, and there's still room
|
||||
curCheat[cheatLength++] = button;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for special cases for map hack
|
||||
#ifndef FINAL_BUILD
|
||||
if (Cvar_VariableIntegerValue("cl_maphack"))
|
||||
{
|
||||
if (_UIRunning && button == A_JOY11 && pressed)
|
||||
{
|
||||
// Left trigger -> F1
|
||||
Sys_QueEvent( 0, SE_KEY, A_F1, pressed, 0, NULL );
|
||||
return;
|
||||
}
|
||||
else if (_UIRunning && button == A_JOY12 && pressed)
|
||||
{
|
||||
// Right trigger -> F2
|
||||
Sys_QueEvent( 0, SE_KEY, A_F2, pressed, 0, NULL );
|
||||
return;
|
||||
}
|
||||
else if (_UIRunning && button == A_JOY4 && pressed)
|
||||
{
|
||||
// Start button -> F3
|
||||
//IN_SetMainController(controller);
|
||||
Sys_QueEvent( 0, SE_KEY, A_F3, pressed, 0, NULL );
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(inSplashMenu->integer)
|
||||
{
|
||||
// START always works, A only works if the popup isn't shown:
|
||||
if(button == A_JOY4 || (button == A_JOY15 && controllerOut->integer < 0))
|
||||
{
|
||||
Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int controllerout = controllerOut->integer;
|
||||
if(controllerout != -1)
|
||||
{
|
||||
if(controllerout == controller && (button == A_JOY4))// || button == A_JOY15))
|
||||
Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
if(IN_GetMainController() == controller )
|
||||
{
|
||||
// Always map start button to ESCAPE
|
||||
if (!_UIRunning && button == A_JOY4 && cls.state != CA_CINEMATIC)
|
||||
Sys_QueEvent( 0, SE_KEY, A_ESCAPE, pressed, 0, NULL );
|
||||
|
||||
#ifdef DEBUG_CONTROLLER
|
||||
if (controller != 3)
|
||||
#endif
|
||||
Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CONTROLLER
|
||||
if (controller == 3 && pressed)
|
||||
{
|
||||
HandleDebugJoystickPress(button);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//JLF
|
||||
|
||||
}
|
||||
|
||||
qboolean g_noCheckAxis = qfalse;
|
||||
|
||||
/**********
|
||||
IN_CommonUpdate
|
||||
Updates thumbstick events based on _padInfo and ui_thumbStickMode
|
||||
**********/
|
||||
void IN_CommonUpdate()
|
||||
{
|
||||
extern int Key_GetCatcher( void );
|
||||
_UIRunning = Key_GetCatcher() == KEYCATCH_UI;
|
||||
|
||||
// Even in the UI, only the main controller should be able to scroll:
|
||||
if( _UIRunning && _padInfo.padId == IN_GetMainController() )
|
||||
{
|
||||
Sys_QueEvent( 0,
|
||||
SE_MOUSE,
|
||||
(_padInfo.joyInfo[0].x + _padInfo.joyInfo[1].x) * 4.0f,
|
||||
(_padInfo.joyInfo[0].y + _padInfo.joyInfo[1].y) * -4.0f,
|
||||
0,
|
||||
NULL );
|
||||
}
|
||||
else if(_padInfo.padId == IN_GetMainController())
|
||||
{
|
||||
// Find out how to configure the thumbsticks
|
||||
//int thumbStickMode = Cvar_Get("ui_thumbStickMode", "0" , 0)->integer;
|
||||
int thumbStickMode = cl_thumbStickMode->integer;
|
||||
|
||||
switch(thumbStickMode)
|
||||
{
|
||||
case 0:
|
||||
// Configure left thumbstick to move forward/back & strafe left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[0].x * 127.0f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[0].y * 127.0f, 0, NULL );
|
||||
|
||||
// Configure right thumbstick for freelook
|
||||
Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[1].x * 48.0f, _padInfo.joyInfo[1].y * 48.0f, 0, NULL );
|
||||
break;
|
||||
case 1:
|
||||
// Configure left thumbstick for freelook
|
||||
Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[0].x * 48.0f, _padInfo.joyInfo[0].y * 48.0f, 0, NULL );
|
||||
|
||||
// Configure right thumbstick to move forward/back & strafe left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[1].x * 127.0f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[1].y * 127.0f, 0, NULL );
|
||||
break;
|
||||
case 2:
|
||||
// Configure left thumbstick to move forward/back & turn left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[0].y * 127.0f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[0].x * 48.0f, 0.0f, 0, NULL );
|
||||
|
||||
// Configure right thumbstick to look up/down & strafe left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[1].x * 127.f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_MOUSE, 0.0f, _padInfo.joyInfo[1].y * 48.0f, 0, NULL );
|
||||
break;
|
||||
case 3:
|
||||
// Configure left thumbstick to look up/down & strafe left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[0].x * 127.f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_MOUSE, 0.0f, _padInfo.joyInfo[0].y * 48.0f, 0, NULL );
|
||||
|
||||
// Configure right thumbstick to move forward/back & turn left/right
|
||||
Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[1].y * 127.0f, 0, NULL );
|
||||
Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[1].x * 48.0f, 0.0f, 0, NULL );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void startsetMainController(int controller)
|
||||
{
|
||||
|
||||
IN_SetMainController(controller);
|
||||
if ( !wasPlugged[controller])
|
||||
{
|
||||
mainControllerDelayedUnplug = 1 << controller;
|
||||
}
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_DisplayControllerUnplugged
|
||||
*********/
|
||||
|
||||
static void IN_DisplayControllerUnplugged(int controller)
|
||||
{
|
||||
uiControllerNotification = controller;
|
||||
|
||||
bool noControllersConnected = !wasPlugged[0] &&
|
||||
!wasPlugged[1] &&
|
||||
!wasPlugged[2] &&
|
||||
!wasPlugged[3];
|
||||
|
||||
if ( !( cls.keyCatchers & KEYCATCH_UI ) )
|
||||
{
|
||||
if ( cls.state == CA_ACTIVE )
|
||||
{
|
||||
if (controller == IN_GetMainController())
|
||||
{
|
||||
Cvar_SetValue("ControllerOutNum", controller);
|
||||
UI_SetActiveMenu( "ingame","noController" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else // UI
|
||||
{
|
||||
if(inSplashMenu->integer && noControllersConnected)
|
||||
{
|
||||
Cvar_SetValue("ControllerOutNum", 4);
|
||||
UI_SetActiveMenu("ui_popup", "noController");
|
||||
}
|
||||
else if( controller == IN_GetMainController())
|
||||
{
|
||||
Cvar_SetValue("ControllerOutNum", controller);
|
||||
UI_SetActiveMenu("ui_popup", "noController");
|
||||
}
|
||||
}
|
||||
// END JLF
|
||||
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_ClearControllerUnplugged
|
||||
*********/
|
||||
static void IN_ClearControllerUnplugged(void)
|
||||
{
|
||||
uiControllerNotification = -1;
|
||||
|
||||
//TODO Add a call to the UI that removes the controller disconnected
|
||||
// message from the screen.
|
||||
// VM_Call( uivm, UI_CONTROLLER_UNPLUGGED, false, 0);
|
||||
}
|
||||
|
||||
qboolean CurrentStateIsInteractive()
|
||||
{
|
||||
if (cls.state == CA_UNINITIALIZED ||
|
||||
cls.state ==CA_CONNECTING||
|
||||
cls.state ==CA_CONNECTED||
|
||||
cls.state ==CA_CHALLENGING||
|
||||
cls.state ==CA_PRIMED||
|
||||
cls.state ==CA_CINEMATIC ||
|
||||
!SG_GameAllowedToSaveHere(qtrue))
|
||||
return qfalse;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
// Magic flag used to avoid popping up the "no controllers" dialog if
|
||||
// none were present when we booted (but not from MP)
|
||||
bool hadAController = false;
|
||||
|
||||
/*********
|
||||
IN_ControllerMustBePlugged
|
||||
*********/
|
||||
static bool IN_ControllerMustBePlugged(int controller)
|
||||
{
|
||||
if( cls.state == CA_LOADING ||
|
||||
cls.state == CA_CONNECTING ||
|
||||
cls.state == CA_CONNECTED ||
|
||||
cls.state == CA_CHALLENGING ||
|
||||
cls.state == CA_PRIMED ||
|
||||
cls.state == CA_CINEMATIC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're at the splash screen, have no controllers anymore, and there
|
||||
// was a controller ever inserted into the machine:
|
||||
extern bool Sys_QuickStart();
|
||||
if( inSplashMenu->integer &&
|
||||
!wasPlugged[0] && !wasPlugged[1] &&
|
||||
!wasPlugged[2] && !wasPlugged[3] &&
|
||||
hadAController )
|
||||
return true;
|
||||
|
||||
// If we're at the splash screen, and anything else above is false
|
||||
// (we have another controller, or there's never been a controller):
|
||||
if( inSplashMenu->integer )
|
||||
return false;
|
||||
|
||||
// OK. In all other cases, we need the main controller:
|
||||
return (controller == IN_GetMainController());
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
IN_PadUnplugged
|
||||
*********/
|
||||
void IN_PadUnplugged(int controller)
|
||||
{
|
||||
if(wasPlugged[controller])
|
||||
{
|
||||
Com_Printf("\tController %d unplugged\n",controller);
|
||||
}
|
||||
//JLF moved
|
||||
wasPlugged[controller] = false;
|
||||
|
||||
//IN_CheckForNoControllers();
|
||||
|
||||
if(IN_ControllerMustBePlugged(controller)&& SG_GameAllowedToSaveHere(qtrue))
|
||||
{
|
||||
//If UI isn't busy, inform it about controller loss.
|
||||
if(uiControllerNotification == -1 && Cvar_VariableIntegerValue("ControllerOutNum")<0)
|
||||
{
|
||||
IN_DisplayControllerUnplugged(controller);
|
||||
mainControllerDelayedUnplug &= ~( 1<< controller);
|
||||
}
|
||||
// else
|
||||
// mainControllerDelayedUnplug = 1 << controller;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( controller == IN_GetMainController())
|
||||
{
|
||||
//store somehow for checking again later
|
||||
mainControllerDelayedUnplug = 1 << controller;
|
||||
}
|
||||
}
|
||||
// wasPlugged[controller] = false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_PadPlugged
|
||||
*********/
|
||||
void IN_PadPlugged(int controller)
|
||||
{
|
||||
if(!wasPlugged[controller])
|
||||
{
|
||||
Com_Printf("\tController %d plugged\n",controller);
|
||||
}
|
||||
|
||||
if(IN_ControllerMustBePlugged(controller)&& SG_GameAllowedToSaveHere(qtrue))
|
||||
{
|
||||
//If UI is dealing with this controller, tell it to stop.
|
||||
if(uiControllerNotification == controller || (_UIRunning && cls.state != CA_ACTIVE ))
|
||||
{
|
||||
IN_ClearControllerUnplugged();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (controller == IN_GetMainController())
|
||||
{
|
||||
//store somehow for checking again later
|
||||
mainControllerDelayedUnplug &= ~(1 << controller);
|
||||
}
|
||||
}
|
||||
|
||||
wasPlugged[controller] = true;
|
||||
noControllersConnected = false;
|
||||
hadAController = true;
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_GetMainController
|
||||
*********/
|
||||
int IN_GetMainController(void)
|
||||
{
|
||||
return cls.mainGamepad;
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_SetMainController
|
||||
*********/
|
||||
void IN_SetMainController(int id)
|
||||
{
|
||||
cls.mainGamepad = id;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
* DEBUGGING CODE
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
#ifdef DEBUG_CONTROLLER
|
||||
static void HandleDebugJoystickPress(fakeAscii_t button)
|
||||
{
|
||||
switch(button) {
|
||||
case A_JOY13: // Right pad up (yellow)
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "give all\n");
|
||||
break;
|
||||
case A_JOY16: // Right pad left (blue)
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "viewpos\n");
|
||||
break;
|
||||
case A_JOY14: // Right pad right (red)
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "noclip\n");
|
||||
break;
|
||||
case A_JOY15: // Right pad down (green)
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "god\n");
|
||||
break;
|
||||
case A_JOY4: // Start
|
||||
break;
|
||||
case A_JOY1: // back
|
||||
break;
|
||||
case A_JOY2: // Left thumbstick
|
||||
extern void Z_CompactStats(void);
|
||||
Z_CompactStats();
|
||||
break;
|
||||
case A_JOY12: // Upper right trigger
|
||||
break;
|
||||
case A_JOY8: // Left pad left
|
||||
break;
|
||||
case A_JOY6: // Left pad right
|
||||
break;
|
||||
case A_JOY5: // Left pad up
|
||||
break;
|
||||
case A_JOY7: // Left pad down
|
||||
break;
|
||||
case A_JOY11: // Upper left trigger
|
||||
break;
|
||||
case A_JOY9: // White button
|
||||
break;
|
||||
case A_JOY10: // Black button
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
686
code/win32/win_input_rumble.cpp
Normal file
686
code/win32/win_input_rumble.cpp
Normal file
@@ -0,0 +1,686 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
#include "../cgame/cg_local.h"
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "win_local.h"
|
||||
#include "win_input.h"
|
||||
|
||||
|
||||
//MB #include "../client/cl_data.h"
|
||||
#include "../game/q_shared.h"
|
||||
|
||||
extern qboolean G_ActivePlayerNormal(void);
|
||||
static int rumble_timer = 0;
|
||||
|
||||
cvar_t* in_shaking_rumble; // 1 - shaking rumble on, 0 - shaking rumble off
|
||||
|
||||
struct rumblestate_t
|
||||
{
|
||||
int timeToStop;
|
||||
|
||||
// Right motor speed on Xbox, action type on Gamecube
|
||||
int arg1;
|
||||
|
||||
// Left motor speed on Xbox, secondary action type on Gamecube
|
||||
int arg2;
|
||||
};
|
||||
|
||||
struct rumblestate_special_t
|
||||
{
|
||||
int code;
|
||||
int arg1;
|
||||
int arg2;
|
||||
};
|
||||
|
||||
struct rumblescript_t
|
||||
{
|
||||
int nextStateAt;
|
||||
|
||||
int controller;
|
||||
|
||||
int currentState;
|
||||
int usedStates;
|
||||
int numStates;
|
||||
|
||||
bool autoDelete;
|
||||
rumblestate_t *states;
|
||||
};
|
||||
|
||||
struct rumblestatus_t
|
||||
{
|
||||
bool changed;
|
||||
bool killed;
|
||||
bool paused;
|
||||
int timePaused;
|
||||
};
|
||||
|
||||
#define MAX_RUMBLE_STATES 10
|
||||
#define MAX_RUMBLE_SCRIPTS 10
|
||||
#define MAX_RUMBLE_CONTROLLERS 4
|
||||
|
||||
// In rumblestate, highest speed for each side takes precidence
|
||||
// Number of rumble states is fairly small, so a plain array will work fine
|
||||
static rumblestatus_t rumbleStatus[MAX_RUMBLE_CONTROLLERS];
|
||||
static rumblescript_t rumbleScripts[MAX_RUMBLE_SCRIPTS];
|
||||
|
||||
cvar_t* in_useRumble = NULL;
|
||||
|
||||
bool IN_usingRumble( void )
|
||||
{
|
||||
return in_useRumble->integer;
|
||||
}
|
||||
|
||||
|
||||
// Creates a rumble script with numStates
|
||||
// Returns -1 on no more room, otherwise an identifier to use for scripts
|
||||
int IN_CreateRumbleScript(int controller, int numStates, bool deleteWhenFinished)
|
||||
{
|
||||
if (!IN_usingRumble()) return -1;
|
||||
|
||||
if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return -1;
|
||||
assert (numStates > 0 && numStates < MAX_RUMBLE_STATES);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
{
|
||||
if (rumbleScripts[i].states == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_RUMBLE_SCRIPTS)
|
||||
return -1; // Ran out of scripts
|
||||
|
||||
|
||||
rumbleScripts[i].autoDelete = deleteWhenFinished;
|
||||
rumbleScripts[i].controller = controller;
|
||||
rumbleScripts[i].currentState = 0;
|
||||
rumbleScripts[i].nextStateAt = 0;
|
||||
rumbleScripts[i].numStates = numStates;
|
||||
rumbleScripts[i].usedStates = 0;
|
||||
rumbleScripts[i].states = new rumblestate_t[numStates];
|
||||
memset(rumbleScripts[i].states, 0, sizeof(rumblestate_t) * numStates);
|
||||
return i;
|
||||
}
|
||||
|
||||
// A negative time will last until you kill it explicitly
|
||||
// Returns index, used to kill or change a state in a script
|
||||
int IN_AddRumbleStateFull(int whichScript, int arg1, int arg2, int timeInMs)
|
||||
{
|
||||
if (!IN_usingRumble()) return -1;
|
||||
|
||||
assert(whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
assert(rumbleScripts[whichScript].usedStates < rumbleScripts[whichScript].numStates);
|
||||
|
||||
// Get the current state
|
||||
rumblescript_t *curScript = &rumbleScripts[whichScript];
|
||||
rumblestate_t *curState = &curScript->states[curScript->usedStates];
|
||||
|
||||
curState->arg1 = arg1;
|
||||
curState->arg2 = arg2;
|
||||
|
||||
curState->timeToStop = timeInMs;
|
||||
return curScript->usedStates++;
|
||||
}
|
||||
|
||||
int IN_AddRumbleState(int whichScript, int leftSpeed, int rightSpeed, int timeInMs)
|
||||
{
|
||||
return IN_AddRumbleStateFull(whichScript, leftSpeed, rightSpeed, timeInMs);
|
||||
}
|
||||
|
||||
int IN_AddRumbleStateSpecial(int whichScript, int action, int arg1, int arg2)
|
||||
{
|
||||
if (!IN_usingRumble()) return -1;
|
||||
|
||||
assert(whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
assert(rumbleScripts[whichScript].usedStates < rumbleScripts[whichScript].numStates);
|
||||
|
||||
// Get the current state
|
||||
rumblescript_t *curScript = &rumbleScripts[whichScript];
|
||||
rumblestate_special_t *curState = (rumblestate_special_t*)&curScript->states[curScript->usedStates];
|
||||
|
||||
curState->code = action;
|
||||
curState->arg1 = arg1;
|
||||
curState->arg2 = arg2;
|
||||
return curScript->usedStates++;
|
||||
}
|
||||
|
||||
int IN_AddEffectFade4(int whichScript, int startLeft, int startRight,
|
||||
int endLeft, int endRight, int timeInMs)
|
||||
{
|
||||
const int fadeSmoothness = 50; // number of ms between updates, smaller is smoother
|
||||
|
||||
int e = IN_AddRumbleState(whichScript, startLeft, startRight, fadeSmoothness); // Lasts for fadeSmoothness ms
|
||||
|
||||
if (startLeft < endLeft) // Fade increases
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_LEFT, e,
|
||||
(endLeft - startLeft) * fadeSmoothness / timeInMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_DEC_LEFT, e,
|
||||
(startLeft - endLeft) * fadeSmoothness / timeInMs);
|
||||
}
|
||||
|
||||
if (startRight < endRight)
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_RIGHT, e,
|
||||
(endRight - startRight) * fadeSmoothness / timeInMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_DEC_RIGHT, e,
|
||||
(startRight - endRight) * fadeSmoothness / timeInMs);
|
||||
}
|
||||
|
||||
return IN_AddRumbleStateSpecial(whichScript, IN_CMD_GOTO_XTIMES,
|
||||
e, timeInMs / fadeSmoothness);
|
||||
}
|
||||
|
||||
int IN_AddEffectFadeExp6(int whichScript, int startLeft, int startRight,
|
||||
int endLeft, int endRight, char factor, int timeInMs)
|
||||
{
|
||||
const int fadeSmoothness = 10; // number of ms between updates, smaller is smoother
|
||||
|
||||
int state = IN_AddRumbleState(whichScript, startLeft, startRight, fadeSmoothness); // Lasts for fadeSmoothness ms
|
||||
|
||||
if (startLeft < endLeft) // Fade increases
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_LEFT, state,
|
||||
(endLeft - startLeft) * fadeSmoothness / timeInMs -
|
||||
(factor / 2) * ( 1 - timeInMs / fadeSmoothness)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_DEC_LEFT, state,
|
||||
(startLeft - endLeft) * fadeSmoothness / timeInMs -
|
||||
(factor / 2) * ( 1 - timeInMs / fadeSmoothness)
|
||||
);
|
||||
}
|
||||
|
||||
if (startRight < endRight)
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_RIGHT, state,
|
||||
(endRight - startRight) * fadeSmoothness / timeInMs -
|
||||
(factor / 2) * ( 1 - timeInMs / fadeSmoothness)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_DEC_RIGHT, state,
|
||||
(startRight - endRight) * fadeSmoothness / timeInMs -
|
||||
(factor / 2) * ( 1 - timeInMs / fadeSmoothness)
|
||||
);
|
||||
}
|
||||
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_ARG2, state + 1, factor);
|
||||
IN_AddRumbleStateSpecial(whichScript, IN_CMD_INC_ARG2, state + 2, factor);
|
||||
return IN_AddRumbleStateSpecial(whichScript, IN_CMD_GOTO_XTIMES,
|
||||
state, timeInMs / fadeSmoothness);
|
||||
}
|
||||
|
||||
// Kills a rumble state based on index
|
||||
void IN_KillRumbleState(int whichScript, int index)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
|
||||
assert( whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
assert( index < rumbleScripts[whichScript].numStates );
|
||||
|
||||
rumbleScripts[whichScript].states[index].timeToStop = 0;
|
||||
rumbleStatus[rumbleScripts[whichScript].controller].changed = true;
|
||||
}
|
||||
|
||||
// Stops the script, if script has autodelete on then it will get deleted, otherwise it will only stop
|
||||
void IN_KillRumbleScript(int whichScript)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
|
||||
assert (whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
|
||||
rumbleScripts[whichScript].nextStateAt = 0;
|
||||
if (rumbleScripts[whichScript].autoDelete)
|
||||
{
|
||||
if (rumbleScripts[whichScript].states)
|
||||
delete [] rumbleScripts[whichScript].states;
|
||||
rumbleScripts[whichScript].states = 0;
|
||||
}
|
||||
|
||||
rumbleStatus[rumbleScripts[whichScript].controller].changed = true;
|
||||
}
|
||||
|
||||
// Stops Rumbling for specific controller
|
||||
void IN_KillRumbleScripts(int controller)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return;
|
||||
if (rumbleStatus[controller].killed == true) return;
|
||||
|
||||
for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
{
|
||||
if (rumbleScripts[i].controller == controller)
|
||||
IN_KillRumbleScript(i);
|
||||
}
|
||||
|
||||
rumbleStatus[controller].killed = IN_RumbleAdjust(controller, 0, 0);
|
||||
}
|
||||
|
||||
// Stops Rumbling on all controllers
|
||||
void IN_KillRumbleScripts( void )
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
|
||||
for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
IN_KillRumbleScript(i);
|
||||
|
||||
for (int j = 0; j < MAX_RUMBLE_CONTROLLERS; j++)
|
||||
{
|
||||
if (!rumbleStatus[j].killed)
|
||||
{
|
||||
rumbleStatus[j].killed = IN_RumbleAdjust(j, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IN_DeleteRumbleScript(int whichScript)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
|
||||
assert (whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
|
||||
if (rumbleScripts[whichScript].states)
|
||||
delete [] rumbleScripts[whichScript].states;
|
||||
rumbleScripts[whichScript].nextStateAt = 0;
|
||||
rumbleScripts[whichScript].states = 0;
|
||||
|
||||
rumbleStatus[rumbleScripts[whichScript].controller].changed = true;
|
||||
}
|
||||
|
||||
int IN_RunSpecialScript(int whichScript)
|
||||
{
|
||||
rumblestate_special_t *sp = (rumblestate_special_t*)&rumbleScripts[whichScript].states[rumbleScripts[whichScript].currentState];
|
||||
switch (sp->code)
|
||||
{
|
||||
// updates the current state pointer
|
||||
// uses arg1
|
||||
case IN_CMD_GOTO:
|
||||
rumbleScripts[whichScript].currentState = sp->arg1;
|
||||
return rumbleScripts[whichScript].states[sp->arg1].timeToStop;
|
||||
break;
|
||||
// does a goto, and decreases count of arg2, until 0
|
||||
case IN_CMD_GOTO_XTIMES:
|
||||
if (--sp->arg2 >= 0)
|
||||
{
|
||||
rumbleScripts[whichScript].currentState = sp->arg1;
|
||||
return rumbleScripts[whichScript].states[sp->arg1].timeToStop;
|
||||
}
|
||||
else // Go onto next cmd
|
||||
{
|
||||
if (!IN_AdvanceToNextState(whichScript))
|
||||
return -2; // Done
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
// Decreasae Arg2 of a State, sp->arg1 = state, sp->arg2 = amount to decrease arg2 of state by
|
||||
case IN_CMD_DEC_ARG2:
|
||||
{
|
||||
rumblestate_special_t *temp = (rumblestate_special_t*)&rumbleScripts[whichScript].states[sp->arg1];
|
||||
temp->arg2 -= sp->arg2;
|
||||
}
|
||||
break;
|
||||
|
||||
// Increase Arg2 of a State, sp->arg1 = state, sp->arg2 = amount to increase arg2 of state by
|
||||
case IN_CMD_INC_ARG2:
|
||||
{
|
||||
rumblestate_special_t *temp = (rumblestate_special_t*)&rumbleScripts[whichScript].states[sp->arg1];
|
||||
temp->arg2 += sp->arg2;
|
||||
}
|
||||
break;
|
||||
|
||||
// Decreasae Arg1 of a State, sp->arg1 = state, sp->arg2 = amount to decrease arg1 of state by
|
||||
case IN_CMD_DEC_ARG1:
|
||||
{
|
||||
rumblestate_special_t *temp = (rumblestate_special_t*)&rumbleScripts[whichScript].states[sp->arg1];
|
||||
temp->arg1 -= sp->arg2;
|
||||
}
|
||||
break;
|
||||
|
||||
// Increase Arg2 of a State, sp->arg1 = state, sp->arg2 = amount to increase arg1 of state by
|
||||
case IN_CMD_INC_ARG1:
|
||||
{
|
||||
rumblestate_special_t *temp = (rumblestate_special_t*)&rumbleScripts[whichScript].states[sp->arg1];
|
||||
temp->arg1 += sp->arg2;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_CMD_DEC_LEFT:
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg2 -= sp->arg2;
|
||||
if (rumbleScripts[whichScript].states[sp->arg1].arg2 < 0)
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg2 = 0;
|
||||
if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
|
||||
return -2; // Done
|
||||
return rumbleScripts[whichScript].states[++rumbleScripts[whichScript].currentState].timeToStop;
|
||||
break;
|
||||
|
||||
case IN_CMD_DEC_RIGHT:
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg1 -= sp->arg2;
|
||||
if (rumbleScripts[whichScript].states[sp->arg1].arg1 < 0)
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg1 = 0;
|
||||
if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
|
||||
return -2; // Done
|
||||
return rumbleScripts[whichScript].states[++rumbleScripts[whichScript].currentState].timeToStop;
|
||||
break;
|
||||
|
||||
case IN_CMD_INC_LEFT:
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg2 += sp->arg2;
|
||||
if (rumbleScripts[whichScript].states[sp->arg1].arg2 > 65534)
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg2 = 65534;
|
||||
if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
|
||||
return -2; // Done
|
||||
return rumbleScripts[whichScript].states[++rumbleScripts[whichScript].currentState].timeToStop;
|
||||
break;
|
||||
|
||||
case IN_CMD_INC_RIGHT:
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg1 += sp->arg2;
|
||||
if (rumbleScripts[whichScript].states[sp->arg1].arg1 > 65534)
|
||||
rumbleScripts[whichScript].states[sp->arg1].arg1 = 65534;
|
||||
if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
|
||||
return -2; // Done
|
||||
return rumbleScripts[whichScript].states[++rumbleScripts[whichScript].currentState].timeToStop;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IN_Time()
|
||||
{
|
||||
//mb return ClientManager::ActiveClient().cg.time;
|
||||
return cg.time;
|
||||
}
|
||||
|
||||
int testTime;
|
||||
|
||||
void IN_ExecuteRumbleScript(int whichScript)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
|
||||
assert (whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS);
|
||||
|
||||
// Can't execute an empty script???
|
||||
assert (rumbleScripts[whichScript].usedStates > 0);
|
||||
|
||||
rumbleScripts[whichScript].currentState = 0;
|
||||
int cmd = rumbleScripts[whichScript].states[rumbleScripts[whichScript].currentState].timeToStop;
|
||||
if (cmd < 0)
|
||||
{
|
||||
cmd = IN_RunSpecialScript(whichScript);
|
||||
}
|
||||
|
||||
rumbleScripts[whichScript].nextStateAt = -1;//IN_Time() + cmd;
|
||||
|
||||
rumbleStatus[rumbleScripts[whichScript].controller].changed = true;
|
||||
rumbleStatus[rumbleScripts[whichScript].controller].killed = false;
|
||||
|
||||
testTime = IN_Time();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void IN_PauseRumbling(int controller)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return;
|
||||
if (rumbleStatus[controller].paused == true) return;
|
||||
|
||||
rumbleStatus[controller].timePaused = IN_Time();
|
||||
rumbleStatus[controller].paused = IN_RumbleAdjust(controller, 0, 0);
|
||||
IN_KillRumbleScripts();
|
||||
}
|
||||
|
||||
void IN_UnPauseRumbling(int controller)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return;
|
||||
|
||||
// can't unpause a control that wasn't paused
|
||||
if (rumbleStatus[controller].paused == false) return;
|
||||
|
||||
int cur_time = IN_Time();
|
||||
for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
{
|
||||
if (rumbleScripts[i].controller == controller)
|
||||
{
|
||||
if (rumbleScripts[i].nextStateAt == 0) continue;
|
||||
// update the time to stop based on how long it was paused
|
||||
rumbleScripts[i].nextStateAt += (cur_time - rumbleStatus[controller].timePaused);
|
||||
}
|
||||
}
|
||||
|
||||
rumbleStatus[controller].paused = false;
|
||||
rumbleStatus[controller].changed = true;
|
||||
rumbleStatus[controller].killed = false;
|
||||
|
||||
IN_KillRumbleScripts();
|
||||
}
|
||||
|
||||
void IN_TogglePauseRumbling(int controller)
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
if (controller <= -1 || controller >= MAX_RUMBLE_CONTROLLERS) return;
|
||||
if (rumbleStatus[controller].paused)
|
||||
IN_UnPauseRumbling(controller);
|
||||
else
|
||||
IN_PauseRumbling(controller);
|
||||
}
|
||||
|
||||
// Pauses rumbling on all controllers
|
||||
void IN_PauseRumbling( void )
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
for (int i = 0; i < MAX_RUMBLE_CONTROLLERS; i++)
|
||||
IN_PauseRumbling(i);
|
||||
}
|
||||
|
||||
// UnPauses rumbling on all controllers
|
||||
void IN_UnPauseRumbling( void )
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
for (int i = 0; i < MAX_RUMBLE_CONTROLLERS; i++)
|
||||
IN_UnPauseRumbling(i);
|
||||
}
|
||||
|
||||
// Toggles Pausing on all controllers
|
||||
void IN_TogglePauseRumbling( void )
|
||||
{
|
||||
if (!IN_usingRumble()) return;
|
||||
for (int i = 0; i < MAX_RUMBLE_CONTROLLERS; i++)
|
||||
IN_TogglePauseRumbling(i);
|
||||
}
|
||||
|
||||
// Returns false when the end of the script is reached
|
||||
bool IN_AdvanceToNextState(int whichScript)
|
||||
{
|
||||
assert( whichScript >= 0 && whichScript < MAX_RUMBLE_SCRIPTS );
|
||||
|
||||
if (rumbleScripts[whichScript].currentState >= rumbleScripts[whichScript].usedStates - 1)
|
||||
{
|
||||
// Script is at its end, so kill it( which deletes only if autodelete
|
||||
IN_KillRumbleScript(whichScript);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance a state
|
||||
rumbleScripts[whichScript].currentState++;
|
||||
|
||||
int cmd = rumbleScripts[whichScript].states[rumbleScripts[whichScript].currentState].timeToStop;
|
||||
while (cmd < 0)
|
||||
{
|
||||
cmd = IN_RunSpecialScript(whichScript);
|
||||
if (cmd == -1) return true;
|
||||
if (cmd == -2) return false;
|
||||
}
|
||||
|
||||
rumbleScripts[whichScript].nextStateAt = IN_Time() + cmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Max rumble takes precidence
|
||||
// Other possibility is some kind of sum of all the speeds
|
||||
// Call this once a frame, to update the controller based on the rumble states
|
||||
extern qboolean _UI_IsFullscreen( void );
|
||||
void IN_UpdateRumbleFromStates()
|
||||
{
|
||||
if(_UI_IsFullscreen())
|
||||
{
|
||||
IN_KillRumbleScripts();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int i;
|
||||
int value[MAX_RUMBLE_CONTROLLERS][2];
|
||||
int cur_time = IN_Time();
|
||||
bool canKillScripts = false;
|
||||
|
||||
memset(value, 0, sizeof(int)*MAX_RUMBLE_CONTROLLERS*2);
|
||||
for (i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
{
|
||||
// If rumble is paused on current controller than skip this rumble state
|
||||
if ( rumbleStatus[rumbleScripts[i].controller].paused) continue;
|
||||
|
||||
//*mb ClientManager::ActivateByControllerId(rumbleScripts[i].controller);
|
||||
if ( !IN_usingRumble() )
|
||||
{
|
||||
IN_KillRumbleScript(i);
|
||||
continue;
|
||||
}
|
||||
/*mb
|
||||
if (!ClientManager::ActiveGentity() || !G_ActivePlayerNormal())
|
||||
{
|
||||
IN_KillRumbleScript(i);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
// Unset state so skip
|
||||
if ( rumbleScripts[i].nextStateAt == 0) continue;
|
||||
|
||||
canKillScripts = true;
|
||||
|
||||
if ( rumbleScripts[i].nextStateAt == -1)
|
||||
{
|
||||
int cmd = rumbleScripts[i].states[rumbleScripts[i].currentState].timeToStop;
|
||||
rumbleScripts[i].nextStateAt = cur_time + cmd;
|
||||
}
|
||||
|
||||
// Time is up on this rumble state
|
||||
if ( rumbleScripts[i].nextStateAt < cur_time)
|
||||
{
|
||||
// If timeToStop is < cur_time and > 0 then end this state otherwise (negative number) always rumble
|
||||
if (rumbleScripts[i].nextStateAt > 0)
|
||||
{
|
||||
rumbleStatus[rumbleScripts[i].controller].changed = true;
|
||||
rumbleStatus[rumbleScripts[i].controller].killed = false;
|
||||
if (!IN_AdvanceToNextState(i)) // Returns false if reached the end of script
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rumblescript_t *curScript = &rumbleScripts[i];
|
||||
|
||||
if (value[curScript->controller][0] < curScript->states[curScript->currentState].arg2)
|
||||
value[curScript->controller][0] = curScript->states[curScript->currentState].arg2;
|
||||
if (value[curScript->controller][1] < curScript->states[curScript->currentState].arg1)
|
||||
value[curScript->controller][1] = curScript->states[curScript->currentState].arg1;
|
||||
}
|
||||
|
||||
// Go through the 4 controller ports
|
||||
for (i = 0; i < MAX_RUMBLE_CONTROLLERS; i++)
|
||||
{
|
||||
// paused, so do nothing for this controller
|
||||
if ( rumbleStatus[i].paused) continue;
|
||||
|
||||
// Only update the actual hardware if a state has changed
|
||||
if (!rumbleStatus[i].changed) continue;
|
||||
|
||||
IN_RumbleAdjust(i, value[i][0], value[i][1]);
|
||||
|
||||
// State has changed
|
||||
rumbleStatus[i].changed = false;
|
||||
}
|
||||
|
||||
if(canKillScripts)
|
||||
{
|
||||
if( (cur_time - rumble_timer) > 5000 )
|
||||
IN_KillRumbleScripts();
|
||||
}
|
||||
else
|
||||
{
|
||||
rumble_timer = cur_time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
IN_RumbleInit
|
||||
==================
|
||||
*/
|
||||
void IN_RumbleInit (void) {
|
||||
memset(&rumbleStatus, 0, sizeof(rumblestatus_t)*MAX_RUMBLE_CONTROLLERS);
|
||||
memset(&rumbleScripts, 0, sizeof(rumblescript_t)*MAX_RUMBLE_SCRIPTS);
|
||||
|
||||
in_useRumble = Cvar_Get( "in_useRumble", "1", 0 );
|
||||
in_shaking_rumble = Cvar_Get("in_shaking_rumble", "1", 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
IN_RumbleShutdown
|
||||
==================
|
||||
*/
|
||||
void IN_RumbleShutdown (void) {
|
||||
for (int i = 0; i < MAX_RUMBLE_SCRIPTS; i++)
|
||||
{
|
||||
if (rumbleScripts[i].states)
|
||||
delete [] rumbleScripts[i].states;
|
||||
rumbleScripts[i].states = 0;
|
||||
rumbleScripts[i].nextStateAt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
IN_RumbleFrame
|
||||
==================
|
||||
*/
|
||||
void IN_RumbleFrame (void)
|
||||
{
|
||||
// Check to see if we need to pause rumbling
|
||||
if(cl_paused->integer && !rumbleStatus[IN_GetMainController()].paused)
|
||||
{
|
||||
IN_PauseRumbling(IN_GetMainController());
|
||||
}
|
||||
else if(!cl_paused->integer && rumbleStatus[IN_GetMainController()].paused)
|
||||
{
|
||||
IN_UnPauseRumbling(IN_GetMainController());
|
||||
}
|
||||
|
||||
// Update the states
|
||||
IN_UpdateRumbleFromStates();
|
||||
}
|
||||
339
code/win32/win_input_xbox.cpp
Normal file
339
code/win32/win_input_xbox.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
// win_input.c -- win32 mouse and joystick code
|
||||
// 02/21/97 JCB Added extended DirectInput code to support external controllers.
|
||||
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
// #include "../server/exe_headers.h"
|
||||
|
||||
#include <xtl.h>
|
||||
#include "glw_win_dx8.h"
|
||||
|
||||
#include "../client/client.h"
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
#ifdef _JK2MP
|
||||
#include "../ui/keycodes.h"
|
||||
#else
|
||||
#include "../client/keycodes.h"
|
||||
#endif
|
||||
|
||||
#include "win_local.h"
|
||||
#include "win_input.h"
|
||||
|
||||
#define IN_MAX_CONTROLLERS 4
|
||||
|
||||
void IN_UIEmptyQueue();
|
||||
void IN_CheckForNoControllers();
|
||||
|
||||
struct inputstate_t
|
||||
{
|
||||
struct controller_t
|
||||
{
|
||||
HANDLE handle;
|
||||
XINPUT_STATE state;
|
||||
XINPUT_FEEDBACK feedback;
|
||||
};
|
||||
controller_t controllers[IN_MAX_CONTROLLERS];
|
||||
};
|
||||
|
||||
inputstate_t *in_state = NULL;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=========================================================================
|
||||
|
||||
JOYSTICK
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
//JLF moved here for multiple access (then not used multiple times. oh well.)
|
||||
extern bool noControllersConnected;
|
||||
// Process all the insertions and removals, updating handles and such
|
||||
void IN_ProcessChanges(DWORD dwInsert, DWORD dwRemove)
|
||||
{
|
||||
for(int port = 0; port < IN_MAX_CONTROLLERS; ++port)
|
||||
{
|
||||
// Close removals.
|
||||
if((1 << port) & dwRemove)
|
||||
{
|
||||
if ( in_state->controllers[port].handle )
|
||||
{
|
||||
XInputClose( in_state->controllers[port].handle );
|
||||
in_state->controllers[port].handle = 0;
|
||||
}
|
||||
IN_PadUnplugged(port);
|
||||
|
||||
}
|
||||
|
||||
// Open insertions.
|
||||
if( (1 << port) & dwInsert )
|
||||
{
|
||||
in_state->controllers[port].handle = XInputOpen( XDEVICE_TYPE_GAMEPAD, port, XDEVICE_NO_SLOT, NULL );
|
||||
IN_PadPlugged(port);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*********
|
||||
IN_CheckForNoControllers()
|
||||
If there are no controllers plugged in, the UI
|
||||
is notified so it can display an appropriate
|
||||
message.
|
||||
*********/
|
||||
void IN_CheckForNoControllers()
|
||||
{
|
||||
extern bool noControllersConnected;
|
||||
if(!noControllersConnected)
|
||||
{
|
||||
extern bool wasPlugged[4];
|
||||
if( !wasPlugged[0] &&
|
||||
!wasPlugged[1] &&
|
||||
!wasPlugged[2] &&
|
||||
!wasPlugged[3] )
|
||||
{
|
||||
// Tell the UI that there are no controllers connected
|
||||
// VM_Call( uivm, UI_CONTROLLER_UNPLUGGED, true, -1);
|
||||
noControllersConnected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================================
|
||||
|
||||
RUMBLE SUPPORT
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
|
||||
bool IN_RumbleAdjust(int controller, int left, int right)
|
||||
{
|
||||
assert(controller >= 0 && controller < IN_MAX_CONTROLLERS);
|
||||
|
||||
// Get a device handle for the controller. This may fail.
|
||||
HANDLE handle = in_state->controllers[controller].handle;
|
||||
|
||||
if (!handle) return false;
|
||||
|
||||
XINPUT_FEEDBACK* fb = &in_state->controllers[controller].feedback;
|
||||
|
||||
// If a prior rumble update is still pending, go away
|
||||
if (fb->Header.dwStatus == ERROR_IO_PENDING) return false;
|
||||
|
||||
fb->Rumble.wLeftMotorSpeed = left;
|
||||
fb->Rumble.wRightMotorSpeed = right;
|
||||
|
||||
return ERROR_IO_PENDING == XInputSetState(handle, fb);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=========================================================================
|
||||
|
||||
=========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
igBool IN_WindowClose(igWindow *window)
|
||||
{
|
||||
SV_Shutdown ("Server quit\n");
|
||||
CL_Shutdown ();
|
||||
Com_Shutdown ();
|
||||
Sys_Quit ();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Shutdown
|
||||
===========
|
||||
*/
|
||||
void IN_Shutdown( void ) {
|
||||
IN_RumbleShutdown();
|
||||
|
||||
delete in_state;
|
||||
in_state = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Init
|
||||
===========
|
||||
*/
|
||||
void IN_Init( void )
|
||||
{
|
||||
in_state = new inputstate_t;
|
||||
|
||||
// Initialize support for 4 gamepads
|
||||
XDEVICE_PREALLOC_TYPE xdpt[] = {
|
||||
{XDEVICE_TYPE_GAMEPAD, 4}
|
||||
};
|
||||
|
||||
// Initialize the peripherals. We can only ever
|
||||
// call XInitDevices once, no matter what.
|
||||
static bool bInputInitialized = false;
|
||||
if (!bInputInitialized)
|
||||
XInitDevices( sizeof(xdpt) / sizeof(XDEVICE_PREALLOC_TYPE), xdpt );
|
||||
bInputInitialized = true;
|
||||
|
||||
// Zero all of our data, including handles
|
||||
memset(in_state->controllers, 0, sizeof(in_state->controllers));
|
||||
|
||||
// Find out the status of all gamepad ports, then open them
|
||||
IN_ProcessChanges( XGetDevices( XDEVICE_TYPE_GAMEPAD ), 0 );
|
||||
|
||||
IN_RumbleInit();
|
||||
}
|
||||
|
||||
static inline float _joyAxisConvert(SHORT x)
|
||||
{
|
||||
// Change scale
|
||||
float y = x / 32767.0;
|
||||
|
||||
// Cheesy deadzone
|
||||
if(fabs(y) < 0.25f)
|
||||
{
|
||||
y = 0.0f;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
// How many controls on the xbox gamepad?
|
||||
#define IN_NUM_DIGITAL_BUTTONS 8
|
||||
#define IN_NUM_ANALOG_BUTTONS 8
|
||||
// Cutoff where the analog buttons are considered to be "pressed"
|
||||
// This should be smarter.
|
||||
#define IN_ANALOG_BUTTON_THRESHOLD 64
|
||||
|
||||
void IN_UpdateGamepad(int port)
|
||||
{
|
||||
// Lookup table to convert the digital buttons to fakeAscii_t, in mask order
|
||||
const fakeAscii_t digitalXlat[IN_NUM_DIGITAL_BUTTONS] = {
|
||||
A_JOY5, // DPAD_UP
|
||||
A_JOY7, // DPAD_DOWN
|
||||
A_JOY8, // DPAD_LEFT
|
||||
A_JOY6, // DPAD_RIGHT
|
||||
A_JOY4, // Start
|
||||
A_JOY1, // Back
|
||||
A_JOY2, // Left stick
|
||||
A_JOY3 // Right stick
|
||||
};
|
||||
|
||||
// Lookup table to convet the analog buttons to fakeAscii_t, in DX order
|
||||
const fakeAscii_t analogXlat[IN_NUM_ANALOG_BUTTONS] = {
|
||||
A_JOY15, // A
|
||||
A_JOY14, // B
|
||||
A_JOY16, // X
|
||||
A_JOY13, // Y
|
||||
A_JOY10, // Black
|
||||
A_JOY9, // White
|
||||
A_JOY11, // Left trigger
|
||||
A_JOY12 // Right trigger
|
||||
};
|
||||
|
||||
// Get new state
|
||||
XINPUT_STATE newState;
|
||||
XInputGetState( in_state->controllers[port].handle, &newState );
|
||||
|
||||
// Get old state
|
||||
XINPUT_STATE &oldState(in_state->controllers[port].state);
|
||||
|
||||
int buttonIdx;
|
||||
bool oldPressed, newPressed;
|
||||
|
||||
// Check all digital buttons first
|
||||
for (buttonIdx = 0; buttonIdx < IN_NUM_DIGITAL_BUTTONS; ++buttonIdx)
|
||||
{
|
||||
oldPressed = oldState.Gamepad.wButtons & (1 << buttonIdx);
|
||||
newPressed = newState.Gamepad.wButtons & (1 << buttonIdx);
|
||||
|
||||
if (oldPressed != newPressed)
|
||||
IN_CommonJoyPress(port, digitalXlat[buttonIdx], newPressed);
|
||||
}
|
||||
|
||||
// Now check all analog buttons
|
||||
for (buttonIdx = 0; buttonIdx < IN_NUM_ANALOG_BUTTONS; ++buttonIdx)
|
||||
{
|
||||
oldPressed = oldState.Gamepad.bAnalogButtons[buttonIdx] > IN_ANALOG_BUTTON_THRESHOLD;
|
||||
newPressed = newState.Gamepad.bAnalogButtons[buttonIdx] > IN_ANALOG_BUTTON_THRESHOLD;
|
||||
|
||||
if (oldPressed != newPressed)
|
||||
IN_CommonJoyPress(port, analogXlat[buttonIdx], newPressed);
|
||||
}
|
||||
|
||||
// Update joysticks
|
||||
_padInfo.joyInfo[0].x = _joyAxisConvert(newState.Gamepad.sThumbLX);
|
||||
_padInfo.joyInfo[0].y = _joyAxisConvert(newState.Gamepad.sThumbLY);
|
||||
_padInfo.joyInfo[1].x = _joyAxisConvert(newState.Gamepad.sThumbRX);
|
||||
_padInfo.joyInfo[1].y = _joyAxisConvert(newState.Gamepad.sThumbRY);
|
||||
_padInfo.joyInfo[0].valid = _padInfo.joyInfo[1].valid = true;
|
||||
_padInfo.padId = port;
|
||||
|
||||
// Copy state back
|
||||
oldState = newState;
|
||||
|
||||
// Update game
|
||||
IN_CommonUpdate();
|
||||
}
|
||||
|
||||
extern qboolean CurrentStateIsInteractive();
|
||||
extern int mainControllerDelayedUnplug;
|
||||
|
||||
extern void startsetMainController(int controller);
|
||||
extern int gLaunchController;
|
||||
/*
|
||||
==================
|
||||
IN_Frame
|
||||
|
||||
Called every frame, even if not generating commands
|
||||
==================
|
||||
*/
|
||||
//extern int ignoreInputTime;
|
||||
extern vmCvar_t ControllerOutNum;
|
||||
void IN_Frame (void)
|
||||
{
|
||||
static qboolean first = qtrue;
|
||||
if (in_state)
|
||||
{
|
||||
// First, check for changes in device status (removed/inserted pads)
|
||||
DWORD dwInsert, dwRemove;
|
||||
if( XGetDeviceChanges( XDEVICE_TYPE_GAMEPAD, &dwInsert, &dwRemove ) )
|
||||
{
|
||||
IN_ProcessChanges(dwInsert, dwRemove);
|
||||
}
|
||||
|
||||
if ( first )
|
||||
{
|
||||
// We only force the controller to be locked when we came from MP:
|
||||
extern bool Sys_QuickStart( void );
|
||||
if( Sys_QuickStart() )
|
||||
{
|
||||
Com_Printf("\tController %d initialized\n", gLaunchController);
|
||||
startsetMainController(gLaunchController);
|
||||
|
||||
// We're bypassing splash menu!
|
||||
Cvar_SetValue( "inSplashMenu", 0 );
|
||||
}
|
||||
|
||||
// Only do this check once, no matter what:
|
||||
first = qfalse;
|
||||
}
|
||||
|
||||
if ( mainControllerDelayedUnplug && CurrentStateIsInteractive() && ControllerOutNum.integer < 0)
|
||||
IN_ProcessChanges(0, mainControllerDelayedUnplug);
|
||||
|
||||
// Generate callbacks for each controller that's plugged in
|
||||
for (int port = 0; port < IN_MAX_CONTROLLERS; ++port)
|
||||
if (in_state->controllers[port].handle)
|
||||
IN_UpdateGamepad(port);
|
||||
|
||||
IN_UIEmptyQueue();
|
||||
IN_RumbleFrame();
|
||||
}
|
||||
}
|
||||
977
code/win32/win_lighteffects.cpp
Normal file
977
code/win32/win_lighteffects.cpp
Normal file
@@ -0,0 +1,977 @@
|
||||
//
|
||||
//
|
||||
// win_lighteffects.cpp
|
||||
//
|
||||
// Various lighting effects w/ pixel shaders
|
||||
//
|
||||
//
|
||||
|
||||
#ifdef VV_LIGHTING
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "glw_win_dx8.h"
|
||||
#include "win_local.h"
|
||||
#include "../renderer/tr_lightmanager.h"
|
||||
|
||||
#include "win_lighteffects.h"
|
||||
|
||||
#include <xgraphics.h>
|
||||
#include <xgmath.h>
|
||||
|
||||
#include "shader_constants.h"
|
||||
|
||||
|
||||
LightEffects::LightEffects()
|
||||
{
|
||||
m_pCubeMap = NULL;
|
||||
m_pBumpMap = NULL;
|
||||
m_pSpecularMap = NULL;
|
||||
m_pFalloffMap = NULL;
|
||||
m_dwVertexShaderLight = 0L;
|
||||
m_dwPixelShaderLight = 0L;
|
||||
m_dwVertexShaderSpecular_Dynamic = 0L;
|
||||
m_dwPixelShaderSpecular_Dynamic = 0L;
|
||||
m_dwVertexShaderSpecular_Static = 0L;
|
||||
m_dwPixelShaderSpecular_Static = 0L;
|
||||
m_dwVertexShaderEnvironment = 0L;
|
||||
m_dwVertexShaderBump = 0L;
|
||||
m_dwPixelShaderBump = 0L;
|
||||
m_bInLightPhase = false;
|
||||
m_bInitialized = false;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
LightEffects::~LightEffects()
|
||||
{
|
||||
if( m_pCubeMap )
|
||||
m_pCubeMap->Release();
|
||||
m_pCubeMap = NULL;
|
||||
|
||||
if(m_pBumpMap)
|
||||
m_pBumpMap->Release();
|
||||
m_pBumpMap = NULL;
|
||||
|
||||
if(m_pFalloffMap)
|
||||
m_pFalloffMap->Release();
|
||||
m_pFalloffMap = NULL;
|
||||
|
||||
if(m_pSpecularMap)
|
||||
m_pSpecularMap->Release();
|
||||
m_pSpecularMap = NULL;
|
||||
|
||||
if( glw_state->device )
|
||||
{
|
||||
glw_state->device->DeleteVertexShader( m_dwVertexShaderLight );
|
||||
glw_state->device->DeletePixelShader( m_dwPixelShaderLight );
|
||||
glw_state->device->DeleteVertexShader( m_dwVertexShaderSpecular_Dynamic );
|
||||
glw_state->device->DeletePixelShader( m_dwPixelShaderSpecular_Dynamic );
|
||||
glw_state->device->DeleteVertexShader( m_dwVertexShaderSpecular_Static );
|
||||
glw_state->device->DeletePixelShader( m_dwPixelShaderSpecular_Static );
|
||||
glw_state->device->DeleteVertexShader( m_dwVertexShaderEnvironment );
|
||||
glw_state->device->DeletePixelShader( m_dwPixelShaderBump );
|
||||
glw_state->device->DeleteVertexShader( m_dwVertexShaderBump );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LightEffects::StartLightPhase()
|
||||
{
|
||||
m_bInLightPhase = true;
|
||||
}
|
||||
|
||||
|
||||
void LightEffects::EndLightPhase()
|
||||
{
|
||||
m_bInLightPhase = false;
|
||||
}
|
||||
|
||||
extern const char *Sys_RemapPath( const char *filename );
|
||||
|
||||
bool LightEffects::Initialize()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// Create a vertex shader
|
||||
DWORD dwVertexDecl[] =
|
||||
{
|
||||
D3DVSD_STREAM( 0 ),
|
||||
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // v0 = Position
|
||||
D3DVSD_REG( 1, D3DVSDT_FLOAT3 ), // v1 = Normal
|
||||
D3DVSD_REG( 2, D3DVSDT_FLOAT2 ), // v2 = Base tex coords
|
||||
D3DVSD_REG( 3, D3DVSDT_FLOAT3 ), // v3 = Tangent space tangent
|
||||
D3DVSD_END()
|
||||
};
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\dlight.xvu"), dwVertexDecl, &m_dwVertexShaderLight)))
|
||||
return false;
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\specular_dynamic.xvu"), dwVertexDecl, &m_dwVertexShaderSpecular_Dynamic)))
|
||||
return false;
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\specular_static.xvu"), dwVertexDecl, &m_dwVertexShaderSpecular_Static)))
|
||||
return false;
|
||||
|
||||
DWORD dwVertexDeclBump[] =
|
||||
{
|
||||
D3DVSD_STREAM( 0 ),
|
||||
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // v0 = Position
|
||||
D3DVSD_REG( 1, D3DVSDT_FLOAT3 ), // v1 = Normal
|
||||
D3DVSD_REG( 2, D3DVSDT_FLOAT2 ), // v2 = Base tex coords 0
|
||||
D3DVSD_REG( 3, D3DVSDT_FLOAT2 ), // v2 = Base tex coords 1
|
||||
D3DVSD_REG( 4, D3DVSDT_FLOAT3 ), // v4 = Tangent space tangent
|
||||
D3DVSD_END()
|
||||
};
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\bump.xvu"), dwVertexDeclBump, &m_dwVertexShaderBump)))
|
||||
return false;
|
||||
|
||||
DWORD dwVertexDeclEnv[] =
|
||||
{
|
||||
D3DVSD_STREAM( 0 ),
|
||||
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // v0 = Position
|
||||
D3DVSD_REG( 1, D3DVSDT_FLOAT3 ), // v1 = Normal
|
||||
D3DVSD_REG( 2, D3DVSDT_D3DCOLOR ), // v2 = Color
|
||||
D3DVSD_END()
|
||||
};
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\environment.xvu"), dwVertexDeclEnv, &m_dwVertexShaderEnvironment)))
|
||||
return false;
|
||||
|
||||
// Create the pixel shader
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\dlight.xpu"), &m_dwPixelShaderLight)))
|
||||
return false;
|
||||
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\specular_dynamic.xpu"), &m_dwPixelShaderSpecular_Dynamic)))
|
||||
return false;
|
||||
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\specular_static.xpu"), &m_dwPixelShaderSpecular_Static)))
|
||||
return false;
|
||||
|
||||
if(!(CreatePixelShader(Sys_RemapPath("base\\media\\bump.xpu"), &m_dwPixelShaderBump)))
|
||||
return false;
|
||||
|
||||
hr = D3DXCreateTextureFromFileEx(glw_state->device,
|
||||
Sys_RemapPath("base\\media\\defaultbump.dds"),
|
||||
D3DX_DEFAULT,
|
||||
D3DX_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
D3DFMT_A8R8G8B8,
|
||||
0,
|
||||
D3DX_FILTER_LINEAR,
|
||||
D3DX_FILTER_LINEAR,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&m_pBumpMap);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = D3DXCreateTextureFromFileEx(glw_state->device,
|
||||
Sys_RemapPath("base\\media\\diffspec.dds"),
|
||||
D3DX_DEFAULT,
|
||||
D3DX_DEFAULT,
|
||||
0,
|
||||
0,
|
||||
D3DFMT_A8R8G8B8,
|
||||
0,
|
||||
D3DX_FILTER_LINEAR,
|
||||
D3DX_FILTER_LINEAR,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&m_pSpecularMap);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the volume falloff texture
|
||||
UINT width = 32,
|
||||
height = 32,
|
||||
depth = 32,
|
||||
levels = 1;
|
||||
D3DFORMAT format = D3DFMT_A8;
|
||||
if (FAILED (hr = glw_state->device->CreateVolumeTexture(width, height, depth,
|
||||
1, 0, format, D3DPOOL_DEFAULT, &m_pFalloffMap) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill the volume texture
|
||||
D3DVOLUME_DESC desc;
|
||||
D3DLOCKED_BOX lock;
|
||||
m_pFalloffMap->GetLevelDesc( 0, &desc );
|
||||
m_pFalloffMap->LockBox( 0, &lock, 0, 0L );
|
||||
BYTE* pBits = (BYTE*)lock.pBits;
|
||||
|
||||
for( UINT w=0; w<width; w++ )
|
||||
{
|
||||
for( UINT v=0; v<height; v++ )
|
||||
{
|
||||
for( UINT u=0; u<depth; u++ )
|
||||
{
|
||||
FLOAT x = (2.0f*u)/(width-1) - 1.0f; // Ranges from -1 to +1
|
||||
FLOAT y = (2.0f*v)/(height-1) - 1.0f; // Ranges from -1 to +1
|
||||
FLOAT z = (2.0f*w)/(depth-1) - 1.0f;
|
||||
|
||||
FLOAT distance = (float)(x*x + y*y + z*z);
|
||||
if (distance == 0)
|
||||
{
|
||||
*pBits++ = (BYTE)255;
|
||||
}
|
||||
else
|
||||
{
|
||||
FLOAT falloff = min(1.0f, max(0.0f, ((1.0f/2.0f)/distance - 1.0f/2.0f)/1.0f ) );
|
||||
*pBits++ = (BYTE)(255*falloff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwPixelSize = XGBytesPerPixelFromFormat( desc.Format );
|
||||
DWORD dwTextureSize = desc.Width * desc.Height * desc.Depth * dwPixelSize;
|
||||
|
||||
BYTE* pSrcBits = new BYTE[ dwTextureSize ];
|
||||
memcpy( pSrcBits, lock.pBits, dwTextureSize );
|
||||
|
||||
XGSwizzleBox( pSrcBits, 0, 0, NULL, lock.pBits,
|
||||
desc.Width, desc.Height, desc.Depth,
|
||||
NULL, dwPixelSize );
|
||||
|
||||
delete [] pSrcBits;
|
||||
|
||||
m_pFalloffMap->UnlockBox( 0 );
|
||||
|
||||
// Create the normalization cube map
|
||||
if(!CreateNormalizationCubeMap( 64, &m_pCubeMap ))
|
||||
return false;
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LightEffects::RenderDynamicLights()
|
||||
{
|
||||
VVdlight_t *dl;
|
||||
shaderStage_t *dStage;
|
||||
vec3_t origin;
|
||||
byte clipBits[SHADER_MAX_VERTEXES];
|
||||
glIndex_t hitIndexes[SHADER_MAX_INDEXES];
|
||||
int numIndexes;
|
||||
float radius;
|
||||
int fogging;
|
||||
vec3_t dist;
|
||||
vec3_t e1;
|
||||
vec3_t e2;
|
||||
vec3_t normal;
|
||||
float fac;
|
||||
|
||||
if(!VVLightMan.num_dlights)
|
||||
return true;
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
|
||||
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
|
||||
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_MIPFILTER, D3DTEXF_POINT );
|
||||
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ALPHAKILL, D3DTALPHAKILL_ENABLE);
|
||||
|
||||
// GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
|
||||
if(tess.shader->isBumpMap)
|
||||
{
|
||||
for ( int stage = 0; stage < tess.shader->numUnfoggedPasses; stage++ )
|
||||
{
|
||||
shaderStage_t *pStage = &tess.xstages[stage];
|
||||
if(pStage->isBumpMap)
|
||||
{
|
||||
glwstate_t::texturexlat_t::iterator i = glw_state->textureXlat.find(pStage->bundle[1].image->texnum);
|
||||
glw_state->device->SetTexture( 1, i->second.mipmap );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
glw_state->device->SetTexture(1, m_pBumpMap);
|
||||
|
||||
glw_state->device->SetTexture(2, m_pFalloffMap);
|
||||
glw_state->device->SetTexture(3, m_pCubeMap);
|
||||
|
||||
glw_state->device->SetPixelShader(m_dwPixelShaderLight);
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderLight);
|
||||
|
||||
for(int l = 0; l < VVLightMan.num_dlights; l++)
|
||||
{
|
||||
if(!(tess.dlightBits & (1 << l)))
|
||||
continue;
|
||||
|
||||
dl = &VVLightMan.dlights[l];
|
||||
if(!dl)
|
||||
continue;
|
||||
|
||||
// Not going to bother testing all the polygons in a ghoul2 model
|
||||
// they almost always all end up in range anyway
|
||||
if(!backEnd.currentEntity->e.ghoul2)
|
||||
{
|
||||
VectorCopy( dl->transformed, origin );
|
||||
radius = dl->radius;
|
||||
|
||||
int clipall = 63;
|
||||
for (int i = 0 ; i < tess.numVertexes ; i++)
|
||||
{
|
||||
int clip;
|
||||
VectorSubtract( origin, tess.xyz[i], dist );
|
||||
|
||||
clip = 0;
|
||||
if ( dist[0] < -radius )
|
||||
{
|
||||
clip |= 1;
|
||||
}
|
||||
else if ( dist[0] > radius )
|
||||
{
|
||||
clip |= 2;
|
||||
}
|
||||
if ( dist[1] < -radius )
|
||||
{
|
||||
clip |= 4;
|
||||
}
|
||||
else if ( dist[1] > radius )
|
||||
{
|
||||
clip |= 8;
|
||||
}
|
||||
if ( dist[2] < -radius )
|
||||
{
|
||||
clip |= 16;
|
||||
}
|
||||
else if ( dist[2] > radius )
|
||||
{
|
||||
clip |= 32;
|
||||
}
|
||||
|
||||
clipBits[i] = clip;
|
||||
clipall &= clip;
|
||||
}
|
||||
if ( clipall )
|
||||
{
|
||||
continue; // this surface doesn't have any of this light
|
||||
}
|
||||
|
||||
// build a list of triangles that need light
|
||||
numIndexes = 0;
|
||||
for ( i = 0 ; i < tess.numIndexes ; i += 3 )
|
||||
{
|
||||
int a, b, c;
|
||||
|
||||
a = tess.indexes[i];
|
||||
b = tess.indexes[i+1];
|
||||
c = tess.indexes[i+2];
|
||||
if ( clipBits[a] & clipBits[b] & clipBits[c] )
|
||||
{
|
||||
continue; // not lighted
|
||||
}
|
||||
|
||||
VectorSubtract( tess.xyz[a], tess.xyz[b], e1);
|
||||
VectorSubtract( tess.xyz[c], tess.xyz[b], e2);
|
||||
CrossProduct(e1,e2,normal);
|
||||
|
||||
VectorNormalize(normal);
|
||||
fac=DotProduct(normal,origin)-DotProduct(normal, tess.xyz[a]);
|
||||
if (fac >= radius) // out of range
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// save the indexes
|
||||
hitIndexes[numIndexes] = tess.indexes[i];
|
||||
hitIndexes[numIndexes + 1] = tess.indexes[i + 1];
|
||||
hitIndexes[numIndexes + 2] = tess.indexes[i + 2];
|
||||
|
||||
numIndexes += 3;
|
||||
|
||||
if (numIndexes>=SHADER_MAX_VERTEXES-3)
|
||||
{
|
||||
break; // we are out of space, so we are done :)
|
||||
}
|
||||
}
|
||||
|
||||
if ( !numIndexes ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//don't have fog enabled when we redraw with alpha test, or it will double over
|
||||
//and screw the tri up -rww
|
||||
if (r_drawfog->value == 2 &&
|
||||
tr.world &&
|
||||
(tess.fogNum == tr.world->globalFog || tess.fogNum == tr.world->numfogs))
|
||||
{
|
||||
fogging = qglIsEnabled(GL_FOG);
|
||||
|
||||
if (fogging)
|
||||
{
|
||||
qglDisable(GL_FOG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fogging = 0;
|
||||
}
|
||||
|
||||
dStage = NULL;
|
||||
if (tess.shader && qglActiveTextureARB)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < tess.shader->numUnfoggedPasses)
|
||||
{
|
||||
const int blendBits = (GLS_SRCBLEND_BITS+GLS_DSTBLEND_BITS);
|
||||
if (((tess.shader->stages[i].bundle[0].image && !tess.shader->stages[i].bundle[0].isLightmap && !tess.shader->stages[i].bundle[0].numTexMods && tess.shader->stages[i].bundle[0].tcGen != TCGEN_ENVIRONMENT_MAPPED && tess.shader->stages[i].bundle[0].tcGen != TCGEN_FOG) ||
|
||||
(tess.shader->stages[i].bundle[1].image && !tess.shader->stages[i].bundle[1].isLightmap && !tess.shader->stages[i].bundle[1].numTexMods && tess.shader->stages[i].bundle[1].tcGen != TCGEN_ENVIRONMENT_MAPPED && tess.shader->stages[i].bundle[1].tcGen != TCGEN_FOG)) &&
|
||||
(tess.shader->stages[i].stateBits & blendBits) == 0 )
|
||||
{ //only use non-lightmap opaque stages
|
||||
dStage = &tess.shader->stages[i];
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dStage)
|
||||
{
|
||||
GL_SelectTexture( 0 );
|
||||
GL_State(0);
|
||||
// animMaps don't actually have a texture in image, it's an array of image pointers:
|
||||
if (dStage->bundle[0].numImageAnimations > 1)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (backEnd.currentEntity->e.renderfx & RF_SETANIMINDEX )
|
||||
{
|
||||
index = backEnd.currentEntity->e.skinNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is necessary to do this messy calc to make sure animations line up
|
||||
// exactly with waveforms of the same frequency
|
||||
index = myftol( backEnd.refdef.floatTime * dStage->bundle[0].imageAnimationSpeed * FUNCTABLE_SIZE );
|
||||
index >>= FUNCTABLE_SIZE2;
|
||||
|
||||
if ( index < 0 ) {
|
||||
index = 0; // may happen with shader time offsets
|
||||
}
|
||||
}
|
||||
|
||||
if ( dStage->bundle[0].oneShotAnimMap )
|
||||
{
|
||||
if ( index >= dStage->bundle[0].numImageAnimations )
|
||||
{
|
||||
// stick on last frame
|
||||
index = dStage->bundle[0].numImageAnimations - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// loop
|
||||
index %= dStage->bundle[0].numImageAnimations;
|
||||
}
|
||||
|
||||
GL_Bind( *((image_t**)dStage->bundle[0].image + index) );
|
||||
}
|
||||
else if (dStage->bundle[0].image && !dStage->bundle[0].isLightmap && !dStage->bundle[0].numTexMods && dStage->bundle[0].tcGen != TCGEN_ENVIRONMENT_MAPPED && dStage->bundle[0].tcGen != TCGEN_FOG)
|
||||
{
|
||||
GL_Bind( dStage->bundle[0].image );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_Bind( dStage->bundle[1].image );
|
||||
}
|
||||
|
||||
GL_State(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);// | GLS_DEPTHFUNC_EQUAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_Bind( tr.whiteImage );
|
||||
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE);// | GLS_DEPTHFUNC_EQUAL );
|
||||
}
|
||||
|
||||
glwstate_t::texturexlat_t::iterator inf = glw_state->textureXlat.find(glw_state->currentTexture[0]);
|
||||
|
||||
glw_state->device->SetTexture(0, inf->second.mipmap);
|
||||
|
||||
D3DXVECTOR4 vecLightRange(1.0f / dl->radius, 0.0f, 0.0f, 0.0f);
|
||||
glw_state->device->SetVertexShaderConstant(CV_ONE_OVER_LIGHT_RANGE, (void*)&vecLightRange.x, 1);
|
||||
|
||||
glw_state->device->SetPixelShaderConstant(CP_DIFFUSE_COLOR, &dl->color[0], 1);
|
||||
|
||||
ProcessVertices( (D3DXVECTOR3*)&dl->direction, (D3DXVECTOR3*)&dl->transformed );
|
||||
|
||||
if(backEnd.currentEntity->e.ghoul2)
|
||||
renderObject_Light( tess.numIndexes, tess.indexes );
|
||||
else
|
||||
renderObject_Light( numIndexes, hitIndexes );
|
||||
|
||||
if (fogging)
|
||||
{
|
||||
qglEnable(GL_FOG);
|
||||
}
|
||||
}
|
||||
|
||||
glw_state->device->SetPixelShader( 0 );
|
||||
|
||||
// This is kinda a hack to get the quake renderer to discard
|
||||
// these textures after they are used here, instead of applying
|
||||
// them to more geometry
|
||||
glState.currenttextures[0] = -2;
|
||||
glState.currenttextures[1] = -2;
|
||||
glw_state->currentTexture[0] = -2;
|
||||
glw_state->currentTexture[1] = -2;
|
||||
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ALPHAKILL, D3DTALPHAKILL_DISABLE);
|
||||
|
||||
glw_state->device->SetTexture(2, NULL);
|
||||
glw_state->device->SetTexture(3, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LightEffects::RenderSpecular()
|
||||
{
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
||||
|
||||
glwstate_t::texturexlat_t::iterator i = glw_state->textureXlat.find(glw_state->currentTexture[0]);
|
||||
|
||||
glw_state->device->SetTexture( 0, i->second.mipmap );
|
||||
glw_state->device->SetTexture( 2, m_pSpecularMap );
|
||||
|
||||
glw_state->device->SetVertexShaderConstant(CV_CAMERA_DIRECTION, D3DXVECTOR4(tr.viewParms.or.axis[0][0],
|
||||
tr.viewParms.or.axis[0][1],
|
||||
tr.viewParms.or.axis[0][2],
|
||||
1.0f), 1 );
|
||||
|
||||
RenderSpecular_Static();
|
||||
|
||||
if(tess.dlightBits)
|
||||
RenderSpecular_Dynamic();
|
||||
|
||||
glw_state->device->SetPixelShader(0);
|
||||
|
||||
// This is kinda a hack to get the quake renderer to discard
|
||||
// these textures after they are used here, instead of applying
|
||||
// them to more geometry
|
||||
glState.currenttextures[0] = -2;
|
||||
glState.currenttextures[1] = -2;
|
||||
glw_state->currentTexture[0] = -2;
|
||||
glw_state->currentTexture[1] = -2;
|
||||
}
|
||||
|
||||
|
||||
bool LightEffects::RenderSpecular_Dynamic()
|
||||
{
|
||||
VVdlight_t *dl;
|
||||
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MIPFILTER, D3DTEXF_POINT );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
|
||||
glw_state->device->SetTexture( 3, m_pFalloffMap );
|
||||
|
||||
glw_state->device->SetPixelShader(m_dwPixelShaderSpecular_Dynamic);
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderSpecular_Dynamic);
|
||||
|
||||
for(int i = 0; i < VVLightMan.num_dlights; i++)
|
||||
{
|
||||
if(!(tess.dlightBits & (1 << i)))
|
||||
continue;
|
||||
|
||||
dl = &VVLightMan.dlights[i];
|
||||
|
||||
D3DXVECTOR4 vecLightRange(1.0f / dl->radius, 0.0f, 0.0f, 0.0f);
|
||||
glw_state->device->SetVertexShaderConstant(CV_ONE_OVER_LIGHT_RANGE, (void*)&vecLightRange.x, 1);
|
||||
|
||||
ProcessVertices( (D3DXVECTOR3*)&dl->direction, (D3DXVECTOR3*)&dl->transformed );
|
||||
|
||||
renderObject_Light( tess.numIndexes, tess.indexes);
|
||||
}
|
||||
|
||||
glw_state->device->SetTexture( 3, NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LightEffects::RenderSpecular_Static()
|
||||
{
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
glw_state->device->SetTextureStageState( 2, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
||||
|
||||
glw_state->device->SetPixelShader(m_dwPixelShaderSpecular_Static);
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderSpecular_Static);
|
||||
|
||||
ProcessVertices( NULL, NULL );
|
||||
|
||||
D3DXVECTOR4 vLight;
|
||||
if (backEnd.currentEntity && (backEnd.currentEntity->e.hModel||backEnd.currentEntity->e.ghoul2) )
|
||||
{
|
||||
vLight.x = backEnd.currentEntity->lightDir[0];
|
||||
vLight.y = backEnd.currentEntity->lightDir[1];
|
||||
vLight.z = backEnd.currentEntity->lightDir[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// These values were taken from the RB_CalcSpecularAlpha default case
|
||||
vLight.x = -960.0f;
|
||||
vLight.y = 1920.0f;
|
||||
vLight.z = 96.0f;
|
||||
}
|
||||
|
||||
vLight.w = 1.0f;
|
||||
|
||||
glw_state->device->SetVertexShaderConstant(CV_LIGHT_DIRECTION, vLight, 1);
|
||||
|
||||
renderObject_Light( tess.numIndexes, tess.indexes );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LightEffects::RenderEnvironment()
|
||||
{
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, false );
|
||||
|
||||
glw_state->device->SetVertexShaderConstant(CV_CAMERA_DIRECTION, D3DXVECTOR4(backEnd.ori.viewOrigin[0],
|
||||
backEnd.ori.viewOrigin[1],
|
||||
backEnd.ori.viewOrigin[2],
|
||||
1.0f), 1 );
|
||||
|
||||
ProcessVertices(NULL, NULL);
|
||||
|
||||
XGMATRIX *view, viewtran;
|
||||
view = (XGMATRIX*)glw_state->matrixStack[glw_state->MatrixMode_Model]->GetTop();
|
||||
XGMatrixTranspose( &viewtran, view );
|
||||
glw_state->device->SetVertexShaderConstant(CV_VIEW_0, viewtran, 4);
|
||||
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderEnvironment);
|
||||
|
||||
renderObject_Env();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Renders bump maps without the benefit of dynamic lights
|
||||
void LightEffects::RenderBump()
|
||||
{
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, false );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, false );
|
||||
|
||||
glwstate_t::texturexlat_t::iterator i = glw_state->textureXlat.find(glw_state->currentTexture[0]);
|
||||
glw_state->device->SetTexture( 0, i->second.mipmap );
|
||||
|
||||
i = glw_state->textureXlat.find(glw_state->currentTexture[1]);
|
||||
glw_state->device->SetTexture( 1, i->second.mipmap );
|
||||
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_MAXANISOTROPY, i->second.anisotropy);
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_MINFILTER, i->second.minFilter);
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_MIPFILTER, i->second.mipFilter);
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_MAGFILTER, i->second.magFilter);
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_ADDRESSU, i->second.wrapU);
|
||||
glw_state->device->SetTextureStageState(0, D3DTSS_ADDRESSV, i->second.wrapV);
|
||||
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_MAXANISOTROPY, i->second.anisotropy);
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_MINFILTER, i->second.minFilter);
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_MIPFILTER, i->second.mipFilter);
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_MAGFILTER, i->second.magFilter);
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_ADDRESSU, i->second.wrapU);
|
||||
glw_state->device->SetTextureStageState(1, D3DTSS_ADDRESSV, i->second.wrapV);
|
||||
|
||||
glw_state->device->SetRenderState(D3DRS_SPECULARENABLE, true);
|
||||
|
||||
glw_state->device->SetPixelShader(m_dwPixelShaderBump);
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderBump);
|
||||
|
||||
ProcessVertices( NULL, NULL );
|
||||
|
||||
D3DXVECTOR4 vAmbient, vDiffuse, vLightDir;
|
||||
|
||||
if (backEnd.currentEntity && (backEnd.currentEntity->e.hModel||backEnd.currentEntity->e.ghoul2) )
|
||||
{
|
||||
if(tess.shader->stages[tess.currentPass].rgbGen == CGEN_LIGHTING_DIFFUSE_ENTITY)
|
||||
{
|
||||
vAmbient.x = (backEnd.currentEntity->ambientLight[0] / 255.f) * (backEnd.currentEntity->e.shaderRGBA[0] / 255.0);
|
||||
vAmbient.y = (backEnd.currentEntity->ambientLight[1] / 255.f) * (backEnd.currentEntity->e.shaderRGBA[1] / 255.0);
|
||||
vAmbient.z = (backEnd.currentEntity->ambientLight[2] / 255.f) * (backEnd.currentEntity->e.shaderRGBA[2] / 255.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vAmbient.x = backEnd.currentEntity->ambientLight[0] / 255.f;
|
||||
vAmbient.y = backEnd.currentEntity->ambientLight[1] / 255.f;
|
||||
vAmbient.z = backEnd.currentEntity->ambientLight[2] / 255.f;
|
||||
}
|
||||
|
||||
vDiffuse.x = backEnd.currentEntity->directedLight[0] / 255.f;
|
||||
vDiffuse.y = backEnd.currentEntity->directedLight[1] / 255.f;
|
||||
vDiffuse.z = backEnd.currentEntity->directedLight[2] / 255.f;
|
||||
|
||||
vLightDir.x = DotProduct( backEnd.currentEntity->lightDir, backEnd.currentEntity->e.axis[0] );
|
||||
vLightDir.y = DotProduct( backEnd.currentEntity->lightDir, backEnd.currentEntity->e.axis[1] );
|
||||
vLightDir.z = DotProduct( backEnd.currentEntity->lightDir, backEnd.currentEntity->e.axis[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3_t sundir;
|
||||
sundir[0] = r_sundir_x->value;
|
||||
sundir[1] = r_sundir_y->value;
|
||||
sundir[2] = r_sundir_z->value;
|
||||
|
||||
VectorNormalize(sundir);
|
||||
|
||||
vLightDir.x = sundir[0];//tr.sunDirection[0];
|
||||
vLightDir.y = sundir[1];//tr.sunDirection[1];
|
||||
vLightDir.z = sundir[2];//tr.sunDirection[2];
|
||||
vLightDir.w = 1.0f;
|
||||
|
||||
vAmbient.x = tr.sunAmbient[0] / 1.5f;
|
||||
vAmbient.y = tr.sunAmbient[1] / 1.5f;
|
||||
vAmbient.z = tr.sunAmbient[2] / 1.5f;
|
||||
|
||||
vDiffuse.x = 1.0f;
|
||||
vDiffuse.y = 1.0f;
|
||||
vDiffuse.z = 1.0f;
|
||||
}
|
||||
|
||||
glw_state->device->SetPixelShaderConstant(CP_AMBIENT_COLOR, vAmbient, 1);
|
||||
glw_state->device->SetPixelShaderConstant(CP_DIFFUSE_COLOR, vDiffuse, 1);
|
||||
|
||||
glw_state->device->SetVertexShaderConstant(CV_LIGHT_DIRECTION, vLightDir, 1);
|
||||
|
||||
glw_state->device->SetVertexShaderConstant(CV_CAMERA_DIRECTION, D3DXVECTOR4(tr.viewParms.or.axis[0][0],
|
||||
tr.viewParms.or.axis[0][1],
|
||||
tr.viewParms.or.axis[0][2],
|
||||
1.0f), 1 );
|
||||
|
||||
renderObject_Bump();
|
||||
|
||||
glw_state->device->SetPixelShader( 0 );
|
||||
|
||||
glw_state->device->SetRenderState(D3DRS_SPECULARENABLE, false);
|
||||
}
|
||||
|
||||
|
||||
//bool LightEffects::RenderStaticLights()
|
||||
//{
|
||||
// VVslight_t *sl;
|
||||
//
|
||||
// for(int i = 0; i < tess.numSlights; i++)
|
||||
// {
|
||||
// sl = &VVLightMan.slights[tess.slightBits[i]];
|
||||
//
|
||||
// D3DXVECTOR4 vecLightRange(1.0f / (sl->radius * 2.0f), sl->radius, 1.0f, 1.0f);
|
||||
// glw_state->device->SetVertexShaderConstant(CV_ONE_OVER_LIGHT_RANGE, (void*)&vecLightRange.x, 1);
|
||||
//
|
||||
// glw_state->device->SetVertexShaderConstant(CV_LIGHT_COLOR, &sl->color[0], 1);
|
||||
//
|
||||
// ProcessVertices( NULL, (D3DXVECTOR3*)&sl->origin );
|
||||
//
|
||||
// renderObject_Light();
|
||||
//
|
||||
// tess.currentPass++;
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
//}
|
||||
|
||||
|
||||
void LightEffects::ProcessVertices( D3DXVECTOR3* pDirLightDir, D3DXVECTOR3* pPtLightPos )
|
||||
{
|
||||
// Just in case, this doesn't always get set
|
||||
glw_state->device->SetTransform( D3DTS_PROJECTION, glw_state->matrixStack[glw_state->MatrixMode_Projection]->GetTop() );
|
||||
|
||||
// Compute the matrix set
|
||||
XGMATRIX matComposite, matProjectionViewport, matWorld;
|
||||
// Get the projection viewport matrix the fixed pipeline uses.
|
||||
// The viewport matrix includes the viewport x,y scale and the
|
||||
// appropriate z scale.
|
||||
glw_state->device->GetProjectionViewportMatrix( &matProjectionViewport );
|
||||
|
||||
D3DVIEWPORT8 view;
|
||||
glw_state->device->GetViewport(&view);
|
||||
|
||||
// Gotta do this to fix an XDK bug
|
||||
// GetProjectionViewportMatrix does not seem to reflect the viewport values
|
||||
// when the viewport is offset
|
||||
matProjectionViewport._31 += view.X;
|
||||
matProjectionViewport._32 += view.Y;
|
||||
|
||||
XGMatrixMultiply( &matComposite, (XGMATRIX*)glw_state->matrixStack[glwstate_t::MatrixMode_Model]->GetTop(), &matProjectionViewport );
|
||||
|
||||
// Transpose and set the composite matrix.
|
||||
XGMatrixTranspose( &matComposite, &matComposite );
|
||||
glw_state->device->SetVertexShaderConstant( CV_WORLDVIEWPROJ_0, &matComposite, 4 );
|
||||
|
||||
if (pPtLightPos)
|
||||
glw_state->device->SetVertexShaderConstant( CV_LIGHT_POSITION, pPtLightPos, 1 );
|
||||
|
||||
// Set viewport offsets.
|
||||
float fViewportOffsets[4] = { 0.53125f, 0.53125f, 0.0f, 0.0f };
|
||||
glw_state->device->SetVertexShaderConstant( CV_VIEWPORT_OFFSETS, &fViewportOffsets, 1 );
|
||||
|
||||
// Set common constants
|
||||
glw_state->device->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
|
||||
glw_state->device->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1);
|
||||
}
|
||||
|
||||
|
||||
inline D3DCOLOR VectorToRGBA( const D3DXVECTOR3* v, FLOAT fHeight = 1.0f )
|
||||
{
|
||||
D3DCOLOR r = (D3DCOLOR)( ( v->x + 1.0f ) * 127.5f );
|
||||
D3DCOLOR g = (D3DCOLOR)( ( v->y + 1.0f ) * 127.5f );
|
||||
D3DCOLOR b = (D3DCOLOR)( ( v->z + 1.0f ) * 127.5f );
|
||||
D3DCOLOR a = (D3DCOLOR)( 255.0f * fHeight );
|
||||
return( (a<<24L) + (r<<16L) + (g<<8L) + (b<<0L) );
|
||||
}
|
||||
|
||||
|
||||
bool LightEffects::CreateNormalizationCubeMap( DWORD dwSize, LPDIRECT3DCUBETEXTURE8* ppCubeMap )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// Create the cube map
|
||||
if( FAILED( hr = glw_state->device->CreateCubeTexture( dwSize, 1, 0, D3DFMT_X8R8G8B8,
|
||||
D3DPOOL_DEFAULT, ppCubeMap ) ) )
|
||||
return false;
|
||||
|
||||
// Allocate temp space for swizzling the cubemap surfaces
|
||||
DWORD* pSourceBits = new DWORD[ dwSize * dwSize ];
|
||||
|
||||
// Fill all six sides of the cubemap
|
||||
for( DWORD i=0; i<6; i++ )
|
||||
{
|
||||
// Lock the i'th cubemap surface
|
||||
LPDIRECT3DSURFACE8 pCubeMapFace;
|
||||
(*ppCubeMap)->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pCubeMapFace );
|
||||
|
||||
// Write the RGBA-encoded normals to the surface pixels
|
||||
DWORD* pPixel = pSourceBits;
|
||||
D3DXVECTOR3 n;
|
||||
FLOAT w, h;
|
||||
|
||||
for( DWORD y = 0; y < dwSize; y++ )
|
||||
{
|
||||
h = (FLOAT)y / (FLOAT)(dwSize-1); // 0 to 1
|
||||
h = ( h * 2.0f ) - 1.0f; // -1 to 1
|
||||
|
||||
for( DWORD x = 0; x < dwSize; x++ )
|
||||
{
|
||||
w = (FLOAT)x / (FLOAT)(dwSize-1); // 0 to 1
|
||||
w = ( w * 2.0f ) - 1.0f; // -1 to 1
|
||||
|
||||
// Calc the normal for this texel
|
||||
switch( i )
|
||||
{
|
||||
case D3DCUBEMAP_FACE_POSITIVE_X: // +x
|
||||
n.x = +1.0;
|
||||
n.y = -h;
|
||||
n.z = -w;
|
||||
break;
|
||||
|
||||
case D3DCUBEMAP_FACE_NEGATIVE_X: // -x
|
||||
n.x = -1.0;
|
||||
n.y = -h;
|
||||
n.z = +w;
|
||||
break;
|
||||
|
||||
case D3DCUBEMAP_FACE_POSITIVE_Y: // y
|
||||
n.x = +w;
|
||||
n.y = +1.0;
|
||||
n.z = +h;
|
||||
break;
|
||||
|
||||
case D3DCUBEMAP_FACE_NEGATIVE_Y: // -y
|
||||
n.x = +w;
|
||||
n.y = -1.0;
|
||||
n.z = -h;
|
||||
break;
|
||||
|
||||
case D3DCUBEMAP_FACE_POSITIVE_Z: // +z
|
||||
n.x = +w;
|
||||
n.y = -h;
|
||||
n.z = +1.0;
|
||||
break;
|
||||
|
||||
case D3DCUBEMAP_FACE_NEGATIVE_Z: // -z
|
||||
n.x = -w;
|
||||
n.y = -h;
|
||||
n.z = -1.0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Store the normal as an RGBA color
|
||||
D3DXVec3Normalize( &n, &n );
|
||||
*pPixel++ = VectorToRGBA( &n );
|
||||
}
|
||||
}
|
||||
|
||||
// Swizzle the result into the cubemap face surface
|
||||
D3DLOCKED_RECT lock;
|
||||
pCubeMapFace->LockRect( &lock, 0, 0L );
|
||||
XGSwizzleRect( pSourceBits, 0, NULL, lock.pBits, dwSize, dwSize,
|
||||
NULL, sizeof(DWORD) );
|
||||
pCubeMapFace->UnlockRect();
|
||||
|
||||
// Release the cubemap face
|
||||
pCubeMapFace->Release();
|
||||
}
|
||||
|
||||
// Free temp space
|
||||
if( pSourceBits )
|
||||
delete [] pSourceBits;
|
||||
pSourceBits = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // VV_LIGHTING
|
||||
52
code/win32/win_lighteffects.h
Normal file
52
code/win32/win_lighteffects.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
//
|
||||
// win_lightefects.h
|
||||
//
|
||||
// Declaration of class for pixel shader light effects
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef _WIN_LIGHTEFFECTS_H_
|
||||
#define _WIN_LIGHTEFFECTS_H_
|
||||
|
||||
|
||||
class LightEffects
|
||||
{
|
||||
public:
|
||||
LPDIRECT3DCUBETEXTURE9 m_pCubeMap; // Normalization cubemap
|
||||
LPDIRECT3DTEXTURE9 m_pBumpMap;
|
||||
LPDIRECT3DTEXTURE9 m_pSpecularMap;
|
||||
LPDIRECT3DVOLUMETEXTURE9 m_pFalloffMap;
|
||||
DWORD m_dwVertexShaderLight;
|
||||
DWORD m_dwPixelShaderLight;
|
||||
DWORD m_dwVertexShaderSpecular_Dynamic;
|
||||
DWORD m_dwPixelShaderSpecular_Dynamic;
|
||||
DWORD m_dwVertexShaderSpecular_Static;
|
||||
DWORD m_dwPixelShaderSpecular_Static;
|
||||
DWORD m_dwVertexShaderEnvironment;
|
||||
DWORD m_dwVertexShaderBump;
|
||||
DWORD m_dwPixelShaderBump;
|
||||
bool m_bInLightPhase;
|
||||
bool m_bInitialized;
|
||||
|
||||
public:
|
||||
LightEffects();
|
||||
virtual ~LightEffects();
|
||||
|
||||
bool Initialize();
|
||||
void ProcessVertices(D3DXVECTOR3* pDirLightDir, D3DXVECTOR3* pPtLightPos);
|
||||
bool RenderDynamicLights();
|
||||
bool RenderStaticLights();
|
||||
void RenderSpecular();
|
||||
bool RenderSpecular_Dynamic();
|
||||
bool RenderSpecular_Static();
|
||||
bool RenderEnvironment();
|
||||
void RenderBump();
|
||||
bool CreateNormalizationCubeMap( DWORD dwSize, LPDIRECT3DCUBETEXTURE9* ppCubeMap );
|
||||
void StartLightPhase();
|
||||
void EndLightPhase();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
79
code/win32/win_local.h
Normal file
79
code/win32/win_local.h
Normal file
@@ -0,0 +1,79 @@
|
||||
// win_local.h: Win32-specific Quake3 header file
|
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#pragma warning(disable : 4201)
|
||||
#pragma warning( push )
|
||||
#endif
|
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#ifndef _XBOX
|
||||
#define DIRECTINPUT_VERSION 0x0800 //[ 0x0300 | 0x0500 | 0x0700 | 0x0800 ]
|
||||
#include <dinput.h>
|
||||
#include <dsound.h>
|
||||
#else
|
||||
#include "../qcommon/platform.h"
|
||||
#endif
|
||||
|
||||
void IN_MouseEvent (int mstate);
|
||||
|
||||
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
|
||||
|
||||
void Sys_CreateConsole( void );
|
||||
void Sys_DestroyConsole( void );
|
||||
|
||||
char *Sys_ConsoleInput (void);
|
||||
|
||||
// Input subsystem
|
||||
|
||||
void IN_Init (void);
|
||||
void IN_Shutdown (void);
|
||||
void IN_JoystickCommands (void);
|
||||
|
||||
void IN_Move (usercmd_t *cmd);
|
||||
// add additional non keyboard / non mouse movement on top of the keyboard move cmd
|
||||
|
||||
void IN_DeactivateWin32Mouse( void);
|
||||
|
||||
void IN_Activate (qboolean active);
|
||||
void IN_Frame (void);
|
||||
|
||||
// window procedure
|
||||
#ifndef _XBOX
|
||||
LONG WINAPI MainWndProc (
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
#endif
|
||||
|
||||
void Conbuf_AppendText( const char *msg );
|
||||
|
||||
void SNDDMA_Activate( qboolean bAppActive );
|
||||
|
||||
#ifndef _XBOX
|
||||
typedef struct
|
||||
{
|
||||
HWND hWnd;
|
||||
HINSTANCE hInstance;
|
||||
qboolean activeApp;
|
||||
qboolean isMinimized;
|
||||
OSVERSIONINFO osversion;
|
||||
|
||||
// when we get a windows message, we store the time off so keyboard processing
|
||||
// can know the exact time of an event
|
||||
unsigned sysMsgTime;
|
||||
} WinVars_t;
|
||||
|
||||
extern WinVars_t g_wv;
|
||||
#endif
|
||||
|
||||
|
||||
#define MAX_QUED_EVENTS 256
|
||||
#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
|
||||
|
||||
#define YELLOW_MODE 0
|
||||
|
||||
|
||||
1241
code/win32/win_main.cpp
Normal file
1241
code/win32/win_main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
332
code/win32/win_main_common.cpp
Normal file
332
code/win32/win_main_common.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
// win_main.h
|
||||
|
||||
#include "../game/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
#include "resource.h"
|
||||
|
||||
#ifndef _GAMECUBE
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//#define SPANK_MONKEYS //----(SA) commented out for running net developer release builds
|
||||
int sys_monkeySpank;
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_MonkeyShouldBeSpanked
|
||||
==================
|
||||
*/
|
||||
int Sys_MonkeyShouldBeSpanked( void ) {
|
||||
return sys_monkeySpank;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_FunctionCmp
|
||||
==================
|
||||
*/
|
||||
int Sys_FunctionCmp(void *f1, void *f2) {
|
||||
|
||||
int i, j, l;
|
||||
byte func_end[32] = {0xC3, 0x90, 0x90, 0x00};
|
||||
byte *ptr, *ptr2;
|
||||
byte *f1_ptr, *f2_ptr;
|
||||
|
||||
ptr = (byte *) f1;
|
||||
if (*(byte *)ptr == 0xE9) {
|
||||
//Com_Printf("f1 %p1 jmp %d\n", (int *) f1, *(int*)(ptr+1));
|
||||
f1_ptr = (byte*)(((byte*)f1) + (*(int *)(ptr+1)) + 5);
|
||||
}
|
||||
else {
|
||||
f1_ptr = ptr;
|
||||
}
|
||||
//Com_Printf("f1 ptr %p\n", f1_ptr);
|
||||
|
||||
ptr = (byte *) f2;
|
||||
if (*(byte *)ptr == 0xE9) {
|
||||
//Com_Printf("f2 %p jmp %d\n", (int *) f2, *(int*)(ptr+1));
|
||||
f2_ptr = (byte*)(((byte*)f2) + (*(int *)(ptr+1)) + 5);
|
||||
}
|
||||
else {
|
||||
f2_ptr = ptr;
|
||||
}
|
||||
//Com_Printf("f2 ptr %p\n", f2_ptr);
|
||||
|
||||
#ifdef _DEBUG
|
||||
sprintf((char *)func_end, "%c%c%c%c%c%c%c", 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC3);
|
||||
#endif
|
||||
for (i = 0; i < 1024; i++) {
|
||||
for (j = 0; func_end[j]; j++) {
|
||||
if (f1_ptr[i+j] != func_end[j])
|
||||
break;
|
||||
}
|
||||
if (!func_end[j]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
l = i + 7;
|
||||
#else
|
||||
l = i + 2;
|
||||
#endif
|
||||
//Com_Printf("function length = %d\n", l);
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
// check for a potential function call
|
||||
if (*((byte *) &f1_ptr[i]) == 0xE8) {
|
||||
// get the function pointers in case this really is a function call
|
||||
ptr = (byte *) (((byte *) &f1_ptr[i]) + (*(int *) &f1_ptr[i+1])) + 5;
|
||||
ptr2 = (byte *) (((byte *) &f2_ptr[i]) + (*(int *) &f2_ptr[i+1])) + 5;
|
||||
// if it was a function call and both f1 and f2 call the same function
|
||||
if (ptr == ptr2) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f1_ptr[i] != f2_ptr[i])
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_FunctionCheckSum
|
||||
==================
|
||||
*/
|
||||
int Sys_FunctionCheckSum(void *f1) {
|
||||
|
||||
int i, j, l;
|
||||
unsigned shermcrap;
|
||||
byte func_end[32] = {0xC3, 0x90, 0x90, 0x00};
|
||||
byte *ptr;
|
||||
byte *f1_ptr;
|
||||
|
||||
ptr = (byte *) f1;
|
||||
if (*(byte *)ptr == 0xE9) {
|
||||
//Com_Printf("f1 %p1 jmp %d\n", (int *) f1, *(int*)(ptr+1));
|
||||
f1_ptr = (byte*)(((byte*)f1) + (*(int *)(ptr+1)) + 5);
|
||||
}
|
||||
else {
|
||||
f1_ptr = ptr;
|
||||
}
|
||||
//Com_Printf("f1 ptr %p\n", f1_ptr);
|
||||
|
||||
#ifdef _DEBUG
|
||||
sprintf((char *)func_end, "%c%c%c%c%c%c%c", 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC3);
|
||||
#endif
|
||||
for (i = 0; i < 1024; i++) {
|
||||
for (j = 0; func_end[j]; j++) {
|
||||
if (f1_ptr[i+j] != func_end[j])
|
||||
break;
|
||||
}
|
||||
if (!func_end[j]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
l = i + 7;
|
||||
#else
|
||||
l = i + 2;
|
||||
#endif
|
||||
//Com_Printf("function length = %d\n", l);
|
||||
shermcrap = Com_BlockChecksum( f1_ptr, l );
|
||||
return (int)shermcrap;
|
||||
}
|
||||
|
||||
|
||||
//NOTE TTimo: heavily NON PORTABLE, PLZ DON'T USE
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=447
|
||||
#if 0
|
||||
//----(SA) added
|
||||
/*
|
||||
==============
|
||||
Sys_ShellExecute
|
||||
|
||||
- Windows only
|
||||
|
||||
Performs an operation on a specified file.
|
||||
|
||||
See info on ShellExecute() for details
|
||||
|
||||
==============
|
||||
*/
|
||||
int Sys_ShellExecute(char *op, char *file, qboolean doexit, char *params, char *dir ) {
|
||||
unsigned int retval;
|
||||
char *se_op;
|
||||
|
||||
// set default operation to "open"
|
||||
if(op) se_op = op;
|
||||
else se_op = "open";
|
||||
|
||||
|
||||
// probably need to protect this some in the future so people have
|
||||
// less chance of system invasion with this powerful interface
|
||||
// (okay, not so invasive, but could be annoying/rude)
|
||||
|
||||
|
||||
retval = (UINT)ShellExecute(NULL, se_op, file, params, dir, SW_NORMAL); // only option forced by game is 'sw_normal'
|
||||
|
||||
if( retval <= 32) { // ERROR
|
||||
Com_DPrintf("Sys_ShellExecuteERROR: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ( doexit ) {
|
||||
// (SA) this works better for exiting cleanly...
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "quit" );
|
||||
}
|
||||
|
||||
return 999; // success
|
||||
}
|
||||
//----(SA) end
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_BeginProfiling
|
||||
==================
|
||||
*/
|
||||
void Sys_BeginProfiling( void ) {
|
||||
// this is just used on the mac build
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_DefaultCDPath
|
||||
==============
|
||||
*/
|
||||
char *Sys_DefaultCDPath( void ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_DefaultBasePath
|
||||
==============
|
||||
*/
|
||||
char *Sys_DefaultBasePath( void ) {
|
||||
return Sys_Cwd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
EVENT LOOP
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
|
||||
sysEvent_t eventQue[MAX_QUED_EVENTS];
|
||||
int eventHead, eventTail;
|
||||
byte sys_packetReceived[MAX_MSGLEN];
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_QueEvent
|
||||
|
||||
A time of 0 will get the current time
|
||||
Ptr should either be null, or point to a block of data that can
|
||||
be freed by the game later.
|
||||
================
|
||||
*/
|
||||
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
|
||||
sysEvent_t *ev;
|
||||
|
||||
ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
|
||||
if ( eventHead - eventTail >= MAX_QUED_EVENTS ) {
|
||||
Com_Printf("Sys_QueEvent: overflow\n");
|
||||
// we are discarding an event, but don't leak memory
|
||||
if ( ev->evPtr ) {
|
||||
Z_Free( ev->evPtr );
|
||||
}
|
||||
eventTail++;
|
||||
}
|
||||
|
||||
eventHead++;
|
||||
|
||||
if ( time == 0 ) {
|
||||
time = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
ev->evTime = time;
|
||||
ev->evType = type;
|
||||
ev->evValue = value;
|
||||
ev->evValue2 = value2;
|
||||
ev->evPtrLength = ptrLength;
|
||||
ev->evPtr = ptr;
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_Net_Restart_f
|
||||
|
||||
Restart the network subsystem
|
||||
=================
|
||||
*/
|
||||
void Sys_Net_Restart_f( void ) {
|
||||
// NET_Restart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
|
||||
|
||||
void Sys_InitStreamThread( void ) {
|
||||
}
|
||||
|
||||
void Sys_ShutdownStreamThread( void ) {
|
||||
}
|
||||
|
||||
void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
|
||||
}
|
||||
|
||||
void Sys_EndStreamedFile( fileHandle_t f ) {
|
||||
}
|
||||
|
||||
int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
|
||||
return FS_Read( buffer, size * count, f );
|
||||
}
|
||||
|
||||
void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
|
||||
FS_Seek( f, offset, origin );
|
||||
}
|
||||
|
||||
|
||||
void *Sys_InitializeCriticalSection() {
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
void Sys_EnterCriticalSection(void *ptr) {
|
||||
}
|
||||
|
||||
void Sys_LeaveCriticalSection(void *ptr) {
|
||||
}
|
||||
|
||||
821
code/win32/win_main_console.cpp
Normal file
821
code/win32/win_main_console.cpp
Normal file
@@ -0,0 +1,821 @@
|
||||
#include "../game/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
#include "resource.h"
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include "../game/g_public.h"
|
||||
#include <xonline.h>
|
||||
#include "glw_win_dx8.h"
|
||||
#include "../qcommon/xb_settings.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <IO.h>
|
||||
#define NEWDECL __cdecl
|
||||
|
||||
#ifndef FINAL_BUILD
|
||||
#include "dbg_console_xbox.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int gLaunchController = 0;
|
||||
|
||||
extern int eventHead, eventTail;
|
||||
extern sysEvent_t eventQue[MAX_QUED_EVENTS];
|
||||
extern byte sys_packetReceived[MAX_MSGLEN];
|
||||
|
||||
void *NEWDECL operator new(size_t size)
|
||||
{
|
||||
return Z_Malloc(size, TAG_NEWDEL, qfalse);
|
||||
}
|
||||
|
||||
|
||||
void *NEWDECL operator new[](size_t size)
|
||||
{
|
||||
return Z_Malloc(size, TAG_NEWDEL, qfalse);
|
||||
}
|
||||
|
||||
|
||||
void NEWDECL operator delete[](void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void NEWDECL operator delete(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Init
|
||||
|
||||
Called after the common systems (cvars, files, etc)
|
||||
are initialized
|
||||
================
|
||||
*/
|
||||
extern void Sys_In_Restart_f(void);
|
||||
extern void Sys_Net_Restart_f(void);
|
||||
void Sys_Init( void )
|
||||
{
|
||||
Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
|
||||
Cmd_AddCommand ("net_restart", Sys_Net_Restart_f);
|
||||
}
|
||||
|
||||
#ifdef XBOX_DEMO
|
||||
// When we're a demo, we're not running from D:\, so we need some hacks:
|
||||
char demoBasePath[64];
|
||||
#endif
|
||||
|
||||
char *Sys_Cwd( void )
|
||||
{
|
||||
static char cwd[MAX_OSPATH];
|
||||
|
||||
#ifdef XBOX_DEMO
|
||||
strcpy( cwd, demoBasePath );
|
||||
#else
|
||||
strcpy(cwd, "d:");
|
||||
#endif
|
||||
|
||||
return cwd;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_In_Restart_f
|
||||
|
||||
Restart the input subsystem
|
||||
=================
|
||||
*/
|
||||
void Sys_In_Restart_f( void ) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Sys_Error
|
||||
|
||||
Show the early console as an error dialog
|
||||
=============
|
||||
*/
|
||||
void Sys_Error( const char *error, ... ) {
|
||||
va_list argptr;
|
||||
char text[256];
|
||||
|
||||
va_start (argptr, error);
|
||||
vsprintf (text, error, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
#ifdef _GAMECUBE
|
||||
printf(text);
|
||||
#else
|
||||
OutputDebugString(text);
|
||||
#endif
|
||||
|
||||
#if 0 // UN-PORT
|
||||
Com_ShutdownZoneMemory();
|
||||
Com_ShutdownHunkMemory();
|
||||
#endif
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_GetEvent
|
||||
|
||||
================
|
||||
*/
|
||||
sysEvent_t Sys_GetEvent( void ) {
|
||||
sysEvent_t ev;
|
||||
|
||||
// return if we have data
|
||||
if ( eventHead > eventTail ) {
|
||||
eventTail++;
|
||||
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
|
||||
}
|
||||
|
||||
// check for network packets
|
||||
msg_t netmsg;
|
||||
MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
|
||||
|
||||
// return if we have data
|
||||
if ( eventHead > eventTail ) {
|
||||
eventTail++;
|
||||
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
|
||||
}
|
||||
|
||||
// create an empty event to return
|
||||
memset( &ev, 0, sizeof( ev ) );
|
||||
ev.evTime = Sys_Milliseconds();
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
||||
void Sys_Print(const char *msg)
|
||||
{
|
||||
#ifdef _GAMECUBE
|
||||
printf(msg);
|
||||
#else
|
||||
OutputDebugString(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Log
|
||||
==============
|
||||
*/
|
||||
void Sys_Log( const char *file, const char *msg ) {
|
||||
Sys_Log(file, msg, strlen(msg), strchr(msg, '\n') ? true : false);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Log
|
||||
==============
|
||||
*/
|
||||
void Sys_Log( const char *file, const void *buffer, int size, bool flush ) {
|
||||
#ifndef FINAL_BUILD
|
||||
static bool unableToLog = false;
|
||||
|
||||
// Once we've failed to write to the log files once, bail out.
|
||||
// This lets us put release builds on DVD without recompiling.
|
||||
if (unableToLog)
|
||||
return;
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
FILE *handle;
|
||||
};
|
||||
|
||||
const int LOG_MAX_FILES = 4;
|
||||
static FileInfo files[LOG_MAX_FILES];
|
||||
static int num_files = 0;
|
||||
|
||||
FileInfo* cur = NULL;
|
||||
for (int f = 0; f < num_files; ++f)
|
||||
{
|
||||
if (!stricmp(file, files[f].name))
|
||||
{
|
||||
cur = &files[f];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur == NULL)
|
||||
{
|
||||
if (num_files >= LOG_MAX_FILES)
|
||||
{
|
||||
Sys_Print("Too many log files!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cur = &files[num_files++];
|
||||
strcpy(cur->name, file);
|
||||
cur->handle = NULL;
|
||||
}
|
||||
|
||||
char fullname[MAX_QPATH];
|
||||
sprintf(fullname, "d:\\%s", cur->name);
|
||||
if (!cur->handle)
|
||||
{
|
||||
cur->handle = fopen(fullname, "wb");
|
||||
if (cur->handle == NULL)
|
||||
{
|
||||
Sys_Print("Unable to open log file!\n");
|
||||
unableToLog = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 1) fputc(*(char*)buffer, cur->handle);
|
||||
else fwrite(buffer, size, 1, cur->handle);
|
||||
|
||||
if (flush)
|
||||
{
|
||||
fflush(cur->handle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
HANDLE Sys_FileStreamMutex = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
|
||||
void Win_Init(void)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
Sys_FileStreamMutex = CreateMutex(NULL, FALSE, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
|
||||
XBE SWITCHING SUPPORT
|
||||
|
||||
=====================
|
||||
*/
|
||||
|
||||
#ifdef XBOX_DEMO
|
||||
// Filled in when we're launched from CDX
|
||||
LD_DEMO demoLaunchData;
|
||||
bool demoLaunchDataValid = false;
|
||||
|
||||
// If we were launched by the user, or someone has pressed a key
|
||||
// then the timer should not count down during movies/loading:
|
||||
bool demoTimerAlways = false;
|
||||
int demoTimer = 0;
|
||||
#endif
|
||||
|
||||
// Takes a filename (relative to ".") and pre-pends the right path. This
|
||||
// is needed for demos where the game won't be running from D:
|
||||
const char *Sys_RemapPath( const char *filename )
|
||||
{
|
||||
#ifdef XBOX_DEMO
|
||||
return va( "%s\\%s", demoBasePath, filename );
|
||||
#else
|
||||
return va( "D:\\%s", filename );
|
||||
#endif
|
||||
}
|
||||
|
||||
// Despite what you may think, this function actually just returns
|
||||
// a value telling you if you *should* quick-boot -- ie skip intro
|
||||
// cinematics and such. Only supposed to XGetLaunchInfo once per
|
||||
// boot, so we cache the results.
|
||||
//
|
||||
// This function always gets called at startup, so we also use it
|
||||
// to retrieve the launch info for a demo
|
||||
#define LAUNCH_MAGIC "J3D1"
|
||||
bool Sys_QuickStart( void )
|
||||
{
|
||||
static bool retVal = false;
|
||||
static bool initialized = false;
|
||||
|
||||
if( initialized )
|
||||
return retVal;
|
||||
|
||||
initialized = true;
|
||||
|
||||
#ifdef XBOX_DEMO
|
||||
// Default to D:\, this gets replaced below if CDX started us
|
||||
strcpy( demoBasePath, "D:" );
|
||||
|
||||
gLaunchController = 0; // Irrelevant in demo
|
||||
retVal = false; // We never come from MP (eg), so always false
|
||||
DWORD launchType;
|
||||
|
||||
DWORD result = XGetLaunchInfo( &launchType, (LAUNCH_DATA *) &demoLaunchData );
|
||||
if( result == ERROR_SUCCESS && launchType == LDT_TITLE )
|
||||
{
|
||||
// We were launched by CDX:
|
||||
demoLaunchDataValid = true;
|
||||
|
||||
// How we were launched affects timer behavior:
|
||||
demoTimerAlways = (demoLaunchData.dwRunmode == XLDEMO_RUNMODE_KIOSKMODE);
|
||||
|
||||
// Need to re-map paths, as D:\\ doesn't work now:
|
||||
Q_strncpyz( demoBasePath, demoLaunchData.szLaunchedXBE, sizeof(demoBasePath), qtrue );
|
||||
|
||||
// Find our executable name in the path, and truncate the string there:
|
||||
char *pXBE = strstr( demoBasePath, "\\default.xbe" );
|
||||
if( !pXBE )
|
||||
Com_Error( ERR_FATAL, "Error re-mapping D drive\n" );
|
||||
*pXBE = 0;
|
||||
|
||||
// Fix the video path:
|
||||
extern char XBOX_VIDEO_PATH[64];
|
||||
strcpy( XBOX_VIDEO_PATH, demoBasePath );
|
||||
strcat( XBOX_VIDEO_PATH, "\\base\\video\\" );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
#else
|
||||
DWORD launchType;
|
||||
LAUNCH_DATA ld;
|
||||
|
||||
if( (XGetLaunchInfo( &launchType, &ld ) != ERROR_SUCCESS) ||
|
||||
(launchType != LDT_TITLE) ||
|
||||
strcmp((const char *)&ld.Data[1], LAUNCH_MAGIC) )
|
||||
return (retVal = false);
|
||||
|
||||
gLaunchController = ld.Data[0];
|
||||
|
||||
// Magic number to disable settings/saving
|
||||
if( ld.Data[5] == 0x42 )
|
||||
Settings.Disable();
|
||||
|
||||
return (retVal = true);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int IN_GetMainController(void);
|
||||
extern void SP_DrawMPLoadScreen(void);
|
||||
|
||||
// Takes an extra parameter so that the accepted invite code can pass
|
||||
// in the XONLINE_ACCEPTED_INVITE to be copied into launch data.
|
||||
//
|
||||
// For the demo, the only valid reason is "demo", and pData should be NULL
|
||||
void Sys_Reboot( const char *reason, const void *pData )
|
||||
{
|
||||
#ifdef XBOX_DEMO
|
||||
if( pData || !demoLaunchDataValid || Q_stricmp( reason, "demo" ) != 0 )
|
||||
Com_Error( ERR_DROP, "Invalid Sys_Reboot call\n" );
|
||||
|
||||
// Kill off the sound and stream threads:
|
||||
S_Shutdown();
|
||||
extern void Sys_StreamShutdown(void);
|
||||
Sys_StreamShutdown();
|
||||
|
||||
// Now return to CDX
|
||||
XLaunchNewImage( demoLaunchData.szLauncherXBE, (LAUNCH_DATA *) &demoLaunchData );
|
||||
// Should never return!
|
||||
#else
|
||||
LAUNCH_DATA ld;
|
||||
const char *path = NULL;
|
||||
int controller;
|
||||
|
||||
memset( &ld, 0, sizeof(ld) );
|
||||
controller = IN_GetMainController();
|
||||
ld.Data[0] = (byte) controller;
|
||||
Com_Printf("\tController %d Passed\n",controller);
|
||||
|
||||
if (!Q_stricmp(reason, "multiplayer"))
|
||||
{
|
||||
path = "d:\\jamp.xbe";
|
||||
SP_DrawMPLoadScreen();
|
||||
|
||||
// Set a magic number if saving is disabled
|
||||
if( Settings.IsDisabled() )
|
||||
ld.Data[1] = 0x42;
|
||||
|
||||
// Flag that there is no invite in the launch data:
|
||||
ld.Data[2] = 0;
|
||||
}
|
||||
else if (!Q_stricmp(reason, "invite"))
|
||||
{
|
||||
path = "d:\\jamp.xbe";
|
||||
SP_DrawMPLoadScreen();
|
||||
|
||||
// Set a magic number if saving is disabled
|
||||
if( Settings.IsDisabled() )
|
||||
ld.Data[1] = 0x42;
|
||||
|
||||
// Flag that we're including an invite with the launch data:
|
||||
ld.Data[2] = 1;
|
||||
|
||||
memcpy( &ld.Data[3], pData, sizeof(XONLINE_ACCEPTED_GAMEINVITE) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Error( ERR_FATAL, "Unknown reboot code %s\n", reason );
|
||||
}
|
||||
|
||||
// Title should not be doing ANYTHING in the background.
|
||||
// Shutting down sound ensures that the sound thread is gone
|
||||
S_Shutdown();
|
||||
// Similarly, kill off the streaming thread
|
||||
extern void Sys_StreamShutdown(void);
|
||||
Sys_StreamShutdown();
|
||||
|
||||
// Keep the loading screen up while we reboot!
|
||||
glw_state->device->PersistDisplay();
|
||||
|
||||
XLaunchNewImage(path, &ld);
|
||||
|
||||
// This function should not return!
|
||||
Com_Error( ERR_FATAL, "ERROR: XLaunchNewImage returned\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
static XONLINE_ACCEPTED_GAMEINVITE acceptedGameInvite;
|
||||
|
||||
// Used to check for the presence of an accepted invite for our game on the HD.
|
||||
// Can only return true on the FIRST call.
|
||||
bool Sys_InviteExists( void )
|
||||
{
|
||||
#ifdef XBOX_DEMO
|
||||
return false;
|
||||
#else
|
||||
static bool initialized = false;
|
||||
if( initialized )
|
||||
return false;
|
||||
initialized = true;
|
||||
|
||||
// If we just came from the MP XBE, don't auto-reboot again. That's just silly.
|
||||
if( Sys_QuickStart() )
|
||||
return false;
|
||||
|
||||
// Try to retrieve an invitation from the HD (this requires that we start XOnline):
|
||||
XOnlineStartup( NULL );
|
||||
HRESULT hr = XOnlineFriendsGetAcceptedGameInvite( &acceptedGameInvite );
|
||||
XOnlineCleanup();
|
||||
|
||||
return (hr == S_OK);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Reboot to MP to join the game that we have an invite for:
|
||||
void Sys_JoinInvite( void )
|
||||
{
|
||||
// Aha. Well, XTL seems to blow this away now, so we need to copy it to launch_data. Bleh.
|
||||
Sys_Reboot( "invite", &acceptedGameInvite );
|
||||
// Never returns!
|
||||
}
|
||||
|
||||
#ifdef XBOX_DEMO
|
||||
// Timer code for the demo:
|
||||
static int lastTime = 0;
|
||||
static bool demoTimerPaused = false;
|
||||
|
||||
// Notify the demo timer of a keypress, which resets the timer, and ensures
|
||||
// that the timer no longer runs during FMV/loading (if it was before)
|
||||
void Demo_TimerKeypress( void )
|
||||
{
|
||||
demoTimerAlways = false;
|
||||
|
||||
// Reset the timer:
|
||||
demoTimer = demoLaunchData.dwTimeout;
|
||||
|
||||
// Stamp the diff-timer
|
||||
lastTime = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
// Update the timer, and check to see if we should reboot:
|
||||
void Demo_TimerUpdate( void )
|
||||
{
|
||||
// Handle first call correctly
|
||||
if( !lastTime )
|
||||
{
|
||||
demoTimer = demoLaunchData.dwTimeout;
|
||||
lastTime = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
int newTime = Sys_Milliseconds();
|
||||
int diffTime = newTime - lastTime;
|
||||
lastTime = newTime;
|
||||
|
||||
// If the timer isn't supposed to run, and we're "paused", don't update:
|
||||
extern bool in_camera;
|
||||
if( !demoTimerAlways && (demoTimerPaused || in_camera) )
|
||||
return;
|
||||
|
||||
// If we weren't even launched by CDX in the first place, or were given
|
||||
// a zero timeout, do nothing:
|
||||
if( !demoLaunchDataValid || !demoLaunchData.dwTimeout )
|
||||
return;
|
||||
|
||||
// Time ran out?
|
||||
if( demoTimer < diffTime )
|
||||
Sys_Reboot( "demo", NULL );
|
||||
|
||||
demoTimer -= diffTime;
|
||||
}
|
||||
|
||||
// Pause/unpause the demo timer when entering/exiting non-interactive state:
|
||||
void Demo_TimerPause( bool bPaused )
|
||||
{
|
||||
// Always stamp the timer right before we change state:
|
||||
Demo_TimerUpdate();
|
||||
|
||||
demoTimerPaused = bPaused;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
WinMain
|
||||
|
||||
==================
|
||||
*/
|
||||
#if defined (_XBOX)
|
||||
int __cdecl main()
|
||||
#elif defined (_GAMECUBE)
|
||||
int main(int argc, char* argv[])
|
||||
#endif
|
||||
{
|
||||
// Z_SetFreeOSMem();
|
||||
|
||||
// I'm going to kill someone. This should not be necessary. No, really.
|
||||
Direct3D_SetPushBufferSize(1024*1024, 128*1024);
|
||||
|
||||
// get the initial time base
|
||||
Sys_Milliseconds();
|
||||
|
||||
// Need to fetch this stuff REALLY early so that path re-mappnig works
|
||||
// for renderer startup. Bleh.
|
||||
Sys_QuickStart();
|
||||
|
||||
Win_Init();
|
||||
Com_Init( "" );
|
||||
|
||||
// Run one frame, to finish loading (calls CL_StartHunkUsers)...
|
||||
IN_Frame();
|
||||
Com_Frame();
|
||||
|
||||
extern void G_AllocGentities( void );
|
||||
G_AllocGentities();
|
||||
|
||||
// And then quickly copy all the planet binks to the Z: drive
|
||||
extern void Sys_BinkCopyInit(void);
|
||||
Sys_BinkCopyInit();
|
||||
|
||||
// main game loop
|
||||
while( 1 ) {
|
||||
IN_Frame();
|
||||
Com_Frame();
|
||||
|
||||
// Poll debug console for new commands
|
||||
#ifndef FINAL_BUILD
|
||||
DebugConsoleHandleCommands();
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *Sys_GetClipboardData(void) { return NULL; }
|
||||
|
||||
void Sys_StartProcess(char *, qboolean) {}
|
||||
|
||||
void Sys_OpenURL(char *, int) {}
|
||||
|
||||
void Sys_Quit(void) {}
|
||||
|
||||
void Sys_ShowConsole(int, int) {}
|
||||
|
||||
void Sys_Mkdir(const char *) {}
|
||||
|
||||
int Sys_LowPhysicalMemory(void) { return 0; }
|
||||
|
||||
void Sys_FreeFileList(char **filelist)
|
||||
{
|
||||
// All strings in a file list are allocated at once, so we just need to
|
||||
// do two frees, one for strings, one for the pointers.
|
||||
if ( filelist )
|
||||
{
|
||||
if ( filelist[0] )
|
||||
Z_Free( filelist[0] );
|
||||
|
||||
Z_Free( filelist );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _JK2MP
|
||||
char** Sys_ListFiles(const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs)
|
||||
#else
|
||||
char** Sys_ListFiles(const char *directory, const char *extension, int *numfiles, qboolean wantsubs)
|
||||
#endif
|
||||
{
|
||||
#ifdef _JK2MP
|
||||
// MP has extra filter paramter. We don't support that.
|
||||
if (filter)
|
||||
{
|
||||
assert(!"Sys_ListFiles doesn't support filter on console!");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Hax0red console version of Sys_ListFiles. We mangle our arguments to get a standard filename
|
||||
// That file should exist, and contain the list of files that meet this search criteria.
|
||||
char listFilename[MAX_OSPATH];
|
||||
char *listFile, *curFile, *end;
|
||||
int nfiles;
|
||||
char **retList;
|
||||
|
||||
// S00per hack
|
||||
#ifdef XBOX_DEMO
|
||||
const char *basePath = Sys_RemapPath( "base\\" );
|
||||
if (strstr(directory, basePath))
|
||||
directory += strlen( basePath );
|
||||
#else
|
||||
if (strstr(directory, "d:\\base\\"))
|
||||
directory += 8;
|
||||
#endif
|
||||
|
||||
if (!extension)
|
||||
{
|
||||
extension = "";
|
||||
}
|
||||
else if (extension[0] == '/' && extension[1] == 0)
|
||||
{
|
||||
// Passing a slash as extension will find directories
|
||||
extension = "dir";
|
||||
}
|
||||
else if (extension[0] == '.')
|
||||
{
|
||||
// Skip over leading .
|
||||
extension++;
|
||||
}
|
||||
|
||||
// Build our filename
|
||||
Com_sprintf(listFilename, sizeof(listFilename), "%s\\_console_%s_list_", directory, extension);
|
||||
if (FS_ReadFile( listFilename, (void**)&listFile ) <= 0)
|
||||
{
|
||||
if(listFile) {
|
||||
FS_FreeFile(listFile);
|
||||
}
|
||||
Com_Printf( "WARNING: List file %s not found\n", listFilename );
|
||||
if (numfiles)
|
||||
*numfiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do a first pass to count number of files in the list
|
||||
nfiles = 0;
|
||||
curFile = listFile;
|
||||
while (true)
|
||||
{
|
||||
// Find end of line
|
||||
end = strchr(curFile, '\r');
|
||||
if (end)
|
||||
{
|
||||
// Should have a \n next -- skip them both
|
||||
end += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = strchr(curFile, '\n');
|
||||
if (end) end++;
|
||||
else end = curFile + strlen(curFile);
|
||||
}
|
||||
|
||||
// Is the line empty? If so, we're done.
|
||||
if (!curFile || !curFile[0]) break;
|
||||
++nfiles;
|
||||
|
||||
// Advance to next line
|
||||
curFile = end;
|
||||
}
|
||||
|
||||
// Fill in caller's pointer for number of files found
|
||||
if (numfiles) *numfiles = nfiles;
|
||||
|
||||
// Did we find any files at all?
|
||||
if (nfiles == 0)
|
||||
{
|
||||
FS_FreeFile(listFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate a file list, and quick string pool, but use LISTFILES
|
||||
retList = (char **) Z_Malloc( ( nfiles + 1 ) * sizeof( *retList ), TAG_LISTFILES, qfalse);
|
||||
// Our string pool is actually slightly too large, but it's temporary, and that's better
|
||||
// than slightly too small
|
||||
char *stringPool = (char *) Z_Malloc( strlen(listFile) + 1, TAG_LISTFILES, qfalse );
|
||||
|
||||
// Now go through the list of files again, and fill in the list to be returned
|
||||
nfiles = 0;
|
||||
curFile = listFile;
|
||||
while (true)
|
||||
{
|
||||
// Find end of line
|
||||
end = strchr(curFile, '\r');
|
||||
if (end)
|
||||
{
|
||||
// Should have a \n next -- skip them both
|
||||
*end++ = '\0';
|
||||
*end++ = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
end = strchr(curFile, '\n');
|
||||
if (end) *end++ = '\0';
|
||||
else end = curFile + strlen(curFile);
|
||||
}
|
||||
|
||||
// Is the line empty? If so, we're done.
|
||||
int curStrSize = strlen(curFile);
|
||||
if (curStrSize < 1)
|
||||
{
|
||||
retList[nfiles] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Alloc a small copy
|
||||
//retList[nfiles++] = CopyString( curFile );
|
||||
retList[nfiles++] = stringPool;
|
||||
strcpy(stringPool, curFile);
|
||||
stringPool += (curStrSize + 1);
|
||||
|
||||
// Advance to next line
|
||||
curFile = end;
|
||||
}
|
||||
|
||||
// Free the special file's buffer
|
||||
FS_FreeFile( listFile );
|
||||
|
||||
return retList;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_UnloadGame
|
||||
=================
|
||||
*/
|
||||
void Sys_UnloadGame( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_GetGameAPI
|
||||
|
||||
Loads the game dll
|
||||
=================
|
||||
*/
|
||||
#ifndef _JK2MP
|
||||
void *Sys_GetGameAPI (void *parms)
|
||||
{
|
||||
extern game_export_t *GetGameAPI( game_import_t *import );
|
||||
return GetGameAPI((game_import_t *)parms);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_LoadCgame
|
||||
|
||||
Used to hook up a development dll
|
||||
=================
|
||||
*/
|
||||
// void * Sys_LoadCgame( void )
|
||||
#ifndef _JK2MP
|
||||
void * Sys_LoadCgame( int (**entryPoint)(int, ...), int (*systemcalls)(int, ...) )
|
||||
{
|
||||
extern void CG_PreInit();
|
||||
extern void cg_dllEntry( int (*syscallptr)( int arg,... ) );
|
||||
extern int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7 );
|
||||
cg_dllEntry(systemcalls);
|
||||
*entryPoint = (int (*)(int,...))vmMain;
|
||||
// CG_PreInit();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* VVFIXME: More stubs */
|
||||
qboolean Sys_FileOutOfDate( LPCSTR psFinalFileName /* dest */, LPCSTR psDataFileName /* src */ )
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean Sys_CopyFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, qboolean bOverwrite)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
qboolean Sys_CheckCD( void )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
1342
code/win32/win_qal_xbox.cpp
Normal file
1342
code/win32/win_qal_xbox.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4276
code/win32/win_qgl.cpp
Normal file
4276
code/win32/win_qgl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
6963
code/win32/win_qgl_dx8.cpp
Normal file
6963
code/win32/win_qgl_dx8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
281
code/win32/win_shared.cpp
Normal file
281
code/win32/win_shared.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../game/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "win_local.h"
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
================
|
||||
*/
|
||||
int Sys_Milliseconds (void)
|
||||
{
|
||||
static int sys_timeBase = timeGetTime();
|
||||
int sys_curtime;
|
||||
|
||||
sys_curtime = timeGetTime() - sys_timeBase;
|
||||
|
||||
return sys_curtime;
|
||||
}
|
||||
|
||||
/*
|
||||
** --------------------------------------------------------------------------------
|
||||
**
|
||||
** PROCESSOR STUFF
|
||||
**
|
||||
** --------------------------------------------------------------------------------
|
||||
*/
|
||||
static inline void CPUID( int func, unsigned int regs[4] )
|
||||
{
|
||||
unsigned regEAX, regEBX, regECX, regEDX;
|
||||
|
||||
__asm mov eax, func
|
||||
__asm __emit 00fh
|
||||
__asm __emit 0a2h
|
||||
__asm mov regEAX, eax
|
||||
__asm mov regEBX, ebx
|
||||
__asm mov regECX, ecx
|
||||
__asm mov regEDX, edx
|
||||
|
||||
regs[0] = regEAX;
|
||||
regs[1] = regEBX;
|
||||
regs[2] = regECX;
|
||||
regs[3] = regEDX;
|
||||
}
|
||||
|
||||
static int IsPentium( void )
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushfd // save eflags
|
||||
pop eax
|
||||
test eax, 0x00200000 // check ID bit
|
||||
jz set21 // bit 21 is not set, so jump to set_21
|
||||
and eax, 0xffdfffff // clear bit 21
|
||||
push eax // save new value in register
|
||||
popfd // store new value in flags
|
||||
pushfd
|
||||
pop eax
|
||||
test eax, 0x00200000 // check ID bit
|
||||
jz good
|
||||
jmp err // cpuid not supported
|
||||
set21:
|
||||
or eax, 0x00200000 // set ID bit
|
||||
push eax // store new value
|
||||
popfd // store new value in EFLAGS
|
||||
pushfd
|
||||
pop eax
|
||||
test eax, 0x00200000 // if bit 21 is on
|
||||
jnz good
|
||||
jmp err
|
||||
}
|
||||
|
||||
err:
|
||||
return qfalse;
|
||||
good:
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
static int Is3DNOW( void )
|
||||
{
|
||||
unsigned regs[4];
|
||||
char pstring[16];
|
||||
char processorString[13];
|
||||
|
||||
// get name of processor
|
||||
CPUID( 0, ( unsigned int * ) pstring );
|
||||
processorString[0] = pstring[4];
|
||||
processorString[1] = pstring[5];
|
||||
processorString[2] = pstring[6];
|
||||
processorString[3] = pstring[7];
|
||||
processorString[4] = pstring[12];
|
||||
processorString[5] = pstring[13];
|
||||
processorString[6] = pstring[14];
|
||||
processorString[7] = pstring[15];
|
||||
processorString[8] = pstring[8];
|
||||
processorString[9] = pstring[9];
|
||||
processorString[10] = pstring[10];
|
||||
processorString[11] = pstring[11];
|
||||
processorString[12] = 0;
|
||||
|
||||
// REMOVED because you can have 3DNow! on non-AMD systems
|
||||
// if ( strcmp( processorString, "AuthenticAMD" ) )
|
||||
// return qfalse;
|
||||
|
||||
// check AMD-specific functions
|
||||
CPUID( 0x80000000, regs );
|
||||
if ( regs[0] < 0x80000000 )
|
||||
return qfalse;
|
||||
|
||||
// bit 31 of EDX denotes 3DNOW! support
|
||||
CPUID( 0x80000001, regs );
|
||||
if ( regs[3] & ( 1 << 31 ) )
|
||||
return qtrue;
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int IsKNI( void )
|
||||
{
|
||||
unsigned regs[4];
|
||||
|
||||
// get CPU feature bits
|
||||
CPUID( 1, regs );
|
||||
|
||||
// bit 25 of EDX denotes KNI existence
|
||||
if ( regs[3] & ( 1 << 25 ) )
|
||||
{
|
||||
// Ok, CPU supports this instruction, but does the OS?
|
||||
//
|
||||
// Test a KNI instruction and make sure you don't get an exception...
|
||||
//
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad;
|
||||
// orps xmm1,xmm1; // Below are the op codes for this instruction
|
||||
// emits will compile w/ MSVC 5.0 compiler
|
||||
// You can comment these out and uncomment the
|
||||
// orps when using the Intel Compiler
|
||||
__emit 0x0f
|
||||
__emit 0x56
|
||||
__emit 0xc9
|
||||
popad;
|
||||
}
|
||||
}// If OS creates an exception, it doesn't support Pentium III Instructions
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int IsWIL( void )
|
||||
{
|
||||
unsigned regs[4];
|
||||
|
||||
// get CPU feature bits
|
||||
CPUID( 1, regs );
|
||||
|
||||
// bit 26 of EDX denotes WIL existence
|
||||
if ( regs[3] & ( 1 << 26 ) )
|
||||
{
|
||||
// Ok, CPU supports this instruction, but does the OS?
|
||||
//
|
||||
// Test a WIL instruction and make sure you don't get an exception...
|
||||
//
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad;
|
||||
// xorpd xmm0,xmm0; // Willamette New Instructions
|
||||
__emit 0x0f
|
||||
__emit 0x56
|
||||
__emit 0xc9
|
||||
popad;
|
||||
}
|
||||
}// If OS creates an exception, it doesn't support PentiumIV Instructions
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
// if(_exception_code()==STATUS_ILLEGAL_INSTRUCTION) // forget it, any exception should count as fail for safety
|
||||
return qfalse; // Willamette New Instructions not supported
|
||||
}
|
||||
|
||||
return qtrue; // Williamette/P4 instructions available
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int IsMMX( void )
|
||||
{
|
||||
unsigned int regs[4];
|
||||
|
||||
// get CPU feature bits
|
||||
CPUID( 1, regs );
|
||||
|
||||
// bit 23 of EDX denotes MMX existence
|
||||
if ( regs[3] & ( 1 << 23 ) )
|
||||
return qtrue;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
int Sys_GetProcessorId( void )
|
||||
{
|
||||
#if defined _M_ALPHA
|
||||
return CPUID_AXP;
|
||||
#elif !defined _M_IX86
|
||||
return CPUID_GENERIC;
|
||||
#else
|
||||
|
||||
// verify we're at least a Pentium or 486 w/ CPUID support
|
||||
if ( !IsPentium() )
|
||||
return CPUID_INTEL_UNSUPPORTED;
|
||||
|
||||
// check for MMX
|
||||
if ( !IsMMX() )
|
||||
{
|
||||
// Pentium or PPro
|
||||
return CPUID_INTEL_PENTIUM;
|
||||
}
|
||||
|
||||
// see if we're an AMD 3DNOW! processor
|
||||
if ( Is3DNOW() )
|
||||
{
|
||||
return CPUID_AMD_3DNOW;
|
||||
}
|
||||
|
||||
// see if we're an Intel Katmai
|
||||
if ( IsKNI() )
|
||||
{
|
||||
// if we are, see if we're a Williamette as well...
|
||||
//
|
||||
if ( IsWIL() )
|
||||
{
|
||||
return CPUID_INTEL_WILLIAMETTE;
|
||||
}
|
||||
return CPUID_INTEL_KATMAI;
|
||||
}
|
||||
|
||||
// by default we're functionally a vanilla Pentium/MMX or P2/MMX
|
||||
return CPUID_INTEL_MMX;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//============================================
|
||||
|
||||
char *Sys_GetCurrentUser( void )
|
||||
{
|
||||
#ifdef _XBOX
|
||||
return NULL;
|
||||
#else
|
||||
static char s_userName[1024];
|
||||
unsigned long size = sizeof( s_userName );
|
||||
|
||||
|
||||
if ( !GetUserName( s_userName, &size ) )
|
||||
strcpy( s_userName, "player" );
|
||||
|
||||
if ( !s_userName[0] )
|
||||
{
|
||||
strcpy( s_userName, "player" );
|
||||
}
|
||||
|
||||
return s_userName;
|
||||
#endif
|
||||
}
|
||||
414
code/win32/win_snd.cpp
Normal file
414
code/win32/win_snd.cpp
Normal file
@@ -0,0 +1,414 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "../client/snd_local.h"
|
||||
#include "win_local.h"
|
||||
|
||||
HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter);
|
||||
#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c)
|
||||
|
||||
#define SECONDARY_BUFFER_SIZE 0x10000
|
||||
|
||||
|
||||
extern int s_UseOpenAL;
|
||||
|
||||
static qboolean dsound_init;
|
||||
static int sample16;
|
||||
static DWORD gSndBufSize;
|
||||
static DWORD locksize;
|
||||
static LPDIRECTSOUND pDS;
|
||||
static LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf;
|
||||
static HINSTANCE hInstDS;
|
||||
|
||||
static int SNDDMA_InitDS ();
|
||||
|
||||
static const char *DSoundError( int error ) {
|
||||
switch ( error ) {
|
||||
case DSERR_BUFFERLOST:
|
||||
return "DSERR_BUFFERLOST";
|
||||
case DSERR_INVALIDCALL:
|
||||
return "DSERR_INVALIDCALLS";
|
||||
case DSERR_INVALIDPARAM:
|
||||
return "DSERR_INVALIDPARAM";
|
||||
case DSERR_PRIOLEVELNEEDED:
|
||||
return "DSERR_PRIOLEVELNEEDED";
|
||||
case DSERR_ALLOCATED:
|
||||
return "DSERR_ALLOCATED";
|
||||
case DSERR_UNINITIALIZED:
|
||||
return "DSERR_UNINITIALIZED";
|
||||
case DSERR_UNSUPPORTED:
|
||||
return "DSERR_UNSUPPORTED ";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_Shutdown
|
||||
==================
|
||||
*/
|
||||
void SNDDMA_Shutdown( void ) {
|
||||
Com_DPrintf( "Shutting down sound system\n" );
|
||||
|
||||
if ( pDS ) {
|
||||
Com_DPrintf( "Destroying DS buffers\n" );
|
||||
if ( pDS )
|
||||
{
|
||||
Com_DPrintf( "...setting NORMAL coop level\n" );
|
||||
pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_NORMAL );
|
||||
}
|
||||
|
||||
if ( pDSBuf )
|
||||
{
|
||||
Com_DPrintf( "...stopping and releasing sound buffer\n" );
|
||||
pDSBuf->Stop( );
|
||||
pDSBuf->Release( );
|
||||
}
|
||||
|
||||
// only release primary buffer if it's not also the mixing buffer we just released
|
||||
if ( pDSPBuf && ( pDSBuf != pDSPBuf ) )
|
||||
{
|
||||
Com_DPrintf( "...releasing primary buffer\n" );
|
||||
pDSPBuf->Release( );
|
||||
}
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
|
||||
dma.buffer = NULL;
|
||||
|
||||
Com_DPrintf( "...releasing DS object\n" );
|
||||
pDS->Release( );
|
||||
}
|
||||
|
||||
if ( hInstDS ) {
|
||||
Com_DPrintf( "...freeing DSOUND.DLL\n" );
|
||||
FreeLibrary( hInstDS );
|
||||
hInstDS = NULL;
|
||||
}
|
||||
|
||||
pDS = NULL;
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
dsound_init = qfalse;
|
||||
memset ((void *)&dma, 0, sizeof (dma));
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_Init
|
||||
|
||||
Initialize direct sound
|
||||
Returns false if failed
|
||||
==================
|
||||
*/
|
||||
qboolean SNDDMA_Init(void) {
|
||||
|
||||
memset ((void *)&dma, 0, sizeof (dma));
|
||||
dsound_init = qfalse;
|
||||
|
||||
if ( !SNDDMA_InitDS () ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
dsound_init = qtrue;
|
||||
|
||||
Com_DPrintf("Completed successfully\n" );
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
||||
static int SNDDMA_InitDS ()
|
||||
{
|
||||
HRESULT hresult;
|
||||
qboolean pauseTried;
|
||||
DSBUFFERDESC dsbuf;
|
||||
DSBCAPS dsbcaps;
|
||||
WAVEFORMATEX format;
|
||||
|
||||
Com_Printf( "Initializing DirectSound\n");
|
||||
|
||||
if ( !hInstDS ) {
|
||||
Com_DPrintf( "...loading dsound.dll: " );
|
||||
|
||||
hInstDS = LoadLibrary("dsound.dll");
|
||||
|
||||
if ( hInstDS == NULL ) {
|
||||
Com_Printf ("failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Com_DPrintf ("ok\n");
|
||||
pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *))
|
||||
GetProcAddress(hInstDS,"DirectSoundCreate");
|
||||
|
||||
if ( !pDirectSoundCreate ) {
|
||||
Com_Printf ("*** couldn't get DS proc addr ***\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Com_DPrintf( "...creating DS object: " );
|
||||
pauseTried = qfalse;
|
||||
while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) {
|
||||
if ( hresult != DSERR_ALLOCATED ) {
|
||||
Com_Printf( "failed\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pauseTried ) {
|
||||
Com_Printf ("failed, hardware already in use\n" );
|
||||
return 0;
|
||||
}
|
||||
// first try just waiting five seconds and trying again
|
||||
// this will handle the case of a sysyem beep playing when the
|
||||
// game starts
|
||||
Com_DPrintf ("retrying...\n");
|
||||
Sleep( 3000 );
|
||||
pauseTried = qtrue;
|
||||
}
|
||||
Com_DPrintf( "ok\n" );
|
||||
|
||||
Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );
|
||||
|
||||
if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) ) {
|
||||
Com_Printf ("failed\n");
|
||||
SNDDMA_Shutdown ();
|
||||
return qfalse;
|
||||
}
|
||||
Com_DPrintf("ok\n" );
|
||||
|
||||
|
||||
// create the secondary buffer we'll actually work with
|
||||
dma.channels = 2;
|
||||
dma.samplebits = 16;
|
||||
|
||||
if (s_khz->integer == 44)
|
||||
dma.speed = 44100;
|
||||
else if (s_khz->integer == 22)
|
||||
dma.speed = 22050;
|
||||
else
|
||||
dma.speed = 11025;
|
||||
|
||||
memset (&format, 0, sizeof(format));
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = dma.channels;
|
||||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.cbSize = 0;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign;
|
||||
|
||||
memset (&dsbuf, 0, sizeof(dsbuf));
|
||||
dsbuf.dwSize = sizeof(DSBUFFERDESC);
|
||||
|
||||
#define idDSBCAPS_GETCURRENTPOSITION2 0x00010000
|
||||
|
||||
dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE | idDSBCAPS_GETCURRENTPOSITION2;
|
||||
dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
|
||||
dsbuf.lpwfxFormat = &format;
|
||||
|
||||
Com_DPrintf( "...creating secondary buffer: " );
|
||||
hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL);
|
||||
if (hresult != DS_OK)
|
||||
{
|
||||
if ( hresult == DSERR_CONTROLUNAVAIL )
|
||||
{
|
||||
Com_Printf( " - Ancient version of DirectX - this will slow FPS\n" );
|
||||
dsbuf.dwFlags &= ~idDSBCAPS_GETCURRENTPOSITION2; // lose this DX8 cursor-position feature, and try again
|
||||
hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL);
|
||||
}
|
||||
|
||||
if (hresult != DS_OK)
|
||||
{
|
||||
// we can't even specify sounds should be in hardware?...
|
||||
//
|
||||
// ( this seems to happen on integrated sound devices (eg SoundMax), regardless of DX version )
|
||||
//
|
||||
dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY; // note that DX docs say that this can still use hardware if it wants to, since neither DSBCAPS_LOCHARDWARE nor DSBCAPS_LOCSOFTWARE were specified
|
||||
hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL);
|
||||
if (hresult != DS_OK) {
|
||||
Com_Printf( "failed to create secondary buffer - %s\n", DSoundError( hresult ) );
|
||||
SNDDMA_Shutdown ();
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
Com_Printf( "locked hardware. ok\n" );
|
||||
|
||||
// Make sure mixer is active
|
||||
if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) {
|
||||
Com_Printf ("*** Looped sound play failed ***\n");
|
||||
SNDDMA_Shutdown ();
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
memset(&dsbcaps, 0, sizeof(dsbcaps));
|
||||
dsbcaps.dwSize = sizeof(dsbcaps);
|
||||
// get the returned buffer size
|
||||
if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
|
||||
Com_Printf ("*** GetCaps failed ***\n");
|
||||
SNDDMA_Shutdown ();
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
gSndBufSize = dsbcaps.dwBufferBytes;
|
||||
|
||||
dma.channels = format.nChannels;
|
||||
dma.samplebits = format.wBitsPerSample;
|
||||
dma.speed = format.nSamplesPerSec;
|
||||
dma.samples = gSndBufSize/(dma.samplebits/8);
|
||||
dma.submission_chunk = 1;
|
||||
dma.buffer = NULL; // must be locked first
|
||||
|
||||
sample16 = (dma.samplebits/8) - 1;
|
||||
|
||||
SNDDMA_BeginPainting ();
|
||||
if (dma.buffer)
|
||||
memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
|
||||
SNDDMA_Submit ();
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
==============
|
||||
SNDDMA_GetDMAPos
|
||||
|
||||
return the current sample position (in mono samples read)
|
||||
inside the recirculating dma buffer, so the mixing code will know
|
||||
how many sample are required to fill it up.
|
||||
===============
|
||||
*/
|
||||
int SNDDMA_GetDMAPos( void ) {
|
||||
MMTIME mmtime;
|
||||
int s;
|
||||
DWORD dwWrite;
|
||||
|
||||
if ( !dsound_init ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mmtime.wType = TIME_SAMPLES;
|
||||
pDSBuf->GetCurrentPosition(&mmtime.u.sample, &dwWrite);
|
||||
|
||||
s = mmtime.u.sample;
|
||||
|
||||
s >>= sample16;
|
||||
|
||||
s &= (dma.samples-1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_BeginPainting
|
||||
|
||||
Makes sure dma.buffer is valid
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_BeginPainting( void ) {
|
||||
int reps;
|
||||
DWORD dwSize2;
|
||||
DWORD *pbuf, *pbuf2;
|
||||
HRESULT hresult;
|
||||
DWORD dwStatus;
|
||||
|
||||
if ( !pDSBuf ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the buffer was lost or stopped, restore it and/or restart it
|
||||
if ( pDSBuf->GetStatus (&dwStatus) != DS_OK ) {
|
||||
Com_Printf ("Couldn't get sound buffer status\n");
|
||||
}
|
||||
|
||||
if (dwStatus & DSBSTATUS_BUFFERLOST)
|
||||
pDSBuf->Restore ();
|
||||
|
||||
if (!(dwStatus & DSBSTATUS_PLAYING))
|
||||
pDSBuf->Play(0, 0, DSBPLAY_LOOPING);
|
||||
|
||||
// lock the dsound buffer
|
||||
|
||||
reps = 0;
|
||||
dma.buffer = NULL;
|
||||
|
||||
while ((hresult = pDSBuf->Lock(0, gSndBufSize, (void **)&pbuf, &locksize,
|
||||
(void **)&pbuf2, &dwSize2, 0)) != DS_OK)
|
||||
{
|
||||
if (hresult != DSERR_BUFFERLOST)
|
||||
{
|
||||
Com_Printf( "SNDDMA_BeginPainting: Lock failed with error '%s'\n", DSoundError( hresult ) );
|
||||
S_Shutdown ();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDSBuf->Restore( );
|
||||
}
|
||||
|
||||
if (++reps > 2)
|
||||
return;
|
||||
}
|
||||
dma.buffer = (unsigned char *)pbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
Also unlocks the dsound buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit( void ) {
|
||||
// unlock the dsound buffer
|
||||
if ( pDSBuf ) {
|
||||
pDSBuf->Unlock(dma.buffer, locksize, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SNDDMA_Activate
|
||||
|
||||
When we change windows we need to do this
|
||||
=================
|
||||
*/
|
||||
void SNDDMA_Activate( qboolean bAppActive )
|
||||
{
|
||||
if (s_UseOpenAL)
|
||||
{
|
||||
S_AL_MuteAllSounds(!bAppActive);
|
||||
}
|
||||
|
||||
if ( !pDS ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) ) {
|
||||
Com_Printf ("sound SetCooperativeLevel failed\n");
|
||||
SNDDMA_Shutdown ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// I know this is a bit horrible, but I need to pass our LPDIRECTSOUND ptr to Bink for video playback,
|
||||
// and I don't want other modules to have to know about LPDIRECTSOUND handles, hence the int casting
|
||||
//
|
||||
// (I'd prefer to use DWORD, but not all modules understand those)
|
||||
//
|
||||
unsigned int SNDDMA_GetDSHandle(void)
|
||||
{
|
||||
return (unsigned int) pDS;
|
||||
}
|
||||
|
||||
|
||||
474
code/win32/win_stencilshadow.cpp
Normal file
474
code/win32/win_stencilshadow.cpp
Normal file
@@ -0,0 +1,474 @@
|
||||
//
|
||||
//
|
||||
// win_stencilshadow.cpp
|
||||
//
|
||||
// Stencil shadow computation/rendering
|
||||
//
|
||||
//
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "../renderer/tr_local.h"
|
||||
#include "../renderer/tr_lightmanager.h"
|
||||
#include "glw_win_dx8.h"
|
||||
#include "win_local.h"
|
||||
|
||||
#include "win_stencilshadow.h"
|
||||
|
||||
#include <xgraphics.h>
|
||||
#include <xgmath.h>
|
||||
|
||||
#include "shader_constants.h"
|
||||
|
||||
|
||||
|
||||
StencilShadow StencilShadower;
|
||||
|
||||
|
||||
StencilShadow::StencilShadow()
|
||||
{
|
||||
m_dwVertexShaderShadow = 0;
|
||||
|
||||
for(int i = 0; i < SHADER_MAX_VERTEXES / 2; i++)
|
||||
{
|
||||
m_extrusionIndicators[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StencilShadow::~StencilShadow()
|
||||
{
|
||||
if(m_dwVertexShaderShadow)
|
||||
glw_state->device->DeleteVertexShader(m_dwVertexShaderShadow);
|
||||
}
|
||||
|
||||
extern const char *Sys_RemapPath( const char *filename );
|
||||
|
||||
bool StencilShadow::Initialize()
|
||||
{
|
||||
// Create a vertex shader
|
||||
DWORD dwVertexDecl[] =
|
||||
{
|
||||
D3DVSD_STREAM( 0 ),
|
||||
D3DVSD_REG( 0, D3DVSDT_FLOAT3 ), // v0 = Position
|
||||
D3DVSD_REG( 1, D3DVSDT_FLOAT1 ), // v1 = Extrusion determinant
|
||||
D3DVSD_END()
|
||||
};
|
||||
|
||||
if(!( CreateVertexShader(Sys_RemapPath("base\\media\\shadow.xvu"), dwVertexDecl, &m_dwVertexShaderShadow)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void StencilShadow::AddEdge( unsigned short i1, unsigned short i2, byte facing )
|
||||
{
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
int c;
|
||||
|
||||
c = m_numEdgeDefs[ i1 ];
|
||||
if ( c == MAX_EDGE_DEFS )
|
||||
{
|
||||
Com_Printf("WARNING: MAX_EDGE_DEFS overflow!\n");
|
||||
return; // overflow
|
||||
}
|
||||
m_edgeDefs[ i1 ][ c ].i2 = i2;
|
||||
m_edgeDefs[ i1 ][ c ].facing = facing;
|
||||
|
||||
m_numEdgeDefs[ i1 ]++;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void StencilShadow::BuildEdges()
|
||||
{
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
int i;
|
||||
int c;
|
||||
int j;
|
||||
unsigned short i2;
|
||||
int numTris;
|
||||
unsigned short o1, o2, o3;
|
||||
|
||||
int hit[2];
|
||||
int c2, k;
|
||||
|
||||
// an edge is NOT a silhouette edge if its face doesn't face the light,
|
||||
// or if it has a reverse paired edge that also faces the light.
|
||||
// A well behaved polyhedron would have exactly two faces for each edge,
|
||||
// but lots of models have dangling edges or overfanned edges
|
||||
m_nIndexes = 0;
|
||||
m_nIndexesCap = 0;
|
||||
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ )
|
||||
{
|
||||
c = m_numEdgeDefs[ i ];
|
||||
for ( j = 0 ; j < c ; j++ )
|
||||
{
|
||||
if ( !m_edgeDefs[ i ][ j ].facing )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*i2 = m_edgeDefs[ i ][ j ].i2;
|
||||
|
||||
m_shadowIndexes[m_nIndexes++] = i;
|
||||
m_shadowIndexes[m_nIndexes++] = i + tess.numVertexes;
|
||||
m_shadowIndexes[m_nIndexes++] = i2 + tess.numVertexes;
|
||||
m_shadowIndexes[m_nIndexes++] = i2;*/
|
||||
|
||||
hit[0] = 0;
|
||||
hit[1] = 0;
|
||||
|
||||
i2 = m_edgeDefs[ i ][ j ].i2;
|
||||
c2 = m_numEdgeDefs[ i2 ];
|
||||
for ( k = 0 ; k < c2 ; k++ ) {
|
||||
if ( m_edgeDefs[ i2 ][ k ].i2 == i ) {
|
||||
hit[ m_edgeDefs[ i2 ][ k ].facing ]++;
|
||||
}
|
||||
}
|
||||
|
||||
// if it doesn't share the edge with another front facing
|
||||
// triangle, it is a sil edge
|
||||
if ( hit[ 1 ] == 0 ) {
|
||||
m_shadowIndexes[m_nIndexes++] = i;
|
||||
m_shadowIndexes[m_nIndexes++] = i + tess.numVertexes;
|
||||
m_shadowIndexes[m_nIndexes++] = i2 + tess.numVertexes;
|
||||
m_shadowIndexes[m_nIndexes++] = i2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_nIndexes)
|
||||
return;
|
||||
|
||||
#ifdef _STENCIL_REVERSE
|
||||
//Carmack Reverse<tm> method requires that volumes
|
||||
//be capped properly -rww
|
||||
numTris = tess.numIndexes / 3;
|
||||
|
||||
for ( i = 0 ; i < numTris ; i++ )
|
||||
{
|
||||
if ( !m_facing[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
o1 = tess.indexes[ i*3 + 0 ];
|
||||
o2 = tess.indexes[ i*3 + 1 ];
|
||||
o3 = tess.indexes[ i*3 + 2 ];
|
||||
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o1;
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o2;
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o3;
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o3 + tess.numVertexes;
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o2 + tess.numVertexes;
|
||||
m_shadowIndexesCap[m_nIndexesCap++] = o1 + tess.numVertexes;
|
||||
}
|
||||
#endif // _STENCIL_REVERSE
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool StencilShadow::BuildFromLight()
|
||||
{
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
int i;
|
||||
int numTris;
|
||||
vec3_t lightDir, ground;
|
||||
float d;
|
||||
|
||||
// we can only do this if we have enough space in the vertex buffers
|
||||
if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//controlled method - try to keep shadows in range so they don't show through so much -rww
|
||||
//VectorCopy( backEnd.currentEntity->shadowDir, lightDir );
|
||||
//
|
||||
//ground[0] = backEnd.ori.axis[0][2];
|
||||
//ground[1] = backEnd.ori.axis[1][2];
|
||||
//ground[2] = backEnd.ori.axis[2][2];
|
||||
|
||||
//d = DotProduct( lightDir, ground );
|
||||
//// don't let the shadows get too long or go negative
|
||||
//if ( d < 0.8 ) {
|
||||
// VectorMA( lightDir, (0.8 - d), ground, lightDir );
|
||||
// d = DotProduct( lightDir, ground );
|
||||
//}
|
||||
//d = 1.0 / d;
|
||||
|
||||
//lightDir[0] = lightDir[0] * d;
|
||||
//lightDir[1] = lightDir[1] * d;
|
||||
//lightDir[2] = lightDir[2] * d;
|
||||
|
||||
//VectorNormalize(lightDir);
|
||||
|
||||
vec3_t entLight;
|
||||
VectorCopy( backEnd.currentEntity->lightDir, entLight );
|
||||
entLight[2] = 0.0f;
|
||||
VectorNormalize(entLight);
|
||||
|
||||
//Oh well, just cast them straight down no matter what onto the ground plane.
|
||||
//This presets no chance of screwups and still looks better than a stupid
|
||||
//shader blob.
|
||||
VectorSet(lightDir, entLight[0]*0.3f, entLight[1]*0.3f, 1.0f);
|
||||
|
||||
|
||||
// Set the vertex shader constants
|
||||
D3DXVECTOR4 light = D3DXVECTOR4(lightDir[0], lightDir[1], lightDir[2], 1.0f);
|
||||
glw_state->device->SetVertexShaderConstant( CV_LIGHT_DIRECTION, light, 1 );
|
||||
|
||||
glw_state->device->SetVertexShaderConstant( CV_SHADOW_FACTORS, D3DXVECTOR4(backEnd.ori.origin[0],
|
||||
backEnd.ori.origin[1],
|
||||
backEnd.ori.origin[2],
|
||||
1.0f), 1);
|
||||
glw_state->device->SetVertexShaderConstant( CV_SHADOW_PLANE, D3DXVECTOR4( backEnd.currentEntity->e.shadowPlane - 16.0f,
|
||||
backEnd.currentEntity->e.shadowPlane - 16.0f,
|
||||
backEnd.currentEntity->e.shadowPlane - 16.0f,
|
||||
1.0f), 1);
|
||||
|
||||
// Create a second set of vertices to be projected
|
||||
memcpy(&tess.xyz[tess.numVertexes], &tess.xyz[0], sizeof(vec4_t) * tess.numVertexes);
|
||||
|
||||
// decide which triangles face the light
|
||||
memset( m_numEdgeDefs, 0, sizeof(short) * tess.numVertexes );
|
||||
|
||||
numTris = tess.numIndexes / 3;
|
||||
for ( i = 0 ; i < numTris ; i++ )
|
||||
{
|
||||
short i1, i2, i3;
|
||||
vec3_t d1, d2, normal;
|
||||
float *v1, *v2, *v3;
|
||||
float d;
|
||||
|
||||
i1 = tess.indexes[ i*3 + 0 ];
|
||||
i2 = tess.indexes[ i*3 + 1 ];
|
||||
i3 = tess.indexes[ i*3 + 2 ];
|
||||
|
||||
v1 = tess.xyz[ i1 ];
|
||||
v2 = tess.xyz[ i2 ];
|
||||
v3 = tess.xyz[ i3 ];
|
||||
|
||||
VectorSubtract( v2, v1, d1 );
|
||||
VectorSubtract( v3, v1, d2 );
|
||||
CrossProduct( d1, d2, normal );
|
||||
|
||||
d = DotProduct( normal, lightDir );
|
||||
if ( d > 0 ) {
|
||||
m_facing[ i ] = 1;
|
||||
} else {
|
||||
m_facing[ i ] = 0;
|
||||
}
|
||||
|
||||
// create the edges
|
||||
AddEdge( i1, i2, m_facing[ i ] );
|
||||
AddEdge( i2, i3, m_facing[ i ] );
|
||||
AddEdge( i3, i1, m_facing[ i ] );
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void StencilShadow::RenderShadow()
|
||||
{
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
DWORD lighting, fog, srcblend, destblend, alphablend, zwrite, zfunc, cullmode;
|
||||
|
||||
GL_State(GLS_DEFAULT);
|
||||
|
||||
glw_state->device->GetRenderState( D3DRS_LIGHTING, &lighting );
|
||||
glw_state->device->GetRenderState( D3DRS_FOGENABLE, &fog );
|
||||
glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend );
|
||||
glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend );
|
||||
glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend );
|
||||
glw_state->device->GetRenderState( D3DRS_ZWRITEENABLE, &zwrite );
|
||||
glw_state->device->GetRenderState( D3DRS_ZFUNC, &zfunc );
|
||||
glw_state->device->GetRenderState( D3DRS_CULLMODE, &cullmode );
|
||||
|
||||
pVerts = NULL;
|
||||
pExtrusions = NULL;
|
||||
|
||||
GL_Bind( tr.whiteImage );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
|
||||
|
||||
// Disable z-buffer writes (note: z-testing still occurs), and enable the
|
||||
// stencil-buffer
|
||||
glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILENABLE, TRUE );
|
||||
|
||||
// Don't bother with interpolating color
|
||||
glw_state->device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS );
|
||||
|
||||
// Set up stencil compare function, reference value, and masks.
|
||||
// Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
|
||||
// Note: since we set up the stencil-test to always pass, the STENCILFAIL
|
||||
// renderstate is really not needed.
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
|
||||
#ifdef _STENCIL_REVERSE
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
|
||||
#else
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_INCR );
|
||||
#endif
|
||||
|
||||
// If ztest passes, inc/decrement stencil buffer value
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILREF, 0x1 );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILMASK, 0x7f ); //0xffffffff );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILWRITEMASK, 0x7f ); //0xffffffff );
|
||||
|
||||
// Make sure that no pixels get drawn to the frame buffer
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
||||
glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, 0 );
|
||||
|
||||
glw_state->device->SetTexture(0, NULL);
|
||||
glw_state->device->SetTexture(1, NULL);
|
||||
|
||||
// Compute the matrix set
|
||||
XGMATRIX matComposite, matProjectionViewport, matWorld;
|
||||
glw_state->device->GetProjectionViewportMatrix( &matProjectionViewport );
|
||||
|
||||
XGMatrixMultiply( &matComposite, (XGMATRIX*)glw_state->matrixStack[glwstate_t::MatrixMode_Model]->GetTop(), &matProjectionViewport );
|
||||
|
||||
// Transpose and set the composite matrix.
|
||||
XGMatrixTranspose( &matComposite, &matComposite );
|
||||
glw_state->device->SetVertexShaderConstant( CV_WORLDVIEWPROJ_0, &matComposite, 4 );
|
||||
|
||||
// Set viewport offsets.
|
||||
float fViewportOffsets[4] = { 0.53125f, 0.53125f, 0.0f, 0.0f };
|
||||
glw_state->device->SetVertexShaderConstant( CV_VIEWPORT_OFFSETS, &fViewportOffsets, 1 );
|
||||
|
||||
glw_state->device->SetVertexShader(m_dwVertexShaderShadow);
|
||||
|
||||
#ifdef _STENCIL_REVERSE
|
||||
qglCullFace( GL_FRONT );
|
||||
#else
|
||||
qglCullFace( GL_BACK );
|
||||
#endif
|
||||
|
||||
BuildEdges();
|
||||
|
||||
// Draw front-side of shadow volume in stencil/z only
|
||||
if(m_nIndexes)
|
||||
renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes );
|
||||
#ifdef _STENCIL_REVERSE
|
||||
if(m_nIndexesCap)
|
||||
renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap );
|
||||
#endif
|
||||
|
||||
// Now reverse cull order so back sides of shadow volume are written.
|
||||
#ifdef _STENCIL_REVERSE
|
||||
qglCullFace( GL_BACK );
|
||||
#else
|
||||
qglCullFace( GL_FRONT );
|
||||
#endif
|
||||
|
||||
// Decrement stencil buffer value
|
||||
#ifdef _STENCIL_REVERSE
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR );
|
||||
#else
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
|
||||
#endif
|
||||
|
||||
// Draw back-side of shadow volume in stencil/z only
|
||||
if(m_nIndexes)
|
||||
renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes );
|
||||
#ifdef _STENCIL_REVERSE
|
||||
if(m_nIndexesCap)
|
||||
renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap );
|
||||
#endif
|
||||
|
||||
// Restore render states
|
||||
glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, lighting );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, fog );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend );
|
||||
glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, zwrite );
|
||||
glw_state->device->SetRenderState( D3DRS_ZFUNC, zfunc );
|
||||
glw_state->device->SetRenderState( D3DRS_CULLMODE, cullmode );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void StencilShadow::FinishShadows()
|
||||
{
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
|
||||
DWORD lighting, fog, srcblend, destblend, alphablend;
|
||||
|
||||
glw_state->device->GetRenderState( D3DRS_LIGHTING, &lighting );
|
||||
glw_state->device->GetRenderState( D3DRS_FOGENABLE, &fog );
|
||||
glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend );
|
||||
glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend );
|
||||
glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend );
|
||||
|
||||
// The stencilbuffer values indicates # of shadows that overlap each pixel.
|
||||
// We only want to draw pixels that are in shadow, which was set up in
|
||||
// RenderShadow() such that StencilBufferValue >= 1. In the Direct3D API,
|
||||
// the stencil test is pseudo coded as:
|
||||
// StencilRef CompFunc StencilBufferValue
|
||||
// so we set our renderstates with StencilRef = 1 and CompFunc = LESSEQUAL.
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILENABLE, TRUE );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILREF, 0);//0x1 );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);//D3DCMP_LESSEQUAL );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILMASK, 0x7f ); // New!
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILWRITEMASK, 0x7f ); //255 );
|
||||
|
||||
// Set renderstates (disable z-buffering and turn on alphablending)
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
|
||||
// Set the hardware to draw black, alpha-blending pixels
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
|
||||
glw_state->device->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR );
|
||||
glw_state->device->SetRenderState( D3DRS_TEXTUREFACTOR, 0x50000000 );
|
||||
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
||||
|
||||
// Draw the big, darkening square
|
||||
static FLOAT v[4][4] =
|
||||
{
|
||||
{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f },
|
||||
{ 640 - 0.5f, 0 - 0.5f, 0.0f, 1.0f },
|
||||
{ 640 - 0.5f, 480 - 0.5f, 0.0f, 1.0f },
|
||||
{ 0 - 0.5f, 480 - 0.5f, 0.0f, 1.0f },
|
||||
};
|
||||
|
||||
glw_state->device->SetVertexShader( D3DFVF_XYZRHW );
|
||||
glw_state->device->DrawPrimitiveUP( D3DPT_QUADLIST, 1, v, sizeof(v[0]) );
|
||||
|
||||
// Restore render states
|
||||
glw_state->device->SetRenderState( D3DRS_ZENABLE, TRUE );
|
||||
glw_state->device->SetRenderState( D3DRS_STENCILENABLE, FALSE );
|
||||
glw_state->device->SetRenderState( D3DRS_LIGHTING, lighting );
|
||||
glw_state->device->SetRenderState( D3DRS_FOGENABLE, fog );
|
||||
glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend );
|
||||
glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend );
|
||||
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend );
|
||||
#endif
|
||||
}
|
||||
63
code/win32/win_stencilshadow.h
Normal file
63
code/win32/win_stencilshadow.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
//
|
||||
// win_stencilshadow.h
|
||||
//
|
||||
// Declaration for stencil shadowing class
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _WIN_STENCILSHADOW_H_
|
||||
#define _WIN_STENCILSHADOW_H_
|
||||
|
||||
// Quick way turn off all stencilshadow code, and get back 170k of memory:
|
||||
//#define DISABLE_STENCILSHADOW
|
||||
|
||||
// Enable this to enable Carmack's stencil reverse method
|
||||
#define _STENCIL_REVERSE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// facing is only one bit, but we can't do better than 4 bytes without
|
||||
// packing all the data we need into a single unsigned short, which
|
||||
// isn't really worth it. (unless we REALLY need 64k at some point).
|
||||
unsigned short i2;
|
||||
byte facing;
|
||||
} edgeDef_t;
|
||||
|
||||
#define MAX_EDGE_DEFS 16
|
||||
|
||||
|
||||
class StencilShadow
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef DISABLE_STENCILSHADOW
|
||||
edgeDef_t m_edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS];
|
||||
short m_numEdgeDefs[SHADER_MAX_VERTEXES];
|
||||
byte m_facing[SHADER_MAX_INDEXES/3];
|
||||
unsigned short m_shadowIndexes[SHADER_MAX_INDEXES];
|
||||
unsigned short m_nIndexes;
|
||||
float m_extrusionIndicators[SHADER_MAX_VERTEXES/2];
|
||||
#ifdef _STENCIL_REVERSE
|
||||
unsigned short m_shadowIndexesCap[SHADER_MAX_INDEXES];
|
||||
unsigned short m_nIndexesCap;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
DWORD m_dwVertexShaderShadow;
|
||||
DWORD *pVerts; // For reusing vertices in multiple shadow renderings
|
||||
DWORD *pExtrusions;
|
||||
|
||||
StencilShadow();
|
||||
~StencilShadow();
|
||||
bool Initialize();
|
||||
void AddEdge( unsigned short i1, unsigned short i2, byte facing );
|
||||
void BuildEdges();
|
||||
bool BuildFromLight();
|
||||
void RenderShadow();
|
||||
void FinishShadows();
|
||||
};
|
||||
|
||||
extern StencilShadow StencilShadower;
|
||||
|
||||
#endif
|
||||
511
code/win32/win_stream_dx8.cpp
Normal file
511
code/win32/win_stream_dx8.cpp
Normal file
@@ -0,0 +1,511 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "../zlib/zlib.h"
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(_XBOX)
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
extern void Z_SetNewDeleteTemporary(bool);
|
||||
|
||||
#define STREAM_SLOW_READ 0
|
||||
|
||||
#include "../client/snd_local_console.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
extern HANDLE Sys_FileStreamMutex;
|
||||
extern int Sys_GetFileCodeSize(int code);
|
||||
|
||||
#define STREAM_MAX_OPEN 48
|
||||
struct StreamInfo
|
||||
{
|
||||
unsigned int file;
|
||||
volatile bool used;
|
||||
volatile bool error;
|
||||
volatile bool opening;
|
||||
volatile bool reading;
|
||||
};
|
||||
static StreamInfo* s_Streams = NULL;
|
||||
|
||||
enum IORequestType
|
||||
{
|
||||
IOREQ_OPEN,
|
||||
IOREQ_READ,
|
||||
IOREQ_SHUTDOWN,
|
||||
};
|
||||
|
||||
struct IORequest
|
||||
{
|
||||
IORequestType type;
|
||||
streamHandle_t handle;
|
||||
DWORD data[3];
|
||||
};
|
||||
typedef std::deque<IORequest> requestqueue_t;
|
||||
requestqueue_t* s_IORequestQueue = NULL;
|
||||
|
||||
HANDLE s_Thread = INVALID_HANDLE_VALUE;
|
||||
HANDLE s_QueueMutex = INVALID_HANDLE_VALUE;
|
||||
HANDLE s_QueueLen = INVALID_HANDLE_VALUE;
|
||||
|
||||
|
||||
#include "../qcommon/fixedmap.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
unsigned char filenameFlags;
|
||||
int offset;
|
||||
int size;
|
||||
} sound_file_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static HANDLE soundfile = INVALID_HANDLE_VALUE;
|
||||
static VVFixedMap< sound_file_t, unsigned int >* soundLookup = NULL;
|
||||
|
||||
void Sys_StreamInitialize( void );
|
||||
|
||||
static DWORD WINAPI _streamThread(LPVOID)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
IORequest req;
|
||||
DWORD bytes;
|
||||
StreamInfo* strm;
|
||||
|
||||
// Wait for the IO queue to fill
|
||||
WaitForSingleObject(s_QueueLen, INFINITE);
|
||||
|
||||
// Grab the next IO request
|
||||
WaitForSingleObject(s_QueueMutex, INFINITE);
|
||||
assert(!s_IORequestQueue->empty());
|
||||
req = s_IORequestQueue->front();
|
||||
s_IORequestQueue->pop_front();
|
||||
ReleaseMutex(s_QueueMutex);
|
||||
|
||||
int offset = 0;
|
||||
sound_file_t* crap;
|
||||
|
||||
// Process request
|
||||
switch (req.type)
|
||||
{
|
||||
case IOREQ_OPEN:
|
||||
|
||||
strm = &s_Streams[req.handle];
|
||||
assert(strm->used);
|
||||
|
||||
strm->file = req.data[0];
|
||||
strm->error = (strm->file == -1);
|
||||
strm->opening = false;
|
||||
break;
|
||||
/*
|
||||
{
|
||||
const char* name = Sys_GetFileCodeName(req.data[0]);
|
||||
|
||||
WaitForSingleObject(Sys_FileStreamMutex, INFINITE);
|
||||
|
||||
strm->file =
|
||||
CreateFile(name, GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
ReleaseMutex(Sys_FileStreamMutex);
|
||||
}
|
||||
|
||||
strm->error = (strm->file == INVALID_HANDLE_VALUE);
|
||||
strm->opening = false;
|
||||
break;
|
||||
*/
|
||||
case IOREQ_READ:
|
||||
{
|
||||
strm = &s_Streams[req.handle];
|
||||
assert(strm->used);
|
||||
|
||||
WaitForSingleObject(Sys_FileStreamMutex, INFINITE);
|
||||
|
||||
crap = soundLookup->Find(strm->file);
|
||||
|
||||
if(crap)
|
||||
{
|
||||
offset = crap->offset + req.data[2];
|
||||
strm->error = (SetFilePointer(soundfile, offset, 0, FILE_BEGIN) != offset) ||
|
||||
(ReadFile(soundfile, (void*)req.data[0], req.data[1], &bytes, NULL) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
strm->error = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
strm->error =
|
||||
(SetFilePointer(strm->file, req.data[2], 0, FILE_BEGIN) != req.data[2] ||
|
||||
ReadFile(strm->file, (void*)req.data[0], req.data[1], &bytes, NULL) == 0);
|
||||
*/
|
||||
|
||||
ReleaseMutex(Sys_FileStreamMutex);
|
||||
|
||||
strm->reading = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOREQ_SHUTDOWN:
|
||||
ExitThread(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void _sendIORequest(const IORequest& req)
|
||||
{
|
||||
// Add request to queue
|
||||
WaitForSingleObject(s_QueueMutex, INFINITE);
|
||||
Z_SetNewDeleteTemporary(true);
|
||||
s_IORequestQueue->push_back(req);
|
||||
Z_SetNewDeleteTemporary(false);
|
||||
ReleaseMutex(s_QueueMutex);
|
||||
|
||||
// Let IO thread know it has one more pending request
|
||||
ReleaseSemaphore(s_QueueLen, 1, NULL);
|
||||
}
|
||||
|
||||
void Sys_IORequestQueueClear(void)
|
||||
{
|
||||
WaitForSingleObject(s_QueueMutex, INFINITE);
|
||||
delete s_IORequestQueue;
|
||||
s_IORequestQueue = new requestqueue_t;
|
||||
ReleaseMutex(s_QueueMutex);
|
||||
}
|
||||
|
||||
void Sys_StreamInit(void)
|
||||
{
|
||||
Sys_StreamInitialize();
|
||||
|
||||
// Create array for storing open streams
|
||||
s_Streams = (StreamInfo*)Z_Malloc(
|
||||
STREAM_MAX_OPEN * sizeof(StreamInfo), TAG_FILESYS, qfalse);
|
||||
for (int i = 0; i < STREAM_MAX_OPEN; ++i)
|
||||
{
|
||||
s_Streams[i].used = false;
|
||||
}
|
||||
|
||||
// Create queue to hold requests for IO thread
|
||||
s_IORequestQueue = new requestqueue_t;
|
||||
|
||||
// Create a thread to service IO
|
||||
s_QueueMutex = CreateMutex(NULL, FALSE, NULL);
|
||||
s_QueueLen = CreateSemaphore(NULL, 0, STREAM_MAX_OPEN * 3, NULL);
|
||||
s_Thread = CreateThread(NULL, 64*1024, _streamThread, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void Sys_StreamShutdown(void)
|
||||
{
|
||||
// Tell the IO thread to shutdown
|
||||
IORequest req;
|
||||
req.type = IOREQ_SHUTDOWN;
|
||||
_sendIORequest(req);
|
||||
|
||||
// Wait for thread to close
|
||||
WaitForSingleObject(s_Thread, INFINITE);
|
||||
|
||||
// Kill IO thread
|
||||
CloseHandle(s_Thread);
|
||||
CloseHandle(s_QueueLen);
|
||||
CloseHandle(s_QueueMutex);
|
||||
|
||||
// Remove queue of IO requests
|
||||
delete s_IORequestQueue;
|
||||
|
||||
// Remove streaming table
|
||||
Z_Free(s_Streams);
|
||||
}
|
||||
|
||||
static streamHandle_t GetFreeHandle(void)
|
||||
{
|
||||
for (streamHandle_t i = 1; i < STREAM_MAX_OPEN; ++i)
|
||||
{
|
||||
if (!s_Streams[i].used) return i;
|
||||
}
|
||||
|
||||
// handle 0 is invalid by convention
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Sys_StreamOpen(int code, streamHandle_t *handle)
|
||||
{
|
||||
// Find a free handle
|
||||
*handle = GetFreeHandle();
|
||||
if (*handle == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find the file size
|
||||
sound_file_t* crap = soundLookup->Find(code);
|
||||
int size = -1;
|
||||
if(crap)
|
||||
{
|
||||
size = crap->size;
|
||||
}
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
*handle = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Init stream data
|
||||
s_Streams[*handle].used = true;
|
||||
s_Streams[*handle].opening = true;
|
||||
s_Streams[*handle].reading = false;
|
||||
s_Streams[*handle].error = false;
|
||||
|
||||
// Send an open request to the thread
|
||||
IORequest req;
|
||||
req.type = IOREQ_OPEN;
|
||||
req.handle = *handle;
|
||||
req.data[0] = code;
|
||||
_sendIORequest(req);
|
||||
|
||||
// Return file size
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Sys_StreamRead(void* buffer, int size, int pos, streamHandle_t handle)
|
||||
{
|
||||
assert((unsigned int)buffer % 32 == 0);
|
||||
|
||||
// Handle must be valid. Do not allow multiple reads.
|
||||
if (!s_Streams[handle].used || s_Streams[handle].reading) return false;
|
||||
|
||||
// Ready to read
|
||||
s_Streams[handle].reading = true;
|
||||
s_Streams[handle].error = false;
|
||||
|
||||
// Request IO threading reading
|
||||
IORequest req;
|
||||
req.type = IOREQ_READ;
|
||||
req.handle = handle;
|
||||
req.data[0] = (DWORD)buffer;
|
||||
req.data[1] = size;
|
||||
req.data[2] = pos;
|
||||
_sendIORequest(req);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sys_StreamIsReading(streamHandle_t handle)
|
||||
{
|
||||
return s_Streams[handle].used && s_Streams[handle].reading;
|
||||
}
|
||||
|
||||
bool Sys_StreamIsError(streamHandle_t handle)
|
||||
{
|
||||
return s_Streams[handle].used && s_Streams[handle].error;
|
||||
}
|
||||
|
||||
void Sys_StreamClose(streamHandle_t handle)
|
||||
{
|
||||
if (s_Streams[handle].used)
|
||||
{
|
||||
// Block until read is done
|
||||
while (s_Streams[handle].opening || s_Streams[handle].reading);
|
||||
|
||||
// Close the file
|
||||
// CloseHandle(s_Streams[handle].file);
|
||||
s_Streams[handle].used = false;
|
||||
}
|
||||
}
|
||||
|
||||
extern char* FS_BuildOSPathUnMapped(const char* name);
|
||||
|
||||
unsigned int Sys_GetSoundFileCode(const char* name)
|
||||
{
|
||||
// Get system level path
|
||||
char* osname = FS_BuildOSPathUnMapped(name);
|
||||
|
||||
// Generate hash for file name
|
||||
strlwr(osname);
|
||||
unsigned int code = crc32(0, (const byte *)osname, strlen(osname));
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
unsigned int Sys_GetSoundFileCodeFlags(unsigned int code)
|
||||
{
|
||||
sound_file_t* sf;
|
||||
sf = soundLookup->Find(code);
|
||||
|
||||
if(!sf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sf->filenameFlags;
|
||||
}
|
||||
}
|
||||
|
||||
int Sys_GetSoundFileCodeSize(unsigned int code)
|
||||
{
|
||||
sound_file_t* sf;
|
||||
sf = soundLookup->Find(code);
|
||||
|
||||
if(!sf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sf->size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if PROFILE_SOUND
|
||||
VVFixedMap< char*, unsigned int>* soundCrc = NULL;
|
||||
void Sys_LoadSoundCRCFile( void )
|
||||
{
|
||||
FILE* file;
|
||||
file = fopen("d:\\base\\soundbank\\crclookup.txt", "rb");
|
||||
|
||||
if(!file)
|
||||
return;
|
||||
|
||||
int numberOfLines = 0;
|
||||
unsigned int crc = 0;
|
||||
char name[255];
|
||||
|
||||
// count the number of lines
|
||||
while(1)
|
||||
{
|
||||
if(fscanf(file, "%d %s", &crc, name) == -1)
|
||||
break;
|
||||
numberOfLines++;
|
||||
}
|
||||
|
||||
// allocate memory for the crc lookup
|
||||
soundCrc = new VVFixedMap<char*, unsigned int>(numberOfLines);
|
||||
|
||||
// actually read and store the data
|
||||
fseek(file, 0, SEEK_SET);
|
||||
while(1)
|
||||
{
|
||||
if(fscanf(file, "%d %s", &crc, name) == -1)
|
||||
break;
|
||||
|
||||
char *temp = (char*)Z_Malloc(strlen(name) + 1, TAG_SND_RAWDATA, qtrue);
|
||||
|
||||
strcpy(temp, name);
|
||||
|
||||
soundCrc->Insert(temp, crc);
|
||||
}
|
||||
soundCrc->Sort();
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
char* Sys_GetSoundName( unsigned int crc )
|
||||
{
|
||||
char* name = *soundCrc->Find(crc);
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif // PROFILE_SOUND
|
||||
|
||||
extern const char *Sys_RemapPath( const char *filename );
|
||||
|
||||
void Sys_StreamInitialize( void )
|
||||
{
|
||||
// open the sound file
|
||||
soundfile = CreateFile(
|
||||
Sys_RemapPath("base\\soundbank\\sound.bnk"),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL );
|
||||
|
||||
// fill in the lookup table
|
||||
HANDLE table = INVALID_HANDLE_VALUE;
|
||||
|
||||
table = CreateFile(
|
||||
Sys_RemapPath("base\\soundbank\\sound.tbl"),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL );
|
||||
|
||||
DWORD fileSize = 0;
|
||||
fileSize = GetFileSize(
|
||||
table,
|
||||
NULL);
|
||||
|
||||
int numberOfRecords = fileSize / ((sizeof(unsigned int) * 3) + 1);
|
||||
|
||||
soundLookup = new VVFixedMap<sound_file_t, unsigned int>(numberOfRecords);
|
||||
|
||||
byte* tempData = (byte*)Z_Malloc(fileSize, TAG_TEMP_WORKSPACE, true, 32);
|
||||
byte* restore = tempData;
|
||||
|
||||
DWORD bytesRead;
|
||||
|
||||
ReadFile(
|
||||
table,
|
||||
tempData,
|
||||
fileSize,
|
||||
&bytesRead,
|
||||
NULL );
|
||||
|
||||
if(bytesRead != fileSize)
|
||||
Com_Error(0,"Could not read sound index file.\n");
|
||||
|
||||
CloseHandle(table);
|
||||
|
||||
for(int i = 0; i < numberOfRecords; i++)
|
||||
{
|
||||
unsigned int filecode = *(unsigned int*)tempData;
|
||||
tempData += sizeof(unsigned int);
|
||||
unsigned int offset = *(unsigned int*)tempData;
|
||||
tempData += sizeof(unsigned int);
|
||||
int size = *(int*)tempData;
|
||||
tempData += sizeof(int);
|
||||
unsigned char filenameFlags = *(unsigned char*)tempData;
|
||||
tempData++;
|
||||
|
||||
sound_file_t sfile;
|
||||
sfile.offset = offset;
|
||||
sfile.size = size;
|
||||
sfile.filenameFlags = filenameFlags;
|
||||
|
||||
soundLookup->Insert(sfile, filecode);
|
||||
}
|
||||
|
||||
soundLookup->Sort();
|
||||
Z_Free(restore);
|
||||
#if PROFILE_SOUND
|
||||
Sys_LoadSoundCRCFile();
|
||||
#endif
|
||||
}
|
||||
536
code/win32/win_syscon.cpp
Normal file
536
code/win32/win_syscon.cpp
Normal file
@@ -0,0 +1,536 @@
|
||||
// win_syscon.h
|
||||
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
#include "resource.h"
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
|
||||
#define COPY_ID 1
|
||||
#define QUIT_ID 2
|
||||
#define CLEAR_ID 3
|
||||
|
||||
#define ERRORBOX_ID 10
|
||||
#define ERRORTEXT_ID 11
|
||||
|
||||
#define EDIT_ID 100
|
||||
#define INPUT_ID 101
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HWND hWnd;
|
||||
HWND hwndBuffer;
|
||||
|
||||
HWND hwndButtonClear;
|
||||
HWND hwndButtonCopy;
|
||||
HWND hwndButtonQuit;
|
||||
|
||||
HWND hwndErrorBox;
|
||||
HWND hwndErrorText;
|
||||
|
||||
HBITMAP hbmLogo;
|
||||
HBITMAP hbmClearBitmap;
|
||||
|
||||
HBRUSH hbrEditBackground;
|
||||
HBRUSH hbrErrorBackground;
|
||||
|
||||
HFONT hfBufferFont;
|
||||
HFONT hfButtonFont;
|
||||
|
||||
HWND hwndInputLine;
|
||||
|
||||
char errorString[80];
|
||||
|
||||
char consoleText[512], returnedText[512];
|
||||
int visLevel;
|
||||
qboolean quitOnClose;
|
||||
int windowWidth, windowHeight;
|
||||
|
||||
WNDPROC SysInputLineWndProc;
|
||||
|
||||
} WinConData;
|
||||
|
||||
static WinConData s_wcd;
|
||||
|
||||
static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char *cmdString;
|
||||
static qboolean s_timePolarity;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
if ( LOWORD( wParam ) != WA_INACTIVE )
|
||||
{
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
}
|
||||
|
||||
if ( com_viewlog )
|
||||
{
|
||||
// if the viewlog is open, check to see if it's being minimized
|
||||
if ( com_viewlog->integer == 1 )
|
||||
{
|
||||
if ( HIWORD( wParam ) ) // minimized flag
|
||||
{
|
||||
Cvar_Set( "viewlog", "2" );
|
||||
}
|
||||
}
|
||||
else if ( com_viewlog->integer == 2 )
|
||||
{
|
||||
if ( !HIWORD( wParam ) ) // minimized flag
|
||||
{
|
||||
Cvar_Set( "viewlog", "1" );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
//cmdString = CopyString( "quit" );
|
||||
//Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
|
||||
if ( s_wcd.quitOnClose )
|
||||
{
|
||||
PostQuitMessage( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_ShowConsole( 0, qfalse );
|
||||
Cvar_Set( "viewlog", "0" );
|
||||
}
|
||||
return 0;
|
||||
case WM_CTLCOLORSTATIC:
|
||||
if ( ( HWND ) lParam == s_wcd.hwndBuffer )
|
||||
{
|
||||
SetBkColor( ( HDC ) wParam, RGB( 0, 0, 0 ) );
|
||||
SetTextColor( ( HDC ) wParam, RGB( 249, 249, 000 ) );
|
||||
return ( long ) s_wcd.hbrEditBackground;
|
||||
}
|
||||
else if ( ( HWND ) lParam == s_wcd.hwndErrorBox )
|
||||
{
|
||||
if ( s_timePolarity & 1 )
|
||||
{
|
||||
SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
|
||||
SetTextColor( ( HDC ) wParam, RGB( 0xff, 0x00, 0x00 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
|
||||
SetTextColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0x00 ) );
|
||||
}
|
||||
return ( long ) s_wcd.hbrErrorBackground;
|
||||
}
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
if ( wParam == COPY_ID )
|
||||
{
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
|
||||
SendMessage( s_wcd.hwndBuffer, WM_COPY, 0, 0 );
|
||||
}
|
||||
else if ( wParam == QUIT_ID )
|
||||
{
|
||||
if ( s_wcd.quitOnClose )
|
||||
{
|
||||
PostQuitMessage( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdString = CopyString( "quit" );
|
||||
Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
|
||||
}
|
||||
}
|
||||
else if ( wParam == CLEAR_ID )
|
||||
{
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, ( LPARAM ) "" );
|
||||
UpdateWindow( s_wcd.hwndBuffer );
|
||||
}
|
||||
break;
|
||||
case WM_CREATE:
|
||||
s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0x00 ) );
|
||||
s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) );
|
||||
SetTimer( hWnd, 1, 1000, NULL );
|
||||
break;
|
||||
case WM_ERASEBKGND:
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
case WM_TIMER:
|
||||
if ( wParam == 1 )
|
||||
{
|
||||
s_timePolarity = !s_timePolarity;
|
||||
if ( s_wcd.hwndErrorBox )
|
||||
{
|
||||
InvalidateRect( s_wcd.hwndErrorBox, NULL, FALSE );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char inputBuffer[1024];
|
||||
|
||||
switch ( uMsg )
|
||||
{
|
||||
case WM_KILLFOCUS:
|
||||
if ( ( HWND ) wParam == s_wcd.hWnd ||
|
||||
( HWND ) wParam == s_wcd.hwndErrorBox )
|
||||
{
|
||||
SetFocus( hWnd );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
if ( wParam == 13 )
|
||||
{
|
||||
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) );
|
||||
strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
|
||||
strcat( s_wcd.consoleText, "\n" );
|
||||
SetWindowText( s_wcd.hwndInputLine, "" );
|
||||
|
||||
Sys_Print( va( "]%s\n", inputBuffer ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
/*
|
||||
** Sys_CreateConsole
|
||||
*/
|
||||
void Sys_CreateConsole( void )
|
||||
{
|
||||
HDC hDC;
|
||||
WNDCLASS wc;
|
||||
RECT rect;
|
||||
const char *DEDCLASS = "JK2MP WinConsole";
|
||||
int nHeight;
|
||||
int swidth, sheight;
|
||||
int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
|
||||
|
||||
memset( &wc, 0, sizeof( wc ) );
|
||||
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC) ConWndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = g_wv.hInstance;
|
||||
wc.hIcon = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1));
|
||||
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH__ *)COLOR_INACTIVEBORDER;//(HBRUSH__ *)COLOR_WINDOW;
|
||||
wc.lpszMenuName = 0;
|
||||
wc.lpszClassName = DEDCLASS;
|
||||
|
||||
if ( !RegisterClass (&wc) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
rect.left = 0;
|
||||
rect.right = 600;
|
||||
rect.top = 0;
|
||||
rect.bottom = 450;
|
||||
AdjustWindowRect( &rect, DEDSTYLE, FALSE );
|
||||
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
swidth = GetDeviceCaps( hDC, HORZRES );
|
||||
sheight = GetDeviceCaps( hDC, VERTRES );
|
||||
ReleaseDC( GetDesktopWindow(), hDC );
|
||||
|
||||
s_wcd.windowWidth = rect.right - rect.left + 1;
|
||||
s_wcd.windowHeight = rect.bottom - rect.top + 1;
|
||||
|
||||
s_wcd.hWnd = CreateWindowEx( 0,
|
||||
DEDCLASS,
|
||||
"Jedi Knight®: Jedi Academy SP Console",
|
||||
DEDSTYLE,
|
||||
( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1,
|
||||
NULL,
|
||||
NULL,
|
||||
g_wv.hInstance,
|
||||
NULL );
|
||||
|
||||
if ( s_wcd.hWnd == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// create fonts
|
||||
//
|
||||
hDC = GetDC( s_wcd.hWnd );
|
||||
nHeight = -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY), 72);
|
||||
|
||||
s_wcd.hfBufferFont = CreateFont( nHeight,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FW_LIGHT,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
DEFAULT_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY,
|
||||
FF_MODERN | FIXED_PITCH,
|
||||
"Courier New" );
|
||||
|
||||
ReleaseDC( s_wcd.hWnd, hDC );
|
||||
|
||||
//
|
||||
// create the input line
|
||||
//
|
||||
s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER |
|
||||
ES_LEFT | ES_AUTOHSCROLL,
|
||||
6, 400, s_wcd.windowWidth-20, 20,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) INPUT_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
|
||||
//
|
||||
// create the buttons
|
||||
//
|
||||
s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
|
||||
5, 425, 72, 24,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) COPY_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" );
|
||||
|
||||
s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
|
||||
82, 425, 72, 24,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) CLEAR_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" );
|
||||
|
||||
s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
|
||||
s_wcd.windowWidth-92, 425, 72, 24,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) QUIT_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" );
|
||||
|
||||
|
||||
//
|
||||
// create the scrollbuffer
|
||||
//
|
||||
s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER |
|
||||
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
|
||||
6, 40, s_wcd.windowWidth-20, 354,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) EDIT_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
|
||||
|
||||
s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc );
|
||||
SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_LIMITTEXT, ( WPARAM ) 0x7fff, 0 );
|
||||
|
||||
ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow( s_wcd.hWnd );
|
||||
SetForegroundWindow( s_wcd.hWnd );
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
|
||||
s_wcd.visLevel = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sys_DestroyConsole
|
||||
*/
|
||||
void Sys_DestroyConsole( void ) {
|
||||
if ( s_wcd.hWnd ) {
|
||||
DeleteObject(s_wcd.hbrEditBackground);
|
||||
DeleteObject(s_wcd.hbrErrorBackground);
|
||||
DeleteObject(s_wcd.hfBufferFont);
|
||||
ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
CloseWindow( s_wcd.hWnd );
|
||||
DestroyWindow( s_wcd.hWnd );
|
||||
s_wcd.hWnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Sys_ShowConsole
|
||||
*/
|
||||
void Sys_ShowConsole( int visLevel, qboolean quitOnClose )
|
||||
{
|
||||
s_wcd.quitOnClose = quitOnClose;
|
||||
|
||||
if ( visLevel == s_wcd.visLevel )
|
||||
{
|
||||
if (quitOnClose) {//attempt to bring it to the front on error exit
|
||||
SetForegroundWindow( s_wcd.hWnd );
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
s_wcd.visLevel = visLevel;
|
||||
|
||||
if ( !s_wcd.hWnd ){
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( visLevel )
|
||||
{
|
||||
case 0:
|
||||
ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
break;
|
||||
case 1:
|
||||
ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
|
||||
if (quitOnClose) {//attempt to bring it to the front on error exit
|
||||
SetForegroundWindow( s_wcd.hWnd );
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ShowWindow( s_wcd.hWnd, SW_MINIMIZE );
|
||||
break;
|
||||
default:
|
||||
Sys_Error( "Invalid visLevel %d sent to Sys_ShowConsole\n", visLevel );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Sys_ConsoleInput
|
||||
*/
|
||||
char *Sys_ConsoleInput( void )
|
||||
{
|
||||
if ( s_wcd.consoleText[0] == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy( s_wcd.returnedText, s_wcd.consoleText );
|
||||
s_wcd.consoleText[0] = 0;
|
||||
|
||||
return s_wcd.returnedText;
|
||||
}
|
||||
|
||||
/*
|
||||
** Conbuf_AppendText
|
||||
*/
|
||||
void Conbuf_AppendText( const char *pMsg )
|
||||
{
|
||||
#define CONSOLE_BUFFER_SIZE 16384
|
||||
if ( !s_wcd.hWnd ) {
|
||||
return;
|
||||
}
|
||||
char buffer[CONSOLE_BUFFER_SIZE*4];
|
||||
char *b = buffer;
|
||||
const char *msg;
|
||||
int bufLen;
|
||||
int i = 0;
|
||||
static unsigned long s_totalChars;
|
||||
|
||||
//
|
||||
// if the message is REALLY long, use just the last portion of it
|
||||
//
|
||||
if ( strlen( pMsg ) > CONSOLE_BUFFER_SIZE - 1 )
|
||||
{
|
||||
msg = pMsg + strlen( pMsg ) - CONSOLE_BUFFER_SIZE + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = pMsg;
|
||||
}
|
||||
|
||||
//
|
||||
// copy into an intermediate buffer
|
||||
//
|
||||
while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) )
|
||||
{
|
||||
if ( msg[i] == '\n' && msg[i+1] == '\r' )
|
||||
{
|
||||
b[0] = '\r';
|
||||
b[1] = '\n';
|
||||
b += 2;
|
||||
i++;
|
||||
}
|
||||
else if ( msg[i] == '\r' )
|
||||
{
|
||||
b[0] = '\r';
|
||||
b[1] = '\n';
|
||||
b += 2;
|
||||
}
|
||||
else if ( msg[i] == '\n' )
|
||||
{
|
||||
b[0] = '\r';
|
||||
b[1] = '\n';
|
||||
b += 2;
|
||||
}
|
||||
else if ( Q_IsColorString( &msg[i] ) )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*b= msg[i];
|
||||
b++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*b = 0;
|
||||
bufLen = b - buffer;
|
||||
|
||||
s_totalChars += bufLen;
|
||||
|
||||
//
|
||||
// replace selection instead of appending if we're overflowing
|
||||
//
|
||||
if ( s_totalChars > 0x7fff )
|
||||
{
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
|
||||
s_totalChars = bufLen;
|
||||
}
|
||||
|
||||
//
|
||||
// put this text into the windows console
|
||||
//
|
||||
SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
** Sys_SetErrorText
|
||||
*/
|
||||
void Sys_SetErrorText( const char *buf )
|
||||
{
|
||||
Q_strncpyz( s_wcd.errorString, buf, sizeof( s_wcd.errorString ) );
|
||||
|
||||
if ( !s_wcd.hwndErrorBox )
|
||||
{
|
||||
s_wcd.hwndErrorBox = CreateWindow( "static", NULL, WS_CHILD | WS_VISIBLE | SS_SUNKEN,
|
||||
6, 5, s_wcd.windowWidth-20, 30,
|
||||
s_wcd.hWnd,
|
||||
( HMENU ) ERRORBOX_ID, // child window ID
|
||||
g_wv.hInstance, NULL );
|
||||
SendMessage( s_wcd.hwndErrorBox, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
|
||||
SetWindowText( s_wcd.hwndErrorBox, s_wcd.errorString );
|
||||
|
||||
DestroyWindow( s_wcd.hwndInputLine );
|
||||
s_wcd.hwndInputLine = NULL;
|
||||
}
|
||||
}
|
||||
325
code/win32/win_video.cpp
Normal file
325
code/win32/win_video.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
// Filename:- win_video.cpp
|
||||
//
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
|
||||
/*
|
||||
#include "bink.h"
|
||||
|
||||
|
||||
static HANDLE hBinkFile = NULL;
|
||||
static HBINK hBink = NULL;
|
||||
*/
|
||||
|
||||
extern unsigned int SNDDMA_GetDSHandle(void);
|
||||
extern int s_soundStarted; // if 0, game is running in silent mode
|
||||
|
||||
// ret qtrue if success...
|
||||
//
|
||||
qboolean VIDEO_GetDims(int *piWidth, int *piHeight)
|
||||
{
|
||||
/*
|
||||
if (hBink)
|
||||
{
|
||||
if (piWidth && piHeight)
|
||||
{
|
||||
// *piWidth = hBink->Width; // Width (1 based, 640 for example)
|
||||
|
||||
if (hBink->decompwidth == hBink->Width/2)
|
||||
{
|
||||
*piWidth = hBink->decompwidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piWidth = hBink->Width;
|
||||
}
|
||||
|
||||
if (hBink->decompheight == hBink->Height/2)
|
||||
{
|
||||
*piHeight = hBink->decompheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piHeight = hBink->Height;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
// ret qtrue if no reason to delay...
|
||||
//
|
||||
qboolean VIDEO_NextFrameReady(void)
|
||||
{
|
||||
/* if (hBink && BinkWait(hBink))
|
||||
{
|
||||
return qfalse;
|
||||
}
|
||||
*/
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void VIDEO_Pause(qboolean bPaused)
|
||||
{
|
||||
/*
|
||||
if (hBink)
|
||||
{
|
||||
BinkPause(hBink, bPaused);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void VIDEO_Mute(qboolean bMute)
|
||||
{
|
||||
/*
|
||||
if (!s_soundStarted)
|
||||
bMute = qtrue; // <g>
|
||||
|
||||
if (hBink)
|
||||
{
|
||||
// BinkSetSoundOnOff(hBink, !bMute); // this has a bug, and freezes video playback
|
||||
BinkSetVolume(hBink,bMute?0:32768); // effectively the same, and instant, not just to next audio packet
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// advance to the next Bink Frame, qtrue if not finished playback
|
||||
//
|
||||
//qboolean VIDEO_NextFrame( byte *pbDestBuffer ) // pbDestBuffer will be sizeof Vid dims *4
|
||||
qboolean VIDEO_NextFrame( byte *pbDestBuffer, int iBytesPerLine, qboolean &bFrameSkipped)
|
||||
{
|
||||
/*
|
||||
if (hBink)
|
||||
{
|
||||
bFrameSkipped = BinkDoFrame(hBink);
|
||||
|
||||
if (!bFrameSkipped)
|
||||
{
|
||||
|
||||
//extern cvar_t *r_speeds;
|
||||
//int start,end;
|
||||
//if ( r_speeds->integer )
|
||||
//{
|
||||
// start = Sys_Milliseconds();
|
||||
//}
|
||||
BinkCopyToBuffer( hBink, // HBINK bnk,
|
||||
pbDestBuffer, // void* dest,
|
||||
iBytesPerLine,//hBink->Width*4, // u32 destpitch (bytes, not pixels)
|
||||
hBink->Height, // u32 destheight
|
||||
0, // u32 destx
|
||||
0, // u32 desty,
|
||||
BINKSURFACE32R
|
||||
//|BINKCOPYALL
|
||||
|BINKCOPYNOSCALING // important, or you'll crash on half-height compressed videos now!
|
||||
);
|
||||
|
||||
//if ( r_speeds->integer )
|
||||
//{
|
||||
// end = Sys_Milliseconds();
|
||||
// Com_Printf( "BinkCopyToBuffer(): %i msec\n", end - start );
|
||||
//}
|
||||
}
|
||||
|
||||
// finished?
|
||||
//
|
||||
qboolean bStillPlaying = qtrue;
|
||||
|
||||
if (hBink->FrameNum == hBink->Frames)
|
||||
{
|
||||
bStillPlaying = qfalse; // finished
|
||||
}
|
||||
else
|
||||
{
|
||||
BinkNextFrame(hBink);
|
||||
}
|
||||
|
||||
return bStillPlaying;
|
||||
}
|
||||
*/
|
||||
return qfalse; // will only get here if some sort of error in Q3 logic (which does happen) so that this is called
|
||||
// at the wrong time.
|
||||
}
|
||||
|
||||
|
||||
|
||||
// called even if not fully opened, so check everything...
|
||||
//
|
||||
void VIDEO_Close(void)
|
||||
{
|
||||
/*
|
||||
if (hBink)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
BINKSUMMARY Summary;
|
||||
BinkGetSummary(hBink, &Summary);
|
||||
Com_DPrintf("\nBINK Playback Summary:\n\n");
|
||||
Com_DPrintf("TotalTime: %d\n",Summary.TotalTime); //
|
||||
Com_DPrintf("FileFrameRate: %d\n",Summary.FileFrameRate); // frame rate
|
||||
Com_DPrintf("FileFrameRateDiv: %d\n",Summary.FileFrameRateDiv); // frame rate divisor
|
||||
Com_DPrintf("FrameRate: %d\n",Summary.FrameRate); // frame rate
|
||||
Com_DPrintf("FrameRateDiv: %d\n",Summary.FrameRateDiv); // frame rate divisor
|
||||
Com_DPrintf("TotalOpenTime: %d\n",Summary.TotalOpenTime); // Time to open and prepare for decompression
|
||||
Com_DPrintf("TotalFrames: %d\n",Summary.TotalFrames); // Total Frames
|
||||
Com_DPrintf("TotalPlayedFrames: %d\n",Summary.TotalPlayedFrames); // Total Frames played
|
||||
Com_DPrintf("SkippedFrames: %d\n",Summary.SkippedFrames); // Total number of skipped frames
|
||||
Com_DPrintf("SkippedBlits: %d\n",Summary.SkippedBlits); // Total number of skipped blits
|
||||
Com_DPrintf("SoundSkips: %d\n",Summary.SoundSkips); // Total number of sound skips
|
||||
Com_DPrintf("TotalBlitTime: %d\n",Summary.TotalBlitTime); // Total time spent blitting
|
||||
Com_DPrintf("TotalReadTime: %d\n",Summary.TotalReadTime); // Total time spent reading
|
||||
Com_DPrintf("TotalVideoDecompTime: %d\n",Summary.TotalVideoDecompTime); // Total time spent decompressing video
|
||||
Com_DPrintf("TotalAudioDecompTime: %d\n",Summary.TotalAudioDecompTime); // Total time spent decompressing audio
|
||||
Com_DPrintf("TotalBackReadTime: %d\n",Summary.TotalBackReadTime); // Total time spent reading in background
|
||||
Com_DPrintf("TotalReadSpeed: %d\n",Summary.TotalReadSpeed); // Total io speed (bytes/second)
|
||||
Com_DPrintf("SlowestFrameTime: %d\n",Summary.SlowestFrameTime); // Slowest single frame time (ms)
|
||||
Com_DPrintf("Slowest2FrameTime: %d\n",Summary.Slowest2FrameTime); // Second slowest single frame time (ms)
|
||||
Com_DPrintf("SlowestFrameNum: %d\n",Summary.SlowestFrameNum); // Slowest single frame number
|
||||
Com_DPrintf("Slowest2FrameNum: %d\n",Summary.Slowest2FrameNum); // Second slowest single frame number
|
||||
Com_DPrintf("AverageDataRate: %d\n",Summary.AverageDataRate); // Average data rate of the movie
|
||||
Com_DPrintf("AverageFrameSize: %d\n",Summary.AverageFrameSize); // Average size of the frame
|
||||
Com_DPrintf("HighestMemAmount: %d\n",Summary.HighestMemAmount); // Highest amount of memory allocated
|
||||
Com_DPrintf("TotalIOMemory: %d\n",Summary.TotalIOMemory); // Total extra memory allocated
|
||||
Com_DPrintf("HighestIOUsed: %d\n",Summary.HighestIOUsed); // Highest extra memory actually used
|
||||
Com_DPrintf("Highest1SecRate: %d\n",Summary.Highest1SecRate); // Highest 1 second rate
|
||||
Com_DPrintf("Highest1SecFrame: %d\n",Summary.Highest1SecFrame); // Highest 1 second start frame
|
||||
Com_DPrintf("\n");
|
||||
#endif
|
||||
BinkClose(hBink);
|
||||
hBink = NULL;
|
||||
SNDDMA_Activate();
|
||||
}
|
||||
|
||||
if (hBinkFile)
|
||||
{
|
||||
CloseHandle(hBinkFile);
|
||||
hBinkFile = NULL;
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
static qboolean VIDEO_Open2(char *psPathlessBaseName, qboolean qbInGame, qboolean qbTestOpenOnly, int iLanguageNumber)
|
||||
{
|
||||
char sLocalFilename[MAX_OSPATH];
|
||||
|
||||
// Get the Quake filesystem to see if it exists, and fill in some internal structs as to where it really is,
|
||||
// and what offset (if PAK) etc...
|
||||
//
|
||||
Com_sprintf (sLocalFilename, sizeof(sLocalFilename), "video/%s.bik", psPathlessBaseName);
|
||||
char *psActualFilename;
|
||||
int iSeekOffset;
|
||||
qboolean bResult = FS_GetExtendedInfo_FOpenFileRead(sLocalFilename, &psActualFilename, &iSeekOffset);
|
||||
if (!bResult)
|
||||
{
|
||||
if (!qbTestOpenOnly)
|
||||
{
|
||||
Com_Printf(S_COLOR_RED"Couldn't open %s\n", sLocalFilename);
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (qbTestOpenOnly)
|
||||
return qtrue;
|
||||
|
||||
|
||||
// Now re-open as a Windoze HANDLE, because Bink doesn't use FILE * types...
|
||||
//
|
||||
hBinkFile = CreateFile( psActualFilename, // LPCTSTR lpFileName, // pointer to name of the file
|
||||
GENERIC_READ, // DWORD dwDesiredAccess, // access (read-write) mode
|
||||
FILE_SHARE_READ, // DWORD dwShareMode, // share mode
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
|
||||
OPEN_EXISTING, // DWORD dwCreationDisposition, // how to create
|
||||
FILE_FLAG_SEQUENTIAL_SCAN,// DWORD dwFlagsAndAttributes, // file attributes
|
||||
NULL // HANDLE hTemplateFile // handle to file with attributes to
|
||||
);
|
||||
|
||||
if (hBinkFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Com_Printf(S_COLOR_RED"Error converting FILE* to HANDLE for Bink, file: %s\n", psActualFilename);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
// Opened ok, now seek the handle to the correct position for starting (ie if inside a PAK file etc)
|
||||
//
|
||||
DWORD dwFileOffset = SetFilePointer(hBinkFile, // HANDLE hFile, // handle of file
|
||||
iSeekOffset,// LONG lDistanceToMove, // number of bytes to move file pointer
|
||||
NULL, // PLONG lpDistanceToMoveHigh, // pointer to high-order DWORD of distance to move
|
||||
FILE_BEGIN // DWORD dwMoveMethod // how to move
|
||||
);
|
||||
|
||||
if (dwFileOffset != iSeekOffset)
|
||||
{
|
||||
VIDEO_Close();
|
||||
Com_Printf( S_COLOR_RED"Error seeking to Bink video start (offset %d), file: %s\n", iSeekOffset,psActualFilename);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
// ok, I think we're ready...
|
||||
//
|
||||
if (!cls.soundStarted || s_soundStarted) // sound system not started (occurs in very first video), or sound desired
|
||||
{
|
||||
BinkSoundUseDirectSound(SNDDMA_GetDSHandle());
|
||||
BinkSetSoundTrack(iLanguageNumber); // select the language anyway here, regardless of multi-lingual file or not
|
||||
}
|
||||
else
|
||||
{
|
||||
BinkSetSoundTrack(BINKNOSOUND);
|
||||
}
|
||||
|
||||
// hBink = BinkOpen("d:\\kiss.bik",0);
|
||||
hBink = BinkOpen((char *)hBinkFile,BINKFILEHANDLE | BINKSNDTRACK);
|
||||
if (!hBink)
|
||||
{
|
||||
VIDEO_Close();
|
||||
Com_Printf( S_COLOR_RED"Unrecognised video file: %s\n", psActualFilename);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!s_soundStarted) // game running in silent mode?
|
||||
{
|
||||
VIDEO_Mute(qtrue);
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
*/
|
||||
|
||||
// now modified to take different languages into account...
|
||||
//
|
||||
qboolean VIDEO_Open(char *psPathlessBaseName, qboolean qbInGame, qboolean qbTestOpenOnly, int iLanguageNumber)
|
||||
{
|
||||
/*
|
||||
qboolean qbReturn = VIDEO_Open2(psPathlessBaseName, qbInGame, qbTestOpenOnly, iLanguageNumber);
|
||||
|
||||
if (qbReturn)
|
||||
{
|
||||
if (!qbTestOpenOnly && hBink)
|
||||
{
|
||||
// check we didn't try to (eg) select German audio on a file with 1 track (eg just music)
|
||||
//
|
||||
if (iLanguageNumber+1 > hBink->NumTracks)
|
||||
{
|
||||
VIDEO_Close();
|
||||
return VIDEO_Open2(psPathlessBaseName, qbInGame, qbTestOpenOnly, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qbReturn;
|
||||
*/
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
//////////////// eof //////////////////
|
||||
|
||||
532
code/win32/win_wndproc.cpp
Normal file
532
code/win32/win_wndproc.cpp
Normal file
@@ -0,0 +1,532 @@
|
||||
// leave this as first line for PCH reasons...
|
||||
//
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "win_local.h"
|
||||
|
||||
// The only directly referenced keycode - the console key (which gives different ascii codes depending on locale)
|
||||
#define CONSOLE_SCAN_CODE 0x29
|
||||
|
||||
|
||||
WinVars_t g_wv;
|
||||
|
||||
#ifndef WM_MOUSEWHEEL
|
||||
#define WM_MOUSEWHEEL (WM_MOUSELAST+1) // message that will be supported by the OS
|
||||
#endif
|
||||
|
||||
static UINT MSH_MOUSEWHEEL;
|
||||
|
||||
// Console variables that we need to access from this module
|
||||
cvar_t *vid_xpos; // X coordinate of window position
|
||||
cvar_t *vid_ypos; // Y coordinate of window position
|
||||
cvar_t *sr_fullscreen;
|
||||
|
||||
#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
|
||||
|
||||
LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
static qboolean s_alttab_disabled;
|
||||
|
||||
static void WIN_DisableAltTab( void )
|
||||
{
|
||||
if ( s_alttab_disabled )
|
||||
return;
|
||||
|
||||
if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
|
||||
{
|
||||
RegisterHotKey( 0, 0, MOD_ALT, VK_TAB );
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL old;
|
||||
|
||||
SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 );
|
||||
}
|
||||
s_alttab_disabled = qtrue;
|
||||
}
|
||||
|
||||
static void WIN_EnableAltTab( void )
|
||||
{
|
||||
if ( s_alttab_disabled )
|
||||
{
|
||||
if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) )
|
||||
{
|
||||
UnregisterHotKey( 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL old;
|
||||
|
||||
SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 );
|
||||
}
|
||||
|
||||
s_alttab_disabled = qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
VID_AppActivate
|
||||
==================
|
||||
*/
|
||||
static void VID_AppActivate(BOOL fActive, BOOL minimize)
|
||||
{
|
||||
g_wv.isMinimized = minimize;
|
||||
|
||||
Key_ClearStates(); // FIXME!!!
|
||||
|
||||
// we don't want to act like we're active if we're minimized
|
||||
if (fActive && !g_wv.isMinimized )
|
||||
{
|
||||
g_wv.activeApp = qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_wv.activeApp = qfalse;
|
||||
}
|
||||
|
||||
// minimize/restore mouse-capture on demand
|
||||
if (!g_wv.activeApp )
|
||||
{
|
||||
IN_Activate (qfalse);
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_Activate (qtrue);
|
||||
}
|
||||
}
|
||||
|
||||
static byte virtualKeyConvert[0x92][2] =
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ A_MOUSE1, A_MOUSE1 }, // VK_LBUTTON 01 Left mouse button
|
||||
{ A_MOUSE2, A_MOUSE2 }, // VK_RBUTTON 02 Right mouse button
|
||||
{ 0, 0 }, // VK_CANCEL 03 Control-break processing
|
||||
{ A_MOUSE3, A_MOUSE3 }, // VK_MBUTTON 04 Middle mouse button (three-button mouse)
|
||||
{ A_MOUSE4, A_MOUSE4 }, // VK_XBUTTON1 05 Windows 2000/XP: X1 mouse button
|
||||
{ A_MOUSE5, A_MOUSE5 }, // VK_XBUTTON2 06 Windows 2000/XP: X2 mouse button
|
||||
{ 0, 0 }, // 07 Undefined
|
||||
{ A_BACKSPACE, A_BACKSPACE }, // VK_BACK 08 BACKSPACE key
|
||||
{ A_TAB, A_TAB }, // VK_TAB 09 TAB key
|
||||
{ 0, 0 }, // 0A Reserved
|
||||
{ 0, 0 }, // 0B Reserved
|
||||
{ A_KP_5, 0 }, // VK_CLEAR 0C CLEAR key
|
||||
{ A_ENTER, A_KP_ENTER }, // VK_RETURN 0D ENTER key
|
||||
{ 0, 0 }, // 0E Undefined
|
||||
{ 0, 0 }, // 0F Undefined
|
||||
{ A_SHIFT, A_SHIFT }, // VK_SHIFT 10 SHIFT key
|
||||
{ A_CTRL, A_CTRL }, // VK_CONTROL 11 CTRL key
|
||||
{ A_ALT, A_ALT }, // VK_MENU 12 ALT key
|
||||
{ A_PAUSE, A_PAUSE }, // VK_PAUSE 13 PAUSE key
|
||||
{ A_CAPSLOCK, A_CAPSLOCK }, // VK_CAPITAL 14 CAPS LOCK key
|
||||
{ 0, 0 }, // VK_KANA 15 IME Kana mode
|
||||
{ 0, 0 }, // 16 Undefined
|
||||
{ 0, 0 }, // VK_JUNJA 17 IME Junja mode
|
||||
{ 0, 0 }, // VK_FINAL 18 IME final mode
|
||||
{ 0, 0 }, // VK_KANJI 19 IME Kanji mode
|
||||
{ 0, 0 }, // 1A Undefined
|
||||
{ A_ESCAPE, A_ESCAPE }, // VK_ESCAPE 1B ESC key
|
||||
{ 0, 0 }, // VK_CONVERT 1C IME convert
|
||||
{ 0, 0 }, // VK_NONCONVERT 1D IME nonconvert
|
||||
{ 0, 0 }, // VK_ACCEPT 1E IME accept
|
||||
{ 0, 0 }, // VK_MODECHANGE 1F IME mode change request
|
||||
{ A_SPACE, A_SPACE }, // VK_SPACE 20 SPACEBAR
|
||||
{ A_KP_9, A_PAGE_UP }, // VK_PRIOR 21 PAGE UP key
|
||||
{ A_KP_3, A_PAGE_DOWN }, // VK_NEXT 22 PAGE DOWN key
|
||||
{ A_KP_1, A_END }, // VK_END 23 END key
|
||||
{ A_KP_7, A_HOME }, // VK_HOME 24 HOME key
|
||||
{ A_KP_4, A_CURSOR_LEFT }, // VK_LEFT 25 LEFT ARROW key
|
||||
{ A_KP_8, A_CURSOR_UP }, // VK_UP 26 UP ARROW key
|
||||
{ A_KP_6, A_CURSOR_RIGHT }, // VK_RIGHT 27 RIGHT ARROW key
|
||||
{ A_KP_2, A_CURSOR_DOWN }, // VK_DOWN 28 DOWN ARROW key
|
||||
{ 0, 0 }, // VK_SELECT 29 SELECT key
|
||||
{ 0, 0 }, // VK_PRINT 2A PRINT key
|
||||
{ 0, 0 }, // VK_EXECUTE 2B EXECUTE key
|
||||
{ A_PRINTSCREEN, A_PRINTSCREEN }, // VK_SNAPSHOT 2C PRINT SCREEN key
|
||||
{ A_KP_0, A_INSERT }, // VK_INSERT 2D INS key
|
||||
{ A_KP_PERIOD, A_DELETE }, // VK_DELETE 2E DEL key
|
||||
{ 0, 0 }, // VK_HELP 2F HELP key
|
||||
{ A_0, A_0 }, // 30 0 key
|
||||
{ A_1, A_1 }, // 31 1 key
|
||||
{ A_2, A_2 }, // 32 2 key
|
||||
{ A_3, A_3 }, // 33 3 key
|
||||
{ A_4, A_4 }, // 34 4 key
|
||||
{ A_5, A_5 }, // 35 5 key
|
||||
{ A_6, A_6 }, // 36 6 key
|
||||
{ A_7, A_7 }, // 37 7 key
|
||||
{ A_8, A_8 }, // 38 8 key
|
||||
{ A_9, A_9 }, // 39 9 key
|
||||
{ 0, 0 }, // 3A Undefined
|
||||
{ 0, 0 }, // 3B Undefined
|
||||
{ 0, 0 }, // 3C Undefined
|
||||
{ 0, 0 }, // 3D Undefined
|
||||
{ 0, 0 }, // 3E Undefined
|
||||
{ 0, 0 }, // 3F Undefined
|
||||
{ 0, 0 }, // 40 Undefined
|
||||
{ A_CAP_A, A_CAP_A }, // 41 A key
|
||||
{ A_CAP_B, A_CAP_B }, // 42 B key
|
||||
{ A_CAP_C, A_CAP_C }, // 43 C key
|
||||
{ A_CAP_D, A_CAP_D }, // 44 D key
|
||||
{ A_CAP_E, A_CAP_E }, // 45 E key
|
||||
{ A_CAP_F, A_CAP_F }, // 46 F key
|
||||
{ A_CAP_G, A_CAP_G }, // 47 G key
|
||||
{ A_CAP_H, A_CAP_H }, // 48 H key
|
||||
{ A_CAP_I, A_CAP_I }, // 49 I key
|
||||
{ A_CAP_J, A_CAP_J }, // 4A J key
|
||||
{ A_CAP_K, A_CAP_K }, // 4B K key
|
||||
{ A_CAP_L, A_CAP_L }, // 4C L key
|
||||
{ A_CAP_M, A_CAP_M }, // 4D M key
|
||||
{ A_CAP_N, A_CAP_N }, // 4E N key
|
||||
{ A_CAP_O, A_CAP_O }, // 4F O key
|
||||
{ A_CAP_P, A_CAP_P }, // 50 P key
|
||||
{ A_CAP_Q, A_CAP_Q }, // 51 Q key
|
||||
{ A_CAP_R, A_CAP_R }, // 52 R key
|
||||
{ A_CAP_S, A_CAP_S }, // 53 S key
|
||||
{ A_CAP_T, A_CAP_T }, // 54 T key
|
||||
{ A_CAP_U, A_CAP_U }, // 55 U key
|
||||
{ A_CAP_V, A_CAP_V }, // 56 V key
|
||||
{ A_CAP_W, A_CAP_W }, // 57 W key
|
||||
{ A_CAP_X, A_CAP_X }, // 58 X key
|
||||
{ A_CAP_Y, A_CAP_Y }, // 59 Y key
|
||||
{ A_CAP_Z, A_CAP_Z }, // 5A Z key
|
||||
{ 0, 0 }, // VK_LWIN 5B Left Windows key (Microsoft® Natural® keyboard)
|
||||
{ 0, 0 }, // VK_RWIN 5C Right Windows key (Natural keyboard)
|
||||
{ 0, 0 }, // VK_APPS 5D Applications key (Natural keyboard)
|
||||
{ 0, 0 }, // 5E Reserved
|
||||
{ 0, 0 }, // VK_SLEEP 5F Computer Sleep key
|
||||
{ A_KP_0, A_KP_0 }, // VK_NUMPAD0 60 Numeric keypad 0 key
|
||||
{ A_KP_1, A_KP_1 }, // VK_NUMPAD1 61 Numeric keypad 1 key
|
||||
{ A_KP_2, A_KP_2 }, // VK_NUMPAD2 62 Numeric keypad 2 key
|
||||
{ A_KP_3, A_KP_3 }, // VK_NUMPAD3 63 Numeric keypad 3 key
|
||||
{ A_KP_4, A_KP_4 }, // VK_NUMPAD4 64 Numeric keypad 4 key
|
||||
{ A_KP_5, A_KP_5 }, // VK_NUMPAD5 65 Numeric keypad 5 key
|
||||
{ A_KP_6, A_KP_6 }, // VK_NUMPAD6 66 Numeric keypad 6 key
|
||||
{ A_KP_7, A_KP_7 }, // VK_NUMPAD7 67 Numeric keypad 7 key
|
||||
{ A_KP_8, A_KP_8 }, // VK_NUMPAD8 68 Numeric keypad 8 key
|
||||
{ A_KP_9, A_KP_9 }, // VK_NUMPAD9 69 Numeric keypad 9 key
|
||||
{ A_MULTIPLY, A_MULTIPLY }, // VK_MULTIPLY 6A Multiply key
|
||||
{ A_KP_PLUS, A_KP_PLUS }, // VK_ADD 6B Add key
|
||||
{ 0, 0 }, // VK_SEPARATOR 6C Separator key
|
||||
{ A_KP_MINUS, A_KP_MINUS }, // VK_SUBTRACT 6D Subtract key
|
||||
{ A_KP_PERIOD, A_KP_PERIOD }, // VK_DECIMAL 6E Decimal key
|
||||
{ A_DIVIDE, A_DIVIDE }, // VK_DIVIDE 6F Divide key
|
||||
{ A_F1, A_F1 }, // VK_F1 70 F1 key
|
||||
{ A_F2, A_F2 }, // VK_F2 71 F2 key
|
||||
{ A_F3, A_F3 }, // VK_F3 72 F3 key
|
||||
{ A_F4, A_F4 }, // VK_F4 73 F4 key
|
||||
{ A_F5, A_F5 }, // VK_F5 74 F5 key
|
||||
{ A_F6, A_F6 }, // VK_F6 75 F6 key
|
||||
{ A_F7, A_F7 }, // VK_F7 76 F7 key
|
||||
{ A_F8, A_F8 }, // VK_F8 77 F8 key
|
||||
{ A_F9, A_F9 }, // VK_F9 78 F9 key
|
||||
{ A_F10, A_F10 }, // VK_F10 79 F10 key
|
||||
{ A_F11, A_F11 }, // VK_F11 7A F11 key
|
||||
{ A_F12, A_F12 }, // VK_F12 7B F12 key
|
||||
{ 0, 0 }, // VK_F13 7C F13 key
|
||||
{ 0, 0 }, // VK_F14 7D F14 key
|
||||
{ 0, 0 }, // VK_F15 7E F15 key
|
||||
{ 0, 0 }, // VK_F16 7F F16 key
|
||||
{ 0, 0 }, // VK_F17 80H F17 key
|
||||
{ 0, 0 }, // VK_F18 81H F18 key
|
||||
{ 0, 0 }, // VK_F19 82H F19 key
|
||||
{ 0, 0 }, // VK_F20 83H F20 key
|
||||
{ 0, 0 }, // VK_F21 84H F21 key
|
||||
{ 0, 0 }, // VK_F22 85H F22 key
|
||||
{ 0, 0 }, // VK_F23 86H F23 key
|
||||
{ 0, 0 }, // VK_F24 87H F24 key
|
||||
{ 0, 0 }, // 88 Unassigned
|
||||
{ 0, 0 }, // 89 Unassigned
|
||||
{ 0, 0 }, // 8A Unassigned
|
||||
{ 0, 0 }, // 8B Unassigned
|
||||
{ 0, 0 }, // 8C Unassigned
|
||||
{ 0, 0 }, // 8D Unassigned
|
||||
{ 0, 0 }, // 8E Unassigned
|
||||
{ 0, 0 }, // 8F Unassigned
|
||||
{ A_NUMLOCK, A_NUMLOCK }, // VK_NUMLOCK 90 NUM LOCK key
|
||||
{ A_SCROLLLOCK, A_SCROLLLOCK } // VK_SCROLL 91
|
||||
};
|
||||
|
||||
/*
|
||||
=======
|
||||
MapKey
|
||||
|
||||
Map from windows to quake keynums
|
||||
=======
|
||||
*/
|
||||
static int MapKey (ulong key, word wParam)
|
||||
{
|
||||
ulong result, scan, extended;
|
||||
|
||||
// Check for the console key (hard code to the key you would expect)
|
||||
scan = ( key >> 16 ) & 0xff;
|
||||
if(scan == CONSOLE_SCAN_CODE)
|
||||
{
|
||||
return(A_CONSOLE);
|
||||
}
|
||||
|
||||
// Try to convert the virtual key directly
|
||||
result = 0;
|
||||
extended = (key >> 24) & 1;
|
||||
if(wParam > 0 && wParam <= VK_SCROLL)
|
||||
{
|
||||
result = virtualKeyConvert[wParam][extended];
|
||||
}
|
||||
// Get the unshifted ascii code (if any)
|
||||
if(!result)
|
||||
{
|
||||
result = MapVirtualKey(wParam, 2) & 0xff;
|
||||
}
|
||||
// Output any debug prints
|
||||
// if(in_debug && in_debug->integer & 1)
|
||||
// {
|
||||
// Com_Printf("WM_KEY: %x : %x : %x\n", key, wParam, result);
|
||||
// }
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
MainWndProc
|
||||
|
||||
main window procedure
|
||||
====================
|
||||
*/
|
||||
|
||||
#define WM_BUTTON4DOWN (WM_MOUSELAST+2)
|
||||
#define WM_BUTTON4UP (WM_MOUSELAST+3)
|
||||
#define MK_BUTTON4L 0x0020
|
||||
#define MK_BUTTON4R 0x0040
|
||||
|
||||
LONG WINAPI MainWndProc (
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
byte code;
|
||||
|
||||
if ( uMsg == MSH_MOUSEWHEEL )
|
||||
{
|
||||
if ( ( ( int ) wParam ) > 0 )
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELUP, qtrue, 0, NULL );
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELUP, qfalse, 0, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELDOWN, qtrue, 0, NULL );
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELDOWN, qfalse, 0, NULL );
|
||||
}
|
||||
return DefWindowProc (hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_MOUSEWHEEL:
|
||||
//
|
||||
//
|
||||
// this chunk of code theoretically only works under NT4 and Win98
|
||||
// since this message doesn't exist under Win95
|
||||
//
|
||||
if ( ( short ) HIWORD( wParam ) > 0 )
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELUP, qtrue, 0, NULL );
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELUP, qfalse, 0, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELDOWN, qtrue, 0, NULL );
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, A_MWHEELDOWN, qfalse, 0, NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CREATE:
|
||||
|
||||
g_wv.hWnd = hWnd;
|
||||
|
||||
vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
|
||||
vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
|
||||
sr_fullscreen = Cvar_Get ("r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG");
|
||||
if ( sr_fullscreen->integer )
|
||||
{
|
||||
WIN_DisableAltTab();
|
||||
}
|
||||
else
|
||||
{
|
||||
WIN_EnableAltTab();
|
||||
}
|
||||
|
||||
break;
|
||||
#if 0
|
||||
case WM_DISPLAYCHANGE:
|
||||
Com_DPrintf( "WM_DISPLAYCHANGE\n" );
|
||||
// we need to force a vid_restart if the user has changed
|
||||
// their desktop resolution while the game is running,
|
||||
// but don't do anything if the message is a result of
|
||||
// our own calling of ChangeDisplaySettings
|
||||
if ( com_insideVidInit ) {
|
||||
break; // we did this on purpose
|
||||
}
|
||||
// something else forced a mode change, so restart all our gl stuff
|
||||
Cbuf_AddText( "vid_restart\n" );
|
||||
break;
|
||||
#endif
|
||||
case WM_DESTROY:
|
||||
// let sound and input know about this?
|
||||
g_wv.hWnd = NULL;
|
||||
if ( sr_fullscreen->integer )
|
||||
{
|
||||
WIN_EnableAltTab();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
Cbuf_ExecuteText( EXEC_APPEND, "quit" );
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
int fActive, fMinimized;
|
||||
|
||||
fActive = LOWORD(wParam);
|
||||
fMinimized = (BOOL) HIWORD(wParam);
|
||||
|
||||
VID_AppActivate( fActive != WA_INACTIVE, fMinimized);
|
||||
SNDDMA_Activate( fActive != WA_INACTIVE && !fMinimized );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
int xPos, yPos;
|
||||
RECT r;
|
||||
int style;
|
||||
|
||||
if (!sr_fullscreen->integer )
|
||||
{
|
||||
xPos = (short) LOWORD(lParam); // horizontal position
|
||||
yPos = (short) HIWORD(lParam); // vertical position
|
||||
|
||||
r.left = 0;
|
||||
r.top = 0;
|
||||
r.right = 1;
|
||||
r.bottom = 1;
|
||||
|
||||
style = GetWindowLong( hWnd, GWL_STYLE );
|
||||
AdjustWindowRect( &r, style, FALSE );
|
||||
|
||||
Cvar_SetValue( "vid_xpos", xPos + r.left);
|
||||
Cvar_SetValue( "vid_ypos", yPos + r.top);
|
||||
vid_xpos->modified = qfalse;
|
||||
vid_ypos->modified = qfalse;
|
||||
if ( g_wv.activeApp )
|
||||
{
|
||||
IN_Activate (qtrue);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// this is complicated because Win32 seems to pack multiple mouse events into
|
||||
// one update sometimes, so we always check all states and look for events
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_BUTTON4DOWN:
|
||||
case WM_BUTTON4UP:
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = 0;
|
||||
|
||||
if (wParam & MK_LBUTTON)
|
||||
temp |= 1;
|
||||
|
||||
if (wParam & MK_RBUTTON)
|
||||
temp |= 2;
|
||||
|
||||
if (wParam & MK_MBUTTON)
|
||||
temp |= 4;
|
||||
|
||||
if (wParam & MK_BUTTON4L)
|
||||
temp |= 8;
|
||||
|
||||
if (wParam & MK_BUTTON4R)
|
||||
temp |= 16;
|
||||
|
||||
IN_MouseEvent (temp);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
if ( (wParam&0xFFF0) == SC_SCREENSAVE || (wParam&0xFFF0) == SC_MONITORPOWER)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
if ( wParam == VK_RETURN ) //alt-enter
|
||||
{
|
||||
if ( sr_fullscreen && !ge || (ge->GameAllowedToSaveHere() && !(cls.keyCatchers&KEYCATCH_UI)) )
|
||||
{//okay, don't switch if the game is running while in a cinematic or in the menu
|
||||
Cvar_SetValue( "r_fullscreen", !sr_fullscreen->integer );
|
||||
Cbuf_AddText( "vid_restart\n" );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// fall through
|
||||
case WM_KEYDOWN:
|
||||
code = MapKey( lParam, wParam );
|
||||
if(code)
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, code, qtrue, 0, NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
code = MapKey( lParam, wParam );
|
||||
if(code)
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, code, qfalse, 0, NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
if(((lParam >> 16) & 0xff) != CONSOLE_SCAN_CODE)
|
||||
{
|
||||
Sys_QueEvent( g_wv.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL );
|
||||
}
|
||||
// Output any debug prints
|
||||
// if(in_debug && in_debug->integer & 2)
|
||||
// {
|
||||
// Com_Printf("WM_CHAR: %x\n", wParam);
|
||||
// }
|
||||
break;
|
||||
|
||||
case WM_POWERBROADCAST:
|
||||
if (wParam == PBT_APMQUERYSUSPEND)
|
||||
{
|
||||
#ifndef FINAL_BUILD
|
||||
Com_Printf("Cannot go into hibernate / standby mode while game is running!\n");
|
||||
#endif
|
||||
return BROADCAST_QUERY_DENY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
101
code/win32/winquake.rc
Normal file
101
code/win32/winquake.rc
Normal file
@@ -0,0 +1,101 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "starwars.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "AutoVersion.h"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_MAJOR_RELEASE,VERSION_MINOR_RELEASE,VERSION_EXTERNAL_BUILD,VERSION_INTERNAL_BUILD
|
||||
PRODUCTVERSION VERSION_MAJOR_RELEASE,VERSION_MINOR_RELEASE,VERSION_EXTERNAL_BUILD,VERSION_INTERNAL_BUILD
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Raven Software"
|
||||
VALUE "CompanyName", "Activision Inc"
|
||||
VALUE "FileDescription", "Jedi Academy SP"
|
||||
VALUE "FileVersion", VERSION_STRING
|
||||
VALUE "InternalName", "JASP"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2003"
|
||||
VALUE "OriginalFilename", "jasp.exe"
|
||||
VALUE "ProductName", "Jedi Knight®: Jedi Academy"
|
||||
VALUE "ProductVersion", VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
126
code/win32/xbox_texture_man.h
Normal file
126
code/win32/xbox_texture_man.h
Normal file
@@ -0,0 +1,126 @@
|
||||
|
||||
/*
|
||||
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
||||
* United States. Use of a copyright notice is precautionary only and
|
||||
* does not imply publication or disclosure.
|
||||
*
|
||||
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
||||
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
||||
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
||||
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
||||
*/
|
||||
|
||||
#ifndef __XBOX_TEXTURE_MAN_H__
|
||||
#define __XBOX_TEXTURE_MAN_H__
|
||||
|
||||
#include "glw_win_dx8.h"
|
||||
#include <xtl.h>
|
||||
|
||||
|
||||
// Texture allocator that never frees anything, just grows until it's totally reset:
|
||||
class StaticTextureAllocator
|
||||
{
|
||||
public:
|
||||
StaticTextureAllocator( void ) { }
|
||||
|
||||
void Initialize( unsigned long size )
|
||||
{
|
||||
base = (unsigned char *) D3D_AllocContiguousMemory( size, 0 );
|
||||
allocPoint = 0;
|
||||
poolSize = size;
|
||||
maxAlloc = 0;
|
||||
swappedSize = 0;
|
||||
swappedPoint = 0;
|
||||
}
|
||||
|
||||
// No bookkeeping necessary, texNum is unused:
|
||||
void *Allocate( unsigned long size, GLuint texNum )
|
||||
{
|
||||
#ifndef FINAL_BUILD
|
||||
if( allocPoint + size > poolSize )
|
||||
throw "Static texture pool full";
|
||||
#endif
|
||||
|
||||
// Current location:
|
||||
void *retVal = base + allocPoint;
|
||||
|
||||
// Advance, then round up:
|
||||
allocPoint += size;
|
||||
allocPoint = (allocPoint + 127) & ~127;
|
||||
|
||||
#ifndef FINAL_BUILD
|
||||
if( allocPoint > maxAlloc )
|
||||
maxAlloc = allocPoint;
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void Reset( void )
|
||||
{
|
||||
// Just move our allocation marker back to the start:
|
||||
allocPoint = 0;
|
||||
}
|
||||
|
||||
// This is used by the bink code to make room for a giant texture
|
||||
// that doesn't need to live at the same time as any others
|
||||
void SwapTextureMemory( unsigned long size )
|
||||
{
|
||||
assert( !swappedPoint && !swappedSize && (size < poolSize) );
|
||||
|
||||
// Save off old texturePoint:
|
||||
swappedPoint = allocPoint;
|
||||
swappedSize = size;
|
||||
|
||||
// Reset texture pool to the beginning of the block:
|
||||
allocPoint = 0;
|
||||
|
||||
// Save whatever's there now:
|
||||
DWORD dwWritten = 0;
|
||||
HANDLE h = CreateFile( "Z:\\texswap", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
|
||||
assert( h != INVALID_HANDLE_VALUE );
|
||||
if( !WriteFile( h, base, size, &dwWritten, NULL ) || (dwWritten != size) )
|
||||
assert( 0 );
|
||||
|
||||
CloseHandle( h );
|
||||
}
|
||||
|
||||
void UnswapTextureMemory( void )
|
||||
{
|
||||
assert( swappedSize );
|
||||
|
||||
// Read back the data we dumped out before:
|
||||
DWORD dwRead = 0;
|
||||
HANDLE h = CreateFile( "Z:\\texswap", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
|
||||
assert( h != INVALID_HANDLE_VALUE );
|
||||
if( !ReadFile( h, base, swappedSize, &dwRead, NULL ) || (dwRead != swappedSize) )
|
||||
assert( 0 );
|
||||
|
||||
CloseHandle( h );
|
||||
|
||||
// Reset texture point
|
||||
allocPoint = swappedPoint;
|
||||
swappedPoint = 0;
|
||||
swappedSize = 0;
|
||||
}
|
||||
|
||||
unsigned long Size( void )
|
||||
{
|
||||
return allocPoint;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char *base;
|
||||
unsigned long allocPoint;
|
||||
unsigned long poolSize;
|
||||
unsigned long maxAlloc;
|
||||
|
||||
// Extra bookkeeping for Bink texture nastiness:
|
||||
unsigned long swappedSize;
|
||||
unsigned long swappedPoint;
|
||||
};
|
||||
|
||||
// Global texture allocators:
|
||||
extern StaticTextureAllocator gTextures;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user