Compare commits

...

40 commits
master ... dev

Author SHA1 Message Date
a1b66e99f0 Search for SDL2 in cloonelgraphics. 2017-10-24 20:20:02 +01:00
cerkiewny
ba60426cc2 Merged in cerkiewny/clooneljump/dev (pull request #1)
fixing bug with build for release mode

Approved-by: Michele Santullo <dev00@gmx.it>
2017-03-18 15:29:20 +00:00
cerkiewny
b0f02fd8a8 fixing bug with build for release mode 2017-03-18 12:28:21 +01:00
8669e5e674 Fix wrong macro usage.
This should work with both modern GCC and clang.
2017-03-16 21:48:10 +00:00
c30b4e430e Make inclusions to vectorwrapper through generated headers.
This way cloonelgraphics includes headers using the absolute path
and should be usable from other projecs. Setting
CLOONEL_SRC_DIR to the path to cloonel's top-level cmake file is
now compulsory.
2017-03-16 21:32:35 +00:00
19db180460 Make a cloonel's specific symlink where compiler should look for vwr. 2017-03-16 21:01:15 +00:00
ceb3e180fe Revert "Add methods to create additional renderers."
This reverts commit 012daa47d7.
2017-03-11 11:56:02 +00:00
77e2bf539f Buildfix for external projects using cloonelgraphics directly. 2017-03-11 08:49:29 +00:00
6ce7b57882 Update vwr. 2017-03-04 01:21:29 +00:00
ad5b9d8fb8 Always use the local vwr 2017-03-04 01:07:49 +00:00
41585f1982 Update vwr and use the versioned include dir. 2017-03-04 01:05:19 +00:00
e53e59e4ff Impose cloonel as the outer namespace for vwr.
This is needed when cloonelgraphics is used outside of
clooneljump project.
2017-03-04 00:33:54 +00:00
65b6269cea Update vwr and use cloonel as the enclosing namespace for it. 2017-03-04 00:21:50 +00:00
012daa47d7 Add methods to create additional renderers. 2017-03-03 23:03:51 +00:00
c6e7f68a0f Fix build error when using bundled PhysFS 2016-11-25 20:54:07 +00:00
3ed0a214da Split files in jumping into two libraries.
Files in cloonelgraphics could be further split, but this should be enough for the
time being.
2016-11-25 21:14:49 +01:00
706f1aaa0a Fix drawing of vertically clipped surfaces.
Also fix bottom platforms disappearing and wrong coordinates being
sent to the function that draws debug lines. Obviously debug lines
drawing is still messed up... but at least you see the two lines!
2016-11-17 01:17:20 +01:00
10f830809b Add unit test for the deferred virtual call implementation in SizeNotifiable.
Fix the build as necessary.
Change DeferredRegister() to take no construction parameters.
2016-11-14 00:29:49 +01:00
0a3897f60a Refactor cmake file so the main part of the code is a lib. 2016-11-11 21:18:39 +01:00
7f49ef36d6 Import Catch and make a unit test program that uses it. 2016-11-11 20:37:35 +01:00
ce9eff82f1 Update PhysicsFSWrapper and print version on startup. 2016-11-11 02:36:10 +01:00
b5f7e30471 Update description for the bug fixed in the previous commit. 2016-11-10 23:26:41 +01:00
5e76b49cae Use the deferred virtual call mechanism to avoid the virtual
call bug in the constructor.

See docs/wrong_virtual_call.md for a description.
2016-11-10 23:19:55 +01:00
0b6cdeb5f5 Warning and assert fixes. 2016-11-09 23:35:41 +01:00
72bfb64795 NotifyResChanged() should not be virtual itself.
Make an OnResChanged() virtual method instead.
2016-11-09 23:35:19 +01:00
a87255ef66 Fix texture clipping 2016-11-09 22:25:57 +01:00
68d179975e Cast vectors explicitly using vector_cast. 2016-11-02 18:37:45 +01:00
650f8d6de1 Replace vector.hpp with vectorwrapper 2016-11-02 18:37:45 +01:00
e64b53f8d0 Warning fix on clang. 2016-11-02 02:53:29 +01:00
d12b7f777a Update gitignore with YouCompleteMe files 2016-10-31 21:07:24 +01:00
19dc6759df Don't use -std=c++11 explicitly and update cmake version requirement. 2016-10-31 20:47:47 +01:00
7985ba2bc4 Add old code that is presumably made to display debug collision lines. 2016-10-31 20:10:33 +01:00
a7bd060452 Fix memory leak when loading png files. 2016-10-31 20:09:44 +01:00
09299595fe Fix wrong increment of deleted iterator.
This fixes the invalid access spotted by valgrind.
2016-10-31 19:51:52 +01:00
09b41f6d0c Update tree to 3.1
see http://tree.phi-sci.com/download.html
2016-10-31 19:41:50 +01:00
8d2f7085c4 Ignore cscope's files. 2016-10-31 19:27:47 +01:00
1ef3dc86ac Remove unused inclusion. 2014-09-04 12:14:57 +02:00
c27055f8d0 Ignore offscreen segments. 2014-09-04 12:14:31 +02:00
efb0f93062 Draw collision lines for the platforms as well.
This highlits the issue with the broken collision and bouncing.
2014-08-25 19:28:10 +02:00
cc0f174be5 Round instead of truncating. 2014-08-25 18:06:55 +02:00
129 changed files with 1182 additions and 741 deletions

6
.gitignore vendored
View file

@ -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
View 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

View file

@ -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()

View file

@ -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")

View 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")

View 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")

View 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

View file

@ -1,2 +1,3 @@
a.out
*~
doxygen

View file

@ -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.

View file

@ -1,5 +1,5 @@
RELEASE=2.8
RELEASE=3.1
HTML=${HOME}/public_html/
.PHONY: doc tarball

View file

@ -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>

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 782 B

View file

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 881 B

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 888 KiB

After

Width:  |  Height:  |  Size: 888 KiB

View file

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View file

@ -1,3 +1,4 @@
*.o
*.res
test1
test2

View file

@ -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

View file

@ -1,3 +1,5 @@
#include <iostream>
#include "tree.hh"
#include "tree_util.hh"

111
lib/tree-3.1/src/test2.cc Normal file
View 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;
}
}

View file

@ -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();
}
}

View file

@ -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

View 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
)

View file

@ -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());

View file

@ -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());

View file

@ -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 {

View file

@ -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());
}
///------------------------------------------------------------------------

View file

@ -20,7 +20,7 @@
#ifndef id8E7A054DAC9040B887F2620EFD229EE8
#define id8E7A054DAC9040B887F2620EFD229EE8
#include "vector.hpp"
#include "vectypes.hpp"
#include <memory>
#include <string>

View file

@ -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

View file

@ -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

View file

@ -20,7 +20,7 @@
#ifndef id3098F08C14B84E3C8CE169CBA05C9C86
#define id3098F08C14B84E3C8CE169CBA05C9C86
#include "vector.hpp"
#include "vectypes.hpp"
namespace cloonel {
class SizeRatio {

View file

@ -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;

View file

@ -20,7 +20,7 @@
#ifndef id0F37904CB7274575B7E9419E615DA250
#define id0F37904CB7274575B7E9419E615DA250
#include "vector.hpp"
#include "vectypes.hpp"
#include <string>
struct SDL_Texture;

View 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

View 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
)

View file

@ -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));

View 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
)

View file

@ -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
}

View file

@ -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"

View file

@ -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>

View file

@ -20,7 +20,7 @@
#ifndef idC5A880D06A03407DB4E9FC21593A47FB
#define idC5A880D06A03407DB4E9FC21593A47FB
#include "vector.hpp"
#include "vectypes.hpp"
namespace cloonel {
class SDLMain;

View file

@ -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

View file

@ -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;
};

View file

@ -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);
}
///--------------------------------------------------------------------------

View file

@ -20,7 +20,7 @@
#ifndef id3E40B29606D048569E18083DB682280F
#define id3E40B29606D048569E18083DB682280F
#include "vector.hpp"
#include "vectypes.hpp"
#include "compatibility.h"
#include <ciso646>
#include <algorithm>

View file

@ -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"

View file

@ -20,7 +20,7 @@
#ifndef id202E39A912AA43E5A224AC77D676F6CA
#define id202E39A912AA43E5A224AC77D676F6CA
#include "vector.hpp"
#include "vectypes.hpp"
#include "placeable.hpp"
#include "line.hpp"
#include "compatibility.h"

View file

@ -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 {

View file

@ -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;
}

View file

@ -20,7 +20,7 @@
#ifndef idDF0B3D1FA4714EF3AB1241C3DA0D4E3D
#define idDF0B3D1FA4714EF3AB1241C3DA0D4E3D
#include "vector.hpp"
#include "vectypes.hpp"
#include "line.hpp"
#include "compatibility.h"
#include <cmath>

Some files were not shown because too many files have changed in this diff Show more