Homebrew Homebrew Development

nic0lette

Well-Known Member
Newcomer
Joined
Feb 5, 2016
Messages
70
Trophies
0
Age
40
XP
100
Country
United States
Dumb question -- is there anything like the NetLoader/3dslink pair from the Homebrew Launcher but runs as a CIA (from EmuNAND or A9LHax...NAND)
 

nic0lette

Well-Known Member
Newcomer
Joined
Feb 5, 2016
Messages
70
Trophies
0
Age
40
XP
100
Country
United States
You mean for developing homebrew? Probably the closest is this: https://github.com/Cpasjuste/libctrshell

For developing homebrew, yes, but basically something to load the code over the network like one can do with Netloader/3dslink. Network printfs sound neat, but loading code without yanking my sdcard out constantly is more interesting to me XD
 

daxtsu

Well-Known Member
Member
Joined
Jun 9, 2007
Messages
5,627
Trophies
2
XP
5,194
Country
Antarctica
For developing homebrew, yes, but basically something to load the code over the network like one can do with Netloader/3dslink. Network printfs sound neat, but loading code without yanking my sdcard out constantly is more interesting to me XD

If I'm not mistaken, that library has code to push new CIAs over the currently running one for testing purposes.
 
  • Like
Reactions: nic0lette

TarableCode

Well-Known Member
Member
Joined
Mar 2, 2016
Messages
184
Trophies
0
Age
37
XP
319
Country
Canada
I just did a quick test and it's possible to send network printfs over udp broadcast messages and read them using netcat. (at least on windows)
That would be great since you wouldn't need to hardcode an IP to listen to debug info.

Weird thing is that netcat required the -w 1 parameter or no more messages would be received until netcat was reopened.
I'll have to fiddle with my socket code more and see what's going on.

Beyond that I could hook it into devoptab so it could be hooked into stdio and written to using regular printfs.
:D

edit:
It totally works :D shame the code is a messy pile though.

Simple proof of concept if anyone needs, it should probably be rewritten at some point.
Code:
#include <3ds.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/iosupport.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>

/* Correct buffer size? */
#define SOCBUF_SIZE 128 * 1024

/*
 * If set, this will also write to the default console device as set up by libctru.
*/
#define ALSO_PRINT_CONSOLE

/*
 * If set, sets the socket to non-blocking I/O mode.
 * I have no idea if this matters or not.
 */
#define DONT_BLOCK

/*
 * con_write From libctru.
 * Are we even supposed to be able to access this?
 */
extern ssize_t con_write(struct _reent *r,int fd,const char *ptr, size_t len);

static int DebugMsgSocket = -1;
static void* SOCBuffer = NULL;
static struct sockaddr_in ServerAddr;

/*
 * Our device descriptor. 
 * Maybe one day implement stdin over UDP?
 */
static const devoptab_t MyDevOpTab = {
	"con",
	0,
	NULL,
	NULL,
	Netcon_Write,
	NULL,
	NULL,
	NULL
};

static ssize_t Netcon_Write( struct _reent* r, int fd, const char* ptr, size_t len ) {
	ssize_t Count = 0;

#ifdef ALSO_PRINT_CONSOLE
	/*
	 * Only care about the number of characters written to the console.
	 */
	Count = con_write( r, fd, ptr, len );
	sendto( DebugMsgSocket, ptr, len, 0, ( const struct sockaddr* ) &ServerAddr, sizeof( struct sockaddr_in ) );
#else
	Count = sendto( DebugMsgSocket, ptr, len, 0, ( const struct sockaddr* ) &ServerAddr, sizeof( struct sockaddr_in ) );
#endif

	return Count;
}

/*
 * TODO:
 * This is awful.
 * Just awful.
 */
int netprintf_Init( int Port ) {
	int Flags = 0;
	u32 Status = 0;

	if ( acInit( ) == 0 ) {
		ACU_GetWifiStatus( &Status );
		
		if ( Status > 0 ) {
			SOCBuffer = memalign( 0x1000, SOCBUF_SIZE );

			if ( SOCBuffer ) {
				if ( socInit( ( u32* ) SOCBuffer, SOCBUF_SIZE ) == 0 ) {
					DebugMsgSocket = socket( AF_INET, SOCK_DGRAM, 0 );

					if ( DebugMsgSocket != -1 ) {
						memset( &ServerAddr, 0, sizeof( ServerAddr ) );

	#ifdef DONT_BLOCK
						Flags = fcntl( DebugMsgSocket, F_GETFL, 0 );
						Flags|= O_NONBLOCK;

						fcntl( DebugMsgSocket, F_SETFL, Flags );
	#else
						/* Keep compiler from bitchin' */
						Flags++;
	#endif

						ServerAddr.sin_family = AF_INET;
						ServerAddr.sin_addr.s_addr = INADDR_BROADCAST;
						ServerAddr.sin_port = htons( Port );

						devoptab_list[ STD_OUT ] = &MyDevOpTab;
						devoptab_list[ STD_ERR ] = &MyDevOpTab;

						setvbuf( stdout, NULL, _IONBF, 0 );
						setvbuf( stderr, NULL, _IONBF, 0 );

						return 1;
					}
				} 

				linearFree( SOCBuffer );
			}
		}
	}

	return 0;
}

/*
 * same
 */
void netprintf_Close( void ) {
	if ( DebugMsgSocket )
		closesocket( DebugMsgSocket );

	socExit( );
	acExit( );

	if ( SOCBuffer )
		free( SOCBuffer );
}
 
Last edited by TarableCode,

TarableCode

Well-Known Member
Member
Joined
Mar 2, 2016
Messages
184
Trophies
0
Age
37
XP
319
Country
Canada
Indexed->RGB conversion is slow as balls but I wondered if anyone had figured out some kind of witchcraft to speed it up or hax around it?
Only updating dirty regions is the best solution so far but a full screen update on the o3ds is still not great.
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
Indexed->RGB conversion is slow as balls but I wondered if anyone had figured out some kind of witchcraft to speed it up or hax around it?
Only updating dirty regions is the best solution so far but a full screen update on the o3ds is still not great.
Double buffer and offload it to the system core. From doing that I saved 5ms but increased complexity, so I reverted back to the original code.
 

DiscostewSM

Well-Known Member
Member
Joined
Feb 10, 2009
Messages
5,484
Trophies
2
Location
Sacramento, California
Website
lazerlight.x10.mx
XP
5,522
Country
United States
You could use the constant texenv color to set one channel to 0 and interpolate or modulate ops. That would remove all red for instance - maybe not what you where looking for though.

Nah, not a channel, but a particular color of my choosing. We're coming up with a solution for possible 8-bit paletted textures using the GPU_L8 format to get 255 adjustable colors with reflective color LUTs. It works from tests, but the problem is the remaining entry. From what we understand, it's basically an invalid entry, and seems to always display pure black no matter what is set in the LUTs. We'd like to use it as a transparency index. Dunno if internally when it's processed that it registers as the color set in the LUTs, but if it is, and we can match that up with some color to discard it, then that would help. We'd basically limit the LUTs to 15-bit color combinations with the exception of this one LUT entry, so we can cull it out and not cull anything else.

We do have the option of using GPU_LA8, and force the alpha to full on everything except for that entry, but it needs to be tested, and it may not even work if the invalid entry defaults to a solid black color. I'd rather not use it (if it works) because it requires double the texture space vs GPU_L8.
 

TarableCode

Well-Known Member
Member
Joined
Mar 2, 2016
Messages
184
Trophies
0
Age
37
XP
319
Country
Canada
Double buffer and offload it to the system core. From doing that I saved 5ms but increased complexity, so I reverted back to the original code.

What were your times like on o3ds on the syscore?
From what I read we only have ~80MHz worth of CPU time there and I found on my end a 512x384 framebuffer took ~10ms to complete on the main thread.

Curse that damn pica200 for not having any indexed modes.
-_-
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
What were your times like on o3ds on the syscore?
From what I read we only have ~80MHz worth of CPU time there and I found on my end a 512x384 framebuffer took ~10ms to complete on the main thread.

Curse that damn pica200 for not having any indexed modes.
-_-

I didn't really time it, but it was enough for 60fps , but there was no scaling involved. Are you using the GPU for scaling?
 

TarableCode

Well-Known Member
Member
Joined
Mar 2, 2016
Messages
184
Trophies
0
Age
37
XP
319
Country
Canada
Yeah, I'll take free linear scaling any day :D
The texture upload is nothing, it's the indexed->rgb that seems to be the slowest part, unless I've been timing it wrong?

I've been using osGetTime before and after the framebuffer conversions and getting the difference.
 

MasterFeizz

Well-Known Member
Member
Joined
Oct 15, 2015
Messages
1,098
Trophies
1
Age
29
XP
3,710
Country
United States
Yeah, I'll take free linear scaling any day :D
The texture upload is nothing, it's the indexed->rgb that seems to be the slowest part, unless I've been timing it wrong?

I've been using osGetTime before and after the framebuffer conversions and getting the difference.
Thats how I timed it, simple and accurate enough.
 

TheCruel

Developer
Banned
Joined
Dec 6, 2013
Messages
1,350
Trophies
2
XP
3,131
Country
United States
Indexed->RGB conversion is slow as balls but I wondered if anyone had figured out some kind of witchcraft to speed it up or hax around it?
Only updating dirty regions is the best solution so far but a full screen update on the o3ds is still not great.
The GPU supports procedural textures, which includes a color LUT, but it's not completely documented and I don't know of anyone who has successfully achieved it. I will be toying with it this week though for usage in ScummVM.

Some data on it:
https://www.3dbrew.org/wiki/GPU/Procedural_Texture_Generation
https://www.3dbrew.org/wiki/GPU/Internal_Registers#GPUREG_PROCTEX_LUT
 
Last edited by TheCruel,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    K3Nv2 @ K3Nv2: Bueno