Compare commits
10 Commits
cf33d7c172
...
1401e51918
Author | SHA1 | Date |
---|---|---|
NaiJi ✨ | 1401e51918 | |
NaiJi ✨ | 5af1b94e22 | |
NaiJi ✨ | 3044b87dec | |
NaiJi ✨ | d6818bbd2f | |
NaiJi ✨ | ea71de96b5 | |
Jun | 9d9fa0e0b2 | |
NaiJi ✨ | 7923e894e2 | |
Jun | 47ac94bfbe | |
NaiJi ✨ | 5b22f627fa | |
NaiJi ✨ | 4b91146c33 |
|
@ -0,0 +1,18 @@
|
||||||
|
IndentWidth: 4
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: Right
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: true
|
|
@ -0,0 +1,32 @@
|
||||||
|
# project-kyoku
|
||||||
|
|
||||||
|
I am just trying to create a rhythm game inspired by project-diva
|
||||||
|
|
||||||
|
### Initial setup
|
||||||
|
|
||||||
|
- Make sure you have a compiler supporting c++17 and cmake
|
||||||
|
- Make sure you have [sfml](https://www.sfml-dev.org/) installed, either static or not, just make sure to edit impl/ CMake file, you'll see it.
|
||||||
|
- Now clone it
|
||||||
|
```
|
||||||
|
git clone https://dev.udongein.xyz/NaiJi/project-kyoku
|
||||||
|
```
|
||||||
|
|
||||||
|
- Go to the project folder
|
||||||
|
```
|
||||||
|
cd project-kyoku/
|
||||||
|
```
|
||||||
|
|
||||||
|
- Now build it!
|
||||||
|
```
|
||||||
|
cmake CMakeLists.txt -B ./build
|
||||||
|
cd ./build
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conventional commits
|
||||||
|
|
||||||
|
This project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
||||||
|
|
||||||
|
`<type>(optional scope): <description>`
|
||||||
|
|
||||||
|
Example: `feat(classic-mode): Implement something great`
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "flake-utils",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1663491030,
|
||||||
|
"narHash": "sha256-MVsfBhE9US5DvLtBAaTRjwYdv1tLO8xjahM8qLXTgTo=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "767542707d394ff15ac1981e903e005ba69528b5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
description = "Project Kyoku";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem
|
||||||
|
(system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShell = import ./shell.nix { inherit pkgs; };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -27,20 +27,22 @@ struct Area
|
||||||
|
|
||||||
inline kku::Point position() const noexcept
|
inline kku::Point position() const noexcept
|
||||||
{
|
{
|
||||||
return kku::Point{static_cast<float>(left),
|
return kku::Point{
|
||||||
static_cast<float>(top) };
|
static_cast<float>(left),
|
||||||
|
static_cast<float>(top),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void moveBy(const kku::Vector2<T>& vector)
|
inline void moveBy(const kku::Vector2<T> &vector)
|
||||||
{
|
{
|
||||||
top += vector.second;
|
top += vector.second;
|
||||||
left += vector.first;
|
left += vector.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool contains(const kku::Point& point) const
|
inline bool contains(const kku::Point &point) const
|
||||||
{
|
{
|
||||||
return point.x >= left ; // debug it when on computer
|
return point.x >= left; // debug it when on computer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -34,10 +34,10 @@ struct BPMSection
|
||||||
/// by timestamp of start
|
/// by timestamp of start
|
||||||
struct BPMSectionComparator
|
struct BPMSectionComparator
|
||||||
{
|
{
|
||||||
bool operator()(const BPMSection& lhs, const BPMSection& rhs) const noexcept
|
bool operator()(const BPMSection &lhs, const BPMSection &rhs) const noexcept
|
||||||
{
|
{
|
||||||
return lhs.offset_start < rhs.offset_start;
|
return lhs.offset_start < rhs.offset_start;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -14,4 +14,4 @@ struct Color
|
||||||
unsigned char alpha = 0;
|
unsigned char alpha = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "core/music.h"
|
|
||||||
#include "core/text.h"
|
|
||||||
#include "core/resourceholder.h"
|
|
||||||
#include "core/rectangle.h"
|
|
||||||
#include "core/vector.h"
|
|
||||||
#include "core/line.h"
|
#include "core/line.h"
|
||||||
|
#include "core/music.h"
|
||||||
|
#include "core/rectangle.h"
|
||||||
|
#include "core/resourceholder.h"
|
||||||
#include "core/sprite.h"
|
#include "core/sprite.h"
|
||||||
|
#include "core/text.h"
|
||||||
|
#include "core/vector.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
@ -19,14 +19,15 @@ namespace kku
|
||||||
/// multimedia elements and data
|
/// multimedia elements and data
|
||||||
class CoreFactory
|
class CoreFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~CoreFactory() = default;
|
virtual ~CoreFactory() = default;
|
||||||
virtual std::shared_ptr<kku::Music> getMusic() const = 0;
|
virtual std::shared_ptr<kku::Music> getMusic() const = 0;
|
||||||
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const = 0;
|
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const = 0;
|
||||||
virtual std::shared_ptr<kku::Rectangle> getRectangle() const = 0;
|
virtual std::shared_ptr<kku::Rectangle> getRectangle() const = 0;
|
||||||
virtual std::shared_ptr<kku::Line> getLine() const = 0;
|
virtual std::shared_ptr<kku::Line> getLine() const = 0;
|
||||||
virtual std::shared_ptr<kku::Sprite> getSprite(kku::GUISprite::Id id) const = 0;
|
virtual std::shared_ptr<kku::Sprite>
|
||||||
|
getSprite(kku::GUISprite::Id id) const = 0;
|
||||||
virtual kku::Vector2<std::size_t> getRenderSize() const = 0;
|
virtual kku::Vector2<std::size_t> getRenderSize() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "core/bpmsection.h"
|
||||||
#include "core/gameevent.h"
|
#include "core/gameevent.h"
|
||||||
#include "core/updatedata.h"
|
#include "core/updatedata.h"
|
||||||
#include "core/bpmsection.h"
|
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
@ -16,41 +16,42 @@ namespace kku
|
||||||
/// logic for Editor game mode
|
/// logic for Editor game mode
|
||||||
class Editor
|
class Editor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Editor() = default;
|
virtual ~Editor() = default;
|
||||||
|
|
||||||
virtual void input(GameEvent&& input) = 0;
|
virtual void input(GameEvent &&input) = 0;
|
||||||
virtual void update(UpdateData&& updatedata) = 0;
|
virtual void update(UpdateData &&updatedata) = 0;
|
||||||
virtual void display() const = 0;
|
virtual void display() const = 0;
|
||||||
virtual void recalculate(const microsec& timestamp) = 0;
|
virtual void recalculate(const microsec ×tamp) = 0;
|
||||||
|
|
||||||
void setBPMSections(const std::set<BPMSection, BPMSectionComparator>& sections) noexcept
|
void setBPMSections(
|
||||||
|
const std::set<BPMSection, BPMSectionComparator> §ions) noexcept
|
||||||
{
|
{
|
||||||
_bpm_sections = sections;
|
_bpm_sections = sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBPMSections(std::set<BPMSection, BPMSectionComparator>&& sections) noexcept
|
void setBPMSections(
|
||||||
|
std::set<BPMSection, BPMSectionComparator> &§ions) noexcept
|
||||||
{
|
{
|
||||||
_bpm_sections = std::move(sections);
|
_bpm_sections = std::move(sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insertBPMSection(const BPMSection& section)
|
bool insertBPMSection(const BPMSection §ion)
|
||||||
{
|
{
|
||||||
return _bpm_sections.insert(section).second;
|
return _bpm_sections.insert(section).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insertBPMSection(BPMSection&& section)
|
bool insertBPMSection(BPMSection &§ion)
|
||||||
{
|
{
|
||||||
return _bpm_sections.insert(section).second;
|
return _bpm_sections.insert(section).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removeBPMSectionAt(const microsec& offset)
|
bool removeBPMSectionAt(const microsec &offset)
|
||||||
{
|
{
|
||||||
auto section_it = std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
|
auto section_it =
|
||||||
[offset](const auto& section)
|
std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
|
||||||
{
|
[offset](const auto §ion)
|
||||||
return section.offset_start < offset;
|
{ return section.offset_start < offset; });
|
||||||
});
|
|
||||||
|
|
||||||
if (section_it != _bpm_sections.rend())
|
if (section_it != _bpm_sections.rend())
|
||||||
{
|
{
|
||||||
|
@ -63,13 +64,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BPMSection getBPMSectionAt(const microsec& offset) const
|
BPMSection getBPMSectionAt(const microsec &offset) const
|
||||||
{
|
{
|
||||||
auto section_it = std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
|
auto section_it =
|
||||||
[offset](const auto& section)
|
std::find_if(_bpm_sections.rbegin(), _bpm_sections.rend(),
|
||||||
{
|
[offset](const auto §ion)
|
||||||
return section.offset_start < offset;
|
{ return section.offset_start < offset; });
|
||||||
});
|
|
||||||
|
|
||||||
if (section_it != _bpm_sections.rend())
|
if (section_it != _bpm_sections.rend())
|
||||||
{
|
{
|
||||||
|
@ -80,13 +80,10 @@ public:
|
||||||
return BPMSection();
|
return BPMSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearBPMSections() noexcept
|
void clearBPMSections() noexcept { _bpm_sections.clear(); }
|
||||||
{
|
|
||||||
_bpm_sections.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::set<BPMSection, BPMSectionComparator> _bpm_sections;
|
std::set<BPMSection, BPMSectionComparator> _bpm_sections;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/systemevent.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
|
@ -8,7 +7,7 @@ namespace kku
|
||||||
|
|
||||||
class EditorCallback
|
class EditorCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~EditorCallback() = default;
|
virtual ~EditorCallback() = default;
|
||||||
|
|
||||||
struct Metadata
|
struct Metadata
|
||||||
|
@ -23,4 +22,4 @@ public:
|
||||||
virtual Metadata getMetadata() const = 0;
|
virtual Metadata getMetadata() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -8,4 +8,4 @@ namespace kku
|
||||||
using lambda = std::function<void(void)>;
|
using lambda = std::function<void(void)>;
|
||||||
using predicate = std::function<bool(void)>;
|
using predicate = std::function<bool(void)>;
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -12,13 +12,13 @@ namespace kku
|
||||||
/// logic for actual game mode
|
/// logic for actual game mode
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Game() = default;
|
virtual ~Game() = default;
|
||||||
|
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
virtual void input(GameEvent&& inputdata) = 0;
|
virtual void input(GameEvent &&inputdata) = 0;
|
||||||
virtual void update(UpdateData&& updatedata) = 0;
|
virtual void update(UpdateData &&updatedata) = 0;
|
||||||
virtual void display() const = 0;
|
virtual void display() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -12,4 +12,4 @@ struct GameEvent
|
||||||
const SystemEvent event;
|
const SystemEvent event;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/point.h"
|
|
||||||
#include "core/color.h"
|
#include "core/color.h"
|
||||||
|
#include "core/point.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
@ -11,11 +11,11 @@ namespace kku
|
||||||
/// Graphical 2D line
|
/// Graphical 2D line
|
||||||
class Line
|
class Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Line() = default;
|
virtual ~Line() = default;
|
||||||
virtual void setPosition(const kku::Point& p1, const kku::Point& p2) = 0;
|
virtual void setPosition(const kku::Point &p1, const kku::Point &p2) = 0;
|
||||||
virtual void setColor(const kku::Color& c1, const kku::Color& c2) = 0;
|
virtual void setColor(const kku::Color &c1, const kku::Color &c2) = 0;
|
||||||
virtual void display() = 0;
|
virtual void display() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -12,10 +12,10 @@ namespace kku
|
||||||
/// Object for streaming music file
|
/// Object for streaming music file
|
||||||
class Music
|
class Music
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Music() = default;
|
virtual ~Music() = default;
|
||||||
|
|
||||||
virtual bool open(const std::string& filepath) = 0;
|
virtual bool open(const std::string &filepath) = 0;
|
||||||
|
|
||||||
virtual void play() = 0;
|
virtual void play() = 0;
|
||||||
virtual void pause() = 0;
|
virtual void pause() = 0;
|
||||||
|
@ -25,11 +25,11 @@ public:
|
||||||
|
|
||||||
virtual void setVolume(float volume) = 0;
|
virtual void setVolume(float volume) = 0;
|
||||||
|
|
||||||
virtual void setOffset(const kku::microsec& offset) = 0;
|
virtual void setOffset(const kku::microsec &offset) = 0;
|
||||||
virtual void moveOffset(const kku::microsec& delta) = 0;
|
virtual void moveOffset(const kku::microsec &delta) = 0;
|
||||||
|
|
||||||
virtual kku::microsec fetchOffset() = 0;
|
virtual kku::microsec fetchOffset() = 0;
|
||||||
virtual kku::microsec getDuration() const = 0;
|
virtual kku::microsec getDuration() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,55 +1,52 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/time.h"
|
|
||||||
#include "core/gameevent.h"
|
#include "core/gameevent.h"
|
||||||
|
#include "core/time.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
class Note
|
class Note
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Note(microsec perfect_offset) :
|
explicit Note(microsec perfect_offset) : _perfect_offset(perfect_offset) {}
|
||||||
_perfect_offset(perfect_offset) {}
|
|
||||||
virtual ~Note() = default;
|
virtual ~Note() = default;
|
||||||
|
|
||||||
virtual bool isActive(const microsec& offset) const = 0;
|
virtual bool isActive(const microsec &offset) const = 0;
|
||||||
virtual void update(const microsec& music_offset) = 0;
|
virtual void update(const microsec &music_offset) = 0;
|
||||||
|
|
||||||
virtual void input(kku::GameEvent&& input) = 0;
|
virtual void input(kku::GameEvent &&input) = 0;
|
||||||
|
|
||||||
inline const microsec& getPerfectOffset() const noexcept
|
inline const microsec &getPerfectOffset() const noexcept
|
||||||
{
|
{
|
||||||
return _perfect_offset;
|
return _perfect_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Note& note) const
|
bool operator<(const Note ¬e) const
|
||||||
{
|
{
|
||||||
return _perfect_offset < note._perfect_offset;
|
return _perfect_offset < note._perfect_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Note& note) const
|
bool operator==(const Note ¬e) const
|
||||||
{
|
{
|
||||||
return _perfect_offset == note._perfect_offset;
|
return _perfect_offset == note._perfect_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const Note& note) const
|
bool operator>(const Note ¬e) const
|
||||||
{
|
{
|
||||||
return _perfect_offset > note._perfect_offset;
|
return _perfect_offset > note._perfect_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
microsec _perfect_offset;
|
microsec _perfect_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NotePtrComparator
|
struct NotePtrComparator
|
||||||
{
|
{
|
||||||
bool operator()(const Note* lhs, const Note* rhs) const noexcept
|
bool operator()(const Note *lhs, const Note *rhs) const noexcept
|
||||||
{
|
{
|
||||||
return lhs->getPerfectOffset() < rhs->getPerfectOffset();
|
return lhs->getPerfectOffset() < rhs->getPerfectOffset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,18 @@ struct Point
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
|
|
||||||
constexpr inline explicit Point() noexcept :
|
constexpr inline explicit Point() noexcept : x(0.), y(0.) {}
|
||||||
x(0.), y(0.)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr inline explicit Point(int x, int y) noexcept :
|
constexpr inline explicit Point(int x, int y) noexcept : x(x), y(y) {}
|
||||||
x(x), y(y)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr inline explicit Point(float x, float y) noexcept :
|
constexpr inline explicit Point(float x, float y) noexcept : x(x), y(y) {}
|
||||||
x(x), y(y)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr inline Point operator+(const Point& right) const noexcept
|
constexpr inline Point operator+(const Point &right) const noexcept
|
||||||
{
|
{
|
||||||
return Point{right.x + x, right.y + y};
|
return Point{right.x + x, right.y + y};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline Point operator-(const Point& right) const noexcept
|
constexpr inline Point operator-(const Point &right) const noexcept
|
||||||
{
|
{
|
||||||
return Point{right.x - x, right.y - y};
|
return Point{right.x - x, right.y - y};
|
||||||
}
|
}
|
||||||
|
@ -43,4 +37,4 @@ struct Point
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,37 +1,34 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "core/time.h"
|
#include "core/time.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename Grade, typename = std::enable_if_t<std::is_enum<Grade>::value>>
|
template <typename Grade,
|
||||||
|
typename = std::enable_if_t<std::is_enum<Grade>::value>>
|
||||||
class PrecisionEvaluator
|
class PrecisionEvaluator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrecisionEvaluator(const std::vector<microsec>& intervals, microsec offset) :
|
PrecisionEvaluator(const std::vector<microsec> &intervals, microsec offset)
|
||||||
_offset(offset),
|
: _offset(offset), _intervals(intervals)
|
||||||
_intervals(intervals)
|
|
||||||
{
|
{
|
||||||
_start_handling_offset = _offset - intervals.back();
|
_start_handling_offset = _offset - intervals.back();
|
||||||
_end_handling_offset = _offset + intervals.back();
|
_end_handling_offset = _offset + intervals.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline microsec offset() const noexcept
|
inline microsec offset() const noexcept { return _offset; }
|
||||||
{
|
|
||||||
return _offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isActive(microsec music_play_offset) const noexcept
|
inline bool isActive(microsec music_play_offset) const noexcept
|
||||||
{
|
{
|
||||||
return music_play_offset > _start_handling_offset
|
return music_play_offset > _start_handling_offset &&
|
||||||
&& music_play_offset < _end_handling_offset;
|
music_play_offset < _end_handling_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
Grade calculatePrecision(microsec odds) const
|
Grade calculatePrecision(microsec odds) const
|
||||||
|
@ -51,7 +48,7 @@ public:
|
||||||
return static_cast<Grade>(raw_grade);
|
return static_cast<Grade>(raw_grade);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
microsec _offset;
|
microsec _offset;
|
||||||
microsec _start_handling_offset;
|
microsec _start_handling_offset;
|
||||||
microsec _end_handling_offset;
|
microsec _end_handling_offset;
|
||||||
|
@ -66,4 +63,4 @@ private:
|
||||||
const std::vector<microsec> _intervals;
|
const std::vector<microsec> _intervals;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -8,20 +8,20 @@ namespace kku
|
||||||
|
|
||||||
class Rectangle
|
class Rectangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Rectangle() = default;
|
virtual ~Rectangle() = default;
|
||||||
virtual void setRect(const Area<float>& rect) = 0;
|
virtual void setRect(const Area<float> &rect) = 0;
|
||||||
virtual Area<float> getRect() const = 0;
|
virtual Area<float> getRect() const = 0;
|
||||||
|
|
||||||
virtual void setPosition(const Point& position) = 0;
|
virtual void setPosition(const Point &position) = 0;
|
||||||
virtual Point getPosition() const = 0;
|
virtual Point getPosition() const = 0;
|
||||||
virtual void move(const kku::Vector2<float>& delta) = 0;
|
virtual void move(const kku::Vector2<float> &delta) = 0;
|
||||||
|
|
||||||
virtual void setColor(const Color& color) = 0;
|
virtual void setColor(const Color &color) = 0;
|
||||||
virtual kku::Color getColor() const = 0;
|
virtual kku::Color getColor() const = 0;
|
||||||
virtual bool contains(const kku::Point& position) const = 0;
|
virtual bool contains(const kku::Point &position) const = 0;
|
||||||
|
|
||||||
virtual void display() = 0;
|
virtual void display() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename Resource, typename Id>
|
template <typename Resource, typename Id> class ResourceHolder
|
||||||
class ResourceHolder
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline void load(Id id, std::unique_ptr<Resource>&& resource) noexcept
|
inline void load(Id id, std::unique_ptr<Resource> &&resource) noexcept
|
||||||
{
|
{
|
||||||
_resources[id] = std::move(resource);
|
_resources[id] = std::move(resource);
|
||||||
}
|
}
|
||||||
|
@ -20,33 +19,33 @@ public:
|
||||||
return _resources.find(id)->second;
|
return _resources.find(id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<Id, std::shared_ptr<Resource>> _resources;
|
std::map<Id, std::shared_ptr<Resource>> _resources;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Font
|
namespace Font
|
||||||
{
|
{
|
||||||
enum class Id
|
enum class Id
|
||||||
{
|
{
|
||||||
GUI
|
GUI
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Texture
|
namespace Texture
|
||||||
{
|
{
|
||||||
enum class Id
|
enum class Id
|
||||||
{
|
{
|
||||||
GUI
|
GUI
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace GUISprite
|
namespace GUISprite
|
||||||
{
|
{
|
||||||
enum class Id
|
enum class Id
|
||||||
{
|
{
|
||||||
SFML_LOGO,
|
SFML_LOGO,
|
||||||
CRYPTOPP_LOGO
|
CRYPTOPP_LOGO
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/area.h"
|
#include "core/point.h"
|
||||||
|
#include "core/vector.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
class Sprite
|
class Sprite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Sprite() = default;
|
virtual ~Sprite() = default;
|
||||||
|
|
||||||
virtual void setPosition(const Point& position) = 0;
|
virtual void setPosition(const Point &position) = 0;
|
||||||
virtual Point getPosition() const = 0;
|
virtual Point getPosition() const = 0;
|
||||||
virtual void move(const kku::Vector2<float>& delta) = 0;
|
virtual void move(const kku::Vector2<float> &delta) = 0;
|
||||||
|
|
||||||
virtual void display() const = 0;
|
virtual void display() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <map>
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename Type, class SpriteFactory, class Sprite,
|
template <typename Type, class SpriteFactory, class Sprite,
|
||||||
typename = std::enable_if_t<std::is_enum<Type>::value>>
|
typename = std::enable_if_t<std::is_enum<Type>::value>>
|
||||||
class SpriteContainer
|
class SpriteContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SpriteContainer(std::initializer_list<Type>&& types,
|
explicit SpriteContainer(std::initializer_list<Type> &&types,
|
||||||
const std::shared_ptr<SpriteFactory>& factory,
|
const std::shared_ptr<SpriteFactory> &factory,
|
||||||
std::size_t reserve_size = 20) :
|
std::size_t reserve_size = 20)
|
||||||
_sprite_factory(factory),
|
: _sprite_factory(factory), _poll_reserve_size(reserve_size)
|
||||||
_poll_reserve_size(reserve_size)
|
|
||||||
{
|
{
|
||||||
for (const Type& type : types)
|
for (const Type &type : types)
|
||||||
reallocatePoll(type);
|
reallocatePoll(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Sprite> getSprite(Type type)
|
inline std::shared_ptr<Sprite> getSprite(Type type)
|
||||||
{
|
{
|
||||||
SpritePoll& poll = _sprite_dispatcher.at(type);
|
SpritePoll &poll = _sprite_dispatcher.at(type);
|
||||||
|
|
||||||
if (poll.empty())
|
if (poll.empty())
|
||||||
reallocatePoll(type);
|
reallocatePoll(type);
|
||||||
|
@ -33,7 +34,8 @@ public:
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void resetSprite(const std::shared_ptr<Sprite> &sprite, Type action) noexcept
|
inline void resetSprite(const std::shared_ptr<Sprite> &sprite,
|
||||||
|
Type action) noexcept
|
||||||
{
|
{
|
||||||
sprite->reset();
|
sprite->reset();
|
||||||
_sprite_dispatcher[action].push(sprite);
|
_sprite_dispatcher[action].push(sprite);
|
||||||
|
@ -41,7 +43,7 @@ public:
|
||||||
|
|
||||||
~SpriteContainer() = default;
|
~SpriteContainer() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void reallocatePoll(Type sprite_type)
|
inline void reallocatePoll(Type sprite_type)
|
||||||
{
|
{
|
||||||
SpritePoll &poll = _sprite_dispatcher[sprite_type];
|
SpritePoll &poll = _sprite_dispatcher[sprite_type];
|
||||||
|
@ -59,4 +61,4 @@ private:
|
||||||
std::size_t _poll_reserve_size;
|
std::size_t _poll_reserve_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -152,9 +152,9 @@ struct SystemEvent
|
||||||
|
|
||||||
enum class Button
|
enum class Button
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Wheel = 1,
|
Wheel = 1,
|
||||||
Left = 2,
|
Left = 2,
|
||||||
Right = 3
|
Right = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,10 +162,11 @@ struct SystemEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
struct None
|
struct None
|
||||||
{};
|
{
|
||||||
|
};
|
||||||
|
|
||||||
Type type = Type::None;
|
Type type = Type::None;
|
||||||
std::variant<Size, Key, Mouse, None> data;
|
std::variant<Size, Key, Mouse, None> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "core/color.h"
|
#include "core/color.h"
|
||||||
#include "core/point.h"
|
#include "core/point.h"
|
||||||
#include "core/vector.h"
|
#include "core/vector.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
class Text
|
class Text
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Text() = default;
|
virtual ~Text() = default;
|
||||||
virtual void setString(const std::string& string) = 0;
|
virtual void setString(const std::string &string) = 0;
|
||||||
virtual void setCharacterSize(std::size_t pixels) = 0;
|
virtual void setCharacterSize(std::size_t pixels) = 0;
|
||||||
virtual void setPosition(const Point& point) = 0;
|
virtual void setPosition(const Point &point) = 0;
|
||||||
virtual void move(const kku::Vector2<float>& delta) = 0;
|
virtual void move(const kku::Vector2<float> &delta) = 0;
|
||||||
virtual void setColor(const Color& color) = 0;
|
virtual void setColor(const Color &color) = 0;
|
||||||
|
|
||||||
virtual void display() = 0;
|
virtual void display() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -3,20 +3,41 @@
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// microsec
|
||||||
|
///
|
||||||
|
/// Primitive alias representing microseconds, which
|
||||||
|
/// is the main time measure in-game.
|
||||||
|
/// 1 second is 1000000 microseconds.
|
||||||
using microsec = long long;
|
using microsec = long long;
|
||||||
|
|
||||||
|
/// TimeRange
|
||||||
|
///
|
||||||
|
/// Object representing a section of time.
|
||||||
|
/// To ensure order safety use
|
||||||
|
/// static produceValidated function.
|
||||||
struct TimeRange
|
struct TimeRange
|
||||||
{
|
{
|
||||||
const microsec begin = 0;
|
const microsec begin = 0;
|
||||||
const microsec end = 0;
|
const microsec end = 0;
|
||||||
|
|
||||||
constexpr inline explicit TimeRange() noexcept :
|
constexpr inline explicit TimeRange() noexcept : begin(0), end(0)
|
||||||
begin(0), end(0)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
constexpr inline explicit TimeRange(microsec x, microsec y) noexcept :
|
constexpr inline explicit TimeRange(microsec x, microsec y) noexcept
|
||||||
begin(x), end(y)
|
: begin(x), end(y)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// produceValidated
|
||||||
|
///
|
||||||
|
/// Creates an object of TimeRange, but
|
||||||
|
/// also makes sure to place begin and end
|
||||||
|
/// in the right order to avoid confusion.
|
||||||
|
static inline TimeRange produceValidated(microsec x, microsec y) noexcept
|
||||||
|
{
|
||||||
|
return (x < y) ? TimeRange(x, y) : TimeRange(y, x);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,56 +1,58 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <memory>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "core/time.h"
|
|
||||||
#include "core/note.h"
|
#include "core/note.h"
|
||||||
|
#include "core/time.h"
|
||||||
|
|
||||||
namespace kku
|
namespace kku
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class TNote, class = std::enable_if_t<std::is_base_of<Note, TNote>::value>>
|
template <class TNote,
|
||||||
|
class = std::enable_if_t<std::is_base_of<Note, TNote>::value>>
|
||||||
class Timeline
|
class Timeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Timeline() :
|
explicit Timeline() : _current_offset(0)
|
||||||
_current_offset(0)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
typedef typename std::set<TNote*>::const_iterator Iterator;
|
typedef typename std::set<TNote *>::const_iterator Iterator;
|
||||||
|
|
||||||
void recalculate(const microsec& offset)
|
void recalculate(const microsec &offset)
|
||||||
{
|
{
|
||||||
_current_offset = offset;
|
_current_offset = offset;
|
||||||
expire(_top_note);
|
expire(_top_note);
|
||||||
|
|
||||||
if (!_timeline.empty())
|
if (_timeline.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Iterator head_iterator = _timeline.begin();
|
||||||
|
|
||||||
|
while (!isExpired(head_iterator))
|
||||||
{
|
{
|
||||||
Iterator head_iterator = _timeline.begin();
|
if ((*head_iterator)->getPerfectOffset() >= offset)
|
||||||
|
|
||||||
while (!isExpired(head_iterator))
|
|
||||||
{
|
{
|
||||||
if ((*head_iterator)->getPerfectOffset() >= offset)
|
Iterator pre_head = head_iterator;
|
||||||
{
|
--pre_head;
|
||||||
Iterator pre_head = head_iterator;
|
|
||||||
--pre_head;
|
|
||||||
|
|
||||||
_top_note = !isExpired(pre_head) && (*pre_head)->isActive(offset)
|
_top_note =
|
||||||
? pre_head
|
!isExpired(pre_head) && (*pre_head)->isActive(offset)
|
||||||
: head_iterator;
|
? pre_head
|
||||||
break;
|
: head_iterator;
|
||||||
}
|
break;
|
||||||
|
|
||||||
++head_iterator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isExpired(_top_note))
|
++head_iterator;
|
||||||
_top_note = _timeline.begin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isExpired(_top_note))
|
||||||
|
_top_note = _timeline.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNotes(const std::set<TNote*, NotePtrComparator>& notes)
|
void setNotes(const std::set<TNote *, NotePtrComparator> ¬es)
|
||||||
{
|
{
|
||||||
_timeline = std::move(notes);
|
_timeline = std::move(notes);
|
||||||
|
|
||||||
|
@ -60,43 +62,42 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertNote(TNote* note)
|
void insertNote(TNote *note)
|
||||||
{
|
{
|
||||||
_top_note = _timeline.insert(note).first;
|
_top_note = _timeline.insert(note).first;
|
||||||
recalculate(_current_offset);
|
recalculate(_current_offset);
|
||||||
update(_current_offset);
|
update(_current_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertNotes(const std::set<TNote*, NotePtrComparator>& notes)
|
void insertNotes(const std::set<TNote *, NotePtrComparator> ¬es)
|
||||||
{
|
{
|
||||||
_timeline.insert(notes.begin(), notes.end());
|
_timeline.insert(notes.begin(), notes.end());
|
||||||
recalculate(_current_offset);
|
recalculate(_current_offset);
|
||||||
update(_current_offset);
|
update(_current_offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear()
|
inline void clear()
|
||||||
{
|
{
|
||||||
for (auto& note : _timeline)
|
for (auto ¬e : _timeline)
|
||||||
delete note;
|
delete note;
|
||||||
|
|
||||||
_timeline.clear();
|
_timeline.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const microsec& offset)
|
void update(const microsec &offset)
|
||||||
{
|
{
|
||||||
_current_offset = offset;
|
_current_offset = offset;
|
||||||
updateTopNote(_current_offset);
|
updateTopNote(_current_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator getActiveNote(const microsec& music_offset) noexcept
|
Iterator getActiveNote(const microsec &music_offset) noexcept
|
||||||
{
|
{
|
||||||
Iterator return_note = _timeline.end();
|
Iterator return_note = _timeline.end();
|
||||||
|
|
||||||
auto note_iterator = _top_note;
|
auto note_iterator = _top_note;
|
||||||
while (!isExpired(note_iterator))
|
while (!isExpired(note_iterator))
|
||||||
{
|
{
|
||||||
const auto& note = *note_iterator;
|
const auto ¬e = *note_iterator;
|
||||||
if (note->isActive(music_offset))
|
if (note->isActive(music_offset))
|
||||||
{
|
{
|
||||||
return_note = note_iterator;
|
return_note = note_iterator;
|
||||||
|
@ -111,21 +112,20 @@ public:
|
||||||
return return_note;
|
return return_note;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Iterator getNoteBy(const microsec& music_offset) noexcept
|
inline Iterator getNoteBy(const microsec &music_offset) noexcept
|
||||||
{
|
{
|
||||||
return std::find_if(_timeline.begin(), _timeline.end(),
|
return std::find_if(_timeline.begin(), _timeline.end(),
|
||||||
[music_offset](const auto& note)
|
[music_offset](const auto ¬e) {
|
||||||
{
|
|
||||||
return note->getPerfectOffset() == music_offset;
|
return note->getPerfectOffset() == music_offset;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isExpired(const Iterator& iterator) const noexcept
|
inline bool isExpired(const Iterator &iterator) const noexcept
|
||||||
{
|
{
|
||||||
return iterator == _timeline.end();
|
return iterator == _timeline.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void expire(Iterator& iterator) noexcept
|
inline void expire(Iterator &iterator) noexcept
|
||||||
{
|
{
|
||||||
iterator = _timeline.end();
|
iterator = _timeline.end();
|
||||||
}
|
}
|
||||||
|
@ -145,19 +145,19 @@ public:
|
||||||
return _timeline.end();
|
return _timeline.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<TNote*, NotePtrComparator> _timeline;
|
std::set<TNote *, NotePtrComparator> _timeline;
|
||||||
microsec _current_offset;
|
microsec _current_offset;
|
||||||
|
|
||||||
inline void updateTopNote(const microsec& music_offset) noexcept
|
inline void updateTopNote(const microsec &music_offset) noexcept
|
||||||
{
|
{
|
||||||
if (isExpired(_top_note))
|
if (isExpired(_top_note))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& top_note = *_top_note;
|
const auto &top_note = *_top_note;
|
||||||
|
|
||||||
bool already_played = top_note->getPerfectOffset() < music_offset
|
bool already_played = top_note->getPerfectOffset() < music_offset &&
|
||||||
&& !top_note->isActive(music_offset);
|
!top_note->isActive(music_offset);
|
||||||
|
|
||||||
if (already_played)
|
if (already_played)
|
||||||
++_top_note;
|
++_top_note;
|
||||||
|
@ -166,6 +166,4 @@ private:
|
||||||
Iterator _top_note;
|
Iterator _top_note;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,4 @@ struct UpdateData
|
||||||
const microsec dt;
|
const microsec dt;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,12 @@ namespace kku
|
||||||
///
|
///
|
||||||
/// Meaning an element of a vector space in math.
|
/// Meaning an element of a vector space in math.
|
||||||
/// Don't mistake for std::vector<T>
|
/// Don't mistake for std::vector<T>
|
||||||
template <typename T>
|
template <typename T> using Vector2 = std::pair<T, T>;
|
||||||
using Vector2 = std::pair<T, T>;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr auto makeVector(T&& l, T&& r) -> Vector2<T>
|
inline constexpr auto makeVector(T &&l, T &&r) -> Vector2<T>
|
||||||
{
|
{
|
||||||
return std::make_pair(std::forward<T>(l), std::forward<T>(r));
|
return std::make_pair(std::forward<T>(l), std::forward<T>(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
pkgs ? import <nixpkgs> {},
|
||||||
|
unstable ? import <nixos-unstable> {},
|
||||||
|
}:
|
||||||
|
|
||||||
|
with pkgs;
|
||||||
|
mkShell {
|
||||||
|
buildInputs = [ sfml ];
|
||||||
|
nativeBuildInputs = [ ccls cmake ];
|
||||||
|
}
|
|
@ -7,26 +7,30 @@
|
||||||
class Group;
|
class Group;
|
||||||
class PushButton;
|
class PushButton;
|
||||||
|
|
||||||
namespace kku { class Sprite; class Text; }
|
namespace kku
|
||||||
|
{
|
||||||
|
class Sprite;
|
||||||
|
class Text;
|
||||||
|
} // namespace kku
|
||||||
|
|
||||||
class About : public GUIState
|
class About : public GUIState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
kku::lambda onLeaveAboutState;
|
kku::lambda onLeaveAboutState;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit About(const std::shared_ptr<kku::CoreFactory>& factory, Callbacks&& callbacks);
|
explicit About(const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
virtual void input(const kku::SystemEvent& event) override;
|
Callbacks &&callbacks);
|
||||||
virtual void update(const kku::microsec& dt) override;
|
virtual void input(const kku::SystemEvent &event) override;
|
||||||
|
virtual void update(const kku::microsec &dt) override;
|
||||||
virtual void display() const override;
|
virtual void display() const override;
|
||||||
|
|
||||||
virtual void enter() override;
|
virtual void enter() override;
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Callbacks _callbacks;
|
const Callbacks _callbacks;
|
||||||
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
||||||
const std::shared_ptr<kku::Sprite> _sfml_logo;
|
const std::shared_ptr<kku::Sprite> _sfml_logo;
|
||||||
|
@ -36,4 +40,3 @@ private:
|
||||||
std::shared_ptr<Group> _buttons;
|
std::shared_ptr<Group> _buttons;
|
||||||
std::shared_ptr<PushButton> _exit_button;
|
std::shared_ptr<PushButton> _exit_button;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,33 +2,37 @@
|
||||||
|
|
||||||
#include "application/state.h"
|
#include "application/state.h"
|
||||||
#include "core/corefactory.h"
|
#include "core/corefactory.h"
|
||||||
#include "core/music.h"
|
|
||||||
#include "core/functional.h"
|
#include "core/functional.h"
|
||||||
|
#include "core/music.h"
|
||||||
|
|
||||||
class BPMCalculator;
|
class BPMCalculator;
|
||||||
class Group;
|
class Group;
|
||||||
|
|
||||||
namespace kku { class Editor; }
|
namespace kku
|
||||||
|
{
|
||||||
|
class Editor;
|
||||||
|
}
|
||||||
|
|
||||||
class EditorState : public GUIState
|
class EditorState : public GUIState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
kku::lambda onLeaveEditorState;
|
kku::lambda onLeaveEditorState;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit EditorState(const std::shared_ptr<kku::CoreFactory>& core_factory, std::unique_ptr<kku::Editor>&& editor, Callbacks&& callbacks);
|
explicit EditorState(const std::shared_ptr<kku::CoreFactory> &core_factory,
|
||||||
|
std::unique_ptr<kku::Editor> &&editor,
|
||||||
|
Callbacks &&callbacks);
|
||||||
virtual ~EditorState() override;
|
virtual ~EditorState() override;
|
||||||
virtual void input(const kku::SystemEvent& event) override;
|
virtual void input(const kku::SystemEvent &event) override;
|
||||||
virtual void update(const kku::microsec& dt) override;
|
virtual void update(const kku::microsec &dt) override;
|
||||||
virtual void display() const override;
|
virtual void display() const override;
|
||||||
|
|
||||||
virtual void enter() override;
|
virtual void enter() override;
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Callbacks _callbacks;
|
const Callbacks _callbacks;
|
||||||
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
||||||
std::shared_ptr<kku::Music> _music;
|
std::shared_ptr<kku::Music> _music;
|
||||||
|
@ -38,4 +42,3 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<kku::Editor> _editor;
|
std::unique_ptr<kku::Editor> _editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "state.h"
|
|
||||||
#include "core/music.h"
|
|
||||||
#include "core/game.h"
|
|
||||||
#include "core/corefactory.h"
|
#include "core/corefactory.h"
|
||||||
#include "core/functional.h"
|
#include "core/functional.h"
|
||||||
|
#include "core/game.h"
|
||||||
|
#include "core/music.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
class Group;
|
class Group;
|
||||||
|
|
||||||
class GameState : public GUIState
|
class GameState : public GUIState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
kku::lambda onLeaveGame;
|
kku::lambda onLeaveGame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
explicit GameState(const std::shared_ptr<kku::CoreFactory> &core_factory,
|
||||||
|
const std::shared_ptr<kku::Game> &game,
|
||||||
|
Callbacks &&callbacks);
|
||||||
|
|
||||||
explicit GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks);
|
virtual void input(const kku::SystemEvent &event) override;
|
||||||
|
virtual void update(const kku::microsec &dt) override;
|
||||||
virtual void input(const kku::SystemEvent& event) override;
|
|
||||||
virtual void update(const kku::microsec& dt) override;
|
|
||||||
virtual void display() const override;
|
virtual void display() const override;
|
||||||
|
|
||||||
virtual void enter() override;
|
virtual void enter() override;
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
||||||
std::shared_ptr<kku::Music> _music;
|
std::shared_ptr<kku::Music> _music;
|
||||||
std::shared_ptr<kku::Game> _game;
|
std::shared_ptr<kku::Game> _game;
|
||||||
|
@ -35,4 +35,3 @@ private:
|
||||||
kku::lambda _onEnterGameCallback;
|
kku::lambda _onEnterGameCallback;
|
||||||
kku::lambda _onLeaveGameCallback;
|
kku::lambda _onLeaveGameCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ class Group;
|
||||||
|
|
||||||
class MainMenu : public GUIState
|
class MainMenu : public GUIState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
kku::lambda onAppendGameState;
|
kku::lambda onAppendGameState;
|
||||||
|
@ -17,18 +16,18 @@ public:
|
||||||
kku::lambda onAppendAboutState;
|
kku::lambda onAppendAboutState;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit MainMenu(const std::shared_ptr<kku::CoreFactory>& factory, Callbacks&& callbacks);
|
explicit MainMenu(const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
virtual void input(const kku::SystemEvent& event) override;
|
Callbacks &&callbacks);
|
||||||
virtual void update(const kku::microsec& dt) override;
|
virtual void input(const kku::SystemEvent &event) override;
|
||||||
|
virtual void update(const kku::microsec &dt) override;
|
||||||
virtual void display() const override;
|
virtual void display() const override;
|
||||||
|
|
||||||
virtual void enter() override;
|
virtual void enter() override;
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Callbacks _callbacks;
|
const Callbacks _callbacks;
|
||||||
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
const std::shared_ptr<kku::CoreFactory> _core_factory;
|
||||||
|
|
||||||
std::shared_ptr<Group> _buttons;
|
std::shared_ptr<Group> _buttons;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stack>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "core/systemevent.h"
|
#include "core/systemevent.h"
|
||||||
#include "core/vector.h"
|
|
||||||
#include "core/time.h"
|
#include "core/time.h"
|
||||||
|
#include "core/vector.h"
|
||||||
|
|
||||||
class GUIState
|
class GUIState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum Tag
|
||||||
enum Tag {
|
{
|
||||||
SPLASH_SCREEN,
|
SPLASH_SCREEN,
|
||||||
MAIN_MENU,
|
MAIN_MENU,
|
||||||
GAME_PICKER,
|
GAME_PICKER,
|
||||||
|
@ -26,8 +26,8 @@ public:
|
||||||
|
|
||||||
virtual ~GUIState() = default;
|
virtual ~GUIState() = default;
|
||||||
|
|
||||||
virtual void input(const kku::SystemEvent& event) = 0;
|
virtual void input(const kku::SystemEvent &event) = 0;
|
||||||
virtual void update(const kku::microsec& dt) = 0;
|
virtual void update(const kku::microsec &dt) = 0;
|
||||||
virtual void display() const = 0;
|
virtual void display() const = 0;
|
||||||
|
|
||||||
virtual void enter() = 0;
|
virtual void enter() = 0;
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../../include/application/state.h" // HOW? WHY DOESN'T "application/state.h" LINK ON BY ITSELF
|
#include "../../include/application/state.h" // HOW? WHY DOESN'T "application/state.h" LINK ON BY ITSELF
|
||||||
#include "core/corefactory.h"
|
#include "core/corefactory.h"
|
||||||
|
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Application() = default;
|
virtual ~Application() = default;
|
||||||
virtual bool init();
|
virtual bool init();
|
||||||
virtual void display() = 0;
|
virtual void display() = 0;
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
|
||||||
void input(const kku::SystemEvent& input);
|
void input(const kku::SystemEvent &input);
|
||||||
void update(const kku::microsec& dt);
|
void update(const kku::microsec &dt);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<kku::CoreFactory> _core_factory;
|
std::shared_ptr<kku::CoreFactory> _core_factory;
|
||||||
|
|
||||||
std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states;
|
std::array<std::shared_ptr<GUIState>, GUIState::Tag::AMOUNT> _states;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Basic logging class
|
||||||
|
*
|
||||||
|
* Defines helper functions for logging facility. Configured in
|
||||||
|
* Application::init()
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum LogLevel
|
||||||
|
{
|
||||||
|
FATAL,
|
||||||
|
ERROR,
|
||||||
|
WARN,
|
||||||
|
INFO,
|
||||||
|
DEBUG,
|
||||||
|
};
|
||||||
|
|
||||||
|
LogLevel level = WARN; ///< Default logging level
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prints message to stdout
|
||||||
|
*
|
||||||
|
* TODO: write to configurable stream, be it stdout, stderr or even a file
|
||||||
|
*
|
||||||
|
* @param level the message level
|
||||||
|
* @param fmt the message format
|
||||||
|
* @param ... variable parameters
|
||||||
|
*/
|
||||||
|
void log(LogLevel level, const std::string &fmt, ...);
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline std::string _getLabel(LogLevel level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case DEBUG:
|
||||||
|
return "DEBUG";
|
||||||
|
case INFO:
|
||||||
|
return "INFO ";
|
||||||
|
case WARN:
|
||||||
|
return "WARN ";
|
||||||
|
case ERROR:
|
||||||
|
return "ERROR";
|
||||||
|
case FATAL:
|
||||||
|
return "FATAL";
|
||||||
|
default:
|
||||||
|
return "UNK ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Log LOG; /// Global variable :(
|
||||||
|
|
||||||
|
#define INFO(fmt, ...) LOG.log(Log::INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#define WARN(fmt, ...) LOG.log(Log::WARN, fmt, ##__VA_ARGS__)
|
||||||
|
#define ERROR(fmt, ...) LOG.log(Log::ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#define FATAL(fmt, ...) LOG.log(Log::FATAL, fmt, ##__VA_ARGS__)
|
||||||
|
#define DEBUG(fmt, ...) LOG.log(Log::DEBUG, fmt, ##__VA_ARGS__)
|
|
@ -1,14 +1,14 @@
|
||||||
#include "application/about.h"
|
#include "application/about.h"
|
||||||
#include "widgets/pushbutton.h"
|
|
||||||
#include "widgets/group.h"
|
#include "widgets/group.h"
|
||||||
|
#include "widgets/pushbutton.h"
|
||||||
|
|
||||||
About::About(const std::shared_ptr<kku::CoreFactory>& factory, About::Callbacks&& callbacks) :
|
About::About(const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
_callbacks(std::move(callbacks)),
|
About::Callbacks &&callbacks)
|
||||||
_core_factory(factory),
|
: _callbacks(std::move(callbacks)), _core_factory(factory),
|
||||||
_sfml_logo(factory->getSprite(kku::GUISprite::Id::SFML_LOGO)),
|
_sfml_logo(factory->getSprite(kku::GUISprite::Id::SFML_LOGO)),
|
||||||
_cryptopp_logo(factory->getSprite(kku::GUISprite::Id::CRYPTOPP_LOGO)),
|
_cryptopp_logo(factory->getSprite(kku::GUISprite::Id::CRYPTOPP_LOGO)),
|
||||||
_powered_by_text(factory->getText(kku::Font::Id::GUI)),
|
_powered_by_text(factory->getText(kku::Font::Id::GUI)),
|
||||||
_buttons(std::make_shared<Group>())
|
_buttons(std::make_shared<Group>())
|
||||||
{
|
{
|
||||||
_powered_by_text->setString("Powered by: ");
|
_powered_by_text->setString("Powered by: ");
|
||||||
_powered_by_text->move(kku::Vector2<float>{0., 60});
|
_powered_by_text->move(kku::Vector2<float>{0., 60});
|
||||||
|
@ -16,12 +16,12 @@ About::About(const std::shared_ptr<kku::CoreFactory>& factory, About::Callbacks&
|
||||||
_cryptopp_logo->move(kku::Vector2<float>{250., 180});
|
_cryptopp_logo->move(kku::Vector2<float>{250., 180});
|
||||||
}
|
}
|
||||||
|
|
||||||
void About::input(const kku::SystemEvent& event)
|
void About::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
_buttons->input(event);
|
_buttons->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void About::update(const kku::microsec& dt)
|
void About::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_buttons->update(dt);
|
_buttons->update(dt);
|
||||||
}
|
}
|
||||||
|
@ -42,13 +42,15 @@ void About::enter()
|
||||||
|
|
||||||
if (!_exit_button)
|
if (!_exit_button)
|
||||||
{
|
{
|
||||||
_exit_button = std::make_shared<PushButton>("Return", _core_factory, 48);
|
_exit_button =
|
||||||
|
std::make_shared<PushButton>("Return", _core_factory, 48);
|
||||||
_exit_button->setCallback(_callbacks.onLeaveAboutState);
|
_exit_button->setCallback(_callbacks.onLeaveAboutState);
|
||||||
_buttons->addChild(_exit_button);
|
_buttons->addChild(_exit_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
_exit_button->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 4,
|
_exit_button->setRect(
|
||||||
window_width / 3.f, window_height / 7.f});
|
kku::Area<float>{window_width / 3.f, window_height / 7.f * 4,
|
||||||
|
window_width / 3.f, window_height / 7.f});
|
||||||
_buttons->setVisibility();
|
_buttons->setVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,4 +58,3 @@ void About::leave()
|
||||||
{
|
{
|
||||||
_buttons->setVisibility(false);
|
_buttons->setVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,41 @@
|
||||||
#include "application/application.h"
|
#include "application/application.h"
|
||||||
#include "core/gameevent.h"
|
#include "application/log.h"
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
|
#include "core/gameevent.h"
|
||||||
|
|
||||||
#include "application/mainmenu.h"
|
|
||||||
#include "application/gamestate.h"
|
|
||||||
#include "application/editorstate.h"
|
|
||||||
#include "application/about.h"
|
#include "application/about.h"
|
||||||
|
#include "application/editorstate.h"
|
||||||
|
#include "application/gamestate.h"
|
||||||
|
#include "application/mainmenu.h"
|
||||||
|
|
||||||
#include "classicmode/classicfactory.h"
|
#include "classicmode/classicfactory.h"
|
||||||
|
|
||||||
|
Log LOG;
|
||||||
|
|
||||||
bool Application::init()
|
bool Application::init()
|
||||||
{
|
{
|
||||||
|
LOG.level = Log::DEBUG;
|
||||||
|
DEBUG("Initializing Application");
|
||||||
|
|
||||||
if (!_core_factory)
|
if (!_core_factory)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MainMenu::Callbacks callbacks =
|
MainMenu::Callbacks callbacks = {
|
||||||
{
|
[&]() { pushState(GUIState::Tag::GAME); },
|
||||||
[&](){ pushState(GUIState::Tag::GAME); },
|
[&]() { pushState(GUIState::Tag::EDITOR); },
|
||||||
[&](){ pushState(GUIState::Tag::EDITOR); },
|
[&]() { pushState(GUIState::Tag::ABOUT); },
|
||||||
[&](){ pushState(GUIState::Tag::ABOUT); },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto main_menu = std::make_shared<MainMenu>(_core_factory, std::move(callbacks));
|
const auto main_menu =
|
||||||
const auto game_state = std::make_shared<GameState>(_core_factory, classic::getGame(_core_factory), GameState::Callbacks{[&](){ popState(); }});
|
std::make_shared<MainMenu>(_core_factory, std::move(callbacks));
|
||||||
const auto editor = std::make_shared<EditorState>(_core_factory, classic::getEditor(_core_factory), EditorState::Callbacks{[&](){ popState(); }});
|
const auto game_state = std::make_shared<GameState>(
|
||||||
const auto about = std::make_shared<About>(_core_factory, About::Callbacks{[&](){ popState(); }});
|
_core_factory, classic::getGame(_core_factory),
|
||||||
|
GameState::Callbacks{[&]() { popState(); }});
|
||||||
|
const auto editor = std::make_shared<EditorState>(
|
||||||
|
_core_factory, classic::getEditor(_core_factory),
|
||||||
|
EditorState::Callbacks{[&]() { popState(); }});
|
||||||
|
const auto about = std::make_shared<About>(
|
||||||
|
_core_factory, About::Callbacks{[&]() { popState(); }});
|
||||||
|
|
||||||
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
||||||
_states[GUIState::Tag::GAME] = game_state;
|
_states[GUIState::Tag::GAME] = game_state;
|
||||||
|
@ -36,18 +47,20 @@ bool Application::init()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::input(const kku::SystemEvent& event)
|
void Application::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
_state_stack.back()->input(event);
|
_state_stack.back()->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::update(const kku::microsec& dt)
|
void Application::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_state_stack.back()->update(dt);
|
_state_stack.back()->update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::pushState(GUIState::Tag new_state)
|
void Application::pushState(GUIState::Tag new_state)
|
||||||
{
|
{
|
||||||
|
DEBUG("Pushing state %d", new_state);
|
||||||
|
|
||||||
if (!_state_stack.empty())
|
if (!_state_stack.empty())
|
||||||
_state_stack.back()->leave();
|
_state_stack.back()->leave();
|
||||||
|
|
||||||
|
@ -57,6 +70,7 @@ void Application::pushState(GUIState::Tag new_state)
|
||||||
|
|
||||||
void Application::popState()
|
void Application::popState()
|
||||||
{
|
{
|
||||||
|
DEBUG("Popping state");
|
||||||
_state_stack.back()->leave();
|
_state_stack.back()->leave();
|
||||||
_state_stack.pop_back();
|
_state_stack.pop_back();
|
||||||
_state_stack.back()->enter();
|
_state_stack.back()->enter();
|
||||||
|
|
|
@ -1,31 +1,32 @@
|
||||||
#include "application/editorstate.h"
|
#include "application/editorstate.h"
|
||||||
|
#include "tools/bpmcalculator.h"
|
||||||
|
#include "widgets/bpmcalculatorwidget.h"
|
||||||
#include "widgets/button.h"
|
#include "widgets/button.h"
|
||||||
|
#include "widgets/editorwidget.h"
|
||||||
#include "widgets/group.h"
|
#include "widgets/group.h"
|
||||||
#include "widgets/menubar.h"
|
#include "widgets/menubar.h"
|
||||||
#include "widgets/window.h"
|
#include "widgets/window.h"
|
||||||
#include "widgets/editorwidget.h"
|
|
||||||
#include "widgets/bpmcalculatorwidget.h"
|
|
||||||
#include "tools/bpmcalculator.h"
|
|
||||||
|
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
|
|
||||||
EditorState::EditorState(const std::shared_ptr<kku::CoreFactory>& core_factory,
|
EditorState::EditorState(const std::shared_ptr<kku::CoreFactory> &core_factory,
|
||||||
std::unique_ptr<kku::Editor>&& editor,
|
std::unique_ptr<kku::Editor> &&editor,
|
||||||
Callbacks&& callbacks) :
|
Callbacks &&callbacks)
|
||||||
_callbacks(std::move(callbacks)),
|
: _callbacks(std::move(callbacks)), _core_factory(core_factory),
|
||||||
_core_factory(core_factory),
|
_editor(std::move(editor))
|
||||||
_editor(std::move(editor))
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
EditorState::~EditorState()
|
EditorState::~EditorState()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void EditorState::input(const kku::SystemEvent& event)
|
void EditorState::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
_group->input(event);
|
_group->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorState::update(const kku::microsec& dt)
|
void EditorState::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_group->update(dt);
|
_group->update(dt);
|
||||||
}
|
}
|
||||||
|
@ -41,54 +42,59 @@ void EditorState::enter()
|
||||||
_music->open("resources/METEOR.flac");
|
_music->open("resources/METEOR.flac");
|
||||||
_music->setVolume(5.f);
|
_music->setVolume(5.f);
|
||||||
|
|
||||||
auto& group = _group;
|
auto &group = _group;
|
||||||
auto& music = _music;
|
auto &music = _music;
|
||||||
auto& editor = _editor;
|
auto &editor = _editor;
|
||||||
|
|
||||||
_bpm_calculator = std::make_shared<BPMCalculator>();
|
_bpm_calculator = std::make_shared<BPMCalculator>();
|
||||||
auto& bpm_calculator = _bpm_calculator;
|
auto &bpm_calculator = _bpm_calculator;
|
||||||
std::shared_ptr<BPMCalculatorWidget> bpm_widget = std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _core_factory);
|
std::shared_ptr<BPMCalculatorWidget> bpm_widget =
|
||||||
|
std::make_shared<BPMCalculatorWidget>(_bpm_calculator, _core_factory);
|
||||||
|
|
||||||
auto button_start = std::make_shared<PushButton>("Start", _core_factory);
|
auto button_start = std::make_shared<PushButton>("Start", _core_factory);
|
||||||
auto button_stop = std::make_shared<PushButton>("Stop", _core_factory);
|
auto button_stop = std::make_shared<PushButton>("Stop", _core_factory);
|
||||||
auto button_apply = std::make_shared<PushButton>("Apply", _core_factory);
|
auto button_apply = std::make_shared<PushButton>("Apply", _core_factory);
|
||||||
|
|
||||||
button_start->setCallback([bpm_calculator, button_start, button_stop, &music]()
|
button_start->setCallback(
|
||||||
{
|
[bpm_calculator, button_start, button_stop, &music]()
|
||||||
music->play();
|
{
|
||||||
bpm_calculator->start();
|
music->play();
|
||||||
button_start->setVisibility(false);
|
bpm_calculator->start();
|
||||||
button_stop->setVisibility(true);
|
button_start->setVisibility(false);
|
||||||
});
|
button_stop->setVisibility(true);
|
||||||
|
});
|
||||||
|
|
||||||
button_stop->setCallback([bpm_calculator, button_start, button_stop, &music]()
|
button_stop->setCallback(
|
||||||
{
|
[bpm_calculator, button_start, button_stop, &music]()
|
||||||
music->stop();
|
{
|
||||||
bpm_calculator->stop();
|
music->stop();
|
||||||
button_start->setVisibility(true);
|
bpm_calculator->stop();
|
||||||
button_stop->setVisibility(false);
|
button_start->setVisibility(true);
|
||||||
});
|
button_stop->setVisibility(false);
|
||||||
|
});
|
||||||
|
|
||||||
button_apply->setCallback([&editor, bpm_calculator]()
|
button_apply->setCallback(
|
||||||
{
|
[&editor, bpm_calculator]()
|
||||||
kku::BPMSection section;
|
{
|
||||||
const auto& info = bpm_calculator->fetchApproximatedInfo();
|
kku::BPMSection section;
|
||||||
section.bpm = info.BPM;
|
const auto &info = bpm_calculator->fetchApproximatedInfo();
|
||||||
section.interval = info.interval;
|
section.bpm = info.BPM;
|
||||||
section.fraction = 2;
|
section.interval = info.interval;
|
||||||
section.offset_start = bpm_calculator->getStartingOffset();
|
section.fraction = 2;
|
||||||
|
section.offset_start = bpm_calculator->getStartingOffset();
|
||||||
|
|
||||||
editor->insertBPMSection(std::move(section));
|
editor->insertBPMSection(std::move(section));
|
||||||
});
|
});
|
||||||
|
|
||||||
BPMCalculatorWidget::Init bpm_widget_init;
|
BPMCalculatorWidget::Init bpm_widget_init;
|
||||||
bpm_widget_init.stop = button_stop;
|
bpm_widget_init.stop = button_stop;
|
||||||
bpm_widget_init.apply = button_apply;
|
bpm_widget_init.apply = button_apply;
|
||||||
bpm_widget_init.start = button_start;
|
bpm_widget_init.start = button_start;
|
||||||
bpm_widget_init.current_time = [&music]() -> kku::microsec { return music->fetchOffset(); };
|
bpm_widget_init.current_time = [&music]() -> kku::microsec
|
||||||
|
{ return music->fetchOffset(); };
|
||||||
|
|
||||||
bpm_widget->init(std::move(bpm_widget_init));
|
bpm_widget->init(std::move(bpm_widget_init));
|
||||||
const auto bpm_widget_callback = [&group, bpm_widget=bpm_widget, &music]()
|
const auto bpm_widget_callback = [&group, bpm_widget = bpm_widget, &music]()
|
||||||
{
|
{
|
||||||
music->stop();
|
music->stop();
|
||||||
bpm_widget->setVisibility(false);
|
bpm_widget->setVisibility(false);
|
||||||
|
@ -100,16 +106,19 @@ void EditorState::enter()
|
||||||
|
|
||||||
auto menu_bar = std::make_shared<MenuBar>(_core_factory);
|
auto menu_bar = std::make_shared<MenuBar>(_core_factory);
|
||||||
|
|
||||||
auto bpm_button = std::make_shared<PushButton>("Calculate BPM", _core_factory);
|
auto bpm_button =
|
||||||
|
std::make_shared<PushButton>("Calculate BPM", _core_factory);
|
||||||
|
|
||||||
bpm_button->setCallback([&group, bpm_widget=bpm_widget]()
|
bpm_button->setCallback(
|
||||||
{
|
[&group, bpm_widget = bpm_widget]()
|
||||||
group->blockBy(bpm_widget);
|
{
|
||||||
bpm_widget->setVisibility(true);
|
group->blockBy(bpm_widget);
|
||||||
});
|
bpm_widget->setVisibility(true);
|
||||||
|
});
|
||||||
|
|
||||||
bpm_widget->setRect(kku::Area<float>{render_size.first / 3.f, render_size.second / 3.f,
|
bpm_widget->setRect(
|
||||||
render_size.first / 3.f, render_size.second / 3.f});
|
kku::Area<float>{render_size.first / 3.f, render_size.second / 3.f,
|
||||||
|
render_size.first / 3.f, render_size.second / 3.f});
|
||||||
|
|
||||||
bpm_widget->addBarButton("X", bpm_widget_callback);
|
bpm_widget->addBarButton("X", bpm_widget_callback);
|
||||||
bpm_widget->setVisibility(false);
|
bpm_widget->setVisibility(false);
|
||||||
|
@ -120,9 +129,11 @@ void EditorState::enter()
|
||||||
auto test_menu_3 = std::make_shared<MenuDrop>(_core_factory);
|
auto test_menu_3 = std::make_shared<MenuDrop>(_core_factory);
|
||||||
test_menu_3->setRect(kku::Area<float>{0., 0., 200., 27. * 5.});
|
test_menu_3->setRect(kku::Area<float>{0., 0., 200., 27. * 5.});
|
||||||
|
|
||||||
auto test_cascade_button = std::make_shared<CascadeMenuButton>("Show submenu", _core_factory);
|
auto test_cascade_button =
|
||||||
|
std::make_shared<CascadeMenuButton>("Show submenu", _core_factory);
|
||||||
|
|
||||||
auto test_cascade_button_2 = std::make_shared<CascadeMenuButton>("Show submenu 2", _core_factory);
|
auto test_cascade_button_2 =
|
||||||
|
std::make_shared<CascadeMenuButton>("Show submenu 2", _core_factory);
|
||||||
|
|
||||||
auto quit_button = std::make_shared<PushButton>("Quit", _core_factory);
|
auto quit_button = std::make_shared<PushButton>("Quit", _core_factory);
|
||||||
quit_button->setCallback(_callbacks.onLeaveEditorState);
|
quit_button->setCallback(_callbacks.onLeaveEditorState);
|
||||||
|
@ -150,19 +161,18 @@ void EditorState::enter()
|
||||||
menu_bar->setVisibility(true);
|
menu_bar->setVisibility(true);
|
||||||
|
|
||||||
EditorWidget::Callbacks callbacks;
|
EditorWidget::Callbacks callbacks;
|
||||||
callbacks.onDisplay = [&editor]()
|
callbacks.onDisplay = [&editor]() { editor->display(); };
|
||||||
{
|
|
||||||
editor->display();
|
|
||||||
};
|
|
||||||
|
|
||||||
callbacks.onInput = [&editor, &music](const kku::SystemEvent& event)
|
callbacks.onInput = [&editor, &music](const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
if (event.type == kku::SystemEvent::Type::KeyRelease
|
if (event.type == kku::SystemEvent::Type::KeyRelease &&
|
||||||
&& std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
|
std::get<kku::SystemEvent::Key>(event.data).view ==
|
||||||
|
kku::SystemEvent::Key::Code::Space)
|
||||||
music->isPlaying() ? music->pause() : music->play();
|
music->isPlaying() ? music->pause() : music->play();
|
||||||
else if (event.type == kku::SystemEvent::Type::MouseWheelScroll)
|
else if (event.type == kku::SystemEvent::Type::MouseWheelScroll)
|
||||||
{
|
{
|
||||||
const auto& up = std::get<kku::SystemEvent::Mouse>(event.data).scrolled_up;
|
const auto &up =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).scrolled_up;
|
||||||
music->moveOffset(up ? 500000 : -500000);
|
music->moveOffset(up ? 500000 : -500000);
|
||||||
editor->recalculate(music->fetchOffset());
|
editor->recalculate(music->fetchOffset());
|
||||||
}
|
}
|
||||||
|
@ -170,8 +180,7 @@ void EditorState::enter()
|
||||||
editor->input(kku::GameEvent{music->fetchOffset(), event});
|
editor->input(kku::GameEvent{music->fetchOffset(), event});
|
||||||
};
|
};
|
||||||
|
|
||||||
callbacks.onUpdate = [&editor, &music](const kku::microsec& dt)
|
callbacks.onUpdate = [&editor, &music](const kku::microsec &dt) {
|
||||||
{
|
|
||||||
editor->update(kku::UpdateData{music->fetchOffset(), dt});
|
editor->update(kku::UpdateData{music->fetchOffset(), dt});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
|
|
||||||
#include "core/game.h"
|
#include "core/game.h"
|
||||||
|
|
||||||
GameState::GameState(const std::shared_ptr<kku::CoreFactory>& core_factory, const std::shared_ptr<kku::Game>& game, Callbacks&& callbacks) :
|
GameState::GameState(const std::shared_ptr<kku::CoreFactory> &core_factory,
|
||||||
_core_factory(core_factory),
|
const std::shared_ptr<kku::Game> &game,
|
||||||
_game(game),
|
Callbacks &&callbacks)
|
||||||
_onLeaveGameCallback(callbacks.onLeaveGame)
|
: _core_factory(core_factory), _game(game),
|
||||||
|
_onLeaveGameCallback(callbacks.onLeaveGame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::input(const kku::SystemEvent& event)
|
void GameState::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +34,7 @@ void GameState::input(const kku::SystemEvent& event)
|
||||||
_game->input(kku::GameEvent{_music->fetchOffset(), event});
|
_game->input(kku::GameEvent{_music->fetchOffset(), event});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::update(const kku::microsec& dt)
|
void GameState::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_game->update(kku::UpdateData{_music->fetchOffset(), dt});
|
_game->update(kku::UpdateData{_music->fetchOffset(), dt});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "application/log.h"
|
||||||
|
|
||||||
|
void Log::log(LogLevel level, const std::string &fmt, ...)
|
||||||
|
{
|
||||||
|
if (level > this->level)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
// First va_start: count how many characters are needed for formatting
|
||||||
|
va_start(args, fmt);
|
||||||
|
size_t len = std::vsnprintf(NULL, 0, fmt.c_str(), args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
std::vector<char> buf(len + 1);
|
||||||
|
|
||||||
|
// Second va_start: actually write formatted message to buffer
|
||||||
|
va_start(args, fmt);
|
||||||
|
std::vsnprintf(&buf[0], len + 1, fmt.c_str(), args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
std::cout << this->_getLabel(level) << " " << &buf[0] << std::endl;
|
||||||
|
}
|
|
@ -1,20 +1,20 @@
|
||||||
#include "application/mainmenu.h"
|
#include "application/mainmenu.h"
|
||||||
#include "widgets/pushbutton.h"
|
|
||||||
#include "widgets/group.h"
|
#include "widgets/group.h"
|
||||||
|
#include "widgets/pushbutton.h"
|
||||||
|
|
||||||
MainMenu::MainMenu(const std::shared_ptr<kku::CoreFactory>& factory, MainMenu::Callbacks&& callbacks) :
|
MainMenu::MainMenu(const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
_callbacks(std::move(callbacks)),
|
MainMenu::Callbacks &&callbacks)
|
||||||
_core_factory(factory),
|
: _callbacks(std::move(callbacks)), _core_factory(factory),
|
||||||
_buttons(std::make_shared<Group>())
|
_buttons(std::make_shared<Group>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainMenu::input(const kku::SystemEvent& event)
|
void MainMenu::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
_buttons->input(event);
|
_buttons->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainMenu::update(const kku::microsec& dt)
|
void MainMenu::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_buttons->update(dt);
|
_buttons->update(dt);
|
||||||
}
|
}
|
||||||
|
@ -30,19 +30,25 @@ void MainMenu::enter()
|
||||||
const float window_width = render_size.first;
|
const float window_width = render_size.first;
|
||||||
const float window_height = render_size.second;
|
const float window_height = render_size.second;
|
||||||
|
|
||||||
auto button_start = std::make_shared<PushButton>("Start", _core_factory, 48);
|
auto button_start =
|
||||||
button_start->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f,
|
std::make_shared<PushButton>("Start", _core_factory, 48);
|
||||||
window_width / 3.f, window_height / 7.f});
|
button_start->setRect(
|
||||||
|
kku::Area<float>{window_width / 3.f, window_height / 7.f,
|
||||||
|
window_width / 3.f, window_height / 7.f});
|
||||||
button_start->setCallback(_callbacks.onAppendGameState);
|
button_start->setCallback(_callbacks.onAppendGameState);
|
||||||
|
|
||||||
auto button_editor = std::make_shared<PushButton>("Editor", _core_factory, 48);
|
auto button_editor =
|
||||||
button_editor->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 3,
|
std::make_shared<PushButton>("Editor", _core_factory, 48);
|
||||||
window_width / 3.f, window_height / 7.f});
|
button_editor->setRect(
|
||||||
|
kku::Area<float>{window_width / 3.f, window_height / 7.f * 3,
|
||||||
|
window_width / 3.f, window_height / 7.f});
|
||||||
button_editor->setCallback(_callbacks.onAppendEditorState);
|
button_editor->setCallback(_callbacks.onAppendEditorState);
|
||||||
|
|
||||||
auto button_about = std::make_shared<PushButton>("About", _core_factory, 48);
|
auto button_about =
|
||||||
button_about->setRect(kku::Area<float>{window_width / 3.f, window_height / 7.f * 5,
|
std::make_shared<PushButton>("About", _core_factory, 48);
|
||||||
window_width / 3.f, window_height / 7.f});
|
button_about->setRect(
|
||||||
|
kku::Area<float>{window_width / 3.f, window_height / 7.f * 5,
|
||||||
|
window_width / 3.f, window_height / 7.f});
|
||||||
button_about->setCallback(_callbacks.onAppendAboutState);
|
button_about->setCallback(_callbacks.onAppendAboutState);
|
||||||
|
|
||||||
_buttons->addChild(button_start);
|
_buttons->addChild(button_start);
|
||||||
|
@ -56,4 +62,3 @@ void MainMenu::leave()
|
||||||
{
|
{
|
||||||
_buttons->setVisibility(false);
|
_buttons->setVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#include "bpmcalculatorwidget.h"
|
#include "bpmcalculatorwidget.h"
|
||||||
#include "tools/bpmcalculator.h"
|
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
|
#include "tools/bpmcalculator.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
BPMCalculatorWidget::BPMCalculatorWidget(const std::shared_ptr<BPMCalculator>& bpm_calculator, const std::shared_ptr<kku::CoreFactory>& factory) :
|
BPMCalculatorWidget::BPMCalculatorWidget(
|
||||||
Window(factory, "BPM Calculation"),
|
const std::shared_ptr<BPMCalculator> &bpm_calculator,
|
||||||
_bpm_calculator(bpm_calculator),
|
const std::shared_ptr<kku::CoreFactory> &factory)
|
||||||
_slider(std::make_shared<BPMSlider>(factory)),
|
: Window(factory, "BPM Calculation"), _bpm_calculator(bpm_calculator),
|
||||||
_core_factory(factory),
|
_slider(std::make_shared<BPMSlider>(factory)), _core_factory(factory),
|
||||||
_ticked(false)
|
_ticked(false)
|
||||||
{
|
{
|
||||||
_bpm_value = _core_factory->getText(kku::Font::Id::GUI);
|
_bpm_value = _core_factory->getText(kku::Font::Id::GUI);
|
||||||
_bpm_value->setCharacterSize(40);
|
_bpm_value->setCharacterSize(40);
|
||||||
|
@ -20,7 +20,7 @@ BPMCalculatorWidget::BPMCalculatorWidget(const std::shared_ptr<BPMCalculator>& b
|
||||||
_slap.setVolume(30.);*/
|
_slap.setVolume(30.);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::input(const kku::SystemEvent& event)
|
void BPMCalculatorWidget::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,8 @@ void BPMCalculatorWidget::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::KeyPress:
|
case kku::SystemEvent::Type::KeyPress:
|
||||||
{
|
{
|
||||||
if (std::get<kku::SystemEvent::Key>(event.data).view == kku::SystemEvent::Key::Code::Space)
|
if (std::get<kku::SystemEvent::Key>(event.data).view ==
|
||||||
|
kku::SystemEvent::Key::Code::Space)
|
||||||
{
|
{
|
||||||
_bpm_calculator->click(_current_time());
|
_bpm_calculator->click(_current_time());
|
||||||
}
|
}
|
||||||
|
@ -40,7 +41,7 @@ void BPMCalculatorWidget::input(const kku::SystemEvent& event)
|
||||||
Window::input(event);
|
Window::input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::update(const kku::microsec& dt)
|
void BPMCalculatorWidget::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Window::update(dt);
|
Window::update(dt);
|
||||||
|
|
||||||
|
@ -49,13 +50,16 @@ void BPMCalculatorWidget::update(const kku::microsec& dt)
|
||||||
{
|
{
|
||||||
_bpm_value->setString(std::to_string(static_cast<int>(beat_info.BPM)));
|
_bpm_value->setString(std::to_string(static_cast<int>(beat_info.BPM)));
|
||||||
|
|
||||||
const kku::microsec until_beat = _bpm_calculator->fetchTimeUntilNextBeat(_current_time());
|
const kku::microsec until_beat =
|
||||||
const auto time_relation = static_cast<long double>(beat_info.interval) / static_cast<long double>(until_beat);
|
_bpm_calculator->fetchTimeUntilNextBeat(_current_time());
|
||||||
|
const auto time_relation =
|
||||||
|
static_cast<long double>(beat_info.interval) /
|
||||||
|
static_cast<long double>(until_beat);
|
||||||
const auto slider_path_left = _slider->getRect().width / time_relation;
|
const auto slider_path_left = _slider->getRect().width / time_relation;
|
||||||
if (slider_path_left < 50)
|
if (slider_path_left < 50)
|
||||||
{
|
{
|
||||||
//if (!_ticked)
|
// if (!_ticked)
|
||||||
//_slap.play();
|
//_slap.play();
|
||||||
_ticked = true;
|
_ticked = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -79,30 +83,38 @@ void BPMCalculatorWidget::display() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::setRect(const kku::Area<float>& rect)
|
void BPMCalculatorWidget::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
Window::setRect(rect);
|
Window::setRect(rect);
|
||||||
_slider->setRect(kku::Area<float>{0, 0, rect.width / 8 * 6, 100});
|
_slider->setRect(kku::Area<float>{0, 0, rect.width / 8 * 6, 100});
|
||||||
_slider->setPosition(kku::Point{_window_content->getRect().left + rect.width / 8,
|
_slider->setPosition(
|
||||||
_window_content->getRect().top + rect.height / 8 * 3});
|
kku::Point{_window_content->getRect().left + rect.width / 8,
|
||||||
|
_window_content->getRect().top + rect.height / 8 * 3});
|
||||||
|
|
||||||
_button_start->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
_button_start->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
||||||
_button_start->setPosition(kku::Point{_window_content->getRect().left + rect.width / 7,
|
_button_start->setPosition(
|
||||||
_window_content->getRect().top + _window_content->getRect().height - 40});
|
kku::Point{_window_content->getRect().left + rect.width / 7,
|
||||||
|
_window_content->getRect().top +
|
||||||
|
_window_content->getRect().height - 40});
|
||||||
|
|
||||||
_button_stop->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
_button_stop->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
||||||
_button_stop->setPosition(kku::Point{_window_content->getRect().left + rect.width / 7,
|
_button_stop->setPosition(
|
||||||
_window_content->getRect().top + _window_content->getRect().height - 40});
|
kku::Point{_window_content->getRect().left + rect.width / 7,
|
||||||
|
_window_content->getRect().top +
|
||||||
|
_window_content->getRect().height - 40});
|
||||||
|
|
||||||
_button_apply->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
_button_apply->setRect(kku::Area<float>{0, 0, rect.width / 10 * 3, 30});
|
||||||
_button_apply->setPosition(kku::Point{_window_content->getRect().left + 50 + (2 * (rect.width / 7)),
|
_button_apply->setPosition(kku::Point{
|
||||||
_window_content->getRect().top + _window_content->getRect().height - 40});
|
_window_content->getRect().left + 50 + (2 * (rect.width / 7)),
|
||||||
|
_window_content->getRect().top + _window_content->getRect().height -
|
||||||
|
40});
|
||||||
|
|
||||||
_bpm_value->setPosition(kku::Point{_window_content->getRect().left + rect.width / 8,
|
_bpm_value->setPosition(
|
||||||
_window_content->getRect().top + rect.height / 8 });
|
kku::Point{_window_content->getRect().left + rect.width / 8,
|
||||||
|
_window_content->getRect().top + rect.height / 8});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::move(const kku::Vector2<float>& delta)
|
void BPMCalculatorWidget::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
Window::move(delta);
|
Window::move(delta);
|
||||||
|
|
||||||
|
@ -110,7 +122,7 @@ void BPMCalculatorWidget::move(const kku::Vector2<float>& delta)
|
||||||
_bpm_value->move(delta);
|
_bpm_value->move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMCalculatorWidget::setPosition(const kku::Point& position)
|
void BPMCalculatorWidget::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
Window::setPosition(position);
|
Window::setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@ BPMSlider::BPMSlider(const std::shared_ptr<kku::CoreFactory> &factory)
|
||||||
_slider_tick->setColor(kku::Color{255, 0, 0, 255});
|
_slider_tick->setColor(kku::Color{255, 0, 0, 255});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMSlider::input(const kku::SystemEvent& event)
|
void BPMSlider::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
Widget::input(event);
|
Widget::input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMSlider::update(const kku::microsec& dt)
|
void BPMSlider::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -26,28 +26,26 @@ void BPMSlider::display() const
|
||||||
Widget::display();
|
Widget::display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMSlider::setRect(const kku::Area<float>& rect)
|
void BPMSlider::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_slider_background->setRect(rect);
|
_slider_background->setRect(rect);
|
||||||
_slider_tick->setRect(kku::Area<float>{rect.left,
|
_slider_tick->setRect(
|
||||||
rect.top,
|
kku::Area<float>{rect.left, rect.top, rect.width / 30.f, rect.height});
|
||||||
rect.width / 30.f,
|
|
||||||
rect.height});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMSlider::setPosition(const kku::Point& position)
|
void BPMSlider::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_slider_background->setPosition(position);
|
_slider_background->setPosition(position);
|
||||||
_slider_tick->setPosition(position);
|
_slider_tick->setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BPMSlider::move(const kku::Vector2<float>& delta)
|
void BPMSlider::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_slider_background->move(delta);
|
_slider_background->move(delta);
|
||||||
_slider_tick->move(delta);
|
_slider_tick->move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BPMSlider::isUnderMouse(const kku::Point& position) const
|
bool BPMSlider::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _slider_background->contains(position);
|
return _slider_background->contains(position);
|
||||||
}
|
}
|
||||||
|
@ -64,6 +62,7 @@ kku::Point BPMSlider::getPosition() const
|
||||||
|
|
||||||
void BPMSlider::setTickPosition(float x_position)
|
void BPMSlider::setTickPosition(float x_position)
|
||||||
{
|
{
|
||||||
_slider_tick->setPosition(kku::Point{_slider_background->getPosition().x + x_position,
|
_slider_tick->setPosition(
|
||||||
_slider_tick->getPosition().y});
|
kku::Point{_slider_background->getPosition().x + x_position,
|
||||||
|
_slider_tick->getPosition().y});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
Button::Button(const std::string &text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
|
Button::Button(const std::string &text,
|
||||||
_core_factory(factory)
|
const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
|
unsigned int font_size)
|
||||||
|
: _core_factory(factory)
|
||||||
{
|
{
|
||||||
_button_text = _core_factory->getText(kku::Font::Id::GUI);
|
_button_text = _core_factory->getText(kku::Font::Id::GUI);
|
||||||
_button_text->setString(text);
|
_button_text->setString(text);
|
||||||
|
@ -10,7 +12,7 @@ Button::Button(const std::string &text, const std::shared_ptr<kku::CoreFactory>&
|
||||||
_button_text->setCharacterSize(font_size);
|
_button_text->setCharacterSize(font_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::update(const kku::microsec& dt)
|
void Button::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -26,14 +28,13 @@ void Button::display() const
|
||||||
Widget::display();
|
Widget::display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setRect(const kku::Area<float>& rect)
|
void Button::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_button_content->setRect(rect);
|
_button_content->setRect(rect);
|
||||||
_button_text->setPosition(kku::Point{rect.left + 5,
|
_button_text->setPosition(kku::Point{rect.left + 5, rect.top + 5});
|
||||||
rect.top + 5});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setPosition(const kku::Point& position)
|
void Button::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_button_content->setPosition(position);
|
_button_content->setPosition(position);
|
||||||
|
|
||||||
|
@ -42,19 +43,19 @@ void Button::setPosition(const kku::Point& position)
|
||||||
_button_text->setPosition(new_point);
|
_button_text->setPosition(new_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::move(const kku::Vector2<float>& delta)
|
void Button::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_button_content->move(delta);
|
_button_content->move(delta);
|
||||||
_button_text->move(delta);
|
_button_text->move(delta);
|
||||||
Widget::move(delta);
|
Widget::move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Button::isUnderMouse(const kku::Point& position) const
|
bool Button::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _is_visible && _button_content->contains(position);
|
return _is_visible && _button_content->contains(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setText(const std::string& text)
|
void Button::setText(const std::string &text)
|
||||||
{
|
{
|
||||||
_button_text->setString(text);
|
_button_text->setString(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include "cascademenubutton.h"
|
#include "cascademenubutton.h"
|
||||||
#include "menudrop.h"
|
#include "menudrop.h"
|
||||||
|
|
||||||
CascadeMenuButton::CascadeMenuButton(const std::string& text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
|
CascadeMenuButton::CascadeMenuButton(
|
||||||
Button(text, factory, font_size)
|
const std::string &text, const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
|
unsigned int font_size)
|
||||||
|
: Button(text, factory, font_size)
|
||||||
{
|
{
|
||||||
_color_idle = kku::Color{230, 230, 230, 255};
|
_color_idle = kku::Color{230, 230, 230, 255};
|
||||||
_color_hover = kku::Color{84, 158, 253, 255};
|
_color_hover = kku::Color{84, 158, 253, 255};
|
||||||
|
@ -11,7 +13,7 @@ CascadeMenuButton::CascadeMenuButton(const std::string& text, const std::shared_
|
||||||
_button_content->setColor(_color_idle);
|
_button_content->setColor(_color_idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CascadeMenuButton::input(const kku::SystemEvent& event)
|
void CascadeMenuButton::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
if (!_submenu)
|
if (!_submenu)
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +25,8 @@ void CascadeMenuButton::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MouseMove:
|
case kku::SystemEvent::Type::MouseMove:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (isUnderMouse(position))
|
if (isUnderMouse(position))
|
||||||
{
|
{
|
||||||
_button_content->setColor(_color_hover);
|
_button_content->setColor(_color_hover);
|
||||||
|
@ -40,17 +43,16 @@ void CascadeMenuButton::input(const kku::SystemEvent& event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CascadeMenuButton::setRect(const kku::Area<float>& rect)
|
void CascadeMenuButton::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
Button::setRect(rect);
|
Button::setRect(rect);
|
||||||
resetRect();
|
resetRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CascadeMenuButton::setSubmenu(const std::shared_ptr<MenuDrop>& submenu)
|
void CascadeMenuButton::setSubmenu(const std::shared_ptr<MenuDrop> &submenu)
|
||||||
{
|
{
|
||||||
_submenu = submenu;
|
_submenu = submenu;
|
||||||
resetRect();
|
resetRect();
|
||||||
|
@ -65,12 +67,14 @@ void CascadeMenuButton::resetRect()
|
||||||
{
|
{
|
||||||
if (_submenu)
|
if (_submenu)
|
||||||
{
|
{
|
||||||
_submenu->setPosition(kku::Point{_button_content->getPosition().x + _button_content->getRect().width,
|
_submenu->setPosition(kku::Point{_button_content->getPosition().x +
|
||||||
|
_button_content->getRect().width,
|
||||||
_button_content->getPosition().y});
|
_button_content->getPosition().y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CascadeMenuButton::setFillColors(kku::Color&& idle_color, kku::Color&& hover_color)
|
void CascadeMenuButton::setFillColors(kku::Color &&idle_color,
|
||||||
|
kku::Color &&hover_color)
|
||||||
{
|
{
|
||||||
_color_idle = idle_color;
|
_color_idle = idle_color;
|
||||||
_color_hover = hover_color;
|
_color_hover = hover_color;
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
#include "editorwidget.h"
|
#include "editorwidget.h"
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
|
|
||||||
EditorWidget::EditorWidget(Callbacks&& callbacks) :
|
EditorWidget::EditorWidget(Callbacks &&callbacks)
|
||||||
_input(std::move(callbacks.onInput)),
|
: _input(std::move(callbacks.onInput)),
|
||||||
_update(std::move(callbacks.onUpdate)),
|
_update(std::move(callbacks.onUpdate)),
|
||||||
_draw(std::move(callbacks.onDisplay))
|
_draw(std::move(callbacks.onDisplay))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void EditorWidget::input(const kku::SystemEvent& event)
|
void EditorWidget::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
_input(event);
|
_input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWidget::update(const kku::microsec& dt)
|
void EditorWidget::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
_update(dt);
|
_update(dt);
|
||||||
}
|
}
|
||||||
|
@ -22,18 +23,18 @@ void EditorWidget::display() const
|
||||||
_draw();
|
_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWidget::move(const kku::Vector2<float>& delta)
|
void EditorWidget::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
(void)delta;
|
(void)delta;
|
||||||
// delegate to children
|
// delegate to children
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditorWidget::isUnderMouse(const kku::Point& position) const
|
bool EditorWidget::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _parent->isUnderMouse(position);
|
return _parent->isUnderMouse(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWidget::setRect(const kku::Area<float>& rect)
|
void EditorWidget::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
(void)rect;
|
(void)rect;
|
||||||
// basically useless beacuse editor widget fills the entire screen
|
// basically useless beacuse editor widget fills the entire screen
|
||||||
|
@ -44,7 +45,7 @@ kku::Area<float> EditorWidget::getRect() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWidget::setPosition(const kku::Point& position)
|
void EditorWidget::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
(void)position;
|
(void)position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
|
|
||||||
void Group::input(const kku::SystemEvent& event)
|
void Group::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
Widget::input(event);
|
Widget::input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::update(const kku::microsec& dt)
|
void Group::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -15,18 +15,18 @@ void Group::display() const
|
||||||
Widget::display();
|
Widget::display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::setRect(const kku::Area<float>& rect)
|
void Group::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_rect = rect;
|
_rect = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::setPosition(const kku::Point& position)
|
void Group::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_rect.top = position.y;
|
_rect.top = position.y;
|
||||||
_rect.left = position.x;
|
_rect.left = position.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::move(const kku::Vector2<float>& delta)
|
void Group::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_rect.top += delta.first;
|
_rect.top += delta.first;
|
||||||
_rect.left += delta.second;
|
_rect.left += delta.second;
|
||||||
|
@ -34,9 +34,9 @@ void Group::move(const kku::Vector2<float>& delta)
|
||||||
Widget::move(delta);
|
Widget::move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Group::isUnderMouse(const kku::Point& position) const
|
bool Group::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _rect.contains(position);
|
return _rect.contains(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
kku::Area<float> Group::getRect() const
|
kku::Area<float> Group::getRect() const
|
||||||
|
@ -46,10 +46,5 @@ kku::Area<float> Group::getRect() const
|
||||||
|
|
||||||
kku::Point Group::getPosition() const
|
kku::Point Group::getPosition() const
|
||||||
{
|
{
|
||||||
return kku::Point
|
return kku::Point{_rect.top, _rect.left};
|
||||||
{
|
|
||||||
_rect.top,
|
|
||||||
_rect.left
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
#include "menubar.h"
|
#include "menubar.h"
|
||||||
|
|
||||||
MenuBar::MenuBar(const std::shared_ptr<kku::CoreFactory>& factory) :
|
MenuBar::MenuBar(const std::shared_ptr<kku::CoreFactory> &factory)
|
||||||
_core_factory(factory),
|
: _core_factory(factory), _bar_rect(factory->getRectangle()),
|
||||||
_bar_rect(factory->getRectangle()),
|
_amount_buttons(0), _button_width(170)
|
||||||
_amount_buttons(0),
|
|
||||||
_button_width(170)
|
|
||||||
{
|
{
|
||||||
_bar_rect->setColor(kku::Color{88, 57, 107, 255});
|
_bar_rect->setColor(kku::Color{88, 57, 107, 255});
|
||||||
}
|
}
|
||||||
|
@ -18,10 +16,11 @@ void MenuBar::input(const kku::SystemEvent &event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MouseRelease:
|
case kku::SystemEvent::Type::MouseRelease:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (!isUnderMouse(position))
|
if (!isUnderMouse(position))
|
||||||
{
|
{
|
||||||
for (auto& submenu : _submenus)
|
for (auto &submenu : _submenus)
|
||||||
submenu->unlock();
|
submenu->unlock();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -31,7 +30,7 @@ void MenuBar::input(const kku::SystemEvent &event)
|
||||||
Widget::input(event);
|
Widget::input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::update(const kku::microsec& dt)
|
void MenuBar::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -44,58 +43,58 @@ void MenuBar::display() const
|
||||||
Widget::display();
|
Widget::display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::setRect(const kku::Area<float>& rect)
|
void MenuBar::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_bar_rect->setRect(rect);
|
_bar_rect->setRect(rect);
|
||||||
|
|
||||||
// Buttons will not resize
|
// Buttons will not resize
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::setPosition(const kku::Point& position)
|
void MenuBar::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_bar_rect->setPosition(position);
|
_bar_rect->setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::move(const kku::Vector2<float>& delta)
|
void MenuBar::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_bar_rect->move(delta);
|
_bar_rect->move(delta);
|
||||||
|
|
||||||
Widget::move(delta);
|
Widget::move(delta);
|
||||||
|
|
||||||
for (auto& menu : _submenus)
|
for (auto &menu : _submenus)
|
||||||
menu->move(delta);
|
menu->move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuBar::isUnderMouse(const kku::Point& position) const
|
bool MenuBar::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
bool bar_under_mouse = _bar_rect->contains(position);
|
bool bar_under_mouse = _bar_rect->contains(position);
|
||||||
|
|
||||||
bool submenus_under_mouse = std::any_of(_children.begin(), _children.end(),
|
bool submenus_under_mouse = std::any_of(_children.begin(), _children.end(),
|
||||||
[p=position](const auto& child)
|
[p = position](const auto &child)
|
||||||
{
|
{ return child->isUnderMouse(p); });
|
||||||
return child->isUnderMouse(p);
|
|
||||||
});
|
|
||||||
|
|
||||||
return bar_under_mouse || submenus_under_mouse;
|
return bar_under_mouse || submenus_under_mouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::addRootSubMenu(std::string name, const std::shared_ptr<MenuDrop>& submenu)
|
void MenuBar::addRootSubMenu(std::string name,
|
||||||
|
const std::shared_ptr<MenuDrop> &submenu)
|
||||||
{
|
{
|
||||||
const auto new_button = std::make_shared<PushButton>(name, _core_factory);
|
const auto new_button = std::make_shared<PushButton>(name, _core_factory);
|
||||||
|
|
||||||
std::size_t current_index = _amount_buttons;
|
std::size_t current_index = _amount_buttons;
|
||||||
new_button->setRect(kku::Area<float>{static_cast<float>(current_index * _button_width),
|
new_button->setRect(kku::Area<float>{
|
||||||
0.f,
|
static_cast<float>(current_index * _button_width), 0.f,
|
||||||
static_cast<float>(_button_width),
|
static_cast<float>(_button_width), _bar_rect->getRect().height});
|
||||||
_bar_rect->getRect().height});
|
new_button->setCallback(
|
||||||
new_button->setCallback([submenu=submenu]()
|
[submenu = submenu]()
|
||||||
{
|
{
|
||||||
submenu->setVisibility(true);
|
submenu->setVisibility(true);
|
||||||
submenu->lock();
|
submenu->lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
submenu->setPosition(kku::Point{static_cast<float>(current_index * _button_width),
|
submenu->setPosition(
|
||||||
_bar_rect->getRect().height});
|
kku::Point{static_cast<float>(current_index * _button_width),
|
||||||
|
_bar_rect->getRect().height});
|
||||||
|
|
||||||
new_button->setColors(kku::Color{171, 141, 189, 255},
|
new_button->setColors(kku::Color{171, 141, 189, 255},
|
||||||
kku::Color{48, 27, 57, 255});
|
kku::Color{48, 27, 57, 255});
|
||||||
|
@ -116,7 +115,7 @@ void MenuBar::setVisibility(bool is_visible)
|
||||||
{
|
{
|
||||||
Widget::setVisibility(is_visible);
|
Widget::setVisibility(is_visible);
|
||||||
|
|
||||||
for (auto& submenu : _submenus)
|
for (auto &submenu : _submenus)
|
||||||
submenu->setVisibility(false);
|
submenu->setVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
#include "menudrop.h"
|
#include "menudrop.h"
|
||||||
#include "core/corefactory.h"
|
#include "core/corefactory.h"
|
||||||
|
|
||||||
MenuDrop::MenuDrop(const std::shared_ptr<kku::CoreFactory>& factory) :
|
MenuDrop::MenuDrop(const std::shared_ptr<kku::CoreFactory> &factory)
|
||||||
_is_locked(false),
|
: _is_locked(false), _button_height(27), _button_index(0)
|
||||||
_button_height(27),
|
|
||||||
_button_index(0)
|
|
||||||
{
|
{
|
||||||
_is_visible = false;
|
_is_visible = false;
|
||||||
_content_rect = factory->getRectangle();
|
_content_rect = factory->getRectangle();
|
||||||
_content_rect->setColor(kku::Color{200, 200, 200, 255});
|
_content_rect->setColor(kku::Color{200, 200, 200, 255});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::input(const kku::SystemEvent& event)
|
void MenuDrop::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
if (!_is_visible)
|
if (!_is_visible)
|
||||||
return;
|
return;
|
||||||
|
@ -25,11 +23,12 @@ void MenuDrop::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MouseRelease:
|
case kku::SystemEvent::Type::MouseRelease:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (isUnderMouse(position))
|
if (isUnderMouse(position))
|
||||||
{
|
{
|
||||||
setVisibility(false);
|
setVisibility(false);
|
||||||
for (auto& submenu : _submenus)
|
for (auto &submenu : _submenus)
|
||||||
{
|
{
|
||||||
submenu->unlock();
|
submenu->unlock();
|
||||||
submenu->setVisibility(false);
|
submenu->setVisibility(false);
|
||||||
|
@ -40,7 +39,8 @@ void MenuDrop::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MouseMove:
|
case kku::SystemEvent::Type::MouseMove:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (!isUnderMouse(position))
|
if (!isUnderMouse(position))
|
||||||
{
|
{
|
||||||
if (!isLocked() && !hasActiveSubmenus())
|
if (!isLocked() && !hasActiveSubmenus())
|
||||||
|
@ -54,13 +54,11 @@ void MenuDrop::input(const kku::SystemEvent& event)
|
||||||
bool MenuDrop::hasActiveSubmenus() const
|
bool MenuDrop::hasActiveSubmenus() const
|
||||||
{
|
{
|
||||||
return std::any_of(_submenus.begin(), _submenus.end(),
|
return std::any_of(_submenus.begin(), _submenus.end(),
|
||||||
[](const auto& submenu) -> bool
|
[](const auto &submenu) -> bool
|
||||||
{
|
{ return submenu->_is_visible; });
|
||||||
return submenu->_is_visible;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::update(const kku::microsec& dt)
|
void MenuDrop::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -73,27 +71,27 @@ void MenuDrop::display() const
|
||||||
Widget::display();
|
Widget::display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::setRect(const kku::Area<float>& rect)
|
void MenuDrop::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_content_rect->setRect(rect);
|
_content_rect->setRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::setPosition(const kku::Point& position)
|
void MenuDrop::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_content_rect->setPosition(position);
|
_content_rect->setPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::move(const kku::Vector2<float>& delta)
|
void MenuDrop::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_content_rect->move(delta);
|
_content_rect->move(delta);
|
||||||
|
|
||||||
Widget::move(delta);
|
Widget::move(delta);
|
||||||
|
|
||||||
for (auto& submenu : _submenus)
|
for (auto &submenu : _submenus)
|
||||||
submenu->move(delta);
|
submenu->move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuDrop::isUnderMouse(const kku::Point& position) const
|
bool MenuDrop::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _is_visible && _content_rect->contains(position);
|
return _is_visible && _content_rect->contains(position);
|
||||||
}
|
}
|
||||||
|
@ -106,33 +104,34 @@ void MenuDrop::setVisibility(bool is_visible)
|
||||||
_is_locked = false;
|
_is_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::addPushButton(const std::shared_ptr<PushButton>& button)
|
void MenuDrop::addPushButton(const std::shared_ptr<PushButton> &button)
|
||||||
{
|
{
|
||||||
add(button);
|
add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::addCascadeButton(const std::shared_ptr<CascadeMenuButton>& button)
|
void MenuDrop::addCascadeButton(
|
||||||
|
const std::shared_ptr<CascadeMenuButton> &button)
|
||||||
{
|
{
|
||||||
auto& submenu = button->submenu();
|
auto &submenu = button->submenu();
|
||||||
_submenus.emplace_back(submenu);
|
_submenus.emplace_back(submenu);
|
||||||
add(button);
|
add(button);
|
||||||
|
|
||||||
submenu->setParent(_parent);
|
submenu->setParent(_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::addSeparator(const std::shared_ptr<MenuSeparator>& separator)
|
void MenuDrop::addSeparator(const std::shared_ptr<MenuSeparator> &separator)
|
||||||
{
|
{
|
||||||
add(separator);
|
add(separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuDrop::add(const std::shared_ptr<Widget> &widget)
|
void MenuDrop::add(const std::shared_ptr<Widget> &widget)
|
||||||
{
|
{
|
||||||
const auto& parent_rect = _content_rect->getRect();
|
const auto &parent_rect = _content_rect->getRect();
|
||||||
|
|
||||||
widget->setRect(kku::Area<float>{parent_rect.left,
|
widget->setRect(kku::Area<float>{
|
||||||
parent_rect.top + (parent_rect.height * _button_index),
|
parent_rect.left,
|
||||||
parent_rect.width,
|
parent_rect.top + (parent_rect.height * _button_index),
|
||||||
static_cast<float>(_button_height)});
|
parent_rect.width, static_cast<float>(_button_height)});
|
||||||
|
|
||||||
addChild(widget);
|
addChild(widget);
|
||||||
++_button_index;
|
++_button_index;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "menuseparator.h"
|
#include "menuseparator.h"
|
||||||
|
|
||||||
void MenuSeparator::input(const kku::SystemEvent& event)
|
void MenuSeparator::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
Widget::input(event);
|
Widget::input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuSeparator::update(const kku::microsec& dt)
|
void MenuSeparator::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -15,24 +15,24 @@ void MenuSeparator::display() const
|
||||||
_line->display();
|
_line->display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuSeparator::setRect(const kku::Area<float>& rect)
|
void MenuSeparator::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_rect = rect;
|
_rect = rect;
|
||||||
|
|
||||||
//_line
|
//_line
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuSeparator::setPosition(const kku::Point& position)
|
void MenuSeparator::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
(void)position;
|
(void)position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuSeparator::move(const kku::Vector2<float>& delta)
|
void MenuSeparator::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
(void)delta;
|
(void)delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuSeparator::isUnderMouse(const kku::Point& position) const
|
bool MenuSeparator::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _is_visible && _rect.contains(position);
|
return _is_visible && _rect.contains(position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "pushbutton.h"
|
#include "pushbutton.h"
|
||||||
|
|
||||||
PushButton::PushButton(const std::string& text, const std::shared_ptr<kku::CoreFactory>& factory, unsigned int font_size) :
|
PushButton::PushButton(const std::string &text,
|
||||||
Button(text, factory, font_size),
|
const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
_pressed(false)
|
unsigned int font_size)
|
||||||
|
: Button(text, factory, font_size), _pressed(false)
|
||||||
{
|
{
|
||||||
_color_idle = kku::Color{230, 230, 230, 255};
|
_color_idle = kku::Color{230, 230, 230, 255};
|
||||||
_color_pressed = kku::Color{200, 200, 200, 255};
|
_color_pressed = kku::Color{200, 200, 200, 255};
|
||||||
|
@ -10,7 +11,7 @@ PushButton::PushButton(const std::string& text, const std::shared_ptr<kku::CoreF
|
||||||
_button_content->setColor(_color_idle);
|
_button_content->setColor(_color_idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushButton::input(const kku::SystemEvent& event)
|
void PushButton::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
|
@ -19,7 +20,8 @@ void PushButton::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MousePress:
|
case kku::SystemEvent::Type::MousePress:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (isUnderMouse(position))
|
if (isUnderMouse(position))
|
||||||
{
|
{
|
||||||
_pressed = true;
|
_pressed = true;
|
||||||
|
@ -32,7 +34,8 @@ void PushButton::input(const kku::SystemEvent& event)
|
||||||
{
|
{
|
||||||
if (_pressed)
|
if (_pressed)
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
_button_content->setColor(_color_idle);
|
_button_content->setColor(_color_idle);
|
||||||
_pressed = false;
|
_pressed = false;
|
||||||
if (isUnderMouse(position))
|
if (isUnderMouse(position))
|
||||||
|
@ -48,7 +51,7 @@ void PushButton::setCallback(kku::lambda callback)
|
||||||
_on_click_callback = callback;
|
_on_click_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushButton::setColors(kku::Color&& idle_color, kku::Color&& pressed_color)
|
void PushButton::setColors(kku::Color &&idle_color, kku::Color &&pressed_color)
|
||||||
{
|
{
|
||||||
_color_idle = idle_color;
|
_color_idle = idle_color;
|
||||||
_color_pressed = pressed_color;
|
_color_pressed = pressed_color;
|
||||||
|
|
|
@ -7,33 +7,33 @@ void Widget::input(const kku::SystemEvent &event)
|
||||||
_blocker->input(event);
|
_blocker->input(event);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto& child : _children)
|
for (auto &child : _children)
|
||||||
child->input(event);
|
child->input(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::update(const kku::microsec& dt)
|
void Widget::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
for (auto& child : _children)
|
for (auto &child : _children)
|
||||||
child->update(dt);
|
child->update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::display() const
|
void Widget::display() const
|
||||||
{
|
{
|
||||||
for (const auto& child : _children)
|
for (const auto &child : _children)
|
||||||
child->display();
|
child->display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::move(const kku::Vector2<float>& delta)
|
void Widget::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
for (auto& child : _children)
|
for (auto &child : _children)
|
||||||
child->move(delta);
|
child->move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setVisibility(bool is_visible)
|
void Widget::setVisibility(bool is_visible)
|
||||||
{
|
{
|
||||||
_is_visible = is_visible;
|
_is_visible = is_visible;
|
||||||
for (auto& child : _children)
|
for (auto &child : _children)
|
||||||
child->setVisibility(_is_visible);
|
child->setVisibility(_is_visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ bool Widget::isVisible() const
|
||||||
return _is_visible;
|
return _is_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::addChild(const std::shared_ptr<Widget>& child)
|
void Widget::addChild(const std::shared_ptr<Widget> &child)
|
||||||
{
|
{
|
||||||
child->setParent(shared_from_this());
|
child->setParent(shared_from_this());
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ void Widget::addChild(const std::shared_ptr<Widget>& child)
|
||||||
_children.emplace_back(child);
|
_children.emplace_back(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setParent(const std::shared_ptr<Widget>& parent)
|
void Widget::setParent(const std::shared_ptr<Widget> &parent)
|
||||||
{
|
{
|
||||||
if (_parent != parent)
|
if (_parent != parent)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ void Widget::setParent(const std::shared_ptr<Widget>& parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::blockBy(const std::shared_ptr<Widget>& blocker)
|
void Widget::blockBy(const std::shared_ptr<Widget> &blocker)
|
||||||
{
|
{
|
||||||
_blocker = blocker;
|
_blocker = blocker;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
Window::Window(const std::shared_ptr<kku::CoreFactory>& factory, const std::string& title) :
|
Window::Window(const std::shared_ptr<kku::CoreFactory> &factory,
|
||||||
_core_factory(factory),
|
const std::string &title)
|
||||||
_is_dragging(false)
|
: _core_factory(factory), _is_dragging(false)
|
||||||
{
|
{
|
||||||
_bar_title = _core_factory->getText(kku::Font::Id::GUI);
|
_bar_title = _core_factory->getText(kku::Font::Id::GUI);
|
||||||
_bar_title->setString(title);
|
_bar_title->setString(title);
|
||||||
|
@ -16,7 +16,7 @@ Window::Window(const std::shared_ptr<kku::CoreFactory>& factory, const std::stri
|
||||||
_window_content->setColor(kku::Color{188, 157, 207, 255});
|
_window_content->setColor(kku::Color{188, 157, 207, 255});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::input(const kku::SystemEvent& event)
|
void Window::input(const kku::SystemEvent &event)
|
||||||
{
|
{
|
||||||
Widget::input(event);
|
Widget::input(event);
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ void Window::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MousePress:
|
case kku::SystemEvent::Type::MousePress:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (_bar->contains(position))
|
if (_bar->contains(position))
|
||||||
{
|
{
|
||||||
_is_dragging = true;
|
_is_dragging = true;
|
||||||
|
@ -42,7 +43,8 @@ void Window::input(const kku::SystemEvent& event)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MouseMove:
|
case kku::SystemEvent::Type::MouseMove:
|
||||||
{
|
{
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
if (_is_dragging)
|
if (_is_dragging)
|
||||||
{
|
{
|
||||||
float x_mouse_diff = position.x - _previous_click_position.x;
|
float x_mouse_diff = position.x - _previous_click_position.x;
|
||||||
|
@ -57,7 +59,7 @@ void Window::input(const kku::SystemEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::update(const kku::microsec& dt)
|
void Window::update(const kku::microsec &dt)
|
||||||
{
|
{
|
||||||
Widget::update(dt);
|
Widget::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -73,18 +75,17 @@ void Window::display() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setRect(const kku::Area<float>& rect)
|
void Window::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_window_content->setRect(rect);
|
_window_content->setRect(rect);
|
||||||
|
|
||||||
kku::Area<float> bar_rect = {rect.left, rect.top, rect.width, 30};
|
kku::Area<float> bar_rect = {rect.left, rect.top, rect.width, 30};
|
||||||
_bar->setRect(bar_rect);
|
_bar->setRect(bar_rect);
|
||||||
|
|
||||||
_bar_title->setPosition(kku::Point{rect.left + 5,
|
_bar_title->setPosition(kku::Point{rect.left + 5, rect.top + 5});
|
||||||
rect.top + 5});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setPosition(const kku::Point& position)
|
void Window::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_window_content->setPosition(position);
|
_window_content->setPosition(position);
|
||||||
_bar->setPosition(position);
|
_bar->setPosition(position);
|
||||||
|
@ -94,7 +95,7 @@ void Window::setPosition(const kku::Point& position)
|
||||||
_bar_title->setPosition(new_position);
|
_bar_title->setPosition(new_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::move(const kku::Vector2<float>& delta)
|
void Window::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_window_content->move(delta);
|
_window_content->move(delta);
|
||||||
_bar->move(delta);
|
_bar->move(delta);
|
||||||
|
@ -103,7 +104,7 @@ void Window::move(const kku::Vector2<float>& delta)
|
||||||
Widget::move(delta);
|
Widget::move(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::isUnderMouse(const kku::Point& position) const
|
bool Window::isUnderMouse(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _is_visible && _window_content->contains(position);
|
return _is_visible && _window_content->contains(position);
|
||||||
}
|
}
|
||||||
|
@ -114,8 +115,7 @@ void Window::addBarButton(const std::string &text, kku::lambda callback)
|
||||||
|
|
||||||
auto b = std::make_shared<PushButton>(text, _core_factory, 20);
|
auto b = std::make_shared<PushButton>(text, _core_factory, 20);
|
||||||
b->setCallback(callback);
|
b->setCallback(callback);
|
||||||
b->setRect({area.left + area.width - 35,
|
b->setRect({area.left + area.width - 35, area.top, 30, 30});
|
||||||
area.top, 30, 30});
|
|
||||||
|
|
||||||
Widget::addChild(b);
|
Widget::addChild(b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include "applicationsfml.h"
|
#include "applicationsfml.h"
|
||||||
#include "sfml/corefactorysfml.h"
|
|
||||||
#include "sfml/application/inputconvertersfml.h"
|
#include "sfml/application/inputconvertersfml.h"
|
||||||
|
#include "sfml/corefactorysfml.h"
|
||||||
|
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
|
|
||||||
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f);
|
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f);
|
||||||
|
|
||||||
ApplicationSFML::ApplicationSFML(sf::RenderWindow * const render_window) :
|
ApplicationSFML::ApplicationSFML(sf::RenderWindow *const render_window)
|
||||||
_render_window(render_window)
|
: _render_window(render_window)
|
||||||
{
|
{
|
||||||
_render_window->setFramerateLimit(60);
|
_render_window->setFramerateLimit(60);
|
||||||
_render_window->setKeyRepeatEnabled(false);
|
_render_window->setKeyRepeatEnabled(false);
|
||||||
|
@ -21,7 +21,7 @@ void ApplicationSFML::display()
|
||||||
{
|
{
|
||||||
_render_window->clear();
|
_render_window->clear();
|
||||||
|
|
||||||
for (const auto& state : _state_stack)
|
for (const auto &state : _state_stack)
|
||||||
state->display();
|
state->display();
|
||||||
|
|
||||||
_render_window->display();
|
_render_window->display();
|
||||||
|
@ -39,7 +39,7 @@ void ApplicationSFML::run()
|
||||||
sf::Event event;
|
sf::Event event;
|
||||||
while (_render_window->pollEvent(event))
|
while (_render_window->pollEvent(event))
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
case sf::Event::Closed:
|
case sf::Event::Closed:
|
||||||
_render_window->close();
|
_render_window->close();
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
|
|
||||||
class ApplicationSFML : public Application
|
class ApplicationSFML : public Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ApplicationSFML(sf::RenderWindow * const _render_window);
|
explicit ApplicationSFML(sf::RenderWindow *const _render_window);
|
||||||
virtual void display() override;
|
virtual void display() override;
|
||||||
virtual void run() override;
|
virtual void run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RenderWindow * const _render_window;
|
sf::RenderWindow *const _render_window;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ constexpr kku::SystemEvent::Key::Code convert(sf::Keyboard::Key key) noexcept
|
||||||
return kku::SystemEvent::Key::Code{int(key)};
|
return kku::SystemEvent::Key::Code{int(key)};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr kku::SystemEvent convert(const sf::Event& event) noexcept
|
constexpr kku::SystemEvent convert(const sf::Event &event) noexcept
|
||||||
{
|
{
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
|
@ -19,120 +19,64 @@ constexpr kku::SystemEvent convert(const sf::Event& event) noexcept
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::Resized:
|
case sf::Event::Resized:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::Resize,
|
kku::SystemEvent::Type::Resize,
|
||||||
kku::SystemEvent::Size
|
kku::SystemEvent::Size{event.size.width, event.size.height}};
|
||||||
{
|
|
||||||
event.size.width,
|
|
||||||
event.size.height
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::KeyPress,
|
kku::SystemEvent::Type::KeyPress,
|
||||||
kku::SystemEvent::Key
|
kku::SystemEvent::Key{kku::convert(event.key.code), event.key.alt,
|
||||||
{
|
event.key.control, event.key.shift}};
|
||||||
kku::convert(event.key.code),
|
|
||||||
event.key.alt,
|
|
||||||
event.key.control,
|
|
||||||
event.key.shift
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::KeyReleased:
|
case sf::Event::KeyReleased:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::KeyRelease,
|
kku::SystemEvent::Type::KeyRelease,
|
||||||
kku::SystemEvent::Key
|
kku::SystemEvent::Key{kku::convert(event.key.code), event.key.alt,
|
||||||
{
|
event.key.control, event.key.shift}};
|
||||||
kku::convert(event.key.code),
|
|
||||||
event.key.alt,
|
|
||||||
event.key.control,
|
|
||||||
event.key.shift
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::MouseWheelScrolled:
|
case sf::Event::MouseWheelScrolled:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::MouseWheelScroll,
|
kku::SystemEvent::Type::MouseWheelScroll,
|
||||||
kku::SystemEvent::Mouse
|
kku::SystemEvent::Mouse{
|
||||||
{
|
kku::Point{event.mouseWheelScroll.x, event.mouseWheelScroll.y},
|
||||||
kku::Point
|
|
||||||
{
|
|
||||||
event.mouseWheelScroll.x,
|
|
||||||
event.mouseWheelScroll.y
|
|
||||||
},
|
|
||||||
|
|
||||||
(event.mouseWheelScroll.delta > 0),
|
(event.mouseWheelScroll.delta > 0),
|
||||||
kku::SystemEvent::Mouse::Button::Wheel
|
kku::SystemEvent::Mouse::Button::Wheel}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::MouseMoved:
|
case sf::Event::MouseMoved:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::MouseMove,
|
kku::SystemEvent::Type::MouseMove,
|
||||||
kku::SystemEvent::Mouse
|
kku::SystemEvent::Mouse{
|
||||||
{
|
kku::Point{event.mouseMove.x, event.mouseMove.y},
|
||||||
kku::Point
|
|
||||||
{
|
|
||||||
event.mouseMove.x,
|
|
||||||
event.mouseMove.y
|
|
||||||
},
|
|
||||||
|
|
||||||
false,
|
false, kku::SystemEvent::Mouse::Button::None}};
|
||||||
kku::SystemEvent::Mouse::Button::None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::MouseButtonPressed:
|
case sf::Event::MouseButtonPressed:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::MousePress,
|
kku::SystemEvent::Type::MousePress,
|
||||||
kku::SystemEvent::Mouse
|
kku::SystemEvent::Mouse{
|
||||||
{
|
kku::Point{event.mouseButton.x, event.mouseButton.y},
|
||||||
kku::Point
|
|
||||||
{
|
|
||||||
event.mouseButton.x,
|
|
||||||
event.mouseButton.y
|
|
||||||
},
|
|
||||||
|
|
||||||
false,
|
false,
|
||||||
((event.mouseButton.button == sf::Mouse::Button::Left)
|
((event.mouseButton.button == sf::Mouse::Button::Left)
|
||||||
? kku::SystemEvent::Mouse::Button::Left
|
? kku::SystemEvent::Mouse::Button::Left
|
||||||
: kku::SystemEvent::Mouse::Button::Right)
|
: kku::SystemEvent::Mouse::Button::Right)}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
case sf::Event::MouseButtonReleased:
|
case sf::Event::MouseButtonReleased:
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{
|
||||||
{
|
|
||||||
kku::SystemEvent::Type::MouseRelease,
|
kku::SystemEvent::Type::MouseRelease,
|
||||||
kku::SystemEvent::Mouse
|
kku::SystemEvent::Mouse{
|
||||||
{
|
kku::Point{event.mouseButton.x, event.mouseButton.y},
|
||||||
kku::Point
|
|
||||||
{
|
|
||||||
event.mouseButton.x,
|
|
||||||
event.mouseButton.y
|
|
||||||
},
|
|
||||||
|
|
||||||
false,
|
false,
|
||||||
((event.mouseButton.button == sf::Mouse::Button::Left)
|
((event.mouseButton.button == sf::Mouse::Button::Left)
|
||||||
? kku::SystemEvent::Mouse::Button::Left
|
? kku::SystemEvent::Mouse::Button::Left
|
||||||
: kku::SystemEvent::Mouse::Button::Right)
|
: kku::SystemEvent::Mouse::Button::Right)}};
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return kku::SystemEvent
|
return kku::SystemEvent{kku::SystemEvent::Type::None,
|
||||||
{
|
kku::SystemEvent::None{}};
|
||||||
kku::SystemEvent::Type::None,
|
|
||||||
kku::SystemEvent::None{}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace kku
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include "corefactorysfml.h"
|
#include "corefactorysfml.h"
|
||||||
|
|
||||||
#include "rectanglesfml.h"
|
|
||||||
#include "musicsfml.h"
|
|
||||||
#include "textsfml.h"
|
|
||||||
#include "linesfml.h"
|
#include "linesfml.h"
|
||||||
|
#include "musicsfml.h"
|
||||||
|
#include "rectanglesfml.h"
|
||||||
#include "spritesfml.h"
|
#include "spritesfml.h"
|
||||||
|
#include "textsfml.h"
|
||||||
|
|
||||||
CoreFactorySFML::CoreFactorySFML(sf::RenderTarget * const render_target) :
|
CoreFactorySFML::CoreFactorySFML(sf::RenderTarget *const render_target)
|
||||||
_render_target(render_target)
|
: _render_target(render_target)
|
||||||
{
|
{
|
||||||
auto gui_font = std::make_unique<sf::Font>();
|
auto gui_font = std::make_unique<sf::Font>();
|
||||||
gui_font->loadFromFile("resources/SourceCodePro-Regular.ttf");
|
gui_font->loadFromFile("resources/SourceCodePro-Regular.ttf");
|
||||||
|
@ -33,13 +33,14 @@ std::shared_ptr<kku::Rectangle> CoreFactorySFML::getRectangle() const
|
||||||
return std::make_unique<RectangleSFML>(_render_target);
|
return std::make_unique<RectangleSFML>(_render_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<kku::Line> CoreFactorySFML::getLine() const
|
std::shared_ptr<kku::Line> CoreFactorySFML::getLine() const
|
||||||
{
|
{
|
||||||
return std::make_unique<LineSFML>(_render_target);
|
return std::make_unique<LineSFML>(_render_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<kku::Sprite> CoreFactorySFML::getSprite(kku::GUISprite::Id id) const
|
std::shared_ptr<kku::Sprite>
|
||||||
{
|
CoreFactorySFML::getSprite(kku::GUISprite::Id id) const
|
||||||
|
{
|
||||||
const auto texture = _texture_holder.get(kku::Texture::Id::GUI);
|
const auto texture = _texture_holder.get(kku::Texture::Id::GUI);
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
|
@ -48,16 +49,18 @@ std::shared_ptr<kku::Rectangle> CoreFactorySFML::getRectangle() const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kku::GUISprite::Id::SFML_LOGO:
|
case kku::GUISprite::Id::SFML_LOGO:
|
||||||
return std::make_unique<SpriteSFML>(_render_target, _texture_holder.get(kku::Texture::Id::GUI),
|
return std::make_unique<SpriteSFML>(
|
||||||
kku::Area<unsigned int>{0, 0, 252, 81});
|
_render_target, _texture_holder.get(kku::Texture::Id::GUI),
|
||||||
|
kku::Area<unsigned int>{0, 0, 252, 81});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kku::GUISprite::Id::CRYPTOPP_LOGO:
|
case kku::GUISprite::Id::CRYPTOPP_LOGO:
|
||||||
return std::make_unique<SpriteSFML>(_render_target, _texture_holder.get(kku::Texture::Id::GUI),
|
return std::make_unique<SpriteSFML>(
|
||||||
kku::Area<unsigned int>{252, 0, 135, 36});
|
_render_target, _texture_holder.get(kku::Texture::Id::GUI),
|
||||||
|
kku::Area<unsigned int>{252, 0, 135, 36});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kku::Vector2<std::size_t> CoreFactorySFML::getRenderSize() const
|
kku::Vector2<std::size_t> CoreFactorySFML::getRenderSize() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SFML/Graphics/Font.hpp>
|
||||||
#include <SFML/Graphics/RectangleShape.hpp>
|
#include <SFML/Graphics/RectangleShape.hpp>
|
||||||
#include <SFML/Graphics/RenderTarget.hpp>
|
#include <SFML/Graphics/RenderTarget.hpp>
|
||||||
#include <SFML/Graphics/Font.hpp>
|
|
||||||
#include <SFML/Graphics/Sprite.hpp>
|
#include <SFML/Graphics/Sprite.hpp>
|
||||||
#include <SFML/Graphics/Texture.hpp>
|
#include <SFML/Graphics/Texture.hpp>
|
||||||
|
|
||||||
|
@ -10,17 +10,18 @@
|
||||||
|
|
||||||
class CoreFactorySFML : public kku::CoreFactory
|
class CoreFactorySFML : public kku::CoreFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CoreFactorySFML(sf::RenderTarget * const render_target);
|
explicit CoreFactorySFML(sf::RenderTarget *const render_target);
|
||||||
virtual std::shared_ptr<kku::Music> getMusic() const override;
|
virtual std::shared_ptr<kku::Music> getMusic() const override;
|
||||||
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const override;
|
virtual std::shared_ptr<kku::Text> getText(kku::Font::Id id) const override;
|
||||||
virtual std::shared_ptr<kku::Rectangle> getRectangle() const override;
|
virtual std::shared_ptr<kku::Rectangle> getRectangle() const override;
|
||||||
virtual std::shared_ptr<kku::Line> getLine() const override;
|
virtual std::shared_ptr<kku::Line> getLine() const override;
|
||||||
virtual std::shared_ptr<kku::Sprite> getSprite(kku::GUISprite::Id id) const override;
|
virtual std::shared_ptr<kku::Sprite>
|
||||||
|
getSprite(kku::GUISprite::Id id) const override;
|
||||||
virtual kku::Vector2<std::size_t> getRenderSize() const override;
|
virtual kku::Vector2<std::size_t> getRenderSize() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RenderTarget * const _render_target;
|
sf::RenderTarget *const _render_target;
|
||||||
kku::ResourceHolder<sf::Font, kku::Font::Id> _font_holder;
|
kku::ResourceHolder<sf::Font, kku::Font::Id> _font_holder;
|
||||||
kku::ResourceHolder<sf::Texture, kku::Texture::Id> _texture_holder;
|
kku::ResourceHolder<sf::Texture, kku::Texture::Id> _texture_holder;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#include "linesfml.h"
|
#include "linesfml.h"
|
||||||
|
|
||||||
LineSFML::LineSFML(sf::RenderTarget * const render_target) :
|
LineSFML::LineSFML(sf::RenderTarget *const render_target)
|
||||||
_render_target(render_target)
|
: _render_target(render_target)
|
||||||
{
|
{
|
||||||
_vertex = sf::VertexArray(sf::LinesStrip, 2);
|
_vertex = sf::VertexArray(sf::LinesStrip, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineSFML::setPosition(const kku::Point& p1, const kku::Point& p2)
|
void LineSFML::setPosition(const kku::Point &p1, const kku::Point &p2)
|
||||||
{
|
{
|
||||||
_vertex[0].position = {p1.x, p1.y};
|
_vertex[0].position = {p1.x, p1.y};
|
||||||
_vertex[1].position = {p2.x, p2.y};
|
_vertex[1].position = {p2.x, p2.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineSFML::setColor(const kku::Color& c1, const kku::Color& c2)
|
void LineSFML::setColor(const kku::Color &c1, const kku::Color &c2)
|
||||||
{
|
{
|
||||||
_vertex[0].color = sf::Color{c1.red, c1.green, c1.blue, c1.alpha};
|
_vertex[0].color = sf::Color{c1.red, c1.green, c1.blue, c1.alpha};
|
||||||
_vertex[1].color = sf::Color{c2.red, c2.green, c2.blue, c2.alpha};
|
_vertex[1].color = sf::Color{c2.red, c2.green, c2.blue, c2.alpha};
|
||||||
|
|
|
@ -8,13 +8,14 @@
|
||||||
|
|
||||||
class LineSFML : public kku::Line
|
class LineSFML : public kku::Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit LineSFML(sf::RenderTarget * const render_target);
|
explicit LineSFML(sf::RenderTarget *const render_target);
|
||||||
virtual void setPosition(const kku::Point& p1, const kku::Point& p2) override;
|
virtual void setPosition(const kku::Point &p1,
|
||||||
virtual void setColor(const kku::Color& c1, const kku::Color& c2) override;
|
const kku::Point &p2) override;
|
||||||
|
virtual void setColor(const kku::Color &c1, const kku::Color &c2) override;
|
||||||
virtual void display() override;
|
virtual void display() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RenderTarget * const _render_target;
|
sf::RenderTarget *const _render_target;
|
||||||
sf::VertexArray _vertex;
|
sf::VertexArray _vertex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
#include "musicsfml.h"
|
#include "musicsfml.h"
|
||||||
|
|
||||||
MusicSFML::MusicSFML() :
|
MusicSFML::MusicSFML()
|
||||||
_sfml_music_offset(0),
|
: _sfml_music_offset(0), _previous_frame_offset(0), _absolute_offset(0)
|
||||||
_previous_frame_offset(0),
|
{
|
||||||
_absolute_offset(0)
|
}
|
||||||
{}
|
|
||||||
|
|
||||||
bool MusicSFML::open(const std::string& filepath)
|
bool MusicSFML::open(const std::string &filepath)
|
||||||
{
|
{
|
||||||
return _music.openFromFile(filepath);
|
return _music.openFromFile(filepath);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,7 @@ void MusicSFML::setVolume(float volume)
|
||||||
_music.setVolume(volume);
|
_music.setVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicSFML::setOffset(const kku::microsec& offset)
|
void MusicSFML::setOffset(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
//_previous_frame_offset += (offset - _absolute_offset);
|
//_previous_frame_offset += (offset - _absolute_offset);
|
||||||
_music.setPlayingOffset(sf::microseconds(offset));
|
_music.setPlayingOffset(sf::microseconds(offset));
|
||||||
|
@ -48,7 +47,8 @@ kku::microsec MusicSFML::fetchOffset()
|
||||||
if (_music.getStatus() != sf::Music::Status::Playing)
|
if (_music.getStatus() != sf::Music::Status::Playing)
|
||||||
return _absolute_offset;
|
return _absolute_offset;
|
||||||
|
|
||||||
const auto interpolator_timestamp = _offset_interpolator.getElapsedTime().asMicroseconds();
|
const auto interpolator_timestamp =
|
||||||
|
_offset_interpolator.getElapsedTime().asMicroseconds();
|
||||||
const auto sfml_new_offset = _music.getPlayingOffset().asMicroseconds();
|
const auto sfml_new_offset = _music.getPlayingOffset().asMicroseconds();
|
||||||
|
|
||||||
_absolute_offset += (interpolator_timestamp - _previous_frame_offset);
|
_absolute_offset += (interpolator_timestamp - _previous_frame_offset);
|
||||||
|
@ -62,7 +62,7 @@ kku::microsec MusicSFML::fetchOffset()
|
||||||
return _absolute_offset;
|
return _absolute_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicSFML::moveOffset(const kku::microsec& delta)
|
void MusicSFML::moveOffset(const kku::microsec &delta)
|
||||||
{
|
{
|
||||||
const auto offset = fetchOffset();
|
const auto offset = fetchOffset();
|
||||||
const auto result = offset + delta;
|
const auto result = offset + delta;
|
||||||
|
@ -86,4 +86,3 @@ kku::microsec MusicSFML::getDuration() const
|
||||||
{
|
{
|
||||||
return _music.getDuration().asMicroseconds();
|
return _music.getDuration().asMicroseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
class MusicSFML : public kku::Music
|
class MusicSFML : public kku::Music
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MusicSFML();
|
explicit MusicSFML();
|
||||||
virtual bool open(const std::string& filepath) override;
|
virtual bool open(const std::string &filepath) override;
|
||||||
|
|
||||||
virtual void play() override;
|
virtual void play() override;
|
||||||
virtual void pause() override;
|
virtual void pause() override;
|
||||||
|
@ -19,13 +19,13 @@ public:
|
||||||
|
|
||||||
virtual void setVolume(float volume) override;
|
virtual void setVolume(float volume) override;
|
||||||
|
|
||||||
virtual void setOffset(const kku::microsec& offset) override;
|
virtual void setOffset(const kku::microsec &offset) override;
|
||||||
virtual void moveOffset(const kku::microsec& delta) override;
|
virtual void moveOffset(const kku::microsec &delta) override;
|
||||||
|
|
||||||
virtual kku::microsec fetchOffset() override;
|
virtual kku::microsec fetchOffset() override;
|
||||||
virtual kku::microsec getDuration() const override;
|
virtual kku::microsec getDuration() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::Music _music;
|
sf::Music _music;
|
||||||
sf::Clock _offset_interpolator;
|
sf::Clock _offset_interpolator;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "rectanglesfml.h"
|
#include "rectanglesfml.h"
|
||||||
|
|
||||||
RectangleSFML::RectangleSFML(sf::RenderTarget * const render_target) :
|
RectangleSFML::RectangleSFML(sf::RenderTarget *const render_target)
|
||||||
_render_target(render_target)
|
: _render_target(render_target)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void RectangleSFML::setRect(const kku::Area<float>& rect)
|
void RectangleSFML::setRect(const kku::Area<float> &rect)
|
||||||
{
|
{
|
||||||
_rectangle.setPosition(rect.left, rect.top);
|
_rectangle.setPosition(rect.left, rect.top);
|
||||||
_rectangle.setSize({rect.width, rect.height});
|
_rectangle.setSize({rect.width, rect.height});
|
||||||
|
@ -18,12 +19,12 @@ kku::Area<float> RectangleSFML::getRect() const
|
||||||
return kku::Area<float>{position.x, position.y, size.x, size.y};
|
return kku::Area<float>{position.x, position.y, size.x, size.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
void RectangleSFML::move(const kku::Vector2<float>& delta)
|
void RectangleSFML::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_rectangle.move({delta.first, delta.second});
|
_rectangle.move({delta.first, delta.second});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RectangleSFML::setPosition(const kku::Point& position)
|
void RectangleSFML::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_rectangle.setPosition({position.x, position.y});
|
_rectangle.setPosition({position.x, position.y});
|
||||||
}
|
}
|
||||||
|
@ -34,10 +35,10 @@ kku::Point RectangleSFML::getPosition() const
|
||||||
return kku::Point{position.x, position.y};
|
return kku::Point{position.x, position.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
void RectangleSFML::setColor(const kku::Color& color)
|
void RectangleSFML::setColor(const kku::Color &color)
|
||||||
{
|
{
|
||||||
_rectangle.setFillColor(sf::Color{color.red, color.green,
|
_rectangle.setFillColor(
|
||||||
color.blue, color.alpha});
|
sf::Color{color.red, color.green, color.blue, color.alpha});
|
||||||
}
|
}
|
||||||
|
|
||||||
kku::Color RectangleSFML::getColor() const
|
kku::Color RectangleSFML::getColor() const
|
||||||
|
@ -46,7 +47,7 @@ kku::Color RectangleSFML::getColor() const
|
||||||
return kku::Color{color.r, color.g, color.b, color.a};
|
return kku::Color{color.r, color.g, color.b, color.a};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RectangleSFML::contains(const kku::Point& position) const
|
bool RectangleSFML::contains(const kku::Point &position) const
|
||||||
{
|
{
|
||||||
return _rectangle.getGlobalBounds().contains(position.x, position.y);
|
return _rectangle.getGlobalBounds().contains(position.x, position.y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SFML/Graphics/RenderTarget.hpp>
|
|
||||||
#include <SFML/Graphics/RectangleShape.hpp>
|
#include <SFML/Graphics/RectangleShape.hpp>
|
||||||
|
#include <SFML/Graphics/RenderTarget.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "core/rectangle.h"
|
#include "core/rectangle.h"
|
||||||
|
|
||||||
class RectangleSFML : public kku::Rectangle
|
class RectangleSFML : public kku::Rectangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit RectangleSFML(sf::RenderTarget * const render_target);
|
explicit RectangleSFML(sf::RenderTarget *const render_target);
|
||||||
virtual void setRect(const kku::Area<float>& rect) override;
|
virtual void setRect(const kku::Area<float> &rect) override;
|
||||||
virtual kku::Area<float> getRect() const override;
|
virtual kku::Area<float> getRect() const override;
|
||||||
|
|
||||||
virtual void setPosition(const kku::Point& position) override;
|
virtual void setPosition(const kku::Point &position) override;
|
||||||
virtual kku::Point getPosition() const override;
|
virtual kku::Point getPosition() const override;
|
||||||
virtual void move(const kku::Vector2<float>& delta) override;
|
virtual void move(const kku::Vector2<float> &delta) override;
|
||||||
|
|
||||||
virtual void setColor(const kku::Color& color) override;
|
virtual void setColor(const kku::Color &color) override;
|
||||||
virtual kku::Color getColor() const override;
|
virtual kku::Color getColor() const override;
|
||||||
virtual bool contains(const kku::Point& position) const override;
|
virtual bool contains(const kku::Point &position) const override;
|
||||||
|
|
||||||
virtual void display() override;
|
virtual void display() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RenderTarget * const _render_target;
|
sf::RenderTarget *const _render_target;
|
||||||
sf::RectangleShape _rectangle;
|
sf::RectangleShape _rectangle;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
#include "spritesfml.h"
|
#include "spritesfml.h"
|
||||||
|
|
||||||
SpriteSFML::SpriteSFML(sf::RenderTarget * const render_target,
|
SpriteSFML::SpriteSFML(sf::RenderTarget *const render_target,
|
||||||
const std::shared_ptr<sf::Texture>& texture,
|
const std::shared_ptr<sf::Texture> &texture,
|
||||||
const kku::Area<unsigned int> &cropping) :
|
const kku::Area<unsigned int> &cropping)
|
||||||
_render_target(render_target),
|
: _render_target(render_target),
|
||||||
_sprite(*texture, sf::IntRect(cropping.left, cropping.top, cropping.width, cropping.height))
|
_sprite(*texture, sf::IntRect(cropping.left, cropping.top, cropping.width,
|
||||||
{}
|
cropping.height))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void SpriteSFML::setPosition(const kku::Point& position)
|
void SpriteSFML::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_sprite.setPosition(position.x, position.y);
|
_sprite.setPosition(position.x, position.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
kku::Point SpriteSFML::getPosition() const
|
kku::Point SpriteSFML::getPosition() const
|
||||||
{
|
{
|
||||||
const auto& position = _sprite.getPosition();
|
const auto &position = _sprite.getPosition();
|
||||||
return kku::Point
|
return kku::Point{position.x, position.y};
|
||||||
{
|
|
||||||
position.x,
|
|
||||||
position.y
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteSFML::move(const kku::Vector2<float>& delta)
|
void SpriteSFML::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_sprite.move({delta.first, delta.second});
|
_sprite.move({delta.first, delta.second});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,22 +4,23 @@
|
||||||
#include <SFML/Graphics/Sprite.hpp>
|
#include <SFML/Graphics/Sprite.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "core/area.h"
|
||||||
#include "core/sprite.h"
|
#include "core/sprite.h"
|
||||||
|
|
||||||
class SpriteSFML : public kku::Sprite
|
class SpriteSFML : public kku::Sprite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SpriteSFML(sf::RenderTarget * const render_target,
|
explicit SpriteSFML(sf::RenderTarget *const render_target,
|
||||||
const std::shared_ptr<sf::Texture> &texture,
|
const std::shared_ptr<sf::Texture> &texture,
|
||||||
const kku::Area<unsigned int>& cropping);
|
const kku::Area<unsigned int> &cropping);
|
||||||
|
|
||||||
virtual void setPosition(const kku::Point& position) override;
|
virtual void setPosition(const kku::Point &position) override;
|
||||||
virtual kku::Point getPosition() const override;
|
virtual kku::Point getPosition() const override;
|
||||||
virtual void move(const kku::Vector2<float>& delta) override;
|
virtual void move(const kku::Vector2<float> &delta) override;
|
||||||
|
|
||||||
virtual void display() const override;
|
virtual void display() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sf::RenderTarget * const _render_target;
|
sf::RenderTarget *const _render_target;
|
||||||
sf::Sprite _sprite;
|
sf::Sprite _sprite;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include "textsfml.h"
|
#include "textsfml.h"
|
||||||
|
|
||||||
TextSFML::TextSFML(sf::RenderTarget * const render_target,
|
TextSFML::TextSFML(sf::RenderTarget *const render_target,
|
||||||
const std::shared_ptr<const sf::Font>& font) :
|
const std::shared_ptr<const sf::Font> &font)
|
||||||
_render_target(render_target)
|
: _render_target(render_target)
|
||||||
{
|
{
|
||||||
_text.setFont(*font);
|
_text.setFont(*font);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextSFML::setString(const std::string& string)
|
void TextSFML::setString(const std::string &string)
|
||||||
{
|
{
|
||||||
_text.setString(string);
|
_text.setString(string);
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,20 @@ void TextSFML::setCharacterSize(std::size_t pixels)
|
||||||
_text.setCharacterSize(pixels);
|
_text.setCharacterSize(pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextSFML::setPosition(const kku::Point& point)
|
void TextSFML::setPosition(const kku::Point &point)
|
||||||
{
|
{
|
||||||
_text.setPosition(point.x, point.y);
|
_text.setPosition(point.x, point.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextSFML::move(const kku::Vector2<float>& delta)
|
void TextSFML::move(const kku::Vector2<float> &delta)
|
||||||
{
|
{
|
||||||
_text.move({delta.first, delta.second});
|
_text.move({delta.first, delta.second});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextSFML::setColor(const kku::Color& color)
|
void TextSFML::setColor(const kku::Color &color)
|
||||||
{
|
{
|
||||||
_text.setFillColor(sf::Color{color.red, color.green, color.blue, color.alpha});
|
_text.setFillColor(
|
||||||
|
sf::Color{color.red, color.green, color.blue, color.alpha});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextSFML::display()
|
void TextSFML::display()
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <SFML/Graphics/Font.hpp>
|
||||||
#include <SFML/Graphics/RenderTarget.hpp>
|
#include <SFML/Graphics/RenderTarget.hpp>
|
||||||
#include <SFML/Graphics/Text.hpp>
|
#include <SFML/Graphics/Text.hpp>
|
||||||
#include <SFML/Graphics/Font.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "core/text.h"
|
#include "core/text.h"
|
||||||
|
|
||||||
class TextSFML : public kku::Text
|
class TextSFML : public kku::Text
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TextSFML(sf::RenderTarget * const render_target,
|
explicit TextSFML(sf::RenderTarget *const render_target,
|
||||||
const std::shared_ptr<const sf::Font>& font);
|
const std::shared_ptr<const sf::Font> &font);
|
||||||
|
|
||||||
virtual void setString(const std::string& string) override;
|
virtual void setString(const std::string &string) override;
|
||||||
virtual void setCharacterSize(std::size_t pixels) override;
|
virtual void setCharacterSize(std::size_t pixels) override;
|
||||||
virtual void setPosition(const kku::Point& point) override;
|
virtual void setPosition(const kku::Point &point) override;
|
||||||
virtual void move(const kku::Vector2<float>& delta) override;
|
virtual void move(const kku::Vector2<float> &delta) override;
|
||||||
virtual void setColor(const kku::Color& color) override;
|
virtual void setColor(const kku::Color &color) override;
|
||||||
|
|
||||||
virtual void display() override;
|
virtual void display() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sf::RenderTarget * const _render_target;
|
sf::RenderTarget *const _render_target;
|
||||||
sf::Text _text;
|
sf::Text _text;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
sf::RenderWindow window(sf::VideoMode{1280, 720}, "Project Kyoku", sf::Style::Default);
|
sf::RenderWindow window(sf::VideoMode{1280, 720}, "Project Kyoku",
|
||||||
|
sf::Style::Default);
|
||||||
|
|
||||||
ApplicationSFML app(&window);
|
ApplicationSFML app(&window);
|
||||||
if (app.init())
|
if (app.init())
|
||||||
app.run();
|
app.run();
|
||||||
|
|
|
@ -1,46 +1,53 @@
|
||||||
#include "classicmode/classicfactory.h"
|
#include "classicmode/classicfactory.h"
|
||||||
|
|
||||||
|
#include "graphics/classicgraphicsfactory.h"
|
||||||
#include "graphics/classicscenegraphicsmanager.h"
|
#include "graphics/classicscenegraphicsmanager.h"
|
||||||
#include "graphics/classictimelinegraphicsmanager.h"
|
#include "graphics/classictimelinegraphicsmanager.h"
|
||||||
#include "graphics/classicgraphicsfactory.h"
|
|
||||||
|
|
||||||
#include "core/timeline.h"
|
#include "core/timeline.h"
|
||||||
#include "game/classicgame.h"
|
|
||||||
#include "game/gamecontext.h"
|
|
||||||
#include "game/holdmanager.h"
|
|
||||||
#include "editor/classiceditor.h"
|
#include "editor/classiceditor.h"
|
||||||
#include "editor/editorcontext.h"
|
#include "editor/editorcontext.h"
|
||||||
#include "editor/selectionmanager.h"
|
#include "editor/selectionmanager.h"
|
||||||
|
#include "game/classicgame.h"
|
||||||
|
#include "game/gamecontext.h"
|
||||||
|
#include "game/holdmanager.h"
|
||||||
|
|
||||||
|
std::unique_ptr<kku::Game>
|
||||||
std::unique_ptr<kku::Game> classic::getGame(const std::shared_ptr<kku::CoreFactory>& core_factory)
|
classic::getGame(const std::shared_ptr<kku::CoreFactory> &core_factory)
|
||||||
{
|
{
|
||||||
// read offset from beatmap metadata
|
|
||||||
const kku::microsec visibility_offset = 1648648;
|
const kku::microsec visibility_offset = 1648648;
|
||||||
|
|
||||||
const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory);
|
const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory);
|
||||||
const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>();
|
const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>();
|
||||||
const auto graphics_manager = std::make_shared<ClassicSceneGraphicsManager>(timeline, factory, visibility_offset);
|
const auto graphics_manager = std::make_shared<ClassicSceneGraphicsManager>(
|
||||||
|
timeline, factory, visibility_offset);
|
||||||
const auto hold_manager = std::make_shared<HoldManager>();
|
const auto hold_manager = std::make_shared<HoldManager>();
|
||||||
|
|
||||||
const auto context = std::make_shared<GameContext>(hold_manager, graphics_manager);
|
const auto context =
|
||||||
|
std::make_shared<GameContext>(hold_manager, graphics_manager);
|
||||||
|
|
||||||
return std::make_unique<ClassicGame>(timeline, context);
|
return std::make_unique<ClassicGame>(timeline, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<kku::Editor> classic::getEditor(const std::shared_ptr<kku::CoreFactory>& core_factory)
|
std::unique_ptr<kku::Editor>
|
||||||
|
classic::getEditor(const std::shared_ptr<kku::CoreFactory> &core_factory)
|
||||||
{
|
{
|
||||||
// read offset from beatmap metadata
|
|
||||||
const kku::microsec visibility_offset = 1648648;
|
const kku::microsec visibility_offset = 1648648;
|
||||||
|
|
||||||
const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory);
|
const auto factory = std::make_shared<ClassicGraphicsFactory>(core_factory);
|
||||||
const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>();
|
const auto timeline = std::make_shared<kku::Timeline<ClassicNote>>();
|
||||||
const auto selection_manager = std::make_shared<SelectionManager<ClassicNote>>();
|
const auto selection_manager =
|
||||||
|
std::make_shared<SelectionManager<ClassicNote>>();
|
||||||
std::vector<std::shared_ptr<ClassicGraphicsManager>> graphics_managers;
|
std::vector<std::shared_ptr<ClassicGraphicsManager>> graphics_managers;
|
||||||
graphics_managers.emplace_back(std::make_shared<ClassicSceneGraphicsManager>(timeline, factory, visibility_offset));
|
graphics_managers.emplace_back(
|
||||||
graphics_managers.emplace_back(std::make_shared<ClassicTimelineGraphicsManager>(timeline, factory, visibility_offset * 2));
|
std::make_shared<ClassicSceneGraphicsManager>(timeline, factory,
|
||||||
|
visibility_offset));
|
||||||
|
graphics_managers.emplace_back(
|
||||||
|
std::make_shared<ClassicTimelineGraphicsManager>(
|
||||||
|
timeline, factory, visibility_offset * 2));
|
||||||
|
|
||||||
const auto context = std::make_shared<EditorContext>(selection_manager, std::move(graphics_managers));
|
const auto context = std::make_shared<EditorContext>(
|
||||||
|
selection_manager, std::move(graphics_managers));
|
||||||
|
|
||||||
return std::make_unique<ClassicEditor>(timeline, context);
|
return std::make_unique<ClassicEditor>(timeline, context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#include "classicmode/classicnote.h"
|
#include "classicmode/classicnote.h"
|
||||||
|
|
||||||
ClassicNote::ClassicNote(const kku::microsec& perfect_offset, int id) :
|
ClassicNote::ClassicNote(const kku::microsec &perfect_offset, int id)
|
||||||
Note(perfect_offset),
|
: Note(perfect_offset), _state(State::NONE), _id(id)
|
||||||
_state(State::NONE),
|
{
|
||||||
_id(id)
|
}
|
||||||
{}
|
|
||||||
|
|
||||||
void ClassicNote::setState(ClassicNote::State state) noexcept
|
void ClassicNote::setState(ClassicNote::State state) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "callbacksimple.h"
|
#include "callbacksimple.h"
|
||||||
|
|
||||||
CallbackSimple::CallbackSimple(Init&& init, Metadata&& metadata) :
|
CallbackSimple::CallbackSimple(Init &&init, Metadata &&metadata)
|
||||||
_run(std::move(init.run)),
|
: _run(std::move(init.run)), _is_enabled(std::move(init.is_enabled)),
|
||||||
_is_enabled(std::move(init.is_enabled)),
|
_metadata(std::move(metadata))
|
||||||
_metadata(std::move(metadata))
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
bool CallbackSimple::isEnabled() const
|
bool CallbackSimple::isEnabled() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,37 +1,35 @@
|
||||||
#include "classiceditor.h"
|
#include "classiceditor.h"
|
||||||
|
|
||||||
#include "graphics/classicgraphicsmanager.h"
|
|
||||||
#include "editor/selectionmanager.h"
|
#include "editor/selectionmanager.h"
|
||||||
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
|
|
||||||
// Replace with interface by dependency injection
|
// Replace with interface by dependency injection
|
||||||
#include "graphics/animations/classicflyinganimationscenario.h"
|
|
||||||
#include "graphics/animations/classicdyinganimationscenario.h"
|
#include "graphics/animations/classicdyinganimationscenario.h"
|
||||||
|
#include "graphics/animations/classicflyinganimationscenario.h"
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "game/classicarrownote.h"
|
|
||||||
#include "editorcontext.h"
|
|
||||||
#include "callbacks/callbacksimple.h"
|
#include "callbacks/callbacksimple.h"
|
||||||
|
#include "editorcontext.h"
|
||||||
|
#include "game/classicarrownote.h"
|
||||||
|
|
||||||
ClassicEditor::ClassicEditor(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
|
ClassicEditor::ClassicEditor(
|
||||||
const std::shared_ptr<EditorContext>& context) :
|
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline,
|
||||||
_timeline(timeline),
|
const std::shared_ptr<EditorContext> &context)
|
||||||
_context(context),
|
: _timeline(timeline), _context(context), _selected_type(Type::UP),
|
||||||
_selected_type(Type::UP),
|
_current_time(0), _scroll_step(500000), _note_id(0)
|
||||||
_current_time(0),
|
|
||||||
_scroll_step(500000),
|
|
||||||
_note_id(0)
|
|
||||||
{
|
{
|
||||||
kku::microsec starting_beat_offset = 402162;
|
kku::microsec starting_beat_offset = 402162;
|
||||||
int amount_of_beats = 209;
|
int amount_of_beats = 209;
|
||||||
kku::microsec interval = 1412162;
|
kku::microsec interval = 1412162;
|
||||||
kku::microsec tempo_interval = interval / 4;
|
kku::microsec tempo_interval = interval / 4;
|
||||||
kku::microsec note_input_offset = 412162 / 2;
|
kku::microsec note_input_offset = 412162 / 2;
|
||||||
//microsec note_input_offset_fast = 412162 / 6;
|
// microsec note_input_offset_fast = 412162 / 6;
|
||||||
kku::microsec bpm_iterator = starting_beat_offset;
|
kku::microsec bpm_iterator = starting_beat_offset;
|
||||||
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
||||||
|
|
||||||
std::vector<kku::microsec> input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
std::vector<kku::microsec> input_intervals = {
|
||||||
std::set<ClassicNote*, kku::NotePtrComparator> notes;
|
note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
||||||
|
std::set<ClassicNote *, kku::NotePtrComparator> notes;
|
||||||
input_intervals.shrink_to_fit();
|
input_intervals.shrink_to_fit();
|
||||||
|
|
||||||
bpm_iterator += tempo_interval;
|
bpm_iterator += tempo_interval;
|
||||||
|
@ -53,6 +51,14 @@ ClassicEditor::ClassicEditor(const std::shared_ptr<kku::Timeline<ClassicNote>>&
|
||||||
|
|
||||||
bool hold = false;
|
bool hold = false;
|
||||||
|
|
||||||
|
if (_note_id == 0)
|
||||||
|
{
|
||||||
|
element.keys = {kku::SystemEvent::Key::Code::S,
|
||||||
|
kku::SystemEvent::Key::Code::Down};
|
||||||
|
|
||||||
|
element.type = Type::DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
if (counter == 0)
|
if (counter == 0)
|
||||||
{
|
{
|
||||||
hold = true;
|
hold = true;
|
||||||
|
@ -67,15 +73,8 @@ ClassicEditor::ClassicEditor(const std::shared_ptr<kku::Timeline<ClassicNote>>&
|
||||||
|
|
||||||
--counter;
|
--counter;
|
||||||
|
|
||||||
ClassicArrowNote::Init init
|
ClassicArrowNote::Init init{_note_id++, context, bpm_iterator,
|
||||||
{
|
input_intervals, {element}, hold};
|
||||||
_note_id++,
|
|
||||||
context,
|
|
||||||
bpm_iterator,
|
|
||||||
input_intervals,
|
|
||||||
{element},
|
|
||||||
hold
|
|
||||||
};
|
|
||||||
|
|
||||||
notes.insert(new ClassicArrowNote(std::move(init)));
|
notes.insert(new ClassicArrowNote(std::move(init)));
|
||||||
|
|
||||||
|
@ -91,16 +90,16 @@ ClassicEditor::ClassicEditor(const std::shared_ptr<kku::Timeline<ClassicNote>>&
|
||||||
|
|
||||||
kku::microsec ClassicEditor::adjustOffset(kku::microsec offset) const noexcept
|
kku::microsec ClassicEditor::adjustOffset(kku::microsec offset) const noexcept
|
||||||
{
|
{
|
||||||
const auto& section = getBPMSectionAt(offset);
|
const auto §ion = getBPMSectionAt(offset);
|
||||||
const kku::microsec actual_offset = offset - section.offset_start;
|
const kku::microsec actual_offset = offset - section.offset_start;
|
||||||
|
|
||||||
return actual_offset + (actual_offset % (section.interval + 1));
|
return actual_offset + (actual_offset % (section.interval + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::input(kku::GameEvent&& input)
|
void ClassicEditor::input(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
_current_time = input.timestamp;
|
_current_time = input.timestamp;
|
||||||
const auto& event = input.event;
|
const auto &event = input.event;
|
||||||
|
|
||||||
switch (input.event.type)
|
switch (input.event.type)
|
||||||
{
|
{
|
||||||
|
@ -131,11 +130,13 @@ void ClassicEditor::input(kku::GameEvent&& input)
|
||||||
case kku::SystemEvent::Type::MousePress:
|
case kku::SystemEvent::Type::MousePress:
|
||||||
{
|
{
|
||||||
const auto note = _timeline->getNoteBy(_current_time);
|
const auto note = _timeline->getNoteBy(_current_time);
|
||||||
if (_timeline->isExpired(note) && !_bpm_sections.empty() && _current_time >= (*_bpm_sections.begin()).offset_start)
|
if (_timeline->isExpired(note) && !_bpm_sections.empty() &&
|
||||||
|
_current_time >= (*_bpm_sections.begin()).offset_start)
|
||||||
{
|
{
|
||||||
ArrowElement element;
|
ArrowElement element;
|
||||||
|
|
||||||
element.position = std::get<kku::SystemEvent::Mouse>(event.data).position;
|
element.position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(event.data).position;
|
||||||
element.falling_curve_interpolation = {};
|
element.falling_curve_interpolation = {};
|
||||||
|
|
||||||
element.keys = {kku::SystemEvent::Key::Code::W,
|
element.keys = {kku::SystemEvent::Key::Code::W,
|
||||||
|
@ -143,15 +144,8 @@ void ClassicEditor::input(kku::GameEvent&& input)
|
||||||
|
|
||||||
element.type = Type::UP;
|
element.type = Type::UP;
|
||||||
|
|
||||||
ClassicArrowNote::Init init
|
ClassicArrowNote::Init init{_note_id++, _context, _current_time,
|
||||||
{
|
{}, {element}, false};
|
||||||
_note_id++,
|
|
||||||
_context,
|
|
||||||
_current_time,
|
|
||||||
{},
|
|
||||||
{element},
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
_timeline->insertNote(new ClassicArrowNote(std::move(init)));
|
_timeline->insertNote(new ClassicArrowNote(std::move(init)));
|
||||||
}
|
}
|
||||||
|
@ -163,11 +157,12 @@ void ClassicEditor::input(kku::GameEvent&& input)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_context->inputUI(std::move(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::update(kku::UpdateData&& updatedata)
|
void ClassicEditor::update(kku::UpdateData &&updatedata)
|
||||||
{
|
{
|
||||||
_timeline->update(updatedata.timestamp);
|
_timeline->update(updatedata.timestamp);
|
||||||
_context->updateGraphics(updatedata.timestamp);
|
_context->updateGraphics(updatedata.timestamp);
|
||||||
|
@ -178,7 +173,7 @@ void ClassicEditor::display() const
|
||||||
_context->displayGraphics();
|
_context->displayGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::recalculate(const kku::microsec& timestamp)
|
void ClassicEditor::recalculate(const kku::microsec ×tamp)
|
||||||
{
|
{
|
||||||
_timeline->recalculate(timestamp);
|
_timeline->recalculate(timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,15 @@
|
||||||
#include "graphics/classicgraphicsmanager.h"
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
#include "graphics/classicnotegraphics.h"
|
#include "graphics/classicnotegraphics.h"
|
||||||
|
|
||||||
EditorContext::EditorContext(const std::shared_ptr<SelectionManager<ClassicNote>>& selection_manager,
|
EditorContext::EditorContext(
|
||||||
std::vector<std::shared_ptr<ClassicGraphicsManager>>&& graphics_managers) :
|
const std::shared_ptr<SelectionManager<ClassicNote>> &selection_manager,
|
||||||
_selection_manager(selection_manager),
|
std::vector<std::shared_ptr<ClassicGraphicsManager>> &&graphics_managers)
|
||||||
_graphics_managers(std::move(graphics_managers))
|
: _selection_manager(selection_manager),
|
||||||
{}
|
_graphics_managers(std::move(graphics_managers))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void EditorContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
|
void EditorContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const
|
||||||
{
|
{
|
||||||
(void)note;
|
(void)note;
|
||||||
switch (input.event.type)
|
switch (input.event.type)
|
||||||
|
@ -19,58 +21,62 @@ void EditorContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*case kku::SystemEvent::Type::MousePress:
|
/*case kku::SystemEvent::Type::MousePress:
|
||||||
{
|
|
||||||
bool selection_changed = false;
|
|
||||||
std::size_t amount_selected = 0;
|
|
||||||
|
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(input.event.data).position;
|
|
||||||
for (auto& element : note->getElements())
|
|
||||||
{
|
{
|
||||||
if (element.sprite->getRectangle()->contains(position))
|
bool selection_changed = false;
|
||||||
|
std::size_t amount_selected = 0;
|
||||||
|
|
||||||
|
const auto position =
|
||||||
|
std::get<kku::SystemEvent::Mouse>(input.event.data).position; for (auto&
|
||||||
|
element : note->getElements())
|
||||||
{
|
{
|
||||||
element.selected = !element.selected;
|
if (element.sprite->getRectangle()->contains(position))
|
||||||
selection_changed = true;
|
{
|
||||||
if (element.selected)
|
element.selected = !element.selected;
|
||||||
++amount_selected;
|
selection_changed = true;
|
||||||
|
if (element.selected)
|
||||||
|
++amount_selected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (selection_changed)
|
if (selection_changed)
|
||||||
{
|
{
|
||||||
if (amount_selected > 0)
|
if (amount_selected > 0)
|
||||||
_selection_manager->fetch(note);
|
_selection_manager->fetch(note);
|
||||||
else
|
else
|
||||||
_selection_manager->remove(note);
|
_selection_manager->remove(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorContext::update(ClassicArrowNote *note, const kku::microsec& music_offset) const
|
void EditorContext::update(ClassicArrowNote *note,
|
||||||
|
const kku::microsec &music_offset) const
|
||||||
{
|
{
|
||||||
auto& elements = note->getElements();
|
auto &elements = note->getElements();
|
||||||
|
|
||||||
switch (note->getState())
|
switch (note->getState())
|
||||||
{
|
{
|
||||||
default: return;
|
default:
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClassicArrowNote::State::INITIAL:
|
case ClassicArrowNote::State::INITIAL:
|
||||||
note->setState(ClassicArrowNote::State::FLYING);
|
note->setState(ClassicArrowNote::State::FLYING);
|
||||||
for (auto& manager : _graphics_managers)
|
for (auto &manager : _graphics_managers)
|
||||||
manager->update(music_offset, note);
|
manager->update(music_offset, note);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClassicArrowNote::State::FLYING:
|
case ClassicArrowNote::State::FLYING:
|
||||||
if (!note->isActive(music_offset) && music_offset > note->getPerfectOffset())
|
if (!note->isActive(music_offset) &&
|
||||||
|
music_offset > note->getPerfectOffset())
|
||||||
{
|
{
|
||||||
note->setState(ClassicArrowNote::State::DYING);
|
note->setState(ClassicArrowNote::State::DYING);
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
element.animations[note->getState()]->launch(element.sprite, music_offset, note->getPerfectOffset());
|
element.animations[note->getState()]->launch(
|
||||||
|
element.sprite, music_offset, note->getPerfectOffset());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -78,30 +84,37 @@ void EditorContext::update(ClassicArrowNote *note, const kku::microsec& music_of
|
||||||
if (elements[0].animations[note->getState()]->isDone())
|
if (elements[0].animations[note->getState()]->isDone())
|
||||||
{
|
{
|
||||||
note->setState(ClassicArrowNote::State::DEAD);
|
note->setState(ClassicArrowNote::State::DEAD);
|
||||||
for (auto& manager : _graphics_managers)
|
for (auto &manager : _graphics_managers)
|
||||||
manager->update(music_offset, note);
|
manager->update(music_offset, note);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
if (element.animations[note->getState()])
|
if (element.animations[note->getState()])
|
||||||
element.animations[note->getState()]->update(music_offset);
|
element.animations[note->getState()]->update(music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SelectionManager<ClassicNote>> EditorContext::getSelectionManager() const
|
std::shared_ptr<SelectionManager<ClassicNote>>
|
||||||
|
EditorContext::getSelectionManager() const
|
||||||
{
|
{
|
||||||
return _selection_manager;
|
return _selection_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorContext::updateGraphics(const kku::microsec& music_offset)
|
void EditorContext::inputUI(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
for (auto& manager : _graphics_managers)
|
for (auto &manager : _graphics_managers)
|
||||||
|
manager->input(std::move(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorContext::updateGraphics(const kku::microsec &music_offset)
|
||||||
|
{
|
||||||
|
for (auto &manager : _graphics_managers)
|
||||||
manager->update(music_offset);
|
manager->update(music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorContext::displayGraphics() const
|
void EditorContext::displayGraphics() const
|
||||||
{
|
{
|
||||||
for (const auto& manager : _graphics_managers)
|
for (const auto &manager : _graphics_managers)
|
||||||
manager->display();
|
manager->display();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const override;
|
virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const override;
|
||||||
virtual void update(ClassicArrowNote *note, const kku::microsec &music_offset) const override;
|
virtual void update(ClassicArrowNote *note, const kku::microsec &music_offset) const override;
|
||||||
|
|
||||||
|
void inputUI(kku::GameEvent&& input);
|
||||||
void updateGraphics(const kku::microsec& music_offset);
|
void updateGraphics(const kku::microsec& music_offset);
|
||||||
void displayGraphics() const;
|
void displayGraphics() const;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class SelectionManager
|
class SelectionManager
|
||||||
|
|
|
@ -2,26 +2,24 @@
|
||||||
#include "classicmode/context.h"
|
#include "classicmode/context.h"
|
||||||
#include "graphics/classicgraphicsmanager.h"
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
|
|
||||||
ClassicArrowNote::ClassicArrowNote(Init&& init) :
|
ClassicArrowNote::ClassicArrowNote(Init &&init)
|
||||||
ClassicNote(init.perfect_offset, init.id),
|
: ClassicNote(init.perfect_offset, init.id),
|
||||||
_evaluator(init.intervals, init.perfect_offset),
|
_evaluator(init.intervals, init.perfect_offset), _context(init.context),
|
||||||
_context(init.context),
|
_is_holding(init.is_holding)
|
||||||
_is_holding(init.is_holding)
|
|
||||||
{
|
{
|
||||||
_elements.resize(init.elements.size());
|
_elements.resize(init.elements.size());
|
||||||
|
|
||||||
for (std::size_t i = 0; i < _elements.size(); ++i)
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
||||||
{
|
{
|
||||||
_elements[i].keys = init.elements[i].keys;
|
_elements[i].keys = init.elements[i].keys;
|
||||||
_elements[i].position = init.elements[i].position;
|
_elements[i].position = init.elements[i].position;
|
||||||
_elements[i].type = init.elements[i].type;
|
_elements[i].type = init.elements[i].type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicArrowNote::isActive(const kku::microsec& offset) const
|
bool ClassicArrowNote::isActive(const kku::microsec &offset) const
|
||||||
{
|
{
|
||||||
return _evaluator.isActive(offset)
|
return _evaluator.isActive(offset) && _state != State::DYING;
|
||||||
&& _state != State::DYING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicArrowNote::update(const kku::microsec &music_offset)
|
void ClassicArrowNote::update(const kku::microsec &music_offset)
|
||||||
|
@ -29,14 +27,15 @@ void ClassicArrowNote::update(const kku::microsec &music_offset)
|
||||||
_context->update(this, music_offset);
|
_context->update(this, music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicArrowNote::input(kku::GameEvent&& input)
|
void ClassicArrowNote::input(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
_context->input(this, std::move(input));
|
_context->input(this, std::move(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicArrowNote::draw(const std::shared_ptr<const ClassicGraphicsManager>& graphics_manager) const
|
void ClassicArrowNote::draw(
|
||||||
|
const std::shared_ptr<const ClassicGraphicsManager> &graphics_manager) const
|
||||||
{
|
{
|
||||||
graphics_manager->draw(_elements);
|
graphics_manager->draw(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicArrowNote::isHold() const
|
bool ClassicArrowNote::isHold() const
|
||||||
|
@ -44,12 +43,18 @@ bool ClassicArrowNote::isHold() const
|
||||||
return _is_holding;
|
return _is_holding;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ArrowElement>& ClassicArrowNote::getElements()
|
std::vector<ArrowElement> &ClassicArrowNote::getElements()
|
||||||
{
|
{
|
||||||
return _elements;
|
return _elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ClassicArrowNote::calculatePrecision(const kku::microsec& offset) const -> Grade
|
const std::vector<ArrowElement> &ClassicArrowNote::getElements() const
|
||||||
|
{
|
||||||
|
return _elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ClassicArrowNote::calculatePrecision(const kku::microsec &offset) const
|
||||||
|
-> Grade
|
||||||
{
|
{
|
||||||
return _evaluator.calculatePrecision(offset);
|
return _evaluator.calculatePrecision(offset);
|
||||||
}
|
}
|
||||||
|
@ -57,8 +62,6 @@ auto ClassicArrowNote::calculatePrecision(const kku::microsec& offset) const ->
|
||||||
bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
|
bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
|
||||||
{
|
{
|
||||||
return std::any_of(_elements.begin(), _elements.end(),
|
return std::any_of(_elements.begin(), _elements.end(),
|
||||||
[key](const auto& element)
|
[key](const auto &element)
|
||||||
{
|
{ return key == element.pressed_as; });
|
||||||
return key == element.pressed_as;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
|
|
||||||
bool isHold() const;
|
bool isHold() const;
|
||||||
std::vector<ArrowElement>& getElements();
|
std::vector<ArrowElement>& getElements();
|
||||||
|
const std::vector<ArrowElement>& getElements() const;
|
||||||
Grade calculatePrecision(const kku::microsec& offset) const;
|
Grade calculatePrecision(const kku::microsec& offset) const;
|
||||||
bool isPressedAs(kku::SystemEvent::Key::Code key) const;
|
bool isPressedAs(kku::SystemEvent::Key::Code key) const;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#include "classicgame.h"
|
#include "classicgame.h"
|
||||||
#include "classicmode/classicnote.h"
|
|
||||||
#include "classicmapcreator.h"
|
#include "classicmapcreator.h"
|
||||||
|
#include "classicmode/classicnote.h"
|
||||||
#include "gamecontext.h"
|
#include "gamecontext.h"
|
||||||
#include "holdmanager.h"
|
|
||||||
#include "graphics/classicgraphicsmanager.h"
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
|
#include "holdmanager.h"
|
||||||
|
|
||||||
ClassicGame::ClassicGame(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
|
ClassicGame::ClassicGame(
|
||||||
const std::shared_ptr<GameContext>& context) :
|
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline,
|
||||||
_timeline(timeline),
|
const std::shared_ptr<GameContext> &context)
|
||||||
_context(context)
|
: _timeline(timeline), _context(context)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ClassicGame::run()
|
void ClassicGame::run()
|
||||||
{
|
{
|
||||||
|
@ -17,7 +18,7 @@ void ClassicGame::run()
|
||||||
_timeline->setNotes(beatmap.notes);
|
_timeline->setNotes(beatmap.notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::input(kku::GameEvent&& input)
|
void ClassicGame::input(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
switch (input.event.type)
|
switch (input.event.type)
|
||||||
{
|
{
|
||||||
|
@ -39,22 +40,24 @@ void ClassicGame::input(kku::GameEvent&& input)
|
||||||
|
|
||||||
case kku::SystemEvent::Type::KeyRelease:
|
case kku::SystemEvent::Type::KeyRelease:
|
||||||
{
|
{
|
||||||
_context->getHoldManager()->checkRelease(std::get<kku::SystemEvent::Key>(input.event.data).view);
|
_context->getHoldManager()->checkRelease(
|
||||||
|
std::get<kku::SystemEvent::Key>(input.event.data).view);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::update(kku::UpdateData&& updatedata)
|
void ClassicGame::update(kku::UpdateData &&updatedata)
|
||||||
{
|
{
|
||||||
// UNCOMMENT TO TEST AUTOPLAY
|
// UNCOMMENT TO TEST AUTOPLAY
|
||||||
/*auto note_it = _timeline->getActiveNote(updatedata.timestamp);
|
/*auto note_it = _timeline->getActiveNote(updatedata.timestamp);
|
||||||
|
|
||||||
if (!_timeline->isExpired(note_it) && updatedata.timestamp >= (*note_it)->getPerfectOffset())
|
if (!_timeline->isExpired(note_it) && updatedata.timestamp >=
|
||||||
|
(*note_it)->getPerfectOffset())
|
||||||
{
|
{
|
||||||
auto note = (*note_it);
|
auto note = (*note_it);
|
||||||
note->input(kku::GameEvent{updatedata.timestamp, kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}});
|
note->input(kku::GameEvent{updatedata.timestamp,
|
||||||
|
kku::SystemEvent{kku::SystemEvent::Type::None, kku::SystemEvent::Key{}}});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
_timeline->update(updatedata.timestamp);
|
_timeline->update(updatedata.timestamp);
|
||||||
|
|
|
@ -3,25 +3,28 @@
|
||||||
#include "gamecontext.h"
|
#include "gamecontext.h"
|
||||||
|
|
||||||
// Replace with interface by dependency injection
|
// Replace with interface by dependency injection
|
||||||
#include "graphics/animations/classicflyinganimationscenario.h"
|
|
||||||
#include "graphics/animations/classicdyinganimationscenario.h"
|
#include "graphics/animations/classicdyinganimationscenario.h"
|
||||||
|
#include "graphics/animations/classicflyinganimationscenario.h"
|
||||||
//
|
//
|
||||||
|
|
||||||
auto classic::createBeatmap(const std::string& filepath, const std::shared_ptr<GameContext>& context) -> Beatmap
|
auto classic::createBeatmap(const std::string &filepath,
|
||||||
|
const std::shared_ptr<GameContext> &context)
|
||||||
|
-> Beatmap
|
||||||
{
|
{
|
||||||
(void) filepath;
|
(void)filepath;
|
||||||
|
|
||||||
kku::microsec starting_beat_offset = 402162;
|
kku::microsec starting_beat_offset = 402162;
|
||||||
int amount_of_beats = 209;
|
int amount_of_beats = 209;
|
||||||
kku::microsec interval = 1412162;
|
kku::microsec interval = 1412162;
|
||||||
kku::microsec tempo_interval = interval / 4;
|
kku::microsec tempo_interval = interval / 4;
|
||||||
kku::microsec note_input_offset = 412162 / 2;
|
kku::microsec note_input_offset = 412162 / 2;
|
||||||
//microsec note_input_offset_fast = 412162 / 6;
|
// microsec note_input_offset_fast = 412162 / 6;
|
||||||
kku::microsec bpm_iterator = starting_beat_offset;
|
kku::microsec bpm_iterator = starting_beat_offset;
|
||||||
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
kku::microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
||||||
|
|
||||||
std::vector<kku::microsec> input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
std::vector<kku::microsec> input_intervals = {
|
||||||
std::set<ClassicNote*, kku::NotePtrComparator> notes;
|
note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
||||||
|
std::set<ClassicNote *, kku::NotePtrComparator> notes;
|
||||||
input_intervals.shrink_to_fit();
|
input_intervals.shrink_to_fit();
|
||||||
|
|
||||||
bpm_iterator += tempo_interval;
|
bpm_iterator += tempo_interval;
|
||||||
|
@ -59,15 +62,8 @@ auto classic::createBeatmap(const std::string& filepath, const std::shared_ptr<G
|
||||||
|
|
||||||
--counter;
|
--counter;
|
||||||
|
|
||||||
ClassicArrowNote::Init init
|
ClassicArrowNote::Init init{
|
||||||
{
|
id++, context, bpm_iterator, input_intervals, {element}, hold};
|
||||||
id++,
|
|
||||||
context,
|
|
||||||
bpm_iterator,
|
|
||||||
input_intervals,
|
|
||||||
{element},
|
|
||||||
hold
|
|
||||||
};
|
|
||||||
|
|
||||||
notes.insert(new ClassicArrowNote(std::move(init)));
|
notes.insert(new ClassicArrowNote(std::move(init)));
|
||||||
|
|
||||||
|
@ -80,4 +76,3 @@ auto classic::createBeatmap(const std::string& filepath, const std::shared_ptr<G
|
||||||
|
|
||||||
return {std::move(notes), note_input_offset * 8};
|
return {std::move(notes), note_input_offset * 8};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,41 +4,43 @@
|
||||||
#include "graphics/animations/classicanimationscenario.h"
|
#include "graphics/animations/classicanimationscenario.h"
|
||||||
#include "graphics/classicgraphicsmanager.h"
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
|
|
||||||
GameContext::GameContext(const std::shared_ptr<HoldManager>& hold_manager,
|
GameContext::GameContext(
|
||||||
const std::shared_ptr<ClassicGraphicsManager>& graphics_manager) :
|
const std::shared_ptr<HoldManager> &hold_manager,
|
||||||
_hold_manager(hold_manager),
|
const std::shared_ptr<ClassicGraphicsManager> &graphics_manager)
|
||||||
_graphics_manager(graphics_manager)
|
: _hold_manager(hold_manager), _graphics_manager(graphics_manager)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void GameContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
|
void GameContext::input(ClassicArrowNote *note, kku::GameEvent &&input) const
|
||||||
{
|
{
|
||||||
auto grade = ClassicArrowNote::Grade::BAD;
|
auto grade = ClassicArrowNote::Grade::BAD;
|
||||||
auto& elements = note->getElements();
|
auto &elements = note->getElements();
|
||||||
|
|
||||||
bool input_valid = std::any_of(elements.begin(), elements.end(),
|
bool input_valid = std::any_of(
|
||||||
[input=input](auto& element)
|
elements.begin(), elements.end(),
|
||||||
{
|
[input = input](auto &element)
|
||||||
if (element.pressed)
|
{
|
||||||
return false;
|
if (element.pressed)
|
||||||
|
return false;
|
||||||
|
|
||||||
const auto code = std::get<kku::SystemEvent::Key>(input.event.data).view;
|
const auto code =
|
||||||
auto key_iterator = std::find(element.keys.begin(), element.keys.end(), code);
|
std::get<kku::SystemEvent::Key>(input.event.data).view;
|
||||||
|
auto key_iterator =
|
||||||
|
std::find(element.keys.begin(), element.keys.end(), code);
|
||||||
|
|
||||||
bool found_key = key_iterator != element.keys.end();
|
bool found_key = key_iterator != element.keys.end();
|
||||||
if (found_key)
|
if (found_key)
|
||||||
{
|
{
|
||||||
element.pressed = true;
|
element.pressed = true;
|
||||||
element.pressed_as = code;
|
element.pressed_as = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found_key;
|
return found_key;
|
||||||
});
|
});
|
||||||
|
|
||||||
bool all_pressed = std::all_of(elements.begin(), elements.end(),
|
bool all_pressed =
|
||||||
[](const auto& element)
|
std::all_of(elements.begin(), elements.end(),
|
||||||
{
|
[](const auto &element) { return element.pressed; });
|
||||||
return element.pressed;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (all_pressed)
|
if (all_pressed)
|
||||||
{
|
{
|
||||||
|
@ -50,20 +52,23 @@ void GameContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
|
||||||
if (all_pressed || !input_valid)
|
if (all_pressed || !input_valid)
|
||||||
{
|
{
|
||||||
note->setState(ClassicArrowNote::State::DYING);
|
note->setState(ClassicArrowNote::State::DYING);
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
element.animations[note->getState()]->launch(element.sprite, input.timestamp, note->getPerfectOffset());
|
element.animations[note->getState()]->launch(
|
||||||
|
element.sprite, input.timestamp, note->getPerfectOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameContext::update(ClassicArrowNote *note, const kku::microsec& music_offset) const
|
void GameContext::update(ClassicArrowNote *note,
|
||||||
|
const kku::microsec &music_offset) const
|
||||||
{
|
{
|
||||||
auto& elements = note->getElements();
|
auto &elements = note->getElements();
|
||||||
|
|
||||||
switch (note->getState())
|
switch (note->getState())
|
||||||
{
|
{
|
||||||
default: return;
|
default:
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClassicArrowNote::State::INITIAL:
|
case ClassicArrowNote::State::INITIAL:
|
||||||
|
@ -72,11 +77,13 @@ void GameContext::update(ClassicArrowNote *note, const kku::microsec& music_offs
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ClassicArrowNote::State::FLYING:
|
case ClassicArrowNote::State::FLYING:
|
||||||
if (!note->isActive(music_offset) && music_offset > note->getPerfectOffset())
|
if (!note->isActive(music_offset) &&
|
||||||
|
music_offset > note->getPerfectOffset())
|
||||||
{
|
{
|
||||||
note->setState(ClassicArrowNote::State::DYING);
|
note->setState(ClassicArrowNote::State::DYING);
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
element.animations[note->getState()]->launch(element.sprite, music_offset, note->getPerfectOffset());
|
element.animations[note->getState()]->launch(
|
||||||
|
element.sprite, music_offset, note->getPerfectOffset());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -86,7 +93,7 @@ void GameContext::update(ClassicArrowNote *note, const kku::microsec& music_offs
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
if (element.animations[note->getState()])
|
if (element.animations[note->getState()])
|
||||||
element.animations[note->getState()]->update(music_offset);
|
element.animations[note->getState()]->update(music_offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "holdmanager.h"
|
#include "holdmanager.h"
|
||||||
#include "classicarrownote.h"
|
#include "classicarrownote.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
void HoldManager::emplace(ClassicArrowNote* note)
|
void HoldManager::emplace(ClassicArrowNote *note)
|
||||||
{
|
{
|
||||||
_notes_on_hold.emplace_back(note);
|
_notes_on_hold.emplace_back(note);
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,8 @@ void HoldManager::emplace(ClassicArrowNote* note)
|
||||||
void HoldManager::checkRelease(kku::SystemEvent::Key::Code released_key)
|
void HoldManager::checkRelease(kku::SystemEvent::Key::Code released_key)
|
||||||
{
|
{
|
||||||
bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(),
|
bool key_match = std::any_of(_notes_on_hold.begin(), _notes_on_hold.end(),
|
||||||
[released_key](const auto& note)
|
[released_key](const auto ¬e)
|
||||||
{
|
{ return note->isPressedAs(released_key); });
|
||||||
return note->isPressedAs(released_key);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (key_match)
|
if (key_match)
|
||||||
_notes_on_hold.clear();
|
_notes_on_hold.clear();
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "classicdyinganimationscenario.h"
|
#include "classicdyinganimationscenario.h"
|
||||||
#include "graphics/classicnotegraphics.h"
|
#include "graphics/classicnotegraphics.h"
|
||||||
|
|
||||||
void ClassicDyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGraphics> sprite, const kku::microsec& time_begin, const kku::microsec &time_end)
|
void ClassicDyingAnimationScenario::launch(
|
||||||
|
const std::shared_ptr<ClassicNoteGraphics> sprite,
|
||||||
|
const kku::microsec &time_begin, const kku::microsec &time_end)
|
||||||
{
|
{
|
||||||
_sprite = sprite;
|
_sprite = sprite;
|
||||||
_time_begin = time_begin;
|
_time_begin = time_begin;
|
||||||
|
@ -12,9 +14,9 @@ void ClassicDyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGrap
|
||||||
_sprite->setTrailPosition(kku::Point{0, 0});
|
_sprite->setTrailPosition(kku::Point{0, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicDyingAnimationScenario::update(const kku::microsec& music_offset)
|
void ClassicDyingAnimationScenario::update(const kku::microsec &music_offset)
|
||||||
{
|
{
|
||||||
(void) music_offset;
|
(void)music_offset;
|
||||||
|
|
||||||
auto fill_color = _sprite->getColor();
|
auto fill_color = _sprite->getColor();
|
||||||
|
|
||||||
|
@ -25,7 +27,8 @@ void ClassicDyingAnimationScenario::update(const kku::microsec& music_offset)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto new_alpha = (int(fill_color.alpha) - 15) < 0 ? 0 : int(fill_color.alpha) - 15;
|
auto new_alpha =
|
||||||
|
(int(fill_color.alpha) - 15) < 0 ? 0 : int(fill_color.alpha) - 15;
|
||||||
fill_color.alpha = new_alpha;
|
fill_color.alpha = new_alpha;
|
||||||
|
|
||||||
_sprite->setColor(fill_color);
|
_sprite->setColor(fill_color);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "classicflyinganimationscenario.h"
|
#include "classicflyinganimationscenario.h"
|
||||||
#include "graphics/classicnotegraphics.h"
|
#include "graphics/classicnotegraphics.h"
|
||||||
|
|
||||||
void ClassicFlyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGraphics> sprite, const kku::microsec& time_begin, const kku::microsec &time_end)
|
void ClassicFlyingAnimationScenario::launch(
|
||||||
|
const std::shared_ptr<ClassicNoteGraphics> sprite,
|
||||||
|
const kku::microsec &time_begin, const kku::microsec &time_end)
|
||||||
{
|
{
|
||||||
_sprite = sprite;
|
_sprite = sprite;
|
||||||
_time_begin = time_begin;
|
_time_begin = time_begin;
|
||||||
|
@ -12,12 +14,13 @@ void ClassicFlyingAnimationScenario::launch(const std::shared_ptr<ClassicNoteGra
|
||||||
_sprite->setTrailColor(_sprite->getColor());
|
_sprite->setTrailColor(_sprite->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
float ClassicFlyingAnimationScenario::getPoint(const kku::Point& point, float perc) const
|
float ClassicFlyingAnimationScenario::getPoint(const kku::Point &point,
|
||||||
|
float perc) const
|
||||||
{
|
{
|
||||||
return point.x + ((point.y - point.x) * perc);
|
return point.x + ((point.y - point.x) * perc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicFlyingAnimationScenario::update(const kku::microsec& music_offset)
|
void ClassicFlyingAnimationScenario::update(const kku::microsec &music_offset)
|
||||||
{
|
{
|
||||||
const auto crd = _sprite->getPosition();
|
const auto crd = _sprite->getPosition();
|
||||||
auto update_time = music_offset - _time_begin;
|
auto update_time = music_offset - _time_begin;
|
||||||
|
@ -28,7 +31,8 @@ void ClassicFlyingAnimationScenario::update(const kku::microsec& music_offset)
|
||||||
float xb = getPoint(kku::Point{crd.x + 90, crd.x}, i);
|
float xb = getPoint(kku::Point{crd.x + 90, crd.x}, i);
|
||||||
float yb = getPoint(kku::Point{crd.y - 150, crd.y}, i);
|
float yb = getPoint(kku::Point{crd.y - 150, crd.y}, i);
|
||||||
|
|
||||||
_sprite->setTrailPosition(kku::Point(getPoint( kku::Point{xa, xb}, i ), getPoint( kku::Point{ya, yb}, i )));
|
_sprite->setTrailPosition(kku::Point(getPoint(kku::Point{xa, xb}, i),
|
||||||
|
getPoint(kku::Point{ya, yb}, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicFlyingAnimationScenario::isDone() const
|
bool ClassicFlyingAnimationScenario::isDone() const
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include "classicgraphicsfactory.h"
|
#include "classicgraphicsfactory.h"
|
||||||
|
|
||||||
ClassicGraphicsFactory::ClassicGraphicsFactory(const std::shared_ptr<kku::CoreFactory>& core_factory) :
|
ClassicGraphicsFactory::ClassicGraphicsFactory(
|
||||||
_core_factory(core_factory)
|
const std::shared_ptr<kku::CoreFactory> &core_factory)
|
||||||
{}
|
: _core_factory(core_factory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
|
auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
|
||||||
{
|
{
|
||||||
|
@ -31,7 +33,7 @@ auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
|
||||||
color = kku::Color{255, 0, 255, 255};
|
color = kku::Color{255, 0, 255, 255};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // yellow
|
default: // yellow
|
||||||
color = kku::Color{255, 239, 0, 255};
|
color = kku::Color{255, 239, 0, 255};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,14 +43,20 @@ auto ClassicGraphicsFactory::generate(Type type) const -> SpriteData
|
||||||
return SpriteData{shape, trail, color};
|
return SpriteData{shape, trail, color};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClassicNoteGraphics> ClassicGraphicsFactory::createSprite(Type type) const
|
std::shared_ptr<ClassicNoteGraphics>
|
||||||
|
ClassicGraphicsFactory::createSprite(Type type) const
|
||||||
{
|
{
|
||||||
const auto data = generate(type);
|
const auto data = generate(type);
|
||||||
return std::make_shared<ClassicNoteGraphics>(ClassicNoteGraphics::Init{data.shape, data.trail, data.color});
|
return std::make_shared<ClassicNoteGraphics>(
|
||||||
|
ClassicNoteGraphics::Init{data.shape, data.trail, data.color});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClassicSelectionGraphics> ClassicGraphicsFactory::createSelection() const
|
std::shared_ptr<ClassicSelectionGraphics>
|
||||||
|
ClassicGraphicsFactory::createSelection() const
|
||||||
{
|
{
|
||||||
const auto shape = _core_factory->getRectangle();
|
const auto shape = _core_factory->getRectangle();
|
||||||
return std::make_shared<ClassicSelectionGraphics>(ClassicSelectionGraphics::Init{shape, kku::Color{51, 153, 255, 120}});
|
return std::make_shared<ClassicSelectionGraphics>(
|
||||||
|
ClassicSelectionGraphics::Init{
|
||||||
|
shape, kku::Color{51, 153, 255, 120}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) = 0;
|
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) = 0;
|
||||||
// virtual void update(const kku::microsec& offset, ClassicSliderNote* note) = 0;
|
// virtual void update(const kku::microsec& offset, ClassicSliderNote* note) = 0;
|
||||||
|
|
||||||
virtual void draw(const std::vector<ArrowElement>& elements) const = 0;
|
virtual void draw(const ClassicArrowNote * const note) const = 0;
|
||||||
// virtual void draw(ClassicSliderNote* note) const = 0;
|
// virtual void draw(ClassicSliderNote* note) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#include "classicnotegraphics.h"
|
#include "classicnotegraphics.h"
|
||||||
|
|
||||||
ClassicNoteGraphics::ClassicNoteGraphics(ClassicNoteGraphics::Init&& init) :
|
ClassicNoteGraphics::ClassicNoteGraphics(ClassicNoteGraphics::Init &&init)
|
||||||
_reset_color(init.color),
|
: _reset_color(init.color), _shape(init.shape), _trail(init.trail)
|
||||||
_shape(init.shape),
|
|
||||||
_trail(init.trail)
|
|
||||||
{
|
{
|
||||||
_shape->setColor(init.color);
|
_shape->setColor(init.color);
|
||||||
_trail->setColor(init.color);
|
_trail->setColor(init.color);
|
||||||
|
@ -18,7 +16,7 @@ void ClassicNoteGraphics::reset()
|
||||||
_trail->setColor(_reset_color);
|
_trail->setColor(_reset_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicNoteGraphics::setPosition(const kku::Point& position)
|
void ClassicNoteGraphics::setPosition(const kku::Point &position)
|
||||||
{
|
{
|
||||||
_shape->setPosition(position);
|
_shape->setPosition(position);
|
||||||
}
|
}
|
||||||
|
@ -38,12 +36,12 @@ kku::Point ClassicNoteGraphics::getTrailPosition() const
|
||||||
return _trail->getPosition();
|
return _trail->getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicNoteGraphics::setColor(const kku::Color& color)
|
void ClassicNoteGraphics::setColor(const kku::Color &color)
|
||||||
{
|
{
|
||||||
_shape->setColor(color);
|
_shape->setColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicNoteGraphics::setTrailColor(const kku::Color& color)
|
void ClassicNoteGraphics::setTrailColor(const kku::Color &color)
|
||||||
{
|
{
|
||||||
_trail->setColor(color);
|
_trail->setColor(color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,20 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
ClassicSceneGraphicsManager::ClassicSceneGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
|
ClassicSceneGraphicsManager::ClassicSceneGraphicsManager(
|
||||||
const std::shared_ptr<ClassicGraphicsFactory>& factory,
|
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline,
|
||||||
const kku::microsec& visibility_offset) :
|
const std::shared_ptr<ClassicGraphicsFactory> &factory,
|
||||||
ClassicGraphicsManager(visibility_offset),
|
const kku::microsec &visibility_offset)
|
||||||
_sprite_container({Type::UP, Type::DOWN,
|
: ClassicGraphicsManager(visibility_offset),
|
||||||
Type::LEFT, Type::RIGHT},
|
_sprite_container({Type::UP, Type::DOWN, Type::LEFT, Type::RIGHT},
|
||||||
factory),
|
factory),
|
||||||
_factory(factory),
|
_factory(factory), _timeline(timeline)
|
||||||
_timeline(timeline)
|
|
||||||
{
|
{
|
||||||
_timeline->expire(_first);
|
_timeline->expire(_first);
|
||||||
_timeline->expire(_last);
|
_timeline->expire(_last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::input(kku::GameEvent&& input)
|
void ClassicSceneGraphicsManager::input(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
return;
|
return;
|
||||||
|
@ -49,14 +48,18 @@ void ClassicSceneGraphicsManager::update(const kku::microsec &offset)
|
||||||
updateVisibleNotes(offset);
|
updateVisibleNotes(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note)
|
void ClassicSceneGraphicsManager::update(const kku::microsec &offset,
|
||||||
|
ClassicArrowNote *note)
|
||||||
{
|
{
|
||||||
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
|
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
|
||||||
|
|
||||||
if (isVisiblyClose(note, offset) && !hasGraphics)
|
if (isVisiblyClose(note, offset) && !hasGraphics)
|
||||||
{
|
{
|
||||||
std::cout << note->getId() << ": set graphics!\n" << std::flush;
|
std::cout << note->getId() << ": set graphics!\n" << std::flush;
|
||||||
setGraphics(note->getElements(), kku::TimeRange{note->getPerfectOffset() - _visibility_offset, note->getPerfectOffset()});
|
setGraphics(
|
||||||
|
note->getElements(),
|
||||||
|
kku::TimeRange{note->getPerfectOffset() - _visibility_offset,
|
||||||
|
note->getPerfectOffset()});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -65,17 +68,18 @@ void ClassicSceneGraphicsManager::update(const kku::microsec& offset, ClassicArr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::draw(const std::vector<ArrowElement>& elements) const
|
void ClassicSceneGraphicsManager::draw(const ClassicArrowNote *const note) const
|
||||||
{
|
{
|
||||||
|
const auto elements = note->getElements();
|
||||||
for (std::size_t i = 0; i < elements.size(); ++i)
|
for (std::size_t i = 0; i < elements.size(); ++i)
|
||||||
{
|
{
|
||||||
const auto& sprite = elements[i].sprite;
|
const auto &sprite = elements[i].sprite;
|
||||||
|
|
||||||
if (i >= 1)
|
if (i >= 1)
|
||||||
{
|
{
|
||||||
//const auto& neighbor_sprite = elements[i - 1].sprite;
|
// const auto& neighbor_sprite = elements[i - 1].sprite;
|
||||||
//const auto c1 = neighbor_sprite->trailPosition();
|
// const auto c1 = neighbor_sprite->trailPosition();
|
||||||
//const auto c2 = sprite->trailPosition();
|
// const auto c2 = sprite->trailPosition();
|
||||||
//_render_target->draw(makeLine(c1, c2));
|
//_render_target->draw(makeLine(c1, c2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,26 +87,31 @@ void ClassicSceneGraphicsManager::draw(const std::vector<ArrowElement>& elements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range)
|
void ClassicSceneGraphicsManager::setGraphics(
|
||||||
|
std::vector<ArrowElement> &elements, kku::TimeRange &&range)
|
||||||
{
|
{
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
{
|
{
|
||||||
element.sprite = _sprite_container.getSprite(element.type);
|
element.sprite = _sprite_container.getSprite(element.type);
|
||||||
element.sprite->setPosition(element.position);
|
element.sprite->setPosition(element.position);
|
||||||
element.sprite->setTrailPosition(kku::Point( 0.f, 9.f ));
|
element.sprite->setTrailPosition(kku::Point(0.f, 9.f));
|
||||||
|
|
||||||
element.animations[ClassicNote::State::NONE] = nullptr;
|
element.animations[ClassicNote::State::NONE] = nullptr;
|
||||||
element.animations[ClassicNote::State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
|
element.animations[ClassicNote::State::FLYING] =
|
||||||
element.animations[ClassicNote::State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
|
std::make_shared<ClassicFlyingAnimationScenario>();
|
||||||
|
element.animations[ClassicNote::State::DYING] =
|
||||||
|
std::make_shared<ClassicDyingAnimationScenario>();
|
||||||
element.animations[ClassicNote::State::DEAD] = nullptr;
|
element.animations[ClassicNote::State::DEAD] = nullptr;
|
||||||
|
|
||||||
element.animations[ClassicNote::State::FLYING]->launch(element.sprite, range.begin, range.end);
|
element.animations[ClassicNote::State::FLYING]->launch(
|
||||||
|
element.sprite, range.begin, range.end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::removeGraphics(std::vector<ArrowElement>& elements)
|
void ClassicSceneGraphicsManager::removeGraphics(
|
||||||
|
std::vector<ArrowElement> &elements)
|
||||||
{
|
{
|
||||||
for (auto& element : elements)
|
for (auto &element : elements)
|
||||||
{
|
{
|
||||||
_sprite_container.resetSprite(element.sprite, element.type);
|
_sprite_container.resetSprite(element.sprite, element.type);
|
||||||
element.sprite = nullptr;
|
element.sprite = nullptr;
|
||||||
|
@ -116,16 +125,17 @@ void ClassicSceneGraphicsManager::removeGraphics(std::vector<ArrowElement>& elem
|
||||||
|
|
||||||
bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept
|
bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept
|
||||||
{
|
{
|
||||||
return _timeline->isExpired(_first)
|
return _timeline->isExpired(_first) || _timeline->isExpired(_last);
|
||||||
|| _timeline->isExpired(_last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicSceneGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept
|
bool ClassicSceneGraphicsManager::isVisiblyClose(
|
||||||
|
const ClassicNote *const note,
|
||||||
|
const kku::microsec &music_offset) const noexcept
|
||||||
{
|
{
|
||||||
return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
|
return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
return;
|
return;
|
||||||
|
@ -133,7 +143,8 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
||||||
if (offset < (*_first)->getPerfectOffset())
|
if (offset < (*_first)->getPerfectOffset())
|
||||||
{
|
{
|
||||||
Iterator note_iterator = _first;
|
Iterator note_iterator = _first;
|
||||||
while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset))
|
while (note_iterator != _timeline->begin() &&
|
||||||
|
isVisiblyClose(*note_iterator, offset))
|
||||||
{
|
{
|
||||||
--note_iterator;
|
--note_iterator;
|
||||||
}
|
}
|
||||||
|
@ -142,10 +153,10 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
||||||
|
|
||||||
auto note = *_first;
|
auto note = *_first;
|
||||||
const auto state = note->getState();
|
const auto state = note->getState();
|
||||||
if (state != ClassicNote::State::FLYING
|
if (state != ClassicNote::State::FLYING &&
|
||||||
&& state != ClassicNote::State::DYING
|
state != ClassicNote::State::DYING &&
|
||||||
&& state != ClassicNote::State::INITIAL
|
state != ClassicNote::State::INITIAL &&
|
||||||
&& offset <= note->getPerfectOffset())
|
offset <= note->getPerfectOffset())
|
||||||
{
|
{
|
||||||
note->setState(ClassicNote::State::INITIAL);
|
note->setState(ClassicNote::State::INITIAL);
|
||||||
}
|
}
|
||||||
|
@ -158,7 +169,7 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
||||||
auto note = *note_iterator;
|
auto note = *note_iterator;
|
||||||
if (note->getState() == ClassicNote::State::DEAD)
|
if (note->getState() == ClassicNote::State::DEAD)
|
||||||
{
|
{
|
||||||
// note->removeGraphics(this);
|
// note->removeGraphics(this);
|
||||||
++_first;
|
++_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,20 +178,21 @@ void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec& offset)
|
void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
Iterator note_iterator = _timeline->getTopNote();
|
Iterator note_iterator = _timeline->getTopNote();
|
||||||
while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset))
|
while (!_timeline->isExpired(note_iterator) &&
|
||||||
|
isVisiblyClose(*note_iterator, offset))
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
_first = note_iterator;
|
_first = note_iterator;
|
||||||
|
|
||||||
auto note = *note_iterator;
|
auto note = *note_iterator;
|
||||||
const auto state = note->getState();
|
const auto state = note->getState();
|
||||||
if (state != ClassicNote::State::FLYING
|
if (state != ClassicNote::State::FLYING &&
|
||||||
&& state != ClassicNote::State::DYING
|
state != ClassicNote::State::DYING &&
|
||||||
&& state != ClassicNote::State::INITIAL
|
state != ClassicNote::State::INITIAL &&
|
||||||
&& offset <= note->getPerfectOffset())
|
offset <= note->getPerfectOffset())
|
||||||
{
|
{
|
||||||
note->setState(ClassicNote::State::INITIAL);
|
note->setState(ClassicNote::State::INITIAL);
|
||||||
}
|
}
|
||||||
|
@ -191,7 +203,8 @@ void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec& offset)
|
||||||
_last = note_iterator;
|
_last = note_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSceneGraphicsManager::updateVisibleNotes(const kku::microsec& offset)
|
void ClassicSceneGraphicsManager::updateVisibleNotes(
|
||||||
|
const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
for (auto it = _first; it != _last; ++it)
|
for (auto it = _first; it != _last; ++it)
|
||||||
(*it)->update(offset);
|
(*it)->update(offset);
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual void update(const kku::microsec& offset) override;
|
virtual void update(const kku::microsec& offset) override;
|
||||||
|
|
||||||
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
|
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
|
||||||
virtual void draw(const std::vector<ArrowElement>& elements) const override;
|
virtual void draw(const ClassicArrowNote * const note) const override;
|
||||||
|
|
||||||
void setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range);
|
void setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range);
|
||||||
void removeGraphics(std::vector<ArrowElement>& elements);
|
void removeGraphics(std::vector<ArrowElement>& elements);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "classicselectiongraphics.h"
|
#include "classicselectiongraphics.h"
|
||||||
#include "classicnotegraphics.h"
|
#include "classicnotegraphics.h"
|
||||||
|
|
||||||
ClassicSelectionGraphics::ClassicSelectionGraphics(ClassicSelectionGraphics::Init&& init) :
|
ClassicSelectionGraphics::ClassicSelectionGraphics(
|
||||||
_fill_color(init.color),
|
ClassicSelectionGraphics::Init &&init)
|
||||||
_shape(init.shape)
|
: _fill_color(init.color), _shape(init.shape)
|
||||||
{
|
{
|
||||||
_shape->setColor(init.color);
|
_shape->setColor(init.color);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ void ClassicSelectionGraphics::display() const
|
||||||
_shape->display();
|
_shape->display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSelectionGraphics::adjustTo(const std::shared_ptr<ClassicNoteGraphics>& sprite)
|
void ClassicSelectionGraphics::adjustTo(
|
||||||
|
const std::shared_ptr<ClassicNoteGraphics> &sprite)
|
||||||
{
|
{
|
||||||
_shape->setRect(sprite->getRectangle()->getRect());
|
_shape->setRect(sprite->getRectangle()->getRect());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,53 +3,72 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
|
ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(
|
||||||
const std::shared_ptr<ClassicGraphicsFactory>& factory,
|
const std::shared_ptr<kku::Timeline<ClassicNote>> &timeline,
|
||||||
const kku::microsec& visibility_offset) :
|
const std::shared_ptr<ClassicGraphicsFactory> &factory,
|
||||||
ClassicGraphicsManager(visibility_offset),
|
const kku::microsec &visibility_offset)
|
||||||
_sprite_container({Type::UP, Type::DOWN,
|
: ClassicGraphicsManager(visibility_offset),
|
||||||
Type::LEFT, Type::RIGHT},
|
_sprite_container({Type::UP, Type::DOWN, Type::LEFT, Type::RIGHT},
|
||||||
factory),
|
factory),
|
||||||
_factory(factory),
|
_factory(factory), _timeline(timeline),
|
||||||
_timeline(timeline)
|
_back_visibility_offset(static_cast<double>(visibility_offset) / 4.f),
|
||||||
|
_last_offset(0)
|
||||||
{
|
{
|
||||||
_timeline->expire(_first);
|
_timeline->expire(_first);
|
||||||
_timeline->expire(_last);
|
_timeline->expire(_last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::input(kku::GameEvent&& input)
|
void ClassicTimelineGraphicsManager::input(kku::GameEvent &&input)
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
switch (input.event.type)
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto it = _first; it != _last; ++it)
|
|
||||||
{
|
{
|
||||||
(*it)->input(std::move(input));
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kku::SystemEvent::Type::KeyPress:
|
||||||
|
{
|
||||||
|
const auto key_data = std::get<kku::SystemEvent::Key>(input.event.data);
|
||||||
|
if (key_data.view == kku::SystemEvent::Key::Code::Add)
|
||||||
|
{
|
||||||
|
_visibility_offset += 200000;
|
||||||
|
_back_visibility_offset =
|
||||||
|
static_cast<double>(_visibility_offset) / 4.f;
|
||||||
|
}
|
||||||
|
else if (key_data.view == kku::SystemEvent::Key::Code::Subtract)
|
||||||
|
{
|
||||||
|
_visibility_offset -= 200000;
|
||||||
|
_back_visibility_offset =
|
||||||
|
static_cast<double>(_visibility_offset) / 4.f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::display() const
|
void ClassicTimelineGraphicsManager::display() const
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
// if (nothingToDraw())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
|
std::cout << "displaying on tl: ";
|
||||||
for (auto it = _first; it != _last; ++it)
|
for (auto it = _first; it != _last; ++it)
|
||||||
{
|
{
|
||||||
const auto note = *it;
|
std::cout << (*it)->getId() << " ";
|
||||||
if (note->getState() != ClassicNote::State::DEAD)
|
(*it)->draw(shared_from_this());
|
||||||
note->draw(shared_from_this());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "\n" << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::update(const kku::microsec &offset)
|
void ClassicTimelineGraphicsManager::update(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
|
_last_offset = offset;
|
||||||
fetchLastNote(offset);
|
fetchLastNote(offset);
|
||||||
fetchFirstNote(offset);
|
fetchFirstNote(offset);
|
||||||
|
|
||||||
updateVisibleNotes(offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note)
|
void ClassicTimelineGraphicsManager::update(const kku::microsec &offset,
|
||||||
|
ClassicArrowNote *note)
|
||||||
{
|
{
|
||||||
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
|
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
|
||||||
|
|
||||||
|
@ -63,103 +82,72 @@ void ClassicTimelineGraphicsManager::update(const kku::microsec& offset, Classic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::draw(const std::vector<ArrowElement>& elements) const
|
void ClassicTimelineGraphicsManager::draw(
|
||||||
|
const ClassicArrowNote *const note) const
|
||||||
{
|
{
|
||||||
|
const double d_visibility_offset =
|
||||||
|
static_cast<double>(_last_offset + _visibility_offset);
|
||||||
|
const double d_back_visibility_offset =
|
||||||
|
static_cast<double>(_last_offset - _back_visibility_offset);
|
||||||
|
|
||||||
|
const double span = d_visibility_offset - d_back_visibility_offset;
|
||||||
|
const double note_span =
|
||||||
|
static_cast<double>(note->getPerfectOffset()) - d_visibility_offset;
|
||||||
|
|
||||||
|
const double percent = note_span / (span / 100.f);
|
||||||
|
|
||||||
|
const auto elements = note->getElements();
|
||||||
for (std::size_t i = 0; i < elements.size(); ++i)
|
for (std::size_t i = 0; i < elements.size(); ++i)
|
||||||
{
|
{
|
||||||
const auto& sprite = elements[i].sprite;
|
auto timeline_sprite = _factory->createSprite(elements[i].type);
|
||||||
|
timeline_sprite->setPosition(
|
||||||
|
kku::Point{static_cast<int>(850 + 1280.f / 100.f * percent), 700});
|
||||||
|
|
||||||
if (i >= 1)
|
timeline_sprite->display();
|
||||||
{
|
|
||||||
//const auto& neighbor_sprite = elements[i - 1].sprite;
|
|
||||||
//const auto c1 = neighbor_sprite->trailPosition();
|
|
||||||
//const auto c2 = sprite->trailPosition();
|
|
||||||
//_render_target->draw(makeLine(c1, c2));
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite->display();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept
|
bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept
|
||||||
{
|
{
|
||||||
return _timeline->isExpired(_first)
|
return _timeline->isExpired(_first) || _timeline->isExpired(_last);
|
||||||
|| _timeline->isExpired(_last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicTimelineGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept
|
bool ClassicTimelineGraphicsManager::isVisiblyClose(
|
||||||
|
const ClassicNote *const note,
|
||||||
|
const kku::microsec &music_offset) const noexcept
|
||||||
{
|
{
|
||||||
return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
|
const auto &perfect_offset = note->getPerfectOffset();
|
||||||
|
|
||||||
|
return ((perfect_offset - _visibility_offset) <= music_offset) ||
|
||||||
|
((perfect_offset + (_visibility_offset / 4.)) >= music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec& offset)
|
void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
// if (nothingToDraw())
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (offset < (*_first)->getPerfectOffset())
|
Iterator note_iterator = _first;
|
||||||
|
while (note_iterator != _timeline->begin() &&
|
||||||
|
isVisiblyClose(*note_iterator, offset))
|
||||||
{
|
{
|
||||||
Iterator note_iterator = _first;
|
--note_iterator;
|
||||||
while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset))
|
|
||||||
{
|
|
||||||
--note_iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
_first = note_iterator;
|
|
||||||
|
|
||||||
auto note = *_first;
|
|
||||||
const auto state = note->getState();
|
|
||||||
if (state != ClassicNote::State::FLYING
|
|
||||||
&& state != ClassicNote::State::DYING
|
|
||||||
&& state != ClassicNote::State::INITIAL
|
|
||||||
&& offset <= note->getPerfectOffset())
|
|
||||||
{
|
|
||||||
note->setState(ClassicNote::State::INITIAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Iterator note_iterator = _first;
|
|
||||||
while (note_iterator != _last)
|
|
||||||
{
|
|
||||||
auto note = *note_iterator;
|
|
||||||
if (note->getState() == ClassicNote::State::DEAD)
|
|
||||||
{
|
|
||||||
// note->removeGraphics(this);
|
|
||||||
++_first;
|
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
_first = note_iterator;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec& offset)
|
void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
Iterator note_iterator = _timeline->getTopNote();
|
Iterator note_iterator = _timeline->getTopNote();
|
||||||
while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset))
|
while (!_timeline->isExpired(note_iterator) &&
|
||||||
|
isVisiblyClose(*note_iterator, offset))
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
_first = note_iterator;
|
_first = note_iterator;
|
||||||
|
|
||||||
auto note = *note_iterator;
|
|
||||||
const auto state = note->getState();
|
|
||||||
if (state != ClassicNote::State::FLYING
|
|
||||||
&& state != ClassicNote::State::DYING
|
|
||||||
&& state != ClassicNote::State::INITIAL
|
|
||||||
&& offset <= note->getPerfectOffset())
|
|
||||||
{
|
|
||||||
note->setState(ClassicNote::State::INITIAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
++note_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
_last = note_iterator;
|
_last = note_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimelineGraphicsManager::updateVisibleNotes(const kku::microsec& offset)
|
|
||||||
{
|
|
||||||
for (auto it = _first; it != _last; ++it)
|
|
||||||
(*it)->update(offset);
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual void update(const kku::microsec& offset) override;
|
virtual void update(const kku::microsec& offset) override;
|
||||||
|
|
||||||
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
|
virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override;
|
||||||
virtual void draw(const std::vector<ArrowElement>& elements) const override;
|
virtual void draw(const ClassicArrowNote * const note) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container;
|
kku::SpriteContainer<Type, ClassicGraphicsFactory, ClassicNoteGraphics> _sprite_container;
|
||||||
|
@ -35,10 +35,11 @@ protected:
|
||||||
Iterator _last;
|
Iterator _last;
|
||||||
|
|
||||||
const std::shared_ptr<kku::Timeline<ClassicNote>> _timeline;
|
const std::shared_ptr<kku::Timeline<ClassicNote>> _timeline;
|
||||||
|
kku::microsec _back_visibility_offset;
|
||||||
|
kku::microsec _last_offset;
|
||||||
|
|
||||||
inline bool nothingToDraw() const noexcept;
|
inline bool nothingToDraw() const noexcept;
|
||||||
inline bool isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept;
|
inline bool isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept;
|
||||||
void fetchFirstNote(const kku::microsec& offset);
|
void fetchFirstNote(const kku::microsec& offset);
|
||||||
void fetchLastNote(const kku::microsec& offset);
|
void fetchLastNote(const kku::microsec& offset);
|
||||||
void updateVisibleNotes(const kku::microsec& offset);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
#include "tools/beatutils.h"
|
#include "tools/beatutils.h"
|
||||||
#include <numeric>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
auto beat_utils::calculateBeatRateInfo(const std::vector<kku::microsec>& approximate_deltas) -> BeatInfo
|
auto beat_utils::calculateBeatRateInfo(
|
||||||
|
const std::vector<kku::microsec> &approximate_deltas) -> BeatInfo
|
||||||
{
|
{
|
||||||
if (approximate_deltas.empty())
|
if (approximate_deltas.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const long double sum = std::accumulate(approximate_deltas.begin(), approximate_deltas.end(), 0);
|
const long double sum = std::accumulate(approximate_deltas.begin(),
|
||||||
|
approximate_deltas.end(), 0);
|
||||||
const long double amount = approximate_deltas.size();
|
const long double amount = approximate_deltas.size();
|
||||||
|
|
||||||
long double average = sum / amount;
|
long double average = sum / amount;
|
||||||
|
|
||||||
const int bpm = static_cast<int>(60000000. / average);
|
const int bpm = static_cast<int>(60000000. / average);
|
||||||
|
|
||||||
|
return BeatInfo{bpm, static_cast<kku::microsec>(
|
||||||
return BeatInfo
|
1. / static_cast<long double>(bpm) * 60000000.)};
|
||||||
{
|
|
||||||
bpm,
|
|
||||||
static_cast<kku::microsec>(1. / static_cast<long double>(bpm) * 60000000.)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "tools/bpmcalculator.h"
|
#include "tools/bpmcalculator.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <numeric>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
BPMCalculator::BPMCalculator()
|
BPMCalculator::BPMCalculator()
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ void BPMCalculator::click(const kku::microsec &offset)
|
||||||
_previous_click_offset = offset;
|
_previous_click_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const beat_utils::BeatInfo& BPMCalculator::fetchApproximatedInfo()
|
const beat_utils::BeatInfo &BPMCalculator::fetchApproximatedInfo()
|
||||||
{
|
{
|
||||||
if (!_need_recalculate)
|
if (!_need_recalculate)
|
||||||
return _approximated_info;
|
return _approximated_info;
|
||||||
|
@ -65,8 +65,8 @@ const beat_utils::BeatInfo& BPMCalculator::fetchApproximatedInfo()
|
||||||
bool hasEnoughDeltas = _deltas.size() >= 8;
|
bool hasEnoughDeltas = _deltas.size() >= 8;
|
||||||
|
|
||||||
_approximated_info = (!hasEnoughDeltas)
|
_approximated_info = (!hasEnoughDeltas)
|
||||||
? beat_utils::BeatInfo{}
|
? beat_utils::BeatInfo{}
|
||||||
: beat_utils::calculateBeatRateInfo(_deltas);
|
: beat_utils::calculateBeatRateInfo(_deltas);
|
||||||
|
|
||||||
return _approximated_info;
|
return _approximated_info;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ void BPMCalculator::moveStartingOffsetBy(kku::microsec shift)
|
||||||
_first_click_offset += shift;
|
_first_click_offset += shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
kku::microsec BPMCalculator::fetchTimeUntilNextBeat(const kku::microsec& offset)
|
kku::microsec BPMCalculator::fetchTimeUntilNextBeat(const kku::microsec &offset)
|
||||||
{
|
{
|
||||||
const kku::microsec actual_offset = offset - getStartingOffset();
|
const kku::microsec actual_offset = offset - getStartingOffset();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue