Widget and trophy updates.
This commit is contained in:
parent
c87b9a6986
commit
6c2d39e1d1
18
src/defs.h
18
src/defs.h
|
@ -35,8 +35,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0)
|
#define TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0)
|
||||||
#define TO_DEGREES(angleRadians) (angleRadians * 180.0 / PI)
|
#define TO_DEGREES(angleRadians) (angleRadians * 180.0 / PI)
|
||||||
|
|
||||||
#define SAVE_FILENAME "game.save"
|
#define SAVE_FILENAME "game.save"
|
||||||
#define CONFIG_FILENAME "config.json"
|
#define CONFIG_FILENAME "config.json"
|
||||||
|
|
||||||
#define SCREEN_WIDTH 1280
|
#define SCREEN_WIDTH 1280
|
||||||
#define SCREEN_HEIGHT 720
|
#define SCREEN_HEIGHT 720
|
||||||
|
@ -51,6 +51,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define NUM_TEXT_BUCKETS 64
|
#define NUM_TEXT_BUCKETS 64
|
||||||
#define TEXT_TTL (1000 * 20)
|
#define TEXT_TTL (1000 * 20)
|
||||||
|
|
||||||
|
#define MAX_WIDGETS 48
|
||||||
|
|
||||||
#define MAX_NAME_LENGTH 32
|
#define MAX_NAME_LENGTH 32
|
||||||
#define MAX_DESCRIPTION_LENGTH 512
|
#define MAX_DESCRIPTION_LENGTH 512
|
||||||
#define MAX_LINE_LENGTH 1024
|
#define MAX_LINE_LENGTH 1024
|
||||||
|
@ -306,6 +308,7 @@ enum
|
||||||
SND_CONFIRMED,
|
SND_CONFIRMED,
|
||||||
SND_MISSION_COMPLETE,
|
SND_MISSION_COMPLETE,
|
||||||
SND_HEART_CELL,
|
SND_HEART_CELL,
|
||||||
|
SND_TROPHY,
|
||||||
SND_MAX
|
SND_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -327,7 +330,16 @@ enum
|
||||||
{
|
{
|
||||||
WT_BUTTON,
|
WT_BUTTON,
|
||||||
WT_SPINNER,
|
WT_SPINNER,
|
||||||
WT_PLAIN_BUTTON
|
WT_PLAIN_BUTTON,
|
||||||
|
WT_INPUT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TROPHY_BRONZE,
|
||||||
|
TROPHY_SILVER,
|
||||||
|
TROPHY_GOLD,
|
||||||
|
TROPHY_PLATINUM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -20,6 +20,220 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "trophies.h"
|
#include "trophies.h"
|
||||||
|
|
||||||
|
static void loadTrophyData(void);
|
||||||
|
static void resetAlert(void);
|
||||||
|
static void nextAlert(void);
|
||||||
|
|
||||||
|
static Trophy trophyHead, *trophyTail;
|
||||||
|
static int numTrophies;
|
||||||
|
static SDL_Rect alertRect;
|
||||||
|
static int alertTimer;
|
||||||
|
static Trophy *alertTrophy;
|
||||||
|
static float sparkleAngle;
|
||||||
|
/*
|
||||||
|
static SDL_Texture *trophyIcons[TROPHY_MAX];
|
||||||
|
static SDL_Texture *sparkle;
|
||||||
|
static SDL_Texture *alertSphere;
|
||||||
|
*/
|
||||||
|
static int awarded;
|
||||||
|
|
||||||
|
void initTrophies(void)
|
||||||
|
{
|
||||||
|
memset(&trophyHead, 0, sizeof(Trophy));
|
||||||
|
trophyTail = &trophyHead;
|
||||||
|
|
||||||
|
numTrophies = 0;
|
||||||
|
|
||||||
|
awarded = 0;
|
||||||
|
|
||||||
|
alertTimer = 0;
|
||||||
|
|
||||||
|
sparkleAngle = 0;
|
||||||
|
|
||||||
|
loadTrophyData();
|
||||||
|
}
|
||||||
|
|
||||||
void awardTrophy(char *id)
|
void awardTrophy(char *id)
|
||||||
{
|
{
|
||||||
|
Trophy *t;
|
||||||
|
int numRemaining;
|
||||||
|
|
||||||
|
numRemaining = 0;
|
||||||
|
|
||||||
|
for (t = trophyHead.next ; t != NULL ; t = t->next)
|
||||||
|
{
|
||||||
|
if (t->awardDate == 0 && strcmp(t->id, id) == 0)
|
||||||
|
{
|
||||||
|
t->awardDate = time(NULL);
|
||||||
|
t->notify = SDL_GetTicks();
|
||||||
|
|
||||||
|
SDL_Delay(1);
|
||||||
|
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Awarding trophy '%s'", t->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->awardDate == 0)
|
||||||
|
{
|
||||||
|
numRemaining++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the Platinum will always be the last trophy to unlock */
|
||||||
|
if (numRemaining == 1)
|
||||||
|
{
|
||||||
|
awardTrophy("PLATINUM");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void awardTrophies(void)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
Trophy *t;
|
||||||
|
|
||||||
|
for (t = trophyHead.next ; t != NULL ; t = t->next)
|
||||||
|
{
|
||||||
|
if (t->awardDate == 0 && t->statValue != 0)
|
||||||
|
{
|
||||||
|
val = game.stats[t->stat];
|
||||||
|
|
||||||
|
if (val >= t->statValue)
|
||||||
|
{
|
||||||
|
awardTrophy(t->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doTrophyAlerts(void)
|
||||||
|
{
|
||||||
|
if (!alertTrophy)
|
||||||
|
{
|
||||||
|
nextAlert();
|
||||||
|
}
|
||||||
|
else if (alertTrophy)
|
||||||
|
{
|
||||||
|
alertRect.x = MIN(alertRect.x + 24, -1);
|
||||||
|
|
||||||
|
if (alertRect.x > -150)
|
||||||
|
{
|
||||||
|
alertTimer--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alertTimer <= 0)
|
||||||
|
{
|
||||||
|
alertTrophy->notify = 0;
|
||||||
|
resetAlert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sparkleAngle = mod(sparkleAngle + 0.25, 360);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nextAlert(void)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
Trophy *t;
|
||||||
|
|
||||||
|
for (t = trophyHead.next ; t != NULL ; t = t->next)
|
||||||
|
{
|
||||||
|
if (t->notify)
|
||||||
|
{
|
||||||
|
if (!alertTrophy || t->notify < alertTrophy->notify)
|
||||||
|
{
|
||||||
|
alertTrophy = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alertTrophy)
|
||||||
|
{
|
||||||
|
playSound(SND_TROPHY, -1);
|
||||||
|
|
||||||
|
textSize(alertTrophy->title, 30, &alertRect.w, &h);
|
||||||
|
textSize(alertTrophy->description, 20, &w, &h);
|
||||||
|
|
||||||
|
alertRect.w = MAX(alertRect.w, w);
|
||||||
|
alertRect.w = MAX(400, alertRect.w);
|
||||||
|
alertRect.w += 125;
|
||||||
|
alertRect.x = -alertRect.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetAlert(void)
|
||||||
|
{
|
||||||
|
alertTimer = FPS * 3;
|
||||||
|
alertTrophy = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawTrophyAlert(void)
|
||||||
|
{
|
||||||
|
/*int x, y;*/
|
||||||
|
|
||||||
|
if (alertTrophy)
|
||||||
|
{
|
||||||
|
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||||
|
SDL_RenderFillRect(app.renderer, &alertRect);
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(app.renderer, 64, 64, 64, SDL_ALPHA_OPAQUE);
|
||||||
|
SDL_RenderDrawRect(app.renderer, &alertRect);
|
||||||
|
|
||||||
|
drawText(alertRect.x + 15, alertRect.y + 5, 30, TA_LEFT, colors.white, alertTrophy->title);
|
||||||
|
drawText(alertRect.x + 15, alertRect.y + 45, 20, TA_LEFT, colors.white, alertTrophy->description);
|
||||||
|
|
||||||
|
/*
|
||||||
|
x = alertRect.x alertRect.w - 72;
|
||||||
|
y = alertRect.y 20;
|
||||||
|
|
||||||
|
setSparkleColor(alertTrophy);
|
||||||
|
blit(alertSphere, x 24, y 24, 1);
|
||||||
|
blitRotated(sparkle, x 24, y 24, sparkleAngle);
|
||||||
|
blitRotated(sparkle, x 24, y 24, -sparkleAngle);
|
||||||
|
blitScaled(trophyIcons[alertTrophy->value], x, y, 48, 48, 0);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadTrophyData(void)
|
||||||
|
{
|
||||||
|
cJSON *root, *node;
|
||||||
|
char *text;
|
||||||
|
Trophy *t;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
filename = "data/misc/trophies.json";
|
||||||
|
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
|
||||||
|
|
||||||
|
text = readFile(filename);
|
||||||
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
|
for (node = root->child ; node != NULL ; node = node->next)
|
||||||
|
{
|
||||||
|
t = malloc(sizeof(Trophy));
|
||||||
|
memset(t, 0, sizeof(Trophy));
|
||||||
|
trophyTail->next = t;
|
||||||
|
trophyTail = t;
|
||||||
|
|
||||||
|
STRNCPY(t->id, cJSON_GetObjectItem(node, "id")->valuestring, MAX_NAME_LENGTH);
|
||||||
|
STRNCPY(t->title, _(cJSON_GetObjectItem(node, "title")->valuestring), MAX_DESCRIPTION_LENGTH);
|
||||||
|
STRNCPY(t->description, _(cJSON_GetObjectItem(node, "description")->valuestring), MAX_DESCRIPTION_LENGTH);
|
||||||
|
t->value = lookup(cJSON_GetObjectItem(node, "value")->valuestring);
|
||||||
|
|
||||||
|
if (cJSON_GetObjectItem(node, "hidden"))
|
||||||
|
{
|
||||||
|
t->hidden = cJSON_GetObjectItem(node, "hidden")->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->stat = -1;
|
||||||
|
|
||||||
|
if (cJSON_GetObjectItem(node, "stat"))
|
||||||
|
{
|
||||||
|
t->stat = lookup(cJSON_GetObjectItem(node, "stat")->valuestring);
|
||||||
|
t->statValue = cJSON_GetObjectItem(node, "statValue")->valueint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,3 +19,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
|
#include "../json/cJSON.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
extern char *readFile(const char *filename);
|
||||||
|
extern long lookup(const char *name);
|
||||||
|
extern void textSize(char *text, int size, int *w, int *h);
|
||||||
|
extern void playSound(int snd, int ch);
|
||||||
|
extern void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...);
|
||||||
|
extern float mod(float n, float x);
|
||||||
|
|
||||||
|
extern App app;
|
||||||
|
extern Colors colors;
|
||||||
|
extern Game game;
|
||||||
|
|
|
@ -76,6 +76,8 @@ int main(int argc, char *argv[])
|
||||||
game.stats[STAT_TIME_PLAYED]++;
|
game.stats[STAT_TIME_PLAYED]++;
|
||||||
|
|
||||||
nextSecond = SDL_GetTicks() + 1000;
|
nextSecond = SDL_GetTicks() + 1000;
|
||||||
|
|
||||||
|
awardTrophies();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ extern void presentScene(void);
|
||||||
extern void initAtlasTest(void);
|
extern void initAtlasTest(void);
|
||||||
extern void init18N(int argc, char *argv[]);
|
extern void init18N(int argc, char *argv[]);
|
||||||
extern void initLookups(void);
|
extern void initLookups(void);
|
||||||
|
extern void awardTrophies(void);
|
||||||
|
|
||||||
App app;
|
App app;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef struct Widget Widget;
|
||||||
typedef struct Atlas Atlas;
|
typedef struct Atlas Atlas;
|
||||||
typedef struct Bucket Bucket;
|
typedef struct Bucket Bucket;
|
||||||
typedef struct EntityDef EntityDef;
|
typedef struct EntityDef EntityDef;
|
||||||
|
typedef struct Trophy Trophy;
|
||||||
typedef struct cJSON cJSON;
|
typedef struct cJSON cJSON;
|
||||||
|
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
|
@ -464,21 +465,17 @@ typedef struct {
|
||||||
} World;
|
} World;
|
||||||
|
|
||||||
struct Widget {
|
struct Widget {
|
||||||
int type;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
int visible;
|
|
||||||
int enabled;
|
|
||||||
char name[MAX_NAME_LENGTH];
|
char name[MAX_NAME_LENGTH];
|
||||||
char group[MAX_NAME_LENGTH];
|
char group[MAX_NAME_LENGTH];
|
||||||
char label[MAX_NAME_LENGTH];
|
char label[MAX_NAME_LENGTH];
|
||||||
|
int type;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int visible;
|
||||||
|
int enabled;
|
||||||
int numOptions;
|
int numOptions;
|
||||||
char **options;
|
char **options;
|
||||||
int value;
|
int value;
|
||||||
int clicked;
|
|
||||||
Widget *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Atlas {
|
struct Atlas {
|
||||||
|
@ -487,6 +484,21 @@ struct Atlas {
|
||||||
Atlas *next;
|
Atlas *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Trophy {
|
||||||
|
char id[MAX_NAME_LENGTH];
|
||||||
|
char title[MAX_DESCRIPTION_LENGTH];
|
||||||
|
char description[MAX_DESCRIPTION_LENGTH];
|
||||||
|
char awardDateStr[MAX_NAME_LENGTH];
|
||||||
|
int value;
|
||||||
|
int hidden;
|
||||||
|
int stat;
|
||||||
|
int statValue;
|
||||||
|
int awarded;
|
||||||
|
unsigned long awardDate;
|
||||||
|
int notify;
|
||||||
|
Trophy *next;
|
||||||
|
};
|
||||||
|
|
||||||
/* ===== i18n stuff ==== */
|
/* ===== i18n stuff ==== */
|
||||||
|
|
||||||
struct Bucket {
|
struct Bucket {
|
||||||
|
|
|
@ -135,6 +135,7 @@ void initGameSystem(void)
|
||||||
initFonts,
|
initFonts,
|
||||||
initAtlas,
|
initAtlas,
|
||||||
initWidgets,
|
initWidgets,
|
||||||
|
initTrophies,
|
||||||
initSounds,
|
initSounds,
|
||||||
initSprites,
|
initSprites,
|
||||||
initEntityFactory
|
initEntityFactory
|
||||||
|
|
|
@ -35,6 +35,7 @@ extern void initAtlas(void);
|
||||||
extern void initSounds(void);
|
extern void initSounds(void);
|
||||||
extern void initSprites(void);
|
extern void initSprites(void);
|
||||||
extern void initWidgets(void);
|
extern void initWidgets(void);
|
||||||
|
extern void initTrophies(void);
|
||||||
extern void initEntityFactory(void);
|
extern void initEntityFactory(void);
|
||||||
extern void destroyLookups(void);
|
extern void destroyLookups(void);
|
||||||
extern void destroyFonts(void);
|
extern void destroyFonts(void);
|
||||||
|
|
|
@ -33,6 +33,8 @@ static void doKeyDown(SDL_KeyboardEvent *event)
|
||||||
if (event->keysym.scancode >= 0 && event->keysym.scancode < MAX_KEYBOARD_KEYS && event->repeat == 0)
|
if (event->keysym.scancode >= 0 && event->keysym.scancode < MAX_KEYBOARD_KEYS && event->repeat == 0)
|
||||||
{
|
{
|
||||||
app.keyboard[event->keysym.scancode] = 1;
|
app.keyboard[event->keysym.scancode] = 1;
|
||||||
|
|
||||||
|
app.lastKeyPressed = event->keysym.scancode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +109,8 @@ static void doButtonDown(SDL_JoyButtonEvent *event)
|
||||||
if (event->state == SDL_PRESSED)
|
if (event->state == SDL_PRESSED)
|
||||||
{
|
{
|
||||||
app.joypadButton[event->button] = 1;
|
app.joypadButton[event->button] = 1;
|
||||||
|
|
||||||
|
app.lastButtonPressed = event->button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,29 @@ void initLookups(void)
|
||||||
addLookup("WT_BUTTON", WT_BUTTON);
|
addLookup("WT_BUTTON", WT_BUTTON);
|
||||||
addLookup("WT_SPINNER", WT_SPINNER);
|
addLookup("WT_SPINNER", WT_SPINNER);
|
||||||
addLookup("WT_PLAIN_BUTTON", WT_PLAIN_BUTTON);
|
addLookup("WT_PLAIN_BUTTON", WT_PLAIN_BUTTON);
|
||||||
|
|
||||||
|
addLookup("TROPHY_BRONZE", TROPHY_BRONZE);
|
||||||
|
addLookup("TROPHY_SILVER", TROPHY_SILVER);
|
||||||
|
addLookup("TROPHY_GOLD", TROPHY_GOLD);
|
||||||
|
addLookup("TROPHY_PLATINUM", TROPHY_PLATINUM);
|
||||||
|
|
||||||
|
addLookup("STAT_KEYS_FOUND", STAT_KEYS_FOUND);
|
||||||
|
addLookup("STAT_CELLS_FOUND", STAT_CELLS_FOUND);
|
||||||
|
addLookup("STAT_HEARTS_FOUND", STAT_HEARTS_FOUND);
|
||||||
|
addLookup("STAT_TARGETS_DEFEATED", STAT_TARGETS_DEFEATED);
|
||||||
|
addLookup("STAT_MIAS_RESCUED", STAT_MIAS_RESCUED);
|
||||||
|
addLookup("STAT_DEATHS", STAT_DEATHS);
|
||||||
|
addLookup("STAT_SHOTS_FIRED", STAT_SHOTS_FIRED);
|
||||||
|
addLookup("STAT_SHOTS_HIT", STAT_SHOTS_HIT);
|
||||||
|
addLookup("STAT_EYE_DROID_EXPLOSION_KILLS", STAT_EYE_DROID_EXPLOSION_KILLS);
|
||||||
|
addLookup("STAT_FLY_TIME", STAT_FLY_TIME);
|
||||||
|
addLookup("STAT_SWIM_TIME", STAT_SWIM_TIME);
|
||||||
|
addLookup("STAT_CHERRIES_PICKED_UP", STAT_CHERRIES_PICKED_UP);
|
||||||
|
addLookup("STAT_BATTERIES_PICKED_UP", STAT_BATTERIES_PICKED_UP);
|
||||||
|
addLookup("STAT_WEAPONS_PICKED_UP", STAT_WEAPONS_PICKED_UP);
|
||||||
|
addLookup("STAT_ENEMIES_KILLED", STAT_ENEMIES_KILLED);
|
||||||
|
addLookup("STAT_MISSIONS_PLAYED", STAT_MISSIONS_PLAYED);
|
||||||
|
addLookup("STAT_TIME_PLAYED", STAT_TIME_PLAYED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addLookup(const char *name, long value)
|
static void addLookup(const char *name, long value)
|
||||||
|
|
|
@ -20,28 +20,109 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "widgets.h"
|
#include "widgets.h"
|
||||||
|
|
||||||
Widget *getWidgetAt(int x, int y);
|
|
||||||
static void loadWidgetGroup(char *filename);
|
static void loadWidgetGroup(char *filename);
|
||||||
static void loadWidgets(void);
|
static void loadWidgets(void);
|
||||||
|
static void createWidgetOptions(Widget *w, char *options);
|
||||||
|
static void selectWidget(int dir);
|
||||||
|
|
||||||
static Widget widgetHead;
|
static Widget widgets[MAX_WIDGETS];
|
||||||
static Widget *widgetTail;
|
|
||||||
static Widget *selectedWidget;
|
static Widget *selectedWidget;
|
||||||
|
static int widgetIndex;
|
||||||
|
static int numWidgets;
|
||||||
|
|
||||||
void initWidgets(void)
|
void initWidgets(void)
|
||||||
{
|
{
|
||||||
memset(&widgetHead, 0, sizeof(Widget));
|
memset(widgets, 0, sizeof(Widget) * MAX_WIDGETS);
|
||||||
widgetTail = &widgetHead;
|
|
||||||
|
numWidgets = 0;
|
||||||
|
|
||||||
loadWidgets();
|
loadWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget *getWidget(char *name, char *group)
|
void doWidgets(void)
|
||||||
{
|
{
|
||||||
|
if (app.keyboard[SDL_SCANCODE_UP])
|
||||||
|
{
|
||||||
|
selectWidget(-1);
|
||||||
|
|
||||||
|
app.keyboard[SDL_SCANCODE_UP] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.keyboard[SDL_SCANCODE_DOWN])
|
||||||
|
{
|
||||||
|
selectWidget(1);
|
||||||
|
|
||||||
|
app.keyboard[SDL_SCANCODE_DOWN] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.keyboard[SDL_SCANCODE_LEFT] && selectedWidget->type == WT_SPINNER)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.keyboard[SDL_SCANCODE_RIGHT] && selectedWidget->type == WT_SPINNER)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawWidgets(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
Widget *w;
|
Widget *w;
|
||||||
|
|
||||||
for (w = widgetHead.next ; w != NULL ; w = w->next)
|
for (i = 0 ; i < numWidgets ; i++)
|
||||||
{
|
{
|
||||||
|
w = &widgets[i];
|
||||||
|
|
||||||
|
if (w->visible)
|
||||||
|
{
|
||||||
|
switch (w->type)
|
||||||
|
{
|
||||||
|
case WT_BUTTON:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WT_PLAIN_BUTTON:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WT_SPINNER:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WT_INPUT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void selectWidget(int dir)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
widgetIndex += dir;
|
||||||
|
|
||||||
|
if (widgetIndex < 0)
|
||||||
|
{
|
||||||
|
widgetIndex = numWidgets - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widgetIndex >= numWidgets)
|
||||||
|
{
|
||||||
|
widgetIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedWidget = &widgets[widgetIndex];
|
||||||
|
|
||||||
|
} while (!selectedWidget->enabled && !selectedWidget->visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget *getWidget(char *name, char *group)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Widget *w;
|
||||||
|
|
||||||
|
for (i = 0 ; i < numWidgets ; i++)
|
||||||
|
{
|
||||||
|
w = &widgets[i];
|
||||||
|
|
||||||
if (strcmp(w->name, name) == 0 && strcmp(w->group, group) == 0)
|
if (strcmp(w->name, name) == 0 && strcmp(w->group, group) == 0)
|
||||||
{
|
{
|
||||||
return w;
|
return w;
|
||||||
|
@ -54,59 +135,13 @@ Widget *getWidget(char *name, char *group)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleWidgetClick(int x, int y)
|
|
||||||
{
|
|
||||||
Widget *w;
|
|
||||||
|
|
||||||
w = getWidgetAt(x, y);
|
|
||||||
|
|
||||||
if (w != NULL)
|
|
||||||
{
|
|
||||||
if (w->type == WT_SPINNER)
|
|
||||||
{
|
|
||||||
w->value++;
|
|
||||||
|
|
||||||
w->value %= w->numOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
w->clicked = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void activeSelected(void)
|
|
||||||
{
|
|
||||||
if (selectedWidget->type == WT_SPINNER)
|
|
||||||
{
|
|
||||||
selectedWidget->value++;
|
|
||||||
|
|
||||||
selectedWidget->value %= selectedWidget->numOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedWidget->clicked = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget *getWidgetAt(int x, int y)
|
|
||||||
{
|
|
||||||
Widget *w;
|
|
||||||
|
|
||||||
for (w = widgetHead.next ; w != NULL ; w = w->next)
|
|
||||||
{
|
|
||||||
if (w->visible && w->enabled && collision(x, y, 1, 1, w->x - (w->w / 2), w->y, w->w, w->h))
|
|
||||||
{
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hideAllWidgets(void)
|
void hideAllWidgets(void)
|
||||||
{
|
{
|
||||||
Widget *w;
|
int i;
|
||||||
|
|
||||||
for (w = widgetHead.next ; w != NULL ; w = w->next)
|
for (i = 0 ; i < numWidgets ; i++)
|
||||||
{
|
{
|
||||||
w->visible = 0;
|
widgets[i].visible = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedWidget = NULL;
|
selectedWidget = NULL;
|
||||||
|
@ -114,12 +149,15 @@ void hideAllWidgets(void)
|
||||||
|
|
||||||
void showWidgetGroup(char *group)
|
void showWidgetGroup(char *group)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
Widget *w;
|
Widget *w;
|
||||||
|
|
||||||
hideAllWidgets();
|
hideAllWidgets();
|
||||||
|
|
||||||
for (w = widgetHead.next ; w != NULL ; w = w->next)
|
for (i = 0 ; i < numWidgets ; i++)
|
||||||
{
|
{
|
||||||
|
w = &widgets[i];
|
||||||
|
|
||||||
if (strcmp(w->group, group) == 0)
|
if (strcmp(w->group, group) == 0)
|
||||||
{
|
{
|
||||||
if (selectedWidget == NULL)
|
if (selectedWidget == NULL)
|
||||||
|
@ -132,17 +170,6 @@ void showWidgetGroup(char *group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wasWidgetClicked(Widget *w)
|
|
||||||
{
|
|
||||||
int wasClicked;
|
|
||||||
|
|
||||||
wasClicked = w->clicked;
|
|
||||||
|
|
||||||
w->clicked = 0;
|
|
||||||
|
|
||||||
return wasClicked;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void loadWidgets(void)
|
static void loadWidgets(void)
|
||||||
{
|
{
|
||||||
char **filenames;
|
char **filenames;
|
||||||
|
@ -176,29 +203,28 @@ static void loadWidgetGroup(char *filename)
|
||||||
|
|
||||||
for (node = root->child ; node != NULL ; node = node->next)
|
for (node = root->child ; node != NULL ; node = node->next)
|
||||||
{
|
{
|
||||||
w = malloc(sizeof(Widget));
|
if (++numWidgets >= MAX_WIDGETS)
|
||||||
memset(w, 0, sizeof(Widget));
|
{
|
||||||
widgetTail->next = w;
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Out of widget space.");
|
||||||
widgetTail = w;
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
w = &widgets[numWidgets];
|
||||||
|
|
||||||
STRNCPY(w->name, cJSON_GetObjectItem(node, "name")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(w->name, cJSON_GetObjectItem(node, "name")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(w->group, cJSON_GetObjectItem(node, "group")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(w->group, cJSON_GetObjectItem(node, "group")->valuestring, MAX_NAME_LENGTH);
|
||||||
STRNCPY(w->label, cJSON_GetObjectItem(node, "label")->valuestring, MAX_NAME_LENGTH);
|
STRNCPY(w->label, cJSON_GetObjectItem(node, "label")->valuestring, MAX_NAME_LENGTH);
|
||||||
w->x = cJSON_GetObjectItem(node, "x")->valueint;
|
w->x = cJSON_GetObjectItem(node, "x")->valueint;
|
||||||
w->y = cJSON_GetObjectItem(node, "y")->valueint;
|
w->y = cJSON_GetObjectItem(node, "y")->valueint;
|
||||||
w->w = cJSON_GetObjectItem(node, "w")->valueint;
|
|
||||||
w->h = cJSON_GetObjectItem(node, "h")->valueint;
|
|
||||||
w->type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
w->type = lookup(cJSON_GetObjectItem(node, "type")->valuestring);
|
||||||
|
|
||||||
switch (w->type)
|
switch (w->type)
|
||||||
{
|
{
|
||||||
case WT_BUTTON:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WT_SPINNER:
|
case WT_SPINNER:
|
||||||
|
createWidgetOptions(w, cJSON_GetObjectItem(node, "options")->valuestring);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WT_PLAIN_BUTTON:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,6 +234,38 @@ static void loadWidgetGroup(char *filename)
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void createWidgetOptions(Widget *w, char *options)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *option;
|
||||||
|
|
||||||
|
w->numOptions = 1;
|
||||||
|
|
||||||
|
for (i = 0 ; i < strlen(options) ; i++)
|
||||||
|
{
|
||||||
|
if (options[i] == '|')
|
||||||
|
{
|
||||||
|
w->numOptions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w->options = malloc(w->numOptions * sizeof(char*));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
option = strtok(options, "|");
|
||||||
|
while (option)
|
||||||
|
{
|
||||||
|
w->options[i] = malloc(strlen(option) + 1);
|
||||||
|
strcpy(w->options[i], option);
|
||||||
|
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "widget.option[%d] = %s", i, option);
|
||||||
|
|
||||||
|
option = strtok(NULL, "|");
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void destroy(void)
|
void destroy(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
#include "../json/cJSON.h"
|
#include "../json/cJSON.h"
|
||||||
|
|
||||||
extern int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);
|
|
||||||
extern char *readFile(const char *filename);
|
extern char *readFile(const char *filename);
|
||||||
extern char **getFileList(const char *dir, int *count);
|
extern char **getFileList(const char *dir, int *count);
|
||||||
extern long lookup(const char *name);
|
extern long lookup(const char *name);
|
||||||
|
|
||||||
|
extern App app;
|
||||||
|
|
|
@ -20,9 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
|
|
||||||
int mod(int n, int x)
|
float mod(float n, float x)
|
||||||
{
|
{
|
||||||
return ((n % x) + x) % x;
|
return fmod(fmod(n, x) + x, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rrnd(int low, int high)
|
int rrnd(int low, int high)
|
||||||
|
|
Loading…
Reference in New Issue