Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From e15f643b8fcd897edd56a52aa4429d995b79879a Mon Sep 17 00:00:00 2001
- From: gocha <gochaism@gmail.com>
- Date: Sat, 5 Feb 2011 00:00:51 +0900
- Subject: [PATCH] avi output support interlace
- ---
- win32/win32.cpp | 79 ++++++++++++++++++++++++++++++++++++-------------------
- 1 files changed, 52 insertions(+), 27 deletions(-)
- diff --git a/win32/win32.cpp b/win32/win32.cpp
- index 1f1dad1..fc0e919 100644
- --- a/win32/win32.cpp
- +++ b/win32/win32.cpp
- @@ -202,12 +202,8 @@
- //#define DEBUGGER
- #include <math.h>
- -#ifndef max
- -#define max(a, b) (((a) > (b)) ? (a) : (b))
- -#endif
- -#ifndef min
- -#define min(a, b) (((a) < (b)) ? (a) : (b))
- -#endif
- +
- +#include <algorithm>
- BYTE *ScreenBuf1 = NULL;
- BYTE *ScreenBuffer = NULL;
- @@ -1129,20 +1125,24 @@ void BuildAVIVideoFrame1X (void)
- {
- const int snesWidth = IPPU.RenderedScreenWidth;
- const int snesHeight = IPPU.RenderedScreenHeight;
- - const int width = min(snesWidth, avi_width);
- - const int height = min(snesHeight, avi_height);
- + const bool snesInterlaced = (snesHeight > SNES_HEIGHT_EXTENDED);
- + const int snesVerticalScale = snesInterlaced ? 2 : 1;
- + const int width = std::min(snesWidth, avi_width);
- + const int height = std::min(snesHeight / snesVerticalScale, avi_height);
- const int pitch = GFX.Pitch;
- #ifdef LSB_FIRST
- const bool order_is_rgb = (GUI.RedShift < GUI.BlueShift);
- #else
- const bool order_is_rgb = (GUI.RedShift > GUI.BlueShift);
- #endif
- - const int src_step = pitch - width * 2;
- + const int src_step = (pitch - width * 2) + (snesInterlaced ? pitch : 0);
- const int dst_step = -(avi_pitch + width * 3);
- const int image_offset = (avi_height - height) * avi_pitch;
- uint16 *s = GFX.Screen;
- uint8 *d = &avi_buffer[(avi_height - 1) * avi_pitch];
- + // TODO: vertical blend for interlace
- +
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- @@ -1150,7 +1150,10 @@ void BuildAVIVideoFrame1X (void)
- if(order_is_rgb)
- {
- // Order is RGB
- - uint32 pixel = *s++;
- + uint32 pixel = s[0];
- + if (snesInterlaced)
- + pixel = Interp(pixel,s[pitch]);
- + s++;
- *(d + 0) = (pixel >> (11 - 3)) & 0xf8;
- *(d + 1) = (pixel >> (6 - 3)) & 0xf8;
- *(d + 2) = (pixel & 0x1f) << 3;
- @@ -1159,7 +1162,10 @@ void BuildAVIVideoFrame1X (void)
- else
- {
- // Order is BGR
- - uint32 pixel = *s++;
- + uint32 pixel = s[0];
- + if (snesInterlaced)
- + pixel = Interp(pixel,s[pitch]);
- + s++;
- *(d + 0) = (pixel & 0x1f) << 3;
- *(d + 1) = (pixel >> (6 - 3)) & 0xf8;
- *(d + 2) = (pixel >> (11 - 3)) & 0xf8;
- @@ -1181,21 +1187,23 @@ void BuildAVIVideoFrame2X (void)
- {
- const int snesWidth = IPPU.RenderedScreenWidth;
- const int snesHeight = IPPU.RenderedScreenHeight;
- - const int width = min(snesWidth, avi_width / 2);
- - const int height = min(snesHeight, avi_height / 2);
- + const bool snesInterlaced = (snesHeight > SNES_HEIGHT_EXTENDED);
- + const int snesVerticalScale = snesInterlaced ? 2 : 1;
- + const int width = std::min(snesWidth, avi_width / 2);
- + const int height = std::min(snesHeight * 2 / snesVerticalScale, avi_height);
- const int pitch = GFX.Pitch;
- #ifdef LSB_FIRST
- const bool order_is_rgb = (GUI.RedShift < GUI.BlueShift);
- #else
- const bool order_is_rgb = (GUI.RedShift > GUI.BlueShift);
- #endif
- - const int src_step[2] = { -width * 2, pitch - width * 2 };
- + const int src_step[2] = { -width * 2 + (snesInterlaced ? pitch : 0), -width * 2 + pitch };
- const int dst_step = -(avi_pitch + width * 3 * 2);
- - const int image_offset = (avi_height - height * 2) * avi_pitch;
- + const int image_offset = (avi_height - height) * avi_pitch;
- uint16 *s = GFX.Screen;
- uint8 *d = &avi_buffer[(avi_height - 1) * avi_pitch];
- - for(int y = 0; y < height * 2; y++)
- + for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- @@ -1233,15 +1241,17 @@ void BuildAVIVideoFrame1XHiRes (void)
- {
- const int snesWidth = IPPU.RenderedScreenWidth;
- const int snesHeight = IPPU.RenderedScreenHeight;
- - const int width = min(snesWidth / 2, avi_width);
- - const int height = min(snesHeight, avi_height);
- + const bool snesInterlaced = (snesHeight > SNES_HEIGHT_EXTENDED);
- + const int snesVerticalScale = snesInterlaced ? 2 : 1;
- + const int width = std::min(snesWidth / 2, avi_width);
- + const int height = std::min(snesHeight / snesVerticalScale, avi_height);
- const int pitch = GFX.Pitch;
- #ifdef LSB_FIRST
- const bool order_is_rgb = (GUI.RedShift < GUI.BlueShift);
- #else
- const bool order_is_rgb = (GUI.RedShift > GUI.BlueShift);
- #endif
- - const int src_step = pitch - width * 2 * 2;
- + const int src_step = (pitch - width * 2 * 2) + (snesInterlaced ? pitch : 0);
- const int dst_step = -(avi_pitch + width * 3);
- const int image_offset = (avi_height - height) * avi_pitch;
- uint16 *s = GFX.Screen;
- @@ -1260,6 +1270,11 @@ void BuildAVIVideoFrame1XHiRes (void)
- {
- // Order is RGB
- uint32 pixel = Interp(s[0],s[1]);
- + if (snesInterlaced)
- + {
- + uint32 pixel2 = Interp(s[pitch],s[pitch + 1]);
- + pixel = Interp(pixel,pixel2);
- + }
- s += 2;
- *(d + 0) = (pixel >> (11 - 3)) & 0xf8;
- *(d + 1) = (pixel >> (6 - 3)) & 0xf8;
- @@ -1270,6 +1285,11 @@ void BuildAVIVideoFrame1XHiRes (void)
- {
- // Order is BGR
- uint32 pixel = Interp(s[0],s[1]);
- + if (snesInterlaced)
- + {
- + uint32 pixel2 = Interp(s[pitch],s[pitch + 1]);
- + pixel = Interp(pixel,pixel2);
- + }
- s += 2;
- *(d + 0) = (pixel & 0x1f) << 3;
- *(d + 1) = (pixel >> (6 - 3)) & 0xf8;
- @@ -1292,21 +1312,23 @@ void BuildAVIVideoFrame2XHiRes (void)
- {
- const int snesWidth = IPPU.RenderedScreenWidth;
- const int snesHeight = IPPU.RenderedScreenHeight;
- - const int width = min(snesWidth, avi_width);
- - const int height = min(snesHeight, avi_height / 2);
- + const bool snesInterlaced = (snesHeight > SNES_HEIGHT_EXTENDED);
- + const int snesVerticalScale = snesInterlaced ? 2 : 1;
- + const int width = std::min(snesWidth, avi_width);
- + const int height = std::min(snesHeight * 2 / snesVerticalScale, avi_height);
- const int pitch = GFX.Pitch;
- #ifdef LSB_FIRST
- const bool order_is_rgb = (GUI.RedShift < GUI.BlueShift);
- #else
- const bool order_is_rgb = (GUI.RedShift > GUI.BlueShift);
- #endif
- - const int src_step[2] = { -width * 2, pitch - width * 2 };
- + const int src_step[2] = { -width * 2 + (snesInterlaced ? pitch : 0), -width * 2 + pitch };
- const int dst_step = -(avi_pitch + width * 3);
- - const int image_offset = (avi_height - height * 2) * avi_pitch;
- + const int image_offset = (avi_height - height) * avi_pitch;
- uint16 *s = GFX.Screen;
- uint8 *d = &avi_buffer[(avi_height - 1) * avi_pitch];
- - for(int y = 0; y < height * 2; y++)
- + for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- @@ -1371,11 +1393,15 @@ void DoAVIOpen(const TCHAR* filename)
- avi_skip_frames = Settings.SkipFrames;
- if(GUI.AVIHiRes && avi_width <= SNES_WIDTH)
- - avi_width = SNES_WIDTH*2;
- + avi_width = SNES_WIDTH * 2;
- else if(!GUI.AVIHiRes && avi_width > SNES_WIDTH)
- avi_width = SNES_WIDTH;
- - if(GUI.HeightExtend && avi_height < SNES_HEIGHT_EXTENDED)
- + if (avi_height > SNES_HEIGHT_EXTENDED)
- + avi_height /= 2;
- + if(GUI.HeightExtend)
- avi_height = SNES_HEIGHT_EXTENDED;
- + else
- + avi_height = std::max(SNES_HEIGHT, avi_height);
- if(GUI.AVIHiRes)
- avi_height *= 2;
- if(avi_height % 2 != 0) // most codecs can't handle odd-height images
- @@ -1492,7 +1518,6 @@ void DoAVIVideoFrame(SSurface* source_surface)
- // convert to bitdepth 24
- const int snesWidth = IPPU.RenderedScreenWidth;
- - const int snesHeight = IPPU.RenderedScreenHeight;
- if(snesWidth < SNES_WIDTH*2) // normal
- {
- if(avi_width < snesWidth*2) // 1x
- --
- 1.7.3.1.msysgit.0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement