More backport from the ogl-es irrlicht branch

This commit is contained in:
Lucas Baudin 2016-02-24 20:34:46 +01:00
parent a470cd74d6
commit 48069a7bcc
18 changed files with 5293 additions and 53 deletions

View File

@ -28,6 +28,10 @@ namespace irr
//! A device native to Mac OSX
/** This device uses Apple's Cocoa API and works in Mac OSX 10.2 and above. */
EIDT_OSX,
//! A device native to the IPhone/IPod touch
/** This device should be used with the OpenGL-ES driver. */
EIDT_IPHONE,
//! A device which uses Simple DirectMedia Layer
/** The SDL device works under all platforms supported by SDL but first must be compiled
@ -51,7 +55,13 @@ namespace irr
to your operating system. If this is unavailable then the X11, SDL and then console device
will be tried. This ensures that Irrlicht will run even if your platform is unsupported,
although it may not be able to render anything. */
EIDT_BEST
EIDT_BEST,
//! A device for Android platforms
/** Best used with embedded devices and mobile systems.
Does not need X11 or other graphical subsystems.
May support hw-acceleration via OpenGL-ES */
EIDT_ANDROID,
};
} // end namespace irr

View File

@ -33,6 +33,18 @@ namespace irr
/** Like mouse events, keyboard events are created by the device and passed to
IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */
EET_KEY_INPUT_EVENT,
//! A multi touch event.
EET_MULTI_TOUCH_EVENT,
//! A accelerometer event.
EET_ACCELEROMETER_EVENT,
//! A gyroscope event.
EET_GYROSCOPE_EVENT,
//! A device motion event.
EET_DEVICE_MOTION_EVENT,
//! A joystick (joypad, gamepad) input event.
/** Joystick events are created by polling all connected joysticks once per
@ -49,14 +61,6 @@ namespace irr
user receiver then no text will be sent to the console. */
EET_LOG_TEXT_EVENT,
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
//! A input method event
/** Input method events are created by the input method message and passed to IrrlichtDevice::postEventFromUser.
Windows: Implemented.
Linux / Other: Not yet implemented. */
EET_IMPUT_METHOD_EVENT,
#endif
//! A user event with user data.
/** This is not used by Irrlicht and can be used to send user
specific data though the system. The Irrlicht 'window handle'
@ -149,20 +153,25 @@ namespace irr
EMBSM_FORCE_32_BIT = 0x7fffffff
};
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
//! Enumeration for all input method events
enum EINPUT_METHOD_EVENT
//! Enumeration for all touch input events
enum EMULTI_TOUCH_INPUT_EVENT
{
//! a character from input method.
EIME_CHAR_INPUT = 0,
//! change position of composition window
EIME_CHANGE_POS,
EIME_FORCE_32_BIT = 0x7fffffff
//! Max multi touch count
NUMBER_OF_MULTI_TOUCHES = 10,
//! Touch was pressed down.
EMTIE_PRESSED_DOWN = 0,
//! Touch was left up.
EMTIE_LEFT_UP,
//! The touch changed its position.
EMTIE_MOVED,
//! No real event. Just for convenience to get number of events
EMTIE_COUNT
};
#endif
namespace gui
{
@ -352,6 +361,97 @@ struct SEvent
//! True if ctrl was also pressed
bool Control:1;
};
//! Any kind of multi touch event.
struct SMultiTouchInput
{
//! A helper function to check if a button is pressed.
u32 touchedCount() const
{
u32 count = 0;
for (u16 i = 0; i < NUMBER_OF_MULTI_TOUCHES; ++i)
{
if (Touched[i])
count++;
}
return count;
}
//! Reset variables.
void clear()
{
for (u16 i = 0; i < NUMBER_OF_MULTI_TOUCHES; ++i)
{
Touched[i] = 0;
X[i] = 0;
Y[i] = 0;
PrevX[i] = 0;
PrevY[i] = 0;
}
}
// Status of simple touch.
u8 Touched[NUMBER_OF_MULTI_TOUCHES];
// X position of simple touch.
s32 X[NUMBER_OF_MULTI_TOUCHES];
// Y position of simple touch.
s32 Y[NUMBER_OF_MULTI_TOUCHES];
// Previous X position of simple touch.
s32 PrevX[NUMBER_OF_MULTI_TOUCHES];
// Previous Y position of simple touch.
s32 PrevY[NUMBER_OF_MULTI_TOUCHES];
//! Type of multi touch event
EMULTI_TOUCH_INPUT_EVENT Event;
};
//! Any kind of accelerometer event.
struct SAccelerometerEvent
{
// X acceleration.
f64 X;
// Y acceleration.
f64 Y;
// Z acceleration.
f64 Z;
};
//! Any kind of gyroscope event.
struct SGyroscopeEvent
{
// X rotation.
f64 X;
// Y rotation.
f64 Y;
// Z rotation.
f64 Z;
};
//! Any kind of device motion event.
struct SDeviceMotionEvent
{
// X angle - roll.
f64 X;
// Y angle - pitch.
f64 Y;
// Z angle - yaw.
f64 Z;
};
//! A joystick event.
/** Unlike other events, joystick events represent the result of polling
@ -373,7 +473,7 @@ struct SEvent
AXIS_R, // e.g. rudder, or analog 2 stick 2 top to bottom
AXIS_U,
AXIS_V,
NUMBER_OF_AXES = 32
NUMBER_OF_AXES
};
/** A bitmap of button states. You can use IsButtonPressed() to
@ -412,7 +512,6 @@ struct SEvent
}
};
//! Any kind of log event.
struct SLogEvent
{
@ -433,32 +532,19 @@ struct SEvent
s32 UserData2;
};
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
struct SInputMethodEvent
{
//! Parent window handle for IMM functions (Windows only)
void* Handle;
//! Character from Input Method
wchar_t Char;
//! Type of input method event
EINPUT_METHOD_EVENT Event;
};
#endif
EEVENT_TYPE EventType;
union
{
struct SGUIEvent GUIEvent;
struct SMouseInput MouseInput;
struct SKeyInput KeyInput;
struct SMultiTouchInput MultiTouchInput;
struct SAccelerometerEvent AccelerometerEvent;
struct SGyroscopeEvent GyroscopeEvent;
struct SDeviceMotionEvent DeviceMotionEvent;
struct SJoystickEvent JoystickEvent;
struct SLogEvent LogEvent;
struct SUserEvent UserEvent;
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
struct SInputMethodEvent InputMethodEvent;
#endif
};
};
@ -520,14 +606,6 @@ struct SJoystickInfo
//! The presence or absence of a hat cannot be determined.
POV_HAT_UNKNOWN
} PovHat;
//! Set if the name of the joystick is useful:
/** On windows the generic name is useless, since it's always the same
* indepentent of what joystick is connected ("Microsoft PC-joystick driver").
* We will try to get a better name from the registry, but if this should
* fail this flag is set and used by STK. */
bool HasGenericName;
}; // struct SJoystickInfo

View File

@ -45,6 +45,9 @@ enum E_FILE_ARCHIVE_TYPE
//! A wad Archive, Quake2, Halflife
EFAT_WAD = MAKE_IRR_ID('W','A','D', 0),
//! An Android asset file archive
EFAT_ANDROID_ASSET = MAKE_IRR_ID('A','S','S','E'),
//! The type of this archive is unknown
EFAT_UNKNOWN = MAKE_IRR_ID('u','n','k','n')
};

View File

@ -81,6 +81,7 @@ namespace irr
DisplayAdapter = other.DisplayAdapter;
UsePerformanceTimer = other.UsePerformanceTimer;
ForceLegacyDevice = other.ForceLegacyDevice;
PrivateData = other.PrivateData;
return *this;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,166 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_3DS_MESH_FILE_LOADER_H_INCLUDED__
#define __C_3DS_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "ISceneManager.h"
#include "irrString.h"
#include "SMesh.h"
#include "matrix4.h"
namespace irr
{
namespace scene
{
//! Meshloader capable of loading 3ds meshes.
class C3DSMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs);
//! destructor
virtual ~C3DSMeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
// byte-align structures
#include "irrpack.h"
struct ChunkHeader
{
u16 id;
s32 length;
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
struct ChunkData
{
ChunkData() : read(0) {}
ChunkHeader header;
s32 read;
};
struct SCurrentMaterial
{
void clear() {
Material=video::SMaterial();
Name="";
Filename[0]="";
Filename[1]="";
Filename[2]="";
Filename[3]="";
Filename[4]="";
Strength[0]=0.f;
Strength[1]=0.f;
Strength[2]=0.f;
Strength[3]=0.f;
Strength[4]=0.f;
}
video::SMaterial Material;
core::stringc Name;
core::stringc Filename[5];
f32 Strength[5];
};
struct SMaterialGroup
{
SMaterialGroup() : faceCount(0), faces(0) {};
SMaterialGroup(const SMaterialGroup& o)
{
*this = o;
}
~SMaterialGroup()
{
clear();
}
void clear()
{
delete [] faces;
faces = 0;
faceCount = 0;
}
void operator =(const SMaterialGroup& o)
{
MaterialName = o.MaterialName;
faceCount = o.faceCount;
faces = new u16[faceCount];
for (u16 i=0; i<faceCount; ++i)
faces[i] = o.faces[i];
}
core::stringc MaterialName;
u16 faceCount;
u16* faces;
};
bool readChunk(io::IReadFile* file, ChunkData* parent);
bool readMaterialChunk(io::IReadFile* file, ChunkData* parent);
bool readFrameChunk(io::IReadFile* file, ChunkData* parent);
bool readTrackChunk(io::IReadFile* file, ChunkData& data,
IMeshBuffer* mb, const core::vector3df& pivot);
bool readObjectChunk(io::IReadFile* file, ChunkData* parent);
bool readPercentageChunk(io::IReadFile* file, ChunkData* chunk, f32& percentage);
bool readColorChunk(io::IReadFile* file, ChunkData* chunk, video::SColor& out);
void readChunkData(io::IReadFile* file, ChunkData& data);
void readString(io::IReadFile* file, ChunkData& data, core::stringc& out);
void readVertices(io::IReadFile* file, ChunkData& data);
void readIndices(io::IReadFile* file, ChunkData& data);
void readMaterialGroup(io::IReadFile* file, ChunkData& data);
void readTextureCoords(io::IReadFile* file, ChunkData& data);
void composeObject(io::IReadFile* file, const core::stringc& name);
void loadMaterials(io::IReadFile* file);
void cleanUp();
scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem;
f32* Vertices;
u16* Indices;
u32* SmoothingGroups;
core::array<u16> TempIndices;
f32* TCoords;
u16 CountVertices;
u16 CountFaces; // = CountIndices/4
u16 CountTCoords;
core::array<SMaterialGroup> MaterialGroups;
SCurrentMaterial CurrentMaterial;
core::array<SCurrentMaterial> Materials;
core::array<core::stringc> MeshBufferNames;
core::matrix4 TransformationMatrix;
SMesh* Mesh;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -0,0 +1,101 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetFileArchive.h"
#include "CIrrDeviceAndroid.h"
#include <android_native_app_glue.h>
#include <android/native_activity.h>
#include <android/log.h>
namespace irr
{
namespace io
{
CAndroidAssetFileArchive *createAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths)
{
if(!CIrrDeviceAndroid::getAndroidApp())
return NULL;
return new CAndroidAssetFileArchive(ignoreCase, ignorePaths);
}
CAndroidAssetFileArchive::CAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths)
: CFileList("/asset", ignoreCase, ignorePaths)
{
AssetManager = CIrrDeviceAndroid::getAndroidApp()->activity->assetManager;
addDirectory("");
}
CAndroidAssetFileArchive::~CAndroidAssetFileArchive()
{
}
//! get the archive type
E_FILE_ARCHIVE_TYPE CAndroidAssetFileArchive::getType() const
{
return EFAT_ANDROID_ASSET;
}
const IFileList* CAndroidAssetFileArchive::getFileList() const
{
// The assert_manager can not read directory names, so
// for now getFileList does not work as expected.
return this; // Keep the compiler happy
}
//! opens a file by file name
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(const io::path& filename)
{
CAndroidAssetReader *reader = new CAndroidAssetReader(filename);
if(reader->isOpen())
return reader;
reader->drop();
return NULL;
}
//! opens a file by index
IReadFile* CAndroidAssetFileArchive::createAndOpenFile(u32 index)
{
// Since we can't list files, not much sense in giving them an index
}
void CAndroidAssetFileArchive::addDirectory(const io::path &dirname)
{
AAssetDir *dir = AAssetManager_openDir(AssetManager, core::stringc(dirname).c_str());
if(!dir)
return;
addItem(dirname, 0, 0, /*isDir*/true, getFileCount());
while(const char *filename = AAssetDir_getNextFileName(dir))
{
core::stringc full_filename= dirname=="" ? filename
: dirname+"/"+filename;
// We can't get the size without opening the file - so for performance
// reasons we set the file size to 0.
addItem(full_filename, /*offet*/0, /*size*/0, /*isDir*/false,
getFileCount());
}
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

View File

@ -0,0 +1,70 @@
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_ANDROID_ASSET_FILE_ARCHIVE_H_INCLUDED__
#define __C_ANDROID_ASSET_FILE_ARCHIVE_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
#include "IFileArchive.h"
#include "CFileList.h"
#include <android/native_activity.h>
namespace irr
{
namespace io
{
/*!
Android asset file system written August 2012 by J.Henrichs
*/
class CAndroidAssetFileArchive : public virtual IFileArchive,
virtual CFileList
{
public:
//! constructor
CAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths);
//! destructor
virtual ~CAndroidAssetFileArchive();
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const io::path& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const;
//! Add a directory to read files from. Since the Android
//! API does not return names of directories, they need to
//! be added manually.
virtual void addDirectory(const io::path &filename);
protected:
//! Android's asset manager - keep a copy here
AAssetManager *AssetManager;
}; // CAndroidAssetFileArchive
CAndroidAssetFileArchive *createAndroidAssetFileArchive(bool ignoreCase=false,
bool ignorePaths=false);
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
#endif // __C_ANDROID_ASSET_READER_H_INCLUDED__

View File

@ -0,0 +1,72 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "CAndroidAssetReader.h"
#include "CReadFile.h"
#include "coreutil.h"
#include "CAndroidAssetReader.h"
#include "CIrrDeviceAndroid.h"
#include <android_native_app_glue.h>
#include <android/native_activity.h>
#include <android/log.h>
namespace irr
{
namespace io
{
CAndroidAssetReader::CAndroidAssetReader(const io::path &filename)
{
AssetManager = CIrrDeviceAndroid::getAndroidApp()->activity->assetManager;
Asset = AAssetManager_open(AssetManager,
core::stringc(filename).c_str(),
AASSET_MODE_RANDOM);
Filename = filename;
}
CAndroidAssetReader::~CAndroidAssetReader()
{
if(Asset)
AAsset_close(Asset);
}
s32 CAndroidAssetReader::read(void* buffer, u32 sizeToRead)
{
return AAsset_read(Asset, buffer, sizeToRead);
}
bool CAndroidAssetReader::seek(long finalPos, bool relativeMovement)
{
long off = AAsset_seek(Asset, finalPos, relativeMovement ? SEEK_CUR
: SEEK_SET);
return off = relativeMovement-1;
}
long CAndroidAssetReader::getSize() const
{
return AAsset_getLength(Asset);
}
long CAndroidAssetReader::getPos() const
{
return AAsset_getLength(Asset) - AAsset_getRemainingLength(Asset);
}
const io::path& CAndroidAssetReader::getFileName() const
{
return Filename;
}
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_

View File

@ -0,0 +1,74 @@
// Copyright (C) 2012 Joerg Henrichs
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_ANDROID_ASSET_READER_H_INCLUDED__
#define __C_ANDROID_ASSET_READER_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_ANDROID_ASSET_READER_
#include "IReadFile.h"
struct AAssetManager;
struct AAsset;
namespace irr
{
namespace io
{
class CAndroidAssetReader : public virtual IReadFile
{
public:
CAndroidAssetReader(const io::path &filename);
virtual ~CAndroidAssetReader();
//! Reads an amount of bytes from the file.
/** \param buffer Pointer to buffer where read bytes are written to.
\param sizeToRead Amount of bytes to read from the file.
\return How many bytes were read. */
virtual s32 read(void* buffer, u32 sizeToRead);
//! Changes position in file
/** \param finalPos Destination position in the file.
\param relativeMovement If set to true, the position in the file is
changed relative to current position. Otherwise the position is changed
from beginning of file.
\return True if successful, otherwise false. */
virtual bool seek(long finalPos, bool relativeMovement = false);
//! Get size of file.
/** \return Size of the file in bytes. */
virtual long getSize() const;
//! Get the current position in the file.
/** \return Current position in the file in bytes. */
virtual long getPos() const;
//! Get name of file.
/** \return File name as zero terminated character string. */
virtual const io::path& getFileName() const;
/** Return true if the file could be opened. */
bool isOpen() const { return Asset!=NULL; }
protected:
//! Android's asset manager - keep a copy here
AAssetManager *AssetManager;
// An asset, i.e. file
AAsset *Asset;
path Filename;
};
} // end namespace io
} // end namespace irr
#endif // _IRR_COMPILE_ANDROID_ASSET_READER_
#endif // __C_ANDROID_ASSET_READER_H_INCLUDED__

View File

@ -0,0 +1,448 @@
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// Copyright (C) 2007-2011 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CIrrDeviceAndroid.h"
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <assert.h>
#include "os.h"
#include "CFileSystem.h"
#include "CAndroidAssetFileArchive.h"
namespace irr
{
namespace video
{
IVideoDriver* createOGLES1Driver(const SIrrlichtCreationParameters& params,
video::SExposedVideoData& data, io::IFileSystem* io);
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
video::SExposedVideoData& data, io::IFileSystem* io);
}
}
namespace irr
{
android_app* CIrrDeviceAndroid::Android = NULL;
#include <android/log.h>
//! constructor
CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
: CIrrDeviceStub(param),
Animating(false),
IsReady(false),
IsClosing(false),
DeviceWidth(param.WindowSize.Width),
DeviceHeight(param.WindowSize.Height),
MouseX(0),
MouseY(0)
{
int ident;
int events;
struct android_poll_source* source;
#ifdef _DEBUG
setDebugName("CIrrDeviceAndroid");
#endif
// Get the interface to the native Android activity.
Android = (android_app *)(param.PrivateData);
// Set the private data so we can use it in any static callbacks.
Android->userData = this;
// Set the default command handler. This is a callback function
// that the Android OS invokes to send the native activity
// messages.
Android->onAppCmd = handleAndroidCommand;
// Create a sensor manager to recieve touch screen events from the
// java acivity.
SensorManager = ASensorManager_getInstance();
SensorEventQueue = ASensorManager_createEventQueue(
SensorManager, Android->looper,
LOOPER_ID_USER, NULL, NULL);
Android->onInputEvent = handleInput;
// Need to find a better way of doing this... but poll until the
// Android activity has been created and a window is open. The device
// cannot be created until the main window has been created by the
// Android OS.
os::Printer::log("Waiting for Android activity window to be created.", ELL_DEBUG);
do
{
while( (ident = ALooper_pollAll( 0, NULL, &events,(void**)&source)) >= 0 )
{
// Process this event.
if( source != NULL )
{
source->process( Android, source );
}
}
}
while( IsReady == false );
assert( Android->window );
// Create cursor control
CursorControl = new CCursorControl(this);
// Create the driver.
createDriver();
if (VideoDriver)
createGUIAndScene();
io::CAndroidAssetFileArchive *assets = io::createAndroidAssetFileArchive(false, false);
assets->addDirectory("media");
FileSystem->addFileArchive(assets);
// TODO
//
// if engine->app->savedState is not NULL then use postEventFromUser()
// with a custom android event so the user can use their own event
// receiver in order to load the apps previous state.
// The message should have a pointer to be filled and a size variable
// of how much data has been saved. Android free's this data later so
// there's no need to free it manually.
Animating = true;
}
CIrrDeviceAndroid::~CIrrDeviceAndroid(void)
{
}
void CIrrDeviceAndroid::createDriver( void )
{
video::SExposedVideoData data;
// Create the driver.
switch(CreationParams.DriverType)
{
case video::EDT_OGLES1:
#ifdef _IRR_COMPILE_WITH_OGLES1_
VideoDriver = video::createOGLES1Driver(CreationParams, data, FileSystem);
#else
os::Printer::log("No OpenGL ES 1.0 support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_OGLES2:
#ifdef _IRR_COMPILE_WITH_OGLES2_
VideoDriver = video::createOGLES2Driver(CreationParams, data, FileSystem);
#else
os::Printer::log("No OpenGL ES 2.0 support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_NULL:
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
break;
default:
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
}
}
bool CIrrDeviceAndroid::run( void )
{
bool close = false;
// Read all pending events.
int ident;
int events;
struct android_poll_source* source;
// Check if Android is trying to shut us down.
if( IsClosing == true )
return( false );
// If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue
// to draw the next frame of animation.
while( ( ident = ALooper_pollAll( ( Animating || IsClosing ) ? 0 : -1,
NULL, &events,
(void**)&source)) >= 0 )
{
// Process this event.
if( source != NULL )
{
source->process( Android, source );
}
#if 0
// If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) {
if (engine.accelerometerSensor != NULL) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
&event, 1) > 0) {
DEBUG_INFO1("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
}
}
}
#endif
// Check if we are exiting.
if( Android->destroyRequested != 0 )
{
close = true;
}
}
os::Timer::tick();
return( !close );
}
void CIrrDeviceAndroid::yield( void )
{
}
void CIrrDeviceAndroid::sleep( u32 timeMs, bool pauseTimer )
{
}
void CIrrDeviceAndroid::setWindowCaption(const wchar_t* text)
{
}
bool CIrrDeviceAndroid::present(video::IImage* surface, void* windowId, core::rect<s32>* srcClip)
{
return( true );
}
bool CIrrDeviceAndroid::isWindowActive( void ) const
{
return( true );
}
bool CIrrDeviceAndroid::isWindowFocused( void ) const
{
return( false );
}
bool CIrrDeviceAndroid::isWindowMinimized( void ) const
{
return( false );
}
void CIrrDeviceAndroid::closeDevice( void )
{
}
void CIrrDeviceAndroid::setResizable( bool resize )
{
}
void CIrrDeviceAndroid::minimizeWindow( void )
{
}
void CIrrDeviceAndroid::maximizeWindow( void )
{
}
void CIrrDeviceAndroid::restoreWindow( void )
{
}
E_DEVICE_TYPE CIrrDeviceAndroid::getType( void ) const
{
return( EIDT_ANDROID );
}
///////////////////////////////
///////////////////////////////
void CIrrDeviceAndroid::handleAndroidCommand( struct android_app* app, s32 cmd )
{
CIrrDeviceAndroid *deviceAndroid = (CIrrDeviceAndroid *)app->userData;
switch (cmd)
{
case APP_CMD_SAVE_STATE:
os::Printer::log("Android command APP_CMD_SAVE_STATE", ELL_DEBUG);
// TODO
//
// use postEventFromUser() with a custom android event so the user can
// use their own event receiver in order to save the apps state.
// The message should have a pointer to be filled and a size variable
// of ho emuch data has been saved.
#if 0
// The system has asked us to save our current state. Do so.
engine->app->savedState = malloc(sizeof(struct saved_state));
*((struct saved_state*)engine->app->savedState) = engine->state;
engine->app->savedStateSize = sizeof(struct saved_state);
#endif
break;
case APP_CMD_INIT_WINDOW:
os::Printer::log("Android command APP_CMD_INIT_WINDOW", ELL_DEBUG);
deviceAndroid->IsReady = true;
break;
case APP_CMD_TERM_WINDOW:
os::Printer::log("Android command APP_CMD_TERM_WINDOW", ELL_DEBUG);
break;
case APP_CMD_GAINED_FOCUS:
os::Printer::log("Android command APP_CMD_GAINED_FOCUS", ELL_DEBUG);
#if 0
// When our app gains focus, we start monitoring the accelerometer.
if (engine->accelerometerSensor != NULL) {
ASensorEventQueue_enableSensor(engine->sensorEventQueue,
engine->accelerometerSensor);
// We'd like to get 60 events per second (in us).
ASensorEventQueue_setEventRate(engine->sensorEventQueue,
engine->accelerometerSensor, (1000L/60)*1000);
}
#endif
deviceAndroid->Animating = true;
break;
case APP_CMD_LOST_FOCUS:
os::Printer::log("Android command APP_CMD_LOST_FOCUS", ELL_DEBUG);
// When our app loses focus, we stop monitoring the accelerometer.
// This is to avoid consuming battery while not being used.
#if 0
if (engine->accelerometerSensor != NULL) {
ASensorEventQueue_disableSensor(engine->sensorEventQueue,
engine->accelerometerSensor);
}
#endif
// Also stop animating.
deviceAndroid->Animating = false;
break;
case APP_CMD_DESTROY:
// The application is being destroyed. We must close the native
// acitivity code and clean up otherwise the acitivity will stay
// active.
os::Printer::log("Android command APP_CMD_DESTROY", ELL_DEBUG);
deviceAndroid->IsClosing = true;
break;
case APP_CMD_PAUSE:
os::Printer::log("Android command APP_CMD_PAUSE", ELL_DEBUG);
break;
case APP_CMD_STOP:
os::Printer::log("Android command APP_CMD_STOP", ELL_DEBUG);
break;
case APP_CMD_RESUME:
os::Printer::log("Android command APP_CMD_RESUME", ELL_DEBUG);
break;
default:
os::Printer::log("Unhandled android command",
core::stringc(cmd).c_str(), ELL_WARNING );
}
}
s32 CIrrDeviceAndroid::handleInput( struct android_app* app, AInputEvent* androidEvent )
{
CIrrDeviceAndroid *deviceAndroid = (CIrrDeviceAndroid *)app->userData;
int32_t eventAction;
int pointerCount = 0;
SEvent irrEvent;
int i = 0;
if( AInputEvent_getType( androidEvent ) == AINPUT_EVENT_TYPE_MOTION )
{
// Get the number of pointers.
pointerCount = AMotionEvent_getPointerCount( androidEvent );
// Get the actual input event type.
eventAction = AMotionEvent_getAction( androidEvent );
switch( eventAction )
{
case AMOTION_EVENT_ACTION_DOWN:
if( pointerCount == 1 )
{
irrEvent.EventType = EET_MOUSE_INPUT_EVENT;
irrEvent.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN;
}
break;
case AMOTION_EVENT_ACTION_MOVE:
if( pointerCount == 1 )
{
irrEvent.EventType = EET_MOUSE_INPUT_EVENT;
irrEvent.MouseInput.Event = EMIE_MOUSE_MOVED;
}
else
{
irrEvent.EventType = EET_MULTI_TOUCH_EVENT;
irrEvent.MultiTouchInput.Event = EMTIE_MOVED;
}
deviceAndroid->postEventFromUser(irrEvent);
break;
case AMOTION_EVENT_ACTION_UP:
if( pointerCount == 1 )
{
irrEvent.EventType = EET_MOUSE_INPUT_EVENT;
irrEvent.MouseInput.Event = EMIE_LMOUSE_LEFT_UP;
}
break;
default:
os::Printer::log("Unhandled motion event",
core::stringc(eventAction).c_str(),
ELL_WARNING );
}
if( pointerCount == 1 )
{
// Fill in the details for a one touch event.
deviceAndroid->MouseX = irrEvent.MouseInput.X = AMotionEvent_getX(androidEvent, 0);
deviceAndroid->MouseY = irrEvent.MouseInput.Y = AMotionEvent_getY(androidEvent, 0);
irrEvent.MouseInput.ButtonStates = 0;
}
else if( pointerCount > 1 )
{
// Fill in the details for a multi touch event.
for( i=0 ; i<pointerCount ; i++ )
{
irrEvent.MultiTouchInput.Touched[i] = 1;
irrEvent.MultiTouchInput.PrevX[i] = irrEvent.MultiTouchInput.X[i];
irrEvent.MultiTouchInput.PrevY[i] = irrEvent.MultiTouchInput.Y[i];
irrEvent.MultiTouchInput.X[i] = AMotionEvent_getX(androidEvent, i);
irrEvent.MultiTouchInput.Y[i] = AMotionEvent_getY(androidEvent, i);
}
// Reset the data for the rest of the pointers that aren't being used.
for( ;i<NUMBER_OF_MULTI_TOUCHES ; i++ )
{
irrEvent.MultiTouchInput.Touched[i] = 0;
irrEvent.MultiTouchInput.PrevX[i] = 0;
irrEvent.MultiTouchInput.PrevY[i] = 0;
irrEvent.MultiTouchInput.X[i] = 0;
irrEvent.MultiTouchInput.Y[i] = 0;
}
}
else
{
// Shouldn't ever get here, but just in case...
os::Printer::log("We had a input event but no pointers were active!", ELL_DEBUG);
return( 0 );
}
deviceAndroid->postEventFromUser(irrEvent);
return( 1 );
}
return( 0 );
}
} // end namespace irr
#endif

View File

@ -0,0 +1,157 @@
// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_IRR_DEVICE_ANDROID_H_INCLUDED__
#define __C_IRR_DEVICE_ANDROID_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <android/sensor.h>
#include <android_native_app_glue.h>
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IImagePresenter.h"
#include "ICursorControl.h"
namespace irr
{
class CIrrDeviceAndroid : public CIrrDeviceStub, video::IImagePresenter
{
public:
//! constructor
CIrrDeviceAndroid(const SIrrlichtCreationParameters& param);
//! destructor
virtual ~CIrrDeviceAndroid();
virtual bool run( void );
virtual void yield( void );
virtual void sleep( u32 timeMs, bool pauseTimer=false );
virtual void setWindowCaption(const wchar_t* text);
virtual bool present(video::IImage* surface, void* windowId, core::rect<s32>* srcClip) ;
virtual bool isWindowActive( void ) const;
virtual bool isWindowFocused( void ) const;
virtual bool isWindowMinimized( void ) const;
virtual void closeDevice( void );
virtual void setResizable( bool resize=false );
virtual void minimizeWindow( void );
virtual void maximizeWindow( void );
virtual void restoreWindow( void );
virtual E_DEVICE_TYPE getType( void ) const;
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{
public:
CCursorControl(CIrrDeviceAndroid* dev)
: Device(dev), IsVisible(true)
{
}
//! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible)
{
IsVisible = visible;
//if ( visible )
// SDL_ShowCursor( SDL_ENABLE );
//else
// SDL_ShowCursor( SDL_DISABLE );
}
//! Returns if the cursor is currently visible.
virtual bool isVisible() const
{
return IsVisible;
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<f32> &pos)
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(f32 x, f32 y)
{
setPosition((s32)(x*Device->DeviceWidth), (s32)(y*Device->DeviceHeight));
}
//! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<s32> &pos)
{
setPosition(pos.X, pos.Y);
}
//! Sets the new position of the cursor.
virtual void setPosition(s32 x, s32 y)
{
//SDL_WarpMouse( x, y );
}
//! Returns the current position of the mouse cursor.
virtual const core::position2d<s32>& getPosition()
{
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<f32> getRelativePosition()
{
updateCursorPos();
return core::position2d<f32>(CursorPos.X / (f32)Device->DeviceWidth,
CursorPos.Y / (f32)Device->DeviceHeight);
}
virtual void setReferenceRect(core::rect<s32>* rect=0)
{
}
private:
void updateCursorPos()
{
CursorPos.X = Device->MouseX;
CursorPos.Y = Device->MouseY;
if (CursorPos.X < 0)
CursorPos.X = 0;
if (CursorPos.X > (s32)Device->DeviceWidth)
CursorPos.X = Device->DeviceWidth;
if (CursorPos.Y < 0)
CursorPos.Y = 0;
if (CursorPos.Y > (s32)Device->DeviceHeight)
CursorPos.Y = Device->DeviceHeight;
}
CIrrDeviceAndroid* Device;
core::position2d<s32> CursorPos;
bool IsVisible;
};
static android_app *getAndroidApp() { return Android; }
private:
static android_app *Android;
ASensorManager *SensorManager;
ASensorEventQueue *SensorEventQueue;
bool Animating;
bool IsReady;
bool IsClosing;
u32 DeviceWidth, DeviceHeight;
u32 MouseX, MouseY;
void createDriver( void );
static void handleAndroidCommand( struct android_app* app, s32 cmd );
static s32 handleInput( struct android_app* app, AInputEvent* event );
};
} // end namespace irr
#endif // _IRR_COMPILE_WITH_ANDROID_DEVICE_
#endif // __C_IRR_DEVICE_ANDROID_H_INCLUDED__

View File

@ -17,6 +17,8 @@
#include <SDL/SDL.h>
#endif
#include <android/log.h>
namespace irr
{
namespace video
@ -41,6 +43,8 @@ COGLES1Driver::COGLES1Driver(const SIrrlichtCreationParameters& params,
,ViewDepthRenderbuffer(0)
#endif
{
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "frame %d", __LINE__);
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "frame %s %d", __FILE__, __LINE__);
#ifdef _DEBUG
setDebugName("COGLESDriver");
#endif
@ -55,8 +59,11 @@ COGLES1Driver::COGLES1Driver(const SIrrlichtCreationParameters& params,
#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
Device = device;
#elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "frame %s %d", __FILE__, __LINE__);
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "frame %d %d", __LINE__, ((struct android_app *)(params.PrivateData)));
EglWindow = ((struct android_app *)(params.PrivateData))->window;
EglDisplay = EGL_NO_DISPLAY;
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "frame %s %d", __FILE__, __LINE__);
#endif
#ifdef EGL_VERSION_1_0
if(EglDisplay == EGL_NO_DISPLAY)

View File

@ -70,6 +70,14 @@
//! Enable debug features
#define SCENEMANAGER_DEBUG
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
#include "C3DSMeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_X_LOADER_
#include "CXMeshFileLoader.h"
#endif
namespace irr
{
namespace scene
@ -126,6 +134,13 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
#endif
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
MeshLoaderList.push_back(new C3DSMeshFileLoader(this, FileSystem));
#endif
#ifdef _IRR_COMPILE_WITH_X_LOADER_
MeshLoaderList.push_back(new CXMeshFileLoader(this, FileSystem));
#endif
// factories

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,198 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_X_MESH_FILE_LOADER_H_INCLUDED__
#define __C_X_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "irrString.h"
#include "CSkinnedMesh.h"
namespace irr
{
namespace io
{
class IFileSystem;
class IReadFile;
} // end namespace io
namespace scene
{
class IMeshManipulator;
//! Meshloader capable of loading x meshes.
class CXMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
struct SXTemplateMaterial
{
core::stringc Name; // template name from Xfile
video::SMaterial Material; // material
};
struct SXMesh
{
SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false), HasVertexColors(false) {}
// this mesh contains triangulated texture data.
// because in an .x file, faces can be made of more than 3
// vertices, the indices data structure is triangulated during the
// loading process. The IndexCountPerFace array is filled during
// this triangulation process and stores how much indices belong to
// every face. This data structure can be ignored, because all data
// in this structure is triangulated.
core::stringc Name;
u32 MaxSkinWeightsPerVertex;
u32 MaxSkinWeightsPerFace;
u32 BoneCount;
core::array<u16> IndexCountPerFace; // default 3, but could be more
core::array<scene::SSkinMeshBuffer*> Buffers;
core::array<video::S3DVertex> Vertices;
core::array<core::vector2df> TCoords2;
core::array<u32> Indices;
core::array<u32> FaceMaterialIndices; // index of material for each face
core::array<video::SMaterial> Materials; // material array
core::array<u32> WeightJoint;
core::array<u32> WeightNum;
s32 AttachedJointID;
bool HasSkinning;
bool HasVertexColors;
};
private:
bool load(io::IReadFile* file);
bool readFileIntoMemory(io::IReadFile* file);
bool parseFile();
bool parseDataObject();
bool parseDataObjectTemplate();
bool parseDataObjectFrame(CSkinnedMesh::SJoint *parent);
bool parseDataObjectTransformationMatrix(core::matrix4 &mat);
bool parseDataObjectMesh(SXMesh &mesh);
bool parseDataObjectSkinWeights(SXMesh &mesh);
bool parseDataObjectSkinMeshHeader(SXMesh &mesh);
bool parseDataObjectMeshNormals(SXMesh &mesh);
bool parseDataObjectMeshTextureCoords(SXMesh &mesh);
bool parseDataObjectMeshVertexColors(SXMesh &mesh);
bool parseDataObjectMeshMaterialList(SXMesh &mesh);
bool parseDataObjectMaterial(video::SMaterial& material);
bool parseDataObjectAnimationSet();
bool parseDataObjectAnimation();
bool parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint);
bool parseDataObjectTextureFilename(core::stringc& texturename);
bool parseUnknownDataObject();
//! places pointer to next begin of a token, and ignores comments
void findNextNoneWhiteSpace();
//! places pointer to next begin of a token, which must be a number,
// and ignores comments
void findNextNoneWhiteSpaceNumber();
//! returns next parseable token. Returns empty string if no token there
core::stringc getNextToken();
//! reads header of dataobject including the opening brace.
//! returns false if error happened, and writes name of object
//! if there is one
bool readHeadOfDataObject(core::stringc* outname=0);
//! checks for closing curly brace, returns false if not there
bool checkForClosingBrace();
//! checks for one following semicolons, returns false if not there
bool checkForOneFollowingSemicolons();
//! checks for two following semicolons, returns false if they are not there
bool checkForTwoFollowingSemicolons();
//! reads a x file style string
bool getNextTokenAsString(core::stringc& out);
void readUntilEndOfLine();
u16 readBinWord();
u32 readBinDWord();
u32 readInt();
f32 readFloat();
bool readVector2(core::vector2df& vec);
bool readVector3(core::vector3df& vec);
bool readMatrix(core::matrix4& mat);
bool readRGB(video::SColor& color);
bool readRGBA(video::SColor& color);
ISceneManager* SceneManager;
io::IFileSystem* FileSystem;
core::array<CSkinnedMesh::SJoint*> *AllJoints;
CSkinnedMesh* AnimatedMesh;
c8* Buffer;
const c8* P;
c8* End;
// counter for number arrays in binary format
u32 BinaryNumCount;
u32 Line;
io::path FilePath;
CSkinnedMesh::SJoint *CurFrame;
core::array<SXMesh*> Meshes;
core::array<SXTemplateMaterial> TemplateMaterials;
u32 MajorVersion;
u32 MinorVersion;
bool BinaryFormat;
c8 FloatSize;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -4,7 +4,7 @@
#include "IrrCompileConfig.h"
//static const char* const copyright = "Irrlicht Engine (c) 2002-2012 Nikolaus Gebhardt";
static const char* const copyright = "Irrlicht Engine (c) 2002-2012 Nikolaus Gebhardt";
#ifdef _IRR_WINDOWS_
#include <windows.h>
@ -30,6 +30,10 @@
#include "CIrrDeviceLinux.h"
#endif
#ifdef _IRR_COMPILE_WITH_IPHONE_DEVICE_
#include "iOS/CIrrDeviceiOS.h"
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
#include "CIrrDeviceSDL.h"
#endif
@ -42,14 +46,18 @@
#include "CIrrDeviceConsole.h"
#endif
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include "CIrrDeviceAndroid.h"
#include <android/log.h>
#endif
namespace irr
{
//! stub for calling createDeviceEx
IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType,
const core::dimension2d<u32>& windowSize,
u32 bits, bool fullscreen,
bool stencilbuffer, bool vsync, IEventReceiver* res,
io::IFileSystem *file_system)
bool stencilbuffer, bool vsync, IEventReceiver* res)
{
SIrrlichtCreationParameters p;
p.DriverType = driverType;
@ -59,7 +67,6 @@ namespace irr
p.Stencilbuffer = stencilbuffer;
p.Vsync = vsync;
p.EventReceiver = res;
p.FileSystem = file_system;
return createDeviceEx(p);
}
@ -88,6 +95,11 @@ namespace irr
if (params.DeviceType == EIDT_X11 || (!dev && params.DeviceType == EIDT_BEST))
dev = new CIrrDeviceLinux(params);
#endif
#ifdef _IRR_COMPILE_WITH_IPHONE_DEVICE_
if (params.DeviceType == EIDT_IPHONE || (!dev && params.DeviceType == EIDT_BEST))
dev = new CIrrDeviceIPhone(params);
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST))
@ -99,6 +111,12 @@ namespace irr
dev = new CIrrDeviceFB(params);
#endif
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
if (params.DeviceType == EIDT_ANDROID || (!dev && params.DeviceType == EIDT_BEST)) {
dev = new CIrrDeviceAndroid(params);
}
#endif
#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_
if (params.DeviceType == EIDT_CONSOLE || (!dev && params.DeviceType == EIDT_BEST))
dev = new CIrrDeviceConsole(params);
@ -129,7 +147,7 @@ namespace video
} // end namespace irr
#if defined(_IRR_WINDOWS_API_) && !defined(_IRR_STATIC_LIB_)
#if defined(_IRR_WINDOWS_API_)
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,

View File

@ -142,6 +142,7 @@ namespace os
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <android/log.h>
namespace irr
{
@ -176,24 +177,30 @@ namespace os
void Printer::log(const c8* message, ELOG_LEVEL ll)
{
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "%s", message);
if (Logger)
Logger->log(message, ll);
}
void Printer::log(const wchar_t* message, ELOG_LEVEL ll)
{
char test[200];
wcstombs(test, message, 200);
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "%s", test);
if (Logger)
Logger->log(message, ll);
}
void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll)
{
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "%s %s", message, hint);
if (Logger)
Logger->log(message, hint, ll);
}
void Printer::log(const c8* message, const io::path& hint, ELOG_LEVEL ll)
{
__android_log_print(ANDROID_LOG_VERBOSE, "native-activity", "%s %s", message, core::stringc(hint).c_str());
if (Logger)
Logger->log(message, hint.c_str(), ll);
}