diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index 9107cfe77..3d729a587 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -739,14 +739,14 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg) } // search nicks first - for (slot = 0; slot < MAX_CLIENTS; slot++) + for (slot = 0; slot < cl.allocated_client_slots; slot++) { s = &cl.players[slot]; if (s->name[0] && !s->spectator && !Q_strcasecmp(s->name, plrarg)) break; } - if (slot == MAX_CLIENTS) + if (slot == cl.allocated_client_slots) { // didn't find nick, so search userids int userid; @@ -766,14 +766,14 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg) userid = atoi(plrarg); - for (slot = 0; slot < MAX_CLIENTS; slot++) + for (slot = 0; slot < cl.allocated_client_slots; slot++) { s = &cl.players[slot]; if (s->name[0] && !s->spectator && s->userid == userid) break; } - if (slot == MAX_CLIENTS) + if (slot == cl.allocated_client_slots) { Con_Printf("Couldn't find userid %i\n", userid); return; diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index eda2ea420..3b4390a3e 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -845,7 +845,11 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case CG_S_STARTBACKGROUNDTRACK: + Media_BackgroundTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1])); + return 0; case CG_S_STOPBACKGROUNDTRACK: + Media_BackgroundTrack(NULL, NULL); + return 0; case CG_S_CLEARLOOPINGSOUNDS: break; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 20eca375c..125002701 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -1346,6 +1346,8 @@ void CL_Disconnect (void) FS_PureMode(0, NULL, NULL, 0); + Alias_WipeStuffedAliases(); + //now start up the csqc/menu module again. CSQC_UnconnectedInit(); } @@ -1361,8 +1363,6 @@ void CL_Disconnect_f (void) #endif CL_Disconnect (); - - Alias_WipeStuffedAliaes(); } /* @@ -4475,6 +4475,10 @@ void Host_Shutdown(void) //disconnect server/client/etc CL_Disconnect_f(); +#ifdef CSQC_DAT + CSQC_Shutdown(); +#endif + #ifdef VM_UI UI_Stop(); #endif diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index a1dfb4905..7ffd9a3a9 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -914,7 +914,7 @@ void CL_Sbar_Callback(struct cvar_s *var, char *oldvalue) { } -void SCR_CrosshairPosition(playerview_t *pview, int *x, int *y) +void SCR_CrosshairPosition(playerview_t *pview, float *x, float *y) { extern cvar_t cl_crossx, cl_crossy, crosshaircorrect, v_viewheight; diff --git a/engine/client/client.h b/engine/client/client.h index a07bc3587..351194432 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1368,6 +1368,7 @@ struct cin_s *Media_StartCin(char *name); texid_tf Media_UpdateForShader(cin_t *cin); void Media_ShutdownCin(cin_t *cin); qboolean Media_FakeTrack(int i, qboolean loop); +qboolean Media_BackgroundTrack(char *track, char *looptrack); #endif //these accept NULL for cin to mean the current fullscreen video diff --git a/engine/client/console.c b/engine/client/console.c index fb63e82c1..722fe6771 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1043,20 +1043,20 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y, } //put the cursor in the middle - x = (right-left)/2; + x = (right-left)/2 + left; //move the line to the right if there's not enough text to touch the right hand side - if (x < right-rhs) - x = right - rhs; + if (x < right-rhs - Font_CharWidth(0xe000|11|CON_WHITEMASK)) + x = right - rhs - Font_CharWidth(0xe000|11|CON_WHITEMASK); //if the left hand side is on the right of the left point (overrides right alignment) - if (x - lhs > 0) - x = lhs; + if (x > lhs + left) + x = lhs + left; - lhs = x - lhs + left; + lhs = x - lhs; for (cchar = maskedtext; cchar < cursor; cchar++) { lhs = Font_DrawChar(lhs, y, *cchar); } - rhs = x + left; + rhs = x; if (cursorframe) { // extern cvar_t com_parseutf8; @@ -1498,6 +1498,15 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in int i; int x; + if (l != con->footerline) + if (l != con->current) + { + y -= 8; + // draw arrows to show the buffer is backscrolled + for (x = sx ; xdisplay; - if (l != con_current->current) - { - y -= 8; - // draw arrows to show the buffer is backscrolled - for (x = sx ; xfromgame == fg_doom) - return; //no lightmaps. - for (j=1 ; j>1) */, sbar_rect.y + y + (sbar_rect.height-SBAR_HEIGHT), w, h, pic); } @@ -969,7 +971,7 @@ Sbar_DrawSubPic JACK: Draws a portion of the picture in the status bar. */ -void Sbar_DrawSubPic(int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight) +void Sbar_DrawSubPic(float x, float y, float width, float height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight) { R2D_SubPic (sbar_rect.x + x, sbar_rect.y + y+(sbar_rect.height-SBAR_HEIGHT), width, height, pic, srcx, srcy, srcwidth, srcheight); } @@ -981,10 +983,11 @@ Sbar_DrawCharacter Draws one solid graphics character ================ */ -void Sbar_DrawCharacter (int x, int y, int num) +void Sbar_DrawCharacter (float x, float y, int num) { - Font_BeginString(font_conchar, sbar_rect.x + x + 4, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &x, &y); - Font_DrawChar(x, y, num | 0xe000 | CON_WHITEMASK); + int px, py; + Font_BeginString(font_conchar, sbar_rect.x + x + 4, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &px, &py); + Font_DrawChar(px, py, num | 0xe000 | CON_WHITEMASK); Font_EndString(font_conchar); } @@ -993,19 +996,20 @@ void Sbar_DrawCharacter (int x, int y, int num) Sbar_DrawString ================ */ -void Sbar_DrawString (int x, int y, char *str) +void Sbar_DrawString (float x, float y, char *str) { Draw_FunString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str); } -void Sbar_DrawExpandedString (int x, int y, conchar_t *str) +void Sbar_DrawExpandedString (float x, float y, conchar_t *str) { Draw_ExpandedString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str); } -void Draw_TinyString (int x, int y, const qbyte *str) +void Draw_TinyString (float x, float y, const qbyte *str) { float xstart; + int px, py; if (!font_tiny) { @@ -1014,28 +1018,28 @@ void Draw_TinyString (int x, int y, const qbyte *str) return; } - Font_BeginString(font_tiny, x, y, &x, &y); - xstart = x; + Font_BeginString(font_tiny, x, y, &px, &py); + xstart = px; while (*str) { if (*str == '\n') { - x = xstart; - y += Font_CharHeight(); + px = xstart; + py += Font_CharHeight(); str++; continue; } - x = Font_DrawChar(x, y, CON_WHITEMASK|*str++); + px = Font_DrawChar(px, py, CON_WHITEMASK|*str++); } Font_EndString(font_tiny); } -void Sbar_DrawTinyString (int x, int y, char *str) +void Sbar_DrawTinyString (float x, float y, char *str) { Draw_TinyString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str); } -void Sbar_FillPC (int x, int y, int w, int h, unsigned int pcolour) +void Sbar_FillPC (float x, float y, float w, float h, unsigned int pcolour) { if (pcolour >= 16) { @@ -1048,7 +1052,7 @@ void Sbar_FillPC (int x, int y, int w, int h, unsigned int pcolour) R2D_FillBlock (x, y, w, h); } } -static void Sbar_FillPCDark (int x, int y, int w, int h, unsigned int pcolour) +static void Sbar_FillPCDark (float x, float y, float w, float h, unsigned int pcolour) { if (pcolour >= 16) { @@ -1104,7 +1108,7 @@ int Sbar_itoa (int num, char *buf) Sbar_DrawNum ============= */ -void Sbar_DrawNum (int x, int y, int num, int digits, int color) +void Sbar_DrawNum (float x, float y, int num, int digits, int color) { char str[12]; char *ptr; @@ -1151,7 +1155,7 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color) } } -void Sbar_Hexen2DrawNum (int x, int y, int num, int digits) +void Sbar_Hexen2DrawNum (float x, float y, int num, int digits) { char str[12]; char *ptr; @@ -1621,7 +1625,8 @@ void Sbar_DrawFrags (playerview_t *pv) { int i, k, l; int top, bottom; - int x, y, f; + float x, y; + int f; int ownnum; char num[12]; player_info_t *s; @@ -1878,7 +1883,7 @@ void Sbar_DrawScoreboard (void) } -static void Sbar_Hexen2DrawItem(playerview_t *pv, int x, int y, int itemnum) +static void Sbar_Hexen2DrawItem(playerview_t *pv, float x, float y, int itemnum) { int num; Sbar_DrawPic(x, y, 29, 28, R2D_SafeCachePic(va("gfx/arti%02d.lmp", itemnum))); @@ -2285,22 +2290,20 @@ static void Sbar_Voice(int y) loudness = S_Voip_Loudness(cl_voip_showmeter.ival==2); if (loudness >= 0) { - int x=0,t; + int w; + int x=0; int s, i; float range = loudness/100.0f; - Font_BeginString(font_conchar, x, y, &t, &t); - x = vid.width; - x -= Font_CharWidth(0xe080 | CON_WHITEMASK); - x -= Font_CharWidth(0xe081 | CON_WHITEMASK)*16; - x -= Font_CharWidth(0xe082 | CON_WHITEMASK); - x /= 2; - x -= Font_CharWidth('M' | CON_WHITEMASK); - x -= Font_CharWidth('i' | CON_WHITEMASK); - x -= Font_CharWidth('c' | CON_WHITEMASK); - x -= Font_CharWidth(' ' | CON_WHITEMASK); - - y = sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT; - Font_BeginString(font_conchar, x, y, &x, &y); + w = 0; + Font_BeginString(font_conchar, sbar_rect.x + sbar_rect.width/2, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &x, &y); + w += Font_CharWidth(0xe080 | CON_WHITEMASK); + w += Font_CharWidth(0xe081 | CON_WHITEMASK)*16; + w += Font_CharWidth(0xe082 | CON_WHITEMASK); + w += Font_CharWidth('M' | CON_WHITEMASK); + w += Font_CharWidth('i' | CON_WHITEMASK); + w += Font_CharWidth('c' | CON_WHITEMASK); + w += Font_CharWidth(' ' | CON_WHITEMASK); + x -= w/2; x = Font_DrawChar(x, y, 'M' | CON_WHITEMASK); x = Font_DrawChar(x, y, 'i' | CON_WHITEMASK); x = Font_DrawChar(x, y, 'c' | CON_WHITEMASK); @@ -2374,7 +2377,7 @@ void Sbar_Draw (playerview_t *pv) if (scr_centersbar.ival) { - int ofs = (sbar_rect.width - sbarwidth)/2; + float ofs = (sbar_rect.width - sbarwidth)/2; sbar_rect.x += ofs; sbar_rect.width -= ofs; } @@ -2465,13 +2468,6 @@ void Sbar_Draw (playerview_t *pv) Sbar_DrawNormal (pv); } - if (sb_lines > 24) - Sbar_Voice(-32); - else if (sb_lines > 0) - Sbar_Voice(-8); - else - Sbar_Voice(16); - if (minidmoverlay) Sbar_MiniDeathmatchOverlay (pv); @@ -2490,6 +2486,13 @@ void Sbar_Draw (playerview_t *pv) R2D_TileClear (sbar_rect.x + 320, r_refdef.grect.y+sbar_rect.height - sb_lines, sbar_rect.width - (320), sb_lines); } + if (sb_lines > 24) + Sbar_Voice(-32); + else if (sb_lines > 0) + Sbar_Voice(-8); + else + Sbar_Voice(16); + { extern int scr_chatmode; if (scr_chatmode) @@ -2505,7 +2508,7 @@ Sbar_IntermissionNumber ================== */ -void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color, qboolean left) +void Sbar_IntermissionNumber (float x, float y, int num, int digits, int color, qboolean left) { char str[12]; char *ptr; @@ -2563,6 +2566,9 @@ void Sbar_TeamOverlay (void) int plow, phigh, pavg; playerview_t *pv = r_refdef.playerview; + if (!pv) + pv = &cl.playerview[0]; + // request new ping times every two second if (!cl.teamplay) { diff --git a/engine/client/screen.h b/engine/client/screen.h index 1dae474b1..004d7e650 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -54,7 +54,7 @@ void SCR_ImageName (char *mapname); //this stuff is internal to the screen systems. void RSpeedShow(void); -void SCR_CrosshairPosition(playerview_t *pview, int *x, int *y); +void SCR_CrosshairPosition(playerview_t *pview, float *x, float *y); void SCR_DrawLoading (void); void SCR_TileClear (void); void SCR_DrawNotifyString (void); @@ -97,9 +97,9 @@ void Font_Init(void); void Font_Shutdown(void); struct font_s *Font_LoadFont(int height, char *fontfilename); void Font_Free(struct font_s *f); -void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); +void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py); void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/ -void Font_Transform(int vx, int vy, int *px, int *py); +void Font_Transform(float vx, float vy, int *px, int *py); int Font_CharHeight(void); float Font_CharScaleHeight(void); int Font_CharWidth(unsigned int charcode); diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 6e9b864f9..b664b7695 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -87,7 +87,7 @@ cvar_t snd_inactive = CVARAFD( "s_inactive", "0", "snd_inactive", 0, "Play sound while application is inactive (ex. tabbed out). Needs a snd_restart if changed." ); //set if you want sound even when tabbed out. -cvar_t _snd_mixahead = CVARAFD( "s_mixahead", "0.08", +cvar_t _snd_mixahead = CVARAFD( "s_mixahead", "0.1", "_snd_mixahead", CVAR_ARCHIVE, "Specifies how many seconds to prebuffer audio. Lower values give less latency, but might result in crackling. Different hardware/drivers have different tolerances."); cvar_t snd_leftisright = CVARAF( "s_swapstereo", "0", "snd_leftisright", CVAR_ARCHIVE); @@ -2032,7 +2032,7 @@ sfx_t *S_PrecacheSound (char *name) { sfx_t *sfx; - if (nosound.ival) + if (nosound.ival || !known_sfx) return NULL; sfx = S_FindName (name); diff --git a/engine/client/view.c b/engine/client/view.c index 058268552..717fef474 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1082,8 +1082,6 @@ void V_ApplyRefdef (void) //======================================== - r_refdef.flags = 0; - // intermission is always full screen if (cl.intermission || !r_refdef.drawsbar) size = 120; @@ -1202,6 +1200,7 @@ void V_ClearRefdef(playerview_t *pv) r_refdef.fov_y = 0; r_refdef.drawsbar = !cl.intermission; + r_refdef.flags = 0; } /* @@ -1410,7 +1409,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum) } } -void Draw_ExpandedString(int x, int y, conchar_t *str); +void Draw_ExpandedString(float x, float y, conchar_t *str); extern vec3_t nametagorg[MAX_CLIENTS]; extern qboolean nametagseen[MAX_CLIENTS]; void R_DrawNameTags(void) diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 94fd2d9cb..42509c553 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -214,7 +214,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define HUFFNETWORK //huffman network compression #define DOOMWADS //doom wad/sprite support // #define MAP_DOOM //doom map support - #define MAP_PROC //doom3/quake4 map support +// #define MAP_PROC //doom3/quake4 map support //#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet) #define Q2BSPS //quake 2 bsp support #define Q3BSPS //quake 3 bsp support diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 8817cc10c..7e44e1bcb 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -565,15 +565,6 @@ void Cmd_Echo_f (void) Con_Printf ("\n"); } -char *CopyString (char *in) -{ - char *out; - - out = (char*)Z_Malloc (strlen(in)+1); - strcpy (out, in); - return out; -} - void Cmd_ShowAlias_f (void) { cmdalias_t *a; @@ -764,7 +755,7 @@ void Cmd_Alias_f (void) a->value = newv; } else - a->value = CopyString(s); + a->value = Z_StrDup(s); } return; @@ -811,7 +802,7 @@ void Cmd_Alias_f (void) a->execlevel = 0; //run at users exec level a->restriction = 1; //this is possibly a security risk if the admin also changes execlevel } - a->value = CopyString (cmd); + a->value = Z_StrDup (cmd); } void Cmd_DeleteAlias(char *name) @@ -821,6 +812,7 @@ void Cmd_DeleteAlias(char *name) { a = cmd_alias; cmd_alias = cmd_alias->next; + Z_Free(a->value); Z_Free(a); return; } @@ -830,6 +822,7 @@ void Cmd_DeleteAlias(char *name) { b = a->next; a->next = b->next; + Z_Free(b->value); Z_Free(b); return; } @@ -966,19 +959,19 @@ void Alias_WriteAliases (vfsfile_t *f) } } -void Alias_WipeStuffedAliaes(void) +void Alias_WipeStuffedAliases(void) { - cmdalias_t *cmd, *n; - for (cmd=cmd_alias ; cmd ; ) + cmdalias_t **link, *cmd; + for (link=&cmd_alias ; (cmd=*link) ; ) { if (cmd->flags & ALIAS_FROMSERVER) { - n = cmd->next; - Cmd_DeleteAlias(cmd->name); - cmd = n; + *link = cmd->next; + Z_Free(cmd->value); + Z_Free(cmd); } else - cmd=cmd->next; + link=&(*link)->next; } } @@ -1521,6 +1514,21 @@ void Cmd_RemoveCommand (char *cmd_name) back = &cmd->next; } } +void Cmd_RemoveCommands (xcommand_t function) +{ + cmd_function_t *cmd, **back; + + for (back = &cmd_functions; (cmd = *back); ) + { + if (cmd->function == function) + { + *back = cmd->next; + Z_Free (cmd); + continue; + } + back = &cmd->next; + } +} void Cmd_RestrictCommand_f (void) { @@ -2433,13 +2441,13 @@ void Cbuf_ExecBlock(int level) exectext = newv; } else - exectext = CopyString(line); + exectext = Z_StrDup(line); // Con_Printf("Exec \"%s\"\n", line); } } else { - exectext = CopyString(line); + exectext = Z_StrDup(line); // Con_Printf("Exec \"%s\"\n", line); } remainingcbuf = Cbuf_StripText(level); //this craziness is to prevent an if } from breaking the entire con text diff --git a/engine/common/cmd.h b/engine/common/cmd.h index a09eeb0bd..18018600f 100644 --- a/engine/common/cmd.h +++ b/engine/common/cmd.h @@ -76,6 +76,7 @@ void Cmd_Init (void); void Cmd_Shutdown(void); void Cmd_StuffCmds (void); +void Cmd_RemoveCommands (xcommand_t function); //unregister all commands that use the same function. for wrappers and stuff. void Cmd_RemoveCommand (char *cmd_name); qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function); qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *description); @@ -110,7 +111,7 @@ int Cmd_CheckParm (char *parm); // where the given parameter apears, or 0 if not present char *Cmd_AliasExist(char *name, int restrictionlevel); -void Alias_WipeStuffedAliaes(void); +void Alias_WipeStuffedAliases(void); void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions); diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 9f78725d1..a2450dad9 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -1283,7 +1283,7 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float mesh->snormals_array = blerp>0.5?p2s:p1s; //never lerp mesh->tnormals_array = blerp>0.5?p2t:p1t; //never lerp - mesh->colors4f_array = NULL; //not generated + mesh->colors4f_array[0] = NULL; //not generated if (p1v == p2v || r_nolerp.value || !blerp) { @@ -1491,7 +1491,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in mesh->st_array = inf->ofs_st_array; mesh->trneighbors = inf->ofs_trineighbours; - mesh->colors4f_array = meshcache.colours; + mesh->colors4f_array[0] = meshcache.colours; if (meshcache.surfnum == inf->shares_verts && meshcache.ent == e) { @@ -4230,6 +4230,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) Mod_ClampModelSize(mod); + mod->type = mod_alias; mod->meshinfo = root; mod->funcs.NativeTrace = Mod_Trace; diff --git a/engine/common/common.c b/engine/common/common.c index b096e991e..a30e64305 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -73,10 +73,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #endif -#undef malloc -#undef free - - #define NUM_SAFE_ARGVS 6 usercmd_t nullcmd; // guarenteed to be zero diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 47b4c6e37..77521bea2 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -42,7 +42,7 @@ qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], v qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace); unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs); unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p); - +extern mplane_t *box_planes; extern char loadname[32]; @@ -357,8 +357,8 @@ static vecV_t *map_verts; //3points static int numvertexes; static vec2_t *map_vertstmexcoords; -static vec2_t *map_vertlstmexcoords[4]; -static vec4_t *map_colors4f_array; +static vec2_t *map_vertlstmexcoords[MAXLIGHTMAPS]; +static vec4_t *map_colors4f_array[MAXLIGHTMAPS]; static vec3_t *map_normals_array; static vec3_t *map_svector_array; static vec3_t *map_tvector_array; @@ -2085,11 +2085,11 @@ qboolean CModQ3_LoadVertexes (lump_t *l) tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); map_verts = out; map_vertstmexcoords = stout; - map_vertlstmexcoords[0] = lmout; - map_vertlstmexcoords[1] = lmout; - map_vertlstmexcoords[2] = lmout; - map_vertlstmexcoords[3] = lmout; - map_colors4f_array = cout; + for (i = 0; i < MAXLIGHTMAPS; i++) + { + map_vertlstmexcoords[i] = lmout; + map_colors4f_array[i] = cout; + } map_normals_array = nout; map_svector_array = sout; map_tvector_array = tout; @@ -2143,15 +2143,17 @@ qboolean CModRBSP_LoadVertexes (lump_t *l) out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); stout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*stout)); lmout = ZG_Malloc(&loadmodel->memgroup, MAXLIGHTMAPS*count*sizeof(*lmout)); - cout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*cout)); + cout = ZG_Malloc(&loadmodel->memgroup, MAXLIGHTMAPS*count*sizeof(*cout)); nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout)); tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout)); map_verts = out; map_vertstmexcoords = stout; for (sty = 0; sty < MAXLIGHTMAPS; sty++) + { map_vertlstmexcoords[sty] = lmout + sty*count; - map_colors4f_array = cout; + map_colors4f_array[sty] = cout + sty*count; + } map_normals_array = nout; map_svector_array = sout; map_tvector_array = tout; @@ -2170,9 +2172,12 @@ qboolean CModRBSP_LoadVertexes (lump_t *l) for (sty = 0; sty < MAXLIGHTMAPS; sty++) map_vertlstmexcoords[sty][i][j] = LittleFloat ( ((float *)in->texcoords)[j+2*(sty+1)] ); } - for ( j=0 ; j < 4 ; j++) + for (sty = 0; sty < MAXLIGHTMAPS; sty++) { - cout[i][j] = in->color[0][j]; + for ( j=0 ; j < 4 ; j++) + { + map_colors4f_array[sty][i][j] = in->color[sty][j]/255.0f; + } } } @@ -2472,7 +2477,11 @@ void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patc // fill in Patch_Evaluate ( map_verts[firstvert], patch_cp, step, mesh->xyz_array[0], sizeof(vecV_t)/sizeof(vec_t)); - Patch_Evaluate ( map_colors4f_array[firstvert], patch_cp, step, mesh->colors4f_array[0], 4 ); + for (sty = 0; sty < MAXLIGHTMAPS; sty++) + { + if (mesh->colors4f_array[sty]) + Patch_Evaluate ( map_colors4f_array[sty][firstvert], patch_cp, step, mesh->colors4f_array[sty][0], 4 ); + } Patch_Evaluate ( map_normals_array[firstvert], patch_cp, step, mesh->normals_array[0], 3 ); Patch_Evaluate ( map_vertstmexcoords[firstvert], patch_cp, step, mesh->st_array[0], 2 ); for (sty = 0; sty < MAXLIGHTMAPS; sty++) @@ -2542,8 +2551,8 @@ void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, void *cookie) for (sty = 0; sty < MAXLIGHTMAPS; sty++) { Vector2Copy(map_vertlstmexcoords[sty][fv + i], out->mesh->lmst_array[sty][i]); + Vector4Copy(map_colors4f_array[sty][fv + i], out->mesh->colors4f_array[sty][i]); } - Vector4Copy(map_colors4f_array[fv + i], out->mesh->colors4f_array[i]); VectorCopy(map_normals_array[fv + i], out->mesh->normals_array[i]); } @@ -2612,7 +2621,7 @@ void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, void *cookie) VectorCopy(map_verts[fv + i], out->mesh->xyz_array[i]); Vector2Copy(map_vertstmexcoords[fv + i], out->mesh->st_array[i]); Vector2Copy(map_vertlstmexcoords[0][fv + i], out->mesh->lmst_array[0][i]); - Vector4Copy(map_colors4f_array[fv + i], out->mesh->colors4f_array[i]); + Vector4Copy(map_colors4f_array[0][fv + i], out->mesh->colors4f_array[0][i]); VectorCopy(map_normals_array[fv + i], out->mesh->normals_array[i]); } @@ -3762,6 +3771,7 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c numvisibility = 0; numentitychars = 0; map_entitystring = NULL; + box_planes = NULL; //so its rebuilt loadmodel->type = mod_brush; @@ -4313,7 +4323,7 @@ void CM_InitBoxHull (void) box_model.hulls[0].available = true; - box_model.nodes = ZG_Malloc(&loadmodel->memgroup, sizeof(mnode_t)*6); + box_model.nodes = ZG_Malloc(&box_model.memgroup, sizeof(mnode_t)*6); box_planes = &map_planes[numplanes]; if (numbrushes+1 > SANITY_MAX_MAP_BRUSHES || numleafbrushes+1 > MAX_Q2MAP_LEAFBRUSHES diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 1dbaf8265..bb2208f25 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -590,9 +590,9 @@ void QCBUILTIN PF_getsurfacepointattribute(pubprogfuncs_t *prinst, struct global G_FLOAT(OFS_RETURN+2) = 0; break; case 6: - G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][0]; - G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][1]; - G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->colors4f_array[pointnum][2]; + G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->colors4f_array[0][pointnum][0]; + G_FLOAT(OFS_RETURN+1) = model->surfaces[surfnum].mesh->colors4f_array[0][pointnum][1]; + G_FLOAT(OFS_RETURN+2) = model->surfaces[surfnum].mesh->colors4f_array[0][pointnum][2]; //no way to return alpha here. break; } @@ -2224,16 +2224,15 @@ void QCBUILTIN PF_strconv (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa //returns a string containing one character per parameter (up to the qc max params of 8). void QCBUILTIN PF_chr2str (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { + int ch; int i; char string[128], *s = string; - if (VMUTF8) + for (i = 0; i < prinst->callargc; i++) { - for (i = 0; i < prinst->callargc; i++) - s += unicode_encode(s, G_FLOAT(OFS_PARM0 + i*3), (string+sizeof(string)-1)-s); - } - else - { - for (i = 0; i < prinst->callargc; i++) + ch = G_FLOAT(OFS_PARM0 + i*3); + if (VMUTF8 || ch > 0xff) + s += unicode_encode(s, ch, (string+sizeof(string)-1)-s); + else *s++ = G_FLOAT(OFS_PARM0 + i*3); } *s++ = '\0'; @@ -3496,7 +3495,7 @@ void QCBUILTIN PF_ArgV (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals /*negative indexes are relative to the end*/ if (idx < 0) - idx += qctoken_count; + idx += qctoken_count; if ((unsigned int)idx >= qctoken_count) G_INT(OFS_RETURN) = 0; diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index d0f49be7b..a6db1d5dd 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -84,6 +84,8 @@ char *PF_TempStr(pubprogfuncs_t *prinst); //returns a tempstring which can be fi extern cvar_t pr_tempstringsize; extern cvar_t pr_tempstringcount; +extern int qcinput_scan; +extern int qcinput_unicode; int MP_TranslateFTEtoQCCodes(int code); int MP_TranslateQCtoFTECodes(int code); @@ -349,6 +351,8 @@ void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_getmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); diff --git a/engine/common/zone.c b/engine/common/zone.c index 0c0d93f2d..e738d25de 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -24,9 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "winquake.h" #endif -#undef malloc -#undef free - #define NOZONE #ifdef _DEBUG diff --git a/engine/d3d/d3d11_backend.c b/engine/d3d/d3d11_backend.c index 22878eafd..671d8b9bd 100644 --- a/engine/d3d/d3d11_backend.c +++ b/engine/d3d/d3d11_backend.c @@ -1015,7 +1015,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa shaderstate.passsinglecolour = false; ret |= D3D_VDEC_COL4B; - if (shaderstate.batchvbo && (m->colors4f_array && + if (shaderstate.batchvbo && (m->colors4f_array[0] && ((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING) || (pass->rgbgen == RGB_GEN_VERTEX_EXACT) || (pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX)) && @@ -1029,8 +1029,8 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++) { m = shaderstate.meshlist[mno]; - colourgenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m); - alphagenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m); + colourgenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array[0], (byte_vec4_t*)map, m); + alphagenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array[0], (byte_vec4_t*)map, m); map += m->numvertexes*4; vertcount += m->numvertexes; } @@ -1683,7 +1683,7 @@ static void D3D11BE_Cull(unsigned int cullflags) rasterdesc.FillMode = D3D11_FILL_SOLID; rasterdesc.FrontCounterClockwise = false; rasterdesc.MultisampleEnable = false; - rasterdesc.ScissorEnable = false; + rasterdesc.ScissorEnable = true; rasterdesc.SlopeScaledDepthBias = 0.0f; ID3D11Device_CreateRasterizerState(pD3DDev11, &rasterdesc, &newrasterizerstate); @@ -1890,13 +1890,13 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *mesh) tmpvbo.svector.d3d.offs = (quintptr_t)&out[0].sdir - (quintptr_t)&out[0] + shaderstate.vertexstreamoffset; tmpvbo.tvector.d3d.buff = shaderstate.vertexstream; tmpvbo.tvector.d3d.offs = (quintptr_t)&out[0].tdir - (quintptr_t)&out[0] + shaderstate.vertexstreamoffset; - tmpvbo.colours.d3d.buff = shaderstate.vertexstream; - tmpvbo.colours.d3d.offs = (quintptr_t)&out[0].colorsb - (quintptr_t)&out[0] + shaderstate.vertexstreamoffset; + tmpvbo.colours[0].d3d.buff = shaderstate.vertexstream; + tmpvbo.colours[0].d3d.offs = (quintptr_t)&out[0].colorsb - (quintptr_t)&out[0] + shaderstate.vertexstreamoffset; //consumed shaderstate.vertexstreamoffset += sz; //now vomit into the buffer - if (!mesh->normals_array && mesh->colors4f_array) + if (!mesh->normals_array && mesh->colors4f_array[0]) { //2d drawing for (i = 0; i < mesh->numvertexes; i++) @@ -1906,7 +1906,7 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *mesh) VectorClear(out[i].ndir); VectorClear(out[i].sdir); VectorClear(out[i].tdir); - Vector4Scale(mesh->colors4f_array[i], 255, out[i].colorsb); + Vector4Scale(mesh->colors4f_array[0][i], 255, out[i].colorsb); } } else if (!mesh->normals_array && mesh->colors4b_array) @@ -1922,7 +1922,7 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *mesh) *(unsigned int*)out[i].colorsb = *(unsigned int*)mesh->colors4b_array[i]; } } - else if (mesh->normals_array && !mesh->colors4f_array && !mesh->colors4b_array) + else if (mesh->normals_array && !mesh->colors4f_array[0] && !mesh->colors4b_array) { //hlsl-lit models for (i = 0; i < mesh->numvertexes; i++) @@ -1961,11 +1961,11 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *mesh) Vector4Copy(mesh->colors4b_array[i], out[i].colorsb); } } - else if (mesh->colors4f_array) + else if (mesh->colors4f_array[0]) { for (i = 0; i < mesh->numvertexes; i++) { - Vector4Scale(mesh->colors4f_array[i], 255, out[i].colorsb); + Vector4Scale(mesh->colors4f_array[0][i], 255, out[i].colorsb); } } else @@ -2084,8 +2084,8 @@ void D3D11BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopba VectorCopy(m->tnormals_array[i], vbovdata->tdir); else VectorSet(vbovdata->tdir, 0, 1, 0); - if (m->colors4f_array) - Vector4Scale(m->colors4f_array[i], 255, vbovdata->colorsb); + if (m->colors4f_array[0]) + Vector4Scale(m->colors4f_array[0][i], 255, vbovdata->colorsb); else if (m->colors4b_array) Vector4Copy(m->colors4b_array[i], vbovdata->colorsb); else @@ -2143,8 +2143,8 @@ void D3D11BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopba vbo->svector.d3d.offs = (quintptr_t)&vbovdata->sdir; vbo->tvector.d3d.buff = vbuff; vbo->tvector.d3d.offs = (quintptr_t)&vbovdata->tdir; - vbo->colours.d3d.buff = vbuff; - vbo->colours.d3d.offs = (quintptr_t)&vbovdata->colorsb; + vbo->colours[0].d3d.buff = vbuff; + vbo->colours[0].d3d.offs = (quintptr_t)&vbovdata->colorsb; vbo->indicies.d3d.buff = ebuff; vbo->indicies.d3d.offs = 0; @@ -2931,7 +2931,22 @@ void D3D11BE_VBO_Destroy(vboarray_t *vearray) void D3D11BE_Scissor(srect_t *rect) { - //stub + D3D11_RECT drect; + if (rect) + { + drect.left = (rect->x)*vid.pixelwidth; + drect.right = (rect->x + rect->width)*vid.pixelwidth; + drect.bottom = (1-(rect->y))*vid.pixelheight; + drect.top = (1-(rect->y + rect->height))*vid.pixelheight; + } + else + { + drect.left = 0; + drect.right = vid.pixelwidth; + drect.top = 0; + drect.bottom = vid.pixelheight; + } + ID3D11DeviceContext_RSSetScissorRects(d3ddevctx, 1, &drect); } #endif diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index 37614f3d0..0394e5094 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -1094,7 +1094,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa m = shaderstate.meshlist[0]; - if (pass->flags & SHADER_PASS_NOCOLORARRAY) + if (1)//pass->flags & SHADER_PASS_NOCOLORARRAY) { shaderstate.passsinglecolour = true; shaderstate.passcolour = D3DCOLOR_RGBA(255,255,255,255); @@ -1108,13 +1108,14 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa shaderstate.passsinglecolour = false; ret |= D3D_VDEC_COL4B; - if (shaderstate.batchvbo && (m->colors4f_array && + if (shaderstate.batchvbo && (m->colors4f_array[0] && ((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING) || (pass->rgbgen == RGB_GEN_VERTEX_EXACT) || (pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX)) && (pass->alphagen == ALPHA_GEN_VERTEX))) { - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(vbovdata_t))); + //fixme + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours[0].d3d.buff, shaderstate.batchvbo->colours[0].d3d.offs, sizeof(vbovdata_t))); } else { @@ -1122,8 +1123,8 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa for (vertcount = 0, mno = 0; mno < shaderstate.nummeshes; mno++) { m = shaderstate.meshlist[mno]; - colourgenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m); - alphagenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array, (byte_vec4_t*)map, m); + colourgenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array[0], (byte_vec4_t*)map, m); + alphagenbyte(pass, m->numvertexes, m->colors4b_array, m->colors4f_array[0], (byte_vec4_t*)map, m); map += m->numvertexes*4; vertcount += m->numvertexes; } @@ -1617,6 +1618,7 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, NULL, 0, 0)); BindTexture(tmu, NULL); d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE)); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); tmu++; } shaderstate.lastpasscount = tmu; @@ -1829,6 +1831,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i { BindTexture(passno, NULL); d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_COLOROP, D3DTOP_DISABLE)); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); } shaderstate.lastpasscount = passno; @@ -1836,7 +1839,10 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i if (vdec & D3D_VDEC_COL4B) { if (shaderstate.batchvbo) - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(vbovdata_t))); + { + //fixme + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours[0].d3d.buff, shaderstate.batchvbo->colours[0].d3d.offs, sizeof(vbovdata_t))); + } else { int mno,v; @@ -1847,14 +1853,15 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i { byte_vec4_t *dest = (byte_vec4_t*)((char*)map+vertcount*sizeof(byte_vec4_t)); m = shaderstate.meshlist[mno]; - if (m->colors4f_array) + if (m->colors4f_array[0]) { for (v = 0; v < m->numvertexes; v++) { - dest[v][0] = bound(0, m->colors4f_array[v][0] * 255, 255); - dest[v][1] = bound(0, m->colors4f_array[v][1] * 255, 255); - dest[v][2] = bound(0, m->colors4f_array[v][2] * 255, 255); - dest[v][3] = bound(0, m->colors4f_array[v][3] * 255, 255); + //fixme: + dest[v][0] = bound(0, m->colors4f_array[0][v][0] * 255, 255); + dest[v][1] = bound(0, m->colors4f_array[0][v][1] * 255, 255); + dest[v][2] = bound(0, m->colors4f_array[0][v][2] * 255, 255); + dest[v][3] = bound(0, m->colors4f_array[0][v][3] * 255, 255); } } else if (m->colors4b_array) @@ -2110,6 +2117,7 @@ static void BE_DrawMeshChain_Internal(void) d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+passno, NULL, 0, 0)); BindTexture(passno, NULL); d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_COLOROP, D3DTOP_DISABLE)); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); passno++; } shaderstate.lastpasscount = 0; @@ -2207,8 +2215,8 @@ static void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t * vbo->svector.d3d.offs = (quintptr_t)&vbovdata->sdir; vbo->tvector.d3d.buff = vbuff; vbo->tvector.d3d.offs = (quintptr_t)&vbovdata->tdir; - vbo->colours.d3d.buff = vbuff; - vbo->colours.d3d.offs = (quintptr_t)&vbovdata->colorsb; + vbo->colours[0].d3d.buff = vbuff; + vbo->colours[0].d3d.offs = (quintptr_t)&vbovdata->colorsb; vbo->indicies.d3d.buff = ebuff; vbo->indicies.d3d.offs = 0; @@ -2231,7 +2239,7 @@ static void D3D9BE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t * VectorCopy(m->normals_array[i], vbovdata->ndir); VectorCopy(m->snormals_array[i], vbovdata->sdir); VectorCopy(m->tnormals_array[i], vbovdata->tdir); - Vector4Scale(m->colors4f_array[i], 255, vbovdata->colorsb); + Vector4Scale(m->colors4f_array[0][i], 255, vbovdata->colorsb); vbovdata++; } @@ -2459,12 +2467,12 @@ void D3D9BE_GenBrushModelVBO(model_t *mod) colours[vcount+v][2] = m->colors4b_array[v][2]; colours[vcount+v][3] = m->colors4b_array[v][3]; } - if (m->colors4f_array) + if (m->colors4f_array[0]) { - colours[vcount+v][0] = m->colors4f_array[v][0] * 255; - colours[vcount+v][1] = m->colors4f_array[v][1] * 255; - colours[vcount+v][2] = m->colors4f_array[v][2] * 255; - colours[vcount+v][3] = m->colors4f_array[v][3] * 255; + colours[vcount+v][0] = m->colors4f_array[0][v][0] * 255; + colours[vcount+v][1] = m->colors4f_array[0][v][1] * 255; + colours[vcount+v][2] = m->colors4f_array[0][v][2] * 255; + colours[vcount+v][3] = m->colors4f_array[0][v][3] * 255; } } vcount += v; diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 2c0184d4e..602c625af 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -1039,7 +1039,7 @@ static void (D3D9_SCR_UpdateScreen) (void) else #endif #ifdef CSQC_DAT - if (cls.state == ca_active && CSQC_DrawView()) + if (CSQC_DrawView()) nohud = true; else #endif diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index 204d0759d..d190c2987 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -1098,7 +1098,7 @@ static void (D3D11_SCR_UpdateScreen) (void) else #endif #ifdef CSQC_DAT - if (cls.state == ca_active && CSQC_DrawView()) + if (CSQC_DrawView()) nohud = true; else #endif diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 65ec4c73c..579ebe997 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1603,7 +1603,7 @@ static void R_DB_LightningBeam(batch_t *batch) mesh.xyz_array = points; mesh.indexes = indexarray; mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]); - mesh.colors4f_array = (vec4_t*)colors; + mesh.colors4f_array[0] = (vec4_t*)colors; mesh.normals_array = NULL; mesh.numvertexes = 4; mesh.st_array = texcoords; @@ -1673,7 +1673,7 @@ static void R_DB_RailgunBeam(batch_t *batch) mesh.xyz_array = points; mesh.indexes = indexarray; mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]); - mesh.colors4f_array = (vec4_t*)colors; + mesh.colors4f_array[0] = (vec4_t*)colors; mesh.normals_array = NULL; mesh.numvertexes = 4; mesh.st_array = texcoords; @@ -1825,7 +1825,7 @@ static void R_DB_Sprite(batch_t *batch) mesh.xyz_array = vertcoords; mesh.indexes = indexes; mesh.numindexes = sizeof(indexes)/sizeof(indexes[0]); - mesh.colors4f_array = colours; + mesh.colors4f_array[0] = colours; mesh.normals_array = NULL; mesh.numvertexes = 4; mesh.st_array = texcoords; @@ -1920,7 +1920,7 @@ static void R_DB_Poly(batch_t *batch) mesh.xyz_array = cl_strisvertv + cl_stris[i].firstvert; mesh.st_array = cl_strisvertt + cl_stris[i].firstvert; - mesh.colors4f_array = cl_strisvertc + cl_stris[i].firstvert; + mesh.colors4f_array[0] = cl_strisvertc + cl_stris[i].firstvert; mesh.indexes = cl_strisidx + cl_stris[i].firstidx; mesh.numindexes = cl_stris[i].numidx; mesh.numvertexes = cl_stris[i].numvert; @@ -2024,7 +2024,7 @@ void BE_GenModelBatches(batch_t **batches) switch(ent->model->type) { case mod_brush: - if (r_drawentities.ival == 2) + if (r_drawentities.ival == 2 || !lightmap) continue; Surf_GenBrushBatches(batches, ent); break; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index d2e5d1a61..cc0c1e252 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -154,7 +154,8 @@ struct { int pendingtexcoordvbo[SHADER_TMU_MAX]; void *pendingtexcoordpointer[SHADER_TMU_MAX]; - float identitylighting; //set to how bright lightmaps should be (reduced for overbright or realtime_world_lightmaps) + float identitylighting; //set to how bright world lighting should be (reduced by realtime_world_lightmaps) + float identitylightmap; //set to how bright lightmaps should be (reduced by overbrights+realtime_world_lightmaps) texid_t temptexture; //$current texid_t fogtexture; @@ -272,7 +273,7 @@ static void BE_SetPassBlendMode(int tmu, int pbm) qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); break; case PBM_REPLACELIGHT: - if (shaderstate.identitylighting != 1) + // if (shaderstate.identitylighting != 1) goto forcemod; GL_TexEnv(GL_REPLACE); break; @@ -565,13 +566,25 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend } break; case VATTR_COLOUR: - if (shaderstate.sourcevbo->colours.gl.addr) + if (shaderstate.sourcevbo->colours[0].gl.addr) { - GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo); - qglVertexAttribPointer(VATTR_COLOUR, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours.gl.addr); + GL_SelectVBO(shaderstate.sourcevbo->colours[0].gl.vbo); + qglVertexAttribPointer(VATTR_COLOUR, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[0].gl.addr); break; } break; + case VATTR_COLOUR2: + GL_SelectVBO(shaderstate.sourcevbo->colours[1].gl.vbo); + qglVertexAttribPointer(VATTR_COLOUR2, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[1].gl.addr); + break; + case VATTR_COLOUR3: + GL_SelectVBO(shaderstate.sourcevbo->colours[2].gl.vbo); + qglVertexAttribPointer(VATTR_COLOUR3, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[2].gl.addr); + break; + case VATTR_COLOUR4: + GL_SelectVBO(shaderstate.sourcevbo->colours[3].gl.vbo); + qglVertexAttribPointer(VATTR_COLOUR4, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[3].gl.addr); + break; case VATTR_TEXCOORD: GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo); qglVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->texcoord.gl.addr); @@ -1286,6 +1299,7 @@ void GLBE_Init(void) } shaderstate.identitylighting = 1; + shaderstate.identitylightmap = 1; for (i = 0; i < MAXLIGHTMAPS; i++) shaderstate.dummybatch.lightmap[i] = -1; @@ -1611,6 +1625,7 @@ static void GenerateTCMods(const shaderpass_t *pass, int passnum) //dest is packed too static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *dst, const mesh_t *mesh) { + int n = cnt; switch (pass->rgbgen) { case RGB_GEN_ENTITY: @@ -1630,6 +1645,23 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds } break; case RGB_GEN_VERTEX_LIGHTING: + if (mesh->colors4f_array[1]) + { + float lm[4]; + lm[0] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f*shaderstate.identitylighting; + lm[1] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[1]]/256.0f*shaderstate.identitylighting; + lm[2] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[2]]/256.0f*shaderstate.identitylighting; + lm[3] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[3]]/256.0f*shaderstate.identitylighting; + while((cnt)--) + { + VectorScale( mesh->colors4f_array[0][cnt], lm[0], dst[cnt]); + VectorMA(dst[cnt], lm[1], mesh->colors4f_array[1][cnt], dst[cnt]); + VectorMA(dst[cnt], lm[2], mesh->colors4f_array[2][cnt], dst[cnt]); + VectorMA(dst[cnt], lm[3], mesh->colors4f_array[3][cnt], dst[cnt]); + } + break; + } + if (shaderstate.identitylighting != 1) { if (!src) @@ -1678,13 +1710,14 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds } break; case RGB_GEN_IDENTITY_LIGHTING: - if (shaderstate.curbatch->lightstyle[0] != 255) + if (shaderstate.curbatch->vtlightstyle[0] != 255 && d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]] != 256) { + //FIXME: while((cnt)--) { - dst[cnt][0] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[0]]/256.0f; - dst[cnt][1] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[0]]/256.0f; - dst[cnt][2] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[0]]/256.0f; + dst[cnt][0] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f; + dst[cnt][1] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f; + dst[cnt][2] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f; } } else @@ -1698,13 +1731,21 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds } } break; + case RGB_GEN_IDENTITY_OVERBRIGHT: + while((cnt)--) + { + dst[cnt][0] = shaderstate.identitylightmap; + dst[cnt][1] = shaderstate.identitylightmap; + dst[cnt][2] = shaderstate.identitylightmap; + } + break; default: case RGB_GEN_IDENTITY: while((cnt)--) { - dst[cnt][0] = 1; - dst[cnt][1] = 1; - dst[cnt][2] = 1; + dst[cnt][0] = shaderstate.identitylighting; + dst[cnt][1] = shaderstate.identitylighting; + dst[cnt][2] = shaderstate.identitylighting; } break; case RGB_GEN_CONST: @@ -2189,8 +2230,8 @@ static void GenerateColourMods(const shaderpass_t *pass) if (pass->flags & SHADER_PASS_NOCOLORARRAY && qglColor4fv) { - colourgen(pass, 1, meshlist->colors4f_array, &shaderstate.pendingcolourflat, meshlist); - alphagen(pass, 1, meshlist->colors4f_array, &shaderstate.pendingcolourflat, meshlist); + colourgen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist); + alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist); shaderstate.pendingcolourvbo = 0; shaderstate.pendingcolourpointer = NULL; } @@ -2202,7 +2243,7 @@ static void GenerateColourMods(const shaderpass_t *pass) if (shaderstate.mode == BEM_DEPTHDARK || shaderstate.mode == BEM_DEPTHONLY) { shaderstate.pendingcolourflat[0] = shaderstate.pendingcolourflat[1] = shaderstate.pendingcolourflat[2] = 0; - alphagen(pass, 1, meshlist->colors4f_array, &shaderstate.pendingcolourflat, meshlist); + alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist); shaderstate.pendingcolourvbo = 0; shaderstate.pendingcolourpointer = NULL; return; @@ -2210,7 +2251,7 @@ static void GenerateColourMods(const shaderpass_t *pass) if (shaderstate.mode == BEM_LIGHT) { shaderstate.pendingcolourflat[0] = shaderstate.pendingcolourflat[1] = shaderstate.pendingcolourflat[2] = 1; - alphagen(pass, 1, meshlist->colors4f_array, &shaderstate.pendingcolourflat, meshlist); + alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist); shaderstate.pendingcolourvbo = 0; shaderstate.pendingcolourpointer = NULL; return; @@ -2228,8 +2269,8 @@ static void GenerateColourMods(const shaderpass_t *pass) //if its vetex lighting, just use the vbo if (((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING && shaderstate.identitylighting == 1) || pass->rgbgen == RGB_GEN_VERTEX_EXACT) && pass->alphagen == ALPHA_GEN_VERTEX) { - shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours.gl.vbo; - shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours.gl.addr; + shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo; + shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr; return; } @@ -2237,8 +2278,8 @@ static void GenerateColourMods(const shaderpass_t *pass) { meshlist = shaderstate.meshes[m]; - colourgen(pass, meshlist->numvertexes, meshlist->colors4f_array, coloursarray + meshlist->vbofirstvert, meshlist); - alphagen(pass, meshlist->numvertexes, meshlist->colors4f_array, coloursarray + meshlist->vbofirstvert, meshlist); + colourgen(pass, meshlist->numvertexes, meshlist->colors4f_array[0], coloursarray + meshlist->vbofirstvert, meshlist); + alphagen(pass, meshlist->numvertexes, meshlist->colors4f_array[0], coloursarray + meshlist->vbofirstvert, meshlist); } shaderstate.colourarraytype = GL_FLOAT; @@ -2638,9 +2679,9 @@ static void DrawPass(const shaderpass_t *pass) shaderstate.pendingcolourvbo = 0; shaderstate.pendingcolourpointer = NULL; - shaderstate.pendingcolourflat[0] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f; - shaderstate.pendingcolourflat[1] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f; - shaderstate.pendingcolourflat[2] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f; + shaderstate.pendingcolourflat[0] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lmlightstyle[j]]/256.0f; + shaderstate.pendingcolourflat[1] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lmlightstyle[j]]/256.0f; + shaderstate.pendingcolourflat[2] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lmlightstyle[j]]/256.0f; shaderstate.pendingcolourflat[3] = 1; /*pick the correct st coords for this lightmap pass*/ @@ -2755,6 +2796,42 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, qglUniform2fvARB(ph, 1, shaderstate.meshes[0]->xyz_blendw); break; + case SP_E_VLSCALE: + if (perm & PERMUTATION_LIGHTSTYLES) + { + vec4_t colscale[MAXLIGHTMAPS]; + int j, s; + for (j = 0; j < MAXLIGHTMAPS ; j++) + { + s = shaderstate.curbatch->vtlightstyle[j]; + if (s == 255) + { + for (; j < MAXLIGHTMAPS ; j++) + { + colscale[j][0] = 0; + colscale[j][1] = 0; + colscale[j][2] = 0; + colscale[j][3] = 1; + } + break; + } + if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT) + { + float sc = (1<lightstyle[j]; + s = shaderstate.curbatch->lmlightstyle[j]; if (s == 255) { for (; j < MAXLIGHTMAPS ; j++) @@ -3768,26 +3845,26 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *m) //FIXME: lightmaps - if (m->colors4f_array) + if (m->colors4f_array[0]) { - memcpy(buffer+len, m->colors4f_array, sizeof(*m->colors4f_array) * m->numvertexes); - shaderstate.dummyvbo.colours.gl.addr = (void*)len; - shaderstate.dummyvbo.colours.gl.vbo = shaderstate.streamvbo[shaderstate.streamid]; - len += sizeof(*m->colors4f_array) * m->numvertexes; + memcpy(buffer+len, m->colors4f_array[0], sizeof(*m->colors4f_array[0]) * m->numvertexes); + shaderstate.dummyvbo.colours[0].gl.addr = (void*)len; + shaderstate.dummyvbo.colours[0].gl.vbo = shaderstate.streamvbo[shaderstate.streamid]; + len += sizeof(*m->colors4f_array[0]) * m->numvertexes; shaderstate.colourarraytype = GL_FLOAT; } else if (m->colors4b_array) { memcpy(buffer+len, m->colors4b_array, sizeof(*m->colors4b_array) * m->numvertexes); - shaderstate.dummyvbo.colours.gl.addr = (void*)len; - shaderstate.dummyvbo.colours.gl.vbo = shaderstate.streamvbo[shaderstate.streamid]; + shaderstate.dummyvbo.colours[0].gl.addr = (void*)len; + shaderstate.dummyvbo.colours[0].gl.vbo = shaderstate.streamvbo[shaderstate.streamid]; len += sizeof(*m->colors4b_array) * m->numvertexes; shaderstate.colourarraytype = GL_UNSIGNED_BYTE; } else { - shaderstate.dummyvbo.colours.gl.addr = NULL; - shaderstate.dummyvbo.colours.gl.vbo = 0; + shaderstate.dummyvbo.colours[0].gl.addr = NULL; + shaderstate.dummyvbo.colours[0].gl.vbo = 0; shaderstate.colourarraytype = GL_FLOAT; } @@ -3813,15 +3890,15 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *m) shaderstate.dummyvbo.normals.gl.addr = m->normals_array; shaderstate.dummyvbo.svector.gl.addr = m->snormals_array; shaderstate.dummyvbo.tvector.gl.addr = m->tnormals_array; - if (m->colors4f_array) + if (m->colors4f_array[0]) { shaderstate.colourarraytype = GL_FLOAT; - shaderstate.dummyvbo.colours.gl.addr = m->colors4f_array; + shaderstate.dummyvbo.colours[0].gl.addr = m->colors4f_array[0]; } else { shaderstate.colourarraytype = GL_UNSIGNED_BYTE; - shaderstate.dummyvbo.colours.gl.addr = m->colors4b_array; + shaderstate.dummyvbo.colours[0].gl.addr = m->colors4b_array; } shaderstate.dummyvbo.bonenums.gl.addr = m->bonenums; shaderstate.dummyvbo.boneweights.gl.addr = m->boneweights; @@ -4553,7 +4630,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis) else #endif shaderstate.identitylighting = 1; -// shaderstate.identitylighting /= 1<charheight; curfont_scaled = false; } -void Font_Transform(int vx, int vy, int *px, int *py) +void Font_Transform(float vx, float vy, int *px, int *py) { if (px) *px = (vx*(int)vid.rotpixelwidth) / (float)vid.width; diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index a6f86c44e..b645e9a85 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -447,7 +447,7 @@ static hmsection_t *Terr_ReadSection(heightmap_t *hm, hmsection_t *s, int sx, in lightmap[s->lightmap]->rectchange.h = HMLMSTRIDE; } - s->mesh.colors4f_array = s->colours; + s->mesh.colors4f_array[0] = s->colours; if (ds->flags & TSF_HASCOLOURS) { for (i = 0, colours = (float*)ptr; i < SECTHEIGHTSIZE*SECTHEIGHTSIZE; i++, colours+=4) @@ -1205,7 +1205,7 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y) BZ_Free(mesh->indexes); mesh->indexes = BZ_Malloc(sizeof(index_t) * SECTHEIGHTSIZE*SECTHEIGHTSIZE*6*3); mesh->numindexes = 0; - mesh->colors4f_array = NULL; + mesh->colors4f_array[0] = NULL; for (vy = 0; vy < SECTHEIGHTSIZE-1; vy++) { @@ -1395,7 +1395,7 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y) mesh->st_array = (void*) (mesh->xyz_array + (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE)); mesh->lmst_array[0] = (void*) (mesh->st_array + (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE)); } - mesh->colors4f_array = s->colours; + mesh->colors4f_array[0] = s->colours; mesh->numvertexes = 0; /*64 quads across requires 65 verticies*/ for (vy = 0; vy < SECTHEIGHTSIZE; vy++) @@ -1504,8 +1504,8 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y) s->vbo.texcoord.gl.vbo = s->vbo.coord.gl.vbo; s->vbo.lmcoord[0].gl.addr = (void*)((char*)mesh->lmst_array[0] - (char*)mesh->xyz_array); s->vbo.lmcoord[0].gl.vbo = s->vbo.coord.gl.vbo; - s->vbo.colours.gl.addr = (void*)((sizeof(vecV_t)+sizeof(vec2_t)+sizeof(vec2_t)) * mesh->numvertexes); - s->vbo.colours.gl.vbo = s->vbo.coord.gl.vbo; + s->vbo.colours[0].gl.addr = (void*)((sizeof(vecV_t)+sizeof(vec2_t)+sizeof(vec2_t)) * mesh->numvertexes); + s->vbo.colours[0].gl.vbo = s->vbo.coord.gl.vbo; // Z_Free(mesh->xyz_array); // mesh->xyz_array = NULL; // mesh->st_array = NULL; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index ada59d509..ec2740a45 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -128,13 +128,13 @@ void Mod_BatchList_f(void) for (batch = mod->batches[i]; batch; batch = batch->next) { if (batch->lightmap[3] >= 0) - Con_Printf("%s lm=(%i:%i %i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->lightmap[2], batch->lightstyle[2], batch->lightmap[3], batch->lightstyle[3], batch->maxmeshes); + Con_Printf("%s lm=(%i:%i %i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->lightmap[2], batch->lmlightstyle[2], batch->lightmap[3], batch->lmlightstyle[3], batch->maxmeshes); else if (batch->lightmap[2] >= 0) - Con_Printf("%s lm=(%i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->lightmap[2], batch->lightstyle[2], batch->maxmeshes); + Con_Printf("%s lm=(%i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->lightmap[2], batch->lmlightstyle[2], batch->maxmeshes); else if (batch->lightmap[1] >= 0) - Con_Printf("%s lm=(%i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->maxmeshes); - else if (batch->lightstyle[0] != 255) - Con_Printf("%s lm=(%i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->maxmeshes); + Con_Printf("%s lm=(%i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->maxmeshes); + else if (batch->lmlightstyle[0] != 255) + Con_Printf("%s lm=(%i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->maxmeshes); else Con_Printf("%s lm=%i surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->maxmeshes); count++; @@ -2472,11 +2472,14 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, void *cookie) VectorNormalize(mesh->snormals_array[i]); VectorNormalize(mesh->tnormals_array[i]); - //q1bsp has no colour information (fixme: sample from the lightmap) - mesh->colors4f_array[i][0] = 1; - mesh->colors4f_array[i][1] = 1; - mesh->colors4f_array[i][2] = 1; - mesh->colors4f_array[i][3] = 1; + //q1bsp has no colour information (fixme: sample from the lightmap?) + for (sty = 0; sty < 1; sty++) + { + mesh->colors4f_array[sty][i][0] = 1; + mesh->colors4f_array[sty][i][1] = 1; + mesh->colors4f_array[sty][i][2] = 1; + mesh->colors4f_array[sty][i][3] = 1; + } } } @@ -2492,24 +2495,35 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi int sty; vbo_t vbo; int styles = mod->lightmaps.surfstyles; + char *ptr; vbo.indicies.dummy = ZG_Malloc(&loadmodel->memgroup, sizeof(index_t) * maxindicies); - vbo.coord.dummy = ZG_Malloc(&loadmodel->memgroup, (sizeof(vecV_t)+sizeof(vec2_t)*(1+styles)+sizeof(vec3_t)*3+sizeof(vec4_t))* maxverts); - vbo.colours.dummy = (vecV_t*)vbo.coord.dummy + maxverts; - vbo.texcoord.dummy = (vec4_t*)vbo.colours.dummy + maxverts; - sty = 0; - if (styles) + ptr = ZG_Malloc(&loadmodel->memgroup, (sizeof(vecV_t)+sizeof(vec2_t)*(1+styles)+sizeof(vec3_t)*3+sizeof(vec4_t)*styles)* maxverts); + vbo.coord.dummy = ptr; + ptr += sizeof(vecV_t)*maxverts; + for (sty = 0; sty < styles; sty++) { - vbo.lmcoord[0].dummy = (vec2_t*)vbo.texcoord.dummy + maxverts; - sty = 1; + vbo.colours[sty].dummy = ptr; + ptr += sizeof(vec4_t)*maxverts; } + for (; sty < MAXLIGHTMAPS; sty++) + vbo.colours[sty].dummy = NULL; + vbo.texcoord.dummy = ptr; + ptr += sizeof(vec2_t)*maxverts; + sty = 0; for (; sty < styles; sty++) - vbo.lmcoord[sty].dummy = (vec2_t*)vbo.lmcoord[sty-1].dummy + maxverts; + { + vbo.lmcoord[sty].dummy = ptr; + ptr += sizeof(vec2_t)*maxverts; + } for (; sty < MAXLIGHTMAPS; sty++) vbo.lmcoord[sty].dummy = NULL; - vbo.normals.dummy = styles?((vec2_t*)vbo.lmcoord[styles-1].dummy + maxverts):((vec2_t*)vbo.texcoord.dummy + maxverts); - vbo.svector.dummy = (vec3_t*)vbo.normals.dummy + maxverts; - vbo.tvector.dummy = (vec3_t*)vbo.svector.dummy + maxverts; + vbo.normals.dummy = ptr; + ptr += sizeof(vec3_t)*maxverts; + vbo.svector.dummy = ptr; + ptr += sizeof(vec3_t)*maxverts; + vbo.tvector.dummy = ptr; + ptr += sizeof(vec3_t)*maxverts; numindicies = 0; numverts = 0; @@ -2539,11 +2553,14 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi mesh->lmst_array[sty] = (vec2_t*)vbo.lmcoord[sty].dummy + mesh->vbofirstvert; else mesh->lmst_array[sty] = NULL; + if (vbo.colours[sty].dummy) + mesh->colors4f_array[sty] = (vec4_t*)vbo.colours[sty].dummy + mesh->vbofirstvert; + else + mesh->colors4f_array[sty] = NULL; } mesh->normals_array = (vec3_t*)vbo.normals.dummy + mesh->vbofirstvert; mesh->snormals_array = (vec3_t*)vbo.svector.dummy + mesh->vbofirstvert; mesh->tnormals_array = (vec3_t*)vbo.tvector.dummy + mesh->vbofirstvert; - mesh->colors4f_array = (vec4_t*)vbo.colours.dummy + mesh->vbofirstvert; mesh->indexes = (index_t*)vbo.indicies.dummy + mesh->vbofirstelement; mesh->vbofirstvert = 0; @@ -2765,21 +2782,21 @@ static void Mod_Batches_SplitLightmaps(model_t *mod) for (sty = 0; sty < MAXLIGHTMAPS; sty++) { batch->lightmap[sty] = surf->lightmaptexturenums[sty]; - batch->lightstyle[sty] = surf->styles[sty]; + batch->lmlightstyle[sty] = surf->styles[sty]; } for (j = 1; j < batch->maxmeshes; j++) { surf = (msurface_t*)batch->mesh[j]; - if (surf->lightmaptexturenums[0] != batch->lightmap[0] || - surf->lightmaptexturenums[1] != batch->lightmap[1] || - surf->lightmaptexturenums[2] != batch->lightmap[2] || - surf->lightmaptexturenums[3] != batch->lightmap[3] || - //fixme: we should merge later (reverted matching) surfaces into the prior batch - surf->styles[0] != batch->lightstyle[0] || - surf->styles[1] != batch->lightstyle[1] || - surf->styles[2] != batch->lightstyle[2] || - surf->styles[3] != batch->lightstyle[3] ) + for (sty = 0; sty < MAXLIGHTMAPS; sty++) + { + if (surf->lightmaptexturenums[sty] != batch->lightmap[sty] || + //fixme: we should merge later (reverted matching) surfaces into the prior batch + surf->styles[sty] != batch->lmlightstyle[sty] || + surf->vlstyles[sty] != batch->vtlightstyle[sty]) + break; + } + if (sty < MAXLIGHTMAPS) { nb = ZG_Malloc(&loadmodel->memgroup, sizeof(*batch)); *nb = *batch; @@ -2791,7 +2808,8 @@ static void Mod_Batches_SplitLightmaps(model_t *mod) for (sty = 0; sty < MAXLIGHTMAPS; sty++) { nb->lightmap[sty] = surf->lightmaptexturenums[sty]; - nb->lightstyle[sty] = surf->styles[sty]; + nb->lmlightstyle[sty] = surf->styles[sty]; + nb->vtlightstyle[sty] = surf->vlstyles[sty]; } memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes); @@ -2833,7 +2851,8 @@ static void Mod_Batches_AllocLightmaps(model_t *mod) for (sty = 0; sty < MAXLIGHTMAPS; sty++) { batch->lightmap[sty] = surf->lightmaptexturenums[sty]; - batch->lightstyle[sty] = 255;//don't do special backend rendering of lightstyles. + batch->lmlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. + batch->vtlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. } for (j = 1; j < batch->maxmeshes; j++) diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 3e0b2e181..2e5e06a2e 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -82,7 +82,7 @@ typedef struct mesh_s vec3_t *tnormals_array;/*required for rtlighting*/ vec2_t *st_array; /*texture coords*/ vec2_t *lmst_array[MAXLIGHTMAPS]; /*second texturecoord set (merely dubbed lightmap, one for each potential lightstyle)*/ - avec4_t *colors4f_array;/*floating point colours array*/ + avec4_t *colors4f_array[MAXLIGHTMAPS];/*floating point colours array*/ byte_vec4_t *colors4b_array;/*byte colours array*/ index_t *indexes; @@ -113,15 +113,16 @@ typedef struct batch_s shader_t *shader; struct vbo_s *vbo; entity_t *ent; /*used for shader properties*/ - int lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/ - - unsigned char lightstyle[MAXLIGHTMAPS]; struct mfog_s *fog; - struct texture_s *texture; /*is this used by the backend?*/ - struct texnums_s *skin; + short lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/ + unsigned char lmlightstyle[MAXLIGHTMAPS]; + unsigned char vtlightstyle[MAXLIGHTMAPS]; + unsigned int maxmeshes; /*not used by backend*/ unsigned int flags; /*backend flags (force transparency etc)*/ + struct texture_s *texture; /*is this used by the backend?*/ + struct texnums_s *skin; void (*buildmeshes)(struct batch_s *b); /*caller-use, not interpreted by backend*/ @@ -267,7 +268,7 @@ typedef struct vbo_s vboarray_t svector; vboarray_t tvector; - vboarray_t colours; + vboarray_t colours[MAXLIGHTMAPS]; vboarray_t bonenums; @@ -395,6 +396,7 @@ typedef struct msurface_s int lightmaptexturenums[MAXLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps qbyte styles[MAXLIGHTMAPS]; + qbyte vlstyles[MAXLIGHTMAPS]; int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap qboolean cached_dlight; // true if dynamic light in cache qbyte cached_colour[MAXLIGHTMAPS]; diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 5ec81e1cb..35562d1cf 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -171,7 +171,7 @@ void R_InitFlashblends(void) flashblend_mesh.numvertexes = FLASHBLEND_VERTS+1; flashblend_mesh.xyz_array = flashblend_vcoords; flashblend_mesh.st_array = flashblend_tccoords; - flashblend_mesh.colors4f_array = flashblend_colours; + flashblend_mesh.colors4f_array[0] = flashblend_colours; flashblend_mesh.indexes = flashblend_indexes; flashblend_mesh.numindexes = FLASHBLEND_VERTS*3; flashblend_mesh.istrifan = true; @@ -179,7 +179,7 @@ void R_InitFlashblends(void) flashblend_fsmesh.numvertexes = 4; flashblend_fsmesh.xyz_array = flashblend_vcoords; flashblend_fsmesh.st_array = flashblend_tccoords; - flashblend_fsmesh.colors4f_array = flashblend_colours; + flashblend_fsmesh.colors4f_array[0] = flashblend_colours; flashblend_fsmesh.indexes = flashblend_fsindexes; flashblend_fsmesh.numindexes = 6; flashblend_fsmesh.istrifan = true; diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 70b893ee6..121b9bf26 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -92,6 +92,18 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int } for (s = 0; s < MAXLIGHTMAPS; s++) { + if (vbo->colours[s].gl.addr) + { + vbo->colours[s].gl.vbo = vbos[0]; + vbo->colours[s].gl.addr = (vec4_t*)((char*)vbo->colours[s].gl.addr - (char*)vdata); + switch(s) + { + default: vaostatic |= VATTR_COLOUR; break; + case 1: vaostatic |= VATTR_COLOUR2; break; + case 2: vaostatic |= VATTR_COLOUR3; break; + case 3: vaostatic |= VATTR_COLOUR4; break; + } + } if (vbo->lmcoord[s].gl.addr) { vbo->lmcoord[s].gl.vbo = vbos[0]; @@ -123,12 +135,7 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int vbo->tvector.gl.addr = (vec3_t*)((char*)vbo->tvector.gl.addr - (char*)vdata); vaostatic |= VATTR_TNORMALS; } - if (vbo->colours.gl.addr) - { - vbo->colours.gl.vbo = vbos[0]; - vbo->colours.gl.addr = (vec4_t*)((char*)vbo->colours.gl.addr - (char*)vdata); - vaostatic |= VATTR_COLOUR; - } + GLBE_SetupVAO(vbo, vaodynamic, vaostatic); @@ -173,7 +180,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch vec3_t *normals; vec3_t *svector; vec3_t *tvector; - vec4_t *colours; + vec4_t *colours[MAXLIGHTMAPS]; index_t *indicies; batch_t *batch; int vbosize; @@ -207,7 +214,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch sizeof(vec3_t)+ //normal sizeof(vec3_t)+ //sdir sizeof(vec3_t)+ //tdir - sizeof(vec4_t); //colours + sizeof(vec4_t)*lightmaps; //colours vbo->vertdata = BZ_Malloc((maxvboverts+1)*pervertsize + (maxvboelements+1)*sizeof(index_t)); @@ -222,7 +229,10 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch vbo->normals.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t)); vbo->svector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t)); vbo->tvector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t)); - vbo->colours.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec4_t)); + for (s = 0; s < lightmaps; s++) + vbo->colours[s].gl.addr = allocbuf(&p, maxvboverts, sizeof(vec4_t)); + for (; s < MAXLIGHTMAPS; s++) + vbo->lmcoord[s].gl.addr = NULL; vbosize = (char*)p - (char*)vbo->coord.gl.addr; if ((char*)p - (char*)vbo->vertdata > (maxvboverts+1)*pervertsize) Sys_Error("GLBE_GenBatchVBOs: aligned overflow"); @@ -230,12 +240,14 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch coord = vbo->coord.gl.addr; texcoord = vbo->texcoord.gl.addr; - for (s = 0; s < 4; s++) + for (s = 0; s < MAXLIGHTMAPS; s++) + { lmcoord[s] = vbo->lmcoord[s].gl.addr; + colours[s] = vbo->colours[s].gl.addr; + } normals = vbo->normals.gl.addr; svector = vbo->svector.gl.addr; tvector = vbo->tvector.gl.addr; - colours = vbo->colours.gl.addr; indicies = vbo->indicies.gl.addr; //vbo->meshcount = meshes; @@ -275,6 +287,13 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch lmcoord[s][vcount+v][0] = m->lmst_array[s][v][0]; lmcoord[s][vcount+v][1] = m->lmst_array[s][v][1]; } + if (m->colors4f_array[s]) + { + colours[s][vcount+v][0] = m->colors4f_array[s][v][0]; + colours[s][vcount+v][1] = m->colors4f_array[s][v][1]; + colours[s][vcount+v][2] = m->colors4f_array[s][v][2]; + colours[s][vcount+v][3] = m->colors4f_array[s][v][3]; + } } if (m->normals_array) { @@ -294,13 +313,6 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch tvector[vcount+v][1] = m->tnormals_array[v][1]; tvector[vcount+v][2] = m->tnormals_array[v][2]; } - if (m->colors4f_array) - { - colours[vcount+v][0] = m->colors4f_array[v][0]; - colours[vcount+v][1] = m->colors4f_array[v][1]; - colours[vcount+v][2] = m->colors4f_array[v][2]; - colours[vcount+v][3] = m->colors4f_array[v][3]; - } } vcount += v; } diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 37143f83d..66161c7aa 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -3562,9 +3562,18 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) else return; if (pass->texgen == T_GEN_LIGHTMAP && pass->blendmode == PBM_REPLACELIGHT && pass2->blendmode == PBM_MODULATE && config_tex_env_combine) + { + if (pass->rgbgen == RGB_GEN_IDENTITY) + pass->rgbgen = RGB_GEN_IDENTITY_OVERBRIGHT; //get the light levels right pass2->blendmode = PBM_OVERBRIGHT; + } if (pass2->texgen == T_GEN_LIGHTMAP && pass2->blendmode == PBM_MODULATE && config_tex_env_combine) + { + if (pass->rgbgen == RGB_GEN_IDENTITY) + pass->rgbgen = RGB_GEN_IDENTITY_OVERBRIGHT; //get the light levels right + pass->blendmode = PBM_REPLACELIGHT; pass2->blendmode = PBM_OVERBRIGHT; + } } void Shader_SetFeatures ( shader_t *s ) @@ -3733,7 +3742,7 @@ void Shader_Finish (shader_t *s) s->sort = SHADER_SORT_DECAL; } - if ((r_vertexlight.value || !(s->flags & SUF_LIGHTMAP)) && !s->prog) + if ((r_vertexlight.value || !(s->usageflags & SUF_LIGHTMAP)) && !s->prog) { // do we have a lightmap pass? pass = s->passes; @@ -3808,7 +3817,7 @@ void Shader_Finish (shader_t *s) s->passes[0].alphagen = ALPHA_GEN_IDENTITY; s->passes[0].blendmode = 0; s->passes[0].flags &= ~(SHADER_PASS_ANIMMAP|SHADER_PASS_NOCOLORARRAY); - pass->shaderbits &= ~SBITS_BLEND_BITS; + s->passes[0].shaderbits &= ~SBITS_BLEND_BITS; s->passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE; s->passes[0].numMergedPasses = 1; s->numpasses = 1; @@ -4772,7 +4781,7 @@ qboolean Shader_ReadShaderTerms(shader_t *s, char **shadersource, int parsemode, #define COND_IGNOREPARENT 2 #define COND_ALLOWELSE 4 - if (!shadersource) + if (!*shadersource) return false; token = COM_ParseExt (shadersource, true, true); @@ -4966,7 +4975,7 @@ static int R_LoadShader (char *name, unsigned int usageflags, shader_gen_t *defa //make sure the same texture can be used as either a lightmap or vertexlit shader //if it has an explicit shader overriding it then that still takes precidence. we might just have multiple copies of it. //q3 has a separate (internal) shader for every lightmap. - if (!defaultgen || (s->generator == defaultgen && !s->genargs == !genargs && (!genargs || !strcmp(s->genargs, genargs)))) + if (!((s->usageflags ^ usageflags) & SUF_LIGHTMAP)) { i = s - r_shaders; r_shaders[i].uses++; diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index e0340c9d2..388856b6f 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1429,6 +1429,9 @@ GLhandleARB GLSlang_CreateProgramObject (char *name, GLhandleARB vert, GLhandleA qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position"); qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour"); + qglBindAttribLocationARB(program, VATTR_COLOUR2, "v_colour2"); + qglBindAttribLocationARB(program, VATTR_COLOUR3, "v_colour3"); + qglBindAttribLocationARB(program, VATTR_COLOUR4, "v_colour4"); qglBindAttribLocationARB(program, VATTR_TEXCOORD, "v_texcoord"); qglBindAttribLocationARB(program, VATTR_LMCOORD, "v_lmcoord"); qglBindAttribLocationARB(program, VATTR_LMCOORD2, "v_lmcoord2"); @@ -1815,7 +1818,7 @@ void DumpGLState(void) qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &no); qglGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr); - Sys_Printf("attrib%i: %s as:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr); + Sys_Printf("attrib%i: %s sz:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr); } qglGetIntegerv(GL_CURRENT_PROGRAM, &glint); @@ -1849,19 +1852,19 @@ void DumpGLState(void) GL_SelectTexture(0); qglGetIntegerv(GL_TEXTURE_2D, &glint); - Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + Sys_Printf("0: GL_TEXTURE_2D: %i\n", glint); qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); - Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + Sys_Printf("0: GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); GL_SelectTexture(1); qglGetIntegerv(GL_TEXTURE_2D, &glint); - Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + Sys_Printf("1: GL_TEXTURE_2D: %i\n", glint); qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); - Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + Sys_Printf("1: GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); GL_SelectTexture(2); qglGetIntegerv(GL_TEXTURE_2D, &glint); - Sys_Printf("GL_TEXTURE_2D: %i\n", glint); + Sys_Printf("2: GL_TEXTURE_2D: %i\n", glint); qglGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint); - Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); + Sys_Printf("2: GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint)); } } #endif diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index f4b6cab48..bfd525455 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -707,7 +707,7 @@ static void GL_DrawSkyBox (texid_t *texnums, batch_t *s) skyfacemesh.indexes = skyface_index; skyfacemesh.st_array = skyface_texcoord; skyfacemesh.xyz_array = skyface_vertex; - skyfacemesh.colors4f_array = skyface_colours; + skyfacemesh.colors4f_array[0] = skyface_colours; skyfacemesh.numindexes = 6; skyfacemesh.numvertexes = 4; diff --git a/engine/gl/shader.h b/engine/gl/shader.h index e0e9826d3..a26bbc460 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -192,6 +192,7 @@ typedef struct shaderpass_s { RGB_GEN_VERTEX_EXACT, RGB_GEN_ONE_MINUS_VERTEX, RGB_GEN_IDENTITY_LIGHTING, + RGB_GEN_IDENTITY_OVERBRIGHT, RGB_GEN_IDENTITY, RGB_GEN_CONST, RGB_GEN_UNKNOWN, @@ -323,6 +324,10 @@ enum shaderattribs_e VATTR_LMCOORD2, VATTR_LMCOORD3, VATTR_LMCOORD4, + VATTR_COLOUR2, + VATTR_COLOUR3, + VATTR_COLOUR4, + VATTR_LEG_VERTEX, //note: traditionally this is actually index 0. //however, implementations are allowed to directly alias, or remap, @@ -344,7 +349,8 @@ typedef struct { /*entity properties*/ SP_E_VBLEND, - SP_E_LMSCALE, + SP_E_LMSCALE, //lightmap scales + SP_E_VLSCALE, //vertex lighting style scales SP_E_ORIGIN, SP_E_COLOURS, SP_E_COLOURSIDENT, diff --git a/engine/qclib/comprout.c b/engine/qclib/comprout.c index 2ce95e56c..c6153122f 100644 --- a/engine/qclib/comprout.c +++ b/engine/qclib/comprout.c @@ -49,6 +49,7 @@ void PostCompile(void) if (!qccpersisthunk) qccClearHunk(); QCC_PR_CloseProcessor(); + QCC_Cleanup(); if (asmfile) { diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index fcaae99ba..345f2e90f 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -1106,6 +1106,14 @@ static int PDECL qclib_null_printf(const char *s, ...) { return 0; } +static void *PDECL qclib_malloc(int size) +{ + return malloc(size); +} +static void PDECL qclib_free(void *ptr) +{ + free(ptr); +} #ifdef FTE_TARGET_WEB #define printf NULL //should be some null wrapper instead #endif @@ -1138,8 +1146,8 @@ progexterns_t defexterns = { NULL, //void (*loadcompleate) (int edictsize); //notification to reset any pointers. NULL, - (void*)malloc, //void *(*memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use memalloc if you want) - free, //void (*memfree) (void * mem); + qclib_malloc, //void *(*memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use memalloc if you want) + qclib_free, //void (*memfree) (void * mem); NULL, //builtin_t *globalbuiltins; //these are available to all progs diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index 35a3bdc7b..ec39f7646 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -7,6 +7,18 @@ Setting them should be fine. #ifndef __PR_COMP_H__ #define __PR_COMP_H__ +/* +#ifdef USE_MSVCRT_DEBUG +void *BZ_MallocNamed(int size, char *file, int line); +void *BZ_ReallocNamed(void *data, int newsize, char *file, int line); +void BZ_Free(void *data); +#define BZ_Malloc(size) BZ_MallocNamed(size, __FILE__, __LINE__) +#define BZ_Realloc(ptr, size) BZ_ReallocNamed(ptr, size, __FILE__, __LINE__) +#define malloc BZ_Malloc +#define realloc BZ_Realloc +#define free BZ_Free +#endif +*/ typedef int dstring_t; #define QCC_string_t dstring_t diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 4fad8e00c..51f122eaa 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -46,6 +46,7 @@ typedef unsigned char qbyte; #include "pr_comp.h" + #ifdef _MSC_VER #pragma warning(disable : 4244) #pragma warning(disable : 4267) diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index 996c80a27..f857990ab 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -849,6 +849,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, QCC_type_t *basetype); void PostCompile(void); pbool PreCompile(void); +void QCC_Cleanup(void); #define FIRST_LOCAL (MAX_REGS) diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index fd63a76d5..17d3baa2d 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -1773,6 +1773,20 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_ //a is const, b is not switch (op - pr_opcodes) { + //OP_NOT_S needs to do a string comparison + case OP_NOT_F: + optres_constantarithmatic++; + return QCC_MakeFloatConst(!G_FLOAT(var_a->ofs)); + case OP_NOT_V: + optres_constantarithmatic++; + return QCC_MakeFloatConst(!G_FLOAT(var_a->ofs+0) && !G_FLOAT(var_a->ofs+1) && !G_FLOAT(var_a->ofs+2)); + case OP_NOT_ENT: // o.O + case OP_NOT_FNC: // o.O + optres_constantarithmatic++; + return QCC_MakeFloatConst(!G_INT(var_a->ofs)); + case OP_NOT_I: + optres_constantarithmatic++; + return QCC_MakeIntConst(!G_INT(var_a->ofs)); case OP_CONV_FTOI: optres_constantarithmatic++; return QCC_MakeIntConst(G_FLOAT(var_a->ofs)); @@ -3762,6 +3776,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *newself, QCC_def_t *func) //warn //ret = spawn() result = QCC_PR_GenerateFunctionCall(NULL, func, NULL, NULL, 0); + def_ret.temp->used = true; if (!rettype) rettype = type_entity; else @@ -3780,6 +3795,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *newself, QCC_def_t *func) //warn v = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); p = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], result, f, NULL); + QCC_UnFreeTemp(result); type_pointer->aux_type = f->type->aux_type; if (v->type->size == 3) QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STOREP_V], v, p, NULL)); @@ -3789,6 +3805,9 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *newself, QCC_def_t *func) //warn QCC_PR_Expect(")"); } + if (!def_ret.temp->used) + QCC_PR_ParseError(ERR_INTERNAL, "self clobbered."); + //tmp oself = self if (rettype != type_entity) { @@ -5321,8 +5340,6 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign, p QCC_PR_ParseWarning (WARN_SELFNOTTHIS, "'self' used inside OO function, use 'this'.", pr_scope->name); } - d = QCC_PR_ParseArrayPointer(d, allowarrayassign, makearraypointers); - if (pr_classtype && expandmemberfields && d->type->type == ev_field) { QCC_def_t *t; @@ -5335,9 +5352,12 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign, p else t = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false); + d = QCC_PR_ParseArrayPointer(d, allowarrayassign, makearraypointers); //opportunistic vecmember[0] handling d = QCC_PR_ExpandField(t, d); } + d = QCC_PR_ParseArrayPointer(d, allowarrayassign, makearraypointers); + return d; } @@ -10452,5 +10472,18 @@ pbool QCC_Include(char *filename) return true; } - +void QCC_Cleanup(void) +{ + free(pr_breaks); + free(pr_continues); + free(pr_cases); + free(pr_casesdef); + free(pr_casesdef2); + max_breaks = max_continues = max_cases = num_continues = num_breaks = num_cases = 0; + pr_breaks = NULL; + pr_continues = NULL; + pr_cases = NULL; + pr_casesdef = NULL; + pr_casesdef2 = NULL; +} #endif diff --git a/engine/qclib/qcdecomp.c b/engine/qclib/qcdecomp.c index 3925d0fe7..4fa154741 100644 --- a/engine/qclib/qcdecomp.c +++ b/engine/qclib/qcdecomp.c @@ -1,5 +1,6 @@ #if !defined(MINIMAL) && !defined(OMIT_QCC) +//#include "qcc.h" #include "progsint.h" #include "setjmp.h" diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 30dd87832..16258f3a9 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -1860,23 +1860,27 @@ qboolean PR_UserCmd(char *s) if (gfuncs.UserCmd && pr_imitatemvdsv.value >= 0) { //we didn't recognise it. see if the mod does. - + char *arg0; //ktpro bug warning: //admin + judge. I don't know the exact rules behind this bug, so I just ban the entire command //I can't be arsed detecting ktpro specifically, so assume we're always running ktpro - if (!strncmp(s, "admin", 5) || !strncmp(s, "judge", 5)) - { - Con_Printf("Blocking potentially unsafe ktpro command: %s\n", s); - return true; - } - pr_globals = PR_globals(svprogfuncs, PR_CURRENT); pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); tokenizeqc(s, true); + //make sure we use the same logic that the qc will use. specifically that we check for " and leading spaces etc + G_FLOAT(OFS_PARM0) = 0; + PF_ArgV(svprogfuncs, pr_globals); + arg0 = PR_GetStringOfs(svprogfuncs, OFS_RETURN); + if (!strcmp(arg0, "admin") || !strcmp(arg0, "judge")) + { + Con_Printf("Blocking potentially unsafe ktpro command: %s\n", s); + return true; + } + G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s); PR_ExecuteProgram (svprogfuncs, gfuncs.UserCmd); return !!G_FLOAT(OFS_RETURN); @@ -10250,7 +10254,8 @@ void PR_DumpPlatform_f(void) {"end_sys_globals", "void", QW|NQ|CS|MENU}, {"modelindex", ".float", QW|NQ|CS}, - {"absmin, absmax", ".vector", QW|NQ|CS}, + {"absmin", ".vector", QW|NQ|CS}, + {"absmax", ".vector", QW|NQ|CS}, {"ltime", ".float", QW|NQ}, {"entnum", ".float", CS, "The entity number as its known on the server."}, {"drawmask", ".float", CS, "Acts as a filter in the addentities call."}, @@ -10275,7 +10280,8 @@ void PR_DumpPlatform_f(void) {"lerpfrac", ".float", CS, "If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between."}, {"skin", ".float", QW|NQ|CS}, {"effects", ".float", QW|NQ|CS}, - {"mins, maxs", ".vector", QW|NQ|CS}, + {"mins", ".vector", QW|NQ|CS}, + {"maxs", ".vector", QW|NQ|CS}, {"size", ".vector", QW|NQ|CS}, {"touch", ".void()", QW|NQ|CS}, {"use", ".void()", QW|NQ}, diff --git a/engine/server/savegame.c b/engine/server/savegame.c index b14a6176f..abdcfd393 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -1035,9 +1035,9 @@ void SV_Savegame (char *savename) Q_strncpyz(str, localinfo, sizeof(str)); Info_RemovePrefixedKeys(str, '*'); - VFS_PRINTF (f, "%s\n", str); + VFS_PUTS(f, str); - VFS_PRINTF (f, "{\n"); //all game vars. FIXME: Should save the ones that have been retrieved/set by progs. + VFS_PRINTF (f, "\n{\n"); //all game vars. FIXME: Should save the ones that have been retrieved/set by progs. VFS_PRINTF (f, "skill \"%s\"\n", skill.string); VFS_PRINTF (f, "deathmatch \"%s\"\n", deathmatch.string); VFS_PRINTF (f, "coop \"%s\"\n", coop.string); diff --git a/engine/server/server.h b/engine/server/server.h index 8e67022e0..aff8287c3 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -999,6 +999,7 @@ qboolean SVQ3_InitGame(void); qboolean SVQ3_ConsoleCommand(void); qboolean SVQ3_HandleClient(void); void SVQ3_DirectConnect(void); +void SVQ3_NewMapConnects(void); void SVQ3_DropClient(client_t *cl); int SVQ3_AddBot(void); void SVQ3_RunFrame(void); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 1bd76b1c1..01a6c6407 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -1697,7 +1697,6 @@ SV_Serverinfo_f Examine or change the serverinfo string =========== */ -char *CopyString(char *s); extern char *Info_KeyForNumber(char *s, int num); void SV_Serverinfo_f (void) { @@ -1758,7 +1757,7 @@ void SV_Serverinfo_f (void) { Cvar_Set(var, value); /* Z_Free (var->string); // free the old value string - var->string = CopyString (value); + var->string = Z_StrDup (value); var->value = Q_atof (var->string); */ } @@ -1773,7 +1772,6 @@ SV_Serverinfo_f Examine or change the serverinfo string =========== */ -char *CopyString(char *s); void SV_Localinfo_f (void) { char *old; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 033cb58f1..233cf5aa9 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -1145,6 +1145,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us #endif break; } + //fixme: properly kick any other clients (ie: without notifying gamecode). for (i=0 ; iedict; SV_Drop_f(); - break; + return; case clc_nop: break; @@ -6884,6 +6884,8 @@ void SVNQ_ExecuteClientMessage (client_t *cl) host_client = cl; sv_player = cl->edict; + if (cl->state < cs_connected) + return; break; case clc_qcrequest: diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index f426d53fe..60f8e78bf 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -3110,6 +3110,26 @@ qboolean SVQ3_HandleClient(void) SVQ3_ParseClientMessage(&svs.clients[i]); return true; } +void SVQ3_NewMapConnects(void) +{ + int i; + qintptr_t ret; + for (i = 0; i < sv.allocated_client_slots; i++) + { + if (svs.clients[i].state < cs_connected) + continue; + + ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, i, false, false); + if (ret) + { + SV_DropClient(&svs.clients[i]); + } + else + { + //FIXME: make sure bots get the right GAME_CLIENT_BEGIN + } + } +} void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and let the gamecode know of it. { @@ -3117,7 +3137,7 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and char *reason; client_t *cl; char *userinfo = NULL; - int ret; + qintptr_t ret; int challenge; int qport; char adr[MAX_ADR_SIZE]; @@ -3164,7 +3184,7 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and if (!ret) reason = NULL; else - reason = (char*)VM_MemoryBase(q3gamevm)+ret; //this is going to stop q3 dll gamecode at 64bits. + reason = (char*)VM_MemoryBase(q3gamevm)+ret; } }