Optional free axis mode
This commit is contained in:
parent
d8ceb05757
commit
4754e6c76e
11 changed files with 94 additions and 14 deletions
|
@ -42,6 +42,7 @@ ConfigEntry configdefs[] = {
|
|||
{CFGT_INT, GAMEPAD_AXIS_UD, "gamepad_axis_ud"},
|
||||
{CFGT_INT, GAMEPAD_AXIS_LR, "gamepad_axis_lr"},
|
||||
{CFGT_INT, GAMEPAD_AXIS_THRESHOLD, "gamepad_axis_threshold"},
|
||||
{CFGT_INT, GAMEPAD_AXIS_FREE, "gamepad_axis_free"},
|
||||
|
||||
// gamepad controls
|
||||
{CFGT_INT, GP_UP, "gamepad_key_up"},
|
||||
|
@ -67,6 +68,7 @@ ConfigEntry* config_findentry(char *name) {
|
|||
|
||||
void config_preset(void) {
|
||||
memset(tconfig.strval, 0, sizeof(tconfig.strval));
|
||||
memset(tconfig.intval, 0, sizeof(tconfig.intval));
|
||||
|
||||
tconfig.intval[KEY_UP] = SDLK_UP;
|
||||
tconfig.intval[KEY_DOWN] = SDLK_DOWN;
|
||||
|
|
|
@ -57,6 +57,7 @@ typedef enum ConfigKey {
|
|||
GAMEPAD_AXIS_UD,
|
||||
GAMEPAD_AXIS_LR,
|
||||
GAMEPAD_AXIS_THRESHOLD,
|
||||
GAMEPAD_AXIS_FREE,
|
||||
|
||||
// gamepad controls
|
||||
// The UDLR ones should work without adjusting - but you can assign custom buttons to them if you really need to
|
||||
|
|
|
@ -38,6 +38,8 @@ typedef enum {
|
|||
// EF_Game
|
||||
E_PlrKeyDown,
|
||||
E_PlrKeyUp,
|
||||
E_PlrAxisUD,
|
||||
E_PlrAxisLR,
|
||||
E_Pause
|
||||
} EventType;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "taisei_err.h"
|
||||
#include "config.h"
|
||||
#include "events.h"
|
||||
#include "global.h"
|
||||
|
||||
static struct {
|
||||
int initialized;
|
||||
|
@ -85,8 +86,20 @@ int gamepad_axis2menuevt(int id, int val) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void gamepad_axis(int id, int val, EventHandler handler, EventFlags flags, void *arg) {
|
||||
int *a = gamepad.axis;
|
||||
int gamepad_axis2gameevt(int id) {
|
||||
if(id == tconfig.intval[GAMEPAD_AXIS_LR])
|
||||
return E_PlrAxisLR;
|
||||
|
||||
if(id == tconfig.intval[GAMEPAD_AXIS_UD])
|
||||
return E_PlrAxisUD;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gamepad_axis(int id, int raw, EventHandler handler, EventFlags flags, void *arg) {
|
||||
int *a = gamepad.axis;
|
||||
int val = AXISVAL(raw);
|
||||
int free = tconfig.intval[GAMEPAD_AXIS_FREE];
|
||||
|
||||
int menu = flags & EF_Menu;
|
||||
int game = flags & EF_Game;
|
||||
|
@ -96,11 +109,19 @@ void gamepad_axis(int id, int val, EventHandler handler, EventFlags flags, void
|
|||
return;
|
||||
}
|
||||
|
||||
printf("axis: %i %i %i\n", id, val, raw);
|
||||
|
||||
if(game && free) {
|
||||
int evt = gamepad_axis2gameevt(id);
|
||||
if(evt >= 0)
|
||||
handler(evt, raw, arg);
|
||||
}
|
||||
|
||||
if(val) { // simulate press
|
||||
if(!a[id]) {
|
||||
a[id] = val;
|
||||
|
||||
if(game) {
|
||||
if(game && !free) {
|
||||
int key = gamepad_axis2gamekey(id, val);
|
||||
if(key >= 0)
|
||||
handler(E_PlrKeyDown, key, arg);
|
||||
|
@ -164,10 +185,8 @@ void gamepad_event(SDL_Event *event, EventHandler handler, EventFlags flags, voi
|
|||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
val = event->jaxis.value;
|
||||
if(val < -sens || val > sens || !val) {
|
||||
printf("Axis: %i %i\n", event->jaxis.axis, val);
|
||||
gamepad_axis(event->jaxis.axis, AXISVAL(val), handler, flags, arg);
|
||||
}
|
||||
if(val < -sens || val > sens || !val)
|
||||
gamepad_axis(event->jaxis.axis, val, handler, flags, arg);
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP:
|
||||
|
|
|
@ -27,6 +27,7 @@ enum {
|
|||
};
|
||||
|
||||
#define GAMEPAD_AXES 16
|
||||
#define AXISVAL(x) ((x > 0) - (x < 0))
|
||||
#define GAMEPAD_AXIS_RANGE 32767
|
||||
#define AXISVAL SIGN
|
||||
|
||||
#endif
|
||||
|
|
|
@ -152,11 +152,15 @@ int strendswith(char *s, char *e);
|
|||
char* difficulty_name(Difficulty diff);
|
||||
void stralloc(char **dest, char *src);
|
||||
|
||||
#define SIGN(x) ((x > 0) - (x < 0))
|
||||
|
||||
// this is used by both player and replay code
|
||||
enum {
|
||||
EV_PRESS,
|
||||
EV_RELEASE,
|
||||
EV_OVER // replay-only
|
||||
EV_OVER, // replay-only
|
||||
EV_AXIS_LR,
|
||||
EV_AXIS_UD,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
41
src/player.c
41
src/player.c
|
@ -291,13 +291,47 @@ void player_event(Player* plr, int type, int key) {
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
case EV_AXIS_LR:
|
||||
plr->axis_lr = key;
|
||||
break;
|
||||
|
||||
case EV_AXIS_UD:
|
||||
plr->axis_ud = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// free-axis movement
|
||||
int player_applymovement_gamepad(Player *plr) {
|
||||
if(!plr->axis_lr && !plr->axis_ud)
|
||||
return False;
|
||||
|
||||
complex direction = (plr->axis_lr + plr->axis_ud*I) / (double)GAMEPAD_AXIS_RANGE;
|
||||
//if(cabs(direction))
|
||||
// direction /= cabs(direction);
|
||||
|
||||
double real = creal(direction);
|
||||
double imag = cimag(direction);
|
||||
int sr = SIGN(real);
|
||||
int si = SIGN(imag);
|
||||
|
||||
player_setmoveflag(plr, KEY_UP, si == -1);
|
||||
player_setmoveflag(plr, KEY_DOWN, si == 1);
|
||||
player_setmoveflag(plr, KEY_LEFT, sr == -1);
|
||||
player_setmoveflag(plr, KEY_RIGHT, sr == 1);
|
||||
|
||||
if(direction)
|
||||
player_move(&global.plr, direction);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
void player_applymovement(Player* plr) {
|
||||
if(plr->deathtime < -1)
|
||||
return;
|
||||
|
||||
int gamepad = player_applymovement_gamepad(plr);
|
||||
plr->moving = False;
|
||||
|
||||
int up = plr->moveflags & MOVEFLAG_UP,
|
||||
|
@ -311,7 +345,10 @@ void player_applymovement(Player* plr) {
|
|||
} else if(right && !left) {
|
||||
plr->moving = True;
|
||||
plr->dir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(gamepad)
|
||||
return;
|
||||
|
||||
complex direction = 0;
|
||||
|
||||
|
@ -319,7 +356,7 @@ void player_applymovement(Player* plr) {
|
|||
if(down) direction += 1I;
|
||||
if(left) direction -= 1;
|
||||
if(right) direction += 1;
|
||||
|
||||
|
||||
if(cabs(direction))
|
||||
direction /= cabs(direction);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <complex.h>
|
||||
#include "enemy.h"
|
||||
|
||||
#include "gamepad.h"
|
||||
#include "resource/animation.h"
|
||||
|
||||
enum {
|
||||
|
@ -65,6 +65,9 @@ typedef struct {
|
|||
int movetime;
|
||||
int prevmove;
|
||||
int prevmovetime;
|
||||
|
||||
int axis_ud;
|
||||
int axis_lr;
|
||||
} Player;
|
||||
|
||||
void init_player(Player*);
|
||||
|
|
|
@ -89,7 +89,7 @@ void replay_event(Replay *rpy, int type, int key) {
|
|||
ReplayEvent *e = &(s->events[s->ecount]);
|
||||
e->frame = global.frames;
|
||||
e->type = (char)type;
|
||||
e->key = (char)key;
|
||||
e->key = (short)key;
|
||||
s->ecount++;
|
||||
|
||||
if(s->ecount >= s->capacity) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
typedef struct ReplayEvent {
|
||||
int frame;
|
||||
char type;
|
||||
char key;
|
||||
short key;
|
||||
} ReplayEvent;
|
||||
|
||||
typedef struct ReplayStage {
|
||||
|
|
11
src/stage.c
11
src/stage.c
|
@ -86,6 +86,16 @@ void stage_input_event(EventType type, int key, void *arg) {
|
|||
stage_ingamemenu();
|
||||
break;
|
||||
|
||||
case E_PlrAxisLR:
|
||||
player_event(&global.plr, EV_AXIS_LR, key);
|
||||
replay_event(&global.replay, EV_AXIS_LR, key);
|
||||
break;
|
||||
|
||||
case E_PlrAxisUD:
|
||||
player_event(&global.plr, EV_AXIS_UD, key);
|
||||
replay_event(&global.replay, EV_AXIS_UD, key);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -477,6 +487,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
|
|||
|
||||
player_set_power(&global.plr, power);
|
||||
global.plr.movetime = global.plr.prevmove = global.plr.prevmovetime = 0;
|
||||
global.plr.axis_lr = global.plr.axis_ud = 0;
|
||||
|
||||
start();
|
||||
|
||||
|
|
Loading…
Reference in a new issue