Пример #1
0
        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);
        }
Пример #2
0
 static void CloseReader()
 {
     entryPoint = -1;
     process.Close();
     process = null;
 }