mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-07-04 05:55:47 -07:00
Minor additions: Added hotkeys to GUI buttons, camera bookmarking (not sure if this system will stay), shoring up some JS error checking, moved a bunch of constants into the config file and added a new rotation mode.
This was SVN commit r804.
This commit is contained in:
parent
5ea728fd28
commit
6d8b9e33ef
21 changed files with 452 additions and 229 deletions
|
|
@ -185,4 +185,16 @@ void CCamera::GetScreenCoordinates( const CVector3D& world, float& x, float& y )
|
||||||
y = screenspace.Y / screenspace.Z;
|
y = screenspace.Y / screenspace.Z;
|
||||||
x = ( x + 1 ) * 0.5f * g_Renderer.GetWidth();
|
x = ( x + 1 ) * 0.5f * g_Renderer.GetWidth();
|
||||||
y = ( 1 - y ) * 0.5f * g_Renderer.GetHeight();
|
y = ( 1 - y ) * 0.5f * g_Renderer.GetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCamera::LookAt( const CVector3D& camera, const CVector3D& target, const CVector3D& up )
|
||||||
|
{
|
||||||
|
CVector3D delta = target - camera;
|
||||||
|
delta.Normalize();
|
||||||
|
CVector3D s = delta.Cross( up );
|
||||||
|
CVector3D u = s.Cross( delta );
|
||||||
|
m_Orientation._11 = -s.X; m_Orientation._12 = up.X; m_Orientation._13 = delta.X; m_Orientation._14 = camera.X;
|
||||||
|
m_Orientation._21 = -s.Y; m_Orientation._22 = up.Y; m_Orientation._23 = delta.Y; m_Orientation._24 = camera.Y;
|
||||||
|
m_Orientation._31 = -s.Z; m_Orientation._32 = up.Z; m_Orientation._33 = delta.Z; m_Orientation._34 = camera.Z;
|
||||||
|
m_Orientation._41 = 0.0f; m_Orientation._42 = 0.0f; m_Orientation._43 = 0.0f; m_Orientation._44 = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
@ -71,6 +71,10 @@ class CCamera
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetScreenCoordinates( const CVector3D& world, float& x, float& y );
|
void GetScreenCoordinates( const CVector3D& world, float& x, float& y );
|
||||||
|
|
||||||
|
// Build an orientation matrix from camera position, camera target, and up-vector
|
||||||
|
void LookAt( const CVector3D& camera, const CVector3D& target, const CVector3D& up );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//This is the orientation matrix. The inverse of this
|
//This is the orientation matrix. The inverse of this
|
||||||
//is the view matrix
|
//is the view matrix
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ gee@pyro.nu
|
||||||
#include "Overlay.h"
|
#include "Overlay.h"
|
||||||
|
|
||||||
#include "scripting/ScriptingHost.h"
|
#include "scripting/ScriptingHost.h"
|
||||||
|
#include "Hotkey.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -63,6 +64,18 @@ int gui_handler(const SDL_Event* ev)
|
||||||
|
|
||||||
int CGUI::HandleEvent(const SDL_Event* ev)
|
int CGUI::HandleEvent(const SDL_Event* ev)
|
||||||
{
|
{
|
||||||
|
// MT: If something's gone wrong, check this block... (added for hotkey support)
|
||||||
|
|
||||||
|
if( ev->type == SDL_GUIHOTKEYPRESS )
|
||||||
|
{
|
||||||
|
const CStr& objectName = *( (CStr*)ev->user.code );
|
||||||
|
IGUIObject* object = FindObjectByName( objectName );
|
||||||
|
object->HandleMessage( SGUIMessage( GUIM_PRESSED ) );
|
||||||
|
object->ScriptEvent( "press" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- MT
|
||||||
|
|
||||||
if(ev->type == SDL_MOUSEMOTION)
|
if(ev->type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
m_MousePos = CPos(ev->motion.x, ev->motion.y);
|
m_MousePos = CPos(ev->motion.x, ev->motion.y);
|
||||||
|
|
@ -106,6 +119,7 @@ int CGUI::HandleEvent(const SDL_Event* ev)
|
||||||
// Now we'll call UpdateMouseOver on *all* objects,
|
// Now we'll call UpdateMouseOver on *all* objects,
|
||||||
// we'll input the one hovered, and they will each
|
// we'll input the one hovered, and they will each
|
||||||
// update their own data and send messages accordingly
|
// update their own data and send messages accordingly
|
||||||
|
|
||||||
GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
|
GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
|
||||||
&IGUIObject::UpdateMouseOver,
|
&IGUIObject::UpdateMouseOver,
|
||||||
pNearest);
|
pNearest);
|
||||||
|
|
@ -1067,6 +1081,9 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
|
||||||
ATTR(style);
|
ATTR(style);
|
||||||
ATTR(type);
|
ATTR(type);
|
||||||
ATTR(name);
|
ATTR(name);
|
||||||
|
// MT - temp tag
|
||||||
|
ATTR(hotkey);
|
||||||
|
// -- MT
|
||||||
ATTR(z);
|
ATTR(z);
|
||||||
ATTR(on);
|
ATTR(on);
|
||||||
ATTR(file);
|
ATTR(file);
|
||||||
|
|
@ -1101,6 +1118,10 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
|
||||||
bool NameSet = false;
|
bool NameSet = false;
|
||||||
bool ManuallySetZ = false; // if z has been manually set, this turn true
|
bool ManuallySetZ = false; // if z has been manually set, this turn true
|
||||||
|
|
||||||
|
// MT - temp tag
|
||||||
|
CStr hotkeyTag( "" );
|
||||||
|
// -- MT
|
||||||
|
|
||||||
// Now we can iterate all attributes and store
|
// Now we can iterate all attributes and store
|
||||||
for (i=0; i<attributes.Count; ++i)
|
for (i=0; i<attributes.Count; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -1122,6 +1143,12 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MT - temp tag
|
||||||
|
// Wire up the hotkey tag, if it has one
|
||||||
|
if( attr.Name == attr_hotkey )
|
||||||
|
hotkeyTag = attr.Value;
|
||||||
|
// -- MT
|
||||||
|
|
||||||
if (attr.Name == attr_z)
|
if (attr.Name == attr_z)
|
||||||
ManuallySetZ = true;
|
ManuallySetZ = true;
|
||||||
|
|
||||||
|
|
@ -1184,6 +1211,11 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
|
||||||
++m_InternalNameNumber;
|
++m_InternalNameNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MT - temp tag
|
||||||
|
// Attempt to register the hotkey tag, if one was provided
|
||||||
|
if( hotkeyTag.Length() )
|
||||||
|
hotkeyRegisterGUIObject( object->GetName(), hotkeyTag );
|
||||||
|
// -- MT
|
||||||
|
|
||||||
CStr caption = (CStr)Element.getText();
|
CStr caption = (CStr)Element.getText();
|
||||||
caption.Trim(PS_TRIM_BOTH);
|
caption.Trim(PS_TRIM_BOTH);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ IGUIObject::IGUIObject() :
|
||||||
AddSetting(GUIST_bool, "hidden");
|
AddSetting(GUIST_bool, "hidden");
|
||||||
AddSetting(GUIST_CClientArea, "size");
|
AddSetting(GUIST_CClientArea, "size");
|
||||||
AddSetting(GUIST_CStr, "style");
|
AddSetting(GUIST_CStr, "style");
|
||||||
|
// MT - temp tag
|
||||||
|
AddSetting(GUIST_CStr, "hotkey" );
|
||||||
|
// -- MT
|
||||||
AddSetting(GUIST_float, "z");
|
AddSetting(GUIST_float, "z");
|
||||||
// AddSetting(GUIST_CGUIString, "caption");
|
// AddSetting(GUIST_CGUIString, "caption");
|
||||||
AddSetting(GUIST_bool, "absolute");
|
AddSetting(GUIST_bool, "absolute");
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ SDL_ActiveEvent;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u16 code;
|
intptr_t code;
|
||||||
}
|
}
|
||||||
SDL_UserEvent;
|
SDL_UserEvent;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -714,6 +714,8 @@ static void psInit()
|
||||||
g_Console->m_iFontHeight = unifont_linespacing(g_Font_Console);
|
g_Console->m_iFontHeight = unifont_linespacing(g_Font_Console);
|
||||||
g_Console->m_iFontOffset = 9;
|
g_Console->m_iFontOffset = 9;
|
||||||
|
|
||||||
|
loadHotkeys();
|
||||||
|
|
||||||
#ifndef NO_GUI
|
#ifndef NO_GUI
|
||||||
// GUI uses VFS, so this must come after VFS init.
|
// GUI uses VFS, so this must come after VFS init.
|
||||||
g_GUI.Initialize();
|
g_GUI.Initialize();
|
||||||
|
|
@ -971,14 +973,13 @@ if(!g_MapFile)
|
||||||
|
|
||||||
in_add_handler(interactInputHandler);
|
in_add_handler(interactInputHandler);
|
||||||
|
|
||||||
in_add_handler(conInputHandler);
|
|
||||||
#ifndef NO_GUI
|
#ifndef NO_GUI
|
||||||
in_add_handler(gui_handler);
|
in_add_handler(gui_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
in_add_handler(hotkeyInputHandler);
|
in_add_handler(conInputHandler);
|
||||||
|
|
||||||
loadHotkeys();
|
in_add_handler(hotkeyInputHandler); // <- Leave this one until after all the others.
|
||||||
|
|
||||||
MICROLOG(L"render blank");
|
MICROLOG(L"render blank");
|
||||||
// render everything to a blank frame to force renderer to load everything
|
// render everything to a blank frame to force renderer to load everything
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ bool CConfigDB::Reload(EConfigNamespace ns)
|
||||||
|
|
||||||
for( size_t t = 0; t < argCount; t++ )
|
for( size_t t = 0; t < argCount; t++ )
|
||||||
{
|
{
|
||||||
if( !parserLine.GetArgString( t + 1, value ) )
|
if( !parserLine.GetArgString( (int)t + 1, value ) )
|
||||||
continue;
|
continue;
|
||||||
CConfigValue argument;
|
CConfigValue argument;
|
||||||
argument.m_String = value;
|
argument.m_String = value;
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,30 @@
|
||||||
#include "Hotkey.h"
|
#include "Hotkey.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "ConfigDB.h"
|
#include "ConfigDB.h"
|
||||||
|
#include "CConsole.h"
|
||||||
|
#include "CStr.h"
|
||||||
|
|
||||||
bool hotkeys[HOTKEY_LAST];
|
extern CConsole* g_Console;
|
||||||
extern bool keys[SDLK_LAST];
|
extern bool keys[SDLK_LAST];
|
||||||
extern bool mouseButtons[5];
|
extern bool mouseButtons[5];
|
||||||
|
|
||||||
|
/* SDL-type */
|
||||||
|
|
||||||
struct SHotkeyMapping
|
struct SHotkeyMapping
|
||||||
{
|
{
|
||||||
int mapsTo;
|
int mapsTo;
|
||||||
std::vector<int> requires;
|
std::vector<int> requires;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<SHotkeyMapping> hotkeyMap[SDLK_LAST + 5];
|
typedef std::vector<SHotkeyMapping> KeyMapping;
|
||||||
|
|
||||||
|
// A mapping of keycodes onto sets of SDL event codes
|
||||||
|
static KeyMapping hotkeyMap[SDLK_LAST + 5];
|
||||||
|
|
||||||
|
// An array of the status of virtual keys
|
||||||
|
bool hotkeys[HOTKEY_LAST];
|
||||||
|
|
||||||
|
// 'Keycodes' for the mouse buttons
|
||||||
const int MOUSE_LEFT = SDLK_LAST + SDL_BUTTON_LEFT;
|
const int MOUSE_LEFT = SDLK_LAST + SDL_BUTTON_LEFT;
|
||||||
const int MOUSE_RIGHT = SDLK_LAST + SDL_BUTTON_RIGHT;
|
const int MOUSE_RIGHT = SDLK_LAST + SDL_BUTTON_RIGHT;
|
||||||
const int MOUSE_MIDDLE = SDLK_LAST + SDL_BUTTON_MIDDLE;
|
const int MOUSE_MIDDLE = SDLK_LAST + SDL_BUTTON_MIDDLE;
|
||||||
|
|
@ -40,11 +51,15 @@ static SHotkeyInfo hotkeyInfo[] =
|
||||||
{ HOTKEY_CAMERA_ZOOM_WHEEL_IN, "camera.zoom.wheel.in", MOUSE_WHEELUP, 0 },
|
{ HOTKEY_CAMERA_ZOOM_WHEEL_IN, "camera.zoom.wheel.in", MOUSE_WHEELUP, 0 },
|
||||||
{ HOTKEY_CAMERA_ZOOM_WHEEL_OUT, "camera.zoom.wheel.out", MOUSE_WHEELDOWN, 0 },
|
{ HOTKEY_CAMERA_ZOOM_WHEEL_OUT, "camera.zoom.wheel.out", MOUSE_WHEELDOWN, 0 },
|
||||||
{ HOTKEY_CAMERA_ROTATE, "camera.rotate", 0, 0 },
|
{ HOTKEY_CAMERA_ROTATE, "camera.rotate", 0, 0 },
|
||||||
|
{ HOTKEY_CAMERA_ROTATE_ABOUT_TARGET, "camera.rotate.abouttarget", 0, 0 },
|
||||||
{ HOTKEY_CAMERA_PAN, "camera.pan", MOUSE_MIDDLE, 0 },
|
{ HOTKEY_CAMERA_PAN, "camera.pan", MOUSE_MIDDLE, 0 },
|
||||||
{ HOTKEY_CAMERA_PAN_LEFT, "camera.pan.left", SDLK_LEFT, 0 },
|
{ HOTKEY_CAMERA_PAN_LEFT, "camera.pan.left", SDLK_LEFT, 0 },
|
||||||
{ HOTKEY_CAMERA_PAN_RIGHT, "camera.pan.right", SDLK_RIGHT, 0 },
|
{ HOTKEY_CAMERA_PAN_RIGHT, "camera.pan.right", SDLK_RIGHT, 0 },
|
||||||
{ HOTKEY_CAMERA_PAN_FORWARD, "camera.pan.forward", SDLK_UP, 0 },
|
{ HOTKEY_CAMERA_PAN_FORWARD, "camera.pan.forward", SDLK_UP, 0 },
|
||||||
{ HOTKEY_CAMERA_PAN_BACKWARD, "camera.pan.backward", SDLK_DOWN, 0 },
|
{ HOTKEY_CAMERA_PAN_BACKWARD, "camera.pan.backward", SDLK_DOWN, 0 },
|
||||||
|
{ HOTKEY_CAMERA_BOOKMARK_MODIFIER, "camera.bookmark.modifier", 0, 0 },
|
||||||
|
{ HOTKEY_CAMERA_BOOKMARK_SAVE, "camera.bookmark.save", 0, 0 },
|
||||||
|
{ HOTKEY_CAMERA_BOOKMARK_SNAP, "camera.bookmark.snap", 0, 0 },
|
||||||
{ HOTKEY_CONSOLE_TOGGLE, "console.toggle", SDLK_F1, 0 },
|
{ HOTKEY_CONSOLE_TOGGLE, "console.toggle", SDLK_F1, 0 },
|
||||||
{ HOTKEY_SELECTION_ADD, "selection.add", SDLK_LSHIFT, SDLK_RSHIFT },
|
{ HOTKEY_SELECTION_ADD, "selection.add", SDLK_LSHIFT, SDLK_RSHIFT },
|
||||||
{ HOTKEY_SELECTION_REMOVE, "selection.remove", SDLK_LCTRL, SDLK_RCTRL },
|
{ HOTKEY_SELECTION_REMOVE, "selection.remove", SDLK_LCTRL, SDLK_RCTRL },
|
||||||
|
|
@ -52,89 +67,134 @@ static SHotkeyInfo hotkeyInfo[] =
|
||||||
{ HOTKEY_SELECTION_GROUP_SAVE, "selection.group.save", SDLK_LCTRL, SDLK_RCTRL },
|
{ HOTKEY_SELECTION_GROUP_SAVE, "selection.group.save", SDLK_LCTRL, SDLK_RCTRL },
|
||||||
{ HOTKEY_SELECTION_GROUP_SNAP, "selection.group.snap", SDLK_LALT, SDLK_RALT },
|
{ HOTKEY_SELECTION_GROUP_SNAP, "selection.group.snap", SDLK_LALT, SDLK_RALT },
|
||||||
{ HOTKEY_SELECTION_SNAP, "selection.snap", SDLK_HOME, 0 },
|
{ HOTKEY_SELECTION_SNAP, "selection.snap", SDLK_HOME, 0 },
|
||||||
|
{ HOTKEY_ORDER_QUEUE, "order.queue", SDLK_LSHIFT, SDLK_RSHIFT },
|
||||||
{ HOTKEY_CONTEXTORDER_NEXT, "contextorder.next", SDLK_RIGHTBRACKET, 0 },
|
{ HOTKEY_CONTEXTORDER_NEXT, "contextorder.next", SDLK_RIGHTBRACKET, 0 },
|
||||||
{ HOTKEY_CONTEXTORDER_PREVIOUS, "contextorder.previous", SDLK_LEFTBRACKET, 0 },
|
{ HOTKEY_CONTEXTORDER_PREVIOUS, "contextorder.previous", SDLK_LEFTBRACKET, 0 },
|
||||||
{ HOTKEY_HIGHLIGHTALL, "highlightall", SDLK_o, 0 }
|
{ HOTKEY_HIGHLIGHTALL, "highlightall", SDLK_o, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* SDL-type ends */
|
||||||
|
|
||||||
|
/* GUI-type */
|
||||||
|
|
||||||
|
struct SHotkeyMappingGUI
|
||||||
|
{
|
||||||
|
CStr mapsTo;
|
||||||
|
std::vector<int> requires;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<SHotkeyMappingGUI> GuiMapping;
|
||||||
|
|
||||||
|
// A mapping of keycodes onto sets of hotkey name strings (e.g. '[hotkey.]camera.reset')
|
||||||
|
static GuiMapping hotkeyMapGUI[SDLK_LAST + 5];
|
||||||
|
|
||||||
|
typedef std::vector<CStr> GUIObjectList; // A list of GUI objects
|
||||||
|
typedef std::map<CStr,GUIObjectList> GUIHotkeyMap; // A mapping of name strings to lists of GUI objects that they trigger
|
||||||
|
|
||||||
|
static GUIHotkeyMap guiHotkeyMap;
|
||||||
|
|
||||||
|
// Look up a key binding in the config file and set the mappings for
|
||||||
|
// all key combinations that trigger it.
|
||||||
|
|
||||||
|
void setBindings( const CStr& hotkeyName, int integerMapping = -1 )
|
||||||
|
{
|
||||||
|
CConfigValueSet* binding = g_ConfigDB.GetValues( CFG_SYSTEM, CStr( "hotkey." ) + hotkeyName );
|
||||||
|
if( binding )
|
||||||
|
{
|
||||||
|
int mapping;
|
||||||
|
|
||||||
|
CConfigValueSet::iterator it;
|
||||||
|
CParser multikeyParser;
|
||||||
|
multikeyParser.InputTaskType( "multikey", "<_$value_+_>_$value" );
|
||||||
|
|
||||||
|
// Iterate through the bindings for this event...
|
||||||
|
|
||||||
|
for( it = binding->begin(); it != binding->end(); it++ )
|
||||||
|
{
|
||||||
|
std::string hotkey;
|
||||||
|
if( it->GetString( hotkey ) )
|
||||||
|
{
|
||||||
|
std::vector<int> keyCombination;
|
||||||
|
|
||||||
|
CParserLine multikeyIdentifier;
|
||||||
|
multikeyIdentifier.ParseString( multikeyParser, hotkey );
|
||||||
|
|
||||||
|
// Iterate through multiple-key bindings (e.g. Ctrl+I)
|
||||||
|
|
||||||
|
for( size_t t = 0; t < multikeyIdentifier.GetArgCount(); t++ )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( multikeyIdentifier.GetArgString( (int)t, hotkey ) )
|
||||||
|
{
|
||||||
|
mapping = getKeyCode( hotkey ); // Attempt decode as key name
|
||||||
|
if( !mapping )
|
||||||
|
if( !it->GetInt( mapping ) ) // Attempt decode as key code
|
||||||
|
continue;
|
||||||
|
keyCombination.push_back( mapping );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int>::iterator itKey, itKey2;
|
||||||
|
|
||||||
|
SHotkeyMapping bindCode;
|
||||||
|
SHotkeyMappingGUI bindName;
|
||||||
|
|
||||||
|
for( itKey = keyCombination.begin(); itKey != keyCombination.end(); itKey++ )
|
||||||
|
{
|
||||||
|
bindName.mapsTo = hotkeyName;
|
||||||
|
bindName.requires.clear();
|
||||||
|
if( integerMapping != -1 )
|
||||||
|
{
|
||||||
|
bindCode.mapsTo = integerMapping;
|
||||||
|
bindCode.requires.clear();
|
||||||
|
}
|
||||||
|
for( itKey2 = keyCombination.begin(); itKey2 != keyCombination.end(); itKey2++ )
|
||||||
|
{
|
||||||
|
// Push any auxiliary keys.
|
||||||
|
if( itKey != itKey2 )
|
||||||
|
{
|
||||||
|
bindName.requires.push_back( *itKey2 );
|
||||||
|
if( integerMapping != -1 )
|
||||||
|
bindCode.requires.push_back( *itKey2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hotkeyMapGUI[*itKey].push_back( bindName );
|
||||||
|
if( integerMapping != -1 )
|
||||||
|
hotkeyMap[*itKey].push_back( bindCode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( integerMapping != -1 )
|
||||||
|
{
|
||||||
|
SHotkeyMapping bind[2];
|
||||||
|
bind[0].mapsTo = integerMapping;
|
||||||
|
bind[1].mapsTo = integerMapping;
|
||||||
|
bind[0].requires.clear();
|
||||||
|
bind[1].requires.clear();
|
||||||
|
hotkeyMap[ hotkeyInfo[integerMapping].defaultmapping1 ].push_back( bind[0] );
|
||||||
|
if( hotkeyInfo[integerMapping].defaultmapping2 )
|
||||||
|
hotkeyMap[ hotkeyInfo[integerMapping].defaultmapping2 ].push_back( bind[1] );
|
||||||
|
}
|
||||||
|
}
|
||||||
void loadHotkeys()
|
void loadHotkeys()
|
||||||
{
|
{
|
||||||
initKeyNameMap();
|
initKeyNameMap();
|
||||||
|
|
||||||
CParser multikeyParser;
|
|
||||||
multikeyParser.InputTaskType( "multikey", "<_$value_+_>_$value" );
|
|
||||||
|
|
||||||
for( int i = 0; i < HOTKEY_LAST; i++ )
|
for( int i = 0; i < HOTKEY_LAST; i++ )
|
||||||
|
setBindings( hotkeyInfo[i].name, i );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void hotkeyRegisterGUIObject( const CStr& objName, const CStr& hotkeyName )
|
||||||
|
{
|
||||||
|
GUIObjectList& boundTo = guiHotkeyMap[hotkeyName];
|
||||||
|
if( boundTo.empty() )
|
||||||
{
|
{
|
||||||
CStr hotkeyname( "hotkey." );
|
// Load keybindings from the config file
|
||||||
hotkeyname += hotkeyInfo[i].name;
|
setBindings( hotkeyName );
|
||||||
|
|
||||||
CConfigValueSet* binding = g_ConfigDB.GetValues( CFG_SYSTEM, hotkeyname );
|
|
||||||
|
|
||||||
if( binding )
|
|
||||||
{
|
|
||||||
int mapping;
|
|
||||||
|
|
||||||
CConfigValueSet::iterator it;
|
|
||||||
|
|
||||||
// Iterate through the bindings for this event...
|
|
||||||
|
|
||||||
for( it = binding->begin(); it != binding->end(); it++ )
|
|
||||||
{
|
|
||||||
std::string hotkey;
|
|
||||||
if( it->GetString( hotkey ) )
|
|
||||||
{
|
|
||||||
std::vector<int> keyCombination;
|
|
||||||
|
|
||||||
CParserLine multikeyIdentifier;
|
|
||||||
multikeyIdentifier.ParseString( multikeyParser, hotkey );
|
|
||||||
|
|
||||||
// Iterate through multiple-key bindings (e.g. Ctrl+I)
|
|
||||||
|
|
||||||
for( size_t t = 0; t < multikeyIdentifier.GetArgCount(); t++ )
|
|
||||||
{
|
|
||||||
|
|
||||||
if( multikeyIdentifier.GetArgString( (int)t, hotkey ) )
|
|
||||||
{
|
|
||||||
mapping = getKeyCode( hotkey ); // Attempt decode as key name
|
|
||||||
if( !mapping )
|
|
||||||
if( !it->GetInt( mapping ) ) // Attempt decode as key code
|
|
||||||
continue;
|
|
||||||
keyCombination.push_back( mapping );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int>::iterator itKey, itKey2;
|
|
||||||
|
|
||||||
SHotkeyMapping bind;
|
|
||||||
|
|
||||||
for( itKey = keyCombination.begin(); itKey != keyCombination.end(); itKey++ )
|
|
||||||
{
|
|
||||||
bind.mapsTo = i;
|
|
||||||
bind.requires.clear();
|
|
||||||
for( itKey2 = keyCombination.begin(); itKey2 != keyCombination.end(); itKey2++ )
|
|
||||||
{
|
|
||||||
// Push any auxiliary keys.
|
|
||||||
if( itKey != itKey2 )
|
|
||||||
bind.requires.push_back( *itKey2 );
|
|
||||||
}
|
|
||||||
hotkeyMap[*itKey].push_back( bind );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SHotkeyMapping bind[2];
|
|
||||||
bind[0].mapsTo = i;
|
|
||||||
bind[1].mapsTo = i;
|
|
||||||
bind[0].requires.clear();
|
|
||||||
bind[1].requires.clear();
|
|
||||||
hotkeyMap[ hotkeyInfo[i].defaultmapping1 ].push_back( bind[0] );
|
|
||||||
if( hotkeyInfo[i].defaultmapping2 )
|
|
||||||
hotkeyMap[ hotkeyInfo[i].defaultmapping2 ].push_back( bind[1] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
boundTo.push_back( objName );
|
||||||
}
|
}
|
||||||
|
|
||||||
int hotkeyInputHandler( const SDL_Event* ev )
|
int hotkeyInputHandler( const SDL_Event* ev )
|
||||||
|
|
@ -155,11 +215,22 @@ int hotkeyInputHandler( const SDL_Event* ev )
|
||||||
return( EV_PASS );
|
return( EV_PASS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inhibit the dispatch of hotkey events caused by printable or control keys
|
||||||
|
// while the console is up.
|
||||||
|
|
||||||
|
if( g_Console->IsActive() && (
|
||||||
|
( keycode == 8 ) || ( keycode == 9 ) || ( keycode == 13 ) || /* Editing */
|
||||||
|
( ( keycode >= 32 ) && ( keycode < 282 ) ) ) ) /* Printable (<128), 'World' (<256) */
|
||||||
|
return( EV_PASS ); /* Numeric keypad (<273) and Navigation (<282) */
|
||||||
|
|
||||||
std::vector<SHotkeyMapping>::iterator it;
|
std::vector<SHotkeyMapping>::iterator it;
|
||||||
|
std::vector<SHotkeyMappingGUI>::iterator itGUI;
|
||||||
|
|
||||||
SDL_Event hotkeyNotification;
|
SDL_Event hotkeyNotification;
|
||||||
|
|
||||||
if( ( ev->type == SDL_KEYDOWN ) || ( ev->type == SDL_MOUSEBUTTONDOWN ) )
|
if( ( ev->type == SDL_KEYDOWN ) || ( ev->type == SDL_MOUSEBUTTONDOWN ) )
|
||||||
{
|
{
|
||||||
|
// SDL-events bit
|
||||||
for( it = hotkeyMap[keycode].begin(); it < hotkeyMap[keycode].end(); it++ )
|
for( it = hotkeyMap[keycode].begin(); it < hotkeyMap[keycode].end(); it++ )
|
||||||
{
|
{
|
||||||
// Check to see if all auxiliary keys are down
|
// Check to see if all auxiliary keys are down
|
||||||
|
|
@ -187,6 +258,45 @@ int hotkeyInputHandler( const SDL_Event* ev )
|
||||||
SDL_PushEvent( &hotkeyNotification );
|
SDL_PushEvent( &hotkeyNotification );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// GUI bit... could do with some optimization later.
|
||||||
|
for( itGUI = hotkeyMapGUI[keycode].begin(); itGUI != hotkeyMapGUI[keycode].end(); itGUI++ )
|
||||||
|
{
|
||||||
|
// Check to see if all auxiliary keys are down
|
||||||
|
|
||||||
|
std::vector<int>::iterator itKey;
|
||||||
|
bool accept = true;
|
||||||
|
|
||||||
|
for( itKey = itGUI->requires.begin(); itKey != itGUI->requires.end(); itKey++ )
|
||||||
|
{
|
||||||
|
if( *itKey < SDLK_LAST )
|
||||||
|
{
|
||||||
|
if( !keys[*itKey] ) accept = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !mouseButtons[(*itKey)-SDLK_LAST] ) accept = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( accept )
|
||||||
|
{
|
||||||
|
// GUI-objects bit
|
||||||
|
// This fragment is an obvious candidate for rewriting when speed becomes an issue.
|
||||||
|
GUIHotkeyMap::iterator map_it;
|
||||||
|
GUIObjectList::iterator obj_it;
|
||||||
|
map_it = guiHotkeyMap.find( itGUI->mapsTo );
|
||||||
|
if( map_it != guiHotkeyMap.end() )
|
||||||
|
{
|
||||||
|
GUIObjectList& targets = map_it->second;
|
||||||
|
for( obj_it = targets.begin(); obj_it != targets.end(); obj_it++ )
|
||||||
|
{
|
||||||
|
hotkeyNotification.type = SDL_GUIHOTKEYPRESS;
|
||||||
|
hotkeyNotification.user.code = (intptr_t)&(*obj_it);
|
||||||
|
SDL_PushEvent( &hotkeyNotification );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@
|
||||||
// Constant definitions and a couple of exports for the hotkey processor
|
// Constant definitions and a couple of exports for the hotkey processor
|
||||||
//
|
//
|
||||||
// Mark Thompson (mot20@cam.ac.uk / mark@wildfiregames.com)
|
// Mark Thompson (mot20@cam.ac.uk / mark@wildfiregames.com)
|
||||||
|
//
|
||||||
// Adding a hotkey:
|
// Hotkeys can be mapped onto SDL events (for use internal to the engine),
|
||||||
|
// or used to trigger activation of GUI buttons.
|
||||||
|
//
|
||||||
|
// Adding a hotkey (SDL event type):
|
||||||
//
|
//
|
||||||
// - Define your constant in the enum, just below;
|
// - Define your constant in the enum, just below;
|
||||||
// - Add an entry to hotkeyInfo[], in Hotkey.cpp
|
// - Add an entry to hotkeyInfo[], in Hotkey.cpp
|
||||||
|
|
@ -20,6 +23,7 @@
|
||||||
|
|
||||||
const int SDL_HOTKEYDOWN = SDL_USEREVENT;
|
const int SDL_HOTKEYDOWN = SDL_USEREVENT;
|
||||||
const int SDL_HOTKEYUP = SDL_USEREVENT + 1;
|
const int SDL_HOTKEYUP = SDL_USEREVENT + 1;
|
||||||
|
const int SDL_GUIHOTKEYPRESS = SDL_USEREVENT + 2;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
@ -32,11 +36,15 @@ enum
|
||||||
HOTKEY_CAMERA_ZOOM_WHEEL_IN,
|
HOTKEY_CAMERA_ZOOM_WHEEL_IN,
|
||||||
HOTKEY_CAMERA_ZOOM_WHEEL_OUT,
|
HOTKEY_CAMERA_ZOOM_WHEEL_OUT,
|
||||||
HOTKEY_CAMERA_ROTATE,
|
HOTKEY_CAMERA_ROTATE,
|
||||||
|
HOTKEY_CAMERA_ROTATE_ABOUT_TARGET,
|
||||||
HOTKEY_CAMERA_PAN,
|
HOTKEY_CAMERA_PAN,
|
||||||
HOTKEY_CAMERA_PAN_LEFT,
|
HOTKEY_CAMERA_PAN_LEFT,
|
||||||
HOTKEY_CAMERA_PAN_RIGHT,
|
HOTKEY_CAMERA_PAN_RIGHT,
|
||||||
HOTKEY_CAMERA_PAN_FORWARD,
|
HOTKEY_CAMERA_PAN_FORWARD,
|
||||||
HOTKEY_CAMERA_PAN_BACKWARD,
|
HOTKEY_CAMERA_PAN_BACKWARD,
|
||||||
|
HOTKEY_CAMERA_BOOKMARK_MODIFIER,
|
||||||
|
HOTKEY_CAMERA_BOOKMARK_SAVE,
|
||||||
|
HOTKEY_CAMERA_BOOKMARK_SNAP,
|
||||||
HOTKEY_CONSOLE_TOGGLE,
|
HOTKEY_CONSOLE_TOGGLE,
|
||||||
HOTKEY_SELECTION_ADD,
|
HOTKEY_SELECTION_ADD,
|
||||||
HOTKEY_SELECTION_REMOVE,
|
HOTKEY_SELECTION_REMOVE,
|
||||||
|
|
@ -44,6 +52,7 @@ enum
|
||||||
HOTKEY_SELECTION_GROUP_SAVE,
|
HOTKEY_SELECTION_GROUP_SAVE,
|
||||||
HOTKEY_SELECTION_GROUP_SNAP,
|
HOTKEY_SELECTION_GROUP_SNAP,
|
||||||
HOTKEY_SELECTION_SNAP,
|
HOTKEY_SELECTION_SNAP,
|
||||||
|
HOTKEY_ORDER_QUEUE,
|
||||||
HOTKEY_CONTEXTORDER_NEXT,
|
HOTKEY_CONTEXTORDER_NEXT,
|
||||||
HOTKEY_CONTEXTORDER_PREVIOUS,
|
HOTKEY_CONTEXTORDER_PREVIOUS,
|
||||||
HOTKEY_HIGHLIGHTALL,
|
HOTKEY_HIGHLIGHTALL,
|
||||||
|
|
@ -52,6 +61,7 @@ enum
|
||||||
|
|
||||||
void loadHotkeys();
|
void loadHotkeys();
|
||||||
int hotkeyInputHandler( const SDL_Event* ev );
|
int hotkeyInputHandler( const SDL_Event* ev );
|
||||||
|
void hotkeyRegisterGUIObject( const CStr& objName, const CStr& hotkeyName );
|
||||||
|
|
||||||
void initKeyNameMap();
|
void initKeyNameMap();
|
||||||
CStr getKeyName( int keycode );
|
CStr getKeyName( int keycode );
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,12 @@ void CSelectedEntities::update()
|
||||||
setCameraTarget( getGroupPosition( m_group_highlight ) );
|
setCameraTarget( getGroupPosition( m_group_highlight ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSelectedEntities::setContext( int contextOrder )
|
||||||
|
{
|
||||||
|
assert( isContextValid( contextOrder ) );
|
||||||
|
m_contextOrder = contextOrder;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSelectedEntities::nextContext()
|
bool CSelectedEntities::nextContext()
|
||||||
{
|
{
|
||||||
// No valid orders?
|
// No valid orders?
|
||||||
|
|
@ -342,8 +348,6 @@ bool CSelectedEntities::nextContext()
|
||||||
return( false );
|
return( false );
|
||||||
m_contextOrder = t;
|
m_contextOrder = t;
|
||||||
return( true );
|
return( true );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSelectedEntities::previousContext()
|
bool CSelectedEntities::previousContext()
|
||||||
|
|
@ -672,27 +676,53 @@ int interactInputHandler( const SDL_Event* ev )
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
if( ( ev->key.keysym.sym >= SDLK_0 ) && ( ev->key.keysym.sym <= SDLK_9 ) )
|
if( ( ev->key.keysym.sym >= SDLK_0 ) && ( ev->key.keysym.sym <= SDLK_9 ) )
|
||||||
{
|
{
|
||||||
u8 groupid = ev->key.keysym.sym - SDLK_0;
|
u8 id = ev->key.keysym.sym - SDLK_0;
|
||||||
if( hotkeys[HOTKEY_SELECTION_GROUP_ADD] )
|
// This competes with the camera bookmarks for the top-row number keys
|
||||||
|
// Find out which this is, and act accordingly
|
||||||
|
if( !hotkeys[HOTKEY_CAMERA_BOOKMARK_MODIFIER] )
|
||||||
{
|
{
|
||||||
g_Selection.addGroup( groupid );
|
if( hotkeys[HOTKEY_SELECTION_GROUP_ADD] )
|
||||||
}
|
{
|
||||||
else if( hotkeys[HOTKEY_SELECTION_GROUP_SAVE] )
|
g_Selection.addGroup( id );
|
||||||
{
|
}
|
||||||
g_Selection.saveGroup( groupid );
|
else if( hotkeys[HOTKEY_SELECTION_GROUP_SAVE] )
|
||||||
}
|
{
|
||||||
else if( hotkeys[HOTKEY_SELECTION_GROUP_SNAP] )
|
g_Selection.saveGroup( id );
|
||||||
{
|
}
|
||||||
g_Selection.highlightGroup( groupid );
|
else if( hotkeys[HOTKEY_SELECTION_GROUP_SNAP] )
|
||||||
|
{
|
||||||
|
g_Selection.highlightGroup( id );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ( g_Selection.m_group == id ) && g_Selection.getGroupCount( id ) )
|
||||||
|
{
|
||||||
|
setCameraTarget( g_Selection.getGroupPosition( id ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_Selection.loadGroup( id );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( ( g_Selection.m_group == groupid ) && g_Selection.getGroupCount( groupid ) )
|
if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SAVE] )
|
||||||
{
|
{
|
||||||
setCameraTarget( g_Selection.getGroupPosition( groupid ) );
|
cameraBookmarks[id] = g_Camera.m_Orientation.GetTranslation() + g_Camera.m_Orientation.GetIn() * 160.0f;
|
||||||
|
bookmarkInUse[id] = true;
|
||||||
|
}
|
||||||
|
else if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SNAP] )
|
||||||
|
{
|
||||||
|
if( bookmarkInUse[id] && ( currentBookmark == 255 ) )
|
||||||
|
{
|
||||||
|
pushCameraTarget( cameraBookmarks[id] );
|
||||||
|
currentBookmark = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_Selection.loadGroup( groupid );
|
{
|
||||||
|
if( bookmarkInUse[id] )
|
||||||
|
setCameraTarget( cameraBookmarks[id] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -723,6 +753,11 @@ int interactInputHandler( const SDL_Event* ev )
|
||||||
if( g_Selection.m_group_highlight != 255 )
|
if( g_Selection.m_group_highlight != 255 )
|
||||||
g_Selection.highlightNone();
|
g_Selection.highlightNone();
|
||||||
break;
|
break;
|
||||||
|
case HOTKEY_CAMERA_BOOKMARK_SNAP:
|
||||||
|
if( currentBookmark != 255 )
|
||||||
|
popCameraTarget();
|
||||||
|
currentBookmark = 255;
|
||||||
|
break;
|
||||||
case HOTKEY_HIGHLIGHTALL:
|
case HOTKEY_HIGHLIGHTALL:
|
||||||
g_Mouseover.m_viewall = false;
|
g_Mouseover.m_viewall = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -772,7 +807,7 @@ int interactInputHandler( const SDL_Event* ev )
|
||||||
g_Mouseover.setSelection();
|
g_Mouseover.setSelection();
|
||||||
break;
|
break;
|
||||||
case SDL_BUTTON_RIGHT:
|
case SDL_BUTTON_RIGHT:
|
||||||
g_Selection.contextOrder( keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT] );
|
g_Selection.contextOrder( hotkeys[HOTKEY_ORDER_QUEUE] );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,6 @@
|
||||||
#include "Scheduler.h"
|
#include "Scheduler.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
// In it's current incarnation, inefficient but pretty
|
|
||||||
#define SELECTION_TERRAIN_CONFORMANCE
|
|
||||||
|
|
||||||
#define SELECTION_CIRCLE_POINTS 25
|
|
||||||
#define SELECTION_BOX_POINTS 10
|
|
||||||
|
|
||||||
// CSelectedEntities: the singleton containing entities currently selected on the local machine.
|
// CSelectedEntities: the singleton containing entities currently selected on the local machine.
|
||||||
// (including group allocations on the local machine)
|
// (including group allocations on the local machine)
|
||||||
|
|
||||||
|
|
@ -51,6 +45,7 @@ struct CSelectedEntities : public Singleton<CSelectedEntities>
|
||||||
void update();
|
void update();
|
||||||
bool isContextValid( int contextOrder );
|
bool isContextValid( int contextOrder );
|
||||||
void contextOrder( bool pushQueue = false );
|
void contextOrder( bool pushQueue = false );
|
||||||
|
void setContext( int contextOrder );
|
||||||
bool nextContext();
|
bool nextContext();
|
||||||
bool previousContext();
|
bool previousContext();
|
||||||
|
|
||||||
|
|
@ -115,6 +110,9 @@ void popCameraTarget();
|
||||||
int interactInputHandler( const SDL_Event* ev );
|
int interactInputHandler( const SDL_Event* ev );
|
||||||
|
|
||||||
extern std::vector<CVector3D> cameraTargets;
|
extern std::vector<CVector3D> cameraTargets;
|
||||||
|
extern CVector3D cameraBookmarks[10];
|
||||||
|
extern bool bookmarkInUse[10];
|
||||||
|
extern u8 currentBookmark;
|
||||||
extern CVector3D cameraDelta;
|
extern CVector3D cameraDelta;
|
||||||
|
|
||||||
#define g_Selection CSelectedEntities::GetSingleton()
|
#define g_Selection CSelectedEntities::GetSingleton()
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,7 @@ void CRenderer::BeginFrame()
|
||||||
if (m_LightEnv) {
|
if (m_LightEnv) {
|
||||||
CVector3D dirlight;
|
CVector3D dirlight;
|
||||||
m_LightEnv->GetSunDirection(dirlight);
|
m_LightEnv->GetSunDirection(dirlight);
|
||||||
|
|
||||||
m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
||||||
m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor);
|
||||||
|
|
||||||
|
|
@ -363,6 +364,7 @@ void CRenderer::CalcShadowMatrices()
|
||||||
CVector3D lightdir;
|
CVector3D lightdir;
|
||||||
// ??? RC using matrix rotation to get sun direction?
|
// ??? RC using matrix rotation to get sun direction?
|
||||||
m_LightEnv->GetSunDirection(lightdir);
|
m_LightEnv->GetSunDirection(lightdir);
|
||||||
|
|
||||||
// ??? RC more optimal light placement?
|
// ??? RC more optimal light placement?
|
||||||
CVector3D lightpos=centre-(lightdir*1000);
|
CVector3D lightpos=centre-(lightdir*1000);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@
|
||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "BaseEntityCollection.h"
|
#include "BaseEntityCollection.h"
|
||||||
#include "Scheduler.h"
|
#include "Scheduler.h"
|
||||||
#include "Interact.h"
|
|
||||||
#include "scripting/JSInterface_Entity.h"
|
#include "scripting/JSInterface_Entity.h"
|
||||||
#include "scripting/JSInterface_BaseEntity.h"
|
#include "scripting/JSInterface_BaseEntity.h"
|
||||||
#include "scripting/JSInterface_Vector3D.h"
|
#include "scripting/JSInterface_Vector3D.h"
|
||||||
#include "gui/scripting/JSInterface_IGUIObject.h"
|
#include "gui/scripting/JSInterface_IGUIObject.h"
|
||||||
|
#include "scripting/JSInterface_Selection.h"
|
||||||
|
|
||||||
extern CConsole* g_Console;
|
extern CConsole* g_Console;
|
||||||
|
|
||||||
|
|
@ -50,8 +50,8 @@ enum ScriptGlobalTinyIDs
|
||||||
|
|
||||||
JSPropertySpec ScriptGlobalTable[] =
|
JSPropertySpec ScriptGlobalTable[] =
|
||||||
{
|
{
|
||||||
{ "selected", GLOBAL_SELECTED, JSPROP_PERMANENT, getSelected, setSelected },
|
{ "selected", GLOBAL_SELECTED, JSPROP_PERMANENT, JSI_Selected::getProperty, JSI_Selected::setProperty },
|
||||||
{ "selection", GLOBAL_SELECTIONARRAY, JSPROP_PERMANENT, getSelection, setSelection },
|
{ "selection", GLOBAL_SELECTIONARRAY, JSPROP_PERMANENT, JSI_Selection::getProperty, JSI_Selection::setProperty },
|
||||||
{ 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -233,82 +233,6 @@ JSBool cancelInterval( JSContext* context, JSObject* globalObject, unsigned int
|
||||||
return( JS_TRUE );
|
return( JS_TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool getSelected( JSContext* context, JSObject* globalObject, jsval id, jsval* vp )
|
|
||||||
{
|
|
||||||
if( g_Selection.m_selected.size() )
|
|
||||||
{
|
|
||||||
JSObject* entity = JS_NewObject( context, &JSI_Entity::JSI_class, NULL, NULL );
|
|
||||||
JS_SetPrivate( context, entity, new HEntity( g_Selection.m_selected[0]->me ) );
|
|
||||||
*vp = OBJECT_TO_JSVAL( entity );
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*vp = JSVAL_NULL;
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JSBool setSelected( JSContext* context, JSObject* globalObject, jsval id, jsval* vp )
|
|
||||||
{
|
|
||||||
g_Selection.clearSelection();
|
|
||||||
JSObject* selection = JSVAL_TO_OBJECT( *vp );
|
|
||||||
if( !JSVAL_IS_NULL( *vp ) && JSVAL_IS_OBJECT( *vp ) && ( JS_GetClass( selection ) == &JSI_Entity::JSI_class ) )
|
|
||||||
{
|
|
||||||
HEntity* entity = (HEntity*)JS_GetPrivate( context, selection );
|
|
||||||
g_Selection.addSelection( *entity );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
JS_ReportError( context, "[Entity] Invalid reference" );
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
JSBool getSelection( JSContext* context, JSObject* globalObject, jsval id, jsval* vp )
|
|
||||||
{
|
|
||||||
JSObject* selectionArray = JS_NewArrayObject( context, 0, NULL );
|
|
||||||
std::vector<CEntity*>::iterator it; int i;
|
|
||||||
for( it = g_Selection.m_selected.begin(), i = 0; it < g_Selection.m_selected.end(); it++, i++ )
|
|
||||||
{
|
|
||||||
JSObject* entity = JS_NewObject( context, &JSI_Entity::JSI_class, NULL, NULL );
|
|
||||||
JS_SetPrivate( context, entity, new HEntity( (*it)->me ) );
|
|
||||||
jsval j = OBJECT_TO_JSVAL( entity );
|
|
||||||
JS_SetElement( context, selectionArray, i, &j );
|
|
||||||
}
|
|
||||||
*vp = OBJECT_TO_JSVAL( selectionArray );
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
JSBool setSelection( JSContext* context, JSObject* globalObject, jsval id, jsval* vp )
|
|
||||||
{
|
|
||||||
g_Selection.clearSelection();
|
|
||||||
JSObject* selectionArray = JSVAL_TO_OBJECT( *vp );
|
|
||||||
if( JSVAL_IS_NULL( *vp ) || !JSVAL_IS_OBJECT( *vp ) || !JS_IsArrayObject( context, selectionArray ) )
|
|
||||||
{
|
|
||||||
JS_ReportError( context, "Not an array" );
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
jsuint selectionCount;
|
|
||||||
if( !JS_GetArrayLength( context, selectionArray, &selectionCount ) )
|
|
||||||
{
|
|
||||||
JS_ReportError( context, "Not an array" );
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
for( jsuint i = 0; i < selectionCount; i++ )
|
|
||||||
{
|
|
||||||
jsval entry;
|
|
||||||
JS_GetElement( context, selectionArray, i, &entry );
|
|
||||||
JSObject* selection = JSVAL_TO_OBJECT( entry );
|
|
||||||
if( !JSVAL_IS_NULL( entry ) && JSVAL_IS_OBJECT( entry ) && ( JS_GetClass( selection ) == &JSI_Entity::JSI_class ) )
|
|
||||||
{
|
|
||||||
HEntity* entity = (HEntity*)JS_GetPrivate( context, JSVAL_TO_OBJECT( entry ) );
|
|
||||||
g_Selection.addSelection( &(**entity) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
JS_ReportError( context, "[Entity] Invalid reference" );
|
|
||||||
}
|
|
||||||
return( JS_TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
JSBool getGUIGlobal( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval )
|
JSBool getGUIGlobal( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval )
|
||||||
{
|
{
|
||||||
*rval = OBJECT_TO_JSVAL( g_GUI.GetScriptObject() );
|
*rval = OBJECT_TO_JSVAL( g_GUI.GetScriptObject() );
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,6 @@ JSBool getEntityTemplate( JSContext* context, JSObject* globalObject, unsigned i
|
||||||
JSBool setTimeout( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
JSBool setTimeout( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||||
JSBool setInterval( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
JSBool setInterval( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||||
JSBool cancelInterval( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
JSBool cancelInterval( JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval );
|
||||||
// Getter/Setter for interface global objects (e.g. selection object)
|
|
||||||
JSBool getSelected( JSContext* context, JSObject* globalObject, jsval id, jsval* vp );
|
|
||||||
JSBool setSelected( JSContext* context, JSObject* globalObject, jsval id, jsval* vp );
|
|
||||||
JSBool getSelection( JSContext* context, JSObject* globalObject, jsval id, jsval* vp );
|
|
||||||
JSBool setSelection( JSContext* context, JSObject* globalObject, jsval id, jsval* vp );
|
|
||||||
|
|
||||||
// Returns the sort-of-global object associated with the current GUI
|
// Returns the sort-of-global object associated with the current GUI
|
||||||
JSBool getGUIGlobal(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
|
JSBool getGUIGlobal(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ bool getRayIntersection( const CVector2D& source, const CVector2D& forward, cons
|
||||||
assert( (*it)->m_bounds );
|
assert( (*it)->m_bounds );
|
||||||
if( (*it)->m_bounds == destinationCollisionObject ) continue;
|
if( (*it)->m_bounds == destinationCollisionObject ) continue;
|
||||||
// HACK:
|
// HACK:
|
||||||
if( (*it)->m_bounds->m_type == CBoundingObject::BOUND_OABB ) continue;
|
// if( (*it)->m_bounds->m_type == CBoundingObject::BOUND_OABB ) continue;
|
||||||
if( (*it)->m_speed ) continue;
|
if( (*it)->m_speed ) continue;
|
||||||
CBoundingObject* obj = (*it)->m_bounds;
|
CBoundingObject* obj = (*it)->m_bounds;
|
||||||
delta = obj->m_pos - source;
|
delta = obj->m_pos - source;
|
||||||
|
|
|
||||||
|
|
@ -120,4 +120,15 @@ public:
|
||||||
void pushOrder( CEntityOrder& order );
|
void pushOrder( CEntityOrder& order );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// General entity globals
|
||||||
|
|
||||||
|
|
||||||
|
// In it's current incarnation, inefficient but pretty
|
||||||
|
#define SELECTION_TERRAIN_CONFORMANCE
|
||||||
|
|
||||||
|
extern int SELECTION_CIRCLE_POINTS;
|
||||||
|
extern int SELECTION_BOX_POINTS;
|
||||||
|
extern int SELECTION_SMOOTHNESS_UNIFIED;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,22 @@
|
||||||
|
|
||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "BaseEntityCollection.h"
|
#include "BaseEntityCollection.h"
|
||||||
|
#include "ConfigDB.h"
|
||||||
|
|
||||||
|
int SELECTION_CIRCLE_POINTS;
|
||||||
|
int SELECTION_BOX_POINTS;
|
||||||
|
int SELECTION_SMOOTHNESS_UNIFIED;
|
||||||
|
|
||||||
CEntityManager::CEntityManager()
|
CEntityManager::CEntityManager()
|
||||||
{
|
{
|
||||||
m_nextalloc = 0;
|
m_nextalloc = 0;
|
||||||
m_extant = true;
|
m_extant = true;
|
||||||
|
// Also load a couple of global entity settings
|
||||||
|
CConfigValue* cfg = g_ConfigDB.GetValue( CFG_SYSTEM, "selection.outline.quality" );
|
||||||
|
if( cfg ) cfg->GetInt( SELECTION_SMOOTHNESS_UNIFIED );
|
||||||
|
if( SELECTION_SMOOTHNESS_UNIFIED < 0 ) SELECTION_SMOOTHNESS_UNIFIED = 0;
|
||||||
|
SELECTION_CIRCLE_POINTS = 7 + 2 * SELECTION_SMOOTHNESS_UNIFIED;
|
||||||
|
SELECTION_BOX_POINTS = 1 + SELECTION_SMOOTHNESS_UNIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntityManager::~CEntityManager()
|
CEntityManager::~CEntityManager()
|
||||||
|
|
|
||||||
|
|
@ -314,17 +314,18 @@ CProperty_CVector3D& CProperty_CVector3D::operator =( const CVector3D& value )
|
||||||
void CProperty_CVector3D::set( jsval value )
|
void CProperty_CVector3D::set( jsval value )
|
||||||
{
|
{
|
||||||
JSObject* vector3d = JSVAL_TO_OBJECT( value );
|
JSObject* vector3d = JSVAL_TO_OBJECT( value );
|
||||||
if( JSVAL_IS_NULL( value ) || !JSVAL_IS_OBJECT( value ) || ( JS_GetClass( vector3d ) != &JSI_Vector3D::JSI_class ) )
|
JSI_Vector3D::Vector3D_Info* v = NULL;
|
||||||
|
if( JSVAL_IS_OBJECT( value ) && ( v = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), vector3d, &JSI_Vector3D::JSI_class, NULL ) ) )
|
||||||
{
|
{
|
||||||
X = 0.0f; Y = 0.0f; Z = 0.0f;
|
CVector3D* copy = v->vector;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CVector3D* copy = ( (JSI_Vector3D::Vector3D_Info*)JS_GetPrivate( g_ScriptingHost.getContext(), vector3d ) )->vector;
|
|
||||||
X = copy->X;
|
X = copy->X;
|
||||||
Y = copy->Y;
|
Y = copy->Y;
|
||||||
Z = copy->Z;
|
Z = copy->Z;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
X = 0.0f; Y = 0.0f; Z = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CProperty_CVector3D::rebuild( CProperty* parent, bool triggerFn )
|
bool CProperty_CVector3D::rebuild( CProperty* parent, bool triggerFn )
|
||||||
|
|
@ -349,9 +350,10 @@ CProperty_CBaseEntityPtr& CProperty_CBaseEntityPtr::operator =( CBaseEntity* val
|
||||||
void CProperty_CBaseEntityPtr::set( jsval value )
|
void CProperty_CBaseEntityPtr::set( jsval value )
|
||||||
{
|
{
|
||||||
JSObject* baseEntity = JSVAL_TO_OBJECT( value );
|
JSObject* baseEntity = JSVAL_TO_OBJECT( value );
|
||||||
if( !JSVAL_IS_NULL( value ) && JSVAL_IS_OBJECT( value ) && ( JS_GetClass( baseEntity ) == &JSI_BaseEntity::JSI_class ) )
|
CBaseEntity* base = NULL;
|
||||||
|
if( JSVAL_IS_OBJECT( value ) && ( base = (CBaseEntity*)JS_GetInstancePrivate( g_ScriptingHost.getContext(), baseEntity, &JSI_BaseEntity::JSI_class, NULL ) ) )
|
||||||
{
|
{
|
||||||
data = (CBaseEntity*)JS_GetPrivate( g_ScriptingHost.getContext(), baseEntity );
|
data = base;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
JS_ReportError( g_ScriptingHost.getContext(), "[BaseEntity] Invalid reference" );
|
JS_ReportError( g_ScriptingHost.getContext(), "[BaseEntity] Invalid reference" );
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||||
if( m_bounds->m_type == CBoundingObject::BOUND_OABB )
|
if( m_bounds->m_type == CBoundingObject::BOUND_OABB )
|
||||||
((CBoundingBox*)m_bounds)->setOrientation( m_ahead );
|
((CBoundingBox*)m_bounds)->setOrientation( m_ahead );
|
||||||
|
|
||||||
|
|
||||||
float scale = m_speed * timestep;
|
float scale = m_speed * timestep;
|
||||||
|
|
||||||
if( scale > len )
|
if( scale > len )
|
||||||
|
|
@ -112,6 +111,9 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, float timestep )
|
||||||
// Oh dear. Most likely explanation is that this unit was created
|
// Oh dear. Most likely explanation is that this unit was created
|
||||||
// within the bounding area of another entity.
|
// within the bounding area of another entity.
|
||||||
// Try a little boost of speed, to help resolve the situation more quickly.
|
// Try a little boost of speed, to help resolve the situation more quickly.
|
||||||
|
|
||||||
|
// This really shouldn't happen in the current build.
|
||||||
|
|
||||||
m_position.X += delta.x * 2.0f;
|
m_position.X += delta.x * 2.0f;
|
||||||
m_position.Z += delta.y * 2.0f;
|
m_position.Z += delta.y * 2.0f;
|
||||||
m_bounds->setPosition( m_position.X, m_position.Z );
|
m_bounds->setPosition( m_position.X, m_position.Z );
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ JSBool JSI_Entity::getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* v
|
||||||
if( !e )
|
if( !e )
|
||||||
{
|
{
|
||||||
*vp = JSVAL_NULL;
|
*vp = JSVAL_NULL;
|
||||||
JS_ReportError( cx, "[Entity] Invalid reference" );
|
|
||||||
return( JS_TRUE );
|
return( JS_TRUE );
|
||||||
}
|
}
|
||||||
CStr propName = g_ScriptingHost.ValueToString( id );
|
CStr propName = g_ScriptingHost.ValueToString( id );
|
||||||
|
|
@ -69,17 +68,13 @@ JSBool JSI_Entity::setProperty( JSContext* cx, JSObject* obj, jsval id, jsval* v
|
||||||
JSBool JSI_Entity::construct( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval )
|
JSBool JSI_Entity::construct( JSContext* cx, JSObject* obj, unsigned int argc, jsval* argv, jsval* rval )
|
||||||
{
|
{
|
||||||
assert( argc >= 2 );
|
assert( argc >= 2 );
|
||||||
CBaseEntity* baseEntity;
|
CBaseEntity* baseEntity = NULL;
|
||||||
CVector3D position;
|
CVector3D position;
|
||||||
float orientation = 0.0f;
|
float orientation = 0.0f;
|
||||||
JSObject* jsBaseEntity = JSVAL_TO_OBJECT( argv[0] );
|
JSObject* jsBaseEntity = JSVAL_TO_OBJECT( argv[0] );
|
||||||
CStr templateName;
|
CStr templateName;
|
||||||
|
|
||||||
if( !JSVAL_IS_NULL( argv[0] ) && JSVAL_IS_OBJECT( argv[0] ) && ( JS_GetClass( jsBaseEntity ) == &JSI_BaseEntity::JSI_class ) )
|
if( !JSVAL_IS_OBJECT( argv[0] ) || !( baseEntity = (CBaseEntity*)JS_GetInstancePrivate( cx, jsBaseEntity, &JSI_BaseEntity::JSI_class, NULL ) ) )
|
||||||
{
|
|
||||||
baseEntity = (CBaseEntity*)JS_GetPrivate( cx, jsBaseEntity );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -99,10 +94,10 @@ JSBool JSI_Entity::construct( JSContext* cx, JSObject* obj, unsigned int argc, j
|
||||||
JS_ReportError( cx, "No such template: %s", (const char*)templateName );
|
JS_ReportError( cx, "No such template: %s", (const char*)templateName );
|
||||||
return( JS_TRUE );
|
return( JS_TRUE );
|
||||||
}
|
}
|
||||||
JSObject* jsVector3D = JSVAL_TO_OBJECT( argv[1] );
|
JSI_Vector3D::Vector3D_Info* jsVector3D = NULL;
|
||||||
if( !JSVAL_IS_NULL( argv[1] ) && JSVAL_IS_OBJECT( argv[1] ) && ( JS_GetClass( jsVector3D ) == &JSI_Vector3D::JSI_class ) )
|
if( JSVAL_IS_OBJECT( argv[1] ) && ( jsVector3D = (JSI_Vector3D::Vector3D_Info*)JS_GetInstancePrivate( cx, JSVAL_TO_OBJECT( argv[1] ), &JSI_Vector3D::JSI_class, NULL ) ) )
|
||||||
{
|
{
|
||||||
position = *( ( (JSI_Vector3D::Vector3D_Info*)JS_GetPrivate( cx, jsVector3D ) )->vector );
|
position = *( jsVector3D->vector );
|
||||||
}
|
}
|
||||||
if( argc >= 3 )
|
if( argc >= 3 )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Terrain.h"
|
#include "Terrain.h"
|
||||||
#include "LightEnv.h"
|
#include "LightEnv.h"
|
||||||
|
#include "HFTracer.h"
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
#include "ObjectManager.h"
|
#include "ObjectManager.h"
|
||||||
#include "Prometheus.h"
|
#include "Prometheus.h"
|
||||||
#include "Hotkey.h"
|
#include "Hotkey.h"
|
||||||
|
#include "ConfigDB.h"
|
||||||
|
|
||||||
#include "sdl.h"
|
#include "sdl.h"
|
||||||
#include "res/tex.h"
|
#include "res/tex.h"
|
||||||
|
|
@ -34,15 +36,23 @@ CLightEnv g_LightEnv;
|
||||||
float g_CameraZoom = 10;
|
float g_CameraZoom = 10;
|
||||||
|
|
||||||
std::vector<CVector3D> cameraTargets;
|
std::vector<CVector3D> cameraTargets;
|
||||||
|
CVector3D cameraBookmarks[10];
|
||||||
|
bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false };
|
||||||
|
u8 currentBookmark = 255;
|
||||||
CVector3D cameraDelta;
|
CVector3D cameraDelta;
|
||||||
|
CVector3D cameraPivot;
|
||||||
|
|
||||||
|
// These were 'const'; loaded from config now.
|
||||||
|
|
||||||
|
float ViewScrollSpeed = 60;
|
||||||
|
float ViewRotateSensitivity = 0.002f;
|
||||||
|
float ViewRotateAboutTargetSensitivity = 0.010f;
|
||||||
|
float ViewDragSensitivity = 0.5f;
|
||||||
|
float ViewZoomSensitivityWheel = 16.0f;
|
||||||
|
float ViewZoomSensitivity = 256.0f;
|
||||||
|
float ViewZoomSmoothness = 0.02f; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves
|
||||||
|
float ViewSnapSmoothness = 0.02f; // Just the same.
|
||||||
|
|
||||||
const float ViewScrollSpeed = 60;
|
|
||||||
const float ViewRotateSensitivity = 0.002f;
|
|
||||||
const float ViewDragSensitivity = 0.5f;
|
|
||||||
const float ViewZoomSensitivityWheel = 16.0f;
|
|
||||||
const float ViewZoomSensitivity = 256.0f;
|
|
||||||
const float ViewZoomSmoothness = 0.02f; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves
|
|
||||||
const float ViewSnapSmoothness = 0.02f; // Just the same.
|
|
||||||
float ViewFOV;
|
float ViewFOV;
|
||||||
|
|
||||||
extern int g_xres, g_yres;
|
extern int g_xres, g_yres;
|
||||||
|
|
@ -56,6 +66,26 @@ void terr_init()
|
||||||
vp.m_Height=g_yres;
|
vp.m_Height=g_yres;
|
||||||
g_Camera.SetViewPort(&vp);
|
g_Camera.SetViewPort(&vp);
|
||||||
|
|
||||||
|
CConfigValue* cfg;
|
||||||
|
|
||||||
|
#define getViewParameter( name, value ) STMT( \
|
||||||
|
cfg = g_ConfigDB.GetValue( CFG_SYSTEM, name );\
|
||||||
|
if( cfg ) cfg->GetFloat( value ); )
|
||||||
|
|
||||||
|
getViewParameter( "view.scroll.speed", ViewScrollSpeed );
|
||||||
|
getViewParameter( "view.rotate.speed", ViewRotateSensitivity );
|
||||||
|
getViewParameter( "view.rotate.abouttarget.speed", ViewRotateAboutTargetSensitivity );
|
||||||
|
getViewParameter( "view.drag.speed", ViewDragSensitivity );
|
||||||
|
getViewParameter( "view.zoom.speed", ViewZoomSensitivity );
|
||||||
|
getViewParameter( "view.zoom.wheel.speed", ViewZoomSensitivityWheel );
|
||||||
|
getViewParameter( "view.zoom.smoothness", ViewZoomSmoothness );
|
||||||
|
getViewParameter( "view.snap.smoothness", ViewSnapSmoothness );
|
||||||
|
|
||||||
|
if( ( ViewZoomSmoothness < 0.0f ) || ( ViewZoomSmoothness > 1.0f ) ) ViewZoomSmoothness = 0.02f;
|
||||||
|
if( ( ViewSnapSmoothness < 0.0f ) || ( ViewSnapSmoothness > 1.0f ) ) ViewSnapSmoothness = 0.02f;
|
||||||
|
|
||||||
|
#undef getViewParameter
|
||||||
|
|
||||||
InitResources ();
|
InitResources ();
|
||||||
InitScene ();
|
InitScene ();
|
||||||
}
|
}
|
||||||
|
|
@ -85,9 +115,9 @@ static void move_camera(float DeltaTime)
|
||||||
|
|
||||||
// Miscellaneous vectors
|
// Miscellaneous vectors
|
||||||
CVector3D forwards = g_Camera.m_Orientation.GetIn();
|
CVector3D forwards = g_Camera.m_Orientation.GetIn();
|
||||||
CVector3D upwards (0.0f, 1.0f, 0.0f);
|
CVector3D rightwards = g_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards);
|
||||||
CVector3D rightwards = upwards.Cross(forwards);
|
CVector3D upwards( 0.0f, 1.0f, 0.0f );
|
||||||
rightwards.Normalize();
|
// rightwards.Normalize();
|
||||||
|
|
||||||
CVector3D forwards_horizontal = forwards;
|
CVector3D forwards_horizontal = forwards;
|
||||||
forwards_horizontal.Y = 0.0f;
|
forwards_horizontal.Y = 0.0f;
|
||||||
|
|
@ -117,9 +147,39 @@ static void move_camera(float DeltaTime)
|
||||||
g_Camera.m_Orientation.Translate(position);
|
g_Camera.m_Orientation.Translate(position);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
|
||||||
else if (mouseButtons[SDL_BUTTON_MIDDLE])
|
{
|
||||||
*/
|
CVector3D origin = g_Camera.m_Orientation.GetTranslation();
|
||||||
|
CVector3D delta = origin - cameraPivot;
|
||||||
|
|
||||||
|
CQuaternion rotateH, rotateV; CMatrix3D rotateM;
|
||||||
|
|
||||||
|
// Side-to-side rotation
|
||||||
|
rotateH.FromAxisAngle( upwards, ViewRotateAboutTargetSensitivity * (float)mouse_dx );
|
||||||
|
|
||||||
|
// Up-down rotation
|
||||||
|
rotateV.FromAxisAngle( rightwards, ViewRotateAboutTargetSensitivity * (float)mouse_dy );
|
||||||
|
|
||||||
|
rotateH *= rotateV;
|
||||||
|
rotateH.ToMatrix( rotateM );
|
||||||
|
|
||||||
|
delta = rotateM.Rotate( delta );
|
||||||
|
|
||||||
|
// Lock the inclination to a rather arbitrary values (for the sake of graphical decency)
|
||||||
|
|
||||||
|
float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y;
|
||||||
|
if( ( scan >= 0.5f ) )
|
||||||
|
{
|
||||||
|
// Move the camera to the origin (in preparation for rotation )
|
||||||
|
g_Camera.m_Orientation.Translate( origin * -1.0f );
|
||||||
|
|
||||||
|
g_Camera.m_Orientation.Rotate( rotateH );
|
||||||
|
|
||||||
|
// Move the camera back to where it belongs
|
||||||
|
g_Camera.m_Orientation.Translate( cameraPivot + delta );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else if( hotkeys[HOTKEY_CAMERA_PAN] )
|
else if( hotkeys[HOTKEY_CAMERA_PAN] )
|
||||||
{
|
{
|
||||||
// Middle-drag to pan
|
// Middle-drag to pan
|
||||||
|
|
@ -129,15 +189,18 @@ static void move_camera(float DeltaTime)
|
||||||
|
|
||||||
// Mouse movement
|
// Mouse movement
|
||||||
|
|
||||||
if (mouse_x >= g_xres-2)
|
if( !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
|
||||||
g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime));
|
{
|
||||||
else if (mouse_x <= 3)
|
if (mouse_x >= g_xres-2)
|
||||||
g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime));
|
g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime));
|
||||||
|
else if (mouse_x <= 3)
|
||||||
|
g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime));
|
||||||
|
|
||||||
if (mouse_y >= g_yres-2)
|
if (mouse_y >= g_yres-2)
|
||||||
g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
||||||
else if (mouse_y <= 3)
|
else if (mouse_y <= 3)
|
||||||
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Keyboard movement (added to mouse movement, so you can go faster if you want)
|
// Keyboard movement (added to mouse movement, so you can go faster if you want)
|
||||||
|
|
@ -152,7 +215,6 @@ static void move_camera(float DeltaTime)
|
||||||
if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] )
|
if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] )
|
||||||
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime));
|
||||||
|
|
||||||
|
|
||||||
// Smoothed zooming (move a certain percentage towards the desired zoom distance every frame)
|
// Smoothed zooming (move a certain percentage towards the desired zoom distance every frame)
|
||||||
|
|
||||||
static float zoom_delta = 0.0f;
|
static float zoom_delta = 0.0f;
|
||||||
|
|
@ -325,7 +387,22 @@ int terr_handler(const SDL_Event* ev)
|
||||||
g_Camera.m_Orientation.Translate (100, 150, -100);
|
g_Camera.m_Orientation.Translate (100, 150, -100);
|
||||||
return( EV_HANDLED );
|
return( EV_HANDLED );
|
||||||
|
|
||||||
|
case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET:
|
||||||
|
{
|
||||||
|
int x, z;
|
||||||
|
CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), CELL_SIZE, HEIGHT_SCALE );
|
||||||
|
CVector3D origin, dir;
|
||||||
|
origin = g_Camera.m_Orientation.GetTranslation();
|
||||||
|
dir = g_Camera.m_Orientation.GetIn();
|
||||||
|
g_Camera.BuildCameraRay( origin, dir );
|
||||||
|
|
||||||
|
if( !tracer.RayIntersect( origin, dir, x, z, cameraPivot ) )
|
||||||
|
cameraPivot = origin - dir * ( origin.Y / dir.Y );
|
||||||
|
}
|
||||||
|
return( EV_HANDLED );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EV_PASS;
|
return EV_PASS;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue