static void parse_script (script_t *script) { int cmd; while (Script_GetToken (script, true)) { if (strcasecmp ("$LOAD", script->token->str) == 0) { Script_GetToken (script, false); load_image (script->token->str); continue; } if (strcasecmp ("$DEST", script->token->str) == 0) { Script_GetToken (script, false); dstring_copystr (&destfile, script->token->str); continue; } if (strcasecmp ("$SINGLEDEST", script->token->str) == 0) { Script_GetToken (script, false); dstring_copystr (&destfile, script->token->str); savesingle = true; continue; } if (!lumpname) lumpname = dstring_newstr (); dstring_copystr (lumpname, script->token->str); Script_GetToken (script, false); for (cmd = 0; commands[cmd].name; cmd++) { if (!strcasecmp (script->token->str, commands[cmd].name)) { commands[cmd].func (script); break; } } if (!commands[cmd].name) Sys_Error ("Unrecognized token '%s' at line %i", script->token->str, script->line); //grabbed++; if (savesingle) write_file (); else write_lump (TYP_LUMPY + cmd); } }
void _Material_AddSkin(Material_t *mCurrentMaterial, MaterialFunctionContext_t mftContext, char *cArg) { // Proceed to the next line. Script_GetToken(true); if (cToken[0] == '{') { while (true) { if (!Script_GetToken(true)) { Con_Warning("End of field without closing brace! (%s) (%i)\n", mCurrentMaterial->cPath, iScriptLine); break; } material_currentcontext = MATERIAL_FUNCTION_SKIN; if (cToken[0] == '}') { mCurrentMaterial->iSkins++; break; } // '$' declares that the following is a function. else if (cToken[0] == SCRIPT_SYMBOL_FUNCTION) Material_CheckFunctions(mCurrentMaterial); // '%' declares that the following is a variable. else if (cToken[0] == SCRIPT_SYMBOL_VARIABLE) { /* TODO: * Collect variable * Check it against internal solutions * Otherwise declare it, figure out where/how it's used */ } else { Con_Warning("Invalid field! (%s) (%i)\n", mCurrentMaterial->cPath, iScriptLine); break; } } } else Con_Warning("Invalid skin, no opening brace! (%s) (%i)\n", mCurrentMaterial->cPath, iScriptLine); }
static plitem_t * convert_to_game_dict (script_t *script) { plitem_t *game = PL_NewDictionary (); plitem_t *item; plitem_t *list; int skill; int i; // savegame comment (ignored) Script_GetToken (script, 1); PL_D_AddObject (game, "comment", PL_NewString (script->token->str)); // spawn_parms item = PL_NewArray (); for (i = 0; i < NUM_SPAWN_PARMS; i++) { Script_GetToken (script, 1); PL_A_AddObject (item, PL_NewString (script->token->str)); } PL_D_AddObject (game, "spawn_parms", item); // this silliness is so we can load 1.06 save files, which have float skill // values Script_GetToken (script, 1); skill = (int) (atof (script->token->str) + 0.1); PL_D_AddObject (game, "current_skill", PL_NewString (va ("%d", skill))); Script_GetToken (script, 1); PL_D_AddObject (game, "name", PL_NewString (script->token->str)); Script_GetToken (script, 1); PL_D_AddObject (game, "time", PL_NewString (script->token->str)); // load the light styles item = PL_NewArray (); for (i = 0; i < MAX_LIGHTSTYLES; i++) { Script_GetToken (script, 1); PL_A_AddObject (item, PL_NewString (script->token->str)); //char *s; //s = Hunk_Alloc (strlen (script->token->str) + 1); //strcpy (s, script->token->str); //sv.lightstyles[i] = s; } PL_D_AddObject (game, "lightstyles", item); // load the edicts out of the savegame file list = ED_ConvertToPlist (&sv_pr_state, script); item = PL_RemoveObjectAtIndex (list, 0); PL_D_AddObject (game, "globals", item); PL_D_AddObject (game, "entities", list); return game; }
void Material_CheckFunctions(Material_t *mNewMaterial) { MaterialKey_t *mKey; // Find the related function. for (mKey = MaterialFunctions; mKey->cKey; mKey++) // Remain case sensitive. if (!Q_strcasecmp(mKey->cKey, cToken + 1)) { /* todo account for texture slots etc */ if ((mKey->mftType != MATERIAL_FUNCTION_UNIVERSAL) && (material_currentcontext != mKey->mftType)) Sys_Error("Attempted to call a function within the wrong context! (%s) (%s) (%i)\n", cToken, mNewMaterial->cPath, iScriptLine); Script_GetToken(false); mKey->Function(mNewMaterial, material_currentcontext, cToken); return; } Con_Warning("Unknown function! (%s) (%s) (%i)\n", cToken, mNewMaterial->cPath, iScriptLine); }
static void Host_Loadgame_f (void) { dstring_t *name = 0; QFile *f; char *mapname = 0; script_t *script = 0; plitem_t *game = 0; plitem_t *list; plitem_t *item; char *script_data = 0; int i; int entnum; int count; int version; float spawn_parms[NUM_SPAWN_PARMS]; if (cmd_source != src_command) goto end; if (Cmd_Argc () != 2) { Sys_Printf ("load <savename> : load a game\n"); goto end; } cls.demonum = -1; // stop demo loop in case this fails name = dstring_newstr (); dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); QFS_DefaultExtension (name, ".sav"); cl.loading = true; CL_UpdateScreen (cl.time); Sys_Printf ("Loading game from %s...\n", name->str); f = QFS_Open (name->str, "rz"); if (!f) { Sys_Printf ("ERROR: couldn't open.\n"); goto end; } script_data = malloc (Qfilesize (f) + 1); i = Qread (f, script_data, Qfilesize (f)); script_data[i] = 0; Qclose (f); script = Script_New (); script->single = ""; // disable {}()': lexing Script_Start (script, name->str, script_data); Script_GetToken (script, 1); if (strequal (script->token->str, PACKAGE_NAME)) { if (!Script_TokenAvailable (script, 1)) { Sys_Printf ("Unexpected EOF reading %s\n", name->str); goto end; } game = PL_GetPropertyList (script->p); } else { sscanf (script->token->str, "%i", &version); if (version != SAVEGAME_VERSION) { Sys_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); goto end; } game = convert_to_game_dict (script); } item = PL_ObjectForKey (game, "spawn_parms"); for (i = 0; i < NUM_SPAWN_PARMS; i++) { if (i >= PL_A_NumObjects (item)) break; spawn_parms[i] = atof (PL_String (PL_ObjectAtIndex (item, i))); } current_skill = atoi (PL_String (PL_ObjectForKey (game, "current_skill"))); Cvar_SetValue (skill, current_skill); mapname = strdup (PL_String (PL_ObjectForKey (game, "name"))); CL_Disconnect_f (); SV_SpawnServer (mapname); if (!sv.active) { Sys_Printf ("Couldn't load map %s\n", mapname); goto end; } sv.paused = true; // pause until all clients connect sv.loadgame = true; list = PL_ObjectForKey (game, "lightstyles"); for (i = 0; i < MAX_LIGHTSTYLES; i++) { const char *style; char *str; if (i >= PL_A_NumObjects (list)) break; item = PL_ObjectAtIndex (list, i); style = PL_String (item); sv.lightstyles[i] = str = Hunk_Alloc (strlen (style) + 1); strcpy (str, style); } ED_InitGlobals (&sv_pr_state, PL_ObjectForKey (game, "globals")); list = PL_ObjectForKey (game, "entities"); entnum = 0; count = PL_A_NumObjects (list); if (count > sv.max_edicts) Host_Error ("too many entities in saved game. adjust max_edicts\n"); for (entnum = 0; entnum < count; entnum++) { plitem_t *entity = PL_ObjectAtIndex (list, entnum); edict_t *ent = EDICT_NUM (&sv_pr_state, entnum); memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4); ent->free = false; ED_InitEntity (&sv_pr_state, entity, ent); // link it into the bsp tree if (!ent->free) SV_LinkEdict (ent, false); } sv.num_edicts = entnum; sv.time = atof (PL_String (PL_ObjectForKey (game, "time"))); for (i = 0; i < NUM_SPAWN_PARMS; i++) svs.clients->spawn_parms[i] = spawn_parms[i]; if (cls.state != ca_dedicated) { CL_EstablishConnection ("local"); Host_Reconnect_f (); } end: if (game) PL_Free (game); if (mapname) free (mapname); if (script) Script_Delete (script); if (script_data) free (script_data); if (name) dstring_delete (name); }
/* Loads and parses material. Returns false on complete failure. */ Material_t *Material_Load(const char *ccPath) { Material_t *mNewMaterial; void *cData; char cPath[PLATFORM_MAX_PATH], cMaterialName[64] = { 0 }; // Ensure that the given material names are correct! if (ccPath[0] == ' ') Sys_Error("Invalid material path! (%s)\n", ccPath); if (!material_initialized) { Con_Warning("Attempted to load material, before initialization! (%s)\n", ccPath); return NULL; } // Update the given path with the base path plus extension. sprintf(cPath, "%s%s.material", g_state.cMaterialPath, ccPath); // Check if it's been cached already... mNewMaterial = Material_GetByPath(cPath); if(mNewMaterial) return mNewMaterial; cData = COM_LoadHeapFile(cPath); if(!cData) { Con_Warning("Failed to load material! (%s) (%s)\n", cPath, ccPath); return NULL; } Script_StartTokenParsing((char*)cData); if(!Script_GetToken(true)) { Con_Warning("Failed to get initial token! (%s) (%i)\n",ccPath,iScriptLine); return NULL; } else if (cToken[0] != '{') { if (!strcmp(cToken, "material_version")) { Script_GetToken(false); } else // Probably a name... { // Copy over the given name. strncpy(cMaterialName, cToken, sizeof(cMaterialName)); if (cMaterialName[0] == ' ') Sys_Error("Invalid material name!\n"); // Check if it's been cached already... mNewMaterial = Material_GetByName(cMaterialName); if (mNewMaterial) { Con_Warning("Attempted to load duplicate material! (%s) (%s) vs (%s) (%s)\n", ccPath, cMaterialName, mNewMaterial->cPath, mNewMaterial->cName); free(cData); return mNewMaterial; } } Script_GetToken(true); if (cToken[0] != '{') { Con_Warning("Missing '{'! (%s) (%i)\n", ccPath, iScriptLine); goto MATERIAL_LOAD_ERROR; } } // Assume that the material hasn't been cached yet, so allocate a new copy of one. mNewMaterial = Material_Allocate(); if (!mNewMaterial) { Con_Warning("Failed to allocate material! (%s)\n",ccPath); goto MATERIAL_LOAD_ERROR; } if (cMaterialName[0]) strncpy(mNewMaterial->cName, cMaterialName, sizeof(mNewMaterial->cName)); else { char cIn[PLATFORM_MAX_PATH]; strncpy(cIn, ccPath, sizeof(cIn)); // Otherwise just use the filename. ExtractFileBase(cIn, mNewMaterial->cName); } strncpy(mNewMaterial->cPath, ccPath, sizeof(mNewMaterial->cPath)); for (;;) { if(!Script_GetToken(true)) { Con_Warning("End of field without closing brace! (%s) (%i)\n",ccPath,iScriptLine); goto MATERIAL_LOAD_ERROR; } material_currentcontext = MATERIAL_FUNCTION_MATERIAL; // End if (cToken[0] == '}') { // TODO: Load material data at the END! return mNewMaterial; } // Start else if (cToken[0] == SCRIPT_SYMBOL_FUNCTION) Material_CheckFunctions(mNewMaterial); } MATERIAL_LOAD_ERROR: free(cData); return NULL; }
void _Material_AddTexture(Material_t *material, MaterialFunctionContext_t mftContext, char *cArg) { char cTexturePath[MAX_QPATH]; MaterialSkin_t *msSkin = Material_GetSkin(material, material->iSkins); if (!msSkin) Sys_Error("Failed to get skin!\n"); #ifdef _MSC_VER #pragma warning(suppress: 6011) #endif msSkin->mtTexture[msSkin->uiTextures].EnvironmentMode = VIDEO_TEXTURE_MODE_MODULATE; msSkin->mtTexture[msSkin->uiTextures].matrixmod = false; msSkin->mtTexture[msSkin->uiTextures].fRotate = 0; msSkin->mtTexture[msSkin->uiTextures].mttType = MATERIAL_TEXTURE_DIFFUSE; msSkin->mtTexture[msSkin->uiTextures].vScroll[0] = 0; msSkin->mtTexture[msSkin->uiTextures].vScroll[1] = 0; strcpy(cTexturePath, cArg); // Get following line. Script_GetToken(true); if (cToken[0] == '{') { for (;;) { if (!Script_GetToken(true)) { Con_Warning("End of field without closing brace! (%s) (%i)\n", material->cPath, iScriptLine); break; } // Update state. material_currentcontext = MATERIAL_FUNCTION_TEXTURE; if (cToken[0] == '}') { msSkin->mtTexture[msSkin->uiTextures].gMap = Material_LoadTexture(material, msSkin, cTexturePath); msSkin->uiTextures++; break; } // '$' declares that the following is a function. else if (cToken[0] == SCRIPT_SYMBOL_FUNCTION) Material_CheckFunctions(material); // '%' declares that the following is a variable. else if (cToken[0] == SCRIPT_SYMBOL_VARIABLE) { /* TODO: * Collect variable * Check it against internal solutions * Otherwise declare it, figure out where/how it's used */ } else { Con_Warning("Invalid field! (%s) (%i)\n", material->cPath, iScriptLine); break; } } } else #if 1 Con_Warning("Invalid skin, no opening brace! (%s) (%i)\n", material->cPath, iScriptLine); #else { msSkin->mtTexture[msSkin->uiTextures].gMap = Material_LoadTexture(mCurrentMaterial, msSkin, cTexturePath); msSkin->uiTextures++; Script_GetToken(true); } #endif }