Index: src/g_game.c
===================================================================
--- src/g_game.c	(revision 1040)
+++ src/g_game.c	(working copy)
@@ -145,8 +145,10 @@
 boolean         lowres_turn;            // low resolution turning for longtics
 boolean         demoplayback; 
 boolean		netdemo; 
-byte*		demobuffer;
-byte*		demo_p;
+byte*		demo_in_buffer;
+byte*		demo_out_buffer;
+byte*		demo_in_p;
+byte*		demo_out_p = NULL;
 byte*		demoend; 
 boolean         singledemo;            	// quit after playing a demo from cmdline 
  
@@ -1742,28 +1744,28 @@
 
 void G_ReadDemoTiccmd (ticcmd_t* cmd) 
 { 
-    if (*demo_p == DEMOMARKER) 
+    if (*demo_in_p == DEMOMARKER) 
     {
 	// end of demo data stream 
 	G_CheckDemoStatus (); 
 	return; 
     } 
-    cmd->forwardmove = ((signed char)*demo_p++); 
-    cmd->sidemove = ((signed char)*demo_p++); 
+    cmd->forwardmove = ((signed char)*demo_in_p++); 
+    cmd->sidemove = ((signed char)*demo_in_p++); 
 
     // If this is a longtics demo, read back in higher resolution
 
     if (longtics)
     {
-        cmd->angleturn = *demo_p++;
-        cmd->angleturn |= (*demo_p++) << 8;
+        cmd->angleturn = *demo_in_p++;
+        cmd->angleturn |= (*demo_in_p++) << 8;
     }
     else
     {
-        cmd->angleturn = ((unsigned char) *demo_p++)<<8; 
+        cmd->angleturn = ((unsigned char) *demo_in_p++)<<8; 
     }
 
-    cmd->buttons = (unsigned char)*demo_p++; 
+    cmd->buttons = (unsigned char)*demo_in_p++; 
 } 
 
 // Increase the size of the demo buffer to allow unlimited demos
@@ -1777,57 +1779,59 @@
 
     // Find the current size
 
-    current_length = demoend - demobuffer;
+    current_length = demoend - demo_out_buffer;
     
     // Generate a new buffer twice the size
     new_length = current_length * 2;
     
     new_demobuffer = Z_Malloc(new_length, PU_STATIC, 0);
-    new_demop = new_demobuffer + (demo_p - demobuffer);
+    new_demop = new_demobuffer + (demo_out_p - demo_out_buffer);
 
     // Copy over the old data
 
-    memcpy(new_demobuffer, demobuffer, current_length);
+    memcpy(new_demobuffer, demo_out_buffer, current_length);
 
     // Free the old buffer and point the demo pointers at the new buffer.
 
-    Z_Free(demobuffer);
+    Z_Free(demo_out_buffer);
 
-    demobuffer = new_demobuffer;
-    demo_p = new_demop;
-    demoend = demobuffer + new_length;
+    demo_out_buffer = new_demobuffer;
+    demo_out_p = new_demop;
+    demoend = demo_out_buffer + new_length;
 }
 
 void G_WriteDemoTiccmd (ticcmd_t* cmd) 
 { 
-    byte *demo_start;
+    if (demo_out_p == NULL)
+    {
+        G_BeginRecording();
+    }
 
     if (gamekeydown['q'])           // press q to end demo recording 
+    {
+        gamekeydown['q'] = 0;
 	G_CheckDemoStatus (); 
+        return;
+    }
 
-    demo_start = demo_p;
+    *demo_out_p++ = cmd->forwardmove; 
+    *demo_out_p++ = cmd->sidemove; 
 
-    *demo_p++ = cmd->forwardmove; 
-    *demo_p++ = cmd->sidemove; 
-
     // If this is a longtics demo, record in higher resolution
  
     if (longtics)
     {
-        *demo_p++ = (cmd->angleturn & 0xff);
-        *demo_p++ = (cmd->angleturn >> 8) & 0xff;
+        *demo_out_p++ = (cmd->angleturn & 0xff);
+        *demo_out_p++ = (cmd->angleturn >> 8) & 0xff;
     }
     else
     {
-        *demo_p++ = cmd->angleturn >> 8; 
+        *demo_out_p++ = cmd->angleturn >> 8; 
     }
 
-    *demo_p++ = cmd->buttons; 
+    *demo_out_p++ = cmd->buttons; 
 
-    // reset demo pointer back
-    demo_p = demo_start;
-
-    if (demo_p > demoend - 16)
+    if (demo_out_p > demoend - 16)
     {
         if (vanilla_demo_limit)
         {
@@ -1843,8 +1847,6 @@
             IncreaseDemoBuffer();
         }
     } 
-	
-    G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same 
 } 
  
  
@@ -1873,8 +1875,8 @@
     i = M_CheckParm ("-maxdemo");
     if (i && i<myargc-1)
 	maxsize = atoi(myargv[i+1])*1024;
-    demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL); 
-    demoend = demobuffer + maxsize;
+    demo_out_buffer = Z_Malloc (maxsize,PU_STATIC,NULL); 
+    demoend = demo_out_buffer + maxsize;
 	
     demorecording = true; 
 } 
@@ -1896,30 +1898,30 @@
 
     lowres_turn = !longtics;
     
-    demo_p = demobuffer;
+    demo_out_p = demo_out_buffer;
 	
     // Save the right version code for this demo
  
     if (longtics)
     {
-        *demo_p++ = DOOM_191_VERSION;
+        *demo_out_p++ = DOOM_191_VERSION;
     }
     else
     {
-        *demo_p++ = DOOM_VERSION;
+        *demo_out_p++ = DOOM_VERSION;
     }
 
-    *demo_p++ = gameskill; 
-    *demo_p++ = gameepisode; 
-    *demo_p++ = gamemap; 
-    *demo_p++ = deathmatch; 
-    *demo_p++ = respawnparm;
-    *demo_p++ = fastparm;
-    *demo_p++ = nomonsters;
-    *demo_p++ = consoleplayer;
+    *demo_out_p++ = gameskill; 
+    *demo_out_p++ = gameepisode; 
+    *demo_out_p++ = gamemap; 
+    *demo_out_p++ = deathmatch; 
+    *demo_out_p++ = respawnparm;
+    *demo_out_p++ = fastparm;
+    *demo_out_p++ = nomonsters;
+    *demo_out_p++ = consoleplayer;
 	 
     for (i=0 ; i<MAXPLAYERS ; i++) 
-	*demo_p++ = playeringame[i]; 		 
+	*demo_out_p++ = playeringame[i]; 		 
 } 
  
 
@@ -1942,9 +1944,9 @@
     int demoversion;
 	 
     gameaction = ga_nothing; 
-    demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); 
+    demo_in_buffer = demo_in_p = W_CacheLumpName (defdemoname, PU_STATIC); 
 
-    demoversion = *demo_p++;
+    demoversion = *demo_in_p++;
 
     if (demoversion == DOOM_VERSION)
     {
@@ -1965,17 +1967,17 @@
         I_Error(errorbuf);
     }
     
-    skill = *demo_p++; 
-    episode = *demo_p++; 
-    map = *demo_p++; 
-    deathmatch = *demo_p++;
-    respawnparm = *demo_p++;
-    fastparm = *demo_p++;
-    nomonsters = *demo_p++;
-    consoleplayer = *demo_p++;
+    skill = *demo_in_p++; 
+    episode = *demo_in_p++; 
+    map = *demo_in_p++; 
+    deathmatch = *demo_in_p++;
+    respawnparm = *demo_in_p++;
+    fastparm = *demo_in_p++;
+    nomonsters = *demo_in_p++;
+    consoleplayer = *demo_in_p++;
 	
     for (i=0 ; i<MAXPLAYERS ; i++) 
-	playeringame[i] = *demo_p++; 
+	playeringame[i] = *demo_in_p++; 
 
     //!
     // @category demo
@@ -2060,7 +2062,7 @@
 	 
     if (demoplayback) 
     { 
-	Z_ChangeTag (demobuffer, PU_CACHE); 
+	Z_ChangeTag (demo_in_buffer, PU_CACHE); 
 	demoplayback = false; 
 	netdemo = false;
 	netgame = false;
@@ -2071,19 +2073,22 @@
 	nomonsters = false;
 	consoleplayer = 0;
         
-        if (singledemo) 
-            I_Quit (); 
-        else 
-            D_AdvanceDemo (); 
+        if (!demorecording)
+        {
+            if (singledemo) 
+                I_Quit (); 
+            else 
+                D_AdvanceDemo (); 
+        }
 
-	return true; 
+        return true; 
     } 
  
     if (demorecording) 
     { 
-	*demo_p++ = DEMOMARKER; 
-	M_WriteFile (demoname, demobuffer, demo_p - demobuffer); 
-	Z_Free (demobuffer); 
+	*demo_out_p++ = DEMOMARKER; 
+	M_WriteFile (demoname, demo_out_buffer, demo_out_p - demo_out_buffer); 
+	Z_Free (demo_out_buffer); 
 	demorecording = false; 
 	I_Error ("Demo %s recorded",demoname); 
     } 
Index: src/d_net.c
===================================================================
--- src/d_net.c	(revision 1040)
+++ src/d_net.c	(working copy)
@@ -145,6 +145,11 @@
 
     lasttime = nowtime;
 
+    if (demoplayback && demorecording)
+    {
+        newtics = 1;
+    }
+
     if (skiptics <= newtics)
     {
         newtics -= skiptics;
Index: src/d_main.c
===================================================================
--- src/d_main.c	(revision 1040)
+++ src/d_main.c	(working copy)
@@ -242,6 +242,11 @@
     if (nodrawers)
 	return;                    // for comparative timing / profiling
 		
+    if (demoplayback && demorecording)
+    {
+        return;
+    }
+    
     redrawsbar = false;
     
     // change the view size if needed
@@ -395,9 +400,6 @@
 
 void D_DoomLoop (void)
 {
-    if (demorecording)
-	G_BeginRecording ();
-		
     if (M_CheckParm ("-debugfile"))
     {
 	char    filename[20];
