Etterna 0.74.4
Loading...
Searching...
No Matches
NoteTypes.h
1
3#ifndef NOTE_TYPES_H
4#define NOTE_TYPES_H
5
6#include "GameConstantsAndTypes.h"
7#include "Core/Services/Locator.hpp"
8
9class XNode;
10
13{
17 TapNoteResult() = default;
19 TapNoteScore tns{ TNS_None };
20
27 float fTapNoteOffset{ 1.F };
28
31 bool bHidden{ false };
32
33 // XML
34 [[nodiscard]] auto CreateNode() const -> XNode*;
35 void LoadFromNode(const XNode* pNode);
36
37 // Lua
38 void PushSelf(lua_State* L);
39};
42{
43 HoldNoteResult() = default;
44 [[nodiscard]] auto GetLastHeldBeat() const -> float;
45
46 HoldNoteScore hns{ HNS_None };
47
58 float fLife{ 1.F };
59
64 float fOverlappedTime{ 0 };
65
68 int iLastHeldRow{ 0 };
69
72 int iCheckpointsHit{ 0 };
75 int iCheckpointsMissed{ 0 };
76
78 bool bHeld{ false };
81 bool bActive{ false };
82
83 // XML
84 [[nodiscard]] auto CreateNode() const -> XNode*;
85 void LoadFromNode(const XNode* pNode);
86
87 // Lua
88 void PushSelf(lua_State* L);
89};
90
92enum TapNoteType
93{
94 TapNoteType_Empty,
95 TapNoteType_Tap,
96 TapNoteType_HoldHead,
98 TapNoteType_HoldTail,
100 TapNoteType_Mine,
102 TapNoteType_Lift,
103 TapNoteType_AutoKeysound,
105 TapNoteType_Fake,
107 NUM_TapNoteType,
108 TapNoteType_Invalid
109};
110auto
111TapNoteTypeToString(TapNoteType tnt) -> const std::string&;
112auto
113TapNoteTypeToLocalizedString(TapNoteType tnt) -> const std::string&;
114LuaDeclareType(TapNoteType);
115
117enum TapNoteSubType
118{
119 TapNoteSubType_Hold,
120 TapNoteSubType_Roll,
122 // TapNoteSubType_Mine,
123 NUM_TapNoteSubType,
124 TapNoteSubType_Invalid
125};
126auto
127TapNoteSubTypeToString(TapNoteSubType tnst) -> const std::string&;
128auto
129TapNoteSubTypeToLocalizedString(TapNoteSubType tnst) -> const std::string&;
130LuaDeclareType(TapNoteSubType);
131
133enum TapNoteSource
134{
135 TapNoteSource_Original,
136 TapNoteSource_Addition,
138 NUM_TapNoteSource,
139 TapNoteSource_Invalid
140};
141auto
142TapNoteSourceToString(TapNoteSource tns) -> const std::string&;
143auto
144TapNoteSourceToLocalizedString(TapNoteSource tns) -> const std::string&;
145LuaDeclareType(TapNoteSource);
146
149{
151 TapNoteType type{ TapNoteType_Empty };
154 TapNoteSubType subType{ TapNoteSubType_Invalid };
156 TapNoteSource source{ TapNoteSource_Original };
159
160 // Index into Song's vector of keysound files if nonnegative:
161 int iKeysoundIndex{ -1 };
162
163 // also used for hold_head only:
164 int iDuration{ 0 };
165 HoldNoteResult HoldResult;
166
167 // XML
168 [[nodiscard]] auto CreateNode() const -> XNode*;
169 void LoadFromNode(const XNode* pNode);
170
171 // Lua
172 void PushSelf(lua_State* L);
173
174 // So I'm not repeatedly typing this out - Mina
175 [[nodiscard]] auto IsNote() const -> bool
176 {
177 return type == TapNoteType_Tap || type == TapNoteType_HoldHead;
178 }
179
180 TapNote() = default;
181 void Init()
182 {
183 type = TapNoteType_Empty;
184 subType = TapNoteSubType_Invalid;
185 source = TapNoteSource_Original;
186 iDuration = 0;
187 }
188 TapNote(TapNoteType type_,
189 TapNoteSubType subType_,
190 TapNoteSource source_,
191 int iKeysoundIndex_)
192 : type(type_)
193 , subType(subType_)
194 , source(source_)
195 , iKeysoundIndex(iKeysoundIndex_)
196 {
197 if (type_ > TapNoteType_Fake) {
198 Locator::getLogger()->trace("Invalid tap note type {} (most likely) due to random "
199 "vanish issues. Assume it doesn't need judging.",
200 TapNoteTypeToString(type_).c_str());
201 type = TapNoteType_Empty;
202 }
203 }
204
209 auto operator==(const TapNote& other) const -> bool
210 {
211#define COMPARE(x) \
212 if ((x) != other.x) \
213 return false
214 COMPARE(type);
215 COMPARE(subType);
216 COMPARE(source);
217 COMPARE(iKeysoundIndex);
218 COMPARE(iDuration);
219#undef COMPARE
220 return true;
221 }
226 auto operator!=(const TapNote& other) const -> bool
227 {
228 return !operator==(other);
229 }
230};
231
232extern TapNote TAP_EMPTY; // '0'
233extern TapNote TAP_ORIGINAL_TAP; // '1'
234extern TapNote TAP_ORIGINAL_HOLD_HEAD; // '2'
235extern TapNote TAP_ORIGINAL_ROLL_HEAD; // '4'
236extern TapNote TAP_ORIGINAL_MINE; // 'M'
237extern TapNote TAP_ORIGINAL_LIFT; // 'L'
238extern TapNote TAP_ORIGINAL_ATTACK; // 'A'
239extern TapNote TAP_ORIGINAL_AUTO_KEYSOUND; // 'K'
240extern TapNote TAP_ORIGINAL_FAKE; // 'F'
241// extern TapNote TAP_ORIGINAL_MINE_HEAD; // 'N' (tentative, we'll see when
242// iDance gets ripped.)
243extern TapNote TAP_ADDITION_TAP;
244extern TapNote TAP_ADDITION_MINE;
245
251const int MAX_NOTE_TRACKS = 16;
252
262const int ROWS_PER_BEAT = 48;
263
265const int MAX_NOTE_ROW = (1 << 30);
266
268enum NoteType
269{
270 NOTE_TYPE_4TH,
271 NOTE_TYPE_8TH,
272 NOTE_TYPE_12TH,
273 NOTE_TYPE_16TH,
274 NOTE_TYPE_24TH,
275 NOTE_TYPE_32ND,
276 NOTE_TYPE_48TH,
277 NOTE_TYPE_64TH,
278 NOTE_TYPE_192ND,
279 NUM_NoteType,
280 NoteType_Invalid
281};
282auto
283NoteTypeToString(NoteType nt) -> const std::string&;
284auto
285NoteTypeToLocalizedString(NoteType nt) -> const std::string&;
286LuaDeclareType(NoteType);
287auto
288NoteTypeToBeat(NoteType nt) -> float;
289auto
290NoteTypeToRow(NoteType nt) -> int;
291auto
292GetNoteType(int row) -> NoteType;
293auto
294BeatToNoteType(float fBeat) -> NoteType;
295auto
296IsNoteOfType(int row, NoteType t) -> bool;
297
298/* This is more accurate: by computing the integer and fractional parts
299separately, we
300 * can avoid storing very large numbers in a float and possibly losing
301precision. It's
302 * slower; use this once less stuff uses BeatToNoteRow.
303 *
304 * This function rounds up.
305inline int BeatToNoteRow( float fBeatNum )
306{
307 float fraction = fBeatNum - truncf(fBeatNum);
308 int integer = int(fBeatNum) * ROWS_PER_BEAT;
309 return integer + lrintf(fraction * ROWS_PER_BEAT);
310}
311*/
312
317inline auto
318BeatToNoteRow(float fBeatNum) -> int
319{
320 return lround(fBeatNum * 48.F);
321}
326inline auto
327NoteRowToBeat(int iRow) -> float
328{
329 return iRow / static_cast<float>(ROWS_PER_BEAT);
330}
331
332// These functions can be useful for function templates,
333// where both rows and beats can be specified.
334
339static inline auto
340ToNoteRow(int row) -> int
341{
342 return row;
343}
344
349static inline auto
350ToNoteRow(float beat) -> int
351{
352 return BeatToNoteRow(beat);
353}
354
359static inline auto
360ToBeat(int row) -> float
361{
362 return NoteRowToBeat(row);
363}
364
369static inline auto
370ToBeat(float beat) -> float
371{
372 return beat;
373}
374
383template<typename T>
384auto
385ScalePosition(T start, T length, T newLength, T position) -> T
386{
387 if (position < start)
388 return position;
389 if (position >= start + length)
390 return position - length + newLength;
391 return start + (position - start) * newLength / length;
392}
393
394#endif
Definition XmlFile.h:95
The result of holding (or letting go of) a hold note.
Definition NoteTypes.h:42
The result of hitting (or missing) a tap note.
Definition NoteTypes.h:13
TapNoteResult()=default
Set up the TapNoteResult with default values. The default offset value should be 1 not 0 as to diffre...
float fTapNoteOffset
Offset, in seconds, for a tap grade.
Definition NoteTypes.h:27
bool bHidden
If the whole row has been judged, all taps on the row will be set to hidden.
Definition NoteTypes.h:31
TapNoteScore tns
The TapNoteScore that was achieved by the player.
Definition NoteTypes.h:19
The various properties of a tap note.
Definition NoteTypes.h:149
auto operator!=(const TapNote &other) const -> bool
Determine if the two TapNotes are not equal to each other.
Definition NoteTypes.h:226
auto operator==(const TapNote &other) const -> bool
Determine if the two TapNotes are equal to each other.
Definition NoteTypes.h:209
TapNoteResult result
The result of hitting or missing the TapNote.
Definition NoteTypes.h:158