Homebrew [Release] {beta} sf2dlib - Simple and Fast 2D library (using the GPU)

Davideesk

Well-Known Member
Newcomer
Joined
Aug 19, 2015
Messages
67
Trophies
0
Age
27
XP
395
Country
United States
Can anyone provide a working example of using GPU_SetAlphaBlending (or something similar) to modify the sf2d render code? No matter what I try I can't seem to get much to work. I eventually just gave up and ported the original code from minicraft, and the results were poor.

7eYUr3s.jpg


Just having 4 lantern entities on the ground is enough to drop the frame-rate below 60. Modifying each pixel individually is not going to work. Does anyone have a better solution, preferably something GPU related?
Here is the original code for reference.
Code:
/* Software-render code, it is bad for the framerate. */
void renderLight(int x, int y, int r){
    x-=offsetX;
    y-=offsetY;

    int x0 = x - r;
    int x1 = x + r;
    int y0 = y - r;
    int y1 = y + r;
   
    int xx, yy;
    for (yy = y0; yy < y1; yy++) {
        int yd = yy - y;
        yd = yd * yd;
        for (xx = x0; xx < x1; xx++) {
            int xd = xx - x;
            int dist = xd * xd + yd;
            if (dist <= r * r) sf2d_set_pixel(lightScreen, xx, yy, 0); // set transparent pixel
        }
    }
}
 

Nutzer

New Member
Newbie
Joined
Jun 29, 2015
Messages
3
Trophies
0
Age
35
XP
61
Country
Gambia, The
Code:
shader.vsh
sf2d.c
arm-none-eabi-gcc -MMD -MP -MF /c/Users/Nutzer/Documents/libsf2d/build/sf2d.d -g -Wall -O2 -march=armv6k -mtune=mpcore -mfloat-abi=hard -I/c/Users/Nutzer/Documents/libsf2d/include -I/c/devkitPro/libctru/include -I/c/Users/Nutzer/Documents/libsf2d/build -DARM11 -D_3DS -c /c/Users/Nutzer/Documents/libsf2d/source/sf2d.c -o sf2d.o 
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:36:8: error: unknown type name 'aptHookCookie'
 static aptHookCookie apt_hook_cookie;
        ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_init_advanced':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:79:2: warning: implicit declaration of function 'aptHook' [-Wimplicit-function-declaration]
  aptHook(&apt_hook_cookie, apt_hook_func, NULL);
  ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_fini':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:104:2: warning: implicit declaration of function 'aptUnhook' [-Wimplicit-function-declaration]
  aptUnhook(&apt_hook_cookie);
  ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_start_frame':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:154:19: error: 'GPU_STENCIL_KEEP' undeclared (first use in this function)
  GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
                   ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:154:19: note: each undeclared identifier is reported only once for each function it appears in
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'apt_hook_func':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:284:14: error: 'APTHOOK_ONRESTORE' undeclared (first use in this function)
  if (hook == APTHOOK_ONRESTORE) {
              ^
make[1]: *** [sf2d.o] Error 1
make: *** [build] Error 2

...could you tell me what I'm doing wrong?
 

Garcia98

Hey! Listen!
Member
Joined
Sep 8, 2015
Messages
361
Trophies
0
Location
Salamanca
Website
github.com
XP
267
Country
Code:
shader.vsh
sf2d.c
arm-none-eabi-gcc -MMD -MP -MF /c/Users/Nutzer/Documents/libsf2d/build/sf2d.d -g -Wall -O2 -march=armv6k -mtune=mpcore -mfloat-abi=hard -I/c/Users/Nutzer/Documents/libsf2d/include -I/c/devkitPro/libctru/include -I/c/Users/Nutzer/Documents/libsf2d/build -DARM11 -D_3DS -c /c/Users/Nutzer/Documents/libsf2d/source/sf2d.c -o sf2d.o
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:36:8: error: unknown type name 'aptHookCookie'
static aptHookCookie apt_hook_cookie;
        ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_init_advanced':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:79:2: warning: implicit declaration of function 'aptHook' [-Wimplicit-function-declaration]
  aptHook(&apt_hook_cookie, apt_hook_func, NULL);
  ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_fini':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:104:2: warning: implicit declaration of function 'aptUnhook' [-Wimplicit-function-declaration]
  aptUnhook(&apt_hook_cookie);
  ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'sf2d_start_frame':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:154:19: error: 'GPU_STENCIL_KEEP' undeclared (first use in this function)
  GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP);
                   ^
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:154:19: note: each undeclared identifier is reported only once for each function it appears in
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c: In function 'apt_hook_func':
c:/Users/Nutzer/Documents/libsf2d/source/sf2d.c:284:14: error: 'APTHOOK_ONRESTORE' undeclared (first use in this function)
  if (hook == APTHOOK_ONRESTORE) {
              ^
make[1]: *** [sf2d.o] Error 1
make: *** [build] Error 2

...could you tell me what I'm doing wrong?

Use latest ctrulib version
 

Davideesk

Well-Known Member
Newcomer
Joined
Aug 19, 2015
Messages
67
Trophies
0
Age
27
XP
395
Country
United States
I would like to request a screenshot function feature for a future update, so people don't have to use a phone to take screenshots of their game.

I actually wrote my own quick hacky version of it into sf2d_end_frame. It creates a PPM image that I then convert to a png file later on. (I highly don't recommend anyone to use this code, as it was made quick and dirty)

Code:
void sf2d_end_frame(bool shouldTakeScreenShot)
{
    GPU_FinishDrawing();
    GPUCMD_Finalize();
    GPUCMD_FlushAndRun(NULL);
    gspWaitForP3D();

    //Copy the GPU rendered FB to the screen FB
    if (cur_screen == GFX_TOP) {
        GX_SetDisplayTransfer(NULL, gpu_fb_addr, GX_BUFFER_DIM(240, 400),
            (u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL),
            GX_BUFFER_DIM(240, 400), 0x1000);

             if(shouldTakeScreenShot){
                    const int dimx = 240, dimy = 400;
                    FILE *fp = fopen("top.ppm", "wb"); /* b - binary mode */
                    fprintf(fp, "P6\n%d %d\n255\n", dimx, dimy);
                    u8 * buf = gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL);
                    int i;
                    /* Switch from BGR to RGB */
                    for(i=0; i < 240*400; i++){
                        u8 buf1 = buf[i*3+0];
                        buf[i*3+0] = buf[i*3+2];
                        buf[i*3+2] = buf1;
                    }
                    fwrite(buf, 240*400*3,1, fp);
                    fclose(fp);
                }

    } else {
        GX_SetDisplayTransfer(NULL, gpu_fb_addr, GX_BUFFER_DIM(240, 320),
            (u32 *)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL),
            GX_BUFFER_DIM(240, 320), 0x1000);

            if(shouldTakeScreenShot){
                    const int dimx = 240, dimy = 320;
                    FILE *fp = fopen("bottom.ppm", "wb"); /* b - binary mode */
                    fprintf(fp, "P6\n%d %d\n255\n", dimx, dimy);
                    u8 * buf = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
                    int i;
                    /* Switch from BGR to RGB */
                    for(i=0; i < 240*320; i++){
                        u8 buf1 = buf[i*3+0];
                        buf[i*3+0] = buf[i*3+2];
                        buf[i*3+2] = buf1;
                    }
                    fwrite(buf, 240*320*3,1, fp);
                    fclose(fp);
                }

    }
    gspWaitForPPF();

    //Clear the screen
    GX_SetMemoryFill(NULL, gpu_fb_addr, clear_color, &gpu_fb_addr[0x2EE00],
        0x201, gpu_depth_fb_addr, 0x00000000, &gpu_depth_fb_addr[0x2EE00], 0x201);
    gspWaitForPSC0();
}

Here is the result from the code and some very minor editing:

Udqdk23.png


I chose PPM because it was the simplest image format to make, however most programs like Paint.net don't seem to support it. So I had to use a converter website to make the image a PNG file. Preferably making a .png, .jpg, or even a .bmp would be better. I'm not sure how complicated that would make things.

What do you think?
 

william341

Last remaining VinsClone
Member
Joined
Dec 26, 2014
Messages
391
Trophies
0
Age
29
XP
280
Country
United States
I would like to request a screenshot function feature for a future update, so people don't have to use a phone to take screenshots of their game.

I actually wrote my own quick hacky version of it into sf2d_end_frame. It creates a PPM image that I then convert to a png file later on. (I highly don't recommend anyone to use this code, as it was made quick and dirty)

Code:
void sf2d_end_frame(bool shouldTakeScreenShot)
{
    GPU_FinishDrawing();
    GPUCMD_Finalize();
    GPUCMD_FlushAndRun(NULL);
    gspWaitForP3D();

    //Copy the GPU rendered FB to the screen FB
    if (cur_screen == GFX_TOP) {
        GX_SetDisplayTransfer(NULL, gpu_fb_addr, GX_BUFFER_DIM(240, 400),
            (u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL),
            GX_BUFFER_DIM(240, 400), 0x1000);

             if(shouldTakeScreenShot){
                    const int dimx = 240, dimy = 400;
                    FILE *fp = fopen("top.ppm", "wb"); /* b - binary mode */
                    fprintf(fp, "P6\n%d %d\n255\n", dimx, dimy);
                    u8 * buf = gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL);
                    int i;
                    /* Switch from BGR to RGB */
                    for(i=0; i < 240*400; i++){
                        u8 buf1 = buf[i*3+0];
                        buf[i*3+0] = buf[i*3+2];
                        buf[i*3+2] = buf1;
                    }
                    fwrite(buf, 240*400*3,1, fp);
                    fclose(fp);
                }

    } else {
        GX_SetDisplayTransfer(NULL, gpu_fb_addr, GX_BUFFER_DIM(240, 320),
            (u32 *)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL),
            GX_BUFFER_DIM(240, 320), 0x1000);

            if(shouldTakeScreenShot){
                    const int dimx = 240, dimy = 320;
                    FILE *fp = fopen("bottom.ppm", "wb"); /* b - binary mode */
                    fprintf(fp, "P6\n%d %d\n255\n", dimx, dimy);
                    u8 * buf = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
                    int i;
                    /* Switch from BGR to RGB */
                    for(i=0; i < 240*320; i++){
                        u8 buf1 = buf[i*3+0];
                        buf[i*3+0] = buf[i*3+2];
                        buf[i*3+2] = buf1;
                    }
                    fwrite(buf, 240*320*3,1, fp);
                    fclose(fp);
                }

    }
    gspWaitForPPF();

    //Clear the screen
    GX_SetMemoryFill(NULL, gpu_fb_addr, clear_color, &gpu_fb_addr[0x2EE00],
        0x201, gpu_depth_fb_addr, 0x00000000, &gpu_depth_fb_addr[0x2EE00], 0x201);
    gspWaitForPSC0();
}

Here is the result from the code and some very minor editing:

Udqdk23.png


I chose PPM because it was the simplest image format to make, however most programs like Paint.net don't seem to support it. So I had to use a converter website to make the image a PNG file. Preferably making a .png, .jpg, or even a .bmp would be better. I'm not sure how complicated that would make things.

What do you think?

You should make it self-convert. Also how is MiniCraft3ds. It's HYPE here as i love that game and cant wait for it to be out.
 

Davideesk

Well-Known Member
Newcomer
Joined
Aug 19, 2015
Messages
67
Trophies
0
Age
27
XP
395
Country
United States
You should make it self-convert. Also how is MiniCraft3ds. It's HYPE here as i love that game and cant wait for it to be out.

The game itself is about 80% complete. The two main obstacles I have right now is the underground lighting (see earlier posts) and sound. I have not seen any documentation on sound yet, so i'm kinda hoping that someone makes a 3ds sound library for us c/c++ makers.
 

william341

Last remaining VinsClone
Member
Joined
Dec 26, 2014
Messages
391
Trophies
0
Age
29
XP
280
Country
United States
The game itself is about 80% complete. The two main obstacles I have right now is the underground lighting (see earlier posts) and sound. I have not seen any documentation on sound yet, so i'm kinda hoping that someone makes a 3ds sound library for us c/c++ makers.
I'd be glad to test it for you!
 

Garcia98

Hey! Listen!
Member
Joined
Sep 8, 2015
Messages
361
Trophies
0
Location
Salamanca
Website
github.com
XP
267
Country
I don't know how to use it. Can you load up a .wav file and play it?

I don't know about WAV files but for loading a RAW PCM audio file you can use the following code:

Code:
// Audio variables
u8* buffer;
u32 size;

// Audio functions (load audio)
void audio_load(const char *audio){
    FILE *file = fopen(audio, "rb");
    fseek(file, 0, SEEK_END);
    off_t size = ftell(file);
    fseek(file, 0, SEEK_SET);
    buffer = linearAlloc(size);
    off_t bytesRead = fread(buffer, 1, size, file);
    fclose(file);
    csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, buffer, buffer, size);
    linearFree(buffer);
}

// Audio functions (stop audio)
void audio_stop(void){
    csndExecCmds(true);
    CSND_SetPlayState(0x8, 0);
    memset(buffer, 0, size);
    GSPGPU_FlushDataCache(NULL, buffer, size);
    linearFree(buffer);
}
 

Lucar

Well-Known Member
Member
Joined
Sep 12, 2015
Messages
528
Trophies
0
XP
619
Country
Canada
Cant seem to compile, I think it's because I have python 2.7 and 3 installed, so it's using python 2.7 and not 3 via the 'python' command, instead of 'python3'. I don't know how to make 'make' run the file in Python 3 instead of Python 2. Help?

Code:
vectrex@Vectrex:~/devkitPro/sf2dlib-master/libsf2d$ make
shader.vsh
  File "/home/vectrex/devkitPro/sf2dlib-master/aemstro.py", line 158
    print("    "*numIdent+s,end='')
                           ^
SyntaxError: invalid syntax
make[1]: *** [shader.vsh.o] Error 1
make: *** [build] Error 2
 
Last edited by Lucar,

Davideesk

Well-Known Member
Newcomer
Joined
Aug 19, 2015
Messages
67
Trophies
0
Age
27
XP
395
Country
United States
I don't know about WAV files but for loading a RAW PCM audio file you can use the following code:

Code:
// Audio variables
u8* buffer;
u32 size;

// Audio functions (load audio)
void audio_load(const char *audio){
    FILE *file = fopen(audio, "rb");
    fseek(file, 0, SEEK_END);
    off_t size = ftell(file);
    fseek(file, 0, SEEK_SET);
    buffer = linearAlloc(size);
    off_t bytesRead = fread(buffer, 1, size, file);
    fclose(file);
    csndPlaySound(8, SOUND_FORMAT_16BIT | SOUND_REPEAT, 44100, 1, 0, buffer, buffer, size);
    linearFree(buffer);
}

// Audio functions (stop audio)
void audio_stop(void){
    csndExecCmds(true);
    CSND_SetPlayState(0x8, 0);
    memset(buffer, 0, size);
    GSPGPU_FlushDataCache(NULL, buffer, size);
    linearFree(buffer);
}

I converted my .wav files to .raw and this code works perfectly with them. Thank you! :)
 
  • Like
Reactions: Garcia98

spinal_cord

Knows his stuff
Member
Joined
Jul 21, 2007
Messages
3,231
Trophies
1
Age
43
Location
somewhere
Website
spinalcode.co.uk
XP
3,450
Country
I haven't really looked into this lib yet but...

Would this lib be faster than doing the following?
Code:
    // get screen buffer
    u8* bufAdr=gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);

    int slider = 22- ((CONFIG_3D_SLIDERSTATE)*22); // scroll screen using 3d slider!
  
    for(int y=slider; y<240+slider; y++){
        for(int x=0; x<384; x++){
            int r = palette_red[bufmem[x+512*y]];
            int g = palette_green[bufmem[x+512*y]];
            int b = palette_blue[bufmem[x+512*y]];
            drawPixel(x+8,y-slider,r,g,b,bufAdr);
        }
    }

(the slider part isn't really important at all)

Is there for example an 8bit paletted texture format or something?
 
Last edited by spinal_cord,
  • Like
Reactions: Cid2mizard

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • Xdqwerty @ Xdqwerty:
    Brb going with my dad
  • Xdqwerty @ Xdqwerty:
    @Psionic Roshambo, are most of those games shovelware?
    +1
  • K3Nv2 @ K3Nv2:
    Nah gotta buy 3 1tb SD cards for 3ds the entire libraries need archived in my home
    +1
  • SylverReZ @ SylverReZ:
    >buys x3 1TB SD cards
    >stores the entire 3DS library on them
    >installs CFW
    >realised why I wasted loads of money and resources
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    Lol no I clean my sets
  • K3Nv2 @ K3Nv2:
    Cause it's in my home ready to go
  • K3Nv2 @ K3Nv2:
    Like uremum
  • Psionic Roshambo @ Psionic Roshambo:
    But 100 games on SNES and Genesis and GBA then TG16 and NES and GB and GBC then all the other random systems and arcade games it all adds up lol
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Virtual Boy alone has probably 5 games!!! Lol
    +1
  • K3Nv2 @ K3Nv2:
    I won't mention any names in chat but some of us wastes $300 on preloaded hdds :tpi:
    +1
  • SylverReZ @ SylverReZ:
    @Psionic Roshambo, The PS5 had none.
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    Lol I spent more than that on a stuffed 4TB drive lol
  • K3Nv2 @ K3Nv2:
    Honestly I've yet to fill the 1tb internal drive on my ps5
    +1
  • Xdqwerty @ Xdqwerty:
    @SylverReZ, 1) except final fantasy 16. 2) why would I have a console's whole catalogue if most of the games are either shovelware or terrible games?
  • Psionic Roshambo @ Psionic Roshambo:
    Kind of a waste, but the allure of all those games over 100,000
  • Psionic Roshambo @ Psionic Roshambo:
    Some shovel ware with low ratings you might enjoy more than the ratings would sugest
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Cruisn on the Wii is one of my personal examples of that, it's considered one of the worst games of all time, I loved it and completed it several times.
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    The trick for me was to go into the settings and crank up the Wiimote sensitivity to the max and it gets twitchy but you can win that way lol
  • Psionic Roshambo @ Psionic Roshambo:
    Lots of other games I enjoyed that reviews would say otherwise lol
  • btei @ btei:
    lethal company servers are down rn
  • btei @ btei:
    my pocket pikachu is going crazy rn
  • Psionic Roshambo @ Psionic Roshambo:
    Pocket Pikachu sounds dirty lol
  • SylverReZ @ SylverReZ:
    True lol
    SylverReZ @ SylverReZ: :tpi: