Inital source commit

This commit is contained in:
Joel16 2019-03-31 20:29:13 -05:00
parent 75692ab1db
commit eb898405fa
72 changed files with 22941 additions and 1 deletions

108
CMakeLists.txt Normal file
View File

@ -0,0 +1,108 @@
cmake_minimum_required(VERSION 2.8)
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{VITASDK})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
else()
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
endif()
endif()
project(eleven_music_player_vita)
include("${VITASDK}/share/vita.cmake" REQUIRED)
set(VITA_APP_NAME "Eleven Music Player")
set(VITA_TITLEID "ELEVENMPV")
set(VITA_VERSION "01.00")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall -Werror -ffast-math")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1")
FUNCTION(ADD_RESOURCES out_var)
SET(result)
FOREACH(in_f ${ARGN})
SET(out_f "${CMAKE_CURRENT_BINARY_DIR}/${in_f}.o")
GET_FILENAME_COMPONENT(out_dir ${out_f} DIRECTORY)
ADD_CUSTOM_COMMAND(OUTPUT ${out_f}
COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir}
COMMAND ${CMAKE_LINKER} -r -b binary -o ${out_f} ${in_f}
DEPENDS ${in_f}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Building resource ${out_f}"
VERBATIM
)
LIST(APPEND result ${out_f})
ENDFOREACH()
SET(${out_var} "${result}" PARENT_SCOPE)
ENDFUNCTION()
file(GLOB res_files RELATIVE
${CMAKE_SOURCE_DIR}
res/*.png
)
add_resources(elevenmp_res ${res_files})
include_directories(
include
include/audio
include/menus
)
link_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
add_executable(${PROJECT_NAME}
${elevenmp_res}
source/common.c
source/dirbrowse.c
source/fs.c
source/main.c
source/status_bar.c
source/textures.c
source/utils.c
source/audio/audio.c
source/audio/flac.c
source/audio/mp3.c
source/audio/ogg.c
source/audio/stb_vorbis.c
source/audio/vitaaudiolib.c
source/audio/wav.c
source/audio/xm.c
source/menus/menu_displayfiles.c
source/menus/menu_audioplayer.c
)
target_link_libraries(${PROJECT_NAME}
vita2d
freetype
png
jpeg
z
m
c
mpg123
SceAppUtil_stub
SceAudio_stub
SceAudiodec_stub
SceCommonDialog_stub
SceCtrl_stub
SceDisplay_stub
SceGxm_stub
ScePower_stub
SceRtc_stub
SceSysmodule_stub
SceTouch_stub
)
vita_create_self(${PROJECT_NAME}.self ${PROJECT_NAME})
vita_create_vpk(${PROJECT_NAME}.vpk ${VITA_TITLEID} ${PROJECT_NAME}.self
VERSION ${VITA_VERSION}
NAME ${VITA_APP_NAME}
FILE sce_sys/icon0.png sce_sys/icon0.png
FILE sce_sys/livearea/contents/bg.png sce_sys/livearea/contents/bg.png
FILE sce_sys/livearea/contents/startup.png sce_sys/livearea/contents/startup.png
FILE sce_sys/livearea/contents/template.xml sce_sys/livearea/contents/template.xml
FILE res/Roboto-Regular.ttf Roboto-Regular.ttf
)

View File

@ -1 +1,17 @@
# ElevenMPV
# ElevenMPV - Eleven Music Player VITA
A homebrew music player for Playstation VITA that aims to support many different audio formats compared to the offical PS VITA music application.
# Currently supported formats: (16 bit signed samples)
- FLAC
- MP3
- OGG
- WAV (A-law and u-law, Microsoft ADPCM, IMA ADPCM)
- XM (Extended module)
# Features:
- Browse ux0:/ to play the above audio formats.
- Pause/Play audio.
- Shuffle/Repeat audio.
- Next/Previous track in current working directory.
- Display ID3v1 and ID3v2 metadata for MP3 files.

32
include/audio/audio.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _ELEVENMPV_AUDIO_H_
#define _ELEVENMPV_AUDIO_H_
#include <psp2/types.h>
#include <vita2d.h>
extern SceBool playing, paused;
typedef struct {
SceBool has_meta;
char title[31];
char album[31];
char artist[31];
char year[5];
char comment[31];
char genre[31];
vita2d_texture *cover_image;
} Audio_Metadata;
extern Audio_Metadata metadata;
int Audio_Init(const char *path);
SceBool Audio_IsPaused(void);
void Audio_Pause(void);
void Audio_Stop(void);
SceUInt64 Audio_GetPosition(void);
SceUInt64 Audio_GetLength(void);
SceUInt64 Audio_GetPositionSeconds(void);
SceUInt64 Audio_GetLengthSeconds(void);
void Audio_Term(void);
#endif

8196
include/audio/dr_flac.h Normal file

File diff suppressed because it is too large Load Diff

4377
include/audio/dr_wav.h Normal file

File diff suppressed because it is too large Load Diff

14
include/audio/flac.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_AUDIO_FLAC_H_
#define _ELEVENMPV_AUDIO_FLAC_H_
#include <psp2/types.h>
int FLAC_Init(const char *path);
SceUInt32 FLAC_GetSampleRate(void);
SceUInt8 FLAC_GetChannels(void);
void FLAC_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 FLAC_GetPosition(void);
SceUInt64 FLAC_GetLength(void);
void FLAC_Term(void);
#endif

2667
include/audio/jar_xm.h Normal file

File diff suppressed because it is too large Load Diff

14
include/audio/mp3.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_AUDIO_MP3_H_
#define _ELEVENMPV_AUDIO_MP3_H_
#include <psp2/types.h>
int MP3_Init(const char *path);
SceUInt32 MP3_GetSampleRate(void);
SceUInt8 MP3_GetChannels(void);
void MP3_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 MP3_GetPosition(void);
SceUInt64 MP3_GetLength(void);
void MP3_Term(void);
#endif

14
include/audio/ogg.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_AUDIO_OGG_H_
#define _ELEVENMPV_AUDIO_OGG_H_
#include <psp2/types.h>
int OGG_Init(const char *path);
SceUInt32 OGG_GetSampleRate(void);
SceUInt8 OGG_GetChannels(void);
void OGG_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 OGG_GetPosition(void);
SceUInt64 OGG_GetLength(void);
void OGG_Term(void);
#endif

View File

@ -0,0 +1,40 @@
#ifndef _ELEVENMPV_AUDIO_LIB_H_
#define _ELEVENMPV_AUDIO_LIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <psp2/audioout.h>
#define VITA_NUM_AUDIO_CHANNELS 1
#define VITA_NUM_AUDIO_SAMPLES 1024
#define VITA_VOLUME_MAX 0x8000
typedef void (* vitaAudioCallback_t)(void *buf, unsigned int reqn, void *pdata);
typedef struct {
int threadhandle;
int handle;
int volumeleft;
int volumeright;
vitaAudioCallback_t callback;
void *pdata;
} VITA_audio_channelinfo;
typedef int (* vitaAudioThreadfunc_t)(int args, void *argp);
void vitaAudioSetVolume(int channel, int left, int right);
int vitaAudioSetFrequency(int channel, int frequency);
void vitaAudioChannelThreadCallback(int channel, void *buf, unsigned int reqn);
void vitaAudioSetChannelCallback(int channel, vitaAudioCallback_t callback, void *pdata);
int vitaAudioOutBlocking(unsigned int channel, unsigned int vol1, unsigned int vol2, void *buf);
int vitaAudioInit(int frequency, SceAudioOutMode mode);
void vitaAudioEndPre(void);
void vitaAudioEnd(void);
#ifdef __cplusplus
}
#endif
#endif

14
include/audio/wav.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_AUDIO_WAV_H_
#define _ELEVENMPV_AUDIO_WAV_H_
#include <psp2/types.h>
int WAV_Init(const char *path);
SceUInt32 WAV_GetSampleRate(void);
SceUInt8 WAV_GetChannels(void);
void WAV_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 WAV_GetPosition(void);
SceUInt64 WAV_GetLength(void);
void WAV_Term(void);
#endif

14
include/audio/xm.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_AUDIO_XM_H_
#define _ELEVENMPV_AUDIO_XM_H_
#include <psp2/types.h>
int XM_Init(const char *path);
SceUInt32 XM_GetSampleRate(void);
SceUInt8 XM_GetChannels(void);
void XM_Decode(void *buf, unsigned int length, void *userdata);
SceUInt64 XM_GetPosition(void);
SceUInt64 XM_GetLength(void);
void XM_Term(void);
#endif

26
include/common.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _ELEVENMPV_COMMON_H_
#define _ELEVENMPV_COMMON_H_
#include <psp2/ctrl.h>
#include <psp2/types.h>
#include <vita2d.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)
/// Returns the level of a result code.
#define MAX_FILES 1024
#define ROOT_PATH "ux0:/"
#define FILES_PER_PAGE 6
extern vita2d_font *font;
extern enum SceCtrlButtons SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
extern SceUInt32 pressed;
extern int position;
extern int file_count;
extern char cwd[512];
#endif

21
include/dirbrowse.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _ELEVENMPV_DIRBROWSE_H_
#define _ELEVENMPV_DIRBROWSE_H_
#include <psp2/types.h>
typedef struct File {
struct File *next; // Next item
int is_dir; // Folder flag
char name[256]; // File name
char ext[5]; // File extension
} File;
extern File *files;
int Dirbrowse_PopulateFiles(SceBool clear);
void Dirbrowse_DisplayFiles(void);
File *Dirbrowse_GetFileIndex(int index);
void Dirbrowse_OpenFile(void);
int Dirbrowse_Navigate(SceBool parent);
#endif

13
include/fs.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _ELEVENMPV_FS_H_
#define _ELEVENMPV_FS_H_
#include <psp2/types.h>
SceBool FS_FileExists(const char *path);
SceBool FS_DirExists(const char *path);
const char *FS_GetFileExt(const char *filename);
int FS_GetFileSize(const char *path, SceOff *size);
int FS_ReadFile(const char *path, void *buf, int size);
int FS_WriteFile(char *path, void *buf, int size);
#endif

View File

@ -0,0 +1,6 @@
#ifndef _ELEVENMPV_MENU_PLAYAUDIO_H_
#define _ELEVENMPV_MENU_PLAYAUDIO_H_
void Menu_PlayAudio(char *path);
#endif

View File

@ -0,0 +1,6 @@
#ifndef _ELEVENMPV_MENU_DISPLAYFILES_H_
#define _ELEVENMPV_MENU_DISPLAYFILES_H_
void Menu_DisplayFiles(void);
#endif

6
include/status_bar.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _ELEVENMPV_STATUS_BAR_H_
#define _ELEVENMPV_STATUS_BAR_H_
void StatusBar_Display(void);
#endif

14
include/textures.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_TEXTURES_H_
#define _ELEVENMPV_TEXTURES_H_
#include <vita2d.h>
vita2d_texture *icon_dir, *icon_file, *icon_audio, *battery_20, *battery_20_charging, *battery_30, *battery_30_charging, *battery_50, *battery_50_charging, \
*battery_60, *battery_60_charging, *battery_80, *battery_80_charging, *battery_90, *battery_90_charging, *battery_full, *battery_full_charging, \
*battery_low, *battery_unknown, *default_artwork, *default_artwork_blur, *btn_play, *btn_pause, *btn_rewind, *btn_forward, *btn_repeat, \
*btn_shuffle, *btn_repeat_overlay, *btn_shuffle_overlay, *icon_back;
void Textures_Load(void);
void Textures_Free(void);
#endif

14
include/utils.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _ELEVENMPV_UTILS_H_
#define _ELEVENMPV_UTILS_H_
void Utils_SetMax(int *set, int value, int max);
void Utils_SetMin(int *set, int value, int min);
int Utils_ReadControls(void);
int Utils_InitAppUtil(void);
int Utils_TermAppUtil(void);
int Utils_GetEnterButton(void);
int Utils_GetCancelButton(void);
int Utils_Alphasort(const void *p1, const void *p2);
char *Utils_Basename(const char *filename);
#endif

BIN
res/Roboto-Regular.ttf Normal file

Binary file not shown.

BIN
res/battery_20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

BIN
res/battery_20_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

BIN
res/battery_30.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
res/battery_30_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

BIN
res/battery_50.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

BIN
res/battery_50_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

BIN
res/battery_60.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

BIN
res/battery_60_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

BIN
res/battery_80.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

BIN
res/battery_80_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

BIN
res/battery_90.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

BIN
res/battery_90_charging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

BIN
res/battery_full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
res/battery_low.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

BIN
res/battery_unknown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
res/btn_playback_pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

BIN
res/btn_playback_play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

BIN
res/btn_playback_repeat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
res/btn_playback_rewind.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
res/default_artwork.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 KiB

BIN
res/icon_audio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

BIN
res/icon_back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
res/icon_file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

BIN
res/icon_folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

BIN
sce_sys/icon0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<livearea style="a1" format-ver="01.00" content-rev="1">
<livearea-background>
<image>bg.png</image>
</livearea-background>
<gate>
<startup-image>startup.png</startup-image>
</gate>
</livearea>

289
source/audio/audio.c Normal file
View File

@ -0,0 +1,289 @@
#include <psp2/kernel/threadmgr.h>
#include <stdio.h>
#include <string.h>
#include "audio.h"
#include "vitaaudiolib.h"
#include "fs.h"
#include "flac.h"
#include "mp3.h"
#include "ogg.h"
#include "wav.h"
#include "xm.h"
enum Audio_FileType {
FILE_TYPE_NONE = 0,
FILE_TYPE_FLAC = 1,
FILE_TYPE_MP3 = 2,
FILE_TYPE_OGG = 3,
FILE_TYPE_WAV = 4,
FILE_TYPE_XM = 5
};
static enum Audio_FileType file_type = FILE_TYPE_NONE;
Audio_Metadata metadata;
SceBool playing = SCE_TRUE, paused = SCE_FALSE;
static SceUInt32 Audio_GetSampleRate(void) {
SceUInt32 sample_rate = 0;
switch(file_type) {
case FILE_TYPE_FLAC:
sample_rate = FLAC_GetSampleRate();
break;
case FILE_TYPE_MP3:
sample_rate = MP3_GetSampleRate();
break;
case FILE_TYPE_OGG:
sample_rate = OGG_GetSampleRate();
break;
case FILE_TYPE_WAV:
sample_rate = WAV_GetSampleRate();
break;
case FILE_TYPE_XM:
sample_rate = XM_GetSampleRate();
break;
default:
break;
}
return sample_rate;
}
static SceUInt8 Audio_GetChannels(void) {
SceUInt8 channels = 0;
switch(file_type) {
case FILE_TYPE_FLAC:
channels = FLAC_GetChannels();
break;
case FILE_TYPE_MP3:
channels = MP3_GetChannels();
break;
case FILE_TYPE_OGG:
channels = OGG_GetChannels();
break;
case FILE_TYPE_WAV:
channels = WAV_GetChannels();
break;
case FILE_TYPE_XM:
channels = XM_GetChannels();
break;
default:
break;
}
return channels;
}
static void Audio_Decode(void *buf, unsigned int length, void *userdata) {
if (playing == SCE_FALSE || paused == SCE_TRUE) {
short *buf_short = (short *)buf;
unsigned int count;
for (count = 0; count < length * 2; count++)
*(buf_short + count) = 0;
}
else {
switch(file_type) {
case FILE_TYPE_FLAC:
FLAC_Decode(buf, length, userdata);
break;
case FILE_TYPE_MP3:
MP3_Decode(buf, length, userdata);
break;
case FILE_TYPE_OGG:
OGG_Decode(buf, length, userdata);
break;
case FILE_TYPE_WAV:
WAV_Decode(buf, length, userdata);
break;
case FILE_TYPE_XM:
XM_Decode(buf, length, userdata);
break;
default:
break;
}
}
}
int Audio_Init(const char *path) {
playing = SCE_TRUE;
paused = SCE_FALSE;
// Clear struct
static const Audio_Metadata empty;
metadata = empty;
if (!strncasecmp(FS_GetFileExt(path), "flac", 4))
file_type = FILE_TYPE_FLAC;
else if (!strncasecmp(FS_GetFileExt(path), "mp3", 3))
file_type = FILE_TYPE_MP3;
else if (!strncasecmp(FS_GetFileExt(path), "ogg", 3))
file_type = FILE_TYPE_OGG;
else if (!strncasecmp(FS_GetFileExt(path), "wav", 3))
file_type = FILE_TYPE_WAV;
else if (!strncasecmp(FS_GetFileExt(path), "xm", 2))
file_type = FILE_TYPE_XM;
switch(file_type) {
case FILE_TYPE_FLAC:
FLAC_Init(path);
break;
case FILE_TYPE_MP3:
MP3_Init(path);
break;
case FILE_TYPE_OGG:
OGG_Init(path);
break;
case FILE_TYPE_WAV:
WAV_Init(path);
break;
case FILE_TYPE_XM:
XM_Init(path);
break;
default:
break;
}
vitaAudioInit(Audio_GetSampleRate(), Audio_GetChannels() == 2? SCE_AUDIO_OUT_MODE_STEREO : SCE_AUDIO_OUT_MODE_MONO);
vitaAudioSetChannelCallback(0, Audio_Decode, NULL);
return 0;
}
SceBool Audio_IsPaused(void) {
return paused;
}
void Audio_Pause(void) {
paused = !paused;
}
void Audio_Stop(void) {
playing = !playing;
}
SceUInt64 Audio_GetPosition(void) {
SceUInt64 position = 0;
switch(file_type) {
case FILE_TYPE_FLAC:
position = FLAC_GetPosition();
break;
case FILE_TYPE_MP3:
position = MP3_GetPosition();
break;
case FILE_TYPE_OGG:
position = OGG_GetPosition();
break;
case FILE_TYPE_WAV:
position = WAV_GetPosition();
break;
case FILE_TYPE_XM:
position = XM_GetPosition();
break;
default:
break;
}
return position;
}
SceUInt64 Audio_GetLength(void) {
SceUInt64 length = 0;
switch(file_type) {
case FILE_TYPE_FLAC:
length = FLAC_GetLength();
break;
case FILE_TYPE_MP3:
length = MP3_GetLength();
break;
case FILE_TYPE_WAV:
length = WAV_GetLength();
break;
case FILE_TYPE_OGG:
length = OGG_GetLength();
break;
case FILE_TYPE_XM:
length = XM_GetLength();
break;
default:
break;
}
return length;
}
SceUInt64 Audio_GetPositionSeconds(void) {
return (Audio_GetPosition() / Audio_GetSampleRate());
}
SceUInt64 Audio_GetLengthSeconds(void) {
return (Audio_GetLength() / Audio_GetSampleRate());
}
void Audio_Term(void) {
switch(file_type) {
case FILE_TYPE_FLAC:
FLAC_Term();
break;
case FILE_TYPE_MP3:
MP3_Term();
break;
case FILE_TYPE_OGG:
OGG_Term();
break;
case FILE_TYPE_WAV:
WAV_Term();
break;
case FILE_TYPE_XM:
XM_Term();
break;
default:
break;
}
playing = SCE_TRUE;
paused = SCE_FALSE;
vitaAudioSetChannelCallback(0, NULL, NULL); // Clear channel callback
vitaAudioEndPre();
sceKernelDelayThread(50 * 1000);
vitaAudioEnd();
}

42
source/audio/flac.c Normal file
View File

@ -0,0 +1,42 @@
#include "audio.h"
#define DR_FLAC_IMPLEMENTATION
#include "dr_flac.h"
static drflac *flac;
static drflac_uint64 frames_read = 0;
int FLAC_Init(const char *path) {
flac = drflac_open_file(path);
if (flac == NULL)
return -1;
return 0;
}
SceUInt32 FLAC_GetSampleRate(void) {
return flac->sampleRate;
}
SceUInt8 FLAC_GetChannels(void) {
return flac->channels;
}
void FLAC_Decode(void *buf, unsigned int length, void *userdata) {
frames_read += drflac_read_pcm_frames_s16(flac, (drflac_uint64)length, (drflac_int16 *)buf);
if (frames_read == flac->totalPCMFrameCount)
playing = SCE_FALSE;
}
SceUInt64 FLAC_GetPosition(void) {
return frames_read;
}
SceUInt64 FLAC_GetLength(void) {
return flac->totalPCMFrameCount;
}
void FLAC_Term(void) {
frames_read = 0;
drflac_close(flac);
}

204
source/audio/mp3.c Normal file
View File

@ -0,0 +1,204 @@
#include <mpg123.h>
#include <stdio.h>
#include <string.h>
#include "audio.h"
// For MP3 ID3 tags
struct genre {
int code;
char text[112];
};
// For MP3 ID3 tags
struct genre genreList[] = {
{0 , "Blues"}, {1 , "Classic Rock"}, {2 , "Country"}, {3 , "Dance"}, {4 , "Disco"}, {5 , "Funk"}, {6 , "Grunge"}, {7 , "Hip-Hop"}, {8 , "Jazz"}, {9 , "Metal"}, {10 , "New Age"},
{11 , "Oldies"}, {12 , "Other"}, {13 , "Pop"}, {14 , "R&B"}, {15 , "Rap"}, {16 , "Reggae"}, {17 , "Rock"}, {18 , "Techno"}, {19 , "Industrial"}, {20 , "Alternative"},
{21 , "Ska"}, {22 , "Death Metal"}, {23 , "Pranks"}, {24 , "Soundtrack"}, {25 , "Euro-Techno"}, {26 , "Ambient"}, {27 , "Trip-Hop"}, {28 , "Vocal"}, {29 , "Jazz+Funk"}, {30 , "Fusion"},
{31 , "Trance"}, {32 , "Classical"}, {33 , "Instrumental"}, {34 , "Acid"}, {35 , "House"}, {36 , "Game"}, {37 , "Sound Clip"}, {38 , "Gospel"}, {39 , "Noise"}, {40 , "Alternative Rock"},
{41 , "Bass"}, {42 , "Soul"}, {43 , "Punk"}, {44 , "Space"}, {45 , "Meditative"}, {46 , "Instrumental Pop"}, {47 , "Instrumental Rock"}, {48 , "Ethnic"}, {49 , "Gothic"}, {50 , "Darkwave"},
{51 , "Techno-Industrial"}, {52 , "Electronic"}, {53 , "Pop-Folk"}, {54 , "Eurodance"}, {55 , "Dream"}, {56 , "Southern Rock"}, {57 , "Comedy"}, {58 , "Cult"}, {59 , "Gangsta"}, {60 , "Top 40"},
{61 , "Christian Rap"}, {62 , "Pop/Funk"}, {63 , "Jungle"}, {64 , "Native US"}, {65 , "Cabaret"}, {66 , "New Wave"}, {67 , "Psychadelic"}, {68 , "Rave"}, {69 , "Showtunes"}, {70 , "Trailer"},
{71 , "Lo-Fi"}, {72 , "Tribal"}, {73 , "Acid Punk"}, {74 , "Acid Jazz"}, {75 , "Polka"}, {76 , "Retro"}, {77 , "Musical"}, {78 , "Rock & Roll"}, {79 , "Hard Rock"}, {80 , "Folk"},
{81 , "Folk-Rock"}, {82 , "National Folk"}, {83 , "Swing"}, {84 , "Fast Fusion"}, {85 , "Bebob"}, {86 , "Latin"}, {87 , "Revival"}, {88 , "Celtic"}, {89 , "Bluegrass"}, {90 , "Avantgarde"},
{91 , "Gothic Rock"}, {92 , "Progressive Rock"}, {93 , "Psychedelic Rock"}, {94 , "Symphonic Rock"}, {95 , "Slow Rock"}, {96 , "Big Band"}, {97 , "Chorus"}, {98 , "Easy Listening"}, {99 , "Acoustic"},
{100 , "Humour"}, {101 , "Speech"}, {102 , "Chanson"}, {103 , "Opera"}, {104 , "Chamber Music"}, {105 , "Sonata"}, {106 , "Symphony"}, {107 , "Booty Bass"}, {108 , "Primus"}, {109 , "Porn Groove"},
{110 , "Satire"}, {111 , "Slow Jam"}, {112 , "Club"}, {113 , "Tango"}, {114 , "Samba"}, {115 , "Folklore"}, {116 , "Ballad"}, {117 , "Power Ballad"}, {118 , "Rhytmic Soul"}, {119 , "Freestyle"}, {120 , "Duet"},
{121 , "Punk Rock"}, {122 , "Drum Solo"}, {123 , "A capella"}, {124 , "Euro-House"}, {125 , "Dance Hall"}, {126 , "Goa"}, {127 , "Drum & Bass"}, {128 , "Club-House"}, {129 , "Hardcore"}, {130 , "Terror"},
{131 , "Indie"}, {132 , "BritPop"}, {133 , "Negerpunk"}, {134 , "Polsk Punk"}, {135 , "Beat"}, {136 , "Christian Gangsta"}, {137 , "Heavy Metal"}, {138 , "Black Metal"}, {139 , "Crossover"}, {140 , "Contemporary C"},
{141 , "Christian Rock"}, {142 , "Merengue"}, {143 , "Salsa"}, {144 , "Thrash Metal"}, {145 , "Anime"}, {146 , "JPop"}, {147 , "SynthPop"}
};
static mpg123_handle *mp3;
static SceUInt64 frames_read = 0, total_samples = 0;
static long sample_rate = 0;
static int channels = 0;
// For MP3 ID3 tags
// Helper for v1 printing, get these strings their zero byte.
static void safe_print(char *tag, char *name, char *data, size_t size) {
char safe[31];
if (size > 30)
return;
memcpy(safe, data, size);
safe[size] = 0;
snprintf(tag, 34, "%s: %s\n", name, safe);
}
// For MP3 ID3 tags
// Print out ID3v1 info.
static void print_v1(Audio_Metadata *ID3tag, mpg123_id3v1 *v1) {
safe_print(ID3tag->title, "", v1->title, sizeof(v1->title));
safe_print(ID3tag->artist, "", v1->artist, sizeof(v1->artist));
safe_print(ID3tag->album, "", v1->album, sizeof(v1->album));
safe_print(ID3tag->year, "", v1->year, sizeof(v1->year));
safe_print(ID3tag->comment, "", v1->comment, sizeof(v1->comment));
safe_print(ID3tag->genre, "", genreList[v1->genre].text, sizeof(genreList[v1->genre].text));
}
// For MP3 ID3 tags
// Split up a number of lines separated by \n, \r, both or just zero byte
// and print out each line with specified prefix.
static void print_lines(char *data, const char *prefix, mpg123_string *inlines) {
size_t i;
int hadcr = 0, hadlf = 0;
char *lines = NULL;
char *line = NULL;
size_t len = 0;
if (inlines != NULL && inlines->fill) {
lines = inlines->p;
len = inlines->fill;
}
else
return;
line = lines;
for (i = 0; i < len; ++i) {
if (lines[i] == '\n' || lines[i] == '\r' || lines[i] == 0) {
char save = lines[i]; /* saving, changing, restoring a byte in the data */
if (save == '\n')
++hadlf;
if (save == '\r')
++hadcr;
if ((hadcr || hadlf) && (hadlf % 2 == 0) && (hadcr % 2 == 0))
line = "";
if (line) {
lines[i] = 0;
if (data == NULL)
printf("%s%s\n", prefix, line);
else
snprintf(data, 0x1F, "%s%s\n", prefix, line);
line = NULL;
lines[i] = save;
}
}
else {
hadlf = hadcr = 0;
if (line == NULL)
line = lines + i;
}
}
}
// For MP3 ID3 tags
// Print out the named ID3v2 fields.
static void print_v2(Audio_Metadata *ID3tag, mpg123_id3v2 *v2) {
print_lines(ID3tag->title, "", v2->title);
print_lines(ID3tag->artist, "", v2->artist);
print_lines(ID3tag->album, "", v2->album);
print_lines(ID3tag->year, "", v2->year);
print_lines(ID3tag->comment, "", v2->comment);
print_lines(ID3tag->genre, "", v2->genre);
}
int MP3_Init(const char *path) {
int error = mpg123_init();
if (error != MPG123_OK)
return error;
mp3 = mpg123_new(NULL, &error);
if (error != MPG123_OK)
return error;
error = mpg123_param(mp3, MPG123_ADD_FLAGS, MPG123_PICTURE, 0.0);
if (error != MPG123_OK)
return error;
error = mpg123_open(mp3, path);
if (error != MPG123_OK)
return error;
mpg123_seek(mp3, 0, SEEK_SET);
metadata.has_meta = mpg123_meta_check(mp3);
mpg123_id3v1 *v1;
mpg123_id3v2 *v2;
if (metadata.has_meta & MPG123_ID3 && mpg123_id3(mp3, &v1, &v2) == MPG123_OK) {
if (v1 != NULL)
print_v1(&metadata, v1);
if (v2 != NULL) {
print_v2(&metadata, v2);
for (size_t count = 0; count < v2->pictures; count++) {
mpg123_picture *pic = &v2->picture[count];
char *str = pic->mime_type.p;
if ((pic->type == 3 ) || (pic->type == 0)) {
if ((!strcasecmp(str, "image/jpg")) || (!strcasecmp(str, "image/jpeg"))) {
metadata.cover_image = vita2d_load_JPEG_buffer(pic->data, pic->size);
break;
}
else if (!strcasecmp(str, "image/png")) {
metadata.cover_image = vita2d_load_PNG_buffer(pic->data);
break;
}
}
}
}
}
total_samples = mpg123_length(mp3);
mpg123_getformat(mp3, &sample_rate, &channels, NULL);
mpg123_format_none(mp3);
mpg123_format(mp3, sample_rate, channels, MPG123_ENC_SIGNED_16);
return 0;
}
SceUInt32 MP3_GetSampleRate(void) {
return sample_rate;
}
SceUInt8 MP3_GetChannels(void) {
return channels;
}
void MP3_Decode(void *buf, unsigned int length, void *userdata) {
size_t done = 0;
mpg123_read(mp3, buf, length * (sizeof(SceInt16) * 2), &done);
frames_read += done/(sizeof(SceInt16) * 2);
if (frames_read == total_samples)
playing = SCE_FALSE;
}
SceUInt64 MP3_GetPosition(void) {
return frames_read;
}
SceUInt64 MP3_GetLength(void) {
return total_samples;
}
void MP3_Term(void) {
frames_read = 0;
if (metadata.has_meta)
metadata.has_meta = SCE_FALSE;
mpg123_close(mp3);
mpg123_delete(mp3);
mpg123_exit();
}

48
source/audio/ogg.c Normal file
View File

@ -0,0 +1,48 @@
#include "audio.h"
#define STB_VORBIS_HEADER_ONLY
#define STB_VORBIS_NO_PUSHDATA_API
#include "stb_vorbis.c"
static stb_vorbis *ogg;
static stb_vorbis_info ogg_info;
static unsigned int samples_read = 0, max_lenth = 0;
int OGG_Init(const char *path) {
int error = 0;
ogg = stb_vorbis_open_filename(path, &error, NULL);
if (!ogg)
return -1;
ogg_info = stb_vorbis_get_info(ogg);
max_lenth = stb_vorbis_stream_length_in_samples(ogg);
return 0;
}
SceUInt32 OGG_GetSampleRate(void) {
return ogg_info.sample_rate;
}
SceUInt8 OGG_GetChannels(void) {
return ogg_info.channels;
}
void OGG_Decode(void *buf, unsigned int length, void *userdata) {
samples_read += stb_vorbis_get_samples_short_interleaved(ogg, ogg_info.channels, (short *)buf, (int)length * ogg_info.channels);
if (samples_read == max_lenth)
playing = SCE_FALSE;
}
SceUInt64 OGG_GetPosition(void) {
return samples_read;
}
SceUInt64 OGG_GetLength(void) {
return max_lenth;
}
void OGG_Term(void) {
samples_read = 0;
stb_vorbis_close(ogg);
}

5494
source/audio/stb_vorbis.c Normal file

File diff suppressed because it is too large Load Diff

169
source/audio/vitaaudiolib.c Normal file
View File

@ -0,0 +1,169 @@
#include <psp2/kernel/threadmgr.h>
#include <string.h>
#include "vitaaudiolib.h"
static int audio_ready = 0;
static short vitaAudioSoundBuffer[VITA_NUM_AUDIO_CHANNELS][2][VITA_NUM_AUDIO_SAMPLES][2];
static VITA_audio_channelinfo vitaAudioStatus[VITA_NUM_AUDIO_CHANNELS];
static volatile int audio_terminate = 0;
void vitaAudioSetVolume(int channel, int left, int right) {
vitaAudioStatus[channel].volumeleft = left;
vitaAudioStatus[channel].volumeright = right;
}
int vitaAudioSetFrequency(int channel, int frequency) {
return sceAudioOutSetConfig(vitaAudioStatus[channel].handle, VITA_NUM_AUDIO_SAMPLES, frequency, SCE_AUDIO_OUT_MODE_STEREO);
}
void vitaAudioSetChannelCallback(int channel, vitaAudioCallback_t callback, void *data) {
volatile VITA_audio_channelinfo *pci = &vitaAudioStatus[channel];
if (callback == 0)
pci->callback = 0;
else
pci->callback = callback;
}
int vitaAudioOutBlocking(unsigned int channel, unsigned int vol1, unsigned int vol2, void *buf) {
if (!audio_ready)
return(-1);
if (channel >= VITA_NUM_AUDIO_CHANNELS)
return(-1);
if (vol1 > VITA_VOLUME_MAX)
vol1 = VITA_VOLUME_MAX;
if (vol2 > VITA_VOLUME_MAX)
vol2 = VITA_VOLUME_MAX;
int vols2[2] = { vol1, vol2 };
sceAudioOutSetVolume(vitaAudioStatus[channel].handle, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols2);
return sceAudioOutOutput(vitaAudioStatus[channel].handle, buf);
}
static int vitaAudioChannelThread(int args, void *argp) {
volatile int bufidx = 0;
int channel = *(int *) argp;
while (audio_terminate == 0) {
void *bufptr = &vitaAudioSoundBuffer[channel][bufidx];
vitaAudioCallback_t callback;
callback = vitaAudioStatus[channel].callback;
if (callback)
callback(bufptr, VITA_NUM_AUDIO_SAMPLES, vitaAudioStatus[channel].pdata);
else {
unsigned int *ptr = bufptr;
int i;
for (i = 0; i < VITA_NUM_AUDIO_SAMPLES; ++i)
*(ptr++) = 0;
}
vitaAudioOutBlocking(channel, vitaAudioStatus[channel].volumeleft, vitaAudioStatus[channel].volumeright, bufptr);
bufidx = (bufidx ? 0:1);
}
sceKernelExitThread(0);
return(0);
}
int vitaAudioInit(int frequency, SceAudioOutMode mode) {
int i, ret;
int failed = 0;
char str[32];
audio_terminate = 0;
audio_ready = 0;
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
vitaAudioStatus[i].handle = -1;
vitaAudioStatus[i].threadhandle = -1;
vitaAudioStatus[i].volumeright = VITA_VOLUME_MAX;
vitaAudioStatus[i].volumeleft = VITA_VOLUME_MAX;
vitaAudioStatus[i].callback = 0;
vitaAudioStatus[i].pdata = 0;
}
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
if ((vitaAudioStatus[i].handle = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_BGM, VITA_NUM_AUDIO_SAMPLES, frequency, mode)) < 0)
failed = 1;
}
if (failed) {
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
if (vitaAudioStatus[i].handle != -1)
sceAudioOutReleasePort(vitaAudioStatus[i].handle);
vitaAudioStatus[i].handle = -1;
}
return 0;
}
audio_ready = 1;
strcpy(str, "audiot0");
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
str[6]= '0' + i;
vitaAudioStatus[i].threadhandle = sceKernelCreateThread(str, (void*)&vitaAudioChannelThread, 0x40, 0x10000, 0, 0, NULL);
if (vitaAudioStatus[i].threadhandle < 0) {
vitaAudioStatus[i].threadhandle = -1;
failed = 1;
break;
}
ret = sceKernelStartThread(vitaAudioStatus[i].threadhandle, sizeof(i), &i);
if (ret != 0) {
failed = 1;
break;
}
}
if (failed) {
audio_terminate = 1;
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
if (vitaAudioStatus[i].threadhandle != -1)
sceKernelDeleteThread(vitaAudioStatus[i].threadhandle);
vitaAudioStatus[i].threadhandle = -1;
}
audio_ready = 0;
return 0;
}
return 1;
}
void vitaAudioEndPre(void) {
audio_ready = 0;
audio_terminate = 1;
}
void vitaAudioEnd(void) {
int i = 0;
audio_ready = 0;
audio_terminate = 1;
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
if (vitaAudioStatus[i].threadhandle != -1)
sceKernelDeleteThread(vitaAudioStatus[i].threadhandle);
vitaAudioStatus[i].threadhandle = -1;
}
for (i = 0; i < VITA_NUM_AUDIO_CHANNELS; i++) {
if (vitaAudioStatus[i].handle != -1) {
sceAudioOutReleasePort(vitaAudioStatus[i].handle);
vitaAudioStatus[i].handle = -1;
}
}
}

41
source/audio/wav.c Normal file
View File

@ -0,0 +1,41 @@
#include "audio.h"
#define DR_WAV_IMPLEMENTATION
#include "dr_wav.h"
static drwav wav;
static drwav_uint64 frames_read = 0;
int WAV_Init(const char *path) {
if (!drwav_init_file(&wav, path))
return -1;
return 0;
}
SceUInt32 WAV_GetSampleRate(void) {
return wav.sampleRate;
}
SceUInt8 WAV_GetChannels(void) {
return wav.channels;
}
void WAV_Decode(void *buf, unsigned int length, void *userdata) {
frames_read += drwav_read_pcm_frames_s16(&wav, (drwav_uint64)length, (drwav_int16 *)buf);
if (frames_read == wav.totalPCMFrameCount)
playing = SCE_FALSE;
}
SceUInt64 WAV_GetPosition(void) {
return frames_read;
}
SceUInt64 WAV_GetLength(void) {
return wav.totalPCMFrameCount;
}
void WAV_Term(void) {
frames_read = 0;
drwav_uninit(&wav);
}

57
source/audio/xm.c Normal file
View File

@ -0,0 +1,57 @@
#include "audio.h"
#include "common.h"
#include "fs.h"
#define JAR_XM_IMPLEMENTATION
#include "jar_xm.h"
static jar_xm_context_t *xm;
static SceUInt64 samples_read = 0, total_samples = 0;
static char *data = NULL;
int XM_Init(const char *path) {
int ret = 0;
char *xm_data = NULL;
SceUInt64 xm_size_bytes = 0;
if (R_FAILED(ret = FS_GetFileSize(path, (SceOff *)&xm_size_bytes)))
return ret;
xm_data = malloc(xm_size_bytes);
if (R_FAILED(ret = FS_ReadFile(path, xm_data, xm_size_bytes)))
return ret;
jar_xm_create_context_safe(&xm, xm_data, (size_t)xm_size_bytes, (SceUInt32)48000);
total_samples = jar_xm_get_remaining_samples(xm);
return 0;
}
SceUInt32 XM_GetSampleRate(void) {
return 48000;
}
SceUInt8 XM_GetChannels(void) {
return 2;
}
void XM_Decode(void *buf, unsigned int length, void *userdata) {
jar_xm_generate_samples_16bit(xm, (short *)buf, (size_t)length);
jar_xm_get_position(xm, NULL, NULL, NULL, &samples_read);
if (samples_read == total_samples)
playing = SCE_FALSE;
}
SceUInt64 XM_GetPosition(void) {
return samples_read;
}
SceUInt64 XM_GetLength(void) {
return total_samples;
}
void XM_Term(void) {
samples_read = 0;
jar_xm_free_context(xm);
free(data);
}

8
source/common.c Normal file
View File

@ -0,0 +1,8 @@
#include "common.h"
vita2d_font *font;
enum SceCtrlButtons SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
SceUInt32 pressed = 0;
int position = 0;
int file_count = 0;
char cwd[512];

205
source/dirbrowse.c Normal file
View File

@ -0,0 +1,205 @@
#include <psp2/io/dirent.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "dirbrowse.h"
#include "fs.h"
#include "menu_audioplayer.h"
#include "textures.h"
#include "utils.h"
File *files = NULL;
static void Dirbrowse_RecursiveFree(File *node) {
if (node == NULL) // End of list
return;
Dirbrowse_RecursiveFree(node->next); // Nest further
free(node); // Free memory
}
static void Dirbrowse_SaveLastDirectory(void) {
char *buf = malloc(256);
int len = snprintf(buf, 256, "%s\n", cwd);
FS_WriteFile("ux0:data/elevenmpv/lastdir.txt", buf, len);
free(buf);
}
int Dirbrowse_PopulateFiles(SceBool refresh) {
SceUID dir = 0;
Dirbrowse_RecursiveFree(files);
files = NULL;
file_count = 0;
if (R_SUCCEEDED(dir = sceIoDopen(cwd))) {
int entryCount = 0, i = 0;
SceIoDirent *entries = (SceIoDirent *)calloc(MAX_FILES, sizeof(SceIoDirent));
while (sceIoDread(dir, &entries[entryCount]) > 0)
entryCount++;
sceIoDclose(dir);
qsort(entries, entryCount, sizeof(SceIoDirent), Utils_Alphasort);
for (i = 0; i < entryCount; i++) {
// Ingore null filename
if (entries[i].d_name[0] == '\0')
continue;
// Ignore "." in all directories
if (!strcmp(entries[i].d_name, "."))
continue;
// Ignore ".." in Root Directory
if ((!strcmp(cwd, ROOT_PATH)) && (!strncmp(entries[i].d_name, "..", 2))) // Ignore ".." in Root Directory
continue;
// Allocate Memory
File *item = (File *)malloc(sizeof(File));
memset(item, 0, sizeof(File));
item->is_dir = SCE_S_ISDIR(entries[i].d_stat.st_mode);
// Copy File Name
strcpy(item->name, entries[i].d_name);
strcpy(item->ext, FS_GetFileExt(item->name));
// New List
if (files == NULL)
files = item;
// Existing List
else {
File *list = files;
while(list->next != NULL)
list = list->next;
list->next = item;
}
file_count++;
}
free(entries);
}
else
return dir;
if (!refresh) {
if (position >= file_count)
position = file_count - 1; // Keep index
}
else
position = 0; // Refresh position
return 0;
}
void Dirbrowse_DisplayFiles(void) {
vita2d_font_draw_text(font, 102, 40 + ((72 - vita2d_font_text_height(font, 25, cwd)) / 2) + 20, RGBA8(255, 255, 255, 255), 25, cwd);
int i = 0, printed = 0;
File *file = files; // Draw file list
for(; file != NULL; file = file->next) {
if (printed == FILES_PER_PAGE) // Limit the files per page
break;
if (position < FILES_PER_PAGE || i > (position - FILES_PER_PAGE)) {
if (i == position)
vita2d_draw_rectangle(0, 112 + (72 * printed), 960, 72, RGBA8(230, 230, 230, 255));
if (file->is_dir)
vita2d_draw_texture(icon_dir, 15, 117 + (72 * printed));
else if ((!strncasecmp(file->ext, "flac", 4)) || (!strncasecmp(file->ext, "mp3", 3)) || (!strncasecmp(file->ext, "ogg", 3))
|| (!strncasecmp(file->ext, "wav", 3)) || (!strncasecmp(file->ext, "xm", 2)))
vita2d_draw_texture(icon_audio, 15, 117 + (72 * printed));
else
vita2d_draw_texture(icon_file, 15, 117 + (72 * printed));
if (strncmp(file->name, "..", 2) == 0)
vita2d_font_draw_text(font, 102, 120 + (72 / 2) + (72 * printed), RGBA8(51, 51, 51, 255), 25, "Parent folder");
else
vita2d_font_draw_text(font, 102, 120 + (72 / 2) + (72 * printed), RGBA8(51, 51, 51, 255), 25, file->name);
printed++; // Increase printed counter
}
i++; // Increase counter
}
}
File *Dirbrowse_GetFileIndex(int index) {
int i = 0;
File *file = files; // Find file Item
for(; file != NULL && i != index; file = file->next)
i++;
return file; // Return file
}
void Dirbrowse_OpenFile(void) {
char path[512];
File *file = Dirbrowse_GetFileIndex(position);
if (file == NULL)
return;
strcpy(path, cwd);
strcpy(path + strlen(path), file->name);
if (file->is_dir) {
// Attempt to navigate to target
if (R_SUCCEEDED(Dirbrowse_Navigate(SCE_FALSE))) {
Dirbrowse_SaveLastDirectory();
Dirbrowse_PopulateFiles(SCE_TRUE);
}
}
else if ((!strncasecmp(file->ext, "flac", 4)) || (!strncasecmp(file->ext, "mp3", 3)) || (!strncasecmp(file->ext, "ogg", 3))
|| (!strncasecmp(file->ext, "wav", 3)) || (!strncasecmp(file->ext, "xm", 2)))
Menu_PlayAudio(path);
}
// Navigate to Folder
int Dirbrowse_Navigate(SceBool parent) {
File *file = Dirbrowse_GetFileIndex(position); // Get index
if (file == NULL)
return -1;
// Special case ".."
if ((parent) || (!strncmp(file->name, "..", 2))) {
char *slash = NULL;
// Find last '/' in working directory
int i = strlen(cwd) - 2; for(; i >= 0; i--) {
// Slash discovered
if (cwd[i] == '/') {
slash = cwd + i + 1; // Save pointer
break; // Stop search
}
}
slash[0] = 0; // Terminate working directory
}
// Normal folder
else {
if (file->is_dir) {
// Append folder to working directory
strcpy(cwd + strlen(cwd), file->name);
cwd[strlen(cwd) + 1] = 0;
cwd[strlen(cwd)] = '/';
}
}
Dirbrowse_SaveLastDirectory();
return 0; // Return success
}

74
source/fs.c Normal file
View File

@ -0,0 +1,74 @@
#include <psp2/io/dirent.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <string.h>
#include "common.h"
#include "fs.h"
SceBool FS_FileExists(const char *path) {
SceUID file = 0;
if (R_SUCCEEDED(file = sceIoOpen(path, SCE_O_RDONLY, 0777))) {
sceIoClose(file);
return SCE_TRUE;
}
return SCE_FALSE;
}
SceBool FS_DirExists(const char *path) {
SceUID dir = 0;
if (R_SUCCEEDED(dir = sceIoDopen(path))) {
sceIoDclose(dir);
return SCE_TRUE;
}
return SCE_FALSE;
}
const char *FS_GetFileExt(const char *filename) {
const char *dot = strrchr(filename, '.');
if (!dot || dot == filename)
return "";
return dot + 1;
}
int FS_GetFileSize(const char *path, SceOff *size) {
SceIoStat stat;
int ret = 0;
if (R_FAILED(ret = sceIoGetstat(path, &stat)))
return ret;
*size = stat.st_size;
return 0;
}
int FS_ReadFile(const char *path, void *buf, int size) {
SceUID file = 0;
if (R_SUCCEEDED(file = sceIoOpen(path, SCE_O_RDONLY, 0))) {
int bytes_read = sceIoRead(file, buf, size);
sceIoClose(file);
return bytes_read;
}
return file;
}
int FS_WriteFile(char *path, void *buf, int size) {
SceUID file = 0;
if (R_SUCCEEDED(file = sceIoOpen(path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777))) {
int bytes_written = sceIoWrite(file, buf, size);
sceIoClose(file);
return bytes_written;
}
return file;
}

77
source/main.c Normal file
View File

@ -0,0 +1,77 @@
#include <psp2/io/stat.h>
#include <psp2/kernel/processmgr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "fs.h"
#include "menu_displayfiles.h"
#include "textures.h"
#include "utils.h"
static int GetLastDirectory(void) {
int ret = 0;
if (!FS_DirExists("ux0:data/elevenmpv"))
sceIoMkdir("ux0:data/elevenmpv", 0777);
if (!FS_FileExists("ux0:data/elevenmpv/lastdir.txt")) {
char *buf = malloc(8);
int length = snprintf(buf, 8, ROOT_PATH);
if (R_FAILED(ret = FS_WriteFile("ux0:data/elevenmpv/lastdir.txt", buf, length))) {
free(buf);
return ret;
}
strcpy(cwd, ROOT_PATH); // Set Start Path to "sdmc:/" if lastDir.txt hasn't been created.
}
else {
SceOff size = 0;
FS_GetFileSize("ux0:data/elevenmpv/lastdir.txt", &size);
char *buf = malloc(size + 1);
if (R_FAILED(ret = FS_ReadFile("ux0:data/elevenmpv/lastdir.txt", buf, size))) {
free(buf);
return ret;
}
buf[size] = '\0';
char path[513];
sscanf(buf, "%[^\n]s", path);
if (FS_DirExists(path)) // Incase a directory previously visited had been deleted, set start path to sdmc:/ to avoid errors.
strcpy(cwd, path);
else
strcpy(cwd, ROOT_PATH);
free(buf);
}
return 0;
}
int main(int argc, char *argv[]) {
vita2d_init();
font = vita2d_load_font_file("app0:Roboto-Regular.ttf");
Textures_Load();
Utils_InitAppUtil();
SCE_CTRL_ENTER = Utils_GetEnterButton();
SCE_CTRL_CANCEL = Utils_GetCancelButton();
GetLastDirectory();
Menu_DisplayFiles();
Utils_TermAppUtil();
Textures_Free();
vita2d_free_font(font);
vita2d_fini();
sceKernelExitProcess(0);
return 0;
}

View File

@ -0,0 +1,238 @@
#include <psp2/io/dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "audio.h"
#include "common.h"
#include "fs.h"
#include "menu_displayfiles.h"
#include "status_bar.h"
#include "textures.h"
#include "utils.h"
#define BUTTON_WIDTH 68
#define BUTTON_HEIGHT 68
typedef enum {
MUSIC_STATE_NONE, // 0
MUSIC_STATE_REPEAT, // 1
MUSIC_STATE_SHUFFLE // 2
} Music_State;
static char playlist[1024][512];
static int count = 0, selection = 0, state = 0;
static int length_time_width = 0;
char *position_time = NULL, *length_time = NULL, *filename = NULL;
static int Menu_GetMusicList(void) {
SceUID dir = 0;
if (R_SUCCEEDED(dir = sceIoDopen(cwd))) {
int entryCount = 0, i = 0;
SceIoDirent *entries = (SceIoDirent *)calloc(MAX_FILES, sizeof(SceIoDirent));
while (sceIoDread(dir, &entries[entryCount]) > 0)
entryCount++;
sceIoDclose(dir);
qsort(entries, entryCount, sizeof(SceIoDirent), Utils_Alphasort);
for (i = 0; i < entryCount; i++) {
if ((!strncasecmp(FS_GetFileExt(entries[i].d_name), "flac", 4)) || (!strncasecmp(FS_GetFileExt(entries[i].d_name), "mp3", 3)) || (!strncasecmp(FS_GetFileExt(entries[i].d_name), "ogg", 3))
|| (!strncasecmp(FS_GetFileExt(entries[i].d_name), "wav", 3)) || (!strncasecmp(FS_GetFileExt(entries[i].d_name), "xm", 2))) {
strcpy(playlist[count], cwd);
strcpy(playlist[count] + strlen(playlist[count]), entries[i].d_name);
count++;
}
}
free(entries);
}
else {
sceIoDclose(dir);
return dir;
}
return 0;
}
static int Music_GetCurrentIndex(char *path) {
for(int i = 0; i < count; ++i) {
if (!strcmp(playlist[i], path))
return i;
}
return 0;
}
static void Menu_ConvertSecondsToString(char *string, SceUInt64 seconds) {
int h = 0, m = 0, s = 0;
h = (seconds / 3600);
m = (seconds - (3600 * h)) / 60;
s = (seconds - (3600 * h) - (m * 60));
if (h > 0)
snprintf(string, 35, "%02d:%02d:%02d", h, m, s);
else
snprintf(string, 35, "%02d:%02d", m, s);
}
static void Menu_InitMusic(char *path) {
Audio_Init(path);
filename = malloc(128);
snprintf(filename, 128, Utils_Basename(path));
position_time = malloc(35);
length_time = malloc(35);
length_time_width = 0;
Menu_ConvertSecondsToString(length_time, Audio_GetLengthSeconds());
length_time_width = vita2d_font_text_width(font, 25, length_time);
selection = Music_GetCurrentIndex(path);
}
static void Music_HandleNext(SceBool forward, int state) {
if (state == MUSIC_STATE_NONE) {
if (forward)
selection++;
else
selection--;
}
else if (state == MUSIC_STATE_SHUFFLE) {
int old_selection = selection;
time_t t;
srand((unsigned) time(&t));
selection = rand() % (count - 1);
if (selection == old_selection)
selection--;
}
Utils_SetMax(&selection, 0, (count - 1));
Utils_SetMin(&selection, (count - 1), 0);
Audio_Stop();
free(filename);
free(length_time);
free(position_time);
if ((metadata.has_meta) && (metadata.cover_image)) {
vita2d_wait_rendering_done();
vita2d_free_texture(metadata.cover_image);
}
Audio_Term();
Menu_InitMusic(playlist[selection]);
}
void Menu_PlayAudio(char *path) {
Menu_GetMusicList();
Menu_InitMusic(path);
while(SCE_TRUE) {
vita2d_start_drawing();
vita2d_clear_screen();
vita2d_draw_texture(default_artwork_blur, 0, 0);
vita2d_draw_rectangle(0, 0, 960, 40, RGBA8(97, 97, 97, 255));
vita2d_draw_texture(icon_back, 10, 57);
StatusBar_Display();
if ((metadata.has_meta) && (strlen(metadata.title) != 0) && (strlen(metadata.artist) != 0)) {
vita2d_font_draw_text(font, 80, 22 + (80 - vita2d_font_text_height(font, 25, strupr(metadata.title))) + 20, RGBA8(255, 255, 255, 255), 25, strupr(metadata.title));
vita2d_font_draw_text(font, 80, 22 + (80 - vita2d_font_text_height(font, 25, strupr(metadata.artist))) + 55, RGBA8(255, 255, 255, 255), 25, strupr(metadata.artist));
}
else if ((metadata.has_meta) && (strlen(metadata.title) != 0))
vita2d_font_draw_text(font, 80, 22 + (80 - vita2d_font_text_height(font, 25, strupr(metadata.title))) + 15, RGBA8(255, 255, 255, 255), 25, strupr(metadata.title));
else if (!metadata.has_meta)
vita2d_font_draw_text(font, 80, 22 + (80 - vita2d_font_text_height(font, 25, strupr(filename))) + 15, RGBA8(255, 255, 255, 255), 25, filename);
vita2d_draw_rectangle(0, 124, 400, 400, RGBA8(97, 97, 97, 255));
if ((metadata.has_meta) && (metadata.cover_image))
vita2d_draw_texture_scale(metadata.cover_image, 0, 124, 400.0f/vita2d_texture_get_width(metadata.cover_image), 400.0f/vita2d_texture_get_height(metadata.cover_image));
else
vita2d_draw_texture(default_artwork, 0, 124); // Default album art
vita2d_draw_rectangle(410, 124, 550, 400, RGBA8(45, 48, 50, 255)); // Draw info box (outer)
vita2d_draw_rectangle(420, 134, 530, 380, RGBA8(46, 49, 51, 255)); // Draw info box (inner)
if (!Audio_IsPaused())
vita2d_draw_texture(btn_pause, 410 + ((550 - BUTTON_WIDTH) / 2), 124 + ((400 - BUTTON_HEIGHT) / 2)); // Playing
else
vita2d_draw_texture(btn_play, 410 + ((550 - BUTTON_WIDTH) / 2), 124 + ((400 - BUTTON_HEIGHT) / 2)); // Paused
vita2d_draw_texture(btn_rewind, 410 + ((550 - BUTTON_WIDTH) / 2) - 136, 124 + ((400 - BUTTON_HEIGHT) / 2));
vita2d_draw_texture(btn_forward, 410 + ((550 - BUTTON_WIDTH) / 2) + 136, 124 + ((400 - BUTTON_HEIGHT) / 2));
vita2d_draw_texture(state == MUSIC_STATE_SHUFFLE? btn_shuffle_overlay : btn_shuffle, 410 + ((550 - BUTTON_WIDTH) / 2) - 90, 124 + ((400 - BUTTON_HEIGHT) / 2) + 100);
vita2d_draw_texture(state == MUSIC_STATE_REPEAT? btn_repeat_overlay : btn_repeat, 410 + ((550 - BUTTON_WIDTH) / 2) + 90, 124 + ((400 - BUTTON_HEIGHT) / 2) + 100);
Menu_ConvertSecondsToString(position_time, Audio_GetPositionSeconds());
vita2d_font_draw_text(font, 460, 480, RGBA8(255, 255, 255, 255), 25, position_time);
vita2d_font_draw_text(font, 910 - length_time_width, 480, RGBA8(255, 255, 255, 255), 25, length_time);
vita2d_draw_rectangle(460, 490, 450, 4, RGBA8(97, 97, 97, 255));
vita2d_draw_rectangle(460, 490, (((double)Audio_GetPosition()/(double)Audio_GetLength()) * 450.0), 4, RGBA8(255, 255, 255, 255));
vita2d_end_drawing();
vita2d_swap_buffers();
if (!playing) {
if (state == MUSIC_STATE_NONE)
break;
else if (state == MUSIC_STATE_REPEAT)
Music_HandleNext(SCE_FALSE, MUSIC_STATE_REPEAT);
else if (state == MUSIC_STATE_SHUFFLE) {
if (count != 0)
Music_HandleNext(SCE_FALSE, MUSIC_STATE_SHUFFLE);
}
}
Utils_ReadControls();
if (pressed & SCE_CTRL_ENTER)
Audio_Pause();
if (pressed & SCE_CTRL_TRIANGLE) {
if (state == MUSIC_STATE_SHUFFLE)
state = MUSIC_STATE_NONE;
else
state = MUSIC_STATE_SHUFFLE;
}
else if (pressed & SCE_CTRL_SQUARE) {
if (state == MUSIC_STATE_REPEAT)
state = MUSIC_STATE_NONE;
else
state = MUSIC_STATE_REPEAT;
}
if (pressed & SCE_CTRL_LTRIGGER) {
if (count != 0)
Music_HandleNext(SCE_FALSE, MUSIC_STATE_NONE);
}
else if (pressed & SCE_CTRL_RTRIGGER) {
if (count != 0)
Music_HandleNext(SCE_TRUE, MUSIC_STATE_NONE);
}
if (pressed & SCE_CTRL_CANCEL)
break;
}
free(filename);
free(length_time);
free(position_time);
if ((metadata.has_meta) && (metadata.cover_image)) {
vita2d_wait_rendering_done();
vita2d_free_texture(metadata.cover_image);
}
Audio_Stop();
Audio_Term();
count = 0;
Menu_DisplayFiles();
}

View File

@ -0,0 +1,56 @@
#include <string.h>
#include "common.h"
#include "dirbrowse.h"
#include "status_bar.h"
#include "textures.h"
#include "utils.h"
static void Menu_HandleControls(void) {
if (file_count > 0) {
if (pressed & SCE_CTRL_UP)
position--;
else if (pressed & SCE_CTRL_DOWN)
position++;
Utils_SetMax(&position, 0, file_count - 1);
Utils_SetMin(&position, file_count - 1, 0);
if (pressed & SCE_CTRL_LEFT)
position = 0;
else if (pressed & SCE_CTRL_RIGHT)
position = file_count - 1;
if (pressed & SCE_CTRL_ENTER)
Dirbrowse_OpenFile();
if ((strcmp(cwd, ROOT_PATH) != 0) && (pressed & SCE_CTRL_CANCEL)) {
Dirbrowse_Navigate(SCE_TRUE);
Dirbrowse_PopulateFiles(SCE_TRUE);
}
}
}
void Menu_DisplayFiles(void) {
Dirbrowse_PopulateFiles(SCE_FALSE);
vita2d_set_clear_color(RGBA8(250, 250, 250, 255));
while (SCE_TRUE) {
vita2d_start_drawing();
vita2d_clear_screen();
vita2d_draw_rectangle(0, 0, 960, 40, RGBA8(40, 40, 40, 255));
vita2d_draw_rectangle(0, 40, 960, 72, RGBA8(51, 51, 51, 255));
StatusBar_Display();
Dirbrowse_DisplayFiles();
vita2d_end_drawing();
vita2d_swap_buffers();
Utils_ReadControls();
Menu_HandleControls();
if (pressed & SCE_CTRL_START)
break;
}
}

105
source/status_bar.c Normal file
View File

@ -0,0 +1,105 @@
#include <psp2/power.h>
#include <psp2/rtc.h>
#include <stdio.h>
#include "common.h"
#include "textures.h"
static int percent_width = 0;
static char *StatusBar_GetCurrentTime(void) {
static char buffer[27];
SceDateTime time;
sceRtcGetCurrentClockLocalTime(&time);
int hours = sceRtcGetHour(&time);
int am_or_pm = 0;
if (hours < 12)
am_or_pm = 1;
if (hours == 0)
hours = 12;
else if (hours > 12)
hours = hours - 12;
if ((hours >= 1) && (hours < 10))
snprintf(buffer, 27, "%2i:%02i %s", hours, sceRtcGetMinute(&time), am_or_pm ? "AM" : "PM");
else
snprintf(buffer, 27, "%2i:%02i %s", hours, sceRtcGetMinute(&time), am_or_pm ? "AM" : "PM");
return buffer;
}
static void StatusBar_GetBatteryStatus(int x, int y) {
int percent = 0;
SceBool state = SCE_FALSE;
char buf[13];
if (R_FAILED(state = scePowerIsBatteryCharging()))
state = SCE_FALSE;
if (R_SUCCEEDED(percent = scePowerGetBatteryLifePercent())) {
if (percent < 20)
vita2d_draw_texture(battery_low, x, 4);
else if ((percent >= 20) && (percent < 30)) {
if (state)
vita2d_draw_texture(battery_20_charging, x, 4);
else
vita2d_draw_texture(battery_20, x, 4);
}
else if ((percent >= 30) && (percent < 50)) {
if (state)
vita2d_draw_texture(battery_50_charging, x, 4);
else
vita2d_draw_texture(battery_50, x, 4);
}
else if ((percent >= 50) && (percent < 60)) {
if (state)
vita2d_draw_texture(battery_50_charging, x, 4);
else
vita2d_draw_texture(battery_50, x, 4);
}
else if ((percent >= 60) && (percent < 80)) {
if (state)
vita2d_draw_texture(battery_60_charging, x, 4);
else
vita2d_draw_texture(battery_60, x, 4);
}
else if ((percent >= 80) && (percent < 90)) {
if (state)
vita2d_draw_texture(battery_80_charging, x, 4);
else
vita2d_draw_texture(battery_80, x, 4);
}
else if ((percent >= 90) && (percent < 100)) {
if (state)
vita2d_draw_texture(battery_90_charging, x, 4);
else
vita2d_draw_texture(battery_90, x, 4);
}
else if (percent == 100) {
if (state)
vita2d_draw_texture(battery_full_charging, x, 4);
else
vita2d_draw_texture(battery_full, x, 4);
}
snprintf(buf, 13, "%d%%", percent);
percent_width = vita2d_font_text_width(font, 25, buf);
vita2d_font_draw_text(font, (x - percent_width - 5), y, RGBA8(255, 255, 255, 255), 25, buf);
}
else {
snprintf(buf, 13, "%d%%", percent);
percent_width = vita2d_font_text_width(font, 25, buf);
vita2d_font_draw_text(font, (x - percent_width - 5), y, RGBA8(255, 255, 255, 255), 25, buf);
vita2d_draw_texture(battery_unknown, x, 4);
}
}
void StatusBar_Display(void) {
int width = 0, height = 0;
vita2d_font_text_dimensions(font, 25, StatusBar_GetCurrentTime(), &width, &height);
StatusBar_GetBatteryStatus(((950 - width) - (32 + 10)), ((40 - height) / 2) + 25);
vita2d_font_draw_text(font, (950 - width), ((40 - height) / 2) + 25, RGBA8(255, 255, 255, 255), 25, StatusBar_GetCurrentTime());
}

118
source/textures.c Normal file
View File

@ -0,0 +1,118 @@
#include <psp2/types.h>
#include "textures.h"
extern SceUChar8 _binary_res_battery_20_png_start;
extern SceUChar8 _binary_res_battery_30_png_start;
extern SceUChar8 _binary_res_battery_50_png_start;
extern SceUChar8 _binary_res_battery_60_png_start;
extern SceUChar8 _binary_res_battery_80_png_start;
extern SceUChar8 _binary_res_battery_90_png_start;
extern SceUChar8 _binary_res_battery_full_png_start;
extern SceUChar8 _binary_res_battery_20_charging_png_start;
extern SceUChar8 _binary_res_battery_30_charging_png_start;
extern SceUChar8 _binary_res_battery_50_charging_png_start;
extern SceUChar8 _binary_res_battery_60_charging_png_start;
extern SceUChar8 _binary_res_battery_80_charging_png_start;
extern SceUChar8 _binary_res_battery_90_charging_png_start;
extern SceUChar8 _binary_res_battery_full_charging_png_start;
extern SceUChar8 _binary_res_battery_low_png_start;
extern SceUChar8 _binary_res_battery_unknown_png_start;
extern SceUChar8 _binary_res_icon_audio_png_start;
extern SceUChar8 _binary_res_icon_file_png_start;
extern SceUChar8 _binary_res_icon_folder_png_start;
extern SceUChar8 _binary_res_icon_back_png_start;
extern SceUChar8 _binary_res_btn_playback_forward_png_start;
extern SceUChar8 _binary_res_btn_playback_pause_png_start;
extern SceUChar8 _binary_res_btn_playback_play_png_start;
extern SceUChar8 _binary_res_btn_playback_repeat_png_start;
extern SceUChar8 _binary_res_btn_playback_repeat_overlay_png_start;
extern SceUChar8 _binary_res_btn_playback_rewind_png_start;
extern SceUChar8 _binary_res_btn_playback_shuffle_png_start;
extern SceUChar8 _binary_res_btn_playback_shuffle_overlay_png_start;
extern SceUChar8 _binary_res_default_artwork_png_start;
extern SceUChar8 _binary_res_default_artwork_blur_png_start;
static vita2d_texture *Texture_LoadImageBilinear(SceUChar8 *buffer) {
vita2d_texture *texture = vita2d_load_PNG_buffer(buffer);
vita2d_texture_set_filters(texture, SCE_GXM_TEXTURE_FILTER_LINEAR, SCE_GXM_TEXTURE_FILTER_LINEAR);
return texture;
}
void Textures_Load(void) {
battery_20 = Texture_LoadImageBilinear(&_binary_res_battery_20_png_start);
battery_30 = Texture_LoadImageBilinear(&_binary_res_battery_30_png_start);
battery_50 = Texture_LoadImageBilinear(&_binary_res_battery_50_png_start);
battery_60 = Texture_LoadImageBilinear(&_binary_res_battery_60_png_start);
battery_80 = Texture_LoadImageBilinear(&_binary_res_battery_80_png_start);
battery_90 = Texture_LoadImageBilinear(&_binary_res_battery_90_png_start);
battery_full = Texture_LoadImageBilinear(&_binary_res_battery_full_png_start);
battery_20_charging = Texture_LoadImageBilinear(&_binary_res_battery_20_charging_png_start);
battery_30_charging = Texture_LoadImageBilinear(&_binary_res_battery_30_charging_png_start);
battery_50_charging = Texture_LoadImageBilinear(&_binary_res_battery_50_charging_png_start);
battery_60_charging = Texture_LoadImageBilinear(&_binary_res_battery_60_charging_png_start);
battery_80_charging = Texture_LoadImageBilinear(&_binary_res_battery_80_charging_png_start);
battery_90_charging = Texture_LoadImageBilinear(&_binary_res_battery_90_charging_png_start);
battery_full_charging = Texture_LoadImageBilinear(&_binary_res_battery_full_charging_png_start);
battery_low = Texture_LoadImageBilinear(&_binary_res_battery_low_png_start);
battery_unknown = Texture_LoadImageBilinear(&_binary_res_battery_unknown_png_start);
icon_audio = Texture_LoadImageBilinear(&_binary_res_icon_audio_png_start);
icon_file = Texture_LoadImageBilinear(&_binary_res_icon_file_png_start);
icon_dir = Texture_LoadImageBilinear(&_binary_res_icon_folder_png_start);
icon_back = Texture_LoadImageBilinear(&_binary_res_icon_back_png_start);
btn_forward = Texture_LoadImageBilinear(&_binary_res_btn_playback_forward_png_start);
btn_pause = Texture_LoadImageBilinear(&_binary_res_btn_playback_pause_png_start);
btn_play = Texture_LoadImageBilinear(&_binary_res_btn_playback_play_png_start);
btn_repeat = Texture_LoadImageBilinear(&_binary_res_btn_playback_repeat_png_start);
btn_repeat_overlay = Texture_LoadImageBilinear(&_binary_res_btn_playback_repeat_overlay_png_start);
btn_rewind = Texture_LoadImageBilinear(&_binary_res_btn_playback_rewind_png_start);
btn_shuffle = Texture_LoadImageBilinear(&_binary_res_btn_playback_shuffle_png_start);
btn_shuffle_overlay = Texture_LoadImageBilinear(&_binary_res_btn_playback_shuffle_overlay_png_start);
default_artwork = Texture_LoadImageBilinear(&_binary_res_default_artwork_png_start);
default_artwork_blur = Texture_LoadImageBilinear(&_binary_res_default_artwork_blur_png_start);
}
void Textures_Free(void) {
vita2d_free_texture(default_artwork_blur);
vita2d_free_texture(default_artwork);
vita2d_free_texture(btn_shuffle_overlay);
vita2d_free_texture(btn_shuffle);
vita2d_free_texture(btn_rewind);
vita2d_free_texture(btn_repeat_overlay);
vita2d_free_texture(btn_repeat);
vita2d_free_texture(btn_play);
vita2d_free_texture(btn_pause);
vita2d_free_texture(btn_forward);
vita2d_free_texture(icon_back);
vita2d_free_texture(icon_dir);
vita2d_free_texture(icon_file);
vita2d_free_texture(icon_audio);
vita2d_free_texture(battery_unknown);
vita2d_free_texture(battery_low);
vita2d_free_texture(battery_full_charging);
vita2d_free_texture(battery_90_charging);
vita2d_free_texture(battery_80_charging);
vita2d_free_texture(battery_60_charging);
vita2d_free_texture(battery_50_charging);
vita2d_free_texture(battery_30_charging);
vita2d_free_texture(battery_20_charging);
vita2d_free_texture(battery_full);
vita2d_free_texture(battery_90);
vita2d_free_texture(battery_80);
vita2d_free_texture(battery_60);
vita2d_free_texture(battery_50);
vita2d_free_texture(battery_30);
vita2d_free_texture(battery_20);
}

92
source/utils.c Normal file
View File

@ -0,0 +1,92 @@
#include <psp2/apputil.h>
#include <psp2/io/dirent.h>
#include <psp2/system_param.h>
#include <string.h>
#include "common.h"
static SceCtrlData pad, old_pad;
void Utils_SetMax(int *set, int value, int max) {
if (*set > max)
*set = value;
}
void Utils_SetMin(int *set, int value, int min) {
if (*set < min)
*set = value;
}
int Utils_ReadControls(void) {
memset(&pad, 0, sizeof(SceCtrlData));
sceCtrlPeekBufferPositive(0, &pad, 1);
pressed = pad.buttons & ~old_pad.buttons;
old_pad = pad;
return 0;
}
int Utils_InitAppUtil(void) {
SceAppUtilInitParam init;
SceAppUtilBootParam boot;
memset(&init, 0, sizeof(SceAppUtilInitParam));
memset(&boot, 0, sizeof(SceAppUtilBootParam));
int ret = 0;
if (R_FAILED(ret = sceAppUtilInit(&init, &boot)))
return ret;
return 0;
}
int Utils_TermAppUtil(void) {
int ret = 0;
if (R_FAILED(ret = sceAppUtilShutdown()))
return ret;
return 0;
}
int Utils_GetEnterButton(void) {
int button = 0;
sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button);
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
return SCE_CTRL_CIRCLE;
else
return SCE_CTRL_CROSS;
return 0;
}
int Utils_GetCancelButton(void) {
int button = 0;
sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button);
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE)
return SCE_CTRL_CROSS;
else
return SCE_CTRL_CIRCLE;
return 0;
}
int Utils_Alphasort(const void *p1, const void *p2) {
SceIoDirent *entryA = (SceIoDirent *) p1;
SceIoDirent *entryB = (SceIoDirent *) p2;
if ((SCE_S_ISDIR(entryA->d_stat.st_mode)) && !(SCE_S_ISDIR(entryB->d_stat.st_mode)))
return -1;
else if (!(SCE_S_ISDIR(entryA->d_stat.st_mode)) && (SCE_S_ISDIR(entryB->d_stat.st_mode)))
return 1;
return strcasecmp(entryA->d_name, entryB->d_name);
}
char *Utils_Basename(const char *filename) {
char *p = strrchr (filename, '/');
return p ? p + 1 : (char *) filename;
}