PSVITA port.

This commit is contained in:
Rinnegatamante 2021-07-29 23:08:40 +02:00
parent 30061396e8
commit 6cd719e8e4
57 changed files with 1617 additions and 84 deletions

7
.gitignore vendored
View File

@ -1,3 +1,10 @@
*.o
*.vpk
*.sfo
*.bin
*.elf
*.velf
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##

67
Makefile Normal file
View File

@ -0,0 +1,67 @@
TITLE := "Grand Theft Auto: Vice City"
TITLE_ID := GTAVCECTY
TARGET := GTAVC
SOURCES := src src/collision src/buildings src/animation src/audio src/audio/oal src/audio/eax src/control src/core src/entities src/math src/modelinfo src/objects src/peds src/renderer src/rw src/save src/skel src/skel/glfw src/text src/vehicles src/weapons src/extras src/fakerw
INCLUDES := src src/collision src/buildings src/animation src/audio src/audio/oal src/audio/eax src/control src/core src/entities src/math src/modelinfo src/objects src/peds src/renderer src/rw src/save src/skel src/skel/glfw src/text src/vehicles src/weapons src/extras src/fakerw librw
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
CPPFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.cpp))
BINFILES := $(foreach dir,$(DATA), $(wildcard $(dir)/*.bin))
OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
INCLUDE := $(foreach dir,$(INCLUDES),-I$(dir))
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
ARCH := -mtune=cortex-a9 -march=armv7-a -mfpu=neon
CFLAGS := -g -Wl,-q,--no-enum-size-warning -fsigned-char -fno-short-enums -fno-optimize-sibling-calls -O3 -mfloat-abi=hard $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -DPSP2 -DMASTER -DLIBRW -DRW_GL3 -DAUDIO_OAL -DLIBRW_GLAD -fno-builtin-memcpy -DNDEBUG
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fpermissive
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lrw -lopenal -lvitaGL -lSceAppMgr_stub -lSceDisplay_stub -lSceCommonDialog_stub -lSceLibKernel_stub \
-lSceSysmodule_stub -lvitashark -lSceShaccCg_stub -lvitaGL -lmathneon -lSceGxm_stub -lScePower_stub \
-lSceCtrl_stub -lSceHid_stub -lSceAudio_stub -lSceTouch_stub -lm -lpthread -lmpg123 -lSceAudioIn_stub \
-lSDL2 -lvita2d -lSceMotion_stub -lSceAvPlayer_stub -lSceSysmodule_stub -lSceKernelDmacMgr_stub
all: $(TARGET).vpk
%.vpk: eboot.bin
vita-mksfoex -s TITLE_ID=$(TITLE_ID) -d ATTRIBUTE2=12 $(TITLE) param.sfo
vita-pack-vpk -s param.sfo -b eboot.bin \
--add sce_sys/icon0.png=sce_sys/icon0.png \
--add sce_sys/livearea/contents/bg.png=sce_sys/livearea/contents/bg.png \
--add sce_sys/livearea/contents/startup.png=sce_sys/livearea/contents/startup.png \
--add sce_sys/livearea/contents/template.xml=sce_sys/livearea/contents/template.xml \
--add sce_sys/manual/001.png=sce_sys/manual/001.png \
--add sce_sys/manual/002.png=sce_sys/manual/002.png \
--add sce_sys/manual/003.png=sce_sys/manual/003.png \
--add sce_sys/manual/004.png=sce_sys/manual/004.png \
--add sce_sys/manual/005.png=sce_sys/manual/005.png \
--add sce_sys/manual/006.png=sce_sys/manual/006.png \
--add sce_sys/manual/007.png=sce_sys/manual/007.png \
--add sce_sys/manual/008.png=sce_sys/manual/008.png \
--add sce_sys/manual/009.png=sce_sys/manual/009.png \
--add sce_sys/manual/010.png=sce_sys/manual/010.png \
--add sce_sys/manual/011.png=sce_sys/manual/011.png \
--add sce_sys/manual/012.png=sce_sys/manual/012.png \
--add sce_sys/manual/013.png=sce_sys/manual/013.png \
--add sce_sys/manual/014.png=sce_sys/manual/014.png \
--add sce_sys/manual/015.png=sce_sys/manual/015.png \
--add sce_sys/manual/016.png=sce_sys/manual/016.png \
--add sce_sys/manual/017.png=sce_sys/manual/017.png \
$(TARGET).vpk
eboot.bin: $(TARGET).velf
vita-make-fself -c -s $< $@
%.velf: %.elf
vita-elf-create $< $@
$(TARGET).elf: $(OBJS)
$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
clean:
@rm -rf $(TARGET).vpk $(TARGET).velf $(TARGET).elf $(OBJS) eboot.bin param.sfo

BIN
sce_sys/icon0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 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>

BIN
sce_sys/manual/001.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
sce_sys/manual/002.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
sce_sys/manual/003.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
sce_sys/manual/004.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
sce_sys/manual/005.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
sce_sys/manual/006.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
sce_sys/manual/007.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
sce_sys/manual/008.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
sce_sys/manual/009.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
sce_sys/manual/010.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
sce_sys/manual/011.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
sce_sys/manual/012.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
sce_sys/manual/013.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

BIN
sce_sys/manual/014.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
sce_sys/manual/015.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
sce_sys/manual/016.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

BIN
sce_sys/manual/017.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -51,6 +51,7 @@ using namespace re3_openal;
void EFXInit()
{
#ifndef PSP2
/* Define a macro to help load the function pointers. */
#define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x))
LOAD_PROC(LPALGENEFFECTS, alGenEffects);
@ -89,6 +90,7 @@ void EFXInit()
LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf);
LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv);
#undef LOAD_PROC
#endif
}
void SetEffectsLevel(ALuint uiFilter, float level)

View File

@ -530,8 +530,11 @@ public:
m_pMH = mpg123_new(nil, nil);
if ( m_pMH )
{
#ifdef PSP2
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
#else
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
#endif
m_bOpened = true;
m_bFileNotOpenedYet = true;
// It's possible to move this to audioFileOpsThread(), but effect isn't noticable + probably not compatible with our current cutscene audio handling

View File

@ -122,7 +122,11 @@ enum
#define MAX_STREAMS 3
#ifdef PSP2
#define DIGITALRATE 44100
#else
#define DIGITALRATE 32000
#endif
#define DIGITALBITS 16
#define DIGITALCHANNELS 2

View File

@ -264,8 +264,11 @@ U32 RadioHandlers[9];
U32 WINAPI vfs_open_callback(char const* Filename, U32* FileHandle)
{
#ifdef PSP2
*FileHandle = (U32)fcaseopen(Filename, "rb");
#else
*FileHandle = (U32)fopen(Filename, "rb");
#endif
// couldn't they just use stricmp once? and strlen? this is very inefficient
if ((strcmp(Filename + strlen(Filename) - 4, ".adf") == 0) || (strcmp(Filename + strlen(Filename) - 4, ".ADF") == 0)) {
for (int i = 0; i < ARRAY_SIZE(RadioHandlers); i++) {
@ -988,7 +991,11 @@ cSampleManager::Initialise(void)
#ifdef AUDIO_CACHE
TRACE("cache");
#ifdef PSP2
FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb");
#else
FILE *cacheFile = fopen("audio\\sound.cache", "rb");
#endif
bool8 CreateCache = FALSE;
if (cacheFile) {
fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
@ -1027,9 +1034,11 @@ cSampleManager::Initialise(void)
{
strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[0]);
#ifdef PSP2
FILE *f = fcaseopen(filepath, "rb");
#else
FILE *f = fopen(filepath, "rb");
#endif
if ( f )
{
fclose(f);
@ -1223,7 +1232,11 @@ cSampleManager::Initialise(void)
#ifdef AUDIO_CACHE
if (CreateCache) {
#ifdef PSP2
cacheFile = fcaseopen("audio\\sound.cache", "wb");
#else
cacheFile = fopen("audio\\sound.cache", "wb");
#endif
fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
fclose(cacheFile);
}
@ -1413,9 +1426,11 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
strcpy(filepath, m_MiscomPath);
strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]);
#ifdef PSP2
FILE *f = fcaseopen(filepath, "rb");
#else
FILE *f = fopen(filepath, "rb");
#endif
if ( f )
{
fclose(f);
@ -2397,12 +2412,18 @@ bool8
cSampleManager::InitialiseSampleBanks(void)
{
int32 nBank = SFX_BANK_0;
#ifdef PSP2
fpSampleDescHandle = fcaseopen(SampleBankDescFilename, "rb");
#else
fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
#endif
if ( fpSampleDescHandle == NULL )
return FALSE;
#ifdef PSP2
fpSampleDataHandle = fcaseopen(SampleBankDataFilename, "rb");
#else
fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
#endif
if ( fpSampleDataHandle == NULL )
{
fclose(fpSampleDescHandle);

View File

@ -255,7 +255,7 @@ set_new_provider(int index)
usingEAX = 0;
usingEAX3 = 0;
_usingEFX = false;
#ifndef PSP2
if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3")
&& alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
@ -283,7 +283,7 @@ set_new_provider(int index)
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]);
}
#endif
//SampleManager.SetSpeakerConfig(speaker_type);
if ( IsFXSupported() )
@ -482,18 +482,20 @@ _FindMP3s(void)
int total_ms;
WIN32_FIND_DATA fd;
char filepath[MAX_PATH + sizeof(fd.cFileName)];
#ifndef PSP2
if (getcwd(_mp3DirectoryPath, MAX_PATH) == NULL) {
perror("getcwd: ");
return;
}
#endif
if (strlen(_mp3DirectoryPath) + 1 > MAX_PATH - 10) {
// This is not gonna end well
printf("MP3 folder path is too long, no place left for file names. MP3 finding aborted.\n");
return;
}
OutputDebugString("Finding MP3s...");
strcpy(path, _mp3DirectoryPath);
strcat(path, "\\MP3\\");
@ -535,6 +537,7 @@ _FindMP3s(void)
{
if (filepathlen > 0)
{
#ifndef PSP2
if (_ResolveLink(filepath, filepath))
{
OutputDebugString("Resolving Link");
@ -542,6 +545,7 @@ _FindMP3s(void)
bShortcut = TRUE;
}
else
#endif
{
bShortcut = FALSE;
if (filepathlen > MAX_PATH) {
@ -594,6 +598,7 @@ _FindMP3s(void)
{
if ( filepathlen > 0 )
{
#ifndef PSP2
if ( _ResolveLink(filepath, filepath) )
{
OutputDebugString("Resolving Link");
@ -601,6 +606,7 @@ _FindMP3s(void)
bShortcut = TRUE;
}
else
#endif
bShortcut = FALSE;
if (aStream[0] && aStream[0]->Open(filepath))
@ -864,14 +870,14 @@ cSampleManager::Initialise(void)
alListenerfv(AL_ORIENTATION, orientation);
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
#ifndef PSP2
if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
_effectsSupported = providers[index].bSupportsFx;
alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
alGenEffects(1, &ALEffect);
}
#endif
alGenSources(MAX_STREAMS*2, ALStreamSources[0]);
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{

View File

@ -1,5 +1,7 @@
#include "common.h"
#ifdef PSP2
#include "crossplatform.h"
#endif
#include "Script.h"
#include "ScriptCommands.h"
@ -2308,7 +2310,11 @@ void CTheScripts::Init()
CFileMgr::SetDirMyDocuments();
if (dbg_log)
fclose(dbg_log);
#ifdef PSP2
dbg_log = fcaseopen("SCRDBG.LOG", "w");
#else
dbg_log = fopen("SCRDBG.LOG", "w");
#endif
static const char* init_msg = "Starting debug script log\n\n";
PrintToLog(init_msg);
CFileMgr::SetDir("");
@ -2420,7 +2426,11 @@ void CTheScripts::Process()
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#if SCRIPT_LOG_FILE_LEVEL == 1
CFileMgr::SetDirMyDocuments();
#ifdef PSP2
dbg_log = fcaseopen("SCRDBG.LOG", "w");
#else
dbg_log = fopen("SCRDBG.LOG", "w");
#endif
static const char* init_msg = "Starting debug script log\n\n";
PrintToLog(init_msg);
CFileMgr::SetDir("");

View File

@ -7,7 +7,9 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#ifndef PSP2
#include <sys/statvfs.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -26,6 +28,11 @@
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#ifdef PSP2
#define USE_UNNAMED_SEM
#define SEM_FAILED ((sem_t *) 0)
#endif
#ifdef FLUSHABLE_STREAMING
bool flushStream[MAX_CDCHANNELS];
#endif
@ -198,6 +205,7 @@ CdStreamInitThread(void)
void
CdStreamInit(int32 numChannels)
{
#ifndef PSP2
struct statvfs fsInfo;
if((statvfs("models/gta3.img", &fsInfo)) < 0)
@ -206,6 +214,7 @@ CdStreamInit(int32 numChannels)
ASSERT(0);
return;
}
#endif
#ifdef __linux__
_gdwCdStreamFlags = O_RDONLY | O_NOATIME;
#else
@ -219,7 +228,11 @@ CdStreamInit(int32 numChannels)
debug("Using no buffered loading for streaming\n");
}
*/
#ifndef PSP2
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, (RwUInt32)fsInfo.f_bsize);
#else
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
#endif
ASSERT( pBuffer != nil );
gNumImages = 0;

View File

@ -2409,6 +2409,7 @@ wchar *CControllerConfigManager::GetControllerSettingTextMouse(e_ControllerActio
wchar *CControllerConfigManager::GetControllerSettingTextJoystick(e_ControllerAction action)
{
#ifndef PSP2
if (m_aSettings[action][JOYSTICK].m_Key == 0)
return NULL;
@ -2419,6 +2420,66 @@ wchar *CControllerConfigManager::GetControllerSettingTextJoystick(e_ControllerAc
NewStringWithNumber);
return NewStringWithNumber;
#else
const char *button;
switch (m_aSettings[action][JOYSTICK].m_Key)
{
case 1:
button = "CIRCLE";
break;
case 2:
button = "CROSS";
break;
case 3:
button = "SQUARE";
break;
case 4:
button = "TRIANGLE";
break;
case 5:
button = "L2";
break;
case 6:
button = "R2";
break;
case 7:
button = "L1";
break;
case 8:
button = "R1";
break;
case 9:
button = "SELECT";
break;
case 10:
button = "L3";
break;
case 11:
button = "R3";
break;
case 12:
button = "START";
break;
case 13:
button = "UP";
break;
case 14:
button = "RIGHT";
break;
case 15:
button = "DOWN";
break;
case 16:
button = "LEFT";
break;
default: return NULL;
}
static wchar text[30];
AsciiToUnicode(button, text);
return text;
#endif
}
int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction action)

View File

@ -502,7 +502,11 @@ CMenuManager::CMenuManager()
DisplayComboButtonErrMsg = false;
m_PrefsDMA = 1;
OS_Language = LANG_ENGLISH;
#ifdef PSP2
m_ControlMethod = CONTROL_CLASSIC;
#else
m_ControlMethod = CONTROL_STANDARD;
#endif
#ifdef PC_PLAYER_CONTROLS
CCamera::m_bUseMouse3rdPerson = true;
#else
@ -1343,7 +1347,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
break;
#endif
}
#ifdef PSP2
wchar tmp[256];
if (!strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "PSP2", 4)) {
UnicodeStrcpy(tmp, leftText);
UnicodeStrcat(tmp, rightText);
rightText = nil;
leftText = tmp;
}
#endif
// Highlight trapezoid
if (activeScreen && i == m_nCurrOption && itemsAreSelectable && section == 0) {

View File

@ -244,6 +244,13 @@ CGame::InitialiseRenderWare(void)
CreateDebugFont();
#ifdef LIBRW
#ifdef PSP2
#ifdef PS2_MATFX
rw::MatFX::modulateEnvMap = true;
#else
rw::MatFX::modulateEnvMap = false;
#endif
#else
#ifdef PS2_MATFX
rw::MatFX::envMapApplyLight = true;
rw::MatFX::envMapUseMatColor = true;
@ -255,6 +262,7 @@ CGame::InitialiseRenderWare(void)
#endif
rw::RGBA envcol = { 64, 64, 64, 255 };
rw::MatFX::envMapColor = envcol;
#endif
#else
#ifdef PS2_MATFX
ReplaceMatFxCallback();

View File

@ -28,6 +28,10 @@
#include "ControllerConfig.h"
#include "DMAudio.h"
#ifdef PSP2
extern bool useRearpad;
#endif
// Menu screens array is at the bottom of the file.
#ifdef PC_MENU
@ -596,6 +600,9 @@ CMenuScreenCustom aScreens[] = {
#endif
#ifdef DETECT_JOYSTICK_MENU
MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER,
#endif
#ifdef PSP2
MENUACTION_CFO_SELECT, "PSP2", { new CCFOSelect((int8*)&useRearpad, "Controller", "Rearpad", off_on, 2, false) }, 0, 0, MENUALIGN_CENTER,
#endif
MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER,

View File

@ -1,5 +1,11 @@
#pragma once
#ifdef PSP2
extern "C"{
#include <math_neon.h>
};
#endif
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#pragma warning(disable: 4244) // int to float
@ -391,4 +397,3 @@ __inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function
#define STR(x) STRINGIFY(x)
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)

View File

@ -297,16 +297,20 @@ enum Config {
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define PS2_ALPHA_TEST // emulate ps2 alpha test
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
#ifndef PSP2
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
#endif
#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
#define ANISOTROPIC_FILTERING // set all textures to max anisotropic filtering
//#define USE_TEXTURE_POOL
#ifdef LIBRW
#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
#ifndef PSP2
#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
#define SCREEN_DROPLETS // neo water droplets
#define NEW_RENDERER // leeds-like world rendering, needs librw
#endif
#endif
#define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc)
@ -359,9 +363,11 @@ enum Config {
# ifdef CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable
#ifndef PSP2
# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
# define CUTSCENE_BORDERS_SWITCH
# define MULTISAMPLING // adds MSAA option
#endif
# define CUTSCENE_BORDERS_SWITCH
# define INVERT_LOOK_FOR_PAD // enable the hidden option
# endif
#endif
@ -422,7 +428,9 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
#ifndef PSP2
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later
#endif
#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
#ifdef AUDIO_OPUS

View File

@ -355,6 +355,11 @@ RwGrabScreen(RwCamera *camera, RwChar *filename)
#define TILE_WIDTH 576
#define TILE_HEIGHT 432
#ifdef PSP2
extern GLuint fxfb;
bool using_fbo = false;
#endif
void
DoRWStuffEndOfFrame(void)
{
@ -362,6 +367,16 @@ DoRWStuffEndOfFrame(void)
CDebug::DebugDisplayTextBuffer();
FlushObrsPrintfs();
RwCameraEndUpdate(Scene.camera);
#if defined(PSP2) && defined(EXTENDED_COLOURFILTER)
if(CPostFX::NeedBackBuffer()){
if (using_fbo) {
glBindFramebuffer(GL_FRAMEBUFFER, fxfb);
using_fbo = false;
} else glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
#endif
RsCameraShowRaster(Scene.camera);
#ifndef MASTER
char s[48];

View File

@ -661,9 +661,11 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
setLights(&lights);
setupDone = true;
}
#ifdef PSP2
setMaterial(m->color, m->surfaceProps);
#else
setMaterial(flags, m->color, m->surfaceProps);
#endif
setTexture(0, m->texture);
drawInst(building->instHeader, inst);

View File

@ -13,6 +13,11 @@
#include "MBlur.h"
#include "postfx.h"
#ifdef PSP2
GLuint fxraster = 0xDEADBEEF, fxfb;
extern bool using_fbo;
#endif
RwRaster *CPostFX::pFrontBuffer;
RwRaster *CPostFX::pBackBuffer;
bool CPostFX::bJustInitialised;
@ -153,22 +158,38 @@ CPostFX::Open(RwCamera *cam)
#endif
#ifdef RW_OPENGL
using namespace rw::gl3;
#ifdef PSP2
#include "shaders/im2d_v.h"
#endif
{
#ifdef PSP2
#include "shaders/colourfilterVC_f.h"
const char *vs[] = { (const char*)im2d_v, (const char*)&size_im2d_v, nil };
const char *fs[] = { (const char*)colourfilterVC_f, (const char*)&size_colourfilterVC_f, nil };
colourFilterVC = Shader::create(vs, fs, true);
#else
#include "shaders/obj/im2d_vert.inc"
#include "shaders/obj/colourfilterVC_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
colourFilterVC = Shader::create(vs, fs);
#endif
assert(colourFilterVC);
}
{
#ifdef PSP2
#include "shaders/contrast_f.h"
const char *vs[] = { (const char*)im2d_v, (const char*)&size_im2d_v, nil };
const char *fs[] = { (const char*)contrast_f, (const char*)&size_contrast_f, nil };
contrast = Shader::create(vs, fs, true);
#else
#include "shaders/obj/im2d_vert.inc"
#include "shaders/obj/contrast_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil };
contrast = Shader::create(vs, fs);
#endif
assert(contrast);
}
@ -305,6 +326,13 @@ CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
glUniform4fv(colourFilterVC->uniformLocations[u_blurcolor], 1, blurcolors);
#endif
}
#ifdef PSP2
glBindTexture(GL_TEXTURE_2D, fxraster);
RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, 255);
RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, 255);
RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, 255);
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
#endif
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
#ifdef RW_D3D9
rw::d3d::im2dOverridePS = nil;
@ -403,10 +431,10 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
blue = AvgBlue;
blur = AvgAlpha;
}
#ifndef PSP2
if(NeedBackBuffer())
GetBackBuffer(cam);
#endif
DefinedState();
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
@ -417,22 +445,38 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
if(type == MOTION_BLUR_SNIPER){
if(!bJustInitialised)
RenderOverlaySniper(cam, red, green, blue, blur);
}else switch(EffectSwitch){
case POSTFX_OFF:
case POSTFX_SIMPLE:
// no actual rendering here
break;
case POSTFX_NORMAL:
if(MotionBlurOn){
if(!bJustInitialised)
RenderOverlayBlur(cam, red, green, blue, blur);
}else{
RenderOverlayShader(cam, red, green, blue, blur);
}else {
#if defined(PSP2) && defined(EXTENDED_COLOURFILTER)
if (NeedBackBuffer()) {
if(fxraster == 0xDEADBEEF){
glGenTextures(1, &fxraster);
glBindTexture(GL_TEXTURE_2D, fxraster);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glGenFramebuffers(1, &fxfb);
glBindFramebuffer(GL_FRAMEBUFFER, fxfb);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fxraster, 0);
}
using_fbo = true;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
#endif
switch(EffectSwitch){
case POSTFX_OFF:
case POSTFX_SIMPLE:
// no actual rendering here
break;
case POSTFX_NORMAL:
if(MotionBlurOn){
if(!bJustInitialised)
RenderOverlayBlur(cam, red, green, blue, blur);
}else{
RenderOverlayShader(cam, red, green, blue, blur);
}
break;
case POSTFX_MOBILE:
RenderOverlayShader(cam, red, green, blue, blur);
break;
}
break;
case POSTFX_MOBILE:
RenderOverlayShader(cam, red, green, blue, blur);
break;
}
if(!bJustInitialised)

View File

@ -0,0 +1,41 @@
#define u_fogStart (u_fogData.x)
#define u_fogEnd (u_fogData.y)
#define u_fogRange (u_fogData.z)
#define u_fogDisable (u_fogData.w)
void DoAlphaTest(float a, half2 u_alphaRef)
{
if(a < u_alphaRef.x || a >= u_alphaRef.y)
discard;
}
float4 main(
half4 v_color : COLOR0,
half2 v_tex0 : TEXCOORD0,
fixed v_fog : FOG,
uniform half4 u_fogColor,
uniform half2 u_alphaRef,
uniform half4 u_blurcolor,
uniform sampler2D tex0
) {
half a = u_blurcolor.a;
half4 doublec = clamp(u_blurcolor*2.0, 0.0, 1.0);
half4 dst = v_color*tex2D(tex0, half2(v_tex0.x, 1.0-v_tex0.y));
dst.rgb = lerp(u_fogColor.rgb, dst.rgb, v_fog);
DoAlphaTest(dst.a, u_alphaRef);
half4 prev = dst;
for (int i = 0; i < 5; i++){
half4 tmp = dst*(1.0-a) + prev*doublec*a;
tmp += prev*u_blurcolor;
tmp += prev*u_blurcolor;
prev = clamp(tmp, 0.0, 1.0);
}
half4 color;
color.rgb = prev.rgb;
color.a = 1.0f;
return color;
}

View File

@ -0,0 +1,59 @@
#ifndef __colourfilterVC_f__
#define __colourfilterVC_f__
static unsigned int size_colourfilterVC_f = 808;
static unsigned char colourfilterVC_f[] __attribute__((aligned(16))) = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, 0x27, 0x03, 0x00, 0x00, 0xa1, 0xf7, 0x98, 0x5f,
0xc1, 0x2a, 0x69, 0x80, 0x0d, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x04, 0x00, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x00,
0xe0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x02, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0f, 0xa0, 0xc0, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x40, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xc0, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x41, 0xa2, 0x8e, 0x0b, 0x81, 0x40, 0xc2, 0x00, 0x49, 0xa0, 0x86, 0x43, 0xa0, 0x10,
0x4f, 0x50, 0x44, 0x90, 0x86, 0x13, 0xa5, 0x10, 0x40, 0x60, 0x44, 0x90, 0x86, 0x03, 0xa5, 0x10,
0x42, 0x00, 0x04, 0xa2, 0x86, 0x33, 0xa4, 0x10, 0x86, 0x90, 0xed, 0xa1, 0xa6, 0x03, 0xc0, 0x10,
0x40, 0x02, 0x04, 0x81, 0x0a, 0x05, 0x84, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0xfa, 0x46, 0x90, 0x44, 0xb0, 0x22, 0x01, 0x00, 0x10,
0x00, 0x42, 0x00, 0xe0, 0x0c, 0x84, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xf9,
0x00, 0x00, 0x04, 0x8f, 0x84, 0x4f, 0xa4, 0x10, 0x01, 0xbe, 0x03, 0x30, 0xb5, 0xc6, 0xc8, 0x48,
0x09, 0xbe, 0x03, 0x30, 0x35, 0xc9, 0x88, 0x4a, 0x00, 0xbc, 0x19, 0x20, 0x7c, 0x0d, 0x81, 0x40,
0x06, 0x03, 0x00, 0xf0, 0x06, 0x04, 0x30, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x01, 0x01, 0x00, 0xa0, 0x46, 0x0d, 0x81, 0x40,
0x00, 0x00, 0x40, 0xf0, 0xa6, 0x92, 0x80, 0x04, 0x01, 0x00, 0x40, 0x20, 0x86, 0x92, 0x80, 0x04,
0xc1, 0x01, 0x04, 0xe0, 0x84, 0x43, 0xa4, 0x10, 0x00, 0x12, 0x00, 0xc0, 0x86, 0x92, 0xa0, 0x04,
0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04, 0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04,
0x0f, 0x50, 0x04, 0x90, 0x86, 0x13, 0xa5, 0x10, 0x00, 0x60, 0x44, 0x90, 0x86, 0x03, 0xa5, 0x10,
0x00, 0x12, 0x00, 0xc0, 0x86, 0x92, 0xa0, 0x04, 0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04,
0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04, 0x0f, 0x50, 0x04, 0x90, 0x86, 0x13, 0xa5, 0x10,
0x00, 0x60, 0x44, 0x90, 0x86, 0x03, 0xa5, 0x10, 0x00, 0x12, 0x00, 0xc0, 0x86, 0x92, 0xa0, 0x04,
0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04, 0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04,
0x0f, 0x50, 0x04, 0x90, 0x86, 0x13, 0xa5, 0x10, 0x00, 0x60, 0x44, 0x90, 0x86, 0x03, 0xa5, 0x10,
0x00, 0x12, 0x00, 0xc0, 0x86, 0x92, 0xa0, 0x04, 0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04,
0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04, 0x0f, 0x50, 0x04, 0x90, 0x86, 0x13, 0xa5, 0x10,
0x00, 0x60, 0x44, 0x90, 0x86, 0x03, 0xa5, 0x10, 0x00, 0x12, 0x00, 0xc0, 0x86, 0x92, 0xa0, 0x04,
0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04, 0x80, 0x10, 0x00, 0xe0, 0x86, 0x92, 0xa0, 0x04,
0x0f, 0x50, 0x04, 0x90, 0x86, 0x13, 0xa5, 0x10, 0x00, 0x60, 0x04, 0x90, 0x86, 0x03, 0xa5, 0x10,
0x0f, 0x00, 0x04, 0x90, 0x86, 0x17, 0xc5, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40,
0x06, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00,
0x60, 0x00, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5b, 0x00, 0x00, 0x00, 0x11, 0xe2, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x56, 0x00, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x02, 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x5f, 0x66, 0x6f, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x75, 0x5f, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x52, 0x65, 0x66, 0x00, 0x75, 0x5f, 0x62, 0x6c, 0x75, 0x72, 0x63, 0x6f, 0x6c, 0x6f,
0x72, 0x00, 0x74, 0x65, 0x78, 0x30, 0x00, 0x00,
};
#endif

View File

@ -0,0 +1,33 @@
#define u_fogStart (u_fogData.x)
#define u_fogEnd (u_fogData.y)
#define u_fogRange (u_fogData.z)
#define u_fogDisable (u_fogData.w)
void DoAlphaTest(float a, half2 u_alphaRef)
{
if(a < u_alphaRef.x || a >= u_alphaRef.y)
discard;
}
float4 main(
half4 v_color : COLOR0,
half2 v_tex0 : TEXCOORD0,
fixed v_fog : FOG,
uniform half4 u_fogColor,
uniform half2 u_alphaRef,
uniform float3 u_contrastAdd,
uniform float3 u_contrastMult,
uniform sampler2D tex0
) {
half4 dst = v_color*tex2D(tex0, half2(v_tex0.x, 1.0-v_tex0.y));
dst.rgb = lerp(u_fogColor.rgb, dst.rgb, v_fog);
DoAlphaTest(dst.a, u_alphaRef);
half4 color;
color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;
color.a = 1.0f;
return color;
}

View File

@ -0,0 +1,47 @@
#ifndef __contrast_f__
#define __contrast_f__
static unsigned int size_contrast_f = 616;
static unsigned char contrast_f[] __attribute__((aligned(16))) = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, 0x68, 0x02, 0x00, 0x00, 0x3b, 0xd7, 0x5e, 0x63,
0x4f, 0x9c, 0x1e, 0xe8, 0x09, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x04, 0x00, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x02, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0f, 0xa0, 0xc0, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x40, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xc0, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x41, 0xa2, 0x8e, 0x0b, 0x81, 0x40, 0x40, 0x02, 0x04, 0x81, 0x0a, 0x05, 0x84, 0x38,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0xfa,
0x46, 0x90, 0x44, 0xb0, 0x22, 0x21, 0x00, 0x10, 0x80, 0x43, 0x00, 0xe0, 0x0c, 0x84, 0x01, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0xf9, 0x00, 0x00, 0x04, 0x8f, 0x84, 0x4f, 0xa4, 0x10,
0x01, 0xbe, 0x03, 0x30, 0xb5, 0xc6, 0xc8, 0x48, 0x09, 0xbe, 0x03, 0x30, 0x35, 0xc9, 0x88, 0x4a,
0x00, 0xbc, 0x19, 0x20, 0x7c, 0x0d, 0x81, 0x40, 0x0c, 0x06, 0x00, 0xf0, 0x06, 0x04, 0x30, 0xf9,
0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xf8, 0x40, 0x00, 0xf0, 0x81, 0x08, 0x0d, 0x80, 0x38,
0x00, 0xc0, 0x03, 0xf0, 0xa2, 0x9a, 0x80, 0x04, 0x00, 0xc0, 0x03, 0x2f, 0x80, 0x9b, 0x80, 0x04,
0x06, 0x82, 0xa1, 0xff, 0x9c, 0x0d, 0xc0, 0x40, 0x04, 0x11, 0x11, 0xcf, 0x80, 0x8b, 0xb1, 0x18,
0x01, 0x0f, 0x04, 0x1f, 0x84, 0x17, 0xc5, 0x08, 0x00, 0xbc, 0x19, 0x20, 0x7e, 0x0d, 0x81, 0x40,
0x01, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00,
0x70, 0x00, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6b, 0x00, 0x00, 0x00, 0x11, 0xe2, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x66, 0x00, 0x00, 0x00, 0x01, 0xe3, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00, 0x01, 0xe3, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x63, 0x00, 0x00, 0x00, 0x02, 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x5f, 0x66, 0x6f, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x75, 0x5f, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x52, 0x65, 0x66, 0x00, 0x75, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74,
0x41, 0x64, 0x64, 0x00, 0x75, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x4d, 0x75,
0x6c, 0x74, 0x00, 0x74, 0x65, 0x78, 0x30, 0x00,
};
#endif

View File

@ -0,0 +1,35 @@
#define u_fogStart (u_fogData.x)
#define u_fogEnd (u_fogData.y)
#define u_fogRange (u_fogData.z)
#define u_fogDisable (u_fogData.w)
#define MAX_LIGHTS 8
#define surfAmbient (u_surfProps.x)
#define surfSpecular (u_surfProps.y)
#define surfDiffuse (u_surfProps.z)
fixed DoFog(float w, half4 u_fogData)
{
return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);
}
void main(
float4 in_pos,
half4 in_color,
half2 in_tex0,
uniform half4 u_fogData,
uniform float4 u_xform,
half4 out v_color : COLOR0,
half2 out v_tex0 : TEXCOORD0,
fixed out v_fog : FOG,
float4 out gl_Position : POSITION
) {
gl_Position = in_pos;
gl_Position.w = 1.0;
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
v_fog = DoFog(gl_Position.z, u_fogData);
gl_Position.xyz *= gl_Position.w;
v_color = in_color;
v_tex0 = in_tex0;
}

View File

@ -0,0 +1,37 @@
#ifndef __im2d_v__
#define __im2d_v__
static unsigned int size_im2d_v = 452;
static unsigned char im2d_v[] __attribute__((aligned(16))) = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, 0xc2, 0x01, 0x00, 0x00, 0x7b, 0x45, 0xf3, 0x4d,
0x7a, 0x27, 0x43, 0x53, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
0xa0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x01, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x0c,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0xa1,
0x86, 0x0b, 0x81, 0x40, 0x03, 0x00, 0x00, 0xa1, 0x86, 0x0b, 0xc1, 0x40, 0x01, 0x00, 0x80, 0xaf,
0x84, 0x0b, 0x81, 0x40, 0x05, 0x80, 0x11, 0x80, 0xc2, 0x80, 0xe5, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x01, 0x01, 0x01, 0x34, 0x08, 0x00, 0x10, 0xfa,
0x80, 0x00, 0x08, 0x83, 0x21, 0x2d, 0x80, 0x38, 0x40, 0x11, 0x00, 0xff, 0x84, 0x08, 0x80, 0x00,
0x03, 0x5f, 0x04, 0x3f, 0x84, 0x00, 0xa4, 0x08, 0x3c, 0x61, 0x04, 0xc1, 0x85, 0x00, 0xa4, 0x08,
0x42, 0x00, 0x00, 0xf0, 0x86, 0x91, 0xa0, 0x00, 0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08,
0x41, 0x00, 0x54, 0x90, 0x89, 0x11, 0xc1, 0x08, 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0xe4, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x00, 0x69,
0x6e, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x69, 0x6e, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x00,
0x75, 0x5f, 0x66, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x00, 0x75, 0x5f, 0x78, 0x66, 0x6f, 0x72,
0x6d, 0x00, 0x00, 0x00,
};
#endif

View File

@ -300,13 +300,38 @@ RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture);
// TODO
void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { }
#ifdef PSP2
static rw::Raster*
ConvertTexRaster(rw::Raster *ras)
{
using namespace rw;
if(ras->platform == rw::platform)
return ras;
// compatible platforms
if(ras->platform == PLATFORM_D3D8 && rw::platform == PLATFORM_D3D9 ||
ras->platform == PLATFORM_D3D9 && rw::platform == PLATFORM_D3D8)
return ras;
Image *img = ras->toImage();
ras->destroy();
img->unpalettize();
ras = Raster::createFromImage(img);
img->destroy();
return ras;
}
#endif
// hack for reading native textures
RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size)
{
*tex = Texture::streamReadNative(stream);
#ifdef LIBRW
#ifdef PSP2
(*tex)->raster = ConvertTexRaster((*tex)->raster);
#else
(*tex)->raster = rw::Raster::convertTexToCurrentPlatform((*tex)->raster);
#endif
#endif
return *tex != nil;
}
@ -552,6 +577,7 @@ static void *reallocWrap(void *p, size_t sz, uint32 hint) { return real_realloc(
// WARNING: unused parameters
RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) {
#ifndef PSP2
if(memFuncs){
real_malloc = memFuncs->rwmalloc;
real_realloc = memFuncs->rwrealloc;
@ -562,6 +588,9 @@ RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 re
}else{
Engine::init(nil);
}
#else
Engine::init();
#endif
return true;
}
// TODO: this is platform dependent
@ -602,9 +631,18 @@ RwInt32 RwEngineGetMaxTextureSize(void);
void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) {}
RwBool RwD3D8DeviceSupportsDXTTexture(void) { return true; }
void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level) { Engine::setMultiSamplingLevels(level); }
RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void) { return Engine::getMaxMultiSamplingLevels(); }
void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level) {
#ifndef PSP2
Engine::setMultiSamplingLevels(level);
#endif
}
RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void) {
#ifndef PSP2
return Engine::getMaxMultiSamplingLevels();
#else
return 0;
#endif
}
RpMaterial *RpMaterialCreate(void) { return Material::create(); }
@ -1005,8 +1043,14 @@ RwBool RtCharsetDestroy(RtCharset * charSet) { charSet->destroy(); return
#include <rpanisot.h>
#ifdef PSP2
RwInt8 RpAnisotGetMaxSupportedMaxAnisotropy(void) { return 0; }
RwTexture *RpAnisotTextureSetMaxAnisotropy(RwTexture *tex, RwInt8 val) { return nullptr; }
RwInt8 RpAnisotTextureGetMaxAnisotropy(RwTexture *tex) { return 0; }
RwBool RpAnisotPluginAttach(void) { return false; }
#else
RwInt8 RpAnisotGetMaxSupportedMaxAnisotropy(void) { return rw::getMaxSupportedMaxAnisotropy(); }
RwTexture *RpAnisotTextureSetMaxAnisotropy(RwTexture *tex, RwInt8 val) { tex->setMaxAnisotropy(val); return tex; }
RwInt8 RpAnisotTextureGetMaxAnisotropy(RwTexture *tex) { return tex->getMaxAnisotropy(); }
RwBool RpAnisotPluginAttach(void) { rw::registerAnisotropyPlugin(); return true; }
#endif

View File

@ -176,44 +176,82 @@ CMatrix::SetTranslate(float x, float y, float z)
void
CMatrix::SetRotateXOnly(float angle)
{
#ifdef PSP2
float cs[2];
sincosf_c(angle, cs);
#else
float c = Cos(angle);
float s = Sin(angle);
#endif
rx = 1.0f;
ry = 0.0f;
rz = 0.0f;
fx = 0.0f;
#ifdef PSP2
fy = cs[1];
fz = cs[0];
ux = 0.0f;
uy = -cs[0];
uz = cs[1];
#else
fy = c;
fz = s;
ux = 0.0f;
uy = -s;
uz = c;
ux = c;
#endif
}
void
CMatrix::SetRotateYOnly(float angle)
{
#ifdef PSP2
float cs[2];
sincosf_c(angle, cs);
rx = cs[1];
ry = 0.0f;
rz = -cs[0];
#else
float c = Cos(angle);
float s = Sin(angle);
rx = c;
ry = 0.0f;
rz = -s;
#endif
fx = 0.0f;
fy = 1.0f;
fz = 0.0f;
#ifdef PSP2
ux = cs[0];
uy = 0.0f;
uz = cs[1];
#else
ux = s;
uy = 0.0f;
uz = c;
#endif
}
void
CMatrix::SetRotateZOnly(float angle)
{
#ifdef PSP2
float cs[2];
sincosf_c(angle, cs);
rx = cs[1];
ry = cs[0];
rz = 0.0f;
fx = -cs[0];
fy = cs[1];
fz = 0.0f;
#else
float c = Cos(angle);
float s = Sin(angle);
@ -224,7 +262,7 @@ CMatrix::SetRotateZOnly(float angle)
fx = -s;
fy = c;
fz = 0.0f;
#endif
ux = 0.0f;
uy = 0.0f;
uz = 1.0f;
@ -261,6 +299,26 @@ CMatrix::SetRotateZ(float angle)
void
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
{
#ifdef PSP2
float csX[2];
float csY[2];
float csZ[2];
sincosf_c(xAngle, csX);
sincosf_c(yAngle, csY);
sincosf_c(zAngle, csZ);
rx = csZ[1] * csY[1] - (csZ[0] * csX[0]) * csY[0];
ry = (csZ[1] * csX[0]) * csY[0] + csZ[0] * csY[1];
rz = -csX[1] * csY[0];
fx = -csZ[0] * csX[1];
fy = csZ[1] * csX[1];
fz = csX[0];
ux = (csZ[0] * csX[0]) * csY[1] + csZ[1] * csY[0];
uy = csZ[0] * csY[0] - (csZ[1] * csX[0]) * csY[1];
uz = csX[1] * csY[1];
#else
float cX = Cos(xAngle);
float sX = Sin(xAngle);
float cY = Cos(yAngle);
@ -279,6 +337,7 @@ CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
ux = (sZ * sX) * cY + cZ * sY;
uy = sZ * sY - (cZ * sX) * cY;
uz = cX * cY;
#endif
px = 0.0f;
py = 0.0f;
@ -288,9 +347,13 @@ CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
void
CMatrix::RotateX(float x)
{
#ifdef PSP2
float cs[2];
sincosf_c(x, cs);
#else
float c = Cos(x);
float s = Sin(x);
#endif
float ry = this->ry;
float rz = this->rz;
float uy = this->fy;
@ -299,7 +362,16 @@ CMatrix::RotateX(float x)
float az = this->uz;
float py = this->py;
float pz = this->pz;
#ifdef PSP2
this->ry = cs[1] * ry - cs[0] * rz;
this->rz = cs[1] * rz + cs[0] * ry;
this->fy = cs[1] * uy - cs[0] * uz;
this->fz = cs[1] * uz + cs[0] * uy;
this->uy = cs[1] * ay - cs[0] * az;
this->uz = cs[1] * az + cs[0] * ay;
this->py = cs[1] * py - cs[0] * pz;
this->pz = cs[1] * pz + cs[0] * py;
#else
this->ry = c * ry - s * rz;
this->rz = c * rz + s * ry;
this->fy = c * uy - s * uz;
@ -308,14 +380,19 @@ CMatrix::RotateX(float x)
this->uz = c * az + s * ay;
this->py = c * py - s * pz;
this->pz = c * pz + s * py;
#endif
}
void
CMatrix::RotateY(float y)
{
#ifdef PSP2
float cs[2];
sincosf_c(y, cs);
#else
float c = Cos(y);
float s = Sin(y);
#endif
float rx = this->rx;
float rz = this->rz;
float ux = this->fx;
@ -324,7 +401,16 @@ CMatrix::RotateY(float y)
float az = this->uz;
float px = this->px;
float pz = this->pz;
#ifdef PSP2
this->rx = cs[1] * rx + cs[0] * rz;
this->rz = cs[1] * rz - cs[0] * rx;
this->fx = cs[1] * ux + cs[0] * uz;
this->fz = cs[1] * uz - cs[0] * ux;
this->ux = cs[1] * ax + cs[0] * az;
this->uz = cs[1] * az - cs[0] * ax;
this->px = cs[1] * px + cs[0] * pz;
this->pz = cs[1] * pz - cs[0] * px;
#else
this->rx = c * rx + s * rz;
this->rz = c * rz - s * rx;
this->fx = c * ux + s * uz;
@ -333,14 +419,19 @@ CMatrix::RotateY(float y)
this->uz = c * az - s * ax;
this->px = c * px + s * pz;
this->pz = c * pz - s * px;
#endif
}
void
CMatrix::RotateZ(float z)
{
#ifdef PSP2
float cs[2];
sincosf_c(z, cs);
#else
float c = Cos(z);
float s = Sin(z);
#endif
float ry = this->ry;
float rx = this->rx;
float uy = this->fy;
@ -349,7 +440,16 @@ CMatrix::RotateZ(float z)
float ax = this->ux;
float py = this->py;
float px = this->px;
#ifdef PSP2
this->rx = cs[1] * rx - cs[0] * ry;
this->ry = cs[1] * ry + cs[0] * rx;
this->fx = cs[1] * ux - cs[0] * uy;
this->fy = cs[1] * uy + cs[0] * ux;
this->ux = cs[1] * ax - cs[0] * ay;
this->uy = cs[1] * ay + cs[0] * ax;
this->px = cs[1] * px - cs[0] * py;
this->py = cs[1] * py + cs[0] * px;
#else
this->rx = c * rx - s * ry;
this->ry = c * ry + s * rx;
this->fx = c * ux - s * uy;
@ -358,19 +458,27 @@ CMatrix::RotateZ(float z)
this->uy = c * ay + s * ax;
this->px = c * px - s * py;
this->py = c * py + s * px;
#endif
}
void
CMatrix::Rotate(float x, float y, float z)
{
#ifdef PSP2
float csX[2];
float csY[2];
float csZ[2];
sincosf_c(x, csX);
sincosf_c(y, csY);
sincosf_c(z, csZ);
#else
float cX = Cos(x);
float sX = Sin(x);
float cY = Cos(y);
float sY = Sin(y);
float cZ = Cos(z);
float sZ = Sin(z);
#endif
float rx = this->rx;
float ry = this->ry;
float rz = this->rz;
@ -383,7 +491,17 @@ CMatrix::Rotate(float x, float y, float z)
float px = this->px;
float py = this->py;
float pz = this->pz;
#ifdef PSP2
float x1 = csZ[1] * csY[1] - (csZ[0] * csX[0]) * csY[0];
float x2 = (csZ[1] * csX[0]) * csY[0] + csZ[0] * csY[1];
float x3 = -csX[1] * csY[0];
float y1 = -csZ[0] * csX[1];
float y2 = csZ[1] * csX[1];
float y3 = csX[0];
float z1 = (csZ[0] * csX[0]) * csY[1] + csZ[1] * csY[0];
float z2 = csZ[0] * csY[0] - (csZ[1] * csX[0]) * csY[1];
float z3 = csX[1] * csY[1];
#else
float x1 = cZ * cY - (sZ * sX) * sY;
float x2 = (cZ * sX) * sY + sZ * cY;
float x3 = -cX * sY;
@ -393,6 +511,7 @@ CMatrix::Rotate(float x, float y, float z)
float z1 = (sZ * sX) * cY + cZ * sY;
float z2 = sZ * sY - (cZ * sX) * cY;
float z3 = cX * cY;
#endif
this->rx = x1 * rx + y1 * ry + z1 * rz;
this->ry = x2 * rx + y2 * ry + z2 * rz;

View File

@ -1,5 +1,9 @@
#pragma once
#ifdef PSP2
extern "C"{
#include <math_neon.h>
};
#endif
class CMatrix
{
public:

View File

@ -3,6 +3,9 @@
void
CVector::Normalise(void)
{
#ifdef PSP2
normalize3_neon(&this->x, &this->x);
#else
float sq = MagnitudeSqr();
if (sq > 0.0f) {
float invsqrt = RecipSqrt(sq);
@ -11,6 +14,7 @@ CVector::Normalise(void)
z *= invsqrt;
} else
x = 1.0f;
#endif
}
CVector

View File

@ -593,6 +593,7 @@ CMBlur::AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type)
void
CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf)
{
#ifndef PSP2
bool drawWaterDrops = false;
RwIm2DVertex verts[4];
int red = (0.75f*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.55f * 255;
@ -798,4 +799,5 @@ CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf)
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
pBufVertCount = 0;
#endif
}

View File

@ -185,6 +185,7 @@ GetGPUcaps(GPUcaps *caps)
caps->subplatform = 0;
caps->dxtSupport = 0;
// TODO: more later
#ifndef PSP2
#ifdef RW_GL3
caps->subplatform = rw::gl3::gl3Caps.gles;
caps->dxtSupport = rw::gl3::gl3Caps.dxtSupported;
@ -192,6 +193,7 @@ GetGPUcaps(GPUcaps *caps)
#ifdef RW_D3D9
caps->dxtSupport = 1; // TODO, probably
#endif
#endif
}
void
@ -391,7 +393,7 @@ CreateTxdImageForVideoCard()
return false;
}
#ifdef RW_GL3
#if defined(RW_GL3) && !defined(PSP2)
// so we can read back DXT with GLES
// only works for textures that are not yet loaded
// so let's hope that is the case for all
@ -434,7 +436,7 @@ CreateTxdImageForVideoCard()
delete []buf;
delete pDir;
CStreaming::RemoveTxd(i);
#ifdef RW_GL3
#if defined(RW_GL3) && !defined(PSP2)
rw::gl3::needToReadBackTextures = false;
#endif
return false;
@ -469,7 +471,7 @@ CreateTxdImageForVideoCard()
RwStreamClose(img, nil);
delete []buf;
#ifdef RW_GL3
#if defined(RW_GL3) && !defined(PSP2)
rw::gl3::needToReadBackTextures = false;
#endif

View File

@ -1,6 +1,328 @@
#include "common.h"
#include "crossplatform.h"
#ifdef PSP2
/*int printf(const char *format, ...)
{
va_list list;
char string[512];
va_start(list, format);
vsnprintf(string, sizeof(string), format, list);
va_end(list);
SceUID fd = sceIoOpen("ux0:data/gtavc.txt", SCE_O_WRONLY | SCE_O_CREAT | SCE_O_APPEND, 0777);
if (fd >= 0) {
sceIoWrite(fd, string, strlen(string));
sceIoClose(fd);
}
return 0;
}*/
extern SceTouchPanelInfo panelInfo[2];
bool useRearpad = false;
void *memcpy(void *dest, const void *src, size_t n)
{
return sceClibMemcpy(dest, src, n);
}
static unsigned char gButtons[GLFW_GAMEPAD_BUTTON_LAST+1];
static float gAxes[GLFW_GAMEPAD_AXIS_LAST+1];
unsigned char* glfwGetJoystickButtons(int jid, int* count)
{
int port_id = useRearpad ? 1 : 0;
SceCtrlData pad;
SceTouchData touch;
sceCtrlPeekBufferPositiveExt2(0, &pad, 1);
sceTouchPeek(port_id, &touch, 1);
gButtons[GLFW_GAMEPAD_BUTTON_CROSS] = pad.buttons & SCE_CTRL_CROSS ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_CIRCLE] = pad.buttons & SCE_CTRL_CIRCLE ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_SQUARE] = pad.buttons & SCE_CTRL_SQUARE ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_TRIANGLE] = pad.buttons & SCE_CTRL_TRIANGLE ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_LEFT_BUMPER] = pad.buttons & SCE_CTRL_L1 ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER] = pad.buttons & SCE_CTRL_R1 ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_BACK] = pad.buttons & SCE_CTRL_SELECT ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_START] = pad.buttons & SCE_CTRL_START ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_GUIDE] = GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = pad.buttons & SCE_CTRL_L3 ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] = pad.buttons & SCE_CTRL_R3 ? GLFW_PRESS : GLFW_RELEASE;
for (int i = 0; i < touch.reportNum; i++) {
if (touch.report[i].y >= (panelInfo[port_id].minAaY + panelInfo[port_id].maxAaY) / 2) {
if (touch.report[i].x < (panelInfo[port_id].minAaX + panelInfo[port_id].maxAaX) / 2)
gButtons[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = GLFW_PRESS;
else
gButtons[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] = GLFW_PRESS;
}
}
gButtons[GLFW_GAMEPAD_BUTTON_DPAD_UP] = pad.buttons & SCE_CTRL_UP ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT] = pad.buttons & SCE_CTRL_RIGHT ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_DPAD_DOWN] = pad.buttons & SCE_CTRL_DOWN ? GLFW_PRESS : GLFW_RELEASE;
gButtons[GLFW_GAMEPAD_BUTTON_DPAD_LEFT] = pad.buttons & SCE_CTRL_LEFT ? GLFW_PRESS : GLFW_RELEASE;
if (count)
*count = GLFW_GAMEPAD_BUTTON_LAST+1;
return gButtons;
}
float* glfwGetJoystickAxes(int jid, int* count)
{
int port_id = useRearpad ? 1 : 0;
SceCtrlData pad;
SceTouchData touch;
sceCtrlPeekBufferPositiveExt2(0, &pad, 1);
sceTouchPeek(port_id, &touch, 1);
gAxes[GLFW_GAMEPAD_AXIS_LEFT_X] = ((float)pad.lx - 128.0f) / 128.0f;
gAxes[GLFW_GAMEPAD_AXIS_LEFT_Y] = ((float)pad.ly - 128.0f) / 128.0f;
gAxes[GLFW_GAMEPAD_AXIS_RIGHT_X] = ((float)pad.rx - 128.0f) / 128.0f;
gAxes[GLFW_GAMEPAD_AXIS_RIGHT_Y] = ((float)pad.ry - 128.0f) / 128.0f;
gAxes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER] = pad.buttons & SCE_CTRL_L2 ? 1.0f : -1.0f;
gAxes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER] = pad.buttons & SCE_CTRL_R2 ? 1.0f : -1.0f;
for (int i = 0; i < touch.reportNum; i++) {
if (touch.report[i].y < (panelInfo[port_id].minAaY + panelInfo[port_id].maxAaY) / 2) {
if (touch.report[i].x < (panelInfo[port_id].minAaX + panelInfo[port_id].maxAaX) / 2)
gAxes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER] = 1.0f;
else
gAxes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER] = 1.0f;
}
}
if (count)
*count = GLFW_GAMEPAD_AXIS_LAST+1;
return gAxes;
}
int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
{
unsigned char *buttons = glfwGetJoystickButtons(jid, NULL);
float *axes = glfwGetJoystickAxes(jid, NULL);
sceClibMemcpy(state->buttons, buttons, sizeof(state->buttons));
sceClibMemcpy(state->axes, axes, sizeof(state->axes));
return 1;
}
int glfwJoystickPresent(int jid)
{
return jid == 0;
}
int glfwJoystickIsGamepad(int jid)
{
return jid == 0;
}
int glfwGetKey(GLFWwindow* window, int key)
{
return GLFW_RELEASE;
}
int glfwGetMouseButton(GLFWwindow* window, int button)
{
return GLFW_RELEASE;
}
void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos)
{
if (xpos)
*xpos = 0.0f;
if (ypos)
*ypos = 0.0f;
return;
}
void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos)
{
return;
}
const char* glfwGetJoystickName(int jid)
{
return "Vita Pad";
}
int glfwWindowShouldClose(GLFWwindow* window)
{
return 0;
}
GLFWmonitor* glfwGetPrimaryMonitor(void)
{
return NULL;
}
static GLFWvidmode gVideoMode { .width = 960, .height = 544 };
const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor)
{
return &gVideoMode;
}
int clock_gettime(int clk_id, struct timespec *tp)
{
if (clk_id == CLOCK_MONOTONIC)
{
SceKernelSysClock ticks;
sceKernelGetProcessTime(&ticks);
tp->tv_sec = ticks / (1000 * 1000);
tp->tv_nsec = (ticks * 1000) % (1000 * 1000 * 1000);
return 0;
}
else if (clk_id == CLOCK_REALTIME)
{
time_t seconds;
SceDateTime time;
sceRtcGetCurrentClockLocalTime(&time);
sceRtcGetTime_t(&time, &seconds);
tp->tv_sec = seconds;
tp->tv_nsec = time.microsecond * 1000;
return 0;
}
return -ENOSYS;
}
int lstat(const char *path, struct stat *buf)
{
debug("lstat %s\n", path);
return stat(path, buf);
}
char *realpath(const char *path, char *resolved_path)
{
char data_path[PATH_MAX];
getcwd(data_path, sizeof(data_path));
if (strncmp(path, "ux0:", 4) == 0)
{
strcpy(resolved_path, path);
}
else
{
sprintf(resolved_path, "%s/%s", data_path, path);
}
debug("realpath %s -> %s\n", path, resolved_path);
return resolved_path;
}
ssize_t readlink(const char *path, char *buf, size_t bufsiz)
{
debug("readlink %s\n", path);
return 0;
}
char cur_dir[PATH_MAX] = "ux0:data/gtavc";
char *getcwd(char *buf, size_t size)
{
if (buf != NULL)
{
strncpy(buf, cur_dir, size);
}
return cur_dir;
}
int chdir(const char *path)
{
if (strncmp(path, "ux0:", 4) == 0)
{
strcpy(cur_dir, path);
}
else
{
sprintf(cur_dir, "%s/%s", cur_dir, path);
}
debug("chdir %s -> %s\n", path, cur_dir);
return 0;
}
int mkdir(const char *pathname, mode_t mode)
{
char* real = casepath(pathname);
int result = sceIoMkdir(real, mode) < 0 ? -1 : 0;
free(real);
return result;
}
int unlink(const char *pathname)
{
char* real = casepath(pathname);
int result = remove(real);
free(real);
return result;
}
HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char pathCopy[MAX_PATH];
snprintf(pathCopy, sizeof(pathCopy), "ux0:data/gtavc/%s", pathname);
char *folder = strtok(pathCopy, "*");
char *extension = strtok(NULL, "*");
// because strtok doesn't return NULL for last delimiter
if (extension - folder == strlen(pathname))
extension = nil;
// Case-sensitivity and backslashes...
// Will be freed at the bottom
char *realFolder = casepath(folder);
if (realFolder) {
folder = realFolder;
}
strncpy(firstfile->folder, folder, sizeof(firstfile->folder));
if (extension)
strncpy(firstfile->extension, extension, sizeof(firstfile->extension));
else
firstfile->extension[0] = '\0';
if (realFolder)
free(realFolder);
HANDLE d;
if ((d = (HANDLE)opendir(firstfile->folder)) == NULL || !FindNextFile(d, firstfile))
return NULL;
return d;
}
bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) {
dirent *file;
static struct stat fileStats;
static char path[PATH_MAX], relativepath[NAME_MAX + sizeof(finddata->folder) + 1];
int extensionLen = strlen(finddata->extension);
while ((file = readdir((DIR*)d)) != NULL) {
// We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type.
if (extensionLen == 0 || strncasecmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0) {
sprintf(relativepath, "%s/%s", finddata->folder, file->d_name);
realpath(relativepath, path);
stat(path, &fileStats);
strncpy(finddata->cFileName, file->d_name, sizeof(finddata->cFileName));
finddata->ftLastWriteTime = fileStats.st_mtime;
return true;
}
}
return false;
}
char* casepath(char const* path, bool checkPathFirst)
{
char* out = (char*)malloc(PATH_MAX);
realpath(path, out);
size_t l = strlen(out);
for (int i = l-1; i >= 0; i--) {
if (out[i] == '\\' || out[i] == '/' || out[i] == ' ')
out[i] = '\0';
else
break;
}
return out;
}
#endif
// Codes compatible with Windows and Linux
#ifndef _WIN32
@ -24,7 +346,7 @@ void GetLocalTime_CP(SYSTEMTIME *out) {
#endif
// Compatible with Linux/POSIX and MinGW on Windows
#ifndef _WIN32
#if !defined(_WIN32) && !defined(PSP2)
HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char pathCopy[MAX_PATH];
strcpy(pathCopy, pathname);
@ -81,7 +403,9 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) {
}
return false;
}
#endif
#ifndef _WIN32
void GetDateFormat(int unused1, int unused2, SYSTEMTIME* in, int unused3, char* out, int size) {
tm linuxTime;
linuxTime.tm_year = in->wYear - 1900;
@ -178,6 +502,7 @@ int _caserename(const char *old_filename, const char *new_filename)
return result;
}
#ifndef PSP2
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
// Returned string should freed manually (if exists)
char* casepath(char const* path, bool checkPathFirst)
@ -279,7 +604,7 @@ char* casepath(char const* path, bool checkPathFirst)
return out;
}
#endif
#endif
#if !defined(_MSC_VER) && !defined(__CWCC__)
char *strdate(char *buf) {
time_t timestamp;

View File

@ -1,6 +1,115 @@
#include <time.h>
#include <limits.h>
#ifdef PSP2
#define GLFW_RELEASE 0
#define GLFW_PRESS 1
#define GLFW_KEY_R 82
#define GLFW_MOUSE_BUTTON_1 0
#define GLFW_MOUSE_BUTTON_2 1
#define GLFW_MOUSE_BUTTON_3 2
#define GLFW_MOUSE_BUTTON_4 3
#define GLFW_MOUSE_BUTTON_5 4
#define GLFW_MOUSE_BUTTON_6 5
#define GLFW_MOUSE_BUTTON_7 6
#define GLFW_MOUSE_BUTTON_8 7
#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
#define GLFW_JOYSTICK_1 0
#define GLFW_JOYSTICK_2 1
#define GLFW_JOYSTICK_3 2
#define GLFW_JOYSTICK_4 3
#define GLFW_JOYSTICK_5 4
#define GLFW_JOYSTICK_6 5
#define GLFW_JOYSTICK_7 6
#define GLFW_JOYSTICK_8 7
#define GLFW_JOYSTICK_9 8
#define GLFW_JOYSTICK_10 9
#define GLFW_JOYSTICK_11 10
#define GLFW_JOYSTICK_12 11
#define GLFW_JOYSTICK_13 12
#define GLFW_JOYSTICK_14 13
#define GLFW_JOYSTICK_15 14
#define GLFW_JOYSTICK_16 15
#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
#define GLFW_GAMEPAD_BUTTON_A 0
#define GLFW_GAMEPAD_BUTTON_B 1
#define GLFW_GAMEPAD_BUTTON_X 2
#define GLFW_GAMEPAD_BUTTON_Y 3
#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
#define GLFW_GAMEPAD_BUTTON_BACK 6
#define GLFW_GAMEPAD_BUTTON_START 7
#define GLFW_GAMEPAD_BUTTON_GUIDE 8
#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
#define GLFW_GAMEPAD_AXIS_LEFT_X 0
#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
typedef struct GLFWgamepadstate
{
unsigned char buttons[15];
float axes[6];
} GLFWgamepadstate;
typedef struct GLFWvidmode
{
int width;
int height;
} GLFWvidmode;
typedef void GLFWmonitor;
typedef void GLFWwindow;
GLFWmonitor* glfwGetPrimaryMonitor(void);
int glfwWindowShouldClose(GLFWwindow* window);
const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
int glfwGetKey(GLFWwindow* window, int key);
int glfwGetMouseButton(GLFWwindow* window, int button);
void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
int glfwJoystickPresent(int jid);
float* glfwGetJoystickAxes(int jid, int* count);
unsigned char* glfwGetJoystickButtons(int jid, int* count);
int glfwJoystickIsGamepad(int jid);
const char* glfwGetJoystickName(int jid);
int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
#define CLOCK_MONOTONIC 0
int clock_gettime(int clk_id, struct timespec *tp);
#define PATH_MAX 1024
#define NAME_MAX 255
int lstat(const char *path, struct stat *buf);
char *realpath(const char *path, char *resolved_path);
#endif
// This is the common include for platform/renderer specific skeletons(glfw.cpp, win.cpp etc.) and using cross platform things (like Windows directories wrapper, platform specific global arrays etc.)
// Functions that's different on glfw and win but have same signature, should be located on platform.h.

View File

@ -13,15 +13,17 @@ DWORD _dwOperatingSystemVersion;
#else
long _dwOperatingSystemVersion;
#ifndef __APPLE__
#ifndef PSP2
#include <sys/sysinfo.h>
#endif
#else
#include <mach/mach_host.h>
#include <sys/sysctl.h>
#endif
#include <errno.h>
#include <stddef.h>
#include <locale.h>
#include <signal.h>
#include <stddef.h>
#include <errno.h>
#endif
#include "common.h"
@ -51,7 +53,7 @@ long _dwOperatingSystemVersion;
#include "MemoryMgr.h"
// We found out that GLFW's keyboard input handling is still pretty delayed/not stable, so now we fetch input from X11 directly on Linux.
#if !defined _WIN32 && !defined __APPLE__ && !defined __SWITCH__ // && !defined WAYLAND
#if !defined _WIN32 && !defined __APPLE__ && !defined __SWITCH__ && !defined PSP2 // && !defined WAYLAND
#define GET_KEYBOARD_INPUT_FROM_X11
#endif
@ -62,6 +64,15 @@ long _dwOperatingSystemVersion;
#include <GLFW/glfw3native.h>
#endif
#ifdef PSP2
#include <malloc.h>
#include <vitasdk.h>
#include <vitaGL.h>
#include "shaders/movie_f.h"
#include "shaders/movie_v.h"
int _newlib_heap_size_user = 256 * 1024 * 1024;
#endif
#ifdef _WIN32
#define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h>
@ -480,7 +491,7 @@ psInitialize(void)
_dwMemAvailPhys = (uint64_t)(vm_stat.free_count * page_size);
debug("Physical memory size %llu\n", _dwMemAvailPhys);
debug("Available physical memory %llu\n", size);
#else
#elif !defined(PSP2)
#ifndef __APPLE__
struct sysinfo systemInfo;
sysinfo(&systemInfo);
@ -865,6 +876,7 @@ psSelectDevice()
return TRUE;
}
#ifndef PSP2
#ifndef GET_KEYBOARD_INPUT_FROM_X11
void keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods);
#endif
@ -875,7 +887,7 @@ void cursorEnterCB(GLFWwindow* window, int entered);
void windowFocusCB(GLFWwindow* window, int focused);
void windowIconifyCB(GLFWwindow* window, int iconified);
void joysChangeCB(int jid, int event);
#endif
bool IsThisJoystickBlacklisted(int i)
{
#ifndef DETECT_JOYSTICK_MENU
@ -898,7 +910,7 @@ void _InputInitialiseJoys()
{
PSGLOBAL(joy1id) = -1;
PSGLOBAL(joy2id) = -1;
#ifndef PSP2
// Load our gamepad mappings.
#define SDL_GAMEPAD_DB_PATH "gamecontrollerdb.txt"
FILE *f = fopen(SDL_GAMEPAD_DB_PATH, "rb");
@ -928,7 +940,7 @@ void _InputInitialiseJoys()
if (EnvControlConfig != nil) {
glfwUpdateGamepadMappings(EnvControlConfig);
}
#endif
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if (glfwJoystickPresent(i) && !IsThisJoystickBlacklisted(i)) {
if (PSGLOBAL(joy1id) == -1)
@ -950,12 +962,16 @@ void _InputInitialiseJoys()
}
}
#ifndef PSP2
int lastCursorMode = GLFW_CURSOR_HIDDEN;
#endif
long _InputInitialiseMouse(bool exclusive)
{
#ifndef PSP2
// Disabled = keep cursor centered and hide
lastCursorMode = exclusive ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_HIDDEN;
glfwSetInputMode(PSGLOBAL(window), GLFW_CURSOR, lastCursorMode);
#endif
return 0;
}
@ -974,14 +990,18 @@ bool _InputMouseNeedsExclusive()
// If windowed, free the cursor on menu(where this func. is called and DISABLED-HIDDEN transition is done accordingly)
// If it's fullscreen, be sure that it didn't stuck on HIDDEN.
#ifdef PSP2
return !(vm.flags & rwVIDEOMODEEXCLUSIVE);
#else
return !(vm.flags & rwVIDEOMODEEXCLUSIVE) || lastCursorMode == GLFW_CURSOR_HIDDEN;
#endif
}
void psPostRWinit(void)
{
RwVideoMode vm;
RwEngineGetVideoModeInfo(&vm, GcurSelVM);
#if !defined(PSP2)
#ifndef GET_KEYBOARD_INPUT_FROM_X11
glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
#endif
@ -992,13 +1012,13 @@ void psPostRWinit(void)
glfwSetWindowIconifyCallback(PSGLOBAL(window), windowIconifyCB);
glfwSetWindowFocusCallback(PSGLOBAL(window), windowFocusCB);
glfwSetJoystickCallback(joysChangeCB);
#endif
_InputInitialiseJoys();
_InputInitialiseMouse(false);
#ifndef PSP2
if(!(vm.flags & rwVIDEOMODEEXCLUSIVE))
glfwSetWindowSize(PSGLOBAL(window), RsGlobal.maximumWidth, RsGlobal.maximumHeight);
#endif
// Make sure all keys are released
CPad::GetPad(0)->Clear(true);
CPad::GetPad(1)->Clear(true);
@ -1296,7 +1316,7 @@ void HandleExit()
#endif
}
#ifndef _WIN32
#if defined(_WIN32) && !defined(PSP2)
void terminateHandler(int sig, siginfo_t *info, void *ucontext) {
RsGlobal.quit = TRUE;
}
@ -1307,7 +1327,7 @@ void dummyHandler(int sig){
}
#endif
#endif
#ifndef PSP2
void resizeCB(GLFWwindow* window, int width, int height) {
/*
* Handle event to ensure window contents are displayed during re-size
@ -1752,14 +1772,17 @@ void checkKeyPresses()
}
#endif
#endif
// R* calls that in ControllerConfig, idk why
void
_InputTranslateShiftKeyUpDown(RsKeyCodes *rs) {
#ifndef PSP2
RsKeyboardEventHandler(lshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsLSHIFT));
RsKeyboardEventHandler(rshiftStatus ? rsKEYDOWN : rsKEYUP, &(*rs = rsRSHIFT));
#endif
}
#ifndef PSP2
// TODO this only works in frontend(and luckily only frontend use this). Fun fact: if I get pos manually in game, glfw reports that it's > 32000
void
cursorCB(GLFWwindow* window, double xpos, double ypos) {
@ -1776,6 +1799,7 @@ void
cursorEnterCB(GLFWwindow* window, int entered) {
PSGLOBAL(cursorIsInWindow) = !!entered;
}
#endif
void
windowFocusCB(GLFWwindow* window, int focused) {
@ -1813,9 +1837,234 @@ WinMain(HINSTANCE instance,
#endif
#else
#ifdef PSP2
#define FB_ALIGNMENT 0x40000
#define ALIGN_MEM(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
SceAvPlayerHandle movie_player;
GLuint movie_frame[2];
uint8_t movie_frame_idx = 0;
SceGxmTexture *movie_tex[2];
GLuint movie_fs;
GLuint movie_vs;
GLuint movie_prog;
SceUID audio_thid;
int audio_new;
int audio_port;
int audio_len;
int audio_freq;
int audio_mode;
enum {
PLAYER_INACTIVE,
PLAYER_ACTIVE,
PLAYER_STOP,
};
int player_state = PLAYER_INACTIVE;
float movie_pos[8] = {
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, 1.0f,
1.0f, -1.0f
};
float movie_texcoord[8] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
void *mem_alloc(void *p, uint32_t align, uint32_t size) {
return memalign(align, size);
}
void mem_free(void *p, void *ptr) {
free(ptr);
}
void *gpu_alloc(void *p, uint32_t align, uint32_t size) {
if (align < FB_ALIGNMENT) {
align = FB_ALIGNMENT;
}
size = ALIGN_MEM(size, align);
return vglAlloc(size, VGL_MEM_SLOW);
}
void gpu_free(void *p, void *ptr) {
glFinish();
vglFree(ptr);
}
void movie_player_audio_init(void) {
audio_port = -1;
for (int i = 0; i < 8; i++) {
if (sceAudioOutGetConfig(i, SCE_AUDIO_OUT_CONFIG_TYPE_LEN) >= 0) {
audio_port = i;
break;
}
}
if (audio_port == -1) {
audio_port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, 1024, 48000, SCE_AUDIO_OUT_MODE_STEREO);
audio_new = 1;
} else {
audio_len = sceAudioOutGetConfig(audio_port, SCE_AUDIO_OUT_CONFIG_TYPE_LEN);
audio_freq = sceAudioOutGetConfig(audio_port, SCE_AUDIO_OUT_CONFIG_TYPE_FREQ);
audio_mode = sceAudioOutGetConfig(audio_port, SCE_AUDIO_OUT_CONFIG_TYPE_MODE);
audio_new = 0;
}
}
void movie_player_audio_shutdown(void) {
if (audio_new) {
sceAudioOutReleasePort(audio_port);
} else {
sceAudioOutSetConfig(audio_port, audio_len, audio_freq, (SceAudioOutMode)audio_mode);
}
}
int movie_player_audio_thread(SceSize args, void *argp) {
SceAvPlayerFrameInfo frame;
memset(&frame, 0, sizeof(SceAvPlayerFrameInfo));
while (player_state == PLAYER_ACTIVE && sceAvPlayerIsActive(movie_player)) {
if (sceAvPlayerGetAudioData(movie_player, &frame)) {
sceAudioOutSetConfig(audio_port, 1024, frame.details.audio.sampleRate, frame.details.audio.channelCount == 1 ? SCE_AUDIO_OUT_MODE_MONO : SCE_AUDIO_OUT_MODE_STEREO);
sceAudioOutOutput(audio_port, frame.pData);
} else {
sceKernelDelayThread(1000);
}
}
return sceKernelExitDeleteThread(0);
}
void movie_player_draw(void) {
if (player_state == PLAYER_ACTIVE) {
if (sceAvPlayerIsActive(movie_player)) {
SceAvPlayerFrameInfo frame;
if (sceAvPlayerGetVideoData(movie_player, &frame)) {
movie_frame_idx = (movie_frame_idx + 1) % 2;
sceGxmTextureInitLinear(
movie_tex[movie_frame_idx],
frame.pData,
SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC1,
frame.details.video.width,
frame.details.video.height, 0);
sceGxmTextureSetMinFilter(movie_tex[movie_frame_idx], SCE_GXM_TEXTURE_FILTER_LINEAR);
sceGxmTextureSetMagFilter(movie_tex[movie_frame_idx], SCE_GXM_TEXTURE_FILTER_LINEAR);
glUseProgram(movie_prog);
glBindTexture(GL_TEXTURE_2D, movie_frame[movie_frame_idx]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, &movie_pos[0]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, &movie_texcoord[0]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
vglSwapBuffers(GL_FALSE);
}
} else {
player_state = PLAYER_STOP;
}
}
if (player_state == PLAYER_STOP) {
sceAvPlayerStop(movie_player);
sceKernelWaitThreadEnd(audio_thid, NULL, NULL);
sceAvPlayerClose(movie_player);
movie_player_audio_shutdown();
player_state = PLAYER_INACTIVE;
glClear(GL_COLOR_BUFFER_BIT);
vglSwapBuffers(GL_FALSE);
}
}
int movie_player_inited = 0;
void movie_player_init() {
if (movie_player_inited)
return;
sceSysmoduleLoadModule(SCE_SYSMODULE_AVPLAYER);
glGenTextures(2, movie_frame);
for (int i = 0; i < 2; i++) {
glBindTexture(GL_TEXTURE_2D, movie_frame[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 960, 544, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
movie_tex[i] = vglGetGxmTexture(GL_TEXTURE_2D);
vglFree(vglGetTexDataPointer(GL_TEXTURE_2D));
}
movie_vs = glCreateShader(GL_VERTEX_SHADER);
glShaderBinary(1, &movie_vs, 0, movie_v, size_movie_v);
movie_fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderBinary(1, &movie_fs, 0, movie_f, size_movie_f);
movie_prog = glCreateProgram();
glAttachShader(movie_prog, movie_vs);
glAttachShader(movie_prog, movie_fs);
glBindAttribLocation(movie_prog, 0, "inPos");
glBindAttribLocation(movie_prog, 1, "inTex");
glLinkProgram(movie_prog);
movie_player_inited = 1;
}
void movie_player_play(const char *file) {
SceIoStat st;
if (sceIoGetstat(file, &st) < 0)
return;
movie_player_init();
movie_player_audio_init();
SceAvPlayerInitData playerInit;
sceClibMemset(&playerInit, 0, sizeof(SceAvPlayerInitData));
playerInit.memoryReplacement.allocate = mem_alloc;
playerInit.memoryReplacement.deallocate = mem_free;
playerInit.memoryReplacement.allocateTexture = gpu_alloc;
playerInit.memoryReplacement.deallocateTexture = gpu_free;
playerInit.basePriority = 0xA0;
playerInit.numOutputVideoFrameBuffers = 2;
playerInit.autoStart = GL_TRUE;
movie_player = sceAvPlayerInit(&playerInit);
sceAvPlayerAddSource(movie_player, file);
audio_thid = sceKernelCreateThread("movie_audio_thread", movie_player_audio_thread, 0x10000100 - 10, 0x4000, 0, 0, NULL);
sceKernelStartThread(audio_thid, 0, NULL);
player_state = PLAYER_ACTIVE;
}
#endif
#ifdef PSP2
SceTouchPanelInfo panelInfo[2];
#endif
int
main(int argc, char *argv[])
{
#ifdef PSP2
sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE);
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START);
scePowerSetArmClockFrequency(444);
scePowerSetBusClockFrequency(222);
scePowerSetGpuClockFrequency(222);
scePowerSetGpuXbarClockFrequency(166);
sceTouchGetPanelInfo(SCE_TOUCH_PORT_FRONT, &panelInfo[0]);
sceTouchGetPanelInfo(SCE_TOUCH_PORT_BACK, &panelInfo[1]);
#endif
#endif
RwV2d pos;
RwInt32 i;
@ -1824,7 +2073,7 @@ main(int argc, char *argv[])
InitMemoryMgr();
#endif
#ifndef _WIN32
#if defined(_WIN32) && !defined(PSP2)
struct sigaction act;
act.sa_sigaction = terminateHandler;
act.sa_flags = SA_SIGINFO;
@ -1877,8 +2126,9 @@ main(int argc, char *argv[])
openParams.width = RsGlobal.maximumWidth;
openParams.height = RsGlobal.maximumHeight;
openParams.windowtitle = RsGlobal.appName;
#ifndef PSP2
openParams.window = &PSGLOBAL(window);
#endif
ControlsManager.MakeControllerActionsBlank();
ControlsManager.InitDefaultControlConfiguration();
@ -1994,9 +2244,9 @@ main(int argc, char *argv[])
FrontEndMenuManager.DrawMemoryCardStartUpMenus();
}
#endif
#ifndef PSP2
initkeymap();
#endif
while ( TRUE )
{
RwInitialised = TRUE;
@ -2038,7 +2288,9 @@ main(int argc, char *argv[])
while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart && !glfwWindowShouldClose(PSGLOBAL(window)))
#endif
{
#ifndef PSP2
glfwPollEvents();
#endif
#ifdef GET_KEYBOARD_INPUT_FROM_X11
checkKeyPresses();
#endif
@ -2054,7 +2306,7 @@ main(int argc, char *argv[])
{
case GS_START_UP:
{
#ifdef NO_MOVIES
#if defined(NO_MOVIES) && !defined(PSP2)
gGameState = GS_INIT_ONCE;
#else
gGameState = GS_INIT_LOGO_MPEG;
@ -2067,6 +2319,9 @@ main(int argc, char *argv[])
{
//if (!startupDeactivate)
// PlayMovieInWindow(cmdShow, "movies\\Logo.mpg");
#ifdef PSP2
movie_player_play("ux0:data/gtavc/movies/Logo.mp4");
#endif
gGameState = GS_LOGO_MPEG;
TRACE("gGameState = GS_LOGO_MPEG;");
break;
@ -2077,7 +2332,19 @@ main(int argc, char *argv[])
// CPad::UpdatePads();
// if (startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0)
#ifdef PSP2
movie_player_draw();
if (!(player_state == PLAYER_ACTIVE && sceAvPlayerIsActive(movie_player)))
gGameState++;
CPad::UpdatePads();
if (ControlsManager.GetJoyButtonJustDown() != 0)
player_state = PLAYER_STOP;
#else
++gGameState;
#endif
// else if (CPad::GetPad(0)->GetLeftMouseJustDown())
// ++gGameState;
// else if (CPad::GetPad(0)->GetEnterJustDown())
@ -2103,7 +2370,9 @@ main(int argc, char *argv[])
// PlayMovieInWindow(cmdShow, "movies\\GTAtitlesGER.mpg");
// else
// PlayMovieInWindow(cmdShow, "movies\\GTAtitles.mpg");
#ifdef PSP2
movie_player_play("ux0:data/gtavc/movies/GTAtitles.mp4");
#endif
gGameState = GS_INTRO_MPEG;
TRACE("gGameState = GS_INTRO_MPEG;");
break;
@ -2114,7 +2383,19 @@ main(int argc, char *argv[])
// CPad::UpdatePads();
//
// if (startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0)
#ifdef PSP2
movie_player_draw();
if (!(player_state == PLAYER_ACTIVE && sceAvPlayerIsActive(movie_player)))
gGameState++;
CPad::UpdatePads();
if (ControlsManager.GetJoyButtonJustDown() != 0)
player_state = PLAYER_STOP;
#else
++gGameState;
#endif
// else if (CPad::GetPad(0)->GetLeftMouseJustDown())
// ++gGameState;
// else if (CPad::GetPad(0)->GetEnterJustDown())
@ -2180,6 +2461,9 @@ main(int argc, char *argv[])
case GS_FRONTEND:
{
#ifndef PSP2
if(!glfwGetWindowAttrib(PSGLOBAL(window), GLFW_ICONIFIED))
#endif
if(!WindowIconified)
RsEventHandler(rsFRONTENDIDLE, nil);
@ -2489,7 +2773,7 @@ void CapturePad(RwInt32 padID)
return;
}
#ifndef PSP2
void joysChangeCB(int jid, int event)
{
if (event == GLFW_CONNECTED && !IsThisJoystickBlacklisted(jid)) {
@ -2514,7 +2798,7 @@ void joysChangeCB(int jid, int event)
PSGLOBAL(joy2id) = -1;
}
}
#endif
#if (defined(_MSC_VER))
int strcasecmp(const char* str1, const char* str2)
{

View File

@ -0,0 +1,33 @@
#ifndef __movie_f__
#define __movie_f__
/*
float4 main(
float2 texcoord : TEXCOORD0,
uniform sampler2D tex
) {
return tex2D(tex, texcoord);
}
*/
static unsigned int size_movie_f = 256;
static unsigned char movie_f[] __attribute__((aligned(16))) = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, 0x00, 0x01, 0x00, 0x00, 0x2f, 0x18, 0xe0, 0x2b,
0xc0, 0xa3, 0x06, 0x39, 0x01, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x30, 0x00, 0x00, 0x00,
0x02, 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
};
#endif

View File

@ -0,0 +1,38 @@
#ifndef __movie_v__
#define __movie_v__
/*
void main(
float2 inPos,
float2 inTex,
float4 out pos : POSITION,
float2 out texcoord : TEXCOORD0
) {
texcoord = inTex;
pos = float4(inPos, 1.f, 1.f);
}
*/
static unsigned int size_movie_v = 276;
static unsigned char movie_v[] __attribute__((aligned(16))) = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, 0x14, 0x01, 0x00, 0x00, 0x0a, 0xf8, 0x9c, 0x1c,
0xb3, 0x51, 0x01, 0x8f, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, 0x80, 0x00, 0x08, 0x83, 0x21, 0x05, 0x80, 0x38,
0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08, 0x01, 0x80, 0x56, 0x90, 0x81, 0x11, 0x83, 0x08,
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x50, 0x6f, 0x73, 0x00, 0x69, 0x6e,
0x54, 0x65, 0x78, 0x00,
};
#endif

View File

@ -105,9 +105,20 @@ CText::Unload(void)
memset(szMissionTableName, 0, sizeof(szMissionTableName));
}
#ifdef PSP2
wchar *rearpad_str = nullptr;
#endif
wchar*
CText::Get(const char *key)
{
#ifdef PSP2
if (!strncmp(key, "PSP2", 4)) {
if (!rearpad_str)
rearpad_str = AllocUnicode("Use Rearpad: ");
return rearpad_str;
}
#endif
uint8 result = false;
#if defined (FIX_BUGS) || defined(FIX_BUGS_64)
wchar *outstr = keyArray.Search(key, data.chars, &result);