Donnerstag, 11. Februar 2021

reBounce - softfp-to-hardfp LD_PRELOAD hack for Bounce on N9

This depends on Bounce (the N900 .deb) and SDL 1.2 being installed. Google "bounce_1.0.0_armel.deb" for the former, and use n9repomirror for the latter.

This is available on OpenRepos: https://openrepos.net/content/thp/rebounce

Source code (copy'n'paste this into a file named "rebounce.c", then run it using your shell):

#if 0

gcc -Os -shared -fPIC -lSDL -o librebounce.so rebounce.c

LD_PRELOAD=$(pwd)/librebounce.so /opt/bounce/bin/bounce

exit 0

#endif


/**

 * reBounce -- softfp-to-hardfp LD_PRELOAD hack for Bounce on N9

 *

 * Bounce was a really nice 2009 tech demo on the N900. This

 * makes this tech demo work on an N9 by translating the calls

 * that use floating point arguments to the hardfp ABI. It also

 * fixes input using SDL1.2 to get sensor values from sensorfw.

 *

 * Known issues: Audio is muted on startup until mute is toggled.

 *

 * 2021-02-11 Thomas Perl <m@thp.io>

 **/


#define _GNU_SOURCE


#include <stdio.h>

#include <dlfcn.h>

#include <pthread.h>

#include <SDL/SDL.h>


#define SFP __attribute__((pcs("aapcs")))


typedef unsigned int GLuint;


static void *

sensor_thread(void *user_data)

{

    SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);


    SDL_Joystick *accelerometer = SDL_JoystickOpen(0);


    while (1) {

        SDL_JoystickUpdate();


        float x = 0.053888f * SDL_JoystickGetAxis(accelerometer, 0);

        float y = 0.053888f * SDL_JoystickGetAxis(accelerometer, 1);

        float z = 0.053888f * SDL_JoystickGetAxis(accelerometer, 2);


        FILE *out = fopen("/dev/shm/bounce.sensor.tmp", "wb");

        fprintf(out, "%f %f %f\n", -y, x, z);

        fclose(out);

        rename("/dev/shm/bounce.sensor.tmp", "/dev/shm/bounce.sensor");


        SDL_Delay(10);

    }


    return NULL;

}


FILE *

fopen(const char *filename, const char *mode)

{

    FILE *(*fopen_orig)(const char *, const char *) = dlsym(RTLD_NEXT, "fopen");

    if (strcmp(filename, "/sys/class/i2c-adapter/i2c-3/3-001d/coord") == 0) {

        static int sensor_inited = 0;

        if (!sensor_inited) {

            sensor_inited = 1;


            pthread_t thread;

            pthread_create(&thread, NULL, sensor_thread, NULL);

        }


        filename = "/dev/shm/bounce.sensor";

    }


    return fopen_orig(filename, mode);

}


#define f_f(name) float SFP name(float x) { return ((float (*)(float))dlsym(RTLD_NEXT, #name))(x); }

#define d_d(name) double SFP name(double x) { return ((double (*)(double))dlsym(RTLD_NEXT, #name))(x); }

#define f_ff(name) float SFP name(float x, float y) { return ((float (*)(float, float))dlsym(RTLD_NEXT, #name))(x, y); }

#define d_dd(name) double SFP name(double x, double y) { return ((double (*)(double, double))dlsym(RTLD_NEXT, #name))(x, y); }


f_f(sinhf) f_f(coshf) f_f(tanhf) f_f(asinf) f_f(acosf) f_f(atanf) f_f(sinf) f_f(cosf) f_f(tanf) f_f(expf) f_f(logf)

f_f(log10f) f_f(ceilf) f_f(floorf) d_d(log) d_d(sin) f_ff(atan2f) f_ff(fmodf) d_dd(atan2) d_dd(pow) d_dd(fmod)


double SFP

frexp(double value, int *exp)

{

    return ((double (*)(double, int *))dlsym(RTLD_NEXT, "frexp"))(value, exp);

}


double SFP

ldexp(double x, int n)

{

    return ((double (*)(double, int))dlsym(RTLD_NEXT, "ldexp"))(x, n);

}


double SFP

modf(double value, double *iptr)

{

    return ((double (*)(double, double *))dlsym(RTLD_NEXT, "modf"))(value, iptr);

}


void SFP

glClearColor(float r, float g, float b, float a)

{

    ((void (*)(float, float, float, float))dlsym(RTLD_NEXT, "glClearColor"))(r, g, b, a);

}


void SFP

glUniform4f(GLuint location, float v0, float v1, float v2, float v3)

{

    ((void (*)(GLuint, float, float, float, float))dlsym(RTLD_NEXT, "glUniform4f"))(location, v0, v1, v2, v3);

}


void SFP

glUniform1f(GLuint location, float v0)

{

    ((void (*)(GLuint, float))dlsym(RTLD_NEXT, "glUniform1f"))(location, v0);

}


Keine Kommentare: