diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index 78c90882f..ef1055de5 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -762,10 +762,20 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long break; case CG_R_REGISTERSHADER: - VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0]))); + if (!*(char*)VM_POINTER(arg[0])) + VM_LONG(ret) = 0; + else if (qrenderer == QR_OPENGL) + VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0]))); + else + VM_LONG(ret) = VM_TOHANDLE(Draw_SafeCachePic(VM_POINTER(arg[0]))); break; case CG_R_REGISTERSHADERNOMIP: - VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0]))); + if (!*(char*)VM_POINTER(arg[0])) + VM_LONG(ret) = 0; + else if (qrenderer == QR_OPENGL) + VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0]))); + else + VM_LONG(ret) = VM_TOHANDLE(Draw_SafeCachePic(VM_POINTER(arg[0]))); break; case CG_R_CLEARSCENE: //clear scene @@ -802,16 +812,10 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long break; case CG_R_DRAWSTRETCHPIC: - switch (qrenderer) - { -#ifdef RGLQUAKE - case QR_OPENGL: - GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_FROMHANDLE(arg[8])); - break; -#endif - default: - break; //FIXME - } + if (qrenderer == QR_OPENGL) + GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (void *)VM_LONG(arg[8])); + else + Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); break; case CG_R_LERPTAG: //Lerp tag... @@ -1104,17 +1108,17 @@ void CG_Start (void) return; } -#ifdef RGLQUAKE +#if defined(RGLQUAKE) || defined(DIRECT3D) if (!Draw_SafeCachePic) //no renderer loaded { CG_Stop(); return; } - if (qrenderer != QR_OPENGL) + if (qrenderer != QR_OPENGL && qrenderer != QR_DIRECT3D) { //sorry. CG_Stop(); - Host_EndGame("Unable to connect to q3 servers without opengl.\n"); + Host_EndGame("Unable to connect to q3 servers without opengl or d3d.\n"); return; } diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 989f1821b..227d4702e 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -266,12 +266,19 @@ qboolean CL_GetDemoMessage (void) q1usercmd_t q1cmd; #ifdef NQPROT - if (cls.demoplayback == DPB_NETQUAKE || cls.demoplayback == DPB_QUAKE2) + if (cls.demoplayback == DPB_NETQUAKE +#ifdef Q2CLIENT + || cls.demoplayback == DPB_QUAKE2 +#endif + ) { //read the nq demo +#ifdef Q2CLIENT if (cls.demoplayback == DPB_QUAKE2 && (cls.netchan.last_received == realtime || cls.netchan.last_received > realtime-0.1)) return 0; - else if (cls.demoplayback == DPB_NETQUAKE && cls.signon == 4/*SIGNONS*/) + else +#endif + if (cls.demoplayback == DPB_NETQUAKE && cls.signon == 4/*SIGNONS*/) { if (!realtime) { @@ -1717,6 +1724,32 @@ void CL_QTVList_f (void) qtvrequestsize = 0; } +void CL_QTVDemos_f (void) +{ + char *connrequest; + vfsfile_t *newf; + newf = FS_OpenTCP(Cmd_Argv(1)); + + if (!newf) + { + Con_Printf("Couldn't connect to proxy\n"); + return; + } + + connrequest = "QTV\n" + "VERSION: 1\n"; + VFS_WRITE(newf, connrequest, strlen(connrequest)); + connrequest = "DEMOLIST\n"; + VFS_WRITE(newf, connrequest, strlen(connrequest)); + connrequest = "\n"; + VFS_WRITE(newf, connrequest, strlen(connrequest)); + + if (qtvrequest) + VFS_CLOSE(qtvrequest); + qtvrequest = newf; + qtvrequestsize = 0; +} + /* ==================== CL_FinishTimeDemo diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 67074c8d6..31199f6e3 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -1453,6 +1453,11 @@ void V_AddLerpEntity(entity_t *in) //a convienience function ent->angles[0]*=-1; } +void V_AddLight (vec3_t org, float quant, float r, float g, float b) +{ + CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b); +} + /* =============== CL_LinkPacketEntities diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 55fa5cfa4..d385dbbd2 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -641,7 +641,6 @@ void CL_DrawPrydonCursor(void) } } -void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t cursor_start, vec3_t cursor_impact, int *entnum) { vec3_t cursor_end; @@ -699,7 +698,7 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso temp[1] = (-cursor_screen[1]+1)/2; temp[2] = 1; - ML_UnProject(temp, cursor_end, cl.viewangles[0], vec3_origin, (float)vid.width/vid.height, scr_fov.value ); + Matrix4_UnProject(temp, cursor_end, cl.viewangles[0], vec3_origin, (float)vid.width/vid.height, scr_fov.value ); VectorScale(cursor_end, 100000, cursor_end); VectorAdd(cursor_start, cl.simorg[0], cursor_start); diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index a778aba21..606702577 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -508,7 +508,7 @@ void CL_SendConnectPacket ( #ifdef HUFFNETWORK if (compressioncrc && Huff_CompressionCRC(compressioncrc)) { - strcat(data, va("0x%x 0x%x\n", (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24)), LittleLong(compressioncrc))); + strcat(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_HUFFMAN, LittleLong(compressioncrc))); cls.netchan.compress = true; } else @@ -2846,6 +2846,7 @@ void CL_Init (void) Cmd_AddCommand ("playdemo", CL_PlayDemo_f); Cmd_AddCommand ("qtvplay", CL_QTVPlay_f); Cmd_AddCommand ("qtvlist", CL_QTVList_f); + Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f); Cmd_AddCommand ("demo_jump", CL_DemoJump_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f); diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 72a402c3c..2d2449d66 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -236,7 +236,7 @@ int VARGS Plug_Draw_Character(void *offset, unsigned int mask, const long *arg) Draw_Character(arg[0], arg[1], (unsigned int)arg[2]); return 0; } - +void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h); int VARGS Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg) { float x, y, width, height; @@ -260,6 +260,9 @@ int VARGS Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg) qglEnable(GL_TEXTURE_2D); return 1; #endif + case QR_DIRECT3D: +// D3D_Draw_Fill_Colours(x, y, width, height); + break; default: break; } diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 5e79c28b5..c0bac10c7 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -28,6 +28,75 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +void RSpeedShow(void) +{ + int i; + static int samplerspeeds[RSPEED_MAX]; + static int samplerquant[RQUANT_MAX]; + char *RSpNames[RSPEED_MAX]; + char *RQntNames[RQUANT_MAX]; + char *s; + static int framecount; + + if (!r_speeds.value) + return; + + memset(RSpNames, 0, sizeof(RSpNames)); + RSpNames[RSPEED_TOTALREFRESH] = "Total refresh"; + RSpNames[RSPEED_PROTOCOL] = "Protocol"; + RSpNames[RSPEED_LINKENTITIES] = "Entity setup"; + RSpNames[RSPEED_WORLDNODE] = "World walking"; + RSpNames[RSPEED_WORLD] = "World rendering"; + RSpNames[RSPEED_DYNAMIC] = "Lightmap updates"; + RSpNames[RSPEED_PARTICLES] = "Particle physics and sorting"; + RSpNames[RSPEED_PARTICLESDRAW] = "Particle drawing"; + RSpNames[RSPEED_2D] = "2d elements"; + RSpNames[RSPEED_SERVER] = "Server"; + + RSpNames[RSPEED_DRAWENTITIES] = "Entity rendering"; + + RSpNames[RSPEED_PALETTEFLASHES] = "Palette flashes"; + RSpNames[RSPEED_STENCILSHADOWS] = "Stencil Shadows"; + + RSpNames[RSPEED_FULLBRIGHTS] = "World fullbrights"; + + RSpNames[RSPEED_FINISH] = "Waiting for card to catch up"; + + RQntNames[RQUANT_MSECS] = "Microseconds"; + RQntNames[RQUANT_EPOLYS] = "Entity Polys"; + RQntNames[RQUANT_WPOLYS] = "World Polys"; + RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces"; + RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges"; + RQntNames[RQUANT_LITFACES] = "Lit faces"; + + for (i = 0; i < RSPEED_MAX; i++) + { + s = va("%i %-30s", samplerspeeds[i], RSpNames[i]); + Draw_String(vid.width-strlen(s)*8, i*8, s); + } + for (i = 0; i < RQUANT_MAX; i++) + { + s = va("%i %-30s", samplerquant[i], RQntNames[i]); + Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); + } + s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate"); + Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); + + if (framecount++>=100) + { + for (i = 0; i < RSPEED_MAX; i++) + { + samplerspeeds[i] = rspeeds[i]; + rspeeds[i] = 0; + } + for (i = 0; i < RQUANT_MAX; i++) + { + samplerquant[i] = rquant[i]; + rquant[i] = 0; + } + framecount=0; + } +} /* @@ -1050,7 +1119,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y) adj+=v_viewheight.value; start[2]+=adj; - ML_Project(tr.endpos, end, cl.simangles[pnum], start, (float)rect.width/rect.height, r_refdef.fov_y); + Matrix4_Project(tr.endpos, end, cl.simangles[pnum], start, (float)rect.width/rect.height, r_refdef.fov_y); *x = rect.x+rect.width*end[0]; *y = rect.y+rect.height*(1-end[1]); return; @@ -1697,7 +1766,7 @@ int MipColor(int r, int g, int b) return best; } -void SCR_ScreenShot (char *filename) +qboolean SCR_ScreenShot (char *filename) { int truewidth, trueheight; qbyte *buffer; @@ -1711,6 +1780,9 @@ void SCR_ScreenShot (char *filename) buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight); + if (!buffer) + return false; + #ifdef AVAIL_PNGLIB if (!strcmp(ext, "png")) { @@ -1773,6 +1845,8 @@ void SCR_ScreenShot (char *filename) BZ_Free (buffer); + + return true; } /* @@ -1828,8 +1902,10 @@ void SCR_ScreenShot_f (void) } } - SCR_ScreenShot(pcxname); - Con_Printf ("Wrote %s\n", pcxname); + if (SCR_ScreenShot(pcxname)) + Con_Printf ("Wrote %s\n", pcxname); + else + Con_Printf ("Screenshot failed\n"); } diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 53470ccfa..ae506e8bc 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -1056,11 +1056,12 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg) UI_RegisterFont(VM_POINTER(arg[0]), arg[1], VM_POINTER(arg[2])); break; case UI_R_REGISTERSHADERNOMIP: - if (!Draw_SafeCachePic || !*(char*)VM_POINTER(arg[0])) + if (!*(char*)VM_POINTER(arg[0])) VM_LONG(ret) = 0; - else -// VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0])); + else if (qrenderer == QR_OPENGL) VM_LONG(ret) = (long)R_RegisterPic(VM_POINTER(arg[0])); + else + VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0])); break; case UI_R_CLEARSCENE: //clear scene @@ -1090,9 +1091,10 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg) // qglDisable(GL_ALPHA_TEST); // qglEnable(GL_BLEND); // GL_TexEnv(GL_MODULATE); - if (Draw_Image) + if (qrenderer == QR_OPENGL) GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (void *)VM_LONG(arg[8])); -// Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); + else + Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); break; case UI_CM_LERPTAG: //Lerp tag... @@ -1753,7 +1755,7 @@ void UI_Start (void) if (!Draw_SafeCachePic) //no renderer loaded return; - if (qrenderer != QR_OPENGL) + if (qrenderer != QR_OPENGL && qrenderer != QR_DIRECT3D) return; uivm = VM_Create(NULL, "vm/qwui", UI_SystemCalls, UI_SystemCallsEx); diff --git a/engine/client/client.h b/engine/client/client.h index 8d24865b1..4d29cbefe 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -754,6 +754,7 @@ void CL_ReRecord_f (void); void CL_PlayDemo_f (void); void CL_QTVPlay_f (void); void CL_QTVList_f (void); +void CL_QTVDemos_f (void); void CL_DemoJump_f(void); void CL_ProgressDemoTime(void); void CL_TimeDemo_f (void); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index b57b85fb9..d8347aa8c 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1306,10 +1306,6 @@ struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base) */ -void V_AddLight (vec3_t org, float quant, float r, float g, float b) -{ - CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b); -} /* =============== CL_AddPacketEntities diff --git a/engine/client/image.c b/engine/client/image.c index 4cf19af34..6e274253c 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -3,6 +3,10 @@ #include "glquake.h" #endif +#ifdef D3DQUAKE +#include "d3dquake.h" +#endif + cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upside down. //This is due to a bug in tenebrae. //(normally) the textures are actually the right way around. @@ -1727,7 +1731,13 @@ void BoostGamma(qbyte *rgba, int width, int height) #endif } -#if defined(RGLQUAKE) + + + + + + +#if defined(RGLQUAKE) || defined(D3DQUAKE) #ifdef DDS #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT @@ -1925,16 +1935,16 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al *data = '#'; } - if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists. + if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists. return len; if (subpath && *subpath) { snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name); - if ((len = GL_FindTexture(fname))!=-1) //don't bother if it already exists. + if ((len = R_FindTexture(fname))!=-1) //don't bother if it already exists. return len; } - if ((len = GL_LoadCompressed(name))) + if ((len = R_LoadCompressed(name))) return len; if (strchr(name, '/')) //never look in a root dir for the pic @@ -1985,10 +1995,10 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al if (i == 1) { //if it came from a special subpath (eg: map specific), upload it using the subpath prefix snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name); - len = GL_LoadTexture32 (fname, image_width, image_height, (unsigned*)data, mipmap, alpha); + len = R_LoadTexture32 (fname, image_width, image_height, (unsigned*)data, mipmap, alpha); } else - len = GL_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha); + len = R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha); BZ_Free(data); @@ -2008,7 +2018,7 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al //now look in wad files. (halflife compatability) data = W_GetTexture(name, &image_width, &image_height, &alphaed); if (data) - return GL_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alphaed); + return R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alphaed); return 0; } int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust) @@ -2044,10 +2054,10 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath) COM_StripExtension(name, nicename, sizeof(nicename)); - if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists. + if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists. return len; - if ((len = GL_LoadCompressed(name))) + if ((len = R_LoadCompressed(name))) return len; if (strchr(name, '/')) //never look in a root dir for the pic @@ -2081,7 +2091,7 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath) if ((data = ReadTargaFile(buf, com_filesize, &image_width, &image_height, 2))) //Only load a greyscale image. { TRACE(("dbg: Mod_LoadBumpmapTexture: tga %s loaded\n", name)); - len = GL_LoadTexture8Bump(name, image_width, image_height, data, true, r_shadow_bumpscale_bumpmap.value); + len = R_LoadTexture8Bump(name, image_width, image_height, data, true, r_shadow_bumpscale_bumpmap.value); BZ_Free(data); } else diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 01e7dfe3e..c4756e887 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -1208,7 +1208,7 @@ void IN_ReInit (void) { IN_StartupMouse (); IN_StartupJoystick (); - IN_ActivateMouse(); +// IN_ActivateMouse(); } void IN_Init (void) diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 8e951785e..c519e47e3 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -736,7 +736,8 @@ menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qb return n; } -menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max) +//delta may be 0 +menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max, float delta) { menuslider_t *n = Z_Malloc(sizeof(menuslider_t)+strlen(text)+1); n->common.type = mt_slider; @@ -759,6 +760,8 @@ menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t n->min = min; n->max = max; + n->smallchange = delta; + n->largechange = delta*5; n->common.next = menu->options; menu->options = (menuoption_t *)n; @@ -999,35 +1002,41 @@ menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int x, int y, const char void MC_Slider_Key(menuslider_t *option, int key) { - float range = (option->current - option->min)/(option->max-option->min); + float range = option->current; + float delta; + + if (option->smallchange) + delta = option->smallchange; + else + delta = 0.1; if (key == K_LEFTARROW || key == K_MWHEELDOWN) { - range -= 0.1; - if (range < 0) - range = 0; - option->current = range = (range * (option->max-option->min)) + option->min; + range -= delta; + if (range < option->min) + range = option->min; + option->current = range; if (option->var) Cvar_SetValue(option->var, range); } else if (key == K_RIGHTARROW || key == K_MWHEELUP) { - range += 0.1; - if (range > 1) - range = 1; - option->current = range = (range * (option->max-option->min)) + option->min; + range += delta; + if (range > option->max) + range = option->max; + option->current = range; if (option->var) Cvar_SetValue(option->var, range); } else if (key == K_ENTER || key == K_MOUSE1) { - range += 0.1; + range += delta; - if (range >= 1.05) - range = 0; - if (range > 1) - range = 1; - option->current = range = (range * (option->max-option->min)) + option->min; + if (range >= option->max + delta/2) + range = option->min; + if (range > option->max) + range = option->max; + option->current = range; if (option->var) Cvar_SetValue(option->var, range); } diff --git a/engine/client/m_multi.c b/engine/client/m_multi.c index ba0f9e1ef..00c08a4c1 100644 --- a/engine/client/m_multi.c +++ b/engine/client/m_multi.c @@ -39,6 +39,18 @@ void M_Menu_MultiPlayer_f (void) } else if (mgt == MGT_HEXEN2) { + MC_AddCenterPicture(menu, 0, "gfx/menu/title4.lmp"); + + mgt=64; + menu->selecteditem = (menuoption_t*) + MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Join A Game ", "menu_slist\n");mgt+=20; + MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Old Browser ", "menu_serversold\n");mgt+=20; + MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "New Server ", "menu_newmulti\n");mgt+=20; + MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Player Setup", "menu_setup\n");mgt+=20; + MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Demos ", "menu_demo\n");mgt+=20; + + menu->cursoritem = (menuoption_t *)MC_AddCursor(menu, 48, 64); + return; } else if (QBigFontWorks()) { @@ -435,7 +447,7 @@ void M_Menu_GameOptions_f (void) info->timelimit = MC_AddCombo (menu, 64, y, " Time Limit", (const char **)timelimitoptions, timelimit.value/5);y+=8; info->fraglimit = MC_AddCombo (menu, 64, y, " Frag Limit", (const char **)fraglimitoptions, fraglimit.value/10);y+=8; y+=8; - MC_AddSlider (menu, 64-7*8, y, "Extra edict support", &pr_maxedicts, 512, 2047);y+=8; + MC_AddSlider (menu, 64-7*8, y, "Extra edict support", &pr_maxedicts, 512, 2047, 256);y+=8; y+=8; if (mgt == MGT_QUAKE2) info->mapnameedit = MC_AddEdit (menu, 64, y, " map", "base1"); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index d5ba59249..87f6351bc 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -37,7 +37,7 @@ void M_Menu_Options_f (void) { int mgt; extern cvar_t cl_standardchat; - extern cvar_t cl_standardmsg; + extern cvar_t cl_standardmsg, crosshair; #ifdef _WIN32 extern qboolean vid_isfullscreen; #endif @@ -72,7 +72,8 @@ void M_Menu_Options_f (void) MC_AddConsoleCommand(menu, 16, y, " Go to console", "toggleconsole\nplay misc/menu2.wav\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " Reset to defaults", "exec default.cfg\nplay misc/menu2.wav\n"); y+=8; - MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10); y+=8; + MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10, 0.5); y+=8; + MC_AddSlider(menu, 16, y, " Crosshair", &crosshair, 0, 22, 1); y+=8; MC_AddCheckBox(menu, 16, y, " Always Run", NULL,0)->func = M_Options_AlwaysRun; y+=8; MC_AddCheckBox(menu, 16, y, " Invert Mouse", NULL,0)->func = M_Options_InvertMouse; y+=8; @@ -282,9 +283,9 @@ void M_Menu_Audio_f (void) menu->selecteditem = (union menuoption_s *) - MC_AddSlider(menu, 16, y, " CD Music Volume", &bgmvolume, 0, 1);y+=8; - MC_AddSlider(menu, 16, y, " Sound Volume", &volume, 0, 1);y+=8; - MC_AddSlider(menu, 16, y, " Ambient Volume", &ambient_level, 0, 1);y+=8; + MC_AddSlider(menu, 16, y, " CD Music Volume", &bgmvolume, 0, 1, 0.1);y+=8; + MC_AddSlider(menu, 16, y, " Sound Volume", &volume, 0, 1, 0.1);y+=8; + MC_AddSlider(menu, 16, y, " Ambient Volume", &ambient_level, 0, 1, 0.1);y+=8; MC_AddCheckBox(menu, 16, y, " no sound", &nosound,0);y+=8; MC_AddCheckBox(menu, 16, y, " precache", &precache,0);y+=8; MC_AddCheckBox(menu, 16, y, " Low Quality Sound", &loadas8bit,0);y+=8; @@ -482,7 +483,7 @@ void M_Menu_FPS_f (void) MC_AddCheckBox(menu, 48, y, " Dynamic shadows", &r_shadows,0);y+=8; MC_AddCheckBox(menu, 48, y, " Realtime Lights", &r_shadow_realtime_world,0);y+=8; MC_AddCheckBox(menu, 48, y, " Waterwarp", &r_waterwarp,0);y+=8; - MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99);y+=8; + MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99, 0);y+=8; break; #endif #ifdef SWQUAKE @@ -490,8 +491,8 @@ void M_Menu_FPS_f (void) if (r_pixbytes == 4) {MC_AddCheckBox(menu, 48, y, " Load .lit files", &r_loadlits,0);y+=8;} MC_AddCheckBox(menu, 48, y, " Texture Smoothing", &d_smooth,0);y+=8; - MC_AddSlider(menu, 48, y, " Mipmap scale", &d_mipscale, 0.1, 3);y+=8; - MC_AddSlider(menu, 48, y, " Mipmap Capping", &d_mipcap, 0, 3);y+=8; + MC_AddSlider(menu, 48, y, " Mipmap scale", &d_mipscale, 0.1, 3, 1);y+=8; + MC_AddSlider(menu, 48, y, " Mipmap Capping", &d_mipcap, 0, 3, 1);y+=8; break; #endif default: diff --git a/engine/client/m_script.c b/engine/client/m_script.c index f29f69b48..25ffc6229 100644 --- a/engine/client/m_script.c +++ b/engine/client/m_script.c @@ -137,7 +137,7 @@ void M_MenuS_Slider_f (void) cvar = Cvar_Get(cvarname, text, 0, "User variables"); if (!cvar) return; - MC_AddSlider(menu_script, x, y, text, cvar, min, max); + MC_AddSlider(menu_script, x, y, text, cvar, min, max, 0); } void M_MenuS_Picture_f (void) diff --git a/engine/client/menu.c b/engine/client/menu.c index b7f9d642d..08827aacf 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -338,6 +338,55 @@ bindnames_t q2bindnames[] = }; #endif + +bindnames_t h2bindnames[] = +{ +{"+attack", "attack "}, +{"impulse 10", "change weapon "}, +{"+jump", "jump / swim up"}, +{"+forward", "walk forward "}, +{"+back", "backpedal "}, +{"+left", "turn left "}, +{"+right", "turn right "}, +{"+speed", "run "}, +{"+moveleft", "step left "}, +{"+moveright", "step right "}, +{"+strafe", "sidestep "}, +{"+crouch", "crouch "}, +{"+lookup", "look up "}, +{"+lookdown", "look down "}, +{"centerview", "center view "}, +{"+mlook", "mouse look "}, +{"+klook", "keyboard look "}, +{"+moveup", "swim up "}, +{"+movedown", "swim down "}, +{"impulse 13", "lift object "}, +{"invuse", "use inv item "}, +{"impulse 44", "drop inv item "}, +{"+showinfo", "full inventory"}, +{"+showdm", "info / frags "}, +//{"toggle_dm", "toggle frags "}, +//{"+infoplaque", "objectives "}, //requires pulling info out of the mod... on the client. +{"invleft", "inv move left "}, +{"invright", "inv move right"}, +{"impulse 100", "inv:torch "}, +{"impulse 101", "inv:qrtz flask"}, +{"impulse 102", "inv:mystic urn"}, +{"impulse 103", "inv:krater "}, +{"impulse 104", "inv:chaos devc"}, +{"impulse 105", "inv:tome power"}, +{"impulse 106", "inv:summon stn"}, +{"impulse 107", "inv:invisiblty"}, +{"impulse 108", "inv:glyph "}, +{"impulse 109", "inv:boots "}, +{"impulse 110", "inv:repulsion "}, +{"impulse 111", "inv:bo peep "}, +{"impulse 112", "inv:flight "}, +{"impulse 113", "inv:force cube"}, +{"impulse 114", "inv:icon defn "}, +{NULL} +}; + bindnames_t *bindnames; int numbindnames; @@ -348,6 +397,7 @@ void M_Menu_Keys_f (void) { int y; menu_t *menu; + int mgt; key_dest = key_menu; m_state = m_complex; @@ -356,11 +406,15 @@ void M_Menu_Keys_f (void) MC_AddCenterPicture(menu, 4, "gfx/ttl_cstm.lmp"); + mgt = M_GameType(); #ifdef Q2CLIENT - if (cls.protocol == CP_QUAKE2) + if (mgt == MGT_QUAKE2) //quake2 main menu. bindnames = q2bindnames; else #endif + if (mgt == MGT_HEXEN2) + bindnames = h2bindnames; + else bindnames = qwbindnames; y = 48; diff --git a/engine/client/menu.h b/engine/client/menu.h index 7d9403d55..60f16fa2e 100644 --- a/engine/client/menu.h +++ b/engine/client/menu.h @@ -279,7 +279,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname); menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname); menupicture_t *MC_AddCursor(menu_t *menu, int x, int y); -menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max); +menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max, float delta); menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t *var, int cvarbitmask); menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits); menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command); diff --git a/engine/client/merged.h b/engine/client/merged.h index c5e6da039..5df3a89d0 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -100,8 +100,8 @@ extern void FNC(Mod_TouchModel) (char *name); extern void FNC(Mod_NowLoadExternal) (void); extern void FNC(Mod_Think) (void); -extern qboolean FNC(Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); -extern int FNC(Mod_TagNumForName) (struct model_s *model, char *name); +//extern qboolean FNC(Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); +//extern int FNC(Mod_TagNumForName) (struct model_s *model, char *name); extern int FNC(Mod_SkinForName) (struct model_s *model, char *name); #undef FNC diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 50aa95e2b..f96cf504f 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -856,10 +856,10 @@ static void buildmatricies(void) float modelview[16]; float proj[16]; - ML_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg); - ML_ProjectionMatrix2(proj, r_refdef.fov_x, r_refdef.fov_y); + Matrix4_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg); + Matrix4_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4); Matrix4_Multiply(proj, modelview, mvp); - Matrix4x4_Invert_Simple((matrix4x4_t*)mvpi, (matrix4x4_t*)mvp); //not actually used in this function. + Matrix4_Invert_Simple((matrix4x4_t*)mvpi, (matrix4x4_t*)mvp); //not actually used in this function. csqc_rebuildmatricies = false; } diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 7e6070b32..42ebafcc2 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -32,6 +32,9 @@ The engine has a few builtins. #ifdef RGLQUAKE #include "glquake.h"//hack #endif +#ifdef D3DQUAKE +#include "d3dquake.h"//hack +#endif #include "renderque.h" @@ -143,24 +146,6 @@ cvar_t r_part_contentswitch = SCVAR("r_part_contentswitch", "1"); static float particletime; -typedef struct skytris_s { - struct skytris_s *next; - vec3_t org; - vec3_t x; - vec3_t y; - float area; - float nexttime; - msurface_t *face; -} skytris_t; - -//these could be deltas or absolutes depending on ramping mode. -typedef struct { - vec3_t rgb; - float alpha; - float scale; - float rotation; -} ramp_t; - #define APPLYBLEND(bm) \ switch (bm) \ { \ @@ -179,102 +164,29 @@ typedef struct { break; \ } -// TODO: merge in alpha with rgb to gain benefit of vector opts -typedef struct part_type_s { - char name[MAX_QPATH]; - char texname[MAX_QPATH]; - vec3_t rgb; - vec3_t rgbchange; - vec3_t rgbrand; - int colorindex; - int colorrand; - float rgbchangetime; - vec3_t rgbrandsync; - float scale, alpha; - float alphachange; - float die, randdie; - float randomvel, veladd; - float orgadd; - float offsetspread; - float offsetspreadvert; - float randomvelvert; - float randscale; +#define APPLYD3DBLEND(bm) \ + switch (bm) \ + { \ + case BM_ADD: \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); \ + break; \ + case BM_SUBTRACT: \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLENDCOLOUR: \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR); \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLEND: \ + default: \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \ + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); \ + break; \ + } - float spawntime; - float spawnchance; - enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; - blendmode_t blendmode; - - float rotationstartmin, rotationstartrand; - float rotationmin, rotationrand; - - float scaledelta; - float count; - float countrand; - int texturenum; - int assoc; - int cliptype; - int inwater; - float clipcount; - int emit; - float emittime; - float emitrand; - float emitstart; - - float areaspread; - float areaspreadvert; - float scalefactor; - float invscalefactor; - - float spawnparam1; - float spawnparam2; -/* float spawnparam3; */ - - float offsetup; // make this into a vec3_t later with dir, possibly for mdls - - enum { - SM_BOX, //box = even spread within the area - SM_CIRCLE, //circle = around edge of a circle - SM_BALL, //ball = filled sphere - SM_SPIRAL, //spiral = spiral trail - SM_TRACER, //tracer = tracer trail - SM_TELEBOX, //telebox = q1-style telebox - SM_LAVASPLASH, //lavasplash = q1-style lavasplash - SM_UNICIRCLE, //unicircle = uniform circle - SM_FIELD, //field = synced field (brightfield, etc) - SM_DISTBALL // uneven distributed ball - } spawnmode; - - float gravity; - vec3_t friction; - float clipbounce; - int stains; - - enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode; - int rampindexes; - ramp_t *ramp; - - int loaded; - particle_t *particles; - clippeddecal_t *clippeddecals; - beamseg_t *beams; - skytris_t *skytris; - struct part_type_s *nexttorun; - - unsigned int flags; -#define PT_VELOCITY 0x001 -#define PT_FRICTION 0x002 -#define PT_CHANGESCOLOUR 0x004 -#define PT_CITRACER 0x008 // Q1-style tracer behavior for colorindex -#define PT_INVFRAMETIME 0x010 // apply inverse frametime to count (causes emits to be per frame) -#define PT_AVERAGETRAIL 0x020 // average trail points from start to end, useful with t_lightning, etc -#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...) -#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle -#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle - unsigned int state; -#define PS_INRUNLIST 0x1 // particle type is currently in execution list -} part_type_t; int numparticletypes; part_type_t *part_type; part_type_t *part_run_list; @@ -403,28 +315,56 @@ static int CheckAssosiation(char *name, int from) return orig; } -#ifdef RGLQUAKE void P_LoadTexture(part_type_t *ptype, qboolean warn) { - if (*ptype->texname && strcmp(ptype->texname, "default")) + switch (qrenderer) { - ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); - - if (!ptype->texturenum) +#ifdef RGLQUAKE + case QR_OPENGL: + if (*ptype->texname && strcmp(ptype->texname, "default")) { - if (warn) - Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); + ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); - if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) - ptype->texturenum = balltexture; - else - ptype->texturenum = explosiontexture; + if (!ptype->texturenum) + { + if (warn) + Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); + + if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) + ptype->texturenum = balltexture; + else + ptype->texturenum = explosiontexture; + } } - } - else - ptype->texturenum = explosiontexture; -} + else + ptype->texturenum = explosiontexture; + break; #endif +#ifdef D3DQUAKE + case QR_DIRECT3D: + if (*ptype->texname && strcmp(ptype->texname, "default")) + { + ptype->d3dtexture = NULL;//Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); + + if (!ptype->d3dtexture) + { + if (warn) + Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); + + if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) + ptype->d3dtexture = d3dballtexture; + else + ptype->d3dtexture = d3dexplosiontexture; + } + } + else + ptype->d3dtexture = d3dexplosiontexture; + break; +#endif + default: + break; + } +} //Uses FTE's multiline console stuff. //This is the function that loads the effect descriptions (via console). @@ -1030,12 +970,7 @@ void P_ParticleEffect_f(void) Con_Printf("Particle type %s has a ramp but no ramp mode\n", ptype->name); } -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - { - P_LoadTexture(ptype, true); - } -#endif + P_LoadTexture(ptype, true); } //assosiate a point effect with a model. @@ -1061,6 +996,8 @@ void P_AssosiateEffect_f (void) } model = Mod_FindName(modelname); + if (!model) + return; if (!cls.demoplayback && (model->flags & EF_ROTATE)) { Con_Printf("Sorry: You may not assosiate effects with item model \"%s\"\n", modelname); @@ -1094,6 +1031,8 @@ void P_AssosiateTrail_f (void) } model = Mod_FindName(modelname); + if (!model) + return; effectnum = P_AllocateParticleType(effectname); model->particletrail = effectnum; model->engineflags |= MDLF_NODEFAULTTRAIL; //we could have assigned the trail to a model that wasn't loaded. @@ -1508,15 +1447,10 @@ void P_ClearParticles (void) particletime = cl.time; -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) + for (i = 0; i < numparticletypes; i++) { - for (i = 0; i < numparticletypes; i++) - { - P_LoadTexture(&part_type[i], false); - } + P_LoadTexture(&part_type[i], false); } -#endif for (i = 0; i < numparticletypes; i++) { @@ -3942,6 +3876,422 @@ void SWD_DrawParticleBeam(beamseg_t *beam, part_type_t *type) D_DrawSparkTrans(p, p->org, q->org, type->blendmode); } #endif +#ifdef D3DQUAKE +typedef struct d3dparticlevert_s { + float org[3]; + unsigned int colour; + float s, t; //these could actually be preinitialised +} d3dparticlevert_t; +d3dparticlevert_t d3dparticlevert[4]; + +typedef struct d3dparticlevertut_s { + float org[3]; + unsigned int colour; +} d3dparticlevertut_t; +d3dparticlevertut_t d3dparticlevertut[4]; + +unsigned short d3dparticlevertindexes[] = +{ + 0, 1, 2, + 0, 2, 3 +}; + +void D3D_DrawParticleBlob(particle_t *p, part_type_t *type) +{ + float scale; + float x; + float y; + unsigned int colour; + int cb, cg, cr, ca; + if (lastgltype != type) + { + lastgltype = type; + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3DBLEND(type->blendmode); + } + + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.25; + else + scale = 0.25 + scale * 0.001; + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + if (p->angle) + { + x = sin(p->angle)*scale; + y = cos(p->angle)*scale; + } + else + { + x = 0; + y = scale; + } + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + d3dparticlevert[0].org[0] = p->org[0] - x*pright[0] - y*pup[0]; + d3dparticlevert[0].org[1] = p->org[1] - x*pright[1] - y*pup[1]; + d3dparticlevert[0].org[2] = p->org[2] - x*pright[2] - y*pup[2]; + + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + d3dparticlevert[1].org[0] = p->org[0] - y*pright[0] + x*pup[0]; + d3dparticlevert[1].org[1] = p->org[1] - y*pright[1] + x*pup[1]; + d3dparticlevert[1].org[2] = p->org[2] - y*pright[2] + x*pup[2]; + + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + d3dparticlevert[2].org[0] = p->org[0] + x*pright[0] + y*pup[0]; + d3dparticlevert[2].org[1] = p->org[1] + x*pright[1] + y*pup[1]; + d3dparticlevert[2].org[2] = p->org[2] + x*pright[2] + y*pup[2]; + + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + d3dparticlevert[3].org[0] = p->org[0] + y*pright[0] - x*pup[0]; + d3dparticlevert[3].org[1] = p->org[1] + y*pright[1] - x*pup[1]; + d3dparticlevert[3].org[2] = p->org[2] + y*pright[2] - x*pup[2]; + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0); +} +void D3D_DrawParticleSpark(particle_t *p, part_type_t *type) +{ + vec3_t v, crv, o2; + + unsigned int colour; + int cb, cg, cr, ca; + + if (lastgltype != type) + { + lastgltype = type; + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3DBLEND(type->blendmode); + } + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + VectorSubtract(r_refdef.vieworg, p->org, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(p->org, -p->scale/2, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(p->org, p->scale/2, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + VectorMA(p->org, 0.1, p->vel, o2); + + VectorSubtract(r_refdef.vieworg, o2, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(o2, p->scale/2, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(o2, -p->scale/2, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0); +} +void D3D_DrawParticleBeam(beamseg_t *b, part_type_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + + if (lastgltype != type) + { + lastgltype = type; + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3DBLEND(type->blendmode); + } + + + + + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(q->org, -q->scale, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = ts; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = ts; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(p->org, p->scale, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = ts; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = ts; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0); +} + +void D3D_DrawParticleBeamUT(beamseg_t *b, part_type_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + +// D3D_DrawParticleBeam(b, type); +// return; + + if (lastgltype != type) + { + lastgltype = type; + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + + + APPLYD3DBLEND(type->blendmode); + } + + + + + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(q->org, -q->scale, crv, d3dparticlevertut[0].org); + d3dparticlevertut[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevertut[1].org); + d3dparticlevertut[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(p->org, p->scale, crv, d3dparticlevertut[2].org); + d3dparticlevertut[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevertut[3].org); + d3dparticlevertut[3].colour = colour; + + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE, d3dparticlevertut, 4, d3dparticlevertindexes, 6, 0); +} +#endif void DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type_t*), void (*sparklineparticles)(particle_t*,part_type_t*), void (*sparkfanparticles)(particle_t*,part_type_t*), void (*sparktexturedparticles)(particle_t*,part_type_t*), void (*beamparticlest)(beamseg_t*,part_type_t*), void (*beamparticlesut)(beamseg_t*,part_type_t*), void (*drawdecalparticles)(clippeddecal_t*,part_type_t*)) { @@ -4572,6 +4922,41 @@ void P_DrawParticles (void) return; } #endif +#if defined(D3DQUAKE) + if (qrenderer == QR_DIRECT3D) + { + if (pD3DDev) + { + lastgltype = NULL; + DrawParticleTypes(D3D_DrawParticleBlob, D3D_DrawParticleSpark, D3D_DrawParticleSpark, D3D_DrawParticleSpark, D3D_DrawParticleBeam, D3D_DrawParticleBeamUT, NULL); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZWRITEENABLE, FALSE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); + + RSpeedRemark(); + RQ_RenderDistAndClear(); + RSpeedEnd(RSPEED_PARTICLESDRAW); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZWRITEENABLE, TRUE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + return; + } + else + D3D9_DrawParticles(particletime); + } +#endif + + if (qrenderer) + { + RSpeedRemark(); + RQ_RenderDistAndClear(); + RSpeedEnd(RSPEED_PARTICLESDRAW); + } } diff --git a/engine/client/render.h b/engine/client/render.h index 75083112a..1cf57b33c 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -27,6 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TOP_RANGE (TOP_DEFAULT<<4) #define BOTTOM_RANGE (BOTTOM_DEFAULT<<4) +extern int r_framecount; + struct msurface_s; //============================================================================= @@ -266,15 +268,124 @@ void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj); struct palremap_s *D_IdentityRemap(void); +//normalmaps +//bumpmaps +//32bits +//8bits +//8bitpal24 +//8bitpal32 + +#define TF_NOMIPMAP 0x0000 +#define TF_NOTBUMPMAP 0x0000 +#define TF_NOALPHA 0x0000 + +#define TF_MIPMAP 0x0001 +#define TF_BUMPMAP 0x0002 //or normalmap, depending on 8/24 bitness +#define TF_ALPHA 0x0004 //preserve alpha channel (8biit, use index 255 for transparency) + +#define TF_FULLBRIGHT 0x0008 //dark pixels have alpha forced to 0 +#define TF_24BIT 0x0010 +#define TF_32BIT 0x0020 //use the standard quake palette + +#define TF_MANDATORY (TF_NOMIPMAP|TF_NOTBUMPMAP|TF_NOALPHA) + +#if 0 +/* +int R_LoadTexture(char *name, int width, int height, void *data, void *palette, int flags) +{ + if (palette) + { + if (flags & TF_BUMPMAP) + return 0; //huh? + + if (flags & TF_FULLBRIGHT) + return 0; //huh? + + if (flags & TF_32BIT) + return R_LoadTexture8Pal32(name, width, height, data, palette, flags&TF_MIPMAP, flags&TF_ALPHA); + + return 0; + } + + if (flags & TF_FULLBRIGHT) + { + if (flags & TF_BUMPMAP) + return 0; //huh? + + if (flags & TF_24BIT) + return 0; + if (flags & TF_32BIT) + return 0; + + //8bit fullbrights + return R_LoadTextureFB(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA); + } + + if (flags & TF_BUMPMAP) + { + if (flags & TF_24BIT) + return 0; + if (flags & TF_32BIT) + return R_LoadTexture32(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA); //Warning: this is not correct + return R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_BUMPMAP | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + } + + if (flags & TF_32BIT) + return R_LoadTexture32(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA); + if (data) + return R_LoadTexture8(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA); + + return R_FindTexture(name); +} + + #define R_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) R_LoadTexture(name, width, height, data, palette, TF_32BIT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + #define R_LoadTexture8(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + #define R_LoadTexture32(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_32BIT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + #define R_LoadTextureFB(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_FULLBRIGHT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + #define R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_BUMPMAP | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA)) + + #define R_FindTexture(name) R_LoadTexture(name, 0, 0, NULL, NULL, 0) + #define R_LoadCompressed(name) ((qrenderer == QR_OPENGL)?GL_LoadCompressed(name):0) +*/ +#elif defined(RGLQUAKE) && defined(D3DQUAKE) + #define R_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha)) + #define R_LoadTexture8Pal24(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha)) + #define R_LoadTexture8(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture(skinname, width, height, data, usemips, alpha):GL_LoadTexture(skinname, width, height, data, usemips, alpha)) + #define R_LoadTexture32(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture32(skinname, width, height, data, usemips, alpha):GL_LoadTexture32(skinname, width, height, data, usemips, alpha)) + #define R_LoadTextureFB(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTextureFB(skinname, width, height, data, usemips, alpha):GL_LoadTextureFB(skinname, width, height, data, usemips, alpha)) + #define R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?/*D3D_LoadTexture8Bump(skinname, width, height, data, usemips, alpha)*/NULL:GL_LoadTexture8Bump(skinname, width, height, data, usemips, alpha)) + + #define R_FindTexture(name) ((qrenderer == QR_DIRECT3D)?D3D_FindTexture(name):GL_FindTexture(name)) + #define R_LoadCompressed(name) ((qrenderer == QR_DIRECT3D)?D3D_LoadCompressed(name):GL_LoadCompressed(name)) +#elif defined(D3DQUAKE) + #define R_LoadTexture8Pal32 D3D_LoadTexture8Pal32 + #define R_LoadTexture8 D3D_LoadTexture + #define R_LoadTexture32 D3D_LoadTexture32 + #define R_LoadTextureFB D3D_LoadTextureFB + #define R_LoadTexture8Bump D3D_LoadTexture8Bump + + #define R_FindTexture D3D_FindTexture + #define R_LoadCompressed D3D_LoadCompressed +#elif defined(RGLQUAKE) + #define R_LoadTexture8Pal32 GL_LoadTexture8Pal32 + #define R_LoadTexture8 GL_LoadTexture + #define R_LoadTexture32 GL_LoadTexture32 + #define R_LoadTextureFB GL_LoadTextureFB + #define R_LoadTexture8Bump GL_LoadTexture8Bump + + #define R_FindTexture GL_FindTexture + #define R_LoadCompressed GL_LoadCompressed +#endif -#if defined(RGLQUAKE) + +#if defined(RGLQUAKE) || defined(D3DQUAKE) void GLMod_Init (void); -qboolean GLMod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result); -int GLMod_TagNumForName(struct model_s *model, char *name); -int GLMod_SkinNumForName(struct model_s *model, char *name); +qboolean Mod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result); +int Mod_TagNumForName(struct model_s *model, char *name); +int Mod_SkinNumForName(struct model_s *model, char *name); void GLMod_ClearAll (void); struct model_s *GLMod_ForName (char *name, qboolean crash); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index e02f73499..da852cae3 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -35,6 +35,7 @@ void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldval // +cvar_t r_novis = SCVAR("r_novis", "0"); cvar_t r_drawviewmodel = SCVAR("r_drawviewmodel","1"); cvar_t r_drawviewmodelinvis = SCVAR("r_drawviewmodelinvis", "0"); cvar_t r_netgraph = SCVAR("r_netgraph","0"); @@ -139,7 +140,7 @@ cvar_t gl_compress = SCVARF("gl_compress", "0", CVAR_ARCHIVE); cvar_t gl_savecompressedtex = SCVAR("gl_savecompressedtex", "0"); extern cvar_t gl_dither; extern cvar_t gl_maxdist; -extern cvar_t gl_mindist; +cvar_t gl_mindist = SCVARF("gl_mindist", "4", CVAR_CHEAT); //by setting to 64 or something, you can use this as a wallhack cvar_t gl_detail = SCVARF("gl_detail", "0", CVAR_ARCHIVE); @@ -259,6 +260,13 @@ cvar_t r_fastskycolour = SCVAR("r_fastskycolour", "0"); cvar_t r_menutint = SCVARF("r_menutint", "0.68 0.4 0.13", CVAR_RENDERERCALLBACK); +#if defined(RGLQUAKE) || defined(D3DQUAKE) +void GLD3DRenderer_Init(void) +{ + Cvar_Register (&gl_load24bit, GRAPHICALNICETIES); +} +#endif + #if defined(RGLQUAKE) cvar_t gl_schematics = SCVAR("gl_schematics","0"); cvar_t gl_ztrick = SCVAR("gl_ztrick","0"); @@ -280,7 +288,6 @@ void GLRenderer_Init(void) Cvar_Register (&vid_desktopgamma, GLRENDEREROPTIONS); //renderer - Cvar_Register (&r_novis, GLRENDEREROPTIONS); Cvar_Register (&r_mirroralpha, GLRENDEREROPTIONS); Cvar_Register (&r_norefresh, GLRENDEREROPTIONS); @@ -333,7 +340,6 @@ void GLRenderer_Init(void) #ifdef R_XFLIP Cvar_Register (&r_xflip, GLRENDEREROPTIONS); #endif - Cvar_Register (&gl_load24bit, GRAPHICALNICETIES); Cvar_Register (&gl_specular, GRAPHICALNICETIES); // Cvar_Register (&gl_lightmapmode, GLRENDEREROPTIONS); @@ -476,6 +482,9 @@ void Renderer_Init(void) Cmd_AddCommand("setrenderer", R_SetRenderer_f); Cmd_AddCommand("vid_restart", R_RestartRenderer_f); +#if defined(RGLQUAKE) || defined(D3DQUAKE) + GLD3DRenderer_Init(); +#endif #if defined(RGLQUAKE) GLRenderer_Init(); #endif @@ -483,6 +492,8 @@ void Renderer_Init(void) SWRenderer_Init(); #endif + Cvar_Register (&r_novis, GLRENDEREROPTIONS); + //but register ALL vid_ commands. Cvar_Register (&_vid_wait_override, VIDCOMMANDGROUP); Cvar_Register (&vid_stretch, VIDCOMMANDGROUP); @@ -662,8 +673,8 @@ void (*Mod_TouchModel) (char *name); void (*Mod_NowLoadExternal) (void); void (*Mod_Think) (void); -qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); -int (*Mod_TagNumForName) (struct model_s *model, char *name); +//qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); +//int (*Mod_TagNumForName) (struct model_s *model, char *name); int (*Mod_SkinForName) (struct model_s *model, char *name); @@ -759,7 +770,7 @@ rendererinfo_t dedicatedrendererinfo = { SWMod_NowLoadExternal, SWMod_Think, -#elif defined(RGLQUAKE) +#elif defined(RGLQUAKE) || defined(D3DQUAKE) GLMod_Init, GLMod_ClearAll, GLMod_ForName, @@ -770,7 +781,7 @@ rendererinfo_t dedicatedrendererinfo = { GLMod_NowLoadExternal, GLMod_Think, #else - #error "No renderer in client build" +#error "Need logic here!" #endif NULL, //Mod_GetTag @@ -963,9 +974,9 @@ rendererinfo_t openglrendererinfo = { GLMod_NowLoadExternal, GLMod_Think, - GLMod_GetTag, - GLMod_TagNumForName, - GLMod_SkinNumForName, + Mod_GetTag, + Mod_TagNumForName, + Mod_SkinNumForName, GLVID_Init, GLVID_DeInit, @@ -990,8 +1001,16 @@ rendererinfo_t openglrendererinfo = { rendererinfo_t *popenglrendererinfo = &openglrendererinfo; #endif +#ifdef D3DQUAKE +rendererinfo_t d3d7rendererinfo; +rendererinfo_t *pd3d7rendererinfo = &d3d7rendererinfo; +#endif + rendererinfo_t *pd3drendererinfo; +rendererinfo_t d3d9rendererinfo; +rendererinfo_t *pd3d9rendererinfo = &d3d9rendererinfo; + rendererinfo_t **rendererinfo[] = { &pdedicatedrendererinfo, @@ -1002,6 +1021,12 @@ rendererinfo_t **rendererinfo[] = &popenglrendererinfo, &pd3drendererinfo, #endif +#ifdef D3DQUAKE + &pd3d7rendererinfo, +#endif +#ifdef D3DQUAKE + &pd3d9rendererinfo, +#endif }; @@ -1190,6 +1215,9 @@ void M_Menu_Video_f (void) #ifdef USE_D3D "Direct3D", #endif +#endif +#ifdef D3DQUAKE + "NDirect3D", #endif NULL }; @@ -1298,12 +1326,12 @@ void M_Menu_Video_f (void) MC_AddCheckBox(menu, 16, y, " Bloom", &r_bloom,0); y+=8; #endif MC_AddCheckBox(menu, 16, y, " Dynamic lights", &r_dynamic,0); y+=8; - MC_AddSlider(menu, 16, y, " Screen size", &scr_viewsize, 30, 120);y+=8; - MC_AddSlider(menu, 16, y, " Gamma", &v_gamma, 0.3, 1); y+=8; - MC_AddSlider(menu, 16, y, " Contrast", &v_contrast, 1, 3); y+=8; + MC_AddSlider(menu, 16, y, " Screen size", &scr_viewsize, 30, 120, 0.1);y+=8; + MC_AddSlider(menu, 16, y, " Gamma", &v_gamma, 0.3, 1, 0.05); y+=8; + MC_AddSlider(menu, 16, y, " Contrast", &v_contrast, 1, 3, 0.05); y+=8; #ifdef RGLQUAKE info->texturefiltercombo = MC_AddCombo(menu, 16, y, " Texture Filter ", texturefilternames, currenttexturefilter); y+=8; - MC_AddSlider(menu, 16, y, "Anisotropy Level", &gl_texture_anisotropic_filtering, 1, 16); y+=8; + MC_AddSlider(menu, 16, y, "Anisotropy Level", &gl_texture_anisotropic_filtering, 1, 16, 1); y+=8; //urm, this shouldn't really be a slider, but should be a combo instead #endif menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 152, 32, NULL, false); @@ -1398,8 +1426,8 @@ void R_SetRenderer(int wanted) Mod_NowLoadExternal = ri->Mod_NowLoadExternal; - Mod_GetTag = ri->Mod_GetTag; - Mod_TagNumForName = ri->Mod_TagNumForName; +// Mod_GetTag = ri->Mod_GetTag; +// Mod_TagNumForName = ri->Mod_TagNumForName; Mod_SkinForName = ri->Mod_SkinForName; SCR_UpdateScreen = ri->SCR_UpdateScreen; @@ -1419,6 +1447,15 @@ qbyte default_conchar[11356] = #include "lhfont.h" }; +qboolean R_ApplyRenderer_Load (rendererstate_t *newr); +void D3DSucks(void) +{ + SCR_DeInit(); + + if (!R_ApplyRenderer_Load(NULL))//¤trendererstate)) + Sys_Error("Failed to reload content after mode switch\n"); +} + qboolean R_ApplyRenderer (rendererstate_t *newr) { int i, j; @@ -1461,6 +1498,14 @@ qboolean R_ApplyRenderer (rendererstate_t *newr) R_SetRenderer(newr->renderer); + R_ApplyRenderer_Load(newr); +} +qboolean R_ApplyRenderer_Load (rendererstate_t *newr) +{ + int i, j; + extern model_t *loadmodel; + extern int host_hunklevel; + Cache_Flush(); Hunk_FreeToLowMark(host_hunklevel); //is this a good idea? @@ -1475,7 +1520,8 @@ qboolean R_ApplyRenderer (rendererstate_t *newr) #ifndef CLIENTONLY isDedicated = false; #endif - Con_Printf("Setting mode %i*%i*%i*%i\n", newr->width, newr->height, newr->bpp, newr->rate); + if (newr) + Con_Printf("Setting mode %i*%i*%i*%i\n", newr->width, newr->height, newr->bpp, newr->rate); if (host_basepal) BZ_Free(host_basepal); @@ -1544,10 +1590,19 @@ q2colormap: TRACE(("dbg: R_ApplyRenderer: Palette loaded\n")); - if (!VID_Init(newr, host_basepal)) +#ifdef _WIN32 + if (hwnd_dialog) { - return false; + DestroyWindow (hwnd_dialog); + hwnd_dialog = NULL; } +#endif + + if (newr) + if (!VID_Init(newr, host_basepal)) + { + return false; + } TRACE(("dbg: R_ApplyRenderer: vid applied\n")); W_LoadWadFile("gfx.wad"); @@ -1799,6 +1854,12 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); "-----------------------------\n" "OpenGL renderer initialized\n"); break; + + case QR_DIRECT3D: + Con_Printf( "\n" + "-----------------------------\n" + "Direct3d renderer initialized\n"); + break; } TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n")); @@ -1807,7 +1868,8 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); TRACE(("dbg: R_ApplyRenderer: done\n")); - memcpy(¤trendererstate, newr, sizeof(currentrendererstate)); + if (newr) + memcpy(¤trendererstate, newr, sizeof(currentrendererstate)); return true; } @@ -1865,6 +1927,8 @@ TRACE(("dbg: R_RestartRenderer_f\n")); #elif defined(RGLQUAKE) Cmd_ExecuteString("setrenderer gl\n", RESTRICT_LOCAL); +#elif defined(D3DQUAKE) + Cmd_ExecuteString("setrenderer d3d\n", RESTRICT_LOCAL); #else Cmd_ExecuteString("setrenderer sw\n", RESTRICT_LOCAL); #endif @@ -2014,3 +2078,558 @@ void R_SetRenderer_f (void) + + + + + + + + + + + + + + + + + +/* +================ +R_GetSpriteFrame +================ +*/ +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = currententity->model->cache.data; + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else if (psprite->frames[frame].type == SPR_ANGLED) + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7]; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = currententity->frame1time; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} + + + +float r_projection_matrix[16]; +float r_view_matrix[16]; + +void MYgluPerspective(double fovx, double fovy, double zNear, double zFar) +{ + double xmin, xmax, ymin, ymax; + + ymax = zNear * tan( fovy * M_PI / 360.0 ); + ymin = -ymax; + + xmax = zNear * tan( fovx * M_PI / 360.0 ); + xmin = -xmax; + + r_projection_matrix[0] = (2*zNear) / (xmax - xmin); + r_projection_matrix[4] = 0; + r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin); + r_projection_matrix[12] = 0; + + r_projection_matrix[1] = 0; + r_projection_matrix[5] = (2*zNear) / (ymax - ymin); + r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin); + r_projection_matrix[13] = 0; + + r_projection_matrix[2] = 0; + r_projection_matrix[6] = 0; + r_projection_matrix[10] = - (zFar+zNear)/(zFar-zNear); + r_projection_matrix[14] = - (2.0f*zFar*zNear)/(zFar-zNear); + + r_projection_matrix[3] = 0; + r_projection_matrix[7] = 0; + r_projection_matrix[11] = -1; + r_projection_matrix[15] = 0; +} + +void GL_InfinatePerspective(double fovx, double fovy, + double zNear) +{ + // nudge infinity in just slightly for lsb slop + float nudge = 1;// - 1.0 / (1<<23); + + double xmin, xmax, ymin, ymax; + + ymax = zNear * tan( fovy * M_PI / 360.0 ); + ymin = -ymax; + + xmax = zNear * tan( fovx * M_PI / 360.0 ); + xmin = -xmax; + + r_projection_matrix[0] = (2*zNear) / (xmax - xmin); + r_projection_matrix[4] = 0; + r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin); + r_projection_matrix[12] = 0; + + r_projection_matrix[1] = 0; + r_projection_matrix[5] = (2*zNear) / (ymax - ymin); + r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin); + r_projection_matrix[13] = 0; + + r_projection_matrix[2] = 0; + r_projection_matrix[6] = 0; + r_projection_matrix[10] = -1 * nudge; + r_projection_matrix[14] = -2*zNear * nudge; + + r_projection_matrix[3] = 0; + r_projection_matrix[7] = 0; + r_projection_matrix[11] = -1; + r_projection_matrix[15] = 0; +} + +void GL_ParallelPerspective(double xmin, double xmax, double ymax, double ymin, + double znear, double zfar) +{ + r_projection_matrix[0] = 2/(xmax-xmin); + r_projection_matrix[4] = 0; + r_projection_matrix[8] = 0; + r_projection_matrix[12] = (xmax+xmin)/(xmax-xmin); + + r_projection_matrix[1] = 0; + r_projection_matrix[5] = 2/(ymax-ymin); + r_projection_matrix[9] = 0; + r_projection_matrix[13] = (ymax+ymin)/(ymax-ymin); + + r_projection_matrix[2] = 0; + r_projection_matrix[6] = 0; + r_projection_matrix[10] = -2/(zfar-znear); + r_projection_matrix[14] = (zfar+znear)/(zfar-znear); + + r_projection_matrix[3] = 0; + r_projection_matrix[7] = 0; + r_projection_matrix[11] = 0; + r_projection_matrix[15] = 1; +} + + + +/* +=============== +R_TextureAnimation + +Returns the proper texture for a given time and base texture +=============== +*/ +extern entity_t *currententity; +texture_t *R_TextureAnimation (texture_t *base) +{ + int reletive; + int count; + + if (currententity->frame) + { + if (base->alternate_anims) + base = base->alternate_anims; + } + + if (!base->anim_total) + return base; + + reletive = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > reletive || base->anim_max <= reletive) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + + return base; +} + + + + + +extern mleaf_t *r_viewleaf, *r_oldviewleaf; +extern mleaf_t *r_viewleaf2, *r_oldviewleaf2; +extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; +extern int r_visframecount; +extern mleaf_t *r_vischain; // linked list of visible leafs + +/* +=============== +R_MarkLeaves +=============== +*/ + +void R_MarkLeaves (void) +{ + qbyte fatvis[MAX_MAP_LEAFS/8]; + qbyte *vis; + mnode_t *node; + int i; + qbyte solid[4096]; +#ifdef Q3BSPS + if (cl.worldmodel->fromgame == fg_quake3) + { + int cluster; + mleaf_t *leaf; + + if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1) + return; + + // development aid to let you run around and see exactly where + // the pvs ends +// if (r_lockpvs->value) +// return; + + r_vischain = NULL; + r_visframecount++; + r_oldviewcluster = r_viewcluster; + + if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis ) + { + // mark everything + for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) + { + if ( !leaf->nummarksurfaces ) { + continue; + } + + leaf->visframe = r_visframecount; + leaf->vischain = r_vischain; + r_vischain = leaf; + } + return; + } + + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel); + for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) + { + cluster = leaf->cluster; + if ( cluster == -1 || !leaf->nummarksurfaces ) { + continue; + } + if ( vis[cluster>>3] & (1<<(cluster&7)) ) { + leaf->visframe = r_visframecount; + leaf->vischain = r_vischain; + r_vischain = leaf; + } + } + return; + } +#endif + +#ifdef Q2BSPS + if (cl.worldmodel->fromgame == fg_quake2) + { + int c; + mleaf_t *leaf; + int cluster; + + if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) + return; + + r_oldviewcluster = r_viewcluster; + r_oldviewcluster2 = r_viewcluster2; + + if (r_novis.value == 2) + return; + r_visframecount++; + if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis) + { + // mark everything + for (i=0 ; inumleafs ; i++) + cl.worldmodel->leafs[i].visframe = r_visframecount; + for (i=0 ; inumnodes ; i++) + cl.worldmodel->nodes[i].visframe = r_visframecount; + return; + } + + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel); + // may have to combine two clusters because of solid water boundaries + if (r_viewcluster2 != r_viewcluster) + { + memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8); + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel); + c = (cl.worldmodel->numleafs+31)/32; + for (i=0 ; ileafs ; inumleafs ; i++, leaf++) + { + cluster = leaf->cluster; + if (cluster == -1) + continue; + if (vis[cluster>>3] & (1<<(cluster&7))) + { + node = (mnode_t *)leaf; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } + return; + } +#endif + + if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2) + return; + +// if (mirror) +// return; + + r_visframecount++; + + r_oldviewleaf = r_viewleaf; + r_oldviewleaf2 = r_viewleaf2; + + if (r_novis.value) + { + vis = solid; + memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); + } + else if (r_viewleaf2) + { + int c; + Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis); + vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL); + c = (cl.worldmodel->numleafs+31)/32; + for (i=0 ; inumleafs ; i++) + { + if (vis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } +} + + + +mplane_t frustum[4]; + + +/* +================= +R_CullBox + +Returns true if the box is completely outside the frustom +================= +*/ +qboolean R_CullBox (vec3_t mins, vec3_t maxs) +{ + int i; + + for (i=0 ; i<4 ; i++) + if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2) + return true; + return false; +} + +qboolean R_CullSphere (vec3_t org, float radius) +{ + //four frustrum planes all point inwards in an expanding 'cone'. + int i; + float d; + + for (i=0 ; i<4 ; i++) + { + d = DotProduct(frustum[i].normal, org)-frustum[i].dist; + if (d <= -radius) + return true; + } + return false; +} + +qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs) +{ + int i; + vec3_t wmin, wmax; + float fmin, fmax; + + //convert the model's bbox to the expanded maximum size of the entity, as drawn with this model. + //The result is an axial box, which we pass to R_CullBox + + for (i = 0; i < 3; i++) + { + fmin = DotProduct(modmins, e->axis[i]); + fmax = DotProduct(modmaxs, e->axis[i]); + + if (fmin > -16) + fmin = -16; + if (fmax < 16) + fmax = 16; + + if (fmin < fmax) + { + wmin[i] = e->origin[i]+fmin; + wmax[i] = e->origin[i]+fmax; + } + else + { //box went inside out + wmin[i] = e->origin[i]+fmax; + wmax[i] = e->origin[i]+fmin; + } + } + + + return R_CullBox(wmin, wmax); +} + + + + +int SignbitsForPlane (mplane_t *out) +{ + int bits, j; + + // for fast box on planeside test + + bits = 0; + for (j=0 ; j<3 ; j++) + { + if (out->normal[j] < 0) + bits |= 1<0) return; #endif + + Sbar_Start(); + if (cls.gamemode != GAME_DEATHMATCH) Sbar_CoopIntermission(); else if (cl.teamplay > 0 && !sb_showscores) diff --git a/engine/client/screen.h b/engine/client/screen.h index d1c529d3b..24420f6f0 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -91,6 +91,6 @@ void SCR_ShowPic_Clear(void); //a header is better than none... void Draw_TextBox (int x, int y, int width, int lines); -void SCR_ScreenShot (char *filename); +qboolean SCR_ScreenShot (char *filename); void SCR_DrawTwoDimensional(int uimenu, qboolean nohud); diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index 1f47523ce..68e1f6310 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "winquake.h" +#include + #define SND_ERROR 0 #define SND_LOADED 1 #define SND_NOMORE 2 //like error, but doesn't try the next card. diff --git a/engine/client/vid.h b/engine/client/vid.h index c4344ba14..65d100a5c 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // a pixel can be one, two, or four bytes typedef qbyte pixel_t; -typedef enum {QR_NONE, QR_SOFTWARE, QR_OPENGL} r_qrenderer_t; +typedef enum {QR_NONE, QR_SOFTWARE, QR_OPENGL, QR_DIRECT3D} r_qrenderer_t; typedef struct { //you are not allowed to make anything not work if it's not based on these vars... @@ -59,10 +59,12 @@ typedef struct float aspect; // width / height -- < 0 is taller than wide int numpages; int recalc_refdef; // if true, recalc vid-based stuff + pixel_t *conbuffer; int conrowbytes; unsigned conwidth; unsigned conheight; + int maxwarpwidth; int maxwarpheight; pixel_t *direct; // direct drawing to framebuffer, if not @@ -143,5 +145,6 @@ int SWVID_ForceUnlockedAndReturnState (void); void SWVID_ForceLockState (int lk); char *SWVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight); + void SWVID_SetCaption(char *caption); #endif diff --git a/engine/client/view.c b/engine/client/view.c index 3b970d0db..008acef71 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -374,7 +374,7 @@ void SWV_Gamma_Callback(struct cvar_s *var, char *oldvalue) } #endif -#ifdef RGLQUAKE +#if defined(RGLQUAKE) || defined(D3DQUAKE) void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue) { BuildGammaTable (v_gamma.value, v_contrast.value); @@ -610,7 +610,7 @@ void V_CalcPowerupCshift (void) V_CalcBlend ============= */ -#if defined(RGLQUAKE) +#if defined(RGLQUAKE) || defined(D3DQUAKE) void GLV_CalcBlendServer (float colors[4]) { @@ -1299,7 +1299,6 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum) r_refdef.fov_y = CalcFov(r_refdef.fov_x, vrect->width, vrect->height); } -void ML_Project(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); void R_DrawNameTags(void) { int i; @@ -1332,7 +1331,7 @@ void R_DrawNameTags(void) { VectorCopy(state->origin, tagcenter); tagcenter[2] += 32; - ML_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, (float)r_refdef.vrect.width/r_refdef.vrect.height, r_refdef.fov_y); + Matrix4_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, (float)r_refdef.vrect.width/r_refdef.vrect.height, r_refdef.fov_y); if (center[2] > 1) continue; Draw_FunString(center[0]*r_refdef.vrect.width+r_refdef.vrect.x, (1-center[1])*r_refdef.vrect.height+r_refdef.vrect.y, cl.players[i].name); diff --git a/engine/client/winquake.h b/engine/client/winquake.h index e118d6920..cc5f78ca1 100644 --- a/engine/client/winquake.h +++ b/engine/client/winquake.h @@ -49,7 +49,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef SERVERONLY #ifndef NODIRECTX #include -#include #endif #ifdef SWQUAKE #ifdef MGL diff --git a/engine/common/common.c b/engine/common/common.c index 743a2dceb..163cd71ca 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1185,7 +1185,7 @@ char *MSG_ReadString (void) do { c = MSG_ReadChar (); - if (c == -1 || c == 0) + if (msg_badread || c == 0) break; string[l] = c; l++; @@ -1205,7 +1205,7 @@ char *MSG_ReadStringLine (void) do { c = MSG_ReadChar (); - if (c == -1 || c == 0 || c == '\n') + if (msg_badread || c == 0 || c == '\n') break; string[l] = c; l++; diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 51a0fd7d3..bbd01b6c5 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -3,6 +3,9 @@ #include "glquake.h" #include "shader.h" #endif +#ifdef D3DQUAKE +#include "d3dquake.h" +#endif #define MAX_Q3MAP_INDICES 0x80000 #define MAX_Q3MAP_VERTEXES 0x80000 @@ -1067,7 +1070,7 @@ void *Mod_LoadWall(char *name) if (in) //this is a pcx. { #ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) + if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) { tex = Hunk_AllocName(sizeof(texture_t), ln); @@ -1075,11 +1078,9 @@ void *Mod_LoadWall(char *name) tex->width = width; tex->height = height; - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, loadname, true, false, true))) if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, "bmodels", true, false, true))) tex->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false); - texture_mode = GL_LINEAR; } else #endif @@ -1148,8 +1149,8 @@ void *Mod_LoadWall(char *name) return tex; } -#if defined(RGLQUAKE) - if (qrenderer == QR_OPENGL) +#if defined(RGLQUAKE) || defined(D3DQUAKE) + if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) { int j; tex = Hunk_AllocName(sizeof(texture_t), ln); @@ -1158,17 +1159,15 @@ void *Mod_LoadWall(char *name) tex->width = wal->width; tex->height = wal->height; - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, loadname, true, false, true))) if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, "bmodels", true, false, true))) - tex->gl_texturenum = GL_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); + tex->gl_texturenum = R_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); in = Hunk_TempAllocMore(wal->width*wal->height); oin = (qbyte *)wal+wal->offsets[0]; for (j = 0; j < wal->width*wal->height; j++) in[j] = (d_q28to24table[oin[j]*3+0] + d_q28to24table[oin[j]*3+1] + d_q28to24table[oin[j]*3+2])/3; - tex->gl_texturenumbumpmap = GL_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value); - texture_mode = GL_LINEAR; + tex->gl_texturenumbumpmap = R_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value); } else #endif @@ -1259,7 +1258,7 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac loadmodel->texinfo = out; loadmodel->numtexinfo = count; -#if !defined(SERVERONLY) && defined(RGLQUAKE) +#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE)) skytexturenum = -1; #endif @@ -1462,7 +1461,7 @@ qboolean CMod_LoadFaces (lump_t *l) if (i == -1) out->samples = NULL; #ifdef RGLQUAKE - else if (qrenderer == QR_OPENGL) + else if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) out->samples = loadmodel->lightdata + i; #endif #ifdef SWQUAKE @@ -2099,7 +2098,7 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) numtexinfo = count; out = map_surfaces = Hunk_Alloc(count*sizeof(*out)); -#if !defined(SERVERONLY) && defined(RGLQUAKE) +#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE)) skytexturenum = -1; #endif @@ -2111,8 +2110,8 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) { loadmodel->texinfo[i].texture = Hunk_Alloc(sizeof(texture_t)); Q_strncpyz(loadmodel->texinfo[i].texture->name, in->shadername, sizeof(loadmodel->texinfo[i].texture->name)); -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL && !useshaders) +#if defined(RGLQUAKE) || defined(D3DQUAKE) + if ((qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) && !useshaders) { loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, loadname, true, false, true); if (!loadmodel->texinfo[i].texture->gl_texturenum) @@ -2252,7 +2251,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l) qboolean CModQ3_LoadIndexes (lump_t *l) { int i, count; - int *in, *out; + int *in; + index_t *out; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -3475,7 +3475,7 @@ int CM_GetQ2Palette (void) BZ_Free(f); -#ifdef RGLQUAKE +#if defined(RGLQUAKE) || defined(D3DQUAKE) { extern float vid_gamma; float f, inf; @@ -3855,7 +3855,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned #ifdef Q3SHADERS { extern cvar_t gl_shadeq3; - useshaders = gl_shadeq3.value; + useshaders = qrenderer == QR_OPENGL && gl_shadeq3.value; } #else useshaders = false; @@ -3901,6 +3901,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned { #if defined(RGLQUAKE) case QR_OPENGL: +#endif +#if defined(D3DQUAKE) + case QR_DIRECT3D: #endif case QR_NONE: //dedicated only mapisq3 = true; @@ -3922,8 +3925,8 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned noerrors = noerrors && CModRBSP_LoadFaces (&header.lumps[Q3LUMP_SURFACES]); else noerrors = noerrors && CModQ3_LoadFaces (&header.lumps[Q3LUMP_SURFACES]); -#if defined(RGLQUAKE) - if (qrenderer == QR_OPENGL) +#if defined(RGLQUAKE) || defined(D3DQUAKE) + if (qrenderer != QR_NONE) { if (noerrors) GLMod_LoadLighting (&header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading. @@ -3972,7 +3975,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum; -#if defined(RGLQUAKE) +#if defined(RGLQUAKE) || defined(D3DQUAKE) loadmodel->funcs.LightPointValues = GLQ3_LightGrid; loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode; loadmodel->funcs.MarkLights = Q2BSP_MarkLights; @@ -4180,6 +4183,8 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned break; #endif default: + Hunk_FreeToLowMark(start); + return NULL; Sys_Error("Bad internal renderer on q2 map load\n"); } } diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index d95909bdf..455db7ee9 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -832,7 +832,7 @@ void Matrix4_Transform3(float *matrix, float *vector, float *product) product[2] = matrix[2]*vector[0] + matrix[6]*vector[1] + matrix[10]*vector[2] + matrix[14]; } -void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg) +void Matrix4_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg) { float tempmat[16]; //load identity. @@ -861,7 +861,7 @@ void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg) Matrix4_Multiply(tempmat, Matrix4_NewTranslation(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up } -void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg) +void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg) { float tempmat[16]; @@ -886,64 +886,108 @@ void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_ } -void ML_ProjectionMatrix(float *proj, float wdivh, float fovy) +void Matrix4_ModelMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg) +{ + float tempmat[16]; + + tempmat[ 0] = pn[0]; + tempmat[ 1] = pn[1]; + tempmat[ 2] = pn[2]; + tempmat[ 3] = 0; + tempmat[ 4] = right[0]; + tempmat[ 5] = right[1]; + tempmat[ 6] = right[2]; + tempmat[ 7] = 0; + tempmat[ 8] = up[0]; + tempmat[ 9] = up[1]; + tempmat[10] = up[2]; + tempmat[11] = 0; + tempmat[12] = 0; + tempmat[13] = 0; + tempmat[14] = 0; + tempmat[15] = 1; + + Matrix4_Multiply(Matrix4_NewTranslation(vieworg[0], vieworg[1], vieworg[2]), tempmat, modelview); // put Z going up +} + +void Matrix4_Identity(float *outm) +{ + outm[ 0] = 1; + outm[ 1] = 0; + outm[ 2] = 0; + outm[ 3] = 0; + outm[ 4] = 0; + outm[ 5] = 1; + outm[ 6] = 0; + outm[ 7] = 0; + outm[ 8] = 0; + outm[ 9] = 0; + outm[10] = 1; + outm[11] = 0; + outm[12] = 0; + outm[13] = 0; + outm[14] = 0; + outm[15] = 1; +} + +void Matrix4_Projection(float *proj, float wdivh, float fovy, float neard) { float xmin, xmax, ymin, ymax; float nudge = 1; //proj - ymax = 4 * tan( fovy * M_PI / 360.0 ); + ymax = neard * tan( fovy * M_PI / 360.0 ); ymin = -ymax; xmin = ymin * wdivh; xmax = ymax * wdivh; - proj[0] = (2*4) / (xmax - xmin); + proj[0] = (2*neard) / (xmax - xmin); proj[4] = 0; proj[8] = (xmax + xmin) / (xmax - xmin); proj[12] = 0; proj[1] = 0; - proj[5] = (2*4) / (ymax - ymin); + proj[5] = (2*neard) / (ymax - ymin); proj[9] = (ymax + ymin) / (ymax - ymin); proj[13] = 0; proj[2] = 0; proj[6] = 0; proj[10] = -1 * nudge; - proj[14] = -2*4 * nudge; + proj[14] = -2*neard * nudge; proj[3] = 0; proj[7] = 0; proj[11] = -1; proj[15] = 0; } -void ML_ProjectionMatrix2(float *proj, float fovx, float fovy) +void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard) { float xmin, xmax, ymin, ymax; float nudge = 1; //proj - ymax = 4 * tan( fovy * M_PI / 360.0 ); + ymax = neard * tan( fovy * M_PI / 360.0 ); ymin = -ymax; - xmax = 4 * tan( fovx * M_PI / 360.0 ); + xmax = neard * tan( fovx * M_PI / 360.0 ); xmin = -xmax; - proj[0] = (2*4) / (xmax - xmin); + proj[0] = (2*neard) / (xmax - xmin); proj[4] = 0; proj[8] = (xmax + xmin) / (xmax - xmin); proj[12] = 0; proj[1] = 0; - proj[5] = (2*4) / (ymax - ymin); + proj[5] = (2*neard) / (ymax - ymin); proj[9] = (ymax + ymin) / (ymax - ymin); proj[13] = 0; proj[2] = 0; proj[6] = 0; proj[10] = -1 * nudge; - proj[14] = -2*4 * nudge; + proj[14] = -2*neard * nudge; proj[3] = 0; proj[7] = 0; @@ -951,7 +995,31 @@ void ML_ProjectionMatrix2(float *proj, float fovx, float fovy) proj[15] = 0; } -void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1) +void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float ymin, + float znear, float zfar) +{ + proj[0] = 2/(xmax-xmin); + proj[4] = 0; + proj[8] = 0; + proj[12] = (xmax+xmin)/(xmax-xmin); + + proj[1] = 0; + proj[5] = 2/(ymax-ymin); + proj[9] = 0; + proj[13] = (ymax+ymin)/(ymax-ymin); + + proj[2] = 0; + proj[6] = 0; + proj[10] = -2/(zfar-znear); + proj[14] = (zfar+znear)/(zfar-znear); + + proj[3] = 0; + proj[7] = 0; + proj[11] = 0; + proj[15] = 1; +} + +void Matrix4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1) { // we only support uniform scaling, so assume the first row is enough // (note the lack of sqrt here, because we're trying to undo the scaling, @@ -993,17 +1061,17 @@ void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1) //screen->3d -void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy) +void Matrix4_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy) { float modelview[16]; float proj[16]; float tempm[16]; - ML_ModelViewMatrix(modelview, viewangles, vieworg); - ML_ProjectionMatrix(proj, wdivh, fovy); + Matrix4_ModelViewMatrix(modelview, viewangles, vieworg); + Matrix4_Projection(proj, wdivh, fovy, 4); Matrix4_Multiply(proj, modelview, tempm); - Matrix4x4_Invert_Simple((void*)proj, (void*)tempm); + Matrix4_Invert_Simple((void*)proj, (void*)tempm); { float v[4], tempv[4]; @@ -1023,13 +1091,13 @@ void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, floa //returns fractions of screen. //uses GL style rotations and translations and stuff. //3d -> screen (fixme: offscreen return values needed) -void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy) +void Matrix4_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy) { float modelview[16]; float proj[16]; - ML_ModelViewMatrix(modelview, viewangles, vieworg); - ML_ProjectionMatrix(proj, wdivh, fovy); + Matrix4_ModelViewMatrix(modelview, viewangles, vieworg); + Matrix4_Projection(proj, wdivh, fovy, 4); { float v[4], tempv[4]; @@ -1120,3 +1188,4 @@ void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up) VectorNormalize (right); CrossProduct (right, forward, up); } + diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index 1ea76f9dc..f8fce542f 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -114,14 +114,19 @@ typedef struct { } matrix4x4_t; //used for crosshair stuff. -void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); +void Matrix4_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); +void Matrix4_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out); void Matrix4_Multiply(float *a, float *b, float *out); void Matrix4_Transform3(float *matrix, float *vector, float *product); void Matrix4_Transform4(float *matrix, float *vector, float *product); -void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1); -void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg); -void ML_ProjectionMatrix2(float *proj, float fovx, float fovy); -void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg); +void Matrix4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1); +void Matrix4_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg); +void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard); +void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float ymin, float znear, float zfar); +void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg); +void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); +qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2); +void ClearBounds (vec3_t mins, vec3_t maxs); diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 57bdc49cb..ebd86b14c 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -533,7 +533,7 @@ dblbreak: if (strlen(s) >= sizeof(copy)-1) return false; - + strcpy (copy, s); // strip off a trailing :port if present for (colon = copy ; *colon ; colon++) diff --git a/engine/common/particles.h b/engine/common/particles.h index 6c865ea9a..3aa84bf7d 100644 --- a/engine/common/particles.h +++ b/engine/common/particles.h @@ -126,6 +126,128 @@ typedef struct beamseg_s float texture_s; } beamseg_t; + + +typedef struct skytris_s { + struct skytris_s *next; + vec3_t org; + vec3_t x; + vec3_t y; + float area; + float nexttime; + struct msurface_s *face; +} skytris_t; + +//these could be deltas or absolutes depending on ramping mode. +typedef struct { + vec3_t rgb; + float alpha; + float scale; + float rotation; +} ramp_t; +typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT } blendmode_t; +// TODO: merge in alpha with rgb to gain benefit of vector opts +typedef struct part_type_s { + char name[MAX_QPATH]; + char texname[MAX_QPATH]; + vec3_t rgb; + vec3_t rgbchange; + vec3_t rgbrand; + int colorindex; + int colorrand; + float rgbchangetime; + vec3_t rgbrandsync; + float scale, alpha; + float alphachange; + float die, randdie; + float randomvel, veladd; + float orgadd; + float offsetspread; + float offsetspreadvert; + float randomvelvert; + float randscale; + + float spawntime; + float spawnchance; + + enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; + blendmode_t blendmode; + + float rotationstartmin, rotationstartrand; + float rotationmin, rotationrand; + + float scaledelta; + float count; + float countrand; + int texturenum; +#ifdef D3DQUAKE + void *d3dtexture; +#endif + int assoc; + int cliptype; + int inwater; + float clipcount; + int emit; + float emittime; + float emitrand; + float emitstart; + + float areaspread; + float areaspreadvert; + float scalefactor; + float invscalefactor; + + float spawnparam1; + float spawnparam2; +/* float spawnparam3; */ + + float offsetup; // make this into a vec3_t later with dir, possibly for mdls + + enum { + SM_BOX, //box = even spread within the area + SM_CIRCLE, //circle = around edge of a circle + SM_BALL, //ball = filled sphere + SM_SPIRAL, //spiral = spiral trail + SM_TRACER, //tracer = tracer trail + SM_TELEBOX, //telebox = q1-style telebox + SM_LAVASPLASH, //lavasplash = q1-style lavasplash + SM_UNICIRCLE, //unicircle = uniform circle + SM_FIELD, //field = synced field (brightfield, etc) + SM_DISTBALL // uneven distributed ball + } spawnmode; + + float gravity; + vec3_t friction; + float clipbounce; + int stains; + + enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode; + int rampindexes; + ramp_t *ramp; + + int loaded; + particle_t *particles; + clippeddecal_t *clippeddecals; + beamseg_t *beams; + skytris_t *skytris; + struct part_type_s *nexttorun; + + unsigned int flags; +#define PT_VELOCITY 0x001 +#define PT_FRICTION 0x002 +#define PT_CHANGESCOLOUR 0x004 +#define PT_CITRACER 0x008 // Q1-style tracer behavior for colorindex +#define PT_INVFRAMETIME 0x010 // apply inverse frametime to count (causes emits to be per frame) +#define PT_AVERAGETRAIL 0x020 // average trail points from start to end, useful with t_lightning, etc +#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...) +#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle +#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle + unsigned int state; +#define PS_INRUNLIST 0x1 // particle type is currently in execution list +} part_type_t; + + + #define PARTICLE_Z_CLIP 8.0 #define frandom() (rand()*(1.0f/RAND_MAX)) @@ -179,8 +301,6 @@ void P_EmitSkyEffectTris(struct model_s *mod, struct msurface_s *fa); // trailstate functions void P_DelinkTrailstate(trailstate_t **tsk); -typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT } blendmode_t; - // used for callback extern cvar_t r_particlesdesc; diff --git a/engine/d3d/d3d_draw.c b/engine/d3d/d3d_draw.c new file mode 100644 index 000000000..05801e642 --- /dev/null +++ b/engine/d3d/d3d_draw.c @@ -0,0 +1,811 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3dquake.h" + +#define MAX_WIDTH 512 +#define MAX_HEIGHT 512 + +void *d3dexplosiontexture; +void *d3dballtexture; + +LPDIRECTDRAWSURFACE7 draw_chars_tex; +mpic_t *conback_tex; + +typedef struct d3dcachepic_s +{ + char name[MAX_QPATH]; + mpic_t pic; +} d3dcachepic_t; +#define MAX_CACHED_PICS 512 //a temporary solution +d3dcachepic_t d3dmenu_cachepics[MAX_CACHED_PICS]; +int d3dmenu_numcachepics; + + + +typedef struct { + float x, y, z; + int colour; + float s, t; +} d3dquadvert_t; +d3dquadvert_t d3dquadvert[4]; +index_t d3dquadindexes[6] = { + 0, 1, 2, + 0, 2, 3 +}; +//pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2, d3dstate.vertbuf, d3dstate.numverts, d3dstate.indexbuf, d3dstate.numindicies, 0); + + +static void Upload_Texture_32(LPDIRECTDRAWSURFACE7 surf, unsigned int *data, int width, int height) +{ + int x, y; + unsigned int *dest; + unsigned char swapbuf[4]; + unsigned char swapbuf2[4]; + DDSURFACEDESC2 desc; + + memset(&desc, 0, sizeof(desc)); + + surf->lpVtbl->Lock(surf, NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + + if (width == desc.dwWidth && height == desc.dwHeight) + { +// if (desc.lPitch == twidth*4) +// { +// memcpy(desc.lpSurface, data, width*height*4); +// } +// else + { + for (y = 0; y < desc.dwHeight; y++) + { + dest = (unsigned int *)((char *)desc.lpSurface + desc.lPitch*y); + for (x = 0; x < desc.dwWidth; x++) + { + *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x]; + swapbuf[0] = swapbuf2[2]; + swapbuf[2] = swapbuf2[0]; + dest[x] = *(unsigned int*)swapbuf; + } + data += width; + } + } + } + else + { + int x, y; + int iny; + unsigned int *scaled, *row, *inrow; + + for (y = 0; y < desc.dwHeight; y++) + { + row = (unsigned int*)((char *)desc.lpSurface + desc.lPitch*y); + iny = (y * height) / desc.dwHeight; + inrow = data + width*iny; + for (x = 0; x < desc.dwWidth; x++) + { + *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.dwWidth]; + swapbuf[0] = swapbuf2[2]; + swapbuf[2] = swapbuf2[0]; + row[x] = *(unsigned int*)swapbuf; + } + } + + + + //mimic opengl and draw it white +// memset(desc.lpSurface, 255, twidth*theight*4); + } + + surf->lpVtbl->Unlock(surf, NULL); +} + +void D3D_MipMap (qbyte *out, qbyte *in, int width, int height) +{ + int i, j; + + width <<=2; + height >>= 1; + for (i=0 ; i>2; + out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2; + out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2; + out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2; + } + } +} + +//create a basic shader from a 32bit image +void *D3D_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags) +{ + int x, y; + unsigned int *dest; + unsigned char swapbuf[4]; + unsigned char swapbuf2[4]; + + static unsigned char mipdata[(MAX_WIDTH/2)*(MAX_HEIGHT/2)][4]; + + + + DWORD tflags; + DWORD twidth = width; + DWORD theight = height; + D3DX_SURFACEFORMAT tformat = D3DX_SF_A8R8G8B8; + LPDIRECTDRAWSURFACE7 newsurf; + DWORD nummips; + +/* if (!(flags & TF_MANDATORY)) + { + Con_Printf("Texture upload missing flags\n"); + return NULL; + } +*/ + if (flags & TF_MIPMAP) + tflags = 0; + else + tflags = D3DX_TEXTURE_NOMIPMAP; + + D3DXCreateTexture(pD3DDev, &tflags, &twidth, &theight, &tformat, NULL, &newsurf, &nummips); + if (!newsurf) + return NULL; + + if (tformat != D3DX_SF_A8R8G8B8) + Sys_Error("Couldn't create a d3d texture with a usable texture format"); + + + Upload_Texture_32(newsurf, data, width, height); + + if (flags & TF_MIPMAP) + { + LPDIRECTDRAWSURFACE7 miptex; + LPDIRECTDRAWSURFACE7 lasttex; + DDSCAPS2 caps; + memset(&caps, 0, sizeof(caps)); + caps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; + newsurf->lpVtbl->GetAttachedSurface(newsurf, &caps, &miptex); + while (miptex) + { + D3D_MipMap(mipdata, data, width, height); + data = mipdata; + width/=2; + height/=2; + + Upload_Texture_32(miptex, mipdata, width, height); + + lasttex = miptex; + miptex->lpVtbl->GetAttachedSurface(miptex, &caps, &miptex); + lasttex->lpVtbl->Release(lasttex); + } + } + + return newsurf; +} + +//create a basic shader from an 8bit image with 24bit palette +void *D3D_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix) +{ + //just expands it to 32bpp and passes it on + static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4]; + int i; + + if (!(flags & TF_ALPHA)) + transparentpix = 256; + + if (width*height > MAX_WIDTH*MAX_HEIGHT) + Sys_Error("GL_Upload8_Pal24: too big"); + + for (i = width*height; i >= 0 ; i--) + { + out[i][0] = palette[data[i]*3+0]; + out[i][1] = palette[data[i]*3+1]; + out[i][2] = palette[data[i]*3+2]; + out[i][3] = 255*(data[i] != transparentpix); + } + + + return D3D_LoadTexture_32(name, (unsigned int*)out, width, height, flags); +} + +void *D3D_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette) +{ + //just expands it to 32bpp and passes it on + static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4]; + int i; + + if (width*height > MAX_WIDTH*MAX_HEIGHT) + Sys_Error("GL_Upload8_Pal24: too big"); + + for (i = width*height; i >= 0 ; i--) + { + out[i][0] = palette[data[i]*4+0]; + out[i][1] = palette[data[i]*4+1]; + out[i][2] = palette[data[i]*4+2]; + out[i][3] = palette[data[i]*4+3]; + } + + + return D3D_LoadTexture_32(name, (unsigned int*)out, width, height, flags); +} + + +void D3D_UnloadTexture(LPDIRECTDRAWSURFACE7 tex) +{ + tex->lpVtbl->Release(tex); +} + + + + + + + + +static qbyte exptexture[16][16] = +{ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0}, + {0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0}, + {0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0}, + {0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0}, + {0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0}, + {0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0}, + {0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0}, + {0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0}, + {0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0}, + {0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0}, + {0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0}, + {0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0}, + {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +}; +void D3D_InitParticleTexture (void) +{ +#define PARTICLETEXTURESIZE 64 + int x,y; + float dx, dy, d; + qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4]; + +//Explosion texture + + + for (x=0 ; x<16 ; x++) + { + for (y=0 ; y<16 ; y++) + { + data[y*16+x][0] = 255; + data[y*16+x][1] = 255; + data[y*16+x][2] = 255; + data[y*16+x][3] = exptexture[x][y]*255/9.0; + } + } + d3dexplosiontexture = D3D_LoadTexture_32("", (unsigned int*)data, 16, 16, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP); + + memset(data, 255, sizeof(data)); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dx*dx+dy*dy)); + d = bound(0, d, 255); + data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d; + } + } + + d3dballtexture = D3D_LoadTexture_32("", (unsigned int*)data, PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP); +} + + + + + + + + + +mpic_t *(D3D_Draw_SafePicFromWad) (char *name) +{ + LPDIRECTDRAWSURFACE7 *p; + d3dcachepic_t *pic; + qpic_t *qpic; + int i; + + for (i = 0; i < d3dmenu_numcachepics; i++) + { + if (!strcmp(d3dmenu_cachepics[i].name, name)) + return &d3dmenu_cachepics[i].pic; + } + + qpic = (qpic_t *)W_SafeGetLumpName (name); + if (!qpic) + { + return NULL; + } + + SwapPic (qpic); + + pic = &d3dmenu_cachepics[d3dmenu_numcachepics++]; + + Q_strncpyz (pic->name, name, sizeof(pic->name)); + + pic->pic.width = qpic->width; + pic->pic.height = qpic->height; + p = (LPDIRECTDRAWSURFACE7*)&pic->pic.data; + if (!strcmp(name, "conchars")) + *p = draw_chars_tex; + else + { + *p = Mod_LoadReplacementTexture(pic->name, "wad", false, true, true); + if (!*p) + *p = D3D_LoadTexture_8_Pal24(name, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255); + } + +// Con_Printf("Fixme: D3D_Draw_SafePicFromWad\n"); + return &pic->pic; +} +mpic_t *(D3D_Draw_SafeCachePic) (char *path) +{ + LPDIRECTDRAWSURFACE7 *p; + d3dcachepic_t *pic; + qpic_t *qpic; + int i; + + + for (i = 0; i < d3dmenu_numcachepics; i++) + { + if (!strcmp(d3dmenu_cachepics[i].name, path)) + return &d3dmenu_cachepics[i].pic; + } + + qpic = (qpic_t *)COM_LoadTempFile (path); + if (!qpic) + { + return NULL; + } + + SwapPic (qpic); + + pic = &d3dmenu_cachepics[d3dmenu_numcachepics++]; + + Q_strncpyz (pic->name, path, sizeof(pic->name)); + + pic->pic.width = qpic->width; + pic->pic.height = qpic->height; + p = (LPDIRECTDRAWSURFACE7*)&pic->pic.data; + *p = Mod_LoadReplacementTexture(pic->name, "gfx", false, true, true); + if (!*p) + *p = D3D_LoadTexture_8_Pal24(path, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255); + +// Con_Printf("Fixme: D3D_Draw_SafeCachePic\n"); + return &pic->pic; +} +mpic_t *(D3D_Draw_CachePic) (char *path) +{ + mpic_t *pic; + pic = D3D_Draw_SafeCachePic(path); + if (!pic) + Sys_Error("Couldn't load picture %s", path); + return pic; +} +void (D3D_Draw_ReInit) (void) +{ + d3dmenu_numcachepics = 0; + + draw_chars = W_SafeGetLumpName ("conchars"); + + draw_chars_tex = Mod_LoadReplacementTexture("conchars", "gfx", false, true, true); + if (!draw_chars_tex) + draw_chars_tex = D3D_LoadTexture_8_Pal24("conchars", draw_chars, 128, 128, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 0); + + + //now emit the conchars picture as if from a wad. + strcpy(d3dmenu_cachepics[d3dmenu_numcachepics].name, "conchars"); + d3dmenu_cachepics[d3dmenu_numcachepics].pic.width = 128; + d3dmenu_cachepics[d3dmenu_numcachepics].pic.height = 128; + *(int *)&d3dmenu_cachepics[d3dmenu_numcachepics].pic.data = draw_chars_tex; + d3dmenu_numcachepics++; + + + conback_tex = D3D_Draw_SafeCachePic("gfx/conback.lmp"); + + + Plug_DrawReloadImages(); + D3D_InitParticleTexture(); +} +void (D3D_Draw_Init) (void) +{ + D3D_Draw_ReInit(); +} +void (D3D_Draw_Character) (int x, int y, unsigned int num) +{ + int row; + int col; + float frow, fcol, size; + +#define char_instep 0 + num &= 255; + if (num == ' ') + return; + + row = num>>4; + col = num&15; + + frow = row*0.0625+char_instep; + fcol = col*0.0625+char_instep; + size = 0.0625-char_instep*2; + + d3dquadvert[0].x = x; + d3dquadvert[0].y = y; + d3dquadvert[0].z = 0; + d3dquadvert[0].colour = 0xffffffff; + d3dquadvert[0].s = fcol; + d3dquadvert[0].t = frow; + + d3dquadvert[1].x = x+8; + d3dquadvert[1].y = y; + d3dquadvert[1].z = 0; + d3dquadvert[1].colour = 0xffffffff; + d3dquadvert[1].s = fcol+size; + d3dquadvert[1].t = frow; + + d3dquadvert[2].x = x+8; + d3dquadvert[2].y = y+8; + d3dquadvert[2].z = 0; + d3dquadvert[2].colour = 0xffffffff; + d3dquadvert[2].s = fcol+size; + d3dquadvert[2].t = frow+size; + + d3dquadvert[3].x = x; + d3dquadvert[3].y = y+8; + d3dquadvert[3].z = 0; + d3dquadvert[3].colour = 0xffffffff; + d3dquadvert[3].s = fcol; + d3dquadvert[3].t = frow+size; + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, draw_chars_tex); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0); + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0); +} + +void (D3D_Draw_ColouredCharacter) (int x, int y, unsigned int num) +{ + int row; + int col; + float frow, fcol, size; + unsigned int imgcolour; + unsigned char *c = (unsigned char *)&imgcolour; + +#define char_instep 0 + + if (num&0xffff == ' ') + return; + + col = (num & CON_FGMASK) >> CON_FGSHIFT; + c[0] = consolecolours[col].fb*255; + c[1] = consolecolours[col].fg*255; + c[2] = consolecolours[col].fr*255; + c[3] = (num & CON_HALFALPHA)?128:255; + + + num &= 0xff; + row = num>>4; + col = num&15; + + frow = row*0.0625+char_instep; + fcol = col*0.0625+char_instep; + size = 0.0625-char_instep*2; + + d3dquadvert[0].x = x; + d3dquadvert[0].y = y; + d3dquadvert[0].z = 0; + d3dquadvert[0].colour = imgcolour; + d3dquadvert[0].s = fcol; + d3dquadvert[0].t = frow; + + d3dquadvert[1].x = x+8; + d3dquadvert[1].y = y; + d3dquadvert[1].z = 0; + d3dquadvert[1].colour = imgcolour; + d3dquadvert[1].s = fcol+size; + d3dquadvert[1].t = frow; + + d3dquadvert[2].x = x+8; + d3dquadvert[2].y = y+8; + d3dquadvert[2].z = 0; + d3dquadvert[2].colour = imgcolour; + d3dquadvert[2].s = fcol+size; + d3dquadvert[2].t = frow+size; + + d3dquadvert[3].x = x; + d3dquadvert[3].y = y+8; + d3dquadvert[3].z = 0; + d3dquadvert[3].colour = imgcolour; + d3dquadvert[3].s = fcol; + d3dquadvert[3].t = frow+size; + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, draw_chars_tex); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0); + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0); +} +void (D3D_Draw_String) (int x, int y, const qbyte *str) +{ + while(*str) + { + D3D_Draw_Character(x, y, *str++); + x+=8; + } +} +void (D3D_Draw_Alt_String) (int x, int y, const qbyte *str) +{ + while(*str) + { + D3D_Draw_Character(x, y, *str++ | 128); + x+=8; + } +} +void (D3D_Draw_Crosshair) (void) +{ + D3D_Draw_Character(vid.width/2 - 4, vid.height/2 - 4, '+'); +} +void (D3D_Draw_DebugChar) (qbyte num) +{ + Sys_Error("D3D function not implemented\n"); +} +void (D3D_Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation) +{ +// Sys_Error("D3D function not implemented\n"); +} +void (D3D_Draw_TileClear) (int x, int y, int w, int h) +{ +// Sys_Error("D3D function not implemented\n"); +} +void (D3D_Draw_Fill_I) (int x, int y, int w, int h, unsigned int imgcolour) +{ + d3dquadvert[0].x = x; + d3dquadvert[0].y = y; + d3dquadvert[0].z = 0; + d3dquadvert[0].colour = imgcolour; + d3dquadvert[0].s = 0; + d3dquadvert[0].t = 0; + + d3dquadvert[1].x = x+w; + d3dquadvert[1].y = y; + d3dquadvert[1].z = 0; + d3dquadvert[1].colour = imgcolour; + d3dquadvert[1].s = 0; + d3dquadvert[1].t = 0; + + d3dquadvert[2].x = x+w; + d3dquadvert[2].y = y+h; + d3dquadvert[2].z = 0; + d3dquadvert[2].colour = imgcolour; + d3dquadvert[2].s = 0; + d3dquadvert[2].t = 0; + + d3dquadvert[3].x = x; + d3dquadvert[3].y = y+h; + d3dquadvert[3].z = 0; + d3dquadvert[3].colour = imgcolour; + d3dquadvert[3].s = 0; + d3dquadvert[3].t = 0; + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +} + +void (D3D_Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b) +{ + char colours[4]; + colours[0] = b*255; + colours[1] = g*255; + colours[2] = r*255; + colours[3] = 255; + + D3D_Draw_Fill_I(x, y, w, h, *(unsigned int*)colours); +} + +void (D3D_Draw_Fill) (int x, int y, int w, int h, int c) +{ + D3D_Draw_FillRGB(x, y, w, h, host_basepal[c*3+0]/255.0f, host_basepal[c*3+1]/255.0f, host_basepal[c*3+2]/255.0f); +} +void (D3D_Draw_FadeScreen) (void) +{ +// Sys_Error("D3D function not implemented\n"); +} +void (D3D_Draw_BeginDisc) (void) +{ +// Sys_Error("D3D function not implemented\n"); +} +void (D3D_Draw_EndDisc) (void) +{ +// Sys_Error("D3D function not implemented\n"); +} + +static int imgcolour; + +void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h) +{ + D3D_Draw_Fill_I(x, y, w, h, imgcolour); +} + +void (D3D_Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic) +{ + LPDIRECTDRAWSURFACE7 *p; + if (!conback_tex) + return; + if (!pic) + return; + + d3dquadvert[0].x = x; + d3dquadvert[0].y = y; + d3dquadvert[0].z = 0; + d3dquadvert[0].colour = imgcolour; + d3dquadvert[0].s = s1;// - 3.0/pic->width; + d3dquadvert[0].t = t1; + + d3dquadvert[1].x = x+w; + d3dquadvert[1].y = y; + d3dquadvert[1].z = 0; + d3dquadvert[1].colour = imgcolour; + d3dquadvert[1].s = s2;// - 3.0/pic->width; + d3dquadvert[1].t = t1; + + d3dquadvert[2].x = x+w; + d3dquadvert[2].y = y+h; + d3dquadvert[2].z = 0; + d3dquadvert[2].colour = imgcolour; + d3dquadvert[2].s = s2;// - 3.0/pic->width; + d3dquadvert[2].t = t2; + + d3dquadvert[3].x = x; + d3dquadvert[3].y = y+h; + d3dquadvert[3].z = 0; + d3dquadvert[3].colour = imgcolour; + d3dquadvert[3].s = s1;// - 3.0/pic->width; + d3dquadvert[3].t = t2; + + p = (LPDIRECTDRAWSURFACE7*)&pic->data; + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, *p); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0); + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0); +} + +void (D3D_Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic) +{ + D3D_Draw_Image(x, y, width, height, 0, 0, 1, 1, pic); +} +void (D3D_Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height) +{ + float s, t; + float sw, tw; + if (!pic) + return; + + s = (float)srcx/pic->width; + t = (float)srcy/pic->height; + sw = (float)width/pic->width; + tw = (float)height/pic->height; + D3D_Draw_Image(x, y, width, height, s, t, s+sw, t+tw, pic); +} +void (D3D_Draw_TransPic) (int x, int y, mpic_t *pic) +{ + if (!pic) + return; + D3D_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic); +} +void (D3D_Draw_Pic) (int x, int y, mpic_t *pic) +{ + if (!pic) + return; + D3D_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic); +} +void (D3D_Draw_ImageColours) (float r, float g, float b, float a) +{ + unsigned char *c = (unsigned char *)&imgcolour; + + c[0] = b*255; + c[1] = g*255; + c[2] = r*255; + c[3] = a*255; +} + +void (D3D_Draw_ConsoleBackground) (int lines) +{ + D3D_Draw_ImageColours(1,1,1,1); + D3D_Draw_Image(0, 0, vid.width, lines, 0, 1 - (float)lines/vid.height, 1, 1, conback_tex); +} +void (D3D_Draw_EditorBackground) (int lines) +{ + D3D_Draw_ConsoleBackground(lines); +} + + + + +void (D3D_Media_ShowFrameBGR_24_Flip) (qbyte *framedata, int inwidth, int inheight) +{ + mpic_t pic; + LPDIRECTDRAWSURFACE7 *p; + p = (LPDIRECTDRAWSURFACE7*)&pic.data; + *p = D3D_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP); + + D3D_Set2D (); + D3D_Draw_ImageColours(1,1,1,1); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + D3D_UnloadTexture(*p); +} //input is bottom up... +void (D3D_Media_ShowFrameRGBA_32) (qbyte *framedata, int inwidth, int inheight) +{ + mpic_t pic; + LPDIRECTDRAWSURFACE7 *p; + + pic.width = inwidth; + pic.height = inheight; + pic.flags = 0; + p = (LPDIRECTDRAWSURFACE7*)&pic.data; + *p = D3D_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP); + + D3D_Set2D (); + D3D_Draw_ImageColours(1,1,1,1); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + D3D_UnloadTexture(*p); +} //top down +void (D3D_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette) +{ + mpic_t pic; + LPDIRECTDRAWSURFACE7 *p; + p = (LPDIRECTDRAWSURFACE7*)&pic.data; + *p = D3D_LoadTexture_8_Pal24("", (unsigned char*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP, palette, 256); + + D3D_Set2D (); + D3D_Draw_ImageColours(1,1,1,1); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + D3D_UnloadTexture(*p); +} //paletted topdown (framedata is 8bit indexes into palette) +#endif diff --git a/engine/d3d/d3d_mesh.c b/engine/d3d/d3d_mesh.c new file mode 100644 index 000000000..cdc00eb87 --- /dev/null +++ b/engine/d3d/d3d_mesh.c @@ -0,0 +1,696 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3dquake.h" + +#include "com_mesh.h" + +extern cvar_t r_fullbrightSkins; +extern cvar_t r_vertexdlights; + + +typedef struct { + float x, y, z; + float s, t; +} meshvert_t; + +typedef struct { + float x, y, z; + unsigned int colour; + float s, t; +} meshcolouredvert_t; + +void D3D_DrawMesh(mesh_t *mesh) +{ + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + { + int v; + vec3_t *xyz; + byte_vec4_t *colour; + vec2_t *wm; + xyz = mesh->xyz_array; + wm = mesh->st_array; + colour = mesh->colors_array; + + if (colour) + { + meshcolouredvert_t *meshvert = alloca(sizeof(meshcolouredvert_t)*mesh->numvertexes); + + for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++, colour++) + { + meshvert[v].x = (*xyz)[0]; + meshvert[v].y = (*xyz)[1]; + meshvert[v].z = (*xyz)[2]; + meshvert[v].colour = *(unsigned int*)colour; + meshvert[v].s = (*wm)[0]; + meshvert[v].t = (*wm)[1]; + } + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, meshvert, mesh->numvertexes, mesh->indexes, mesh->numindexes, 0); + } + else + { + meshvert_t *meshvert = alloca(sizeof(meshvert_t)*mesh->numvertexes); + + for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++) + { + meshvert[v].x = (*xyz)[0]; + meshvert[v].y = (*xyz)[1]; + meshvert[v].z = (*xyz)[2]; + meshvert[v].s = (*wm)[0]; + meshvert[v].t = (*wm)[1]; + } + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, meshvert, mesh->numvertexes, mesh->indexes, mesh->numindexes, 0); + } + } +} + + + + +hashtable_t skincolourmapped; + +void d3d_GAliasFlushSkinCache(void) +{ + int i; + bucket_t *b; + for (i = 0; i < skincolourmapped.numbuckets; i++) + { + while((b = skincolourmapped.bucket[i])) + { + skincolourmapped.bucket[i] = b->next; + BZ_Free(b->data); + } + } + if (skincolourmapped.bucket) + BZ_Free(skincolourmapped.bucket); + skincolourmapped.bucket = NULL; + skincolourmapped.numbuckets = 0; +} + +static galiastexnum_t *D3D_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e) +{ + galiasskin_t *skins; + galiastexnum_t *texnums; + int frame; + + int tc, bc; + int local; + + if (!gl_nocolors.value) + { + if (e->scoreboard) + { + if (!e->scoreboard->skin) + Skin_Find(e->scoreboard); + tc = e->scoreboard->topcolor; + bc = e->scoreboard->bottomcolor; + + //colour forcing + if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen. + { + if (cl.teamplay && cl.spectator) + { + local = Cam_TrackNum(0); + if (local < 0) + local = cl.playernum[0]; + } + else + local = cl.playernum[0]; + if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[local].team)) + { + if (cl_teamtopcolor>=0) + tc = cl_teamtopcolor; + if (cl_teambottomcolor>=0) + bc = cl_teambottomcolor; + } + else + { + if (cl_enemytopcolor>=0) + tc = cl_enemytopcolor; + if (cl_enemybottomcolor>=0) + bc = cl_enemybottomcolor; + } + } + } + else + { + tc = 1; + bc = 1; + } + + if (tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin)) + { + int inwidth, inheight; + int tinwidth, tinheight; + char *skinname; + qbyte *original; + int cc; + galiascolourmapped_t *cm; + char hashname[512]; + cc = (tc<<4)|bc; + + if (e->scoreboard && e->scoreboard->skin && !gl_nocolors.value) + { + snprintf(hashname, sizeof(hashname), "%s$%s$%i", modelname, e->scoreboard->skin->name, surfnum); + skinname = hashname; + } + else if (surfnum) + { + snprintf(hashname, sizeof(hashname), "%s$%i", modelname, surfnum); + skinname = hashname; + } + else + skinname = modelname; + + if (!skincolourmapped.numbuckets) + Hash_InitTable(&skincolourmapped, 256, BZ_Malloc(Hash_BytesForBuckets(256))); + + for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm)) + { + if (cm->colour == cc && cm->skinnum == e->skinnum) + { + return &cm->texnum; + } + } + + if (!inf->numskins) + { + skins = NULL; + texnums = NULL; + } + else + { + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (!skins->texnums) + { + skins = NULL; + texnums = NULL; + } + else + { + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums); + } + } + + //colourmap isn't present yet. + cm = BZ_Malloc(sizeof(*cm)); + Q_strncpyz(cm->name, skinname, sizeof(cm->name)); + Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket); + cm->colour = cc; + cm->skinnum = e->skinnum; + cm->texnum.fullbright = 0; + cm->texnum.base = 0; + + if (!texnums) + { //load just the skin (q2) +/* if (e->scoreboard && e->scoreboard->skin) + { + if (cls.protocol == CP_QUAKE2) + { + original = Skin_Cache32(e->scoreboard->skin); + if (original) + { + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, true, false); + return &cm->texnum; + } + } + else + { + original = Skin_Cache8(e->scoreboard->skin); + if (original) + { + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, true, false); + return &cm->texnum; + } + } + + cm->texnum.base = Mod_LoadHiResTexture(e->scoreboard->skin->name, "skins", true, false, true); + return &cm->texnum; + } +*/ + return NULL; + } + + cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping + if (cls.protocol != CP_QUAKE2 && ((!texnums || !strcmp(modelname, "progs/player.mdl")) && e->scoreboard && e->scoreboard->skin)) + { + original = Skin_Cache8(e->scoreboard->skin); + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + } + else + { + original = NULL; + inwidth = 0; + inheight = 0; + } + if (!original) + { + if (skins->ofstexels) + { + original = (qbyte *)skins + skins->ofstexels; + inwidth = skins->skinwidth; + inheight = skins->skinheight; + } + else + { + original = NULL; + inwidth = 0; + inheight = 0; + } + } + tinwidth = skins->skinwidth; + tinheight = skins->skinheight; + if (original) + { + int i, j; + qbyte translate[256]; + unsigned translate32[256]; + static unsigned pixels[512*512]; + unsigned *out; + unsigned frac, fracstep; + + unsigned scaled_width, scaled_height; + qbyte *inrow; + + texnums = &cm->texnum; + + texnums->base = 0; + texnums->fullbright = 0; + + if (gl_max_size.value <= 0) + gl_max_size.value = 512; + + scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512; + scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512; + + for (i=0 ; i<256 ; i++) + translate[i] = i; + + tc<<=4; + bc<<=4; + + for (i=0 ; i<16 ; i++) + { + if (tc < 128) // the artists made some backwards ranges. sigh. + translate[TOP_RANGE+i] = tc+i; + else + translate[TOP_RANGE+i] = tc+15-i; + + if (bc < 128) + translate[BOTTOM_RANGE+i] = bc+i; + else + translate[BOTTOM_RANGE+i] = bc+15-i; + } + + + for (i=0 ; i<256 ; i++) + translate32[i] = d_8to24rgbtable[translate[i]]; + + out = pixels; + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i> 1; + for (j=0 ; j>16]] | 0xff000000; + frac += fracstep; + out[j+1] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + out[j+2] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + out[j+3] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + } + } + texnums->base = D3D_LoadTexture_32 ("", pixels, scaled_width, scaled_height, 0); +/* texnums->base = texture_extension_number++; + GL_Bind(texnums->base); + qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +*/ + + //now do the fullbrights. + out = pixels; + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i> 1; + for (j=0 ; j>16] < 255-vid.fullbright) + ((char *) (&out[j]))[3] = 0; //alpha 0 + frac += fracstep; + } + } +/* texnums->fullbright = texture_extension_number++; + GL_Bind(texnums->fullbright); + qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +*/ + } + else + { + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + + if (!inf->numskins || !skins->texnums) + return NULL; + + frame = cl.time*skins->skinspeed; + frame = frame%skins->texnums; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + memcpy(&cm->texnum, texnums, sizeof(cm->texnum)); + } + return &cm->texnum; + } + } + + if (!inf->numskins) + return NULL; + + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + else + { + Con_DPrintf("Skin number out of range\n"); + if (!inf->numskins) + return NULL; + } + + if (!skins->texnums) + return NULL; + + frame = cl.time*skins->skinspeed; + frame = frame%skins->texnums; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + + return texnums; +} + + +extern vec3_t shadevector; +extern vec3_t ambientlight; +extern vec3_t shadelight; + +static void LotsOfLightDirectionHacks(entity_t *e, model_t *m, vec3_t lightaxis[3]) +{ + int i; + vec3_t dist; + float add; + qboolean nolightdir; + vec3_t lightdir; + + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + { + if (e->flags & Q2RF_WEAPONMODEL) + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir); + else + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir); + } + else + { + ambientlight[0] = ambientlight[1] = ambientlight[2] = shadelight[0] = shadelight[1] = shadelight[2] = 255; + lightdir[0] = 0; + lightdir[1] = 1; + lightdir[2] = 1; + } + + if (!r_vertexdlights.value) + { + for (i=0 ; iorigin, + cl_dlights[i].origin, + dist); + add = cl_dlights[i].radius - Length(dist); + + if (add > 0) { + add*=5; + ambientlight[0] += add * cl_dlights[i].color[0]; + ambientlight[1] += add * cl_dlights[i].color[1]; + ambientlight[2] += add * cl_dlights[i].color[2]; + //ZOID models should be affected by dlights as well + shadelight[0] += add * cl_dlights[i].color[0]; + shadelight[1] += add * cl_dlights[i].color[1]; + shadelight[2] += add * cl_dlights[i].color[2]; + } + } + } + } + else + { + } + + for (i = 0; i < 3; i++) //clamp light so it doesn't get vulgar. + { + if (ambientlight[i] > 128) + ambientlight[i] = 128; + if (ambientlight[i] + shadelight[i] > 192) + shadelight[i] = 192 - ambientlight[i]; + } + + if (e->flags & Q2RF_WEAPONMODEL) + { + for (i = 0; i < 3; i++) + { + if (ambientlight[i] < 24) + ambientlight[i] = shadelight[i] = 24; + } + } + +//MORE HUGE HACKS! WHEN WILL THEY CEASE! + // clamp lighting so it doesn't overbright as much + // ZOID: never allow players to go totally black + nolightdir = false; + if (m->engineflags & MDLF_PLAYER) + { + float fb = r_fullbrightSkins.value; + if (fb > cls.allow_fbskins) + fb = cls.allow_fbskins; + if (fb < 0) + fb = 0; + if (fb) + { + extern cvar_t r_fb_models; + + if (fb >= 1 && r_fb_models.value) + { + ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; + shadelight[0] = shadelight[1] = shadelight[2] = 4096; + nolightdir = true; + } + else + { + for (i = 0; i < 3; i++) + { + ambientlight[i] = max(ambientlight[i], 8 + fb * 120); + shadelight[i] = max(shadelight[i], 8 + fb * 120); + } + } + } + for (i = 0; i < 3; i++) + { + if (ambientlight[i] < 8) + ambientlight[i] = shadelight[i] = 8; + } + } + if (m->engineflags & MDLF_FLAME) + { + shadelight[0] = shadelight[1] = shadelight[2] = 4096; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; + nolightdir = true; + } + else + { + for (i = 0; i < 3; i++) + { + if (ambientlight[i] > 128) + ambientlight[i] = 128; + + shadelight[i] /= 200.0/255; + ambientlight[i] /= 200.0/255; + } + } + + if ((e->drawflags & MLS_MASKIN) == MLS_ABSLIGHT) + { + shadelight[0] = shadelight[1] = shadelight[2] = e->abslight; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + } + if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) + { + shadelight[0] = shadelight[1] = shadelight[2] = 255; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + nolightdir = true; + } + +//#define SHOWLIGHTDIR + { //lightdir is absolute, shadevector is relative + shadevector[0] = DotProduct(lightdir, e->axis[0]); + shadevector[1] = DotProduct(lightdir, e->axis[1]); + shadevector[2] = DotProduct(lightdir, e->axis[2]); + + if (e->flags & Q2RF_WEAPONMODEL) + { + vec3_t temp; + temp[0] = DotProduct(shadevector, vpn); + temp[1] = DotProduct(shadevector, vright); + temp[2] = DotProduct(shadevector, vup); + + VectorCopy(temp, shadevector); + } + + VectorNormalize(shadevector); + + VectorCopy(shadevector, lightaxis[2]); + VectorVectors(lightaxis[2], lightaxis[1], lightaxis[0]); + VectorInverse(lightaxis[1]); + } + + if (e->flags & Q2RF_GLOW) + { + shadelight[0] += sin(cl.time)*0.25; + shadelight[1] += sin(cl.time)*0.25; + shadelight[2] += sin(cl.time)*0.25; + } + + //d3d is bgra + //ogl is rgba + //so switch em and use the gl code + add = shadelight[0]; + shadelight[0] = shadelight[2]; + shadelight[2] = add; + + add = ambientlight[0]; + ambientlight[0] = ambientlight[2]; + ambientlight[2] = add; +} + + +qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int frame2, float lerp, float alpha, float fg1time, float fg2time, qboolean nolightdir); +//draws currententity +void D3D_DrawAliasModel(void) +{ + mesh_t mesh; + extern entity_t *currententity; + entity_t *e = currententity; + galiasinfo_t *inf; + model_t *m; + galiastexnum_t *skin; + int i; + + if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL) + return; + + { + extern int cl_playerindex; + if (e->scoreboard && e->model == cl.model_precache[cl_playerindex]) + { + m = e->scoreboard->model; + if (!m || m->type != mod_alias) + m = e->model; + } + else + m = e->model; + } + + if (!(e->flags & Q2RF_WEAPONMODEL)) + if (R_CullEntityBox (e, m->mins, m->maxs)) + return; + + + inf = GLMod_Extradata (m); + + if (!inf) + return; + + + LotsOfLightDirectionHacks(e, m, mesh.lightaxis); + + + { + float matrix[16]; + + if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0) + { //view weapons need to be rotated onto the screen first + float view[16]; + float ent[16]; + Matrix4_ModelMatrixFromAxis(view, cl.viewent[r_refdef.currentplayernum].axis[0], cl.viewent[r_refdef.currentplayernum].axis[1], cl.viewent[r_refdef.currentplayernum].axis[2], cl.viewent[r_refdef.currentplayernum].origin); + Matrix4_ModelMatrixFromAxis(ent, e->axis[0], e->axis[1], e->axis[2], e->origin); + Matrix4_Multiply(view, ent, matrix); + } + else + { + Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); + } + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix); + } + +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + +if (e->flags & Q2RF_DEPTHHACK) +{ //apply the depth hack to stop things from poking into walls. + //(basically moving it closer to the screen) + D3DVIEWPORT7 viewport; + pD3DDev->lpVtbl->GetViewport(pD3DDev, &viewport); + viewport.dvMinZ = 0; + viewport.dvMaxZ = 0.3; + pD3DDev->lpVtbl->SetViewport(pD3DDev, &viewport); +} + + for(i = 0;; i++) + { + R_GAliasBuildMesh(&mesh, inf, e->frame, e->oldframe, e->lerpfrac, e->shaderRGBAf[3], e->frame1time, e->frame2time, 0); + + skin = D3D_ChooseSkin(inf, m->name, e->skinnum, e); + if (!skin) + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL); + else + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, skin->base); + D3D_DrawMesh(&mesh); + + if (inf->nextsurf == 0) + break; + inf = (galiasinfo_t*)((char*)inf + inf->nextsurf); + } + +if (e->flags & Q2RF_DEPTHHACK) +{ + D3DVIEWPORT7 viewport; + pD3DDev->lpVtbl->GetViewport(pD3DDev, &viewport); + viewport.dvMinZ = 0; + viewport.dvMaxZ = 1; + pD3DDev->lpVtbl->SetViewport(pD3DDev, &viewport); +} + + { + float matrix[16]; + Matrix4_Identity(matrix); + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix); + } +} +#endif diff --git a/engine/d3d/d3d_rmain.c b/engine/d3d/d3d_rmain.c new file mode 100644 index 000000000..466117efb --- /dev/null +++ b/engine/d3d/d3d_rmain.c @@ -0,0 +1,964 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3dquake.h" + +mleaf_t *r_viewleaf, *r_oldviewleaf; +mleaf_t *r_viewleaf2, *r_oldviewleaf2; +int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; +extern qbyte areabits[MAX_Q2MAP_AREAS/8]; + + +int r_visframecount; +entity_t r_worldentity; +refdef_t r_refdef; +vec3_t r_origin, vpn, vright, vup; +extern float r_projection_matrix[16]; +extern float r_view_matrix[16]; + + +//mplane_t frustum[4]; + +vec3_t modelorg; + +entity_t *currententity; +extern cvar_t gl_mindist; + + +void (D3D_R_DeInit) (void) +{ +} +void (D3D_R_ReInit) (void) +{ +} +void (D3D_R_Init) (void) +{ + D3D_R_ReInit(); +} + +//most of this is a direct copy from gl +void (D3D_SetupFrame) (void) +{ + mleaf_t *leaf; + vec3_t temp; + + GLR_AnimateLight(); + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + VectorCopy (r_refdef.vieworg, r_origin); + r_framecount++; + + r_oldviewleaf = r_viewleaf; + r_oldviewleaf2 = r_viewleaf2; + r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + + if (!r_viewleaf) + { + } + else if (r_viewleaf->contents == Q1CONTENTS_EMPTY) + { //look down a bit + VectorCopy (r_origin, temp); + temp[2] -= 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA) + { //in water, look up a bit. + + VectorCopy (r_origin, temp); + temp[2] += 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents == Q1CONTENTS_EMPTY) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else + r_viewleaf2 = NULL; + + if (r_viewleaf) + V_SetContentsColor (r_viewleaf->contents); +} + +void D3D_SetupViewPort(void) +{ + float screenaspect; + int glwidth = vid.width, glheight=vid.height; + int x, x2, y2, y, w, h; + + float fov_x, fov_y; + + D3DVIEWPORT7 vport; + + D3D_GetBufferSize(&glwidth, &glheight); + + // + // set up viewpoint + // + x = r_refdef.vrect.x * glwidth/(int)vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width; + y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height; + y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height; + + // fudge around because of frac screen scale + if (x > 0) + x--; + if (x2 < glwidth) + x2++; + if (y < 0) + y--; + if (y2 < glheight) + y2++; + + w = x2 - x; + h = y2 - y; + +/* if (envmap) + { + x = y2 = 0; + w = h = 256; + } +*/ + + vport.dwX = x; + vport.dwY = y; + vport.dwWidth = w; + vport.dwHeight = h; + vport.dvMinZ = 0; + vport.dvMaxZ = 1; + pD3DDev->lpVtbl->SetViewport(pD3DDev, &vport); + + fov_x = r_refdef.fov_x;//+sin(cl.time)*5; + fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; + + if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER) + { + fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + } + + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; +// if (r_refdef.useperspective) + { +/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp) + { + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; + // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; + // MYgluPerspective (yfov, screenaspect, 4, 4096); + MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value); + } + else*/ + { + GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value); + } + } +/* else + { + if (gl_maxdist.value>=1) + GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value); + else + GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999); + }*/ + + Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg); + + + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX*)r_projection_matrix); + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX*)r_view_matrix); + + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE); +} + + + + + + +qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer); + + + +//fixme: direct copy from gl (apart from lightmaps) +static void D3D7_RecursiveWorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int shift; + +start: + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = r_framecount; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + D3D7_RecursiveWorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + shift = 0;//GLR_LightmapShift(cl.worldmodel); + +// if (dot < 0 -BACKFACE_EPSILON) +// side = SURF_PLANEBACK; +// else if (dot > BACKFACE_EPSILON) +// side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + +// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) +// continue; // wrong side + + D3DR_RenderDynamicLightmaps (surf, shift); + // if sorting by texture, just store it out +/* if (surf->flags & SURF_DRAWALPHA) + { // add to the translucent chain + surf->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = surf; + surf->ownerent = &r_worldentity; + } + else +*/ { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + +// recurse down the back side +// GLR_RecursiveWorldNode (node->children[!side]); + node = node->children[!side]; + goto start; +} + +struct { + float x, y, z; +// unsigned colour; + float wms, wmt; + float lms, lmt; +} worldvert[64]; +void D3D_DrawTextureChains(void) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + int lmnum; + extern int skytexturenum; // index in cl.loadmodel, not gl texture object + + if (skytexturenum>=0) + { + t = currentmodel->textures[skytexturenum]; + if (t) + { + s = t->texturechain; + if (s) + { + t->texturechain = NULL; + D3D7_DrawSkyChain (s); + } + } + } + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + for (i = 0; i < currentmodel->numtextures; i++) + { + t = currentmodel->textures[i]; + if (!t) + continue; //happens on e1m2 + s = t->texturechain; + if (!s) + continue; + t->texturechain = NULL; + +pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0); + +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); +pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + while(s) + { + m = s->mesh; + if (m) + { + + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { + if (lightmap[lmnum]->modified) + { + DDSURFACEDESC2 desc; + + desc.dwSize = sizeof(desc); + lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL); + + lightmap[lmnum]->modified = false; + } + + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + +//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + s = s->texturechain; + } + } + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); +} + +void D3D_BaseBModelTextures(entity_t *e) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + float matrix[16]; + int lmnum = -1; + currentmodel = e->model; + + + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + { + m = s->mesh; + if (m) + D3DR_RenderDynamicLightmaps (s, 0); + } + } + + + + Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum); + pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[s->lightmaptexturenum]); + { + m = s->mesh; + if (m) + { + + if (lmnum != s->lightmaptexturenum) + { + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { + if (lightmap[lmnum]->modified) + { + DDSURFACEDESC2 desc; + + desc.dwSize = sizeof(desc); + lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL); + + lightmap[lmnum]->modified = false; + } + + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + } + + + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + } + } + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix); +} + + + +typedef struct { + float pos[3]; + int colour; + float tc[2]; +} d3dvert_t; +/* +================ +R_GetSpriteFrame +================ +*/ +/* +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = currententity->model->cache.data; + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else if (psprite->frames[frame].type == SPR_ANGLED) + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7]; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = currententity->frame1time; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} +*/ +static void D3D_DrawSpriteModel (entity_t *e) +{ + vec3_t point; + mspriteframe_t *frame; + vec3_t forward, right, up; + msprite_t *psprite; + qbyte coloursb[4]; + + d3dvert_t d3dvert[4]; + index_t vertindexes[6] = { + 0, 1, 2, + 0, 2, 3 + }; + + if (!e->model) + return; + + if (e->flags & RF_NODEPTHTEST) + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS); + + // don't even bother culling, because it's just a single + // polygon without a surface cache + frame = R_GetSpriteFrame (e); + psprite = e->model->cache.data; +// frame = 0x05b94140; + + switch(psprite->type) + { + case SPR_ORIENTED: + // bullet marks on walls + AngleVectors (e->angles, forward, right, up); + break; + + case SPR_FACING_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + right[0] = e->origin[1] - r_origin[1]; + right[1] = -(e->origin[0] - r_origin[0]); + right[2] = 0; + VectorNormalize (right); + break; + case SPR_VP_PARALLEL_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + VectorCopy (vright, right); + break; + + default: + case SPR_VP_PARALLEL: + //normal sprite + VectorCopy(vup, up); + VectorCopy(vright, right); + break; + } + up[0]*=e->scale; + up[1]*=e->scale; + up[2]*=e->scale; + right[0]*=e->scale; + right[1]*=e->scale; + right[2]*=e->scale; + + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)frame->gl_texturenum); + +/* { + extern int gldepthfunc; + qglDepthFunc(gldepthfunc); + qglDepthMask(0); + if (gldepthmin == 0.5) + qglCullFace ( GL_BACK ); + else + qglCullFace ( GL_FRONT ); + + GL_TexEnv(GL_MODULATE); + + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_ALPHA_TEST); + qglDisable(GL_BLEND); + }*/ + +/* if (e->flags & Q2RF_ADDATIVE) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + qglEnable (GL_ALPHA_TEST); +*/ + + d3dvert[0].colour = 0xffffffff; + d3dvert[0].tc[0] = 0; + d3dvert[0].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->left, right, d3dvert[0].pos); + + d3dvert[1].colour = 0xffffffff; + d3dvert[1].tc[0] = 0; + d3dvert[1].tc[0] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->left, right, d3dvert[1].pos); + + d3dvert[2].colour = 0xffffffff; + d3dvert[2].tc[0] = 1; + d3dvert[2].tc[1] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->right, right, d3dvert[2].pos); + + d3dvert[3].colour = 0xffffffff; + d3dvert[3].tc[0] = 1; + d3dvert[3].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->right, right, d3dvert[3].pos); + + + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLEFAN, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dvert, 4, vertindexes, 6, 0); + + + if (e->flags & RF_NODEPTHTEST) + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); + +// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! +// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +//================================================================================== + +void D3DR_DrawSprite(void *e, void *parm) +{ + currententity = e; + + D3D_DrawSpriteModel (currententity); + +// P_FlushRenderer(); +} + + + +qboolean D3D_ShouldDraw(void) +{ + { + if (currententity->flags & Q2RF_EXTERNALMODEL) + return false; +// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) +// return false; +// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) +// continue; + if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1)) + return false; + } + return true; +} + + +void D3DR_DrawEntitiesOnList (void) +{ + int i; + + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; irtype) + { + case RT_SPRITE: + RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin); + continue; +#ifdef Q3SHADERS + case RT_BEAM: + case RT_RAIL_RINGS: + case RT_LIGHTNING: + R_DrawLightning(currententity); + continue; + case RT_RAIL_CORE: + R_DrawRailCore(currententity); + continue; +#endif + case RT_MODEL: //regular model + break; + case RT_PORTALSURFACE: + continue; //this doesn't do anything anyway, does it? + default: + case RT_POLY: //these are a little painful, we need to do them some time... just not yet. + continue; + } + if (currententity->flags & Q2RF_BEAM) + { +// R_DrawBeam(currententity); + continue; + } + if (!currententity->model) + continue; + + + if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static + { +/* if (gl_part_flame.value) + { + if (currententity->model->engineflags & MDLF_ENGULPHS) + continue; + }*/ + } + + switch (currententity->model->type) + { + + case mod_alias: +// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D_DrawAliasModel (); + break; + +#ifdef HALFLIFEMODELS + case mod_halflife: + R_DrawHLModel (currententity); + break; +#endif + + case mod_brush: +// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D_BaseBModelTextures (currententity); + break; + + case mod_sprite: + RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin); + break; +/* +#ifdef TERRAIN + case mod_heightmap: + D3D_DrawHeightmapModel(currententity); + break; +#endif +*/ + default: + break; + } + } + + { + float m_identity[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)m_identity); + } +} + +void D3D_DrawWorld(void) +{ + RSpeedLocals(); + entity_t ent; + + memset (&ent, 0, sizeof(ent)); + ent.model = cl.worldmodel; + currentmodel = cl.worldmodel; + + VectorCopy (r_refdef.vieworg, modelorg); + + currententity = &ent; +#ifdef TERRAIN + if (currentmodel->type == mod_heightmap) + GL_DrawHeightmapModel(currententity); + else +#endif + { +// qglColor3f (1,1,1); + //#ifdef QUAKE2 +// R_ClearSkyBox (); + //#endif + + RSpeedRemark(); +/* +#ifdef Q2BSPS + if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3) + { + int leafnum; + int clientarea; +#ifdef QUAKE2 + if (cls.protocol == CP_QUAKE2) //we can get server sent info + memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); + else +#endif + { //generate the info each frame. + leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); + clientarea = CM_LeafArea (cl.worldmodel, leafnum); + CM_WriteAreaBits(cl.worldmodel, areabits, clientarea); + } +#ifdef Q3BSPS + if (ent.model->fromgame == fg_quake3) + { + D3D7_LeafWorldNode (); + } + else +#endif + D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes); + } + else +#endif +*/ + D3D7_RecursiveWorldNode (cl.worldmodel->nodes); + + RSpeedEnd(RSPEED_WORLDNODE); + TRACE(("dbg: calling PPL_DrawWorld\n")); +// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) + D3D_DrawTextureChains(); +// else +// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg); + + +//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// GLR_LessenStains(); + } +} + +void D3D_R_RenderScene(void) +{ + if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) + r_refdef.flags |= Q2RDF_NOWORLDMODEL; + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + { + R_MarkLeaves (); // done here so we know if we're in water + D3D_DrawWorld (); // adds static entities to the list + } + + D3DR_DrawEntitiesOnList (); + + P_DrawParticles(); +} + +void (D3D_R_RenderView) (void) +{ + D3D_SetupFrame(); + D3D_SetupViewPort(); + R_SetFrustum(); + D3D_R_RenderScene(); +} +#endif diff --git a/engine/d3d/d3d_rsurf.c b/engine/d3d/d3d_rsurf.c new file mode 100644 index 000000000..d78c820d9 --- /dev/null +++ b/engine/d3d/d3d_rsurf.c @@ -0,0 +1,1369 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3dquake.h" + +int numlightmaps; + +mvertex_t *r_pcurrentvertbase; + +#define LMBLOCK_WIDTH 128 +#define LMBLOCK_HEIGHT LMBLOCK_WIDTH + +LPDIRECTDRAWSURFACE7 *lightmap_d3dtextures; +LPDIRECTDRAWSURFACE7 *deluxmap_d3dtextures; +lightmapinfo_t **lightmap; + + + +void D3D_BuildSurfaceDisplayList (msurface_t *fa) +{ + int i, lindex, lnumverts; + medge_t *pedges, *r_pedge; + int vertpage; + float *vec; + float s, t; + int lm; + + int size; + mesh_t *mesh; + +// reconstruct the polygon + pedges = currentmodel->edges; + lnumverts = fa->numedges; + vertpage = 0; + + + if (lnumverts<3) + return; //q3 map. + + size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec3_t) + sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts; + + fa->mesh = mesh = Hunk_Alloc(size); + mesh->xyz_array = (vec3_t*)(mesh + 1); + mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts); + mesh->st_array = (vec2_t*)(mesh->normals_array + lnumverts); + mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts); + mesh->colors_array = (byte_vec4_t*)(mesh->lmst_array + lnumverts); + mesh->indexes = (index_t*)(mesh->colors_array + lnumverts); + + mesh->numindexes = (lnumverts-2)*3; + mesh->numvertexes = lnumverts; + mesh->patchWidth = mesh->patchHeight = 1; + + for (i=0 ; iindexes[i*3] = 0; + mesh->indexes[i*3+1] = i+1; + mesh->indexes[i*3+2] = i+2; + } + + for (i=0 ; isurfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + vec = r_pcurrentvertbase[r_pedge->v[0]].position; + } + else + { + r_pedge = &pedges[-lindex]; + vec = r_pcurrentvertbase[r_pedge->v[1]].position; + } + + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + + VectorCopy (vec, mesh->xyz_array[i]); + mesh->xyz_array[i][3] = 1; + mesh->st_array[i][0] = s/fa->texinfo->texture->width; + mesh->st_array[i][1] = t/fa->texinfo->texture->height; + + s -= fa->texturemins[0]; + lm = s*fa->light_t; + s += fa->light_s*16; + s += 8; + s /= LMBLOCK_WIDTH*16; + + t -= fa->texturemins[1]; + lm += t; + t += fa->light_t*16; + t += 8; + t /= LMBLOCK_HEIGHT*16; + + mesh->lmst_array[i][0] = s; + mesh->lmst_array[i][1] = t; + + if (fa->flags & SURF_PLANEBACK) + VectorNegate(fa->plane->normal, mesh->normals_array[i]); + else + VectorCopy(fa->plane->normal, mesh->normals_array[i]); + + mesh->colors_array[i][0] = 255; + mesh->colors_array[i][1] = 255; + mesh->colors_array[i][2] = 255; + mesh->colors_array[i][3] = 255; + } +} + + + + + + + +#define MAX_LIGHTMAP_SIZE 18 + +vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; +unsigned blocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; + +unsigned greenblklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; +unsigned blueblklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; + +void D3DR_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift) +{ + int smax, tmax; + int t; + int i, j, size; + qbyte *lightmap; + unsigned scale; + int maps; + unsigned *bl; + qboolean isstained; + extern cvar_t r_ambient; + extern cvar_t gl_lightmap_shift; + + unsigned *blg; + unsigned *blb; + + int r, g, b; + int cr, cg, cb; + + int stride = LMBLOCK_WIDTH*lightmap_bytes; + + shift += 7; // increase to base value + surf->cached_dlight = (surf->dlightframe == r_framecount); + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + + if (size > MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE) + { //fixme: fill in? + Con_Printf("Lightmap too large\n"); + return; + } + +// if (currentmodel->deluxdata) +// GLR_BuildDeluxMap(surf, deluxdest); + + + + if (true) + { + // set to full bright if no light data + if (r_fullbright.value>0) //not qw + { + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + } + goto store; + } + if (!currentmodel->lightdata) + { + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + goto store; + } + +// clear to no light + t = r_ambient.value*255; + for (i=0 ; ifromgame == fg_quake3) //rgb + { + /* for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) //no light styles in q3 apparently. + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + } + */ + for (i = 0; i < tmax; i++) //q3 maps store thier light in a block fashion, q1/q2/hl store it in a linear fashion. + { + for (j = 0; j < smax; j++) + { + blocklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3]; + greenblklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+1]; + blueblklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+2]; + } + } +// memset(blocklights, 255, sizeof(blocklights)); + } + else if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb + { + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + + + if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative. + { + for (i=0 ; istyles[maps]].colour & 1) + for (i=0 ; istyles[maps]].colour & 2) + for (i=0 ; istyles[maps]].colour & 4) + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + + if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative. + { + for (i=0 ; istyles[maps]].colour & 1) + for (i=0 ; istyles[maps]].colour & 2) + for (i=0 ; istyles[maps]].colour & 4) + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + } + else + { + // set to full bright if no light data + if (r_fullbright.value || !currentmodel->lightdata) + { + for (i=0 ; iengineflags & MDLF_RGBLIGHTING) //rgb + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]/3; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLights (surf); + } + +// bound, invert, and shift +store: +#define INVERTLIGHTMAPS +#ifdef INVERTLIGHTMAPS + switch (lightmap_bytes) + { + case 4: + stride -= (smax<<2); + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest[3] = 0;//(dest[0]+dest[1]+dest[2])/3; + dest += 4; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + /* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[2] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +//*/ + + + + dest[3] = (dest[0]+dest[1]+dest[2])/3; //alpha?!?! + dest += 4; + } + } + } + break; + + case 3: + stride -= smax*3; + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest += 3; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + /* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[2] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +// */ + dest += 3; + } + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +#else + switch (lightmap_bytes) + { + case 4: + stride -= (smax<<2); + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest[3] = 0;//(dest[0]+dest[1]+dest[2])/3; + dest += 4; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +*/ + + + + dest[3] = (dest[0]+dest[1]+dest[2])/3; //alpha?!?! + dest += 4; + } + } + } + break; + + case 3: + stride -= smax*3; + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 255; + else if (t < 0) + dest[0] = 0; + else + dest[0] = t; + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 255; + else if (t < 0) + dest[1] = 0; + else + dest[1] = t; + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 255; + else if (t < 0) + dest[2] = 0; + else + dest[2] = t; + + dest += 3; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[2] = 255; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +// */ + dest += 3; + } + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +#endif +} + + + +int D3DFillBlock (int texnum, int w, int h, int x, int y) +{ + int i, l; + while (texnum >= numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. + { + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap_d3dtextures = BZ_Realloc(lightmap_d3dtextures, sizeof(*lightmap_d3dtextures)*(numlightmaps+4)); +// lightmap_textures[numlightmaps+0] = texture_extension_number++; +// lightmap_textures[numlightmaps+1] = texture_extension_number++; +// lightmap_textures[numlightmaps+2] = texture_extension_number++; +// lightmap_textures[numlightmaps+3] = texture_extension_number++; + + deluxmap_d3dtextures = BZ_Realloc(deluxmap_d3dtextures, sizeof(*deluxmap_d3dtextures)*(numlightmaps+4)); +// deluxmap_textures[numlightmaps+0] = texture_extension_number++; +// deluxmap_textures[numlightmaps+1] = texture_extension_number++; +// deluxmap_textures[numlightmaps+2] = texture_extension_number++; +// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + numlightmaps+=4; + } + for (i = texnum; i >= 0; i--) + { + if (!lightmap[i]) + { + lightmap[i] = BZ_Malloc(sizeof(*lightmap[i])); + for (l=0 ; lallocated[l] = LMBLOCK_HEIGHT; + } + + //maybe someone screwed with my lightmap... + memset(lightmap[i]->lightmaps, 255, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); + if (cl.worldmodel->lightdata) + memcpy(lightmap[i]->lightmaps, cl.worldmodel->lightdata+3*LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); + + } + else + break; + } + return texnum; +} + +int D3D7_AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + for (texnum=0 ; ; texnum++) + { + if (texnum == numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. + { + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap_d3dtextures = BZ_Realloc(lightmap_d3dtextures, sizeof(*lightmap_d3dtextures)*(numlightmaps+4)); +// lightmap_textures[numlightmaps+0] = texture_extension_number++; +// lightmap_textures[numlightmaps+1] = texture_extension_number++; +// lightmap_textures[numlightmaps+2] = texture_extension_number++; +// lightmap_textures[numlightmaps+3] = texture_extension_number++; + + deluxmap_d3dtextures = BZ_Realloc(deluxmap_d3dtextures, sizeof(*deluxmap_d3dtextures)*(numlightmaps+4)); +// deluxmap_textures[numlightmaps+0] = texture_extension_number++; +// deluxmap_textures[numlightmaps+1] = texture_extension_number++; +// deluxmap_textures[numlightmaps+2] = texture_extension_number++; +// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + numlightmaps+=4; + } + if (!lightmap[texnum]) + { + lightmap[texnum] = Z_Malloc(sizeof(*lightmap[texnum])); + // reset stainmap since it now starts at 255 + memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps)); + } + + + best = LMBLOCK_HEIGHT; + + for (i=0 ; iallocated[i+j] >= best) + break; + if (lightmap[texnum]->allocated[i+j] > best2) + best2 = lightmap[texnum]->allocated[i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > LMBLOCK_HEIGHT) + continue; + + for (i=0 ; iallocated[*x + i] = best + h; + + return texnum; + } + + Sys_Error ("AllocBlock: full"); + return 0; +} + + +void D3D_CreateSurfaceLightmap (msurface_t *surf, int shift) +{ + int smax, tmax; + qbyte *base, *luxbase; stmap *stainbase; + + if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) + surf->lightmaptexturenum = -1; + if (surf->texinfo->flags & TEX_SPECIAL) + surf->lightmaptexturenum = -1; + if (surf->lightmaptexturenum<0) + return; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + + if (smax > LMBLOCK_WIDTH || tmax > LMBLOCK_HEIGHT || smax < 0 || tmax < 0) + { //whoa, buggy. + surf->lightmaptexturenum = -1; + return; + } + + if (currentmodel->fromgame == fg_quake3) + D3DFillBlock(surf->lightmaptexturenum, smax, tmax, surf->light_s, surf->light_t); + else + surf->lightmaptexturenum = D3D7_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + base = lightmap[surf->lightmaptexturenum]->lightmaps; + base += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes; + + luxbase = lightmap[surf->lightmaptexturenum]->deluxmaps; + luxbase += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes; + + stainbase = lightmap[surf->lightmaptexturenum]->stainmaps; + stainbase += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * 3; + + D3DR_BuildLightMap (surf, base, luxbase, stainbase, shift); +} + + +void D3DR_RenderDynamicLightmaps (msurface_t *fa, int shift) +{ + qbyte *base, *luxbase; + stmap *stainbase; + int maps; + glRect_t *theRect; + int smax, tmax; + + if (!fa->mesh) + return; + +// c_brush_polys++; + + if (fa->lightmaptexturenum<0) + return; + + if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) + return; + + if (fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP)) + return; + + if (fa->texinfo->flags & (TEX_SPECIAL)) + { + if (cl.worldmodel->fromgame == fg_halflife) + return; //some textures do this. + } + +// fa->polys->chain = lightmap[fa->lightmaptexturenum]->polys; +// lightmap[fa->lightmaptexturenum]->polys = fa->polys; + + // check for lightmap modification +// if (cl.worldmodel->fromgame != fg_quake3) //no lightstyles on q3 maps + { + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] + #ifdef PEXT_LIGHTSTYLECOL + || cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps] + #endif + ) + { + goto dynamic; + } + } + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { + RSpeedLocals(); +dynamic: + RSpeedRemark(); + + lightmap[fa->lightmaptexturenum]->modified = true; + + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + + theRect = &lightmap[fa->lightmaptexturenum]->rectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + lightmap[fa->lightmaptexturenum]->deluxmodified = true; + theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + + base = lightmap[fa->lightmaptexturenum]->lightmaps; + base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps; + luxbase += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + stainbase = lightmap[fa->lightmaptexturenum]->stainmaps; + stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3; + D3DR_BuildLightMap (fa, base, luxbase, stainbase, shift); + + RSpeedEnd(RSPEED_DYNAMIC); + } +} + + + +LPDIRECTDRAWSURFACE7 D3D_NewLightmap(void) +{ + DWORD tflags = D3DX_TEXTURE_NOMIPMAP; //for now + DWORD twidth = LMBLOCK_WIDTH; + DWORD theight = LMBLOCK_HEIGHT; + D3DX_SURFACEFORMAT tformat = D3DX_SF_A8R8G8B8; + LPDIRECTDRAWSURFACE7 newsurf; + DWORD nummips; + DDSURFACEDESC2 desc; + + D3DXCreateTexture(pD3DDev, &tflags, &twidth, &theight, &tformat, NULL, &newsurf, &nummips); + if (!newsurf) + return NULL; + + return newsurf; +} + +void D3D_BuildLightmaps (void) +{ + DDSURFACEDESC2 desc; + + int i, j; + model_t *m; + int shift; + + r_framecount = 1; // no dlightcache +/* + for (i = 0; i < numlightmaps; i++) + { + if (!lightmap[i]) + break; + BZ_Free(lightmap[i]); + lightmap[i] = NULL; + } + + if (cl.worldmodel->fromgame == fg_doom) + return; //no lightmaps. + + if ((cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value) + gl_lightmap_format = GL_RGB; + else + gl_lightmap_format = GL_LUMINANCE; + + + if (cl.worldmodel->fromgame == fg_quake3 && gl_lightmap_format != GL_RGB && gl_lightmap_format != GL_RGBA) + gl_lightmap_format = GL_RGB; + + + switch (gl_lightmap_format) + { + case GL_RGBA: + lightmap_bytes = 4; + break; + case GL_RGB: + lightmap_bytes = 3; + break; + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_ALPHA: + lightmap_bytes = 1; + break; + } +*/ + for (j=1 ; jname[0] == '*') + continue; + + r_pcurrentvertbase = m->vertexes; + currentmodel = m; + shift = 0;//GLR_LightmapShift(currentmodel); + + for (i=0 ; inumsurfaces ; i++) + { + D3D_CreateSurfaceLightmap (m->surfaces + i, shift); + P_EmitSkyEffectTris(m, &m->surfaces[i]); + if (m->surfaces[i].mesh) //there are some surfaces that have a display list already (the subdivided ones) + continue; + D3D_BuildSurfaceDisplayList (m->surfaces + i); + } + } + + // + // upload all lightmaps that were filled + // + for (i=0 ; imodified = false; + lightmap[i]->rectchange.l = LMBLOCK_WIDTH; + lightmap[i]->rectchange.t = LMBLOCK_HEIGHT; + lightmap[i]->rectchange.w = 0; + lightmap[i]->rectchange.h = 0; + + if (!lightmap_d3dtextures[i]) + { + lightmap_d3dtextures[i] = D3D_NewLightmap(); + + if (!lightmap_d3dtextures[i]) + { + Con_Printf("Couldn't create new lightmap\n"); + return; + } + } + + desc.dwSize = sizeof(desc); + lightmap_d3dtextures[i]->lpVtbl->Lock(lightmap_d3dtextures[i], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[i]->lightmaps, sizeof(lightmap[i]->lightmaps)); + /* memset(desc.lpSurface, 0, sizeof(lightmap[i]->lightmaps)); + { + int i; + unsigned char *c; + c = desc.lpSurface; + for (i = 0; i < sizeof(lightmap[i]->lightmaps); i++) + *c++ = rand(); + }*/ + lightmap_d3dtextures[i]->lpVtbl->Unlock(lightmap_d3dtextures[i], NULL); + + if (deluxmap_d3dtextures[i]) + { + deluxmap_d3dtextures[i]->lpVtbl->Lock(deluxmap_d3dtextures[i], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[i]->lightmaps, sizeof(lightmap[i]->deluxmaps)); + deluxmap_d3dtextures[i]->lpVtbl->Unlock(deluxmap_d3dtextures[i], NULL); + } + } + +} +#endif diff --git a/engine/d3d/d3dquake.h b/engine/d3d/d3dquake.h new file mode 100644 index 000000000..edcb5cc62 --- /dev/null +++ b/engine/d3d/d3dquake.h @@ -0,0 +1,73 @@ +#include "ddraw.h" +#include "d3d.h" +#include "d3dx.h" + +void *D3D_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags); +void *D3D_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix); +void *D3D_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette); +/* +#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal) +#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255) +#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP) +#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0 +#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0 + +#define D3D9_FindTexture(name) -1 +#define D3D9_LoadCompressed(name) 0 +*/ + + +void *D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags); +void *D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix); +void *D3D9_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette); + + +#define D3D_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal32:D3D9_LoadTexture_8_Pal32)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, palette) +#define D3D_LoadTexture8Pal24(skinname,width,height,data,palette,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal24:D3D9_LoadTexture_8_Pal24)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, palette, 255) +#define D3D_LoadTexture(skinname,width,height,data,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal24:D3D9_LoadTexture_8_Pal24)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255) +#define D3D_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_32:D3D9_LoadTexture_32)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP) +#define D3D_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0 +#define D3D_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0 + +#define D3D_FindTexture(name) -1 +#define D3D_LoadCompressed(name) 0 + + + +extern LPDIRECT3DDEVICE7 pD3DDev; + +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +#define lightmap_bytes 4 + + +extern int numlightmaps; + +extern mvertex_t *r_pcurrentvertbase; + +#ifndef LMBLOCK_WIDTH +#define LMBLOCK_WIDTH 128 +#define LMBLOCK_HEIGHT LMBLOCK_WIDTH +typedef struct glRect_s { + unsigned char l,t,w,h; +} glRect_t; +typedef unsigned char stmap; + +typedef struct { + qboolean modified; + qboolean deluxmodified; + glRect_t rectchange; + glRect_t deluxrectchange; + int allocated[LMBLOCK_WIDTH]; + qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; + qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage. + stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed. +} lightmapinfo_t; +#endif + +extern LPDIRECTDRAWSURFACE7 *lightmap_d3dtextures; +extern LPDIRECTDRAWSURFACE7 *deluxmap_d3dtextures; +extern lightmapinfo_t **lightmap; + +extern void *d3dexplosiontexture; +extern void *d3dballtexture; \ No newline at end of file diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c new file mode 100644 index 000000000..02a23bea9 --- /dev/null +++ b/engine/d3d/vid_d3d.c @@ -0,0 +1,1263 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3dquake.h" + + +#pragma comment(lib, "d3dx.lib") +#pragma comment(lib, "ddraw.lib") +#pragma comment(lib, "dxguid.lib") + + +#ifndef WM_XBUTTONDOWN + #define WM_XBUTTONDOWN 0x020B + #define WM_XBUTTONUP 0x020C +#endif +#ifndef MK_XBUTTON1 + #define MK_XBUTTON1 0x0020 + #define MK_XBUTTON2 0x0040 +// copied from DarkPlaces in an attempt to grab more buttons + #define MK_XBUTTON3 0x0080 + #define MK_XBUTTON4 0x0100 + #define MK_XBUTTON5 0x0200 + #define MK_XBUTTON6 0x0400 + #define MK_XBUTTON7 0x0800 +#endif + +#ifndef WM_INPUT + #define WM_INPUT 255 +#endif + + +int gl_bumpmappingpossible; + +static LPD3DXCONTEXT pD3DX; +static LPDIRECTDRAW7 pDD; +static LPDIRECT3D7 pD3D; +LPDIRECT3DDEVICE7 pD3DDev; +static LPDIRECTDRAWSURFACE7 pPrimary; +static LPDIRECTDRAWGAMMACONTROL pGammaControl; + + +static qboolean vid_initializing; + +extern qboolean scr_initialized; // ready to draw +extern qboolean scr_drawloading; + + +cvar_t vid_hardwaregamma; + + +HWND mainwindow; + +struct texture_s *r_notexture_mip; + +int r_framecount; + +mleaf_t *r_viewleaf; + +#define MAX_MOD_KNOWN 1024 +int mod_numknown; +model_t mod_known[MAX_MOD_KNOWN]; +model_t *loadmodel; +model_t *currentmodel; +char loadname[32]; +qbyte *mod_base; + +qboolean DDActive; + +model_t *lightmodel; +int relitsurface; + +int window_center_x, window_center_y; +RECT window_rect; +int window_x, window_y; + +qboolean r_cache_thrash; // set if thrashing the surface cache + +mpic_t *draw_disc; // also used on sbar + +#if !defined(SWQUAKE) && !defined(RGLQUAKE) +qbyte GetPalette(int red, int green, int blue) +{ + //slow, horrible method. + { + int i, best=15; + int bestdif=256*256*256, curdif; + extern qbyte *host_basepal; + qbyte *pa; + + #define _abs(x) ((x)*(x)) + + pa = host_basepal; + for (i = 0; i < 256; i++, pa+=3) + { + curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]); + if (curdif < bestdif) + { + if (curdif<1) + return i; + bestdif = curdif; + best = i; + } + } + return best; + } +} +#endif + +void BuildGammaTable (float g, float c); +void D3D_VID_GenPaletteTables (unsigned char *palette) +{ + qbyte *pal; + unsigned r,g,b; + unsigned v; + unsigned short i; + unsigned *table; + extern qbyte gammatable[256]; + + if (palette) + { + BuildGammaTable(1, 1); + + // + // 8 8 8 encoding + // + if (vid_hardwaregamma.value) + { + // don't built in the gamma table + + pal = palette; + table = d_8to24rgbtable; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + + // v = (255<<24) + (r<<16) + (g<<8) + (b<<0); + // v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent + } + else + { + //computer has no hardware gamma (poor suckers) increase table accordingly + + pal = palette; + table = d_8to24rgbtable; + for (i=0 ; i<256 ; i++) + { + r = gammatable[pal[0]]; + g = gammatable[pal[1]]; + b = gammatable[pal[2]]; + pal += 3; + + // v = (255<<24) + (r<<16) + (g<<8) + (b<<0); + // v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent + } + + if (LittleLong(1) != 1) + for (i=0 ; i<256 ; i++) + d_8to24rgbtable[i] = LittleLong(d_8to24rgbtable[i]); + } +} + +#if !defined(SWQUAKE) && !defined(GLQUAKE) +void D_FlushCaches (void) +{ +} +#endif + + + + +void D3DMod_Think (void) +{ +} +void D3DMod_NowLoadExternal(void) +{ +} +void D3DMod_TouchModel (char *name) +{ +} +void *D3DMod_Extradata (struct model_s *mod) // handles caching +{ + return NULL; +} +struct model_s *D3DMod_FindName (char *name) +{ + return NULL; +} +struct model_s *D3DMod_ForName (char *name, qboolean crash) +{ + return NULL; +} +void D3DMod_ClearAll (void) +{ +} +void D3DMod_Init (void) +{ +} + + +typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t; +static modestate_t modestate; + +qboolean D3DAppActivate(BOOL fActive, BOOL minimize) +/**************************************************************************** +* +* Function: AppActivate +* Parameters: fActive - True if app is activating +* +* Description: If the application is activating, then swap the system +* into SYSPAL_NOSTATIC mode so that our palettes will display +* correctly. +* +****************************************************************************/ +{ + static BOOL sound_active; + + if (ActiveApp == fActive && Minimized == minimize) + return false; //so windows doesn't crash us over and over again. + + ActiveApp = fActive; + Minimized = minimize; + +// enable/disable sound on focus gain/loss + if (!ActiveApp && sound_active) + { + S_BlockSound (); + sound_active = false; + } + else if (ActiveApp && !sound_active) + { + S_UnblockSound (); + sound_active = true; + } + + if (fActive) + { +/* if (modestate != MS_WINDOWED) + { + IN_ActivateMouse (); + IN_HideMouse (); +// if (vid_canalttab && vid_wassuspended) + { +// vid_wassuspended = false; +// ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN); + ShowWindow(mainwindow, SW_SHOWNORMAL); + + // Fix for alt-tab bug in NVidia drivers +// MoveWindow (mainwindow, 0, 0, gdevmode.dmPelsWidth, gdevmode.dmPelsHeight, false); + } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value && (key_dest == key_game || key_dest == key_menu)) + { + IN_ActivateMouse (); + IN_HideMouse (); + } +*/ + Cvar_ForceCallback(&v_gamma); + } + + if (!fActive) + { +/* if (modestate != MS_WINDOWED) + { + IN_DeactivateMouse (); + IN_ShowMouse (); +// if (vid_canalttab) +// { +// ChangeDisplaySettings (NULL, 0); +// vid_wassuspended = true; +// } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } +*/ + Cvar_ForceCallback(&v_gamma); //wham bam thanks. +/* + if (qSetDeviceGammaRamp) + { + if (vid_desktopgamma.value) + { + HDC hDC = GetDC(GetDesktopWindow()); + qSetDeviceGammaRamp (hDC, originalgammaramps); + ReleaseDC(GetDesktopWindow(), hDC); + } + else + { + qSetDeviceGammaRamp(maindc, originalgammaramps); + } + } + */ + } + + return true; +} + + + + + +static LRESULT WINAPI D3D7_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LONG lRet = 1; + int fActive, fMinimized, temp; + extern unsigned int uiWheelMessage; + + if ( uMsg == uiWheelMessage ) + uMsg = WM_MOUSEWHEEL; + + switch (uMsg) + { + case WM_KILLFOCUS: + if (modestate == MS_FULLDIB) + ShowWindow(mainwindow, SW_SHOWMINNOACTIVE); + break; + + case WM_CREATE: + break; + + case WM_MOVE: + GetWindowRect(mainwindow, &window_rect); + window_x = (int) LOWORD(lParam); + window_y = (int) HIWORD(lParam); +// VID_UpdateWindowStatus (); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (!vid_initializing) + Key_Event (MapKey(lParam), true); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + if (!vid_initializing) + Key_Event (MapKey(lParam), false); + break; + + case WM_SYSCHAR: + // keep Alt-Space from happening + break; + + // this is complicated because Win32 seems to pack multiple mouse events into + // one update sometimes, so we always check all states and look for events + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEMOVE: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + temp = 0; + + if (wParam & MK_LBUTTON) + temp |= 1; + + if (wParam & MK_RBUTTON) + temp |= 2; + + if (wParam & MK_MBUTTON) + temp |= 4; + + if (wParam & MK_XBUTTON1) + temp |= 8; + + if (wParam & MK_XBUTTON2) + temp |= 16; + + if (wParam & MK_XBUTTON3) + temp |= 32; + + if (wParam & MK_XBUTTON4) + temp |= 64; + + if (wParam & MK_XBUTTON5) + temp |= 128; + + if (wParam & MK_XBUTTON6) + temp |= 256; + + if (wParam & MK_XBUTTON7) + temp |= 512; + + if (!vid_initializing) + IN_MouseEvent (temp); + + break; + + // JACK: This is the mouse wheel with the Intellimouse + // Its delta is either positive or neg, and we generate the proper + // Event. + case WM_MOUSEWHEEL: + if (!vid_initializing) + { + if ((short) HIWORD(wParam) > 0) + { + Key_Event(K_MWHEELUP, true); + Key_Event(K_MWHEELUP, false); + } + else + { + Key_Event(K_MWHEELDOWN, true); + Key_Event(K_MWHEELDOWN, false); + } + } + break; + + case WM_INPUT: + // raw input handling + IN_RawInput_MouseRead((HANDLE)lParam); + break; + + case WM_SIZE: + if (!vid_initializing) + { + GetWindowRect(mainwindow, &window_rect); + // force width/height to be updated +// glwidth = window_rect.right - window_rect.left; +// glheight = window_rect.bottom - window_rect.top; +// Cvar_ForceCallback(&vid_conautoscale); +// Cvar_ForceCallback(&vid_conwidth); + } + break; + + case WM_CLOSE: + if (!vid_initializing) + if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", + MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) + { + Sys_Quit (); + } + + break; + + case WM_ACTIVATE: + fActive = LOWORD(wParam); + fMinimized = (BOOL) HIWORD(wParam); + if (!D3DAppActivate(!(fActive == WA_INACTIVE), fMinimized)) + break;//so, urm, tell me microsoft, what changed? + if (modestate == MS_FULLDIB) + ShowWindow(mainwindow, SW_SHOWNORMAL); + + // fix the leftover Alt from any Alt-Tab or the like that switched us away +// ClearAllStates (); + + break; + + case WM_DESTROY: + { +// if (dibwindow) +// DestroyWindow (dibwindow); + } + break; + + case MM_MCINOTIFY: + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + break; + + + case WM_MWHOOK: + if (!vid_initializing) + MW_Hook_Message (lParam); + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + + + +qboolean D3D_VID_Init(rendererstate_t *info, unsigned char *palette) +{ + DWORD width = info->width; + DWORD height = info->height; + DWORD bpp = info->bpp; + DWORD zbpp = 16; + DWORD flags = 0; + MSG msg; + + extern cvar_t vid_conwidth; + extern cvar_t vid_conheight; + + DDGAMMARAMP gammaramp; + char errs[1024]; + int i; + HRESULT hr; + + char *CLASSNAME = "FTED3D7QUAKE"; + WNDCLASS wc = { + 0, + &D3D7_WindowProc, + 0, + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + CLASSNAME + }; + +// wc.style = 0; + wc.lpfnWndProc = D3D7_WindowProc; +// wc.cbClsExtra; +// wc.cbWndExtra; +// wc.hInstance; +// wc.hIcon; +// wc.hCursor; +// wc.hbrBackground; +// wc.lpszMenuName; + wc.lpszClassName = CLASSNAME; + + vid_initializing = true; + + if( FAILED(hr = D3DXInitialize()) ) + { + D3DXGetErrorString(hr, sizeof(errs), errs); + Con_Printf("D3D initialisation failed: error %X: %s\n", hr, errs); + return false; + } + + RegisterClass(&wc); + + flags |= info->fullscreen ? D3DX_CONTEXT_FULLSCREEN : 0; + + if (flags & D3DX_CONTEXT_FULLSCREEN) + mainwindow = CreateWindow(CLASSNAME, "Direct3D", 0, 0, 0, width, height, NULL, NULL, NULL, NULL); + else + mainwindow = CreateWindow(CLASSNAME, "Direct3D", WS_OVERLAPPEDWINDOW, 0, 0, width, height, NULL, NULL, NULL, NULL); +/* + width = vid_conwidth.value; + height = vid_conheight.value; +*/ + // Try as specified. + hr = D3DXCreateContextEx(D3DX_DEFAULT, flags, + mainwindow, NULL, bpp, 0, + zbpp, 0, 1, width, height, D3DX_DEFAULT, &pD3DX); + if( FAILED(hr) ) + { + D3DXGetErrorString(hr, sizeof(errs), errs); + printf("D3D initialisation failed: error %X: %s\n", hr, errs); + + // default z-buffer + hr = D3DXCreateContextEx(D3DX_DEFAULT, flags, + mainwindow, NULL, bpp, 0, + D3DX_DEFAULT, 0, 1, width, height, D3DX_DEFAULT, &pD3DX); + if( FAILED(hr) ) + { + // default depth and z-buffer + hr = D3DXCreateContextEx(D3DX_DEFAULT, flags, + mainwindow, NULL, D3DX_DEFAULT, 0, + D3DX_DEFAULT, 0, 1, width, height, D3DX_DEFAULT, &pD3DX); + if( FAILED(hr) ) + { + // default everything + hr = D3DXCreateContextEx(D3DX_DEFAULT, flags, + mainwindow, NULL, D3DX_DEFAULT, 0, + D3DX_DEFAULT, 0, 1, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, &pD3DX); + if( FAILED(hr) ) + { + D3DXGetErrorString(hr, sizeof(errs), errs); + Con_Printf("D3D fallbacks failed: error %X: %s\n", hr, errs); + + DestroyWindow(mainwindow); + mainwindow = NULL; + return false; + } + } + } + } + //the void* casts are because microsoft screwed up in the header files I have + pDD = pD3DX->lpVtbl->GetDD((void*)pD3DX); + pD3D = pD3DX->lpVtbl->GetD3D((void*)pD3DX); + pD3DDev = pD3DX->lpVtbl->GetD3DDevice((void*)pD3DX); + pPrimary = pD3DX->lpVtbl->GetPrimary((void*)pD3DX); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + ShowWindow(mainwindow, SW_NORMAL); + pD3DX->lpVtbl->SetClearColor((void*)pD3DX, 0xffffffff); + pD3DX->lpVtbl->Clear((void*)pD3DX, D3DCLEAR_TARGET); + pD3DX->lpVtbl->UpdateFrame((void*)pD3DX, 0); + + + + pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, &width, &height); + vid.width = width; + vid.height = height; + vid.recalc_refdef = true; + + pDD->lpVtbl->QueryInterface ((void*)pDD, &IID_IDirectDrawGammaControl, (void**)&pGammaControl); + if (pGammaControl) + { + for (i = 0; i < 256; i++) + gammaramp.red[i] = i*2; + pGammaControl->lpVtbl->SetGammaRamp(pGammaControl, 0, &gammaramp); + } + else + Con_Printf("Couldn't get gamma controls\n"); + + vid_initializing = false; + + + + + + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER ); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHAREF, 0.666*256 ); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); + + + //pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DITHERENABLE, FALSE); + //pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SPECULARENABLE, FALSE); + //pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_LIGHTING, FALSE); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZWRITEENABLE, TRUE); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZVISIBLE, TRUE); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); + + + GetWindowRect(mainwindow, &window_rect); + + + D3D_VID_GenPaletteTables(palette); + + + + { + extern cvar_t vid_conwidth, vid_conheight; + vid.conwidth = vid_conwidth.value; + vid.conheight = vid_conheight.value; + if (vid.width != vid.conwidth || vid.height != vid.conheight) + vid.recalc_refdef = true; + vid.width = vid.conwidth; + vid.height = vid.conheight; + } + + return true; +} + + + +qboolean (D3D_R_CheckSky) (void) +{ + return false; +} +void (D3D_R_SetSky) (char *name, float rotate, vec3_t axis) +{ +} + +void (D3D_R_NewMap) (void) +{ + extern int skytexturenum; + int i; + r_worldentity.model = cl.worldmodel; + GLR_AnimateLight(); + D3D_BuildLightmaps(); + + P_ClearParticles(); + + skytexturenum = -1; + + for (i=0 ; inumtextures ; i++) + { + if (!cl.worldmodel->textures[i]) + continue; + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) + skytexturenum = i; +// if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) +// mirrortexturenum = i; + cl.worldmodel->textures[i]->texturechain = NULL; + } +} + +mleaf_t *r_viewleaf, *r_oldviewleaf; +mleaf_t *r_viewleaf2, *r_oldviewleaf2; +void (D3D_R_PreNewMap) (void) +{ + r_viewleaf = NULL; + r_oldviewleaf = NULL; + r_viewleaf2 = NULL; + r_oldviewleaf2 = NULL; +} +int (D3D_R_LightPoint) (vec3_t point) +{ + return 0; +} + +void (D3D_R_PushDlights) (void) +{ +} +void (D3D_R_AddStain) (vec3_t org, float red, float green, float blue, float radius) +{ +} +void (D3D_R_LessenStains) (void) +{ +} + +void (D3D_Mod_Init) (void) +{ +} +void (D3D_Mod_ClearAll) (void) +{ +} +struct model_s *(D3D_Mod_ForName) (char *name, qboolean crash) +{ + return NULL; +} +struct model_s *(D3D_Mod_FindName) (char *name) +{ + return NULL; +} +void *(D3D_Mod_Extradata) (struct model_s *mod) +{ + return NULL; +} // handles caching +void (D3D_Mod_TouchModel) (char *name) +{ +} + +void (D3D_Mod_NowLoadExternal) (void) +{ +} +void (D3D_Mod_Think) (void) +{ +} +qboolean(D3D_Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result) +{ + return false; +} +int (D3D_Mod_TagNumForName) (struct model_s *model, char *name) +{ + return 0; +} +int (D3D_Mod_SkinForName) (struct model_s *model, char *name) +{ + return 0; +} + +void (D3D_VID_DeInit) (void) +{ + if (pPrimary) + { + pPrimary->lpVtbl->Release(pPrimary); + pPrimary = NULL; + } + if (pD3DDev) + { + pD3DDev->lpVtbl->Release(pD3DDev); + pD3DDev = NULL; + } + if (pD3D) + { + pD3D->lpVtbl->Release(pD3D); + pD3D = NULL; + } + if (pDD) + { + pDD->lpVtbl->Release(pDD); + pDD = NULL; + } + if (pD3DX) + { + pD3DX->lpVtbl->Release((void*)pD3DX); + pD3DX = NULL; + } + if (mainwindow) + { + DestroyWindow(mainwindow); + mainwindow = NULL; + } +} +void (D3D_VID_HandlePause) (qboolean pause) +{ +} +void (D3D_VID_LockBuffer) (void) +{ +} +void (D3D_VID_UnlockBuffer) (void) +{ +} +void (D3D_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height) +{ +} +void (D3D_D_EndDirectRect) (int x, int y, int width, int height) +{ +} +void (D3D_VID_ForceLockState) (int lk) +{ +} +int (D3D_VID_ForceUnlockedAndReturnState) (void) +{ + return 0; +} + +void (D3D_VID_SetPalette) (unsigned char *palette) +{ + D3D_VID_GenPaletteTables(palette); +} +void (D3D_VID_ShiftPalette) (unsigned char *palette) +{ + D3D_VID_GenPaletteTables(palette); +} +char *(D3D_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight) +{ + return NULL; +} +void (D3D_VID_SetWindowCaption) (char *msg) +{ + SetWindowText(mainwindow, msg); +} + +void d3d7_ortho(float *m) +{ + D3DXMatrixOrthoOffCenter((D3DXMATRIX*)m, 0, vid.width, vid.height, 0, -100, 100); +} + +void D3D_Set2D (void) +{ + int r; + float m[16]; + D3DVIEWPORT7 vport; +// pD3DDev->lpVtbl->EndScene(pD3DDev); + + D3DXMatrixOrthoOffCenter((D3DXMATRIX*)m, 0, vid.width, vid.height, 0, -100, 100); + r = pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX*)m); + + D3DXMatrixIdentity((D3DXMATRIX*)m); + r = pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)m); + + D3DXMatrixIdentity((D3DXMATRIX*)m); + pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX*)m); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_MIPFILTER, D3DTFP_LINEAR); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_MIPFILTER, D3DTFP_LINEAR); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_MINFILTER, D3DTFN_LINEAR); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_MINFILTER, D3DTFN_LINEAR); + + vport.dwX = 0; + vport.dwY = 0; + pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, &vport.dwWidth, &vport.dwHeight); + vport.dvMinZ = 0; + vport.dvMaxZ = 1; + pD3DDev->lpVtbl->SetViewport(pD3DDev, &vport); + +// pD3DDev->lpVtbl->BeginScene(pD3DDev); +} + +void D3D_GetBufferSize(int *width, int *height) +{ + pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, width, height); +} + + +void (D3D_SCR_UpdateScreen) (void) +{ + extern cvar_t vid_conheight; + int uimenu; +#ifdef TEXTEDITOR + extern qboolean editormodal; +#endif + qboolean nohud; + RSpeedMark(); + + if (block_drawing) + { + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + + vid.numpages = 2;// + gl_triplebuffer.value; + + scr_copytop = 0; + scr_copyeverything = 0; + + if (scr_disabled_for_loading) + { + extern float scr_disabled_time; + if (Sys_DoubleTime() - scr_disabled_time > 60 || key_dest != key_game) + { + scr_disabled_for_loading = false; + } + else + { + pD3DDev->lpVtbl->BeginScene(pD3DDev); + scr_drawloading = true; + SCR_DrawLoading (); + scr_drawloading = false; + pD3DDev->lpVtbl->EndScene(pD3DDev); + pD3DX->lpVtbl->UpdateFrame((void*)pD3DX, 0); + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + } + + if (!scr_initialized || !con_initialized) + { + RSpeedEnd(RSPEED_TOTALREFRESH); + return; // not initialized yet + } + + { + extern cvar_t vid_conwidth, vid_conheight; + vid.conwidth = vid_conwidth.value; + vid.conheight = vid_conheight.value; + if (vid.width != vid.conwidth || vid.height != vid.conheight) + vid.recalc_refdef = true; + vid.width = vid.conwidth; + vid.height = vid.conheight; + } + + +#ifdef VM_UI + uimenu = UI_MenuState(); +#else + uimenu = 0; +#endif + + pD3DDev->lpVtbl->BeginScene(pD3DDev); + D3D_Set2D (); +/* +#ifdef TEXTEDITOR + if (editormodal) + { + Editor_Draw(); + GLV_UpdatePalette (false); +#if defined(_WIN32) && defined(RGLQUAKE) + Media_RecordFrame(); +#endif + GLR_BrightenScreen(); + + if (key_dest == key_console) + Con_DrawConsole(vid_conheight.value/2, false); + GL_EndRendering (); + GL_DoSwap(); + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } +#endif +*/ + if (Media_ShowFilm()) + { + M_Draw(0); +// GLV_UpdatePalette (false); +#if defined(_WIN32) + Media_RecordFrame(); +#endif +// GLR_BrightenScreen(); + pD3DDev->lpVtbl->EndScene(pD3DDev); + pD3DX->lpVtbl->UpdateFrame((void*)pD3DX, 0); + + pD3DX->lpVtbl->SetClearColor((void*)pD3DX, rand()); + pD3DX->lpVtbl->Clear((void*)pD3DX, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER); + +// pD3DDev->lpVtbl->BeginScene(pD3DDev); + + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + + // + // determine size of refresh window + // + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + nohud = false; + +#ifdef VM_CG + if (CG_Refresh()) + nohud = true; + else +#endif +#ifdef CSQC_DAT + if (cls.state == ca_active && CSQC_DrawView()) + nohud = true; + else +#endif + if (r_worldentity.model && uimenu != 1) + { + V_RenderView (); +// Q1BSP_TestClipDecal(); + } + + + D3D_Set2D (); + +// GLR_BrightenScreen(); + + if (!nohud) + SCR_TileClear (); + + SCR_DrawTwoDimensional(uimenu, nohud); + +// GLV_UpdatePalette (false); +#if defined(_WIN32) && defined(RGLQUAKE) + Media_RecordFrame(); +#endif + + RSpeedEnd(RSPEED_TOTALREFRESH); + RSpeedShow(); + + + + pD3DDev->lpVtbl->EndScene(pD3DDev); + pD3DX->lpVtbl->UpdateFrame((void*)pD3DX, 0); + + + pD3DX->lpVtbl->SetClearColor((void*)pD3DX, rand()); + pD3DX->lpVtbl->Clear((void*)pD3DX, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER); + + + window_center_x = (window_rect.left + window_rect.right)/2; + window_center_y = (window_rect.top + window_rect.bottom)/2; + + + + if (modestate == MS_WINDOWED) + { + extern int mouseusedforgui; + extern qboolean mouseactive; + if (!_windowed_mouse.value) + { + if (mouseactive) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } + else + { + if ((key_dest == key_game||mouseusedforgui) && !mouseactive && ActiveApp) + { + IN_ActivateMouse (); + IN_HideMouse (); + } + else if (mouseactive && key_dest == key_console) + {//!(key_dest == key_game || mouseusedforgui)) { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } + } +} + + + + + +mpic_t *(D3D_Draw_SafePicFromWad) (char *name); +mpic_t *(D3D_Draw_CachePic) (char *path); +mpic_t *(D3D_Draw_SafeCachePic) (char *path); +void (D3D_Draw_Init) (void); +void (D3D_Draw_ReInit) (void); +void (D3D_Draw_Character) (int x, int y, unsigned int num); +void (D3D_Draw_ColouredCharacter) (int x, int y, unsigned int num); +void (D3D_Draw_String) (int x, int y, const qbyte *str); +void (D3D_Draw_Alt_String) (int x, int y, const qbyte *str); +void (D3D_Draw_Crosshair) (void); +void (D3D_Draw_DebugChar) (qbyte num); +void (D3D_Draw_Pic) (int x, int y, mpic_t *pic); +void (D3D_Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic); +void (D3D_Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); +void (D3D_Draw_TransPic) (int x, int y, mpic_t *pic); +void (D3D_Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation); +void (D3D_Draw_ConsoleBackground) (int lines); +void (D3D_Draw_EditorBackground) (int lines); +void (D3D_Draw_TileClear) (int x, int y, int w, int h); +void (D3D_Draw_Fill) (int x, int y, int w, int h, int c); +void (D3D_Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); +void (D3D_Draw_FadeScreen) (void); +void (D3D_Draw_BeginDisc) (void); +void (D3D_Draw_EndDisc) (void); + +void (D3D_Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); //gl-style scaled/coloured/subpic +void (D3D_Draw_ImageColours) (float r, float g, float b, float a); + +void (D3D_R_Init) (void); +void (D3D_R_DeInit) (void); +void (D3D_R_ReInit) (void); +void (D3D_R_RenderView) (void); // must set r_refdef first + +qboolean (D3D_R_CheckSky) (void); +void (D3D_R_SetSky) (char *name, float rotate, vec3_t axis); + +void (D3D_R_NewMap) (void); +void (D3D_R_PreNewMap) (void); +int (D3D_R_LightPoint) (vec3_t point); + +void (D3D_R_PushDlights) (void); +void (D3D_R_AddStain) (vec3_t org, float red, float green, float blue, float radius); +void (D3D_R_LessenStains) (void); + +void (D3D_Media_ShowFrameBGR_24_Flip) (qbyte *framedata, int inwidth, int inheight); //input is bottom up... +void (D3D_Media_ShowFrameRGBA_32) (qbyte *framedata, int inwidth, int inheight); //top down +void (D3D_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette); //paletted topdown (framedata is 8bit indexes into palette) + +void (D3D_Mod_Init) (void); +void (D3D_Mod_ClearAll) (void); +struct model_s *(D3D_Mod_ForName) (char *name, qboolean crash); +struct model_s *(D3D_Mod_FindName) (char *name); +void *(D3D_Mod_Extradata) (struct model_s *mod); // handles caching +void (D3D_Mod_TouchModel) (char *name); + +void (D3D_Mod_NowLoadExternal) (void); +void (D3D_Mod_Think) (void); +qboolean(D3D_Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result); +int (D3D_Mod_TagNumForName) (struct model_s *model, char *name); +int (D3D_Mod_SkinForName) (struct model_s *model, char *name); + + +qboolean (D3D_VID_Init) (rendererstate_t *info, unsigned char *palette); +void (D3D_VID_DeInit) (void); +void (D3D_VID_HandlePause) (qboolean pause); +void (D3D_VID_LockBuffer) (void); +void (D3D_VID_UnlockBuffer) (void); +void (D3D_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height); +void (D3D_D_EndDirectRect) (int x, int y, int width, int height); +void (D3D_VID_ForceLockState) (int lk); +int (D3D_VID_ForceUnlockedAndReturnState) (void); +void (D3D_VID_SetPalette) (unsigned char *palette); +void (D3D_VID_ShiftPalette) (unsigned char *palette); +char *(D3D_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); +void (D3D_VID_SetWindowCaption) (char *msg); + +void (D3D_SCR_UpdateScreen) (void); + + + + + + + +rendererinfo_t d3d7rendererinfo = +{ + "Direct3D7 Native", + { + "D3D7" + }, + QR_DIRECT3D, + + D3D_Draw_SafePicFromWad, + D3D_Draw_CachePic, + D3D_Draw_SafeCachePic, + D3D_Draw_Init, + D3D_Draw_ReInit, + D3D_Draw_Character, + D3D_Draw_ColouredCharacter, + D3D_Draw_String, + D3D_Draw_Alt_String, + D3D_Draw_Crosshair, + D3D_Draw_DebugChar, + D3D_Draw_Pic, + D3D_Draw_ScalePic, + D3D_Draw_SubPic, + D3D_Draw_TransPic, + D3D_Draw_TransPicTranslate, + D3D_Draw_ConsoleBackground, + D3D_Draw_EditorBackground, + D3D_Draw_TileClear, + D3D_Draw_Fill, + D3D_Draw_FillRGB, + D3D_Draw_FadeScreen, + D3D_Draw_BeginDisc, + D3D_Draw_EndDisc, + + D3D_Draw_Image, + D3D_Draw_ImageColours, + + D3D_R_Init, + D3D_R_DeInit, + D3D_R_ReInit, + D3D_R_RenderView, + + D3D_R_CheckSky, + D3D_R_SetSky, + + D3D_R_NewMap, + D3D_R_PreNewMap, + D3D_R_LightPoint, + + D3D_R_PushDlights, + D3D_R_AddStain, + D3D_R_LessenStains, + + D3D_Media_ShowFrameBGR_24_Flip, + D3D_Media_ShowFrameRGBA_32, + D3D_Media_ShowFrame8bit, + + GLMod_Init, + GLMod_ClearAll, + GLMod_ForName, + GLMod_FindName, + GLMod_Extradata, + GLMod_TouchModel, + + GLMod_NowLoadExternal, + GLMod_Think, + D3D_Mod_GetTag, + D3D_Mod_TagNumForName, + D3D_Mod_SkinForName, + + + D3D_VID_Init, + D3D_VID_DeInit, + D3D_VID_HandlePause, + D3D_VID_LockBuffer, + D3D_VID_UnlockBuffer, + D3D_D_BeginDirectRect, + D3D_D_EndDirectRect, + D3D_VID_ForceLockState, + D3D_VID_ForceUnlockedAndReturnState, + D3D_VID_SetPalette, + D3D_VID_ShiftPalette, + D3D_VID_GetRGBInfo, + D3D_VID_SetWindowCaption, + + D3D_SCR_UpdateScreen + +}; +#endif diff --git a/engine/d3d9/d3d9_draw.c b/engine/d3d9/d3d9_draw.c new file mode 100644 index 000000000..6193b9fd2 --- /dev/null +++ b/engine/d3d9/d3d9_draw.c @@ -0,0 +1,821 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3d9quake.h" + +#define MAX_WIDTH 512 +#define MAX_HEIGHT 512 + +void *d3dexplosiontexture; +void *d3dballtexture; + +LPDIRECT3DBASETEXTURE9 d3d9chars_tex; +mpic_t *conback_tex; + +typedef struct d3dcachepic_s +{ + char name[MAX_QPATH]; + mpic_t pic; +} d3dcachepic_t; +#define MAX_CACHED_PICS 512 //a temporary solution +d3dcachepic_t d3dmenu_cachepics[MAX_CACHED_PICS]; +int d3dmenu_numcachepics; + + + +typedef struct { + float x, y, z; + int colour; + float s, t; +} d3dquadvert_t; +d3dquadvert_t d3d9quadvert[4]; +index_t d3d9quadindexes[6] = { + 0, 1, 2, + 0, 2, 3 +}; +//pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2, d3dstate.vertbuf, d3dstate.numverts, d3dstate.indexbuf, d3dstate.numindicies, 0); + + +static void Upload_Texture_32(LPDIRECT3DTEXTURE9 surf, unsigned int *data, int width, int height) +{ + int x, y; + unsigned int *dest; + unsigned char swapbuf[4]; + unsigned char swapbuf2[4]; + D3DLOCKED_RECT lock; + + D3DSURFACE_DESC desc; + IDirect3DTexture9_GetLevelDesc(surf, 0, &desc); + + IDirect3DTexture9_LockRect(surf, 0, &lock, NULL, DDLOCK_NOSYSLOCK|D3DLOCK_READONLY); + + //(surf, NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + + if (width == desc.Width && height == desc.Height) + { +// if (desc.lPitch == twidth*4) +// { +// memcpy(desc.lpSurface, data, width*height*4); +// } +// else + { + for (y = 0; y < height; y++) + { + dest = (unsigned int *)((char *)lock.pBits + lock.Pitch*y); + for (x = 0; x < width; x++) + { + *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x]; + swapbuf[0] = swapbuf2[2]; + swapbuf[2] = swapbuf2[0]; + dest[x] = *(unsigned int*)swapbuf; + } + data += width; + } + } + } + else + { + int x, y; + int iny; + unsigned int *row, *inrow; + + for (y = 0; y < desc.Height; y++) + { + row = (unsigned int*)((char *)lock.pBits + lock.Pitch*y); + iny = (y * height) / desc.Height; + inrow = data + width*iny; + for (x = 0; x < desc.Width; x++) + { + *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.Width]; + swapbuf[0] = swapbuf2[2]; + swapbuf[2] = swapbuf2[0]; + row[x] = *(unsigned int*)swapbuf; + } + } + + + + //mimic opengl and draw it white +// memset(desc.lpSurface, 255, twidth*theight*4); + } + + IDirect3DTexture9_UnlockRect(surf, 0); +} + +void D3D9_MipMap (qbyte *out, qbyte *in, int width, int height) +{ + int i, j; + + width <<=2; + height >>= 1; + for (i=0 ; i>2; + out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2; + out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2; + out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2; + } + } +} + +//create a basic shader from a 32bit image +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags) +{ + int nwidth, nheight; + + LPDIRECT3DTEXTURE9 newsurf; +/* + if (!(flags & TF_MANDATORY)) + { + Con_Printf("Texture upload missing flags\n"); + return NULL; + } +*/ + + nwidth = width; + nheight = height; + GL_RoundDimensions(&nwidth, &nheight, flags & TF_MIPMAP); + + IDirect3DDevice9_CreateTexture(pD3DDev9, nwidth, nheight, 0, 0|((flags & TF_MIPMAP)?D3DUSAGE_AUTOGENMIPMAP:0), D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &newsurf, NULL); + + if (!newsurf) + return NULL; + + Upload_Texture_32(newsurf, data, width, height); + + if (flags & TF_MIPMAP) + IDirect3DBaseTexture9_GenerateMipSubLevels(newsurf); + + return (LPDIRECT3DBASETEXTURE9)newsurf; +} + +//create a basic shader from an 8bit image with 24bit palette +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix) +{ + //just expands it to 32bpp and passes it on + static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4]; + int i; + + if (!(flags & TF_ALPHA)) + transparentpix = 256; + + if (width*height > MAX_WIDTH*MAX_HEIGHT) + Sys_Error("GL_Upload8_Pal24: too big"); + + for (i = width*height; i >= 0 ; i--) + { + out[i][0] = palette[data[i]*3+0]; + out[i][1] = palette[data[i]*3+1]; + out[i][2] = palette[data[i]*3+2]; + out[i][3] = 255*(data[i] != transparentpix); + } + + + return D3D9_LoadTexture_32(name, (unsigned int*)out, width, height, flags); +} + +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette) +{ + //just expands it to 32bpp and passes it on + static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4]; + int i; + + if (width*height > MAX_WIDTH*MAX_HEIGHT) + Sys_Error("GL_Upload8_Pal24: too big"); + + for (i = width*height; i >= 0 ; i--) + { + out[i][0] = palette[data[i]*4+0]; + out[i][1] = palette[data[i]*4+1]; + out[i][2] = palette[data[i]*4+2]; + out[i][3] = palette[data[i]*4+3]; + } + + + return D3D9_LoadTexture_32(name, (unsigned int*)out, width, height, flags); +} + + +void D3D9_UnloadTexture(LPDIRECT3DBASETEXTURE9 tex) +{ + if (tex) + IDirect3DBaseTexture9_Release(tex); +} + + + + + + + + +static qbyte exptexture[16][16] = +{ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0}, + {0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0}, + {0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0}, + {0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0}, + {0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0}, + {0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0}, + {0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0}, + {0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0}, + {0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0}, + {0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0}, + {0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0}, + {0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0}, + {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +}; +void D3D9_InitParticleTexture (void) +{ +#define PARTICLETEXTURESIZE 64 + int x,y; + float dx, dy, d; + qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4]; + +//Explosion texture + + + for (x=0 ; x<16 ; x++) + { + for (y=0 ; y<16 ; y++) + { + data[y*16+x][0] = 255; + data[y*16+x][1] = 255; + data[y*16+x][2] = 255; + data[y*16+x][3] = exptexture[x][y]*255/9.0; + } + } + d3dexplosiontexture = D3D9_LoadTexture_32("", (unsigned int*)data, 16, 16, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP); + + memset(data, 255, sizeof(data)); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dx*dx+dy*dy)); + d = bound(0, d, 255); + data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d; + } + } + + d3dballtexture = D3D9_LoadTexture_32("", (unsigned int*)data, PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP); +} + + + + + + + + + +mpic_t *D3D9_Draw_SafePicFromWad (char *name) +{ + LPDIRECT3DBASETEXTURE9 *p; + d3dcachepic_t *pic; + qpic_t *qpic; + int i; + + for (i = 0; i < d3dmenu_numcachepics; i++) + { + if (!strcmp(d3dmenu_cachepics[i].name, name)) + return &d3dmenu_cachepics[i].pic; + } + + qpic = (qpic_t *)W_SafeGetLumpName (name); + if (qpic) + SwapPic (qpic); + + pic = &d3dmenu_cachepics[d3dmenu_numcachepics]; + + Q_strncpyz (pic->name, name, sizeof(pic->name)); + + p = (LPDIRECT3DBASETEXTURE9*)&pic->pic.data; + if (!strcmp(name, "conchars")) + { + pic->pic.width = 256; + pic->pic.height = 256; + *p = d3d9chars_tex; + } + else if (qpic) + { + pic->pic.width = qpic->width; + pic->pic.height = qpic->height; + + *p = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture(pic->name, "wad", false, true, true); + if (!*p) + *p = D3D9_LoadTexture_8_Pal24(name, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255); + } + else + { + extern int image_width, image_height; + *p = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture(pic->name, "wad", false, true, true); + if (!p) + return NULL; + pic->pic.width = image_width; + pic->pic.height = image_height; + } + + d3dmenu_numcachepics++; + +// Con_Printf("Fixme: D3D9_Draw_SafePicFromWad\n"); + return &pic->pic; +} +mpic_t *D3D9_Draw_SafeCachePic (char *path) +{ + LPDIRECT3DBASETEXTURE9 *p; + d3dcachepic_t *pic; + qpic_t *qpic; + int i; + + + for (i = 0; i < d3dmenu_numcachepics; i++) + { + if (!strcmp(d3dmenu_cachepics[i].name, path)) + return &d3dmenu_cachepics[i].pic; + } + + qpic = (qpic_t *)COM_LoadTempFile (path); + if (qpic) + SwapPic (qpic); + + pic = &d3dmenu_cachepics[d3dmenu_numcachepics]; + + Q_strncpyz (pic->name, path, sizeof(pic->name)); + + p = (LPDIRECT3DBASETEXTURE9*)&pic->pic.data; + + if (qpic) + { + pic->pic.width = qpic->width; + pic->pic.height = qpic->height; + *p = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture(pic->name, "gfx", false, true, true); + if (!*p && qpic) + *p = D3D9_LoadTexture_8_Pal24(path, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255); + } + else + { + extern int image_width, image_height; + *p = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture(pic->name, "gfx", false, true, true); + if (!*p) + { + return NULL; + } + pic->pic.width = image_width; + pic->pic.height = image_height; + } + + d3dmenu_numcachepics++; + +// Con_Printf("Fixme: D3D9_Draw_SafeCachePic\n"); + return &pic->pic; +} +mpic_t *D3D9_Draw_CachePic (char *path) +{ + mpic_t *pic; + pic = D3D9_Draw_SafeCachePic(path); + if (!pic) + Sys_Error("Couldn't load picture %s", path); + return pic; +} +void D3D9_Draw_ReInit (void) +{ + d3dmenu_numcachepics = 0; + + draw_chars = W_SafeGetLumpName ("conchars"); + + d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture("conchars", "gfx", false, true, true); + if (!d3d9chars_tex) + { + if (draw_chars) + d3d9chars_tex = D3D9_LoadTexture_8_Pal24("conchars", draw_chars, 128, 128, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 0); + if (!d3d9chars_tex) + d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false); //try q3 path + if (!d3d9chars_tex) + d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false); //try low res q2 path + } + + + //now emit the conchars picture as if from a wad. + strcpy(d3dmenu_cachepics[d3dmenu_numcachepics].name, "conchars"); + d3dmenu_cachepics[d3dmenu_numcachepics].pic.width = 128; + d3dmenu_cachepics[d3dmenu_numcachepics].pic.height = 128; + *(int *)&d3dmenu_cachepics[d3dmenu_numcachepics].pic.data = (int)d3d9chars_tex; + d3dmenu_numcachepics++; + + + conback_tex = D3D9_Draw_SafeCachePic("gfx/conback.lmp"); + if (!conback_tex) + conback_tex = D3D9_Draw_SafeCachePic("textures/sfx/logo512.jpg"); //try q3 path + if (!conback_tex) + conback_tex = D3D9_Draw_SafeCachePic("pics/conback.pcx"); + + + Plug_DrawReloadImages(); + D3D9_InitParticleTexture(); +} +void D3D9_Draw_Init (void) +{ + D3D9_Draw_ReInit(); +} +void D3D9_Draw_Character (int x, int y, unsigned int num) +{ + int row; + int col; + float frow, fcol, size; + +#define char_instep 0 + num &= 255; + if (num == ' ') + return; + + row = num>>4; + col = num&15; + + frow = row*0.0625+char_instep; + fcol = col*0.0625+char_instep; + size = 0.0625-char_instep*2; + + d3d9quadvert[0].x = x; + d3d9quadvert[0].y = y; + d3d9quadvert[0].z = 0; + d3d9quadvert[0].colour = 0xffffffff; + d3d9quadvert[0].s = fcol; + d3d9quadvert[0].t = frow; + + d3d9quadvert[1].x = x+8; + d3d9quadvert[1].y = y; + d3d9quadvert[1].z = 0; + d3d9quadvert[1].colour = 0xffffffff; + d3d9quadvert[1].s = fcol+size; + d3d9quadvert[1].t = frow; + + d3d9quadvert[2].x = x+8; + d3d9quadvert[2].y = y+8; + d3d9quadvert[2].z = 0; + d3d9quadvert[2].colour = 0xffffffff; + d3d9quadvert[2].s = fcol+size; + d3d9quadvert[2].t = frow+size; + + d3d9quadvert[3].x = x; + d3d9quadvert[3].y = y+8; + d3d9quadvert[3].z = 0; + d3d9quadvert[3].colour = 0xffffffff; + d3d9quadvert[3].s = fcol; + d3d9quadvert[3].t = frow+size; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, d3d9chars_tex); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0])); +} + +void D3D9_Draw_ColouredCharacter (int x, int y, unsigned int num) +{ + int row; + int col; + float frow, fcol, size; + unsigned int imgcolour; + unsigned char *c = (unsigned char *)&imgcolour; + +#define char_instep 0 + + if (num&0xffff == ' ') + return; + + col = (num & CON_FGMASK) >> CON_FGSHIFT; + c[0] = consolecolours[col].fb*255; + c[1] = consolecolours[col].fg*255; + c[2] = consolecolours[col].fr*255; + c[3] = (num & CON_HALFALPHA)?128:255; + + + num &= 0xff; + row = num>>4; + col = num&15; + + frow = row*0.0625+char_instep; + fcol = col*0.0625+char_instep; + size = 0.0625-char_instep*2; + + d3d9quadvert[0].x = x; + d3d9quadvert[0].y = y; + d3d9quadvert[0].z = 0; + d3d9quadvert[0].colour = imgcolour; + d3d9quadvert[0].s = fcol; + d3d9quadvert[0].t = frow; + + d3d9quadvert[1].x = x+8; + d3d9quadvert[1].y = y; + d3d9quadvert[1].z = 0; + d3d9quadvert[1].colour = imgcolour; + d3d9quadvert[1].s = fcol+size; + d3d9quadvert[1].t = frow; + + d3d9quadvert[2].x = x+8; + d3d9quadvert[2].y = y+8; + d3d9quadvert[2].z = 0; + d3d9quadvert[2].colour = imgcolour; + d3d9quadvert[2].s = fcol+size; + d3d9quadvert[2].t = frow+size; + + d3d9quadvert[3].x = x; + d3d9quadvert[3].y = y+8; + d3d9quadvert[3].z = 0; + d3d9quadvert[3].colour = imgcolour; + d3d9quadvert[3].s = fcol; + d3d9quadvert[3].t = frow+size; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, d3d9chars_tex); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0])); +} +void D3D9_Draw_String (int x, int y, const qbyte *str) +{ + while(*str) + { + D3D9_Draw_Character(x, y, *str++); + x+=8; + } +} +void D3D9_Draw_Alt_String (int x, int y, const qbyte *str) +{ + while(*str) + { + D3D9_Draw_Character(x, y, *str++ | 128); + x+=8; + } +} +void D3D9_Draw_Crosshair (void) +{ + D3D9_Draw_Character(vid.width/2 - 4, vid.height/2 - 4, '+'); +} +void D3D9_Draw_DebugChar (qbyte num) +{ + Sys_Error("D3D function not implemented\n"); +} +void D3D9_Draw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation) +{ +// Sys_Error("D3D function not implemented\n"); +} +void D3D9_Draw_TileClear (int x, int y, int w, int h) +{ +// Sys_Error("D3D function not implemented\n"); +} +void D3D9_Draw_Fill_I (int x, int y, int w, int h, unsigned int imgcolour) +{ + d3d9quadvert[0].x = x; + d3d9quadvert[0].y = y; + d3d9quadvert[0].z = 0; + d3d9quadvert[0].colour = imgcolour; + d3d9quadvert[0].s = 0; + d3d9quadvert[0].t = 0; + + d3d9quadvert[1].x = x+w; + d3d9quadvert[1].y = y; + d3d9quadvert[1].z = 0; + d3d9quadvert[1].colour = imgcolour; + d3d9quadvert[1].s = 0; + d3d9quadvert[1].t = 0; + + d3d9quadvert[2].x = x+w; + d3d9quadvert[2].y = y+h; + d3d9quadvert[2].z = 0; + d3d9quadvert[2].colour = imgcolour; + d3d9quadvert[2].s = 0; + d3d9quadvert[2].t = 0; + + d3d9quadvert[3].x = x; + d3d9quadvert[3].y = y+h; + d3d9quadvert[3].z = 0; + d3d9quadvert[3].colour = imgcolour; + d3d9quadvert[3].s = 0; + d3d9quadvert[3].t = 0; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0])); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); +} + +void D3D9_Draw_FillRGB (int x, int y, int w, int h, float r, float g, float b) +{ + char colours[4]; + colours[0] = b*255; + colours[1] = g*255; + colours[2] = r*255; + colours[3] = 255; + + D3D9_Draw_Fill_I(x, y, w, h, *(unsigned int*)colours); +} + +void D3D9_Draw_Fill (int x, int y, int w, int h, int c) +{ + D3D9_Draw_FillRGB(x, y, w, h, host_basepal[c*3+0]/255.0f, host_basepal[c*3+1]/255.0f, host_basepal[c*3+2]/255.0f); +} +void D3D9_Draw_FadeScreen (void) +{ +// Sys_Error("D3D function not implemented\n"); +} +void D3D9_Draw_BeginDisc (void) +{ +// Sys_Error("D3D function not implemented\n"); +} +void D3D9_Draw_EndDisc (void) +{ +// Sys_Error("D3D function not implemented\n"); +} + +static int imgcolour; + +void D3D9_Draw_Fill_Colours (int x, int y, int w, int h) +{ + D3D9_Draw_Fill_I(x, y, w, h, imgcolour); +} + +void D3D9_Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic) +{ + LPDIRECT3DBASETEXTURE9 *p; + if (!conback_tex) + return; + if (!pic) + return; + + d3d9quadvert[0].x = x; + d3d9quadvert[0].y = y; + d3d9quadvert[0].z = 0; + d3d9quadvert[0].colour = imgcolour; + d3d9quadvert[0].s = s1;// - 3.0/pic->width; + d3d9quadvert[0].t = t1; + + d3d9quadvert[1].x = x+w; + d3d9quadvert[1].y = y; + d3d9quadvert[1].z = 0; + d3d9quadvert[1].colour = imgcolour; + d3d9quadvert[1].s = s2;// - 3.0/pic->width; + d3d9quadvert[1].t = t1; + + d3d9quadvert[2].x = x+w; + d3d9quadvert[2].y = y+h; + d3d9quadvert[2].z = 0; + d3d9quadvert[2].colour = imgcolour; + d3d9quadvert[2].s = s2;// - 3.0/pic->width; + d3d9quadvert[2].t = t2; + + d3d9quadvert[3].x = x; + d3d9quadvert[3].y = y+h; + d3d9quadvert[3].z = 0; + d3d9quadvert[3].colour = imgcolour; + d3d9quadvert[3].s = s1;// - 3.0/pic->width; + d3d9quadvert[3].t = t2; + + p = (LPDIRECT3DBASETEXTURE9*)&pic->data; + IDirect3DDevice9_SetTexture(pD3DDev9, 0, *p); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0])); + +} + +void D3D9_Draw_ScalePic (int x, int y, int width, int height, mpic_t *pic) +{ + D3D9_Draw_Image(x, y, width, height, 0, 0, 1, 1, pic); +} +void D3D9_Draw_SubPic (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height) +{ + float s, t; + float sw, tw; + if (!pic) + return; + + s = (float)srcx/pic->width; + t = (float)srcy/pic->height; + sw = (float)width/pic->width; + tw = (float)height/pic->height; + D3D9_Draw_Image(x, y, width, height, s, t, s+sw, t+tw, pic); +} +void D3D9_Draw_TransPic (int x, int y, mpic_t *pic) +{ + if (!pic) + return; + D3D9_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic); +} +void D3D9_Draw_Pic (int x, int y, mpic_t *pic) +{ + if (!pic) + return; + D3D9_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic); +} +void D3D9_Draw_ImageColours (float r, float g, float b, float a) +{ + unsigned char *c = (unsigned char *)&imgcolour; + + c[0] = b*255; + c[1] = g*255; + c[2] = r*255; + c[3] = a*255; +} + +void D3D9_Draw_ConsoleBackground (int lines) +{ + D3D9_Draw_ImageColours(1,1,1,1); + D3D9_Draw_Image(0, 0, vid.width, lines, 0, 1 - (float)lines/vid.height, 1, 1, conback_tex); +} +void D3D9_Draw_EditorBackground (int lines) +{ + D3D9_Draw_ConsoleBackground(lines); +} + + + + +void D3D9_Media_ShowFrameBGR_24_Flip (qbyte *framedata, int inwidth, int inheight) +{ + mpic_t pic; + LPDIRECT3DBASETEXTURE9 *p; + p = (LPDIRECT3DBASETEXTURE9*)&pic.data; + *p = D3D9_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP); + + D3D9_Set2D (); + D3D9_Draw_ImageColours(1,1,1,1); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + D3D9_UnloadTexture(*p); +} //input is bottom up... +void D3D9_Media_ShowFrameRGBA_32 (qbyte *framedata, int inwidth, int inheight) +{ + mpic_t pic; + LPDIRECT3DBASETEXTURE9 *p; + + pic.width = inwidth; + pic.height = inheight; + pic.flags = 0; + p = (LPDIRECT3DBASETEXTURE9*)&pic.data; + *p = D3D9_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP); + + D3D9_Set2D (); + D3D9_Draw_ImageColours(1,1,1,1); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + D3D9_UnloadTexture(*p); +} //top down +void (D3D9_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette) +{ + mpic_t pic; + LPDIRECT3DBASETEXTURE9 *p; + p = (LPDIRECT3DBASETEXTURE9*)&pic.data; + *p = D3D9_LoadTexture_8_Pal24("", (unsigned char*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP, palette, 256); + + D3D9_Set2D (); + D3D9_Draw_ImageColours(1,1,1,1); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + D3D9_UnloadTexture(*p); +} //paletted topdown (framedata is 8bit indexes into palette) +#endif diff --git a/engine/d3d9/d3d9_mesh.c b/engine/d3d9/d3d9_mesh.c new file mode 100644 index 000000000..04b5e7800 --- /dev/null +++ b/engine/d3d9/d3d9_mesh.c @@ -0,0 +1,706 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3d9quake.h" + +#include "com_mesh.h" + +extern cvar_t r_fullbrightSkins; +extern cvar_t r_vertexdlights; + + +typedef struct { + float x, y, z; + float s, t; +} meshvert_t; + +typedef struct { + float x, y, z; + unsigned int colour; + float s, t; +} meshcolouredvert_t; + +void D3D9_DrawMesh(mesh_t *mesh) +{ + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + { + int v; + vec3_t *xyz; + byte_vec4_t *colour; + vec2_t *wm; + xyz = mesh->xyz_array; + wm = mesh->st_array; + colour = mesh->colors_array; + + if (colour) + { + meshcolouredvert_t *meshvert = alloca(sizeof(meshcolouredvert_t)*mesh->numvertexes); + + for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++, colour++) + { + meshvert[v].x = (*xyz)[0]; + meshvert[v].y = (*xyz)[1]; + meshvert[v].z = (*xyz)[2]; + meshvert[v].colour = *(unsigned int*)colour; + meshvert[v].s = (*wm)[0]; + meshvert[v].t = (*wm)[1]; + } + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, mesh->numvertexes, mesh->numindexes/3, mesh->indexes, D3DFMT_QINDEX, meshvert, sizeof(meshvert[0])); + } + else + { + meshvert_t *meshvert = alloca(sizeof(meshvert_t)*mesh->numvertexes); + + for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++) + { + meshvert[v].x = (*xyz)[0]; + meshvert[v].y = (*xyz)[1]; + meshvert[v].z = (*xyz)[2]; + meshvert[v].s = (*wm)[0]; + meshvert[v].t = (*wm)[1]; + } + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, mesh->numvertexes, mesh->numindexes/3, mesh->indexes, D3DFMT_QINDEX, meshvert, sizeof(meshvert[0])); + } + } +} + + + + +hashtable_t skincolourmapped; + +void d3d9_GAliasFlushSkinCache(void) +{ + int i; + bucket_t *b; + for (i = 0; i < skincolourmapped.numbuckets; i++) + { + while((b = skincolourmapped.bucket[i])) + { + skincolourmapped.bucket[i] = b->next; + BZ_Free(b->data); + } + } + if (skincolourmapped.bucket) + BZ_Free(skincolourmapped.bucket); + skincolourmapped.bucket = NULL; + skincolourmapped.numbuckets = 0; +} + +static galiastexnum_t *D3D9_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e) +{ + galiasskin_t *skins; + galiastexnum_t *texnums; + int frame; + + int tc, bc; + int local; + + if (!gl_nocolors.value) + { + if (e->scoreboard) + { + if (!e->scoreboard->skin) + Skin_Find(e->scoreboard); + tc = e->scoreboard->topcolor; + bc = e->scoreboard->bottomcolor; + + //colour forcing + if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen. + { + if (cl.teamplay && cl.spectator) + { + local = Cam_TrackNum(0); + if (local < 0) + local = cl.playernum[0]; + } + else + local = cl.playernum[0]; + if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[local].team)) + { + if (cl_teamtopcolor>=0) + tc = cl_teamtopcolor; + if (cl_teambottomcolor>=0) + bc = cl_teambottomcolor; + } + else + { + if (cl_enemytopcolor>=0) + tc = cl_enemytopcolor; + if (cl_enemybottomcolor>=0) + bc = cl_enemybottomcolor; + } + } + } + else + { + tc = 1; + bc = 1; + } + + if (tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin)) + { + int inwidth, inheight; + int tinwidth, tinheight; + char *skinname; + qbyte *original; + int cc; + galiascolourmapped_t *cm; + char hashname[512]; + cc = (tc<<4)|bc; + + if (e->scoreboard && e->scoreboard->skin && !gl_nocolors.value) + { + snprintf(hashname, sizeof(hashname), "%s$%s$%i", modelname, e->scoreboard->skin->name, surfnum); + skinname = hashname; + } + else if (surfnum) + { + snprintf(hashname, sizeof(hashname), "%s$%i", modelname, surfnum); + skinname = hashname; + } + else + skinname = modelname; + + if (!skincolourmapped.numbuckets) + Hash_InitTable(&skincolourmapped, 256, BZ_Malloc(Hash_BytesForBuckets(256))); + + for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm)) + { + if (cm->colour == cc && cm->skinnum == e->skinnum) + { + return &cm->texnum; + } + } + + if (!inf->numskins) + { + skins = NULL; + texnums = NULL; + } + else + { + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (!skins->texnums) + { + skins = NULL; + texnums = NULL; + } + else + { + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums); + } + } + + //colourmap isn't present yet. + cm = BZ_Malloc(sizeof(*cm)); + Q_strncpyz(cm->name, skinname, sizeof(cm->name)); + Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket); + cm->colour = cc; + cm->skinnum = e->skinnum; + cm->texnum.fullbright = 0; + cm->texnum.base = 0; + + if (!texnums) + { //load just the skin (q2) +/* if (e->scoreboard && e->scoreboard->skin) + { + if (cls.protocol == CP_QUAKE2) + { + original = Skin_Cache32(e->scoreboard->skin); + if (original) + { + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, true, false); + return &cm->texnum; + } + } + else + { + original = Skin_Cache8(e->scoreboard->skin); + if (original) + { + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, true, false); + return &cm->texnum; + } + } + + cm->texnum.base = Mod_LoadHiResTexture(e->scoreboard->skin->name, "skins", true, false, true); + return &cm->texnum; + } +*/ + return NULL; + } + + cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping + if (cls.protocol != CP_QUAKE2 && ((!texnums || !strcmp(modelname, "progs/player.mdl")) && e->scoreboard && e->scoreboard->skin)) + { + original = Skin_Cache8(e->scoreboard->skin); + inwidth = e->scoreboard->skin->width; + inheight = e->scoreboard->skin->height; + } + else + { + original = NULL; + inwidth = 0; + inheight = 0; + } + if (!original) + { + if (skins->ofstexels) + { + original = (qbyte *)skins + skins->ofstexels; + inwidth = skins->skinwidth; + inheight = skins->skinheight; + } + else + { + original = NULL; + inwidth = 0; + inheight = 0; + } + } + tinwidth = skins->skinwidth; + tinheight = skins->skinheight; + if (original) + { + int i, j; + qbyte translate[256]; + unsigned translate32[256]; + static unsigned pixels[512*512]; + unsigned *out; + unsigned frac, fracstep; + + unsigned scaled_width, scaled_height; + qbyte *inrow; + + texnums = &cm->texnum; + + texnums->base = 0; + texnums->fullbright = 0; + + if (gl_max_size.value <= 0) + gl_max_size.value = 512; + + scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512; + scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512; + + for (i=0 ; i<256 ; i++) + translate[i] = i; + + tc<<=4; + bc<<=4; + + for (i=0 ; i<16 ; i++) + { + if (tc < 128) // the artists made some backwards ranges. sigh. + translate[TOP_RANGE+i] = tc+i; + else + translate[TOP_RANGE+i] = tc+15-i; + + if (bc < 128) + translate[BOTTOM_RANGE+i] = bc+i; + else + translate[BOTTOM_RANGE+i] = bc+15-i; + } + + + for (i=0 ; i<256 ; i++) + translate32[i] = d_8to24rgbtable[translate[i]]; + + out = pixels; + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i> 1; + for (j=0 ; j>16]] | 0xff000000; + frac += fracstep; + out[j+1] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + out[j+2] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + out[j+3] = translate32[inrow[frac>>16]] | 0xff000000; + frac += fracstep; + } + } + texnums->base = D3D9_LoadTexture_32 ("", pixels, scaled_width, scaled_height, TF_NOTBUMPMAP); +/* texnums->base = texture_extension_number++; + GL_Bind(texnums->base); + qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +*/ + + //now do the fullbrights. + out = pixels; + fracstep = tinwidth*0x10000/scaled_width; + for (i=0 ; i> 1; + for (j=0 ; j>16] < 255-vid.fullbright) + ((char *) (&out[j]))[3] = 0; //alpha 0 + frac += fracstep; + } + } +/* texnums->fullbright = texture_extension_number++; + GL_Bind(texnums->fullbright); + qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +*/ + } + else + { + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + + if (!inf->numskins || !skins->texnums) + return NULL; + + frame = cl.time*skins->skinspeed; + frame = frame%skins->texnums; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + memcpy(&cm->texnum, texnums, sizeof(cm->texnum)); + } + return &cm->texnum; + } + } + + if (!inf->numskins) + return NULL; + + skins = (galiasskin_t*)((char *)inf + inf->ofsskins); + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + else + { + Con_DPrintf("Skin number out of range\n"); + if (!inf->numskins) + return NULL; + } + + if (!skins->texnums) + return NULL; + + frame = cl.time*skins->skinspeed; + frame = frame%skins->texnums; + texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + + return texnums; +} + + +extern vec3_t shadevector; +extern vec3_t ambientlight; +extern vec3_t shadelight; + +static void LotsOfLightDirectionHacks(entity_t *e, model_t *m, vec3_t lightaxis[3]) +{ + int i; + vec3_t dist; + float add; + qboolean nolightdir; + vec3_t lightdir; + + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + { + if (e->flags & Q2RF_WEAPONMODEL) + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir); + else + cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir); + } + else + { + ambientlight[0] = ambientlight[1] = ambientlight[2] = shadelight[0] = shadelight[1] = shadelight[2] = 255; + lightdir[0] = 0; + lightdir[1] = 1; + lightdir[2] = 1; + } + + if (!r_vertexdlights.value) + { + for (i=0 ; iorigin, + cl_dlights[i].origin, + dist); + add = cl_dlights[i].radius - Length(dist); + + if (add > 0) { + add*=5; + ambientlight[0] += add * cl_dlights[i].color[0]; + ambientlight[1] += add * cl_dlights[i].color[1]; + ambientlight[2] += add * cl_dlights[i].color[2]; + //ZOID models should be affected by dlights as well + shadelight[0] += add * cl_dlights[i].color[0]; + shadelight[1] += add * cl_dlights[i].color[1]; + shadelight[2] += add * cl_dlights[i].color[2]; + } + } + } + } + else + { + } + + for (i = 0; i < 3; i++) //clamp light so it doesn't get vulgar. + { + if (ambientlight[i] > 128) + ambientlight[i] = 128; + if (ambientlight[i] + shadelight[i] > 192) + shadelight[i] = 192 - ambientlight[i]; + } + + if (e->flags & Q2RF_WEAPONMODEL) + { + for (i = 0; i < 3; i++) + { + if (ambientlight[i] < 24) + ambientlight[i] = shadelight[i] = 24; + } + } + +//MORE HUGE HACKS! WHEN WILL THEY CEASE! + // clamp lighting so it doesn't overbright as much + // ZOID: never allow players to go totally black + nolightdir = false; + if (m->engineflags & MDLF_PLAYER) + { + float fb = r_fullbrightSkins.value; + if (fb > cls.allow_fbskins) + fb = cls.allow_fbskins; + if (fb < 0) + fb = 0; + if (fb) + { + extern cvar_t r_fb_models; + + if (fb >= 1 && r_fb_models.value) + { + ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; + shadelight[0] = shadelight[1] = shadelight[2] = 4096; + nolightdir = true; + } + else + { + for (i = 0; i < 3; i++) + { + ambientlight[i] = max(ambientlight[i], 8 + fb * 120); + shadelight[i] = max(shadelight[i], 8 + fb * 120); + } + } + } + for (i = 0; i < 3; i++) + { + if (ambientlight[i] < 8) + ambientlight[i] = shadelight[i] = 8; + } + } + if (m->engineflags & MDLF_FLAME) + { + shadelight[0] = shadelight[1] = shadelight[2] = 4096; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; + nolightdir = true; + } + else + { + for (i = 0; i < 3; i++) + { + if (ambientlight[i] > 128) + ambientlight[i] = 128; + + shadelight[i] /= 200.0/255; + ambientlight[i] /= 200.0/255; + } + } + + if ((e->drawflags & MLS_MASKIN) == MLS_ABSLIGHT) + { + shadelight[0] = shadelight[1] = shadelight[2] = e->abslight; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + } + if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) + { + shadelight[0] = shadelight[1] = shadelight[2] = 255; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + nolightdir = true; + } + +//#define SHOWLIGHTDIR + { //lightdir is absolute, shadevector is relative + shadevector[0] = DotProduct(lightdir, e->axis[0]); + shadevector[1] = DotProduct(lightdir, e->axis[1]); + shadevector[2] = DotProduct(lightdir, e->axis[2]); + + if (e->flags & Q2RF_WEAPONMODEL) + { + vec3_t temp; + temp[0] = DotProduct(shadevector, vpn); + temp[1] = DotProduct(shadevector, vright); + temp[2] = DotProduct(shadevector, vup); + + VectorCopy(temp, shadevector); + } + + VectorNormalize(shadevector); + + VectorCopy(shadevector, lightaxis[2]); + VectorVectors(lightaxis[2], lightaxis[1], lightaxis[0]); + VectorInverse(lightaxis[1]); + } + + if (e->flags & Q2RF_GLOW) + { + shadelight[0] += sin(cl.time)*0.25; + shadelight[1] += sin(cl.time)*0.25; + shadelight[2] += sin(cl.time)*0.25; + } + + //d3d is bgra + //ogl is rgba + //so switch em and use the gl code + add = shadelight[0]; + shadelight[0] = shadelight[2]; + shadelight[2] = add; + + add = ambientlight[0]; + ambientlight[0] = ambientlight[2]; + ambientlight[2] = add; +} + + +qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int frame2, float lerp, float alpha, float fg1time, float fg2time, qboolean nolightdir); +//draws currententity +void D3D9_DrawAliasModel(void) +{ + mesh_t mesh; + extern entity_t *currententity; + entity_t *e = currententity; + galiasinfo_t *inf; + model_t *m; + galiastexnum_t *skin; + int i; + + if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL) + return; + + { + extern int cl_playerindex; + if (e->scoreboard && e->model == cl.model_precache[cl_playerindex]) + { + m = e->scoreboard->model; + if (!m || m->type != mod_alias) + m = e->model; + } + else + m = e->model; + } + + if (!(e->flags & Q2RF_WEAPONMODEL)) + if (R_CullEntityBox (e, m->mins, m->maxs)) + return; + + + inf = GLMod_Extradata (m); + + if (!inf) + return; + + + LotsOfLightDirectionHacks(e, m, mesh.lightaxis); + + + { + float matrix[16]; + + if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0) + { //view weapons need to be rotated onto the screen first + float view[16]; + float ent[16]; + Matrix4_ModelMatrixFromAxis(view, cl.viewent[r_refdef.currentplayernum].axis[0], cl.viewent[r_refdef.currentplayernum].axis[1], cl.viewent[r_refdef.currentplayernum].axis[2], cl.viewent[r_refdef.currentplayernum].origin); + Matrix4_ModelMatrixFromAxis(ent, e->axis[0], e->axis[1], e->axis[2], e->origin); + Matrix4_Multiply(view, ent, matrix); + } + else + { + Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); + } + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + } + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + +if (e->flags & Q2RF_DEPTHHACK) +{ //apply the depth hack to stop things from poking into walls. + //(basically moving it closer to the screen) + D3DVIEWPORT9 viewport; + IDirect3DDevice9_GetViewport(pD3DDev9, &viewport); + viewport.MinZ = 0; + viewport.MaxZ = 0.3; + IDirect3DDevice9_SetViewport(pD3DDev9, &viewport); +} + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + for(i = 0;; i++) + { + R_GAliasBuildMesh(&mesh, inf, e->frame, e->oldframe, e->lerpfrac, e->shaderRGBAf[3], e->frame1time, e->frame2time, 0); + + skin = D3D9_ChooseSkin(inf, m->name, e->skinnum, e); + if (!skin) + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + else + IDirect3DDevice9_SetTexture(pD3DDev9, 0, skin->base); + D3D9_DrawMesh(&mesh); + + if (inf->nextsurf == 0) + break; + inf = (galiasinfo_t*)((char*)inf + inf->nextsurf); + } + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + +if (e->flags & Q2RF_DEPTHHACK) +{ + D3DVIEWPORT9 viewport; + IDirect3DDevice9_GetViewport(pD3DDev9, &viewport); + viewport.MinZ = 0; + viewport.MaxZ = 1; + IDirect3DDevice9_SetViewport(pD3DDev9, &viewport); +} + + { + float matrix[16]; + Matrix4_Identity(matrix); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + } +} +#endif diff --git a/engine/d3d9/d3d9_rmain.c b/engine/d3d9/d3d9_rmain.c new file mode 100644 index 000000000..6ef62765e --- /dev/null +++ b/engine/d3d9/d3d9_rmain.c @@ -0,0 +1,1874 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3d9quake.h" + +mleaf_t *r_viewleaf, *r_oldviewleaf; +mleaf_t *r_viewleaf2, *r_oldviewleaf2; +int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; +extern qbyte areabits[MAX_Q2MAP_AREAS/8]; + + +int r_visframecount; +entity_t r_worldentity; +refdef_t r_refdef; +vec3_t r_origin, vpn, vright, vup; +extern float r_projection_matrix[16]; +extern float r_view_matrix[16]; + + +extern mplane_t frustum[4]; + +vec3_t modelorg; + +entity_t *currententity; +extern cvar_t gl_mindist; + + +void (D3D9_R_DeInit) (void) +{ + int i; + +#ifdef Q3SHADERS + Shader_Shutdown(); +#endif + + + for (i = 0; i < numlightmaps; i++) + { + if (!lightmap[i]) + break; + BZ_Free(lightmap[i]); + lightmap[i] = NULL; + } + + if (lightmap_d3d9textures) + BZ_Free(lightmap_d3d9textures); + if (lightmap) + BZ_Free(lightmap); + + lightmap_d3d9textures=NULL; + lightmap=NULL; + numlightmaps=0; +} +void (D3D9_R_ReInit) (void) +{ +} +void (D3D9_R_Init) (void) +{ + D3D9_R_ReInit(); +} + +//most of this is a direct copy from gl +void (D3D9_SetupFrame) (void) +{ + mleaf_t *leaf; + vec3_t temp; + + GLR_AnimateLight(); + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + VectorCopy (r_refdef.vieworg, r_origin); + r_framecount++; + + if (r_refdef.flags & Q2RDF_NOWORLDMODEL) + { + } +#ifdef Q2BSPS + else if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)) + { + static mleaf_t fakeleaf; + mleaf_t *leaf; + + r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps. + r_viewleaf->contents = Q1CONTENTS_EMPTY; + r_viewleaf2 = NULL; + + r_oldviewcluster = r_viewcluster; + r_oldviewcluster2 = r_viewcluster2; + leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + r_viewcluster = r_viewcluster2 = leaf->cluster; + + // check above and below so crossing solid water doesn't draw wrong + if (!leaf->contents) + { // look down a bit + vec3_t temp; + + VectorCopy (r_origin, temp); + temp[2] -= 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if ( !(leaf->contents & Q2CONTENTS_SOLID) && + (leaf->cluster != r_viewcluster2) ) + r_viewcluster2 = leaf->cluster; + } + else + { // look up a bit + vec3_t temp; + + VectorCopy (r_origin, temp); + temp[2] += 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if ( !(leaf->contents & Q2CONTENTS_SOLID) && + (leaf->cluster != r_viewcluster2) ) + r_viewcluster2 = leaf->cluster; + } + } +#endif + else + { + r_oldviewleaf = r_viewleaf; + r_oldviewleaf2 = r_viewleaf2; + r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + + if (!r_viewleaf) + { + } + else if (r_viewleaf->contents == Q1CONTENTS_EMPTY) + { //look down a bit + VectorCopy (r_origin, temp); + temp[2] -= 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA) + { //in water, look up a bit. + + VectorCopy (r_origin, temp); + temp[2] += 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents == Q1CONTENTS_EMPTY) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else + r_viewleaf2 = NULL; + + if (r_viewleaf) + V_SetContentsColor (r_viewleaf->contents); + } +} + +void D3D9_SetupViewPort(void) +{ + float screenaspect; + int glwidth = vid.width, glheight=vid.height; + int x, x2, y2, y, w, h; + + float fov_x, fov_y; + + D3DVIEWPORT9 vport; + + D3D9_GetBufferSize(&glwidth, &glheight); + + // + // set up viewpoint + // + x = r_refdef.vrect.x * glwidth/(int)vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width; + y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height; + y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height; + + // fudge around because of frac screen scale + if (x > 0) + x--; + if (x2 < glwidth) + x2++; + if (y < 0) + y--; + if (y2 < glheight) + y2++; + + w = x2 - x; + h = y2 - y; + +/* if (envmap) + { + x = y2 = 0; + w = h = 256; + } +*/ + + vport.X = x; + vport.Y = y; + vport.Width = w; + vport.Height = h; + vport.MinZ = 0; + vport.MaxZ = 1; + IDirect3DDevice9_SetViewport(pD3DDev9, &vport); + + fov_x = r_refdef.fov_x;//+sin(cl.time)*5; + fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; + + if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER) + { + fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + } + + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; +// if (r_refdef.useperspective) + { +/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp) + { + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; + // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; + // MYgluPerspective (yfov, screenaspect, 4, 4096); + MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value); + } + else*/ + { + GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value); + } + } +/* else + { + if (gl_maxdist.value>=1) + GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value); + else + GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999); + }*/ + + Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg); + + + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_projection_matrix); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_view_matrix); + + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZENABLE, D3DZB_TRUE); +} + + + + + + +qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer); + + + +//fixme: direct copy from gl (apart from lightmaps) +static void D3D9_RecursiveWorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int shift; + +start: + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = r_framecount; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + D3D9_RecursiveWorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + shift = 0;//GLR_LightmapShift(cl.worldmodel); + +// if (dot < 0 -BACKFACE_EPSILON) +// side = SURF_PLANEBACK; +// else if (dot > BACKFACE_EPSILON) +// side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + +// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) +// continue; // wrong side + + D3DR_RenderDynamicLightmaps (surf, shift); + // if sorting by texture, just store it out +/* if (surf->flags & SURF_DRAWALPHA) + { // add to the translucent chain + surf->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = surf; + surf->ownerent = &r_worldentity; + } + else +*/ { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + +// recurse down the back side +// D3D9_RecursiveWorldNode (node->children[!side]); + node = node->children[!side]; + goto start; +} + +//fixme: direct copy from gl (apart from lightmaps) +static void D3D9_RecursiveQ2WorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int shift; + +start: + + if (node->contents == Q2CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = r_framecount; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + D3D9_RecursiveQ2WorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + shift = 0;//GLR_LightmapShift(cl.worldmodel); + +// if (dot < 0 -BACKFACE_EPSILON) +// side = SURF_PLANEBACK; +// else if (dot > BACKFACE_EPSILON) +// side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + +// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) +// continue; // wrong side + + D3DR_RenderDynamicLightmaps (surf, shift); + // if sorting by texture, just store it out +/* if (surf->flags & SURF_DRAWALPHA) + { // add to the translucent chain + surf->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = surf; + surf->ownerent = &r_worldentity; + } + else +*/ { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + +// recurse down the back side +// D3D9_RecursiveWorldNode (node->children[!side]); + node = node->children[!side]; + goto start; +} + +#ifdef Q3BSPS +extern mleaf_t *r_vischain; // linked list of visible leafs +static void D3D9_LeafWorldNode (void) +{ + int i; + int clipflags; + msurface_t **mark, *surf; + mleaf_t *pleaf; + + + int clipped; + mplane_t *clipplane; + + + for ( pleaf = r_vischain; pleaf; pleaf = pleaf->vischain ) + { + // check for door connected areas +// if ( areabits ) + { +// if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) +// { +// continue; // not visible +// } + } + + clipflags = 15; // 1 | 2 | 4 | 8 +// if ( !r_nocull->value ) + { + + for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) + { + clipped = BoxOnPlaneSide ( pleaf->minmaxs, pleaf->minmaxs+3, clipplane ); + if ( clipped == 2 ) { + break; + } else if ( clipped == 1 ) { + clipflags &= ~(1<nummarksurfaces; + mark = pleaf->firstmarksurface; + + do + { + surf = *mark++; + if ( surf->visframe != r_framecount ) //sufraces exist in multiple leafs. + { + surf->visframe = r_framecount; + + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } while (--i); + +// c_world_leafs++; + } +} +#endif + +struct { + float x, y, z; +// unsigned colour; + float wms, wmt; + float lms, lmt; +} worldvert[1024]; +void D3D9_DrawTextureChains(void) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + int lmnum; + extern int skytexturenum; // index in cl.loadmodel, not gl texture object + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + + if (skytexturenum>=0) + { + t = currentmodel->textures[skytexturenum]; + if (t) + { + s = t->texturechain; + if (s) + { + t->texturechain = NULL; + D3D9_DrawSkyChain (s); + } + } + } + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + for (i = 0; i < currentmodel->numtextures; i++) + { + t = currentmodel->textures[i]; + if (!t) + continue; //happens on e1m2 + s = t->texturechain; + if (!s) + continue; + t->texturechain = NULL; + + if (s->flags & SURF_DRAWTURB) + { + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->gl_texturenum); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); +IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->gl_texturenum); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); +IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)t->gl_texturenum); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + + while(s) + { + m = s->mesh; + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; + // worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0] + cl.time*0.2; + worldvert[v].wmt = (*wm)[1] + cl.time*0.2 + 0.5; + worldvert[v].lms = (*wm)[0] + cl.time*0.1; + worldvert[v].lmt = (*wm)[1] + cl.time*0.1; + } + + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); + + s = s->texturechain; + } + lmnum = -4; + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + + continue; + } + +IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->gl_texturenum); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + while(s) + { + m = s->mesh; + if (m) + { + + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { + if (lightmap[lmnum]->modified) + { + D3DLOCKED_RECT desc; + + IDirect3DTexture9_LockRect(lightmap_d3d9textures[lmnum], 0, &desc, NULL, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS); + memcpy(desc.pBits, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + IDirect3DTexture9_UnlockRect(lightmap_d3d9textures[lmnum], NULL); + + lightmap[lmnum]->modified = false; + } + + + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + +//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + if (!wm || !lm) + { + s = s->texturechain; + continue; + } + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); +// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + s = s->texturechain; + } + } + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} + +void D3D9_BaseBModelTextures(entity_t *e) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + float matrix[16]; + int lmnum = -1; + currentmodel = e->model; + + + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + { + m = s->mesh; + if (m) + D3DR_RenderDynamicLightmaps (s, 0); + } + } + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + if (s->lightmaptexturenum < 0) + continue; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->gl_texturenum); + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[s->lightmaptexturenum]); + { + m = s->mesh; + if (m) + { + + if (lmnum != s->lightmaptexturenum) + { + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { +#if 0 + if (lightmap[lmnum]->modified) + { + DDSURFACEDESC2 desc; + + desc.dwSize = sizeof(desc); + lightmap_d3d9textures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + lightmap_d3d9textures[lmnum]->lpVtbl->Unlock(lightmap_d3d9textures[lmnum], NULL); + + lightmap[lmnum]->modified = false; + } +#endif + + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + } + + + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); +// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + } + } + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} + + + +typedef struct { + float pos[3]; + int colour; + float tc[2]; +} d3dvert_t; +/* +================ +R_GetSpriteFrame +================ +*/ +/* +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = currententity->model->cache.data; + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else if (psprite->frames[frame].type == SPR_ANGLED) + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7]; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = currententity->frame1time; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} +*/ +static void D3D9_DrawSpriteModel (entity_t *e) +{ + vec3_t point; + mspriteframe_t *frame; + vec3_t forward, right, up; + msprite_t *psprite; + qbyte coloursb[4]; + + d3dvert_t d3dvert[4]; + index_t vertindexes[6] = { + 0, 1, 2, + 0, 2, 3 + }; + + if (e->forcedshader || !e->model) + { + int colour; + mpic_t *pic = e->forcedshader; + + colour = 0; + + ((unsigned char*)&colour)[0] = e->shaderRGBAf[2]*255; + ((unsigned char*)&colour)[1] = e->shaderRGBAf[1]*255; + ((unsigned char*)&colour)[2] = e->shaderRGBAf[0]*255; + ((unsigned char*)&colour)[3] = e->shaderRGBAf[3]*255; + + VectorCopy(vup, up); + VectorCopy(vright, right); + + up[0]*=e->scale; + up[1]*=e->scale; + up[2]*=e->scale; + right[0]*=e->scale; + right[1]*=e->scale; + right[2]*=e->scale; + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE); + + if (pic) + IDirect3DDevice9_SetTexture(pD3DDev9, 0, *(LPDIRECT3DBASETEXTURE9*)&pic->data); + else + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); + + d3dvert[0].colour = colour; + d3dvert[0].tc[0] = 0; + d3dvert[0].tc[1] = 1; + VectorMA (e->origin, -1, up, point); + VectorMA (point, -1, right, d3dvert[0].pos); + + d3dvert[1].colour = colour; + d3dvert[1].tc[0] = 0; + d3dvert[1].tc[0] = 0; + VectorMA (e->origin, 1, up, point); + VectorMA (point, -1, right, d3dvert[1].pos); + + d3dvert[2].colour = colour; + d3dvert[2].tc[0] = 1; + d3dvert[2].tc[1] = 0; + VectorMA (e->origin, 1, up, point); + VectorMA (point, 1, right, d3dvert[2].pos); + + d3dvert[3].colour = colour; + d3dvert[3].tc[0] = 1; + d3dvert[3].tc[1] = 1; + VectorMA (e->origin, -1, up, point); + VectorMA (point, 1, right, d3dvert[3].pos); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); + + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + + return; + } + + if (!e->model) + return; + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); + + // don't even bother culling, because it's just a single + // polygon without a surface cache + frame = R_GetSpriteFrame (e); + if (!frame) + return; + psprite = e->model->cache.data; +// frame = 0x05b94140; + + switch(psprite->type) + { + case SPR_ORIENTED: + // bullet marks on walls + AngleVectors (e->angles, forward, right, up); + break; + + case SPR_FACING_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + right[0] = e->origin[1] - r_origin[1]; + right[1] = -(e->origin[0] - r_origin[0]); + right[2] = 0; + VectorNormalize (right); + break; + case SPR_VP_PARALLEL_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + VectorCopy (vright, right); + break; + + default: + case SPR_VP_PARALLEL: + //normal sprite + VectorCopy(vup, up); + VectorCopy(vright, right); + break; + } + up[0]*=e->scale; + up[1]*=e->scale; + up[2]*=e->scale; + right[0]*=e->scale; + right[1]*=e->scale; + right[2]*=e->scale; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)frame->gl_texturenum); + +/* { + extern int gldepthfunc; + qglDepthFunc(gldepthfunc); + qglDepthMask(0); + if (gldepthmin == 0.5) + qglCullFace ( GL_BACK ); + else + qglCullFace ( GL_FRONT ); + + GL_TexEnv(GL_MODULATE); + + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_ALPHA_TEST); + qglDisable(GL_BLEND); + }*/ + +/* if (e->flags & Q2RF_ADDATIVE) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + qglEnable (GL_ALPHA_TEST); +*/ + + d3dvert[0].colour = 0xffffffff; + d3dvert[0].tc[0] = 0; + d3dvert[0].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->left, right, d3dvert[0].pos); + + d3dvert[1].colour = 0xffffffff; + d3dvert[1].tc[0] = 0; + d3dvert[1].tc[0] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->left, right, d3dvert[1].pos); + + d3dvert[2].colour = 0xffffffff; + d3dvert[2].tc[0] = 1; + d3dvert[2].tc[1] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->right, right, d3dvert[2].pos); + + d3dvert[3].colour = 0xffffffff; + d3dvert[3].tc[0] = 1; + d3dvert[3].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->right, right, d3dvert[3].pos); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); + + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + +// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! +// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +//================================================================================== + +void D3D9R_DrawSprite(void *e, void *parm) +{ + currententity = e; + + D3D9_DrawSpriteModel (currententity); + +// P_FlushRenderer(); +} + + + +qboolean D3D9_ShouldDraw(void) +{ + { + if (currententity->flags & Q2RF_EXTERNALMODEL) + return false; +// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) +// return false; +// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) +// continue; + if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1)) + return false; + } + return true; +} + + +void D3D9_R_DrawEntitiesOnList (void) +{ + int i; + + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; irtype) + { + case RT_SPRITE: + RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); + continue; +#ifdef Q3SHADERS + case RT_BEAM: + case RT_RAIL_RINGS: + case RT_LIGHTNING: +// R_DrawLightning(currententity); + continue; + case RT_RAIL_CORE: +// R_DrawRailCore(currententity); + continue; +#endif + case RT_MODEL: //regular model + break; + case RT_PORTALSURFACE: + continue; //this doesn't do anything anyway, does it? + default: + case RT_POLY: //these are a little painful, we need to do them some time... just not yet. + continue; + } + if (currententity->flags & Q2RF_BEAM) + { +// R_DrawBeam(currententity); + continue; + } + if (!currententity->model) + continue; + + + if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static + { +/* if (gl_part_flame.value) + { + if (currententity->model->engineflags & MDLF_ENGULPHS) + continue; + }*/ + } + + switch (currententity->model->type) + { + + case mod_alias: +// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D9_DrawAliasModel (); + break; + +#ifdef HALFLIFEMODELS + case mod_halflife: + R_DrawHLModel (currententity); + break; +#endif + + case mod_brush: +// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D9_BaseBModelTextures (currententity); + break; + + case mod_sprite: + RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); + break; +/* +#ifdef TERRAIN + case mod_heightmap: + D3D9_DrawHeightmapModel(currententity); + break; +#endif +*/ + default: + break; + } + } + + { + float m_identity[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m_identity); + } +} + +void D3D9_DrawWorld(void) +{ + RSpeedLocals(); + entity_t ent; + + memset (&ent, 0, sizeof(ent)); + ent.model = cl.worldmodel; + currentmodel = cl.worldmodel; + + VectorCopy (r_refdef.vieworg, modelorg); + + currententity = &ent; +#ifdef TERRAIN + if (currentmodel->type == mod_heightmap) + GL_DrawHeightmapModel(currententity); + else +#endif + { +// qglColor3f (1,1,1); + //#ifdef QUAKE2 +// R_ClearSkyBox (); + //#endif + + RSpeedRemark(); + +#ifdef Q2BSPS + if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3) + { + int leafnum; + int clientarea; +#ifdef QUAKE2 + if (cls.protocol == CP_QUAKE2) //we can get server sent info + memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); + else +#endif + { //generate the info each frame. + leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); + clientarea = CM_LeafArea (cl.worldmodel, leafnum); + CM_WriteAreaBits(cl.worldmodel, areabits, clientarea); + } +#ifdef Q3BSPS + if (ent.model->fromgame == fg_quake3) + { + D3D9_LeafWorldNode (); + } + else +#endif + D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes); + } + else +#endif + D3D9_RecursiveWorldNode (cl.worldmodel->nodes); + + RSpeedEnd(RSPEED_WORLDNODE); + TRACE(("dbg: calling PPL_DrawWorld\n")); +// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) + D3D9_DrawTextureChains(); +// else +// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg); + + +//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// GLR_LessenStains(); + } +} + +void D3D9_R_RenderScene(void) +{ + if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) + r_refdef.flags |= Q2RDF_NOWORLDMODEL; + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + { + R_MarkLeaves (); // done here so we know if we're in water + D3D9_DrawWorld (); // adds static entities to the list + } + + D3D9_R_DrawEntitiesOnList (); + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + P_DrawParticles(); + + D3D9_Set2D(); +} + +void (D3D9_R_RenderView) (void) +{ + D3D9_SetupFrame(); + D3D9_SetupViewPort(); + R_SetFrustum(); + D3D9_R_RenderScene(); +} + + + +#include "particles.h" + +#define APPLYD3D9BLEND(bm) \ + switch (bm) \ + { \ + case BM_ADD: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_ONE); \ + break; \ + case BM_SUBTRACT: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLENDCOLOUR: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLEND: \ + default: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ + break; \ + } + + +typedef struct d3dparticlevert_s { + float org[3]; + unsigned int colour; + float s, t; //these could actually be preinitialised +} d3dparticlevert_t; +d3dparticlevert_t d3dparticlevert[4]; + +typedef struct d3dparticlevertut_s { + float org[3]; + unsigned int colour; +} d3dparticlevertut_t; +d3dparticlevertut_t d3dparticlevertut[4]; + +part_type_t *lastd3dtype; +static vec3_t pright, pup; +static float particletime; + +void IDirect3DDevice9_DrawIndexedPrimitive7(LPDIRECT3DDEVICE9 pD3DDev9, int mode, int fvf, void *verts, int numverts, index_t *indicies, int numindicies, int wasted) +{ + int size = 0; + if (fvf & D3DFVF_XYZ) + size += 12; + if (fvf & D3DFVF_DIFFUSE) + size += 4; + if (fvf & D3DFVF_TEX1) + size += 8; + + IDirect3DDevice9_SetFVF(pD3DDev9, fvf); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, mode, 0, numverts, numindicies/3, indicies, D3DFMT_QINDEX, verts, size); +} + +index_t d3d9particlevertindexes[] = +{ + 0, 1, 2, + 0, 2, 3 +}; + +void D3D9_DrawParticleBlob(particle_t *p, part_type_t *type) +{ + float scale; + float x; + float y; + unsigned int colour; + int cb, cg, cr, ca; + if (lastd3dtype != type) + { + lastd3dtype = type; + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + } + + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.25; + else + scale = 0.25 + scale * 0.001; + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + if (p->angle) + { + x = sin(p->angle)*scale; + y = cos(p->angle)*scale; + } + else + { + x = 0; + y = scale; + } + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + d3dparticlevert[0].org[0] = p->org[0] - x*pright[0] - y*pup[0]; + d3dparticlevert[0].org[1] = p->org[1] - x*pright[1] - y*pup[1]; + d3dparticlevert[0].org[2] = p->org[2] - x*pright[2] - y*pup[2]; + + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + d3dparticlevert[1].org[0] = p->org[0] - y*pright[0] + x*pup[0]; + d3dparticlevert[1].org[1] = p->org[1] - y*pright[1] + x*pup[1]; + d3dparticlevert[1].org[2] = p->org[2] - y*pright[2] + x*pup[2]; + + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + d3dparticlevert[2].org[0] = p->org[0] + x*pright[0] + y*pup[0]; + d3dparticlevert[2].org[1] = p->org[1] + x*pright[1] + y*pup[1]; + d3dparticlevert[2].org[2] = p->org[2] + x*pright[2] + y*pup[2]; + + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + d3dparticlevert[3].org[0] = p->org[0] + y*pright[0] - x*pup[0]; + d3dparticlevert[3].org[1] = p->org[1] + y*pright[1] - x*pup[1]; + d3dparticlevert[3].org[2] = p->org[2] + y*pright[2] - x*pup[2]; + + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); +} +void D3D9_DrawParticleSpark(particle_t *p, part_type_t *type) +{ + vec3_t v, crv, o2; + + unsigned int colour; + int cb, cg, cr, ca; + + if (lastd3dtype != type) + { + lastd3dtype = type; + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + } + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + VectorSubtract(r_refdef.vieworg, p->org, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(p->org, -p->scale/2, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(p->org, p->scale/2, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + VectorMA(p->org, 0.1, p->vel, o2); + + VectorSubtract(r_refdef.vieworg, o2, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(o2, p->scale/2, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(o2, -p->scale/2, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); +} +void D3D9_DrawParticleBeam(beamseg_t *b, part_type_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + + if (lastd3dtype != type) + { + lastd3dtype = type; + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + } + + + + + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(q->org, -q->scale, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = ts; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = ts; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(p->org, p->scale, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = ts; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = ts; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); +} + +void D3D9_DrawParticleBeamUT(beamseg_t *b, part_type_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + +// D3D_DrawParticleBeam(b, type); +// return; + + if (lastd3dtype != type) + { + lastd3dtype = type; + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + + + APPLYD3D9BLEND(type->blendmode); + } + + + + + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(q->org, -q->scale, crv, d3dparticlevertut[0].org); + d3dparticlevertut[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevertut[1].org); + d3dparticlevertut[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(p->org, p->scale, crv, d3dparticlevertut[2].org); + d3dparticlevertut[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevertut[3].org); + d3dparticlevertut[3].colour = colour; + + + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE, d3dparticlevertut, 4, d3d9particlevertindexes, 6, 0); +} + + + + + + +void D3D9_DrawParticles(float ptime) +{ + RSpeedLocals(); + + particletime = ptime; + VectorScale (vup, 1.5, pup); + VectorScale (vright, 1.5, pright); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); //they're not all mipmapped + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + lastd3dtype = NULL; + DrawParticleTypes(D3D9_DrawParticleBlob, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleBeam, D3D9_DrawParticleBeamUT, NULL); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, FALSE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE ); + + RSpeedRemark(); + RQ_RenderDistAndClear(); + RSpeedEnd(RSPEED_PARTICLESDRAW); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} +#endif diff --git a/engine/d3d9/d3d9_rsurf.c b/engine/d3d9/d3d9_rsurf.c new file mode 100644 index 000000000..2468087e3 --- /dev/null +++ b/engine/d3d9/d3d9_rsurf.c @@ -0,0 +1,1410 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3d9quake.h" + +int numlightmaps; + +mvertex_t *r_pcurrentvertbase; + +#define LMBLOCK_WIDTH 128 +#define LMBLOCK_HEIGHT LMBLOCK_WIDTH + +LPDIRECT3DTEXTURE9 *lightmap_d3d9textures; +LPDIRECT3DTEXTURE9 *deluxmap_d3d9textures; +lightmapinfo_t **lightmap; + + + +void D3D9_BuildSurfaceDisplayList (msurface_t *fa) +{ + int i, lindex, lnumverts; + medge_t *pedges, *r_pedge; + int vertpage; + float *vec; + float s, t; + int lm; + + int size; + mesh_t *mesh; + +// reconstruct the polygon + pedges = currentmodel->edges; + lnumverts = fa->numedges; + vertpage = 0; + + + if (lnumverts<3) + return; //q3 map. + + size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec3_t) + sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts; + + fa->mesh = mesh = Hunk_Alloc(size); + mesh->xyz_array = (vec3_t*)(mesh + 1); + mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts); + mesh->st_array = (vec2_t*)(mesh->normals_array + lnumverts); + mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts); + mesh->colors_array = (byte_vec4_t*)(mesh->lmst_array + lnumverts); + mesh->indexes = (index_t*)(mesh->colors_array + lnumverts); + + mesh->numindexes = (lnumverts-2)*3; + mesh->numvertexes = lnumverts; + mesh->patchWidth = mesh->patchHeight = 1; + + for (i=0 ; iindexes[i*3] = 0; + mesh->indexes[i*3+1] = i+1; + mesh->indexes[i*3+2] = i+2; + } + + for (i=0 ; isurfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + vec = r_pcurrentvertbase[r_pedge->v[0]].position; + } + else + { + r_pedge = &pedges[-lindex]; + vec = r_pcurrentvertbase[r_pedge->v[1]].position; + } + + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + + VectorCopy (vec, mesh->xyz_array[i]); + mesh->xyz_array[i][3] = 1; + mesh->st_array[i][0] = s/fa->texinfo->texture->width; + mesh->st_array[i][1] = t/fa->texinfo->texture->height; + + s -= fa->texturemins[0]; + lm = s*fa->light_t; + s += fa->light_s*16; + s += 8; + s /= LMBLOCK_WIDTH*16; + + t -= fa->texturemins[1]; + lm += t; + t += fa->light_t*16; + t += 8; + t /= LMBLOCK_HEIGHT*16; + + mesh->lmst_array[i][0] = s; + mesh->lmst_array[i][1] = t; + + if (fa->flags & SURF_PLANEBACK) + VectorNegate(fa->plane->normal, mesh->normals_array[i]); + else + VectorCopy(fa->plane->normal, mesh->normals_array[i]); + + mesh->colors_array[i][0] = 255; + mesh->colors_array[i][1] = 255; + mesh->colors_array[i][2] = 255; + mesh->colors_array[i][3] = 255; + } +} + + + + + + + +#define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH + +vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; +unsigned blocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; + +unsigned greenblklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; +unsigned blueblklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; + +void D3D9R_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift) +{ + int smax, tmax; + int t; + int i, j, size; + qbyte *lightmap; + unsigned scale; + int maps; + unsigned *bl; + qboolean isstained; + extern cvar_t r_ambient; + extern cvar_t gl_lightmap_shift; + + unsigned *blg; + unsigned *blb; + + int r, g, b; + int cr, cg, cb; + + int stride = LMBLOCK_WIDTH*lightmap_bytes; + + shift += 7; // increase to base value + surf->cached_dlight = (surf->dlightframe == r_framecount); + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + + if (size > MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE) + { //fixme: fill in? + Con_Printf("Lightmap too large\n"); + return; + } + +// if (currentmodel->deluxdata) +// GLR_BuildDeluxMap(surf, deluxdest); + + + + if (true) + { + // set to full bright if no light data + if (r_fullbright.value>0) //not qw + { + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + } + goto store; + } + if (!currentmodel->lightdata) + { + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + goto store; + } + +// clear to no light + t = r_ambient.value*255; + for (i=0 ; ifromgame == fg_quake3) //rgb + { + /* for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) //no light styles in q3 apparently. + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + } + */ + for (i = 0; i < tmax; i++) //q3 maps store thier light in a block fashion, q1/q2/hl store it in a linear fashion. + { + for (j = 0; j < smax; j++) + { + blocklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3]; + greenblklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+1]; + blueblklights[i*smax+j] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+2]; + } + } +// memset(blocklights, 255, sizeof(blocklights)); + } + else if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb + { + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + + + if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative. + { + for (i=0 ; istyles[maps]].colour & 1) + for (i=0 ; istyles[maps]].colour & 2) + for (i=0 ; istyles[maps]].colour & 4) + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + + if (cl_lightstyle[surf->styles[maps]].colour == 7) //hopefully a faster alternative. + { + for (i=0 ; istyles[maps]].colour & 1) + for (i=0 ; istyles[maps]].colour & 2) + for (i=0 ; istyles[maps]].colour & 4) + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLightsColours (surf); + } + else + { + // set to full bright if no light data + if (r_fullbright.value || !currentmodel->lightdata) + { + for (i=0 ; iengineflags & MDLF_RGBLIGHTING) //rgb + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]/3; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + surf->cached_colour[maps] = cl_lightstyle[surf->styles[maps]].colour; + for (i=0 ; idlightframe == r_framecount) +// GLR_AddDynamicLights (surf); + } + +// bound, invert, and shift +store: +#define INVERTLIGHTMAPS +#ifdef INVERTLIGHTMAPS + switch (lightmap_bytes) + { + case 4: + stride -= (smax<<2); + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest[3] = 0;//(dest[0]+dest[1]+dest[2])/3; + dest += 4; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + /* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[2] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +//*/ + + + + dest[3] = (dest[0]+dest[1]+dest[2])/3; //alpha?!?! + dest += 4; + } + } + } + break; + + case 3: + stride -= smax*3; + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest += 3; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + /* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[2] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +// */ + dest += 3; + } + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +#else + switch (lightmap_bytes) + { + case 4: + stride -= (smax<<2); + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 0; + else if (t < 0) + dest[0] = 256; + else + dest[0] = (255-t); + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 0; + else if (t < 0) + dest[1] = 256; + else + dest[1] = (255-t); + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 0; + else if (t < 0) + dest[2] = 256; + else + dest[2] = (255-t); + + dest[3] = 0;//(dest[0]+dest[1]+dest[2])/3; + dest += 4; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[2] = 0; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 255; + else + dest[2] = 255-(r+cr); + + if ((g+cg) > 255) + dest[1] = 0; + else if ((g+cg) < 0) + dest[1] = 255; + else + dest[1] = 255-(g+cg); + + if ((b+cb) > 255) + dest[0] = 0; + else if ((b+cb) < 0) + dest[0] = 255; + else + dest[0] = 255-(b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +*/ + + + + dest[3] = (dest[0]+dest[1]+dest[2])/3; //alpha?!?! + dest += 4; + } + } + } + break; + + case 3: + stride -= smax*3; + bl = blocklights; + blg = greenblklights; + blb = blueblklights; + +// if (!r_stains.value) + isstained = false; +// else +// isstained = surf->stained; + +/* if (!gl_lightcomponantreduction.value) + { + for (i=0 ; i>= 7; + if (t > 255) + dest[0] = 255; + else if (t < 0) + dest[0] = 0; + else + dest[0] = t; + + t = *blg++; + t >>= 7; + if (t > 255) + dest[1] = 255; + else if (t < 0) + dest[1] = 0; + else + dest[1] = t; + + t = *blb++; + t >>= 7; + if (t > 255) + dest[2] = 255; + else if (t < 0) + dest[2] = 0; + else + dest[2] = t; + + dest += 3; + } + } + } + else +*/ { + stmap *stain; + for (i=0 ; i>= shift; + g >>= shift; + b >>= shift; + + if (isstained) // merge in stain + { + r = (127+r*(*stain++)) >> 8; + g = (127+g*(*stain++)) >> 8; + b = (127+b*(*stain++)) >> 8; + } + + cr = 0; + cg = 0; + cb = 0; + + if (r > 255) //ak too much red + { + cr -= (255-r)/2; + cg += (255-r)/4; //reduce it, and indicate to drop the others too. + cb += (255-r)/4; + r = 255; + } +// else if (r < 0) +// r = 0; + + if (g > 255) + { + cr += (255-g)/4; + cg -= (255-g)/2; + cb += (255-g)/4; + g = 255; + } +// else if (g < 0) +// g = 0; + + if (b > 255) + { + cr += (255-b)/4; + cg += (255-b)/4; + cb -= (255-b)/2; + b = 255; + } +// else if (b < 0) +// b = 0; + //* + if ((r+cr) > 255) + dest[2] = 255; //inverse lighting + else if ((r+cr) < 0) + dest[2] = 0; + else + dest[2] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[0] = 255; + else if ((b+cb) < 0) + dest[0] = 0; + else + dest[0] = (b+cb); +/*/ + if ((r+cr) > 255) + dest[0] = 255; //non-inverse lighting + else if ((r+cr) < 0) + dest[0] = 0; + else + dest[0] = (r+cr); + + if ((g+cg) > 255) + dest[1] = 255; + else if ((g+cg) < 0) + dest[1] = 0; + else + dest[1] = (g+cg); + + if ((b+cb) > 255) + dest[2] = 255; + else if ((b+cb) < 0) + dest[2] = 0; + else + dest[2] = (b+cb); +// */ + dest += 3; + } + } + } + break; + default: + Sys_Error ("Bad lightmap format"); + } +#endif +} + + + +int D3D9_FillBlock (int texnum, int w, int h, int x, int y) +{ + int i, l; + while (texnum >= numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. + { + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap_d3d9textures = BZ_Realloc(lightmap_d3d9textures, sizeof(*lightmap_d3d9textures)*(numlightmaps+4)); +// lightmap_textures[numlightmaps+0] = texture_extension_number++; +// lightmap_textures[numlightmaps+1] = texture_extension_number++; +// lightmap_textures[numlightmaps+2] = texture_extension_number++; +// lightmap_textures[numlightmaps+3] = texture_extension_number++; + + deluxmap_d3d9textures = BZ_Realloc(deluxmap_d3d9textures, sizeof(*deluxmap_d3d9textures)*(numlightmaps+4)); +// deluxmap_textures[numlightmaps+0] = texture_extension_number++; +// deluxmap_textures[numlightmaps+1] = texture_extension_number++; +// deluxmap_textures[numlightmaps+2] = texture_extension_number++; +// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + numlightmaps+=4; + } + for (i = texnum; i >= 0; i--) + { + if (!lightmap[i]) + { + lightmap[i] = BZ_Malloc(sizeof(*lightmap[i])); + for (l=0 ; lallocated[l] = LMBLOCK_HEIGHT; + } + + //maybe someone screwed with my lightmap... + memset(lightmap[i]->lightmaps, 255, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); +// if (cl.worldmodel->lightdata) +// memcpy(lightmap[i]->lightmaps, cl.worldmodel->lightdata+3*LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); + + } + else + break; + } + return texnum; +} + +int D3D9_AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + for (texnum=0 ; ; texnum++) + { + if (texnum == numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. + { + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap_d3d9textures = BZ_Realloc(lightmap_d3d9textures, sizeof(*lightmap_d3d9textures)*(numlightmaps+4)); +// lightmap_textures[numlightmaps+0] = texture_extension_number++; +// lightmap_textures[numlightmaps+1] = texture_extension_number++; +// lightmap_textures[numlightmaps+2] = texture_extension_number++; +// lightmap_textures[numlightmaps+3] = texture_extension_number++; + + deluxmap_d3d9textures = BZ_Realloc(deluxmap_d3d9textures, sizeof(*deluxmap_d3d9textures)*(numlightmaps+4)); +// deluxmap_textures[numlightmaps+0] = texture_extension_number++; +// deluxmap_textures[numlightmaps+1] = texture_extension_number++; +// deluxmap_textures[numlightmaps+2] = texture_extension_number++; +// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + numlightmaps+=4; + } + if (!lightmap[texnum]) + { + lightmap[texnum] = Z_Malloc(sizeof(*lightmap[texnum])); + // reset stainmap since it now starts at 255 + memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps)); + } + + + best = LMBLOCK_HEIGHT; + + for (i=0 ; iallocated[i+j] >= best) + break; + if (lightmap[texnum]->allocated[i+j] > best2) + best2 = lightmap[texnum]->allocated[i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > LMBLOCK_HEIGHT) + continue; + + for (i=0 ; iallocated[*x + i] = best + h; + + return texnum; + } + + Sys_Error ("AllocBlock: full"); + return 0; +} + + +void D3D9_CreateSurfaceLightmap (msurface_t *surf, int shift) +{ + int smax, tmax; + qbyte *base, *luxbase; stmap *stainbase; + + if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) + surf->lightmaptexturenum = -1; + if (surf->texinfo->flags & TEX_SPECIAL) + surf->lightmaptexturenum = -1; + if (surf->lightmaptexturenum<0) + return; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + + if (smax > LMBLOCK_WIDTH || tmax > LMBLOCK_HEIGHT || smax < 0 || tmax < 0) + { //whoa, buggy. + surf->lightmaptexturenum = -1; + return; + } + + if (currentmodel->fromgame == fg_quake3) + D3D9_FillBlock(surf->lightmaptexturenum, smax, tmax, surf->light_s, surf->light_t); + else + surf->lightmaptexturenum = D3D9_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + base = lightmap[surf->lightmaptexturenum]->lightmaps; + base += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes; + + luxbase = lightmap[surf->lightmaptexturenum]->deluxmaps; + luxbase += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes; + + stainbase = lightmap[surf->lightmaptexturenum]->stainmaps; + stainbase += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * 3; + + D3D9R_BuildLightMap (surf, base, luxbase, stainbase, shift); +} + + +void D3D9R_RenderDynamicLightmaps (msurface_t *fa, int shift) +{ + qbyte *base, *luxbase; + stmap *stainbase; + int maps; + glRect_t *theRect; + int smax, tmax; + + if (!fa->mesh) + return; + +// c_brush_polys++; + + if (fa->lightmaptexturenum<0) + return; + + if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) + return; + + if (fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP)) + return; + + if (fa->texinfo->flags & (TEX_SPECIAL)) + { + if (cl.worldmodel->fromgame == fg_halflife) + return; //some textures do this. + } + +// fa->polys->chain = lightmap[fa->lightmaptexturenum]->polys; +// lightmap[fa->lightmaptexturenum]->polys = fa->polys; + + // check for lightmap modification +// if (cl.worldmodel->fromgame != fg_quake3) //no lightstyles on q3 maps + { + for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; + maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] + #ifdef PEXT_LIGHTSTYLECOL + || cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps] + #endif + ) + { + goto dynamic; + } + } + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { + RSpeedLocals(); +dynamic: + RSpeedRemark(); + + lightmap[fa->lightmaptexturenum]->modified = true; + + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + + theRect = &lightmap[fa->lightmaptexturenum]->rectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + lightmap[fa->lightmaptexturenum]->deluxmodified = true; + theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + + base = lightmap[fa->lightmaptexturenum]->lightmaps; + base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps; + luxbase += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + stainbase = lightmap[fa->lightmaptexturenum]->stainmaps; + stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3; + D3D9R_BuildLightMap (fa, base, luxbase, stainbase, shift); + + RSpeedEnd(RSPEED_DYNAMIC); + } +} + + + +LPDIRECT3DTEXTURE9 D3D9_NewLightmap(void) +{ + LPDIRECT3DTEXTURE9 newsurf; + IDirect3DDevice9_CreateTexture(pD3DDev9, LMBLOCK_WIDTH, LMBLOCK_WIDTH, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &newsurf, NULL); + + if (!newsurf) + return NULL; + + return newsurf; +} + +void D3D9_BuildLightmaps (void) +{ + D3DLOCKED_RECT desc; + + int i, j; + model_t *m; + int shift; + + r_framecount = 1; // no dlightcache +/* + for (i = 0; i < numlightmaps; i++) + { + if (!lightmap[i]) + break; + BZ_Free(lightmap[i]); + lightmap[i] = NULL; + } + + if (cl.worldmodel->fromgame == fg_doom) + return; //no lightmaps. + + if ((cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value) + gl_lightmap_format = GL_RGB; + else + gl_lightmap_format = GL_LUMINANCE; + + + if (cl.worldmodel->fromgame == fg_quake3 && gl_lightmap_format != GL_RGB && gl_lightmap_format != GL_RGBA) + gl_lightmap_format = GL_RGB; + + + switch (gl_lightmap_format) + { + case GL_RGBA: + lightmap_bytes = 4; + break; + case GL_RGB: + lightmap_bytes = 3; + break; + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_ALPHA: + lightmap_bytes = 1; + break; + } +*/ + for (j=1 ; jname[0] == '*') + continue; + + r_pcurrentvertbase = m->vertexes; + currentmodel = m; + shift = 0;//GLR_LightmapShift(currentmodel); + + for (i=0 ; inumsurfaces ; i++) + { + D3D9_CreateSurfaceLightmap (m->surfaces + i, shift); + P_EmitSkyEffectTris(m, &m->surfaces[i]); + if (m->surfaces[i].mesh) //there are some surfaces that have a display list already (the subdivided ones) + continue; + D3D9_BuildSurfaceDisplayList (m->surfaces + i); + } + } + + // + // upload all lightmaps that were filled + // + for (i=0 ; imodified = false; + lightmap[i]->rectchange.l = LMBLOCK_WIDTH; + lightmap[i]->rectchange.t = LMBLOCK_HEIGHT; + lightmap[i]->rectchange.w = 0; + lightmap[i]->rectchange.h = 0; + + if (!lightmap_d3d9textures[i]) + { + lightmap_d3d9textures[i] = D3D9_NewLightmap(); + + if (!lightmap_d3d9textures[i]) + { + Con_Printf("Couldn't create new lightmap\n"); + return; + } + } + + IDirect3DTexture9_LockRect(lightmap_d3d9textures[i], 0, &desc, NULL, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS); + memcpy(desc.pBits, lightmap[i]->lightmaps, sizeof(lightmap[i]->lightmaps)); + /* memset(desc.lpSurface, 0, sizeof(lightmap[i]->lightmaps)); + { + int i; + unsigned char *c; + c = desc.lpSurface; + for (i = 0; i < sizeof(lightmap[i]->lightmaps); i++) + *c++ = rand(); + }*/ + IDirect3DTexture9_UnlockRect(lightmap_d3d9textures[i], 0); + + if (deluxmap_d3d9textures[i]) + { + IDirect3DTexture9_LockRect(deluxmap_d3d9textures[i], 0, &desc, NULL, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS); + memcpy(desc.pBits, lightmap[i]->lightmaps, sizeof(lightmap[i]->deluxmaps)); + IDirect3DTexture9_UnlockRect(deluxmap_d3d9textures[i], 0); + } + } + +} + + + + + + +void D3D9_DrawSkyMesh(int pass, int texture, void *verts, int numverts, void *indicies, int numelements) +{ + if (pass == 0) + { + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (LPDIRECT3DBASETEXTURE9)texture); + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, numverts, numelements, indicies, D3DFMT_QINDEX, verts, 20); + } + + if (pass == 1) + { + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (LPDIRECT3DBASETEXTURE9)texture); + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, numverts, numelements, indicies, D3DFMT_QINDEX, verts, 20); + + + + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE); + } +} + +#endif diff --git a/engine/d3d9/d3d9quake.h b/engine/d3d9/d3d9quake.h new file mode 100644 index 000000000..6eb6a0948 --- /dev/null +++ b/engine/d3d9/d3d9quake.h @@ -0,0 +1,65 @@ +//#include "ddraw.h" + + +#include "d3d9.h" + +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags); +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix); + + + +#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal) +#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255) +#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP) +#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0 +#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0 + +#define D3D9_FindTexture(name) -1 +#define D3D9_LoadCompressed(name) 0 + + + +extern LPDIRECT3DDEVICE9 pD3DDev9; + +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +#define lightmap_bytes 4 + + +extern int numlightmaps; + +extern mvertex_t *r_pcurrentvertbase; + +#ifndef LMBLOCK_WIDTH +#define LMBLOCK_WIDTH 128 +#define LMBLOCK_HEIGHT LMBLOCK_WIDTH +typedef struct glRect_s { + unsigned char l,t,w,h; +} glRect_t; +typedef unsigned char stmap; + +typedef struct { + qboolean modified; + qboolean deluxmodified; + glRect_t rectchange; + glRect_t deluxrectchange; + int allocated[LMBLOCK_WIDTH]; + qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; + qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage. + stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed. +} lightmapinfo_t; +#endif + +extern LPDIRECT3DTEXTURE9 *lightmap_d3d9textures; +extern LPDIRECT3DTEXTURE9 *deluxmap_d3d9textures; +extern lightmapinfo_t **lightmap; + +extern void *d3dexplosiontexture; +extern void *d3dballtexture; + +extern index_t dummyindex; +#if sizeof_index_t == 2 + #define D3DFMT_QINDEX D3DFMT_INDEX16 +#else + #define D3DFMT_QINDEX D3DFMT_INDEX32 +#endif diff --git a/engine/d3d9/vid_d3d9.c b/engine/d3d9/vid_d3d9.c new file mode 100644 index 000000000..0defa34b8 --- /dev/null +++ b/engine/d3d9/vid_d3d9.c @@ -0,0 +1,1536 @@ +#include "quakedef.h" +#ifdef D3DQUAKE +#include "d3d9quake.h" + +//#include "d3d9.h" + + +//#pragma comment(lib, "../libs/dxsdk9/lib/d3d9.lib") + + +#ifndef WM_XBUTTONDOWN + #define WM_XBUTTONDOWN 0x020B + #define WM_XBUTTONUP 0x020C +#endif +#ifndef MK_XBUTTON1 + #define MK_XBUTTON1 0x0020 + #define MK_XBUTTON2 0x0040 +// copied from DarkPlaces in an attempt to grab more buttons + #define MK_XBUTTON3 0x0080 + #define MK_XBUTTON4 0x0100 + #define MK_XBUTTON5 0x0200 + #define MK_XBUTTON6 0x0400 + #define MK_XBUTTON7 0x0800 +#endif + +#ifndef WM_INPUT + #define WM_INPUT 255 +#endif + + +int gl_bumpmappingpossible; + +void D3D9_GetBufferSize(int *width, int *height); +static LPDIRECT3D9 pD3D; +LPDIRECT3DDEVICE9 pD3DDev9; +//static LPDIRECTDRAWGAMMACONTROL pGammaControl; + + +static qboolean vid_initializing; + +extern qboolean scr_initialized; // ready to draw +extern qboolean scr_drawloading; + + +cvar_t vid_hardwaregamma; + + +HWND mainwindow; + +struct texture_s *r_notexture_mip; + +int r_framecount; + +mleaf_t *r_viewleaf; + +#define MAX_MOD_KNOWN 1024 +int mod_numknown; +model_t mod_known[MAX_MOD_KNOWN]; +model_t *loadmodel; +model_t *currentmodel; +char loadname[32]; +qbyte *mod_base; + +qboolean DDActive; + +model_t *lightmodel; +int relitsurface; + +int window_center_x, window_center_y; +RECT window_rect; +int window_x, window_y; + +qboolean r_cache_thrash; // set if thrashing the surface cache + +mpic_t *draw_disc; // also used on sbar + +int d3d9width, d3d9height; + +#if !defined(SWQUAKE) && !defined(RGLQUAKE) +qbyte GetPalette(int red, int green, int blue) +{ + //slow, horrible method. + { + int i, best=15; + int bestdif=256*256*256, curdif; + extern qbyte *host_basepal; + qbyte *pa; + + #define _abs(x) ((x)*(x)) + + pa = host_basepal; + for (i = 0; i < 256; i++, pa+=3) + { + curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]); + if (curdif < bestdif) + { + if (curdif<1) + return i; + bestdif = curdif; + best = i; + } + } + return best; + } +} +#endif + +void BuildGammaTable (float g, float c); +void D3D9_VID_GenPaletteTables (unsigned char *palette) +{ + extern unsigned short ramps[3][256]; + qbyte *pal; + unsigned r,g,b; + unsigned v; + unsigned short i; + unsigned *table; + extern qbyte gammatable[256]; + + if (palette) + { + extern cvar_t v_contrast; + BuildGammaTable(v_gamma.value, v_contrast.value); + + // + // 8 8 8 encoding + // + if (1)//vid_hardwaregamma.value) + { + // don't built in the gamma table + + pal = palette; + table = d_8to24rgbtable; + for (i=0 ; i<256 ; i++) + { + r = pal[0]; + g = pal[1]; + b = pal[2]; + pal += 3; + + // v = (255<<24) + (r<<16) + (g<<8) + (b<<0); + // v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent + } + else + { + //computer has no hardware gamma (poor suckers) increase table accordingly + + pal = palette; + table = d_8to24rgbtable; + for (i=0 ; i<256 ; i++) + { + r = gammatable[pal[0]]; + g = gammatable[pal[1]]; + b = gammatable[pal[2]]; + pal += 3; + + // v = (255<<24) + (r<<16) + (g<<8) + (b<<0); + // v = (255<<0) + (r<<8) + (g<<16) + (b<<24); + v = (255<<24) + (r<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent + } + + if (LittleLong(1) != 1) + { + for (i=0 ; i<256 ; i++) + d_8to24rgbtable[i] = LittleLong(d_8to24rgbtable[i]); + } + } + + if (pD3DDev9) + IDirect3DDevice9_SetGammaRamp(pD3DDev9, 0, D3DSGR_NO_CALIBRATION, ramps); +} + +#if !defined(SWQUAKE) && !defined(GLQUAKE) +void D_FlushCaches (void) +{ +} +#endif + + +/* + +void D3D9_Mod_Think (void) +{ +} +void D3D9_Mod_NowLoadExternal(void) +{ +} +void D3D9_Mod_TouchModel (char *name) +{ +} +void *D3D9_Mod_Extradata (struct model_s *mod) // handles caching +{ + return NULL; +} +struct model_s *D3D9_Mod_FindName (char *name) +{ + return NULL; +} +struct model_s *D3D9_Mod_ForName (char *name, qboolean crash) +{ + return NULL; +} +void D3D9_Mod_ClearAll (void) +{ +} +void D3D9_Mod_Init (void) +{ +}*/ + + +typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t; +static modestate_t modestate; + +qboolean D3D9AppActivate(BOOL fActive, BOOL minimize) +/**************************************************************************** +* +* Function: AppActivate +* Parameters: fActive - True if app is activating +* +* Description: If the application is activating, then swap the system +* into SYSPAL_NOSTATIC mode so that our palettes will display +* correctly. +* +****************************************************************************/ +{ + static BOOL sound_active; + + if (ActiveApp == fActive && Minimized == minimize) + return false; //so windows doesn't crash us over and over again. + + ActiveApp = fActive; + Minimized = minimize; + +// enable/disable sound on focus gain/loss + if (!ActiveApp && sound_active) + { + S_BlockSound (); + sound_active = false; + } + else if (ActiveApp && !sound_active) + { + S_UnblockSound (); + sound_active = true; + } + + if (fActive) + { +/* if (modestate != MS_WINDOWED) + { + IN_ActivateMouse (); + IN_HideMouse (); +// if (vid_canalttab && vid_wassuspended) + { +// vid_wassuspended = false; +// ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN); + ShowWindow(mainwindow, SW_SHOWNORMAL); + + // Fix for alt-tab bug in NVidia drivers +// MoveWindow (mainwindow, 0, 0, gdevmode.dmPelsWidth, gdevmode.dmPelsHeight, false); + } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value && (key_dest == key_game || key_dest == key_menu)) + { + IN_ActivateMouse (); + IN_HideMouse (); + } +*/ + Cvar_ForceCallback(&v_gamma); + } + + if (!fActive) + { +/* if (modestate != MS_WINDOWED) + { + IN_DeactivateMouse (); + IN_ShowMouse (); +// if (vid_canalttab) +// { +// ChangeDisplaySettings (NULL, 0); +// vid_wassuspended = true; +// } + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } +*/ + Cvar_ForceCallback(&v_gamma); //wham bam thanks. +/* + if (qSetDeviceGammaRamp) + { + if (vid_desktopgamma.value) + { + HDC hDC = GetDC(GetDesktopWindow()); + qSetDeviceGammaRamp (hDC, originalgammaramps); + ReleaseDC(GetDesktopWindow(), hDC); + } + else + { + qSetDeviceGammaRamp(maindc, originalgammaramps); + } + } + */ + } + + return true; +} + + + + + +static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LONG lRet = 1; + int fActive, fMinimized, temp; + extern unsigned int uiWheelMessage; + + if ( uMsg == uiWheelMessage ) + uMsg = WM_MOUSEWHEEL; + + switch (uMsg) + { + case WM_KILLFOCUS: + if (modestate == MS_FULLDIB) + ShowWindow(mainwindow, SW_SHOWMINNOACTIVE); + break; + + case WM_CREATE: + break; + + case WM_MOVE: + GetWindowRect(mainwindow, &window_rect); + window_x = (int) LOWORD(lParam); + window_y = (int) HIWORD(lParam); +// VID_UpdateWindowStatus (); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (!vid_initializing) + Key_Event (MapKey(lParam), true); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + if (!vid_initializing) + Key_Event (MapKey(lParam), false); + break; + + case WM_SYSCHAR: + // keep Alt-Space from happening + break; + + // this is complicated because Win32 seems to pack multiple mouse events into + // one update sometimes, so we always check all states and look for events + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEMOVE: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + temp = 0; + + if (wParam & MK_LBUTTON) + temp |= 1; + + if (wParam & MK_RBUTTON) + temp |= 2; + + if (wParam & MK_MBUTTON) + temp |= 4; + + if (wParam & MK_XBUTTON1) + temp |= 8; + + if (wParam & MK_XBUTTON2) + temp |= 16; + + if (wParam & MK_XBUTTON3) + temp |= 32; + + if (wParam & MK_XBUTTON4) + temp |= 64; + + if (wParam & MK_XBUTTON5) + temp |= 128; + + if (wParam & MK_XBUTTON6) + temp |= 256; + + if (wParam & MK_XBUTTON7) + temp |= 512; + + if (!vid_initializing) + IN_MouseEvent (temp); + + break; + + // JACK: This is the mouse wheel with the Intellimouse + // Its delta is either positive or neg, and we generate the proper + // Event. + case WM_MOUSEWHEEL: + if (!vid_initializing) + { + if ((short) HIWORD(wParam) > 0) + { + Key_Event(K_MWHEELUP, true); + Key_Event(K_MWHEELUP, false); + } + else + { + Key_Event(K_MWHEELDOWN, true); + Key_Event(K_MWHEELDOWN, false); + } + } + break; + + case WM_INPUT: + // raw input handling + IN_RawInput_MouseRead((HANDLE)lParam); + break; + + case WM_SIZE: + if (!vid_initializing) + { + GetWindowRect(mainwindow, &window_rect); + // force width/height to be updated +// glwidth = window_rect.right - window_rect.left; +// glheight = window_rect.bottom - window_rect.top; +// Cvar_ForceCallback(&vid_conautoscale); +// Cvar_ForceCallback(&vid_conwidth); + } + break; + + case WM_CLOSE: + if (!vid_initializing) + if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", + MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) + { + Sys_Quit (); + } + + break; + + case WM_ACTIVATE: + fActive = LOWORD(wParam); + fMinimized = (BOOL) HIWORD(wParam); + if (!D3D9AppActivate(!(fActive == WA_INACTIVE), fMinimized)) + break;//so, urm, tell me microsoft, what changed? + if (modestate == MS_FULLDIB) + ShowWindow(mainwindow, SW_SHOWNORMAL); + + // fix the leftover Alt from any Alt-Tab or the like that switched us away +// ClearAllStates (); + + break; + + case WM_DESTROY: + { +// if (dibwindow) +// DestroyWindow (dibwindow); + } + break; + + case MM_MCINOTIFY: + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + break; + + + case WM_MWHOOK: + if (!vid_initializing) + MW_Hook_Message (lParam); + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 1 if handled message, 0 if not */ + return lRet; +} + +static D3DPRESENT_PARAMETERS d3dpp; +void resetD3D9(void) +{ + IDirect3DDevice9_Reset(pD3DDev9, &d3dpp); + + + IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0); + IDirect3DDevice9_BeginScene(pD3DDev9); + IDirect3DDevice9_EndScene(pD3DDev9); + IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); + + + + + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAFUNC, D3DCMP_GREATER ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAREF, 0.666*256 ); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_DITHERENABLE, FALSE); + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_SPECULARENABLE, FALSE); + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_LIGHTING, FALSE); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + +} + +#if WINVER < 0x500 +typedef struct tagMONITORINFO +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; +#endif +/* +void testD3D(HWND hWnd) +{ + + D3DPRESENT_PARAMETERS d3dpp[2]; + + int i; + int numadaptors; + int err; + D3DADAPTER_IDENTIFIER9 inf; + + static HMODULE d3d9dll; + LPDIRECT3D9 (WINAPI *pDirect3DCreate9) (int version); + + if (!d3d9dll) + d3d9dll = LoadLibrary("d3d9.dll"); + if (!d3d9dll) + { + Con_Printf("Direct3d 9 does not appear to be installed\n"); + return; + } + pDirect3DCreate9 = (void*)GetProcAddress(d3d9dll, "Direct3DCreate9"); + if (!pDirect3DCreate9) + { + Con_Printf("Direct3d 9 does not appear to be installed properly\n"); + return; + } + + pD3D = pDirect3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface + if (!pD3D) + return; + + for (i = 0; i < 2; i++) + { + memset(&d3dpp[0], 0, sizeof(d3dpp)); // clear out the struct for use + d3dpp[0].SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames + d3dpp[0].hDeviceWindow = hWnd; // set the window to be used by Direct3D + d3dpp[0].BackBufferWidth = d3d9width = info->width; + d3dpp[0].BackBufferHeight = d3d9height = info->height; + d3dpp[0].MultiSampleType = info->multisample; + d3dpp[0].BackBufferCount = 3; + d3dpp[0].FullScreen_RefreshRateInHz = info->fullscreen?info->rate:0; //don't pass a rate if not fullscreen, d3d doesn't like it. + d3dpp[0].Windowed = !info->fullscreen; + + d3dpp[0].EnableAutoDepthStencil = true; + d3dpp[0].AutoDepthStencilFormat = D3DFMT_D16; + d3dpp[0].BackBufferFormat = info->fullscreen?D3DFMT_X8R8G8B8:D3DFMT_UNKNOWN; + } + + IDirect3D9_CreateDevice(pD3D, + i, + D3DDEVTYPE_HAL, + hWnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, + &pD3DDev9); + +} +*/ +void initD3D9(HWND hWnd, rendererstate_t *info) +{ + int i; + int numadaptors; + int err; + D3DADAPTER_IDENTIFIER9 inf; + extern cvar_t _vid_wait_override; + + static HMODULE d3d9dll; + LPDIRECT3D9 (WINAPI *pDirect3DCreate9) (int version); + + if (!d3d9dll) + d3d9dll = LoadLibrary("d3d9.dll"); + if (!d3d9dll) + { + Con_Printf("Direct3d 9 does not appear to be installed\n"); + return; + } + pDirect3DCreate9 = (void*)GetProcAddress(d3d9dll, "Direct3DCreate9"); + if (!pDirect3DCreate9) + { + Con_Printf("Direct3d 9 does not appear to be installed properly\n"); + return; + } + + pD3D = pDirect3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface + if (!pD3D) + return; + + numadaptors = IDirect3D9_GetAdapterCount(pD3D); + for (i = 0; i < numadaptors; i++) + { //try each adaptor in turn until we get one that actually works + memset(&d3dpp, 0, sizeof(d3dpp)); // clear out the struct for use + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames + d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D + d3dpp.BackBufferWidth = d3d9width = info->width; + d3dpp.BackBufferHeight = d3d9height = info->height; + d3dpp.MultiSampleType = info->multisample; + d3dpp.BackBufferCount = 3; + d3dpp.FullScreen_RefreshRateInHz = info->fullscreen?info->rate:0; //don't pass a rate if not fullscreen, d3d doesn't like it. + d3dpp.Windowed = !info->fullscreen; + + d3dpp.EnableAutoDepthStencil = true; + d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + d3dpp.BackBufferFormat = info->fullscreen?D3DFMT_X8R8G8B8:D3DFMT_UNKNOWN; + + if (!*_vid_wait_override.string) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + else + { + if (_vid_wait_override.value == 1) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else if (_vid_wait_override.value == 2) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; + else if (_vid_wait_override.value == 3) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE; + else if (_vid_wait_override.value == 4) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR; + else + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + memset(&inf, 0, sizeof(inf)); + err = IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &inf); + + // create a device class using this information and information from the d3dpp stuct + IDirect3D9_CreateDevice(pD3D, + i, + D3DDEVTYPE_HAL, + hWnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, + &pD3DDev9); + + if (pD3DDev9) + { + HMONITOR hm; + MONITORINFO mi; + char *s; + for (s = inf.Description + strlen(inf.Description)-1; s >= inf.Description && *s <= ' '; s--) + *s = 0; + Con_Printf("D3D9: Using device %s\n", inf.Description); + + if (d3dpp.Windowed) //fullscreen we get positioned automagically. + { //windowed, we get positioned at 0,0... which is often going to be on the wrong screen + //the user can figure it out from here + static HANDLE huser32; + BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR hMonitor, LPMONITORINFO lpmi); + if (!huser32) + huser32 = LoadLibrary("user32.dll"); + if (!huser32) + return; + pGetMonitorInfoA = (void*)GetProcAddress(huser32, "GetMonitorInfoA"); + if (!pGetMonitorInfoA) + return; + + hm = IDirect3D9_GetAdapterMonitor(pD3D, i); + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + pGetMonitorInfoA(hm, &mi); + MoveWindow(d3dpp.hDeviceWindow, mi.rcWork.left, mi.rcWork.top, d3dpp.BackBufferWidth, d3dpp.BackBufferHeight, false); + } + return; //successful + } + } + + + Con_Printf("IDirect3D9_CreateDevice failed\n"); + + + return; +} + +qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette) +{ + DWORD width = info->width; + DWORD height = info->height; + DWORD bpp = info->bpp; + DWORD zbpp = 16; + DWORD flags = 0; + MSG msg; + + extern cvar_t vid_conwidth; + extern cvar_t vid_conheight; + + DDGAMMARAMP gammaramp; + int i; + + char *CLASSNAME = "FTED3D9QUAKE"; + WNDCLASS wc = { + 0, + &D3D9_WindowProc, + 0, + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + CLASSNAME + }; + + vid_initializing = true; + + RegisterClass(&wc); + + if (info->fullscreen) + mainwindow = CreateWindow(CLASSNAME, "Direct3D", 0, 0, 0, width, height, NULL, NULL, NULL, NULL); + else + mainwindow = CreateWindow(CLASSNAME, "Direct3D", WS_OVERLAPPEDWINDOW, 0, 0, width, height, NULL, NULL, NULL, NULL); +/* + width = vid_conwidth.value; + height = vid_conheight.value; +*/ + // Try as specified. + + initD3D9(mainwindow, info); + if (!pD3DDev9) + return false; + + + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + ShowWindow(mainwindow, SW_NORMAL); + //IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1, 0); + //IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); + + IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + IDirect3DDevice9_BeginScene(pD3DDev9); + IDirect3DDevice9_EndScene(pD3DDev9); + IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); + + + +// pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, &width, &height); + vid.width = width; + vid.height = height; + vid.recalc_refdef = true; + +// pDD->lpVtbl->QueryInterface ((void*)pDD, &IID_IDirectDrawGammaControl, (void**)&pGammaControl); +/* if (pGammaControl) + { + for (i = 0; i < 256; i++) + gammaramp.red[i] = i*2; + pGammaControl->lpVtbl->SetGammaRamp(pGammaControl, 0, &gammaramp); + } + else*/ + Con_Printf("Couldn't get gamma controls\n"); + + vid_initializing = false; + + + +resetD3D9();/* + + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAFUNC, D3DCMP_GREATER ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHAREF, 0.666*256 ); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_DITHERENABLE, FALSE); + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_SPECULARENABLE, FALSE); + //IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_LIGHTING, FALSE); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + +*/ + GetWindowRect(mainwindow, &window_rect); + + + D3D9_VID_GenPaletteTables(palette); + + { + extern qboolean mouseactive; + mouseactive = false; + } + + { + extern cvar_t v_contrast; + void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue); + Cvar_Hook(&v_gamma, GLV_Gamma_Callback); + Cvar_Hook(&v_contrast, GLV_Gamma_Callback); + + Cvar_ForceCallback(&v_gamma); + } + + { + extern cvar_t vid_conwidth, vid_conheight; + vid.conwidth = vid_conwidth.value; + vid.conheight = vid_conheight.value; + if (vid.width != vid.conwidth || vid.height != vid.conheight) + vid.recalc_refdef = true; + vid.width = vid.conwidth; + vid.height = vid.conheight; + } + + return true; +} + + + +qboolean (D3D9_R_CheckSky) (void) +{ + return false; +} +void (D3D9_R_SetSky) (char *name, float rotate, vec3_t axis) +{ +} + +void (D3D9_R_NewMap) (void) +{ + extern int skytexturenum; + int i; + r_worldentity.model = cl.worldmodel; + GLR_AnimateLight(); + D3D9_BuildLightmaps(); + + P_ClearParticles(); + + skytexturenum = -1; + + for (i=0 ; inumtextures ; i++) + { + if (!cl.worldmodel->textures[i]) + continue; + if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) + skytexturenum = i; +// if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) +// mirrortexturenum = i; + cl.worldmodel->textures[i]->texturechain = NULL; + } +} + +mleaf_t *r_viewleaf, *r_oldviewleaf; +mleaf_t *r_viewleaf2, *r_oldviewleaf2; +void (D3D9_R_PreNewMap) (void) +{ + r_viewleaf = NULL; + r_oldviewleaf = NULL; + r_viewleaf2 = NULL; + r_oldviewleaf2 = NULL; +} +int (D3D9_R_LightPoint) (vec3_t point) +{ + return 0; +} + +void (D3D9_R_PushDlights) (void) +{ +} +void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius) +{ +} +void (D3D9_R_LessenStains) (void) +{ +} + +void (D3D9_Mod_Init) (void) +{ +} +void (D3D9_Mod_ClearAll) (void) +{ +} +struct model_s *(D3D9_Mod_ForName) (char *name, qboolean crash) +{ + return NULL; +} +struct model_s *(D3D9_Mod_FindName) (char *name) +{ + return NULL; +} +void *(D3D9_Mod_Extradata) (struct model_s *mod) +{ + return NULL; +} // handles caching +void (D3D9_Mod_TouchModel) (char *name) +{ +} + +void (D3D9_Mod_NowLoadExternal) (void) +{ +} +void (D3D9_Mod_Think) (void) +{ +} + +int (D3D9_Mod_SkinForName) (struct model_s *model, char *name) +{ + return 0; +} + +void (D3D9_VID_DeInit) (void) +{ + if (pD3DDev9) + { + IDirect3DDevice9_Release(pD3DDev9); + pD3DDev9 = NULL; + } + if (pD3D) + { + IDirect3D9_Release(pD3D); + pD3D = NULL; + } + if (mainwindow) + { + DestroyWindow(mainwindow); + mainwindow = NULL; + } +} +void (D3D9_VID_HandlePause) (qboolean pause) +{ +} +void (D3D9_VID_LockBuffer) (void) +{ +} +void (D3D9_VID_UnlockBuffer) (void) +{ +} +void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height) +{ +} +void (D3D9_D_EndDirectRect) (int x, int y, int width, int height) +{ +} +void (D3D9_VID_ForceLockState) (int lk) +{ +} +int (D3D9_VID_ForceUnlockedAndReturnState) (void) +{ + return 0; +} + +void (D3D9_VID_SetPalette) (unsigned char *palette) +{ + D3D9_VID_GenPaletteTables(palette); +} +void (D3D9_VID_ShiftPalette) (unsigned char *palette) +{ + D3D9_VID_GenPaletteTables(palette); +} +char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight) +{ + return NULL; +} +void (D3D9_VID_SetWindowCaption) (char *msg) +{ + SetWindowText(mainwindow, msg); +} + +#if 0 +#undef IDirect3DDevice9_SetRenderState +void IDirect3DDevice9_SetRenderState(void *pD3DDev9, int D3DRS, int param) +{ +} +#endif + +void D3D9_Set2D (void) +{ + int r; + float m[16]; + D3DVIEWPORT9 vport; +// IDirect3DDevice9_EndScene(pD3DDev9); + + Matrix4_Orthographic(m, 0, vid.width, vid.height, 0, -100, 100); + d3d7_ortho(m); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)m); + + Matrix4_Identity(m); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m); + + Matrix4_Identity(m); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)m); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW ); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZENABLE, D3DZB_FALSE); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE ); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE ); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + + vport.X = 0; + vport.Y = 0; + D3D9_GetBufferSize(&vport.Width, &vport.Height); + vport.MinZ = 0; + vport.MaxZ = 1; + IDirect3DDevice9_SetViewport(pD3DDev9, &vport); + +// IDirect3DDevice9_BeginScene(pD3DDev9); +} + +void D3D9_GetBufferSize(int *width, int *height) +{ + *width = d3d9width;//vid.width; + *height = d3d9height;//vid.height; +// IDirect3DDevice9_GetBufferSize((void*)pD3DX, width, height); +} + +int d3d9error(int i) +{ + if (FAILED(i))// != D3D_OK) + Con_Printf("D3D error: %x %i\n", i); + return i; +} + +typedef struct { + float x, y, z; + unsigned int colour; +} d3d9bsvert_t; +void D3D9_BrightenScreen (void) +{ + d3d9bsvert_t d3d9bsvert[4]; +index_t d3d9quadindexes[6] = { + 0, 1, 2, + 0, 2, 3 +}; + +extern cvar_t gl_contrast; + extern float vid_gamma; + float f; + unsigned int colour; + + RSpeedMark(); + + if (gl_contrast.value <= 1.0) + return; + + f = gl_contrast.value; + f = min (f, 3); + + f = pow (f, vid_gamma); + + IDirect3DDevice9_SetTexture (pD3DDev9, 0, NULL); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_ONE); + + while (f > 1) + { + if (f >= 2) + colour = 0xffffffff; + else + { + colour = (f-1)*255; + colour = (colour * 0x010101) | 0xff000000; + } + + + d3d9bsvert[0].x = 0; + d3d9bsvert[0].y = 0; + d3d9bsvert[0].z = 0; + d3d9bsvert[0].colour = colour; + + d3d9bsvert[1].x = vid.width; + d3d9bsvert[1].y = 0; + d3d9bsvert[1].z = 0; + d3d9bsvert[1].colour = colour; + + d3d9bsvert[2].x = vid.width; + d3d9bsvert[2].y = vid.height; + d3d9bsvert[2].z = 0; + d3d9bsvert[2].colour = colour; + + d3d9bsvert[3].x = 0; + d3d9bsvert[3].y = vid.height; + d3d9bsvert[3].z = 0; + d3d9bsvert[3].colour = colour; + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9bsvert, sizeof(d3d9bsvert[0])); + + + f *= 0.5; + } + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE); + + RSpeedEnd(RSPEED_PALETTEFLASHES); +} + +void (D3D9_SCR_UpdateScreen) (void) +{ + int err; + extern int keydown[]; + extern cvar_t vid_conheight; + int uimenu; +#ifdef TEXTEDITOR + extern qboolean editormodal; +#endif + qboolean nohud; + RSpeedMark(); + + switch (IDirect3DDevice9_TestCooperativeLevel(pD3DDev9)) + { + case D3DERR_DEVICELOST: + //the user has task switched away from us or something + return; + case D3DERR_DEVICENOTRESET: + resetD3D9(); + if (FAILED(IDirect3DDevice9_TestCooperativeLevel(pD3DDev9))) + Sys_Error("D3D9 Device lost. Additionally restoration failed.\n"); + // D3DSucks(); + // scr_disabled_for_loading = false; + + VID_ShiftPalette (NULL); + break; + default: + break; + } + + + if (keydown['k']) + { + d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(rand()&255, rand()&255, rand()&255), 1.0f, 0)); + d3d9error(IDirect3DDevice9_BeginScene(pD3DDev9)); + d3d9error(IDirect3DDevice9_EndScene(pD3DDev9)); + d3d9error(IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL)); + + VID_ShiftPalette (NULL); + } + + + if (block_drawing) + { + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + + vid.numpages = 2;// + gl_triplebuffer.value; + + scr_copytop = 0; + scr_copyeverything = 0; + + if (scr_disabled_for_loading) + { + extern float scr_disabled_time; + if (Sys_DoubleTime() - scr_disabled_time > 60 || key_dest != key_game) + { + scr_disabled_for_loading = false; + } + else + { + IDirect3DDevice9_BeginScene(pD3DDev9); + scr_drawloading = true; + SCR_DrawLoading (); + scr_drawloading = false; + IDirect3DDevice9_EndScene(pD3DDev9); + IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + } + + if (!scr_initialized || !con_initialized) + { + RSpeedEnd(RSPEED_TOTALREFRESH); + return; // not initialized yet + } + + { + extern cvar_t vid_conwidth, vid_conheight; + vid.conwidth = vid_conwidth.value; + vid.conheight = vid_conheight.value; + if (vid.width != vid.conwidth || vid.height != vid.conheight) + vid.recalc_refdef = true; + vid.width = vid.conwidth; + vid.height = vid.conheight; + } + + +#ifdef VM_UI + uimenu = UI_MenuState(); +#else + uimenu = 0; +#endif + + d3d9error(IDirect3DDevice9_BeginScene(pD3DDev9)); + D3D9_Set2D (); +/* +#ifdef TEXTEDITOR + if (editormodal) + { + Editor_Draw(); + GLV_UpdatePalette (false); +#if defined(_WIN32) && defined(RGLQUAKE) + Media_RecordFrame(); +#endif + GLR_BrightenScreen(); + + if (key_dest == key_console) + Con_DrawConsole(vid_conheight.value/2, false); + GL_EndRendering (); + GL_DoSwap(); + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } +#endif +*/ + if (Media_ShowFilm()) + { + M_Draw(0); +// GLV_UpdatePalette (false); +#if defined(_WIN32) + Media_RecordFrame(); +#endif +// GLR_BrightenScreen(); + IDirect3DDevice9_EndScene(pD3DDev9); + IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); + + d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(rand()&255, rand()&255, rand()&255), 1, 0)); + +// pD3DDev->lpVtbl->BeginScene(pD3DDev); + + RSpeedEnd(RSPEED_TOTALREFRESH); + return; + } + + // + // determine size of refresh window + // + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + nohud = false; + +#ifdef VM_CG + if (CG_Refresh()) + nohud = true; + else +#endif +#ifdef CSQC_DAT + if (cls.state == ca_active && CSQC_DrawView()) + nohud = true; + else +#endif + if (r_worldentity.model && uimenu != 1) + { + V_RenderView (); +// Q1BSP_TestClipDecal(); + } + + + D3D9_Set2D (); + + D3D9_BrightenScreen(); + + if (!nohud) + SCR_TileClear (); + + SCR_DrawTwoDimensional(uimenu, nohud); + + GLV_UpdatePalette (false); +#if defined(_WIN32) && defined(RGLQUAKE) + Media_RecordFrame(); +#endif + + RSpeedEnd(RSPEED_TOTALREFRESH); + RSpeedShow(); + + + + d3d9error(IDirect3DDevice9_EndScene(pD3DDev9)); + d3d9error(IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL)); + + + + d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, rand()&255), 1, 0)); + d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(rand()&255, rand()&255, rand()&255), 1, 0)); + + window_center_x = (window_rect.left + window_rect.right)/2; + window_center_y = (window_rect.top + window_rect.bottom)/2; + + + + if (modestate == MS_WINDOWED) + { + extern int mouseusedforgui; + extern qboolean mouseactive; + qboolean wantactive; + + wantactive = _windowed_mouse.value && (key_dest == key_game||mouseusedforgui) && ActiveApp; + if (wantactive != mouseactive) + { + if (!mouseactive) + { + IN_ActivateMouse (); + IN_HideMouse (); + } + else + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } + } + + VID_ShiftPalette (NULL); +} + + + + + +mpic_t *(D3D9_Draw_SafePicFromWad) (char *name); +mpic_t *(D3D9_Draw_CachePic) (char *path); +mpic_t *(D3D9_Draw_SafeCachePic) (char *path); +void (D3D9_Draw_Init) (void); +void (D3D9_Draw_ReInit) (void); +void (D3D9_Draw_Character) (int x, int y, unsigned int num); +void (D3D9_Draw_ColouredCharacter) (int x, int y, unsigned int num); +void (D3D9_Draw_String) (int x, int y, const qbyte *str); +void (D3D9_Draw_Alt_String) (int x, int y, const qbyte *str); +void (D3D9_Draw_Crosshair) (void); +void (D3D9_Draw_DebugChar) (qbyte num); +void (D3D9_Draw_Pic) (int x, int y, mpic_t *pic); +void (D3D9_Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic); +void (D3D9_Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); +void (D3D9_Draw_TransPic) (int x, int y, mpic_t *pic); +void (D3D9_Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation); +void (D3D9_Draw_ConsoleBackground) (int lines); +void (D3D9_Draw_EditorBackground) (int lines); +void (D3D9_Draw_TileClear) (int x, int y, int w, int h); +void (D3D9_Draw_Fill) (int x, int y, int w, int h, int c); +void (D3D9_Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); +void (D3D9_Draw_FadeScreen) (void); +void (D3D9_Draw_BeginDisc) (void); +void (D3D9_Draw_EndDisc) (void); + +void (D3D9_Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); //gl-style scaled/coloured/subpic +void (D3D9_Draw_ImageColours) (float r, float g, float b, float a); + +void (D3D9_R_Init) (void); +void (D3D9_R_DeInit) (void); +void (D3D9_R_ReInit) (void); +void (D3D9_R_RenderView) (void); // must set r_refdef first + +qboolean (D3D9_R_CheckSky) (void); +void (D3D9_R_SetSky) (char *name, float rotate, vec3_t axis); + +void (D3D9_R_NewMap) (void); +void (D3D9_R_PreNewMap) (void); +int (D3D9_R_LightPoint) (vec3_t point); + +void (D3D9_R_PushDlights) (void); +void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius); +void (D3D9_R_LessenStains) (void); + +void (D3D9_Media_ShowFrameBGR_24_Flip) (qbyte *framedata, int inwidth, int inheight); //input is bottom up... +void (D3D9_Media_ShowFrameRGBA_32) (qbyte *framedata, int inwidth, int inheight); //top down +void (D3D9_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette); //paletted topdown (framedata is 8bit indexes into palette) + +void (D3D9_Mod_Init) (void); +void (D3D9_Mod_ClearAll) (void); +struct model_s *(D3D9_Mod_ForName) (char *name, qboolean crash); +struct model_s *(D3D9_Mod_FindName) (char *name); +void *(D3D9_Mod_Extradata) (struct model_s *mod); // handles caching +void (D3D9_Mod_TouchModel) (char *name); + +void (D3D9_Mod_NowLoadExternal) (void); +void (D3D9_Mod_Think) (void); +qboolean(D3D9_Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result); +int (D3D9_Mod_TagNumForName) (struct model_s *model, char *name); +int (D3D9_Mod_SkinForName) (struct model_s *model, char *name); + + +qboolean (D3D9_VID_Init) (rendererstate_t *info, unsigned char *palette); +void (D3D9_VID_DeInit) (void); +void (D3D9_VID_HandlePause) (qboolean pause); +void (D3D9_VID_LockBuffer) (void); +void (D3D9_VID_UnlockBuffer) (void); +void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height); +void (D3D9_D_EndDirectRect) (int x, int y, int width, int height); +void (D3D9_VID_ForceLockState) (int lk); +int (D3D9_VID_ForceUnlockedAndReturnState) (void); +void (D3D9_VID_SetPalette) (unsigned char *palette); +void (D3D9_VID_ShiftPalette) (unsigned char *palette); +char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); +void (D3D9_VID_SetWindowCaption) (char *msg); + +void (D3D9_SCR_UpdateScreen) (void); + + + + + + + +rendererinfo_t d3d9rendererinfo = +{ + "Direct3D9 Native", + { + "D3D9", + "Direct3d", + "DirectX", + "DX" + }, + QR_DIRECT3D, + + D3D9_Draw_SafePicFromWad, + D3D9_Draw_CachePic, + D3D9_Draw_SafeCachePic, + D3D9_Draw_Init, + D3D9_Draw_ReInit, + D3D9_Draw_Character, + D3D9_Draw_ColouredCharacter, + D3D9_Draw_String, + D3D9_Draw_Alt_String, + D3D9_Draw_Crosshair, + D3D9_Draw_DebugChar, + D3D9_Draw_Pic, + D3D9_Draw_ScalePic, + D3D9_Draw_SubPic, + D3D9_Draw_TransPic, + D3D9_Draw_TransPicTranslate, + D3D9_Draw_ConsoleBackground, + D3D9_Draw_EditorBackground, + D3D9_Draw_TileClear, + D3D9_Draw_Fill, + D3D9_Draw_FillRGB, + D3D9_Draw_FadeScreen, + D3D9_Draw_BeginDisc, + D3D9_Draw_EndDisc, + + D3D9_Draw_Image, + D3D9_Draw_ImageColours, + + D3D9_R_Init, + D3D9_R_DeInit, + D3D9_R_ReInit, + D3D9_R_RenderView, + + D3D9_R_CheckSky, + D3D9_R_SetSky, + + D3D9_R_NewMap, + D3D9_R_PreNewMap, + D3D9_R_LightPoint, + + D3D9_R_PushDlights, + D3D9_R_AddStain, + D3D9_R_LessenStains, + + D3D9_Media_ShowFrameBGR_24_Flip, + D3D9_Media_ShowFrameRGBA_32, + D3D9_Media_ShowFrame8bit, + + GLMod_Init, + GLMod_ClearAll, + GLMod_ForName, + GLMod_FindName, + GLMod_Extradata, + GLMod_TouchModel, + + GLMod_NowLoadExternal, + GLMod_Think, + Mod_GetTag, + Mod_TagNumForName, + D3D9_Mod_SkinForName, + + + D3D9_VID_Init, + D3D9_VID_DeInit, + D3D9_VID_HandlePause, + D3D9_VID_LockBuffer, + D3D9_VID_UnlockBuffer, + D3D9_D_BeginDirectRect, + D3D9_D_EndDirectRect, + D3D9_VID_ForceLockState, + D3D9_VID_ForceUnlockedAndReturnState, + D3D9_VID_SetPalette, + D3D9_VID_ShiftPalette, + D3D9_VID_GetRGBInfo, + D3D9_VID_SetWindowCaption, + + D3D9_SCR_UpdateScreen + +}; +#endif diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index bf38fbf99..66c452daf 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Application" 0x0101 -CFG=ftequake - Win32 Debug Dedicated ServerQ3 +CFG=ftequake - Win32 D3DDebug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,7 +13,7 @@ CFG=ftequake - Win32 Debug Dedicated ServerQ3 !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "ftequake.mak" CFG="ftequake - Win32 Debug Dedicated ServerQ3" +!MESSAGE NMAKE /f "ftequake.mak" CFG="ftequake - Win32 D3DDebug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -30,6 +30,7 @@ CFG=ftequake - Win32 Debug Dedicated ServerQ3 !MESSAGE "ftequake - Win32 MinSW" (based on "Win32 (x86) Application") !MESSAGE "ftequake - Win32 GLDebugQ3" (based on "Win32 (x86) Application") !MESSAGE "ftequake - Win32 Debug Dedicated ServerQ3" (based on "Win32 (x86) Application") +!MESSAGE "ftequake - Win32 D3DDebug" (based on "Win32 (x86) Application") !MESSAGE # Begin Project @@ -164,7 +165,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NQPROT" /D "_DEBUG" /D "GLQUAKE" /D "SERVERDLL" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c +# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../libs/dxsdk9/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../d3d" /I "../d3d9" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "D3DQUAKE" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c # SUBTRACT CPP /WX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -403,6 +404,36 @@ LINK32=link.exe # ADD BASE LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"../../fteqwsv.exe" /libpath:"../libs/dxsdk7/lib" # ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /pdb:none /map /debug /machine:I386 /out:"../../fteqwsv.exe" /libpath:"../libs/dxsdk7/lib" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ftequake___Win32_D3DDebug" +# PROP BASE Intermediate_Dir "ftequake___Win32_D3DDebug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "D3DDebug" +# PROP Intermediate_Dir "D3DDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# SUBTRACT BASE CPP /X +# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../d3d" /D "_DEBUG" /D "D3DQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\D3DDebug/" /Fp".\D3DDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\D3DDebug/" /Fd".\D3DDebug/" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"../../fteglqw_dbg.exe" /libpath:"../libs/dxsdk7/lib" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"../../fted3dqw_dbg.exe" /libpath:"../libs/dxsdk7/lib" +# SUBTRACT LINK32 /pdb:none + !ENDIF # Begin Target @@ -420,6 +451,7 @@ LINK32=link.exe # Name "ftequake - Win32 MinSW" # Name "ftequake - Win32 GLDebugQ3" # Name "ftequake - Win32 Debug Dedicated ServerQ3" +# Name "ftequake - Win32 D3DDebug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" @@ -567,6 +599,8 @@ SOURCE=..\server\svq3_game.c # PROP BASE Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -617,6 +651,8 @@ SOURCE=..\client\cd_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -658,6 +694,8 @@ SOURCE=..\client\cl_cam.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -709,6 +747,8 @@ SOURCE=..\client\cl_cg.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -750,6 +790,8 @@ SOURCE=..\client\cl_demo.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -791,6 +833,8 @@ SOURCE=..\client\cl_ents.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -828,6 +872,8 @@ SOURCE=..\client\cl_ignore.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -869,6 +915,8 @@ SOURCE=..\client\cl_input.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -910,6 +958,8 @@ SOURCE=..\client\cl_main.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -951,6 +1001,8 @@ SOURCE=..\client\cl_parse.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -992,6 +1044,8 @@ SOURCE=..\client\cl_pred.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1033,6 +1087,8 @@ SOURCE=..\client\cl_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1074,6 +1130,8 @@ SOURCE=..\client\cl_tent.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1115,6 +1173,8 @@ SOURCE=..\client\cl_ui.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1158,6 +1218,8 @@ SOURCE=..\client\clq2_cin.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1201,6 +1263,8 @@ SOURCE=..\client\clq2_ents.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1252,6 +1316,8 @@ SOURCE=..\client\clq3_parse.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1293,6 +1359,8 @@ SOURCE=..\client\console.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1334,6 +1402,8 @@ SOURCE=..\client\fragstats.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1375,6 +1445,8 @@ SOURCE=..\client\image.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1416,6 +1488,8 @@ SOURCE=..\client\in_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1457,6 +1531,8 @@ SOURCE=..\client\keys.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1497,6 +1573,8 @@ SOURCE=..\client\m_download.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1538,6 +1616,8 @@ SOURCE=..\client\m_items.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1581,6 +1661,8 @@ SOURCE=..\client\m_master.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1622,6 +1704,8 @@ SOURCE=..\client\m_mp3.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1663,6 +1747,8 @@ SOURCE=..\client\m_multi.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1704,6 +1790,8 @@ SOURCE=..\client\m_options.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1745,6 +1833,8 @@ SOURCE=..\client\m_script.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1786,6 +1876,8 @@ SOURCE=..\client\m_single.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1827,6 +1919,8 @@ SOURCE=..\client\menu.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1870,6 +1964,8 @@ SOURCE=..\client\net_master.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1910,6 +2006,8 @@ SOURCE=..\client\pr_csqc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1953,6 +2051,8 @@ SOURCE=..\client\pr_menu.c # ADD BASE CPP /WX # ADD CPP /WX +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -1994,6 +2094,8 @@ SOURCE=..\client\r_bulleten.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2036,6 +2138,8 @@ SOURCE=..\client\r_efrag.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2077,6 +2181,8 @@ SOURCE=..\client\r_part.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2142,6 +2248,11 @@ SOURCE=..\client\r_partset.c # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -2183,6 +2294,8 @@ SOURCE=..\client\renderer.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2224,6 +2337,8 @@ SOURCE=..\client\renderque.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2267,6 +2382,8 @@ SOURCE=..\client\roq_read.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2308,6 +2425,8 @@ SOURCE=..\client\sbar.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2349,6 +2468,8 @@ SOURCE=..\client\skin.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2389,6 +2510,8 @@ SOURCE=..\client\snd_directx.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2430,6 +2553,8 @@ SOURCE=..\client\snd_dma.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2471,6 +2596,8 @@ SOURCE=..\client\snd_mem.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2512,6 +2639,8 @@ SOURCE=..\client\snd_mix.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2553,6 +2682,8 @@ SOURCE=..\client\snd_ov.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2594,6 +2725,8 @@ SOURCE=..\client\snd_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2635,6 +2768,8 @@ SOURCE=..\client\sys_win.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2676,6 +2811,8 @@ SOURCE=..\client\teamplay.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2717,6 +2854,8 @@ SOURCE=..\client\textedit.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2758,6 +2897,8 @@ SOURCE=..\client\valid.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2799,6 +2940,8 @@ SOURCE=..\client\view.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2840,6 +2983,8 @@ SOURCE=..\client\wad.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2883,6 +3028,8 @@ SOURCE=..\client\zqtp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -2947,6 +3094,11 @@ SOURCE=..\gl\doomclip.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -2991,6 +3143,8 @@ SOURCE=..\gl\gl_alias.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3037,6 +3191,8 @@ SOURCE=..\gl\gl_backend.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3076,6 +3232,8 @@ SOURCE=..\gl\gl_bloom.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3122,6 +3280,8 @@ SOURCE=..\gl\gl_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3190,6 +3350,11 @@ SOURCE=..\gl\gltod3d\gl_fakegl.cpp # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -3227,6 +3392,8 @@ SOURCE=..\gl\gl_heightmap.c # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3275,6 +3442,8 @@ SOURCE=..\gl\gl_hlmdl.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3321,6 +3490,8 @@ SOURCE=..\gl\gl_model.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3367,6 +3538,8 @@ SOURCE=..\gl\gl_ngraph.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3413,6 +3586,8 @@ SOURCE=..\gl\gl_ppl.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3448,6 +3623,8 @@ SOURCE=..\common\gl_q2bsp.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3494,6 +3671,8 @@ SOURCE=..\gl\gl_rlight.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3540,6 +3719,8 @@ SOURCE=..\gl\gl_rmain.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3586,6 +3767,8 @@ SOURCE=..\gl\gl_rmisc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3632,6 +3815,8 @@ SOURCE=..\gl\gl_rsurf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3678,6 +3863,8 @@ SOURCE=..\gl\gl_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3713,6 +3900,8 @@ SOURCE=..\gl\gl_shader.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3759,6 +3948,8 @@ SOURCE=..\gl\gl_vidcommon.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3805,6 +3996,8 @@ SOURCE=..\gl\gl_vidnt.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3851,6 +4044,8 @@ SOURCE=..\gl\gl_warp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3899,6 +4094,8 @@ SOURCE=..\gl\glmod_doom.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -3947,6 +4144,8 @@ SOURCE=..\gl\LTFACE.C # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -4007,6 +4206,11 @@ SOURCE=..\sw\d_edge.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4059,6 +4263,11 @@ SOURCE=..\sw\d_fill.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4111,6 +4320,11 @@ SOURCE=..\sw\d_init.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4163,6 +4377,11 @@ SOURCE=..\sw\d_modech.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4215,6 +4434,11 @@ SOURCE=..\sw\d_part.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4267,6 +4491,11 @@ SOURCE=..\sw\d_polyse.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4319,6 +4548,11 @@ SOURCE=..\sw\d_scan.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4371,6 +4605,11 @@ SOURCE=..\sw\d_sky.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4423,6 +4662,11 @@ SOURCE=..\sw\d_sprite.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4475,6 +4719,11 @@ SOURCE=..\sw\d_surf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4527,6 +4776,11 @@ SOURCE=..\sw\d_trans.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4579,6 +4833,11 @@ SOURCE=..\sw\d_vars.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4631,6 +4890,11 @@ SOURCE=..\sw\d_zpoint.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4683,6 +4947,11 @@ SOURCE=..\sw\nonintel.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4735,6 +5004,11 @@ SOURCE=..\sw\r_aclip.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4787,6 +5061,11 @@ SOURCE=..\sw\r_alias.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4839,6 +5118,11 @@ SOURCE=..\sw\r_bsp.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4891,6 +5175,11 @@ SOURCE=..\sw\r_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4943,6 +5232,11 @@ SOURCE=..\sw\r_edge.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -4995,6 +5289,11 @@ SOURCE=..\sw\r_light.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5047,6 +5346,11 @@ SOURCE=..\sw\r_main.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5099,6 +5403,11 @@ SOURCE=..\sw\r_misc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5151,6 +5460,11 @@ SOURCE=..\sw\r_sky.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5203,6 +5517,11 @@ SOURCE=..\sw\r_sprite.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5255,6 +5574,11 @@ SOURCE=..\sw\r_surf.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5307,6 +5631,11 @@ SOURCE=..\sw\r_vars.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5359,6 +5688,11 @@ SOURCE=..\sw\sw_draw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5411,6 +5745,11 @@ SOURCE=..\sw\sw_model.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5463,6 +5802,11 @@ SOURCE=..\sw\sw_screen.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5515,6 +5859,11 @@ SOURCE=..\sw\vid_ddraw.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5567,6 +5916,11 @@ SOURCE=..\sw\vid_dib.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5619,6 +5973,11 @@ SOURCE=..\sw\vid_win2.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -5636,6 +5995,10 @@ SOURCE=..\common\cmd.c # End Source File # Begin Source File +SOURCE=..\common\com_mesh.c +# End Source File +# Begin Source File + SOURCE=..\common\common.c # ADD CPP /Yc"quakedef.h" # End Source File @@ -5730,6 +6093,8 @@ SOURCE=..\common\q3common.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -5850,6 +6215,11 @@ SOURCE=..\QCLIB\qcc_pr_comp.c # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -5911,6 +6281,11 @@ SOURCE=..\QCLIB\qcc_pr_lex.c # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -5972,6 +6347,11 @@ SOURCE=..\QCLIB\QccMain.c # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -6038,6 +6418,11 @@ SOURCE=..\QCLIB\qcdecomp.c # SUBTRACT BASE CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# SUBTRACT BASE CPP /YX /Yc /Yu +# SUBTRACT CPP /YX /Yc /Yu + !ENDIF # End Source File @@ -6165,6 +6550,11 @@ InputName=d_draw # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6288,6 +6678,11 @@ InputName=d_draw16 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6411,6 +6806,11 @@ InputName=d_parta # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6534,6 +6934,11 @@ InputName=d_polysa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6657,6 +7062,11 @@ InputName=d_scana # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6780,6 +7190,11 @@ InputName=d_spr8 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -6903,6 +7318,11 @@ InputName=d_varsa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7106,6 +7526,21 @@ InputName=math # End Custom Build +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# Begin Custom Build +OutDir=.\D3DDebug +InputPath=..\common\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -7229,6 +7664,11 @@ InputName=r_aclipa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7352,6 +7792,11 @@ InputName=r_aliasa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7475,6 +7920,11 @@ InputName=r_drawa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7598,6 +8048,11 @@ InputName=r_edgea # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7721,6 +8176,11 @@ InputName=r_varsa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -7893,6 +8353,21 @@ InputName=snd_mixa # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# Begin Custom Build +OutDir=.\D3DDebug +InputPath=..\client\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -8016,6 +8491,11 @@ InputName=surf16 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -8139,6 +8619,11 @@ InputName=surf8 # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -8311,6 +8796,21 @@ InputName=sys_wina # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# Begin Custom Build +OutDir=.\D3DDebug +InputPath=..\client\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -8514,6 +9014,21 @@ InputName=worlda # End Custom Build +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# Begin Custom Build +OutDir=.\D3DDebug +InputPath=..\server\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp + ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + !ENDIF # End Source File @@ -8553,6 +9068,8 @@ SOURCE=..\http\ftpclient.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -8588,6 +9105,8 @@ SOURCE=..\http\ftpserver.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -8623,6 +9142,8 @@ SOURCE=..\http\httpclient.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -8658,6 +9179,8 @@ SOURCE=..\http\httpserver.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -8702,6 +9225,8 @@ SOURCE=..\http\webgen.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -8766,6 +9291,11 @@ SOURCE=..\sndcodec\g711.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -8826,6 +9356,11 @@ SOURCE=..\sndcodec\g721.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -8886,6 +9421,11 @@ SOURCE=..\sndcodec\g723_24.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -8946,6 +9486,11 @@ SOURCE=..\sndcodec\g723_40.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9006,6 +9551,11 @@ SOURCE=..\sndcodec\g72x.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9066,6 +9616,11 @@ SOURCE=..\sndcodec\snd_vc.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9126,6 +9681,11 @@ SOURCE=..\sndcodec\snd_voicecodecs.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9186,6 +9746,11 @@ SOURCE=..\sndcodec\voicechat.h # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9252,6 +9817,11 @@ SOURCE=..\server\sv_sys_win.c # ADD BASE CPP /Yu"qwsvdef.h" # ADD CPP /Yu"qwsvdef.h" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9314,6 +9884,104 @@ SOURCE=..\server\svmodel.c # ADD BASE CPP /Yu"qwsvdef.h" # ADD CPP /Yu"qwsvdef.h" +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Group "d3d" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\common\com_mesh.h +# End Source File +# Begin Source File + +SOURCE=..\d3d\d3d_draw.c +# End Source File +# Begin Source File + +SOURCE=..\d3d\d3d_mesh.c +# End Source File +# Begin Source File + +SOURCE=..\d3d\d3d_rmain.c +# End Source File +# Begin Source File + +SOURCE=..\d3d\d3d_rsurf.c +# End Source File +# Begin Source File + +SOURCE=..\d3d\d3dquake.h +# End Source File +# Begin Source File + +SOURCE=..\d3d\vid_d3d.c +# End Source File +# End Group +# Begin Group "d3d9" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\d3d9\d3d9_draw.c +# End Source File +# Begin Source File + +SOURCE=..\d3d9\d3d9_mesh.c +# End Source File +# Begin Source File + +SOURCE=..\d3d9\d3d9_rmain.c +# End Source File +# Begin Source File + +SOURCE=..\d3d9\d3d9_rsurf.c +# End Source File +# Begin Source File + +SOURCE=..\d3d9\d3d9quake.h +# End Source File +# Begin Source File + +SOURCE=..\d3d9\vid_d3d9.c + +!IF "$(CFG)" == "ftequake - Win32 Release" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" + +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -9324,8 +9992,8 @@ SOURCE=..\client\winquake.rc !IF "$(CFG)" == "ftequake - Win32 Release" -# ADD BASE RSC /l 0x809 /i "\ftetgcvs\svn\engine\client" /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" -# ADD RSC /l 0x809 /i "\ftetgcvs\svn\engine\client" /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" /d "MINIMAL" +# ADD BASE RSC /l 0x809 /i "\ftetgcvs\svnd3d\engine\client" /i "\ftetgcvs\svn\engine\client" /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" +# ADD RSC /l 0x809 /i "\ftetgcvs\svnd3d\engine\client" /i "\ftetgcvs\svn\engine\client" /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" /d "MINIMAL" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" @@ -9359,6 +10027,8 @@ SOURCE=..\client\winquake.rc # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + !ENDIF # End Source File @@ -9398,6 +10068,10 @@ SOURCE=..\common\protocol.h SOURCE=..\client\quakedef.h # End Source File +# Begin Source File + +SOURCE=..\client\render.h +# End Source File # End Group # Begin Group "Resource Files" @@ -9483,6 +10157,11 @@ SOURCE=..\..\mp3\libmad\bit.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9551,6 +10230,11 @@ SOURCE=..\..\mp3\libmad\decoder.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9619,6 +10303,11 @@ SOURCE=..\..\mp3\libmad\fixed.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9687,6 +10376,11 @@ SOURCE=..\..\mp3\libmad\frame.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9755,6 +10449,11 @@ SOURCE=..\..\mp3\libmad\huffman.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9823,6 +10522,11 @@ SOURCE=..\..\mp3\libmad\layer12.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9891,6 +10595,11 @@ SOURCE=..\..\mp3\libmad\layer3.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -9959,6 +10668,11 @@ SOURCE=..\client\mymad.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -10027,6 +10741,11 @@ SOURCE=..\..\mp3\libmad\stream.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -10095,6 +10814,11 @@ SOURCE=..\..\mp3\libmad\synth.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -10163,6 +10887,11 @@ SOURCE=..\..\mp3\libmad\timer.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -10231,6 +10960,11 @@ SOURCE=..\..\mp3\libmad\version.c # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index f83e142a7..d4f314a00 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1448,7 +1448,7 @@ void GL_DrawAliasMesh_Sketch (mesh_t *mesh) else */ qglDisableClientState( GL_COLOR_ARRAY ); - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); qglDisableClientState( GL_VERTEX_ARRAY ); qglDisableClientState( GL_COLOR_ARRAY ); @@ -1554,7 +1554,7 @@ void GL_DrawAliasMesh (mesh_t *mesh, int texnum) qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertexes, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); qglDisableClientState( GL_VERTEX_ARRAY ); qglDisableClientState( GL_COLOR_ARRAY ); @@ -1566,41 +1566,6 @@ void GL_DrawAliasMesh (mesh_t *mesh, int texnum) #endif } -qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs) -{ - int i; - vec3_t wmin, wmax; - float fmin, fmax; - - //convert the model's bbox to the expanded maximum size of the entity, as drawn with this model. - //The result is an axial box, which we pass to R_CullBox - - for (i = 0; i < 3; i++) - { - fmin = DotProduct(modmins, e->axis[i]); - fmax = DotProduct(modmaxs, e->axis[i]); - - if (fmin > -16) - fmin = -16; - if (fmax < 16) - fmax = 16; - - if (fmin < fmax) - { - wmin[i] = e->origin[i]+fmin; - wmax[i] = e->origin[i]+fmax; - } - else - { //box went inside out - wmin[i] = e->origin[i]+fmax; - wmax[i] = e->origin[i]+fmin; - } - } - - - return R_CullBox(wmin, wmax); -} - #ifdef Q3SHADERS mfog_t *CM_FogForOrigin(vec3_t org); #endif @@ -1982,7 +1947,7 @@ void R_DrawGAliasModel (entity_t *e) VectorCopy(r_refdef.vieworg, currententity->origin); } -#ifdef Q3SHADERS +#if defined(Q3SHADERS) && defined(Q2BSPS) fog = CM_FogForOrigin(currententity->origin); #endif @@ -2338,7 +2303,7 @@ void R_AliasGenerateTextureVectors(mesh_t *mesh, float *normal3f, float *svector { int i; float sdir[3], tdir[3], normal[3], *v; - int *e; + index_t *e; float *vertex3f = (float*)mesh->xyz_array; float *texcoord2f = (float*)mesh->st_array; // clear the vectors @@ -2486,7 +2451,7 @@ void R_DrawMeshBumpmap(mesh_t *mesh, galiastexnum_t *skin, vec3_t lightdir) } else { //we don't support 3tmus, so draw the bumps, and multiply the rest over the top - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); qglDisable(GL_TEXTURE_CUBE_MAP_ARB); GL_MBind(mtexid0, skin->base); } @@ -2494,7 +2459,7 @@ void R_DrawMeshBumpmap(mesh_t *mesh, galiastexnum_t *skin, vec3_t lightdir) qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); @@ -2682,7 +2647,7 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius) -static int R_FindTriangleWithEdge ( int *indexes, int numtris, int start, int end, int ignore) +static int R_FindTriangleWithEdge ( index_t *indexes, int numtris, index_t start, index_t end, int ignore) { int i; int match, count; @@ -2712,10 +2677,10 @@ static int R_FindTriangleWithEdge ( int *indexes, int numtris, int start, int en return match; } -static void R_BuildTriangleNeighbours ( int *neighbours, int *indexes, int numtris ) +static void R_BuildTriangleNeighbours ( int *neighbours, index_t *indexes, int numtris ) { int i, *n; - int *index; + index_t *index; for (i = 0, index = indexes, n = neighbours; i < numtris; i++, index += 3, n += 3) { @@ -2796,3336 +2761,6 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris, } } } - - -char **skinfilelist; -int skinfilecount; - -static qboolean VARGS TryAddSkin(char *skinname, ...) -{ - va_list argptr; - char string[MAX_QPATH]; - - //make sure we don't add it twice - int i; - - - va_start (argptr, skinname); - vsnprintf (string,sizeof(string)-1, skinname,argptr); - va_end (argptr); - string[MAX_QPATH-1] = '\0'; - - for (i = 0; i < skinfilecount; i++) - { - if (!strcmp(skinfilelist[i], string)) - return true; //already added - } - - if (!COM_FCheckExists(string)) - return false; - - skinfilelist = BZ_Realloc(skinfilelist, sizeof(*skinfilelist)*(skinfilecount+1)); - skinfilelist[skinfilecount] = Z_Malloc(strlen(string)+1); - strcpy(skinfilelist[skinfilecount], string); - skinfilecount++; - return true; -} - -int GL_EnumerateSkins(char *name, int size, void *param) -{ - TryAddSkin(name); - return true; -} - -int GL_BuildSkinFileList(char *modelname) -{ - int i; - char skinfilename[MAX_QPATH]; - - //flush the old list - for (i = 0; i < skinfilecount; i++) - { - Z_Free(skinfilelist[i]); - skinfilelist[i] = NULL; - } - skinfilecount=0; - - COM_StripExtension(modelname, skinfilename, sizeof(skinfilename)); - - //try and add numbered skins, and then try fixed names. - for (i = 0; ; i++) - { - if (!TryAddSkin("%s_%i.skin", modelname, i)) - { - if (i == 0) - { - if (!TryAddSkin("%s_default.skin", skinfilename, i)) - break; - } - else if (i == 1) - { - if (!TryAddSkin("%s_blue.skin", skinfilename, i)) - break; - } - else if (i == 2) - { - if (!TryAddSkin("%s_red.skin", skinfilename, i)) - break; - } - else if (i == 3) - { - if (!TryAddSkin("%s_green.skin", skinfilename, i)) - break; - } - else if (i == 4) - { - if (!TryAddSkin("%s_yellow.skin", skinfilename, i)) - break; - } - else - break; - } - } - -// if (strstr(modelname, "lower") || strstr(modelname, "upper") || strstr(modelname, "head")) -// { - COM_EnumerateFiles(va("%s_*.skin", modelname), GL_EnumerateSkins, NULL); - COM_EnumerateFiles(va("%s_*.skin", skinfilename), GL_EnumerateSkins, NULL); -// } -// else -// COM_EnumerateFiles("*.skin", GL_EnumerateSkins, NULL); - - return skinfilecount; -} - -//This is a hack. It uses an assuption about q3 player models. -void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum, char *skinfilename) -{ - const char *f = NULL, *p; - int len; - - if (skinnum >= skinfilecount) - return; - - if (skinfilename) - strcpy(skinfilename, skinfilelist[skinnum]); - - f = COM_LoadTempFile2(skinfilelist[skinnum]); - - while(f) - { - f = COM_ParseToken(f,NULL); - if (!f) - return; - if (!strcmp(com_token, "replace")) - { - f = COM_ParseToken(f, NULL); - - len = strlen(com_token); - - //copy surfname -> out, until we meet the part we need to replace - while(*surfname) - { - if (!strncmp(com_token, surfname, len)) - //found it - { - surfname+=len; - f = COM_ParseToken(f, NULL); - p = com_token; - while(*p) //copy the replacement - *out++ = *p++; - - while(*surfname) //copy the remaining - *out++ = *surfname++; - *out++ = '\0'; //we didn't find it. - return; - } - *out++ = *surfname++; - } - *out++ = '\0'; //we didn't find it. - return; - } - else - { - while(*f == ' ' || *f == '\t') - f++; - if (*f == ',') - { - if (!strcmp(com_token, surfname)) - { - f++; - COM_ParseToken(f, NULL); - strcpy(out, com_token); - return; - } - } - } - - p = strchr(f, '\n'); - if (!p) - f = f+strlen(f); - else - f = p+1; - if (!*f) - break; - } -} - -void GL_LoadSkinFile(galiastexnum_t *texnum, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) -{ - char shadername[MAX_QPATH]; - Q_strncpyz(shadername, surfacename, sizeof(shadername)); - - GL_ParseQ3SkinFile(shadername, surfacename, loadmodel->name, skinnumber, NULL); - -#ifdef Q3SHADERS - texnum->shader = R_RegisterSkin(shadername); #endif - texnum->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); -} - -#endif //SERVERONLY - - -//Q1 model loading -#if 1 -static galiasinfo_t *galias; -static dmdl_t *pq1inmodel; -#define NUMVERTEXNORMALS 162 -extern float r_avertexnormals[NUMVERTEXNORMALS][3]; -static void *QTest_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) -{ - galiaspose_t *pose; - galiasgroup_t *frame; - dtrivertx_t *pinframe; - qtestaliasframe_t *frameinfo; - int i, j; - - vec3_t *normals; - vec3_t *verts; - - frame = (galiasgroup_t*)((char *)galias + galias->groupofs); - - for (i = 0; i < pq1inmodel->numframes; i++) - { - switch(LittleLong(pframetype->type)) - { - case ALIAS_SINGLE: - frameinfo = (qtestaliasframe_t*)((char *)(pframetype+1)); - pinframe = (dtrivertx_t*)((char*)frameinfo+sizeof(qtestaliasframe_t)); - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*2*galias->numverts); - frame->poseofs = (char *)pose - (char *)frame; - frame->numposes = 1; - galias->groups++; - - frame->name[0] = '\0'; - - verts = (vec3_t *)(pose+1); - normals = &verts[galias->numverts]; - pose->ofsverts = (char *)verts - (char *)pose; -#ifndef SERVERONLY - pose->ofsnormals = (char *)normals - (char *)pose; -#endif - - for (j = 0; j < pq1inmodel->numverts; j++) - { - verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0]; - verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1]; - verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2]; -#ifndef SERVERONLY - VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]); -#endif - if (seamremaps[j] != j) - { - VectorCopy(verts[j], verts[seamremaps[j]]); - VectorCopy(normals[j], normals[seamremaps[j]]); - } - } - -// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts); - - pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts]; - break; - default: - Con_Printf(S_ERROR "Bad frame type for QTest model in %s\n", loadmodel->name); - return NULL; - } - frame++; - } - return pframetype; -} - -static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) -{ - galiaspose_t *pose; - galiasgroup_t *frame; - dtrivertx_t *pinframe; - daliasframe_t *frameinfo; - int i, j, k; - daliasgroup_t *ingroup; - daliasinterval_t *intervals; - float sinter; - - vec3_t *normals; - vec3_t *verts; - - frame = (galiasgroup_t*)((char *)galias + galias->groupofs); - - for (i = 0; i < pq1inmodel->numframes; i++) - { - switch(LittleLong(pframetype->type)) - { - case ALIAS_SINGLE: - frameinfo = (daliasframe_t*)((char *)(pframetype+1)); - pinframe = (dtrivertx_t*)((char*)frameinfo+sizeof(daliasframe_t)); - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*2*galias->numverts); - frame->poseofs = (char *)pose - (char *)frame; - frame->numposes = 1; - galias->groups++; - - Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name)); - - verts = (vec3_t *)(pose+1); - normals = &verts[galias->numverts]; - pose->ofsverts = (char *)verts - (char *)pose; -#ifndef SERVERONLY - pose->ofsnormals = (char *)normals - (char *)pose; -#endif - - for (j = 0; j < pq1inmodel->numverts; j++) - { - verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0]; - verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1]; - verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2]; -#ifndef SERVERONLY - VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]); -#endif - if (seamremaps[j] != j) - { - VectorCopy(verts[j], verts[seamremaps[j]]); - VectorCopy(normals[j], normals[seamremaps[j]]); - } - } - -// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts); - - pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts]; - break; - - case ALIAS_GROUP: - case ALIAS_GROUP_SWAPPED: // prerelease - ingroup = (daliasgroup_t *)(pframetype+1); - - pose = (galiaspose_t *)Hunk_Alloc(LittleLong(ingroup->numframes)*(sizeof(galiaspose_t) + sizeof(vec3_t)*2*galias->numverts)); - frame->poseofs = (char *)pose - (char *)frame; - frame->numposes = LittleLong(ingroup->numframes); - frame->loop = true; - galias->groups++; - - verts = (vec3_t *)(pose+frame->numposes); - normals = &verts[galias->numverts]; - - intervals = (daliasinterval_t *)(ingroup+1); - sinter = LittleFloat(intervals->interval); - if (sinter <= 0) - sinter = 0.1; - frame->rate = 1/sinter; - - pinframe = (dtrivertx_t *)(intervals+frame->numposes); - for (k = 0; k < frame->numposes; k++) - { - pose->ofsverts = (char *)verts - (char *)pose; -#ifndef SERVERONLY - pose->ofsnormals = (char *)normals - (char *)pose; -#endif - - frameinfo = (daliasframe_t*)pinframe; - pinframe = (dtrivertx_t *)((char *)frameinfo + sizeof(daliasframe_t)); - - if (k == 0) - Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name)); - - for (j = 0; j < pq1inmodel->numverts; j++) - { - verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0]; - verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1]; - verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2]; -#ifndef SERVERONLY - VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]); -#endif - if (seamremaps[j] != j) - { - VectorCopy(verts[j], verts[seamremaps[j]]); - VectorCopy(normals[j], normals[seamremaps[j]]); - } - } - verts = &normals[galias->numverts]; - normals = &verts[galias->numverts]; - pose++; - - pinframe += pq1inmodel->numverts; - } - -// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts); - - pframetype = (daliasframetype_t *)pinframe; - break; - default: - Con_Printf(S_ERROR "Bad frame type in %s\n", loadmodel->name); - return NULL; - } - frame++; - } - return pframetype; -} - -#ifdef SERVERONLY //greatly reduced version of Q1_LoadSkins (too many #ifdefs -static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) -{ - int i; - int s; - int *count; - float *intervals; - qbyte *data; - - s = pq1inmodel->skinwidth*pq1inmodel->skinheight; - for (i = 0; i < pq1inmodel->numskins; i++) - { - switch(LittleLong(pskintype->type)) - { - case ALIAS_SKIN_SINGLE: - pskintype = (daliasskintype_t *)((char *)(pskintype+1)+s); - break; - - default: - count = (int *)(pskintype+1); - intervals = (float *)(count+1); - data = (qbyte *)(intervals + LittleLong(*count)); - data += s*LittleLong(*count); - pskintype = (daliasskintype_t *)data; - break; - } - } - galias->numskins=pq1inmodel->numskins; - return pskintype; -} -#else -static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) -{ - extern cvar_t gl_bump; - galiastexnum_t *texnums; - char skinname[MAX_QPATH]; - int i; - int s, t; - float sinter; - daliasskingroup_t *count; - daliasskininterval_t *intervals; - qbyte *data, *saved; - galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); - - int texture; - int fbtexture; - int bumptexture; - - s = pq1inmodel->skinwidth*pq1inmodel->skinheight; - for (i = 0; i < pq1inmodel->numskins; i++) - { - switch(LittleLong(pskintype->type)) - { - case ALIAS_SKIN_SINGLE: - outskin->skinwidth = pq1inmodel->skinwidth; - outskin->skinheight = pq1inmodel->skinheight; - - //LH's naming scheme ("models" is likly to be ignored) - fbtexture = 0; - bumptexture = 0; - snprintf(skinname, sizeof(skinname), "%s_%i.", loadmodel->name, i); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (texture) - { - snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadmodel->name, i); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (gl_bump.value) - { - snprintf(skinname, sizeof(skinname), "%s_%i_bump", loadmodel->name, i); - bumptexture = Mod_LoadBumpmapTexture(skinname, "models"); - } - } - else - { - snprintf(skinname, sizeof(skinname), "%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (texture && r_fb_models.value) - { - snprintf(skinname, sizeof(skinname), "%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); - } - if (texture && gl_bump.value) - { - snprintf(skinname, sizeof(skinname), "%s_%i_bump", loadname, i); - bumptexture = Mod_LoadBumpmapTexture(skinname, "models"); - } - } - -//but only preload it if we have no replacement. - if (!texture) - { - //we're not using 24bits - texnums = Hunk_Alloc(sizeof(*texnums)+s); - saved = (qbyte*)(texnums+1); - outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin; - memcpy(saved, pskintype+1, s); - GLMod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); - -//the extra underscore is to stop - snprintf(skinname, sizeof(skinname), "%s__%i", loadname, i); - texture = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); - if (r_fb_models.value) - { - snprintf(skinname, sizeof(skinname), "%s__%i_luma", loadname, i); - fbtexture = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); - } - if (gl_bump.value) - { - snprintf(skinname, sizeof(skinname), "%s__%i_bump", loadname, i); - bumptexture = GL_LoadTexture8Bump(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); - } - } - else - texnums = Hunk_Alloc(sizeof(*texnums)); - outskin->texnums=1; - - outskin->ofstexnums = (char *)texnums - (char *)outskin; - -#ifdef Q3SHADERS - if (cls.allow_shaders) - { - sprintf(skinname, "%s_%i", loadname, i); - texnums->shader = R_RegisterCustom (skinname, NULL); - } -#endif - - - texnums->base = texture; - texnums->fullbright = fbtexture; - texnums->bump = bumptexture; - - pskintype = (daliasskintype_t *)((char *)(pskintype+1)+s); - break; - - default: - outskin->skinwidth = pq1inmodel->skinwidth; - outskin->skinheight = pq1inmodel->skinheight; - count = (daliasskingroup_t*)(pskintype+1); - intervals = (daliasskininterval_t *)(count+1); - outskin->texnums = LittleLong(count->numskins); - data = (qbyte *)(intervals + outskin->texnums); - texnums = Hunk_Alloc(sizeof(*texnums)*outskin->texnums); - outskin->ofstexnums = (char *)texnums - (char *)outskin; - outskin->ofstexels = 0; - sinter = LittleFloat(intervals[0].interval); - if (sinter <= 0) - sinter = 0.1; - outskin->skinspeed = 1/sinter; - - for (t = 0; t < outskin->texnums; t++,data+=s, texnums++) - { - texture = 0; - fbtexture = 0; - - //LH naming scheme - if (!texture) - { - sprintf(skinname, "%s_%i_%i.", loadmodel->name, i, t); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - } - if (!fbtexture && r_fb_models.value) - { - sprintf(skinname, "%s_%i_%i_luma.", loadmodel->name, i, t); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); - } - - //Fuhquake naming scheme - if (!texture) - { - sprintf(skinname, "%s_%i_%i", loadname, i, t); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - } - if (!fbtexture && r_fb_models.value) - { - sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); - } - - if (!texture || (!fbtexture && r_fb_models.value)) - { - if (t == 0) - { - saved = Hunk_Alloc(s); - outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin; - } - else - saved = BZ_Malloc(s); - memcpy(saved, data, s); - GLMod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); - if (!texture) - { - sprintf(skinname, "%s_%i_%i", loadname, i, t); - texture = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); - } - - - if (!fbtexture && r_fb_models.value) - { - sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); - fbtexture = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); - } - - if (t != 0) //only keep the first. - BZ_Free(saved); - } - -#ifdef Q3SHADERS - if (cls.allow_shaders) - { - sprintf(skinname, "%s_%i_%i", loadname, i, t); - texnums->shader = R_RegisterCustom (skinname, NULL); - } -#endif - - texnums->base = texture; - texnums->fullbright = fbtexture; - } - pskintype = (daliasskintype_t *)data; - break; - } - outskin++; - } - galias->numskins=pq1inmodel->numskins; - return pskintype; -} -#endif - -qboolean GL_LoadQ1Model (model_t *mod, void *buffer) -{ -#ifndef SERVERONLY - vec2_t *st_array; - int j; -#endif - int hunkstart, hunkend, hunktotal; - int version; - int i, onseams; - dstvert_t *pinstverts; - dtriangle_t *pintriangles; - int *seamremap; - index_t *indexes; - qboolean qtest = false; - - int size; - - loadmodel=mod; - - Mod_DoCRC(loadmodel, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - pq1inmodel = (dmdl_t *)buffer; - - loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT; - - version = LittleLong(pq1inmodel->version); - if (version == QTESTALIAS_VERSION) - qtest = true; - else if (version != ALIAS_VERSION) - { - Con_Printf (S_ERROR "%s has wrong version number (%i should be %i)\n", - mod->name, version, ALIAS_VERSION); - return false; - } - - seamremap = (int*)pq1inmodel; //I like overloading locals. - - if (qtest) - i = sizeof(dmdl_t)/4 - sizeof(int)*2 - 1; - else - i = sizeof(dmdl_t)/4 - 1; - - for (; i >= 0; i--) - seamremap[i] = LittleLong(seamremap[i]); - - if (pq1inmodel->numframes < 1 || - pq1inmodel->numskins < 1 || - pq1inmodel->numtris < 1 || - pq1inmodel->numverts < 3 || - pq1inmodel->skinheight < 1 || - pq1inmodel->skinwidth < 1) - { - Con_Printf(S_ERROR "Model %s has an invalid quantity\n", mod->name); - return false; - } - - if (qtest) - mod->flags = 0; // Qtest has no flags in header - else - mod->flags = pq1inmodel->flags; - - size = sizeof(galiasinfo_t) -#ifndef SERVERONLY - + pq1inmodel->numskins*sizeof(galiasskin_t) -#endif - + pq1inmodel->numframes*sizeof(galiasgroup_t); - - galias = Hunk_Alloc(size); - galias->groupofs = sizeof(*galias); -#ifndef SERVERONLY - galias->ofsskins = sizeof(*galias)+pq1inmodel->numframes*sizeof(galiasgroup_t); -#endif - galias->nextsurf = 0; - -//skins - if (qtest) - pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)((char *)buffer + sizeof(dmdl_t) - sizeof(int)*2), 0); - else if( mod->flags & EF_HOLEY ) - pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)(pq1inmodel+1), 3); - else if( mod->flags & EF_TRANSPARENT ) - pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)(pq1inmodel+1), 2); - else if( mod->flags & EF_SPECIAL_TRANS ) - pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)(pq1inmodel+1), 4); - else - pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)(pq1inmodel+1), 0); - -// pinstverts = (dstvert_t *)Q1_LoadSkins((daliasskintype_t *)(pq1inmodel+1)); - - //count number of verts that are onseam. - for (onseams=0,i = 0; i < pq1inmodel->numverts; i++) - { - if (pinstverts[i].onseam) - onseams++; - } - seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numverts); - - galias->numverts = pq1inmodel->numverts+onseams; - - //st -#ifndef SERVERONLY - st_array = Hunk_Alloc(sizeof(*st_array)*(pq1inmodel->numverts+onseams)); - galias->ofs_st_array = (char *)st_array - (char *)galias; - for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++) - { - st_array[i][0] = (LittleLong(pinstverts[i].s)+0.5)/(float)pq1inmodel->skinwidth; - st_array[i][1] = (LittleLong(pinstverts[i].t)+0.5)/(float)pq1inmodel->skinheight; - - if (pinstverts[i].onseam) - { - st_array[j][0] = st_array[i][0]+0.5; - st_array[j][1] = st_array[i][1]; - seamremap[i] = j; - j++; - } - else - seamremap[i] = i; - } -#endif - - //trianglelists; - pintriangles = (dtriangle_t *)&pinstverts[pq1inmodel->numverts]; - - galias->numindexes = pq1inmodel->numtris*3; - indexes = Hunk_Alloc(galias->numindexes*sizeof(*indexes)); - galias->ofs_indexes = (char *)indexes - (char *)galias; - for (i=0 ; inumtris ; i++) - { - if (!pintriangles[i].facesfront) - { - indexes[i*3+0] = seamremap[LittleLong(pintriangles[i].vertindex[0])]; - indexes[i*3+1] = seamremap[LittleLong(pintriangles[i].vertindex[1])]; - indexes[i*3+2] = seamremap[LittleLong(pintriangles[i].vertindex[2])]; - } - else - { - indexes[i*3+0] = LittleLong(pintriangles[i].vertindex[0]); - indexes[i*3+1] = LittleLong(pintriangles[i].vertindex[1]); - indexes[i*3+2] = LittleLong(pintriangles[i].vertindex[2]); - } - } - - //frames - if (qtest) - { - if (QTest_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap) == NULL) - { - BZ_Free(seamremap); - Hunk_FreeToLowMark (hunkstart); - return false; - } - } - else - { - if (Q1_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap) == NULL) - { - BZ_Free(seamremap); - Hunk_FreeToLowMark (hunkstart); - return false; - } - } - BZ_Free(seamremap); - - -#ifndef SERVERONLY - if (r_shadows.value) - { - int *neighbours; - neighbours = Hunk_Alloc(sizeof(int)*3*pq1inmodel->numtris); - galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; - R_BuildTriangleNeighbours(neighbours, indexes, pq1inmodel->numtris); - } -#endif - VectorCopy (pq1inmodel->scale_origin, mod->mins); - VectorMA (mod->mins, 255, pq1inmodel->scale, mod->maxs); -// -// move the complete, relocatable alias model to the cache -// - hunkend = Hunk_LowMark (); - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, galias, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - mod->funcs.Trace = GLMod_Trace; - - return true; -} -#endif - - -int Mod_ReadFlagsFromMD1(char *name, int md3version) -{ - dmdl_t *pinmodel; - char fname[MAX_QPATH]; - COM_StripExtension(name, fname, sizeof(fname)); - COM_DefaultExtension(fname, ".mdl", sizeof(fname)); - - if (strcmp(name, fname)) //md3 renamed as mdl - { - COM_StripExtension(name, fname, sizeof(fname)); //seeing as the md3 is named over the mdl, - COM_DefaultExtension(fname, ".md1", sizeof(fname));//read from a file with md1 (one, not an ell) - return 0; - } - - pinmodel = (dmdl_t *)COM_LoadTempFile(fname); - - if (!pinmodel) //not found - return 0; - - if (LittleLong(pinmodel->ident) != IDPOLYHEADER) - return 0; - if (LittleLong(pinmodel->version) != ALIAS_VERSION) - return 0; - return LittleLong(pinmodel->flags); -} - -#ifdef MD2MODELS - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Q2 model loading - -static galiasinfo_t *galias; -static model_t *loadmodel; -static md2_t *pq2inmodel; -#define Q2NUMVERTEXNORMALS 162 -extern vec3_t bytedirs[Q2NUMVERTEXNORMALS]; - -static void Q2_LoadSkins(char *skins) -{ -#ifndef SERVERONLY - int i; - galiastexnum_t *texnums; - galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); - - for (i = 0; i < LittleLong(pq2inmodel->num_skins); i++, outskin++) - { - texnums = Hunk_Alloc(sizeof(*texnums)); - outskin->ofstexnums = (char *)texnums - (char *)outskin; - outskin->texnums=1; - - COM_CleanUpPath(skins); //blooming tanks. - texnums->base = Mod_LoadReplacementTexture(skins, "models", true, false, true); - texnums->shader = R_RegisterCustom(skins, NULL); - if (!texnums->base && !texnums->shader) - Con_Printf("Couldn't load %s\n", skins); - outskin->skinwidth = 0; - outskin->skinheight = 0; - outskin->skinspeed = 0; - - skins += MD2MAX_SKINNAME; - } -#endif - galias->numskins = LittleLong(pq2inmodel->num_skins); - -#ifndef SERVERONLY - outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); - outskin += galias->numskins - 1; - if (galias->numskins) - { - texnums = (galiastexnum_t*)((char *)outskin +outskin->ofstexnums); - if (texnums->base) - return; - if (texnums->shader) - return; - - galias->numskins--; - } -#endif -} - -#define MD2_MAX_TRIANGLES 4096 -qboolean GL_LoadQ2Model (model_t *mod, void *buffer) -{ -#ifndef SERVERONLY - dmd2stvert_t *pinstverts; - vec2_t *st_array; - vec3_t *normals; -#endif - - int hunkstart, hunkend, hunktotal; - int version; - int i, j; - dmd2triangle_t *pintri; - index_t *indexes; - int numindexes; - - vec3_t min; - vec3_t max; - - galiaspose_t *pose; - galiasgroup_t *poutframe; - dmd2aliasframe_t *pinframe; - int framesize; - vec3_t *verts; - - int indremap[MD2_MAX_TRIANGLES*3]; - unsigned short ptempindex[MD2_MAX_TRIANGLES*3], ptempstindex[MD2_MAX_TRIANGLES*3]; - - int numverts; - - int size; - - - loadmodel=mod; - - loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - pq2inmodel = (md2_t *)buffer; - - version = LittleLong (pq2inmodel->version); - if (version != MD2ALIAS_VERSION) - { - Con_Printf (S_ERROR "%s has wrong version number (%i should be %i)\n", - mod->name, version, MD2ALIAS_VERSION); - return false; - } - - if (LittleLong(pq2inmodel->num_frames) < 1 || - LittleLong(pq2inmodel->num_skins) < 0 || - LittleLong(pq2inmodel->num_tris) < 1 || - LittleLong(pq2inmodel->num_xyz) < 3 || - LittleLong(pq2inmodel->num_st) < 3 || - LittleLong(pq2inmodel->skinheight) < 1 || - LittleLong(pq2inmodel->skinwidth) < 1) - { - Con_Printf(S_ERROR "Model %s has an invalid quantity\n", mod->name); - return false; - } - - mod->flags = 0; - - loadmodel->numframes = LittleLong(pq2inmodel->num_frames); - - size = sizeof(galiasinfo_t) -#ifndef SERVERONLY - + LittleLong(pq2inmodel->num_skins)*sizeof(galiasskin_t) -#endif - + LittleLong(pq2inmodel->num_frames)*sizeof(galiasgroup_t); - - galias = Hunk_Alloc(size); - galias->groupofs = sizeof(*galias); -#ifndef SERVERONLY - galias->ofsskins = sizeof(*galias)+LittleLong(pq2inmodel->num_frames)*sizeof(galiasgroup_t); -#endif - galias->nextsurf = 0; - -//skins - Q2_LoadSkins(((char *)pq2inmodel+LittleLong(pq2inmodel->ofs_skins))); - - //trianglelists; - pintri = (dmd2triangle_t *)((char *)pq2inmodel + LittleLong(pq2inmodel->ofs_tris)); - - - for (i=0 ; inum_tris) ; i++, pintri++) - { - for (j=0 ; j<3 ; j++) - { - ptempindex[i*3+j] = ( unsigned short )LittleShort ( pintri->xyz_index[j] ); - ptempstindex[i*3+j] = ( unsigned short )LittleShort ( pintri->st_index[j] ); - } - } - - numindexes = galias->numindexes = LittleLong(pq2inmodel->num_tris)*3; - indexes = Hunk_Alloc(galias->numindexes*sizeof(*indexes)); - galias->ofs_indexes = (char *)indexes - (char *)galias; - memset ( indremap, -1, sizeof(indremap) ); - numverts=0; - - for ( i = 0; i < numindexes; i++ ) - { - if ( indremap[i] != -1 ) { - continue; - } - - for ( j = 0; j < numindexes; j++ ) - { - if ( j == i ) { - continue; - } - - if ( (ptempindex[i] == ptempindex[j]) && (ptempstindex[i] == ptempstindex[j]) ) { - indremap[j] = i; - } - } - } - - // count unique vertexes - for ( i = 0; i < numindexes; i++ ) - { - if ( indremap[i] != -1 ) { - continue; - } - - indexes[i] = numverts++; - indremap[i] = i; - } - - Con_DPrintf ( "%s: remapped %i verts to %i\n", mod->name, LittleLong(pq2inmodel->num_xyz), numverts ); - - galias->numverts = numverts; - - // remap remaining indexes - for ( i = 0; i < numindexes; i++ ) - { - if ( indremap[i] != i ) { - indexes[i] = indexes[indremap[i]]; - } - } - -// s and t vertices -#ifndef SERVERONLY - pinstverts = ( dmd2stvert_t * ) ( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_st) ); - st_array = Hunk_Alloc(sizeof(*st_array)*(numverts)); - galias->ofs_st_array = (char *)st_array - (char *)galias; - - for (j=0 ; jskinwidth)); - st_array[indexes[j]][1] = (float)(((double)LittleShort (pinstverts[ptempstindex[indremap[j]]].t) + 0.5f) /LittleLong(pq2inmodel->skinheight)); - } -#endif - - //frames - ClearBounds ( mod->mins, mod->maxs ); - - poutframe = (galiasgroup_t*)((char *)galias + galias->groupofs); - framesize = LittleLong (pq2inmodel->framesize); - for (i=0 ; inum_frames) ; i++) - { - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*numverts -#ifndef SERVERONLY - + sizeof(vec3_t)*numverts -#endif - ); - poutframe->poseofs = (char *)pose - (char *)poutframe; - poutframe->numposes = 1; - galias->groups++; - - verts = (vec3_t *)(pose+1); - pose->ofsverts = (char *)verts - (char *)pose; -#ifndef SERVERONLY - normals = &verts[galias->numverts]; - pose->ofsnormals = (char *)normals - (char *)pose; -#endif - - - pinframe = ( dmd2aliasframe_t * )( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_frames) + i * framesize ); - Q_strncpyz(poutframe->name, pinframe->name, sizeof(poutframe->name)); - - for (j=0 ; j<3 ; j++) - { - pose->scale[j] = LittleFloat (pinframe->scale[j]); - pose->scale_origin[j] = LittleFloat (pinframe->translate[j]); - } - - for (j=0 ; jscale_origin[0]+pose->scale[0]*pinframe->verts[ptempindex[indremap[j]]].v[0]; - verts[indexes[j]][1] = pose->scale_origin[1]+pose->scale[1]*pinframe->verts[ptempindex[indremap[j]]].v[1]; - verts[indexes[j]][2] = pose->scale_origin[2]+pose->scale[2]*pinframe->verts[ptempindex[indremap[j]]].v[2]; -#ifndef SERVERONLY - VectorCopy(bytedirs[pinframe->verts[ptempindex[indremap[j]]].lightnormalindex], normals[indexes[j]]); -#endif - } - -// Mod_AliasCalculateVertexNormals ( numindexes, poutindex, numverts, poutvertex, qfalse ); - - VectorCopy ( pose->scale_origin, min ); - VectorMA ( pose->scale_origin, 255, pose->scale, max ); - -// poutframe->radius = RadiusFromBounds ( min, max ); - -// mod->radius = max ( mod->radius, poutframe->radius ); - AddPointToBounds ( min, mod->mins, mod->maxs ); - AddPointToBounds ( max, mod->mins, mod->maxs ); - -// GL_GenerateNormals((float*)verts, (float*)normals, indexes, numindexes/3, numverts); - - poutframe++; - } - - - -#ifndef SERVERONLY - if (r_shadows.value) - { - int *neighbours; - neighbours = Hunk_Alloc(sizeof(int)*3*LittleLong(pq2inmodel->num_tris)); - galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; - R_BuildTriangleNeighbours(neighbours, indexes, LittleLong(pq2inmodel->num_tris)); - } -#endif - /* - VectorCopy (pq2inmodel->scale_origin, mod->mins); - VectorMA (mod->mins, 255, pq2inmodel->scale, mod->maxs); - */ -// -// move the complete, relocatable alias model to the cache -// - hunkend = Hunk_LowMark (); - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, galias, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - mod->funcs.Trace = GLMod_Trace; - - return true; -} - -#endif - - - - - - - - - - - - - - - - -typedef struct { - char name[MAX_QPATH]; - vec3_t org; - float ang[3][3]; -} md3tag_t; - - - -#ifndef SERVERONLY -qboolean GLMod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result) -#else -qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result) -#endif -{ - galiasinfo_t *inf; - - - if (!model || model->type != mod_alias) - return false; - - inf = Mod_Extradata(model); -#ifdef SKELETALMODELS - if (inf->numbones) - { - galiasbone_t *bone; - galiasgroup_t *g1, *g2; - - float tempmatrix[12]; //flipped between this and bonematrix - float *matrix; //the matrix for a single bone in a single pose. - float m[12]; //combined interpolated version of 'matrix'. - int b, k; //counters - - float *pose[4]; //the per-bone matricies (one for each pose) - float plerp[4]; //the ammount of that pose to use (must combine to 1) - int numposes = 0; - - if (tagnum <= 0 || tagnum > inf->numbones) - return false; - tagnum--; //tagnum 0 is 'use my angles/org' - - if (frame1 < 0 || frame1 >= inf->groups) - return false; - if (frame2 < 0 || frame2 >= inf->groups) - { - f2ness = 0; - frame2 = frame1; - } - - bone = (galiasbone_t*)((char*)inf + inf->ofsbones); -//the higher level merges old/new anims, but we still need to blend between automated frame-groups. - g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1); - g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2); - - f1time *= g1->rate; - frame1 = (int)f1time%g1->numposes; - frame2 = ((int)f1time+1)%g1->numposes; - f1time = f1time - (int)f1time; - pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame1); - plerp[numposes] = (1-f1time) * (1-f2ness); - numposes++; - if (frame1 != frame2) - { - pose[numposes] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*inf->numbones*12*frame2); - plerp[numposes] = f1time * (1-f2ness); - numposes++; - } - if (f2ness) - { - f2time *= g2->rate; - frame1 = (int)f2time%g2->numposes; - frame2 = ((int)f2time+1)%g2->numposes; - f2time = f2time - (int)f2time; - pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame1); - plerp[numposes] = (1-f2time) * f2ness; - numposes++; - if (frame1 != frame2) - { - pose[numposes] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*inf->numbones*12*frame2); - plerp[numposes] = f2time * f2ness; - numposes++; - } - } - - //set up the identity matrix - for (k = 0;k < 12;k++) - result[k] = 0; - result[0] = 1; - result[5] = 1; - result[10] = 1; - while(tagnum >= 0) - { - //set up the per-bone transform matrix - for (k = 0;k < 12;k++) - m[k] = 0; - for (b = 0;b < numposes;b++) - { - matrix = pose[b] + tagnum*12; - - for (k = 0;k < 12;k++) - m[k] += matrix[k] * plerp[b]; - } - - memcpy(tempmatrix, result, sizeof(tempmatrix)); - R_ConcatTransforms((void*)m, (void*)tempmatrix, (void*)result); - - tagnum = bone[tagnum].parent; - } - - return true; - } -#endif - if (inf->numtags) - { - md3tag_t *t1, *t2; - - if (tagnum <= 0 || tagnum > inf->numtags) - return false; - if (frame1 < 0) - return false; - if (frame1 >= inf->numtagframes) - frame1 = inf->numtagframes - 1; - if (frame2 < 0 || frame2 >= inf->numtagframes) - frame2 = frame1; - tagnum--; //tagnum 0 is 'use my angles/org' - - t1 = (md3tag_t*)((char*)inf + inf->ofstags); - t1 += tagnum; - t1 += inf->numtags*frame1; - - t2 = (md3tag_t*)((char*)inf + inf->ofstags); - t2 += tagnum; - t2 += inf->numtags*frame2; - - if (t1 == t2) - { - result[0] = t1->ang[0][0]; - result[1] = t1->ang[0][1]; - result[2] = t1->ang[0][2]; - result[3] = t1->org[0]; - result[4] = t1->ang[1][0]; - result[5] = t1->ang[1][1]; - result[6] = t1->ang[1][2]; - result[7] = t1->org[1]; - result[8] = t1->ang[2][0]; - result[9] = t1->ang[2][1]; - result[10] = t1->ang[2][2]; - result[11] = t1->org[2]; - } - else - { - float f1ness = 1-f2ness; - result[0] = t1->ang[0][0]*f1ness + t2->ang[0][0]*f2ness; - result[1] = t1->ang[0][1]*f1ness + t2->ang[0][1]*f2ness; - result[2] = t1->ang[0][2]*f1ness + t2->ang[0][2]*f2ness; - result[3] = t1->org[0]*f1ness + t2->org[0]*f2ness; - result[4] = t1->ang[1][0]*f1ness + t2->ang[1][0]*f2ness; - result[5] = t1->ang[1][1]*f1ness + t2->ang[1][1]*f2ness; - result[6] = t1->ang[1][2]*f1ness + t2->ang[1][2]*f2ness; - result[7] = t1->org[1]*f1ness + t2->org[1]*f2ness; - result[8] = t1->ang[2][0]*f1ness + t2->ang[2][0]*f2ness; - result[9] = t1->ang[2][1]*f1ness + t2->ang[2][1]*f2ness; - result[10] = t1->ang[2][2]*f1ness + t2->ang[2][2]*f2ness; - result[11] = t1->org[2]*f1ness + t2->org[2]*f2ness; - } - return true; - } - return false; -} - -#ifndef SERVERONLY -int GLMod_TagNumForName(model_t *model, char *name) -#else -int Mod_TagNumForName(model_t *model, char *name) -#endif -{ - int i; - galiasinfo_t *inf; - md3tag_t *t; - - if (!model || model->type != mod_alias) - return 0; - inf = Mod_Extradata(model); - -#ifdef SKELETALMODELS - if (inf->numbones) - { - galiasbone_t *b; - b = (galiasbone_t*)((char*)inf + inf->ofsbones); - for (i = 0; i < inf->numbones; i++) - { - if (!strcmp(b[i].name, name)) - return i+1; - } - } -#endif - t = (md3tag_t*)((char*)inf + inf->ofstags); - for (i = 0; i < inf->numtags; i++) - { - if (!strcmp(t[i].name, name)) - return i+1; - } - - return 0; -} -#ifndef SERVERONLY -int GLMod_SkinNumForName(model_t *model, char *name) -{ - int i; - galiasinfo_t *inf; - galiasskin_t *skin; - - if (!model || model->type != mod_alias) - return -1; - inf = Mod_Extradata(model); - - skin = (galiasskin_t*)((char*)inf+inf->ofsskins); - for (i = 0; i < inf->numskins; i++, skin++) - { - if (!strcmp(skin->name, name)) - return i; - } - - return -1; -} -#endif - - -#ifdef MD3MODELS - -//structures from Tenebrae -typedef struct { - int ident; - int version; - - char name[MAX_QPATH]; - - int flags; //Does anyone know what these are? - - int numFrames; - int numTags; - int numSurfaces; - - int numSkins; - - int ofsFrames; - int ofsTags; - int ofsSurfaces; - int ofsEnd; -} md3Header_t; - -//then has header->numFrames of these at header->ofs_Frames -typedef struct md3Frame_s { - vec3_t bounds[2]; - vec3_t localOrigin; - float radius; - char name[16]; -} md3Frame_t; - -//there are header->numSurfaces of these at header->ofsSurfaces, following from ofsEnd -typedef struct { - int ident; // - - char name[MAX_QPATH]; // polyset name - - int flags; - int numFrames; // all surfaces in a model should have the same - - int numShaders; // all surfaces in a model should have the same - int numVerts; - - int numTriangles; - int ofsTriangles; - - int ofsShaders; // offset from start of md3Surface_t - int ofsSt; // texture coords are common for all frames - int ofsXyzNormals; // numVerts * numFrames - - int ofsEnd; // next surface follows -} md3Surface_t; - -//at surf+surf->ofsXyzNormals -typedef struct { - short xyz[3]; - qbyte latlong[2]; -} md3XyzNormal_t; - -//surf->numTriangles at surf+surf->ofsTriangles -typedef struct { - int indexes[3]; -} md3Triangle_t; - -//surf->numVerts at surf+surf->ofsSt -typedef struct { - float s; - float t; -} md3St_t; - -typedef struct { - char name[MAX_QPATH]; - int shaderIndex; -} md3Shader_t; -//End of Tenebrae 'assistance' - -qboolean GL_LoadQ3Model(model_t *mod, void *buffer) -{ -#ifndef SERVERONLY - galiasskin_t *skin; - galiastexnum_t *texnum; - float lat, lng; - md3St_t *inst; - vec3_t *normals; - vec2_t *st_array; - md3Shader_t *inshader; -#endif - int hunkstart, hunkend, hunktotal; -// int version; - int s, i, j, d; - - index_t *indexes; - - vec3_t min; - vec3_t max; - - galiaspose_t *pose; - galiasinfo_t *parent, *root; - galiasgroup_t *group; - - vec3_t *verts; - - md3Triangle_t *intris; - md3XyzNormal_t *invert; - - - int size; - int externalskins; - - md3Header_t *header; - md3Surface_t *surf; - - - loadmodel=mod; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - header = buffer; - -// if (header->version != sdfs) -// Sys_Error("GL_LoadQ3Model: Bad version\n"); - - parent = NULL; - root = NULL; - -#ifndef SERVERONLY - externalskins = GL_BuildSkinFileList(mod->name); -#else - externalskins = 0; -#endif - - min[0] = min[1] = min[2] = 0; - max[0] = max[1] = max[2] = 0; - - surf = (md3Surface_t *)((qbyte *)header + LittleLong(header->ofsSurfaces)); - for (s = 0; s < LittleLong(header->numSurfaces); s++) - { - if (LittleLong(surf->ident) != MD3_IDENT) - Con_Printf(S_WARNING "Warning: md3 sub-surface doesn't match ident\n"); - size = sizeof(galiasinfo_t) + sizeof(galiasgroup_t)*LittleLong(header->numFrames); - galias = Hunk_Alloc(size); - galias->groupofs = sizeof(*galias); //frame groups - galias->groups = LittleLong(header->numFrames); - galias->numverts = LittleLong(surf->numVerts); - galias->numindexes = LittleLong(surf->numTriangles)*3; - if (parent) - parent->nextsurf = (qbyte *)galias - (qbyte *)parent; - else - root = galias; - parent = galias; - -#ifndef SERVERONLY - st_array = Hunk_Alloc(sizeof(vec2_t)*galias->numindexes); - galias->ofs_st_array = (qbyte*)st_array - (qbyte*)galias; - inst = (md3St_t*)((qbyte*)surf + LittleLong(surf->ofsSt)); - for (i = 0; i < galias->numverts; i++) - { - st_array[i][0] = LittleFloat(inst[i].s); - st_array[i][1] = LittleFloat(inst[i].t); - } -#endif - - indexes = Hunk_Alloc(sizeof(*indexes)*galias->numindexes); - galias->ofs_indexes = (qbyte*)indexes - (qbyte*)galias; - intris = (md3Triangle_t *)((qbyte*)surf + LittleLong(surf->ofsTriangles)); - for (i = 0; i < LittleLong(surf->numTriangles); i++) - { - indexes[i*3+0] = LittleLong(intris[i].indexes[0]); - indexes[i*3+1] = LittleLong(intris[i].indexes[1]); - indexes[i*3+2] = LittleLong(intris[i].indexes[2]); - } - - group = (galiasgroup_t *)(galias+1); - invert = (md3XyzNormal_t *)((qbyte*)surf + LittleLong(surf->ofsXyzNormals)); - for (i = 0; i < LittleLong(surf->numFrames); i++) - { - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*LittleLong(surf->numVerts) -#ifndef SERVERONLY - + sizeof(vec3_t)*LittleLong(surf->numVerts) -#endif - ); - - verts = (vec3_t*)(pose+1); - pose->ofsverts = (qbyte*)verts - (qbyte*)pose; -#ifndef SERVERONLY - normals = verts + LittleLong(surf->numVerts); - pose->ofsnormals = (qbyte*)normals - (qbyte*)pose; -#endif - - for (j = 0; j < LittleLong(surf->numVerts); j++) - { -#ifndef SERVERONLY - lat = (float)invert[j].latlong[0] * (2 * M_PI)*(1.0 / 255.0); - lng = (float)invert[j].latlong[1] * (2 * M_PI)*(1.0 / 255.0); - normals[j][0] = cos ( lng ) * sin ( lat ); - normals[j][1] = sin ( lng ) * sin ( lat ); - normals[j][2] = cos ( lat ); -#endif - for (d = 0; d < 3; d++) - { - verts[j][d] = LittleShort(invert[j].xyz[d])/64.0f; - if (verts[j][d]max[d]) - max[d] = verts[j][d]; - } - } - - pose->scale[0] = 1; - pose->scale[1] = 1; - pose->scale[2] = 1; - - pose->scale_origin[0] = 0; - pose->scale_origin[1] = 0; - pose->scale_origin[2] = 0; - - snprintf(group->name, sizeof(group->name)-1, "frame%i", i); - - group->numposes = 1; - group->rate = 1; - group->poseofs = (qbyte*)pose - (qbyte*)group; - - group++; - invert += LittleLong(surf->numVerts); - } - -#ifndef SERVERONLY - if (externalskinsnumShaders)) - externalskins = LittleLong(surf->numShaders); - if (externalskins) - { -#ifndef Q3SHADERS - char name[1024]; - extern int gl_bumpmappingpossible; -#endif - char shadname[1024]; - - skin = Hunk_Alloc((LittleLong(surf->numShaders)+externalskins)*((sizeof(galiasskin_t)+sizeof(galiastexnum_t)))); - galias->ofsskins = (qbyte *)skin - (qbyte *)galias; - texnum = (galiastexnum_t *)(skin + LittleLong(surf->numShaders)+externalskins); - inshader = (md3Shader_t *)((qbyte *)surf + LittleLong(surf->ofsShaders)); - for (i = 0; i < externalskins; i++) - { - skin->texnums = 1; - skin->ofstexnums = (qbyte *)texnum - (qbyte *)skin; - skin->ofstexels = 0; - skin->skinwidth = 0; - skin->skinheight = 0; - skin->skinspeed = 0; - - shadname[0] = '\0'; - - GL_ParseQ3SkinFile(shadname, surf->name, loadmodel->name, i, skin->name); - - if (!*shadname) - { - if (i >= LittleLong(surf->numShaders)) - strcpy(shadname, "missingskin"); //this shouldn't be possible - else - strcpy(shadname, inshader->name); - - Q_strncpyz(skin->name, shadname, sizeof(skin->name)); - } - -#ifdef Q3SHADERS - if (qrenderer) - { - texnum->shader = R_RegisterSkin(shadname); - - if (r_shadows.value) //real-time shadows requires a texture to lighten the model with, even if it has a shader. - //fixme: this should be read from the shader. - texnum->base = Mod_LoadHiResTexture(shadname, "models", true, true, true); - } -#else - - texnum->base = Mod_LoadHiResTexture(shadname, "models", true, true, true); - if (!texnum->base) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - texnum->base = Mod_LoadHiResTexture(name, "models", true, true, true); - } - - texnum->bump = 0; - if (gl_bumpmappingpossible) - { - COM_StripExtension(shadname, name, sizeof(name)); //go for the normalmap - strcat(name, "_norm"); - texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false); - if (!texnum->bump) - { - strcpy(name, loadmodel->name); - COM_StripExtension(COM_SkipPath(shadname), COM_SkipPath(name), sizeof(name)); - strcat(name, "_norm"); - texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false); - if (!texnum->bump) - { - COM_StripExtension(shadname, name, sizeof(name)); //bother, go for heightmap and convert - strcat(name, "_bump"); - texnum->bump = Mod_LoadBumpmapTexture(name, "models"); - if (!texnum->bump) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - COM_StripExtension(name, name, sizeof(name)); - strcat(name, "_bump"); - texnum->bump = Mod_LoadBumpmapTexture(name, "models"); - } - } - } - } - if (r_fb_models.value) - { - COM_StripExtension(shadname, name, sizeof(name)); //go for the normalmap - strcat(name, "_luma"); - texnum->fullbright = Mod_LoadHiResTexture(name, "models", true, true, true); - if (!texnum->base) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - COM_StripExtension(name, name, sizeof(name)); - strcat(name, "_luma"); - texnum->fullbright = Mod_LoadBumpmapTexture(name, "models"); - } - } -#endif - - inshader++; - skin++; - texnum++; - } - galias->numskins = i; - } -#endif - - VectorCopy(min, loadmodel->mins); - VectorCopy(max, loadmodel->maxs); - - -#ifndef SERVERONLY - if (r_shadows.value) - { - int *neighbours; - neighbours = Hunk_Alloc(sizeof(int)*3*LittleLong(surf->numTriangles)); - galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; - R_BuildTriangleNeighbours(neighbours, indexes, LittleLong(surf->numTriangles)); - } -#endif - surf = (md3Surface_t *)((qbyte *)surf + LittleLong(surf->ofsEnd)); - } - - if (!root) - root = Hunk_Alloc(sizeof(galiasinfo_t)); - - root->numtagframes = LittleLong(header->numFrames); - root->numtags = LittleLong(header->numTags); - root->ofstags = (char*)Hunk_Alloc(LittleLong(header->numTags)*sizeof(md3tag_t)*LittleLong(header->numFrames)) - (char*)root; - - { - md3tag_t *src; - md3tag_t *dst; - - src = (md3tag_t *)(((unsigned int)header)+LittleLong(header->ofsTags)); - dst = (md3tag_t *)(((unsigned int)root)+root->ofstags); - for(i=0;inumTags)*LittleLong(header->numFrames);i++) - { - memcpy(dst->name, src->name, sizeof(dst->name)); - for(j=0;j<3;j++) - { - dst->org[j] = LittleFloat(src->org[j]); - } - - for(j=0;j<3;j++) - { - for(s=0;s<3;s++) - { - dst->ang[j][s] = LittleFloat(src->ang[j][s]); - } - } - - src++; - dst++; - } - } - -// -// move the complete, relocatable alias model to the cache -// - - hunkend = Hunk_LowMark (); -#ifndef SERVERONLY - if (mod_md3flags.value) - mod->flags = LittleLong(header->flags); - else -#endif - mod->flags = 0; - if (!mod->flags) - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); - - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, root, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - mod->funcs.Trace = GLMod_Trace; - - return true; -} -#endif - - - -#ifdef ZYMOTICMODELS - - -typedef struct zymlump_s -{ - int start; - int length; -} zymlump_t; - -typedef struct zymtype1header_s -{ - char id[12]; // "ZYMOTICMODEL", length 12, no termination - int type; // 0 (vertex morph) 1 (skeletal pose) or 2 (skeletal scripted) - int filesize; // size of entire model file - float mins[3], maxs[3], radius; // for clipping uses - int numverts; - int numtris; - int numsurfaces; - int numbones; // this may be zero in the vertex morph format (undecided) - int numscenes; // 0 in skeletal scripted models - -// skeletal pose header - // lump offsets are relative to the file - zymlump_t lump_scenes; // zymscene_t scene[numscenes]; // name and other information for each scene (see zymscene struct) - zymlump_t lump_poses; // float pose[numposes][numbones][6]; // animation data - zymlump_t lump_bones; // zymbone_t bone[numbones]; - zymlump_t lump_vertbonecounts; // int vertbonecounts[numvertices]; // how many bones influence each vertex (separate mainly to make this compress better) - zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct - zymlump_t lump_texcoords; // float texcoords[numvertices][2]; - zymlump_t lump_render; // int renderlist[rendersize]; // sorted by shader with run lengths (int count), shaders are sequentially used, each run can be used with glDrawElements (each triangle is 3 int indices) - zymlump_t lump_surfnames; // char shadername[numsurfaces][32]; // shaders used on this model - zymlump_t lump_trizone; // byte trizone[numtris]; // see trizone explanation -} zymtype1header_t; - -typedef struct zymbone_s -{ - char name[32]; - int flags; - int parent; // parent bone number -} zymbone_t; - -typedef struct zymscene_s -{ - char name[32]; - float mins[3], maxs[3], radius; // for clipping - float framerate; // the scene will animate at this framerate (in frames per second) - int flags; - int start, length; // range of poses -} zymscene_t; -#define ZYMSCENEFLAG_NOLOOP 1 - -typedef struct zymvertex_s -{ - int bonenum; - float origin[3]; -} zymvertex_t; - -//this can generate multiple meshes (one for each shader). -//but only one set of transforms are ever generated. -qboolean GLMod_LoadZymoticModel(model_t *mod, void *buffer) -{ -#ifndef SERVERONLY - galiasskin_t *skin; - galiastexnum_t *texnum; - int skinfiles; - int j; -#endif - - int i; - int hunkstart, hunkend, hunktotal; - - zymtype1header_t *header; - galiasinfo_t *root; - - galisskeletaltransforms_t *transforms; - zymvertex_t *intrans; - - galiasbone_t *bone; - zymbone_t *inbone; - int v; - float multiplier; - float *matrix, *inmatrix; - - vec2_t *stcoords; - vec2_t *inst; - - int *vertbonecounts; - - galiasgroup_t *grp; - zymscene_t *inscene; - - int *renderlist, count; - index_t *indexes; - - char *surfname; - - - loadmodel=mod; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - header = buffer; - - if (memcmp(header->id, "ZYMOTICMODEL", 12)) - { - Con_Printf("GLMod_LoadZymoticModel: %s, doesn't appear to BE a zymotic!\n", mod->name); - return false; - } - - if (BigLong(header->type) != 1) - { - Con_Printf("GLMod_LoadZymoticModel: %s, only type 1 is supported\n", mod->name); - return false; - } - - for (i = 0; i < sizeof(zymtype1header_t)/4; i++) - ((int*)header)[i] = BigLong(((int*)header)[i]); - - if (!header->numverts) - { - Con_Printf("GLMod_LoadZymoticModel: %s, no vertexes\n", mod->name); - return false; - } - - if (!header->numsurfaces) - { - Con_Printf("GLMod_LoadZymoticModel: %s, no surfaces\n", mod->name); - return false; - } - - VectorCopy(header->mins, mod->mins); - VectorCopy(header->maxs, mod->maxs); - - root = Hunk_AllocName(sizeof(galiasinfo_t)*header->numsurfaces, loadname); - - root->numtransforms = header->lump_verts.length/sizeof(zymvertex_t); - transforms = Hunk_Alloc(root->numtransforms*sizeof(*transforms)); - root->ofstransforms = (char*)transforms - (char*)root; - - vertbonecounts = (int *)((char*)header + header->lump_vertbonecounts.start); - intrans = (zymvertex_t *)((char*)header + header->lump_verts.start); - - vertbonecounts[0] = BigLong(vertbonecounts[0]); - multiplier = 1.0f / vertbonecounts[0]; - for (i = 0, v=0; i < root->numtransforms; i++) - { - while(!vertbonecounts[v]) - { - v++; - if (v == header->numverts) - { - Con_Printf("GLMod_LoadZymoticModel: %s, too many transformations\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - vertbonecounts[v] = BigLong(vertbonecounts[v]); - multiplier = 1.0f / vertbonecounts[v]; - } - transforms[i].vertexindex = v; - transforms[i].boneindex = BigLong(intrans[i].bonenum); - transforms[i].org[0] = multiplier*BigFloat(intrans[i].origin[0]); - transforms[i].org[1] = multiplier*BigFloat(intrans[i].origin[1]); - transforms[i].org[2] = multiplier*BigFloat(intrans[i].origin[2]); - transforms[i].org[3] = multiplier*1; - vertbonecounts[v]--; - } - if (intrans != (zymvertex_t *)((char*)header + header->lump_verts.start)) - { - Con_Printf(S_ERROR "%s, Vertex transforms list appears corrupt.\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - if (vertbonecounts != (int *)((char*)header + header->lump_vertbonecounts.start)) - { - Con_Printf(S_ERROR "%s, Vertex bone counts list appears corrupt.\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - - root->numverts = v+1; - - root->numbones = header->numbones; - bone = Hunk_Alloc(root->numtransforms*sizeof(*transforms)); - inbone = (zymbone_t*)((char*)header + header->lump_bones.start); - for (i = 0; i < root->numbones; i++) - { - Q_strncpyz(bone[i].name, inbone[i].name, sizeof(bone[i].name)); - bone[i].parent = BigLong(inbone[i].parent); - } - root->ofsbones = (char *)bone - (char *)root; - - renderlist = (int*)((char*)header + header->lump_render.start); - for (i = 0;i < header->numsurfaces; i++) - { - count = BigLong(*renderlist++); - count *= 3; - indexes = Hunk_Alloc(count*sizeof(*indexes)); - root[i].ofs_indexes = (char *)indexes - (char*)&root[i]; - root[i].numindexes = count; - while(count) - { //invert - indexes[count-1] = BigLong(renderlist[count-3]); - indexes[count-2] = BigLong(renderlist[count-2]); - indexes[count-3] = BigLong(renderlist[count-1]); - count-=3; - } - renderlist += root[i].numindexes; - } - if (renderlist != (int*)((char*)header + header->lump_render.start + header->lump_render.length)) - { - Con_Printf(S_ERROR "%s, render list appears corrupt.\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - - grp = Hunk_Alloc(sizeof(*grp)*header->numscenes*header->numsurfaces); - matrix = Hunk_Alloc(header->lump_poses.length); - inmatrix = (float*)((char*)header + header->lump_poses.start); - for (i = 0; i < header->lump_poses.length/4; i++) - matrix[i] = BigFloat(inmatrix[i]); - inscene = (zymscene_t*)((char*)header + header->lump_scenes.start); - surfname = ((char*)header + header->lump_surfnames.start); - - stcoords = Hunk_Alloc(root[0].numverts*sizeof(vec2_t)); - inst = (vec2_t *)((char *)header + header->lump_texcoords.start); - for (i = 0; i < header->lump_texcoords.length/8; i++) - { - stcoords[i][0] = BigFloat(inst[i][0]); - stcoords[i][1] = 1-BigFloat(inst[i][1]); //hmm. upside down skin coords? - } - -#ifndef SERVERONLY - skinfiles = GL_BuildSkinFileList(loadmodel->name); - if (skinfiles < 1) - skinfiles = 1; -#endif - - for (i = 0; i < header->numsurfaces; i++, surfname+=32) - { - root[i].groups = header->numscenes; - root[i].groupofs = (char*)grp - (char*)&root[i]; - -#ifdef SERVERONLY - root[i].numskins = 1; -#else - root[i].ofs_st_array = (char*)stcoords - (char*)&root[i]; - root[i].numskins = skinfiles; - - skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles); - texnum = (galiastexnum_t*)(skin+skinfiles); - for (j = 0; j < skinfiles; j++, texnum++) - { - skin[j].texnums = 1; //non-sequenced skins. - skin[j].ofstexnums = (char *)texnum - (char *)&skin[j]; - - GL_LoadSkinFile(texnum, surfname, j, NULL, 0, 0, NULL); - } - - root[i].ofsskins = (char *)skin - (char *)&root[i]; -#endif - } - - - for (i = 0; i < header->numscenes; i++, grp++, inscene++) - { - Q_strncpyz(grp->name, inscene->name, sizeof(grp->name)); - - grp->isheirachical = 1; - grp->rate = BigFloat(inscene->framerate); - grp->loop = !(BigLong(inscene->flags) & ZYMSCENEFLAG_NOLOOP); - grp->numposes = BigLong(inscene->length); - grp->poseofs = (char*)matrix - (char*)grp; - grp->poseofs += BigLong(inscene->start)*12*sizeof(float)*root->numbones; - } - - if (inscene != (zymscene_t*)((char*)header + header->lump_scenes.start+header->lump_scenes.length)) - { - Con_Printf(S_ERROR "%s, scene list appears corrupt.\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - - for (i = 0; i < header->numsurfaces-1; i++) - root[i].nextsurf = sizeof(galiasinfo_t); - for (i = 1; i < header->numsurfaces; i++) - { - root[i].sharesverts = true; - root[i].numbones = root[0].numbones; - root[i].numverts = root[0].numverts; - - root[i].ofsbones = root[0].ofsbones; - - root[i-1].nextsurf = sizeof(*root); - } - -// -// move the complete, relocatable alias model to the cache -// - - hunkend = Hunk_LowMark (); - - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); //file replacement - inherit flags from any defunc mdl files. - - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, root, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - - mod->funcs.Trace = GLMod_Trace; - - return true; -} - - - - - - - - - -////////////////////////////////////////////////////////////// -//dpm - - -// header for the entire file -typedef struct dpmheader_s -{ - char id[16]; // "DARKPLACESMODEL\0", length 16 - unsigned int type; // 2 (hierarchical skeletal pose) - unsigned int filesize; // size of entire model file - float mins[3], maxs[3], yawradius, allradius; // for clipping uses - - // these offsets are relative to the file - unsigned int num_bones; - unsigned int num_meshs; - unsigned int num_frames; - unsigned int ofs_bones; // dpmbone_t bone[num_bones]; - unsigned int ofs_meshs; // dpmmesh_t mesh[num_meshs]; - unsigned int ofs_frames; // dpmframe_t frame[num_frames]; -} dpmheader_t; - -// there may be more than one of these -typedef struct dpmmesh_s -{ - // these offsets are relative to the file - char shadername[32]; // name of the shader to use - unsigned int num_verts; - unsigned int num_tris; - unsigned int ofs_verts; // dpmvertex_t vert[numvertices]; // see vertex struct - unsigned int ofs_texcoords; // float texcoords[numvertices][2]; - unsigned int ofs_indices; // unsigned int indices[numtris*3]; // designed for glDrawElements (each triangle is 3 unsigned int indices) - unsigned int ofs_groupids; // unsigned int groupids[numtris]; // the meaning of these values is entirely up to the gamecode and modeler -} dpmmesh_t; - -// if set on a bone, it must be protected from removal -#define DPMBONEFLAG_ATTACHMENT 1 - -// one per bone -typedef struct dpmbone_s -{ - // name examples: upperleftarm leftfinger1 leftfinger2 hand, etc - char name[32]; - // parent bone number - signed int parent; - // flags for the bone - unsigned int flags; -} dpmbone_t; - -// a bonepose matrix is intended to be used like this: -// (n = output vertex, v = input vertex, m = matrix, f = influence) -// n[0] = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2] + f * m[0][3]; -// n[1] = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2] + f * m[1][3]; -// n[2] = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2] + f * m[2][3]; -typedef struct dpmbonepose_s -{ - float matrix[3][4]; -} dpmbonepose_t; - -// immediately followed by bone positions for the frame -typedef struct dpmframe_s -{ - // name examples: idle_1 idle_2 idle_3 shoot_1 shoot_2 shoot_3, etc - char name[32]; - float mins[3], maxs[3], yawradius, allradius; - int ofs_bonepositions; // dpmbonepose_t bonepositions[bones]; -} dpmframe_t; - -// one or more of these per vertex -typedef struct dpmbonevert_s -{ - float origin[3]; // vertex location (these blend) - float influence; // influence fraction (these must add up to 1) - float normal[3]; // surface normal (these blend) - unsigned int bonenum; // number of the bone -} dpmbonevert_t; - -// variable size, parsed sequentially -typedef struct dpmvertex_s -{ - unsigned int numbones; - // immediately followed by 1 or more dpmbonevert_t structures -} dpmvertex_t; - -qboolean GLMod_LoadDarkPlacesModel(model_t *mod, void *buffer) -{ -#ifndef SERVERONLY - galiasskin_t *skin; - galiastexnum_t *texnum; - int skinfiles; - float *inst; - float *outst; -#endif - - int i, j, k; - int hunkstart, hunkend, hunktotal; - - dpmheader_t *header; - galiasinfo_t *root, *m; - dpmmesh_t *mesh; - dpmvertex_t *vert; - dpmbonevert_t *bonevert; - - galisskeletaltransforms_t *transforms; - - galiasbone_t *outbone; - dpmbone_t *inbone; - - float *outposedata; - galiasgroup_t *outgroups; - float *inposedata; - dpmframe_t *inframes; - - unsigned int *index; index_t *outdex; // groan... - - int numtransforms; - int numverts; - - - loadmodel=mod; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - header = buffer; - - if (memcmp(header->id, "DARKPLACESMODEL\0", 16)) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: %s, doesn't appear to be a darkplaces model!\n", mod->name); - return false; - } - - if (BigLong(header->type) != 2) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: %s, only type 2 is supported\n", mod->name); - return false; - } - - for (i = 0; i < sizeof(dpmheader_t)/4; i++) - ((int*)header)[i] = BigLong(((int*)header)[i]); - - if (!header->num_bones) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: %s, no bones\n", mod->name); - return false; - } - if (!header->num_frames) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: %s, no frames\n", mod->name); - return false; - } - if (!header->num_meshs) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: %s, no surfaces\n", mod->name); - return false; - } - - - VectorCopy(header->mins, mod->mins); - VectorCopy(header->maxs, mod->maxs); - - root = Hunk_AllocName(sizeof(galiasinfo_t)*header->num_meshs, loadname); - - mesh = (dpmmesh_t*)((char*)buffer + header->ofs_meshs); - for (i = 0; i < header->num_meshs; i++, mesh++) - { - //work out how much memory we need to allocate - - mesh->num_verts = BigLong(mesh->num_verts); - mesh->num_tris = BigLong(mesh->num_tris); - mesh->ofs_verts = BigLong(mesh->ofs_verts); - mesh->ofs_texcoords = BigLong(mesh->ofs_texcoords); - mesh->ofs_indices = BigLong(mesh->ofs_indices); - mesh->ofs_groupids = BigLong(mesh->ofs_groupids); - - - numverts = mesh->num_verts; - numtransforms = 0; - //count and byteswap the transformations - vert = (dpmvertex_t*)((char *)buffer+mesh->ofs_verts); - for (j = 0; j < mesh->num_verts; j++) - { - vert->numbones = BigLong(vert->numbones); - numtransforms += vert->numbones; - bonevert = (dpmbonevert_t*)(vert+1); - vert = (dpmvertex_t*)(bonevert+vert->numbones); - } - - m = &root[i]; -#ifdef SERVERONLY - transforms = Hunk_AllocName(numtransforms*sizeof(galisskeletaltransforms_t) + mesh->num_tris*3*sizeof(index_t), loadname); -#else - outst = Hunk_AllocName(numverts*sizeof(vec2_t) + numtransforms*sizeof(galisskeletaltransforms_t) + mesh->num_tris*3*sizeof(index_t), loadname); - m->ofs_st_array = (char*)outst - (char*)m; - m->numverts = mesh->num_verts; - inst = (float*)((char*)buffer + mesh->ofs_texcoords); - for (j = 0; j < numverts; j++, outst+=2, inst+=2) - { - outst[0] = BigFloat(inst[0]); - outst[1] = BigFloat(inst[1]); - } - - transforms = (galisskeletaltransforms_t*)outst; -#endif - - //build the transform list. - m->ofstransforms = (char*)transforms - (char*)m; - m->numtransforms = numtransforms; - vert = (dpmvertex_t*)((char *)buffer+mesh->ofs_verts); - for (j = 0; j < mesh->num_verts; j++) - { - bonevert = (dpmbonevert_t*)(vert+1); - for (k = 0; k < vert->numbones; k++, bonevert++, transforms++) - { - transforms->boneindex = BigLong(bonevert->bonenum); - transforms->vertexindex = j; - transforms->org[0] = BigFloat(bonevert->origin[0]); - transforms->org[1] = BigFloat(bonevert->origin[1]); - transforms->org[2] = BigFloat(bonevert->origin[2]); - transforms->org[3] = BigFloat(bonevert->influence); - //do nothing with the normals. :( - } - vert = (dpmvertex_t*)bonevert; - } - - index = (index_t*)((char*)buffer + mesh->ofs_indices); - outdex = (index_t *)transforms; - m->ofs_indexes = (char*)outdex - (char*)m; - m->numindexes = mesh->num_tris*3; - for (j = 0; j < m->numindexes; j++) - { - *outdex++ = BigLong(*index++); - } - } - - outbone = Hunk_Alloc(sizeof(galiasbone_t)*header->num_bones); - inbone = (dpmbone_t*)((char*)buffer + header->ofs_bones); - for (i = 0; i < header->num_bones; i++) - { - outbone[i].parent = BigLong(inbone[i].parent); - if (outbone[i].parent >= i || outbone[i].parent < -1) - { - Con_Printf(S_ERROR "GLMod_LoadDarkPlacesModel: bad bone index in %s\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - - Q_strncpyz(outbone[i].name, inbone[i].name, sizeof(outbone[i].name)); - //throw away the flags. - } - - outgroups = Hunk_Alloc(sizeof(galiasgroup_t)*header->num_frames + sizeof(float)*header->num_frames*header->num_bones*12); - outposedata = (float*)(outgroups+header->num_frames); - - inframes = (dpmframe_t*)((char*)buffer + header->ofs_frames); - for (i = 0; i < header->num_frames; i++) - { - inframes[i].ofs_bonepositions = BigLong(inframes[i].ofs_bonepositions); - inframes[i].allradius = BigLong(inframes[i].allradius); - inframes[i].yawradius = BigLong(inframes[i].yawradius); - inframes[i].mins[0] = BigLong(inframes[i].mins[0]); - inframes[i].mins[1] = BigLong(inframes[i].mins[1]); - inframes[i].mins[2] = BigLong(inframes[i].mins[2]); - inframes[i].maxs[0] = BigLong(inframes[i].maxs[0]); - inframes[i].maxs[1] = BigLong(inframes[i].maxs[1]); - inframes[i].maxs[2] = BigLong(inframes[i].maxs[2]); - - Q_strncpyz(outgroups[i].name, inframes[i].name, sizeof(outgroups[i].name)); - - outgroups[i].rate = 10; - outgroups[i].numposes = 1; - outgroups[i].isheirachical = true; - outgroups[i].poseofs = (char*)outposedata - (char*)&outgroups[i]; - - inposedata = (float*)((char*)buffer + inframes[i].ofs_bonepositions); - for (j = 0; j < header->num_bones*12; j++) - *outposedata++ = BigFloat(*inposedata++); - } - -#ifndef SERVERONLY - skinfiles = GL_BuildSkinFileList(loadmodel->name); - if (skinfiles < 1) - skinfiles = 1; -#endif - - mesh = (dpmmesh_t*)((char*)buffer + header->ofs_meshs); - for (i = 0; i < header->num_meshs; i++, mesh++) - { - m = &root[i]; - if (i < header->num_meshs-1) - m->nextsurf = sizeof(galiasinfo_t); - m->sharesbones = true; - - m->ofsbones = (char*)outbone-(char*)m; - m->numbones = header->num_bones; - - m->groups = header->num_frames; - m->groupofs = (char*)outgroups - (char*)m; - - - -#ifdef SERVERONLY - m->numskins = 1; -#else - m->numskins = skinfiles; - - skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles); - texnum = (galiastexnum_t*)(skin+skinfiles); - for (j = 0; j < skinfiles; j++, texnum++) - { - skin[j].texnums = 1; //non-sequenced skins. - skin[j].ofstexnums = (char *)texnum - (char *)&skin[j]; - - GL_LoadSkinFile(texnum, mesh->shadername, j, NULL, 0, 0, NULL); - } - - m->ofsskins = (char *)skin - (char *)m; -#endif - } - root[0].sharesbones = false; - - - - -// -// move the complete, relocatable alias model to the cache -// - hunkend = Hunk_LowMark (); - - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); //file replacement - inherit flags from any defunc mdl files. - - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, root, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - - mod->funcs.Trace = GLMod_Trace; - - return true; -} - - - - - - - -#endif //ZYMOTICMODELS - -#ifdef MD5MODELS - -static void GenMatrix(float x, float y, float z, float qx, float qy, float qz, float result[12]) -{ - float qw; - { //figure out qw - float term = 1 - (qx*qx) - (qy*qy) - (qz*qz); - if (term < 0) - qw = 0; - else - qw = - (float) sqrt(term); - } - - { //generate the matrix - /* - float xx = qx * qx; - float xy = qx * qy; - float xz = qx * qz; - float xw = qx * qw; - float yy = qy * qy; - float yz = qy * qz; - float yw = qy * qw; - float zz = qz * qz; - float zw = qz * qw; - result[0*4+0] = 1 - 2 * ( yy + zz ); - result[0*4+1] = 2 * ( xy - zw ); - result[0*4+2] = 2 * ( xz + yw ); - result[0*4+3] = x; - result[1*4+0] = 2 * ( xy + zw ); - result[1*4+1] = 1 - 2 * ( xx + zz ); - result[1*4+2] = 2 * ( yz - xw ); - result[1*4+3] = y; - result[2*4+0] = 2 * ( xz - yw ); - result[2*4+1] = 2 * ( yz + xw ); - result[2*4+2] = 1 - 2 * ( xx + yy ); - result[2*4+3] = z; - */ - - float xx, xy, xz, xw, yy, yz, yw, zz, zw; - float x2, y2, z2; - x2 = qx + qx; - y2 = qy + qy; - z2 = qz + qz; - - xx = qx * x2; xy = qx * y2; xz = qx * z2; - yy = qy * y2; yz = qy * z2; zz = qz * z2; - xw = qw * x2; yw = qw * y2; zw = qw * z2; - - result[0*4+0] = 1.0f - (yy + zz); - result[1*4+0] = xy + zw; - result[2*4+0] = xz - yw; - - result[0*4+1] = xy - zw; - result[1*4+1] = 1.0f - (xx + zz); - result[2*4+1] = yz + xw; - - result[0*4+2] = xz + yw; - result[1*4+2] = yz - xw; - result[2*4+2] = 1.0f - (xx + yy); - - result[0*4+3] = x; - result[1*4+3] = y; - result[2*4+3] = z; - } -} - -galiasinfo_t *GLMod_ParseMD5MeshModel(char *buffer) -{ -#define MD5ERROR0PARAM(x) { Con_Printf(S_ERROR x "\n"); return NULL; } -#define MD5ERROR1PARAM(x, y) { Con_Printf(S_ERROR x "\n", y); return NULL; } -#define EXPECT(x) buffer = COM_Parse(buffer); if (strcmp(com_token, x)) Sys_Error("MD5MESH: expected %s", x); - int numjoints = 0; - int nummeshes = 0; - qboolean foundjoints = false; - int i; - - galiasbone_t *bones = NULL; - galiasgroup_t *pose = NULL; - galiasinfo_t *inf, *root, *lastsurf; - float *posedata; -#ifndef SERVERONLY - galiasskin_t *skin; - galiastexnum_t *texnum; -#endif - - float x, y, z, qx, qy, qz; - - - - buffer = COM_Parse(buffer); - if (strcmp(com_token, "MD5Version")) - MD5ERROR0PARAM("MD5 model without MD5Version identifier first"); - - buffer = COM_Parse(buffer); - if (atoi(com_token) != 10) - MD5ERROR0PARAM("MD5 model with unsupported MD5Version"); - - - root = Hunk_Alloc(sizeof(galiasinfo_t)); - lastsurf = NULL; - - for(;;) - { - buffer = COM_Parse(buffer); - if (!buffer) - break; - - if (!strcmp(com_token, "commandline")) - { //we don't need this - buffer = strchr(buffer, '\"'); - buffer = strchr((char*)buffer+1, '\"')+1; -// buffer = COM_Parse(buffer); - } - else if (!strcmp(com_token, "numJoints")) - { - if (numjoints) - MD5ERROR0PARAM("MD5MESH: numMeshes was already declared"); - buffer = COM_Parse(buffer); - numjoints = atoi(com_token); - if (numjoints <= 0) - MD5ERROR0PARAM("MD5MESH: Needs some joints"); - } - else if (!strcmp(com_token, "numMeshes")) - { - if (nummeshes) - MD5ERROR0PARAM("MD5MESH: numMeshes was already declared"); - buffer = COM_Parse(buffer); - nummeshes = atoi(com_token); - if (nummeshes <= 0) - MD5ERROR0PARAM("MD5MESH: Needs some meshes"); - } - else if (!strcmp(com_token, "joints")) - { - if (foundjoints) - MD5ERROR0PARAM("MD5MESH: Duplicate joints section"); - foundjoints=true; - if (!numjoints) - MD5ERROR0PARAM("MD5MESH: joints section before (or without) numjoints"); - - bones = Hunk_Alloc(sizeof(*bones) * numjoints); - pose = Hunk_Alloc(sizeof(galiasgroup_t)); - posedata = Hunk_Alloc(sizeof(float)*12 * numjoints); - pose->isheirachical = false; - pose->rate = 1; - pose->numposes = 1; - pose->poseofs = (char*)posedata - (char*)pose; - - Q_strncpyz(pose->name, "base", sizeof(pose->name)); - - EXPECT("{"); - //"name" parent (x y z) (s t u) - //stu are a normalized quaternion, which we will convert to a 3*4 matrix for no apparent reason - - for (i = 0; i < numjoints; i++) - { - buffer = COM_Parse(buffer); - Q_strncpyz(bones[i].name, com_token, sizeof(bones[i].name)); - buffer = COM_Parse(buffer); - bones[i].parent = atoi(com_token); - if (bones[i].parent >= i) - MD5ERROR0PARAM("MD5MESH: joints parent's must be lower"); - if ((bones[i].parent < 0 && i) || (!i && bones[i].parent!=-1)) - MD5ERROR0PARAM("MD5MESH: Only the root joint may have a negative parent"); - - EXPECT("("); - buffer = COM_Parse(buffer); - x = atof(com_token); - buffer = COM_Parse(buffer); - y = atof(com_token); - buffer = COM_Parse(buffer); - z = atof(com_token); - EXPECT(")"); - EXPECT("("); - buffer = COM_Parse(buffer); - qx = atof(com_token); - buffer = COM_Parse(buffer); - qy = atof(com_token); - buffer = COM_Parse(buffer); - qz = atof(com_token); - EXPECT(")"); - GenMatrix(x, y, z, qx, qy, qz, posedata+i*12); - } - EXPECT("}"); - } - else if (!strcmp(com_token, "mesh")) - { - int numverts = 0; - int numweights = 0; - int numtris = 0; - - int num; - int vnum; - - int numusableweights = 0; - int *firstweightlist = NULL; - int *numweightslist = NULL; - - galisskeletaltransforms_t *trans; -#ifndef SERVERONLY - float *stcoord = NULL; -#endif - int *indexes = NULL; - float w; - - vec4_t *rawweight = NULL; - int *rawweightbone = NULL; - - - if (!nummeshes) - MD5ERROR0PARAM("MD5MESH: mesh section before (or without) nummeshes"); - if (!foundjoints || !bones || !pose) - MD5ERROR0PARAM("MD5MESH: mesh must come after joints"); - - if (!lastsurf) - { - lastsurf = root; - inf = root; - } - else - { - inf = Hunk_Alloc(sizeof(*inf)); - lastsurf->nextsurf = (char*)inf - (char*)lastsurf; - lastsurf = inf; - } - - inf->ofsbones = (char*)bones - (char*)inf; - inf->numbones = numjoints; - inf->groups = 1; - inf->groupofs = (char*)pose - (char*)inf; - -#ifndef SERVERONLY - skin = Hunk_Alloc(sizeof(*skin)); - texnum = Hunk_Alloc(sizeof(*texnum)); - inf->numskins = 1; - inf->ofsskins = (char*)skin - (char*)inf; - skin->texnums = 1; - skin->skinspeed = 1; - skin->ofstexnums = (char*)texnum - (char*)skin; -#endif - EXPECT("{"); - for(;;) - { - buffer = COM_Parse(buffer); - if (!buffer) - MD5ERROR0PARAM("MD5MESH: unexpected eof"); - - if (!strcmp(com_token, "shader")) - { - buffer = COM_Parse(buffer); -#ifndef SERVERONLY - // texnum->shader = R_RegisterSkin(com_token); - texnum->base = Mod_LoadHiResTexture(com_token, "models", true, true, true); -#endif - } - else if (!strcmp(com_token, "numverts")) - { - if (numverts) - MD5ERROR0PARAM("MD5MESH: numverts was already specified"); - buffer = COM_Parse(buffer); - numverts = atoi(com_token); - if (numverts < 0) - MD5ERROR0PARAM("MD5MESH: numverts cannot be negative"); - - firstweightlist = Z_Malloc(sizeof(*firstweightlist) * numverts); - numweightslist = Z_Malloc(sizeof(*numweightslist) * numverts); -#ifndef SERVERONLY - stcoord = Hunk_Alloc(sizeof(float)*2*numverts); - inf->ofs_st_array = (char*)stcoord - (char*)inf; - inf->numverts = numverts; -#endif - } - else if (!strcmp(com_token, "vert")) - { //vert num ( s t ) firstweight numweights - - buffer = COM_Parse(buffer); - num = atoi(com_token); - if (num < 0 || num >= numverts || !indexes) - MD5ERROR0PARAM("MD5MESH: vertex out of range"); - - EXPECT("("); - buffer = COM_Parse(buffer); -#ifndef SERVERONLY - if (!stcoord) - MD5ERROR0PARAM("MD5MESH: vertex out of range"); - stcoord[num*2+0] = atof(com_token); -#endif - buffer = COM_Parse(buffer); -#ifndef SERVERONLY - stcoord[num*2+1] = atof(com_token); -#endif - EXPECT(")"); - buffer = COM_Parse(buffer); - firstweightlist[num] = atoi(com_token); - buffer = COM_Parse(buffer); - numweightslist[num] = atoi(com_token); - - numusableweights += numweightslist[num]; - } - else if (!strcmp(com_token, "numtris")) - { - if (numtris) - MD5ERROR0PARAM("MD5MESH: numtris was already specified"); - buffer = COM_Parse(buffer); - numtris = atoi(com_token); - if (numtris < 0) - MD5ERROR0PARAM("MD5MESH: numverts cannot be negative"); - - indexes = Hunk_Alloc(sizeof(int)*3*numtris); - inf->ofs_indexes = (char*)indexes - (char*)inf; - inf->numindexes = numtris*3; - } - else if (!strcmp(com_token, "tri")) - { - buffer = COM_Parse(buffer); - num = atoi(com_token); - if (num < 0 || num >= numtris) - MD5ERROR0PARAM("MD5MESH: vertex out of range"); - - buffer = COM_Parse(buffer); - indexes[num*3+0] = atoi(com_token); - buffer = COM_Parse(buffer); - indexes[num*3+1] = atoi(com_token); - buffer = COM_Parse(buffer); - indexes[num*3+2] = atoi(com_token); - } - else if (!strcmp(com_token, "numweights")) - { - if (numweights) - MD5ERROR0PARAM("MD5MESH: numweights was already specified"); - buffer = COM_Parse(buffer); - numweights = atoi(com_token); - - rawweight = Z_Malloc(sizeof(*rawweight)*numweights); - rawweightbone = Z_Malloc(sizeof(*rawweightbone)*numweights); - } - else if (!strcmp(com_token, "weight")) - { - //weight num bone scale ( x y z ) - buffer = COM_Parse(buffer); - num = atoi(com_token); - if (num < 0 || num >= numweights) - MD5ERROR0PARAM("MD5MESH: weight out of range"); - - buffer = COM_Parse(buffer); - rawweightbone[num] = atoi(com_token); - if (rawweightbone[num] < 0 || rawweightbone[num] >= numjoints) - MD5ERROR0PARAM("MD5MESH: weight specifies bad bone"); - buffer = COM_Parse(buffer); - w = atof(com_token); - - EXPECT("("); - buffer = COM_Parse(buffer); - rawweight[num][0] = w*atof(com_token); - buffer = COM_Parse(buffer); - rawweight[num][1] = w*atof(com_token); - buffer = COM_Parse(buffer); - rawweight[num][2] = w*atof(com_token); - EXPECT(")"); - rawweight[num][3] = w; - } - else if (!strcmp(com_token, "}")) - break; - else - MD5ERROR1PARAM("MD5MESH: Unrecognised token inside mesh (%s)", com_token); - - } - - trans = Hunk_Alloc(sizeof(*trans)*numusableweights); - inf->ofstransforms = (char*)trans - (char*)inf; - - for (num = 0, vnum = 0; num < numverts; num++) - { - if (numweightslist[num] <= 0) - MD5ERROR0PARAM("MD5MESH: weights not set on vertex"); - while(numweightslist[num]) - { - trans[vnum].vertexindex = num; - trans[vnum].boneindex = rawweightbone[firstweightlist[num]]; - trans[vnum].org[0] = rawweight[firstweightlist[num]][0]; - trans[vnum].org[1] = rawweight[firstweightlist[num]][1]; - trans[vnum].org[2] = rawweight[firstweightlist[num]][2]; - trans[vnum].org[3] = rawweight[firstweightlist[num]][3]; - vnum++; - firstweightlist[num]++; - numweightslist[num]--; - } - } - inf->numtransforms = vnum; - - if (firstweightlist) - Z_Free(firstweightlist); - if (numweightslist) - Z_Free(numweightslist); - if (rawweight) - Z_Free(rawweight); - if (rawweightbone) - Z_Free(rawweightbone); - } - else - MD5ERROR1PARAM("Unrecognised token in MD5 model (%s)", com_token); - } - - if (!lastsurf) - MD5ERROR0PARAM("MD5MESH: No meshes"); - - return root; -#undef MD5ERROR0PARAM -#undef MD5ERROR1PARAM -#undef EXPECT -} - -qboolean GLMod_LoadMD5MeshModel(model_t *mod, void *buffer) -{ - galiasinfo_t *root; - int hunkstart, hunkend, hunktotal; - - - loadmodel=mod; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - - root = GLMod_ParseMD5MeshModel(buffer); - if (root == NULL) - { - Hunk_FreeToLowMark(hunkstart); - return false; - } - - - hunkend = Hunk_LowMark (); - - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); //file replacement - inherit flags from any defunc mdl files. - - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, root, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - - mod->funcs.Trace = GLMod_Trace; - return true; -} - -qboolean GLMod_ParseMD5Anim(char *buffer, galiasinfo_t *prototype, void**poseofs, galiasgroup_t *gat) -{ -#define MD5ERROR0PARAM(x) { Con_Printf(S_ERROR x "\n"); return false; } -#define MD5ERROR1PARAM(x, y) { Con_Printf(S_ERROR x "\n", y); return false; } -#define EXPECT(x) buffer = COM_Parse(buffer); if (strcmp(com_token, x)) MD5ERROR1PARAM("MD5ANIM: expected %s", x); - unsigned int i, j; - - galiasgroup_t grp; - - unsigned int parent; - unsigned int numframes; - unsigned int numjoints; - float framespersecond; - unsigned int numanimatedparts; - galiasbone_t *bonelist; - - unsigned char *boneflags; - unsigned int *firstanimatedcomponants; - - float *animatedcomponants; - float *baseframe; //6 componants. - float *posedata; - float tx, ty, tz, qx, qy, qz; - int fac, flags; - float f; - - EXPECT("MD5Version"); - EXPECT("10"); - - EXPECT("commandline"); - buffer = COM_Parse(buffer); - - EXPECT("numFrames"); - buffer = COM_Parse(buffer); - numframes = atoi(com_token); - - EXPECT("numJoints"); - buffer = COM_Parse(buffer); - numjoints = atoi(com_token); - - EXPECT("frameRate"); - buffer = COM_Parse(buffer); - framespersecond = atof(com_token); - - EXPECT("numAnimatedComponents"); - buffer = COM_Parse(buffer); - numanimatedparts = atoi(com_token); - - firstanimatedcomponants = BZ_Malloc(sizeof(int)*numjoints); - animatedcomponants = BZ_Malloc(sizeof(float)*numanimatedparts); - boneflags = BZ_Malloc(sizeof(unsigned char)*numjoints); - baseframe = BZ_Malloc(sizeof(float)*12*numjoints); - - *poseofs = posedata = Hunk_Alloc(sizeof(float)*12*numjoints*numframes); - - if (prototype) - { - if (prototype->numbones != numjoints) - MD5ERROR0PARAM("MD5ANIM: number of bones doesn't match"); - bonelist = (galiasbone_t *)((char*)prototype + prototype->ofsbones); - } - else - { - bonelist = Hunk_Alloc(sizeof(galiasbone_t)*numjoints); - prototype->ofsbones = (char*)bonelist - (char*)prototype; - prototype->numbones = numjoints; - } - - EXPECT("hierarchy"); - EXPECT("{"); - for (i = 0; i < numjoints; i++, bonelist++) - { - buffer = COM_Parse(buffer); - if (prototype) - { - if (strcmp(bonelist->name, com_token)) - MD5ERROR1PARAM("MD5ANIM: bone name doesn't match (%s)", com_token); - } - else - Q_strncpyz(bonelist->name, com_token, sizeof(bonelist->name)); - buffer = COM_Parse(buffer); - parent = atoi(com_token); - if (prototype) - { - if (bonelist->parent != parent) - MD5ERROR1PARAM("MD5ANIM: bone name doesn't match (%s)", com_token); - } - else - bonelist->parent = parent; - - buffer = COM_Parse(buffer); - boneflags[i] = atoi(com_token); - buffer = COM_Parse(buffer); - firstanimatedcomponants[i] = atoi(com_token); - } - EXPECT("}"); - - EXPECT("bounds"); - EXPECT("{"); - for (i = 0; i < numframes; i++) - { - EXPECT("("); - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f < loadmodel->mins[0]) loadmodel->mins[0] = f; - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f < loadmodel->mins[1]) loadmodel->mins[1] = f; - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f < loadmodel->mins[2]) loadmodel->mins[2] = f; - EXPECT(")"); - EXPECT("("); - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f > loadmodel->maxs[0]) loadmodel->maxs[0] = f; - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f > loadmodel->maxs[1]) loadmodel->maxs[1] = f; - buffer = COM_Parse(buffer);f=atoi(com_token); - if (f > loadmodel->maxs[2]) loadmodel->maxs[2] = f; - EXPECT(")"); - } - EXPECT("}"); - - EXPECT("baseframe"); - EXPECT("{"); - for (i = 0; i < numjoints; i++) - { - EXPECT("("); - buffer = COM_Parse(buffer); - baseframe[i*6+0] = atof(com_token); - buffer = COM_Parse(buffer); - baseframe[i*6+1] = atof(com_token); - buffer = COM_Parse(buffer); - baseframe[i*6+2] = atof(com_token); - EXPECT(")"); - EXPECT("("); - buffer = COM_Parse(buffer); - baseframe[i*6+3] = atof(com_token); - buffer = COM_Parse(buffer); - baseframe[i*6+4] = atof(com_token); - buffer = COM_Parse(buffer); - baseframe[i*6+5] = atof(com_token); - EXPECT(")"); - } - EXPECT("}"); - - for (i = 0; i < numframes; i++) - { - EXPECT("frame"); - EXPECT(va("%i", i)); - EXPECT("{"); - for (j = 0; j < numanimatedparts; j++) - { - buffer = COM_Parse(buffer); - animatedcomponants[j] = atof(com_token); - } - EXPECT("}"); - - for (j = 0; j < numjoints; j++) - { - fac = firstanimatedcomponants[j]; - flags = boneflags[j]; - - if (flags&1) - tx = animatedcomponants[fac++]; - else - tx = baseframe[j*6+0]; - if (flags&2) - ty = animatedcomponants[fac++]; - else - ty = baseframe[j*6+1]; - if (flags&4) - tz = animatedcomponants[fac++]; - else - tz = baseframe[j*6+2]; - if (flags&8) - qx = animatedcomponants[fac++]; - else - qx = baseframe[j*6+3]; - if (flags&16) - qy = animatedcomponants[fac++]; - else - qy = baseframe[j*6+4]; - if (flags&32) - qz = animatedcomponants[fac++]; - else - qz = baseframe[j*6+5]; - - GenMatrix(tx, ty, tz, qx, qy, qz, posedata+12*(j+numjoints*i)); - } - } - - BZ_Free(firstanimatedcomponants); - BZ_Free(animatedcomponants); - BZ_Free(boneflags); - BZ_Free(baseframe); - - Q_strncpyz(grp.name, "", sizeof(grp.name)); - grp.isheirachical = true; - grp.numposes = numframes; - grp.rate = framespersecond; - grp.loop = true; - - *gat = grp; - return true; -#undef MD5ERROR0PARAM -#undef MD5ERROR1PARAM -#undef EXPECT -} - -/* -EXTERNALANIM - -//File what specifies md5 model/anim stuff. - -model test/imp.md5mesh - -group test/idle1.md5anim -clampgroup test/idle1.md5anim -frames test/idle1.md5anim - -*/ -qboolean GLMod_LoadCompositeAnim(model_t *mod, void *buffer) -{ - int i; - - char *file; - galiasinfo_t *root = NULL; - int numgroups = 0; - galiasgroup_t *grouplist = NULL; - galiasgroup_t *newgroup = NULL; - void **poseofs; - int hunkstart, hunkend, hunktotal; - - - loadmodel=mod; - - Mod_DoCRC(mod, buffer, com_filesize); - - hunkstart = Hunk_LowMark (); - - - - - buffer = COM_Parse(buffer); - if (strcmp(com_token, "EXTERNALANIM")) - { - Con_Printf (S_ERROR "EXTERNALANIM: header is not compleate (%s)\n", mod->name); - return false; - } - - buffer = COM_Parse(buffer); - if (!strcmp(com_token, "model")) - { - buffer = COM_Parse(buffer); - file = COM_LoadTempFile2(com_token); - - if (!file) //FIXME: make non fatal somehow.. - { - Con_Printf(S_ERROR "Couldn't open %s (from %s)\n", com_token, mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - - root = GLMod_ParseMD5MeshModel(file); - if (root == NULL) - { - Hunk_FreeToLowMark(hunkstart); - return false; - } - newgroup = (galiasgroup_t*)((char*)root + root->groupofs); - - grouplist = BZ_Malloc(sizeof(galiasgroup_t)*(numgroups+root->groups)); - memcpy(grouplist, newgroup, sizeof(galiasgroup_t)*(numgroups+root->groups)); - poseofs = BZ_Malloc(sizeof(galiasgroup_t)*(numgroups+root->groups)); - for (i = 0; i < root->groups; i++) - { - grouplist[numgroups] = newgroup[i]; - poseofs[numgroups] = (char*)&newgroup[i] + newgroup[i].poseofs; - numgroups++; - } - } - else - { - Con_Printf (S_ERROR "EXTERNALANIM: model must be defined immediatly after the header\n"); - return false; - } - - for (;;) - { - buffer = COM_Parse(buffer); - if (!buffer) - break; - - if (!strcmp(com_token, "group")) - { - grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+1)); - poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+1)); - buffer = COM_Parse(buffer); - file = COM_LoadTempFile2(com_token); - if (file) //FIXME: make non fatal somehow.. - { - char namebkup[MAX_QPATH]; - Q_strncpyz(namebkup, com_token, sizeof(namebkup)); - if (!GLMod_ParseMD5Anim(file, root, &poseofs[numgroups], &grouplist[numgroups])) - { - Hunk_FreeToLowMark(hunkstart); - return false; - } - Q_strncpyz(grouplist[numgroups].name, namebkup, sizeof(grouplist[numgroups].name)); - numgroups++; - } - } - else if (!strcmp(com_token, "clampgroup")) - { - Con_Printf(S_ERROR "EXTERNALANIM: clampgroup not yet supported (%s)\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - else if (!strcmp(com_token, "frames")) - { - Con_Printf (S_ERROR "EXTERNALANIM: frames not yet supported (%s)\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - else - { - Con_Printf(S_ERROR "EXTERNALANIM: unrecognised token (%s)\n", mod->name); - Hunk_FreeToLowMark(hunkstart); - return false; - } - } - - newgroup = grouplist; - grouplist = Hunk_Alloc(sizeof(galiasgroup_t)*numgroups); - for(;;) - { - root->groupofs = (char*)grouplist - (char*)root; - root->groups = numgroups; - if (!root->nextsurf) - break; - root = (galiasinfo_t*)((char*)root + root->nextsurf); - } - for (i = 0; i < numgroups; i++) - { - grouplist[i] = newgroup[i]; - grouplist[i].poseofs = (char*)poseofs[i] - (char*)&grouplist[i]; - } - - - hunkend = Hunk_LowMark (); - - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); //file replacement - inherit flags from any defunc mdl files. - - Hunk_Alloc(0); - hunktotal = hunkend - hunkstart; - - Cache_Alloc (&mod->cache, hunktotal, loadname); - mod->type = mod_alias; - if (!mod->cache.data) - { - Hunk_FreeToLowMark (hunkstart); - return false; - } - memcpy (mod->cache.data, root, hunktotal); - - Hunk_FreeToLowMark (hunkstart); - - - mod->funcs.Trace = GLMod_Trace; - return true; -} - -#endif //MD5MODELS - #endif // defined(RGLQUAKE) || defined(SERVERONLY) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index b506cf3cb..e64688f02 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -843,7 +843,7 @@ void R_FlushArrays (void) if ( !r_arrays_locked ) { R_DrawTriangleStrips ( indexesArray, numIndexes ); } else { - qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray ); + qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexesArray ); } r_numtris += numIndexes / 3; @@ -888,7 +888,7 @@ void R_FlushArraysMtex (void) if ( !r_arrays_locked ) { R_DrawTriangleStrips ( indexesArray, numIndexes ); } else { - qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray ); + qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexesArray ); } r_numtris += numIndexes / 3; @@ -1193,7 +1193,7 @@ void RB_CalcEnvironmentTexCoords( float *st ) R_VertexTCBase ============== */ -void R_VertexTCBase ( int tcgen, int unit ) +float *R_VertexTCBase ( int tcgen, int unit ) { int i; // vec3_t t, n; @@ -1203,7 +1203,6 @@ void R_VertexTCBase ( int tcgen, int unit ) // mat3_t axis; outCoords = tUnitCoordsArray[unit][0]; - qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords ); if ( tcgen == TC_GEN_BASE ) { @@ -1278,6 +1277,7 @@ void R_VertexTCBase ( int tcgen, int unit ) } } + return tUnitCoordsArray[unit][0]; } /* @@ -1331,7 +1331,7 @@ void R_ModifyTextureCoords ( shaderpass_t *pass, int unit ) } else if ( pass->tcgen == TC_GEN_LIGHTMAP ) { qglTexCoordPointer( 2, GL_FLOAT, 0, lightmapCoordsArray ); } else { - R_VertexTCBase ( pass->tcgen, unit ); + qglTexCoordPointer( 2, GL_FLOAT, 0, R_VertexTCBase (pass->tcgen, unit)); } return; } diff --git a/engine/gl/gl_bloom.c b/engine/gl/gl_bloom.c index 97fb522fa..6bd2d0964 100644 --- a/engine/gl/gl_bloom.c +++ b/engine/gl/gl_bloom.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //http://www.quakesrc.org/forums/viewtopic.php?t=4340&start=0 #include "quakedef.h" + #ifdef RGLQUAKE #include "glquake.h" diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index bc0a855c9..dfdd7b673 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -798,7 +798,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); if (!draw_chars) //or low res. { if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false))) //try low res q2 path - if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try low res q2 path + if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try q3 path { //gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system. diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index b85ad465f..19f704537 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -1,6 +1,9 @@ #include "quakedef.h" + #if defined(TERRAIN) && !defined(SERVERONLY) //fixme +#ifdef RGLQUAKE #include "glquake.h" +#endif //heightmaps work thusly: //there is one raw heightmap file @@ -27,7 +30,7 @@ typedef struct { unsigned short mins[SECTIONS*SECTIONS], maxs[SECTIONS*SECTIONS]; } heightmap_t; - +#ifdef RGLQUAKE #define DISPLISTS //#define MULTITEXTURE //ATI suck. I don't know about anyone else (this goes at 1/5th the speed). @@ -51,7 +54,7 @@ void GL_DrawHeightmapModel (entity_t *e) R_ClearSkyBox(); R_ForceSkyBox(); - R_DrawSkyBox(NULL); + GL_DrawSkyBox(NULL); } else qglColor4fv(e->shaderRGBAf); @@ -173,6 +176,8 @@ void GL_DrawHeightmapModel (entity_t *e) } } } +#endif + unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, vec3_t org) { float x, y; @@ -652,6 +657,10 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer) Con_Printf(S_ERROR "%s wasn't terrain map\n", mod->name); //shouldn't happen return false; } + + if (qrenderer != QR_OPENGL) + return false; + for(;;) { buffer = COM_Parse(buffer); @@ -751,10 +760,11 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer) hm->heightscale = heightsize; hm->numsegs = numsegs; - hm->detailtexture = Mod_LoadHiResTexture(detailtexname, "", true, true, false); - mod->entities = COM_LoadHunkFile(entfile); +#ifdef RGLQUAKE + hm->detailtexture = Mod_LoadHiResTexture(detailtexname, "", true, true, false); + for (x = 0; x < numsegs; x++) { for (y = 0; y < numsegs; y++) @@ -764,6 +774,7 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer) qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } } +#endif R_SetSky(skyname, skyrotate, skyaxis); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index d9c64383a..0191bae0d 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -23,8 +23,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // on the same machine. #include "quakedef.h" -#ifdef RGLQUAKE + + +#if defined(RGLQUAKE) || defined(D3DQUAKE) + +#if defined(RGLQUAKE) #include "glquake.h" +#endif + +#ifdef D3DQUAKE +#include "d3dquake.h" +#endif #ifdef Q3SHADERS #include "shader.h" @@ -46,9 +55,8 @@ extern char loadname[32]; // for hunk tags void CM_Init(void); -qboolean GLMod_LoadCompositeAnim(model_t *mod, void *buffer); +qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer); qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer); -qboolean GLMod_LoadDarkPlacesModel(model_t *mod, void *buffer); qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer); qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer); qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer); @@ -57,10 +65,11 @@ qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer); #endif qboolean Mod_LoadHLModel (model_t *mod, void *buffer); #ifdef ZYMOTICMODELS -qboolean GLMod_LoadZymoticModel(model_t *mod, void *buffer); +qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer); +qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer); #endif #ifdef MD5MODELS -qboolean GLMod_LoadMD5MeshModel(model_t *mod, void *buffer); +qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer); #endif model_t *GLMod_LoadModel (model_t *mod, qboolean crash); @@ -68,12 +77,12 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash); qboolean Mod_LoadDoomLevel(model_t *mod); #endif -qboolean GL_LoadQ1Model (model_t *mod, void *buffer); +qboolean Mod_LoadQ1Model (model_t *mod, void *buffer); #ifdef MD2MODELS -qboolean GL_LoadQ2Model (model_t *mod, void *buffer); +qboolean Mod_LoadQ2Model (model_t *mod, void *buffer); #endif #ifdef MD3MODELS -qboolean GL_LoadQ3Model (model_t *mod, void *buffer); +qboolean Mod_LoadQ3Model (model_t *mod, void *buffer); #endif #ifdef DOOMWADS @@ -187,13 +196,12 @@ void GLMod_BlockTextureColour_f (void) if (!stricmp(tx->name, match)) { - tx->gl_texturenum = GL_LoadTexture32(texname, 8, 8, colour, true, false); + tx->gl_texturenum = R_LoadTexture32(texname, 8, 8, colour, true, false); } } } } } - /* =============== Mod_Init @@ -455,7 +463,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) // //look for a replacement, but not for q1 sprites ext = COM_FileExtension(mod->name); - if (Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2")) + if (gl_load24bit.value && Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2")) { char mdlbase[MAX_QPATH]; COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); @@ -535,25 +543,47 @@ couldntload: switch (LittleLong(*(unsigned *)buf)) { +//The binary 3d mesh model formats case IDPOLYHEADER: - if (!GL_LoadQ1Model(mod, buf)) + if (!Mod_LoadQ1Model(mod, buf)) goto couldntload; break; #ifdef MD2MODELS case MD2IDALIASHEADER: - if (!GL_LoadQ2Model(mod, buf)) + if (!Mod_LoadQ2Model(mod, buf)) goto couldntload; break; #endif #ifdef MD3MODELS case MD3_IDENT: - if (!GL_LoadQ3Model (mod, buf)) + if (!Mod_LoadQ3Model (mod, buf)) goto couldntload; break; #endif +#ifdef HALFLIFEMODELS + case (('T'<<24)+('S'<<16)+('D'<<8)+'I'): + if (!Mod_LoadHLModel (mod, buf)) + goto couldntload; + break; +#endif + +//Binary skeletal model formats +#ifdef ZYMOTICMODELS + case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'): + if (!Mod_LoadZymoticModel(mod, buf)) + goto couldntload; + break; + case (('K'<<24)+('R'<<16)+('A'<<8)+'D'): + if (!Mod_LoadDarkPlacesModel(mod, buf)) + goto couldntload; + break; +#endif + + +//Binary Sprites #ifdef SP2MODELS case IDSPRITE2HEADER: if (!GLMod_LoadSprite2Model (mod, buf)) @@ -565,6 +595,9 @@ couldntload: if (!GLMod_LoadSpriteModel (mod, buf)) goto couldntload; break; + + +//Binary Map formats #ifdef Q2BSPS case ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24): case IDBSPHEADER: //looks like id switched to have proper ids @@ -572,20 +605,9 @@ couldntload: goto couldntload; break; #endif -#ifdef HALFLIFEMODELS - case (('T'<<24)+('S'<<16)+('D'<<8)+'I'): - if (!Mod_LoadHLModel (mod, buf)) - goto couldntload; - break; -#endif -#ifdef TERRAINMAPS - case (('R'<<24)+('R'<<16)+('E'<<8)+'T'): - Mod_LoadTerrain(mod, buf); - break; -#endif #ifdef DOOMWADS - case (('D'<<24)+('A'<<16)+('W'<<8)+'I'): - case (('D'<<24)+('A'<<16)+('W'<<8)+'P'): + case (('D'<<24)+('A'<<16)+('W'<<8)+'I'): //the id is hacked by the FS .wad loader (main wad). + case (('D'<<24)+('A'<<16)+('W'<<8)+'P'): //the id is hacked by the FS .wad loader (patch wad). if (!Mod_LoadDoomLevel (mod)) goto couldntload; break; @@ -597,35 +619,27 @@ couldntload: if (!GLMod_LoadBrushModel (mod, buf)) goto couldntload; break; -#ifdef ZYMOTICMODELS - case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'): - if (!GLMod_LoadZymoticModel(mod, buf)) - goto couldntload; - break; - case (('K'<<24)+('R'<<16)+('A'<<8)+'D'): - if (!GLMod_LoadDarkPlacesModel(mod, buf)) - goto couldntload; - break; -#endif + +//Text based misc types. default: //check for text based headers COM_Parse((char*)buf); #ifdef MD5MODELS - if (!strcmp(com_token, "MD5Version")) + if (!strcmp(com_token, "MD5Version")) //doom3 format, text based, skeletal { - if (!GLMod_LoadMD5MeshModel (mod, buf)) + if (!Mod_LoadMD5MeshModel (mod, buf)) goto couldntload; break; } - if (!strcmp(com_token, "EXTERNALANIM")) + if (!strcmp(com_token, "EXTERNALANIM")) //custom format, text based, specifies skeletal models to load and which md5anim files to use. { - if (!GLMod_LoadCompositeAnim (mod, buf)) + if (!Mod_LoadCompositeAnim (mod, buf)) goto couldntload; break; } #endif #ifdef TERRAIN - if (!strcmp(com_token, "terrain")) + if (!strcmp(com_token, "terrain")) //custom format, text based. { if (!GL_LoadHeightmapModel(mod, buf)) goto couldntload; @@ -812,6 +826,7 @@ void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int if (!*stdname && !*flatname) return; TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name)); + if (norm && gl_bumpmappingpossible && cls.allow_bump) { *base = 0; @@ -935,11 +950,10 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); // the pixels immediately follow the structures // memcpy ( tx+1, mt+1, pixels); //have to be saved for dynamic screen changing (done by reloading entire vid/draw subsystem and all textures) - if (!Q_strncmp(mt->name,"sky",3)) { tx->offsets[0] = (char *)mt + mt->offsets[0] - (char *)tx; - GLR_InitSky (tx); + R_InitSky (tx); } else #ifdef PEXT_BULLETENS @@ -957,21 +971,17 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); {//external textures have already been filtered. base = W_ConvertWAD3Texture(mt, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit. tx->alphaed = alphaed; - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, alphaed, true))) if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, alphaed, true))) - tx->gl_texturenum = GL_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); + tx->gl_texturenum = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); *tx->name = *mt->name; - texture_mode = GL_LINEAR; } else { - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, false, true))) if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, false, true))) - tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, base, true, false); - texture_mode = GL_LINEAR; + tx->gl_texturenum = R_LoadTexture8 (mt->name, tx->width, tx->height, base, true, false); if (r_fb_bmodels.value) { @@ -983,7 +993,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, "bmodels", true, false, true); } if (!tx->gl_texturenumfb) //generate one (if possible). - tx->gl_texturenumfb = GL_LoadTextureFB(altname, tx->width, tx->height, base, true, true); + tx->gl_texturenumfb = R_LoadTextureFB(altname, tx->width, tx->height, base, true, true); } } @@ -1017,7 +1027,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); for (j = 0; j < pixels; j++) base[j] = (host_basepal[base[j]*3] + host_basepal[base[j]*3+1] + host_basepal[base[j]*3+2]) / 3; - tx->gl_texturenumbumpmap = GL_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it. + tx->gl_texturenumbumpmap = R_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it. } //don't do any complex quake 8bit -> glossmap. It would likly look a little ugly... @@ -1181,7 +1191,6 @@ void GLMod_NowLoadExternal(void) #endif { qbyte * data; - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; data = W_GetTexture(tx->name, &width, &height, &alphaed); if (data) @@ -1192,7 +1201,6 @@ void GLMod_NowLoadExternal(void) if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, loadname, true, false, true))) if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, "bmodels", true, false, true))) tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", NULL, true, false, true); //a fallback. :/ - texture_mode = GL_LINEAR; } } if (!tx->gl_texturenumbumpmap && *tx->name != '{' && gl_bumpmappingpossible && cls.allow_bump) @@ -1217,7 +1225,7 @@ void GLMod_NowLoadExternal(void) *heightmap++ = (data[j*4+0] + data[j*4+1] + data[j*4+2])/3; } - tx->gl_texturenumbumpmap = GL_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value); + tx->gl_texturenumbumpmap = R_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value); } } } @@ -2519,6 +2527,7 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs); void GLR_StainSurf (msurface_t *surf, float *parms); static void Q1BSP_StainNode (mnode_t *node, float *parms) { +#ifdef RGLQUAKE mplane_t *splitplane; float dist; msurface_t *surf; @@ -2552,6 +2561,7 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms) Q1BSP_StainNode (node->children[0], parms); Q1BSP_StainNode (node->children[1], parms); +#endif } @@ -2560,6 +2570,121 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); +void GLMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent) +{ + if (!node) + return; + + if (node->contents >= 0) + { + GLMod_FixupNodeMinsMaxs (node->children[0], node); + GLMod_FixupNodeMinsMaxs (node->children[1], node); + } + + if (parent) + { + if (parent->minmaxs[0] > node->minmaxs[0]) + parent->minmaxs[0] = node->minmaxs[0]; + if (parent->minmaxs[1] > node->minmaxs[1]) + parent->minmaxs[1] = node->minmaxs[1]; + if (parent->minmaxs[2] > node->minmaxs[2]) + parent->minmaxs[2] = node->minmaxs[2]; + + if (parent->minmaxs[3] < node->minmaxs[3]) + parent->minmaxs[3] = node->minmaxs[3]; + if (parent->minmaxs[4] < node->minmaxs[4]) + parent->minmaxs[4] = node->minmaxs[4]; + if (parent->minmaxs[5] < node->minmaxs[5]) + parent->minmaxs[5] = node->minmaxs[5]; + } + +} +void GLMod_FixupMinsMaxs(void) +{ + //q1 bsps are capped to +/- 32767 by the nodes/leafs + //verts arn't though + //so if the map is too big, let's figure out what they should be + float *v; + msurface_t **mark, *surf; + mleaf_t *pleaf; + medge_t *e, *pedges; + int en, lindex; + int i, c, lnumverts; + qboolean needsfixup = false; + + if (loadmodel->mins[0] < -32768) + needsfixup = true; + if (loadmodel->mins[1] < -32768) + needsfixup = true; + if (loadmodel->mins[2] < -32768) + needsfixup = true; + + if (loadmodel->maxs[0] > 32767) + needsfixup = true; + if (loadmodel->maxs[1] > 32767) + needsfixup = true; + if (loadmodel->maxs[2] > 32767) + needsfixup = true; + + if (!needsfixup) + return; + + //this is insane. + //why am I writing this? + //by the time the world actually gets this large, the floating point errors are going to be so immensly crazy that it's just not worth it. + + pedges = loadmodel->edges; + + for (i = 0; i < loadmodel->numleafs; i++) + { + pleaf = &loadmodel->leafs[i]; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + surf = (*mark++); + + lnumverts = surf->numedges; + for (en=0 ; ensurfedges[surf->firstedge + en]; + + if (lindex > 0) + { + e = &pedges[lindex]; + v = currentmodel->vertexes[e->v[0]].position; + } + else + { + e = &pedges[-lindex]; + v = currentmodel->vertexes[e->v[1]].position; + } + + if (pleaf->minmaxs[0] > v[0]) + pleaf->minmaxs[0] = v[0]; + if (pleaf->minmaxs[1] > v[1]) + pleaf->minmaxs[1] = v[1]; + if (pleaf->minmaxs[2] > v[2]) + pleaf->minmaxs[2] = v[2]; + + if (pleaf->minmaxs[3] < v[0]) + pleaf->minmaxs[3] = v[0]; + if (pleaf->minmaxs[4] < v[1]) + pleaf->minmaxs[4] = v[1]; + if (pleaf->minmaxs[5] < v[2]) + pleaf->minmaxs[5] = v[2]; + + } + } while (--c); + } + } + GLMod_FixupNodeMinsMaxs (loadmodel->nodes, NULL); // sets nodes and leafs +} + /* ================= Mod_LoadBrushModel @@ -2765,6 +2890,9 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer) LightLoadEntities(lightmodel->entities); #endif + if (1) + GLMod_FixupMinsMaxs(); + return true; } @@ -2925,17 +3053,17 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum { size *= 4; if (!pspriteframe->gl_texturenum) - pspriteframe->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true); + pspriteframe->gl_texturenum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true); } else if (version == SPRITEHL_VERSION) { if (!pspriteframe->gl_texturenum) - pspriteframe->gl_texturenum = GL_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true); + pspriteframe->gl_texturenum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true); } else { if (!pspriteframe->gl_texturenum) - pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (qbyte *)(pinframe + 1), true, true); + pspriteframe->gl_texturenum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), true, true); } return (void *)((qbyte *)(pinframe+1) + size); @@ -3193,6 +3321,7 @@ qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer) frame = psprite->frames[i].frameptr = Hunk_AllocName(sizeof(mspriteframe_t), loadname); frame->gl_texturenum = Mod_LoadHiResTexture(pframetype->name, NULL, true, true, true); + frame->width = LittleLong(pframetype->width); frame->height = LittleLong(pframetype->height); origin[0] = LittleLong (pframetype->origin_x); diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 8de08a567..9c36c5b19 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -56,7 +56,18 @@ typedef struct { int (*LeafnumForPoint) (struct model_s *model, vec3_t point); } bspfuncs_t; -typedef int index_t; +#ifdef D3DQUAKE + #define sizeof_index_t 2 +#endif + +#if sizeof_index_t == 2 + #define GL_INDEX_TYPE GL_UNSIGNED_SHORT + typedef unsigned short index_t; +#else + #define GL_INDEX_TYPE GL_UNSIGNED_INT + typedef unsigned int index_t; +#endif + typedef struct mesh_s { int numvertexes; @@ -336,9 +347,13 @@ typedef struct mleaf_s int nummarksurfaces; int key; // BSP sequence number for leaf's contents qbyte ambient_sound_level[NUM_AMBIENTS]; + +#if defined(Q2BSPS) || defined(Q3BSPS) + int cluster; + struct mleaf_s *vischain; +#endif #ifdef Q2BSPS //it's a q2 thing - int cluster; int area; unsigned short firstleafbrush; unsigned short numleafbrushes; @@ -348,8 +363,6 @@ typedef struct mleaf_s unsigned short numleafpatches; unsigned short firstleafpatch; - - struct mleaf_s *vischain; #endif } mleaf_t; diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 0ff496541..ea5522976 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -141,7 +141,7 @@ typedef struct { #define MAXARRAYVERTS 2048 static surfvertexarray_t varray_v[MAXARRAYVERTS]; -static unsigned int varray_i[MAXARRAYVERTS]; +static index_t varray_i[MAXARRAYVERTS]; //static unsigned int varray_i_forward[MAXARRAYVERTS]; //static unsigned int varray_i_polytotri[MAXARRAYVERTS]; //012 023 034 045... int varray_ic; @@ -162,7 +162,7 @@ inline void PPL_EnableVertexArrays(void) inline void PPL_FlushArrays(void) { if (varray_ic) - qglDrawElements(GL_TRIANGLES, varray_ic, GL_UNSIGNED_INT, varray_i); + qglDrawElements(GL_TRIANGLES, varray_ic, GL_INDEX_TYPE, varray_i); varray_ic = 0; varray_vc = 0; } @@ -362,8 +362,8 @@ static void PPL_BaseChain_NoBump_1TMU(msurface_t *first, texture_t *tex) qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); - //qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); + //qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } qglDisable(GL_TEXTURE_2D); @@ -448,7 +448,7 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex) qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } if (overbright != 1) @@ -1146,7 +1146,7 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex) qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } GLSlang_UseProgram(0); @@ -1288,7 +1288,7 @@ static void PPL_BaseChain_Flat(msurface_t *first) qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } qglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1654,7 +1654,7 @@ static void PPL_BaseTextureChain(msurface_t *first) - t = GLR_TextureAnimation (first->texinfo->texture); + t = R_TextureAnimation (first->texinfo->texture); if (first->flags & SURF_DRAWTURB) { @@ -1714,7 +1714,7 @@ static void PPL_FullBrightTextureChain(msurface_t *first) texture_t *t; msurface_t *s; - t = GLR_TextureAnimation (first->texinfo->texture); + t = R_TextureAnimation (first->texinfo->texture); if (detailtexture && gl_detail.value) { @@ -1797,7 +1797,7 @@ void PPL_BaseTextures(model_t *model) if (s) { t->texturechain = NULL; - R_DrawSkyChain (s); + GL_DrawSkyChain (s); } } } @@ -2511,7 +2511,7 @@ void PPL_LightTexturesFP_Cached(model_t *model, vec3_t modelorigin, dlight_t *li s = shm->litsurfs[j].s[0]; t = s->texinfo->texture; - t = GLR_TextureAnimation (t); + t = R_TextureAnimation (t); for (i=0 ; ilitsurfs[j].count ; i++) { @@ -2582,7 +2582,7 @@ void PPL_LightTexturesFP_Cached(model_t *model, vec3_t modelorigin, dlight_t *li qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } } GLSlang_UseProgram(0); @@ -2628,7 +2628,7 @@ void PPL_LightTexturesFP(model_t *model, vec3_t modelorigin, dlight_t *light, ve // if ((s->flags & SURF_DRAWTURB) && r_wateralphaval != 1.0) // continue; // draw translucent water later - t = GLR_TextureAnimation (t); + t = R_TextureAnimation (t); p = 0; @@ -2684,7 +2684,7 @@ void PPL_LightTexturesFP(model_t *model, vec3_t modelorigin, dlight_t *light, ve qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } } @@ -2732,7 +2732,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 { extern int normalisationCubeMap; - t = GLR_TextureAnimation (t); + t = R_TextureAnimation (t); qglEnableClientState(GL_COLOR_ARRAY); @@ -2814,7 +2814,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 PPL_GenerateLightArrays(s, relativelightorigin, light, colour); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); varray_ic = 0; varray_vc = 0; @@ -2878,7 +2878,7 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour) { tnum = s->texinfo->texture; - t = GLR_TextureAnimation (tnum); + t = R_TextureAnimation (tnum); p = 0; if (t->gl_texturenumbumpmap && ppl_light_shader[p|PERMUTATION_BUMPMAP]) @@ -2913,7 +2913,7 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour) qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } @@ -2954,7 +2954,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) { - t = GLR_TextureAnimation (s->texinfo->texture); + t = R_TextureAnimation (s->texinfo->texture); qglEnableClientState(GL_COLOR_ARRAY); qglColorPointer(3, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stl); @@ -3043,7 +3043,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) PPL_GenerateLightArrays(s, relativelightorigin, light, colour); qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); varray_ic = 0; varray_vc = 0; } @@ -3702,7 +3702,7 @@ void PPL_RecursiveWorldNode_r (mnode_t *node) shadowsurfcount++; qglVertexPointer(3, GL_FLOAT, 0, surf->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_UNSIGNED_INT, surf->mesh->indexes); + qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes); //fixme:this only works becuse q1bsps don't have combined meshes yet... //back (depth precision doesn't matter) @@ -3877,7 +3877,7 @@ void PPL_RecursiveWorldNodeQ2_r (mnode_t *node) //front face qglVertexPointer(3, GL_FLOAT, 0, surf->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_UNSIGNED_INT, surf->mesh->indexes); + qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes); //fixme:this only works becuse q1bsps don't have combined meshes yet... //back (depth precision doesn't matter) @@ -3972,7 +3972,7 @@ void PPL_RecursiveWorldNodeQ3_r (mnode_t *node) { //front face qglVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*VERTEXSIZE, p->verts); - qglDrawElements(GL_TRIANGLES, (p->numverts-2)*3, GL_UNSIGNED_INT, varray_i_polytotri); + qglDrawElements(GL_TRIANGLES, (p->numverts-2)*3, GL_INDEX_TYPE, varray_i_polytotri); //fixme... for (v = 0; v < p->numverts; v++) { @@ -4086,7 +4086,7 @@ void PPL_RecursiveWorldNode (dlight_t *dl) { qglEnableClientState(GL_VERTEX_ARRAY); qglVertexPointer(3, GL_FLOAT, 0, dl->worldshadowmesh->verts); - qglDrawRangeElements(GL_TRIANGLES, 0, dl->worldshadowmesh->numverts, dl->worldshadowmesh->numindicies, GL_UNSIGNED_INT, dl->worldshadowmesh->indicies); + qglDrawRangeElements(GL_TRIANGLES, 0, dl->worldshadowmesh->numverts, dl->worldshadowmesh->numindicies, GL_INDEX_TYPE, dl->worldshadowmesh->indicies); return; } @@ -4491,7 +4491,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs) v[1] = (i & 2) ? mins[1] : maxs[1]; v[2] = (i & 4) ? mins[2] : maxs[2]; v[3] = 1.0f; - ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, (float)vid.width/vid.height, r_refdef.fov_y); + Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, (float)vid.width/vid.height, r_refdef.fov_y); v2[0]*=r_view_width; v2[1]*=r_view_height; // GL_TransformToScreen(v, v2); @@ -4561,7 +4561,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs) v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_refdef.vieworg[1]; v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_refdef.vieworg[2]; v[3] = 1.0f; - ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y); + Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y); v2[0]*=r_view_width; v2[1]*=r_view_height; // GL_TransformToScreen(v, v2); diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 3b8b63c2f..0bb4056b6 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -20,11 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // r_light.c #include "quakedef.h" -#ifdef RGLQUAKE +#if defined(RGLQUAKE) || defined(D3DQUAKE) #include "glquake.h" int r_dlightframecount; - +int d_lightstylevalue[256]; // 8.8 fraction of base light value /* ================== @@ -64,6 +64,9 @@ void GLR_AnimateLight (void) v2 = cl_lightstyle[j].map[v2] - 'a'; d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22; + + if (d_lightstylevalue[j] > 255) + d_lightstylevalue[j] = 255; } } @@ -111,6 +114,7 @@ void R_InitBubble() { } } +#ifdef RGLQUAKE void R_RenderDlight (dlight_t *light) { int i, j; @@ -157,7 +161,7 @@ void R_RenderDlight (dlight_t *light) R_RenderDlights ============= */ -void R_RenderDlights (void) +void GLR_RenderDlights (void) { int i; dlight_t *l; @@ -206,7 +210,7 @@ void R_RenderDlights (void) qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglDepthMask (1); } - +#endif /* ============================================================================= diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 9d2d3b973..22f4b338c 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -54,7 +54,7 @@ int r_framecount; // used for dlight push checking float r_wateralphaval; //allowed or not... -mplane_t frustum[4]; +//mplane_t frustum[4]; int c_brush_polys, c_alias_polys; @@ -79,8 +79,8 @@ vec3_t vpn; vec3_t vright; vec3_t r_origin; -float r_projection_matrix[16]; -float r_view_matrix[16]; +extern float r_projection_matrix[16]; +extern float r_view_matrix[16]; // // screen size info @@ -93,10 +93,7 @@ int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; texture_t *r_notexture_mip; -int d_lightstylevalue[256]; // 8.8 fraction of base light value - - -void GLR_MarkLeaves (void); +//void R_MarkLeaves (void); cvar_t r_norefresh = SCVAR("r_norefresh","0"); //cvar_t r_drawentities = SCVAR("r_drawentities","1"); @@ -105,7 +102,7 @@ cvar_t r_norefresh = SCVAR("r_norefresh","0"); //cvar_t r_fullbright = SCVAR("r_fullbright","0"); cvar_t r_mirroralpha = SCVARF("r_mirroralpha","1", CVAR_CHEAT); //cvar_t r_waterwarp = SCVAR("r_waterwarp", "0"); -cvar_t r_novis = SCVAR("r_novis","0"); +//cvar_t r_novis = SCVAR("r_novis","0"); //cvar_t r_netgraph = SCVAR("r_netgraph","0"); extern cvar_t gl_part_flame; @@ -122,7 +119,7 @@ cvar_t gl_finish = SCVAR("gl_finish","0"); cvar_t gl_contrast = SCVAR("gl_contrast", "1"); cvar_t gl_dither = SCVAR("gl_dither", "1"); cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192"); -cvar_t gl_mindist = SCVARF("gl_mindist", "4", CVAR_CHEAT); //by setting to 64 or something, you can use this as a wallhack +extern cvar_t gl_mindist; extern cvar_t gl_motionblur; extern cvar_t gl_motionblurscale; @@ -365,39 +362,6 @@ void GL_SetupSceneProcessingTextures (void) qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex); } -/* -================= -R_CullBox - -Returns true if the box is completely outside the frustom -================= -*/ -qboolean R_CullBox (vec3_t mins, vec3_t maxs) -{ - int i; - - for (i=0 ; i<4 ; i++) - if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2) - return true; - return false; -} - -qboolean R_CullSphere (vec3_t org, float radius) -{ - //four frustrum planes all point inwards in an expanding 'cone'. - int i; - float d; - - for (i=0 ; i<4 ; i++) - { - d = DotProduct(frustum[i].normal, org)-frustum[i].dist; - if (d <= -radius) - return true; - } - return false; -} - - void R_RotateForEntity (entity_t *e) { float m[16]; @@ -462,6 +426,7 @@ void R_RotateForEntity (entity_t *e) R_GetSpriteFrame ================ */ +/* mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) { msprite_t *psprite; @@ -512,7 +477,7 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) return pspriteframe; } - +*/ /* ================= @@ -535,7 +500,7 @@ void R_DrawSpriteModel (entity_t *e) mesh_t mesh; vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}}; vec3_t vertcoords[4]; - int indexes[6] = {0, 1, 2, 0, 2, 3}; + index_t indexes[6] = {0, 1, 2, 0, 2, 3}; byte_vec4_t colours[4]; float x, y; @@ -890,100 +855,6 @@ void GLR_BrightenScreen (void) RSpeedEnd(RSPEED_PALETTEFLASHES); } -int SignbitsForPlane (mplane_t *out) -{ - int bits, j; - - // for fast box on planeside test - - bits = 0; - for (j=0 ; j<3 ; j++) - { - if (out->normal[j] < 0) - bits |= 1<nextalphasurface) //write the polys to the stencil buffer. { qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes); + qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index db5e0618d..8253bee36 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -41,7 +41,7 @@ int *lightmap_textures; int *deluxmap_textures; int detailtexture; -#define MAX_LIGHTMAP_SIZE 256 +#define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; unsigned blocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; @@ -1665,42 +1665,6 @@ store: #endif } -/* -=============== -R_TextureAnimation - -Returns the proper texture for a given time and base texture -=============== -*/ -texture_t *GLR_TextureAnimation (texture_t *base) -{ - int reletive; - int count; - - if (currententity->frame) - { - if (base->alternate_anims) - base = base->alternate_anims; - } - - if (!base->anim_total) - return base; - - reletive = (int)(cl.time*10) % base->anim_total; - - count = 0; - while (base->anim_min > reletive || base->anim_max <= reletive) - { - base = base->anim_next; - if (!base) - Sys_Error ("R_TextureAnimation: broken cycle"); - if (++count > 100) - Sys_Error ("R_TextureAnimation: infinite cycle"); - } - - return base; -} - /* ============================================================= @@ -1758,7 +1722,7 @@ static void DrawGLPoly (mesh_t *mesh) qglEnableClientState( GL_VERTEX_ARRAY ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); R_IBrokeTheArrays(); /* @@ -1892,11 +1856,11 @@ void R_RenderBrushPoly (msurface_t *fa) if (fa->flags & SURF_DRAWSKY) { // warp texture, no lightmaps - EmitBothSkyLayers (fa); + GL_EmitBothSkyLayers (fa); return; } - t = GLR_TextureAnimation (fa->texinfo->texture); + t = R_TextureAnimation (fa->texinfo->texture); GL_Bind (t->gl_texturenum); if (fa->flags & SURF_DRAWTURB) @@ -2328,6 +2292,7 @@ void VectorVectors(vec3_t forward, vec3_t right, vec3_t up); DrawTextureChains ================ */ +/* #if 0 static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelightorigin) { @@ -2353,7 +2318,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight if (s) { t->texturechain = NULL; - R_DrawSkyChain (s); + GL_DrawSkyChain (s); } } } @@ -2383,7 +2348,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight continue; t->texturechain = NULL; if (i == skytexturenum && model == cl.worldmodel) - R_DrawSkyChain (s); + GL_DrawSkyChain (s); else if (i == mirrortexturenum && model == cl.worldmodel && r_mirroralpha.value != 1.0) R_MirrorChain (s); else @@ -2399,7 +2364,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight else first = s; - t = GLR_TextureAnimation (t); + t = R_TextureAnimation (t); cf = s; @@ -2674,11 +2639,13 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } #endif +*/ /* ================= R_DrawBrushModel ================= */ +/* #if 0 static void R_DrawBrushModel (entity_t *e) { @@ -2794,7 +2761,7 @@ e->angles[0] = -e->angles[0]; // stupid quake bug glPopMatrix (); } #endif - +*/ /* ============================================================= @@ -3038,6 +3005,7 @@ static void GLR_RecursiveQ2WorldNode (mnode_t *node) #endif #ifdef Q3BSPS +mleaf_t *r_vischain; // linked list of visible leafs static void GLR_LeafWorldNode (void) { int i; @@ -3175,174 +3143,6 @@ qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer); -/* -=============== -R_MarkLeaves -=============== -*/ -void GLR_MarkLeaves (void) -{ - qbyte fatvis[MAX_MAP_LEAFS/8]; - qbyte *vis; - mnode_t *node; - int i; - qbyte solid[4096]; -#ifdef Q3BSPS - if (cl.worldmodel->fromgame == fg_quake3) - { - int cluster; - mleaf_t *leaf; - - if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1) - return; - - // development aid to let you run around and see exactly where - // the pvs ends -// if (r_lockpvs->value) -// return; - - r_vischain = NULL; - r_visframecount++; - r_oldviewcluster = r_viewcluster; - - if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis ) - { - // mark everything - for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) - { - if ( !leaf->nummarksurfaces ) { - continue; - } - - leaf->visframe = r_visframecount; - leaf->vischain = r_vischain; - r_vischain = leaf; - } - return; - } - - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel); - for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) - { - cluster = leaf->cluster; - if ( cluster == -1 || !leaf->nummarksurfaces ) { - continue; - } - if ( vis[cluster>>3] & (1<<(cluster&7)) ) { - leaf->visframe = r_visframecount; - leaf->vischain = r_vischain; - r_vischain = leaf; - } - } - return; - } -#endif - -#ifdef Q2BSPS - if (cl.worldmodel->fromgame == fg_quake2) - { - int c; - mleaf_t *leaf; - int cluster; - - if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) - return; - - r_oldviewcluster = r_viewcluster; - r_oldviewcluster2 = r_viewcluster2; - - if (r_novis.value == 2) - return; - r_visframecount++; - if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis) - { - // mark everything - for (i=0 ; inumleafs ; i++) - cl.worldmodel->leafs[i].visframe = r_visframecount; - for (i=0 ; inumnodes ; i++) - cl.worldmodel->nodes[i].visframe = r_visframecount; - return; - } - - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel); - // may have to combine two clusters because of solid water boundaries - if (r_viewcluster2 != r_viewcluster) - { - memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8); - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel); - c = (cl.worldmodel->numleafs+31)/32; - for (i=0 ; ileafs ; inumleafs ; i++, leaf++) - { - cluster = leaf->cluster; - if (cluster == -1) - continue; - if (vis[cluster>>3] & (1<<(cluster&7))) - { - node = (mnode_t *)leaf; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } - return; - } -#endif - - if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2) - return; - -// if (mirror) -// return; - - r_visframecount++; - - r_oldviewleaf = r_viewleaf; - r_oldviewleaf2 = r_viewleaf2; - - if (r_novis.value) - { - vis = solid; - memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); - } - else if (r_viewleaf2) - { - int c; - Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis); - vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL); - c = (cl.worldmodel->numleafs+31)/32; - for (i=0 ; inumleafs ; i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } -} - /* @@ -3471,7 +3271,7 @@ int nColinElim; BuildSurfaceDisplayList ================ */ -void BuildSurfaceDisplayList (msurface_t *fa) +void GL_BuildSurfaceDisplayList (msurface_t *fa) { int i, lindex, lnumverts; medge_t *pedges, *r_pedge; @@ -3837,7 +3637,7 @@ void GL_BuildLightmaps (void) P_EmitSkyEffectTris(m, &m->surfaces[i]); if (m->surfaces[i].mesh) //there are some surfaces that have a display list already (the subdivided ones) continue; - BuildSurfaceDisplayList (m->surfaces + i); + GL_BuildSurfaceDisplayList (m->surfaces + i); } } diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 48e9d288a..8053557c6 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -42,77 +42,6 @@ extern int scr_chatmode; extern cvar_t scr_chatmodecvar; - -void RSpeedShow(void) -{ - int i; - static int samplerspeeds[RSPEED_MAX]; - static int samplerquant[RQUANT_MAX]; - char *RSpNames[RSPEED_MAX]; - char *RQntNames[RQUANT_MAX]; - char *s; - static int framecount; - - if (!r_speeds.value) - return; - - memset(RSpNames, 0, sizeof(RSpNames)); - RSpNames[RSPEED_TOTALREFRESH] = "Total refresh"; - RSpNames[RSPEED_PROTOCOL] = "Protocol"; - RSpNames[RSPEED_LINKENTITIES] = "Entity setup"; - RSpNames[RSPEED_WORLDNODE] = "World walking"; - RSpNames[RSPEED_WORLD] = "World rendering"; - RSpNames[RSPEED_DYNAMIC] = "Lightmap updates"; - RSpNames[RSPEED_PARTICLES] = "Particle physics and sorting"; - RSpNames[RSPEED_PARTICLESDRAW] = "Particle drawing"; - RSpNames[RSPEED_2D] = "2d elements"; - RSpNames[RSPEED_SERVER] = "Server"; - - RSpNames[RSPEED_DRAWENTITIES] = "Entity rendering"; - - RSpNames[RSPEED_PALETTEFLASHES] = "Palette flashes"; - RSpNames[RSPEED_STENCILSHADOWS] = "Stencil Shadows"; - - RSpNames[RSPEED_FULLBRIGHTS] = "World fullbrights"; - - RSpNames[RSPEED_FINISH] = "Waiting for card to catch up"; - - RQntNames[RQUANT_MSECS] = "Microseconds"; - RQntNames[RQUANT_EPOLYS] = "Entity Polys"; - RQntNames[RQUANT_WPOLYS] = "World Polys"; - RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces"; - RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges"; - RQntNames[RQUANT_LITFACES] = "Lit faces"; - - for (i = 0; i < RSPEED_MAX; i++) - { - s = va("%i %-30s", samplerspeeds[i], RSpNames[i]); - Draw_String(vid.width-strlen(s)*8, i*8, s); - } - for (i = 0; i < RQUANT_MAX; i++) - { - s = va("%i %-30s", samplerquant[i], RQntNames[i]); - Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); - } - s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate"); - Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); - - if (framecount++>=100) - { - for (i = 0; i < RSPEED_MAX; i++) - { - samplerspeeds[i] = rspeeds[i]; - rspeeds[i] = 0; - } - for (i = 0; i < RQUANT_MAX; i++) - { - samplerquant[i] = rquant[i]; - rquant[i] = 0; - } - framecount=0; - } -} - // console size manipulation callbacks void GLVID_Console_Resize(void) { diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 0ad163435..577809e50 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -167,13 +167,6 @@ const char *gl_renderer; const char *gl_version; const char *gl_extensions; -//int texture_mode = GL_NEAREST; -//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; -//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; -int texture_mode = GL_LINEAR; -//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; -//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; - int texture_extension_number = 1; void APIENTRY GL_DrawRangeElementsEmul(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index a7c108b46..5a3f926b1 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -85,7 +85,6 @@ static qboolean vid_initialized = false; static qboolean leavecurrentmode= true; static qboolean vid_canalttab = false; static qboolean vid_wassuspended = false; -static int windowed_mouse; extern qboolean mouseactive; // from in_win.c static HICON hIcon; extern qboolean vid_isfullscreen; @@ -910,16 +909,14 @@ void GL_DoSwap (void) { if (!_windowed_mouse.value) { - if (windowed_mouse) + if (mouseactive) { IN_DeactivateMouse (); IN_ShowMouse (); - windowed_mouse = false; } } else { - windowed_mouse = true; if ((key_dest == key_game||mouseusedforgui) && !mouseactive && ActiveApp) { IN_ActivateMouse (); diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 4f11a4744..b0ed07415 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -20,8 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // gl_warp.c -- sky and water polygons #include "quakedef.h" -#ifdef RGLQUAKE +#if defined(RGLQUAKE) || defined(D3DQUAKE) #include "glquake.h" +#ifdef D3DQUAKE +#include "d3dquake.h" +#endif #ifdef Q3SHADERS #include "shader.h" #endif @@ -30,7 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern void GL_DrawAliasMesh (mesh_t *mesh, int texnum); -void R_DrawSkySphere (msurface_t *fa); +void GL_DrawSkySphere (msurface_t *fa); +void D3D7_DrawSkySphere (msurface_t *fa); +void D3D9_DrawSkySphere (msurface_t *fa); extern model_t *loadmodel; @@ -55,7 +60,7 @@ char defaultskybox[MAX_QPATH]; int skyboxtex[6]; -void R_DrawSkyBox (msurface_t *s); +void GL_DrawSkyBox (msurface_t *s); void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) { int i, j; @@ -92,6 +97,7 @@ EmitWaterPolys Does a water warp on the pre-fragmented glpoly_t chain ============= */ +#ifdef RGLQUAKE void EmitWaterPolys (msurface_t *fa, float basealpha) { float a; @@ -167,7 +173,7 @@ This will be called for brushmodels, the world will have them chained together. =============== */ -void EmitBothSkyLayers (msurface_t *fa) +void GL_EmitBothSkyLayers (msurface_t *fa) { GL_DisableMultitexture(); @@ -187,13 +193,16 @@ void EmitBothSkyLayers (msurface_t *fa) qglDisable (GL_BLEND); } +#endif + /* ================= -R_DrawSkyChain +GL_DrawSkyChain ================= */ +#ifdef RGLQUAKE void R_DrawSkyBoxChain (msurface_t *s); -void R_DrawSkyChain (msurface_t *s) +void GL_DrawSkyChain (msurface_t *s) { msurface_t *fa; @@ -229,7 +238,7 @@ void R_DrawSkyChain (msurface_t *s) for (fa=s ; fa ; fa=fa->texturechain) { qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_UNSIGNED_INT, fa->mesh->indexes); + qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); } R_IBrokeTheArrays(); @@ -245,7 +254,7 @@ void R_DrawSkyChain (msurface_t *s) } // if (usingskydome) { - R_DrawSkySphere(s); + GL_DrawSkySphere(s); return; } @@ -269,6 +278,116 @@ void R_DrawSkyChain (msurface_t *s) qglDisable (GL_BLEND); } +#endif + +#ifdef D3DQUAKE +void R_DrawSkyBoxChain (msurface_t *s); +void D3D7_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + +#ifdef Q3SHADERS + if (!solidskytexture&&!usingskybox) + { + int i; + if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) + { + for (i = 0; i < 6; i++) + { + skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; + } + solidskytexture = 1; + } + } +#endif +/* + if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) + { + int fc; + qbyte *pal; + fc = r_fastskycolour.value; + if (fc > 255) + fc = 255; + if (fc < 0) + fc = 0; + pal = host_basepal+fc*3; + qglDisable(GL_TEXTURE_2D); + qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f); + qglDisableClientState( GL_COLOR_ARRAY ); + for (fa=s ; fa ; fa=fa->texturechain) + { + qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); + qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); + } + R_IBrokeTheArrays(); + + qglColor3f(1, 1, 1); + qglEnable(GL_TEXTURE_2D); + return; + } +*/ +/* if (usingskybox) + { + R_DrawSkyBoxChain(s); + return; + } +*/ + D3D7_DrawSkySphere(s); +} + +void D3D9_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + +#ifdef Q3SHADERS + if (!solidskytexture&&!usingskybox) + { + int i; + if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) + { + for (i = 0; i < 6; i++) + { + skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; + } + solidskytexture = 1; + } + } +#endif +/* + if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) + { + int fc; + qbyte *pal; + fc = r_fastskycolour.value; + if (fc > 255) + fc = 255; + if (fc < 0) + fc = 0; + pal = host_basepal+fc*3; + qglDisable(GL_TEXTURE_2D); + qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f); + qglDisableClientState( GL_COLOR_ARRAY ); + for (fa=s ; fa ; fa=fa->texturechain) + { + qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); + qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); + } + R_IBrokeTheArrays(); + + qglColor3f(1, 1, 1); + qglEnable(GL_TEXTURE_2D); + return; + } +*/ +/* if (usingskybox) + { + R_DrawSkyBoxChain(s); + return; + } +*/ + D3D9_DrawSkySphere(s); +} +#endif /* ================================================================= @@ -338,8 +457,14 @@ void GLR_LoadSkys (void) if (!skyboxtex[i]) break; - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#ifdef RGLQUAKE + //so the user can specify GL_NEAREST and still get nice skyboxes... yeah, a hack + if (qrenderer == QR_OPENGL) + { + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +#endif } if (boxname != defaultskybox && i < 6 && *defaultskybox) { @@ -585,7 +710,7 @@ void ClipSkyPolygon (int nump, vec3_t vecs, int stage) /* ================= -R_DrawSkyChain +R_DrawSkyBoxChain ================= */ void R_DrawSkyBoxChain (msurface_t *s) @@ -611,7 +736,13 @@ void R_DrawSkyBoxChain (msurface_t *s) } } - R_DrawSkyBox (s); +#ifdef RGLQUAKE + if (qrenderer == QR_OPENGL) + { + GL_DrawSkyBox (s); + return; + } +#endif } #define skygridx 16 @@ -622,16 +753,106 @@ void R_DrawSkyBoxChain (msurface_t *s) #define skygridyrecip (1.0f / (skygridy)) #define skysphere_numverts (skygridx1 * skygridy1) #define skysphere_numtriangles (skygridx * skygridy * 2) -static float skysphere_vertex3f[skysphere_numverts * 3]; -static float skysphere_texcoord2f[skysphere_numverts * 2]; -static int skysphere_element3i[skysphere_numtriangles * 3]; -mesh_t skymesh; int skymade; +static index_t skysphere_element3i[skysphere_numtriangles * 3]; +static float skysphere_texcoord2f[skysphere_numverts * 2]; -static void skyspherecalc(int skytype) +#ifdef D3DQUAKE +static float skysphere_d3dvertex[skysphere_numverts * 5]; +static d3d_animateskysphere(float time) +{ + int i; + float *d3dvert, *texcoord2f; + + d3dvert = skysphere_d3dvertex; + texcoord2f = skysphere_texcoord2f; + for (i = 0; i < skysphere_numverts; i++) + { + d3dvert[3] = time+*texcoord2f++; + d3dvert[4] = time+*texcoord2f++; + + d3dvert+=5; + } +} +static void d3d_skyspherecalc(int skytype) { //yes, this is basically stolen from DarkPlaces - int i, j, *e; + int i, j; + index_t *e; + float a, b, x, ax, ay, v[3], length, *d3dvert, *texcoord2f; + float dx, dy, dz; + + float texscale; + + if (skymade == skytype+500) + return; + + skymade = skytype+500; + + if (skytype == 2) + texscale = 1/16.0f; + else + texscale = 1/1.5f; + + texscale*=3; + + dx = 16; + dy = 16; + dz = 16 / 3; + + d3dvert = skysphere_d3dvertex; + texcoord2f = skysphere_texcoord2f; + + for (j = 0;j <= skygridy;j++) + { + a = j * skygridyrecip; + ax = cos(a * M_PI * 2); + ay = -sin(a * M_PI * 2); + for (i = 0;i <= skygridx;i++) + { + b = i * skygridxrecip; + x = cos((b + 0.5) * M_PI); + v[0] = ax*x * dx; + v[1] = ay*x * dy; + v[2] = -sin((b + 0.5) * M_PI) * dz; + length = texscale / sqrt(v[0]*v[0]+v[1]*v[1]+(v[2]*v[2]*9)); + + *d3dvert++ = v[0]*1000; + *d3dvert++ = v[1]*1000; + *d3dvert++ = v[2]*1000; + + d3dvert+=2; + + *texcoord2f++ = v[0] * length; + *texcoord2f++ = v[1] * length; + } + } + e = skysphere_element3i; + for (j = 0;j < skygridy;j++) + { + for (i = 0;i < skygridx;i++) + { + *e++ = j * skygridx1 + i; + *e++ = j * skygridx1 + i + 1; + *e++ = (j + 1) * skygridx1 + i; + + *e++ = j * skygridx1 + i + 1; + *e++ = (j + 1) * skygridx1 + i + 1; + *e++ = (j + 1) * skygridx1 + i; + } + } +} +#endif + +#ifdef RGLQUAKE +static float skysphere_vertex3f[skysphere_numverts * 3]; +mesh_t skymesh; + + +static void gl_skyspherecalc(int skytype) +{ //yes, this is basically stolen from DarkPlaces + int i, j; + index_t *e; float a, b, x, ax, ay, v[3], length, *vertex3f, *texcoord2f; float dx, dy, dz; @@ -697,7 +918,8 @@ static void skyspherecalc(int skytype) } } } -void R_DrawSkySphere (msurface_t *fa) + +void GL_DrawSkySphere (msurface_t *fa) { extern cvar_t gl_maxdist; float time = cl.gametime+realtime-cl.gametimemark; @@ -718,7 +940,7 @@ void R_DrawSkySphere (msurface_t *fa) if (fa->texinfo->texture->shader) { //the shader route. meshbuffer_t mb; - skyspherecalc(2); + gl_skyspherecalc(2); mb.sortkey = 0; mb.infokey = -1; mb.dlightbits = 0; @@ -732,7 +954,7 @@ void R_DrawSkySphere (msurface_t *fa) else #endif { //the boring route. - skyspherecalc(1); + gl_skyspherecalc(1); qglMatrixMode(GL_TEXTURE); qglPushMatrix(); qglTranslatef(time*8/128, time*8/128, 0); @@ -759,6 +981,169 @@ void R_DrawSkySphere (msurface_t *fa) qglColorMask(1,1,1,1); } } +#endif + +#ifdef D3DQUAKE +void D3D7_DrawSkySphere (msurface_t *fa) +{ + extern cvar_t gl_maxdist; + float time = cl.gametime+realtime-cl.gametimemark; + + float skydist = 99999;//gl_maxdist.value; + if (skydist<1) + skydist=gl_skyboxdist.value; + skydist/=16; + + //scale sky sphere and place around view origin. +// qglPushMatrix(); +// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]); +// qglScalef(skydist, skydist, skydist); + +//draw in bulk? this is eeevil +//FIXME: We should use the skybox clipping code and split the sphere into 6 sides. +/*#ifdef Q3SHADERS + if (fa->texinfo->texture->shader) + { //the shader route. + meshbuffer_t mb; + d3d_skyspherecalc(2); + mb.sortkey = 0; + mb.infokey = -1; + mb.dlightbits = 0; + mb.entity = &r_worldentity; + mb.shader = fa->texinfo->texture->shader; + mb.fog = NULL; + mb.mesh = &skymesh; + R_PushMesh(mb.mesh, mb.shader->features); + R_RenderMeshBuffer(&mb, false); + } + else +#endif*/ + { //the boring route. + d3d_skyspherecalc(1); +// qglMatrixMode(GL_TEXTURE); +// qglPushMatrix(); +// qglTranslatef(time*8/128, time*8/128, 0); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); + + d3d_animateskysphere(time*8/128); + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)solidskytexture); + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); +// pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + +// qglTranslatef(time*8/128, time*8/128, 0); + d3d_animateskysphere(time*16/128); + pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)alphaskytexture); + pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0); + + pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); +// qglDisable(GL_BLEND); +// qglPopMatrix(); +// qglMatrixMode(GL_MODELVIEW); + } +// qglPopMatrix(); + +/* + if (!cls.allow_skyboxes) //allow a little extra fps. + {//Draw the texture chain to only the depth buffer. + if (qglColorMask) + qglColorMask(0,0,0,0); + for (; fa; fa = fa->texturechain) + { + GL_DrawAliasMesh(fa->mesh, 0); + } + if (qglColorMask) + qglColorMask(1,1,1,1); + } + */ +} +void D3D9_DrawSkySphere (msurface_t *fa) +{ + extern cvar_t gl_maxdist; + float time = cl.gametime+realtime-cl.gametimemark; + + float skydist = 99999;//gl_maxdist.value; + if (skydist<1) + skydist=gl_skyboxdist.value; + skydist/=16; + + //scale sky sphere and place around view origin. +// qglPushMatrix(); +// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]); +// qglScalef(skydist, skydist, skydist); + +//draw in bulk? this is eeevil +//FIXME: We should use the skybox clipping code and split the sphere into 6 sides. +/*#ifdef Q3SHADERS + if (fa->texinfo->texture->shader) + { //the shader route. + meshbuffer_t mb; + d3d_skyspherecalc(2); + mb.sortkey = 0; + mb.infokey = -1; + mb.dlightbits = 0; + mb.entity = &r_worldentity; + mb.shader = fa->texinfo->texture->shader; + mb.fog = NULL; + mb.mesh = &skymesh; + R_PushMesh(mb.mesh, mb.shader->features); + R_RenderMeshBuffer(&mb, false); + } + else +#endif*/ + { //the boring route. + d3d_skyspherecalc(1); +// qglMatrixMode(GL_TEXTURE); +// qglPushMatrix(); +// qglTranslatef(time*8/128, time*8/128, 0); + + d3d_animateskysphere(time*8/128); + D3D9_DrawSkyMesh(0, solidskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles); + d3d_animateskysphere(time*16/128); + D3D9_DrawSkyMesh(1, alphaskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles); + +// qglDisable(GL_BLEND); +// qglPopMatrix(); +// qglMatrixMode(GL_MODELVIEW); + } +// qglPopMatrix(); + +/* + if (!cls.allow_skyboxes) //allow a little extra fps. + {//Draw the texture chain to only the depth buffer. + if (qglColorMask) + qglColorMask(0,0,0,0); + for (; fa; fa = fa->texturechain) + { + GL_DrawAliasMesh(fa->mesh, 0); + } + if (qglColorMask) + qglColorMask(1,1,1,1); + } + */ +} +#endif /* ============== @@ -801,8 +1186,8 @@ void R_ForceSkyBox (void) } } - -void MakeSkyVec (float s, float t, int axis) +#ifdef RGLQUAKE +void GL_MakeSkyVec (float s, float t, int axis) { vec3_t v, b; int j, k; @@ -842,6 +1227,7 @@ void MakeSkyVec (float s, float t, int axis) qglTexCoord2f (s, t); qglVertex3fv (v); } +#endif /* ============== @@ -849,7 +1235,8 @@ R_DrawSkyBox ============== */ int skytexorder[6] = {0,2,1,3,4,5}; -void R_DrawSkyBox (msurface_t *s) +#ifdef RGLQUAKE +void GL_DrawSkyBox (msurface_t *s) { msurface_t *fa; int i; @@ -895,10 +1282,10 @@ void R_DrawSkyBox (msurface_t *s) GL_Bind (skyboxtex[skytexorder[i]]); qglBegin (GL_QUADS); - MakeSkyVec (skymins[0][i], skymins[1][i], i); - MakeSkyVec (skymins[0][i], skymaxs[1][i], i); - MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); - MakeSkyVec (skymaxs[0][i], skymins[1][i], i); + GL_MakeSkyVec (skymins[0][i], skymins[1][i], i); + GL_MakeSkyVec (skymins[0][i], skymaxs[1][i], i); + GL_MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); + GL_MakeSkyVec (skymaxs[0][i], skymins[1][i], i); qglEnd (); } @@ -916,6 +1303,7 @@ void R_DrawSkyBox (msurface_t *s) qglColorMask(1, 1, 1, 1); } } +#endif @@ -928,12 +1316,12 @@ R_InitSky A sky texture is 256*128, with the right side being a masked overlay ============== */ -void GLR_InitSky (texture_t *mt) +void R_InitSky (texture_t *mt) { int i, j, p; qbyte *src; unsigned trans[128*128]; - unsigned transpix; + unsigned transpix, alphamask; int r, g, b; unsigned *rgba; char name[MAX_QPATH]; @@ -964,7 +1352,7 @@ void GLR_InitSky (texture_t *mt) Q_strlwr(name); solidskytexture = Mod_LoadReplacementTexture(name, NULL, true, false, true); if (!solidskytexture) - solidskytexture = GL_LoadTexture32(name, 128, 128, trans, true, false); + solidskytexture = R_LoadTexture32(name, 128, 128, trans, true, false); /* if (!solidskytexture) solidskytexture = texture_extension_number++; @@ -974,7 +1362,7 @@ void GLR_InitSky (texture_t *mt) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); */ - + alphamask = LittleLong(0x7fffffff); for (i=0 ; i<128 ; i++) for (j=0 ; j<128 ; j++) { @@ -982,14 +1370,14 @@ void GLR_InitSky (texture_t *mt) if (p == 0) trans[(i*128) + j] = transpix; else - trans[(i*128) + j] = d_8to24rgbtable[p]; + trans[(i*128) + j] = d_8to24rgbtable[p] & alphamask; } sprintf(name, "%s_trans", mt->name); Q_strlwr(name); alphaskytexture = Mod_LoadReplacementTexture(name, NULL, true, true, true); if (!alphaskytexture) - alphaskytexture = GL_LoadTexture32(name, 128, 128, trans, true, true); + alphaskytexture = R_LoadTexture32(name, 128, 128, trans, true, true); /* if (!alphaskytexture) alphaskytexture = texture_extension_number++; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index fc95cf4ac..0d4cc5ce5 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -83,7 +83,6 @@ extern PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI; extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI; extern int texture_extension_number; -extern int texture_mode; typedef struct { qboolean tex_env_combine; @@ -158,7 +157,7 @@ extern int glx, gly, glwidth, glheight; void R_TimeRefresh_f (void); texture_t *SWR_TextureAnimation (texture_t *base); -texture_t *GLR_TextureAnimation (texture_t *base); +texture_t *R_TextureAnimation (texture_t *base); #include "particles.h" @@ -226,6 +225,11 @@ void R_IBrokeTheArrays(void); void R_ClearArrays (void); #endif +int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); +extern int image_width, image_height; +int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); +int Mod_LoadBumpmapTexture(char *name, char *subpath); + #if defined(RGLQUAKE) void R_TranslatePlayerSkin (int playernum); void GL_Bind (int texnum); @@ -278,10 +282,10 @@ void GL_DoSwap (void); // gl_warp.c // void GL_SubdivideSurface (msurface_t *fa, float dividesize); -void EmitBothSkyLayers (msurface_t *fa); +void GL_EmitBothSkyLayers (msurface_t *fa); void EmitWaterPolys (msurface_t *fa, float basealpha); void EmitSkyPolys (msurface_t *fa); -void R_DrawSkyChain (msurface_t *s); +void GL_DrawSkyChain (msurface_t *s); void R_ClearSkyBox (void); void R_DrawSkyBox (msurface_t *s); @@ -324,7 +328,7 @@ void R_DrawGroupModel (entity_t *ent); void GLR_MarkLights (dlight_t *light, int bit, mnode_t *node); void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node); void GLR_AnimateLight (void); -void R_RenderDlights (void); +void GLR_RenderDlights (void); int GLR_LightPoint (vec3_t p); void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); @@ -348,11 +352,8 @@ void R_DrawWorld (void); void GL_BuildLightmaps (void); void GL_LoadShaders(void); -int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); -extern int image_width, image_height; -int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); -int Mod_LoadBumpmapTexture(char *name, char *subpath); +#ifndef LMBLOCK_WIDTH #define LMBLOCK_WIDTH 128 #define LMBLOCK_HEIGHT 128 typedef struct glRect_s { @@ -369,6 +370,7 @@ typedef struct { qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage. stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed. } lightmapinfo_t; +#endif //gl_ppl.c void PPL_DrawWorld (void); diff --git a/engine/gl/gltod3d/gl_fakegl.cpp b/engine/gl/gltod3d/gl_fakegl.cpp index 1db6a4e9c..81124b8f4 100644 --- a/engine/gl/gltod3d/gl_fakegl.cpp +++ b/engine/gl/gltod3d/gl_fakegl.cpp @@ -4073,7 +4073,7 @@ extern "C" { rendererinfo_t d3drendererinfo = { "Direct3D", { - "d3d", + "faked3d", "crap" }, QR_OPENGL, @@ -4140,8 +4140,8 @@ rendererinfo_t d3drendererinfo = { GLMod_NowLoadExternal, GLMod_Think, - GLMod_GetTag, - GLMod_TagNumForName, + Mod_GetTag, + Mod_TagNumForName, NULL, D3DVID_Init, diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index cdcc6ae64..be224e620 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -1,9 +1,9 @@ #include "quakedef.h" -#if defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE)) +#if defined(D3DQUAKE) || defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE)) #ifdef RUNTIMELIGHTING -#if defined(RGLQUAKE) +#if defined(RGLQUAKE) || defined(D3DQUAKE) extern model_t *lightmodel; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 43b753b40..d6199cedf 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -569,6 +569,12 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us if (!isDedicated && (!qrenderer || qrenderer == -1)) { R_RestartRenderer_f(); + + if (!qrenderer || qrenderer == -1) + { + Sys_Error("No renderer set when map restarted\n"); + return; + } } #endif @@ -766,8 +772,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us } sv.state = ss_loading; sv.worldmodel = Mod_ForName (sv.modelname, true); - if (sv.worldmodel->needload) - Sys_Error("%s is missing\n", sv.modelname); + if (!sv.worldmodel || sv.worldmodel->needload) + Sys_Error("%s is missing or corrupt\n", sv.modelname); if (sv.worldmodel->type != mod_brush && sv.worldmodel->type != mod_heightmap) Sys_Error("%s is not a bsp model\n", sv.modelname); sv.state = ss_dead; diff --git a/engine/sw/r_sprite.c b/engine/sw/r_sprite.c index f9a7e5962..d38b0ad8e 100644 --- a/engine/sw/r_sprite.c +++ b/engine/sw/r_sprite.c @@ -233,13 +233,16 @@ void R_SetupAndDrawSprite () R_GetSpriteframe ================ */ -mspriteframe_t *R_GetSpriteframe (msprite_t *psprite) +/* +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) { + msprite_t *psprite; mspritegroup_t *pspritegroup; mspriteframe_t *pspriteframe; int i, numframes, frame; float *pintervals, fullinterval, targettime, time; + psprite = currententity->model->cache.data; frame = currententity->frame; if ((frame >= psprite->numframes) || (frame < 0)) @@ -276,7 +279,7 @@ mspriteframe_t *R_GetSpriteframe (msprite_t *psprite) return pspriteframe; } - +*/ /* ================ @@ -292,7 +295,7 @@ void R_DrawSprite (void) psprite = currententity->model->cache.data; - r_spritedesc.pspriteframe = R_GetSpriteframe (psprite); + r_spritedesc.pspriteframe = R_GetSpriteFrame (currententity); sprite_width = r_spritedesc.pspriteframe->width; sprite_height = r_spritedesc.pspriteframe->height;