Merge branch 'dev'

Conflicts:
	src/line.hpp
	src/platformset.cpp
	src/vector.hpp
This commit is contained in:
King_DuckZ 2014-08-25 17:41:06 +02:00
commit 5a71b943b2
22 changed files with 835 additions and 32 deletions

View file

@ -1,14 +1,30 @@
cmake_minimum_required(VERSION 2.8)
project(CloonelJump CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
include(TargetArch)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -pedantic -Wconversion")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -Wall -Wextra -pedantic -Wconversion")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -Wall -Wextra -pedantic -Wconversion")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -Wall -Wextra -pedantic -Wconversion -DWITH_DEBUG_VISUALS -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -Wall -Wextra -pedantic -Wconversion -O3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
target_architecture(TARGET_ARCH)
message (STATUS "Target architecture: ${TARGET_ARCH}")
option(WITH_BUILTIN_PHYSFS "Force using the version of PhysFS accompanying the code even if a system library is available" OFF)
option(FORCE_OPENGLES "Try to chose the openGL ES renderer if available. Enable this on Raspberry Pi" OFF)
option(RASPBERRY_PI "Compile for Raspberry Pi" OFF)
if (TARGET_ARCH MATCHES "^x86_64$")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -msse3")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -msse3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -msse3")
endif (TARGET_ARCH MATCHES "^x86_64$")
if (FORCE_OPENGLES OR RASPBERRY_PI)
add_definitions(-DFORCE_OPENGLES)
if (RASPBERRY_PI)
@ -103,6 +119,7 @@ add_executable(${PROJECT_NAME}
src/line.cpp
src/collider.cpp
src/platformset.cpp
src/drawableline.cpp
)
target_link_libraries(${PROJECT_NAME}

View file

@ -0,0 +1,134 @@
# Based on the Qt 5 processor detection code, so should be very accurate
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
# Regarding POWER/PowerPC, just as is noted in the Qt source,
# "There are many more known variants/revisions that we do not handle/detect."
set(archdetect_c_code "
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
#error cmake_ARCH armv7
#elif defined(__ARM_ARCH_6__) \\
|| defined(__ARM_ARCH_6J__) \\
|| defined(__ARM_ARCH_6T2__) \\
|| defined(__ARM_ARCH_6Z__) \\
|| defined(__ARM_ARCH_6K__) \\
|| defined(__ARM_ARCH_6ZK__) \\
|| defined(__ARM_ARCH_6M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
#error cmake_ARCH armv6
#elif defined(__ARM_ARCH_5TEJ__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
#error cmake_ARCH armv5
#else
#error cmake_ARCH arm
#endif
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#error cmake_ARCH ppc64
#else
#error cmake_ARCH ppc
#endif
#endif
#error cmake_ARCH unknown
")
# Set ppc_support to TRUE before including this file or ppc and ppc64
# will be treated as invalid architectures since they are no longer supported by Apple
function(target_architecture output_var)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
endforeach()
# Now add all the architectures in our normalized order
if(osx_arch_ppc)
list(APPEND ARCH ppc)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
if(osx_arch_x86_64)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/arch.c"
COMPILE_OUTPUT_VARIABLE ARCH
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
)
# Parse the architecture name from the compiler output
string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
# Get rid of the value marker leaving just the architecture name
string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
# If we are compiling with an unknown architecture this variable should
# already be set to "unknown" but in the case that it's empty (i.e. due
# to a typo in the code), then set it to unknown
if (NOT ARCH)
set(ARCH unknown)
endif()
endif()
set(${output_var} "${ARCH}" PARENT_SCOPE)
endfunction()

View file

@ -39,6 +39,9 @@ namespace cloonel {
m_screenRatio(parMain),
m_bounceCallback(&DoNothing),
m_texture(new Texture(parPath, parMain, false))
#if defined(WITH_DEBUG_VISUALS)
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<short2>(m_bottomBar.From()), static_cast<short2>(m_bottomBar.To()))
#endif
{
assert(parMain);
m_bottomBar.SetCallback(std::bind(&Character::OnBounce, this, std::placeholders::_1, std::placeholders::_2));
@ -53,6 +56,9 @@ namespace cloonel {
m_screenRatio(parMain),
m_bounceCallback(&DoNothing),
m_texture(new Texture(parPath, parMain, false))
#if defined(WITH_DEBUG_VISUALS)
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<short2>(m_bottomBar.From()), static_cast<short2>(m_bottomBar.To()))
#endif
{
assert(parMain);
m_bottomBar.SetCallback(std::bind(&Character::OnBounce, this, std::placeholders::_1, std::placeholders::_2));
@ -88,6 +94,9 @@ namespace cloonel {
///-------------------------------------------------------------------------
void Character::Draw() const {
m_texture->Render(GetPos(), WidthHeight(), m_screenRatio.Ratio(), true);
#if defined(WITH_DEBUG_VISUALS)
m_bottomBarDrawable.Render(GetPos(), m_screenRatio.Ratio());
#endif
}
///-------------------------------------------------------------------------

View file

@ -27,6 +27,9 @@
#include "sizenotifiable.hpp"
#include "horzcollisionbar.hpp"
#include "collidertypedef.hpp"
#if defined(WITH_DEBUG_VISUALS)
# include "drawableline.hpp"
#endif
#include <string>
#include <memory>
#include <cstdint>
@ -64,6 +67,9 @@ namespace cloonel {
SizeNotifiable<regbehaviours::AutoRegister> m_screenRatio;
BounceCallbackType m_bounceCallback;
const std::unique_ptr<Texture> m_texture;
#if defined(WITH_DEBUG_VISUALS)
DrawableLine m_bottomBarDrawable;
#endif
};
} //unnamed namespace

62
src/colour.hpp Normal file
View file

@ -0,0 +1,62 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id1DA767EB516A4F4588347DFC14D1A999
#define id1DA767EB516A4F4588347DFC14D1A999
#if defined(WITH_DEBUG_VISUALS)
#include <cstdint>
namespace cloonel {
struct Colour {
typedef uint8_t ChannelType;
Colour ( void ) = default;
Colour ( ChannelType parR, ChannelType parG, ChannelType parB, ChannelType parA );
Colour ( ChannelType parR, ChannelType parG, ChannelType parB ) : Colour(parR, parG, parB, 0xFF) {}
explicit Colour ( ChannelType parFill );
Colour ( const Colour& parOther ) = default;
ChannelType r, g, b, a;
};
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
inline Colour::Colour (ChannelType parR, ChannelType parG, ChannelType parB, ChannelType parA) :
r(parR),
g(parG),
b(parB),
a(parA)
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
inline Colour::Colour (ChannelType parFill) :
r(parFill),
g(parFill),
b(parFill),
a(parFill)
{
}
} //namespace cloonel
#endif
#endif

137
src/drawableline.cpp Normal file
View file

@ -0,0 +1,137 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "drawableline.hpp"
#include "sdlmain.hpp"
#include "geometry_2d.hpp"
#if !defined(NDEBUG)
# include "line_helpers.hpp"
#endif
#include <SDL2/SDL.h>
#include <algorithm>
#if defined(WITH_DEBUG_VISUALS)
namespace cloonel {
namespace {
///----------------------------------------------------------------------
///----------------------------------------------------------------------
void ClipLine (const SDL_Rect& parArea, Line<int16_t, 2>& parLine) {
Line<float, 2> line(static_cast<float2>(parLine[0]), static_cast<float2>(parLine[1]));
const float al = static_cast<float>(parArea.x);
const float at = static_cast<float>(parArea.y);
const float ar = static_cast<float>(parArea.x + parArea.w);
const float ab = static_cast<float>(parArea.y + parArea.h);
{
const Line<float, 2> leftLine(al, at, al, ab);
const auto intersection(Intersection(line, leftLine));
if (intersection.first) {
if (line[0] < leftLine)
line[0] = intersection.second;
if (line[1] < leftLine)
line[1] = intersection.second;
}
}
{
const Line<float, 2> rightLine(ar, at, ar, ab);
const auto intersection(Intersection(line, rightLine));
if (intersection.first) {
if (line[0] > rightLine)
line[0] = intersection.second;
if (line[1] > rightLine)
line[1] = intersection.second;
}
}
{
const Line<float, 2> topLine(al, at, ar, at);
const auto intersection(Intersection(line, topLine));
if (intersection.first) {
if (line[0] < topLine)
line[0] = intersection.second;
if (line[1] < topLine)
line[1] = intersection.second;
}
}
{
const Line<float, 2> bottomLine(al, ab, ar, ab);
const auto intersection(Intersection(line, bottomLine));
if (intersection.first) {
if (line[0] > bottomLine)
line[0] = intersection.second;
if (line[1] > bottomLine)
line[1] = intersection.second;
}
}
parLine[0] = static_cast<short2>(line[0]);
parLine[1] = static_cast<short2>(line[1]);
}
} //unnamed namespace
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
DrawableLine::DrawableLine (SDLMain* parMain, Colour parColour, const LineBase& parLine) :
LineBase(parLine),
m_sdlmain(parMain),
m_colour(parColour)
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
DrawableLine::DrawableLine (SDLMain* parMain, Colour parColour, const LineBase::Point& parStart, const LineBase::Point& parEnd) :
LineBase(parStart, parEnd),
m_sdlmain(parMain),
m_colour(parColour)
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void DrawableLine::Render (const float2& parPos, const float2& parScaling) const {
SDL_SetRenderDrawColor(m_sdlmain->GetRenderer(), m_colour.r, m_colour.g, m_colour.b, m_colour.a);
LineBase scaledLine(*this);
scaledLine += static_cast<short2>(parPos);
scaledLine *= parScaling;
{
SDL_Rect screen;
screen.x = screen.y = 0;
const short2 wh(static_cast<short2>(m_sdlmain->WidthHeight()));
screen.w = wh.x();
screen.h = wh.y();
ClipLine(screen, scaledLine);
}
const int16_t h = static_cast<int16_t>(m_sdlmain->WidthHeight().y());
if (scaledLine[0] != scaledLine[1]) {
SDL_RenderDrawLine(
m_sdlmain->GetRenderer(),
scaledLine[0].x(),
h - scaledLine[0].y(),
scaledLine[1].x(),
h - scaledLine[1].y()
);
}
//Returns 0 on success or a negative error code on failure; call SDL_GetError() for more information.
//http://www.ginkgobitter.org/sdl/?SDL_RenderDrawLine
}
} //namespace cloonel
#endif

71
src/drawableline.hpp Normal file
View file

@ -0,0 +1,71 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef idE8A33294FB164199B0A23E0385DD0E09
#define idE8A33294FB164199B0A23E0385DD0E09
#if defined(WITH_DEBUG_VISUALS)
#include "colour.hpp"
#include "line.hpp"
#include <cstdint>
namespace cloonel {
class SDLMain;
class DrawableLine : public Line<int16_t, 2> {
typedef Line<int16_t, 2> LineBase;
public:
explicit DrawableLine ( SDLMain* parMain );
explicit DrawableLine ( SDLMain* parMain, Colour parColour );
DrawableLine ( SDLMain* parMain, Colour parColour, const LineBase& parLine );
DrawableLine ( SDLMain* parMain, Colour parColour, const LineBase::Point& parStart, const LineBase::Point& parEnd );
DrawableLine ( const DrawableLine& parOther ) = default;
virtual ~DrawableLine ( void ) noexcept = default;
DrawableLine& operator= ( const DrawableLine& ) = delete;
void Render ( const float2& parPos, const float2& parScaling ) const;
private:
SDLMain* const m_sdlmain;
Colour m_colour;
};
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
inline DrawableLine::DrawableLine (SDLMain* parMain) :
m_sdlmain(parMain),
m_colour()
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
inline DrawableLine::DrawableLine (SDLMain* parMain, Colour parColour) :
m_sdlmain(parMain),
m_colour(parColour)
{
}
} //namespace cloonel
#endif
#endif

25
src/geometry.cpp Normal file
View file

@ -0,0 +1,25 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "geometry.hpp"
namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
} //namespace cloonel

34
src/geometry.hpp Normal file
View file

@ -0,0 +1,34 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id3E40B29606D048569E18083DB682280F
#define id3E40B29606D048569E18083DB682280F
#include "vector.hpp"
#include <ciso646>
#include <algorithm>
namespace cloonel {
template <typename T, uint32_t S>
bool IsPointOnSegment ( const Vector<T, S>& parPoint, const Vector<T, S>& parSegA, const Vector<T, S>& parSegB ) __attribute__((pure));
} //namespace cloonel
#include "geometry.inl"
#endif

31
src/geometry.inl Normal file
View file

@ -0,0 +1,31 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
bool IsPointOnSegment (const Vector<T, S>& parPoint, const Vector<T, S>& parSegA, const Vector<T, S>& parSegB) {
for (uint32_t z = 0; z < S; ++z) {
if (parPoint[z] <= std::max(parSegA[z], parSegB[z]) and parPoint[z] >= std::min(parSegA[z], parSegB[z]))
return false;
}
return true;
}
} //namespace cloonel

23
src/geometry_2d.cpp Normal file
View file

@ -0,0 +1,23 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "geometry_2d.hpp"
namespace cloonel {
} //namespace cloonel

43
src/geometry_2d.hpp Normal file
View file

@ -0,0 +1,43 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vector.hpp"
#include "line.hpp"
#include "geometry.hpp"
#include <ciso646>
#include <algorithm>
#include <utility>
#ifndef id2B404E7CFDD3470680E572779CB819F6
#define id2B404E7CFDD3470680E572779CB819F6
namespace cloonel {
template <typename T>
int GetOrientation ( const Vector<T, 2>& parPointA, const Vector<T, 2>& parPointB, const Vector<T, 2>& parPointC ) __attribute__((pure));
template <typename T>
bool Intersection2D ( const Vector<T, 2>& parSegA1, const Vector<T, 2>& parSegA2, const Vector<T, 2>& parSegB1, const Vector<T, 2>& parSegB2 ) __attribute__((pure));
template <typename T>
std::pair<bool, Vector<T, 2>> Intersection ( const Line<T, 2>& parSegA, const Line<T, 2>& parSegB ) __attribute__((pure));
} //namespace cloonel
#include "geometry_2d.inl"
#endif

88
src/geometry_2d.inl Normal file
View file

@ -0,0 +1,88 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
int GetOrientation (const Vector<T, 2>& parPointA, const Vector<T, 2>& parPointB, const Vector<T, 2>& parPointC) {
const auto ret =
(parPointB.y() - parPointA.y()) * (parPointC.x() - parPointB.x()) -
(parPointB.x() - parPointA.x()) * (parPointC.y() - parPointB.y());
const T zero(0);
if (ret == zero)
return 0;
else if (ret < zero)
return -1;
else
return 1;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
bool Intersection2D (const Vector<T, 2>& parSegA1, const Vector<T, 2>& parSegA2, const Vector<T, 2>& parSegB1, const Vector<T, 2>& parSegB2) {
const int o1 = GetOrientation(parSegA1, parSegA2, parSegB1);
const int o2 = GetOrientation(parSegA1, parSegA2, parSegB2);
const int o3 = GetOrientation(parSegB1, parSegB2, parSegA1);
const int o4 = GetOrientation(parSegB1, parSegB2, parSegA2);
if (o1 != o2 and o3 != o4)
return true;
if (0 == o1 and IsPointOnSegment(parSegA1, parSegB1, parSegA2))
return true;
if (0 == o2 and IsPointOnSegment(parSegA1, parSegB2, parSegA2))
return true;
if (0 == o3 and IsPointOnSegment(parSegB1, parSegA1, parSegB2))
return true;
if (0 == o4 and IsPointOnSegment(parSegB1, parSegA2, parSegB2))
return true;
return false;
}
///--------------------------------------------------------------------------
///http://www.gidforums.com/t-20866.html
///--------------------------------------------------------------------------
template <typename T>
std::pair<bool, Vector<T, 2>> Intersection (const Line<T, 2>& parSegA, const Line<T, 2>& parSegB) {
typedef Line<T, 2> LineType;
const typename LineType::Point& startA = parSegA[0];
const typename LineType::Point& endA = parSegA[1];
const typename LineType::Point& startB = parSegB[0];
const typename LineType::Point& endB = parSegB[1];
const T A1(endA.y() - startA.y());
const T A2(endB.y() - startB.y());
const T B1(startA.x() - endA.x());
const T B2(startB.x() - endB.x());
const T det(A1 * B2 - A2 * B1);
if (det == 0) {
return std::make_pair(false, typename LineType::Point(0));
}
else {
const T C1(A1 * startA.x() + B1 * startA.y());
const T C2(A2 * startB.x() + B2 * startB.y());
return std::make_pair(true, typename LineType::Point((B2 * C1 - B1 * C2) / det, (A1 * C2 - A2 * C1) / det));
}
}
} //namespace cloonel

View file

@ -97,7 +97,8 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
float2 HorzCollisionBar::To() const {
return this->GetPos() + len(m_segment);
assert(m_segment.End().x() - m_segment.Start().x() != 0.0f);
return this->GetPos() + float2(std::abs(m_segment.End().x() - m_segment.Start().x()), 0.0f);
}
///--------------------------------------------------------------------------

View file

@ -23,6 +23,8 @@
#include "compatibility.h"
#include "vector.hpp"
#include "vectormath.hpp"
#include <ciso646>
#include <cstdint>
namespace cloonel {
template <typename T, uint32_t S>
@ -36,6 +38,7 @@ namespace cloonel {
Line ( const Line& parOther );
Line ( const Point& parStart, const Point& parEnd );
Line ( const Point& parStart, const Point& parDirection, Scalar parLength ) : Line(parStart, parStart + parDirection * parLength) { }
Line ( Scalar parX1, Scalar parY1, Scalar parX2, Scalar parY2 );
~Line ( void ) noexcept = default;
Point& Start ( void ) { return m_points.x(); }
@ -43,8 +46,15 @@ namespace cloonel {
const Point& Start ( void ) const { return m_points.x(); }
const Point& End ( void ) const { return m_points.y(); }
Point& operator[] ( int parIndex ) { assert(parIndex >= 0); return m_points[static_cast<uint32_t>(parIndex)]; }
const Point& operator[] ( int parIndex ) const { assert(parIndex >= 0); return m_points[static_cast<uint32_t>(parIndex)]; }
Point& operator[] ( uint32_t parIndex ) { return m_points[parIndex]; }
const Point& operator[] ( uint32_t parIndex ) const { return m_points[parIndex]; }
Line& operator+= ( const Point& parRhs ) a_flatten;
Line& operator-= ( const Point& parRhs ) a_flatten;
template <typename U>
Line& operator*= ( const Vector<U, S>& parRhs ) a_flatten;
private:
Vector<Point, 2> m_points;
@ -58,6 +68,10 @@ namespace cloonel {
Line<T, S> operator+ ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) a_pure a_flatten;
template <typename T, uint32_t S>
Line<T, S> operator- ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) a_pure a_flatten;
template <typename T, typename U, uint32_t S>
Line<T, S> operator* ( const Vector<U, S>& parLhs, Line<T, S> parRhs ) a_pure a_flatten;
template <typename T, typename U, uint32_t S>
Line<T, S> operator* ( Line<T, S> parLhs, const Vector<U, S>& parRhs ) a_pure a_flatten;
template <typename T>
bool operator> ( const Vector<T, 2>& parLhs, const Line<T, 2>& parRhs ) a_pure;

View file

@ -23,6 +23,14 @@ namespace cloonel {
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S>::Line (Scalar parX1, Scalar parY1, Scalar parX2, Scalar parY2) :
m_points(Point(parX1, parY1), Point(parX2, parY2))
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
@ -44,7 +52,17 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S> operator+ ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) {
template <typename U>
Line<T, S>& Line<T, S>::operator*= (const Vector<U, S>& parRhs) {
m_points.x() = static_cast<Point>(m_points.x() * parRhs);
m_points.y() = static_cast<Point>(m_points.y() * parRhs);
return *this;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S> operator+ (const Vector<T, S>& parLhs, Line<T, S> parRhs) {
parRhs += parLhs;
return parRhs;
}
@ -52,7 +70,7 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S> operator- ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) {
Line<T, S> operator- (const Vector<T, S>& parLhs, Line<T, S> parRhs) {
parRhs -= parLhs;
return parRhs;
}
@ -60,7 +78,7 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S> operator+ ( Line<T, S> parLhs, const Vector<T, S>& parRhs ) {
Line<T, S> operator+ (Line<T, S> parLhs, const Vector<T, S>& parRhs) {
parLhs += parRhs;
return parLhs;
}
@ -68,11 +86,27 @@ namespace cloonel {
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, uint32_t S>
Line<T, S> operator- ( Line<T, S> parLhs, const Vector<T, S>& parRhs ) {
Line<T, S> operator- (Line<T, S> parLhs, const Vector<T, S>& parRhs) {
parLhs -= parRhs;
return parLhs;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, typename U, uint32_t S>
Line<T, S> operator* (const Vector<U, S>& parLhs, Line<T, S> parRhs) {
parRhs *= parLhs;
return parRhs;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T, typename U, uint32_t S>
Line<T, S> operator* (Line<T, S> parLhs, const Vector<U, S>& parRhs) {
parLhs *= parRhs;
return parLhs;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>

View file

@ -44,6 +44,7 @@ namespace cloonel {
void MoverSine::ApplyMotion (float parDelta) {
const float pitwo = static_cast<float>(M_PI) * 2.0f;
m_alpha += parDelta * 2.6f;
//TODO: optimize - see https://groups.google.com/forum/#!topic/comp.graphics.api.opengl/FFl3djAYERs
while (m_alpha >= pitwo)
m_alpha -= pitwo;
}

View file

@ -74,4 +74,10 @@ namespace cloonel {
void Platform::OnRegister (Mover& parMover, Mover::PlaceableTicketType parParentTicket) {
parMover.RegisterPlaceable(m_collisionTop.get(), parParentTicket);
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void Platform::CopyDrawables (std::vector<const Drawable*>& parOut) const {
parOut.push_back(this);
}
} //namespace cloonel

View file

@ -25,6 +25,7 @@
#include "placeable.hpp"
#include "collidertypedef.hpp"
#include <memory>
#include <vector>
namespace cloonel {
class Texture;
@ -33,6 +34,10 @@ namespace cloonel {
class Platform : public Drawable, public Placeable {
public:
enum {
SurfaceCount = 1
};
Platform ( SDLMain* parSdlMain, const float2& parPos, Texture* parTexture, const float2& parSize );
Platform ( Platform&& parOther ) noexcept;
Platform ( const Platform& ) = delete;
@ -42,6 +47,7 @@ namespace cloonel {
float2 TopLeft ( void ) const { return GetPos(); }
float2 BottomRight ( void ) const { return TopLeft() + m_size; }
const HorzCollisionBar* TopCollisionBar ( void ) const { return m_collisionTop.get(); }
void CopyDrawables ( std::vector<const Drawable*>& parOut ) const;
//Overrides
virtual void Draw ( void ) const;

View file

@ -79,9 +79,9 @@ namespace cloonel {
void PlatformSet::CopyDrawables (std::vector<const Drawable*>& parOut) const {
auto eleCopy = FindFirstVisible(m_platforms);
const size_t count = checked_numcast<size_t>(m_platforms.end() - eleCopy);
parOut.reserve(parOut.size() + count);
parOut.reserve(parOut.size() + count * Platform::SurfaceCount);
while (m_platforms.end() != eleCopy) {
parOut.push_back(&*eleCopy);
eleCopy->CopyDrawables(parOut);
++eleCopy;
}
}

View file

@ -25,6 +25,7 @@
#include <ciso646>
#include <type_traits>
#include <algorithm>
#include <cassert>
#if !defined(NDEBUG)
#include <iostream>
@ -76,21 +77,21 @@ namespace cloonel {
template <typename U> const Vector& operator*= ( U parOther );
template <typename U> const Vector& operator/= ( U parOther );
T& operator[] ( uint32_t parIndex ) { return m_mem[parIndex]; }
const T& operator[] ( uint32_t parIndex ) const { return m_mem[parIndex]; }
T& operator[] ( uint32_t parIndex ) { assert(parIndex < S); return m_mem[parIndex]; }
const T& operator[] ( uint32_t parIndex ) const { assert(parIndex < S); return m_mem[parIndex]; }
private:
T m_mem[S];
};
template <typename T, typename U, uint32_t S>
Vector<typename std::common_type<T, U>::type, S> operator+ ( Vector<T, S> parA, const Vector<U, S>& parB ) a_pure;
Vector<typename std::common_type<T, U>::type, S> operator+ ( const Vector<T, S>& parA, const Vector<U, S>& parB ) a_pure;
template <typename T, typename U, uint32_t S>
Vector<typename std::common_type<T, U>::type, S> operator- ( Vector<T, S> parA, const Vector<U, S>& parB ) a_pure;
Vector<typename std::common_type<T, U>::type, S> operator- ( const Vector<T, S>& parA, const Vector<U, S>& parB ) a_pure;
template <typename T, typename U, uint32_t S>
Vector<typename std::common_type<T, U>::type, S> operator* ( Vector<T, S> parA, const Vector<U, S>& parB ) a_pure;
Vector<typename std::common_type<T, U>::type, S> operator* ( const Vector<T, S>& parA, const Vector<U, S>& parB ) a_pure;
template <typename T, typename U, uint32_t S>
Vector<typename std::common_type<T, U>::type, S> operator/ ( Vector<T, S> parA, const Vector<U, S>& parB ) a_pure;
Vector<typename std::common_type<T, U>::type, S> operator/ ( const Vector<T, S>& parA, const Vector<U, S>& parB ) a_pure;
template <typename T, typename U, uint32_t S, typename=typename std::enable_if<std::is_fundamental<U>::value>::type>
Vector<typename std::common_type<T, U>::type, S> operator+ ( U parA, const Vector<T, S>& parB ) a_pure;
template <typename T, typename U, uint32_t S, typename=typename std::enable_if<std::is_fundamental<U>::value>::type>
@ -126,6 +127,9 @@ namespace cloonel {
typedef Vector<float, 2> float2;
typedef Vector<uint16_t, 2> ushort2;
#if !defined(NDEBUG)
typedef Vector<int16_t, 2> short2;
#endif
typedef Vector<int32_t, 2> int2;
#if !defined(NDEBUG)
@ -140,6 +144,71 @@ namespace cloonel {
}
#endif
namespace implem {
template <typename T, typename U>
struct CategorizeTypes {
typedef typename std::common_type<T, U>::type CommonType;
typedef typename std::conditional<std::is_same<CommonType, T>::value, U, T>::type OtherType;
};
template <typename Cat, uint32_t S, bool Straightforward=std::is_same<typename Cat::CommonType, typename Cat::OtherType>::value>
struct DoOperation {
static Vector<typename Cat::CommonType, S> do_mul ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
parLho *= parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_div ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
parLho /= parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_sum ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
parLho += parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_sub ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
parLho -= parRho;
return parLho;
}
};
template <typename Cat, uint32_t S>
struct DoOperation<Cat, S, false> {
static Vector<typename Cat::CommonType, S> do_mul ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
parLho *= parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_mul ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
Vector<typename Cat::CommonType, S> ret(parLho);
ret *= parRho;
return ret;
}
static Vector<typename Cat::CommonType, S> do_div ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
parLho /= parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_div ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
Vector<typename Cat::CommonType, S> ret(parLho);
ret /= parRho;
return ret;
}
static Vector<typename Cat::CommonType, S> do_sum ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
parLho += parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_sum ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
Vector<typename Cat::CommonType, S> ret(parLho);
ret += parRho;
return ret;
}
static Vector<typename Cat::CommonType, S> do_sub ( Vector<typename Cat::CommonType, S> parLho, const Vector<typename Cat::OtherType, S>& parRho ) {
parLho -= parRho;
return parLho;
}
static Vector<typename Cat::CommonType, S> do_sub ( const Vector<typename Cat::OtherType, S>& parLho, const Vector<typename Cat::CommonType, S>& parRho ) {
Vector<typename Cat::CommonType, S> ret(parLho);
ret -= parRho;
return ret;
}
};
} //namespace implem
} //namespace cloonel
#include "vector.inl"

View file

@ -121,27 +121,23 @@ namespace cloonel {
///-------------------------------------------------------------------------
template <typename T, typename U, uint32_t S>
inline
Vector<typename std::common_type<T, U>::type, S> operator+ (Vector<T, S> parA, const Vector<U, S>& parB) {
parA += parB;
return parA;
Vector<typename std::common_type<T, U>::type, S> operator+ (const Vector<T, S>& parA, const Vector<U, S>& parB) {
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_sum(parA, parB);
}
template <typename T, typename U, uint32_t S>
inline
Vector<typename std::common_type<T, U>::type, S> operator- (Vector<T, S> parA, const Vector<U, S>& parB) {
parA -= parB;
return parA;
Vector<typename std::common_type<T, U>::type, S> operator- (const Vector<T, S>& parA, const Vector<U, S>& parB) {
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_sub(parA, parB);
}
template <typename T, typename U, uint32_t S>
inline
Vector<typename std::common_type<T, U>::type, S> operator* (Vector<T, S> parA, const Vector<U, S>& parB) {
parA *= parB;
return parA;
Vector<typename std::common_type<T, U>::type, S> operator* (const Vector<T, S>& parA, const Vector<U, S>& parB) {
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_mul(parA, parB);
}
template <typename T, typename U, uint32_t S>
inline
Vector<typename std::common_type<T, U>::type, S> operator/ (Vector<T, S> parA, const Vector<U, S>& parB) {
parA /= parB;
return parA;
Vector<typename std::common_type<T, U>::type, S> operator/ (const Vector<T, S>& parA, const Vector<U, S>& parB) {
return implem::DoOperation<implem::CategorizeTypes<T, U>, S>::do_div(parA, parB);
}
///-------------------------------------------------------------------------
@ -243,11 +239,7 @@ namespace cloonel {
}
template <typename T, typename U, uint32_t S>
inline bool operator!= (const Vector<T, S>& parA, const Vector<U, S>& parB) {
bool retVal = true;
for (uint32_t z = 0; z < S; ++z) {
retVal &= static_cast<bool>(parA[z] != parB[z]);
}
return retVal;
return not operator==(parA, parB);
}
template <typename T, uint32_t S>