From 8881dc526502a1c12f219ef8c9468bbff9f2693d Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Wed, 6 Mar 2013 20:17:14 +0000
Subject: [PATCH] [Add] Keybord events work with lists. I think I optimized
 pilots to use temp sprite values here too. Forgot to diff.

---
 README         |  4 +--
 src/input.c    |  4 +--
 src/lephisto.c |  1 +
 src/pilot.c    | 12 +++----
 src/pilot.h    |  1 +
 src/toolkit.c  | 94 ++++++++++++++++++++++++++++++++++++++++++++++++--
 src/toolkit.h  |  1 +
 src/weapon.c   |  5 +--
 8 files changed, 107 insertions(+), 15 deletions(-)

diff --git a/README b/README
index 1fb0c9d..b0144b6 100644
--- a/README
+++ b/README
@@ -109,8 +109,8 @@ Keys:
 		-- 'j' : Jump through hyperspace.
 
   GUI:
-    -- UP   : Zoom in.
-    -- DOWN : Zoom out.
+    -- '0'  : Zoom in.
+    -- '9' 	: Zoom out.
     -- F12  : Take a screenshot.
 		-- ESC  : Menu.
 		-- 'i'	: Opens the character information window.
diff --git a/src/input.c b/src/input.c
index 432e99c..3a7ef02 100644
--- a/src/input.c
+++ b/src/input.c
@@ -61,8 +61,8 @@ void input_setDefault(void) {
   input_setKeybind("jump",            KEYBIND_KEYBOARD, SDLK_j,       0);
 
   // Misc.
-  input_setKeybind("mapzoomin",       KEYBIND_KEYBOARD, SDLK_UP,      0);
-  input_setKeybind("mapzoomout",      KEYBIND_KEYBOARD, SDLK_DOWN,    0);
+  input_setKeybind("mapzoomin",       KEYBIND_KEYBOARD, SDLK_0,      	0);
+  input_setKeybind("mapzoomout",      KEYBIND_KEYBOARD, SDLK_9,    		0);
   input_setKeybind("screenshot",      KEYBIND_KEYBOARD, SDLK_F12,     0);
   input_setKeybind("pause",           KEYBIND_KEYBOARD, SDLK_F1,      0);
   input_setKeybind("menu",            KEYBIND_KEYBOARD, SDLK_ESCAPE,  0);
diff --git a/src/lephisto.c b/src/lephisto.c
index 1f51cb5..790fcb7 100644
--- a/src/lephisto.c
+++ b/src/lephisto.c
@@ -189,6 +189,7 @@ int main(int argc, char** argv) {
     glClear(GL_COLOR_BUFFER_BIT);
     
     fps_control(); // Who doesn't love FPS control?
+		toolkit_update(); // Simulate key repetition.
     if(!paused && !toolkit) update_space(); // Update the game.
 
     render_space();
diff --git a/src/pilot.c b/src/pilot.c
index c492abb..f9ac555 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -260,12 +260,9 @@ void pilot_setAmmo(Pilot* p) {
 
 // Render the pilot.
 void pilot_render(Pilot* p) {
-  int sx, sy;
-
-  // Get the sprite corresponding to the direction facing.
-  gl_getSpriteFromDir(&sx, &sy, p->ship->gfx_space, p->solid->dir);
-
-  gl_blitSprite(p->ship->gfx_space, p->solid->pos.x, p->solid->pos.y,  sx, sy, NULL);
+  gl_blitSprite(p->ship->gfx_space,
+				p->solid->pos.x, p->solid->pos.y,
+				p->tsx, p->tsy, NULL);
 }
 
 // Update the pilot.
@@ -320,6 +317,8 @@ static void pilot_update(Pilot* pilot, const double dt) {
 
     // Update the solid.
     pilot->solid->update(pilot->solid, dt);
+		gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
+					pilot->ship->gfx_space, pilot->solid->dir);
     return;
   }
   // We are still alive.
@@ -333,6 +332,7 @@ static void pilot_update(Pilot* pilot, const double dt) {
 
   // Update the solid.
   (*pilot->solid->update)(pilot->solid, dt);
+	gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy, pilot->ship->gfx_space, pilot->solid->dir);
   
   if(!pilot_isFlag(pilot, PILOT_HYPERSPACE))
     // Should not go faster.
diff --git a/src/pilot.h b/src/pilot.h
index e0b01dc..c194b35 100644
--- a/src/pilot.h
+++ b/src/pilot.h
@@ -58,6 +58,7 @@ typedef struct Pilot_ {
   // Object characteristics.
   Ship* ship;     // Pilots ship.
   Solid* solid;   // Associated solid (physics).
+	int tsx, tsy;		// Current sprite, calculated on update.
 
   // Current health.
   double armour, shield, energy;
diff --git a/src/toolkit.c b/src/toolkit.c
index d7e5feb..89fae18 100644
--- a/src/toolkit.c
+++ b/src/toolkit.c
@@ -1,8 +1,12 @@
+#include "lephisto.h"
 #include "log.h"
 #include "pause.h"
 #include "opengl.h"
 #include "toolkit.h"
 
+#define INPUT_DELAY		500
+#define INPUT_FREQ		100
+
 typedef enum WidgetType_ {
   WIDGET_NULL,
   WIDGET_BUTTON,
@@ -85,6 +89,8 @@ static void toolkit_mouseEvent(SDL_Event* event);
 static int toolkit_keyEvent(SDL_Event* event);
 static void toolkit_nextFocus(void);
 static void toolkit_triggerFocus(void);
+static Widget* toolkit_getFocus(void);
+static void toolkit_listScroll(Widget* wgt, int direction);
 // Render.
 static void window_render(Window* w);
 static void toolkit_renderButton(Widget* btn, double bx, double by);
@@ -690,7 +696,7 @@ static void toolkit_renderList(Widget* lst, double bx, double by) {
 	toolkit_drawOutline(x, y, lst->w, lst->h, 1., oc, NULL);
 
 	// Draw selected.
-	toolkit_drawRect(x, y-1.+lst->h-(1+lst->dat.lst.selected-lst->dat.lst.pos)*(gl_defFont.h+3.),
+	toolkit_drawRect(x, y-1.+lst->h-(1+lst->dat.lst.selected-lst->dat.lst.pos)*(gl_defFont.h+2.),
 				lst->w, gl_defFont.h+2., &cHilight, NULL);
 
 	// Draw content.
@@ -780,7 +786,8 @@ static void toolkit_mouseEvent(SDL_Event* event) {
           break;
         case SDL_MOUSEBUTTONDOWN:
           wgt->status = WIDGET_STATUS_MOUSEDOWN;
-          break;
+          w->focus = i;
+					break;
         case SDL_MOUSEBUTTONUP:
           if(wgt->status == WIDGET_STATUS_MOUSEDOWN) {
 						if(wgt->type == WIDGET_BUTTON) {
@@ -800,6 +807,25 @@ static void toolkit_mouseEvent(SDL_Event* event) {
 }
 
 // Handle the key events.
+static SDLKey input_key;
+static unsigned int input_keyTime;
+static int input_keyCounter;
+static void toolkit_regKey(SDLKey key) {
+	if((input_key == 0) && (input_keyTime == 0)) {
+		input_key = key;
+		input_keyTime = SDL_GetTicks();
+		input_keyCounter = 0;
+	}
+}
+
+static void toolkit_unregKey(SDLKey key) {
+	if(input_key == key) {
+		input_key = 0;
+		input_keyTime = 0;
+		input_keyCounter = 0;
+	}
+}
+
 static int toolkit_keyEvent(SDL_Event* event) {
 	SDLKey key = event->key.keysym.sym;
 	switch(key) {
@@ -812,14 +838,51 @@ static int toolkit_keyEvent(SDL_Event* event) {
 				toolkit_triggerFocus();
 			return 1;
 		case SDLK_UP:
+			if(event->type == SDL_KEYDOWN) {
+				toolkit_regKey(SDLK_UP);
+				toolkit_listScroll(toolkit_getFocus(), +1);
+			}
+			else if(event->type == SDL_KEYUP)
+				toolkit_unregKey(SDLK_UP);
+			printf("Key Up\n");
+			return 0;
 		case SDLK_DOWN:
-			// TODO: list up/down.
+			if(event->type == SDL_KEYDOWN) {
+				toolkit_regKey(SDLK_DOWN);
+				toolkit_listScroll(toolkit_getFocus(), -1);
+			}
+			else if(event->type == SDL_KEYUP)
+				toolkit_unregKey(SDLK_DOWN);
+			printf("Key Down\n");
 			return 0;
 		default:
 			return 0;
 	}
 }
 
+void toolkit_update(void) {
+	unsigned int t;
+
+	t = SDL_GetTicks();
+
+	if(input_key == 0) return;
+
+	if(input_keyTime + INPUT_DELAY + input_keyCounter*INPUT_FREQ > t)
+		return;
+
+	input_keyCounter++;
+	switch(input_key) {
+		case SDLK_UP:
+			toolkit_listScroll(toolkit_getFocus(), +1);
+			break;
+		case SDLK_DOWN:
+			toolkit_listScroll(toolkit_getFocus(), -1);
+			break;
+		default:
+			break;
+	}
+}
+
 // Focus next widget.
 static void toolkit_nextFocus(void) {
 	Window* wdw = &windows[nwindows-1]; // Get active window.
@@ -854,6 +917,31 @@ static void toolkit_triggerFocus(void) {
 	}
 }
 
+// Try to scroll up/down by direction.
+static void toolkit_listScroll(Widget* wgt, int direction) {
+	if(wgt == NULL) return;
+
+	switch(wgt->type) {
+		case WIDGET_LIST:
+			wgt->dat.lst.selected -= direction;
+			wgt->dat.lst.selected = MAX(0, wgt->dat.lst.selected);
+			wgt->dat.lst.selected = MIN(wgt->dat.lst.selected, wgt->dat.lst.noptions-1);
+			break;
+		default:
+			break;
+	}
+}
+
+// Return the focused widget.
+static Widget* toolkit_getFocus(void) {
+	Window* wdw;
+	wdw = &windows[nwindows-1];
+
+	if(wdw->focus == -1) return NULL;
+
+	return &wdw->widgets[wdw->focus];
+}
+
 // Init.
 int toolkit_init(void) {
   windows = malloc(sizeof(Window)*MIN_WINDOWS);
diff --git a/src/toolkit.h b/src/toolkit.h
index 73548ed..cde25b9 100644
--- a/src/toolkit.h
+++ b/src/toolkit.h
@@ -41,6 +41,7 @@ void toolkit_render(void);
 
 // Input.
 int toolkit_input(SDL_Event* event);
+void toolkit_update(void);
 
 // Init/Exit.
 int toolkit_init(void);
diff --git a/src/weapon.c b/src/weapon.c
index 0d8bba4..c0c7b12 100644
--- a/src/weapon.c
+++ b/src/weapon.c
@@ -267,8 +267,9 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
   gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
 
   for(i = 0; i < pilots; i++) {
-    gl_getSpriteFromDir(&psx, &psy, pilot_stack[i]->ship->gfx_space,
-          pilot_stack[i]->solid->dir);
+		psx = pilot_stack[i]->tsx;
+		psy = pilot_stack[i]->tsy;
+
     if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
 
     if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&