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,227
Trophies
1
Age
43
Location
somewhere
Website
spinalcode.co.uk
XP
3,402
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
    K3Nv2 @ K3Nv2: I was about to be like can't wait for gta6 so @Psionic Roshambo can tell me places to go then... +2