]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Crude port from demo rerecording code from quakespasm/proquake. Outputs a working...
authorDes <xon@damianv.com.ar>
Mon, 5 Aug 2024 11:58:59 +0000 (08:58 -0300)
committerDes <xon@damianv.com.ar>
Mon, 5 Aug 2024 11:58:59 +0000 (08:58 -0300)
cl_demo.c
common.c
common.h

index f44e539f46ef9c498197b914473690a100270de2..077f97703afa339db3d51e89856e1f27e99e7d55 100644 (file)
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -27,6 +27,10 @@ extern cvar_t cl_capturevideo_demo_stop;
 
 static void CL_FinishTimeDemo (void);
 
+// from ProQuake: space to fill out the demo header for record at any tim
+static unsigned char    *demo_head;
+static int              *demo_head_sizes;
+
 /*
 ==============================================================================
 
@@ -116,6 +120,11 @@ void CL_WriteDemoMessage (sizebuf_t *message)
        if (cls.demopaused) // LadyHavoc: pausedemo
                return;
 
+       if (cls.signon < 2)
+       {
+               Vec_Append ((void**)&demo_head, 1, message->data, message->cursize);
+               VEC_PUSH (demo_head_sizes, message->cursize);
+       }
        len = LittleLong (message->cursize);
        FS_Write (cls.demofile, &len, 4);
        for (i=0 ; i<3 ; i++)
@@ -365,12 +374,16 @@ void CL_Record_f(cmd_state_t *cmd)
 
        if (c == 2 && cls.state == ca_connected)
        {
+#if 0
                Con_Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n");
                return;
+#endif
        }
 
+#if 0
        if (cls.state == ca_connected)
                CL_Disconnect();
+#endif
 
        // write the forced cd track number, or -1
        if (c == 4)
@@ -408,6 +421,78 @@ void CL_Record_f(cmd_state_t *cmd)
        cls.demorecording = true;
        cls.demo_lastcsprogssize = -1;
        cls.demo_lastcsprogscrc = -1;
+
+       // from ProQuake: initialize the demo file if we're already connected
+       if (c == 2 && cls.state == ca_connected)
+       {
+               sizebuf_t buf;
+               unsigned char tmpbuf[NET_MAXMESSAGE];
+               int cursize = buf.cursize;
+               int maxsize = buf.maxsize;
+               int i, count;
+
+               buf.data = demo_head;
+               for (i = 0, count = VEC_SIZE (demo_head_sizes); i < count; i++)
+               {
+                       buf.cursize = demo_head_sizes[i];
+                       CL_WriteDemoMessage(&buf);
+                       buf.data += buf.cursize;
+               }
+
+               buf.data = tmpbuf;
+               buf.maxsize = sizeof (tmpbuf);
+               SZ_Clear (&buf);
+
+               // current names, colors, and frag counts
+               for (i = 0; i < cl.maxclients; i++)
+               {
+                       MSG_WriteByte (&buf, svc_updatename);
+                       MSG_WriteByte (&buf, i);
+                       MSG_WriteString (&buf, cl.scores[i].name);
+                       MSG_WriteByte (&buf, svc_updatefrags);
+                       MSG_WriteByte (&buf, i);
+                       MSG_WriteShort (&buf, cl.scores[i].frags);
+                       MSG_WriteByte (&buf, svc_updatecolors);
+                       MSG_WriteByte (&buf, i);
+                       MSG_WriteByte (&buf, cl.scores[i].colors);
+               }
+
+               // send all current light styles
+               for (i = 0; i < MAX_LIGHTSTYLES; i++)
+               {
+                       MSG_WriteByte (&buf, svc_lightstyle);
+                       MSG_WriteByte (&buf, i);
+                       MSG_WriteString (&buf, cl.lightstyle[i].map);
+               }
+
+               // what about the CD track or SVC fog... future consideration.
+               MSG_WriteByte (&buf, svc_updatestat);
+               MSG_WriteByte (&buf, STAT_TOTALSECRETS);
+               MSG_WriteLong (&buf, cl.stats[STAT_TOTALSECRETS]);
+
+               MSG_WriteByte (&buf, svc_updatestat);
+               MSG_WriteByte (&buf, STAT_TOTALMONSTERS);
+               MSG_WriteLong (&buf, cl.stats[STAT_TOTALMONSTERS]);
+
+               MSG_WriteByte (&buf, svc_updatestat);
+               MSG_WriteByte (&buf, STAT_SECRETS);
+               MSG_WriteLong (&buf, cl.stats[STAT_SECRETS]);
+
+               MSG_WriteByte (&buf, svc_updatestat);
+               MSG_WriteByte (&buf, STAT_MONSTERS);
+               MSG_WriteLong (&buf, cl.stats[STAT_MONSTERS]);
+
+               // view entity
+               MSG_WriteByte (&buf, svc_setview);
+               MSG_WriteShort (&buf, cl.viewentity);
+
+               // signon
+               MSG_WriteByte (&buf, svc_signonnum);
+               MSG_WriteByte (&buf, 3);
+
+               CL_WriteDemoMessage(&buf);
+
+       }
 }
 
 void CL_PlayDemo(const char *demo)
index f0f2fcce3842875b769c20b0f80e89e4f53439ac..c5c33cf1d31a86d885d8e4863e3034ffc36f6704 100644 (file)
--- a/common.c
+++ b/common.c
@@ -1498,3 +1498,67 @@ size_t base64_encode(unsigned char *buf, size_t buflen, size_t outbuflen)
        }
        return blocks * 4;
 }
+
+
+/*
+============================================================================
+
+                                                       DYNAMIC VECTORS
+
+============================================================================
+*/
+
+void Vec_Grow (void **pvec, size_t element_size, size_t count)
+{
+       vec_header_t header;
+       if (*pvec)
+               header = VEC_HEADER(*pvec);
+       else
+               header.size = header.capacity = 0;
+
+       if (header.size + count > header.capacity)
+       {
+               void *new_buffer;
+               size_t total_size;
+
+               header.capacity = header.size + count;
+               header.capacity += header.capacity >> 1;
+               if (header.capacity < 16)
+                       header.capacity = 16;
+               total_size = sizeof(vec_header_t) + header.capacity * element_size;
+
+               if (*pvec)
+                       new_buffer = realloc (((vec_header_t*)*pvec) - 1, total_size);
+               else
+                       new_buffer = malloc (total_size);
+               if (!new_buffer)
+                       Sys_Error ("Vec_Grow: failed to allocate %lu bytes\n", (unsigned long)total_size);
+
+               *pvec = 1 + (vec_header_t*)new_buffer;
+               VEC_HEADER(*pvec) = header;
+       }
+}
+
+void Vec_Append (void **pvec, size_t element_size, const void *data, size_t count)
+{
+       if (!count)
+               return;
+       Vec_Grow (pvec, element_size, count);
+       memcpy ((unsigned char *)*pvec + VEC_HEADER(*pvec).size, data, count * element_size);
+       VEC_HEADER(*pvec).size += count;
+}
+
+void Vec_Clear (void **pvec)
+{
+       if (*pvec)
+               VEC_HEADER(*pvec).size = 0;
+}
+
+void Vec_Free (void **pvec)
+{
+       if (*pvec)
+       {
+               free(&VEC_HEADER(*pvec));
+               *pvec = NULL;
+       }
+}
index cde830dcfdc7e51fac232f75fee227459d8cfbcd..0e012a3062bde19006249734dfdb8bf7786c50e8 100644 (file)
--- a/common.h
+++ b/common.h
@@ -75,6 +75,26 @@ void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
 void COM_Init_Commands(void);
 
 
+//============================================================================
+//                                                      void* Vector
+//============================================================================
+typedef struct vec_header_t {
+       size_t capacity;
+       size_t size;
+} vec_header_t;
+
+#define VEC_HEADER(v)                  (((vec_header_t*)(v))[-1])
+
+#define VEC_PUSH(v,n)                  do { Vec_Grow((void**)&(v), sizeof((v)[0]), 1); (v)[VEC_HEADER(v).size++] = (n); } while (0)
+#define VEC_SIZE(v)                            ((v) ? VEC_HEADER(v).size : 0)
+#define VEC_FREE(v)                            Vec_Free((void**)&(v))
+#define VEC_CLEAR(v)                   Vec_Clear((void**)&(v))
+
+void Vec_Grow (void **pvec, size_t element_size, size_t count);
+void Vec_Append (void **pvec, size_t element_size, const void *data, size_t count);
+void Vec_Clear (void **pvec);
+void Vec_Free (void **pvec);
+
 //============================================================================
 //                                                     Endianess handling
 //============================================================================