/*
-Copyright (C) 2004 Parallel Realities
+Copyright (C) 2004-2011 Parallel Realities
+Copyright (C) 2011-2015 Perpendicular Dimensions
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
*/
#include "headers.h"
+#include <errno.h>
+extern Graphics graphics;
Engine::Engine()
{
- for (int i = 0 ; i < 350 ; i++)
- {
- keyState[i] = 0;
- }
-
- for (int i = 0 ; i < 32 ; i++)
- {
- joystickState[i] = 0;
- }
+ memset(keyState, 0, sizeof keyState);
+
+ memset(joystickState, 0, sizeof joystickState);
joyX = joyY = 0;
binaryBuffer = NULL;
#ifdef FRAMEWORK_SDL
char pakPath[PATH_MAX];
- strncpy(pakPath, PAKFULLPATH, sizeof(pakPath));
+ strlcpy(pakPath, PAKFULLPATH, sizeof(pakPath));
if (CFBundleGetMainBundle() != NULL) {
CFURLRef pakURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR(PAKNAME), NULL, NULL);
if (pakURL != NULL) {
// Cheats
memset(lastKeyEvents, ' ', 25);
- #if USEPAK
- cheats = false;
- #else
- cheats = true;
- #endif
cheatHealth = cheatExtras = cheatFuel = cheatLevels = false;
cheatBlood = cheatInvulnerable = cheatReload = cheatSpeed = cheatSkipLevel = false;
deleteWidgets();
debug(("engine: free databuffer\n"));
- if (dataBuffer != NULL)
- delete[] dataBuffer;
+ delete[] dataBuffer;
debug(("engine: free binarybuffer\n"));
- if (binaryBuffer != NULL)
- delete[] binaryBuffer;
+ delete[] binaryBuffer;
debug(("Clearing Define List...\n"));
defineList.clear();
bool Engine::compareLastKeyInputs()
{
- if (strstr(lastKeyEvents, "lockandload"))
+ if (strstr(lastKeyEvents, "LOCKANDLOAD"))
{
cheats = true;
return true;
if (index == -1)
{
- for (int i = 0 ; i < 25 ; i++)
+ for (int i = 0 ; i < 24 ; i++)
{
lastKeyEvents[i] = lastKeyEvents[i + 1];
}
void Engine::getInput()
{
- SDL_GetMouseState(&mouseX, &mouseY);
-
while (SDL_PollEvent(&event))
{
switch (event.type)
if (event.button.button == SDL_BUTTON_RIGHT) mouseRight = 0;
break;
+ case SDL_MOUSEMOTION:
+ mouseX = event.motion.x;
+ mouseY = event.motion.y;
+ break;
+
case SDL_KEYDOWN:
if (waitForButton)
{
- if (event.key.keysym.sym == SDLK_ESCAPE)
+ if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
lastButtonPressed = -1;
*highlightedWidget->value = abs(*highlightedWidget->value) - 1000;
allowJoypad = false;
}
- if (event.key.keysym.sym == SDLK_BACKSPACE)
+ if (event.key.keysym.scancode == SDL_SCANCODE_BACKSPACE)
{
lastButtonPressed = -2;
*highlightedWidget->value = -2;
if (waitForKey)
{
- if (event.key.keysym.sym == SDLK_ESCAPE)
+ if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
*highlightedWidget->value = -*highlightedWidget->value;
}
else
{
- *highlightedWidget->value = event.key.keysym.sym;
+ *highlightedWidget->value = event.key.keysym.scancode;
}
lastButtonPressed = -1;
return;
}
- keyState[event.key.keysym.sym] = 1;
- strncpy(lastKeyPressed, SDL_GetKeyName(event.key.keysym.sym), sizeof lastKeyPressed);
+ keyState[event.key.keysym.scancode] = 1;
+ strlcpy(lastKeyPressed, SDL_GetKeyName(SDL_GetKeyFromScancode(event.key.keysym.scancode)), sizeof lastKeyPressed);
addKeyEvent();
break;
case SDL_KEYUP:
- keyState[event.key.keysym.sym] = 0;
+ keyState[event.key.keysym.scancode] = 0;
break;
case SDL_JOYAXISMOTION:
if (event.jaxis.axis == 0)
{
- joyX = event.jaxis.value;
+ joyX = event.jaxis.value;
+ int joycurX = joyX < -25000 ? -1 : joyX > 25000 ? 1 : 0;
+ if (joycurX != joyprevX)
+ joykeyX = joyprevX = joycurX;
}
else if (event.jaxis.axis == 1)
{
- joyY = event.jaxis.value;
+ joyY = event.jaxis.value;
+ int joycurY = joyY < -25000 ? -1 : joyY > 25000 ? 1 : 0;
+ if (joycurY != joyprevY)
+ joykeyY = joyprevY = joycurY;
}
-
break;
case SDL_JOYBUTTONDOWN:
-
if (waitForButton)
{
lastButtonPressed = event.jbutton.button;
}
joystickState[event.jbutton.button] = 1;
+ joykeyFire = true;
break;
case SDL_JOYBUTTONUP:
joystickState[event.jbutton.button] = 0;
+ joykeyFire = false;
+ break;
+
+ case SDL_JOYHATMOTION:
+ switch (event.jhat.value) {
+ case SDL_HAT_CENTERED:
+ joyX = 0, joyY = 0; break;
+ case SDL_HAT_LEFT:
+ joyX = -32768, joyY = 0; break;
+ case SDL_HAT_LEFTUP:
+ joyX = -32768, joyY = -32768; break;
+ case SDL_HAT_UP:
+ joyX = 0, joyY = -32768; break;
+ case SDL_HAT_RIGHTUP:
+ joyX = 32767, joyY = -32768; break;
+ case SDL_HAT_RIGHT:
+ joyX = 32767, joyY = 0; break;
+ case SDL_HAT_RIGHTDOWN:
+ joyX = 32767, joyY = 32767; break;
+ case SDL_HAT_DOWN:
+ joyX = 0, joyY = 32767; break;
+ case SDL_HAT_LEFTDOWN:
+ joyX = -32768, joyY = 32767; break;
+ }
+
+ if (joyX != joyprevX)
+ joykeyX = joyprevX = joyX;
+ if (joyY != joyprevY)
+ joykeyY = joyprevY = joyY;
+
+ break;
+
+ case SDL_WINDOWEVENT:
+ if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
+ paused = true;
break;
default:
}
}
-int Engine::getMouseX()
+int Engine::getMouseX() const
{
return mouseX;
}
-int Engine::getMouseY()
+int Engine::getMouseY() const
{
return mouseY;
}
-void Engine::setMouse(int x, int y)
+void Engine::moveMouse(int dx, int dy)
{
- SDL_WarpMouse(x, y);
+ mouseX += dx;
+ mouseY += dy;
+ Math::limitInt(&mouseX, 0, 640);
+ Math::limitInt(&mouseY, 0, 480);
}
bool Engine::userAccepts()
{
- if ((keyState[SDLK_SPACE]) || (keyState[SDLK_ESCAPE]) || (keyState[SDLK_LCTRL]) || (keyState[SDLK_RCTRL]) || (keyState[SDLK_RETURN]) || (keyState[SDLK_LCTRL]))
+ if ((keyState[SDL_SCANCODE_SPACE]) || (keyState[SDL_SCANCODE_ESCAPE]) || (keyState[SDL_SCANCODE_LCTRL]) || (keyState[SDL_SCANCODE_RCTRL]) || (keyState[SDL_SCANCODE_RETURN]) || (keyState[SDL_SCANCODE_LCTRL]) || joykeyFire)
{
return true;
}
void Engine::clearInput()
{
- for (int i = 0 ; i < 350 ; i++)
- keyState[i] = 0;
+ memset(keyState, 0, sizeof keyState);
mouseLeft = mouseRight = 0;
+ joykeyX = joykeyY = 0;
+ joykeyFire = false;
}
void Engine::setUserHome(const char *path)
{
- strncpy(userHomeDirectory, path, sizeof userHomeDirectory);
+ strlcpy(userHomeDirectory, path, sizeof userHomeDirectory);
debug(("User Home = %s\n", path));
}
*/
bool Engine::unpack(const char *filename, int fileType)
{
+ bool ret = true;
+
if (fileType == PAK_DATA)
{
- if (dataBuffer != NULL)
- delete[] dataBuffer;
-
+ delete[] dataBuffer;
dataBuffer = NULL;
}
else
{
- if (binaryBuffer != NULL)
- delete[] binaryBuffer;
-
+ delete[] binaryBuffer;
binaryBuffer = NULL;
}
}
}
- if ((fileType == PAK_MUSIC) || (fileType == PAK_FONT))
+ if ((fileType == PAK_MUSIC) || (fileType == PAK_FONT) || (fileType == PAK_TAGS))
{
char tempPath[PATH_MAX];
snprintf(tempPath, sizeof tempPath, "%smusic.mod", userHomeDirectory);
fp = fopen(tempPath, "wb");
}
-
- if (fileType == PAK_FONT)
+ else if (fileType == PAK_TAGS)
+ {
+ snprintf(tempPath, sizeof tempPath, "%smusic.tags", userHomeDirectory);
+ fp = fopen(tempPath, "wb");
+ }
+ else if (fileType == PAK_FONT)
{
snprintf(tempPath, sizeof tempPath, "%sfont.ttf", userHomeDirectory);
fp = fopen(tempPath, "wb");
if (!fp)
{
+ printf("Fatal Error: could not open %s for writing: %s", tempPath, strerror(errno));
return false;
}
- fwrite(binaryBuffer, 1, pak.getUncompressedSize(), fp);
+ if (fwrite(binaryBuffer, 1, pak.getUncompressedSize(), fp) != pak.getUncompressedSize())
+ {
+ printf("Fatal Error: could not write to %s: %s", tempPath, strerror(errno));
+ ret = false;
+ }
fclose(fp);
}
- debug(("unpack() : Loaded %s (%d)\n", filename, pak.getUncompressedSize()));
+ debug(("unpack() : Loaded %s (%d), ret: %d\n", filename, pak.getUncompressedSize(), (int)ret));
- return true;
+ return ret;
}
bool Engine::loadData(const char *filename)
{
- if (dataBuffer != NULL)
- {
- delete[] dataBuffer;
- dataBuffer = NULL;
- }
+ bool ret = true;
+
+ delete[] dataBuffer;
+ dataBuffer = NULL;
#if USEPAK
return unpack(filename, PAK_DATA);
rewind(fp);
- dataBuffer = new unsigned char[fSize];
+ dataBuffer = new unsigned char[fSize + 1];
+
+ if (fread(dataBuffer, 1, fSize, fp) != (size_t)fSize)
+ ret = false;
- fread(dataBuffer, 1, fSize, fp);
+ dataBuffer[fSize] = 0;
fclose(fp);
- debug(("loadData() : Loaded %s (%d)\n", filename, fSize));
+ debug(("loadData() : Loaded %s (%d), ret: %d\n", filename, fSize, (int)ret));
- return true;
+ return ret;
}
void Engine::reportFontFailure()
Math::limitInt(&playerPosY, limitUp, limitDown);
}
-int Engine::getFrameLoop()
+int Engine::getFrameLoop() const
{
return frameLoop;
}
time2 = SDL_GetTicks();
}
-float Engine::getTimeDifference()
+float Engine::getTimeDifference() const
{
return timeDifference;
}
{
if (priority >= messagePriority)
{
- strncpy(this->message, message, sizeof this->message);
+ strlcpy(this->message, message, sizeof this->message);
messageTime = 180;
messagePriority = priority;
messageType = type;
{
int update = 0;
- if (keyState[SDLK_UP])
+ if (keyState[SDL_SCANCODE_UP] || joykeyY < 0)
{
highlightWidget(-1);
update = 1;
clearInput();
}
- if (keyState[SDLK_DOWN])
+ if (keyState[SDL_SCANCODE_DOWN] || joykeyY > 0)
{
highlightWidget(1);
update = 1;
clearInput();
}
- if (keyState[SDLK_LEFT] && (highlightedWidget->type != WG_BUTTON && highlightedWidget->type != WG_JOYPAD))
+ if ((keyState[SDL_SCANCODE_LEFT] || joykeyX < 0) && (highlightedWidget->type != WG_BUTTON && highlightedWidget->type != WG_JOYPAD))
{
SDL_Delay(1);
clearInput();
}
- if (keyState[SDLK_RIGHT] && (highlightedWidget->type != WG_BUTTON && highlightedWidget->type != WG_JOYPAD))
+ if ((keyState[SDL_SCANCODE_RIGHT] || joykeyX > 0) && (highlightedWidget->type != WG_BUTTON && highlightedWidget->type != WG_JOYPAD))
{
SDL_Delay(1);
clearInput();
}
- if ((keyState[SDLK_RETURN]) || (keyState[SDLK_SPACE]) || (keyState[SDLK_LCTRL]))
+ if ((keyState[SDL_SCANCODE_RETURN]) || (keyState[SDL_SCANCODE_SPACE]) || (keyState[SDL_SCANCODE_LCTRL]) || (joykeyFire && highlightedWidget->type != WG_JOYPAD))
{
if (highlightedWidget->value == NULL)
{
clearInput();
}
+ if (joykeyX > 0 && highlightedWidget->type == WG_JOYPAD)
+ {
+ waitForButton = true;
+ waitForKey = false;
+ allowJoypad = true;
+
+ if (*highlightedWidget->value > -1000)
+ {
+ *highlightedWidget->value = (-1000 - *highlightedWidget->value);
+ }
+
+ clearInput();
+ }
+
+ if (joykeyX < 0 && highlightedWidget->type == WG_JOYPAD)
+ {
+ if (waitForButton)
+ {
+ lastButtonPressed = -1;
+ *highlightedWidget->value = abs(*highlightedWidget->value) - 1000;
+ }
+ else
+ {
+ lastButtonPressed = -2;
+ *highlightedWidget->value = -2;
+ }
+
+ waitForButton = false;
+ allowJoypad = false;
+ highlightedWidget->redraw();
+ clearInput();
+ }
+
return update;
}
if (!loadData("data/defines.h"))
return false;
- char *token = strtok((char*)dataBuffer, "\n");
-
- Data *data;
+ strtok((char*)dataBuffer, "\n");
while (true)
{
- token = strtok(NULL, "\n");
+ char *token = strtok(NULL, "\n");
if (!token)
break;
if (!strstr(token, "/*"))
{
sscanf(token, "%*s %s %[^\n\r]", string[0], string[1]);
- data = new Data();
+ Data *data = new Data();
data->set(string[0], string[1], 1, 1);
defineList.add(data);
}
char line[1024];
bool found;
int value;
- strncpy(line, realLine, sizeof line);
+ strlcpy(line, realLine, sizeof line);
int flags = 0;