Homebrew app Want to use shapes on my 3DS with devkitpro.

Yukkuri_XP

New Member
OP
Newbie
Joined
Oct 14, 2022
Messages
4
Trophies
0
Location
ヰンドウズ
XP
65
Country
Japan
Hi.
I am making a program to draw shapes in devkitpro 3DS, but I am unable to build it due to an error.
I would appreciate it if you could tell me where I can correct the problem.
C++:
#include <3ds.h>
#include <stdio.h>
#include <string.h>

u8* pDispBuffer;
unsigned char PenColor[3];
unsigned char BrushColor[3];
unsigned int ClippingRect[4];

#define XYtoOfset(x,y) ((239-y)*3+(x*720))

//SelectFrame : set the frame pointer
// u8* pFrame : Pointer to framebuffer obtained by gfxGetFramebuffer
//
// Note: Always specify this before drawing

void SelectFrame(u8* pFrame) {
    if (pFrame) {
        pDispBuffer = pFrame;
    }
}

//SetClipping : set clipping area
// int x1,y1 : start point coordinates
// int x2,y2 : end point coordinates
void SetClipping(int x1, int y1, int x2, int y2) {
    ClippingRect[0] = x1;
    ClippingRect[1] = y1;
    ClippingRect[2] = x2;
    ClippingRect[3] = y2;
}
//SetPenColor          :pen color
// unsigned char r,g,b :color (RGB)
void SetPenColor(unsigned char r, unsigned char g, unsigned char b) {
    PenColor[2] = r;
    PenColor[1] = g;
    PenColor[0] = b;
}

//SetBrushColor        :brush color
// unsigned char r,g,b :color (RGB)
void SetBrushColor(unsigned char r, unsigned char g, unsigned char b) {
    BrushColor[2] = r;
    BrushColor[1] = g;
    BrushColor[0] = b;
}

//DrawDot : draw a point
// int x1,y1: coordinates
//
// Note: the color selected with the pen will be used.
void DrawDot(int x1, int y1) {
    if (pDispBuffer == NULL) return;
    if ((ClippingRect[0]<=x1)&&(ClippingRect[1]<=y1)&&(ClippingRect[2]>=x1)&&(ClippingRect[3]>=y1))
        memcpy(pDispBuffer + XYtoOfset(x1, y1), PenColor, sizeof(PenColor));
}

//DrawLine : draw a line
// int x1,y1 : start point coordinates
// int x2,y2 : end point coordinates
//
// Note: the color selected with the pen will be used.
void DrawLine(int x1, int y1, int x2, int y2) {
    DrawLineEx(x1, y1, x2, y2, (PenColor[2] << 16) | (PenColor[1] << 8) | PenColor[0]);
}
void DrawLineEx(int x1, int y1, int x2, int y2, int Color) {
    if (pDispBuffer == NULL) return;
    unsigned char brg[3] = { 0,0,0 };
    brg[2] = ((Color >> 16) & 0xFF);
    brg[1] = ((Color >> 8) & 0xFF);
    brg[0] = Color & 0xFF;
    int sp = 0, i = 0;
    double dSlope = 0.0, dSection = 0.0;
    if (x1 == x2) {
        if (y1 < y2) {
            sp = y1;
        } else {
            sp = y2;
        }
        for (i = sp; i < abs(y1 - y2)+sp; i++) {
            if ((ClippingRect[0]<=x1)&&(ClippingRect[1]<=i)&&(ClippingRect[2]>=x1)&&(ClippingRect[3]>=i))
                memcpy(pDispBuffer + XYtoOfset(x1, i), brg, sizeof(brg));
        }
        return;
    }
    dSlope = (double)(y1 - y2) / (double)(x1 - x2);
    dSection = (double)y1 - dSlope * x1;
    if (abs(x1 - x2) >= abs(y1 - y2)) {
        if (x1 < x2) {
            sp = x1;
        } else {
            sp = x2;
        }
        for (i = sp; i < abs(x1 - x2)+sp; i++) {
            if ((ClippingRect[0]<=i)&&(ClippingRect[1]<=(int)(dSlope * (double)i + dSection))&&(ClippingRect[2]>=i)&&(ClippingRect[3]>=(int)(dSlope * (double)i + dSection)))
                memcpy(pDispBuffer + XYtoOfset(i, (int)(dSlope * (double)i + dSection)), brg, sizeof(brg));
        }
    } else {
        if (y1 < y2) {
            sp = y1;
        } else {
            sp = y2;
        }
        for (i = sp; i < abs(y1 - y2)+sp; i++) {
            if ((ClippingRect[0]<=(int)((dSection*-1 + (double)i) / dSlope))&&(ClippingRect[1]<=i)&&(ClippingRect[2]>=(int)((dSection*-1 + (double)i) / dSlope))&&(ClippingRect[3]>=i))
                memcpy(pDispBuffer + XYtoOfset((int)((dSection*-1 + (double)i) / dSlope), i), brg, sizeof(brg));
        }
    }
}

//DrawRect : draw a filled rectangle
// int x1,y1 : start point coordinates
// int x2,y2 : end point coordinates
//
// Note: the color selected with the brush will be used.
void DrawRect(int x1, int y1, int x2, int y2) {
    if (pDispBuffer == NULL) return;
    for (int i1 = y1; i1 < y2; i1++) {
        for (int i2 = x1; i2 < x2; i2++) {
            if ((ClippingRect[0]<=i2)&&(ClippingRect[1]<=i1)&&(ClippingRect[2]>=i2)&&(ClippingRect[3]>=i1))
                memcpy(pDispBuffer + XYtoOfset(i2, i1), BrushColor, sizeof(BrushColor));
        }
    }
}

//DrawFrame : Draw a rectangle with only a frame
// int x1,y1 : start point coordinates
// int x2,y2 : end point coordinates
//
// Note: the color selected with the pen will be used.
void DrawFrame(int x1, int y1, int x2, int y2) {
    if (pDispBuffer == NULL) return;
    DrawLine(x1, y1, x2, y1);
    DrawLine(x2, y1, x2, y2 + 1);
    DrawLine(x2, y2, x1, y2);
    DrawLine(x1, y2, x1, y1);
}

//DrawCircle : draw a circle
// int x1,y1 : start point coordinates
// int x2,y2 : end point coordinates
// bool bPaint : whether to paint
//
// NOTE: The line will use the color selected with the pen.
// The color selected with the brush is used for filling.
void DrawCircle(int x1, int y1, int x2, int y2, bool bPaint) {
    if ((x1 == x2) || (y1 == y2)) return;
    int r = (x2 - x1) / 2, oldx = 0, oldy1 = 0, oldy2 = 0;
    double f = (double)(y2 - y1) / (double)(x2 - x1),tmp;
    int x = x1 + r, y = y1 + (int)((double)r*(double)f);
    if (bPaint) {
        for (int i = -r; i <= r; i++) {
            tmp = f*sqrt(r*r - i*i);
            DrawLineEx(x + i, y - tmp, x + i, y + tmp, (BrushColor[2] << 16) | (BrushColor[1] << 8) | BrushColor[0]);
        }
    }
    for (int i = -r; i <= r; i++) {
        tmp = f*sqrt(r*r - i*i);
        if (i == -r) {
            DrawDot(x + i, y - tmp);
            DrawDot(x + i, y + tmp);
        } else {
            DrawLine(x + i, y - tmp, oldx, oldy1);
            DrawLine(x + i, y + tmp, oldx, oldy2);
        }
        oldx = x + i;
        oldy1 = y - tmp;
        oldy2 = y + tmp;
    }
}

int main(void) {
    gfxInitDefault();
    gfxSetDoubleBuffering(GFX_TOP,true);

    int xpos = 190;
    int ypos = 110;

    while (aptMainLoop()) {
        hidScanInput();
        unsigned int keyDown = hidKeysDown();

        u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
        SelectFrame(fb);

        SetBrushColor(0,0,0);
        DrawRect(0,0,400,240);

        SetBrushColor(255,255,255);
        DrawCircle( xpos, ypos, xpos+20, ypos+20, true);
        if (keyDown & KEY_START) break;
        gfxFlushBuffers();
        gfxSwapBuffers();
        gspWaitForVBlank();
        };
    gfxExit();
    return 0;
};

Is there a library for drawing shapes with devkitpro on 3DS?
If anyone knows, please let me know.

↓The command prompt looks like this.
View attachment 332172
 
Last edited by Yukkuri_XP,

poisoned_soap

Member
Newcomer
Joined
May 10, 2020
Messages
7
Trophies
0
Age
20
XP
303
Country
United States
citro2d is the built-in library for drawing shapes, images and sprites.
You can use this site fo learn more about it, and I'm pretty sure you need to change the makefile in order for the program to actually compile.
 

Yukkuri_XP

New Member
OP
Newbie
Joined
Oct 14, 2022
Messages
4
Trophies
0
Location
ヰンドウズ
XP
65
Country
Japan
citro2d is the built-in library for drawing shapes, images and sprites.
You can use fo learn more about it, and I'm pretty sure you need to change the makefile in order for the program to actually compile.
Sorry, but is it possible to draw shapes only with gfxGetFramebuffer and memcpy?
I used to be able to use this module, but after updating devkitpro, it is no longer available.
C++:
void SelectFrame(u8* pFrame) {
    if (pFrame) {
        pDispBuffer = pFrame;
    }
}

void SetClipping(int x1, int y1, int x2, int y2) {
    ClippingRect[0] = x1;
    ClippingRect[1] = y1;
    ClippingRect[2] = x2;
    ClippingRect[3] = y2;
}
//SetPenColor
// unsigned char r,g,b
void SetPenColor(unsigned char r, unsigned char g, unsigned char b) {
    PenColor[2] = r;
    PenColor[1] = g;
    PenColor[0] = b;
}

void SetBrushColor(unsigned char r, unsigned char g, unsigned char b) {
    BrushColor[2] = r;
    BrushColor[1] = g;
    BrushColor[0] = b;
}

void DrawDot(int x1, int y1) {
    if (pDispBuffer == NULL) return;
    if ((ClippingRect[0]<=x1)&&(ClippingRect[1]<=y1)&&(ClippingRect[2]>=x1)&&(ClippingRect[3]>=y1))
        memcpy(pDispBuffer + XYtoOfset(x1, y1), PenColor, sizeof(PenColor));
}

void DrawLine(int x1, int y1, int x2, int y2) {
    DrawLineEx(x1, y1, x2, y2, (PenColor[2] << 16) | (PenColor[1] << 8) | PenColor[0]);
}
void DrawLineEx(int x1, int y1, int x2, int y2, int Color) {
    if (pDispBuffer == NULL) return;
    unsigned char brg[3] = { 0,0,0 };
    brg[2] = ((Color >> 16) & 0xFF);
    brg[1] = ((Color >> 8) & 0xFF);
    brg[0] = Color & 0xFF;
    int sp = 0, i = 0;
    double dSlope = 0.0, dSection = 0.0;
    if (x1 == x2) {
        if (y1 < y2) {
            sp = y1;
        } else {
            sp = y2;
        }
        for (i = sp; i < abs(y1 - y2)+sp; i++) {
            if ((ClippingRect[0]<=x1)&&(ClippingRect[1]<=i)&&(ClippingRect[2]>=x1)&&(ClippingRect[3]>=i))
                memcpy(pDispBuffer + XYtoOfset(x1, i), brg, sizeof(brg));
        }
        return;
    }
    dSlope = (double)(y1 - y2) / (double)(x1 - x2);
    dSection = (double)y1 - dSlope * x1;
    if (abs(x1 - x2) >= abs(y1 - y2)) {
        if (x1 < x2) {
            sp = x1;
        } else {
            sp = x2;
        }
        for (i = sp; i < abs(x1 - x2)+sp; i++) {
            if ((ClippingRect[0]<=i)&&(ClippingRect[1]<=(int)(dSlope * (double)i + dSection))&&(ClippingRect[2]>=i)&&(ClippingRect[3]>=(int)(dSlope * (double)i + dSection)))
                memcpy(pDispBuffer + XYtoOfset(i, (int)(dSlope * (double)i + dSection)), brg, sizeof(brg));
        }
    } else {
        if (y1 < y2) {
            sp = y1;
        } else {
            sp = y2;
        }
        for (i = sp; i < abs(y1 - y2)+sp; i++) {
            if ((ClippingRect[0]<=(int)((dSection*-1 + (double)i) / dSlope))&&(ClippingRect[1]<=i)&&(ClippingRect[2]>=(int)((dSection*-1 + (double)i) / dSlope))&&(ClippingRect[3]>=i))
                memcpy(pDispBuffer + XYtoOfset((int)((dSection*-1 + (double)i) / dSlope), i), brg, sizeof(brg));
        }
    }
}

void DrawRect(int x1, int y1, int x2, int y2) {
    if (pDispBuffer == NULL) return;
    for (int i1 = y1; i1 < y2; i1++) {
        for (int i2 = x1; i2 < x2; i2++) {
            if ((ClippingRect[0]<=i2)&&(ClippingRect[1]<=i1)&&(ClippingRect[2]>=i2)&&(ClippingRect[3]>=i1))
                memcpy(pDispBuffer + XYtoOfset(i2, i1), BrushColor, sizeof(BrushColor));
        }
    }
}

void DrawFrame(int x1, int y1, int x2, int y2) {
    if (pDispBuffer == NULL) return;
    DrawLine(x1, y1, x2, y1);
    DrawLine(x2, y1, x2, y2 + 1);
    DrawLine(x2, y2, x1, y2);
    DrawLine(x1, y2, x1, y1);
}

void DrawCircle(int x1, int y1, int x2, int y2, bool bPaint) {
    if ((x1 == x2) || (y1 == y2)) return;
    int r = (x2 - x1) / 2, oldx = 0, oldy1 = 0, oldy2 = 0;
    double f = (double)(y2 - y1) / (double)(x2 - x1),tmp;
    int x = x1 + r, y = y1 + (int)((double)r*(double)f);
    if (bPaint) {
        for (int i = -r; i <= r; i++) {
            tmp = f*sqrt(r*r - i*i);
            DrawLineEx(x + i, y - tmp, x + i, y + tmp, (BrushColor[2] << 16) | (BrushColor[1] << 8) | BrushColor[0]);
        }
    }
    for (int i = -r; i <= r; i++) {
        tmp = f*sqrt(r*r - i*i);
        if (i == -r) {
            DrawDot(x + i, y - tmp);
            DrawDot(x + i, y + tmp);
        } else {
            DrawLine(x + i, y - tmp, oldx, oldy1);
            DrawLine(x + i, y + tmp, oldx, oldy2);
        }
        oldx = x + i;
        oldy1 = y - tmp;
        oldy2 = y + tmp;
    }
}

void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, bool bPaint) {
}
*/
 
Last edited by Yukkuri_XP,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • K3Nv2 @ K3Nv2:
    How do you know if the night will be good when you're asleep
  • BakerMan @ BakerMan:
    because i didn't say i was asleep
  • BakerMan @ BakerMan:
    i said i was sleeping...
  • BakerMan @ BakerMan:
    sleeping with uremum
  • K3Nv2 @ K3Nv2:
    Even my mum slept on that uremum
  • TwoSpikedHands @ TwoSpikedHands:
    yall im torn... ive been hacking away at tales of phantasia GBA (the USA version) and have so many documents of reverse engineering i've done
  • TwoSpikedHands @ TwoSpikedHands:
    I just found out that the EU version is better in literally every way, better sound quality, better lighting, and there's even a patch someone made to make the text look nicer
  • TwoSpikedHands @ TwoSpikedHands:
    Do I restart now using what i've learned on the EU version since it's a better overall experience? or do I continue with the US version since that is what ive been using, and if someone decides to play my hack, it would most likely be that version?
  • Sicklyboy @ Sicklyboy:
    @TwoSpikedHands, I'll preface this with the fact that I know nothing about the game, but, I think it depends on what your goals are. Are you trying to make a definitive version of the game? You may want to refocus your efforts on the EU version then. Or, are you trying to make a better US version? In which case, the only way to make a better US version is to keep on plugging away at that one ;)
  • Sicklyboy @ Sicklyboy:
    I'm not familiar with the technicalities of the differences between the two versions, but I'm wondering if at least some of those differences are things that you could port over to the US version in your patch without having to include copyrighted assets from the EU version
  • TwoSpikedHands @ TwoSpikedHands:
    @Sicklyboy I am wanting to fully change the game and bend it to my will lol. I would like to eventually have the ability to add more characters, enemies, even have a completely different story if i wanted. I already have the ability to change the tilemaps in the US version, so I can basically make my own map and warp to it in game - so I'm pretty far into it!
  • TwoSpikedHands @ TwoSpikedHands:
    I really would like to make a hack that I would enjoy playing, and maybe other people would too. swapping to the EU version would also mean my US friends could not legally play it
  • TwoSpikedHands @ TwoSpikedHands:
    I am definitely considering porting over some of the EU features without using the actual ROM itself, tbh that would probably be the best way to go about it... but i'm sad that the voice acting is so.... not good on the US version. May not be a way around that though
  • TwoSpikedHands @ TwoSpikedHands:
    I appreciate the insight!
  • The Real Jdbye @ The Real Jdbye:
    @TwoSpikedHands just switch, all the knowledge you learned still applies and most of the code and assets should be the same anyway
  • The Real Jdbye @ The Real Jdbye:
    and realistically they wouldn't

    be able to play it legally anyway since they need a ROM and they probably don't have the means to dump it themselves
  • The Real Jdbye @ The Real Jdbye:
    why the shit does the shitbox randomly insert newlines in my messages
  • Veho @ Veho:
    It does that when I edit a post.
  • Veho @ Veho:
    It inserts a newline in a random spot.
  • The Real Jdbye @ The Real Jdbye:
    never had that i don't think
  • Karma177 @ Karma177:
    do y'all think having an sd card that has a write speed of 700kb/s is a bad idea?
    trying to restore emunand rn but it's taking ages... (also when I finished the first time hekate decided to delete all my fucking files :wacko:)
  • The Real Jdbye @ The Real Jdbye:
    @Karma177 that sd card is 100% faulty so yes, its a bad idea
  • The Real Jdbye @ The Real Jdbye:
    even the slowest non-sdhc sd cards are a few MB/s
  • Karma177 @ Karma177:
    @The Real Jdbye it hasn't given me any error trying to write things on it so I don't really think it's faulty (pasted 40/50gb+ folders and no write errors)
    Karma177 @ Karma177: @The Real Jdbye it hasn't given me any error trying to write things on it so I don't really...