Start of v0.1

This commit is contained in:
Steve 2018-01-21 09:31:38 +00:00
parent 75e5bb3f44
commit 1c429f33d3
34 changed files with 2330 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
data
gfx
music
sound
blobwarsAttrition
*.o

31
common.mk Normal file
View File

@ -0,0 +1,31 @@
VERSION = 0.1
REVISION = $(shell git rev-list HEAD 2>/dev/null | wc -l)
LOCALE_MO = $(patsubst %.po,%.mo,$(wildcard locale/*.po))
SEARCHPATH += src src/game src/system src/util
vpath %.c $(SEARCHPATH)
vpath %.h $(SEARCHPATH)
DEPS += defs.h structs.h
OBJS += draw.o
OBJS += game.o
OBJS += init.o input.o io.o
OBJS += lookup.o
OBJS += main.o maths.o
OBJS += text.o textures.o title.o
OBJS += util.o
# top-level rule to create the program.
all: $(PROG) $(LOCALE_MO)
# compiling other source files.
%.o: %.c %.h $(DEPS)
$(CC) $(CFLAGS) $(CXXFLAGS) -c $<
%.mo: %.po
msgfmt -c -o $@ $<
# cleaning everything that can be automatically recreated with "make".
clean:
$(RM) $(OBJS) $(PROG) $(LOCALE_MO)

97
makefile Normal file
View File

@ -0,0 +1,97 @@
PROG = blobwarsAttrition
CC = gcc
PREFIX ?= /usr
BIN_DIR ?= $(PREFIX)/bin
DATA_DIR ?= /opt/$(PROG)
LOCALE_DIR = $(PREFIX)/share/locale
ICON_DIR = $(PREFIX)/share/icons/hicolor
DESKTOP_DIR = $(PREFIX)/share/applications
DESTDIR ?=
INST_BIN_DIR = $(DESTDIR)$(BIN_DIR)
INST_DATA_DIR = $(DESTDIR)$(DATA_DIR)
INST_LOCALE_DIR = $(DESTDIR)$(LOCALE_DIR)
INST_ICON_DIR = $(DESTDIR)$(ICON_DIR)
INST_DESKTOP_DIR = $(DESTDIR)$(DESKTOP_DIR)
SEARCHPATH += src/plat/unix
OBJS += unixInit.o
include common.mk
CXXFLAGS += `sdl2-config --cflags` -DVERSION=$(VERSION) -DREVISION=$(REVISION) -DDATA_DIR=\"$(DATA_DIR)\" -DLOCALE_DIR=\"$(LOCALE_DIR)\"
CXXFLAGS += -Wall -Wempty-body -ansi -pedantic -Werror -Wstrict-prototypes -Werror=maybe-uninitialized -Warray-bounds
CXXFLAGS += -g -lefence
LDFLAGS += `sdl2-config --libs` -lSDL2_mixer -lSDL2_image -lSDL2_ttf -lm
SHARED_FILES = CHANGELOG LICENSE README.md data gfx manual music sound icons
DIST_FILES = $(SHARED_FILES) locale $(PROG)
SRC_DIST_FILES = $(SHARED_FILES) src makefile* common.mk
# linking the program.
$(PROG): $(OBJS)
$(CC) -o $@ $(OBJS) $(LDFLAGS)
install:
mkdir -p $(INST_BIN_DIR)
install -m 0755 $(PROG) $(INST_BIN_DIR)
mkdir -p $(INST_DATA_DIR)
cp -r data $(INST_DATA_DIR)
cp -r gfx $(INST_DATA_DIR)
cp -r manual $(INST_DATA_DIR)
cp -r music $(INST_DATA_DIR)
cp -r sound $(INST_DATA_DIR)
mkdir -p $(INST_ICON_DIR)/16x16/apps
mkdir -p $(INST_ICON_DIR)/32x32/apps
mkdir -p $(INST_ICON_DIR)/64x64/apps
mkdir -p $(INST_ICON_DIR)/128x128/apps
cp -p icons/$(PROG)-16x16.png $(INST_ICON_DIR)/16x16/apps/$(PROG).png
cp -p icons/$(PROG)-32x32.png $(INST_ICON_DIR)/32x32/apps/$(PROG).png
cp -p icons/$(PROG)-64x64.png $(INST_ICON_DIR)/64x64/apps/$(PROG).png
cp -p icons/$(PROG)-128x128.png $(INST_ICON_DIR)/128x128/apps/$(PROG).png
mkdir -p $(INST_DESKTOP_DIR)
cp -p icons/$(PROG).desktop $(INST_DESKTOP_DIR)
@for f in $(LOCALE_MO); do \
lang=`echo $$f | sed -e 's/^locale\///;s/\.mo$$//'`; \
mkdir -p $(INST_LOCALE_DIR)/$$lang/LC_MESSAGES; \
cp -v $$f $(INST_LOCALE_DIR)/$$lang/LC_MESSAGES/$(PROG).mo; \
done
uninstall:
$(RM) $(BIN_DIR)/$(PROG)
$(RM) -rf $(DATA_DIR)
$(RM) $(ICON_DIR)/16x16/apps/$(PROG).png
$(RM) $(ICON_DIR)/32x32/apps/$(PROG).png
$(RM) $(ICON_DIR)/64x64/apps/$(PROG).png
$(RM) $(ICON_DIR)/128x128/apps/$(PROG).png
$(RM) $(DESKTOP_DIR)/$(PROG).desktop
@for f in $(LOCALE_MO); do \
lang=`echo $$f | sed -e 's/^locale\///;s/\.mo$$//'`; \
$(RM) -v $(LOCALE_DIR)/$$lang/LC_MESSAGES/$(PROG).mo; \
done
# prepare an archive for the program
dist:
$(RM) -rf $(PROG)-$(VERSION)
mkdir $(PROG)-$(VERSION)
cp -r $(DIST_FILES) $(PROG)-$(VERSION)
tar czf $(PROG)-$(VERSION)-$(REVISION).linux-x86.tar.gz $(PROG)-$(VERSION)
mkdir -p dist
mv $(PROG)-$(VERSION)-$(REVISION).linux-x86.tar.gz dist
$(RM) -rf $(PROG)-$(VERSION)
# prepare an archive for the program
src-dist:
$(RM) -rf $(PROG)-$(VERSION)
mkdir $(PROG)-$(VERSION)
cp -r $(SRC_DIST_FILES) $(PROG)-$(VERSION)
git log --pretty=format:"%h%x09%an%x09%ad%x09%s" --date=short >$(PROG)-$(VERSION)/CHANGELOG.raw
tar czf $(PROG)-$(VERSION)-$(REVISION).src.tar.gz $(PROG)-$(VERSION)
mkdir -p dist
mv $(PROG)-$(VERSION)-$(REVISION).src.tar.gz dist
$(RM) -rf $(PROG)-$(VERSION)
.PHONY: dist

30
src/common.h Normal file
View File

@ -0,0 +1,30 @@
/*
Copyright (C) 2018 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 "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "ctype.h"
#include "SDL2/SDL.h"
#include "defs.h"
#include "structs.h"

85
src/defs.h Normal file
View File

@ -0,0 +1,85 @@
/*
Copyright (C) 2018 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.
*/
#ifndef REVISION
#define REVISION 0
#endif
#ifndef DATA_DIR
#define DATA_DIR ""
#endif
#define _(string) getTranslatedString(string)
#define PI 3.14159265358979323846
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define STRNCPY(dest, src, n) strncpy(dest, src, n); dest[n - 1] = '\0'
#define TO_RAIDANS(angleDegrees) (angleDegrees * PI / 180.0)
#define TO_DEGREES(angleRadians) (angleRadians * 180.0 / PI)
#define SAVE_FILENAME "game.save"
#define CONFIG_FILENAME "config.json"
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
#define MAX_KEYBOARD_KEYS 350
#define MAX_MOUSE_BUTTONS 6
#define FPS 60
#define LOGIC_RATE (1000.0 / FPS)
#define MAX_FONTS 64
#define NUM_TEXT_BUCKETS 64
#define TEXT_TTL (1000 * 20)
#define MAX_NAME_LENGTH 32
#define MAX_DESCRIPTION_LENGTH 512
#define MAX_LINE_LENGTH 1024
#define MAX_FILENAME_LENGTH 1024
#define NUM_TEXTURE_BUCKETS 32
enum
{
CONTROL_LEFT,
CONTROL_RIGHT,
CONTROL_UP,
CONTROL_DOWN,
CONTROL_FIRE,
CONTROL_JUMP,
CONTROL_JETPACK,
CONTROL_SCREENSHOT,
CONTROL_MAX
};
enum
{
TA_LEFT,
TA_RIGHT,
TA_CENTER
};
enum
{
CH_PLAYER,
CH_MAX
};

25
src/game/game.c Normal file
View File

@ -0,0 +1,25 @@
/*
Copyright (C) 2018 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 "game.h"
void destroyGame(void)
{
}

21
src/game/game.h Normal file
View File

@ -0,0 +1,21 @@
/*
Copyright (C) 2018 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 "../common.h"

38
src/game/title.c Normal file
View File

@ -0,0 +1,38 @@
/*
Copyright (C) 2018 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 "title.h"
static void logic(void);
static void draw(void);
void initTitle(void)
{
app.delegate.logic = &logic;
app.delegate.draw = &draw;
}
static void logic(void)
{
}
static void draw(void)
{
}

23
src/game/title.h Normal file
View File

@ -0,0 +1,23 @@
/*
Copyright (C) 2018 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 "../common.h"
extern App app;

95
src/main.c Normal file
View File

@ -0,0 +1,95 @@
/*
Copyright (C) 2018 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 "main.h"
static long capFrameRate(const long then);
static void handleCommandLine(int argc, const char *argv[]);
int main(int argc, const char *argv[])
{
long then, nextSecond;
atexit(cleanup);
srand(time(NULL));
initSDL();
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
initGameSystem();
handleCommandLine(argc, argv);
nextSecond = SDL_GetTicks() + 1000;
while (1)
{
then = SDL_GetTicks();
handleInput();
app.delegate.logic();
prepareScene();
app.delegate.draw();
presentScene();
then = capFrameRate(then);
if (SDL_GetTicks() >= nextSecond)
{
game.timePlayed++;
nextSecond = SDL_GetTicks() + 1000;
}
}
return 0;
}
static long capFrameRate(const long then)
{
long wait;
wait = 16 - (SDL_GetTicks() - then);
if (wait > 0)
{
SDL_Delay(wait);
}
return SDL_GetTicks();
}
static void handleCommandLine(int argc, const char *argv[])
{
int i;
for (i = 1 ; i < argc ; i++)
{
}
initTitle();
}

35
src/main.h Normal file
View File

@ -0,0 +1,35 @@
/*
Copyright (C) 2018 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 "common.h"
#include <time.h>
extern void cleanup(void);
extern void initSDL(void);
extern void initGameSystem(void);
extern void handleInput(void);
extern void prepareScene(void);
extern void presentScene(void);
extern void initTitle(void);
App app;
Colors colors;
Dev dev;
Game game;

53
src/plat/unix/unixInit.c Normal file
View File

@ -0,0 +1,53 @@
/*
Copyright (C) 2018 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 "unixInit.h"
void createSaveFolder(void)
{
char *userHome;
char dir[MAX_FILENAME_LENGTH];
userHome = getenv("HOME");
if (!userHome)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Unable to determine user save folder. Will save to current dir.");
return;
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "User home = %s", userHome);
sprintf(dir, "%s/.local/share/blobwarsAttrition", userHome);
if (mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0 && errno != EEXIST)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Failed to create save dir '%s'. Will save to current dir.", dir);
return;
}
STRNCPY(app.saveDir, dir, MAX_FILENAME_LENGTH);
}
void createScreenshotFolder(void)
{
mkdir("/tmp/blobwarsAttrition", S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
dev.screenshotFolder = "/tmp/blobwarsAttrition";
}

29
src/plat/unix/unixInit.h Normal file
View File

@ -0,0 +1,29 @@
/*
Copyright (C) 2018 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 <sys/stat.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>
#include "../../common.h"
extern App app;
extern Dev dev;

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2018 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 "win32Init.h"
void createSaveFolder(void)
{
char *userHome;
char dir[MAX_FILENAME_LENGTH];
userHome = getenv("USERPROFILE");
if (!userHome)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Unable to determine user save folder. Will save to current dir.");
return;
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "User home = %s", userHome);
sprintf(dir, "%s\\blobwarsAttrition", userHome);
if (mkdir(dir) != 0 && errno != EEXIST)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, "Failed to create save dir '%s'. Will save to current dir.", dir);
return;
}
STRNCPY(app.saveDir, dir, MAX_FILENAME_LENGTH);
}
void createScreenshotFolder(void)
{
dev.screenshotFolder = "./";
}

View File

@ -0,0 +1,28 @@
/*
Copyright (C) 2018 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 <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "../../common.h"
extern App app;
extern Dev dev;

114
src/structs.h Normal file
View File

@ -0,0 +1,114 @@
/*
Copyright (C) 2018 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.
*/
typedef struct Texture Texture;
typedef struct Lookup Lookup;
typedef struct Entity Entity;
typedef struct {
int debug;
int takeScreenshots;
char *screenshotFolder;
int noAIWeapons;
int showFPS;
int playerImmortal;
int playerUnlimitedMissiles;
int noEntityActions;
int allImmortal;
int fps;
} Dev;
struct Texture {
char name[MAX_DESCRIPTION_LENGTH];
long hash;
long ttl;
SDL_Texture *texture;
Texture *next;
};
typedef struct {
SDL_Color red;
SDL_Color orange;
SDL_Color yellow;
SDL_Color green;
SDL_Color blue;
SDL_Color cyan;
SDL_Color purple;
SDL_Color white;
SDL_Color black;
SDL_Color lightGrey;
SDL_Color darkGrey;
} Colors;
struct Lookup {
char name[MAX_NAME_LENGTH];
long value;
Lookup *next;
};
typedef struct {
void (*logic)(void);
void (*draw)(void);
void (*handleClick)(int x, int y, int btn);
void (*handleDrag)(int x, int y, int dx, int dy, int cx, int cy);
void (*handleMouseUp)(int x, int y, int btn);
} Delegate;
struct Entity {
float x;
float y;
};
typedef struct {
int x;
int y;
int w;
int h;
int dx;
int dy;
int button[MAX_MOUSE_BUTTONS];
int dragging;
} Mouse;
typedef struct {
char saveDir[MAX_FILENAME_LENGTH];
int winWidth;
int winHeight;
float scaleX;
float scaleY;
int fullscreen;
int musicVolume;
int soundVolume;
int hideMouse;
Mouse mouse;
int keyboard[MAX_KEYBOARD_KEYS];
SDL_Texture *backBuffer;
SDL_Renderer *renderer;
SDL_Window *window;
Delegate delegate;
int awaitingWidgetInput;
int lastKeyPressed;
int lastButtonPressed;
int keyControls[CONTROL_MAX];
} App;
typedef struct {
long timePlayed;
} Game;

199
src/system/draw.c Normal file
View File

@ -0,0 +1,199 @@
/*
Copyright (C) 2018 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 "draw.h"
static void initColor(SDL_Color *c, int r, int g, int b);
void initGraphics(void)
{
initColor(&colors.red, 255, 0, 0);
initColor(&colors.orange, 255, 128, 0);
initColor(&colors.yellow, 255, 255, 0);
initColor(&colors.green, 0, 255, 0);
initColor(&colors.blue, 0, 0, 255);
initColor(&colors.cyan, 0, 255, 255);
initColor(&colors.purple, 255, 0, 255);
initColor(&colors.white, 255, 255, 255);
initColor(&colors.black, 0, 0, 0);
initColor(&colors.lightGrey, 192, 192, 192);
initColor(&colors.darkGrey, 128, 128, 128);
app.backBuffer = SDL_CreateTexture(app.renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
}
void prepareScene(void)
{
SDL_SetRenderTarget(app.renderer, app.backBuffer);
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
SDL_RenderClear(app.renderer);
}
void presentScene(void)
{
SDL_SetRenderTarget(app.renderer, NULL);
SDL_RenderCopy(app.renderer, app.backBuffer, NULL, NULL);
SDL_RenderPresent(app.renderer);
}
void clearScreen(void)
{
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(app.renderer, 0, 0, 0, 255);
SDL_RenderFillRect(app.renderer, NULL);
}
void blit(SDL_Texture *texture, int x, int y, int center)
{
SDL_Rect dstRect;
dstRect.x = x;
dstRect.y = y;
SDL_QueryTexture(texture, NULL, NULL, &dstRect.w, &dstRect.h);
if (center)
{
dstRect.x -= (dstRect.w / 2);
dstRect.y -= (dstRect.h / 2);
}
SDL_RenderCopy(app.renderer, texture, NULL, &dstRect);
}
void blitFlip(SDL_Texture *texture, int x, int y, int center, SDL_RendererFlip flip)
{
SDL_Rect dstRect;
dstRect.x = x;
dstRect.y = y;
SDL_QueryTexture(texture, NULL, NULL, &dstRect.w, &dstRect.h);
SDL_RenderCopyEx(app.renderer, texture, NULL, &dstRect, 0, NULL, flip);
}
void blitScaled(SDL_Texture *texture, int x, int y, int w, int h, int center)
{
SDL_Rect dstRect;
dstRect.x = x;
dstRect.y = y;
dstRect.w = w;
dstRect.h = h;
if (center)
{
dstRect.x -= (dstRect.w / 2);
dstRect.y -= (dstRect.h / 2);
}
SDL_RenderCopy(app.renderer, texture, NULL, &dstRect);
}
void blitRotated(SDL_Texture *texture, int x, int y, float angle)
{
SDL_Rect dstRect;
dstRect.x = x;
dstRect.y = y;
SDL_QueryTexture(texture, NULL, NULL, &dstRect.w, &dstRect.h);
dstRect.x -= (dstRect.w / 2);
dstRect.y -= (dstRect.h / 2);
SDL_RenderCopyEx(app.renderer, texture, NULL, &dstRect, angle, NULL, SDL_FLIP_NONE);
}
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
{
SDL_SetRenderDrawColor(app.renderer, r, g, b, a);
SDL_RenderDrawLine(app.renderer, x1, y1, x2, y2);
}
void drawCircle(int cx, int cy, int radius, int r, int g, int b, int a)
{
int x = radius;
int y = 0;
int radiusError = 1 - x;
SDL_Point p[8];
SDL_SetRenderDrawColor(app.renderer, r, g, b, a);
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_BLEND);
while (x >= y)
{
p[0].x = x + cx; p[0].y = y + cy;
p[1].x = y + cx; p[1].y = x + cy;
p[2].x = -x + cx; p[2].y = y + cy;
p[3].x = -y + cx; p[3].y = x + cy;
p[4].x = -x + cx; p[4].y = -y + cy;
p[5].x = -y + cx; p[5].y = -x + cy;
p[6].x = x + cx; p[6].y = -y + cy;
p[7].x = y + cx; p[7].y = -x + cy;
SDL_RenderDrawPoints(app.renderer, p, 8);
y++;
if (radiusError < 0)
{
radiusError += 2 * y + 1;
}
else
{
x--;
radiusError += 2 * (y - x) + 1;
}
}
SDL_SetRenderDrawBlendMode(app.renderer, SDL_BLENDMODE_NONE);
}
void drawRect(int x, int y, int w, int h, int r, int g, int b, int a)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
SDL_SetRenderDrawBlendMode(app.renderer, a < 255 ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(app.renderer, r, g, b, a);
SDL_RenderFillRect(app.renderer, &rect);
}
void drawOutlineRect(int x, int y, int w, int h, int r, int g, int b, int a)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
SDL_SetRenderDrawBlendMode(app.renderer, a < 255 ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(app.renderer, r, g, b, a);
SDL_RenderDrawRect(app.renderer, &rect);
}
static void initColor(SDL_Color *c, int r, int g, int b)
{
memset(c, 0, sizeof(SDL_Color));
c->r = r;
c->g = g;
c->b = b;
c->a = 255;
}

24
src/system/draw.h Normal file
View File

@ -0,0 +1,24 @@
/*
Copyright (C) 2018 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 "../common.h"
extern App app;
extern Colors colors;

108
src/system/init.c Normal file
View File

@ -0,0 +1,108 @@
/*
Copyright (C) 2018 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 "init.h"
void initSDL(void)
{
int rendererFlags, windowFlags;
/* done in src/plat/ */
createSaveFolder();
app.winWidth = SCREEN_WIDTH;
app.winHeight = SCREEN_HEIGHT;
rendererFlags = SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC;
windowFlags = 0;
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) == -1)
{
printf("Couldn't initialize SDL Mixer\n");
exit(1);
}
Mix_AllocateChannels(CH_MAX);
app.window = SDL_CreateWindow("Blob Wars : Attrition", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, app.winWidth, app.winHeight, windowFlags);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
app.renderer = SDL_CreateRenderer(app.window, -1, rendererFlags);
IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
if (TTF_Init() < 0)
{
printf("Couldn't initialize SDL TTF: %s\n", SDL_GetError());
exit(1);
}
}
void initGameSystem(void)
{
int i, numInitFuns;
void (*initFuncs[]) (void) = {
initLookups,
initGraphics,
initFonts
};
numInitFuns = sizeof(initFuncs) / sizeof(void*);
for (i = 0 ; i < numInitFuns ; i++)
{
/*showLoadingStep(i + 1, numInitFuns);*/
initFuncs[i]();
}
}
void cleanup(void)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Cleaning up ...");
destroyLookups();
destroyFonts();
destroyTextures();
expireTexts(1);
destroyGame();
SDL_DestroyRenderer(app.renderer);
SDL_DestroyWindow(app.window);
TTF_Quit();
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Done.");
SDL_Quit();
}

37
src/system/init.h Normal file
View File

@ -0,0 +1,37 @@
/*
Copyright (C) 2018 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 "../common.h"
#include "SDL2/SDL_image.h"
#include "SDL2/SDL_mixer.h"
#include "SDL2/SDL_ttf.h"
extern void createSaveFolder(void);
extern void initLookups(void);
extern void initGraphics(void);
extern void initFonts(void);
extern void destroyLookups(void);
extern void destroyFonts(void);
extern void destroyTextures(void);
extern void expireTexts(int all);
extern void destroyGame(void);
extern App app;

159
src/system/input.c Normal file
View File

@ -0,0 +1,159 @@
/*
Copyright (C) 2018 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 int mouseDownTimer;
static SDL_Point dragStart;
void initInput(void)
{
mouseDownTimer = 0;
}
static void doKeyDown(SDL_KeyboardEvent *event)
{
if (event->keysym.scancode >= 0 && event->keysym.scancode < MAX_KEYBOARD_KEYS && event->repeat == 0)
{
app.keyboard[event->keysym.scancode] = 1;
}
}
static void doKeyUp(SDL_KeyboardEvent *event)
{
if (event->keysym.scancode >= 0 && event->keysym.scancode < MAX_KEYBOARD_KEYS)
{
app.keyboard[event->keysym.scancode] = 0;
}
}
static void doMouseDown(SDL_MouseButtonEvent *event)
{
if (event->button >= 0 && event->button < MAX_MOUSE_BUTTONS)
{
app.mouse.button[event->button] = 1;
}
}
static void doMouseUp(SDL_MouseButtonEvent *event)
{
if (event->button >= 0 && event->button < MAX_MOUSE_BUTTONS)
{
app.mouse.button[event->button] = 0;
if (event->button == SDL_BUTTON_LEFT)
{
app.mouse.dragging = 0;
mouseDownTimer = 0;
}
}
}
/*
* Note: the following assumes that SDL_BUTTON_X1 and SDL_BUTTON_X2 are 4 and 5, respectively. They usually are.
*/
static void doMouseWheel(SDL_MouseWheelEvent *event)
{
if (event->y == -1)
{
app.mouse.button[SDL_BUTTON_X1] = 1;
}
if (event->y == 1)
{
app.mouse.button[SDL_BUTTON_X2] = 1;
}
}
static void doMouseMotion(SDL_MouseMotionEvent *event)
{
if (event->state & SDL_BUTTON_LMASK)
{
if (++mouseDownTimer >= 4 && (abs(dragStart.x - event->x) >= MOUSE_DRAG_THRESHOLD || abs(dragStart.y - event->y) >= MOUSE_DRAG_THRESHOLD))
{
app.mouse.dx = event->xrel;
app.mouse.dy = event->yrel;
app.mouse.dragging = 1;
dragStart.x = event->x;
dragStart.y = event->y;
}
}
else
{
mouseDownTimer = 0;
}
}
void clearInput(void)
{
SDL_Event event;
memset(app.keyboard, 0, sizeof(int) * MAX_KEYBOARD_KEYS);
memset(&app.mouse, 0, sizeof(Mouse));
while (SDL_PollEvent(&event))
{
}
}
void handleInput(void)
{
SDL_Event event;
app.mouse.dx = 0;
app.mouse.dy = 0;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
doMouseMotion(&event.motion);
break;
case SDL_MOUSEWHEEL:
doMouseWheel(&event.wheel);
break;
case SDL_MOUSEBUTTONDOWN:
doMouseDown(&event.button);
break;
case SDL_MOUSEBUTTONUP:
doMouseUp(&event.button);
break;
case SDL_KEYDOWN:
doKeyDown(&event.key);
break;
case SDL_KEYUP:
doKeyUp(&event.key);
break;
case SDL_QUIT:
exit(0);
break;
}
}
SDL_GetMouseState(&app.mouse.x, &app.mouse.y);
}

25
src/system/input.h Normal file
View File

@ -0,0 +1,25 @@
/*
Copyright (C) 2018 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.
*/
#define MOUSE_DRAG_THRESHOLD 4
#include "../common.h"
extern App app;

163
src/system/io.c Normal file
View File

@ -0,0 +1,163 @@
/*
Copyright (C) 2018 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 "io.h"
static int stringComparator(const void *a, const void *b);
int fileExists(const char *filename)
{
struct stat buffer;
return (stat(filename, &buffer) == 0);
}
const char *getFileLocation(const char *filename)
{
static char path[MAX_FILENAME_LENGTH];
memset(path, '\0', MAX_FILENAME_LENGTH);
if (fileExists(filename))
{
return filename;
}
sprintf(path, DATA_DIR"/%s", filename);
if (!fileExists(path))
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_CRITICAL, "No such file '%s'", path);
exit(1);
}
return path;
}
char *readFile(const char *filename)
{
char *buffer = 0;
unsigned long length;
FILE *file = fopen(getFileLocation(filename), "rb");
if (file)
{
fseek(file, 0, SEEK_END);
length = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = malloc(length + 1);
memset(buffer, 0, length + 1);
fread(buffer, 1, length, file);
fclose(file);
buffer[length] = '\0';
}
return buffer;
}
int writeFile(const char *filename, const char *data)
{
FILE *file = fopen(filename, "wb");
if (file)
{
fprintf(file, "%s\n", data);
fclose(file);
return 1;
}
return 0;
}
char *getSaveFilePath(const char *filename)
{
static char path[MAX_FILENAME_LENGTH];
memset(path, '\0', MAX_FILENAME_LENGTH);
sprintf(path, "%s/%s", app.saveDir, filename);
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "getSaveFilePath = '%s'", path);
return path;
}
char **getFileList(const char *dir, int *count)
{
DIR *d;
int i;
struct dirent *ent;
char **filenames;
i = 0;
filenames = NULL;
if ((d = opendir(getFileLocation(dir))) != NULL)
{
while ((ent = readdir(d)) != NULL)
{
if (ent->d_name[0] != '.')
{
i++;
}
}
if (i > 0)
{
filenames = malloc(sizeof(char*) * i);
memset(filenames, 0, sizeof(char*) * i);
rewinddir(d);
i = 0;
while ((ent = readdir(d)) != NULL)
{
if (ent->d_name[0] != '.')
{
filenames[i] = malloc(sizeof(char) * MAX_FILENAME_LENGTH);
STRNCPY(filenames[i], ent->d_name, MAX_FILENAME_LENGTH);
i++;
}
}
}
closedir(d);
}
*count = i;
if (filenames)
{
qsort(filenames, i, sizeof(char*), stringComparator);
}
return filenames;
}
static int stringComparator(const void *a, const void *b)
{
char **s1 = (char **)a;
char **s2 = (char **)b;
return strcmp(*s1, *s2);
}

26
src/system/io.h Normal file
View File

@ -0,0 +1,26 @@
/*
Copyright (C) 2018 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 "../common.h"
#include "sys/stat.h"
#include "dirent.h"
extern App app;

147
src/system/lookup.c Normal file
View File

@ -0,0 +1,147 @@
/*
Copyright (C) 2018 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 "lookup.h"
static Lookup head;
static Lookup *tail;
static void addLookup(const char *name, long value);
void initLookups(void)
{
memset(&head, 0, sizeof(Lookup));
tail = &head;
addLookup("DUMMY", 0);
}
static void addLookup(const char *name, long value)
{
Lookup *lookup = malloc(sizeof(Lookup));
memset(lookup, 0, sizeof(Lookup));
STRNCPY(lookup->name, name, MAX_NAME_LENGTH);
lookup->value = value;
tail->next = lookup;
tail = lookup;
}
long lookup(const char *name)
{
Lookup *l;
for (l = head.next ; l != NULL ; l = l->next)
{
if (strcmp(l->name, name) == 0)
{
return l->value;
}
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "No such lookup value '%s'", name);
exit(1);
return 0;
}
char *getLookupName(const char *prefix, long num)
{
Lookup *l;
for (l = head.next ; l != NULL ; l = l->next)
{
if (l->value == num && strncmp(prefix, l->name, strlen(prefix)) == 0)
{
return l->name;
}
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "No such lookup value %ld, prefix=%s", num, prefix);
exit(1);
return "";
}
const char *getFlagValues(const char *prefix, long flags)
{
static char flagStr[MAX_DESCRIPTION_LENGTH];
int requirePlus;
Lookup *l;
memset(flagStr, '\0', MAX_DESCRIPTION_LENGTH);
requirePlus = 0;
for (l = head.next ; l != NULL ; l = l->next)
{
if (flags & l->value && strncmp(prefix, l->name, strlen(prefix)) == 0)
{
if (requirePlus)
{
strcat(flagStr, "+");
}
strcat(flagStr, l->name);
requirePlus = 1;
}
}
return flagStr;
}
long flagsToLong(const char *in)
{
char *flag, *flags;
long total;
total = 0;
if (strlen(in) > 0)
{
flags = malloc(strlen(in) + 1);
STRNCPY(flags, in, strlen(in) + 1);
flag = strtok(flags, "+");
while (flag)
{
total += lookup(flag);
flag = strtok(NULL, "+");
}
free(flags);
}
return total;
}
void destroyLookups(void)
{
Lookup *l;
while (head.next)
{
l = head.next;
head.next = l->next;
free(l);
}
}

23
src/system/lookup.h Normal file
View File

@ -0,0 +1,23 @@
/*
Copyright (C) 2018 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 "../common.h"
long flagsToLong(const char *in);

314
src/system/text.c Normal file
View File

@ -0,0 +1,314 @@
/*
Copyright (C) 2018 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 "text.h"
static void loadFont(int size);
static SDL_Texture *getCachedText(unsigned long hash);
static void cacheText(unsigned long hash, SDL_Texture *t);
static void drawTextNormal(int x, int y, int size, int align, SDL_Color c, const char *text);
static void drawTextSplit(int x, int y, int size, int align, SDL_Color c, char *text);
void textSize(const char *text, int size, int *w, int *h);
static char drawTextBuffer[MAX_LINE_LENGTH];
static TTF_Font *font[MAX_FONTS];
static Texture textures[NUM_TEXT_BUCKETS];
static int maxWidth = 0;
static int cacheSize = 0;
static int textShadow = 1;
static SDL_Color textShadowColor;
void initFonts(void)
{
memset(&font, 0, sizeof(TTF_Font*) * MAX_FONTS);
memset(&textures, 0, sizeof(Texture) * NUM_TEXT_BUCKETS);
}
void drawText(int x, int y, int size, int align, SDL_Color c, const char *format, ...)
{
va_list args;
memset(&drawTextBuffer, '\0', sizeof(drawTextBuffer));
va_start(args, format);
vsprintf(drawTextBuffer, format, args);
va_end(args);
if (maxWidth == 0)
{
drawTextNormal(x, y, size, align, c, drawTextBuffer);
}
else
{
drawTextSplit(x, y, size, align, c, drawTextBuffer);
}
}
static void drawTextNormal(int x, int y, int size, int align, SDL_Color c, const char *text)
{
SDL_Surface *surface;
SDL_Texture *t;
int w, h;
long hash;
if (size >= MAX_FONTS)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_CRITICAL, "ERROR: %d exceeds max font size index of %d\n", size, MAX_FONTS);
exit(1);
}
if (!font[size])
{
loadFont(size);
}
hash = hashcode(text) + size;
t = getCachedText(hash);
if (!t)
{
surface = TTF_RenderText_Blended(font[size], text, colors.white);
t = SDL_CreateTextureFromSurface(app.renderer, surface);
SDL_FreeSurface(surface);
cacheText(hash, t);
}
SDL_QueryTexture(t, NULL, NULL, &w, &h);
if (align == TA_CENTER)
{
x -= (w / 2);
}
else if (align == TA_RIGHT)
{
x -= w;
}
if (textShadow)
{
SDL_SetTextureColorMod(t, textShadowColor.r, textShadowColor.g, textShadowColor.b);
blit(t, x + 1, y + 1, 0);
blit(t, x + 2, y + 2, 0);
}
SDL_SetTextureColorMod(t, c.r, c.g, c.b);
blit(t, x, y, 0);
}
static void drawTextSplit(int x, int y, int size, int align, SDL_Color c, char *text)
{
char drawTextBuffer[MAX_DESCRIPTION_LENGTH];
char *token;
int w, h, currentWidth;
memset(&drawTextBuffer, '\0', sizeof(drawTextBuffer));
token = strtok(text, " ");
currentWidth = 0;
while (token)
{
textSize(token, size, &w, &h);
if (currentWidth + w > maxWidth)
{
drawTextNormal(x, y, size, align, c, drawTextBuffer);
currentWidth = 0;
y += h;
memset(&drawTextBuffer, '\0', sizeof(drawTextBuffer));
}
strcat(drawTextBuffer, token);
strcat(drawTextBuffer, " ");
currentWidth += w;
token = strtok(NULL, " ");
}
drawTextNormal(x, y, size, align, c, drawTextBuffer);
}
int getWrappedTextHeight(const char *text, int size)
{
char textBuffer[MAX_DESCRIPTION_LENGTH];
char *token;
int w, h, currentWidth;
int y;
STRNCPY(textBuffer, text, MAX_DESCRIPTION_LENGTH);
token = strtok(textBuffer, " ");
y = 0;
currentWidth = 0;
while (token)
{
textSize(token, size, &w, &h);
if (currentWidth + w > maxWidth)
{
currentWidth = 0;
y += h;
}
currentWidth += w;
token = strtok(NULL, " ");
}
return y + h;
}
void textSize(const char *text, int size, int *w, int *h)
{
if (!font[size])
{
loadFont(size);
}
TTF_SizeText(font[size], text, w, h);
}
void limitTextWidth(int width)
{
maxWidth = width;
}
void useTextShadow(int enable, int r, int g, int b)
{
textShadow = 1;
textShadowColor.r = r;
textShadowColor.g = g;
textShadowColor.b = b;
}
static SDL_Texture *getCachedText(unsigned long hash)
{
Texture *t;
int i;
i = hash % NUM_TEXT_BUCKETS;
t = textures[i].next;
for (t = textures[i].next ; t != NULL ; t = t->next)
{
if (t->hash == hash)
{
t->ttl = SDL_GetTicks() + TEXT_TTL;
return t->texture;
}
}
return NULL;
}
static void cacheText(unsigned long hash, SDL_Texture *texture)
{
Texture *t, *new;
int i;
i = hash % NUM_TEXT_BUCKETS;
t = &textures[i];
/* horrible bit to find the tail */
while (t->next)
{
t = t->next;
}
new = malloc(sizeof(Texture));
memset(new, 0, sizeof(Texture));
new->hash = hash;
new->texture = texture;
new->ttl = SDL_GetTicks() + TEXT_TTL;
t->next = new;
cacheSize++;
}
void expireTexts(int all)
{
Texture *t, *prev;
int i, n;
long now;
n = 0;
now = SDL_GetTicks();
for (i = 0 ; i < NUM_TEXT_BUCKETS ; i++)
{
prev = &textures[i];
for (t = textures[i].next ; t != NULL ; t = t->next)
{
if (t->ttl <= now || all)
{
prev->next = t->next;
SDL_DestroyTexture(t->texture);
free(t);
cacheSize--;
n++;
t = prev;
}
prev = t;
}
}
if (n > 0)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Expired %d texts", n);
}
}
static void loadFont(int size)
{
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "loadFonts(%d)", size);
font[size] = TTF_OpenFont(getFileLocation("data/fonts/LiberationMono-Regular.ttf"), size);
}
void destroyFonts(void)
{
int i;
for (i = 0 ; i < MAX_FONTS ; i++)
{
if (font[i])
{
TTF_CloseFont(font[i]);
}
}
}

30
src/system/text.h Normal file
View File

@ -0,0 +1,30 @@
/*
Copyright (C) 2018 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 "../common.h"
#include "SDL2/SDL_ttf.h"
extern void blit(SDL_Texture *texture, int x, int y, int centered);
extern char *getFileLocation(const char *filename);
extern unsigned long hashcode(const char *str);
extern App app;
extern Colors colors;

111
src/system/textures.c Normal file
View File

@ -0,0 +1,111 @@
/*
Copyright (C) 2018 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 "textures.h"
static Texture textures[NUM_TEXTURE_BUCKETS];
static Texture *addTextureToCache(const char *name, SDL_Texture *texture);
Texture *getTexture(const char *name);
void initTextures(void)
{
memset(&textures, 0, sizeof(Texture) * NUM_TEXTURE_BUCKETS);
}
static Texture *addTextureToCache(const char *name, SDL_Texture *texture)
{
Texture *t, *new;
int i;
i = hashcode(name) % NUM_TEXTURE_BUCKETS;
t = &textures[i];
/* horrible bit to look for the tail */
while (t->next)
{
t = t->next;
}
new = malloc(sizeof(Texture));
memset(new, 0, sizeof(Texture));
STRNCPY(new->name, name, MAX_DESCRIPTION_LENGTH);
new->texture = texture;
t->next = new;
return new;
}
static Texture *loadTexture(const char *filename)
{
SDL_Texture *texture;
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", filename);
texture = IMG_LoadTexture(app.renderer, getFileLocation(filename));
return addTextureToCache(filename, texture);
}
Texture *getTexture(const char *filename)
{
Texture *t;
int i;
i = hashcode(filename) % NUM_TEXTURE_BUCKETS;
/* check if the texture is already loaded */
for (t = textures[i].next ; t != NULL ; t = t->next)
{
if (strcmp(t->name, filename) == 0)
{
return t;
}
}
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "%s not in texture cache", filename);
return loadTexture(filename);
}
void destroyTextures(void)
{
Texture *t, *next;
int i;
for (i = 0 ; i < NUM_TEXTURE_BUCKETS ; i++)
{
t = textures[i].next;
while (t)
{
next = t->next;
SDL_DestroyTexture(t->texture);
free(t);
t = next;
}
textures[i].next = NULL;
}
}

28
src/system/textures.h Normal file
View File

@ -0,0 +1,28 @@
/*
Copyright (C) 2018 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 "../common.h"
#include "SDL2/SDL_image.h"
extern char *getFileLocation(const char *filename);
extern unsigned long hashcode(const char *str);
extern App app;

82
src/util/maths.c Normal file
View File

@ -0,0 +1,82 @@
/*
Copyright (C) 2018 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 "maths.h"
int mod(int n, int x)
{
return ((n % x) + x) % x;
}
int rrnd(int low, int high)
{
return low + rand() % ((high - low) + 1);
}
int getPercent(float current, float total)
{
return (current / total) * 100;
}
int getDistance(int x1, int y1, int x2, int y2)
{
int x, y;
x = x2 - x1;
y = y2 - y1;
return sqrt(x * x + y *y);
}
void getSlope(int x1, int y1, int x2, int y2, float *dx, float *dy)
{
int steps = MAX(abs(x1 - x2), abs(y1 - y2));
if (steps == 0)
{
*dx = *dy = 0;
return;
}
*dx = (x1 - x2);
*dx /= steps;
*dy = (y1 - y2);
*dy /= steps;
}
unsigned long hashcode(const char *str)
{
unsigned long hash = 5381;
int c;
c = *str;
while (c)
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
c = *str++;
}
hash = ((hash << 5) + hash);
return hash;
}

22
src/util/maths.h Normal file
View File

@ -0,0 +1,22 @@
/*
Copyright (C) 2018 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 "../common.h"

49
src/util/util.c Normal file
View File

@ -0,0 +1,49 @@
/*
Copyright (C) 2018 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 "util.h"
int collision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
return (MAX(x1, x2) < MIN(x1 + w1, x2 + w2)) && (MAX(y1, y2) < MIN(y1 + h1, y2 + h2));
}
char *timeToString(long millis, int showHours)
{
static char TIME[MAX_NAME_LENGTH];
int hours, minutes, seconds;
seconds = millis / FPS;
minutes = (seconds / FPS) % 60;
hours = seconds / (FPS * FPS);
seconds %= 60;
if (showHours)
{
sprintf(TIME, "%dh %02dm %02ds", hours, minutes, seconds);
}
else
{
sprintf(TIME, "%dm %02ds", minutes, seconds);
}
return TIME;
}

22
src/util/util.h Normal file
View File

@ -0,0 +1,22 @@
/*
Copyright (C) 2018 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 "../common.h"