From 519350c635f130461f90d0e69fcbf6d375c61112 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 28 May 2017 17:14:23 +0000 Subject: [PATCH] example terrain generator for eukara. some compile fixes too. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5111 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/pr_csqc.c | 2 +- engine/client/sbar.h | 4 +- engine/client/view.c | 4 +- engine/common/bothdefs.h | 22 ++- engine/common/net_wins.c | 2 + engine/server/pr_cmds.c | 104 +++++------ plugins/terrorgen/terragen.c | 139 ++++++++++++++ plugins/terrorgen/terrorgen.vcproj | 283 +++++++++++++++++++++++++++++ 8 files changed, 496 insertions(+), 64 deletions(-) create mode 100644 plugins/terrorgen/terragen.c create mode 100644 plugins/terrorgen/terrorgen.vcproj diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index c19dff8bb..b9cd0387a 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -2189,7 +2189,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars { SCR_TileClear (sb_lines); Sbar_Draw (r_refdef.playerview); - Sbar_DrawScoreboard (); + Sbar_DrawScoreboard (r_refdef.playerview); } else SCR_TileClear (0); diff --git a/engine/client/sbar.h b/engine/client/sbar.h index 47f397d06..9cf5c7c4c 100644 --- a/engine/client/sbar.h +++ b/engine/client/sbar.h @@ -58,10 +58,10 @@ int Sbar_TranslateHudClick(void); #define Sbar_Changed() #define Sbar_Draw(pv) #define Sbar_Flush() -#define Sbar_ShouldDraw() false +#define Sbar_ShouldDraw(pv) false #define Sbar_DrawScoreboard() #define Sbar_FinaleOverlay() -#define Sbar_IntermissionOverlay() +#define Sbar_IntermissionOverlay(pv) #define Sbar_TranslateHudClick() 0 #endif diff --git a/engine/client/view.c b/engine/client/view.c index 50958a997..ef0711591 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -2252,11 +2252,11 @@ void V_RenderView (void) #ifdef PLUGINS Plug_SBar (r_refdef.playerview); #else - if (Sbar_ShouldDraw()) + if (Sbar_ShouldDraw(r_refdef.playerview)) { SCR_TileClear (sb_lines); Sbar_Draw (r_refdef.playerview); - Sbar_DrawScoreboard (); + Sbar_DrawScoreboard (r_refdef.playerview); } else SCR_TileClear (0); diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 73c316f30..a2263732e 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -449,8 +449,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef Q2BSPS #undef Q3BSPS #undef RFBSPS - #undef WEBSERVER //http/ftp servers - #undef WEBCLIENT //http/ftp clients. + #undef WEBSERVER //http server + #undef FTPSERVER //ftp server + #undef WEBCLIENT //http client. + #undef FTPCLIENT //ftp client. #endif #ifdef __DJGPP__ @@ -491,7 +493,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef VM_Q1 //no dlls #undef MAP_PROC //meh #undef HALFLIFEMODELS //blurgh - #undef WEBSERVER //hah, yeah, right #undef SUPPORT_ICE //requires udp, so not usable. webrtc could be used instead, but that logic is out of our hands. #undef HAVE_MIXER //depend upon openal instead. @@ -523,8 +524,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef AVAIL_DINPUT //nope, not supported. #undef SV_MASTER //no socket interface #undef CL_MASTER //no socket interface - #undef WEBSERVER //http/ftp servers - #undef WEBCLIENT //http/ftp clients. #undef MULTITHREAD #undef HEADLESSQUAKE #endif @@ -545,7 +544,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef SUPPORT_ICE #undef CL_MASTER //no sockets support #undef SV_MASTER //noone uses this anyway - #undef WEBSERVER //no sockets support (certainly no servers) + #undef WEBSERVER //http server + #undef FTPSERVER //ftp server + #undef FTPCLIENT //ftp client. #undef TCPCONNECT #undef IRCCONNECT #define GLSLONLY //pointless having the junk @@ -623,7 +624,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef NPFTE #undef TEXTEDITOR - #undef WEBSERVER + #undef WEBSERVER //http server + #undef FTPSERVER //ftp server + #undef FTPCLIENT //ftp client. #endif #ifndef AVAIL_ZLIB @@ -633,7 +636,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef HAVE_TCP #undef TCPCONNECT #undef IRCCONNECT - #undef WEBSERVER + #undef WEBSERVER //http server + #undef FTPSERVER //ftp server + #undef FTPCLIENT //ftp client. #if !defined(FTE_TARGET_WEB) && !defined(NACL) #undef WEBCLIENT #endif @@ -662,6 +667,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef Q3SERVER #undef HLSERVER #undef WEBSERVER + #undef FTPSERVER #undef VM_Q1 #undef SQL #endif diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index f49d669a8..abe36ff77 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -1899,6 +1899,7 @@ void FTENET_Loop_Close(ftenet_generic_connection_t *con) int sock = con->thesocket; sock &= 1; loopbacks[sock].inited = false; + loopbacks[sock].get = loopbacks[sock^1].send = 0; for (i = 0; i < MAX_LOOPBACK; i++) { BZ_Free(loopbacks[sock].msgs[i].data); @@ -1922,6 +1923,7 @@ static ftenet_generic_connection_t *FTENET_Loop_EstablishConnection(qboolean iss if (newcon) { loopbacks[sock].inited = true; + loopbacks[sock].get = loopbacks[sock^1].send = 0; newcon->GetLocalAddresses = FTENET_Loop_GetLocalAddresses; newcon->GetPacket = FTENET_Loop_GetPacket; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index edaed8875..14fb2372e 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -3692,19 +3692,20 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags) if (flags & STUFFCMD_BROADCAST) { - for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++) - { - if (cl->state != cs_spawned || cl->controller == cl) - continue; - SV_StuffcmdToClient(cl, str); - } + if (!(flags & STUFFCMD_DEMOONLY)) + for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++) + { + if (cl->state != cs_spawned || cl->controller != cl) + continue; + SV_StuffcmdToClient(cl, str); + } if (!(flags & STUFFCMD_IGNOREINDEMO)) - if (sv.mvdrecording) - { - sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, 2 + strlen(str)); - MSG_WriteByte (msg, svc_stufftext); - MSG_WriteString (msg, str); - } + if (sv.mvdrecording) + { + sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, 2 + strlen(str)); + MSG_WriteByte (msg, svc_stufftext); + MSG_WriteString (msg, str); + } return; } @@ -6665,42 +6666,6 @@ static void QCBUILTIN PF_readcmd (pubprogfuncs_t *prinst, struct globalvars_s *p SV_BeginRedirect(old, oldl); } -/* -================= -PF_redirectcmd - -void redirectcmd (entity to, string str) - -the mvdsv implementation executes it now. we delay till the end of the frame, to avoid issues with map changes etc. -================= -*/ -static void PF_Redirectcmdcallback(struct frameendtasks_s *task) -{ //called at the end of the frame when there's no qc running - host_client = svs.clients + task->ctxint; - if (host_client->state >= cs_connected) - { - SV_BeginRedirect(RD_CLIENT, host_client->language); - Cmd_ExecuteString(task->data, RESTRICT_INSECURE); - SV_EndRedirect(); - } -} -static void QCBUILTIN PF_redirectcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - struct frameendtasks_s *task, **link; - int entnum = G_EDICTNUM(prinst, OFS_PARM0); - const char *s = PR_GetStringOfs(prinst, OFS_PARM1); - if (entnum < 1 || entnum > sv.allocated_client_slots) - PR_RunError (prinst, "Parm 0 not a client"); - - task = Z_Malloc(sizeof(*task)+strlen(s)); - task->callback = PF_Redirectcmdcallback; - strcpy(task->data, s); - task->ctxint = entnum-1; - for(link = &svs.frameendtasks; *link; link = &(*link)->next) - ; //add them on the end, so they're execed in order - *link = task; -} - /* ================= PF_forcedemoframe @@ -6870,6 +6835,42 @@ static void QCBUILTIN PF_logtext(pubprogfuncs_t *prinst, struct globalvars_s *pr } #endif +/* +================= +PF_redirectcmd + +void redirectcmd (entity to, string str) + +the mvdsv implementation executes it now. we delay till the end of the frame, to avoid issues with map changes etc. +================= +*/ +static void PF_Redirectcmdcallback(struct frameendtasks_s *task) +{ //called at the end of the frame when there's no qc running + host_client = svs.clients + task->ctxint; + if (host_client->state >= cs_connected) + { + SV_BeginRedirect(RD_CLIENT, host_client->language); + Cmd_ExecuteString(task->data, RESTRICT_INSECURE); + SV_EndRedirect(); + } +} +static void QCBUILTIN PF_redirectcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + struct frameendtasks_s *task, **link; + int entnum = G_EDICTNUM(prinst, OFS_PARM0); + const char *s = PR_GetStringOfs(prinst, OFS_PARM1); + if (entnum < 1 || entnum > sv.allocated_client_slots) + PR_RunError (prinst, "Parm 0 not a client"); + + task = Z_Malloc(sizeof(*task)+strlen(s)); + task->callback = PF_Redirectcmdcallback; + strcpy(task->data, s); + task->ctxint = entnum-1; + for(link = &svs.frameendtasks; *link; link = &(*link)->next) + ; //add them on the end, so they're execed in order + *link = task; +} + static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef Q2BSPS @@ -11790,10 +11791,11 @@ void PR_DumpPlatform_f(void) {"SERVERKEY_PAUSESTATE","const string", CS, D("1 if the server claimed to be paused. 0 otherwise"), 0, "\"pausestate\""}, {"SERVERKEY_DLSTATE", "const string", CS, D("The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info:\nfiles-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes\nIf the current file info is omitted, then we are waiting for a download to start."), 0, "\"dlstate\""}, {"SERVERKEY_PROTOCOL", "const string", CS, D("The protocol we are connected to the server with."), 0, "\"protocol\""}, - {"SERVERKEY_MAXPLAYERS","const string", CS, D("The protocol we are connected to the server with."), 0, "\"maxplayers\""}, + {"SERVERKEY_MAXPLAYERS","const string", CS, D("The number of player/spectator slots allocated on the server."), 0, "\"maxplayers\""}, - {"STUFFCMD_IGNOREINDEMO","const float", QW|NQ, D("The protocol we are connected to the server with."), STUFFCMD_IGNOREINDEMO}, - {"STUFFCMD_DEMOONLY", "const float", QW|NQ, D("The protocol we are connected to the server with."), STUFFCMD_DEMOONLY}, + {"STUFFCMD_IGNOREINDEMO","const float", QW|NQ, D("This stuffcmd will NOT be written to mvds/qtv."), STUFFCMD_IGNOREINDEMO}, + {"STUFFCMD_DEMOONLY", "const float", QW|NQ, D("This stuffcmd will ONLY be written into mvds/qtv streams."), STUFFCMD_DEMOONLY}, + {"STUFFCMD_BROADCAST", "const float", QW|NQ, D("The stuffcmd will be broadcast server-wide (according to the mvd filters)."), STUFFCMD_BROADCAST}, /* {"SOUND_RELIABLE", "const float", QW|NQ, D("The sound will be sent reliably, and without regard to phs."), CF_RELIABLE}, {"SOUND_FORCELOOP", "const float", QW|NQ|CS,D("The sound will restart once it reaches the end of the sample."), CF_FORCELOOP}, diff --git a/plugins/terrorgen/terragen.c b/plugins/terrorgen/terragen.c new file mode 100644 index 000000000..ff0d2d106 --- /dev/null +++ b/plugins/terrorgen/terragen.c @@ -0,0 +1,139 @@ +/* +mod_terrain_create terrorgen; edit maps/terrorgen.hmp; map terrorgen +you can use mod_terrain_convert to generate+save the entire map for redistribution to people without this particular plugin version, ensuring longevity. +(this paticular command was meant to load+save the entire map, once mod_terrain_savever 2 is default...) + +FIXME: no way to speciffy which gen plugin to use for a particular map +*/ + +#include "../plugin.h" +#include "glquake.h" +#include "com_mesh.h" +#include "gl_terrain.h" + +static terrainfuncs_t *terr; +static modplugfuncs_t *modfuncs; + +static void TerrorGen_GenerateOne(heightmap_t *hm, int sx, int sy, hmsection_t *s) +{ + int x,y,i; + qbyte *lm; + + s->flags |= TSF_RELIGHT; + + //pick the textures to blend between. I'm just hardcoding shit here. this is meant to be some sort example. + Q_strlcpy(s->texname[0], "city4_2", sizeof(s->texname[0])); + Q_strlcpy(s->texname[1], "ground1_2", sizeof(s->texname[1])); + Q_strlcpy(s->texname[2], "ground1_8", sizeof(s->texname[2])); + Q_strlcpy(s->texname[3], "ground1_1", sizeof(s->texname[3])); + + for (y = 0, i=0; y < SECTHEIGHTSIZE; y++) + for (x = 0; x < SECTHEIGHTSIZE; x++, i++) + { + //calculate where it is in worldspace, if that's useful to you. + float wx = hm->sectionsize*(sx + x/(float)(SECTHEIGHTSIZE-1)); + float wy = hm->sectionsize*(sy + y/(float)(SECTHEIGHTSIZE-1)); + + //many shallow mounds, on a grid. + s->heights[i] = 128*sin(wx * (2*M_PI/1024)) * sin(wy * (2*M_PI/1024)); + + //calculate the RGBA tint. these are floats, so you can oversaturate. + s->colours[i][0] = 1; + s->colours[i][1] = 1; + s->colours[i][2] = 1; + s->colours[i][3] = 1; + } + + //make sure there's lightmap storage available + terr->InitLightmap(s, /*fill with default values*/true); + lm = terr->GetLightmap(s, 0, /*flag as edited*/true); + if (lm) + { //pleaseworkpleaseworkpleasework + for (y = 0; y < SECTTEXSIZE; y++, lm += (HMLMSTRIDE)*4) + for (x = 0; x < SECTTEXSIZE; x++) + { + //calculate where it is in worldspace, if that's useful to you. + float wx = hm->sectionsize*(sx + x/(float)(SECTTEXSIZE-1)); + float wy = hm->sectionsize*(sy + y/(float)(SECTTEXSIZE-1)); + + //calc which texture to use + //adds to 1, with texture[3] taking the remainder. + lm[x*4+0] = max(0, 255 - 255*fabs(wx/1024)); + lm[x*4+1] = max(0, 255 - 255*fabs(wy/1024)); + lm[x*4+2] = min(lm[x*4+0],lm[x*4+1]); + lm[x*4+0] -= lm[x*4+2]; + lm[x*4+1] -= lm[x*4+2]; + + //logically: lm[x*4+3] = 255-(lm[x*4+0]+lm[x*4+1]+lm[x*4+2]); + //however, the fourth channel is actually used as a lighting multiplier. + lm[x*4+3] = 255; + } + } + + //insert the occasional mesh... + if ((sx&3) == 0 && (sy&3) == 0) + { + vec3_t ang, org, axis[3]; + org[0] = hm->sectionsize*sx; + org[1] = hm->sectionsize*sy; + org[2] = 128; + VectorClear(ang); + ang[0] = sy*12.5; //lul + ang[1] = sx*12.5; + modfuncs->AngleVectors(ang, axis[0], axis[1], axis[2]); + VectorNegate(axis[1],axis[1]); //axis[1] needs to be left, not right. silly quakeisms. + + //obviously you can insert mdls instead... preferably do that! + terr->AddMesh(hm, TGS_TRYLOAD, NULL, "maps/dm4.bsp", org, axis, 1); + } +} + +#define GENBLOCKSIZE 1 +static qboolean QDECL TerrorGen_GenerateBlock(heightmap_t *hm, int sx, int sy, unsigned int tgsflags) +{ + hmsection_t *sect[GENBLOCKSIZE*GENBLOCKSIZE]; + int mx = sx & ~(GENBLOCKSIZE-1); + int my = sy & ~(GENBLOCKSIZE-1); + + if (!terr->GenerateSections(hm, mx, my, GENBLOCKSIZE, sect)) + return false; + + for (sy = 0; sy < GENBLOCKSIZE; sy++) + { + for (sx = 0; sx < GENBLOCKSIZE; sx++) + { + if (!sect[sx + sy*GENBLOCKSIZE]) + continue; //already in memory. + + TerrorGen_GenerateOne(hm, mx+sx-CHUNKBIAS, my+sy-CHUNKBIAS, sect[sx + sy*GENBLOCKSIZE]); + terr->FinishedSection(sect[sx + sy*GENBLOCKSIZE], true); + } + } + return true; +} + +static qintptr_t TerrorGen_Shutdown(qintptr_t *args) +{ //if its still us, make sure there's no dangling pointers. + if (terr->AutogenerateSection == TerrorGen_GenerateBlock) + terr->AutogenerateSection = NULL; + return true; +} +qintptr_t Plug_Init(qintptr_t *args) +{ + if (CHECKBUILTIN(Mod_GetPluginModelFuncs)) + { + modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t)); + if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION) + modfuncs = NULL; + } + + if (modfuncs && modfuncs->GetTerrainFuncs) + terr = modfuncs->GetTerrainFuncs(); + if (!terr) + return false; + if (!Plug_Export("Shutdown", TerrorGen_Shutdown)) + return false; + + terr->AutogenerateSection = TerrorGen_GenerateBlock; + return true; +} \ No newline at end of file diff --git a/plugins/terrorgen/terrorgen.vcproj b/plugins/terrorgen/terrorgen.vcproj new file mode 100644 index 000000000..0dfefa9ab --- /dev/null +++ b/plugins/terrorgen/terrorgen.vcproj @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +