Skip to content

Commit

Permalink
Backport gtasa changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOfficialFloW committed Apr 24, 2021
1 parent 5d226d7 commit b751a62
Show file tree
Hide file tree
Showing 24 changed files with 1,118 additions and 179 deletions.
16 changes: 13 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,55 @@ set(VITA_APP_NAME "Bully")
set(VITA_TITLEID "BULLY0000")
set(VITA_MKSFOEX_FLAGS "-d ATTRIBUTE2=12")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wl,-q -Wall -O3 -mfloat-abi=softfp")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wl,-q,--wrap,memcpy,--wrap,memmove,--wrap,memset -Wall -O3 -mfloat-abi=softfp")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11")

add_executable(Bully
main.c
dialog.c
fios.c
so_util.c
jni_patch.c
mpg123_patch.c
openal_patch.c
opengl_patch.c
sha1.c
)

target_link_libraries(Bully
-Wl,--whole-archive pthread -Wl,--no-whole-archive
stdc++
m
mathneon
mpg123
openal
vitaGL
vitashark
kubridge_stub
SceAppMgr_stub
SceAppUtil_stub
SceAudio_stub
SceAudioIn_stub
SceCtrl_stub
SceCommonDialog_stub
SceDisplay_stub
SceFios2_stub
SceGxm_stub
SceLibcBridge_stub
SceShaccCg_stub
SceSysmodule_stub
ScePower_stub
SceTouch_stub
SceAppUtil_stub
SceVshBridge_stub
)

vita_create_self(eboot.bin Bully UNSAFE)
vita_create_vpk(Bully.vpk ${VITA_TITLEID} eboot.bin
VERSION ${VITA_VERSION}
NAME ${VITA_APP_NAME}
FILE ${CMAKE_SOURCE_DIR}/sce_sys/icon0.png sce_sys/icon0.png
${CMAKE_SOURCE_DIR}/sce_sys/livearea/contents/bg.png sce_sys/livearea/contents/bg.png
${CMAKE_SOURCE_DIR}/sce_sys/livearea/contents/startup.png sce_sys/livearea/contents/startup.png
${CMAKE_SOURCE_DIR}/sce_sys/livearea/contents/template.xml sce_sys/livearea/contents/template.xml
)

add_custom_target(copy
Expand Down
10 changes: 9 additions & 1 deletion config.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__

// #define DEBUG

#define LOAD_ADDRESS 0x98000000

#define MEMORY_MB 128
#define MEMORY_SCELIBC_MB 4
#define MEMORY_NEWLIB_MB 128
#define MEMORY_VITAGL_THRESHOLD_MB 16

#define DATA_PATH "ux0:data/Bully"
#define SO_PATH DATA_PATH "/" "libBully.so"
#define CONFIG_PATH DATA_PATH "/" "config.txt"
#define GLSL_PATH DATA_PATH "/" "glsl"
#define GXP_PATH DATA_PATH "/" "gxp"

#define SCREEN_W 960
#define SCREEN_H 544

#define TOUCH_X_MARGIN 100

#endif
144 changes: 144 additions & 0 deletions dialog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* dialog.c -- common dialog for error messages and cheats input
*
* Copyright (C) 2021 fgsfds, Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

#include <psp2/kernel/processmgr.h>
#include <psp2/ctrl.h>
#include <psp2/ime_dialog.h>
#include <psp2/message_dialog.h>
#include <vitaGL.h>

#include <stdio.h>
#include <stdarg.h>

#include "main.h"
#include "dialog.h"

static uint16_t ime_title_utf16[SCE_IME_DIALOG_MAX_TITLE_LENGTH];
static uint16_t ime_initial_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH];
static uint16_t ime_input_text_utf16[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1];
static uint8_t ime_input_text_utf8[SCE_IME_DIALOG_MAX_TEXT_LENGTH + 1];

void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
for (int i = 0; src[i]; i++) {
if ((src[i] & 0xFF80) == 0) {
*(dst++) = src[i] & 0xFF;
} else if((src[i] & 0xF800) == 0) {
*(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0;
*(dst++) = (src[i] & 0x3F) | 0x80;
} else if((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) {
*(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0;
*(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80;
*(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF);
*(dst++) = (src[i + 1] & 0x3F) | 0x80;
i += 1;
} else {
*(dst++) = ((src[i] >> 12) & 0xF) | 0xE0;
*(dst++) = ((src[i] >> 6) & 0x3F) | 0x80;
*(dst++) = (src[i] & 0x3F) | 0x80;
}
}

*dst = '\0';
}

void utf8_to_utf16(const uint8_t *src, uint16_t *dst) {
for (int i = 0; src[i];) {
if ((src[i] & 0xE0) == 0xE0) {
*(dst++) = ((src[i] & 0x0F) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F);
i += 3;
} else if ((src[i] & 0xC0) == 0xC0) {
*(dst++) = ((src[i] & 0x1F) << 6) | (src[i + 1] & 0x3F);
i += 2;
} else {
*(dst++) = src[i];
i += 1;
}
}

*dst = '\0';
}

int init_ime_dialog(const char *title, const char *initial_text) {
memset(ime_title_utf16, 0, sizeof(ime_title_utf16));
memset(ime_initial_text_utf16, 0, sizeof(ime_initial_text_utf16));
memset(ime_input_text_utf16, 0, sizeof(ime_input_text_utf16));
memset(ime_input_text_utf8, 0, sizeof(ime_input_text_utf8));

utf8_to_utf16((uint8_t *)title, ime_title_utf16);
utf8_to_utf16((uint8_t *)initial_text, ime_initial_text_utf16);

SceImeDialogParam param;
sceImeDialogParamInit(&param);

param.supportedLanguages = 0x0001FFFF;
param.languagesForced = SCE_TRUE;
param.type = SCE_IME_TYPE_BASIC_LATIN;
param.title = ime_title_utf16;
param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH;
param.initialText = ime_initial_text_utf16;
param.inputTextBuffer = ime_input_text_utf16;

return sceImeDialogInit(&param);
}

char *get_ime_dialog_result(void) {
if (sceImeDialogGetStatus() != SCE_COMMON_DIALOG_STATUS_FINISHED)
return NULL;

SceImeDialogResult result;
memset(&result, 0, sizeof(SceImeDialogResult));
sceImeDialogGetResult(&result);
if (result.button == SCE_IME_DIALOG_BUTTON_ENTER)
utf16_to_utf8(ime_input_text_utf16, ime_input_text_utf8);
sceImeDialogTerm();
// For some reason analog stick stops working after ime
sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE);

return (char *)ime_input_text_utf8;
}

int init_msg_dialog(const char *msg) {
SceMsgDialogUserMessageParam msg_param;
memset(&msg_param, 0, sizeof(msg_param));
msg_param.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_OK;
msg_param.msg = (SceChar8 *)msg;

SceMsgDialogParam param;
sceMsgDialogParamInit(&param);
_sceCommonDialogSetMagicNumber(&param.commonParam);
param.mode = SCE_MSG_DIALOG_MODE_USER_MSG;
param.userMsgParam = &msg_param;

return sceMsgDialogInit(&param);
}

int get_msg_dialog_result(void) {
if (sceMsgDialogGetStatus() != SCE_COMMON_DIALOG_STATUS_FINISHED)
return 0;
sceMsgDialogTerm();
return 1;
}

void fatal_error(const char *fmt, ...) {
va_list list;
char string[512];

va_start(list, fmt);
vsnprintf(string, sizeof(string), fmt, list);
va_end(list);

vglInit(0);

init_msg_dialog(string);

while (!get_msg_dialog_result())
vglSwapBuffers(GL_TRUE);

sceKernelExitProcess(0);
while (1);
}
12 changes: 12 additions & 0 deletions dialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef __DIALOG_H__
#define __DIALOG_H__

int init_ime_dialog(const char *title, const char *initial_text);
char *get_ime_dialog_result(void);

int init_msg_dialog(const char *msg);
int get_msg_dialog_result(void);

void fatal_error(const char *fmt, ...) __attribute__((noreturn));

#endif
74 changes: 74 additions & 0 deletions fios.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* fios.c -- use FIOS2 for optimized I/O
*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

#include <malloc.h>
#include <stdio.h>
#include <string.h>

#include "main.h"
#include "config.h"
#include "fios.h"
#include "so_util.h"

#define MAX_PATH_LENGTH 256
#define RAMCACHEBLOCKSIZE (64 * 1024)
#define RAMCACHEBLOCKNUM 128

static int64_t g_OpStorage[SCE_FIOS_OP_STORAGE_SIZE(64, MAX_PATH_LENGTH) / sizeof(int64_t) + 1];
static int64_t g_ChunkStorage[SCE_FIOS_CHUNK_STORAGE_SIZE(1024) / sizeof(int64_t) + 1];
static int64_t g_FHStorage[SCE_FIOS_FH_STORAGE_SIZE(128, MAX_PATH_LENGTH) / sizeof(int64_t) + 1];
static int64_t g_DHStorage[SCE_FIOS_DH_STORAGE_SIZE(32, MAX_PATH_LENGTH) / sizeof(int64_t) + 1];

static SceFiosRamCacheContext g_RamCacheContext = SCE_FIOS_RAM_CACHE_CONTEXT_INITIALIZER;
static char *g_RamCacheWorkBuffer;

int fios_init(void) {
int res;

SceFiosParams params = SCE_FIOS_PARAMS_INITIALIZER;
params.opStorage.pPtr = g_OpStorage;
params.opStorage.length = sizeof(g_OpStorage);
params.chunkStorage.pPtr = g_ChunkStorage;
params.chunkStorage.length = sizeof(g_ChunkStorage);
params.fhStorage.pPtr = g_FHStorage;
params.fhStorage.length = sizeof(g_FHStorage);
params.dhStorage.pPtr = g_DHStorage;
params.dhStorage.length = sizeof(g_DHStorage);
params.pathMax = MAX_PATH_LENGTH;

params.threadAffinity[SCE_FIOS_IO_THREAD] = 0x20000;
params.threadAffinity[SCE_FIOS_CALLBACK_THREAD] = 0;
params.threadAffinity[SCE_FIOS_DECOMPRESSOR_THREAD] = 0;

params.threadPriority[SCE_FIOS_IO_THREAD] = 64;
params.threadPriority[SCE_FIOS_CALLBACK_THREAD] = 191;
params.threadPriority[SCE_FIOS_DECOMPRESSOR_THREAD] = 191;

res = sceFiosInitialize(&params);
if (res < 0)
return res;

g_RamCacheWorkBuffer = memalign(8, RAMCACHEBLOCKNUM * RAMCACHEBLOCKSIZE);
if (!g_RamCacheWorkBuffer)
return -1;

g_RamCacheContext.pPath = DATA_PATH;
g_RamCacheContext.pWorkBuffer = g_RamCacheWorkBuffer;
g_RamCacheContext.workBufferSize = RAMCACHEBLOCKNUM * RAMCACHEBLOCKSIZE;
g_RamCacheContext.blockSize = RAMCACHEBLOCKSIZE;
res = sceFiosIOFilterAdd(0, sceFiosIOFilterCache, &g_RamCacheContext);
if (res < 0)
return res;

return 0;
}

void fios_terminate(void) {
sceFiosTerminate();
free(g_RamCacheWorkBuffer);
}
79 changes: 79 additions & 0 deletions fios.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#ifndef __FIOS_H__
#define __FIOS_H__

#define SCE_FIOS_FH_SIZE 80
#define SCE_FIOS_DH_SIZE 80
#define SCE_FIOS_OP_SIZE 168
#define SCE_FIOS_CHUNK_SIZE 64

#define SCE_FIOS_ALIGN_UP(val, align) (((val) + ((align) - 1)) & ~((align) - 1))
#define SCE_FIOS_STORAGE_SIZE(num, size) (((num) * (size)) + SCE_FIOS_ALIGN_UP(SCE_FIOS_ALIGN_UP((num), 8) / 8, 8))

#define SCE_FIOS_DH_STORAGE_SIZE(numDHs, pathMax) SCE_FIOS_STORAGE_SIZE(numDHs, SCE_FIOS_DH_SIZE + pathMax)
#define SCE_FIOS_FH_STORAGE_SIZE(numFHs, pathMax) SCE_FIOS_STORAGE_SIZE(numFHs, SCE_FIOS_FH_SIZE + pathMax)
#define SCE_FIOS_OP_STORAGE_SIZE(numOps, pathMax) SCE_FIOS_STORAGE_SIZE(numOps, SCE_FIOS_OP_SIZE + pathMax)
#define SCE_FIOS_CHUNK_STORAGE_SIZE(numChunks) SCE_FIOS_STORAGE_SIZE(numChunks, SCE_FIOS_CHUNK_SIZE)

#define SCE_FIOS_BUFFER_INITIALIZER { 0, 0 }
#define SCE_FIOS_PARAMS_INITIALIZER { 0, sizeof(SceFiosParams), 0, 0, 2, 1, 0, 0, 256 * 1024, 2, 0, 0, 0, 0, 0, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, SCE_FIOS_BUFFER_INITIALIZER, NULL, NULL, NULL, { 66, 189, 66 }, { 0x40000, 0, 0x40000}, { 8 * 1024, 16 * 1024, 8 * 1024}}
#define SCE_FIOS_RAM_CACHE_CONTEXT_INITIALIZER { sizeof(SceFiosRamCacheContext), 0, (64 * 1024), NULL, NULL, 0, {0, 0, 0} }

typedef enum SceFiosThreadType {
SCE_FIOS_IO_THREAD = 0,
SCE_FIOS_DECOMPRESSOR_THREAD = 1,
SCE_FIOS_CALLBACK_THREAD = 2,
SCE_FIOS_THREAD_TYPES = 3
} SceFiosThreadType;

typedef struct SceFiosRamCacheContext {
size_t sizeOfContext;
size_t workBufferSize;
size_t blockSize;
void *pWorkBuffer;
const char *pPath;
intptr_t flags;
intptr_t reserved[3];
} SceFiosRamCacheContext;

typedef struct SceFiosBuffer {
void *pPtr;
size_t length;
} SceFiosBuffer;

typedef struct SceFiosParams {
uint32_t initialized : 1;
uint32_t paramsSize : 15;
uint32_t pathMax : 16;
uint32_t profiling;
uint32_t ioThreadCount;
uint32_t threadsPerScheduler;
uint32_t extraFlag1 : 1;
uint32_t extraFlags : 31;
uint32_t maxChunk;
uint8_t maxDecompressorThreadCount;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
intptr_t reserved4;
intptr_t reserved5;
SceFiosBuffer opStorage;
SceFiosBuffer fhStorage;
SceFiosBuffer dhStorage;
SceFiosBuffer chunkStorage;
void *pVprintf;
void *pMemcpy;
void *pProfileCallback;
int threadPriority[3];
int threadAffinity[3];
int threadStackSize[3];
} SceFiosParams;

int sceFiosInitialize(const SceFiosParams *params);
void sceFiosTerminate();

int sceFiosIOFilterAdd(int index, void *pFilterCallback, void *pFilterContext);
void sceFiosIOFilterCache();

int fios_init(void);

#endif
Loading

0 comments on commit b751a62

Please sign in to comment.