Homebrew Homebrew Development

Sizednochi

Well-Known Member
Member
Joined
Dec 16, 2012
Messages
697
Trophies
1
XP
867
Country
Brazil
How hard would it be to make a system-wide button remapper like the one on the PSP? It'd be handy to remap buttons for VC games as well as use the D-pad on Circle Pad only games
 
  • Like
Reactions: SLiV3R

MichiS97

"Leftist snowflake milennial"
Member
Joined
Jun 14, 2011
Messages
1,815
Trophies
2
Age
26
Location
Munich
XP
3,602
Country
Germany
So I've managed to make threads work in the app I'm coding but now I really have a major problem. Why is it that the app works flawlessly on Citra but just gives me black screen after the 3DS boot screen on my 3DS?
 

Tjessx

Well-Known Member
Member
Joined
Dec 3, 2014
Messages
1,160
Trophies
0
Age
27
XP
952
Country
Belgium
So I've managed to make threads work in the app I'm coding but now I really have a major problem. Why is it that the app works flawlessly on Citra but just gives me black screen after the 3DS boot screen on my 3DS?
Probably a memory issue, could you post your source?
 

MichiS97

"Leftist snowflake milennial"
Member
Joined
Jun 14, 2011
Messages
1,815
Trophies
2
Age
26
Location
Munich
XP
3,602
Country
Germany
@Tjessx
#include "Game.h"
#include <string.h>
#include <malloc.h>
#include <inttypes.h>
#include <stdlib.h>

Handle threadHandle;

#define STACKSIZE (4*1024)

volatile bool threadExit = false;
Game *Snake;


using namespace std;



void ThreadSnake(void *arg)
{
while(true)
{
if(threadExit)
{
svcExitThread();
}
if(Snake == NULL)
{
Snake = new Game();

Snake->init();


}

}



}



int main(int argc, char** argv) {
Snake = NULL;
gfxInitDefault();

consoleInit(GFX_TOP, NULL);

u32 *threadStack =(u32*) memalign(32, STACKSIZE);


Result ret = svcCreateThread(&threadHandle, ThreadSnake, 0, &threadStack[STACKSIZE/4], 0x3f,0);
while(aptMainLoop()){
svcSleepThread(1000000);
Snake->moveSnake();
}

threadExit = true;
svcSleepThread(10000000ULL);
svcCloseHandle(threadHandle);
free(threadStack);
gfxExit();
return 0;


}

I guess the main.cpp is enough since that's where the "thread stuff" is and that is the only part where I don't really know wtf I'm doing ^^ I don't even know exactly what the Stacksize means for example, I just copied those parts from the example provided by ctrulib. Like I said, it works perfectly fine on Citra. And yes, the code is messy.
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,033
Country
United States
@Tjessx
#include "Game.h"
#include <string.h>
#include <malloc.h>
#include <inttypes.h>
#include <stdlib.h>

Handle threadHandle;

#define STACKSIZE (4*1024)

volatile bool threadExit = false;
Game *Snake;


using namespace std;



void ThreadSnake(void *arg)
{
while(true)
{
if(threadExit)
{
svcExitThread();
}
if(Snake == NULL)
{
Snake = new Game();

Snake->init();


}

}



}



int main(int argc, char** argv) {
Snake = NULL;
gfxInitDefault();

consoleInit(GFX_TOP, NULL);

u32 *threadStack =(u32*) memalign(32, STACKSIZE);


Result ret = svcCreateThread(&threadHandle, ThreadSnake, 0, &threadStack[STACKSIZE/4], 0x3f,0);
while(aptMainLoop()){
svcSleepThread(1000000);
Snake->moveSnake();
}

threadExit = true;
svcSleepThread(10000000ULL);
svcCloseHandle(threadHandle);
free(threadStack);
gfxExit();
return 0;


}

I guess the main.cpp is enough since that's where the "thread stuff" is and that is the only part where I don't really know wtf I'm doing ^^ I don't even know exactly what the Stacksize means for example, I just copied those parts from the example provided by ctrulib. Like I said, it works perfectly fine on Citra. And yes, the code is messy.
The stack is where local variables are allocated. When you call a function it uses space in the stack to store your local variables. So if your function calls a function then both functions local variables will be on the stack. The stack space is released when a function returns. So you need enough space on the stack to store local variables for how deep your function calls will get.

I am guessing you removed some code before posting this example... But keep in mind there is no guarantee that Snake will be created in the thread before the main loop is entered. Also, the 3ds uses cooperative multasking. Your thread needs to explicitly sleep or use a wait function when it does not have anything to do as well as periodically. If your thread works constantly then the main thread will never execute. Your thread likely is running in a tight loop constantly checking Snake in the thread and the main thread is not getting a chance to run.

Again, code likely removed from your posting, but this does not appear to be a good use for a thread. It would appear that this could be accomplished far easier in the main thread.
 
  • Like
Reactions: Tjessx

MichiS97

"Leftist snowflake milennial"
Member
Joined
Jun 14, 2011
Messages
1,815
Trophies
2
Age
26
Location
Munich
XP
3,602
Country
Germany
The stack is where local variables are allocated. When you call a function it uses space in the stack to store your local variables. So if your function calls a function then both functions local variables will be on the stack. The stack space is released when a function returns. So you need enough space on the stack to store local variables for how deep your function calls will get.

I am guessing you removed some code before posting this example... But keep in mind there is no guarantee that Snake will be created in the thread before the main loop is entered. Also, the 3ds uses cooperative multasking. Your thread needs to explicitly sleep or use a wait function when it does not have anything to do as well as periodically. If your thread works constantly then the main thread will never execute. Your thread likely is running in a tight loop constantly checking Snake in the thread and the main thread is not getting a chance to run.

Again, code likely removed from your posting, but this does not appear to be a good use for a thread. It would appear that this could be accomplished far easier in the main thread.

I know that it's not a good use but I don't know how to do it properly. I figured that as long as it works (on Citra) it should be good enough. Can you give me a heads up on how to do this? And no, I didn't remove any code at all, this is the entire main.cpp
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,033
Country
United States
I know that it's not a good use but I don't know how to do it properly. I figured that as long as it works (on Citra) it should be good enough. Can you give me a heads up on how to do this? And no, I didn't remove any code at all, this is the entire main.cpp
it looks like you used the thread example from ctrulib as your starting point. The event pieces that you removed are what I would recommend adding back. essentially, in your main thread create an event. you set the event in the main thread when you want your worker thread to wake up and do something. in the worker thread you wait for the event to be set. when the main thread sets the event the worker thread will return from the wait function (be sure to clear the event in the worker thread) and presumably do some work. When the work is done the worker thread should wait on the event again - waiting for more work.

also, citra is not really at a point where you can make that assumption. my experience is that if it dies in citra then it probably will die on hardware too, but if it works in citra then it might work on hardware.
 

MichiS97

"Leftist snowflake milennial"
Member
Joined
Jun 14, 2011
Messages
1,815
Trophies
2
Age
26
Location
Munich
XP
3,602
Country
Germany
it looks like you used the thread example from ctrulib as your starting point. The event pieces that you removed are what I would recommend adding back. essentially, in your main thread create an event. you set the event in the main thread when you want your worker thread to wake up and do something. in the worker thread you wait for the event to be set. when the main thread sets the event the worker thread will return from the wait function (be sure to clear the event in the worker thread) and presumably do some work. When the work is done the worker thread should wait on the event again - waiting for more work.

also, citra is not really at a point where you can make that assumption. my experience is that if it dies in citra then it probably will die on hardware too, but if it works in citra then it might work on hardware.
Alright, did that. But it still doesn't work >.<
 

MichiS97

"Leftist snowflake milennial"
Member
Joined
Jun 14, 2011
Messages
1,815
Trophies
2
Age
26
Location
Munich
XP
3,602
Country
Germany
How did you evaluate how much stack you need? Do you you use an large local variables in your thread function calls? Try increasing the stack size to 16k. It is currently 4k and could be exhausted quickly.

How should I evaluate how much stack I need? Sorry for these questions but I've only recently started to learn C++. I tried to change the stack to 16k, even 64k but it doesn't work either. I guess that I need a very large stack since the thread starts and runs the game which uses many variables.
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,033
Country
United States
How should I evaluate how much stack I need? Sorry for these questions but I've only recently started to learn C++. I tried to change the stack to 16k, even 64k but it doesn't work either. I guess that I need a very large stack since the thread starts and runs the game which uses many variables.
You need to look at the size of the variables you are creating and think about how deep the function calls get-the thread function needs to be in this list too. Say you have a 1MB char array that is created in the thread. This will be too big for a 16k stack. You would need to make this a global or dynamically allocate it.

My recommendation at this point would be to just try creating a minimal thread in your code - comment out to local variables and function calls aside from the bare sync functions. Once that is working gradually add back the required functionality and see where the issue pops up. You can print from the thread (it will get messed up a little if the main thread is printing too) then add prints to verify you get to a certain point. Sometimes I even add a busy loop to stop at a certain point so I can verify it is reached - like a hard coded break point.
 

Tjessx

Well-Known Member
Member
Joined
Dec 3, 2014
Messages
1,160
Trophies
0
Age
27
XP
952
Country
Belgium
How do you correctly combine 2 char*'s in C?
I need to combine 2 strings in C to give them as a parameter.
Tried some stuff but it didn't worked.
 

Tjessx

Well-Known Member
Member
Joined
Dec 3, 2014
Messages
1,160
Trophies
0
Age
27
XP
952
Country
Belgium
Does anyone know an opensource homebrew app that uses sockets?
EDIT: Nevermind, found one (ctr-streaming-server)
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Psionic Roshambo @ Psionic Roshambo: https://www.youtube.com/watch?v=ZJewzRHdH8c