cmfilemanager-psp: Inital reimplementation in c++
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
61
.gitignore
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
.vscode/
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
*.SFO
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
*.PBP
|
||||
*.prx
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# CMFileManager PSP Specific objects
|
||||
app/drivers/audio_driver.S
|
||||
app/drivers/display_driver.S
|
||||
app/drivers/fs_driver.S
|
||||
app/drivers/impose_driver.S
|
||||
app/drivers/input_driver.S
|
17
.travis.yml
Normal file
@ -0,0 +1,17 @@
|
||||
language: c
|
||||
|
||||
dist: bionic
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
script:
|
||||
- docker run -it --rm -v "$PWD:/src" haydenkow/nu-pspdev make -f Makefile.psp
|
||||
- sh .travis/.build.sh
|
||||
|
||||
deploy:
|
||||
provider: pages
|
||||
skip_cleanup: true
|
||||
github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard
|
||||
on:
|
||||
branch: master
|
12
.travis/.build.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
rm -rf .git .travis common libs .gitattributes .gitignore .travis.yml ICON0.PNG LICENSE Makefile.psp README.md
|
||||
mkdir -p PSP/GAME/CMFileManager
|
||||
mv app/EBOOT.PBP PSP/GAME/CMFileManager/APP.PBP && mv launcher/EBOOT.PBP PSP/GAME/CMFileManager/EBOOT.PBP
|
||||
mv audio_driver/audio_driver.prx PSP/GAME/CMFileManager/audio_driver.prx
|
||||
mv display_driver/display_driver.prx PSP/GAME/CMFileManager/display_driver.prx
|
||||
mv fs_driver/fs_driver.prx PSP/GAME/CMFileManager/fs_driver.prx
|
||||
mv impose_driver/impose_driver.prx PSP/GAME/CMFileManager/impose_driver.prx
|
||||
mv input_driver/input_driver.prx PSP/GAME/CMFileManager/input_driver.prx
|
||||
zip -r CMFileManager-PSP.zip PSP/
|
||||
rm -rf app audio_driver display_driver fs_driver impose_driver, input_driver launcher PSP
|
7
Makefile.psp
Normal file
@ -0,0 +1,7 @@
|
||||
SUBDIRS = audio_driver display_driver fs_driver impose_driver input_driver app launcher
|
||||
|
||||
all:
|
||||
@for dir in $(SUBDIRS); do $(MAKE) -C $$dir; done
|
||||
|
||||
clean:
|
||||
@for dir in $(SUBDIRS); do $(MAKE) clean -C $$dir; done
|
55
README.MD
Normal file
@ -0,0 +1,55 @@
|
||||
# CMFileManager PSP [![Build Status](https://travis-ci.org/joel16/CMFileManager-PSP.svg?branch=master)](https://travis-ci.org/joel16/CMFileManager-PSP) ![Github latest downloads](https://img.shields.io/github/downloads/joel16/CMFileManager-PSP/total.svg)
|
||||
|
||||
CMFileManager PSP is a PSP application built using the unofficial PSPSDK and [glib2d (modded)](https://github.com/joel16/gLib2D). The user interface in this homebrew is heavily inspired and based on the LineageOS/CM file manager. The aim of this project is to provide a stable and up to date file manager that makes use of updated tools, whilst offering a modernized and user friendly interace. CMFileManager PSP is the **only** homebrew that properly uses the 'move' function correctly for moving files/folder from one place to another. Unlike other file managers for PSP which copies a file from one place to another and then deletes it, which can take a while depending on the file size.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Copy files/folders.
|
||||
- Move files/folders.
|
||||
- Delete files/folders.
|
||||
- Multi file handling functions for copy/move/delete.
|
||||
- File properties. (File size, creation time, modification time, access times, permissions)
|
||||
- Creating directories.
|
||||
- Renaming files/folders.
|
||||
- Image viewer (BMP, GIF - non animated, JPG, PCX, PNG, PGM, PPM and TGA).
|
||||
- Auto USB mount (with ef0:/ and ms0:/ support for PSP Go).
|
||||
- Dark theme mode.
|
||||
- EBOOT (homebrew/game) launcher - Also allows you to rip icon0/pic1 from eboot if it exists.
|
||||
- Browse other drives like flah0, flash1 and UMD (if not using PSP Go).
|
||||
- Support for both ef0:/ (internal) and ms0:/ (external) drives on PSP Go.
|
||||
- Screenshots in .BMP format. Use L + R to capture a screenshot.
|
||||
- Audio Player 16-Bit short 41K - 48K Hz. (FLAC, IT, MOD, MP3, OGG, OPUS, S3M, WAV and XM)
|
||||
- FTP connection
|
||||
|
||||
|
||||
**FTP Mode Instructions:**
|
||||
1. Press *START* to open settings menu and select `FTP connection`.
|
||||
3. Select a network connection when the Network dialog pops up.
|
||||
4. After it is connected successfully, a message will appear saying `FTP Connection established IP:Port`. Use an FTP client like WinSCP and enter the IP and port (1337) and make sure to use anonymous login.
|
||||
6. Once an FTP connection is established from your server, you won't see any folders or files. You have to manually search for the path `/ms0:` or `/ef0:`. You can also search for other devices like `/flash0:` or UMD - `/disc0:` (**Please use caution when browsing any flash0-flash3**)
|
||||
|
||||
|
||||
**Buttons:**
|
||||
|
||||
- Press *DPAD Up* to move the cursor up.
|
||||
- Press *DPAD Right* to move the cursor down.
|
||||
- Press *DPAD Left* to position the cursor to the start of the directory.
|
||||
- Press *DPAD Right* to position the cursor to the end of the directory.
|
||||
- Press *Start* to open settings.
|
||||
- Press *Select* to open menubar.
|
||||
- Press *Triangle* to bring up file options.
|
||||
- Press *enter button (depending on your region)* to enter directory/open file.
|
||||
- Press *cancel button (depending on your region)* to go back to previous directory/menu.
|
||||
- Press *L + R* to caputre screenshot.
|
||||
- Press *Select + Start* to exit.
|
||||
- Press *Start* on FTP mode or Audio player to disable/enable screen to save battery.
|
||||
|
||||
|
||||
**Image Viewer controls:**
|
||||
- L/R - Rotate anti-clockwise/clockwise
|
||||
- Up/Down - Zoom in/out
|
||||
- Select - Help menu
|
||||
- Left/Right - Previous/Next image
|
||||
- Analog stick - Position image after zoom
|
||||
- Triangle - Flip vertically
|
||||
- Square - Flip horizantally
|
44
app/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
TARGET = CMFileManager
|
||||
|
||||
SOURCES := data drivers source source/audio source/gui
|
||||
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
|
||||
SFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.S))
|
||||
CPPFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.cpp))
|
||||
GFXFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.png))
|
||||
FONTFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.pgf))
|
||||
|
||||
OBJS := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CFILES:.c=.o) $(SFILES:.S=.o) $(CPPFILES:.cpp=.o) $(GFXFILES:.png=.o) $(FONTFILES:.pgf=.o)
|
||||
|
||||
VERSION_MAJOR := 4
|
||||
VERSION_MINOR := 0
|
||||
VERSION_MICRO := 0
|
||||
|
||||
INCDIR = ../libs/include ../libs/include/ogg ../libs/include/opus include
|
||||
CFLAGS = -Os -G0 -Wall -ffast-math -fno-rtti -fno-exceptions \
|
||||
-DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_MICRO=$(VERSION_MICRO)
|
||||
CXXFLAGS = $(CFLAGS) -std=gnu++17
|
||||
ASFLAGS := $(CFLAGS)
|
||||
|
||||
BUILD_PRX = 1
|
||||
PSP_LARGE_MEMORY = 1
|
||||
|
||||
LIBDIR = ../libs/lib
|
||||
LDFLAGS =
|
||||
LIBS = -lpsputility -lintrafont -lglib2d -lpspgu -lpsprtc -lpspvram \
|
||||
-lxmp-lite -lmpg123 -lvorbisfile -lvorbis -lopusfile -lopus -lFLAC -logg -lpspaudio \
|
||||
-lpspctrl -lpsppower -lpspreg -lpspusb -lpspusbstor -lpspusbdevice -lpspumd \
|
||||
-lpspkubridge -lpspsystemctrl_user -lstdc++ -lm -lz
|
||||
|
||||
EXTRA_TARGETS = EBOOT.PBP
|
||||
PSP_EBOOT_TITLE = CM File Manager PSP v$(VERSION_MAJOR).$(VERSION_MINOR)$(VERSION_MICRO)
|
||||
PSP_EBOOT_ICON = ../ICON0.PNG
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build.mak
|
||||
|
||||
%.o: %.png
|
||||
bin2o -i $< $@ $(addsuffix _png, $(basename $(notdir $<) ))
|
||||
|
||||
%.o: %.pgf
|
||||
bin2o -i $< $@ $(addsuffix _pgf, $(basename $(notdir $<) ))
|
6
app/config.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"config_ver": 4,
|
||||
"sort": 0,
|
||||
"dark_theme": 1,
|
||||
"dev_options": 1
|
||||
}
|
BIN
app/data/battery_20.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
app/data/battery_20_charging.png
Normal file
After Width: | Height: | Size: 327 B |
BIN
app/data/battery_30.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
app/data/battery_30_charging.png
Normal file
After Width: | Height: | Size: 332 B |
BIN
app/data/battery_50.png
Normal file
After Width: | Height: | Size: 231 B |
BIN
app/data/battery_50_charging.png
Normal file
After Width: | Height: | Size: 332 B |
BIN
app/data/battery_60.png
Normal file
After Width: | Height: | Size: 231 B |
BIN
app/data/battery_60_charging.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
app/data/battery_80.png
Normal file
After Width: | Height: | Size: 227 B |
BIN
app/data/battery_80_charging.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
app/data/battery_full.png
Normal file
After Width: | Height: | Size: 178 B |
BIN
app/data/battery_full_charging.png
Normal file
After Width: | Height: | Size: 305 B |
BIN
app/data/bg_header.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
app/data/btn_material_light_check_off_normal.png
Normal file
After Width: | Height: | Size: 152 B |
BIN
app/data/btn_material_light_check_off_normal_dark.png
Normal file
After Width: | Height: | Size: 152 B |
BIN
app/data/btn_material_light_check_on_normal.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
app/data/btn_material_light_check_on_normal_dark.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
app/data/btn_material_light_radio_off_normal.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
app/data/btn_material_light_radio_off_normal_dark.png
Normal file
After Width: | Height: | Size: 364 B |
BIN
app/data/btn_material_light_radio_on_normal.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
app/data/btn_material_light_radio_on_normal_dark.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
app/data/btn_material_light_toggle_off_normal.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/data/btn_material_light_toggle_on_normal.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/data/btn_material_light_toggle_on_normal_dark.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/data/btn_playback_forward.png
Normal file
After Width: | Height: | Size: 812 B |
BIN
app/data/btn_playback_pause.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
app/data/btn_playback_play.png
Normal file
After Width: | Height: | Size: 424 B |
BIN
app/data/btn_playback_repeat.png
Normal file
After Width: | Height: | Size: 1020 B |
BIN
app/data/btn_playback_repeat_overlay.png
Normal file
After Width: | Height: | Size: 1020 B |
BIN
app/data/btn_playback_rewind.png
Normal file
After Width: | Height: | Size: 802 B |
BIN
app/data/btn_playback_shuffle.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/data/btn_playback_shuffle_overlay.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/data/default_artwork.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
app/data/default_artwork_blur.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
app/data/ic_arrow_back_normal.png
Normal file
After Width: | Height: | Size: 339 B |
BIN
app/data/ic_fso_default.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/data/ic_fso_folder.png
Normal file
After Width: | Height: | Size: 469 B |
BIN
app/data/ic_fso_folder_dark.png
Normal file
After Width: | Height: | Size: 523 B |
BIN
app/data/ic_fso_type_app.png
Normal file
After Width: | Height: | Size: 802 B |
BIN
app/data/ic_fso_type_audio.png
Normal file
After Width: | Height: | Size: 829 B |
BIN
app/data/ic_fso_type_compress.png
Normal file
After Width: | Height: | Size: 540 B |
BIN
app/data/ic_fso_type_image.png
Normal file
After Width: | Height: | Size: 832 B |
BIN
app/data/ic_fso_type_text.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
app/data/ic_material_dialog.png
Normal file
After Width: | Height: | Size: 701 B |
BIN
app/data/ic_material_dialog_dark.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
app/data/ic_material_light_navigation_drawer.png
Normal file
After Width: | Height: | Size: 182 B |
BIN
app/data/ic_material_light_sdcard.png
Normal file
After Width: | Height: | Size: 314 B |
BIN
app/data/ic_material_light_sdcard_dark.png
Normal file
After Width: | Height: | Size: 305 B |
BIN
app/data/ic_material_light_secure.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
app/data/ic_material_light_secure_dark.png
Normal file
After Width: | Height: | Size: 564 B |
BIN
app/data/ic_material_light_usb.png
Normal file
After Width: | Height: | Size: 333 B |
BIN
app/data/ic_material_options_dialog.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/data/ic_material_options_dialog_dark.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/data/ic_material_properties_dialog.png
Normal file
After Width: | Height: | Size: 768 B |
BIN
app/data/ic_material_properties_dialog_dark.png
Normal file
After Width: | Height: | Size: 946 B |
BIN
app/data/ic_play_btn.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
6
app/debug.log
Normal file
@ -0,0 +1,6 @@
|
||||
pspOpenDir(ms0:) failed: 0x0
|
||||
pspOpenDir(ms0:) failed: 0x0
|
||||
pspOpenDir(ms0:) failed: 0x0
|
||||
pspOpenDir(ms0:) failed: 0x0
|
||||
pspOpenDir(ms0:) failed: 0x0
|
||||
pspOpenDir(ms0:) failed: 0x0
|
140
app/drivers/mutex-imports.S
Normal file
@ -0,0 +1,140 @@
|
||||
.set noreorder
|
||||
|
||||
#include <pspimport.s>
|
||||
|
||||
IMPORT_START "ThreadManForUser", 0x40010000
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB7D098C6, sceKernelCreateMutex
|
||||
IMPORT_FUNC "ThreadManForUser", 0xF8170FBE, sceKernelDeleteMutex
|
||||
IMPORT_FUNC "ThreadManForUser", 0x6B30100F, sceKernelUnlockMutex
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB011B11F, sceKernelLockMutex
|
||||
IMPORT_FUNC "ThreadManForUser", 0x5bf4dd27, sceKernelLockMutexCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x0DDCD2C9, sceKernelTryLockMutex
|
||||
|
||||
IMPORT_FUNC "ThreadManForUser", 0x6E9EA350,_sceKernelReturnFromCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0x0C106E53, sceKernelRegisterThreadEventHandler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x72F3C145, sceKernelReleaseThreadEventHandler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x369EEB6B, sceKernelReferThreadEventHandlerStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0xE81CAF8F, sceKernelCreateCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0xEDBA5844, sceKernelDeleteCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0xC11BA8C4, sceKernelNotifyCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0xBA4051D6, sceKernelCancelCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0x2A3D44FF, sceKernelGetCallbackCount
|
||||
IMPORT_FUNC "ThreadManForUser", 0x349D6D6C, sceKernelCheckCallback
|
||||
IMPORT_FUNC "ThreadManForUser", 0x730ED8BC, sceKernelReferCallbackStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x9ACE131E, sceKernelSleepThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x82826F70, sceKernelSleepThreadCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD59EAD2F, sceKernelWakeupThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0xFCCFAD26, sceKernelCancelWakeupThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x9944F31F, sceKernelSuspendThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x75156E8F, sceKernelResumeThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x278C0DF5, sceKernelWaitThreadEnd
|
||||
IMPORT_FUNC "ThreadManForUser", 0x840E8133, sceKernelWaitThreadEndCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xCEADEB47, sceKernelDelayThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x68DA9E36, sceKernelDelayThreadCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xBD123D9E, sceKernelDelaySysClockThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x1181E963, sceKernelDelaySysClockThreadCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD6DA4BA1, sceKernelCreateSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0x28B6489C, sceKernelDeleteSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0x3F53E640, sceKernelSignalSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0x4E3A1105, sceKernelWaitSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0x6D212BAC, sceKernelWaitSemaCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x58B1F937, sceKernelPollSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0x8FFDF9A2, sceKernelCancelSema
|
||||
IMPORT_FUNC "ThreadManForUser", 0xBC6FEBC5, sceKernelReferSemaStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x55C20A00, sceKernelCreateEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0xEF9E4C70, sceKernelDeleteEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0x1FB15A32, sceKernelSetEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0x812346E4, sceKernelClearEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0x402FCF22, sceKernelWaitEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0x328C546A, sceKernelWaitEventFlagCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x30FD48F0, sceKernelPollEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0xCD203292, sceKernelCancelEventFlag
|
||||
IMPORT_FUNC "ThreadManForUser", 0xA66B0120, sceKernelReferEventFlagStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x8125221D, sceKernelCreateMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0x86255ADA, sceKernelDeleteMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0xE9B3061E, sceKernelSendMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0x18260574, sceKernelReceiveMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0xF3986382, sceKernelReceiveMbxCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x0D81716A, sceKernelPollMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0x87D4DD36, sceKernelCancelReceiveMbx
|
||||
IMPORT_FUNC "ThreadManForUser", 0xA8E8C846, sceKernelReferMbxStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x7C0DC2A0, sceKernelCreateMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0xF0B7DA1C, sceKernelDeleteMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0x876DBFAD, sceKernelSendMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0x7C41F2C2, sceKernelSendMsgPipeCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x884C9F90, sceKernelTrySendMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0x74829B76, sceKernelReceiveMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0xFBFA697D, sceKernelReceiveMsgPipeCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xDF52098F, sceKernelTryReceiveMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0x349B864D, sceKernelCancelMsgPipe
|
||||
IMPORT_FUNC "ThreadManForUser", 0x33BE4024, sceKernelReferMsgPipeStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x56C039B5, sceKernelCreateVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0x89B3D48C, sceKernelDeleteVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xBED27435, sceKernelAllocateVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xEC0A693F, sceKernelAllocateVplCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0xAF36D708, sceKernelTryAllocateVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB736E9FF, sceKernelFreeVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0x1D371B8A, sceKernelCancelVpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0x39810265, sceKernelReferVplStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0xC07BB470, sceKernelCreateFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xED1410E0, sceKernelDeleteFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD979E9BF, sceKernelAllocateFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xE7282CB6, sceKernelAllocateFplCB
|
||||
IMPORT_FUNC "ThreadManForUser", 0x623AE665, sceKernelTryAllocateFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xF6414A71, sceKernelFreeFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xA8AA591F, sceKernelCancelFpl
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD8199E4C, sceKernelReferFplStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x0E927AED,_sceKernelReturnFromTimerHandler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x110DEC9A, sceKernelUSec2SysClock
|
||||
IMPORT_FUNC "ThreadManForUser", 0xC8CD158C, sceKernelUSec2SysClockWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0xBA6B92E2, sceKernelSysClock2USec
|
||||
IMPORT_FUNC "ThreadManForUser", 0xE1619D7C, sceKernelSysClock2USecWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0xDB738F35, sceKernelGetSystemTime
|
||||
IMPORT_FUNC "ThreadManForUser", 0x82BC5777, sceKernelGetSystemTimeWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0x369ED59D, sceKernelGetSystemTimeLow
|
||||
IMPORT_FUNC "ThreadManForUser", 0x6652B8CA, sceKernelSetAlarm
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB2C25152, sceKernelSetSysClockAlarm
|
||||
IMPORT_FUNC "ThreadManForUser", 0x7E65B999, sceKernelCancelAlarm
|
||||
IMPORT_FUNC "ThreadManForUser", 0xDAA3F564, sceKernelReferAlarmStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x20FFF560, sceKernelCreateVTimer
|
||||
IMPORT_FUNC "ThreadManForUser", 0x328F9E52, sceKernelDeleteVTimer
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB3A59970, sceKernelGetVTimerBase
|
||||
IMPORT_FUNC "ThreadManForUser", 0xB7C18B77, sceKernelGetVTimerBaseWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0x034A921F, sceKernelGetVTimerTime
|
||||
IMPORT_FUNC "ThreadManForUser", 0xC0B3FFD2, sceKernelGetVTimerTimeWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0x542AD630, sceKernelSetVTimerTime
|
||||
IMPORT_FUNC "ThreadManForUser", 0xFB6425C3, sceKernelSetVTimerTimeWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0xC68D9437, sceKernelStartVTimer
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD0AEEE87, sceKernelStopVTimer
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD8B299AE, sceKernelSetVTimerHandler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x53B00E9A, sceKernelSetVTimerHandlerWide
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD2D615EF, sceKernelCancelVTimerHandler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x5F32BEAA, sceKernelReferVTimerStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x446D8DE6, sceKernelCreateThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x9FA03CD3, sceKernelDeleteThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0xF475845D, sceKernelStartThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x532A522E,_sceKernelExitThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0xAA73C935, sceKernelExitThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x809CE29B, sceKernelExitDeleteThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x616403BA, sceKernelTerminateThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x383F7BCC, sceKernelTerminateDeleteThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x3AD58B8C, sceKernelSuspendDispatchThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x27E22EC2, sceKernelResumeDispatchThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0xEA748E31, sceKernelChangeCurrentThreadAttr
|
||||
IMPORT_FUNC "ThreadManForUser", 0x71BC9871, sceKernelChangeThreadPriority
|
||||
IMPORT_FUNC "ThreadManForUser", 0x912354A7, sceKernelRotateThreadReadyQueue
|
||||
IMPORT_FUNC "ThreadManForUser", 0x2C34E053, sceKernelReleaseWaitThread
|
||||
IMPORT_FUNC "ThreadManForUser", 0x293B45B8, sceKernelGetThreadId
|
||||
IMPORT_FUNC "ThreadManForUser", 0x94AA61EE, sceKernelGetThreadCurrentPriority
|
||||
IMPORT_FUNC "ThreadManForUser", 0x3B183E26, sceKernelGetThreadExitStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0xD13BDE95, sceKernelCheckThreadStack
|
||||
IMPORT_FUNC "ThreadManForUser", 0x52089CA1, sceKernelGetThreadStackFreeSize
|
||||
IMPORT_FUNC "ThreadManForUser", 0x17C1684E, sceKernelReferThreadStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0xFFC36A14, sceKernelReferThreadRunStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x627E6F3A, sceKernelReferSystemStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x94416130, sceKernelGetThreadmanIdList
|
||||
IMPORT_FUNC "ThreadManForUser", 0x57CF62DD, sceKernelGetThreadmanIdType
|
||||
IMPORT_FUNC "ThreadManForUser", 0x64D4540E, sceKernelReferThreadProfiler
|
||||
IMPORT_FUNC "ThreadManForUser", 0x8218B4DD, sceKernelReferGlobalProfiler
|
||||
IMPORT_FUNC "ThreadManForUser", 0xA9C2CB9A, sceKernelReferMutexStatus
|
||||
IMPORT_FUNC "ThreadManForUser", 0x87D9223C, sceKernelCancelMutex
|
24
app/include/colours.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _CMFILEMANAGER_COLOURS_H_
|
||||
#define _CMFILEMANAGER_COLOURS_H_
|
||||
|
||||
#include <glib2d.h>
|
||||
|
||||
constexpr g2dColor BLACK_BG = G2D_RGBA(48, 48, 48, 255);
|
||||
constexpr g2dColor STATUS_BAR_LIGHT = G2D_RGBA(37, 79, 174, 255);
|
||||
constexpr g2dColor STATUS_BAR_DARK = G2D_RGBA(38, 50, 56, 255);
|
||||
constexpr g2dColor MENU_BAR_LIGHT = G2D_RGBA(51, 103, 214, 255);
|
||||
constexpr g2dColor MENU_BAR_DARK = G2D_RGBA(55, 71, 79, 255);
|
||||
constexpr g2dColor SELECTOR_COLOUR_LIGHT = G2D_RGBA(241, 241, 241, 255);
|
||||
constexpr g2dColor SELECTOR_COLOUR_DARK = G2D_RGBA(76, 76, 76, 255);
|
||||
constexpr g2dColor TITLE_COLOUR_LIGHT = G2D_RGBA(30, 136, 229, 255);
|
||||
constexpr g2dColor TITLE_COLOUR_DARK = G2D_RGBA(0, 150, 136, 255);
|
||||
constexpr g2dColor TEXT_COLOUR_LIGHT = G2D_RGBA(32, 32, 32, 255);
|
||||
constexpr g2dColor TEXT_COLOUR_DARK = G2D_RGBA(185, 185, 185, 255);
|
||||
|
||||
extern g2dColor BG_COLOUR, STATUS_BAR_COLOUR, MENU_BAR_COLOUR, SELECTOR_COLOUR, TITLE_COLOUR, TEXT_COLOUR;
|
||||
|
||||
namespace Colours {
|
||||
void Get(void);
|
||||
}
|
||||
|
||||
#endif
|
20
app/include/config.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef _CMFILEMANAGER_CONFIG_H_
|
||||
#define _CMFILEMANAGER_CONFIG_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef struct {
|
||||
int sort = 0;
|
||||
bool dark_theme = false;
|
||||
bool dev_options = false;
|
||||
std::string cwd;
|
||||
} config_t;
|
||||
|
||||
extern config_t cfg;
|
||||
|
||||
namespace Config {
|
||||
int Save(config_t config);
|
||||
int Load(void);
|
||||
}
|
||||
|
||||
#endif
|
36
app/include/fs.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef _CMFILEMANAGER_FS_H_
|
||||
#define _CMFILEMANAGER_FS_H_
|
||||
|
||||
#include <pspiofilemgr.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef enum FileType {
|
||||
FileTypeNone,
|
||||
FileTypeApp,
|
||||
FileTypeArchive,
|
||||
FileTypeAudio,
|
||||
FileTypeImage,
|
||||
FileTypeText
|
||||
} FileType;
|
||||
|
||||
namespace FS {
|
||||
bool FileExists(const std::string &path);
|
||||
bool DirExists(const std::string &path);
|
||||
int MakeDir(const std::string &path);
|
||||
int CreateFile(const std::string &path);
|
||||
std::string GetFileExt(const std::string &filename);
|
||||
FileType GetFileType(const std::string &filename);
|
||||
SceOff GetFileSize(const std::string &path);
|
||||
int ReadFile(const std::string &path, void *buf, int size);
|
||||
int WriteFile(const std::string &path, void *buf, int size);
|
||||
int GetDirList(const std::string &path, std::vector<SceIoDirent> &entries);
|
||||
int ChangeDirNext(const std::string &path, std::vector<SceIoDirent> &entries);
|
||||
int ChangeDirPrev(std::vector<SceIoDirent> &entries);
|
||||
void Copy(SceIoDirent *entry, const std::string &path);
|
||||
int Paste(void);
|
||||
int Move(void);
|
||||
int Delete(SceIoDirent *entry);
|
||||
}
|
||||
|
||||
#endif
|
71
app/include/ftppsp.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Sergi Granell (xerpi), Joel16
|
||||
*/
|
||||
|
||||
#ifndef _CMFILEMANAGER_FTPPSP_H_
|
||||
#define _CMFILEMANAGER_FTPPSP_H_
|
||||
|
||||
#include <pspsdk.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
typedef void (*ftppsp_log_cb_t)(const char *);
|
||||
|
||||
/* Returns PSVita's IP and FTP port. 0 on success */
|
||||
int ftppsp_init(char *psp_ip, unsigned short int *psp_port);
|
||||
void ftppsp_fini(void);
|
||||
int ftppsp_is_initialized(void);
|
||||
int ftppsp_add_device(const char *devname);
|
||||
int ftppsp_del_device(const char *devname);
|
||||
void ftppsp_set_info_log_cb(ftppsp_log_cb_t cb);
|
||||
void ftppsp_set_debug_log_cb(ftppsp_log_cb_t cb);
|
||||
void ftppsp_set_file_buf_size(unsigned int size);
|
||||
|
||||
/* Extended functionality */
|
||||
|
||||
typedef enum {
|
||||
FTP_DATA_CONNECTION_NONE,
|
||||
FTP_DATA_CONNECTION_ACTIVE,
|
||||
FTP_DATA_CONNECTION_PASSIVE
|
||||
} DataConnectionType;
|
||||
|
||||
|
||||
typedef struct ftppsp_client_info {
|
||||
/* Client number */
|
||||
int num;
|
||||
/* Thread UID */
|
||||
SceUID thid;
|
||||
/* Control connection socket FD */
|
||||
int ctrl_sockfd;
|
||||
/* Data connection attributes */
|
||||
int data_sockfd;
|
||||
DataConnectionType data_con_type;
|
||||
struct sockaddr_in data_sockaddr;
|
||||
/* PASV mode client socket */
|
||||
struct sockaddr_in pasv_sockaddr;
|
||||
int pasv_sockfd;
|
||||
/* Remote client net info */
|
||||
struct sockaddr_in addr;
|
||||
/* Receive buffer attributes */
|
||||
int n_recv;
|
||||
char recv_buffer[1024];
|
||||
/* Points to the character after the first space */
|
||||
const char *recv_cmd_args;
|
||||
/* Current working directory */
|
||||
char cur_path[1024];
|
||||
/* Rename path */
|
||||
char rename_path[1024];
|
||||
/* Client list */
|
||||
struct ftppsp_client_info *next;
|
||||
struct ftppsp_client_info *prev;
|
||||
/* Offset for transfer resume */
|
||||
unsigned int restore_point;
|
||||
} ftppsp_client_info_t;
|
||||
|
||||
typedef void (*cmd_dispatch_func)(ftppsp_client_info_t *client); // Command handler
|
||||
|
||||
int ftppsp_ext_add_custom_command(const char *cmd, cmd_dispatch_func func);
|
||||
int ftppsp_ext_del_custom_command(const char *cmd);
|
||||
void ftppsp_ext_client_send_ctrl_msg(ftppsp_client_info_t *client, const char *msg);
|
||||
void ftppsp_ext_client_send_data_msg(ftppsp_client_info_t *client, const char *str);
|
||||
|
||||
#endif
|
19
app/include/g2d.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _CMFILEMANAGER_GLIB2D_HELPER_H_
|
||||
#define _CMFILEMANAGER_GLIB2D_HELPER_H_
|
||||
|
||||
#include <glib2d.h>
|
||||
#include <intraFont.h>
|
||||
#include <string>
|
||||
|
||||
extern intraFont *font, *jpn0, *chn;
|
||||
|
||||
namespace G2D {
|
||||
void DrawRect(float x, float y, float width, float height, g2dColor colour);
|
||||
void DrawImage(g2dTexture *tex, float x, float y);
|
||||
void DrawImageScale(g2dTexture *tex, float x, float y, float w, float h);
|
||||
char *KeyboardGetText(const std::string &desc_msg, const std::string &initial_msg);
|
||||
void FontSetStyle(intraFont *font, float size, unsigned int colour, unsigned int options);
|
||||
float GetTextHeight(intraFont *font);
|
||||
}
|
||||
|
||||
#endif
|
54
app/include/gui.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef _CMFILEMANAGER_GUI_HELPER_H_
|
||||
#define _CMFILEMANAGER_GUI_HELPER_H_
|
||||
|
||||
#include <pspiofilemgr.h>
|
||||
#include <vector>
|
||||
|
||||
enum MENU_STATES {
|
||||
MENU_STATE_FILEBROWSER,
|
||||
MENU_STATE_OPTIONS,
|
||||
MENU_STATE_DELETE,
|
||||
MENU_STATE_PROPERTIES,
|
||||
MENU_STATE_SETTINGS,
|
||||
MENU_STATE_IMAGEVIEWER,
|
||||
MENU_STATE_ARCHIVEEXTRACT,
|
||||
MENU_STATE_TEXTREADER,
|
||||
MENU_STATE_UPDATE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
MENU_STATES state = MENU_STATE_FILEBROWSER;
|
||||
int selected = 0;
|
||||
std::vector<SceIoDirent> entries;
|
||||
std::vector<bool> checked;
|
||||
std::vector<bool> checked_copy;
|
||||
std::string checked_cwd;
|
||||
int checked_count = 0;
|
||||
u64 used_storage = 0;
|
||||
u64 total_storage = 0;
|
||||
g2dTexture *texture;
|
||||
} MenuItem;
|
||||
|
||||
namespace GUI {
|
||||
void ResetCheckbox(MenuItem *item);
|
||||
void GetStorageSize(MenuItem *item);
|
||||
void DisplayStatusBar(void);
|
||||
int RenderLoop(void);
|
||||
|
||||
void DisplayFileBrowser(MenuItem *item);
|
||||
void ControlFileBrowser(MenuItem *item, int *ctrl);
|
||||
|
||||
void DisplaySettings(MenuItem *item);
|
||||
void ControlSettings(MenuItem *item, int *ctrl);
|
||||
|
||||
void DisplayFileOptions(MenuItem *item);
|
||||
void ControlFileOptions(MenuItem *item, int *ctrl);
|
||||
|
||||
void DisplayDeleteOptions(MenuItem *item);
|
||||
void ControlDeleteOptions(MenuItem *item, int *ctrl);
|
||||
|
||||
void DisplayImageViewer(MenuItem *item);
|
||||
void ControlImageViewer(MenuItem *item, float *delta_time);
|
||||
}
|
||||
|
||||
#endif
|
43
app/include/kernel_functions.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef _CMFILEMANAGER_KERNEL_FUNCTIONS_H_
|
||||
#define _CMFILEMANAGER_KERNEL_FUNCTIONS_H_
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <pspctrl.h>
|
||||
#include <pspiofilemgr.h>
|
||||
|
||||
// Kernel function prototypes
|
||||
|
||||
// audio_driver functions
|
||||
extern int pspAudioSetFrequency(int frequency);
|
||||
|
||||
// display_driver functions
|
||||
extern int pspGetBrightness(int *brightness);
|
||||
extern int pspSetBrightness(int brightness);
|
||||
extern int pspDisplayEnable(void);
|
||||
extern int pspDisplayDisable(void);
|
||||
|
||||
// fs_driver functions
|
||||
extern int pspOpenDir(const char *dirname);
|
||||
extern int pspReadDir(SceUID dir, SceIoDirent *dirent);
|
||||
extern int pspCloseDir(SceUID dir);
|
||||
|
||||
// impose_driver functions
|
||||
extern int pspGetVolume(void);
|
||||
extern int pspSetVolume(int volume);
|
||||
extern int pspGetMute(void);
|
||||
extern int pspSetMute(int mute);
|
||||
extern int pspGetEqualizerMode(void);
|
||||
extern int pspSetEqualizerMode(int mode);
|
||||
extern int pspSetHomePopup(int popup);
|
||||
|
||||
// input_driver functions
|
||||
extern unsigned int pspGetButtons(void);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
10
app/include/log.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _CMFILEMANAGER_LOG_H_
|
||||
#define _CMFILEMANAGER_LOG_H_
|
||||
|
||||
namespace Log {
|
||||
int OpenHande(void);
|
||||
int CloseHandle(void);
|
||||
int Error(const char *format, ...);
|
||||
}
|
||||
|
||||
#endif
|
23
app/include/mutex.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _CMFILEMANAGER_MUTEX_H_
|
||||
#define _CMFILEMANAGER_MUTEX_H_
|
||||
|
||||
#define PSP_MUTEX_ATTR_FIFO 0
|
||||
#define PSP_MUTEX_ATTR_PRIORITY 0x100
|
||||
#define PSP_MUTEX_ATTR_ALLOW_RECURSIVE 0x200
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int sceKernelCreateMutex(const char *name, uint attributes, int initial_count, void* options);
|
||||
int sceKernelDeleteMutex(int mutexId);
|
||||
int sceKernelLockMutex(int mutexId, int count, uint* timeout);
|
||||
int sceKernelTryLockMutex(int mutexId, int count);
|
||||
int sceKernelUnlockMutex(int mutexId, int count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
23
app/include/textures.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _CMFILEMANAGER_TEXTURES_H_
|
||||
#define _CMFILEMANAGER_TEXTURES_H_
|
||||
|
||||
#include <glib2d.h>
|
||||
|
||||
constexpr int NUM_ICONS = 6;
|
||||
constexpr int NUM_BATT_ICONS = 6;
|
||||
|
||||
extern g2dTexture *file_icons[NUM_ICONS], *icon_dir, *icon_dir_dark, *icon_check, *icon_check_dark, *icon_uncheck, \
|
||||
*icon_uncheck_dark, *icon_toggle_on, *icon_toggle_dark_on, *icon_toggle_off, *icon_radio_off, \
|
||||
*icon_radio_on, *icon_radio_dark_off, *icon_radio_dark_on, *icon_nav_drawer, *icon_back, \
|
||||
*options_dialog, *options_dialog_dark, *properties_dialog, *properties_dialog_dark, *dialog, *dialog_dark, \
|
||||
*battery_charging[NUM_BATT_ICONS], *battery[NUM_BATT_ICONS], *usb_icon, \
|
||||
*default_artwork, *default_artwork_blur, *btn_play, *btn_pause, *btn_rewind, *btn_forward, \
|
||||
*btn_repeat, *btn_shuffle, *btn_repeat_overlay, *btn_shuffle_overlay, \
|
||||
*bg_header, *icon_sd, *icon_secure, *icon_sd_dark, *icon_secure_dark, *ic_play_btn;
|
||||
|
||||
namespace Textures {
|
||||
void Load(void);
|
||||
void Free(void);
|
||||
}
|
||||
|
||||
#endif
|
48
app/include/utils.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef _CMFILEMANAGER_UTILS_H_
|
||||
#define _CMFILEMANAGER_UTILS_H_
|
||||
|
||||
#include <pspctrl.h>
|
||||
#include <psptypes.h>
|
||||
|
||||
/// Checks whether a result code indicates success.
|
||||
#define R_SUCCEEDED(res) ((res) >= 0)
|
||||
/// Checks whether a result code indicates failure.
|
||||
#define R_FAILED(res) ((res) < 0)
|
||||
|
||||
enum BROWSE_STATE {
|
||||
BROWSE_STATE_INTERNAL,
|
||||
BROWSE_STATE_EXTERNAL
|
||||
};
|
||||
|
||||
extern bool psp_usb_cable_connection, is_ms_inserted, is_psp_go;
|
||||
extern enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
|
||||
extern BROWSE_STATE device;
|
||||
|
||||
namespace Utils {
|
||||
void SetBounds(int *set, int min, int max);
|
||||
void SetMax(int *set, int value, int max);
|
||||
void SetMin(int *set, int value, int min);
|
||||
void GetSizeString(char *string, double size);
|
||||
void InitKernelDrivers(void);
|
||||
void TermKernelDrivers(void);
|
||||
void HandleUSB(void);
|
||||
bool IsModelPSPGo(void);
|
||||
int IsMemCardInserted(bool *is_inserted);
|
||||
bool IsEF0(void);
|
||||
int LaunchEboot(const char *path);
|
||||
u64 GetTotalStorage(void);
|
||||
u64 GetFreeStorage(void);
|
||||
u64 GetUsedStorage(void);
|
||||
int ReadControls(void);
|
||||
int IsButtonPressed(enum PspCtrlButtons buttons);
|
||||
int IsButtonHeld(enum PspCtrlButtons buttons);
|
||||
int IsKButtonPressed(enum PspCtrlButtons buttons);
|
||||
int IsKButtonHeld(enum PspCtrlButtons buttons);
|
||||
int GetEnterButton(void);
|
||||
int GetCancelButton(void);
|
||||
float GetAnalogX(void);
|
||||
float GetAnalogY(void);
|
||||
bool IsCancelButtonPressed(void);
|
||||
}
|
||||
|
||||
#endif
|
15
app/source/colours.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "colours.h"
|
||||
#include "config.h"
|
||||
|
||||
g2dColor BG_COLOUR, STATUS_BAR_COLOUR, MENU_BAR_COLOUR, SELECTOR_COLOUR, TITLE_COLOUR, TEXT_COLOUR;
|
||||
|
||||
namespace Colours {
|
||||
void Get(void) {
|
||||
BG_COLOUR = cfg.dark_theme? BLACK_BG : WHITE;
|
||||
STATUS_BAR_COLOUR = cfg.dark_theme? STATUS_BAR_DARK : STATUS_BAR_LIGHT;
|
||||
MENU_BAR_COLOUR = cfg.dark_theme? MENU_BAR_DARK : MENU_BAR_LIGHT;
|
||||
SELECTOR_COLOUR = cfg.dark_theme? SELECTOR_COLOUR_DARK : SELECTOR_COLOUR_LIGHT;
|
||||
TITLE_COLOUR = cfg.dark_theme? TITLE_COLOUR_DARK : TITLE_COLOUR_LIGHT;
|
||||
TEXT_COLOUR = cfg.dark_theme? TEXT_COLOUR_DARK : TEXT_COLOUR_LIGHT;
|
||||
}
|
||||
}
|
86
app/source/config.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "log.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "utils.h"
|
||||
|
||||
constexpr int config_version = 4;
|
||||
constexpr char config_file[] = "{\n\t\"config_ver\": %d,\n\t\"sort\": %d,\n\t\"dark_theme\": %d,\n\t\"dev_options\": %d\n}\n";
|
||||
static int config_version_holder = 0;
|
||||
config_t cfg;
|
||||
|
||||
namespace Config {
|
||||
int Save(config_t config) {
|
||||
int ret = 0;
|
||||
char *buf = new char[128];
|
||||
int len = snprintf(buf, 128, config_file, config_version, cfg.sort, cfg.dark_theme, cfg.dev_options);
|
||||
|
||||
if (R_FAILED(ret = FS::WriteFile("config.json", buf, len))) {
|
||||
Log::Error("Read config failed in Config_Save 0x%lx\n", ret);
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
delete[] buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetDefault(config_t *config) {
|
||||
config->sort = 0;
|
||||
config->dark_theme = false;
|
||||
config->dev_options = false;
|
||||
}
|
||||
|
||||
int Load(void) {
|
||||
int ret = 0;
|
||||
|
||||
// Set root path and current working directory based on model.
|
||||
cfg.cwd = is_psp_go? "ef0:" : "ms0:";
|
||||
|
||||
if (is_psp_go)
|
||||
device = BROWSE_STATE_INTERNAL;
|
||||
else
|
||||
device = BROWSE_STATE_EXTERNAL;
|
||||
|
||||
if (!FS::FileExists("config.json")) {
|
||||
Config::SetDefault(&cfg);
|
||||
Log::Error("File doesn't exist\n");
|
||||
return Save(cfg);
|
||||
}
|
||||
|
||||
u64 size = FS::GetFileSize("config.json");
|
||||
char *buf = new char[size];
|
||||
|
||||
if (R_FAILED(ret = FS::ReadFile("config.json", buf, size))) {
|
||||
Log::Error("Read config failed in Config_Load 0x%lx\n", ret);
|
||||
delete[] buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf[size] = '\0';
|
||||
|
||||
rapidjson::Document document;
|
||||
document.Parse(buf);
|
||||
assert(document.IsObject());
|
||||
assert(document.HasMember("config_ver"));
|
||||
assert(document.HasMember("sort"));
|
||||
assert(document.HasMember("dark_theme"));
|
||||
assert(document.HasMember("dev_options"));
|
||||
|
||||
config_version_holder = document["config_ver"].GetInt();
|
||||
cfg.sort = document["sort"].GetInt();
|
||||
cfg.dark_theme = document["dark_theme"].GetInt();
|
||||
cfg.dev_options = document["dev_options"].GetInt();
|
||||
|
||||
delete[] buf;
|
||||
|
||||
// delete[] config file if config file is updated. This will rarely happen.
|
||||
if (config_version_holder < config_version) {
|
||||
sceIoRemove("config.json");
|
||||
Config::SetDefault(&cfg);
|
||||
return Config::Save(cfg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
512
app/source/fs.cpp
Normal file
@ -0,0 +1,512 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <cstdarg>
|
||||
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "kernel_functions.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace FS {
|
||||
typedef struct {
|
||||
std::string copy_path;
|
||||
std::string copy_filename;
|
||||
bool is_dir = false;
|
||||
} FSCopyEntry;
|
||||
|
||||
static FSCopyEntry fs_copy_entry;
|
||||
|
||||
bool FileExists(const std::string &path) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_RDONLY, 0777))) {
|
||||
sceIoClose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DirExists(const std::string &path) {
|
||||
SceUID dir = 0;
|
||||
|
||||
if (R_SUCCEEDED(dir = sceIoDopen(path.c_str()))) {
|
||||
sceIoDclose(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int MakeDir(const std::string &path) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceIoMkdir(path.c_str(), 0777)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CreateFile(const std::string &path) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777))) {
|
||||
sceIoClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
std::string GetFileExt(const std::string &filename) {
|
||||
std::string ext = std::filesystem::path(filename).extension();
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::toupper);
|
||||
return ext;
|
||||
}
|
||||
|
||||
FileType GetFileType(const std::string &filename) {
|
||||
std::string ext = FS::GetFileExt(filename);
|
||||
|
||||
if (!ext.compare(".PBP"))
|
||||
return FileTypeApp;
|
||||
else if ((!ext.compare(".ZIP")) || (!ext.compare(".RAR")) || (!ext.compare(".7Z")) || (!ext.compare(".LZMA")))
|
||||
return FileTypeArchive;
|
||||
else if ((!ext.compare(".FLAC")) || (!ext.compare(".IT")) || (!ext.compare(".MOD")) || (!ext.compare(".MP3")) || (!ext.compare(".OGG"))
|
||||
|| (!ext.compare(".OPUS")) || (!ext.compare(".S3M")) || (!ext.compare(".WAV")) || (!ext.compare(".XM")))
|
||||
return FileTypeAudio;
|
||||
else if ((!ext.compare(".BMP")) || (!ext.compare(".GIF")) || (!ext.compare(".JPG")) || (!ext.compare(".JPEG")) || (!ext.compare(".PGM"))
|
||||
|| (!ext.compare(".PPM")) || (!ext.compare(".PNG")) || (!ext.compare(".PSD")) || (!ext.compare(".TGA")) || (!ext.compare(".WEBP")))
|
||||
return FileTypeImage;
|
||||
else if ((!ext.compare(".JSON")) || (!ext.compare(".LOG")) || (!ext.compare(".TXT")) || (!ext.compare(".CFG")) || (!ext.compare(".INI")))
|
||||
return FileTypeText;
|
||||
|
||||
return FileTypeNone;
|
||||
}
|
||||
|
||||
SceOff GetFileSize(const std::string &path) {
|
||||
int ret = 0;
|
||||
|
||||
SceIoStat stat;
|
||||
std::memset(&stat, 0, sizeof(stat));
|
||||
|
||||
if (R_FAILED(ret = sceIoGetstat(path.c_str(), &stat)))
|
||||
return ret;
|
||||
|
||||
return stat.st_size;
|
||||
}
|
||||
|
||||
int ReadFile(const std::string &path, void *buf, int size) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_RDONLY, 0))) {
|
||||
int read = sceIoRead(file, buf, size);
|
||||
sceIoClose(file);
|
||||
return read;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
int WriteFile(const std::string &path, void *buf, int size) {
|
||||
SceUID file = 0;
|
||||
|
||||
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777))) {
|
||||
int written = sceIoWrite(file, buf, size);
|
||||
sceIoClose(file);
|
||||
return written;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static bool Sort(const SceIoDirent &entryA, const SceIoDirent &entryB) {
|
||||
if ((FIO_S_ISDIR(entryA.d_stat.st_mode)) && !(FIO_S_ISDIR(entryB.d_stat.st_mode)))
|
||||
return true;
|
||||
else if (!(FIO_S_ISDIR(entryA.d_stat.st_mode)) && (FIO_S_ISDIR(entryB.d_stat.st_mode)))
|
||||
return false;
|
||||
else {
|
||||
switch(cfg.sort) {
|
||||
case 0:
|
||||
if (strcasecmp(entryA.d_name, entryB.d_name) < 0)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (strcasecmp(entryB.d_name, entryA.d_name) < 0)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (entryB.d_stat.st_size < entryA.d_stat.st_size)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (entryA.d_stat.st_size < entryB.d_stat.st_size)
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetDirList(const std::string &path, std::vector<SceIoDirent> &entries) {
|
||||
int ret = 0;
|
||||
SceUID dir = 0;
|
||||
entries.clear();
|
||||
|
||||
if (R_FAILED(ret = dir = sceIoDopen(path.c_str()))) {
|
||||
Log::Error("sceIoDopen(%s) failed: 0x%lx\n", path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
SceIoDirent entry;
|
||||
std::memset(&entry, 0, sizeof(entry));
|
||||
|
||||
ret = sceIoDread(dir, &entry);
|
||||
if (ret > 0) {
|
||||
if ((std::strcmp(entry.d_name, ".") == 0) || (std::strcmp(entry.d_name, "..") == 0))
|
||||
continue;
|
||||
|
||||
entries.push_back(entry);
|
||||
}
|
||||
} while (ret > 0);
|
||||
|
||||
std::sort(entries.begin(), entries.end(), FS::Sort);
|
||||
sceIoDclose(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO: Clean up change directory impl.
|
||||
static int ChangeDir(const std::string &path, std::vector<SceIoDirent> &entries) {
|
||||
int ret = 0;
|
||||
std::vector<SceIoDirent> new_entries;
|
||||
|
||||
if (R_FAILED(ret = FS::GetDirList(path, new_entries)))
|
||||
return ret;
|
||||
|
||||
// Free entries and change the current working directory.
|
||||
entries.clear();
|
||||
cfg.cwd = path;
|
||||
entries = new_entries;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChangeDirUp(char path[256]) {
|
||||
if (cfg.cwd.back() == ':')
|
||||
return -1;
|
||||
|
||||
// Remove upmost directory
|
||||
bool copy = false;
|
||||
int len = 0;
|
||||
for (ssize_t i = cfg.cwd.length(); i >= 0; i--) {
|
||||
if (cfg.cwd.c_str()[i] == '/')
|
||||
copy = true;
|
||||
if (copy) {
|
||||
path[i] = cfg.cwd.c_str()[i];
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
// remove trailing slash
|
||||
if (len > 1 && path[len - 1] == '/')
|
||||
len--;
|
||||
|
||||
path[len] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ChangeDirNext(const std::string &path, std::vector<SceIoDirent> &entries) {
|
||||
std::string new_path = cfg.cwd;
|
||||
new_path.append("/");
|
||||
new_path.append(path);
|
||||
return FS::ChangeDir(new_path, entries);
|
||||
}
|
||||
|
||||
int ChangeDirPrev(std::vector<SceIoDirent> &entries) {
|
||||
char new_path[256];
|
||||
if (FS::ChangeDirUp(new_path) < 0)
|
||||
return -1;
|
||||
|
||||
return FS::ChangeDir(std::string(new_path), entries);
|
||||
}
|
||||
|
||||
static int CopyFile(const std::string &src_path, const std::string &dest_path) {
|
||||
int ret = 0;
|
||||
SceUID src_handle = 0, dest_handle = 0;
|
||||
|
||||
if (R_FAILED(ret = src_handle = sceIoOpen(src_path.c_str(), PSP_O_RDONLY, 0))) {
|
||||
Log::Error("sceIoOpen(%s) failed: 0x%x\n", src_path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u64 size = sceIoLseek(src_handle, 0, PSP_SEEK_END);
|
||||
sceIoLseek(src_handle, 0, PSP_SEEK_SET);
|
||||
|
||||
// Make sure we have enough storage to carry out this operation
|
||||
if (Utils::GetFreeStorage() < size) {
|
||||
Log::Error("Not enough storage is available to process this command 0x%x\n", src_path.c_str(), ret);
|
||||
sceIoClose(src_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = dest_handle = sceIoOpen(dest_path.c_str(), PSP_O_WRONLY | PSP_O_CREAT | PSP_O_APPEND, 0777))) {
|
||||
Log::Error("sceIoOpen(%s) failed: 0x%x\n", dest_path.c_str(), ret);
|
||||
sceIoClose(src_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 bytes_read = 0, bytes_written = 0;
|
||||
const u64 buf_size = 0x10000;
|
||||
u64 offset = 0;
|
||||
u8 *buf = new u8[buf_size];
|
||||
std::string filename = std::filesystem::path(src_path.data()).filename();
|
||||
|
||||
do {
|
||||
if (Utils::IsCancelButtonPressed()) {
|
||||
delete[] buf;
|
||||
sceIoClose(src_handle);
|
||||
sceIoClose(dest_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::memset(buf, 0, buf_size);
|
||||
|
||||
if (R_FAILED(ret = bytes_read = sceIoRead(src_handle, buf, buf_size))) {
|
||||
Log::Error("sceIoRead(%s) failed: 0x%x\n", src_path.c_str(), ret);
|
||||
delete[] buf;
|
||||
sceIoClose(src_handle);
|
||||
sceIoClose(dest_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = bytes_written = sceIoWrite(dest_handle, buf, bytes_read))) {
|
||||
Log::Error("sceIoWrite(%s) failed: 0x%x\n", dest_path.c_str(), ret);
|
||||
delete[] buf;
|
||||
sceIoClose(src_handle);
|
||||
sceIoClose(dest_handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset += bytes_read;
|
||||
//GUI::ProgressBar("Copying", filename.c_str(), offset, size);
|
||||
} while(offset < size);
|
||||
|
||||
delete[] buf;
|
||||
sceIoClose(src_handle);
|
||||
sceIoClose(dest_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CopyDir(const std::string &src_path, const std::string &dest_path) {
|
||||
int ret = 0;
|
||||
SceUID dir;
|
||||
|
||||
if (R_FAILED(dir = sceIoDopen(src_path.c_str()))) {
|
||||
Log::Error("sceIoDopen(%s) failed: 0x%lx\n", src_path.c_str(), ret);
|
||||
return dir;
|
||||
}
|
||||
|
||||
// This may fail or not, but we don't care -> make the dir if it doesn't exist, otherwise continue.
|
||||
sceIoMkdir(dest_path.c_str(), 0777);
|
||||
|
||||
do {
|
||||
SceIoDirent entry;
|
||||
std::memset(&entry, 0, sizeof(entry));
|
||||
|
||||
ret = sceIoDread(dir, &entry);
|
||||
if (ret > 0) {
|
||||
if ((std::strcmp(entry.d_name, ".") == 0) || (std::strcmp(entry.d_name, "..") == 0))
|
||||
continue;
|
||||
|
||||
std::string src = src_path;
|
||||
src.append("/");
|
||||
src.append(entry.d_name);
|
||||
|
||||
std::string dest = dest_path;
|
||||
dest.append("/");
|
||||
dest.append(entry.d_name);
|
||||
|
||||
if (FIO_S_ISDIR(entry.d_stat.st_mode))
|
||||
FS::CopyDir(src, dest); // Copy Folder (via recursion)
|
||||
else
|
||||
FS::CopyFile(src, dest); // Copy File
|
||||
}
|
||||
} while (ret > 0);
|
||||
|
||||
sceIoDclose(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ClearCopyData(void) {
|
||||
fs_copy_entry.copy_path.clear();
|
||||
fs_copy_entry.copy_filename.clear();
|
||||
fs_copy_entry.is_dir = false;
|
||||
}
|
||||
|
||||
void Copy(SceIoDirent *entry, const std::string &path) {
|
||||
FS::ClearCopyData();
|
||||
fs_copy_entry.copy_path = path;
|
||||
fs_copy_entry.copy_path.append("/");
|
||||
fs_copy_entry.copy_path.append(entry->d_name);
|
||||
fs_copy_entry.copy_filename.append(entry->d_name);
|
||||
|
||||
if (FIO_S_ISDIR(entry->d_stat.st_mode))
|
||||
fs_copy_entry.is_dir = true;
|
||||
}
|
||||
|
||||
int Paste(void) {
|
||||
int ret = 0;
|
||||
std::string path = cfg.cwd;
|
||||
path.append("/");
|
||||
path.append(fs_copy_entry.copy_filename);
|
||||
|
||||
if (fs_copy_entry.is_dir) // Copy folder recursively
|
||||
ret = FS::CopyDir(fs_copy_entry.copy_path, path);
|
||||
else // Copy file
|
||||
ret = FS::CopyFile(fs_copy_entry.copy_path, path);
|
||||
|
||||
FS::ClearCopyData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Thanks to TN for finding this.
|
||||
static int sceIoMove(const char *src, const char *dest) {
|
||||
int ret = 0;
|
||||
size_t i = 0;
|
||||
char strage[32];
|
||||
char *p1 = nullptr, *p2 = nullptr;
|
||||
p1 = std::strchr(src, ':');
|
||||
|
||||
if (p1 == nullptr)
|
||||
return -1;
|
||||
|
||||
p2 = std::strchr(dest, ':');
|
||||
if (p2 == nullptr)
|
||||
return -1;
|
||||
|
||||
if ((p1 - src) != (p2 - dest))
|
||||
return -1;
|
||||
|
||||
for (i = 0; (src + i) <= p1; i++) {
|
||||
if ((i+1) >= sizeof(strage))
|
||||
return -1;
|
||||
|
||||
if (src[i] != dest[i])
|
||||
return -1;
|
||||
|
||||
strage[i] = src[i];
|
||||
}
|
||||
|
||||
strage[i] = '\0';
|
||||
|
||||
u32 data[2];
|
||||
data[0] = (u32)(p1 + 1);
|
||||
data[1] = (u32)(p2 + 1);
|
||||
|
||||
if (R_FAILED(ret = sceIoDevctl(strage, 0x02415830, &data, sizeof(data), nullptr, 0))) {
|
||||
Log::Error("sceIoDevctl() failed!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Move(void) {
|
||||
int ret = 0;
|
||||
std::string path = cfg.cwd;
|
||||
path.append("/");
|
||||
path.append(fs_copy_entry.copy_filename);
|
||||
|
||||
if (R_FAILED(ret = sceIoMove(fs_copy_entry.copy_path.c_str(), path.c_str()))) {
|
||||
Log::Error("sceIoMove(%s, %s) failed: 0x%x\n", fs_copy_entry.copy_filename.c_str(), path.c_str(), ret);
|
||||
FS::ClearCopyData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
FS::ClearCopyData();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DeleteDirectoryRecursive(const std::string &path) {
|
||||
int ret = 0;
|
||||
SceUID dir = 0;
|
||||
|
||||
if (R_FAILED(ret = dir = sceIoDopen(path.c_str()))) {
|
||||
if (R_FAILED(ret = sceIoRemove(path.c_str()))) {
|
||||
Log::Error("sceIoRemove(%s) failed: 0x%lx\n", path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
SceIoDirent entry;
|
||||
std::memset(&entry, 0, sizeof(entry));
|
||||
|
||||
ret = sceIoDread(dir, &entry);
|
||||
if (ret > 0) {
|
||||
if ((std::strcmp(entry.d_name, ".") == 0) || (std::strcmp(entry.d_name, "..") == 0))
|
||||
continue;
|
||||
|
||||
std::string new_path = path;
|
||||
new_path.append("/");
|
||||
new_path.append(entry.d_name);
|
||||
|
||||
if (FIO_S_ISDIR(entry.d_stat.st_mode)) {
|
||||
int result = FS::DeleteDirectoryRecursive(new_path);
|
||||
if (result <= 0) {
|
||||
Log::Error("FS::DeleteDirectoryRecursive(%s) failed: 0x%lx\n", path.c_str(), ret);
|
||||
sceIoDclose(dir);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int result = sceIoRemove(new_path.c_str());
|
||||
if (R_FAILED(result)) {
|
||||
Log::Error("sceIoRemove(%s) failed: 0x%lx\n", path.c_str(), ret);
|
||||
sceIoDclose(dir);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (ret > 0);
|
||||
|
||||
sceIoDclose(dir);
|
||||
|
||||
if (R_FAILED(ret = sceIoRmdir(path.c_str()))) {
|
||||
Log::Error("sceIoRmdir(%s) failed: 0x%lx\n", path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Delete(SceIoDirent *entry) {
|
||||
int ret = 0;
|
||||
std::string path = cfg.cwd;
|
||||
path.append("/");
|
||||
path.append(entry->d_name);
|
||||
|
||||
if (FIO_S_ISDIR(entry->d_stat.st_mode)) {
|
||||
if (R_FAILED(ret = FS::DeleteDirectoryRecursive(path))) {
|
||||
Log::Error("FS::DeleteDirectoryRecursive(%s) failed: 0x%x\n", path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (R_FAILED(ret = sceIoRemove(path.c_str()))) {
|
||||
Log::Error("sceIoRemove(%s) failed: 0x%x\n", path.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
1095
app/source/ftppsp.cpp
Normal file
147
app/source/g2d.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include <pspkernel.h>
|
||||
#include <pspdisplay.h>
|
||||
#include <pspgu.h>
|
||||
#include <psputility.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "g2d.h"
|
||||
#include "utils.h"
|
||||
|
||||
intraFont *font, *jpn0, *chn;
|
||||
|
||||
namespace G2D {
|
||||
void DrawRect(float x, float y, float width, float height, g2dColor colour) {
|
||||
g2dBeginRects(nullptr); {
|
||||
g2dSetColor(colour);
|
||||
g2dSetScaleWH(width, height);
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
void DrawImage(g2dTexture *tex, float x, float y) {
|
||||
g2dBeginRects(tex); {
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
void DrawImageScale(g2dTexture *tex, float x, float y, float w, float h) {
|
||||
g2dBeginRects(tex); {
|
||||
g2dSetScaleWH(w, h);
|
||||
g2dSetCoordXY(x, y);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
|
||||
static int GetText(char *input, unsigned short *intext, unsigned short *desc) {
|
||||
bool done = false;
|
||||
unsigned short outtext[128] = { 0 };
|
||||
|
||||
SceUtilityOskData data;
|
||||
std::memset(&data, 0, sizeof(SceUtilityOskData));
|
||||
|
||||
data.language = PSP_UTILITY_OSK_LANGUAGE_DEFAULT; // Use system default for text input
|
||||
data.lines = 1;
|
||||
data.unk_24 = 1;
|
||||
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL; // Allow all input types
|
||||
data.desc = desc;
|
||||
data.intext = intext;
|
||||
data.outtextlength = 128;
|
||||
data.outtextlimit = 32; // Limit input to 32 characters
|
||||
data.outtext = outtext;
|
||||
|
||||
SceUtilityOskParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
params.base.size = sizeof(params);
|
||||
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, ¶ms.base.language);
|
||||
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, ¶ms.base.buttonSwap);
|
||||
params.base.graphicsThread = 17;
|
||||
params.base.accessThread = 19;
|
||||
params.base.fontThread = 18;
|
||||
params.base.soundThread = 16;
|
||||
params.datacount = 1;
|
||||
params.data = &data;
|
||||
|
||||
int ret = 0;
|
||||
if (R_FAILED(ret = sceUtilityOskInitStart(¶ms)))
|
||||
return ret;
|
||||
|
||||
while(!done) {
|
||||
int i = 0, j = 0;
|
||||
|
||||
g2dClear(G2D_RGBA(39, 50, 56, 255));
|
||||
sceGuFinish();
|
||||
sceGuSync(0, 0);
|
||||
|
||||
switch(sceUtilityOskGetStatus()) {
|
||||
case PSP_UTILITY_DIALOG_INIT:
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_VISIBLE:
|
||||
sceUtilityOskUpdate(1);
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_QUIT:
|
||||
sceUtilityOskShutdownStart();
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_FINISHED:
|
||||
break;
|
||||
|
||||
case PSP_UTILITY_DIALOG_NONE:
|
||||
done = true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(i = 0; data.outtext[i]; i++) {
|
||||
if (data.outtext[i] != '\0' && data.outtext[i] != '\n' && data.outtext[i] != '\r') {
|
||||
input[j] = data.outtext[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
input[j] = 0;
|
||||
g2dFlip(G2D_VSYNC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *KeyboardGetText(const std::string &desc_msg, const std::string &initial_msg) {
|
||||
int ret = 0;
|
||||
size_t i = 0;
|
||||
static char str[64];
|
||||
unsigned short initial[128] = { 0 };
|
||||
unsigned short desc[128] = { 0 };
|
||||
|
||||
if (initial_msg.c_str()[0] != 0) {
|
||||
for (i = 0; i <= initial_msg.length(); i++)
|
||||
initial[i] = static_cast<unsigned short>(initial_msg.c_str()[i]);
|
||||
}
|
||||
|
||||
if (desc_msg.c_str()[0] != 0) {
|
||||
for (i = 0; i <= desc_msg.length(); i++)
|
||||
desc[i] = static_cast<unsigned short>(desc_msg.c_str()[i]);
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(ret = G2D::GetText(str, initial, desc)))
|
||||
return str;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FontSetStyle(intraFont *font, float size, unsigned int colour, unsigned int options) {
|
||||
intraFontSetStyle(font, size, colour, G2D_RGBA(0, 0, 0, 0), 0.f, options);
|
||||
}
|
||||
|
||||
float GetTextHeight(intraFont *font) {
|
||||
return font->advancey * font->size / 4.f + 2.f;
|
||||
}
|
||||
}
|
122
app/source/gui.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include <psppower.h>
|
||||
#include <sys/time.h>
|
||||
#include <psprtc.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "colours.h"
|
||||
#include "fs.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace GUI {
|
||||
void ResetCheckbox(MenuItem *item) {
|
||||
item->checked.clear();
|
||||
item->checked_copy.clear();
|
||||
item->checked.resize(item->entries.size());
|
||||
item->checked.assign(item->checked.size(), false);
|
||||
item->checked_cwd.clear();
|
||||
item->checked_count = 0;
|
||||
};
|
||||
|
||||
void GetStorageSize(MenuItem *item) {
|
||||
item->total_storage = Utils::GetTotalStorage();
|
||||
item->used_storage = Utils::GetUsedStorage();
|
||||
}
|
||||
|
||||
void DisplayStatusBar(void) {
|
||||
pspTime time;
|
||||
static char time_string[30];
|
||||
|
||||
if (R_SUCCEEDED(sceRtcGetCurrentClockLocalTime(&time)))
|
||||
snprintf(time_string, 30, "%2i:%02i %s", ((time.hour % 12) == 0)? 12 : time.hour % 12, time.minutes, (time.hour / 12)? "PM" : "AM");
|
||||
|
||||
G2D::FontSetStyle(font, 1.0f, WHITE, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, 5, 14, time_string);
|
||||
|
||||
int state = scePowerIsBatteryCharging();
|
||||
int percent = scePowerGetBatteryLifePercent();
|
||||
int battery_val = (percent / 20);
|
||||
|
||||
static char percent_string[13];
|
||||
snprintf(percent_string, 13, "%d%%", percent);
|
||||
int percent_width = intraFontMeasureText(font, percent_string);
|
||||
intraFontPrint(font, 475 - percent_width, 14, percent_string);
|
||||
|
||||
G2D::DrawImage(state != 0? battery_charging[battery_val] : battery[battery_val], 475 - percent_width - battery[battery_val]->w, 2);
|
||||
}
|
||||
|
||||
int RenderLoop(void) {
|
||||
bool done = false;
|
||||
MenuItem item;
|
||||
|
||||
int ret = 0;
|
||||
if (R_FAILED(ret = FS::GetDirList(cfg.cwd, item.entries)))
|
||||
return ret;
|
||||
|
||||
GUI::ResetCheckbox(&item);
|
||||
GUI::GetStorageSize(&item);
|
||||
|
||||
u64 last = 0;
|
||||
u32 tick = sceRtcGetTickResolution();
|
||||
sceRtcGetCurrentTick(&last);
|
||||
|
||||
Colours::Get();
|
||||
|
||||
while(!done) {
|
||||
u64 current = 0;
|
||||
sceRtcGetCurrentTick(¤t);
|
||||
|
||||
float delta_time = (current - last) / static_cast<float>(tick);
|
||||
last = current;
|
||||
|
||||
int ctrl = Utils::ReadControls();
|
||||
|
||||
g2dClear(BG_COLOUR);
|
||||
G2D::DrawRect(0, 0, 480, 18, STATUS_BAR_COLOUR);
|
||||
G2D::DrawRect(0, 18, 480, 34, MENU_BAR_COLOUR);
|
||||
G2D::DrawImageScale(icon_nav_drawer, 5, 24, 26.f, 26.f);
|
||||
GUI::DisplayStatusBar();
|
||||
GUI::DisplayFileBrowser(&item);
|
||||
|
||||
switch(item.state) {
|
||||
case MENU_STATE_FILEBROWSER:
|
||||
GUI::ControlFileBrowser(&item, &ctrl);
|
||||
break;
|
||||
|
||||
case MENU_STATE_OPTIONS:
|
||||
GUI::DisplayFileOptions(&item);
|
||||
GUI::ControlFileOptions(&item, &ctrl);
|
||||
break;
|
||||
|
||||
case MENU_STATE_DELETE:
|
||||
GUI::DisplayDeleteOptions(&item);
|
||||
GUI::ControlDeleteOptions(&item, &ctrl);
|
||||
break;
|
||||
|
||||
case MENU_STATE_SETTINGS:
|
||||
GUI::DisplaySettings(&item);
|
||||
GUI::ControlSettings(&item, &ctrl);
|
||||
break;
|
||||
|
||||
case MENU_STATE_IMAGEVIEWER:
|
||||
GUI::DisplayImageViewer(&item);
|
||||
GUI::ControlImageViewer(&item, &delta_time);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g2dFlip(G2D_VSYNC);
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_START))
|
||||
item.state = MENU_STATE_SETTINGS;
|
||||
else if (Utils::IsKButtonPressed(PSP_CTRL_HOME))
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
87
app/source/gui/delete.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "colours.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "log.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Options {
|
||||
void Delete(MenuItem *item, int *selection) {
|
||||
int ret = 0;
|
||||
Log::CloseHandle();
|
||||
|
||||
if ((item->checked_count > 1) && (!item->checked_cwd.compare(cfg.cwd))) {
|
||||
for (u32 i = 0; i < item->checked.size(); i++) {
|
||||
if (item->checked.at(i)) {
|
||||
if (R_FAILED(ret = FS::Delete(&item->entries[i]))) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FS::Delete(&item->entries[item->selected]);
|
||||
|
||||
if (R_SUCCEEDED(ret)) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
}
|
||||
|
||||
GUI::GetStorageSize(item);
|
||||
Log::OpenHande();
|
||||
*selection = 0;
|
||||
item->selected = 0;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
static int selection = 0;
|
||||
static const std::string prompt = "Do you wish to continue?";
|
||||
|
||||
void DisplayDeleteOptions(MenuItem *item) {
|
||||
G2D::DrawRect(0, 18, 480, 254, G2D_RGBA(0, 0, 0, cfg.dark_theme? 50: 80));
|
||||
G2D::DrawImage(cfg.dark_theme? dialog_dark : dialog, ((480 - (dialog->w)) / 2), ((272 - (dialog->h)) / 2));
|
||||
G2D::FontSetStyle(font, 1.0f, TITLE_COLOUR, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, ((480 - (dialog->w)) / 2) + 10, ((272 - (dialog->h)) / 2) + 20, "Delete");
|
||||
|
||||
int prompt_width = intraFontMeasureText(font, prompt.c_str());
|
||||
G2D::FontSetStyle(font, 1.0f, TEXT_COLOUR, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, ((480 - (prompt_width)) / 2), ((272 - (dialog->h)) / 2) + 60, prompt.c_str());
|
||||
|
||||
int confirm_width = intraFontMeasureText(font, "YES");
|
||||
int cancel_width = intraFontMeasureText(font, "NO");
|
||||
|
||||
if (selection == 0)
|
||||
G2D::DrawRect((364 - cancel_width) - 5, (180 - (font->texYSize - 15)) - 5, cancel_width + 10, (font->texYSize - 5) + 10, SELECTOR_COLOUR);
|
||||
else
|
||||
G2D::DrawRect((409 - (confirm_width)) - 5, (180 - (font->texYSize - 15)) - 5, confirm_width + 10, (font->texYSize - 5) + 10, SELECTOR_COLOUR);
|
||||
|
||||
G2D::FontSetStyle(font, 1.0f, TITLE_COLOUR, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, 409 - (confirm_width), (192 - (font->texYSize - 15)) - 3, "YES");
|
||||
intraFontPrint(font, 364 - cancel_width, (192 - (font->texYSize - 15)) - 3, "NO");
|
||||
}
|
||||
|
||||
void ControlDeleteOptions(MenuItem *item, int *ctrl) {
|
||||
if (*ctrl & PSP_CTRL_RIGHT)
|
||||
selection++;
|
||||
else if (*ctrl & PSP_CTRL_LEFT)
|
||||
selection--;
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
if (selection == 1)
|
||||
Options::Delete(item, &selection);
|
||||
else
|
||||
item->state = MENU_STATE_OPTIONS;
|
||||
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_CANCEL))
|
||||
item->state = MENU_STATE_OPTIONS;
|
||||
|
||||
Utils::SetBounds(&selection, 0, 1);
|
||||
}
|
||||
}
|
148
app/source/gui/filebrowser.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include <algorithm>
|
||||
#include <pspctrl.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "colours.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace GUI {
|
||||
static const int sel_dist = 20;
|
||||
static const int start_y = 52;
|
||||
static const u32 max_entries = 11;
|
||||
static int start = 0;
|
||||
|
||||
// static std::string empty_dir = "This is an empty directory";
|
||||
// static float empty_dir_width = 0.f, empty_dir_height = 0.f;
|
||||
|
||||
void DisplayFileBrowser(MenuItem *item) {
|
||||
G2D::FontSetStyle(font, 1.0f, WHITE, INTRAFONT_ALIGN_LEFT);
|
||||
float height = G2D::GetTextHeight(font);
|
||||
intraFontPrint(font, 40, 36, cfg.cwd.c_str());
|
||||
G2D::DrawRect(40, 43, 400, 3, SELECTOR_COLOUR);
|
||||
float fill = (static_cast<double>(item->used_storage)/static_cast<double>(item->total_storage)) * 400.f;
|
||||
G2D::DrawRect(40, 43, fill, 3, TITLE_COLOUR);
|
||||
|
||||
for (u32 i = start; i < item->entries.size(); i++) {
|
||||
std::string filename = item->entries[i].d_name;
|
||||
|
||||
if (i == static_cast<u32>(item->selected))
|
||||
G2D::DrawRect(0, start_y + (sel_dist * (i - start)), 480, sel_dist, SELECTOR_COLOUR);
|
||||
|
||||
if ((item->checked[i]) && (!item->checked_cwd.compare(cfg.cwd)))
|
||||
G2D::DrawImageScale(cfg.dark_theme? icon_check_dark : icon_check, 0, start_y + (sel_dist * (i - start)), 18.f, 18.f);
|
||||
else
|
||||
G2D::DrawImageScale(cfg.dark_theme? icon_uncheck_dark : icon_uncheck, 0, start_y + (sel_dist * (i - start)), 18.f, 18.f);
|
||||
|
||||
FileType file_type = FS::GetFileType(filename);
|
||||
if (FIO_S_ISDIR(item->entries[i].d_stat.st_mode))
|
||||
G2D::DrawImageScale(cfg.dark_theme? icon_dir_dark : icon_dir, 20, start_y + (sel_dist * (i - start)), 18.f, 18.f);
|
||||
else
|
||||
G2D::DrawImageScale(file_icons[file_type], 20, start_y + (sel_dist * (i - start)), 18.f, 18.f);
|
||||
|
||||
G2D::FontSetStyle(font, 1.0f, cfg.dark_theme? WHITE : BLACK, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrintf(font, 45, start_y + 10 + ((sel_dist - height) / 2) + (i - start) * sel_dist, filename.length() > 52? "%.52s..." : "%s", filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ControlFileBrowser(MenuItem *item, int *ctrl) {
|
||||
u32 size = (item->entries.size() - 1);
|
||||
Utils::SetBounds(&item->selected, 0, size);
|
||||
|
||||
if (*ctrl & PSP_CTRL_UP) {
|
||||
item->selected--;
|
||||
if (item->selected < 0)
|
||||
item->selected = size;
|
||||
|
||||
if (size < max_entries)
|
||||
start = 0;
|
||||
else if (start > item->selected)
|
||||
start--;
|
||||
else if ((static_cast<u32>(item->selected) == size) && (size > (max_entries - 1)))
|
||||
start = size - (max_entries - 1);
|
||||
}
|
||||
else if (*ctrl & PSP_CTRL_DOWN) {
|
||||
item->selected++;
|
||||
if(static_cast<u32>(item->selected) > size)
|
||||
item->selected = 0;
|
||||
|
||||
if ((static_cast<u32>(item->selected) > (start + (max_entries - 1))) && ((start + (max_entries - 1)) < size))
|
||||
start++;
|
||||
if (item->selected == 0)
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_LEFT)) {
|
||||
item->selected = 0;
|
||||
start = 0;
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_RIGHT)) {
|
||||
item->selected = item->entries.size() - 1;
|
||||
if ((item->entries.size() - 1) > max_entries)
|
||||
start = size - (max_entries - 1);
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
if (FIO_S_ISDIR(item->entries[item->selected].d_stat.st_mode)) {
|
||||
if (item->entries.size() != 0) {
|
||||
if (R_SUCCEEDED(FS::ChangeDirNext(item->entries[item->selected].d_name, item->entries))) {
|
||||
start = 0;
|
||||
// Make a copy before resizing our vector.
|
||||
if ((item->checked_count > 1) && (item->checked_copy.empty()))
|
||||
item->checked_copy = item->checked;
|
||||
|
||||
item->checked.resize(item->entries.size());
|
||||
item->selected = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string path = cfg.cwd;
|
||||
path.append(item->entries[item->selected].d_name);
|
||||
FileType file_type = FS::GetFileType(item->entries[item->selected].d_name);
|
||||
|
||||
switch(file_type) {
|
||||
case FileTypeImage:
|
||||
item->texture = g2dTexLoad(path.c_str(), G2D_SWIZZLE);
|
||||
if (item->texture)
|
||||
item->state = MENU_STATE_IMAGEVIEWER;
|
||||
break;
|
||||
|
||||
// case FileTypeZip:
|
||||
// if (R_SUCCEEDED(ArchiveHelper::Extract(path))) {
|
||||
// FS::GetDirList(cfg.cwd, item->entries);
|
||||
// GUI::ResetCheckbox(item);
|
||||
// }
|
||||
// break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
if (R_SUCCEEDED(FS::ChangeDirPrev(item->entries))) {
|
||||
// Make a copy before resizing our vector.
|
||||
if (item->checked_count > 1)
|
||||
item->checked_copy = item->checked;
|
||||
|
||||
item->checked.resize(item->entries.size());
|
||||
item->selected = 0;
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_SQUARE)) {
|
||||
if ((!item->checked_cwd.empty()) && (item->checked_cwd.compare(cfg.cwd) != 0))
|
||||
GUI::ResetCheckbox(item);
|
||||
|
||||
item->checked_cwd = cfg.cwd;
|
||||
item->checked[item->selected] = !item->checked[item->selected];
|
||||
item->checked_count = std::count(item->checked.begin(), item->checked.end(), true);
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_TRIANGLE))
|
||||
item->state = MENU_STATE_OPTIONS;
|
||||
}
|
||||
}
|
125
app/source/gui/imageviewer.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "colours.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace ImageViewer {
|
||||
static void Draw(g2dTexture *tex, float w, float h, float zoom_factor, int angle, int pos_x, int pos_y) {
|
||||
g2dBeginRects(tex); {
|
||||
g2dSetCoordMode(G2D_CENTER);
|
||||
g2dSetScaleWH(w * zoom_factor, h * zoom_factor);
|
||||
g2dSetCoordXY((G2D_SCR_W / 2) - (pos_x * zoom_factor - pos_x) / 2, (G2D_SCR_H / 2) - (pos_y * zoom_factor - pos_y) / 2);
|
||||
g2dSetRotation(angle);
|
||||
g2dAdd();
|
||||
}
|
||||
g2dEnd();
|
||||
}
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
static bool properties = false, horizantal_flip = false, vertical_flip = false;
|
||||
static float scale_factor = 0.f, width = 0.f, height = 0.f, zoom_factor = 1.f;
|
||||
static int degrees = 0, pos_x = 0, pos_y = 0;
|
||||
|
||||
void DisplayImageViewer(MenuItem *item) {
|
||||
g2dClear(BLACK_BG);
|
||||
|
||||
if (static_cast<float>(item->texture->h) > 272.f) {
|
||||
scale_factor = (272.f / static_cast<float>(item->texture->h));
|
||||
width = static_cast<float>(item->texture->w) * scale_factor;
|
||||
height = static_cast<float>(item->texture->h) * scale_factor;
|
||||
}
|
||||
else {
|
||||
width = static_cast<float>(item->texture->w);
|
||||
height = static_cast<float>(item->texture->h);
|
||||
}
|
||||
|
||||
ImageViewer::Draw(item->texture, width, height, zoom_factor, degrees, pos_x, pos_y);
|
||||
}
|
||||
|
||||
void ControlImageViewer(MenuItem *item, float *delta_time) {
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_LTRIGGER)) {
|
||||
degrees -= 90;
|
||||
|
||||
if (degrees < 0)
|
||||
degrees = 270;
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_RTRIGGER)) {
|
||||
degrees += 90;
|
||||
|
||||
if (degrees > 270)
|
||||
degrees = 0;
|
||||
}
|
||||
|
||||
// Flip horizantally
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_SQUARE)) {
|
||||
horizantal_flip = !horizantal_flip;
|
||||
width = -width;
|
||||
}
|
||||
|
||||
// Flip vertically
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_TRIANGLE)) {
|
||||
vertical_flip = !vertical_flip;
|
||||
height = -height;
|
||||
}
|
||||
|
||||
if (Utils::IsButtonHeld(PSP_CTRL_UP)) {
|
||||
zoom_factor += 0.5f * (*delta_time);
|
||||
|
||||
if (zoom_factor > 2.0f)
|
||||
zoom_factor = 2.0f;
|
||||
}
|
||||
else if (Utils::IsButtonHeld(PSP_CTRL_DOWN)) {
|
||||
zoom_factor -= 0.5f * (*delta_time);
|
||||
|
||||
if (zoom_factor < 0.5f)
|
||||
zoom_factor = 0.5f;
|
||||
|
||||
if (zoom_factor <= 1.0f) {
|
||||
pos_x = 0;
|
||||
pos_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((height * zoom_factor > 272.f) || (width * zoom_factor > 480.f)) {
|
||||
double velocity = 2.f / zoom_factor;
|
||||
if (Utils::GetAnalogY() < -0.4f)
|
||||
pos_y -= ((velocity * zoom_factor) * (*delta_time) * 1000.f);
|
||||
if (Utils::GetAnalogY() > 0.4f)
|
||||
pos_y += ((velocity * zoom_factor) * (*delta_time) * 1000.f);
|
||||
if (Utils::GetAnalogX() < -0.4f)
|
||||
pos_x -= ((velocity * zoom_factor) * (*delta_time) * 1000.f);
|
||||
if (Utils::GetAnalogX() > 0.4f)
|
||||
pos_x += ((velocity * zoom_factor) * (*delta_time) * 1000.f);
|
||||
}
|
||||
|
||||
if ((degrees == 0) || (degrees == 180)) {
|
||||
Utils::SetMax(&pos_x, horizantal_flip? -width : width, horizantal_flip? -width : width);
|
||||
Utils::SetMin(&pos_x, horizantal_flip? width : -width, horizantal_flip? width : -width);
|
||||
Utils::SetMax(&pos_y, vertical_flip? -height : height, vertical_flip? -height : height);
|
||||
Utils::SetMin(&pos_y, vertical_flip? height : -height, vertical_flip? height : -height);
|
||||
}
|
||||
else {
|
||||
Utils::SetMax(&pos_x, vertical_flip? -height : height, vertical_flip? -height : height);
|
||||
Utils::SetMin(&pos_x, vertical_flip? height : -height, vertical_flip? height : -height);
|
||||
Utils::SetMax(&pos_y, horizantal_flip? -width : width, horizantal_flip? -width : width);
|
||||
Utils::SetMin(&pos_y, horizantal_flip? width : -width, horizantal_flip? width : -width);
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
if (!properties) {
|
||||
if (item->texture)
|
||||
g2dTexFree(&item->texture);
|
||||
|
||||
zoom_factor = 1.f;
|
||||
pos_x = 0;
|
||||
pos_y = 0;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
else
|
||||
properties = false;
|
||||
}
|
||||
}
|
||||
}
|
258
app/source/gui/options.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
#include <pspctrl.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "colours.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int row = 0, column = 0;
|
||||
static bool copy = false, move = false, options_more = false;
|
||||
|
||||
namespace Options {
|
||||
static void ResetSelector(void) {
|
||||
row = 0;
|
||||
column = 0;
|
||||
}
|
||||
|
||||
static void HandleMultipleCopy(MenuItem *item, int (*func)()) {
|
||||
int ret = 0;
|
||||
std::vector<SceIoDirent> entries;
|
||||
|
||||
if (R_FAILED(ret = FS::GetDirList(item->checked_cwd.data(), entries)))
|
||||
return;
|
||||
|
||||
for (u32 i = 0; i < item->checked_copy.size(); i++) {
|
||||
if (item->checked_copy.at(i)) {
|
||||
FS::Copy(&entries[i], item->checked_cwd);
|
||||
if (R_FAILED((*func)())) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
static void CreateFolder(MenuItem *item) {
|
||||
std::string path = cfg.cwd;
|
||||
path.append("/");
|
||||
std::string name = G2D::KeyboardGetText("Enter folder name", "New folder");
|
||||
path.append(name);
|
||||
|
||||
if (R_SUCCEEDED(FS::MakeDir(path.c_str()))) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateFile(MenuItem *item) {
|
||||
std::string path = cfg.cwd;
|
||||
path.append("/");
|
||||
std::string name = G2D::KeyboardGetText("Enter file name", "New File");
|
||||
path.append(name);
|
||||
|
||||
if (R_SUCCEEDED(FS::CreateFile(path.c_str()))) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void Rename(MenuItem *item, const std::string &filename) {
|
||||
std::string src_path = cfg.cwd;
|
||||
src_path.append("/");
|
||||
src_path.append(item->entries[item->selected].d_name);
|
||||
|
||||
std::string dest_path = cfg.cwd;
|
||||
dest_path.append("/");
|
||||
std::string name = G2D::KeyboardGetText("Enter new name", filename);
|
||||
dest_path.append(name);
|
||||
|
||||
if (R_SUCCEEDED(sceIoRename(src_path.c_str(), dest_path.c_str()))) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
Options::ResetSelector();
|
||||
options_more = false;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
static void Copy(MenuItem *item) {
|
||||
if (!copy) {
|
||||
if ((item->checked_count >= 1) && (item->checked_cwd.compare(cfg.cwd) != 0))
|
||||
GUI::ResetCheckbox(item);
|
||||
if (item->checked_count <= 1)
|
||||
FS::Copy(&item->entries[item->selected], cfg.cwd);
|
||||
|
||||
copy = !copy;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
else {
|
||||
if ((item->checked_count > 1) && (item->checked_cwd.compare(cfg.cwd) != 0))
|
||||
Options::HandleMultipleCopy(item, &FS::Paste);
|
||||
else {
|
||||
if (R_SUCCEEDED(FS::Paste())) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
}
|
||||
}
|
||||
|
||||
GUI::GetStorageSize(item);
|
||||
copy = !copy;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
static void Move(MenuItem *item) {
|
||||
if (!move) {
|
||||
if ((item->checked_count >= 1) && (item->checked_cwd.compare(cfg.cwd) != 0))
|
||||
GUI::ResetCheckbox(item);
|
||||
|
||||
if (item->checked_count <= 1)
|
||||
FS::Copy(&item->entries[item->selected], cfg.cwd);
|
||||
}
|
||||
else {
|
||||
if ((item->checked_count > 1) && (item->checked_cwd.compare(cfg.cwd) != 0))
|
||||
Options::HandleMultipleCopy(item, &FS::Move);
|
||||
else if (R_SUCCEEDED(FS::Move())) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
GUI::ResetCheckbox(item);
|
||||
}
|
||||
}
|
||||
|
||||
move = !move;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
void DisplayFileOptions(MenuItem *item) {
|
||||
G2D::DrawRect(0, 18, 480, 254, G2D_RGBA(0, 0, 0, cfg.dark_theme? 50: 80));
|
||||
G2D::DrawImage(cfg.dark_theme? options_dialog_dark : options_dialog, (480 - options_dialog->w) / 2, (272 - options_dialog->h) / 2);
|
||||
G2D::FontSetStyle(font, 1.0f, TITLE_COLOUR, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, 140, 52, "Actions");
|
||||
|
||||
if (row == 0 && column == 0)
|
||||
G2D::DrawRect(132, 71, 107, 38, SELECTOR_COLOUR);
|
||||
else if (row == 1 && column == 0)
|
||||
G2D::DrawRect(241, 71, 107, 38, SELECTOR_COLOUR);
|
||||
else if (row == 0 && column == 1)
|
||||
G2D::DrawRect(132, 110, 107, 38, SELECTOR_COLOUR);
|
||||
else if (row == 1 && column == 1)
|
||||
G2D::DrawRect(241, 110, 107, 38, SELECTOR_COLOUR);
|
||||
else if (row == 0 && column == 2 && !options_more)
|
||||
G2D::DrawRect(132, 148, 107, 38, SELECTOR_COLOUR);
|
||||
else if (row == 1 && column == 2 && !options_more)
|
||||
G2D::DrawRect(241, 148, 107, 38, SELECTOR_COLOUR);
|
||||
else if (column == 3 && !options_more)
|
||||
G2D::DrawRect((340 - intraFontMeasureText(font, "CANCEL")) - 5, (230 - (font->texYSize - 6)) - 5, intraFontMeasureText(font, "CANCEL") + 10,
|
||||
(font->texYSize - 6) + 10, SELECTOR_COLOUR);
|
||||
else if (column == 2 && options_more)
|
||||
G2D::DrawRect((340 - intraFontMeasureText(font, "CANCEL")) - 5, (230 - (font->texYSize - 6)) - 5, intraFontMeasureText(font, "CANCEL") + 10,
|
||||
(font->texYSize - 6) + 10, SELECTOR_COLOUR);
|
||||
|
||||
intraFontPrint(font, 340 - intraFontMeasureText(font, "CANCEL"), 230 - (font->texYSize - 15), "CANCEL");
|
||||
G2D::FontSetStyle(font, 1.0f, TEXT_COLOUR, INTRAFONT_ALIGN_LEFT);
|
||||
|
||||
if (!options_more) {
|
||||
intraFontPrint(font, 143, 95, "Properties");
|
||||
intraFontPrint(font, 143, 133, copy? "Paste" : "Copy");
|
||||
intraFontPrint(font, 143, 171, "Delete");
|
||||
intraFontPrint(font, 247, 95, "Refresh");
|
||||
intraFontPrint(font, 247, 133, move? "Paste" : "Move");
|
||||
intraFontPrint(font, 247, 171, "More...");
|
||||
}
|
||||
else {
|
||||
intraFontPrint(font, 143, 95, "New folder");
|
||||
intraFontPrint(font, 143, 133, "Rename");
|
||||
intraFontPrint(font, 247, 95, "New file");
|
||||
}
|
||||
}
|
||||
|
||||
void ControlFileOptions(MenuItem *item, int *ctrl) {
|
||||
if (*ctrl & PSP_CTRL_RIGHT)
|
||||
row++;
|
||||
else if (*ctrl & PSP_CTRL_LEFT)
|
||||
row--;
|
||||
|
||||
if (*ctrl & PSP_CTRL_DOWN)
|
||||
column++;
|
||||
else if (*ctrl & PSP_CTRL_UP)
|
||||
column--;
|
||||
|
||||
if (!options_more) {
|
||||
Utils::SetBounds(&row, 0, 1);
|
||||
Utils::SetBounds(&column, 0, 3);
|
||||
}
|
||||
else {
|
||||
Utils::SetBounds(&column, 0, 2);
|
||||
|
||||
if (column == 1)
|
||||
Utils::SetBounds(&row, 0, 0);
|
||||
else
|
||||
Utils::SetBounds(&row, 0, 1);
|
||||
}
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_CROSS)) {
|
||||
const std::string filename = item->entries[item->selected].d_name;
|
||||
|
||||
if (row == 0) {
|
||||
if (!options_more) {
|
||||
if (column == 0)
|
||||
item->state = MENU_STATE_PROPERTIES;
|
||||
else if (column == 1)
|
||||
Options::Copy(item);
|
||||
else if (column == 2)
|
||||
item->state = MENU_STATE_DELETE;
|
||||
}
|
||||
else {
|
||||
if (column == 0)
|
||||
Options::CreateFolder(item);
|
||||
else if (column == 1)
|
||||
Options::Rename(item, filename);
|
||||
}
|
||||
}
|
||||
else if (row == 1) {
|
||||
if (!options_more) {
|
||||
if (column == 0) {
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
Options::ResetSelector();
|
||||
options_more = false;
|
||||
item->selected = 0;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
else if (column == 1)
|
||||
Options::Move(item);
|
||||
else if (column == 2) {
|
||||
Options::ResetSelector();
|
||||
options_more = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (column == 0)
|
||||
Options::CreateFile(item);
|
||||
}
|
||||
}
|
||||
if (column == 3) {
|
||||
copy = false;
|
||||
move = false;
|
||||
Options::ResetSelector();
|
||||
options_more = false;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
}
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
Options::ResetSelector();
|
||||
|
||||
if (!options_more)
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
else
|
||||
options_more = false;
|
||||
}
|
||||
}
|
||||
}
|
156
app/source/gui/settings.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include "config.h"
|
||||
#include "colours.h"
|
||||
#include "fs.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace GUI {
|
||||
enum SETTINGS_STATE {
|
||||
GENERAL_SETTINGS,
|
||||
FTP_SETTINGS,
|
||||
SORT_SETTINGS,
|
||||
ABOUT_SETTINGS
|
||||
};
|
||||
|
||||
static SETTINGS_STATE settings_state = GENERAL_SETTINGS;
|
||||
static int selection = 0;
|
||||
static const int sel_dist = 44;
|
||||
|
||||
static void DisplaySortSettings(void) {
|
||||
intraFontPrint(font, 40, 40, "Sorting Options");
|
||||
|
||||
G2D::FontSetStyle(font, 1.0f, cfg.dark_theme? WHITE : BLACK, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, 40, 72, "Alphabetical");
|
||||
intraFontPrint(font, 40, 86, "Sort alphabetically in ascending order.");
|
||||
|
||||
intraFontPrint(font, 40, 116, "Alphabetical");
|
||||
intraFontPrint(font, 40, 130, "Sort alphabetically in descending order.");
|
||||
|
||||
intraFontPrint(font, 40, 160, "Size");
|
||||
intraFontPrint(font, 40, 174, "Sort by size (largest first).");
|
||||
|
||||
intraFontPrint(font, 40, 204, "Size");
|
||||
intraFontPrint(font, 40, 218, "Sort by size (smallest first).");
|
||||
|
||||
G2D::DrawImage(cfg.sort == 0? (cfg.dark_theme? icon_radio_dark_on : icon_radio_on) : (cfg.dark_theme? icon_radio_dark_off : icon_radio_off), 425, 60);
|
||||
G2D::DrawImage(cfg.sort == 1? (cfg.dark_theme? icon_radio_dark_on : icon_radio_on) : (cfg.dark_theme? icon_radio_dark_off : icon_radio_off), 425, 104);
|
||||
G2D::DrawImage(cfg.sort == 2? (cfg.dark_theme? icon_radio_dark_on : icon_radio_on) : (cfg.dark_theme? icon_radio_dark_off : icon_radio_off), 425, 148);
|
||||
G2D::DrawImage(cfg.sort == 3? (cfg.dark_theme? icon_radio_dark_on : icon_radio_on) : (cfg.dark_theme? icon_radio_dark_off : icon_radio_off), 425, 192);
|
||||
}
|
||||
|
||||
static void ControlSortSettings(MenuItem *item, int *ctrl) {
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
cfg.sort = selection;
|
||||
Config::Save(cfg);
|
||||
FS::GetDirList(cfg.cwd, item->entries);
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
selection = 0;
|
||||
settings_state = GENERAL_SETTINGS;
|
||||
}
|
||||
|
||||
Utils::SetBounds(&selection, 0, 3);
|
||||
}
|
||||
|
||||
static void DisplayGeneralSettings(void) {
|
||||
intraFontPrint(font, 40, 40, "Settings");
|
||||
|
||||
G2D::FontSetStyle(font, 1.0f, cfg.dark_theme? WHITE : BLACK, INTRAFONT_ALIGN_LEFT);
|
||||
intraFontPrint(font, 40, 72, "FTP connection");
|
||||
intraFontPrint(font, 40, 86, "Wireless connection");
|
||||
|
||||
intraFontPrint(font, 40, 116, "Sorting options");
|
||||
intraFontPrint(font, 40, 130, "Select between various sorting options.");
|
||||
|
||||
intraFontPrint(font, 40, 160, "Dark theme");
|
||||
intraFontPrint(font, 40, 174, "Enables dark theme mode.");
|
||||
|
||||
intraFontPrint(font, 40, 204, "Developer options");
|
||||
intraFontPrint(font, 40, 218, "Enable logging and fs access to NAND.");
|
||||
|
||||
intraFontPrint(font, 40, 248, "About");
|
||||
intraFontPrint(font, 40, 262, "Application and device info");
|
||||
|
||||
if (cfg.dark_theme)
|
||||
G2D::DrawImage(cfg.dark_theme? icon_toggle_dark_on : icon_toggle_on, 415, 143);
|
||||
else
|
||||
G2D::DrawImage(icon_toggle_off, 415, 143);
|
||||
|
||||
G2D::DrawImage(cfg.dev_options? (cfg.dark_theme? icon_toggle_dark_on : icon_toggle_on) : icon_toggle_off, 415, 187);
|
||||
}
|
||||
|
||||
static void ControlGeneralSettings(MenuItem *item, int *ctrl) {
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_ENTER)) {
|
||||
switch(selection) {
|
||||
case 1:
|
||||
settings_state = SORT_SETTINGS;
|
||||
selection = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cfg.dark_theme = !cfg.dark_theme;
|
||||
Colours::Get();
|
||||
Config::Save(cfg);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cfg.dev_options = !cfg.dev_options;
|
||||
Config::Save(cfg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Utils::IsButtonPressed(PSP_CTRL_CANCEL)) {
|
||||
selection = 0;
|
||||
item->state = MENU_STATE_FILEBROWSER;
|
||||
}
|
||||
|
||||
Utils::SetBounds(&selection, 0, 4);
|
||||
}
|
||||
|
||||
void DisplaySettings(MenuItem *item) {
|
||||
G2D::DrawRect(0, 18, 480, 34, MENU_BAR_COLOUR);
|
||||
G2D::DrawRect(0, 52, 480, 220, BG_COLOUR);
|
||||
G2D::DrawImage(icon_back, 5, 20);
|
||||
|
||||
G2D::DrawRect(0, 52 + (selection * sel_dist), 480, sel_dist, SELECTOR_COLOUR);
|
||||
G2D::FontSetStyle(font, 1.0f, WHITE, INTRAFONT_ALIGN_LEFT);
|
||||
|
||||
switch(settings_state) {
|
||||
case GENERAL_SETTINGS:
|
||||
DisplayGeneralSettings();
|
||||
break;
|
||||
|
||||
case SORT_SETTINGS:
|
||||
DisplaySortSettings();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ControlSettings(MenuItem *item, int *ctrl) {
|
||||
if (*ctrl & PSP_CTRL_UP)
|
||||
selection--;
|
||||
else if (*ctrl & PSP_CTRL_DOWN)
|
||||
selection++;
|
||||
|
||||
switch(settings_state) {
|
||||
case GENERAL_SETTINGS:
|
||||
ControlGeneralSettings(item, ctrl);
|
||||
break;
|
||||
|
||||
case SORT_SETTINGS:
|
||||
ControlSortSettings(item, ctrl);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
27
app/source/kernel_functions.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "kernel_functions.h"
|
||||
|
||||
// audio_driver functions
|
||||
int pspAudioSetFrequency(int frequency);
|
||||
|
||||
// display driver functions
|
||||
int pspGetBrightness(int *brightness);
|
||||
int pspSetBrightness(int brightness);
|
||||
int pspDisplayEnable(void);
|
||||
int pspDisplayDisable(void);
|
||||
|
||||
// fs_driver functions
|
||||
int pspOpenDir(const char *dirname);
|
||||
int pspReadDir(SceUID dir, SceIoDirent *dirent);
|
||||
int pspCloseDir(SceUID dir);
|
||||
|
||||
// impose_driver functions
|
||||
int pspGetVolume(void);
|
||||
int pspSetVolume(int volume);
|
||||
int pspGetMute(void);
|
||||
int pspSetMute(int mute);
|
||||
int pspGetEqualizerMode(void);
|
||||
int pspSetEqualizerMode(int mode);
|
||||
int pspSetHomePopup(int popup);
|
||||
|
||||
// input_driver functions
|
||||
unsigned int pspGetButtons(void);
|
47
app/source/log.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <pspiofilemgr.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Log {
|
||||
SceUID log_handle = 0;
|
||||
|
||||
int OpenHande(void) {
|
||||
if (R_FAILED(log_handle = sceIoOpen("debug.log", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_APPEND, 0777)))
|
||||
return log_handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CloseHandle(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceIoClose(log_handle)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Error(const char *format, ...) {
|
||||
if (!cfg.dev_options)
|
||||
return -1;
|
||||
|
||||
va_list list;
|
||||
char string[512] = {0};
|
||||
|
||||
va_start(list, format);
|
||||
std::vsprintf(string, format, list);
|
||||
va_end(list);
|
||||
|
||||
std::printf("%s", string);
|
||||
|
||||
int ret = 0;
|
||||
if (R_FAILED(ret = sceIoWrite(log_handle, string, std::strlen(string))))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
64
app/source/main.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <pspctrl.h>
|
||||
#include <pspkernel.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "g2d.h"
|
||||
#include "gui.h"
|
||||
#include "log.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
PSP_MODULE_INFO("CMFileManager", 0x800, VERSION_MAJOR, VERSION_MINOR);
|
||||
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
|
||||
PSP_HEAP_SIZE_MAX();
|
||||
|
||||
namespace Services {
|
||||
int Init(void) {
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
Log::OpenHande();
|
||||
Utils::InitKernelDrivers();
|
||||
Textures::Load();
|
||||
|
||||
int ret = 0;
|
||||
if (R_FAILED(ret = Config::Load())) {
|
||||
Log::Error("Config::Load failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = intraFontInit())) {
|
||||
Log::Error("intraFontInit failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
font = intraFontLoad("flash0:/font/ltn8.pgf", 0);
|
||||
jpn0 = intraFontLoad("flash0:/font/jpn0.pgf", INTRAFONT_STRING_UTF8);
|
||||
chn = intraFontLoad("flash0:/font/gb3s1518.bwfon", 0);
|
||||
intraFontSetAltFont(font, jpn0);
|
||||
intraFontSetAltFont(jpn0, chn);
|
||||
intraFontSetEncoding(font, INTRAFONT_STRING_UTF8);
|
||||
|
||||
Utils::IsMemCardInserted(&is_ms_inserted);
|
||||
is_psp_go = Utils::IsModelPSPGo();
|
||||
|
||||
PSP_CTRL_ENTER = static_cast<enum PspCtrlButtons>(Utils::GetEnterButton());
|
||||
PSP_CTRL_CANCEL = static_cast<enum PspCtrlButtons>(Utils::GetCancelButton());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
intraFontUnload(chn);
|
||||
intraFontUnload(jpn0);
|
||||
intraFontUnload(font);
|
||||
Textures::Free();
|
||||
Log::CloseHandle();
|
||||
Utils::TermKernelDrivers();
|
||||
sceKernelExitGame();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
Services::Init();
|
||||
GUI::RenderLoop();
|
||||
Services::Exit();
|
||||
}
|
156
app/source/textures.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include "textures.h"
|
||||
|
||||
extern unsigned char ic_fso_type_app_png_start[], ic_fso_type_compress_png_start[], ic_fso_type_audio_png_start[],
|
||||
ic_fso_folder_png_start[], ic_fso_folder_dark_png_start[], ic_fso_default_png_start[], ic_fso_type_image_png_start[],
|
||||
ic_fso_type_text_png_start[], btn_material_light_check_on_normal_png_start[], btn_material_light_check_on_normal_dark_png_start[],
|
||||
btn_material_light_check_off_normal_png_start[], btn_material_light_check_off_normal_dark_png_start[], btn_material_light_toggle_on_normal_png_start[],
|
||||
btn_material_light_toggle_on_normal_dark_png_start[], btn_material_light_toggle_off_normal_png_start[], btn_material_light_radio_off_normal_png_start[],
|
||||
btn_material_light_radio_on_normal_png_start[], btn_material_light_radio_off_normal_dark_png_start[], btn_material_light_radio_on_normal_dark_png_start[],
|
||||
ic_material_light_navigation_drawer_png_start[], ic_arrow_back_normal_png_start[], ic_material_options_dialog_png_start[],
|
||||
ic_material_options_dialog_dark_png_start[], ic_material_properties_dialog_png_start[], ic_material_properties_dialog_dark_png_start[],
|
||||
ic_material_dialog_png_start[], ic_material_dialog_dark_png_start[], battery_20_png_start[], battery_20_charging_png_start[], battery_30_png_start[],
|
||||
battery_30_charging_png_start[], battery_50_png_start[], battery_50_charging_png_start[], battery_60_png_start[], battery_60_charging_png_start[],
|
||||
battery_80_png_start[], battery_80_charging_png_start[], battery_full_png_start[], battery_full_charging_png_start[], ic_material_light_usb_png_start[],
|
||||
default_artwork_png_start[], default_artwork_blur_png_start[], btn_playback_play_png_start[], btn_playback_pause_png_start[],
|
||||
btn_playback_rewind_png_start[], btn_playback_forward_png_start[], btn_playback_repeat_png_start[], btn_playback_shuffle_png_start[],
|
||||
btn_playback_repeat_overlay_png_start[], btn_playback_shuffle_overlay_png_start[], bg_header_png_start[], ic_material_light_sdcard_png_start[],
|
||||
ic_material_light_secure_png_start[], ic_material_light_sdcard_dark_png_start[], ic_material_light_secure_dark_png_start[], ic_play_btn_png_start[];
|
||||
|
||||
extern unsigned int ic_fso_type_app_png_size, ic_fso_type_compress_png_size, ic_fso_type_audio_png_size, ic_fso_folder_png_size,
|
||||
ic_fso_folder_dark_png_size, ic_fso_default_png_size, ic_fso_type_image_png_size, ic_fso_type_text_png_size,
|
||||
btn_material_light_check_on_normal_png_size, btn_material_light_check_on_normal_dark_png_size, btn_material_light_check_off_normal_png_size,
|
||||
btn_material_light_check_off_normal_dark_png_size, btn_material_light_toggle_on_normal_png_size, btn_material_light_toggle_on_normal_dark_png_size,
|
||||
btn_material_light_toggle_off_normal_png_size, btn_material_light_radio_off_normal_png_size, btn_material_light_radio_on_normal_png_size,
|
||||
btn_material_light_radio_off_normal_dark_png_size, btn_material_light_radio_on_normal_dark_png_size, ic_material_light_navigation_drawer_png_size,
|
||||
ic_arrow_back_normal_png_size, ic_material_options_dialog_png_size, ic_material_options_dialog_dark_png_size, ic_material_properties_dialog_png_size,
|
||||
ic_material_properties_dialog_dark_png_size, ic_material_dialog_png_size, ic_material_dialog_dark_png_size, battery_20_png_size,
|
||||
battery_20_charging_png_size, battery_30_png_size, battery_30_charging_png_size, battery_50_png_size, battery_50_charging_png_size,
|
||||
battery_60_png_size, battery_60_charging_png_size, battery_80_png_size, battery_80_charging_png_size, battery_full_png_size,
|
||||
battery_full_charging_png_size, ic_material_light_usb_png_size,
|
||||
default_artwork_png_size, default_artwork_blur_png_size, btn_playback_play_png_size, btn_playback_pause_png_size, btn_playback_rewind_png_size,
|
||||
btn_playback_forward_png_size, btn_playback_repeat_png_size, btn_playback_shuffle_png_size, btn_playback_repeat_overlay_png_size,
|
||||
btn_playback_shuffle_overlay_png_size, bg_header_png_size, ic_material_light_sdcard_png_size, ic_material_light_secure_png_size,
|
||||
ic_material_light_sdcard_dark_png_size, ic_material_light_secure_dark_png_size, ic_play_btn_png_size;
|
||||
|
||||
g2dTexture *file_icons[NUM_ICONS], *icon_dir, *icon_dir_dark, *icon_check, *icon_check_dark, *icon_uncheck, \
|
||||
*icon_uncheck_dark, *icon_toggle_on, *icon_toggle_dark_on, *icon_toggle_off, *icon_radio_off, \
|
||||
*icon_radio_on, *icon_radio_dark_off, *icon_radio_dark_on, *icon_nav_drawer, *icon_back, \
|
||||
*options_dialog, *options_dialog_dark, *properties_dialog, *properties_dialog_dark, *dialog, *dialog_dark, \
|
||||
*battery_charging[NUM_BATT_ICONS], *battery[NUM_BATT_ICONS], *usb_icon, \
|
||||
*default_artwork, *default_artwork_blur, *btn_play, *btn_pause, *btn_rewind, *btn_forward, \
|
||||
*btn_repeat, *btn_shuffle, *btn_repeat_overlay, *btn_shuffle_overlay, \
|
||||
*bg_header, *icon_sd, *icon_secure, *icon_sd_dark, *icon_secure_dark, *ic_play_btn;
|
||||
|
||||
namespace Textures {
|
||||
void Load(void) {
|
||||
file_icons[0] = g2dTexLoadMemory(ic_fso_default_png_start, ic_fso_default_png_size, G2D_SWIZZLE);
|
||||
file_icons[1] = g2dTexLoadMemory(ic_fso_type_app_png_start, ic_fso_type_app_png_size, G2D_SWIZZLE);
|
||||
file_icons[2] = g2dTexLoadMemory(ic_fso_type_compress_png_start, ic_fso_type_compress_png_size, G2D_SWIZZLE);
|
||||
file_icons[3] = g2dTexLoadMemory(ic_fso_type_audio_png_start, ic_fso_type_audio_png_size, G2D_SWIZZLE);
|
||||
file_icons[4] = g2dTexLoadMemory(ic_fso_type_image_png_start, ic_fso_type_image_png_size, G2D_SWIZZLE);
|
||||
file_icons[5] = g2dTexLoadMemory(ic_fso_type_text_png_start, ic_fso_type_text_png_size, G2D_SWIZZLE);
|
||||
|
||||
icon_dir = g2dTexLoadMemory(ic_fso_folder_png_start, ic_fso_folder_png_size, G2D_SWIZZLE);
|
||||
icon_dir_dark = g2dTexLoadMemory(ic_fso_folder_dark_png_start, ic_fso_folder_dark_png_size, G2D_SWIZZLE);
|
||||
icon_check = g2dTexLoadMemory(btn_material_light_check_on_normal_png_start, btn_material_light_check_on_normal_png_size, G2D_SWIZZLE);
|
||||
icon_check_dark = g2dTexLoadMemory(btn_material_light_check_on_normal_dark_png_start, btn_material_light_check_on_normal_dark_png_size, G2D_SWIZZLE);
|
||||
icon_uncheck = g2dTexLoadMemory(btn_material_light_check_off_normal_png_start, btn_material_light_check_off_normal_png_size, G2D_SWIZZLE);
|
||||
icon_uncheck_dark = g2dTexLoadMemory(btn_material_light_check_off_normal_dark_png_start, btn_material_light_check_off_normal_dark_png_size, G2D_SWIZZLE);
|
||||
icon_toggle_on = g2dTexLoadMemory(btn_material_light_toggle_on_normal_png_start, btn_material_light_toggle_on_normal_png_size, G2D_SWIZZLE);
|
||||
icon_toggle_dark_on = g2dTexLoadMemory(btn_material_light_toggle_on_normal_dark_png_start, btn_material_light_toggle_on_normal_dark_png_size, G2D_SWIZZLE);
|
||||
icon_toggle_off = g2dTexLoadMemory(btn_material_light_toggle_off_normal_png_start, btn_material_light_toggle_off_normal_png_size, G2D_SWIZZLE);
|
||||
icon_radio_off = g2dTexLoadMemory(btn_material_light_radio_off_normal_png_start, btn_material_light_radio_off_normal_png_size, G2D_SWIZZLE);
|
||||
icon_radio_on = g2dTexLoadMemory(btn_material_light_radio_on_normal_png_start, btn_material_light_radio_on_normal_png_size, G2D_SWIZZLE);
|
||||
icon_radio_dark_off = g2dTexLoadMemory(btn_material_light_radio_off_normal_dark_png_start, btn_material_light_radio_off_normal_dark_png_size, G2D_SWIZZLE);
|
||||
icon_radio_dark_on = g2dTexLoadMemory(btn_material_light_radio_on_normal_dark_png_start, btn_material_light_radio_on_normal_dark_png_size, G2D_SWIZZLE);
|
||||
icon_nav_drawer = g2dTexLoadMemory(ic_material_light_navigation_drawer_png_start, ic_material_light_navigation_drawer_png_size, G2D_SWIZZLE);
|
||||
icon_back = g2dTexLoadMemory(ic_arrow_back_normal_png_start, ic_arrow_back_normal_png_size, G2D_SWIZZLE);
|
||||
options_dialog = g2dTexLoadMemory(ic_material_options_dialog_png_start, ic_material_options_dialog_png_size, G2D_SWIZZLE);
|
||||
options_dialog_dark = g2dTexLoadMemory(ic_material_options_dialog_dark_png_start, ic_material_options_dialog_dark_png_size, G2D_SWIZZLE);
|
||||
properties_dialog = g2dTexLoadMemory(ic_material_properties_dialog_png_start, ic_material_properties_dialog_png_size, G2D_SWIZZLE);
|
||||
properties_dialog_dark = g2dTexLoadMemory(ic_material_properties_dialog_dark_png_start, ic_material_properties_dialog_dark_png_size, G2D_SWIZZLE);
|
||||
dialog = g2dTexLoadMemory(ic_material_dialog_png_start, ic_material_dialog_png_size, G2D_SWIZZLE);
|
||||
dialog_dark = g2dTexLoadMemory(ic_material_dialog_dark_png_start, ic_material_dialog_dark_png_size, G2D_SWIZZLE);
|
||||
|
||||
battery_charging[0] = g2dTexLoadMemory(battery_20_charging_png_start, battery_20_charging_png_size, G2D_SWIZZLE);
|
||||
battery_charging[1] = g2dTexLoadMemory(battery_30_charging_png_start, battery_30_charging_png_size, G2D_SWIZZLE);
|
||||
battery_charging[2] = g2dTexLoadMemory(battery_50_charging_png_start, battery_50_charging_png_size, G2D_SWIZZLE);
|
||||
battery_charging[3] = g2dTexLoadMemory(battery_60_charging_png_start, battery_60_charging_png_size, G2D_SWIZZLE);
|
||||
battery_charging[4] = g2dTexLoadMemory(battery_80_charging_png_start, battery_80_charging_png_size, G2D_SWIZZLE);
|
||||
battery_charging[5] = g2dTexLoadMemory(battery_full_charging_png_start, battery_full_charging_png_size, G2D_SWIZZLE);
|
||||
|
||||
battery[0] = g2dTexLoadMemory(battery_20_png_start, battery_30_png_size, G2D_SWIZZLE);
|
||||
battery[1] = g2dTexLoadMemory(battery_30_png_start, battery_30_png_size, G2D_SWIZZLE);
|
||||
battery[2] = g2dTexLoadMemory(battery_50_png_start, battery_50_png_size, G2D_SWIZZLE);
|
||||
battery[3] = g2dTexLoadMemory(battery_60_png_start, battery_60_png_size, G2D_SWIZZLE);
|
||||
battery[4] = g2dTexLoadMemory(battery_80_png_start, battery_80_png_size, G2D_SWIZZLE);
|
||||
battery[5] = g2dTexLoadMemory(battery_full_png_start, battery_full_png_size, G2D_SWIZZLE);
|
||||
|
||||
usb_icon = g2dTexLoadMemory(ic_material_light_usb_png_start, ic_material_light_usb_png_size, G2D_SWIZZLE);
|
||||
default_artwork = g2dTexLoadMemory(default_artwork_png_start, default_artwork_png_size, G2D_SWIZZLE);
|
||||
default_artwork_blur = g2dTexLoadMemory(default_artwork_blur_png_start, default_artwork_blur_png_size, G2D_SWIZZLE);
|
||||
btn_play = g2dTexLoadMemory(btn_playback_play_png_start, btn_playback_play_png_size, G2D_SWIZZLE);
|
||||
btn_pause = g2dTexLoadMemory(btn_playback_pause_png_start, btn_playback_pause_png_size, G2D_SWIZZLE);
|
||||
btn_rewind = g2dTexLoadMemory(btn_playback_rewind_png_start, btn_playback_rewind_png_size, G2D_SWIZZLE);
|
||||
btn_forward = g2dTexLoadMemory(btn_playback_forward_png_start, btn_playback_forward_png_size, G2D_SWIZZLE);
|
||||
btn_repeat = g2dTexLoadMemory(btn_playback_repeat_png_start, btn_playback_repeat_png_size, G2D_SWIZZLE);
|
||||
btn_shuffle = g2dTexLoadMemory(btn_playback_shuffle_png_start, btn_playback_shuffle_png_size, G2D_SWIZZLE);
|
||||
btn_repeat_overlay = g2dTexLoadMemory(btn_playback_repeat_overlay_png_start, btn_playback_repeat_overlay_png_size, G2D_SWIZZLE);
|
||||
btn_shuffle_overlay = g2dTexLoadMemory(btn_playback_shuffle_overlay_png_start, btn_playback_shuffle_overlay_png_size, G2D_SWIZZLE);
|
||||
bg_header = g2dTexLoadMemory(bg_header_png_start, bg_header_png_size, G2D_SWIZZLE);
|
||||
icon_sd = g2dTexLoadMemory(ic_material_light_sdcard_png_start, ic_material_light_sdcard_png_size, G2D_SWIZZLE);
|
||||
icon_secure = g2dTexLoadMemory(ic_material_light_secure_png_start, ic_material_light_secure_png_size, G2D_SWIZZLE);
|
||||
icon_sd_dark = g2dTexLoadMemory(ic_material_light_sdcard_dark_png_start, ic_material_light_sdcard_dark_png_size, G2D_SWIZZLE);
|
||||
icon_secure_dark = g2dTexLoadMemory(ic_material_light_secure_dark_png_start, ic_material_light_secure_dark_png_size, G2D_SWIZZLE);
|
||||
ic_play_btn = g2dTexLoadMemory(ic_play_btn_png_start, ic_play_btn_png_size, G2D_SWIZZLE);
|
||||
}
|
||||
|
||||
void Free(void) {
|
||||
g2dTexFree(&ic_play_btn);
|
||||
g2dTexFree(&icon_secure_dark);
|
||||
g2dTexFree(&icon_sd_dark);
|
||||
g2dTexFree(&icon_secure);
|
||||
g2dTexFree(&icon_sd);
|
||||
g2dTexFree(&bg_header);
|
||||
g2dTexFree(&btn_shuffle_overlay);
|
||||
g2dTexFree(&btn_repeat_overlay);
|
||||
g2dTexFree(&btn_shuffle);
|
||||
g2dTexFree(&btn_repeat);
|
||||
g2dTexFree(&btn_forward);
|
||||
g2dTexFree(&btn_rewind);
|
||||
g2dTexFree(&btn_pause);
|
||||
g2dTexFree(&btn_play);
|
||||
g2dTexFree(&default_artwork_blur);
|
||||
g2dTexFree(&default_artwork);
|
||||
g2dTexFree(&usb_icon);
|
||||
g2dTexFree(&dialog_dark);
|
||||
g2dTexFree(&dialog);
|
||||
g2dTexFree(&properties_dialog_dark);
|
||||
g2dTexFree(&properties_dialog);
|
||||
g2dTexFree(&options_dialog_dark);
|
||||
g2dTexFree(&options_dialog);
|
||||
g2dTexFree(&icon_back);
|
||||
g2dTexFree(&icon_nav_drawer);
|
||||
g2dTexFree(&icon_radio_dark_on);
|
||||
g2dTexFree(&icon_radio_dark_off);
|
||||
g2dTexFree(&icon_radio_on);
|
||||
g2dTexFree(&icon_radio_off);
|
||||
g2dTexFree(&icon_toggle_off);
|
||||
g2dTexFree(&icon_toggle_dark_on);
|
||||
g2dTexFree(&icon_toggle_on);
|
||||
g2dTexFree(&icon_uncheck_dark);
|
||||
g2dTexFree(&icon_uncheck);
|
||||
g2dTexFree(&icon_check_dark);
|
||||
g2dTexFree(&icon_check);
|
||||
g2dTexFree(&icon_dir_dark);
|
||||
g2dTexFree(&icon_dir);
|
||||
|
||||
for (int i = 0; i < NUM_ICONS; i++)
|
||||
g2dTexFree(&file_icons[i]);
|
||||
|
||||
for (int i = 0; i < NUM_BATT_ICONS; i++) {
|
||||
g2dTexFree(&battery_charging[i]);
|
||||
g2dTexFree(&battery[i]);
|
||||
}
|
||||
}
|
||||
}
|
435
app/source/utils.cpp
Normal file
@ -0,0 +1,435 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <pspkernel.h>
|
||||
#include <pspreg.h>
|
||||
#include <pspusb.h>
|
||||
#include <pspusbstor.h>
|
||||
#include <vector>
|
||||
|
||||
#include "config.h"
|
||||
#include "kernel_functions.h"
|
||||
#include "kubridge.h"
|
||||
#include "log.h"
|
||||
#include "pspusbdevice.h"
|
||||
#include "systemctrl.h"
|
||||
#include "systemctrl_se.h"
|
||||
#include "utils.h"
|
||||
|
||||
bool psp_usb_cable_connection = false, is_ms_inserted = false, is_psp_go = false;
|
||||
enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
|
||||
BROWSE_STATE device = BROWSE_STATE_EXTERNAL;
|
||||
|
||||
namespace Utils {
|
||||
constexpr unsigned int CTRL_DEADZONE_DELAY = 500000;
|
||||
constexpr unsigned int CTRL_DELAY = 100000;
|
||||
|
||||
static SceCtrlData pad, kernel_pad, prev_pad;
|
||||
static unsigned int last_button = 0;
|
||||
static int last_button_tick = 0, deadzone_tick = 0;
|
||||
static bool usb_module_loaded = false;
|
||||
static bool usb_actived = false;
|
||||
|
||||
typedef struct {
|
||||
const char *path = nullptr;
|
||||
int id = 0;
|
||||
} Module;
|
||||
|
||||
static std::vector<Module> kernel_modules {
|
||||
{ "audio_driver.prx", -1, },
|
||||
{ "display_driver.prx", -1, },
|
||||
{ "fs_driver.prx", -1, },
|
||||
{ "impose_driver.prx", -1, },
|
||||
{ "input_driver.prx", -1, }
|
||||
};
|
||||
|
||||
static std::vector<Module> usb_modules {
|
||||
{ "flash0:/kd/_usbdevice.prx", -1, },
|
||||
{ "flash0:/kd/semawm.prx", -1, },
|
||||
{ "flash0:/kd/usbstor.prx", -1, },
|
||||
{ "flash0:/kd/usbstormgr.prx", -1, },
|
||||
{ "flash0:/kd/usbstorms.prx", -1, },
|
||||
{ "flash0:/kd/usbstoreflash.prx", -1, },
|
||||
{ "flash0:/kd/usbstorboot.prx", -1, }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned long maxclusters = 0;
|
||||
unsigned long freeclusters = 0;
|
||||
int unk1 = 0;
|
||||
unsigned int sectorsize = 0;
|
||||
u64 sectorcount = 0;
|
||||
} SystemDevCtl;
|
||||
|
||||
typedef struct {
|
||||
SystemDevCtl *pdevinf;
|
||||
} SystemDevCommand;
|
||||
|
||||
void SetBounds(int *set, int min, int max) {
|
||||
if (*set > max)
|
||||
*set = min;
|
||||
else if (*set < min)
|
||||
*set = max;
|
||||
}
|
||||
|
||||
void SetMax(int *set, int value, int max) {
|
||||
if (*set > max)
|
||||
*set = value;
|
||||
}
|
||||
|
||||
void SetMin(int *set, int value, int min) {
|
||||
if (*set < min)
|
||||
*set = value;
|
||||
}
|
||||
|
||||
void GetSizeString(char *string, double size) {
|
||||
int i = 0;
|
||||
const char *units[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
|
||||
|
||||
while (size >= 1024.0f) {
|
||||
size /= 1024.0f;
|
||||
i++;
|
||||
}
|
||||
|
||||
std::sprintf(string, "%.*f %s", (i == 0) ? 0 : 2, size, units[i]);
|
||||
}
|
||||
|
||||
static int LoadStartModule(const char *path) {
|
||||
int ret = 0, status = 0;
|
||||
SceUID modID = 0;
|
||||
|
||||
if (R_FAILED(ret = modID = kuKernelLoadModule(path, 0, nullptr))) {
|
||||
Log::Error("kuKernelLoadModule(%s) failed: 0x%lx\n", path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceKernelStartModule(modID, 0, nullptr, &status, nullptr))) {
|
||||
Log::Error("sceKernelStartModule(%s) failed: 0x%lx\n", path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void StopUnloadModules(SceUID modID) {
|
||||
sceKernelStopModule(modID, 0, nullptr, nullptr, nullptr);
|
||||
sceKernelUnloadModule(modID);
|
||||
}
|
||||
|
||||
static int InitUSB(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (!usb_module_loaded) {
|
||||
for (unsigned int i = 0; i < usb_modules.size(); ++i)
|
||||
usb_modules[i].id = Utils::LoadStartModule(usb_modules[i].path);
|
||||
|
||||
usb_module_loaded = true;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceUsbStart(PSP_USBBUS_DRIVERNAME, 0, 0))) {
|
||||
Log::Error("sceUsbStart(PSP_USBBUS_DRIVERNAME) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceUsbStart(PSP_USBSTOR_DRIVERNAME, 0, 0))) {
|
||||
Log::Error("sceUsbStart(PSP_USBSTOR_DRIVERNAME) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceUsbstorBootSetCapacity(0x800000))) {
|
||||
Log::Error("sceUsbstorBootSetCapacity(0x800000) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_actived = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StartUSBStorage(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceUsbActivate(0x1c8))) {
|
||||
Log::Error("sceUsbActivate(0x1c8) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
psp_usb_cable_connection = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StopUSBStorage(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (R_FAILED(ret = sceUsbDeactivate(0x1c8))) {
|
||||
Log::Error("sceUsbActivate(0x1c8) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceIoDevctl("fatms0:", 0x0240D81E, nullptr, 0, nullptr, 0))) { // Avoid corrupted files
|
||||
Log::Error("sceIoDevctl(\"fatms0:\", 0x0240D81E, nullptr, 0, nullptr, 0) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
psp_usb_cable_connection = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DisableUSB(void) {
|
||||
int ret = 0;
|
||||
|
||||
if (!usb_actived)
|
||||
return -1;
|
||||
|
||||
if (R_FAILED(ret = Utils::StopUSBStorage()))
|
||||
return ret;
|
||||
|
||||
if (R_FAILED(ret = sceUsbStop(PSP_USBSTOR_DRIVERNAME, 0, 0))) {
|
||||
Log::Error("sceUsbStop(PSP_USBSTOR_DRIVERNAME) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceUsbStop(PSP_USBBUS_DRIVERNAME, 0, 0))) {
|
||||
Log::Error("sceUsbStop(PSP_USBBUS_DRIVERNAME) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = pspUsbDeviceFinishDevice())) {
|
||||
Log::Error("pspUsbDeviceFinishDevice() failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_actived = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ExitUSB(void) {
|
||||
Utils::DisableUSB();
|
||||
|
||||
if (usb_module_loaded) {
|
||||
for (int i = usb_modules.size() - 1; i >= 0; --i) {
|
||||
Utils::StopUnloadModules(usb_modules[i].id);
|
||||
usb_modules[i].id = -1;
|
||||
}
|
||||
|
||||
usb_module_loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InitKernelDrivers(void) {
|
||||
for (unsigned int i = 0; i < kernel_modules.size(); ++i)
|
||||
kernel_modules[i].id = Utils::LoadStartModule(kernel_modules[i].path);
|
||||
|
||||
Utils::InitUSB();
|
||||
}
|
||||
|
||||
void TermKernelDrivers(void) {
|
||||
for (int i = kernel_modules.size() - 1; i >= 0; --i) {
|
||||
Utils::StopUnloadModules(kernel_modules[i].id);
|
||||
kernel_modules[i].id = -1;
|
||||
}
|
||||
|
||||
Utils::ExitUSB();
|
||||
}
|
||||
|
||||
void UpdateUSB(void) {
|
||||
if (sceUsbGetState() & PSP_USB_CABLE_CONNECTED) {
|
||||
if (psp_usb_cable_connection == false)
|
||||
Utils::StartUSBStorage();
|
||||
}
|
||||
else {
|
||||
if (psp_usb_cable_connection == true)
|
||||
Utils::StopUSBStorage();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsModelPSPGo(void) {
|
||||
return (kuKernelGetModel() == 4);
|
||||
}
|
||||
|
||||
int IsMemCardInserted(bool *is_inserted) {
|
||||
int status = 0, ret = 0;
|
||||
if (R_FAILED(ret = sceIoDevctl("mscmhc0:", 0x02025806, 0, 0, &status, sizeof(status))))
|
||||
return ret;
|
||||
|
||||
if (status != 1)
|
||||
*is_inserted = false;
|
||||
else
|
||||
*is_inserted = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsEF0(void) {
|
||||
if (is_psp_go) {
|
||||
if (!is_ms_inserted)
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int LaunchEboot(const char *path) {
|
||||
int ret = 0;
|
||||
struct SceKernelLoadExecVSHParam param;
|
||||
std::memset(¶m, 0, sizeof(param));
|
||||
|
||||
param.size = sizeof(param);
|
||||
param.args = std::strlen(path) + 1;
|
||||
param.argp = (void *)path;
|
||||
param.key = "game";
|
||||
|
||||
if (R_FAILED(ret = sctrlKernelLoadExecVSHWithApitype(IsEF0()? 0x152 : 0x141, path, ¶m))) {
|
||||
Log::Error("sctrlKernelLoadExecVSHWithApitype(%x, %s) failed: 0x%lx\n", IsEF0()? 0x152 : 0x141, path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 GetTotalStorage(void) {
|
||||
int ret = 0;
|
||||
SystemDevCtl devctl;
|
||||
SystemDevCommand command;
|
||||
command.pdevinf = &devctl;
|
||||
|
||||
if (R_FAILED(ret = sceIoDevctl(device == BROWSE_STATE_INTERNAL? "ef0": "ms0:", 0x02425818, &command, sizeof(SystemDevCommand), nullptr, 0)))
|
||||
return 0;
|
||||
|
||||
u64 size = (devctl.maxclusters * devctl.sectorcount) * devctl.sectorsize;
|
||||
return size;
|
||||
}
|
||||
|
||||
u64 GetFreeStorage(void) {
|
||||
int ret = 0;
|
||||
SystemDevCtl devctl;
|
||||
SystemDevCommand command;
|
||||
command.pdevinf = &devctl;
|
||||
|
||||
if (R_FAILED(ret = sceIoDevctl(device == BROWSE_STATE_INTERNAL? "ef0": "ms0:", 0x02425818, &command, sizeof(SystemDevCommand), nullptr, 0)))
|
||||
return 0;
|
||||
|
||||
u64 size = (devctl.freeclusters * devctl.sectorcount) * devctl.sectorsize;
|
||||
return size;
|
||||
}
|
||||
|
||||
u64 GetUsedStorage(void) {
|
||||
return (Utils::GetTotalStorage() - Utils::GetFreeStorage());
|
||||
}
|
||||
|
||||
static int GetRegistryValue(const char *dir, const char *name, unsigned int *value) {
|
||||
int ret = 0;
|
||||
struct RegParam reg;
|
||||
REGHANDLE h;
|
||||
|
||||
std::memset(®, 0, sizeof(reg));
|
||||
reg.regtype = 1;
|
||||
reg.namelen = std::strlen("/system");
|
||||
reg.unk2 = 1;
|
||||
reg.unk3 = 1;
|
||||
std::strcpy(reg.name, "/system");
|
||||
|
||||
if (R_SUCCEEDED(sceRegOpenRegistry(®, 2, &h))) {
|
||||
REGHANDLE hd;
|
||||
|
||||
if (R_SUCCEEDED(sceRegOpenCategory(h, dir, 2, &hd))) {
|
||||
REGHANDLE hk;
|
||||
unsigned int type, size;
|
||||
|
||||
if (R_SUCCEEDED(sceRegGetKeyInfo(hd, name, &hk, &type, &size))) {
|
||||
if (!sceRegGetKeyValue(hd, hk, value, 4)) {
|
||||
ret = 1;
|
||||
sceRegFlushCategory(hd);
|
||||
}
|
||||
}
|
||||
|
||||
sceRegCloseCategory(hd);
|
||||
}
|
||||
|
||||
sceRegFlushRegistry(h);
|
||||
sceRegCloseRegistry(h);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ReadControls(void) {
|
||||
prev_pad = pad;
|
||||
kernel_pad.Buttons = pspGetButtons();
|
||||
sceCtrlReadBufferPositive(&pad, 1);
|
||||
|
||||
if (pad.Buttons == last_button) {
|
||||
if (pad.TimeStamp - deadzone_tick < CTRL_DEADZONE_DELAY)
|
||||
return 0;
|
||||
|
||||
if (pad.TimeStamp - last_button_tick < CTRL_DELAY)
|
||||
return 0;
|
||||
|
||||
last_button_tick = pad.TimeStamp;
|
||||
return last_button;
|
||||
}
|
||||
|
||||
last_button = pad.Buttons;
|
||||
deadzone_tick = last_button_tick = pad.TimeStamp;
|
||||
return last_button;
|
||||
}
|
||||
|
||||
int IsButtonPressed(enum PspCtrlButtons buttons) {
|
||||
return ((pad.Buttons & buttons) == buttons) && ((prev_pad.Buttons & buttons) != buttons);
|
||||
}
|
||||
|
||||
int IsButtonHeld(enum PspCtrlButtons buttons) {
|
||||
return pad.Buttons & buttons;
|
||||
}
|
||||
|
||||
int IsKButtonPressed(enum PspCtrlButtons buttons) {
|
||||
return ((kernel_pad.Buttons & buttons) == buttons) && ((prev_pad.Buttons & buttons) != buttons);
|
||||
}
|
||||
|
||||
int IsKButtonHeld(enum PspCtrlButtons buttons) {
|
||||
return kernel_pad.Buttons & buttons;
|
||||
}
|
||||
|
||||
int GetEnterButton(void) {
|
||||
unsigned int button = 0;
|
||||
|
||||
if (R_SUCCEEDED(GetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", &button))) {
|
||||
if (button == 0)
|
||||
return 0x002000; // PSP_CTRL_CIRCLE
|
||||
else
|
||||
return 0x004000; // PSP_CTRL_CROSS
|
||||
}
|
||||
|
||||
return 0x004000; // By default return PSP_CTRL_CROSS
|
||||
}
|
||||
|
||||
// Basically the opposite of GetEnterButton()
|
||||
int GetCancelButton(void) {
|
||||
unsigned int button = 0;
|
||||
if (R_SUCCEEDED(GetRegistryValue("/CONFIG/SYSTEM/XMB", "button_assign", &button))) {
|
||||
if (button == 0)
|
||||
return 0x004000; // PSP_CTRL_CROSS
|
||||
else
|
||||
return 0x002000; // PSP_CTRL_CIRCLE
|
||||
}
|
||||
|
||||
return 0x002000; // By default return PSP_CTRL_CIRCLE
|
||||
}
|
||||
|
||||
float GetAnalogX(void) {
|
||||
return ((static_cast<float>(pad.Lx - 122.5f)) / 122.5f);
|
||||
}
|
||||
|
||||
float GetAnalogY(void) {
|
||||
return ((static_cast<float>(pad.Ly - 122.5f)) / 122.5f);
|
||||
}
|
||||
|
||||
bool IsCancelButtonPressed(void) {
|
||||
Utils::ReadControls();
|
||||
|
||||
if (Utils::IsButtonPressed(PSP_CTRL_CANCEL))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
26
audio_driver/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
TARGET = audio_driver
|
||||
OBJS = audio_driver.o exports.o
|
||||
|
||||
PRX_EXPORTS = exports.exp
|
||||
|
||||
# Use the kernel's small inbuilt libc
|
||||
USE_KERNEL_LIBC = 1
|
||||
# Use only kernel libraries
|
||||
USE_KERNEL_LIBS = 1
|
||||
|
||||
INCDIR =
|
||||
CFLAGS = -Os -G0 -Wall -fno-builtin-printf
|
||||
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
LIBDIR =
|
||||
|
||||
LDFLAGS = -nostartfiles
|
||||
LIBS = -lpspaudio_driver
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build_prx.mak
|
||||
|
||||
all:
|
||||
psp-build-exports -s $(PRX_EXPORTS)
|
||||
mv audio_driver.S "../app/drivers/"
|
20
audio_driver/audio_driver.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <pspsdk.h>
|
||||
#include <pspaudio_kernel.h>
|
||||
|
||||
PSP_MODULE_INFO("audio_driver", PSP_MODULE_KERNEL, 1, 3);
|
||||
PSP_NO_CREATE_MAIN_THREAD();
|
||||
|
||||
int pspAudioSetFrequency(int frequency) {
|
||||
u32 k1 = pspSdkSetK1(0);
|
||||
int ret = sceAudioSetFrequency(frequency);
|
||||
pspSdkSetK1(k1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int module_start(SceSize args, void *argp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int module_stop(void) {
|
||||
return 0;
|
||||
}
|
16
audio_driver/exports.exp
Normal file
@ -0,0 +1,16 @@
|
||||
# Define the exports for the prx
|
||||
PSP_BEGIN_EXPORTS
|
||||
|
||||
# These four lines are mandatory (although you can add other functions like module_stop)
|
||||
# syslib is a psynonym for the single mandatory export.
|
||||
PSP_EXPORT_START(syslib, 0, 0x8000)
|
||||
PSP_EXPORT_FUNC(module_start)
|
||||
PSP_EXPORT_FUNC(module_stop)
|
||||
PSP_EXPORT_VAR(module_info)
|
||||
PSP_EXPORT_END
|
||||
|
||||
PSP_EXPORT_START(audio_driver, 0, 0x4001)
|
||||
PSP_EXPORT_FUNC(pspAudioSetFrequency)
|
||||
PSP_EXPORT_END
|
||||
|
||||
PSP_END_EXPORTS
|
26
display_driver/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
TARGET = display_driver
|
||||
OBJS = display_driver.o exports.o sceDisplay_driver.o
|
||||
|
||||
PRX_EXPORTS = exports.exp
|
||||
|
||||
# Use the kernel's small inbuilt libc
|
||||
USE_KERNEL_LIBC = 1
|
||||
# Use only kernel libraries
|
||||
USE_KERNEL_LIBS = 1
|
||||
|
||||
INCDIR =
|
||||
CFLAGS = -Os -G0 -Wall -fno-builtin-printf
|
||||
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
LIBDIR =
|
||||
|
||||
LDFLAGS = -nostartfiles
|
||||
LIBS =
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build_prx.mak
|
||||
|
||||
all:
|
||||
psp-build-exports -s $(PRX_EXPORTS)
|
||||
mv display_driver.S "../app/drivers/"
|
59
display_driver/display_driver.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <pspsdk.h>
|
||||
#include <pspdisplay_kernel.h>
|
||||
#include <pspsysmem_kernel.h>
|
||||
|
||||
PSP_MODULE_INFO("display_driver", PSP_MODULE_KERNEL, 1, 3);
|
||||
PSP_NO_CREATE_MAIN_THREAD();
|
||||
|
||||
int sceDisplayEnable(void);
|
||||
int sceDisplayDisable(void);
|
||||
int sceDisplayEnable371(void);
|
||||
int sceDisplayDisable371(void);
|
||||
|
||||
int pspGetBrightness(int *brightness) {
|
||||
u32 k1 = pspSdkSetK1(0);
|
||||
sceDisplayGetBrightness(brightness, 0);
|
||||
pspSdkSetK1(k1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pspSetBrightness(int brightness) {
|
||||
u32 k1 = pspSdkSetK1(0);
|
||||
sceDisplaySetBrightness(brightness, 0);
|
||||
pspSdkSetK1(k1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pspDisplayEnable(void) {
|
||||
u32 k1 = pspSdkSetK1(0);
|
||||
|
||||
int ret = 0;
|
||||
if (sceKernelDevkitVersion() < 0x03070110)
|
||||
ret = sceDisplayEnable();
|
||||
else
|
||||
ret = sceDisplayEnable371();
|
||||
|
||||
pspSdkSetK1(k1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pspDisplayDisable(void) {
|
||||
u32 k1 = pspSdkSetK1(0);
|
||||
|
||||
int ret = 0;
|
||||
if (sceKernelDevkitVersion() < 0x03070110)
|
||||
ret = sceDisplayDisable();
|
||||
else
|
||||
ret = sceDisplayDisable371();
|
||||
|
||||
pspSdkSetK1(k1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int module_start(SceSize args, void *argp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int module_stop(void) {
|
||||
return 0;
|
||||
}
|
19
display_driver/exports.exp
Normal file
@ -0,0 +1,19 @@
|
||||
# Define the exports for the prx
|
||||
PSP_BEGIN_EXPORTS
|
||||
|
||||
# These four lines are mandatory (although you can add other functions like module_stop)
|
||||
# syslib is a psynonym for the single mandatory export.
|
||||
PSP_EXPORT_START(syslib, 0, 0x8000)
|
||||
PSP_EXPORT_FUNC(module_start)
|
||||
PSP_EXPORT_FUNC(module_stop)
|
||||
PSP_EXPORT_VAR(module_info)
|
||||
PSP_EXPORT_END
|
||||
|
||||
PSP_EXPORT_START(display_driver, 0, 0x4001)
|
||||
PSP_EXPORT_FUNC(pspGetBrightness)
|
||||
PSP_EXPORT_FUNC(pspSetBrightness)
|
||||
PSP_EXPORT_FUNC(pspDisplayEnable)
|
||||
PSP_EXPORT_FUNC(pspDisplayDisable)
|
||||
PSP_EXPORT_END
|
||||
|
||||
PSP_END_EXPORTS
|