Homebrew Homebrew Development

  • Thread starter Thread starter aliak11
  • Start date Start date
  • Views Views 1,474,996
  • Replies Replies 6,048
  • Likes Likes 54
No clue why it doesn't work. And I can't exactly figure out blargSnes' audio :\
Post your complete code here, i also added stereo support (actually in a shitty method because i'm having issues with looping audio, it seems not work :/)
Code:
static int lua_openwav(lua_State *L)
{
    int argc = lua_gettop(L);
    if (argc != 1) return luaL_error(L, "wrong number of arguments");
    const char *file_tbo = luaL_checkstring(L, 1);
    Handle fileHandle;
    FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}};
    FS_path filePath=FS_makePath(PATH_CHAR, file_tbo);
    Result ret=FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
    if(ret) return luaL_error(L, "error opening file");
    u32 magic,samplerate,bytesRead,jump,chunk=0x00000000;
    u16 audiotype;
    FSFILE_Read(fileHandle, &bytesRead, 0, &magic, 4);
    if (magic == 0x46464952){
    u64 size;
    u32 pos = 16;
    while (chunk != 0x61746164){
    FSFILE_Read(fileHandle, &bytesRead, pos, &jump, 4);
    pos=pos+4+jump;
    FSFILE_Read(fileHandle, &bytesRead, pos, &chunk, 4);
    pos=pos+4;
    }
    FSFILE_GetSize(fileHandle, &size);
    FSFILE_Read(fileHandle, &bytesRead, 22, &audiotype, 2);
    FSFILE_Read(fileHandle, &bytesRead, 24, &samplerate, 4);
    wav *wav_file = (wav*)malloc(sizeof(wav));
    wav_file->samplerate = samplerate;
    if (audiotype == 1){
    wav_file->audiobuf = (u8*)linearAlloc(size-(pos+4));
    FSFILE_Read(fileHandle, &bytesRead, pos+4, wav_file->audiobuf, size-(pos+4));
    wav_file->audiobuf2 = NULL;
    wav_file->size = size-(pos+4);
    }else{
    // I must reordinate my buffer in order to play stereo sound (Thanks CSND/FS libraries .-.)
    u16 bytepersample;
    FSFILE_Read(fileHandle, &bytesRead, 32, &bytepersample, 2);
    u8* tmp_buffer = (u8*)linearAlloc((size-(pos+4)));
    wav_file->audiobuf = (u8*)linearAlloc((size-(pos+4))/2);
    wav_file->audiobuf2 = (u8*)linearAlloc((size-(pos+4))/2);
    FSFILE_Read(fileHandle, &bytesRead, pos+4, tmp_buffer, size-(pos+4));
    u32 off=0;
    u32 i=0;
    u16 z;
    while (i < (size-(pos+4))){
    z=0;
    while (z < (bytepersample/2)){
    wav_file->audiobuf[off+z] = tmp_buffer[i+z];
    z++;
    }
    z=0;
    while (z < (bytepersample/2)){
    wav_file->audiobuf2[off+z] = tmp_buffer[i+z+(bytepersample/2)];
    z++;
    }
    i=i+bytepersample;
    off=off+(bytepersample/2);
    }
    linearFree(tmp_buffer);
    wav_file->size = (size-(pos+4))/2;
    }
    lua_pushnumber(L,(u32)wav_file);
    }
    FSFILE_Close(fileHandle);
    svcCloseHandle(fileHandle);
    return 1;
}
 
Remember, I'm trying to make it so it doesn't need the Lua coding, I just want the C++ code:

Code:
#include <string.h>

#include <3ds.h>

u8* audiobuf;
u64 size;
u32 magic, samplerate, bytesRead, jump, chunk=0x00000000;
u32 pos = 16;

int main()
{
    // Initialize services
    srvInit();
    aptInit();
    hidInit(NULL);
    gfxInit();
    fsInit();
    CSND_initialize(NULL);
    //gfxSet3D(true); // uncomment if using stereoscopic 3D

    const char *file_tbo = "/canary.wav";
    Handle fileHandle;
    
    //Open wav file
    FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}};
    FS_path filePath=FS_makePath(PATH_CHAR, file_tbo);
    Result ret=FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
    FSFILE_Read(fileHandle, &bytesRead, 0, &magic, 4);
    if (magic == 0x46464952){
        while (chunk != 0x61746164){
            FSFILE_Read(fileHandle, &bytesRead, pos, &jump, 4);
            pos=pos+4+jump;
            FSFILE_Read(fileHandle, &bytesRead, pos, &chunk, 4);
            pos=pos+4;
        }
        FSFILE_GetSize(fileHandle, &size);
        audiobuf = (u8*)linearAlloc(size-(pos+4));
        FSFILE_Read(fileHandle, &bytesRead, 24, &samplerate, 4);
        FSFILE_Read(fileHandle, &bytesRead, pos+4, audiobuf, size-(pos+4));
    }
    FSFILE_Close(fileHandle);

    // Main loop
    while (aptMainLoop())
    {
        gspWaitForVBlank();
        hidScanInput();

        u32 kDown = hidKeysDown();
        if (kDown & KEY_START){
            break;
        };
        
        //Start wav file
        if(hidKeysUp() & KEY_A){
            GSPGPU_FlushDataCache(NULL, audiobuf, size-(pos+4));
            CSND_playsound(0x09, CSND_LOOP_DISABLE, CSND_ENCODING_PCM16, samplerate, (u32*)audiobuf, NULL, size-(pos+4), 2, 0);
        };
        
        // Flush and swap framebuffers
        gfxFlushBuffers();
        gfxSwapBuffers();
    }
    linearFree(audiobuf);
    CSND_shutdown();
    svcCloseHandle(fileHandle);
    // Exit services
    fsExit();
    gfxExit();
    hidExit();
    aptExit();
    srvExit();
    return 0;
}
 
So I'm trying to port LemmingsDS and I'm stuck how to port the draw functions...maybe something like

Code:
void DrawPixelA(int x, int y, u16 c, u8* screen)
{
    int height=240;
   
    u32 v=(height-1-y+x*height)*3;
    screen[v]=((c) | BIT(15));
    }
?

ds_backbuff.h
Code:
// DS Sprite thingy that will run way too slow.
//  by Mathew Carr
 
#ifndef DS_BACKBUFF_H
#define DS_BACKBUFF_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include <nds.h>
 
// These are silly. We should be writing to specific VRAM banks if we're going to make any sense of this mess.
#define VRAM_MAIN ((uint16 *)0x06000000)
#define VRAM_SUB ((uint16 *)0x06200000)
 
#define DrawPixelA(x, y, c) drawbuffer[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawPixel( x, y, c) drawbuffer[(x) + ((y)<<8)] = (c)
 
#define DrawDBPixelA(x, y, c) backbuff[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawDBPixel( x, y, c) backbuff[(x) + ((y)<<8)] = (c)
 
extern u16 *drawbuffer;
 
extern u16 backbuff[SCREEN_WIDTH * SCREEN_HEIGHT];
 
#ifdef __cplusplus
}
#endif
 
#endif // DS_BACKBUFF_H
ds_backbuff.c
Code:
// DS Sprite thingy that will run way too slow.
//  by Mathew Carr
 
#include "ds_backbuff.h"
 
u16 *drawbuffer = 0x06020000;
 
u16 backbuff[SCREEN_WIDTH * SCREEN_HEIGHT];
example function using one of the draw functions
Code:
void DS_DrawSprite(const DS_SPRITE *sprite, int d_x, int d_y, const u16 *pal) {
  if (pal == 0) pal = sprite->palette;
 
  if (d_x >= SCREEN_WIDTH)      return;
  if (d_y >= SCREEN_HEIGHT)      return;
  if (d_x <  (0-sprite->width))  return;
  if (d_y <  (0-sprite->height)) return;
 
  u16 d;
 
  // These are the start coordinates (on the sprite for source)
  int start_src_x = (d_x < 0) ? (0-d_x) : 0;
  int start_src_y = (d_y < 0) ? (0-d_y) : 0;
 
  // These are the dest coordinates (on the screen for draw)
  int start_dst_x = (d_x < 0) ? 0 : d_x;
  int start_dst_y = (d_y < 0) ? 0 : d_y;
 
  int src_x, src_y, dst_x, dst_y;
 
  for (src_y = start_src_y, dst_y = start_dst_y; (src_y < sprite->height) && (dst_y < SCREEN_HEIGHT); src_y++, dst_y++) {
      for (src_x = start_src_x, dst_x = start_dst_x; (src_x < sprite->width) && (dst_x < SCREEN_WIDTH); src_x++, dst_x++) {
        d = sprite->data[src_x + (src_y*(sprite->width))];
        if (d != 0) {
            DrawPixel(dst_x, dst_y, pal[d]);
        }
      }
  }
}
Also, why did he define the functions the way he did above?
 
  • Like
Reactions: Margen67
So I'm trying to port LemmingsDS and I'm stuck how to port the draw functions...maybe something like

Code:
#ifndef DS_BACKBUFF_H
#define DS_BACKBUFF_H
 
/* code */
 
#endif

Also, why did he define the functions the way he did above?


To prevent the code being re-included multiple times and causing redefinition errors.
 
To prevent the code being re-included multiple times and causing redefinition errors.
I was talking about
Code:
#define DrawPixelA(x, y, c) drawbuffer[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawPixel( x, y, c) drawbuffer[(x) + ((y)<<8)] = (c)
 
#define DrawDBPixelA(x, y, c) backbuff[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawDBPixel( x, y, c) backbuff[(x) + ((y)<<8)] = (c)
 
I was talking about
Code:
#define DrawPixelA(x, y, c) drawbuffer[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawPixel( x, y, c) drawbuffer[(x) + ((y)<<8)] = (c)
 
#define DrawDBPixelA(x, y, c) backbuff[(x) + ((y)<<8)] = ((c) | BIT(15))
#define DrawDBPixel( x, y, c) backbuff[(x) + ((y)<<8)] = (c)


This is because the framebuffer os NDS is 15bpp if i am not mistaken, you will need use 24bpp or use 15bpp format in 3DS FrameBuffer(i don't know if this is possible, i just know the 16bpp =P)
 
This is because the framebuffer os NDS is 15bpp if i am not mistaken, you will need use 24bpp or use 15bpp format in 3DS FrameBuffer(i don't know if this is possible, i just know the 16bpp =P)
So would
Code:
void DrawPixelA(int x, int y, u16 c, u8* screen)
{
    int height=240;
   
    u32 v=(height-1-y+x*height)*3;
    screen[v] = ((c) | BIT(24));
    }
work for the 3ds?
 
So would
Code:
void DrawPixelA(int x, int y, u16 c, u8* screen)
{
    int height=240;
 
    u32 v=(height-1-y+x*height)*3;
    screen[v] = ((c) | BIT(24));
    }
work for the 3ds?



No, need be something like

screen[v] = B
screen[v + 1] = G
screen[v + 2] = R

Each color is 8 bits, i don't know how the BIT work but i belive it won't work, you will need modify it =p
 
No, need be something like

screen[v] = B
screen[v + 1] = G
screen[v + 2] = R
Well the function get a u16 var for the palette colours so I'm not sure how I'm supposed to convert that to 3 chars...

Each color is 8 bits, i don't know how the BIT work but i belive it won't work, you will need modify it =p
Well, I'm not sure how the BIT works either. I don't know why there's one function with (c | BIT(15)) and one without it. And I also don't know why there are sprites drawn to a backbuff array that's never written to memory.
 
Well the function get a u16 var for the palette colours so I'm not sure how I'm supposed to convert that to 3 chars...


Well, I'm not sure how the BIT works either. I don't know why there's one function with (c | BIT(15)) and one without it. And I also don't know why there are sprites drawn to a backbuff array that's never written to memory.


You have two way to solve it, you can convert the 16bpp to 24bpp in the DrawPixel function(probably you will lost speed with it) or if it is a *Palette* you can use a Palette with 24bpp
 
you can convert the 16bpp to 24bpp in the DrawPixel function(probably you will lost speed with it)
Is that possible? I know you can go from 24bpp to 16bpp but I didn't think you could do so the other way around? And didn't StapleButter say that the CPU could only support 8, 16, or 32?
 
Try this:

Code:
#include <string.h>
 
#include <3ds.h>
 
u8* StartWav(const char *file){
Handle fileHandle;
u8* audiobuf;
u64 size;
u32 magic, samplerate, bytesRead, jump, chunk=0x00000000;
u32 pos = 16;
FS_archive sdmcArchive=(FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}};
    FS_path filePath=FS_makePath(PATH_CHAR, file);
    Result ret=FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
    FSFILE_Read(fileHandle, &bytesRead, 0, &magic, 4);
    if (magic == 0x46464952){
        while (chunk != 0x61746164){
            FSFILE_Read(fileHandle, &bytesRead, pos, &jump, 4);
            pos=pos+4+jump;
            FSFILE_Read(fileHandle, &bytesRead, pos, &chunk, 4);
            pos=pos+4;
        }
        FSFILE_GetSize(fileHandle, &size);
        audiobuf = (u8*)linearAlloc(size-(pos+4));
        FSFILE_Read(fileHandle, &bytesRead, 24, &samplerate, 4);
        FSFILE_Read(fileHandle, &bytesRead, pos+4, audiobuf, size-(pos+4));
    }
    FSFILE_Close(fileHandle);
    svcCloseHandle(fileHandle);
GSPGPU_FlushDataCache(NULL, audiobuf, size-(pos+4));
CSND_playsound(0x08, CSND_LOOP_DISABLE, CSND_ENCODING_PCM16, samplerate, (u32*)audiobuf, NULL, size-(pos+4), 2, 0);
return audiobuf;
}
 
int main()
{
    // Initialize services
    srvInit();
    aptInit();
    hidInit(NULL);
    gfxInit();
    fsInit();
    CSND_initialize(NULL);
    //gfxSet3D(true); // uncomment if using stereoscopic 3D
 
    u8* wav_file = StartWav("/canary.wav");
   
 
    // Main loop
    while (aptMainLoop())
    {
        gspWaitForVBlank();
        hidScanInput();
 
        u32 kDown = hidKeysDown();
        if (kDown & KEY_START){
            break;
        };
       
        // Flush and swap framebuffers
        gfxFlushBuffers();
        gfxSwapBuffers();
    }
    linearFree(wav_file);
    CSND_shutdown();
    svcCloseHandle(fileHandle);
    // Exit services
    fsExit();
    gfxExit();
    hidExit();
    aptExit();
    srvExit();
    return 0;
}

I'm assuming your wav file is not too big to not be loaded (actually, you can store approssimately a WAV that reach at max a size of 60-62 MB).
 
I'm using the wav file you gave me. And I got this error:
Code:
/Users/AgentMoose/3DS/Sound/source/main.c: In function 'main':
/Users/AgentMoose/3DS/Sound/source/main.c:64:20: error: 'fileHandle' undeclared (first use in this function)
     svcCloseHandle(fileHandle);

I tried moving "Handle fileHandle" bove the OpenWav function and the application was able to be compiled, but when I tried it on the 3DS it crashed.
 
Is that possible? I know you can go from 24bpp to 16bpp but I didn't think you could do so the other way around? And didn't StapleButter say that the CPU could only support 8, 16, or 32?


Sorry my away, working hard on 3DNES XDDD, anyway, is if i am not mistaken you can convert 16bpp to 24bpp, but it should cause slowdown.

the CPU support only 8,16,32 is because we work just with Byte(8 bits = 1 byte), Short(16 bits = 2 bytes) and Int(32 bits = 4 bytes), if you look the ARM documentation you can see which each register have 32 bits and you can use condition to load byte, short and int(half/word in this case) and store the same way, we work with this standard , of course i am not 100% sure but i belive is this =P.
 
Just out of curiosity has there been any work on cheat applications, or plugins, for 3DS games? Would love to hear that progress has been made with that.
 
Just out of curiosity has there been any work on cheat applications, or plugins, for 3DS games? Would love to hear that progress has been made with that.
I can't find the link thanks to the forum remodel, but there is a plugin for the leaked CFW for a couple real time cheats in a game. (game was maybe a link between world's? Something like max hearts/rupees constantly.)
 

Site & Scene News

Popular threads in this forum