win32: bilinear filter
This commit is contained in:
parent
9735a8a1fd
commit
da1bc169a1
|
@ -601,6 +601,10 @@
|
|||
RelativePath=".\filter\2xsai.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filter\bilinear.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filter\hq2x.cpp"
|
||||
>
|
||||
|
|
|
@ -717,6 +717,10 @@
|
|||
RelativePath=".\aviout.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filter\bilinear.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cheatsWin.cpp"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
/** Code adapted from Exult source code by Forgotten
|
||||
** Scale.cc - Trying to scale with bilinear interpolation.
|
||||
**
|
||||
** Written: 6/14/00 - JSF
|
||||
**/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
int systemRedShift = 10;
|
||||
int systemGreenShift = 0;
|
||||
int systemBlueShift = 5;
|
||||
|
||||
#define RGB1(r,g,b) ((r)>>3) << systemRedShift |\
|
||||
((g) >> 3) << systemGreenShift |\
|
||||
((b) >> 3) << systemBlueShift\
|
||||
|
||||
static void fill_rgb_row_16(u16 *from, int src_width, u8 *row, int width)
|
||||
{
|
||||
u8 *copy_start = row + src_width*3;
|
||||
u8 *all_stop = row + width*3;
|
||||
while (row < copy_start) {
|
||||
u16 color = *from++;
|
||||
*row++ = ((color >> systemRedShift) & 0x1f) << 3;
|
||||
*row++ = ((color >> systemGreenShift) & 0x1f) << 3;
|
||||
*row++ = ((color >> systemBlueShift) & 0x1f) << 3;
|
||||
}
|
||||
// any remaining elements to be written to 'row' are a replica of the
|
||||
// preceding pixel
|
||||
u8 *p = row-3;
|
||||
while (row < all_stop) {
|
||||
// we're guaranteed three elements per pixel; could unroll the loop
|
||||
// further, especially with a Duff's Device, but the gains would be
|
||||
// probably limited (judging by profiler output)
|
||||
*row++ = *p++;
|
||||
*row++ = *p++;
|
||||
*row++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
void Bilinear(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
|
||||
u8 *dstPtr, u32 dstPitch, int width, int height)
|
||||
{
|
||||
u8 row_cur[3*322];
|
||||
u8 row_next[3*322];
|
||||
u8 *rgb_row_cur = row_cur;
|
||||
u8 *rgb_row_next = row_next;
|
||||
|
||||
u16 *to = (u16 *)dstPtr;
|
||||
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
|
||||
|
||||
int from_width = width;
|
||||
u16 *from = (u16 *)srcPtr;
|
||||
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
|
||||
|
||||
for(int y = 0; y < height; y++) {
|
||||
u16 *from_orig = from;
|
||||
u16 *to_orig = to;
|
||||
|
||||
if (y+1 < height)
|
||||
fill_rgb_row_16(from+width, from_width, rgb_row_next,
|
||||
width+1);
|
||||
else
|
||||
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
|
||||
|
||||
// every pixel in the src region, is extended to 4 pixels in the
|
||||
// destination, arranged in a square 'quad'; if the current src
|
||||
// pixel is 'a', then in what follows 'b' is the src pixel to the
|
||||
// right, 'c' is the src pixel below, and 'd' is the src pixel to
|
||||
// the right and down
|
||||
u8 *cur_row = rgb_row_cur;
|
||||
u8 *next_row = rgb_row_next;
|
||||
u8 *ar = cur_row++;
|
||||
u8 *ag = cur_row++;
|
||||
u8 *ab = cur_row++;
|
||||
u8 *cr = next_row++;
|
||||
u8 *cg = next_row++;
|
||||
u8 *cb = next_row++;
|
||||
for(int x=0; x < width; x++) {
|
||||
u8 *br = cur_row++;
|
||||
u8 *bg = cur_row++;
|
||||
u8 *bb = cur_row++;
|
||||
u8 *dr = next_row++;
|
||||
u8 *dg = next_row++;
|
||||
u8 *db = next_row++;
|
||||
|
||||
// upper left pixel in quad: just copy it in
|
||||
*to++ = RGB1(*ar, *ag, *ab);
|
||||
|
||||
// upper right
|
||||
*to++ = RGB1((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
|
||||
|
||||
// lower left
|
||||
*to_odd++ = RGB1((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
|
||||
|
||||
// lower right
|
||||
*to_odd++ = RGB1((*ar+*br+*cr+*dr)>>2,
|
||||
(*ag+*bg+*cg+*dg)>>2,
|
||||
(*ab+*bb+*cb+*db)>>2);
|
||||
|
||||
// 'b' becomes 'a', 'd' becomes 'c'
|
||||
ar = br;
|
||||
ag = bg;
|
||||
ab = bb;
|
||||
cr = dr;
|
||||
cg = dg;
|
||||
cb = db;
|
||||
}
|
||||
|
||||
// the "next" rgb row becomes the current; the old current rgb row is
|
||||
// recycled and serves as the new "next" row
|
||||
u8 *temp;
|
||||
temp = rgb_row_cur;
|
||||
rgb_row_cur = rgb_row_next;
|
||||
rgb_row_next = temp;
|
||||
|
||||
// update the pointers for start of next pair of lines
|
||||
from = (u16 *)((u8 *)from_orig + srcPitch);
|
||||
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
|
||||
to_odd = (u16 *)((u8 *)to + dstPitch);
|
||||
}
|
||||
}
|
||||
|
||||
struct SSurface {
|
||||
unsigned char *Surface;
|
||||
|
||||
unsigned int Pitch;
|
||||
unsigned int Width, Height;
|
||||
};
|
||||
|
||||
void BilinearPlus(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
|
||||
u8 *dstPtr, u32 dstPitch, int width, int height)
|
||||
{
|
||||
u8 row_cur[3*322];
|
||||
u8 row_next[3*322];
|
||||
u8 *rgb_row_cur = row_cur;
|
||||
u8 *rgb_row_next = row_next;
|
||||
|
||||
u16 *to = (u16 *)dstPtr;
|
||||
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
|
||||
|
||||
int from_width = width;
|
||||
u16 *from = (u16 *)srcPtr;
|
||||
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
|
||||
|
||||
for(int y = 0; y < height; y++) {
|
||||
u16 *from_orig = from;
|
||||
u16 *to_orig = to;
|
||||
|
||||
if (y+1 < height)
|
||||
fill_rgb_row_16(from+width, from_width, rgb_row_next,
|
||||
width+1);
|
||||
else
|
||||
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
|
||||
|
||||
// every pixel in the src region, is extended to 4 pixels in the
|
||||
// destination, arranged in a square 'quad'; if the current src
|
||||
// pixel is 'a', then in what follows 'b' is the src pixel to the
|
||||
// right, 'c' is the src pixel below, and 'd' is the src pixel to
|
||||
// the right and down
|
||||
u8 *cur_row = rgb_row_cur;
|
||||
u8 *next_row = rgb_row_next;
|
||||
u8 *ar = cur_row++;
|
||||
u8 *ag = cur_row++;
|
||||
u8 *ab = cur_row++;
|
||||
u8 *cr = next_row++;
|
||||
u8 *cg = next_row++;
|
||||
u8 *cb = next_row++;
|
||||
for(int x=0; x < width; x++) {
|
||||
u8 *br = cur_row++;
|
||||
u8 *bg = cur_row++;
|
||||
u8 *bb = cur_row++;
|
||||
u8 *dr = next_row++;
|
||||
u8 *dg = next_row++;
|
||||
u8 *db = next_row++;
|
||||
|
||||
// upper left pixel in quad: just copy it in
|
||||
//*to++ = manip.rgb(*ar, *ag, *ab);
|
||||
#ifdef USE_ORIGINAL_BILINEAR_PLUS
|
||||
*to++ = RGB(
|
||||
(((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
|
||||
(((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
|
||||
(((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
|
||||
#else
|
||||
*to++ = RGB1(
|
||||
(((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
|
||||
(((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
|
||||
(((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
|
||||
#endif
|
||||
|
||||
// upper right
|
||||
*to++ = RGB1((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
|
||||
|
||||
// lower left
|
||||
*to_odd++ = RGB1((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
|
||||
|
||||
// lower right
|
||||
*to_odd++ = RGB1((*ar+*br+*cr+*dr)>>2,
|
||||
(*ag+*bg+*cg+*dg)>>2,
|
||||
(*ab+*bb+*cb+*db)>>2);
|
||||
|
||||
// 'b' becomes 'a', 'd' becomes 'c'
|
||||
ar = br;
|
||||
ag = bg;
|
||||
ab = bb;
|
||||
cr = dr;
|
||||
cg = dg;
|
||||
cb = db;
|
||||
}
|
||||
|
||||
// the "next" rgb row becomes the current; the old current rgb row is
|
||||
// recycled and serves as the new "next" row
|
||||
u8 *temp;
|
||||
temp = rgb_row_cur;
|
||||
rgb_row_cur = rgb_row_next;
|
||||
rgb_row_next = temp;
|
||||
|
||||
// update the pointers for start of next pair of lines
|
||||
from = (u16 *)((u8 *)from_orig + srcPitch);
|
||||
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
|
||||
to_odd = (u16 *)((u8 *)to + dstPitch);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderBilinear (SSurface Src, SSurface Dst)
|
||||
{
|
||||
|
||||
unsigned char *lpSrc, *lpDst;
|
||||
|
||||
lpSrc = Src.Surface;
|
||||
lpDst = Dst.Surface;
|
||||
|
||||
Bilinear (lpSrc, Src.Pitch,
|
||||
lpSrc,
|
||||
lpDst, Dst.Pitch, Src.Width, Src.Height);
|
||||
|
||||
}
|
|
@ -9,4 +9,5 @@ void RenderHQ2X (SSurface Src, SSurface Dst);
|
|||
void Render2xSaI (SSurface Src, SSurface Dst);
|
||||
void RenderSuper2xSaI (SSurface Src, SSurface Dst);
|
||||
void RenderSuperEagle (SSurface Src, SSurface Dst);
|
||||
void RenderScanline( SSurface Src, SSurface Dst);
|
||||
void RenderScanline( SSurface Src, SSurface Dst);
|
||||
void RenderBilinear( SSurface Src, SSurface Dst);
|
|
@ -2491,6 +2491,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
MainWindow->checkMenu(IDM_RENDER_SUPER2XSAI, MF_BYCOMMAND | video.currentfilter == video.SUPER2XSAI ? MF_CHECKED:MF_UNCHECKED);
|
||||
MainWindow->checkMenu(IDM_RENDER_SUPEREAGLE, MF_BYCOMMAND | video.currentfilter == video.SUPEREAGLE ? MF_CHECKED:MF_UNCHECKED);
|
||||
MainWindow->checkMenu(IDM_RENDER_SCANLINE, MF_BYCOMMAND | video.currentfilter == video.SCANLINE ? MF_CHECKED:MF_UNCHECKED);
|
||||
MainWindow->checkMenu(IDM_RENDER_BILINEAR, MF_BYCOMMAND | video.currentfilter == video.BILINEAR ? MF_CHECKED:MF_UNCHECKED);
|
||||
|
||||
//Language selection
|
||||
|
||||
|
@ -2843,6 +2844,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
video.setfilter(video.SCANLINE);
|
||||
FilterUpdate(hwnd);
|
||||
break;
|
||||
case IDM_RENDER_BILINEAR:
|
||||
video.setfilter(video.BILINEAR);
|
||||
FilterUpdate(hwnd);
|
||||
break;
|
||||
case IDM_STATE_LOAD:
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
|
|
|
@ -168,6 +168,7 @@
|
|||
#define IDM_RENDER_SUPER2XSAI 554
|
||||
#define IDM_RENDER_SUPEREAGLE 555
|
||||
#define IDM_RENDER_SCANLINE 556
|
||||
#define IDM_RENDER_BILINEAR 557
|
||||
#define IDD_IO_REG 601
|
||||
#define IDM_RECORD_MOVIE 602
|
||||
#define IDM_PLAY_MOVIE 603
|
||||
|
|
Binary file not shown.
|
@ -20,7 +20,8 @@ public:
|
|||
_2XSAI,
|
||||
SUPER2XSAI,
|
||||
SUPEREAGLE,
|
||||
SCANLINE
|
||||
SCANLINE,
|
||||
BILINEAR
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,6 +83,9 @@ public:
|
|||
case SCANLINE:
|
||||
RenderScanline(src, dst);
|
||||
break;
|
||||
case BILINEAR:
|
||||
RenderBilinear(src, dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue