[ion/sdl] First import

This commit is contained in:
Romain Goyet
2019-02-25 17:19:44 +01:00
parent d7975cfa7f
commit 1e6a3958be
14 changed files with 643 additions and 0 deletions

33
ion/src/sdl/Makefile Normal file
View File

@@ -0,0 +1,33 @@
# TODO
objs += $(addprefix ion/src/shared/, \
crc32.o \
crc32_padded.o \
events.o \
events_modifier.o \
power.o \
random.o \
timing.o \
dummy/backlight.o \
dummy/battery.o \
dummy/fcc_id.o \
dummy/led.o \
dummy/serial_number.o \
dummy/stack.o \
dummy/usb.o \
)
objs += $(addprefix ion/src/sdl/, \
display.o \
events.o \
main.o \
keyboard.o \
layout.o \
)
objs += $(addprefix ion/src/sdl/android/, \
images.o \
)
SFLAGS += -I/Users/romain/Sources/SDL/include
include ion/src/sdl/external/Makefile

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace com.test.game with the identifier of your game below, e.g.
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.numworks.calculator"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Touchscreen support -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- Game controller support -->
<uses-feature
android:name="android.hardware.gamepad"
android:required="false" />
<!-- External mouse input events -->
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Allow access to the vibrator -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- if you want to capture audio, uncomment this. -->
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
<!-- Create a Java class extending SDLActivity and place it in a
directory under app/src/main/java matching the package, e.g. app/src/main/java/com/gamemaker/game/MyGame.java
then replace "SDLActivity" with the name of your class (e.g. "MyGame")
in the XML below.
An example Java class can be found in README-android.md
-->
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true" >
<!-- Example of setting SDL hints from AndroidManifest.xml:
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
-->
<activity android:name="EpsilonActivity"
android:label="@string/app_name"
android:alwaysRetainTaskState="true"
android:launchMode="singleInstance"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Drop file event -->
<!--
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
-->
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,34 @@
package com.numworks.calculator;
import android.graphics.Bitmap;
//import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.app.Activity;
import android.util.Log;
import org.libsdl.app.SDLActivity;
public class EpsilonActivity extends SDLActivity {
protected String[] getLibraries() {
return new String[] {
"SDL2",
"epsilon"
};
}
public Bitmap retrieveBitmapAsset(String identifier) {
Log.w("LoadTexture", "Retrieving bitmap asset");
Log.w("LoadTexture", "Asset is " + identifier);
Bitmap bitmap = null;
try {
Log.w("LoadTexture", "Rez is " + this.getResources().getAssets().open(identifier));
bitmap = BitmapFactory.decodeStream(
this.getResources().getAssets().open(identifier)
);
} catch (Exception e) {
Log.w("LoadTexture", "Coundn't load a file:" + identifier);
}
return bitmap;
}
}

View File

@@ -0,0 +1,53 @@
// This shall be implemented per-platform
//
#include <SDL.h>
#include <jni.h>
#include <android/bitmap.h>
SDL_Surface * loadImage(const char * identifier) {
JNIEnv * env = static_cast<JNIEnv *>(SDL_AndroidGetJNIEnv());
jobject activity = static_cast<jobject>(SDL_AndroidGetActivity());
jstring j_identifier = env->NewStringUTF(identifier);
jclass j_class = env->FindClass("com/numworks/calculator/EpsilonActivity");
jmethodID j_methodId = env->GetMethodID(
j_class,
"retrieveBitmapAsset",
"(Ljava/lang/String;)Landroid/graphics/Bitmap;"
);
jobject j_bitmap = env->CallObjectMethod(activity, j_methodId, j_identifier);
AndroidBitmapInfo bitmapInfo;
AndroidBitmap_getInfo(env, j_bitmap, &bitmapInfo);
void * bitmapPixels = nullptr;
AndroidBitmap_lockPixels(env, j_bitmap, &bitmapPixels);
// TODO: Handle the case where lockPixels fails
SDL_Surface * inputSurface = SDL_CreateRGBSurfaceWithFormatFrom(
bitmapPixels,
bitmapInfo.width,
bitmapInfo.height,
32, // BPP. TODO: Infer from pixel format
4 * bitmapInfo.width, // Pitch. TODO: Infer from pixel format
SDL_PIXELFORMAT_ABGR8888
);
SDL_Surface * outputSurface = SDL_CreateRGBSurface(
0, // Flags. Unused.
bitmapInfo.width, // Width
bitmapInfo.height, // Height
32, // Bits per pixel
0, 0, 0, 0 // Default masks for the given depth
);
SDL_BlitSurface(inputSurface, NULL, outputSurface, NULL);
SDL_FreeSurface(inputSurface);
AndroidBitmap_unlockPixels(env, j_bitmap);
return outputSurface;
}

59
ion/src/sdl/display.cpp Normal file
View File

@@ -0,0 +1,59 @@
#include "display.h"
#include "keyboard.h"
#include <ion/display.h>
#include <SDL.h>
static KDColor sPixels[Ion::Display::Width * Ion::Display::Height];
namespace Ion {
namespace Display {
static KDFrameBuffer sFrameBuffer = KDFrameBuffer(sPixels, KDSize(Ion::Display::Width, Ion::Display::Height));
void pushRect(KDRect r, const KDColor * pixels) {
sFrameBuffer.pushRect(r, pixels);
}
void pushRectUniform(KDRect r, KDColor c) {
sFrameBuffer.pushRectUniform(r, c);
}
void pullRect(KDRect r, KDColor * pixels) {
sFrameBuffer.pullRect(r, pixels);
}
void waitForVBlank() {
}
}
}
namespace Ion {
namespace SDL {
namespace Display {
static SDL_Surface * sFramebufferSurface = nullptr;
void init() {
sFramebufferSurface = SDL_CreateRGBSurfaceWithFormatFrom(
sPixels,
Ion::Display::Width,
Ion::Display::Height,
16,
Ion::Display::Width * 2,
SDL_PIXELFORMAT_RGB565
);
}
void quit() {
SDL_FreeSurface(sFramebufferSurface);
sFramebufferSurface = nullptr;
}
void blit(SDL_Surface * dst, SDL_Rect * rect) {
SDL_BlitScaled(sFramebufferSurface, NULL, dst, rect);
}
}
}
}

20
ion/src/sdl/display.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef ION_SDL_DISPLAY_H
#define ION_SDL_DISPLAY_H
#include <kandinsky.h>
#include <SDL.h>
namespace Ion {
namespace SDL {
namespace Display {
void init();
void quit();
void blit(SDL_Surface * dst, SDL_Rect * rect);
}
}
}
#endif

43
ion/src/sdl/events.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "main.h"
#include "layout.h"
#include <ion/events.h>
#include <SDL.h>
namespace Ion {
namespace Events {
static bool needsRefresh = true;
Event getEvent(int * timeout) {
if (needsRefresh) {
Ion::SDL::Main::refresh();
needsRefresh = false;
}
SDL_Event event;
if (!SDL_WaitEventTimeout(&event, *timeout)) {
return None;
}
if (event.type == SDL_FINGERDOWN) {
SDL_FPoint fp;
fp.x = event.tfinger.x;
fp.y = event.tfinger.y;
Keyboard::Key key = SDL::Layout::keyAtF(&fp);
if (key == Keyboard::Key::None) {
return None;
}
needsRefresh = true;
Event event = Event(key, isShiftActive(), isAlphaActive());
return event;
}
return None;
}
}
}

5
ion/src/sdl/images.h Normal file
View File

@@ -0,0 +1,5 @@
// This shall be implemented per-platform
//
#include <SDL.h>
SDL_Surface * loadImage(const char * identifier);

63
ion/src/sdl/keyboard.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "keyboard.h"
#include <ion/keyboard.h>
#include <android/log.h>
#include "images.h"
#define APPNAME "MyApp"
namespace Ion {
namespace Keyboard {
State scan() {
return State(0);
}
}
}
namespace Ion {
namespace SDL {
namespace Keyboard {
using namespace Ion::Keyboard;
static SDL_Rect s_rect;
void init(SDL_Rect rect) {
s_rect = rect;
}
static SDL_Rect rectForKey(Key k) {
int i = static_cast<int>(k);
return {i%10, i/10, 10, 10};
}
void drawOnSurface(SDL_Surface * surface) {
for (int i=0; i<NumberOfValidKeys; i++) {
Key k = ValidKeys[i];
SDL_Rect r = rectForKey(k);
SDL_Rect scaledRect = {r.x * 32, r.y*24, 2, 2};
SDL_FillRect(surface, &scaledRect, SDL_MapRGB(surface->format, 0xFF, 0x00, 0xFF));
}
}
Key keyAt(SDL_Point p) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Looking up %dx%d", p.x, p.y);
for (int i=0; i<NumberOfValidKeys; i++) {
Key k = ValidKeys[i];
SDL_Rect r = rectForKey(k);
if (SDL_PointInRect(&p, &r)) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Got match at index %d", i);
return k;
}
}
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "No match");
return Key::None;
}
}
}
}

19
ion/src/sdl/keyboard.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef ION_SDL_KEYBOARD_H
#define ION_SDL_KEYBOARD_H
#include <kandinsky.h>
#include <SDL.h>
#include <ion/keyboard.h>
namespace Ion {
namespace SDL {
namespace Keyboard {
void drawOnSurface(SDL_Surface * surface);
Ion::Keyboard::Key keyAt(SDL_Point p);
}
}
}
#endif

121
ion/src/sdl/layout.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "layout.h"
namespace Ion {
namespace SDL {
namespace Layout {
#define X(x) ((x)/(1250.0f))
#define Y(y) ((y)/(2100.0f))
static int sWidth = 0;
static int sHeight = 0;
static void makeAbsolute(SDL_FRect * f, SDL_Rect * r) {
r->x = f->x * sWidth;
r->y = f->y * sHeight;
r->w = f->w * sWidth;
r->h = f->h * sHeight;
}
static void makeAbsolute(SDL_FPoint * f, SDL_Point * p) {
p->x = f->x * sWidth;
p->y = f->y * sHeight;
}
void setSize(int width, int height) {
sWidth = width;
sHeight = height;
}
void getScreenRect(SDL_Rect * rect) {
SDL_FRect fRect;
fRect.x = X(310);
fRect.y = Y(215);
fRect.w = X(640);
fRect.h = Y(485);
makeAbsolute(&fRect, rect);
}
Keyboard::Key keyAtF(SDL_FPoint * f) {
SDL_Point p;
makeAbsolute(f, &p);
return keyAt(&p);
}
Keyboard::Key keyAt(SDL_Point * p) {
for (int i=0; i<Keyboard::NumberOfValidKeys; i++) {
SDL_Rect r;
getKeyRect(i, &r);
if (SDL_PointInRect(p, &r)) {
return Keyboard::ValidKeys[i];
}
}
return Keyboard::Key::None;
}
void getKeyRect(int validKeyIndex, SDL_Rect * rect) {
assert(validKeyIndex >= 0);
assert(validKeyIndex < Keyboard::NumberOfValidKeys);
SDL_FRect rectForKey[Keyboard::NumberOfValidKeys] = {
{X(250), Y(880), X(85), Y(75) }, // A1, Left
{X(330), Y(795), X(75), Y(85) }, // A2, Up
{X(330), Y(950), X(75), Y(85) }, // A3, Down
{X(400), Y(880), X(85), Y(75) }, // A4, Right
{X(765), Y(855), X(110), Y(110)}, // A5, OK
{X(900), Y(855), X(110), Y(110)}, // A6, Back
{X(565), Y(815), X(130), Y(85)}, // B1, Home
{X(565), Y(920), X(130), Y(85)}, // B2, Power
{X(255), Y(1066), X(110), Y(75)}, // C1, Shift
{X(385), Y(1066), X(110), Y(75)}, // C2, Alpha
{X(512), Y(1066), X(110), Y(75)}, // C3, xnt
{X(638), Y(1066), X(110), Y(75)}, // C4, var
{X(768), Y(1066), X(110), Y(75)}, // C5, toolbox
{X(895), Y(1066), X(110), Y(75)}, // C6, Delete
{X(255), Y(1170), X(110), Y(75)}, // D1, exp
{X(385), Y(1170), X(110), Y(75)}, // D2, ln
{X(512), Y(1170), X(110), Y(75)}, // D3, log
{X(638), Y(1170), X(110), Y(75)}, // D4, i
{X(768), Y(1170), X(110), Y(75)}, // D5, comma
{X(895), Y(1170), X(110), Y(75)}, // D6, power
{X(255), Y(1272), X(110), Y(75)}, // E1, sin
{X(385), Y(1272), X(110), Y(75)}, // E2, cos
{X(512), Y(1272), X(110), Y(75)}, // E3, tan
{X(638), Y(1272), X(110), Y(75)}, // E4, pi
{X(768), Y(1272), X(110), Y(75)}, // E5, sqrt
{X(895), Y(1272), X(110), Y(75)}, // E6, square
{X(255), Y(1376), X(130), X(85)}, // F1, 7
{X(408), Y(1376), X(130), X(85)}, // F2, 8
{X(564), Y(1376), X(130), X(85)}, // F3, 9
{X(718), Y(1376), X(130), X(85)}, // F4, (
{X(872), Y(1376), X(130), X(85)}, // F5, )
{X(255), Y(1490), X(130), X(85)}, // G1, 4
{X(408), Y(1490), X(130), X(85)}, // G2, 5
{X(564), Y(1490), X(130), X(85)}, // G3, 6
{X(718), Y(1490), X(130), X(85)}, // G4, *
{X(872), Y(1490), X(130), X(85)}, // G5, /
{X(255), Y(1605), X(130), X(85)}, // H1, 1
{X(408), Y(1605), X(130), X(85)}, // H2, 2
{X(564), Y(1605), X(130), X(85)}, // H3, 3
{X(718), Y(1605), X(130), X(85)}, // H4, +
{X(872), Y(1605), X(130), X(85)}, // H5, -
{X(255), Y(1718), X(130), X(85)}, // I1, 0
{X(408), Y(1718), X(130), X(85)}, // I2, .
{X(564), Y(1718), X(130), X(85)}, // I3, x10
{X(718), Y(1718), X(130), X(85)}, // I4, Ans
{X(872), Y(1718), X(130), X(85)}, // I5, EXE
};
makeAbsolute(&rectForKey[validKeyIndex], rect);
}
}
}
}

23
ion/src/sdl/layout.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef ION_SDL_LAYOUT_H
#define ION_SDL_LAYOUT_H
#include <ion/keyboard.h>
#include <SDL.h>
namespace Ion {
namespace SDL {
namespace Layout {
void setSize(int w, int h);
void getScreenRect(SDL_Rect * rect);
Ion::Keyboard::Key keyAt(SDL_Point * p);
Ion::Keyboard::Key keyAtF(SDL_FPoint * p);
void getKeyRect(int validKeyIndex, SDL_Rect * rect);
}
}
}
#endif

78
ion/src/sdl/main.cpp Normal file
View File

@@ -0,0 +1,78 @@
#include "main.h"
#include "display.h"
#include <ion.h>
#include "images.h"
#include "layout.h"
#include <ion/timing.h>
#include <ion/events.h>
#include <SDL.h>
void Ion::Timing::msleep(unsigned int) {
// Do nothing!
}
int main(int argc, char * argv[]) {
Ion::SDL::Main::init();
ion_main(argc, argv);
//Ion::SDL::Main::quit();
return 0;
}
namespace Ion {
namespace SDL {
namespace Main {
static SDL_Window * sWindow = nullptr;
static SDL_Surface * sSurface = nullptr;
static SDL_Surface * sBackgroundSurface = nullptr;
void init() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
// Error...
return;
}
sWindow = SDL_CreateWindow(
"Epsilon",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
0, 0,
SDL_WINDOW_RESIZABLE
);
SDL_SetWindowFullscreen(sWindow, 0);
sSurface = SDL_GetWindowSurface(sWindow);
Display::init();
sBackgroundSurface = loadImage("background.jpg");
}
void relayout() {
int windowWidth = 0;
int windowHeight = 0;
SDL_GetWindowSize(sWindow, &windowWidth, &windowHeight);
Layout::setSize(windowWidth, windowHeight);
}
static void blitBackground(SDL_Rect * rect) {
SDL_BlitScaled(sBackgroundSurface, NULL, sSurface, rect);
}
void refresh() {
relayout();
SDL_Rect screenRect;
Layout::getScreenRect(&screenRect);
blitBackground(nullptr);
Display::blit(sSurface, &screenRect);
SDL_UpdateWindowSurface(sWindow);
}
}
}
}

17
ion/src/sdl/main.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef ION_SDL_MAIN_H
#define ION_SDL_MAIN_H
namespace Ion {
namespace SDL {
namespace Main {
void init();
void quit();
void refresh();
}
}
}
#endif