View unanswered posts | View active topics It is currently Mon Nov 18, 2019 11:53 pm



This topic is locked, you cannot edit posts or make further replies.  [ 158 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next
The unofficial BSNES pixel shader thread 
Author Message
ZSNES Shake Shake Prinny
User avatar

Joined: Wed Jul 28, 2004 4:15 pm
Posts: 5615
Location: PAL50, dood !
Reply with quote
Post 
byuu wrote:
Quote:
way less intimidating


Please. What self-respecting programmer hasn't memorized up to at least 2^20 in their head? :)

Invaluable for those bit-shift operations ...

PSLLQ ! because why not go for 64 while you're at it...

_________________
皆黙って俺について来い!!
Code:
<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)

Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54


Tue Jun 10, 2008 7:59 pm
Profile
Official tech support dood

Joined: Wed Jan 25, 2006 7:57 am
Posts: 2091
Reply with quote
Post 
grinvader wrote:
byuu wrote:
Quote:
way less intimidating


Please. What self-respecting programmer hasn't memorized up to at least 2^20 in their head? :)

Invaluable for those bit-shift operations ...

PSLLQ ! because why not go for 64 while you're at it...


I just remember being really excited when I was in middle school replaying the original Dragon Warrior and suddenly understood why the limits for gold and exp were 65535...

_________________
Why yes, my shift key *IS* broken.


Tue Jun 10, 2008 8:05 pm
Profile
Seen it all
User avatar

Joined: Mon Jan 03, 2005 5:04 pm
Posts: 2302
Location: Germany
Reply with quote
Post 
grinvader wrote:
creaothceann wrote:
2^16

64k

way less intimidating

I wrote it like that at first, but someone might read it as 64 KB.

_________________
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list


Tue Jun 10, 2008 9:09 pm
Profile WWW
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
mudlord I like what you have done with mario and a cube!


Thanks. Though that was a little test to see how the rendering code worked (you can see how I messed up the tex coords in the sample though :lol:) . And it now works fine. Thanks again VG. 8)

Quote:
You could use a buffer of 2^16 items to store the final 24-bit values.


Hmmmz, true. Although, it works fine enough though at the moment (though I have a C2D 4500, so speed isn't really a problem. My only concern is the pressure my emulator will put on the video card in older PCs, since it uses dynamic plasma effects, wave/water effects and other things that involve changing textures every single frame. And it all does this without shaders. But we will see when I release it.)


Wed Jun 11, 2008 12:54 pm
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
I upgraded ubuntu to 8.04 and tried running my bsnes opengl 2.0 driver with visual effects set to normal and extra, and it did not work, It just showed me a white screen!


Dude, there is a bug in your code. I fixed it:

Code:
 glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
    glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
    glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
    glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
    glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
    glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
    glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
    glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");
    glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");

    // Create our fragment shader...
    fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);

    FILE *fp = fopen("shader.frag", "rb");
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *buffer = new char[size + 1];
    fread(buffer, 1, size, fp);
    buffer[size] = 0;
    fclose(fp);
    const char *fbuffer = buffer;

    glShaderSource(fragmentshader, 1, &fbuffer, 0);
    glCompileShader(fragmentshader);
    delete[] buffer;

    // Create a program object and attach our compiled fragment shader to it...
    program = glCreateProgram();
    glAttachShader(program, fragmentshader);

    // Link the program object...
    glLinkProgram(program);

    // Locate some parameters by name so we can set them later...
    glGetUniformLocation(program, "texture");


The problem was gltexture = glGetUniformLocation(program, "texture");

Thats the fixed version. Works for me in my MuNES. :P Thanks again for porting my pixel shaders!

Image


Sat Jun 21, 2008 2:09 am
Profile
Rookie

Joined: Sat Sep 29, 2007 4:08 am
Posts: 13
Reply with quote
Post Bug in my bsnes shader code
Quote:
Dude, there is a bug in your code. I fixed it

Cheers man, I have updated my sources =D
Quote:
Works for me in my MuNES. Thanks again for porting my pixel shaders!

No probs!


Sun Jun 22, 2008 5:08 pm
Profile WWW
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
krom, found some more issues with your code using glIntercept. I will post some patched code ASAP. IIRC, ATI cards need vertex shaders, as well as fragment shaders, for some retarded reason. As such, I will be posting some code that should add vertex shader support, too.


Thu Jul 17, 2008 11:36 pm
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Code:
PFNGLCREATEPROGRAMOBJECTARBPROC  glCreateProgramObjectARB  = NULL;
PFNGLDELETEOBJECTARBPROC         glDeleteObjectARB         = NULL;
PFNGLUSEPROGRAMOBJECTARBPROC     glUseProgramObjectARB     = NULL;
PFNGLCREATESHADEROBJECTARBPROC   glCreateShaderObjectARB   = NULL;
PFNGLSHADERSOURCEARBPROC         glShaderSourceARB         = NULL;
PFNGLCOMPILESHADERARBPROC        glCompileShaderARB        = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
PFNGLATTACHOBJECTARBPROC         glAttachObjectARB         = NULL;
PFNGLGETINFOLOGARBPROC           glGetInfoLogARB           = NULL;
PFNGLLINKPROGRAMARBPROC          glLinkProgramARB          = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC   glGetUniformLocationARB   = NULL;
PFNGLUNIFORM4FARBPROC            glUniform4fARB            = NULL;
PFNGLUNIFORM1IARBPROC            glUniform1iARB            = NULL;

void initShader(char *filename, char* filename2) {
    glCreateProgramObjectARB  = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
    glDeleteObjectARB         = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
    glUseProgramObjectARB     = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
    glCreateShaderObjectARB   = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
    glShaderSourceARB         = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
    glCompileShaderARB        = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
    glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
    glAttachObjectARB         = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
    glGetInfoLogARB           = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
    glLinkProgramARB          = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
    glGetUniformLocationARB   = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
    glUniform4fARB            = (PFNGLUNIFORM4FARBPROC)wglGetProcAddress("glUniform4fARB");
   glUniform1iARB            = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
    // Create our fragment shader...
    fragmentshader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
   vertexshader = glCreateShaderObjectARB(GL_VERTEX_SHADER);
   //for the frag shader
    FILE *fp = fopen(filename, "rb");
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *buffer = new char[size + 1];
    fread(buffer, 1, size, fp);
    buffer[size] = 0;
    fclose(fp);
    const char *fbuffer = buffer;
    glShaderSourceARB(fragmentshader, 1, &fbuffer, 0);
    glCompileShaderARB(fragmentshader);
    delete[] buffer;

   //for the vertex shader
    FILE *fp2 = fopen(filename2, "rb");
    fseek(fp2, 0, SEEK_END);
    int size2 = ftell(fp2);
    fseek(fp2, 0, SEEK_SET);
    char *buffer2 = new char[size2 + 1];
    fread(buffer2, 1, size2, fp2);
    buffer2[size2] = 0;
    fclose(fp2);
    const char *vbuffer = buffer2;
    glShaderSourceARB(vertexshader, 1, &vbuffer, 0);
    glCompileShaderARB(vertexshader);
    delete[] buffer2;

    // Create a program object and attach our compiled fragment shader to it...
    program = glCreateProgramObjectARB();
    glAttachObjectARB(program, fragmentshader);
    glAttachObjectARB(program, vertexshader);
    // Link the program object...
    glLinkProgramARB(program);
    // Locate some parameters by name so we can set them later...
    glGetUniformLocationARB(program, "texture");
}


And when you render.....

Code:
if (useShaders == 1)
   glUseProgramObjectARB(program);

        *render textured quad here*
   
   if (useShaders == 1)
   glUseProgramObjectARB(NULL);


There.


Mon Jul 21, 2008 1:58 am
Profile
ZNES Developer
User avatar

Joined: Mon Aug 02, 2004 11:22 pm
Posts: 215
Reply with quote
Post 
During my previous efforts with cubic kernels I realised that the methods were probably overkill for the kind of images they would be subjected to, rather, I opted to construct a quadratic kernel with a small radius, one that requires 4 texture fetches, making it readily PS v2.0 compliant. It was constructed with sharpness in mind, so everyone that enjoys the pixelated look, but can't cope with the artifacts of non-uniform box filtering, rejoice.

At the time the shader ignores any extra information provided by the pseudo-hires modes (it only maps to a 256x224 or 256x239 texture), figures for the highest resolution modes in NTSC and PAL are welcome, so that I may implement this later.

Pixel shader: Quadratic interpolation.
v0.1 - Release
v0.11 - Fixed resolution detection.

NOT tested with any hardware besides mine.

Usage:
Patch bsnes and copy/paste the following code into a "shader.fx" file inside the main folder.
Launch bsnes and make sure to check "Point" and "None" in the "Filter" menu.
Test and provide feedback.

Examples:
1x with NTSC aspect ratio compensation:
Image

3x with NTSC aspect ratio compensation:
Image

Source:
Code:
/* Quadratic Resampler v0.11
 * By DOLLS
 * Do not distribute a modified version without permission.
 */

texture tex1, tex2;
float2 rcpres;
sampler s0 = sampler_state {
   texture = <tex1>;
   AddressU = mirror;
   AddressV = mirror;
};

sampler s1 = sampler_state {
   texture = <tex2>;
   AddressU = mirror;
   AddressV = mirror;
};

int2 res;

float4 Normalize(in float2 coord : TEXCOORD0): COLOR0
{      
   res = int2(256, (frac(1 / (224 * rcpres.y)) < 0.05)? 224 : 239);
   float2 loc = coord * float2(rcpres.y * res.y / (rcpres.x * res.x), 1.0) / (res.y * rcpres.y);
   return tex2D(s0, loc);      
}

float pow2(float x)
{
   return x * x;
}

float getWeight(float x)
{   
   if (x == 0.0) return 1.0;
   else if (x < 0.5) return 1 - 2 * pow2(x);
   else if (x < 1.0) return 2 * pow2(1 - x);
   else return 0.0;   
}

float4 Resample(in float2 coord : TEXCOORD0) : COLOR0
{   
   res = int2(256, (frac(1 / (224 * rcpres.y)) < 0.05)? 224 : 239);
   float2 pos = coord * res - 0.5;
   float2 tex = (floor(pos) + 0.5) * rcpres;
   float2 next_tex = tex + rcpres;
      
   float2 delta = frac(pos);
   float2 w0 = float2(getWeight(delta.x), getWeight(delta.y));
   float2 w1 = float2(getWeight(1 - delta.x), getWeight(1 - delta.y));
   
   float4 value = w0.x * w0.y * tex2D(s1, tex);
   value += w1.x * w0.y * tex2D(s1, float2(next_tex.x, tex.y));
   value += w0.x * w1.y * tex2D(s1, float2(tex.x, next_tex.y));
   value += w1.x * w1.y * tex2D(s1, next_tex);
   return value;      
}

Technique T0
{      
   pass p0 {      
      PixelShader = compile ps_2_0 Normalize();
   }      
   pass p1 {
      PixelShader = compile ps_2_0 Resample();
   }      
}


Wed Jul 23, 2008 10:44 am
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Not a bad shader! I am considering adding this to the shader pack, if you don't mind :D .

Any chance of a Lanczos shader? :P


Thu Jul 24, 2008 4:06 am
Profile
ZNES Developer
User avatar

Joined: Mon Aug 02, 2004 11:22 pm
Posts: 215
Reply with quote
Post 
mudlord: Sure, go ahead!

New shaders:
Cubic spline & Lanczos2 based resamplers, normal & gamma corrected, gamma corrected variation of the Quadratic resampler added as well.

Lanczos3 (the common one) was avoided as it introduces unnecessary ringing artifacts, it's better suited for captured media (photo, video).

If your display operates in sRGB color space (gamma 2.2 calibrated), you might want to check out the gamma corrected variations of the shaders ("_sRGB" appended in the filename, remove that part).
PS v2.0a required.

Download link:
http://www.megaupload.com/?d=MDEU3IYZ
(Sorry, my FTP is currently offline)

DOLLS wrote:
At the time the shader ignores any extra information provided by the pseudo-hires modes (it only maps to a 256x224 or 256x239 texture), figures for the highest resolution modes in NTSC and PAL are welcome, so that I may implement this later.

I'm still requesting this information.


Sun Jul 27, 2008 5:14 am
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
mudlord: Sure, go ahead!


Okay.

I will update the pack when I update my site. Which is when I am in the mood to.


Mon Jul 28, 2008 4:45 am
Profile
Rookie

Joined: Sat Sep 29, 2007 4:08 am
Posts: 13
Reply with quote
Post Cheers mudlord
Quote:
krom, found some more issues with your code using glIntercept. I will post some patched code ASAP. IIRC, ATI cards need vertex shaders, as well as fragment shaders, for some retarded reason. As such, I will be posting some code that should add vertex shader support, too.

Sorry for the late reply mudlord,
Thanks a lot for the new code, I have updated my sources and I am very appreciative of your help =D

btw how is the nes emu going?


Wed Aug 06, 2008 10:20 pm
Profile WWW
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
Sorry for the late reply mudlord,
Thanks a lot for the new code, I have updated my sources and I am very appreciative of your help =D

btw how is the nes emu going?


No probs!

And its going excellent. I need to replace SDL as a sound server, though I have very little experience with DirectSound or WinMM. If anyone can help, I would be so grateful.

All I need is some code that
* has a init function that sets the samplerate
* a closing function that is a void()
* a writing function that has a parameter, that sets the amount of samples processed, as well as a parameter that contains the raw audio data.

Currently my code is based of Sound_Queue by blargg, so that should give ideas in how to do the WinMM/DSound sound server. (I know byuu was wanting to do something for me...maybe this can be it).


Wed Aug 06, 2008 10:39 pm
Profile
Reply with quote
Post 
All of that is in src/lib/ruby/audio/directsound.cpp :D
Only 5kb in size.

Init:

Code:
    DirectSoundCreate(0, &ds, 0);
    ds->SetCooperativeLevel((HWND)settings.handle, DSSCL_PRIORITY);

    memset(&dsbd, 0, sizeof(dsbd));
    dsbd.dwSize        = sizeof(dsbd);
    dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
    dsbd.dwBufferBytes = 0;
    dsbd.lpwfxFormat   = 0;
    ds->CreateSoundBuffer(&dsbd, &dsb_p, 0);

    memset(&wfx, 0, sizeof(wfx));
    wfx.wFormatTag      = WAVE_FORMAT_PCM;
    wfx.nChannels       = 2;
    wfx.nSamplesPerSec  = settings.frequency;
    wfx.wBitsPerSample  = 16;
    wfx.nBlockAlign     = wfx.wBitsPerSample / 8 * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
    dsb_p->SetFormat(&wfx);

    memset(&dsbd, 0, sizeof(dsbd));
    dsbd.dwSize          = sizeof(dsbd);
    dsbd.dwFlags         = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY |
                           DSBCAPS_GLOBALFOCUS | DSBCAPS_LOCSOFTWARE;
    dsbd.dwBufferBytes   = data.ring_size * 3;
    dsbd.guid3DAlgorithm = GUID_NULL;
    dsbd.lpwfxFormat     = &wfx;
    ds->CreateSoundBuffer(&dsbd, &dsb_b, 0);
    dsb_b->SetFrequency(settings.frequency);
    dsb_b->SetCurrentPosition(0);


Term:

Code:
    if(dsb_b) { dsb_b->Stop(); dsb_b->Release(); dsb_b = 0; }
    if(dsb_p) { dsb_p->Stop(); dsb_p->Release(); dsb_p = 0; }
    if(ds) { ds->Release(); ds = 0; }


Write:

Code:
    data.buffer[data.buffer_pos++] = (l_sample << 0) + (r_sample << 16);
    if(data.buffer_pos < settings.frequency / 40) return;

  DWORD ring_pos, pos, size;
    for(;;) {
      dsb_b->GetCurrentPosition(&pos, 0);
      ring_pos = pos / data.ring_size;
      if(settings.synchronize == false || ring_pos != data.ring_pos) break;
      Sleep(1);
    }

    data.ring_pos = ring_pos;
  void *output;
    if(dsb_b->Lock(((data.ring_pos + 2) % 3) * data.ring_size, data.ring_size,
      &output, &size, 0, 0, 0) == DS_OK) {
      memcpy(output, data.buffer, data.ring_size);
      dsb_b->Unlock(output, size, 0, 0);
    }

    data.buffer_pos = 0;


Link with -ldsound or dsound.lib.

I'll be happy to go over any section that is unclear in detail, if you like.

You're free to use all of src/lib directly as public domain, as well.


Wed Aug 06, 2008 10:45 pm
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Strange, tried out the code, failed to work. :(

Not a single bit of sound, apart from a close to inaudible buzz. :(

Here's the main callback function for sound if you are interested.....
Code:
void NESCore_Callback_OutputSample(int nSamples, byte *channel1, byte *channel2,
    byte *channel3, byte *channel4, byte *channel5)
{
   short temp [1024];
   int i;
   for ( i = 0; i < nSamples; i++ )
    temp [i] = (channel1 [i] + channel2 [i] + channel3 [i] + channel4 [i] + channel5 [i]) * 32;

   // sync_audio_write( temp, nSamples );
   sample((int16_t)temp);


}


I changed the "sample" function of your class, to make "temp" write to it, unfortunately it done nothing...

sync_audio_write() was the SDL related function that I was talking about before...


Thu Aug 07, 2008 5:20 am
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Hheehehe, found a workaround to the problem.

Instead of adding DirectSound, I completely regutted SDL.

Everything not relating to threads, mutexes, or raw DirectSound audio has been completely stripped. Result? Managed to shrink the entire library from a mammoth ~150KB to a petite 24.5KB. Which is perfect for what I am using it for. :lol:


Sun Aug 10, 2008 3:38 am
Profile
Reply with quote
Post 
mudlord wrote:
Hheehehe, found a workaround to the problem.

Instead of adding DirectSound, I completely regutted SDL.

Everything not relating to threads, mutexes, or raw DirectSound audio has been completely stripped. Result? Managed to shrink the entire library from a mammoth ~150KB to a petite 24.5KB. Which is perfect for what I am using it for. :lol:


Ah, I believe someone else did that with one of the driver classes ... I want to say it was input related, but i can't be sure. You guys are truly brave to gut such a massive program like that, heh.

Anyway, sounds neat! If you change your mind, let me know. I'd need you to send me your source code, though, so I can get it working on my side. That, or perhaps I could make the DSound lib into its own app with nothing else in the way that just plays a quick WAV file or something using an API similar to yours.

I dare say raw DSound is a bit better (love the ability to query the play cursor position), but it hinders portability, so your single API solution is probably best.


Mon Aug 11, 2008 12:32 am
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
That, or perhaps I could make the DSound lib into its own app with nothing else in the way that just plays a quick WAV file or something using an API similar to yours.


That would be so cool :) Even a sample showing a sine wave will be enough, since we are dealing with raw audio data.

I admit, I am kinda very ashamed to show you my GUI/IO source code. :( It is super messy, with some global variables, as well as using the Windows message pump to process core events, instead of using a seperate thread (OpenGL is extremely picky on which threads rendering contexts are made), though I do plan on fixing that.

Though, the emu does run extremely fast on a 1.3 Celeron M. The render code is quite weird too, since I do plan on adding some extra rendering features at a later date....


Mon Aug 11, 2008 1:56 am
Profile
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Sent the code.

Beware again, I can't stress enough how ugly it may look. Sorry 'bout that. I will fix it when I solve the OpenGL thread issues.


Mon Aug 11, 2008 2:07 am
Profile
Reply with quote
Post 
mudlord wrote:
That would be so cool :) Even a sample showing a sine wave will be enough, since we are dealing with raw audio data.


Here's one that outputs static at 22khz / 16-bit stereo. You can easily change things via audio.settings.frequency, audio.settings.synchronize, etc before-hand.

To set it up, you call audio.init(), write samples with audio.sample(left, right), and finish with audio.term().

Compile with kernel32.lib, user32.lib, dsound.lib and uuid.lib.

Binary and source included. My example has synchronization on, meaning it will put the process to sleep when too much data is in the sound buffer. It's a purely sync-to-audio setup, the same as with bsnes. Hopefully that's appropriate for MuNES, because I don't know how to do it any other way.

http://www.geocities.com/byuu64/directsound.zip

Quote:
It is super messy, with some global variables, as well as using the Windows message pump to process core events, instead of using a seperate thread


Eh, it looks pretty good to me. Not 100% abstracted, but so long as it's Windows-only, that's not really a problem.

I do wish you'd drop VC6, though. That compiler is evil :P


Mon Aug 11, 2008 6:34 pm
has wat u liek
User avatar

Joined: Tue Sep 11, 2007 2:54 pm
Posts: 559
Location: Banland.
Reply with quote
Post 
Quote:
Here's one that outputs static at 22khz / 16-bit stereo. You can easily change things via audio.settings.frequency, audio.settings.synchronize, etc before-hand.

To set it up, you call audio.init(), write samples with audio.sample(left, right), and finish with audio.term().

Compile with kernel32.lib, user32.lib, dsound.lib and uuid.lib.


Thank you! Much appreciated!

MuNES without SDL.dll as dependancy:
http://vba-m.ngemu.com/munes_vc6.rar

Quote:
Eh, it looks pretty good to me. Not 100% abstracted, but so long as it's Windows-only, that's not really a problem.

I do wish you'd drop VC6, though. That compiler is evil :P


Thanks, I honestly think though some parts can still be improved. Its quite hackish. Though, it does the job :/

I agree though about VC6, but I want to be assured that it runs with as little dependancies as possible. MSVCR71.DLL aint a option, if thats what your implying. I am trying my hardest to keep around 64KB and no over...or in the event of that, 96KB.

*curses VC6 over its DWORD_PTR support*


Tue Aug 12, 2008 5:03 am
Profile
Regular

Joined: Sat Mar 04, 2006 3:17 pm
Posts: 307
Reply with quote
Post 
Hi guys

Is anyone willing/able to turn this into a shader filter?

NTSC tv phosphor simulation filter

Image is scaled(without filters) to 4800*2700

In each pixel color data is deleted so only 1 color remains

The deletion works as follows:
(width*height)
10*45 black pixels(all color data is dropped)
10*45 red pixles (blue and green are dropped)
10*45 black pixels(all color data is dropped)
10*45 green pixels(Red and blue are dropped)
10*45 black pixels(all color data is dropped)
10*45 blue pixels(red and green are dropped)

Each 10*45 block is averaged into a single color
The 6 10*45 blocks are mixed into a new single color

The single color 60*45 block is scaled down to 1 pixel

The result is a single 800*600 image which can then be displayed on screen

This image will be an accurate representation of a basic NTSC tv's phosphor map. However due to the lack of whiter than white's the image will look overly dark.

Without a working filter there is no way to see how much gamma correction is needed to fix this.

I bet this whole calculation could be simplified into a single line of code by someone good with math


Thu Aug 21, 2008 1:41 pm
Profile
Regular
User avatar

Joined: Tue Mar 07, 2006 10:32 am
Posts: 347
Location: The Netherlands
Reply with quote
Post 
Because of the way shaders work, we cannot resize the input to a 4800*2700 image before processing (at least in the current implementation). We get a 1024x1024 image from bsnes of which only a part is in use (i.e. 256x224 for unfiltered low-res NTSC), and we output to whatever scale factor you have bsnes set to.

Anyway, that doesn't mean your idea won't work just fine, just not in the way you presented it :)


Thu Aug 21, 2008 3:25 pm
Profile
Regular

Joined: Sat Mar 04, 2006 3:17 pm
Posts: 307
Reply with quote
Post 
okay.

i think the entire thing, apart from the stretch to 800x600 part can be done with math alone.


Thu Aug 21, 2008 8:36 pm
Profile
Display posts from previous:  Sort by  
This topic is locked, you cannot edit posts or make further replies.   [ 158 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software.