diff --git a/First Game Engine Project/res/font/font.png b/First Game Engine Project/res/font/font.png new file mode 100644 index 0000000..f614b31 Binary files /dev/null and b/First Game Engine Project/res/font/font.png differ diff --git a/First Game Engine Project/src/mrdev023/audio/Audio.java b/First Game Engine Project/src/mrdev023/audio/Audio.java new file mode 100644 index 0000000..5749740 --- /dev/null +++ b/First Game Engine Project/src/mrdev023/audio/Audio.java @@ -0,0 +1,341 @@ +package mrdev023.audio; + +import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.openal.ALC10.*; +import static org.lwjgl.openal.ALC11.*; +import static org.lwjgl.openal.ALUtil.*; +import static org.lwjgl.stb.STBVorbis.*; +import static org.lwjgl.system.MemoryUtil.*; + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; + +import javax.sound.sampled.*; + +import org.lwjgl.*; +import org.lwjgl.openal.*; + + +import org.lwjgl.stb.STBVorbisInfo; + +public class Audio { + + //Variables global + //------------------------------------------------------ + public static ALDevice device; + public static ALCCapabilities caps; + public static ALContext context; + public static final int INITIAL_STATE = 4113,PAUSED_STATE = 4115,STOPPED_STATE = 4116,PLAYING_STATE = 4114; + //------------------------------------------------------ + + //Variable de l'objet audio ou du son a lire + //------------------------------------------------------ + private int buffer,source; + private String fileName; + private String format; + //------------------------------------------------------ + + //Fonction global + //------------------------------------------------------ + public static void create(){ + device = ALDevice.create(null); + if ( device == null ) + throw new IllegalStateException("Failed to open the default device."); + caps = device.getCapabilities(); + System.out.println("---------------------------- Create Audio Device -------------------------------------"); + System.out.println("OpenALC10: " + caps.OpenALC10); + System.out.println("OpenALC11: " + caps.OpenALC11); + System.out.println("caps.ALC_EXT_EFX = " + caps.ALC_EXT_EFX); + + String defaultDeviceSpecifier = alcGetString(0L, ALC_DEFAULT_DEVICE_SPECIFIER); + System.out.println("Default device: " + defaultDeviceSpecifier); + + context = ALContext.create(device); + + System.out.println("ALC_FREQUENCY: " + alcGetInteger(device.address(), ALC_FREQUENCY) + "Hz"); + System.out.println("ALC_REFRESH: " + alcGetInteger(device.address(), ALC_REFRESH) + "Hz"); + System.out.println("ALC_SYNC: " + (alcGetInteger(device.address(), ALC_SYNC) == ALC_TRUE)); + System.out.println("ALC_MONO_SOURCES: " + alcGetInteger(device.address(), ALC_MONO_SOURCES)); + System.out.println("ALC_STEREO_SOURCES: " + alcGetInteger(device.address(), ALC_STEREO_SOURCES)); + System.out.println("---------------------------------------------------------------------------------------"); + } + + public static void destroy(){ + context.destroy(); + device.destroy(); + } + //------------------------------------------------------ + + //Fonction de l'objet audio ou du son a lire + //------------------------------------------------------ + + public Audio(String fileName) throws Exception{ + this.fileName = fileName; + setSound(); + } + + private void setSound() throws Exception{ + if(fileName.endsWith(".ogg")){ + loadOGGFormat(); + format = "OGG"; + }else if(fileName.endsWith(".wav")){ + loadWavFormat(); + format = "WAV"; + }else{ + throw new Exception("Format not supported !"); + } + alSourcei(source, AL_BUFFER, buffer); + checkALError(); + int size = alGetBufferi(buffer,AL_SIZE); + int bits = alGetBufferi(buffer, AL_BITS); + int channels = alGetBufferi(buffer, AL_CHANNELS); + int freq = alGetBufferi(buffer, AL_FREQUENCY); + System.out.println(fileName + " loaded !" + " | TIME : " + (size/channels/(bits/8)/freq) + "s | BITS : " + bits + " | CHANNELS : " + channels + " | FREQUENCE : " + freq + " FORMAT : " + format); + } + + public void loadWavFormat() throws Exception{ + AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(fileName))); + AudioFormat audioformat = ais.getFormat(); + + // get channels + int channels = 0; + if (audioformat.getChannels() == 1) { + if (audioformat.getSampleSizeInBits() == 8) { + channels = AL10.AL_FORMAT_MONO8; + } else if (audioformat.getSampleSizeInBits() == 16) { + channels = AL10.AL_FORMAT_MONO16; + } else { + assert false : "Illegal sample size"; + } + } else if (audioformat.getChannels() == 2) { + if (audioformat.getSampleSizeInBits() == 8) { + channels = AL10.AL_FORMAT_STEREO8; + } else if (audioformat.getSampleSizeInBits() == 16) { + channels = AL10.AL_FORMAT_STEREO16; + } else { + assert false : "Illegal sample size"; + } + } else { + assert false : "Only mono or stereo is supported"; + } + + int available = ais.available(); + if(available <= 0) { + available = ais.getFormat().getChannels() * (int) ais.getFrameLength() * ais.getFormat().getSampleSizeInBits() / 8; + } + byte[] buf = new byte[ais.available()]; + int read = 0, total = 0; + while ((read = ais.read(buf, total, buf.length - total)) != -1 + && total < buf.length) { + total += read; + } + byte[] audio_bytes = buf; + boolean two_bytes_data = audioformat.getSampleSizeInBits() == 16; + ByteOrder order = audioformat.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; + ByteBuffer dest = ByteBuffer.allocateDirect(audio_bytes.length); + dest.order(ByteOrder.nativeOrder()); + ByteBuffer src = ByteBuffer.wrap(audio_bytes); + src.order(order); + if (two_bytes_data) { + ShortBuffer dest_short = dest.asShortBuffer(); + ShortBuffer src_short = src.asShortBuffer(); + while (src_short.hasRemaining()) + dest_short.put(src_short.get()); + } else { + while (src.hasRemaining()) + dest.put(src.get()); + } + dest.rewind(); + + this.buffer = alGenBuffers(); + this.source = alGenSources(); + alBufferData(this.buffer, channels, dest, (int)audioformat.getSampleRate()); + dest.clear(); + } + + public void loadOGGFormat(){ + STBVorbisInfo info = STBVorbisInfo.malloc(); + ByteBuffer buff = BufferUtils.createByteBuffer(0); + //lecture du fichier + //---------------------------------------------------------------------------------------------------------------- + try { + File file = new File(fileName); + if ( file.isFile() ) { + FileInputStream fis = new FileInputStream(file); + FileChannel fc = fis.getChannel(); + buff = BufferUtils.createByteBuffer((int)fc.size() + 1); + + while ( fc.read(buff) != -1 ) ; + + fis.close(); + fc.close(); + } else { + System.err.println("File not found !"); + return; + } + + buff.flip(); + } catch (IOException e) { + throw new RuntimeException(e); + } + //---------------------------------------------------------------------------------------------------------------- + + IntBuffer error = BufferUtils.createIntBuffer(1); + long decoder = stb_vorbis_open_memory(buff, error, null); + if ( decoder == NULL ) + throw new RuntimeException("Failed to open Ogg Vorbis file. Error: " + error.get(0)); + + stb_vorbis_get_info(decoder, info); + + int channels = info.channels(); + + stb_vorbis_seek_start(decoder); + int lengthSamples = stb_vorbis_stream_length_in_samples(decoder); + + ByteBuffer pcm = BufferUtils.createByteBuffer(lengthSamples * 2 * channels); + + stb_vorbis_get_samples_short_interleaved(decoder, channels, pcm, lengthSamples); + stb_vorbis_close(decoder); + + buffer = alGenBuffers(); + checkALError(); + + source = alGenSources(); + checkALError(); + + if(channels == 1)alBufferData(buffer, AL_FORMAT_MONO16, pcm, info.sample_rate()); + else alBufferData(buffer, AL_FORMAT_STEREO16, pcm, info.sample_rate()); + checkALError(); + } + + public void playSound(){ + if(source == 0 || buffer == 0) return; + alSourcePlay(source); + } + + public int getPosition(){ + return alGetSourcei(source, AL_POSITION); + } + + public int getDurationInSeconds(){ + if(source == 0 || buffer == 0) return 0; + int size = alGetBufferi(buffer,AL_SIZE); + int bits = alGetBufferi(buffer, AL_BITS); + int channels = alGetBufferi(buffer, AL_CHANNELS); + int freq = alGetBufferi(buffer, AL_FREQUENCY); + return size/channels/(bits/8)/freq; + } + + public int getStateSound(){ + if(source == 0 || buffer == 0) return 0; + return alGetSourcei(source, AL_SOURCE_STATE); + } + + public boolean isStopped(){ + if(source == 0 || buffer == 0) return false; + if(alGetSourcei(source, AL_SOURCE_STATE) == STOPPED_STATE)return true; + else return false; + } + + public boolean isPaused(){ + if(source == 0 || buffer == 0) return false; + if(alGetSourcei(source, AL_SOURCE_STATE) == PAUSED_STATE)return true; + else return false; + } + + public boolean isPlaying(){ + if(source == 0 || buffer == 0) return false; + if(alGetSourcei(source, AL_SOURCE_STATE) == PLAYING_STATE)return true; + else return false; + } + + public boolean isInitial(){ + if(source == 0 || buffer == 0) return false; + if(alGetSourcei(source, AL_SOURCE_STATE) == INITIAL_STATE)return true; + else return false; + } + + public void stopSound(){ + if(source == 0 || buffer == 0) return; + alSourceStop(source); + } + + public void pauseSound(){ + if(source == 0 || buffer == 0) return; + alSourcePause(source); + } + + public void rewindSound(){ + if(source == 0 || buffer == 0) return; + alSourceRewind(source); + } + + public void setGain(float gain){ + if(source == 0 || buffer == 0) return; + if(gain > 1.0f)gain = 1.0f; + if(gain < 0.0f)gain = 0.0f; + alSourcef(source, AL_GAIN, gain); + } + + public void setPitch(float pitch){ + if(source == 0 || buffer == 0) return; + if(pitch < 0.0f)pitch = 0.0f; + alSourcef(source, AL_PITCH, pitch); + } + + + public float getGain(){ + if(source == 0 || buffer == 0) return 0; + return alGetSourcef(source, AL_GAIN); + } + + public float getPitch(){ + if(source == 0 || buffer == 0) return 0; + return alGetSourcef(source, AL_PITCH); + } + + public void setLooping(boolean looping){ + if(source == 0 || buffer == 0) return; + if(looping){ + alSourcef(source, AL_LOOPING, AL_TRUE); + }else{ + alSourcef(source, AL_LOOPING, AL_FALSE); + } + } + + public void destroySound(){ + alDeleteSources(source); + alDeleteBuffers(buffer); + source = 0; + buffer = 0; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) throws Exception { + this.fileName = fileName; + destroySound(); + setSound(); + } + + public int getBuffer() { + return buffer; + } + + public void setBuffer(int buffer) { + this.buffer = buffer; + } + + public int getSource() { + return source; + } + + public void setSource(int source) { + this.source = source; + } + //------------------------------------------------------ + +} diff --git a/First Game Engine Project/src/mrdev023/gameengine/GameEngine.java b/First Game Engine Project/src/mrdev023/gameengine/GameEngine.java index 23f3516..26f4bd9 100644 --- a/First Game Engine Project/src/mrdev023/gameengine/GameEngine.java +++ b/First Game Engine Project/src/mrdev023/gameengine/GameEngine.java @@ -1,7 +1,11 @@ package mrdev023.gameengine; +import java.io.*; + +import mrdev023.audio.*; import mrdev023.gameengine.gamestate.main.*; import mrdev023.network.client.*; +import mrdev023.network.common.*; import mrdev023.network.packet.*; import mrdev023.opengl.*; @@ -28,8 +32,19 @@ public class GameEngine { } public static void init(){ +// try{ +// File file = new File("/log/" + System.currentTimeMillis() + ".txt"); +// if(!file.exists()){ +// file.createNewFile(); +// } +// PrintStream out = new PrintStream(file); +// System.setOut(out); +// }catch(Exception e){e.printStackTrace();} + Input.init(); current = System.nanoTime(); state.init(); + Texture.init(); + Audio.create(); } public static void loop(){ @@ -48,6 +63,7 @@ public class GameEngine { if(elapsedTicks >= 1000000000/60){ frame.updateEvent(); + Input.update(); state.updateKeyboard(); state.updateMouse(); state.update(); @@ -83,7 +99,10 @@ public class GameEngine { public static void destroy(){ state.destroy(); + Audio.destroy(); + Input.destroy(); frame.destroy(); + MainClient.send(new ClientDisconnect(MainClient.pseudo)); MainClient.client.destroy(); } diff --git a/First Game Engine Project/src/mrdev023/gameengine/gamestate/MainState.java b/First Game Engine Project/src/mrdev023/gameengine/gamestate/MainState.java index 79cf864..8cc03ff 100644 --- a/First Game Engine Project/src/mrdev023/gameengine/gamestate/MainState.java +++ b/First Game Engine Project/src/mrdev023/gameengine/gamestate/MainState.java @@ -1,9 +1,23 @@ package mrdev023.gameengine.gamestate; +import static org.lwjgl.glfw.GLFW.*; + +import java.awt.*; +import java.util.*; + +import javax.swing.*; + +import mrdev023.gameengine.*; import mrdev023.gameengine.gamestate.main.*; +import mrdev023.network.client.*; +import mrdev023.network.packet.*; +import mrdev023.opengl.*; +import mrdev023.opengl.gui.*; public class MainState implements IGameState{ + public static ArrayList messages = new ArrayList(); + public void init() { } @@ -21,7 +35,9 @@ public class MainState implements IGameState{ } public void renderGUI() { - + for(int i = 0;i < messages.size();i++){ + messages.get(i).render(10, 10 + i * 20); + } } public void render2D() { @@ -29,11 +45,28 @@ public class MainState implements IGameState{ } public void update() { - + ArrayList rmList = new ArrayList(); + for(Message m : messages){ + if(m.isTimeOut()){ + rmList.add(m); + } + } + for(Message m : rmList){ + messages.remove(m); + } + rmList.clear(); } public void updateKeyboard() { - + if(Input.isKeyDown(GLFW_KEY_M)){ + try { + MainClient.client.send(new MessagePacket(JOptionPane.showInputDialog(null, "Entrez votre message :"),MainClient.pseudo)); + } catch (HeadlessException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } } public void updateMouse() { diff --git a/First Game Engine Project/src/mrdev023/math/Color4f.java b/First Game Engine Project/src/mrdev023/math/Color4f.java new file mode 100644 index 0000000..401fa47 --- /dev/null +++ b/First Game Engine Project/src/mrdev023/math/Color4f.java @@ -0,0 +1,77 @@ +package mrdev023.math; + +import static org.lwjgl.opengl.GL11.*; + +public class Color4f { + + public static final Color4f + RED = new Color4f(1,0,0,1), + BLUE = new Color4f(0,0,1,1), + GREEN = new Color4f(0,1,0,1), + YELLOW = new Color4f(1,1,0,1), + PURPLE = new Color4f(1,0,1,1), + CYAN = new Color4f(0,1,1,1), + BLACK = new Color4f(0,0,0,1), + WHITE = new Color4f(1,1,1,1); + + public float r,g,b,a; + + public Color4f(float r,float g,float b,float a){ + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public static Color4f mul (Color4f a, float b){ + return new Color4f(a.r * b,a.g * b,a.b * b,a.a * b); + } + + public static Color4f mul (Color4f a, Color4f b){ + return new Color4f((a.r + b.r)/2.0f,(a.g + b.g)/2.0f,(a.b + b.b)/2.0f,(a.a + b.a)/2.0f); + } + + public Color4f() { + } + + public float getR() { + return r; + } + + public void setR(float r) { + this.r = r; + } + + public float getG() { + return g; + } + + public void setG(float g) { + this.g = g; + } + + public float getB() { + return b; + } + + public void setB(float b) { + this.b = b; + } + + public float getA() { + return a; + } + + public void setA(float a) { + this.a = a; + } + + public void bind(){ + glColor4f(r,g,b,a); + } + + public void unbind(){ + BLACK.bind(); + } + +} diff --git a/First Game Engine Project/src/mrdev023/math/Mathf.java b/First Game Engine Project/src/mrdev023/math/Mathf.java new file mode 100644 index 0000000..a48a987 --- /dev/null +++ b/First Game Engine Project/src/mrdev023/math/Mathf.java @@ -0,0 +1,58 @@ +package mrdev023.math; + +public class Mathf { + + public static final float PI = (float)Math.PI; + public static final float EPSILON = 1.401298e-45f; + + public static float cos(float angle){ + return (float)Math.cos(angle); + } + + public static float acos(float angle){ + return (float)Math.acos(angle); + } + + public static float sin(float angle){ + return (float)Math.sin(angle); + } + + public static float asin(float angle){ + return (float)Math.asin(angle); + } + + public static float toRadians(float angle){ + return (float)Math.toRadians(angle); + } + + public static float toDegrees(float angle){ + return (float)Math.toDegrees(angle); + } + + public static float atan2(float a,float b){ + return (float)Math.atan2(a,b); + } + + public static float cut(float nbre,float a){ + return (float)((int)(nbre*Math.pow(10, a))/Math.pow(10, a)); + } + + public static boolean equals(float a,float b,float tolerance){ + return (a + tolerance >= b) && (a - tolerance <= b); + } + + public static float sqrt(float a){ + return (float)Math.sqrt(a); + } + + public static float clamp(float value, float min, float max) { + if(value < min){ + value = min; + } + if(value > max){ + value = max; + } + return value; + } + +} diff --git a/First Game Engine Project/src/mrdev023/math/Vector2f.java b/First Game Engine Project/src/mrdev023/math/Vector2f.java new file mode 100644 index 0000000..6d37fce --- /dev/null +++ b/First Game Engine Project/src/mrdev023/math/Vector2f.java @@ -0,0 +1,41 @@ +package mrdev023.math; + +import java.util.*; + +public class Vector2f { + + public float x,y; + + public Vector2f(){ + x = 0; + y = 0; + } + + public Vector2f(float x,float y){ + this.x = x; + this.y = y; + } + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public String toString(){ + StringJoiner st = new StringJoiner(",","vec2(",")"); + st.add("" + x); + st.add("" + y); + return st.toString(); + } +} diff --git a/First Game Engine Project/src/mrdev023/network/client/MainClient.java b/First Game Engine Project/src/mrdev023/network/client/MainClient.java index b57d7d8..4ddc522 100644 --- a/First Game Engine Project/src/mrdev023/network/client/MainClient.java +++ b/First Game Engine Project/src/mrdev023/network/client/MainClient.java @@ -15,8 +15,9 @@ public class MainClient { public static String pseudo = ""; public static void startClient() { + Register.registerClass(); try { - String input = JOptionPane.showInputDialog(null,"Entrer ip:port du serveur"); + String input = "127.0.0.1:9999";//JOptionPane.showInputDialog(null,"Entrer ip:port du serveur"); String[] i = input.split(":"); String pseudo = JOptionPane.showInputDialog(null,"Pseudo:"); client = new Client(InetAddress.getByName(i[0]),Integer.parseInt(i[1])); diff --git a/First Game Engine Project/src/mrdev023/network/common/Client.java b/First Game Engine Project/src/mrdev023/network/common/Client.java index 076037b..293374b 100644 --- a/First Game Engine Project/src/mrdev023/network/common/Client.java +++ b/First Game Engine Project/src/mrdev023/network/common/Client.java @@ -53,7 +53,7 @@ public class Client extends Thread{ DataBuffer dataBuff = new DataBuffer(); dataBuff.setData(data); try { - String name = dataBuff.getString(); + String name = Register.getClass(dataBuff.getInt()); IPacket obj = (IPacket)Class.forName(name).newInstance(); if(obj == null)continue; obj.read(dataBuff); @@ -88,7 +88,7 @@ public class Client extends Thread{ public void send(IPacket packet) throws Exception{ DataBuffer data = new DataBuffer(); - data.put(packet.getClass().getName()); + data.put(Register.getClassID(packet.getClass())); packet.write(data); DatagramPacket sendPacket = new DatagramPacket(data.getData(),data.getData().length,address,port); client.send(sendPacket); diff --git a/First Game Engine Project/src/mrdev023/network/common/Register.java b/First Game Engine Project/src/mrdev023/network/common/Register.java new file mode 100644 index 0000000..404e8a0 --- /dev/null +++ b/First Game Engine Project/src/mrdev023/network/common/Register.java @@ -0,0 +1,34 @@ +package mrdev023.network.common; + +import java.util.*; + +import mrdev023.network.packet.*; + +public class Register { + + private static ArrayList classReg = new ArrayList(); + + public static void registerClass(){ + addClass(ChangePseudoPacket.class); + addClass(ClientConnect.class); + addClass(ClientDisconnect.class); + addClass(MessagePacket.class); + addClass(MessageTestPacket.class); + addClass(OutOfSocketPacket.class); + addClass(PingClientPacket.class); + } + + public static void addClass(Class cl){ + classReg.add(cl.getName()); + } + + public static String getClass(int i){ + return classReg.get(i); + } + + public static int getClassID(Class cl){ + for(int i = 0;i < classReg.size();i++)if(cl.getName().equals(classReg.get(i)))return i; + return -1; + } + +} diff --git a/First Game Engine Project/src/mrdev023/network/packet/ClientConnect.java b/First Game Engine Project/src/mrdev023/network/packet/ClientConnect.java index b62f7bc..5c325e4 100644 --- a/First Game Engine Project/src/mrdev023/network/packet/ClientConnect.java +++ b/First Game Engine Project/src/mrdev023/network/packet/ClientConnect.java @@ -2,8 +2,10 @@ package mrdev023.network.packet; import java.net.*; +import mrdev023.gameengine.gamestate.*; import mrdev023.network.common.*; import mrdev023.network.packet.main.*; +import mrdev023.opengl.gui.*; public class ClientConnect implements IPacket{ @@ -21,7 +23,8 @@ public class ClientConnect implements IPacket{ } public void manage(Client client, IPacket packet) throws Exception { - + MainState.messages.add(new Message(pseudo + " has connected !")); + System.out.println("hello"); } public void manage(Client client, IPacket packet, DatagramSocket server) throws Exception { diff --git a/First Game Engine Project/src/mrdev023/network/packet/ClientDisconnect.java b/First Game Engine Project/src/mrdev023/network/packet/ClientDisconnect.java index 36445b4..59db0d9 100644 --- a/First Game Engine Project/src/mrdev023/network/packet/ClientDisconnect.java +++ b/First Game Engine Project/src/mrdev023/network/packet/ClientDisconnect.java @@ -2,8 +2,11 @@ package mrdev023.network.packet; import java.net.*; +import mrdev023.gameengine.gamestate.*; import mrdev023.network.common.*; import mrdev023.network.packet.main.*; +import mrdev023.network.server.*; +import mrdev023.opengl.gui.*; public class ClientDisconnect implements IPacket{ @@ -21,11 +24,14 @@ public String pseudo; } public void manage(Client client, IPacket packet) throws Exception { - + MainState.messages.add(new Message(pseudo + " has disconnected !")); } public void manage(Client client, IPacket packet, DatagramSocket server) throws Exception { - + System.out.println(client.getPseudo() + " has diconnected " + client.getAddress().getHostName() + ":" + client.getPort()); + MainServer.sendToClients(new ClientDisconnect(client.getPseudo())); + client.setRunning(false); + MainServer.clients.remove(client); } } diff --git a/First Game Engine Project/src/mrdev023/network/packet/MessagePacket.java b/First Game Engine Project/src/mrdev023/network/packet/MessagePacket.java index 95a3084..ac8afbe 100644 --- a/First Game Engine Project/src/mrdev023/network/packet/MessagePacket.java +++ b/First Game Engine Project/src/mrdev023/network/packet/MessagePacket.java @@ -2,9 +2,11 @@ package mrdev023.network.packet; import java.net.*; +import mrdev023.gameengine.gamestate.*; import mrdev023.network.common.*; import mrdev023.network.packet.main.*; import mrdev023.network.server.*; +import mrdev023.opengl.gui.*; public class MessagePacket implements IPacket{ @@ -25,7 +27,7 @@ public class MessagePacket implements IPacket{ } public void manage(Client client, IPacket packet) throws Exception { - System.out.println(pseudo + ": " + message); + MainState.messages.add(new Message(pseudo + " : " + message)); } public void manage(Client client, IPacket packet, DatagramSocket server) throws Exception { diff --git a/First Game Engine Project/src/mrdev023/network/packet/OutOfSocketPacket.java b/First Game Engine Project/src/mrdev023/network/packet/OutOfSocketPacket.java index 06f6934..ddc2626 100644 --- a/First Game Engine Project/src/mrdev023/network/packet/OutOfSocketPacket.java +++ b/First Game Engine Project/src/mrdev023/network/packet/OutOfSocketPacket.java @@ -4,6 +4,7 @@ import java.net.*; import javax.swing.*; +import mrdev023.gameengine.*; import mrdev023.network.common.*; import mrdev023.network.packet.main.*; @@ -19,8 +20,7 @@ public class OutOfSocketPacket implements IPacket{ public void manage(Client client, IPacket packet) throws Exception { JOptionPane.showMessageDialog(null,"OutOfSocket","Error",JOptionPane.ERROR_MESSAGE); - client.setRunning(false); - System.exit(0); + GameEngine.setRunning(false); } public void manage(Client client, IPacket packet, DatagramSocket server) throws Exception { diff --git a/First Game Engine Project/src/mrdev023/network/server/MainServer.java b/First Game Engine Project/src/mrdev023/network/server/MainServer.java index 217c5ff..d0f1162 100644 --- a/First Game Engine Project/src/mrdev023/network/server/MainServer.java +++ b/First Game Engine Project/src/mrdev023/network/server/MainServer.java @@ -40,6 +40,7 @@ public class MainServer extends Thread{ server = new DatagramSocket(9999); System.out.println("Server binding " + InetAddress.getLocalHost().getHostAddress() + ":" + PORT); isRunning = true; + Register.registerClass(); (new Thread(new MainServer())).start(); while(isRunning){ byte[] data = new byte[DataBuffer.SIZE]; @@ -49,7 +50,7 @@ public class MainServer extends Thread{ if(p.getAddress() != null){ DataBuffer buffer = new DataBuffer(); buffer.setData(data); - IPacket packet = (IPacket)Class.forName(buffer.getString()).newInstance(); + IPacket packet = (IPacket)Class.forName(Register.getClass(buffer.getInt())).newInstance(); packet.read(buffer); Client c = getClient(p.getAddress(), p.getPort()); if(c == null){ @@ -112,7 +113,7 @@ public class MainServer extends Thread{ public static void send(IPacket packet,InetAddress ip,int port){ try { DataBuffer buffer = new DataBuffer(); - buffer.put(packet.getClass().getName()); + buffer.put(Register.getClassID(packet.getClass())); packet.write(buffer); DatagramPacket p = new DatagramPacket(buffer.getData(), buffer.getData().length,ip,port); server.send(p); diff --git a/First Game Engine Project/src/mrdev023/opengl/DisplayManager.java b/First Game Engine Project/src/mrdev023/opengl/DisplayManager.java index eacc035..83eacda 100644 --- a/First Game Engine Project/src/mrdev023/opengl/DisplayManager.java +++ b/First Game Engine Project/src/mrdev023/opengl/DisplayManager.java @@ -1,25 +1,44 @@ package mrdev023.opengl; +import mrdev023.gameengine.*; +import static org.lwjgl.opengl.GL11.*; + public class DisplayManager { public static void clear(){ - + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } public static void preRender2D(){ - + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, GameEngine.getFrame().getWidth(), 0, GameEngine.getFrame().getHeight(), -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glEnable(GL_TEXTURE_2D); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GameEngine.getGameState().preRender2D(); } public static void preRenderGUI(){ - + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, GameEngine.getFrame().getWidth(), 0, GameEngine.getFrame().getHeight(), -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glEnable(GL_TEXTURE_2D); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GameEngine.getGameState().preRenderGUI(); } public static void render2D(){ - + GameEngine.getGameState().render2D(); } public static void renderGUI(){ - + GameEngine.getGameState().renderGUI(); } } diff --git a/First Game Engine Project/src/mrdev023/opengl/Frame.java b/First Game Engine Project/src/mrdev023/opengl/Frame.java index d90db22..8763658 100644 --- a/First Game Engine Project/src/mrdev023/opengl/Frame.java +++ b/First Game Engine Project/src/mrdev023/opengl/Frame.java @@ -36,7 +36,7 @@ public class Frame { //definie la sortie d'erreur errorCallback = new GLFWErrorCallback() { public void invoke(int error, long description) { - System.err.println("ID : " + error + " | Description :" + description); + //System.err.println("ID : " + error + " | Description :" + description); } }; glfwSetErrorCallback(errorCallback); @@ -94,7 +94,7 @@ public class Frame { //definie la sortie d'erreur errorCallback = new GLFWErrorCallback() { public void invoke(int error, long description) { - System.err.println("ID : " + error + " | Description :" + description); + //System.err.println("ID : " + error + " | Description :" + description); } }; glfwSetErrorCallback(errorCallback); diff --git a/First Game Engine Project/src/mrdev023/opengl/Input.java b/First Game Engine Project/src/mrdev023/opengl/Input.java new file mode 100644 index 0000000..880436d --- /dev/null +++ b/First Game Engine Project/src/mrdev023/opengl/Input.java @@ -0,0 +1,245 @@ +package mrdev023.opengl; + +import static org.lwjgl.glfw.GLFW.*; + +import java.util.*; +import java.util.Map.*; + +import org.lwjgl.glfw.*; + +import mrdev023.gameengine.*; +import mrdev023.math.*; +import mrdev023.opengl.*; + +public class Input{ + + public static GLFWScrollCallback scroll; + public static GLFWCursorPosCallback mousePos; + + private static Vector2f mousePosition = new Vector2f(); + private static Vector2f dMouse = new Vector2f(); + private static Vector2f previousDMouse = new Vector2f(); + + public static final int NONE = 0,PRESSED = 1,RELEASED = 2,REPEATED = 3,UP = 2,DOWN = 1, + NBRE_KEY = 0x15D,NBRE_BUTTON = 10, + MOUSE_OFFSET = NBRE_KEY + 1,MOUSE_WHEEL_OFFSET = MOUSE_OFFSET + NBRE_BUTTON + 1; + + private static HashMap state = new HashMap(); + + private static double ywheel = 0; + + public static void init(){ + glfwSetScrollCallback(GameEngine.getFrame().getWindowID(), scroll = new GLFWScrollCallback() { + public void invoke(long window, double xoffset, double yoffset) { + scroll(window, xoffset, yoffset); + } + }); + glfwSetCursorPosCallback(GameEngine.getFrame().getWindowID(), mousePos = new GLFWCursorPosCallback() { + public void invoke(long window, double xpos, double ypos) { + mousepos(window, xpos, ypos); + } + }); + for(int i = 0;i < NBRE_KEY;i++){ + state.put(i, NONE); + } + for(int i = 0;i < NBRE_BUTTON;i++){ + state.put(i + MOUSE_OFFSET, NONE); + } + state.put(MOUSE_WHEEL_OFFSET, NONE); + } + + public static void update(){ + for(Entry set : state.entrySet()){ + int i = set.getKey(); + int st = set.getValue(); + if(i > -1 && i < NBRE_KEY){ + if(glfwGetKey(GameEngine.getFrame().getWindowID(), i) == 0 && st == NONE)continue; + if(glfwGetKey(GameEngine.getFrame().getWindowID(), i) == 1 && st == NONE){ + state.replace(i, PRESSED); + }else if(glfwGetKey(GameEngine.getFrame().getWindowID(), i) == 1 && st == PRESSED){ + state.replace(i, REPEATED); + }else if(glfwGetKey(GameEngine.getFrame().getWindowID(), i) == 0 && (st == PRESSED || st == REPEATED)){ + state.replace(i, RELEASED); + }else if(glfwGetKey(GameEngine.getFrame().getWindowID(), i) == 0 && st == RELEASED){ + state.replace(i, NONE); + } + }else if(i >= MOUSE_OFFSET && i < MOUSE_OFFSET + NBRE_BUTTON){ + if(glfwGetMouseButton(GameEngine.getFrame().getWindowID(), i - MOUSE_OFFSET) == 0 && st == NONE)continue; + if(glfwGetMouseButton(GameEngine.getFrame().getWindowID(), i - MOUSE_OFFSET) == 1 && st == NONE){ + state.replace(i, PRESSED); + }else if(glfwGetMouseButton(GameEngine.getFrame().getWindowID(), i - MOUSE_OFFSET) == 1 && st == PRESSED){ + state.replace(i, REPEATED); + }else if(glfwGetMouseButton(GameEngine.getFrame().getWindowID(), i - MOUSE_OFFSET) == 0 && (st == PRESSED || st == REPEATED)){ + state.replace(i, RELEASED); + }else if(glfwGetMouseButton(GameEngine.getFrame().getWindowID(), i - MOUSE_OFFSET) == 0 && st == RELEASED){ + state.replace(i, NONE); + } + } + } + int st = state.get(MOUSE_WHEEL_OFFSET); + if(ywheel > 0 && (st == NONE || st == UP)){ + state.replace(MOUSE_WHEEL_OFFSET, UP); + }else if(ywheel < 0 && (st == NONE || st == DOWN)){ + state.replace(MOUSE_WHEEL_OFFSET, DOWN); + }else if(ywheel == 0 && (st == DOWN || st == UP)){ + state.replace(MOUSE_WHEEL_OFFSET, NONE); + } + ywheel = 0; + if(dMouse.equals(previousDMouse)){ + dMouse = new Vector2f(); + }else{ + previousDMouse = dMouse; + } + } + + public static void destroy(){ + mousePos.release(); + scroll.release(); + } + + public static void scroll(long window, double xoffset, double yoffset) { + ywheel = yoffset; + } + + public static void mousepos(long window, double xpos, double ypos) { + dMouse.x = (float) (xpos - mousePosition.x); + dMouse.y = (float) (ypos - mousePosition.y); + mousePosition.x = (float) xpos; + mousePosition.y = (float) ypos; + } + + public static boolean isButtonDown(int button){ + return state.get(button + MOUSE_OFFSET) == PRESSED; + } + + public static boolean isButtonUp(int button){ + return state.get(button + MOUSE_OFFSET) == RELEASED; + } + + public static boolean isButton(int button){ + return state.get(button + MOUSE_OFFSET) == PRESSED || state.get(button + MOUSE_OFFSET) == REPEATED; + } + + public static int isButtonState(int button){ + return state.get(button + MOUSE_OFFSET); + } + + public static boolean isKeyDown(int key){ + return state.get(key) == PRESSED; + } + + public static boolean isKeyUp(int key){ + return state.get(key) == RELEASED; + } + + public static boolean isKey(int key){ + return state.get(key) == PRESSED || state.get(key) == REPEATED; + } + + public static int isKeyState(int key){ + return state.get(key); + } + + public static int isMouseWheelState(){ + return state.get(MOUSE_WHEEL_OFFSET); + } + + public static boolean isMouseWheelUp(){ + return state.get(MOUSE_WHEEL_OFFSET) == UP; + } + + public static boolean isMouseWheelDown(){ + return state.get(MOUSE_WHEEL_OFFSET) == DOWN; + } + + public static GLFWScrollCallback getScroll() { + return scroll; + } + + public static void setScroll(GLFWScrollCallback scroll) { + Input.scroll = scroll; + } + + public static GLFWCursorPosCallback getMousePos() { + return mousePos; + } + + public static void setMousePos(GLFWCursorPosCallback mousePos) { + Input.mousePos = mousePos; + } + + public static Vector2f getMousePosition() { + return mousePosition; + } + + public static void setMousePosition(Vector2f mousePosition) { + Input.mousePosition = mousePosition; + } + + public static Vector2f getDMouse() { + return dMouse; + } + + public static void setDMouse(Vector2f dMouse) { + Input.dMouse = dMouse; + } + + public static HashMap getState() { + return state; + } + + public static void setState(HashMap state) { + Input.state = state; + } + + public static double getYwheel() { + return ywheel; + } + + public static void setYwheel(double ywheel) { + Input.ywheel = ywheel; + } + + public static int getNone() { + return NONE; + } + + public static int getPressed() { + return PRESSED; + } + + public static int getReleased() { + return RELEASED; + } + + public static int getRepeated() { + return REPEATED; + } + + public static int getUp() { + return UP; + } + + public static int getDown() { + return DOWN; + } + + public static int getNbreKey() { + return NBRE_KEY; + } + + public static int getNbreButton() { + return NBRE_BUTTON; + } + + public static int getMouseOffset() { + return MOUSE_OFFSET; + } + + public static int getMouseWheelOffset() { + return MOUSE_WHEEL_OFFSET; + } + + + +} diff --git a/First Game Engine Project/src/mrdev023/opengl/TextFont.java b/First Game Engine Project/src/mrdev023/opengl/TextFont.java new file mode 100644 index 0000000..242850d --- /dev/null +++ b/First Game Engine Project/src/mrdev023/opengl/TextFont.java @@ -0,0 +1,41 @@ +package mrdev023.opengl; + +import static org.lwjgl.opengl.GL11.*; + +public class TextFont { + + public static final String font = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "+ + "0123456789.,!?'\"-+=/\\%()<>:; "; + + public static void drawText(String title,int x,int y,int size,float alpha){ + int id = 0; + title = title.toUpperCase(); + glBindTexture(GL_TEXTURE_2D,Texture.FONT.getID()); + glBegin(GL_QUADS); + for(int i = 0;i < title.length();i++){ + id = font.indexOf(title.charAt(i)); + int xx = x + size * i; + int yy = y; + int ty = (id >= 32)?1:0; + int tx = id % 32; + + glColor4f(1,1,1,alpha); + + glTexCoord2f((0 + tx)/32.0f, (0 + ty)/2.0f); + glVertex2i(xx,yy + size); + + glTexCoord2f((1 + tx)/32.0f, (0 + ty)/2.0f); + glVertex2i(xx + size,yy + size); + + glTexCoord2f((1 + tx)/32.0f, (1 + ty)/2.0f); + glVertex2i(xx + size,yy); + + glTexCoord2f((0 + tx)/32.0f, (1 + ty)/2.0f); + glVertex2i(xx,yy); + + } + glEnd(); + glBindTexture(GL_TEXTURE_2D,0); + } + +} diff --git a/First Game Engine Project/src/mrdev023/opengl/Texture.java b/First Game Engine Project/src/mrdev023/opengl/Texture.java new file mode 100644 index 0000000..dc7fa3d --- /dev/null +++ b/First Game Engine Project/src/mrdev023/opengl/Texture.java @@ -0,0 +1,99 @@ +package mrdev023.opengl; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL12.*; + +import java.awt.image.*; +import java.io.*; +import java.nio.*; + +import javax.imageio.*; + +import org.lwjgl.*; + +public class Texture { + + public static Texture FONT; + + int width, height; + int id; + + public static void init() { + System.out.println("---------------------------- Load Texture --------------------------------------------"); + FONT = Texture.loadTexture("res/font/font.png"); + System.out.println("--------------------------------------------------------------------------------------"); + } + + public Texture(int width,int height,int id){ + this.id = id; + this.width = width; + this.height = height; + } + + public static Texture loadTexture(String path){ + try { + BufferedImage image = ImageIO.read(new File(path)); + int width = image.getWidth(); + int height = image.getHeight(); + int[] pixels = new int[width * height]; + + image.getRGB(0, 0, width, height, pixels, 0,width); + + int[] data = new int[pixels.length]; + for (int i = 0; i < data.length; i++) { + int a = (pixels[i] & 0xff000000) >> 24; + int r = (pixels[i] & 0xff0000) >> 16; + int g = (pixels[i] & 0xff00) >> 8; + int b = (pixels[i] & 0xff); + + data[i] = a << 24 | b << 16 | g << 8 | r; + } + + IntBuffer buffer = BufferUtils.createIntBuffer(data.length); + buffer.put(data); + buffer.flip(); + + int id = glGenTextures(); + glBindTexture(GL_TEXTURE_2D, id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + glBindTexture(GL_TEXTURE_2D, 0); + + System.out.println("Texture loaded ! " + width + "x" + height + " id:" + id); + + return new Texture(width, height, id); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getID(){ + return id; + } + + public void bind(){ + glBindTexture(GL_TEXTURE_2D, id); + } + + public void unbind(){ + glBindTexture(GL_TEXTURE_2D, 0); + } + + +} diff --git a/First Game Engine Project/src/mrdev023/opengl/gui/Message.java b/First Game Engine Project/src/mrdev023/opengl/gui/Message.java new file mode 100644 index 0000000..c658620 --- /dev/null +++ b/First Game Engine Project/src/mrdev023/opengl/gui/Message.java @@ -0,0 +1,34 @@ +package mrdev023.opengl.gui; + +import mrdev023.opengl.*; + +public class Message { + + public static final int TIME_OUT = 5000; + private long current, previous, time = 0; + private String message; + + + public Message(String message){ + current = System.currentTimeMillis(); + this.message = message; + } + + public void render(int x,int y){ + previous = current; + current = System.currentTimeMillis(); + time += current - previous; + + if(time < TIME_OUT - 1000){ + TextFont.drawText(message, x, y, 16, 1); + }else{ + TextFont.drawText(message, x, y, 16, (TIME_OUT - time)/1000f); + } + + } + + public boolean isTimeOut(){ + return time > TIME_OUT; + } + +}