diff --git a/BizHawk.Emulation.Cores/Libretro/LibRetro.cs b/BizHawk.Emulation.Cores/Libretro/LibRetro.cs index a6d285cc52..16f2e36794 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibRetro.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibRetro.cs @@ -16,7 +16,15 @@ namespace BizHawk.Emulation.Cores /// public class LibRetro : IDisposable { - public const int RETRO_API_VERSION = 1; + public const int RETRO_API_VERSION = 1; + + public enum RETRO_ROTATION + { + ROTATION_0_CCW = 0, + ROTATION_90_CCW = 1, + ROTATION_180_CCW = 2, + ROTATION_270_CCW = 3, + } public enum RETRO_DEVICE { diff --git a/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs b/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs index f3028acab3..49a885bfaf 100644 --- a/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs +++ b/BizHawk.Emulation.Cores/Libretro/LibRetroEmulator.cs @@ -101,8 +101,15 @@ namespace BizHawk.Emulation.Cores Console.WriteLine(cmd); switch (cmd) { - case LibRetro.RETRO_ENVIRONMENT.SET_ROTATION: - return false; + case LibRetro.RETRO_ENVIRONMENT.SET_ROTATION: + { + var rotation = (LibRetro.RETRO_ROTATION)(*(int*)data.ToPointer()); + if (rotation == LibRetro.RETRO_ROTATION.ROTATION_0_CCW) environmentInfo.Rotation_CCW = 0; + if (rotation == LibRetro.RETRO_ROTATION.ROTATION_90_CCW) environmentInfo.Rotation_CCW = 90; + if (rotation == LibRetro.RETRO_ROTATION.ROTATION_180_CCW) environmentInfo.Rotation_CCW = 180; + if (rotation == LibRetro.RETRO_ROTATION.ROTATION_270_CCW) environmentInfo.Rotation_CCW = 270; + return true; + } case LibRetro.RETRO_ENVIRONMENT.GET_OVERSCAN: return false; case LibRetro.RETRO_ENVIRONMENT.GET_CAN_DUPE: @@ -273,7 +280,8 @@ namespace BizHawk.Emulation.Cores class RetroEnvironmentInfo { - public bool SupportNoGame; + public bool SupportNoGame; + public int Rotation_CCW; } //disposable resources @@ -774,7 +782,7 @@ namespace BizHawk.Emulation.Cores #region IVideoProvider float dar; - int[] vidbuff; + int[] vidbuff, rawvidbuff; LibRetro.RETRO_PIXEL_FORMAT pixelfmt = LibRetro.RETRO_PIXEL_FORMAT.XRGB1555; void Blit555(short* src, int* dst, int width, int height, int pitch) @@ -847,13 +855,27 @@ namespace BizHawk.Emulation.Cores void retro_video_refresh(IntPtr data, uint width, uint height, uint pitch) { if (data == IntPtr.Zero) // dup frame - return; - if (width * height > vidbuff.Length) - { - Console.WriteLine("Unexpected libretro video buffer overrun?"); - return; - } - fixed (int* dst = &vidbuff[0]) + return; + + + //if (BufferWidth != width) BufferWidth = (int)width; + //if (BufferHeight != height) BufferHeight = (int)height; + //if (BufferWidth * BufferHeight != rawvidbuff.Length) + // rawvidbuff = new int[BufferWidth * BufferHeight]; + + //if we have rotation, we might have a geometry mismatch and in any event we need a temp buffer to do the rotation from + //but that's a general problem, isnt it? + if (rawvidbuff == null || rawvidbuff.Length != width * height) + { + rawvidbuff = new int[width * height]; + } + + int[] target = vidbuff; + if (environmentInfo.Rotation_CCW != 0) + target = rawvidbuff; + + + fixed (int* dst = &target[0]) { if (pixelfmt == LibRetro.RETRO_PIXEL_FORMAT.XRGB8888) Blit888((int*)data, dst, (int)width, (int)height, (int)pitch / 4); @@ -861,6 +883,27 @@ namespace BizHawk.Emulation.Cores Blit565((short*)data, dst, (int)width, (int)height, (int)pitch / 2); else Blit555((short*)data, dst, (int)width, (int)height, (int)pitch / 2); + } + + int dw = BufferWidth, dh = BufferHeight; + if (environmentInfo.Rotation_CCW == 0) { } + else if (environmentInfo.Rotation_CCW == 270) + { + for(int y=0;y