Compare commits

..

6 Commits

Author SHA1 Message Date
Kayne Ruse 8f39d58107 A few tweaks 2014-06-21 04:05:16 +10:00
Kayne Ruse ccc57ec2d2 Basic perlin noise is working 2014-06-21 02:46:50 +10:00
Kayne Ruse fbaf15337f Working on a new generator class, nearly there 2014-06-18 01:00:31 +10:00
Kayne Ruse ff5c170579 Ditched the perlin I wrote before 2014-06-17 22:15:06 +10:00
Kayne Ruse 1cd198ad66 Tweaks, trying to get it to work 2014-06-17 06:48:01 +10:00
Kayne Ruse 2b46608d68 Initial commit, basic infrastructure 2014-06-17 05:41:59 +10:00
33 changed files with 1132 additions and 984 deletions
-25
View File
@@ -1,25 +0,0 @@
#Editor generated files
*.sln
*.vcproj
*.suo
*.ncb
*.user
#Directories
Release/
Debug/
Out/
release/
debug/
out/
bin/
#Project generated files
*.db
*.o
*.a
*.exe
#Shell files
*.bat
*.sh
-3
View File
@@ -1,3 +0,0 @@
[submodule "common"]
path = common
url = https://github.com/Ratstail91/Tortuga.git
Submodule common deleted from 3eafb57403
+11 -11
View File
@@ -1,23 +1,23 @@
#for use on Windows:
#MKDIR=mkdir
#RM=del /y
CXXFLAGS+=-static-libgcc -static-libstdc++
export
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C common
$(MAKE) -C utils
$(MAKE) -C mapgen
$(MAKE) -C src
debug: export CXXFLAGS+=-g
debug: clean all
$(OUTDIR):
mkdir $(OUTDIR)
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.o *.a *.exe
else ifeq ($(shell uname), Linux)
find . -type f -name '*.o' -exec rm -f -r -v {} \;
find . -type f -name '*.a' -exec rm -f -r -v {} \;
rm -f -v $(OUT)
find . -empty -type d -delete
endif
rebuild: clean all
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=. ../utils
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+120
View File
@@ -0,0 +1,120 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_generator.hpp"
#include "vector2.hpp"
#include <cmath>
//-------------------------
//Utility functions
//-------------------------
//snap to a grid (floating point version)
static double snap(double x, double base) {
return floor(x / base) * base;
}
//A.K.A.: the dot product
static double scalarProduct(Vector2 lhs, Vector2 rhs) {
return lhs.x * rhs.x + lhs.y * rhs.y;
}
//curved interpolation
static double curve(double x) {
//param: 0 to 1 inclusive
return 3.0 * pow(x, 2.0) - 2.0 * pow(x, 3.0);
}
//fix the overflow
static double curl(double x) {
if (x > 1.0) {
return -curl(x-1) +1;
}
if (x < 0.0) {
return curl(-x);
}
return x;
}
static double cut(double x) {
if (x > 1.0) {
return 1.0;
}
if (x < 0.0) {
return 0.0;
}
return x;
}
//-------------------------
//Public methods
//-------------------------
Vector2 MapGenerator::RawNoise(Vector2 const& gridPoint) {
double angle = rng(gridPoint.x * 0xffff + gridPoint.y);
Vector2 v = {cos(angle), sin(angle)};
v.Normalize();
return v;
}
double MapGenerator::Influence(Vector2 const& gridPoint, Vector2 const& queryPoint, double width, double height) {
//note: inverting the distance here, so the smaller the distance the more influence it has
Vector2 distance = queryPoint - gridPoint;
Vector2 inverted = {width - distance.x, height - distance.y};
double ret = scalarProduct(RawNoise(gridPoint), inverted);
return ret > 0 ? ret : -ret;
}
double MapGenerator::ScaledNoise(double x, double y, double width, double height) {
Vector2 queryPoint = {x, y};
//the "grid points"
Vector2 tl = {snap(x, width), snap(y, height)};
Vector2 tr = {tl.x + width, tl.y};
Vector2 bl = {tl.x, tl.y + height};
Vector2 br = {tl.x + width, tl.y + height};
//influence equasion
double s = Influence(tl, queryPoint, width, height);
double t = Influence(tr, queryPoint, width, height);
double u = Influence(bl, queryPoint, width, height);
double v = Influence(br, queryPoint, width, height);
//Finally, calc the value
double a = s + curve((t - s) / width);
double b = u + curve((v - u) / width);
return curve((b - a) / height);
}
double MapGenerator::ScaledOctave(double x, double y, double width, double height, double octave) {
double ret = 0;
if (octave > 1) {
ret += ScaledOctave(x, y, width/2, height/2, octave-1);
}
return ret / octave + ScaledNoise(x, y, width, height);
}
double MapGenerator::GetPixel(double x, double y, double width, double height, double octave) {
//use this as a decorator function
return curl(ScaledOctave(x, y, width, height, octave));
}
+44
View File
@@ -0,0 +1,44 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef MAPGENERATOR_HPP_
#define MAPGENERATOR_HPP_
#include "simple_rng.hpp"
#include "vector2.hpp"
class MapGenerator {
public:
MapGenerator() = default;
~MapGenerator() = default;
Vector2 RawNoise(Vector2 const&);
double Influence(Vector2 const& gridPoint, Vector2 const& queryPoint, double width, double height);
double ScaledNoise(double x, double y, double width, double height);
double ScaledOctave(double x, double y, double width, double height, double octave);
double GetPixel(double x, double y, double width, double height, double octave);
private:
SimpleRNG rng;
};
#endif
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

-139
View File
@@ -1,139 +0,0 @@
--generate a roguelike map
--[[ DOCS: Game design theory, read more
As a basic starting point, I can create a list of "seed" tiles, which are the
center of rooms. The rooms can be any size, as long as they don't overlap. From
There, a tunnel can be "carved" from each seed tile to the next. Finally, the
map is populated, but that is beyond this exercise.
This specification isn't ironclad, as the current implementation has no overlap
prevention, resulting in some strange dungeon designs.
--]]
print("Beginning generator...")
function newroom(northBound, eastBound, southBound, westBound)
--place the room within proximity of the center, so that they're not too far apart.
local x = math.random(westBound, eastBound)
local y = math.random(northBound, southBound)
local w = math.random(2, 5)
local h = math.random(2, 5)
--return this new room
return {
seedX = x,
seedY = y,
--give it a decent size
north = y - h,
south = y + h,
east = x + w,
west = x - w,
}
end
function newpath(x1, y1, x2, y2)
--NOTE: a path is an ordered list of {x, y} pairs
local path = {}
local step = 0
--vertical
if y1 > y2 then
step = -1
else
step = 1
end
for i = y1, y2, step do
table.insert(path, {x = x1, y = i})
end
--horizontal
if x1 > x2 then
step = -1
else
step = 1
end
for i = x1, x2, step do
table.insert(path, {x = i, y = y2})
end
--NOTE: {x, y} pairs are duplicated at the corners
--TODO: improve the pathing system
return path
end
function buildpaths(roomlist)
local roomcount = #roomlist
local pathlist = {}
--tunnel the shortest paths
for i = 1, roomcount-1 do
table.insert(pathlist, newpath(
roomlist[i].seedX,
roomlist[i].seedY,
roomlist[i+1].seedX,
roomlist[i+1].seedY))
end
--return the new paths
return pathlist
end
print("Populating lists")
math.randomseed(os.time())
roomlist = {}
pathlist = {}
--populate the roomlist
roomcount = math.random(10, 15)
for i = 1, roomcount do
table.insert(roomlist, newroom(-30, 0, 30, -60)) --60x60
end
roomcount = math.random(5, 10)
for i = 1, roomcount do
table.insert(roomlist, newroom(-30, 50, 30, -10)) --60x60
end
print("Building boss room")
--boss room
local bossRoom = {
seedX = math.random(60, 90),
seedY = math.random(-30, 30),
}
bossRoom.north = bossRoom.seedY - 5
bossRoom.south = bossRoom.seedY + 5
bossRoom.east = bossRoom.seedX + 5
bossRoom.west = bossRoom.seedX - 5
table.insert(roomlist, bossRoom)
--paths
pathlist = buildpaths(roomlist)
--pass the data onto the pager
pager = ... --called as a chunk
--create the rooms
for k, iter in next, roomlist do
--for each tile in the room
for i = iter.west, iter.east do
for j = iter.north, iter.south do
--set
region_pager.SetTile(pager, i, j, 0, 14)
end
end
end
--create the paths
iter = nil
for k, path in next, pathlist do --multiple paths in the lsit
for k, iter in next, path do
--for each tile in the path, set
region_pager.SetTile(pager, iter.x, iter.y, 0, 14)
end
end
print("Generator finished")
-80
View File
@@ -1,80 +0,0 @@
--the indeces of tiles from an associated tileset
--this file is intended for use with a generator
--store the tilesheet's format
local format = {
fname = "roguetileset.png",
sheetWidth = 256,
sheetHeight = 256,
tileWidth = 16,
tileHeight = 16,
countX = 16,
countY = 16
}
--define the walls of the simple "walls" set
local walls = {
--concave
nw = format.countX * 0 + 1, n = format.countX * 0 + 2, ne = format.countX * 0 + 3,
w = format.countX * 1 + 1, e = format.countX * 1 + 3,
sw = format.countX * 2 + 1, s = format.countX * 2 + 2, se = format.countX * 2 + 3,
--convex (corner pieces jutting out)
--DOCS: These are named according to the corresponding tile they fit
sec = format.countX * 0 + 7, swc = format.countX * 0 + 9,
nec = format.countX * 2 + 7, nwc = format.countX * 2 + 9
}
--define the corridor pieces
--named for their door locations in the order nesw
local corridors = {
--straight
ns = 10, ew = 11,
--dead ends
s = format.countX * 0 + 8,
w = format.countX * 1 + 9,
n = format.countX * 2 + 8,
e = format.countX * 1 + 7,
--loop (compass)
es = format.countX * 0 + 4, esw = format.countX * 0 + 5, sw = format.countX * 0 + 6,
nes = format.countX * 1 + 4, nesw = format.countX * 1 + 5, nsw = format.countX * 1 + 6,
ne = format.countX * 2 + 4, new = format.countX * 2 + 5, nw = format.countX * 2 + 6
}
--DEBUG: dump the values
--[[
print("walls:")
for k, v in pairs(walls) do
print("", k, v)
end
print("corridors:")
for k, v in pairs(corridors) do
print("", k, v)
end
--]]
--DEBUG: test the values
--[[
local test = {}
for k, v in pairs(walls) do
if test[v] then
print("Error found: ", k)
return
end
test[v] = true
end
for k, v in pairs(corridors) do
if test[v] then
print("Error found: ", k)
return
end
test[v] = true
end
print("No errors detected")
--]]
return {format, walls, corridors}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
-35
View File
@@ -1,35 +0,0 @@
--args are: userdata RegionPagerLua;
print("Running startup script")
pager = ...
--[[
--DOCS: These lambdas should return true or false, depending on if the operation succeeded or not
--DOCS: No return value given is recognized as a failure
--DOCS: OnCreate() and OnUnload() return values are currently ignored
region_pager.SetOnLoad(pager, function(r)
print("Calling SetOnLoad's lambda")
end)
region_pager.SetOnSave(pager, function(r)
print("Calling SetOnSave's lambda")
end)
region_pager.SetOnCreate(pager, function(r)
print("Calling SetOnCreate's lambda")
end)
region_pager.SetOnUnload(pager, function(r)
print("Calling SetOnUnload's lambda")
end)
--]]
generator, msg = loadfile("../rsc/roguegenerator.lua")
if generator == nil then
print("error: ", msg)
else
generator(pager)
end
print("Finished startup script")
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

+48 -164
View File
@@ -1,11 +1,11 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* including commercial Applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
@@ -21,206 +21,90 @@
*/
#include "application.hpp"
#include <chrono>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <chrono>
#include <sstream>
void Application::Init(int argc, char* argv[]) {
//create and check the window
window = SDL_CreateWindow(
"Example Caption",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
screenWidth,
screenHeight,
SDL_WINDOW_RESIZABLE);
//-------------------------
//Scene headers
//-------------------------
if (!window) {
std::ostringstream msg;
msg << "Failed to create the window: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
//Add the custom scene headers here
#include "shell_scene.hpp"
//-------------------------
//Public access members
//-------------------------
void Application::Init(int argc, char** argv) {
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
else {
std::cout << "Created the window" << std::endl;
}
//create and check the renderer
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
std::ostringstream msg;
msg << "Failed to create the renderer: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Created the renderer" << std::endl;
}
//screen scaling
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
//set the hook for the renderer
BaseScene::SetRenderer(renderer);
std::cout << "Initialized screen scaling" << std::endl;
//setting up SDL2_ttf
if (TTF_Init()) {
std::ostringstream msg;
msg << "Failed to initialize SDL2_ttf: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Initialized SDL2_ttf" << std::endl;
}
//setup lua
lua = luaL_newstate();
if (!lua) {
std::ostringstream msg;
msg << "Failed to create the lua state";
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Initialized lua" << std::endl;
}
luaL_openlibs(lua);
std::cout << "Initialization sucessful" << std::endl;
BaseScene::SetScreen(800, 600, 0, SDL_HWSURFACE|SDL_DOUBLEBUF);
}
void Application::Proc() {
//load the first scene
ProcessSceneSignal(SceneSignal::FIRST);
LoadScene(SceneList::FIRST);
//fixed frame rate
//prepare the time system
typedef std::chrono::steady_clock Clock;
std::chrono::duration<int, std::milli> delta(16);
Clock::time_point simTime = Clock::now();
Clock::time_point realTime;
constexpr std::chrono::duration<int, std::milli> frameDelay(16); //~60FPS
//the game loop continues until the scenes signal QUIT
while(activeScene->GetSceneSignal() != SceneSignal::QUIT) {
//switch scenes if necessary
if(activeScene->GetSceneSignal() != SceneSignal::CONTINUE) {
ProcessSceneSignal(activeScene->GetSceneSignal());
//The main loop
while(activeScene->GetNextScene() != SceneList::QUIT) {
//switch scenes when necessary
if (activeScene->GetNextScene() != SceneList::CONTINUE) {
LoadScene(activeScene->GetNextScene());
continue;
}
//update the current time
realTime = Clock::now();
//simulate the game or give the machine a break
if (simTime < realTime) {
while(simTime < realTime) {
//call the user defined functions
activeScene->FrameStart();
ProcessEvents();
activeScene->Update();
activeScene->FrameEnd();
//step to the next frame
simTime += frameDelay;
}
}
else {
SDL_Delay(1);
//simulate game time
while (simTime < realTime) {
//call each user defined function
activeScene->RunFrame(double(delta.count()) / std::chrono::duration<int, std::milli>::period::den);
simTime += delta;
}
SDL_RenderClear(renderer);
activeScene->RenderFrame(renderer);
SDL_RenderPresent(renderer);
//draw the game to the screen
activeScene->RenderFrame();
}
//cleanup
ClearScene();
UnloadScene();
}
void Application::Quit() {
std::cout << "Closing the APIs" << std::endl;
lua_close(lua);
TTF_Quit();
//clean up after the program
BaseScene::SetRenderer(nullptr);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
//-------------------------
//Scene management
//Private access members
//-------------------------
void Application::ProcessEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
activeScene->QuitEvent();
break;
case SDL_MOUSEMOTION:
activeScene->MouseMotion(event.motion);
break;
case SDL_MOUSEBUTTONDOWN:
activeScene->MouseButtonDown(event.button);
break;
case SDL_MOUSEBUTTONUP:
activeScene->MouseButtonUp(event.button);
break;
case SDL_MOUSEWHEEL:
activeScene->MouseWheel(event.wheel);
break;
case SDL_KEYDOWN:
activeScene->KeyDown(event.key);
break;
case SDL_KEYUP:
activeScene->KeyUp(event.key);
break;
//TODO: joystick and controller events
//window events are handled internally
case SDL_WINDOWEVENT:
switch(event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
SDL_RenderSetLogicalSize(renderer, event.window.data1, event.window.data2);
break;
}
break;
}
}
}
//Add the custom scene headers here
#include "example_scene.hpp"
void Application::ProcessSceneSignal(SceneSignal signal) {
ClearScene();
switch(signal) {
case SceneSignal::FIRST:
case SceneSignal::EXAMPLE_SCENE:
activeScene = new ExampleScene(lua);
void Application::LoadScene(SceneList sceneIndex) {
UnloadScene();
switch(sceneIndex) {
//add scene creation calls here
case SceneList::FIRST:
case SceneList::SHELL:
activeScene = new ShellScene();
break;
default: {
std::ostringstream msg;
msg << "Failed to recognize the scene signal: " << signal;
msg << "Failed to recognize the scene index: ";
msg << sceneIndex;
throw(std::logic_error(msg.str()));
}
}
}
void Application::ClearScene() {
void Application::UnloadScene() {
delete activeScene;
activeScene = nullptr;
}
}
+10 -23
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,40 +19,27 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#ifndef APPLICATION_HPP_
#define APPLICATION_HPP_
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "scene_signal.hpp"
#include "lua.hpp"
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
//TODO: do something with these
constexpr int screenWidth = 800;
constexpr int screenHeight = 600;
//DOCS: The Application class handles scene switching, utilizing only one window
class Application {
public:
Application() = default;
~Application() = default;
void Init(int argc, char* argv[]);
void Init(int argc, char** argv);
void Proc();
void Quit();
private:
//scene management
void ProcessEvents();
void ProcessSceneSignal(SceneSignal);
void ClearScene();
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
BaseScene* activeScene = nullptr;
};
//TODO: build a "window" class?
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
lua_State* lua = nullptr;
};
#endif
+103 -69
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -21,85 +21,119 @@
*/
#include "base_scene.hpp"
SDL_Renderer* BaseScene::rendererHandle = nullptr;
#include <stdexcept>
//-------------------------
//Static declarations
//-------------------------
SDL_Surface* BaseScene::screen = nullptr;
//-------------------------
//Public access members
//-------------------------
BaseScene::BaseScene() {
//EMPTY
//
}
BaseScene::~BaseScene() {
//EMPTY
}
void BaseScene::RenderFrame(SDL_Renderer* renderer) {
//EMPTY
}
void BaseScene::SetRenderer(SDL_Renderer* r) {
rendererHandle = r;
}
SDL_Renderer* BaseScene::GetRenderer() {
return rendererHandle;
}
void BaseScene::SetSceneSignal(SceneSignal signal) {
sceneSignal = signal;
}
SceneSignal BaseScene::GetSceneSignal() {
return sceneSignal;
//
}
//-------------------------
//frame phases
//Program control
//-------------------------
void BaseScene::FrameStart() {
//EMPTY
}
void BaseScene::Update() {
//EMPTY
}
void BaseScene::FrameEnd() {
//EMPTY
}
//-------------------------
//input events
//-------------------------
void BaseScene::QuitEvent() {
sceneSignal = SceneSignal::QUIT;
}
void BaseScene::MouseMotion(SDL_MouseMotionEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseWheel(SDL_MouseWheelEvent const& event) {
//EMPTY
}
void BaseScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) {
if (!bpp) {
bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
}
screen = SDL_SetVideoMode(w, h, bpp, flags);
if (!screen) {
throw(std::runtime_error("Failed to create the screen surface"));
}
return screen;
}
void BaseScene::KeyUp(SDL_KeyboardEvent const& event) {
//EMPTY
SDL_Surface* BaseScene::GetScreen() {
return screen;
}
SceneList BaseScene::SetNextScene(SceneList sceneIndex) {
return nextScene = sceneIndex;
}
SceneList BaseScene::GetNextScene() const {
return nextScene;
}
//-------------------------
//Frame loop
//-------------------------
void BaseScene::RunFrame(double delta) {
FrameStart();
HandleEvents();
Update(delta);
FrameEnd();
}
void BaseScene::RenderFrame() {
SDL_FillRect(screen, 0, 0);
Render(screen);
SDL_Flip(screen);
}
//-------------------------
//Event handlers
//-------------------------
void BaseScene::HandleEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
QuitEvent();
break;
case SDL_VIDEORESIZE:
SetScreen(event.resize.w, event.resize.h, 0, screen->flags);
break;
case SDL_MOUSEMOTION:
MouseMotion(event.motion);
break;
case SDL_MOUSEBUTTONDOWN:
MouseButtonDown(event.button);
break;
case SDL_MOUSEBUTTONUP:
MouseButtonUp(event.button);
break;
case SDL_KEYDOWN:
KeyDown(event.key);
break;
case SDL_KEYUP:
KeyUp(event.key);
break;
#ifdef USE_EVENT_JOYSTICK
//TODO: joystick/gamepad support
#endif
#ifdef USE_EVENT_UNKNOWN
default:
UnknownEvent(event);
break;
#endif
}//switch
}//while
}
+40 -27
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,43 +19,56 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#ifndef BASESCENE_HPP_
#define BASESCENE_HPP_
#include "scene_signal.hpp"
#include "scene_list.hpp"
#include "SDL2/SDL.h"
#include "SDL/SDL.h"
class BaseScene {
public:
//Public access members
BaseScene();
virtual ~BaseScene();
virtual void RenderFrame(SDL_Renderer*);
static void SetRenderer(SDL_Renderer*);
SceneSignal GetSceneSignal();
//Program control
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
static SDL_Surface* GetScreen();
//frame phases
virtual void FrameStart();
virtual void Update();
virtual void FrameEnd();
SceneList SetNextScene(SceneList sceneIndex);
SceneList GetNextScene() const;
//input events
virtual void QuitEvent();
virtual void MouseMotion(SDL_MouseMotionEvent const& event);
virtual void MouseButtonDown(SDL_MouseButtonEvent const& event);
virtual void MouseButtonUp(SDL_MouseButtonEvent const& event);
virtual void MouseWheel(SDL_MouseWheelEvent const& event);
virtual void KeyDown(SDL_KeyboardEvent const& event);
virtual void KeyUp(SDL_KeyboardEvent const& event);
//TODO: joystick and controller events
//Frame loop
virtual void RunFrame(double delta);
virtual void RenderFrame();
protected:
//control
static SDL_Renderer* GetRenderer();
void SetSceneSignal(SceneSignal);
virtual void FrameStart() {}
virtual void HandleEvents();
virtual void Update(double delta) {}
virtual void FrameEnd() {}
virtual void Render(SDL_Surface* const screen) {}
//Event handlers
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {}
virtual void KeyDown(SDL_KeyboardEvent const&) {}
virtual void KeyUp(SDL_KeyboardEvent const&) {}
#ifdef USE_EVENT_JOYSTICK
//TODO: joystick/gamepad support
#endif
#ifdef USE_EVENT_UNKNOWN
virtual void UnknownEvent(SDL_Event const&) {}
#endif
private:
static SDL_Renderer* rendererHandle;
SceneSignal sceneSignal = SceneSignal::CONTINUE;
};
static SDL_Surface* screen;
SceneList nextScene = SceneList::CONTINUE;
};
#endif
-221
View File
@@ -1,221 +0,0 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "example_scene.hpp"
#include <iomanip>
#include <iostream>
#include <sstream>
ExampleScene::ExampleScene(lua_State* L) {
lua = L;
//TODO: non-hardcoded source
tileSheet.Load(GetRenderer(), "../rsc/terrain.png", 32, 32);
//set the pager's hook
regionPager.SetLuaState(lua);
//load the file as a chunk
luaL_loadfile(lua, "../rsc/startup.lua");
//push the pager as an arg
lua_pushlightuserdata(lua, static_cast<void*>(&regionPager));
//run the function
lua_pcall(lua, 1, LUA_MULTRET, 0);
//DEBUG: cam jump
camera.x = -3000;
camera.y = -1500;
camera.scale = 0.25;
//DEBUG: testing buttons
buttonBG.Load(GetRenderer(), "../rsc/button.png");
//Ubuntu: "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
font = TTF_OpenFont("C:\\Windows\\Fonts\\Arial.ttf", 12);
if (!font) {
std::ostringstream msg;
msg << "Failed to load a font: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
button.SetBackgroundTexture(GetRenderer(), buttonBG.GetTexture());
button.SetText(GetRenderer(), font, "BUTTON TEXT", {0, 0, 0, 255});
button.SetX(400);
button.SetY(200);
// {140, 62, 54, 255}
//DEBUG: testing textLine
textBox.PushLine(GetRenderer(), font, "first line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "second line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "third line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "FOURTH LINE!!", {255, 0, 0, 0});
//
blankImage.Create(GetRenderer(), 256, 256);
//
std::cout << "Scene setup finished" << std::endl;
}
ExampleScene::~ExampleScene() {
TTF_CloseFont(font);
}
//-------------------------
//frame phases
//-------------------------
void ExampleScene::FrameStart() {
//
}
void ExampleScene::Update() {
//
}
void ExampleScene::FrameEnd() {
//
}
void ExampleScene::RenderFrame(SDL_Renderer* renderer) {
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
//NOTE: Graphical scaling is done internally
tileSheet.DrawRegionTo(renderer, &(*it), camera.x, camera.y, camera.scale, camera.scale);
}
//DEBUG: testing UI
button.DrawTo(renderer);
textBox.DrawTo(renderer, 0, 550, -12);
blankImage.DrawTo(renderer, 0, 0);
}
//-------------------------
//input events
//-------------------------
void ExampleScene::MouseMotion(SDL_MouseMotionEvent const& event) {
Button::State state = button.MouseMotion(event);
if (state == Button::State::PRESSED) {
//motion while pressed
return;
}
//right mouse button moves the camera
if (event.state & SDL_BUTTON_RMASK) {
camera.x -= event.xrel / camera.scale;
camera.y -= event.yrel / camera.scale;
}
}
void ExampleScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
Button::State state = button.MouseButtonDown(event);
//catch button input
if (state == Button::State::PRESSED) {
//TODO: do stuff
std::cout << "pressed" << std::endl;
return;
}
switch(event.button) {
case SDL_BUTTON_LEFT: {
//DOCS: broke this down into several lines for clarity
//these are the "real" click positions, relative to the map
//(scaled input is transformed into unscaled tile selection)
int fieldX = event.x / camera.scale + camera.x;
int fieldY = event.y / camera.scale + camera.y;
//these are the x & y indexes of the selected tile
//NOTE: the terniary operator is used to circumvent an error with integer devision
int tileX = (fieldX >= 0 ? fieldX : fieldX - tileSheet.GetTileW()) / tileSheet.GetTileW();
int tileY = (fieldY >= 0 ? fieldY : fieldY - tileSheet.GetTileH()) / tileSheet.GetTileH();
//finally, call the method
regionPager.SetTile(tileX, tileY, layer, selection);
}
break;
}
}
void ExampleScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
Button::State state = button.MouseButtonUp(event);
//catch button input
if (state == Button::State::RELEASED) {
std::cout << "released" << std::endl;
return;
}
}
void ExampleScene::MouseWheel(SDL_MouseWheelEvent const& event) {
constexpr double scaleMod = 1.2;
constexpr double scaleUpperBound = 3.0;
constexpr double scaleLowerBound = 0.5;
//zoom out
if (event.y < 0) { //downscroll
if (camera.scale / scaleMod <= scaleLowerBound) {
camera.scale = scaleLowerBound;
}
else {
camera.scale /= scaleMod;
}
}
//zoom in
if (event.y > 0) { //upscroll
if (camera.scale * scaleMod >= scaleUpperBound) {
camera.scale = scaleUpperBound;
}
else {
camera.scale *= scaleMod;
}
}
}
void ExampleScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
case SDLK_r:
SetSceneSignal(SceneSignal::EXAMPLE_SCENE);
break;
case SDLK_SPACE:
camera.scale = 1.0;
break;
case SDLK_RETURN:
textBox.PushLine(GetRenderer(), font, "You pressed enter.", {128, 128, 128, 255});
break;
}
}
void ExampleScene::KeyUp(SDL_KeyboardEvent const& event) {
//
}
-74
View File
@@ -1,74 +0,0 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include "base_scene.hpp"
#include "button.hpp"
#include "region_pager_lua.hpp"
#include "text_box.hpp"
#include "tile_sheet.hpp"
#include "lua.hpp"
#include "SDL2/SDL_ttf.h"
class ExampleScene : public BaseScene {
public:
ExampleScene(lua_State* L);
~ExampleScene();
void RenderFrame(SDL_Renderer* renderer) override;
private:
//frame phases
void FrameStart() override;
void Update() override;
void FrameEnd() override;
//input events
void MouseMotion(SDL_MouseMotionEvent const& event) override;
void MouseButtonDown(SDL_MouseButtonEvent const& event) override;
void MouseButtonUp(SDL_MouseButtonEvent const& event) override;
void MouseWheel(SDL_MouseWheelEvent const& event) override;
void KeyDown(SDL_KeyboardEvent const& event) override;
void KeyUp(SDL_KeyboardEvent const& event) override;
//members
lua_State* lua = nullptr;
RegionPagerLua regionPager;
TileSheet tileSheet;
struct {
int x = 0;
int y = 0;
double scale = 1.0;
} camera;
int selection = 1;
int layer = 0;
TTF_Font* font = nullptr;
Image buttonBG;
Button button;
TextBox textBox;
//blank image
Image blankImage;
};
-66
View File
@@ -1,66 +0,0 @@
/*
** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
*/
#define linit_c
#define LUA_LIB
#include "lua.hpp"
#include "region_api.hpp"
#include "region_pager_api.hpp"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
//custom stuff
{TORTUGA_REGION_API, openRegionAPI},
{TORTUGA_REGION_PAGER_API, openRegionPagerAPI},
{NULL, NULL}
};
/*
** these libs are preloaded and must be required before used
*/
static const luaL_Reg preloadedlibs[] = {
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* call open functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
/* add open functions from 'preloadedlibs' into 'package.preload' table */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
for (lib = preloadedlibs; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); /* remove _PRELOAD table */
}
+9 -9
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -21,23 +21,23 @@
*/
#include "application.hpp"
#include "SDL2/SDL.h"
#include <iostream>
#include <stdexcept>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
std::cout << "Beginning " << argv[0] << std::endl;
cout << "Beginning " << argv[0] << endl;
try {
Application app;
app.Init(argc, argv);
app.Proc();
app.Quit();
}
catch(std::exception& e) {
std::cerr << "Fatal Error: " << e.what() << std::endl;
catch(exception& e) {
cerr << "Fatal exception thrown: " << e.what() << endl;
return 1;
}
std::cout << "Clean exit from " << argv[0] << std::endl;
cout << "Clean exit" << endl;
return 0;
}
}
+4 -27
View File
@@ -1,24 +1,7 @@
#include directories
INCLUDES+=. ../common/graphics ../common/map
#libraries
#the order of the $(LIBS) is important, at least for MinGW
LIBS+=../common/libcommon.a
ifeq ($(OS),Windows_NT)
LIBS+=-lmingw32
endif
LIBS+=-lSDL2main -lSDL2 -lSDL2_image -lSDL2_ttf -llua
ifeq ($(shell uname), Linux)
#I don't know what this does, but Ubuntu needs it (dynamic linking for lua)
LIBS+=-ldl
endif
#flags
#config
INCLUDES+=. ../utils ../mapgen
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
ifeq ($(shell uname), Linux)
#read data about the current install
CXXFLAGS+=$(shell sdl-config --cflags --static-libs)
endif
#source
CXXSRC=$(wildcard *.cpp)
@@ -29,7 +12,7 @@ OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,map)
OUT=$(addprefix $(OUTDIR)/,shell)
#targets
all: $(OBJ) $(OUT)
@@ -49,12 +32,6 @@ $(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.o *.a *.exe
else ifeq ($(shell uname), Linux)
find . -type f -name '*.o' -exec rm -f -r -v {} \;
find . -type f -name '*.a' -exec rm -f -r -v {} \;
rm -f -v $(OUT)
endif
rebuild: clean all
+13 -10
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2015
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,14 +19,17 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#ifndef SCENELIST_HPP_
#define SCENELIST_HPP_
enum SceneSignal {
//reserved members for internal use
QUIT = -1,
CONTINUE = 0,
FIRST = 1,
enum SceneList {
//these are reserved
QUIT,
CONTINUE,
FIRST,
//custom scenes
EXAMPLE_SCENE
};
//custom indexes
SHELL,
};
#endif
+150
View File
@@ -0,0 +1,150 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "shell_scene.hpp"
#include <iostream>
//-------------------------
//Public access members
//-------------------------
static double max = 0;
static double min = 0;
void setPixel(SDL_Surface* const dest, int x, int y, int colour) {
*(static_cast<int*>(dest->pixels) + dest->w * y + x) = colour;
}
int convertToColour(SDL_PixelFormat* format, double x) {
//track the max value
max = x > max ? x : max;
min = x < min ? x : min;
if (x > 1) {
return SDL_MapRGB(format, 255, 0, 0);
}
if (x < 0) {
return SDL_MapRGB(format, 0, 255, 0);
}
if (x == 0) {
return SDL_MapRGB(format, 0, 0, 255);
}
return SDL_MapRGB(format, 255*x, 255*x, 255*x);
}
int convertToTerrain(SDL_PixelFormat* format, double x) {
//water
if (x < 0.4) {
return SDL_MapRGB(format, 0, 0, 255);
}
//sand
if (x < 0.5) {
return SDL_MapRGB(format, 255, 255, 0);
}
//grass
if (x < 0.6) {
return SDL_MapRGB(format, 0, 255, 0);
}
//forest
if (x < 0.8) {
return SDL_MapRGB(format, 0, 128, 0);
}
//snow
if (x < 0.8) {
return SDL_MapRGB(format, 255, 255, 255);
}
//dark snow
return SDL_MapRGB(format, 128, 128, 128);
}
ShellScene::ShellScene() {
//test the generator
int width = 256;
int height = 256;
image.CreateSurface(GetScreen()->w, GetScreen()->h);
double value;
int colour;
std::cout << "Beggining generation" << std::endl;
for (int i = 0; i < image.GetSurface()->w; i++) {
for (int j = 0; j < image.GetSurface()->h; j++) {
value = generator.GetPixel(i, j, width, height, 8);
colour = convertToColour(image.GetSurface()->format, value);
setPixel(image.GetSurface(), i, j, colour);
}
}
std::cout << "Finished generation" << std::endl;
std::cout << "Max: " << max << std::endl;
std::cout << "Min: " << min << std::endl;
}
ShellScene::~ShellScene() {
//
}
//-------------------------
//Frame loop
//-------------------------
void ShellScene::FrameStart() {
//
}
void ShellScene::Update(double delta) {
//
}
void ShellScene::FrameEnd() {
//
}
void ShellScene::Render(SDL_Surface* const screen) {
image.DrawTo(screen, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void ShellScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void ShellScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void ShellScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void ShellScene::KeyDown(SDL_KeyboardEvent const& key) {
//
}
void ShellScene::KeyUp(SDL_KeyboardEvent const& key) {
//
}
+56
View File
@@ -0,0 +1,56 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SHELLSCENE_HPP_
#define SHELLSCENE_HPP_
#include "base_scene.hpp"
#include "map_generator.hpp"
#include "image.hpp"
class ShellScene : public BaseScene {
public:
//Public access members
ShellScene();
~ShellScene();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
//Event handlers
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//members
MapGenerator generator;
Image image;
};
#endif
+145
View File
@@ -0,0 +1,145 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "image.hpp"
#include <stdexcept>
#include <sstream>
Image& Image::operator=(Image const& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Copy the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = false;
}
Image& Image::operator=(Image&& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
FreeSurface();
//Steal the other Image's stuff
surface = rhs.surface;
clip = rhs.clip;
local = rhs.local;
rhs.surface = nullptr;
rhs.clip = {0, 0, 0, 0};
rhs.local = false;
}
SDL_Surface* Image::LoadSurface(std::string fname) {
FreeSurface();
SDL_Surface* p = SDL_LoadBMP(fname.c_str());
if (!p) {
std::ostringstream os;
os << "Failed to load file: " << fname;
throw(std::runtime_error(os.str()));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::CreateSurface(Uint16 w, Uint16 h) {
FreeSurface();
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface* p = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask);
if (!p) {
throw(std::runtime_error("Failed to create Image surface"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = true;
SetTransparentColor(255, 0, 255); //default
return surface;
}
SDL_Surface* Image::SetSurface(SDL_Surface* p) {
FreeSurface();
if (!p) {
throw(std::invalid_argument("No surface pointer provided"));
}
surface = p;
clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h};
local = false;
return surface;
}
void Image::FreeSurface() {
if (local) {
SDL_FreeSurface(surface);
local = false;
}
surface = nullptr;
clip = {0, 0, 0, 0};
}
void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) {
if (!surface) {
throw(std::logic_error("No image surface to draw"));
}
SDL_Rect sclip = clip, dclip = {x,y};
SDL_BlitSurface(surface, &sclip, dest, &dclip);
}
void Image::SetTransparentColor(Uint8 r, Uint8 g, Uint8 b) {
if (!surface) {
throw(std::logic_error("Failed to set the transparent color"));
}
if (!local) {
throw(std::logic_error("Cannot set the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, r, g, b));
}
void Image::ClearTransparentColor() {
if (!surface) {
throw(std::logic_error("Failed to clear the transparent color"));
}
if (!local) {
throw(std::logic_error("Cannot clear the transparent color of a non-local surface"));
}
SDL_SetColorKey(surface, 0, 0);
}
+73
View File
@@ -0,0 +1,73 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef IMAGE_HPP_
#define IMAGE_HPP_
#include "SDL/SDL.h"
#include <string>
class Image {
public:
Image() = default;
Image(Image const& rhs) { *this = rhs; }
Image(Image&& rhs) { *this = std::move(rhs); }
Image(std::string fname) { LoadSurface(fname); }
Image(Uint16 w, Uint16 h) { CreateSurface(w, h); }
Image(SDL_Surface* p) { SetSurface(p); }
~Image() { FreeSurface(); }
Image& operator=(Image const&);
Image& operator=(Image&&);
SDL_Surface* LoadSurface(std::string fname);
SDL_Surface* CreateSurface(Uint16 w, Uint16 h);
SDL_Surface* SetSurface(SDL_Surface*);
SDL_Surface* GetSurface() const { return surface; }
void FreeSurface();
void DrawTo(SDL_Surface* const, Sint16 x, Sint16 y);
//Clip handlers
SDL_Rect SetClip(SDL_Rect r) { return clip = r; }
SDL_Rect GetClip() const { return clip; }
Sint16 SetClipX(Sint16 x) { return clip.x = x; }
Sint16 SetClipY(Sint16 y) { return clip.y = y; }
Uint16 SetClipW(Uint16 w) { return clip.w = w; }
Uint16 SetClipH(Uint16 h) { return clip.h = h; }
Sint16 GetClipX() const { return clip.x; }
Sint16 GetClipY() const { return clip.y; }
Uint16 GetClipW() const { return clip.w; }
Uint16 GetClipH() const { return clip.h; }
bool GetLocal() const { return local; }
void SetTransparentColor(Uint8 r, Uint8 g, Uint8 b);
void ClearTransparentColor();
protected:
SDL_Surface* surface = nullptr;
SDL_Rect clip = {0, 0, 0, 0};
bool local = false;
};
#endif
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=.
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+45
View File
@@ -0,0 +1,45 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "maths.hpp"
double curve(double x) {
return 3.0 * pow(x, 2.0) - 2.0 * pow(x, 3.0);
}
double snap(double x, double base) {
//snap to a grid (floating point version)
return floor(x / base) * base;
}
int snap(int x, int base) {
//snap to a grid (integer devision version)
if (x < 0) {
++x;
return x / base * base - base;
}
return x / base * base;
}
double scalarProduct(Vector2 lhs, Vector2 rhs) {
//the dot product
return lhs.x * rhs.x + lhs.y * rhs.y;
}
+37
View File
@@ -0,0 +1,37 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef MATHS_HPP_
#define MATHS_HPP_
#include "vector2.hpp"
//param: 0 to 1 inclusive
double curve(double);
//snap x to a grid of base
double snap(double x, double base);
int snap(int x, int base);
//vector dot product
double scalarProduct(Vector2, Vector2);
#endif
+42
View File
@@ -0,0 +1,42 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SIMPLERNG_HPP_
#define SIMPLERNG_HPP_
//a simple, stateless, random number generator
class SimpleRNG {
public:
SimpleRNG() { SetSeed(8891.0); }
SimpleRNG(double x) { SetSeed(x); }
double SetSeed(double s) { return seed = s; }
double GetSeed() { return seed; }
double operator()(double x) {
return (x + seed) * 11235.0 + 81321.0;
};
private:
double seed;
};
#endif
+108
View File
@@ -0,0 +1,108 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef VECTOR2_HPP_
#define VECTOR2_HPP_
#include <type_traits>
#include <stdexcept>
#include <cmath>
class Vector2 {
public:
double x, y;
Vector2() = default;
Vector2(double i, double j): x(i), y(j) {};
~Vector2() = default;
Vector2& operator=(Vector2 const&) = default;
double Length() const {
return sqrt(x*x+y*y);
}
double SquaredLength() const {
return x*x+y*y;
}
void Normalize() {
double l = Length();
x /= l;
y /= l;
}
//Arithmetic operators
Vector2 operator+(Vector2 v) const {
Vector2 ret;
ret.x = x + v.x;
ret.y = y + v.y;
return ret;
}
Vector2 operator-(Vector2 v) const {
Vector2 ret;
ret.x = x - v.x;
ret.y = y - v.y;
return ret;
}
Vector2 operator*(Vector2 v) const {
Vector2 ret;
ret.x = x * v.x;
ret.y = y * v.y;
return ret;
}
Vector2 operator*(double d) const {
Vector2 ret;
ret.x = x * d;
ret.y = y * d;
return ret;
}
Vector2 operator/(Vector2 v) {
if (!v.x || !v.y)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / v.x;
ret.y = y / v.y;
return ret;
}
Vector2 operator/(double d) {
if (!d)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / d;
ret.y = y / d;
return ret;
}
bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
//member templates (curry the above operators)
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
template<typename T> Vector2 operator/=(T t) { return *this = *this / t; }
template<typename T> bool operator==(T t) { return (x == t && y == t); }
template<typename T> bool operator!=(T t) { return (x != t || y != t); }
};
//This is explicitly a POD
static_assert(std::is_pod<Vector2>::value, "Vector2 is not a POD");
#endif