public static void UpdateUsing(CSTranslationContext context, VMVariableScope scope) { var csClass = context.CurrentClass; if (!csClass.UseLocals && (scope == VMVariableScope.Local || scope == VMVariableScope.LocalByTemp)) { csClass.UseLocals = true; } if (!csClass.UseTemps && (scope == VMVariableScope.Temps || scope == VMVariableScope.TempByTemp || scope == VMVariableScope.DynSpriteFlagForTempOfStackObject || scope == VMVariableScope.LocalByTemp || scope == VMVariableScope.MyPersonDataByTemp || scope == VMVariableScope.RoomByTemp0 || scope == VMVariableScope.StackObjectAttributeByTemp || scope == VMVariableScope.StackObjectMotiveByTemp || scope == VMVariableScope.StackObjectPersonDataByTemp || scope == VMVariableScope.StackObjectTemp || scope == VMVariableScope.TempXL || scope == VMVariableScope.JobData || scope == VMVariableScope.MyList || scope == VMVariableScope.StackObjectList)) { csClass.UseTemps = true; } if (!csClass.UseParams && (scope == VMVariableScope.Parameters || scope == VMVariableScope.StackObjectAttributeByParameter)) { csClass.UseParams = true; } }
public void InitInfo(CSTranslationContext ctx) { var info = GetInfoFromId(ctx, Instruction.Opcode); _CanYield = info.Item1; FuncFile = info.Item2; FuncClass = info.Item3; FuncArgs = info.Item4; }
private static Tuple <bool, string, string, int> GetInfoFromId(CSTranslationContext ctx, ushort call) { SimAnticsModule module; CSTranslationContext ctx2; //find the bhav. if (call < 4096) { //global module = ctx.GlobalModule; ctx2 = ctx.GlobalContext as CSTranslationContext; } else if (call < 8192) { //local (can only be us) module = null; ctx2 = null; } else { //semiglobal module = ctx.SemiGlobalModule; ctx2 = ctx.SemiGlobalContext as CSTranslationContext; } if (ctx2 != null) { //in previously compiled context StructuredBHAV newBHAV; if (ctx2.BHAVInfo.TryGetValue(call, out newBHAV)) { return(new Tuple <bool, string, string, int>(newBHAV.Yields, ctx2.NamespaceName, CSTranslationContext.FormatName(newBHAV.Source.ChunkLabel) + "_" + newBHAV.Source.ChunkID, Math.Max(4, (int)newBHAV.Source.Args))); } return(new Tuple <bool, string, string, int>(true, null, null, 4)); } if (module != null) { //in compiled module var func = module.GetFunction(call); if (func == null) { return(new Tuple <bool, string, string, int>(true, null, null, 4)); } return(new Tuple <bool, string, string, int>(func is IBHAV, module.GetType().Namespace, func.GetType().Name, (func as IInlineBHAV)?.ArgCount ?? 4)); } else { StructuredBHAV newBHAV; if (ctx.BHAVInfo.TryGetValue(call, out newBHAV)) { return(new Tuple <bool, string, string, int>(newBHAV.Yields, null, CSTranslationContext.FormatName(newBHAV.Source.ChunkLabel) + "_" + newBHAV.Source.ChunkID, Math.Max(4, (int)newBHAV.Source.Args))); } return(new Tuple <bool, string, string, int>(true, null, null, 4)); } }
public static string GetConstant(CSTranslationContext context, VMVariableScope scope, short data) { switch (scope) { case VMVariableScope.Literal: return(data.ToString()); case VMVariableScope.Tuning: return(GetTuningVariable(context, (ushort)data).ToString()); } throw new Exception("Scope " + scope.ToString() + " not supported as Constant."); }
public RoslynSimanticsModule(RoslynSimanticsContext context, GameIffResource file) { Context = context; File = file; if (file is GameGlobalResource) { if (file.MainIff.Filename == "global.iff") { IsGlobal = true; } else { IsSemiGlobal = true; } } Name = CSTranslationContext.FormatName(File.MainIff.Filename.Replace(".iff", "")); FilePath = Path.Combine(Context.CacheDirectory, Name); }
public RoslynSimanticsModule GetModuleFor(GameIffResource res) { var source = res.MainIff; var name = CSTranslationContext.FormatName(source.Filename.Substring(0, source.Filename.Length - 4)); RoslynSimanticsModule result; lock (FormattedNameToRoslynModule) { if (FormattedNameToRoslynModule.TryGetValue(name, out result)) { return(result); } else { //try to create one! result = new RoslynSimanticsModule(Context, res); FormattedNameToRoslynModule[name] = result; return(result); } } }
public SimAnticsModule GetModuleFor(IffFile source) { if (source.CachedJITModule != null) { return((SimAnticsModule)source.CachedJITModule); } var name = CSTranslationContext.FormatName(source.Filename.Substring(0, source.Filename.Length - 4)); SimAnticsModule result; if (FormattedNameToModule.TryGetValue(name, out result)) { //TODO: checksum if (!result.Inited) { result.Init(); } source.CachedJITModule = result; return(result); } return(null); }
public void ConversionAction() { int i = 0; while (i++ < 1) { var translator = new CSTranslator(); var globalRes = Content.Content.Get().WorldObjectGlobals.Get("global").Resource; var iff = globalRes.MainIff; iff.Filename = "global.iff"; translator.Context.GlobalRes = globalRes; var globalText = translator.TranslateIff(iff); using (var file = System.IO.File.Open(Path.Combine(DestPath, "Global.cs"), System.IO.FileMode.Create)) { using (var writer = new System.IO.StreamWriter(file)) { writer.Write(globalText); } } if (Abort) { break; } var globalContext = (CSTranslationContext)translator.Context; var compiledSG = new Dictionary <GameGlobalResource, CSTranslationContext>(); var objs = Content.Content.Get().WorldObjects.Entries.Where(x => User || (x.Value.Source != GameObjectSource.User)).ToList(); var fileComplete = new HashSet <string>(); var objPct = 0; foreach (var obj in objs) { var r = obj.Value; if (!fileComplete.Contains(r.FileName)) { Invoke(new Action(() => { AOTProgress.Value = 10 + (objPct * 90) / objs.Count; })); fileComplete.Add(r.FileName); var objRes = r.Get(); CSTranslationContext sg = null; if (objRes.Resource.SemiGlobal != null) { if (!compiledSG.TryGetValue(objRes.Resource.SemiGlobal, out sg)) { //compile semiglobals translator = new CSTranslator(); var sgIff = objRes.Resource.SemiGlobal.MainIff; translator.Context.ObjectRes = objRes.Resource; //pass this in as occasionally *local* tuning constants are used in *semiglobal* functions. translator.Context.GlobalRes = globalRes; translator.Context.SemiGlobalRes = objRes.Resource.SemiGlobal; translator.Context.GlobalContext = globalContext; Invoke(new Action(() => { AOTStatus.Text = $"Translating Semi-Global {sgIff.Filename}"; })); var semiglobalText = translator.TranslateIff(sgIff); using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create)) { using (var writer = new System.IO.StreamWriter(file)) { writer.Write(semiglobalText); } } sg = (CSTranslationContext)translator.Context; compiledSG[objRes.Resource.SemiGlobal] = sg; } } translator = new CSTranslator(); var objIff = objRes.Resource.MainIff; translator.Context.GlobalRes = globalRes; translator.Context.SemiGlobalRes = objRes.Resource.SemiGlobal; translator.Context.ObjectRes = objRes.Resource; translator.Context.GlobalContext = globalContext; translator.Context.SemiGlobalContext = sg; Invoke(new Action(() => { AOTStatus.Text = $"Translating {objIff.Filename}"; })); var objText = translator.TranslateIff(objIff); using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create)) { using (var writer = new System.IO.StreamWriter(file)) { writer.Write(objText); } } } objPct++; } if (!Abort) { Invoke(new Action(() => { AOTStatus.Text = $"Completed! {objs.Count} objects converted."; AOTProgress.Value = 100; })); } } if (Abort) { Invoke(new Action(() => { AOTStatus.Text = "Aborted."; })); } Invoke(new Action(() => { AOTToggle.Text = "Begin"; AOTToggle.Enabled = true; })); Abort = false; ConversionThread = null; }
public static string SetStatement(CSTranslationContext context, VMVariableScope scope, short data, string op, string value, bool big) { UpdateUsing(context, scope); if (big && !IsBig(scope)) { value = $"(short)({value})"; } if (ScopeMutable(scope)) { //the GetVariable version is mutable, meaning we can use +=, %= etc. var exp = GetExpression(context, scope, data, big); return($"{exp} {op} {value};"); } else { if (op != "=") { op = op.Substring(0, 1); var exp = GetExpression(context, scope, data, big); value = $"(short)({exp} {op} {value})"; //eg. "x[0] += 1" becomes "x[0] = x[0] + 1"; } switch (scope) { case VMVariableScope.MyObjectAttributes: //0 return($"context.Caller.SetAttribute({(ushort)data}, {value});"); case VMVariableScope.StackObjectAttributes: //1 return($"context.StackObject.SetAttribute({(ushort)data}, {value});"); case VMVariableScope.TargetObjectAttributes: //2 throw new Exception("Target Object is Deprecated!"); case VMVariableScope.MyObject: //3 return($"context.Caller.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});"); case VMVariableScope.StackObject: //4 return($"context.StackObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});"); case VMVariableScope.TargetObject: //5 throw new Exception("Target Object is Deprecated!"); case VMVariableScope.Global: //6 return($"context.VM.SetGlobalValue({(ushort)data}, {value});"); case VMVariableScope.Literal: //7 /** Huh? **/ return($""); case VMVariableScope.TreeAdRange: //12 return($""); //can't set this! case VMVariableScope.StackObjectTemp: //13 break; case VMVariableScope.MyMotives: //14 return($"((VMAvatar)context.Caller).SetMotiveData({EnumValueName((VMMotive)data)}, {value});"); case VMVariableScope.StackObjectMotives: //15 return($"(context.StackObject as VMAvatar)?.SetMotiveData({EnumValueName((VMMotive)data)}, {value});"); case VMVariableScope.StackObjectSlot: //16 return($"/* attempting to assign stack object slot? */"); //can't set this! //throw new Exception("Not implemented..."); case VMVariableScope.StackObjectMotiveByTemp: //17 return($"((VMAvatar)context.StackObject).SetMotiveData((VMMotive)temps[{data}], {value});"); case VMVariableScope.MyPersonData: //18 return($"((VMAvatar)context.Caller).SetPersonData({EnumValueName((VMPersonDataVariable)data)}, {value});"); case VMVariableScope.StackObjectPersonData: //19 return($"((VMAvatar)context.StackObject).SetPersonData({EnumValueName((VMPersonDataVariable)data)}, {value});"); case VMVariableScope.MySlot: //20 throw new Exception("Not implemented..."); case VMVariableScope.StackObjectDefinition: //21 return($""); //you can't set this! case VMVariableScope.StackObjectAttributeByParameter: //22 return($"context.StackObject.SetAttribute((ushort)args[{data}], {value});"); //23: room by temp 0 //24: neighbor in stack object case VMVariableScope.Tuning: //26 return($""); //you can't set this! case VMVariableScope.DynSpriteFlagForTempOfStackObject: //27 return($"context.StackObject.SetDynamicSpriteFlag((ushort)temps[{data}], {value} > 0);"); case VMVariableScope.TreeAdPersonalityVar: //28 return($""); //you can't set this! case VMVariableScope.TreeAdMin: //29 return($""); //you can't set this! case VMVariableScope.MyPersonDataByTemp: //30 return($"((VMAvatar)context.Caller).SetPersonData((VMPersonDataVariable)temps[{data}], {value});"); case VMVariableScope.StackObjectPersonDataByTemp: //31 return($"((VMAvatar)context.StackObject).SetPersonData((VMPersonDataVariable)temps[{data}], {value});"); case VMVariableScope.NeighborPersonData: //32 throw new Exception("Not implemented..."); case VMVariableScope.JobData: //33 throw new Exception("Not implemented..."); case VMVariableScope.NeighborhoodData: //34 throw new Exception("Not implemented..."); case VMVariableScope.StackObjectFunction: //35 return($""); //you can't set this! case VMVariableScope.MyTypeAttr: //36 if (context.TS1) { return($"Content.Content.Get().Neighborhood.SetTATT((context.Caller.MasterDefinition ?? context.Caller.Object.OBJ).TypeAttrGUID, {data}, {value});"); } return($""); case VMVariableScope.StackObjectTypeAttr: //37 if (context.TS1) { return($"Content.Content.Get().Neighborhood.SetTATT((context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ).TypeAttrGUID, {data}, {value});"); } return($""); case VMVariableScope.NeighborsObjectDefinition: //38 return($""); //you can't set this! case VMVariableScope.StackObjectAttributeByTemp: //41 return($"context.StackObject.SetAttribute((ushort)temps[{data}], {value});"); case VMVariableScope.CityTime: //43 case VMVariableScope.TSOStandardTime: //44 case VMVariableScope.GameTime: //45 return($""); //you can't set this! case VMVariableScope.MyList: //46 return($"/** Set My List **/"); //throw new Exception("Not implemented..."); case VMVariableScope.StackObjectList: //47 return($"/** Set Stack Obj List **/"); //you can't set this! //throw new Exception("Not implemented..."); case VMVariableScope.MoneyOverHead32Bit: //48 return($"((VMAvatar)context.Caller).ShowMoneyHeadline({value});"); case VMVariableScope.MyLeadTileAttribute: //49 return($"context.Caller.MultitileGroup.BaseObject.SetAttribute({(ushort)data}, {value});"); case VMVariableScope.StackObjectLeadTileAttribute: //50 return($"context.StackObject.MultitileGroup.BaseObject.SetAttribute({(ushort)data}, {value});"); case VMVariableScope.MyLeadTile: //51 return($"context.Caller.MultitileGroup.BaseObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});"); case VMVariableScope.StackObjectLeadTile: //52 return($"context.StackObject.MultitileGroup.BaseObject.SetValue({EnumValueName((VMStackObjectVariable)data)}, {value});"); case VMVariableScope.StackObjectMasterDef: //53 return($""); case VMVariableScope.FeatureEnableLevel: //54 throw new Exception("Not implemented..."); case VMVariableScope.MyAvatarID: //59 return($""); //you can't set this! } } return($"VMMemory.SetVariable(context, {EnumValueName(scope)}, {data}, {value});"); }
public static string GetExpression(CSTranslationContext context, VMVariableScope scope, short data, bool big) { UpdateUsing(context, scope); switch (scope) { case VMVariableScope.MyObjectAttributes: //0 return(Exp($"context.Caller.GetAttribute({(ushort)data})")); case VMVariableScope.StackObjectAttributes: //1 return(Exp($"context.StackObject.GetAttribute({(ushort)data})")); case VMVariableScope.TargetObjectAttributes: //2 throw new Exception("Target Object is Deprecated!"); case VMVariableScope.MyObject: //3 return(Exp($"context.Caller.GetValue({EnumValueName((VMStackObjectVariable)data)})")); case VMVariableScope.StackObject: //4 return(Exp($"context.StackObject.GetValue({EnumValueName((VMStackObjectVariable)data)})")); case VMVariableScope.TargetObject: //5 throw new Exception("Target Object is Deprecated!"); case VMVariableScope.Global: //6 return(Exp($"context.VM.GetGlobalValue({(ushort)data})")); case VMVariableScope.Literal: //7 return(Exp(data.ToString())); case VMVariableScope.Temps: //8 return(Exp($"temps[{data}]")); case VMVariableScope.Parameters: //9 return(Exp($"args[{data}]")); case VMVariableScope.StackObjectID: //10 return(Exp($"context.StackObjectID")); case VMVariableScope.TempByTemp: //11 return(Exp($"temps[temps[{data}]]")); case VMVariableScope.TreeAdRange: //12 return(Exp($"0")); //throw new VMSimanticsException("Not implemented...", context); case VMVariableScope.StackObjectTemp: //13 return(Exp($"context.StackObject.Thread.TempRegisters[{data}]")); case VMVariableScope.MyMotives: //14 return(Exp($"((VMAvatar)context.Caller).GetMotiveData({EnumValueName((VMMotive)data)})")); case VMVariableScope.StackObjectMotives: //15 return(Exp($"((context.StackObject as VMAvatar)?.GetMotiveData({EnumValueName((VMMotive)data)}) ?? 0)")); case VMVariableScope.StackObjectSlot: //16 return(Exp($"(context.StackObject.GetSlot({data})?.ObjectID ?? 0)")); case VMVariableScope.StackObjectMotiveByTemp: //17 return(Exp($"((VMAvatar)context.StackObject).GetMotiveData((VMMotive)temps[{data}])")); case VMVariableScope.MyPersonData: //18 return(Exp($"((VMAvatar)context.Caller).GetPersonData({EnumValueName((VMPersonDataVariable)data)})")); case VMVariableScope.StackObjectPersonData: //19 return(Exp($"((VMAvatar)context.StackObject).GetPersonData({EnumValueName((VMPersonDataVariable)data)})")); case VMVariableScope.MySlot: //20 return(Exp($"(context.Caller.GetSlot({data})?.ObjectID ?? 0)")); case VMVariableScope.StackObjectDefinition: //21 return(Exp($"VMMemory.GetEntityDefinitionVar(context.StackObject.Object.OBJ, {EnumValueName((VMOBJDVariable)data)}, context)")); case VMVariableScope.StackObjectAttributeByParameter: //22 return(Exp($"context.StackObject.GetAttribute((ushort)args[{data}])")); //23 : room, fallback //24 : nhood, fallback case VMVariableScope.Local: //25 return(Exp($"locals[{data}]")); case VMVariableScope.Tuning: //26 return(Exp($"VMMemory.GetTuningVariable(context.Callee, {(ushort)data}, context)")); case VMVariableScope.DynSpriteFlagForTempOfStackObject: //27 return(Exp($"(context.StackObject.IsDynamicSpriteFlagSet((ushort)temps[{data}]) ? (short)1 : (short)0)")); case VMVariableScope.TreeAdPersonalityVar: //28 throw new Exception("Not implemented..."); case VMVariableScope.TreeAdMin: //29 throw new Exception("Not implemented..."); case VMVariableScope.MyPersonDataByTemp: //30 return(Exp($"((VMAvatar)context.Caller).GetPersonData((VMPersonDataVariable)(temps[{data}]))")); case VMVariableScope.StackObjectPersonDataByTemp: //31 return(Exp($"((VMAvatar)context.StackObject).GetPersonData((VMPersonDataVariable)(temps[{data}]))")); case VMVariableScope.NeighborPersonData: //32 if (!context.TS1) { throw new Exception("Only valid in TS1."); } return(Exp($"(Content.Content.Get().Neighborhood.GetNeighborByID(context.StackObjectID)?.PersonData?.ElementAt({data}) ?? 0)")); case VMVariableScope.JobData: //33 jobdata(temp0, temp1), used a few times to test if a person is at work but that isn't relevant for tso... if (!context.TS1) { throw new Exception("Only valid in TS1."); } return(Exp($"Content.Content.Get().Jobs.GetJobData((ushort)temps[0], temps[1], {data})")); case VMVariableScope.NeighborhoodData: //34 return(Exp($"0")); //tutorial values only case VMVariableScope.StackObjectFunction: //35 return(Exp($"(short)context.StackObject.EntryPoints[{data}].ActionFunction")); case VMVariableScope.MyTypeAttr: //36 if (context.TS1) { return(Exp($"Content.Content.Get().Neighborhood.GetTATT((context.Caller.MasterDefinition ?? context.Caller.Object.OBJ).TypeAttrGUID, {data})")); } return(Exp($"0")); case VMVariableScope.StackObjectTypeAttr: //37 if (context.TS1) { return(Exp($"Content.Content.Get().Neighborhood.GetTATT((context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ).TypeAttrGUID, {data})")); } return(Exp($"0")); //38 neighbor object definition: fallback case VMVariableScope.Unused: return(Exp($"context.VM.TuningCache.GetLimit({EnumValueName((VMMotive)data)})")); case VMVariableScope.LocalByTemp: //40 return(Exp($"locals[temps[{data}]]")); case VMVariableScope.StackObjectAttributeByTemp: //41 return(Exp($"context.StackObject.GetAttribute((ushort)temps[{data}])")); case VMVariableScope.TempXL: //42 if (big) { return(Exp($"context.Thread.TempXL[{data}]")); } else { return(Exp($"(short)context.Thread.TempXL[{data}]")); } case VMVariableScope.TSOStandardTime: //44 //return GetTSOStandardTime(data) var time = "context.VM.Context.Clock.UTCNow"; switch (data) { case 0: return(Exp($"(short){time}.Second")); case 1: return(Exp($"(short){time}.Minute")); case 2: return(Exp($"(short){time}.Hour")); case 3: return(Exp($"(short){time}.Day")); case 4: return(Exp($"(short){time}.Month")); case 5: return(Exp($"(short){time}.Year")); } ; return(Exp($"0")); case VMVariableScope.CityTime: //43 case VMVariableScope.GameTime: //45 var timeN = "context.VM.Context.Clock"; switch (data) { case 0: return(Exp($"(short){timeN}.Seconds")); case 1: return(Exp($"(short){timeN}.Minutes")); case 2: return(Exp($"(short){timeN}.Hours")); case 3: return(Exp($"(short){timeN}.TimeOfDay")); case 4: return(Exp($"(short){timeN}.DayOfMonth")); case 5: return(Exp($"(short){timeN}.Month")); case 6: return(Exp($"(short){timeN}.Year")); } ; break; case VMVariableScope.MyList: //46 (man if only i knew what this meant) switch (data) { case 0: return(Exp($"context.Caller.MyList.First.Value")); //is this allowed? case 1: return(Exp($"context.Caller.MyList.Last.Value")); case 2: return(Exp($"(short)context.Caller.MyList.Count")); default: return(Exp($"context.Caller.MyList.ElementAt(temps[0])")); } case VMVariableScope.StackObjectList: //47 //if (context.StackObject == null) return 0; (this hack is probably needed by something) switch (data) { case 0: return(Exp($"context.StackObject.MyList.First.Value")); case 1: return(Exp($"context.StackObject.MyList.Last.Value")); case 2: return(Exp($"(short)context.StackObject.MyList.Count")); default: return(Exp($"context.StackObject.MyList.ElementAt(temps[0])")); } case VMVariableScope.MoneyOverHead32Bit: //48 //we're poor... will need special case for this in expression like TempXL if (big) { Exp($"0"); } return(Exp($"0")); case VMVariableScope.MyLeadTileAttribute: //49 return(Exp($"context.Caller.MultitileGroup.BaseObject.GetAttribute({(ushort)data})")); case VMVariableScope.StackObjectLeadTileAttribute: //50 return(Exp($"context.StackObject.MultitileGroup.BaseObject.GetAttribute({(ushort)data})")); case VMVariableScope.MyLeadTile: //51 return($"context.Caller.MultitileGroup.BaseObject.GetValue({EnumValueName((VMStackObjectVariable)data)})"); case VMVariableScope.StackObjectLeadTile: //52 return($"context.StackObject.MultitileGroup.BaseObject.GetValue({EnumValueName((VMStackObjectVariable)data)})"); //throw new Exception("Not implemented..."); case VMVariableScope.StackObjectMasterDef: //53 //gets definition of the master tile of a multi tile object in the stack object. return(Exp($"GetEntityDefinitionVar(context.StackObject.MasterDefinition ?? context.StackObject.Object.OBJ, {EnumValueName((VMOBJDVariable)data)}, context)")); case VMVariableScope.FeatureEnableLevel: //54 return(Exp($"1")); //all of them are enabled, dont really care right now //59: MyAvatarID, fallback } return(Exp($"VMMemory.GetVariable(context, {EnumValueName(scope)}, {data})")); }