mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-11 00:10:46 +00:00
Merge branch 'development' of https://github.com/GarageGames/Torque3D into PBR_ProbeArrayGLWIP
# Conflicts: # Engine/source/gfx/D3D11/gfxD3D11Device.cpp # Engine/source/lighting/lightManager.cpp # Templates/Full/game/levels/Empty Room.mis # Templates/Full/game/levels/Empty Terrain.mis
This commit is contained in:
commit
97ec99f704
235 changed files with 7064 additions and 3090 deletions
13
.editorconfig
Normal file
13
.editorconfig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
tab_width = 3
|
||||
indent_style = space
|
||||
indent_size = 3
|
||||
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
44
.travis.yml
44
.travis.yml
|
|
@ -1,4 +1,42 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
dist: xenial
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
compiler: clang
|
||||
env: if CXXFLAGS="-fgnu-inline-asm -fasm-blocks"
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
compiler: clang
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- build-essential
|
||||
- nasm
|
||||
- libogg-dev
|
||||
- libxft-dev
|
||||
- libx11-dev
|
||||
- libxxf86vm-dev
|
||||
- libopenal-dev
|
||||
- libfreetype6-dev
|
||||
- libxcursor-dev
|
||||
- libxinerama-dev
|
||||
- libxi-dev
|
||||
- libxrandr-dev
|
||||
- libxss-dev
|
||||
- libglu1-mesa-dev
|
||||
- libgtk-3-dev
|
||||
|
||||
script:
|
||||
- mkdir -p My\ Projects/TestProject/buildFiles/travis/
|
||||
- cd My\ Projects/TestProject/buildFiles/travis/
|
||||
- cmake ../../../.. -DTORQUE_APP_NAME=TestProject -DCMAKE_BUILD_TYPE=Debug
|
||||
- make 2>/dev/null # Do the actual build, but ignore all the warnings
|
||||
- make # build again. This time all output is printed but the warnings that happened earlier do not happen again
|
||||
- make install
|
||||
- cd ../../game/
|
||||
- ls
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Native File Dialog #
|
||||
|
||||
A tiny, neat C library that portably invokes native file open and save dialogs. Write dialog code once and have it pop up native dialogs on all supported platforms. Avoid linking large dependencies like wxWidgets and qt.
|
||||
A tiny, neat C library that portably invokes native file open, folder select and save dialogs. Write dialog code once and have it pop up native dialogs on all supported platforms. Avoid linking large dependencies like wxWidgets and qt.
|
||||
|
||||
Features:
|
||||
|
||||
|
|
@ -11,11 +11,12 @@ Features:
|
|||
- Paid support available.
|
||||
- Multiple file selection support.
|
||||
- 64-bit and 32-bit friendly.
|
||||
- GCC, Clang and Visual Studio supported.
|
||||
- No third party dependencies.
|
||||
- GCC, Clang, Xcode, Mingw and Visual Studio supported.
|
||||
- No third party dependencies for building or linking.
|
||||
- Support for Vista's modern `IFileDialog` on Windows.
|
||||
- Support for non-deprecated Cocoa APIs on OS X.
|
||||
- GTK+3 dialog on Linux.
|
||||
- GTK3 dialog on Linux.
|
||||
- Optional Zenity support on Linux to avoid linking GTK.
|
||||
- Tested, works alongside [http://www.libsdl.org](SDL2) on all platforms, for the game developers out there.
|
||||
|
||||
# Example Usage #
|
||||
|
|
@ -50,47 +51,74 @@ See [NFD.h](src/include/nfd.h) for more options.
|
|||
|
||||
# Screenshots #
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Changelog ##
|
||||
|
||||
release | what's new | date
|
||||
--------|-----------------------------|---------
|
||||
1.0.0 | initial | oct 2014
|
||||
1.1.0 | premake5; scons deprecated | aug 2016
|
||||
1.1.1 | mingw support, build fixes | aug 2016
|
||||
1.1.2 | test_pickfolder() added | aug 2016
|
||||
1.1.3 | zenity linux backend added | nov 2017
|
||||
1.1.3 | fix char type in decls | nov 2017
|
||||
1.1.4 | fix win32 memleaks | dec 2018
|
||||
1.1.4 | improve win32 errorhandling | dec 2018
|
||||
1.1.4 | macos fix focus bug | dec 2018
|
||||
|
||||
|
||||
## Building ##
|
||||
|
||||
NFD uses [SCons](http://www.scons.org) for cross-platform builds. After installing SCons, build it with:
|
||||
NFD uses [Premake5](https://premake.github.io/download.html) generated Makefiles and IDE project files. The generated project files are checked in under `build/` so you don't have to download and use Premake in most cases.
|
||||
|
||||
cd src
|
||||
scons debug=[0,1]
|
||||
If you need to run Premake5 directly, further [build documentation](docs/build.md) is available.
|
||||
|
||||
Alternatively, you can avoid Scons by just including NFD files to your existing project:
|
||||
Previously, NFD used SCons to build. It still works, but is now deprecated; updates to it are discouraged. Opt to use the native build system where possible.
|
||||
|
||||
1. Add all header files in `src/` and `src/include` to your project.
|
||||
2. Add `src/include` to your include search path or copy it into your existing search path.
|
||||
3. Add `src/nfd_common.c` to your project.
|
||||
4. Add `src/nfd_<platform>` to your project, where `<platform>` is the NFD backend for the platform you are fixing to build.
|
||||
5. On Visual Studio, define `_CRT_SECURE_NO_WARNINGS` to avoid warnings.
|
||||
`nfd.a` will be built for release builds, and `nfd_d.a` will be built for debug builds.
|
||||
|
||||
### Makefiles ###
|
||||
|
||||
The makefile offers five options, with `release_x64` as the default.
|
||||
|
||||
make config=release_x86
|
||||
make config=release_x64
|
||||
make config=debug_x86
|
||||
make config=debug_x64
|
||||
|
||||
### Compiling Your Programs ###
|
||||
|
||||
1. Add `src/include` to your include search path.
|
||||
2. Add `nfd.lib` to the list of list of static libraries to link against.
|
||||
3. Add `src/` to the library search path.
|
||||
2. Add `nfd.lib` or `nfd_d.lib` to the list of list of static libraries to link against (for release or debug, respectively).
|
||||
3. Add `build/<debug|release>/<arch>` to the library search path.
|
||||
|
||||
On Linux, you must compile and link against GTK+. Recommend use of `pkg-config --cflags --libs gtk+-3.0`.
|
||||
#### Linux GTK ####
|
||||
`apt-get libgtk-3-dev` installs the gtk dependency for library compilation.
|
||||
|
||||
On Mac OS X, add `AppKit` to the list of frameworks.
|
||||
On Linux, you have the option of compiling and linking against GTK. If you use it, the recommended way to compile is to include the arguments of `pkg-config --cflags --libs gtk+-3.0`.
|
||||
|
||||
#### Linux Zenity ####
|
||||
|
||||
Alternatively, you can use the Zenity backend by running the Makefile in `build/gmake_linux_zenity`. Zenity runs the dialog in its own address space, but requires the user to have Zenity correctly installed and configured on their system.
|
||||
|
||||
#### MacOS ####
|
||||
On Mac OS, add `AppKit` to the list of frameworks.
|
||||
|
||||
#### Windows ####
|
||||
On Windows, ensure you are building against `comctl32.lib`.
|
||||
|
||||
## Usage ##
|
||||
|
||||
See `NFD.h` for API calls. See `tests/*.c` for example code.
|
||||
|
||||
See `tests/SConstruct` for a working build script that compiles on all platforms.
|
||||
After compiling, `build/bin` contains compiled test programs.
|
||||
|
||||
## File Filter Syntax ##
|
||||
|
||||
There is a form of file filtering in every file dialog, but no consistent means of supporting it. NFD provides support for filtering files by groups of extensions, providing its own descriptions (where applicable) for the extensions.
|
||||
There is a form of file filtering in every file dialog API, but no consistent means of supporting it. NFD provides support for filtering files by groups of extensions, providing its own descriptions (where applicable) for the extensions.
|
||||
|
||||
A wildcard filter is always added to every dialog.
|
||||
|
||||
|
|
@ -113,16 +141,14 @@ See [test_opendialogmultiple.c](test/test_opendialogmultiple.c).
|
|||
|
||||
# Known Limitations #
|
||||
|
||||
I accept quality code patches, or will resolve these and other matters through support.
|
||||
I accept quality code patches, or will resolve these and other matters through support. See [submitting pull requests](docs/submitting_pull_requests.md) for details.
|
||||
|
||||
- No support for Windows XP's legacy dialogs such as `GetOpenFileName`.
|
||||
- No support for file filter names -- ex: "Image Files" (*.png, *.jpg). Nameless filters are supported, though.
|
||||
- No support for selecting folders instead of files.
|
||||
- On Linux, GTK+ cannot be uninitialized to save memory. Launching a file dialog costs memory. I am open to accepting an alternative `nfd_zenity.c` implementation which uses Zenity and pipes.
|
||||
- No support for file filter names -- ex: "Image Files" (*.png, *.jpg). Nameless filters are supported, however.
|
||||
|
||||
# Copyright and Credit #
|
||||
|
||||
Copyright © 2014 [Frogtoss Games](http://www.frogtoss.com), Inc.
|
||||
Copyright © 2014-2017 [Frogtoss Games](http://www.frogtoss.com), Inc.
|
||||
File [LICENSE](LICENSE) covers all files in this repo.
|
||||
|
||||
Native File Dialog by Michael Labbe
|
||||
|
|
@ -130,6 +156,10 @@ Native File Dialog by Michael Labbe
|
|||
|
||||
Tomasz Konojacki for [microutf8](http://puszcza.gnu.org.ua/software/microutf8/)
|
||||
|
||||
[Denis Kolodin](https://github.com/DenisKolodin) for mingw support.
|
||||
|
||||
[Tom Mason](https://github.com/wheybags) for Zenity support.
|
||||
|
||||
## Support ##
|
||||
|
||||
Directed support for this work is available from the original author under a paid agreement.
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ static nfdresult_t AllocPathSet( NSArray *urls, nfdpathset_t *pathset )
|
|||
/* public */
|
||||
|
||||
|
||||
nfdresult_t NFD_OpenDialog( const char *filterList,
|
||||
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath )
|
||||
{
|
||||
|
|
@ -146,6 +146,7 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
|
|||
if ( !*outPath )
|
||||
{
|
||||
[pool release];
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return NFD_ERROR;
|
||||
}
|
||||
memcpy( *outPath, utf8Path, len+1 ); /* copy null term */
|
||||
|
|
@ -163,6 +164,7 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
nfdpathset_t *outPaths )
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
|
||||
|
||||
NSOpenPanel *dialog = [NSOpenPanel openPanel];
|
||||
[dialog setAllowsMultipleSelection:YES];
|
||||
|
|
@ -181,12 +183,14 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
if ( [urls count] == 0 )
|
||||
{
|
||||
[pool release];
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return NFD_CANCEL;
|
||||
}
|
||||
|
||||
if ( AllocPathSet( urls, outPaths ) == NFD_ERROR )
|
||||
{
|
||||
[pool release];
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -194,6 +198,7 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
}
|
||||
[pool release];
|
||||
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return nfdResult;
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +208,8 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
nfdchar_t **outPath )
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
|
||||
|
||||
NSSavePanel *dialog = [NSSavePanel savePanel];
|
||||
[dialog setExtensionHidden:NO];
|
||||
|
||||
|
|
@ -225,6 +231,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
if ( !*outPath )
|
||||
{
|
||||
[pool release];
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return NFD_ERROR;
|
||||
}
|
||||
memcpy( *outPath, utf8Path, byteLen );
|
||||
|
|
@ -232,7 +239,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return nfdResult;
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +248,7 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
|
|||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
|
||||
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
|
||||
NSOpenPanel *dialog = [NSOpenPanel openPanel];
|
||||
[dialog setAllowsMultipleSelection:NO];
|
||||
[dialog setCanChooseDirectories:YES];
|
||||
|
|
@ -264,6 +271,7 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
|
|||
if ( !*outPath )
|
||||
{
|
||||
[pool release];
|
||||
[keyWindow makeKeyAndOrderFront:nil];
|
||||
return NFD_ERROR;
|
||||
}
|
||||
memcpy( *outPath, utf8Path, len+1 ); /* copy null term */
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ static void WaitForCleanup(void)
|
|||
|
||||
/* public */
|
||||
|
||||
nfdresult_t NFD_OpenDialog( const char *filterList,
|
||||
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
http://www.frogtoss.com/labs
|
||||
*/
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
/* only locally define UNICODE in this compilation unit */
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
|
|
@ -19,7 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <ShObjIdl.h>
|
||||
#include <shobjidl.h>
|
||||
#include "nfd_common.h"
|
||||
|
||||
|
||||
|
|
@ -47,9 +51,9 @@ static void CopyWCharToNFDChar( const wchar_t *inStr, nfdchar_t **outStr )
|
|||
/* includes NULL terminator byte in return */
|
||||
static size_t GetUTF8ByteCountForWChar( const wchar_t *str )
|
||||
{
|
||||
int bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
|
||||
str, -1,
|
||||
NULL, 0, NULL, NULL );
|
||||
size_t bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
|
||||
str, -1,
|
||||
NULL, 0, NULL, NULL );
|
||||
assert( bytesNeeded );
|
||||
return bytesNeeded+1;
|
||||
}
|
||||
|
|
@ -148,12 +152,12 @@ static nfdresult_t AddFiltersToDialog( ::IFileDialog *fileOpenDialog, const char
|
|||
}
|
||||
|
||||
/* filterCount plus 1 because we hardcode the *.* wildcard after the while loop */
|
||||
COMDLG_FILTERSPEC *specList = (COMDLG_FILTERSPEC*)NFDi_Malloc( sizeof(COMDLG_FILTERSPEC) * (filterCount + 1) );
|
||||
COMDLG_FILTERSPEC *specList = (COMDLG_FILTERSPEC*)NFDi_Malloc( sizeof(COMDLG_FILTERSPEC) * ((size_t)filterCount + 1) );
|
||||
if ( !specList )
|
||||
{
|
||||
return NFD_ERROR;
|
||||
}
|
||||
for (size_t i = 0; i < filterCount+1; ++i )
|
||||
for (UINT i = 0; i < filterCount+1; ++i )
|
||||
{
|
||||
specList[i].pszName = NULL;
|
||||
specList[i].pszSpec = NULL;
|
||||
|
|
@ -181,9 +185,8 @@ static nfdresult_t AddFiltersToDialog( ::IFileDialog *fileOpenDialog, const char
|
|||
if ( *p_filterList == ';' || *p_filterList == '\0' )
|
||||
{
|
||||
/* end of filter -- add it to specList */
|
||||
|
||||
// Empty filter name -- Windows describes them by extension.
|
||||
CopyNFDCharToWChar(specbuf, (wchar_t**)&specList[specIdx].pszName);
|
||||
|
||||
CopyNFDCharToWChar( specbuf, (wchar_t**)&specList[specIdx].pszName );
|
||||
CopyNFDCharToWChar( specbuf, (wchar_t**)&specList[specIdx].pszSpec );
|
||||
|
||||
memset( specbuf, 0, sizeof(char)*NFD_MAX_STRLEN );
|
||||
|
|
@ -270,6 +273,8 @@ static nfdresult_t AllocPathSet( IShellItemArray *shellItems, nfdpathset_t *path
|
|||
|
||||
// Calculate length of name with UTF-8 encoding
|
||||
bufSize += GetUTF8ByteCountForWChar( name );
|
||||
|
||||
CoTaskMemFree(name);
|
||||
}
|
||||
|
||||
assert(bufSize);
|
||||
|
|
@ -304,6 +309,7 @@ static nfdresult_t AllocPathSet( IShellItemArray *shellItems, nfdpathset_t *path
|
|||
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
|
||||
|
||||
int bytesWritten = CopyWCharToExistingNFDCharBuffer(name, p_buf);
|
||||
CoTaskMemFree(name);
|
||||
|
||||
ptrdiff_t index = p_buf - pathSet->buf;
|
||||
assert( index >= 0 );
|
||||
|
|
@ -353,29 +359,30 @@ static nfdresult_t SetDefaultPath( IFileDialog *dialog, const char *defaultPath
|
|||
/* public */
|
||||
|
||||
|
||||
nfdresult_t NFD_OpenDialog( const char *filterList,
|
||||
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath )
|
||||
{
|
||||
nfdresult_t nfdResult = NFD_ERROR;
|
||||
|
||||
// Init COM library.
|
||||
HRESULT result = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
HRESULT coResult = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
|
||||
::IFileOpenDialog *fileOpenDialog(NULL);
|
||||
|
||||
if ( !SUCCEEDED(result))
|
||||
if ( !SUCCEEDED(coResult))
|
||||
{
|
||||
fileOpenDialog = NULL;
|
||||
NFDi_SetError("Could not initialize COM.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Create dialog
|
||||
result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileOpenDialog,
|
||||
reinterpret_cast<void**>(&fileOpenDialog) );
|
||||
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileOpenDialog,
|
||||
reinterpret_cast<void**>(&fileOpenDialog) );
|
||||
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
|
|
@ -412,6 +419,7 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
|
|||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
NFDi_SetError("Could not get file path for selected.");
|
||||
shellItem->Release();
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -420,6 +428,7 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
|
|||
if ( !*outPath )
|
||||
{
|
||||
/* error is malloc-based, error message would be redundant */
|
||||
shellItem->Release();
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -436,8 +445,12 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
|
|||
nfdResult = NFD_ERROR;
|
||||
}
|
||||
|
||||
end:
|
||||
::CoUninitialize();
|
||||
end:
|
||||
if (fileOpenDialog)
|
||||
fileOpenDialog->Release();
|
||||
|
||||
if (SUCCEEDED(coResult))
|
||||
::CoUninitialize();
|
||||
|
||||
return nfdResult;
|
||||
}
|
||||
|
|
@ -449,10 +462,10 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
nfdresult_t nfdResult = NFD_ERROR;
|
||||
|
||||
// Init COM library.
|
||||
HRESULT result = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
if ( !SUCCEEDED(result))
|
||||
HRESULT coResult = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
if ( !SUCCEEDED(coResult))
|
||||
{
|
||||
NFDi_SetError("Could not initialize COM.");
|
||||
return NFD_ERROR;
|
||||
|
|
@ -461,12 +474,13 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
::IFileOpenDialog *fileOpenDialog(NULL);
|
||||
|
||||
// Create dialog
|
||||
result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileOpenDialog,
|
||||
reinterpret_cast<void**>(&fileOpenDialog) );
|
||||
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileOpenDialog,
|
||||
reinterpret_cast<void**>(&fileOpenDialog) );
|
||||
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
fileOpenDialog = NULL;
|
||||
NFDi_SetError("Could not create dialog.");
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -512,6 +526,7 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
|
||||
if ( AllocPathSet( shellItems, outPaths ) == NFD_ERROR )
|
||||
{
|
||||
shellItems->Release();
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -528,8 +543,12 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
|||
nfdResult = NFD_ERROR;
|
||||
}
|
||||
|
||||
end:
|
||||
::CoUninitialize();
|
||||
end:
|
||||
if ( fileOpenDialog )
|
||||
fileOpenDialog->Release();
|
||||
|
||||
if (SUCCEEDED(coResult))
|
||||
::CoUninitialize();
|
||||
|
||||
return nfdResult;
|
||||
}
|
||||
|
|
@ -541,10 +560,10 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
nfdresult_t nfdResult = NFD_ERROR;
|
||||
|
||||
// Init COM library.
|
||||
HRESULT result = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
if ( !SUCCEEDED(result))
|
||||
HRESULT coResult = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
if ( !SUCCEEDED(coResult))
|
||||
{
|
||||
NFDi_SetError("Could not initialize COM.");
|
||||
return NFD_ERROR;
|
||||
|
|
@ -553,12 +572,13 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
::IFileSaveDialog *fileSaveDialog(NULL);
|
||||
|
||||
// Create dialog
|
||||
result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileSaveDialog,
|
||||
reinterpret_cast<void**>(&fileSaveDialog) );
|
||||
HRESULT result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileSaveDialog,
|
||||
reinterpret_cast<void**>(&fileSaveDialog) );
|
||||
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
fileSaveDialog = NULL;
|
||||
NFDi_SetError("Could not create dialog.");
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -591,6 +611,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
shellItem->Release();
|
||||
NFDi_SetError("Could not get file path for selected.");
|
||||
goto end;
|
||||
}
|
||||
|
|
@ -600,6 +621,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
if ( !*outPath )
|
||||
{
|
||||
/* error is malloc-based, error message would be redundant */
|
||||
shellItem->Release();
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -616,8 +638,12 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
nfdResult = NFD_ERROR;
|
||||
}
|
||||
|
||||
end:
|
||||
::CoUninitialize();
|
||||
end:
|
||||
if ( fileSaveDialog )
|
||||
fileSaveDialog->Release();
|
||||
|
||||
if (SUCCEEDED(coResult))
|
||||
::CoUninitialize();
|
||||
|
||||
return nfdResult;
|
||||
}
|
||||
|
|
@ -729,7 +755,8 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
|
|||
ComPtr<IShellItem> pShellItem;
|
||||
if (!SUCCEEDED(pFileDialog->GetResult(&pShellItem)))
|
||||
{
|
||||
return NFD_OKAY;
|
||||
NFDi_SetError("Could not get shell item from dialog.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Finally get the path
|
||||
|
|
|
|||
311
Engine/lib/nativeFileDialogs/nfd_zenity.c
Normal file
311
Engine/lib/nativeFileDialogs/nfd_zenity.c
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
Native File Dialog
|
||||
|
||||
http://www.frogtoss.com/labs
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "nfd.h"
|
||||
#include "nfd_common.h"
|
||||
|
||||
#define SIMPLE_EXEC_IMPLEMENTATION
|
||||
#include "simple_exec.h"
|
||||
|
||||
|
||||
const char NO_ZENITY_MSG[] = "zenity not installed";
|
||||
|
||||
|
||||
static void AddTypeToFilterName( const char *typebuf, char *filterName, size_t bufsize )
|
||||
{
|
||||
size_t len = strlen(filterName);
|
||||
if( len > 0 )
|
||||
strncat( filterName, " *.", bufsize - len - 1 );
|
||||
else
|
||||
strncat( filterName, "--file-filter=*.", bufsize - len - 1 );
|
||||
|
||||
len = strlen(filterName);
|
||||
strncat( filterName, typebuf, bufsize - len - 1 );
|
||||
}
|
||||
|
||||
static void AddFiltersToCommandArgs(char** commandArgs, int commandArgsLen, const char *filterList )
|
||||
{
|
||||
char typebuf[NFD_MAX_STRLEN] = {0};
|
||||
const char *p_filterList = filterList;
|
||||
char *p_typebuf = typebuf;
|
||||
char filterName[NFD_MAX_STRLEN] = {0};
|
||||
int i;
|
||||
|
||||
if ( !filterList || strlen(filterList) == 0 )
|
||||
return;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
|
||||
if ( NFDi_IsFilterSegmentChar(*p_filterList) )
|
||||
{
|
||||
char typebufWildcard[NFD_MAX_STRLEN];
|
||||
/* add another type to the filter */
|
||||
assert( strlen(typebuf) > 0 );
|
||||
assert( strlen(typebuf) < NFD_MAX_STRLEN-1 );
|
||||
|
||||
snprintf( typebufWildcard, NFD_MAX_STRLEN, "*.%s", typebuf );
|
||||
|
||||
AddTypeToFilterName( typebuf, filterName, NFD_MAX_STRLEN );
|
||||
|
||||
p_typebuf = typebuf;
|
||||
memset( typebuf, 0, sizeof(char) * NFD_MAX_STRLEN );
|
||||
}
|
||||
|
||||
if ( *p_filterList == ';' || *p_filterList == '\0' )
|
||||
{
|
||||
/* end of filter -- add it to the dialog */
|
||||
|
||||
for(i = 0; commandArgs[i] != NULL && i < commandArgsLen; i++);
|
||||
|
||||
commandArgs[i] = strdup(filterName);
|
||||
|
||||
filterName[0] = '\0';
|
||||
|
||||
if ( *p_filterList == '\0' )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !NFDi_IsFilterSegmentChar( *p_filterList ) )
|
||||
{
|
||||
*p_typebuf = *p_filterList;
|
||||
p_typebuf++;
|
||||
}
|
||||
|
||||
p_filterList++;
|
||||
}
|
||||
|
||||
/* always append a wildcard option to the end*/
|
||||
|
||||
for(i = 0; commandArgs[i] != NULL && i < commandArgsLen; i++);
|
||||
|
||||
commandArgs[i] = strdup("--file-filter=*.*");
|
||||
}
|
||||
|
||||
static nfdresult_t ZenityCommon(char** command, int commandLen, const char* defaultPath, const char* filterList, char** stdOut)
|
||||
{
|
||||
if(defaultPath != NULL)
|
||||
{
|
||||
char* prefix = "--filename";
|
||||
int len = strlen(prefix) + strlen(defaultPath) + 1;
|
||||
|
||||
char* tmp = (char*) calloc(len, 1);
|
||||
strcat(tmp, prefix);
|
||||
strcat(tmp, defaultPath);
|
||||
|
||||
int i;
|
||||
for(i = 0; command[i] != NULL && i < commandLen; i++);
|
||||
|
||||
command[i] = tmp;
|
||||
}
|
||||
|
||||
AddFiltersToCommandArgs(command, commandLen, filterList);
|
||||
|
||||
int byteCount = 0;
|
||||
int exitCode = 0;
|
||||
int processInvokeError = runCommandArray(stdOut, &byteCount, &exitCode, 0, command);
|
||||
|
||||
for(int i = 0; command[i] != NULL && i < commandLen; i++)
|
||||
free(command[i]);
|
||||
|
||||
nfdresult_t result = NFD_OKAY;
|
||||
|
||||
if(processInvokeError == COMMAND_NOT_FOUND)
|
||||
{
|
||||
NFDi_SetError(NO_ZENITY_MSG);
|
||||
result = NFD_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(exitCode == 1)
|
||||
result = NFD_CANCEL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static nfdresult_t AllocPathSet(char* zenityList, nfdpathset_t *pathSet )
|
||||
{
|
||||
size_t bufSize = 0;
|
||||
nfdchar_t *p_buf;
|
||||
size_t count = 0;
|
||||
|
||||
assert(zenityList);
|
||||
assert(pathSet);
|
||||
|
||||
size_t len = strlen(zenityList) + 1;
|
||||
pathSet->buf = NFDi_Malloc(len);
|
||||
|
||||
int numEntries = 1;
|
||||
|
||||
for(size_t i = 0; i < len; i++)
|
||||
{
|
||||
char ch = zenityList[i];
|
||||
|
||||
if(ch == '|')
|
||||
{
|
||||
numEntries++;
|
||||
ch = '\0';
|
||||
}
|
||||
|
||||
pathSet->buf[i] = ch;
|
||||
}
|
||||
|
||||
pathSet->count = numEntries;
|
||||
assert( pathSet->count > 0 );
|
||||
|
||||
pathSet->indices = NFDi_Malloc( sizeof(size_t)*pathSet->count );
|
||||
|
||||
int entry = 0;
|
||||
pathSet->indices[0] = 0;
|
||||
for(size_t i = 0; i < len; i++)
|
||||
{
|
||||
char ch = zenityList[i];
|
||||
|
||||
if(ch == '|')
|
||||
{
|
||||
entry++;
|
||||
pathSet->indices[entry] = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NFD_OKAY;
|
||||
}
|
||||
|
||||
/* public */
|
||||
|
||||
nfdresult_t NFD_OpenDialog( const char *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath )
|
||||
{
|
||||
int commandLen = 100;
|
||||
char* command[commandLen];
|
||||
memset(command, 0, commandLen * sizeof(char*));
|
||||
|
||||
command[0] = strdup("zenity");
|
||||
command[1] = strdup("--file-selection");
|
||||
command[2] = strdup("--title=Open File");
|
||||
|
||||
char* stdOut = NULL;
|
||||
nfdresult_t result = ZenityCommon(command, commandLen, defaultPath, filterList, &stdOut);
|
||||
|
||||
if(stdOut != NULL)
|
||||
{
|
||||
size_t len = strlen(stdOut);
|
||||
*outPath = NFDi_Malloc(len);
|
||||
memcpy(*outPath, stdOut, len);
|
||||
(*outPath)[len-1] = '\0'; // trim out the final \n with a null terminator
|
||||
free(stdOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
*outPath = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdpathset_t *outPaths )
|
||||
{
|
||||
int commandLen = 100;
|
||||
char* command[commandLen];
|
||||
memset(command, 0, commandLen * sizeof(char*));
|
||||
|
||||
command[0] = strdup("zenity");
|
||||
command[1] = strdup("--file-selection");
|
||||
command[2] = strdup("--title=Open Files");
|
||||
command[3] = strdup("--multiple");
|
||||
|
||||
char* stdOut = NULL;
|
||||
nfdresult_t result = ZenityCommon(command, commandLen, defaultPath, filterList, &stdOut);
|
||||
|
||||
if(stdOut != NULL)
|
||||
{
|
||||
size_t len = strlen(stdOut);
|
||||
stdOut[len-1] = '\0'; // remove trailing newline
|
||||
|
||||
if ( AllocPathSet( stdOut, outPaths ) == NFD_ERROR )
|
||||
result = NFD_ERROR;
|
||||
|
||||
free(stdOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = NFD_ERROR;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
||||
const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath )
|
||||
{
|
||||
int commandLen = 100;
|
||||
char* command[commandLen];
|
||||
memset(command, 0, commandLen * sizeof(char*));
|
||||
|
||||
command[0] = strdup("zenity");
|
||||
command[1] = strdup("--file-selection");
|
||||
command[2] = strdup("--title=Save File");
|
||||
command[3] = strdup("--save");
|
||||
|
||||
char* stdOut = NULL;
|
||||
nfdresult_t result = ZenityCommon(command, commandLen, defaultPath, filterList, &stdOut);
|
||||
|
||||
if(stdOut != NULL)
|
||||
{
|
||||
size_t len = strlen(stdOut);
|
||||
*outPath = NFDi_Malloc(len);
|
||||
memcpy(*outPath, stdOut, len);
|
||||
(*outPath)[len-1] = '\0'; // trim out the final \n with a null terminator
|
||||
free(stdOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
*outPath = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath)
|
||||
{
|
||||
int commandLen = 100;
|
||||
char* command[commandLen];
|
||||
memset(command, 0, commandLen * sizeof(char*));
|
||||
|
||||
command[0] = strdup("zenity");
|
||||
command[1] = strdup("--file-selection");
|
||||
command[2] = strdup("--directory");
|
||||
command[3] = strdup("--title=Select folder");
|
||||
|
||||
char* stdOut = NULL;
|
||||
nfdresult_t result = ZenityCommon(command, commandLen, defaultPath, "", &stdOut);
|
||||
|
||||
if(stdOut != NULL)
|
||||
{
|
||||
size_t len = strlen(stdOut);
|
||||
*outPath = NFDi_Malloc(len);
|
||||
memcpy(*outPath, stdOut, len);
|
||||
(*outPath)[len-1] = '\0'; // trim out the final \n with a null terminator
|
||||
free(stdOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
*outPath = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
214
Engine/lib/nativeFileDialogs/simple_exec.h
Normal file
214
Engine/lib/nativeFileDialogs/simple_exec.h
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
// copied from: https://github.com/wheybags/simple_exec/blob/5a74c507c4ce1b2bb166177ead4cca7cfa23cb35/simple_exec.h
|
||||
|
||||
// simple_exec.h, single header library to run external programs + retrieve their status code and output (unix only for now)
|
||||
//
|
||||
// do this:
|
||||
// #define SIMPLE_EXEC_IMPLEMENTATION
|
||||
// before you include this file in *one* C or C++ file to create the implementation.
|
||||
// i.e. it should look like this:
|
||||
// #define SIMPLE_EXEC_IMPLEMENTATION
|
||||
// #include "simple_exec.h"
|
||||
|
||||
#ifndef SIMPLE_EXEC_H
|
||||
#define SIMPLE_EXEC_H
|
||||
|
||||
int runCommand(char** stdOut, int* stdOutByteCount, int* returnCode, int includeStdErr, char* command, ...);
|
||||
int runCommandArray(char** stdOut, int* stdOutByteCount, int* returnCode, int includeStdErr, char* const* allArgs);
|
||||
|
||||
#endif // SIMPLE_EXEC_H
|
||||
|
||||
#ifdef SIMPLE_EXEC_IMPLEMENTATION
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define release_assert(x) do { int __release_assert_tmp__ = (x); assert(__release_assert_tmp__); } while(0)
|
||||
|
||||
enum PIPE_FILE_DESCRIPTORS
|
||||
{
|
||||
READ_FD = 0,
|
||||
WRITE_FD = 1
|
||||
};
|
||||
|
||||
enum RUN_COMMAND_ERROR
|
||||
{
|
||||
COMMAND_RAN_OK = 0,
|
||||
COMMAND_NOT_FOUND = 1
|
||||
};
|
||||
|
||||
int runCommandArray(char** stdOut, int* stdOutByteCount, int* returnCode, int includeStdErr, char* const* allArgs)
|
||||
{
|
||||
// adapted from: https://stackoverflow.com/a/479103
|
||||
|
||||
int bufferSize = 256;
|
||||
char buffer[bufferSize + 1];
|
||||
|
||||
int dataReadFromChildDefaultSize = bufferSize * 5;
|
||||
int dataReadFromChildSize = dataReadFromChildDefaultSize;
|
||||
int dataReadFromChildUsed = 0;
|
||||
char* dataReadFromChild = (char*)malloc(dataReadFromChildSize);
|
||||
|
||||
|
||||
int parentToChild[2];
|
||||
release_assert(pipe(parentToChild) == 0);
|
||||
|
||||
int childToParent[2];
|
||||
release_assert(pipe(childToParent) == 0);
|
||||
|
||||
int errPipe[2];
|
||||
release_assert(pipe(errPipe) == 0);
|
||||
|
||||
pid_t pid;
|
||||
switch( pid = fork() )
|
||||
{
|
||||
case -1:
|
||||
{
|
||||
release_assert(0 && "Fork failed");
|
||||
}
|
||||
|
||||
case 0: // child
|
||||
{
|
||||
release_assert(dup2(parentToChild[READ_FD ], STDIN_FILENO ) != -1);
|
||||
release_assert(dup2(childToParent[WRITE_FD], STDOUT_FILENO) != -1);
|
||||
|
||||
if(includeStdErr)
|
||||
{
|
||||
release_assert(dup2(childToParent[WRITE_FD], STDERR_FILENO) != -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int devNull = open("/dev/null", O_WRONLY);
|
||||
release_assert(dup2(devNull, STDERR_FILENO) != -1);
|
||||
}
|
||||
|
||||
// unused
|
||||
release_assert(close(parentToChild[WRITE_FD]) == 0);
|
||||
release_assert(close(childToParent[READ_FD ]) == 0);
|
||||
release_assert(close(errPipe[READ_FD]) == 0);
|
||||
|
||||
const char* command = allArgs[0];
|
||||
execvp(command, allArgs);
|
||||
|
||||
char err = 1;
|
||||
write(errPipe[WRITE_FD], &err, 1);
|
||||
|
||||
close(errPipe[WRITE_FD]);
|
||||
close(parentToChild[READ_FD]);
|
||||
close(childToParent[WRITE_FD]);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
default: // parent
|
||||
{
|
||||
// unused
|
||||
release_assert(close(parentToChild[READ_FD]) == 0);
|
||||
release_assert(close(childToParent[WRITE_FD]) == 0);
|
||||
release_assert(close(errPipe[WRITE_FD]) == 0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
ssize_t bytesRead = 0;
|
||||
switch(bytesRead = read(childToParent[READ_FD], buffer, bufferSize))
|
||||
{
|
||||
case 0: // End-of-File, or non-blocking read.
|
||||
{
|
||||
int status = 0;
|
||||
release_assert(waitpid(pid, &status, 0) == pid);
|
||||
|
||||
// done with these now
|
||||
release_assert(close(parentToChild[WRITE_FD]) == 0);
|
||||
release_assert(close(childToParent[READ_FD]) == 0);
|
||||
|
||||
char errChar = 0;
|
||||
read(errPipe[READ_FD], &errChar, 1);
|
||||
close(errPipe[READ_FD]);
|
||||
|
||||
if(errChar)
|
||||
{
|
||||
free(dataReadFromChild);
|
||||
return COMMAND_NOT_FOUND;
|
||||
}
|
||||
|
||||
// free any un-needed memory with realloc + add a null terminator for convenience
|
||||
dataReadFromChild = (char*)realloc(dataReadFromChild, dataReadFromChildUsed + 1);
|
||||
dataReadFromChild[dataReadFromChildUsed] = '\0';
|
||||
|
||||
if(stdOut != NULL)
|
||||
*stdOut = dataReadFromChild;
|
||||
else
|
||||
free(dataReadFromChild);
|
||||
|
||||
if(stdOutByteCount != NULL)
|
||||
*stdOutByteCount = dataReadFromChildUsed;
|
||||
if(returnCode != NULL)
|
||||
*returnCode = WEXITSTATUS(status);
|
||||
|
||||
return COMMAND_RAN_OK;
|
||||
}
|
||||
case -1:
|
||||
{
|
||||
release_assert(0 && "read() failed");
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if(dataReadFromChildUsed + bytesRead + 1 >= dataReadFromChildSize)
|
||||
{
|
||||
dataReadFromChildSize += dataReadFromChildDefaultSize;
|
||||
dataReadFromChild = (char*)realloc(dataReadFromChild, dataReadFromChildSize);
|
||||
}
|
||||
|
||||
memcpy(dataReadFromChild + dataReadFromChildUsed, buffer, bytesRead);
|
||||
dataReadFromChildUsed += bytesRead;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int runCommand(char** stdOut, int* stdOutByteCount, int* returnCode, int includeStdErr, char* command, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, command);
|
||||
|
||||
char* currArg = NULL;
|
||||
|
||||
int allArgsInitialSize = 16;
|
||||
int allArgsSize = allArgsInitialSize;
|
||||
char** allArgs = (char**)malloc(sizeof(char*) * allArgsSize);
|
||||
allArgs[0] = command;
|
||||
|
||||
int i = 1;
|
||||
do
|
||||
{
|
||||
currArg = va_arg(vl, char*);
|
||||
allArgs[i] = currArg;
|
||||
|
||||
i++;
|
||||
|
||||
if(i >= allArgsSize)
|
||||
{
|
||||
allArgsSize += allArgsInitialSize;
|
||||
allArgs = (char**)realloc(allArgs, sizeof(char*) * allArgsSize);
|
||||
}
|
||||
|
||||
} while(currArg != NULL);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
int retval = runCommandArray(stdOut, stdOutByteCount, returnCode, includeStdErr, allArgs);
|
||||
free(allArgs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif //SIMPLE_EXEC_IMPLEMENTATION
|
||||
236
Engine/source/T3D/Scene.cpp
Normal file
236
Engine/source/T3D/Scene.cpp
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
#include "Scene.h"
|
||||
|
||||
Scene * Scene::smRootScene = nullptr;
|
||||
Vector<Scene*> Scene::smSceneList;
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(Scene);
|
||||
|
||||
Scene::Scene() :
|
||||
mIsSubScene(false),
|
||||
mParentScene(nullptr),
|
||||
mSceneId(-1),
|
||||
mIsEditing(false),
|
||||
mIsDirty(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addGroup("Internal");
|
||||
addField("isSubscene", TypeBool, Offset(mIsSubScene, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
addField("isEditing", TypeBool, Offset(mIsEditing, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
addField("isDirty", TypeBool, Offset(mIsDirty, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
endGroup("Internal");
|
||||
}
|
||||
|
||||
bool Scene::onAdd()
|
||||
{
|
||||
if (!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
smSceneList.push_back(this);
|
||||
mSceneId = smSceneList.size() - 1;
|
||||
|
||||
/*if (smRootScene == nullptr)
|
||||
{
|
||||
//we're the first scene, so we're the root. woo!
|
||||
smRootScene = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsSubScene = true;
|
||||
smRootScene->mSubScenes.push_back(this);
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scene::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
|
||||
smSceneList.remove(this);
|
||||
mSceneId = -1;
|
||||
|
||||
/*if (smRootScene == this)
|
||||
{
|
||||
for (U32 i = 0; i < mSubScenes.size(); i++)
|
||||
{
|
||||
mSubScenes[i]->deleteObject();
|
||||
}
|
||||
}
|
||||
else if (smRootScene != nullptr)
|
||||
{
|
||||
for (U32 i = 0; i < mSubScenes.size(); i++)
|
||||
{
|
||||
if(mSubScenes[i]->getId() == getId())
|
||||
smRootScene->mSubScenes.erase(i);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Scene::addObject(SimObject* object)
|
||||
{
|
||||
//Child scene
|
||||
Scene* scene = dynamic_cast<Scene*>(object);
|
||||
if (scene)
|
||||
{
|
||||
//We'll keep these principly separate so they don't get saved into each other
|
||||
mSubScenes.push_back(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
|
||||
if (sceneObj)
|
||||
{
|
||||
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
|
||||
mPermanentObjects.push_back(sceneObj);
|
||||
Parent::addObject(object);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::addObject(object);
|
||||
}
|
||||
|
||||
void Scene::removeObject(SimObject* object)
|
||||
{
|
||||
//Child scene
|
||||
Scene* scene = dynamic_cast<Scene*>(object);
|
||||
if (scene)
|
||||
{
|
||||
//We'll keep these principly separate so they don't get saved into each other
|
||||
mSubScenes.remove(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
|
||||
if (sceneObj)
|
||||
{
|
||||
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
|
||||
|
||||
mPermanentObjects.remove(sceneObj);
|
||||
Parent::removeObject(object);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Parent::removeObject(object);
|
||||
}
|
||||
|
||||
void Scene::addDynamicObject(SceneObject* object)
|
||||
{
|
||||
mDynamicObjects.push_back(object);
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::addObject(object);
|
||||
}
|
||||
|
||||
void Scene::removeDynamicObject(SceneObject* object)
|
||||
{
|
||||
mDynamicObjects.remove(object);
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::removeObject(object);
|
||||
}
|
||||
|
||||
void Scene::interpolateTick(F32 delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::processTick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::advanceTime(F32 timeDelta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
U32 Scene::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
|
||||
{
|
||||
bool ret = Parent::packUpdate(conn, mask, stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Scene::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
Vector<SceneObject*> Scene::getObjectsByClass(String className)
|
||||
{
|
||||
return Vector<SceneObject*>();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getScene, Scene*, (U32 sceneId), (0),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
if (Scene::smSceneList.empty() || sceneId >= Scene::smSceneList.size())
|
||||
return nullptr;
|
||||
|
||||
return Scene::smSceneList[sceneId];
|
||||
}
|
||||
|
||||
DefineEngineFunction(getRootScene, S32, (), ,
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
Scene* root = Scene::getRootScene();
|
||||
|
||||
if (root)
|
||||
return root->getId();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, getRootScene, S32, (),,
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
Scene* root = Scene::getRootScene();
|
||||
|
||||
if (root)
|
||||
return root->getId();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, addDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
object->addDynamicObject(sceneObj);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, removeDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
object->removeDynamicObject(sceneObj);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, getObjectsByClass, String, (String className), (""),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
if (className == String::EmptyString)
|
||||
return "";
|
||||
|
||||
//return object->getObjectsByClass(className);
|
||||
return "";
|
||||
}
|
||||
79
Engine/source/T3D/Scene.h
Normal file
79
Engine/source/T3D/Scene.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#ifndef _NETOBJECT_H_
|
||||
#include "sim/netObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ITICKABLE_H_
|
||||
#include "core/iTickable.h"
|
||||
#endif
|
||||
|
||||
#include "scene/sceneObject.h"
|
||||
|
||||
/// Scene
|
||||
/// This object is effectively a smart container to hold and manage any relevent scene objects and data
|
||||
/// used to run things.
|
||||
class Scene : public NetObject, public virtual ITickable
|
||||
{
|
||||
typedef NetObject Parent;
|
||||
|
||||
bool mIsSubScene;
|
||||
|
||||
Scene* mParentScene;
|
||||
|
||||
Vector<Scene*> mSubScenes;
|
||||
|
||||
Vector<SceneObject*> mPermanentObjects;
|
||||
|
||||
Vector<SceneObject*> mDynamicObjects;
|
||||
|
||||
S32 mSceneId;
|
||||
|
||||
bool mIsEditing;
|
||||
|
||||
bool mIsDirty;
|
||||
|
||||
protected:
|
||||
static Scene * smRootScene;
|
||||
|
||||
DECLARE_CONOBJECT(Scene);
|
||||
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
virtual void interpolateTick(F32 delta);
|
||||
virtual void processTick();
|
||||
virtual void advanceTime(F32 timeDelta);
|
||||
|
||||
virtual void addObject(SimObject* object);
|
||||
virtual void removeObject(SimObject* object);
|
||||
|
||||
void addDynamicObject(SceneObject* object);
|
||||
void removeDynamicObject(SceneObject* object);
|
||||
|
||||
//
|
||||
//Networking
|
||||
U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
|
||||
void unpackUpdate(NetConnection *conn, BitStream *stream);
|
||||
|
||||
//
|
||||
Vector<SceneObject*> getObjectsByClass(String className);
|
||||
|
||||
static Scene *getRootScene()
|
||||
{
|
||||
if (Scene::smSceneList.empty())
|
||||
return nullptr;
|
||||
|
||||
return Scene::smSceneList[0];
|
||||
}
|
||||
|
||||
static Vector<Scene*> smSceneList;
|
||||
};
|
||||
|
|
@ -621,8 +621,6 @@ void AnimationComponent::advanceThreads(F32 dt)
|
|||
Thread& st = mAnimationThreads[i];
|
||||
if (st.thread && st.sequence != -1)
|
||||
{
|
||||
bool cyclic = getShape()->sequences[st.sequence].isCyclic();
|
||||
|
||||
if (!getShape()->sequences[st.sequence].isCyclic() &&
|
||||
!st.atEnd &&
|
||||
((st.timescale > 0.f) ? mOwnerShapeInstance->getPos(st.thread) >= 1.0 : mOwnerShapeInstance->getPos(st.thread) <= 0))
|
||||
|
|
|
|||
|
|
@ -237,8 +237,6 @@ bool CameraComponent::getCameraTransform(F32* pos,MatrixF* mat)
|
|||
{
|
||||
// Returns camera to world space transform
|
||||
// Handles first person / third person camera position
|
||||
bool isServer = isServerObject();
|
||||
|
||||
if (mTargetNodeIdx == -1)
|
||||
{
|
||||
if (mUseParentTransform)
|
||||
|
|
@ -479,7 +477,6 @@ void CameraComponent::setRotation(RotationF newRot)
|
|||
Frustum CameraComponent::getFrustum()
|
||||
{
|
||||
Frustum visFrustum;
|
||||
F32 left, right, top, bottom;
|
||||
F32 aspectRatio = mClientScreen.x / mClientScreen.y;
|
||||
|
||||
visFrustum.set(false, mDegToRad(mCameraFov), aspectRatio, 0.1f, 1000, mOwner->getTransform());
|
||||
|
|
|
|||
|
|
@ -538,7 +538,6 @@ PhysicsCollision* CollisionComponent::buildColShapes()
|
|||
for (S32 o = start; o < end; o++)
|
||||
{
|
||||
const TSShape::Object &object = shape->objects[o];
|
||||
const String &meshName = shape->names[object.nameIndex];
|
||||
|
||||
if (object.numMeshes <= detail.objectDetailNum)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ void StateMachine::readConditions(StateTransition ¤tTransition)
|
|||
//get our first state
|
||||
StateTransition::Condition firstCondition;
|
||||
StateField firstField;
|
||||
bool fieldRead = false;
|
||||
|
||||
readFieldName(&firstField, reader);
|
||||
firstCondition.field = firstField;
|
||||
|
|
|
|||
|
|
@ -239,8 +239,6 @@ bool TriggerComponent::testObject(SceneObject* enter)
|
|||
myList.setObject(mOwner);
|
||||
|
||||
myCI->buildPolyList(PLC_Collision, &myList, enterBox, sphere);
|
||||
|
||||
bool test = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,9 +330,6 @@ void PlayerControllerComponent::updateMove()
|
|||
}
|
||||
|
||||
// Update current orientation
|
||||
bool doStandardMove = true;
|
||||
GameConnection* con = mOwner->getControllingClient();
|
||||
|
||||
MatrixF zRot;
|
||||
zRot.set(EulerF(0.0f, 0.0f, mOwner->getRotation().asEulerF().z));
|
||||
|
||||
|
|
@ -355,7 +352,6 @@ void PlayerControllerComponent::updateMove()
|
|||
mContactInfo.jump = false;
|
||||
mContactInfo.run = false;
|
||||
|
||||
bool jumpSurface = false, runSurface = false;
|
||||
if (!mOwner->isMounted())
|
||||
findContact(&mContactInfo.run, &mContactInfo.jump, &mContactInfo.contactNormal);
|
||||
if (mContactInfo.jump)
|
||||
|
|
@ -577,7 +573,6 @@ void PlayerControllerComponent::updatePos(const F32 travelTime)
|
|||
newPos = mPhysicsRep->move(mVelocity * travelTime, collisionList);
|
||||
|
||||
bool haveCollisions = false;
|
||||
bool wasFalling = mFalling;
|
||||
if (collisionList.getCount() > 0)
|
||||
{
|
||||
mFalling = false;
|
||||
|
|
|
|||
|
|
@ -719,8 +719,6 @@ bool ConvexShape::buildExportPolyList(ColladaUtils::ExportData* exportData, cons
|
|||
//Convex shapes only have the one 'level', so we'll just rely on the export post-process to back-fill
|
||||
if (isServerObject() && getClientObject())
|
||||
{
|
||||
ConvexShape* clientShape = dynamic_cast<ConvexShape*>(getClientObject());
|
||||
|
||||
exportData->meshData.increment();
|
||||
|
||||
//Prep a meshData for this shape in particular
|
||||
|
|
|
|||
|
|
@ -306,8 +306,6 @@ void Entity::onPostAdd()
|
|||
|
||||
bool Entity::_setGameObject(void *object, const char *index, const char *data)
|
||||
{
|
||||
Entity *e = static_cast<Entity*>(object);
|
||||
|
||||
// Sanity!
|
||||
AssertFatal(data != NULL, "Cannot use a NULL asset Id.");
|
||||
|
||||
|
|
@ -513,8 +511,6 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
|||
|
||||
for (U32 i = 0; i < mNetworkedComponents.size(); i++)
|
||||
{
|
||||
NetworkedComponent::UpdateState state = mNetworkedComponents[i].updateState;
|
||||
|
||||
if (mNetworkedComponents[i].updateState == NetworkedComponent::Adding)
|
||||
{
|
||||
const char* className = mComponents[mNetworkedComponents[i].componentIndex]->getClassName();
|
||||
|
|
@ -1381,7 +1377,6 @@ bool Entity::removeComponent(Component *comp, bool deleteComponent)
|
|||
//to re-add them. Need to implement a clean clear function that will clear the local list, and only delete unused behaviors during an update.
|
||||
void Entity::clearComponents(bool deleteComponents)
|
||||
{
|
||||
bool srv = isServerObject();
|
||||
if (!deleteComponents)
|
||||
{
|
||||
while (mComponents.size() > 0)
|
||||
|
|
@ -1399,8 +1394,6 @@ void Entity::clearComponents(bool deleteComponents)
|
|||
{
|
||||
comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
|
||||
|
||||
bool removed = mComponents.remove(comp);
|
||||
|
||||
//we only need to delete them on the server side. they'll be cleaned up on the client side
|
||||
//via the ghosting system for us
|
||||
if (isServerObject())
|
||||
|
|
@ -1663,7 +1656,6 @@ void Entity::notifyComponents(String signalFunction, String argA, String argB, S
|
|||
|
||||
void Entity::setComponentsDirty()
|
||||
{
|
||||
bool tmp = true;
|
||||
/*if (mToLoadComponents.empty())
|
||||
mStartComponentUpdate = true;
|
||||
|
||||
|
|
@ -1694,7 +1686,6 @@ void Entity::setComponentsDirty()
|
|||
|
||||
void Entity::setComponentDirty(Component *comp, bool forceUpdate)
|
||||
{
|
||||
bool found = false;
|
||||
for (U32 i = 0; i < mComponents.size(); i++)
|
||||
{
|
||||
if (mComponents[i]->getId() == comp->getId())
|
||||
|
|
|
|||
|
|
@ -309,7 +309,6 @@ Vector<T*> Entity::getComponents()
|
|||
Vector<T*> foundObjects;
|
||||
|
||||
T *curObj;
|
||||
Component* comp;
|
||||
|
||||
// Loop through our child objects.
|
||||
for (U32 i = 0; i < mComponents.size(); i++)
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ void ParticleEmitterData::unpackData(BitStream* stream)
|
|||
#if defined(AFX_CAP_PARTICLE_POOLS)
|
||||
if (stream->readFlag())
|
||||
{
|
||||
pool_datablock = (afxParticlePoolData*)stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
pool_datablock = (afxParticlePoolData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
|
||||
stream->read(&pool_index);
|
||||
pool_depth_fade = stream->readFlag();
|
||||
pool_radial_fade = stream->readFlag();
|
||||
|
|
|
|||
|
|
@ -553,7 +553,6 @@ void renderFrame(GFXTextureTargetRef* target, MatrixF transform, Frustum frustum
|
|||
GFX->setStateBlock(mDefaultGuiSB);
|
||||
|
||||
GFXTargetRef origTarget = GFX->getActiveRenderTarget();
|
||||
U32 origStyle = GFX->getCurrentRenderStyle();
|
||||
|
||||
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
|
||||
GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
|
||||
|
|
|
|||
|
|
@ -6150,8 +6150,22 @@ void Player::updateWorkingCollisionSet()
|
|||
mWorkingQueryBox.maxExtents += twolPoint;
|
||||
|
||||
disableCollision();
|
||||
|
||||
//We temporarily disable the collisions of anything mounted to us so we don't accidentally walk into things we've attached to us
|
||||
for (SceneObject *ptr = mMount.list; ptr; ptr = ptr->getMountLink())
|
||||
{
|
||||
ptr->disableCollision();
|
||||
}
|
||||
|
||||
mConvex.updateWorkingList(mWorkingQueryBox,
|
||||
isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask);
|
||||
|
||||
//And now re-enable the collisions of the mounted things
|
||||
for (SceneObject *ptr = mMount.list; ptr; ptr = ptr->getMountLink())
|
||||
{
|
||||
ptr->enableCollision();
|
||||
}
|
||||
|
||||
enableCollision();
|
||||
}
|
||||
}
|
||||
|
|
@ -6345,6 +6359,14 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
|||
if(len > 8191)
|
||||
len = 8191;
|
||||
stream->writeInt((S32)len, 13);
|
||||
|
||||
// constrain the range of mRot.z
|
||||
while (mRot.z < 0.0f)
|
||||
mRot.z += M_2PI_F;
|
||||
while (mRot.z > M_2PI_F)
|
||||
mRot.z -= M_2PI_F;
|
||||
|
||||
|
||||
}
|
||||
stream->writeFloat(mRot.z / M_2PI_F, 7);
|
||||
stream->writeSignedFloat(mHead.x / (mDataBlock->maxLookAngle - mDataBlock->minLookAngle), 6);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "T3D/physics/physicsShape.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
// We use this locally ( within this file ) to prevent infinite recursion
|
||||
// while loading prefab files that contain other prefabs.
|
||||
static Vector<String> sPrefabFileStack;
|
||||
|
|
@ -269,11 +271,11 @@ void Prefab::setFile( String file )
|
|||
|
||||
SimGroup* Prefab::explode()
|
||||
{
|
||||
SimGroup *missionGroup;
|
||||
Scene* scene = Scene::getRootScene();
|
||||
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
if ( !scene)
|
||||
{
|
||||
Con::errorf( "Prefab::explode, MissionGroup was not found." );
|
||||
Con::errorf( "Prefab::explode, Scene was not found." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +297,7 @@ SimGroup* Prefab::explode()
|
|||
smChildToPrefabMap.erase( child->getId() );
|
||||
}
|
||||
|
||||
missionGroup->addObject(group);
|
||||
scene->addObject(group);
|
||||
mChildGroup = NULL;
|
||||
mChildMap.clear();
|
||||
|
||||
|
|
@ -468,10 +470,10 @@ Prefab* Prefab::getPrefabByChild( SimObject *child )
|
|||
|
||||
bool Prefab::isValidChild( SimObject *simobj, bool logWarnings )
|
||||
{
|
||||
if ( simobj->getName() && dStricmp(simobj->getName(),"MissionGroup") == 0 )
|
||||
if ( simobj->getName() && simobj == Scene::getRootScene() )
|
||||
{
|
||||
if ( logWarnings )
|
||||
Con::warnf( "MissionGroup is not valid within a Prefab." );
|
||||
Con::warnf( "root Scene is not valid within a Prefab." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public:
|
|||
void setFile( String file );
|
||||
|
||||
/// Removes all children from this Prefab and puts them into a SimGroup
|
||||
/// which is added to the MissionGroup and returned to the caller.
|
||||
/// which is added to the Scene and returned to the caller.
|
||||
SimGroup* explode();
|
||||
|
||||
bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@ class ProximityMine: public Item
|
|||
protected:
|
||||
enum MaskBits {
|
||||
DeployedMask = Parent::NextFreeMask,
|
||||
ExplosionMask = Parent::NextFreeMask << 1,
|
||||
NextFreeMask = Parent::NextFreeMask << 2
|
||||
ExplosionMask = Parent::NextFreeMask << 1
|
||||
};
|
||||
|
||||
enum State
|
||||
|
|
|
|||
|
|
@ -3266,7 +3266,7 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
st.play = stream->readFlag();
|
||||
if ( st.play )
|
||||
{
|
||||
st.profile = (SFXTrack*) stream->readRangedU32( DataBlockObjectIdFirst,
|
||||
st.profile = (SFXTrack*)(uintptr_t)stream->readRangedU32( DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ ShapeBaseImageData::ShapeBaseImageData()
|
|||
lightRadius = 10.f;
|
||||
lightBrightness = 1.0f;
|
||||
|
||||
shapeName = "core/art/shapes/noshape.dts";
|
||||
shapeName = "core/shapes/noshape.dts";
|
||||
shapeNameFP = "";
|
||||
imageAnimPrefix = "";
|
||||
imageAnimPrefixFP = "";
|
||||
|
|
@ -1202,7 +1202,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
|
|||
}
|
||||
|
||||
projectile = (stream->readFlag() ?
|
||||
(ProjectileData*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
(ProjectileData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast) : 0);
|
||||
|
||||
cloakable = stream->readFlag();
|
||||
|
|
@ -1340,7 +1340,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
|
|||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
s.emitter = (ParticleEmitterData*) stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
s.emitter = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
stream->read(&s.emitterTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@ void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* stat
|
|||
for (U32 i = 0; i < count; i++)
|
||||
{
|
||||
//Server side items exist for data, but we don't actually render them
|
||||
bool isClient = MeshRenderSystemInterface::all[i]->mIsClient;
|
||||
if (!MeshRenderSystemInterface::all[i]->mIsClient)
|
||||
continue;
|
||||
|
||||
bool isStatic = MeshRenderSystemInterface::all[i]->mStatic;
|
||||
if (MeshRenderSystemInterface::all[i]->mStatic)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,6 @@ bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const B
|
|||
if (isServerObject() && getClientObject())
|
||||
{
|
||||
TSStatic* clientShape = dynamic_cast<TSStatic*>(getClientObject());
|
||||
U32 numDetails = clientShape->mShapeInstance->getNumDetails() - 1;
|
||||
|
||||
exportData->meshData.increment();
|
||||
|
||||
|
|
|
|||
|
|
@ -282,14 +282,14 @@ void FlyingVehicleData::unpackData(BitStream* stream)
|
|||
for (S32 i = 0; i < MaxSounds; i++) {
|
||||
sound[i] = NULL;
|
||||
if (stream->readFlag())
|
||||
sound[i] = (SFXProfile*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
sound[i] = (SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
for (S32 j = 0; j < MaxJetEmitters; j++) {
|
||||
jetEmitter[j] = NULL;
|
||||
if (stream->readFlag())
|
||||
jetEmitter[j] = (ParticleEmitterData*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
jetEmitter[j] = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -411,13 +411,13 @@ void HoverVehicleData::unpackData(BitStream* stream)
|
|||
|
||||
for (S32 i = 0; i < MaxSounds; i++)
|
||||
sound[i] = stream->readFlag()?
|
||||
(SFXProfile*) stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
(SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast): 0;
|
||||
|
||||
for (S32 j = 0; j < MaxJetEmitters; j++) {
|
||||
jetEmitter[j] = NULL;
|
||||
if (stream->readFlag())
|
||||
jetEmitter[j] = (ParticleEmitterData*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
jetEmitter[j] = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ void VehicleData::unpackData(BitStream* stream)
|
|||
for (i = 0; i < Body::MaxSounds; i++) {
|
||||
body.sound[i] = NULL;
|
||||
if (stream->readFlag())
|
||||
body.sound[i] = (SFXProfile*)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
body.sound[i] = (SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ void WheeledVehicleData::unpackData(BitStream* stream)
|
|||
Parent::unpackData(stream);
|
||||
|
||||
tireEmitter = stream->readFlag()?
|
||||
(ParticleEmitterData*) stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
(ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
|
||||
DataBlockObjectIdLast): 0;
|
||||
|
||||
for (S32 i = 0; i < MaxSounds; i++)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void afxEffectGroupData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
|||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
|
||||
}
|
||||
|
||||
#define myOffset(field) Offset(field, afxEffectGroupData)
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ void afxEffectWrapperData::unpack_mods(BitStream* stream, afxXM_BaseData* mods[]
|
|||
{
|
||||
S32 n_mods = stream->readInt(6);
|
||||
for (int i = 0; i < n_mods; i++)
|
||||
mods[i] = (afxXM_BaseData*) readDatablockID(stream);
|
||||
mods[i] = (afxXM_BaseData*)(uintptr_t)readDatablockID(stream);
|
||||
}
|
||||
|
||||
bool afxEffectWrapperData::preload(bool server, String &errorStr)
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ void afxEffectronData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
|||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
|
||||
}
|
||||
|
||||
void afxEffectronData::packData(BitStream* stream)
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ void afxMagicSpellData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
|||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
|
||||
}
|
||||
|
||||
void afxMagicSpellData::packData(BitStream* stream)
|
||||
|
|
@ -356,7 +356,7 @@ void afxMagicSpellData::unpackData(BitStream* stream)
|
|||
mDo_move_interrupts = stream->readFlag();
|
||||
stream->read(&mMove_interrupt_speed);
|
||||
|
||||
mMissile_db = (afxMagicMissileData*) readDatablockID(stream);
|
||||
mMissile_db = (afxMagicMissileData*)(uintptr_t)readDatablockID(stream);
|
||||
stream->read(&mLaunch_on_server_signal);
|
||||
stream->read(&mPrimary_target_types);
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,12 @@ void afxRenderHighlightMgr::render( SceneRenderState *state )
|
|||
matrixSet.setProjection(*passRI->projection);
|
||||
mat->setTransforms(matrixSet, state);
|
||||
|
||||
// Setup HW skinning transforms if applicable
|
||||
if (mat->usesHardwareSkinning())
|
||||
{
|
||||
mat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount);
|
||||
}
|
||||
|
||||
mat->setSceneInfo(state, sgData);
|
||||
mat->setBuffers(passRI->vertBuff, passRI->primBuff);
|
||||
|
||||
|
|
@ -173,4 +179,4 @@ void afxRenderHighlightMgr::render( SceneRenderState *state )
|
|||
|
||||
// Make sure the effect is gonna render.
|
||||
getSelectionEffect()->setSkip( false );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ void afxSelectronData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
|||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
|
||||
}
|
||||
|
||||
void afxSelectronData::packData(BitStream* stream)
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ void afxSpellBookData::unpackData(BitStream* stream)
|
|||
|
||||
do_id_convert = true;
|
||||
for (S32 i = 0; i < pages_per_book*spells_per_page; i++)
|
||||
rpg_spells[i] = (afxRPGMagicSpellData*) readDatablockID(stream);
|
||||
rpg_spells[i] = (afxRPGMagicSpellData*)(uintptr_t)readDatablockID(stream);
|
||||
}
|
||||
|
||||
DefineEngineMethod(afxSpellBookData, getPageSlotIndex, S32, (Point2I bookSlot),,
|
||||
|
|
|
|||
|
|
@ -195,8 +195,8 @@ void afxT3DLightBaseData::unpackData(BitStream* stream)
|
|||
stream->read( &mAnimState.animationPhase );
|
||||
stream->read( &mFlareScale );
|
||||
|
||||
mAnimationData = (LightAnimData*) readDatablockID(stream);
|
||||
mFlareData = (LightFlareData*) readDatablockID(stream);
|
||||
mAnimationData = (LightAnimData*)(uintptr_t)readDatablockID(stream);
|
||||
mFlareData = (LightFlareData*)(uintptr_t)readDatablockID(stream);
|
||||
|
||||
do_id_convert = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ void afxPhraseEffectData::unpack_fx(BitStream* stream, afxEffectList& fx)
|
|||
fx.clear();
|
||||
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
|
||||
for (int i = 0; i < n_fx; i++)
|
||||
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
|
||||
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
|
||||
}
|
||||
|
||||
void afxPhraseEffectData::packData(BitStream* stream)
|
||||
|
|
|
|||
|
|
@ -1611,9 +1611,7 @@ static void handleExtendedMasterServerListResponse(BitStream* stream, U32 key, U
|
|||
{
|
||||
U16 packetIndex, packetTotal;
|
||||
U32 i;
|
||||
U16 serverCount, port;
|
||||
U8 netNum[16];
|
||||
char addressBuffer[256];
|
||||
U16 serverCount;
|
||||
NetAddress addr;
|
||||
|
||||
stream->read(&packetIndex);
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ void AssetManager::initPersistFields()
|
|||
// Call parent.
|
||||
Parent::initPersistFields();
|
||||
|
||||
addField( "EchoInfo", TypeBool, Offset(mEchoInfo, AssetManager), "Whether the asset manager echos extra information to the console or not." );
|
||||
addField( "IgnoreAutoUnload", TypeBool, Offset(mIgnoreAutoUnload, AssetManager), "Whether the asset manager should ignore unloading of auto-unload assets or not." );
|
||||
addField( "EchoInfo", TypeBool, false, Offset(mEchoInfo, AssetManager), "Whether the asset manager echos extra information to the console or not." );
|
||||
addField( "IgnoreAutoUnload", TypeBool, true, Offset(mIgnoreAutoUnload, AssetManager), "Whether the asset manager should ignore unloading of auto-unload assets or not." );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -228,7 +228,7 @@ bool AssetManager::loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition)
|
|||
AssertFatal(pModuleDefinition != NULL, "Cannot auto load assets using a NULL module definition");
|
||||
|
||||
// Does the module have any assets associated with it?
|
||||
if (pModuleDefinition->getModuleAssets().empty())
|
||||
if (pModuleDefinition->getModuleAssets().empty() && mEchoInfo)
|
||||
{
|
||||
// Yes, so warn.
|
||||
Con::warnf("Asset Manager: Cannot auto load assets to module '%s' as it has no existing assets.", pModuleDefinition->getSignature());
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ public:
|
|||
/// Define a call-in point for calling into the engine. Unlike with DefineEngineFunction, the statically
|
||||
/// callable function will be confined to the namespace of the given class.
|
||||
///
|
||||
/// @param name The name of the C++ class (or a registered export scope).
|
||||
/// @param classname The name of the C++ class (or a registered export scope).
|
||||
/// @param name The name of the method as it should be seen by the control layer.
|
||||
/// @param returnType The value type returned to the control layer.
|
||||
/// @param args The argument list as it would appear on the function definition
|
||||
|
|
|
|||
|
|
@ -2834,13 +2834,16 @@ DefineEngineMethod( SimObject, getFieldValue, const char*, ( const char* fieldNa
|
|||
"@param index Optional parameter to specify the index of an array field separately.\n"
|
||||
"@return The value of the given field or \"\" if undefined." )
|
||||
{
|
||||
const U32 nameLen = dStrlen( fieldName );
|
||||
if (nameLen == 0)
|
||||
return "";
|
||||
|
||||
char fieldNameBuffer[ 1024 ];
|
||||
char arrayIndexBuffer[ 64 ];
|
||||
|
||||
// Parse out index if the field is given in the form of 'name[index]'.
|
||||
|
||||
const char* arrayIndex = NULL;
|
||||
const U32 nameLen = dStrlen( fieldName );
|
||||
if( fieldName[ nameLen - 1 ] == ']' )
|
||||
{
|
||||
const char* leftBracket = dStrchr( fieldName, '[' );
|
||||
|
|
|
|||
|
|
@ -398,10 +398,10 @@ void CloudLayer::_initTexture()
|
|||
}
|
||||
|
||||
if ( mTextureName.isNotEmpty() )
|
||||
mTexture.set( mTextureName, &GFXStaticTextureSRGBProfile, "CloudLayer" );
|
||||
mTexture.set( mTextureName, &GFXNormalMapProfile, "CloudLayer" );
|
||||
|
||||
if ( mTexture.isNull() )
|
||||
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "CloudLayer" );
|
||||
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXNormalMapProfile, "CloudLayer" );
|
||||
}
|
||||
|
||||
void CloudLayer::_initBuffers()
|
||||
|
|
@ -501,4 +501,4 @@ void CloudLayer::_initBuffers()
|
|||
}
|
||||
|
||||
mPB.unlock();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
#include "materials/materialDefinition.h"
|
||||
#include "T3D/prefab.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiMeshRoadEditorCtrl);
|
||||
|
||||
ConsoleDocClass( GuiMeshRoadEditorCtrl,
|
||||
|
|
@ -420,12 +422,14 @@ void GuiMeshRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
|
|||
|
||||
newRoad->registerObject();
|
||||
|
||||
// Add to MissionGroup
|
||||
SimGroup *missionGroup;
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
Con::errorf( "GuiMeshRoadEditorCtrl - could not find MissionGroup to add new MeshRoad" );
|
||||
// Add to scene
|
||||
Scene *scene;
|
||||
|
||||
scene = Scene::getRootScene();
|
||||
if ( !scene)
|
||||
Con::errorf( "GuiMeshRoadEditorCtrl - could not find Scene to add new MeshRoad" );
|
||||
else
|
||||
missionGroup->addObject( newRoad );
|
||||
scene->addObject( newRoad );
|
||||
|
||||
Point3F pos( endPnt );
|
||||
pos.z += mDefaultDepth * 0.5f;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "T3D/prefab.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiRiverEditorCtrl);
|
||||
|
||||
ConsoleDocClass( GuiRiverEditorCtrl,
|
||||
|
|
@ -444,12 +446,12 @@ void GuiRiverEditorCtrl::_process3DMouseDown( const Gui3DMouseEvent& event )
|
|||
return;
|
||||
}
|
||||
|
||||
// Add to MissionGroup
|
||||
SimGroup *missionGroup;
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
Con::errorf( "GuiRiverEditorCtrl - could not find MissionGroup to add new River" );
|
||||
// Add to Scene
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( !scene )
|
||||
Con::errorf( "GuiRiverEditorCtrl - could not find root Scene to add new River" );
|
||||
else
|
||||
missionGroup->addObject( newRiver );
|
||||
scene->addObject( newRiver );
|
||||
|
||||
Point3F pos( endPnt );
|
||||
pos.z += mDefaultDepth * 0.5f;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#include "gui/worldEditor/undoActions.h"
|
||||
#include "materials/materialDefinition.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiRoadEditorCtrl);
|
||||
|
||||
ConsoleDocClass( GuiRoadEditorCtrl,
|
||||
|
|
@ -407,12 +409,12 @@ void GuiRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
|
|||
|
||||
newRoad->registerObject();
|
||||
|
||||
// Add to MissionGroup
|
||||
SimGroup *missionGroup;
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
Con::errorf( "GuiDecalRoadEditorCtrl - could not find MissionGroup to add new DecalRoad" );
|
||||
// Add to scene
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( !scene )
|
||||
Con::errorf( "GuiDecalRoadEditorCtrl - could not find scene to add new DecalRoad" );
|
||||
else
|
||||
missionGroup->addObject( newRoad );
|
||||
scene->addObject( newRoad );
|
||||
|
||||
newRoad->insertNode( tPos, mDefaultWidth, 0 );
|
||||
U32 newNode = newRoad->insertNode( tPos, mDefaultWidth, 1 );
|
||||
|
|
@ -722,7 +724,7 @@ void GuiRoadEditorCtrl::renderScene(const RectI & updateRect)
|
|||
// Draw the spline based from the client-side road
|
||||
// because the serverside spline is not actually reliable...
|
||||
// Can be incorrect if the DecalRoad is before the TerrainBlock
|
||||
// in the MissionGroup.
|
||||
// in the scene.
|
||||
|
||||
if ( mHoverRoad && mHoverRoad != mSelRoad )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ void ForestCreateUndoAction::addItem( ForestItemData *data,
|
|||
// We store the datablock ID rather than the actual pointer
|
||||
// since the pointer could go bad.
|
||||
SimObjectId dataId = item.getData()->getId();
|
||||
mItems.last().setData( (ForestItemData*)dataId );
|
||||
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
|
||||
}
|
||||
|
||||
void ForestCreateUndoAction::redo()
|
||||
|
|
@ -110,7 +110,7 @@ void ForestDeleteUndoAction::removeItem( const ForestItem &item )
|
|||
SimObjectId dataId = item.getData()->getId();
|
||||
|
||||
mItems.push_back( item );
|
||||
mItems.last().setData( (ForestItemData*)dataId );
|
||||
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
|
||||
mData->removeItem( item.getKey(), item.getPosition() );
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ void ForestUpdateAction::saveItem( const ForestItem &item )
|
|||
// We store the datablock ID rather than the actual pointer
|
||||
// since the pointer could go bad.
|
||||
SimObjectId dataId = item.getData()->getId();
|
||||
mItems.last().setData( (ForestItemData*)dataId );
|
||||
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
|
||||
}
|
||||
|
||||
void ForestUpdateAction::_swapState()
|
||||
|
|
@ -215,7 +215,7 @@ void ForestUpdateAction::_swapState()
|
|||
item.getScale() );
|
||||
|
||||
// Save the state before this swap for the next swap.
|
||||
newItem.setData( (ForestItemData*)data->getId() );
|
||||
newItem.setData( (ForestItemData*)(uintptr_t)data->getId() );
|
||||
mItems.push_back( newItem );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode
|
|||
|
||||
if (mode.fullScreen)
|
||||
{
|
||||
d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
|
||||
d3dpp.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
d3dpp.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
}
|
||||
|
|
@ -1893,4 +1893,4 @@ void GFXD3D11Device::setDebugMarker(ColorI color, const char *name)
|
|||
|
||||
D3DPERF_SetMarker(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
|
||||
(LPCWSTR)&eventName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ _STRING_VALUE_LOOKUP_FXN(GFXStringBlendOp);
|
|||
|
||||
#define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
|
||||
for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
tablearray[i] = (type)GFX_UNINIT_VAL;
|
||||
tablearray[i] = (type)(uintptr_t)GFX_UNINIT_VAL;
|
||||
#define INIT_LOOKUPTABLE_EX( tablearray, enumprefix, type, typeTable ) \
|
||||
for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
|
||||
{\
|
||||
tablearray[i] = (type)GFX_UNINIT_VAL;\
|
||||
tablearray[i] = (type)(uintptr_t)GFX_UNINIT_VAL;\
|
||||
typeTable[i] = &defaultStringValueLookup;\
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ void GFXGLPrimitiveBuffer::finish()
|
|||
GLvoid* GFXGLPrimitiveBuffer::getBuffer()
|
||||
{
|
||||
// NULL specifies no offset into the hardware buffer
|
||||
return (GLvoid*)mBufferOffset;
|
||||
return (GLvoid*)(uintptr_t)mBufferOffset;
|
||||
}
|
||||
|
||||
void GFXGLPrimitiveBuffer::zombify()
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = true;
|
||||
glElement.type = GL_UNSIGNED_BYTE;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -196,7 +196,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_UNSIGNED_BYTE;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
glElement.pointerFirst = (void*)(uintptr_t)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
++texCoordIndex;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ GuiSwatchButtonCtrl::GuiSwatchButtonCtrl()
|
|||
void GuiSwatchButtonCtrl::initPersistFields()
|
||||
{
|
||||
addField("color", TypeColorF, Offset(mSwatchColor, GuiSwatchButtonCtrl), "The foreground color of GuiSwatchButtonCtrl");
|
||||
addField( "gridBitmap", TypeString, Offset( mGridBitmap, GuiSwatchButtonCtrl ), "The bitmap used for the transparent grid" );
|
||||
addField( "gridBitmap", TypeRealString, Offset( mGridBitmap, GuiSwatchButtonCtrl ), "The bitmap used for the transparent grid" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -613,3 +613,25 @@ void GuiSplitContainer::onMouseDragged( const GuiEvent &event )
|
|||
solvePanelConstraints(newDragPos, firstPanel, secondPanel, clientRect);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiSplitContainer::setSplitPoint(Point2I splitPoint)
|
||||
{
|
||||
GuiContainer *firstPanel = dynamic_cast<GuiContainer*>(at(0));
|
||||
GuiContainer *secondPanel = dynamic_cast<GuiContainer*>(at(1));
|
||||
|
||||
// This function will constrain the panels to their minExtents and update the mSplitPoint
|
||||
if (firstPanel && secondPanel)
|
||||
{
|
||||
RectI clientRect = getClientRect();
|
||||
|
||||
solvePanelConstraints(splitPoint, firstPanel, secondPanel, clientRect);
|
||||
|
||||
layoutControls(clientRect);
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiSplitContainer, setSplitPoint, void, (Point2I splitPoint), ,
|
||||
"Set the position of the split handle.")
|
||||
{
|
||||
object->setSplitPoint(splitPoint);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ public:
|
|||
virtual void solvePanelConstraints(Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, const RectI& clientRect);
|
||||
virtual Point2I getMinExtent() const;
|
||||
|
||||
//Set the positin of the split handler
|
||||
void setSplitPoint(Point2I splitPoint);
|
||||
|
||||
protected:
|
||||
|
||||
S32 mFixedPanel;
|
||||
|
|
|
|||
298
Engine/source/gui/controls/gui3DProjectionCtrl.cpp
Normal file
298
Engine/source/gui/controls/gui3DProjectionCtrl.cpp
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Gui3DProjectionCtrl
|
||||
// Doppelganger Inc
|
||||
// Orion Elenzil 200701
|
||||
//
|
||||
// This control is meant to be merely a container for other controls.
|
||||
// What's neat is that it's easy to 'attach' this control to a point in world-space
|
||||
// or, more interestingly, to an object such as a player.
|
||||
//
|
||||
// Usage:
|
||||
// * Create the Gui3DProjectionControl - by default it will be at 0, 0, 0.
|
||||
// * You can change where it's located by setting the field "offsetWorld".
|
||||
// - note you can specify that right in the .gui file
|
||||
// * You can attach it to any SceneObject by calling "setAttachedTo()".
|
||||
//
|
||||
// Behaviour:
|
||||
// * If you're attaching it to a player, by default it will center on the player's head.
|
||||
// * If you attach it to an object, by default it will delete itself if the object is deleted.
|
||||
// * Doesn't occlude w/r/t 3D objects.
|
||||
//
|
||||
// Console Methods:
|
||||
// * SetAttachedTo(SceneObject)
|
||||
// * GetAttachedTo()
|
||||
//
|
||||
// Params:
|
||||
// * pointWorld - read/write point in worldspace. read-only if attached to an object.
|
||||
// * offsetObject - an offset in objectspace. default 0, 0, 0.
|
||||
// * offsetWorld - an offset in worldspace. default 0, 0, 0.
|
||||
// * offsetScreen - an offset in screenspace. default 0, 0.
|
||||
// * hAlign - horizontal alignment. 0 = left, 1 = center, 2 = right. default center.
|
||||
// * vAlign - vertical alignment. 0 = top, 1 = center, 2 = bottomt. default center.
|
||||
// * useEyePoint - H & V usage of the eyePoint, if player object. default 0, 1. (ie - use only the vertical component)
|
||||
// * autoDelete - self-delete when attachedTo object is deleted. default true.
|
||||
//
|
||||
// Todo:
|
||||
// * occlusion - hide the control when its anchor point is occluded.
|
||||
// * integrate w/ zbuffer - this would actually be a change to the whole GuiControl system.
|
||||
// * allow attaching to arbitrary nodes in a skeleton.
|
||||
// * avoid projection when the object is out of the frustum.
|
||||
//
|
||||
// oxe 20070111
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "scene/sceneObject.h"
|
||||
#include "T3D/player.h"
|
||||
#include "gui/controls/gui3DProjectionCtrl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(Gui3DProjectionCtrl);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Gui3DProjectionCtrl::Gui3DProjectionCtrl()
|
||||
{
|
||||
mTSCtrl = NULL;
|
||||
mAttachedTo = NULL;
|
||||
mAttachedToPlayer = NULL;
|
||||
mAutoDelete = true;
|
||||
mHAlign = center;
|
||||
mVAlign = center;
|
||||
mUseEyePoint.x = 0;
|
||||
mUseEyePoint.y = 1;
|
||||
|
||||
mPtWorld .set(0, 0, 0);
|
||||
mPtProj .set(0, 0);
|
||||
mOffsetObject.set(0, 0, 0);
|
||||
mOffsetWorld .set(0, 0, 0);
|
||||
mOffsetScreen.set(0, 0);
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
addGroup("3DProjection");
|
||||
addField("pointWorld" , TypePoint3F , Offset(mPtWorld , Gui3DProjectionCtrl));
|
||||
addField("offsetObject" , TypePoint3F , Offset(mOffsetObject , Gui3DProjectionCtrl));
|
||||
addField("offsetWorld" , TypePoint3F , Offset(mOffsetWorld , Gui3DProjectionCtrl));
|
||||
addField("offsetScreen" , TypePoint2I , Offset(mOffsetScreen , Gui3DProjectionCtrl));
|
||||
addField("hAlign" , TypeS32 , Offset(mHAlign , Gui3DProjectionCtrl));
|
||||
addField("vAlign" , TypeS32 , Offset(mVAlign , Gui3DProjectionCtrl));
|
||||
addField("useEyePoint" , TypePoint2I , Offset(mUseEyePoint , Gui3DProjectionCtrl));
|
||||
addField("autoDelete" , TypeBool , Offset(mAutoDelete , Gui3DProjectionCtrl));
|
||||
endGroup("3DProjection");
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::onRender(Point2I offset, const RectI &updateRect)
|
||||
{
|
||||
doPositioning();
|
||||
doProjection();
|
||||
doAlignment();
|
||||
|
||||
Parent::onRender(offset, updateRect);
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::resizeDuringRender()
|
||||
{
|
||||
doPositioning();
|
||||
doProjection ();
|
||||
doAlignment ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Gui3DProjectionCtrl::onWake()
|
||||
{
|
||||
// walk up the GUI tree until we find a GuiTSCtrl.
|
||||
|
||||
mTSCtrl = NULL;
|
||||
GuiControl* walkCtrl = getParent();
|
||||
AssertFatal(walkCtrl != NULL, "Gui3DProjectionCtrl::onWake() - NULL parent");
|
||||
bool doMore = true;
|
||||
|
||||
while (doMore)
|
||||
{
|
||||
mTSCtrl = dynamic_cast<GuiTSCtrl*>(walkCtrl);
|
||||
walkCtrl = walkCtrl->getParent();
|
||||
doMore = (mTSCtrl == NULL) && (walkCtrl != NULL);
|
||||
}
|
||||
|
||||
if (!mTSCtrl)
|
||||
Con::errorf("Gui3DProjectionCtrl::onWake() - no TSCtrl parent");
|
||||
|
||||
return Parent::onWake();
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::onSleep()
|
||||
{
|
||||
mTSCtrl = NULL;
|
||||
return Parent::onSleep();
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::onDeleteNotify(SimObject* obj)
|
||||
{
|
||||
// - SimSet assumes that obj is a member of THIS, which in our case ain't true.
|
||||
// oxe 20070116 - the following doesn't compile on GCC.
|
||||
// SimSet::Parent::onDeleteNotify(obj);
|
||||
|
||||
if (!obj)
|
||||
{
|
||||
Con::warnf("Gui3DProjectionCtrl::onDeleteNotify - got NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj != mAttachedTo)
|
||||
{
|
||||
if (mAttachedTo != NULL)
|
||||
Con::warnf("Gui3DProjectionCtrl::onDeleteNotify - got unexpected object: %d vs. %d", obj->getId(), mAttachedTo->getId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAutoDelete)
|
||||
this->deleteObject();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Gui3DProjectionCtrl::doPositioning()
|
||||
{
|
||||
if (mAttachedTo == NULL)
|
||||
return;
|
||||
|
||||
Point3F ptBase; // the regular position of the object.
|
||||
Point3F ptEye; // the render position of the eye node, if a player object.
|
||||
Point3F pt; // combination of ptBase and ptEye.
|
||||
|
||||
MatrixF mat; // utility
|
||||
|
||||
mAttachedTo->getRenderTransform().getColumn(3, &ptBase);
|
||||
|
||||
if (mAttachedToPlayer != NULL)
|
||||
{
|
||||
mAttachedToPlayer->getRenderEyeTransform(&mat);
|
||||
mat.getColumn(3, &ptEye);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptEye = ptBase;
|
||||
}
|
||||
|
||||
// use some components from ptEye but other position from ptBase
|
||||
pt = ptBase;
|
||||
if (mUseEyePoint.x != 0)
|
||||
{
|
||||
pt.x = ptEye.x;
|
||||
pt.y = ptEye.y;
|
||||
}
|
||||
if (mUseEyePoint.y != 0)
|
||||
{
|
||||
pt.z = ptEye.z;
|
||||
}
|
||||
|
||||
// object-space offset
|
||||
Point3F offsetObj;
|
||||
QuatF quat(mAttachedTo->getRenderTransform());
|
||||
quat.mulP(mOffsetObject, &offsetObj);
|
||||
pt += offsetObj;
|
||||
|
||||
|
||||
// world-space offset
|
||||
pt += mOffsetWorld;
|
||||
|
||||
mPtWorld = pt;
|
||||
}
|
||||
|
||||
|
||||
void Gui3DProjectionCtrl::doProjection()
|
||||
{
|
||||
if (!mTSCtrl)
|
||||
return;
|
||||
|
||||
Point3F pt;
|
||||
|
||||
if (!mTSCtrl->project(mPtWorld, &pt))
|
||||
return;
|
||||
|
||||
mPtProj.x = (S32)(pt.x + 0.5f);
|
||||
mPtProj.y = (S32)(pt.y + 0.5f);
|
||||
}
|
||||
|
||||
void Gui3DProjectionCtrl::doAlignment()
|
||||
{
|
||||
// alignment
|
||||
Point2I offsetAlign;
|
||||
switch(mHAlign)
|
||||
{
|
||||
default:
|
||||
case center:
|
||||
offsetAlign.x = -getBounds().extent.x / 2;
|
||||
break;
|
||||
case min:
|
||||
offsetAlign.x = 0;
|
||||
break;
|
||||
case max:
|
||||
offsetAlign.x = -getBounds().extent.x;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(mVAlign)
|
||||
{
|
||||
default:
|
||||
case center:
|
||||
offsetAlign.y = -getBounds().extent.y / 2;
|
||||
break;
|
||||
case min:
|
||||
offsetAlign.y = 0;
|
||||
break;
|
||||
case max:
|
||||
offsetAlign.y = -getBounds().extent.y;
|
||||
break;
|
||||
}
|
||||
|
||||
// projected point
|
||||
mPtScreen = mPtProj;
|
||||
|
||||
// alignment offset
|
||||
mPtScreen += offsetAlign;
|
||||
|
||||
// screen offset
|
||||
mPtScreen += mOffsetScreen;
|
||||
|
||||
// setTrgPosition(mPtScreen);
|
||||
RectI bounds = getBounds();
|
||||
bounds.point = mPtScreen;
|
||||
setBounds(bounds);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Gui3DProjectionCtrl::setAttachedTo(SceneObject* obj)
|
||||
{
|
||||
if (obj == mAttachedTo)
|
||||
return;
|
||||
|
||||
if (mAttachedTo)
|
||||
clearNotify(mAttachedTo);
|
||||
|
||||
mAttachedTo = obj;
|
||||
mAttachedToPlayer = dynamic_cast<Player*>(obj);
|
||||
|
||||
if (mAttachedTo)
|
||||
deleteNotify(mAttachedTo);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Gui3DProjectionCtrl, setAttachedTo, void, (SceneObject* target), (nullAsType<SceneObject*>()), "(object)")
|
||||
{
|
||||
if(target)
|
||||
object->setAttachedTo(target);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Gui3DProjectionCtrl, getAttachedTo, S32, (),, "()")
|
||||
{
|
||||
SceneObject* obj = object->getAttachedTo();
|
||||
if (!obj)
|
||||
return 0;
|
||||
else
|
||||
return obj->getId();
|
||||
}
|
||||
77
Engine/source/gui/controls/gui3DProjectionCtrl.h
Normal file
77
Engine/source/gui/controls/gui3DProjectionCtrl.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Gui3DProjectionCtrl
|
||||
// Doppelganger Inc
|
||||
// Orion Elenzil 200701
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GUI3DPROJECTIONCTRL_H_
|
||||
#define _GUI3DPROJECTIONCTRL_H_
|
||||
|
||||
#include "gui/core/guiTypes.h"
|
||||
#include "gui/core/guiControl.h"
|
||||
#include "gui/3d/guiTSControl.h"
|
||||
#include "scene/sceneObject.h"
|
||||
#include "T3D/player.h"
|
||||
|
||||
class Gui3DProjectionCtrl : public GuiControl
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// stock stuff
|
||||
public:
|
||||
Gui3DProjectionCtrl();
|
||||
typedef GuiControl Parent;
|
||||
|
||||
DECLARE_CONOBJECT(Gui3DProjectionCtrl);
|
||||
|
||||
static void initPersistFields ();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// more interesting stuff
|
||||
|
||||
GuiTSCtrl* mTSCtrl; /// must be a child of one of these.
|
||||
SimObjectPtr<SceneObject> mAttachedTo; /// optional object we're attached to.
|
||||
SimObjectPtr<Player> mAttachedToPlayer; /// same pointer as mAttachedTo, but conveniently casted to player.
|
||||
|
||||
Point3F mPtWorld; /// the worldspace point which we're projecting
|
||||
Point2I mPtProj; /// the screenspace projected point. - note there are further modifiers before
|
||||
Point2I mPtScreen;
|
||||
|
||||
Point3F mOffsetObject; /// object-space offset applied first to the attached point to obtain mPtWorld.
|
||||
Point3F mOffsetWorld; /// world-space offset applied second to the attached point to obtain mPtWorld.
|
||||
Point2I mOffsetScreen; /// screen-space offset applied to mPtProj. note we still have centering, etc.
|
||||
|
||||
enum alignment
|
||||
{
|
||||
min = 0,
|
||||
center = 1,
|
||||
max = 2
|
||||
};
|
||||
|
||||
alignment mHAlign; /// horizontal alignment
|
||||
alignment mVAlign; /// horizontal alignment
|
||||
|
||||
bool mAutoDelete; /// optionally self-delete when mAttachedTo is deleted.
|
||||
Point2I mUseEyePoint; /// optionally use the eye point. x != 0 -> horiz. y != 0 -> vert.
|
||||
|
||||
|
||||
virtual void onRender (Point2I offset, const RectI &updateRect);
|
||||
virtual void resizeDuringRender ();
|
||||
|
||||
virtual bool onWake ();
|
||||
virtual void onSleep ();
|
||||
virtual void onDeleteNotify (SimObject *object);
|
||||
|
||||
void doPositioning ();
|
||||
void doProjection ();
|
||||
void doAlignment ();
|
||||
|
||||
void setAttachedTo (SceneObject* obj);
|
||||
SceneObject* getAttachedTo () { return mAttachedTo; }
|
||||
void setWorldPt (Point3F& pt) { mPtWorld = pt; }
|
||||
Point3F getWorldPt () { return mPtWorld; }
|
||||
};
|
||||
|
||||
#endif //_GUI3DPROJECTIONCTRL_H_
|
||||
|
|
@ -89,9 +89,6 @@ bool GuiConsole::onWake()
|
|||
S32 GuiConsole::getMaxWidth(S32 startIndex, S32 endIndex)
|
||||
{
|
||||
//sanity check
|
||||
U32 size;
|
||||
ConsoleLogEntry *log;
|
||||
|
||||
if (startIndex < 0 || (U32)endIndex >= mFilteredLog.size() || startIndex > endIndex)
|
||||
return 0;
|
||||
|
||||
|
|
@ -190,9 +187,6 @@ void GuiConsole::onPreRender()
|
|||
|
||||
void GuiConsole::onRenderCell(Point2I offset, Point2I cell, bool /*selected*/, bool /*mouseOver*/)
|
||||
{
|
||||
U32 size;
|
||||
ConsoleLogEntry *log;
|
||||
|
||||
ConsoleLogEntry &entry = mFilteredLog[cell.y];
|
||||
switch (entry.mLevel)
|
||||
{
|
||||
|
|
@ -210,9 +204,6 @@ void GuiConsole::onCellSelected( Point2I cell )
|
|||
{
|
||||
Parent::onCellSelected( cell );
|
||||
|
||||
U32 size;
|
||||
ConsoleLogEntry* log;
|
||||
|
||||
ConsoleLogEntry& entry = mFilteredLog[cell.y];
|
||||
onMessageSelected_callback( entry.mLevel, entry.mString );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -631,7 +631,7 @@ DefineEngineMethod( GuiListBoxCtrl, addItem, S32, (const char* newItem, const ch
|
|||
else if(elementCount == 1)
|
||||
{
|
||||
U32 objId = dAtoi( color );
|
||||
return object->addItem( newItem, (void*)objId );
|
||||
return object->addItem( newItem, (void*)(uintptr_t)objId );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1523,7 +1523,7 @@ void GuiListBoxCtrl::_mirror()
|
|||
|
||||
if ( !found )
|
||||
{
|
||||
addItem( _makeMirrorItemName( curObj ), (void*)curId );
|
||||
addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1241,6 +1241,9 @@ void GuiTextEditCtrl::onLoseFirstResponder()
|
|||
root->disableKeyboardTranslation();
|
||||
}
|
||||
|
||||
updateHistory(&mTextBuffer, true);
|
||||
mHistoryDirty = false;
|
||||
|
||||
//execute the validate command
|
||||
if( mValidateCommand.isNotEmpty() )
|
||||
evaluate( mValidateCommand );
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gfx/primBuilder.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "gui/editor/guiPopupMenuCtrl.h"
|
||||
|
||||
// menu bar:
|
||||
// basic idea - fixed height control bar at the top of a window, placed and sized in gui editor
|
||||
|
|
@ -1113,6 +1114,13 @@ GuiMenuBar::GuiMenuBar()
|
|||
|
||||
void GuiMenuBar::onRemove()
|
||||
{
|
||||
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
|
||||
if (Sim::findObject("PopUpMenuControl", backgroundCtrl))
|
||||
{
|
||||
if (backgroundCtrl->mMenuBarCtrl == this)
|
||||
backgroundCtrl->mMenuBarCtrl = nullptr;
|
||||
}
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
|
|
@ -1472,11 +1480,11 @@ PopupMenu* GuiMenuBar::getMenu(U32 index)
|
|||
return mMenuList[index].popupMenu;
|
||||
}
|
||||
|
||||
PopupMenu* GuiMenuBar::findMenu(StringTableEntry barTitle)
|
||||
PopupMenu* GuiMenuBar::findMenu(String barTitle)
|
||||
{
|
||||
for (U32 i = 0; i < mMenuList.size(); i++)
|
||||
{
|
||||
if (mMenuList[i].text == barTitle)
|
||||
if (String::ToLower(mMenuList[i].text) == String::ToLower(barTitle))
|
||||
return mMenuList[i].popupMenu;
|
||||
}
|
||||
|
||||
|
|
@ -1521,8 +1529,7 @@ DefineEngineMethod(GuiMenuBar, insert, void, (SimObject* pObject, S32 pos), (nul
|
|||
|
||||
DefineEngineMethod(GuiMenuBar, findMenu, S32, (const char* barTitle), (""), "(barTitle)")
|
||||
{
|
||||
StringTableEntry barTitleStr = StringTable->insert(barTitle);
|
||||
PopupMenu* menu = object->findMenu(barTitleStr);
|
||||
PopupMenu* menu = object->findMenu(barTitle);
|
||||
|
||||
if (menu)
|
||||
return menu->getId();
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public:
|
|||
U32 getMenuListCount() { return mMenuList.size(); }
|
||||
|
||||
PopupMenu* getMenu(U32 index);
|
||||
PopupMenu* findMenu(StringTableEntry barTitle);
|
||||
PopupMenu* findMenu(String barTitle);
|
||||
|
||||
DECLARE_CONOBJECT(GuiMenuBar);
|
||||
DECLARE_CALLBACK( void, onMouseInMenu, ( bool hasLeftMenu ));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ GuiInspectorField::GuiInspectorField( GuiInspector* inspector,
|
|||
mField( field ),
|
||||
mFieldArrayIndex( NULL ),
|
||||
mEdit( NULL ),
|
||||
mTargetObject(NULL)
|
||||
mTargetObject(NULL),
|
||||
mUseHeightOverride(false),
|
||||
mHeightOverride(18)
|
||||
{
|
||||
if( field != NULL )
|
||||
mCaption = field->pFieldname;
|
||||
|
|
@ -77,7 +79,9 @@ GuiInspectorField::GuiInspectorField()
|
|||
mTargetObject(NULL),
|
||||
mVariableName(StringTable->EmptyString()),
|
||||
mCallbackName(StringTable->EmptyString()),
|
||||
mSpecialEditField(false)
|
||||
mSpecialEditField(false),
|
||||
mUseHeightOverride(false),
|
||||
mHeightOverride(18)
|
||||
{
|
||||
setCanSave( false );
|
||||
}
|
||||
|
|
@ -112,7 +116,12 @@ bool GuiInspectorField::onAdd()
|
|||
if ( mEdit == NULL )
|
||||
return false;
|
||||
|
||||
setBounds(0,0,100,18);
|
||||
S32 fieldHeight = 18;
|
||||
|
||||
if (mUseHeightOverride)
|
||||
fieldHeight = mHeightOverride;
|
||||
|
||||
setBounds(0,0,100, fieldHeight);
|
||||
|
||||
// Add our edit as a child
|
||||
addObject( mEdit );
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ class GuiInspectorField : public GuiControl
|
|||
///
|
||||
bool mHighlighted;
|
||||
|
||||
//These are so we can special-case our height for additional room on certain field-types
|
||||
bool mUseHeightOverride;
|
||||
U32 mHeightOverride;
|
||||
|
||||
//An override that lets us bypass inspector-dependent logic for setting/getting variables/fields
|
||||
bool mSpecialEditField;
|
||||
//An override to make sure this field is associated to an object that isn't expressly
|
||||
|
|
|
|||
|
|
@ -133,9 +133,6 @@ bool GuiInspectorMountingGroup::inspectGroup()
|
|||
clearFields();
|
||||
|
||||
bool bNewItems = false;
|
||||
bool bMakingArray = false;
|
||||
GuiStackControl *pArrayStack = NULL;
|
||||
GuiRolloutCtrl *pArrayRollout = NULL;
|
||||
bool bGrabItems = false;
|
||||
|
||||
AbstractClassRep* commonAncestorClass = findCommonAncestorClass();
|
||||
|
|
@ -240,7 +237,6 @@ void GuiInspectorMountingGroup::updateAllFields()
|
|||
void GuiInspectorMountingGroup::onMouseMove(const GuiEvent &event)
|
||||
{
|
||||
//mParent->mOverDivider = false;
|
||||
bool test = false;
|
||||
}
|
||||
|
||||
DefineEngineMethod(GuiInspectorMountingGroup, inspectGroup, bool, (),, "Refreshes the dynamic fields in the inspector.")
|
||||
|
|
|
|||
|
|
@ -282,156 +282,159 @@ void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */)
|
|||
if (owner == NULL)
|
||||
return;
|
||||
|
||||
GuiControl* editorGui;
|
||||
Sim::findObject("EditorGui", editorGui);
|
||||
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
|
||||
Sim::findObject("PopUpMenuControl", backgroundCtrl);
|
||||
|
||||
if (editorGui)
|
||||
GuiControlProfile* profile;
|
||||
Sim::findObject("GuiMenubarProfile", profile);
|
||||
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
if (mTextList == nullptr)
|
||||
{
|
||||
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
|
||||
Sim::findObject("PopUpMenuControl", backgroundCtrl);
|
||||
mTextList = new GuiPopupMenuTextListCtrl();
|
||||
mTextList->registerObject();
|
||||
mTextList->setControlProfile(profile);
|
||||
|
||||
GuiControlProfile* profile;
|
||||
Sim::findObject("GuiMenubarProfile", profile);
|
||||
|
||||
if (!profile)
|
||||
return;
|
||||
|
||||
if (mTextList == nullptr)
|
||||
{
|
||||
mTextList = new GuiPopupMenuTextListCtrl();
|
||||
mTextList->registerObject();
|
||||
mTextList->setControlProfile(profile);
|
||||
|
||||
mTextList->mPopup = this;
|
||||
mTextList->mMenuBar = getMenuBarCtrl();
|
||||
}
|
||||
|
||||
if (!backgroundCtrl)
|
||||
{
|
||||
backgroundCtrl = new GuiPopupMenuBackgroundCtrl();
|
||||
|
||||
backgroundCtrl->registerObject("PopUpMenuControl");
|
||||
}
|
||||
|
||||
if (!backgroundCtrl || !mTextList)
|
||||
return;
|
||||
|
||||
if (!mIsSubmenu)
|
||||
{
|
||||
//if we're a 'parent' menu, then tell the background to clear out all existing other popups
|
||||
|
||||
backgroundCtrl->clearPopups();
|
||||
}
|
||||
|
||||
//find out if we're doing a first-time add
|
||||
S32 popupIndex = backgroundCtrl->findPopupMenu(this);
|
||||
|
||||
if (popupIndex == -1)
|
||||
{
|
||||
backgroundCtrl->addObject(mTextList);
|
||||
backgroundCtrl->mPopups.push_back(this);
|
||||
}
|
||||
|
||||
mTextList->mBackground = backgroundCtrl;
|
||||
|
||||
owner->pushDialogControl(backgroundCtrl, 10);
|
||||
|
||||
//Set the background control's menubar, if any, and if it's not already set
|
||||
if(backgroundCtrl->mMenuBarCtrl == nullptr)
|
||||
backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl();
|
||||
|
||||
backgroundCtrl->setExtent(editorGui->getExtent());
|
||||
|
||||
mTextList->clear();
|
||||
|
||||
S32 textWidth = 0, width = 0;
|
||||
S32 acceleratorWidth = 0;
|
||||
GFont *font = profile->mFont;
|
||||
|
||||
Point2I maxBitmapSize = Point2I(0, 0);
|
||||
|
||||
S32 numBitmaps = profile->mBitmapArrayRects.size();
|
||||
if (numBitmaps)
|
||||
{
|
||||
RectI *bitmapBounds = profile->mBitmapArrayRects.address();
|
||||
for (S32 i = 0; i < numBitmaps; i++)
|
||||
{
|
||||
if (bitmapBounds[i].extent.x > maxBitmapSize.x)
|
||||
maxBitmapSize.x = bitmapBounds[i].extent.x;
|
||||
if (bitmapBounds[i].extent.y > maxBitmapSize.y)
|
||||
maxBitmapSize.y = bitmapBounds[i].extent.y;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < mMenuItems.size(); i++)
|
||||
{
|
||||
if (!mMenuItems[i].mVisible)
|
||||
continue;
|
||||
|
||||
S32 iTextWidth = font->getStrWidth(mMenuItems[i].mText.c_str());
|
||||
S32 iAcceleratorWidth = mMenuItems[i].mAccelerator ? font->getStrWidth(mMenuItems[i].mAccelerator) : 0;
|
||||
|
||||
if (iTextWidth > textWidth)
|
||||
textWidth = iTextWidth;
|
||||
if (iAcceleratorWidth > acceleratorWidth)
|
||||
acceleratorWidth = iAcceleratorWidth;
|
||||
}
|
||||
|
||||
width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4;
|
||||
|
||||
mTextList->setCellSize(Point2I(width, font->getHeight() + 2));
|
||||
mTextList->clearColumnOffsets();
|
||||
mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index.
|
||||
mTextList->addColumnOffset(maxBitmapSize.x + 1);
|
||||
mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4);
|
||||
|
||||
U32 entryCount = 0;
|
||||
|
||||
for (U32 i = 0; i < mMenuItems.size(); i++)
|
||||
{
|
||||
if (!mMenuItems[i].mVisible)
|
||||
continue;
|
||||
|
||||
char buf[512];
|
||||
|
||||
// If this menu item is a submenu, then set the isSubmenu to 2 to indicate
|
||||
// an arrow should be drawn. Otherwise set the isSubmenu normally.
|
||||
char isSubmenu = 1;
|
||||
if (mMenuItems[i].mIsSubmenu)
|
||||
isSubmenu = 2;
|
||||
|
||||
char bitmapIndex = 1;
|
||||
if (mMenuItems[i].mBitmapIndex >= 0 && (mMenuItems[i].mBitmapIndex * 3 <= profile->mBitmapArrayRects.size()))
|
||||
bitmapIndex = mMenuItems[i].mBitmapIndex + 2;
|
||||
|
||||
dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].mText.c_str(), mMenuItems[i].mAccelerator ? mMenuItems[i].mAccelerator : "");
|
||||
mTextList->addEntry(entryCount, buf);
|
||||
|
||||
if (!mMenuItems[i].mEnabled)
|
||||
mTextList->setEntryActive(entryCount, false);
|
||||
|
||||
entryCount++;
|
||||
}
|
||||
|
||||
Point2I pos = Point2I::Zero;
|
||||
|
||||
if (x == -1 && y == -1)
|
||||
pos = owner->getCursorPos();
|
||||
else
|
||||
pos = Point2I(x, y);
|
||||
|
||||
mTextList->setPosition(pos);
|
||||
|
||||
//nudge in if we'd overshoot the screen
|
||||
S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth();
|
||||
if (widthDiff > 0)
|
||||
{
|
||||
Point2I popupPos = mTextList->getPosition();
|
||||
mTextList->setPosition(popupPos.x - widthDiff, popupPos.y);
|
||||
}
|
||||
|
||||
mTextList->setHidden(false);
|
||||
mTextList->mPopup = this;
|
||||
mTextList->mMenuBar = getMenuBarCtrl();
|
||||
}
|
||||
|
||||
if (!backgroundCtrl)
|
||||
{
|
||||
backgroundCtrl = new GuiPopupMenuBackgroundCtrl();
|
||||
|
||||
backgroundCtrl->registerObject("PopUpMenuControl");
|
||||
}
|
||||
|
||||
if (!backgroundCtrl || !mTextList)
|
||||
return;
|
||||
|
||||
if (!mIsSubmenu)
|
||||
{
|
||||
//if we're a 'parent' menu, then tell the background to clear out all existing other popups
|
||||
|
||||
backgroundCtrl->clearPopups();
|
||||
}
|
||||
|
||||
//find out if we're doing a first-time add
|
||||
S32 popupIndex = backgroundCtrl->findPopupMenu(this);
|
||||
|
||||
if (popupIndex == -1)
|
||||
{
|
||||
backgroundCtrl->addObject(mTextList);
|
||||
backgroundCtrl->mPopups.push_back(this);
|
||||
}
|
||||
|
||||
mTextList->mBackground = backgroundCtrl;
|
||||
|
||||
owner->pushDialogControl(backgroundCtrl, 10);
|
||||
|
||||
//Set the background control's menubar, if any, and if it's not already set
|
||||
if(backgroundCtrl->mMenuBarCtrl == nullptr)
|
||||
backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl();
|
||||
|
||||
backgroundCtrl->setExtent(owner->getExtent());
|
||||
|
||||
mTextList->clear();
|
||||
|
||||
S32 textWidth = 0, width = 0;
|
||||
S32 acceleratorWidth = 0;
|
||||
GFont *font = profile->mFont;
|
||||
|
||||
Point2I maxBitmapSize = Point2I(0, 0);
|
||||
|
||||
S32 numBitmaps = profile->mBitmapArrayRects.size();
|
||||
if (numBitmaps)
|
||||
{
|
||||
RectI *bitmapBounds = profile->mBitmapArrayRects.address();
|
||||
for (S32 i = 0; i < numBitmaps; i++)
|
||||
{
|
||||
if (bitmapBounds[i].extent.x > maxBitmapSize.x)
|
||||
maxBitmapSize.x = bitmapBounds[i].extent.x;
|
||||
if (bitmapBounds[i].extent.y > maxBitmapSize.y)
|
||||
maxBitmapSize.y = bitmapBounds[i].extent.y;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < mMenuItems.size(); i++)
|
||||
{
|
||||
if (!mMenuItems[i].mVisible)
|
||||
continue;
|
||||
|
||||
S32 iTextWidth = font->getStrWidth(mMenuItems[i].mText.c_str());
|
||||
S32 iAcceleratorWidth = mMenuItems[i].mAccelerator ? font->getStrWidth(mMenuItems[i].mAccelerator) : 0;
|
||||
|
||||
if (iTextWidth > textWidth)
|
||||
textWidth = iTextWidth;
|
||||
if (iAcceleratorWidth > acceleratorWidth)
|
||||
acceleratorWidth = iAcceleratorWidth;
|
||||
}
|
||||
|
||||
width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4;
|
||||
|
||||
mTextList->setCellSize(Point2I(width, font->getHeight() + 2));
|
||||
mTextList->clearColumnOffsets();
|
||||
mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index.
|
||||
mTextList->addColumnOffset(maxBitmapSize.x + 1);
|
||||
mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4);
|
||||
|
||||
U32 entryCount = 0;
|
||||
|
||||
for (U32 i = 0; i < mMenuItems.size(); i++)
|
||||
{
|
||||
if (!mMenuItems[i].mVisible)
|
||||
continue;
|
||||
|
||||
char buf[512];
|
||||
|
||||
// If this menu item is a submenu, then set the isSubmenu to 2 to indicate
|
||||
// an arrow should be drawn. Otherwise set the isSubmenu normally.
|
||||
char isSubmenu = 1;
|
||||
if (mMenuItems[i].mIsSubmenu)
|
||||
isSubmenu = 2;
|
||||
|
||||
char bitmapIndex = 1;
|
||||
if (mMenuItems[i].mBitmapIndex >= 0 && (mMenuItems[i].mBitmapIndex * 3 <= profile->mBitmapArrayRects.size()))
|
||||
bitmapIndex = mMenuItems[i].mBitmapIndex + 2;
|
||||
|
||||
dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].mText.c_str(), mMenuItems[i].mAccelerator ? mMenuItems[i].mAccelerator : "");
|
||||
mTextList->addEntry(entryCount, buf);
|
||||
|
||||
if (!mMenuItems[i].mEnabled)
|
||||
mTextList->setEntryActive(entryCount, false);
|
||||
|
||||
entryCount++;
|
||||
}
|
||||
|
||||
Point2I pos = Point2I::Zero;
|
||||
|
||||
if (x == -1 && y == -1)
|
||||
pos = owner->getCursorPos();
|
||||
else
|
||||
pos = Point2I(x, y);
|
||||
|
||||
mTextList->setPosition(pos);
|
||||
|
||||
//nudge in if we'd overshoot the screen
|
||||
S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth();
|
||||
if (widthDiff > 0)
|
||||
{
|
||||
Point2I popupPos = mTextList->getPosition();
|
||||
mTextList->setPosition(popupPos.x - widthDiff, popupPos.y);
|
||||
}
|
||||
|
||||
//If we'd overshoot the screen vertically, just mirror the axis so we're above the mouse
|
||||
S32 heightDiff = (mTextList->getPosition().y + mTextList->getExtent().y) - backgroundCtrl->getHeight();
|
||||
if (heightDiff > 0)
|
||||
{
|
||||
Point2I popupPos = mTextList->getPosition();
|
||||
mTextList->setPosition(popupPos.x, popupPos.y - mTextList->getExtent().y);
|
||||
}
|
||||
|
||||
|
||||
mTextList->setHidden(false);
|
||||
}
|
||||
|
||||
void PopupMenu::hidePopup()
|
||||
|
|
|
|||
|
|
@ -58,9 +58,25 @@ ConsoleDocClass( GuiInputCtrl,
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
GuiInputCtrl::GuiInputCtrl()
|
||||
: mSendAxisEvents(false),
|
||||
mSendBreakEvents(false),
|
||||
mSendModifierEvents(false)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void GuiInputCtrl::initPersistFields()
|
||||
{
|
||||
|
||||
addGroup("GuiInputCtrl");
|
||||
addField("sendAxisEvents", TypeBool, Offset(mSendAxisEvents, GuiInputCtrl),
|
||||
"If true, onAxisEvent callbacks will be sent for SI_AXIS Move events (Default false).");
|
||||
addField("sendBreakEvents", TypeBool, Offset(mSendBreakEvents, GuiInputCtrl),
|
||||
"If true, break events for all devices will generate callbacks (Default false).");
|
||||
addField("sendModifierEvents", TypeBool, Offset(mSendModifierEvents, GuiInputCtrl),
|
||||
"If true, Make events will be sent for modifier keys (Default false).");
|
||||
endGroup("GuiInputCtrl");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
|
@ -110,6 +126,8 @@ static bool isModifierKey( U16 keyCode )
|
|||
case KEY_RALT:
|
||||
case KEY_LSHIFT:
|
||||
case KEY_RSHIFT:
|
||||
case KEY_MAC_LOPT:
|
||||
case KEY_MAC_ROPT:
|
||||
return( true );
|
||||
}
|
||||
|
||||
|
|
@ -117,33 +135,49 @@ static bool isModifierKey( U16 keyCode )
|
|||
}
|
||||
|
||||
IMPLEMENT_CALLBACK( GuiInputCtrl, onInputEvent, void, (const char* device, const char* action, bool state ),
|
||||
( device, action, state),
|
||||
"@brief Callback that occurs when an input is triggered on this control\n\n"
|
||||
"@param device The device type triggering the input, such as keyboard, mouse, etc\n"
|
||||
"@param action The actual event occuring, such as a key or button\n"
|
||||
"@param state True if the action is being pressed, false if it is being release\n\n"
|
||||
);
|
||||
( device, action, state),
|
||||
"@brief Callback that occurs when an input is triggered on this control\n\n"
|
||||
"@param device The device type triggering the input, such as keyboard, mouse, etc\n"
|
||||
"@param action The actual event occuring, such as a key or button\n"
|
||||
"@param state True if the action is being pressed, false if it is being release\n\n");
|
||||
|
||||
IMPLEMENT_CALLBACK(GuiInputCtrl, onAxisEvent, void, (const char* device, const char* action, F32 axisValue),
|
||||
(device, action, axisValue),
|
||||
"@brief Callback that occurs when an axis event is triggered on this control\n\n"
|
||||
"@param device The device type triggering the input, such as mouse, joystick, gamepad, etc\n"
|
||||
"@param action The ActionMap code for the axis\n"
|
||||
"@param axisValue The current value of the axis\n\n");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool GuiInputCtrl::onInputEvent( const InputEventInfo &event )
|
||||
{
|
||||
// TODO - add POV support...
|
||||
char deviceString[32];
|
||||
if ( event.action == SI_MAKE )
|
||||
{
|
||||
if ( event.objType == SI_BUTTON
|
||||
|| event.objType == SI_POV
|
||||
|| ( ( event.objType == SI_KEY ) && !isModifierKey( event.objInst ) ) )
|
||||
|| event.objType == SI_KEY )
|
||||
{
|
||||
char deviceString[32];
|
||||
if ( !ActionMap::getDeviceName( event.deviceType, event.deviceInst, deviceString ) )
|
||||
return( false );
|
||||
return false;
|
||||
|
||||
const char* actionString = ActionMap::buildActionString( &event );
|
||||
if ((event.objType == SI_KEY) && isModifierKey(event.objInst))
|
||||
{
|
||||
if (!mSendModifierEvents)
|
||||
return false;
|
||||
|
||||
//Con::executef( this, "onInputEvent", deviceString, actionString, "1" );
|
||||
onInputEvent_callback(deviceString, actionString, 1);
|
||||
char keyString[32];
|
||||
if (!ActionMap::getKeyString(event.objInst, keyString))
|
||||
return false;
|
||||
|
||||
return( true );
|
||||
onInputEvent_callback(deviceString, keyString, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* actionString = ActionMap::buildActionString(&event);
|
||||
onInputEvent_callback(deviceString, actionString, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ( event.action == SI_BREAK )
|
||||
|
|
@ -152,14 +186,36 @@ bool GuiInputCtrl::onInputEvent( const InputEventInfo &event )
|
|||
{
|
||||
char keyString[32];
|
||||
if ( !ActionMap::getKeyString( event.objInst, keyString ) )
|
||||
return( false );
|
||||
return false;
|
||||
|
||||
//Con::executef( this, "onInputEvent", "keyboard", keyString, "0" );
|
||||
onInputEvent_callback("keyboard", keyString, 0);
|
||||
onInputEvent_callback("keyboard", keyString, 0);
|
||||
return true;
|
||||
}
|
||||
else if (mSendBreakEvents)
|
||||
{
|
||||
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
|
||||
return false;
|
||||
|
||||
return( true );
|
||||
const char* actionString = ActionMap::buildActionString(&event);
|
||||
|
||||
onInputEvent_callback(deviceString, actionString, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mSendAxisEvents && ((event.objType == SI_AXIS) || (event.objType == SI_INT) || (event.objType == SI_FLOAT)))
|
||||
{
|
||||
F32 fValue = event.fValue;
|
||||
if (event.objType == SI_INT)
|
||||
fValue = (F32)event.iValue;
|
||||
|
||||
return( false );
|
||||
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
|
||||
return false;
|
||||
|
||||
const char* actionString = ActionMap::buildActionString(&event);
|
||||
|
||||
onAxisEvent_callback(deviceString, actionString, fValue);
|
||||
return (event.deviceType != MouseDeviceType); // Don't consume mouse move events
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,23 +32,31 @@
|
|||
/// to script. This is useful for implementing custom keyboard handling code.
|
||||
class GuiInputCtrl : public GuiMouseEventCtrl
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
bool mSendAxisEvents;
|
||||
bool mSendBreakEvents;
|
||||
bool mSendModifierEvents;
|
||||
|
||||
typedef GuiMouseEventCtrl Parent;
|
||||
|
||||
// GuiControl.
|
||||
virtual bool onWake();
|
||||
virtual void onSleep();
|
||||
public:
|
||||
|
||||
virtual bool onInputEvent( const InputEventInfo &event );
|
||||
|
||||
static void initPersistFields();
|
||||
typedef GuiMouseEventCtrl Parent;
|
||||
|
||||
DECLARE_CONOBJECT(GuiInputCtrl);
|
||||
DECLARE_CATEGORY( "Gui Other Script" );
|
||||
DECLARE_DESCRIPTION( "A control that locks the mouse and reports all keyboard input events to script." );
|
||||
GuiInputCtrl();
|
||||
|
||||
DECLARE_CALLBACK( void, onInputEvent, ( const char* device, const char* action, bool state ));
|
||||
// GuiControl.
|
||||
virtual bool onWake();
|
||||
virtual void onSleep();
|
||||
|
||||
virtual bool onInputEvent( const InputEventInfo &event );
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(GuiInputCtrl);
|
||||
DECLARE_CATEGORY( "Gui Other Script" );
|
||||
DECLARE_DESCRIPTION( "A control that locks the mouse and reports all input events to script." );
|
||||
|
||||
DECLARE_CALLBACK( void, onInputEvent, ( const char* device, const char* action, bool state ));
|
||||
DECLARE_CALLBACK(void, onAxisEvent, (const char* device, const char* action, F32 axisValue));
|
||||
};
|
||||
|
||||
#endif // _GUI_INPUTCTRL_H
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "scene/sceneRenderState.h"
|
||||
#include "renderInstance/renderBinManager.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(EditTSCtrl);
|
||||
ConsoleDocClass( EditTSCtrl,
|
||||
|
|
@ -795,15 +796,15 @@ void EditTSCtrl::_renderScene( ObjectRenderInst*, SceneRenderState *state, BaseM
|
|||
GFXTransformSaver saver;
|
||||
|
||||
// render through console callbacks
|
||||
SimSet * missionGroup = static_cast<SimSet*>(Sim::findObject("MissionGroup"));
|
||||
if(missionGroup)
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if(scene)
|
||||
{
|
||||
mConsoleRendering = true;
|
||||
|
||||
// [ rene, 27-Jan-10 ] This calls onEditorRender on the server objects instead
|
||||
// of on the client objects which seems a bit questionable to me.
|
||||
|
||||
for(SimSetIterator itr(missionGroup); *itr; ++itr)
|
||||
for(SimSetIterator itr(scene); *itr; ++itr)
|
||||
{
|
||||
SceneObject* object = dynamic_cast< SceneObject* >( *itr );
|
||||
if( object && object->isRenderEnabled() && !object->isHidden() )
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include "T3D/portal.h"
|
||||
#include "math/mPolyhedron.impl.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT( GuiConvexEditorCtrl );
|
||||
|
||||
ConsoleDocClass( GuiConvexEditorCtrl,
|
||||
|
|
@ -121,12 +123,12 @@ bool GuiConvexEditorCtrl::onWake()
|
|||
if ( !Parent::onWake() )
|
||||
return false;
|
||||
|
||||
SimGroup *missionGroup;
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( !scene )
|
||||
return true;
|
||||
|
||||
SimGroup::iterator itr = missionGroup->begin();
|
||||
for ( ; itr != missionGroup->end(); itr++ )
|
||||
SimGroup::iterator itr = scene->begin();
|
||||
for ( ; itr != scene->end(); itr++ )
|
||||
{
|
||||
if ( dStrcmp( (*itr)->getClassName(), "ConvexShape" ) == 0 )
|
||||
{
|
||||
|
|
@ -166,8 +168,8 @@ void GuiConvexEditorCtrl::setVisible( bool val )
|
|||
mSavedGizmoFlags = -1;
|
||||
}
|
||||
|
||||
SimGroup* misGroup;
|
||||
if (Sim::findObject("MissionGroup", misGroup))
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if (scene != nullptr)
|
||||
{
|
||||
//Make our proxy objects "real" again
|
||||
for (U32 i = 0; i < mProxyObjects.size(); ++i)
|
||||
|
|
@ -178,13 +180,13 @@ void GuiConvexEditorCtrl::setVisible( bool val )
|
|||
AbstractClassRep* classRep = AbstractClassRep::findClassRep(mProxyObjects[i].targetObjectClass);
|
||||
if (!classRep)
|
||||
{
|
||||
Con::errorf("WorldEditor::createPolyhedralObject - No such class: %s", mProxyObjects[i].targetObjectClass);
|
||||
Con::errorf("WorldEditor::createPolyhedralObject - No such class: %s", mProxyObjects[i].targetObjectClass.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneObject* polyObj = createPolyhedralObject(mProxyObjects[i].targetObjectClass.c_str(), mProxyObjects[i].shapeProxy);
|
||||
|
||||
misGroup->addObject(polyObj);
|
||||
scene->addObject(polyObj);
|
||||
|
||||
//Now, remove the convex proxy
|
||||
mProxyObjects[i].shapeProxy->deleteObject();
|
||||
|
|
@ -222,19 +224,19 @@ void GuiConvexEditorCtrl::setVisible( bool val )
|
|||
updateGizmoPos();
|
||||
mSavedGizmoFlags = mGizmoProfile->flags;
|
||||
|
||||
SimGroup* misGroup;
|
||||
if (Sim::findObject("MissionGroup", misGroup))
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if (scene != nullptr)
|
||||
{
|
||||
for (U32 c = 0; c < misGroup->size(); ++c)
|
||||
for (U32 c = 0; c < scene->size(); ++c)
|
||||
{
|
||||
bool isTrigger = (misGroup->at(c)->getClassName() == StringTable->insert("Trigger"));
|
||||
bool isZone = (misGroup->at(c)->getClassName() == StringTable->insert("Zone"));
|
||||
bool isPortal = (misGroup->at(c)->getClassName() == StringTable->insert("Portal"));
|
||||
bool isOccluder = (misGroup->at(c)->getClassName() == StringTable->insert("OcclusionVolume"));
|
||||
bool isTrigger = (scene->at(c)->getClassName() == StringTable->insert("Trigger"));
|
||||
bool isZone = (scene->at(c)->getClassName() == StringTable->insert("Zone"));
|
||||
bool isPortal = (scene->at(c)->getClassName() == StringTable->insert("Portal"));
|
||||
bool isOccluder = (scene->at(c)->getClassName() == StringTable->insert("OcclusionVolume"));
|
||||
|
||||
if (isZone || isPortal || isOccluder)
|
||||
{
|
||||
SceneObject* sceneObj = static_cast<SceneObject*>(misGroup->at(c));
|
||||
SceneObject* sceneObj = static_cast<SceneObject*>(scene->at(c));
|
||||
if (!sceneObj)
|
||||
{
|
||||
Con::errorf("WorldEditor::createConvexShapeFrom - Invalid object");
|
||||
|
|
@ -1350,9 +1352,9 @@ void GuiConvexEditorCtrl::setupShape( ConvexShape *shape )
|
|||
shape->registerObject();
|
||||
updateShape( shape );
|
||||
|
||||
SimGroup *group;
|
||||
if ( Sim::findObject( "missionGroup", group ) )
|
||||
group->addObject( shape );
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( scene )
|
||||
scene->addObject( shape );
|
||||
}
|
||||
|
||||
void GuiConvexEditorCtrl::updateShape( ConvexShape *shape, S32 offsetFace )
|
||||
|
|
@ -1929,10 +1931,8 @@ ConvexEditorTool::EventResult ConvexEditorCreateTool::on3DMouseUp( const Gui3DMo
|
|||
}
|
||||
else if ( mStage == 0 )
|
||||
{
|
||||
SimGroup *mg;
|
||||
Sim::findObject( "MissionGroup", mg );
|
||||
|
||||
mg->addObject( mNewConvex );
|
||||
SimGroup *scene = Scene::getRootScene();
|
||||
scene->addObject( mNewConvex );
|
||||
|
||||
mStage = -1;
|
||||
|
||||
|
|
@ -2128,9 +2128,9 @@ ConvexShape* ConvexEditorCreateTool::extrudeShapeFromFace( ConvexShape *inShape,
|
|||
newShape->registerObject();
|
||||
mEditor->updateShape( newShape );
|
||||
|
||||
SimGroup *group;
|
||||
if ( Sim::findObject( "missionGroup", group ) )
|
||||
group->addObject( newShape );
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( scene )
|
||||
scene->addObject( newShape );
|
||||
|
||||
return newShape;
|
||||
}
|
||||
|
|
@ -2513,4 +2513,4 @@ if (convex)
|
|||
DefineEngineMethod( GuiConvexEditorCtrl, splitSelectedFace, void, (), , "" )
|
||||
{
|
||||
object->splitSelectedFace();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include "gui/worldEditor/terrainActions.h"
|
||||
#include "terrain/terrMaterial.h"
|
||||
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(TerrainEditor);
|
||||
|
||||
|
|
@ -2405,10 +2405,10 @@ void TerrainEditor::reorderMaterial( S32 index, S32 orderPos )
|
|||
|
||||
DefineEngineMethod( TerrainEditor, attachTerrain, void, (const char * terrain), (""), "(TerrainBlock terrain)")
|
||||
{
|
||||
SimSet * missionGroup = dynamic_cast<SimSet*>(Sim::findObject("MissionGroup"));
|
||||
if (!missionGroup)
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if (!scene)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: no mission group found");
|
||||
Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: no scene found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2417,7 +2417,7 @@ DefineEngineMethod( TerrainEditor, attachTerrain, void, (const char * terrain),
|
|||
// attach to first found terrainBlock
|
||||
if (dStrcmp (terrain,"")==0)
|
||||
{
|
||||
for(SimSetIterator itr(missionGroup); *itr; ++itr)
|
||||
for(SimSetIterator itr(scene); *itr; ++itr)
|
||||
{
|
||||
TerrainBlock* terrBlock = dynamic_cast<TerrainBlock*>(*itr);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
|
||||
#include "tools/editorTool.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT( WorldEditor );
|
||||
|
||||
ConsoleDocClass( WorldEditor,
|
||||
|
|
@ -455,19 +457,20 @@ bool WorldEditor::pasteSelection( bool dropSel )
|
|||
return false;
|
||||
}
|
||||
|
||||
SimGroup *missionGroup = NULL;
|
||||
SimGroup *targetGroup = NULL;
|
||||
if( isMethod( "getNewObjectGroup" ) )
|
||||
{
|
||||
const char* targetGroupName = Con::executef( this, "getNewObjectGroup" );
|
||||
if( targetGroupName && targetGroupName[ 0 ] && !Sim::findObject( targetGroupName, missionGroup ) )
|
||||
if( targetGroupName && targetGroupName[ 0 ] && !Sim::findObject( targetGroupName, targetGroup) )
|
||||
Con::errorf( "WorldEditor::pasteSelection() - no SimGroup called '%s'", targetGroupName );
|
||||
}
|
||||
|
||||
if( !missionGroup )
|
||||
if( !targetGroup)
|
||||
{
|
||||
if( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
targetGroup = Scene::getRootScene();
|
||||
if( !targetGroup)
|
||||
{
|
||||
Con::errorf( "WorldEditor::pasteSelection() - MissionGroup not found" );
|
||||
Con::errorf( "WorldEditor::pasteSelection() - Scene not found" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -481,8 +484,8 @@ bool WorldEditor::pasteSelection( bool dropSel )
|
|||
if ( !obj )
|
||||
continue;
|
||||
|
||||
if ( missionGroup )
|
||||
missionGroup->addObject( obj );
|
||||
if (targetGroup)
|
||||
targetGroup->addObject( obj );
|
||||
|
||||
action->addObject( obj );
|
||||
|
||||
|
|
@ -594,7 +597,7 @@ void WorldEditor::hideObject(SceneObject* serverObj, bool hide)
|
|||
|
||||
void WorldEditor::hideSelection(bool hide)
|
||||
{
|
||||
SimGroup* pGroup = dynamic_cast<SimGroup*>(Sim::findObject("MissionGroup"));
|
||||
Scene* scene = Scene::getRootScene();
|
||||
|
||||
// set server/client objects hide field
|
||||
for(U32 i = 0; i < mSelected->size(); i++)
|
||||
|
|
@ -605,7 +608,7 @@ void WorldEditor::hideSelection(bool hide)
|
|||
|
||||
// Prevent non-mission group objects (i.e. Player) from being hidden.
|
||||
// Otherwise it is difficult to show them again.
|
||||
if(!serverObj->isChildOfGroup(pGroup))
|
||||
if(!serverObj->isChildOfGroup(scene))
|
||||
continue;
|
||||
|
||||
hideObject(serverObj, hide);
|
||||
|
|
@ -2437,7 +2440,7 @@ void WorldEditor::renderScene( const RectI &updateRect )
|
|||
}
|
||||
|
||||
// Render the paths
|
||||
renderPaths(Sim::findObject("MissionGroup"));
|
||||
renderPaths(Scene::getRootScene());
|
||||
|
||||
// walk selected
|
||||
Selection* selection = getActiveSelectionSet();
|
||||
|
|
@ -3653,10 +3656,10 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
|
|||
return;
|
||||
}
|
||||
|
||||
SimGroup *missionGroup;
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if ( !scene)
|
||||
{
|
||||
Con::errorf( "WorldEditor::makeSelectionPrefab - Could not find MissionGroup." );
|
||||
Con::errorf( "WorldEditor::makeSelectionPrefab - Could not find root Scene." );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3746,7 +3749,7 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
|
|||
fabMat.inverse();
|
||||
fab->setTransform( fabMat );
|
||||
fab->registerObject();
|
||||
missionGroup->addObject( fab );
|
||||
scene->addObject( fab );
|
||||
|
||||
// Select it, mark level as dirty.
|
||||
clearSelection();
|
||||
|
|
@ -3812,10 +3815,10 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
|
|||
return;
|
||||
}
|
||||
|
||||
SimGroup *missionGroup;
|
||||
if (!Sim::findObject("MissionGroup", missionGroup))
|
||||
Scene* scene = Scene::getRootScene();
|
||||
if (!scene)
|
||||
{
|
||||
Con::errorf("WorldEditor::makeSelectionAMesh - Could not find MissionGroup.");
|
||||
Con::errorf("WorldEditor::makeSelectionAMesh - Could not find root Scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3877,8 +3880,6 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
|
|||
fabMat.inverse();
|
||||
|
||||
MatrixF objMat;
|
||||
SimObject *obj = NULL;
|
||||
SceneObject *sObj = NULL;
|
||||
|
||||
Vector< SceneObject* > objectList;
|
||||
|
||||
|
|
@ -3967,7 +3968,7 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
|
|||
fabMat.inverse();
|
||||
ts->setTransform(fabMat);
|
||||
ts->registerObject();
|
||||
missionGroup->addObject(ts);
|
||||
scene->addObject(ts);
|
||||
|
||||
// Select it, mark level as dirty.
|
||||
clearSelection();
|
||||
|
|
|
|||
|
|
@ -226,8 +226,8 @@ void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLigh
|
|||
{
|
||||
// Cull the lights using the frustum.
|
||||
getSceneManager()->getContainer()->findObjectList(*frustum, lightMask, &activeLights);
|
||||
|
||||
if (enableZoneLightCulling)
|
||||
/*
|
||||
for (U32 i = 0; i < activeLights.size(); ++i)
|
||||
{
|
||||
for (U32 i = 0; i < activeLights.size(); ++i)
|
||||
{
|
||||
|
|
@ -238,7 +238,7 @@ void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLigh
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// Store the culling position for sun placement
|
||||
// later... see setSpecialLight.
|
||||
mCullPos = frustum->getPosition();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
#define M_CONST_E_F 2.7182818284590452353602874f
|
||||
|
||||
#define POINT_EPSILON (1e-4) ///< Epsilon for point types.
|
||||
#define POINT_EPSILON (0.0001f) ///< Epsilon for point types.
|
||||
|
||||
|
||||
/// Result of an overlap test.
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ void Frustum::setNearFarDist( F32 nearDist, F32 farDist )
|
|||
// Recalculate the frustum.
|
||||
MatrixF xfm( mTransform );
|
||||
|
||||
const F32 CENTER_EPSILON = 0.001;
|
||||
const F32 CENTER_EPSILON = 0.001f;
|
||||
F32 centerX = mNearLeft + (mNearRight - mNearLeft) * 0.5;
|
||||
F32 centerY = mNearBottom + (mNearTop - mNearBottom) * 0.5;
|
||||
if ((centerX > CENTER_EPSILON || centerX < -CENTER_EPSILON) || (centerY > CENTER_EPSILON || centerY < -CENTER_EPSILON) )
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ S32 QSORT_CALLBACK moduleDefinitionVersionIdSort( const void* a, const void* b )
|
|||
|
||||
ModuleManager::ModuleManager() :
|
||||
mEnforceDependencies(true),
|
||||
mEchoInfo(true),
|
||||
mEchoInfo(false),
|
||||
mDatabaseLocks( 0 ),
|
||||
mIgnoreLoadedGroups(false)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -107,8 +107,7 @@ DefineEngineFunction(NavMeshUpdateAll, void, (S32 objid, bool remove), (0, false
|
|||
SceneObject *obj;
|
||||
if(!Sim::findObject(objid, obj))
|
||||
return;
|
||||
if(remove)
|
||||
obj->disableCollision();
|
||||
obj->mPathfindingIgnore = remove;
|
||||
SimSet *set = NavMesh::getServerSet();
|
||||
for(U32 i = 0; i < set->size(); i++)
|
||||
{
|
||||
|
|
@ -119,8 +118,6 @@ DefineEngineFunction(NavMeshUpdateAll, void, (S32 objid, bool remove), (0, false
|
|||
m->buildTiles(obj->getWorldBox());
|
||||
}
|
||||
}
|
||||
if(remove)
|
||||
obj->enableCollision();
|
||||
}
|
||||
|
||||
DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove), (0, false),
|
||||
|
|
@ -129,8 +126,7 @@ DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove),
|
|||
SceneObject *obj;
|
||||
if (!Sim::findObject(objid, obj))
|
||||
return;
|
||||
if (remove)
|
||||
obj->disableCollision();
|
||||
obj->mPathfindingIgnore = remove;
|
||||
SimSet *set = NavMesh::getServerSet();
|
||||
for (U32 i = 0; i < set->size(); i++)
|
||||
{
|
||||
|
|
@ -141,8 +137,6 @@ DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove),
|
|||
m->buildTiles(obj->getWorldBox());
|
||||
}
|
||||
}
|
||||
if (remove)
|
||||
obj->enableCollision();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -281,9 +281,22 @@ void AsyncPacketBufferedInputStream< Stream, Packet >::_requestNext()
|
|||
IResettable* resettable = dynamic_cast< IResettable* >( s );
|
||||
if( resettable )
|
||||
{
|
||||
IPositionable< U32 >* positionable = dynamic_cast< IPositionable< U32 >* >( &Deref( stream ) );
|
||||
U32 pos;
|
||||
if(positionable)
|
||||
pos = positionable->getPosition();
|
||||
|
||||
resettable->reset();
|
||||
isEOS = false;
|
||||
this->mNumRemainingSourceElements = mNumTotalSourceElements;
|
||||
|
||||
if( positionable )
|
||||
{
|
||||
positionable->setPosition(pos);
|
||||
U32 dur = stream->getDuration();
|
||||
if(dur != 0) //avoiding division by zero? not needed, probably
|
||||
this->mNumRemainingSourceElements -= (U32)(mNumTotalSourceElements*(F32)pos/dur);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( isEOS )
|
||||
|
|
|
|||
|
|
@ -249,6 +249,14 @@ enum InputObjectInstancesEnum
|
|||
SI_DPOV2 = 0x215,
|
||||
SI_LPOV2 = 0x216,
|
||||
SI_RPOV2 = 0x217,
|
||||
SI_POVMASK = 0x218,
|
||||
SI_POVMASK2 = 0x219,
|
||||
|
||||
/// Trackball event codes.
|
||||
SI_XBALL = 0x21A,
|
||||
SI_YBALL = 0x21B,
|
||||
SI_XBALL2 = 0x21C,
|
||||
SI_YBALL2 = 0x21D,
|
||||
|
||||
XI_CONNECT = 0x300,
|
||||
XI_THUMBLX = 0x301,
|
||||
|
|
@ -262,7 +270,7 @@ enum InputObjectInstancesEnum
|
|||
XI_DPAD_DOWN = 0x308,
|
||||
XI_DPAD_LEFT = 0x309,
|
||||
XI_DPAD_RIGHT = 0x310,*/
|
||||
|
||||
|
||||
XI_START = 0x311,
|
||||
XI_BACK = 0x312,
|
||||
XI_LEFT_THUMB = 0x313,
|
||||
|
|
@ -273,7 +281,8 @@ enum InputObjectInstancesEnum
|
|||
XI_A = 0x317,
|
||||
XI_B = 0x318,
|
||||
XI_X = 0x319,
|
||||
XI_Y = 0x320,
|
||||
XI_Y = 0x31A,
|
||||
XI_GUIDE = 0x31B,
|
||||
|
||||
INPUT_DEVICE_PLUGIN_CODES_START = 0x400,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -285,9 +285,9 @@ bool FileDialog::Execute()
|
|||
{
|
||||
// Single file selection, do it the easy way
|
||||
if(mForceRelativePath)
|
||||
mData.mFile = Platform::makeRelativePathName(resultPath.c_str(), NULL);
|
||||
mData.mFile = Con::getReturnBuffer(Platform::makeRelativePathName(resultPath.c_str(), NULL));
|
||||
else
|
||||
mData.mFile = resultPath.c_str();
|
||||
mData.mFile = Con::getReturnBuffer(resultPath.c_str());
|
||||
}
|
||||
else if (mData.mStyle & FileDialogData::FDS_MULTIPLEFILES)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,7 +230,6 @@ namespace PlatformNetState
|
|||
// which are required for LAN queries (PC->Xbox connectivity). The wire protocol still
|
||||
// uses the VDP packet structure, though.
|
||||
S32 protocol = IPPROTO_UDP;
|
||||
bool useVDP = false;
|
||||
#ifdef TORQUE_DISABLE_PC_CONNECTIVITY
|
||||
// Xbox uses a VDP (voice/data protocol) socket for networking
|
||||
protocol = IPPROTO_VDP;
|
||||
|
|
@ -1956,7 +1955,6 @@ void Net::enableMulticast()
|
|||
|
||||
if (error == NoError)
|
||||
{
|
||||
NetAddress listenAddress;
|
||||
char listenAddressStr[256];
|
||||
Net::addressToString(&multicastAddress, listenAddressStr);
|
||||
Con::printf("Multicast initialized on %s", listenAddressStr);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#import "platform/profiler.h"
|
||||
#import "cinterface/c_controlInterface.h"
|
||||
#import "core/volume.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
//TODO: file io still needs some work...
|
||||
|
||||
#define MAX_MAC_PATH_LONG 2048
|
||||
|
|
@ -992,25 +992,22 @@ bool Platform::fileTimeToString(FileTime * time, char * string, U32 strLen) { re
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(TORQUE_DEBUG)
|
||||
ConsoleFunction(testHasSubdir,void,2,2,"tests platform::hasSubDirectory") {
|
||||
Con::printf("testing %s",(const char*)argv[1]);
|
||||
DefineEngineFunction(testHasSubdir,void, (String _dir),,"tests platform::hasSubDirectory") {
|
||||
Platform::addExcludedDirectory(".svn");
|
||||
if(Platform::hasSubDirectory(argv[1]))
|
||||
if(Platform::hasSubDirectory(_dir.c_str()))
|
||||
Con::printf(" has subdir");
|
||||
else
|
||||
Con::printf(" does not have subdir");
|
||||
}
|
||||
|
||||
ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int depth, bool noBasePath)") {
|
||||
DefineEngineFunction(testDumpDirectories,void,(String _path, S32 _depth, bool _noBasePath),,"testDumpDirectories('path', int depth, bool noBasePath)") {
|
||||
Vector<StringTableEntry> paths;
|
||||
const S32 depth = dAtoi(argv[2]);
|
||||
const bool noBasePath = dAtob(argv[3]);
|
||||
|
||||
Platform::addExcludedDirectory(".svn");
|
||||
|
||||
Platform::dumpDirectories(argv[1], paths, depth, noBasePath);
|
||||
Platform::dumpDirectories(_path.c_str(), paths, _depth, _noBasePath);
|
||||
|
||||
Con::printf("Dumping directories starting from %s with depth %i", (const char*)argv[1],depth);
|
||||
Con::printf("Dumping directories starting from %s with depth %i", _path.c_str(), _depth);
|
||||
|
||||
for(Vector<StringTableEntry>::iterator itr = paths.begin(); itr != paths.end(); itr++) {
|
||||
Con::printf(*itr);
|
||||
|
|
@ -1018,14 +1015,13 @@ ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int de
|
|||
|
||||
}
|
||||
|
||||
ConsoleFunction(testDumpPaths, void, 3, 3, "testDumpPaths('path', int depth)")
|
||||
DefineEngineFunction(testDumpPaths, void, (String _path, S32 _depth),, "testDumpPaths('path', int depth)")
|
||||
{
|
||||
Vector<Platform::FileInfo> files;
|
||||
S32 depth = dAtoi(argv[2]);
|
||||
|
||||
Platform::addExcludedDirectory(".svn");
|
||||
|
||||
Platform::dumpPath(argv[1], files, depth);
|
||||
Platform::dumpPath(_path.c_str(), files, _depth);
|
||||
|
||||
for(Vector<Platform::FileInfo>::iterator itr = files.begin(); itr != files.end(); itr++) {
|
||||
Con::printf("%s/%s",itr->pFullPath, itr->pFileName);
|
||||
|
|
@ -1033,15 +1029,15 @@ ConsoleFunction(testDumpPaths, void, 3, 3, "testDumpPaths('path', int depth)")
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ConsoleFunction(testFileTouch, bool , 2,2, "testFileTouch('path')")
|
||||
DefineEngineFunction(testFileTouch, bool , (String _path),, "testFileTouch('path')")
|
||||
{
|
||||
return dFileTouch(argv[1]);
|
||||
return dFileTouch(_path.c_str());
|
||||
}
|
||||
|
||||
ConsoleFunction(testGetFileTimes, bool, 2,2, "testGetFileTimes('path')")
|
||||
DefineEngineFunction(testGetFileTimes, bool, (String _path),, "testGetFileTimes('path')")
|
||||
{
|
||||
FileTime create, modify;
|
||||
bool ok = Platform::getFileTimes(argv[1], &create, &modify);
|
||||
bool ok = Platform::getFileTimes(_path.c_str(), &create, &modify);
|
||||
Con::printf("%s Platform::getFileTimes %i, %i", ok ? "+OK" : "-FAIL", create, modify);
|
||||
return ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#import "console/console.h"
|
||||
#import "math/mMath.h"
|
||||
#import "core/strings/stringFunctions.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
extern void mInstallLibrary_C();
|
||||
extern void mInstallLibrary_Vec();
|
||||
|
|
@ -51,7 +52,13 @@ void Platform::setMathControlStateKnown()
|
|||
}
|
||||
|
||||
//--------------------------------------
|
||||
ConsoleFunction( MathInit, void, 1, 10, "(DETECT|C|SSE)")
|
||||
DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
|
||||
"@brief Install the math library with specified extensions.\n\n"
|
||||
"Possible parameters are:\n\n"
|
||||
" - 'DETECT' Autodetect math lib settings.\n\n"
|
||||
" - 'C' Enable the C math routines. C routines are always enabled.\n\n"
|
||||
" - 'SSE' Enable SSE math routines.\n\n"
|
||||
"@ingroup Math")
|
||||
{
|
||||
U32 properties = CPU_PROP_C; // C entensions are always used
|
||||
|
||||
|
|
|
|||
|
|
@ -27,15 +27,11 @@
|
|||
|
||||
#include "sdlInput.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "sdlInputManager.h"
|
||||
#include "SDL.h"
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
// Static class variables:
|
||||
InputManager* Input::smManager;
|
||||
InputManager* Input::smManager = NULL;
|
||||
bool Input::smActive;
|
||||
U8 Input::smModifierKeys;
|
||||
bool Input::smLastKeyboardActivated;
|
||||
|
|
@ -43,10 +39,6 @@ bool Input::smLastMouseActivated;
|
|||
bool Input::smLastJoystickActivated;
|
||||
InputEvent Input::smInputEvent;
|
||||
|
||||
#ifdef LOG_INPUT
|
||||
static HANDLE gInputLog;
|
||||
#endif
|
||||
|
||||
static void fillAsciiTable() {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -91,24 +83,17 @@ void Input::init()
|
|||
fillAsciiTable();
|
||||
Con::printf( "" );
|
||||
|
||||
smManager = new SDLInputManager;
|
||||
if (smManager)
|
||||
{
|
||||
SDLInputManager::init();
|
||||
}
|
||||
|
||||
// Set ourselves to participate in per-frame processing.
|
||||
Process::notify(Input::process, PROCESS_INPUT_ORDER);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DefineEngineFunction(isJoystickDetected, bool, (),, "")
|
||||
{
|
||||
return(SDL_NumJoysticks() > 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DefineEngineFunction(getJoystickAxes, const char*, (const char* instance), , "")
|
||||
{
|
||||
// TODO SDL
|
||||
return("");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
U16 Input::getKeyCode( U16 asciiCode )
|
||||
{
|
||||
|
|
@ -118,7 +103,7 @@ U16 Input::getKeyCode( U16 asciiCode )
|
|||
char c[2];
|
||||
c[0]= asciiCode;
|
||||
c[1] = NULL;
|
||||
return KeyMapSDL::getTorqueScanCodeFromSDL( SDL_GetScancodeFromName( c ) );
|
||||
return KeyMapSDL::getTorqueScanCodeFromSDL( SDL_GetScancodeFromKey( SDL_GetKeyFromName(c) ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -159,6 +144,13 @@ void Input::destroy()
|
|||
|
||||
SDL_QuitSubSystem( SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER );
|
||||
|
||||
if (smManager)
|
||||
{
|
||||
if (smManager->isEnabled())
|
||||
smManager->disable();
|
||||
delete smManager;
|
||||
smManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -186,8 +178,8 @@ void Input::activate()
|
|||
//ImmReleaseContext( getWin32WindowHandle(), winState.imeHandle );
|
||||
#endif
|
||||
|
||||
if ( !Con::getBoolVariable( "$enableDirectInput" ) )
|
||||
return;
|
||||
if (smManager && !smManager->isEnabled())
|
||||
smManager->enable();
|
||||
|
||||
if ( smManager && smManager->isEnabled() && !smActive )
|
||||
{
|
||||
|
|
@ -199,7 +191,10 @@ void Input::activate()
|
|||
//------------------------------------------------------------------------------
|
||||
void Input::deactivate()
|
||||
{
|
||||
if ( smManager && smManager->isEnabled() && smActive )
|
||||
if (smManager && smManager->isEnabled())
|
||||
smManager->disable();
|
||||
|
||||
if (smActive)
|
||||
{
|
||||
smActive = false;
|
||||
Con::printf( "Input deactivated." );
|
||||
|
|
@ -435,4 +430,4 @@ U32 KeyMapSDL::getSDLScanCodeFromTorque(U32 torque)
|
|||
buildScanCodeArray();
|
||||
|
||||
return T3D_SDL[torque];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1381
Engine/source/platformSDL/sdlInputManager.cpp
Normal file
1381
Engine/source/platformSDL/sdlInputManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
114
Engine/source/platformSDL/sdlInputManager.h
Normal file
114
Engine/source/platformSDL/sdlInputManager.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SDLINPUTMANAGER_H_
|
||||
#define _SDLINPUTMANAGER_H_
|
||||
|
||||
#ifndef _PLATFORMINPUT_H_
|
||||
#include "platform/platformInput.h"
|
||||
#endif
|
||||
#include "SDL.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class SDLInputManager : public InputManager
|
||||
{
|
||||
enum Constants {
|
||||
MaxJoysticks = 4, // Up to 4 simultaneous joysticks
|
||||
MaxControllers = 4, // Up to 4 simultaneous controllers
|
||||
MaxHats = 2, // Maximum 2 hats per device
|
||||
MaxBalls = 2, // Maximum 2 trackballs per device
|
||||
MaxControllerAxes = 7, // From map_StringForControllerAxis[] in SDL_gamecontroller.c
|
||||
MaxControllerButtons = 16 // From map_StringForControllerButton[] in SDL_gamecontroller.c
|
||||
};
|
||||
|
||||
struct controllerState
|
||||
{
|
||||
S32 sdlInstID; // SDL device instance id
|
||||
U32 torqueInstID; // Torque device instance id
|
||||
SDL_GameController *inputDevice;
|
||||
};
|
||||
|
||||
struct joystickState
|
||||
{
|
||||
S32 sdlInstID; // SDL device instance id
|
||||
U32 torqueInstID; // Torque device instance id
|
||||
SDL_Joystick *inputDevice;
|
||||
U32 numAxes;
|
||||
U8 lastHatState[MaxHats];
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
private:
|
||||
typedef InputManager Parent;
|
||||
|
||||
static S32 map_EventForControllerAxis[MaxControllerAxes];
|
||||
static S32 map_EventForControllerButton[MaxControllerButtons];
|
||||
|
||||
static bool smJoystickEnabled;
|
||||
static bool smJoystickSplitAxesLR;
|
||||
static bool smControllerEnabled;
|
||||
static bool smPOVButtonEvents;
|
||||
static bool smPOVMaskEvents;
|
||||
|
||||
joystickState mJoysticks[MaxJoysticks];
|
||||
controllerState mControllers[MaxControllers];
|
||||
|
||||
// Used to look up a torque instance based on a device inst
|
||||
HashTable<S32, joystickState*> mJoystickMap;
|
||||
HashTable<S32, controllerState*> mControllerMap;
|
||||
|
||||
bool mJoystickActive;
|
||||
|
||||
void deviceConnectedCallback(S32 index);
|
||||
bool closeControllerByIndex(S32 index);
|
||||
void closeController(SDL_JoystickID sdlId);
|
||||
bool closeJoystickByIndex(S32 index);
|
||||
void closeJoystick(SDL_JoystickID sdlId);
|
||||
|
||||
void buildInputEvent(U32 deviceType, U32 deviceInst, InputEventType objType, InputObjectInstances objInst, InputActionType action, S32 iValue);
|
||||
void buildInputEvent(U32 deviceType, U32 deviceInst, InputEventType objType, InputObjectInstances objInst, InputActionType action, F32 fValue);
|
||||
void buildHatEvents(U32 deviceType, U32 deviceInst, U8 lastState, U8 currentState, S32 hatIndex);
|
||||
|
||||
public:
|
||||
DECLARE_STATIC_CLASS(SDLInputManager);
|
||||
|
||||
public:
|
||||
SDLInputManager();
|
||||
|
||||
bool enable();
|
||||
void disable();
|
||||
void process();
|
||||
|
||||
void processEvent(SDL_Event &evt);
|
||||
|
||||
static void init();
|
||||
|
||||
// Console interface:
|
||||
S32 openJoystick(S32 sdlIndex, S32 requestedTID);
|
||||
S32 openController(S32 sdlIndex, S32 requestedTID);
|
||||
void closeDevice(S32 sdlIndex);
|
||||
S32 getJoystickOpenState(S32 sdlIndex);
|
||||
void getJoystickTorqueInst(S32 sdlIndex, char* instBuffer);
|
||||
};
|
||||
|
||||
#endif // _SDLINPUTMANAGER_H_
|
||||
|
|
@ -34,13 +34,14 @@
|
|||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
StdConsole *stdConsole = NULL;
|
||||
|
||||
ConsoleFunction(enableWinConsole, void, 2, 2, "enableWinConsole(bool);")
|
||||
DefineEngineFunction(enableWinConsole, void, (bool _enable),, "enableWinConsole(bool);")
|
||||
{
|
||||
argc;
|
||||
if (stdConsole)
|
||||
stdConsole->enable(dAtob(argv[1]));
|
||||
stdConsole->enable(_enable);
|
||||
}
|
||||
|
||||
void StdConsole::create()
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
#include "console/console.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "util/tempAlloc.h"
|
||||
#include "cinterface/cinterface.h"
|
||||
#include "cinterface/c_controlInterface.h"
|
||||
#include "core/volume.h"
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "console/console.h"
|
||||
#include "math/mMath.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
extern void mInstallLibrary_C();
|
||||
extern void mInstallLibrary_ASM();
|
||||
|
|
@ -35,7 +35,13 @@ extern void mInstall_Library_SSE();
|
|||
|
||||
|
||||
//--------------------------------------
|
||||
ConsoleFunction( MathInit, void, 1, 10, "(detect|C|FPU|MMX|3DNOW|SSE|...)")
|
||||
DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
|
||||
"@brief Install the math library with specified extensions.\n\n"
|
||||
"Possible parameters are:\n\n"
|
||||
" - 'DETECT' Autodetect math lib settings.\n\n"
|
||||
" - 'C' Enable the C math routines. C routines are always enabled.\n\n"
|
||||
" - 'SSE' Enable SSE math routines.\n\n"
|
||||
"@ingroup Math")
|
||||
{
|
||||
U32 properties = CPU_PROP_C; // C entensions are always used
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#ifndef TORQUE_DEDICATED
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
|
@ -203,10 +203,7 @@ void Platform::outputDebugString(const char *string, ...)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
// testing function
|
||||
ConsoleFunction(debug_debugbreak, void, 1, 1, "debug_debugbreak()")
|
||||
{
|
||||
Platform::debugBreak();
|
||||
}
|
||||
//DefineEngineFunction(debug_debugbreak, void, () , , "debug_debugbreak();");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Platform::restartInstance()
|
||||
|
|
|
|||
|
|
@ -1392,7 +1392,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
|
|||
// This is truly lame, but it can happen. There must be a better way to
|
||||
// deal with this.
|
||||
if (minCoord == SceneContainer::csmTotalBinSize)
|
||||
minCoord = SceneContainer::csmTotalBinSize - 0.01;
|
||||
minCoord = SceneContainer::csmTotalBinSize - 0.01f;
|
||||
}
|
||||
|
||||
AssertFatal(minCoord >= 0.0 && minCoord < SceneContainer::csmTotalBinSize, "Bad minCoord");
|
||||
|
|
@ -1415,7 +1415,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
|
|||
// This is truly lame, but it can happen. There must be a better way to
|
||||
// deal with this.
|
||||
if (minCoord == SceneContainer::csmTotalBinSize)
|
||||
minCoord = SceneContainer::csmTotalBinSize - 0.01;
|
||||
minCoord = SceneContainer::csmTotalBinSize - 0.01f;
|
||||
}
|
||||
AssertFatal(minCoord >= 0.0 && minCoord < SceneContainer::csmTotalBinSize, "Bad minCoord");
|
||||
|
||||
|
|
@ -1426,7 +1426,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
|
|||
// This is truly lame, but it can happen. There must be a better way to
|
||||
// deal with this.
|
||||
if (maxCoord == SceneContainer::csmTotalBinSize)
|
||||
maxCoord = SceneContainer::csmTotalBinSize - 0.01;
|
||||
maxCoord = SceneContainer::csmTotalBinSize - 0.01f;
|
||||
}
|
||||
AssertFatal(maxCoord >= 0.0 && maxCoord < SceneContainer::csmTotalBinSize, "Bad maxCoord");
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ ConsoleDocClass( SceneObject,
|
|||
"@ingroup gameObjects\n"
|
||||
);
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
extern bool gEditingMission;
|
||||
#endif
|
||||
|
||||
Signal< void( SceneObject* ) > SceneObject::smSceneObjectAdd;
|
||||
Signal< void( SceneObject* ) > SceneObject::smSceneObjectRemove;
|
||||
|
|
@ -763,8 +766,14 @@ void SceneObject::onCameraScopeQuery( NetConnection* connection, CameraScopeQuer
|
|||
|
||||
bool SceneObject::isRenderEnabled() const
|
||||
{
|
||||
AbstractClassRep *classRep = getClassRep();
|
||||
return ( mObjectFlags.test( RenderEnabledFlag ) && classRep->isRenderEnabled() );
|
||||
#ifdef TORQUE_TOOLS
|
||||
if (gEditingMission)
|
||||
{
|
||||
AbstractClassRep *classRep = getClassRep();
|
||||
return (mObjectFlags.test(RenderEnabledFlag) && classRep->isRenderEnabled());
|
||||
}
|
||||
#endif
|
||||
return (mObjectFlags.test(RenderEnabledFlag));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "renderInstance/renderPassManager.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
extern bool gEditingMission;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
@ -59,13 +61,13 @@ DefineEngineFunction(pathOnMissionLoadDone, void, (),,
|
|||
"@ingroup Networking")
|
||||
{
|
||||
// Need to load subobjects for all loaded interiors...
|
||||
SimGroup* pMissionGroup = dynamic_cast<SimGroup*>(Sim::findObject("MissionGroup"));
|
||||
AssertFatal(pMissionGroup != NULL, "Error, mission done loading and no mission group?");
|
||||
Scene* scene = Scene::getRootScene();
|
||||
AssertFatal(scene != NULL, "Error, mission done loading and no scene?");
|
||||
|
||||
U32 currStart = 0;
|
||||
U32 currEnd = 1;
|
||||
Vector<SimGroup*> groups;
|
||||
groups.push_back(pMissionGroup);
|
||||
groups.push_back(scene);
|
||||
|
||||
while (true) {
|
||||
for (U32 i = currStart; i < currEnd; i++) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#else
|
||||
# include <al/al.h>
|
||||
# include <al/alc.h>
|
||||
# include <AL/alext.h>
|
||||
# include <AL/efx-presets.h>
|
||||
#endif
|
||||
|
||||
#ifndef ALAPIENTRY
|
||||
|
|
@ -134,6 +136,31 @@ typedef void * (ALCAPIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, con
|
|||
typedef ALCenum (ALCAPIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
|
||||
typedef const ALCchar* (ALCAPIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
|
||||
typedef void (ALCAPIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
|
||||
///Changes for effects
|
||||
typedef void (ALAPIENTRY *LPALGENEFFECTS)(ALsizei n, ALuint *effects);
|
||||
typedef void (ALAPIENTRY *LPALDELETEEFFECTS)(ALsizei n, const ALuint *effects);
|
||||
typedef ALboolean (ALAPIENTRY *LPALISEFFECT)(ALuint effect);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTI)(ALuint effect, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTIV)(ALuint effect, ALenum param, const ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTF)(ALuint effect, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALEFFECTFV)(ALuint effect, ALenum param, const ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTI)(ALuint effect, ALenum param, ALint *value);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTIV)(ALuint effect, ALenum param, ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTF)(ALuint effect, ALenum param, ALfloat *value);
|
||||
typedef void (ALAPIENTRY *LPALGETEFFECTFV)(ALuint effect, ALenum param, ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALRELEASEALEFFECTS)(ALCdevice *device);
|
||||
typedef void (ALAPIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei n, ALuint *effectslots);
|
||||
typedef void (ALAPIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei n, const ALuint *effectslots);
|
||||
typedef ALboolean (ALAPIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint effectslot);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint value);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, const ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat value);
|
||||
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, const ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint *value);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, ALint *values);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat *value);
|
||||
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, ALfloat *values);
|
||||
typedef void (ALAPIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -166,6 +193,7 @@ typedef struct
|
|||
LPALISSOURCE alIsSource;
|
||||
LPALSOURCEI alSourcei;
|
||||
LPALSOURCEF alSourcef;
|
||||
LPALSOURCE3I alSource3i;
|
||||
LPALSOURCE3F alSource3f;
|
||||
LPALSOURCEFV alSourcefv;
|
||||
LPALGETSOURCEI alGetSourcei;
|
||||
|
|
@ -203,6 +231,29 @@ typedef struct
|
|||
LPALCISEXTENSIONPRESENT alcIsExtensionPresent;
|
||||
LPALCGETPROCADDRESS alcGetProcAddress;
|
||||
LPALCGETENUMVALUE alcGetEnumValue;
|
||||
LPALGENEFFECTS alGenEffects;
|
||||
LPALDELETEEFFECTS alDeleteEffects;
|
||||
LPALISEFFECT alIsEffect;
|
||||
LPALEFFECTI alEffecti;
|
||||
LPALEFFECTIV alEffectiv;
|
||||
LPALEFFECTF alEffectf;
|
||||
LPALEFFECTFV alEffectfv;
|
||||
LPALGETEFFECTI alGetEffecti;
|
||||
LPALGETEFFECTIV alGetEffectiv;
|
||||
LPALGETEFFECTF alGetEffectf;
|
||||
LPALGETEFFECTFV alGetEffectfv;
|
||||
LPALRELEASEALEFFECTS alReleaseEffects;
|
||||
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
||||
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
||||
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
|
||||
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
||||
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
|
||||
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
|
||||
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
|
||||
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
|
||||
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
|
||||
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
||||
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
||||
} OPENALFNTABLE, *LPOPENALFNTABLE;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -42,16 +42,21 @@ SFXALDevice::SFXALDevice( SFXProvider *provider,
|
|||
|
||||
// TODO: The OpenAL device doesn't set the primary buffer
|
||||
// $pref::SFX::frequency or $pref::SFX::bitrate!
|
||||
//check auxiliary device sends 4 and add them to the device
|
||||
ALint attribs[4] = { 0 };
|
||||
ALCint iSends = 0;
|
||||
attribs[0] = ALC_MAX_AUXILIARY_SENDS;
|
||||
attribs[1] = 4;
|
||||
|
||||
mDevice = mOpenAL.alcOpenDevice( name );
|
||||
mOpenAL.alcGetError( mDevice );
|
||||
if( mDevice )
|
||||
{
|
||||
mContext = mOpenAL.alcCreateContext( mDevice, NULL );
|
||||
mContext = mOpenAL.alcCreateContext( mDevice, attribs );
|
||||
|
||||
if( mContext )
|
||||
mOpenAL.alcMakeContextCurrent( mContext );
|
||||
|
||||
mOpenAL.alcGetIntegerv(mDevice, ALC_MAX_AUXILIARY_SENDS, 1, &iSends);
|
||||
U32 err = mOpenAL.alcGetError( mDevice );
|
||||
|
||||
if( err != ALC_NO_ERROR )
|
||||
|
|
@ -78,7 +83,10 @@ SFXALDevice::SFXALDevice( SFXProvider *provider,
|
|||
SFXALDevice::~SFXALDevice()
|
||||
{
|
||||
_releaseAllResources();
|
||||
|
||||
///cleanup our effects
|
||||
mOpenAL.alDeleteAuxiliaryEffectSlots(4, effectSlot);
|
||||
mOpenAL.alDeleteEffects(2, effect);
|
||||
///cleanup of effects ends
|
||||
mOpenAL.alcMakeContextCurrent( NULL );
|
||||
mOpenAL.alcDestroyContext( mContext );
|
||||
mOpenAL.alcCloseDevice( mDevice );
|
||||
|
|
@ -145,6 +153,9 @@ void SFXALDevice::setListener( U32 index, const SFXListenerProperties& listener
|
|||
mOpenAL.alListenerfv( AL_POSITION, pos );
|
||||
mOpenAL.alListenerfv( AL_VELOCITY, velocity );
|
||||
mOpenAL.alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] );
|
||||
///Pass a unit size to openal, 1.0 assumes 1 meter to 1 game unit.
|
||||
///Crucial for air absorbtion calculations.
|
||||
mOpenAL.alListenerf(AL_METERS_PER_UNIT, 1.0f);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -164,7 +175,13 @@ void SFXALDevice::setDistanceModel( SFXDistanceModel model )
|
|||
if( mUserRolloffFactor != mRolloffFactor )
|
||||
_setRolloffFactor( mUserRolloffFactor );
|
||||
break;
|
||||
|
||||
/// create a case for our exponential distance model
|
||||
case SFXDistanceModelExponent:
|
||||
mOpenAL.alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
|
||||
if (mUserRolloffFactor != mRolloffFactor)
|
||||
_setRolloffFactor(mUserRolloffFactor);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertWarn( false, "SFXALDevice::setDistanceModel - distance model not implemented" );
|
||||
}
|
||||
|
|
@ -200,3 +217,109 @@ void SFXALDevice::setRolloffFactor( F32 factor )
|
|||
|
||||
mUserRolloffFactor = factor;
|
||||
}
|
||||
|
||||
void SFXALDevice::openSlots()
|
||||
{
|
||||
for (uLoop = 0; uLoop < 4; uLoop++)
|
||||
{
|
||||
mOpenAL.alGenAuxiliaryEffectSlots(1, &effectSlot[uLoop]);
|
||||
}
|
||||
|
||||
for (uLoop = 0; uLoop < 2; uLoop++)
|
||||
{
|
||||
mOpenAL.alGenEffects(1, &effect[uLoop]);
|
||||
}
|
||||
///debug string output so we know our slots are open
|
||||
Platform::outputDebugString("Slots Open");
|
||||
}
|
||||
|
||||
///create reverb effect
|
||||
void SFXALDevice::setReverb(const SFXReverbProperties& reverb)
|
||||
{
|
||||
///output a debug string so we know each time the reverb changes
|
||||
Platform::outputDebugString("Updated");
|
||||
|
||||
///load an efxeaxreverb default and add our values from
|
||||
///sfxreverbproperties to it
|
||||
EFXEAXREVERBPROPERTIES prop = EFX_REVERB_PRESET_GENERIC;
|
||||
|
||||
prop.flDensity = reverb.flDensity;
|
||||
prop.flDiffusion = reverb.flDiffusion;
|
||||
prop.flGain = reverb.flGain;
|
||||
prop.flGainHF = reverb.flGainHF;
|
||||
prop.flGainLF = reverb.flGainLF;
|
||||
prop.flDecayTime = reverb.flDecayTime;
|
||||
prop.flDecayHFRatio = reverb.flDecayHFRatio;
|
||||
prop.flDecayLFRatio = reverb.flDecayLFRatio;
|
||||
prop.flReflectionsGain = reverb.flReflectionsGain;
|
||||
prop.flReflectionsDelay = reverb.flReflectionsDelay;
|
||||
prop.flLateReverbGain = reverb.flLateReverbGain;
|
||||
prop.flLateReverbDelay = reverb.flLateReverbDelay;
|
||||
prop.flEchoTime = reverb.flEchoTime;
|
||||
prop.flEchoDepth = reverb.flEchoDepth;
|
||||
prop.flModulationTime = reverb.flModulationTime;
|
||||
prop.flModulationDepth = reverb.flModulationDepth;
|
||||
prop.flAirAbsorptionGainHF = reverb.flAirAbsorptionGainHF;
|
||||
prop.flHFReference = reverb.flHFReference;
|
||||
prop.flLFReference = reverb.flLFReference;
|
||||
prop.flRoomRolloffFactor = reverb.flRoomRolloffFactor;
|
||||
prop.iDecayHFLimit = reverb.iDecayHFLimit;
|
||||
|
||||
if (mOpenAL.alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
|
||||
{
|
||||
|
||||
/// EAX Reverb is available. Set the EAX effect type
|
||||
|
||||
mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
|
||||
///add our values to the setup of the reverb
|
||||
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DENSITY, prop.flDensity);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DIFFUSION, prop.flDiffusion);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAIN, prop.flGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINHF, prop.flGainHF);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINLF, prop.flGainLF);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_TIME, prop.flDecayTime);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_LFRATIO, prop.flDecayLFRatio);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_TIME, prop.flEchoTime);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_DEPTH, prop.flEchoDepth);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_TIME, prop.flModulationTime);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_DEPTH, prop.flModulationDepth);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_HFREFERENCE, prop.flHFReference);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LFREFERENCE, prop.flLFReference);
|
||||
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
|
||||
mOpenAL.alEffecti(effect[0], AL_EAXREVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
|
||||
mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
|
||||
Platform::outputDebugString("eax reverb properties set");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/// No EAX Reverb. Set the standard reverb effect
|
||||
mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_DENSITY, prop.flDensity);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_DIFFUSION, prop.flDiffusion);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_GAIN, prop.flGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_GAINHF, prop.flGainHF);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_TIME, prop.flDecayTime);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
|
||||
mOpenAL.alEffectf(effect[0], AL_REVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
|
||||
mOpenAL.alEffecti(effect[0], AL_REVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
|
||||
mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -85,6 +85,15 @@ class SFXALDevice : public SFXDevice
|
|||
virtual void setDistanceModel( SFXDistanceModel model );
|
||||
virtual void setDopplerFactor( F32 factor );
|
||||
virtual void setRolloffFactor( F32 factor );
|
||||
//function for openAL to open slots
|
||||
virtual void openSlots();
|
||||
//slots
|
||||
ALuint effectSlot[4] = { 0 };
|
||||
ALuint effect[2] = { 0 };
|
||||
ALuint uLoop;
|
||||
//get values from sfxreverbproperties and pass it to openal device
|
||||
virtual void setReverb(const SFXReverbProperties& reverb);
|
||||
virtual void resetReverb() {}
|
||||
};
|
||||
|
||||
#endif // _SFXALDEVICE_H_
|
||||
|
|
@ -118,7 +118,8 @@ void SFXALVoice::_play()
|
|||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALVoice] Starting playback" );
|
||||
#endif
|
||||
|
||||
//send every voice that plays to the alauxiliary slot that has the reverb
|
||||
mOpenAL.alSource3i(mSourceName, AL_AUXILIARY_SEND_FILTER, 1, 0, AL_FILTER_NULL);
|
||||
mOpenAL.alSourcePlay( mSourceName );
|
||||
|
||||
//WORKAROUND: Adjust play cursor for buggy OAL when resuming playback. Do this after alSourcePlay
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue