From 5a6dfaa8630ea8a81725e1af6483994febbd9ce8 Mon Sep 17 00:00:00 2001 From: pelya Date: Mon, 14 Mar 2011 17:33:58 +0200 Subject: [PATCH] Added Gun Bros-like controls to TeeWorlds, implemented SDL_WarpMouse() for relative mouse mode --- project/jni/application/src | 2 +- .../teeworlds/AndroidAppSettings.cfg | 6 +- .../teeworlds/src/engine/client/ec_gfx.cpp | 65 +++++++++++++------ .../teeworlds/src/engine/client/ec_inp.cpp | 44 ++++++++++++- .../src/video/android/SDL_androidinput.c | 8 +-- 5 files changed, 96 insertions(+), 29 deletions(-) diff --git a/project/jni/application/src b/project/jni/application/src index 92362c4db..299033683 120000 --- a/project/jni/application/src +++ b/project/jni/application/src @@ -1 +1 @@ -ufoai \ No newline at end of file +teeworlds \ No newline at end of file diff --git a/project/jni/application/teeworlds/AndroidAppSettings.cfg b/project/jni/application/teeworlds/AndroidAppSettings.cfg index bae4dea8c..161a549bb 100644 --- a/project/jni/application/teeworlds/AndroidAppSettings.cfg +++ b/project/jni/application/teeworlds/AndroidAppSettings.cfg @@ -1,5 +1,5 @@ # The application settings for Android libSDL port -AppSettingVersion=16 +AppSettingVersion=17 LibSdlVersion=1.2 AppName="TeeWorlds" AppFullName=com.teeworlds @@ -9,11 +9,12 @@ AppDataDownloadUrl="Game data is 8 Mb|http://sourceforge.net/projects/libsdl-and SdlVideoResize=n SdlVideoResizeKeepAspect=n NeedDepthBuffer=n +SwVideoMode=n AppUsesMouse=y AppNeedsTwoButtonMouse=y AppNeedsArrowKeys=y AppNeedsTextInput=y -AppUsesJoystick=n +AppUsesJoystick=y AppHandlesJoystickSensitivity=n AppUsesMultitouch=n NonBlockingSwapBuffers=n @@ -29,6 +30,5 @@ CustomBuildScript=n AppCflags='-O3' AppLdflags='' AppSubdirsBuild='' -AppUseCrystaXToolchain=n AppCmdline='' ReadmeText='^You may press "Home" now - the data will be downloaded in background' diff --git a/project/jni/application/teeworlds/src/engine/client/ec_gfx.cpp b/project/jni/application/teeworlds/src/engine/client/ec_gfx.cpp index 792f187f9..eb60402b1 100644 --- a/project/jni/application/teeworlds/src/engine/client/ec_gfx.cpp +++ b/project/jni/application/teeworlds/src/engine/client/ec_gfx.cpp @@ -108,7 +108,8 @@ static int first_free_texture; static int memory_usage = 0; static int active_texture = -1; -static SDL_Surface *screen_surface; +extern SDL_Surface *EC_screen_surface; +SDL_Surface *EC_screen_surface = NULL; static const unsigned char null_texture_data[] = { 0xff,0x00,0x00,0xff, 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0xff,0x00,0xff, @@ -291,6 +292,9 @@ static void add_vertices(int count) flush(); } +extern SDL_Joystick * EC_joystick; +SDL_Joystick * EC_joystick = NULL; + static int try_init() { const SDL_VideoInfo *info; @@ -311,50 +315,56 @@ static int try_init() if( ! SDL_ANDROID_GetScreenKeyboardRedefinedByUser() ) { // Disable DPAD - SDL_Rect pos = {0, 0, 0, 0}; - SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &pos); + SDL_Rect pos; - // Rope button in lower-right pos.x = screen_width; pos.y = screen_height; - pos.w = screen_width / 6; - pos.h = pos.w * 2 / 3; + pos.h = screen_height * 3 / 5; + pos.w = pos.h; pos.x -= pos.w; pos.y -= pos.h; - SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos); - - // Move and jump buttons overlapped in lower-left + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &pos); + + // Move buttons overlapped in lower-left pos.x = 0; pos.y = screen_height; - pos.w = screen_width / 8; - pos.h = pos.w*1.5; + pos.h = screen_height / 2; + pos.w = pos.h / 2; pos.y -= pos.h; SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &pos); pos.x += pos.w; + // Jump button overlaps move buttons SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &pos); pos.w *= 2; - pos.h = pos.w*2/3; + pos.h = pos.w/2; pos.x = 0; pos.y -= pos.h/2; SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &pos); + // Rope button below jump button + pos.y = 0; + pos.h = pos.h * 2 / 3; + pos.y = screen_height - pos.h; + + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos); + // weapprev weapnext buttons pos.x = screen_width; - pos.y = screen_height / 6; - pos.w = screen_width / 10; + pos.y = 0; + pos.w = screen_width / 8; pos.h = pos.w; pos.x -= pos.w; SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &pos); - pos.x = 0; + pos.x -= pos.w; SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &pos); @@ -400,13 +410,26 @@ static int try_init() SDL_WM_SetCaption("Teeworlds", "Teeworlds"); /* create window */ - screen_surface = SDL_SetVideoMode(screen_width, screen_height, 0, flags); - if(screen_surface == NULL) + EC_screen_surface = SDL_SetVideoMode(screen_width, screen_height, 0, flags); + if(EC_screen_surface == NULL) { dbg_msg("gfx", "unable to set video mode: %s", SDL_GetError()); return -1; } - +#ifdef ANDROID + dbg_msg("gfx", "Number of joysticks: %d", SDL_NumJoysticks()); + if(SDL_NumJoysticks() > 0) + { + dbg_msg("gfx", "Joystick 0: %s", SDL_JoystickName(0)); + EC_joystick = SDL_JoystickOpen(0); + if( EC_joystick ) + dbg_msg("gfx", "Opened joystick 0, numaxes %d numbuttons %d", SDL_JoystickNumAxes(EC_joystick), SDL_JoystickNumButtons(EC_joystick)); + else + dbg_msg("gfx", "Error opening joystick 0"); + SDL_JoystickEventState(SDL_ENABLE); + } +#endif + return 0; } @@ -463,7 +486,11 @@ int gfx_init() if(config.cl_eventthread) systems |= SDL_INIT_EVENTTHREAD; - + +#ifdef ANDROID + systems |= SDL_INIT_JOYSTICK; +#endif + if(SDL_Init(systems) < 0) { dbg_msg("gfx", "unable to init SDL: %s", SDL_GetError()); diff --git a/project/jni/application/teeworlds/src/engine/client/ec_inp.cpp b/project/jni/application/teeworlds/src/engine/client/ec_inp.cpp index 2ffc0e33a..b2f5644c0 100644 --- a/project/jni/application/teeworlds/src/engine/client/ec_inp.cpp +++ b/project/jni/application/teeworlds/src/engine/client/ec_inp.cpp @@ -6,6 +6,8 @@ #include #include +#include + static struct { unsigned char presses; @@ -20,6 +22,11 @@ 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; @@ -51,6 +58,23 @@ 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 @@ -144,6 +168,8 @@ 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; @@ -168,6 +194,7 @@ void inp_update() /* 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 */ @@ -175,7 +202,7 @@ void inp_update() 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; + if(i&SDL_BUTTON(8)) input_state[input_current][KEY_MOUSE_8] = 1; { SDL_Event event; @@ -221,6 +248,9 @@ void inp_update() /* other messages */ case SDL_QUIT: +#ifdef ANDROID + case SDL_VIDEORESIZE: +#endif /* TODO: cleaner exit */ exit(0); break; @@ -236,5 +266,17 @@ void inp_update() } } + + 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; } } diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c index 1b436e462..2c1277247 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c @@ -635,12 +635,10 @@ void SDL_ANDROID_WarpMouse(int x, int y) } else { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_WarpMouse(): %dx%d rel %dx%d old %dx%d", x, y, relativeMovementX, relativeMovementY, oldMouseX, oldMouseY); + relativeMovementX -= oldMouseX-x; + relativeMovementY -= oldMouseY-y; SDL_ANDROID_MainThreadPushMouseMotion(x, y); - // TODO: test and enable it - /* - relativeMovementX = x; - relativeMovementY = y; - */ } };