Refactored and reformatted code to use less static variables

This commit is contained in:
CrushedPixel
2015-04-23 14:09:54 +02:00
parent f22416be2c
commit 0003f040ed
109 changed files with 9037 additions and 10229 deletions

View File

@@ -1,113 +1,95 @@
package eu.crushedpixel.replaymod.video;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.IntBuffer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.imageio.ImageIO;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
import eu.crushedpixel.replaymod.events.TickAndRenderListener;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.shader.Framebuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.utils.ImageUtils;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class ReplayScreenshot {
private static Minecraft mc = Minecraft.getMinecraft();
private static Minecraft mc = Minecraft.getMinecraft();
private static long last_finish = -1;
private static long last_finish = -1;
private static boolean before;
private static double beforeSpeed;
private static GuiScreen beforeScreen;
private static boolean before;
private static double beforeSpeed;
private static GuiScreen beforeScreen;
private static boolean locked = false;
public static void prepareScreenshot() {
before = mc.gameSettings.hideGUI;
beforeSpeed = ReplayHandler.getSpeed();
beforeScreen = mc.currentScreen;
}
private static boolean locked = false;
public static void prepareScreenshot() {
before = mc.gameSettings.hideGUI;
beforeSpeed = ReplayMod.replaySender.getReplaySpeed();
beforeScreen = mc.currentScreen;
}
public static void saveScreenshot() {
public static void saveScreenshot() {
if(locked) return;
locked = true;
try {
GuiReplaySaving.replaySaving = true;
if(locked) return;
locked = true;
mc.gameSettings.hideGUI = true;
mc.currentScreen = null;
try {
GuiReplaySaving.replaySaving = true;
mc.entityRenderer.updateCameraAndRender(0);
ReplayHandler.setSpeed(0);
mc.gameSettings.hideGUI = true;
mc.currentScreen = null;
final BufferedImage fbi = ScreenCapture.captureScreen();
mc.entityRenderer.updateCameraAndRender(0);
ReplayMod.replaySender.setReplaySpeed(0);
mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen;
ReplayHandler.setSpeed(beforeSpeed);
final BufferedImage fbi = ScreenCapture.captureScreen();
//The actual cropping and saving should be executed in a separate thread
Thread ioThread = new Thread(new Runnable() {
mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen;
ReplayMod.replaySender.setReplaySpeed(beforeSpeed);
@Override
public void run() {
try {
float aspect = 1280f/720f;
//The actual cropping and saving should be executed in a separate thread
Thread ioThread = new Thread(new Runnable() {
Rectangle rect;
if((float)fbi.getWidth()/(float)fbi.getHeight() <= aspect) {
int h = Math.round(fbi.getWidth()/aspect);
int y = (fbi.getHeight()/2) - (h/2);
rect = new Rectangle(0, y, fbi.getWidth(), h);
} else {
int w = Math.round(fbi.getHeight()*aspect);
int x = (fbi.getWidth()/2) - (w/2);
rect = new Rectangle(x, 0, w, fbi.getHeight());
}
@Override
public void run() {
try {
float aspect = 1280f / 720f;
final BufferedImage nbi = ImageUtils.cropImage(fbi, rect);
Rectangle rect;
if((float) fbi.getWidth() / (float) fbi.getHeight() <= aspect) {
int h = Math.round(fbi.getWidth() / aspect);
int y = (fbi.getHeight() / 2) - (h / 2);
rect = new Rectangle(0, y, fbi.getWidth(), h);
} else {
int w = Math.round(fbi.getHeight() * aspect);
int x = (fbi.getWidth() / 2) - (w / 2);
rect = new Rectangle(x, 0, w, fbi.getHeight());
}
File replayFile = ReplayHandler.getReplayFile();
final BufferedImage nbi = ImageUtils.cropImage(fbi, rect);
File tempImage = File.createTempFile("thumb", null);
File replayFile = ReplayHandler.getReplayFile();
int h = 720;
int w = 1280;
File tempImage = File.createTempFile("thumb", null);
BufferedImage img = ImageUtils.scaleImage(nbi, new Dimension(w, h));
int h = 720;
int w = 1280;
ImageIO.write(img, "jpg", tempImage);
BufferedImage img = ImageUtils.scaleImage(nbi, new Dimension(w, h));
ReplayFileIO.addThumbToZip(replayFile, tempImage);
ImageIO.write(img, "jpg", tempImage);
tempImage.delete();
ReplayFileIO.addThumbToZip(replayFile, tempImage);
tempImage.delete();
/*
File outputFile = File.createTempFile(replayFile.getName(), null);
File outputFile = File.createTempFile(replayFile.getName(), null);
byte[] buf = new byte[1024];
@@ -155,31 +137,29 @@ public class ReplayScreenshot {
tempImage.delete();
*/
ChatMessageRequests.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
} catch(Exception e) {
e.printStackTrace();
}
finally {
GuiReplaySaving.replaySaving = false;
locked = false;
TickAndRenderListener.finishScreenshot();
}
}
});
ReplayMod.chatMessageHandler.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
} catch(Exception e) {
e.printStackTrace();
} finally {
GuiReplaySaving.replaySaving = false;
locked = false;
TickAndRenderListener.finishScreenshot();
}
}
});
ioThread.start();
}
catch (Exception exception) {
exception.printStackTrace();
mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen;
ReplayHandler.setSpeed(beforeSpeed);
exception.printStackTrace();
ChatMessageRequests.addChatMessage("Thumbnail could not be saved", ChatMessageType.WARNING);
}
ioThread.start();
} catch(Exception exception) {
exception.printStackTrace();
mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen;
ReplayMod.replaySender.setReplaySpeed(beforeSpeed);
exception.printStackTrace();
ReplayMod.chatMessageHandler.addChatMessage("Thumbnail could not be saved", ChatMessageType.WARNING);
}
last_finish = System.currentTimeMillis();
}
last_finish = System.currentTimeMillis();
}
}

View File

@@ -5,13 +5,13 @@ import net.minecraft.util.Timer;
public class ReplayTimer extends Timer {
public ReplayTimer(float p_i1018_1_) {
super(p_i1018_1_);
}
public ReplayTimer(float p_i1018_1_) {
super(p_i1018_1_);
}
@Override
public void updateTimer() {
if(ReplayProcess.isVideoRecording()) return;
super.updateTimer();
}
@Override
public void updateTimer() {
if(ReplayProcess.isVideoRecording()) return;
super.updateTimer();
}
}

View File

@@ -1,85 +1,73 @@
package eu.crushedpixel.replaymod.video;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.nio.IntBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.shader.Framebuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.monte.screenrecorder.ScreenRecorder;
import java.awt.image.BufferedImage;
import java.nio.IntBuffer;
public class ScreenCapture {
private static final Minecraft mc = Minecraft.getMinecraft();
private static IntBuffer pixelBuffer;
private static int[] pixelValues;
public static BufferedImage captureScreen() {
int width = mc.displayWidth;
int height = mc.displayHeight;
private static final Minecraft mc = Minecraft.getMinecraft();
Framebuffer buffer = mc.getFramebuffer();
if (OpenGlHelper.isFramebufferEnabled())
{
width = buffer.framebufferTextureWidth;
height = buffer.framebufferTextureHeight;
}
private static IntBuffer pixelBuffer;
private static int[] pixelValues;
int k = width * height;
public static BufferedImage captureScreen() {
int width = mc.displayWidth;
int height = mc.displayHeight;
if (pixelBuffer == null || pixelBuffer.capacity() < k)
{
pixelBuffer = BufferUtils.createIntBuffer(k);
pixelValues = new int[k];
}
Framebuffer buffer = mc.getFramebuffer();
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
pixelBuffer.clear();
if(OpenGlHelper.isFramebufferEnabled()) {
width = buffer.framebufferTextureWidth;
height = buffer.framebufferTextureHeight;
}
if (OpenGlHelper.isFramebufferEnabled()) {
GlStateManager.bindTexture(buffer.framebufferTexture);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
}
else {
GL11.glReadPixels(0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
}
int k = width * height;
pixelBuffer.get(pixelValues);
TextureUtil.processPixelValues(pixelValues, width, height);
BufferedImage bufferedimage = null;
if(pixelBuffer == null || pixelBuffer.capacity() < k) {
pixelBuffer = BufferUtils.createIntBuffer(k);
pixelValues = new int[k];
}
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
pixelBuffer.clear();
if(OpenGlHelper.isFramebufferEnabled()) {
GlStateManager.bindTexture(buffer.framebufferTexture);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
} else {
GL11.glReadPixels(0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
}
pixelBuffer.get(pixelValues);
TextureUtil.processPixelValues(pixelValues, width, height);
BufferedImage bufferedimage = null;
if (OpenGlHelper.isFramebufferEnabled())
{
bufferedimage = new BufferedImage(buffer.framebufferWidth, buffer.framebufferHeight, 1);
int l = buffer.framebufferTextureHeight - buffer.framebufferHeight;
if(OpenGlHelper.isFramebufferEnabled()) {
bufferedimage = new BufferedImage(buffer.framebufferWidth, buffer.framebufferHeight, 1);
int l = buffer.framebufferTextureHeight - buffer.framebufferHeight;
for (int i1 = l; i1 < buffer.framebufferTextureHeight; ++i1)
{
for (int j1 = 0; j1 < buffer.framebufferWidth; ++j1)
{
bufferedimage.setRGB(j1, i1 - l, pixelValues[i1 * buffer.framebufferTextureWidth + j1]);
}
}
}
else {
bufferedimage = new BufferedImage(width, height, 1);
bufferedimage.setRGB(0, 0, width, height, pixelValues, 0, width);
}
return bufferedimage;
}
for(int i1 = l; i1 < buffer.framebufferTextureHeight; ++i1) {
for(int j1 = 0; j1 < buffer.framebufferWidth; ++j1) {
bufferedimage.setRGB(j1, i1 - l, pixelValues[i1 * buffer.framebufferTextureWidth + j1]);
}
}
} else {
bufferedimage = new BufferedImage(width, height, 1);
bufferedimage.setRGB(0, 0, width, height, pixelValues, 0, width);
}
return bufferedimage;
}
}

View File

@@ -1,5 +1,11 @@
package eu.crushedpixel.replaymod.video;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import org.monte.media.*;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.math.Rational;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -8,140 +14,127 @@ import java.util.Calendar;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.monte.media.Buffer;
import org.monte.media.Format;
import org.monte.media.FormatKeys;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.MovieWriter;
import org.monte.media.Registry;
import org.monte.media.VideoFormatKeys;
import org.monte.media.math.Rational;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
public class VideoWriter {
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
private static final String VIDEO_EXTENSION = ".avi";
private static final String VIDEO_EXTENSION = ".avi";
private static MovieWriter out;
private static File file;
private static boolean isRecording = false;
private static boolean requestFinish = false;
private static boolean abort = false;
private static MovieWriter out;
private static File file;
private static boolean isRecording = false;
private static boolean requestFinish = false;
private static boolean abort = false;
private static Buffer buf;
private static int track;
private static Buffer buf;
private static int track;
private static Queue<BufferedImage> toWrite = new LinkedBlockingQueue<BufferedImage>();
public static boolean isRecording() {
return isRecording;
}
public static boolean isRecording() {
return isRecording;
}
public static void startRecording(int width, int height) {
if(isRecording) {
IllegalStateException up = new IllegalStateException("VideoWriter is already recording!");
throw up; //lolololo
}
isRecording = true;
public static void startRecording(int width, int height) {
if(isRecording) {
IllegalStateException up = new IllegalStateException("VideoWriter is already recording!");
throw up; //lolololo
}
isRecording = true;
toWrite = new LinkedBlockingQueue<BufferedImage>();
toWrite = new LinkedBlockingQueue<BufferedImage>();
try {
File folder = ReplayFileIO.getRenderFolder();
try {
File folder = ReplayFileIO.getRenderFolder();
String fileName = sdf.format(Calendar.getInstance().getTime());
String fileName = sdf.format(Calendar.getInstance().getTime());
file = new File(folder, fileName+VIDEO_EXTENSION);
file.createNewFile();
file = new File(folder, fileName + VIDEO_EXTENSION);
file.createNewFile();
out = Registry.getInstance().getWriter(file);
Format format = new Format(FormatKeys.MediaTypeKey, MediaType.VIDEO,
FormatKeys.EncodingKey, VideoFormatKeys.ENCODING_AVI_MJPG,
FormatKeys.FrameRateKey, new Rational(ReplayMod.replaySettings.getVideoFramerate(), 1),
VideoFormatKeys.WidthKey, width,
VideoFormatKeys.HeightKey, height,
VideoFormatKeys.DepthKey, 24,
VideoFormatKeys.QualityKey, (float)ReplayMod.replaySettings.getVideoQuality());
out = Registry.getInstance().getWriter(file);
Format format = new Format(FormatKeys.MediaTypeKey, MediaType.VIDEO,
FormatKeys.EncodingKey, VideoFormatKeys.ENCODING_AVI_MJPG,
FormatKeys.FrameRateKey, new Rational(ReplayMod.replaySettings.getVideoFramerate(), 1),
VideoFormatKeys.WidthKey, width,
VideoFormatKeys.HeightKey, height,
VideoFormatKeys.DepthKey, 24,
VideoFormatKeys.QualityKey, (float) ReplayMod.replaySettings.getVideoQuality());
track = out.addTrack(format);
track = out.addTrack(format);
buf = new Buffer();
buf.format = new Format(VideoFormatKeys.DataClassKey, BufferedImage.class);
buf.sampleDuration = out.getFormat(track).get(VideoFormatKeys.FrameRateKey).inverse();
} catch (IOException e) {
e.printStackTrace();
}
buf = new Buffer();
buf.format = new Format(VideoFormatKeys.DataClassKey, BufferedImage.class);
buf.sampleDuration = out.getFormat(track).get(VideoFormatKeys.FrameRateKey).inverse();
} catch(IOException e) {
e.printStackTrace();
}
Thread t = new Thread(new Runnable() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
if(toWrite.isEmpty() || abort) {
if(requestFinish) {
requestFinish = false;
isRecording = false;
try {
out.close();
if(abort) {
file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
abort = false;
toWrite = new LinkedBlockingQueue<BufferedImage>();
return;
}
try {
Thread.sleep(10);
} catch(Exception e) {
e.printStackTrace();
}
} else {
write();
}
}
}
});
t.start();
}
@Override
public void run() {
while(true) {
if(toWrite.isEmpty() || abort) {
if(requestFinish) {
requestFinish = false;
isRecording = false;
try {
out.close();
if(abort) {
file.delete();
}
} catch(IOException e) {
e.printStackTrace();
}
abort = false;
toWrite = new LinkedBlockingQueue<BufferedImage>();
return;
}
try {
Thread.sleep(10);
} catch(Exception e) {
e.printStackTrace();
}
} else {
write();
}
}
}
});
t.start();
}
private static Queue<BufferedImage> toWrite = new LinkedBlockingQueue<BufferedImage>();
public static void writeImage(BufferedImage image) {
if(requestFinish || !isRecording) {
IllegalStateException up = new IllegalStateException(
"The VideoWriter is currently not available. Please try again later.");
throw up; //lolololo^2
}
public static void writeImage(BufferedImage image) {
if(requestFinish || !isRecording) {
IllegalStateException up = new IllegalStateException(
"The VideoWriter is currently not available. Please try again later.");
throw up; //lolololo^2
}
toWrite.add(image);
}
toWrite.add(image);
}
public static void endRecording() {
if(!isRecording) return;
requestFinish = true;
}
public static void endRecording() {
if(!isRecording) return;
requestFinish = true;
}
private static void write() {
try {
BufferedImage img = toWrite.poll();
if(img != null) {
buf.data = img;
out.write(track, buf);
}
} catch(IOException e) {
e.printStackTrace();
}
}
private static void write() {
try {
BufferedImage img = toWrite.poll();
if(img != null) {
buf.data = img;
out.write(track, buf);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void abortRecording() {
requestFinish = true;
abort = true;
}
public static void abortRecording() {
requestFinish = true;
abort = true;
}
}