mirror of
				https://github.com/ctruLua/ctruLua.git
				synced 2025-10-27 16:39:29 +00:00 
			
		
		
		
	Added fs lib; fs.list working. Added a simple shell.
This commit is contained in:
		
							parent
							
								
									551e8e121e
								
							
						
					
					
						commit
						85d8f60f94
					
				
					 5 changed files with 211 additions and 65 deletions
				
			
		
							
								
								
									
										76
									
								
								sdcard/3ds/ctruLua/example.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								sdcard/3ds/ctruLua/example.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | |||
| local gfx = require("ctr.gfx") | ||||
| local hid = require("ctr.hid") | ||||
| local ctr = require("ctr") | ||||
| 
 | ||||
| local x = 50 | ||||
| local y = 50 | ||||
| local dMul = 1 | ||||
| 
 | ||||
| local angle = 0 | ||||
| 
 | ||||
| gfx.color.setBackground(gfx.color.RGBA8(200, 200, 200)) | ||||
| gfx.set3D(true) | ||||
| 
 | ||||
| local function drawStuffIn3D(depth) | ||||
| 	gfx.text(2, 5, "Depth multiplicator: "..dMul) | ||||
| 
 | ||||
| 	-- 3D stuff | ||||
| 	local depth = math.floor(depth * dMul) | ||||
| 
 | ||||
| 	gfx.color.setDefault(0x00FFFFFF) | ||||
| 	gfx.rectangle(240 + depth*5, 150, 120, 10) | ||||
| 
 | ||||
| 	gfx.point(10 + depth*3, 20, 0xFF0000FF) | ||||
| 
 | ||||
| 	gfx.color.setDefault(0xFF0000FF) | ||||
| 	gfx.rectangle(x + depth*math.ceil(5*math.sin(ctr.time()/500)), y, 20, 20, angle) | ||||
| 
 | ||||
| 	gfx.line(50 - depth*3, 50, 75 + depth*2, 96, gfx.color.RGBA8(52, 10, 65)) | ||||
| 
 | ||||
| 	gfx.circle(125 - depth*4, 125, 16) | ||||
| end | ||||
| 
 | ||||
| while ctr.run() do | ||||
| 	hid.read() | ||||
| 	local keys = hid.keys() | ||||
| 
 | ||||
| 	if keys.down.start then return end | ||||
| 
 | ||||
| 	if keys.held.right then x = x + 1 end | ||||
| 	if keys.held.left then x = x - 1 end | ||||
| 	if keys.held.up then y = y - 1 end | ||||
| 	if keys.held.down then y = y + 1 end | ||||
| 	 | ||||
| 	if keys.held.r then dMul = dMul + 0.05 end | ||||
| 	if keys.held.l then dMul = dMul - 0.05 end | ||||
| 
 | ||||
| 	gfx.startFrame(gfx.GFX_TOP, gfx.GFX_LEFT) | ||||
| 
 | ||||
| 		drawStuffIn3D(-1) | ||||
| 
 | ||||
| 	gfx.endFrame() | ||||
| 	 | ||||
| 	gfx.startFrame(gfx.GFX_TOP, gfx.GFX_RIGHT) | ||||
| 		 | ||||
| 		drawStuffIn3D(1) | ||||
| 		 | ||||
| 	gfx.endFrame() | ||||
| 	 | ||||
| 	gfx.startFrame(gfx.GFX_BOTTOM) | ||||
| 
 | ||||
| 		gfx.color.setDefault(0, 0, 0) | ||||
| 		gfx.text(5, 7, "FPS: "..math.ceil(gfx.getFPS())) | ||||
| 		gfx.text(5, 20, "Hello world, from Lua !", 20) | ||||
| 		gfx.text(5, 30, "Time: "..os.date()) | ||||
| 
 | ||||
| 		local cx, cy = hid.circle() | ||||
| 		gfx.rectangle(40, 90, 60, 60, 0, 0xDDDDDDFF) | ||||
| 		gfx.circle(70 + math.ceil(cx/156 * 30), 120 - math.ceil(cy/156 * 30), 10, 0x000000FF) | ||||
| 
 | ||||
| 	gfx.endFrame() | ||||
| 
 | ||||
| 	angle = angle + 0.05 | ||||
| 	if angle > 2*math.pi then angle = angle - 2*math.pi end | ||||
| 
 | ||||
| 	gfx.render() | ||||
| end | ||||
|  | @ -1,76 +1,50 @@ | |||
| local gfx = require("ctr.gfx") | ||||
| local hid = require("ctr.hid") | ||||
| local ctr = require("ctr") | ||||
| local gfx = require("ctr.gfx") | ||||
| 
 | ||||
| local x = 50 | ||||
| local y = 50 | ||||
| local dMul = 1 | ||||
| 
 | ||||
| local angle = 0 | ||||
| 
 | ||||
| gfx.color.setBackground(gfx.color.RGBA8(200, 200, 200)) | ||||
| gfx.set3D(true) | ||||
| 
 | ||||
| local function drawStuffIn3D(depth) | ||||
| 	gfx.text(2, 5, "Depth multiplicator: "..dMul) | ||||
| 
 | ||||
| 	-- 3D stuff | ||||
| 	local depth = math.floor(depth * dMul) | ||||
| 
 | ||||
| 	gfx.color.setDefault(0x00FFFFFF) | ||||
| 	gfx.rectangle(240 + depth*5, 150, 120, 10) | ||||
| 
 | ||||
| 	gfx.point(10 + depth*3, 20, 0xFF0000FF) | ||||
| 
 | ||||
| 	gfx.color.setDefault(0xFF0000FF) | ||||
| 	gfx.rectangle(x + depth*math.ceil(5*math.sin(ctr.time()/500)), y, 20, 20, angle) | ||||
| 
 | ||||
| 	gfx.line(50 - depth*3, 50, 75 + depth*2, 96, gfx.color.RGBA8(52, 10, 65)) | ||||
| 
 | ||||
| 	gfx.circle(125 - depth*4, 125, 16) | ||||
| end | ||||
| local sel = 1 | ||||
| local curdir = "/" | ||||
| local files = ctr.fs.list(curdir) | ||||
| 
 | ||||
| while ctr.run() do | ||||
| 	hid.read() | ||||
| 	local keys = hid.keys() | ||||
| 	ctr.hid.read() | ||||
| 	local keys = ctr.hid.keys() | ||||
| 	if keys.down.start then break end | ||||
| 
 | ||||
| 	if keys.down.start then return end | ||||
| 	if keys.down.down and sel < #files then sel = sel + 1 | ||||
| 	elseif keys.down.up and sel > 1 then sel = sel - 1 end | ||||
| 
 | ||||
| 	if keys.held.right then x = x + 1 end | ||||
| 	if keys.held.left then x = x - 1 end | ||||
| 	if keys.held.up then y = y - 1 end | ||||
| 	if keys.held.down then y = y + 1 end | ||||
| 	 | ||||
| 	if keys.held.r then dMul = dMul + 0.05 end | ||||
| 	if keys.held.l then dMul = dMul - 0.05 end | ||||
| 	if keys.down.a then | ||||
| 		local f = files[sel] | ||||
| 
 | ||||
| 	gfx.startFrame(gfx.GFX_TOP, gfx.GFX_LEFT) | ||||
| 		if f.isDirectory then | ||||
| 			if f.name == ".." then curdir = curdir:gsub("[^/]+/$", "") | ||||
| 			else curdir = curdir..f.name.."/" end | ||||
| 
 | ||||
| 		drawStuffIn3D(-1) | ||||
| 			sel = 1 | ||||
| 			files = ctr.fs.list(curdir) | ||||
| 
 | ||||
| 			if curdir ~= "/" then | ||||
| 				table.insert(files, 1, { name = "..", isDirectory = true, fileSize = "parent directory" }) | ||||
| 			end | ||||
| 		else | ||||
| 			if f.name:match("%..+$") == ".lua" then | ||||
| 				dofile(curdir..f.name) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 
 | ||||
| 	gfx.startFrame(gfx.GFX_TOP) | ||||
| 
 | ||||
| 		gfx.text(3, 9, curdir) | ||||
| 
 | ||||
| 		for i,f in pairs(files) do | ||||
| 			local name = f.isDirectory and "["..f.name.."]" or f.name.." ("..f.fileSize.."b)" | ||||
| 			if not f.isHidden then gfx.text(5, 9+i*9, name) end | ||||
| 		end | ||||
| 
 | ||||
| 		gfx.text(0, 9+sel*9, ">") | ||||
| 
 | ||||
| 	gfx.endFrame() | ||||
| 	 | ||||
| 	gfx.startFrame(gfx.GFX_TOP, gfx.GFX_RIGHT) | ||||
| 		 | ||||
| 		drawStuffIn3D(1) | ||||
| 		 | ||||
| 	gfx.endFrame() | ||||
| 	 | ||||
| 	gfx.startFrame(gfx.GFX_BOTTOM) | ||||
| 
 | ||||
| 		gfx.color.setDefault(0, 0, 0) | ||||
| 		gfx.text(5, 7, "FPS: "..math.ceil(gfx.getFPS())) | ||||
| 		gfx.text(5, 20, "Hello world, from Lua !", 20) | ||||
| 		gfx.text(5, 30, "Time: "..os.date()) | ||||
| 
 | ||||
| 		local cx, cy = hid.circle() | ||||
| 		gfx.rectangle(40, 90, 60, 60, 0, 0xDDDDDDFF) | ||||
| 		gfx.circle(70 + math.ceil(cx/156 * 30), 120 - math.ceil(cy/156 * 30), 10, 0x000000FF) | ||||
| 
 | ||||
| 	gfx.endFrame() | ||||
| 
 | ||||
| 	angle = angle + 0.05 | ||||
| 	if angle > 2*math.pi then angle = angle - 2*math.pi end | ||||
| 
 | ||||
| 	gfx.render() | ||||
| end | ||||
| end | ||||
|  | @ -10,6 +10,7 @@ int load_news_lib(lua_State *L); | |||
| int load_ptm_lib(lua_State *L); | ||||
| int load_hid_lib(lua_State *L); | ||||
| int load_ir_lib(lua_State *L); | ||||
| int load_fs_lib(lua_State *L); | ||||
| 
 | ||||
| static int ctr_run(lua_State *L) { | ||||
| 	lua_pushboolean(L, aptMainLoop()); | ||||
|  | @ -37,6 +38,7 @@ struct { char *name; int (*load)(lua_State *L); } ctr_libs[] = { | |||
| 	{ "ptm",  load_ptm_lib  }, | ||||
| 	{ "hid",  load_hid_lib  }, | ||||
| 	{ "ir",   load_ir_lib   }, | ||||
| 	{ "fs",   load_fs_lib   }, | ||||
| 	{ NULL, NULL } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										92
									
								
								source/fs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								source/fs.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | |||
| #include <3ds/types.h> | ||||
| #include <3ds/util/utf.h> | ||||
| #include <3ds/services/fs.h> | ||||
| 
 | ||||
| #include <lua.h> | ||||
| #include <lauxlib.h> | ||||
| 
 | ||||
| Handle *fsuHandle; | ||||
| FS_archive sdmcArchive; | ||||
| 
 | ||||
| int fs_list(lua_State *L) { | ||||
| 	const char *path = luaL_checkstring(L, 1); | ||||
| 
 | ||||
| 	lua_newtable(L); | ||||
| 	int i = 1; // table index
 | ||||
| 
 | ||||
| 	FS_path dirPath = FS_makePath(PATH_CHAR, path); | ||||
| 
 | ||||
| 	Handle dirHandle; | ||||
| 	FSUSER_OpenDirectory(fsuHandle, &dirHandle, sdmcArchive, dirPath); | ||||
| 
 | ||||
| 	u32 entriesRead = 0; | ||||
| 	do { | ||||
| 		FS_dirent buffer; | ||||
| 
 | ||||
| 		FSDIR_Read(dirHandle, &entriesRead, 1, &buffer); | ||||
| 
 | ||||
| 		if (!entriesRead) break; | ||||
| 
 | ||||
| 		uint8_t name[256]; // utf8 file name
 | ||||
| 		size_t size = utf16_to_utf8(name, buffer.name, 0x106); | ||||
| 		*(name+size) = 0x0; // mark text end
 | ||||
| 
 | ||||
| 		lua_createtable(L, 0, 8); | ||||
| 
 | ||||
| 		lua_pushstring(L, (const char *)name); | ||||
| 		lua_setfield(L, -2, "name"); | ||||
| 		lua_pushstring(L, (const char *)buffer.shortName); | ||||
| 		lua_setfield(L, -2, "shortName"); | ||||
| 		lua_pushstring(L, (const char *)buffer.shortExt); | ||||
| 		lua_setfield(L, -2, "shortExt"); | ||||
| 		lua_pushboolean(L, buffer.isDirectory); | ||||
| 		lua_setfield(L, -2, "isDirectory"); | ||||
| 		lua_pushboolean(L, buffer.isHidden); | ||||
| 		lua_setfield(L, -2, "isHidden"); | ||||
| 		lua_pushboolean(L, buffer.isArchive); | ||||
| 		lua_setfield(L, -2, "isArchive"); | ||||
| 		lua_pushboolean(L, buffer.isReadOnly); | ||||
| 		lua_setfield(L, -2, "isReadOnly"); | ||||
| 		lua_pushinteger(L, buffer.fileSize); | ||||
| 		lua_setfield(L, -2, "fileSize"); | ||||
| 
 | ||||
| 		lua_seti(L, -2, i); | ||||
| 		i++; | ||||
| 
 | ||||
| 	} while (entriesRead > 0); | ||||
| 
 | ||||
| 	FSDIR_Close(dirHandle); | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static const struct luaL_Reg fs_lib[] = { | ||||
| 	{ "list", fs_list }, | ||||
| 	{ NULL, NULL } | ||||
| }; | ||||
| 
 | ||||
| int luaopen_fs_lib(lua_State *L) { | ||||
| 	luaL_newlib(L, fs_lib); | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| int load_fs_lib(lua_State *L) { | ||||
| 	fsInit(); | ||||
| 
 | ||||
| 	fsuHandle = fsGetSessionHandle(); | ||||
| 	FSUSER_Initialize(fsuHandle); | ||||
| 
 | ||||
| 	sdmcArchive = (FS_archive){ARCH_SDMC, FS_makePath(PATH_EMPTY, "")}; | ||||
| 	FSUSER_OpenArchive(fsuHandle, &sdmcArchive); | ||||
| 
 | ||||
| 	luaL_requiref(L, "ctr.fs", luaopen_fs_lib, false); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void unload_fs_lib(lua_State *L) { | ||||
| 	FSUSER_CloseArchive(fsuHandle, &sdmcArchive); | ||||
| 
 | ||||
| 	fsExit(); | ||||
| } | ||||
|  | @ -10,6 +10,7 @@ | |||
| 
 | ||||
| int load_ctr_lib(lua_State *L); | ||||
| void unload_font_lib(); | ||||
| void unload_fs_lib(); | ||||
| 
 | ||||
| bool gfxinit = false; | ||||
| 
 | ||||
|  | @ -64,8 +65,9 @@ int main() { | |||
| 	// Unload Lua
 | ||||
| 	lua_close(L); | ||||
| 
 | ||||
| 	// Unload current font
 | ||||
| 	// Unload libs
 | ||||
| 	unload_font_lib(); | ||||
| 	unload_fs_lib(); | ||||
| 	 | ||||
| 	// Disable accel/gyro
 | ||||
| 	HIDUSER_DisableAccelerometer(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Reuh
						Reuh