PhilExile Posted September 20, 2011 Posted September 20, 2011 (edited) Hello, I had a chance to do some comparison shots of the NES favorite, Super Mario Bros. See below for the interesting results. Note: I only did SD tests for this round. I may add HDTV versions later. Please make sure to click on each screen to view it full size. NES - 240p, Composite The original hardware. Note: The blue sky continues on the right side of the screen. WII - 240p, Component Wii Virtual Console in action. I was actually surprised about how saturated the image was. However, upon closer inspection it lookslike the right values, just bumped up a lot. XBOX - Nestopia 240p, Frosty VGA Cable -> Extron Emotia The color values here aren't quite as saturated and I sorta prefer this to the Virtual Console. The image isn't quite as sharp here either, however, thisis probably due to my having the 'peak' set to minimum on my VGA switch - so this could be sharper. Also, the Extron Emotia has a horizontal stretch dial that can increase the default image size. This works better than I thought. When looking atthese images, I can barely tell the difference - width wise - between this and the Virtual Console version. (Another reason to get an Emotia) XBOX - Nestopia 480i, Component Standard component output here. It actually looks pretty good, but the image is fluttery due to it being 480i. Colors are nice and bright. The onlydownside here is that the 512 image width is apparent. The picture isn't too great, just focus on the lower portion of the image. XBOX - Nestopia 480i, S-Video Standard s-video output here. Again, the image looks really good, but the colors are a lot less vibrant. (More noticeable in person) (Continues....) Edited September 20, 2011 by PhilExile
PhilExile Posted September 20, 2011 Author Posted September 20, 2011 CLOSEUPS NES - 240p, Composite WII - 240p, Component XBOX - Nestopia 240p, Frosty VGA Cable -> Extron Emotia XBOX - Nestopia 480i, Component XBOX - Nestopia 480i, S-Video
PhilExile Posted September 20, 2011 Author Posted September 20, 2011 LAST ONES - The Pole I thought this was interesting because of the texture that is created in the pole at the end of a Mario level by composite output. We can also take a look at Blaarg's NTSC filter - Composite compared to the real composite output on the same monitor. NES - 240p, Composite XBOX - Nestopia 240p, Frosty VGA Cable -> Extron Emotia - BLAARG'S NTSC FILTER - COMPOSITE It looks pretty good, but its not 100% spot on. Though, I think you can tweak this filter to your liking. Also, the video output quality may vary fromNES to NES. WII - 240p, Component XBOX - Nestopia 240p, Frosty VGA Cable -> Extron Emotia XBOX - Nestopia 480i, Component XBOX - Nestopia 480i, S-Video That is all.
+ T + Posted September 20, 2011 Posted September 20, 2011 Now this is good stuff. But could you ditch those ridiculous pixel-perfect values and post up some shots of the Xbox screen scaled to the same proportions as the NES display? Since most people don't have the extra hardware to produce the 240p output.
PhilExile Posted September 20, 2011 Author Posted September 20, 2011 I don't see the point. It would introduce pixel distortion (probably on visible when the screen is moving) and bilinear would need to be turned on to mask it.
Cospefogo Posted September 20, 2011 Posted September 20, 2011 Great stuff Phil!Thanks for the pictures. But +T+, if we scale the Xbox screen to any given proportionthe aspect ratio will be broken, and there will be artifacts in thescreen while it is moving... ...unless you are in bilinear or trilinear, of course. Well, I am a bit confused now.Where are we all trying to go from here? C.
PhilExile Posted September 20, 2011 Author Posted September 20, 2011 (edited) Ha, no where! I determined with this new round of test that my previous experiment with SUPER STAR WARS on Snes9x was flawed. I had 10x11 pixel ratio turned on by mistake on my SDTV, Sony PVM setup. Basically, you can mimic the 'look' of SNES/NES games with your Xbox emulators on either SD or HDTVs. Just for clarity: SDTV Setup - Buy an Extron Emotia | See here for more details: http://scanlines.hazard-city.de/ - Buy either a Frosty VGA cable, YUV -> VGA converter, or build your own VGA cable- Set your dash/emulator to 480p- Set your emulator to 'perfect pixel' size - i.e. 512x448- Once everything is hooked up, stretch the horizontal size of the picture to the maximum on the Emotia- Flip the interlacing switch on the front of the Emotia to activate 240p HDTV Setup - Buy an SLG3000*- Buy a YUV -> VGA coverter (I've had spotty luck with the Frosty cable on modern HDTVs)- Set your dash/emulator to 480p - Set your emulator to 'perfect pixel' size - i.e. 512x448- Set the pixel mode to 10x11- On your TV, set the video mode to stretch to fill the screen. This is different on every TV, but you are basically taking the 4:3 signal from the Xbox and scaling it to fill the 16:9 viewing area of the TV * The SLG3000 (& VGA converter) wouldn't be necessary if scanlines were built into the emulator. I *think* this is planned for the next release of SNES9x by Madmab. Enjoy! Well, I am a bit confused now.Where are we all trying to go from here? Edited September 20, 2011 by PhilExile
+ T + Posted September 20, 2011 Posted September 20, 2011 (edited) Yes, you will have to enable hardware filtering and preferably the Simple2X filter to eliminate the blur that introduces. There is no way around this because, no matter what you do, the image must be upscaled. Since it cannot be stretched to an accurate size in the hardware, the stretching must be emulated in the software. The only way point filtering will be useful is if you intend to leave the screen at 512x448 which looks absolutely nothing like the output of the system and is therefore not viable. Yet again, I'm totally puzzled by this pixel-perfect stuff; it just looks silly to me. Hardware and software filtering is really the only option for anyone who wants their NES emulator to look as close as possible to an NES. EDIT: Just read your latest post. Obviously I'm talking about reproducing the look of the original system without having to purchase extra hardware. Edited September 20, 2011 by + T +
Cospefogo Posted September 20, 2011 Posted September 20, 2011 * The SLG3000 (& VGA converter) wouldn't be necessary if scanlines were built into the emulator. I *think* this is planned for the next release of SNES9x by Madmab. Hmmm... I have been helping MadMab to test his scanline filter attempts in MednafenX-NESbut we have been out of luck. MadMab was able to create the filter using some oldcode left behind inside Xport Atari800 emulator, however the filter was breaking the60fps framerate integrity in some games, for example, Akumajou Densetsu wasrunning in constant 42fps. Also, he was thinking to try to "import" the scanlines filter used in ZsneXbox, howeverthe whole filter is coded in the most devilish language of the world --- assembly.Assembly is evil. MadMab is doing his best. Ouch!C.
+ T + Posted September 20, 2011 Posted September 20, 2011 Also, he was thinking to try to "import" the scanlines filter used in ZsneXbox, howeverthe whole filter is coded in the most devilish language of the world --- assembly.Assembly is evil. MadMab is doing his best. Ouch!C.FBL's scanline filter isn't coded in assembly as far as I'm aware. Maybe he'd have more luck with that. I believe the exact same filter code is used in NestopiaX.
PhilExile Posted September 21, 2011 Author Posted September 21, 2011 (edited) XBOX - Mednafenx-NES 240p, Frosty VGA Cable -> Extron Emotia REDUX By turning up the peak on my VGA switch, I was able to sharpen the image. Now the image is on par with the Wii's Virtual Consoleemulator - the gold standard in my opinion. Not bad for a 10 year old console. Edited September 21, 2011 by PhilExile
madmab Posted September 21, 2011 Posted September 21, 2011 /*void Scanlines(u8 *srcPtr, u32 srcPitch, u8 *, u8 *dstPtr, u32 dstPitch, int width, int height) { __asm { mov eax, width; mov edx, srcPitch; shr eax, 2; shl eax, 3; sub edx, eax; mov srcPitch, edx; shr eax, 3; mov width, eax; mov esi, srcPtr; mov edi, dstPtr; mov edx, edi; add edx, dstPitch; mov ecx, height; pxor mm2, mm2; align 4; label0: mov eax, width; align 4; label1: movq mm0, qword ptr [esi]; movq mm1, mm0; punpcklwd mm0, qword ptr [esi]; punpckhwd mm1, qword ptr [esi]; movq qword ptr [edi], mm0; movq qword ptr [edx], mm2; movq qword ptr [edi + 8], mm1; movq qword ptr [edx + 8], mm2; add esi, 8; add edi, 16; add edx, 16; dec eax; jnz label1; add esi, srcPitch; add edi, dstPitch; add edx, dstPitch; dec ecx; jnz label0; ;emms; } }*/ #define RGB_LOW_BITS_MASK 0x0821 __int64 colorMask = ~((__int64)RGB_LOW_BITS_MASK | ((__int64)RGB_LOW_BITS_MASK << 16) | ((__int64)RGB_LOW_BITS_MASK << 32) | ((__int64)RGB_LOW_BITS_MASK << 48)); void ScanlinesTV(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) { __asm { mov esi, srcPtr; mov edi, dstPtr; mov edx, edi; add edx, dstPitch; mov ecx, height; movq mm7, colorMask; ;fix tiger heli and others mov ebx,srcPitch; shl ebx,1; mov eax,dstPitch; sub eax,ebx; add dstPitch,eax; mov eax, width; mov ebx, srcPitch; shl eax, 1; //width *2 sub ebx, eax; // srcpitch - width*2 mov srcPitch, ebx; shr eax, 3; // width /4 mov width, eax; align 4; label2: mov eax, width; mov ebx, dword ptr[esi]; align 4; label3: movq mm0, qword ptr [esi]; movq mm1, mm0; movq mm2, mm0; psllq mm1, 16; pand mm2, mm7; pinsrw mm1, ebx, 0; psrlw mm2, 1; pand mm1, mm7; pextrw ebx, mm0, 3; psrlw mm1, 1; paddw mm1, mm2; movq mm0, mm1; punpckhwd mm1, qword ptr [esi]; punpcklwd mm0, qword ptr [esi]; movq mm3, mm1; movq mm2, mm0; pand mm3, mm7; pand mm2, mm7; psrlw mm3, 1; psrlw mm2, 1; movq mm5, mm3; movq mm4, mm2; pand mm5, mm7; pand mm4, mm7; psrlw mm5, 1; psrlw mm4, 1; paddw mm3, mm5; paddw mm2, mm4; movq qword ptr [edi], mm0; movq qword ptr [edx], mm2; movq qword ptr [edi + 8], mm1; movq qword ptr [edx + 8], mm3; add esi, 8; add edi, 16; add edx, 16; dec eax; jnz label3; add esi, srcPitch; add edi, dstPitch; add edx, dstPitch; dec ecx; jnz label2; ;emms; } } Looks like ASM to me... Notice the first one is commented out. The one used by Zsnes.. copy640x480x16bwin ALIGN 32 %include "macros.mac" EXTSYM vesa2selec,vidbuffer,GUIOn,MMXSupport,resolutn,En2xSaI,antienab,scanlines EXTSYM hirestiledat,res512switch,curblank,spritetablea EXTSYM lineleft,_2xSaILineW,_2xSaISuperEagleLineW, _2xSaISuper2xSaILineW EXTSYM newengen,cfield,HalfTrans EXTSYM GUIOn2,FilteredGUI EXTSYM SpecialLine EXTSYM vidbufferofsb EXTSYM HalfTransB,HalfTransC SECTION .bss NEWSYM AddEndBytes, resd 1 ; Number of bytes between each line NEWSYM NumBytesPerLine, resd 1 ; Total number of bytes per line (1024+AddEndBytes) NEWSYM WinVidMemStart, resd 1 SECTION .text NEWSYM copy640x480x16bwin cmp byte[curblank],40h jne .startcopy ret .startcopy pushad mov esi,[vidbuffer] mov edi,[WinVidMemStart] add esi,16*2+256*2+32*2 cmp byte[GUIOn],1 je .not239 cmp byte[resolutn],239 jne .not239 add esi,8*288*2 .not239 xor eax,eax ; Check if interpolation mode cmp byte[FilteredGUI],0 jne .yi cmp byte[GUIOn2],1 je .nointerp .yi cmp byte[MMXSupport],1 jne .nommx cmp byte[En2xSaI],0 jne near Process2xSaIwin .nommx cmp byte[antienab],1 je near interpolate640x480x16bwin .nointerp mov dl,224 dec dl dec dl cmp byte[scanlines],1 je near .scanlines cmp byte[scanlines],3 je near .halfscanlines cmp byte[scanlines],2 je near .quartscanlines mov ebx,hirestiledat+1 cmp byte[newengen],0 je .loopa mov ebx,SpecialLine+1 .loopa mov ecx,256 cmp byte[ebx],1 je near .yeshires cmp byte[GUIOn],1 je .ignorehr cmp byte[ebx],1 ja near .yeshiresng .ignorehr cmp byte[MMXSupport],1 je near .mmx .a mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .a sub esi,256*2 add edi,[AddEndBytes] mov ecx,256 .a2 mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .a2 .return add esi,64 add edi,[AddEndBytes] inc ebx dec dl jnz near .loopa popad xor byte[res512switch],1 cmp byte[MMXSupport],1 je .mmx2 ret .mmx2 emms ret .yeshires mov byte[ebx],0 test byte[res512switch],1 jnz .rightside push ebx mov ebx,[NumBytesPerLine] .b mov ax,[esi] mov [edi],ax mov [edi+ebx],ax add esi,2 add edi,4 dec ecx jnz .b pop ebx add edi,[NumBytesPerLine] jmp .return .rightside push ebx mov ebx,[NumBytesPerLine] .c mov ax,[esi] mov [edi+2],ax mov [edi+2+ebx],ax add esi,2 add edi,4 dec ecx jnz .c pop ebx add edi,[NumBytesPerLine] jmp .return .mmx mov eax,[spritetablea] mov ecx,64 add eax,512 .mmxr movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 movq [edi],mm0 punpckhwd mm1,mm1 movq [edi+8],mm1 movq [eax],mm0 movq [eax+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxr mov eax,[spritetablea] mov ecx,32 add eax,512 add edi,[AddEndBytes] .mmxr2 movq mm0,[eax] movq [edi],mm0 movq mm1,[eax+8] movq [edi+8],mm1 movq mm2,[eax+16] movq [edi+16],mm2 movq mm3,[eax+24] movq [edi+24],mm3 add eax,32 add edi,32 dec ecx jnz .mmxr2 jmp .return .yeshiresng call HighResProc jmp .return .bng mov eax,[esi+75036*4-2] mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .bng add edi,[AddEndBytes] sub esi,256*2 mov ecx,256 .bngb mov eax,[esi+75036*4-2] mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .bngb jmp .return .scanlines mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopab cmp byte[newengen],0 je .loopab mov ebx,SpecialLine+1 .loopab mov ecx,256 cmp byte[ebx],1 je near .yeshiresb cmp byte[ebx],1 jbe .ignorehrb call HighResProc jmp .returnb .ignorehrb cmp byte[MMXSupport],1 je near .mmxsl .ab mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .ab .returnb add esi,64 add edi,[AddEndBytes] mov ecx,256 .fslloop mov dword[edi],0 add edi,4 dec ecx jnz .fslloop add edi,[AddEndBytes] inc ebx dec dl jnz .loopab popad xor byte[res512switch],1 cmp byte[MMXSupport],1 je near .mmx2 ret .yeshiresb mov byte[ebx],0 test byte[res512switch],1 jnz .rightsideb .bb mov ax,[esi] mov [edi],ax add esi,2 add edi,4 dec ecx jnz .bb jmp .returnb .rightsideb .cb mov ax,[esi] mov [edi+2],ax add esi,2 add edi,4 dec ecx jnz .cb jmp .returnb .mmxsl mov ecx,64 .mmxrsl movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 punpckhwd mm1,mm1 movq [edi],mm0 movq [edi+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxrsl jmp .returnb .halfscanlines mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopabh cmp byte[newengen],0 je .loopabh mov ebx,SpecialLine+1 .loopabh cmp byte[ebx],1 jbe .ignorehrbh call HighResProc jmp .returnbh .ignorehrbh cmp byte[MMXSupport],1 je near .mmxslh mov ecx,256 .abh mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abh mov ecx,256 sub esi,512 add edi,[AddEndBytes] .abhs mov ax,[esi] shl eax,16 mov ax,[esi] and eax,[HalfTrans] shr eax,1 mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abhs .returnbh add esi,64 add edi,[AddEndBytes] inc ebx dec dl jnz near .loopabh popad cmp byte[MMXSupport],1 je near .mmx2 ret .mmxslh mov eax,[spritetablea] mov ecx,64 add eax,512 .mmxrslh movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 punpckhwd mm1,mm1 movq [edi],mm0 movq [edi+8],mm1 movq [eax],mm0 movq [eax+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxrslh mov eax,[spritetablea] mov ecx,32 add eax,512 add edi,[AddEndBytes] movq mm4,[HalfTrans] .mmxr2h movq mm0,[eax] movq mm1,[eax+8] movq mm2,[eax+16] movq mm3,[eax+24] pand mm0,mm4 pand mm1,mm4 pand mm2,mm4 pand mm3,mm4 psrlw mm0,1 psrlw mm1,1 psrlw mm2,1 psrlw mm3,1 movq [edi],mm0 movq [edi+8],mm1 movq [edi+16],mm2 movq [edi+24],mm3 add eax,32 add edi,32 dec ecx jnz .mmxr2h jmp .returnbh .quartscanlines mov [lineleft],dl mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopabh2 cmp byte[newengen],0 je .loopabh2 mov ebx,SpecialLine+1 .loopabh2 cmp byte[ebx],1 jbe .ignorehrbh2 call HighResProc jmp .returnbh2 .ignorehrbh2 cmp byte[MMXSupport],1 je near .mmxslh2 mov ecx,256 .abh2 mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abh2 mov ecx,256 sub esi,512 add edi,[AddEndBytes] .abhs2 mov ax,[esi] shl eax,16 mov ax,[esi] and eax,[HalfTrans] shr eax,1 mov edx,eax and edx,[HalfTrans] shr edx,1 add eax,edx mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abhs2 .returnbh2 add esi,64 add edi,[AddEndBytes] inc ebx dec byte[lineleft] jnz near .loopabh2 popad cmp byte[MMXSupport],1 je near .mmx2 ret .mmxslh2 mov eax,[spritetablea] mov ecx,64 add eax,512 .mmxrslh2 movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 punpckhwd mm1,mm1 movq [edi],mm0 movq [edi+8],mm1 movq [eax],mm0 movq [eax+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxrslh2 mov eax,[spritetablea] mov ecx,64 add eax,512 add edi,[AddEndBytes] movq mm4,[HalfTrans] .mmxr2h2 movq mm0,[eax] movq mm1,[eax+8] pand mm0,mm4 pand mm1,mm4 psrlw mm0,1 psrlw mm1,1 movq mm2,mm0 movq mm3,mm1 pand mm2,mm4 pand mm3,mm4 psrlw mm2,1 psrlw mm3,1 paddd mm0,mm2 paddd mm1,mm3 movq [edi],mm0 movq [edi+8],mm1 add eax,16 add edi,16 dec ecx jnz .mmxr2h2 jmp .returnbh2 HighResProc: mov ecx,256 cmp byte[ebx],3 je near .hiresmode7 cmp byte[ebx],7 je near .hiresmode7 test byte[ebx],4 jz .nofield cmp byte[scanlines],0 jne .nofield test byte[cfield],1 jz .nofield add edi,[NumBytesPerLine] .nofield test byte[ebx],3 jnz near .hires .a mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .a cmp byte[scanlines],0 jne .nofield test byte[cfield],1 jnz .nofielde add edi,[NumBytesPerLine] .nofielde ret .hiresmode7 cmp byte[MMXSupport],1 je .yeshiresngmmxmode7 .a2 mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .a2 add edi,[AddEndBytes] sub esi,512 mov ecx,256 add esi,75036*4 .a2b mov ax,[esi] shl eax,16 mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .a2b sub esi,75036*4 ret .yeshiresngmmxmode7 mov ecx,64 .mmxr movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 movq [edi],mm0 punpckhwd mm1,mm1 movq [edi+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxr add edi,[AddEndBytes] sub esi,512 add esi,75036*4 mov ecx,64 .mmxrb movq mm0,[esi] movq mm1,mm0 punpcklwd mm0,mm1 movq [edi],mm0 punpckhwd mm1,mm1 movq [edi+8],mm1 add esi,8 add edi,16 add eax,16 dec ecx jnz .mmxrb sub esi,75036*4 ret .hires cmp byte[MMXSupport],1 je near .yeshiresngmmx .bng mov eax,[esi+75036*4-2] mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .bng test byte[ebx],4 jz .nofieldb cmp byte[scanlines],0 jne .nofieldb test byte[cfield],1 jnz .lowerfield add edi,[NumBytesPerLine] .lowerfield ret .nofieldb cmp byte[scanlines],1 je near .scanlines cmp byte[scanlines],3 je near .halfscanlines cmp byte[scanlines],2 je near .quartscanlines add edi,[AddEndBytes] sub esi,256*2 mov ecx,256 .bngb mov eax,[esi+75036*4-2] mov ax,[esi] mov [edi],eax add esi,2 add edi,4 dec ecx jnz .bngb ret .scanlines ret .yeshiresngmmx mov eax,[spritetablea] mov ecx,64 add eax,512 .ngal movq mm0,[esi] movq mm1,[esi+75036*4] movq mm2,mm0 punpcklwd mm0,mm1 movq [edi],mm0 punpckhwd mm2,mm1 movq [edi+8],mm2 movq [eax],mm0 movq [eax+8],mm2 add esi,8 add edi,16 add eax,16 dec ecx jnz .ngal test byte[ebx],4 jz .nofieldc cmp byte[scanlines],0 jne .nofieldc test byte[cfield],1 jnz .lowerfieldb add edi,[NumBytesPerLine] .lowerfieldb ret .nofieldc cmp byte[scanlines],1 je near .scanlines cmp byte[scanlines],3 je near .halfscanlinesmmx cmp byte[scanlines],2 je near .quartscanlinesmmx test byte[ebx+1],3 jz .noaa cmp byte[En2xSaI],0 jne near .antialias cmp byte[antienab],0 jne near .antialias .noaa add edi,[AddEndBytes] mov eax,[spritetablea] mov ecx,32 add eax,512 .mmxr2 movq mm0,[eax] movq [edi],mm0 movq mm1,[eax+8] movq [edi+8],mm1 movq mm2,[eax+16] movq [edi+16],mm2 movq mm3,[eax+24] movq [edi+24],mm3 add eax,32 add edi,32 dec ecx jnz .mmxr2 ret .antialias add edi,[AddEndBytes] mov eax,[spritetablea] mov ecx,64 add eax,512 movq mm4,[HalfTrans] sub esi,256*2 .mmxr2aa movq mm0,[esi+288*2] movq mm1,[esi+288*2+75036*4] movq mm2,mm0 punpcklwd mm0,mm1 punpckhwd mm2,mm1 movq mm1,[eax] movq mm3,[eax+8] pand mm0,mm4 pand mm1,mm4 pand mm2,mm4 pand mm3,mm4 psrlw mm0,1 psrlw mm1,1 psrlw mm2,1 psrlw mm3,1 paddd mm0,mm1 paddd mm2,mm3 movq [edi],mm0 movq [edi+8],mm2 add eax,16 add edi,16 add esi,8 dec ecx jnz .mmxr2aa ret .halfscanlines add edi,[AddEndBytes] sub esi,256*2 mov ecx,256 .abhs mov eax,[esi+75036*4-2] mov ax,[esi] and eax,[HalfTrans] shr eax,1 mov edx,eax mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abhs ret .quartscanlines add edi,[AddEndBytes] sub esi,256*2 mov ecx,256 .abhs2 mov eax,[esi+75036*4-2] mov ax,[esi] and eax,[HalfTrans] shr eax,1 mov edx,eax and edx,[HalfTrans] shr edx,1 add eax,edx mov [edi],eax add esi,2 add edi,4 dec ecx jnz .abhs2 ret .halfscanlinesmmx mov eax,[spritetablea] mov ecx,32 add eax,512 add edi,[AddEndBytes] movq mm4,[HalfTrans] .mmxr2h movq mm0,[eax] movq mm1,[eax+8] movq mm2,[eax+16] movq mm3,[eax+24] pand mm0,mm4 pand mm1,mm4 pand mm2,mm4 pand mm3,mm4 psrlw mm0,1 psrlw mm1,1 psrlw mm2,1 psrlw mm3,1 movq [edi],mm0 movq [edi+8],mm1 movq [edi+16],mm2 movq [edi+24],mm3 add eax,32 add edi,32 dec ecx jnz .mmxr2h ret .quartscanlinesmmx mov eax,[spritetablea] mov ecx,64 add eax,512 add edi,[AddEndBytes] movq mm4,[HalfTransC] .mmxr2h2 movq mm0,[eax] movq mm1,[eax+8] pand mm0,mm4 pand mm1,mm4 psrlw mm0,1 psrlw mm1,1 movq mm2,mm0 movq mm3,mm1 pand mm2,mm4 pand mm3,mm4 psrlw mm2,1 psrlw mm3,1 paddd mm0,mm2 paddd mm1,mm3 movq [edi],mm0 movq [edi+8],mm1 add eax,16 add edi,16 dec ecx jnz .mmxr2h2 popad ret Process2xSaIwin: mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopabi cmp byte[newengen],0 je .loopabi mov ebx,SpecialLine+1 .loopabi mov [interPtr],ebx ; add edi,[VESAAddr] mov dl,224 sub dl,2 ; Compensate for top/bottom line + 2 lines in 2xSaI mov byte[lineleft],dl mov dword[esi+512],0 mov dword[esi+512+576*2],0 mov ebx,[vidbufferofsb] add ebx,288*2 .next mov dword[esi+512+576*3],0 mov eax,[interPtr] cmp byte[eax],1 jbe .ignorehr push ebx mov ebx,[interPtr] call HighResProc pop ebx push ebx mov ecx,144 .nextb mov dword[ebx],0FFFFFFFFh add ebx,4 dec ecx jnz .nextb pop ebx jmp .returninterp .ignorehr ;srcPtr equ 8 ;deltaPtr equ 12 ;srcPitch equ 16 ;width equ 20 ;dstOffset equ 24 ;dstPitch equ 28 ;dstSegment equ 32 push ebx mov eax,[NumBytesPerLine] push eax mov eax,edi ; destination offset push eax mov eax,256 ; width push eax mov eax,576 ; source pitch push eax push ebx mov eax,esi ; source pointer push eax cmp byte[En2xSaI],2 je .supereagle cmp byte[En2xSaI],3 je .super2xSaI call _2xSaILineW jmp .normal .supereagle call _2xSaISuperEagleLineW jmp .normal .super2xSaI call _2xSaISuper2xSaILineW .normal add esp,24 pop ebx add esi,576 add edi,[NumBytesPerLine] add edi,[NumBytesPerLine] add ebx,576 inc dword[interPtr] dec dword[lineleft] jnz near .next mov ecx,256 sub edi,[NumBytesPerLine] .loop mov dword[es:edi],0 add edi,4 dec ecx jnz .loop emms popad ret .returninterp add esi,64 inc dword[interPtr] add edi,[AddEndBytes] add ebx,576 dec byte[lineleft] jnz near .next emms popad ret MMXInterpolwin: mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopab cmp byte[newengen],0 je .loopab mov ebx,SpecialLine+1 .loopab mov dl,224 dec dl dec dl dec dl movq mm2,[HalfTransC] cmp byte[scanlines],1 je near .scanlines cmp byte[scanlines],2 je near .scanlinesquart cmp byte[scanlines],3 je near .scanlineshalf inc ebx mov [lineleft],dl ; do scanlines mov edx,[spritetablea] mov ecx,64 mov eax,[esi+510] add edx,512 mov [esi+512],eax .a2 movq mm0,[esi] movq mm3,mm0 movq mm4,mm0 movq mm1,[esi+2] pand mm3,mm1 pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 paddd mm0,mm1 pand mm3,[HalfTransB] paddw mm0,mm3 movq mm5,mm4 ; mm4/mm5 contains original values, mm0 contains mixed values punpcklwd mm4,mm0 punpckhwd mm5,mm0 movq [edi],mm4 movq [edi+8],mm5 movq [edx],mm4 movq [edx+8],mm5 add esi,8 add edi,16 add edx,16 dec ecx jnz .a2 add esi,64 add edi,[AddEndBytes] .a5 cmp byte[ebx],1 jbe .ignorehr call HighResProc movq mm2,[HalfTransC] jmp .returninterp .ignorehr mov eax,[esi+510] mov ecx,64 mov [esi+512],eax mov edx,[spritetablea] add edx,512 ; Process next line .a3 movq mm0,[esi] movq mm3,mm0 movq mm4,mm0 movq mm1,[esi+2] pand mm3,mm1 pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 paddd mm0,mm1 pand mm3,[HalfTransB] paddw mm0,mm3 movq mm5,mm4 ; mm4/mm5 contains original values, mm0 contains mixed values movq mm6,[edx] movq mm7,[edx+8] punpcklwd mm4,mm0 punpckhwd mm5,mm0 movq [edx],mm4 movq [edx+8],mm5 pand mm0,mm4 movq mm0,mm6 pand mm4,mm2 pand mm6,mm2 psrlw mm4,1 psrlw mm6,1 pand mm0,[HalfTransB] paddd mm4,mm6 paddw mm4,mm0 movq mm0,mm5 pand mm0,mm7 pand mm5,mm2 pand mm7,mm2 psrlw mm5,1 pand mm0,[HalfTransB] psrlw mm7,1 paddd mm5,mm7 paddw mm5,mm0 movq [edi],mm4 movq [edi+8],mm5 add esi,8 add edi,16 add edx,16 dec ecx jnz near .a3 add edi,[AddEndBytes] mov edx,[spritetablea] add edx,512 mov ecx,64 .a4 movq mm0,[edx] movq mm1,[edx+8] movq [edi],mm0 movq [edi+8],mm1 add edi,16 add edx,16 dec ecx jnz .a4 .returninterp add esi,64 add edi,[AddEndBytes] inc ebx dec byte[lineleft] jnz near .a5 emms popad ret .scanlines inc dl mov [lineleft],dl ; do scanlines mov eax,[esi+510] mov ecx,64 mov [esi+512],eax .asl cmp byte[ebx],1 jbe .ignorehrs call HighResProc movq mm2,[HalfTrans] jmp .returninterps .ignorehrs .a movq mm0,[esi] movq mm4,mm0 movq mm1,[esi+2] pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 paddd mm0,mm1 movq mm5,mm4 ; mm4/mm5 contains original values, mm0 contains mixed values punpcklwd mm4,mm0 punpckhwd mm5,mm0 movq [edi],mm4 movq [edi+8],mm5 add esi,8 add edi,16 dec ecx jnz .a .returninterps add esi,64 add edi,[AddEndBytes] mov ecx,256 .fslloop mov dword[edi],0 add edi,4 dec ecx jnz .fslloop add edi,[AddEndBytes] inc ebx mov ecx,64 dec byte[lineleft] jnz near .asl emms popad ret .scanlineshalf inc dl mov [lineleft],dl ; do scanlines .ahb cmp byte[ebx],1 jbe .ignorehrhs call HighResProc movq mm2,[HalfTrans] jmp .returninterphs .ignorehrhs mov eax,[esi+510] mov ecx,64 mov [esi+512],eax mov edx,[spritetablea] add edx,512 .ah movq mm0,[esi] movq mm4,mm0 movq mm1,[esi+2] pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 paddd mm0,mm1 movq mm5,mm4 ; mm4/mm5 contains original values, mm0 contains mixed values punpcklwd mm4,mm0 punpckhwd mm5,mm0 movq [edx],mm4 movq [edx+8],mm5 movq [edi],mm4 movq [edi+8],mm5 add esi,8 add edi,16 add edx,16 dec ecx jnz .ah add edi,[AddEndBytes] sub edx,16*64 mov ecx,64 .ahc movq mm0,[edx] movq mm1,[edx+8] pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 movq [edi],mm0 movq [edi+8],mm1 add edi,16 add edx,16 dec ecx jnz .ahc .returninterphs add edi,[AddEndBytes] add esi,64 inc ebx dec byte[lineleft] jnz near .ahb emms popad ret .scanlinesquart inc dl mov [lineleft],dl ; do scanlines .ahb2 cmp byte[ebx],1 jbe .ignorehrqs call HighResProc movq mm2,[HalfTransC] jmp .returninterpqs .ignorehrqs mov eax,[esi+510] mov ecx,64 mov [esi+512],eax mov edx,[spritetablea] add edx,512 .ah2 movq mm0,[esi] movq mm3,mm0 movq mm4,mm0 movq mm1,[esi+2] pand mm3,mm1 pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 paddd mm0,mm1 pand mm3,[HalfTransB] paddw mm0,mm3 movq mm5,mm4 ; mm4/mm5 contains original values, mm0 contains mixed values punpcklwd mm4,mm0 punpckhwd mm5,mm0 movq [edx],mm4 movq [edx+8],mm5 movq [edi],mm4 movq [edi+8],mm5 add esi,8 add edi,16 add edx,16 dec ecx jnz .ah2 add edi,[AddEndBytes] sub edx,16*64 mov ecx,64 movq mm3,mm2 .ahc2 movq mm0,[edx] movq mm1,[edx+8] pand mm0,mm2 pand mm1,mm2 psrlw mm0,1 psrlw mm1,1 movq mm4,mm0 movq mm5,mm1 pand mm4,mm2 pand mm5,mm2 psrlw mm4,1 psrlw mm5,1 paddd mm0,mm4 paddd mm1,mm5 movq [edi],mm0 movq [edi+8],mm1 add edi,16 add edx,16 dec ecx jnz .ahc2 .returninterpqs add esi,64 add edi,[AddEndBytes] inc ebx dec byte[lineleft] jnz near .ahb2 emms popad ret NEWSYM interpolate640x480x16bwin cmp byte[MMXSupport],1 je near MMXInterpolwin mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopabi cmp byte[newengen],0 je .loopabi mov ebx,SpecialLine+1 .loopabi mov [interPtr],ebx mov dl,224 dec dl dec dl dec dl cmp byte[scanlines],1 je near .scanlines cmp byte[scanlines],2 je near .scanlinesquart cmp byte[scanlines],3 je near .scanlineshalf inc dword[interPtr] mov [lineleft],dl ; do first line mov ecx,255 mov edx,[spritetablea] .a mov ax,[esi] mov bx,[esi+2] and ebx,[HalfTrans+6] and eax,[HalfTrans+6] add ebx,eax shl ebx,15 mov bx,[esi] mov [edi],ebx mov [edx],ebx add esi,2 add edi,4 add edx,4 dec ecx jnz .a add esi,66 add edi,[AddEndBytes] add edi,4 .loopb mov ebx,[interPtr] cmp byte[ebx],1 jbe .ignorehr call HighResProc jmp .returninterp .ignorehr mov ecx,255 mov edx,[spritetablea] .c mov ax,[esi] mov bx,[esi+2] and ebx,[HalfTrans+6] and eax,[HalfTrans+6] add ebx,eax shl ebx,15 mov eax,[edx] mov bx,[esi] and eax,[HalfTrans] mov [edx],ebx and ebx,[HalfTrans] shr eax,1 shr ebx,1 add eax,ebx mov [edi],eax add esi,2 add edi,4 add edx,4 dec ecx jnz .c add edi,4 add edi,[AddEndBytes] mov edx,[spritetablea] mov ecx,255 .d mov eax,[edx] mov [edi],eax add edx,4 add edi,4 dec ecx jnz .d add esi,66 inc dword[interPtr] add edi,[AddEndBytes] add edi,4 dec byte[lineleft] jnz near .loopb popad ret .returninterp add esi,64 inc dword[interPtr] add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopb popad ret .scanlines xor eax,eax mov ebx,hirestiledat+1 cmp byte[GUIOn],1 je .loopabis cmp byte[newengen],0 je .loopabis mov ebx,SpecialLine+1 .loopabis .loopab mov ecx,255 cmp byte[ebx],1 jbe .ignorehrs call HighResProc jmp .returninterps .ignorehrs cmp byte[ebx],1 je near .yeshiresb .ignorehrb push ebx .ab mov ax,[esi] mov bx,[esi+2] and ebx,[HalfTrans+6] and eax,[HalfTrans+6] add ebx,eax shl ebx,15 mov bx,[esi] mov [edi],ebx add esi,2 add edi,4 dec ecx jnz .ab pop ebx .returnb add esi,66 add edi,4 add edi,[AddEndBytes] mov ecx,256 .fslloop mov dword[edi],0 add edi,4 dec ecx jnz .fslloop add edi,[AddEndBytes] inc ebx dec dl jnz .loopab xor byte[res512switch],1 popad ret .yeshiresb mov byte[ebx],0 test byte[res512switch],1 jnz .rightsideb .bb mov ax,[esi] mov [edi],ax add esi,2 add edi,4 dec ecx jnz .bb jmp .returnb .rightsideb .cb mov ax,[esi] mov [edi+2],ax add esi,2 add edi,4 dec ecx jnz .cb jmp .returnb .returninterps add esi,64 inc dword[interPtr] add edi,[AddEndBytes] mov ecx,256 .fslloop2 mov dword[edi],0 add edi,4 dec ecx jnz .fslloop2 add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopab popad ret .scanlineshalf xor eax,eax mov [lineleft],dl .loopab2 mov ebx,[interPtr] cmp byte[ebx],1 jbe .ignorehrhs call HighResProc jmp .returninterphs .ignorehrhs mov ecx,255 mov edx,[spritetablea] add edx,512 .ab2 mov ax,[esi] mov bx,[esi+2] and ebx,[HalfTrans+6] and eax,[HalfTrans+6] add ebx,eax shl ebx,15 mov bx,[esi] mov [edx],ebx mov [edi],ebx add esi,2 add edi,4 add edx,4 dec ecx jnz .ab2 add edi,4 add edi,[AddEndBytes] mov ecx,255 mov edx,[spritetablea] add edx,512 .ab2b mov eax,[edx] and eax,[HalfTrans] shr eax,1 mov [edi],eax add edi,4 add edx,4 dec ecx jnz .ab2b inc dword[interPtr] add esi,66 add edi,4 add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopab2 popad ret .returninterphs add esi,64 inc dword[interPtr] add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopab2 popad ret .scanlinesquart xor eax,eax mov [lineleft],dl .loopab3 mov ebx,[interPtr] cmp byte[ebx],1 jbe .ignorehrqs call HighResProc jmp .returninterpqs .ignorehrqs mov ecx,255 mov edx,[spritetablea] add edx,512 .ab3 mov ax,[esi] mov bx,[esi+2] and ebx,[HalfTrans+6] and eax,[HalfTrans+6] add ebx,eax shl ebx,15 mov bx,[esi] mov [edx],ebx mov [edi],ebx add esi,2 add edi,4 add edx,4 dec ecx jnz .ab3 add edi,AddEndBytes add edi,4 mov ecx,255 mov edx,[spritetablea] add edx,512 .ab3b mov eax,[edx] and eax,[HalfTrans] shr eax,1 mov ebx,eax and ebx,[HalfTrans] shr ebx,1 add eax,ebx mov [edi],eax add edi,4 add edx,4 dec ecx jnz .ab3b inc dword[interPtr] add esi,66 add edi,4 add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopab3 popad ret .returninterpqs add esi,64 inc dword[interPtr] add edi,[AddEndBytes] dec byte[lineleft] jnz near .loopab3 popad ret SECTION .data InterPtr dd 0
Cospefogo Posted September 21, 2011 Posted September 21, 2011 (edited) Looks like ASM to me... Notice the first one is commented out. Looks like something spoken right from the mouth of the Devil to me! Edited September 21, 2011 by Cospefogo
PhilExile Posted September 21, 2011 Author Posted September 21, 2011 Madmab, How difficult would it be to add a PNG overlay, with an adjustable opacity? Thanks for chiming in.
sharpfork Posted September 21, 2011 Posted September 21, 2011 (edited) Thanks bunch, this is great stuff! SDTV Setup- Buy an Extron Emotia | See here for more details: http://scanlines.hazard-city.de/ - Buy either a Frosty VGA cable, YUV -> VGA converter, or build your own VGA cable- Set your dash/emulator to 480p- Set your emulator to 'perfect pixel' size - i.e. 512x448- Once everything is hooked up, stretch the horizontal size of the picture to the maximum on the Emotia- Flip the interlacing switch on the front of the Emotia to activate 240p I thought that 480p was ED, not SD but I'm known to be an idiot with this stuff.. I get some scan lines from the cheepo 480i SD TV I bought super cheep. I wonder how that compares to adding the Extron in the mix. Edited September 21, 2011 by sharpfork
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now