Skip to content
This repository has been archived by the owner on Jan 26, 2025. It is now read-only.

Commit

Permalink
workin on the chart editor rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
MaybeMaru committed Apr 7, 2024
1 parent 080edd3 commit 05e84f3
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 44 deletions.
2 changes: 1 addition & 1 deletion source/funkin/graphics/FlxFunkText.hx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class FlxFunkText extends FlxSpriteExt {
}

static inline function getFont(value:String) {
final _font = (value.startsWith("assets/") || value.startsWith("mods/")) ? value : Paths.font(value);
final _font = (value.startsWith("assets/") #if MODS_ALLOWED || value.startsWith("mods/") #end) ? value : Paths.font(value);
return Paths.exists(_font, FONT) ? (_font.startsWith("assets/") ? OpenFlAssets.getFont(_font).fontName : _font) : FlxAssets.FONT_DEFAULT;
}

Expand Down
56 changes: 31 additions & 25 deletions source/funkin/graphics/FlxRepeatSprite.hx
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ class FlxRepeatSprite extends FlxSpriteExt
return newRect.getRotatedBounds(angle, _scaledOrigin, newRect);
}

static final __tempPoint:FlxPoint = FlxPoint.get();
static final __lastMatrix = FlxPoint.get(); // Nasty hack
static final tempPoint:FlxPoint = FlxPoint.get();
static final lastMatrix = FlxPoint.get(); // Nasty hack

override function drawComplex(camera:FlxCamera) {
prepareFrameMatrix(_frame, _matrix);
Expand All @@ -119,21 +119,22 @@ class FlxRepeatSprite extends FlxSpriteExt
// Holds the og matrix position for each tile
var point = CoolUtil.point.set(_matrix.tx, _matrix.ty);

// Temp point for calculations
var tempPoint = __tempPoint;

// Fix bug of tiles duplicating
__lastMatrix.set(-1, -1);
lastMatrix.set(-1, -1);

var scaleX = scaleX();
var scaleY = scaleY();
var fw:Float = frameWidth * scaleX; // TODO: replace this shit same way as Height

switch (drawStyle) {
switch (drawStyle)
{
// Draw from left top to right bottom style
case TOP_BOTTOM:
for (xi in 0...tilesX) {
for (xi in 0...tilesX)
{
var heightPos:Float = 0;
for (yi in 0...tilesY) {
for (yi in 0...tilesY)
{
setupTile(xi, yi, frame);

var addW = fw * (xi + 1);
Expand All @@ -142,7 +143,7 @@ class FlxRepeatSprite extends FlxSpriteExt

heightPos += tempPoint.y;
if (heightPos > repeatHeight) // Cut frame height
_frame.frame.height = (tempPoint.y + (repeatHeight - heightPos)) / scaleY();
_frame.frame.height = (tempPoint.y + (repeatHeight - heightPos)) / scaleY;

// Position and draw
var addX = addW - fw;
Expand All @@ -157,20 +158,24 @@ class FlxRepeatSprite extends FlxSpriteExt
}
// Draw from bottom to top style
case BOTTOM_TOP:
for (xi in 0...tilesX) {
for (xi in 0...tilesX)
{
var heightPos:Float = repeatHeight;
for (yi in 0...tilesY) {
for (yi in 0...tilesY)
{
setupTile(xi, yi, frame);

var addW = fw * (xi + 1);
if (addW > repeatWidth) // Cut frame width
_frame.frame.width = (fw + (repeatWidth - addW)) / scaleX;

heightPos -= tempPoint.y;
if (heightPos < 0) {
var scaleY = scaleY();
_frame.frame.height += heightPos / scaleY;
_frame.frame.y -= heightPos / scaleY;
if (heightPos < 0)
{
var moveH = heightPos / scaleY;
_frame.frame.height = _frame.frame.height + moveH;
_frame.frame.y = _frame.frame.y - moveH;

heightPos = 0;
}

Expand All @@ -188,36 +193,36 @@ class FlxRepeatSprite extends FlxSpriteExt
}

private inline function translateWithTrig(tx:Float, ty:Float) {
_matrix.tx += (tx * _cosAngle) + (ty * -_sinAngle);
_matrix.ty += (tx * _sinAngle) + (ty * _cosAngle);
_matrix.tx = _matrix.tx + ((tx * _cosAngle) + (ty * -_sinAngle));
_matrix.ty = _matrix.ty + ((tx * _sinAngle) + (ty * _cosAngle));
}

// Prepare tile dimensions
function setupTile(tileX:Int, tileY:Int, baseFrame:FlxFrame) {
var frame = baseFrame.frame;
var point = __tempPoint.set(frame.width * scaleX(), frame.height * scaleY());
var point = tempPoint.set(frame.width * scaleX(), frame.height * scaleY());
_frame.frame.copyFrom(frame);
_frame.angle = baseFrame.angle;
return point;
}

var tileOffset:FlxPoint = FlxPoint.get();

function drawTile(tileX:Int, tileY:Int, tileFrame:FlxFrame, baseFrame:FlxFrame, bitmap:BitmapData, tilePos:FlxPoint, camera:FlxCamera) {
function drawTile(tileX:Int, tileY:Int, tileFrame:FlxFrame, baseFrame:FlxFrame, bitmap:BitmapData, tilePos:FlxPoint, camera:FlxCamera):Void
{
// Do cliprect stuff
var doDraw:Bool = clipRect != null ? handleClipRect(tileFrame, baseFrame, tilePos) : true;
if (tileRect != null) tileFrame = tileFrame.clipTo(tileRect);

var lastMatrix = __lastMatrix;
var mTx = _matrix.tx;
var mTy = _matrix.ty;

if (doDraw) if ((lastMatrix.x != mTx || lastMatrix.y != mTy)) {
if (doDraw) if ((lastMatrix.x != mTx) || (lastMatrix.y != mTy))
{
lastMatrix.set(mTx, mTy);
translateWithTrig(-tileOffset.x, -tileOffset.y);

var frame = tileFrame.frame;
if (rectInBounds(mTx, mTy, frame.width, frame.height, camera)) // dont draw stuff out of bounds
if (rectInBounds(mTx, mTy, tileFrame.frame.width, tileFrame.frame.height, camera)) // dont draw stuff out of bounds
drawTileToCamera(tileFrame, bitmap, _matrix, camera);

translateWithTrig(tileOffset.x, tileOffset.y);
Expand Down Expand Up @@ -245,7 +250,8 @@ class FlxRepeatSprite extends FlxSpriteExt
return cam.containsRect(rect.getRotatedBounds(angle, null, rect));
}

function handleClipRect(tileFrame:FlxFrame, baseFrame:FlxFrame, tilePos:FlxPoint) {
function handleClipRect(tileFrame:FlxFrame, baseFrame:FlxFrame, tilePos:FlxPoint):Bool
{
translateWithTrig(clipRect.x, clipRect.y);
tilePos.add(clipRect.x, clipRect.y);

Expand Down
3 changes: 2 additions & 1 deletion source/funkin/objects/note/Note.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package funkin.objects.note;

class Note extends BasicNote {
class Note extends BasicNote
{
public function new(noteData:Int = 0, strumTime:Float = 0.0, skin:String = "default", ?child:Sustain) {
super(noteData, strumTime, skin); // Load skin
this.child = child;
Expand Down
3 changes: 2 additions & 1 deletion source/funkin/states/MusicBeatState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class MusicBeatState extends FlxUIState implements IMusicGetter {
ModdingUtil.addCall('stateCreate');
}

Main.transition.exitTrans();
if (Main.transition != null)
Main.transition.exitTrans();
}

// Only for backwards compatibility
Expand Down
5 changes: 4 additions & 1 deletion source/funkin/states/newchart/ChartEditor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class ChartEditor extends MusicBeatState

public static function setupSong(song:String, diff:String, ?input:SwagSong):SwagSong
{
return SONG = input ?? Song.loadFromFile(diff, song);
SONG = input ?? Song.loadFromFile(diff, song);
Conductor.bpm = SONG.bpm;
Conductor.songPosition = 0.0;
return SONG;
}
}
155 changes: 145 additions & 10 deletions source/funkin/states/newchart/ChartGrid.hx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package funkin.states.newchart;

import flixel.addons.display.FlxBackdrop;
import openfl.events.MouseEvent;
import flixel.addons.display.FlxGridOverlay;

Expand All @@ -8,21 +9,29 @@ class ChartGrid extends Group
{
inline static var TILE:Int = 40;

var notesGrid:FlxSpriteExt;
var eventsGrid:FlxSpriteExt;
var downscroll:Bool = false;

var notesGrid:FlxBackdrop;
var eventsGrid:FlxBackdrop;

var beats:FlxBackdrop;

var strumline:ChartStrumLine;

public function new() {
super();

// Use the same bitmap for batch rendering on both grids
var bitmap = FlxGridOverlay.createGrid(1, 1, 8, 16, true, 0xff7c7c7c, 0xff6e6e6e);

notesGrid = new FlxSpriteExt(0, 0, bitmap);
notesGrid.setScale(TILE);
notesGrid = new FlxBackdrop(bitmap, Y);
notesGrid.scale.set(TILE, TILE);
notesGrid.updateHitbox();
add(notesGrid);

eventsGrid = new FlxSpriteExt(0, 0, bitmap);
eventsGrid.setScale(TILE);
eventsGrid = new FlxBackdrop(bitmap, Y);
eventsGrid.scale.set(TILE, TILE);
eventsGrid.updateHitbox();
add(eventsGrid);

// Adjust events grid shit
Expand All @@ -34,9 +43,75 @@ class ChartGrid extends Group
notesGrid.screenCenter(X);
eventsGrid.x = notesGrid.x - TILE - 10;

beats = new FlxBackdrop(null, Y);
beats.setPosition(notesGrid.x, notesGrid.y);
beats.makeGraphic(1, 1, 0xff565456);
beats.antialiasing = false;
beats.scale.set(notesGrid.width, 2);
beats.updateHitbox();
add(beats);

var separator = new FlxSpriteExt().makeRect(2, FlxG.height, FlxColor.BLACK);
separator.antialiasing = false;
separator.scrollFactor.set();
separator.screenCenter(X);
add(separator);

strumline = new ChartStrumLine(notesGrid.x);
add(strumline);

prepareBpmChanges();
prepareObjects();

setSnap(4);
updatePosition();

FlxG.mouse._stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}

override function update(elapsed:Float)
{
if (Conductor.playing)
{
updatePosition();
}
else
{
var mult:Int = FlxG.keys.pressed.SHIFT ? 4 : 1;

if (FlxG.keys.justPressed.A) curSection += (downscroll ? mult : -mult);
if (FlxG.keys.justPressed.D) curSection += (downscroll ? -mult : mult);

if (FlxG.keys.pressed.W) move((downscroll ? elapsed : -elapsed) * mult);
if (FlxG.keys.pressed.S) move((downscroll ? -elapsed : elapsed) * mult);
}
}

function move(elapsed:Float):Void {
Conductor.songPosition += elapsed * 1000;

if (Conductor.songPosition < 0)
Conductor.songPosition = 0;

if (Conductor.songPosition >= sectionTimes[curSection + 1]) curSection++;
if (Conductor.songPosition < sectionTimes[curSection]) {
curSection--;
Conductor.songPosition = sectionTimes[curSection + 1] - 1; // Adjust time
}

updatePosition();
}

function updatePosition() {
strumline.y = getCurrentTimeY();
FlxG.camera.scroll.y = strumline.y - (downscroll ? 480 : 240);
}

function setSnap(snap:Int = 4)
{
beats.spacing.y = ((snap / 2) * TILE) - 1;
}

// Save doing the mouse stuff on update
function onMouseMove(e)
{
Expand All @@ -48,21 +123,81 @@ class ChartGrid extends Group
return Conductor.playing ? Conductor.inst.time + Conductor.offset[0] + Conductor.latency : Conductor.songPosition;
}

inline function getTimeY():Float {
return inline FlxMath.remapToRange(getTime(), 0, Conductor.sectionCrochet, 0, TILE * 16); // TODO: Change the 16 with the snap later
// TODO: Change the 16 with the snap later
inline function getTimeY(time:Float):Float {
var range:Float = inline FlxMath.remapToRange(time, 0, Conductor.sectionCrochet, 0, TILE * 16);
return downscroll ? -(range + TILE) : range;
}

// Get the conductor songPosition time Y
inline function getCurrentTimeY():Float {
return getTimeY(Math.max(0, getTime()));
}

// TODO:
// Merge prepareObjects and prepareBPM since the notes gotta change position depending on the bpm
// Maybe generate notes first and make another function to position them at runtime?
// Make a beats seperator class to accomodate for that too

public var sectionObjects:Array<Array<FlxObject>> = [];

function prepareObjects() {
ChartEditor.SONG.notes.fastForEach((section, i) ->
{
var array:Array<FlxObject> = [];

section.sectionNotes.fastForEach((note, i) -> {
var note = makeNote(note[0], note[1]);
array.push(note);
});

sectionObjects.push(array);
});
}

public var sectionTimes:Array<Float> = [];

function prepareBpmChanges() {
sectionTimes.splice(0, sectionTimes.length);

var time:Float = 0.0;
var bpm = ChartEditor.SONG.bpm;

ChartEditor.SONG.notes.fastForEach((section, i) -> {
sectionTimes.push(time);

if (section.changeBPM)
bpm = section.bpm;

time += 4 * (60000 / bpm);
});
}

function makeNote(strumTime:Float, noteData:Int) {
var note = new Note(noteData, strumTime);
note.x = notesGrid.x + (TILE * noteData);
note.y = getTimeY(strumTime);
note.setGraphicSize(TILE, TILE);
note.updateHitbox();
return note;
}

var curSection(default, set):Int = 0;
inline function set_curSection(value:Int):Int {
return curSection = cast FlxMath.bound(value, 0, ChartEditor.SONG.notes.length - 1);
inline function set_curSection(value:Int):Int
{
value = cast FlxMath.bound(value, 0, ChartEditor.SONG.notes.length - 1);

Conductor.songPosition = sectionTimes[value] ?? sectionTimes[sectionTimes.length - 1];
updatePosition();

return curSection = value;
}

override function draw() {
super.draw();

// Render the 3 current visible sections, maybe make this higher depending on the snap?
// TODO: replace with ChartGridContent
for (i in 0...3)
{
if (sectionObjects[curSection - 1 + i] != null)
Expand Down
Loading

0 comments on commit 05e84f3

Please sign in to comment.