├── meta ├── bg.png ├── icon0.png ├── startup.png └── template.xml ├── src ├── boot │ ├── boot.lua │ └── boot_http.lua ├── font │ └── UbuntuMono-R.ttf ├── revitalize_splash.png ├── vitafm │ ├── src │ │ ├── vitafm_launch.lua │ │ ├── programs │ │ │ ├── rm.lua │ │ │ ├── mount.lua │ │ │ ├── lcall.lua │ │ │ ├── mkdir.lua │ │ │ ├── viewer.lua │ │ │ ├── font.lua │ │ │ ├── uvloader.lua │ │ │ └── imgview.lua │ │ ├── types.lua │ │ └── vitafm_base.lua │ └── Makefile ├── ffi │ ├── fs.c │ ├── misc.c │ ├── touch.c │ ├── battery.c │ ├── input.c │ ├── sound.c │ ├── vita2d.c │ ├── http.c │ └── physfs.c └── main.c ├── .gitmodules ├── README.md ├── lua ├── colors.lua ├── hash.lua ├── init.lua ├── battery.lua ├── misc.lua ├── audio.lua ├── touch.lua ├── input.lua ├── http.lua ├── fs.lua ├── lua_player.lua ├── ui.lua ├── ltn12.lua └── vita2d.lua ├── .gitignore ├── scripts └── generate_ffi_init_list.sh ├── LICENSE └── Makefile /meta/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stary2001/vita-lua/HEAD/meta/bg.png -------------------------------------------------------------------------------- /src/boot/boot.lua: -------------------------------------------------------------------------------- 1 | dofile("cache0:/VitaDefilerClient/Documents/script.lua") 2 | -------------------------------------------------------------------------------- /meta/icon0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stary2001/vita-lua/HEAD/meta/icon0.png -------------------------------------------------------------------------------- /meta/startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stary2001/vita-lua/HEAD/meta/startup.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lua/vfs"] 2 | path = lua/vfs 3 | url = https://github.com/carbonsrv/vfs 4 | -------------------------------------------------------------------------------- /src/font/UbuntuMono-R.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stary2001/vita-lua/HEAD/src/font/UbuntuMono-R.ttf -------------------------------------------------------------------------------- /src/revitalize_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Stary2001/vita-lua/HEAD/src/revitalize_splash.png -------------------------------------------------------------------------------- /src/vitafm/src/vitafm_launch.lua: -------------------------------------------------------------------------------- 1 | -- VitaFM Launcher 2 | print("Launching vitafm...") 3 | vitafm.run() 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vita-lua 2 | 3 | Sort of like LuaPlayer, but not really. 4 | See the [wiki](https://github.com/stary2001/vita-lua/wiki) for more details. 5 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/rm.lua: -------------------------------------------------------------------------------- 1 | -- rm.lua 2 | local args = {...} 3 | local file = args[1] 4 | if file then 5 | assert(vfs.delete(file)) 6 | else 7 | error("Usage: rm file") 8 | end 9 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/mount.lua: -------------------------------------------------------------------------------- 1 | -- mount.lua 2 | local args = {...} 3 | if args[1] and args[2] then 4 | return phyfs.mount(args[1], args[2]) 5 | else 6 | error("Usage: mount ") 7 | end 8 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/lcall.lua: -------------------------------------------------------------------------------- 1 | -- lcall.lua 2 | local args = {...} 3 | if not args[1] then 4 | return nil 5 | end 6 | 7 | local f = args[1] 8 | table.remove(args, 1) 9 | 10 | f(unpack(args)) 11 | -------------------------------------------------------------------------------- /meta/template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bg.png 6 | 7 | 8 | 9 | startup.png 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/mkdir.lua: -------------------------------------------------------------------------------- 1 | -- mkdir.Lua 2 | local args = {...} 3 | local file = args[1] 4 | if file then 5 | if not vfs.exists(file) then 6 | assert(vfs.mkdir(file)) 7 | else 8 | error("File or directory already exists!") 9 | end 10 | else 11 | error("Usage: mkdir directory") 12 | end 13 | -------------------------------------------------------------------------------- /lua/colors.lua: -------------------------------------------------------------------------------- 1 | -- colors 2 | local bit = require 'bit' 3 | 4 | colors = {} 5 | 6 | colors.red = 0xff0000ff 7 | colors.green = 0xff00ff00 8 | colors.blue = 0xffff0000 9 | colors.white = 0xffffffff 10 | colors.black = 0xff000000 11 | colors.yellow = bit.bor(colors.red, colors.green) 12 | colors.purple = bit.bor(colors.red, colors.blue) 13 | colors.cyan = bit.bor(colors.green, colors.blue) 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Objects 2 | src/*.o 3 | src/ffi/*.o 4 | lua/*.o 5 | *.elf 6 | *.velf 7 | *.vpk 8 | param.sfo 9 | eboot.bin 10 | /vpktmp 11 | 12 | # Generated source 13 | /src/ffi_init.c 14 | /src/boot.c 15 | /src/font.c 16 | /src/splash.c 17 | 18 | # VitaFM 19 | /src/vitafm/vitafm.c 20 | /src/vitafm/vitafm.o 21 | /src/vitafm/vitafm.lua 22 | /src/vitafm/vitafm_min.lua 23 | 24 | # Vim Files 25 | *.un~ 26 | *.swp 27 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/viewer.lua: -------------------------------------------------------------------------------- 1 | -- viewer.lua 2 | local args = {...} 3 | local file = args[1] 4 | if file then 5 | if vfs.exists(file) then 6 | local data = assert(vfs.read(file)) 7 | ui.pager(data, file, true) 8 | else 9 | --ui.error("viewer: Couldn't open File", "Error:\nFile ''" .. file .. "' could not be opened.") 10 | error("File ''" .. file .. "' could not be opened.") 11 | end 12 | else 13 | error("Usage: viewer file") 14 | end 15 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/font.lua: -------------------------------------------------------------------------------- 1 | -- font.lua 2 | local args = {...} 3 | local file = args[1] 4 | if file then 5 | if vfs.exists(file) then 6 | local data = assert(vfs.read(file)) 7 | font = vita2d.load_font_data(data) 8 | else 9 | --ui.error("font: Couldn't open File", "Error:\nFile ''" .. file .. "' could not be opened.") 10 | error("File ''" .. file .. "' could not be opened.") 11 | end 12 | else 13 | error("Usage: font font.ttf") 14 | end 15 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/uvloader.lua: -------------------------------------------------------------------------------- 1 | -- uvloader.lua 2 | local args = {...} 3 | if args[1] then 4 | vita2d.fini() -- Deinitialize vita2d, so that graphics aren't messed up. 5 | 6 | local status = uvl.load(args[1]) 7 | 8 | os.sleep(0.5) -- Take our time, so that we don't accidentally select a bad thing. 9 | vita2d.init() -- Initialize that thing again. 10 | vita2d.clear_screen() 11 | os.sleep(0.5) 12 | return status 13 | else 14 | error("Usage: uvloader homebrew.velf") 15 | end 16 | -------------------------------------------------------------------------------- /src/vitafm/src/types.lua: -------------------------------------------------------------------------------- 1 | -- List of types assigned in vitafm as default. 2 | vitafm.types = { 3 | -- Lua files 4 | [".lua"] = "lua %f", 5 | 6 | -- Text files 7 | [".txt"] = "viewer %f", 8 | [".log"] = "viewer %f", 9 | 10 | -- Image files 11 | [".png"] = "imgview %f", 12 | [".jpeg"] = "imgview %f", 13 | [".jpg"] = "imgview %f", 14 | [".bmp"] = "imgview %f", 15 | 16 | -- Fonts 17 | [".ttf"] = "font %f", 18 | 19 | -- Physfs archives. 20 | [".zip"] = "mount %F", 21 | 22 | -- Ask for handler 23 | ["*"] = "ask %f %e" 24 | } 25 | -------------------------------------------------------------------------------- /src/ffi/fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_fs() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"sceIoDopen", sceIoDopen}, 10 | {"sceIoDread", sceIoDread}, 11 | {"sceIoDclose", sceIoDclose}, 12 | {"sceIoMkdir", sceIoMkdir}, 13 | {"sceIoRmdir", sceIoRmdir}, 14 | {"sceIoGetstat", sceIoGetstat}, 15 | {"sceIoChstat", sceIoChstat}, 16 | {NULL, NULL} 17 | }; 18 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 19 | ffi_add_table(&table); 20 | } 21 | -------------------------------------------------------------------------------- /src/ffi/misc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void ffi_register_misc() 8 | { 9 | static Function funcs[] = 10 | { 11 | {"sceKernelDelayThread", sceKernelDelayThread}, 12 | {"sceKernelGetProcessTime", sceKernelGetProcessTime}, 13 | {"sceKernelExitProcess", sceKernelExitProcess}, 14 | {"crc32", crc32}, 15 | {NULL, NULL} 16 | }; 17 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 18 | ffi_add_table(&table); 19 | } 20 | -------------------------------------------------------------------------------- /src/boot/boot_http.lua: -------------------------------------------------------------------------------- 1 | local url = "http://192.168.0.13/code.lua" 2 | 3 | function exec(url) 4 | local status, req = http.get(url) 5 | if status == nil then 6 | print("HTTP error: " .. tostring(req)) 7 | return 8 | end 9 | local code = req:read("*a") 10 | req:close() 11 | 12 | print("Loading code...") 13 | local func, err = loadstring(code) 14 | if func == nil then 15 | print("Error: "..err) 16 | return 17 | end 18 | 19 | local success, err = pcall(func) 20 | if not success then 21 | print("Error: "..err) 22 | end 23 | end 24 | 25 | exec(url) 26 | -------------------------------------------------------------------------------- /src/ffi/touch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_touch() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"sceTouchGetPanelInfo", sceTouchGetPanelInfo}, 10 | {"sceTouchRead", sceTouchRead}, 11 | {"sceTouchPeek", sceTouchPeek}, 12 | {"sceTouchSetSamplingState", sceTouchSetSamplingState}, 13 | {"sceTouchGetSamplingState", sceTouchGetSamplingState}, 14 | {"sceTouchEnableTouchForce", sceTouchEnableTouchForce}, 15 | {"sceTouchDisableTouchForce", sceTouchDisableTouchForce}, 16 | {NULL, NULL} 17 | }; 18 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 19 | ffi_add_table(&table); 20 | } 21 | -------------------------------------------------------------------------------- /lua/hash.lua: -------------------------------------------------------------------------------- 1 | -- hash 2 | 3 | local ffi = require 'ffi' 4 | 5 | ffi.cdef [[ 6 | unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); 7 | ]] 8 | 9 | hash = {} 10 | 11 | function hash.crc32(data, crc) 12 | if crc == nil then 13 | crc = ffi.C.crc32(0, nil, 0) 14 | end 15 | return ffi.C.crc32(crc, data, #data) 16 | end 17 | 18 | function hash.file_crc32(file) 19 | local crc = ffi.C.crc32(0, nil, 0) -- init crc 20 | local f = io.open(file, "r") 21 | if f == nil then return end 22 | 23 | while true do 24 | local block = f:read(8192) 25 | if not block then break end 26 | crc = ffi.C.crc32(crc, block, #block) 27 | end 28 | 29 | return crc 30 | end 31 | -------------------------------------------------------------------------------- /src/vitafm/src/programs/imgview.lua: -------------------------------------------------------------------------------- 1 | -- imgview.lua 2 | local args = {...} 3 | if args[1] then 4 | local ext = file_extension(args[1]) 5 | if ext == nil then 6 | ext = ui.choose({".png", ".jpg", ".bmp"}, "What format is the file?") 7 | if ext == nil then 8 | return 9 | end 10 | end 11 | local file = args[1] 12 | if vfs.exists(file) then 13 | local data = assert(vfs.read(file)) 14 | local image = vita2d.load_texture_data(ext:gsub("%.", ""), data) 15 | ui.view_image(image) 16 | else 17 | --ui.error("imgview: Couldn't open File", "Error:\nFile ''" .. file .. "' could not be opened.") 18 | error("File ''" .. file .. "' could not be opened.") 19 | end 20 | else 21 | error("Usage: imgview image [png/jpg/bmp]") 22 | end 23 | -------------------------------------------------------------------------------- /scripts/generate_ffi_init_list.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat << EOF > src/ffi_init.c 4 | // This file was generated by a terrible bash script. 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | EOF 11 | 12 | find src/ffi/ -type f -name '*.c' | while read f; do 13 | name=${f%.c} 14 | name=${name#src/ffi/} 15 | echo "void ffi_register_${name}();" >> src/ffi_init.c 16 | done 17 | 18 | echo >> src/ffi_init.c 19 | 20 | cat << EOF >> src/ffi_init.c 21 | void open_ffi(lua_State *l) 22 | { 23 | EOF 24 | find src/ffi/ -type f -name '*.c' | while read f; do 25 | name=${f%.c} 26 | name=${name#src/ffi/} 27 | echo -e "\tffi_register_${name}();" >> src/ffi_init.c 28 | done 29 | 30 | echo '}' >> src/ffi_init.c 31 | -------------------------------------------------------------------------------- /src/ffi/battery.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_battery() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"scePowerIsBatteryCharging", scePowerIsBatteryCharging}, 10 | {"scePowerGetBatteryLifePercent", scePowerGetBatteryLifePercent}, 11 | {"scePowerIsPowerOnline", scePowerIsPowerOnline}, 12 | {"scePowerGetBatteryLifeTime", scePowerGetBatteryLifeTime}, 13 | {"scePowerGetBatteryRemainCapacity", scePowerGetBatteryRemainCapacity}, 14 | {"scePowerIsLowBattery", scePowerIsLowBattery}, 15 | {"scePowerGetBatteryFullCapacity", scePowerGetBatteryFullCapacity}, 16 | {NULL, NULL} 17 | }; 18 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 19 | ffi_add_table(&table); 20 | } 21 | -------------------------------------------------------------------------------- /src/ffi/input.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_input() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"sceCtrlSetSamplingMode", sceCtrlSetSamplingMode}, 10 | {"sceCtrlGetSamplingMode", sceCtrlGetSamplingMode}, 11 | {"sceCtrlPeekBufferPositive", sceCtrlPeekBufferPositive}, 12 | {"sceCtrlPeekBufferNegative", sceCtrlPeekBufferNegative}, 13 | {"sceCtrlReadBufferPositive", sceCtrlReadBufferPositive}, 14 | {"sceCtrlReadBufferNegative", sceCtrlReadBufferNegative}, 15 | {"sceCtrlSetRapidFire", sceCtrlSetRapidFire}, 16 | {"sceCtrlClearRapidFire", sceCtrlClearRapidFire}, 17 | {NULL, NULL} 18 | }; 19 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 20 | ffi_add_table(&table); 21 | } 22 | -------------------------------------------------------------------------------- /src/vitafm/Makefile: -------------------------------------------------------------------------------- 1 | OUTPUT = vitafm.lua 2 | PROGRAM_SOURCE = $(wildcard src/programs/*.lua) 3 | PROGRAMS = $(patsubst src/programs/%.lua, %, $(PROGRAM_SOURCE)) 4 | 5 | all: vitafm 6 | 7 | vitafm_base: 8 | cp src/vitafm_base.lua $(OUTPUT) 9 | 10 | version: 11 | echo "vitafm.version = \"`git describe --abbrev=7 --dirty --always --tags`\"" >> $(OUTPUT) 12 | 13 | .NOTPARALLEL: $(PROGRAMS) 14 | $(PROGRAMS): %: src/programs/%.lua 15 | (echo "vitafm.programs[\"$*\"] = function(...)" && cat $< && echo "end") >> $(OUTPUT) 16 | 17 | types: 18 | cat src/types.lua >> $(OUTPUT) 19 | 20 | vitafm: vitafm_base version $(PROGRAMS) types 21 | #echo "vitafm.run()" >> $(OUTPUT) 22 | 23 | min: vitafm 24 | luamin -f vitafm.lua > vitafm_min.lua 25 | 26 | clean: 27 | rm vitafm.lua || true 28 | -------------------------------------------------------------------------------- /src/ffi/sound.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_sound() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"sceAudioOutOpenPort", sceAudioOutOpenPort}, 10 | {"sceAudioOutReleasePort", sceAudioOutReleasePort}, 11 | {"sceAudioOutOutput", sceAudioOutOutput}, 12 | {"sceAudioOutSetVolume", sceAudioOutSetVolume}, 13 | {"sceAudioOutSetConfig", sceAudioOutSetConfig}, 14 | {"sceAudioOutGetConfig", sceAudioOutGetConfig}, 15 | {"sceAudioOutSetAlcMode", sceAudioOutSetAlcMode}, 16 | {"sceAudioOutGetRestSample", sceAudioOutGetRestSample}, 17 | {"sceAudioOutGetAdopt", sceAudioOutGetAdopt}, 18 | {NULL, NULL} 19 | }; 20 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 21 | ffi_add_table(&table); 22 | } 23 | -------------------------------------------------------------------------------- /lua/init.lua: -------------------------------------------------------------------------------- 1 | -- Load libraries sufficient to load the rest. 2 | package.path = "app0:/lib/?.lua;app0:/lib/?/init.lua" 3 | print("init: Loading basic libs...") 4 | require("fs") 5 | ltn12 = require("ltn12") 6 | vfs = require("vfs") 7 | 8 | -- Initalize VFS 9 | print("init: vfs: Initializing physfs-ffi and mounting app0, ux0, ur0...") 10 | vfs.loadbackends("physfs-ffi") 11 | vfs.new("app0", "physfs", "app0:/") 12 | vfs.new("ux0", "physfs", "ux0:/") 13 | vfs.new("ur0", "physfs", "ur0:/") 14 | 15 | vfs.set_default_drive("app0") 16 | vfs.searchpath("app0:/lib/?.lua;app0:/lib/?/init.lua") 17 | 18 | table.insert(package.loaders, 2, vfs.loader) 19 | 20 | -- Load remaining libs 21 | local libs = {"audio", "battery", "colors", "hash", "http", "input", "misc", "touch", "ui", "vita2d", "vitafm"} 22 | for _, lib in pairs(libs) do 23 | print("Loading "..lib.."...") 24 | require(lib) 25 | end 26 | 27 | -- Load bootscript 28 | print("init: Trying to load app0:/boot.lua") 29 | local suc, err = pcall(dofile, "app0:/boot.lua") 30 | if not suc then 31 | print("Error: "..tostring(err)) 32 | end 33 | -------------------------------------------------------------------------------- /lua/battery.lua: -------------------------------------------------------------------------------- 1 | -- battery 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | int scePowerIsBatteryCharging(); 6 | int scePowerGetBatteryLifePercent(); 7 | int scePowerIsPowerOnline(); 8 | int scePowerGetBatteryLifeTime(); 9 | int scePowerGetBatteryRemainCapacity(); //? 10 | int scePowerIsLowBattery(); 11 | int scePowerGetBatteryFullCapacity(); //? 12 | ]] 13 | 14 | battery = {} 15 | 16 | function battery.is_charging() 17 | -- return ffi.C.scePowerIsBatteryCharging() == 1 18 | return battery.has_charger() and battery.get_percent() ~= 100 19 | end 20 | 21 | function battery.get_percent() 22 | return ffi.C.scePowerGetBatteryLifePercent() 23 | end 24 | 25 | function battery.has_charger() 26 | return ffi.C.scePowerIsPowerOnline() == 1 27 | end 28 | 29 | --[[ 30 | -- unresolved syscalls 31 | 32 | function battery.get_remaining_capacity() 33 | return ffi.C.scePowerGetBatteryRemainCapacity() 34 | end 35 | 36 | function battery.is_low() 37 | return ffi.C.scePowerIsLowBattery() == 1 38 | end 39 | 40 | function battery.get_full_capacity() 41 | return ffi.C.scePowerGetBatteryFullCapacity() 42 | end 43 | 44 | function battery.get_remaining_time() 45 | return ffi.C.scePowerGetBatteryLifeTime() 46 | end 47 | ]] 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2015 Stary2001, vifino and contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | --- 23 | 24 | The license for the font in `src/font/UbuntuMono-R.ttf` differs from the above MIT license. 25 | 26 | This font is licensed under the Ubuntu Font License. 27 | 28 | http://font.ubuntu.com/licence/ 29 | 30 | --- 31 | 32 | The file `lua/ltn12.lua` is under a different license, it's license is as follows: 33 | LuaSocket 3.0 license 34 | Copyright © 2004-2013 Diego Nehab 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a 37 | copy of this software and associated documentation files (the "Software"), 38 | to deal in the Software without restriction, including without limitation 39 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 40 | and/or sell copies of the Software, and to permit persons to whom the 41 | Software is furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in 44 | all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 49 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 51 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 52 | DEALINGS IN THE SOFTWARE. 53 | 54 | --- 55 | 56 | The submodule "lua/vfs"'s license differs, see it's LICENSE file for more details. 57 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = vita-lua 2 | TITLE_ID = STAR00001 3 | 4 | BOOTSCRIPT ?= src/vitafm/src/vitafm_launch.lua 5 | FONT ?= src/font/UbuntuMono-R.ttf 6 | 7 | FFI_BINDINGS = $(wildcard src/ffi/*.c) 8 | FFI_BINDINGS_O = $(patsubst %.c, %.o, $(FFI_BINDINGS)) 9 | 10 | OBJS = src/main.o 11 | 12 | LIBS = -ldebugnet -lvita2d -lfreetype -lpng -lz -ljpeg -lSceTouch_stub -lSceDisplay_stub -lSceGxm_stub -lSceCtrl_stub -lSceNet_stub -lSceNetCtl_stub -lSceHttp_stub -lSceAudio_stub -lScePower_stub -lSceSysmodule_stub -lluajit-5.1 -lm -lphysfs 13 | INCLUDES = -I./includes -I$(VITASDK)/arm-vita-eabi/include/luajit-2.0 14 | 15 | PREFIX = $(VITASDK)/bin/arm-vita-eabi 16 | 17 | CC = $(PREFIX)-gcc 18 | LD = $(PREFIX)-ld 19 | 20 | DEBUGGER_IP ?= $(shell ip addr list `ip route | grep default | grep -oP 'dev \K[a-z0-9]* '` | grep -oP 'inet \K[0-9\.]*') 21 | DEBUGGER_PORT = 18194 22 | DEFS = -DDEBUGGER_IP=\"$(DEBUGGER_IP)\" -DDEBUGGER_PORT=$(DEBUGGER_PORT) 23 | 24 | CFLAGS = -Wl,-q -Wall -O3 -std=gnu99 $(DEFS) $(INCLUDES) 25 | 26 | all: $(TARGET).vpk 27 | 28 | $(TARGET).vpk: eboot.bin vpktmp/lib/vitafm.lua $(wildcard lua/*.lua) lua/vfs/init.lua lua/vfs/LICENSE $(wildcard lua/vfs/backends/*) $(BOOTSCRIPT) 29 | rm $@ || true 30 | mkdir -p vpktmp/sce_sys || true 31 | mkdir vpktmp/lib || true 32 | mkdir vpktmp/sce_sys/livearea/contents -p || true 33 | vita-mksfoex -s TITLE_ID=$(TITLE_ID) "$(TARGET)" vpktmp/sce_sys/param.sfo 34 | cp eboot.bin vpktmp/eboot.bin 35 | cp $(BOOTSCRIPT) vpktmp/boot.lua 36 | cp $(FONT) vpktmp/default_font.ttf 37 | cp meta/icon0.png vpktmp/sce_sys/icon0.png 38 | cp meta/template.xml vpktmp/sce_sys/livearea/contents/template.xml 39 | cp meta/bg.png vpktmp/sce_sys/livearea/contents/bg.png 40 | cp meta/startup.png vpktmp/sce_sys/livearea/contents/startup.png 41 | cp lua/*.lua vpktmp/lib 42 | mkdir -p vpktmp/lib/vfs/backends || true 43 | cp lua/vfs/init.lua lua/vfs/LICENSE vpktmp/lib/vfs 44 | cp lua/vfs/backends/*.lua vpktmp/lib/vfs/backends 45 | cd vpktmp && zip -r --symlinks ../$@ * 46 | 47 | eboot.bin: $(TARGET).velf 48 | vita-make-fself $< $@ 49 | 50 | %.velf: %.elf 51 | $(PREFIX)-strip -g $< 52 | vita-elf-create $< $@ >/dev/null 53 | 54 | vpktmp/lib/vitafm.lua: src/vitafm/src/types.lua src/vitafm/src/vitafm_base.lua src/vitafm/src/vitafm_launch.lua $(wildcard src/vitafm/src/programs/*) 55 | mkdir -p vpktmp/lib || true 56 | make -C src/vitafm 57 | cp src/vitafm/vitafm.lua $@ 58 | 59 | src/ffi_init.c: $(FFI_BINDINGS_O) 60 | ./scripts/generate_ffi_init_list.sh 61 | 62 | $(TARGET).elf: $(OBJS) $(FFI_BINDINGS_O) src/ffi_init.o 63 | $(CC) $(CFLAGS) $^ $(LIBS) $(LUAJIT_LIBS) -o $@ 64 | 65 | clean: 66 | rm -rf $(TARGET).velf $(TARGET).elf $(TARGET).vpk $(OBJS) eboot.bin src/ffi_init.c vpktmp 67 | make -C src/vitafm clean 68 | 69 | vpksend: $(TARGET).vpk 70 | curl -T $(TARGET).vpk ftp://$(PSVITAIP):1337/ux0:/ 71 | @echo "Sent." 72 | 73 | send: eboot.bin 74 | curl -T eboot.bin ftp://$(PSVITAIP):1337/ux0:/app/$(TITLE_ID)/ 75 | @echo "Sent." 76 | -------------------------------------------------------------------------------- /lua/misc.lua: -------------------------------------------------------------------------------- 1 | -- misc 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | typedef uint64_t SceUInt64; 6 | typedef SceUInt64 SceKernelSysClock; 7 | int sceKernelDelayThread(unsigned int delay); 8 | int sceKernelGetProcessTime(SceKernelSysClock *c); 9 | int sceKernelExitProcess(int r); 10 | ]] 11 | 12 | function os.sleep(s) 13 | os.usleep(s * 1000000) 14 | end 15 | 16 | function os.usleep(us) 17 | ffi.C.sceKernelDelayThread(us) 18 | end 19 | 20 | function os.clock() 21 | c = ffi.new('SceKernelSysClock[1]') 22 | ffi.C.sceKernelGetProcessTime(c) 23 | return tonumber(c[0]) / 1000000 24 | end 25 | 26 | --function os.exit(r) 27 | -- ffi.C.sceKernelExitProcess(r) 28 | --end 29 | 30 | -- from http://stackoverflow.com/questions/28664139/lua-split-string-into-words-unless-quoted 31 | function os.shelltokenize(text) 32 | local res = {} 33 | local spat, epat, buf, quoted = [=[^(['"])]=], [=[(['"])$]=] 34 | for str in text:gmatch("%S+") do 35 | local squoted = str:match(spat) 36 | local equoted = str:match(epat) 37 | local escaped = str:match([=[(\*)['"]$]=]) 38 | if squoted and not quoted and not equoted then 39 | buf, quoted = str, squoted 40 | elseif buf and equoted == quoted and #escaped % 2 == 0 then 41 | str, buf, quoted = buf .. ' ' .. str, nil, nil 42 | elseif buf then 43 | buf = buf .. ' ' .. str 44 | end 45 | if not buf then 46 | table.insert(res, (str:gsub(spat,""):gsub(epat,""))) 47 | end 48 | end 49 | if buf then 50 | return false, "Missing matching quote for "..buf 51 | end 52 | return true, res 53 | end 54 | 55 | -- from http://lua-users.org/wiki/SimpleRound 56 | function math.round(num, idp) 57 | local mult = 10^(idp or 0) 58 | return math.floor(num * mult + 0.5) / mult 59 | end 60 | 61 | -- simple lines() 62 | function string.lines(str) 63 | local t = {} 64 | local function helper(line) table.insert(t, line) return "" end 65 | helper((str:gsub("(.-)\r?\n", helper))) 66 | return t 67 | end 68 | 69 | -- String padding and stripping 70 | function string.lpad(str, len, chr) 71 | local char = chr or " " 72 | return str .. string.rep(char, len - #str) 73 | end 74 | function string.rpad(str, len, chr) 75 | local char = chr or " " 76 | return string.rep(char, len - #str) .. str 77 | end 78 | function string.strip(s) 79 | return (s:gsub("^%s*(.-)%s*$", "%1")) 80 | end 81 | -- from PiL2 20.4 82 | 83 | -- Table find 84 | function table.find(t, val) 85 | for k,v in pairs(t) do 86 | if v == val then 87 | return k 88 | end 89 | end 90 | end 91 | 92 | -- Small table helpers. 93 | function table.keys(t) 94 | local res = {} 95 | for k in pairs(t) do 96 | table.insert(res, k) 97 | end 98 | return res 99 | end 100 | function table.iterate(t, f) 101 | for k, v in pairs(t) do 102 | f(k, v) 103 | end 104 | end 105 | function table.map(t, f) 106 | local rest = {} 107 | for k, v in pairs(t) do 108 | rest[k] = f(k, v) 109 | end 110 | return rest 111 | end 112 | -------------------------------------------------------------------------------- /src/ffi/vita2d.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_vita2d() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"vita2d_init", vita2d_init}, 10 | {"vita2d_init_advanced", vita2d_init_advanced}, 11 | {"vita2d_fini", vita2d_fini}, 12 | {"vita2d_clear_screen", vita2d_clear_screen}, 13 | {"vita2d_swap_buffers", vita2d_swap_buffers}, 14 | {"vita2d_start_drawing", vita2d_start_drawing}, 15 | {"vita2d_end_drawing", vita2d_end_drawing}, 16 | {"vita2d_set_clear_color", vita2d_set_clear_color}, 17 | {"vita2d_set_vblank_wait", vita2d_set_vblank_wait}, 18 | {"vita2d_get_current_fb", vita2d_get_current_fb}, 19 | {"vita2d_pool_malloc", vita2d_pool_malloc}, 20 | {"vita2d_pool_memalign", vita2d_pool_memalign}, 21 | {"vita2d_pool_free_space", vita2d_pool_free_space}, 22 | {"vita2d_pool_reset", vita2d_pool_reset}, 23 | {"vita2d_draw_pixel", vita2d_draw_pixel}, 24 | {"vita2d_draw_line", vita2d_draw_line}, 25 | {"vita2d_draw_rectangle", vita2d_draw_rectangle}, 26 | {"vita2d_draw_fill_circle", vita2d_draw_fill_circle}, 27 | {"vita2d_create_empty_texture", vita2d_create_empty_texture}, 28 | {"vita2d_create_empty_texture_format", vita2d_create_empty_texture_format}, 29 | {"vita2d_free_texture", vita2d_free_texture}, 30 | {"vita2d_texture_get_width", vita2d_texture_get_width}, 31 | {"vita2d_texture_get_height", vita2d_texture_get_height}, 32 | {"vita2d_texture_get_stride", vita2d_texture_get_stride}, 33 | {"vita2d_texture_get_format", vita2d_texture_get_format}, 34 | {"vita2d_texture_get_datap", vita2d_texture_get_datap}, 35 | {"vita2d_texture_get_palette", vita2d_texture_get_palette}, 36 | {"vita2d_draw_texture", vita2d_draw_texture}, 37 | {"vita2d_draw_texture_rotate", vita2d_draw_texture_rotate}, 38 | {"vita2d_draw_texture_rotate_hotspot", vita2d_draw_texture_rotate_hotspot}, 39 | {"vita2d_draw_texture_scale", vita2d_draw_texture_scale}, 40 | {"vita2d_draw_texture_part", vita2d_draw_texture_part}, 41 | {"vita2d_draw_texture_part_scale", vita2d_draw_texture_part_scale}, 42 | {"vita2d_draw_texture_tint", vita2d_draw_texture_tint}, 43 | {"vita2d_draw_texture_tint_rotate", vita2d_draw_texture_tint_rotate}, 44 | {"vita2d_draw_texture_tint_rotate_hotspot", vita2d_draw_texture_tint_rotate_hotspot}, 45 | {"vita2d_draw_texture_tint_scale", vita2d_draw_texture_tint_scale}, 46 | {"vita2d_draw_texture_tint_part", vita2d_draw_texture_tint_part}, 47 | {"vita2d_draw_texture_tint_part_scale", vita2d_draw_texture_tint_part_scale}, 48 | {"vita2d_load_PNG_file", vita2d_load_PNG_file}, 49 | {"vita2d_load_PNG_buffer", vita2d_load_PNG_buffer}, 50 | {"vita2d_load_JPEG_file", vita2d_load_JPEG_file}, 51 | {"vita2d_load_JPEG_buffer", vita2d_load_JPEG_buffer}, 52 | {"vita2d_load_BMP_file", vita2d_load_BMP_file}, 53 | {"vita2d_load_BMP_buffer", vita2d_load_BMP_buffer}, 54 | {"vita2d_load_font_file", vita2d_load_font_file}, 55 | {"vita2d_load_font_mem", vita2d_load_font_mem}, 56 | {"vita2d_free_font", vita2d_free_font}, 57 | {"vita2d_font_draw_text", vita2d_font_draw_text}, 58 | {"vita2d_font_draw_textf", vita2d_font_draw_textf}, 59 | {"vita2d_font_text_dimensions", vita2d_font_text_dimensions}, 60 | {"vita2d_font_text_width", vita2d_font_text_width}, 61 | {"vita2d_font_text_height", vita2d_font_text_height}, 62 | {NULL, NULL} 63 | }; 64 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 65 | ffi_add_table(&table); 66 | } 67 | -------------------------------------------------------------------------------- /src/ffi/http.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_http() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"sceHttpInit", sceHttpInit}, 10 | {"sceHttpTerm", sceHttpTerm}, 11 | {"sceHttpGetMemoryPoolStats", sceHttpGetMemoryPoolStats}, 12 | {"sceHttpSetAuthInfoCallback", sceHttpSetAuthInfoCallback}, 13 | {"sceHttpSetAuthEnabled", sceHttpSetAuthEnabled}, 14 | {"sceHttpGetAuthEnabled", sceHttpGetAuthEnabled}, 15 | {"sceHttpSetRedirectCallback", sceHttpSetRedirectCallback}, 16 | {"sceHttpSetAutoRedirect", sceHttpSetAutoRedirect}, 17 | {"sceHttpGetAutoRedirect", sceHttpGetAutoRedirect}, 18 | {"sceHttpSetResolveTimeOut", sceHttpSetResolveTimeOut}, 19 | {"sceHttpSetResolveRetry", sceHttpSetResolveRetry}, 20 | {"sceHttpSetConnectTimeOut", sceHttpSetConnectTimeOut}, 21 | {"sceHttpSetSendTimeOut", sceHttpSetSendTimeOut}, 22 | {"sceHttpSetRecvTimeOut", sceHttpSetRecvTimeOut}, 23 | {"sceHttpSendRequest", sceHttpSendRequest}, 24 | {"sceHttpAbortRequest", sceHttpAbortRequest}, 25 | {"sceHttpGetResponseContentLength", sceHttpGetResponseContentLength}, 26 | {"sceHttpGetStatusCode", sceHttpGetStatusCode}, 27 | {"sceHttpGetAllResponseHeaders", sceHttpGetAllResponseHeaders}, 28 | {"sceHttpReadData", sceHttpReadData}, 29 | {"sceHttpAddRequestHeader", sceHttpAddRequestHeader}, 30 | {"sceHttpRemoveRequestHeader", sceHttpRemoveRequestHeader}, 31 | // {"sceHttpSetProxy", sceHttpSetProxy}, 32 | // {"sceHttpGetProxy", sceHttpGetProxy}, 33 | // {"sceHttpEnableKeepAlive", sceHttpEnableKeepAlive}, 34 | // {"sceHttpDisableKeepAlive", sceHttpDisableKeepAlive}, 35 | // {"sceHttpEnableHttp0_9", sceHttpEnableHttp0_9}, 36 | // {"sceHttpDisableHttp0_9", sceHttpDisableHttp0_9}, 37 | {"sceHttpParseResponseHeader", sceHttpParseResponseHeader}, 38 | {"sceHttpParseStatusLine", sceHttpParseStatusLine}, 39 | {"sceHttpCreateTemplate", sceHttpCreateTemplate}, 40 | {"sceHttpDeleteTemplate", sceHttpDeleteTemplate}, 41 | {"sceHttpCreateConnection", sceHttpCreateConnection}, 42 | {"sceHttpCreateConnectionWithURL", sceHttpCreateConnectionWithURL}, 43 | {"sceHttpDeleteConnection", sceHttpDeleteConnection}, 44 | {"sceHttpCreateRequest", sceHttpCreateRequest}, 45 | {"sceHttpCreateRequestWithURL", sceHttpCreateRequestWithURL}, 46 | {"sceHttpDeleteRequest", sceHttpDeleteRequest}, 47 | // {"sceHttpSetResponseHeaderMaxSize", sceHttpSetResponseHeaderMaxSize}, 48 | // {"sceHttpSetRecvBlockSize", sceHttpSetRecvBlockSize}, 49 | {"sceHttpSetRequestContentLength", sceHttpSetRequestContentLength}, 50 | {"sceHttpUriEscape", sceHttpUriEscape}, 51 | {"sceHttpUriUnescape", sceHttpUriUnescape}, 52 | {"sceHttpUriParse", sceHttpUriParse}, 53 | {"sceHttpUriBuild", sceHttpUriBuild}, 54 | {"sceHttpUriMerge", sceHttpUriMerge}, 55 | {"sceHttpUriSweepPath", sceHttpUriSweepPath}, 56 | {"sceHttpsLoadCert", sceHttpsLoadCert}, 57 | {"sceHttpsUnloadCert", sceHttpsUnloadCert}, 58 | {"sceHttpsEnableOption", sceHttpsEnableOption}, 59 | {"sceHttpsDisableOption", sceHttpsDisableOption}, 60 | {"sceHttpsGetSslError", sceHttpsGetSslError}, 61 | {"sceHttpsSetSslCallback", sceHttpsSetSslCallback}, 62 | {"sceHttpsGetCaList", sceHttpsGetCaList}, 63 | {"sceHttpsFreeCaList", sceHttpsFreeCaList}, 64 | {"sceHttpSetCookieEnabled", sceHttpSetCookieEnabled}, 65 | {"sceHttpGetCookieEnabled", sceHttpGetCookieEnabled}, 66 | {"sceHttpGetCookie", sceHttpGetCookie}, 67 | {"sceHttpAddCookie", sceHttpAddCookie}, 68 | {"sceHttpSetCookieRecvCallback", sceHttpSetCookieRecvCallback}, 69 | {"sceHttpSetCookieSendCallback", sceHttpSetCookieSendCallback}, 70 | {NULL, NULL} 71 | }; 72 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 73 | ffi_add_table(&table); 74 | } 75 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* vim: set tabstop=4 softtabstop=4 shiftwidth=4 expandtab : */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // Debugnet stuff 20 | #ifdef DEBUGGER_IP 21 | #include 22 | #define debugf(...) \ 23 | debugNetPrintf(DEBUG, "%s:%d %s: ", __FILE__, __LINE__, __func__); \ 24 | debugNetPrintf(DEBUG, __VA_ARGS__) 25 | #else 26 | #define debugf(...) \ 27 | printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ 28 | printf(__VA_ARGS__) 29 | #endif 30 | 31 | int panic(lua_State *l) 32 | { 33 | debugf("Lua paniced with '%s!'\n", lua_tostring(l, -1)); 34 | sceKernelExitProcess(0); 35 | return 0; 36 | } 37 | 38 | int print(lua_State *l) 39 | { 40 | debugf("[Lua] %s\n", lua_tostring(l, -1)); 41 | return 0; 42 | } 43 | 44 | void open_ffi(lua_State *l); 45 | 46 | int main() 47 | { 48 | lua_State *lua = luaL_newstate(); 49 | lua_atpanic(lua, panic); 50 | 51 | // Net init 52 | sceSysmoduleLoadModule(SCE_SYSMODULE_NET); 53 | SceNetInitParam netInitParam; 54 | int size = 1024 * 512; 55 | netInitParam.memory = malloc(size); 56 | netInitParam.size = size; 57 | netInitParam.flags = 0; 58 | sceNetInit(&netInitParam); 59 | 60 | sceSysmoduleLoadModule(SCE_SYSMODULE_HTTP); 61 | #ifdef DEBUGGER_IP 62 | debugNetInit(DEBUGGER_IP, DEBUGGER_PORT, DEBUG); 63 | #endif 64 | sceHttpInit(1024 * 50); 65 | 66 | // Init libs 67 | debugf("Init libs....\n"); 68 | debugf("vita2d...\n"); 69 | vita2d_init(); 70 | debugf("physfs\n"); 71 | PHYSFS_init(NULL); 72 | debugf("lualibs\n"); 73 | luaL_openlibs(lua); 74 | debugf("ffi\n"); 75 | open_ffi(lua); 76 | 77 | lua_pushcfunction(lua, print); 78 | lua_setglobal(lua, "print"); 79 | 80 | /* 81 | // Display splash 82 | unsigned int goal = 2*60; 83 | unsigned int counter = 0; 84 | vita2d_texture *tex = vita2d_load_PNG_buffer(splash_data); 85 | SceCtrlData pad; 86 | memset(&pad, 0, sizeof(pad)); 87 | for (;;) { 88 | ++counter; 89 | if (counter >= goal) 90 | break; 91 | sceCtrlPeekBufferPositive(0, &pad, 1); 92 | if (pad.buttons & SCE_CTRL_ANY) 93 | break; 94 | vita2d_start_drawing(); 95 | vita2d_clear_screen(); 96 | vita2d_draw_texture(tex, 0, 0); 97 | vita2d_end_drawing(); 98 | vita2d_swap_buffers(); 99 | } 100 | */ 101 | 102 | debugf("[Lua] Loading app0:/lib/init.lua ...\n"); 103 | if(luaL_loadfile(lua, "app0:/lib/init.lua") == 0) 104 | { 105 | if(lua_pcall(lua, 0, 0, 0) != 0) 106 | { 107 | debugf("[Lua] init error: %s\n", lua_tostring(lua, -1)); 108 | lua_pop(lua, 1); 109 | } 110 | } 111 | 112 | /*debugf("[Lua] Loading app0:/boot.lua ...\n"); 113 | if(luaL_loadfile(lua, "app0:/boot.lua") == 0) 114 | { 115 | if(lua_pcall(lua, 0, 0, 0) != 0) 116 | { 117 | debugf("[Lua] bootscript err: %s\n", lua_tostring(lua, -1)); 118 | lua_pop(lua, 1); 119 | } 120 | } 121 | else 122 | { 123 | debugf("[Lua] bootscript load err: %s\n", lua_tostring(lua, -1)); 124 | lua_pop(lua, 1); 125 | }*/ 126 | 127 | debugf("Deinit. Goodbye.\n"); 128 | sceHttpTerm(); 129 | PHYSFS_deinit(); 130 | vita2d_fini(); 131 | //vita2d_free_texture(tex); 132 | 133 | sceKernelExitProcess(0); 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /lua/audio.lua: -------------------------------------------------------------------------------- 1 | -- audio 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | enum { 6 | //! Used for main audio output, freq must be set to 48000 Hz 7 | PSP2_AUDIO_OUT_PORT_TYPE_MAIN = 0, 8 | 9 | //! Used for Background Music port 10 | PSP2_AUDIO_OUT_PORT_TYPE_BGM = 1, 11 | 12 | //! Used for voice chat port 13 | PSP2_AUDIO_OUT_PORT_TYPE_VOICE = 2 14 | }; 15 | 16 | /*const int PSP2_AUDIO_MIN_LEN = 64; 17 | const int PSP2_AUDIO_MAX_LEN = 65472; //!< Maximum granularity*/ 18 | 19 | int sceAudioOutOpenPort(int type, int len, int freq, int mode); 20 | int sceAudioOutReleasePort(int port); 21 | int sceAudioOutOutput(int port, const void *buf); 22 | 23 | /*const int PSP2_AUDIO_OUT_MAX_VOL = 32768; //!< Maximum output port volume 24 | const int PSP2_AUDIO_VOLUME_0DB = PSP2_AUDIO_OUT_MAX_VOL; //!< Maximum output port volume */ 25 | 26 | enum { 27 | PSP2_AUDIO_VOLUME_FLAG_L_CH = 0x1, //!< Left Channel 28 | PSP2_AUDIO_VOLUME_FLAG_R_CH = 0x2 //!< Right Channel 29 | }; 30 | 31 | enum { 32 | PSP2_AUDIO_OUT_MODE_MONO = 0, 33 | PSP2_AUDIO_OUT_MODE_STEREO = 1 34 | }; 35 | 36 | int sceAudioOutSetVolume(int port, int ch, int *vol); 37 | int sceAudioOutSetConfig(int port, int len, int freq, int mode); 38 | 39 | enum { 40 | PSP2_AUDIO_OUT_CONFIG_TYPE_LEN = 0, 41 | PSP2_AUDIO_OUT_CONFIG_TYPE_FREQ = 1, 42 | PSP2_AUDIO_OUT_CONFIG_TYPE_MODE = 2 43 | }; 44 | 45 | int sceAudioOutGetConfig(int port, int type); 46 | int sceAudioOutGetRestSample(int port); 47 | int sceAudioOutGetAdopt(int type); 48 | 49 | ]] 50 | 51 | local function get_port(port) 52 | if port == "main" then 53 | return ffi.C.PSP2_AUDIO_OUT_PORT_TYPE_MAIN 54 | elseif port == "bgm" then 55 | return ffi.C.PSP2_AUDIO_OUT_PORT_TYPE_BGM 56 | elseif port == "voice" then 57 | return ffi.C.PSP2_AUDIO_OUT_PORT_TYPE_VOICE 58 | else 59 | error("Invalid audio port name!") 60 | end 61 | end 62 | 63 | local function get_mode(mode) 64 | if mode == "mono" then 65 | return ffi.C.PSP2_AUDIO_OUT_MODE_MONO 66 | elseif mode == "stereo" then 67 | return ffi.C.PSP2_AUDIO_OUT_MODE_STEREO 68 | else 69 | error("Invalid audio port mode!") 70 | end 71 | end 72 | 73 | audio = {} 74 | 75 | function audio.open(port, len, freq, mode) 76 | if port == "main" then 77 | freq = 48000 78 | end 79 | port = get_port(port) 80 | mode = get_mode(mode) 81 | return ffi.C.sceAudioOutOpenPort(port, len, freq, mode) 82 | end 83 | 84 | function audio.release(port) 85 | ffi.C.sceAudioOutReleasePort(port) 86 | end 87 | 88 | function audio.play(port, samples) -- SAMPLES SHOULD BE A FFI BUFFER 89 | ffi.C.sceAudioOutOutput(port, samples) 90 | end 91 | 92 | function audio.set_volume(port, vol) 93 | v = ffi.new("int[2]", vol, vol) 94 | ffi.C.sceAudioOutSetVolume(port, bit.bor(1,2), v) -- l/r channels 95 | end 96 | 97 | function audio.set_config(port, len, freq, mode) 98 | mode = get_mode(mode) 99 | ffi.C.sceAudioOutSetConfig(port, len, freq, mode) 100 | end 101 | 102 | function audio.get_config(port, t) 103 | t = get_type(t) 104 | return ffi.C.sceAudioOutGetConfig(port, type) 105 | end 106 | 107 | function audio.get_remaining(port) 108 | return ffi.C.sceAudioOutGetRestSample(port) 109 | end 110 | 111 | function audio.is_open(port) 112 | port = get_port(port) 113 | return ffi.C.sceAudioOutGetAdopt(port) == 1 114 | end 115 | 116 | function audio.set_alc(mode) 117 | if mode == "max" then 118 | mode = ffi.C.PSP2_AUDIO_ALC_MODE_MAX 119 | elseif mode == "on" then 120 | mode = ffi.C.PSP2_AUDIO_ALC_MODE1 121 | elseif mode == "off" then 122 | mode = ffi.C.PSP2_AUDIO_ALC_OFF 123 | else 124 | error("Invalid ALC mode!") 125 | end 126 | ffi.C.sceAudioOutSetAlcMode(mode) 127 | end 128 | -------------------------------------------------------------------------------- /lua/touch.lua: -------------------------------------------------------------------------------- 1 | -- touch 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | typedef uint8_t SceUInt8; 6 | typedef int16_t SceInt16; 7 | typedef uint16_t SceUInt16; 8 | typedef uint32_t SceUInt32; 9 | typedef uint64_t SceUInt64; 10 | 11 | enum { 12 | SCE_TOUCH_PORT_FRONT = 0, //!< Front touch panel id 13 | SCE_TOUCH_PORT_BACK = 1, //!< Back touch panel id 14 | SCE_TOUCH_PORT_MAX_NUM = 2 //!< Number of touch panels 15 | }; 16 | 17 | enum { 18 | SCE_TOUCH_MAX_REPORT = 8 //!< FIXME 6 on front | 4 on back 19 | }; 20 | 21 | typedef struct SceTouchPanelInfo { 22 | SceInt16 minAaX; //!< Min active area X position 23 | SceInt16 minAaY; //!< Min active area Y position 24 | SceInt16 maxAaX; //!< Max active area X position 25 | SceInt16 maxAaY; //!< Max active area Y position 26 | SceInt16 minDispX; //!< Min display X origin (top left) 27 | SceInt16 minDispY; //!< Min display Y origin (top left) 28 | SceInt16 maxDispX; //!< Max display X origin (bottom right) 29 | SceInt16 maxDispY; //!< Max display Y origin (bottom right) 30 | SceUInt8 minForce; //!< Min touch force value 31 | SceUInt8 maxForce; //!< Max touch force value 32 | SceUInt8 reserved[30]; //!< Reserved 33 | } SceTouchPanelInfo; 34 | 35 | typedef struct SceTouchReport { 36 | SceUInt8 id; //!< Touch ID 37 | SceUInt8 force; //!< Touch force 38 | SceInt16 x; //!< X position 39 | SceInt16 y; //!< Y position 40 | SceUInt8 reserved[8]; //!< Reserved 41 | SceUInt16 info; //!< Information of this touch 42 | } SceTouchReport; 43 | 44 | typedef struct SceTouchData { 45 | SceUInt64 timeStamp; //!< Data timestamp 46 | SceUInt32 status; //!< Unused 47 | SceUInt32 reportNum; //!< Number of touch reports 48 | SceTouchReport report[SCE_TOUCH_MAX_REPORT]; //!< Touch reports 49 | } SceTouchData; 50 | 51 | int sceTouchGetPanelInfo(SceUInt32 port, SceTouchPanelInfo *pPanelInfo); 52 | int sceTouchRead(SceUInt32 port, SceTouchData *pData, SceUInt32 nBufs); 53 | int sceTouchPeek(SceUInt32 port, SceTouchData *pData, SceUInt32 nBufs); 54 | int sceTouchSetSamplingState(SceUInt32 port, SceUInt32 state); 55 | int sceTouchGetSamplingState(SceUInt32 port, SceUInt32 *pState); 56 | int sceTouchEnableTouchForce(SceUInt32 port); 57 | int sceTouchDisableTouchForce(SceUInt32 port); 58 | ]] 59 | 60 | touch = {} 61 | 62 | local function get_port(p) 63 | if p == "front" then 64 | return ffi.C.SCE_TOUCH_PORT_FRONT 65 | elseif p == "back" then 66 | return ffi.C.SCE_TOUCH_PORT_BACK 67 | else 68 | error("Invalid touch port!") 69 | end 70 | end 71 | 72 | function touch.get_info(port) 73 | port = get_port(port) 74 | info = ffi.new("SceTouchPanelInfo[1]") 75 | ffi.C.sceTouchGetPanelInfo(port, info) 76 | return info[0] 77 | end 78 | 79 | function touch.get_state(port) 80 | port = get_port(port) 81 | s = ffi.new("SceUInt32[1]") 82 | ffi.C.sceTouchGetSamplingState(port, s) 83 | return s[0] 84 | end 85 | 86 | function touch.set_state(port, active) 87 | port = get_port(port) 88 | active = active == 1 and true or false 89 | ffi.C.sceTouchSetSamplingState(port, active) 90 | end 91 | 92 | function touch.enable_force(port) 93 | port = get_port(port) 94 | ffi.C.sceTouchEnableTouchForce(port) 95 | end 96 | 97 | function touch.disable_force(port) 98 | port = get_port(port) 99 | ffi.C.sceTouchDisableTouchForce(port) 100 | end 101 | 102 | function touch.peek(port) 103 | port = get_port(port) 104 | local touch_data = ffi.new("SceTouchData[1]") 105 | ffi.C.sceTouchPeek(port, touch_data, 1) 106 | touch_data = touch_data[0] 107 | dat = {} 108 | for i = 0, touch_data.reportNum do 109 | dat[i + 1] = touch_data.reports[i] 110 | end 111 | return dat 112 | end 113 | 114 | function touch.read(port) 115 | port = get_port(port) 116 | local touch_data = ffi.new("SceTouchData[1]") 117 | ffi.C.sceTouchRead(port, touch_data, 1) 118 | touch_data = touch_data[0] 119 | return touch_data 120 | end 121 | 122 | function touch.is_pressed() 123 | return #touch.peek() ~= 0 124 | end 125 | -------------------------------------------------------------------------------- /src/ffi/physfs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ffi_register_physfs() 6 | { 7 | static Function funcs[] = 8 | { 9 | {"PHYSFS_addToSearchPath", PHYSFS_addToSearchPath}, 10 | {"PHYSFS_close", PHYSFS_close}, 11 | {"PHYSFS_deinit", PHYSFS_deinit}, 12 | {"PHYSFS_delete", PHYSFS_delete}, 13 | {"PHYSFS_enumerateFilesCallback", PHYSFS_enumerateFilesCallback}, 14 | {"PHYSFS_enumerateFiles", PHYSFS_enumerateFiles}, 15 | {"PHYSFS_eof", PHYSFS_eof}, 16 | {"PHYSFS_exists", PHYSFS_exists}, 17 | {"PHYSFS_fileLength", PHYSFS_fileLength}, 18 | {"PHYSFS_flush", PHYSFS_flush}, 19 | {"PHYSFS_freeList", PHYSFS_freeList}, 20 | {"PHYSFS_getBaseDir", PHYSFS_getBaseDir}, 21 | {"PHYSFS_getCdRomDirsCallback", PHYSFS_getCdRomDirsCallback}, 22 | {"PHYSFS_getCdRomDirs", PHYSFS_getCdRomDirs}, 23 | {"PHYSFS_getDirSeparator", PHYSFS_getDirSeparator}, 24 | {"PHYSFS_getLastError", PHYSFS_getLastError}, 25 | {"PHYSFS_getLastModTime", PHYSFS_getLastModTime}, 26 | {"PHYSFS_getLinkedVersion", PHYSFS_getLinkedVersion}, 27 | {"PHYSFS_getMountPoint", PHYSFS_getMountPoint}, 28 | {"PHYSFS_getRealDir", PHYSFS_getRealDir}, 29 | {"PHYSFS_getSearchPathCallback", PHYSFS_getSearchPathCallback}, 30 | {"PHYSFS_getSearchPath", PHYSFS_getSearchPath}, 31 | {"PHYSFS_getUserDir", PHYSFS_getUserDir}, 32 | {"PHYSFS_getWriteDir", PHYSFS_getWriteDir}, 33 | {"PHYSFS_init", PHYSFS_init}, 34 | {"PHYSFS_isDirectory", PHYSFS_isDirectory}, 35 | {"PHYSFS_isInit", PHYSFS_isInit}, 36 | {"PHYSFS_isSymbolicLink", PHYSFS_isSymbolicLink}, 37 | {"PHYSFS_mkdir", PHYSFS_mkdir}, 38 | {"PHYSFS_mount", PHYSFS_mount}, 39 | {"PHYSFS_openAppend", PHYSFS_openAppend}, 40 | {"PHYSFS_openRead", PHYSFS_openRead}, 41 | {"PHYSFS_openWrite", PHYSFS_openWrite}, 42 | {"PHYSFS_permitSymbolicLinks", PHYSFS_permitSymbolicLinks}, 43 | {"PHYSFS_read", PHYSFS_read}, 44 | {"PHYSFS_readSBE16", PHYSFS_readSBE16}, 45 | {"PHYSFS_readSBE32", PHYSFS_readSBE32}, 46 | {"PHYSFS_readSBE64", PHYSFS_readSBE64}, 47 | {"PHYSFS_readSLE16", PHYSFS_readSLE16}, 48 | {"PHYSFS_readSLE32", PHYSFS_readSLE32}, 49 | {"PHYSFS_readSLE64", PHYSFS_readSLE64}, 50 | {"PHYSFS_readUBE16", PHYSFS_readUBE16}, 51 | {"PHYSFS_readUBE32", PHYSFS_readUBE32}, 52 | {"PHYSFS_readUBE64", PHYSFS_readUBE64}, 53 | {"PHYSFS_readULE16", PHYSFS_readULE16}, 54 | {"PHYSFS_readULE32", PHYSFS_readULE32}, 55 | {"PHYSFS_readULE64", PHYSFS_readULE64}, 56 | {"PHYSFS_removeFromSearchPath", PHYSFS_removeFromSearchPath}, 57 | {"PHYSFS_seek", PHYSFS_seek}, 58 | {"PHYSFS_setAllocator", PHYSFS_setAllocator}, 59 | {"PHYSFS_setBuffer", PHYSFS_setBuffer}, 60 | {"PHYSFS_setSaneConfig", PHYSFS_setSaneConfig}, 61 | {"PHYSFS_setWriteDir", PHYSFS_setWriteDir}, 62 | {"PHYSFS_supportedArchiveTypes", PHYSFS_supportedArchiveTypes}, 63 | {"PHYSFS_swapSBE16", PHYSFS_swapSBE16}, 64 | {"PHYSFS_swapSBE32", PHYSFS_swapSBE32}, 65 | {"PHYSFS_swapSBE64", PHYSFS_swapSBE64}, 66 | {"PHYSFS_swapSLE16", PHYSFS_swapSLE16}, 67 | {"PHYSFS_swapSLE32", PHYSFS_swapSLE32}, 68 | {"PHYSFS_swapSLE64", PHYSFS_swapSLE64}, 69 | {"PHYSFS_swapUBE16", PHYSFS_swapUBE16}, 70 | {"PHYSFS_swapUBE32", PHYSFS_swapUBE32}, 71 | {"PHYSFS_swapUBE64", PHYSFS_swapUBE64}, 72 | {"PHYSFS_swapULE16", PHYSFS_swapULE16}, 73 | {"PHYSFS_swapULE32", PHYSFS_swapULE32}, 74 | {"PHYSFS_swapULE64", PHYSFS_swapULE64}, 75 | {"PHYSFS_symbolicLinksPermitted", PHYSFS_symbolicLinksPermitted}, 76 | {"PHYSFS_tell", PHYSFS_tell}, 77 | {"PHYSFS_utf8FromLatin1", PHYSFS_utf8FromLatin1}, 78 | {"PHYSFS_utf8FromUcs2", PHYSFS_utf8FromUcs2}, 79 | {"PHYSFS_utf8FromUcs4", PHYSFS_utf8FromUcs4}, 80 | {"PHYSFS_utf8ToUcs2", PHYSFS_utf8ToUcs2}, 81 | {"PHYSFS_utf8ToUcs4", PHYSFS_utf8ToUcs4}, 82 | {"PHYSFS_write", PHYSFS_write}, 83 | {"PHYSFS_writeSBE16", PHYSFS_writeSBE16}, 84 | {"PHYSFS_writeSBE32", PHYSFS_writeSBE32}, 85 | {"PHYSFS_writeSBE64", PHYSFS_writeSBE64}, 86 | {"PHYSFS_writeSLE16", PHYSFS_writeSLE16}, 87 | {"PHYSFS_writeSLE32", PHYSFS_writeSLE32}, 88 | {"PHYSFS_writeSLE64", PHYSFS_writeSLE64}, 89 | {"PHYSFS_writeUBE16", PHYSFS_writeUBE16}, 90 | {"PHYSFS_writeUBE32", PHYSFS_writeUBE32}, 91 | {"PHYSFS_writeUBE64", PHYSFS_writeUBE64}, 92 | {"PHYSFS_writeULE16", PHYSFS_writeULE16}, 93 | {"PHYSFS_writeULE32", PHYSFS_writeULE32}, 94 | {"PHYSFS_writeULE64", PHYSFS_writeULE64}, 95 | {NULL, NULL} 96 | }; 97 | static FunctionTable table = { .funcs = funcs, .next = NULL }; 98 | ffi_add_table(&table); 99 | } 100 | -------------------------------------------------------------------------------- /lua/input.lua: -------------------------------------------------------------------------------- 1 | -- input 2 | local bit = require 'bit' 3 | local ffi = require 'ffi' 4 | 5 | ffi.cdef [[ 6 | typedef uint8_t SceUInt8; 7 | typedef int16_t SceInt16; 8 | typedef uint16_t SceUInt16; 9 | typedef uint32_t SceUInt32; 10 | typedef uint64_t SceUInt64; 11 | 12 | enum { 13 | PSP2_CTRL_SELECT = 0x000001, //!< Select button. 14 | PSP2_CTRL_START = 0x000008, //!< Start button. 15 | PSP2_CTRL_UP = 0x000010, //!< Up D-Pad button. 16 | PSP2_CTRL_RIGHT = 0x000020, //!< Right D-Pad button. 17 | PSP2_CTRL_DOWN = 0x000040, //!< Down D-Pad button. 18 | PSP2_CTRL_LEFT = 0x000080, //!< Left D-Pad button. 19 | PSP2_CTRL_LTRIGGER = 0x000100, //!< Left trigger. 20 | PSP2_CTRL_RTRIGGER = 0x000200, //!< Right trigger. 21 | PSP2_CTRL_TRIANGLE = 0x001000, //!< Triangle button. 22 | PSP2_CTRL_CIRCLE = 0x002000, //!< Circle button. 23 | PSP2_CTRL_CROSS = 0x004000, //!< Cross button. 24 | PSP2_CTRL_SQUARE = 0x008000, //!< Square button. 25 | PSP2_CTRL_ANY = 0x010000 //!< Any input intercepted. 26 | }; 27 | 28 | enum { 29 | /** Digitial buttons only. */ 30 | PSP2_CTRL_MODE_DIGITAL = 0, 31 | /** Digital buttons + Analog support. */ 32 | PSP2_CTRL_MODE_ANALOG, 33 | /** Same as ::PSP2_CTRL_MODE_ANALOG, but with larger range for analog sticks. */ 34 | PSP2_CTRL_MODE_ANALOG_WIDE 35 | }; 36 | 37 | /** Returned controller data */ 38 | typedef struct SceCtrlData { 39 | /** The current read frame. */ 40 | uint64_t timeStamp; 41 | /** Bit mask containing zero or more of ::CtrlButtons. */ 42 | unsigned int buttons; 43 | /** Left analogue stick, X axis. */ 44 | unsigned char lx; 45 | /** Left analogue stick, Y axis. */ 46 | unsigned char ly; 47 | /** Right analogue stick, X axis. */ 48 | unsigned char rx; 49 | /** Right analogue stick, Y axis. */ 50 | unsigned char ry; 51 | /** Reserved. */ 52 | uint8_t reserved[16]; 53 | } SceCtrlData; 54 | 55 | typedef struct SceCtrlRapidFireRule { 56 | unsigned int Mask; 57 | unsigned int Trigger; 58 | unsigned int Target; 59 | unsigned int Delay; 60 | unsigned int Make; 61 | unsigned int Break; 62 | } SceCtrlRapidFireRule; 63 | 64 | int sceCtrlSetSamplingMode(int mode); 65 | int sceCtrlGetSamplingMode(int *pMode); 66 | int sceCtrlPeekBufferPositive(int port, SceCtrlData *pad_data, int count); 67 | int sceCtrlPeekBufferNegative(int port, SceCtrlData *pad_data, int count); 68 | int sceCtrlReadBufferPositive(int port, SceCtrlData *pad_data, int count); 69 | int sceCtrlReadBufferNegative(int port, SceCtrlData *pad_data, int count); 70 | int sceCtrlSetRapidFire(int port, int idx, const SceCtrlRapidFireRule* pRule); 71 | int sceCtrlClearRapidFire(int port, int idx); 72 | ]] 73 | 74 | input = {} 75 | buttons = { 76 | ["select"] = ffi.C.PSP2_CTRL_SELECT, 77 | ["start"] = ffi.C.PSP2_CTRL_START, 78 | ["up"] = ffi.C.PSP2_CTRL_UP, 79 | ["right"] = ffi.C.PSP2_CTRL_RIGHT, 80 | ["down"] = ffi.C.PSP2_CTRL_DOWN, 81 | ["left"] = ffi.C.PSP2_CTRL_LEFT, 82 | ["l_trigger"] = ffi.C.PSP2_CTRL_LTRIGGER, 83 | ["r_trigger"] = ffi.C.PSP2_CTRL_RTRIGGER, 84 | ["triangle"] = ffi.C.PSP2_CTRL_TRIANGLE, 85 | ["circle"] = ffi.C.PSP2_CTRL_CIRCLE, 86 | ["cross"] = ffi.C.PSP2_CTRL_CROSS, 87 | ["square"] = ffi.C.PSP2_CTRL_SQUARE, 88 | ["any"] = ffi.C.PSP2_CTRL_ANY 89 | } 90 | 91 | local ctrl_mt = { __index = {} } 92 | 93 | for k,v in pairs(buttons) do 94 | ctrl_mt.__index[k] = function (self) return bit.band(self.buttons, buttons[k]) ~= 0 end 95 | end 96 | 97 | local ctrl_data = ffi.metatype("SceCtrlData", ctrl_mt) 98 | 99 | function input.set_mode(mode) 100 | if mode == "digital" then 101 | mode = ffi.C.PSP2_CTRL_MODE_DIGITAL 102 | elseif mode == "analog" then 103 | mode = ffi.C.PSP2_CTRL_MODE_ANALOG 104 | elseif mode == "analog_wide" then 105 | mode = PSP2_CTRL_MODE_ANALOG_WIDE 106 | else 107 | error("Invalid input mode!") 108 | end 109 | ffi.C.sceCtrlGetSamplingMode(mode) 110 | end 111 | 112 | function input.get_mode() 113 | mode = ffi.new("SceUint32[1]") 114 | ffi.C.sceCtrlGetSamplingMode(mode) 115 | mode = mode[0] 116 | if mode == ffi.C.PSP2_CTRL_MODE_DIGITAL then 117 | mode = "digital" 118 | elseif mode == ffi.C.PSP2_CTRL_MODE_ANALOG then 119 | mode = "analog" 120 | elseif mode == ffi.C.PSP2_CTRL_MODE_ANALOG_WIDE then 121 | mode = "analog_wide" 122 | end 123 | return mode 124 | end 125 | 126 | function input.peek(mode) 127 | if mode == nil then mode = "positive" end 128 | pad = ffi.new("SceCtrlData[1]") 129 | if mode == "positive" then 130 | ffi.C.sceCtrlPeekBufferPositive(0, pad, 1) 131 | elseif mode == "negative" then 132 | ffi.C.sceCtrlPeekBufferNegative(0, pad, 1) 133 | end 134 | return pad[0] 135 | end 136 | 137 | function input.read(mode) 138 | if mode == nil then mode = "positive" end 139 | pad = ffi.new("SceCtrlData[1]") 140 | if mode == "positive" then 141 | ffi.C.sceCtrlReadBufferPositive(0, pad, 1) 142 | elseif mode == "negative" then 143 | ffi.C.sceCtrlReadBufferNegative(0, pad, 1) 144 | end 145 | return pad[0] 146 | end 147 | 148 | function input.is_pressed(button) 149 | local pad = input.peek() 150 | if bit.band(button, pad.buttons) ~= 0 then 151 | return true 152 | else return false end 153 | end 154 | -------------------------------------------------------------------------------- /lua/http.lua: -------------------------------------------------------------------------------- 1 | -- http 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | typedef enum { 6 | PSP2_HTTP_VERSION_1_0 = 1, 7 | PSP2_HTTP_VERSION_1_1 8 | } SceHttpHttpVersion; 9 | 10 | typedef enum { 11 | PSP2_HTTP_METHOD_GET, 12 | PSP2_HTTP_METHOD_POST, 13 | PSP2_HTTP_METHOD_HEAD, 14 | PSP2_HTTP_METHOD_OPTIONS, 15 | PSP2_HTTP_METHOD_PUT, 16 | PSP2_HTTP_METHOD_DELETE, 17 | PSP2_HTTP_METHOD_TRACE, 18 | PSP2_HTTP_METHOD_CONNECT 19 | } SceHttpMethods; 20 | 21 | int sceHttpInit(unsigned int poolSize); 22 | int sceHttpTerm(void); 23 | int sceHttpCreateTemplate(const char *userAgent, int httpVer, int autoProxyConf); 24 | int sceHttpDeleteTemplate(int tmplId); 25 | int sceHttpCreateConnection(int tmplId, const char *serverName, const char *scheme, unsigned short port, int enableKeepalive); 26 | int sceHttpCreateConnectionWithURL(int tmplId, const char *url, int enableKeepalive); 27 | int sceHttpDeleteConnection(int connId); 28 | int sceHttpCreateRequest(int connId, int method, const char *path, unsigned long long int contentLength); 29 | int sceHttpCreateRequestWithURL(int connId, int method, const char *url, unsigned long long int contentLength); 30 | int sceHttpDeleteRequest(int reqId); 31 | 32 | int sceHttpSendRequest(int reqId, const void *postData, unsigned int size); 33 | int sceHttpAbortRequest(int reqId); 34 | int sceHttpGetResponseContentLength(int reqId, unsigned long long int *contentLength); 35 | int sceHttpGetStatusCode(int reqId, int *statusCode); 36 | int sceHttpGetAllResponseHeaders(int reqId, char **header, unsigned int *headerSize); 37 | int sceHttpReadData(int reqId, void *data, unsigned int size); 38 | int sceHttpAddRequestHeader(int id, const char *name, const char *value, unsigned int mode); 39 | int sceHttpRemoveRequestHeader(int id, const char *name); 40 | ]] 41 | 42 | local C = ffi.C 43 | 44 | local messages = 45 | { 46 | [-2143088639] = "BEFORE_INIT", 47 | [-2143088608] = "ALREADY_INITED", 48 | [-2143088607] = "BUSY", 49 | [-2143088606] = "OUT_OF_MEMORY", 50 | [-2143088603] = "NOT_FOUND", 51 | [-2143088534] = "INVALID_VERSION", 52 | [-2143088384] = "INVALID_ID", 53 | [-2143088380] = "OUT_OF_SIZE", 54 | [-2143088130] = "INVALID_VALUE", 55 | [-2143080352] = "INVALID_URL", 56 | [-2143088543] = "UNKNOWN_SCHEME", 57 | [-2143088541] = "NETWORK", 58 | [-2143088540] = "BAD_RESPONSE", 59 | [-2143088539] = "BEFORE_SEND", 60 | [-2143088538] = "AFTER_SEND", 61 | [-2143088536] = "TIMEOUT", 62 | [-2143088535] = "UNKOWN_AUTH_TYPE", 63 | [-2143088533] = "UNKNOWN_METHOD", 64 | [-2143088529] = "READ_BY_HEAD_METHOD", 65 | [-2143088528] = "NOT_IN_COM", 66 | [-2143088527] = "NO_CONTENT_LENGTH", 67 | [-2143088526] = "CHUNK_ENC", 68 | [-2143088525] = "TOO_LARGE_RESPONSE_HEADER", 69 | [-2143088523] = "SSL", 70 | [-2143088512] = "ABORTED", 71 | [-2143088511] = "UNKNOWN", 72 | [-2143084507] = "PARSE_HTTP_NOT_FOUND", 73 | [-2143084448] = "PARSE_HTTP_INVALID_RESPONSE", 74 | [-2143084034] = "PARSE_HTTP_INVALID_VALUE", 75 | [-2143068159] = "RESOLVER_EPACKET", 76 | [-2143068158] = "RESOLVER_ENODNS", 77 | [-2143068157] = "RESOLVER_ETIMEDOUT", 78 | [-2143068156] = "RESOLVER_ENOSUPPORT", 79 | [-2143068155] = "RESOLVER_EFORMAT", 80 | [-2143068154] = "RESOLVER_ESERVERFAILURE", 81 | [-2143068153] = "RESOLVER_ENOHOST", 82 | [-2143068152] = "RESOLVER_ENOTIMPLEMENTED", 83 | [-2143068151] = "RESOLVER_ESERVERREFUSED", 84 | [-2143068150] = "RESOLVER_ENORECORD" 85 | } 86 | 87 | http = {} 88 | local template 89 | 90 | local req_mt = 91 | { 92 | __index = 93 | { 94 | len = function(self) 95 | local len = ffi.new("uint64_t[1]") 96 | C.sceHttpGetResponseContentLength(self.req, len) 97 | return tonumber(len[0]) 98 | end, 99 | 100 | read = function(self, spec) 101 | local len 102 | if spec == "*all" or spec == "*a" or spec == nil then 103 | len = self:len() 104 | elseif type(spec) == "number" then 105 | len = spec 106 | else 107 | error("invalid read() specification") 108 | end 109 | local buf = ffi.new("uint8_t[?]", len) 110 | local r = C.sceHttpReadData(self.req, buf, len) 111 | if r < 0 then 112 | return nil, messages[r] 113 | elseif r == 0 then 114 | return nil, "eof" 115 | end 116 | return ffi.string(buf, r) 117 | end, 118 | 119 | close = function(self) 120 | C.sceHttpDeleteRequest(self.req) 121 | C.sceHttpDeleteConnection(self.conn) 122 | end 123 | } 124 | } 125 | 126 | --[[function http.init() 127 | return C.sceHttpInit(100) 128 | end 129 | 130 | function http.term() 131 | return C.sceHttpTerm() 132 | end]] 133 | 134 | function http.request(meth, url, post_data) 135 | if meth == "GET" then 136 | meth = C.PSP2_HTTP_METHOD_GET 137 | elseif meth == "POST" then 138 | meth = C.PSP2_HTTP_METHOD_POST 139 | else 140 | error("No such method.") 141 | end 142 | 143 | if template == nil then 144 | template = C.sceHttpCreateTemplate("VitaLua", C.PSP2_HTTP_VERSION_1_1, 0) 145 | end 146 | 147 | local conn = C.sceHttpCreateConnectionWithURL(template, url, 0) 148 | if conn == 0 then 149 | return nil, "createConnection failed" 150 | end 151 | 152 | local req = C.sceHttpCreateRequestWithURL(conn, meth, url, post_data and #post_data or 0) 153 | if req == 0 then 154 | return nil, "createRequest failed" 155 | end 156 | 157 | local r = C.sceHttpSendRequest(req, post_data, post_data and #post_data or 0) 158 | if r < 0 then 159 | return nil, messages[r] 160 | end 161 | local status = ffi.new('int[1]') 162 | r = C.sceHttpGetStatusCode(req, status) 163 | if r < 0 then 164 | C.sceHttpDeleteRequest(req) 165 | C.sceHttpDeleteConnection(conn) 166 | return nil, messages[r] 167 | end 168 | 169 | local r = { req = req, conn = conn } 170 | setmetatable(r, req_mt) 171 | return status[0], r 172 | end 173 | 174 | function http.get(url) 175 | return http.request("GET", url) 176 | end 177 | 178 | function http.post(url, post_data) 179 | return http.request("POST", url, post_data) 180 | end 181 | -------------------------------------------------------------------------------- /lua/fs.lua: -------------------------------------------------------------------------------- 1 | -- fs 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | 6 | typedef struct SceDateTime { 7 | unsigned short year; 8 | unsigned short month; 9 | unsigned short day; 10 | unsigned short hour; 11 | unsigned short minute; 12 | unsigned short second; 13 | unsigned int microsecond; 14 | } SceDateTime; 15 | typedef int64_t SceInt64; 16 | typedef int SceUID; 17 | typedef int SceMode; 18 | typedef SceInt64 SceOff; 19 | 20 | enum { 21 | /** Format bits mask */ 22 | PSP2_S_IFMT = 0xF000, 23 | /** Symbolic link */ 24 | PSP2_S_IFLNK = 0x4000, 25 | /** Directory */ 26 | PSP2_S_IFDIR = 0x1000, 27 | /** Regular file */ 28 | PSP2_S_IFREG = 0x2000, 29 | 30 | /** Set UID */ 31 | PSP2_S_ISUID = 0x0800, 32 | /** Set GID */ 33 | PSP2_S_ISGID = 0x0400, 34 | /** Sticky */ 35 | PSP2_S_ISVTX = 0x0200, 36 | 37 | /** User access rights mask */ 38 | PSP2_S_IRWXU = 0x01C0, 39 | /** Read user permission */ 40 | PSP2_S_IRUSR = 0x0100, 41 | /** Write user permission */ 42 | PSP2_S_IWUSR = 0x0080, 43 | /** Execute user permission */ 44 | PSP2_S_IXUSR = 0x0040, 45 | 46 | /** Group access rights mask */ 47 | PSP2_S_IRWXG = 0x0038, 48 | /** Group read permission */ 49 | PSP2_S_IRGRP = 0x0020, 50 | /** Group write permission */ 51 | PSP2_S_IWGRP = 0x0010, 52 | /** Group execute permission */ 53 | PSP2_S_IXGRP = 0x0008, 54 | 55 | /** Others access rights mask */ 56 | PSP2_S_IRWXO = 0x0007, 57 | /** Others read permission */ 58 | PSP2_S_IROTH = 0x0004, 59 | /** Others write permission */ 60 | PSP2_S_IWOTH = 0x0002, 61 | /** Others execute permission */ 62 | PSP2_S_IXOTH = 0x0001, 63 | }; 64 | 65 | enum { 66 | /** Format mask */ 67 | PSP2_SO_IFMT = 0x0038, // Format mask 68 | /** Symlink */ 69 | PSP2_SO_IFLNK = 0x0008, // Symbolic link 70 | /** Directory */ 71 | PSP2_SO_IFDIR = 0x0010, // Directory 72 | /** Regular file */ 73 | PSP2_SO_IFREG = 0x0020, // Regular file 74 | 75 | /** Hidden read permission */ 76 | PSP2_SO_IROTH = 0x0004, // read 77 | /** Hidden write permission */ 78 | PSP2_SO_IWOTH = 0x0002, // write 79 | /** Hidden execute permission */ 80 | PSP2_SO_IXOTH = 0x0001, // execute 81 | }; 82 | 83 | /** Structure to hold the status information about a file */ 84 | typedef struct SceIoStat { 85 | SceMode st_mode; 86 | unsigned int st_attr; 87 | /** Size of the file in bytes. */ 88 | SceOff st_size; 89 | /** Creation time. */ 90 | SceDateTime st_ctime; 91 | /** Access time. */ 92 | SceDateTime st_atime; 93 | /** Modification time. */ 94 | SceDateTime st_mtime; 95 | /** Device-specific data. */ 96 | unsigned int st_private[6]; 97 | } SceIoStat; 98 | 99 | typedef struct SceIoDirent { 100 | /** File status. */ 101 | SceIoStat d_stat; 102 | /** File name. */ 103 | char d_name[256]; 104 | /** Device-specific data. */ 105 | void *d_private; 106 | int dummy; 107 | } SceIoDirent; 108 | 109 | SceUID sceIoDopen(const char *dirname); 110 | int sceIoDread(SceUID fd, SceIoDirent *dir); 111 | int sceIoDclose(SceUID fd); 112 | int sceIoMkdir(const char *dir, SceMode mode); 113 | int sceIoRmdir(const char *path); 114 | int sceIoGetstat(const char *file, SceIoStat *stat); 115 | int sceIoChstat(const char *file, SceIoStat *stat, int bits); 116 | // int sceIoChdir(const char *path); 117 | ]] 118 | 119 | fs = {} 120 | fs.working_dir = "ux0:/" 121 | 122 | function fs.list(path) 123 | t = {} 124 | 125 | fd = ffi.C.sceIoDopen(path) 126 | if fd < 0 then return end 127 | dirent = ffi.new("SceIoDirent[1]") 128 | while ffi.C.sceIoDread(fd, dirent) > 0 do 129 | local file = dirent[0] 130 | print(file.d_name) 131 | t[#t + 1] = { name = ffi.string(file.d_name), directory = (bit.band(file.d_stat.st_attr, ffi.C.PSP2_S_IFDIR) ~= 0), size = tonumber(file.d_stat.st_size) } 132 | end 133 | return t 134 | end 135 | 136 | function fs.mkdir(path) 137 | return ffi.C.sceIoMkdir(path, bit.bor(ffi.C.PSP2_S_IRWXU, ffi.C.PSP2_S_IRWXG, ffi.C.PSP2_S_IXOTH)) == 0 -- all the permissions! 138 | end 139 | 140 | function fs.rmdir(path) 141 | return ffi.C.sceIoRmdir(path) == 0 142 | end 143 | 144 | function fs.is_dir(path) 145 | local stat = ffi.new("SceIoStat[1]") 146 | if ffi.C.sceIoGetstat(path, stat) < 0 then 147 | return nil 148 | end 149 | return bit.band(stat[0].st_mode, ffi.C.PSP2_SO_IFMT) == ffi.C.PSP2_SO_IFDIR 150 | end 151 | 152 | function fs.is_file(path) 153 | local stat = ffi.new("SceIoStat[1]") 154 | if ffi.C.sceIoGetstat(path, stat) < 0 then 155 | return nil 156 | end 157 | return bit.band(stat[0].st_mode, ffi.C.PSP2_SO_IFMT) == ffi.C.PSP2_SO_IFREG 158 | end 159 | 160 | function fs.is_link(path) 161 | local stat = ffi.new("SceIoStat[1]") 162 | if ffi.C.sceIoGetstat(path, stat) < 0 then 163 | return nil 164 | end 165 | return bit.band(stat[0].st_mode, ffi.C.PSP2_SO_IFMT) == ffi.C.PSP2_SO_IFLNK 166 | end 167 | 168 | 169 | function fs.chdir(path) 170 | if path == nil then 171 | return fs.working_dir 172 | end 173 | 174 | if fs.is_relative(path) then 175 | path = fs.working_dir .. "/" .. path 176 | end 177 | 178 | local tmp = fs.working_dir 179 | fs.working_dir = path 180 | return tmp 181 | end 182 | 183 | function fs.is_relative(path) 184 | return not path:find("^(.-):/") 185 | end 186 | 187 | local orig_io = io 188 | io = {} 189 | setmetatable(io, { __index = orig_io }) 190 | 191 | function io.open(name, mode) 192 | if fs.is_relative(name) then 193 | name = fs.working_dir .. "/" .. name 194 | end 195 | return orig_io.open(name, mode) 196 | end 197 | 198 | local orig_dofile = dofile 199 | local orig_loadfile = loadfile 200 | 201 | function dofile(path) 202 | if fs.is_relative(path) then 203 | path = fs.working_dir .. "/" .. path 204 | end 205 | orig_dofile(path) 206 | end 207 | 208 | function loadfile(path) 209 | if fs.is_relative(path) then 210 | path = fs.working_dir .. "/" .. path 211 | end 212 | return orig_loadfile(path) 213 | end 214 | -------------------------------------------------------------------------------- /lua/lua_player.lua: -------------------------------------------------------------------------------- 1 | -- lua player 2 | local bit = require 'bit' 3 | local ffi = require 'ffi' 4 | 5 | local function current_time() 6 | return os.clock() * 1000 7 | end 8 | 9 | player_is_psp = true 10 | 11 | function start_player() 12 | vita2d.init() 13 | local monospace_font = vita2d.load_font() 14 | local prop_font = vita2d.load_font() 15 | 16 | System = {} 17 | System.setCpuSpeed = function () end 18 | System.currentDirectory = function(p) if p == nil then return fs.working_dir else print("new dir is " .. p) fs.chdir(p) end end 19 | System.listDirectory = function(p) print("listing " .. tostring(p) .. " " .. fs.working_dir) if p == nil then return fs.list(fs.working_dir) else return fs.list(p) end end 20 | System.createDirectory = fs.mkdir 21 | System.removeDirectory = fs.rmdir 22 | System.removeFile = function(path) 23 | if fs.is_relative(path) then 24 | path = fs.working_dir + "/" + path 25 | end 26 | os.remove(path) 27 | end 28 | System.draw = vita2d.start_drawing 29 | System.endDraw = vita2d.end_drawing 30 | 31 | System.MSGDIALOG_RESULT_YES = 0 32 | System.MSGDIALOG_RESULT_NO = 1 33 | System.MSGDIALOG_RESULT_BACK = 2 34 | System.MSGDIALOG_RESULT_UNKNOWN1 = 3 35 | System.msgDialog = function(text, default) -- hack 36 | return System.MSGDIALOG_RESULT_NO 37 | end 38 | 39 | System.quit = function() 40 | os.exit(0) 41 | end 42 | 43 | Timer = {} 44 | Timer.new = function(start) 45 | t = { t = 0, off = start and start or 0} 46 | setmetatable(t, { __index = Timer }) 47 | return t 48 | end 49 | 50 | Timer.start = function(self) 51 | if self.t ~= 0 then 52 | return self:time() 53 | else 54 | self.t = math.round(os.clock() * 1000) 55 | return self.off 56 | end 57 | end 58 | 59 | Timer.time = function(self) 60 | if self.t ~= 0 then 61 | return self.off + current_time() - self.t 62 | else 63 | return self.off 64 | end 65 | end 66 | 67 | Timer.stop = function(self) 68 | if self.t ~= 0 then 69 | self.off = self.off + current_time() - self.t 70 | self.t = 0 71 | end 72 | return self.off 73 | end 74 | 75 | Timer.reset = function(self, start) 76 | local tmp 77 | tmp = self:time() 78 | 79 | self.t = 0 80 | self.off = start and start or 0 81 | return tmp 82 | end 83 | 84 | Color = {} 85 | Color.new = function(r, g, b, a) 86 | if a == nil then a = 255 end 87 | t = { r = r, g = g, b = b, a = a} 88 | setmetatable(t, Color) 89 | return t 90 | end 91 | 92 | Color.colors = function(self) 93 | return {self.r,self.g,self.b,self.a} 94 | end 95 | 96 | Color.__equals = function(a, b) 97 | return a.r == b.r and a.g == b.g and a.b == g.b and a.a == b.a 98 | end 99 | 100 | Image = {} 101 | 102 | local function to_rgba(c) 103 | return bit.bor(bit.lshift(c.a, 24), bit.lshift(c.b, 16), bit.lshift(c.g, 8), c.r) 104 | end 105 | 106 | local function to_color(rgba) 107 | return Color.new(bit.band(rgba, 0xff), bit.rshift(bit.band(rgba, 0x0000ff00), 8), bit.rshift(bit.band(rgba, 0x00ff0000), 16), bit.rshift(bit.band(rgba, 0xff000000), 24)) 108 | end 109 | 110 | screen = {} 111 | screen.fillRect = function(x,y,w,h,c) 112 | if c == nil then 113 | c = Color.new(0,0,0) 114 | end 115 | vita2d.draw_rectangle(x,y,w,h,to_rgba(c)) 116 | end 117 | 118 | screen.drawLine = function(x0,y0,x1,y1,c) 119 | if c == nil then 120 | c = Color.new(0,0,0) 121 | end 122 | vita2d.draw_rectangle(x0,y0,x1,y1,to_rgba(c)) 123 | end 124 | 125 | screen.flip = vita2d.swap_buffers 126 | screen.width = function() 127 | if player_is_psp then 128 | return 480 129 | else 130 | return 960 131 | end 132 | end 133 | 134 | screen.height = function() 135 | if player_is_psp then 136 | return 272 137 | else 138 | return 544 139 | end 140 | end 141 | 142 | screen.print = function(self, x, y, text, c) 143 | if c == nil then 144 | c = Color.new(0,0,0) 145 | end 146 | monospace_font:draw_text(x, y, text, to_rgba(c)) 147 | end 148 | 149 | screen.fontPrint = function(self, font, x, y, text, c) 150 | if c == nil then 151 | c = Color.new(0,0,0) 152 | end 153 | font:draw_text(x, y, text, to_rgba(c)) 154 | end 155 | 156 | screen.pixel = function(self, x, y, c) 157 | pixels = ffi.cast("uint32_t *", vita2d.get_framebuffer()) 158 | if c == nil then 159 | return to_color(pixels[(y * 960) + x]) 160 | else 161 | pixels[(y * 960) + x] = to_rgba(c) 162 | end 163 | end 164 | 165 | screen.clear = function(self) vita2d.clear_screen() end 166 | screen.slowClear = screen.clear 167 | 168 | setmetatable(screen, { __index = Image }) 169 | 170 | Image.createEmpty = function(width, height) 171 | t = { tex = vita2d.create_empty_texture(width, height) } 172 | setmetatable(t, { __index = Image } ) 173 | return t 174 | end 175 | 176 | Image.load = function(filename) 177 | t = { tex = vita2d.load_texture(filename) } 178 | setmetatable(t, { __index = Image }) 179 | return t 180 | end 181 | 182 | Image.width = function(self) return self.tex:width() end 183 | Image.height = function(self) return self.tex:height() end 184 | 185 | Image.blit = function(self, x, y, source, alpha, sx, sy, w, h) 186 | if sx == nil and sy == nil and w == nil and h == nil then 187 | sx = 0 188 | sy = 0 189 | w = source:width() 190 | h = source:height() 191 | end 192 | 193 | if alpha == nil then 194 | alpha = 1 195 | end 196 | 197 | if self == screen then 198 | source.tex:draw_part(x, y, sx, sy, w, h) 199 | else 200 | error("blit between images isn't implemented!") 201 | end 202 | end 203 | 204 | Image.pixel = function(self, x, y, c) 205 | pixels = ffi.cast("uint32_t *", self.tex:data()) 206 | if c == nil then 207 | return to_color(pixels[(y * self.tex:width()) + x]) 208 | else 209 | pixels[(y * self.tex:width()) + x] = to_rgba(c) 210 | end 211 | end 212 | 213 | Image.clear = function(self, c) 214 | if c == nil then 215 | c = Color.new(0, 0, 0, 0) 216 | end 217 | c = to_rgba(c) 218 | pixels = ffi.cast("uint32_t *", self.tex:data()) 219 | print(debug.traceback()) 220 | print("clear " .. self.tex:stride()) 221 | print(tostring(self.tex:format())) 222 | for y = 0, self.tex:height()-1 do 223 | print(y) 224 | for x = 0, self.tex:width()-1 do 225 | pixels[(y * self.tex:width()) + x] = c 226 | end 227 | end 228 | end 229 | 230 | Image.save = function(self) 231 | -- hack: stubbed out 232 | end 233 | 234 | Image.free = function(self) 235 | vita2d.free_texture(self.tex) 236 | self.tex = nil 237 | end 238 | 239 | Controls = {} 240 | 241 | Controls.__equals = function(a,b) 242 | return a:buttons() == b:buttons() 243 | end 244 | 245 | Controls.read = function() 246 | t = {buf = input.peek()} 247 | setmetatable(t, { __index = Controls }) 248 | return t 249 | end 250 | 251 | Controls.buttons = function(self) 252 | return self.buf.buttons 253 | end 254 | 255 | funcs = {"select", "start", "up", "right", "down", "left", "triangle", "circle", "cross", "square"} 256 | for k,v in pairs(funcs) do 257 | Controls[v] = function (self) return bit.band(self:buttons(), buttons[v]) ~= 0 end 258 | end 259 | 260 | Controls.l = function(self) return bit.band(self:buttons(), buttons.l_trigger) end 261 | Controls.r = function(self) return bit.band(self:buttons(), buttons.r_trigger) end 262 | 263 | Controls.analogX = function(self) 264 | return self.buf.lx 265 | end 266 | 267 | Controls.analogY = function(self) 268 | return self.buf.ly 269 | end 270 | 271 | os.time = function() return 0 end -- hack - random is no longer random 272 | end 273 | -------------------------------------------------------------------------------- /lua/ui.lua: -------------------------------------------------------------------------------- 1 | -- ui 2 | ui = {} 3 | function ui.choose(options, title, selected, hook, titlecolor, selectedoptcolor, optioncolor, font_custom) 4 | print("ui.choose") 5 | if not options then 6 | error("ui.choose: no options given") 7 | end 8 | local font_to_use = font_custom or font or vita2d.load_font() 9 | local selectedoptcolor = selectedcolor or colors.red 10 | local optioncolor = optioncolor or colors.white 11 | local titlecolor = titlecolor or colors.blue 12 | 13 | local old_pad = input.peek() 14 | 15 | local selected = selected or 1 16 | local num = 18 17 | if title then 18 | num = 17 19 | end 20 | 21 | while true do 22 | print("peek, start, clear") 23 | local pad = input.peek() 24 | vita2d.start_drawing() 25 | vita2d.clear_screen() 26 | 27 | local p = 0 28 | 29 | local min = (selected <= num and 1 or selected - num + 1) 30 | local max = math.min(#options, (selected <= num and num or selected)) 31 | 32 | if title then 33 | print("drawing title text") 34 | font_to_use:draw_text(0, 0, titlecolor, 30, title) 35 | p = 1 36 | end 37 | for i=min, max do 38 | if options[i] then 39 | print("Drawing item") 40 | font_to_use:draw_text(0, p * 30, i == selected and selectedoptcolor or optioncolor, 30, options[i]) 41 | end 42 | p = p + 1 43 | end 44 | 45 | print("End drawing, swap buffers") 46 | vita2d.end_drawing() 47 | vita2d.swap_buffers() 48 | 49 | if hook then 50 | abort, res = hook(options[selected], old_pad, pad) 51 | if abort then 52 | return res, selected, abort 53 | end 54 | end 55 | 56 | if old_pad:up() and not pad:up() and selected > 1 then 57 | selected = selected - 1 58 | if options[selected] == nil then 59 | selected = selected - 1 60 | end 61 | elseif old_pad:down() and not pad:down() and selected < #options then 62 | selected = selected + 1 63 | if options[selected] == nil then 64 | selected = selected + 1 65 | end 66 | elseif old_pad:cross() and not pad:cross() then 67 | return options[selected], selected, false 68 | elseif old_pad:circle() and not pad:circle() then 69 | return nil, selected, false 70 | end 71 | 72 | old_pad = pad 73 | end 74 | end 75 | 76 | function ui.error(title, message, font) 77 | local title = " " .. (title or "") .. " " 78 | local font_to_use = font_custom or font or vita2d.load_font() 79 | 80 | -- Fixed variables. 81 | local vita_w = 960 82 | local vita_h = 544 83 | local half_w = vita_w/2 84 | local half_h = vita_h/2 85 | local maxlength = 64 86 | 87 | -- Math! Yay! 88 | local errorthing_w, errorthing_h = font_to_use:text_size(30, "/!\\") 89 | local titlewidth_w, titlewidth_h = font_to_use:text_size(30, title) 90 | 91 | local first_error_w = half_w - titlewidth_w/2 - errorthing_w 92 | local text_w = half_w - titlewidth_w/2 93 | local second_error_w = half_w + titlewidth_w/2 94 | 95 | local old_pad = input.peek() 96 | 97 | local messagearray = {} 98 | 99 | if not string.find(message, "\n$") then 100 | message = message .. "\n" 101 | end 102 | string.gsub(message, "(.-)\r?\n", function(line) 103 | for s in line:gmatch((".?"):rep(maxlength)) do 104 | if s then 105 | table.insert(messagearray, s) 106 | end 107 | end 108 | end) 109 | if #messagearray == 0 then 110 | for s in message:gmatch((".?"):rep(maxlength)) do 111 | if s then 112 | table.insert(messagearray, s) 113 | end 114 | end 115 | end 116 | 117 | while true do 118 | local pad = input.peek() 119 | 120 | vita2d.start_drawing() 121 | vita2d.clear_screen() 122 | 123 | font_to_use:draw_text(first_error_w, 0, colors.red, 30, "/!\\") 124 | font_to_use:draw_text(text_w, 0, colors.white, 30, title) 125 | font_to_use:draw_text(second_error_w, 0, colors.red, 30, "/!\\") 126 | 127 | for l, c in pairs(messagearray) do 128 | font_to_use:draw_text(0, l * 30, colors.white, 30, c) 129 | end 130 | 131 | vita2d.end_drawing() 132 | vita2d.swap_buffers() 133 | 134 | if old_pad:cross() and not pad:cross() then 135 | return true 136 | elseif old_pad:circle() and not pad:circle() then 137 | return false 138 | end 139 | 140 | old_pad = pad 141 | end 142 | end 143 | 144 | function ui.pager(text, title, displaylinenos, line, selectedcolor, normalcolor, font_custom) 145 | local text = text or "" 146 | local displaylinenos = displaylinenos or false 147 | local font_to_use = font_custom or font or vita2d.load_font() 148 | local selectedcolor = selectedcolor or colors.red 149 | local normalcolor = normalcolor or colors.blue 150 | 151 | local old_pad = input.peek() 152 | 153 | local line = line or 1 154 | 155 | local num = 18 156 | if title then 157 | num = 17 158 | end 159 | 160 | local lines = {} 161 | if type(text) == "string" then 162 | if not string.find(text, "\n$") then 163 | text = text.."\n" 164 | end 165 | local tmp_lines = string.lines(text) 166 | local count = #tmp_lines 167 | local numwidth = #(tostring(count)) 168 | 169 | local maxlength = 62 - numwidth 170 | 171 | for n, line in pairs(tmp_lines) do 172 | local i = 0 173 | for s in line:gmatch((".?"):rep(maxlength)) do 174 | i = i + 1 175 | if displaylinenos then 176 | if i == 1 then 177 | local padded = string.rpad(tostring(n), numwidth) 178 | table.insert(lines, padded.."| ".. s) 179 | else 180 | if s and s ~= "" then 181 | table.insert(lines, string.rep(" ", numwidth).."| ".. s) 182 | end 183 | end 184 | else 185 | table.insert(lines, s) 186 | end 187 | end 188 | end 189 | elseif type(text) == "table" then 190 | lines = text 191 | end 192 | 193 | while true do 194 | local pad = input.peek() 195 | vita2d.start_drawing() 196 | vita2d.clear_screen() 197 | 198 | local p = 0 199 | 200 | local min = (line <= num and 1 or line - num + 1) 201 | local max = math.min(#lines, (line <= num and num or line)) 202 | 203 | if title then 204 | font_to_use:draw_text(0, 0, colors.purple, 30, title) 205 | p = 1 206 | end 207 | for i=min, max do 208 | font_to_use:draw_text(0, p * 30, i == line and selectedcolor or normalcolor, 30, lines[i]) 209 | p = p + 1 210 | end 211 | 212 | vita2d.end_drawing() 213 | vita2d.swap_buffers() 214 | 215 | if old_pad:up() and not pad:up() and line > 1 then 216 | line = line - 1 217 | elseif old_pad:down() and not pad:down() and line < #lines then 218 | line = line + 1 219 | elseif old_pad:cross() and not pad:cross() then 220 | return 221 | elseif old_pad:circle() and not pad:circle() then 222 | return 223 | end 224 | 225 | old_pad = pad 226 | end 227 | end 228 | 229 | function ui.view_image(tex, font_custom) 230 | local font_to_use = font_custom or font or vita2d.load_font() 231 | 232 | local old_pad = input.peek() 233 | local white = false 234 | 235 | local ratio = math.min(960 / tex:width(), 544 / tex:height()) 236 | 237 | while true do 238 | local pad = input.peek() 239 | vita2d.start_drawing() 240 | vita2d.clear_screen() 241 | tex:draw_scale((960 - tex:width()*ratio)/2 , (540 - tex:height()*ratio)/2, ratio, ratio) 242 | font_to_use:draw_text(0, 0, white and colors.black or colors.white, 30, tostring(tex:width()) .. "x" .. tostring(tex:height())) 243 | vita2d.end_drawing() 244 | vita2d.swap_buffers() 245 | 246 | if old_pad:circle() and not pad:circle() then break end 247 | if old_pad:cross() and not pad:cross() then break end 248 | 249 | if old_pad:triangle() and not pad:triangle() then 250 | white = not white 251 | vita2d.set_clear_color(white and colors.white or colors.black) 252 | end 253 | 254 | old_pad = pad 255 | end 256 | vita2d.set_clear_color(colors.black) 257 | end 258 | 259 | function ui.choose_file(startdir, title, selected, hook) 260 | print("ui.choose_file") 261 | local old_dir 262 | 263 | local startdir = string.gsub(startdir or "/", "/$", "") 264 | local path = {""} 265 | if startdir then 266 | for p in startdir:gmatch("[^/]+") do 267 | table.insert(path, p) 268 | end 269 | end 270 | while true do 271 | print("Getting list of files") 272 | local t = vfs.list(table.concat(path, "/") .. "/") 273 | if not string.find(table.concat(path, "/") .. "/", "^/$") then 274 | table.insert(t, 1, "..") 275 | end 276 | 277 | -- hack! 278 | if old_dir then 279 | selected = table.find(t, old_dir) 280 | old_dir = nil 281 | end 282 | 283 | res, selected, abort = ui.choose(t, title or table.concat(path, "/").."/", selected, function(res, old_pad, pad) 284 | print("file_chooser hook") 285 | if hook then 286 | return hook(res or "", old_pad, pad, table.concat(path, "/") .. ((res and "/" .. res) or "")), selected 287 | end 288 | end) 289 | if abort then 290 | return res, table.concat(path, "/"), selected 291 | end 292 | if res == ".." or res == nil then 293 | if #path > 1 then 294 | old_dir = table.remove(path) 295 | end 296 | else 297 | if vfs.isdir(table.concat(path, "/") .. "/" .. res) then 298 | table.insert(path, res) 299 | selected = 1 300 | else 301 | return (table.concat(path, "/") .. "/" .. res), table.concat(path, "/"), selected 302 | end 303 | end 304 | end 305 | end 306 | -------------------------------------------------------------------------------- /lua/ltn12.lua: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------------- 2 | -- LTN12 - Filters, sources, sinks and pumps. 3 | -- LuaSocket toolkit. 4 | -- Author: Diego Nehab 5 | ----------------------------------------------------------------------------- 6 | 7 | ----------------------------------------------------------------------------- 8 | -- Declare module 9 | ----------------------------------------------------------------------------- 10 | local string = require("string") 11 | local table = require("table") 12 | local unpack = unpack or table.unpack 13 | local base = _G 14 | local _M = {} 15 | if module then -- heuristic for exporting a global package table 16 | ltn12 = _M 17 | end 18 | local filter,source,sink,pump = {},{},{},{} 19 | 20 | _M.filter = filter 21 | _M.source = source 22 | _M.sink = sink 23 | _M.pump = pump 24 | 25 | local unpack = unpack or table.unpack 26 | local select = base.select 27 | 28 | -- 2048 seems to be better in windows... 29 | _M.BLOCKSIZE = 2048 30 | _M._VERSION = "LTN12 1.0.3" 31 | 32 | ----------------------------------------------------------------------------- 33 | -- Filter stuff 34 | ----------------------------------------------------------------------------- 35 | -- returns a high level filter that cycles a low-level filter 36 | function filter.cycle(low, ctx, extra) 37 | base.assert(low) 38 | return function(chunk) 39 | local ret 40 | ret, ctx = low(ctx, chunk, extra) 41 | return ret 42 | end 43 | end 44 | 45 | -- chains a bunch of filters together 46 | -- (thanks to Wim Couwenberg) 47 | function filter.chain(...) 48 | local arg = {...} 49 | local n = base.select('#',...) 50 | local top, index = 1, 1 51 | local retry = "" 52 | return function(chunk) 53 | retry = chunk and retry 54 | while true do 55 | if index == top then 56 | chunk = arg[index](chunk) 57 | if chunk == "" or top == n then return chunk 58 | elseif chunk then index = index + 1 59 | else 60 | top = top+1 61 | index = top 62 | end 63 | else 64 | chunk = arg[index](chunk or "") 65 | if chunk == "" then 66 | index = index - 1 67 | chunk = retry 68 | elseif chunk then 69 | if index == n then return chunk 70 | else index = index + 1 end 71 | else base.error("filter returned inappropriate nil") end 72 | end 73 | end 74 | end 75 | end 76 | 77 | ----------------------------------------------------------------------------- 78 | -- Source stuff 79 | ----------------------------------------------------------------------------- 80 | -- create an empty source 81 | local function empty() 82 | return nil 83 | end 84 | 85 | function source.empty() 86 | return empty 87 | end 88 | 89 | -- returns a source that just outputs an error 90 | function source.error(err) 91 | return function() 92 | return nil, err 93 | end 94 | end 95 | 96 | -- creates a file source 97 | function source.file(handle, io_err) 98 | if handle then 99 | return function() 100 | local chunk = handle:read(_M.BLOCKSIZE) 101 | if not chunk then handle:close() end 102 | return chunk 103 | end 104 | else return source.error(io_err or "unable to open file") end 105 | end 106 | 107 | -- turns a fancy source into a simple source 108 | function source.simplify(src) 109 | base.assert(src) 110 | return function() 111 | local chunk, err_or_new = src() 112 | src = err_or_new or src 113 | if not chunk then return nil, err_or_new 114 | else return chunk end 115 | end 116 | end 117 | 118 | -- creates string source 119 | function source.string(s) 120 | if s then 121 | local i = 1 122 | return function() 123 | local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1) 124 | i = i + _M.BLOCKSIZE 125 | if chunk ~= "" then return chunk 126 | else return nil end 127 | end 128 | else return source.empty() end 129 | end 130 | 131 | -- creates rewindable source 132 | function source.rewind(src) 133 | base.assert(src) 134 | local t = {} 135 | return function(chunk) 136 | if not chunk then 137 | chunk = table.remove(t) 138 | if not chunk then return src() 139 | else return chunk end 140 | else 141 | table.insert(t, chunk) 142 | end 143 | end 144 | end 145 | 146 | -- chains a source with one or several filter(s) 147 | function source.chain(src, f, ...) 148 | if ... then f=filter.chain(f, ...) end 149 | base.assert(src and f) 150 | local last_in, last_out = "", "" 151 | local state = "feeding" 152 | local err 153 | return function() 154 | if not last_out then 155 | base.error('source is empty!', 2) 156 | end 157 | while true do 158 | if state == "feeding" then 159 | last_in, err = src() 160 | if err then return nil, err end 161 | last_out = f(last_in) 162 | if not last_out then 163 | if last_in then 164 | base.error('filter returned inappropriate nil') 165 | else 166 | return nil 167 | end 168 | elseif last_out ~= "" then 169 | state = "eating" 170 | if last_in then last_in = "" end 171 | return last_out 172 | end 173 | else 174 | last_out = f(last_in) 175 | if last_out == "" then 176 | if last_in == "" then 177 | state = "feeding" 178 | else 179 | base.error('filter returned ""') 180 | end 181 | elseif not last_out then 182 | if last_in then 183 | base.error('filter returned inappropriate nil') 184 | else 185 | return nil 186 | end 187 | else 188 | return last_out 189 | end 190 | end 191 | end 192 | end 193 | end 194 | 195 | -- creates a source that produces contents of several sources, one after the 196 | -- other, as if they were concatenated 197 | -- (thanks to Wim Couwenberg) 198 | function source.cat(...) 199 | local arg = {...} 200 | local src = table.remove(arg, 1) 201 | return function() 202 | while src do 203 | local chunk, err = src() 204 | if chunk then return chunk end 205 | if err then return nil, err end 206 | src = table.remove(arg, 1) 207 | end 208 | end 209 | end 210 | 211 | ----------------------------------------------------------------------------- 212 | -- Sink stuff 213 | ----------------------------------------------------------------------------- 214 | -- creates a sink that stores into a table 215 | function sink.table(t) 216 | t = t or {} 217 | local f = function(chunk, err) 218 | if chunk then table.insert(t, chunk) end 219 | return 1 220 | end 221 | return f, t 222 | end 223 | 224 | -- turns a fancy sink into a simple sink 225 | function sink.simplify(snk) 226 | base.assert(snk) 227 | return function(chunk, err) 228 | local ret, err_or_new = snk(chunk, err) 229 | if not ret then return nil, err_or_new end 230 | snk = err_or_new or snk 231 | return 1 232 | end 233 | end 234 | 235 | -- creates a file sink 236 | function sink.file(handle, io_err) 237 | if handle then 238 | return function(chunk, err) 239 | if not chunk then 240 | handle:close() 241 | return 1 242 | else return handle:write(chunk) end 243 | end 244 | else return sink.error(io_err or "unable to open file") end 245 | end 246 | 247 | -- creates a sink that discards data 248 | local function null() 249 | return 1 250 | end 251 | 252 | function sink.null() 253 | return null 254 | end 255 | 256 | -- creates a sink that just returns an error 257 | function sink.error(err) 258 | return function() 259 | return nil, err 260 | end 261 | end 262 | 263 | -- chains a sink with one or several filter(s) 264 | function sink.chain(f, snk, ...) 265 | if ... then 266 | local args = { f, snk, ... } 267 | snk = table.remove(args, #args) 268 | f = filter.chain(unpack(args)) 269 | end 270 | base.assert(f and snk) 271 | return function(chunk, err) 272 | if chunk ~= "" then 273 | local filtered = f(chunk) 274 | local done = chunk and "" 275 | while true do 276 | local ret, snkerr = snk(filtered, err) 277 | if not ret then return nil, snkerr end 278 | if filtered == done then return 1 end 279 | filtered = f(done) 280 | end 281 | else return 1 end 282 | end 283 | end 284 | 285 | ----------------------------------------------------------------------------- 286 | -- Pump stuff 287 | ----------------------------------------------------------------------------- 288 | -- pumps one chunk from the source to the sink 289 | function pump.step(src, snk) 290 | local chunk, src_err = src() 291 | local ret, snk_err = snk(chunk, src_err) 292 | if chunk and ret then return 1 293 | else return nil, src_err or snk_err end 294 | end 295 | 296 | -- pumps all data from a source to a sink, using a step function 297 | function pump.all(src, snk, step) 298 | base.assert(src and snk) 299 | step = step or pump.step 300 | while true do 301 | local ret, err = step(src, snk) 302 | if not ret then 303 | if err then return nil, err 304 | else return 1 end 305 | end 306 | end 307 | end 308 | 309 | return _M 310 | -------------------------------------------------------------------------------- /src/vitafm/src/vitafm_base.lua: -------------------------------------------------------------------------------- 1 | -- vitafm 2 | -- Loads up ui.choose_file and applies magic. 3 | local fsroot = "app0:" 4 | local dir = "/" 5 | local binpath = "/bin" 6 | local confpath = "/vitafm.conf" 7 | 8 | vitafm = {} 9 | 10 | -- Helpers 11 | local function file_extension(path) 12 | return tostring(path):match("^.+(%..+)$") 13 | end 14 | 15 | -- Config parser. Something like TOML and INI. 16 | local function config_parse(file) 17 | local c = {} 18 | local subsect 19 | 20 | if vfs.exists(file) then 21 | local data = assert(vfs.read(file)) 22 | for n, line in pairs(string.lines(data)) do 23 | local s = line:match("^%[([^%]]+)%]$") 24 | if s then 25 | subsect = s 26 | c[s] = c[s] or {} 27 | else 28 | local t = subsect and c[subsect] or c 29 | local k, v = line:match("^(.-)%s-=%s-(.+)$") 30 | if k and v then 31 | local nv = tonumber(v) 32 | if v == "true" then 33 | t[k] = true 34 | elseif v == "false" then 35 | t[k] = false 36 | elseif nv ~= nil then 37 | t[k] = nv 38 | else 39 | t[k] = v 40 | end 41 | elseif line ~= "" then 42 | table.insert(t, line) 43 | end 44 | end 45 | end 46 | return c 47 | else 48 | return nil 49 | end 50 | end 51 | 52 | -- Actual vitafm.programs 53 | function vitafm.lua(file) 54 | print("Lua file: ".. file) 55 | if vfs.exists(file) then 56 | local data = assert(vfs.read(file)) 57 | local fn, err = loadstring(data) 58 | if err ~= nil then 59 | print("File manager: Lua syntax error: "..tostring(err)) 60 | --ui.error("lua: Syntax Error", "Error:\n" .. tostring(err)) 61 | error(tostring(err), 0) 62 | return 63 | end 64 | local success, err = pcall(fn) 65 | if not success then 66 | print("File manager: Lua script error: "..tostring(err)) 67 | --ui.error("lua: Script Error", "Error:\n" .. tostring(err)) 68 | error(tostring(err), 0) 69 | return 70 | end 71 | else 72 | --ui.error("lua: Couldn't open File", "Error:\nFile ''" .. file .. "' could not be opened.") 73 | error("File ''" .. file .. "' could not be opened.") 74 | end 75 | end 76 | 77 | -- Types 78 | vitafm.types = { 79 | [".lua"] = "lua %f", 80 | ["*"] = "ask %f %e" 81 | } 82 | 83 | -- "Program" Registration. 84 | vitafm.programs = { 85 | ["lua"] = vitafm.lua 86 | } 87 | 88 | -- Aliases 89 | vitafm.aliases = {} 90 | 91 | function vitafm.add_programs(path) 92 | local dir = vfs.list(path) 93 | if not dir then return end 94 | for k, v in pairs(dir) do 95 | if v:find("%.lua$") then 96 | local filepath = path.."/"..v 97 | if vfs.exists(filepath) then 98 | local data = assert(vfs.read(filepath)) 99 | local fn, err = loadstring(data) 100 | if err ~= nil then 101 | print("File manager: Lua plugin load error: "..tostring(err)) 102 | else 103 | vitafm.programs[v:gsub("%.lua$", "")] = fn 104 | end 105 | end 106 | elseif v:find("%.vsh$") then 107 | local filepath = path.."/"..v 108 | if vfs.exists(filepath) then 109 | local data = assert(vfs.read(filepath)) 110 | local succ, err = vitafm.parse_commands(data, {}, true) 111 | if not succ then 112 | print("File manager: vsh script syntax error: "..tostring(err)) 113 | else 114 | vitafm.programs[v:gsub("%.vsh$", "")] = data 115 | end 116 | end 117 | end 118 | end 119 | end 120 | 121 | function vitafm.exec(prog, ...) 122 | local f = vitafm.programs[prog] 123 | if type(f) == "function" then 124 | f(...) 125 | elseif type(f) == "string" then 126 | vitafm.run_command(f, {}, {...}) 127 | elseif f == nil then 128 | error("No such program.") 129 | else 130 | error("No such program: "..prog) 131 | end 132 | end 133 | function vitafm.exec_vars(prog, vars, ...) 134 | local f = vitafm.programs[prog] 135 | if type(f) == "function" then 136 | f(...) 137 | elseif type(f) == "string" then 138 | vitafm.run_command(f, vars, {...}) 139 | elseif f == nil then 140 | error("No such program.") 141 | else 142 | error("No such program: "..prog) 143 | end 144 | end 145 | 146 | -- The tokenizer/backtick parser 147 | function vitafm.parse_commands(command, vars, dryparse) 148 | local dryparse = dryparse or false 149 | local res = {} 150 | local spat, epat, buf, quoted = [=[^(['"`])]=], [=[(['"`])$]=] 151 | local vars = vars or {} 152 | local pipeno = 1 153 | for str in command:gmatch("%S+") do 154 | res[pipeno] = res[pipeno] or {} 155 | local squoted = str:match(spat) 156 | local equoted = str:match(epat) 157 | local escaped = str:match([=[(\*)['"`]$]=]) 158 | if squoted and not quoted and not equoted then 159 | buf, quoted = str, squoted 160 | elseif buf and equoted == quoted and #escaped % 2 == 0 then 161 | str, buf, quoted = buf .. ' ' .. str, nil, nil 162 | elseif buf then 163 | buf = buf .. ' ' .. str 164 | end 165 | if not buf then 166 | if dryparse then 167 | table.insert(res[pipeno], str:gsub(spat,""):gsub(epat,"")) 168 | else 169 | if quoted == "`" then 170 | table.insert(res[pipeno], vitafm.run_shell(str:gsub(spat,""):gsub(epat,""), vars)) 171 | elseif str == "|" then 172 | pipeno = pipeno + 1 173 | else 174 | local v = str:gsub(spat,""):gsub(epat,"") 175 | local val 176 | local nv = tonumber(val) 177 | if v == "true" then 178 | val = true 179 | elseif v == "false" then 180 | val = false 181 | elseif nv ~= nil then 182 | val = nv 183 | else 184 | local tmp = v 185 | for varname, replacement in pairs(vars) do 186 | --tmp = tmp:gsub(varname:gsub("%%", "%%%1"), replacement) 187 | tmp = tmp:gsub(varname, replacement) 188 | end 189 | val = tmp 190 | end 191 | table.insert(res[pipeno], val) 192 | end 193 | end 194 | end 195 | end 196 | if buf then 197 | return false, "Missing matching quote for "..buf 198 | end 199 | return true, res 200 | end 201 | 202 | function vitafm.escape_args(command) 203 | local res = "" 204 | for k, v in pairs(command) do 205 | if type(v) == "string" then 206 | res = res + "'" + v:gsub("\\", "\\\\"):gsub("'", "\\'") + "'" + " " 207 | elseif type(v) == "number" then 208 | res = res + tostring(v) + " " 209 | elseif v == true or v == false then 210 | res = res + tostring(v) + " " 211 | end 212 | end 213 | return string.strip(res) 214 | end 215 | 216 | function vitafm.run_command(command, vars, appendedargs) 217 | local vars = vars or {} 218 | local succ, pipes = vitafm.parse_commands(command, vars) 219 | if not succ then 220 | ui.error("Command Parser Error", "Error:\n" .. split) 221 | return 222 | end 223 | local res 224 | local pipelen = #pipes 225 | for no, cmd in pairs(pipes) do 226 | if no == pipelen then 227 | if appendedargs then 228 | for k, v in pairs(appendedargs) do 229 | table.insert(cmd, v) 230 | end 231 | end 232 | else 233 | if res ~= nil then 234 | table.insert(cmd, res) 235 | res = nil 236 | end 237 | end 238 | local prog = cmd[1] 239 | table.remove(cmd, 1) 240 | 241 | if vitafm.programs[prog] then 242 | local succ, ret = pcall(vitafm.exec_vars, prog, vars, unpack(cmd)) 243 | if not succ then 244 | print("Program "..prog.." errored: "..ret) 245 | ui.error("Error in program "..prog, ret) 246 | else 247 | res = ret 248 | end 249 | elseif vitafm.aliases[prog] then 250 | res = vitafm.run_shell(vitafm.aliases[prog], vars, cmd) 251 | else 252 | error("No such program.") 253 | end 254 | if no == pipelen then 255 | return res 256 | end 257 | end 258 | end 259 | function vitafm.run_shell(code, vars, appendedargs) 260 | local res 261 | if code then 262 | local lines = string.lines(code) 263 | local len = #lines 264 | for k, line in pairs(lines) do 265 | if k == len then 266 | res = vitafm.run_command(line, vars, appendedargs) 267 | else 268 | vitafm.run_command(line, vars) 269 | end 270 | end 271 | end 272 | end 273 | 274 | -- Handy aliases. 275 | vitafm.sh = vitafm.run_shell 276 | sh = vitafm.run_shell 277 | 278 | local function call_prog(command, file, ext) 279 | return vitafm.run_shell(command, { 280 | ["%%f"] = file, 281 | ["%%F"] = fsroot..file, 282 | ["%%e"] = ext 283 | }) 284 | end 285 | 286 | -- Ask for program to launch it with. 287 | function vitafm.ask(file, ext) 288 | if not string.find(file or "", "^/") then 289 | return 290 | end 291 | local ext = ext or file_extension(file) 292 | local keys = {} 293 | local i = 0 294 | local sel = 1 295 | for k, v in pairs(vitafm.types) do 296 | if k ~= "*" then 297 | i = i + 1 298 | if k == ext then 299 | sel = i 300 | end 301 | table.insert(keys, k .. " - " .. v) 302 | end 303 | end 304 | local l = #keys 305 | keys[l+1] = nil 306 | keys[l+2] = "Open with..." 307 | keys[l+3] = "Back" 308 | while true do 309 | opt = ui.choose(keys, "Launch as... (Extension: ".. (ext or "none") .. ")", sel) 310 | if opt then 311 | res = opt:gsub(" - .-$", "") 312 | if opt == "Back" then 313 | return 314 | elseif opt == "Open with..." then 315 | prog = ui.choose(table.keys(vitafm.programs), "Open with...") 316 | if prog then 317 | return call_prog(prog.." %f", file) 318 | end 319 | return 320 | elseif vitafm.types[res] then 321 | return call_prog(vitafm.types[res], file, res) 322 | end 323 | else 324 | return 325 | end 326 | end 327 | end 328 | vitafm.programs["ask"] = vitafm.ask 329 | 330 | -- Parse Config 331 | function vitafm.parse_config(path) 332 | print("Looking for config...") 333 | if vfs.exists(path) then 334 | print("Loading config...") 335 | local conf = config_parse(path) 336 | if type(conf.filetypes) == "table" then 337 | for k, v in pairs(conf.filetypes) do 338 | vitafm.types[k] = v 339 | end 340 | end 341 | if type(conf.aliases) == "table" then 342 | vitafm.aliases = conf.aliases 343 | end 344 | print("Loaded config.") 345 | else 346 | print("Not found.") 347 | end 348 | end 349 | 350 | local pad = input.peek() 351 | if not (pad:l_trigger() or pad:r_trigger()) then 352 | vitafm.parse_config(confpath) 353 | end 354 | 355 | -- Main loop. 356 | function vitafm.run() 357 | print("vitafm.run()") 358 | local selected 359 | while true do 360 | if vfs.isdir(binpath) then 361 | vitafm.add_programs(binpath) 362 | end 363 | print("vitafm: added programs") 364 | file, dir, selected = ui.choose_file(dir, nil, selected, (function(sel, old_pad, pad, path) 365 | print("hook") 366 | if old_pad:triangle() and not pad:triangle() then -- "Open as" menu 367 | vitafm.programs["ask"](path, file_extension(path)) 368 | return true, nil 369 | elseif old_pad:square() and not pad:square() then -- Tool menu 370 | local title = "VitaFM Menu" 371 | local menuitems = { 372 | "Run Program", 373 | nil, 374 | "Reload Config", 375 | "Exit VitaFM", 376 | "Back" 377 | } 378 | res = ui.choose(menuitems, title) 379 | if res == "Run Program" then 380 | prog = ui.choose(table.keys(vitafm.programs), "Open Program...") 381 | if prog then 382 | local succ, ret = pcall(vitafm.exec, prog) 383 | if not succ then 384 | print("Program "..prog.." errored: "..ret) 385 | ui.error("Error in program "..prog, ret) 386 | else 387 | return ret 388 | end 389 | end 390 | elseif res == "Reload Config" then 391 | vitafm.parse_config(confpath) 392 | elseif res == "Exit VitaFM" then 393 | uvl.exit(0) 394 | end 395 | return true, nil 396 | end 397 | end)) 398 | if file ~= nil then 399 | local ext = file_extension(file) 400 | if vitafm.types[ext] then 401 | call_prog(vitafm.types[ext], file, ext) 402 | elseif vitafm.types["*"] then 403 | call_prog(vitafm.types["*"], file, ext) 404 | end 405 | end 406 | end 407 | end 408 | -------------------------------------------------------------------------------- /lua/vita2d.lua: -------------------------------------------------------------------------------- 1 | -- vita2d 2 | local ffi = require 'ffi' 3 | 4 | ffi.cdef [[ 5 | 6 | typedef enum SceGxmTextureSwizzle4Mode { 7 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR = 0x00000000u, 8 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB = 0x00001000u, 9 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA = 0x00002000u, 10 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA = 0x00003000u, 11 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR = 0x00004000u, 12 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB = 0x00005000u, 13 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1 = 0x00006000u, 14 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1 = 0x00007000u 15 | } SceGxmTextureSwizzle4Mode; 16 | 17 | typedef enum SceGxmTextureSwizzle3Mode { 18 | SCE_GXM_TEXTURE_SWIZZLE3_BGR = 0x00000000u, 19 | SCE_GXM_TEXTURE_SWIZZLE3_RGB = 0x00001000u 20 | } SceGxmTextureSwizzle3Mode; 21 | 22 | typedef enum SceGxmTextureSwizzle2Mode { 23 | SCE_GXM_TEXTURE_SWIZZLE2_GR = 0x00000000u, 24 | SCE_GXM_TEXTURE_SWIZZLE2_00GR = 0x00001000u, 25 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR = 0x00002000u, 26 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG = 0x00003000u, 27 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR = 0x00004000u, 28 | SCE_GXM_TEXTURE_SWIZZLE2_00RG = 0x00005000u 29 | } SceGxmTextureSwizzle2Mode; 30 | 31 | typedef enum SceGxmTextureSwizzle2ModeAlt { 32 | SCE_GXM_TEXTURE_SWIZZLE2_SD = 0x00000000u, 33 | SCE_GXM_TEXTURE_SWIZZLE2_DS = 0x00001000u 34 | } SceGxmTextureSwizzle2ModeAlt; 35 | 36 | typedef enum SceGxmTextureSwizzle1Mode { 37 | SCE_GXM_TEXTURE_SWIZZLE1_R = 0x00000000u, 38 | SCE_GXM_TEXTURE_SWIZZLE1_000R = 0x00001000u, 39 | SCE_GXM_TEXTURE_SWIZZLE1_111R = 0x00002000u, 40 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR = 0x00003000u, 41 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR = 0x00004000u, 42 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR = 0x00005000u, 43 | SCE_GXM_TEXTURE_SWIZZLE1_R000 = 0x00006000u, 44 | SCE_GXM_TEXTURE_SWIZZLE1_R111 = 0x00007000u 45 | } SceGxmTextureSwizzle1Mode; 46 | 47 | typedef enum SceGxmTextureSwizzleYUV422Mode { 48 | SCE_GXM_TEXTURE_SWIZZLE_YUYV_CSC0 = 0x00000000u, 49 | SCE_GXM_TEXTURE_SWIZZLE_YVYU_CSC0 = 0x00001000u, 50 | SCE_GXM_TEXTURE_SWIZZLE_UYVY_CSC0 = 0x00002000u, 51 | SCE_GXM_TEXTURE_SWIZZLE_VYUY_CSC0 = 0x00003000u, 52 | SCE_GXM_TEXTURE_SWIZZLE_YUYV_CSC1 = 0x00004000u, 53 | SCE_GXM_TEXTURE_SWIZZLE_YVYU_CSC1 = 0x00005000u, 54 | SCE_GXM_TEXTURE_SWIZZLE_UYVY_CSC1 = 0x00006000u, 55 | SCE_GXM_TEXTURE_SWIZZLE_VYUY_CSC1 = 0x00007000u 56 | } SceGxmTextureSwizzleYUV422Mode; 57 | 58 | typedef enum SceGxmTextureSwizzleYUV420Mode { 59 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC0 = 0x00000000u, 60 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC0 = 0x00001000u, 61 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC1 = 0x00002000u, 62 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC1 = 0x00003000u 63 | } SceGxmTextureSwizzleYUV420Mode; 64 | 65 | typedef enum SceGxmTextureBaseFormat { 66 | SCE_GXM_TEXTURE_BASE_FORMAT_U8 = 0x00000000, 67 | SCE_GXM_TEXTURE_BASE_FORMAT_S8 = 0x01000000, 68 | SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 = 0x02000000, 69 | SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2 = 0x03000000, 70 | SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 = 0x04000000, 71 | SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5 = 0x05000000, 72 | SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6 = 0x06000000, 73 | SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 = 0x07000000, 74 | SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 = 0x08000000, 75 | SCE_GXM_TEXTURE_BASE_FORMAT_U16 = 0x09000000, 76 | SCE_GXM_TEXTURE_BASE_FORMAT_S16 = 0x0a000000, 77 | SCE_GXM_TEXTURE_BASE_FORMAT_F16 = 0x0b000000, 78 | SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 = 0x0c000000, 79 | SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 = 0x0d000000, 80 | SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 = 0x0e000000, 81 | SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 = 0x0f000000, 82 | SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 = 0x10000000, 83 | SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 = 0x11000000, 84 | SCE_GXM_TEXTURE_BASE_FORMAT_F32 = 0x12000000, 85 | SCE_GXM_TEXTURE_BASE_FORMAT_F32M = 0x13000000, 86 | SCE_GXM_TEXTURE_BASE_FORMAT_X8S8S8U8 = 0x14000000, 87 | SCE_GXM_TEXTURE_BASE_FORMAT_X8U24 = 0x15000000, 88 | SCE_GXM_TEXTURE_BASE_FORMAT_U32 = 0x17000000, 89 | SCE_GXM_TEXTURE_BASE_FORMAT_S32 = 0x18000000, 90 | SCE_GXM_TEXTURE_BASE_FORMAT_SE5M9M9M9 = 0x19000000, 91 | SCE_GXM_TEXTURE_BASE_FORMAT_F11F11F10 = 0x1a000000, 92 | SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 = 0x1b000000, 93 | SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 = 0x1c000000, 94 | SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 = 0x1d000000, 95 | SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 = 0x1e000000, 96 | SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 = 0x1f000000, 97 | SCE_GXM_TEXTURE_BASE_FORMAT_PVRT2BPP = 0x80000000, 98 | SCE_GXM_TEXTURE_BASE_FORMAT_PVRT4BPP = 0x81000000, 99 | SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII2BPP = 0x82000000, 100 | SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII4BPP = 0x83000000, 101 | SCE_GXM_TEXTURE_BASE_FORMAT_UBC1 = 0x85000000, 102 | SCE_GXM_TEXTURE_BASE_FORMAT_UBC2 = 0x86000000, 103 | SCE_GXM_TEXTURE_BASE_FORMAT_UBC3 = 0x87000000, 104 | SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2 = 0x90000000, 105 | SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 = 0x91000000, 106 | SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 = 0x92000000, 107 | SCE_GXM_TEXTURE_BASE_FORMAT_P4 = 0x94000000, 108 | SCE_GXM_TEXTURE_BASE_FORMAT_P8 = 0x95000000, 109 | SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8 = 0x98000000, 110 | SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8 = 0x99000000, 111 | SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 = 0x9a000000 112 | } SceGxmTextureBaseFormat; 113 | 114 | typedef enum SceGxmTextureFormat { 115 | // Supported formats 116 | SCE_GXM_TEXTURE_FORMAT_U8_000R = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 117 | SCE_GXM_TEXTURE_FORMAT_U8_111R = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 118 | SCE_GXM_TEXTURE_FORMAT_U8_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 119 | SCE_GXM_TEXTURE_FORMAT_U8_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 120 | SCE_GXM_TEXTURE_FORMAT_U8_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 121 | SCE_GXM_TEXTURE_FORMAT_U8_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 122 | SCE_GXM_TEXTURE_FORMAT_U8_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 123 | SCE_GXM_TEXTURE_FORMAT_U8_R = SCE_GXM_TEXTURE_BASE_FORMAT_U8 | SCE_GXM_TEXTURE_SWIZZLE1_R, 124 | 125 | SCE_GXM_TEXTURE_FORMAT_S8_000R = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 126 | SCE_GXM_TEXTURE_FORMAT_S8_111R = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 127 | SCE_GXM_TEXTURE_FORMAT_S8_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 128 | SCE_GXM_TEXTURE_FORMAT_S8_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 129 | SCE_GXM_TEXTURE_FORMAT_S8_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 130 | SCE_GXM_TEXTURE_FORMAT_S8_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 131 | SCE_GXM_TEXTURE_FORMAT_S8_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 132 | SCE_GXM_TEXTURE_FORMAT_S8_R = SCE_GXM_TEXTURE_BASE_FORMAT_S8 | SCE_GXM_TEXTURE_SWIZZLE1_R, 133 | 134 | SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 135 | SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 136 | SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 137 | SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 138 | SCE_GXM_TEXTURE_FORMAT_X4U4U4U4_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 139 | SCE_GXM_TEXTURE_FORMAT_X4U4U4U4_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 140 | SCE_GXM_TEXTURE_FORMAT_U4U4U4X4_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 141 | SCE_GXM_TEXTURE_FORMAT_U4U4U4X4_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 142 | 143 | SCE_GXM_TEXTURE_FORMAT_U8U3U3U2_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2, 144 | 145 | SCE_GXM_TEXTURE_FORMAT_U1U5U5U5_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 146 | SCE_GXM_TEXTURE_FORMAT_U1U5U5U5_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 147 | SCE_GXM_TEXTURE_FORMAT_U5U5U5U1_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 148 | SCE_GXM_TEXTURE_FORMAT_U5U5U5U1_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 149 | SCE_GXM_TEXTURE_FORMAT_X1U5U5U5_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 150 | SCE_GXM_TEXTURE_FORMAT_X1U5U5U5_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 151 | SCE_GXM_TEXTURE_FORMAT_U5U5U5X1_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 152 | SCE_GXM_TEXTURE_FORMAT_U5U5U5X1_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 153 | 154 | SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 155 | SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 156 | 157 | SCE_GXM_TEXTURE_FORMAT_U6S5S5_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 158 | SCE_GXM_TEXTURE_FORMAT_S5S5U6_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 159 | 160 | SCE_GXM_TEXTURE_FORMAT_U8U8_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 161 | SCE_GXM_TEXTURE_FORMAT_U8U8_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 162 | SCE_GXM_TEXTURE_FORMAT_U8U8_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 163 | SCE_GXM_TEXTURE_FORMAT_U8U8_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 164 | SCE_GXM_TEXTURE_FORMAT_U8U8_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 165 | SCE_GXM_TEXTURE_FORMAT_U8U8_GR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 166 | 167 | SCE_GXM_TEXTURE_FORMAT_S8S8_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 168 | SCE_GXM_TEXTURE_FORMAT_S8S8_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 169 | SCE_GXM_TEXTURE_FORMAT_S8S8_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 170 | SCE_GXM_TEXTURE_FORMAT_S8S8_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 171 | SCE_GXM_TEXTURE_FORMAT_S8S8_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 172 | SCE_GXM_TEXTURE_FORMAT_S8S8_GR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 173 | 174 | SCE_GXM_TEXTURE_FORMAT_U16_000R = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 175 | SCE_GXM_TEXTURE_FORMAT_U16_111R = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 176 | SCE_GXM_TEXTURE_FORMAT_U16_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 177 | SCE_GXM_TEXTURE_FORMAT_U16_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 178 | SCE_GXM_TEXTURE_FORMAT_U16_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 179 | SCE_GXM_TEXTURE_FORMAT_U16_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 180 | SCE_GXM_TEXTURE_FORMAT_U16_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 181 | SCE_GXM_TEXTURE_FORMAT_U16_R = SCE_GXM_TEXTURE_BASE_FORMAT_U16 | SCE_GXM_TEXTURE_SWIZZLE1_R, 182 | 183 | SCE_GXM_TEXTURE_FORMAT_S16_000R = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 184 | SCE_GXM_TEXTURE_FORMAT_S16_111R = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 185 | SCE_GXM_TEXTURE_FORMAT_S16_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 186 | SCE_GXM_TEXTURE_FORMAT_S16_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 187 | SCE_GXM_TEXTURE_FORMAT_S16_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 188 | SCE_GXM_TEXTURE_FORMAT_S16_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 189 | SCE_GXM_TEXTURE_FORMAT_S16_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 190 | SCE_GXM_TEXTURE_FORMAT_S16_R = SCE_GXM_TEXTURE_BASE_FORMAT_S16 | SCE_GXM_TEXTURE_SWIZZLE1_R, 191 | 192 | SCE_GXM_TEXTURE_FORMAT_F16_000R = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 193 | SCE_GXM_TEXTURE_FORMAT_F16_111R = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 194 | SCE_GXM_TEXTURE_FORMAT_F16_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 195 | SCE_GXM_TEXTURE_FORMAT_F16_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 196 | SCE_GXM_TEXTURE_FORMAT_F16_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 197 | SCE_GXM_TEXTURE_FORMAT_F16_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 198 | SCE_GXM_TEXTURE_FORMAT_F16_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 199 | SCE_GXM_TEXTURE_FORMAT_F16_R = SCE_GXM_TEXTURE_BASE_FORMAT_F16 | SCE_GXM_TEXTURE_SWIZZLE1_R, 200 | 201 | SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 202 | SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 203 | SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 204 | SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 205 | SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 206 | SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 207 | SCE_GXM_TEXTURE_FORMAT_U8U8U8X8_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 208 | SCE_GXM_TEXTURE_FORMAT_U8U8U8X8_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 209 | 210 | SCE_GXM_TEXTURE_FORMAT_S8S8S8S8_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 211 | SCE_GXM_TEXTURE_FORMAT_S8S8S8S8_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 212 | SCE_GXM_TEXTURE_FORMAT_S8S8S8S8_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 213 | SCE_GXM_TEXTURE_FORMAT_S8S8S8S8_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 214 | SCE_GXM_TEXTURE_FORMAT_X8S8S8S8_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 215 | SCE_GXM_TEXTURE_FORMAT_X8S8S8S8_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 216 | SCE_GXM_TEXTURE_FORMAT_S8S8S8X8_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 217 | SCE_GXM_TEXTURE_FORMAT_S8S8S8X8_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 218 | 219 | SCE_GXM_TEXTURE_FORMAT_U2U10U10U10_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 220 | SCE_GXM_TEXTURE_FORMAT_U2U10U10U10_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 221 | SCE_GXM_TEXTURE_FORMAT_U10U10U10U2_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 222 | SCE_GXM_TEXTURE_FORMAT_U10U10U10U2_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 223 | SCE_GXM_TEXTURE_FORMAT_X2U10U10U10_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 224 | SCE_GXM_TEXTURE_FORMAT_X2U10U10U10_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 225 | SCE_GXM_TEXTURE_FORMAT_U10U10U10X2_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 226 | SCE_GXM_TEXTURE_FORMAT_U10U10U10X2_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U2U10U10U10 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 227 | 228 | SCE_GXM_TEXTURE_FORMAT_U16U16_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 229 | SCE_GXM_TEXTURE_FORMAT_U16U16_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 230 | SCE_GXM_TEXTURE_FORMAT_U16U16_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 231 | SCE_GXM_TEXTURE_FORMAT_U16U16_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 232 | SCE_GXM_TEXTURE_FORMAT_U16U16_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 233 | SCE_GXM_TEXTURE_FORMAT_U16U16_GR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 234 | 235 | SCE_GXM_TEXTURE_FORMAT_S16S16_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 236 | SCE_GXM_TEXTURE_FORMAT_S16S16_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 237 | SCE_GXM_TEXTURE_FORMAT_S16S16_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 238 | SCE_GXM_TEXTURE_FORMAT_S16S16_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 239 | SCE_GXM_TEXTURE_FORMAT_S16S16_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 240 | SCE_GXM_TEXTURE_FORMAT_S16S16_GR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 241 | 242 | SCE_GXM_TEXTURE_FORMAT_F16F16_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 243 | SCE_GXM_TEXTURE_FORMAT_F16F16_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 244 | SCE_GXM_TEXTURE_FORMAT_F16F16_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 245 | SCE_GXM_TEXTURE_FORMAT_F16F16_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 246 | SCE_GXM_TEXTURE_FORMAT_F16F16_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 247 | SCE_GXM_TEXTURE_FORMAT_F16F16_GR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 248 | 249 | SCE_GXM_TEXTURE_FORMAT_F32_000R = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 250 | SCE_GXM_TEXTURE_FORMAT_F32_111R = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 251 | SCE_GXM_TEXTURE_FORMAT_F32_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 252 | SCE_GXM_TEXTURE_FORMAT_F32_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 253 | SCE_GXM_TEXTURE_FORMAT_F32_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 254 | SCE_GXM_TEXTURE_FORMAT_F32_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_F32 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 255 | SCE_GXM_TEXTURE_FORMAT_F32M_111R = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_111R, 256 | SCE_GXM_TEXTURE_FORMAT_F32M_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 257 | SCE_GXM_TEXTURE_FORMAT_F32M_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 258 | SCE_GXM_TEXTURE_FORMAT_F32M_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 259 | SCE_GXM_TEXTURE_FORMAT_F32M_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_R000, 260 | SCE_GXM_TEXTURE_FORMAT_F32M_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_R111, 261 | SCE_GXM_TEXTURE_FORMAT_F32M_R = SCE_GXM_TEXTURE_BASE_FORMAT_F32M | SCE_GXM_TEXTURE_SWIZZLE1_R, 262 | 263 | SCE_GXM_TEXTURE_FORMAT_X8S8S8U8_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_X8S8S8U8 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 264 | SCE_GXM_TEXTURE_FORMAT_X8U8S8S8_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_X8S8S8U8 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 265 | 266 | SCE_GXM_TEXTURE_FORMAT_X8U24_SD = SCE_GXM_TEXTURE_BASE_FORMAT_X8U24 | SCE_GXM_TEXTURE_SWIZZLE2_SD, 267 | SCE_GXM_TEXTURE_FORMAT_U24X8_DS = SCE_GXM_TEXTURE_BASE_FORMAT_X8U24 | SCE_GXM_TEXTURE_SWIZZLE2_DS, 268 | 269 | SCE_GXM_TEXTURE_FORMAT_U32_000R = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 270 | SCE_GXM_TEXTURE_FORMAT_U32_111R = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 271 | SCE_GXM_TEXTURE_FORMAT_U32_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 272 | SCE_GXM_TEXTURE_FORMAT_U32_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 273 | SCE_GXM_TEXTURE_FORMAT_U32_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 274 | SCE_GXM_TEXTURE_FORMAT_U32_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 275 | SCE_GXM_TEXTURE_FORMAT_U32_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 276 | SCE_GXM_TEXTURE_FORMAT_U32_R = SCE_GXM_TEXTURE_BASE_FORMAT_U32 | SCE_GXM_TEXTURE_SWIZZLE1_R, 277 | 278 | SCE_GXM_TEXTURE_FORMAT_S32_000R = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_000R, 279 | SCE_GXM_TEXTURE_FORMAT_S32_111R = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_111R, 280 | SCE_GXM_TEXTURE_FORMAT_S32_RRRR = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_RRRR, 281 | SCE_GXM_TEXTURE_FORMAT_S32_0RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_0RRR, 282 | SCE_GXM_TEXTURE_FORMAT_S32_1RRR = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_1RRR, 283 | SCE_GXM_TEXTURE_FORMAT_S32_R000 = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_R000, 284 | SCE_GXM_TEXTURE_FORMAT_S32_R111 = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_R111, 285 | SCE_GXM_TEXTURE_FORMAT_S32_R = SCE_GXM_TEXTURE_BASE_FORMAT_S32 | SCE_GXM_TEXTURE_SWIZZLE1_R, 286 | 287 | SCE_GXM_TEXTURE_FORMAT_SE5M9M9M9_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_SE5M9M9M9 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 288 | SCE_GXM_TEXTURE_FORMAT_SE5M9M9M9_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_SE5M9M9M9 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 289 | 290 | SCE_GXM_TEXTURE_FORMAT_F10F11F11_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_F11F11F10 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 291 | SCE_GXM_TEXTURE_FORMAT_F11F11F10_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_F11F11F10 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 292 | 293 | SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 294 | SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 295 | SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 296 | SCE_GXM_TEXTURE_FORMAT_F16F16F16F16_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 297 | SCE_GXM_TEXTURE_FORMAT_X16F16F16F16_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 298 | SCE_GXM_TEXTURE_FORMAT_X16F16F16F16_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 299 | SCE_GXM_TEXTURE_FORMAT_F16F16F16X16_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 300 | SCE_GXM_TEXTURE_FORMAT_F16F16F16X16_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_F16F16F16F16 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 301 | 302 | SCE_GXM_TEXTURE_FORMAT_U16U16U16U16_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 303 | SCE_GXM_TEXTURE_FORMAT_U16U16U16U16_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 304 | SCE_GXM_TEXTURE_FORMAT_U16U16U16U16_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 305 | SCE_GXM_TEXTURE_FORMAT_U16U16U16U16_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 306 | SCE_GXM_TEXTURE_FORMAT_X16U16U16U16_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 307 | SCE_GXM_TEXTURE_FORMAT_X16U16U16U16_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 308 | SCE_GXM_TEXTURE_FORMAT_U16U16U16X16_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 309 | SCE_GXM_TEXTURE_FORMAT_U16U16U16X16_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U16U16U16U16 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 310 | 311 | SCE_GXM_TEXTURE_FORMAT_S16S16S16S16_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 312 | SCE_GXM_TEXTURE_FORMAT_S16S16S16S16_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 313 | SCE_GXM_TEXTURE_FORMAT_S16S16S16S16_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 314 | SCE_GXM_TEXTURE_FORMAT_S16S16S16S16_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 315 | SCE_GXM_TEXTURE_FORMAT_X16S16S16S16_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 316 | SCE_GXM_TEXTURE_FORMAT_X16S16S16S16_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 317 | SCE_GXM_TEXTURE_FORMAT_S16S16S16X16_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 318 | SCE_GXM_TEXTURE_FORMAT_S16S16S16X16_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_S16S16S16S16 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 319 | 320 | SCE_GXM_TEXTURE_FORMAT_F32F32_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 321 | SCE_GXM_TEXTURE_FORMAT_F32F32_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 322 | SCE_GXM_TEXTURE_FORMAT_F32F32_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 323 | SCE_GXM_TEXTURE_FORMAT_F32F32_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 324 | SCE_GXM_TEXTURE_FORMAT_F32F32_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 325 | SCE_GXM_TEXTURE_FORMAT_F32F32_GR = SCE_GXM_TEXTURE_BASE_FORMAT_F32F32 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 326 | 327 | SCE_GXM_TEXTURE_FORMAT_U32U32_00GR = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_00GR, 328 | SCE_GXM_TEXTURE_FORMAT_U32U32_GRRR = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_GRRR, 329 | SCE_GXM_TEXTURE_FORMAT_U32U32_RGGG = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_RGGG, 330 | SCE_GXM_TEXTURE_FORMAT_U32U32_GRGR = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_GRGR, 331 | SCE_GXM_TEXTURE_FORMAT_U32U32_00RG = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_00RG, 332 | SCE_GXM_TEXTURE_FORMAT_U32U32_GR = SCE_GXM_TEXTURE_BASE_FORMAT_U32U32 | SCE_GXM_TEXTURE_SWIZZLE2_GR, 333 | 334 | SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRT2BPP | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 335 | SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRT2BPP | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 336 | 337 | SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRT4BPP | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 338 | SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRT4BPP | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 339 | 340 | SCE_GXM_TEXTURE_FORMAT_PVRTII2BPP_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII2BPP | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 341 | SCE_GXM_TEXTURE_FORMAT_PVRTII2BPP_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII2BPP | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 342 | 343 | SCE_GXM_TEXTURE_FORMAT_PVRTII4BPP_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII4BPP | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 344 | SCE_GXM_TEXTURE_FORMAT_PVRTII4BPP_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_PVRTII4BPP | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 345 | 346 | SCE_GXM_TEXTURE_FORMAT_UBC1_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_UBC1 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 347 | 348 | SCE_GXM_TEXTURE_FORMAT_UBC2_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_UBC2 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 349 | 350 | SCE_GXM_TEXTURE_FORMAT_UBC3_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_UBC3 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 351 | 352 | SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC0, 353 | SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC0, 354 | SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC1, 355 | SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC1, 356 | 357 | SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC0, 358 | SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC0, 359 | SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 | SCE_GXM_TEXTURE_SWIZZLE_YUV_CSC1, 360 | SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 | SCE_GXM_TEXTURE_SWIZZLE_YVU_CSC1, 361 | 362 | SCE_GXM_TEXTURE_FORMAT_YUYV422_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_YUYV_CSC0, 363 | SCE_GXM_TEXTURE_FORMAT_YVYU422_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_YVYU_CSC0, 364 | SCE_GXM_TEXTURE_FORMAT_UYVY422_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_UYVY_CSC0, 365 | SCE_GXM_TEXTURE_FORMAT_VYUY422_CSC0 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_VYUY_CSC0, 366 | SCE_GXM_TEXTURE_FORMAT_YUYV422_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_YUYV_CSC1, 367 | SCE_GXM_TEXTURE_FORMAT_YVYU422_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_YVYU_CSC1, 368 | SCE_GXM_TEXTURE_FORMAT_UYVY422_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_UYVY_CSC1, 369 | SCE_GXM_TEXTURE_FORMAT_VYUY422_CSC1 = SCE_GXM_TEXTURE_BASE_FORMAT_YUV422 | SCE_GXM_TEXTURE_SWIZZLE_VYUY_CSC1, 370 | 371 | SCE_GXM_TEXTURE_FORMAT_P4_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 372 | SCE_GXM_TEXTURE_FORMAT_P4_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 373 | SCE_GXM_TEXTURE_FORMAT_P4_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 374 | SCE_GXM_TEXTURE_FORMAT_P4_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 375 | SCE_GXM_TEXTURE_FORMAT_P4_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 376 | SCE_GXM_TEXTURE_FORMAT_P4_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 377 | SCE_GXM_TEXTURE_FORMAT_P4_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 378 | SCE_GXM_TEXTURE_FORMAT_P4_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_P4 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 379 | 380 | SCE_GXM_TEXTURE_FORMAT_P8_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 381 | SCE_GXM_TEXTURE_FORMAT_P8_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 382 | SCE_GXM_TEXTURE_FORMAT_P8_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 383 | SCE_GXM_TEXTURE_FORMAT_P8_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 384 | SCE_GXM_TEXTURE_FORMAT_P8_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 385 | SCE_GXM_TEXTURE_FORMAT_P8_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 386 | SCE_GXM_TEXTURE_FORMAT_P8_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 387 | SCE_GXM_TEXTURE_FORMAT_P8_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_P8 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1, 388 | 389 | SCE_GXM_TEXTURE_FORMAT_U8U8U8_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 390 | SCE_GXM_TEXTURE_FORMAT_U8U8U8_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 391 | 392 | SCE_GXM_TEXTURE_FORMAT_S8S8S8_BGR = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE3_BGR, 393 | SCE_GXM_TEXTURE_FORMAT_S8S8S8_RGB = SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8 | SCE_GXM_TEXTURE_SWIZZLE3_RGB, 394 | 395 | SCE_GXM_TEXTURE_FORMAT_U2F10F10F10_ABGR = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_ABGR, 396 | SCE_GXM_TEXTURE_FORMAT_U2F10F10F10_ARGB = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_ARGB, 397 | SCE_GXM_TEXTURE_FORMAT_F10F10F10U2_RGBA = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_RGBA, 398 | SCE_GXM_TEXTURE_FORMAT_F10F10F10U2_BGRA = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_BGRA, 399 | SCE_GXM_TEXTURE_FORMAT_X2F10F10F10_1BGR = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_1BGR, 400 | SCE_GXM_TEXTURE_FORMAT_X2F10F10F10_1RGB = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_1RGB, 401 | SCE_GXM_TEXTURE_FORMAT_F10F10F10X2_RGB1 = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_RGB1, 402 | SCE_GXM_TEXTURE_FORMAT_F10F10F10X2_BGR1 = SCE_GXM_TEXTURE_BASE_FORMAT_U2F10F10F10 | SCE_GXM_TEXTURE_SWIZZLE4_BGR1 403 | } SceGxmTextureFormat; 404 | 405 | typedef struct vita2d_texture vita2d_texture; 406 | typedef struct vita2d_font vita2d_font; 407 | 408 | int vita2d_init(); 409 | int vita2d_init_advanced(unsigned int temp_pool_size); 410 | int vita2d_fini(); 411 | 412 | void vita2d_clear_screen(); 413 | void vita2d_swap_buffers(); 414 | 415 | void vita2d_start_drawing(); 416 | void vita2d_end_drawing(); 417 | 418 | void vita2d_set_clear_color(unsigned int color); 419 | void vita2d_set_vblank_wait(int enable); 420 | void *vita2d_get_current_fb(); 421 | 422 | void *vita2d_pool_malloc(unsigned int size); 423 | void *vita2d_pool_memalign(unsigned int size, unsigned int alignment); 424 | unsigned int vita2d_pool_free_space(); 425 | void vita2d_pool_reset(); 426 | 427 | void vita2d_draw_pixel(float x, float y, unsigned int color); 428 | void vita2d_draw_line(float x0, float y0, float x1, float y1, unsigned int color); 429 | void vita2d_draw_rectangle(float x, float y, float w, float h, unsigned int color); 430 | void vita2d_draw_fill_circle(float x, float y, float radius, unsigned int color); 431 | 432 | vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h); 433 | vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format); 434 | void vita2d_free_texture(vita2d_texture *texture); 435 | 436 | unsigned int vita2d_texture_get_width(const vita2d_texture *texture); 437 | unsigned int vita2d_texture_get_height(const vita2d_texture *texture); 438 | unsigned int vita2d_texture_get_stride(const vita2d_texture *texture); 439 | SceGxmTextureFormat vita2d_texture_get_format(const vita2d_texture *texture); 440 | void *vita2d_texture_get_datap(const vita2d_texture *texture); 441 | void *vita2d_texture_get_palette(const vita2d_texture *texture); 442 | 443 | void vita2d_draw_texture(const vita2d_texture *texture, float x, float y); 444 | void vita2d_draw_texture_rotate(const vita2d_texture *texture, float x, float y, float rad); 445 | void vita2d_draw_texture_rotate_hotspot(const vita2d_texture *texture, float x, float y, float rad, float center_x, float center_y); 446 | void vita2d_draw_texture_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale); 447 | void vita2d_draw_texture_part(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h); 448 | void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale); 449 | 450 | void vita2d_draw_texture_tint(const vita2d_texture *texture, float x, float y, unsigned int color); 451 | void vita2d_draw_texture_tint_rotate(const vita2d_texture *texture, float x, float y, float rad, unsigned int color); 452 | void vita2d_draw_texture_tint_rotate_hotspot(const vita2d_texture *texture, float x, float y, float rad, float center_x, float center_y, unsigned int color); 453 | void vita2d_draw_texture_tint_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, unsigned int color); 454 | void vita2d_draw_texture_tint_part(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, unsigned int color); 455 | void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, unsigned int color); 456 | 457 | vita2d_texture *vita2d_load_PNG_file(const char *filename); 458 | vita2d_texture *vita2d_load_PNG_buffer(const void *buffer); 459 | 460 | vita2d_texture *vita2d_load_JPEG_file(const char *filename); 461 | vita2d_texture *vita2d_load_JPEG_buffer(const void *buffer, unsigned long buffer_size); 462 | 463 | vita2d_texture *vita2d_load_BMP_file(const char *filename); 464 | vita2d_texture *vita2d_load_BMP_buffer(const void *buffer); 465 | 466 | vita2d_font *vita2d_load_font_file(const char *filename); 467 | vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size); 468 | void vita2d_free_font(vita2d_font *font); 469 | void vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text); 470 | void vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...); 471 | void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size, const char *text, int *width, int *height); 472 | int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text); 473 | int vita2d_font_text_height(vita2d_font *font, unsigned int size, const char *text); 474 | ]] 475 | 476 | vita2d = {} 477 | 478 | local map = -- these functions just return void 479 | { 480 | {"vita2d_init", "init"}, 481 | {"vita2d_fini", "fini"}, 482 | {"vita2d_clear_screen", "clear_screen"}, 483 | {"vita2d_swap_buffers", "swap_buffers"}, 484 | {"vita2d_start_drawing", "start_drawing"}, 485 | {"vita2d_end_drawing", "end_drawing"}, 486 | {"vita2d_set_clear_color", "set_clear_color"}, 487 | {"vita2d_draw_pixel", "draw_pixel"}, 488 | {"vita2d_draw_line", "draw_line"}, 489 | {"vita2d_draw_rectangle", "draw_rectangle"}, 490 | {"vita2d_draw_fill_circle", "draw_circle"}, 491 | {"vita2d_get_current_fb", "get_framebuffer"} 492 | } 493 | 494 | for k,v in pairs(map) do 495 | vita2d[v[2]] = ffi.C[v[1]] 496 | end 497 | 498 | local tex_mt = 499 | { 500 | __index = 501 | { 502 | width = function(self) 503 | return ffi.C.vita2d_texture_get_width(self) 504 | end, 505 | height = function(self) 506 | return ffi.C.vita2d_texture_get_height(self) 507 | end, 508 | stride = function(self) 509 | return ffi.C.vita2d_texture_get_stride(self) 510 | end, 511 | data = function(self) 512 | return ffi.C.vita2d_texture_get_datap(self) 513 | end, 514 | format = function(self) 515 | return ffi.C.vita2d_texture_get_format(self) 516 | end, 517 | palette = function(self) 518 | return ffi.C.vita2d_texture_get_palette(self) 519 | end, 520 | draw = ffi.C.vita2d_draw_texture, 521 | draw_rotate = ffi.C.vita2d_draw_texture_rotate, 522 | draw_rotate_hotspot = ffi.C.vita2d_draw_texture_rotate_hotspot, 523 | draw_scale = ffi.C.vita2d_draw_texture_scale, 524 | draw_part = ffi.C.vita2d_draw_texture_part, 525 | draw_part_scale = ffi.C.vita2d_draw_texture_part_scale, 526 | draw_tint = ffi.C.vita2d_draw_texture_tint, 527 | draw_tint_rotate = ffi.C.vita2d_draw_texture_tint_rotate, 528 | draw_tint_rotate_hotspot = ffi.C.vita2d_draw_texture_tint_rotate_hotspot, 529 | draw_tint_scale = ffi.C.vita2d_draw_texture_tint_scale, 530 | draw_tint_part = ffi.C.vita2d_draw_texture_tint_part, 531 | draw_tint_part_scale = ffi.C.vita2d_draw_texture_tint_part_scale 532 | } 533 | } 534 | 535 | local vita2d_texture = ffi.metatype("vita2d_texture", tex_mt) 536 | 537 | local font_mt = 538 | { 539 | __index = 540 | { 541 | text_size = function(self, size, text) 542 | --w = ffi.new("int[1]") 543 | --h = ffi.new("int[1]") 544 | --ffi.C.vita2d_font_get_dimensions(self, size, text, w, h) 545 | --return w[0], h[0] 546 | return ffi.C.vita2d_font_text_width(self, size, text), ffi.C.vita2d_font_text_height(self, size, text) 547 | end, 548 | text_width = ffi.C.vita2d_font_text_width, 549 | text_height = ffi.C.vita2d_font_text_height, 550 | draw_text = function(self, x, y, color, size, text) 551 | print("trying to draw font") 552 | ffi.C.vita2d_font_draw_text(self, x, y, color, size, tostring(text)) 553 | end 554 | } 555 | } 556 | local vita2d_font = ffi.metatype("vita2d_font", font_mt) 557 | 558 | function vita2d.create_empty_texture(w, h) 559 | return ffi.gc(ffi.C.vita2d_create_empty_texture(w,h), ffi.C.vita2d_free_texture) 560 | end 561 | 562 | function vita2d.create_empty_texture_format(w, h, format) 563 | return ffi.gc(ffi.C.vita2d_create_empty_texture_format(w, h, format), ffi.C.vita2d_free_texture) 564 | end 565 | 566 | function vita2d.load_texture(f) 567 | local ext = f:sub(#f-3, #f) 568 | 569 | if fs.is_relative(f) then 570 | f = fs.working_dir .. "/" .. f 571 | end 572 | 573 | if ext == ".png" then 574 | return ffi.gc(ffi.C.vita2d_load_PNG_file(f), ffi.C.vita2d_free_texture) 575 | elseif ext == ".jpg" or ext == "jpeg" then 576 | return ffi.gc(ffi.C.vita2d_load_JPEG_file(f), ffi.C.vita2d_free_texture) 577 | elseif ext == ".bmp" then 578 | return ffi.gc(ffi.C.vita2d_load_BMP_file(f), ffi.C.vita2d_free_texture) 579 | end 580 | end 581 | 582 | function vita2d.load_texture_data(t, buff) 583 | if buff == nil then return end 584 | if t == "png" then 585 | return ffi.gc(ffi.C.vita2d_load_PNG_buffer(buff), ffi.C.vita2d_free_texture) 586 | elseif t == "jpg" or ext == "jpeg" then 587 | return ffi.gc(ffi.C.vita2d_load_JPEG_buffer(buff, #buff), ffi.C.vita2d_free_texture) 588 | elseif t == "bmp" then 589 | return ffi.gc(ffi.C.vita2d_load_BMP_buffer(buff), ffi.C.vita2d_free_texture) 590 | end 591 | end 592 | 593 | function vita2d.load_font_data(buff) 594 | if buff == nil then return end 595 | return ffi.gc(ffi.C.vita2d_load_font_mem(buff, #buff), ffi.C.vita2d_free_font) 596 | end 597 | 598 | function vita2d.load_font(f) 599 | print("vita2d: loading font") 600 | if not f then 601 | print("default font!") 602 | fon = vita2d.load_font("app0:/default_font.ttf") 603 | print("!") 604 | print(tostring(fon)) 605 | return fon 606 | else 607 | if fs.is_relative(f) then 608 | f = fs.working_dir .. "/" .. f 609 | end 610 | return ffi.gc(ffi.C.vita2d_load_font_file(f), ffi.C.vita2d_free_font) 611 | end 612 | end 613 | 614 | function vita2d.free_texture(tex) 615 | ffi.C.vita2d_free_texture(ffi.gc(tex, nil)) 616 | end 617 | 618 | -- void vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...); -- varargs and FFI don't mix very well 619 | --------------------------------------------------------------------------------