protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // dispose managed state (managed objects). currentTexture = null; fpsTextTexture?.Dispose(); fpsTextTexture = null; for (int index = 0; index < (int)KeyPressSurface.Count; ++index) { textures[index]?.Dispose(); textures[index] = null; } pixelTexture?.Dispose(); pixelTexture = null; pixelDebugTexture?.Dispose(); pixelDebugTexture = null; driver?.Dispose(); driver = null; } // free unmanaged resources (unmanaged objects) and override a finalizer below. // set large fields to null. disposedValue = true; } }
public Texture(SDLDriver driver) { if (driver == null) { throw new ArgumentNullException(nameof(driver)); } this.rendererPtr = driver.rendererPtr; this.fontPtr = driver.fontPtr; }
static int Main(string[] args) { if (!driver.Init(WIDTH, HEIGHT)) { Debug.Print("Failed to initialize!"); return(-1); } // Setup the graphics (window size, display mode, etc) if (!driver.SetupGraphics($"assets{Path.DirectorySeparatorChar.ToString(CultureInfo.CurrentCulture)}CHIP-8.logo.bmp")) { Debug.Print("Failed to setup graphics!"); return(-2); } // Setup the input system (register input callbacks) if (!driver.SetupInput()) { Debug.Print("Failed to setup input!"); return(-3); } if (!LoadMedia()) { Debug.Print("Failed to load media!"); return(-4); } //Main loop flag var quit = false; //Event handler SDL.SDL_Event evt; //Set default current surface currentTexture = textures[(int)KeyPressSurface.Default]; Debug.Print("Loaded..."); var pixelColor = appleIIcGreen; var backgroundColor = gray; // Initialize the CHIP-8 system (Clear the memory, registers and screen) myChip8 = new CPU((uint)((pixelColor.a << 24) | (pixelColor.r << 16) | (pixelColor.g << 8) | pixelColor.b), (uint)((backgroundColor.a << 24) | (backgroundColor.r << 16) | (backgroundColor.g << 8) | backgroundColor.b)); myChip8.OnDraw += DrawGraphics; myChip8.OnStartSound += OnStartSound; myChip8.OnEndSound += OnEndSound; // Load (copy) the game into the memory myChip8.LoadGame($"progs{Path.DirectorySeparatorChar.ToString(CultureInfo.CurrentCulture)}demo.ch8"); //Rotation variables double angle = 0; screenCenter = new SDL.SDL_Point { x = WIDTH / 2, y = HEIGHT / 2 }; //Start counting frames per second countedFrames = 0; fpsTimer.Start(); //While application is running while (!quit) { if (!debugKeys && !debugPixels) { // Emulate one cycle of the system myChip8.EmulateCycle(); } //Handle events on queue while (SDL.SDL_PollEvent(out evt) != 0) { //User requests quit switch (evt.type) { case SDL.SDL_EventType.SDL_QUIT: Debug.Print("Quitting..."); quit = true; break; case SDL.SDL_EventType.SDL_KEYDOWN: //Select surfaces based on key press switch (evt.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_ESCAPE: Debug.Print("ESCAPE"); Debug.Print("Quitting..."); quit = true; break; case SDL.SDL_Keycode.SDLK_UP: currentTexture = textures[(int)KeyPressSurface.Up]; Debug.Print("UP"); break; case SDL.SDL_Keycode.SDLK_DOWN: currentTexture = textures[(int)KeyPressSurface.Down]; Debug.Print("DOWN"); break; case SDL.SDL_Keycode.SDLK_LEFT: currentTexture = textures[(int)KeyPressSurface.Left]; Debug.Print("LEFT"); break; case SDL.SDL_Keycode.SDLK_RIGHT: currentTexture = textures[(int)KeyPressSurface.Right]; Debug.Print("RIGHT"); break; case SDL.SDL_Keycode.SDLK_1: keys[0x0] = 1; Debug.Print("1"); break; case SDL.SDL_Keycode.SDLK_2: keys[0x1] = 1; Debug.Print("2"); break; case SDL.SDL_Keycode.SDLK_3: keys[0x2] = 1; Debug.Print("3"); break; case SDL.SDL_Keycode.SDLK_4: keys[0x3] = 1; Debug.Print("4"); break; case SDL.SDL_Keycode.SDLK_q: keys[0x4] = 1; Debug.Print("q"); break; case SDL.SDL_Keycode.SDLK_w: keys[0x5] = 1; Debug.Print("w"); break; case SDL.SDL_Keycode.SDLK_e: keys[0x6] = 1; Debug.Print("e"); break; case SDL.SDL_Keycode.SDLK_r: keys[0x7] = 1; Debug.Print("r"); break; case SDL.SDL_Keycode.SDLK_a: keys[0x8] = 1; Debug.Print("a"); break; case SDL.SDL_Keycode.SDLK_s: keys[0x9] = 1; Debug.Print("s"); break; case SDL.SDL_Keycode.SDLK_d: keys[0xA] = 1; Debug.Print("d"); break; case SDL.SDL_Keycode.SDLK_f: keys[0xA] = 1; Debug.Print("f"); break; case SDL.SDL_Keycode.SDLK_z: keys[0xB] = 1; Debug.Print("z"); break; case SDL.SDL_Keycode.SDLK_y: keys[0xB] = 1; Debug.Print("y"); break; case SDL.SDL_Keycode.SDLK_x: keys[0xC] = 1; Debug.Print("x"); break; case SDL.SDL_Keycode.SDLK_c: keys[0xD] = 1; Debug.Print("c"); break; case SDL.SDL_Keycode.SDLK_v: keys[0xE] = 1; Debug.Print("v"); break; case SDL.SDL_Keycode.SDLK_BACKSPACE: debugKeys = false; debugPixels = !debugPixels; if (debugPixels) { Debug.Print("Entering debug pixel mode"); } else { Debug.Print("Leaving debug pixel mode"); } break; case SDL.SDL_Keycode.SDLK_RETURN: debugKeys = !debugKeys; debugPixels = false; if (debugKeys) { Debug.Print("Entering debug keys mode"); } else { Debug.Print("Leaving debug keys mode"); } break; case SDL.SDL_Keycode.SDLK_PLUS: zoom += 0.5f; Debug.Print($"Zoom level: {zoom.ToString(NumberFormatInfo.CurrentInfo)}x"); break; case SDL.SDL_Keycode.SDLK_MINUS: zoom -= 0.5f; Debug.Print($"Zoom level: {zoom.ToString(NumberFormatInfo.CurrentInfo)}x"); break; case SDL.SDL_Keycode.SDLK_0: zoom = 1.0f; Debug.Print($"Zoom level: {zoom.ToString(NumberFormatInfo.CurrentInfo)}x"); break; default: currentTexture = textures[(int)KeyPressSurface.Default]; Debug.Print("Default Key Press"); break; } break; case SDL.SDL_EventType.SDL_KEYUP: //Select surfaces based on key press switch (evt.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_UP: currentTexture = textures[(int)KeyPressSurface.Default]; break; case SDL.SDL_Keycode.SDLK_DOWN: currentTexture = textures[(int)KeyPressSurface.Default]; break; case SDL.SDL_Keycode.SDLK_LEFT: currentTexture = textures[(int)KeyPressSurface.Default]; break; case SDL.SDL_Keycode.SDLK_RIGHT: currentTexture = textures[(int)KeyPressSurface.Default]; break; case SDL.SDL_Keycode.SDLK_1: keys[0x0] = 0; Debug.Print("1"); break; case SDL.SDL_Keycode.SDLK_2: keys[0x1] = 0; Debug.Print("2"); break; case SDL.SDL_Keycode.SDLK_3: keys[0x2] = 0; Debug.Print("3"); break; case SDL.SDL_Keycode.SDLK_4: keys[0x3] = 0; Debug.Print("4"); break; case SDL.SDL_Keycode.SDLK_q: keys[0x4] = 0; Debug.Print("q"); break; case SDL.SDL_Keycode.SDLK_w: keys[0x5] = 0; Debug.Print("w"); break; case SDL.SDL_Keycode.SDLK_e: keys[0x6] = 0; Debug.Print("e"); break; case SDL.SDL_Keycode.SDLK_r: keys[0x7] = 0; Debug.Print("r"); break; case SDL.SDL_Keycode.SDLK_a: keys[0x8] = 0; Debug.Print("a"); break; case SDL.SDL_Keycode.SDLK_s: keys[0x9] = 0; Debug.Print("s"); break; case SDL.SDL_Keycode.SDLK_d: keys[0xA] = 0; Debug.Print("d"); break; case SDL.SDL_Keycode.SDLK_f: keys[0xA] = 0; Debug.Print("f"); break; case SDL.SDL_Keycode.SDLK_z: keys[0xB] = 0; break; case SDL.SDL_Keycode.SDLK_y: keys[0xB] = 0; break; case SDL.SDL_Keycode.SDLK_x: keys[0xC] = 0; break; case SDL.SDL_Keycode.SDLK_c: keys[0xD] = 0; break; case SDL.SDL_Keycode.SDLK_v: keys[0xE] = 0; break; default: currentTexture = textures[(int)KeyPressSurface.Default]; break; } break; } } if (debugKeys) { if (!SDLDriver.Render(currentTexture)) { Debug.Print("Failed to render texture!"); } } if (debugPixels) { angle = RotateRectangle(angle); } // Store key press state (Press and Release) // If we press or release a key, we should store this state in the part that emulates the keypad myChip8.SetKeys(keys); // 60 Hz = 1000 ms /60 = 16.666 ms => approx. 17 ms (17 ms * 60 = 1020 ms) //SDL.SDL_Delay(17); //Calculate and correct fps var avgFPS = countedFrames / (fpsTimer.Ticks / 1000.0); // It is possible for there to be a very small amount of time passed // for the first frame and have it give us a really high fps. // This is why we correct the value if it is really high. if (avgFPS > 2000000) { avgFPS = 0; } //Set text to be rendered timerText = $"Average {avgFPS.ToString("F2", NumberFormatInfo.CurrentInfo)} Frames Per Second"; var color = white; if (debugKeys) { color = black; } if (debugPixels) { color = green1; } //Render text if (!fpsTextTexture.LoadFromRenderedText(timerText, color)) { Debug.Print("Unable to render FPS texture!"); } //Clear screen //SDL.SDL_SetRenderDrawColor(driver.rendererPtr, 0xFF, 0xFF, 0xFF, 0xFF); //SDL.SDL_RenderClear(driver.rendererPtr); //Render textures fpsTextTexture.Render((WIDTH - fpsTextTexture.Width) / 2, (HEIGHT - (int)(fpsTextTexture.Height * 1.75))); //Update screen if (!driver.Present()) { Debug.Print("Failed to present render!"); } ++countedFrames; } return(0); }
static bool LoadMedia() { //Loading success flag var success = true; IntPtr surface; #pragma warning disable IDISP007 // Don't dispose injected. fpsTextTexture?.Dispose(); #pragma warning restore IDISP007 // Don't dispose injected. fpsTextTexture = new Texture(driver); //Load default surface textures[(int)KeyPressSurface.Default] = new Texture(driver); surface = SDLDriver.LoadSurface("assets/press.bmp"); if (surface == IntPtr.Zero) { Debug.Print("Failed to load default image!"); success = false; } else { textures[(int)KeyPressSurface.Default].LoadFromSurface(surface); SDL.SDL_FreeSurface(surface); surface = IntPtr.Zero; } //Load up surface textures[(int)KeyPressSurface.Up] = new Texture(driver); surface = SDLDriver.LoadSurface("assets/up.bmp"); if (surface == IntPtr.Zero) { Debug.Print("Failed to load up image!"); success = false; } else { textures[(int)KeyPressSurface.Up].LoadFromSurface(surface); SDL.SDL_FreeSurface(surface); surface = IntPtr.Zero; } //Load down surface textures[(int)KeyPressSurface.Down] = new Texture(driver); surface = SDLDriver.LoadSurface("assets/down.bmp"); if (surface == IntPtr.Zero) { Debug.Print("Failed to load down image!"); success = false; } else { textures[(int)KeyPressSurface.Down].LoadFromSurface(surface); SDL.SDL_FreeSurface(surface); surface = IntPtr.Zero; } //Load left surface textures[(int)KeyPressSurface.Left] = new Texture(driver); surface = SDLDriver.LoadSurface("assets/left.bmp"); if (surface == IntPtr.Zero) { Debug.Print("Failed to load left image!"); success = false; } else { textures[(int)KeyPressSurface.Left].LoadFromSurface(surface); SDL.SDL_FreeSurface(surface); surface = IntPtr.Zero; } //Load right surface textures[(int)KeyPressSurface.Right] = new Texture(driver); surface = SDLDriver.LoadSurface("assets/right.bmp"); if (surface == IntPtr.Zero) { Debug.Print("Failed to load right image!"); success = false; } else { textures[(int)KeyPressSurface.Right].LoadFromSurface(surface); SDL.SDL_FreeSurface(surface); surface = IntPtr.Zero; } #pragma warning disable IDISP007 // Don't dispose injected. pixelDebugTexture?.Dispose(); #pragma warning restore IDISP007 // Don't dispose injected. pixelDebugTexture = new Texture(driver); if (!pixelDebugTexture.CreateBlank(WIDTH, HEIGHT, SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET)) { Debug.Print("Failed to create target debug texture!"); success = false; } #pragma warning disable IDISP007 // Don't dispose injected. pixelTexture?.Dispose(); #pragma warning restore IDISP007 // Don't dispose injected. pixelTexture = new Texture(driver); if (!pixelTexture.CreateBlank(WIDTH, HEIGHT, SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_TARGET)) { Debug.Print("Failed to create target texture!"); success = false; } return(success); }