merge
authorkoda
Wed, 10 Jan 2018 15:27:47 +0100
changeset 12889 8f99199b33ea
parent 12886 a089326f0e16 (diff)
parent 12888 41d147eb26ea (current diff)
child 12891 856570ddd409
merge
CMakeLists.txt
--- a/CMakeLists.txt	Wed Jan 10 01:39:10 2018 +0100
+++ b/CMakeLists.txt	Wed Jan 10 15:27:47 2018 +0100
@@ -80,8 +80,8 @@
 #versioning
 set(CPACK_PACKAGE_VERSION_MAJOR 0)
 set(CPACK_PACKAGE_VERSION_MINOR 9)
-set(CPACK_PACKAGE_VERSION_PATCH 23)
-set(HEDGEWARS_PROTO_VER 53)
+set(CPACK_PACKAGE_VERSION_PATCH 24)
+set(HEDGEWARS_PROTO_VER 54)
 set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
 include(${CMAKE_MODULE_PATH}/revinfo.cmake)
 
--- a/gameServer2/src/main.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/main.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -11,7 +11,7 @@
 //use std::io::*;
 //use rand::Rng;
 //use std::cmp::Ordering;
-use mio::tcp::*;
+use mio::net::*;
 use mio::*;
 
 mod utils;
@@ -36,24 +36,24 @@
         poll.poll(&mut events, None).unwrap();
 
         for event in events.iter() {
-            if event.kind().is_readable() {
+            if event.readiness() & Ready::readable() == Ready::readable() {
                 match event.token() {
                     utils::SERVER => server.accept(&poll).unwrap(),
-                    tok => server.client_readable(&poll, tok).unwrap(),
+                    Token(tok) => server.client_readable(&poll, tok).unwrap(),
                 }
             }
-            if event.kind().is_writable() {
+            if event.readiness() & Ready::writable() == Ready::writable() {
                 match event.token() {
                     utils::SERVER => unreachable!(),
-                    tok => server.client_writable(&poll, tok).unwrap(),
+                    Token(tok) => server.client_writable(&poll, tok).unwrap(),
                 }
             }
-            if event.kind().is_hup() || event.kind().is_error() {
-                match event.token() {
-                    utils::SERVER => unreachable!(),
-                    tok => server.client_error(&poll, tok).unwrap(),
-                }
-            }
+//            if event.kind().is_hup() || event.kind().is_error() {
+//                match event.token() {
+//                    utils::SERVER => unreachable!(),
+//                    Token(tok) => server.client_error(&poll, tok).unwrap(),
+//                }
+//            }
         }
     }
 }
--- a/gameServer2/src/server/actions.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/actions.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -22,12 +22,12 @@
 
 use self::Action::*;
 
-pub fn run_action(server: &mut HWServer, token: mio::Token, poll: &mio::Poll, action: Action) {
+pub fn run_action(server: &mut HWServer, token: usize, poll: &mio::Poll, action: Action) {
     match action {
         SendMe(msg) =>
             server.send(token, &msg),
         SendAllButMe(msg) => {
-            for c in server.clients.iter_mut() {
+            for (_i, c) in server.clients.iter_mut() {
                 if c.id != token {
                     c.send_string(&msg)
                 }
@@ -57,7 +57,7 @@
             let joined_msg;
             {
                 let mut lobby_nicks: Vec<&str> = Vec::new();
-                for c in server.clients.iter() {
+                for (_, c) in server.clients.iter() {
                     if c.room_id.is_some() {
                         lobby_nicks.push(&c.nick);
                     }
@@ -71,7 +71,7 @@
                 ]);
         },
         AddRoom(name, password) => {
-            let room_id = server.rooms.insert(HWRoom::new()).ok().expect("Cannot add room");
+            let room_id = server.rooms.insert(HWRoom::new());
             {
                 let r = &mut server.rooms[room_id];
                 let c = &mut server.clients[token];
--- a/gameServer2/src/server/client.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/client.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,4 +1,4 @@
-use mio::tcp::*;
+use mio::net::TcpStream;
 use mio::*;
 use std::io::Write;
 use std::io;
@@ -15,8 +15,8 @@
     decoder: ProtocolDecoder,
     buf_out: netbuf::Buf,
 
-    pub id: Token,
-    pub room_id: Option<Token>,
+    pub id: usize,
+    pub room_id: Option<usize>,
     pub nick: String,
     pub protocol_number: u32,
     pub is_master: bool,
@@ -31,7 +31,7 @@
             decoder: ProtocolDecoder::new(),
             buf_out: netbuf::Buf::new(),
             room_id: None,
-            id: Token(0),
+            id: 0,
 
             nick: String::new(),
             protocol_number: 0,
@@ -42,7 +42,7 @@
     }
 
     pub fn register(&mut self, poll: &Poll, token: Token) {
-        poll.register(&self.sock, token, Ready::all(),
+        poll.register(&self.sock, token, Ready::readable() | Ready::writable(),
                       PollOpt::edge())
             .ok().expect("could not register socket with event loop");
 
@@ -72,7 +72,7 @@
         self.sock.flush();
     }
 
-    pub fn readable(&mut self, poll: &Poll) -> Vec<Action> {
+    pub fn readable(&mut self, _poll: &Poll) -> Vec<Action> {
         let v = self.decoder.read_from(&mut self.sock).unwrap();
         debug!("Read {} bytes", v);
         let mut response = Vec::new();
@@ -85,13 +85,13 @@
         response
     }
 
-    pub fn writable(&mut self, poll: &Poll) -> io::Result<()> {
+    pub fn writable(&mut self, _poll: &Poll) -> io::Result<()> {
         self.buf_out.write_to(&mut self.sock)?;
 
         Ok(())
     }
 
-    pub fn error(&mut self, poll: &Poll) -> Vec<Action> {
+    pub fn error(&mut self, _poll: &Poll) -> Vec<Action> {
         return vec![ByeClient("Connection reset".to_string())]
     }
 }
--- a/gameServer2/src/server/handlers/inroom.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/handlers/inroom.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -6,7 +6,7 @@
 use protocol::messages::HWProtocolMessage;
 use protocol::messages::HWServerMessage::*;
 
-pub fn handle(server: &mut HWServer, token: mio::Token, poll: &mio::Poll, message: HWProtocolMessage) {
+pub fn handle(server: &mut HWServer, token: usize, _poll: &mio::Poll, message: HWProtocolMessage) {
     match message {
         _ => warn!("Unimplemented!"),
     }
--- a/gameServer2/src/server/handlers/lobby.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/handlers/lobby.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -6,14 +6,14 @@
 use protocol::messages::HWProtocolMessage;
 use protocol::messages::HWServerMessage::*;
 
-pub fn handle(server: &mut HWServer, token: mio::Token, poll: &mio::Poll, message: HWProtocolMessage) {
+pub fn handle(server: &mut HWServer, token: usize, poll: &mio::Poll, message: HWProtocolMessage) {
     match message {
         HWProtocolMessage::Chat(msg) => {
             let chat_msg = ChatMsg(&server.clients[token].nick, &msg).to_raw_protocol();
             server.react(token, poll, vec![SendAllButMe(chat_msg)]);
         },
         HWProtocolMessage::CreateRoom(name, password) => {
-            let room_exists = server.rooms.iter().find(|&r| r.name == name).is_some();
+            let room_exists = server.rooms.iter().find(|&(_, r)| r.name == name).is_some();
             if room_exists {
                 server.react(token, poll, vec![Warn("Room exists".to_string())]);
             } else {
--- a/gameServer2/src/server/handlers/loggingin.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/handlers/loggingin.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -6,7 +6,7 @@
 use protocol::messages::HWProtocolMessage;
 use protocol::messages::HWServerMessage::*;
 
-pub fn handle(server: &mut HWServer, token: mio::Token, poll: &mio::Poll, message: HWProtocolMessage) {
+pub fn handle(server: &mut HWServer, token: usize, poll: &mio::Poll, message: HWProtocolMessage) {
     match message {
         HWProtocolMessage::Nick(nick) =>
             if server.clients[token].room_id == None {
--- a/gameServer2/src/server/handlers/mod.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/handlers/mod.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -12,7 +12,7 @@
 mod lobby;
 mod inroom;
 
-pub fn handle(server: &mut HWServer, token: mio::Token, poll: &mio::Poll, message: HWProtocolMessage) {
+pub fn handle(server: &mut HWServer, token: usize, poll: &mio::Poll, message: HWProtocolMessage) {
     match message {
         HWProtocolMessage::Ping =>
             server.react(token, poll, vec![SendMe(Pong.to_raw_protocol())]),
--- a/gameServer2/src/server/server.rs	Wed Jan 10 01:39:10 2018 +0100
+++ b/gameServer2/src/server/server.rs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,5 +1,5 @@
 use slab;
-use mio::tcp::*;
+use mio::net::*;
 use mio::*;
 use std::io;
 
@@ -7,19 +7,19 @@
 use super::client::HWClient;
 use super::actions;
 
-type Slab<T> = slab::Slab<T, Token>;
+type Slab<T> = slab::Slab<T>;
 
 pub struct HWServer {
     listener: TcpListener,
     pub clients: Slab<HWClient>,
     pub rooms: Slab<HWRoom>,
-    pub lobby_id: Token,
+    pub lobby_id: usize,
 }
 
 impl HWServer {
     pub fn new(listener: TcpListener, clients_limit: usize, rooms_limit: usize) -> HWServer {
         let mut rooms = Slab::with_capacity(rooms_limit);
-        let token = rooms.insert(HWRoom::new()).ok().expect("Cannot create lobby");
+        let token = rooms.insert(HWRoom::new());
         HWServer {
             listener: listener,
             clients: Slab::with_capacity(clients_limit),
@@ -38,17 +38,16 @@
         info!("Connected: {}", addr);
 
         let client = HWClient::new(sock);
-        let token = self.clients.insert(client)
-            .ok().expect("could not add connection to slab");
+        let token = self.clients.insert(client);
 
         self.clients[token].id = token;
-        self.clients[token].register(poll, token);
+        self.clients[token].register(poll, Token(token));
 
         Ok(())
     }
 
     pub fn client_readable(&mut self, poll: &Poll,
-                           token: Token) -> io::Result<()> {
+                           token: usize) -> io::Result<()> {
         let actions;
         {
             actions = self.clients[token].readable(poll);
@@ -60,14 +59,14 @@
     }
 
     pub fn client_writable(&mut self, poll: &Poll,
-                           token: Token) -> io::Result<()> {
+                           token: usize) -> io::Result<()> {
         self.clients[token].writable(poll)?;
 
         Ok(())
     }
 
     pub fn client_error(&mut self, poll: &Poll,
-                           token: Token) -> io::Result<()> {
+                           token: usize) -> io::Result<()> {
         let actions;
         {
             actions = self.clients[token].error(poll);
@@ -78,11 +77,11 @@
         Ok(())
     }
 
-    pub fn send(&mut self, token: Token, msg: &String) {
+    pub fn send(&mut self, token: usize, msg: &String) {
         self.clients[token].send_string(msg);
     }
 
-    pub fn react(&mut self, token: Token, poll: &Poll, actions: Vec<actions::Action>) {
+    pub fn react(&mut self, token: usize, poll: &Poll, actions: Vec<actions::Action>) {
         for action in actions {
             actions::run_action(self, token, poll, action);
         }
@@ -91,7 +90,7 @@
 
 
 pub struct HWRoom {
-    pub id: Token,
+    pub id: usize,
     pub name: String,
     pub password: Option<String>,
     pub protocol_number: u32,
@@ -101,7 +100,7 @@
 impl HWRoom {
     pub fn new() -> HWRoom {
         HWRoom {
-            id: Token(0),
+            id: 0,
             name: String::new(),
             password: None,
             protocol_number: 0,
--- a/hedgewars/uCommandHandlers.pas	Wed Jan 10 01:39:10 2018 +0100
+++ b/hedgewars/uCommandHandlers.pas	Wed Jan 10 15:27:47 2018 +0100
@@ -533,7 +533,7 @@
     cSeed:= s;
     InitStepsFlags:= InitStepsFlags or cifRandomize
     end
-    end;
+end;
 
 procedure chAmmoMenu(var s: shortstring);
 begin
--- a/hedgewars/uGearsRender.pas	Wed Jan 10 01:39:10 2018 +0100
+++ b/hedgewars/uGearsRender.pas	Wed Jan 10 15:27:47 2018 +0100
@@ -1243,17 +1243,17 @@
            gtShell: DrawSpriteRotated(sprBazookaShell, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
 
            gtGrave: begin
-                    DrawTextureF(Gear^.Hedgehog^.Team^.GraveTex, 1, x, y, (GameTicks shr 7+Gear^.uid) and 15, 1, 32, 32);
+                    DrawTextureF(Gear^.Hedgehog^.Team^.GraveTex, 1, x, y, (RealTicks shr 7+Gear^.uid) and 15, 1, 32, 32);
                     if Gear^.Health > 0 then
                         begin
                         //Tint($33, $33, $FF, max($40, round($FF * abs(1 - (GameTicks mod (6000 div Gear^.Health)) / 750))));
-                        Tint($f5, $db, $35, max($40, round($FF * abs(1 - (GameTicks mod 1500) / (750 + Gear^.Health)))));
+                        Tint($f5, $db, $35, max($40, round($FF * abs(1 - (RealTicks mod 1500) / (750 + Gear^.Health)))));
                         //Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - (RealTicks mod 1500) / 750))));
                         DrawSprite(sprVampiric, x - 24, y - 24, 0);
                         untint
                         end
                     end;
-             gtBee: DrawSpriteRotatedF(sprBee, x, y, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
+             gtBee: DrawSpriteRotatedF(sprBee, x, y, (RealTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
       gtPickHammer: DrawSprite(sprPHammer, x - 16, y - 50 + LongInt(((GameTicks shr 5) and 1) * 2), 0);
             gtRope: DrawRope(Gear);
 
@@ -1293,7 +1293,7 @@
                                 DrawSprite(sprCase, x - 24, y - 28, 0)
                             else
                                 begin
-                                i:= (GameTicks shr 6) mod 64;
+                                i:= (RealTicks shr 6) mod 64;
                                 if i > 18 then i:= 0;
                                 DrawSprite(sprCase, x - 24, y - 24, i)
                                 end
@@ -1304,7 +1304,7 @@
                                 DrawSprite(sprFAid, x - 24, y - 28, 0)
                             else
                                 begin
-                                i:= ((GameTicks shr 6) + 38) mod 64;
+                                i:= ((RealTicks shr 6) + 38) mod 64;
                                 if i > 13 then i:= 0;
                                 DrawSprite(sprFAid, x - 24, y - 24, i)
                                 end
@@ -1315,7 +1315,7 @@
                                 DrawSprite(sprUtility, x - 24, y - 28, 0)
                             else
                                 begin
-                                i:= (GameTicks shr 6) mod 70;
+                                i:= (RealTicks shr 6) mod 70;
                                 if i > 23 then i:= 0;
                                 i:= i mod 12;
                                 DrawSprite(sprUtility, x - 24, y - 24, i)
@@ -1333,7 +1333,7 @@
                         DrawSprite(sprExplosivesRoll, x - 24, y - 24, 0)
                     else if Gear^.State and gstAnimation = 0 then
                         begin
-                        i:= (GameTicks shr 6 + Gear^.uid*3) mod 64;
+                        i:= (RealTicks shr 6 + Gear^.uid*3) mod 64;
                         if i > 18 then
                             i:= 0;
                         DrawSprite(sprExplosives, x - 24, y - 24, i)
@@ -1369,8 +1369,8 @@
      gtClusterBomb: DrawSpriteRotated(sprClusterBomb, x, y, 0, Gear^.DirAngle);
          gtCluster: DrawSprite(sprClusterParticle, x - 8, y - 8, 0);
            gtFlame: if Gear^.Tag and 1 = 0 then
-                         DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (GameTicks shr 7 + LongWord(Gear^.Tag)) mod 8, 1, 16, 16)
-                    else DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (GameTicks shr 7 + LongWord(Gear^.Tag)) mod 8, -1, 16, 16);
+                         DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, 1, 16, 16)
+                    else DrawTextureF(SpritesData[sprFlame].Texture, 2 / (Gear^.Tag mod 3 + 2), x, y, (RealTicks shr 7 + LongWord(Gear^.Tag)) mod 8, -1, 16, 16);
        gtParachute: begin
                     DrawSprite(sprParachute, x - 24, y - 48, 0);
                     DrawAltWeapon(Gear, x + 1, y - 3)
@@ -1391,7 +1391,7 @@
                         DrawSpriteRotatedF(sprTeleport, hwRound(HHGear^.X) + 1 + WorldDx, hwRound(HHGear^.Y) - 3 + WorldDy, 11 - Gear^.Pos, hwSign(HHGear^.dX), 0)
                         end
                     end;
-        gtSwitcher: DrawSprite(sprSwitch, x - 16, y - 56, (GameTicks shr 6) mod 12);
+        gtSwitcher: DrawSprite(sprSwitch, x - 16, y - 56, (RealTicks shr 6) mod 12);
           gtTarget: begin
                     Tint($FF, $FF, $FF, round($FF * Gear^.Timer / 1000));
                     DrawSprite(sprTarget, x - 16, y - 16, 0);
@@ -1548,7 +1548,9 @@
                                 end
                           end
                       end;
-            gtDuck: DrawSpriteRotatedF(sprDuck, x, y, 1, Gear^.Tag, Gear^.DirAngle);
+            gtDuck: DrawSpriteRotatedF(sprDuck, x, y, 1, Gear^.Tag, 
+                    // replace with something based on dx/dy?
+                    Gear^.DirAngle + 10-round(20 * abs(1 - (RealTicks mod round(0.1/max(0.00005,cWindSpeedf))) / round(0.05/max(0.00005,cWindSpeedf))) ));
             gtGenericFaller: DrawCircle(x, y, 3, 3, $FF, $00, $00, $FF);  // debug
          end;
     if Gear^.State and gstFrozen <> 0 then untint
--- a/hedgewars/uRender.pas	Wed Jan 10 01:39:10 2018 +0100
+++ b/hedgewars/uRender.pas	Wed Jan 10 15:27:47 2018 +0100
@@ -68,7 +68,7 @@
 procedure Tint                  (r, g, b, a: Byte); inline;
 procedure Tint                  (c: Longword); inline;
 procedure untint(); inline;
-procedure setTintAdd            (f: boolean); inline;
+procedure setTintAdd            (enable: boolean); inline;
 
 // call this to finish the rendering of current frame
 procedure FinishRender();
@@ -106,7 +106,7 @@
 
 implementation
 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}uVariables, uUtils
-     {$IFDEF GL2}, uMatrix, uConsole{$ENDIF}, uConsts;
+     {$IFDEF GL2}, uMatrix, uConsole, uPhysFSLayer, uDebug{$ENDIF}, uConsts;
 
 {$IFDEF USE_TOUCH_INTERFACE}
 const
@@ -123,9 +123,8 @@
 var VertexBuffer : array [0 ..59] of TVertex2f;
     TextureBuffer: array [0 .. 7] of TVertex2f;
     LastTint: LongWord = 0;
+{$IFNDEF GL2}
     LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer;
-{$IFDEF GL2}
-    LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
 {$ENDIF}
 
 {$IFDEF USE_S3D_RENDERING}
@@ -740,8 +739,8 @@
         {$ELSE}
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         glEnableClientState(GL_COLOR_ARRAY);
+        LastTexCoordPointer:= nil;
         {$ENDIF}
-        LastTexCoordPointer:= nil;
         end
     else
         begin
@@ -751,8 +750,8 @@
         {$ELSE}
         glDisableClientState(GL_COLOR_ARRAY);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        LastColorPointer:= nil;
         {$ENDIF}
-        LastColorPointer:= nil;
         end;
     EnableTexture(not b);
 end;
@@ -775,58 +774,49 @@
 procedure SetTexCoordPointer(p: Pointer; n: Integer); inline;
 begin
 {$IFDEF GL2}
-    if (p = LastTexCoordPointer) and (n = LastTexCoordPointerN) then
-        exit;
     glBindBuffer(GL_ARRAY_BUFFER, tBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
     glEnableVertexAttribArray(aTexCoord);
     glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
-    LastTexCoordPointerN:= n;
 {$ELSE}
     if p = LastTexCoordPointer then
         exit;
     n:= n;
     glTexCoordPointer(2, GL_FLOAT, 0, p);
+    LastTexCoordPointer:= p;
 {$ENDIF}
-    LastTexCoordPointer:= p;
 end;
 
 procedure SetVertexPointer(p: Pointer; n: Integer); inline;
 begin
 {$IFDEF GL2}
-    if (p = LastVertexPointer) and (n = LastVertexPointerN) then
-        exit;
     glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
     glEnableVertexAttribArray(aVertex);
     glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
-    LastVertexPointerN:= n;
 {$ELSE}
     if p = LastVertexPointer then
         exit;
     n:= n;
     glVertexPointer(2, GL_FLOAT, 0, p);
+    LastVertexPointer:= p;
 {$ENDIF}
-    LastVertexPointer:= p;
 end;
 
 procedure SetColorPointer(p: Pointer; n: Integer); inline;
 begin
 {$IFDEF GL2}
-    if (p = LastColorPointer) and (n = LastColorPointerN) then
-        exit;
     glBindBuffer(GL_ARRAY_BUFFER, cBuffer);
     glBufferData(GL_ARRAY_BUFFER, n * 4, p, GL_STATIC_DRAW);
     glEnableVertexAttribArray(aColor);
     glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pointer(0));
-    LastColorPointerN:= n;
 {$ELSE}
     if p = LastColorPointer then
         exit;
     n:= n;
     glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
+    LastColorPointer:= p;
 {$ENDIF}
-    LastColorPointer:= p;
 end;
 
 procedure EnableTexture(enable:Boolean);
@@ -883,7 +873,10 @@
         end
     else
         begin
-        openglPushMatrix; // save default scaling in matrix
+        if cScaleFactor = cDefaultZoomLevel then
+            begin
+            openglPushMatrix; // save default scaling in matrix;
+            end;
         openglLoadIdentity();
         openglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
         openglTranslatef(0, -cScreenHeight div 2, 0);
@@ -944,7 +937,6 @@
 _t:= r^.y / SourceTexture^.h * SourceTexture^.ry;
 _b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry;
 
-glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
 
 xw:= X + W;
 yh:= Y + H;
@@ -967,9 +959,13 @@
 TextureBuffer[3].X:= _l;
 TextureBuffer[3].Y:= _b;
 
+
+glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
 SetVertexPointer(@VertexBuffer[0], 4);
 SetTexCoordPointer(@TextureBuffer[0], 4);
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
 end;
 
 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline;
@@ -979,7 +975,6 @@
 
 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
 begin
-
 openglPushMatrix;
 openglTranslatef(X, Y, 0);
 
@@ -996,6 +991,7 @@
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
 openglPopMatrix;
 
+UpdateModelviewProjection;
 end;
 
 { this contains tweaks in order to avoid land tile borders in blurry land mode }
@@ -1025,6 +1021,8 @@
 
 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 openglPopMatrix;
+
+UpdateModelviewProjection;
 end;
 
 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
@@ -1132,6 +1130,8 @@
 
 openglPopMatrix;
 
+UpdateModelviewProjection;
+
 end;
 
 procedure DrawSpriteRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
@@ -1171,10 +1171,14 @@
 if Angle <> 0  then
     openglRotatef(Angle, 0, 0, 1);
 
+UpdateModelviewProjection;
+
 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
 
 openglPopMatrix;
 
+UpdateModelviewProjection;
+
 end;
 
 procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
@@ -1212,6 +1216,8 @@
 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
 
 openglPopMatrix;
+
+UpdateModelviewProjection;
 end;
 
 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -1259,6 +1265,7 @@
 
 openglPopMatrix;
 
+UpdateModelviewProjection;
 end;
 
 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt);
@@ -1342,6 +1349,8 @@
     DrawLineOnScreen(X0, Y0, X1, Y1, Width, r, g, b, a);
 
     openglPopMatrix();
+
+    UpdateModelviewProjection;
 end;
 
 procedure DrawLineOnScreen(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
@@ -1376,7 +1385,6 @@
     exit;
 
 EnableTexture(False);
-
 Tint(r, g, b, a);
 
 with rect do
@@ -1510,6 +1518,8 @@
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
     openglPopMatrix;
+
+    UpdateModelviewProjection;
 end;
 
 procedure DrawScreenWidget(widget: POnScreenWidget);
@@ -1904,8 +1914,6 @@
 SetVertexPointer(@VertexBuffer[0], 8);
 SetTexCoordPointer(@TextureBuffer[0], 8);
 
-UpdateModelviewProjection;
-
 glDrawArrays(GL_TRIANGLE_STRIP, first, count);
 
 untint;
@@ -1961,12 +1969,19 @@
     LastTint:= cWhiteColor;
 end;
 
-procedure setTintAdd(f: boolean); inline;
+procedure setTintAdd(enable: boolean); inline;
 begin
-    if f then
+    {$IFDEF GL2}
+        if enable then
+            glUniform1i(glGetUniformLocation(shaderMain, pchar('tintAdd')), 1)
+        else
+            glUniform1i(glGetUniformLocation(shaderMain, pchar('tintAdd')), 0);
+    {$ELSE}
+    if enable then
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD)
     else
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    {$ENDIF}
 end;
 
 procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
@@ -2008,13 +2023,10 @@
 procedure initModule;
 begin
     LastTint:= cWhiteColor + 1;
+{$IFNDEF GL2}
     LastColorPointer    := nil;
     LastTexCoordPointer := nil;
     LastVertexPointer   := nil;
-{$IFDEF GL2}
-    LastColorPointerN   :=   0;
-    LastTexCoordPointerN:=   0;
-    LastVertexPointerN  :=   0;
 {$ENDIF}
 end;
 
--- a/hedgewars/uScript.pas	Wed Jan 10 01:39:10 2018 +0100
+++ b/hedgewars/uScript.pas	Wed Jan 10 15:27:47 2018 +0100
@@ -3059,6 +3059,7 @@
 var mybuf: PChar;
     i: LongInt;
 begin
+    SetRandomSeed(cSeed,true);
     mybuf := physfsReader(L, f, sz);
     if (mybuf <> nil) and ((sz^) > 0) then
         begin
--- a/hedgewars/uVariables.pas	Wed Jan 10 01:39:10 2018 +0100
+++ b/hedgewars/uVariables.pas	Wed Jan 10 15:27:47 2018 +0100
@@ -2731,7 +2731,12 @@
     cMaxZoomLevel:= 1.0;
     cMinZoomLevel:= 3.0;
     cZoomDelta:= 0.25;
-{$ENDIF}
+    {$ENDIF}
+
+    aVertex:= 0;
+    aTexCoord:= 1;
+    aColor:= 2;
+
 
     cMinMaxZoomLevelDelta:= cMaxZoomLevel - cMinZoomLevel;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/CMakeLists.txt	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(qmlfrontend LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+find_package(Qt5 COMPONENTS Core Quick REQUIRED)
+
+add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc")
+
+target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/Page1.qml	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,7 @@
+import QtQuick 2.7
+
+Page1Form {
+  button1.onClicked: {
+    console.log("Button Pressed. Entered text: " + textField1.text);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/Page1Form.ui.qml	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,24 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+Item {
+    property alias textField1: textField1
+    property alias button1: button1
+
+    RowLayout {
+        anchors.horizontalCenter: parent.horizontalCenter
+        anchors.topMargin: 20
+        anchors.top: parent.top
+
+        TextField {
+            id: textField1
+            placeholderText: qsTr("Text Field")
+        }
+
+        Button {
+            id: button1
+            text: qsTr("Press Me")
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/main.cpp	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,15 @@
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+
+int main(int argc, char *argv[])
+{
+  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+  QGuiApplication app(argc, argv);
+
+  QQmlApplicationEngine engine;
+  engine.load(QUrl(QLatin1String("qrc:/main.qml")));
+  if (engine.rootObjects().isEmpty())
+    return -1;
+
+  return app.exec();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/main.qml	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,37 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+ApplicationWindow {
+  visible: true
+  width: 640
+  height: 480
+  title: qsTr("Hello World")
+
+  SwipeView {
+    id: swipeView
+    anchors.fill: parent
+    currentIndex: tabBar.currentIndex
+
+    Page1 {
+    }
+
+    Page {
+      Label {
+        text: qsTr("Second page")
+        anchors.centerIn: parent
+      }
+    }
+  }
+
+  footer: TabBar {
+    id: tabBar
+    currentIndex: swipeView.currentIndex
+    TabButton {
+      text: qsTr("First")
+    }
+    TabButton {
+      text: qsTr("Second")
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/qml.qrc	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,9 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+    <qresource prefix="/">
+        <file>main.qml</file>
+        <file>Page1.qml</file>
+        <file>Page1Form.ui.qml</file>
+        <file>qtquickcontrols2.conf</file>
+    </qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/qtquickcontrols2.conf	Wed Jan 10 15:27:47 2018 +0100
@@ -0,0 +1,15 @@
+; This file can be edited to change the style of the application
+; See Styling Qt Quick Controls 2 in the documentation for details:
+; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html
+
+[Controls]
+Style=Default
+
+[Universal]
+Theme=Light
+;Accent=Steel
+
+[Material]
+Theme=Light
+;Accent=BlueGrey
+;Primary=BlueGray
Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw_base.png has changed
Binary file share/hedgewars/Data/Graphics/BigDigitsGray.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/armenia.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/cm_soviet.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/ireland.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/nepal.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/suisse.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/sweden.png has changed
Binary file share/hedgewars/Data/Graphics/Flags/turkey.png has changed
Binary file share/hedgewars/Data/Graphics/Graves/Simple_reversed.png has changed
Binary file share/hedgewars/Data/Graphics/Progress.png has changed
Binary file share/hedgewars/Data/Graphics/missions.png has changed
--- a/share/hedgewars/Data/Shaders/default.fs	Wed Jan 10 01:39:10 2018 +0100
+++ b/share/hedgewars/Data/Shaders/default.fs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,7 +1,10 @@
+#ifdef GL_ES
 precision mediump float;
+#endif
 
 uniform sampler2D tex0;
 uniform vec4 tint;
+uniform bool tintAdd;
 uniform bool enableTexture;
 
 varying vec2 tex;
@@ -10,7 +13,12 @@
 void main()
 {
     if(enableTexture){
-        gl_FragColor = texture2D(tex0, tex) * tint;
+        if (tintAdd){
+            tint.a = 0.0;
+            gl_FragColor = clamp(texture2D(tex0, tex) + tint, 0.0, 1.1);
+        }else{
+            gl_FragColor = texture2D(tex0, tex) * tint;
+        }
     }else{
         gl_FragColor = tint;
     }
--- a/share/hedgewars/Data/Shaders/default.vs	Wed Jan 10 01:39:10 2018 +0100
+++ b/share/hedgewars/Data/Shaders/default.vs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,4 +1,6 @@
+#ifdef GL_ES
 precision mediump float;
+#endif
 
 attribute vec2 vertex;
 attribute vec2 texcoord;
--- a/share/hedgewars/Data/Shaders/water.fs	Wed Jan 10 01:39:10 2018 +0100
+++ b/share/hedgewars/Data/Shaders/water.fs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,4 +1,6 @@
+#ifdef GL_ES
 precision mediump float;
+#endif
 
 varying vec4 vcolor;
 
--- a/share/hedgewars/Data/Shaders/water.vs	Wed Jan 10 01:39:10 2018 +0100
+++ b/share/hedgewars/Data/Shaders/water.vs	Wed Jan 10 15:27:47 2018 +0100
@@ -1,4 +1,6 @@
+#ifdef GL_ES
 precision mediump float;
+#endif
 
 attribute vec2 vertex;
 attribute vec4 color;