Compare commits
40 commits
Author | SHA1 | Date | |
---|---|---|---|
a1b66e99f0 | |||
|
ba60426cc2 | ||
|
b0f02fd8a8 | ||
8669e5e674 | |||
c30b4e430e | |||
19db180460 | |||
ceb3e180fe | |||
77e2bf539f | |||
6ce7b57882 | |||
ad5b9d8fb8 | |||
41585f1982 | |||
e53e59e4ff | |||
65b6269cea | |||
012daa47d7 | |||
c6e7f68a0f | |||
3ed0a214da | |||
706f1aaa0a | |||
10f830809b | |||
0a3897f60a | |||
7f49ef36d6 | |||
ce9eff82f1 | |||
b5f7e30471 | |||
5e76b49cae | |||
0b6cdeb5f5 | |||
72bfb64795 | |||
a87255ef66 | |||
68d179975e | |||
650f8d6de1 | |||
e64b53f8d0 | |||
d12b7f777a | |||
19dc6759df | |||
7985ba2bc4 | |||
a7bd060452 | |||
09299595fe | |||
09b41f6d0c | |||
8d2f7085c4 | |||
1ef3dc86ac | |||
c27055f8d0 | |||
efb0f93062 | |||
cc0f174be5 |
6
.gitignore
vendored
|
@ -1,3 +1,9 @@
|
|||
tags
|
||||
.clang_complete
|
||||
*.swp
|
||||
cscope.in.out
|
||||
cscope.out
|
||||
cscope.po.out
|
||||
.ycm_extra_conf.py
|
||||
__pycache__/
|
||||
compile_commands.json
|
||||
|
|
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
[submodule "lib/vectorwrapper"]
|
||||
path = lib/vectorwrapper
|
||||
url = https://github.com/KingDuckZ/vectorwrapper.git
|
||||
[submodule "lib/catch"]
|
||||
path = lib/catch
|
||||
url = https://github.com/philsquared/Catch.git
|
131
CMakeLists.txt
|
@ -1,20 +1,31 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(CloonelJump CXX)
|
||||
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
|
||||
project(CloonelJumpProject CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
|
||||
|
||||
include(TargetArch)
|
||||
include(CTest)
|
||||
include(FindPkgConfig)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
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 -DWITH_DEBUG_VISUALS -O0")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -Wall -Wextra -pedantic -Wconversion -O3")
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(Boost 1.55.0 REQUIRED)
|
||||
find_package(PhysFS 2.0.3)
|
||||
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wconversion")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -pedantic -Wconversion -DWITH_DEBUG_VISUALS -O0")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -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")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CLOONEL_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
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)
|
||||
cmake_dependent_option(WITH_BUILTIN_PHYSFS "Force using the version of PhysFS accompanying the code even if a system library is available" OFF "PHYSFS_FOUND" ON)
|
||||
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)
|
||||
|
||||
|
@ -26,34 +37,19 @@ if (TARGET_ARCH MATCHES "^x86_64$")
|
|||
endif (TARGET_ARCH MATCHES "^x86_64$")
|
||||
|
||||
if (FORCE_OPENGLES OR RASPBERRY_PI)
|
||||
add_definitions(-DFORCE_OPENGLES)
|
||||
target_add_definitions(${PROJECT_NAME} INTERFACE -DFORCE_OPENGLES)
|
||||
if (RASPBERRY_PI)
|
||||
add_definitions(-DRASPBERRY_PI)
|
||||
target_add_definitions(${PROJECT_NAME} INTERFACE -DRASPBERRY_PI)
|
||||
endif(RASPBERRY_PI)
|
||||
endif (FORCE_OPENGLES OR RASPBERRY_PI)
|
||||
|
||||
include(FindPkgConfig)
|
||||
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(Boost 1.55.0 REQUIRED)
|
||||
if (NOT WITH_BUILTIN_PHYSFS)
|
||||
find_package(PhysFS 2.0.3)
|
||||
endif()
|
||||
|
||||
if (PHYSFS_FOUND)
|
||||
message(STATUS "Using system's PhysFS, set WITH_BUILTIN_PHYSFS to on to override this")
|
||||
else(PHYSFS_FOUND)
|
||||
if (WITH_BUILTIN_PHYSFS)
|
||||
message(STATUS "Using internal PhysFS")
|
||||
set(PHYSFS_INCLUDE_DIR "lib/physfs-2.0.3")
|
||||
set(PHYSFS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib/physfs-2.0.3")
|
||||
set(PHYSFS_LIBRARY "physfs")
|
||||
endif(PHYSFS_FOUND)
|
||||
|
||||
add_definitions(
|
||||
${PNG_DEFINITIONS}
|
||||
# -DWITH_VERBOSE_OBS_MANAGER
|
||||
-DWITH_VERBOSE_COLLIDER
|
||||
)
|
||||
else(WITH_BUILTIN_PHYSFS)
|
||||
message(STATUS "Using system's PhysFS, set WITH_BUILTIN_PHYSFS to on to override this")
|
||||
endif(WITH_BUILTIN_PHYSFS)
|
||||
|
||||
if (RASPBERRY_PI)
|
||||
message(STATUS "Will build for Raspberry Pi")
|
||||
|
@ -67,18 +63,22 @@ if (RASPBERRY_PI)
|
|||
)
|
||||
endif (RASPBERRY_PI)
|
||||
|
||||
include_directories(SYSTEM
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${PNG_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
lib/tree-2.81/src
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||
INTERFACE ${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
include_directories(
|
||||
src
|
||||
src/movers
|
||||
include
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
${PHYSFS_INCLUDE_DIR}
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
INTERFACE "${PROJECT_BINARY_DIR}"
|
||||
INTERFACE lib/tree-3.1/src
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
INTERFACE VWR_STATIC_CAST_RESULTS
|
||||
INTERFACE VWR_SIZE_TYPE=uint32_t
|
||||
INTERFACE VWR_OUTER_NAMESPACE=cloonel
|
||||
INTERFACE ${PNG_DEFINITIONS}
|
||||
)
|
||||
|
||||
configure_file(
|
||||
|
@ -86,50 +86,19 @@ configure_file(
|
|||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.h"
|
||||
)
|
||||
|
||||
if (NOT PHYSFS_FOUND)
|
||||
add_subdirectory(lib/physfs-2.0.3)
|
||||
endif(NOT PHYSFS_FOUND)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/main.cpp
|
||||
src/texture.cpp
|
||||
src/sdlerror.cpp
|
||||
src/sdlmain.cpp
|
||||
src/gamebase.cpp
|
||||
src/character.cpp
|
||||
src/placeable.cpp
|
||||
src/physicsfswrapper.cpp
|
||||
src/gameplayscene.cpp
|
||||
src/movers/mover.cpp
|
||||
src/movers/moveroneshot.cpp
|
||||
src/movers/moversine.cpp
|
||||
src/gameplaysceneclassic.cpp
|
||||
src/movers/moverrelative.cpp
|
||||
src/inputbag.cpp
|
||||
src/movers/moverleftright.cpp
|
||||
src/tiledwallpaper.cpp
|
||||
src/drawable.cpp
|
||||
src/sizeratio.cpp
|
||||
src/sizenotifiable.cpp
|
||||
src/horzcollisionbar.cpp
|
||||
src/platform.cpp
|
||||
src/vectormath.cpp
|
||||
src/platformspawner.cpp
|
||||
src/movers/moverworld.cpp
|
||||
src/line.cpp
|
||||
src/collider.cpp
|
||||
src/platformset.cpp
|
||||
src/drawableline.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
${SDL2_LIBRARIES}
|
||||
${PHYSFS_LIBRARY}
|
||||
${PNG_LIBRARIES}
|
||||
)
|
||||
|
||||
if (RASPBERRY_PI)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
bcm_host
|
||||
)
|
||||
endif(RASPBERRY_PI)
|
||||
|
||||
if (NOT PHYSFS_FOUND)
|
||||
add_subdirectory(lib/physfs-2.0.3)
|
||||
endif(NOT PHYSFS_FOUND)
|
||||
|
||||
add_subdirectory(src/jumping)
|
||||
add_subdirectory(src/clooneljump)
|
||||
add_subdirectory(src/cloonelgraphics)
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(test/unit)
|
||||
endif()
|
||||
|
|
|
@ -17,28 +17,17 @@
|
|||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef idE31BEAEB229149038D67C6CF370AEEC9
|
||||
#define idE31BEAEB229149038D67C6CF370AEEC9
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
//See vectorwrapper.hpp.in for comments
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#include <iostream>
|
||||
#pragma push_macro("VWR_OUTER_NAMESPACE")
|
||||
#if defined(VWR_OUTER_NAMESPACE)
|
||||
# undef VWR_OUTER_NAMESPACE
|
||||
#endif
|
||||
|
||||
namespace cloonel {
|
||||
#if !defined(NDEBUG)
|
||||
template <typename T, uint32_t S>
|
||||
inline std::ostream& operator<< (std::ostream& parOStream, const Vector<T, S>& parVec) {
|
||||
parOStream << "<";
|
||||
for (uint32_t z = 0; z < S - 1; ++z) {
|
||||
parOStream << parVec[z] << ", ";
|
||||
}
|
||||
parOStream << parVec[S - 1] << ">";
|
||||
return parOStream;
|
||||
}
|
||||
#define VWR_OUTER_NAMESPACE cloonel
|
||||
#include "@CMAKE_CURRENT_SOURCE_DIR@/../../lib/vectorwrapper/include/vectorwrapper/vector_cast.hpp"
|
||||
#undef VWR_OUTER_NAMESPACE
|
||||
|
||||
#endif
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
||||
#pragma pop_macro("VWR_OUTER_NAMESPACE")
|
33
cloonel_vectorwrapper/vectorops.hpp.in
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//See vectorwrapper.hpp.in for comments
|
||||
|
||||
#pragma push_macro("VWR_OUTER_NAMESPACE")
|
||||
#if defined(VWR_OUTER_NAMESPACE)
|
||||
# undef VWR_OUTER_NAMESPACE
|
||||
#endif
|
||||
|
||||
#define VWR_OUTER_NAMESPACE cloonel
|
||||
#include "@CMAKE_CURRENT_SOURCE_DIR@/../../lib/vectorwrapper/include/vectorwrapper/vectorops.hpp"
|
||||
#undef VWR_OUTER_NAMESPACE
|
||||
|
||||
#pragma pop_macro("VWR_OUTER_NAMESPACE")
|
42
cloonel_vectorwrapper/vectorwrapper.hpp.in
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//The reason for this file is that I want to force cloonelgraphics to use the
|
||||
//version of vectorwrapper that it's bundled with in git. When it's used as a
|
||||
//library into a project different than clooneljump, the outer project will
|
||||
//probably have its own version of vectorwrapper, and likely in a different
|
||||
//outer namespace. Since both sdlmain.hpp, for example, and some hypotetical
|
||||
//mygame.cpp from the client code will both #include
|
||||
//"vectorwrapper/vectorwrapper.hpp", the search paths at the time mygame.cpp is
|
||||
//built will be different than the one used by cloonelgraphics. By putting an
|
||||
//absolute path here and forcing the outer namespace to cloonel this problem
|
||||
//should be avoided.
|
||||
|
||||
#pragma push_macro("VWR_OUTER_NAMESPACE")
|
||||
#if defined(VWR_OUTER_NAMESPACE)
|
||||
# undef VWR_OUTER_NAMESPACE
|
||||
#endif
|
||||
|
||||
#define VWR_OUTER_NAMESPACE cloonel
|
||||
#include "@CMAKE_CURRENT_SOURCE_DIR@/../../lib/vectorwrapper/include/vectorwrapper/vectorwrapper.hpp"
|
||||
#undef VWR_OUTER_NAMESPACE
|
||||
|
||||
#pragma pop_macro("VWR_OUTER_NAMESPACE")
|
30
docs/wrong_virtual_call.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
## Bug description ##
|
||||
1) SizeNotifiable, defined as the following:
|
||||
|
||||
class SizeNotifiable<RegisterBehaviour, true> : private RegisterBehaviour, public SizeNotifiableBase { ... };
|
||||
|
||||
gets constructed - it inherits from SizeNotifiableBase which declares NotifyResChanged() as virtual. It also inherits from RegisterBehaviour, which must provide a Register() method.
|
||||
|
||||
2) In SizeNotifiable's constructor RegisterBehaviour::Register(this) gets called. Being in the constructor, virtual calls on this are UB.
|
||||
|
||||
3) When RegisterBehaviour == AutoRegister, we have Register defined as the following:
|
||||
|
||||
void AutoRegister::Register (SizeNotifiableBase* parNotifiable) {
|
||||
m_id = m_sdlmain->RegisterForResChange(parNotifiable);
|
||||
}
|
||||
|
||||
note that parNotifiable is received from SizeNotifiable's constructor, so it's a partially constructed object.
|
||||
|
||||
4) RegisterForResChange() is defined as:
|
||||
|
||||
size_t SDLMain::RegisterForResChange (SizeNotifiableBase* parNotif) {
|
||||
parNotif->NotifyResChanged(m_localData->sizeratio);
|
||||
return m_localData->resChangeNotifList.Add(parNotif);
|
||||
}
|
||||
|
||||
parNotif is, again, the partly constructed object pointed by this in SizeNotifiable's constructor. NotifyResChanged() is a virtual method, thus the bug.
|
||||
Objects being registered need to be notified straight away since they have no clue about the current size held by SDLMain.
|
||||
|
||||
|
||||
## Solution ##
|
||||
Fixed at commit 5e76b49cae954accd1533d6b6431af7cb5f770ef doing something that I call *deferred virtual call*. A temporary object is passed down in the SizeNotifiable's hierarchy. This object's destructor calls the Register() method *if the stack is not being unwinded due to an exception*. Since the object is passed from the top (from outside the topmost constructor), its destructor gets called after the end of the scope of the topmost constructor in the SizeNotifiable's hierarchy. By that point all virtual tables should be set to their final state.
|
1
lib/catch
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 30cebd617788f6b399297725f97317f9bc462114
|
|
@ -1,2 +1,3 @@
|
|||
a.out
|
||||
*~
|
||||
doxygen
|
|
@ -1,3 +1,22 @@
|
|||
2015-05-06 Kasper Peeters <kasper.peeters@phi-sci.com>
|
||||
|
||||
* Released 3.1
|
||||
|
||||
* Added asserts in 'subtree' in order to warn users about
|
||||
constructing empty subtrees.
|
||||
|
||||
2014-12-25 Kasper Peeters <kasper.peeters@phi-sci.com>
|
||||
|
||||
* Released 3.0
|
||||
|
||||
* Added move constructor and move_out, move_in, move_in_as_nth_child.
|
||||
|
||||
2013-09-02 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.9
|
||||
|
||||
* Added 'pre_order_iterator::next_skip_children()'.
|
||||
|
||||
2011-08-23 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Brown paper bag release 2.81.
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
RELEASE=2.8
|
||||
RELEASE=3.1
|
||||
HTML=${HOME}/public_html/
|
||||
|
||||
.PHONY: doc tarball
|
|
@ -76,7 +76,7 @@
|
|||
and all other things referred to on this page) is contained in the
|
||||
tarball</div>
|
||||
<div class="filename">
|
||||
<a href="tree-2.8.tar.gz">tree-2.8.tar.gz</a>
|
||||
<a href="tree-2.81.tar.gz">tree-2.81.tar.gz</a>
|
||||
</div>
|
||||
<div class="text">
|
||||
Feel free to copy the header <a href="tree.hh">tree.hh</a>
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 782 B After Width: | Height: | Size: 782 B |
Before Width: | Height: | Size: 881 B After Width: | Height: | Size: 881 B |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 888 KiB After Width: | Height: | Size: 888 KiB |
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
|
@ -1,3 +1,4 @@
|
|||
*.o
|
||||
*.res
|
||||
test1
|
||||
test2
|
|
@ -1,10 +1,15 @@
|
|||
|
||||
%.o: %.cc
|
||||
g++ -c -I. $^
|
||||
all: test1 test2
|
||||
|
||||
%.o: %.cc
|
||||
g++ -g -c -Wall -O2 -std=c++11 -I. $^
|
||||
|
||||
test1: test1.o
|
||||
g++ -o test1 test1.o
|
||||
|
||||
test2: test2.o
|
||||
g++ -o test2 test2.o
|
||||
|
||||
run_tests: test1 test1.req
|
||||
./test1 > test1.res
|
||||
@diff test1.res test1.req
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
#include <iostream>
|
||||
#include "tree.hh"
|
||||
#include "tree_util.hh"
|
||||
|
111
lib/tree-3.1/src/test2.cc
Normal file
|
@ -0,0 +1,111 @@
|
|||
|
||||
#include <iostream>
|
||||
#include "tree.hh"
|
||||
#include "tree_util.hh"
|
||||
|
||||
tree<std::string> test_move_constructor()
|
||||
{
|
||||
tree<std::string> mtree;
|
||||
tree<std::string>::iterator it = mtree.set_head("top");
|
||||
mtree.append_child(it, "one");
|
||||
mtree.append_child(it, "two");
|
||||
mtree.append_child(it, "three");
|
||||
|
||||
tree<std::string> ctree(std::move(mtree));
|
||||
|
||||
std::cout << "ctree:" << std::endl;
|
||||
kptree::print_tree_bracketed(ctree);
|
||||
std::cout << "\nmtree:" << std::endl;
|
||||
kptree::print_tree_bracketed(mtree);
|
||||
|
||||
return ctree;
|
||||
}
|
||||
|
||||
tree<std::string> test_move_out()
|
||||
{
|
||||
tree<std::string> mtree;
|
||||
tree<std::string>::iterator it = mtree.set_head("top");
|
||||
mtree.append_child(it, "one");
|
||||
auto it2 = mtree.append_child(it, "two");
|
||||
mtree.append_child(it, "three");
|
||||
mtree.append_child(it2, "four");
|
||||
mtree.append_child(it2, "five");
|
||||
|
||||
auto ret = mtree.move_out(it2);
|
||||
ret.debug_verify_consistency();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void test_move_in(tree<std::string>& other)
|
||||
{
|
||||
tree<std::string> mtree;
|
||||
tree<std::string>::iterator it = mtree.set_head("top");
|
||||
mtree.append_child(it, "one");
|
||||
auto it3=mtree.append_child(it, "three");
|
||||
|
||||
mtree.move_in(it3, other);
|
||||
mtree.debug_verify_consistency();
|
||||
kptree::print_tree_bracketed(mtree);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void test_move_in_as_nth_child(int n)
|
||||
{
|
||||
tree<std::string> mtree, other;
|
||||
tree<std::string>::iterator it = mtree.set_head("top");
|
||||
mtree.append_child(it, "one");
|
||||
mtree.append_child(it, "three");
|
||||
|
||||
auto ot1 = other.set_head("hi");
|
||||
other.insert_after(ot1, "second");
|
||||
other.append_child(ot1, "1");
|
||||
other.append_child(ot1, "2");
|
||||
|
||||
mtree.move_in_as_nth_child(it, n, other);
|
||||
mtree.debug_verify_consistency();
|
||||
kptree::print_tree_bracketed(mtree);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
void test_move_below(tree<std::string>& other)
|
||||
{
|
||||
tree<std::string> mtree;
|
||||
tree<std::string>::iterator it = mtree.set_head("top");
|
||||
mtree.append_child(it, "one");
|
||||
auto it3=mtree.append_child(it, "three");
|
||||
|
||||
mtree.move_in(it3, other);
|
||||
kptree::print_tree_bracketed(mtree);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Move constructor.
|
||||
tree<std::string> res = test_move_constructor();
|
||||
std::cout << "res:" << std::endl;
|
||||
kptree::print_tree_bracketed(res);
|
||||
|
||||
// Move out.
|
||||
tree<std::string> res2 = test_move_out();
|
||||
std::cout << "\nres2:" << std::endl;
|
||||
kptree::print_tree_bracketed(res2);
|
||||
std::cout << std::endl;
|
||||
|
||||
// Move in.
|
||||
test_move_in(res2);
|
||||
std::cout << "\n";
|
||||
kptree::print_tree_bracketed(res2);
|
||||
std::cout << "\n";
|
||||
|
||||
// Move in as nth child.
|
||||
test_move_in_as_nth_child(0);
|
||||
test_move_in_as_nth_child(1);
|
||||
test_move_in_as_nth_child(2);
|
||||
try {
|
||||
test_move_in_as_nth_child(3);
|
||||
}
|
||||
catch(const std::range_error& ex) {
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
}
|
|
@ -365,14 +365,8 @@ int main(int argc, char **argv)
|
|||
++li;
|
||||
}
|
||||
|
||||
// tree<std::string> testfixed;
|
||||
// testfixed.insert(testfixed.begin(), "one");
|
||||
// testfixed.insert(testfixed.begin(), "two");
|
||||
// testfixed.insert(testfixed.begin(), "three");
|
||||
// tree<std::string>::fixed_depth_iterator fit=testfixed.begin();
|
||||
// while(testfixed.is_valid(fit)) {
|
||||
// std::cout << *fit << std::endl;
|
||||
// ++fit;
|
||||
// }
|
||||
// test_move_constructor();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
|
||||
// STL-like templated tree class.
|
||||
//
|
||||
// Copyright (C) 2001-2011 Kasper Peeters <kasper@phi-sci.com>
|
||||
// Copyright (C) 2001-2014 Kasper Peeters <kasper@phi-sci.com>
|
||||
// Distributed under the GNU General Public License version 3.
|
||||
//
|
||||
// When used together with the htmlcxx library to create
|
||||
// HTML::Node template instances, the GNU Lesser General Public
|
||||
// version 2 applies. Special permission to use tree.hh under
|
||||
// the LGPL for other projects can be requested from the author.
|
||||
// Special permission to use tree.hh under the conditions of a
|
||||
// different license can be requested from the author.
|
||||
|
||||
/** \mainpage tree.hh
|
||||
\author Kasper Peeters
|
||||
\version 2.81
|
||||
\date 23-Aug-2011
|
||||
\version 3.1
|
||||
\date 06-May-2015
|
||||
\see http://tree.phi-sci.com/
|
||||
\see http://tree.phi-sci.com/ChangeLog
|
||||
|
||||
|
@ -77,12 +75,14 @@ class tree {
|
|||
class sibling_iterator;
|
||||
class leaf_iterator;
|
||||
|
||||
tree();
|
||||
tree(const T&);
|
||||
tree(); // empty constructor
|
||||
tree(const T&); // constructor setting given element as head
|
||||
tree(const iterator_base&);
|
||||
tree(const tree<T, tree_node_allocator>&);
|
||||
tree(const tree<T, tree_node_allocator>&); // copy constructor
|
||||
tree(tree<T, tree_node_allocator>&&); // move constructor
|
||||
~tree();
|
||||
tree<T,tree_node_allocator>& operator=(const tree<T, tree_node_allocator>&);
|
||||
tree<T,tree_node_allocator>& operator=(const tree<T, tree_node_allocator>&); // copy assignment
|
||||
tree<T,tree_node_allocator>& operator=(tree<T, tree_node_allocator>&&); // move assignment
|
||||
|
||||
/// Base class for iterators, only pointers stored, no traversal logic.
|
||||
#ifdef __SGI_STL_PORT
|
||||
|
@ -134,6 +134,8 @@ class tree {
|
|||
pre_order_iterator operator--(int);
|
||||
pre_order_iterator& operator+=(unsigned int);
|
||||
pre_order_iterator& operator-=(unsigned int);
|
||||
|
||||
pre_order_iterator& next_skip_children();
|
||||
};
|
||||
|
||||
/// Depth-first iterator, first accessing the children, then the node itself.
|
||||
|
@ -275,9 +277,9 @@ class tree {
|
|||
/// Return iterator to the parent of a node.
|
||||
template<typename iter> static iter parent(iter);
|
||||
/// Return iterator to the previous sibling of a node.
|
||||
template<typename iter> iter previous_sibling(iter) const;
|
||||
template<typename iter> static iter previous_sibling(iter);
|
||||
/// Return iterator to the next sibling of a node.
|
||||
template<typename iter> iter next_sibling(iter) const;
|
||||
template<typename iter> static iter next_sibling(iter);
|
||||
/// Return iterator to the next node at a given depth.
|
||||
template<typename iter> iter next_at_same_depth(iter) const;
|
||||
|
||||
|
@ -308,6 +310,7 @@ class tree {
|
|||
/// Specialisation of previous member.
|
||||
sibling_iterator insert(sibling_iterator position, const T& x);
|
||||
/// Insert node (with children) pointed to by subtree as previous sibling of node pointed to by position.
|
||||
/// Does not change the subtree itself (use move_in or move_in_below for that).
|
||||
template<typename iter> iter insert_subtree(iter position, const iterator_base& subtree);
|
||||
/// Insert node as next sibling of node pointed to by position.
|
||||
template<typename iter> iter insert_after(iter position, const T& x);
|
||||
|
@ -340,6 +343,16 @@ class tree {
|
|||
/// Move 'source' node (plus its children) to become the node at 'target' (erasing the node at 'target').
|
||||
template<typename iter> iter move_ontop(iter target, iter source);
|
||||
|
||||
/// Extract the subtree starting at the indicated node, removing it from the original tree.
|
||||
tree move_out(iterator);
|
||||
/// Inverse of take_out: inserts the given tree as previous sibling of indicated node by a
|
||||
/// move operation, that is, the given tree becomes empty. Returns iterator to the top node.
|
||||
template<typename iter> iter move_in(iter, tree&);
|
||||
/// As above, but now make the tree a child of the indicated node.
|
||||
template<typename iter> iter move_in_below(iter, tree&);
|
||||
/// As above, but now make the tree the nth child of the indicated node (if possible).
|
||||
template<typename iter> iter move_in_as_nth_child(iter, size_t, tree&);
|
||||
|
||||
/// Merge with other tree, creating new branches and leaves only if they are not already present.
|
||||
void merge(sibling_iterator, sibling_iterator, sibling_iterator, sibling_iterator,
|
||||
bool duplicate_leaves=false);
|
||||
|
@ -486,6 +499,18 @@ tree<T, tree_node_allocator>::tree(const T& x)
|
|||
set_head(x);
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
tree<T, tree_node_allocator>::tree(tree<T, tree_node_allocator>&& x)
|
||||
{
|
||||
head_initialise_();
|
||||
head->next_sibling=x.head->next_sibling;
|
||||
feet->prev_sibling=x.head->prev_sibling;
|
||||
x.head->next_sibling->prev_sibling=head;
|
||||
x.feet->prev_sibling->next_sibling=feet;
|
||||
x.head->next_sibling=x.feet;
|
||||
x.feet->prev_sibling=x.head;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
tree<T, tree_node_allocator>::tree(const iterator_base& other)
|
||||
{
|
||||
|
@ -533,6 +558,20 @@ tree<T,tree_node_allocator>& tree<T, tree_node_allocator>::operator=(const tree<
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
tree<T,tree_node_allocator>& tree<T, tree_node_allocator>::operator=(tree<T, tree_node_allocator>&& x)
|
||||
{
|
||||
if(this != &x) {
|
||||
head->next_sibling=x.head->next_sibling;
|
||||
feet->prev_sibling=x.head->prev_sibling;
|
||||
x.head->next_sibling->prev_sibling=head;
|
||||
x.feet->prev_sibling->next_sibling=feet;
|
||||
x.head->next_sibling=x.feet;
|
||||
x.feet->prev_sibling=x.head;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
tree<T, tree_node_allocator>::tree(const tree<T, tree_node_allocator>& other)
|
||||
{
|
||||
|
@ -770,7 +809,7 @@ iter tree<T, tree_node_allocator>::parent(iter position)
|
|||
|
||||
template <class T, class tree_node_allocator>
|
||||
template <typename iter>
|
||||
iter tree<T, tree_node_allocator>::previous_sibling(iter position) const
|
||||
iter tree<T, tree_node_allocator>::previous_sibling(iter position)
|
||||
{
|
||||
assert(position.node!=0);
|
||||
iter ret(position);
|
||||
|
@ -780,7 +819,7 @@ iter tree<T, tree_node_allocator>::previous_sibling(iter position) const
|
|||
|
||||
template <class T, class tree_node_allocator>
|
||||
template <typename iter>
|
||||
iter tree<T, tree_node_allocator>::next_sibling(iter position) const
|
||||
iter tree<T, tree_node_allocator>::next_sibling(iter position)
|
||||
{
|
||||
assert(position.node!=0);
|
||||
iter ret(position);
|
||||
|
@ -1477,6 +1516,126 @@ template <typename iter> iter tree<T, tree_node_allocator>::move_ontop(iter targ
|
|||
return src;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
tree<T, tree_node_allocator> tree<T, tree_node_allocator>::move_out(iterator source)
|
||||
{
|
||||
tree ret;
|
||||
|
||||
// Move source node into the 'ret' tree.
|
||||
ret.head->next_sibling = source.node;
|
||||
ret.feet->prev_sibling = source.node;
|
||||
source.node->parent=0;
|
||||
|
||||
// Close the links in the current tree.
|
||||
if(source.node->prev_sibling!=0)
|
||||
source.node->prev_sibling->next_sibling = source.node->next_sibling;
|
||||
|
||||
if(source.node->next_sibling!=0)
|
||||
source.node->next_sibling->prev_sibling = source.node->prev_sibling;
|
||||
|
||||
// Fix source prev/next links.
|
||||
source.node->prev_sibling = ret.head;
|
||||
source.node->next_sibling = ret.feet;
|
||||
|
||||
return ret; // A good compiler will move this, not copy.
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
template<typename iter> iter tree<T, tree_node_allocator>::move_in(iter loc, tree& other)
|
||||
{
|
||||
if(other.head->next_sibling==other.feet) return loc; // other tree is empty
|
||||
|
||||
tree_node *other_first_head = other.head->next_sibling;
|
||||
tree_node *other_last_head = other.feet->prev_sibling;
|
||||
|
||||
sibling_iterator prev(loc);
|
||||
--prev;
|
||||
|
||||
prev.node->next_sibling = other_first_head;
|
||||
loc.node->prev_sibling = other_last_head;
|
||||
other_first_head->prev_sibling = prev.node;
|
||||
other_last_head->next_sibling = loc.node;
|
||||
|
||||
// Adjust parent pointers.
|
||||
tree_node *walk=other_first_head;
|
||||
while(true) {
|
||||
walk->parent=loc.node->parent;
|
||||
if(walk==other_last_head)
|
||||
break;
|
||||
walk=walk->next_sibling;
|
||||
}
|
||||
|
||||
// Close other tree.
|
||||
other.head->next_sibling=other.feet;
|
||||
other.feet->prev_sibling=other.head;
|
||||
|
||||
return other_first_head;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
template<typename iter> iter tree<T, tree_node_allocator>::move_in_as_nth_child(iter loc, size_t n, tree& other)
|
||||
{
|
||||
if(other.head->next_sibling==other.feet) return loc; // other tree is empty
|
||||
|
||||
tree_node *other_first_head = other.head->next_sibling;
|
||||
tree_node *other_last_head = other.feet->prev_sibling;
|
||||
|
||||
if(n==0) {
|
||||
if(loc.node->first_child==0) {
|
||||
loc.node->first_child=other_first_head;
|
||||
loc.node->last_child=other_last_head;
|
||||
other_last_head->next_sibling=0;
|
||||
other_first_head->prev_sibling=0;
|
||||
}
|
||||
else {
|
||||
loc.node->first_child->prev_sibling=other_last_head;
|
||||
other_last_head->next_sibling=loc.node->first_child;
|
||||
loc.node->first_child=other_first_head;
|
||||
other_first_head->prev_sibling=0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
--n;
|
||||
tree_node *walk = loc.node->first_child;
|
||||
while(true) {
|
||||
if(walk==0)
|
||||
throw std::range_error("tree: move_in_as_nth_child position "
|
||||
+std::to_string(n+1)
|
||||
+" out of range; only "
|
||||
+std::to_string(number_of_children(loc))
|
||||
+" child nodes present");
|
||||
if(n==0)
|
||||
break;
|
||||
--n;
|
||||
walk = walk->next_sibling;
|
||||
}
|
||||
if(walk->next_sibling==0)
|
||||
loc.node->last_child=other_last_head;
|
||||
else
|
||||
walk->next_sibling->prev_sibling=other_last_head;
|
||||
other_last_head->next_sibling=walk->next_sibling;
|
||||
walk->next_sibling=other_first_head;
|
||||
other_first_head->prev_sibling=walk;
|
||||
}
|
||||
|
||||
// Adjust parent pointers.
|
||||
tree_node *walk=other_first_head;
|
||||
while(true) {
|
||||
walk->parent=loc.node;
|
||||
if(walk==other_last_head)
|
||||
break;
|
||||
walk=walk->next_sibling;
|
||||
}
|
||||
|
||||
// Close other tree.
|
||||
other.head->next_sibling=other.feet;
|
||||
other.feet->prev_sibling=other.head;
|
||||
|
||||
return other_first_head;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
void tree<T, tree_node_allocator>::merge(sibling_iterator to1, sibling_iterator to2,
|
||||
sibling_iterator from1, sibling_iterator from2,
|
||||
|
@ -1617,6 +1776,8 @@ bool tree<T, tree_node_allocator>::equal_subtree(const iter& one_, const iter& t
|
|||
template <class T, class tree_node_allocator>
|
||||
tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_iterator from, sibling_iterator to) const
|
||||
{
|
||||
assert(from!=to); // if from==to, the range is empty, hence no tree to return.
|
||||
|
||||
tree tmp;
|
||||
tmp.set_head(value_type());
|
||||
tmp.replace(tmp.begin(), tmp.end(), from, to);
|
||||
|
@ -1626,6 +1787,8 @@ tree<T, tree_node_allocator> tree<T, tree_node_allocator>::subtree(sibling_itera
|
|||
template <class T, class tree_node_allocator>
|
||||
void tree<T, tree_node_allocator>::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const
|
||||
{
|
||||
assert(from!=to); // if from==to, the range is empty, hence no tree to return.
|
||||
|
||||
tmp.set_head(value_type());
|
||||
tmp.replace(tmp.begin(), tmp.end(), from, to);
|
||||
}
|
||||
|
@ -2160,6 +2323,14 @@ typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allo
|
|||
return copy;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
typename tree<T, tree_node_allocator>::pre_order_iterator& tree<T, tree_node_allocator>::pre_order_iterator::next_skip_children()
|
||||
{
|
||||
(*this).skip_children();
|
||||
(*this)++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T, class tree_node_allocator>
|
||||
typename tree<T, tree_node_allocator>::pre_order_iterator tree<T, tree_node_allocator>::pre_order_iterator::operator--(int)
|
||||
{
|
1
lib/vectorwrapper
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 34e5775972cfe3ba66e5cdf75172bdeed4777d16
|
49
src/cloonelgraphics/CMakeLists.txt
Normal file
|
@ -0,0 +1,49 @@
|
|||
project(cloonelgraphics CXX)
|
||||
include(FindPkgConfig)
|
||||
|
||||
pkg_search_module(SDL2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
|
||||
add_library(${PROJECT_NAME}
|
||||
texture.cpp
|
||||
sdlerror.cpp
|
||||
sdlmain.cpp
|
||||
physicsfswrapper.cpp
|
||||
sizeratio.cpp
|
||||
sizenotifiable.cpp
|
||||
inputbag.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE PkgConfig::SDL2
|
||||
PRIVATE ${PHYSFS_LIBRARY}
|
||||
PRIVATE ${PNG_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${PNG_INCLUDE_DIRS}
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PRIVATE ${PHYSFS_INCLUDE_DIR}
|
||||
PUBLIC ../../lib/tree-3.1/src
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC VWR_STATIC_CAST_RESULTS
|
||||
PUBLIC VWR_SIZE_TYPE=uint32_t
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
configure_file(
|
||||
${CLOONEL_SRC_DIR}/cloonel_vectorwrapper/vectorwrapper.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/cloonel_vectorwrapper/vectorwrapper.hpp
|
||||
)
|
||||
configure_file(
|
||||
${CLOONEL_SRC_DIR}/cloonel_vectorwrapper/vector_cast.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/cloonel_vectorwrapper/vector_cast.hpp
|
||||
)
|
||||
configure_file(
|
||||
${CLOONEL_SRC_DIR}/cloonel_vectorwrapper/vectorops.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/cloonel_vectorwrapper/vectorops.hpp
|
||||
)
|
|
@ -140,8 +140,9 @@ namespace cloonel {
|
|||
template <typename T>
|
||||
void ObserversManager<T>::RemoveAll() noexcept {
|
||||
if (not m_tree.empty()) {
|
||||
for (typename TreeType::sibling_iterator it(m_tree.begin()), itEND(m_tree.end()); it != itEND; ++it) {
|
||||
for (typename TreeType::sibling_iterator it(m_tree.begin()), itEND(m_tree.end()); it != itEND;) {
|
||||
const TicketType ticket = it->ticket;
|
||||
++it;
|
||||
this->Remove(ticket);
|
||||
}
|
||||
assert(m_tree.empty());
|
|
@ -25,7 +25,19 @@
|
|||
#include <cassert>
|
||||
|
||||
namespace cloonel {
|
||||
uint32_t PhysicsFSWrapper::m_init_count = 0;
|
||||
|
||||
namespace {
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
std::string ver_to_string (const PHYSFS_Version& parVer) {
|
||||
std::ostringstream oss;
|
||||
oss << static_cast<int>(parVer.major) << '.'
|
||||
<< static_cast<int>(parVer.minor) << '.'
|
||||
<< static_cast<int>(parVer.patch);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
PHYSFS_File* OpenPhysFSFile (const char* parPath, PhysicsFSFile::OpenMode parMode) {
|
||||
|
@ -45,10 +57,18 @@ namespace cloonel {
|
|||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
PhysicsFSWrapper::PhysicsFSWrapper (const char* parBasePath) {
|
||||
if (not PHYSFS_init(parBasePath)) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error during PhysicsFS initialization: " << PHYSFS_getLastError();
|
||||
throw std::runtime_error(oss.str());
|
||||
if (IsInitialized()) {
|
||||
assert(m_init_count > 0);
|
||||
++m_init_count;
|
||||
}
|
||||
else {
|
||||
assert(0 == m_init_count);
|
||||
if (not PHYSFS_init(parBasePath)) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error during PhysicsFS initialization: " << PHYSFS_getLastError();
|
||||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
m_init_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,9 +77,17 @@ namespace cloonel {
|
|||
///are not checking in its return value as we can't throw anyways.
|
||||
///-------------------------------------------------------------------------
|
||||
PhysicsFSWrapper::~PhysicsFSWrapper() noexcept {
|
||||
const bool succeeded = static_cast<bool>(PHYSFS_deinit());
|
||||
(void)succeeded;
|
||||
assert(succeeded);
|
||||
assert(m_init_count > 0 and IsInitialized());
|
||||
if (m_init_count > 0) {
|
||||
--m_init_count;
|
||||
if (0 == m_init_count) {
|
||||
const bool succeeded = static_cast<bool>(PHYSFS_deinit());
|
||||
#if defined(NDEBUG)
|
||||
static_cast<void>(succeeded);
|
||||
#endif
|
||||
assert(succeeded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
|
@ -76,6 +104,34 @@ namespace cloonel {
|
|||
}
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
std::string PhysicsFSWrapper::LinkedVersion() {
|
||||
PHYSFS_Version ver;
|
||||
PHYSFS_getLinkedVersion(&ver);
|
||||
|
||||
return ver_to_string(ver);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
std::string PhysicsFSWrapper::CompiledVersion() {
|
||||
PHYSFS_Version ver;
|
||||
PHYSFS_VERSION(&ver);
|
||||
|
||||
return ver_to_string(ver);
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
bool PhysicsFSWrapper::IsInitialized() const noexcept {
|
||||
const bool initialized = static_cast<bool>(PHYSFS_isInit());
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
|
@ -84,7 +140,7 @@ namespace cloonel {
|
|||
{
|
||||
if (not m_handle) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error opening " << parDescCategory << " file: \"" <<
|
||||
oss << "Error opening " << parDescCategory << " file: \"";
|
||||
oss << parPath << "\": ";
|
||||
oss << PHYSFS_getLastError();
|
||||
throw std::runtime_error(oss.str());
|
|
@ -21,6 +21,7 @@
|
|||
#define idC54817CCCC0F454F931AE9082DFE9FDA
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#define DEF_PHYSICSFS_BUFFERED true
|
||||
|
||||
|
@ -31,6 +32,13 @@ namespace cloonel {
|
|||
~PhysicsFSWrapper ( void ) noexcept;
|
||||
|
||||
void Append ( const char* parRelativePath, const char* parMountPoint );
|
||||
bool IsInitialized ( void ) const noexcept;
|
||||
|
||||
static std::string LinkedVersion();
|
||||
static std::string CompiledVersion();
|
||||
|
||||
private:
|
||||
static uint32_t m_init_count;
|
||||
};
|
||||
|
||||
class PhysicsFSFile {
|
|
@ -89,7 +89,7 @@ namespace cloonel {
|
|||
m_gameName(parGameName),
|
||||
m_localData(new LocalData)
|
||||
{
|
||||
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
|
||||
m_localData->sizeratio.SetOriginal(vector_cast<float2>(parReferenceRes), vector_cast<float2>(parRes));
|
||||
m_localData->initialized = false;
|
||||
#if defined(RASPBERRY_PI)
|
||||
m_localData->bcmInitialized = false;
|
||||
|
@ -178,7 +178,7 @@ namespace cloonel {
|
|||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::SetResolution (ushort2 parRes) {
|
||||
m_localData->sizeratio.UpdateResolution(static_cast<float2>(parRes));
|
||||
m_localData->sizeratio.UpdateResolution(vector_cast<float2>(parRes));
|
||||
{
|
||||
SDL_Renderer* const renderer = GetRenderer();
|
||||
assert(renderer);
|
||||
|
@ -225,7 +225,7 @@ namespace cloonel {
|
|||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
ushort2 SDLMain::WidthHeight() const noexcept {
|
||||
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
|
||||
return vector_cast<ushort2>(m_localData->sizeratio.Resolution());
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef id8E7A054DAC9040B887F2620EFD229EE8
|
||||
#define id8E7A054DAC9040B887F2620EFD229EE8
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include "sizenotifiable.hpp"
|
||||
#include "sizeratio.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
#include <exception>
|
||||
|
||||
namespace cloonel {
|
||||
namespace implem {
|
||||
|
@ -55,5 +55,19 @@ namespace cloonel {
|
|||
///--------------------------------------------------------------------------
|
||||
void SizeNotifiableBase::NotifyResChanged (const SizeRatio& parSize) {
|
||||
m_scaleRatio = parSize.Ratio();
|
||||
this->OnResChanged(parSize);
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void SizeNotifiableBase::OnResChanged (const SizeRatio&) {
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
DeferredRegister::~DeferredRegister() {
|
||||
assert(m_call);
|
||||
if (m_call and not std::uncaught_exception())
|
||||
m_call();
|
||||
}
|
||||
} //namespace cloonel
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
Copyright 2014-2016 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
|
@ -20,9 +20,12 @@
|
|||
#ifndef id78906DE4FB0D43219CD3F0D9C620FC06
|
||||
#define id78906DE4FB0D43219CD3F0D9C620FC06
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
class SizeRatio;
|
||||
|
@ -68,6 +71,21 @@ namespace cloonel {
|
|||
};
|
||||
} //namespace regbehaviours
|
||||
|
||||
template <class RegisterBehaviour, bool=RegisterBehaviour::SDLMAIN_NEEDED>
|
||||
class SizeNotifiable;
|
||||
|
||||
class DeferredRegister {
|
||||
public:
|
||||
DeferredRegister ( void ) noexcept = default;
|
||||
~DeferredRegister ( void );
|
||||
|
||||
template <typename R>
|
||||
void SetThis ( SizeNotifiable<R>* parObject ) const noexcept;
|
||||
|
||||
private:
|
||||
mutable std::function<void()> m_call;
|
||||
};
|
||||
|
||||
class SizeNotifiableBase {
|
||||
protected:
|
||||
SizeNotifiableBase ( void ) = default;
|
||||
|
@ -76,19 +94,19 @@ namespace cloonel {
|
|||
SizeNotifiableBase& operator= ( const SizeNotifiableBase& ) = delete;
|
||||
|
||||
public:
|
||||
virtual void NotifyResChanged ( const SizeRatio& parSize );
|
||||
void NotifyResChanged ( const SizeRatio& parSize );
|
||||
const float2& Ratio ( void ) const noexcept { return m_scaleRatio; }
|
||||
|
||||
private:
|
||||
virtual void OnResChanged ( const SizeRatio& );
|
||||
|
||||
float2 m_scaleRatio;
|
||||
};
|
||||
|
||||
template <class RegisterBehaviour, bool=RegisterBehaviour::SDLMAIN_NEEDED>
|
||||
class SizeNotifiable;
|
||||
|
||||
template <class RegisterBehaviour>
|
||||
class SizeNotifiable<RegisterBehaviour, false> : private RegisterBehaviour, public SizeNotifiableBase {
|
||||
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == false, "SdlMainNeeded mismatches expected value");
|
||||
friend class DeferredRegister;
|
||||
public:
|
||||
SizeNotifiable ( const SizeNotifiable& ) = delete;
|
||||
SizeNotifiable ( SizeNotifiable&& parOther ) :
|
||||
|
@ -96,8 +114,8 @@ namespace cloonel {
|
|||
SizeNotifiableBase(parOther)
|
||||
{
|
||||
}
|
||||
SizeNotifiable ( void ) {
|
||||
this->Register(this);
|
||||
explicit SizeNotifiable ( const DeferredRegister& parRegisterFunctor ) {
|
||||
parRegisterFunctor.SetThis(this);
|
||||
}
|
||||
virtual ~SizeNotifiable ( void ) noexcept {
|
||||
this->Unregister();
|
||||
|
@ -107,6 +125,7 @@ namespace cloonel {
|
|||
template <class RegisterBehaviour>
|
||||
class SizeNotifiable<RegisterBehaviour, true> : private RegisterBehaviour, public SizeNotifiableBase {
|
||||
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == true, "SdlMainNeeded mismatches expected value");
|
||||
friend class DeferredRegister;
|
||||
public:
|
||||
SizeNotifiable ( const SizeNotifiable& ) = delete;
|
||||
SizeNotifiable ( SizeNotifiable&& parOther ) :
|
||||
|
@ -114,15 +133,22 @@ namespace cloonel {
|
|||
SizeNotifiableBase(parOther)
|
||||
{
|
||||
}
|
||||
explicit SizeNotifiable ( SDLMain* parSdlMain ) :
|
||||
SizeNotifiable ( SDLMain* parSdlMain, const DeferredRegister& parRegisterFunctor ) :
|
||||
RegisterBehaviour(parSdlMain)
|
||||
{
|
||||
this->Register(this);
|
||||
parRegisterFunctor.SetThis(this);
|
||||
}
|
||||
virtual ~SizeNotifiable ( void ) noexcept {
|
||||
this->Unregister();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
void DeferredRegister::SetThis (SizeNotifiable<R>* parObject) const noexcept {
|
||||
assert(not m_call);
|
||||
m_call = std::bind(&R::Register, static_cast<R*>(parObject), parObject);
|
||||
assert(m_call);
|
||||
}
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef id3098F08C14B84E3C8CE169CBA05C9C86
|
||||
#define id3098F08C14B84E3C8CE169CBA05C9C86
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
class SizeRatio {
|
|
@ -30,6 +30,9 @@
|
|||
#include <png.h>
|
||||
#include <endian.h>
|
||||
#include <vector>
|
||||
#if !defined(NDEBUG)
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
#define lengthof(a) (static_cast<int32_t>(sizeof(a) / sizeof(a[0])))
|
||||
|
||||
|
@ -246,10 +249,10 @@ namespace cloonel {
|
|||
break;
|
||||
|
||||
default:
|
||||
png_destroy_read_struct(&pngptr, &infoptr, nullptr);
|
||||
retSurf = nullptr;
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&pngptr, &infoptr, nullptr);
|
||||
return retSurf;
|
||||
}
|
||||
|
||||
|
@ -268,29 +271,33 @@ namespace cloonel {
|
|||
if (parDest.to <= parClip.from or parDest.from >= parClip.to)
|
||||
return false;
|
||||
|
||||
{
|
||||
const RectFloat clip(float2(0.0f), float2(1.0f));
|
||||
const float2 srcWidthHeight(parSrc.WidthHeight());
|
||||
const float2 scaledOffs((parDest.from - parClip.from) / parClip.WidthHeight());
|
||||
parSrc.from -= float2(std::min(0.0f, scaledOffs.x() * srcWidthHeight.x()), std::min(0.0f, scaledOffs.y() * srcWidthHeight.y()));
|
||||
const float2 scaledCrop((parClip.to - parDest.to) / parClip.WidthHeight());
|
||||
parSrc.to += float2(std::min(0.0f, scaledCrop.x() * srcWidthHeight.x()), std::min(0.0f, scaledCrop.y() * srcWidthHeight.y()));
|
||||
assert(parSrc.IsValid());
|
||||
}
|
||||
|
||||
RectFloat dst(parDest.from - parClip.from, parDest.to - parClip.from);
|
||||
dst.from.x() = std::max(dst.from.x(), parClip.from.x());
|
||||
dst.from.y() = std::max(dst.from.y(), parClip.from.y());
|
||||
dst.to.x() = std::min(dst.to.x(), parClip.to.x());
|
||||
dst.to.y() = std::min(dst.to.y(), parClip.to.y());
|
||||
RectFloat dst;
|
||||
dst.from.x() = std::max(parDest.from.x(), parClip.from.x());
|
||||
dst.from.y() = std::max(parDest.from.y(), parClip.from.y());
|
||||
dst.to.x() = std::min(parDest.to.x(), parClip.to.x());
|
||||
dst.to.y() = std::min(parDest.to.y(), parClip.to.y());
|
||||
|
||||
if (not dst.IsValid())
|
||||
return false;
|
||||
|
||||
parDest.from += parClip.from;
|
||||
parDest.to += parClip.from;
|
||||
assert(parDest.from <= dst.from);
|
||||
assert(parDest.to >= dst.to);
|
||||
|
||||
assert(parDest.IsValid());
|
||||
RectFloat src;
|
||||
{
|
||||
const float2 srcWidthHeight(parSrc.WidthHeight());
|
||||
const float2 scaledOffs((dst.from - parDest.from) / parDest.WidthHeight());
|
||||
src.from = parSrc.from + scaledOffs * srcWidthHeight;
|
||||
const float2 scaledCrop((parDest.to - dst.to) / parDest.WidthHeight());
|
||||
src.to = parSrc.to - scaledCrop * srcWidthHeight;
|
||||
assert(src.IsValid());
|
||||
|
||||
assert(dst.IsValid());
|
||||
assert(dst.from >= parClip.from);
|
||||
assert(dst.to <= parClip.to);
|
||||
}
|
||||
parDest = dst;
|
||||
parSrc = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -354,7 +361,7 @@ namespace cloonel {
|
|||
if (m_texture) {
|
||||
int2 wh;
|
||||
SDL_QueryTexture(m_texture, nullptr, nullptr, &wh.x(), &wh.y());
|
||||
m_size = static_cast<float2>(wh);
|
||||
m_size = vector_cast<float2>(wh);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,19 +376,20 @@ namespace cloonel {
|
|||
RectFloat src(float2(0.0f), m_size);
|
||||
|
||||
if (parClip) {
|
||||
const RectFloat clip(float2(0.0f), static_cast<float2>(m_sdlmain->WidthHeight()));
|
||||
const RectFloat clip(float2(0.0f), vector_cast<float2>(m_sdlmain->WidthHeight()));
|
||||
const bool visible = ClipRect(src, dest, clip);
|
||||
if (not visible)
|
||||
return;
|
||||
}
|
||||
#if !defined(NDEBUG)
|
||||
else {
|
||||
const RectFloat clip(float2(0.0f), static_cast<float2>(m_sdlmain->WidthHeight()));
|
||||
const RectFloat clip(float2(0.0f), vector_cast<float2>(m_sdlmain->WidthHeight()));
|
||||
assert(IsRectCompletelyInsideRect(dest, clip));
|
||||
}
|
||||
#endif
|
||||
|
||||
const SDL_Rect sdlsrc(src);
|
||||
SDL_Rect sdlsrc(src);
|
||||
sdlsrc.y = static_cast<decltype(sdlsrc.y)>(m_size.y()) - sdlsrc.y - sdlsrc.h;
|
||||
SDL_Rect sdldst(dest);
|
||||
sdldst.y = m_sdlmain->WidthHeight().y() - sdldst.y - sdldst.h;
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef id0F37904CB7274575B7E9419E615DA250
|
||||
#define id0F37904CB7274575B7E9419E615DA250
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include <string>
|
||||
|
||||
struct SDL_Texture;
|
98
src/cloonelgraphics/vectypes.hpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Copyright 2016 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 id7155F721B70C41B383896327C7D07E30
|
||||
#define id7155F721B70C41B383896327C7D07E30
|
||||
|
||||
#if defined(VWR_OUTER_NAMESPACE)
|
||||
# define CLOONEL_OUTER_NAMESPACE_WAS_DEFINED
|
||||
# pragma push_macro("VWR_OUTER_NAMESPACE")
|
||||
# undef VWR_OUTER_NAMESPACE
|
||||
#endif
|
||||
#define VWR_OUTER_NAMESPACE cloonel
|
||||
|
||||
#include "cloonel_vectorwrapper/vectorwrapper.hpp"
|
||||
#include "cloonel_vectorwrapper/vector_cast.hpp"
|
||||
#include "compatibility.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#if !defined(NDEBUG)
|
||||
# include <iostream>
|
||||
#endif
|
||||
#include <utility>
|
||||
|
||||
#define SPECIALIZE_ARRAY_VECTOR(TYPE, DIM) \
|
||||
template <> \
|
||||
struct VectorWrapperInfo<std::array<TYPE, DIM>> { \
|
||||
enum { dimensions = DIM }; \
|
||||
typedef TYPE scalar_type; \
|
||||
typedef std::array<scalar_type, dimensions> vector_type; \
|
||||
static scalar_type& get_at (uint32_t parIndex, vector_type& parVector) { \
|
||||
return parVector[parIndex]; \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace cloonel {
|
||||
namespace vwr {
|
||||
SPECIALIZE_ARRAY_VECTOR(float, 2);
|
||||
SPECIALIZE_ARRAY_VECTOR(uint16_t, 2);
|
||||
#if !defined(NDEBUG)
|
||||
SPECIALIZE_ARRAY_VECTOR(int16_t, 2);
|
||||
#endif
|
||||
SPECIALIZE_ARRAY_VECTOR(int32_t, 2);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
template <typename V>
|
||||
std::ostream& operator<< (std::ostream& parStream, const Vec<V>& parVec) {
|
||||
parStream << '<';
|
||||
for (uint32_t z = 0; z < Vec<V>::dimensions - 1; ++z) {
|
||||
std::cout << parVec[z] << ", ";
|
||||
}
|
||||
std::cout << parVec[Vec<V>::dimensions - 1] << '>';
|
||||
return parStream;
|
||||
}
|
||||
#endif
|
||||
} //namespace vwr
|
||||
} //namespace cloonel
|
||||
|
||||
//make stuff from CloonelJump compile happily
|
||||
namespace cloonel {
|
||||
template <typename T, uint32_t S>
|
||||
using Vector = vwr::Vec<std::array<T, std::size_t(S)>, S>;
|
||||
|
||||
using ushort2 = Vector<uint16_t, 2>;
|
||||
#if !defined(NDEBUG)
|
||||
using short2 = Vector<int16_t, 2>;
|
||||
#endif
|
||||
using float2 = Vector<float, 2>;
|
||||
using int2 = Vector<int32_t, 2>;
|
||||
|
||||
using vwr::vector_cast;
|
||||
} //namespace cloonel
|
||||
|
||||
#undef SPECIALIZE_ARRAY_VECTOR
|
||||
|
||||
#if defined(CLOONEL_OUTER_NAMESPACE_WAS_DEFINED)
|
||||
# undef CLOONEL_OUTER_NAMESPACE_WAS_DEFINED
|
||||
# pragma pop_macro("VWR_OUTER_NAMESPACE")
|
||||
#else
|
||||
# undef VWR_OUTER_NAMESPACE
|
||||
#endif
|
||||
|
||||
#endif
|
13
src/clooneljump/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
project(clooneljump CXX)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE jumping
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${CLOONEL_SRC_DIR}/src/jumping
|
||||
)
|
|
@ -17,11 +17,11 @@
|
|||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CloonelJumpConfig.h"
|
||||
#include "CloonelJumpProjectConfig.h"
|
||||
#include "sdlmain.hpp"
|
||||
#include "physicsfswrapper.hpp"
|
||||
#include "gameplaysceneclassic.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "casts.hpp"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
@ -50,7 +50,8 @@ int main (int, char* parArgv[]) {
|
|||
#else
|
||||
std::srand(static_cast<unsigned int>(DEF_RANDOM_SEED));
|
||||
#endif
|
||||
std::cout << GameName << " v" << GameVersionMajor << "." << GameVersionMinor << std::endl;
|
||||
std::cout << GameName << " v" << GameVersionMajor << "." << GameVersionMinor << '\n';
|
||||
std::cout << "Built with PhysicsFS v" << cloonel::PhysicsFSWrapper::CompiledVersion() << ", using v" << cloonel::PhysicsFSWrapper::LinkedVersion() << '\n';
|
||||
|
||||
int retVal = 0;
|
||||
cloonel::SDLMain sdlmain(GameName, cloonel::ushort2(DEF_WIN_WIDTH, DEF_WIN_HEIGHT), cloonel::ushort2(REFERENCE_WIDTH, REFERENCE_HEIGHT));
|
40
src/jumping/CMakeLists.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
project(jumping CXX)
|
||||
|
||||
add_library(${PROJECT_NAME}
|
||||
gamebase.cpp
|
||||
character.cpp
|
||||
placeable.cpp
|
||||
gameplayscene.cpp
|
||||
movers/mover.cpp
|
||||
movers/moveroneshot.cpp
|
||||
movers/moversine.cpp
|
||||
gameplaysceneclassic.cpp
|
||||
movers/moverrelative.cpp
|
||||
movers/moverleftright.cpp
|
||||
tiledwallpaper.cpp
|
||||
drawable.cpp
|
||||
horzcollisionbar.cpp
|
||||
platform.cpp
|
||||
vectormath.cpp
|
||||
platformspawner.cpp
|
||||
movers/moverworld.cpp
|
||||
line.cpp
|
||||
collider.cpp
|
||||
platformset.cpp
|
||||
drawableline.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC CloonelJumpProject
|
||||
PUBLIC cloonelgraphics
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE .
|
||||
PRIVATE movers
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
# INTERFACE WITH_VERBOSE_OBS_MANAGER
|
||||
INTERFACE WITH_VERBOSE_COLLIDER
|
||||
)
|
|
@ -33,18 +33,8 @@ namespace cloonel {
|
|||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
Character::Character (const std::string& parPath, SDLMain* parMain, float2 parSize) :
|
||||
Placeable(float2(0.0f)),
|
||||
Drawable(parSize),
|
||||
m_bottomBar(float2(0.0f), parSize.x()),
|
||||
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
|
||||
Character(std::string(parPath), parMain, parSize)
|
||||
{
|
||||
assert(parMain);
|
||||
m_bottomBar.SetCallback(std::bind(&Character::OnBounce, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
|
@ -53,11 +43,11 @@ namespace cloonel {
|
|||
Placeable(float2(0.0f)),
|
||||
Drawable(parSize),
|
||||
m_bottomBar(float2(0.0f), parSize.x()),
|
||||
m_screenRatio(parMain),
|
||||
m_screenRatio(parMain, DeferredRegister()),
|
||||
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()))
|
||||
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), vector_cast<short2>(m_bottomBar.From()), vector_cast<short2>(m_bottomBar.To()))
|
||||
#endif
|
||||
{
|
||||
assert(parMain);
|
||||
|
@ -66,8 +56,7 @@ namespace cloonel {
|
|||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
Character::~Character() noexcept {
|
||||
}
|
||||
Character::~Character() noexcept = default;
|
||||
|
||||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
|
@ -78,9 +67,6 @@ namespace cloonel {
|
|||
///-------------------------------------------------------------------------
|
||||
///-------------------------------------------------------------------------
|
||||
void Character::Prepare() {
|
||||
const SDLMain* const sdlmain = m_texture->SDLObject();
|
||||
const int2 screensize(sdlmain->WidthHeight());
|
||||
|
||||
m_texture->Reload();
|
||||
}
|
||||
|
||||
|
@ -95,7 +81,7 @@ 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());
|
||||
m_bottomBarDrawable.Render(m_bottomBar.From(), m_screenRatio.Ratio());
|
||||
#endif
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include "placeable.hpp"
|
||||
#include "drawable.hpp"
|
||||
#include "drawableset.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "sizenotifiable.hpp"
|
||||
#include "horzcollisionbar.hpp"
|
||||
#include "collidertypedef.hpp"
|
|
@ -20,8 +20,9 @@
|
|||
#include "collider.hpp"
|
||||
#include "horzcollisionbar.hpp"
|
||||
#include "line.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "collisionbarset.hpp"
|
||||
#include "cloonel_vectorwrapper/vectorops.hpp"
|
||||
#include "vectormath.hpp"
|
||||
#include <vector>
|
||||
#include <ciso646>
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef idC5A880D06A03407DB4E9FC21593A47FB
|
||||
#define idC5A880D06A03407DB4E9FC21593A47FB
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
|
||||
#if defined(WITH_DEBUG_VISUALS)
|
||||
namespace cloonel {
|
||||
|
@ -33,7 +34,7 @@ namespace cloonel {
|
|||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
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]));
|
||||
Line<float, 2> line(vector_cast<float2>(parLine[0]), vector_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);
|
||||
|
@ -80,8 +81,8 @@ namespace cloonel {
|
|||
}
|
||||
}
|
||||
|
||||
parLine[0] = static_cast<short2>(line[0]);
|
||||
parLine[1] = static_cast<short2>(line[1]);
|
||||
parLine[0] = short2(static_cast<int16_t>(boost::math::iround(line[0].x())), static_cast<int16_t>(boost::math::iround(line[0].y())));
|
||||
parLine[1] = short2(static_cast<int16_t>(boost::math::iround(line[1].x())), static_cast<int16_t>(boost::math::iround(line[1].y())));
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
|
@ -109,26 +110,32 @@ namespace cloonel {
|
|||
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 += vector_cast<short2>(parPos);
|
||||
scaledLine *= parScaling;
|
||||
const short2 wh(vector_cast<short2>(m_sdlmain->WidthHeight()));
|
||||
{
|
||||
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()
|
||||
);
|
||||
const bool isOnScreen = scaledLine[0] >= short2(0) and scaledLine[0] < wh and
|
||||
scaledLine[1] >= short2(0) and scaledLine[1] < wh;
|
||||
|
||||
if (isOnScreen) {
|
||||
const int16_t h = static_cast<int16_t>(m_sdlmain->WidthHeight().y());
|
||||
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
|
|
@ -37,15 +37,15 @@ namespace cloonel {
|
|||
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;
|
||||
DrawableLine ( const DrawableLine& ) = default;
|
||||
virtual ~DrawableLine ( void ) noexcept = default;
|
||||
|
||||
DrawableLine& operator= ( const DrawableLine& ) = delete;
|
||||
DrawableLine& operator= ( const DrawableLine& ) = default;
|
||||
|
||||
void Render ( const float2& parPos, const float2& parScaling ) const;
|
||||
|
||||
private:
|
||||
SDLMain* const m_sdlmain;
|
||||
SDLMain* m_sdlmain;
|
||||
Colour m_colour;
|
||||
};
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include "tiledwallpaper.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "platformspawner.hpp"
|
||||
#include "CloonelJumpConfig.h"
|
||||
#include "CloonelJumpProjectConfig.h"
|
||||
#include <algorithm>
|
||||
#include <SDL2/SDL_scancode.h>
|
||||
#include <ciso646>
|
||||
|
@ -128,12 +128,12 @@ namespace cloonel {
|
|||
GameplayScene::Destroy();
|
||||
|
||||
//Destroy in reverse creation order
|
||||
m_platforms = std::move(std::unique_ptr<PlatformSpawner>(nullptr));
|
||||
m_wallpaper = std::move(std::unique_ptr<TiledWallpaper>(nullptr));
|
||||
m_moverWorld = std::move(std::unique_ptr<MoverWorld>(nullptr));
|
||||
m_moverLeftRight = std::move(std::unique_ptr<MoverLeftRight>(nullptr));
|
||||
m_player = std::move(std::unique_ptr<Character>(nullptr));
|
||||
m_moverSine = std::move(std::unique_ptr<MoverSine>(nullptr));
|
||||
m_platforms = std::unique_ptr<PlatformSpawner>(nullptr);
|
||||
m_wallpaper = std::unique_ptr<TiledWallpaper>(nullptr);
|
||||
m_moverWorld = std::unique_ptr<MoverWorld>(nullptr);
|
||||
m_moverLeftRight = std::unique_ptr<MoverLeftRight>(nullptr);
|
||||
m_player = std::unique_ptr<Character>(nullptr);
|
||||
m_moverSine = std::unique_ptr<MoverSine>(nullptr);
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef id3E40B29606D048569E18083DB682280F
|
||||
#define id3E40B29606D048569E18083DB682280F
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "compatibility.h"
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
|
@ -17,7 +17,7 @@
|
|||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "line.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "compatibility.h"
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef id202E39A912AA43E5A224AC77D676F6CA
|
||||
#define id202E39A912AA43E5A224AC77D676F6CA
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "placeable.hpp"
|
||||
#include "line.hpp"
|
||||
#include "compatibility.h"
|
|
@ -21,11 +21,25 @@
|
|||
#define id56F112C6551D44039D0C0270F573B35B
|
||||
|
||||
#include "compatibility.h"
|
||||
#include "vector.hpp"
|
||||
#include "vectormath.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "cloonel_vectorwrapper/vectorops.hpp"
|
||||
#include <ciso646>
|
||||
#include <cstdint>
|
||||
|
||||
namespace cloonel {
|
||||
namespace vwr {
|
||||
template <typename T>
|
||||
struct VectorWrapperInfo<std::array<cloonel::Vector<T, 2>, 2>> {
|
||||
enum { dimensions = 2 };
|
||||
typedef cloonel::Vector<T, 2> scalar_type;
|
||||
typedef std::array<scalar_type, dimensions> vector_type;
|
||||
static scalar_type& get_at (uint32_t parIndex, vector_type& parVector) {
|
||||
return parVector[parIndex];
|
||||
}
|
||||
};
|
||||
} //namespace vwr
|
||||
} //namespace cloonel
|
||||
|
||||
namespace cloonel {
|
||||
template <typename T, uint32_t S>
|
||||
class Line {
|
|
@ -54,8 +54,11 @@ namespace cloonel {
|
|||
template <typename T, uint32_t S>
|
||||
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);
|
||||
typedef typename std::common_type<U, T>::type CommonType;
|
||||
typedef Vector<CommonType, S> CommVecType;
|
||||
|
||||
m_points.x() = vector_cast<Point>(vector_cast<CommVecType>(m_points.x()) * vector_cast<CommVecType>(parRhs));
|
||||
m_points.y() = vector_cast<Point>(vector_cast<CommVecType>(m_points.y()) * vector_cast<CommVecType>(parRhs));
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef idDF0B3D1FA4714EF3AB1241C3DA0D4E3D
|
||||
#define idDF0B3D1FA4714EF3AB1241C3DA0D4E3D
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "vectypes.hpp"
|
||||
#include "line.hpp"
|
||||
#include "compatibility.h"
|
||||
#include <cmath>
|