mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2024-11-14 11:07:44 +01:00
Non tested notes drawing code
This commit is contained in:
parent
438fa00558
commit
3dbfc2820c
@ -19,4 +19,8 @@ void Chart::setResolution(int resolution) {
|
||||
Chart::Chart(const std::string &dif, int level, int resolution) : dif_name(dif),
|
||||
level(level),
|
||||
resolution(resolution),
|
||||
Notes() {}
|
||||
Notes() {
|
||||
if (resolution <= 0) {
|
||||
throw std::invalid_argument("Can't set a resolution of "+std::to_string(resolution));
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "tinyfiledialogs.h"
|
||||
#include "Toolbox.h"
|
||||
|
||||
EditorState::EditorState(Fumen &fumen) : fumen(fumen) {
|
||||
EditorState::EditorState(Fumen &fumen) : fumen(fumen), markerEndingState(MISS) {
|
||||
reloadFromFumen();
|
||||
}
|
||||
|
||||
@ -80,6 +80,42 @@ void EditorState::reloadJacket() {
|
||||
}
|
||||
|
||||
void EditorState::displayPlayfield() {
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(400,400),ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0,0),ImVec2(FLT_MAX,FLT_MAX),Toolbox::CustomConstraints::ContentSquare);
|
||||
if (ImGui::Begin("Playfield",&showPlayfield,ImGuiWindowFlags_NoScrollbar)) {
|
||||
float squareSize = ImGui::GetWindowSize().x / 4.f;
|
||||
float TitlebarHeight = ImGui::GetWindowSize().y - ImGui::GetWindowSize().x;
|
||||
if (selectedChart) {
|
||||
int ImGuiIndex = 0;
|
||||
for (auto note : getVisibleNotes()) {
|
||||
std::optional<sf::Texture> t;
|
||||
if ((t = playfield.marker.getSprite(playfield.markerEndingState,getSecondsAt(note.getTiming())))) {
|
||||
int x = note.getPos()%4;
|
||||
int y = note.getPos()/4;
|
||||
ImGui::SetCursorPos({x*squareSize,TitlebarHeight + y*squareSize});
|
||||
ImGui::PushID(ImGuiIndex);
|
||||
ImGui::Image(*t,{squareSize,squareSize});
|
||||
ImGui::PopID();
|
||||
}
|
||||
++ImGuiIndex;
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
ImGui::PushID(x+4*y);
|
||||
ImGui::SetCursorPos({x*squareSize,TitlebarHeight + y*squareSize});
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0,0,0,0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(0,0,1.f,0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(0,0,1.f,0.5f));
|
||||
ImGui::ImageButton(playfield.button,{squareSize,squareSize},0);
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -135,6 +171,8 @@ void EditorState::displayStatus() {
|
||||
ImGui::TextColored(ImVec4(1,0.42,0.41,1),"No jacket loaded");
|
||||
}
|
||||
}
|
||||
ImGui::Checkbox("Beat Tick",&playBeatTick);
|
||||
ImGui::Checkbox("Note Tick",&playNoteTick);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@ -224,6 +262,36 @@ void EditorState::displayTimeline() {
|
||||
ImGui::PopStyleVar(3);
|
||||
}
|
||||
|
||||
std::vector<Note> EditorState::getVisibleNotes() {
|
||||
if (selectedChart) {
|
||||
|
||||
std::vector<Note> visibleNotes;
|
||||
|
||||
float minPos;
|
||||
if (this->markerEndingState == MISS) {
|
||||
minPos = playbackPosition.asSeconds() - 8.f/30.f;
|
||||
} else {
|
||||
minPos = playbackPosition.asSeconds() - 16.f/30.f;
|
||||
}
|
||||
|
||||
float maxPos = playbackPosition.asSeconds() + 16.f/30.f;
|
||||
|
||||
int min_exclusive = static_cast<int>(getTicksAt(minPos));
|
||||
int max_exclusive = static_cast<int>(getTicksAt(maxPos));
|
||||
|
||||
for (auto note : selectedChart->Notes) {
|
||||
if (note.getTiming() > min_exclusive and note.getTiming() < max_exclusive) {
|
||||
visibleNotes.push_back(note);
|
||||
}
|
||||
}
|
||||
|
||||
return visibleNotes;
|
||||
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void ESHelper::save(EditorState& ed) {
|
||||
try {
|
||||
ed.fumen.autoSaveAsMemon();
|
||||
|
@ -10,12 +10,14 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "Fumen.h"
|
||||
#include "Marker.h"
|
||||
#include "Widgets.h"
|
||||
|
||||
class EditorState {
|
||||
|
||||
public:
|
||||
Fumen fumen;
|
||||
Marker marker;
|
||||
Widgets::Playfield playfield;
|
||||
MarkerEndingState markerEndingState;
|
||||
std::optional<sf::Music> music;
|
||||
std::optional<sf::Texture> jacket;
|
||||
std::optional<Chart> selectedChart;
|
||||
@ -23,7 +25,23 @@ public:
|
||||
sf::Time playbackPosition;
|
||||
sf::Time chartRuntime; // Timing at which the playback stops
|
||||
bool playing;
|
||||
float getBeats() {return ((playbackPosition.asSeconds()+fumen.offset)/60.f)* fumen.BPM;};
|
||||
float getBeats() {return getBeatsAt(playbackPosition.asSeconds());};
|
||||
float getBeatsAt(float seconds) {return ((seconds+fumen.offset)/60.f)* fumen.BPM;};
|
||||
float getTicks() {return getTicksAt(playbackPosition.asSeconds());};
|
||||
float getTicksAt(float seconds) {
|
||||
if (selectedChart) {
|
||||
return getBeatsAt(seconds)*selectedChart->getResolution();
|
||||
} else {
|
||||
return getBeatsAt(seconds)*240.f;
|
||||
}
|
||||
}
|
||||
float getSecondsAt(int tick) {
|
||||
if (selectedChart) {
|
||||
return (60.f * tick)/(fumen.BPM * selectedChart->getResolution()) - fumen.offset;
|
||||
} else {
|
||||
return (60.f * tick)/(fumen.BPM * 240.f) - fumen.offset;
|
||||
}
|
||||
}
|
||||
|
||||
void reloadFromFumen();
|
||||
void reloadMusic();
|
||||
@ -42,6 +60,11 @@ public:
|
||||
void displayPlaybackStatus();
|
||||
void displayTimeline();
|
||||
|
||||
bool playBeatTick;
|
||||
bool playNoteTick;
|
||||
|
||||
std::vector<Note> getVisibleNotes();
|
||||
|
||||
explicit EditorState(Fumen& fumen);
|
||||
};
|
||||
|
||||
|
48
Marker.cpp
48
Marker.cpp
@ -2,6 +2,9 @@
|
||||
// Created by Syméon on 17/08/2017.
|
||||
//
|
||||
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "Marker.h"
|
||||
|
||||
Marker::Marker(std::string folder) {
|
||||
@ -41,11 +44,48 @@ Marker::Marker(std::string folder) {
|
||||
}
|
||||
}
|
||||
|
||||
sf::Texture Marker::getSprite(Etat etat, int frame) {
|
||||
std::optional<sf::Texture> Marker::getSprite(MarkerEndingState state, float seconds) {
|
||||
std::ostringstream frameName;
|
||||
int frame = static_cast<int>((seconds*30.f+16.f));
|
||||
if (frame >= 0 and frame <= 15) {
|
||||
frameName << "ma" << std::setfill('0') << std::setw(2) << frame;
|
||||
return textures[frameName.str()];
|
||||
} else {
|
||||
if (state == MISS) {
|
||||
if (frame >= 16 and frame <= 23) {
|
||||
frameName << "ma" << std::setfill('0') << std::setw(2) << frame;
|
||||
return textures[frameName.str()];
|
||||
}
|
||||
} else if (frame >= 16 and frame <= 32) {
|
||||
switch (state) {
|
||||
case EARLY:
|
||||
frameName << "h1";
|
||||
break;
|
||||
case GOOD:
|
||||
frameName << "h2";
|
||||
break;
|
||||
case GREAT:
|
||||
frameName << "h3";
|
||||
break;
|
||||
case PERFECT:
|
||||
frameName << "h4";
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
frameName << std::setfill('0') << std::setw(2) << frame-16;
|
||||
return textures[frameName.str()];
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/*
|
||||
sf::Texture Marker::getSprite(MarkerEndingState state, int frame) {
|
||||
|
||||
int lower;
|
||||
int upper;
|
||||
switch(etat) {
|
||||
switch(state) {
|
||||
case MISS:
|
||||
lower = 16;
|
||||
upper = 32;
|
||||
@ -61,8 +101,7 @@ sf::Texture Marker::getSprite(Etat etat, int frame) {
|
||||
}
|
||||
|
||||
std::string tex_key;
|
||||
switch (etat) {
|
||||
case APPROCHE:
|
||||
switch (state) {
|
||||
case MISS:
|
||||
tex_key += "ma";
|
||||
break;
|
||||
@ -86,3 +125,4 @@ sf::Texture Marker::getSprite(Etat etat, int frame) {
|
||||
return textures[tex_key+std::to_string(frame)];
|
||||
|
||||
}
|
||||
*/
|
||||
|
5
Marker.h
5
Marker.h
@ -11,8 +11,7 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <map>
|
||||
|
||||
enum Etat {
|
||||
APPROCHE,
|
||||
enum MarkerEndingState {
|
||||
MISS,
|
||||
EARLY,
|
||||
GOOD,
|
||||
@ -25,7 +24,7 @@ class Marker {
|
||||
public:
|
||||
|
||||
Marker(std::string folder = "mk0013");
|
||||
sf::Texture getSprite(Etat etat, int frame);
|
||||
std::optional<sf::Texture> getSprite(MarkerEndingState state, float seconds);
|
||||
|
||||
private:
|
||||
|
||||
|
32
Widgets.cpp
32
Widgets.cpp
@ -5,7 +5,7 @@
|
||||
#include "Widgets.h"
|
||||
#include "Toolbox.h"
|
||||
|
||||
Ecran_attente::Ecran_attente() : gris_de_fond(sf::Color(38,38,38)) {
|
||||
Widgets::Ecran_attente::Ecran_attente() : gris_de_fond(sf::Color(38,38,38)) {
|
||||
|
||||
if(!tex_FEIS_logo.loadFromFile("assets/textures/FEIS_logo.png"))
|
||||
{
|
||||
@ -17,7 +17,7 @@ Ecran_attente::Ecran_attente() : gris_de_fond(sf::Color(38,38,38)) {
|
||||
|
||||
}
|
||||
|
||||
void Ecran_attente::render(sf::RenderWindow& window) {
|
||||
void Widgets::Ecran_attente::render(sf::RenderWindow& window) {
|
||||
// effacement de la fenêtre en noir
|
||||
window.clear(gris_de_fond);
|
||||
|
||||
@ -27,9 +27,7 @@ void Ecran_attente::render(sf::RenderWindow& window) {
|
||||
window.draw(FEIS_logo);
|
||||
}
|
||||
|
||||
Playfield::Playfield() {
|
||||
|
||||
marker = Marker();
|
||||
Widgets::Playfield::Playfield() {
|
||||
if (!button.loadFromFile(button_path,{0,0,192,192})) {
|
||||
std::cerr << "Unable to load texture " << button_path;
|
||||
throw std::runtime_error("Unable to load texture " + button_path);
|
||||
@ -39,27 +37,3 @@ Playfield::Playfield() {
|
||||
throw std::runtime_error("Unable to load texture " + button_path);
|
||||
}
|
||||
}
|
||||
|
||||
void Playfield::render(sf::RenderWindow &window, EditorState& editorState) {
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(400,400),ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0,0),ImVec2(FLT_MAX,FLT_MAX),Toolbox::CustomConstraints::ContentSquare);
|
||||
ImGui::Begin("Playfield",&editorState.showPlayfield,ImGuiWindowFlags_NoScrollbar);
|
||||
{
|
||||
float squareSize = ImGui::GetWindowSize().x / 4.f;
|
||||
float TitlebarHeight = ImGui::GetWindowSize().y - ImGui::GetWindowSize().x;
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
ImGui::PushID(x+4*y);
|
||||
ImGui::SetCursorPos({x*squareSize,TitlebarHeight + y*squareSize});
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0,0,0,0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(0,0,1.f,0.1f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(0,0,1.f,0.5f));
|
||||
ImGui::ImageButton(button,{squareSize,squareSize},0);
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
46
Widgets.h
46
Widgets.h
@ -2,43 +2,41 @@
|
||||
// Created by Syméon on 17/08/2017.
|
||||
//
|
||||
|
||||
#ifndef FEIS_SCREEN_H
|
||||
#define FEIS_SCREEN_H
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <imgui.h>
|
||||
#include <imgui-SFML.h>
|
||||
#include "Marker.h"
|
||||
#include "EditorState.h"
|
||||
|
||||
class Ecran_attente {
|
||||
namespace Widgets {
|
||||
class Ecran_attente {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
Ecran_attente();
|
||||
void render(sf::RenderWindow &window);
|
||||
Ecran_attente();
|
||||
void render(sf::RenderWindow &window);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
sf::Color gris_de_fond;
|
||||
sf::Texture tex_FEIS_logo;
|
||||
sf::Sprite FEIS_logo;
|
||||
sf::Color gris_de_fond;
|
||||
sf::Texture tex_FEIS_logo;
|
||||
sf::Sprite FEIS_logo;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class Playfield {
|
||||
class Playfield {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
Playfield();
|
||||
void render(sf::RenderWindow &window, EditorState& editorState);
|
||||
Playfield();
|
||||
|
||||
Marker marker;
|
||||
sf::Texture button;
|
||||
sf::Texture button_pressed;
|
||||
Marker marker;
|
||||
MarkerEndingState markerEndingState;
|
||||
sf::Texture button;
|
||||
sf::Texture button_pressed;
|
||||
|
||||
private:
|
||||
std::string button_path = "assets/textures/edit_textures/game_front_edit_tex_1.tex.png";
|
||||
};
|
||||
|
||||
#endif //FEIS_SCREEN_H
|
||||
private:
|
||||
std::string button_path = "assets/textures/edit_textures/game_front_edit_tex_1.tex.png";
|
||||
};
|
||||
}
|
||||
|
75
main.cpp
75
main.cpp
@ -22,9 +22,25 @@ int main(int argc, char** argv) {
|
||||
IO.Fonts->AddFontFromFileTTF("assets/fonts/NotoSans-Medium.ttf", 16.f);
|
||||
ImGui::SFML::UpdateFontTexture();
|
||||
|
||||
std::string noteTickPath = "assets/sounds/sound note tick.wav";
|
||||
sf::SoundBuffer noteTick;
|
||||
if (!noteTick.loadFromFile(noteTickPath)) {
|
||||
std::cerr << "Unable to load sound " << noteTickPath;
|
||||
throw std::runtime_error("Unable to load sound " + noteTickPath);
|
||||
}
|
||||
sf::Sound noteTickSound(noteTick);
|
||||
|
||||
Ecran_attente bg;
|
||||
Playfield playfield;
|
||||
bool beatTicked = false;
|
||||
std::string beatTickPath = "assets/sounds/sound beat tick.wav";
|
||||
sf::SoundBuffer beatTick;
|
||||
if (!beatTick.loadFromFile(beatTickPath)) {
|
||||
std::cerr << "Unable to load sound " << beatTickPath;
|
||||
throw std::runtime_error("Unable to load sound " + beatTickPath);
|
||||
}
|
||||
sf::Sound beatTickSound(beatTick);
|
||||
|
||||
|
||||
Widgets::Ecran_attente bg;
|
||||
std::optional<EditorState> editorState;
|
||||
|
||||
sf::Clock deltaClock;
|
||||
@ -41,31 +57,33 @@ int main(int argc, char** argv) {
|
||||
window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
|
||||
break;
|
||||
case sf::Event::KeyPressed:
|
||||
if (event.key.code == sf::Keyboard::Space) {
|
||||
if (not ImGui::GetIO().WantTextInput) {
|
||||
if (editorState) {
|
||||
editorState->playing = not editorState->playing;
|
||||
}
|
||||
/*
|
||||
if (editorState and editorState->music) {
|
||||
switch (editorState->music->getStatus()) {
|
||||
case sf::Music::Stopped:
|
||||
case sf::Music::Paused:
|
||||
editorState->music->play();
|
||||
break;
|
||||
case sf::Music::Playing:
|
||||
editorState->music->pause();
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
switch (event.key.code) {
|
||||
case sf::Keyboard::F3:
|
||||
if (editorState) {
|
||||
editorState->playBeatTick = not editorState->playBeatTick;
|
||||
}
|
||||
break;
|
||||
case sf::Keyboard::F4:
|
||||
if (editorState) {
|
||||
editorState->playNoteTick = not editorState->playNoteTick;
|
||||
}
|
||||
break;
|
||||
case sf::Keyboard::Space:
|
||||
if (not ImGui::GetIO().WantTextInput) {
|
||||
if (editorState) {
|
||||
editorState->playing = not editorState->playing;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sf::Time delta = deltaClock.restart();
|
||||
ImGui::SFML::Update(window, delta);
|
||||
|
||||
// Gestion du playback
|
||||
if (editorState->playing) {
|
||||
editorState->playbackPosition += delta;
|
||||
if (editorState->music) {
|
||||
@ -84,6 +102,16 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (editorState->playBeatTick) {
|
||||
if (fmodf(editorState->getBeats(),1.f) < 0.5) {
|
||||
if (not beatTicked) {
|
||||
beatTickSound.play();
|
||||
beatTicked = true;
|
||||
}
|
||||
} else {
|
||||
beatTicked = false;
|
||||
}
|
||||
}
|
||||
if (editorState->playbackPosition >= editorState->chartRuntime) {
|
||||
editorState->playing = false;
|
||||
editorState->playbackPosition = editorState->chartRuntime;
|
||||
@ -99,7 +127,7 @@ int main(int argc, char** argv) {
|
||||
// Dessin du fond
|
||||
if (editorState) {
|
||||
if (editorState->showPlayfield) {
|
||||
playfield.render(window,*editorState);
|
||||
editorState->displayPlayfield();
|
||||
}
|
||||
if (editorState->showProperties) {
|
||||
editorState->displayProperties();
|
||||
@ -118,6 +146,7 @@ int main(int argc, char** argv) {
|
||||
bg.render(window);
|
||||
}
|
||||
|
||||
// TODO : Use events instead
|
||||
// Gestion des Raccourcis Clavier
|
||||
|
||||
// Ctrl+S
|
||||
|
Loading…
Reference in New Issue
Block a user