Merge branch 'master' of github.com:hrydgard/native

This commit is contained in:
Henrik Rydgard
2012-07-08 11:32:46 +02:00
12 changed files with 413 additions and 96 deletions
+36 -13
View File
@@ -21,6 +21,7 @@
#include "input/input_state.h"
#include "audio/mixer.h"
#include "math/math_util.h"
#include "android/native_audio.h"
#define coord_xres 480
#define coord_yres 800
@@ -72,7 +73,6 @@ void LaunchEmail(const char *email_address)
// Remember that all of these need initialization on init! The process
// may be reused when restarting the game. Globals are DANGEROUS.
int xres, yres;
// Used for touch. (TODO)
float xscale = 1;
@@ -82,6 +82,7 @@ InputState input_state;
static bool renderer_inited = false;
static bool first_lost = true;
static bool use_native_audio = false;
extern "C" jboolean Java_com_turboviking_libnative_NativeApp_isLandscape(JNIEnv *env, jclass) {
std::string app_name, app_nice_name;
@@ -92,21 +93,21 @@ extern "C" jboolean Java_com_turboviking_libnative_NativeApp_isLandscape(JNIEnv
extern "C" void Java_com_turboviking_libnative_NativeApp_init
(JNIEnv *env, jclass, jint xxres, jint yyres, jstring apkpath,
jstring dataDir, jstring externalDir, jstring jinstallID) {
jstring dataDir, jstring externalDir, jstring libraryDir, jstring jinstallID, jboolean juseNativeAudio) {
jniEnvUI = env;
xres = xxres;
yres = yyres;
g_xres = xres;
g_yres = yres;
pixel_xres = xxres;
pixel_yres = yyres;
g_xres = xxres;
g_yres = yyres;
use_native_audio = juseNativeAudio;
if (g_xres < g_yres)
{
// Portrait - let's force the imaginary resolution we want
g_xres = coord_xres;
g_yres = coord_yres;
g_xres = pixel_xres;
g_yres = pixel_yres;
}
xscale = (float)coord_xres / xres;
yscale = (float)coord_yres / yres;
xscale = (float)g_xres / pixel_xres;
yscale = (float)g_yres / pixel_yres;
memset(&input_state, 0, sizeof(input_state));
renderer_inited = false;
first_lost = true;
@@ -122,22 +123,34 @@ extern "C" void Java_com_turboviking_libnative_NativeApp_init
str = env->GetStringUTFChars(dataDir, &isCopy);
std::string user_data_path = std::string(str) + "/";
str = env->GetStringUTFChars(libraryDir, &isCopy);
std::string library_path = std::string(str) + "/";
str = env->GetStringUTFChars(jinstallID, &isCopy);
std::string installID = std::string(str);
std::string app_name, app_nice_name;
std::string app_name;
std::string app_nice_name;
bool landscape;
NativeGetAppInfo(&app_name, &app_nice_name, &landscape);
const char *argv[2] = {app_name.c_str(), 0};
NativeInit(1, argv, user_data_path.c_str(), installID.c_str());
if (use_native_audio) {
AndroidAudio_Init(&NativeMix, library_path);
}
}
extern "C" void Java_com_turboviking_libnative_NativeApp_shutdown
(JNIEnv *, jclass) {
ILOG("NativeShutdown.");
if (renderer_inited) {
if (use_native_audio) {
AndroidAudio_Shutdown();
}
if (renderer_inited) {
NativeShutdownGraphics();
renderer_inited = false;
}
NativeShutdown();
ILOG("VFSShutdown.");
@@ -276,3 +289,13 @@ extern "C" void JNICALL Java_com_turboviking_libnative_NativeApp_accelerometer
input_state.acc.y = y;
input_state.acc.z = z;
}
extern "C" void Java_com_turboviking_libnative_NativeApp_sendMessage
(JNIEnv *env, jclass, jstring message, jstring param) {
jboolean isCopy;
std::string msg(env->GetStringUTFChars(message, &isCopy));
std::string prm(env->GetStringUTFChars(param, &isCopy));
ILOG("Message received: %s %s", msg.c_str(), prm.c_str());
}
+199
View File
@@ -0,0 +1,199 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/* This is a JNI example where we use native methods to play sounds
* using OpenSL ES. See the corresponding Java source file located at:
*
* src/com/example/nativeaudio/NativeAudio/NativeAudio.java
*/
#include <assert.h>
#include <string.h>
// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
// #include <android/log.h>
// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "../base/logging.h"
// engine interfaces
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;
// output mix interfaces
static SLObjectItf outputMixObject = NULL;
static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
// buffer queue player interfaces
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLMuteSoloItf bqPlayerMuteSolo;
static SLVolumeItf bqPlayerVolume;
// synthesized sawtooth clip
#define SAWTOOTH_FRAMES 8000
static short sawtoothBuffer[SAWTOOTH_FRAMES];
// pointer and size of the next player buffer to enqueue, and number of remaining buffers
static short *nextBuffer;
static unsigned nextSize;
// synthesize a mono sawtooth wave and place it into a buffer (called automatically on load)
__attribute__((constructor)) static void onDlOpen(void)
{
ILOG("Buffer callback");
unsigned int i;
for (i = 0; i < SAWTOOTH_FRAMES; ++i) {
sawtoothBuffer[i] = 32768 - ((i % 100) * 660);
}
}
// this callback handler is called every time a buffer finishes playing
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
assert(bq == bqPlayerBufferQueue);
assert(NULL == context);
nextBuffer = sawtoothBuffer;
nextSize = sizeof(sawtoothBuffer);
SLresult result;
// enqueue another buffer
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
// which for this code example would indicate a programming error
assert(SL_RESULT_SUCCESS == result);
}
// create the engine and output mix objects
extern "C" bool OpenSLWrap_Init()
{
SLresult result;
// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS == result);
// create output mix, with environmental reverb specified as a non-required interface
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
assert(SL_RESULT_SUCCESS == result);
// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// create buffer queue audio player
// ================================
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
// TODO: This is all wrong.
SLDataFormat_PCM format_pcm = {
SL_DATAFORMAT_PCM,
1,
SL_SAMPLINGRATE_8,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER,
SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
2, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the player
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the play interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
// get the buffer queue interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
// register callback on the buffer queue
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
assert(SL_RESULT_SUCCESS == result);
// get the volume interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
// set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
// Enqueue a first buffer.
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, sawtoothBuffer, sizeof(sawtoothBuffer));
if (SL_RESULT_SUCCESS != result) {
return false;
}
return true;
}
// shut down the native audio system
extern "C" void OpenSLWrap_Shutdown()
{
// destroy buffer queue audio player object, and invalidate all associated interfaces
if (bqPlayerObject != NULL) {
(*bqPlayerObject)->Destroy(bqPlayerObject);
bqPlayerObject = NULL;
bqPlayerPlay = NULL;
bqPlayerBufferQueue = NULL;
bqPlayerMuteSolo = NULL;
bqPlayerVolume = NULL;
}
// destroy output mix object, and invalidate all associated interfaces
if (outputMixObject != NULL) {
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = NULL;
outputMixEnvironmentalReverb = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (engineObject != NULL) {
(*engineObject)->Destroy(engineObject);
engineObject = NULL;
engineEngine = NULL;
}
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// Header for dynamic loading
typedef void (*AndroidAudioCallback)(short *buffer, int num_samples);
typedef bool (*OpenSLWrap_Init_T)(AndroidAudioCallback cb);
typedef void (*OpenSLWrap_Shutdown_T)();
+36
View File
@@ -0,0 +1,36 @@
#include <dlfcn.h>
#include <errno.h>
#include "base/logging.h"
#include "android/native_audio.h"
#include "android/native-audio-so.h"
static void *so;
static OpenSLWrap_Init_T init_func;
static OpenSLWrap_Shutdown_T shutdown_func;
bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir) {
ILOG("Loading native audio library...");
std::string so_filename = libraryDir + "/libnative_audio.so";
so = dlopen(so_filename.c_str(), RTLD_LAZY);
if (!so) {
ELOG("Failed to find native audio library: %i: %s ", errno, dlerror());
return false;
}
init_func = (OpenSLWrap_Init_T)dlsym(so, "OpenSLWrap_Init");
shutdown_func = (OpenSLWrap_Shutdown_T)dlsym(so, "OpenSLWrap_Shutdown");
ILOG("Calling OpenSLWrap_Init_T...");
bool init_retval = init_func(cb);
ILOG("Returned from OpenSLWrap_Init_T");
return init_retval;
}
void AndroidAudio_Shutdown() {
ILOG("Calling OpenSLWrap_Shutdown_T...");
shutdown_func();
ILOG("Returned from OpenSLWrap_Shutdown_T");
dlclose(so);
so = 0;
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "native-audio-so.h"
#include <string>
// This is the file you should include from your program. It dynamically loads
// the native_audio.so shared object and sets up the function pointers.
// Do not call this if you have detected that the android version is below
// 2.2, as it will fail miserably.
bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir);
void AndroidAudio_Shutdown();
@@ -3,6 +3,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.util.UUID;
import javax.microedition.khronos.egl.EGLConfig;
@@ -86,12 +87,31 @@ public class NativeActivity extends Activity {
private GLSurfaceView mGLSurfaceView;
private NativeAudioPlayer audioPlayer;
boolean useOpenSL = false;
public static String runCommand;
public static String commandParameter;
public static String installID;
String getApplicationLibraryDir(ApplicationInfo application) {
String libdir = null;
try {
// Starting from Android 2.3, nativeLibraryDir is available:
Field field = ApplicationInfo.class.getField("nativeLibraryDir");
libdir = (String) field.get(application);
} catch (SecurityException e1) {
} catch (NoSuchFieldException e1) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
if (libdir == null) {
// Fallback for Android < 2.3:
libdir = application.dataDir + "/lib";
}
return libdir;
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (NativeApp.isLandscape()) {
@@ -112,6 +132,7 @@ public class NativeActivity extends Activity {
e.printStackTrace();
throw new RuntimeException("Unable to locate assets, aborting...");
}
String libraryDir = getApplicationLibraryDir(appInfo);
File sdcard = Environment.getExternalStorageDirectory();
Display display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int scrPixelFormat = display.getPixelFormat();
@@ -121,7 +142,8 @@ public class NativeActivity extends Activity {
String externalStorageDir = sdcard.getAbsolutePath();
String dataDir = this.getFilesDir().getAbsolutePath();
String apkFilePath = appInfo.sourceDir;
NativeApp.init(scrWidth, scrHeight, apkFilePath, dataDir, externalStorageDir, installID);
NativeApp.sendMessage("Message from Java", "Hot Coffee");
NativeApp.init(scrWidth, scrHeight, apkFilePath, dataDir, externalStorageDir, libraryDir, installID, useOpenSL);
// Keep the screen bright - very annoying if it goes dark when tilting away
Window window = this.getWindow();
@@ -143,7 +165,8 @@ public class NativeActivity extends Activity {
// Native OpenSL is available. Let's not use the Java player in the future.
// TODO: code for that.
}
audioPlayer = new NativeAudioPlayer();
if (!useOpenSL)
audioPlayer = new NativeAudioPlayer();
}
private boolean detectOpenGLES20() {
@@ -4,7 +4,7 @@ public class NativeApp {
public static native boolean isLandscape();
public static native void init(
int xxres, int yyres, String apkPath,
String dataDir, String externalDir, String installID);
String dataDir, String externalDir, String libraryDir, String installID, boolean useOpenSL);
public static native void shutdown();
public static native void keyDown(int key);
@@ -16,4 +16,6 @@ public class NativeApp {
// Sensor/input data. These are asynchronous, beware!
public static native void touch(float x, float y, int data, int pointerId);
public static native void accelerometer(float x, float y, float z);
public static native void sendMessage(String msg, String arg);
}
+88 -78
View File
@@ -29,7 +29,11 @@
// Simple implementations of System functions
void SystemToast(const char *text) {
#ifdef _WIN32
MessageBox(0, text, "Toast!", MB_ICONINFORMATION);
#else
puts(text);
#endif
}
@@ -72,69 +76,79 @@ void LaunchEmail(const char *email_address)
const int buttonMappings[12] = {
SDLK_x, //A
SDLK_s, //B
SDLK_z, //X
SDLK_a, //Y
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_UP, //UP
SDLK_DOWN, //DOWN
SDLK_LEFT, //LEFT
SDLK_RIGHT, //RIGHT
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;
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;
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;
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;
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;
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);
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;
*/
/* // Xoom resolution. Other common tablet resolutions: 1024x600 , 1366x768
g_xres = 1280;
g_yres = 800;
*/
std::string app_name;
std::string app_name_nice;
bool landscape;
NativeGetAppInfo(&app_name, &app_name_nice, &landscape);
float zoom = 0.7f;
const char *zoomenv = getenv("ZOOM");
if (zoomenv) {
zoom = atof(zoomenv);
}
if (landscape) {
g_xres = 800;
g_yres = 480;
pixel_xres = 800 * zoom;
pixel_yres = 480 * zoom;
} else {
#ifdef _WIN32
g_xres = 1580;
g_yres = 1000;
#endif
pixel_xres = 1580 * zoom;
pixel_yres = 1000 * zoom;
}
net::Init();
float density = 1.0f;
g_xres = (float)pixel_xres * density / zoom;
g_yres = (float)pixel_yres * density / zoom;
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
printf("Virtual pixels: %i x %i\n", g_xres, g_yres);
net::Init();
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
@@ -151,7 +165,7 @@ int main(int argc, char *argv[]) {
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) {
if (SDL_SetVideoMode(pixel_xres, pixel_yres, 0, SDL_OPENGL) == NULL) {
fprintf(stderr, "SDL SetVideoMode failed: Unable to create OpenGL screen: %s\n", SDL_GetError());
SDL_Quit();
return(2);
@@ -189,32 +203,32 @@ int main(int argc, char *argv[]) {
#endif
NativeInit(argc, (const char **)argv, path, "BADCOFFEE");
NativeInitGraphics();
NativeInitGraphics();
SDL_AudioSpec fmt;
fmt.freq = 44100;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 1024;
fmt.callback = &mixaudio;
fmt.userdata = (void *)0;
SDL_AudioSpec fmt;
fmt.freq = 44100;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 1024;
fmt.callback = &mixaudio;
fmt.userdata = (void *)0;
if (SDL_OpenAudio(&fmt, NULL) < 0) {
ELOG("Failed to open audio: %s", SDL_GetError());
return 1;
}
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);
// Audio must be unpaused _after_ NativeInit()
SDL_PauseAudio(0);
InputState input_state;
int framecount = 0;
InputState input_state;
int framecount = 0;
bool nextFrameMD = 0;
while (true) {
SDL_Event event;
input_state.accelerometer_valid = false;
input_state.mouse_valid = true;
input_state.accelerometer_valid = false;
input_state.mouse_valid = true;
int done = 0;
// input_state.mouse_down[1] = nextFrameMD;
@@ -226,61 +240,57 @@ int main(int argc, char *argv[]) {
done = 1;
}
} else if (event.type == SDL_MOUSEMOTION) {
input_state.mouse_x[0] = event.motion.x;
input_state.mouse_y[0] = event.motion.y;
input_state.mouse_x[1] = event.motion.x + 150;
input_state.mouse_y[1] = event.motion.y;
input_state.mouse_x[0] = event.motion.x * density / zoom;
input_state.mouse_y[0] = event.motion.y * density / zoom;
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.button == SDL_BUTTON_LEFT) {
///input_state.mouse_buttons_down = 1;
//input_state.mouse_buttons_down = 1;
input_state.mouse_down[0] = true;
nextFrameMD = true;
}
} else if (event.type == SDL_MOUSEBUTTONUP) {
if (event.button.button == SDL_BUTTON_LEFT) {
input_state.mouse_down[0] = false;
nextFrameMD = false;
//input_state.mouse_buttons_up = 1;
}
nextFrameMD = false;
//input_state.mouse_buttons_up = 1;
}
}
}
if (done)
break;
if (done) break;
input_state.mouse_last[0] = input_state.mouse_down[0];
input_state.mouse_last[0] = input_state.mouse_down[0];
uint8 *keys = (uint8 *)SDL_GetKeyState(NULL);
if (keys[SDLK_ESCAPE]) {
break;
}
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.
}
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
// Simple framerate limiting
static float t=0;
while (time_now() < t+1.0f/60.0f) {
sleep_ms(0);
time_update();
time_update();
}
time_update();
time_update();
t = time_now();
framecount++;
framecount++;
}
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
exit(0);
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
exit(0);
NativeShutdownGraphics();
SDL_PauseAudio(1);
NativeShutdown();
SDL_CloseAudio();
NativeShutdownGraphics();
SDL_PauseAudio(1);
NativeShutdown();
SDL_CloseAudio();
SDL_Quit();
return 0;
}
+2
View File
@@ -2,3 +2,5 @@
int g_xres;
int g_yres;
int pixel_xres;
int pixel_yres;
+2
View File
@@ -5,3 +5,5 @@
extern int g_xres;
extern int g_yres;
extern int pixel_xres;
extern int pixel_yres;
+2 -1
View File
@@ -1,7 +1,8 @@
set(SRCS
draw_buffer.cpp
fbo.cpp
glsl_program.cpp)
glsl_program.cpp
vertex_format.cpp)
set(SRCS ${SRCS})
-1
View File
@@ -2,7 +2,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>