diff --git a/trunk/src/drivers/common/nes_ntsc.c b/trunk/src/drivers/common/nes_ntsc.c index 83777802..36c8eb15 100644 --- a/trunk/src/drivers/common/nes_ntsc.c +++ b/trunk/src/drivers/common/nes_ntsc.c @@ -24,7 +24,7 @@ nes_ntsc_setup_t const nes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, #define alignment_count 3 #define burst_count 3 #define rescale_in 8 -#define rescale_out 6 +#define rescale_out 7 #define artifacts_mid 1.0f #define fringing_mid 1.0f @@ -81,14 +81,13 @@ static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out ) } } -void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup, int bpp, int multiplier ) +void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup, int bpp ) { int merge_fields; int entry; init_t impl; float gamma_factor; - OutputMultiplier = multiplier; OutputDepth = bpp * 8; if ( !setup ) @@ -244,18 +243,12 @@ void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup, int bpp, in #ifndef NES_NTSC_NO_BLITTERS void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* input, long in_row_width, - int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch ) + int burst_phase, int emphasis, int in_width, int in_height, void* rgb_out, long out_pitch ) { int chunk_count = (in_width - 1) / nes_ntsc_in_chunk; - int TempMultiplier = OutputMultiplier * 3; - if (TempMultiplier > 7) - TempMultiplier = 7; - for ( ; in_height; --in_height ) { - int out; - for ( out = OutputMultiplier; out; --out ) { NES_NTSC_IN_T const* line_in = input; NES_NTSC_BEGIN_ROW( ntsc, burst_phase, nes_ntsc_black, nes_ntsc_black, NES_NTSC_ADJ_IN( *line_in ) ); nes_ntsc_out_t* restrict line_out = (nes_ntsc_out_t*) rgb_out; @@ -297,7 +290,6 @@ void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* input, long in_ NES_NTSC_RGB_OUT( 5, line_out [5], OutputDepth ); NES_NTSC_RGB_OUT( 6, line_out [6], OutputDepth ); rgb_out = (char*) rgb_out + out_pitch; - } burst_phase = (burst_phase + 1) % nes_ntsc_burst_count; input += in_row_width; diff --git a/trunk/src/drivers/common/nes_ntsc.h b/trunk/src/drivers/common/nes_ntsc.h index dba8476d..8b629c69 100644 --- a/trunk/src/drivers/common/nes_ntsc.h +++ b/trunk/src/drivers/common/nes_ntsc.h @@ -54,15 +54,16 @@ extern nes_ntsc_setup_t const nes_ntsc_monochrome;/* desaturated + artifacts */ /* Initializes and adjusts parameters. Can be called multiple times on the same nes_ntsc_t object. Can pass NULL for either parameter. */ typedef struct nes_ntsc_t nes_ntsc_t; -void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup, int bpp, int multiplier ); +void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup, int bpp ); /* Filters one or more rows of pixels. Input pixels are 6/9-bit palette indicies. -In_row_width is the number of pixels to get to the next input row. Out_pitch +In_row_width is the number of pixels to get to the next input row. Emphasis is +the emphasis bits to bitwise-OR with all pixels in the input data. Out_pitch is the number of *bytes* to get to the next output row. Output pixel format is set by NES_NTSC_OUT_DEPTH (defaults to 16-bit RGB). */ void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* nes_in, - long in_row_width, int burst_phase, int in_width, int in_height, - void* rgb_out, long out_pitch ); + long in_row_width, int burst_phase, int emphasis, int in_width, + int in_height, void* rgb_out, long out_pitch ); /* Number of output pixels written by blitter for given input width. Width might be rounded down slightly; use NES_NTSC_IN_WIDTH() on result to find rounded diff --git a/trunk/src/drivers/common/nes_ntsc_config.h b/trunk/src/drivers/common/nes_ntsc_config.h index 76b2c43a..4808ac27 100644 --- a/trunk/src/drivers/common/nes_ntsc_config.h +++ b/trunk/src/drivers/common/nes_ntsc_config.h @@ -5,7 +5,7 @@ /* Uncomment to enable emphasis support and use a 512 color palette instead of the base 64 color palette. */ -/*#define NES_NTSC_EMPHASIS 1*/ +#define NES_NTSC_EMPHASIS 1 /* The following affect the built-in blitter only; a custom blitter can handle things however it wants. */ @@ -21,7 +21,7 @@ if you enable emphasis above. */ // CUSTOM: (XBuf uses bit 0x80, and has palettes above 0x3f for LUA) /* Each raw pixel input value is passed through this. You might want to mask the pixel index if you use the high bits as flags, etc. */ -#define NES_NTSC_ADJ_IN( in ) in & 0x3f +#define NES_NTSC_ADJ_IN( in ) ((in & 0x3f) | emphasis) /* For each pixel, this is the basic operation: output_color = color_palette [NES_NTSC_ADJ_IN( NES_NTSC_IN_T )] */ diff --git a/trunk/src/drivers/common/vidblit.cpp b/trunk/src/drivers/common/vidblit.cpp index 36f492d1..813e17b5 100644 --- a/trunk/src/drivers/common/vidblit.cpp +++ b/trunk/src/drivers/common/vidblit.cpp @@ -36,6 +36,8 @@ extern u8 *XDBuf; extern u8 *XDBackBuf; extern pal *palo; +#include "../../ppu.h" // for PPU[] + nes_ntsc_t* nes_ntsc; uint8 burst_phase = 0; @@ -110,7 +112,6 @@ int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int // -Video Modes Tag- if(specfilt == 3) // NTSC 2x { - int multi = (2 * 2); //nes_ntsc variables nes_ntsc_setup_t ntsc_setup = nes_ntsc_composite; @@ -134,8 +135,8 @@ int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int if ( nes_ntsc ) { - nes_ntsc_init( nes_ntsc, &ntsc_setup, b, 2 ); - ntscblit = (uint8*)FCEU_dmalloc(256*257*b*multi); //Need to add multiplier for larger sizes + nes_ntsc_init( nes_ntsc, &ntsc_setup, b ); + ntscblit = (uint8*)FCEU_dmalloc(602*257*b); } } // -Video Modes Tag- @@ -799,14 +800,19 @@ void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, { case 4: if ( nes_ntsc && GameInfo->type!=GIT_NSF) { + int outxr = 301; + //if(xr == 282) outxr = 282; //hack for windows burst_phase ^= 1; - nes_ntsc_blit( nes_ntsc, (unsigned char*)src, xr, burst_phase, xr, yr, ntscblit, xr * Bpp * xscale ); - - //Multiply 4 by the multiplier on output, because it's 4 bpp - //Top 2 lines = line 3, due to distracting flicker - //memcpy(dest,ntscblit+(Bpp * xscale)+(Bpp * xr * xscale),(Bpp * xr * xscale)); - //memcpy(dest+(Bpp * xr * xscale),ntscblit+(Bpp * xscale)+(Bpp * xr * xscale * 2),(Bpp * xr * xscale)); - memcpy(dest+(Bpp * xr * xscale),ntscblit+(Bpp * xscale),(xr*yr*Bpp*xscale*yscale)); + nes_ntsc_blit( nes_ntsc, (unsigned char*)src, xr, burst_phase, (PPU[1] >> 5) << 6, xr, yr, ntscblit, (2*outxr) * Bpp ); + + const uint8 *in = ntscblit + (Bpp * xscale); + uint8 *out = dest; + const int in_stride = Bpp * outxr * 2; + const int out_stride = Bpp * outxr * xscale; + for( int y = 0; y < yr; y++, in += in_stride, out += 2*out_stride ) { + memcpy(out, in, Bpp * outxr * xscale); + memcpy(out + out_stride, in, Bpp * outxr * xscale); + } } else { pinc=pitch-((xr*xscale)<<2); for(y=yr;y;y--,src+=256-xr) diff --git a/trunk/src/drivers/sdl/sdl-video.cpp b/trunk/src/drivers/sdl/sdl-video.cpp index cfef9867..e03beeff 100644 --- a/trunk/src/drivers/sdl/sdl-video.cpp +++ b/trunk/src/drivers/sdl/sdl-video.cpp @@ -342,7 +342,7 @@ InitVideo(FCEUGI *gi) g_config->getOption("SDL.XScale", &s_exs); g_config->getOption("SDL.YScale", &s_eys); g_config->getOption("SDL.SpecialFX", &s_eefx); - + // -Video Modes Tag- if(s_sponge) { if(s_sponge <= 3 && s_sponge >= 1) @@ -363,12 +363,20 @@ InitVideo(FCEUGI *gi) { s_exs = s_eys = 1; } + if(s_sponge == 3) { + xres = 301 * s_exs; + } s_eefx = 0; if(s_sponge == 1 || s_sponge == 4) { desbpp = 32; } } + int scrw = NWIDTH * s_exs; + if(s_sponge == 3) { + scrw = 301 * s_exs; + } + #ifdef OPENGL if(!s_useOpenGL) { s_exs = (int)s_exs; @@ -412,8 +420,7 @@ InitVideo(FCEUGI *gi) } #endif - s_screen = SDL_SetVideoMode((int)(NWIDTH * s_exs), - (int)(s_tlines * s_eys), + s_screen = SDL_SetVideoMode(scrw, (int)(s_tlines * s_eys), desbpp, flags); if(!s_screen) { FCEUD_PrintError(SDL_GetError()); @@ -691,6 +698,13 @@ BlitScreen(uint8 *XBuf) SDL_UnlockSurface(TmpScreen); } + int scrw; + if(s_sponge == 3) { // NTSC 2x + scrw = 301; + } else { + scrw = NWIDTH; + } + // if we have a hardware video buffer, do a fast video->video copy if(s_BlitBuf) { SDL_Rect srect; @@ -698,12 +712,12 @@ BlitScreen(uint8 *XBuf) srect.x = 0; srect.y = 0; - srect.w = NWIDTH; + srect.w = scrw; srect.h = s_tlines; drect.x = 0; drect.y = 0; - drect.w = (Uint16)(s_exs * NWIDTH); + drect.w = (Uint16)(s_exs * scrw); drect.h = (Uint16)(s_eys * s_tlines); SDL_BlitSurface(s_BlitBuf, &srect, s_screen, &drect); @@ -714,7 +728,7 @@ BlitScreen(uint8 *XBuf) //TODO - SDL2 #else SDL_UpdateRect(s_screen, xo, yo, - (Uint32)(NWIDTH * s_exs), (Uint32)(s_tlines * s_eys)); + (Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys)); #endif #ifdef CREATE_AVI diff --git a/trunk/src/drivers/win/main.h b/trunk/src/drivers/win/main.h index e4764950..3589e816 100644 --- a/trunk/src/drivers/win/main.h +++ b/trunk/src/drivers/win/main.h @@ -11,6 +11,7 @@ #define VNSCLIP ((eoptions&EO_CLIPSIDES)?8:0) #define VNSWID ((eoptions&EO_CLIPSIDES)?240:256) +#define VNSWID_NU(XR) (VNSWID==256?XR:((int)(XR/256.f*240))) #define SO_FORCE8BIT 1 #define SO_SECONDARY 2 diff --git a/trunk/src/drivers/win/video.cpp b/trunk/src/drivers/win/video.cpp index b1294575..c86e61b4 100644 --- a/trunk/src/drivers/win/video.cpp +++ b/trunk/src/drivers/win/video.cpp @@ -237,7 +237,13 @@ void recalculateBestFitRect(int width, int height) if (!lpDD7) return; // DirectDraw isn't initialized yet - double screen_width = VNSWID; + int xres = 256; + if(fullscreen && vmodes[0].special==3) + xres=301; + if(!fullscreen && winspecial==3) + xres=301; + + double screen_width = VNSWID_NU(xres); double screen_height = FSettings.TotalScanlines(); if (eoptions & EO_TVASPECT) screen_width = ceil(screen_height * (screen_width / 256) * (tvAspectX / tvAspectY)); @@ -314,6 +320,7 @@ int SetVideoMode(int fs) if(!fs) { + int xres = 256; // -Video Modes Tag- if(winspecial <= 3 && winspecial >= 1) specmul = 2; @@ -326,6 +333,9 @@ int SetVideoMode(int fs) else specmul = 1; + if(winspecial == 3) + xres = 301; + ShowCursorAbs(1); windowedfailed=1; HideFWindow(0); @@ -357,7 +367,7 @@ int SetVideoMode(int fs) ddsdback.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsdback.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN; - ddsdback.dwWidth=256 * specmul; + ddsdback.dwWidth=xres*specmul; ddsdback.dwHeight=FSettings.TotalScanlines() * ((winspecial == 9) ? 1 : specmul); if (directDrawModeWindowed == DIRECTDRAW_MODE_SURFACE_IN_RAM) @@ -414,6 +424,8 @@ int SetVideoMode(int fs) } else { + int xres = 256; + //Following is full-screen if(vmod == 0) // Custom mode { @@ -428,6 +440,9 @@ int SetVideoMode(int fs) specmul = 3; else specmul = 1; + + if(vmodes[0].special==3) + xres = 301; } HideFWindow(1); @@ -453,7 +468,7 @@ int SetVideoMode(int fs) ddsdback.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsdback.ddsCaps.dwCaps= DDSCAPS_OFFSCREENPLAIN; - ddsdback.dwWidth=256 * specmul; //vmodes[vmod].srect.right; + ddsdback.dwWidth=xres * specmul; //vmodes[vmod].srect.right; ddsdback.dwHeight=FSettings.TotalScanlines() * ((vmodes[0].special == 9) ? 1 : specmul); //vmodes[vmod].srect.bottom; if (directDrawModeFullscreen == DIRECTDRAW_MODE_SURFACE_IN_RAM) @@ -586,6 +601,7 @@ static void BlitScreenWindow(unsigned char *XBuf) if (!lpDDSBack) return; // -Video Modes Tag- + int xres = 256; if(winspecial <= 3 && winspecial >= 1) specialmul = 2; else if(winspecial >= 4 && winspecial <= 5) @@ -596,8 +612,11 @@ static void BlitScreenWindow(unsigned char *XBuf) specialmul = 3; else specialmul = 1; + if(winspecial == 3) + xres = 301; + srect.top=srect.left=0; - srect.right=VNSWID * specialmul; + srect.right=VNSWID_NU(xres) * specialmul; srect.bottom=FSettings.TotalScanlines() * ((winspecial == 9) ? 1 : specialmul); if(PaletteChanged==1) @@ -625,7 +644,10 @@ static void BlitScreenWindow(unsigned char *XBuf) memset(ScreenLoc,0,pitch*ddsdback.dwHeight); veflags&=~1; } - Blit8ToHigh(XBuf+FSettings.FirstSLine*256+VNSCLIP,ScreenLoc, VNSWID, FSettings.TotalScanlines(), pitch,specialmul,specialmul); + //NOT VNSWID_NU ON PURPOSE! this is where 256 gets turned to 301 + //we'll actually blit a subrectangle later if we clipped the sides + //MOREOVER: we order this to scale the whole area no matter what; a subrectangle will come out later (right?) + Blit8ToHigh(XBuf+FSettings.FirstSLine*256+VNSCLIP,ScreenLoc, 256, FSettings.TotalScanlines(), pitch,specialmul,specialmul); IDirectDrawSurface7_Unlock(lpDDSBack, NULL); @@ -727,6 +749,7 @@ static void BlitScreenFull(uint8 *XBuf) //uint8 y; //mbg merge 7/17/06 removed RECT srect, drect; LPDIRECTDRAWSURFACE7 lpDDSVPrimary; + int xres = 256; int specmul; // Special scaler size multiplier // -Video Modes Tag- if(vmodes[0].special <= 3 && vmodes[0].special >= 1) @@ -740,6 +763,9 @@ static void BlitScreenFull(uint8 *XBuf) else specmul = 1; + if(vmodes[0].special == 3) + xres = 301; + if(fssync==3) lpDDSVPrimary=lpDDSDBack; else @@ -778,7 +804,7 @@ static void BlitScreenFull(uint8 *XBuf) srect.top=0; srect.left=0; - srect.right=VNSWID * specmul; + srect.right=VNSWID_NU(xres) * specmul; srect.bottom=FSettings.TotalScanlines() * ((vmodes[0].special == 9) ? 1 : specmul); //if(vmodes[vmod].flags&VMDF_STRFS) @@ -955,21 +981,21 @@ static void BlitScreenFull(uint8 *XBuf) if(vmodes[vmod].special) ScreenLoc += (vmodes[vmod].drect.left*(bpp>>3)) + ((vmodes[vmod].drect.top)*pitch); else - ScreenLoc+=((vmodes[vmod].x-VNSWID)>>1)*(bpp>>3)+(((vmodes[vmod].y-FSettings.TotalScanlines())>>1))*pitch; + ScreenLoc+=((vmodes[vmod].x-VNSWID_NU(xres))>>1)*(bpp>>3)+(((vmodes[vmod].y-FSettings.TotalScanlines())>>1))*pitch; } if(bpp>=16) { - Blit8ToHigh(XBuf+FSettings.FirstSLine*256+VNSCLIP,(uint8*)ScreenLoc, VNSWID, FSettings.TotalScanlines(), pitch,specmul,specmul); //mbg merge 7/17/06 added cast + Blit8ToHigh(XBuf+FSettings.FirstSLine*256+VNSCLIP,(uint8*)ScreenLoc, VNSWID_NU(xres), FSettings.TotalScanlines(), pitch,specmul,specmul); //mbg merge 7/17/06 added cast } else { XBuf+=FSettings.FirstSLine*256+VNSCLIP; // -Video Modes Tag- if(vmodes[vmod].special) - Blit8To8(XBuf,(uint8*)ScreenLoc, VNSWID, FSettings.TotalScanlines(), pitch,vmodes[vmod].xscale,vmodes[vmod].yscale,0,vmodes[vmod].special); //mbg merge 7/17/06 added cast + Blit8To8(XBuf,(uint8*)ScreenLoc, VNSWID_NU(xres), FSettings.TotalScanlines(), pitch,vmodes[vmod].xscale,vmodes[vmod].yscale,0,vmodes[vmod].special); //mbg merge 7/17/06 added cast else - Blit8To8(XBuf,(uint8*)ScreenLoc, VNSWID, FSettings.TotalScanlines(), pitch,1,1,0,0); //mbg merge 7/17/06 added cast + Blit8To8(XBuf,(uint8*)ScreenLoc, VNSWID_NU(xres), FSettings.TotalScanlines(), pitch,1,1,0,0); //mbg merge 7/17/06 added cast } } @@ -1115,6 +1141,9 @@ static int RecalcCustom(void) { vmdef *cmode = &vmodes[0]; + //don't see how ntsc could make it through here + int xres = 256; + if ((cmode->x <= 0) || (cmode->y <= 0)) ResetCustomMode(); @@ -1140,7 +1169,7 @@ static int RecalcCustom(void) cmode->flags|=VMDF_DXBLT; - if(VNSWID*cmode->xscale>cmode->x) + if(VNSWID_NU(xres)*cmode->xscale>cmode->x) { if(cmode->special) { @@ -1175,8 +1204,8 @@ static int RecalcCustom(void) cmode->drect.top=(cmode->y-(FSettings.TotalScanlines()*cmode->yscale))>>1; cmode->drect.bottom=cmode->drect.top+FSettings.TotalScanlines()*cmode->yscale; - cmode->drect.left=(cmode->x-(VNSWID*cmode->xscale))>>1; - cmode->drect.right=cmode->drect.left+VNSWID*cmode->xscale; + cmode->drect.left=(cmode->x-(VNSWID_NU(xres)*cmode->xscale))>>1; + cmode->drect.right=cmode->drect.left+VNSWID_NU(xres)*cmode->xscale; } // -Video Modes Tag- @@ -1187,7 +1216,7 @@ static int RecalcCustom(void) //return(0); } - if(cmode->xx