mirror of
https://github.com/libretro/ppsspp.git
synced 2025-01-26 03:04:20 +00:00
Move the SDL C++ wrapper code into the native project as well.
This commit is contained in:
parent
1e398d4269
commit
fc886b23e6
8
android/README.md
Normal file
8
android/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Here's an Android library project. Add this to your eclipse workspace
|
||||
and add a dependency to it, then just inherit from NativeActivity,
|
||||
write your C++ code, and Bob's your uncle.
|
||||
|
||||
|
||||
Contact: hrydgard@gmail.com
|
||||
|
||||
|
@ -13,13 +13,13 @@
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/display.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "input/input_state.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "android/NativeApp.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#define coord_xres 800
|
||||
#define coord_yres 480
|
||||
@ -100,9 +100,7 @@ extern "C" void Java_com_turboviking_libnative_NativeApp_init
|
||||
ILOG("External storage path: %s", str);
|
||||
|
||||
str = env->GetStringUTFChars(dataDir, &isCopy);
|
||||
user_data_path = std::string(str) + "/";
|
||||
settings_file = user_data_path + "settings.json";
|
||||
ILOG("Settings file: %s", settings_file.c_str());
|
||||
std::string user_data_path = std::string(str) + "/";
|
||||
|
||||
str = env->GetStringUTFChars(jinstallID, &isCopy);
|
||||
std::string installID = std::string(str);
|
||||
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello" />
|
||||
|
||||
</LinearLayout>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World!</string>
|
||||
<string name="app_name">libnative</string>
|
||||
|
||||
</resources>
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// The Native App API.
|
||||
//
|
||||
// Implement these functions and you've got a native app. These are called
|
||||
@ -9,12 +11,15 @@
|
||||
// This is defined in input/input_state.h.
|
||||
struct InputState;
|
||||
|
||||
// The very first function to be called. Even NativeMix is not called
|
||||
// before this, although it may be called at any point in time afterwards.
|
||||
// Must not call OpenGL. Main thread.
|
||||
// You must implement this. The first function to get called, just write strings to the two pointers.
|
||||
void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name);
|
||||
|
||||
// The very first function to be called after NativeGetAppInfo. Even NativeMix is not called
|
||||
// before this, although it may be called at any point in time afterwards (on any thread!)
|
||||
// This functions must NOT call OpenGL. Main thread.
|
||||
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *installID);
|
||||
|
||||
// Runs after NativeInit() at some point. Can call OpenGL.
|
||||
// Runs after NativeInit() at some point. May (and probably should) call OpenGL.
|
||||
void NativeInitGraphics();
|
||||
|
||||
// Signals that you need to recreate all buffered OpenGL resources,
|
||||
@ -44,3 +49,13 @@ void NativeMix(short *audio, int num_samples);
|
||||
// Main thread.
|
||||
void NativeShutdownGraphics();
|
||||
void NativeShutdown();
|
||||
|
||||
// Calls back into Java / SDL
|
||||
// These APIs must be implemented by every port (for example app-android.cpp, PCMain.cpp).
|
||||
// You are free to call these.
|
||||
void SystemToast(const char *text);
|
||||
void ShowAd(int x, int y, bool center_x);
|
||||
void Vibrate(int length_ms);
|
||||
void LaunchBrowser(const char *url);
|
||||
void LaunchMarket(const char *url);
|
||||
void LaunchEmail(const char *email_address);
|
270
base/PCMain.cpp
Normal file
270
base/PCMain.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
// Bare bones SDL main.
|
||||
|
||||
// Marble Madness
|
||||
// Marble Mania
|
||||
// Marbeliciuos
|
||||
// Ballsy
|
||||
// Rollerball
|
||||
// Crash
|
||||
// Cowball (with cowbell noises at the menu!)
|
||||
// Rollfish
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <ShellAPI.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_timer.h"
|
||||
#include "SDL/SDL_audio.h"
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "input/input_state.h"
|
||||
#include "base/NativeApp.h"
|
||||
|
||||
|
||||
// Simple implementations of System functions
|
||||
|
||||
void SystemToast(const char *text) {
|
||||
MessageBox(0, text, "Toast!", MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
|
||||
void ShowAd(int x, int y, bool center_x) {
|
||||
// Ignore ads on PC
|
||||
}
|
||||
|
||||
void Vibrate(int length_ms) {
|
||||
// Ignore on PC
|
||||
}
|
||||
|
||||
void LaunchBrowser(const char *url)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void LaunchMarket(const char *url)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void LaunchEmail(const char *email_address)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ShellExecute(NULL, "open", (std::string("mailto:") + email_address).c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int buttonMappings[12] = {
|
||||
SDLK_x, //A
|
||||
SDLK_s, //B
|
||||
SDLK_z, //X
|
||||
SDLK_a, //Y
|
||||
SDLK_w, //LBUMPER
|
||||
SDLK_q, //RBUMPER
|
||||
SDLK_1, //START
|
||||
SDLK_2, //BACK
|
||||
SDLK_UP, //UP
|
||||
SDLK_DOWN, //DOWN
|
||||
SDLK_LEFT, //LEFT
|
||||
SDLK_RIGHT, //RIGHT
|
||||
};
|
||||
|
||||
void SimulateGamepad(const uint8 *keys, InputState *input) {
|
||||
input->pad_buttons = 0;
|
||||
input->pad_lstick_x = 0;
|
||||
input->pad_lstick_y = 0;
|
||||
input->pad_rstick_x = 0;
|
||||
input->pad_rstick_y = 0;
|
||||
for (int b = 0; b < 12; b++) {
|
||||
if (keys[buttonMappings[b]])
|
||||
input->pad_buttons |= (1<<b);
|
||||
}
|
||||
|
||||
if (keys['I']) input->pad_lstick_y=32000;
|
||||
else if (keys['K']) input->pad_lstick_y=-32000;
|
||||
if (keys['J']) input->pad_lstick_x=-32000;
|
||||
else if (keys['L']) input->pad_lstick_x=32000;
|
||||
if (keys['8']) input->pad_rstick_y=32000;
|
||||
else if (keys['2']) input->pad_rstick_y=-32000;
|
||||
if (keys['4']) input->pad_rstick_x=-32000;
|
||||
else if (keys['6']) input->pad_rstick_x=32000;
|
||||
}
|
||||
|
||||
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / 4);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef main
|
||||
#endif
|
||||
int main(int argc, char *argv[]) {
|
||||
/* // Xoom resolution. Other common tablet resolutions: 1024x600 , 1366x768
|
||||
g_xres = 1280;
|
||||
g_yres = 800;
|
||||
*/
|
||||
g_xres = 800;
|
||||
g_yres = 480;
|
||||
|
||||
std::string app_name;
|
||||
std::string app_name_nice;
|
||||
NativeGetAppInfo(&app_name, &app_name_nice);
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
|
||||
|
||||
if (SDL_SetVideoMode(g_xres, g_yres, 0, SDL_OPENGL) == NULL) {
|
||||
fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return(2);
|
||||
}
|
||||
SDL_WM_SetCaption(app_name_nice.c_str(), NULL);
|
||||
|
||||
if (GLEW_OK != glewInit()) {
|
||||
printf("Failed to initialize glew!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GLEW_VERSION_2_0) {
|
||||
printf("OpenGL 2.0 or higher.\n");
|
||||
} else {
|
||||
printf("Sorry, this program requires OpenGL 2.0.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
|
||||
TCHAR path[MAX_PATH];
|
||||
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
|
||||
PathAppend(path, (app_name + "\\").c_str());
|
||||
#else
|
||||
// Mac - what about linux? Also, ugly hardcoding.
|
||||
const char *path = getenv("HOME");
|
||||
if (!homeDir) {
|
||||
struct passwd* pwd = getpwuid(getuid());
|
||||
if (pwd)
|
||||
path = pwd->pw_dir;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NativeInit(argc, (const char **)argv, path, "BADCOFFEE");
|
||||
NativeInitGraphics();
|
||||
|
||||
SDL_AudioSpec fmt;
|
||||
fmt.freq = 44100;
|
||||
fmt.format = AUDIO_S16;
|
||||
fmt.channels = 2;
|
||||
fmt.samples = 512;
|
||||
fmt.callback = &mixaudio;
|
||||
fmt.userdata = (void *)0;
|
||||
|
||||
if (SDL_OpenAudio(&fmt, NULL) < 0) {
|
||||
ELOG("Failed to open audio: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Audio must be unpaused _after_ NativeInit()
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
InputState input_state = {0};
|
||||
int framecount = 0;
|
||||
|
||||
while (true) {
|
||||
SDL_Event event;
|
||||
|
||||
input_state.accelerometer_valid = false;
|
||||
input_state.mouse_valid = true;
|
||||
int done = 0;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
done = 1;
|
||||
} else if (event.type == SDL_KEYDOWN) {
|
||||
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||
done = 1;
|
||||
}
|
||||
} else if (event.type == SDL_MOUSEMOTION) {
|
||||
input_state.mouse_x = event.motion.x;
|
||||
input_state.mouse_y = event.motion.y;
|
||||
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
input_state.mouse_buttons_down = 1;
|
||||
input_state.mouse_buttons = 1;
|
||||
}
|
||||
} else if (event.type == SDL_MOUSEBUTTONUP) {
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
input_state.mouse_buttons = 0;
|
||||
input_state.mouse_buttons_up = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (done) break;
|
||||
|
||||
input_state.mouse_last_buttons = input_state.mouse_buttons;
|
||||
uint8 *keys = (uint8 *)SDL_GetKeyState(NULL);
|
||||
if (keys[SDLK_ESCAPE]) {
|
||||
break;
|
||||
}
|
||||
SimulateGamepad(keys, &input_state);
|
||||
UpdateInputState(&input_state);
|
||||
NativeUpdate(input_state);
|
||||
NativeRender();
|
||||
if (framecount % 60 == 0) {
|
||||
// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
|
||||
}
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
// Simple framerate limiting
|
||||
static float t=0;
|
||||
while (time_now() < t+1.0f/60.0f) {
|
||||
sleep_ms(0);
|
||||
time_update();
|
||||
}
|
||||
time_update();
|
||||
t = time_now();
|
||||
framecount++;
|
||||
}
|
||||
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
|
||||
exit(0);
|
||||
|
||||
NativeShutdownGraphics();
|
||||
SDL_PauseAudio(1);
|
||||
NativeShutdown();
|
||||
SDL_CloseAudio();
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
4
base/display.cpp
Normal file
4
base/display.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "base/display.h"
|
||||
|
||||
int g_xres;
|
||||
int g_yres;
|
7
base/display.h
Normal file
7
base/display.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// This is meant to be a framework for handling DPI scaling etc.
|
||||
// For now, it just consists of these two ugly globals.
|
||||
|
||||
extern int g_xres;
|
||||
extern int g_yres;
|
@ -91,9 +91,11 @@
|
||||
<ClInclude Include="base\basictypes.h" />
|
||||
<ClInclude Include="base\color.h" />
|
||||
<ClInclude Include="base\colorutil.h" />
|
||||
<ClInclude Include="base\display.h" />
|
||||
<ClInclude Include="base\error_context.h" />
|
||||
<ClInclude Include="base\LAMEString.h" />
|
||||
<ClInclude Include="base\logging.h" />
|
||||
<ClInclude Include="base\NativeApp.h" />
|
||||
<ClInclude Include="base\scoped_ptr.h" />
|
||||
<ClInclude Include="base\stats.h" />
|
||||
<ClInclude Include="base\stringutil.h" />
|
||||
@ -136,6 +138,7 @@
|
||||
<ClCompile Include="audio\mixer.cpp" />
|
||||
<ClCompile Include="audio\wav_read.cpp" />
|
||||
<ClCompile Include="base\colorutil.cpp" />
|
||||
<ClCompile Include="base\display.cpp" />
|
||||
<ClCompile Include="base\error_context.cpp" />
|
||||
<ClCompile Include="base\LAMEString.cpp" />
|
||||
<ClCompile Include="base\timeutil.cpp" />
|
||||
@ -176,4 +179,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -138,6 +138,12 @@
|
||||
<ClInclude Include="gfx_es2\vertex_format.h">
|
||||
<Filter>gfx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\NativeApp.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base\display.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="gfx\gl_debug_log.cpp">
|
||||
@ -248,6 +254,9 @@
|
||||
<ClCompile Include="gfx_es2\vertex_format.cpp">
|
||||
<Filter>gfx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\display.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="gfx">
|
||||
|
Loading…
x
Reference in New Issue
Block a user