package vazkii.minetunes.player; import java.awt.Color; import java.awt.Point; import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import vazkii.minetunes.MineTunes; import vazkii.minetunes.config.MTConfig; import vazkii.minetunes.gui.GuiMoveHUD; import vazkii.minetunes.playlist.MP3Metadata; public final class HUDHandler { public static boolean showVolume = false; private float[] oldFFT = new float[SpectrumTools.BANDS]; @SubscribeEvent public void onDrawScreen(RenderGameOverlayEvent.Post event) { if(event.getType() == ElementType.ALL && MTConfig.hudEnabled) { Minecraft mc = Minecraft.getMinecraft(); int width = event.getResolution().getScaledWidth(); int height = event.getResolution().getScaledHeight(); Point coords = getCoords(width, height, MTConfig.hudRelativeTo, MTConfig.hudPosX, MTConfig.hudPosY); if(MineTunes.musicPlayerThread != null && MineTunes.musicPlayerThread.player != null && MineTunes.musicPlayerThread.playingMP3 != null) { MP3Metadata meta = MineTunes.musicPlayerThread.playingMP3; boolean rightSide = MTConfig.hudRelativeTo == 0 || MTConfig.hudRelativeTo == 3; boolean topSide = MTConfig.hudRelativeTo == 0 || MTConfig.hudRelativeTo == 1; String note = MineTunes.musicPlayerThread.paused ? "\u258E\u258E" : "\u266C"; int noteWidth = mc.fontRendererObj.getStringWidth(note) * 2; int noteSpace = 4; String time = MP3Metadata.getLengthStr((int) ((double) meta.lengthMs - (double) meta.lengthMs * MineTunes.musicPlayerThread.getFractionPlayed())); String title = meta.title + " (" + time + ")"; String artist = meta.artist; String volume = showVolume ? I18n.format("minetunes.gui.volume", "+" + (int) (MineTunes.musicPlayerThread.getRelativeVolume() * 100) + "%") : ""; int padding = 4; int titleWidth = mc.fontRendererObj.getStringWidth(title); int artistWidth = mc.fontRendererObj.getStringWidth(artist); int volumeWidth = mc.fontRendererObj.getStringWidth(volume); int textWidth = Math.max(titleWidth, Math.max(artistWidth, volumeWidth)); int hudWidth = textWidth + noteWidth + noteSpace + padding * 2; int hudHeight = (showVolume ? 30 : 20) + padding * 2; int x = coords.x; int y = coords.y; if(rightSide) x -= hudWidth; if(x < 0) x = padding; if(y < 0) y = 0; int xf = x + hudWidth; int yf = y + hudHeight; if(xf > width) x -= (xf - width); if(yf > height) y -= (yf - height); Color color = Color.getHSBColor((float) (System.currentTimeMillis() % 5000) / 5000F, 1F, 1F); int noteX = x + padding + (rightSide ? textWidth + noteSpace : 0); int noteY = y + padding; int noteColor = color.getRGB(); GL11.glPushMatrix(); GL11.glScalef(2F, 2F, 2F); GL11.glTranslatef((float) noteX / 2, (float) noteY / 2, 0F); GL11.glTranslatef(0.5F, 0.5F, 0F); mc.fontRendererObj.drawString(note, 0, 0, color.darker().darker().getRGB()); GL11.glTranslatef(-0.5F, -0.5F, 0F); mc.fontRendererObj.drawString(note, 0, 0, noteColor); GL11.glPopMatrix(); int diffTitle = 0; int diffArtist = 0; int diffVolume = 0; int textLeft = x + padding + (rightSide ? 0 : noteWidth + noteSpace); int spectrumLeft = textLeft; int spaceWidth = SpectrumTools.BANDS - 1; int minWidth = 2 * SpectrumTools.BANDS + spaceWidth; int maxWidth = 16 * SpectrumTools.BANDS; int spectrumWidth = Math.min(maxWidth, Math.max(minWidth, textWidth * 2 - spaceWidth)); if(rightSide) { diffTitle = textWidth - titleWidth; diffArtist = textWidth - artistWidth; diffVolume = textWidth - volumeWidth; spectrumLeft += textWidth - spectrumWidth / 2; } renderSpectrumAnalyzer(mc, spectrumLeft, y + padding + 20, spectrumWidth, 150, noteColor, topSide); mc.fontRendererObj.drawStringWithShadow(title, textLeft + diffTitle, y + padding, 0xFFFFFF); mc.fontRendererObj.drawStringWithShadow(artist, textLeft + diffArtist, y + 10 + padding, 0xDDDDDD); if(showVolume) mc.fontRendererObj.drawStringWithShadow(volume, textLeft + diffVolume, y + 20 + padding, 0xDDDDDD); } } } // Adapted from kjdsp // https://code.google.com/p/libkj-java/ private void renderSpectrumAnalyzer(Minecraft mc, int x, int y, int width, int height, int color, boolean invert) { float[] wFFT = SpectrumTools.getFFTCalculation(); if(wFFT == null) return; x += width / 2; int bandWidth = (int) ((float) width / (float) SpectrumTools.FFT_SAMPLE_SIZE); float multiplier = (SpectrumTools.FFT_SAMPLE_SIZE / 2) / SpectrumTools.BANDS; int alpha = 128; int lightColor = color + (alpha << 24); int darkColor = new Color(lightColor).darker().getRGB() + (alpha << 24); for(int i = 0; i < SpectrumTools.BANDS; i++) { float wFs = 0; // -- Average out nearest bands. for(int j = 0; j < multiplier; j++) wFs += wFFT[i + j]; // -- Log filter. wFs = (wFs * (float) Math.log(i + 2)); if(wFs > 1.0f) wFs = 1.0f; wFs *= 6; // -- Compute SA decay... if(wFs >= (oldFFT[i] - SpectrumTools.DECAY)) oldFFT[i] = wFs; else { oldFFT[i] -= SpectrumTools.DECAY; if(oldFFT[i] < 0) oldFFT[i] = 0; wFs = oldFFT[i]; } int bHeight = Math.min(60, (int) ((float) height * wFs) + 1); GlStateManager.pushMatrix(); GlStateManager.scale(0.5, 0.5, 0.5); if(invert) Gui.drawRect(x * 2, y * 2 - 40, x * 2 + bandWidth * 2, y * 2 - 40 + bHeight, i % 2 == 0 ? lightColor : darkColor); else Gui.drawRect(x * 2, y * 2 - bHeight, x * 2 + bandWidth * 2, y * 2, i % 2 == 0 ? lightColor : darkColor); GlStateManager.popMatrix(); x -= (bandWidth + 1); } } private static boolean shouldRenderHUD() { Minecraft mc = Minecraft.getMinecraft(); if(mc.currentScreen != null && mc.currentScreen instanceof GuiMoveHUD) return true; return MTConfig.hudEnabled; } public static Point getCoords(int screenX, int screenY, int relativePos, int posX, int posY) { switch(relativePos) { case 0 : return new Point(screenX - posX, posY); case 1 : return new Point(posX, posY); case 2 : return new Point(posX, screenY - posY); default : return new Point(screenX - posX, screenY - posY); } } }