Etterna 0.75.1
Loading...
Searching...
No Matches
NoteDisplay.h
1#ifndef NOTE_DISPLAY_H
2#define NOTE_DISPLAY_H
3
4#include "Etterna/Actor/Base/Actor.h"
5#include "Etterna/Models/Misc/CubicSpline.h"
6#include "Etterna/Models/Misc/GameInput.h"
7#include "Etterna/Models/NoteData/NoteData.h"
8#include "Etterna/Models/Misc/PlayerNumber.h"
9
10class Sprite;
11class Model;
12class PlayerState;
13class GhostArrowRow;
15struct TapNote;
16struct HoldNoteResult;
19enum NotePart
20{
21 NotePart_Tap,
22 NotePart_Mine,
23 NotePart_Lift,
24 NotePart_Fake,
25 NotePart_HoldHead,
26 NotePart_HoldTail,
27 NotePart_HoldTopCap,
28 NotePart_HoldBody,
29 NotePart_HoldBottomCap,
30 NUM_NotePart,
31 NotePart_Invalid
32};
33
35enum NoteColorType
36{
37 NoteColorType_Denominator,
38 NoteColorType_Progress,
39 NUM_NoteColorType,
40 NoteColorType_Invalid
41};
42auto
43NoteColorTypeToString(NoteColorType nct) -> const std::string&;
44auto
45StringToNoteColorType(const std::string& s) -> NoteColorType;
46
47struct NoteResource;
48
50{
53 void Load(const std::string& sButton,
54 const std::string& sElement,
55 PlayerNumber,
56 GameController,
57 const std::string&);
58 auto Get(const std::string&) -> Actor*;
59
60 private:
61 std::map<std::string, NoteResource*> g_p;
62};
63
65{
68 void Load(const std::string& sButton,
69 const std::string& sElement,
70 PlayerNumber,
71 GameController,
72 const std::string&);
73 auto Get(const std::string&) -> Sprite*;
74
75 private:
76 std::map<std::string, NoteResource*> g_p;
77};
79enum HoldType
80{
81 hold,
82 roll,
83 // minefield,
84 NUM_HoldType,
85 HoldType_Invalid
86};
88#define FOREACH_HoldType(i) FOREACH_ENUM(HoldType, i)
89auto
90HoldTypeToString(HoldType ht) -> const std::string&;
91
92enum ActiveType
93{
94 active,
95 inactive,
96 NUM_ActiveType,
97 ActiveType_Invalid
98};
100#define FOREACH_ActiveType(i) FOREACH_ENUM(ActiveType, i)
101auto
102ActiveTypeToString(ActiveType at) -> const std::string&;
103
104enum NoteColumnSplineMode
105{
106 NCSM_Disabled,
107 NCSM_Offset,
108 NCSM_Position,
109 NUM_NoteColumnSplineMode,
110 NoteColumnSplineMode_Invalid
111};
112
113auto
114NoteColumnSplineModeToString(NoteColumnSplineMode ncsm) -> const std::string&;
115LuaDeclareType(NoteColumnSplineMode);
116
117// A little pod struct to carry the data the NoteField needs to pass to the
118// NoteDisplay during rendering.
120{
121 const PlayerState* player_state; // to look up PlayerOptions
122 float reverse_offset_pixels;
123 ReceptorArrowRow* receptor_row;
124 GhostArrowRow* ghost_row;
125 const NoteData* note_data;
126 float first_beat;
127 float last_beat;
128 int first_row;
129 int last_row;
130 float draw_pixels_before_targets;
131 float draw_pixels_after_targets;
132 int* selection_begin_marker;
133 int* selection_end_marker;
134 float selection_glow;
135 float fail_fade;
136 float fade_before_targets;
137};
138
139// NCSplineHandler exists to allow NoteColumnRenderer to have separate
140// splines for position, rotation, and zoom, while concisely presenting the
141// same interface for all three.
143{
145 {
146 m_spline.redimension(3);
147 m_spline.m_owned_by_actor = true;
148 m_spline_mode = NCSM_Disabled;
149 m_receptor_t = 0.0F;
150 m_beats_per_t = 1.0F;
151 m_subtract_song_beat_from_curr = true;
152 }
153
154 [[nodiscard]] auto BeatToTValue(float song_beat, float note_beat) const
155 -> float;
156 void EvalForBeat(float song_beat, float note_beat, RageVector3& ret) const;
157 void EvalDerivForBeat(float song_beat,
158 float note_beat,
159 RageVector3& ret) const;
160 void EvalForReceptor(float song_beat, RageVector3& ret) const;
161 static void MakeWeightedAverage(NCSplineHandler& out,
162 const NCSplineHandler& from,
163 const NCSplineHandler& to,
164 float between);
165
166 CubicSplineN m_spline;
167 NoteColumnSplineMode m_spline_mode;
168 float m_receptor_t;
169 float m_beats_per_t;
170 bool m_subtract_song_beat_from_curr;
171
172 void PushSelf(lua_State* L);
173};
174
176{
177 void spae_pos_for_beat(const PlayerState* player_state,
178 float beat,
179 float y_offset,
180 float y_reverse_offset,
181 RageVector3& sp_pos,
182 RageVector3& ae_pos) const;
183 void spae_zoom_for_beat(const PlayerState* state,
184 float beat,
185 RageVector3& sp_zoom,
186 RageVector3& ae_zoom) const;
187 static void SetPRZForActor(Actor* actor,
188 const RageVector3& sp_pos,
189 const RageVector3& ae_pos,
190 const RageVector3& sp_rot,
191 const RageVector3& ae_rot,
192 const RageVector3& sp_zoom,
193 const RageVector3& ae_zoom);
194 const NCSplineHandler* pos_handler;
195 const NCSplineHandler* rot_handler;
196 const NCSplineHandler* zoom_handler;
197 RageColor diffuse;
198 RageColor glow;
199 float song_beat;
200 int column;
201};
202
205{
206 public:
207 NoteDisplay();
208 ~NoteDisplay();
209
210 void Load(int iColNum,
211 const PlayerState* pPlayerState,
212 float fYReverseOffsetPixels);
213
214 static void Update(float fDeltaTime);
215
216 auto DrawHoldsInRange(
217 const NoteFieldRenderArgs& field_args,
218 const NoteColumnRenderArgs& column_args,
219 const std::vector<NoteData::TrackMap::const_iterator>& tap_set) -> bool;
220 auto DrawTapsInRange(
221 const NoteFieldRenderArgs& field_args,
222 const NoteColumnRenderArgs& column_args,
223 const std::vector<NoteData::TrackMap::const_iterator>& tap_set) -> bool;
239 void DrawTap(const TapNote& tn,
240 const NoteFieldRenderArgs& field_args,
241 const NoteColumnRenderArgs& column_args,
242 float fBeat,
243 bool bOnSameRowAsHoldStart,
244 bool bOnSameRowAsRollBeat,
245 bool bIsAddition,
246 float fPercentFadeToFail);
247 void DrawHold(const TapNote& tn,
248 const NoteFieldRenderArgs& field_args,
249 const NoteColumnRenderArgs& column_args,
250 int iRow,
251 bool bIsBeingHeld,
252 const HoldNoteResult& Result,
253 bool bIsAddition,
254 float fPercentFadeToFail);
255
256 [[nodiscard]] auto DrawHoldHeadForTapsOnSameRow() const -> bool;
257 [[nodiscard]] auto DrawRollHeadForTapsOnSameRow() const -> bool;
258 float m_fYReverseOffsetPixels;
259
260 private:
261 void SetActiveFrame(float fNoteBeat,
262 Actor& actorToSet,
263 float fAnimationLength,
264 bool bVivid) const;
265 auto GetTapActor(NoteColorActor& nca, NotePart part, float fNoteBeat) const
266 -> Actor*;
267 auto GetHoldActor(NoteColorActor nca[NUM_HoldType][NUM_ActiveType],
268 NotePart part,
269 float fNoteBeat,
270 bool bIsRoll,
271 bool bIsBeingHeld) const -> Actor*;
272 auto GetHoldSprite(NoteColorSprite ncs[NUM_HoldType][NUM_ActiveType],
273 NotePart part,
274 float fNoteBeat,
275 bool bIsRoll,
276 bool bIsBeingHeld) const -> Sprite*;
277
278 struct draw_hold_part_args
279 {
280 int y_step;
281 float percent_fade_to_fail;
282 float color_scale;
283 float overlapped_time;
284 float y_top;
285 float y_bottom;
286 float y_length;
287 float y_start_pos;
288 float y_end_pos;
289 float top_beat;
290 float bottom_beat;
291 bool wrapping;
292 bool anchor_to_top;
293 bool flip_texture_vertically;
294 };
295
296 void DrawActor(const TapNote& tn,
297 Actor* pActor,
298 NotePart part,
299 const NoteFieldRenderArgs& field_args,
300 const NoteColumnRenderArgs& column_args,
301 float fYOffset,
302 float fBeat,
303 bool bIsAddition,
304 float fPercentFadeToFail,
305 float fColorScale,
306 bool is_being_held) const;
307 void DrawReplayActors(const TapNote& tn,
308 const NoteFieldRenderArgs& field_args,
309 const NoteColumnRenderArgs& column_args,
310 const int& row) const;
311
312 void DrawHoldPart(std::vector<Sprite*>& vpSpr,
313 const NoteFieldRenderArgs& field_args,
314 const NoteColumnRenderArgs& column_args,
315 const draw_hold_part_args& part_args,
316 bool glow,
317 int part_type) const;
318 void DrawHoldBodyInternal(std::vector<Sprite*>& sprite_top,
319 std::vector<Sprite*>& sprite_body,
320 std::vector<Sprite*>& sprite_bottom,
321 const NoteFieldRenderArgs& field_args,
322 const NoteColumnRenderArgs& column_args,
323 draw_hold_part_args& part_args,
324 float head_minus_top,
325 float tail_plus_bottom,
326 float y_head,
327 float y_tail,
328 float y_length,
329 float top_beat,
330 float bottom_beat,
331 bool glow) const;
332 void DrawHoldBody(const TapNote& tn,
333 const NoteFieldRenderArgs& field_args,
334 const NoteColumnRenderArgs& column_args,
335 float beat,
336 bool being_held,
337 float y_head,
338 float y_tail,
339 float y_end,
340 float percent_fade_to_fail,
341 float color_scale,
342 float top_beat,
343 float bottom_beat);
344
345 const PlayerState* m_pPlayerState; // to look up PlayerOptions
346 NoteMetricCache_t* cache;
347
348 NoteColorActor m_TapNote;
349 NoteColorActor m_TapMine;
350 NoteColorActor m_TapLift;
351 NoteColorActor m_TapFake;
352 NoteColorActor m_HoldHead[NUM_HoldType][NUM_ActiveType];
353 NoteColorSprite m_HoldTopCap[NUM_HoldType][NUM_ActiveType];
354 NoteColorSprite m_HoldBody[NUM_HoldType][NUM_ActiveType];
355 NoteColorSprite m_HoldBottomCap[NUM_HoldType][NUM_ActiveType];
356 NoteColorActor m_HoldTail[NUM_HoldType][NUM_ActiveType];
357
358 Actor* replay_offset_start;
359 Actor* replay_offset_body;
360 Actor* replay_offset_end;
361};
362
363// So, this is a bit screwy, and it's partly because routine forces rendering
364// notes from different noteskins in the same column.
365// NoteColumnRenderer exists to hold all the data needed for rendering a
366// column and apply any transforms from that column's actor to the
367// NoteDisplays that render the notes.
368// NoteColumnRenderer is also used as a fake parent for the receptor and ghost
369// actors so they can move with the rest of the column. I didn't use
370// ActorProxy because the receptor/ghost actors need to pull in the parent
371// state of their rows and the parent state of the column. -Kyz
372
374{
375 NoteDisplay* m_displays[PLAYER_INVALID + 1];
376 NoteFieldRenderArgs* m_field_render_args;
377 NoteColumnRenderArgs m_column_render_args;
378 int m_column;
379
380 // UpdateReceptorGhostStuff takes care of the logic for making the ghost
381 // and receptor positions follow the splines. It's called by their row
382 // update functions. -Kyz
383 void UpdateReceptorGhostStuff(Actor* receptor) const;
384 void DrawPrimitives() override;
385 void PushSelf(lua_State* L) override;
386
388 {
390 NCSplineHandler m_pos_handler;
391 NCSplineHandler m_rot_handler;
392 NCSplineHandler m_zoom_handler;
393 static void MakeWeightedAverage(NCR_TweenState& out,
394 const NCR_TweenState& from,
395 const NCR_TweenState& to,
396 float between);
397 auto operator==(const NCR_TweenState& other) const -> bool;
398 auto operator!=(const NCR_TweenState& other) const -> bool
399 {
400 return !operator==(other);
401 }
402 };
403
404 auto NCR_DestTweenState() -> NCR_TweenState&
405 {
406 if (NCR_Tweens.empty()) {
407 return NCR_current;
408 }
409 return NCR_Tweens.back();
410 }
411
412 [[nodiscard]] auto NCR_DestTweenState() const -> const NCR_TweenState&
413 {
414 return const_cast<NoteColumnRenderer*>(this)->NCR_DestTweenState();
415 }
416
417 void SetCurrentTweenStart() override;
418 void EraseHeadTween() override;
419 void UpdatePercentThroughTween(float between) override;
420 void BeginTweening(float time, ITween* interp) override;
421 void StopTweening() override;
422 void FinishTweening() override;
423
424 auto GetPosHandler() -> NCSplineHandler*
425 {
426 return &NCR_DestTweenState().m_pos_handler;
427 }
428 auto GetRotHandler() -> NCSplineHandler*
429 {
430 return &NCR_DestTweenState().m_rot_handler;
431 }
432 auto GetZoomHandler() -> NCSplineHandler*
433 {
434 return &NCR_DestTweenState().m_zoom_handler;
435 }
436
437 private:
438 std::vector<NCR_TweenState> NCR_Tweens;
439 NCR_TweenState NCR_current;
440 NCR_TweenState NCR_start;
441};
442
443#endif
Base class for all objects that appear on the screen.
Definition Actor.h:78
Row of GhostArrow Actors.
Definition GhostArrowRow.h:11
The interface for simple interpolation.
Definition Tween.h:29
Definition Model.h:15
Holds data about the notes that the player is supposed to hit.
Definition NoteData.h:43
Draws TapNotes and HoldNotes.
Definition NoteDisplay.h:205
void DrawTap(const TapNote &tn, const NoteFieldRenderArgs &field_args, const NoteColumnRenderArgs &column_args, float fBeat, bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollBeat, bool bIsAddition, float fPercentFadeToFail)
Draw the TapNote onto the NoteField.
Definition NoteDisplay.cpp:1899
The player's indivdual state.
Definition PlayerState.h:30
A row of ReceptorArrow objects.
Definition ReceptorArrowRow.h:12
A bitmap Actor that animates and moves around.
Definition Sprite.h:13
Definition CubicSpline.h:55
The result of holding (or letting go of) a hold note.
Definition NoteTypes.h:42
Definition NoteDisplay.h:143
Definition NoteDisplay.h:50
Definition NoteDisplay.h:65
Definition NoteDisplay.h:176
Definition NoteDisplay.h:388
Definition NoteDisplay.h:374
void DrawPrimitives() override
Draw the primitives of the Actor.
Definition NoteDisplay.cpp:2075
Definition NoteDisplay.h:120
Definition NoteDisplay.cpp:66
Definition NoteDisplay.cpp:231
Definition RageTypes.h:332
Definition RageTypes.h:172
The various properties of a tap note.
Definition NoteTypes.h:149