Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Vita port. #818

Draft
wants to merge 1 commit into
base: vanilla
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions cmake/VitaPackage.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
include (CMakeParseArguments)
include("${VITASDK}/share/vita.cmake" REQUIRED)
set(GenerateVPKCurrentDir ${CMAKE_CURRENT_LIST_DIR})

function(generate_vita_package target)
set (options)
set (oneValueArgs
APP_NAME
TITLE_ID
ICON
TEMPLATE
LOAD_IMAGE
BACKGROUND
VERSION
)
set (multiValueArgs)
cmake_parse_arguments(VITA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

get_target_property(VITA_EXECUTABLE ${target} OUTPUT_NAME)

set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d ATTRIBUTE2=12")
vita_create_self(${VITA_EXECUTABLE}.self ${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE})

if(NOT VITA_APP_NAME OR "${VITA_APP_NAME}" STREQUAL "")
set(VITA_APP_NAME "VitaApp")
endif()

if(NOT VITA_TITLE_ID OR "${VITA_TITLE_ID}" STREQUAL "")
set(VITA_TITLE_ID "UNKN00000")
endif()

if(NOT VITA_VERSION OR "${VITA_VERSION}" STREQUAL "")
set(VITA_VERSION "01.00")
endif()

if(NOT VITA_TEMPLATE OR "${VITA_TEMPLATE}" STREQUAL "")
set(VITA_TEMPLATE ${GenerateVPKCurrentDir}/template.xml)
list(APPEND VPK_FILE_LIST FILE ${VITA_TEMPLATE} sce_sys/livearea/contents/template.xml)
endif()

if(VITA_ICON)
find_package(ImageMagick COMPONENTS magick)

if(ImageMagick_magick_FOUND)
set(ImageMagick_convert_FOUND TRUE)
set(ImageMagick_convert_EXECUTABLE ${ImageMagick_magick_EXECUTABLE})
set(ImageMagick_convert_ARGS convert)
else()
find_package(ImageMagick COMPONENTS convert)
endif()

if(NOT ImageMagick_convert_FOUND)
message(WARNING "ImageMagick was not found, icons will not be generated.")
endif()

add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_icon0.png"
COMMAND ${ImageMagick_convert_EXECUTABLE} ${ImageMagick_convert_ARGS} -background none -density 72 -resize 128x128 -units "PixelsPerInch" -type Palette -colors 255 ${VITA_ICON} "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_icon0.png"
MAIN_DEPENDENCY ${VITA_ICON}
COMMENT "Vita Bubble Icon Generation: ${VITA_EXECUTABLE}_icon0.png"
)

add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_startup.png"
COMMAND ${ImageMagick_convert_EXECUTABLE} ${ImageMagick_convert_ARGS} -background none -density 72 -resize 158x158 -gravity center -extent 280x158 -type Palette -units "PixelsPerInch" -colors 255 ${VITA_ICON} "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_startup.png"
MAIN_DEPENDENCY ${VITA_ICON}
COMMENT "Vita Startup Icon Generation: ${VITA_EXECUTABLE}_startup.png"
)

add_custom_target(${VITA_EXECUTABLE}_icons
DEPENDS "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_icon0.png" "${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_startup.png"
)

list(APPEND VPK_FILE_LIST FILE ${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_icon0.png sce_sys/icon0.png)
list(APPEND VPK_FILE_LIST FILE ${CMAKE_BINARY_DIR}/${VITA_EXECUTABLE}_startup.png sce_sys/livearea/contents/startup.png)
add_dependencies(${VITA_EXECUTABLE}.self-self ${VITA_EXECUTABLE}_icons)
endif()

if(VITA_LOAD_IMAGE)
list(APPEND VPK_FILE_LIST FILE ${VITA_LOAD_IMAGE} sce_sys/pic0.png)
endif()

if(VITA_BACKGROUND)
list(APPEND VPK_FILE_LIST FILE ${VITA_BACKGROUND} sce_sys/livearea/contents/bg.png)
endif()

set(VITA_PACK_VPK_FLAGS "")

vita_create_vpk(${VITA_EXECUTABLE}.vpk ${VITA_TITLE_ID} ${CMAKE_CURRENT_BINARY_DIR}/${VITA_EXECUTABLE}.self
VERSION ${VITA_VERSION}
NAME ${VITA_APP_NAME}
${VPK_FILE_LIST}
)
add_dependencies(${VITA_EXECUTABLE}.self-self ${target})
endfunction()
11 changes: 11 additions & 0 deletions cmake/template.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>

<livearea style="psmobile" format-ver="01.00" content-rev="1">
<livearea-background>
<image>bg.png</image>
</livearea-background>

<gate>
<startup-image>startup.png</startup-image>
</gate>
</livearea>
31 changes: 31 additions & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ set(COMMON_SRC

if (WIN32)
list(APPEND COMMON_SRC file_win.cpp paths_win.cpp)
elseif(VITA)
list(APPEND COMMON_SRC file_posix.cpp paths_vita.cpp)
else()
list(APPEND COMMON_SRC file_posix.cpp paths_posix.cpp)
endif()
Expand Down Expand Up @@ -172,6 +174,35 @@ target_compile_definitions(common PRIVATE FIXIT_FAST_LOAD $<$<CONFIG:Debug>:_DEB
# Make build check state of git to check for uncommitted changes.
add_dependencies(common check_git)

if(VITA)
target_compile_definitions(common PUBLIC VITA)
target_compile_options(common PUBLIC
-O2
-mcpu=cortex-a9
-mfpu=neon
-ffast-math
-ftree-vectorize
-fno-lto
)
target_link_libraries(common PUBLIC
SceMotion_stub
SceTouch_stub
SceAudio_stub
SceAudioIn_stub
SceCtrl_stub
SceGxm_stub
SceHid_stub
SceDisplay_stub
SceSysmodule_stub
SceCommonDialog_stub
ScePower_stub
SceAppUtil_stub
-Wl,--whole-archive
pthread
-Wl,--no-whole-archive
)
endif()

if(WIN32)
if(WIN9X)
target_compile_definitions(common PUBLIC _WIN32_WINNT=0x400)
Expand Down
15 changes: 15 additions & 0 deletions common/debugstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include <io.h>
#endif

#ifdef VITA
#include <psp2/kernel/clib.h>
#endif

static class DebugStateClass
{
public:
Expand Down Expand Up @@ -66,6 +70,16 @@ void Debug_String_Log(unsigned level, const char* file, int line, const char* fm
fflush(DebugState.File);
}

#ifdef VITA
/* Don't print file and line numbers to stderr to avoid clogging it up with too much info */
va_list args;
sceClibPrintf("%-5s: ", levels[level]);
va_start(args, fmt);
char msg[200];
vsprintf(msg, fmt, args);
sceClibPrintf("%s\n", msg);
va_end(args);
#else
/* Don't print file and line numbers to stderr to avoid clogging it up with too much info */
va_list args;
fprintf(stderr, "%-5s: ", levels[level]);
Expand All @@ -74,6 +88,7 @@ void Debug_String_Log(unsigned level, const char* file, int line, const char* fm
fprintf(stderr, "\n");
va_end(args);
fflush(stderr);
#endif
}

void Debug_String_File(const char* file)
Expand Down
54 changes: 54 additions & 0 deletions common/file_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
#include <limits.h>
#include <fnmatch.h>

#ifdef VITA
// TODO More definitions to move to a compat lib that tests for the symbols?
#define PATH_MAX 256
#define FNM_CASEFOLD 0
#endif

class Find_File_Data_Posix : public Find_File_Data
{
public:
Expand Down Expand Up @@ -122,3 +128,51 @@ Find_File_Data* Find_File_Data::CreateFindData()
{
return new Find_File_Data_Posix();
}

#ifdef VITA
#include <algorithm>
#include <string>
#include <vector>

#define PATH_MAX 256

std::string StringLower(std::string str)
{
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}

// fnmatch is missing from vita newlib, this is here until otherwise.
int fnmatch(const char* pattern, const char* string, int flags)
{
//massive hackjob..
std::string filename = string;
std::string filter = pattern;
filename = StringLower(filename);
filter = StringLower(filter);
std::vector<std::string> filter_split;
std::string delimiter = "*";
bool found = true;

size_t pos = 0;
std::string token;
while ((pos = filter.find(delimiter)) != std::string::npos) {
token = filter.substr(0, pos);
filter_split.push_back(token);
filter.erase(0, pos + delimiter.length());
}

if (!filter_split.empty()) {
for (int i = 0; i < filter_split.size(); ++i) {
if (filename.find(filter_split[i]) == std::string::npos) {
found = false;
break;
}
}
} else {
found = filename.find(filter) != std::string::npos;
}

return found ? 0 : 1;
}
#endif
13 changes: 13 additions & 0 deletions common/mixfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@
#include <libgen.h> // For basename()
#endif

#ifdef VITA
// TODO Another set of functions to move to a compat lib that tests for the function?
#define PATH_MAX 256
#define basename basename_vita

// fails to link due to undefined basename. old newlib?
static char* basename_vita(const char* filename)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here. Maybe we should test if the platform has a basename implementation on build time?

{
char* p = strrchr(filename, '/');
return p ? p + 1 : (char*)filename;
}
#endif

#ifndef _MAX_PATH
#define _MAX_PATH PATH_MAX
#endif
Expand Down
2 changes: 2 additions & 0 deletions common/mssleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <winbase.h>
#elif defined(_WIN32)
#include <synchapi.h>
#elif defined VITA
#include <psp2/kernel/threadmgr.h>
#else /* Assuming recent posix*/
#define __USE_POSIX199309
#define _POSIX_C_SOURCE 199309L
Expand Down
97 changes: 97 additions & 0 deletions common/paths_vita.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.

// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection

#include "paths.h"

#include <cstring>
#include <psp2/io/dirent.h>
#include <psp2/io/stat.h>

#define PATH_MAX 256

static std::string VitaGamePath;

const char* PathsClass::Program_Path()
{
if (ProgramPath.empty()) {
ProgramPath = VitaGamePath;
}

return ProgramPath.c_str();
}

const char* PathsClass::Data_Path()
{
if (DataPath.empty()) {
if (ProgramPath.empty()) {
// Init the program path first if it hasn't been done already.
Program_Path();
}

DataPath = VitaGamePath;

if (!Suffix.empty()) {
DataPath += SEP + Suffix;
}
}

return DataPath.c_str();
}

const char* PathsClass::User_Path()
{
if (UserPath.empty()) {
UserPath = VitaGamePath;

if (!Suffix.empty()) {
UserPath += SEP + Suffix;
}

Create_Directory(UserPath.c_str());
}

return UserPath.c_str();
}

bool PathsClass::Create_Directory(const char* dirname)
{
bool ret = true;

if (dirname == nullptr) {
return ret;
}

std::string temp = dirname;
size_t pos = 0;
do {
pos = temp.find_first_of("/", pos + 1);
sceIoMkdir(temp.substr(0, pos).c_str(), 0700);
} while (pos != std::string::npos);

return ret;
}

bool PathsClass::Is_Absolute(const char* path)
{
return path != nullptr && path[0] == 'u' && path[1] == 'x' && path[2] == '0';
}

std::string PathsClass::Concatenate_Paths(const char* path1, const char* path2)
{
return std::string(path1) + SEP + path2;
}

std::string PathsClass::Argv_Path(const char* cmd_arg)
{
VitaGamePath = cmd_arg;
return VitaGamePath;
}
Loading