From 95e26f3e7b25f17a1b6e6484fcee3aee302f913c Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 23 Nov 2015 14:52:11 +0000 Subject: [PATCH] Start of mouse control integration. --- common.mk | 2 +- gfx/input/mousePointer.png | Bin 0 -> 314 bytes src/battle/player.c | 213 ++++++++++++++++++++++++------------- src/battle/player.h | 1 + src/defs.h | 1 + src/draw/draw.c | 2 + src/draw/draw.h | 1 + src/game/title.c | 2 + src/main.c | 12 +++ src/main.h | 3 + src/structs.h | 7 ++ src/system/init.c | 2 + src/system/init.h | 1 + src/system/input.c | 57 ++++++++++ src/system/input.h | 29 +++++ src/system/widgets.c | 25 ++++- src/system/widgets.h | 1 + 17 files changed, 286 insertions(+), 73 deletions(-) create mode 100644 gfx/input/mousePointer.png create mode 100644 src/system/input.c create mode 100644 src/system/input.h diff --git a/common.mk b/common.mk index 7c28016..a0fa1cb 100644 --- a/common.mk +++ b/common.mk @@ -24,7 +24,7 @@ OBJS += effects.o entities.o extractionPoint.o OBJS += fighters.o OBJS += galacticMap.o game.o grid.o OBJS += hud.o -OBJS += init.o io.o items.o +OBJS += init.o input.o io.o items.o OBJS += load.o lookup.o OBJS += main.o mission.o missionInfo.o OBJS += objectives.o options.o diff --git a/gfx/input/mousePointer.png b/gfx/input/mousePointer.png new file mode 100644 index 0000000000000000000000000000000000000000..c35dd9519c2ef39568f3cca79e4d68bab618b8c6 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkEth{j^=Hq_8BbEalive == ALIVE_ALIVE) { - if (app.keyboard[SDL_SCANCODE_LEFT]) - { - player->angle -= 4; - } + handleKeyboard(); - if (app.keyboard[SDL_SCANCODE_RIGHT]) - { - player->angle += 4; - } - - if (app.keyboard[SDL_SCANCODE_UP] && battle.boostTimer > BOOST_FINISHED_TIME) - { - applyFighterThrust(); - } - - if (app.keyboard[SDL_SCANCODE_DOWN]) - { - applyFighterBrakes(); - } - - if (battle.status == MS_IN_PROGRESS) - { - if (app.keyboard[SDL_SCANCODE_LCTRL] && !player->reload && player->guns[0].type) - { - fireGuns(player); - } - - if (app.keyboard[SDL_SCANCODE_LSHIFT]) - { - switchGuns(); - - app.keyboard[SDL_SCANCODE_LSHIFT] = 0; - } - - if (app.keyboard[SDL_SCANCODE_RETURN] && player->missiles && player->target) - { - if (getDistance(player->x, player->y, player->target->x, player->target->y) <= SCREEN_WIDTH) - { - fireMissile(player); - } - else - { - addHudMessage(colors.white, "Target not in range"); - } - - app.keyboard[SDL_SCANCODE_RETURN] = 0; - } - - if (!player->target || player->target->systemPower <= 0 || app.keyboard[SDL_SCANCODE_T]) - { - selectTarget(); - - app.keyboard[SDL_SCANCODE_T] = 0; - } - - if (app.keyboard[SDL_SCANCODE_SPACE] && battle.boostTimer == BOOST_RECHARGE_TIME) - { - playSound(SND_BOOST); - - activateBoost(); - } - - if (app.keyboard[SDL_SCANCODE_E] && battle.ecmTimer == ECM_RECHARGE_TIME) - { - activateECM(); - } - - if (!battle.missionTarget) - { - selectMissionTarget(); - } - } + handleMouse(); } player->angle = ((int)player->angle) % 360; @@ -166,6 +100,11 @@ void doPlayer(void) initPlayerSelect(); } } + + if (battle.status == MS_IN_PROGRESS) + { + selectMissionTarget(); + } } if (battle.boostTimer == (int)BOOST_FINISHED_TIME) @@ -174,6 +113,137 @@ void doPlayer(void) } } +static void handleKeyboard(void) +{ + if (app.keyboard[SDL_SCANCODE_LEFT]) + { + player->angle -= 4; + } + + if (app.keyboard[SDL_SCANCODE_RIGHT]) + { + player->angle += 4; + } + + if (app.keyboard[SDL_SCANCODE_UP] && battle.boostTimer > BOOST_FINISHED_TIME) + { + applyFighterThrust(); + } + + if (app.keyboard[SDL_SCANCODE_DOWN]) + { + applyFighterBrakes(); + } + + if (battle.status == MS_IN_PROGRESS) + { + if (app.keyboard[SDL_SCANCODE_LCTRL] && !player->reload && player->guns[0].type) + { + fireGuns(player); + } + + if (app.keyboard[SDL_SCANCODE_LSHIFT]) + { + switchGuns(); + + app.keyboard[SDL_SCANCODE_LSHIFT] = 0; + } + + if (app.keyboard[SDL_SCANCODE_RETURN] && player->missiles && player->target) + { + if (getDistance(player->x, player->y, player->target->x, player->target->y) <= SCREEN_WIDTH) + { + fireMissile(player); + } + else + { + addHudMessage(colors.white, "Target not in range"); + } + + app.keyboard[SDL_SCANCODE_RETURN] = 0; + } + + if (!player->target || player->target->systemPower <= 0 || app.keyboard[SDL_SCANCODE_T]) + { + selectTarget(); + + app.keyboard[SDL_SCANCODE_T] = 0; + } + + if (app.keyboard[SDL_SCANCODE_SPACE] && battle.boostTimer == BOOST_RECHARGE_TIME) + { + playSound(SND_BOOST); + + activateBoost(); + } + + if (app.keyboard[SDL_SCANCODE_E] && battle.ecmTimer == ECM_RECHARGE_TIME) + { + activateECM(); + } + } +} + +static void handleMouse(void) +{ + faceMouse(); + + if (battle.status == MS_IN_PROGRESS) + { + if (app.mouse.button[SDL_BUTTON_LEFT] && !player->reload && player->guns[0].type) + { + fireGuns(player); + } + + if (app.mouse.button[SDL_BUTTON_RIGHT]) + { + if (battle.boostTimer > BOOST_FINISHED_TIME) + { + applyFighterThrust(); + } + } + else + { + applyFighterBrakes(); + } + + if (app.mouse.button[SDL_BUTTON_MIDDLE] && player->missiles && player->target) + { + if (getDistance(player->x, player->y, player->target->x, player->target->y) <= SCREEN_WIDTH) + { + fireMissile(player); + } + else + { + addHudMessage(colors.white, "Target not in range"); + } + + app.mouse.button[SDL_BUTTON_MIDDLE] = 0; + } + } +} + +static void faceMouse(void) +{ + int dir; + int x, y, wantedAngle; + + x = player->x - battle.camera.x; + y = player->y - battle.camera.y; + wantedAngle = getAngle(x, y, app.mouse.x, app.mouse.y); + + wantedAngle %= 360; + + if (fabs(wantedAngle - player->angle) > 2) + { + dir = ((int)(wantedAngle - player->angle + 360)) % 360 > 180 ? -1 : 1; + + player->angle += dir * 4; + + player->angle = mod(player->angle, 360); + } +} + void initPlayerSelect(void) { Entity *e; @@ -305,6 +375,7 @@ static void selectTarget(void) Entity *targets[MAX_SELECTABLE_TARGETS]; i = 0; + near = NULL; memset(targets, 0, sizeof(Entity*) * MAX_SELECTABLE_TARGETS); for (e = battle.entityHead.next ; e != NULL ; e = e->next) diff --git a/src/battle/player.h b/src/battle/player.h index e89da11..eb0f9f1 100644 --- a/src/battle/player.h +++ b/src/battle/player.h @@ -35,6 +35,7 @@ extern void addHudMessage(SDL_Color c, char *format, ...); extern int mod(int n, int x); extern void playSound(int id); extern void failMission(void); +extern float getAngle(int x1, int y1, int x2, int y2); extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2); extern App app; diff --git a/src/defs.h b/src/defs.h index 743fe04..ed581a1 100644 --- a/src/defs.h +++ b/src/defs.h @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SCREEN_HEIGHT 720 #define MAX_KEYBOARD_KEYS 350 +#define MAX_MOUSE_BUTTONS 8 #define FPS 60 #define LOGIC_RATE (1000 / FPS) diff --git a/src/draw/draw.c b/src/draw/draw.c index d9276ce..326d389 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -50,6 +50,8 @@ void presentScene(void) drawText(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 25, 14, TA_CENTER, colors.white, "FPS: %d", app.fps); #endif + drawMouse(); + SDL_SetRenderTarget(app.renderer, NULL); SDL_RenderCopy(app.renderer, app.backBuffer, NULL, NULL); SDL_RenderPresent(app.renderer); diff --git a/src/draw/draw.h b/src/draw/draw.h index 8791ac1..41d33cd 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../structs.h" extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...); +extern void drawMouse(void); extern App app; extern Colors colors; diff --git a/src/game/title.c b/src/game/title.c index daf64df..9c043cf 100644 --- a/src/game/title.c +++ b/src/game/title.c @@ -90,6 +90,8 @@ void initTitle(void) endSectionTransition(); + SDL_WarpMouseInWindow(app.window, SCREEN_WIDTH / 2, SCREEN_HEIGHT - 100); + playMusic("music/Rise of spirit.ogg"); } diff --git a/src/main.c b/src/main.c index df0a305..65d0d6c 100644 --- a/src/main.c +++ b/src/main.c @@ -62,6 +62,18 @@ int main(int argc, char *argv[]) { switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + doMouseDown(&event.button); + break; + + case SDL_MOUSEBUTTONUP: + doMouseUp(&event.button); + break; + + case SDL_MOUSEMOTION: + doMouseMove(&event.motion); + break; + case SDL_KEYDOWN: if (event.key.keysym.scancode >= 0 && event.key.keysym.scancode < MAX_KEYBOARD_KEYS) { diff --git a/src/main.h b/src/main.h index d4b7a1a..3638522 100644 --- a/src/main.h +++ b/src/main.h @@ -31,6 +31,9 @@ extern void initGameSystem(void); extern void initTitle(void); extern void loadTestMission(char *filename); extern void saveScreenshot(void); +extern void doMouseDown(SDL_MouseButtonEvent *event); +extern void doMouseUp(SDL_MouseButtonEvent *event); +extern void doMouseMove(SDL_MouseMotionEvent *event); App app; Colors colors; diff --git a/src/structs.h b/src/structs.h index c15327c..f78707c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -290,6 +290,12 @@ struct HudMessage { HudMessage *next; }; +typedef struct { + int x; + int y; + int button[MAX_MOUSE_BUTTONS]; +} Mouse; + typedef struct { char saveDir[MAX_FILENAME_LENGTH]; int winWidth; @@ -301,6 +307,7 @@ typedef struct { int soundVolume; int vSync; int fps; + Mouse mouse; int keyboard[MAX_KEYBOARD_KEYS]; SDL_Texture *backBuffer; SDL_Renderer *renderer; diff --git a/src/system/init.c b/src/system/init.c index 0b2d4a0..2870687 100644 --- a/src/system/init.c +++ b/src/system/init.c @@ -138,6 +138,8 @@ void initGameSystem(void) initColor(&colors.lightGrey, 192, 192, 192); initColor(&colors.darkGrey, 128, 128, 128); + initInput(); + initLookups(); initFonts(); diff --git a/src/system/init.h b/src/system/init.h index 285a52d..5927a0c 100644 --- a/src/system/init.h +++ b/src/system/init.h @@ -61,6 +61,7 @@ extern void destroyTextures(void); extern void destroyGalacticMap(void); extern void destroyWidgets(void); extern void expireTexts(void); +extern void initInput(void); extern App app; extern Colors colors; diff --git a/src/system/input.c b/src/system/input.c new file mode 100644 index 0000000..7a66163 --- /dev/null +++ b/src/system/input.c @@ -0,0 +1,57 @@ +/* +Copyright (C) 2015 Parallel Realities + +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. + +*/ + +#include "input.h" + +static SDL_Texture *mousePointer; + +void initInput(void) +{ + memset(&app.mouse, 0, sizeof(Mouse)); + + mousePointer = getTexture("gfx/input/mousePointer.png"); +} + +void doMouseDown(SDL_MouseButtonEvent *event) +{ + app.mouse.button[event->button] = 1; +} + +void doMouseUp(SDL_MouseButtonEvent *event) +{ + app.mouse.button[event->button] = 0; +} + +void doMouseMove(SDL_MouseMotionEvent *event) +{ + +} + +void drawMouse(void) +{ + int x, y; + + SDL_GetMouseState(&x, &y); + + app.mouse.x = x * app.scaleX; + app.mouse.y = y * app.scaleY; + + blit(mousePointer, app.mouse.x, app.mouse.y, 1); +} diff --git a/src/system/input.h b/src/system/input.h new file mode 100644 index 0000000..977e4a3 --- /dev/null +++ b/src/system/input.h @@ -0,0 +1,29 @@ +/* +Copyright (C) 2015 Parallel Realities + +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. + +*/ + +#include "SDL2/SDL.h" + +#include "../defs.h" +#include "../structs.h" + +extern SDL_Texture *getTexture(char *filename); +extern void blit(SDL_Texture *texture, int x, int y, int centered); + +extern App app; diff --git a/src/system/widgets.c b/src/system/widgets.c index 41d03d3..7dbdab2 100644 --- a/src/system/widgets.c +++ b/src/system/widgets.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void loadWidgets(char *filename); static void loadWidgetSet(char *filename); static void handleKeyboard(void); +static void handleMouse(void); static void createOptions(Widget *w, char *options); static Widget head; @@ -53,6 +54,8 @@ void doWidgets(void) if (drawingWidgets) { handleKeyboard(); + + handleMouse(); } drawingWidgets = 0; @@ -82,6 +85,7 @@ void selectWidget(const char *name, const char *group) void drawWidgets(const char *group) { + int mouseOver; Widget *w; drawingWidgets = 1; @@ -90,6 +94,14 @@ void drawWidgets(const char *group) { if (w->visible && strcmp(w->group, group) == 0) { + mouseOver = (w->enabled && collision(w->rect.x, w->rect.y, w->rect.w, w->rect.h, app.mouse.x, app.mouse.y, 1, 1)); + + if (mouseOver && selectedWidget != w) + { + playSound(SND_GUI_CLICK); + selectedWidget = w; + } + SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderFillRect(app.renderer, &w->rect); @@ -261,13 +273,24 @@ static void handleKeyboard(void) if (app.keyboard[SDL_SCANCODE_RETURN] && selectedWidget->action) { playSound(SND_GUI_SELECT); - selectedWidget->action(); } memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS); } +static void handleMouse(void) +{ + if (selectedWidget && selectedWidget->action && app.mouse.button[SDL_BUTTON_LEFT]) + { + if (collision(selectedWidget->rect.x, selectedWidget->rect.y, selectedWidget->rect.w, selectedWidget->rect.h, app.mouse.x, app.mouse.y, 1, 1)) + { + playSound(SND_GUI_SELECT); + selectedWidget->action(); + } + } +} + static void loadWidgets(char *filename) { cJSON *root, *node; diff --git a/src/system/widgets.h b/src/system/widgets.h index bc9ca06..5e198d4 100644 --- a/src/system/widgets.h +++ b/src/system/widgets.h @@ -31,6 +31,7 @@ extern int getDistance(int x1, int y1, int x2, int y2); extern int mod(int n, int x); extern void blit(SDL_Texture *texture, int x, int y, int centered); extern SDL_Texture *getTexture(char *filename); +extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2); extern void playSound(int id); extern App app;