diff --git a/src/itdelatrisu/opsu/Options.java b/src/itdelatrisu/opsu/Options.java index ba8e4b08..2b88f595 100644 --- a/src/itdelatrisu/opsu/Options.java +++ b/src/itdelatrisu/opsu/Options.java @@ -485,7 +485,7 @@ public class Options { screenshotFormatIndex = i; } }, - CURSOR_SIZE ("Size", "CursorSize", "Change the cursor scale.", 100, 50, 200) { + CURSOR_SIZE ("Size", "CursorSize", "Change the cursor scale.", 100, 10, 200) { @Override public String getValueString() { return String.format("%.2fx", val / 100f); } diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 4221c01f..26abb958 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -51,10 +51,13 @@ import itdelatrisu.opsu.ui.animations.AnimatedValue; import itdelatrisu.opsu.ui.animations.AnimationEquation; import java.io.File; +import java.io.FileFilter; +import java.io.IOException; import java.util.*; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.GL11; import org.newdawn.slick.Animation; import org.newdawn.slick.Color; import org.newdawn.slick.Graphics; @@ -735,6 +738,15 @@ public class Game extends ComplexOpsuState { UI.draw(g); + int i = 0; + g.setColor(new Color(0.2f, 0.2f, 0.2f)); + g.fillRect(0, 0, ReplayPlayback.SQSIZE * 2, displayContainer.height); + g.setColor(Color.black); + g.fillRect(ReplayPlayback.SQSIZE * 2, 0, ReplayPlayback.SQSIZE * 2, displayContainer.height); + for (ReplayPlayback replayPlayback : replays) { + replayPlayback.render(displayContainer.renderDelta, g, i++, trackPosition); + } + super.render(g); } @@ -926,6 +938,7 @@ public class Game extends ComplexOpsuState { // set mouse coordinates autoMousePosition.set(autoPoint.x, autoPoint.y); + autoMousePosition.set(-100, -100); } if (isReplay) { @@ -1444,6 +1457,7 @@ public class Game extends ComplexOpsuState { return true; } + private LinkedList replays; @Override public void enter() { overlays.clear(); @@ -1457,6 +1471,29 @@ public class Game extends ComplexOpsuState { super.enter(); + File replaydir = new File("d:/Users/Robin/games/osu/osr-stuff-master/opsud/"); + File[] files = replaydir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getName().endsWith(".osr"); + } + }); + + replays = new LinkedList<>(); + float hueshift = 360f / files.length; + float hue = 0; + for (File file : files) { + Replay r = new Replay(file); + try { + r.load(); + } catch (IOException e) { + EventBus.post(new BubbleNotificationEvent("could not load replay " + file.getName(), BubbleNotificationEvent.COMMONCOLOR_RED)); + continue; + } + replays.add(new ReplayPlayback(r, new Color(java.awt.Color.getHSBColor((hue) / 360f, 1.0f, 1.0f).getRGB()))); + hue += hueshift; + } + if (isReplay || GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) { displayContainer.drawCursor = false; } diff --git a/src/itdelatrisu/opsu/states/Splash.java b/src/itdelatrisu/opsu/states/Splash.java index c5e3060e..b9ac5e99 100644 --- a/src/itdelatrisu/opsu/states/Splash.java +++ b/src/itdelatrisu/opsu/states/Splash.java @@ -33,6 +33,7 @@ import java.io.File; import org.newdawn.slick.Color; import org.newdawn.slick.Graphics; import org.newdawn.slick.Input; +import org.newdawn.slick.opengl.renderer.Renderer; import org.newdawn.slick.util.Log; import yugecin.opsudance.core.inject.Inject; import yugecin.opsudance.core.state.BaseOpsuState; @@ -70,6 +71,9 @@ public class Splash extends BaseOpsuState { return; } + System.out.println( + Renderer.get().getClass() + ); inited = true; thread = new Thread() { @Override diff --git a/src/itdelatrisu/opsu/ui/Cursor.java b/src/itdelatrisu/opsu/ui/Cursor.java index f5ad23bf..9e0a9182 100644 --- a/src/itdelatrisu/opsu/ui/Cursor.java +++ b/src/itdelatrisu/opsu/ui/Cursor.java @@ -66,6 +66,8 @@ public class Cursor { private boolean isMirrored; + private Color filter; + /** * Constructor. */ @@ -78,6 +80,11 @@ public class Cursor { this.isMirrored = isMirrored; } + public Cursor(Color filter) { + this(false); + this.filter = filter; + } + /** * Draws the cursor. * @param mousePressed whether or not the mouse button is pressed @@ -131,6 +138,10 @@ public class Cursor { lastCursorColor = filter = Dancer.cursorColorOverride.getColor(); } + if (this.filter != null) { + filter = this.filter; + } + // draw a fading trail float alpha = 0f; float t = 2f / trail.size(); @@ -139,7 +150,7 @@ public class Cursor { cursorTrail.startUse(); for (Point p : trail) { alpha += t; - cursorTrail.setImageColor(filter.r, filter.g, filter.b, alpha); + cursorTrail.setImageColor(filter.r, filter.g, filter.b, alpha * 0.1f); cursorTrail.drawEmbedded( p.x - (cursorTrailWidth / 2f), p.y - (cursorTrailHeight / 2f), cursorTrailWidth, cursorTrailHeight, cursorTrailRotation); diff --git a/src/yugecin/opsudance/ReplayPlayback.java b/src/yugecin/opsudance/ReplayPlayback.java new file mode 100644 index 00000000..91281d0a --- /dev/null +++ b/src/yugecin/opsudance/ReplayPlayback.java @@ -0,0 +1,142 @@ +/* + * opsu!dance - fork of opsu! with cursordance auto + * Copyright (C) 2017 yugecin + * + * opsu!dance is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu!dance is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!dance. If not, see . + */ +package yugecin.opsudance; + +import itdelatrisu.opsu.replay.Replay; +import itdelatrisu.opsu.replay.ReplayFrame; +import itdelatrisu.opsu.ui.Cursor; +import itdelatrisu.opsu.ui.Fonts; +import org.newdawn.slick.Color; +import org.newdawn.slick.Graphics; +import yugecin.opsudance.core.DisplayContainer; + +public class ReplayPlayback { + + public final Replay replay; + public ReplayFrame currentFrame; + public ReplayFrame nextFrame; + private int frameIndex; + private Color color; + private Cursor cursor; + private int keydelay[]; + public static final int SQSIZE = 15; + private boolean hr; + private String player; + + public ReplayPlayback(Replay replay, Color color) { + this.replay = replay; + resetFrameIndex(); + this.color = color; + Color cursorcolor = new Color(color); + //cursorcolor.a = 0.5f; + cursor = new Cursor(cursorcolor); + keydelay = new int[4]; + this.player = ""; + if ((replay.mods & 0x1) > 0) { + this.player += "NF"; + } + if ((replay.mods & 0x2) > 0) { + this.player += "EZ"; + } + if ((replay.mods & 0x8) > 0 && (replay.mods & 0x200) == 0) { + this.player += "HD"; + } + if ((replay.mods & 0x10) > 0) { + this.player += "HR"; + hr = true; + } + if ((replay.mods & 0x20) > 0) { + this.player += "SD"; + } + if ((replay.mods & 0x40) > 0) { + this.player += "DT"; + } + if ((replay.mods & 0x80) > 0) { + this.player += "RL"; + } + if ((replay.mods & 0x100) > 0) { + this.player += "HT"; + } + if ((replay.mods & 0x200) > 0) { + this.player += "NC"; + } + if ((replay.mods & 0x400) > 0) { + this.player += "FL"; + } + if ((replay.mods & 0x4000) > 0) { + this.player += "PF"; + } + if (this.player.length() > 0) { + this.player = " +" + this.player; + } + this.player = replay.playerName + this.player; + } + + public void resetFrameIndex() { + frameIndex = 0; + currentFrame = replay.frames[frameIndex++]; + nextFrame = replay.frames[frameIndex]; + } + + public void render(int renderdelta, Graphics g, int ypos, int time) { + while (nextFrame != null && nextFrame.getTime() < time) { + currentFrame = nextFrame; + processKeys(); + frameIndex++; + if (frameIndex >= replay.frames.length) { + nextFrame = null; + continue; + } + nextFrame = replay.frames[frameIndex]; + } + processKeys(); + g.setColor(color); + ypos *= SQSIZE; + for (int i = 0; i < 4; i++) { + if (keydelay[i] > 0) { + g.fillRect(SQSIZE * i, ypos, SQSIZE, SQSIZE); + } + keydelay[i] -= renderdelta; + } + Fonts.SMALLBOLD.drawString(SQSIZE * 5, ypos, this.player, color); + int y = currentFrame.getScaledY(); + if (hr) { + y = DisplayContainer.instance.height - y; + } + cursor.setCursorPosition(renderdelta, currentFrame.getScaledX(), y); + cursor.draw(false); + } + + private void processKeys() { + int keys = currentFrame.getKeys(); + int KEY_DELAY = 50; + if ((keys & 5) == 5) { + keydelay[0] = KEY_DELAY; + } + if ((keys & 10) == 10) { + keydelay[1] = KEY_DELAY; + } + if ((keys ^ 5) == 4) { + keydelay[2] = KEY_DELAY; + } + if ((keys ^ 10) == 8) { + keydelay[3] = KEY_DELAY; + } + } + +}