/* =============== UI_PlayerInfo_SetWeapon =============== */ static void UI_PlayerInfo_SetWeapon( playerInfo_t *pi, weapon_t weaponNum ) { gitem_t * item; char path[MAX_QPATH]; pi->currentWeapon = weaponNum; tryagain: pi->realWeapon = weaponNum; pi->weaponModel = 0; pi->barrelModel = 0; pi->flashModel = 0; if ( weaponNum == WP_NONE ) { return; } for ( item = bg_itemlist + 1; item->classname ; item++ ) { if ( item->giType != IT_WEAPON ) { continue; } if ( item->giTag == weaponNum ) { break; } } if ( item->classname ) { pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); } if( pi->weaponModel == 0 ) { if( weaponNum == WP_MACHINEGUN ) { weaponNum = WP_NONE; goto tryagain; } weaponNum = WP_MACHINEGUN; goto tryagain; } if ( weaponNum == WP_MACHINEGUN || weaponNum == WP_GAUNTLET || weaponNum == WP_BFG ) { strcpy( path, item->world_model[0] ); COM_StripExtension(path, path, sizeof(path)); strcat( path, "_barrel.md3" ); pi->barrelModel = trap_R_RegisterModel( path ); } strcpy( path, item->world_model[0] ); COM_StripExtension(path, path, sizeof(path)); strcat( path, "_flash.md3" ); pi->flashModel = trap_R_RegisterModel( path ); switch( weaponNum ) { case WP_GAUNTLET: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_MACHINEGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_SHOTGUN: MAKERGB( pi->flashDlightColor, 1, 1, 0 ); break; case WP_GRENADE_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); break; case WP_ROCKET_LAUNCHER: MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); break; case WP_LIGHTNING: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_RAILGUN: MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); break; case WP_PLASMAGUN: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; case WP_BFG: MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); break; case WP_GRAPPLING_HOOK: MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); break; default: MAKERGB( pi->flashDlightColor, 1, 1, 1 ); break; } }
/* =============== VM_LoadSymbols =============== */ void VM_LoadSymbols( vm_t *vm ) { union { char *c; void *v; } mapfile; char *text_p, *token; char name[MAX_QPATH]; char symbols[MAX_QPATH]; vmSymbol_t **prev, *sym; int count; int value; int chars; int segment; int numInstructions; // don't load symbols if not developer if ( !com_developer->integer ) { return; } COM_StripExtension(vm->name, name, sizeof(name)); Com_sprintf( symbols, sizeof( symbols ), "vm/%s.map", name ); FS_ReadFile( symbols, &mapfile.v ); if ( !mapfile.c ) { Com_Printf( "Couldn't load symbol file: %s\n", symbols ); return; } numInstructions = vm->instructionCount; // parse the symbols text_p = mapfile.c; prev = &vm->symbols; count = 0; while ( 1 ) { token = COM_Parse( &text_p ); if ( !token[0] ) { break; } segment = ParseHex( token ); if ( segment ) { COM_Parse( &text_p ); COM_Parse( &text_p ); continue; // only load code segment values } token = COM_Parse( &text_p ); if ( !token[0] ) { Com_Printf( "WARNING: incomplete line at end of file\n" ); break; } value = ParseHex( token ); token = COM_Parse( &text_p ); if ( !token[0] ) { Com_Printf( "WARNING: incomplete line at end of file\n" ); break; } chars = strlen( token ); sym = Hunk_Alloc( sizeof( *sym ) + chars, h_high ); *prev = sym; prev = &sym->next; sym->next = NULL; // convert value from an instruction number to a code offset if ( value >= 0 && value < numInstructions ) { value = vm->instructionPointers[value]; } sym->symValue = value; Q_strncpyz( sym->symName, token, chars + 1 ); count++; } vm->numSymbols = count; Com_Printf( "%i symbols parsed from %s\n", count, symbols ); FS_FreeFile( mapfile.v ); }
/* ================= RE_LoadWorldMap Called directly from cgame ================= */ void RE_LoadWorldMap_Actual( const char *name, world_t &worldData, int index ) { dheader_t *header; byte *buffer = NULL; qboolean loadedSubBSP = qfalse; if ( tr.worldMapLoaded && !index ) { Com_Error( ERR_DROP, "ERROR: attempted to redundantly load world map\n" ); } // set default sun direction to be used if it isn't // overridden by a shader if (!index) { skyboxportal = 0; tr.sunDirection[0] = 0.45f; tr.sunDirection[1] = 0.3f; tr.sunDirection[2] = 0.9f; VectorNormalize( tr.sunDirection ); tr.worldMapLoaded = qtrue; // clear tr.world so if the level fails to load, the next // try will not look at the partially loaded version tr.world = NULL; } // check for cached disk file from the server first... // if (ri.gpvCachedMapDiskImage()) { if (!strcmp(name, ri.gsCachedMapDiskImage())) { // we should always get here, if inside the first IF... // buffer = (byte *)ri.gpvCachedMapDiskImage(); } else { // this should never happen (ie renderer loading a different map than the server), but just in case... // // assert(0); // Z_Free(gpvCachedMapDiskImage); // gpvCachedMapDiskImage = NULL; //rww - this is a valid possibility now because of sub-bsp loading.\ //it's alright, just keep the current cache loadedSubBSP = qtrue; } } tr.worldDir[0] = '\0'; if (buffer == NULL) { // still needs loading... // ri.FS_ReadFile( name, (void **)&buffer ); if ( !buffer ) { Com_Error (ERR_DROP, "RE_LoadWorldMap: %s not found", name); } } memset( &worldData, 0, sizeof( worldData ) ); Q_strncpyz( worldData.name, name, sizeof( worldData.name ) ); Q_strncpyz( tr.worldDir, name, sizeof( tr.worldDir ) ); Q_strncpyz( worldData.baseName, COM_SkipPath( worldData.name ), sizeof( worldData.name ) ); COM_StripExtension( worldData.baseName, worldData.baseName, sizeof( worldData.baseName ) ); COM_StripExtension( tr.worldDir, tr.worldDir, sizeof( tr.worldDir ) ); c_gridVerts = 0; header = (dheader_t *)buffer; fileBase = (byte *)header; header->version = LittleLong (header->version); if ( header->version != BSP_VERSION ) { Com_Error (ERR_DROP, "RE_LoadWorldMap: %s has wrong version number (%i should be %i)", name, header->version, BSP_VERSION); } // swap all the lumps for (size_t i=0 ; i<sizeof(dheader_t)/4 ; i++) { ((int *)header)[i] = LittleLong ( ((int *)header)[i]); } // load into heap R_LoadShaders( &header->lumps[LUMP_SHADERS], worldData ); R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS], name, worldData ); R_LoadPlanes (&header->lumps[LUMP_PLANES], worldData); R_LoadFogs( &header->lumps[LUMP_FOGS], &header->lumps[LUMP_BRUSHES], &header->lumps[LUMP_BRUSHSIDES], worldData, index ); R_LoadSurfaces( &header->lumps[LUMP_SURFACES], &header->lumps[LUMP_DRAWVERTS], &header->lumps[LUMP_DRAWINDEXES], worldData, index ); R_LoadMarksurfaces (&header->lumps[LUMP_LEAFSURFACES], worldData); R_LoadNodesAndLeafs (&header->lumps[LUMP_NODES], &header->lumps[LUMP_LEAFS], worldData); R_LoadSubmodels (&header->lumps[LUMP_MODELS], worldData, index); R_LoadVisibility( &header->lumps[LUMP_VISIBILITY], worldData ); if (!index) { R_LoadEntities( &header->lumps[LUMP_ENTITIES], worldData ); R_LoadLightGrid( &header->lumps[LUMP_LIGHTGRID], worldData ); R_LoadLightGridArray( &header->lumps[LUMP_LIGHTARRAY], worldData ); // only set tr.world now that we know the entire level has loaded properly tr.world = &worldData; } if (ri.gpvCachedMapDiskImage() && !loadedSubBSP) { // For the moment, I'm going to keep this disk image around in case we need it to respawn. // No problem for memory, since it'll only be a NZ ptr if we're not low on physical memory // ( ie we've got > 96MB). // // So don't do this... // // Z_Free( gpvCachedMapDiskImage ); // gpvCachedMapDiskImage = NULL; } else { ri.FS_FreeFile( buffer ); } }
static void R_LoadLightmaps( lump_t *l, const char *psMapName, world_t &worldData ) { byte *buf, *buf_p; int len; byte image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4]; int i, j; float maxIntensity = 0; double sumIntensity = 0; int count; if (&worldData == &s_worldData) { tr.numLightmaps = 0; } len = l->filelen; if ( !len ) { return; } buf = fileBase + l->fileofs; // we are about to upload textures //R_SyncRenderThread(); // create all the lightmaps worldData.startLightMapIndex = tr.numLightmaps; count = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3); tr.numLightmaps += count; // if we are in r_vertexLight mode, we don't need the lightmaps at all if ( r_vertexLight->integer ) { return; } char sMapName[MAX_QPATH]; COM_StripExtension(psMapName,sMapName, sizeof(sMapName)); for ( i = 0 ; i < count ; i++ ) { // expand the 24 bit on-disk to 32 bit buf_p = buf + i * LIGHTMAP_SIZE*LIGHTMAP_SIZE * 3; if ( r_lightmap->integer == 2 ) { // color code by intensity as development tool (FIXME: check range) for ( j = 0; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) { float r = buf_p[j*3+0]; float g = buf_p[j*3+1]; float b = buf_p[j*3+2]; float intensity; float out[3] = {0.0f, 0.0f, 0.0f}; intensity = 0.33f * r + 0.685f * g + 0.063f * b; if ( intensity > 255 ) intensity = 1.0f; else intensity /= 255.0f; if ( intensity > maxIntensity ) maxIntensity = intensity; HSVtoRGB( intensity, 1.00, 0.50, out ); image[j*4+0] = out[0] * 255; image[j*4+1] = out[1] * 255; image[j*4+2] = out[2] * 255; image[j*4+3] = 255; sumIntensity += intensity; } } else { for ( j = 0 ; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) { R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] ); image[j*4+3] = 255; } } tr.lightmaps[worldData.startLightMapIndex+i] = R_CreateImage( va("$%s/lightmap%d",sMapName,worldData.startLightMapIndex+i), image, LIGHTMAP_SIZE, LIGHTMAP_SIZE, GL_RGBA, qfalse, qfalse, r_ext_compressed_lightmaps->integer, GL_CLAMP ); } if ( r_lightmap->integer == 2 ) { ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) ); } }
/*QUAKED script_mover (0.5 0.25 1.0) ? TRIGGERSPAWN SOLID EXPLOSIVEDAMAGEONLY RESURECTABLE COMPASS ALLIED AXIS MOUNTED_GUN Scripted brush entity. A simplified means of moving brushes around based on events. "modelscale" - Scale multiplier (defaults to 1, and scales uniformly) "modelscale_vec" - Set scale per-axis. Overrides "modelscale", so if you have both the "modelscale" is ignored "model2" optional md3 to draw over the solid clip brush "scriptname" name used for scripting purposes (like aiName in AI scripting) "health" optionally make this entity damagable "description" used with health, if the entity is damagable, it draws a healthbar with this description above it. */ void SP_script_mover(gentity_t *ent) { float scale[3] = {1,1,1}; vec3_t scalevec; char tagname[MAX_QPATH]; char* modelname; char* tagent; char cs[MAX_INFO_STRING]; char* s; if (!ent->model) G_Error("script_mover must have a \"model\"\n" ); if (!ent->scriptName) G_Error("script_mover must have a \"scriptname\"\n" ); ent->blocked = script_mover_blocked; // first position at start VectorCopy( ent->s.origin, ent->pos1 ); // VectorCopy( ent->r.currentOrigin, ent->pos1 ); VectorCopy( ent->pos1, ent->pos2 ); // don't go anywhere just yet trap_SetBrushModel( ent, ent->model ); InitMover( ent ); ent->reached = NULL; ent->s.animMovetype = 0; ent->s.density = 0; if (ent->spawnflags & 256) { ent->s.density |= 2; } if (ent->spawnflags & 8) { ent->use = script_mover_use; } if (ent->spawnflags & 16) { ent->s.time2 = 1; } else { ent->s.time2 = 0; } if (ent->spawnflags & 32) { ent->s.teamNum = TEAM_ALLIES; } else if (ent->spawnflags & 64) { ent->s.teamNum = TEAM_AXIS; } else { ent->s.teamNum = TEAM_FREE; } if (ent->spawnflags & 1) { ent->use = script_mover_use; trap_UnlinkEntity(ent); // make sure it's not visible return; } G_SetAngle (ent, ent->s.angles); G_SpawnInt( "health", "0", &ent->health ); if(ent->health) { ent->takedamage = qtrue; ent->count = ent->health; // client needs to know about it as well ent->s.effect1Time = ent->count; ent->s.dl_intensity = 255; if( G_SpawnString( "description", "", &s ) ) { trap_GetConfigstring( CS_SCRIPT_MOVER_NAMES, cs, sizeof(cs) ); Info_SetValueForKey( cs, va("%i",ent-g_entities), s ); trap_SetConfigstring( CS_SCRIPT_MOVER_NAMES, cs ); } } else { ent->count = 0; } ent->die = script_mover_die; // look for general scaling if(G_SpawnFloat( "modelscale", "1", &scale[0])) { scale[2] = scale[1] = scale[0]; } if(G_SpawnString( "model2", "", &modelname ) ) { COM_StripExtension( modelname, tagname ); Q_strcat( tagname, MAX_QPATH, ".tag" ); ent->tagNumber = trap_LoadTag( tagname ); /* if( !(ent->tagNumber = trap_LoadTag( tagname )) ) { Com_Error( ERR_DROP, "Failed to load Tag File (%s)\n", tagname ); }*/ } // look for axis specific scaling if(G_SpawnVector("modelscale_vec", "1 1 1", &scalevec[0])) { VectorCopy(scalevec, scale); } if(scale[0] != 1 || scale[1] != 1 || scale[2] != 1) { ent->s.density |= 1; // scale is stored in 'angles2' VectorCopy(scale, ent->s.angles2); } if (ent->spawnflags & 128) { ent->s.density |= 4; ent->waterlevel = 0; if( G_SpawnString( "gun", "", &modelname ) ) { if( !Q_stricmp( modelname, "browning" ) ) { ent->s.density |= 8; } } G_SpawnString("tagent", "", &tagent); Q_strncpyz( ent->tagBuffer, tagent, 16 ); ent->s.powerups = -1; } ent->think = script_mover_spawn; ent->nextthink = level.time + FRAMETIME; }