Merge branch 'sdl_android' of github.com:pelya/commandergenius into sdl_android
Conflicts: project/jni/application/commandergenius/AndroidAppSettings.cfg
This commit is contained in:
@@ -33,7 +33,7 @@ import android.hardware.SensorManager;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class AccelerometerReader implements SensorEventListener
|
||||
{
|
||||
if( _manager != null )
|
||||
{
|
||||
System.out.println("libSDL: stopping accelerometer/gyroscope");
|
||||
Log.i("SDL", "libSDL: stopping accelerometer/gyroscope");
|
||||
_manager.unregisterListener(this);
|
||||
_manager.unregisterListener(gyro);
|
||||
}
|
||||
@@ -64,12 +64,12 @@ class AccelerometerReader implements SensorEventListener
|
||||
if( (Globals.UseAccelerometerAsArrowKeys || Globals.AppUsesAccelerometer) &&
|
||||
_manager != null && _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null )
|
||||
{
|
||||
System.out.println("libSDL: starting accelerometer");
|
||||
Log.i("SDL", "libSDL: starting accelerometer");
|
||||
_manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
if( Globals.AppUsesGyroscope && _manager != null && _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null )
|
||||
{
|
||||
System.out.println("libSDL: starting gyroscope");
|
||||
Log.i("SDL", "libSDL: starting gyroscope");
|
||||
_manager.registerListener(gyro, _manager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class AudioThread
|
||||
}
|
||||
if( !mRecordThread.isStopped() )
|
||||
{
|
||||
System.out.println("SDL: error: application already opened audio recording device");
|
||||
Log.i("SDL", "SDL: error: application already opened audio recording device");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ class AudioThread
|
||||
|
||||
int minBufDevice = AudioRecord.getMinBufferSize(rate, channelConfig, encodingConfig);
|
||||
int minBufferSize = Math.max(bufsize * 8, minBufDevice + (bufsize - (minBufDevice % bufsize)));
|
||||
System.out.println("SDL: app opened recording device, rate " + rate + " channels " + channels + " sample size " + (encoding+1) + " bufsize " + bufsize + " internal bufsize " + minBufferSize);
|
||||
Log.i("SDL", "SDL: app opened recording device, rate " + rate + " channels " + channels + " sample size " + (encoding+1) + " bufsize " + bufsize + " internal bufsize " + minBufferSize);
|
||||
if( mRecorder == null || mRecorder.getSampleRate() != rate ||
|
||||
mRecorder.getChannelCount() != channels ||
|
||||
mRecorder.getAudioFormat() != encodingConfig ||
|
||||
@@ -199,13 +199,13 @@ class AudioThread
|
||||
mRecorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, encodingConfig, minBufferSize);
|
||||
mRecorderBufferSize = minBufferSize;
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("SDL: error: failed to open recording device!");
|
||||
Log.i("SDL", "SDL: error: failed to open recording device!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("SDL: reusing old recording device");
|
||||
Log.i("SDL", "SDL: reusing old recording device");
|
||||
}
|
||||
mRecordThread.startRecording();
|
||||
return mRecordThread.mRecordBuffer;
|
||||
@@ -215,11 +215,11 @@ class AudioThread
|
||||
{
|
||||
if( mRecordThread == null || mRecordThread.isStopped() )
|
||||
{
|
||||
System.out.println("SDL: error: application already closed audio recording device");
|
||||
Log.i("SDL", "SDL: error: application already closed audio recording device");
|
||||
return;
|
||||
}
|
||||
mRecordThread.stopRecording();
|
||||
System.out.println("SDL: app closed recording device");
|
||||
Log.i("SDL", "SDL: app closed recording device");
|
||||
}
|
||||
|
||||
private class RecordingThread extends Thread
|
||||
@@ -261,9 +261,9 @@ class AudioThread
|
||||
}
|
||||
else
|
||||
{
|
||||
//System.out.println("SDL: nativeAudioRecordCallback with len " + mRecordBuffer.length);
|
||||
//Log.i("SDL", "SDL: nativeAudioRecordCallback with len " + mRecordBuffer.length);
|
||||
nativeAudioRecordCallback();
|
||||
//System.out.println("SDL: nativeAudioRecordCallback returned");
|
||||
//Log.i("SDL", "SDL: nativeAudioRecordCallback returned");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ class DataDownloader extends Thread
|
||||
String [] downloadUrls = DataDownloadUrl.split("[|]");
|
||||
if( downloadUrls.length < 2 )
|
||||
{
|
||||
System.out.println("Error: download string invalid: '" + DataDownloadUrl + "', your AndroidAppSettigns.cfg is broken");
|
||||
Log.i("SDL", "Error: download string invalid: '" + DataDownloadUrl + "', your AndroidAppSettigns.cfg is broken");
|
||||
Status.setText( res.getString(R.string.error_dl_from, DataDownloadUrl) );
|
||||
return false;
|
||||
}
|
||||
@@ -249,14 +249,14 @@ class DataDownloader extends Thread
|
||||
if( readed > 0 )
|
||||
compare = new String( b, 0, readed, "UTF-8" );
|
||||
boolean matched = false;
|
||||
//System.out.println("Read URL: '" + compare + "'");
|
||||
//Log.i("SDL", "Read URL: '" + compare + "'");
|
||||
for( int i = 1; i < downloadUrls.length; i++ )
|
||||
{
|
||||
//System.out.println("Comparing: '" + downloadUrls[i] + "'");
|
||||
//Log.i("SDL", "Comparing: '" + downloadUrls[i] + "'");
|
||||
if( compare.compareTo(downloadUrls[i]) == 0 )
|
||||
matched = true;
|
||||
}
|
||||
//System.out.println("Matched: " + String.valueOf(matched));
|
||||
//Log.i("SDL", "Matched: " + String.valueOf(matched));
|
||||
if( ! matched )
|
||||
throw new IOException();
|
||||
Status.setText( res.getString(R.string.download_unneeded) );
|
||||
@@ -269,7 +269,7 @@ class DataDownloader extends Thread
|
||||
checkFile = null;
|
||||
|
||||
// Create output directory (not necessary for phone storage)
|
||||
System.out.println("Downloading data to: '" + outFilesDir + "'");
|
||||
Log.i("SDL", "Downloading data to: '" + outFilesDir + "'");
|
||||
try {
|
||||
File outDir = new File( outFilesDir );
|
||||
if( !(outDir.exists() && outDir.isDirectory()) )
|
||||
@@ -295,7 +295,7 @@ class DataDownloader extends Thread
|
||||
int downloadUrlIndex = 1;
|
||||
while( downloadUrlIndex < downloadUrls.length )
|
||||
{
|
||||
System.out.println("Processing download " + downloadUrls[downloadUrlIndex]);
|
||||
Log.i("SDL", "Processing download " + downloadUrls[downloadUrlIndex]);
|
||||
url = new String(downloadUrls[downloadUrlIndex]);
|
||||
DoNotUnzip = false;
|
||||
if(url.indexOf(":") == 0)
|
||||
@@ -320,35 +320,37 @@ class DataDownloader extends Thread
|
||||
stream1 = Parent.getAssets().open(url + "00");
|
||||
stream1.close();
|
||||
} catch( Exception ee ) {
|
||||
System.out.println("Failed to open file in assets: " + url);
|
||||
Log.i("SDL", "Failed to open file in assets: " + url);
|
||||
downloadUrlIndex++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
FileInAssets = true;
|
||||
System.out.println("Fetching file from assets: " + url);
|
||||
Log.i("SDL", "Fetching file from assets: " + url);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Connecting to: " + url);
|
||||
Log.i("SDL", "Connecting to: " + url);
|
||||
request = new HttpGet(url);
|
||||
request.addHeader("Accept", "*/*");
|
||||
if( partialDownloadLen > 0 )
|
||||
if( partialDownloadLen > 0 ) {
|
||||
request.addHeader("Range", "bytes=" + partialDownloadLen + "-");
|
||||
Log.i("SDL", "Trying to resume download at pos " + partialDownloadLen);
|
||||
}
|
||||
try {
|
||||
DefaultHttpClient client = HttpWithDisabledSslCertCheck();
|
||||
client.getParams().setBooleanParameter("http.protocol.handle-redirects", true);
|
||||
response = client.execute(request);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Failed to connect to " + url);
|
||||
Log.i("SDL", "Failed to connect to " + url);
|
||||
downloadUrlIndex++;
|
||||
};
|
||||
if( response != null )
|
||||
{
|
||||
if( response.getStatusLine().getStatusCode() != 200 && response.getStatusLine().getStatusCode() != 206 )
|
||||
{
|
||||
System.out.println("Failed to connect to " + url + " with error " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
|
||||
Log.i("SDL", "Failed to connect to " + url + " with error " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
|
||||
responseError = response;
|
||||
response = null;
|
||||
downloadUrlIndex++;
|
||||
@@ -376,7 +378,7 @@ class DataDownloader extends Thread
|
||||
multipart = s;
|
||||
else
|
||||
multipart = new SequenceInputStream(multipart, s);
|
||||
System.out.println("Multipart archive found: " + url1);
|
||||
Log.i("SDL", "Multipart archive found: " + url1);
|
||||
} catch( IOException e ) {
|
||||
break;
|
||||
}
|
||||
@@ -393,7 +395,7 @@ class DataDownloader extends Thread
|
||||
stream.close();
|
||||
stream = new CountingInputStream(Parent.getAssets().open(url), 8192);
|
||||
} catch( IOException e ) {
|
||||
System.out.println("Unpacking from assets '" + url + "' - error: " + e.toString());
|
||||
Log.i("SDL", "Unpacking from assets '" + url + "' - error: " + e.toString());
|
||||
Status.setText( res.getString(R.string.error_dl_from, url) );
|
||||
return false;
|
||||
}
|
||||
@@ -403,7 +405,7 @@ class DataDownloader extends Thread
|
||||
{
|
||||
if( response == null )
|
||||
{
|
||||
System.out.println("Error connecting to " + url);
|
||||
Log.i("SDL", "Error connecting to " + url);
|
||||
Status.setText( res.getString(R.string.failed_connecting_to, url) + (responseError == null ? "" : ": " + responseError.getStatusLine().getStatusCode() + " " + responseError.getStatusLine().getReasonPhrase()) );
|
||||
return false;
|
||||
}
|
||||
@@ -420,7 +422,7 @@ class DataDownloader extends Thread
|
||||
|
||||
if(DoNotUnzip)
|
||||
{
|
||||
System.out.println("Saving file '" + path + "'");
|
||||
Log.i("SDL", "Saving file '" + path + "'");
|
||||
OutputStream out = null;
|
||||
try {
|
||||
try {
|
||||
@@ -435,14 +437,16 @@ class DataDownloader extends Thread
|
||||
Header[] range = response.getHeaders("Content-Range");
|
||||
if( range.length > 0 && range[0].getValue().indexOf("bytes") == 0 )
|
||||
{
|
||||
//System.out.println("Resuming download of file '" + path + "': Content-Range: " + range[0].getValue());
|
||||
//Log.i("SDL", "Resuming download of file '" + path + "': Content-Range: " + range[0].getValue());
|
||||
String[] skippedBytes = range[0].getValue().split("/")[0].split("-")[0].split(" ");
|
||||
if( skippedBytes.length >= 2 && Long.parseLong(skippedBytes[1]) == partialDownloadLen )
|
||||
{
|
||||
out = new FileOutputStream( path, true );
|
||||
System.out.println("Resuming download of file '" + path + "' at pos " + partialDownloadLen);
|
||||
Log.i("SDL", "Resuming download of file '" + path + "' at pos " + partialDownloadLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
Log.i("SDL", "Server does not support partial downloads. " + (range.length == 0 ? "" : range[0].getValue()));
|
||||
} catch (Exception e) { }
|
||||
}
|
||||
if( out == null )
|
||||
@@ -451,14 +455,14 @@ class DataDownloader extends Thread
|
||||
partialDownloadLen = 0;
|
||||
}
|
||||
} catch( FileNotFoundException e ) {
|
||||
System.out.println("Saving file '" + path + "' - error creating output file: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - error creating output file: " + e.toString());
|
||||
} catch( SecurityException e ) {
|
||||
System.out.println("Saving file '" + path + "' - error creating output file: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - error creating output file: " + e.toString());
|
||||
};
|
||||
if( out == null )
|
||||
{
|
||||
Status.setText( res.getString(R.string.error_write, path) );
|
||||
System.out.println("Saving file '" + path + "' - error creating output file");
|
||||
Log.i("SDL", "Saving file '" + path + "' - error creating output file");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -480,14 +484,14 @@ class DataDownloader extends Thread
|
||||
out = null;
|
||||
} catch( java.io.IOException e ) {
|
||||
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
|
||||
System.out.println("Saving file '" + path + "' - error writing: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - error writing: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
System.out.println("Saving file '" + path + "' done");
|
||||
Log.i("SDL", "Saving file '" + path + "' done");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Reading from zip file '" + url + "'");
|
||||
Log.i("SDL", "Reading from zip file '" + url + "'");
|
||||
ZipInputStream zip = new ZipInputStream(stream);
|
||||
|
||||
while(true)
|
||||
@@ -496,20 +500,20 @@ class DataDownloader extends Thread
|
||||
try {
|
||||
entry = zip.getNextEntry();
|
||||
if( entry != null )
|
||||
System.out.println("Reading from zip file '" + url + "' entry '" + entry.getName() + "'");
|
||||
Log.i("SDL", "Reading from zip file '" + url + "' entry '" + entry.getName() + "'");
|
||||
} catch( java.io.IOException e ) {
|
||||
Status.setText( res.getString(R.string.error_dl_from, url) );
|
||||
System.out.println("Error reading from zip file '" + url + "': " + e.toString());
|
||||
Log.i("SDL", "Error reading from zip file '" + url + "': " + e.toString());
|
||||
return false;
|
||||
}
|
||||
if( entry == null )
|
||||
{
|
||||
System.out.println("Reading from zip file '" + url + "' finished");
|
||||
Log.i("SDL", "Reading from zip file '" + url + "' finished");
|
||||
break;
|
||||
}
|
||||
if( entry.isDirectory() )
|
||||
{
|
||||
System.out.println("Creating dir '" + getOutFilePath(entry.getName()) + "'");
|
||||
Log.i("SDL", "Creating dir '" + getOutFilePath(entry.getName()) + "'");
|
||||
try {
|
||||
File outDir = new File( getOutFilePath(entry.getName()) );
|
||||
if( !(outDir.exists() && outDir.isDirectory()) )
|
||||
@@ -522,7 +526,7 @@ class DataDownloader extends Thread
|
||||
path = getOutFilePath(entry.getName());
|
||||
float percent = 0.0f;
|
||||
|
||||
System.out.println("Saving file '" + path + "'");
|
||||
Log.i("SDL", "Saving file '" + path + "'");
|
||||
|
||||
try {
|
||||
File outDir = new File( path.substring(0, path.lastIndexOf("/") ));
|
||||
@@ -540,7 +544,7 @@ class DataDownloader extends Thread
|
||||
ff.delete();
|
||||
throw new Exception();
|
||||
}
|
||||
System.out.println("File '" + path + "' exists and passed CRC check - not overwriting it");
|
||||
Log.i("SDL", "File '" + path + "' exists and passed CRC check - not overwriting it");
|
||||
if( totalLen > 0 )
|
||||
percent = stream.getBytesRead() * 100.0f / totalLen;
|
||||
Status.setText( downloadCount + "/" + downloadTotal + ": " + res.getString(R.string.dl_progress, percent, path) );
|
||||
@@ -550,14 +554,14 @@ class DataDownloader extends Thread
|
||||
try {
|
||||
out = new FileOutputStream( path );
|
||||
} catch( FileNotFoundException e ) {
|
||||
System.out.println("Saving file '" + path + "' - cannot create file: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - cannot create file: " + e.toString());
|
||||
} catch( SecurityException e ) {
|
||||
System.out.println("Saving file '" + path + "' - cannot create file: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - cannot create file: " + e.toString());
|
||||
};
|
||||
if( out == null )
|
||||
{
|
||||
Status.setText( res.getString(R.string.error_write, path) );
|
||||
System.out.println("Saving file '" + path + "' - cannot create file");
|
||||
Log.i("SDL", "Saving file '" + path + "' - cannot create file");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -583,7 +587,7 @@ class DataDownloader extends Thread
|
||||
out = null;
|
||||
} catch( java.io.IOException e ) {
|
||||
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
|
||||
System.out.println("Saving file '" + path + "' - error writing or downloading: " + e.toString());
|
||||
Log.i("SDL", "Saving file '" + path + "' - error writing or downloading: " + e.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -600,7 +604,7 @@ class DataDownloader extends Thread
|
||||
{
|
||||
File ff = new File(path);
|
||||
ff.delete();
|
||||
System.out.println("Saving file '" + path + "' - CRC check failed, ZIP: " +
|
||||
Log.i("SDL", "Saving file '" + path + "' - CRC check failed, ZIP: " +
|
||||
String.format("%x", entry.getCrc()) + " actual file: " + String.format("%x", check.getChecksum().getValue()) +
|
||||
" file size in ZIP: " + entry.getSize() + " actual size " + count );
|
||||
throw new Exception();
|
||||
@@ -609,7 +613,7 @@ class DataDownloader extends Thread
|
||||
Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() );
|
||||
return false;
|
||||
}
|
||||
System.out.println("Saving file '" + path + "' done");
|
||||
Log.i("SDL", "Saving file '" + path + "' done");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -682,7 +686,7 @@ class DataDownloader extends Thread
|
||||
}
|
||||
|
||||
|
||||
public class BackKeyListener implements Settings.KeyEventsListener
|
||||
public class BackKeyListener implements MainActivity.KeyEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
public BackKeyListener(MainActivity _p)
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.app.KeyguardManager;
|
||||
|
||||
/**
|
||||
* An implementation of SurfaceView that uses the dedicated surface for
|
||||
@@ -698,15 +699,18 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call
|
||||
EGL10.EGL_NATIVE_RENDERABLE, 0);
|
||||
int caveat = findConfigAttrib(egl, display, config,
|
||||
EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_NONE);
|
||||
int distance = Math.abs(r - mRedSize)
|
||||
+ Math.abs(g - mGreenSize)
|
||||
+ Math.abs(b - mBlueSize) + Math.abs(a - mAlphaSize);
|
||||
int distance = Math.abs(r - mRedSize) + Math.abs(g - mGreenSize) + Math.abs(b - mBlueSize);
|
||||
int dist1 = distance;
|
||||
if( mAlphaSize - a > 0 )
|
||||
distance += mAlphaSize - a;
|
||||
else if( mAlphaSize - a < 0 )
|
||||
distance += 1; // Small penalty if we don't need alpha channel but it is present
|
||||
int dist2 = distance;
|
||||
if( (d > 0) != (mDepthSize > 0) )
|
||||
distance += (mDepthSize > 0) ? 5 : 1; // Small penalty if we don't need zbuffer but it is present
|
||||
int dist3 = distance;
|
||||
if( (s > 0) != (mStencilSize > 0) )
|
||||
distance += (mStencilSize > 0) ? 5 : 1;
|
||||
distance += (mStencilSize > 0) ? 5 : 1; // Small penalty if we don't need stencil buffer but it is present
|
||||
int dist4 = distance;
|
||||
if( (rendertype & desiredtype) == 0 )
|
||||
distance += 5;
|
||||
@@ -732,7 +736,7 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call
|
||||
caveat == EGL10.EGL_NON_CONFORMANT_CONFIG ? "non-conformant" :
|
||||
String.valueOf(caveat)));
|
||||
cfgcur += " nr " + nativeRender;
|
||||
cfgcur += " pos " + distance + " (" + dist2 + "," + dist3 + "," + dist4 + "," + dist5 + ")";
|
||||
cfgcur += " pos " + distance + " (" + dist1 + "," + dist2 + "," + dist3 + "," + dist4 + "," + dist5 + ")";
|
||||
Log.v("SDL", "GL config " + idx + ": " + cfgcur);
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
@@ -1100,6 +1104,10 @@ public class GLSurfaceView_SDL extends SurfaceView implements SurfaceHolder.Call
|
||||
}
|
||||
|
||||
private boolean needToWait() {
|
||||
if (((KeyguardManager)getContext().getSystemService(Context.KEYGUARD_SERVICE)).inKeyguardRestrictedInputMode()) {
|
||||
return true; // We're in lockscreen - sleep until user unlocks the device
|
||||
}
|
||||
|
||||
if (mDone) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class Globals
|
||||
public static boolean AppNeedsArrowKeys = true;
|
||||
public static boolean AppNeedsTextInput = true;
|
||||
public static boolean AppUsesJoystick = false;
|
||||
public static boolean AppUsesSecondJoystick = false;
|
||||
public static boolean AppUsesAccelerometer = false;
|
||||
public static boolean AppUsesGyroscope = false;
|
||||
public static boolean AppUsesMultitouch = false;
|
||||
@@ -64,8 +65,8 @@ class Globals
|
||||
public static String[] AppTouchscreenKeyboardKeysNames = "Fire Shoot Switch_weapon Jump Run Hide/Seek".split(" ");
|
||||
public static int StartupMenuButtonTimeout = 3000;
|
||||
public static int AppMinimumRAM = 0;
|
||||
public static Settings.Menu HiddenMenuOptions [] = {};
|
||||
public static Settings.Menu FirstStartMenuOptions [] = { (AppUsesMouse && ! ForceRelativeMouseMode ? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration() };
|
||||
public static SettingsMenu.Menu HiddenMenuOptions [] = {}; // If you see error here - update HiddenMenuOptions in your AndroidAppSettings.cfg: change OptionalDownloadConfig to SettingsMenuMisc.OptionalDownloadConfig etc.
|
||||
public static SettingsMenu.Menu FirstStartMenuOptions [] = { new SettingsMenuMisc.ShowReadme(), (AppUsesMouse && ! ForceRelativeMouseMode ? new SettingsMenuMouse.DisplaySizeConfig() : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(), new SettingsMenuMisc.GyroscopeCalibration() };
|
||||
public static String AdmobPublisherId = "";
|
||||
public static String AdmobTestDeviceId = "";
|
||||
public static String AdmobBannerSize = "";
|
||||
@@ -77,6 +78,7 @@ class Globals
|
||||
public static boolean UseAccelerometerAsArrowKeys = false;
|
||||
public static boolean UseTouchscreenKeyboard = true;
|
||||
public static int TouchscreenKeyboardSize = 1;
|
||||
public static final int TOUCHSCREEN_KEYBOARD_CUSTOM = 4;
|
||||
public static int TouchscreenKeyboardDrawSize = 1;
|
||||
public static int TouchscreenKeyboardTheme = 2;
|
||||
public static int TouchscreenKeyboardTransparency = 2;
|
||||
@@ -104,8 +106,10 @@ class Globals
|
||||
public static int ClickScreenTouchspotSize = 0;
|
||||
public static int RemapHwKeycode[] = new int[SDL_Keys.JAVA_KEYCODE_LAST];
|
||||
public static int RemapScreenKbKeycode[] = new int[6];
|
||||
public static boolean ScreenKbControlsShown[] = new boolean[8]; /* Also joystick and text input button added */
|
||||
public static int ScreenKbControlsLayout[][] = new int[][] { { 0, 303, 177, 480 }, { 0, 0, 48, 48 }, { 712, 392, 800, 480 }, { 624, 392, 712, 480 }, { 712, 304, 800, 392 }, { 624, 304, 712, 392 }, { 712, 216, 800, 304 }, { 624, 216, 712, 304 } }; // Values for 800x480 resolution
|
||||
public static int ScreenKbControlsLayout[][] = AppUsesSecondJoystick ? // Values for 800x480 resolution
|
||||
new int[][] { { 0, 303, 177, 480 }, { 0, 0, 48, 48 }, { 400, 392, 488, 480 }, { 312, 392, 400, 480 }, { 400, 304, 488, 392 }, { 312, 304, 400, 392 }, { 400, 216, 488, 304 }, { 312, 216, 400, 304 }, { 623, 303, 800, 480 } } :
|
||||
new int[][] { { 0, 303, 177, 480 }, { 0, 0, 48, 48 }, { 712, 392, 800, 480 }, { 624, 392, 712, 480 }, { 712, 304, 800, 392 }, { 624, 304, 712, 392 }, { 712, 216, 800, 304 }, { 624, 216, 712, 304 } };
|
||||
public static boolean ScreenKbControlsShown[] = new boolean[ScreenKbControlsLayout.length]; /* Also joystick and text input button added */
|
||||
public static int RemapMultitouchGestureKeycode[] = new int[4];
|
||||
public static boolean MultitouchGesturesUsed[] = new boolean[4];
|
||||
public static int MultitouchGestureSensitivity = 1;
|
||||
|
||||
@@ -525,6 +525,16 @@ class SDL_Keys
|
||||
|
||||
static final int JAVA_KEYCODE_LAST = 255; // Android 2.3 added several new gaming keys, Android 3.1 added even more - keep in sync with javakeycodes.h
|
||||
|
||||
static String getName(int v)
|
||||
{
|
||||
for( int f = 0; f < values.length; f++ )
|
||||
{
|
||||
if( values[f] == v )
|
||||
return names[f];
|
||||
}
|
||||
return names[0];
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
ArrayList<String> Names = new ArrayList<String> ();
|
||||
|
||||
@@ -74,6 +74,7 @@ import java.util.concurrent.Semaphore;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.view.Display;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
|
||||
public class MainActivity extends Activity
|
||||
{
|
||||
@@ -93,7 +94,7 @@ public class MainActivity extends Activity
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
System.out.println("libSDL: Creating startup screen");
|
||||
Log.i("SDL", "libSDL: Creating startup screen");
|
||||
_layout = new LinearLayout(this);
|
||||
_layout.setOrientation(LinearLayout.VERTICAL);
|
||||
_layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
@@ -114,9 +115,9 @@ public class MainActivity extends Activity
|
||||
public void onClick(View v)
|
||||
{
|
||||
setUpStatusLabel();
|
||||
System.out.println("libSDL: User clicked change phone config button");
|
||||
Log.i("SDL", "libSDL: User clicked change phone config button");
|
||||
loadedLibraries.acquireUninterruptibly();
|
||||
Settings.showConfig(p, false);
|
||||
SettingsMenu.showConfig(p, false);
|
||||
}
|
||||
};
|
||||
_btn.setOnClickListener(new onClickListener(this));
|
||||
@@ -164,10 +165,10 @@ public class MainActivity extends Activity
|
||||
|
||||
if(p.mAudioThread == null)
|
||||
{
|
||||
System.out.println("libSDL: Loading libraries");
|
||||
Log.i("SDL", "libSDL: Loading libraries");
|
||||
p.LoadLibraries();
|
||||
p.mAudioThread = new AudioThread(p);
|
||||
System.out.println("libSDL: Loading settings");
|
||||
Log.i("SDL", "libSDL: Loading settings");
|
||||
final Semaphore loaded = new Semaphore(0);
|
||||
class Callback2 implements Runnable
|
||||
{
|
||||
@@ -191,14 +192,14 @@ public class MainActivity extends Activity
|
||||
{
|
||||
if( Globals.StartupMenuButtonTimeout > 0 )
|
||||
{
|
||||
System.out.println("libSDL: " + String.valueOf(Globals.StartupMenuButtonTimeout) + "-msec timeout in startup screen");
|
||||
Log.i("SDL", "libSDL: " + String.valueOf(Globals.StartupMenuButtonTimeout) + "-msec timeout in startup screen");
|
||||
try {
|
||||
Thread.sleep(Globals.StartupMenuButtonTimeout);
|
||||
} catch( InterruptedException e ) {};
|
||||
}
|
||||
if( Settings.settingsChanged )
|
||||
return;
|
||||
System.out.println("libSDL: Timeout reached in startup screen, process with downloader");
|
||||
Log.i("SDL", "libSDL: Timeout reached in startup screen, process with downloader");
|
||||
p.startDownloader();
|
||||
}
|
||||
}
|
||||
@@ -225,14 +226,14 @@ public class MainActivity extends Activity
|
||||
|
||||
public void startDownloader()
|
||||
{
|
||||
System.out.println("libSDL: Starting data downloader");
|
||||
Log.i("SDL", "libSDL: Starting data downloader");
|
||||
class Callback implements Runnable
|
||||
{
|
||||
public MainActivity Parent;
|
||||
public void run()
|
||||
{
|
||||
setUpStatusLabel();
|
||||
System.out.println("libSDL: Starting downloader");
|
||||
Log.i("SDL", "libSDL: Starting downloader");
|
||||
if( Parent.downloader == null )
|
||||
Parent.downloader = new DataDownloader(Parent, Parent._tv);
|
||||
}
|
||||
@@ -251,7 +252,7 @@ public class MainActivity extends Activity
|
||||
//int tries = 30;
|
||||
while( isCurrentOrientationHorizontal() != Globals.HorizontalOrientation )
|
||||
{
|
||||
System.out.println("libSDL: Waiting for screen orientation to change - the device is probably in the lockscreen mode");
|
||||
Log.i("SDL", "libSDL: Waiting for screen orientation to change - the device is probably in the lockscreen mode");
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch( Exception e ) {}
|
||||
@@ -259,13 +260,13 @@ public class MainActivity extends Activity
|
||||
tries--;
|
||||
if( tries <= 0 )
|
||||
{
|
||||
System.out.println("libSDL: Giving up waiting for screen orientation change");
|
||||
Log.i("SDL", "libSDL: Giving up waiting for screen orientation change");
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if( _isPaused )
|
||||
{
|
||||
System.out.println("libSDL: Application paused, cancelling SDL initialization until it will be brought to foreground");
|
||||
Log.i("SDL", "libSDL: Application paused, cancelling SDL initialization until it will be brought to foreground");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -284,12 +285,9 @@ public class MainActivity extends Activity
|
||||
{
|
||||
if(sdlInited)
|
||||
return;
|
||||
System.out.println("libSDL: Initializing video and SDL application");
|
||||
Log.i("SDL", "libSDL: Initializing video and SDL application");
|
||||
|
||||
sdlInited = true;
|
||||
if(Globals.UseAccelerometerAsArrowKeys || Globals.AppUsesAccelerometer)
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
_videoLayout.removeView(_layout);
|
||||
if( _ad.getView() != null )
|
||||
_videoLayout.removeView(_ad.getView());
|
||||
@@ -363,7 +361,7 @@ public class MainActivity extends Activity
|
||||
@Override
|
||||
public void onWindowFocusChanged (boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
System.out.println("libSDL: onWindowFocusChanged: " + hasFocus + " - sending onPause/onResume");
|
||||
Log.i("SDL", "libSDL: onWindowFocusChanged: " + hasFocus + " - sending onPause/onResume");
|
||||
if (hasFocus == false)
|
||||
onPause();
|
||||
else
|
||||
@@ -396,6 +394,9 @@ public class MainActivity extends Activity
|
||||
if( mGLView != null )
|
||||
mGLView.exitApp();
|
||||
super.onDestroy();
|
||||
try{
|
||||
Thread.sleep(2000); // The event is sent asynchronously, allow app to save it's state, and call exit() itself.
|
||||
} catch (InterruptedException e) {}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@@ -454,7 +455,7 @@ public class MainActivity extends Activity
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//System.out.println("Key " + keyCode + " flags " + event.getFlags() + " action " + event.getAction());
|
||||
//Log.i("SDL", "Key " + keyCode + " flags " + event.getFlags() + " action " + event.getAction());
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -514,7 +515,7 @@ public class MainActivity extends Activity
|
||||
public void setScreenKeyboardHintMessage(String s)
|
||||
{
|
||||
_screenKeyboardHintMessage = s;
|
||||
//System.out.println("setScreenKeyboardHintMessage: " + (_screenKeyboardHintMessage != null ? _screenKeyboardHintMessage : getString(R.string.text_edit_click_here)));
|
||||
//Log.i("SDL", "setScreenKeyboardHintMessage: " + (_screenKeyboardHintMessage != null ? _screenKeyboardHintMessage : getString(R.string.text_edit_click_here)));
|
||||
runOnUiThread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
@@ -667,7 +668,7 @@ public class MainActivity extends Activity
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(final MotionEvent ev)
|
||||
{
|
||||
//System.out.println("dispatchTouchEvent: " + ev.getAction() + " coords " + ev.getX() + ":" + ev.getY() );
|
||||
//Log.i("SDL", "dispatchTouchEvent: " + ev.getAction() + " coords " + ev.getX() + ":" + ev.getY() );
|
||||
if(_screenKeyboard != null)
|
||||
_screenKeyboard.dispatchTouchEvent(ev);
|
||||
else
|
||||
@@ -694,7 +695,7 @@ public class MainActivity extends Activity
|
||||
@Override
|
||||
public boolean dispatchGenericMotionEvent (MotionEvent ev)
|
||||
{
|
||||
//System.out.println("dispatchGenericMotionEvent: " + ev.getAction() + " coords " + ev.getX() + ":" + ev.getY() );
|
||||
//Log.i("SDL", "dispatchGenericMotionEvent: " + ev.getAction() + " coords " + ev.getX() + ":" + ev.getY() );
|
||||
// This code fails to run for Android 1.6, so there will be no generic motion event for Andorid screen keyboard
|
||||
/*
|
||||
if(_screenKeyboard != null)
|
||||
@@ -760,11 +761,11 @@ public class MainActivity extends Activity
|
||||
{
|
||||
if(Globals.NeedGles2)
|
||||
System.loadLibrary("GLESv2");
|
||||
System.out.println("libSDL: loaded GLESv2 lib");
|
||||
Log.i("SDL", "libSDL: loaded GLESv2 lib");
|
||||
}
|
||||
catch ( UnsatisfiedLinkError e )
|
||||
{
|
||||
System.out.println("libSDL: Cannot load GLESv2 lib");
|
||||
Log.i("SDL", "libSDL: Cannot load GLESv2 lib");
|
||||
}
|
||||
|
||||
// ----- VCMI hack -----
|
||||
@@ -772,7 +773,7 @@ public class MainActivity extends Activity
|
||||
for(String binaryZip: binaryZipNames)
|
||||
{
|
||||
try {
|
||||
System.out.println("libSDL: Trying to extract binaries from assets " + binaryZip);
|
||||
Log.i("SDL", "libSDL: Trying to extract binaries from assets " + binaryZip);
|
||||
|
||||
InputStream in = null;
|
||||
try
|
||||
@@ -813,11 +814,11 @@ public class MainActivity extends Activity
|
||||
entry = zip.getNextEntry();
|
||||
/*
|
||||
if( entry != null )
|
||||
System.out.println("Extracting lib " + entry.getName());
|
||||
Log.i("SDL", "Extracting lib " + entry.getName());
|
||||
*/
|
||||
if( entry == null )
|
||||
{
|
||||
System.out.println("Extracting binaries finished");
|
||||
Log.i("SDL", "Extracting binaries finished");
|
||||
break;
|
||||
}
|
||||
if( entry.isDirectory() )
|
||||
@@ -846,11 +847,11 @@ public class MainActivity extends Activity
|
||||
ff.delete();
|
||||
throw new Exception();
|
||||
}
|
||||
System.out.println("File '" + path + "' exists and passed CRC check - not overwriting it");
|
||||
Log.i("SDL", "File '" + path + "' exists and passed CRC check - not overwriting it");
|
||||
continue;
|
||||
} catch( Exception eeeeee ) { }
|
||||
|
||||
System.out.println("Saving to file '" + path + "'");
|
||||
Log.i("SDL", "Saving to file '" + path + "'");
|
||||
|
||||
out = new FileOutputStream( path );
|
||||
int len = zip.read(buf);
|
||||
@@ -868,7 +869,7 @@ public class MainActivity extends Activity
|
||||
}
|
||||
catch ( Exception eee )
|
||||
{
|
||||
//System.out.println("libSDL: Error: " + eee.toString());
|
||||
//Log.i("SDL", "libSDL: Error: " + eee.toString());
|
||||
}
|
||||
}
|
||||
// ----- VCMI hack -----
|
||||
@@ -882,22 +883,22 @@ public class MainActivity extends Activity
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(getFilesDir().getAbsolutePath() + "/../lib/" + libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getAbsolutePath());
|
||||
Log.i("SDL", "libSDL: loading lib " + libpath.getAbsolutePath());
|
||||
System.load(libpath.getPath());
|
||||
}
|
||||
catch( UnsatisfiedLinkError e )
|
||||
{
|
||||
System.out.println("libSDL: error loading lib " + l + ": " + e.toString());
|
||||
Log.i("SDL", "libSDL: error loading lib " + l + ": " + e.toString());
|
||||
try
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(getFilesDir().getAbsolutePath() + "/" + libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getAbsolutePath());
|
||||
Log.i("SDL", "libSDL: loading lib " + libpath.getAbsolutePath());
|
||||
System.load(libpath.getPath());
|
||||
}
|
||||
catch( UnsatisfiedLinkError ee )
|
||||
{
|
||||
System.out.println("libSDL: error loading lib " + l + ": " + ee.toString());
|
||||
Log.i("SDL", "libSDL: error loading lib " + l + ": " + ee.toString());
|
||||
System.loadLibrary(l);
|
||||
}
|
||||
}
|
||||
@@ -906,7 +907,7 @@ public class MainActivity extends Activity
|
||||
catch ( UnsatisfiedLinkError e )
|
||||
{
|
||||
try {
|
||||
System.out.println("libSDL: Extracting APP2SD-ed libs");
|
||||
Log.i("SDL", "libSDL: Extracting APP2SD-ed libs");
|
||||
|
||||
InputStream in = null;
|
||||
try
|
||||
@@ -939,11 +940,11 @@ public class MainActivity extends Activity
|
||||
entry = zip.getNextEntry();
|
||||
/*
|
||||
if( entry != null )
|
||||
System.out.println("Extracting lib " + entry.getName());
|
||||
Log.i("SDL", "Extracting lib " + entry.getName());
|
||||
*/
|
||||
if( entry == null )
|
||||
{
|
||||
System.out.println("Extracting libs finished");
|
||||
Log.i("SDL", "Extracting libs finished");
|
||||
break;
|
||||
}
|
||||
if( entry.isDirectory() )
|
||||
@@ -962,7 +963,7 @@ public class MainActivity extends Activity
|
||||
outDir.mkdirs();
|
||||
} catch( SecurityException eeeee ) { };
|
||||
|
||||
System.out.println("Saving to file '" + path + "'");
|
||||
Log.i("SDL", "Saving to file '" + path + "'");
|
||||
|
||||
out = new FileOutputStream( path );
|
||||
int len = zip.read(buf);
|
||||
@@ -981,14 +982,14 @@ public class MainActivity extends Activity
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(libDir, libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getPath());
|
||||
Log.i("SDL", "libSDL: loading lib " + libpath.getPath());
|
||||
System.load(libpath.getPath());
|
||||
libpath.delete();
|
||||
}
|
||||
}
|
||||
catch ( Exception ee )
|
||||
{
|
||||
System.out.println("libSDL: Error: " + ee.toString());
|
||||
Log.i("SDL", "libSDL: Error: " + ee.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,21 +1008,21 @@ public class MainActivity extends Activity
|
||||
}
|
||||
catch ( UnsatisfiedLinkError e )
|
||||
{
|
||||
System.out.println("libSDL: error loading lib: " + e.toString());
|
||||
Log.i("SDL", "libSDL: error loading lib: " + e.toString());
|
||||
try
|
||||
{
|
||||
for(String l : libs)
|
||||
{
|
||||
String libname = System.mapLibraryName(l);
|
||||
File libpath = new File(context.getFilesDir(), libname);
|
||||
System.out.println("libSDL: loading lib " + libpath.getPath());
|
||||
Log.i("SDL", "libSDL: loading lib " + libpath.getPath());
|
||||
System.load(libpath.getPath());
|
||||
libpath.delete();
|
||||
}
|
||||
}
|
||||
catch ( UnsatisfiedLinkError ee )
|
||||
{
|
||||
System.out.println("libSDL: error loading lib: " + ee.toString());
|
||||
Log.i("SDL", "libSDL: error loading lib: " + ee.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1032,7 +1033,7 @@ public class MainActivity extends Activity
|
||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
return packageInfo.versionCode;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
System.out.println("libSDL: Cannot get the version of our own package: " + e);
|
||||
Log.i("SDL", "libSDL: Cannot get the version of our own package: " + e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1061,8 +1062,19 @@ public class MainActivity extends Activity
|
||||
private EditText _screenKeyboard = null;
|
||||
private String _screenKeyboardHintMessage = null;
|
||||
private boolean sdlInited = false;
|
||||
public Settings.TouchEventsListener touchListener = null;
|
||||
public Settings.KeyEventsListener keyListener = null;
|
||||
|
||||
public interface TouchEventsListener
|
||||
{
|
||||
public void onTouchEvent(final MotionEvent ev);
|
||||
}
|
||||
|
||||
public interface KeyEventsListener
|
||||
{
|
||||
public void onKeyEvent(final int keyCode);
|
||||
}
|
||||
|
||||
public TouchEventsListener touchListener = null;
|
||||
public KeyEventsListener keyListener = null;
|
||||
boolean _isPaused = false;
|
||||
private InputMethodManager _inputManager = null;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
257
project/java/SettingsMenu.java
Normal file
257
project/java/SettingsMenu.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Java source code (C) 2009-2012 Sergii Pylypenko
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
package net.sourceforge.clonekeenplus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import android.util.Log;
|
||||
import java.io.*;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.Collections;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import java.lang.String;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap;
|
||||
import android.widget.TextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Button;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannedString;
|
||||
import android.content.Intent;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.AlarmManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.net.Uri;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.Arrays;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.Sensor;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
class SettingsMenu
|
||||
{
|
||||
public static abstract class Menu
|
||||
{
|
||||
// Should be overridden by children
|
||||
abstract void run(final MainActivity p);
|
||||
abstract String title(final MainActivity p);
|
||||
boolean enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// Should not be overridden
|
||||
boolean enabledOrHidden()
|
||||
{
|
||||
for( Menu m: Globals.HiddenMenuOptions )
|
||||
{
|
||||
if( m.getClass().getName().equals( this.getClass().getName() ) )
|
||||
return false;
|
||||
}
|
||||
return enabled();
|
||||
}
|
||||
void showMenuOptionsList(final MainActivity p, final Menu[] list)
|
||||
{
|
||||
menuStack.add(this);
|
||||
ArrayList<CharSequence> items = new ArrayList<CharSequence> ();
|
||||
for( Menu m: list )
|
||||
{
|
||||
if(m.enabledOrHidden())
|
||||
items.add(m.title(p));
|
||||
}
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(title(p));
|
||||
builder.setItems(items.toArray(new CharSequence[0]), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
int selected = 0;
|
||||
|
||||
for( Menu m: list )
|
||||
{
|
||||
if(m.enabledOrHidden())
|
||||
{
|
||||
if( selected == item )
|
||||
{
|
||||
m.run(p);
|
||||
return;
|
||||
}
|
||||
selected ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBackOuterMenu(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static ArrayList<Menu> menuStack = new ArrayList<Menu> ();
|
||||
|
||||
public static void showConfig(final MainActivity p, final boolean firstStart)
|
||||
{
|
||||
Settings.settingsChanged = true;
|
||||
if( Globals.OptionalDataDownload == null )
|
||||
{
|
||||
String downloads[] = Globals.DataDownloadUrl;
|
||||
Globals.OptionalDataDownload = new boolean[downloads.length];
|
||||
boolean oldFormat = true;
|
||||
for( int i = 0; i < downloads.length; i++ )
|
||||
{
|
||||
if( downloads[i].indexOf("!") == 0 )
|
||||
{
|
||||
Globals.OptionalDataDownload[i] = true;
|
||||
oldFormat = false;
|
||||
}
|
||||
}
|
||||
if( oldFormat )
|
||||
Globals.OptionalDataDownload[0] = true;
|
||||
}
|
||||
|
||||
if(!firstStart)
|
||||
new MainMenu().run(p);
|
||||
else
|
||||
{
|
||||
if( Globals.StartupMenuButtonTimeout > 0 ) // If we did not disable startup menu altogether
|
||||
{
|
||||
for( Menu m: Globals.FirstStartMenuOptions )
|
||||
{
|
||||
boolean hidden = false;
|
||||
for( Menu m1: Globals.HiddenMenuOptions )
|
||||
{
|
||||
if( m1.getClass().getName().equals( m.getClass().getName() ) )
|
||||
hidden = true;
|
||||
}
|
||||
if( ! hidden )
|
||||
menuStack.add(0, m);
|
||||
}
|
||||
}
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
static void goBack(final MainActivity p)
|
||||
{
|
||||
if(menuStack.isEmpty())
|
||||
{
|
||||
Settings.Save(p);
|
||||
p.startDownloader();
|
||||
}
|
||||
else
|
||||
{
|
||||
Menu c = menuStack.remove(menuStack.size() - 1);
|
||||
c.run(p);
|
||||
}
|
||||
}
|
||||
|
||||
static void goBackOuterMenu(final MainActivity p)
|
||||
{
|
||||
if(!menuStack.isEmpty())
|
||||
menuStack.remove(menuStack.size() - 1);
|
||||
goBack(p);
|
||||
}
|
||||
|
||||
static class OkButton extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.ok);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
goBackOuterMenu(p);
|
||||
}
|
||||
}
|
||||
|
||||
static class DummyMenu extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.ok);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
static class MainMenu extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.device_config);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
Menu options[] =
|
||||
{
|
||||
new SettingsMenuMisc.DownloadConfig(),
|
||||
new SettingsMenuMisc.OptionalDownloadConfig(false),
|
||||
new SettingsMenuKeyboard.KeyboardConfigMainMenu(),
|
||||
new SettingsMenuMouse.MouseConfigMainMenu(),
|
||||
new SettingsMenuMisc.GyroscopeCalibration(),
|
||||
new SettingsMenuMisc.AudioConfig(),
|
||||
new SettingsMenuKeyboard.RemapHwKeysConfig(),
|
||||
new SettingsMenuKeyboard.ScreenGesturesConfig(),
|
||||
new SettingsMenuMisc.VideoSettingsConfig(),
|
||||
new SettingsMenuMisc.ResetToDefaultsConfig(),
|
||||
new OkButton(),
|
||||
};
|
||||
showMenuOptionsList(p, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
842
project/java/SettingsMenuKeyboard.java
Normal file
842
project/java/SettingsMenuKeyboard.java
Normal file
@@ -0,0 +1,842 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Java source code (C) 2009-2012 Sergii Pylypenko
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
package net.sourceforge.clonekeenplus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import android.util.Log;
|
||||
import java.io.*;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.Collections;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import java.lang.String;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap;
|
||||
import android.widget.TextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Button;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannedString;
|
||||
import android.content.Intent;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.AlarmManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.net.Uri;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.Arrays;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.Sensor;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
class SettingsMenuKeyboard extends SettingsMenu
|
||||
{
|
||||
static class KeyboardConfigMainMenu extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.controls_screenkb);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.UseTouchscreenKeyboard;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
Menu options[] =
|
||||
{
|
||||
new ScreenKeyboardThemeConfig(),
|
||||
new ScreenKeyboardSizeConfig(),
|
||||
new ScreenKeyboardDrawSizeConfig(),
|
||||
new ScreenKeyboardTransparencyConfig(),
|
||||
new RemapScreenKbConfig(),
|
||||
new CustomizeScreenKbLayout(),
|
||||
new OkButton(),
|
||||
};
|
||||
showMenuOptionsList(p, options);
|
||||
}
|
||||
}
|
||||
|
||||
static class ScreenKeyboardSizeConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.controls_screenkb_size);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_large),
|
||||
p.getResources().getString(R.string.controls_screenkb_medium),
|
||||
p.getResources().getString(R.string.controls_screenkb_small),
|
||||
p.getResources().getString(R.string.controls_screenkb_tiny),
|
||||
p.getResources().getString(R.string.controls_screenkb_custom) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_size));
|
||||
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardSize, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.TouchscreenKeyboardSize = item;
|
||||
dialog.dismiss();
|
||||
if( Globals.TouchscreenKeyboardSize == Globals.TOUCHSCREEN_KEYBOARD_CUSTOM )
|
||||
new CustomizeScreenKbLayout().run(p);
|
||||
else
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class ScreenKeyboardDrawSizeConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.controls_screenkb_drawsize);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_large),
|
||||
p.getResources().getString(R.string.controls_screenkb_medium),
|
||||
p.getResources().getString(R.string.controls_screenkb_small),
|
||||
p.getResources().getString(R.string.controls_screenkb_tiny) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_drawsize));
|
||||
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardDrawSize, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.TouchscreenKeyboardDrawSize = item;
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class ScreenKeyboardThemeConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.controls_screenkb_theme);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = {
|
||||
p.getResources().getString(R.string.controls_screenkb_by, "Ultimate Droid", "Sean Stieber"),
|
||||
p.getResources().getString(R.string.controls_screenkb_by, "Simple Theme", "Beholder"),
|
||||
p.getResources().getString(R.string.controls_screenkb_by, "Sun", "Sirea")
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_theme));
|
||||
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardTheme, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.TouchscreenKeyboardTheme = item;
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class ScreenKeyboardTransparencyConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.controls_screenkb_transparency);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.controls_screenkb_trans_0),
|
||||
p.getResources().getString(R.string.controls_screenkb_trans_1),
|
||||
p.getResources().getString(R.string.controls_screenkb_trans_2),
|
||||
p.getResources().getString(R.string.controls_screenkb_trans_3),
|
||||
p.getResources().getString(R.string.controls_screenkb_trans_4) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.controls_screenkb_transparency));
|
||||
builder.setSingleChoiceItems(items, Globals.TouchscreenKeyboardTransparency, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.TouchscreenKeyboardTransparency = item;
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class RemapHwKeysConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.remap_hwkeys);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
p.setText(p.getResources().getString(R.string.remap_hwkeys_press));
|
||||
p.keyListener = new KeyRemapTool(p);
|
||||
}
|
||||
|
||||
public static class KeyRemapTool implements MainActivity.KeyEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
public KeyRemapTool(MainActivity _p)
|
||||
{
|
||||
p = _p;
|
||||
}
|
||||
|
||||
public void onKeyEvent(final int keyCode)
|
||||
{
|
||||
p.keyListener = null;
|
||||
int keyIndex = keyCode;
|
||||
if( keyIndex < 0 )
|
||||
keyIndex = 0;
|
||||
if( keyIndex > SDL_Keys.JAVA_KEYCODE_LAST )
|
||||
keyIndex = 0;
|
||||
|
||||
final int KeyIndexFinal = keyIndex;
|
||||
CharSequence[] items = {
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[0]],
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[1]],
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[2]],
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[3]],
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[4]],
|
||||
SDL_Keys.names[Globals.RemapScreenKbKeycode[5]],
|
||||
p.getResources().getString(R.string.remap_hwkeys_select_more_keys),
|
||||
};
|
||||
|
||||
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
|
||||
items[i] = Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.remap_hwkeys_select_simple);
|
||||
builder.setItems(items, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
if( item >= 6 )
|
||||
ShowAllKeys(KeyIndexFinal);
|
||||
else
|
||||
{
|
||||
Globals.RemapHwKeycode[KeyIndexFinal] = Globals.RemapScreenKbKeycode[item];
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
public void ShowAllKeys(final int KeyIndex)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.remap_hwkeys_select);
|
||||
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapHwKeycode[KeyIndex]], new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RemapHwKeycode[KeyIndex] = SDL_Keys.namesSortedIdx[item];
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class RemapScreenKbConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.remap_screenkb);
|
||||
}
|
||||
//boolean enabled() { return true; };
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.remap_screenkb_joystick),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_text),
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 1",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 2",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 3",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 4",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 5",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 6",
|
||||
};
|
||||
|
||||
boolean defaults[] = Arrays.copyOf(Globals.ScreenKbControlsShown, Globals.ScreenKbControlsShown.length);
|
||||
if( Globals.AppUsesSecondJoystick )
|
||||
{
|
||||
items = Arrays.copyOf(items, items.length + 1);
|
||||
items[items.length - 1] = p.getResources().getString(R.string.remap_screenkb_joystick) + " 2";
|
||||
defaults = Arrays.copyOf(defaults, defaults.length + 1);
|
||||
defaults[defaults.length - 1] = true;
|
||||
}
|
||||
|
||||
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
|
||||
items[i+2] = items[i+2] + " - " + Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.remap_screenkb));
|
||||
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked)
|
||||
{
|
||||
Globals.ScreenKbControlsShown[item] = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
showRemapScreenKbConfig2(p, 0);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showRemapScreenKbConfig2(final MainActivity p, final int currentButton)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 1",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 2",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 3",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 4",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 5",
|
||||
p.getResources().getString(R.string.remap_screenkb_button) + " 6",
|
||||
};
|
||||
|
||||
for( int i = 0; i < Math.min(6, Globals.AppTouchscreenKeyboardKeysNames.length); i++ )
|
||||
items[i] = items[i] + " - " + Globals.AppTouchscreenKeyboardKeysNames[i].replace("_", " ");
|
||||
|
||||
if( currentButton >= Globals.RemapScreenKbKeycode.length )
|
||||
{
|
||||
goBack(p);
|
||||
return;
|
||||
}
|
||||
if( ! Globals.ScreenKbControlsShown[currentButton + 2] )
|
||||
{
|
||||
showRemapScreenKbConfig2(p, currentButton + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(items[currentButton]);
|
||||
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapScreenKbKeycode[currentButton]], new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RemapScreenKbKeycode[currentButton] = SDL_Keys.namesSortedIdx[item];
|
||||
|
||||
dialog.dismiss();
|
||||
showRemapScreenKbConfig2(p, currentButton + 1);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class ScreenGesturesConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.remap_screenkb_button_gestures);
|
||||
}
|
||||
//boolean enabled() { return true; };
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.remap_screenkb_button_zoomin),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_zoomout),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_rotateleft),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_rotateright),
|
||||
};
|
||||
|
||||
boolean defaults[] = {
|
||||
Globals.MultitouchGesturesUsed[0],
|
||||
Globals.MultitouchGesturesUsed[1],
|
||||
Globals.MultitouchGesturesUsed[2],
|
||||
Globals.MultitouchGesturesUsed[3],
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.remap_screenkb_button_gestures));
|
||||
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked)
|
||||
{
|
||||
Globals.MultitouchGesturesUsed[item] = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
showScreenGesturesConfig2(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showScreenGesturesConfig2(final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = {
|
||||
p.getResources().getString(R.string.accel_slow),
|
||||
p.getResources().getString(R.string.accel_medium),
|
||||
p.getResources().getString(R.string.accel_fast),
|
||||
p.getResources().getString(R.string.accel_veryfast)
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.remap_screenkb_button_gestures_sensitivity);
|
||||
builder.setSingleChoiceItems(items, Globals.MultitouchGestureSensitivity, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.MultitouchGestureSensitivity = item;
|
||||
|
||||
dialog.dismiss();
|
||||
showScreenGesturesConfig3(p, 0);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showScreenGesturesConfig3(final MainActivity p, final int currentButton)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.remap_screenkb_button_zoomin),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_zoomout),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_rotateleft),
|
||||
p.getResources().getString(R.string.remap_screenkb_button_rotateright),
|
||||
};
|
||||
|
||||
if( currentButton >= Globals.RemapMultitouchGestureKeycode.length )
|
||||
{
|
||||
goBack(p);
|
||||
return;
|
||||
}
|
||||
if( ! Globals.MultitouchGesturesUsed[currentButton] )
|
||||
{
|
||||
showScreenGesturesConfig3(p, currentButton + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(items[currentButton]);
|
||||
builder.setSingleChoiceItems(SDL_Keys.namesSorted, SDL_Keys.namesSortedBackIdx[Globals.RemapMultitouchGestureKeycode[currentButton]], new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RemapMultitouchGestureKeycode[currentButton] = SDL_Keys.namesSortedIdx[item];
|
||||
|
||||
dialog.dismiss();
|
||||
showScreenGesturesConfig3(p, currentButton + 1);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomizeScreenKbLayout extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.screenkb_custom_layout);
|
||||
}
|
||||
//boolean enabled() { return true; };
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
p.setText(p.getResources().getString(R.string.screenkb_custom_layout_help));
|
||||
CustomizeScreenKbLayoutTool tool = new CustomizeScreenKbLayoutTool(p);
|
||||
p.touchListener = tool;
|
||||
p.keyListener = tool;
|
||||
Globals.TouchscreenKeyboardSize = Globals.TOUCHSCREEN_KEYBOARD_CUSTOM;
|
||||
}
|
||||
|
||||
static class CustomizeScreenKbLayoutTool implements MainActivity.TouchEventsListener, MainActivity.KeyEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
FrameLayout layout = null;
|
||||
ImageView imgs[] = new ImageView[Globals.ScreenKbControlsLayout.length];
|
||||
Bitmap bmps[] = new Bitmap[Globals.ScreenKbControlsLayout.length];
|
||||
ImageView boundary = null;
|
||||
Bitmap boundaryBmp = null;
|
||||
int currentButton = 0;
|
||||
int buttons[] = {
|
||||
R.drawable.dpad,
|
||||
R.drawable.keyboard,
|
||||
R.drawable.b1,
|
||||
R.drawable.b2,
|
||||
R.drawable.b3,
|
||||
R.drawable.b4,
|
||||
R.drawable.b5,
|
||||
R.drawable.b6,
|
||||
R.drawable.dpad
|
||||
};
|
||||
int oldX = 0, oldY = 0;
|
||||
boolean resizing = false;
|
||||
|
||||
public CustomizeScreenKbLayoutTool(MainActivity _p)
|
||||
{
|
||||
p = _p;
|
||||
layout = new FrameLayout(p);
|
||||
p.getVideoLayout().addView(layout);
|
||||
boundary = new ImageView(p);
|
||||
boundary.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
boundary.setScaleType(ImageView.ScaleType.MATRIX);
|
||||
boundaryBmp = BitmapFactory.decodeResource( p.getResources(), R.drawable.rectangle );
|
||||
boundary.setImageBitmap(boundaryBmp);
|
||||
layout.addView(boundary);
|
||||
currentButton = -1;
|
||||
if( Globals.TouchscreenKeyboardTheme == 2 )
|
||||
{
|
||||
buttons = new int[] {
|
||||
R.drawable.sun_dpad,
|
||||
R.drawable.sun_keyboard,
|
||||
R.drawable.sun_b1,
|
||||
R.drawable.sun_b2,
|
||||
R.drawable.sun_b3,
|
||||
R.drawable.sun_b4,
|
||||
R.drawable.sun_b5,
|
||||
R.drawable.sun_b6,
|
||||
R.drawable.sun_dpad
|
||||
};
|
||||
}
|
||||
|
||||
int displayX = 800;
|
||||
int displayY = 480;
|
||||
try {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
p.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
displayX = dm.widthPixels;
|
||||
displayY = dm.heightPixels;
|
||||
} catch (Exception eeeee) {}
|
||||
|
||||
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
|
||||
{
|
||||
if( ! Globals.ScreenKbControlsShown[i] )
|
||||
continue;
|
||||
if( currentButton == -1 )
|
||||
currentButton = i;
|
||||
//Log.i("SDL", "Screen kb button " + i + " coords " + Globals.ScreenKbControlsLayout[i][0] + ":" + Globals.ScreenKbControlsLayout[i][1] + ":" + Globals.ScreenKbControlsLayout[i][2] + ":" + Globals.ScreenKbControlsLayout[i][3] );
|
||||
// Check if the button is off screen edge or shrunk to zero
|
||||
if( Globals.ScreenKbControlsLayout[i][0] > Globals.ScreenKbControlsLayout[i][2] - displayY/12 )
|
||||
Globals.ScreenKbControlsLayout[i][0] = Globals.ScreenKbControlsLayout[i][2] - displayY/12;
|
||||
if( Globals.ScreenKbControlsLayout[i][1] > Globals.ScreenKbControlsLayout[i][3] - displayY/12 )
|
||||
Globals.ScreenKbControlsLayout[i][1] = Globals.ScreenKbControlsLayout[i][3] - displayY/12;
|
||||
if( Globals.ScreenKbControlsLayout[i][0] < Globals.ScreenKbControlsLayout[i][2] - displayY*2/3 )
|
||||
Globals.ScreenKbControlsLayout[i][0] = Globals.ScreenKbControlsLayout[i][2] - displayY*2/3;
|
||||
if( Globals.ScreenKbControlsLayout[i][1] < Globals.ScreenKbControlsLayout[i][3] - displayY*2/3 )
|
||||
Globals.ScreenKbControlsLayout[i][1] = Globals.ScreenKbControlsLayout[i][3] - displayY*2/3;
|
||||
if( Globals.ScreenKbControlsLayout[i][0] < 0 )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[i][2] += -Globals.ScreenKbControlsLayout[i][0];
|
||||
Globals.ScreenKbControlsLayout[i][0] = 0;
|
||||
}
|
||||
if( Globals.ScreenKbControlsLayout[i][2] > displayX )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[i][0] -= Globals.ScreenKbControlsLayout[i][2] - displayX;
|
||||
Globals.ScreenKbControlsLayout[i][2] = displayX;
|
||||
}
|
||||
if( Globals.ScreenKbControlsLayout[i][1] < 0 )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[i][3] += -Globals.ScreenKbControlsLayout[i][1];
|
||||
Globals.ScreenKbControlsLayout[i][1] = 0;
|
||||
}
|
||||
if( Globals.ScreenKbControlsLayout[i][3] > displayY )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[i][1] -= Globals.ScreenKbControlsLayout[i][3] - displayY;
|
||||
Globals.ScreenKbControlsLayout[i][3] = displayY;
|
||||
}
|
||||
//Log.i("SDL", "After bounds check coords " + Globals.ScreenKbControlsLayout[i][0] + ":" + Globals.ScreenKbControlsLayout[i][1] + ":" + Globals.ScreenKbControlsLayout[i][2] + ":" + Globals.ScreenKbControlsLayout[i][3] );
|
||||
|
||||
imgs[i] = new ImageView(p);
|
||||
imgs[i].setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
imgs[i].setScaleType(ImageView.ScaleType.MATRIX);
|
||||
bmps[i] = BitmapFactory.decodeResource( p.getResources(), buttons[i] );
|
||||
imgs[i].setImageBitmap(bmps[i]);
|
||||
imgs[i].setAlpha(128);
|
||||
layout.addView(imgs[i]);
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmps[i].getWidth(), bmps[i].getHeight());
|
||||
RectF dst = new RectF(Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][1],
|
||||
Globals.ScreenKbControlsLayout[i][2], Globals.ScreenKbControlsLayout[i][3]);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
imgs[i].setImageMatrix(m);
|
||||
}
|
||||
boundary.bringToFront();
|
||||
if( currentButton == -1 )
|
||||
onKeyEvent( KeyEvent.KEYCODE_BACK ); // All buttons disabled - do not show anything
|
||||
else
|
||||
setupButton(currentButton);
|
||||
}
|
||||
|
||||
void setupButton(int i)
|
||||
{
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmps[i].getWidth(), bmps[i].getHeight());
|
||||
RectF dst = new RectF(Globals.ScreenKbControlsLayout[i][0], Globals.ScreenKbControlsLayout[i][1],
|
||||
Globals.ScreenKbControlsLayout[i][2], Globals.ScreenKbControlsLayout[i][3]);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
imgs[i].setImageMatrix(m);
|
||||
m = new Matrix();
|
||||
src = new RectF(0, 0, boundaryBmp.getWidth(), boundaryBmp.getHeight());
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
boundary.setImageMatrix(m);
|
||||
String buttonText = "";
|
||||
if( i >= 2 && i <= 7 )
|
||||
buttonText = p.getResources().getString(R.string.remap_screenkb_button) + (i - 2);
|
||||
if( i >= 2 && i - 2 < Globals.AppTouchscreenKeyboardKeysNames.length )
|
||||
buttonText = Globals.AppTouchscreenKeyboardKeysNames[i - 2].replace("_", " ");
|
||||
if( i == 0 )
|
||||
buttonText = "Joystick";
|
||||
if( i == 1 )
|
||||
buttonText = "Text input";
|
||||
if( i == 8 )
|
||||
buttonText = "Joystick 2";
|
||||
p.setText(p.getResources().getString(R.string.screenkb_custom_layout_help) + "\n" + buttonText);
|
||||
}
|
||||
|
||||
public void onTouchEvent(final MotionEvent ev)
|
||||
{
|
||||
if( ev.getAction() == MotionEvent.ACTION_DOWN )
|
||||
{
|
||||
oldX = (int)ev.getX();
|
||||
oldY = (int)ev.getY();
|
||||
resizing = true;
|
||||
for( int i = 0; i < Globals.ScreenKbControlsLayout.length; i++ )
|
||||
{
|
||||
if( ! Globals.ScreenKbControlsShown[i] )
|
||||
continue;
|
||||
if( Globals.ScreenKbControlsLayout[i][0] <= oldX &&
|
||||
Globals.ScreenKbControlsLayout[i][2] >= oldX &&
|
||||
Globals.ScreenKbControlsLayout[i][1] <= oldY &&
|
||||
Globals.ScreenKbControlsLayout[i][3] >= oldY )
|
||||
{
|
||||
currentButton = i;
|
||||
setupButton(currentButton);
|
||||
resizing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ev.getAction() == MotionEvent.ACTION_MOVE )
|
||||
{
|
||||
int dx = (int)ev.getX() - oldX;
|
||||
int dy = (int)ev.getY() - oldY;
|
||||
if( resizing )
|
||||
{
|
||||
// Resize slowly, with 1/3 of movement speed
|
||||
dx /= 6;
|
||||
dy /= 6;
|
||||
if( Globals.ScreenKbControlsLayout[currentButton][0] <= Globals.ScreenKbControlsLayout[currentButton][2] + dx*2 )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[currentButton][0] -= dx;
|
||||
Globals.ScreenKbControlsLayout[currentButton][2] += dx;
|
||||
}
|
||||
if( Globals.ScreenKbControlsLayout[currentButton][1] <= Globals.ScreenKbControlsLayout[currentButton][3] + dy*2 )
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[currentButton][1] += dy;
|
||||
Globals.ScreenKbControlsLayout[currentButton][3] -= dy;
|
||||
}
|
||||
dx *= 6;
|
||||
dy *= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
Globals.ScreenKbControlsLayout[currentButton][0] += dx;
|
||||
Globals.ScreenKbControlsLayout[currentButton][2] += dx;
|
||||
Globals.ScreenKbControlsLayout[currentButton][1] += dy;
|
||||
Globals.ScreenKbControlsLayout[currentButton][3] += dy;
|
||||
}
|
||||
oldX += dx;
|
||||
oldY += dy;
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmps[currentButton].getWidth(), bmps[currentButton].getHeight());
|
||||
RectF dst = new RectF(Globals.ScreenKbControlsLayout[currentButton][0], Globals.ScreenKbControlsLayout[currentButton][1],
|
||||
Globals.ScreenKbControlsLayout[currentButton][2], Globals.ScreenKbControlsLayout[currentButton][3]);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
imgs[currentButton].setImageMatrix(m);
|
||||
m = new Matrix();
|
||||
src = new RectF(0, 0, boundaryBmp.getWidth(), boundaryBmp.getHeight());
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
boundary.setImageMatrix(m);
|
||||
}
|
||||
}
|
||||
|
||||
public void onKeyEvent(final int keyCode)
|
||||
{
|
||||
if( keyCode == KeyEvent.KEYCODE_BACK )
|
||||
{
|
||||
p.getVideoLayout().removeView(layout);
|
||||
layout = null;
|
||||
p.touchListener = null;
|
||||
p.keyListener = null;
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
701
project/java/SettingsMenuMisc.java
Normal file
701
project/java/SettingsMenuMisc.java
Normal file
@@ -0,0 +1,701 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Java source code (C) 2009-2012 Sergii Pylypenko
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
package net.sourceforge.clonekeenplus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import android.util.Log;
|
||||
import java.io.*;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.Collections;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import java.lang.String;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap;
|
||||
import android.widget.TextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Button;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannedString;
|
||||
import android.content.Intent;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.AlarmManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.net.Uri;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.Arrays;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.Sensor;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
class SettingsMenuMisc extends SettingsMenu
|
||||
{
|
||||
static class DownloadConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.storage_question);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
long freeSdcard = 0;
|
||||
long freePhone = 0;
|
||||
try
|
||||
{
|
||||
StatFs sdcard = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||||
StatFs phone = new StatFs(Environment.getDataDirectory().getPath());
|
||||
freeSdcard = (long)sdcard.getAvailableBlocks() * sdcard.getBlockSize() / 1024 / 1024;
|
||||
freePhone = (long)phone.getAvailableBlocks() * phone.getBlockSize() / 1024 / 1024;
|
||||
}
|
||||
catch(Exception e) {}
|
||||
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.storage_phone, freePhone),
|
||||
p.getResources().getString(R.string.storage_sd, freeSdcard),
|
||||
p.getResources().getString(R.string.storage_custom) };
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.storage_question));
|
||||
builder.setSingleChoiceItems(items, Globals.DownloadToSdcard ? 1 : 0, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
|
||||
if( item == 2 )
|
||||
showCustomDownloadDirConfig(p);
|
||||
else
|
||||
{
|
||||
Globals.DownloadToSdcard = (item != 0);
|
||||
Globals.DataDir = Globals.DownloadToSdcard ?
|
||||
Settings.SdcardAppPath.getPath(p) :
|
||||
p.getFilesDir().getAbsolutePath();
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
static void showCustomDownloadDirConfig(final MainActivity p)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.storage_custom));
|
||||
|
||||
final EditText edit = new EditText(p);
|
||||
edit.setFocusableInTouchMode(true);
|
||||
edit.setFocusable(true);
|
||||
edit.setText(Globals.DataDir);
|
||||
builder.setView(edit);
|
||||
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.DataDir = edit.getText().toString();
|
||||
dialog.dismiss();
|
||||
showCommandLineConfig(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
static void showCommandLineConfig(final MainActivity p)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.storage_commandline));
|
||||
|
||||
final EditText edit = new EditText(p);
|
||||
edit.setFocusableInTouchMode(true);
|
||||
edit.setFocusable(true);
|
||||
edit.setText(Globals.CommandLine);
|
||||
builder.setView(edit);
|
||||
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.CommandLine = edit.getText().toString();
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class OptionalDownloadConfig extends Menu
|
||||
{
|
||||
boolean firstStart = false;
|
||||
OptionalDownloadConfig()
|
||||
{
|
||||
firstStart = true;
|
||||
}
|
||||
OptionalDownloadConfig(boolean firstStart)
|
||||
{
|
||||
this.firstStart = firstStart;
|
||||
}
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.downloads);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
String [] downloadFiles = Globals.DataDownloadUrl;
|
||||
final boolean [] mandatory = new boolean[downloadFiles.length];
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.downloads));
|
||||
|
||||
CharSequence[] items = new CharSequence[downloadFiles.length];
|
||||
for(int i = 0; i < downloadFiles.length; i++ )
|
||||
{
|
||||
items[i] = new String(downloadFiles[i].split("[|]")[0]);
|
||||
if( items[i].toString().indexOf("!") == 0 )
|
||||
items[i] = items[i].toString().substring(1);
|
||||
if( items[i].toString().indexOf("!") == 0 )
|
||||
{
|
||||
items[i] = items[i].toString().substring(1);
|
||||
mandatory[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( Globals.OptionalDataDownload == null || Globals.OptionalDataDownload.length != items.length )
|
||||
{
|
||||
Globals.OptionalDataDownload = new boolean[downloadFiles.length];
|
||||
boolean oldFormat = true;
|
||||
for( int i = 0; i < downloadFiles.length; i++ )
|
||||
{
|
||||
if( downloadFiles[i].indexOf("!") == 0 )
|
||||
{
|
||||
Globals.OptionalDataDownload[i] = true;
|
||||
oldFormat = false;
|
||||
}
|
||||
}
|
||||
if( oldFormat )
|
||||
{
|
||||
Globals.OptionalDataDownload[0] = true;
|
||||
mandatory[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
builder.setMultiChoiceItems(items, Globals.OptionalDataDownload, new DialogInterface.OnMultiChoiceClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked)
|
||||
{
|
||||
Globals.OptionalDataDownload[item] = isChecked;
|
||||
if( mandatory[item] && !isChecked )
|
||||
{
|
||||
Globals.OptionalDataDownload[item] = true;
|
||||
((AlertDialog)dialog).getListView().setItemChecked(item, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
if( firstStart )
|
||||
{
|
||||
builder.setNegativeButton(p.getResources().getString(R.string.show_more_options), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
menuStack.clear();
|
||||
new MainMenu().run(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class AudioConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.audiobuf_question);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.audiobuf_verysmall),
|
||||
p.getResources().getString(R.string.audiobuf_small),
|
||||
p.getResources().getString(R.string.audiobuf_medium),
|
||||
p.getResources().getString(R.string.audiobuf_large) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.audiobuf_question);
|
||||
builder.setSingleChoiceItems(items, Globals.AudioBufferConfig, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.AudioBufferConfig = item;
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class VideoSettingsConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.video);
|
||||
}
|
||||
//boolean enabled() { return true; };
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.pointandclick_keepaspectratio),
|
||||
p.getResources().getString(R.string.video_smooth)
|
||||
};
|
||||
boolean defaults[] = {
|
||||
Globals.KeepAspectRatio,
|
||||
Globals.VideoLinearFilter
|
||||
};
|
||||
|
||||
if(Globals.SwVideoMode && !Globals.CompatibilityHacksVideo)
|
||||
{
|
||||
CharSequence[] items2 = {
|
||||
p.getResources().getString(R.string.pointandclick_keepaspectratio),
|
||||
p.getResources().getString(R.string.video_smooth),
|
||||
p.getResources().getString(R.string.video_separatethread),
|
||||
};
|
||||
boolean defaults2[] = {
|
||||
Globals.KeepAspectRatio,
|
||||
Globals.VideoLinearFilter,
|
||||
Globals.MultiThreadedVideo
|
||||
};
|
||||
items = items2;
|
||||
defaults = defaults2;
|
||||
}
|
||||
|
||||
if(Globals.Using_SDL_1_3)
|
||||
{
|
||||
CharSequence[] items2 = {
|
||||
p.getResources().getString(R.string.pointandclick_keepaspectratio),
|
||||
};
|
||||
boolean defaults2[] = {
|
||||
Globals.KeepAspectRatio,
|
||||
};
|
||||
items = items2;
|
||||
defaults = defaults2;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.video));
|
||||
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked)
|
||||
{
|
||||
if( item == 0 )
|
||||
Globals.KeepAspectRatio = isChecked;
|
||||
if( item == 1 )
|
||||
Globals.VideoLinearFilter = isChecked;
|
||||
if( item == 2 )
|
||||
Globals.MultiThreadedVideo = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class ShowReadme extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return "Readme";
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
String readmes[] = Globals.ReadmeText.split("\\^");
|
||||
String lang = new String(Locale.getDefault().getLanguage()) + ":";
|
||||
String readme = readmes[0];
|
||||
String buttonName = "", buttonUrl = "";
|
||||
for( String r: readmes )
|
||||
{
|
||||
if( r.startsWith(lang) )
|
||||
readme = r.substring(lang.length());
|
||||
if( r.startsWith("button:") )
|
||||
{
|
||||
buttonName = r.substring("button:".length());
|
||||
if( buttonName.indexOf(":") != -1 )
|
||||
{
|
||||
buttonUrl = buttonName.substring(buttonName.indexOf(":") + 1);
|
||||
buttonName = buttonName.substring(0, buttonName.indexOf(":"));
|
||||
}
|
||||
}
|
||||
}
|
||||
readme = readme.trim();
|
||||
if( readme.length() <= 2 )
|
||||
{
|
||||
goBack(p);
|
||||
return;
|
||||
}
|
||||
TextView text = new TextView(p);
|
||||
text.setMaxLines(1000);
|
||||
text.setText(readme);
|
||||
text.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
ScrollView scroll = new ScrollView(p);
|
||||
scroll.addView(text);
|
||||
Button ok = new Button(p);
|
||||
final AlertDialog alertDismiss[] = new AlertDialog[1];
|
||||
ok.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
public void onClick(View v)
|
||||
{
|
||||
alertDismiss[0].cancel();
|
||||
}
|
||||
});
|
||||
ok.setText(R.string.ok);
|
||||
LinearLayout layout = new LinearLayout(p);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.addView(scroll);
|
||||
layout.addView(ok);
|
||||
if( buttonName.length() > 0 )
|
||||
{
|
||||
Button cancel = new Button(p);
|
||||
cancel.setText(buttonName);
|
||||
final String url = buttonUrl;
|
||||
cancel.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
public void onClick(View v)
|
||||
{
|
||||
if( url.length() > 0 )
|
||||
{
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(url));
|
||||
p.startActivity(i);
|
||||
}
|
||||
alertDismiss[0].cancel();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
layout.addView(cancel);
|
||||
}
|
||||
builder.setView(layout);
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alertDismiss[0] = alert;
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class GyroscopeCalibration extends Menu implements SensorEventListener
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.calibrate_gyroscope);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.AppUsesGyroscope;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
if( !Globals.AppUsesGyroscope || !AccelerometerReader.gyro.available(p) )
|
||||
{
|
||||
if( Globals.AppUsesGyroscope )
|
||||
{
|
||||
Toast toast = Toast.makeText(p, p.getResources().getString(R.string.calibrate_gyroscope_not_supported), Toast.LENGTH_LONG);
|
||||
toast.show();
|
||||
}
|
||||
goBack(p);
|
||||
return;
|
||||
}
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.calibrate_gyroscope));
|
||||
builder.setMessage(p.getResources().getString(R.string.calibrate_gyroscope_text));
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
startCalibration(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
ImageView img;
|
||||
Bitmap bmp;
|
||||
int numEvents;
|
||||
MainActivity p;
|
||||
|
||||
void startCalibration(final MainActivity _p)
|
||||
{
|
||||
p = _p;
|
||||
img = new ImageView(p);
|
||||
img.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
img.setScaleType(ImageView.ScaleType.MATRIX);
|
||||
bmp = BitmapFactory.decodeResource( p.getResources(), R.drawable.calibrate );
|
||||
img.setImageBitmap(bmp);
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
|
||||
RectF dst = new RectF( p.getVideoLayout().getWidth()/2 - 50, p.getVideoLayout().getHeight()/2 - 50,
|
||||
p.getVideoLayout().getWidth()/2 + 50, p.getVideoLayout().getHeight()/2 + 50);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
img.setImageMatrix(m);
|
||||
p.getVideoLayout().addView(img);
|
||||
numEvents = 0;
|
||||
AccelerometerReader.gyro.x1 = 100;
|
||||
AccelerometerReader.gyro.x2 = -100;
|
||||
AccelerometerReader.gyro.xc = 0;
|
||||
AccelerometerReader.gyro.y1 = 100;
|
||||
AccelerometerReader.gyro.y2 = -100;
|
||||
AccelerometerReader.gyro.yc = 0;
|
||||
AccelerometerReader.gyro.z1 = 100;
|
||||
AccelerometerReader.gyro.z2 = -100;
|
||||
AccelerometerReader.gyro.zc = 0;
|
||||
AccelerometerReader.gyro.registerListener(p, this);
|
||||
(new Thread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
for(int count = 1; count < 10; count++)
|
||||
{
|
||||
p.setText("" + count + "0% ...");
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch( Exception e ) {}
|
||||
}
|
||||
finishCalibration(p);
|
||||
}
|
||||
}
|
||||
)).start();
|
||||
}
|
||||
|
||||
public void onSensorChanged(SensorEvent event)
|
||||
{
|
||||
gyroscopeEvent(event.values[0], event.values[1], event.values[2]);
|
||||
}
|
||||
public void onAccuracyChanged(Sensor s, int a)
|
||||
{
|
||||
}
|
||||
void gyroscopeEvent(float x, float y, float z)
|
||||
{
|
||||
numEvents++;
|
||||
AccelerometerReader.gyro.xc += x;
|
||||
AccelerometerReader.gyro.yc += y;
|
||||
AccelerometerReader.gyro.zc += z;
|
||||
AccelerometerReader.gyro.x1 = Math.min(AccelerometerReader.gyro.x1, x * 1.1f); // Small safety bound coefficient
|
||||
AccelerometerReader.gyro.x2 = Math.max(AccelerometerReader.gyro.x2, x * 1.1f);
|
||||
AccelerometerReader.gyro.y1 = Math.min(AccelerometerReader.gyro.y1, y * 1.1f);
|
||||
AccelerometerReader.gyro.y2 = Math.max(AccelerometerReader.gyro.y2, y * 1.1f);
|
||||
AccelerometerReader.gyro.z1 = Math.min(AccelerometerReader.gyro.z1, z * 1.1f);
|
||||
AccelerometerReader.gyro.z2 = Math.max(AccelerometerReader.gyro.z2, z * 1.1f);
|
||||
final Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
|
||||
RectF dst = new RectF( x * 5000 + p.getVideoLayout().getWidth()/2 - 50, y * 5000 + p.getVideoLayout().getHeight()/2 - 50,
|
||||
x * 5000 + p.getVideoLayout().getWidth()/2 + 50, y * 5000 + p.getVideoLayout().getHeight()/2 + 50);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
p.runOnUiThread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
img.setImageMatrix(m);
|
||||
}
|
||||
});
|
||||
}
|
||||
void finishCalibration(final MainActivity p)
|
||||
{
|
||||
AccelerometerReader.gyro.unregisterListener(p, this);
|
||||
try {
|
||||
Thread.sleep(200); // Just in case we have pending events
|
||||
} catch( Exception e ) {}
|
||||
if( numEvents > 5 )
|
||||
{
|
||||
AccelerometerReader.gyro.xc /= (float)numEvents;
|
||||
AccelerometerReader.gyro.yc /= (float)numEvents;
|
||||
AccelerometerReader.gyro.zc /= (float)numEvents;
|
||||
}
|
||||
p.runOnUiThread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
p.getVideoLayout().removeView(img);
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static class ResetToDefaultsConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.reset_config);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.reset_config_ask));
|
||||
builder.setMessage(p.getResources().getString(R.string.reset_config_ask));
|
||||
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Settings.DeleteSdlConfigOnUpgradeAndRestart(p); // Never returns
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(p.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
771
project/java/SettingsMenuMouse.java
Normal file
771
project/java/SettingsMenuMouse.java
Normal file
@@ -0,0 +1,771 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Java source code (C) 2009-2012 Sergii Pylypenko
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
package net.sourceforge.clonekeenplus;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import android.util.Log;
|
||||
import java.io.*;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.Collections;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import java.lang.String;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap;
|
||||
import android.widget.TextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.Button;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannedString;
|
||||
import android.content.Intent;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.AlarmManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.net.Uri;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.Arrays;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.Sensor;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
class SettingsMenuMouse extends SettingsMenu
|
||||
{
|
||||
static class MouseConfigMainMenu extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.mouse_emulation);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.AppUsesMouse;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
Menu options[] =
|
||||
{
|
||||
new DisplaySizeConfig(false),
|
||||
new LeftClickConfig(),
|
||||
new RightClickConfig(),
|
||||
new AdditionalMouseConfig(),
|
||||
new JoystickMouseConfig(),
|
||||
new TouchPressureMeasurementTool(),
|
||||
new CalibrateTouchscreenMenu(),
|
||||
new OkButton(),
|
||||
};
|
||||
showMenuOptionsList(p, options);
|
||||
}
|
||||
}
|
||||
|
||||
static class DisplaySizeConfig extends Menu
|
||||
{
|
||||
boolean firstStart = false;
|
||||
DisplaySizeConfig()
|
||||
{
|
||||
this.firstStart = true;
|
||||
}
|
||||
DisplaySizeConfig(boolean firstStart)
|
||||
{
|
||||
this.firstStart = firstStart;
|
||||
}
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.display_size_mouse);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.display_size_tiny_touchpad),
|
||||
p.getResources().getString(R.string.display_size_tiny),
|
||||
p.getResources().getString(R.string.display_size_small),
|
||||
p.getResources().getString(R.string.display_size_small_touchpad),
|
||||
p.getResources().getString(R.string.display_size_large),
|
||||
};
|
||||
int _size_tiny_touchpad = 0;
|
||||
int _size_tiny = 1;
|
||||
int _size_small = 2;
|
||||
int _size_small_touchpad = 3;
|
||||
int _size_large = 4;
|
||||
int _more_options = 5;
|
||||
|
||||
if( ! Globals.SwVideoMode )
|
||||
{
|
||||
CharSequence[] items2 = {
|
||||
p.getResources().getString(R.string.display_size_small_touchpad),
|
||||
p.getResources().getString(R.string.display_size_large),
|
||||
};
|
||||
items = items2;
|
||||
_size_small_touchpad = 0;
|
||||
_size_large = 1;
|
||||
_size_tiny_touchpad = _size_tiny = _size_small = 1000;
|
||||
|
||||
}
|
||||
if( firstStart )
|
||||
{
|
||||
CharSequence[] items2 = {
|
||||
p.getResources().getString(R.string.display_size_tiny_touchpad),
|
||||
p.getResources().getString(R.string.display_size_tiny),
|
||||
p.getResources().getString(R.string.display_size_small),
|
||||
p.getResources().getString(R.string.display_size_small_touchpad),
|
||||
p.getResources().getString(R.string.display_size_large),
|
||||
p.getResources().getString(R.string.show_more_options),
|
||||
};
|
||||
items = items2;
|
||||
if( ! Globals.SwVideoMode )
|
||||
{
|
||||
CharSequence[] items3 = {
|
||||
p.getResources().getString(R.string.display_size_small_touchpad),
|
||||
p.getResources().getString(R.string.display_size_large),
|
||||
p.getResources().getString(R.string.show_more_options),
|
||||
};
|
||||
items = items3;
|
||||
_more_options = 3;
|
||||
}
|
||||
}
|
||||
// Java is so damn worse than C++11
|
||||
final int size_tiny_touchpad = _size_tiny_touchpad;
|
||||
final int size_tiny = _size_tiny;
|
||||
final int size_small = _size_small;
|
||||
final int size_small_touchpad = _size_small_touchpad;
|
||||
final int size_large = _size_large;
|
||||
final int more_options = _more_options;
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.display_size);
|
||||
class ClickListener implements DialogInterface.OnClickListener
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
if( item == size_large )
|
||||
{
|
||||
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL;
|
||||
Globals.RelativeMouseMovement = false;
|
||||
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
|
||||
}
|
||||
if( item == size_small )
|
||||
{
|
||||
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR;
|
||||
Globals.RelativeMouseMovement = false;
|
||||
Globals.ShowScreenUnderFinger = Mouse.ZOOM_MAGNIFIER;
|
||||
}
|
||||
if( item == size_small_touchpad )
|
||||
{
|
||||
Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
|
||||
Globals.RelativeMouseMovement = true;
|
||||
Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE;
|
||||
}
|
||||
if( item == size_tiny )
|
||||
{
|
||||
Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR;
|
||||
Globals.RelativeMouseMovement = false;
|
||||
Globals.ShowScreenUnderFinger = Mouse.ZOOM_SCREEN_TRANSFORM;
|
||||
}
|
||||
if( item == size_tiny_touchpad )
|
||||
{
|
||||
Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT;
|
||||
Globals.RelativeMouseMovement = true;
|
||||
Globals.ShowScreenUnderFinger = Mouse.ZOOM_FULLSCREEN_MAGNIFIER;
|
||||
}
|
||||
if( item == more_options )
|
||||
{
|
||||
menuStack.clear();
|
||||
new MainMenu().run(p);
|
||||
return;
|
||||
}
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
builder.setItems(items, new ClickListener());
|
||||
/*
|
||||
else
|
||||
builder.setSingleChoiceItems(items,
|
||||
Globals.ShowScreenUnderFinger == Mouse.ZOOM_NONE ?
|
||||
( Globals.RelativeMouseMovement ? Globals.SwVideoMode ? 2 : 1 : 0 ) :
|
||||
( Globals.ShowScreenUnderFinger == Mouse.ZOOM_MAGNIFIER && Globals.SwVideoMode ) ? 1 :
|
||||
Globals.ShowScreenUnderFinger + 1,
|
||||
new ClickListener());
|
||||
*/
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class LeftClickConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.leftclick_question);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_normal),
|
||||
p.getResources().getString(R.string.leftclick_near_cursor),
|
||||
p.getResources().getString(R.string.leftclick_multitouch),
|
||||
p.getResources().getString(R.string.leftclick_pressure),
|
||||
p.getResources().getString(R.string.rightclick_key),
|
||||
p.getResources().getString(R.string.leftclick_timeout),
|
||||
p.getResources().getString(R.string.leftclick_tap),
|
||||
p.getResources().getString(R.string.leftclick_tap_or_timeout) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.leftclick_question);
|
||||
builder.setSingleChoiceItems(items, Globals.LeftClickMethod, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
Globals.LeftClickMethod = item;
|
||||
if( item == Mouse.LEFT_CLICK_WITH_KEY )
|
||||
p.keyListener = new KeyRemapToolMouseClick(p, true);
|
||||
else if( item == Mouse.LEFT_CLICK_WITH_TIMEOUT || item == Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT )
|
||||
showLeftClickTimeoutConfig(p);
|
||||
else
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
static void showLeftClickTimeoutConfig(final MainActivity p) {
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_timeout_time_0),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_1),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_2),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_3),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_4) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.leftclick_timeout_time);
|
||||
builder.setSingleChoiceItems(items, Globals.LeftClickTimeout, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.LeftClickTimeout = item;
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class RightClickConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.rightclick_question);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.AppNeedsTwoButtonMouse;
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.rightclick_none),
|
||||
p.getResources().getString(R.string.rightclick_multitouch),
|
||||
p.getResources().getString(R.string.rightclick_pressure),
|
||||
p.getResources().getString(R.string.rightclick_key),
|
||||
p.getResources().getString(R.string.leftclick_timeout) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.rightclick_question);
|
||||
builder.setSingleChoiceItems(items, Globals.RightClickMethod, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RightClickMethod = item;
|
||||
dialog.dismiss();
|
||||
if( item == Mouse.RIGHT_CLICK_WITH_KEY )
|
||||
p.keyListener = new KeyRemapToolMouseClick(p, false);
|
||||
else if( item == Mouse.RIGHT_CLICK_WITH_TIMEOUT )
|
||||
showRightClickTimeoutConfig(p);
|
||||
else
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showRightClickTimeoutConfig(final MainActivity p) {
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.leftclick_timeout_time_0),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_1),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_2),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_3),
|
||||
p.getResources().getString(R.string.leftclick_timeout_time_4) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.leftclick_timeout_time);
|
||||
builder.setSingleChoiceItems(items, Globals.RightClickTimeout, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RightClickTimeout = item;
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyRemapToolMouseClick implements MainActivity.KeyEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
boolean leftClick;
|
||||
public KeyRemapToolMouseClick(MainActivity _p, boolean leftClick)
|
||||
{
|
||||
p = _p;
|
||||
p.setText(p.getResources().getString(R.string.remap_hwkeys_press));
|
||||
this.leftClick = leftClick;
|
||||
}
|
||||
|
||||
public void onKeyEvent(final int keyCode)
|
||||
{
|
||||
p.keyListener = null;
|
||||
int keyIndex = keyCode;
|
||||
if( keyIndex < 0 )
|
||||
keyIndex = 0;
|
||||
if( keyIndex > SDL_Keys.JAVA_KEYCODE_LAST )
|
||||
keyIndex = 0;
|
||||
|
||||
if( leftClick )
|
||||
Globals.LeftClickKey = keyIndex;
|
||||
else
|
||||
Globals.RightClickKey = keyIndex;
|
||||
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
static class AdditionalMouseConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.pointandclick_question);
|
||||
}
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
CharSequence[] items = {
|
||||
p.getResources().getString(R.string.pointandclick_joystickmouse),
|
||||
p.getResources().getString(R.string.click_with_dpadcenter),
|
||||
p.getResources().getString(R.string.pointandclick_relative)
|
||||
};
|
||||
|
||||
boolean defaults[] = {
|
||||
Globals.MoveMouseWithJoystick,
|
||||
Globals.ClickMouseWithDpad,
|
||||
Globals.RelativeMouseMovement
|
||||
};
|
||||
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(p.getResources().getString(R.string.pointandclick_question));
|
||||
builder.setMultiChoiceItems(items, defaults, new DialogInterface.OnMultiChoiceClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked)
|
||||
{
|
||||
if( item == 0 )
|
||||
Globals.MoveMouseWithJoystick = isChecked;
|
||||
if( item == 1 )
|
||||
Globals.ClickMouseWithDpad = isChecked;
|
||||
if( item == 2 )
|
||||
Globals.RelativeMouseMovement = isChecked;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(p.getResources().getString(R.string.ok), new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
dialog.dismiss();
|
||||
if( Globals.RelativeMouseMovement )
|
||||
showRelativeMouseMovementConfig(p);
|
||||
else
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showRelativeMouseMovementConfig(final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.accel_veryslow),
|
||||
p.getResources().getString(R.string.accel_slow),
|
||||
p.getResources().getString(R.string.accel_medium),
|
||||
p.getResources().getString(R.string.accel_fast),
|
||||
p.getResources().getString(R.string.accel_veryfast) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.pointandclick_relative_speed);
|
||||
builder.setSingleChoiceItems(items, Globals.RelativeMouseMovementSpeed, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RelativeMouseMovementSpeed = item;
|
||||
|
||||
dialog.dismiss();
|
||||
showRelativeMouseMovementConfig1(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showRelativeMouseMovementConfig1(final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.none),
|
||||
p.getResources().getString(R.string.accel_slow),
|
||||
p.getResources().getString(R.string.accel_medium),
|
||||
p.getResources().getString(R.string.accel_fast) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.pointandclick_relative_accel);
|
||||
builder.setSingleChoiceItems(items, Globals.RelativeMouseMovementAccel, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.RelativeMouseMovementAccel = item;
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class JoystickMouseConfig extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.pointandclick_joystickmousespeed);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.MoveMouseWithJoystick;
|
||||
};
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.accel_slow),
|
||||
p.getResources().getString(R.string.accel_medium),
|
||||
p.getResources().getString(R.string.accel_fast) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.pointandclick_joystickmousespeed);
|
||||
builder.setSingleChoiceItems(items, Globals.MoveMouseWithJoystickSpeed, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.MoveMouseWithJoystickSpeed = item;
|
||||
|
||||
dialog.dismiss();
|
||||
showJoystickMouseAccelConfig(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
|
||||
static void showJoystickMouseAccelConfig(final MainActivity p)
|
||||
{
|
||||
final CharSequence[] items = { p.getResources().getString(R.string.none),
|
||||
p.getResources().getString(R.string.accel_slow),
|
||||
p.getResources().getString(R.string.accel_medium),
|
||||
p.getResources().getString(R.string.accel_fast) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(p);
|
||||
builder.setTitle(R.string.pointandclick_joystickmouseaccel);
|
||||
builder.setSingleChoiceItems(items, Globals.MoveMouseWithJoystickAccel, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int item)
|
||||
{
|
||||
Globals.MoveMouseWithJoystickAccel = item;
|
||||
|
||||
dialog.dismiss();
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
|
||||
{
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
goBack(p);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.setOwnerActivity(p);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
static class TouchPressureMeasurementTool extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.measurepressure);
|
||||
}
|
||||
boolean enabled()
|
||||
{
|
||||
return Globals.RightClickMethod == Mouse.RIGHT_CLICK_WITH_PRESSURE ||
|
||||
Globals.LeftClickMethod == Mouse.LEFT_CLICK_WITH_PRESSURE;
|
||||
};
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
p.setText(p.getResources().getString(R.string.measurepressure_touchplease));
|
||||
p.touchListener = new TouchMeasurementTool(p);
|
||||
}
|
||||
|
||||
public static class TouchMeasurementTool implements MainActivity.TouchEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
ArrayList<Integer> force = new ArrayList<Integer>();
|
||||
ArrayList<Integer> radius = new ArrayList<Integer>();
|
||||
static final int maxEventAmount = 100;
|
||||
|
||||
public TouchMeasurementTool(MainActivity _p)
|
||||
{
|
||||
p = _p;
|
||||
}
|
||||
|
||||
public void onTouchEvent(final MotionEvent ev)
|
||||
{
|
||||
force.add(new Integer((int)(ev.getPressure() * 1000.0)));
|
||||
radius.add(new Integer((int)(ev.getSize() * 1000.0)));
|
||||
p.setText(p.getResources().getString(R.string.measurepressure_response, force.get(force.size()-1), radius.get(radius.size()-1)));
|
||||
try {
|
||||
Thread.sleep(10L);
|
||||
} catch (InterruptedException e) { }
|
||||
|
||||
if( force.size() >= maxEventAmount )
|
||||
{
|
||||
p.touchListener = null;
|
||||
Globals.ClickScreenPressure = getAverageForce();
|
||||
Globals.ClickScreenTouchspotSize = getAverageRadius();
|
||||
Log.i("SDL", "SDL: measured average force " + Globals.ClickScreenPressure + " radius " + Globals.ClickScreenTouchspotSize);
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
|
||||
int getAverageForce()
|
||||
{
|
||||
int avg = 0;
|
||||
for(Integer f: force)
|
||||
{
|
||||
avg += f;
|
||||
}
|
||||
return avg / force.size();
|
||||
}
|
||||
int getAverageRadius()
|
||||
{
|
||||
int avg = 0;
|
||||
for(Integer r: radius)
|
||||
{
|
||||
avg += r;
|
||||
}
|
||||
return avg / radius.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class CalibrateTouchscreenMenu extends Menu
|
||||
{
|
||||
String title(final MainActivity p)
|
||||
{
|
||||
return p.getResources().getString(R.string.calibrate_touchscreen);
|
||||
}
|
||||
//boolean enabled() { return true; };
|
||||
void run (final MainActivity p)
|
||||
{
|
||||
p.setText(p.getResources().getString(R.string.calibrate_touchscreen_touch));
|
||||
Globals.TouchscreenCalibration[0] = 0;
|
||||
Globals.TouchscreenCalibration[1] = 0;
|
||||
Globals.TouchscreenCalibration[2] = 0;
|
||||
Globals.TouchscreenCalibration[3] = 0;
|
||||
ScreenEdgesCalibrationTool tool = new ScreenEdgesCalibrationTool(p);
|
||||
p.touchListener = tool;
|
||||
p.keyListener = tool;
|
||||
}
|
||||
|
||||
static class ScreenEdgesCalibrationTool implements MainActivity.TouchEventsListener, MainActivity.KeyEventsListener
|
||||
{
|
||||
MainActivity p;
|
||||
ImageView img;
|
||||
Bitmap bmp;
|
||||
|
||||
public ScreenEdgesCalibrationTool(MainActivity _p)
|
||||
{
|
||||
p = _p;
|
||||
img = new ImageView(p);
|
||||
img.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
img.setScaleType(ImageView.ScaleType.MATRIX);
|
||||
bmp = BitmapFactory.decodeResource( p.getResources(), R.drawable.calibrate );
|
||||
img.setImageBitmap(bmp);
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
|
||||
RectF dst = new RectF(Globals.TouchscreenCalibration[0], Globals.TouchscreenCalibration[1],
|
||||
Globals.TouchscreenCalibration[2], Globals.TouchscreenCalibration[3]);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
img.setImageMatrix(m);
|
||||
p.getVideoLayout().addView(img);
|
||||
}
|
||||
|
||||
public void onTouchEvent(final MotionEvent ev)
|
||||
{
|
||||
if( Globals.TouchscreenCalibration[0] == Globals.TouchscreenCalibration[1] &&
|
||||
Globals.TouchscreenCalibration[1] == Globals.TouchscreenCalibration[2] &&
|
||||
Globals.TouchscreenCalibration[2] == Globals.TouchscreenCalibration[3] )
|
||||
{
|
||||
Globals.TouchscreenCalibration[0] = (int)ev.getX();
|
||||
Globals.TouchscreenCalibration[1] = (int)ev.getY();
|
||||
Globals.TouchscreenCalibration[2] = (int)ev.getX();
|
||||
Globals.TouchscreenCalibration[3] = (int)ev.getY();
|
||||
}
|
||||
if( ev.getX() < Globals.TouchscreenCalibration[0] )
|
||||
Globals.TouchscreenCalibration[0] = (int)ev.getX();
|
||||
if( ev.getY() < Globals.TouchscreenCalibration[1] )
|
||||
Globals.TouchscreenCalibration[1] = (int)ev.getY();
|
||||
if( ev.getX() > Globals.TouchscreenCalibration[2] )
|
||||
Globals.TouchscreenCalibration[2] = (int)ev.getX();
|
||||
if( ev.getY() > Globals.TouchscreenCalibration[3] )
|
||||
Globals.TouchscreenCalibration[3] = (int)ev.getY();
|
||||
Matrix m = new Matrix();
|
||||
RectF src = new RectF(0, 0, bmp.getWidth(), bmp.getHeight());
|
||||
RectF dst = new RectF(Globals.TouchscreenCalibration[0], Globals.TouchscreenCalibration[1],
|
||||
Globals.TouchscreenCalibration[2], Globals.TouchscreenCalibration[3]);
|
||||
m.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
|
||||
img.setImageMatrix(m);
|
||||
}
|
||||
|
||||
public void onKeyEvent(final int keyCode)
|
||||
{
|
||||
p.touchListener = null;
|
||||
p.keyListener = null;
|
||||
p.getVideoLayout().removeView(img);
|
||||
goBack(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.graphics.drawable.BitmapDrawable;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.AssetManager;
|
||||
import android.widget.Toast;
|
||||
import android.util.Log;
|
||||
|
||||
import android.widget.TextView;
|
||||
import java.lang.Thread;
|
||||
@@ -108,7 +109,7 @@ abstract class DifferentTouchInput
|
||||
multiTouchAvailable2 = true;
|
||||
}
|
||||
try {
|
||||
System.out.println("Device model: " + android.os.Build.MODEL);
|
||||
Log.i("SDL", "Device model: " + android.os.Build.MODEL);
|
||||
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH )
|
||||
{
|
||||
return IcsTouchInput.Holder.sInstance;
|
||||
@@ -191,7 +192,7 @@ abstract class DifferentTouchInput
|
||||
{
|
||||
int action = -1;
|
||||
|
||||
//System.out.println("Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY());
|
||||
//Log.i("SDL", "Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY());
|
||||
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP ||
|
||||
(event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_CANCEL )
|
||||
{
|
||||
@@ -231,7 +232,7 @@ abstract class DifferentTouchInput
|
||||
{
|
||||
s += " p" + event.getPointerId(i) + "=" + (int)event.getX(i) + ":" + (int)event.getY(i);
|
||||
}
|
||||
System.out.println(s);
|
||||
Log.i("SDL", s);
|
||||
*/
|
||||
int pointerReleased = -1;
|
||||
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP )
|
||||
@@ -332,7 +333,7 @@ abstract class DifferentTouchInput
|
||||
private int buttonState = 0;
|
||||
public void process(final MotionEvent event)
|
||||
{
|
||||
//System.out.println("Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY() + " buttons " + buttonState + " source " + event.getSource());
|
||||
//Log.i("SDL", "Got motion event, type " + (int)(event.getAction()) + " X " + (int)event.getX() + " Y " + (int)event.getY() + " buttons " + buttonState + " source " + event.getSource());
|
||||
int buttonStateNew = event.getButtonState();
|
||||
if( buttonStateNew != buttonState )
|
||||
{
|
||||
@@ -379,7 +380,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
System.out.println("libSDL: DemoRenderer.onSurfaceCreated(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
|
||||
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceCreated(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
|
||||
mGlSurfaceCreated = true;
|
||||
mGl = gl;
|
||||
if( ! mPaused && ! mFirstTimeStart )
|
||||
@@ -388,7 +389,14 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int w, int h) {
|
||||
System.out.println("libSDL: DemoRenderer.onSurfaceChanged(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
|
||||
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceChanged(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart + " w " + w + " h " + h);
|
||||
if( w < h && Globals.HorizontalOrientation )
|
||||
{
|
||||
// Sometimes when Android awakes from lockscreen, portrait orientation is kept
|
||||
int x = w;
|
||||
w = h;
|
||||
h = x;
|
||||
}
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
mGl = gl;
|
||||
@@ -396,7 +404,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
}
|
||||
|
||||
public void onSurfaceDestroyed() {
|
||||
System.out.println("libSDL: DemoRenderer.onSurfaceDestroyed(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
|
||||
Log.i("SDL", "libSDL: DemoRenderer.onSurfaceDestroyed(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart );
|
||||
mGlSurfaceCreated = false;
|
||||
mGlContextLost = true;
|
||||
nativeGlContextLost();
|
||||
@@ -568,6 +576,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
}
|
||||
public void DrawLogo(GL10 gl)
|
||||
{
|
||||
/*
|
||||
// TODO: this not quite works, as it seems
|
||||
BitmapDrawable bmp = null;
|
||||
try
|
||||
@@ -618,6 +627,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
gl.glDeleteTextures(1, mTextureNameWorkspace, 0);
|
||||
|
||||
gl.glFlush();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -723,7 +733,7 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL {
|
||||
return;
|
||||
mRenderer.mPaused = false;
|
||||
super.onResume();
|
||||
System.out.println("libSDL: DemoGLSurfaceView.onResume(): mRenderer.mGlSurfaceCreated " + mRenderer.mGlSurfaceCreated + " mRenderer.mPaused " + mRenderer.mPaused);
|
||||
Log.i("SDL", "libSDL: DemoGLSurfaceView.onResume(): mRenderer.mGlSurfaceCreated " + mRenderer.mGlSurfaceCreated + " mRenderer.mPaused " + mRenderer.mPaused);
|
||||
if( mRenderer.mGlSurfaceCreated && ! mRenderer.mPaused || Globals.NonBlockingSwapBuffers )
|
||||
mRenderer.nativeGlContextRecreated();
|
||||
if( mRenderer.accelerometer != null && mRenderer.accelerometer.openedBySDL ) // For some reason it crashes here often - are we getting this event before initialization?
|
||||
@@ -733,7 +743,7 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL {
|
||||
// This seems like redundant code - it handled in MainActivity.java
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, final KeyEvent event) {
|
||||
//System.out.println("Got key down event, id " + keyCode + " meta " + event.getMetaState() + " event " + event.toString());
|
||||
//Log.i("SDL", "Got key down event, id " + keyCode + " meta " + event.getMetaState() + " event " + event.toString());
|
||||
if( nativeKey( keyCode, 1 ) == 0 )
|
||||
return super.onKeyDown(keyCode, event);
|
||||
return true;
|
||||
@@ -741,7 +751,7 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL {
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, final KeyEvent event) {
|
||||
//System.out.println("Got key up event, id " + keyCode + " meta " + event.getMetaState());
|
||||
//Log.i("SDL", "Got key up event, id " + keyCode + " meta " + event.getMetaState());
|
||||
if( nativeKey( keyCode, 0 ) == 0 )
|
||||
return super.onKeyUp(keyCode, event);
|
||||
return true;
|
||||
|
||||
@@ -172,4 +172,5 @@
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="screenkb_custom_layout_help">Press BACK when done. Resize buttons by sliding on empty space.</string>
|
||||
<string name="controls_screenkb_custom">Custom</string>
|
||||
</resources>
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
<string name="controls_additional">Дополнительные элементы управления</string>
|
||||
<string name="controls_screenkb">Экранная клавиатура</string>
|
||||
<string name="controls_accelnav">Акселерометр</string>
|
||||
<string name="controls_screenkb_size">Экранная клавиатура размером</string>
|
||||
<string name="controls_screenkb_size">Размер экранной клавиатуры</string>
|
||||
<string name="controls_screenkb_large">Большой</string>
|
||||
<string name="controls_screenkb_medium">Средний</string>
|
||||
<string name="controls_screenkb_small">Малые</string>
|
||||
<string name="controls_screenkb_small">Маленький</string>
|
||||
<string name="controls_screenkb_tiny">Крошечный</string>
|
||||
<string name="controls_screenkb_theme">Тема клавиатуры</string>
|
||||
<string name="controls_screenkb_by">%1$s от %2$s</string>
|
||||
@@ -87,10 +87,10 @@
|
||||
<string name="remap_screenkb_joystick">Экранный джойстик</string>
|
||||
<string name="remap_screenkb_button">Экранные кнопки</string>
|
||||
<string name="remap_screenkb_button_text">Экранная кнопка ввода текста</string>
|
||||
<string name="remap_screenkb_button_zoomin">Увеличить двумя пальцами жест</string>
|
||||
<string name="remap_screenkb_button_zoomout">Уменьшить двумя пальцами жест</string>
|
||||
<string name="remap_screenkb_button_rotateleft">Повернуть налево двумя пальцами жест</string>
|
||||
<string name="remap_screenkb_button_rotateright">Повернуть вправо двумя пальцами жест</string>
|
||||
<string name="remap_screenkb_button_zoomin">Увеличить двумя пальцами</string>
|
||||
<string name="remap_screenkb_button_zoomout">Уменьшить двумя пальцами</string>
|
||||
<string name="remap_screenkb_button_rotateleft">Повернуть налево двумя пальцами</string>
|
||||
<string name="remap_screenkb_button_rotateright">Повернуть вправо двумя пальцами</string>
|
||||
<string name="remap_screenkb_button_gestures">Жест двумя пальцами по экрану</string>
|
||||
<string name="accel_veryfast">Очень быстро</string>
|
||||
<string name="remap_screenkb_button_gestures_sensitivity">Чувствительность жеста двумя пальцами по экрану</string>
|
||||
@@ -145,4 +145,5 @@
|
||||
<string name="cancel_download_resume">Загрузка может быть продолжена позднее.</string>
|
||||
<string name="yes">Да</string>
|
||||
<string name="no">Нет</string>
|
||||
<string name="controls_screenkb_custom">Пользовательские настройки</string>
|
||||
</resources>
|
||||
|
||||
@@ -87,10 +87,10 @@
|
||||
<string name="remap_screenkb_joystick">Наекранний джойстік</string>
|
||||
<string name="remap_screenkb_button">Наекранні кнопки</string>
|
||||
<string name="remap_screenkb_button_text">Наекранна кнопка вводу тексту</string>
|
||||
<string name="remap_screenkb_button_zoomin">Збільшити двома пальцями жест</string>
|
||||
<string name="remap_screenkb_button_zoomout">Зменшити двома пальцями жест</string>
|
||||
<string name="remap_screenkb_button_rotateleft">Повернути наліво двома пальцями жест</string>
|
||||
<string name="remap_screenkb_button_rotateright">Повернути праворуч двома пальцями жест</string>
|
||||
<string name="remap_screenkb_button_zoomin">Збільшити двома пальцями</string>
|
||||
<string name="remap_screenkb_button_zoomout">Зменшити двома пальцями</string>
|
||||
<string name="remap_screenkb_button_rotateleft">Повернути наліво двома пальцями</string>
|
||||
<string name="remap_screenkb_button_rotateright">Повернути праворуч двома пальцями</string>
|
||||
<string name="remap_screenkb_button_gestures">Жест двома пальцями по екрану</string>
|
||||
<string name="accel_veryfast">Дуже швидко</string>
|
||||
<string name="remap_screenkb_button_gestures_sensitivity">Чутливість жесту двома пальцями по екрану</string>
|
||||
@@ -144,4 +144,5 @@
|
||||
<string name="cancel_download_resume">Завантаження може бути відновлено пізніше.</string>
|
||||
<string name="yes">Так</string>
|
||||
<string name="no">Ні</string>
|
||||
<string name="controls_screenkb_custom">Налаштування користувача</string>
|
||||
</resources>
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<string name="controls_screenkb_medium">Medium</string>
|
||||
<string name="controls_screenkb_small">Small</string>
|
||||
<string name="controls_screenkb_tiny">Tiny</string>
|
||||
<string name="controls_screenkb_custom">Custom</string>
|
||||
<string name="controls_screenkb_theme">On-screen keyboard theme</string>
|
||||
<string name="controls_screenkb_by">%1$s by %2$s</string>
|
||||
<string name="controls_screenkb_transparency">On-screen keyboard transparency</string>
|
||||
@@ -123,11 +124,13 @@
|
||||
<string name="remap_hwkeys">Remap physical keys</string>
|
||||
<string name="remap_hwkeys_press">Press any key except HOME and POWER, you may use volume keys</string>
|
||||
<string name="remap_hwkeys_select">Select SDL keycode</string>
|
||||
<string name="remap_hwkeys_select_simple">Select action</string>
|
||||
<string name="remap_hwkeys_select_more_keys">Show all keycodes</string>
|
||||
|
||||
<string name="remap_screenkb">Remap on-screen controls</string>
|
||||
<string name="remap_screenkb_joystick">On-screen joystick</string>
|
||||
<string name="remap_screenkb_button">On-screen button</string>
|
||||
<string name="remap_screenkb_button_text">On-screen text input button</string>
|
||||
<string name="remap_screenkb_joystick">Joystick</string>
|
||||
<string name="remap_screenkb_button">Button</string>
|
||||
<string name="remap_screenkb_button_text">Text input button</string>
|
||||
<string name="remap_screenkb_button_gestures">Two-finger screen gestures</string>
|
||||
<string name="remap_screenkb_button_gestures_sensitivity">Two-finger screen gestures sensitivity</string>
|
||||
<string name="remap_screenkb_button_zoomin">Zoom in two-finger gesture</string>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
APP_MODULES := application sdl-1.2 sdl_main stlport jpeg png ogg flac vorbis freetype tremor ogg
|
||||
|
||||
# To filter out static libs from all libs in makefile
|
||||
|
||||
@@ -1,62 +1,215 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
|
||||
AppSettingVersion=18
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="Ballfield"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=net.olofson.ballfield
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="Game data is 1 Mb|ballfield3.zip"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!!Game data is 1 Mb|ballfield3.zip"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=y
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=y
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=y
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=y
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=y
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=y
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=y
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=y
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="SPACE RETURN NO_REMAP NO_REMAP SPACE ESCAPE"
|
||||
AppTouchscreenKeyboardKeysAmount=1
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=6
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="0 1 2 3 4 5 6 7 8 9"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# OkButton DummyMenu MainMenu MouseConfigMainMenu KeyboardConfigMainMenu DownloadConfig OptionalDownloadConfig ScreenKeyboardSizeConfig ScreenKeyboardDrawSizeConfig ScreenKeyboardThemeConfig ScreenKeyboardTransparencyConfig AudioConfig DisplaySizeConfig LeftClickConfig RightClickConfig AdditionalMouseConfig JoystickMouseConfig TouchPressureMeasurementTool RemapHwKeysConfig RemapScreenKbConfig ScreenGesturesConfig CalibrateTouchscreenMenu CustomizeScreenKbLayout VideoSettingsConfig ShowReadme GyroscopeCalibration ResetToDefaultsConfig
|
||||
HiddenMenuOptions='OptionalDownloadConfig'
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default:
|
||||
# new Settings.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# new Settings.OkButton(), new Settings.DummyMenu(), new Settings.MainMenu(), new Settings.MouseConfigMainMenu(), new Settings.KeyboardConfigMainMenu(), new Settings.DownloadConfig(), new Settings.OptionalDownloadConfig(), new Settings.ScreenKeyboardSizeConfig(), new Settings.ScreenKeyboardDrawSizeConfig(), new Settings.ScreenKeyboardThemeConfig(), new Settings.ScreenKeyboardTransparencyConfig(), new Settings.AudioConfig(), new Settings.DisplaySizeConfig(), new Settings.LeftClickConfig(), new Settings.RightClickConfig(), new Settings.AdditionalMouseConfig(), new Settings.JoystickMouseConfig(), new Settings.TouchPressureMeasurementTool(), new Settings.RemapHwKeysConfig(), new Settings.RemapScreenKbConfig(), new Settings.ScreenGesturesConfig(), new Settings.CalibrateTouchscreenMenu(), new Settings.CustomizeScreenKbLayout(), new Settings.VideoSettingsConfig(), new Settings.ShowReadme(), new Settings.GyroscopeCalibration(), new Settings.ResetToDefaultsConfig(),
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=y
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=0
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=101
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.01"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-O2 -finline-functions'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on
|
||||
ReadmeText='^Readme text'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
Definitions...
|
||||
----------------------------------------------------------*/
|
||||
|
||||
#define SCREEN_W 800
|
||||
#define SCREEN_W 640
|
||||
#define SCREEN_H 480
|
||||
|
||||
|
||||
@@ -562,6 +562,8 @@ int main(int argc, char* argv[])
|
||||
SDL_ANDROID_GetScreenKeyboardButtonPos(i, &r);
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "Ballfield", "{ %d, %d, %d, %d },", r.x, r.y, r.x+r.h, r.y+r.w);
|
||||
}
|
||||
//SDL_ANDROID_SetScreenKeyboardButtonGenerateTouchEvents(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, 1);
|
||||
//SDL_ANDROID_SetScreenKeyboardButtonGenerateTouchEvents(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, 1);
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
@@ -1,62 +1,215 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
|
||||
AppSettingVersion=18
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="Commander Genius"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=net.sourceforge.clonekeenplus
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!Keen1|keen1.zip^!Keen4|keen4.zip^!Keen7|keen7.zip^High-quality GFX and music - 50 Mb|http://sourceforge.net/projects/clonekeenplus/files/High%20Quality%20Packs/Version%202.x/hqpv20.zip/download"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=24
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=n
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=n
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=n
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=n
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=y
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=y
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="LCTRL LALT NO_REMAP NO_REMAP RETURN ESCAPE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=4
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=1
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="LCTRL LALT SPACE RETURN"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="LCTRL LALT SPACE RETURN"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# OkButton DummyMenu MainMenu MouseConfigMainMenu KeyboardConfigMainMenu DownloadConfig OptionalDownloadConfig ScreenKeyboardSizeConfig ScreenKeyboardDrawSizeConfig ScreenKeyboardThemeConfig ScreenKeyboardTransparencyConfig AudioConfig DisplaySizeConfig LeftClickConfig RightClickConfig AdditionalMouseConfig JoystickMouseConfig TouchPressureMeasurementTool RemapHwKeysConfig RemapScreenKbConfig ScreenGesturesConfig CalibrateTouchscreenMenu CustomizeScreenKbLayout VideoSettingsConfig ShowReadme GyroscopeCalibration ResetToDefaultsConfig
|
||||
HiddenMenuOptions=''
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default:
|
||||
# new Settings.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# new Settings.OkButton(), new Settings.DummyMenu(), new Settings.MainMenu(), new Settings.MouseConfigMainMenu(), new Settings.KeyboardConfigMainMenu(), new Settings.DownloadConfig(), new Settings.OptionalDownloadConfig(), new Settings.ScreenKeyboardSizeConfig(), new Settings.ScreenKeyboardDrawSizeConfig(), new Settings.ScreenKeyboardThemeConfig(), new Settings.ScreenKeyboardTransparencyConfig(), new Settings.AudioConfig(), new Settings.DisplaySizeConfig(), new Settings.LeftClickConfig(), new Settings.RightClickConfig(), new Settings.AdditionalMouseConfig(), new Settings.JoystickMouseConfig(), new Settings.TouchPressureMeasurementTool(), new Settings.RemapHwKeysConfig(), new Settings.RemapScreenKbConfig(), new Settings.ScreenGesturesConfig(), new Settings.CalibrateTouchscreenMenu(), new Settings.CustomizeScreenKbLayout(), new Settings.VideoSettingsConfig(), new Settings.ShowReadme(), new Settings.GyroscopeCalibration(), new Settings.ResetToDefaultsConfig(),
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=n
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=64
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=144000
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.4.4 Release"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="tremor ogg sdl_image"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-frtti -fexceptions -finline-functions -O2 -DTREMOR=1 -DANDROID=1 -DBUILD_TYPE=LINUX -DTARGET_LNX=1 -Werror=strict-aliasing -Werror=cast-align -Werror=pointer-arith -Werror=address -std=c++11'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags='-ltremor'
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild='commandergenius/src/*'
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=m
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ SdlVideoResizeKeepAspect=n
|
||||
CompatibilityHacks=n
|
||||
CompatibilityHacksStaticInit=n
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
CompatibilityHacksSlowCompatibleEventQueue=y
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
AppUsesMouse=y
|
||||
AppNeedsTwoButtonMouse=y
|
||||
ShowMouseCursor=n
|
||||
@@ -24,25 +29,31 @@ AppNeedsArrowKeys=n
|
||||
AppNeedsTextInput=n
|
||||
AppUsesJoystick=n
|
||||
AppUsesAccelerometer=n
|
||||
AppUsesGyroscope=n
|
||||
AppUsesMultitouch=n
|
||||
AppRecordsAudio=y
|
||||
NonBlockingSwapBuffers=n
|
||||
RedefinedKeys="LCTRL T NO_REMAP NO_REMAP H"
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
RedefinedKeysScreenKb="LCTRL M SPACE C E C H T S L"
|
||||
RedefinedKeysScreenKbNames="LCTRL M SPACE C E C H T S L"
|
||||
StartupMenuButtonTimeout=3000
|
||||
HiddenMenuOptions=''
|
||||
FirstStartMenuOptions=''
|
||||
MultiABI=n
|
||||
AppVersionCode=288220
|
||||
AppVersionName="2882.20"
|
||||
AppMinimumRAM=32
|
||||
AppVersionCode=304100
|
||||
AppVersionName="3041.00"
|
||||
ResetSdlConfigForThisVersion=n
|
||||
DeleteFilesOnUpgrade="libsdl-DownloadFinished-5.flag libsdl-DownloadFinished-6.flag libsdl-DownloadFinished-7.flag libsdl-DownloadFinished-8.flag libsdl-DownloadFinished-9.flag libsdl-DownloadFinished-10.flag libsdl-DownloadFinished-11.flag libsdl-DownloadFinished-12.flag libsdl-DownloadFinished-13.flag libsdl-DownloadFinished-14.flag"
|
||||
CompiledLibraries="sdl_net sdl_mixer sdl_image sdl_ttf png intl"
|
||||
CustomBuildScript=n
|
||||
AppCflags='-finline-functions -O2 -DWITH_ZLIB -DWITH_MIXER -DWITH_XML -DWITH_IMAGE -DWITH_TTF -DWITH_AI=simple -DWITH_DEBUG -DWITH_EDITOR -frtti'
|
||||
AppLdflags=''
|
||||
AppOverlapsSystemHeaders=
|
||||
AppSubdirsBuild='fheroes2/src/engine fheroes2/src/xmlccwrap fheroes2/src/fheroes2/agg fheroes2/src/fheroes2/ai fheroes2/src/fheroes2/ai/simple fheroes2/src/fheroes2/army fheroes2/src/fheroes2/battle fheroes2/src/fheroes2/castle fheroes2/src/fheroes2/dialog fheroes2/src/fheroes2/editor fheroes2/src/fheroes2/game fheroes2/src/fheroes2/gui fheroes2/src/fheroes2/heroes fheroes2/src/fheroes2/image fheroes2/src/fheroes2/kingdom fheroes2/src/fheroes2/maps fheroes2/src/fheroes2/monster fheroes2/src/fheroes2/objects fheroes2/src/fheroes2/pocketpc fheroes2/src/fheroes2/resource fheroes2/src/fheroes2/spell fheroes2/src/fheroes2/system fheroes2/src/fheroes2/test'
|
||||
AppBuildExclude=''
|
||||
AppCmdline='fheroes2'
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
MinimumScreenSize=s
|
||||
|
||||
@@ -1,62 +1,215 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
|
||||
AppSettingVersion=18
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="OpenArena"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=ws.openarena.sdl
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!Game data|:baseoa/pak0.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak0.pk3/download^!Game data|:baseoa/pak1-maps.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak1-maps.pk3/download^!Game data|:baseoa/pak2-players-mature.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak2-players-mature.pk3/download^!Game data|:baseoa/pak2-players.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak2-players.pk3/download^!Game data|:baseoa/pak4-textures.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak4-textures.pk3/download^!Game data|:baseoa/pak5-TA.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak5-TA.pk3/download^!Game data|:baseoa/pak6-misc.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak6-misc.pk3/download^!Game data|:baseoa/pak6-patch085.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak6-patch085.pk3/download^!Game data|:baseoa/pak6-patch088.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/pak6-patch088.pk3/download^!Game data|:baseoa/skn-arachna-forlorna.pk3:http://sourceforge.net/projects/libsdl-android/files/OpenArena/0.8.8/skn-arachna-forlorna.pk3/download^!Game logic|:baseoa/pak7-android.pk3:pak7-android.pk3"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=24
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=y
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=n
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=n
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=n
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=n
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=y
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=y
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=y
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=y
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=y
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=y
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="SPACE SPACE NO_REMAP NO_REMAP RETURN ESCAPE LCTRL"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=6
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="SLASH BACKSPACE TAB END LCTRL SPACE UNKNOWN UNKNOWN UNKNOWN UNKNOWN"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="Change_weapon Sniper_view Show_scores Center_view Fire Jump"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
#
|
||||
HiddenMenuOptions='OptionalDownloadConfig DisplaySizeConfig'
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# new SettingsMenu.OkButton(), new SettingsMenu.DummyMenu(), new SettingsMenu.MainMenu(), new SettingsMenuMisc.DownloadConfig(), new SettingsMenuMisc.OptionalDownloadConfig(), new SettingsMenuMisc.AudioConfig(), new SettingsMenuMisc.VideoSettingsConfig(), new SettingsMenuMisc.ShowReadme(), new SettingsMenuMisc.GyroscopeCalibration(), new SettingsMenuMisc.ResetToDefaultsConfig(), new SettingsMenuMouse.MouseConfigMainMenu(), new SettingsMenuMouse.DisplaySizeConfig(), new SettingsMenuMouse.LeftClickConfig(), new SettingsMenuMouse.RightClickConfig(), new SettingsMenuMouse.AdditionalMouseConfig(), new SettingsMenuMouse.JoystickMouseConfig(), new SettingsMenuMouse.TouchPressureMeasurementTool(), new SettingsMenuMouse.CalibrateTouchscreenMenu(), new SettingsMenuKeyboard.KeyboardConfigMainMenu(), new SettingsMenuKeyboard.ScreenKeyboardSizeConfig(), new SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig(), new SettingsMenuKeyboard.ScreenKeyboardThemeConfig(), new SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig(), new SettingsMenuKeyboard.RemapHwKeysConfig(), new SettingsMenuKeyboard.RemapScreenKbConfig(), new SettingsMenuKeyboard.ScreenGesturesConfig(), new SettingsMenuKeyboard.CustomizeScreenKbLayout(),
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=y
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=300
|
||||
AppVersionCode=08822
|
||||
AppVersionName="0.8.8.22"
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=08823
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="0.8.8.23"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="libsdl-DownloadFinished-10.flag"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_mixer sdl_image freetype curl vorbis ogg openal"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=y
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-O2 -finline-functions'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?)
|
||||
ReadmeText='^Readme text'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=n
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=66133194946FB6C1CD0ED2EFCCB82539
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=BANNER
|
||||
|
||||
|
||||
Submodule project/jni/application/openarena/engine updated: 1c3f8aa9c1...a90f54fd48
Submodule project/jni/application/openarena/vm updated: c88124ddcb...79d6cc69db
@@ -1,62 +1,215 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
|
||||
AppSettingVersion=18
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="OpenTTD"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=org.openttd.sdl
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="!Data files - 20 Mb|http://sourceforge.net/projects/libsdl-android/files/OpenTTD/openttd-data-1.3.0.zip/download^!MIDI music support (18 Mb)|timidity.zip|http://sourceforge.net/projects/libsdl-android/files/timidity.zip^!Config file|:.openttd/openttd.cfg:openttd-1.3.0.25.cfg"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!!Data files - 20 Mb|http://sourceforge.net/projects/libsdl-android/files/OpenTTD/openttd-data-1.3.1.zip/download^!MIDI music support (18 Mb)|timidity.zip|http://sourceforge.net/projects/libsdl-android/files/timidity.zip^!!Config file|:.openttd/openttd.cfg:openttd-1.3.0.25.cfg"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=y
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=n
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=n
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="LALT RETURN NO_REMAP NO_REMAP SPACE DELETE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=0
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="LALT RETURN KP_PLUS KP_MINUS SPACE DELETE KP_PLUS KP_MINUS 1 2"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="LALT RETURN KP_PLUS KP_MINUS SPACE DELETE KP_PLUS KP_MINUS 1 2"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# OkButton DummyMenu MainMenu MouseConfigMainMenu KeyboardConfigMainMenu DownloadConfig OptionalDownloadConfig ScreenKeyboardSizeConfig ScreenKeyboardDrawSizeConfig ScreenKeyboardThemeConfig ScreenKeyboardTransparencyConfig AudioConfig DisplaySizeConfig LeftClickConfig RightClickConfig AdditionalMouseConfig JoystickMouseConfig TouchPressureMeasurementTool RemapHwKeysConfig RemapScreenKbConfig ScreenGesturesConfig CalibrateTouchscreenMenu CustomizeScreenKbLayout VideoSettingsConfig ShowReadme GyroscopeCalibration ResetToDefaultsConfig
|
||||
HiddenMenuOptions='OptionalDownloadConfig'
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default:
|
||||
# new Settings.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new Settings.DisplaySizeConfig(true) : new Settings.DummyMenu()), new Settings.OptionalDownloadConfig(true), new Settings.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# new Settings.OkButton(), new Settings.DummyMenu(), new Settings.MainMenu(), new Settings.MouseConfigMainMenu(), new Settings.KeyboardConfigMainMenu(), new Settings.DownloadConfig(), new Settings.OptionalDownloadConfig(), new Settings.ScreenKeyboardSizeConfig(), new Settings.ScreenKeyboardDrawSizeConfig(), new Settings.ScreenKeyboardThemeConfig(), new Settings.ScreenKeyboardTransparencyConfig(), new Settings.AudioConfig(), new Settings.DisplaySizeConfig(), new Settings.LeftClickConfig(), new Settings.RightClickConfig(), new Settings.AdditionalMouseConfig(), new Settings.JoystickMouseConfig(), new Settings.TouchPressureMeasurementTool(), new Settings.RemapHwKeysConfig(), new Settings.RemapScreenKbConfig(), new Settings.ScreenGesturesConfig(), new Settings.CalibrateTouchscreenMenu(), new Settings.CustomizeScreenKbLayout(), new Settings.VideoSettingsConfig(), new Settings.ShowReadme(), new Settings.GyroscopeCalibration(), new Settings.ResetToDefaultsConfig(),
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=n
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=0
|
||||
AppVersionCode=13025
|
||||
AppVersionName="1.3.0.25"
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=13125
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.3.1.25"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="jpeg png freetype timidity lzma lzo2"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=y
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags=''
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline='openttd'
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?)
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=s
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
LOCAL_PATH=`dirname $0`
|
||||
LOCAL_PATH=`cd $LOCAL_PATH && pwd`
|
||||
VER=1.3.0
|
||||
VER=1.3.1
|
||||
|
||||
|
||||
if [ \! -d openttd-$VER ] ; then
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--- src/debug.cpp 2013-03-31 23:56:27.000000000 +0300
|
||||
+++ src/debug.cpp 2013-04-04 21:22:32.082336178 +0300
|
||||
--- src/debug.cpp 2013-05-31 23:57:15.000000000 +0300
|
||||
+++ src/debug.cpp 2013-06-02 17:34:54.700814123 +0300
|
||||
@@ -16,6 +16,9 @@
|
||||
#include "string_func.h"
|
||||
#include "fileio_func.h"
|
||||
@@ -20,8 +20,8 @@
|
||||
#if defined(ENABLE_NETWORK)
|
||||
if (_debug_socket != INVALID_SOCKET) {
|
||||
char buf2[1024 + 32];
|
||||
--- src/fontcache.cpp 2013-03-31 23:56:27.000000000 +0300
|
||||
+++ src/fontcache.cpp 2013-04-04 21:22:32.082336178 +0300
|
||||
--- src/fontcache.cpp 2013-05-31 23:57:15.000000000 +0300
|
||||
+++ src/fontcache.cpp 2013-06-02 17:34:54.700814123 +0300
|
||||
@@ -808,7 +808,15 @@
|
||||
return ret;
|
||||
}
|
||||
@@ -39,8 +39,8 @@
|
||||
FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) {return FT_Err_Cannot_Open_Resource;}
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; }
|
||||
#endif /* WITH_FONTCONFIG */
|
||||
--- src/music/libtimidity.cpp 2013-03-31 23:56:08.000000000 +0300
|
||||
+++ src/music/libtimidity.cpp 2013-04-04 21:22:32.082336178 +0300
|
||||
--- src/music/libtimidity.cpp 2013-05-31 23:56:52.000000000 +0300
|
||||
+++ src/music/libtimidity.cpp 2013-06-02 17:34:54.700814123 +0300
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "../openttd.h"
|
||||
#include "../sound_type.h"
|
||||
@@ -82,8 +82,8 @@
|
||||
|
||||
/** Factory for the libtimidity driver. */
|
||||
static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity;
|
||||
--- src/network/core/os_abstraction.h 2013-03-31 23:56:21.000000000 +0300
|
||||
+++ src/network/core/os_abstraction.h 2013-04-04 21:22:32.086336178 +0300
|
||||
--- src/network/core/os_abstraction.h 2013-05-31 23:57:06.000000000 +0300
|
||||
+++ src/network/core/os_abstraction.h 2013-06-02 17:34:54.700814123 +0300
|
||||
@@ -161,7 +161,7 @@
|
||||
# include <net/if.h>
|
||||
/* According to glibc/NEWS, <ifaddrs.h> appeared in glibc-2.3. */
|
||||
@@ -93,8 +93,8 @@
|
||||
/* If for any reason ifaddrs.h does not exist on your system, comment out
|
||||
* the following two lines and an alternative way will be used to fetch
|
||||
* the list of IPs from the system. */
|
||||
--- src/os/unix/crashlog_unix.cpp 2013-03-31 23:56:09.000000000 +0300
|
||||
+++ src/os/unix/crashlog_unix.cpp 2013-04-04 21:22:32.086336178 +0300
|
||||
--- src/os/unix/crashlog_unix.cpp 2013-05-31 23:56:54.000000000 +0300
|
||||
+++ src/os/unix/crashlog_unix.cpp 2013-06-02 17:34:54.700814123 +0300
|
||||
@@ -141,7 +141,11 @@
|
||||
};
|
||||
|
||||
@@ -107,8 +107,8 @@
|
||||
|
||||
/**
|
||||
* Entry point for the crash handler.
|
||||
--- src/os/unix/unix.cpp 2013-03-31 23:56:09.000000000 +0300
|
||||
+++ src/os/unix/unix.cpp 2013-04-04 21:22:32.086336178 +0300
|
||||
--- src/os/unix/unix.cpp 2013-05-31 23:56:54.000000000 +0300
|
||||
+++ src/os/unix/unix.cpp 2013-06-02 17:34:54.704814123 +0300
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -130,8 +130,8 @@
|
||||
int CDECL main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
--- src/osk_gui.cpp 2013-03-31 23:56:27.000000000 +0300
|
||||
+++ src/osk_gui.cpp 2013-04-04 21:24:19.418335198 +0300
|
||||
--- src/osk_gui.cpp 2013-05-31 23:57:15.000000000 +0300
|
||||
+++ src/osk_gui.cpp 2013-06-02 17:41:23.344810333 +0300
|
||||
@@ -21,6 +21,9 @@
|
||||
|
||||
#include "table/sprites.h"
|
||||
@@ -142,13 +142,15 @@
|
||||
|
||||
char _keyboard_opt[2][OSK_KEYBOARD_ENTRIES * 4 + 1];
|
||||
static WChar _keyboard[2][OSK_KEYBOARD_ENTRIES];
|
||||
@@ -411,6 +414,14 @@
|
||||
@@ -411,6 +414,16 @@
|
||||
|
||||
GetKeyboardLayout();
|
||||
new OskWindow(&_osk_desc, parent, button);
|
||||
+#ifdef __ANDROID__
|
||||
+ SDL_ANDROID_GetScreenKeyboardTextInput(parent->text.buf, parent->text.max_bytes); /* Invoke Android built-in screen keyboard */
|
||||
+ char text[256];
|
||||
+ SDL_ANDROID_GetScreenKeyboardTextInput(text, sizeof(text) - 1); /* Invoke Android built-in screen keyboard */
|
||||
+ OskWindow *osk = dynamic_cast<OskWindow *>(FindWindowById(WC_OSK, 0));
|
||||
+ osk->qs->text.Assign(text);
|
||||
+ free(osk->orig_str_buf);
|
||||
+ osk->orig_str_buf = strdup(osk->qs->text.buf);
|
||||
+
|
||||
@@ -157,8 +159,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
--- src/script/api/script_date.cpp 2013-03-31 23:56:17.000000000 +0300
|
||||
+++ src/script/api/script_date.cpp 2013-04-04 21:22:32.090336178 +0300
|
||||
--- src/script/api/script_date.cpp 2013-05-31 23:57:01.000000000 +0300
|
||||
+++ src/script/api/script_date.cpp 2013-06-02 17:34:54.704814123 +0300
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/** @file script_date.cpp Implementation of ScriptDate. */
|
||||
@@ -169,8 +171,8 @@
|
||||
#include "script_date.hpp"
|
||||
#include "../../date_func.h"
|
||||
|
||||
--- src/sound/sdl_s.cpp 2013-03-31 23:56:07.000000000 +0300
|
||||
+++ src/sound/sdl_s.cpp 2013-04-04 21:22:32.090336178 +0300
|
||||
--- src/sound/sdl_s.cpp 2013-05-31 23:56:51.000000000 +0300
|
||||
+++ src/sound/sdl_s.cpp 2013-06-02 17:34:54.704814123 +0300
|
||||
@@ -21,6 +21,10 @@
|
||||
/** Factory for the SDL sound driver. */
|
||||
static FSoundDriver_SDL iFSoundDriver_SDL;
|
||||
@@ -192,8 +194,8 @@
|
||||
}
|
||||
|
||||
const char *SoundDriver_SDL::Start(const char * const *parm)
|
||||
--- src/video/sdl_v.cpp 2013-03-31 23:55:59.000000000 +0300
|
||||
+++ src/video/sdl_v.cpp 2013-04-04 21:26:10.534334178 +0300
|
||||
--- src/video/sdl_v.cpp 2013-05-31 23:56:34.000000000 +0300
|
||||
+++ src/video/sdl_v.cpp 2013-06-02 17:34:54.704814123 +0300
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "../fileio_func.h"
|
||||
#include "sdl_v.h"
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
We worship these two higher beings for making the original, legendary game:
|
||||
Fred Ford
|
||||
Paul Reiche III
|
||||
|
||||
|
||||
The Ur-Quan Masters port:
|
||||
-------------------------
|
||||
|
||||
Core team (in alphabetical order):
|
||||
Serge van den Boom <svdb@stack.nl>
|
||||
Mika Kolehmainen <mk@kapsi.fi>
|
||||
Michael Chapman Martin <mcmartin@gmail.com>
|
||||
Chris Nelson <chris@toysforbob.com>
|
||||
Alex Volkov <codepro@usa.net>
|
||||
|
||||
Additional programming (in alphabetical order):
|
||||
Geoffrey Hausheer <uqm-devel@phracturedblue.com>
|
||||
Nicolas Simonds <uqm@submedia.net>
|
||||
|
||||
Music remixers (in alphabetical order):
|
||||
Jouni Airaksinen <markvera@spacesynth.net>
|
||||
Tore Aune Fjellstad
|
||||
Espen Gätzschmann
|
||||
Aaron J. Grier <agrier@poofygoof.com>
|
||||
Dan Nicholson <dan@kosmic.org>
|
||||
George Nowik <norgio@attbi.com>
|
||||
Riku Nuottajärvi <riku.nuottajarvi@pp.inet.fi>
|
||||
Erol Otus <erol@toysforbob.com>
|
||||
|
||||
Other contributions (in alphabetical order):
|
||||
Jouni Airaksinen <markvera@spacesynth.net> (Startup Menu)
|
||||
Karl Bartel <karlb@gmx.net>
|
||||
Travis Chase <cftc@shaw.ca> (BeOS port)
|
||||
Felix Lazarev <felix@freedo.org> (3DO internals)
|
||||
Parker MacMillan
|
||||
Sanjay Madhav <madhav@usc.edu> (code patches)
|
||||
Robert McNamara <robert@americantenor.com> (MacOS X stuff)
|
||||
Mike Melanson (ADPCM basis from FFmpeg used for DUK audio)
|
||||
Mudrony Laszlo <mudronyl@dragon.klte.hu> (PC/DOS content unpacking)
|
||||
Erol Otus <erol@toysforbob.com> (Splash screen)
|
||||
Brian Rogers <burpmaster@truffula.net>
|
||||
Horatiu Romosan <hory@post.ro> (v0.1 Win32 installer)
|
||||
Zarla Sheenaza <astronia@aol.com> (0.6 Win32 installer graphics)
|
||||
Joffrey Smith (setup graphics)
|
||||
Peter van Valderen <p.vanvalderen@chello.nl>
|
||||
Alex Volkov <codepro@usa.net> (additional slides)
|
||||
Alexander Waseleski <Paxtez@hotmail.com> (code patches)
|
||||
Yukki (v0.1 Win32 installer graphics)
|
||||
|
||||
|
||||
Original game:
|
||||
--------------
|
||||
|
||||
Programming & technology:
|
||||
Fred Ford
|
||||
|
||||
Game design and fiction:
|
||||
Paul Reiche III
|
||||
|
||||
3DO programming:
|
||||
Ken Ford
|
||||
Fred Ford
|
||||
Brad Van Tighem
|
||||
|
||||
Producer (3DO version):
|
||||
Mark Wallace
|
||||
|
||||
3DO production:
|
||||
Paul Reiche III
|
||||
Richard Antaki
|
||||
|
||||
Starring the voices of:
|
||||
Richard Antaki ....... Thraddash
|
||||
Alex Bennett ......... Starbase Commander
|
||||
Rich Betz ............ Ariloulaleelay
|
||||
............ Druuge
|
||||
Roy Blumenfeld ....... Zoq-Fot-Pik
|
||||
David Bryce .......... Kohr-Ah
|
||||
.......... Ilwrath
|
||||
.......... Shofixti
|
||||
.......... Spathi
|
||||
Lauren Forcella ...... Supox
|
||||
Greg Johnson ......... Orz
|
||||
......... Pkunk
|
||||
......... Utwig
|
||||
Bruce Leyland ........ Yehat
|
||||
Erol Otus ............ Chmmr
|
||||
Paul Reiche III ...... Mycon
|
||||
...... Talking Pet
|
||||
Brad Van Tighem ...... Slylandro Speaker
|
||||
Madeleine Wild ....... Zoq-Fot-Pik
|
||||
....... Syreen
|
||||
....... VUX
|
||||
Larry Zee ............ Umgah
|
||||
............ Melnorme
|
||||
............ Ur-Quan
|
||||
840-AV ............... Slylandro Probe
|
||||
Paul II, Paul III .... Victory Sequence
|
||||
Arianna & Devin Reiche
|
||||
|
||||
Voice effects:
|
||||
Jeff Forehan
|
||||
Burke Treischmann
|
||||
Mark Miller
|
||||
|
||||
Voice editing:
|
||||
Richard Antaki
|
||||
Paul Reiche III
|
||||
Burke Treischmann
|
||||
Steve Henefin
|
||||
Jeremy Bredow
|
||||
Erik Griss
|
||||
Brad Van Tighem
|
||||
|
||||
Art and animation:
|
||||
George Barr
|
||||
Paul Reiche III
|
||||
Erol Otus
|
||||
Greg Johnson
|
||||
Kyle Balda
|
||||
Jeff Rianda
|
||||
Taunya Shiffer
|
||||
Leonard Robel
|
||||
Greg Hammond
|
||||
Armand Cabrera
|
||||
Silicon Knights
|
||||
|
||||
Additional writing:
|
||||
Greg Johnson
|
||||
Mat Genser
|
||||
Robert Leyland
|
||||
Iain McCaig
|
||||
Tomi Quintana
|
||||
Erol Otus
|
||||
Leonard Robel
|
||||
John Estes
|
||||
|
||||
Music:
|
||||
Burke Treischmann
|
||||
Dan Nicholson
|
||||
Riku Nuottajärvi
|
||||
Eric Berge
|
||||
Erol Otus
|
||||
Marc Brown
|
||||
Aaron Grier
|
||||
Kevin Palivec
|
||||
Tommy Dunbar
|
||||
|
||||
3D cinemagraphics:
|
||||
Gene Bodio
|
||||
Phil Le Marbre
|
||||
TrueMotion(R) "S" Video Compression by The Duck Corporation
|
||||
|
||||
Product marketing manager (3DO version):
|
||||
Jim Curry
|
||||
|
||||
3DO testers:
|
||||
Susan Michele
|
||||
Jeremy Bredow
|
||||
Wes Gittens
|
||||
Ty Johnson
|
||||
Tate Schieferle
|
||||
Carolina Esmurdoc
|
||||
Rob Johnson
|
||||
Kevin Kwan
|
||||
Joe Ganis
|
||||
Chang Fadel
|
||||
Erik Griss
|
||||
Eugene Law
|
||||
Mark Ybarra
|
||||
Steve Groll
|
||||
Tim Jordan
|
||||
Matt Young
|
||||
|
||||
PC/DOS testers:
|
||||
Pam Levins
|
||||
Tomi Quintana
|
||||
Joel Dinolt
|
||||
Robert Daly
|
||||
Greg Hammond
|
||||
B.J. Shea
|
||||
Robert Leyland
|
||||
Sean Vikoren
|
||||
Mike Ebert
|
||||
Tony Hsieh
|
||||
ROL
|
||||
Ed Gwynn
|
||||
Akila Redmer
|
||||
Russell Bornschlegel
|
||||
Steve Graziano
|
||||
Mark Voorsanger
|
||||
|
||||
Special thanks to:
|
||||
Greg Johnson
|
||||
John Ratcliffe
|
||||
|
||||
Paul's Foundation:
|
||||
Laurie
|
||||
Devin
|
||||
and Arianna
|
||||
|
||||
Got us 86'ed out of a restaurant in Las Vegas:
|
||||
Madeline Canepa (we love her anyway)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
LibSdlVersion=1.2
|
||||
AppName="Ur-Quan Masters"
|
||||
AppFullName=com.sourceforge.sc2
|
||||
ScreenOrientation=h
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="!!Game data (15 Mb)|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/sc2-data-5.zip/download^3DO remixed music (19 Mb) - enable it in Setup->Sound Options->3DO Remixes|:addons/3domusic/3domusic.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3domusic.zip/download^UQM music remix pack (150 Mb) - enable it in Setup->Sound Options->UQM Remixes|:addons/remix/remix.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/remix.zip/download^3DO voice (115 Mb) - go to Setup->Sound Options and increase Voice volume from zero|:addons/3dovoice/3dovoice.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovoice.zip/download^Russian translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/russian.zip/download^Deutsch translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/deutsch.zip/download^Spanish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/spanish.zip/download^Slovak translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/slovak.zip/download^Finnish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/finnish.zip/download^3DO video support - after installing this pack copy all files from|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovideo.zip/download^your 3DO Star Control II game CD from 'duckart' dir to the SD card to dir|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovideo.zip/download^'app-data/com.sourceforge.sc2/addons/3dovideo', to extract files from 3DO disk use|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovideo.zip/download^'3DO Commander' or 'uncd-rom' apps from http://madroms.free.fr/3do/|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovideo.zip/download^Then from the game change 'Setup->PC/3DO compat->Cutscenes' to Movies, and restart game|http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/3dovideo.zip/download"
|
||||
VideoDepthBpp=16
|
||||
NeedDepthBuffer=n
|
||||
NeedStencilBuffer=n
|
||||
NeedGles2=n
|
||||
SwVideoMode=y
|
||||
SdlVideoResize=y
|
||||
SdlVideoResizeKeepAspect=n
|
||||
CompatibilityHacks=n
|
||||
CompatibilityHacksStaticInit=n
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
AppUsesMouse=n
|
||||
AppNeedsTwoButtonMouse=n
|
||||
ShowMouseCursor=n
|
||||
ForceRelativeMouseMode=n
|
||||
AppNeedsArrowKeys=y
|
||||
AppNeedsTextInput=y
|
||||
AppUsesJoystick=y
|
||||
AppUsesAccelerometer=n
|
||||
AppUsesMultitouch=n
|
||||
NonBlockingSwapBuffers=n
|
||||
RedefinedKeys="RETURN RSHIFT NO_REMAP NO_REMAP RCTRL F10"
|
||||
AppTouchscreenKeyboardKeysAmount=2
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
RedefinedKeysScreenKb="RCTRL RSHIFT KP_PLUS KP_MINUS"
|
||||
StartupMenuButtonTimeout=3000
|
||||
HiddenMenuOptions=''
|
||||
FirstStartMenuOptions=''
|
||||
MultiABI=n
|
||||
AppMinimumRAM=0
|
||||
AppVersionCode=07023
|
||||
AppVersionName="0.7.0.23"
|
||||
ResetSdlConfigForThisVersion=y
|
||||
DeleteFilesOnUpgrade="%"
|
||||
CompiledLibraries="sdl_image tremor ogg"
|
||||
CustomBuildScript=n
|
||||
AppCflags='-O3 -DGFXMODULE_SDL -DOVCODEC_TREMOR -DNETPLAY=NETPLAY_FULL -DHAVE_JOYSTICK -DHAVE_ZIP=1 -DTHREADLIB_SDL -DUSE_INTERNAL_MIKMOD'
|
||||
AppLdflags=''
|
||||
AppOverlapsSystemHeaders=y
|
||||
AppSubdirsBuild='src src/libs/* src/uqm/*'
|
||||
AppBuildExclude='src/libs/uio/hashtable.c src/libs/uio/memdebug.c'
|
||||
AppCmdline='uqm --addon lang'
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
MinimumScreenSize=s
|
||||
AdmobPublisherId=n
|
||||
AdmobTestDeviceId=
|
||||
AdmobBannerSize=
|
||||
@@ -1,5 +0,0 @@
|
||||
All known bugs and missing features are listed in our online bug database,
|
||||
which can be found at
|
||||
http://bugs.uqm.stack.nl/
|
||||
New bugs that you may find can be reported at the same location.
|
||||
|
||||
@@ -1,944 +0,0 @@
|
||||
|
||||
The Ur-Quan Masters
|
||||
Copyright (C) 1992, 2002 Toys for Bob, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be entertaining,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details. A copy of the
|
||||
General Public License is included at the end of this document.
|
||||
|
||||
The content -- voiceovers, dialogue, graphics, sounds, and music --
|
||||
are copyright (C) 1992, 1993, 2002 Toys for Bob, Inc. or their
|
||||
respective creators. The content may be used freely under the
|
||||
terms of the Creative Commons Attribution-NonCommercial-ShareAlike
|
||||
2.5 license (included below, and also available at
|
||||
http://creativecommons.org/licenses/by-nc-sa/2.5/). The content
|
||||
may also be copied freely as part of a distribution of The Ur-Quan
|
||||
Masters.
|
||||
|
||||
The documentation -- excluding documentation that is part of the
|
||||
code or otherwise clearly governed by the preceding licenses --
|
||||
may be used freely under the terms of the Creative Commons
|
||||
Attribution 2.0 license (included below, and also available at
|
||||
http://creativecommons.org/licenses/by/2.0/).
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CREATIVE COMMONS LICENSE
|
||||
Attribution-NonCommercial-ShareAlike 2.5
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
|
||||
SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
|
||||
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS"
|
||||
BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION
|
||||
PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
|
||||
RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Collective Work" means a work, such as a periodical issue,
|
||||
anthology or encyclopedia, in which the Work in its entirety in
|
||||
unmodified form, along with a number of other contributions,
|
||||
constituting separate and independent works in themselves, are
|
||||
assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as
|
||||
defined below) for the purposes of this License.
|
||||
|
||||
b. "Derivative Work" means a work based upon the Work or upon the
|
||||
Work and other pre-existing works, such as a translation,
|
||||
musical arrangement, dramatization, fictionalization, motion
|
||||
picture version, sound recording, art reproduction, abridgment,
|
||||
condensation, or any other form in which the Work may be recast,
|
||||
transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the
|
||||
purpose of this License. For the avoidance of doubt, where the
|
||||
Work is a musical composition or sound recording, the
|
||||
synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the
|
||||
purpose of this License.
|
||||
|
||||
c. "Licensor" means the individual or entity that offers the Work
|
||||
under the terms of this License.
|
||||
|
||||
d. "Original Author" means the individual or entity who created the
|
||||
Work.
|
||||
|
||||
e. "Work" means the copyrightable work of authorship offered under
|
||||
the terms of this License.
|
||||
|
||||
f. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this
|
||||
License with respect to the Work, or who has received express
|
||||
permission from the Licensor to exercise rights under this
|
||||
License despite a previous violation.
|
||||
|
||||
g. "License Elements" means the following high-level license
|
||||
attributes as selected by Licensor and indicated in the title of
|
||||
this License: Attribution, Noncommercial, ShareAlike.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce,
|
||||
limit, or restrict any rights arising from fair use, first sale or
|
||||
other limitations on the exclusive rights of the copyright owner
|
||||
under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-exclusive, perpetual (for the duration of the applicable
|
||||
copyright) license to exercise the rights in the Work as stated
|
||||
below:
|
||||
|
||||
a. to reproduce the Work, to incorporate the Work into one or more
|
||||
Collective Works, and to reproduce the Work as incorporated in
|
||||
the Collective Works;
|
||||
|
||||
b. to create and reproduce Derivative Works;
|
||||
|
||||
c. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission the Work including as incorporated in
|
||||
Collective Works;
|
||||
|
||||
d. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission Derivative Works;
|
||||
|
||||
The above rights may be exercised in all media and formats whether
|
||||
now known or hereafter devised. The above rights include the right
|
||||
to make such modifications as are technically necessary to exercise
|
||||
the rights in other media and formats. All rights not expressly
|
||||
granted by Licensor are hereby reserved, including but not limited
|
||||
to the rights set forth in Sections 4(e) and 4(f).
|
||||
|
||||
4. Restrictions.
|
||||
|
||||
The license granted in Section 3 above is expressly made subject to and
|
||||
limited by the following restrictions:
|
||||
|
||||
a. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work only under the terms of this
|
||||
License, and You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License with every copy or phonorecord of
|
||||
the Work You distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform. You may not offer or impose any
|
||||
terms on the Work that alter or restrict the terms of this
|
||||
License or the recipients' exercise of the rights granted
|
||||
hereunder. You may not sublicense the Work. You must keep intact
|
||||
all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Work with any
|
||||
technological measures that control access or use of the Work in
|
||||
a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Work as incorporated in a
|
||||
Collective Work, but this does not require the Collective Work
|
||||
apart from the Work itself to be made subject to the terms of
|
||||
this License. If You create a Collective Work, upon notice from
|
||||
any Licensor You must, to the extent practicable, remove from
|
||||
the Collective Work any credit as required by clause 4(d), as
|
||||
requested. If You create a Derivative Work, upon notice from any
|
||||
Licensor You must, to the extent practicable, remove from the
|
||||
Derivative Work any credit as required by clause 4(d), as
|
||||
requested.
|
||||
|
||||
b. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform a Derivative Work only under the
|
||||
terms of this License, a later version of this License with the
|
||||
same License Elements as this License, or a Creative Commons
|
||||
iCommons license that contains the same License Elements as this
|
||||
License (e.g. Attribution-NonCommercial-ShareAlike 2.5
|
||||
Japan). You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License or other license specified in the
|
||||
previous sentence with every copy or phonorecord of each
|
||||
Derivative Work You distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform. You may not offer or
|
||||
impose any terms on the Derivative Works that alter or restrict
|
||||
the terms of this License or the recipients' exercise of the
|
||||
rights granted hereunder, and You must keep intact all notices
|
||||
that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Derivative Work with
|
||||
any technological measures that control access or use of the
|
||||
Work in a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Derivative Work as
|
||||
incorporated in a Collective Work, but this does not require the
|
||||
Collective Work apart from the Derivative Work itself to be made
|
||||
subject to the terms of this License.
|
||||
|
||||
c. You may not exercise any of the rights granted to You in Section
|
||||
3 above in any manner that is primarily intended for or directed
|
||||
toward commercial advantage or private monetary
|
||||
compensation. The exchange of the Work for other copyrighted
|
||||
works by means of digital file-sharing or otherwise shall not be
|
||||
considered to be intended for or directed toward commercial
|
||||
advantage or private monetary compensation, provided there is no
|
||||
payment of any monetary compensation in connection with the
|
||||
exchange of copyrighted works.
|
||||
|
||||
d. If you distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work or any Derivative Works or
|
||||
Collective Works, You must keep intact all copyright notices for
|
||||
the Work and provide, reasonable to the medium or means You are
|
||||
utilizing: (i) the name of the Original Author (or pseudonym, if
|
||||
applicable) if supplied, and/or (ii) if the Original Author
|
||||
and/or Licensor designate another party or parties (e.g. a
|
||||
sponsor institute, publishing entity, journal) for attribution
|
||||
in Licensor's copyright notice, terms of service or by other
|
||||
reasonable means, the name of such party or parties; the title
|
||||
of the Work if supplied; to the extent reasonably practicable,
|
||||
the Uniform Resource Identifier, if any, that Licensor specifies
|
||||
to be associated with the Work, unless such URI does not refer
|
||||
to the copyright notice or licensing information for the Work;
|
||||
and in the case of a Derivative Work, a credit identifying the
|
||||
use of the Work in the Derivative Work (e.g., "French
|
||||
translation of the Work by Original Author," or "Screenplay
|
||||
based on original Work by Original Author"). Such credit may be
|
||||
implemented in any reasonable manner; provided, however, that in
|
||||
the case of a Derivative Work or Collective Work, at a minimum
|
||||
such credit will appear where any other comparable authorship
|
||||
credit appears and in a manner at least as prominent as such
|
||||
other comparable authorship credit.
|
||||
|
||||
e. For the avoidance of doubt, where the Work is a musical composition:
|
||||
|
||||
i. Performance Royalties Under Blanket Licenses. Licensor
|
||||
reserves the exclusive right to collect, whether
|
||||
individually or via a performance rights society
|
||||
(e.g. ASCAP, BMI, SESAC), royalties for the public
|
||||
performance or public digital performance (e.g. webcast)
|
||||
of the Work if that performance is primarily intended for
|
||||
or directed toward commercial advantage or private
|
||||
monetary compensation.
|
||||
|
||||
ii. Mechanical Rights and Statutory Royalties. Licensor
|
||||
reserves the exclusive right to collect, whether
|
||||
individually or via a music rights agency or designated
|
||||
agent (e.g. Harry Fox Agency), royalties for any
|
||||
phonorecord You create from the Work ("cover version")
|
||||
and distribute, subject to the compulsory license created
|
||||
by 17 USC Section 115 of the US Copyright Act (or the
|
||||
equivalent in other jurisdictions), if Your distribution
|
||||
of such cover version is primarily intended for or
|
||||
directed toward commercial advantage or private monetary
|
||||
compensation.
|
||||
|
||||
f. Webcasting Rights and Statutory Royalties. For the avoidance of
|
||||
doubt, where the Work is a sound recording, Licensor reserves
|
||||
the exclusive right to collect, whether individually or via a
|
||||
performance-rights society (e.g. SoundExchange), royalties for
|
||||
the public digital performance (e.g. webcast) of the Work,
|
||||
subject to the compulsory license created by 17 USC Section 114
|
||||
of the US Copyright Act (or the equivalent in other
|
||||
jurisdictions), if Your public digital performance is primarily
|
||||
intended for or directed toward commercial advantage or private
|
||||
monetary compensation.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING,
|
||||
LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR
|
||||
WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED,
|
||||
STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF
|
||||
TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,
|
||||
OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
|
||||
WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability.
|
||||
|
||||
EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||
LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT
|
||||
OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this
|
||||
License. Individuals or entities who have received Derivative
|
||||
Works or Collective Works from You under this License, however,
|
||||
will not have their licenses terminated provided such
|
||||
individuals or entities remain in full compliance with those
|
||||
licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any
|
||||
termination of this License.
|
||||
|
||||
b. Subject to the above terms and conditions, the license granted
|
||||
here is perpetual (for the duration of the applicable copyright
|
||||
in the Work). Notwithstanding the above, Licensor reserves the
|
||||
right to release the Work under different license terms or to
|
||||
stop distributing the Work at any time; provided, however that
|
||||
any such election will not serve to withdraw this License (or
|
||||
any other license that has been, or is required to be, granted
|
||||
under the terms of this License), and this License will continue
|
||||
in full force and effect unless terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You distribute or publicly digitally perform the Work
|
||||
or a Collective Work, the Licensor offers to the recipient a
|
||||
license to the Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
b. Each time You distribute or publicly digitally perform a
|
||||
Derivative Work, Licensor offers to the recipient a license to
|
||||
the original Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
c. If any provision of this License is invalid or unenforceable
|
||||
under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this License,
|
||||
and without further action by the parties to this agreement,
|
||||
such provision shall be reformed to the minimum extent necessary
|
||||
to make such provision valid and enforceable.
|
||||
|
||||
d. No term or provision of this License shall be deemed waived and
|
||||
no breach consented to unless such waiver or consent shall be in
|
||||
writing and signed by the party to be charged with such waiver
|
||||
or consent.
|
||||
|
||||
e. This License constitutes the entire agreement between the
|
||||
parties with respect to the Work licensed here. There are no
|
||||
understandings, agreements or representations with respect to
|
||||
the Work not specified here. Licensor shall not be bound by any
|
||||
additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written
|
||||
agreement of the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, neither party will use the trademark
|
||||
"Creative Commons" or any related trademark or logo of Creative
|
||||
Commons without the prior written consent of Creative Commons. Any
|
||||
permitted use will be in compliance with Creative Commons'
|
||||
then-current trademark usage guidelines, as may be published on its
|
||||
website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
CREATIVE COMMONS LICENSE ATTRIBUTION-2.0
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
|
||||
CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS
|
||||
PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE
|
||||
WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
|
||||
PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
|
||||
AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS
|
||||
YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF
|
||||
SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Collective Work" means a work, such as a periodical issue,
|
||||
anthology or encyclopedia, in which the Work in its entirety in
|
||||
unmodified form, along with a number of other contributions,
|
||||
constituting separate and independent works in themselves, are
|
||||
assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as
|
||||
defined below) for the purposes of this License.
|
||||
|
||||
b. "Derivative Work" means a work based upon the Work or upon the
|
||||
Work and other pre-existing works, such as a translation,
|
||||
musical arrangement, dramatization, fictionalization, motion
|
||||
picture version, sound recording, art reproduction, abridgment,
|
||||
condensation, or any other form in which the Work may be recast,
|
||||
transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the
|
||||
purpose of this License. For the avoidance of doubt, where the
|
||||
Work is a musical composition or sound recording, the
|
||||
synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the
|
||||
purpose of this License.
|
||||
|
||||
c. "Licensor" means the individual or entity that offers the Work
|
||||
under the terms of this License.
|
||||
|
||||
d. "Original Author" means the individual or entity who created the
|
||||
Work.
|
||||
|
||||
e. "Work" means the copyrightable work of authorship offered under
|
||||
the terms of this License.
|
||||
|
||||
f. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this
|
||||
License with respect to the Work, or who has received express
|
||||
permission from the Licensor to exercise rights under this
|
||||
License despite a previous violation.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce,
|
||||
limit, or restrict any rights arising from fair use, first sale or
|
||||
other limitations on the exclusive rights of the copyright owner
|
||||
under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-exclusive, perpetual (for the duration of the applicable
|
||||
copyright) license to exercise the rights in the Work as stated
|
||||
below:
|
||||
|
||||
a. to reproduce the Work, to incorporate the Work into one or more
|
||||
Collective Works, and to reproduce the Work as incorporated in
|
||||
the Collective Works;
|
||||
|
||||
b. to create and reproduce Derivative Works;
|
||||
|
||||
c. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission the Work including as incorporated in
|
||||
Collective Works;
|
||||
|
||||
d. to distribute copies or phonorecords of, display publicly,
|
||||
perform publicly, and perform publicly by means of a digital
|
||||
audio transmission Derivative Works.
|
||||
|
||||
e. For the avoidance of doubt, where the work is a musical
|
||||
composition:
|
||||
|
||||
i. Performance Royalties Under Blanket Licenses. Licensor
|
||||
waives the exclusive right to collect, whether
|
||||
individually or via a performance rights society
|
||||
(e.g. ASCAP, BMI, SESAC), royalties for the public
|
||||
performance or public digital performance (e.g. webcast)
|
||||
of the Work.
|
||||
|
||||
ii. Mechanical Rights and Statutory Royalties. Licensor
|
||||
waives the exclusive right to collect, whether
|
||||
individually or via a music rights agency or designated
|
||||
agent (e.g. Harry Fox Agency), royalties for any
|
||||
phonorecord You create from the Work ("cover version")
|
||||
and distribute, subject to the compulsory license created
|
||||
by 17 USC Section 115 of the US Copyright Act (or the
|
||||
equivalent in other jurisdictions).
|
||||
|
||||
f. Webcasting Rights and Statutory Royalties. For the avoidance of
|
||||
doubt, where the Work is a sound recording, Licensor waives the
|
||||
exclusive right to collect, whether individually or via a
|
||||
performance-rights society (e.g. SoundExchange), royalties for
|
||||
the public digital performance (e.g. webcast) of the Work,
|
||||
subject to the compulsory license created by 17 USC Section 114
|
||||
of the US Copyright Act (or the equivalent in other
|
||||
jurisdictions).
|
||||
|
||||
The above rights may be exercised in all media and formats whether
|
||||
now known or hereafter devised. The above rights include the right
|
||||
to make such modifications as are technically necessary to exercise
|
||||
the rights in other media and formats. All rights not expressly
|
||||
granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly
|
||||
made subject to and limited by the following restrictions:
|
||||
|
||||
a. You may distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work only under the terms of this
|
||||
License, and You must include a copy of, or the Uniform Resource
|
||||
Identifier for, this License with every copy or phonorecord of
|
||||
the Work You distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform. You may not offer or impose any
|
||||
terms on the Work that alter or restrict the terms of this
|
||||
License or the recipients' exercise of the rights granted
|
||||
hereunder. You may not sublicense the Work. You must keep intact
|
||||
all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform the Work with any
|
||||
technological measures that control access or use of the Work in
|
||||
a manner inconsistent with the terms of this License
|
||||
Agreement. The above applies to the Work as incorporated in a
|
||||
Collective Work, but this does not require the Collective Work
|
||||
apart from the Work itself to be made subject to the terms of
|
||||
this License. If You create a Collective Work, upon notice from
|
||||
any Licensor You must, to the extent practicable, remove from
|
||||
the Collective Work any reference to such Licensor or the
|
||||
Original Author, as requested. If You create a Derivative Work,
|
||||
upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Derivative Work any reference to
|
||||
such Licensor or the Original Author, as requested.
|
||||
|
||||
b. If you distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work or any Derivative Works or
|
||||
Collective Works, You must keep intact all copyright notices for
|
||||
the Work and give the Original Author credit reasonable to the
|
||||
medium or means You are utilizing by conveying the name (or
|
||||
pseudonym if applicable) of the Original Author if supplied; the
|
||||
title of the Work if supplied; to the extent reasonably
|
||||
practicable, the Uniform Resource Identifier, if any, that
|
||||
Licensor specifies to be associated with the Work, unless such
|
||||
URI does not refer to the copyright notice or licensing
|
||||
information for the Work; and in the case of a Derivative Work,
|
||||
a credit identifying the use of the Work in the Derivative Work
|
||||
(e.g., "French translation of the Work by Original Author," or
|
||||
"Screenplay based on original Work by Original Author"). Such
|
||||
credit may be implemented in any reasonable manner; provided,
|
||||
however, that in the case of a Derivative Work or Collective
|
||||
Work, at a minimum such credit will appear where any other
|
||||
comparable authorship credit appears and in a manner at least as
|
||||
prominent as such other comparable authorship credit.
|
||||
|
||||
5. Representations, Warranties and Disclaimer. UNLESS OTHERWISE
|
||||
MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK
|
||||
AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
|
||||
CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF
|
||||
ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW
|
||||
THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY
|
||||
TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY
|
||||
APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY
|
||||
LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE
|
||||
OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE
|
||||
WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this
|
||||
License. Individuals or entities who have received Derivative
|
||||
Works or Collective Works from You under this License, however,
|
||||
will not have their licenses terminated provided such
|
||||
individuals or entities remain in full compliance with those
|
||||
licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any
|
||||
termination of this License.
|
||||
|
||||
b. Subject to the above terms and conditions, the license granted
|
||||
here is perpetual (for the duration of the applicable copyright
|
||||
in the Work). Notwithstanding the above, Licensor reserves the
|
||||
right to release the Work under different license terms or to
|
||||
stop distributing the Work at any time; provided, however that
|
||||
any such election will not serve to withdraw this License (or
|
||||
any other license that has been, or is required to be, granted
|
||||
under the terms of this License), and this License will continue
|
||||
in full force and effect unless terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You distribute or publicly digitally perform the Work
|
||||
or a Collective Work, the Licensor offers to the recipient a
|
||||
license to the Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
b. Each time You distribute or publicly digitally perform a
|
||||
Derivative Work, Licensor offers to the recipient a license to
|
||||
the original Work on the same terms and conditions as the
|
||||
license granted to You under this License.
|
||||
|
||||
c. If any provision of this License is invalid or unenforceable
|
||||
under applicable law, it shall not affect the validity or
|
||||
enforceability of the remainder of the terms of this License,
|
||||
and without further action by the parties to this agreement,
|
||||
such provision shall be reformed to the minimum extent necessary
|
||||
to make such provision valid and enforceable.
|
||||
|
||||
d. No term or provision of this License shall be deemed waived and
|
||||
no breach consented to unless such waiver or consent shall be in
|
||||
writing and signed by the party to be charged with such waiver
|
||||
or consent.
|
||||
|
||||
e. This License constitutes the entire agreement between the
|
||||
parties with respect to the Work licensed here. There are no
|
||||
understandings, agreements or representations with respect to
|
||||
the Work not specified here. Licensor shall not be bound by any
|
||||
additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written
|
||||
agreement of the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, neither party will use the trademark
|
||||
"Creative Commons" or any related trademark or logo of Creative
|
||||
Commons without the prior written consent of Creative Commons. Any
|
||||
permitted use will be in compliance with Creative Commons'
|
||||
then-current trademark usage guidelines, as may be published on its
|
||||
website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
These are some guidelines for people who want to contribute to the code.
|
||||
Don't be surprised if your contributions get tossed in the bit-bucket if you
|
||||
do not follow them. We don't want to be unfriendly, but our time is limited.
|
||||
These guidelines are there so that you won't waste both our and your time.
|
||||
|
||||
Before making changes:
|
||||
- Read this entire document
|
||||
- See if the the Bugzilla bug database at
|
||||
http://bugs.uqm.stack.nl/ contains any comments on what you're planning
|
||||
to do.
|
||||
- Make sure you're using the most recent Subversion version
|
||||
- Discuss in advance what you're planning to do, with the core team.
|
||||
The best place to do this is on #sc2 on irc.freenode.net.
|
||||
This prevents you from wasting your time when
|
||||
- someone else is already working on your issue
|
||||
- we've got a very clear idea of how we want it to be
|
||||
- the code you're planning to change will be completely rewritten
|
||||
in the near future.
|
||||
- Don't bother on adding "great ideas" you have for the game;
|
||||
Our current goal is a straight port. The code is GPL, so feel free
|
||||
to start your own modified version, but don't bother sending them
|
||||
in for the official version.
|
||||
|
||||
Making changes:
|
||||
- Follow the coding style of the existing source. You don't have to like it,
|
||||
we don't even always do, but we've accepted this as our standard. The main
|
||||
reason is that this is very close to the original style.
|
||||
Trying to start a discussion about the standard is pointless and is
|
||||
definately NOT appreciated.
|
||||
- Use 1 tab per indentation level
|
||||
- Use no more than 76 chars on a line, when using a tabsize of 4.
|
||||
- Use 2 extra indentation levels for the continuation of a broken line,
|
||||
like this:
|
||||
if (blablablabla || foobar ||
|
||||
zut || linefiller ||
|
||||
morezut)
|
||||
printf ("Yeah!\n");
|
||||
- Don't use tabs for anything but indenting. If you would, and someone
|
||||
has a different tab size, or something in the line changes, other stuff
|
||||
on the line may or may not move, depending on where on the line it is.
|
||||
If you for instance want to align a list of declarations, use spaces,
|
||||
like this:
|
||||
{
|
||||
<TAB>long l,
|
||||
<TAB> m;
|
||||
<TAB>int i;
|
||||
}
|
||||
(Though in this particular case, I personally would repeat the 'long',
|
||||
or place l and m on the same line)
|
||||
- Put { on a seperate line, both for the start of a function and
|
||||
for the start of a block.
|
||||
- one space around binary operators, and after commas.
|
||||
- one space between the function name and following '(', both in
|
||||
declaration and call (unusual as it is).
|
||||
- one space after 'if', 'while', 'do', 'for' and 'switch'.
|
||||
- even for short selections or repetitions, don't have the statement
|
||||
to execute on the same line as the guard. So:
|
||||
if (a)
|
||||
a--;
|
||||
- Use unix-style line-endings, that is '\n' only. If the editor you're
|
||||
using doesn't support this, please pass your code through a conversion
|
||||
program before submitting.
|
||||
- Don't hurry into changing code. All code is there for a reason. Be sure
|
||||
you understand that reason before changing it. Don't just go recode a part
|
||||
because you think that would be easier than trying to understand the
|
||||
original. If you don't have the skills or patience to do so, this is not
|
||||
the place for you.
|
||||
- Only use portable functions. The code is intended to work on Windows,
|
||||
Linux, FreeBSD, BeOS and MacOS X.
|
||||
Try to avoid unnecessary system-dependant code, but use #ifdefs if you
|
||||
really have to.
|
||||
- No shortcuts. Don't assume anything about user input (like the length),
|
||||
and check the return values of functions that may fail.
|
||||
- Your code shouldn't cause any compile-time or runtime-warnings. We know
|
||||
the current source is far from warning-free, but those should be removed
|
||||
eventually and we don't want to make it worse.
|
||||
- Don't add comment lines saying things like "This line added by <me>".
|
||||
These comments only foul the code and don't add anything for people
|
||||
reading it. You'll still be credited in the Changelog, and for large
|
||||
contributions (or many small ones) in the authors list. We have
|
||||
Subversion for when we need to find out when what changes were made.
|
||||
|
||||
Making the patches:
|
||||
- One issue per patch.
|
||||
We need to keep track of what's being changed, and multiple changes
|
||||
in one patch will make that more difficult.
|
||||
Also, we might want to accept one patch, and reject the other.
|
||||
- Use unified diffs.
|
||||
That way, there's a bigger chance the patch can be automatically applied
|
||||
successfully against modified files.
|
||||
- Make the patches against the current Subversion tree.
|
||||
|
||||
Test the patches:
|
||||
- If possible, test your changes both on Windows and a *nix platform, or
|
||||
send them to someone to test them for you.
|
||||
|
||||
Getting the patches committed:
|
||||
- Either attach the patches to the appropriate bug report in the Bugzilla
|
||||
bug database or send them to one of the committers, in plain-text format.
|
||||
This can be done by email, DCC from within the #sc2 channel, or by
|
||||
mentioning an URL where we can get the patch.
|
||||
The committers are listed below (in alphabetical order), with their
|
||||
particular field of expertise with the source. Though all of us
|
||||
should have enough experience to deal with most issues not explicitely
|
||||
mentioned.
|
||||
Serge van den Boom (svdb at stack.nl), Meep-Eep at #sc2
|
||||
- Resource system
|
||||
- 3DO historical code
|
||||
- *nix build system
|
||||
- Netplay
|
||||
- General issues (particularly on *nix)
|
||||
Mika Kolehmainen (mk at kapsi.fi), Gwl at #sc2
|
||||
- Graphics
|
||||
- Sound
|
||||
- General issues
|
||||
Michael Martin (mcmartin at stanford.edu), McMartin at #sc2
|
||||
- Threading
|
||||
- Alien communications code
|
||||
- Graphics
|
||||
- Input system
|
||||
- In-game configuration
|
||||
- General issues
|
||||
Alex Volkov (codepro at usa.net), fOSSiL at #sc2
|
||||
- Graphics
|
||||
- Sound (particularly MixSDL)
|
||||
- General issues
|
||||
- Only submit code that can be used under the GPL. By submitting code you
|
||||
hold the copyright to, you agree that it can be used under the term of
|
||||
the GPL. If you use code by someone else, make sure that it can be used
|
||||
under the GPL and let us know, so that adequate credit can be given.
|
||||
|
||||
|
||||
Initial version of this file by Serge van den Boom, 2002-12-05.
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
You're looking at the readme for 'The Ur-Quan Masters', a volunteer
|
||||
project that intends to bring the classic game 'Star Control II' to
|
||||
modern systems.
|
||||
|
||||
The program code that comprises 'The Ur-Quan Masters' was derived from code
|
||||
written by Toys for Bob, Inc. for the 3DO version of 'Star Control II', with
|
||||
their permission and encouragement.
|
||||
|
||||
If you've got this file from the source tree, you can find everything
|
||||
you need to get started in INSTALL (INSTALL.mingw for MinGW) and
|
||||
doc/users/unixinstall.
|
||||
|
||||
The home page of the project is located at http://sc2.sourceforge.net/
|
||||
You can find links to downloads, our bug database, and our forum there.
|
||||
|
||||
Have fun!
|
||||
|
||||
|
||||
Star Control II is a registered trademark of Accolade, Inc.
|
||||
All other trademarks and tradenames belong to their respective owners.
|
||||
|
||||
@@ -1,370 +0,0 @@
|
||||
This file tries to organize and describe the changes between releases.
|
||||
Changes are broadly classified into the following categories:
|
||||
|
||||
- New Features: These are either elements of the original games that
|
||||
were first implemented in this release, or actually new capabilities
|
||||
that are visible to the user.
|
||||
|
||||
- Bugfixes: The removal of visible Bad Things from the code.
|
||||
|
||||
- Internal Changes: The removal of invisible Bad Things from the code,
|
||||
or changes in the way the program itself is structured. These are
|
||||
unlikely to be of interest to you unless you plan on coding
|
||||
extensions.
|
||||
|
||||
Version 0.6
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Netplay! You can now engage in Super Melee over the Internet.
|
||||
- Key configuration is now entirely in-game.
|
||||
- UQM now compiles and runs on 64-bit systems.
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- The Quit button (F10) now works properly when used during the
|
||||
introduction sequence.
|
||||
- Various small fixes to text and conversation logic.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- The setup menu now reads all its text from the content, easing
|
||||
translation.
|
||||
- The MOD player for PC-style music can now be linked against an
|
||||
external version of libmikmod.
|
||||
- Various code cleanups and memory optimizations.
|
||||
|
||||
Version 0.5
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- The Starmap is searchable! Type / then the beginning of the
|
||||
constellation name, and you can tab through all possible
|
||||
completions.
|
||||
- New 'hq' scaler, based on Maxim Stepin's "HQ2X" scaler. See
|
||||
www.hiend3d.com/hq2x.html for more details.
|
||||
- Scalers can use MMX/SSE/3DNow! instructions for significant speed
|
||||
improvements. The "Processor pack" is necessary for compilation of
|
||||
same on VC6.
|
||||
- Imported DOS versions of many graphics; these have richer palettes
|
||||
and so generally look better
|
||||
- There's a proper credit roll at the end of the game now.
|
||||
- Superior Planet handling: topographical maps scaled far more
|
||||
precisely; optional 3DO-style throbbing slave shield; planets are
|
||||
finally rotating spheres instead of spotlit cylinders or rectangles.
|
||||
The old PC-style "Entering Planetary Orbit..." screen is back.
|
||||
- Setup Menu far more complete and easy to use, and selections made in
|
||||
the Setup Menu will actually persist when you restart the program
|
||||
- Added support for the Tremor Ogg Vorbis decoder (avoids floating point
|
||||
math)
|
||||
- Home, End and BackSpace keys work as you'd expect in text input.
|
||||
- Most of the game works with Unicode properly now, and so, with proper
|
||||
font characters installed, will work with non-Latin alphabets. (On
|
||||
Windows, Unicode input requires a very recent version of SDL.)
|
||||
- Text may be input with the joystick again, as on the 3DO. The
|
||||
available characters are stored in content/lbm/joyalpha.txt.
|
||||
- The intro now plays only when a new game is started.
|
||||
- Color depth is now determined entirely automatically.
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Only SELECT and CANCEL trigger the fade-to-black at the end of a
|
||||
Super Melee, solving the issue of invisible "Really Quit?" menus for
|
||||
Super Melee. The "quit during fades" problem in general is still
|
||||
extant.
|
||||
- Many dialog, and comm animation, and general graphical fixes
|
||||
- Keypress status is not reset when entering battle mode, so (for
|
||||
instance) Melnorme ships can continue to charge a shot across
|
||||
battles.
|
||||
- The Melnorme would occasionally strip off Plot Points as part of a
|
||||
fuel deal. No longer.
|
||||
- Bugs in the original code prevented certain ships from properly
|
||||
spawning in "uncontrolled" space. The "wilds" are now a bit wilder,
|
||||
as apparently originally intended.
|
||||
- Venus's atmospheric density was incorrectly corrected in the 3DO
|
||||
version. It's been correctly corrected now.
|
||||
- Scheduled plot events work properly, even when the game suddenly
|
||||
skips ahead in time.
|
||||
- Fixed version checking in unix build scripts. SDL 1.2.10 is now
|
||||
recognised as newer than 1.2.9.
|
||||
- Spliced communications can be safely skipped past now.
|
||||
- Fixed fast escape weirdness (bug #619)
|
||||
- Threading system no longer assumes that there is no thread 0; this
|
||||
permits compilation on AmigaOS.
|
||||
- Relative paths and fallback paths work properly now.
|
||||
- Scalers now use surface pitch instead of image width - this is
|
||||
reported to solve many strange display problems in non-OpenGL mode
|
||||
on Macs
|
||||
- Ending sequences may now be safely paused.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Added the rest of devel/ and users/ documentation into MSVC .dsp
|
||||
files.
|
||||
- Control scheme upgraded. Old versions of keys.cfg will no longer
|
||||
work.
|
||||
- PNG transparency info (tRNS chunk) is now set properly, based on
|
||||
info in the .ani files.
|
||||
- Paletted images should render much faster now, and collisions
|
||||
between mods are less likely.
|
||||
- New font engine: fonts are loaded and treated as alpha-channel-only
|
||||
images, with font effects handled as backing images.
|
||||
- Melee works properly with alpha-channel graphics new, even when
|
||||
mipmapped.
|
||||
- Lander report drawing handled more sensibly now
|
||||
- Binary resource indexes have been replaced with textual ones.
|
||||
- All spritework is done internally in 32BPP.
|
||||
- Removed MikMod i/o hacks.
|
||||
- The temp files for representing star and group data are now kept in
|
||||
memory instead.
|
||||
- Separate config_win.h file for build.sh builds on Windows
|
||||
- Lowered some animation rates to reasonable levels, lowering CPU
|
||||
usage.
|
||||
- Changed comm subtitle caching scheme. Should kill the "blue comm
|
||||
screen" problem forever.
|
||||
- Refactored setup menu code to use generic widgets.
|
||||
- Cleaner build output. Set '$MAKE_VERBOSE' to 1 for old output.
|
||||
- Improved dependency tracking for unix build system. "./build.sh uqm
|
||||
depend" is now only needed for checking for new source files.
|
||||
|
||||
Version 0.4
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Savegame slot defaults to the last one used during this play
|
||||
- PC intro and ending sequence are now present
|
||||
- 3DO intro and ending movies are supported for those who have these
|
||||
movies from the 3DO CD of Star Control II
|
||||
- Improved slave shield graphics
|
||||
- Added a new -l option to produce logfiles
|
||||
- Added a new 'triscan' scaler derived from scale2x
|
||||
- Made the fact that self-destructing ships grant resources more obvious
|
||||
- Added a "config dir" option for holding saves and melee information
|
||||
- Cocoa hooks
|
||||
- Setup menu now permits configuration of some options. They do not
|
||||
yet persist past program quit, though.
|
||||
- Added a "--version" option
|
||||
- Melee images are now based on the (richer) DOS content
|
||||
- 3-step melee zooming as per the PC version is now implemented
|
||||
- It is now possible to complete the game without ever allying with the
|
||||
Starbase (if one is insane; this is known on the forum as "Beating The
|
||||
Game Differently" - but bugs and plot elements preventing this have been
|
||||
fixed or evaded under this circumstance).
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Fixes to the Quit Confirmation dialog
|
||||
- Collisions/encounters with "invisible" fleeing ships gone
|
||||
- Other ships insystem remain in proper locations after planet landing
|
||||
- Fixed some keyboard "focus" problems where flight controls were
|
||||
being cleared at inappropriate times, or interfering with menus
|
||||
- Graphics fixes
|
||||
- Subtitle timings work in the absence of oggs
|
||||
- Conversation summaries with Melnorme no longer crash
|
||||
- --contentdir argument may now have spaces
|
||||
- $HOME isn't required for Unix systems anymore
|
||||
- Fuel estimates fixed (original bug)
|
||||
- Fuel usage on planet landing now correcly reported on all versions
|
||||
- MOD music will play on big-endian machines under high-quality now
|
||||
- Space marines die in a self-destructing Scout
|
||||
- ZFP speech is properly vertically aligned now
|
||||
- Various odd behaviors when loading in HyperSpace now fixed
|
||||
- Quitting from the Roster screen no longer crashes
|
||||
- Many dialog fixes
|
||||
- The "Blue Comm Screen" problem no longer occurs
|
||||
- Combat Energy computation in Outfit Flagship screen corrected
|
||||
- A game crash that manifested when pausing after 85 minutes has been
|
||||
corrected
|
||||
- Main menu version number drawn more consistently
|
||||
- Transparency bugfixes - 3DO ending credits, planets in battle
|
||||
- Content packs may also be named ".uqm" - these are really still
|
||||
zip files, but you can't expand them by accident.
|
||||
- One may now configure a joystick without crashing the game if the
|
||||
joystick is not present
|
||||
- Music volume normalized throughout the game
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Thread system completely reworked to provide more detailed thread
|
||||
information, and to prevent resource leaks
|
||||
- Sound code is now virtualized and separate from game logic
|
||||
- Fine-grained control of menu sounds
|
||||
- Input system fully unified - all parts of the game use the same
|
||||
basic structure now
|
||||
- Build scripts made more robust
|
||||
- Window-drawing code was lifted out of confirm.c and made more general
|
||||
- Lots of debugging functions
|
||||
- Unicode support for game dialogs and fonts
|
||||
- Lots of code cleanups
|
||||
- Documentation of more internals
|
||||
|
||||
|
||||
Version 0.3
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- PC-style shipyard graphics, complete with animated power lines
|
||||
- Selling ships in the shipyards has slightly different controls
|
||||
that make it harder to sell ships accidentally
|
||||
- Main menu displays version number
|
||||
- Added a '-g' option to control gamma correction
|
||||
- Planet spin has been improved
|
||||
- Trilinear (mipmap-based) scaling in melee
|
||||
- PC-style conversation summaries have been implemented
|
||||
- Ship location display in status bar matches original more closely
|
||||
- Game flags (such as AWARE_OF_SAMATRA) that were ignored by half the
|
||||
game (even in the original) now are more universally available
|
||||
- Oscilloscope and Mini-Map have borders now
|
||||
- Commander Hayes won't let you rescue him until he's explained his
|
||||
predicament
|
||||
- Confirmation dialogs are now menu-based
|
||||
- Positional sound effects are available for OpenAL
|
||||
- Delete key works on Super-Melee team editing
|
||||
- Exit key from the Main Menu will quit the game
|
||||
- Quit option available in GAME menu
|
||||
- New Main Menu graphics: Setup (not yet implemented) and Quit are
|
||||
options at the Main Menu now
|
||||
- Cubic resampling in high quality audio mode
|
||||
- PC-style alien outtakes when game is completed
|
||||
- 2 more ship slots in melee, as the PC Star Control 2 had.
|
||||
- All the standard melee teams from the Star Control 2 PC version.
|
||||
- Support for 50 savegames, instead of just 10
|
||||
- 'CREW'/'BATT' instead of icons in melee when using PC menus
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Text entry doesn't freeze up lander reports anymore
|
||||
- VUX warps in at proper range
|
||||
- Distance-based ship effects (Syreen, Slylandro, Kohr-Ah) were screen
|
||||
size dependent
|
||||
- Line clipping fixed
|
||||
- Various communication animation glitches solved
|
||||
- Various melee crashes solved
|
||||
- Various race conditions eliminated
|
||||
- Scaling of graphics is handled by the rendering thread now, solving
|
||||
issues where the background and object scales would drift out of
|
||||
sync
|
||||
- Subtitle text is clipped more carefully
|
||||
- Objects can no longer be scaled to total invisibility
|
||||
- Various dialogue fixes
|
||||
- Crossfade glitches eliminated
|
||||
- Pause and Exit keys function properly everywhere
|
||||
- Visit Count overflow with Yehat and Chmmr patched
|
||||
- Wav loader and color transforms are now endian safe
|
||||
- Menu glitches when leaving the "GAME" menu are gone
|
||||
- Druuge transactions no longer baselessly increase crew cost
|
||||
- Lander speed has been retimed to match 3DO
|
||||
- Audio resampling works now correctly (less cracklings)
|
||||
- MixSDL buffer underrun handling fixed
|
||||
- Some memory leaks have been eliminated
|
||||
- Fixes and speed improvements on bilinear, biadapt, biadv scalers
|
||||
- Various minor graphics glitch fixes
|
||||
- Crew death on planet is now counted properly in all cases
|
||||
- Mouse cursor is now hidden in fullscreen mode
|
||||
- Guardian in Blazer mode being drained by DOGI will no longer
|
||||
result in a non-blazer Guardian with Blazer effects.
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- Legacy graphics code stripped down tremendously, a lot of "poor
|
||||
man's object orientation" has fallen away too. Many uses of
|
||||
function pointers with only one possible value replaced with simple
|
||||
direct calls.
|
||||
- Crossfades require you to explicitly cache the screen before drawing
|
||||
the transition target
|
||||
- User Input code has been completely rewritten
|
||||
- File I/O code has been completely rewritten
|
||||
- Subtitle drawing is now cached as its own sprite; communication
|
||||
screens are much less graphics intensive now
|
||||
- DRAWABLE_DESC uses separately allocated arrays for its frames
|
||||
|
||||
|
||||
Version 0.2
|
||||
-------------
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
- Planet info "coarse scan" information available and properly rendered,
|
||||
either in 3DO way (symbols) or PC (text)
|
||||
- 3D spinning planet in orbit window is present, with antialiasing and
|
||||
phong lighting and an animated approach
|
||||
- Pixel-perfect collision detection; Spathi/Mycon are thus playable, and
|
||||
the game is now beatable
|
||||
- Build system enhanced and generalized to handle OpenBSD and FreeBSD cleanly.
|
||||
- Oscilloscope display works in communication now
|
||||
- Color-shading in planet scans
|
||||
- Earth with its slave shield now functions properly
|
||||
- Outfit Starship and Shipyard graphics re-extracted
|
||||
- Save data and temp files are put in a separate directory now
|
||||
- Star sizes and colors are properly differentiated.
|
||||
- Planet surface is smoothed, blurred, and randomized slightly when it's
|
||||
magnified
|
||||
- SIS Status window fully implemented (including gradiated fonts from PC
|
||||
version)
|
||||
- Dialogue "slider" shows how far along the speech is; rewind/forward works
|
||||
- 'ESC' alone lets you emergency-warp-escape
|
||||
- Optional PC version menus
|
||||
- Preliminary support for MacOS X (needs more work)
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Melee screens cleaned up, SuperMelee menus work.
|
||||
- Subtitles now render for all alien races
|
||||
- Major editing of subtitles to match more closely the speeches
|
||||
- Speech and subtitles are now synchronized properly
|
||||
- Autopilot indicator doesn't take over the top of the screen anymore.
|
||||
- Entering star systems on autopilot doesn't crash the system.
|
||||
- Planet scan is properly erased when cancelling/landing
|
||||
- Initial display of planet surface on landing is at correct position
|
||||
- Spheres of influence now move correctly on the starmap
|
||||
- Melnorme correctly compute the required additional credits
|
||||
- Team names switching when selecting the next ship to fight in melee fixed
|
||||
- Commas left dots behind on planetary reports; this is fixed
|
||||
- Screen resets properly after loading/saving
|
||||
- Dialog choices wrap properly
|
||||
- Precursor ship crew count now placed correctly in melee
|
||||
- 'Cued' color transforms in conversations occur at the right time now
|
||||
- SIS correctly predicts its own fuel usage now
|
||||
- Melnorme no longer give away fuel
|
||||
- Flagship modules are properly aligned
|
||||
- The PC soundtrack now loops correctly
|
||||
- Lander upgrades were drawn incorrectly
|
||||
- Autopilot now works in QuasiSpace without fuel
|
||||
- Captain portraits in melee are updated properly now
|
||||
- If you have over 1000 units of a resource, those numbers are properly
|
||||
cleared
|
||||
|
||||
INTERNAL CHANGES
|
||||
|
||||
- SDL_mixer has been abandoned in favor of either OpenAL or the new
|
||||
"MixSDL" library built on the basic SDL_audio routines
|
||||
- Color transforms in communications are merged into the core animation
|
||||
thread now, improving speed and stability
|
||||
- Much more flexible handling of commandline options
|
||||
- All allocated memory is allocated through 'safe' routines that abort if
|
||||
the allocation fails.
|
||||
- Thread library now includes condition variables
|
||||
- Threads can tell the rendering thread to sleep until everything they've
|
||||
requested is done
|
||||
- The rendering thread has been recoded to use no heap space and to have a
|
||||
far smaller memory footprint.
|
||||
- Added a special #define, DCQ_OF_DOOM, which simulates severe overload
|
||||
stresses.
|
||||
- SAI and related scalers removed due to GPL incompatibilities; similar
|
||||
algorithms reimplemented under GPL.
|
||||
- Files for the intro and ending sequence have been successfully extracted
|
||||
- Rendering thread routines are somewhat more modular than before
|
||||
- Created a new set of graphics primitives that's much easier to use
|
||||
- Only parts of the screen that actually changed are updated
|
||||
- Input code rewritten entirely
|
||||
- Various functions have their names changed to avoid conflicts with
|
||||
core library routines on OS X
|
||||
|
||||
|
||||
Version 0.1
|
||||
-------------
|
||||
Initial release.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +1,215 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
|
||||
AppSettingVersion=19
|
||||
|
||||
# libSDL version to use (1.2 or 1.3, specify 1.3 for SDL2)
|
||||
LibSdlVersion=1.2
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="SuperTux"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=org.lethargik.supertux2
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="!Data files|http://sourceforge.net/projects/libsdl-android/files/SuperTux/data-1.zip"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!Data files|http://sourceforge.net/projects/libsdl-android/files/SuperTux/data-2.zip"
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=24
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=y
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacks=n
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
AppUsesMouse=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=n
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=n
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=n
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=y
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=n
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n)
|
||||
AppNeedsArrowKeys=y
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
AppUsesJoystick=n
|
||||
AppHandlesJoystickSensitivity=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=n
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=n
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=n
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="LALT RETURN NO_REMAP NO_REMAP SPACE"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=2
|
||||
|
||||
# Number of virtual keyboard keys that support autofire (currently 2 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="SPACE LCTRL"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames="Jump Action"
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
HiddenMenuOptions='OptionalDownloadConfig'
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
HiddenMenuOptions='SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMouse.DisplaySizeConfig'
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
FirstStartMenuOptions=''
|
||||
MultiABI=n
|
||||
AppVersionCode=03304
|
||||
AppVersionName="0.3.3.04"
|
||||
ResetSdlConfigForThisVersion=n
|
||||
DeleteFilesOnUpgrade="%"
|
||||
CompiledLibraries=" sdl_image physfs boost_system curl openal jpeg png tremor ogg"
|
||||
|
||||
# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices,
|
||||
# but .apk size is 2x bigger (y) / (n) / (x86) / (all)
|
||||
MultiABI=y
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=0
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=03305
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="0.3.3.05"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=y
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="data"
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_image physfs boost_system curl openal jpeg png vorbis ogg"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
AppCflags='-include GLES/gl.h -Ijni/openal/include/AL -DHAVE_SDL=1'
|
||||
AppLdflags=''
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-include GLES/gl.h -Ijni/openal/include/AL -DHAVE_SDL=1 -frtti -fexceptions'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags='-frtti -fexceptions'
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild='. supertux/src/* supertux/external/tinygettext/tinygettext supertux/external/tinygettext supertux/external/findlocale supertux/external/obstack supertux/external/squirrel/include supertux/external/squirrel/squirrel supertux/external/squirrel/sqstdlib'
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude='supertux/external/findlocale/example.c'
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?)
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=m
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=n
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER)
|
||||
AdmobBannerSize=
|
||||
|
||||
|
||||
8
project/jni/application/supertux/AndroidPreBuild.sh
Executable file
8
project/jni/application/supertux/AndroidPreBuild.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -e supertux/patched.successfully ]; then
|
||||
exit 0
|
||||
else
|
||||
# Google Code fails to send shallow repository, so we're checking out everything
|
||||
git clone https://code.google.com/p/supertux && patch -p1 -d supertux < android.diff && touch supertux/patched.successfully || exit 1
|
||||
fi
|
||||
@@ -1,33 +1,5 @@
|
||||
diff --git a/src/audio/ogg_sound_file.cpp b/src/audio/ogg_sound_file.cpp
|
||||
index fd7c7fc..ebf978b 100644
|
||||
--- a/src/audio/ogg_sound_file.cpp
|
||||
+++ b/src/audio/ogg_sound_file.cpp
|
||||
@@ -83,8 +83,8 @@ OggSoundFile::read(void* _buffer, size_t buffer_size)
|
||||
}
|
||||
|
||||
long bytesRead
|
||||
- = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
|
||||
- 2, 1, §ion);
|
||||
+ = ov_read(&vorbis_file, buffer, bytes_to_read,
|
||||
+ §ion);
|
||||
if(bytesRead == 0) {
|
||||
break;
|
||||
}
|
||||
diff --git a/src/audio/ogg_sound_file.hpp b/src/audio/ogg_sound_file.hpp
|
||||
index 0a9b8b1..8344177 100644
|
||||
--- a/src/audio/ogg_sound_file.hpp
|
||||
+++ b/src/audio/ogg_sound_file.hpp
|
||||
@@ -18,7 +18,7 @@
|
||||
#define HEADER_SUPERTUX_AUDIO_OGG_SOUND_FILE_HPP
|
||||
|
||||
#include <physfs.h>
|
||||
-#include <vorbis/vorbisfile.h>
|
||||
+#include <tremor/ivorbisfile.h>
|
||||
|
||||
#include "audio/sound_file.hpp"
|
||||
|
||||
diff --git a/src/control/joystickkeyboardcontroller.cpp b/src/control/joystickkeyboardcontroller.cpp
|
||||
index de414fa..92ba634 100644
|
||||
index 6c9e9c0..dbb8a9e 100644
|
||||
--- a/src/control/joystickkeyboardcontroller.cpp
|
||||
+++ b/src/control/joystickkeyboardcontroller.cpp
|
||||
@@ -70,7 +70,7 @@ JoystickKeyboardController::JoystickKeyboardController() :
|
||||
@@ -58,7 +30,7 @@ index 235198c..6126b25 100644
|
||||
try_vsync(true),
|
||||
show_fps(false),
|
||||
diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp
|
||||
index 3dccd6e..f4b179d 100644
|
||||
index d89420f..2c80b2b 100644
|
||||
--- a/src/supertux/main.cpp
|
||||
+++ b/src/supertux/main.cpp
|
||||
@@ -20,7 +20,7 @@
|
||||
@@ -213,7 +185,7 @@ index 6ce6f73..e12edf7 100644
|
||||
return (Console::output);
|
||||
else
|
||||
diff --git a/src/video/gl/gl_lightmap.cpp b/src/video/gl/gl_lightmap.cpp
|
||||
index 2ac49ef..dd5953b 100644
|
||||
index f8a6735..9638b64 100644
|
||||
--- a/src/video/gl/gl_lightmap.cpp
|
||||
+++ b/src/video/gl/gl_lightmap.cpp
|
||||
@@ -60,7 +60,7 @@ GLLightmap::GLLightmap() :
|
||||
@@ -226,12 +198,12 @@ index 2ac49ef..dd5953b 100644
|
||||
|
||||
GLLightmap::~GLLightmap()
|
||||
diff --git a/src/video/gl/gl_renderer.cpp b/src/video/gl/gl_renderer.cpp
|
||||
index 361f30a..f26db81 100644
|
||||
index 0e66433..abf65b8 100644
|
||||
--- a/src/video/gl/gl_renderer.cpp
|
||||
+++ b/src/video/gl/gl_renderer.cpp
|
||||
@@ -118,8 +118,8 @@ GLRenderer::draw_surface(const DrawingRequest& request)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
|
||||
@@ -123,8 +123,8 @@ GLRenderer::draw_surface(const DrawingRequest& request)
|
||||
glBindTexture(GL_TEXTURE_2D, th);
|
||||
}
|
||||
intern_draw(request.pos.x, request.pos.y,
|
||||
- request.pos.x + surface->get_width(),
|
||||
- request.pos.y + surface->get_height(),
|
||||
@@ -240,9 +212,9 @@ index 361f30a..f26db81 100644
|
||||
surface_data->get_uv_left(),
|
||||
surface_data->get_uv_top(),
|
||||
surface_data->get_uv_right(),
|
||||
@@ -150,8 +150,8 @@ GLRenderer::draw_surface_part(const DrawingRequest& request)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
|
||||
@@ -159,8 +159,8 @@ GLRenderer::draw_surface_part(const DrawingRequest& request)
|
||||
glBindTexture(GL_TEXTURE_2D, th);
|
||||
}
|
||||
intern_draw(request.pos.x, request.pos.y,
|
||||
- request.pos.x + surfacepartrequest->size.x,
|
||||
- request.pos.y + surfacepartrequest->size.y,
|
||||
@@ -252,7 +224,7 @@ index 361f30a..f26db81 100644
|
||||
uv_top,
|
||||
uv_right,
|
||||
diff --git a/src/video/gl/gl_renderer.hpp b/src/video/gl/gl_renderer.hpp
|
||||
index 9e20859..8b7e04e 100644
|
||||
index d5d9995..4fdacf8 100644
|
||||
--- a/src/video/gl/gl_renderer.hpp
|
||||
+++ b/src/video/gl/gl_renderer.hpp
|
||||
@@ -63,8 +63,8 @@ inline void intern_draw(float left, float top, float right, float bottom,
|
||||
@@ -490,10 +462,10 @@ index e814547..710a488 100644
|
||||
private:
|
||||
Texture(const Texture&);
|
||||
diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp
|
||||
index 7343a45..86af07e 100644
|
||||
index 0c77a5a..378853b 100644
|
||||
--- a/src/video/texture_manager.cpp
|
||||
+++ b/src/video/texture_manager.cpp
|
||||
@@ -219,6 +219,7 @@ TextureManager::create_dummy_texture()
|
||||
@@ -228,6 +228,7 @@ TextureManager::create_dummy_texture()
|
||||
void
|
||||
TextureManager::save_textures()
|
||||
{
|
||||
@@ -501,7 +473,7 @@ index 7343a45..86af07e 100644
|
||||
#ifdef GL_PACK_ROW_LENGTH
|
||||
/* all this stuff is not support by OpenGL ES */
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
@@ -236,11 +237,13 @@ TextureManager::save_textures()
|
||||
@@ -245,11 +246,13 @@ TextureManager::save_textures()
|
||||
i != image_textures.end(); ++i) {
|
||||
save_texture(dynamic_cast<GLTexture*>(i->second.lock().get()));
|
||||
}
|
||||
@@ -515,7 +487,7 @@ index 7343a45..86af07e 100644
|
||||
SavedTexture saved_texture;
|
||||
saved_texture.texture = texture;
|
||||
glBindTexture(GL_TEXTURE_2D, texture->get_handle());
|
||||
@@ -275,11 +278,13 @@ TextureManager::save_texture(GLTexture* texture)
|
||||
@@ -284,11 +287,13 @@ TextureManager::save_texture(GLTexture* texture)
|
||||
texture->set_handle(0);
|
||||
|
||||
assert_gl("retrieving texture for save");
|
||||
@@ -529,7 +501,7 @@ index 7343a45..86af07e 100644
|
||||
#ifdef GL_UNPACK_ROW_LENGTH
|
||||
/* OpenGL ES doesn't support these */
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -320,6 +325,12 @@ TextureManager::reload_textures()
|
||||
@@ -329,6 +334,12 @@ TextureManager::reload_textures()
|
||||
}
|
||||
|
||||
saved_textures.clear();
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../../../../supertux
|
||||
@@ -1,47 +0,0 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=17
|
||||
LibSdlVersion=1.2
|
||||
AppName="TeeWorlds"
|
||||
AppFullName=com.teeworlds
|
||||
ScreenOrientation=h
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="Game data|teeworlds.zip"
|
||||
VideoDepthBpp=16
|
||||
NeedDepthBuffer=n
|
||||
NeedStencilBuffer=n
|
||||
NeedGles2=n
|
||||
SwVideoMode=n
|
||||
SdlVideoResize=n
|
||||
SdlVideoResizeKeepAspect=n
|
||||
CompatibilityHacks=n
|
||||
CompatibilityHacksStaticInit=n
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
AppUsesMouse=y
|
||||
AppNeedsTwoButtonMouse=y
|
||||
ShowMouseCursor=n
|
||||
ForceRelativeMouseMode=y
|
||||
AppNeedsArrowKeys=y
|
||||
AppNeedsTextInput=y
|
||||
AppUsesJoystick=y
|
||||
AppHandlesJoystickSensitivity=n
|
||||
AppUsesMultitouch=n
|
||||
NonBlockingSwapBuffers=n
|
||||
RedefinedKeys="SPACE RETURN LEFT RIGHT LSHIFT ESCAPE RSHIFT LSHIFT"
|
||||
AppTouchscreenKeyboardKeysAmount=6
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
RedefinedKeysScreenKb="SPACE RETURN LEFT RIGHT RSHIFT LSHIFT"
|
||||
StartupMenuButtonTimeout=3000
|
||||
HiddenMenuOptions='OptionalDownloadConfig DisplaySizeConfig'
|
||||
FirstStartMenuOptions=''
|
||||
MultiABI=y
|
||||
AppVersionCode=5207
|
||||
AppVersionName="0.5.2.07"
|
||||
ResetSdlConfigForThisVersion=n
|
||||
DeleteFilesOnUpgrade="%"
|
||||
CompiledLibraries="sdl_image freetype"
|
||||
CustomBuildScript=n
|
||||
AppCflags='-O3'
|
||||
AppLdflags=''
|
||||
AppSubdirsBuild=''
|
||||
AppCmdline=''
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 3.7 KiB |
@@ -1,28 +0,0 @@
|
||||
Copyright (C) 2007-2010 Magnus Auvinen
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
IMPORTANT NOTE! The source under src/engine/external are stripped
|
||||
libraries with their own licenses. Mostly BSD or zlib/libpng license but
|
||||
check the individual libraries.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
With that being said, contact us if there is anything you want to do
|
||||
that the license does not premit.
|
||||
@@ -1,10 +0,0 @@
|
||||
Copyright (c) 2010 Magnus Auvinen
|
||||
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
|
||||
Please visit http://www.teeworlds.com for up-to-date information about
|
||||
the game, including new versions, custom maps and much more.
|
||||
@@ -1,134 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef BASELIB_FILE_CONFIG_H
|
||||
#define BASELIB_FILE_CONFIG_H
|
||||
|
||||
/*
|
||||
this file detected the family, platform and architecture
|
||||
to compile for.
|
||||
*/
|
||||
|
||||
/* platforms */
|
||||
|
||||
/* windows Family */
|
||||
#if defined(WIN64) || defined(_WIN64)
|
||||
/* Hmm, is this IA64 or x86-64? */
|
||||
#define CONF_FAMILY_WINDOWS 1
|
||||
#define CONF_FAMILY_STRING "windows"
|
||||
#define CONF_PLATFORM_WIN64 1
|
||||
#define CONF_PLATFORM_STRING "win64"
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
|
||||
#define CONF_FAMILY_WINDOWS 1
|
||||
#define CONF_FAMILY_STRING "windows"
|
||||
#define CONF_PLATFORM_WIN32 1
|
||||
#define CONF_PLATFORM_STRING "win32"
|
||||
#endif
|
||||
|
||||
/* unix family */
|
||||
#if defined(__FreeBSD__)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFORM_FREEBSD 1
|
||||
#define CONF_PLATFORM_STRING "freebsd"
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFORM_OPENBSD 1
|
||||
#define CONF_PLATFORM_STRING "openbsd"
|
||||
#endif
|
||||
|
||||
#if defined(__LINUX__) || defined(__linux__)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFORM_LINUX 1
|
||||
#define CONF_PLATFORM_STRING "linux"
|
||||
#endif
|
||||
|
||||
#if defined(MACOSX) || defined(__APPLE__) || defined(__DARWIN__)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFORM_MACOSX 1
|
||||
#define CONF_PLATFORM_STRING "macosx"
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFROM_SOLARIS 1
|
||||
#define CONF_PLATFORM_STRING "solaris"
|
||||
#endif
|
||||
|
||||
/* beos family */
|
||||
#if defined(__BeOS) || defined(__BEOS__)
|
||||
#define CONF_FAMILY_BEOS 1
|
||||
#define CONF_FAMILY_STRING "beos"
|
||||
#define CONF_PLATFORM_BEOS 1
|
||||
#define CONF_PLATFORM_STRING "beos"
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
#define CONF_FAMILY_UNIX 1
|
||||
#define CONF_FAMILY_STRING "unix"
|
||||
#define CONF_PLATFORM_LINUX 1
|
||||
#define CONF_PLATFORM_STRING "android"
|
||||
#endif
|
||||
|
||||
|
||||
/* architectures */
|
||||
#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(CONF_PLATFORM_WIN32)
|
||||
#define CONF_ARCH_IA32 1
|
||||
#define CONF_ARCH_STRING "ia32"
|
||||
#define CONF_ARCH_ENDIAN_LITTLE 1
|
||||
#endif
|
||||
|
||||
#if defined(__ia64__)
|
||||
#define CONF_ARCH_IA64 1
|
||||
#define CONF_ARCH_STRING "ia64"
|
||||
#define CONF_ARCH_ENDIAN_LITTLE 1
|
||||
#endif
|
||||
|
||||
#if defined(__amd64__) || defined(__x86_64__)
|
||||
#define CONF_ARCH_AMD64 1
|
||||
#define CONF_ARCH_STRING "amd64"
|
||||
#define CONF_ARCH_ENDIAN_LITTLE 1
|
||||
#endif
|
||||
|
||||
#if defined(__powerpc__) || defined(__ppc__)
|
||||
#define CONF_ARCH_PPC 1
|
||||
#define CONF_ARCH_STRING "ppc"
|
||||
#define CONF_ARCH_ENDIAN_BIG 1
|
||||
#endif
|
||||
|
||||
#if defined(__sparc__)
|
||||
#define CONF_ARCH_SPARC 1
|
||||
#define CONF_ARCH_STRING "sparc"
|
||||
#define CONF_ARCH_ENDIAN_BIG 1
|
||||
#endif
|
||||
|
||||
#if defined(__ARMEB__)
|
||||
#define CONF_ARCH_ARM 1
|
||||
#define CONF_ARCH_STRING "arm"
|
||||
#define CONF_ARCH_ENDIAN_BIG 1
|
||||
#endif
|
||||
|
||||
#if defined(__ARMEL__)
|
||||
#define CONF_ARCH_ARM 1
|
||||
#define CONF_ARCH_STRING "arm"
|
||||
#define CONF_ARCH_ENDIAN_LITTLE 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CONF_FAMILY_STRING
|
||||
#define CONF_FAMILY_STRING "unknown"
|
||||
#endif
|
||||
|
||||
#ifndef CONF_PLATFORM_STRING
|
||||
#define CONF_PLATFORM_STRING "unknown"
|
||||
#endif
|
||||
|
||||
#ifndef CONF_ARCH_STRING
|
||||
#define CONF_ARCH_STRING "unknown"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef BASE_MATH_H
|
||||
#define BASE_MATH_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
template <typename T>
|
||||
inline T clamp(T val, T min, T max)
|
||||
{
|
||||
if(val < min)
|
||||
return min;
|
||||
if(val > max)
|
||||
return max;
|
||||
return val;
|
||||
}
|
||||
|
||||
inline float sign(float f)
|
||||
{
|
||||
return f<0.0f?-1.0f:1.0f;
|
||||
}
|
||||
|
||||
inline int round(float f)
|
||||
{
|
||||
if(f > 0)
|
||||
return (int)(f+0.5f);
|
||||
return (int)(f-0.5f);
|
||||
}
|
||||
|
||||
template<typename T, typename TB>
|
||||
inline T mix(const T a, const T b, TB amount)
|
||||
{
|
||||
return a + (b-a)*amount;
|
||||
}
|
||||
|
||||
inline float frandom() { return rand()/(float)(RAND_MAX); }
|
||||
|
||||
// float to fixed
|
||||
inline int f2fx(float v) { return (int)(v*(float)(1<<10)); }
|
||||
inline float fx2f(int v) { return v*(1.0f/(1<<10)); }
|
||||
|
||||
class fxp
|
||||
{
|
||||
int value;
|
||||
public:
|
||||
void set(int v) { value = v; }
|
||||
int get() const { return value; }
|
||||
fxp &operator = (int v) { value = v<<10; return *this; }
|
||||
fxp &operator = (float v) { value = (int)(v*(float)(1<<10)); return *this; }
|
||||
operator float() const { return value/(float)(1<<10); }
|
||||
};
|
||||
|
||||
class tune_param
|
||||
{
|
||||
int value;
|
||||
public:
|
||||
void set(int v) { value = v; }
|
||||
int get() const { return value; }
|
||||
tune_param &operator = (int v) { value = (int)(v*100.0f); return *this; }
|
||||
tune_param &operator = (float v) { value = (int)(v*100.0f); return *this; }
|
||||
operator float() const { return value/100.0f; }
|
||||
};
|
||||
|
||||
const float pi = 3.1415926535897932384626433f;
|
||||
|
||||
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
|
||||
template <typename T> inline T max(T a, T b) { return a>b?a:b; }
|
||||
|
||||
#endif // BASE_MATH_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,954 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
/*
|
||||
Title: OS Abstraction
|
||||
*/
|
||||
|
||||
#ifndef BASE_SYSTEM_H
|
||||
#define BASE_SYSTEM_H
|
||||
|
||||
#include "detect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Group: Debug */
|
||||
/*
|
||||
Function: dbg_assert
|
||||
Breaks into the debugger based on a test.
|
||||
|
||||
Parameters:
|
||||
test - Result of the test.
|
||||
msg - Message that should be printed if the test fails.
|
||||
|
||||
Remarks:
|
||||
Does nothing in release version of the library.
|
||||
|
||||
See Also:
|
||||
<dbg_break>
|
||||
*/
|
||||
void dbg_assert(int test, const char *msg);
|
||||
#define dbg_assert(test,msg) dbg_assert_imp(__FILE__, __LINE__, test, msg)
|
||||
void dbg_assert_imp(const char *filename, int line, int test, const char *msg);
|
||||
|
||||
/*
|
||||
Function: dbg_break
|
||||
Breaks into the debugger.
|
||||
|
||||
Remarks:
|
||||
Does nothing in release version of the library.
|
||||
|
||||
See Also:
|
||||
<dbg_assert>
|
||||
*/
|
||||
void dbg_break();
|
||||
|
||||
/*
|
||||
Function: dbg_msg
|
||||
|
||||
Prints a debug message.
|
||||
|
||||
Parameters:
|
||||
sys - A string that describes what system the message belongs to
|
||||
fmt - A printf styled format string.
|
||||
|
||||
Remarks:
|
||||
Does nothing in relase version of the library.
|
||||
|
||||
See Also:
|
||||
<dbg_assert>
|
||||
*/
|
||||
void dbg_msg(const char *sys, const char *fmt, ...);
|
||||
|
||||
/* Group: Memory */
|
||||
|
||||
/*
|
||||
Function: mem_alloc
|
||||
Allocates memory.
|
||||
|
||||
Parameters:
|
||||
size - Size of the needed block.
|
||||
alignment - Alignment for the block.
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the newly allocated block. Returns a
|
||||
null pointer if the memory couldn't be allocated.
|
||||
|
||||
Remarks:
|
||||
- Passing 0 to size will allocated the smallest amount possible
|
||||
and return a unique pointer.
|
||||
|
||||
See Also:
|
||||
<mem_free>
|
||||
*/
|
||||
void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned alignment);
|
||||
#define mem_alloc(s,a) mem_alloc_debug(__FILE__, __LINE__, (s), (a))
|
||||
|
||||
/*
|
||||
Function: mem_free
|
||||
Frees a block allocated through <mem_alloc>.
|
||||
|
||||
Remarks:
|
||||
- In the debug version of the library the function will assert if
|
||||
a non-valid block is passed, like a null pointer or a block that
|
||||
isn't allocated.
|
||||
|
||||
See Also:
|
||||
<mem_alloc>
|
||||
*/
|
||||
void mem_free(void *block);
|
||||
|
||||
/*
|
||||
Function: mem_copy
|
||||
Copies a a memory block.
|
||||
|
||||
Parameters:
|
||||
dest - Destination.
|
||||
source - Source to copy.
|
||||
size - Size of the block to copy.
|
||||
|
||||
Remarks:
|
||||
- This functions DOES NOT handles cases where source and
|
||||
destination is overlapping.
|
||||
|
||||
See Also:
|
||||
<mem_move>
|
||||
*/
|
||||
void mem_copy(void *dest, const void *source, unsigned size);
|
||||
|
||||
/*
|
||||
Function: mem_move
|
||||
Copies a a memory block
|
||||
|
||||
Parameters:
|
||||
dest - Destination
|
||||
source - Source to copy
|
||||
size - Size of the block to copy
|
||||
|
||||
Remarks:
|
||||
- This functions handles cases where source and destination
|
||||
is overlapping
|
||||
|
||||
See Also:
|
||||
<mem_copy>
|
||||
*/
|
||||
void mem_move(void *dest, const void *source, unsigned size);
|
||||
|
||||
/*
|
||||
Function: mem_zero
|
||||
Sets a complete memory block to 0
|
||||
|
||||
Parameters:
|
||||
block - Pointer to the block to zero out
|
||||
size - Size of the block
|
||||
*/
|
||||
void mem_zero(void *block, unsigned size);
|
||||
|
||||
/*
|
||||
Function: mem_comp
|
||||
Compares two blocks of memory
|
||||
|
||||
Parameters:
|
||||
a - First block of data
|
||||
b - Second block of data
|
||||
size - Size of the data to compare
|
||||
|
||||
Returns:
|
||||
<0 - Block a is lesser then block b
|
||||
0 - Block a is equal to block b
|
||||
>0 - Block a is greater then block b
|
||||
*/
|
||||
int mem_comp(const void *a, const void *b, int size);
|
||||
|
||||
/*
|
||||
Function: mem_check
|
||||
Validates the heap
|
||||
Will trigger a assert if memory has failed.
|
||||
*/
|
||||
int mem_check_imp();
|
||||
#define mem_check() dbg_assert_imp(__FILE__, __LINE__, mem_check_imp(), "Memory check failed")
|
||||
|
||||
/* Group: File IO */
|
||||
enum {
|
||||
IOFLAG_READ = 1,
|
||||
IOFLAG_WRITE = 2,
|
||||
IOFLAG_RANDOM = 4,
|
||||
|
||||
IOSEEK_START = 0,
|
||||
IOSEEK_CUR = 1,
|
||||
IOSEEK_END = 2
|
||||
};
|
||||
|
||||
typedef struct IOINTERNAL *IOHANDLE;
|
||||
|
||||
/*
|
||||
Function: io_open
|
||||
Opens a file.
|
||||
|
||||
Parameters:
|
||||
filename - File to open.
|
||||
flags - A set of flags. IOFLAG_READ, IOFLAG_WRITE, IOFLAG_RANDOM.
|
||||
|
||||
Returns:
|
||||
Returns a handle to the file on success and 0 on failure.
|
||||
|
||||
*/
|
||||
IOHANDLE io_open(const char *filename, int flags);
|
||||
|
||||
/*
|
||||
Function: io_read
|
||||
Reads data into a buffer from a file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file to read data from.
|
||||
buffer - Pointer to the buffer that will recive the data.
|
||||
size - Number of bytes to read from the file.
|
||||
|
||||
Returns:
|
||||
Number of bytes read.
|
||||
|
||||
*/
|
||||
unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
|
||||
|
||||
/*
|
||||
Function: io_skip
|
||||
Skips data in a file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
size - Number of bytes to skip.
|
||||
|
||||
Returns:
|
||||
Number of bytes skipped.
|
||||
*/
|
||||
unsigned io_skip(IOHANDLE io, unsigned size);
|
||||
|
||||
/*
|
||||
Function: io_write
|
||||
Writes data from a buffer to file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
buffer - Pointer to the data that should be written.
|
||||
size - Number of bytes to write.
|
||||
|
||||
Returns:
|
||||
Number of bytes written.
|
||||
*/
|
||||
unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
|
||||
|
||||
/*
|
||||
Function: io_seek
|
||||
Seeks to a specified offset in the file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
offset - Offset from pos to stop.
|
||||
origin - Position to start searching from.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success.
|
||||
*/
|
||||
int io_seek(IOHANDLE io, int offset, int origin);
|
||||
|
||||
/*
|
||||
Function: io_tell
|
||||
Gets the current position in the file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
|
||||
Returns:
|
||||
Returns the current position. -1L if an error occured.
|
||||
*/
|
||||
long int io_tell(IOHANDLE io);
|
||||
|
||||
/*
|
||||
Function: io_length
|
||||
Gets the total length of the file. Resetting cursor to the beginning
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
|
||||
Returns:
|
||||
Returns the total size. -1L if an error occured.
|
||||
*/
|
||||
long int io_length(IOHANDLE io);
|
||||
|
||||
/*
|
||||
Function: io_close
|
||||
Closes a file.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success.
|
||||
*/
|
||||
int io_close(IOHANDLE io);
|
||||
|
||||
/*
|
||||
Function: io_flush
|
||||
Empties all buffers and writes all pending data.
|
||||
|
||||
Parameters:
|
||||
io - Handle to the file.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success.
|
||||
*/
|
||||
int io_flush(IOHANDLE io);
|
||||
|
||||
|
||||
/*
|
||||
Function: io_stdin
|
||||
Returns an <IOHANDLE> to the standard input.
|
||||
*/
|
||||
IOHANDLE io_stdin();
|
||||
|
||||
/*
|
||||
Function: io_stdout
|
||||
Returns an <IOHANDLE> to the standard output.
|
||||
*/
|
||||
IOHANDLE io_stdout();
|
||||
|
||||
/*
|
||||
Function: io_stderr
|
||||
Returns an <IOHANDLE> to the standard error.
|
||||
*/
|
||||
IOHANDLE io_stderr();
|
||||
|
||||
|
||||
/* Group: Threads */
|
||||
|
||||
/*
|
||||
Function: thread_sleep
|
||||
Suspends the current thread for a given period.
|
||||
|
||||
Parameters:
|
||||
milliseconds - Number of milliseconds to sleep.
|
||||
*/
|
||||
void thread_sleep(int milliseconds);
|
||||
|
||||
/*
|
||||
Function: thread_create
|
||||
Creates a new thread.
|
||||
|
||||
Parameters:
|
||||
threadfunc - Entry point for the new thread.
|
||||
user - Pointer to pass to the thread.
|
||||
|
||||
*/
|
||||
void *thread_create(void (*threadfunc)(void *), void *user);
|
||||
|
||||
/*
|
||||
Function: thread_wait
|
||||
Waits for a thread to be done or destroyed.
|
||||
|
||||
Parameters:
|
||||
thread - Thread to wait for.
|
||||
*/
|
||||
void thread_wait(void *thread);
|
||||
|
||||
/*
|
||||
Function: thread_destoy
|
||||
Destroys a thread.
|
||||
|
||||
Parameters:
|
||||
thread - Thread to destroy.
|
||||
*/
|
||||
void thread_destroy(void *thread);
|
||||
|
||||
/*
|
||||
Function: thread_yeild
|
||||
Yeild the current threads execution slice.
|
||||
*/
|
||||
void thread_yield();
|
||||
|
||||
|
||||
/* Group: Locks */
|
||||
typedef void* LOCK;
|
||||
|
||||
LOCK lock_create();
|
||||
void lock_destroy(LOCK lock);
|
||||
|
||||
int lock_try(LOCK lock);
|
||||
void lock_wait(LOCK lock);
|
||||
void lock_release(LOCK lock);
|
||||
|
||||
/* Group: Timer */
|
||||
#ifdef __GNUC__
|
||||
/* if compiled with -pedantic-errors it will complain about long
|
||||
not being a C90 thing.
|
||||
*/
|
||||
__extension__ typedef long long int64;
|
||||
#else
|
||||
typedef long long int64;
|
||||
#endif
|
||||
/*
|
||||
Function: time_get
|
||||
Fetches a sample from a high resolution timer.
|
||||
|
||||
Returns:
|
||||
Current value of the timer.
|
||||
|
||||
Remarks:
|
||||
To know how fast the timer is ticking, see <time_freq>.
|
||||
*/
|
||||
int64 time_get();
|
||||
|
||||
/*
|
||||
Function: time_freq
|
||||
Returns the frequency of the high resolution timer.
|
||||
|
||||
Returns:
|
||||
Returns the frequency of the high resolution timer.
|
||||
*/
|
||||
int64 time_freq();
|
||||
|
||||
/*
|
||||
Function: time_timestamp
|
||||
Retrives the current time as a UNIX timestamp
|
||||
|
||||
Returns:
|
||||
The time as a UNIX timestamp
|
||||
*/
|
||||
unsigned time_timestamp();
|
||||
|
||||
/* Group: Network General */
|
||||
typedef int NETSOCKET;
|
||||
enum
|
||||
{
|
||||
NETSOCKET_INVALID = -1,
|
||||
|
||||
NETTYPE_INVALID = 0,
|
||||
NETTYPE_IPV4 = 1,
|
||||
NETTYPE_IPV6 = 2,
|
||||
NETTYPE_ALL = ~0
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int type;
|
||||
unsigned char ip[16];
|
||||
unsigned short port;
|
||||
} NETADDR;
|
||||
|
||||
/*
|
||||
Function: net_init
|
||||
Initiates network functionallity.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success,
|
||||
|
||||
Remarks:
|
||||
You must call this function before using any other network
|
||||
functions.
|
||||
*/
|
||||
int net_init();
|
||||
|
||||
/*
|
||||
Function: net_host_lookup
|
||||
Does a hostname lookup by name and fills out the passed
|
||||
NETADDR struct with the recieved details.
|
||||
|
||||
Returns:
|
||||
0 on success.
|
||||
*/
|
||||
int net_host_lookup(const char *hostname, NETADDR *addr, int types);
|
||||
|
||||
/*
|
||||
Function: net_addr_comp
|
||||
Compares two network addresses.
|
||||
|
||||
Parameters:
|
||||
a - Address to compare
|
||||
b - Address to compare to.
|
||||
|
||||
Returns:
|
||||
<0 - Address a is lesser then address b
|
||||
0 - Address a is equal to address b
|
||||
>0 - Address a is greater then address b
|
||||
*/
|
||||
int net_addr_comp(const NETADDR *a, const NETADDR *b);
|
||||
|
||||
/*
|
||||
Function: net_addr_str
|
||||
Turns a network address into a representive string.
|
||||
|
||||
Parameters:
|
||||
addr - Address to turn into a string.
|
||||
string - Buffer to fill with the string.
|
||||
max_length - Maximum size of the string.
|
||||
|
||||
Remarks:
|
||||
- The string will always be zero terminated
|
||||
|
||||
*/
|
||||
void net_addr_str(const NETADDR *addr, char *string, int max_length);
|
||||
|
||||
/*
|
||||
Function: net_addr_from_str
|
||||
Turns string into a network address.
|
||||
|
||||
Returns:
|
||||
0 on success
|
||||
|
||||
Parameters:
|
||||
addr - Address to fill in.
|
||||
string - String to parse.
|
||||
*/
|
||||
int net_addr_from_str(NETADDR *addr, const char *string);
|
||||
|
||||
/* Group: Network UDP */
|
||||
|
||||
/*
|
||||
Function: net_udp_create
|
||||
Creates a UDP socket and binds it to a port.
|
||||
|
||||
Parameters:
|
||||
bindaddr - Address to bind the socket to.
|
||||
|
||||
Returns:
|
||||
On success it returns an handle to the socket. On failure it
|
||||
returns NETSOCKET_INVALID.
|
||||
*/
|
||||
NETSOCKET net_udp_create(NETADDR bindaddr);
|
||||
|
||||
/*
|
||||
Function: net_udp_send
|
||||
Sends a packet over an UDP socket.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to use.
|
||||
addr - Where to send the packet.
|
||||
data - Pointer to the packet data to send.
|
||||
size - Size of the packet.
|
||||
|
||||
Returns:
|
||||
On success it returns the number of bytes sent. Returns -1
|
||||
on error.
|
||||
*/
|
||||
int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
|
||||
|
||||
/*
|
||||
Function: net_udp_recv
|
||||
Recives a packet over an UDP socket.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to use.
|
||||
addr - Pointer to an NETADDR that will recive the address.
|
||||
data - Pointer to a buffer that will recive the data.
|
||||
maxsize - Maximum size to recive.
|
||||
|
||||
Returns:
|
||||
On success it returns the number of bytes recived. Returns -1
|
||||
on error.
|
||||
*/
|
||||
int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize);
|
||||
|
||||
/*
|
||||
Function: net_udp_close
|
||||
Closes an UDP socket.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to close.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success. -1 on error.
|
||||
*/
|
||||
int net_udp_close(NETSOCKET sock);
|
||||
|
||||
|
||||
/* Group: Network TCP */
|
||||
|
||||
/*
|
||||
Function: net_tcp_create
|
||||
Creates a TCP socket.
|
||||
|
||||
Parameters:
|
||||
bindaddr - Address to bind the socket to.
|
||||
|
||||
Returns:
|
||||
On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID.
|
||||
*/
|
||||
NETSOCKET net_tcp_create(const NETADDR *a);
|
||||
|
||||
/*
|
||||
Function: net_tcp_listen
|
||||
Makes the socket start listening for new connections.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to start listen to.
|
||||
backlog - Size of the queue of incomming connections to keep.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success.
|
||||
*/
|
||||
int net_tcp_listen(NETSOCKET sock, int backlog);
|
||||
|
||||
/*
|
||||
Function: net_tcp_accept
|
||||
Polls a listning socket for a new connection.
|
||||
|
||||
Parameters:
|
||||
sock - Listning socket to poll.
|
||||
new_sock - Pointer to a socket to fill in with the new socket.
|
||||
addr - Pointer to an address that will be filled in the remote address (optional, can be NULL).
|
||||
|
||||
Returns:
|
||||
Returns a non-negative integer on success. Negative integer on failure.
|
||||
*/
|
||||
int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr);
|
||||
|
||||
/*
|
||||
Function: net_tcp_connect
|
||||
Connects one socket to another.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to connect.
|
||||
addr - Address to connect to.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success.
|
||||
|
||||
*/
|
||||
int net_tcp_connect(NETSOCKET sock, const NETADDR *addr);
|
||||
|
||||
/*
|
||||
Function: net_tcp_send
|
||||
Sends data to a TCP stream.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to send data to.
|
||||
data - Pointer to the data to send.
|
||||
size - Size of the data to send.
|
||||
|
||||
Returns:
|
||||
Number of bytes sent. Negative value on failure.
|
||||
*/
|
||||
int net_tcp_send(NETSOCKET sock, const void *data, int size);
|
||||
|
||||
/*
|
||||
Function: net_tcp_recv
|
||||
Recvives data from a TCP stream.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to recvive data from.
|
||||
data - Pointer to a buffer to write the data to
|
||||
max_size - Maximum of data to write to the buffer.
|
||||
|
||||
Returns:
|
||||
Number of bytes recvived. Negative value on failure. When in
|
||||
non-blocking mode, it returns 0 when there is no more data to
|
||||
be fetched.
|
||||
*/
|
||||
int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
|
||||
|
||||
/*
|
||||
Function: net_tcp_close
|
||||
Closes a TCP socket.
|
||||
|
||||
Parameters:
|
||||
sock - Socket to close.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success. Negative value on failure.
|
||||
*/
|
||||
int net_tcp_close(NETSOCKET sock);
|
||||
|
||||
/* Group: Strings */
|
||||
|
||||
/*
|
||||
Function: str_append
|
||||
Appends a string to another.
|
||||
|
||||
Parameters:
|
||||
dst - Pointer to a buffer that contains a string.
|
||||
src - String to append.
|
||||
dst_size - Size of the buffer of the dst string.
|
||||
|
||||
Remarks:
|
||||
- The strings are treated as zero-termineted strings.
|
||||
- Garantees that dst string will contain zero-termination.
|
||||
*/
|
||||
void str_append(char *dst, const char *src, int dst_size);
|
||||
|
||||
/*
|
||||
Function: str_copy
|
||||
Copies a string to another.
|
||||
|
||||
Parameters:
|
||||
dst - Pointer to a buffer that shall recive the string.
|
||||
src - String to be copied.
|
||||
dst_size - Size of the buffer dst.
|
||||
|
||||
Remarks:
|
||||
- The strings are treated as zero-termineted strings.
|
||||
- Garantees that dst string will contain zero-termination.
|
||||
*/
|
||||
void str_copy(char *dst, const char *src, int dst_size);
|
||||
|
||||
/*
|
||||
Function: str_length
|
||||
Returns the length of a zero terminated string.
|
||||
|
||||
Parameters:
|
||||
str - Pointer to the string.
|
||||
|
||||
Returns:
|
||||
Length of string in bytes excluding the zero termination.
|
||||
*/
|
||||
int str_length(const char *str);
|
||||
|
||||
/*
|
||||
Function: str_format
|
||||
Performs printf formating into a buffer.
|
||||
|
||||
Parameters:
|
||||
buffer - Pointer to the buffer to recive the formated string.
|
||||
buffer_size - Size of the buffer.
|
||||
format - printf formating string.
|
||||
... - Parameters for the formating.
|
||||
|
||||
Remarks:
|
||||
- See the C manual for syntax for the printf formating string.
|
||||
- The strings are treated as zero-termineted strings.
|
||||
- Garantees that dst string will contain zero-termination.
|
||||
*/
|
||||
void str_format(char *buffer, int buffer_size, const char *format, ...);
|
||||
|
||||
/*
|
||||
Function: str_sanitize_strong
|
||||
Replaces all characters below 32 and above 127 with whitespace.
|
||||
|
||||
Parameters:
|
||||
str - String to sanitize.
|
||||
|
||||
Remarks:
|
||||
- The strings are treated as zero-termineted strings.
|
||||
*/
|
||||
void str_sanitize_strong(char *str);
|
||||
|
||||
/*
|
||||
Function: str_sanitize
|
||||
Replaces all characters below 32 and above 127 with whitespace with
|
||||
exception to \r, \n and \r.
|
||||
|
||||
Parameters:
|
||||
str - String to sanitize.
|
||||
|
||||
Remarks:
|
||||
- The strings are treated as zero-termineted strings.
|
||||
*/
|
||||
void str_sanitize(char *str);
|
||||
|
||||
/*
|
||||
Function: str_comp_nocase
|
||||
Compares to strings case insensitive.
|
||||
|
||||
Parameters:
|
||||
a - String to compare.
|
||||
b - String to compare.
|
||||
|
||||
Returns:
|
||||
<0 - String a is lesser then string b
|
||||
0 - String a is equal to string b
|
||||
>0 - String a is greater then string b
|
||||
|
||||
Remarks:
|
||||
- Only garanted to work with a-z/A-Z.
|
||||
- The strings are treated as zero-termineted strings.
|
||||
*/
|
||||
int str_comp_nocase(const char *a, const char *b);
|
||||
|
||||
/*
|
||||
Function: str_find_nocase
|
||||
Finds a string inside another string case insensitive.
|
||||
|
||||
Parameters:
|
||||
haystack - String to search in
|
||||
needle - String to search for
|
||||
|
||||
Returns:
|
||||
A pointer into haystack where the needle was found.
|
||||
Returns NULL of needle could not be found.
|
||||
|
||||
Remarks:
|
||||
- Only garanted to work with a-z/A-Z.
|
||||
- The strings are treated as zero-termineted strings.
|
||||
*/
|
||||
const char *str_find_nocase(const char *haystack, const char *needle);
|
||||
|
||||
|
||||
/*
|
||||
Function: str_hex
|
||||
Takes a datablock and generates a hexstring of it.
|
||||
|
||||
Parameters:
|
||||
dst - Buffer to fill with hex data
|
||||
dst_size - size of the buffer
|
||||
data - Data to turn into hex
|
||||
data - Size of the data
|
||||
|
||||
Remarks:
|
||||
- The desination buffer will be zero-terminated
|
||||
*/
|
||||
void str_hex(char *dst, int dst_size, const void *data, int data_size);
|
||||
|
||||
/* Group: Filesystem */
|
||||
|
||||
/*
|
||||
Function: fs_listdir
|
||||
Lists the files in a directory
|
||||
|
||||
Parameters:
|
||||
dir - Directory to list
|
||||
cb - Callback function to call for each entry
|
||||
user - Pointer to give to the callback
|
||||
|
||||
Returns:
|
||||
Always returns 0.
|
||||
*/
|
||||
typedef void (*FS_LISTDIR_CALLBACK)(const char *name, int is_dir, void *user);
|
||||
int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, void *user);
|
||||
|
||||
/*
|
||||
Function: fs_makedir
|
||||
Creates a directory
|
||||
|
||||
Parameters:
|
||||
path - Directory to create
|
||||
|
||||
Returns:
|
||||
Returns 0 on success. Negative value on failure.
|
||||
|
||||
Remarks:
|
||||
Does not create several directories if needed. "a/b/c" will result
|
||||
in a failure if b or a does not exist.
|
||||
*/
|
||||
int fs_makedir(const char *path);
|
||||
|
||||
/*
|
||||
Function: fs_storage_path
|
||||
Fetches per user configuration directory.
|
||||
|
||||
Returns:
|
||||
Returns 0 on success. Negative value on failure.
|
||||
|
||||
Remarks:
|
||||
- Returns ~/.appname on UNIX based systems
|
||||
- Returns ~/Library/Applications Support/appname on Mac OS X
|
||||
- Returns %APPDATA%/Appname on Windows based systems
|
||||
*/
|
||||
int fs_storage_path(const char *appname, char *path, int max);
|
||||
|
||||
/*
|
||||
Function: fs_is_dir
|
||||
Checks if directory exists
|
||||
|
||||
Returns:
|
||||
Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
int fs_is_dir(const char *path);
|
||||
|
||||
/*
|
||||
Function: fs_chdir
|
||||
Changes current working directory
|
||||
|
||||
Returns:
|
||||
Returns 0 on success, 1 on failure.
|
||||
*/
|
||||
int fs_chdir(const char *path);
|
||||
|
||||
/*
|
||||
Group: Undocumented
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Function: net_tcp_connect_non_blocking
|
||||
|
||||
DOCTODO: serp
|
||||
*/
|
||||
int net_tcp_connect_non_blocking(NETSOCKET sock, const NETADDR *a);
|
||||
|
||||
/*
|
||||
Function: net_tcp_set_non_blocking
|
||||
|
||||
DOCTODO: serp
|
||||
*/
|
||||
int net_tcp_set_non_blocking(NETSOCKET sock);
|
||||
|
||||
/*
|
||||
Function: net_tcp_set_non_blocking
|
||||
|
||||
DOCTODO: serp
|
||||
*/
|
||||
int net_tcp_set_blocking(NETSOCKET sock);
|
||||
|
||||
/*
|
||||
Function: net_errno
|
||||
|
||||
DOCTODO: serp
|
||||
*/
|
||||
int net_errno();
|
||||
|
||||
/*
|
||||
Function: net_would_block
|
||||
|
||||
DOCTODO: serp
|
||||
*/
|
||||
int net_would_block();
|
||||
|
||||
int net_socket_read_wait(NETSOCKET sock, int time);
|
||||
|
||||
void mem_debug_dump();
|
||||
|
||||
void swap_endian(void *data, unsigned elem_size, unsigned num);
|
||||
|
||||
typedef void (*DBG_LOGGER)(const char *line);
|
||||
void dbg_logger(DBG_LOGGER logger);
|
||||
void dbg_logger_stdout();
|
||||
void dbg_logger_debugger();
|
||||
void dbg_logger_file(const char *filename);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int allocated;
|
||||
int active_allocations;
|
||||
int total_allocations;
|
||||
} MEMSTATS;
|
||||
|
||||
const MEMSTATS *mem_stats();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int sent_packets;
|
||||
int sent_bytes;
|
||||
int recv_packets;
|
||||
int recv_bytes;
|
||||
} NETSTATS;
|
||||
|
||||
|
||||
void net_stats(NETSTATS *stats);
|
||||
|
||||
int str_isspace(char c);
|
||||
|
||||
|
||||
/*
|
||||
Function: gui_messagebox
|
||||
Display plain OS-dependent message box
|
||||
|
||||
Parameters:
|
||||
title - title of the message box
|
||||
message - text to display
|
||||
*/
|
||||
void gui_messagebox(const char *title, const char *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,196 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef BASE_VMATH_H
|
||||
#define BASE_VMATH_H
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
template<typename T>
|
||||
class vector2_base
|
||||
{
|
||||
public:
|
||||
union { T x,u; };
|
||||
union { T y,v; };
|
||||
|
||||
vector2_base() {}
|
||||
vector2_base(float nx, float ny)
|
||||
{
|
||||
x = nx;
|
||||
y = ny;
|
||||
}
|
||||
|
||||
vector2_base operator -() const { return vector2_base(-x, -y); }
|
||||
vector2_base operator -(const vector2_base &v) const { return vector2_base(x-v.x, y-v.y); }
|
||||
vector2_base operator +(const vector2_base &v) const { return vector2_base(x+v.x, y+v.y); }
|
||||
vector2_base operator *(const T v) const { return vector2_base(x*v, y*v); }
|
||||
|
||||
const vector2_base &operator =(const vector2_base &v) { x = v.x; y = v.y; return *this; }
|
||||
|
||||
const vector2_base &operator +=(const vector2_base &v) { x += v.x; y += v.y; return *this; }
|
||||
const vector2_base &operator -=(const vector2_base &v) { x -= v.x; y -= v.y; return *this; }
|
||||
const vector2_base &operator *=(const T v) { x *= v; y *= v; return *this; }
|
||||
|
||||
bool operator ==(const vector2_base &v) const { return x == v.x && y == v.y; } //TODO: do this with an eps instead
|
||||
|
||||
operator const T* () { return &x; }
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline T length(const vector2_base<T> &a)
|
||||
{
|
||||
return sqrtf(a.x*a.x + a.y*a.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T distance(const vector2_base<T> a, const vector2_base<T> &b)
|
||||
{
|
||||
return length(a-b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T dot(const vector2_base<T> a, const vector2_base<T> &b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline vector2_base<T> normalize(const vector2_base<T> &v)
|
||||
{
|
||||
T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y));
|
||||
return vector2_base<T>(v.x*l, v.y*l);
|
||||
}
|
||||
|
||||
typedef vector2_base<float> vec2;
|
||||
typedef vector2_base<bool> bvec2;
|
||||
typedef vector2_base<int> ivec2;
|
||||
|
||||
template<typename T>
|
||||
inline vector2_base<T> closest_point_on_line(vector2_base<T> line_point0, vector2_base<T> line_point1, vector2_base<T> target_point)
|
||||
{
|
||||
vector2_base<T> c = target_point - line_point0;
|
||||
vector2_base<T> v = (line_point1 - line_point0);
|
||||
v = normalize(v);
|
||||
T d = length(line_point0-line_point1);
|
||||
T t = dot(v, c)/d;
|
||||
return mix(line_point0, line_point1, clamp(t, (T)0, (T)1));
|
||||
/*
|
||||
if (t < 0) t = 0;
|
||||
if (t > 1.0f) return 1.0f;
|
||||
return t;*/
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
template<typename T>
|
||||
class vector3_base
|
||||
{
|
||||
public:
|
||||
union { T x,r,h; };
|
||||
union { T y,g,s; };
|
||||
union { T z,b,v,l; };
|
||||
|
||||
vector3_base() {}
|
||||
vector3_base(float nx, float ny, float nz)
|
||||
{
|
||||
x = nx;
|
||||
y = ny;
|
||||
z = nz;
|
||||
}
|
||||
|
||||
const vector3_base &operator =(const vector3_base &v) { x = v.x; y = v.y; z = v.z; return *this; }
|
||||
|
||||
vector3_base operator -(const vector3_base &v) const { return vector3_base(x-v.x, y-v.y, z-v.z); }
|
||||
vector3_base operator -() const { return vector3_base(-x, -y, -z); }
|
||||
vector3_base operator +(const vector3_base &v) const { return vector3_base(x+v.x, y+v.y, z+v.z); }
|
||||
vector3_base operator *(const T v) const { return vector3_base(x*v, y*v, z*v); }
|
||||
vector3_base operator *(const vector3_base &v) const { return vector3_base(x*v.x, y*v.y, z*v.z); }
|
||||
vector3_base operator /(const T v) const { return vector3_base(x/v, y/v, z/v); }
|
||||
|
||||
const vector3_base &operator +=(const vector3_base &v) { x += v.x; y += v.y; z += v.z; return *this; }
|
||||
const vector3_base &operator -=(const vector3_base &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
|
||||
const vector3_base &operator *=(const T v) { x *= v; y *= v; z *= v; return *this; }
|
||||
|
||||
bool operator ==(const vector3_base &v) const { return x == v.x && y == v.y && z == v.z; } //TODO: do this with an eps instead
|
||||
|
||||
operator const T* () { return &x; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T length(const vector3_base<T> &a)
|
||||
{
|
||||
return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T distance(const vector3_base<T> &a, const vector3_base<T> &b)
|
||||
{
|
||||
return length(a-b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T dot(const vector3_base<T> &a, const vector3_base<T> &b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline vector3_base<T> normalize(const vector3_base<T> &v)
|
||||
{
|
||||
T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y + v.z*v.z));
|
||||
return vector3_base<T>(v.x*l, v.y*l, v.z*l);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline vector3_base<T> cross(const vector3_base<T> &a, const vector3_base<T> &b)
|
||||
{
|
||||
return vector3_base<T>(
|
||||
a.y*b.z - a.z*b.y,
|
||||
a.z*b.x - a.x*b.z,
|
||||
a.x*b.y - a.y*b.x);
|
||||
}
|
||||
|
||||
typedef vector3_base<float> vec3;
|
||||
typedef vector3_base<bool> bvec3;
|
||||
typedef vector3_base<int> ivec3;
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
template<typename T>
|
||||
class vector4_base
|
||||
{
|
||||
public:
|
||||
union { T x,r; };
|
||||
union { T y,g; };
|
||||
union { T z,b; };
|
||||
union { T w,a; };
|
||||
|
||||
vector4_base() {}
|
||||
vector4_base(float nx, float ny, float nz, float nw)
|
||||
{
|
||||
x = nx;
|
||||
y = ny;
|
||||
z = nz;
|
||||
w = nw;
|
||||
}
|
||||
|
||||
vector4_base operator +(const vector4_base &v) const { return vector4_base(x+v.x, y+v.y, z+v.z, w+v.w); }
|
||||
vector4_base operator -(const vector4_base &v) const { return vector4_base(x-v.x, y-v.y, z-v.z, w-v.w); }
|
||||
vector4_base operator -() const { return vector4_base(-x, -y, -z, -w); }
|
||||
vector4_base operator *(const vector4_base &v) const { return vector4_base(x*v.x, y*v.y, z*v.z, w*v.w); }
|
||||
vector4_base operator *(const T v) const { return vector4_base(x*v, y*v, z*v, w*v); }
|
||||
|
||||
const vector4_base &operator =(const vector4_base &v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this; }
|
||||
|
||||
const vector4_base &operator +=(const vector4_base &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
|
||||
const vector4_base &operator -=(const vector4_base &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
|
||||
const vector4_base &operator *=(const T v) { x *= v; y *= v; z *= v; w *= v; return *this; }
|
||||
|
||||
bool operator ==(const vector4_base &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; } //TODO: do this with an eps instead
|
||||
|
||||
operator const T* () { return &x; }
|
||||
};
|
||||
|
||||
typedef vector4_base<float> vec4;
|
||||
typedef vector4_base<bool> bvec4;
|
||||
typedef vector4_base<int> ivec4;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,199 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <base/system.h>
|
||||
#include <engine/e_client_interface.h>
|
||||
#include <engine/e_engine.h>
|
||||
#include "ec_font.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short x, y;
|
||||
short width, height;
|
||||
short x_offset, y_offset;
|
||||
short x_advance;
|
||||
} FONT_CHARACTER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short size;
|
||||
short width, height;
|
||||
|
||||
short line_height;
|
||||
short base;
|
||||
|
||||
FONT_CHARACTER characters[256];
|
||||
|
||||
short kerning[256*256];
|
||||
} FONT_DATA;
|
||||
|
||||
int font_load(FONT *font, const char *filename)
|
||||
{
|
||||
FONT_DATA font_data;
|
||||
IOHANDLE file;
|
||||
|
||||
file = engine_openfile(filename, IOFLAG_READ);
|
||||
|
||||
if(file)
|
||||
{
|
||||
int i;
|
||||
|
||||
io_read(file, &font_data, sizeof(FONT_DATA));
|
||||
io_close(file);
|
||||
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
swap_endian(&font_data, 2, sizeof(FONT_DATA)/2);
|
||||
#endif
|
||||
|
||||
{
|
||||
float scale_factor_x = 1.0f/font_data.size;
|
||||
float scale_factor_y = 1.0f/font_data.size;
|
||||
float scale_factor_tex_x = 1.0f/font_data.width;
|
||||
float scale_factor_tex_y = 1.0f/font_data.height;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
float tex_x0 = font_data.characters[i].x*scale_factor_tex_x;
|
||||
float tex_y0 = font_data.characters[i].y*scale_factor_tex_y;
|
||||
float tex_x1 = (font_data.characters[i].x+font_data.characters[i].width)*scale_factor_tex_x;
|
||||
float tex_y1 = (font_data.characters[i].y+font_data.characters[i].height)*scale_factor_tex_y;
|
||||
|
||||
float width = font_data.characters[i].width*scale_factor_x;
|
||||
float height = font_data.characters[i].height*scale_factor_y;
|
||||
float x_offset = font_data.characters[i].x_offset*scale_factor_x;
|
||||
float y_offset = font_data.characters[i].y_offset*scale_factor_y;
|
||||
float x_advance = (font_data.characters[i].x_advance)*scale_factor_x;
|
||||
|
||||
font->characters[i].tex_x0 = tex_x0;
|
||||
font->characters[i].tex_y0 = tex_y0;
|
||||
font->characters[i].tex_x1 = tex_x1;
|
||||
font->characters[i].tex_y1 = tex_y1;
|
||||
font->characters[i].width = width;
|
||||
font->characters[i].height = height;
|
||||
font->characters[i].x_offset = x_offset;
|
||||
font->characters[i].y_offset = y_offset;
|
||||
font->characters[i].x_advance = x_advance;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 256*256; i++)
|
||||
{
|
||||
font->kerning[i] = (char)font_data.kerning[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*int gfx_load_texture(const char *filename, int store_format, int flags);
|
||||
#define IMG_ALPHA 2*/
|
||||
|
||||
int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_texture_filename, int fonts, ...)
|
||||
{
|
||||
int i;
|
||||
va_list va;
|
||||
|
||||
font_set->font_count = fonts;
|
||||
|
||||
va_start(va, fonts);
|
||||
for (i = 0; i < fonts; i++)
|
||||
{
|
||||
int size;
|
||||
char composed_font_filename[256];
|
||||
char composed_text_texture_filename[256];
|
||||
char composed_outline_texture_filename[256];
|
||||
FONT *font = &font_set->fonts[i];
|
||||
|
||||
size = va_arg(va, int);
|
||||
str_format(composed_font_filename, sizeof(composed_font_filename), font_filename, size);
|
||||
str_format(composed_text_texture_filename, sizeof(composed_text_texture_filename), text_texture_filename, size);
|
||||
str_format(composed_outline_texture_filename, sizeof(composed_outline_texture_filename), outline_texture_filename, size);
|
||||
|
||||
if (font_load(font, composed_font_filename))
|
||||
{
|
||||
dbg_msg("font/loading", "failed loading font %s.", composed_font_filename);
|
||||
va_end(va);
|
||||
return -1;
|
||||
}
|
||||
|
||||
font->size = size;
|
||||
font->text_texture = gfx_load_texture(composed_text_texture_filename, IMG_ALPHA, TEXLOAD_NORESAMPLE);
|
||||
font->outline_texture = gfx_load_texture(composed_outline_texture_filename, IMG_ALPHA, TEXLOAD_NORESAMPLE);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float font_text_width(FONT *font, const char *text, float size, int length)
|
||||
{
|
||||
float width = 0.0f;
|
||||
|
||||
const unsigned char *c = (unsigned char *)text;
|
||||
int chars_left;
|
||||
if (length == -1)
|
||||
chars_left = strlen(text);
|
||||
else
|
||||
chars_left = length;
|
||||
|
||||
while (chars_left--)
|
||||
{
|
||||
float tex_x0, tex_y0, tex_x1, tex_y1;
|
||||
float char_width, char_height;
|
||||
float x_offset, y_offset, x_advance;
|
||||
float advance;
|
||||
|
||||
font_character_info(font, *c, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &char_width, &char_height, &x_offset, &y_offset, &x_advance);
|
||||
|
||||
advance = x_advance + font_kerning(font, *c, *(c+1));
|
||||
|
||||
width += advance;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return width*size;
|
||||
}
|
||||
|
||||
void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_y0, float *tex_x1, float *tex_y1, float *width, float *height, float *x_offset, float *y_offset, float *x_advance)
|
||||
{
|
||||
CHARACTER *character = &font->characters[c];
|
||||
|
||||
*tex_x0 = character->tex_x0;
|
||||
*tex_y0 = character->tex_y0;
|
||||
*tex_x1 = character->tex_x1;
|
||||
*tex_y1 = character->tex_y1;
|
||||
*width = character->width;
|
||||
*height = character->height;
|
||||
*x_offset = character->x_offset;
|
||||
*y_offset = character->y_offset;
|
||||
*x_advance = character->x_advance;
|
||||
}
|
||||
|
||||
float font_kerning(FONT *font, unsigned char c1, unsigned char c2)
|
||||
{
|
||||
return font->kerning[c1 + c2*256] / (float)font->size;
|
||||
}
|
||||
|
||||
FONT *font_set_pick(FONT_SET *font_set, float size)
|
||||
{
|
||||
int i;
|
||||
FONT *picked_font = 0x0;
|
||||
|
||||
for (i = font_set->font_count-1; i >= 0; i--)
|
||||
{
|
||||
FONT *font = &font_set->fonts[i];
|
||||
|
||||
if (font->size >= size)
|
||||
picked_font = font;
|
||||
}
|
||||
|
||||
if (!picked_font)
|
||||
picked_font = &font_set->fonts[font_set->font_count-1];
|
||||
|
||||
return picked_font;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef _FONT_H
|
||||
#define _FONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float tex_x0;
|
||||
float tex_y0;
|
||||
float tex_x1;
|
||||
float tex_y1;
|
||||
float width;
|
||||
float height;
|
||||
float x_offset;
|
||||
float y_offset;
|
||||
float x_advance;
|
||||
}
|
||||
CHARACTER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int text_texture;
|
||||
int outline_texture;
|
||||
int size;
|
||||
CHARACTER characters[256];
|
||||
char kerning[256*256];
|
||||
} FONT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int font_count;
|
||||
FONT fonts[14];
|
||||
} FONT_SET;
|
||||
|
||||
int font_load(FONT *font, const char *filename);
|
||||
int font_set_load(FONT_SET *font_set, const char *font_filename, const char *text_texture_filename, const char *outline_texture_filename, int fonts, ...);
|
||||
float font_text_width(FONT *font, const char *text, float size, int width);
|
||||
void font_character_info(FONT *font, unsigned char c, float *tex_x0, float *tex_y0, float *tex_x1, float *tex_y1, float *width, float *height, float *x_offset, float *y_offset, float *x_advance);
|
||||
float font_kerning(FONT *font, unsigned char c1, unsigned char c2);
|
||||
FONT *font_set_pick(FONT_SET *font_set, float size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,239 +0,0 @@
|
||||
#include <base/system.h>
|
||||
#include <string.h>
|
||||
#include <engine/e_client_interface.h>
|
||||
|
||||
static int word_length(const char *text)
|
||||
{
|
||||
int s = 1;
|
||||
while(1)
|
||||
{
|
||||
if(*text == 0)
|
||||
return s-1;
|
||||
if(*text == '\n' || *text == '\t' || *text == ' ')
|
||||
return s;
|
||||
text++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static float text_r=1;
|
||||
static float text_g=1;
|
||||
static float text_b=1;
|
||||
static float text_a=1;
|
||||
|
||||
static FONT_SET *default_font_set = 0;
|
||||
void gfx_text_set_default_font(void *font)
|
||||
{
|
||||
default_font_set = (FONT_SET *)font;
|
||||
}
|
||||
|
||||
|
||||
void gfx_text_set_cursor(TEXT_CURSOR *cursor, float x, float y, float font_size, int flags)
|
||||
{
|
||||
mem_zero(cursor, sizeof(*cursor));
|
||||
cursor->font_size = font_size;
|
||||
cursor->start_x = x;
|
||||
cursor->start_y = y;
|
||||
cursor->x = x;
|
||||
cursor->y = y;
|
||||
cursor->line_count = 1;
|
||||
cursor->line_width = -1;
|
||||
cursor->flags = flags;
|
||||
cursor->charcount = 0;
|
||||
}
|
||||
|
||||
void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length)
|
||||
{
|
||||
FONT_SET *font_set = (FONT_SET *)cursor->font_set;
|
||||
float screen_x0, screen_y0, screen_x1, screen_y1;
|
||||
float fake_to_screen_x, fake_to_screen_y;
|
||||
int actual_x, actual_y;
|
||||
|
||||
FONT *font;
|
||||
int actual_size;
|
||||
int i;
|
||||
int got_new_line = 0;
|
||||
float draw_x, draw_y;
|
||||
float cursor_x, cursor_y;
|
||||
const char *end;
|
||||
|
||||
float size = cursor->font_size;
|
||||
|
||||
/* to correct coords, convert to screen coords, round, and convert back */
|
||||
gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1);
|
||||
|
||||
fake_to_screen_x = (gfx_screenwidth()/(screen_x1-screen_x0));
|
||||
fake_to_screen_y = (gfx_screenheight()/(screen_y1-screen_y0));
|
||||
actual_x = cursor->x * fake_to_screen_x;
|
||||
actual_y = cursor->y * fake_to_screen_y;
|
||||
|
||||
cursor_x = actual_x / fake_to_screen_x;
|
||||
cursor_y = actual_y / fake_to_screen_y;
|
||||
|
||||
/* same with size */
|
||||
actual_size = size * fake_to_screen_y;
|
||||
size = actual_size / fake_to_screen_y;
|
||||
|
||||
if(!font_set)
|
||||
font_set = default_font_set;
|
||||
|
||||
font = font_set_pick(font_set, actual_size);
|
||||
|
||||
if (length < 0)
|
||||
length = strlen(text);
|
||||
|
||||
end = text + length;
|
||||
|
||||
/* if we don't want to render, we can just skip the first outline pass */
|
||||
i = 1;
|
||||
if(cursor->flags&TEXTFLAG_RENDER)
|
||||
i = 0;
|
||||
|
||||
for(;i < 2; i++)
|
||||
{
|
||||
const unsigned char *current = (unsigned char *)text;
|
||||
int to_render = length;
|
||||
draw_x = cursor_x;
|
||||
draw_y = cursor_y;
|
||||
|
||||
if(cursor->flags&TEXTFLAG_RENDER)
|
||||
{
|
||||
if (i == 0)
|
||||
gfx_texture_set(font->outline_texture);
|
||||
else
|
||||
gfx_texture_set(font->text_texture);
|
||||
|
||||
gfx_quads_begin();
|
||||
if (i == 0)
|
||||
gfx_setcolor(0.0f, 0.0f, 0.0f, 0.3f*text_a);
|
||||
else
|
||||
gfx_setcolor(text_r, text_g, text_b, text_a);
|
||||
}
|
||||
|
||||
while(to_render > 0)
|
||||
{
|
||||
int new_line = 0;
|
||||
int this_batch = to_render;
|
||||
if(cursor->line_width > 0 && !(cursor->flags&TEXTFLAG_STOP_AT_END))
|
||||
{
|
||||
int wlen = word_length((char *)current);
|
||||
TEXT_CURSOR compare = *cursor;
|
||||
compare.x = draw_x;
|
||||
compare.y = draw_y;
|
||||
compare.flags &= ~TEXTFLAG_RENDER;
|
||||
compare.line_width = -1;
|
||||
gfx_text_ex(&compare, text, wlen);
|
||||
|
||||
if(compare.x-draw_x > cursor->line_width)
|
||||
{
|
||||
/* word can't be fitted in one line, cut it */
|
||||
TEXT_CURSOR cutter = *cursor;
|
||||
cutter.charcount = 0;
|
||||
cutter.x = draw_x;
|
||||
cutter.y = draw_y;
|
||||
cutter.flags &= ~TEXTFLAG_RENDER;
|
||||
cutter.flags |= TEXTFLAG_STOP_AT_END;
|
||||
|
||||
gfx_text_ex(&cutter, (const char *)current, wlen);
|
||||
wlen = cutter.charcount;
|
||||
new_line = 1;
|
||||
|
||||
if(wlen <= 3) /* if we can't place 3 chars of the word on this line, take the next */
|
||||
wlen = 0;
|
||||
}
|
||||
else if(compare.x-cursor->start_x > cursor->line_width)
|
||||
{
|
||||
new_line = 1;
|
||||
wlen = 0;
|
||||
}
|
||||
|
||||
this_batch = wlen;
|
||||
}
|
||||
|
||||
if((const char *)current+this_batch > end)
|
||||
this_batch = (const char *)end-(const char *)current;
|
||||
|
||||
to_render -= this_batch;
|
||||
|
||||
while(this_batch-- > 0)
|
||||
{
|
||||
float tex_x0, tex_y0, tex_x1, tex_y1;
|
||||
float width, height;
|
||||
float x_offset, y_offset, x_advance;
|
||||
float advance;
|
||||
|
||||
if(*current == '\n')
|
||||
{
|
||||
draw_x = cursor->start_x;
|
||||
draw_y += size;
|
||||
draw_x = (int)(draw_x * fake_to_screen_x) / fake_to_screen_x; /* realign */
|
||||
draw_y = (int)(draw_y * fake_to_screen_y) / fake_to_screen_y;
|
||||
current++;
|
||||
continue;
|
||||
}
|
||||
|
||||
font_character_info(font, *current, &tex_x0, &tex_y0, &tex_x1, &tex_y1, &width, &height, &x_offset, &y_offset, &x_advance);
|
||||
|
||||
if(cursor->flags&TEXTFLAG_RENDER)
|
||||
{
|
||||
gfx_quads_setsubset(tex_x0, tex_y0, tex_x1, tex_y1);
|
||||
gfx_quads_drawTL(draw_x+x_offset*size, draw_y+y_offset*size, width*size, height*size);
|
||||
}
|
||||
|
||||
advance = x_advance + font_kerning(font, *current, *(current+1));
|
||||
|
||||
if(cursor->flags&TEXTFLAG_STOP_AT_END && draw_x+advance*size-cursor->start_x > cursor->line_width)
|
||||
{
|
||||
/* we hit the end of the line, no more to render or count */
|
||||
to_render = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
draw_x += advance*size;
|
||||
cursor->charcount++;
|
||||
current++;
|
||||
}
|
||||
|
||||
if(new_line)
|
||||
{
|
||||
draw_x = cursor->start_x;
|
||||
draw_y += size;
|
||||
got_new_line = 1;
|
||||
draw_x = (int)(draw_x * fake_to_screen_x) / fake_to_screen_x; /* realign */
|
||||
draw_y = (int)(draw_y * fake_to_screen_y) / fake_to_screen_y;
|
||||
}
|
||||
}
|
||||
|
||||
if(cursor->flags&TEXTFLAG_RENDER)
|
||||
gfx_quads_end();
|
||||
}
|
||||
|
||||
cursor->x = draw_x;
|
||||
|
||||
if(got_new_line)
|
||||
cursor->y = draw_y;
|
||||
}
|
||||
|
||||
void gfx_text(void *font_set_v, float x, float y, float size, const char *text, int max_width)
|
||||
{
|
||||
TEXT_CURSOR cursor;
|
||||
gfx_text_set_cursor(&cursor, x, y, size, TEXTFLAG_RENDER);
|
||||
cursor.line_width = max_width;
|
||||
gfx_text_ex(&cursor, text, -1);
|
||||
}
|
||||
|
||||
float gfx_text_width(void *font_set_v, float size, const char *text, int length)
|
||||
{
|
||||
TEXT_CURSOR cursor;
|
||||
gfx_text_set_cursor(&cursor, 0, 0, size, 0);
|
||||
gfx_text_ex(&cursor, text, length);
|
||||
return cursor.x;
|
||||
}
|
||||
|
||||
void gfx_text_color(float r, float g, float b, float a)
|
||||
{
|
||||
text_r = r;
|
||||
text_g = g;
|
||||
text_b = b;
|
||||
text_a = a;
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
|
||||
#include <base/system.h>
|
||||
#include <engine/e_client_interface.h>
|
||||
#include <engine/e_config.h>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned char presses;
|
||||
unsigned char releases;
|
||||
} input_count[2][1024] = {{{0}}, {{0}}};
|
||||
|
||||
static unsigned char input_state[2][1024] = {{0}, {0}};
|
||||
|
||||
static int input_current = 0;
|
||||
static int input_grabbed = 0;
|
||||
|
||||
static unsigned int last_release = 0;
|
||||
static unsigned int release_delta = -1;
|
||||
|
||||
extern SDL_Joystick * EC_joystick;
|
||||
extern SDL_Surface *EC_screen_surface;
|
||||
|
||||
static void add_event(char c, int key, int flags);
|
||||
|
||||
void inp_mouse_relative(int *x, int *y)
|
||||
{
|
||||
int nx = 0, ny = 0;
|
||||
float sens = config.inp_mousesens/100.0f;
|
||||
|
||||
if(config.inp_grab)
|
||||
SDL_GetRelativeMouseState(&nx, &ny);
|
||||
else
|
||||
{
|
||||
if(input_grabbed)
|
||||
{
|
||||
SDL_GetMouseState(&nx,&ny);
|
||||
SDL_WarpMouse(gfx_screenwidth()/2,gfx_screenheight()/2);
|
||||
nx -= gfx_screenwidth()/2; ny -= gfx_screenheight()/2;
|
||||
}
|
||||
}
|
||||
|
||||
*x = nx*sens;
|
||||
*y = ny*sens;
|
||||
}
|
||||
|
||||
void inp_mouse_absolute(int *x, int *y)
|
||||
{
|
||||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
||||
void inp_warp_mouse(int x, int y)
|
||||
{
|
||||
SDL_WarpMouse(x,y);
|
||||
}
|
||||
|
||||
int inp_process_joystick()
|
||||
{
|
||||
if( !EC_joystick || !EC_screen_surface )
|
||||
return 0;
|
||||
int jx = SDL_JoystickGetAxis(EC_joystick, 0);
|
||||
int jy = SDL_JoystickGetAxis(EC_joystick, 1);
|
||||
if( abs(jx) > 10 && abs(jy) > 10 )
|
||||
{
|
||||
jx = (jx + 32768) * EC_screen_surface->w / 65536;
|
||||
jy = (jy + 32768) * EC_screen_surface->h / 65536;
|
||||
SDL_WarpMouse(jx,jy);
|
||||
SDL_PumpEvents();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
INPUT_BUFFER_SIZE=32
|
||||
};
|
||||
|
||||
static INPUT_EVENT input_events[INPUT_BUFFER_SIZE];
|
||||
static int num_events = 0;
|
||||
|
||||
static void add_event(char c, int key, int flags)
|
||||
{
|
||||
if(num_events != INPUT_BUFFER_SIZE)
|
||||
{
|
||||
input_events[num_events].ch = c;
|
||||
input_events[num_events].key = key;
|
||||
input_events[num_events].flags = flags;
|
||||
num_events++;
|
||||
}
|
||||
}
|
||||
|
||||
int inp_num_events()
|
||||
{
|
||||
return num_events;
|
||||
}
|
||||
|
||||
void inp_clear_events()
|
||||
{
|
||||
num_events = 0;
|
||||
}
|
||||
|
||||
INPUT_EVENT inp_get_event(int index)
|
||||
{
|
||||
if(index < 0 || index >= num_events)
|
||||
{
|
||||
INPUT_EVENT e = {0,0};
|
||||
return e;
|
||||
}
|
||||
|
||||
return input_events[index];
|
||||
}
|
||||
|
||||
void inp_init()
|
||||
{
|
||||
SDL_EnableUNICODE(1);
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
}
|
||||
|
||||
void inp_mouse_mode_absolute()
|
||||
{
|
||||
SDL_ShowCursor(1);
|
||||
input_grabbed = 0;
|
||||
if(config.inp_grab)
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
}
|
||||
|
||||
void inp_mouse_mode_relative()
|
||||
{
|
||||
SDL_ShowCursor(0);
|
||||
input_grabbed = 1;
|
||||
if(config.inp_grab)
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
}
|
||||
|
||||
int inp_mouse_doubleclick()
|
||||
{
|
||||
return release_delta < (time_freq() >> 2);
|
||||
}
|
||||
|
||||
void inp_clear_key_states()
|
||||
{
|
||||
mem_zero(input_state, sizeof(input_state));
|
||||
mem_zero(input_count, sizeof(input_count));
|
||||
}
|
||||
|
||||
int inp_key_presses(int key)
|
||||
{
|
||||
return input_count[input_current][key].presses;
|
||||
}
|
||||
|
||||
int inp_key_releases(int key)
|
||||
{
|
||||
return input_count[input_current][key].releases;
|
||||
}
|
||||
|
||||
int inp_key_state(int key)
|
||||
{
|
||||
return input_state[input_current][key];
|
||||
}
|
||||
|
||||
int inp_key_pressed(int key) { return input_state[input_current][key]; }
|
||||
int inp_key_was_pressed(int key) { return input_state[input_current^1][key]; }
|
||||
int inp_key_down(int key) { return inp_key_pressed(key)&&!inp_key_was_pressed(key); }
|
||||
int inp_button_pressed(int button) { return input_state[input_current][button]; }
|
||||
|
||||
static int oldjoy = 0;
|
||||
|
||||
void inp_update()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(input_grabbed && !gfx_window_active())
|
||||
inp_mouse_mode_absolute();
|
||||
|
||||
/*if(!input_grabbed && gfx_window_active())
|
||||
inp_mouse_mode_relative();*/
|
||||
|
||||
/* clear and begin count on the other one */
|
||||
input_current^=1;
|
||||
mem_zero(&input_count[input_current], sizeof(input_count[input_current]));
|
||||
mem_zero(&input_state[input_current], sizeof(input_state[input_current]));
|
||||
|
||||
{
|
||||
Uint8 *state = SDL_GetKeyState(&i);
|
||||
if(i >= KEY_LAST)
|
||||
i = KEY_LAST-1;
|
||||
mem_copy(input_state[input_current], state, i);
|
||||
}
|
||||
|
||||
/* these states must always be updated manually because they are not in the GetKeyState from SDL */
|
||||
i = SDL_GetMouseState(NULL, NULL);
|
||||
int joy = inp_process_joystick();
|
||||
if(i&SDL_BUTTON(1)) input_state[input_current][KEY_MOUSE_1] = 1; /* 1 is left */
|
||||
if(i&SDL_BUTTON(3)) input_state[input_current][KEY_MOUSE_2] = 1; /* 3 is right */
|
||||
if(i&SDL_BUTTON(2)) input_state[input_current][KEY_MOUSE_3] = 1; /* 2 is middle */
|
||||
if(i&SDL_BUTTON(4)) input_state[input_current][KEY_MOUSE_4] = 1;
|
||||
if(i&SDL_BUTTON(5)) input_state[input_current][KEY_MOUSE_5] = 1;
|
||||
if(i&SDL_BUTTON(6)) input_state[input_current][KEY_MOUSE_6] = 1;
|
||||
if(i&SDL_BUTTON(7)) input_state[input_current][KEY_MOUSE_7] = 1;
|
||||
if(i&SDL_BUTTON(8)) input_state[input_current][KEY_MOUSE_8] = 1;
|
||||
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
while(SDL_PollEvent(&event))
|
||||
{
|
||||
int key = -1;
|
||||
int action = INPFLAG_PRESS;
|
||||
switch (event.type)
|
||||
{
|
||||
/* handle keys */
|
||||
case SDL_KEYDOWN:
|
||||
if(event.key.keysym.unicode < 255)
|
||||
add_event(event.key.keysym.unicode, 0, 0);
|
||||
key = event.key.keysym.sym;
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
action = INPFLAG_RELEASE;
|
||||
key = event.key.keysym.sym;
|
||||
break;
|
||||
|
||||
/* handle mouse buttons */
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
action = INPFLAG_RELEASE;
|
||||
|
||||
if(event.button.button == 1)
|
||||
{
|
||||
release_delta = time_get() - last_release;
|
||||
last_release = time_get();
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if(event.button.button == SDL_BUTTON_LEFT) key = KEY_MOUSE_1;
|
||||
if(event.button.button == SDL_BUTTON_RIGHT) key = KEY_MOUSE_2;
|
||||
if(event.button.button == SDL_BUTTON_MIDDLE) key = KEY_MOUSE_3;
|
||||
if(event.button.button == SDL_BUTTON_WHEELUP) key = KEY_MOUSE_WHEEL_UP;
|
||||
if(event.button.button == SDL_BUTTON_WHEELDOWN) key = KEY_MOUSE_WHEEL_DOWN;
|
||||
if(event.button.button == 6) key = KEY_MOUSE_6;
|
||||
if(event.button.button == 7) key = KEY_MOUSE_7;
|
||||
if(event.button.button == 8) key = KEY_MOUSE_8;
|
||||
break;
|
||||
|
||||
/* other messages */
|
||||
case SDL_QUIT:
|
||||
#ifdef ANDROID
|
||||
case SDL_VIDEORESIZE:
|
||||
#endif
|
||||
/* TODO: cleaner exit */
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* */
|
||||
if(key != -1)
|
||||
{
|
||||
input_count[input_current][key].presses++;
|
||||
if(action == INPFLAG_PRESS)
|
||||
input_state[input_current][key] = 1;
|
||||
add_event(0, key, action);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(joy && !input_state[input_current][KEY_MOUSE_1])
|
||||
{
|
||||
input_count[input_current][KEY_MOUSE_1].presses++;
|
||||
add_event(0, KEY_MOUSE_1, INPFLAG_PRESS);
|
||||
}
|
||||
if(!joy && oldjoy && !(i&SDL_BUTTON(1)))
|
||||
{
|
||||
input_count[input_current][KEY_MOUSE_1].presses++;
|
||||
add_event(0, KEY_MOUSE_1, INPFLAG_RELEASE);
|
||||
}
|
||||
oldjoy = joy;
|
||||
}
|
||||
}
|
||||
@@ -1,482 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include <engine/e_client_interface.h>
|
||||
#include <engine/e_config.h>
|
||||
#include <engine/e_engine.h>
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include <engine/external/wavpack/wavpack.h>
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#ifdef ANDROID
|
||||
#include <strings.h>
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SAMPLES = 512,
|
||||
NUM_VOICES = 64,
|
||||
NUM_CHANNELS = 16,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short *data;
|
||||
int num_frames;
|
||||
int rate;
|
||||
int channels;
|
||||
int loop_start;
|
||||
int loop_end;
|
||||
} SAMPLE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vol;
|
||||
int pan;
|
||||
} CHANNEL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SAMPLE *snd;
|
||||
CHANNEL *channel;
|
||||
int tick;
|
||||
int vol; /* 0 - 255 */
|
||||
int flags;
|
||||
int x, y;
|
||||
} VOICE;
|
||||
|
||||
static SAMPLE samples[NUM_SAMPLES] = { {0} };
|
||||
static VOICE voices[NUM_VOICES] = { {0} };
|
||||
static CHANNEL channels[NUM_CHANNELS] = { {255, 0} };
|
||||
|
||||
static LOCK sound_lock = 0;
|
||||
static int sound_enabled = 0;
|
||||
|
||||
static int center_x = 0;
|
||||
static int center_y = 0;
|
||||
|
||||
static int mixing_rate = 48000;
|
||||
static volatile int sound_volume = 100;
|
||||
|
||||
static int next_voice = 0;
|
||||
static int * mix_buffer = NULL;
|
||||
|
||||
void snd_set_channel(int cid, float vol, float pan)
|
||||
{
|
||||
channels[cid].vol = (int)(vol*255.0f);
|
||||
channels[cid].pan = (int)(pan*255.0f); /* TODO: this is only on and off right now */
|
||||
}
|
||||
|
||||
static int play(int cid, int sid, int flags, float x, float y)
|
||||
{
|
||||
int vid = -1;
|
||||
int i;
|
||||
|
||||
lock_wait(sound_lock);
|
||||
|
||||
/* search for voice */
|
||||
for(i = 0; i < NUM_VOICES; i++)
|
||||
{
|
||||
int id = (next_voice + i) % NUM_VOICES;
|
||||
if(!voices[id].snd)
|
||||
{
|
||||
vid = id;
|
||||
next_voice = id+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* voice found, use it */
|
||||
if(vid != -1)
|
||||
{
|
||||
voices[vid].snd = &samples[sid];
|
||||
voices[vid].channel = &channels[cid];
|
||||
voices[vid].tick = 0;
|
||||
voices[vid].vol = 255;
|
||||
voices[vid].flags = flags;
|
||||
voices[vid].x = (int)x;
|
||||
voices[vid].y = (int)y;
|
||||
}
|
||||
|
||||
lock_release(sound_lock);
|
||||
return vid;
|
||||
}
|
||||
|
||||
int snd_play_at(int cid, int sid, int flags, float x, float y)
|
||||
{
|
||||
return play(cid, sid, flags|SNDFLAG_POS, x, y);
|
||||
}
|
||||
|
||||
int snd_play(int cid, int sid, int flags)
|
||||
{
|
||||
return play(cid, sid, flags, 0, 0);
|
||||
}
|
||||
|
||||
void snd_stop(int vid)
|
||||
{
|
||||
/* TODO: a nice fade out */
|
||||
lock_wait(sound_lock);
|
||||
voices[vid].snd = 0;
|
||||
lock_release(sound_lock);
|
||||
}
|
||||
|
||||
/* TODO: there should be a faster way todo this */
|
||||
static short int2short(int i)
|
||||
{
|
||||
if(i > 0x7fff)
|
||||
return 0x7fff;
|
||||
else if(i < -0x7fff)
|
||||
return -0x7fff;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int iabs(int i)
|
||||
{
|
||||
if(i<0)
|
||||
return -i;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void mix(short *final_out, unsigned frames)
|
||||
{
|
||||
int i, s;
|
||||
int master_vol;
|
||||
|
||||
/* aquire lock while we are mixing */
|
||||
lock_wait(sound_lock);
|
||||
|
||||
#ifdef ANDROID
|
||||
bzero(mix_buffer, frames * 2 * sizeof(int));
|
||||
#else
|
||||
memset(mix_buffer, 0, sizeof(mix_buffer));
|
||||
#endif
|
||||
|
||||
master_vol = sound_volume;
|
||||
|
||||
for(i = 0; i < NUM_VOICES; i++)
|
||||
{
|
||||
if(voices[i].snd)
|
||||
{
|
||||
/* mix voice */
|
||||
VOICE *v = &voices[i];
|
||||
int *out = mix_buffer;
|
||||
|
||||
int step = v->snd->channels; /* setup input sources */
|
||||
short *in_l = &v->snd->data[v->tick*step];
|
||||
short *in_r = &v->snd->data[v->tick*step+1];
|
||||
|
||||
int end = v->snd->num_frames-v->tick;
|
||||
|
||||
int rvol = v->channel->vol;
|
||||
int lvol = v->channel->vol;
|
||||
|
||||
/* make sure that we don't go outside the sound data */
|
||||
if(frames < end)
|
||||
end = frames;
|
||||
|
||||
/* check if we have a mono sound */
|
||||
if(v->snd->channels == 1)
|
||||
in_r = in_l;
|
||||
|
||||
/* volume calculation */
|
||||
if(v->flags&SNDFLAG_POS && v->channel->pan)
|
||||
{
|
||||
/* TODO: we should respect the channel panning value */
|
||||
const int range = 1500; /* magic value, remove */
|
||||
int dx = v->x - center_x;
|
||||
int dy = v->y - center_y;
|
||||
int dist = sqrt(dx*dx+dy*dy); /* double here. nasty */
|
||||
int p = iabs(dx);
|
||||
if(dist < range)
|
||||
{
|
||||
/* panning */
|
||||
if(dx > 0)
|
||||
lvol = ((range-p)*lvol)/range;
|
||||
else
|
||||
rvol = ((range-p)*rvol)/range;
|
||||
|
||||
/* falloff */
|
||||
lvol = (lvol*(range-dist))/range;
|
||||
rvol = (rvol*(range-dist))/range;
|
||||
}
|
||||
else
|
||||
{
|
||||
lvol = 0;
|
||||
rvol = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* process all frames */
|
||||
for(s = 0; s < end; s++)
|
||||
{
|
||||
*out++ += (*in_l)*lvol;
|
||||
*out++ += (*in_r)*rvol;
|
||||
in_l += step;
|
||||
in_r += step;
|
||||
v->tick++;
|
||||
}
|
||||
|
||||
/* free voice if not used any more */
|
||||
if(v->tick == v->snd->num_frames)
|
||||
v->snd = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* release the lock */
|
||||
lock_release(sound_lock);
|
||||
|
||||
{
|
||||
/* clamp accumulated values */
|
||||
/* TODO: this seams slow */
|
||||
for(i = 0; i < frames; i++)
|
||||
{
|
||||
int j = i<<1;
|
||||
int vl = ((mix_buffer[j]*master_vol)/101)>>8;
|
||||
int vr = ((mix_buffer[j+1]*master_vol)/101)>>8;
|
||||
|
||||
final_out[j] = int2short(vl);
|
||||
final_out[j+1] = int2short(vr);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
swap_endian(final_out, sizeof(short), frames * 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sdlcallback(void *unused, Uint8 *stream, int len)
|
||||
{
|
||||
mix((short *)stream, len/2/2);
|
||||
}
|
||||
|
||||
int snd_init()
|
||||
{
|
||||
SDL_AudioSpec format, format2;
|
||||
|
||||
sound_lock = lock_create();
|
||||
|
||||
if(!config.snd_enable)
|
||||
return 0;
|
||||
|
||||
mixing_rate = config.snd_rate;
|
||||
|
||||
/* Set 16-bit stereo audio at 22Khz */
|
||||
format.freq = config.snd_rate;
|
||||
format.format = AUDIO_S16;
|
||||
format.channels = 2;
|
||||
format.samples = config.snd_buffer_size;
|
||||
format.callback = sdlcallback;
|
||||
format.userdata = NULL;
|
||||
|
||||
/* Open the audio device and start playing sound! */
|
||||
if(SDL_OpenAudio(&format, &format2) < 0)
|
||||
{
|
||||
dbg_msg("client/sound", "unable to open audio: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
dbg_msg("client/sound", "sound init successful");
|
||||
|
||||
mix_buffer = (int *)malloc(format2.samples * 2 * sizeof(int));
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
sound_enabled = 1;
|
||||
snd_update(); /* update the volume */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_update()
|
||||
{
|
||||
/* update volume */
|
||||
int wanted_volume = config.snd_volume;
|
||||
|
||||
if(!gfx_window_active() && config.snd_nonactive_mute)
|
||||
wanted_volume = 0;
|
||||
|
||||
if(wanted_volume != sound_volume)
|
||||
{
|
||||
lock_wait(sound_lock);
|
||||
sound_volume = wanted_volume;
|
||||
lock_release(sound_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_shutdown()
|
||||
{
|
||||
SDL_CloseAudio();
|
||||
lock_destroy(sound_lock);
|
||||
if( mix_buffer )
|
||||
free(mix_buffer);
|
||||
mix_buffer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_alloc_id()
|
||||
{
|
||||
/* TODO: linear search, get rid of it */
|
||||
unsigned sid;
|
||||
for(sid = 0; sid < NUM_SAMPLES; sid++)
|
||||
{
|
||||
if(samples[sid].data == 0x0)
|
||||
return sid;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void rate_convert(int sid)
|
||||
{
|
||||
SAMPLE *snd = &samples[sid];
|
||||
int num_frames = 0;
|
||||
short *new_data = 0;
|
||||
int i;
|
||||
|
||||
/* make sure that we need to convert this sound */
|
||||
if(!snd->data || snd->rate == mixing_rate)
|
||||
return;
|
||||
|
||||
/* allocate new data */
|
||||
num_frames = (int)((snd->num_frames/(float)snd->rate)*mixing_rate);
|
||||
new_data = (Sint16 *)mem_alloc(num_frames*snd->channels*sizeof(short), 1);
|
||||
|
||||
for(i = 0; i < num_frames; i++)
|
||||
{
|
||||
/* resample TODO: this should be done better, like linear atleast */
|
||||
float a = i/(float)num_frames;
|
||||
int f = (int)(a*snd->num_frames);
|
||||
if(f >= snd->num_frames)
|
||||
f = snd->num_frames-1;
|
||||
|
||||
/* set new data */
|
||||
if(snd->channels == 1)
|
||||
new_data[i] = snd->data[f];
|
||||
else if(snd->channels == 2)
|
||||
{
|
||||
new_data[i*2] = snd->data[f*2];
|
||||
new_data[i*2+1] = snd->data[f*2+1];
|
||||
}
|
||||
}
|
||||
|
||||
/* free old data and apply new */
|
||||
mem_free(snd->data);
|
||||
snd->data = new_data;
|
||||
snd->num_frames = num_frames;
|
||||
}
|
||||
|
||||
|
||||
static IOHANDLE file = NULL;
|
||||
|
||||
static int read_data(void *buffer, int size)
|
||||
{
|
||||
return io_read(file, buffer, size);
|
||||
}
|
||||
|
||||
int snd_load_wv(const char *filename)
|
||||
{
|
||||
SAMPLE *snd;
|
||||
int sid = -1;
|
||||
char error[100];
|
||||
WavpackContext *context;
|
||||
|
||||
/* don't waste memory on sound when we are stress testing */
|
||||
if(config.dbg_stress)
|
||||
return -1;
|
||||
|
||||
/* no need to load sound when we are running with no sound */
|
||||
if(!sound_enabled)
|
||||
return 1;
|
||||
|
||||
file = engine_openfile(filename, IOFLAG_READ); /* TODO: use system.h stuff for this */
|
||||
if(!file)
|
||||
{
|
||||
dbg_msg("sound/wv", "failed to open %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sid = snd_alloc_id();
|
||||
if(sid < 0)
|
||||
return -1;
|
||||
snd = &samples[sid];
|
||||
|
||||
context = WavpackOpenFileInput(read_data, error);
|
||||
if (context)
|
||||
{
|
||||
int samples = WavpackGetNumSamples(context);
|
||||
int bitspersample = WavpackGetBitsPerSample(context);
|
||||
unsigned int samplerate = WavpackGetSampleRate(context);
|
||||
int channels = WavpackGetNumChannels(context);
|
||||
int *data;
|
||||
int *src;
|
||||
short *dst;
|
||||
int i;
|
||||
|
||||
snd->channels = channels;
|
||||
snd->rate = samplerate;
|
||||
|
||||
if(snd->channels > 2)
|
||||
{
|
||||
dbg_msg("sound/wv", "file is not mono or stereo. filename='%s'", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
if(snd->rate != 44100)
|
||||
{
|
||||
dbg_msg("sound/wv", "file is %d Hz, not 44100 Hz. filename='%s'", snd->rate, filename);
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
if(bitspersample != 16)
|
||||
{
|
||||
dbg_msg("sound/wv", "bps is %d, not 16, filname='%s'", bitspersample, filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = (int *)mem_alloc(4*samples*channels, 1);
|
||||
WavpackUnpackSamples(context, data, samples); /* TODO: check return value */
|
||||
src = data;
|
||||
|
||||
snd->data = (short *)mem_alloc(2*samples*channels, 1);
|
||||
dst = snd->data;
|
||||
|
||||
for (i = 0; i < samples*channels; i++)
|
||||
*dst++ = (short)*src++;
|
||||
|
||||
mem_free(data);
|
||||
|
||||
snd->num_frames = samples;
|
||||
snd->loop_start = -1;
|
||||
snd->loop_end = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("sound/wv", "failed to open %s: %s", filename, error);
|
||||
}
|
||||
|
||||
io_close(file);
|
||||
file = NULL;
|
||||
|
||||
if(config.debug)
|
||||
dbg_msg("sound/wv", "loaded %s", filename);
|
||||
|
||||
rate_convert(sid);
|
||||
return sid;
|
||||
}
|
||||
|
||||
void snd_set_listener_pos(float x, float y)
|
||||
{
|
||||
center_x = (int)x;
|
||||
center_y = (int)y;
|
||||
}
|
||||
@@ -1,737 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include <engine/e_network.h>
|
||||
#include <engine/e_client_interface.h>
|
||||
#include <engine/e_config.h>
|
||||
#include <engine/e_memheap.h>
|
||||
#include <engine/e_engine.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern NETCLIENT *net;
|
||||
|
||||
|
||||
/* ------ server browse ---- */
|
||||
/* TODO: move all this to a separate file */
|
||||
|
||||
typedef struct SERVERENTRY_t SERVERENTRY;
|
||||
struct SERVERENTRY_t
|
||||
{
|
||||
NETADDR addr;
|
||||
int64 request_time;
|
||||
int got_info;
|
||||
SERVER_INFO info;
|
||||
|
||||
SERVERENTRY *next_ip; /* ip hashed list */
|
||||
|
||||
SERVERENTRY *prev_req; /* request list */
|
||||
SERVERENTRY *next_req;
|
||||
};
|
||||
|
||||
static HEAP *serverlist_heap = 0;
|
||||
static SERVERENTRY **serverlist = 0;
|
||||
static int *sorted_serverlist = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_FAVORITES=256
|
||||
};
|
||||
|
||||
static NETADDR favorite_servers[MAX_FAVORITES];
|
||||
static int num_favorite_servers = 0;
|
||||
|
||||
static SERVERENTRY *serverlist_ip[256] = {0}; /* ip hash list */
|
||||
|
||||
static SERVERENTRY *first_req_server = 0; /* request list */
|
||||
static SERVERENTRY *last_req_server = 0;
|
||||
static int num_requests = 0;
|
||||
|
||||
static int need_refresh = 0;
|
||||
|
||||
static int num_sorted_servers = 0;
|
||||
static int num_sorted_servers_capacity = 0;
|
||||
static int num_servers = 0;
|
||||
static int num_server_capacity = 0;
|
||||
|
||||
static int sorthash = 0;
|
||||
static char filterstring[64] = {0};
|
||||
static char filtergametypestring[128] = {0};
|
||||
|
||||
/* the token is to keep server refresh separated from each other */
|
||||
static int current_token = 1;
|
||||
|
||||
static int serverlist_type = 0;
|
||||
static int64 broadcast_time = 0;
|
||||
|
||||
int client_serverbrowse_lan() { return serverlist_type == BROWSETYPE_LAN; }
|
||||
int client_serverbrowse_num() { return num_servers; }
|
||||
|
||||
SERVER_INFO *client_serverbrowse_get(int index)
|
||||
{
|
||||
if(index < 0 || index >= num_servers)
|
||||
return 0;
|
||||
return &serverlist[index]->info;
|
||||
}
|
||||
|
||||
int client_serverbrowse_sorted_num() { return num_sorted_servers; }
|
||||
|
||||
SERVER_INFO *client_serverbrowse_sorted_get(int index)
|
||||
{
|
||||
if(index < 0 || index >= num_sorted_servers)
|
||||
return 0;
|
||||
return &serverlist[sorted_serverlist[index]]->info;
|
||||
}
|
||||
|
||||
|
||||
int client_serverbrowse_num_requests()
|
||||
{
|
||||
return num_requests;
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_name(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
return strcmp(a->info.name, b->info.name);
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_map(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
return strcmp(a->info.map, b->info.map);
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_ping(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
if(a->info.latency > b->info.latency) return 1;
|
||||
if(a->info.latency < b->info.latency) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_gametype(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
return strcmp(a->info.gametype, b->info.gametype);
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_progression(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
if(a->info.progression > b->info.progression) return 1;
|
||||
if(a->info.progression < b->info.progression) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sort_compare_numplayers(const void *ai, const void *bi)
|
||||
{
|
||||
SERVERENTRY *a = serverlist[*(const int*)ai];
|
||||
SERVERENTRY *b = serverlist[*(const int*)bi];
|
||||
if(a->info.num_players > b->info.num_players) return 1;
|
||||
if(a->info.num_players < b->info.num_players) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_serverbrowse_filter()
|
||||
{
|
||||
int i = 0, p = 0;
|
||||
num_sorted_servers = 0;
|
||||
|
||||
/* allocate the sorted list */
|
||||
if(num_sorted_servers_capacity < num_servers)
|
||||
{
|
||||
if(sorted_serverlist)
|
||||
mem_free(sorted_serverlist);
|
||||
num_sorted_servers_capacity = num_servers;
|
||||
sorted_serverlist = (int *)mem_alloc(num_sorted_servers_capacity*sizeof(int), 1);
|
||||
}
|
||||
|
||||
/* filter the servers */
|
||||
for(i = 0; i < num_servers; i++)
|
||||
{
|
||||
int filtered = 0;
|
||||
|
||||
if(config.b_filter_empty && serverlist[i]->info.num_players == 0)
|
||||
filtered = 1;
|
||||
else if(config.b_filter_full && serverlist[i]->info.num_players == serverlist[i]->info.max_players)
|
||||
filtered = 1;
|
||||
else if(config.b_filter_pw && serverlist[i]->info.flags&SRVFLAG_PASSWORD)
|
||||
filtered = 1;
|
||||
else if(config.b_filter_pure && (strcmp(serverlist[i]->info.gametype, "DM") != 0 && strcmp(serverlist[i]->info.gametype, "TDM") != 0 && strcmp(serverlist[i]->info.gametype, "CTF") != 0))
|
||||
filtered = 1;
|
||||
else if(config.b_filter_pure_map &&
|
||||
!(strcmp(serverlist[i]->info.map, "dm1") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "dm2") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "dm6") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "dm7") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "dm8") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "dm9") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "ctf1") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "ctf2") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "ctf3") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "ctf4") == 0 ||
|
||||
strcmp(serverlist[i]->info.map, "ctf5") == 0)
|
||||
)
|
||||
{
|
||||
filtered = 1;
|
||||
}
|
||||
else if(config.b_filter_ping < serverlist[i]->info.latency)
|
||||
filtered = 1;
|
||||
else if(config.b_filter_compatversion && strncmp(serverlist[i]->info.version, modc_net_version(), 3) != 0)
|
||||
filtered = 1;
|
||||
else
|
||||
{
|
||||
if(config.b_filter_string[0] != 0)
|
||||
{
|
||||
int matchfound = 0;
|
||||
|
||||
serverlist[i]->info.quicksearch_hit = 0;
|
||||
|
||||
/* match against server name */
|
||||
if(str_find_nocase(serverlist[i]->info.name, config.b_filter_string))
|
||||
{
|
||||
matchfound = 1;
|
||||
serverlist[i]->info.quicksearch_hit |= BROWSEQUICK_SERVERNAME;
|
||||
}
|
||||
|
||||
/* match against players */
|
||||
for(p = 0; p < serverlist[i]->info.num_players; p++)
|
||||
{
|
||||
if(str_find_nocase(serverlist[i]->info.players[p].name, config.b_filter_string))
|
||||
{
|
||||
matchfound = 1;
|
||||
serverlist[i]->info.quicksearch_hit |= BROWSEQUICK_PLAYERNAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* match against map */
|
||||
if(str_find_nocase(serverlist[i]->info.map, config.b_filter_string))
|
||||
{
|
||||
matchfound = 1;
|
||||
serverlist[i]->info.quicksearch_hit |= BROWSEQUICK_MAPNAME;
|
||||
}
|
||||
|
||||
if(!matchfound)
|
||||
filtered = 1;
|
||||
}
|
||||
|
||||
if(!filtered && config.b_filter_gametype[0] != 0)
|
||||
{
|
||||
/* match against game type */
|
||||
if(!str_find_nocase(serverlist[i]->info.gametype, config.b_filter_gametype))
|
||||
filtered = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(filtered == 0)
|
||||
sorted_serverlist[num_sorted_servers++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
static int client_serverbrowse_sorthash()
|
||||
{
|
||||
int i = config.b_sort&0xf;
|
||||
i |= config.b_filter_empty<<4;
|
||||
i |= config.b_filter_full<<5;
|
||||
i |= config.b_filter_pw<<6;
|
||||
i |= config.b_sort_order<<7;
|
||||
i |= config.b_filter_compatversion<<8;
|
||||
i |= config.b_filter_pure<<9;
|
||||
i |= config.b_filter_pure_map<<10;
|
||||
i |= config.b_filter_ping<<16;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void client_serverbrowse_sort()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* create filtered list */
|
||||
client_serverbrowse_filter();
|
||||
|
||||
/* sort */
|
||||
if(config.b_sort == BROWSESORT_NAME)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_name);
|
||||
else if(config.b_sort == BROWSESORT_PING)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_ping);
|
||||
else if(config.b_sort == BROWSESORT_MAP)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_map);
|
||||
else if(config.b_sort == BROWSESORT_NUMPLAYERS)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_numplayers);
|
||||
else if(config.b_sort == BROWSESORT_GAMETYPE)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_gametype);
|
||||
else if(config.b_sort == BROWSESORT_PROGRESSION)
|
||||
qsort(sorted_serverlist, num_sorted_servers, sizeof(int), client_serverbrowse_sort_compare_progression);
|
||||
|
||||
/* invert the list if requested */
|
||||
if(config.b_sort_order)
|
||||
{
|
||||
for(i = 0; i < num_sorted_servers/2; i++)
|
||||
{
|
||||
int temp = sorted_serverlist[i];
|
||||
sorted_serverlist[i] = sorted_serverlist[num_sorted_servers-i-1];
|
||||
sorted_serverlist[num_sorted_servers-i-1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* set indexes */
|
||||
for(i = 0; i < num_sorted_servers; i++)
|
||||
serverlist[sorted_serverlist[i]]->info.sorted_index = i;
|
||||
|
||||
str_copy(filtergametypestring, config.b_filter_gametype, sizeof(filtergametypestring));
|
||||
str_copy(filterstring, config.b_filter_string, sizeof(filterstring));
|
||||
sorthash = client_serverbrowse_sorthash();
|
||||
}
|
||||
|
||||
static void client_serverbrowse_remove_request(SERVERENTRY *entry)
|
||||
{
|
||||
if(entry->prev_req || entry->next_req || first_req_server == entry)
|
||||
{
|
||||
if(entry->prev_req)
|
||||
entry->prev_req->next_req = entry->next_req;
|
||||
else
|
||||
first_req_server = entry->next_req;
|
||||
|
||||
if(entry->next_req)
|
||||
entry->next_req->prev_req = entry->prev_req;
|
||||
else
|
||||
last_req_server = entry->prev_req;
|
||||
|
||||
entry->prev_req = 0;
|
||||
entry->next_req = 0;
|
||||
num_requests--;
|
||||
}
|
||||
}
|
||||
|
||||
static SERVERENTRY *client_serverbrowse_find(NETADDR *addr)
|
||||
{
|
||||
SERVERENTRY *entry = serverlist_ip[addr->ip[0]];
|
||||
|
||||
for(; entry; entry = entry->next_ip)
|
||||
{
|
||||
if(net_addr_comp(&entry->addr, addr) == 0)
|
||||
return entry;
|
||||
}
|
||||
return (SERVERENTRY*)0;
|
||||
}
|
||||
|
||||
void client_serverbrowse_queuerequest(SERVERENTRY *entry)
|
||||
{
|
||||
/* add it to the list of servers that we should request info from */
|
||||
entry->prev_req = last_req_server;
|
||||
if(last_req_server)
|
||||
last_req_server->next_req = entry;
|
||||
else
|
||||
first_req_server = entry;
|
||||
last_req_server = entry;
|
||||
|
||||
num_requests++;
|
||||
}
|
||||
|
||||
void client_serverbrowse_setinfo(SERVERENTRY *entry, SERVER_INFO *info)
|
||||
{
|
||||
int fav = entry->info.favorite;
|
||||
entry->info = *info;
|
||||
entry->info.favorite = fav;
|
||||
entry->info.netaddr = entry->addr;
|
||||
|
||||
// all these are just for nice compability
|
||||
if(entry->info.gametype[0] == '0' && entry->info.gametype[1] == 0)
|
||||
str_copy(entry->info.gametype, "DM", sizeof(entry->info.gametype));
|
||||
else if(entry->info.gametype[0] == '1' && entry->info.gametype[1] == 0)
|
||||
str_copy(entry->info.gametype, "TDM", sizeof(entry->info.gametype));
|
||||
else if(entry->info.gametype[0] == '2' && entry->info.gametype[1] == 0)
|
||||
str_copy(entry->info.gametype, "CTF", sizeof(entry->info.gametype));
|
||||
|
||||
/*if(!request)
|
||||
{
|
||||
entry->info.latency = (time_get()-entry->request_time)*1000/time_freq();
|
||||
client_serverbrowse_remove_request(entry);
|
||||
}*/
|
||||
|
||||
entry->got_info = 1;
|
||||
client_serverbrowse_sort();
|
||||
}
|
||||
|
||||
SERVERENTRY *client_serverbrowse_add(NETADDR *addr)
|
||||
{
|
||||
int hash = addr->ip[0];
|
||||
SERVERENTRY *entry = 0;
|
||||
int i;
|
||||
|
||||
/* create new entry */
|
||||
entry = (SERVERENTRY *)memheap_allocate(serverlist_heap, sizeof(SERVERENTRY));
|
||||
mem_zero(entry, sizeof(SERVERENTRY));
|
||||
|
||||
/* set the info */
|
||||
entry->addr = *addr;
|
||||
entry->info.netaddr = *addr;
|
||||
|
||||
entry->info.latency = 999;
|
||||
str_format(entry->info.address, sizeof(entry->info.address), "%d.%d.%d.%d:%d",
|
||||
addr->ip[0], addr->ip[1], addr->ip[2],
|
||||
addr->ip[3], addr->port);
|
||||
str_format(entry->info.name, sizeof(entry->info.name), "\255%d.%d.%d.%d:%d", /* the \255 is to make sure that it's sorted last */
|
||||
addr->ip[0], addr->ip[1], addr->ip[2],
|
||||
addr->ip[3], addr->port);
|
||||
|
||||
/*if(serverlist_type == BROWSETYPE_LAN)
|
||||
entry->info.latency = (time_get()-broadcast_time)*1000/time_freq();*/
|
||||
|
||||
/* check if it's a favorite */
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
{
|
||||
if(net_addr_comp(addr, &favorite_servers[i]) == 0)
|
||||
entry->info.favorite = 1;
|
||||
}
|
||||
|
||||
/* add to the hash list */
|
||||
entry->next_ip = serverlist_ip[hash];
|
||||
serverlist_ip[hash] = entry;
|
||||
|
||||
if(num_servers == num_server_capacity)
|
||||
{
|
||||
SERVERENTRY **newlist;
|
||||
num_server_capacity += 100;
|
||||
newlist = (SERVERENTRY**)mem_alloc(num_server_capacity*sizeof(SERVERENTRY*), 1);
|
||||
mem_copy(newlist, serverlist, num_servers*sizeof(SERVERENTRY*));
|
||||
mem_free(serverlist);
|
||||
serverlist = newlist;
|
||||
}
|
||||
|
||||
/* add to list */
|
||||
serverlist[num_servers] = entry;
|
||||
entry->info.server_index = num_servers;
|
||||
num_servers++;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void client_serverbrowse_set(NETADDR *addr, int type, int token, SERVER_INFO *info)
|
||||
{
|
||||
SERVERENTRY *entry = 0;
|
||||
if(type == BROWSESET_MASTER_ADD)
|
||||
{
|
||||
if(serverlist_type != BROWSETYPE_INTERNET)
|
||||
return;
|
||||
|
||||
if(!client_serverbrowse_find(addr))
|
||||
{
|
||||
entry = client_serverbrowse_add(addr);
|
||||
client_serverbrowse_queuerequest(entry);
|
||||
}
|
||||
}
|
||||
else if(type == BROWSESET_FAV_ADD)
|
||||
{
|
||||
if(serverlist_type != BROWSETYPE_FAVORITES)
|
||||
return;
|
||||
|
||||
if(!client_serverbrowse_find(addr))
|
||||
{
|
||||
entry = client_serverbrowse_add(addr);
|
||||
client_serverbrowse_queuerequest(entry);
|
||||
}
|
||||
}
|
||||
else if(type == BROWSESET_TOKEN)
|
||||
{
|
||||
if(token != current_token)
|
||||
return;
|
||||
|
||||
entry = client_serverbrowse_find(addr);
|
||||
if(!entry)
|
||||
entry = client_serverbrowse_add(addr);
|
||||
if(entry)
|
||||
{
|
||||
client_serverbrowse_setinfo(entry, info);
|
||||
if(serverlist_type == BROWSETYPE_LAN)
|
||||
entry->info.latency = (time_get()-broadcast_time)*1000/time_freq();
|
||||
else
|
||||
entry->info.latency = (time_get()-entry->request_time)*1000/time_freq();
|
||||
client_serverbrowse_remove_request(entry);
|
||||
}
|
||||
}
|
||||
else if(type == BROWSESET_OLD_INTERNET)
|
||||
{
|
||||
entry = client_serverbrowse_find(addr);
|
||||
if(entry)
|
||||
{
|
||||
client_serverbrowse_setinfo(entry, info);
|
||||
|
||||
if(serverlist_type == BROWSETYPE_LAN)
|
||||
entry->info.latency = (time_get()-broadcast_time)*1000/time_freq();
|
||||
else
|
||||
entry->info.latency = (time_get()-entry->request_time)*1000/time_freq();
|
||||
client_serverbrowse_remove_request(entry);
|
||||
}
|
||||
}
|
||||
else if(type == BROWSESET_OLD_LAN)
|
||||
{
|
||||
entry = client_serverbrowse_find(addr);
|
||||
if(entry)
|
||||
if(!entry)
|
||||
entry = client_serverbrowse_add(addr);
|
||||
if(entry)
|
||||
client_serverbrowse_setinfo(entry, info);
|
||||
}
|
||||
|
||||
client_serverbrowse_sort();
|
||||
}
|
||||
|
||||
void client_serverbrowse_refresh(int type)
|
||||
{
|
||||
/* clear out everything */
|
||||
if(serverlist_heap)
|
||||
memheap_destroy(serverlist_heap);
|
||||
serverlist_heap = memheap_create();
|
||||
num_servers = 0;
|
||||
num_sorted_servers = 0;
|
||||
mem_zero(serverlist_ip, sizeof(serverlist_ip));
|
||||
first_req_server = 0;
|
||||
last_req_server = 0;
|
||||
num_requests = 0;
|
||||
|
||||
/* next token */
|
||||
current_token = (current_token+1)&0xff;
|
||||
|
||||
/* */
|
||||
serverlist_type = type;
|
||||
|
||||
if(type == BROWSETYPE_LAN)
|
||||
{
|
||||
unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];
|
||||
NETCHUNK packet;
|
||||
int i;
|
||||
|
||||
mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
|
||||
buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token;
|
||||
|
||||
packet.client_id = -1;
|
||||
mem_zero(&packet, sizeof(packet));
|
||||
packet.address.ip[0] = 255;
|
||||
packet.address.ip[1] = 255;
|
||||
packet.address.ip[2] = 255;
|
||||
packet.address.ip[3] = 255;
|
||||
packet.flags = NETSENDFLAG_CONNLESS;
|
||||
packet.data_size = sizeof(buffer);
|
||||
packet.data = buffer;
|
||||
broadcast_time = time_get();
|
||||
|
||||
for(i = 8303; i <= 8310; i++)
|
||||
{
|
||||
packet.address.port = i;
|
||||
netclient_send(net, &packet);
|
||||
}
|
||||
|
||||
if(config.debug)
|
||||
dbg_msg("client", "broadcasting for servers");
|
||||
}
|
||||
else if(type == BROWSETYPE_INTERNET)
|
||||
need_refresh = 1;
|
||||
else if(type == BROWSETYPE_FAVORITES)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
client_serverbrowse_set(&favorite_servers[i], BROWSESET_FAV_ADD, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_serverbrowse_request_impl(NETADDR *addr, SERVERENTRY *entry)
|
||||
{
|
||||
/*unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];*/
|
||||
NETCHUNK p;
|
||||
|
||||
if(config.debug)
|
||||
{
|
||||
dbg_msg("client", "requesting server info from %d.%d.%d.%d:%d",
|
||||
addr->ip[0], addr->ip[1], addr->ip[2],
|
||||
addr->ip[3], addr->port);
|
||||
}
|
||||
|
||||
/*mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
|
||||
buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token;*/
|
||||
|
||||
p.client_id = -1;
|
||||
p.address = *addr;
|
||||
p.flags = NETSENDFLAG_CONNLESS;
|
||||
/*p.data_size = sizeof(buffer);
|
||||
p.data = buffer;
|
||||
netclient_send(net, &p);*/
|
||||
|
||||
/* send old requtest style aswell */
|
||||
p.data_size = sizeof(SERVERBROWSE_OLD_GETINFO);
|
||||
p.data = SERVERBROWSE_OLD_GETINFO;
|
||||
netclient_send(net, &p);
|
||||
|
||||
if(entry)
|
||||
entry->request_time = time_get();
|
||||
}
|
||||
|
||||
void client_serverbrowse_request(NETADDR *addr)
|
||||
{
|
||||
client_serverbrowse_request_impl(addr, 0);
|
||||
}
|
||||
|
||||
|
||||
void client_serverbrowse_update()
|
||||
{
|
||||
int64 timeout = time_freq();
|
||||
int64 now = time_get();
|
||||
int count;
|
||||
SERVERENTRY *entry, *next;
|
||||
|
||||
/* do server list requests */
|
||||
if(need_refresh && !mastersrv_refreshing())
|
||||
{
|
||||
NETADDR addr;
|
||||
NETCHUNK p;
|
||||
int i;
|
||||
|
||||
need_refresh = 0;
|
||||
|
||||
mem_zero(&p, sizeof(p));
|
||||
p.client_id = -1;
|
||||
p.flags = NETSENDFLAG_CONNLESS;
|
||||
p.data_size = sizeof(SERVERBROWSE_GETLIST);
|
||||
p.data = SERVERBROWSE_GETLIST;
|
||||
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
{
|
||||
addr = mastersrv_get(i);
|
||||
if(!addr.ip[0] && !addr.ip[1] && !addr.ip[2] && !addr.ip[3])
|
||||
continue;
|
||||
|
||||
p.address = addr;
|
||||
netclient_send(net, &p);
|
||||
}
|
||||
|
||||
if(config.debug)
|
||||
dbg_msg("client", "requesting server list");
|
||||
}
|
||||
|
||||
/* do timeouts */
|
||||
entry = first_req_server;
|
||||
while(1)
|
||||
{
|
||||
if(!entry) /* no more entries */
|
||||
break;
|
||||
|
||||
next = entry->next_req;
|
||||
|
||||
if(entry->request_time && entry->request_time+timeout < now)
|
||||
{
|
||||
/* timeout */
|
||||
client_serverbrowse_remove_request(entry);
|
||||
num_requests--;
|
||||
}
|
||||
|
||||
entry = next;
|
||||
}
|
||||
|
||||
/* do timeouts */
|
||||
entry = first_req_server;
|
||||
count = 0;
|
||||
while(1)
|
||||
{
|
||||
if(!entry) /* no more entries */
|
||||
break;
|
||||
|
||||
/* no more then 10 concurrent requests */
|
||||
if(count == config.b_max_requests)
|
||||
break;
|
||||
|
||||
if(entry->request_time == 0)
|
||||
client_serverbrowse_request_impl(&entry->addr, entry);
|
||||
|
||||
count++;
|
||||
entry = entry->next_req;
|
||||
}
|
||||
|
||||
/* check if we need to resort */
|
||||
/* TODO: remove the strcmp */
|
||||
if(sorthash != client_serverbrowse_sorthash() || strcmp(filterstring, config.b_filter_string) != 0 || strcmp(filtergametypestring, config.b_filter_gametype) != 0)
|
||||
client_serverbrowse_sort();
|
||||
}
|
||||
|
||||
|
||||
int client_serverbrowse_isfavorite(NETADDR addr)
|
||||
{
|
||||
/* search for the address */
|
||||
int i;
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
{
|
||||
if(net_addr_comp(&addr, &favorite_servers[i]) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void client_serverbrowse_addfavorite(NETADDR addr)
|
||||
{
|
||||
int i;
|
||||
SERVERENTRY *entry;
|
||||
|
||||
if(num_favorite_servers == MAX_FAVORITES)
|
||||
return;
|
||||
|
||||
/* make sure that we don't already have the server in our list */
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
{
|
||||
if(net_addr_comp(&addr, &favorite_servers[i]) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* add the server to the list */
|
||||
favorite_servers[num_favorite_servers++] = addr;
|
||||
entry = client_serverbrowse_find(&addr);
|
||||
if(entry)
|
||||
entry->info.favorite = 1;
|
||||
dbg_msg("", "added fav, %p", entry);
|
||||
}
|
||||
|
||||
void client_serverbrowse_removefavorite(NETADDR addr)
|
||||
{
|
||||
int i;
|
||||
SERVERENTRY *entry;
|
||||
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
{
|
||||
if(net_addr_comp(&addr, &favorite_servers[i]) == 0)
|
||||
{
|
||||
mem_move(&favorite_servers[i], &favorite_servers[i+1], num_favorite_servers-(i+1));
|
||||
num_favorite_servers--;
|
||||
|
||||
entry = client_serverbrowse_find(&addr);
|
||||
if(entry)
|
||||
entry->info.favorite = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void client_serverbrowse_save()
|
||||
{
|
||||
int i;
|
||||
char addrstr[128];
|
||||
char buffer[256];
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
{
|
||||
net_addr_str(&favorite_servers[i], addrstr, sizeof(addrstr));
|
||||
str_format(buffer, sizeof(buffer), "add_favorite %s", addrstr);
|
||||
engine_config_write_line(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int client_serverbrowse_refreshingmasters()
|
||||
{
|
||||
return mastersrv_refreshing();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
Title: Time on the client
|
||||
|
||||
tick, intratick
|
||||
predtick, predintratick
|
||||
|
||||
prevtick tick predtick
|
||||
4 8 14
|
||||
|---------------------|---------------------|
|
||||
0 <- intratick -> 1
|
||||
0 <- ticktime(in s)-> X
|
||||
0 <- predintratick?-> 1
|
||||
@@ -1,19 +0,0 @@
|
||||
Title: Prediction
|
||||
|
||||
The engine calls <modc_predict> when reprediction is required. This happens usally when new data has arrived from the server. <modc_predict> should to prediction from the current snapshot and current snapshot tick (<client_tick> + 1) upto and including the tick returned by <client_predtick>.
|
||||
|
||||
Predicted input sent to the server can be retrived by calling <client_get_input> with the corresponding tick that you want the input for. Here is a simple example of how it might look.
|
||||
|
||||
> void modc_predict()
|
||||
> {
|
||||
> int tick;
|
||||
> prediction_reset();
|
||||
>
|
||||
> for(tick = client_tick()+1; tick <= client_predtick(); tick++)
|
||||
> {
|
||||
> MY_INPUT *input = (MY_INPUT *)client_get_input();
|
||||
> if(input)
|
||||
> prediction_apply_input(input);
|
||||
> prediction_tick();
|
||||
> }
|
||||
> }
|
||||
@@ -1,39 +0,0 @@
|
||||
Title: Server Operation
|
||||
|
||||
Section: Init
|
||||
|
||||
Section: Running
|
||||
|
||||
Here is an graph over how the server operates on each refresh.
|
||||
|
||||
(start code)
|
||||
load map
|
||||
init mod
|
||||
|
||||
while running
|
||||
if map change then
|
||||
load new map
|
||||
shutdown mod <mods_shutdown>
|
||||
reset clients to init state
|
||||
init mod <mods_init>
|
||||
end if
|
||||
|
||||
if new tick then
|
||||
call <mods_tick>
|
||||
for each client do
|
||||
create snapshot <mods_snap>
|
||||
send snapshot
|
||||
end for
|
||||
end
|
||||
|
||||
process new network messages
|
||||
end while
|
||||
|
||||
unload map
|
||||
(end)
|
||||
|
||||
|
||||
|
||||
Section: Reinit
|
||||
|
||||
Section: Shutdown
|
||||
@@ -1,58 +0,0 @@
|
||||
Title: Snapshots
|
||||
|
||||
Section: Overview
|
||||
|
||||
Topic: Definitions
|
||||
|
||||
- *Snapshot*. A is a serialized game state from which a client can render the game from. They are sent from the server at a regular interval and is created specificly for each client in order to reduce bandwidth.
|
||||
- *Delta Snapshot*. A set of data that can be applied to a snapshot in order to create a new snapshot with the updated game state.
|
||||
|
||||
Topic: Structure
|
||||
|
||||
A snapshot contains a series of items. Each item have a type, id and data.
|
||||
|
||||
- *Type*. Type of item. Could be projectile or character for example.
|
||||
- *Id*. A unique id so the client can identify the item between two snapshots.
|
||||
- *Data*. A series of 32-bit integers that contains the per item type specific data.
|
||||
|
||||
Section: Server Side
|
||||
|
||||
Topic: Creating
|
||||
|
||||
Items can be added when <mods_snap> is called using the <snap_new_item> function to insert an item to the snapshot. The server can not inspect the snapshot that is in progress of being created.
|
||||
|
||||
Section: Client Side
|
||||
|
||||
Topic: Inspection
|
||||
<modc_newsnapshot> is called when a new snapshot has arrived for processing. <snap_num_items>, <snap_get_item> and <snap_find_item> can be used to inspect the current and previous snapshot. This can be done anywhere while the client is running and not just in the <modc_newsnapshot> function. The client can also call <snap_invalidate_item> if an item contains improper information that could harm the operation of the client. This should however be done in <modc_newsnapshot> to assure that no bad data propagates into the rest of the client.
|
||||
|
||||
Topic: Rendering
|
||||
DOCTODO
|
||||
|
||||
Section: In depth
|
||||
|
||||
Topic: Compression
|
||||
|
||||
After a snapshot have been created, compression is applyed to reduce the bandwidth. There are several steps taken inorder to reduce the size of the size of the snapshot.
|
||||
|
||||
- *Delta*. The server looks in a clients backlog of snapshots to find a previous acked snapshot. It then compares the two snapshots and creates a delta snapshot containing the changes from the previous acked snapshot to the new one.
|
||||
- *Variable Integers*. The delta snapshot which is only consisting of 32-bit integers is then encoded into variable integers similar to UTF-8. Each byte has a bit that tells the decoder that it needs one more byte to decode the 32-bit integer. The first byte also contains a bit for telling the sign of the integer.
|
||||
|
||||
> ESDDDDDD EDDDDDDD EDDDDDDD EDDDDDDD
|
||||
|
||||
> E = extend
|
||||
> S = sign
|
||||
> D = data bit
|
||||
|
||||
- *Huffman*. The last step is to compress the buffer with a huffman encoder. It uses a static tree that is weighted towards 0 because it's where most of the data will be because of the delta compression.
|
||||
|
||||
Topic: Interval
|
||||
|
||||
The interval for how often a client recives a snapshot changes during the course of the connection. There are three different snapshot rates.
|
||||
|
||||
- *Init*. 5 snapshots per second. Used when a client is connecting and used until the client has acknowlaged a snapshot. This mechanism is used because the first snapshot because no delta compression can be done.
|
||||
|
||||
- *Full*. Snapshot for every tick or every even tick depending on server configuration. This is used during normal gameplay and everything is running smooth.
|
||||
|
||||
- *Recovery*. 1 snapshot each second. A client enters recovery rate when it havn't acknowlaged a snapshot over 1 second. This is to let the client to beable to recover if it has a slow connection.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_CLIENT_INTERFACE_H
|
||||
#define ENGINE_CLIENT_INTERFACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "e_if_other.h"
|
||||
#include "e_if_client.h"
|
||||
#include "e_if_snd.h"
|
||||
#include "e_if_gfx.h"
|
||||
#include "e_if_inp.h"
|
||||
#include "e_if_msg.h"
|
||||
#include "e_if_modc.h"
|
||||
|
||||
#include "e_console.h"
|
||||
#include "e_config.h"
|
||||
#include "client/ec_font.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_COMMON_INTERFACE_H
|
||||
#define ENGINE_COMMON_INTERFACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "e_if_other.h"
|
||||
#include "e_if_msg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,150 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include "e_compression.h"
|
||||
|
||||
|
||||
/* Format: ESDDDDDD EDDDDDDD EDD... Extended, Data, Sign */
|
||||
unsigned char *vint_pack(unsigned char *dst, int i)
|
||||
{
|
||||
*dst = (i>>25)&0x40; /* set sign bit if i<0 */
|
||||
i = i^(i>>31); /* if(i<0) i = ~i */
|
||||
|
||||
*dst |= i&0x3F; /* pack 6bit into dst */
|
||||
i >>= 6; /* discard 6 bits */
|
||||
if(i)
|
||||
{
|
||||
*dst |= 0x80; /* set extend bit */
|
||||
while(1)
|
||||
{
|
||||
dst++;
|
||||
*dst = i&(0x7F); /* pack 7bit */
|
||||
i >>= 7; /* discard 7 bits */
|
||||
*dst |= (i!=0)<<7; /* set extend bit (may branch) */
|
||||
if(!i)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dst++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
const unsigned char *vint_unpack(const unsigned char *src, int *i)
|
||||
{
|
||||
int sign = (*src>>6)&1;
|
||||
*i = *src&0x3F;
|
||||
|
||||
do
|
||||
{
|
||||
if(!(*src&0x80)) break;
|
||||
src++;
|
||||
*i |= (*src&(0x7F))<<(6);
|
||||
|
||||
if(!(*src&0x80)) break;
|
||||
src++;
|
||||
*i |= (*src&(0x7F))<<(6+7);
|
||||
|
||||
if(!(*src&0x80)) break;
|
||||
src++;
|
||||
*i |= (*src&(0x7F))<<(6+7+7);
|
||||
|
||||
if(!(*src&0x80)) break;
|
||||
src++;
|
||||
*i |= (*src&(0x7F))<<(6+7+7+7);
|
||||
} while(0);
|
||||
|
||||
src++;
|
||||
*i ^= -sign; /* if(sign) *i = ~(*i) */
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
long intpack_decompress(const void *src_, int size, void *dst_)
|
||||
{
|
||||
const unsigned char *src = (unsigned char *)src_;
|
||||
const unsigned char *end = src + size;
|
||||
int *dst = (int *)dst_;
|
||||
while(src < end)
|
||||
{
|
||||
src = vint_unpack(src, dst);
|
||||
dst++;
|
||||
}
|
||||
return (long)((unsigned char *)dst-(unsigned char *)dst_);
|
||||
}
|
||||
|
||||
long intpack_compress(const void *src_, int size, void *dst_)
|
||||
{
|
||||
int *src = (int *)src_;
|
||||
unsigned char *dst = (unsigned char *)dst_;
|
||||
size /= 4;
|
||||
while(size)
|
||||
{
|
||||
dst = vint_pack(dst, *src);
|
||||
size--;
|
||||
src++;
|
||||
}
|
||||
return (long)(dst-(unsigned char *)dst_);
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
long zerobit_compress(const void *src_, int size, void *dst_)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)src_;
|
||||
unsigned char *dst = (unsigned char *)dst_;
|
||||
|
||||
while(size)
|
||||
{
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char mask = 0;
|
||||
int dst_move = 1;
|
||||
int chunk = size < 8 ? size : 8;
|
||||
int b;
|
||||
size -= chunk;
|
||||
|
||||
for(b = 0; b < chunk; b++, bit>>=1)
|
||||
{
|
||||
if(*src)
|
||||
{
|
||||
dst[dst_move] = *src;
|
||||
mask |= bit;
|
||||
dst_move++;
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
|
||||
*dst = mask;
|
||||
dst += dst_move;
|
||||
}
|
||||
|
||||
return (long)(dst-(unsigned char *)dst_);
|
||||
}
|
||||
|
||||
long zerobit_decompress(const void *src_, int size, void *dst_)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)src_;
|
||||
unsigned char *dst = (unsigned char *)dst_;
|
||||
unsigned char *end = src + size;
|
||||
|
||||
while(src < end)
|
||||
{
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char mask = *src++;
|
||||
int b;
|
||||
|
||||
for(b = 0; b < 8; b++, bit>>=1)
|
||||
{
|
||||
if(mask&bit)
|
||||
*dst++ = *src++;
|
||||
else
|
||||
*dst++ = 0;
|
||||
}
|
||||
|
||||
if(src > end)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (long)(dst-(unsigned char *)dst_);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* variable int packing */
|
||||
unsigned char *vint_pack(unsigned char *dst, int i);
|
||||
const unsigned char *vint_unpack(const unsigned char *src, int *inout);
|
||||
long intpack_compress(const void *src, int size, void *dst);
|
||||
long intpack_decompress(const void *src, int size, void *dst);
|
||||
|
||||
/* zerobit packing */
|
||||
long zerobit_compress(const void *src, int size, void *dst);
|
||||
long zerobit_decompress(const void *src, int size, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <base/system.h>
|
||||
#include "e_if_other.h"
|
||||
#include "e_config.h"
|
||||
#include "e_linereader.h"
|
||||
#include "e_engine.h"
|
||||
|
||||
CONFIGURATION config;
|
||||
|
||||
void config_reset()
|
||||
{
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) config.name = def;
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) str_copy(config.name, def, len);
|
||||
|
||||
#include "e_config_variables.h"
|
||||
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
}
|
||||
|
||||
void config_save()
|
||||
{
|
||||
char linebuf[1024*2];
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) if((flags)&CFGFLAG_SAVE){ str_format(linebuf, sizeof(linebuf), "%s %i", #name, config.name); engine_config_write_line(linebuf); }
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) if((flags)&CFGFLAG_SAVE){ str_format(linebuf, sizeof(linebuf), "%s %s", #name, config.name); engine_config_write_line(linebuf); }
|
||||
|
||||
#include "e_config_variables.h"
|
||||
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
}
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) int config_get_ ## name (CONFIGURATION *c) { return c->name; }
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) const char *config_get_ ## name (CONFIGURATION *c) { return c->name; }
|
||||
#include "e_config_variables.h"
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) void config_set_ ## name (CONFIGURATION *c, int val) { if(min != max) { if (val < min) val = min; if (max != 0 && val > max) val = max; } c->name = val; }
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) void config_set_ ## name (CONFIGURATION *c, const char *str) { str_copy(c->name, str, len-1); c->name[sizeof(c->name)-1] = 0; }
|
||||
#include "e_config_variables.h"
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
@@ -1,52 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,save,desc) int name;
|
||||
#define MACRO_CONFIG_STR(name,len,def,save,desc) char name[len]; /* Flawfinder: ignore */
|
||||
#include "e_config_variables.h"
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
} CONFIGURATION;
|
||||
|
||||
extern CONFIGURATION config;
|
||||
|
||||
void config_init();
|
||||
void config_reset();
|
||||
void config_save();
|
||||
|
||||
enum
|
||||
{
|
||||
CFGFLAG_SAVE=1,
|
||||
CFGFLAG_CLIENT=2,
|
||||
CFGFLAG_SERVER=4
|
||||
};
|
||||
|
||||
typedef int (*CONFIG_INT_GETTER)(CONFIGURATION *c);
|
||||
typedef const char *(*CONFIG_STR_GETTER)(CONFIGURATION *c);
|
||||
typedef void (*CONFIG_INT_SETTER)(CONFIGURATION *c, int val);
|
||||
typedef void (*CONFIG_STR_SETTER)(CONFIGURATION *c, const char *str);
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) int config_get_ ## name (CONFIGURATION *c);
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) const char *config_get_ ## name (CONFIGURATION *c);
|
||||
#include "e_config_variables.h"
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) void config_set_ ## name (CONFIGURATION *c, int val);
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) void config_set_ ## name (CONFIGURATION *c, const char *str);
|
||||
#include "e_config_variables.h"
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,87 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
/* TODO: remove this */
|
||||
#include "../game/variables.hpp"
|
||||
|
||||
|
||||
MACRO_CONFIG_STR(player_name, 32, "nameless tee", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Name of the player")
|
||||
MACRO_CONFIG_STR(clan_name, 32, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "(not used)")
|
||||
MACRO_CONFIG_STR(password, 32, "", CFGFLAG_CLIENT, "Password to the server")
|
||||
MACRO_CONFIG_STR(logfile, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filename to log all output to")
|
||||
|
||||
MACRO_CONFIG_INT(cl_cpu_throttle, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(cl_editor, 0, 0, 1, CFGFLAG_CLIENT, "")
|
||||
|
||||
MACRO_CONFIG_INT(cl_eventthread, 0, 0, 1, CFGFLAG_CLIENT, "Enables the usage of a thread to pump the events")
|
||||
|
||||
MACRO_CONFIG_INT(inp_grab, 0, 0, 1, CFGFLAG_CLIENT, "Use forceful input grabbing method")
|
||||
|
||||
MACRO_CONFIG_STR(b_filter_string, 64, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string")
|
||||
|
||||
MACRO_CONFIG_INT(b_filter_full, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out full server in browser")
|
||||
MACRO_CONFIG_INT(b_filter_empty, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out empty server in browser")
|
||||
MACRO_CONFIG_INT(b_filter_pw, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out password protected servers in browser")
|
||||
MACRO_CONFIG_INT(b_filter_ping, 999, 0, 999, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Ping to filter by in the server browser")
|
||||
MACRO_CONFIG_STR(b_filter_gametype, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Game types to filter")
|
||||
MACRO_CONFIG_INT(b_filter_pure, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-standard servers in browser")
|
||||
MACRO_CONFIG_INT(b_filter_pure_map, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-standard maps in browser")
|
||||
MACRO_CONFIG_INT(b_filter_compatversion, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-compatible servers in browser")
|
||||
|
||||
MACRO_CONFIG_INT(b_sort, 1, 0, 256, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") // Sort by ping
|
||||
MACRO_CONFIG_INT(b_sort_order, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(b_max_requests, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Number of requests to use when refreshing server browser")
|
||||
|
||||
MACRO_CONFIG_INT(snd_buffer_size, 512, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound buffer size")
|
||||
#ifdef ANDROID
|
||||
MACRO_CONFIG_INT(snd_rate, 22050, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound mixing rate")
|
||||
#else
|
||||
MACRO_CONFIG_INT(snd_rate, 48000, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound mixing rate")
|
||||
#endif
|
||||
MACRO_CONFIG_INT(snd_enable, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound enable")
|
||||
MACRO_CONFIG_INT(snd_volume, 100, 0, 100, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sound volume")
|
||||
MACRO_CONFIG_INT(snd_device, -1, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "(deprecated) Sound device to use")
|
||||
|
||||
MACRO_CONFIG_INT(snd_nonactive_mute, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
|
||||
MACRO_CONFIG_INT(gfx_screen_width, 800, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution width")
|
||||
MACRO_CONFIG_INT(gfx_screen_height, 600, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution height")
|
||||
MACRO_CONFIG_INT(gfx_fullscreen, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Fullscreen")
|
||||
MACRO_CONFIG_INT(gfx_alphabits, 0, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Alpha bits for framebuffer (fullscreen only)")
|
||||
MACRO_CONFIG_INT(gfx_color_depth, 24, 16, 24, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Colors bits for framebuffer (fullscreen only)")
|
||||
MACRO_CONFIG_INT(gfx_clear, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Clear screen before rendering")
|
||||
MACRO_CONFIG_INT(gfx_vsync, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Vertical sync")
|
||||
MACRO_CONFIG_INT(gfx_display_all_modes, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(gfx_texture_compression, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Use texture compression")
|
||||
#ifdef ANDROID
|
||||
MACRO_CONFIG_INT(gfx_high_detail, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "High detail")
|
||||
MACRO_CONFIG_INT(gfx_texture_quality, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(gfx_fsaa_samples, 0, 0, 16, CFGFLAG_SAVE|CFGFLAG_CLIENT, "FSAA Samples")
|
||||
#else
|
||||
MACRO_CONFIG_INT(gfx_high_detail, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "High detail")
|
||||
MACRO_CONFIG_INT(gfx_texture_quality, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(gfx_fsaa_samples, 0, 0, 16, CFGFLAG_SAVE|CFGFLAG_CLIENT, "FSAA Samples")
|
||||
#endif
|
||||
MACRO_CONFIG_INT(gfx_refresh_rate, 0, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen refresh rate")
|
||||
MACRO_CONFIG_INT(gfx_finish, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
|
||||
|
||||
MACRO_CONFIG_INT(inp_mousesens, 100, 5, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity")
|
||||
|
||||
MACRO_CONFIG_STR(sv_name, 128, "unnamed server", CFGFLAG_SERVER, "Server name")
|
||||
MACRO_CONFIG_STR(sv_bindaddr, 128, "", CFGFLAG_SERVER, "Address to bind the server to")
|
||||
MACRO_CONFIG_INT(sv_port, 8303, 0, 0, CFGFLAG_SERVER, "Port to use for the server")
|
||||
MACRO_CONFIG_INT(sv_external_port, 0, 0, 0, CFGFLAG_SERVER, "External port to report to the master servers")
|
||||
MACRO_CONFIG_STR(sv_map, 128, "dm1", CFGFLAG_SERVER, "Map to use on the server")
|
||||
MACRO_CONFIG_INT(sv_max_clients, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients that are allowed on a server")
|
||||
MACRO_CONFIG_INT(sv_high_bandwidth, 0, 0, 1, CFGFLAG_SERVER, "Use high bandwidth mode. Doubles the bandwidth required for the server. LAN use only")
|
||||
MACRO_CONFIG_INT(sv_register, 1, 0, 1, CFGFLAG_SERVER, "Register server with master server for public listing")
|
||||
MACRO_CONFIG_STR(sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password")
|
||||
MACRO_CONFIG_INT(sv_map_reload, 0, 0, 1, CFGFLAG_SERVER, "Reload the current map")
|
||||
|
||||
MACRO_CONFIG_INT(debug, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Debug mode")
|
||||
MACRO_CONFIG_INT(dbg_stress, 0, 0, 0, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Stress systems")
|
||||
MACRO_CONFIG_INT(dbg_stress_network, 0, 0, 0, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Stress network")
|
||||
MACRO_CONFIG_INT(dbg_pref, 0, 0, 1, CFGFLAG_SERVER, "Performance outputs")
|
||||
MACRO_CONFIG_INT(dbg_graphs, 0, 0, 1, CFGFLAG_CLIENT, "Performance graphs")
|
||||
MACRO_CONFIG_INT(dbg_hitch, 0, 0, 0, CFGFLAG_SERVER, "Hitch warnings")
|
||||
MACRO_CONFIG_STR(dbg_stress_server, 32, "localhost", CFGFLAG_CLIENT, "Server to stress")
|
||||
MACRO_CONFIG_INT(dbg_resizable, 0, 0, 0, CFGFLAG_CLIENT, "Enables window resizing")
|
||||
@@ -1,443 +0,0 @@
|
||||
#include <base/system.h>
|
||||
#include "e_if_other.h"
|
||||
#include "e_console.h"
|
||||
#include "e_config.h"
|
||||
#include "e_engine.h"
|
||||
#include "e_linereader.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define CONSOLE_MAX_STR_LENGTH 1024
|
||||
/* the maximum number of tokens occurs in a string of length CONSOLE_MAX_STR_LENGTH with tokens size 1 separated by single spaces */
|
||||
#define MAX_PARTS (CONSOLE_MAX_STR_LENGTH+1)/2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char string_storage[CONSOLE_MAX_STR_LENGTH+1];
|
||||
char *args_start;
|
||||
|
||||
const char *command;
|
||||
const char *args[MAX_PARTS];
|
||||
unsigned int num_args;
|
||||
} PARSE_RESULT;
|
||||
|
||||
static char *str_skipblanks(char *str)
|
||||
{
|
||||
while(*str && (*str == ' ' || *str == '\t' || *str == '\n'))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *str_skiptoblank(char *str)
|
||||
{
|
||||
while(*str && (*str != ' ' && *str != '\t' && *str != '\n'))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* static int digit(char c) { return '0' <= c && c <= '9'; } */
|
||||
|
||||
static int console_parse_start(PARSE_RESULT *result, const char *string, int length)
|
||||
{
|
||||
char *str;
|
||||
int len = sizeof(result->string_storage);
|
||||
if(length < len)
|
||||
len = length;
|
||||
|
||||
str_copy(result->string_storage, string, length);
|
||||
str = result->string_storage;
|
||||
|
||||
/* get command */
|
||||
str = str_skipblanks(str);
|
||||
result->command = str;
|
||||
str = str_skiptoblank(str);
|
||||
|
||||
if(*str)
|
||||
{
|
||||
str[0] = 0;
|
||||
str++;
|
||||
}
|
||||
|
||||
result->args_start = str;
|
||||
result->num_args = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_parse_args(PARSE_RESULT *result, const char *format)
|
||||
{
|
||||
char command;
|
||||
char *str;
|
||||
int optional = 0;
|
||||
int error = 0;
|
||||
|
||||
str = result->args_start;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* fetch command */
|
||||
command = *format;
|
||||
format++;
|
||||
|
||||
if(!command)
|
||||
break;
|
||||
|
||||
if(command == '?')
|
||||
optional = 1;
|
||||
else
|
||||
{
|
||||
str = str_skipblanks(str);
|
||||
|
||||
if(!(*str)) /* error, non optional command needs value */
|
||||
{
|
||||
if(!optional)
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* add token */
|
||||
if(*str == '"')
|
||||
{
|
||||
char *dst;
|
||||
str++;
|
||||
result->args[result->num_args++] = str;
|
||||
|
||||
dst = str; /* we might have to process escape data */
|
||||
while(1)
|
||||
{
|
||||
if(str[0] == '"')
|
||||
break;
|
||||
else if(str[0] == '\\')
|
||||
{
|
||||
if(str[1] == '\\')
|
||||
str++; /* skip due to escape */
|
||||
else if(str[1] == '"')
|
||||
str++; /* skip due to escape */
|
||||
}
|
||||
else if(str[0] == 0)
|
||||
return 1; /* return error */
|
||||
|
||||
*dst = *str;
|
||||
dst++;
|
||||
str++;
|
||||
}
|
||||
|
||||
/* write null termination */
|
||||
*dst = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->args[result->num_args++] = str;
|
||||
|
||||
if(command == 'r') /* rest of the string */
|
||||
break;
|
||||
else if(command == 'i') /* validate int */
|
||||
str = str_skiptoblank(str);
|
||||
else if(command == 'f') /* validate float */
|
||||
str = str_skiptoblank(str);
|
||||
else if(command == 's') /* validate string */
|
||||
str = str_skiptoblank(str);
|
||||
|
||||
if(str[0] != 0) /* check for end of string */
|
||||
{
|
||||
str[0] = 0;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *console_arg_string(void *res, int index)
|
||||
{
|
||||
PARSE_RESULT *result = (PARSE_RESULT *)res;
|
||||
if (index < 0 || index >= result->num_args)
|
||||
return "";
|
||||
return result->args[index];
|
||||
}
|
||||
|
||||
int console_arg_int(void *res, int index)
|
||||
{
|
||||
PARSE_RESULT *result = (PARSE_RESULT *)res;
|
||||
if (index < 0 || index >= result->num_args)
|
||||
return 0;
|
||||
return atoi(result->args[index]);
|
||||
}
|
||||
|
||||
float console_arg_float(void *res, int index)
|
||||
{
|
||||
PARSE_RESULT *result = (PARSE_RESULT *)res;
|
||||
if (index < 0 || index >= result->num_args)
|
||||
return 0.0f;
|
||||
return atof(result->args[index]);
|
||||
}
|
||||
|
||||
int console_arg_num(void *result)
|
||||
{
|
||||
return ((PARSE_RESULT *)result)->num_args;
|
||||
}
|
||||
|
||||
static COMMAND *first_command = 0x0;
|
||||
|
||||
COMMAND *console_find_command(const char *name)
|
||||
{
|
||||
COMMAND *cmd;
|
||||
for (cmd = first_command; cmd; cmd = cmd->next)
|
||||
{
|
||||
if (strcmp(cmd->name, name) == 0)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void console_register(COMMAND *cmd)
|
||||
{
|
||||
cmd->next = first_command;
|
||||
first_command = cmd;
|
||||
}
|
||||
|
||||
static void (*print_callback)(const char *, void *) = 0x0;
|
||||
static void *print_callback_userdata;
|
||||
|
||||
void console_register_print_callback(void (*callback)(const char *, void *), void *user_data)
|
||||
{
|
||||
print_callback = callback;
|
||||
print_callback_userdata = user_data;
|
||||
}
|
||||
|
||||
void console_print(const char *str)
|
||||
{
|
||||
if (print_callback)
|
||||
print_callback(str, print_callback_userdata);
|
||||
}
|
||||
|
||||
void console_execute_line_stroked(int stroke, const char *str)
|
||||
{
|
||||
PARSE_RESULT result;
|
||||
COMMAND *command;
|
||||
|
||||
char strokestr[2] = {'0', 0};
|
||||
if(stroke)
|
||||
strokestr[0] = '1';
|
||||
|
||||
while(str)
|
||||
{
|
||||
const char *end = str;
|
||||
const char *next_part = 0;
|
||||
int in_string = 0;
|
||||
|
||||
while(*end)
|
||||
{
|
||||
if(*end == '"')
|
||||
in_string ^= 1;
|
||||
else if(*end == '\\') /* escape sequences */
|
||||
{
|
||||
if(end[1] == '"')
|
||||
end++;
|
||||
}
|
||||
else if(!in_string)
|
||||
{
|
||||
if(*end == ';') /* command separator */
|
||||
{
|
||||
next_part = end+1;
|
||||
break;
|
||||
}
|
||||
else if(*end == '#') /* comment, no need to do anything more */
|
||||
break;
|
||||
}
|
||||
|
||||
end++;
|
||||
}
|
||||
|
||||
if(console_parse_start(&result, str, (end-str) + 1) != 0)
|
||||
return;
|
||||
|
||||
command = console_find_command(result.command);
|
||||
|
||||
if(command)
|
||||
{
|
||||
int is_stroke_command = 0;
|
||||
if(result.command[0] == '+')
|
||||
{
|
||||
/* insert the stroke direction token */
|
||||
result.args[result.num_args] = strokestr;
|
||||
result.num_args++;
|
||||
is_stroke_command = 1;
|
||||
}
|
||||
|
||||
if(stroke || is_stroke_command)
|
||||
{
|
||||
if(console_parse_args(&result, command->params))
|
||||
{
|
||||
char buf[256];
|
||||
str_format(buf, sizeof(buf), "Invalid arguments... Usage: %s %s", command->name, command->params);
|
||||
console_print(buf);
|
||||
}
|
||||
else
|
||||
command->callback(&result, command->user_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[256];
|
||||
str_format(buf, sizeof(buf), "No such command: %s.", result.command);
|
||||
console_print(buf);
|
||||
}
|
||||
|
||||
str = next_part;
|
||||
}
|
||||
}
|
||||
|
||||
void console_possible_commands(const char *str, int flagmask, void (*callback)(const char *cmd, void *user), void *user)
|
||||
{
|
||||
COMMAND *cmd;
|
||||
for (cmd = first_command; cmd; cmd = cmd->next)
|
||||
{
|
||||
if(cmd->flags&flagmask)
|
||||
{
|
||||
if(str_find_nocase(cmd->name, str))
|
||||
callback(cmd->name, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMMAND *console_get_command(const char *str)
|
||||
{
|
||||
COMMAND *cmd;
|
||||
for (cmd = first_command; cmd; cmd = cmd->next)
|
||||
{
|
||||
if(str_comp_nocase(cmd->name, str) == 0)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void console_execute_line(const char *str)
|
||||
{
|
||||
console_execute_line_stroked(1, str);
|
||||
}
|
||||
|
||||
static void console_execute_file_real(const char *filename)
|
||||
{
|
||||
IOHANDLE file;
|
||||
file = engine_openfile(filename, IOFLAG_READ);
|
||||
|
||||
if(file)
|
||||
{
|
||||
char *line;
|
||||
LINEREADER lr;
|
||||
|
||||
dbg_msg("console", "executing '%s'", filename);
|
||||
linereader_init(&lr, file);
|
||||
|
||||
while((line = linereader_get(&lr)))
|
||||
console_execute_line(line);
|
||||
|
||||
io_close(file);
|
||||
}
|
||||
else
|
||||
dbg_msg("console", "failed to open '%s'", filename);
|
||||
}
|
||||
|
||||
struct EXECFILE
|
||||
{
|
||||
const char *filename;
|
||||
struct EXECFILE *next;
|
||||
};
|
||||
|
||||
void console_execute_file(const char *filename)
|
||||
{
|
||||
static struct EXECFILE *first = 0;
|
||||
struct EXECFILE thisfile;
|
||||
struct EXECFILE *cur;
|
||||
struct EXECFILE *prev;
|
||||
|
||||
/* make sure that this isn't being executed already */
|
||||
for(cur = first; cur; cur = cur->next)
|
||||
if(strcmp(filename, cur->filename) == 0)
|
||||
return;
|
||||
|
||||
/* push this one to the stack */
|
||||
prev = first;
|
||||
thisfile.filename = filename;
|
||||
thisfile.next = first;
|
||||
first = &thisfile;
|
||||
|
||||
/* execute file */
|
||||
console_execute_file_real(filename);
|
||||
|
||||
/* pop this one from the stack */
|
||||
first = prev;
|
||||
}
|
||||
|
||||
static void con_echo(void *result, void *user_data)
|
||||
{
|
||||
console_print(console_arg_string(result, 0));
|
||||
}
|
||||
|
||||
static void con_exec(void *result, void *user_data)
|
||||
{
|
||||
console_execute_file(console_arg_string(result, 0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CONFIG_INT_GETTER getter;
|
||||
CONFIG_INT_SETTER setter;
|
||||
} INT_VARIABLE_DATA;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CONFIG_STR_GETTER getter;
|
||||
CONFIG_STR_SETTER setter;
|
||||
} STR_VARIABLE_DATA;
|
||||
|
||||
static void int_variable_command(void *result, void *user_data)
|
||||
{
|
||||
INT_VARIABLE_DATA *data = (INT_VARIABLE_DATA *)user_data;
|
||||
|
||||
if(console_arg_num(result))
|
||||
data->setter(&config, console_arg_int(result, 0));
|
||||
else
|
||||
{
|
||||
char buf[1024];
|
||||
str_format(buf, sizeof(buf), "Value: %d", data->getter(&config));
|
||||
console_print(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void str_variable_command(void *result, void *user_data)
|
||||
{
|
||||
STR_VARIABLE_DATA *data = (STR_VARIABLE_DATA *)user_data;
|
||||
|
||||
if(console_arg_num(result))
|
||||
data->setter(&config, console_arg_string(result, 0));
|
||||
else
|
||||
{
|
||||
char buf[1024];
|
||||
str_format(buf, sizeof(buf), "Value: %s", data->getter(&config));
|
||||
console_print(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void console_init()
|
||||
{
|
||||
MACRO_REGISTER_COMMAND("echo", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_echo, 0x0, "Echo the text");
|
||||
MACRO_REGISTER_COMMAND("exec", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_exec, 0x0, "Execute the specified file");
|
||||
|
||||
#define MACRO_CONFIG_INT(name,def,min,max,flags,desc) { static INT_VARIABLE_DATA data = { &config_get_ ## name, &config_set_ ## name }; MACRO_REGISTER_COMMAND(#name, "?i", flags, int_variable_command, &data, desc) }
|
||||
#define MACRO_CONFIG_STR(name,len,def,flags,desc) { static STR_VARIABLE_DATA data = { &config_get_ ## name, &config_set_ ## name }; MACRO_REGISTER_COMMAND(#name, "?r", flags, str_variable_command, &data, desc) }
|
||||
|
||||
#include "e_config_variables.h"
|
||||
|
||||
#undef MACRO_CONFIG_INT
|
||||
#undef MACRO_CONFIG_STR
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef _CONSOLE_H
|
||||
#define _CONSOLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
typedef void (*CONSOLE_CALLBACK)(void *result, void *user_data);
|
||||
|
||||
typedef struct COMMAND_t
|
||||
{
|
||||
const char *name;
|
||||
const char *params;
|
||||
int flags;
|
||||
CONSOLE_CALLBACK callback;
|
||||
void *user_data;
|
||||
const char *help;
|
||||
struct COMMAND_t *next;
|
||||
} COMMAND;
|
||||
|
||||
void console_init();
|
||||
void console_register(COMMAND *cmd);
|
||||
void console_execute_line(const char *str);
|
||||
void console_execute_line_stroked(int stroke, const char *str);
|
||||
void console_execute_file(const char *filename);
|
||||
void console_possible_commands(const char *str, int flagmask, void (*callback)(const char *cmd, void *user), void *user);
|
||||
COMMAND *console_get_command(const char *cmd);
|
||||
void console_print(const char *str);
|
||||
void console_register_print_callback(void (*callback)(const char *, void *user_data), void *user_data);
|
||||
|
||||
/*int console_result_string(void *result, int index, const char **str);
|
||||
int console_result_int(void *result, int index, int *i);
|
||||
int console_result_float(void *result, int index, float *f);*/
|
||||
|
||||
const char *console_arg_string(void *result, int index);
|
||||
int console_arg_int(void *result, int index);
|
||||
float console_arg_float(void *result, int index);
|
||||
int console_arg_num(void *result);
|
||||
|
||||
#define MACRO_REGISTER_COMMAND(name, params, flags, func, ptr, help) { static COMMAND cmd = { name, params, flags, func, ptr, help, 0x0}; console_register(&cmd); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,677 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include "e_datafile.h"
|
||||
#include "e_engine.h"
|
||||
#include <zlib.h>
|
||||
|
||||
static const int DEBUG=0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int start;
|
||||
int num;
|
||||
} DATAFILE_ITEM_TYPE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type_and_id;
|
||||
int size;
|
||||
} DATAFILE_ITEM;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char id[4];
|
||||
int version;
|
||||
int size;
|
||||
int swaplen;
|
||||
int num_item_types;
|
||||
int num_items;
|
||||
int num_raw_data;
|
||||
int item_size;
|
||||
int data_size;
|
||||
} DATAFILE_HEADER;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num_item_types;
|
||||
int num_items;
|
||||
int num_raw_data;
|
||||
int item_size;
|
||||
int data_size;
|
||||
char start[4];
|
||||
} DATAFILE_DATA;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DATAFILE_ITEM_TYPE *item_types;
|
||||
int *item_offsets;
|
||||
int *data_offsets;
|
||||
int *data_sizes;
|
||||
|
||||
char *item_start;
|
||||
char *data_start;
|
||||
} DATAFILE_INFO;
|
||||
|
||||
struct DATAFILE_t
|
||||
{
|
||||
IOHANDLE file;
|
||||
DATAFILE_INFO info;
|
||||
DATAFILE_HEADER header;
|
||||
int data_start_offset;
|
||||
char **data_ptrs;
|
||||
char *data;
|
||||
};
|
||||
|
||||
DATAFILE *datafile_load(const char *filename)
|
||||
{
|
||||
DATAFILE *df;
|
||||
IOHANDLE file;
|
||||
DATAFILE_HEADER header;
|
||||
unsigned readsize;
|
||||
|
||||
unsigned *dst;
|
||||
unsigned char *src;
|
||||
unsigned j;
|
||||
int size = 0;
|
||||
int allocsize = 0;
|
||||
|
||||
(void)dst;
|
||||
(void)src;
|
||||
(void)j;
|
||||
|
||||
|
||||
dbg_msg("datafile", "datafile loading. filename='%s'", filename);
|
||||
|
||||
file = engine_openfile(filename, IOFLAG_READ);
|
||||
if(!file)
|
||||
return 0;
|
||||
|
||||
/* TODO: change this header */
|
||||
io_read(file, &header, sizeof(header));
|
||||
if(header.id[0] != 'A' || header.id[1] != 'T' || header.id[2] != 'A' || header.id[3] != 'D')
|
||||
{
|
||||
if(header.id[0] != 'D' || header.id[1] != 'A' || header.id[2] != 'T' || header.id[3] != 'A')
|
||||
{
|
||||
dbg_msg("datafile", "wrong signature. %x %x %x %x", header.id[0], header.id[1], header.id[2], header.id[3]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
swap_endian(&header, sizeof(int), sizeof(header)/sizeof(int));
|
||||
#endif
|
||||
if(header.version != 3 && header.version != 4)
|
||||
{
|
||||
dbg_msg("datafile", "wrong version. version=%x", header.version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read in the rest except the data */
|
||||
size = 0;
|
||||
size += header.num_item_types*sizeof(DATAFILE_ITEM_TYPE);
|
||||
size += (header.num_items+header.num_raw_data)*sizeof(int);
|
||||
if(header.version == 4)
|
||||
size += header.num_raw_data*sizeof(int); /* v4 has uncompressed data sizes aswell */
|
||||
size += header.item_size;
|
||||
|
||||
allocsize = size;
|
||||
allocsize += sizeof(DATAFILE); /* add space for info structure */
|
||||
allocsize += header.num_raw_data*sizeof(void*); /* add space for data pointers */
|
||||
|
||||
df = (DATAFILE*)mem_alloc(allocsize, 1);
|
||||
df->header = header;
|
||||
df->data_start_offset = sizeof(DATAFILE_HEADER) + size;
|
||||
df->data_ptrs = (char**)(df+1);
|
||||
df->data = (char *)(df+1)+header.num_raw_data*sizeof(char *);
|
||||
df->file = file;
|
||||
|
||||
/* clear the data pointers */
|
||||
mem_zero(df->data_ptrs, header.num_raw_data*sizeof(void*));
|
||||
|
||||
/* read types, offsets, sizes and item data */
|
||||
readsize = io_read(file, df->data, size);
|
||||
if(readsize != size)
|
||||
{
|
||||
dbg_msg("datafile", "couldn't load the whole thing, wanted=%d got=%d", size, readsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
swap_endian(df->data, sizeof(int), header.swaplen / sizeof(int));
|
||||
#endif
|
||||
|
||||
if(DEBUG)
|
||||
{
|
||||
dbg_msg("datafile", "allocsize=%d", allocsize);
|
||||
dbg_msg("datafile", "readsize=%d", readsize);
|
||||
dbg_msg("datafile", "swaplen=%d", header.swaplen);
|
||||
dbg_msg("datafile", "item_size=%d", df->header.item_size);
|
||||
}
|
||||
|
||||
df->info.item_types = (DATAFILE_ITEM_TYPE *)df->data;
|
||||
df->info.item_offsets = (int *)&df->info.item_types[df->header.num_item_types];
|
||||
df->info.data_offsets = (int *)&df->info.item_offsets[df->header.num_items];
|
||||
df->info.data_sizes = (int *)&df->info.data_offsets[df->header.num_raw_data];
|
||||
|
||||
if(header.version == 4)
|
||||
df->info.item_start = (char *)&df->info.data_sizes[df->header.num_raw_data];
|
||||
else
|
||||
df->info.item_start = (char *)&df->info.data_offsets[df->header.num_raw_data];
|
||||
df->info.data_start = df->info.item_start + df->header.item_size;
|
||||
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "datafile loading done. datafile='%s'", filename);
|
||||
|
||||
if(DEBUG)
|
||||
{
|
||||
/*
|
||||
for(int i = 0; i < df->data.num_raw_data; i++)
|
||||
{
|
||||
void *p = datafile_get_data(df, i);
|
||||
dbg_msg("datafile", "%d %d", (int)((char*)p - (char*)(&df->data)), size);
|
||||
}
|
||||
|
||||
for(int i = 0; i < datafile_num_items(df); i++)
|
||||
{
|
||||
int type, id;
|
||||
void *data = datafile_get_item(df, i, &type, &id);
|
||||
dbg_msg("map", "\t%d: type=%x id=%x p=%p offset=%d", i, type, id, data, df->info.item_offsets[i]);
|
||||
int *idata = (int*)data;
|
||||
for(int k = 0; k < 3; k++)
|
||||
dbg_msg("datafile", "\t\t%d=%d (%x)", k, idata[k], idata[k]);
|
||||
}
|
||||
|
||||
for(int i = 0; i < df->data.num_item_types; i++)
|
||||
{
|
||||
dbg_msg("map", "\t%d: type=%x start=%d num=%d", i,
|
||||
df->info.item_types[i].type,
|
||||
df->info.item_types[i].start,
|
||||
df->info.item_types[i].num);
|
||||
for(int k = 0; k < df->info.item_types[i].num; k++)
|
||||
{
|
||||
int type, id;
|
||||
datafile_get_item(df, df->info.item_types[i].start+k, &type, &id);
|
||||
if(type != df->info.item_types[i].type)
|
||||
dbg_msg("map", "\tERROR");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return df;
|
||||
}
|
||||
|
||||
int datafile_num_data(DATAFILE *df)
|
||||
{
|
||||
return df->header.num_raw_data;
|
||||
}
|
||||
|
||||
/* always returns the size in the file */
|
||||
int datafile_get_datasize(DATAFILE *df, int index)
|
||||
{
|
||||
if(index == df->header.num_raw_data-1)
|
||||
return df->header.data_size-df->info.data_offsets[index];
|
||||
return df->info.data_offsets[index+1]-df->info.data_offsets[index];
|
||||
}
|
||||
|
||||
static void *datafile_get_data_impl(DATAFILE *df, int index, int swap)
|
||||
{
|
||||
/* load it if needed */
|
||||
if(!df->data_ptrs[index])
|
||||
{
|
||||
/* fetch the data size */
|
||||
int datasize = datafile_get_datasize(df, index);
|
||||
int swapsize = datasize;
|
||||
|
||||
if(df->header.version == 4)
|
||||
{
|
||||
/* v4 has compressed data */
|
||||
void *temp = (char *)mem_alloc(datasize, 1);
|
||||
unsigned long uncompressed_size = df->info.data_sizes[index];
|
||||
unsigned long s;
|
||||
|
||||
dbg_msg("datafile", "loading data index=%d size=%d uncompressed=%d", index, datasize, uncompressed_size);
|
||||
df->data_ptrs[index] = (char *)mem_alloc(uncompressed_size, 1);
|
||||
|
||||
/* read the compressed data */
|
||||
io_seek(df->file, df->data_start_offset+df->info.data_offsets[index], IOSEEK_START);
|
||||
io_read(df->file, temp, datasize);
|
||||
|
||||
/* decompress the data, TODO: check for errors */
|
||||
s = uncompressed_size;
|
||||
uncompress((Bytef*)df->data_ptrs[index], &s, (Bytef*)temp, datasize);
|
||||
swapsize = s;
|
||||
|
||||
/* clean up the temporary buffers */
|
||||
mem_free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load the data */
|
||||
dbg_msg("datafile", "loading data index=%d size=%d", index, datasize);
|
||||
df->data_ptrs[index] = (char *)mem_alloc(datasize, 1);
|
||||
io_seek(df->file, df->data_start_offset+df->info.data_offsets[index], IOSEEK_START);
|
||||
io_read(df->file, df->data_ptrs[index], datasize);
|
||||
}
|
||||
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
if(swap && swapsize)
|
||||
swap_endian(df->data_ptrs[index], sizeof(int), swapsize/sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
return df->data_ptrs[index];
|
||||
}
|
||||
|
||||
void *datafile_get_data(DATAFILE *df, int index)
|
||||
{
|
||||
return datafile_get_data_impl(df, index, 0);
|
||||
}
|
||||
|
||||
void *datafile_get_data_swapped(DATAFILE *df, int index)
|
||||
{
|
||||
return datafile_get_data_impl(df, index, 1);
|
||||
}
|
||||
|
||||
void datafile_unload_data(DATAFILE *df, int index)
|
||||
{
|
||||
if(index < 0)
|
||||
return;
|
||||
|
||||
/* */
|
||||
mem_free(df->data_ptrs[index]);
|
||||
df->data_ptrs[index] = 0x0;
|
||||
}
|
||||
|
||||
int datafile_get_itemsize(DATAFILE *df, int index)
|
||||
{
|
||||
if(index == df->header.num_items-1)
|
||||
return df->header.item_size-df->info.item_offsets[index];
|
||||
return df->info.item_offsets[index+1]-df->info.item_offsets[index];
|
||||
}
|
||||
|
||||
void *datafile_get_item(DATAFILE *df, int index, int *type, int *id)
|
||||
{
|
||||
DATAFILE_ITEM *i = (DATAFILE_ITEM *)(df->info.item_start+df->info.item_offsets[index]);
|
||||
if(type)
|
||||
*type = (i->type_and_id>>16)&0xffff; /* remove sign extention */
|
||||
if(id)
|
||||
*id = i->type_and_id&0xffff;
|
||||
return (void *)(i+1);
|
||||
}
|
||||
|
||||
void datafile_get_type(DATAFILE *df, int type, int *start, int *num)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < df->header.num_item_types; i++)
|
||||
{
|
||||
if(df->info.item_types[i].type == type)
|
||||
{
|
||||
*start = df->info.item_types[i].start;
|
||||
*num = df->info.item_types[i].num;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*start = 0;
|
||||
*num = 0;
|
||||
}
|
||||
|
||||
void *datafile_find_item(DATAFILE *df, int type, int id)
|
||||
{
|
||||
int start, num,i ;
|
||||
int item_id;
|
||||
void *item;
|
||||
|
||||
datafile_get_type(df, type, &start, &num);
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
item = datafile_get_item(df, start+i,0, &item_id);
|
||||
if(id == item_id)
|
||||
return item;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int datafile_num_items(DATAFILE *df)
|
||||
{
|
||||
return df->header.num_items;
|
||||
}
|
||||
|
||||
void datafile_unload(DATAFILE *df)
|
||||
{
|
||||
if(df)
|
||||
{
|
||||
/* free the data that is loaded */
|
||||
int i;
|
||||
for(i = 0; i < df->header.num_raw_data; i++)
|
||||
mem_free(df->data_ptrs[i]);
|
||||
|
||||
io_close(df->file);
|
||||
mem_free(df);
|
||||
}
|
||||
}
|
||||
|
||||
/* DATAFILE output */
|
||||
typedef struct
|
||||
{
|
||||
int uncompressed_size;
|
||||
int compressed_size;
|
||||
void *compressed_data;
|
||||
} DATA_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int id;
|
||||
int size;
|
||||
int next;
|
||||
int prev;
|
||||
void *data;
|
||||
} ITEM_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num;
|
||||
int first;
|
||||
int last;
|
||||
} ITEMTYPE_INFO;
|
||||
|
||||
/* */
|
||||
struct DATAFILE_OUT_t
|
||||
{
|
||||
IOHANDLE file;
|
||||
int num_items;
|
||||
int num_datas;
|
||||
int num_item_types;
|
||||
ITEMTYPE_INFO item_types[0xffff];
|
||||
ITEM_INFO items[1024];
|
||||
DATA_INFO datas[1024];
|
||||
};
|
||||
|
||||
DATAFILE_OUT *datafile_create(const char *filename)
|
||||
{
|
||||
int i;
|
||||
DATAFILE_OUT *df = (DATAFILE_OUT*)mem_alloc(sizeof(DATAFILE_OUT), 1);
|
||||
df->file = engine_openfile(filename, IOFLAG_WRITE);
|
||||
if(!df->file)
|
||||
{
|
||||
mem_free(df);
|
||||
return 0;
|
||||
}
|
||||
|
||||
df->num_items = 0;
|
||||
df->num_datas = 0;
|
||||
df->num_item_types = 0;
|
||||
mem_zero(&df->item_types, sizeof(df->item_types));
|
||||
|
||||
for(i = 0; i < 0xffff; i++)
|
||||
{
|
||||
df->item_types[i].first = -1;
|
||||
df->item_types[i].last = -1;
|
||||
}
|
||||
|
||||
return df;
|
||||
}
|
||||
|
||||
int datafile_add_item(DATAFILE_OUT *df, int type, int id, int size, void *data)
|
||||
{
|
||||
df->items[df->num_items].type = type;
|
||||
df->items[df->num_items].id = id;
|
||||
df->items[df->num_items].size = size;
|
||||
|
||||
/*
|
||||
dbg_msg("datafile", "added item type=%d id=%d size=%d", type, id, size);
|
||||
int i;
|
||||
for(i = 0; i < size/4; i++)
|
||||
dbg_msg("datafile", "\t%d: %08x %d", i, ((int*)data)[i], ((int*)data)[i]);
|
||||
*/
|
||||
|
||||
/* copy data */
|
||||
df->items[df->num_items].data = mem_alloc(size, 1);
|
||||
mem_copy(df->items[df->num_items].data, data, size);
|
||||
|
||||
if(!df->item_types[type].num) /* count item types */
|
||||
df->num_item_types++;
|
||||
|
||||
/* link */
|
||||
df->items[df->num_items].prev = df->item_types[type].last;
|
||||
df->items[df->num_items].next = -1;
|
||||
|
||||
if(df->item_types[type].last != -1)
|
||||
df->items[df->item_types[type].last].next = df->num_items;
|
||||
df->item_types[type].last = df->num_items;
|
||||
|
||||
if(df->item_types[type].first == -1)
|
||||
df->item_types[type].first = df->num_items;
|
||||
|
||||
df->item_types[type].num++;
|
||||
|
||||
df->num_items++;
|
||||
return df->num_items-1;
|
||||
}
|
||||
|
||||
int datafile_add_data(DATAFILE_OUT *df, int size, void *data)
|
||||
{
|
||||
DATA_INFO *info = &df->datas[df->num_datas];
|
||||
unsigned long s = compressBound(size);
|
||||
void *compdata = mem_alloc(s, 1); /* temporary buffer that we use duing compression */
|
||||
|
||||
int result = compress((Bytef*)compdata, &s, (Bytef*)data, size);
|
||||
if(result != Z_OK)
|
||||
{
|
||||
dbg_msg("datafile", "compression error %d", result);
|
||||
dbg_assert(0, "zlib error");
|
||||
}
|
||||
|
||||
info->uncompressed_size = size;
|
||||
info->compressed_size = (int)s;
|
||||
info->compressed_data = mem_alloc(info->compressed_size, 1);
|
||||
mem_copy(info->compressed_data, compdata, info->compressed_size);
|
||||
mem_free(compdata);
|
||||
|
||||
df->num_datas++;
|
||||
return df->num_datas-1;
|
||||
}
|
||||
|
||||
int datafile_add_data_swapped(DATAFILE_OUT *df, int size, void *data)
|
||||
{
|
||||
#if defined(CONF_ARCH_ENDIAN_BIG)
|
||||
void *swapped = mem_alloc(size, 1); /* temporary buffer that we use duing compression */
|
||||
int index;
|
||||
mem_copy(swapped, data, size);
|
||||
swap_endian(&swapped, sizeof(int), size/sizeof(int));
|
||||
index = datafile_add_data(df, size, swapped);
|
||||
mem_free(swapped);
|
||||
return index;
|
||||
#else
|
||||
return datafile_add_data(df, size, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int datafile_finish(DATAFILE_OUT *df)
|
||||
{
|
||||
int itemsize = 0;
|
||||
int i, count, offset;
|
||||
int typessize, headersize, offsetsize, filesize, swapsize;
|
||||
int datasize = 0;
|
||||
DATAFILE_ITEM_TYPE info;
|
||||
DATAFILE_ITEM itm;
|
||||
DATAFILE_HEADER header;
|
||||
|
||||
/* we should now write this file! */
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing");
|
||||
|
||||
/* calculate sizes */
|
||||
for(i = 0; i < df->num_items; i++)
|
||||
{
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "item=%d size=%d (%d)", i, df->items[i].size, df->items[i].size+sizeof(DATAFILE_ITEM));
|
||||
itemsize += df->items[i].size + sizeof(DATAFILE_ITEM);
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < df->num_datas; i++)
|
||||
datasize += df->datas[i].compressed_size;
|
||||
|
||||
/* calculate the complete size */
|
||||
typessize = df->num_item_types*sizeof(DATAFILE_ITEM_TYPE);
|
||||
headersize = sizeof(DATAFILE_HEADER);
|
||||
offsetsize = df->num_items*sizeof(int) + df->num_datas*sizeof(int);
|
||||
filesize = headersize + typessize + offsetsize + itemsize + datasize;
|
||||
swapsize = filesize - datasize;
|
||||
|
||||
(void)swapsize;
|
||||
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "num_item_types=%d typessize=%d itemsize=%d datasize=%d", df->num_item_types, typessize, itemsize, datasize);
|
||||
|
||||
/* construct header */
|
||||
{
|
||||
header.id[0] = 'D';
|
||||
header.id[1] = 'A';
|
||||
header.id[2] = 'T';
|
||||
header.id[3] = 'A';
|
||||
header.version = 4;
|
||||
header.size = filesize - 16;
|
||||
header.swaplen = swapsize - 16;
|
||||
header.num_item_types = df->num_item_types;
|
||||
header.num_items = df->num_items;
|
||||
header.num_raw_data = df->num_datas;
|
||||
header.item_size = itemsize;
|
||||
header.data_size = datasize;
|
||||
|
||||
/* TODO: apply swapping */
|
||||
/* write header */
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "headersize=%d", sizeof(header));
|
||||
io_write(df->file, &header, sizeof(header));
|
||||
}
|
||||
|
||||
/* write types */
|
||||
for(i = 0, count = 0; i < 0xffff; i++)
|
||||
{
|
||||
if(df->item_types[i].num)
|
||||
{
|
||||
/* write info */
|
||||
info.type = i;
|
||||
info.start = count;
|
||||
info.num = df->item_types[i].num;
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing type=%x start=%d num=%d", info.type, info.start, info.num);
|
||||
io_write(df->file, &info, sizeof(info));
|
||||
count += df->item_types[i].num;
|
||||
}
|
||||
}
|
||||
|
||||
/* write item offsets */
|
||||
for(i = 0, offset = 0; i < 0xffff; i++)
|
||||
{
|
||||
if(df->item_types[i].num)
|
||||
{
|
||||
/* write all items in of this type */
|
||||
int k = df->item_types[i].first;
|
||||
while(k != -1)
|
||||
{
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing item offset num=%d offset=%d", k, offset);
|
||||
io_write(df->file, &offset, sizeof(offset));
|
||||
offset += df->items[k].size + sizeof(DATAFILE_ITEM);
|
||||
|
||||
/* next */
|
||||
k = df->items[k].next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write data offsets */
|
||||
for(i = 0, offset = 0; i < df->num_datas; i++)
|
||||
{
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing data offset num=%d offset=%d", i, offset);
|
||||
io_write(df->file, &offset, sizeof(offset));
|
||||
offset += df->datas[i].compressed_size;
|
||||
}
|
||||
|
||||
/* write data uncompressed sizes */
|
||||
for(i = 0, offset = 0; i < df->num_datas; i++)
|
||||
{
|
||||
/*
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing data offset num=%d offset=%d", i, offset);
|
||||
*/
|
||||
io_write(df->file, &df->datas[i].uncompressed_size, sizeof(int));
|
||||
}
|
||||
|
||||
/* write items */
|
||||
for(i = 0; i < 0xffff; i++)
|
||||
{
|
||||
if(df->item_types[i].num)
|
||||
{
|
||||
/* write all items in of this type */
|
||||
int k = df->item_types[i].first;
|
||||
while(k != -1)
|
||||
{
|
||||
itm.type_and_id = (i<<16)|df->items[k].id;
|
||||
itm.size = df->items[k].size;
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing item type=%x idx=%d id=%d size=%d", i, k, df->items[k].id, df->items[k].size);
|
||||
|
||||
io_write(df->file, &itm, sizeof(itm));
|
||||
io_write(df->file, df->items[k].data, df->items[k].size);
|
||||
|
||||
/* next */
|
||||
k = df->items[k].next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write data */
|
||||
for(i = 0; i < df->num_datas; i++)
|
||||
{
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "writing data id=%d size=%d", i, df->datas[i].compressed_size);
|
||||
io_write(df->file, df->datas[i].compressed_data, df->datas[i].compressed_size);
|
||||
}
|
||||
|
||||
/* free data */
|
||||
for(i = 0; i < df->num_items; i++)
|
||||
mem_free(df->items[i].data);
|
||||
|
||||
|
||||
io_close(df->file);
|
||||
mem_free(df);
|
||||
|
||||
if(DEBUG)
|
||||
dbg_msg("datafile", "done");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 64*1024
|
||||
|
||||
int datafile_crc(const char *filename)
|
||||
{
|
||||
unsigned char buffer[BUFFER_SIZE];
|
||||
IOHANDLE file;
|
||||
int crc = 0;
|
||||
unsigned bytes = 0;
|
||||
|
||||
file = engine_openfile(filename, IOFLAG_READ);
|
||||
if(!file)
|
||||
return 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
bytes = io_read(file, buffer, BUFFER_SIZE);
|
||||
if(bytes <= 0)
|
||||
break;
|
||||
crc = crc32(crc, buffer, bytes);
|
||||
}
|
||||
|
||||
io_close(file);
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef __DATAFILE__H__
|
||||
#define __DATAFILE__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* raw datafile access */
|
||||
typedef struct DATAFILE_t DATAFILE;
|
||||
|
||||
/* read access */
|
||||
DATAFILE *datafile_load(const char *filename);
|
||||
DATAFILE *datafile_load_old(const char *filename);
|
||||
void *datafile_get_data(DATAFILE *df, int index);
|
||||
void *datafile_get_data_swapped(DATAFILE *df, int index); /* makes sure that the data is 32bit LE ints when saved */
|
||||
int datafile_get_datasize(DATAFILE *df, int index);
|
||||
void datafile_unload_data(DATAFILE *df, int index);
|
||||
void *datafile_get_item(DATAFILE *df, int index, int *type, int *id);
|
||||
int datafile_get_itemsize(DATAFILE *df, int index);
|
||||
void datafile_get_type(DATAFILE *df, int type, int *start, int *num);
|
||||
void *datafile_find_item(DATAFILE *df, int type, int id);
|
||||
int datafile_num_items(DATAFILE *df);
|
||||
int datafile_num_data(DATAFILE *df);
|
||||
void datafile_unload(DATAFILE *df);
|
||||
|
||||
int datafile_crc(const char *filename);
|
||||
|
||||
/* write access */
|
||||
typedef struct DATAFILE_OUT_t DATAFILE_OUT;
|
||||
DATAFILE_OUT *datafile_create(const char *filename);
|
||||
int datafile_add_data(DATAFILE_OUT *df, int size, void *data);
|
||||
int datafile_add_data_swapped(DATAFILE_OUT *df, int size, void *data);
|
||||
int datafile_add_item(DATAFILE_OUT *df, int type, int id, int size, void *data);
|
||||
int datafile_finish(DATAFILE_OUT *df);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,640 +0,0 @@
|
||||
|
||||
#include <base/system.h>
|
||||
#include "e_demorec.h"
|
||||
#include "e_memheap.h"
|
||||
#include "e_snapshot.h"
|
||||
#include "e_compression.h"
|
||||
#include "e_network.h"
|
||||
#include "e_engine.h"
|
||||
#include "e_if_other.h"
|
||||
#include "e_demorec.h"
|
||||
|
||||
static IOHANDLE record_file = 0;
|
||||
static const unsigned char header_marker[8] = {'T', 'W', 'D', 'E', 'M', 'O', 0, 1};
|
||||
|
||||
/* Record */
|
||||
static int record_lasttickmarker = -1;
|
||||
static int record_lastkeyframe;
|
||||
static unsigned char record_lastsnapshotdata[MAX_SNAPSHOT_SIZE];
|
||||
|
||||
int demorec_isrecording() { return record_file != 0; }
|
||||
|
||||
int demorec_record_start(const char *filename, const char *netversion, const char *map, int crc, const char *type)
|
||||
{
|
||||
DEMOREC_HEADER header;
|
||||
if(record_file)
|
||||
return -1;
|
||||
|
||||
record_file = engine_openfile(filename, IOFLAG_WRITE);
|
||||
|
||||
if(!record_file)
|
||||
{
|
||||
dbg_msg("demorec/record", "Unable to open '%s' for recording", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write header */
|
||||
mem_zero(&header, sizeof(header));
|
||||
mem_copy(header.marker, header_marker, sizeof(header.marker));
|
||||
str_copy(header.netversion, netversion, sizeof(header.netversion));
|
||||
str_copy(header.map, map, sizeof(header.map));
|
||||
str_copy(header.type, type, sizeof(header.type));
|
||||
header.crc[0] = (crc>>24)&0xff;
|
||||
header.crc[1] = (crc>>16)&0xff;
|
||||
header.crc[2] = (crc>>8)&0xff;
|
||||
header.crc[3] = (crc)&0xff;
|
||||
io_write(record_file, &header, sizeof(header));
|
||||
|
||||
record_lastkeyframe = -1;
|
||||
record_lasttickmarker = -1;
|
||||
|
||||
dbg_msg("demorec/record", "Recording to '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Tickmarker
|
||||
7 = Always set
|
||||
6 = Keyframe flag
|
||||
0-5 = Delta tick
|
||||
|
||||
Normal
|
||||
7 = Not set
|
||||
5-6 = Type
|
||||
0-4 = Size
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
CHUNKTYPEFLAG_TICKMARKER = 0x80,
|
||||
CHUNKTICKFLAG_KEYFRAME = 0x40, /* only when tickmarker is set*/
|
||||
|
||||
CHUNKMASK_TICK = 0x3f,
|
||||
CHUNKMASK_TYPE = 0x60,
|
||||
CHUNKMASK_SIZE = 0x1f,
|
||||
|
||||
CHUNKTYPE_SNAPSHOT = 1,
|
||||
CHUNKTYPE_MESSAGE = 2,
|
||||
CHUNKTYPE_DELTA = 3,
|
||||
|
||||
CHUNKFLAG_BIGSIZE = 0x10
|
||||
};
|
||||
|
||||
static void demorec_record_write_tickmarker(int tick, int keyframe)
|
||||
{
|
||||
if(record_lasttickmarker == -1 || tick-record_lasttickmarker > 63 || keyframe)
|
||||
{
|
||||
unsigned char chunk[5];
|
||||
chunk[0] = CHUNKTYPEFLAG_TICKMARKER;
|
||||
chunk[1] = (tick>>24)&0xff;
|
||||
chunk[2] = (tick>>16)&0xff;
|
||||
chunk[3] = (tick>>8)&0xff;
|
||||
chunk[4] = (tick)&0xff;
|
||||
|
||||
if(keyframe)
|
||||
chunk[0] |= CHUNKTICKFLAG_KEYFRAME;
|
||||
|
||||
io_write(record_file, chunk, sizeof(chunk));
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char chunk[1];
|
||||
chunk[0] = CHUNKTYPEFLAG_TICKMARKER | (tick-record_lasttickmarker);
|
||||
io_write(record_file, chunk, sizeof(chunk));
|
||||
}
|
||||
|
||||
record_lasttickmarker = tick;
|
||||
}
|
||||
|
||||
static void demorec_record_write(int type, const void *data, int size)
|
||||
{
|
||||
char buffer[64*1024];
|
||||
char buffer2[64*1024];
|
||||
unsigned char chunk[3];
|
||||
|
||||
if(!record_file)
|
||||
return;
|
||||
|
||||
|
||||
/* pad the data with 0 so we get an alignment of 4,
|
||||
else the compression won't work and miss some bytes */
|
||||
mem_copy(buffer2, data, size);
|
||||
while(size&3)
|
||||
buffer2[size++] = 0;
|
||||
size = intpack_compress(buffer2, size, buffer); /* buffer2 -> buffer */
|
||||
size = netcommon_compress(buffer, size, buffer2, sizeof(buffer2)); /* buffer -> buffer2 */
|
||||
|
||||
|
||||
chunk[0] = ((type&0x3)<<5);
|
||||
if(size < 30)
|
||||
{
|
||||
chunk[0] |= size;
|
||||
io_write(record_file, chunk, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(size < 256)
|
||||
{
|
||||
chunk[0] |= 30;
|
||||
chunk[1] = size&0xff;
|
||||
io_write(record_file, chunk, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk[0] |= 31;
|
||||
chunk[1] = size&0xff;
|
||||
chunk[2] = size>>8;
|
||||
io_write(record_file, chunk, 3);
|
||||
}
|
||||
}
|
||||
|
||||
io_write(record_file, buffer2, size);
|
||||
}
|
||||
|
||||
void demorec_record_snapshot(int tick, const void *data, int size)
|
||||
{
|
||||
if(record_lastkeyframe == -1 || (tick-record_lastkeyframe) > SERVER_TICK_SPEED*5)
|
||||
{
|
||||
/* write full tickmarker */
|
||||
demorec_record_write_tickmarker(tick, 1);
|
||||
|
||||
/* write snapshot */
|
||||
demorec_record_write(CHUNKTYPE_SNAPSHOT, data, size);
|
||||
|
||||
record_lastkeyframe = tick;
|
||||
mem_copy(record_lastsnapshotdata, data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create delta, prepend tick */
|
||||
char delta_data[MAX_SNAPSHOT_SIZE+sizeof(int)];
|
||||
int delta_size;
|
||||
|
||||
/* write tickmarker */
|
||||
demorec_record_write_tickmarker(tick, 0);
|
||||
|
||||
delta_size = snapshot_create_delta((SNAPSHOT*)record_lastsnapshotdata, (SNAPSHOT*)data, &delta_data);
|
||||
if(delta_size)
|
||||
{
|
||||
/* record delta */
|
||||
demorec_record_write(CHUNKTYPE_DELTA, delta_data, delta_size);
|
||||
mem_copy(record_lastsnapshotdata, data, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void demorec_record_message(const void *data, int size)
|
||||
{
|
||||
demorec_record_write(CHUNKTYPE_MESSAGE, data, size);
|
||||
}
|
||||
|
||||
int demorec_record_stop()
|
||||
{
|
||||
if(!record_file)
|
||||
return -1;
|
||||
|
||||
dbg_msg("demorec/record", "Stopped recording");
|
||||
io_close(record_file);
|
||||
record_file = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Playback */
|
||||
typedef struct KEYFRAME
|
||||
{
|
||||
long filepos;
|
||||
int tick;
|
||||
} KEYFRAME;
|
||||
|
||||
typedef struct KEYFRAME_SEARCH
|
||||
{
|
||||
KEYFRAME frame;
|
||||
struct KEYFRAME_SEARCH *next;
|
||||
} KEYFRAME_SEARCH;
|
||||
|
||||
static IOHANDLE play_file = 0;
|
||||
static DEMOREC_PLAYCALLBACK play_callback_snapshot = 0;
|
||||
static DEMOREC_PLAYCALLBACK play_callback_message = 0;
|
||||
static KEYFRAME *keyframes = 0;
|
||||
|
||||
static DEMOREC_PLAYBACKINFO playbackinfo;
|
||||
static unsigned char playback_lastsnapshotdata[MAX_SNAPSHOT_SIZE];
|
||||
static int playback_lastsnapshotdata_size = -1;
|
||||
|
||||
|
||||
const DEMOREC_PLAYBACKINFO *demorec_playback_info() { return &playbackinfo; }
|
||||
int demorec_isplaying() { return play_file != 0; }
|
||||
|
||||
int demorec_playback_registercallbacks(DEMOREC_PLAYCALLBACK snapshot_cb, DEMOREC_PLAYCALLBACK message_cb)
|
||||
{
|
||||
play_callback_snapshot = snapshot_cb;
|
||||
play_callback_message = message_cb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_chunk_header(int *type, int *size, int *tick)
|
||||
{
|
||||
unsigned char chunk = 0;
|
||||
|
||||
*size = 0;
|
||||
*type = 0;
|
||||
|
||||
if(io_read(play_file, &chunk, sizeof(chunk)) != sizeof(chunk))
|
||||
return -1;
|
||||
|
||||
if(chunk&CHUNKTYPEFLAG_TICKMARKER)
|
||||
{
|
||||
/* decode tick marker */
|
||||
int tickdelta = chunk&(CHUNKMASK_TICK);
|
||||
*type = chunk&(CHUNKTYPEFLAG_TICKMARKER|CHUNKTICKFLAG_KEYFRAME);
|
||||
|
||||
if(tickdelta == 0)
|
||||
{
|
||||
unsigned char tickdata[4];
|
||||
if(io_read(play_file, tickdata, sizeof(tickdata)) != sizeof(tickdata))
|
||||
return -1;
|
||||
*tick = (tickdata[0]<<24) | (tickdata[1]<<16) | (tickdata[2]<<8) | tickdata[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
*tick += tickdelta;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* decode normal chunk */
|
||||
*type = (chunk&CHUNKMASK_TYPE)>>5;
|
||||
*size = chunk&CHUNKMASK_SIZE;
|
||||
|
||||
if(*size == 30)
|
||||
{
|
||||
unsigned char sizedata[1];
|
||||
if(io_read(play_file, sizedata, sizeof(sizedata)) != sizeof(sizedata))
|
||||
return -1;
|
||||
*size = sizedata[0];
|
||||
|
||||
}
|
||||
else if(*size == 31)
|
||||
{
|
||||
unsigned char sizedata[2];
|
||||
if(io_read(play_file, sizedata, sizeof(sizedata)) != sizeof(sizedata))
|
||||
return -1;
|
||||
*size = (sizedata[1]<<8) | sizedata[0];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void scan_file()
|
||||
{
|
||||
long start_pos;
|
||||
HEAP *heap = 0;
|
||||
KEYFRAME_SEARCH *first_key = 0;
|
||||
KEYFRAME_SEARCH *current_key = 0;
|
||||
/*DEMOREC_CHUNK chunk;*/
|
||||
int chunk_size, chunk_type, chunk_tick = 0;
|
||||
int i;
|
||||
|
||||
heap = memheap_create();
|
||||
|
||||
start_pos = io_tell(play_file);
|
||||
playbackinfo.seekable_points = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
long current_pos = io_tell(play_file);
|
||||
|
||||
if(read_chunk_header(&chunk_type, &chunk_size, &chunk_tick))
|
||||
break;
|
||||
|
||||
/* read the chunk */
|
||||
if(chunk_type&CHUNKTYPEFLAG_TICKMARKER)
|
||||
{
|
||||
if(chunk_type&CHUNKTICKFLAG_KEYFRAME)
|
||||
{
|
||||
KEYFRAME_SEARCH *key;
|
||||
|
||||
/* save the position */
|
||||
key = (KEYFRAME_SEARCH*)memheap_allocate(heap, sizeof(KEYFRAME_SEARCH));
|
||||
key->frame.filepos = current_pos;
|
||||
key->frame.tick = chunk_tick;
|
||||
key->next = 0;
|
||||
if(current_key)
|
||||
current_key->next = key;
|
||||
if(!first_key)
|
||||
first_key = key;
|
||||
current_key = key;
|
||||
playbackinfo.seekable_points++;
|
||||
}
|
||||
|
||||
if(playbackinfo.first_tick == -1)
|
||||
playbackinfo.first_tick = chunk_tick;
|
||||
playbackinfo.last_tick = chunk_tick;
|
||||
}
|
||||
else if(chunk_size)
|
||||
io_skip(play_file, chunk_size);
|
||||
|
||||
}
|
||||
|
||||
/* copy all the frames to an array instead for fast access */
|
||||
keyframes = (KEYFRAME*)mem_alloc(playbackinfo.seekable_points*sizeof(KEYFRAME), 1);
|
||||
for(current_key = first_key, i = 0; current_key; current_key = current_key->next, i++)
|
||||
keyframes[i] = current_key->frame;
|
||||
|
||||
/* destroy the temporary heap and seek back to the start */
|
||||
memheap_destroy(heap);
|
||||
io_seek(play_file, start_pos, IOSEEK_START);
|
||||
}
|
||||
|
||||
static void do_tick()
|
||||
{
|
||||
static char compresseddata[MAX_SNAPSHOT_SIZE];
|
||||
static char decompressed[MAX_SNAPSHOT_SIZE];
|
||||
static char data[MAX_SNAPSHOT_SIZE];
|
||||
int chunk_size, chunk_type, chunk_tick;
|
||||
int data_size;
|
||||
int got_snapshot = 0;
|
||||
|
||||
/* update ticks */
|
||||
playbackinfo.previous_tick = playbackinfo.current_tick;
|
||||
playbackinfo.current_tick = playbackinfo.next_tick;
|
||||
chunk_tick = playbackinfo.current_tick;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(read_chunk_header(&chunk_type, &chunk_size, &chunk_tick))
|
||||
{
|
||||
/* stop on error or eof */
|
||||
dbg_msg("demorec", "end of file");
|
||||
demorec_playback_pause();
|
||||
break;
|
||||
}
|
||||
|
||||
/* read the chunk */
|
||||
if(chunk_size)
|
||||
{
|
||||
if(io_read(play_file, compresseddata, chunk_size) != chunk_size)
|
||||
{
|
||||
/* stop on error or eof */
|
||||
dbg_msg("demorec", "error reading chunk");
|
||||
demorec_playback_stop();
|
||||
break;
|
||||
}
|
||||
|
||||
data_size = netcommon_decompress(compresseddata, chunk_size, decompressed, sizeof(decompressed));
|
||||
if(data_size < 0)
|
||||
{
|
||||
/* stop on error or eof */
|
||||
dbg_msg("demorec", "error during network decompression");
|
||||
demorec_playback_stop();
|
||||
break;
|
||||
}
|
||||
|
||||
data_size = intpack_decompress(decompressed, data_size, data);
|
||||
|
||||
if(data_size < 0)
|
||||
{
|
||||
dbg_msg("demorec", "error during intpack decompression");
|
||||
demorec_playback_stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(chunk_type == CHUNKTYPE_DELTA)
|
||||
{
|
||||
/* process delta snapshot */
|
||||
static char newsnap[MAX_SNAPSHOT_SIZE];
|
||||
|
||||
got_snapshot = 1;
|
||||
|
||||
data_size = snapshot_unpack_delta((SNAPSHOT*)playback_lastsnapshotdata, (SNAPSHOT*)newsnap, data, data_size);
|
||||
|
||||
if(data_size >= 0)
|
||||
{
|
||||
if(play_callback_snapshot)
|
||||
play_callback_snapshot(newsnap, data_size);
|
||||
|
||||
playback_lastsnapshotdata_size = data_size;
|
||||
mem_copy(playback_lastsnapshotdata, newsnap, data_size);
|
||||
}
|
||||
else
|
||||
dbg_msg("demorec", "error duing unpacking of delta, err=%d", data_size);
|
||||
}
|
||||
else if(chunk_type == CHUNKTYPE_SNAPSHOT)
|
||||
{
|
||||
/* process full snapshot */
|
||||
got_snapshot = 1;
|
||||
|
||||
playback_lastsnapshotdata_size = data_size;
|
||||
mem_copy(playback_lastsnapshotdata, data, data_size);
|
||||
if(play_callback_snapshot)
|
||||
play_callback_snapshot(data, data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if there were no snapshots in this tick, replay the last one */
|
||||
if(!got_snapshot && play_callback_snapshot && playback_lastsnapshotdata_size != -1)
|
||||
{
|
||||
got_snapshot = 1;
|
||||
play_callback_snapshot(playback_lastsnapshotdata, playback_lastsnapshotdata_size);
|
||||
}
|
||||
|
||||
/* check the remaining types */
|
||||
if(chunk_type&CHUNKTYPEFLAG_TICKMARKER)
|
||||
{
|
||||
playbackinfo.next_tick = chunk_tick;
|
||||
break;
|
||||
}
|
||||
else if(chunk_type == CHUNKTYPE_MESSAGE)
|
||||
{
|
||||
if(play_callback_message)
|
||||
play_callback_message(data, data_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void demorec_playback_pause()
|
||||
{
|
||||
playbackinfo.paused = 1;
|
||||
}
|
||||
|
||||
void demorec_playback_unpause()
|
||||
{
|
||||
if(playbackinfo.paused)
|
||||
{
|
||||
/*playbackinfo.start_tick = playbackinfo.current_tick;
|
||||
playbackinfo.start_time = time_get();*/
|
||||
playbackinfo.paused = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int demorec_playback_load(const char *filename)
|
||||
{
|
||||
play_file = engine_openfile(filename, IOFLAG_READ);
|
||||
if(!play_file)
|
||||
{
|
||||
dbg_msg("demorec/playback", "could not open '%s'", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear the playback info */
|
||||
mem_zero(&playbackinfo, sizeof(playbackinfo));
|
||||
playbackinfo.first_tick = -1;
|
||||
playbackinfo.last_tick = -1;
|
||||
/*playbackinfo.start_tick = -1;*/
|
||||
playbackinfo.next_tick = -1;
|
||||
playbackinfo.current_tick = -1;
|
||||
playbackinfo.previous_tick = -1;
|
||||
playbackinfo.speed = 1;
|
||||
|
||||
playback_lastsnapshotdata_size = -1;
|
||||
|
||||
/* read the header */
|
||||
io_read(play_file, &playbackinfo.header, sizeof(playbackinfo.header));
|
||||
if(mem_comp(playbackinfo.header.marker, header_marker, sizeof(header_marker)) != 0)
|
||||
{
|
||||
dbg_msg("demorec/playback", "'%s' is not a demo file", filename);
|
||||
io_close(play_file);
|
||||
play_file = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* scan the file for interessting points */
|
||||
scan_file();
|
||||
|
||||
/* ready for playback */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int demorec_playback_nextframe()
|
||||
{
|
||||
do_tick();
|
||||
return demorec_isplaying();
|
||||
}
|
||||
|
||||
int demorec_playback_play()
|
||||
{
|
||||
/* fill in previous and next tick */
|
||||
while(playbackinfo.previous_tick == -1 && demorec_isplaying())
|
||||
do_tick();
|
||||
|
||||
/* set start info */
|
||||
/*playbackinfo.start_tick = playbackinfo.previous_tick;
|
||||
playbackinfo.start_time = time_get();*/
|
||||
playbackinfo.current_time = playbackinfo.previous_tick*time_freq()/SERVER_TICK_SPEED;
|
||||
playbackinfo.last_update = time_get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int demorec_playback_set(float percent)
|
||||
{
|
||||
int keyframe;
|
||||
int wanted_tick;
|
||||
if(!play_file)
|
||||
return -1;
|
||||
|
||||
/* -5 because we have to have a current tick and previous tick when we do the playback */
|
||||
wanted_tick = playbackinfo.first_tick + (int)((playbackinfo.last_tick-playbackinfo.first_tick)*percent) - 5;
|
||||
|
||||
keyframe = (int)(playbackinfo.seekable_points*percent);
|
||||
|
||||
if(keyframe < 0 || keyframe >= playbackinfo.seekable_points)
|
||||
return -1;
|
||||
|
||||
/* get correct key frame */
|
||||
if(keyframes[keyframe].tick < wanted_tick)
|
||||
while(keyframe < playbackinfo.seekable_points-1 && keyframes[keyframe].tick < wanted_tick)
|
||||
keyframe++;
|
||||
|
||||
while(keyframe && keyframes[keyframe].tick > wanted_tick)
|
||||
keyframe--;
|
||||
|
||||
/* seek to the correct keyframe */
|
||||
io_seek(play_file, keyframes[keyframe].filepos, IOSEEK_START);
|
||||
|
||||
/*playbackinfo.start_tick = -1;*/
|
||||
playbackinfo.next_tick = -1;
|
||||
playbackinfo.current_tick = -1;
|
||||
playbackinfo.previous_tick = -1;
|
||||
|
||||
/* playback everything until we hit our tick */
|
||||
while(playbackinfo.previous_tick < wanted_tick)
|
||||
do_tick();
|
||||
|
||||
demorec_playback_play();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void demorec_playback_setspeed(float speed)
|
||||
{
|
||||
playbackinfo.speed = speed;
|
||||
}
|
||||
|
||||
int demorec_playback_update()
|
||||
{
|
||||
int64 now = time_get();
|
||||
int64 deltatime = now-playbackinfo.last_update;
|
||||
playbackinfo.last_update = now;
|
||||
|
||||
if(!demorec_isplaying())
|
||||
return 0;
|
||||
|
||||
if(playbackinfo.paused)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int64 freq = time_freq();
|
||||
playbackinfo.current_time += (int64)(deltatime*(double)playbackinfo.speed);
|
||||
|
||||
while(1)
|
||||
{
|
||||
int64 curtick_start = (playbackinfo.current_tick)*freq/SERVER_TICK_SPEED;
|
||||
|
||||
/* break if we are ready */
|
||||
if(curtick_start > playbackinfo.current_time)
|
||||
break;
|
||||
|
||||
/* do one more tick */
|
||||
do_tick();
|
||||
|
||||
if(playbackinfo.paused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* update intratick */
|
||||
{
|
||||
int64 curtick_start = (playbackinfo.current_tick)*freq/SERVER_TICK_SPEED;
|
||||
int64 prevtick_start = (playbackinfo.previous_tick)*freq/SERVER_TICK_SPEED;
|
||||
playbackinfo.intratick = (playbackinfo.current_time - prevtick_start) / (float)(curtick_start-prevtick_start);
|
||||
playbackinfo.ticktime = (playbackinfo.current_time - prevtick_start) / (float)freq;
|
||||
}
|
||||
|
||||
if(playbackinfo.current_tick == playbackinfo.previous_tick ||
|
||||
playbackinfo.current_tick == playbackinfo.next_tick)
|
||||
{
|
||||
dbg_msg("demorec/playback", "tick error prev=%d cur=%d next=%d",
|
||||
playbackinfo.previous_tick, playbackinfo.current_tick, playbackinfo.next_tick);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int demorec_playback_stop()
|
||||
{
|
||||
if(!play_file)
|
||||
return -1;
|
||||
|
||||
dbg_msg("demorec/playback", "Stopped playback");
|
||||
io_close(play_file);
|
||||
play_file = 0;
|
||||
mem_free(keyframes);
|
||||
keyframes = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef _DEMOREC_H
|
||||
#define _DEMOREC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
typedef struct DEMOREC_HEADER
|
||||
{
|
||||
char marker[8];
|
||||
char netversion[64];
|
||||
char map[64];
|
||||
unsigned char crc[4];
|
||||
char type[8];
|
||||
} DEMOREC_HEADER;
|
||||
|
||||
typedef struct DEMOREC_CHUNK
|
||||
{
|
||||
char type[2];
|
||||
unsigned short size;
|
||||
} DEMOREC_CHUNK;
|
||||
|
||||
typedef struct DEMOREC_TICKMARKER
|
||||
{
|
||||
int tick;
|
||||
} DEMOREC_TICKMARKER;
|
||||
|
||||
typedef struct DEMOREC_PLAYBACKINFO
|
||||
{
|
||||
DEMOREC_HEADER header;
|
||||
|
||||
int paused;
|
||||
float speed;
|
||||
|
||||
int64 last_update;
|
||||
int64 current_time;
|
||||
|
||||
int first_tick;
|
||||
int last_tick;
|
||||
|
||||
int seekable_points;
|
||||
|
||||
int next_tick;
|
||||
int current_tick;
|
||||
int previous_tick;
|
||||
|
||||
float intratick;
|
||||
float ticktime;
|
||||
} DEMOREC_PLAYBACKINFO;
|
||||
|
||||
int demorec_record_start(const char *filename, const char *netversion, const char *map, int map_crc, const char *type);
|
||||
int demorec_isrecording();
|
||||
void demorec_record_snapshot(int tick, const void *data, int size);
|
||||
void demorec_record_message(const void *data, int size);
|
||||
int demorec_record_stop();
|
||||
|
||||
typedef void (*DEMOREC_PLAYCALLBACK)(void *data, int size);
|
||||
|
||||
int demorec_playback_registercallbacks(DEMOREC_PLAYCALLBACK snapshot_cb, DEMOREC_PLAYCALLBACK message_cb);
|
||||
int demorec_playback_load(const char *filename);
|
||||
int demorec_playback_nextframe();
|
||||
int demorec_playback_play();
|
||||
void demorec_playback_pause();
|
||||
void demorec_playback_unpause();
|
||||
void demorec_playback_setspeed(float speed);
|
||||
int demorec_playback_set(float precent);
|
||||
int demorec_playback_update();
|
||||
const DEMOREC_PLAYBACKINFO *demorec_playback_info();
|
||||
int demorec_isplaying();
|
||||
int demorec_playback_stop();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,596 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <base/system.h>
|
||||
|
||||
#include <engine/e_server_interface.h>
|
||||
#include <engine/e_config.h>
|
||||
#include <engine/e_console.h>
|
||||
#include <engine/e_engine.h>
|
||||
#include <engine/e_network.h>
|
||||
#include "e_linereader.h"
|
||||
|
||||
/* compiled-in data-dir path */
|
||||
#define DATA_DIR "data"
|
||||
|
||||
static JOBPOOL hostlookuppool;
|
||||
static int engine_find_datadir(char *argv0);
|
||||
|
||||
static void con_dbg_dumpmem(void *result, void *user_data)
|
||||
{
|
||||
mem_debug_dump();
|
||||
}
|
||||
|
||||
static void con_dbg_lognetwork(void *result, void *user_data)
|
||||
{
|
||||
netcommon_openlog("network_sent.dat", "network_recv.dat");
|
||||
}
|
||||
|
||||
|
||||
static char application_save_path[512] = {0};
|
||||
static char datadir[512] = {0};
|
||||
|
||||
const char *engine_savepath(const char *filename, char *buffer, int max)
|
||||
{
|
||||
str_format(buffer, max, "%s/%s", application_save_path, filename);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void engine_init(const char *appname)
|
||||
{
|
||||
dbg_logger_stdout();
|
||||
dbg_logger_debugger();
|
||||
|
||||
/* */
|
||||
dbg_msg("engine", "running on %s-%s-%s", CONF_FAMILY_STRING, CONF_PLATFORM_STRING, CONF_ARCH_STRING);
|
||||
#ifdef CONF_ARCH_ENDIAN_LITTLE
|
||||
dbg_msg("engine", "arch is little endian");
|
||||
#elif defined(CONF_ARCH_ENDIAN_BIG)
|
||||
dbg_msg("engine", "arch is big endian");
|
||||
#else
|
||||
dbg_msg("engine", "unknown endian");
|
||||
#endif
|
||||
|
||||
/* init the network */
|
||||
net_init();
|
||||
netcommon_init();
|
||||
|
||||
/* create storage location */
|
||||
{
|
||||
char path[1024] = {0};
|
||||
fs_storage_path(appname, application_save_path, sizeof(application_save_path));
|
||||
if(fs_makedir(application_save_path) == 0)
|
||||
{
|
||||
str_format(path, sizeof(path), "%s/screenshots", application_save_path);
|
||||
fs_makedir(path);
|
||||
|
||||
str_format(path, sizeof(path), "%s/maps", application_save_path);
|
||||
fs_makedir(path);
|
||||
|
||||
str_format(path, sizeof(path), "%s/downloadedmaps", application_save_path);
|
||||
fs_makedir(path);
|
||||
|
||||
str_format(path, sizeof(path), "%s/demos", application_save_path);
|
||||
fs_makedir(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* init console and add the console logger */
|
||||
console_init();
|
||||
dbg_logger(console_print);
|
||||
|
||||
jobs_initpool(&hostlookuppool, 1);
|
||||
|
||||
MACRO_REGISTER_COMMAND("dbg_dumpmem", "", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_dbg_dumpmem, 0x0, "Dump the memory");
|
||||
MACRO_REGISTER_COMMAND("dbg_lognetwork", "", CFGFLAG_SERVER|CFGFLAG_CLIENT, con_dbg_lognetwork, 0x0, "Log the network");
|
||||
|
||||
/* reset the config */
|
||||
config_reset();
|
||||
}
|
||||
|
||||
|
||||
void engine_listdir(int types, const char *path, FS_LISTDIR_CALLBACK cb, void *user)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
/* list current directory */
|
||||
if(types&LISTDIRTYPE_CURRENT)
|
||||
{
|
||||
fs_listdir(path, cb, user);
|
||||
}
|
||||
|
||||
/* list users directory */
|
||||
if(types&LISTDIRTYPE_SAVE)
|
||||
{
|
||||
engine_savepath(path, buffer, sizeof(buffer));
|
||||
fs_listdir(buffer, cb, user);
|
||||
}
|
||||
|
||||
/* list datadir directory */
|
||||
if(types&LISTDIRTYPE_DATA)
|
||||
{
|
||||
str_format(buffer, sizeof(buffer), "%s/%s", datadir, path);
|
||||
fs_listdir(buffer, cb, user);
|
||||
}
|
||||
}
|
||||
|
||||
void engine_getpath(char *buffer, int buffer_size, const char *filename, int flags)
|
||||
{
|
||||
if(flags&IOFLAG_WRITE)
|
||||
engine_savepath(filename, buffer, buffer_size);
|
||||
else
|
||||
{
|
||||
IOHANDLE handle = 0;
|
||||
|
||||
/* check current directory */
|
||||
handle = io_open(filename, flags);
|
||||
if(handle)
|
||||
{
|
||||
str_copy(buffer, filename, buffer_size);
|
||||
io_close(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check user directory */
|
||||
engine_savepath(filename, buffer, buffer_size);
|
||||
handle = io_open(buffer, flags);
|
||||
if(handle)
|
||||
{
|
||||
io_close(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check normal data directory */
|
||||
str_format(buffer, buffer_size, "%s/%s", datadir, filename);
|
||||
handle = io_open(buffer, flags);
|
||||
if(handle)
|
||||
{
|
||||
io_close(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[0] = 0;
|
||||
}
|
||||
|
||||
IOHANDLE engine_openfile(const char *filename, int flags)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
if(flags&IOFLAG_WRITE)
|
||||
{
|
||||
engine_savepath(filename, buffer, sizeof(buffer));
|
||||
return io_open(buffer, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
IOHANDLE handle = 0;
|
||||
|
||||
/* check current directory */
|
||||
handle = io_open(filename, flags);
|
||||
if(handle)
|
||||
return handle;
|
||||
|
||||
/* check user directory */
|
||||
engine_savepath(filename, buffer, sizeof(buffer));
|
||||
handle = io_open(buffer, flags);
|
||||
if(handle)
|
||||
return handle;
|
||||
|
||||
/* check normal data directory */
|
||||
str_format(buffer, sizeof(buffer), "%s/%s", datadir, filename);
|
||||
handle = io_open(buffer, flags);
|
||||
if(handle)
|
||||
return handle;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void engine_parse_arguments(int argc, char **argv)
|
||||
{
|
||||
/* load the configuration */
|
||||
int i;
|
||||
|
||||
/* check for datadir override */
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
if(argv[i][0] == '-' && argv[i][1] == 'd' && argv[i][2] == 0 && argc - i > 1)
|
||||
{
|
||||
str_copy(datadir, argv[i+1], sizeof(datadir));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for data directory */
|
||||
engine_find_datadir(argv[0]);
|
||||
|
||||
dbg_msg("engine/datadir", "paths used:");
|
||||
dbg_msg("engine/datadir", "\t.");
|
||||
dbg_msg("engine/datadir", "\t%s", application_save_path);
|
||||
dbg_msg("engine/datadir", "\t%s", datadir);
|
||||
dbg_msg("engine/datadir", "saving files to: %s", application_save_path);
|
||||
|
||||
|
||||
/* check for scripts to execute */
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
if(argv[i][0] == '-' && argv[i][1] == 'f' && argv[i][2] == 0 && argc - i > 1)
|
||||
{
|
||||
console_execute_file(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* search arguments for overrides */
|
||||
{
|
||||
int i;
|
||||
for(i = 1; i < argc; i++)
|
||||
console_execute_line(argv[i]);
|
||||
}
|
||||
|
||||
console_execute_file("autoexec.cfg");
|
||||
|
||||
/* open logfile if needed */
|
||||
if(config.logfile[0])
|
||||
dbg_logger_file(config.logfile);
|
||||
|
||||
/* set default servers and load from disk*/
|
||||
mastersrv_default();
|
||||
mastersrv_load();
|
||||
}
|
||||
|
||||
|
||||
static IOHANDLE config_file = 0;
|
||||
|
||||
int engine_config_write_start()
|
||||
{
|
||||
config_save();
|
||||
config_file = engine_openfile("settings.cfg", IOFLAG_WRITE);
|
||||
if(config_file == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void engine_config_write_line(const char *line)
|
||||
{
|
||||
if(config_file)
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
static const char newline[] = "\r\n";
|
||||
#else
|
||||
static const char newline[] = "\n";
|
||||
#endif
|
||||
io_write(config_file, line, strlen(line));
|
||||
io_write(config_file, newline, sizeof(newline)-1);
|
||||
}
|
||||
}
|
||||
|
||||
void engine_config_write_stop()
|
||||
{
|
||||
io_close(config_file);
|
||||
config_file = 0;
|
||||
}
|
||||
/*
|
||||
void engine_writeconfig()
|
||||
{
|
||||
}*/
|
||||
|
||||
static int perf_tick = 1;
|
||||
static PERFORMACE_INFO *current = 0;
|
||||
|
||||
void perf_init()
|
||||
{
|
||||
}
|
||||
|
||||
void perf_next()
|
||||
{
|
||||
perf_tick++;
|
||||
current = 0;
|
||||
}
|
||||
|
||||
void perf_start(PERFORMACE_INFO *info)
|
||||
{
|
||||
if(info->tick != perf_tick)
|
||||
{
|
||||
info->parent = current;
|
||||
info->first_child = 0;
|
||||
info->next_child = 0;
|
||||
|
||||
if(info->parent)
|
||||
{
|
||||
info->next_child = info->parent->first_child;
|
||||
info->parent->first_child = info;
|
||||
}
|
||||
|
||||
info->tick = perf_tick;
|
||||
info->biggest = 0;
|
||||
info->total = 0;
|
||||
}
|
||||
|
||||
current = info;
|
||||
current->start = time_get();
|
||||
}
|
||||
|
||||
void perf_end()
|
||||
{
|
||||
if(!current)
|
||||
return;
|
||||
|
||||
current->last_delta = time_get()-current->start;
|
||||
current->total += current->last_delta;
|
||||
|
||||
if(current->last_delta > current->biggest)
|
||||
current->biggest = current->last_delta;
|
||||
|
||||
current = current->parent;
|
||||
}
|
||||
|
||||
static void perf_dump_imp(PERFORMACE_INFO *info, int indent)
|
||||
{
|
||||
char buf[512] = {0};
|
||||
int64 freq = time_freq();
|
||||
int i;
|
||||
|
||||
for(i = 0; i < indent; i++)
|
||||
buf[i] = ' ';
|
||||
|
||||
str_format(&buf[indent], sizeof(buf)-indent, "%-20s %8.2f %8.2f", info->name, info->total*1000/(float)freq, info->biggest*1000/(float)freq);
|
||||
dbg_msg("perf", "%s", buf);
|
||||
|
||||
info = info->first_child;
|
||||
while(info)
|
||||
{
|
||||
perf_dump_imp(info, indent+2);
|
||||
info = info->next_child;
|
||||
}
|
||||
}
|
||||
|
||||
void perf_dump(PERFORMACE_INFO *top)
|
||||
{
|
||||
perf_dump_imp(top, 0);
|
||||
}
|
||||
|
||||
/* master server functions */
|
||||
typedef struct
|
||||
{
|
||||
char hostname[128];
|
||||
NETADDR addr;
|
||||
|
||||
HOSTLOOKUP lookup;
|
||||
} MASTER_INFO;
|
||||
|
||||
static MASTER_INFO master_servers[MAX_MASTERSERVERS] = {{{0}}};
|
||||
static int needs_update = -1;
|
||||
|
||||
int mastersrv_refresh_addresses()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(needs_update != -1)
|
||||
return 0;
|
||||
|
||||
dbg_msg("engine/mastersrv", "refreshing master server addresses");
|
||||
|
||||
/* add lookup jobs */
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
engine_hostlookup(&master_servers[i].lookup, master_servers[i].hostname);
|
||||
|
||||
needs_update = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mastersrv_update()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* check if we need to update */
|
||||
if(needs_update != 1)
|
||||
return;
|
||||
needs_update = 0;
|
||||
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
{
|
||||
if(jobs_status(&master_servers[i].lookup.job) != JOBSTATUS_DONE)
|
||||
needs_update = 1;
|
||||
else
|
||||
{
|
||||
master_servers[i].addr = master_servers[i].lookup.addr;
|
||||
master_servers[i].addr.port = 8300;
|
||||
}
|
||||
}
|
||||
|
||||
if(!needs_update)
|
||||
{
|
||||
dbg_msg("engine/mastersrv", "saving addresses");
|
||||
mastersrv_save();
|
||||
}
|
||||
}
|
||||
|
||||
int mastersrv_refreshing()
|
||||
{
|
||||
return needs_update;
|
||||
}
|
||||
|
||||
NETADDR mastersrv_get(int index)
|
||||
{
|
||||
return master_servers[index].addr;
|
||||
}
|
||||
|
||||
const char *mastersrv_name(int index)
|
||||
{
|
||||
return master_servers[index].hostname;
|
||||
}
|
||||
|
||||
void mastersrv_dump_servers()
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
{
|
||||
dbg_msg("mastersrv", "#%d = %d.%d.%d.%d", i,
|
||||
master_servers[i].addr.ip[0], master_servers[i].addr.ip[1],
|
||||
master_servers[i].addr.ip[2], master_servers[i].addr.ip[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void mastersrv_default()
|
||||
{
|
||||
int i;
|
||||
mem_zero(master_servers, sizeof(master_servers));
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
sprintf(master_servers[i].hostname, "master%d.teeworlds.com", i+1);
|
||||
}
|
||||
|
||||
int mastersrv_load()
|
||||
{
|
||||
LINEREADER lr;
|
||||
IOHANDLE file;
|
||||
int count = 0;
|
||||
|
||||
/* try to open file */
|
||||
file = engine_openfile("masters.cfg", IOFLAG_READ);
|
||||
if(!file)
|
||||
return -1;
|
||||
|
||||
linereader_init(&lr, file);
|
||||
while(1)
|
||||
{
|
||||
MASTER_INFO info = {{0}};
|
||||
int ip[4];
|
||||
const char *line = linereader_get(&lr);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
/* parse line */
|
||||
if(sscanf(line, "%s %d.%d.%d.%d", info.hostname, &ip[0], &ip[1], &ip[2], &ip[3]) == 5)
|
||||
{
|
||||
info.addr.ip[0] = (unsigned char)ip[0];
|
||||
info.addr.ip[1] = (unsigned char)ip[1];
|
||||
info.addr.ip[2] = (unsigned char)ip[2];
|
||||
info.addr.ip[3] = (unsigned char)ip[3];
|
||||
info.addr.port = 8300;
|
||||
if(count != MAX_MASTERSERVERS)
|
||||
{
|
||||
master_servers[count] = info;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
dbg_msg("engine/mastersrv", "warning: skipped master server '%s' due to limit of %d", line, MAX_MASTERSERVERS);
|
||||
}
|
||||
else
|
||||
dbg_msg("engine/mastersrv", "warning: couldn't parse master server '%s'", line);
|
||||
}
|
||||
|
||||
io_close(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mastersrv_save()
|
||||
{
|
||||
IOHANDLE file;
|
||||
int i;
|
||||
|
||||
/* try to open file */
|
||||
file = engine_openfile("masters.cfg", IOFLAG_WRITE);
|
||||
if(!file)
|
||||
return -1;
|
||||
|
||||
for(i = 0; i < MAX_MASTERSERVERS; i++)
|
||||
{
|
||||
char buf[1024];
|
||||
str_format(buf, sizeof(buf), "%s %d.%d.%d.%d\n", master_servers[i].hostname,
|
||||
master_servers[i].addr.ip[0], master_servers[i].addr.ip[1],
|
||||
master_servers[i].addr.ip[2], master_servers[i].addr.ip[3]);
|
||||
|
||||
io_write(file, buf, strlen(buf));
|
||||
}
|
||||
|
||||
io_close(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int hostlookup_thread(void *user)
|
||||
{
|
||||
HOSTLOOKUP *lookup = (HOSTLOOKUP *)user;
|
||||
net_host_lookup(lookup->hostname, &lookup->addr, NETTYPE_IPV4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void engine_hostlookup(HOSTLOOKUP *lookup, const char *hostname)
|
||||
{
|
||||
str_copy(lookup->hostname, hostname, sizeof(lookup->hostname));
|
||||
jobs_add(&hostlookuppool, &lookup->job, hostlookup_thread, lookup);
|
||||
}
|
||||
|
||||
static int engine_find_datadir(char *argv0)
|
||||
{
|
||||
/* 1) use provided data-dir override */
|
||||
if(datadir[0])
|
||||
{
|
||||
if(fs_is_dir(datadir))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
dbg_msg("engine/datadir", "specified data-dir '%s' does not exist", datadir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2) use data-dir in PWD if present */
|
||||
if(fs_is_dir("data"))
|
||||
{
|
||||
strcpy(datadir, "data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 3) use compiled-in data-dir if present */
|
||||
if (fs_is_dir(DATA_DIR))
|
||||
{
|
||||
strcpy(datadir, DATA_DIR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 4) check for usable path in argv[0] */
|
||||
{
|
||||
unsigned int pos = strrchr(argv0, '/') - argv0;
|
||||
|
||||
if (pos < sizeof(datadir))
|
||||
{
|
||||
char basedir[sizeof(datadir)];
|
||||
strncpy(basedir, argv0, pos);
|
||||
basedir[pos] = '\0';
|
||||
str_format(datadir, sizeof(datadir), "%s/data", basedir);
|
||||
|
||||
if (fs_is_dir(datadir))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
/* 5) check for all default locations */
|
||||
{
|
||||
const char *sdirs[] = {
|
||||
"/usr/share/teeworlds",
|
||||
"/usr/local/share/teeworlds"
|
||||
"/opt/teeworlds"
|
||||
};
|
||||
const int sdirs_count = sizeof(sdirs) / sizeof(sdirs[0]);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < sdirs_count; i++)
|
||||
{
|
||||
if (fs_is_dir(sdirs[i]))
|
||||
{
|
||||
strcpy(datadir, sdirs[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* no data-dir found */
|
||||
dbg_msg("engine/datadir", "warning no data directory found");
|
||||
return -1;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#include "e_jobs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
const char *engine_savepath(const char *filename, char *buffer, int max);
|
||||
void engine_init(const char *appname);
|
||||
void engine_parse_arguments(int argc, char **argv);
|
||||
|
||||
int engine_config_write_start();
|
||||
void engine_config_write_line(const char *line);
|
||||
void engine_config_write_stop();
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
LISTDIRTYPE_SAVE=1,
|
||||
LISTDIRTYPE_CURRENT=2,
|
||||
LISTDIRTYPE_DATA=4,
|
||||
LISTDIRTYPE_ALL = ~0
|
||||
};
|
||||
|
||||
void engine_listdir(int types, const char *path, FS_LISTDIR_CALLBACK cb, void *user);
|
||||
IOHANDLE engine_openfile(const char *filename, int flags);
|
||||
void engine_getpath(char *buffer, int buffer_size, const char *filename, int flags);
|
||||
|
||||
int engine_stress(float probability);
|
||||
|
||||
typedef struct HOSTLOOKUP
|
||||
{
|
||||
JOB job;
|
||||
char hostname[128];
|
||||
NETADDR addr;
|
||||
} HOSTLOOKUP;
|
||||
|
||||
void engine_hostlookup(HOSTLOOKUP *lookup, const char *hostname);
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_MASTERSERVERS=4
|
||||
};
|
||||
|
||||
void mastersrv_default();
|
||||
int mastersrv_load();
|
||||
int mastersrv_save();
|
||||
|
||||
int mastersrv_refresh_addresses();
|
||||
void mastersrv_update();
|
||||
int mastersrv_refreshing();
|
||||
void mastersrv_dump_servers();
|
||||
NETADDR mastersrv_get(int index);
|
||||
const char *mastersrv_name(int index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,277 +0,0 @@
|
||||
#include <memory.h> /* memset */
|
||||
#include <string.h> /* memset */
|
||||
#include "e_huffman.h"
|
||||
|
||||
typedef struct HUFFMAN_CONSTRUCT_NODE
|
||||
{
|
||||
unsigned short node_id;
|
||||
int frequency;
|
||||
} HUFFMAN_CONSTRUCT_NODE;
|
||||
|
||||
static void huffman_setbits_r(HUFFMAN_STATE *huff, HUFFMAN_NODE *node, int bits, int depth)
|
||||
{
|
||||
if(node->leafs[1] != 0xffff)
|
||||
huffman_setbits_r(huff, &huff->nodes[node->leafs[1]], bits|(1<<depth), depth+1);
|
||||
if(node->leafs[0] != 0xffff)
|
||||
huffman_setbits_r(huff, &huff->nodes[node->leafs[0]], bits, depth+1);
|
||||
|
||||
if(node->num_bits)
|
||||
{
|
||||
node->bits = bits;
|
||||
node->num_bits = depth;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: this should be something faster, but it's enough for now */
|
||||
void bubblesort(HUFFMAN_CONSTRUCT_NODE **list, int size)
|
||||
{
|
||||
int i, changed = 1;
|
||||
HUFFMAN_CONSTRUCT_NODE *temp;
|
||||
|
||||
while(changed)
|
||||
{
|
||||
changed = 0;
|
||||
for(i = 0; i < size-1; i++)
|
||||
{
|
||||
if(list[i]->frequency < list[i+1]->frequency)
|
||||
{
|
||||
temp = list[i];
|
||||
list[i] = list[i+1];
|
||||
list[i+1] = temp;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void huffman_construct_tree(HUFFMAN_STATE *huff, const unsigned *frequencies)
|
||||
{
|
||||
HUFFMAN_CONSTRUCT_NODE nodes_left_storage[HUFFMAN_MAX_SYMBOLS];
|
||||
HUFFMAN_CONSTRUCT_NODE *nodes_left[HUFFMAN_MAX_SYMBOLS];
|
||||
int num_nodes_left = HUFFMAN_MAX_SYMBOLS;
|
||||
int i;
|
||||
|
||||
/* add the symbols */
|
||||
for(i = 0; i < HUFFMAN_MAX_SYMBOLS; i++)
|
||||
{
|
||||
huff->nodes[i].num_bits = -1;
|
||||
huff->nodes[i].symbol = i;
|
||||
huff->nodes[i].leafs[0] = -1;
|
||||
huff->nodes[i].leafs[1] = -1;
|
||||
|
||||
if(i == HUFFMAN_EOF_SYMBOL)
|
||||
nodes_left_storage[i].frequency = 1;
|
||||
else
|
||||
nodes_left_storage[i].frequency = frequencies[i];
|
||||
nodes_left_storage[i].node_id = i;
|
||||
nodes_left[i] = &nodes_left_storage[i];
|
||||
|
||||
}
|
||||
huff->num_nodes = HUFFMAN_MAX_SYMBOLS;
|
||||
|
||||
/* construct the table */
|
||||
while(num_nodes_left > 1)
|
||||
{
|
||||
/* we can't rely on stdlib's qsort for this, it can generate different results on different implementations */
|
||||
bubblesort(nodes_left, num_nodes_left);
|
||||
|
||||
huff->nodes[huff->num_nodes].num_bits = 0;
|
||||
huff->nodes[huff->num_nodes].leafs[0] = nodes_left[num_nodes_left-1]->node_id;
|
||||
huff->nodes[huff->num_nodes].leafs[1] = nodes_left[num_nodes_left-2]->node_id;
|
||||
nodes_left[num_nodes_left-2]->node_id = huff->num_nodes;
|
||||
nodes_left[num_nodes_left-2]->frequency = nodes_left[num_nodes_left-1]->frequency + nodes_left[num_nodes_left-2]->frequency;
|
||||
|
||||
huff->num_nodes++;
|
||||
num_nodes_left--;
|
||||
}
|
||||
|
||||
/* set start node */
|
||||
huff->start_node = &huff->nodes[huff->num_nodes-1];
|
||||
|
||||
/* build symbol bits */
|
||||
huffman_setbits_r(huff, huff->start_node, 0, 0);
|
||||
}
|
||||
|
||||
void huffman_init(HUFFMAN_STATE *huff, const unsigned *frequencies)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* make sure to cleanout every thing */
|
||||
memset(huff, 0, sizeof(HUFFMAN_STATE));
|
||||
|
||||
/* construct the tree */
|
||||
huffman_construct_tree(huff, frequencies);
|
||||
|
||||
/* build decode LUT */
|
||||
for(i = 0; i < HUFFMAN_LUTSIZE; i++)
|
||||
{
|
||||
unsigned bits = i;
|
||||
int k;
|
||||
HUFFMAN_NODE *node = huff->start_node;
|
||||
for(k = 0; k < HUFFMAN_LUTBITS; k++)
|
||||
{
|
||||
node = &huff->nodes[node->leafs[bits&1]];
|
||||
bits >>= 1;
|
||||
|
||||
if(!node)
|
||||
break;
|
||||
|
||||
if(node->num_bits)
|
||||
{
|
||||
huff->decode_lut[i] = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(k == HUFFMAN_LUTBITS)
|
||||
huff->decode_lut[i] = node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
int huffman_compress(HUFFMAN_STATE *huff, const void *input, int input_size, void *output, int output_size)
|
||||
{
|
||||
/* this macro loads a symbol for a byte into bits and bitcount */
|
||||
#define HUFFMAN_MACRO_LOADSYMBOL(sym) \
|
||||
bits |= huff->nodes[sym].bits << bitcount; \
|
||||
bitcount += huff->nodes[sym].num_bits;
|
||||
|
||||
/* this macro writes the symbol stored in bits and bitcount to the dst pointer */
|
||||
#define HUFFMAN_MACRO_WRITE() \
|
||||
while(bitcount >= 8) \
|
||||
{ \
|
||||
*dst++ = (unsigned char)(bits&0xff); \
|
||||
if(dst == dst_end) \
|
||||
return -1; \
|
||||
bits >>= 8; \
|
||||
bitcount -= 8; \
|
||||
}
|
||||
|
||||
/* setup buffer pointers */
|
||||
const unsigned char *src = (const unsigned char *)input;
|
||||
const unsigned char *src_end = src + input_size;
|
||||
unsigned char *dst = (unsigned char *)output;
|
||||
unsigned char *dst_end = dst + output_size;
|
||||
|
||||
/* symbol variables */
|
||||
unsigned bits = 0;
|
||||
unsigned bitcount = 0;
|
||||
|
||||
/* make sure that we have data that we want to compress */
|
||||
if(input_size)
|
||||
{
|
||||
/* {A} load the first symbol */
|
||||
int symbol = *src++;
|
||||
|
||||
while(src != src_end)
|
||||
{
|
||||
/* {B} load the symbol */
|
||||
HUFFMAN_MACRO_LOADSYMBOL(symbol)
|
||||
|
||||
/* {C} fetch next symbol, this is done here because it will reduce dependency in the code */
|
||||
symbol = *src++;
|
||||
|
||||
/* {B} write the symbol loaded at */
|
||||
HUFFMAN_MACRO_WRITE()
|
||||
}
|
||||
|
||||
/* write the last symbol loaded from {C} or {A} in the case of only 1 byte input buffer */
|
||||
HUFFMAN_MACRO_LOADSYMBOL(symbol)
|
||||
HUFFMAN_MACRO_WRITE()
|
||||
}
|
||||
|
||||
/* write EOF symbol */
|
||||
HUFFMAN_MACRO_LOADSYMBOL(HUFFMAN_EOF_SYMBOL)
|
||||
HUFFMAN_MACRO_WRITE()
|
||||
|
||||
/* write out the last bits */
|
||||
*dst++ = bits;
|
||||
|
||||
/* return the size of the output */
|
||||
return (int)(dst - (const unsigned char *)output);
|
||||
|
||||
/* remove macros */
|
||||
#undef HUFFMAN_MACRO_LOADSYMBOL
|
||||
#undef HUFFMAN_MACRO_WRITE
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
int huffman_decompress(HUFFMAN_STATE *huff, const void *input, int input_size, void *output, int output_size)
|
||||
{
|
||||
/* setup buffer pointers */
|
||||
unsigned char *dst = (unsigned char *)output;
|
||||
unsigned char *src = (unsigned char *)input;
|
||||
unsigned char *dst_end = dst + output_size;
|
||||
unsigned char *src_end = src + input_size;
|
||||
|
||||
unsigned bits = 0;
|
||||
unsigned bitcount = 0;
|
||||
|
||||
HUFFMAN_NODE *eof = &huff->nodes[HUFFMAN_EOF_SYMBOL];
|
||||
HUFFMAN_NODE *node = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* {A} try to load a node now, this will reduce dependency at location {D} */
|
||||
node = 0;
|
||||
if(bitcount >= HUFFMAN_LUTBITS)
|
||||
node = huff->decode_lut[bits&HUFFMAN_LUTMASK];
|
||||
|
||||
/* {B} fill with new bits */
|
||||
while(bitcount < 24 && src != src_end)
|
||||
{
|
||||
bits |= (*src++) << bitcount;
|
||||
bitcount += 8;
|
||||
}
|
||||
|
||||
/* {C} load symbol now if we didn't that earlier at location {A} */
|
||||
if(!node)
|
||||
node = huff->decode_lut[bits&HUFFMAN_LUTMASK];
|
||||
|
||||
/* {D} check if we hit a symbol already */
|
||||
if(node->num_bits)
|
||||
{
|
||||
/* remove the bits for that symbol */
|
||||
bits >>= node->num_bits;
|
||||
bitcount -= node->num_bits;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove the bits that the lut checked up for us */
|
||||
bits >>= HUFFMAN_LUTBITS;
|
||||
bitcount -= HUFFMAN_LUTBITS;
|
||||
|
||||
/* walk the tree bit by bit */
|
||||
while(1)
|
||||
{
|
||||
/* traverse tree */
|
||||
node = &huff->nodes[node->leafs[bits&1]];
|
||||
|
||||
/* remove bit */
|
||||
bitcount--;
|
||||
bits >>= 1;
|
||||
|
||||
/* check if we hit a symbol */
|
||||
if(node->num_bits)
|
||||
break;
|
||||
|
||||
/* no more bits, decoding error */
|
||||
if(bitcount == 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for eof */
|
||||
if(node == eof)
|
||||
break;
|
||||
|
||||
/* output character */
|
||||
if(dst == dst_end)
|
||||
return -1;
|
||||
*dst++ = node->symbol;
|
||||
}
|
||||
|
||||
/* return the size of the decompressed buffer */
|
||||
return (int)(dst - (const unsigned char *)output);
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
#ifndef __HUFFMAN_HEADER__
|
||||
#define __HUFFMAN_HEADER__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
HUFFMAN_EOF_SYMBOL = 256,
|
||||
|
||||
HUFFMAN_MAX_SYMBOLS=HUFFMAN_EOF_SYMBOL+1,
|
||||
HUFFMAN_MAX_NODES=HUFFMAN_MAX_SYMBOLS*2-1,
|
||||
|
||||
HUFFMAN_LUTBITS = 10,
|
||||
HUFFMAN_LUTSIZE = (1<<HUFFMAN_LUTBITS),
|
||||
HUFFMAN_LUTMASK = (HUFFMAN_LUTSIZE-1)
|
||||
};
|
||||
|
||||
typedef struct HUFFMAN_NODE
|
||||
{
|
||||
/* symbol */
|
||||
unsigned bits;
|
||||
unsigned num_bits;
|
||||
|
||||
/* don't use pointers for this. shorts are smaller so we can fit more data into the cache */
|
||||
unsigned short leafs[2];
|
||||
|
||||
/* what the symbol represents */
|
||||
unsigned char symbol;
|
||||
} HUFFMAN_NODE;
|
||||
|
||||
typedef struct HUFFMAN_STATE
|
||||
{
|
||||
HUFFMAN_NODE nodes[HUFFMAN_MAX_NODES];
|
||||
HUFFMAN_NODE *decode_lut[HUFFMAN_LUTSIZE];
|
||||
HUFFMAN_NODE *start_node;
|
||||
int num_nodes;
|
||||
} HUFFMAN_STATE;
|
||||
|
||||
/*
|
||||
Function: huffman_init
|
||||
Inits the compressor/decompressor.
|
||||
|
||||
Parameters:
|
||||
huff - Pointer to the state to init
|
||||
frequencies - A pointer to an array of 256 entries of the frequencies of the bytes
|
||||
|
||||
Remarks:
|
||||
- Does no allocation what so ever.
|
||||
- You don't have to call any cleanup functions when you are done with it
|
||||
*/
|
||||
void huffman_init(HUFFMAN_STATE *huff, const unsigned *frequencies);
|
||||
|
||||
/*
|
||||
Function: huffman_compress
|
||||
Compresses a buffer and outputs a compressed buffer.
|
||||
|
||||
Parameters:
|
||||
huff - Pointer to the huffman state
|
||||
input - Buffer to compress
|
||||
input_size - Size of the buffer to compress
|
||||
output - Buffer to put the compressed data into
|
||||
output_size - Size of the output buffer
|
||||
|
||||
Returns:
|
||||
Returns the size of the compressed data. Negative value on failure.
|
||||
*/
|
||||
int huffman_compress(HUFFMAN_STATE *huff, const void *input, int input_size, void *output, int output_size);
|
||||
|
||||
/*
|
||||
Function: huffman_decompress
|
||||
Decompresses a buffer
|
||||
|
||||
Parameters:
|
||||
huff - Pointer to the huffman state
|
||||
input - Buffer to decompress
|
||||
input_size - Size of the buffer to decompress
|
||||
output - Buffer to put the uncompressed data into
|
||||
output_size - Size of the output buffer
|
||||
|
||||
Returns:
|
||||
Returns the size of the uncompressed data. Negative value on failure.
|
||||
*/
|
||||
int huffman_decompress(HUFFMAN_STATE *huff, const void *input, int input_size, void *output, int output_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __HUFFMAN_HEADER__ */
|
||||
@@ -1,579 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_CLIENT_H
|
||||
#define ENGINE_IF_CLIENT_H
|
||||
|
||||
/*
|
||||
Title: Client Interface
|
||||
*/
|
||||
|
||||
/*
|
||||
Section: Constants
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
/* Constants: Client States
|
||||
CLIENTSTATE_OFFLINE - The client is offline.
|
||||
CLIENTSTATE_CONNECTING - The client is trying to connect to a server.
|
||||
CLIENTSTATE_LOADING - The client has connected to a server and is loading resources.
|
||||
CLIENTSTATE_ONLINE - The client is connected to a server and running the game.
|
||||
CLIENTSTATE_DEMOPLAYBACK - The client is playing a demo
|
||||
CLIENTSTATE_QUITING - The client is quiting.
|
||||
*/
|
||||
CLIENTSTATE_OFFLINE=0,
|
||||
CLIENTSTATE_CONNECTING,
|
||||
CLIENTSTATE_LOADING,
|
||||
CLIENTSTATE_ONLINE,
|
||||
CLIENTSTATE_DEMOPLAYBACK,
|
||||
CLIENTSTATE_QUITING,
|
||||
|
||||
/* Constants: Image Formats
|
||||
IMG_AUTO - Lets the engine choose the format.
|
||||
IMG_RGB - 8-Bit uncompressed RGB
|
||||
IMG_RGBA - 8-Bit uncompressed RGBA
|
||||
IMG_ALPHA - 8-Bit uncompressed alpha
|
||||
*/
|
||||
IMG_AUTO=-1,
|
||||
IMG_RGB=0,
|
||||
IMG_RGBA=1,
|
||||
IMG_ALPHA=2,
|
||||
|
||||
/* Constants: Texture Loading Flags
|
||||
TEXLOAD_NORESAMPLE - Prevents the texture from any resampling
|
||||
*/
|
||||
TEXLOAD_NORESAMPLE=1,
|
||||
|
||||
/* Constants: Server Browser Sorting
|
||||
BROWSESORT_NAME - Sort by name.
|
||||
BROWSESORT_PING - Sort by ping.
|
||||
BROWSESORT_MAP - Sort by map
|
||||
BROWSESORT_GAMETYPE - Sort by game type. DM, TDM etc.
|
||||
BROWSESORT_PROGRESSION - Sort by progression.
|
||||
BROWSESORT_NUMPLAYERS - Sort after how many players there are on the server.
|
||||
*/
|
||||
BROWSESORT_NAME = 0,
|
||||
BROWSESORT_PING,
|
||||
BROWSESORT_MAP,
|
||||
BROWSESORT_GAMETYPE,
|
||||
BROWSESORT_PROGRESSION,
|
||||
BROWSESORT_NUMPLAYERS,
|
||||
|
||||
BROWSEQUICK_SERVERNAME=1,
|
||||
BROWSEQUICK_PLAYERNAME=2,
|
||||
BROWSEQUICK_MAPNAME=4,
|
||||
|
||||
BROWSETYPE_INTERNET = 0,
|
||||
BROWSETYPE_LAN = 1,
|
||||
BROWSETYPE_FAVORITES = 2
|
||||
};
|
||||
|
||||
/*
|
||||
Section: Structures
|
||||
*/
|
||||
|
||||
/*
|
||||
Structure: SERVER_INFO_PLAYER
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[48];
|
||||
int score;
|
||||
} SERVER_INFO_PLAYER;
|
||||
|
||||
/*
|
||||
Structure: SERVER_INFO
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int sorted_index;
|
||||
int server_index;
|
||||
|
||||
NETADDR netaddr;
|
||||
|
||||
int quicksearch_hit;
|
||||
|
||||
int progression;
|
||||
int max_players;
|
||||
int num_players;
|
||||
int flags;
|
||||
int favorite;
|
||||
int latency; /* in ms */
|
||||
char gametype[16];
|
||||
char name[64];
|
||||
char map[32];
|
||||
char version[32];
|
||||
char address[24];
|
||||
SERVER_INFO_PLAYER players[16];
|
||||
} SERVER_INFO;
|
||||
|
||||
/*
|
||||
Section: Functions
|
||||
*/
|
||||
|
||||
/**********************************************************************************
|
||||
Group: Time
|
||||
**********************************************************************************/
|
||||
/*
|
||||
Function: client_tick
|
||||
Returns the tick of the current snapshot.
|
||||
*/
|
||||
int client_tick();
|
||||
|
||||
/*
|
||||
Function: client_prevtick
|
||||
Returns the tick of the previous snapshot.
|
||||
*/
|
||||
int client_prevtick();
|
||||
|
||||
/*
|
||||
Function: client_intratick
|
||||
Returns the current intratick.
|
||||
|
||||
Remarks:
|
||||
The intratick is how far gone the time is from the previous snapshot to the current.
|
||||
0.0 means that it on the previous snapshot. 0.5 means that it's halfway to the current,
|
||||
and 1.0 means that it is on the current snapshot. It can go beyond 1.0 which means that
|
||||
the client has started to extrapolate due to lack of data from the server.
|
||||
|
||||
See Also:
|
||||
<client_tick>
|
||||
*/
|
||||
float client_intratick();
|
||||
|
||||
/*
|
||||
Function: client_predtick
|
||||
Returns the current predicted tick.
|
||||
*/
|
||||
int client_predtick();
|
||||
|
||||
/*
|
||||
Function: client_predintratick
|
||||
Returns the current preticted intra tick.
|
||||
|
||||
Remarks:
|
||||
This is the same as <client_intratick> but for the current predicted tick and
|
||||
previous predicted tick.
|
||||
|
||||
See Also:
|
||||
<client_intratick>
|
||||
*/
|
||||
float client_predintratick();
|
||||
|
||||
/*
|
||||
Function: client_ticktime
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
float client_ticktime();
|
||||
|
||||
/*
|
||||
Function: client_tickspeed
|
||||
Returns how many ticks per second the client is doing.
|
||||
|
||||
Remarks:
|
||||
This will be the same as the server tick speed.
|
||||
*/
|
||||
int client_tickspeed();
|
||||
|
||||
/*
|
||||
Function: client_frametime
|
||||
Returns how long time the last frame took to process.
|
||||
*/
|
||||
float client_frametime();
|
||||
|
||||
/*
|
||||
Function: client_localtime
|
||||
Returns the clients local time.
|
||||
|
||||
Remarks:
|
||||
The local time is set to 0 when the client starts and when
|
||||
it connects to a server. Can be used for client side effects.
|
||||
*/
|
||||
float client_localtime();
|
||||
|
||||
/**********************************************************************************
|
||||
Group: Server Browser
|
||||
**********************************************************************************/
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_refresh
|
||||
Issues a refresh of the server browser.
|
||||
|
||||
Arguments:
|
||||
type - What type of servers to browse, internet, lan or favorites.
|
||||
|
||||
Remarks:
|
||||
This will cause a broadcast on the local network if the lan argument is set.
|
||||
Otherwise it call ask all the master servers for their servers lists.
|
||||
*/
|
||||
void client_serverbrowse_refresh(int type);
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_sorted_get
|
||||
Returns server info from the sorted list.
|
||||
|
||||
Arguments:
|
||||
index - Zero based index into the sorted list.
|
||||
|
||||
See Also:
|
||||
<client_serverbrowse_sorted_num>
|
||||
*/
|
||||
SERVER_INFO *client_serverbrowse_sorted_get(int index);
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_sorted_num
|
||||
Returns how many servers there are in the sorted list.
|
||||
|
||||
See Also:
|
||||
<client_serverbrowse_sorted_get>
|
||||
*/
|
||||
int client_serverbrowse_sorted_num();
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_get
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
SERVER_INFO *client_serverbrowse_get(int index);
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_num
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_serverbrowse_num();
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_num_requests
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_serverbrowse_num_requests();
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_update
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void client_serverbrowse_update();
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_lan
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_serverbrowse_lan();
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_isfavorite
|
||||
Asks the server browser is a netaddr is in the favorite list
|
||||
|
||||
Arguments:
|
||||
addr - Address of the server to ask about.
|
||||
|
||||
Returns:
|
||||
Returns zero if it's not in the list, non-zero if it is.
|
||||
*/
|
||||
int client_serverbrowse_isfavorite(NETADDR addr);
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_addfavorite
|
||||
Adds a server to the favorite list
|
||||
|
||||
Arguments:
|
||||
addr - Address of the favorite server.
|
||||
*/
|
||||
void client_serverbrowse_addfavorite(NETADDR addr);
|
||||
|
||||
/*
|
||||
Function: client_serverbrowse_removefavorite
|
||||
Removes a server to the favorite list
|
||||
|
||||
Arguments:
|
||||
addr - Address of the favorite server.
|
||||
*/
|
||||
void client_serverbrowse_removefavorite(NETADDR addr);
|
||||
|
||||
/**********************************************************************************
|
||||
Group: Actions
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
Function: client_connect
|
||||
Connects to a server at the specified address.
|
||||
|
||||
Arguments:
|
||||
address - Address of the server to connect to.
|
||||
|
||||
See Also:
|
||||
<client_disconnect>
|
||||
*/
|
||||
void client_connect(const char *address);
|
||||
|
||||
/*
|
||||
Function: client_disconnect
|
||||
Disconnects from the current server.
|
||||
|
||||
Remarks:
|
||||
Does nothing if not connected to a server.
|
||||
|
||||
See Also:
|
||||
<client_connect, client_quit>
|
||||
*/
|
||||
void client_disconnect();
|
||||
|
||||
/*
|
||||
Function: client_quit
|
||||
Tells to client to shutdown.
|
||||
|
||||
See Also:
|
||||
<client_disconnect>
|
||||
*/
|
||||
void client_quit();
|
||||
|
||||
void client_entergame();
|
||||
|
||||
/*
|
||||
Function: client_rcon
|
||||
Sends a command to the server to execute on it's console.
|
||||
|
||||
Arguments:
|
||||
cmd - The command to send.
|
||||
|
||||
Remarks:
|
||||
The client must have the correct rcon password to connect.
|
||||
|
||||
See Also:
|
||||
<client_rcon_auth, client_rcon_authed>
|
||||
*/
|
||||
void client_rcon(const char *cmd);
|
||||
|
||||
/*
|
||||
Function: client_rcon_auth
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<client_rcon, client_rcon_authed>
|
||||
*/
|
||||
void client_rcon_auth(const char *name, const char *password);
|
||||
|
||||
/*
|
||||
Function: client_rcon_authed
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<client_rcon, client_rcon_auth>
|
||||
*/
|
||||
int client_rcon_authed();
|
||||
|
||||
/**********************************************************************************
|
||||
Group: Other
|
||||
**********************************************************************************/
|
||||
/*
|
||||
Function: client_latestversion
|
||||
Returns 0 if there's no version difference
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *client_latestversion();
|
||||
|
||||
/*
|
||||
Function: client_get_input
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int *client_get_input(int tick);
|
||||
|
||||
/*
|
||||
Function: client_direct_input
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void client_direct_input(int *input, int size);
|
||||
|
||||
/*
|
||||
Function: client_error_string
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *client_error_string();
|
||||
|
||||
/*
|
||||
Function: client_connection_problems
|
||||
Returns 1 if the client is connection problems.
|
||||
|
||||
Remarks:
|
||||
Connections problems usually means that the client havn't recvived any data
|
||||
from the server in a while.
|
||||
*/
|
||||
int client_connection_problems();
|
||||
|
||||
/*
|
||||
Function: client_state
|
||||
Returns the state of the client.
|
||||
|
||||
See Also:
|
||||
<Client States>
|
||||
*/
|
||||
int client_state();
|
||||
|
||||
/*
|
||||
Function: client_mapdownload_amount
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_mapdownload_amount();
|
||||
|
||||
/*
|
||||
Function: client_mapdownload_totalsize
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_mapdownload_totalsize();
|
||||
|
||||
/*
|
||||
Function: client_save_line
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void client_save_line(const char *line);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
BROWSESET_MASTER_ADD=1,
|
||||
BROWSESET_FAV_ADD,
|
||||
BROWSESET_TOKEN,
|
||||
BROWSESET_OLD_INTERNET,
|
||||
BROWSESET_OLD_LAN
|
||||
};
|
||||
|
||||
void client_serverbrowse_set(NETADDR *addr, int type, int token, SERVER_INFO *info);
|
||||
|
||||
int client_serverbrowse_refreshingmasters();
|
||||
|
||||
|
||||
typedef struct DEMOPLAYBACK_INFO
|
||||
{
|
||||
int first_tick;
|
||||
int last_tick;
|
||||
int current_tick;
|
||||
int paused;
|
||||
float speed;
|
||||
} DEMOPLAYBACK_INFO;
|
||||
|
||||
void client_demoplayer_play(const char *filename);
|
||||
const DEMOPLAYBACK_INFO *client_demoplayer_getinfo();
|
||||
void client_demoplayer_setpos(float percent);
|
||||
void client_demoplayer_setpause(int paused);
|
||||
void client_demoplayer_setspeed(float speed);
|
||||
const char *client_user_directory();
|
||||
void client_serverinfo(SERVER_INFO *serverinfo);
|
||||
void client_serverinfo_request();
|
||||
void client_serverbrowse_request(NETADDR *addr);
|
||||
#endif
|
||||
@@ -1,673 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_GFX_H
|
||||
#define ENGINE_IF_GFX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Title: Graphics
|
||||
*/
|
||||
|
||||
/*
|
||||
Section: Structures
|
||||
*/
|
||||
|
||||
/*
|
||||
Structure: IMAGE_INFO
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/* Variable: width
|
||||
Contains the width of the image */
|
||||
int width;
|
||||
|
||||
/* Variable: height
|
||||
Contains the height of the image */
|
||||
int height;
|
||||
|
||||
/* Variable: format
|
||||
Contains the format of the image. See <Image Formats> for more information. */
|
||||
int format;
|
||||
|
||||
/* Variable: data
|
||||
Pointer to the image data. */
|
||||
void *data;
|
||||
} IMAGE_INFO;
|
||||
|
||||
/*
|
||||
Structure: VIDEO_MODE
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int width, height;
|
||||
int red, green, blue;
|
||||
} VIDEO_MODE;
|
||||
|
||||
/*
|
||||
Section: Functions
|
||||
*/
|
||||
|
||||
/*
|
||||
Group: Quads
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: gfx_quads_begin
|
||||
Begins a quad drawing session.
|
||||
|
||||
Remarks:
|
||||
This functions resets the rotation, color and subset.
|
||||
End the session by using <gfx_quads_end>.
|
||||
You can't change texture or blending mode during a session.
|
||||
|
||||
See Also:
|
||||
<gfx_quads_end>
|
||||
*/
|
||||
void gfx_quads_begin();
|
||||
|
||||
/*
|
||||
Function: gfx_quads_end
|
||||
Ends a quad session.
|
||||
|
||||
See Also:
|
||||
<gfx_quads_begin>
|
||||
*/
|
||||
void gfx_quads_end();
|
||||
|
||||
/*
|
||||
Function: gfx_quads_setrotation
|
||||
Sets the rotation to use when drawing a quad.
|
||||
|
||||
Arguments:
|
||||
angle - Angle in radians.
|
||||
|
||||
Remarks:
|
||||
The angle is reset when <gfx_quads_begin> is called.
|
||||
*/
|
||||
void gfx_quads_setrotation(float angle);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_setsubset
|
||||
Sets the uv coordinates to use.
|
||||
|
||||
Arguments:
|
||||
tl_u - Top-left U value.
|
||||
tl_v - Top-left V value.
|
||||
br_u - Bottom-right U value.
|
||||
br_v - Bottom-right V value.
|
||||
|
||||
Remarks:
|
||||
O,0 is top-left of the texture and 1,1 is bottom-right.
|
||||
The color is reset when <gfx_quads_begin> is called.
|
||||
*/
|
||||
void gfx_quads_setsubset(float tl_u, float tl_v, float br_u, float br_v);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_setsubset_free
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_quads_setsubset_free(
|
||||
float x0, float y0,
|
||||
float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_drawTL
|
||||
Draws a quad by specifying the top-left point.
|
||||
|
||||
Arguments:
|
||||
x - X coordinate of the top-left corner.
|
||||
y - Y coordinate of the top-left corner.
|
||||
width - Width of the quad.
|
||||
height - Height of the quad.
|
||||
|
||||
Remarks:
|
||||
Rotation still occurs from the center of the quad.
|
||||
You must call <gfx_quads_begin> before calling this function.
|
||||
|
||||
See Also:
|
||||
<gfx_quads_draw, gfx_quads_draw_freeform>
|
||||
*/
|
||||
void gfx_quads_drawTL(float x, float y, float width, float height);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_draw
|
||||
Draws a quad by specifying the center point.
|
||||
|
||||
Arguments:
|
||||
x - X coordinate of the center.
|
||||
y - Y coordinate of the center.
|
||||
width - Width of the quad.
|
||||
height - Height of the quad.
|
||||
|
||||
Remarks:
|
||||
You must call <gfx_quads_begin> before calling this function.
|
||||
|
||||
See Also:
|
||||
<gfx_quads_drawTL, gfx_quads_draw_freeform>
|
||||
*/
|
||||
void gfx_quads_draw(float x, float y, float w, float h);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_draw_freeform
|
||||
Draws a quad by specifying the corner points.
|
||||
|
||||
Arguments:
|
||||
x0, y0 - Coordinates of the upper left corner.
|
||||
x1, y1 - Coordinates of the upper right corner.
|
||||
x2, y2 - Coordinates of the lower left corner. // TODO: DOUBLE CHECK!!!
|
||||
x3, y3 - Coordinates of the lower right corner. // TODO: DOUBLE CHECK!!!
|
||||
|
||||
See Also:
|
||||
<gfx_quads_draw, gfx_quads_drawTL>
|
||||
*/
|
||||
void gfx_quads_draw_freeform(
|
||||
float x0, float y0,
|
||||
float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3);
|
||||
|
||||
/*
|
||||
Function: gfx_quads_text
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_quads_text(float x, float y, float size, float r, float g, float b, float a, const char *text);
|
||||
|
||||
/*
|
||||
Group: Lines
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: gfx_lines_begin
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_lines_begin();
|
||||
|
||||
/*
|
||||
Function: gfx_lines_draw
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_lines_draw(float x0, float y0, float x1, float y1);
|
||||
|
||||
/*
|
||||
Function: gfx_minimize
|
||||
Minimizes the window.
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_minimize();
|
||||
|
||||
/*
|
||||
Function: gfx_minimize
|
||||
Maximizes the window.
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_maximize();
|
||||
|
||||
/*
|
||||
Function: gfx_lines_end
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_lines_end();
|
||||
|
||||
/*
|
||||
Group: Text
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Function: gfx_text
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
returns the number of lines written
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_text(void *font, float x, float y, float size, const char *text, int max_width);
|
||||
|
||||
/*
|
||||
Function: gfx_text_width
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
float gfx_text_width(void *font, float size, const char *text, int length);
|
||||
|
||||
/*
|
||||
Function: gfx_text_color
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_text_color(float r, float g, float b, float a);
|
||||
|
||||
/*
|
||||
Function: gfx_text_set_default_font
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_text_set_default_font(void *font);
|
||||
|
||||
/*
|
||||
Group: Other
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: gfx_get_video_modes
|
||||
Fetches a list of all the available video modes.
|
||||
|
||||
Arguments:
|
||||
list - An array to recive the modes. Must be able to contain maxcount number of modes.
|
||||
maxcount - The maximum number of modes to fetch.
|
||||
|
||||
Returns:
|
||||
The number of video modes that was fetched.
|
||||
*/
|
||||
int gfx_get_video_modes(VIDEO_MODE *list, int maxcount);
|
||||
|
||||
/* image loaders */
|
||||
|
||||
/*
|
||||
Function: gfx_load_png
|
||||
Loads a PNG image from disk.
|
||||
|
||||
Arguments:
|
||||
img - Pointer to an structure to be filled out with the image information.
|
||||
filename - Filename of the image to load.
|
||||
|
||||
Returns:
|
||||
Returns non-zero on success and zero on error.
|
||||
|
||||
Remarks:
|
||||
The caller are responsible for cleaning up the allocated memory in the IMAGE_INFO structure.
|
||||
|
||||
See Also:
|
||||
<gfx_load_texture>
|
||||
*/
|
||||
int gfx_load_png(IMAGE_INFO *img, const char *filename);
|
||||
|
||||
/* textures */
|
||||
/*
|
||||
Function: gfx_load_texture
|
||||
Loads a texture from a file. TGA and PNG supported.
|
||||
|
||||
Arguments:
|
||||
filename - Null terminated string to the file to load.
|
||||
store_format - What format to store on gfx card as.
|
||||
flags - controls how the texture is uploaded
|
||||
|
||||
Returns:
|
||||
An ID to the texture. -1 on failure.
|
||||
|
||||
See Also:
|
||||
<gfx_unload_texture, gfx_load_png>
|
||||
*/
|
||||
int gfx_load_texture(const char *filename, int store_format, int flags);
|
||||
|
||||
/*
|
||||
Function: gfx_load_texture_raw
|
||||
Loads a texture from memory.
|
||||
|
||||
Arguments:
|
||||
w - Width of the texture.
|
||||
h - Height of the texture.
|
||||
data - Pointer to the pixel data.
|
||||
format - Format of the pixel data.
|
||||
store_format - The format to store the texture on the graphics card.
|
||||
flags - controls how the texture is uploaded
|
||||
|
||||
Returns:
|
||||
An ID to the texture. -1 on failure.
|
||||
|
||||
Remarks:
|
||||
The pixel data should be in RGBA format with 8 bit per component.
|
||||
So the total size of the data should be w*h*4.
|
||||
|
||||
See Also:
|
||||
<gfx_unload_texture>
|
||||
*/
|
||||
int gfx_load_texture_raw(int w, int h, int format, const void *data, int store_format, int flags);
|
||||
|
||||
/*
|
||||
Function: gfx_texture_set
|
||||
Sets the active texture.
|
||||
|
||||
Arguments:
|
||||
id - ID to the texture to set.
|
||||
*/
|
||||
void gfx_texture_set(int id);
|
||||
|
||||
/*
|
||||
Function: gfx_unload_texture
|
||||
Unloads a texture.
|
||||
|
||||
Arguments:
|
||||
id - ID to the texture to unload.
|
||||
|
||||
See Also:
|
||||
<gfx_load_texture_tga>, <gfx_load_texture_raw>
|
||||
|
||||
Remarks:
|
||||
NOT IMPLEMENTED
|
||||
*/
|
||||
int gfx_unload_texture(int id);
|
||||
|
||||
/*
|
||||
Function: gfx_clear
|
||||
Clears the screen with the specified color.
|
||||
|
||||
Arguments:
|
||||
r - Red component.
|
||||
g - Green component.
|
||||
b - Red component.
|
||||
|
||||
Remarks:
|
||||
The value of the components are given in 0.0 - 1.0 ranges.
|
||||
*/
|
||||
void gfx_clear(float r, float g, float b);
|
||||
|
||||
/*
|
||||
Function: gfx_screenaspect
|
||||
Returns the aspect ratio between width and height.
|
||||
|
||||
See Also:
|
||||
<gfx_screenwidth>, <gfx_screenheight>
|
||||
*/
|
||||
float gfx_screenaspect();
|
||||
|
||||
/*
|
||||
Function: gfx_screenwidth
|
||||
Returns the screen width.
|
||||
|
||||
See Also:
|
||||
<gfx_screenheight>
|
||||
*/
|
||||
int gfx_screenwidth();
|
||||
|
||||
/*
|
||||
Function: gfx_screenheight
|
||||
Returns the screen height.
|
||||
|
||||
See Also:
|
||||
<gfx_screenwidth>
|
||||
*/
|
||||
int gfx_screenheight();
|
||||
|
||||
/*
|
||||
Function: gfx_mapscreen
|
||||
Specifies the coordinate system for the screen.
|
||||
|
||||
Arguments:
|
||||
tl_x - Top-left X
|
||||
tl_y - Top-left Y
|
||||
br_x - Bottom-right X
|
||||
br_y - Bottom-right y
|
||||
*/
|
||||
void gfx_mapscreen(float tl_x, float tl_y, float br_x, float br_y);
|
||||
|
||||
/*
|
||||
Function: gfx_blend_normal
|
||||
Set the active blending mode to normal (src, 1-src).
|
||||
|
||||
Remarks:
|
||||
This must be used before calling <gfx_quads_begin>.
|
||||
This is equal to glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
|
||||
|
||||
See Also:
|
||||
<gfx_blend_additive,gfx_blend_none>
|
||||
*/
|
||||
void gfx_blend_normal();
|
||||
|
||||
/*
|
||||
Function: gfx_blend_additive
|
||||
Set the active blending mode to additive (src, one).
|
||||
|
||||
Remarks:
|
||||
This must be used before calling <gfx_quads_begin>.
|
||||
This is equal to glBlendFunc(GL_SRC_ALPHA, GL_ONE).
|
||||
|
||||
See Also:
|
||||
<gfx_blend_normal,gfx_blend_none>
|
||||
*/
|
||||
void gfx_blend_additive();
|
||||
|
||||
/*
|
||||
Function: gfx_blend_none
|
||||
Disables blending
|
||||
|
||||
Remarks:
|
||||
This must be used before calling <gfx_quads_begin>.
|
||||
|
||||
See Also:
|
||||
<gfx_blend_normal,gfx_blend_additive>
|
||||
*/
|
||||
void gfx_blend_none();
|
||||
|
||||
|
||||
/*
|
||||
Function: gfx_setcolorvertex
|
||||
Sets the color of a vertex.
|
||||
|
||||
Arguments:
|
||||
i - Index to the vertex.
|
||||
r - Red value.
|
||||
g - Green value.
|
||||
b - Blue value.
|
||||
a - Alpha value.
|
||||
|
||||
Remarks:
|
||||
The color values are from 0.0 to 1.0.
|
||||
The color is reset when <gfx_quads_begin> is called.
|
||||
*/
|
||||
void gfx_setcolorvertex(int i, float r, float g, float b, float a);
|
||||
|
||||
/*
|
||||
Function: gfx_setcolor
|
||||
Sets the color of all the vertices.
|
||||
|
||||
Arguments:
|
||||
r - Red value.
|
||||
g - Green value.
|
||||
b - Blue value.
|
||||
a - Alpha value.
|
||||
|
||||
Remarks:
|
||||
The color values are from 0.0 to 1.0.
|
||||
The color is reset when <gfx_quads_begin> is called.
|
||||
*/
|
||||
void gfx_setcolor(float r, float g, float b, float a);
|
||||
|
||||
/*
|
||||
Function: gfx_getscreen
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_getscreen(float *tl_x, float *tl_y, float *br_x, float *br_y);
|
||||
|
||||
/*
|
||||
Function: gfx_memory_usage
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int gfx_memory_usage();
|
||||
|
||||
/*
|
||||
Function: gfx_screenshot
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
filename - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_screenshot();
|
||||
|
||||
/*
|
||||
Function: gfx_screenshot_direct
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
filename - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_screenshot_direct(const char *filename);
|
||||
|
||||
/*
|
||||
Function: gfx_clip_enable
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_clip_enable(int x, int y, int w, int h);
|
||||
|
||||
/*
|
||||
Function: gfx_clip_disable
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void gfx_clip_disable();
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
TEXTFLAG_RENDER=1,
|
||||
TEXTFLAG_ALLOW_NEWLINE=2,
|
||||
TEXTFLAG_STOP_AT_END=4
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
int line_count;
|
||||
int charcount;
|
||||
|
||||
float start_x;
|
||||
float start_y;
|
||||
float line_width;
|
||||
float x, y;
|
||||
void *font_set;
|
||||
float font_size;
|
||||
} TEXT_CURSOR;
|
||||
|
||||
void gfx_text_set_cursor(TEXT_CURSOR *cursor, float x, float y, float font_size, int flags);
|
||||
void gfx_text_ex(TEXT_CURSOR *cursor, const char *text, int length);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,255 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_INP_H
|
||||
#define ENGINE_IF_INP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Section: Input
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Structure: INPUT_EVENT
|
||||
*/
|
||||
enum
|
||||
{
|
||||
INPFLAG_PRESS=1,
|
||||
INPFLAG_RELEASE=2,
|
||||
INPFLAG_REPEAT=4
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
unsigned char ch;
|
||||
int key;
|
||||
} INPUT_EVENT;
|
||||
|
||||
/*
|
||||
Function: inp_mouse_relative
|
||||
Fetches the mouse movements.
|
||||
|
||||
Arguments:
|
||||
x - Pointer to the variable that should get the X movement.
|
||||
y - Pointer to the variable that should get the Y movement.
|
||||
*/
|
||||
void inp_mouse_relative(int *x, int *y);
|
||||
|
||||
void inp_mouse_absolute(int *x, int *y);
|
||||
|
||||
/*
|
||||
Function: inp_mouse_scroll
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_mouse_scroll();
|
||||
|
||||
/*
|
||||
Function: inp_key_pressed
|
||||
Checks if a key is pressed.
|
||||
|
||||
Arguments:
|
||||
key - Index to the key to check
|
||||
|
||||
Returns:
|
||||
Returns 1 if the button is pressed, otherwise 0.
|
||||
|
||||
Remarks:
|
||||
Check keys.h for the keys.
|
||||
*/
|
||||
int inp_key_pressed(int key);
|
||||
|
||||
|
||||
/* input */
|
||||
/*
|
||||
Function: inp_key_was_pressed
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_was_pressed(int key);
|
||||
|
||||
/*
|
||||
Function: inp_key_down
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_down(int key);
|
||||
|
||||
|
||||
/*
|
||||
Function: inp_num_events
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_num_events();
|
||||
|
||||
/*
|
||||
Function: inp_get_event
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
INPUT_EVENT inp_get_event(int index);
|
||||
|
||||
/*
|
||||
Function: inp_clear_events
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void inp_clear_events();
|
||||
|
||||
/*
|
||||
Function: inp_mouse_doubleclick
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_mouse_doubleclick();
|
||||
|
||||
/*
|
||||
Function: inp_key_presses
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_presses(int key);
|
||||
|
||||
/*
|
||||
Function: inp_key_releases
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_releases(int key);
|
||||
|
||||
/*
|
||||
Function: inp_key_state
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_state(int key);
|
||||
|
||||
/*
|
||||
Function: inp_key_name
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *inp_key_name(int k);
|
||||
|
||||
/*
|
||||
Function: inp_key_code
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int inp_key_code(const char *key_name);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Function: inp_clear_key_states
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void inp_clear_key_states();
|
||||
|
||||
void inp_update();
|
||||
void inp_init();
|
||||
void inp_mouse_mode_absolute();
|
||||
void inp_mouse_mode_relative();
|
||||
void inp_warp_mouse(int x, int y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,153 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_MODC_H
|
||||
#define ENGINE_IF_MODC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**********************************************************************************
|
||||
Section: Client Hooks
|
||||
*********************************************************************************/
|
||||
/*
|
||||
Function: modc_console_init
|
||||
TODO
|
||||
*/
|
||||
void modc_console_init();
|
||||
|
||||
/*
|
||||
Function: modc_rcon_line
|
||||
TODO
|
||||
*/
|
||||
void modc_rcon_line(const char *line);
|
||||
|
||||
/*
|
||||
Function: modc_save_config
|
||||
TODO
|
||||
*/
|
||||
void modc_save_config();
|
||||
|
||||
/*
|
||||
Function: modc_init
|
||||
Called when the client starts.
|
||||
|
||||
Remarks:
|
||||
The game should load resources that are used during the entire
|
||||
time of the game. No map is loaded.
|
||||
*/
|
||||
void modc_init();
|
||||
|
||||
/*
|
||||
Function: modc_newsnapshot
|
||||
Called when the client progressed to a new snapshot.
|
||||
|
||||
Remarks:
|
||||
The client can check for items in the snapshot and perform one time
|
||||
events like playing sounds, spawning client side effects etc.
|
||||
*/
|
||||
void modc_newsnapshot();
|
||||
|
||||
/*
|
||||
Function: modc_entergame
|
||||
Called when the client has successfully connect to a server and
|
||||
loaded a map.
|
||||
|
||||
Remarks:
|
||||
The client can check for items in the map and load them.
|
||||
*/
|
||||
void modc_entergame();
|
||||
|
||||
/*
|
||||
Function: modc_shutdown
|
||||
Called when the client closes down.
|
||||
*/
|
||||
void modc_shutdown();
|
||||
|
||||
/*
|
||||
Function: modc_render
|
||||
Called every frame to let the game render it self.
|
||||
*/
|
||||
void modc_render();
|
||||
|
||||
/*
|
||||
Function: modc_statechange
|
||||
Called every time client changes state.
|
||||
*/
|
||||
void modc_statechange(int new_state, int old_state);
|
||||
|
||||
/* undocumented callbacks */
|
||||
/*
|
||||
Function: modc_connected
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void modc_connected();
|
||||
|
||||
/*
|
||||
Function: modc_message
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void modc_message(int msg);
|
||||
|
||||
/*
|
||||
Function: modc_predict
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void modc_predict();
|
||||
|
||||
/*
|
||||
Function: modc_snap_input
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int modc_snap_input(int *data);
|
||||
|
||||
/*
|
||||
Function: modc_net_version
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *modc_net_version();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,176 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_MOD_H
|
||||
#define ENGINE_IF_MOD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**********************************************************************************
|
||||
Section: Server Hooks
|
||||
**********************************************************************************/
|
||||
/*
|
||||
Function: mods_console_init
|
||||
TODO
|
||||
*/
|
||||
void mods_console_init();
|
||||
|
||||
/*
|
||||
Function: mods_init
|
||||
Called when the server is started.
|
||||
|
||||
Remarks:
|
||||
It's called after the map is loaded so all map items are available.
|
||||
*/
|
||||
void mods_init();
|
||||
|
||||
/*
|
||||
Function: mods_shutdown
|
||||
Called when the server quits.
|
||||
|
||||
Remarks:
|
||||
Should be used to clean up all resources used.
|
||||
*/
|
||||
void mods_shutdown();
|
||||
|
||||
/*
|
||||
Function: mods_client_enter
|
||||
Called when a client has joined the game.
|
||||
|
||||
Arguments:
|
||||
cid - Client ID. Is 0 - MAX_CLIENTS.
|
||||
|
||||
Remarks:
|
||||
It's called when the client is finished loading and should enter gameplay.
|
||||
*/
|
||||
void mods_client_enter(int cid);
|
||||
|
||||
/*
|
||||
Function: mods_client_drop
|
||||
Called when a client drops from the server.
|
||||
|
||||
Arguments:
|
||||
cid - Client ID. Is 0 - MAX_CLIENTS
|
||||
*/
|
||||
void mods_client_drop(int cid);
|
||||
|
||||
/*
|
||||
Function: mods_client_direct_input
|
||||
Called when the server recives new input from a client.
|
||||
|
||||
Arguments:
|
||||
cid - Client ID. Is 0 - MAX_CLIENTS.
|
||||
input - Pointer to the input data.
|
||||
size - Size of the data. (NOT IMPLEMENTED YET)
|
||||
*/
|
||||
void mods_client_direct_input(int cid, void *input);
|
||||
|
||||
/*
|
||||
Function: mods_client_predicted_input
|
||||
Called when the server applys the predicted input on the client.
|
||||
|
||||
Arguments:
|
||||
cid - Client ID. Is 0 - MAX_CLIENTS.
|
||||
input - Pointer to the input data.
|
||||
size - Size of the data. (NOT IMPLEMENTED YET)
|
||||
*/
|
||||
void mods_client_predicted_input(int cid, void *input);
|
||||
|
||||
|
||||
/*
|
||||
Function: mods_tick
|
||||
Called with a regular interval to progress the gameplay.
|
||||
|
||||
Remarks:
|
||||
The SERVER_TICK_SPEED tells the number of ticks per second.
|
||||
*/
|
||||
void mods_tick();
|
||||
|
||||
/*
|
||||
Function: mods_presnap
|
||||
Called before the server starts to construct snapshots for the clients.
|
||||
*/
|
||||
void mods_presnap();
|
||||
|
||||
/*
|
||||
Function: mods_snap
|
||||
Called to create the snapshot for a client.
|
||||
|
||||
Arguments:
|
||||
cid - Client ID. Is 0 - MAX_CLIENTS.
|
||||
|
||||
Remarks:
|
||||
The game should make a series of calls to <snap_new_item> to construct
|
||||
the snapshot for the client.
|
||||
*/
|
||||
void mods_snap(int cid);
|
||||
|
||||
/*
|
||||
Function: mods_postsnap
|
||||
Called after the server is done sending the snapshots.
|
||||
*/
|
||||
void mods_postsnap();
|
||||
|
||||
|
||||
/*
|
||||
Function: mods_connected
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void mods_connected(int client_id);
|
||||
|
||||
|
||||
/*
|
||||
Function: mods_net_version
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *mods_net_version();
|
||||
|
||||
/*
|
||||
Function: mods_version
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *mods_version();
|
||||
|
||||
/*
|
||||
Function: mods_message
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void mods_message(int msg, int client_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,158 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_MSG_H
|
||||
#define ENGINE_IF_MSG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Section: Messaging
|
||||
*/
|
||||
|
||||
void msg_pack_start_system(int msg, int flags);
|
||||
|
||||
/*
|
||||
Function: msg_pack_start
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void msg_pack_start(int msg, int flags);
|
||||
|
||||
/*
|
||||
Function: msg_pack_int
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void msg_pack_int(int i);
|
||||
|
||||
/*
|
||||
Function: msg_pack_string
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void msg_pack_string(const char *p, int limit);
|
||||
|
||||
/*
|
||||
Function: msg_pack_raw
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void msg_pack_raw(const void *data, int size);
|
||||
|
||||
/*
|
||||
Function: msg_pack_end
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void msg_pack_end();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int msg;
|
||||
int flags;
|
||||
const unsigned char *data;
|
||||
int size;
|
||||
} MSG_INFO;
|
||||
|
||||
const MSG_INFO *msg_get_info();
|
||||
|
||||
/* message unpacking */
|
||||
int msg_unpack_start(const void *data, int data_size, int *is_system);
|
||||
|
||||
/*
|
||||
Function: msg_unpack_int
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int msg_unpack_int();
|
||||
|
||||
/*
|
||||
Function: msg_unpack_string
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *msg_unpack_string();
|
||||
|
||||
/*
|
||||
Function: msg_unpack_raw
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const unsigned char *msg_unpack_raw(int size);
|
||||
|
||||
/*
|
||||
Function: msg_unpack_error
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int msg_unpack_error();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,392 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_OTHER_H
|
||||
#define ENGINE_IF_OTHER_H
|
||||
|
||||
/*
|
||||
Title: Engine Interface
|
||||
*/
|
||||
|
||||
#include <base/system.h>
|
||||
#include "e_keys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
SERVER_TICK_SPEED=50,
|
||||
MAX_CLIENTS=16,
|
||||
|
||||
SNAP_CURRENT=0,
|
||||
SNAP_PREV=1,
|
||||
|
||||
MASK_NONE=0,
|
||||
MASK_SET,
|
||||
MASK_ZERO,
|
||||
|
||||
SNDFLAG_LOOP=1,
|
||||
SNDFLAG_POS=2,
|
||||
SNDFLAG_ALL=3,
|
||||
|
||||
MAX_NAME_LENGTH=32
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SRVFLAG_PASSWORD = 0x1,
|
||||
};
|
||||
|
||||
/*
|
||||
Structure: SNAP_ITEM
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int id;
|
||||
int datasize;
|
||||
} SNAP_ITEM;
|
||||
|
||||
/*
|
||||
Structure: CLIENT_INFO
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
int latency;
|
||||
} CLIENT_INFO;
|
||||
|
||||
typedef struct PERFORMACE_INFO_t
|
||||
{
|
||||
const char *name;
|
||||
struct PERFORMACE_INFO_t *parent;
|
||||
struct PERFORMACE_INFO_t *first_child;
|
||||
struct PERFORMACE_INFO_t *next_child;
|
||||
int tick;
|
||||
int64 start;
|
||||
int64 total;
|
||||
int64 biggest;
|
||||
int64 last_delta;
|
||||
} PERFORMACE_INFO;
|
||||
|
||||
void perf_init();
|
||||
void perf_next();
|
||||
void perf_start(PERFORMACE_INFO *info);
|
||||
void perf_end();
|
||||
void perf_dump(PERFORMACE_INFO *top);
|
||||
|
||||
int gfx_init();
|
||||
void gfx_shutdown();
|
||||
void gfx_swap();
|
||||
int gfx_window_active();
|
||||
int gfx_window_open();
|
||||
|
||||
void gfx_set_vsync(int val);
|
||||
|
||||
int snd_init();
|
||||
int snd_shutdown();
|
||||
int snd_update();
|
||||
|
||||
int map_load(const char *mapname);
|
||||
void map_unload();
|
||||
|
||||
void map_set(void *m);
|
||||
|
||||
/*
|
||||
#include "e_if_client.h"
|
||||
#include "e_if_server.h"
|
||||
#include "e_if_snd.h"
|
||||
#include "e_if_gfx.h"
|
||||
#include "e_if_inp.h"
|
||||
#include "e_if_msg.h"
|
||||
#include "e_if_mod.h"*/
|
||||
|
||||
/*
|
||||
Section: Map
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: map_is_loaded
|
||||
Checks if a map is loaded.
|
||||
|
||||
Returns:
|
||||
Returns 1 if the button is pressed, otherwise 0.
|
||||
*/
|
||||
int map_is_loaded();
|
||||
|
||||
/*
|
||||
Function: map_num_items
|
||||
Checks the number of items in the loaded map.
|
||||
|
||||
Returns:
|
||||
Returns the number of items. 0 if no map is loaded.
|
||||
*/
|
||||
int map_num_items();
|
||||
|
||||
/*
|
||||
Function: map_find_item
|
||||
Searches the map for an item.
|
||||
|
||||
Arguments:
|
||||
type - Item type.
|
||||
id - Item ID.
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the item if it exists, otherwise it returns NULL.
|
||||
*/
|
||||
void *map_find_item(int type, int id);
|
||||
|
||||
/*
|
||||
Function: map_get_item
|
||||
Gets an item from the loaded map from index.
|
||||
|
||||
Arguments:
|
||||
index - Item index.
|
||||
type - Pointer that recives the item type (can be NULL).
|
||||
id - Pointer that recives the item id (can be NULL).
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the item if it exists, otherwise it returns NULL.
|
||||
*/
|
||||
void *map_get_item(int index, int *type, int *id);
|
||||
|
||||
/*
|
||||
Function: map_get_type
|
||||
Gets the index range of an item type.
|
||||
|
||||
Arguments:
|
||||
type - Item type to search for.
|
||||
start - Pointer that recives the starting index.
|
||||
num - Pointer that recives the number of items.
|
||||
|
||||
Returns:
|
||||
If the item type is not in the map, start and num will be set to 0.
|
||||
*/
|
||||
void map_get_type(int type, int *start, int *num);
|
||||
|
||||
/*
|
||||
Function: map_get_data
|
||||
Fetches a pointer to a raw data chunk in the map.
|
||||
|
||||
Arguments:
|
||||
index - Index to the data to fetch.
|
||||
|
||||
Returns:
|
||||
A pointer to the raw data, otherwise 0.
|
||||
*/
|
||||
void *map_get_data(int index);
|
||||
|
||||
/*
|
||||
Function: map_get_data_swapped
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void *map_get_data_swapped(int index);
|
||||
|
||||
/*
|
||||
Section: Network (Server)
|
||||
*/
|
||||
/*
|
||||
Function: snap_new_item
|
||||
Creates a new item that should be sent.
|
||||
|
||||
Arguments:
|
||||
type - Type of the item.
|
||||
id - ID of the item.
|
||||
size - Size of the item.
|
||||
|
||||
Returns:
|
||||
A pointer to the item data, otherwise 0.
|
||||
|
||||
Remarks:
|
||||
The item data should only consist pf 4 byte integers as
|
||||
they are subject to byte swapping. This means that the size
|
||||
argument should be dividable by 4.
|
||||
*/
|
||||
void *snap_new_item(int type, int id, int size);
|
||||
|
||||
/*
|
||||
Section:Section: Network (Client)
|
||||
*/
|
||||
/*
|
||||
Function: snap_num_items
|
||||
Check the number of items in a snapshot.
|
||||
|
||||
Arguments:
|
||||
snapid - Snapshot ID to the data to fetch.
|
||||
* SNAP_PREV for previous snapshot.
|
||||
* SNAP_CUR for current snapshot.
|
||||
|
||||
Returns:
|
||||
The number of items in the snapshot.
|
||||
*/
|
||||
int snap_num_items(int snapid);
|
||||
|
||||
/*
|
||||
Function: snap_get_item
|
||||
Gets an item from a snapshot.
|
||||
|
||||
Arguments:
|
||||
snapid - Snapshot ID to the data to fetch.
|
||||
* SNAP_PREV for previous snapshot.
|
||||
* SNAP_CUR for current snapshot.
|
||||
index - Index of the item.
|
||||
item - Pointer that recives the item info.
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the item if it exists, otherwise NULL.
|
||||
*/
|
||||
void *snap_get_item(int snapid, int index, SNAP_ITEM *item);
|
||||
|
||||
/*
|
||||
Function: snap_find_item
|
||||
Searches a snapshot for an item.
|
||||
|
||||
Arguments:
|
||||
snapid - Snapshot ID to the data to fetch.
|
||||
* SNAP_PREV for previous snapshot.
|
||||
* SNAP_CUR for current snapshot.
|
||||
type - Type of the item.
|
||||
id - ID of the item.
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the item if it exists, otherwise NULL.
|
||||
*/
|
||||
void *snap_find_item(int snapid, int type, int id);
|
||||
|
||||
/*
|
||||
Function: snap_invalidate_item
|
||||
Marks an item as invalid byt setting type and id to 0xffffffff.
|
||||
|
||||
Arguments:
|
||||
snapid - Snapshot ID to the data to fetch.
|
||||
* SNAP_PREV for previous snapshot.
|
||||
* SNAP_CUR for current snapshot.
|
||||
index - Index of the item.
|
||||
*/
|
||||
void snap_invalidate_item(int snapid, int index);
|
||||
|
||||
/*
|
||||
Function: snap_input
|
||||
Sets the input data to send to the server.
|
||||
|
||||
Arguments:
|
||||
data - Pointer to the data.
|
||||
size - Size of the data.
|
||||
|
||||
Remarks:
|
||||
The data should only consist of 4 bytes integer as they are
|
||||
subject to byte swapping.
|
||||
*/
|
||||
void snap_input(void *data, int size);
|
||||
|
||||
/*
|
||||
Function: snap_set_staticsize
|
||||
Tells the engine how big a specific item always will be. This
|
||||
helps the engine to compress snapshots better.
|
||||
|
||||
Arguments:
|
||||
type - Item type
|
||||
size - Size of the data.
|
||||
|
||||
Remarks:
|
||||
Size must be in a multiple of 4.
|
||||
*/
|
||||
void snap_set_staticsize(int type, int size);
|
||||
|
||||
/* message packing */
|
||||
enum
|
||||
{
|
||||
MSGFLAG_VITAL=1,
|
||||
MSGFLAG_FLUSH=2,
|
||||
MSGFLAG_NORECORD=4,
|
||||
MSGFLAG_RECORD=8,
|
||||
MSGFLAG_NOSEND=16
|
||||
};
|
||||
|
||||
/* message sending */
|
||||
/*
|
||||
Function: server_send_msg
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int server_send_msg(int client_id); /* client_id == -1 == broadcast */
|
||||
|
||||
/*
|
||||
Function: client_send_msg
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int client_send_msg();
|
||||
/* undocumented graphics stuff */
|
||||
|
||||
/* server snap id */
|
||||
/*
|
||||
Function: snap_new_id
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int snap_new_id();
|
||||
|
||||
/*
|
||||
Function: snap_free_id
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void snap_free_id(int id);
|
||||
|
||||
/* other */
|
||||
/*
|
||||
Function: map_unload_data
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void map_unload_data(int index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,149 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_SERVER_H
|
||||
#define ENGINE_IF_SERVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Section: Server Interface
|
||||
*/
|
||||
|
||||
/* server */
|
||||
/*
|
||||
Function: server_getclientinfo
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int server_getclientinfo(int client_id, CLIENT_INFO *info);
|
||||
|
||||
/*
|
||||
Function: server_clientname
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
const char *server_clientname(int client_id);
|
||||
|
||||
/* grabs the latest input for the client. not withholding anything */
|
||||
|
||||
/*
|
||||
Function: server_latestinput
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int *server_latestinput(int client_id, int *size);
|
||||
|
||||
/*
|
||||
Function: server_setclientname
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void server_setclientname(int client_id, const char *name);
|
||||
|
||||
/*
|
||||
Function: server_setclientscore
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void server_setclientscore(int client_id, int score);
|
||||
|
||||
/*
|
||||
Function: server_setbrowseinfo
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void server_setbrowseinfo(const char *game_type, int progression);
|
||||
|
||||
/*
|
||||
Function: server_kick
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
void server_kick(int client_id, const char *reason);
|
||||
|
||||
/*
|
||||
Function: server_tick
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int server_tick();
|
||||
|
||||
/*
|
||||
Function: server_tickspeed
|
||||
TODO
|
||||
|
||||
Arguments:
|
||||
arg1 - desc
|
||||
|
||||
Returns:
|
||||
|
||||
See Also:
|
||||
<other_func>
|
||||
*/
|
||||
int server_tickspeed();
|
||||
|
||||
int server_ban_add(NETADDR addr, int seconds);
|
||||
int server_ban_remove(NETADDR addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,99 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#ifndef ENGINE_IF_SND_H
|
||||
#define ENGINE_IF_SND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Section: Sound
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: snd_set_channel
|
||||
Sets the parameters for a sound channel.
|
||||
|
||||
Arguments:
|
||||
cid - Channel ID
|
||||
vol - Volume for the channel. 0.0 to 1.0.
|
||||
pan - Panning for the channel. -1.0 is all left. 0.0 is equal distribution. 1.0 is all right.
|
||||
*/
|
||||
void snd_set_channel(int cid, float vol, float pan);
|
||||
|
||||
/*
|
||||
Function: snd_load_wv
|
||||
Loads a wavpack compressed sound.
|
||||
|
||||
Arguments:
|
||||
filename - Filename of the file to load
|
||||
|
||||
Returns:
|
||||
The id of the loaded sound. -1 on failure.
|
||||
*/
|
||||
int snd_load_wv(const char *filename);
|
||||
|
||||
/*
|
||||
Function: snd_play_at
|
||||
Plays a sound at a specified postition.
|
||||
|
||||
Arguments:
|
||||
cid - Channel id of the channel to use.
|
||||
sid - Sound id of the sound to play.
|
||||
flags - TODO
|
||||
x - TODO
|
||||
y - TODO
|
||||
|
||||
Returns:
|
||||
An id to the voice. -1 on failure.
|
||||
|
||||
See Also:
|
||||
<snd_play, snd_stop>
|
||||
*/
|
||||
int snd_play_at(int cid, int sid, int flags, float x, float y);
|
||||
|
||||
/*
|
||||
Function: snd_play
|
||||
Plays a sound.
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
cid - Channel id of the channel to use.
|
||||
sid - Sound id of the sound to play.
|
||||
flags - TODO
|
||||
|
||||
Returns:
|
||||
An id to the voice. -1 on failure.
|
||||
|
||||
See Also:
|
||||
<snd_play_at, snd_stop>
|
||||
*/
|
||||
int snd_play(int cid, int sid, int flags);
|
||||
|
||||
/*
|
||||
Function: snd_stop
|
||||
Stops a currenly playing sound.
|
||||
|
||||
Arguments:
|
||||
id - The ID of the voice to stop.
|
||||
|
||||
See Also:
|
||||
<snd_play, snd_play_at>
|
||||
*/
|
||||
void snd_stop(int id);
|
||||
|
||||
/*
|
||||
Function: snd_set_listener_pos
|
||||
Sets the listener posititon.
|
||||
|
||||
Arguments:
|
||||
x - TODO
|
||||
y - TODO
|
||||
*/
|
||||
void snd_set_listener_pos(float x, float y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,76 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include "e_jobs.h"
|
||||
|
||||
void worker_thread(void *user)
|
||||
{
|
||||
JOBPOOL *pool = (JOBPOOL *)user;
|
||||
|
||||
while(1)
|
||||
{
|
||||
JOB *job = 0;
|
||||
|
||||
/* fetch job from queue */
|
||||
lock_wait(pool->lock);
|
||||
if(pool->first_job)
|
||||
{
|
||||
job = pool->first_job;
|
||||
pool->first_job = pool->first_job->next;
|
||||
if(pool->first_job)
|
||||
pool->first_job->prev = 0;
|
||||
else
|
||||
pool->last_job = 0;
|
||||
}
|
||||
lock_release(pool->lock);
|
||||
|
||||
/* do the job if we have one */
|
||||
if(job)
|
||||
{
|
||||
job->status = JOBSTATUS_RUNNING;
|
||||
job->result = job->func(job->func_data);
|
||||
job->status = JOBSTATUS_DONE;
|
||||
}
|
||||
else
|
||||
thread_sleep(10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int jobs_initpool(JOBPOOL *pool, int num_threads)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* empty the pool */
|
||||
mem_zero(pool, sizeof(JOBPOOL));
|
||||
pool->lock = lock_create();
|
||||
|
||||
/* start threads */
|
||||
for(i = 0; i < num_threads; i++)
|
||||
thread_create(worker_thread, pool);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jobs_add(JOBPOOL *pool, JOB *job, JOBFUNC func, void *data)
|
||||
{
|
||||
mem_zero(job, sizeof(JOB));
|
||||
job->func = func;
|
||||
job->func_data = data;
|
||||
|
||||
lock_wait(pool->lock);
|
||||
|
||||
/* add job to queue */
|
||||
job->prev = pool->last_job;
|
||||
if(pool->last_job)
|
||||
pool->last_job->next = job;
|
||||
pool->last_job = job;
|
||||
if(!pool->first_job)
|
||||
pool->first_job = job;
|
||||
|
||||
lock_release(pool->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jobs_status(JOB *job)
|
||||
{
|
||||
return job->status;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (*JOBFUNC)(void *data);
|
||||
|
||||
typedef struct JOB
|
||||
{
|
||||
struct JOBPOOL *pool;
|
||||
struct JOB *prev;
|
||||
struct JOB *next;
|
||||
volatile int status;
|
||||
volatile int result;
|
||||
JOBFUNC func;
|
||||
void *func_data;
|
||||
} JOB;
|
||||
|
||||
typedef struct JOBPOOL
|
||||
{
|
||||
LOCK lock;
|
||||
JOB *first_job;
|
||||
JOB *last_job;
|
||||
} JOBPOOL;
|
||||
|
||||
enum
|
||||
{
|
||||
JOBSTATUS_PENDING=0,
|
||||
JOBSTATUS_RUNNING,
|
||||
JOBSTATUS_DONE
|
||||
/*JOBSTATUS_ABORTING,*/
|
||||
/*JOBSTATUS_ABORTED,*/
|
||||
};
|
||||
|
||||
int jobs_initpool(JOBPOOL *pool, int num_threads);
|
||||
int jobs_add(JOBPOOL *pool, JOB *job, JOBFUNC func, void *data);
|
||||
int jobs_status(JOB *job);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,525 +0,0 @@
|
||||
/* AUTO GENERATED! DO NOT EDIT MANUALLY! */
|
||||
|
||||
#include <string.h>
|
||||
#include "e_if_inp.h"
|
||||
|
||||
static const char key_strings[512][16] =
|
||||
{
|
||||
|
||||
"first",
|
||||
"&1",
|
||||
"&2",
|
||||
"&3",
|
||||
"&4",
|
||||
"&5",
|
||||
"&6",
|
||||
"&7",
|
||||
"backspace",
|
||||
"tab",
|
||||
"&10",
|
||||
"&11",
|
||||
"clear",
|
||||
"return",
|
||||
"&14",
|
||||
"&15",
|
||||
"&16",
|
||||
"&17",
|
||||
"&18",
|
||||
"pause",
|
||||
"&20",
|
||||
"&21",
|
||||
"&22",
|
||||
"&23",
|
||||
"&24",
|
||||
"&25",
|
||||
"&26",
|
||||
"escape",
|
||||
"&28",
|
||||
"&29",
|
||||
"&30",
|
||||
"&31",
|
||||
"space",
|
||||
"exclaim",
|
||||
"quotedbl",
|
||||
"hash",
|
||||
"dollar",
|
||||
"&37",
|
||||
"ampersand",
|
||||
"quote",
|
||||
"leftparen",
|
||||
"rightparen",
|
||||
"asterisk",
|
||||
"plus",
|
||||
"comma",
|
||||
"minus",
|
||||
"period",
|
||||
"slash",
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"colon",
|
||||
"semicolon",
|
||||
"less",
|
||||
"equals",
|
||||
"greater",
|
||||
"question",
|
||||
"at",
|
||||
"&65",
|
||||
"&66",
|
||||
"&67",
|
||||
"&68",
|
||||
"&69",
|
||||
"&70",
|
||||
"&71",
|
||||
"&72",
|
||||
"&73",
|
||||
"&74",
|
||||
"&75",
|
||||
"&76",
|
||||
"&77",
|
||||
"&78",
|
||||
"&79",
|
||||
"&80",
|
||||
"&81",
|
||||
"&82",
|
||||
"&83",
|
||||
"&84",
|
||||
"&85",
|
||||
"&86",
|
||||
"&87",
|
||||
"&88",
|
||||
"&89",
|
||||
"&90",
|
||||
"leftbracket",
|
||||
"backslash",
|
||||
"rightbracket",
|
||||
"caret",
|
||||
"underscore",
|
||||
"backquote",
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"d",
|
||||
"e",
|
||||
"f",
|
||||
"g",
|
||||
"h",
|
||||
"i",
|
||||
"j",
|
||||
"k",
|
||||
"l",
|
||||
"m",
|
||||
"n",
|
||||
"o",
|
||||
"p",
|
||||
"q",
|
||||
"r",
|
||||
"s",
|
||||
"t",
|
||||
"u",
|
||||
"v",
|
||||
"w",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"&123",
|
||||
"&124",
|
||||
"&125",
|
||||
"&126",
|
||||
"delete",
|
||||
"&128",
|
||||
"&129",
|
||||
"&130",
|
||||
"&131",
|
||||
"&132",
|
||||
"&133",
|
||||
"&134",
|
||||
"&135",
|
||||
"&136",
|
||||
"&137",
|
||||
"&138",
|
||||
"&139",
|
||||
"&140",
|
||||
"&141",
|
||||
"&142",
|
||||
"&143",
|
||||
"&144",
|
||||
"&145",
|
||||
"&146",
|
||||
"&147",
|
||||
"&148",
|
||||
"&149",
|
||||
"&150",
|
||||
"&151",
|
||||
"&152",
|
||||
"&153",
|
||||
"&154",
|
||||
"&155",
|
||||
"&156",
|
||||
"&157",
|
||||
"&158",
|
||||
"&159",
|
||||
"world_0",
|
||||
"world_1",
|
||||
"world_2",
|
||||
"world_3",
|
||||
"world_4",
|
||||
"world_5",
|
||||
"world_6",
|
||||
"world_7",
|
||||
"world_8",
|
||||
"world_9",
|
||||
"world_10",
|
||||
"world_11",
|
||||
"world_12",
|
||||
"world_13",
|
||||
"world_14",
|
||||
"world_15",
|
||||
"world_16",
|
||||
"world_17",
|
||||
"world_18",
|
||||
"world_19",
|
||||
"world_20",
|
||||
"world_21",
|
||||
"world_22",
|
||||
"world_23",
|
||||
"world_24",
|
||||
"world_25",
|
||||
"world_26",
|
||||
"world_27",
|
||||
"world_28",
|
||||
"world_29",
|
||||
"world_30",
|
||||
"world_31",
|
||||
"world_32",
|
||||
"world_33",
|
||||
"world_34",
|
||||
"world_35",
|
||||
"world_36",
|
||||
"world_37",
|
||||
"world_38",
|
||||
"world_39",
|
||||
"world_40",
|
||||
"world_41",
|
||||
"world_42",
|
||||
"world_43",
|
||||
"world_44",
|
||||
"world_45",
|
||||
"world_46",
|
||||
"world_47",
|
||||
"world_48",
|
||||
"world_49",
|
||||
"world_50",
|
||||
"world_51",
|
||||
"world_52",
|
||||
"world_53",
|
||||
"world_54",
|
||||
"world_55",
|
||||
"world_56",
|
||||
"world_57",
|
||||
"world_58",
|
||||
"world_59",
|
||||
"world_60",
|
||||
"world_61",
|
||||
"world_62",
|
||||
"world_63",
|
||||
"world_64",
|
||||
"world_65",
|
||||
"world_66",
|
||||
"world_67",
|
||||
"world_68",
|
||||
"world_69",
|
||||
"world_70",
|
||||
"world_71",
|
||||
"world_72",
|
||||
"world_73",
|
||||
"world_74",
|
||||
"world_75",
|
||||
"world_76",
|
||||
"world_77",
|
||||
"world_78",
|
||||
"world_79",
|
||||
"world_80",
|
||||
"world_81",
|
||||
"world_82",
|
||||
"world_83",
|
||||
"world_84",
|
||||
"world_85",
|
||||
"world_86",
|
||||
"world_87",
|
||||
"world_88",
|
||||
"world_89",
|
||||
"world_90",
|
||||
"world_91",
|
||||
"world_92",
|
||||
"world_93",
|
||||
"world_94",
|
||||
"world_95",
|
||||
"kp0",
|
||||
"kp1",
|
||||
"kp2",
|
||||
"kp3",
|
||||
"kp4",
|
||||
"kp5",
|
||||
"kp6",
|
||||
"kp7",
|
||||
"kp8",
|
||||
"kp9",
|
||||
"kp_period",
|
||||
"kp_divide",
|
||||
"kp_multiply",
|
||||
"kp_minus",
|
||||
"kp_plus",
|
||||
"kp_enter",
|
||||
"kp_equals",
|
||||
"up",
|
||||
"down",
|
||||
"right",
|
||||
"left",
|
||||
"insert",
|
||||
"home",
|
||||
"end",
|
||||
"pageup",
|
||||
"pagedown",
|
||||
"f1",
|
||||
"f2",
|
||||
"f3",
|
||||
"f4",
|
||||
"f5",
|
||||
"f6",
|
||||
"f7",
|
||||
"f8",
|
||||
"f9",
|
||||
"f10",
|
||||
"f11",
|
||||
"f12",
|
||||
"f13",
|
||||
"f14",
|
||||
"f15",
|
||||
"&297",
|
||||
"&298",
|
||||
"&299",
|
||||
"numlock",
|
||||
"capslock",
|
||||
"scrollock",
|
||||
"rshift",
|
||||
"lshift",
|
||||
"rctrl",
|
||||
"lctrl",
|
||||
"ralt",
|
||||
"lalt",
|
||||
"rmeta",
|
||||
"lmeta",
|
||||
"lsuper",
|
||||
"rsuper",
|
||||
"mode",
|
||||
"compose",
|
||||
"help",
|
||||
"print",
|
||||
"sysreq",
|
||||
"break",
|
||||
"menu",
|
||||
"power",
|
||||
"euro",
|
||||
"undo",
|
||||
"mouse1",
|
||||
"mouse2",
|
||||
"mouse3",
|
||||
"mouse4",
|
||||
"mouse5",
|
||||
"mouse6",
|
||||
"mouse7",
|
||||
"mouse8",
|
||||
"mousewheelup",
|
||||
"mousewheeldown",
|
||||
"&333",
|
||||
"&334",
|
||||
"&335",
|
||||
"&336",
|
||||
"&337",
|
||||
"&338",
|
||||
"&339",
|
||||
"&340",
|
||||
"&341",
|
||||
"&342",
|
||||
"&343",
|
||||
"&344",
|
||||
"&345",
|
||||
"&346",
|
||||
"&347",
|
||||
"&348",
|
||||
"&349",
|
||||
"&350",
|
||||
"&351",
|
||||
"&352",
|
||||
"&353",
|
||||
"&354",
|
||||
"&355",
|
||||
"&356",
|
||||
"&357",
|
||||
"&358",
|
||||
"&359",
|
||||
"&360",
|
||||
"&361",
|
||||
"&362",
|
||||
"&363",
|
||||
"&364",
|
||||
"&365",
|
||||
"&366",
|
||||
"&367",
|
||||
"&368",
|
||||
"&369",
|
||||
"&370",
|
||||
"&371",
|
||||
"&372",
|
||||
"&373",
|
||||
"&374",
|
||||
"&375",
|
||||
"&376",
|
||||
"&377",
|
||||
"&378",
|
||||
"&379",
|
||||
"&380",
|
||||
"&381",
|
||||
"&382",
|
||||
"&383",
|
||||
"&384",
|
||||
"&385",
|
||||
"&386",
|
||||
"&387",
|
||||
"&388",
|
||||
"&389",
|
||||
"&390",
|
||||
"&391",
|
||||
"&392",
|
||||
"&393",
|
||||
"&394",
|
||||
"&395",
|
||||
"&396",
|
||||
"&397",
|
||||
"&398",
|
||||
"&399",
|
||||
"&400",
|
||||
"&401",
|
||||
"&402",
|
||||
"&403",
|
||||
"&404",
|
||||
"&405",
|
||||
"&406",
|
||||
"&407",
|
||||
"&408",
|
||||
"&409",
|
||||
"&410",
|
||||
"&411",
|
||||
"&412",
|
||||
"&413",
|
||||
"&414",
|
||||
"&415",
|
||||
"&416",
|
||||
"&417",
|
||||
"&418",
|
||||
"&419",
|
||||
"&420",
|
||||
"&421",
|
||||
"&422",
|
||||
"&423",
|
||||
"&424",
|
||||
"&425",
|
||||
"&426",
|
||||
"&427",
|
||||
"&428",
|
||||
"&429",
|
||||
"&430",
|
||||
"&431",
|
||||
"&432",
|
||||
"&433",
|
||||
"&434",
|
||||
"&435",
|
||||
"&436",
|
||||
"&437",
|
||||
"&438",
|
||||
"&439",
|
||||
"&440",
|
||||
"&441",
|
||||
"&442",
|
||||
"&443",
|
||||
"&444",
|
||||
"&445",
|
||||
"&446",
|
||||
"&447",
|
||||
"&448",
|
||||
"&449",
|
||||
"&450",
|
||||
"&451",
|
||||
"&452",
|
||||
"&453",
|
||||
"&454",
|
||||
"&455",
|
||||
"&456",
|
||||
"&457",
|
||||
"&458",
|
||||
"&459",
|
||||
"&460",
|
||||
"&461",
|
||||
"&462",
|
||||
"&463",
|
||||
"&464",
|
||||
"&465",
|
||||
"&466",
|
||||
"&467",
|
||||
"&468",
|
||||
"&469",
|
||||
"&470",
|
||||
"&471",
|
||||
"&472",
|
||||
"&473",
|
||||
"&474",
|
||||
"&475",
|
||||
"&476",
|
||||
"&477",
|
||||
"&478",
|
||||
"&479",
|
||||
"&480",
|
||||
"&481",
|
||||
"&482",
|
||||
"&483",
|
||||
"&484",
|
||||
"&485",
|
||||
"&486",
|
||||
"&487",
|
||||
"&488",
|
||||
"&489",
|
||||
"&490",
|
||||
"&491",
|
||||
"&492",
|
||||
"&493",
|
||||
"&494",
|
||||
"&495",
|
||||
"&496",
|
||||
"&497",
|
||||
"&498",
|
||||
"&499",
|
||||
"&500",
|
||||
"&501",
|
||||
"&502",
|
||||
"&503",
|
||||
"&504",
|
||||
"&505",
|
||||
"&506",
|
||||
"&507",
|
||||
"&508",
|
||||
"&509",
|
||||
"&510",
|
||||
"&511",
|
||||
};
|
||||
|
||||
const char *inp_key_name(int k) { if (k >= 0 && k < 512) return key_strings[k]; else return key_strings[0]; }
|
||||
int inp_key_code(const char *key_name) { int i; if (!strcmp(key_name, "-?-")) return -1; else for (i = 0; i < 512; i++) if (!strcmp(key_strings[i], key_name)) return i; return -1; }
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
#ifndef ENGINE_KEYS_H
|
||||
#define ENGINE_KEYS_H
|
||||
/* AUTO GENERATED! DO NOT EDIT MANUALLY! */
|
||||
enum
|
||||
{
|
||||
KEY_UNKNOWN = 0,
|
||||
KEY_FIRST = 0,
|
||||
KEY_BACKSPACE = 8,
|
||||
KEY_TAB = 9,
|
||||
KEY_CLEAR = 12,
|
||||
KEY_RETURN = 13,
|
||||
KEY_PAUSE = 19,
|
||||
KEY_ESCAPE = 27,
|
||||
KEY_SPACE = 32,
|
||||
KEY_EXCLAIM = 33,
|
||||
KEY_QUOTEDBL = 34,
|
||||
KEY_HASH = 35,
|
||||
KEY_DOLLAR = 36,
|
||||
KEY_AMPERSAND = 38,
|
||||
KEY_QUOTE = 39,
|
||||
KEY_LEFTPAREN = 40,
|
||||
KEY_RIGHTPAREN = 41,
|
||||
KEY_ASTERISK = 42,
|
||||
KEY_PLUS = 43,
|
||||
KEY_COMMA = 44,
|
||||
KEY_MINUS = 45,
|
||||
KEY_PERIOD = 46,
|
||||
KEY_SLASH = 47,
|
||||
KEY_0 = 48,
|
||||
KEY_1 = 49,
|
||||
KEY_2 = 50,
|
||||
KEY_3 = 51,
|
||||
KEY_4 = 52,
|
||||
KEY_5 = 53,
|
||||
KEY_6 = 54,
|
||||
KEY_7 = 55,
|
||||
KEY_8 = 56,
|
||||
KEY_9 = 57,
|
||||
KEY_COLON = 58,
|
||||
KEY_SEMICOLON = 59,
|
||||
KEY_LESS = 60,
|
||||
KEY_EQUALS = 61,
|
||||
KEY_GREATER = 62,
|
||||
KEY_QUESTION = 63,
|
||||
KEY_AT = 64,
|
||||
KEY_LEFTBRACKET = 91,
|
||||
KEY_BACKSLASH = 92,
|
||||
KEY_RIGHTBRACKET = 93,
|
||||
KEY_CARET = 94,
|
||||
KEY_UNDERSCORE = 95,
|
||||
KEY_BACKQUOTE = 96,
|
||||
KEY_a = 97,
|
||||
KEY_b = 98,
|
||||
KEY_c = 99,
|
||||
KEY_d = 100,
|
||||
KEY_e = 101,
|
||||
KEY_f = 102,
|
||||
KEY_g = 103,
|
||||
KEY_h = 104,
|
||||
KEY_i = 105,
|
||||
KEY_j = 106,
|
||||
KEY_k = 107,
|
||||
KEY_l = 108,
|
||||
KEY_m = 109,
|
||||
KEY_n = 110,
|
||||
KEY_o = 111,
|
||||
KEY_p = 112,
|
||||
KEY_q = 113,
|
||||
KEY_r = 114,
|
||||
KEY_s = 115,
|
||||
KEY_t = 116,
|
||||
KEY_u = 117,
|
||||
KEY_v = 118,
|
||||
KEY_w = 119,
|
||||
KEY_x = 120,
|
||||
KEY_y = 121,
|
||||
KEY_z = 122,
|
||||
KEY_DELETE = 127,
|
||||
KEY_WORLD_0 = 160,
|
||||
KEY_WORLD_1 = 161,
|
||||
KEY_WORLD_2 = 162,
|
||||
KEY_WORLD_3 = 163,
|
||||
KEY_WORLD_4 = 164,
|
||||
KEY_WORLD_5 = 165,
|
||||
KEY_WORLD_6 = 166,
|
||||
KEY_WORLD_7 = 167,
|
||||
KEY_WORLD_8 = 168,
|
||||
KEY_WORLD_9 = 169,
|
||||
KEY_WORLD_10 = 170,
|
||||
KEY_WORLD_11 = 171,
|
||||
KEY_WORLD_12 = 172,
|
||||
KEY_WORLD_13 = 173,
|
||||
KEY_WORLD_14 = 174,
|
||||
KEY_WORLD_15 = 175,
|
||||
KEY_WORLD_16 = 176,
|
||||
KEY_WORLD_17 = 177,
|
||||
KEY_WORLD_18 = 178,
|
||||
KEY_WORLD_19 = 179,
|
||||
KEY_WORLD_20 = 180,
|
||||
KEY_WORLD_21 = 181,
|
||||
KEY_WORLD_22 = 182,
|
||||
KEY_WORLD_23 = 183,
|
||||
KEY_WORLD_24 = 184,
|
||||
KEY_WORLD_25 = 185,
|
||||
KEY_WORLD_26 = 186,
|
||||
KEY_WORLD_27 = 187,
|
||||
KEY_WORLD_28 = 188,
|
||||
KEY_WORLD_29 = 189,
|
||||
KEY_WORLD_30 = 190,
|
||||
KEY_WORLD_31 = 191,
|
||||
KEY_WORLD_32 = 192,
|
||||
KEY_WORLD_33 = 193,
|
||||
KEY_WORLD_34 = 194,
|
||||
KEY_WORLD_35 = 195,
|
||||
KEY_WORLD_36 = 196,
|
||||
KEY_WORLD_37 = 197,
|
||||
KEY_WORLD_38 = 198,
|
||||
KEY_WORLD_39 = 199,
|
||||
KEY_WORLD_40 = 200,
|
||||
KEY_WORLD_41 = 201,
|
||||
KEY_WORLD_42 = 202,
|
||||
KEY_WORLD_43 = 203,
|
||||
KEY_WORLD_44 = 204,
|
||||
KEY_WORLD_45 = 205,
|
||||
KEY_WORLD_46 = 206,
|
||||
KEY_WORLD_47 = 207,
|
||||
KEY_WORLD_48 = 208,
|
||||
KEY_WORLD_49 = 209,
|
||||
KEY_WORLD_50 = 210,
|
||||
KEY_WORLD_51 = 211,
|
||||
KEY_WORLD_52 = 212,
|
||||
KEY_WORLD_53 = 213,
|
||||
KEY_WORLD_54 = 214,
|
||||
KEY_WORLD_55 = 215,
|
||||
KEY_WORLD_56 = 216,
|
||||
KEY_WORLD_57 = 217,
|
||||
KEY_WORLD_58 = 218,
|
||||
KEY_WORLD_59 = 219,
|
||||
KEY_WORLD_60 = 220,
|
||||
KEY_WORLD_61 = 221,
|
||||
KEY_WORLD_62 = 222,
|
||||
KEY_WORLD_63 = 223,
|
||||
KEY_WORLD_64 = 224,
|
||||
KEY_WORLD_65 = 225,
|
||||
KEY_WORLD_66 = 226,
|
||||
KEY_WORLD_67 = 227,
|
||||
KEY_WORLD_68 = 228,
|
||||
KEY_WORLD_69 = 229,
|
||||
KEY_WORLD_70 = 230,
|
||||
KEY_WORLD_71 = 231,
|
||||
KEY_WORLD_72 = 232,
|
||||
KEY_WORLD_73 = 233,
|
||||
KEY_WORLD_74 = 234,
|
||||
KEY_WORLD_75 = 235,
|
||||
KEY_WORLD_76 = 236,
|
||||
KEY_WORLD_77 = 237,
|
||||
KEY_WORLD_78 = 238,
|
||||
KEY_WORLD_79 = 239,
|
||||
KEY_WORLD_80 = 240,
|
||||
KEY_WORLD_81 = 241,
|
||||
KEY_WORLD_82 = 242,
|
||||
KEY_WORLD_83 = 243,
|
||||
KEY_WORLD_84 = 244,
|
||||
KEY_WORLD_85 = 245,
|
||||
KEY_WORLD_86 = 246,
|
||||
KEY_WORLD_87 = 247,
|
||||
KEY_WORLD_88 = 248,
|
||||
KEY_WORLD_89 = 249,
|
||||
KEY_WORLD_90 = 250,
|
||||
KEY_WORLD_91 = 251,
|
||||
KEY_WORLD_92 = 252,
|
||||
KEY_WORLD_93 = 253,
|
||||
KEY_WORLD_94 = 254,
|
||||
KEY_WORLD_95 = 255,
|
||||
KEY_KP0 = 256,
|
||||
KEY_KP1 = 257,
|
||||
KEY_KP2 = 258,
|
||||
KEY_KP3 = 259,
|
||||
KEY_KP4 = 260,
|
||||
KEY_KP5 = 261,
|
||||
KEY_KP6 = 262,
|
||||
KEY_KP7 = 263,
|
||||
KEY_KP8 = 264,
|
||||
KEY_KP9 = 265,
|
||||
KEY_KP_PERIOD = 266,
|
||||
KEY_KP_DIVIDE = 267,
|
||||
KEY_KP_MULTIPLY = 268,
|
||||
KEY_KP_MINUS = 269,
|
||||
KEY_KP_PLUS = 270,
|
||||
KEY_KP_ENTER = 271,
|
||||
KEY_KP_EQUALS = 272,
|
||||
KEY_UP = 273,
|
||||
KEY_DOWN = 274,
|
||||
KEY_RIGHT = 275,
|
||||
KEY_LEFT = 276,
|
||||
KEY_INSERT = 277,
|
||||
KEY_HOME = 278,
|
||||
KEY_END = 279,
|
||||
KEY_PAGEUP = 280,
|
||||
KEY_PAGEDOWN = 281,
|
||||
KEY_F1 = 282,
|
||||
KEY_F2 = 283,
|
||||
KEY_F3 = 284,
|
||||
KEY_F4 = 285,
|
||||
KEY_F5 = 286,
|
||||
KEY_F6 = 287,
|
||||
KEY_F7 = 288,
|
||||
KEY_F8 = 289,
|
||||
KEY_F9 = 290,
|
||||
KEY_F10 = 291,
|
||||
KEY_F11 = 292,
|
||||
KEY_F12 = 293,
|
||||
KEY_F13 = 294,
|
||||
KEY_F14 = 295,
|
||||
KEY_F15 = 296,
|
||||
KEY_NUMLOCK = 300,
|
||||
KEY_CAPSLOCK = 301,
|
||||
KEY_SCROLLOCK = 302,
|
||||
KEY_RSHIFT = 303,
|
||||
KEY_LSHIFT = 304,
|
||||
KEY_RCTRL = 305,
|
||||
KEY_LCTRL = 306,
|
||||
KEY_RALT = 307,
|
||||
KEY_LALT = 308,
|
||||
KEY_RMETA = 309,
|
||||
KEY_LMETA = 310,
|
||||
KEY_LSUPER = 311,
|
||||
KEY_RSUPER = 312,
|
||||
KEY_MODE = 313,
|
||||
KEY_COMPOSE = 314,
|
||||
KEY_HELP = 315,
|
||||
KEY_PRINT = 316,
|
||||
KEY_SYSREQ = 317,
|
||||
KEY_BREAK = 318,
|
||||
KEY_MENU = 319,
|
||||
KEY_POWER = 320,
|
||||
KEY_EURO = 321,
|
||||
KEY_UNDO = 322,
|
||||
KEY_MOUSE_1 = 323,
|
||||
KEY_MOUSE_2 = 324,
|
||||
KEY_MOUSE_3 = 325,
|
||||
KEY_MOUSE_4 = 326,
|
||||
KEY_MOUSE_5 = 327,
|
||||
KEY_MOUSE_6 = 328,
|
||||
KEY_MOUSE_7 = 329,
|
||||
KEY_MOUSE_8 = 330,
|
||||
KEY_MOUSE_WHEEL_UP = 331,
|
||||
KEY_MOUSE_WHEEL_DOWN = 332,
|
||||
KEY_LAST,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "e_linereader.h"
|
||||
|
||||
void linereader_init(LINEREADER *lr, IOHANDLE io)
|
||||
{
|
||||
lr->buffer_max_size = 4*1024;
|
||||
lr->buffer_size = 0;
|
||||
lr->buffer_pos = 0;
|
||||
lr->io = io;
|
||||
}
|
||||
|
||||
char *linereader_get(LINEREADER *lr)
|
||||
{
|
||||
unsigned line_start = lr->buffer_pos;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(lr->buffer_pos >= lr->buffer_size)
|
||||
{
|
||||
/* fetch more */
|
||||
|
||||
/* move the remaining part to the front */
|
||||
unsigned read;
|
||||
unsigned left = lr->buffer_size - line_start;
|
||||
|
||||
if(line_start > lr->buffer_size)
|
||||
left = 0;
|
||||
if(left)
|
||||
mem_move(lr->buffer, &lr->buffer[line_start], left);
|
||||
lr->buffer_pos = left;
|
||||
|
||||
/* fill the buffer */
|
||||
read = io_read(lr->io, &lr->buffer[lr->buffer_pos], lr->buffer_max_size-lr->buffer_pos);
|
||||
lr->buffer_size = left + read;
|
||||
line_start = 0;
|
||||
|
||||
if(!read)
|
||||
{
|
||||
if(left)
|
||||
{
|
||||
lr->buffer[left] = 0; /* return the last line */
|
||||
lr->buffer_pos = left;
|
||||
lr->buffer_size = left;
|
||||
return lr->buffer;
|
||||
}
|
||||
else
|
||||
return 0x0; /* we are done! */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(lr->buffer[lr->buffer_pos] == '\n' || lr->buffer[lr->buffer_pos] == '\r')
|
||||
{
|
||||
/* line found */
|
||||
lr->buffer[lr->buffer_pos] = 0;
|
||||
lr->buffer_pos++;
|
||||
return &lr->buffer[line_start];
|
||||
}
|
||||
else
|
||||
lr->buffer_pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <base/system.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* buffered stream for reading lines, should perhaps be something smaller */
|
||||
typedef struct
|
||||
{
|
||||
char buffer[4*1024];
|
||||
unsigned buffer_pos;
|
||||
unsigned buffer_size;
|
||||
unsigned buffer_max_size;
|
||||
IOHANDLE io;
|
||||
} LINEREADER;
|
||||
|
||||
void linereader_init(LINEREADER *lr, IOHANDLE io);
|
||||
char *linereader_get(LINEREADER *lr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include "e_datafile.h"
|
||||
#include "e_if_other.h"
|
||||
|
||||
static DATAFILE *map = 0;
|
||||
|
||||
void *map_get_data(int index)
|
||||
{
|
||||
return datafile_get_data(map, index);
|
||||
}
|
||||
|
||||
void *map_get_data_swapped(int index)
|
||||
{
|
||||
return datafile_get_data_swapped(map, index);
|
||||
}
|
||||
|
||||
void map_unload_data(int index)
|
||||
{
|
||||
datafile_unload_data(map, index);
|
||||
}
|
||||
|
||||
void *map_get_item(int index, int *type, int *id)
|
||||
{
|
||||
return datafile_get_item(map, index, type, id);
|
||||
}
|
||||
|
||||
void map_get_type(int type, int *start, int *num)
|
||||
{
|
||||
datafile_get_type(map, type, start, num);
|
||||
}
|
||||
|
||||
void *map_find_item(int type, int id)
|
||||
{
|
||||
return datafile_find_item(map, type, id);
|
||||
}
|
||||
|
||||
int map_num_items()
|
||||
{
|
||||
return datafile_num_items(map);
|
||||
}
|
||||
|
||||
void map_unload()
|
||||
{
|
||||
datafile_unload(map);
|
||||
map = 0x0;
|
||||
}
|
||||
|
||||
int map_is_loaded()
|
||||
{
|
||||
return map != 0;
|
||||
}
|
||||
|
||||
int map_load(const char *mapname)
|
||||
{
|
||||
char buf[512];
|
||||
str_format(buf, sizeof(buf), "maps/%s.map", mapname);
|
||||
map = datafile_load(buf);
|
||||
return map != 0;
|
||||
}
|
||||
|
||||
void map_set(void *m)
|
||||
{
|
||||
if(map)
|
||||
map_unload();
|
||||
map = (DATAFILE*)m;
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
#include "e_memheap.h"
|
||||
|
||||
typedef struct CHUNK_t
|
||||
{
|
||||
char *memory;
|
||||
char *current;
|
||||
char *end;
|
||||
struct CHUNK_t *next;
|
||||
} CHUNK;
|
||||
|
||||
typedef struct HEAP_t
|
||||
{
|
||||
CHUNK *current;
|
||||
} HEAP;
|
||||
|
||||
/* how large each chunk should be */
|
||||
static const int chunksize = 1024*64;
|
||||
|
||||
/* allocates a new chunk to be used */
|
||||
static CHUNK *memheap_newchunk()
|
||||
{
|
||||
CHUNK *chunk;
|
||||
char *mem;
|
||||
|
||||
/* allocate memory */
|
||||
mem = (char*)mem_alloc(sizeof(CHUNK)+chunksize, 1);
|
||||
if(!mem)
|
||||
return 0x0;
|
||||
|
||||
/* the chunk structure is located in the begining of the chunk */
|
||||
/* init it and return the chunk */
|
||||
chunk = (CHUNK*)mem;
|
||||
chunk->memory = (char*)(chunk+1);
|
||||
chunk->current = chunk->memory;
|
||||
chunk->end = chunk->memory + chunksize;
|
||||
chunk->next = (CHUNK *)0x0;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/******************/
|
||||
static void *memheap_allocate_from_chunk(CHUNK *chunk, unsigned int size)
|
||||
{
|
||||
char *mem;
|
||||
|
||||
/* check if we need can fit the allocation */
|
||||
if(chunk->current + size > chunk->end)
|
||||
return (void*)0x0;
|
||||
|
||||
/* get memory and move the pointer forward */
|
||||
mem = chunk->current;
|
||||
chunk->current += size;
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* creates a heap */
|
||||
HEAP *memheap_create()
|
||||
{
|
||||
CHUNK *chunk;
|
||||
HEAP *heap;
|
||||
|
||||
/* allocate a chunk and allocate the heap structure on that chunk */
|
||||
chunk = memheap_newchunk();
|
||||
heap = (HEAP *)memheap_allocate_from_chunk(chunk, sizeof(HEAP));
|
||||
heap->current = chunk;
|
||||
return heap;
|
||||
}
|
||||
|
||||
/* destroys the heap */
|
||||
void memheap_destroy(HEAP *heap)
|
||||
{
|
||||
CHUNK *chunk = heap->current;
|
||||
CHUNK *next;
|
||||
|
||||
while(chunk)
|
||||
{
|
||||
next = chunk->next;
|
||||
mem_free(chunk);
|
||||
chunk = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
void *memheap_allocate(HEAP *heap, unsigned int size)
|
||||
{
|
||||
char *mem;
|
||||
|
||||
/* try to allocate from current chunk */
|
||||
mem = (char *)memheap_allocate_from_chunk(heap->current, size);
|
||||
if(!mem)
|
||||
{
|
||||
/* allocate new chunk and add it to the heap */
|
||||
CHUNK *chunk = memheap_newchunk();
|
||||
chunk->next = heap->current;
|
||||
heap->current = chunk;
|
||||
|
||||
/* try to allocate again */
|
||||
mem = (char *)memheap_allocate_from_chunk(heap->current, size);
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct HEAP_t HEAP;
|
||||
HEAP *memheap_create();
|
||||
void memheap_destroy(HEAP *heap);
|
||||
void *memheap_allocate(HEAP *heap, unsigned int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include "e_common_interface.h"
|
||||
#include "e_packer.h"
|
||||
|
||||
/* message packing */
|
||||
static PACKER msg_packer;
|
||||
static MSG_INFO pack_info;
|
||||
static int packer_failed = 0;
|
||||
|
||||
void msg_pack_int(int i) { packer_add_int(&msg_packer, i); }
|
||||
void msg_pack_string(const char *p, int limit) { packer_add_string(&msg_packer, p, limit); }
|
||||
void msg_pack_raw(const void *data, int size) { packer_add_raw(&msg_packer, (const unsigned char *)data, size); }
|
||||
|
||||
void msg_pack_start_system(int msg, int flags)
|
||||
{
|
||||
packer_reset(&msg_packer);
|
||||
pack_info.msg = (msg<<1)|1;
|
||||
pack_info.flags = flags;
|
||||
packer_failed = 0;
|
||||
|
||||
msg_pack_int(pack_info.msg);
|
||||
}
|
||||
|
||||
void msg_pack_start(int msg, int flags)
|
||||
{
|
||||
packer_reset(&msg_packer);
|
||||
pack_info.msg = msg<<1;
|
||||
pack_info.flags = flags;
|
||||
packer_failed = 0;
|
||||
|
||||
msg_pack_int(pack_info.msg);
|
||||
}
|
||||
|
||||
void msg_pack_end()
|
||||
{
|
||||
if(msg_packer.error)
|
||||
{
|
||||
packer_failed = 1;
|
||||
pack_info.size = 0;
|
||||
pack_info.data = (unsigned char *)"";
|
||||
}
|
||||
else
|
||||
{
|
||||
pack_info.size = packer_size(&msg_packer);
|
||||
pack_info.data = packer_data(&msg_packer);
|
||||
}
|
||||
}
|
||||
|
||||
const MSG_INFO *msg_get_info()
|
||||
{
|
||||
if(packer_failed)
|
||||
return 0;
|
||||
return &pack_info;
|
||||
}
|
||||
|
||||
/* message unpacking */
|
||||
static UNPACKER msg_unpacker;
|
||||
int msg_unpack_start(const void *data, int data_size, int *system)
|
||||
{
|
||||
int msg;
|
||||
unpacker_reset(&msg_unpacker, (const unsigned char *)data, data_size);
|
||||
msg = msg_unpack_int();
|
||||
*system = msg&1;
|
||||
return msg>>1;
|
||||
}
|
||||
|
||||
int msg_unpack_int() { return unpacker_get_int(&msg_unpacker); }
|
||||
const char *msg_unpack_string() { return unpacker_get_string(&msg_unpacker); }
|
||||
const unsigned char *msg_unpack_raw(int size) { return unpacker_get_raw(&msg_unpacker, size); }
|
||||
int msg_unpack_error() { return msg_unpacker.error; }
|
||||
@@ -1,345 +0,0 @@
|
||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <base/system.h>
|
||||
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
#include "e_config.h"
|
||||
#include "e_engine.h"
|
||||
#include "e_network.h"
|
||||
#include "e_network_internal.h"
|
||||
#include "e_huffman.h"
|
||||
|
||||
void recvinfo_clear(NETRECVINFO *info)
|
||||
{
|
||||
info->valid = 0;
|
||||
}
|
||||
|
||||
void recvinfo_start(NETRECVINFO *info, NETADDR *addr, NETCONNECTION *conn, int cid)
|
||||
{
|
||||
info->addr = *addr;
|
||||
info->conn = conn;
|
||||
info->client_id = cid;
|
||||
info->current_chunk = 0;
|
||||
info->valid = 1;
|
||||
}
|
||||
|
||||
|
||||
int seq_in_backroom(int seq, int ack)
|
||||
{
|
||||
int bottom = (ack-NET_MAX_SEQUENCE/2);
|
||||
if(bottom < 0)
|
||||
{
|
||||
if(seq <= ack)
|
||||
return 1;
|
||||
if(seq >= (bottom + NET_MAX_SEQUENCE))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(seq <= ack && seq >= bottom)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: rename this function */
|
||||
int recvinfo_fetch_chunk(NETRECVINFO *info, NETCHUNK *chunk)
|
||||
{
|
||||
NETCHUNKHEADER header;
|
||||
unsigned char *end = info->data.chunk_data + info->data.data_size;
|
||||
int i;
|
||||
|
||||
while(1)
|
||||
{
|
||||
unsigned char *data = info->data.chunk_data;
|
||||
|
||||
/* check for old data to unpack */
|
||||
if(!info->valid || info->current_chunk >= info->data.num_chunks)
|
||||
{
|
||||
recvinfo_clear(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: add checking here so we don't read too far */
|
||||
for(i = 0; i < info->current_chunk; i++)
|
||||
{
|
||||
data = unpack_chunk_header(data, &header);
|
||||
data += header.size;
|
||||
}
|
||||
|
||||
/* unpack the header */
|
||||
data = unpack_chunk_header(data, &header);
|
||||
info->current_chunk++;
|
||||
|
||||
if(data+header.size > end)
|
||||
{
|
||||
recvinfo_clear(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle sequence stuff */
|
||||
if(info->conn && (header.flags&NET_CHUNKFLAG_VITAL))
|
||||
{
|
||||
if(header.sequence == (info->conn->ack+1)%NET_MAX_SEQUENCE)
|
||||
{
|
||||
/* in sequence */
|
||||
info->conn->ack = (info->conn->ack+1)%NET_MAX_SEQUENCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* old packet that we already got */
|
||||
if(seq_in_backroom(header.sequence, info->conn->ack))
|
||||
continue;
|
||||
|
||||
/* out of sequence, request resend */
|
||||
if(config.debug)
|
||||
dbg_msg("conn", "asking for resend %d %d", header.sequence, (info->conn->ack+1)%NET_MAX_SEQUENCE);
|
||||
conn_want_resend(info->conn);
|
||||
continue; /* take the next chunk in the packet */
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in the info */
|
||||
chunk->client_id = info->client_id;
|
||||
chunk->address = info->addr;
|
||||
chunk->flags = 0;
|
||||
chunk->data_size = header.size;
|
||||
chunk->data = data;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static IOHANDLE datalog_sent = 0;
|
||||
static IOHANDLE datalog_recv = 0;
|
||||
static HUFFMAN_STATE huffmanstate;
|
||||
|
||||
#define COMPRESSION 1
|
||||
|
||||
/* packs the data tight and sends it */
|
||||
void send_packet_connless(NETSOCKET socket, NETADDR *addr, const void *data, int data_size)
|
||||
{
|
||||
unsigned char buffer[NET_MAX_PACKETSIZE];
|
||||
buffer[0] = 0xff;
|
||||
buffer[1] = 0xff;
|
||||
buffer[2] = 0xff;
|
||||
buffer[3] = 0xff;
|
||||
buffer[4] = 0xff;
|
||||
buffer[5] = 0xff;
|
||||
mem_copy(&buffer[6], data, data_size);
|
||||
net_udp_send(socket, addr, buffer, 6+data_size);
|
||||
}
|
||||
|
||||
int netcommon_compress(const void *data, int data_size, void *output, int output_size)
|
||||
{
|
||||
return huffman_compress(&huffmanstate, data, data_size, output, output_size);
|
||||
}
|
||||
|
||||
int netcommon_decompress(const void *data, int data_size, void *output, int output_size)
|
||||
{
|
||||
return huffman_decompress(&huffmanstate, data, data_size, output, output_size);
|
||||
}
|
||||
|
||||
void send_packet(NETSOCKET socket, NETADDR *addr, NETPACKETCONSTRUCT *packet)
|
||||
{
|
||||
unsigned char buffer[NET_MAX_PACKETSIZE];
|
||||
int compressed_size = -1;
|
||||
int final_size = -1;
|
||||
|
||||
/* log the data */
|
||||
if(datalog_sent)
|
||||
{
|
||||
int type = 1;
|
||||
io_write(datalog_sent, &type, sizeof(type));
|
||||
io_write(datalog_sent, &packet->data_size, sizeof(packet->data_size));
|
||||
io_write(datalog_sent, &packet->chunk_data, packet->data_size);
|
||||
io_flush(datalog_sent);
|
||||
}
|
||||
|
||||
/* compress if its enabled */
|
||||
if(COMPRESSION)
|
||||
compressed_size = huffman_compress(&huffmanstate, packet->chunk_data, packet->data_size, &buffer[3], NET_MAX_PACKETSIZE-4);
|
||||
|
||||
/* check if the compression was enabled, successful and good enough */
|
||||
if(compressed_size > 0 && compressed_size < packet->data_size)
|
||||
{
|
||||
final_size = compressed_size;
|
||||
packet->flags |= NET_PACKETFLAG_COMPRESSION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use uncompressed data */
|
||||
final_size = packet->data_size;
|
||||
mem_copy(&buffer[3], packet->chunk_data, packet->data_size);
|
||||
packet->flags &= ~NET_PACKETFLAG_COMPRESSION;
|
||||
}
|
||||
|
||||
/* set header and send the packet if all things are good */
|
||||
if(final_size >= 0)
|
||||
{
|
||||
final_size += NET_PACKETHEADERSIZE;
|
||||
buffer[0] = ((packet->flags<<4)&0xf0)|((packet->ack>>8)&0xf);
|
||||
buffer[1] = packet->ack&0xff;
|
||||
buffer[2] = packet->num_chunks;
|
||||
net_udp_send(socket, addr, buffer, final_size);
|
||||
|
||||
/* log raw socket data */
|
||||
if(datalog_sent)
|
||||
{
|
||||
int type = 0;
|
||||
io_write(datalog_sent, &type, sizeof(type));
|
||||
io_write(datalog_sent, &final_size, sizeof(final_size));
|
||||
io_write(datalog_sent, buffer, final_size);
|
||||
io_flush(datalog_sent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: rename this function */
|
||||
int unpack_packet(unsigned char *buffer, int size, NETPACKETCONSTRUCT *packet)
|
||||
{
|
||||
/* check the size */
|
||||
if(size < NET_PACKETHEADERSIZE || size > NET_MAX_PACKETSIZE)
|
||||
{
|
||||
dbg_msg("", "packet too small, %d", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* log the data */
|
||||
if(datalog_recv)
|
||||
{
|
||||
int type = 0;
|
||||
io_write(datalog_recv, &type, sizeof(type));
|
||||
io_write(datalog_recv, &size, sizeof(size));
|
||||
io_write(datalog_recv, buffer, size);
|
||||
io_flush(datalog_recv);
|
||||
}
|
||||
|
||||
/* read the packet */
|
||||
packet->flags = buffer[0]>>4;
|
||||
packet->ack = ((buffer[0]&0xf)<<8) | buffer[1];
|
||||
packet->num_chunks = buffer[2];
|
||||
packet->data_size = size - NET_PACKETHEADERSIZE;
|
||||
|
||||
if(packet->flags&NET_PACKETFLAG_CONNLESS)
|
||||
{
|
||||
packet->flags = NET_PACKETFLAG_CONNLESS;
|
||||
packet->ack = 0;
|
||||
packet->num_chunks = 0;
|
||||
packet->data_size = size - 6;
|
||||
mem_copy(packet->chunk_data, &buffer[6], packet->data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(packet->flags&NET_PACKETFLAG_COMPRESSION)
|
||||
packet->data_size = huffman_decompress(&huffmanstate, &buffer[3], packet->data_size, packet->chunk_data, sizeof(packet->chunk_data));
|
||||
else
|
||||
mem_copy(packet->chunk_data, &buffer[3], packet->data_size);
|
||||
}
|
||||
|
||||
/* check for errors */
|
||||
if(packet->data_size < 0)
|
||||
{
|
||||
if(config.debug)
|
||||
dbg_msg("network", "error during packet decoding");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* log the data */
|
||||
if(datalog_recv)
|
||||
{
|
||||
int type = 1;
|
||||
io_write(datalog_recv, &type, sizeof(type));
|
||||
io_write(datalog_recv, &packet->data_size, sizeof(packet->data_size));
|
||||
io_write(datalog_recv, packet->chunk_data, packet->data_size);
|
||||
io_flush(datalog_recv);
|
||||
}
|
||||
|
||||
/* return success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: change the arguments of this function */
|
||||
unsigned char *pack_chunk_header(unsigned char *data, int flags, int size, int sequence)
|
||||
{
|
||||
data[0] = ((flags&3)<<6)|((size>>4)&0x3f);
|
||||
data[1] = (size&0xf);
|
||||
if(flags&NET_CHUNKFLAG_VITAL)
|
||||
{
|
||||
data[1] |= (sequence>>2)&0xf0;
|
||||
data[2] = sequence&0xff;
|
||||
return data + 3;
|
||||
}
|
||||
return data + 2;
|
||||
}
|
||||
|
||||
unsigned char *unpack_chunk_header(unsigned char *data, NETCHUNKHEADER *header)
|
||||
{
|
||||
header->flags = (data[0]>>6)&3;
|
||||
header->size = ((data[0]&0x3f)<<4) | (data[1]&0xf);
|
||||
header->sequence = -1;
|
||||
if(header->flags&NET_CHUNKFLAG_VITAL)
|
||||
{
|
||||
header->sequence = ((data[1]&0xf0)<<2) | data[2];
|
||||
return data + 3;
|
||||
}
|
||||
return data + 2;
|
||||
}
|
||||
|
||||
|
||||
void send_controlmsg(NETSOCKET socket, NETADDR *addr, int ack, int controlmsg, const void *extra, int extra_size)
|
||||
{
|
||||
NETPACKETCONSTRUCT construct;
|
||||
construct.flags = NET_PACKETFLAG_CONTROL;
|
||||
construct.ack = ack;
|
||||
construct.num_chunks = 0;
|
||||
construct.data_size = 1+extra_size;
|
||||
construct.chunk_data[0] = controlmsg;
|
||||
mem_copy(&construct.chunk_data[1], extra, extra_size);
|
||||
|
||||
/* send the control message */
|
||||
send_packet(socket, addr, &construct);
|
||||
}
|
||||
|
||||
void netcommon_openlog(const char *sentlog, const char *recvlog)
|
||||
{
|
||||
if(sentlog)
|
||||
{
|
||||
datalog_sent = engine_openfile(sentlog, IOFLAG_WRITE);
|
||||
if(datalog_sent)
|
||||
dbg_msg("network", "logging sent packages to '%s'", sentlog);
|
||||
else
|
||||
dbg_msg("network", "failed to open for logging '%s'", sentlog);
|
||||
}
|
||||
|
||||
if(recvlog)
|
||||
{
|
||||
datalog_recv = engine_openfile(recvlog, IOFLAG_WRITE);
|
||||
if(recvlog)
|
||||
dbg_msg("network", "logging recv packages to '%s'", recvlog);
|
||||
else
|
||||
dbg_msg("network", "failed to open for logging '%s'", recvlog);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned freq_table[256+1] = {
|
||||
1<<30,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186,
|
||||
283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176,
|
||||
872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19,
|
||||
16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68,
|
||||
59,66,61,638,71,157,50,46,69,43,11,24,13,19,10,12,12,20,14,9,
|
||||
20,20,10,10,15,15,12,12,7,19,15,14,13,18,35,19,17,14,8,5,
|
||||
15,17,9,15,14,18,8,10,2173,134,157,68,188,60,170,60,194,62,175,71,
|
||||
148,67,167,78,211,67,156,69,1674,90,174,53,147,89,181,51,174,63,163,80,
|
||||
167,94,128,122,223,153,218,77,200,110,190,73,174,69,145,66,277,143,141,60,
|
||||
136,53,180,57,142,57,158,61,166,112,152,92,26,22,21,28,20,26,30,21,
|
||||
32,27,20,17,23,21,30,22,22,21,27,25,17,27,23,18,39,26,15,21,
|
||||
12,18,18,27,20,18,15,19,11,17,33,12,18,15,19,18,16,26,17,18,
|
||||
9,10,25,22,22,17,20,16,6,16,15,20,14,18,24,335,1517};
|
||||
|
||||
void netcommon_init()
|
||||
{
|
||||
huffman_init(&huffmanstate, freq_table);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user