Homebrew Homebrew Development

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,161
Trophies
0
Age
27
Location
Bologna
Website
rinnegatamante.it
XP
4,675
Country
Italy
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;
}
 

Agent Moose

Well-Known Member
Member
Joined
Dec 6, 2014
Messages
407
Trophies
0
Age
31
XP
527
Country
United States
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;
}
 

CalebW

Fellow Temper
Member
Joined
Jun 29, 2012
Messages
638
Trophies
0
Location
Texas
XP
525
Country
United States
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

spinal_cord

Knows his stuff
Member
Joined
Jul 21, 2007
Messages
3,176
Trophies
0
Age
41
Location
somewhere
Website
spinalcode.co.uk
XP
2,535
Country
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.
 

CalebW

Fellow Temper
Member
Joined
Jun 29, 2012
Messages
638
Trophies
0
Location
Texas
XP
525
Country
United States
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)
 

st4rk

nah
Member
Joined
Feb 11, 2014
Messages
542
Trophies
0
Website
st4rk.net
XP
795
Country
Brazil
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)
 

CalebW

Fellow Temper
Member
Joined
Jun 29, 2012
Messages
638
Trophies
0
Location
Texas
XP
525
Country
United States
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?
 

st4rk

nah
Member
Joined
Feb 11, 2014
Messages
542
Trophies
0
Website
st4rk.net
XP
795
Country
Brazil
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
 

CalebW

Fellow Temper
Member
Joined
Jun 29, 2012
Messages
638
Trophies
0
Location
Texas
XP
525
Country
United States
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.
 

st4rk

nah
Member
Joined
Feb 11, 2014
Messages
542
Trophies
0
Website
st4rk.net
XP
795
Country
Brazil
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
 

CalebW

Fellow Temper
Member
Joined
Jun 29, 2012
Messages
638
Trophies
0
Location
Texas
XP
525
Country
United States
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?
 

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,161
Trophies
0
Age
27
Location
Bologna
Website
rinnegatamante.it
XP
4,675
Country
Italy
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).
 

Agent Moose

Well-Known Member
Member
Joined
Dec 6, 2014
Messages
407
Trophies
0
Age
31
XP
527
Country
United States
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.
 

st4rk

nah
Member
Joined
Feb 11, 2014
Messages
542
Trophies
0
Website
st4rk.net
XP
795
Country
Brazil
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.
 

Prior22

Well-Known Member
Member
Joined
Sep 23, 2010
Messages
833
Trophies
0
XP
2,002
Country
United States
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.
 

Abcdfv

What comes around goes around.
Member
Joined
Dec 24, 2013
Messages
1,455
Trophies
0
XP
807
Country
United States
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.)
 
General chit-chat
Help Users
    Elodain @ Elodain: I'm not saying leave the loophole open, by all means close it, but just leave the people that...