static void SearchEntryPoint() { if (process.Read(memory, 0, memory.Length) > 0 && DosBox.GetExeEntryPoint(memory, out entryPoint)) { //check if CDROM/floppy version byte[] cdPattern = Encoding.ASCII.GetBytes("CD Not Found"); var gameVersion = Shared.Tools.IndexOf(memory, cdPattern) != -1 ? GameVersion.AITD1 : GameVersion.AITD1_FLOPPY; if (gameVersion == GameVersion.AITD1_FLOPPY) { if (Shared.Tools.IndexOf(memory, Encoding.ASCII.GetBytes("USA.PAK")) != -1) { gameVersion = GameVersion.AITD1_DEMO; } } gameConfig = gameConfigs[gameVersion]; switch (gameVersion) { case GameVersion.AITD1: cache = cacheConfig.Where(x => x.Section != VarEnum.MUSIC).ToArray(); break; default: cache = cacheConfig; break; } } else { CloseReader(); } }
static void UpdateMCB(byte[] pixelData, byte[] oldPixelData, uint[] pixels) { if (!DosBox.GetMCBs(pixelData).SequenceEqual(DosBox.GetMCBs(oldPixelData))) { //clear old MCB foreach (var block in DosBox.GetMCBs(oldPixelData)) { int dest = block.Position - 16; int length = Math.Min(block.Size + 16, pixels.Length - dest); Array.Clear(pixels, dest, length); } int psp = pixelData.ReadUnsignedShort(0x0B30) * 16; bool inverse = true; foreach (var block in DosBox.GetMCBs(pixelData)) { uint color; if (block.Owner == 0) { color = 0x90008000; //free } else if (block.Owner != psp) { color = 0x90808000; } else if (block.Position == psp) { color = 0x90800000; //current executable } else { color = inverse ? 0x900080F0 : 0x902000A0; //used } int dest = block.Position - 16; int length = Math.Min(16, pixels.Length - dest); for (int i = 0; i < length; i++) { pixels[dest++] = 0x90FF00FF; } length = Math.Min(block.Size, pixels.Length - dest); for (int i = 0; i < length; i++) { pixels[dest++] = color; } inverse = !inverse; } SetRefreshState(true); } }
static void SearchDosBox() { int processId = DosBox.SearchProcess(); if (processId != -1) { process = new ProcessMemory(processId); process.BaseAddress = process.SearchFor16MRegion(); if (process.BaseAddress == -1) { CloseReader(); } } }
static void ReadMemory() { int ticks = Environment.TickCount; bool readSuccess = true; for (int i = 0; i < cache.Length; i++) { var ch = cache[i]; if (readSuccess &= (process.Read(memory, entryPoint + gameConfig[ch.Index], 4) > 0)) { int cachePointer = memory.ReadFarPointer(0); if (cachePointer != 0 && (readSuccess &= (process.Read(memory, cachePointer - 16, 4096) > 0))) { DosMCB block = DosBox.ReadMCB(memory, 0); if ((block.Tag == 0x4D || block.Tag == 0x5A) && block.Owner != 0 && block.Size < 4096) //block is still allocated { UpdateCache(ch, ticks, 16); UpdateEntries(ch, ticks); if (clearCache) { ClearCache(ch, cachePointer); } } else { ch.Name = null; } } else { ch.Name = null; } } } clearCache = false; if (!readSuccess) { CloseReader(); } }
/// <summary> /// Cast the configuration to string format /// </summary> /// <returns>String DosBox configuration format</returns> public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine(SDL?.ToString()); sb.AppendLine(DosBox?.ToString()); sb.AppendLine(Render?.ToString()); sb.AppendLine(CPU?.ToString()); sb.AppendLine(Mixer?.ToString()); sb.AppendLine(Midi?.ToString()); sb.AppendLine(SoundBlaster?.ToString()); sb.AppendLine(GUS?.ToString()); sb.AppendLine(Speaker?.ToString()); sb.AppendLine(Joystick?.ToString()); sb.AppendLine(Serial?.ToString()); sb.AppendLine(DOS?.ToString()); sb.AppendLine(IPX?.ToString()); sb.Append(Autoexec?.ToString()); return(sb.ToString()); }
public static int Main(string[] args) { winx = Tools.GetArgument <int?>(args, "-screen-width") ?? 640; winy = Tools.GetArgument <int?>(args, "-screen-height") ?? 480; zoom = Tools.GetArgument <int?>(args, "-zoom") ?? 2; //init SDL SDL.SDL_Init(SDL.SDL_INIT_VIDEO); IntPtr window = SDL.SDL_CreateWindow("AITD memory viewer", SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, winx, winy, SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE); IntPtr renderer = SDL.SDL_CreateRenderer(window, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL.SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC); //IntPtr renderer = SDL.SDL_CreateRenderer(window, -1, SDL.SDL_RendererFlags.SDL_RENDERER_SOFTWARE); //SDL.SDL_SetHint(SDL.SDL_HINT_RENDER_SCALE_QUALITY, "linear"); IntPtr texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, RESX, RESY); uint[] palette = new uint[256]; byte[] palette256 = new byte[768]; SetRefreshState(true); bool quit = false, mcb = false, minimized = false; uint[] pixels = new uint[RESX * RESY * SCREENS]; uint[] mcbPixels = new uint[RESX * RESY * SCREENS]; byte[] pixelData = new byte[RESX * RESY * SCREENS]; byte[] oldPixelData = new byte[RESX * RESY * SCREENS]; long paletteAddress = -1; ProcessMemory process = null; uint lastCheck = 0, lastCheckPalette = 0; while (!quit) { SDL.SDL_Event sdlEvent; while (SDL.SDL_PollEvent(out sdlEvent) != 0 && !quit) { switch (sdlEvent.type) { case SDL.SDL_EventType.SDL_QUIT: quit = true; break; case SDL.SDL_EventType.SDL_MOUSEWHEEL: if ((SDL.SDL_GetModState() & SDL.SDL_Keymod.KMOD_CTRL) != 0) { if (sdlEvent.wheel.y > 0) { SetZoom(zoom + 1); } else if (sdlEvent.wheel.y < 0) { SetZoom(zoom - 1); } } break; case SDL.SDL_EventType.SDL_KEYDOWN: switch (sdlEvent.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_SPACE: mcb = !mcb; SetRefreshState(true); break; } if ((sdlEvent.key.keysym.mod & SDL.SDL_Keymod.KMOD_CTRL) != 0) { switch (sdlEvent.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_EQUALS: case SDL.SDL_Keycode.SDLK_KP_PLUS: SetZoom(zoom + 1); break; case SDL.SDL_Keycode.SDLK_MINUS: case SDL.SDL_Keycode.SDLK_KP_MINUS: SetZoom(zoom - 1); break; case SDL.SDL_Keycode.SDLK_0: case SDL.SDL_Keycode.SDLK_KP_0: SetZoom(2); break; } } break; case SDL.SDL_EventType.SDL_WINDOWEVENT: switch (sdlEvent.window.windowEvent) { case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED: winx = sdlEvent.window.data1; winy = sdlEvent.window.data2; SetRefreshState(true); break; case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_MINIMIZED: minimized = true; break; case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESTORED: minimized = false; break; } break; } } if (process == null) { uint time = SDL.SDL_GetTicks(); if ((time - lastCheck) > 1000 || lastCheck == 0) { lastCheck = time; paletteAddress = -1; int processId = DosBox.SearchProcess(); if (processId != -1) { process = new ProcessMemory(processId); process.BaseAddress = process.SearchFor16MRegion(); if (process.BaseAddress == -1) { process.Close(); process = null; } } } } if (process != null) { if (paletteAddress == -1) { uint time = SDL.SDL_GetTicks(); if ((time - lastCheckPalette) > 1000 || lastCheckPalette == 0) { lastCheckPalette = time; //3 bytes + EGA 16 colors palette var pattern = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; paletteAddress = process.SearchForBytePattern(buffer => Tools.IndexOf(buffer, pattern, 1, 4)); } } } if (process != null) { //DOS conventional memory (640KB) //EMS memory (64000B) (skip 64KB (HMA) + 128KB (VCPI)) if (!(process.Read(pixelData, 0, 640 * 1024) > 0 && process.Read(pixelData, (1024 + 192) * 1024, 64000, 640 * 1024) > 0)) { process.Close(); process = null; } } if (process != null) { if (paletteAddress != -1) { if (process.Read(palette256, paletteAddress + 19 - process.BaseAddress, palette256.Length) <= 0) { process.Close(); process = null; } } } UpdatePalette(palette256, palette); Update(pixelData, oldPixelData, pixels, palette); UpdateMCB(pixelData, oldPixelData, mcbPixels); //render int tm = (winx + RESX * zoom - 1) / (RESX * zoom); int tn = (winy + RESY * zoom - 1) / (RESY * zoom); SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_NONE); Render(renderer, texture, tm, tn, pixels); if (mcb) { SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND); Render(renderer, texture, tm, tn, mcbPixels); } SDL.SDL_RenderPresent(renderer); SetRefreshState(false); mustClearScreen = false; if (minimized) { SDL.SDL_Delay(1); } //swap buffers var tmp = pixelData; pixelData = oldPixelData; oldPixelData = tmp; } SDL.SDL_DestroyTexture(texture); SDL.SDL_DestroyRenderer(renderer); SDL.SDL_DestroyWindow(window); SDL.SDL_Quit(); return(0); }
void Update() { float mouseWheel = Input.GetAxis("Mouse ScrollWheel"); if (mouseWheel != 0.0f) { Vector3 cameraHeight = new Vector3(0.0f, 0.0f, Camera.main.transform.position.y); Vector3 mouseBeforeZoom = Camera.main.ScreenToWorldPoint(Input.mousePosition + cameraHeight); float scale = 0.9f; if (mouseWheel < 0.0f) { scale = 1.0f / scale; } if (Camera.main.orthographic) { Camera.main.orthographicSize *= scale; } else { Camera.main.transform.position = Vector3.Scale(Camera.main.transform.position, new Vector3(1.0f, scale, 1.0f)); } cameraHeight = new Vector3(0.0f, 0.0f, Camera.main.transform.position.y); Camera.main.transform.position += mouseBeforeZoom - Camera.main.ScreenToWorldPoint(Input.mousePosition + cameraHeight); } if (!menuEnabled && !GetComponent <WarpDialog>().WarpMenuEnabled) { //start drag if (Input.GetMouseButtonDown(0)) { dragging = false; mousePosition = startDragPosition = Input.mousePosition; } //dragging if (Input.GetMouseButton(0)) { Vector3 newMousePosition = Input.mousePosition; if (newMousePosition != this.mousePosition) { Vector3 cameraHeight = new Vector3(0.0f, 0.0f, Camera.main.transform.position.y); Vector3 mouseDelta = Camera.main.ScreenToWorldPoint(this.mousePosition + cameraHeight) - Camera.main.ScreenToWorldPoint(newMousePosition + cameraHeight); Camera.main.transform.position += mouseDelta; mousePosition = newMousePosition; if ((startDragPosition - newMousePosition).magnitude > 4.0f) { dragging = true; } } } } //menu if (Input.GetMouseButtonDown(1)) { WarpDialog warpDialog = GetComponent <WarpDialog>(); if (menuEnabled) { menuEnabled = false; } else if (warpDialog.WarpMenuEnabled) { warpDialog.WarpMenuEnabled = false; if (speedRunMode) { warpDialog.WarpActorBox = null; //reset to player warpDialog.WarpActorBoxId = -1; } } else if (dosBoxEnabled && highLightedBox != null && highLightedBox.name == "Actor") { warpDialog.LoadActor(highLightedBox); warpDialog.WarpMenuEnabled = true; } else { menuEnabled = true; } } if (Input.GetMouseButtonUp(0) && !RectTransformUtility.RectangleContainsScreenPoint(Panel, Input.mousePosition)) { menuEnabled = false; } if (menuEnabled != Panel.gameObject.activeSelf) { Panel.gameObject.SetActive(menuEnabled); } DosBox dosBox = GetComponent <DosBox>(); dosBox.ShowAdditionalInfo = ShowAdditionalInfo.BoolValue && dosBoxEnabled; dosBox.ShowAITD1Vars = dosBox.ShowAdditionalInfo && isAITD1 && dosBox.IsCDROMVersion; dosBox.SpeedRunMode = speedRunMode; dosBox.RefreshMemory(); dosBox.CalculateFPS(); dosBox.UpdateAllActors(); dosBox.UpdateBoxInfo(); if (isAITD1) { dosBox.UpdateTargetSlot(highLightedBox); } RefreshHighLightedBox(); RefreshSelectedBox(); //process keys if (!GetComponent <WarpDialog>().WarpMenuEnabled) { foreach (var key in keyCodes) { if (Input.GetKeyDown(key)) { ProcessKey(key); } } } //automatic link if (!dosBoxEnabled && linkToDosBoxTimer.Elapsed > 1.0f) { LinkToDosBox(); linkToDosBoxTimer.Restart(); } }
public bool Update() { if (process == null) { int processId = DosBox.SearchProcess(); if (processId != -1) { process = new ProcessMemory(processId); process.BaseAddress = process.SearchFor16MRegion(); if (process.BaseAddress == -1) { CloseReader(); } } } if (process != null && entryPoint == -1) { if (process.Read(memory, 0, memory.Length) > 0 && DosBox.GetExeEntryPoint(memory, out entryPoint)) { //check if CDROM/floppy version byte[] cdPattern = Encoding.ASCII.GetBytes("CD Not Found"); gameVersion = Tools.IndexOf(memory, cdPattern) != -1 ? GameVersion.AITD1 : GameVersion.AITD1_FLOPPY; if (gameVersion == GameVersion.AITD1_FLOPPY) { if (Tools.IndexOf(memory, Encoding.ASCII.GetBytes("USA.PAK")) != -1) { gameVersion = GameVersion.AITD1_DEMO; } } gameConfig = gameConfigs[gameVersion]; } else { CloseReader(); } } if (process != null && !Freeze) { bool needRefresh = false; int time = Environment.TickCount; bool result = true; if (result &= (process.Read(memory, gameConfig.VarsAddress + entryPoint, 4) > 0)) { varsPointer = memory.ReadFarPointer(0); if (varsPointer == 0) { InitVars(vars, 0, VarEnum.VARS); } else { InitVars(vars, gameVersion == GameVersion.AITD1_DEMO ? 22 : 207, VarEnum.VARS); if (result &= (process.Read(memory, varsPointer, vars.Count * 2) > 0)) { needRefresh |= CheckDifferences(vars, time); } } } InitVars(cvars, 16, VarEnum.CVARS); if (result &= (process.Read(memory, gameConfig.CvarAddress + entryPoint, cvars.Count * 2) > 0)) { needRefresh |= CheckDifferences(cvars, time); } if (!result) { CloseReader(); } IgnoreDifferences = false; return(needRefresh); } return(false); }
/// <summary> /// Load configuration from dictionary /// </summary> /// <param name="dictionary">Dictionary with dosbox configuration data.</param> /// <returns>DosBoxConfiguration data</returns> public DosBoxConfiguration LoadDictionary(IDictionary <string, object> dictionary) { foreach (var keyValue in dictionary) { switch (keyValue.Key) { case "sdl": if (keyValue.Value is IDictionary <string, object> ) { SDL.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "dosbox": if (keyValue.Value is IDictionary <string, object> ) { DosBox.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "render": if (keyValue.Value is IDictionary <string, object> ) { Render.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "cpu": if (keyValue.Value is IDictionary <string, object> ) { CPU.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "mixer": if (keyValue.Value is IDictionary <string, object> ) { Mixer.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "midi": if (keyValue.Value is IDictionary <string, object> ) { Midi.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "sblaster": if (keyValue.Value is IDictionary <string, object> ) { SoundBlaster.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "gus": if (keyValue.Value is IDictionary <string, object> ) { GUS.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "speaker": if (keyValue.Value is IDictionary <string, object> ) { Speaker.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "joystick": if (keyValue.Value is IDictionary <string, object> ) { Joystick.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "serial": if (keyValue.Value is IDictionary <string, object> ) { Serial.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "dos": if (keyValue.Value is IDictionary <string, object> ) { DOS.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "ipx": if (keyValue.Value is IDictionary <string, object> ) { IPX.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; case "autoexec": if (keyValue.Value is IDictionary <string, object> ) { Autoexec.LoadDictionary(keyValue.Value as IDictionary <string, object>); } break; default: break; } } return(this); }
/// <summary> /// Load the default DosBox configuration /// </summary> /// <returns>DosBoxConfiguration data</returns> public DosBoxConfiguration LoadDeafult() { SDL.AddAutoLock() .AddFullDouble() .AddFullResolution(Resolution.Original) .AddFullScreen() .AddOutput(VideoOutput.Surface) .AddPriorityFocused() .AddPriorityMinimized() .AddSensitivity() .AddUseScanCodes() .AddWaitOnError() .AddWindowResolution(Resolution.Original); DosBox.AddCaptures() .AddMachine() .AddMemSize(); Render.AddAspect() .AddFrameskip() .AddScaler(ScalerType.Normal2x); CPU.AddCore() .AddCPUType() .AddCycles(new CPUCycles("auto")) .AddCycleUp() .AddCycleDown(); Mixer.AddNoSound() .AddRate() .AddBlockSize() .AddPreBuffer(); Midi.AddMPU401() .AddMidiDevice(); SoundBlaster.AddSBType() .AddSBBase() .AddIRQ() .AddDMA() .AddHDMA() .AddSoundMixer() .AddOplMode() .AddOplEmu() .AddOplRate(); GUS.AddGUS() .AddGusRate() .AddGusBase() .AddGusIRQ() .AddGusDMA() .AddUltraDir(); Speaker.AddPCSpeaker() .AddPCRate() .AddTandy() .AddTandyRate() .AddDisney(); Joystick.AddJoystickType() .AddTimed() .AddAutoFire() .AddSwap34() .AddButtonWrap(); Serial.AddSerial1(Options.Serial.CreateDummy()) .AddSerial2(Options.Serial.CreateDummy()) .AddSerial3(Options.Serial.CreateDisabled()) .AddSerial4(Options.Serial.CreateDisabled()); DOS.AddXMS() .AddEMS() .AddUMB() .AddKeyboardLayout(KeyboardLayout.Auto); IPX.AddIPX(); return(this); }