Homebrew Homebrew Development

  • Thread starter Thread starter aliak11
  • Start date Start date
  • Views Views 1,493,468
  • Replies Replies 6,048
  • Likes Likes 54
I moved CFW plugin threads in the homebrew section (as it's developed tools intended to be run on the console/firmware). But CFW itself are kept in flashcart and playing ROM section.
We are still unsure where to move some threads, we will see with time.

It should be easier to find homebrew projects now (less than 10 pages of homebrew threads).
I'll link to it in a minute when I find it.
Edit: found one for zelda : https://gbatemp.net/threads/release-zelda-a-link-between-worlds-usa-cheat-plugin.375916/
but not general plugin for all games.


Palentine cFW has memory peek/poke feature.


There's also this thread :
https://twitter.com/Bond697/status/490613314859569152

it's still in flashcart forum as we (currently) don't have better place to post general hacking progress.
 
I know, but why are there no functions for drawing on the screen?


3DS Framebuffer is 24bpp, so we have 8 bits per color, we can write a function to write in screen like it:

Code:
void drawPixel(int x, int y, unsigned char R, unsigned char G, unsigned char B) {
        u8* bufAdr = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
        // calcule the position on screen with x and y and save in a var, like var Z
       
       bufAdr[z] = B;
       bufAdr[z + 1] = G;
       bufAdr[z + 2] = R;
}
 
3DS Framebuffer is 24bpp, so we have 8 bits per color, we can write a function to write in screen like it:

Code:
void drawPixel(int x, int y, unsigned char R, unsigned char G, unsigned char B) {
        [B]u8* bufAdr = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);[/B]
        // calcule the position on screen with x and y and save in a var, like var Z
     
      bufAdr[z] = B;
      bufAdr[z + 1] = G;
      bufAdr[z + 2] = R;
}
Ok, but this function would only draw to the top screen left framebuffer right? So you would need to create another one for the bottom screen and the top right framebuffer.
 
  • Like
Reactions: st4rk
You can use one only function to manage every framebuffer

Code:
void DrawPixel(int x,int y,u32 color,int screen, int side){
int idx = ((x)*240) + (239-(y));
if ((screen == 0) && (x < 400) && (y < 240) && (x >= 0) && (y >= 0)){
if (side == 0){
TopLFB[idx*3+0] = (color);
TopLFB[idx*3+1] = (color) >> 8;
TopLFB[idx*3+2] = (color) >> 16;
}else{
TopRFB[idx*3+0] = (color);
TopRFB[idx*3+1] = (color) >> 8;
TopRFB[idx*3+2] = (color) >> 16;
}
}else if((screen == 1) && (x < 320) && (y < 240) && (x >= 0) && (y >= 0)){
BottomFB[idx*3+0] = (color);
BottomFB[idx*3+1] = (color) >> 8;
BottomFB[idx*3+2] = (color) >> 16;
}
}
 
You can use one only function to manage every framebuffer

Code:
void DrawPixel(int x,int y,u32 color,int screen, int side){
int idx = ((x)*240) + (239-(y));
if ((screen == 0) && (x < 400) && (y < 240) && (x >= 0) && (y >= 0)){
if (side == 0){
TopLFB[idx*3+0] = (color);
TopLFB[idx*3+1] = (color) >> 8;
TopLFB[idx*3+2] = (color) >> 16;
}else{
TopRFB[idx*3+0] = (color);
TopRFB[idx*3+1] = (color) >> 8;
TopRFB[idx*3+2] = (color) >> 16;
}
}else if((screen == 1) && (x < 320) && (y < 240) && (x >= 0) && (y >= 0)){
BottomFB[idx*3+0] = (color);
BottomFB[idx*3+1] = (color) >> 8;
BottomFB[idx*3+2] = (color) >> 16;
}
}
Ok, but where do the FB arrays come from?
 
Code:
u8* TopLFB = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
u8* TopRFB = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL);
u8* BottomFB = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);

You can find some drawing functions in all currently released homebrews, this is for example Graphic module for my Lua interpreter:
https://github.com/Rinnegatamante/lpp-3ds/blob/master/source/luaGraphics.cpp
 
You can use one only function to manage every framebuffer

Code:
void DrawPixel(int x,int y,u32 color,int screen, int side){
int idx = ((x)*240) + (239-(y));
if ((screen == 0) && (x < 400) && (y < 240) && (x >= 0) && (y >= 0)){
if (side == 0){
TopLFB[idx*3+0] = (color);
TopLFB[idx*3+1] = (color) >> 8;
TopLFB[idx*3+2] = (color) >> 16;
}else{
TopRFB[idx*3+0] = (color);
TopRFB[idx*3+1] = (color) >> 8;
TopRFB[idx*3+2] = (color) >> 16;
}
}else if((screen == 1) && (x < 320) && (y < 240) && (x >= 0) && (y >= 0)){
BottomFB[idx*3+0] = (color);
BottomFB[idx*3+1] = (color) >> 8;
BottomFB[idx*3+2] = (color) >> 16;
}
}
A downside of this is that you're going to check the side variable for every pixel this runs for. Unless you declare the function as inline, I guess.
 
  • Like
Reactions: filfat
I just compiled 3ds_paint from source, but when I try to load it through Ninjahax it boots to the menu, then crashes and reboots.
 
You can use one only function to manage every framebuffer

Code:
void DrawPixel(int x,int y,u32 color,int screen, int side){
int idx = ((x)*240) + (239-(y));
if ((screen == 0) && (x < 400) && (y < 240) && (x >= 0) && (y >= 0)){
if (side == 0){
TopLFB[idx*3+0] = (color);
TopLFB[idx*3+1] = (color) >> 8;
TopLFB[idx*3+2] = (color) >> 16;
}else{
TopRFB[idx*3+0] = (color);
TopRFB[idx*3+1] = (color) >> 8;
TopRFB[idx*3+2] = (color) >> 16;
}
}else if((screen == 1) && (x < 320) && (y < 240) && (x >= 0) && (y >= 0)){
BottomFB[idx*3+0] = (color);
BottomFB[idx*3+1] = (color) >> 8;
BottomFB[idx*3+2] = (color) >> 16;
}
}

from luaScreen.cpp
Code:
static int lua_pixel(lua_State *L)
{
int argc = lua_gettop(L);
if ((argc != 4) && (argc != 5)) return luaL_error(L, "wrong number of arguments");
int x = luaL_checknumber(L,1);
int y = luaL_checknumber(L,2);
u32 color = luaL_checknumber(L,3);
int screen = luaL_checknumber(L,4);
int side;
if (argc == 5){
side = luaL_checkint(L,5);
}else{
side = 0;
}
if (screen > 1){
DrawImagePixel(x,y,color,(Bitmap*)screen);
}else{
DrawPixel(x,y,color,screen,side);
}
return 0;
}
Shouldn't you export 4 functions instead?
Maybe DrawPixelTopL(x, y, color), DrawPixelTopR(x, y, color), DrawPixelBottom(x, y, color) and DrawImagePixel(x,y,color,(Bitmap*)screen)?
Since you're linking with vanilla Lua, removing those 2 arguments should net a HUGE speedup(> 100%).
and you're doing 4 explicit double->int conversions with luaL_checknumber.
 
Uhm, yes please!

It is weird though. I load up my homebrew that has all the text and what not, and even when I remove the sound stuff, it now crashes. I guess something updated and something I am using is outdated? Anyway, I'll try to do it from scratch and see where the problem is.

Edit: Also, would you happen to know how to convert wav files to bin? I've been googling and I can't seem to find a way to do it. I figured it would be a lot easier to do my idea for a homebrew with .bin files instead of using wav files loaded from the SD.
 

Site & Scene News

Popular threads in this forum