Merge remote-tracking branch 'refs/remotes/origin/master' into gui
This commit is contained in:
@@ -742,7 +742,7 @@ namespace Nz
|
||||
Vector3f halfLengths = lengths/2.f;
|
||||
|
||||
// Face +X
|
||||
transform.MakeTransform(Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, 0.f, -90.f));
|
||||
transform.MakeTransform(Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, -90.f, 180.f));
|
||||
GeneratePlane(Vector2ui(subdivision.z, subdivision.y), Vector2f(lengths.z, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset);
|
||||
indexOffset += xVertexCount;
|
||||
indices += xIndexCount;
|
||||
@@ -776,7 +776,7 @@ namespace Nz
|
||||
vertexPointers.uvPtr += yVertexCount;
|
||||
|
||||
// Face +Z
|
||||
transform.MakeTransform(Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(-90.f, 90.f, 90.f));
|
||||
transform.MakeTransform(Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(90.f, 0.f, 0.f));
|
||||
GeneratePlane(Vector2ui(subdivision.x, subdivision.y), Vector2f(lengths.x, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset);
|
||||
indexOffset += zVertexCount;
|
||||
indices += zIndexCount;
|
||||
@@ -793,7 +793,7 @@ namespace Nz
|
||||
vertexPointers.uvPtr += zVertexCount;
|
||||
|
||||
// Face -X
|
||||
transform.MakeTransform(-Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, 0.f, 90.f));
|
||||
transform.MakeTransform(-Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, 90.f, 180.f));
|
||||
GeneratePlane(Vector2ui(subdivision.z, subdivision.y), Vector2f(lengths.z, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset);
|
||||
indexOffset += xVertexCount;
|
||||
indices += xIndexCount;
|
||||
@@ -810,7 +810,7 @@ namespace Nz
|
||||
vertexPointers.uvPtr += xVertexCount;
|
||||
|
||||
// Face -Y
|
||||
transform.MakeTransform(-Vector3f::UnitY() * halfLengths.y, EulerAnglesf(0.f, 0.f, 180.f));
|
||||
transform.MakeTransform(-Vector3f::UnitY() * halfLengths.y, EulerAnglesf(0.f, 180.f, 180.f));
|
||||
GeneratePlane(Vector2ui(subdivision.x, subdivision.z), Vector2f(lengths.x, lengths.z), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset);
|
||||
indexOffset += yVertexCount;
|
||||
indices += yIndexCount;
|
||||
@@ -827,7 +827,7 @@ namespace Nz
|
||||
vertexPointers.uvPtr += yVertexCount;
|
||||
|
||||
// Face -Z
|
||||
transform.MakeTransform(-Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(-90.f, -90.f, 90.f));
|
||||
transform.MakeTransform(-Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(90.f, 180.f, 0.f));
|
||||
GeneratePlane(Vector2ui(subdivision.x, subdivision.y), Vector2f(lengths.x, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset);
|
||||
indexOffset += zVertexCount;
|
||||
indices += zIndexCount;
|
||||
|
||||
@@ -174,15 +174,15 @@ namespace Nz
|
||||
if (header.format.flags & DDPF_RGB)
|
||||
{
|
||||
// Reverse bits for our masks
|
||||
info.redMask = ReverseBits(header.format.redMask);
|
||||
info.greenMask = ReverseBits(header.format.greenMask);
|
||||
info.blueMask = ReverseBits(header.format.blueMask);
|
||||
info.redMask = header.format.redMask;
|
||||
info.greenMask = header.format.greenMask;
|
||||
info.blueMask = header.format.blueMask;
|
||||
}
|
||||
else if (header.format.flags & DDPF_LUMINANCE)
|
||||
info.redMask = ReverseBits(header.format.redMask);
|
||||
info.redMask = header.format.redMask;
|
||||
|
||||
if (header.format.flags & (DDPF_ALPHA | DDPF_ALPHAPIXELS))
|
||||
info.alphaMask = ReverseBits(header.format.alphaMask);
|
||||
info.alphaMask = header.format.alphaMask;
|
||||
|
||||
*format = PixelFormat::IdentifyFormat(info);
|
||||
if (!PixelFormat::IsValid(*format))
|
||||
|
||||
@@ -81,15 +81,14 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Création du mesh
|
||||
// Le moteur ne supporte plus les animations image-clé, nous ne pouvons charger qu'en statique
|
||||
if (!mesh->CreateStatic()) // Ne devrait jamais échouer
|
||||
// Since the engine no longer supports keyframe animations, let's make a static mesh
|
||||
if (!mesh->CreateStatic())
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des skins
|
||||
// Extract skins (texture name)
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
mesh->SetMaterialCount(header.num_skins);
|
||||
@@ -109,16 +108,15 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, BufferUsage_Static);
|
||||
|
||||
/// Lecture des triangles
|
||||
// Extract triangles data
|
||||
std::vector<MD2_Triangle> triangles(header.num_tris);
|
||||
|
||||
stream.SetCursorPos(header.offset_tris);
|
||||
stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle));
|
||||
|
||||
// And convert them into an index buffer
|
||||
BufferMapper<IndexBuffer> indexMapper(indexBuffer, BufferAccess_DiscardAndWrite);
|
||||
UInt16* index = static_cast<UInt16*>(indexMapper.GetPointer());
|
||||
|
||||
@@ -135,7 +133,7 @@ namespace Nz
|
||||
SwapBytes(&triangles[i].texCoords[2], sizeof(UInt16));
|
||||
#endif
|
||||
|
||||
// On respécifie le triangle dans l'ordre attendu
|
||||
// Reverse winding order
|
||||
*index++ = triangles[i].vertices[0];
|
||||
*index++ = triangles[i].vertices[2];
|
||||
*index++ = triangles[i].vertices[1];
|
||||
@@ -143,10 +141,11 @@ namespace Nz
|
||||
|
||||
indexMapper.Unmap();
|
||||
|
||||
// Optimize if requested (improves cache locality)
|
||||
if (parameters.optimizeIndexBuffers)
|
||||
indexBuffer->Optimize();
|
||||
|
||||
/// Lecture des coordonnées de texture
|
||||
// Extracting texture coordinates
|
||||
std::vector<MD2_TexCoord> texCoords(header.num_st);
|
||||
|
||||
stream.SetCursorPos(header.offset_st);
|
||||
@@ -168,15 +167,15 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des vertices
|
||||
// Extracting vertices
|
||||
stream.SetCursorPos(header.offset_frames);
|
||||
|
||||
std::unique_ptr<MD2_Vertex[]> vertices(new MD2_Vertex[header.num_vertices]);
|
||||
std::vector<MD2_Vertex> vertices(header.num_vertices);
|
||||
Vector3f scale, translate;
|
||||
stream.Read(scale, sizeof(Vector3f));
|
||||
stream.Read(translate, sizeof(Vector3f));
|
||||
stream.Read(nullptr, 16*sizeof(char)); // Nom de la frame, inutile ici
|
||||
stream.Read(vertices.get(), header.num_vertices*sizeof(MD2_Vertex));
|
||||
stream.Read(nullptr, 16*sizeof(char)); //< Frame name, unused
|
||||
stream.Read(vertices.data(), header.num_vertices*sizeof(MD2_Vertex));
|
||||
|
||||
#ifdef NAZARA_BIG_ENDIAN
|
||||
SwapBytes(&scale.x, sizeof(float));
|
||||
@@ -196,23 +195,26 @@ namespace Nz
|
||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite);
|
||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
|
||||
/// Chargement des coordonnées de texture
|
||||
const unsigned int indexFix[3] = {0, 2, 1}; // Pour respécifier les indices dans le bon ordre
|
||||
// Loading texture coordinates
|
||||
const unsigned int indexFix[3] = {0, 2, 1};
|
||||
Vector2f invSkinSize(1.f / header.skinwidth, 1.f / header.skinheight);
|
||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < 3; ++j)
|
||||
{
|
||||
const unsigned int fixedIndex = indexFix[j];
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
float u = static_cast<float>(texC.u) / header.skinwidth;
|
||||
float v = static_cast<float>(texC.v) / header.skinheight;
|
||||
const unsigned int fixedIndex = indexFix[j]; //< Reverse winding order
|
||||
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v);
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
Vector2f uv(texC.u, texC.v);
|
||||
uv *= invSkinSize;
|
||||
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des positions
|
||||
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
|
||||
// Loading vertex position
|
||||
|
||||
// Align the model to our coordinates system
|
||||
Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f);
|
||||
Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale);
|
||||
matrix *= parameters.matrix;
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
vertices->position = finalPos;
|
||||
vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé
|
||||
vertices->uv.Set(parameters.texCoordOffset + vertex.uv * parameters.texCoordScale);
|
||||
vertices++;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Nz
|
||||
VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage);
|
||||
BufferMapper<VertexBuffer> vertexMapper(vertexBuffer, BufferAccess_WriteOnly);
|
||||
|
||||
MeshVertex* vertex = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
MeshVertex* vertices = static_cast<MeshVertex*>(vertexMapper.GetPointer());
|
||||
for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices)
|
||||
{
|
||||
// Skinning MD5 (Formule d'Id Tech)
|
||||
@@ -268,9 +268,9 @@ namespace Nz
|
||||
}
|
||||
|
||||
// On retourne le modèle dans le bon sens
|
||||
vertex->position = matrix * finalPos;
|
||||
vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé
|
||||
vertex++;
|
||||
vertices->position = matrix * finalPos;
|
||||
vertices->uv.Set(parameters.texCoordOffset + md5Vertex.uv * parameters.texCoordScale);
|
||||
vertices++;
|
||||
}
|
||||
|
||||
vertexMapper.Unmap();
|
||||
|
||||
@@ -331,19 +331,19 @@ namespace Nz
|
||||
Emit(mat.specular.b / 255.f);
|
||||
EmitLine();
|
||||
|
||||
if (mat.alpha != 1.f)
|
||||
if (!NumberEquals(mat.alpha, 1.f))
|
||||
{
|
||||
Emit("d ");
|
||||
EmitLine(mat.alpha);
|
||||
}
|
||||
|
||||
if (mat.refractionIndex != 1.f)
|
||||
if (!NumberEquals(mat.refractionIndex, 1.f))
|
||||
{
|
||||
Emit("ni ");
|
||||
EmitLine(mat.refractionIndex);
|
||||
}
|
||||
|
||||
if (mat.shininess != 1.f)
|
||||
if (!NumberEquals(mat.shininess, 1.f))
|
||||
{
|
||||
Emit("ns ");
|
||||
EmitLine(mat.shininess);
|
||||
|
||||
@@ -265,8 +265,8 @@ namespace Nz
|
||||
|
||||
if (vertexIndices.texCoord > 0)
|
||||
{
|
||||
const Vector3f& uvw = texCoords[vertexIndices.texCoord-1];
|
||||
vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
|
||||
Vector2f uv = Vector2f(texCoords[vertexIndices.texCoord - 1]);
|
||||
vertex.uv.Set(parameters.texCoordOffset + uv * parameters.texCoordScale);
|
||||
}
|
||||
else
|
||||
hasTexCoords = false;
|
||||
|
||||
@@ -128,17 +128,17 @@ namespace Nz
|
||||
UInt32 faceReserve = 0;
|
||||
UInt32 vertexReserve = 0;
|
||||
unsigned int matCount = 0;
|
||||
auto GetMaterial = [&] (const String& meshName, const String& matName) -> Mesh*
|
||||
auto GetMaterial = [&] (const String& mesh, const String& mat) -> Mesh*
|
||||
{
|
||||
auto& map = meshesByName[meshName];
|
||||
auto it = map.find(matName);
|
||||
auto& map = meshesByName[mesh];
|
||||
auto it = map.find(mat);
|
||||
if (it == map.end())
|
||||
it = map.insert(std::make_pair(matName, MatPair(Mesh(), matCount++))).first;
|
||||
it = map.insert(std::make_pair(mat, MatPair(Mesh(), matCount++))).first;
|
||||
|
||||
Mesh& mesh = it->second.first;
|
||||
Mesh& meshData = it->second.first;
|
||||
|
||||
mesh.faces.reserve(faceReserve);
|
||||
mesh.vertices.reserve(vertexReserve);
|
||||
meshData.faces.reserve(faceReserve);
|
||||
meshData.vertices.reserve(vertexReserve);
|
||||
faceReserve = 0;
|
||||
vertexReserve = 0;
|
||||
|
||||
@@ -550,19 +550,19 @@ namespace Nz
|
||||
EmitLine(pair.second.size());
|
||||
EmitLine();
|
||||
|
||||
for (std::size_t meshIndex : pair.second)
|
||||
for (std::size_t index : pair.second)
|
||||
{
|
||||
const Mesh& mesh = m_meshes[meshIndex];
|
||||
const Mesh& mesh = m_meshes[index];
|
||||
|
||||
Emit("g ");
|
||||
EmitLine(mesh.name);
|
||||
EmitLine();
|
||||
|
||||
|
||||
Emit("# face count: ");
|
||||
EmitLine(mesh.faces.size());
|
||||
Emit("# vertex count: ");
|
||||
EmitLine(mesh.vertices.size());
|
||||
|
||||
|
||||
for (const Face& face : mesh.faces)
|
||||
{
|
||||
Emit('f');
|
||||
|
||||
@@ -825,6 +825,44 @@ namespace Nz
|
||||
return GetLevelSize(m_sharedImage->width, level);
|
||||
}
|
||||
|
||||
bool Image::HasAlpha() const
|
||||
{
|
||||
NazaraAssert(m_sharedImage != &emptyImage, "Image must be valid");
|
||||
|
||||
if (!PixelFormat::HasAlpha(m_sharedImage->format))
|
||||
return false;
|
||||
|
||||
if (!PixelFormat::IsCompressed(m_sharedImage->format))
|
||||
{
|
||||
const PixelFormatInfo& info = PixelFormat::GetInfo(m_sharedImage->format);
|
||||
const UInt8* pixel = GetConstPixels();
|
||||
|
||||
Bitset<> workingBitset;
|
||||
std::size_t pixelCount = m_sharedImage->width * m_sharedImage->height * ((m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth);
|
||||
if (pixelCount == 0)
|
||||
return false;
|
||||
|
||||
auto seq = workingBitset.Read(GetConstPixels(), info.bitsPerPixel);
|
||||
do
|
||||
{
|
||||
workingBitset &= info.alphaMask;
|
||||
if (workingBitset.Count() != info.alphaMask.Count()) //< Means that at least one bit of the alpha mask of this pixel is disabled
|
||||
return true;
|
||||
|
||||
workingBitset.Clear();
|
||||
workingBitset.Read(seq, info.bitsPerPixel);
|
||||
}
|
||||
while (--pixelCount > 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Currently, we assume the pixel format is already the right one
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::IsValid() const
|
||||
{
|
||||
return m_sharedImage != &emptyImage;
|
||||
@@ -1441,7 +1479,7 @@ namespace Nz
|
||||
SharedImage::PixelContainer levels(m_sharedImage->levels.size());
|
||||
for (unsigned int i = 0; i < levels.size(); ++i)
|
||||
{
|
||||
unsigned int size = GetMemoryUsage(i);
|
||||
std::size_t size = GetMemoryUsage(i);
|
||||
levels[i].reset(new UInt8[size]);
|
||||
std::memcpy(levels[i].get(), m_sharedImage->levels[i].get(), size);
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ namespace Nz
|
||||
Font* SimpleTextDrawer::GetFont(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index == 0, "Font index out of range");
|
||||
NazaraUnused(index);
|
||||
|
||||
return m_font;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
SoftwareBuffer::SoftwareBuffer(Buffer* /*parent*/, BufferType type)
|
||||
SoftwareBuffer::SoftwareBuffer(Buffer* /*parent*/, BufferType /*type*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Nz
|
||||
|
||||
bool VertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard)
|
||||
{
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
std::size_t stride = m_vertexDeclaration->GetStride();
|
||||
return FillRaw(data, startVertex*stride, length*stride, forceDiscard);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Nz
|
||||
width(0)
|
||||
{
|
||||
}
|
||||
|
||||
VideoMode::VideoMode(unsigned int w, unsigned int h) :
|
||||
VideoMode(w, h, GetDesktopMode().bitsPerPixel)
|
||||
{
|
||||
}
|
||||
|
||||
VideoMode::VideoMode(unsigned int w, unsigned int h, UInt8 bpp) :
|
||||
bitsPerPixel(bpp),
|
||||
|
||||
@@ -81,8 +81,9 @@ namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style)
|
||||
bool WindowImpl::Create(const VideoMode& mode, const String& title, WindowStyleFlags style)
|
||||
{
|
||||
bool async = (style & WindowStyle_Threaded) != 0;
|
||||
bool fullscreen = (style & WindowStyle_Fullscreen) != 0;
|
||||
DWORD win32Style, win32StyleEx;
|
||||
unsigned int x, y;
|
||||
@@ -147,19 +148,25 @@ namespace Nz
|
||||
|
||||
m_callback = 0;
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
Mutex mutex;
|
||||
ConditionVariable condition;
|
||||
m_threadActive = true;
|
||||
m_eventListener = true;
|
||||
m_ownsWindow = true;
|
||||
m_sizemove = false;
|
||||
m_style = style;
|
||||
|
||||
// On attend que la fenêtre soit créée
|
||||
mutex.Lock();
|
||||
m_thread = Thread(WindowThread, &m_handle, win32StyleEx, title.GetWideString().data(), win32Style, x, y, width, height, this, &mutex, &condition);
|
||||
condition.Wait(&mutex);
|
||||
mutex.Unlock();
|
||||
#else
|
||||
m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
|
||||
#endif
|
||||
if (async)
|
||||
{
|
||||
Mutex mutex;
|
||||
ConditionVariable condition;
|
||||
m_threadActive = true;
|
||||
|
||||
// On attend que la fenêtre soit créée
|
||||
mutex.Lock();
|
||||
m_thread = Thread(WindowThread, &m_handle, win32StyleEx, title, win32Style, fullscreen, Rectui(x, y, width, height), this, &mutex, &condition);
|
||||
condition.Wait(&mutex);
|
||||
mutex.Unlock();
|
||||
}
|
||||
else
|
||||
m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
|
||||
|
||||
if (!m_handle)
|
||||
{
|
||||
@@ -167,26 +174,8 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
SetForegroundWindow(m_handle);
|
||||
ShowWindow(m_handle, SW_SHOW);
|
||||
}
|
||||
|
||||
m_eventListener = true;
|
||||
m_ownsWindow = true;
|
||||
#if !NAZARA_UTILITY_THREADED_WINDOW
|
||||
m_sizemove = false;
|
||||
#endif
|
||||
m_style = style;
|
||||
|
||||
// Récupération de la position/taille de la fenêtre (Après sa création)
|
||||
RECT clientRect, windowRect;
|
||||
GetClientRect(m_handle, &clientRect);
|
||||
GetWindowRect(m_handle, &windowRect);
|
||||
|
||||
m_position.Set(windowRect.left, windowRect.top);
|
||||
m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
if (!async)
|
||||
PrepareWindow(fullscreen);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -203,9 +192,7 @@ namespace Nz
|
||||
|
||||
m_eventListener = false;
|
||||
m_ownsWindow = false;
|
||||
#if !NAZARA_UTILITY_THREADED_WINDOW
|
||||
m_sizemove = false;
|
||||
#endif
|
||||
m_style = RetrieveStyle(m_handle);
|
||||
|
||||
RECT clientRect, windowRect;
|
||||
@@ -222,18 +209,21 @@ namespace Nz
|
||||
{
|
||||
if (m_ownsWindow)
|
||||
{
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
if (m_thread.IsJoinable())
|
||||
if (m_style & WindowStyle_Threaded)
|
||||
{
|
||||
m_threadActive = false;
|
||||
PostMessageW(m_handle, WM_NULL, 0, 0); // Pour réveiller le thread
|
||||
if (m_thread.IsJoinable())
|
||||
{
|
||||
m_threadActive = false;
|
||||
PostMessageW(m_handle, WM_NULL, 0, 0); // Wake up our thread
|
||||
|
||||
m_thread.Join();
|
||||
m_thread.Join();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_handle)
|
||||
DestroyWindow(m_handle);
|
||||
}
|
||||
#else
|
||||
if (m_handle)
|
||||
DestroyWindow(m_handle);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
SetEventListener(false);
|
||||
@@ -269,7 +259,7 @@ namespace Nz
|
||||
return m_size;
|
||||
}
|
||||
|
||||
UInt32 WindowImpl::GetStyle() const
|
||||
WindowStyleFlags WindowImpl::GetStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
@@ -280,7 +270,7 @@ namespace Nz
|
||||
if (titleSize == 0)
|
||||
return String();
|
||||
|
||||
titleSize++; // Caractère nul
|
||||
titleSize++; // \0
|
||||
|
||||
std::unique_ptr<wchar_t[]> wTitle(new wchar_t[titleSize]);
|
||||
GetWindowTextW(m_handle, wTitle.get(), titleSize);
|
||||
@@ -525,7 +515,6 @@ namespace Nz
|
||||
return true; // Afin que Windows ne ferme pas la fenêtre automatiquement
|
||||
}
|
||||
|
||||
#if !NAZARA_UTILITY_THREADED_WINDOW
|
||||
case WM_ENTERSIZEMOVE:
|
||||
{
|
||||
m_sizemove = true;
|
||||
@@ -536,6 +525,10 @@ namespace Nz
|
||||
{
|
||||
m_sizemove = false;
|
||||
|
||||
// In case of threaded window, size and move events are not blocked
|
||||
if (m_style & WindowStyle_Threaded)
|
||||
break;
|
||||
|
||||
// On vérifie ce qui a changé
|
||||
RECT clientRect, windowRect;
|
||||
GetClientRect(m_handle, &clientRect);
|
||||
@@ -565,7 +558,6 @@ namespace Nz
|
||||
m_parent->PushEvent(event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
@@ -789,15 +781,23 @@ namespace Nz
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
if (m_sizemove && (m_style & WindowStyle_Threaded) == 0)
|
||||
break;
|
||||
|
||||
RECT windowRect;
|
||||
GetWindowRect(m_handle, &windowRect);
|
||||
|
||||
WindowEvent event;
|
||||
event.type = WindowEventType_Moved;
|
||||
event.position.x = windowRect.left;
|
||||
event.position.y = windowRect.top;
|
||||
m_parent->PushEvent(event);
|
||||
Vector2i position(windowRect.left, windowRect.top);
|
||||
if (m_position != position)
|
||||
{
|
||||
m_position = position;
|
||||
|
||||
WindowEvent event;
|
||||
event.type = WindowEventType_Moved;
|
||||
event.position.x = position.x;
|
||||
event.position.y = position.y;
|
||||
m_parent->PushEvent(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -852,27 +852,26 @@ namespace Nz
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
if (wParam != SIZE_MINIMIZED)
|
||||
#else
|
||||
if (!m_sizemove && wParam != SIZE_MINIMIZED)
|
||||
#endif
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(m_handle, &rect);
|
||||
if (m_sizemove && (m_style & WindowStyle_Threaded) == 0)
|
||||
break;
|
||||
|
||||
Vector2ui size(rect.right-rect.left, rect.bottom-rect.top); // On récupère uniquement la taille de la zone client
|
||||
if (m_size == size)
|
||||
break;
|
||||
if (wParam == SIZE_MINIMIZED)
|
||||
break;
|
||||
|
||||
m_size = size;
|
||||
RECT rect;
|
||||
GetClientRect(m_handle, &rect);
|
||||
|
||||
WindowEvent event;
|
||||
event.type = WindowEventType_Resized;
|
||||
event.size.width = size.x;
|
||||
event.size.height = size.y;
|
||||
m_parent->PushEvent(event);
|
||||
}
|
||||
Vector2ui size(rect.right-rect.left, rect.bottom-rect.top); // On récupère uniquement la taille de la zone client
|
||||
if (m_size == size)
|
||||
break;
|
||||
|
||||
m_size = size;
|
||||
|
||||
WindowEvent event;
|
||||
event.type = WindowEventType_Resized;
|
||||
event.size.width = size.x;
|
||||
event.size.height = size.y;
|
||||
m_parent->PushEvent(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -963,6 +962,23 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
void WindowImpl::PrepareWindow(bool fullscreen)
|
||||
{
|
||||
if (fullscreen)
|
||||
{
|
||||
SetForegroundWindow(m_handle);
|
||||
ShowWindow(m_handle, SW_SHOW);
|
||||
}
|
||||
|
||||
// Cache window position/size after creation
|
||||
RECT clientRect, windowRect;
|
||||
GetClientRect(m_handle, &clientRect);
|
||||
GetWindowRect(m_handle, &windowRect);
|
||||
|
||||
m_position.Set(windowRect.left, windowRect.top);
|
||||
m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
}
|
||||
|
||||
bool WindowImpl::Initialize()
|
||||
{
|
||||
// Nous devons faire un type Unicode pour que la fenêtre le soit également
|
||||
@@ -1177,15 +1193,17 @@ namespace Nz
|
||||
return style;
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
void WindowImpl::WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
|
||||
void WindowImpl::WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, bool fullscreen, const Rectui& dimensions, WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
|
||||
{
|
||||
HWND& winHandle = *handle;
|
||||
winHandle = CreateWindowExW(styleEx, className, title, style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), window);
|
||||
winHandle = CreateWindowExW(styleEx, className, title.GetWideString().data(), style, dimensions.x, dimensions.y, dimensions.width, dimensions.height, nullptr, nullptr, GetModuleHandle(nullptr), window);
|
||||
|
||||
if (winHandle)
|
||||
window->PrepareWindow(fullscreen);
|
||||
|
||||
mutex->Lock();
|
||||
condition->Signal();
|
||||
mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici
|
||||
mutex->Unlock(); // mutex and condition may be destroyed after this line
|
||||
|
||||
if (!winHandle)
|
||||
return;
|
||||
@@ -1195,5 +1213,4 @@ namespace Nz
|
||||
|
||||
DestroyWindow(winHandle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Keyboard.hpp>
|
||||
@@ -22,10 +23,8 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
class ConditionVariable;
|
||||
class Mutex;
|
||||
#endif
|
||||
class Window;
|
||||
|
||||
#undef IsMinimized // Conflit avec la méthode du même nom
|
||||
@@ -38,7 +37,7 @@ namespace Nz
|
||||
WindowImpl(WindowImpl&&) = delete; ///TODO?
|
||||
~WindowImpl() = default;
|
||||
|
||||
bool Create(const VideoMode& mode, const String& title, UInt32 style);
|
||||
bool Create(const VideoMode& mode, const String& title, WindowStyleFlags style);
|
||||
bool Create(WindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
@@ -50,7 +49,7 @@ namespace Nz
|
||||
unsigned int GetHeight() const;
|
||||
Vector2i GetPosition() const;
|
||||
Vector2ui GetSize() const;
|
||||
UInt32 GetStyle() const;
|
||||
WindowStyleFlags GetStyle() const;
|
||||
String GetTitle() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
@@ -84,38 +83,31 @@ namespace Nz
|
||||
|
||||
private:
|
||||
bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
void PrepareWindow(bool fullscreen);
|
||||
|
||||
static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags);
|
||||
static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
static UInt32 RetrieveStyle(HWND window);
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
static void WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition);
|
||||
#endif
|
||||
static void WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, bool fullscreen, const Rectui& dimensions, WindowImpl* window, Mutex* mutex, ConditionVariable* condition);
|
||||
|
||||
HCURSOR m_cursor;
|
||||
HWND m_handle;
|
||||
LONG_PTR m_callback;
|
||||
UInt32 m_style;
|
||||
WindowStyleFlags m_style;
|
||||
Vector2i m_maxSize;
|
||||
Vector2i m_minSize;
|
||||
Vector2i m_mousePos;
|
||||
Vector2i m_position;
|
||||
Vector2ui m_size;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
Thread m_thread;
|
||||
#endif
|
||||
Window* m_parent;
|
||||
bool m_eventListener;
|
||||
bool m_keyRepeat;
|
||||
bool m_mouseInside;
|
||||
bool m_ownsWindow;
|
||||
#if !NAZARA_UTILITY_THREADED_WINDOW
|
||||
bool m_sizemove;
|
||||
#endif
|
||||
bool m_smoothScrolling;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
bool m_threadActive;
|
||||
#endif
|
||||
short m_scrolling;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Nz
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool Window::Create(VideoMode mode, const String& title, UInt32 style)
|
||||
bool Window::Create(VideoMode mode, const String& title, WindowStyleFlags style)
|
||||
{
|
||||
// Si la fenêtre est déjà ouverte, nous conservons sa position
|
||||
bool opened = IsOpen();
|
||||
@@ -66,6 +66,8 @@ namespace Nz
|
||||
else if (style & WindowStyle_Closable || style & WindowStyle_Resizable)
|
||||
style |= WindowStyle_Titlebar;
|
||||
|
||||
m_asyncWindow = (style & WindowStyle_Threaded) != 0;
|
||||
|
||||
std::unique_ptr<WindowImpl> impl = std::make_unique<WindowImpl>(this);
|
||||
if (!impl->Create(mode, title, style))
|
||||
{
|
||||
@@ -107,6 +109,7 @@ namespace Nz
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_asyncWindow = false;
|
||||
m_impl = new WindowImpl(this);
|
||||
if (!m_impl->Create(handle))
|
||||
{
|
||||
@@ -225,7 +228,7 @@ namespace Nz
|
||||
return m_impl->GetSize();
|
||||
}
|
||||
|
||||
UInt32 Window::GetStyle() const
|
||||
WindowStyleFlags Window::GetStyle() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
@@ -313,11 +316,8 @@ namespace Nz
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
LockGuard lock(m_eventMutex);
|
||||
#else
|
||||
m_impl->ProcessEvents(false);
|
||||
#endif
|
||||
if (!m_asyncWindow)
|
||||
m_impl->ProcessEvents(false);
|
||||
|
||||
if (!m_events.empty())
|
||||
{
|
||||
@@ -335,10 +335,19 @@ namespace Nz
|
||||
void Window::ProcessEvents(bool block)
|
||||
{
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
NazaraUnused(block);
|
||||
|
||||
#if !NAZARA_UTILITY_THREADED_WINDOW
|
||||
m_impl->ProcessEvents(block);
|
||||
#endif
|
||||
if (!m_asyncWindow)
|
||||
m_impl->ProcessEvents(block);
|
||||
else
|
||||
{
|
||||
LockGuard eventLock(m_eventMutex);
|
||||
|
||||
for (const WindowEvent& event : m_pendingEvents)
|
||||
HandleEvent(event);
|
||||
|
||||
m_pendingEvents.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::SetCursor(WindowCursor cursor)
|
||||
@@ -383,25 +392,13 @@ namespace Nz
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
m_impl->SetEventListener(listener);
|
||||
if (!listener)
|
||||
{
|
||||
// On vide la pile des évènements
|
||||
LockGuard lock(m_eventMutex);
|
||||
// Empty the event queue
|
||||
while (!m_events.empty())
|
||||
m_events.pop();
|
||||
}
|
||||
#else
|
||||
if (m_ownsWindow)
|
||||
{
|
||||
// Inutile de transmettre l'ordre dans ce cas-là
|
||||
if (!listener)
|
||||
NazaraError("A non-threaded window needs to listen to events");
|
||||
}
|
||||
else
|
||||
m_impl->SetEventListener(listener);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Window::SetFocus()
|
||||
@@ -589,22 +586,11 @@ namespace Nz
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
LockGuard lock(m_eventMutex);
|
||||
|
||||
if (m_events.empty())
|
||||
if (!m_asyncWindow)
|
||||
{
|
||||
m_waitForEvent = true;
|
||||
m_eventConditionMutex.Lock();
|
||||
m_eventMutex.Unlock();
|
||||
m_eventCondition.Wait(&m_eventConditionMutex);
|
||||
m_eventMutex.Lock();
|
||||
m_eventConditionMutex.Unlock();
|
||||
m_waitForEvent = false;
|
||||
}
|
||||
while (m_events.empty())
|
||||
m_impl->ProcessEvents(true);
|
||||
|
||||
if (!m_events.empty())
|
||||
{
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
|
||||
@@ -612,19 +598,33 @@ namespace Nz
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LockGuard lock(m_eventMutex);
|
||||
|
||||
return false;
|
||||
#else
|
||||
while (m_events.empty())
|
||||
m_impl->ProcessEvents(true);
|
||||
if (m_events.empty())
|
||||
{
|
||||
m_waitForEvent = true;
|
||||
m_eventConditionMutex.Lock();
|
||||
m_eventMutex.Unlock();
|
||||
m_eventCondition.Wait(&m_eventConditionMutex);
|
||||
m_eventMutex.Lock();
|
||||
m_eventConditionMutex.Unlock();
|
||||
m_waitForEvent = false;
|
||||
}
|
||||
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
if (!m_events.empty())
|
||||
{
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
|
||||
m_events.pop();
|
||||
m_events.pop();
|
||||
|
||||
return true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::OnWindowCreated()
|
||||
|
||||
@@ -23,32 +23,32 @@ namespace Nz
|
||||
switch (key)
|
||||
{
|
||||
// Lettres
|
||||
case Keyboard::A: keysym = XK_A; break;
|
||||
case Keyboard::B: keysym = XK_B; break;
|
||||
case Keyboard::C: keysym = XK_C; break;
|
||||
case Keyboard::D: keysym = XK_D; break;
|
||||
case Keyboard::E: keysym = XK_E; break;
|
||||
case Keyboard::F: keysym = XK_F; break;
|
||||
case Keyboard::G: keysym = XK_G; break;
|
||||
case Keyboard::H: keysym = XK_H; break;
|
||||
case Keyboard::I: keysym = XK_I; break;
|
||||
case Keyboard::J: keysym = XK_J; break;
|
||||
case Keyboard::K: keysym = XK_K; break;
|
||||
case Keyboard::L: keysym = XK_L; break;
|
||||
case Keyboard::M: keysym = XK_M; break;
|
||||
case Keyboard::N: keysym = XK_N; break;
|
||||
case Keyboard::O: keysym = XK_O; break;
|
||||
case Keyboard::P: keysym = XK_P; break;
|
||||
case Keyboard::Q: keysym = XK_Q; break;
|
||||
case Keyboard::R: keysym = XK_R; break;
|
||||
case Keyboard::S: keysym = XK_S; break;
|
||||
case Keyboard::T: keysym = XK_T; break;
|
||||
case Keyboard::U: keysym = XK_U; break;
|
||||
case Keyboard::V: keysym = XK_V; break;
|
||||
case Keyboard::W: keysym = XK_W; break;
|
||||
case Keyboard::X: keysym = XK_X; break;
|
||||
case Keyboard::Y: keysym = XK_Y; break;
|
||||
case Keyboard::Z: keysym = XK_Z; break;
|
||||
case Keyboard::A: keysym = XK_a; break;
|
||||
case Keyboard::B: keysym = XK_b; break;
|
||||
case Keyboard::C: keysym = XK_c; break;
|
||||
case Keyboard::D: keysym = XK_d; break;
|
||||
case Keyboard::E: keysym = XK_e; break;
|
||||
case Keyboard::F: keysym = XK_f; break;
|
||||
case Keyboard::G: keysym = XK_g; break;
|
||||
case Keyboard::H: keysym = XK_h; break;
|
||||
case Keyboard::I: keysym = XK_i; break;
|
||||
case Keyboard::J: keysym = XK_j; break;
|
||||
case Keyboard::K: keysym = XK_k; break;
|
||||
case Keyboard::L: keysym = XK_l; break;
|
||||
case Keyboard::M: keysym = XK_m; break;
|
||||
case Keyboard::N: keysym = XK_n; break;
|
||||
case Keyboard::O: keysym = XK_o; break;
|
||||
case Keyboard::P: keysym = XK_p; break;
|
||||
case Keyboard::Q: keysym = XK_q; break;
|
||||
case Keyboard::R: keysym = XK_r; break;
|
||||
case Keyboard::S: keysym = XK_s; break;
|
||||
case Keyboard::T: keysym = XK_t; break;
|
||||
case Keyboard::U: keysym = XK_u; break;
|
||||
case Keyboard::V: keysym = XK_v; break;
|
||||
case Keyboard::W: keysym = XK_w; break;
|
||||
case Keyboard::X: keysym = XK_x; break;
|
||||
case Keyboard::Y: keysym = XK_y; break;
|
||||
case Keyboard::Z: keysym = XK_z; break;
|
||||
|
||||
// Touches de fonction
|
||||
case Keyboard::F1: keysym = XK_F1; break;
|
||||
@@ -248,6 +248,8 @@ namespace Nz
|
||||
|
||||
xcb_keysym_t keySym = GetKeySym(key);
|
||||
|
||||
xcb_keycode_t realKeyCode = XCB_NO_SYMBOL;
|
||||
|
||||
xcb_key_symbols_t* keySymbols = X11::XCBKeySymbolsAlloc(connection);
|
||||
if (!keySymbols)
|
||||
{
|
||||
@@ -261,6 +263,20 @@ namespace Nz
|
||||
NazaraError("Failed to get key code");
|
||||
return false;
|
||||
}
|
||||
|
||||
// One keysym is associated with multiple key codes, we have to find the matching one ...
|
||||
int i = 0;
|
||||
while (keyCode.get()[i] != XCB_NO_SYMBOL)
|
||||
{
|
||||
xcb_keycode_t toTry = keyCode.get()[i];
|
||||
if (keySym == xcb_key_symbols_get_keysym(keySymbols, toTry, 0))
|
||||
{
|
||||
realKeyCode = toTry;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
X11::XCBKeySymbolsFree(keySymbols);
|
||||
|
||||
ScopedXCB<xcb_generic_error_t> error(nullptr);
|
||||
@@ -281,7 +297,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
// Check our keycode
|
||||
return (keymap->keys[*keyCode.get() / 8] & (1 << (*keyCode.get() % 8))) != 0;
|
||||
return (keymap->keys[realKeyCode / 8] & (1 << (realKeyCode % 8))) != 0;
|
||||
}
|
||||
|
||||
bool EventImpl::IsMouseButtonPressed(Mouse::Button button)
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Nz
|
||||
UpdateEventQueue(nullptr);
|
||||
}
|
||||
|
||||
bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style)
|
||||
bool WindowImpl::Create(const VideoMode& mode, const String& title, WindowStyleFlags style)
|
||||
{
|
||||
bool fullscreen = (style & Nz::WindowStyle_Fullscreen) != 0;
|
||||
m_eventListener = true;
|
||||
@@ -203,17 +203,18 @@ namespace Nz
|
||||
// Set the window's name
|
||||
SetTitle(title);
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
Mutex mutex;
|
||||
ConditionVariable condition;
|
||||
m_threadActive = true;
|
||||
if (m_style & WindowStyle_Threaded)
|
||||
{
|
||||
Mutex mutex;
|
||||
ConditionVariable condition;
|
||||
m_threadActive = true;
|
||||
|
||||
// We wait that thread is well launched
|
||||
mutex.Lock();
|
||||
m_thread = Thread(WindowThread, this, &mutex, &condition);
|
||||
condition.Wait(&mutex);
|
||||
mutex.Unlock();
|
||||
#endif
|
||||
// Wait until the thread is ready
|
||||
mutex.Lock();
|
||||
m_thread = Thread(WindowThread, this, &mutex, &condition);
|
||||
condition.Wait(&mutex);
|
||||
mutex.Unlock();
|
||||
}
|
||||
|
||||
// Set fullscreen video mode and switch to fullscreen if necessary
|
||||
if (fullscreen)
|
||||
@@ -275,13 +276,15 @@ namespace Nz
|
||||
{
|
||||
if (m_ownsWindow)
|
||||
{
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
if (m_thread.IsJoinable())
|
||||
if (m_style & WindowStyle_Threaded)
|
||||
{
|
||||
m_threadActive = false;
|
||||
m_thread.Join();
|
||||
if (m_thread.IsJoinable())
|
||||
{
|
||||
m_threadActive = false;
|
||||
m_thread.Join();
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// Destroy the window
|
||||
if (m_window && m_ownsWindow)
|
||||
{
|
||||
@@ -293,13 +296,11 @@ namespace Nz
|
||||
xcb_destroy_window(
|
||||
connection,
|
||||
m_window
|
||||
))
|
||||
)
|
||||
)))
|
||||
NazaraError("Failed to destroy window");
|
||||
|
||||
xcb_flush(connection);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
SetEventListener(false);
|
||||
@@ -335,7 +336,7 @@ namespace Nz
|
||||
return Vector2ui(m_size_hints.width, m_size_hints.height);
|
||||
}
|
||||
|
||||
UInt32 WindowImpl::GetStyle() const
|
||||
WindowStyleFlags WindowImpl::GetStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
@@ -1247,7 +1248,7 @@ namespace Nz
|
||||
|
||||
char32_t codePoint = GetRepresentation(keysym);
|
||||
|
||||
// WTF if (std::isprint(codePoint, std::locale(""))) + handle combining ?
|
||||
// if (std::isprint(codePoint)) Is not working ? + handle combining ?
|
||||
{
|
||||
WindowEvent event;
|
||||
event.type = Nz::WindowEventType_TextEntered;
|
||||
@@ -1405,7 +1406,7 @@ namespace Nz
|
||||
// Catch reparent events to properly apply fullscreen on
|
||||
// some "strange" window managers (like Awesome) which
|
||||
// seem to make use of temporary parents during mapping
|
||||
if (m_style & Nz::WindowStyle_Fullscreen)
|
||||
if (m_style & WindowStyle_Fullscreen)
|
||||
SwitchToFullscreen();
|
||||
|
||||
break;
|
||||
@@ -1685,12 +1686,11 @@ namespace Nz
|
||||
));
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
void WindowImpl::WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
|
||||
{
|
||||
mutex->Lock();
|
||||
condition->Signal();
|
||||
mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici
|
||||
mutex->Unlock(); // mutex and condition may be destroyed after this line
|
||||
|
||||
if (!window->m_window)
|
||||
return;
|
||||
@@ -1700,5 +1700,4 @@ namespace Nz
|
||||
|
||||
window->Destroy();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,10 +20,8 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
class ConditionVariable;
|
||||
class Mutex;
|
||||
#endif
|
||||
class Cursor;
|
||||
class Icon;
|
||||
class VideoMode;
|
||||
@@ -37,7 +35,7 @@ namespace Nz
|
||||
WindowImpl(WindowImpl&&) = delete; ///TODO?
|
||||
~WindowImpl();
|
||||
|
||||
bool Create(const VideoMode& mode, const String& title, UInt32 style);
|
||||
bool Create(const VideoMode& mode, const String& title, WindowStyleFlags style);
|
||||
bool Create(WindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
@@ -49,7 +47,7 @@ namespace Nz
|
||||
unsigned int GetHeight() const;
|
||||
Vector2i GetPosition() const;
|
||||
Vector2ui GetSize() const;
|
||||
UInt32 GetStyle() const;
|
||||
WindowStyleFlags GetStyle() const;
|
||||
String GetTitle() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
@@ -103,25 +101,19 @@ namespace Nz
|
||||
bool UpdateNormalHints();
|
||||
void UpdateEventQueue(xcb_generic_event_t* event);
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
static void WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition);
|
||||
#endif
|
||||
|
||||
xcb_window_t m_window;
|
||||
xcb_screen_t* m_screen;
|
||||
xcb_randr_get_screen_info_reply_t m_oldVideoMode;
|
||||
xcb_size_hints_t m_size_hints;
|
||||
UInt32 m_style;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
Thread m_thread;
|
||||
#endif
|
||||
WindowStyleFlags m_style;
|
||||
Window* m_parent;
|
||||
bool m_eventListener;
|
||||
bool m_ownsWindow;
|
||||
bool m_smoothScrolling;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
bool m_threadActive;
|
||||
#endif
|
||||
short m_scrolling;
|
||||
Vector2i m_mousePos;
|
||||
bool m_keyRepeat;
|
||||
|
||||
Reference in New Issue
Block a user