7 Commits
Main ... issues

Author SHA1 Message Date
3ac5616c83 Issue 6: save 2026-01-04 13:26:18 +01:00
009cb4bb51 Issue 5: save 2025-05-11 20:03:34 +02:00
d5c372e82d Issue 4: save 2025-05-11 20:03:14 +02:00
e20662f45c Issue 3: save 2025-05-11 20:02:49 +02:00
9e61c50c06 Issue 2: save 2025-05-11 20:02:02 +02:00
6f5ea914af Issue 1: save 2025-05-11 20:01:55 +02:00
9922cbe90d Initialize issues branch 2025-05-11 20:01:38 +02:00
52 changed files with 37 additions and 15365 deletions

View File

@@ -1,63 +0,0 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakTemplateDeclarations: No
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BinPackArguments: false
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentWrappedFunctionNames: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: c++11
IndentWidth: 4
TabWidth: 4
UseTab: AlignWithSpaces
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
AlignConsecutiveAssignments: Consecutive
...

23
.gitignore vendored
View File

@@ -1,23 +0,0 @@
# Building stuff
build-*
*.dll
*.exe
*.so
*.so.*
DIST/*
shot-????.bmp
shot-????.png
.vscode
.DS_Store
*/DIST/*
/CMakeFiles/
Makefile
cmake_install.cmake
CMakeCache.txt
cmake-build-*
build
build-*
.idea
# Results
libGameLib.a

View File

@@ -1,58 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(GameLib)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
if (EMSCRIPTEN)
message(" * Ignore SDL2 package with Emscripten")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2 -Wno-implicit-function-declaration -DEMSCRIPTEN")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL=2 -s TOTAL_MEMORY=134217728 -lidbfs.js")
else()
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
endif()
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL REQUIRED)
# -------------------------------------------------------------
# ----- GameLib
set(GAMELIB_HEADERS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(GAMELIB_HEADERS
src/TimeUtils.h
src/Util.h
src/QuadArray2D.h
src/Draw.h
src/Input.h
src/Audio.h
src/Anim.h
src/Entity.h
src/Bucket.h
src/GameLib.h)
set(GAMELIB_SOURCE
src/TimeUtils.c
src/Util.c
src/QuadArray2D.c
src/Draw.c
src/Input.c
src/Audio.c
src/Anim.c
src/Entity.c
src/Bucket.c
src/GameLib.c)
add_library(GameLib STATIC
${GAMELIB_HEADERS} ${GAMELIB_SOURCE})
target_include_directories(GameLib PRIVATE ${GAMELIB_HEADERS_PATH})
set(GAMELIB_LIBRARIES ${SDL2_LIBRARIES} ${OPENGL_LIBRARY} m GameLib)
get_directory_property(hasParent PARENT_DIRECTORY)
if(hasParent)
set(GAMELIB_HEADERS_PATH ${GAMELIB_HEADERS_PATH} PARENT_SCOPE)
set(GAMELIB_LIBRARIES ${GAMELIB_LIBRARIES} PARENT_SCOPE)
endif()

View File

@@ -1,63 +0,0 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakTemplateDeclarations: No
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BinPackArguments: false
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentWrappedFunctionNames: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: c++11
IndentWidth: 4
TabWidth: 4
UseTab: AlignWithSpaces
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
AlignConsecutiveAssignments: Consecutive
...

View File

@@ -1,20 +0,0 @@
# Building stuff
build-*
*.dll
*.exe
*.so
*.so.*
DIST/*
shot-????.bmp
shot-????.png
.vscode
.DS_Store
*/DIST/*
/CMakeFiles/
Makefile
cmake_install.cmake
CMakeCache.txt
cmake-build-*/
# Results
game

View File

@@ -1,40 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(Example.GameLib)
IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/GameLib)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/GameLib ${CMAKE_CURRENT_BINARY_DIR}/GameLib)
elseif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../GameLib)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../GameLib ${CMAKE_CURRENT_BINARY_DIR}/GameLib)
elseif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../GameLib)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../GameLib ${CMAKE_CURRENT_BINARY_DIR}/GameLib)
endif ()
if (EMSCRIPTEN)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2 -O2 -Wno-implicit-function-declaration -DEMSCRIPTEN")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL=2 -s TOTAL_MEMORY=134217728 -lidbfs.js --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/data@/data")
SET(CMAKE_EXECUTABLE_SUFFIX ".html")
endif ()
# -------------------------------------------------------------
# ----- Example.GameLib
set(GAME_HEADERS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(GAME_HEADERS
src/GameEnts.h
src/GameMap.h)
set(GAME_SOURCE
src/GameEnts.c
src/GameMap.c
src/main.c)
add_executable(game WIN32
${GAME_HEADERS} ${GAME_SOURCE})
target_include_directories(game PRIVATE
${GAMELIB_HEADERS_PATH}
${GAME_HEADERS_PATH})
target_link_libraries(game ${GAMELIB_LIBRARIES})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,71 +0,0 @@
######################
######################
######################
######################
######################
######################
######################
######################
######################
######################
################## ##
###############
#############
#############
##############
########## ###
######### ###
######## ##
######## ##
######## ## |||||
########
#########
##########
###########
############
#############
######## ## #
######### ###
######## ## #
#############
#############
########
##########
########
###########
########
########
############
########
#############
########
########
######## #
######## #
########
########
########
######## P
########
########
########
########
########
########
########
########
#########
########
########
#########
######################
######################
######################
######################
######################
######################
######################
######################
######################
######################

Binary file not shown.

Before

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,5 +0,0 @@
#! /bin/sh
(sleep 1 && xdg-open http://localhost:8081) &
php -S 0.0.0.0:8081 -t DIST/web

View File

@@ -1,19 +0,0 @@
#!/bin/sh
if test -f /c/emsdk/emsdk_env.sh; then
. /c/emsdk/emsdk_env.sh
fi
if test -d cmake-build-emscripten; then
rm -rf cmake-build-emscripten
fi
mkdir cmake-build-emscripten
cd cmake-build-emscripten || exit
emcmake cmake ..
make
cd ..
mkdir -p DIST/web
cp -Rv web/* DIST/web/
cp -Rv cmake-build-emscripten/game.* DIST/web/

View File

@@ -1,179 +0,0 @@
// Copyright (C) 2012-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "GameLib.h"
#include "GameEnts.h"
DrawImg img_player;
DrawImg img_platform;
DrawImg img_block;
Entity ent_Player;
Entity ent_Platform;
Entity ent_Block;
int EntityApplyGravity(Entity e) {
float grav = 10.0f;
float vTerminal = 50.0f;
vec2 vGrav;
// Only apply gravity to some entity types
if (!(e->type == Ent_Player || 0)) {
return (1);
}
// Apply gravity
vec2_set(vGrav, 0.0f, grav);
Entity_AddVelLimit(e, vGrav, vTerminal);
return (1);
}
void Player_Proc(Entity e, int ft) {
float acel = 8.0f;
float maxVel = 30.0f;
float jumpVel = 50.0f;
float airMovementFactor = 0.1f;
// Process elasticity
float entityScale[2];
Entity_GetScale(e, entityScale);
entityScale[0] += (1.0f - entityScale[0]) / 2.0f;
entityScale[1] += (1.0f - entityScale[1]) / 2.0f;
Entity_SetScale(e, entityScale);
if (e->A > 0) {
if (Input_GetKey(InputKey_Jump) == InputKey_Pressed || Input_GetKey(InputKey_Up) == InputKey_Pressed) {
// Apply jump
if (e->vel[1] > (-jumpVel)) {
e->vel[1] = -jumpVel;
}
Entity_CalcBBox(e);
Entity_SetScale(e, (float[2]){0.6f, 1.4f});
// FIXME: play sound
}
if (Input_GetKey(InputKey_Left)) {
vec2 left;
// Apply left movement
vec2_set(left, -acel, 0.0f);
Entity_AddVelLimit(e, left, maxVel);
}
if (Input_GetKey(InputKey_Right)) {
vec2 right;
// Apply right movement
vec2_set(right, acel, 0.0f);
Entity_AddVelLimit(e, right, maxVel);
}
} else {
if (Input_GetKey(InputKey_Left)) {
vec2 left;
// Apply left movement
vec2_set(left, -(acel * airMovementFactor), 0.0f);
Entity_AddVelLimit(e, left, maxVel * airMovementFactor);
}
if (Input_GetKey(InputKey_Right)) {
vec2 right;
// Apply right movement
vec2_set(right, acel * airMovementFactor, 0.0f);
Entity_AddVelLimit(e, right, maxVel * airMovementFactor);
}
}
if (Input_GetKey(InputKey_Action1) == InputKey_Pressed || Input_GetKey(InputKey_Action2) == InputKey_Pressed) {
Entity_SetScale(e, (float[2]){1.0f, 1.0f});
}
e->A = 0;
}
void Player_PostProc(Entity e, int ft) {
// Scroll View
GameLib_MoveToPos(e->pos, 0.6f);
// GameLib_MoveToPos(e->pos, 1.0f);
}
int Player_Collision(Entity ent, Entity ent2, float t, vec2 n) {
if (n[1] < 0 && fabs(n[1]) > fabs(n[0])) {
ent->A = 1;
}
if (fabs(n[0]) > fabs(n[1])) {
float intensity = (fabs(ent->vel[0]) - 10.0f) / 40.0f;
if (intensity > 0) {
Entity_SetScale(ent, (float[2]){1.0f - (0.3f * intensity), 1.0f + (0.3f * intensity)});
}
} else {
float intensity = (fabs(ent->vel[1]) - 10.0f) / 40.0f;
if (intensity > 0) {
Entity_SetScale(ent, (float[2]){1.0f + (0.3f * intensity), 1.0f - (0.3f * intensity)});
}
}
return -1;
}
void GameEnts_Init() {
/////////////////////////////
// Load and initialize media.
//
img_player = Draw_LoadImage("data/player.png");
img_platform = Draw_LoadImage("data/platform.png");
img_block = Draw_LoadImage("data/block.png");
/////////////////////////
// Initialize entity types.
//
ent_Player = Entity_New();
ent_Player->type = Ent_Player;
// ent_Player->flags=EntityFlag_Light;
// Entity_SetLight(ent_Player,.2,.2,.2,200);
ent_Player->flags = EntityFlag_Collision | EntityFlag_Overlap;
ent_Player->zorder = 0;
AnimPlay_SetImg(&ent_Player->anim, img_player);
ent_Player->proc = Player_Proc;
ent_Player->postproc = Player_PostProc;
ent_Player->collision = Player_Collision;
ent_Player->mass = 1.0f;
ent_Player->radius = 12;
ent_Player->width = 24;
ent_Player->height = 24;
ent_Player->fric_static = 0.0f;
ent_Player->fric_dynamic = 0.2f;
ent_Platform = Entity_New();
ent_Platform->type = Ent_Platform;
ent_Platform->flags = EntityFlag_PlatformCollision;
ent_Platform->zorder = -1;
AnimPlay_SetImg(&ent_Platform->anim, img_platform);
ent_Platform->mass = 0.0f;
ent_Platform->radius = 12;
ent_Platform->width = 64;
ent_Platform->height = 16;
ent_Platform->fric_static = 0.0f;
ent_Platform->fric_dynamic = 0.2f;
ent_Block = Entity_New();
ent_Block->type = Ent_Block;
ent_Block->flags = EntityFlag_BlockCollision;
ent_Block->zorder = -1;
AnimPlay_SetImg(&ent_Block->anim, img_block);
ent_Block->mass = 0.0f;
ent_Block->radius = 32;
ent_Block->width = 64;
ent_Block->height = 64;
ent_Block->fric_static = 0.0f;
ent_Block->fric_dynamic = 0.2f;
}

View File

@@ -1,18 +0,0 @@
// Copyright (C) 2012-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef GameEnts_H
#define GameEnts_H
#define Ent_Player 1
#define Ent_Platform 2
#define Ent_Block 3
extern Entity ent_Player;
extern Entity ent_Platform;
extern Entity ent_Block;
int EntityApplyGravity(Entity e);
void GameEnts_Init();
#endif

View File

@@ -1,114 +0,0 @@
// Copyright (C) 2012-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GameLib.h"
#include "GameEnts.h"
#include "GameMap.h"
int ReadLine(FILE *f, char *line, int max) {
int c;
int i = 0;
while (i < (max - 1)) {
c = fgetc(f);
if (c == EOF) {
line[i] = 0;
return (-1);
}
if (c == '\r') {
continue;
}
if (c == '\n') {
line[i] = 0;
return (i);
}
line[i] = c;
i++;
}
line[i] = 0;
return (i);
}
Entity GameMapAux_CreateEnt(Entity ent, int i, int j, int res) {
Entity e;
vec2 pos;
e = Entity_Copy(ent);
vec2_set(pos, (res / 2) + i * res, (res / 2) + j * res);
vec2_plus(e->pos, e->pos, pos);
GameLib_AddEntity(e);
return (e);
}
#define MaxLineLen 1024
int GameMap_LoadLevel(char *filename, int res) {
FILE *file;
char line[MaxLineLen];
int len, i, j;
int width, height;
char *map;
// Open the file
file = fopen(filename, "rb");
if (!file) {
return (0);
}
// Read the file to determine sizes
width = 0;
height = 0;
do {
len = ReadLine(file, line, MaxLineLen);
if (len > -1) {
if (len > height) {
height = len;
}
width++;
}
} while (len > -1);
fseek(file, 0, SEEK_SET);
// Build the map
map = malloc(sizeof(char) * width * height);
memset(map, 0, width * height);
#define MAP(x, y) map[(x) + ((y) * width)]
j = 0;
do {
len = ReadLine(file, line, MaxLineLen);
for (i = 0; i < len; i++) {
MAP(j, (height - 1) - i) = line[i];
}
j++;
} while (len > -1);
// Close the file
fclose(file);
// Parse the map
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
if (MAP(i, j) == 'P') {
// Player
GameMapAux_CreateEnt(ent_Player, i, j, res);
}
if (MAP(i, j) == '#') {
// Block
GameMapAux_CreateEnt(ent_Block, i, j, res);
}
if (MAP(i, j) == '|') {
// Platform
GameMapAux_CreateEnt(ent_Platform, i, j, res);
}
}
}
// Cleanup
free(map);
#undef MAP
return (1);
}

View File

@@ -1,7 +0,0 @@
// Copyright (C) 2012-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef GameMap_H
#define GameMap_H
int GameMap_LoadLevel(char *filename, int res);
#endif

View File

@@ -1,58 +0,0 @@
// Copyright (C) 2012-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "GameLib.h"
#include "GameEnts.h"
#include "GameMap.h"
DrawFnt font;
DrawImg imgBackground;
void MainGame_Text(int x, int y, char *text) {
Draw_SetColor(0.0f, 0.0f, 0.0f, 0.5f);
Draw_DrawText(font, text, x + 1, y + 1);
Draw_SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Draw_DrawText(font, text, x, y);
}
void ProcGame() {}
void PostProcGame() {
// Apply gravity to every entity
GameLib_ForEachEnt(EntityApplyGravity);
}
void PreDrawGame(float f) {}
void DrawGame(float f) { MainGame_Text(8, 8, "Hello world!"); }
int main(int argc, char *argv[]) {
GameLib_Init(640, 480, "Game", 20, 60);
/////////////////////////////
// Load and initialize media.
//
font = Draw_DefaultFont((ColorRgba){255, 255, 255, 255});
imgBackground = Draw_LoadImage("data/background.png");
Draw_SetOffset(imgBackground, 0, 0);
GameEnts_Init();
/////////////////////////
// Initialize world.
//
GameLib_DelEnts();
GameMap_LoadLevel("data/level_01.txt", 64);
/////////////////////////
// Run the world.
//
GameLib_CleanParallaxBackgrounds();
GameLib_AddParallaxBackground(imgBackground, (int[2]){512, 512}, (int[2]){0, 0}, (float[2]){0.5f, 0.0f});
GameLib_Loop(ProcGame, PostProcGame, PreDrawGame, DrawGame);
return (0);
}

View File

@@ -1,157 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Game</title>
</head>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: Verdana, Arial, Helvetica, sans-serif;
background-color: #000000;
color: #777777;
font-size: 10pt;
}
h1 {
text-align: left;
margin-top: 0;
margin-bottom: 1em;
font-size: 16pt;
font-weight: bold;
}
.header {
margin: 0 auto;
width: 600px;
padding-top: 10px;
text-align: center;
}
.progress-container {
border: 1px solid #808080;
border-radius: 5px;
padding: 5px;
box-shadow: 0 0 5px #808080;
width: 600px;
display: block;
margin: 0 auto;
}
.progress-container progress {
width: 100%;
}
.game-screen-container {
display: block;
width: 100%;
padding-top: 10px;
}
.game-screen-container canvas {
border: 1px solid #808080;
border-radius: 5px;
padding: 5px;
box-shadow: 0 0 5px #808080;
margin: 0 auto;
cursor: none;
}
</style>
<body>
<div class="game-screen-container">
<div id="progress-container" class="progress-container">
<h1>Loading...</h1>
<span>Code:</span><br/>
<progress id="progress-code" max="1" value="0"></progress><br/>
<br/>
<span>Data:</span><br/>
<progress id="progress-data" max="1" value="0"></progress><br/>
</div>
<div style="width:0;height:0;position:absolute;display:block;overflow:hidden;">
<input type="button" id="btnFocus" value="focus" />
</div>
<canvas class="game-screen" id="canvas" style="display:none;" oncontextmenu="event.preventDefault()"
onclick="document.getElementById('btnFocus').focus();"></canvas>
</div>
<script type='text/javascript'>
var Module = {
preRun: [function () {
FS.mkdir('/saves');
FS.mount(IDBFS, {}, '/saves');
addRunDependency("SaveDir");
FS.syncfs(true, function (err) {
removeRunDependency("SaveDir");
});
}],
postRun: [],
progressContainer: document.getElementById('progress-container'),
progressCode: document.getElementById('progress-code'),
progressData: document.getElementById('progress-data'),
printErr: function (text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
if (console && console.log) {
console.log(text);
}
},
canvas: (function () {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", function (e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function (text) {
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
if (m) {
this.progressData.value = parseInt(m[2]);
this.progressData.max = parseInt(m[4]);
}
},
totalDependencies: 0,
monitorRunDependencies: function (left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
if (!left) {
// All loaded
this.progressContainer.style.display = "none";
this.canvas.style.display = "block";
}
},
LaunchCode: function () {
var xhr = new XMLHttpRequest();
xhr.open('GET', "game.js", true);
xhr.responseType = 'text';
xhr.onprogress = function (event) {
this.progressCode.value = event.loaded;
this.progressCode.max = event.total;
}.bind(this);
xhr.onload = function (event) {
var packageData = xhr.response;
// Launch loaded code
try {
eval.call(null, packageData);
} catch (e) {
alert("Error " + parent + " " + e);
parent.postMessage("Error", "");
}
};
xhr.onerror = function (event) {
alert(event);
};
xhr.send(null);
}
};
Module.LaunchCode();
</script>
</body>
</html>

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2012-2015 Valeriano Alfonso Rodriguez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,202 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindSDL2
# -------
#
# Locate SDL2 library
#
# This module defines
#
# ::
#
# SDL2_LIBRARY, the name of the library to link against
# SDL2_FOUND, if false, do not try to link to SDL
# SDL2_INCLUDE_DIR, where to find SDL.h
# SDL2_VERSION_STRING, human-readable string containing the version of SDL
#
#
#
# This module responds to the flag:
#
# ::
#
# SDL2_BUILDING_LIBRARY
# If this is defined, then no SDL2_main will be linked in because
# only applications need main().
# Otherwise, it is assumed you are building an application and this
# module will attempt to locate and set the proper link flags
# as part of the returned SDL2_LIBRARY variable.
#
#
#
# Don't forget to include SDLmain.h and SDLmain.m your project for the
# OS X framework based version. (Other versions link to -lSDL2main which
# this module will try to find on your behalf.) Also for OS X, this
# module will automatically add the -framework Cocoa on your behalf.
#
#
#
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your
# configuration and no SDL2_LIBRARY, it means CMake did not find your SDL
# library (SDL.dll, libsdl.so, SDL.framework, etc). Set
# SDL2_LIBRARY_TEMP to point to your SDL library, and configure again.
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this
# value as appropriate. These values are used to generate the final
# SDL2_LIBRARY variable, but when these values are unset, SDL2_LIBRARY
# does not get created.
#
#
#
# $SDL2DIR is an environment variable that would correspond to the
# ./configure --prefix=$SDL2DIR used in building SDL. l.e.galup 9-20-02
#
# Modified by Eric Wing. Added code to assist with automated building
# by using environmental variables and providing a more
# controlled/consistent search behavior. Added new modifications to
# recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
# Also corrected the header search path to follow "proper" SDL
# guidelines. Added a search for SDL2main which is needed by some
# platforms. Added a search for threads which is needed by some
# platforms. Added needed compile switches for MinGW.
#
# On OSX, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of SDL2_LIBRARY to
# override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
#
# Note that the header path has changed from SDL/SDL.h to just SDL.h
# This needed to change because "proper" SDL convention is #include
# "SDL.h", not <SDL/SDL.h>. This is done for portability reasons
# because not all systems place things in SDL/ (see FreeBSD).
message("<FindSDL2.cmake>")
if(NOT SDL2_DIR)
set(SDL2_DIR "" CACHE PATH "SDL2 directory")
endif()
find_path(SDL2_INCLUDE_DIR SDL.h
HINTS
$ENV{SDL2DIR}
${SDL2_DIR}
PATH_SUFFIXES SDL2
# path suffixes to search inside ENV{SDL2DIR}
include/SDL2 include
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(VC_LIB_PATH_SUFFIX lib/x64)
else()
set(VC_LIB_PATH_SUFFIX lib/x86)
endif()
find_library(SDL2_LIBRARY_TEMP
NAMES SDL2
HINTS
ENV SDL2DIR
${SDL2_DIR}
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
# Hide this cache variable from the user, it's an internal implementation
# detail. The documented library variable for the user is SDL2_LIBRARY
# which is derived from SDL2_LIBRARY_TEMP further below.
set_property(CACHE SDL2_LIBRARY_TEMP PROPERTY TYPE INTERNAL)
if(NOT SDL2_BUILDING_LIBRARY)
if(NOT SDL2_INCLUDE_DIR MATCHES ".framework")
# Non-OS X framework versions expect you to also dynamically link to
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
# seem to provide SDL2main for compatibility even though they don't
# necessarily need it.
find_library(SDL2MAIN_LIBRARY
NAMES SDL2main
HINTS
ENV SDL2DIR
${SDL2_DIR}
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
PATHS
/sw
/opt/local
/opt/csw
/opt
)
endif()
endif()
# SDL may require threads on your system.
# The Apple build may not need an explicit flag because one of the
# frameworks may already provide it.
# But for non-OSX systems, I will use the CMake Threads package.
if(NOT APPLE)
find_package(Threads)
endif()
# MinGW needs an additional link flag, -mwindows
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
if(MINGW)
set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
endif()
if(SDL2_LIBRARY_TEMP)
# For SDL2main
if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY)
list(FIND SDL2_LIBRARY_TEMP "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX)
if(_SDL2_MAIN_INDEX EQUAL -1)
set(SDL2_LIBRARY_TEMP "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARY_TEMP})
endif()
unset(_SDL2_MAIN_INDEX)
endif()
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
# CMake doesn't display the -framework Cocoa string in the UI even
# though it actually is there if I modify a pre-used variable.
# I think it has something to do with the CACHE STRING.
# So I use a temporary variable until the end so I can set the
# "real" variable in one-shot.
if(APPLE)
set(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
endif()
# For threads, as mentioned Apple doesn't need this.
# In fact, there seems to be a problem if I used the Threads package
# and try using this line, so I'm just skipping it entirely for OS X.
if(NOT APPLE)
set(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
endif()
# For MinGW library
if(MINGW)
set(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
endif()
# Set the final string here so the GUI reflects the final state.
set(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
endif()
if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL2_version.h")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL2_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL2_MAJOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL2_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL2_MINOR_VERSION[ \t]+[0-9]+$")
file(STRINGS "${SDL2_INCLUDE_DIR}/SDL2_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL2_PATCHLEVEL[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define[ \t]+SDL2_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
string(REGEX REPLACE "^#define[ \t]+SDL2_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
unset(SDL2_VERSION_MAJOR_LINE)
unset(SDL2_VERSION_MINOR_LINE)
unset(SDL2_VERSION_PATCH_LINE)
unset(SDL2_VERSION_MAJOR)
unset(SDL2_VERSION_MINOR)
unset(SDL2_VERSION_PATCH)
endif()
set(SDL2_LIBRARIES ${SDL2_LIBRARY} ${SDL2MAIN_LIBRARY})
set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
VERSION_VAR SDL2_VERSION_STRING)

0
issues/.keep Normal file
View File

6
issues/1.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 1
title: Atlas de imagenes
state: open
tags: enhancement

6
issues/2.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 2
title: Colisiones con poligonos
state: open
tags: enhancement

6
issues/3.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 3
title: Better performance on big maps 200x200
state: closed
tags: enhancement
Using a QuadTree or other spatial structure

6
issues/4.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 4
title: ???
state: closed
tags: invalid

6
issues/5.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 5
title: Rotaciones
state: open
tags: enhancement

7
issues/6.yaml Normal file
View File

@@ -0,0 +1,7 @@
id: 6
title: Evaluate migration to Fenster or RGFW
state: open
tags: enhancement
https://github.com/zserge/fenster
https://github.com/ColleagueRiley/RGFW

View File

@@ -1,365 +0,0 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import <Cocoa/Cocoa.h>
#include <SDL.h>
@interface SDLMain : NSObject
@end
#include <sys/param.h> /* for MAXPATHLEN */
#include <unistd.h>
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
but the method still is there and works. To avoid warnings, we declare
it ourselves here. */
@interface NSApplication (SDL_Missing_Methods)
- (void)setAppleMenu:(NSMenu *)menu;
@end
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 0
/* Use this flag to determine whether we use CPS (docking) or not */
#define SDL_USE_CPS 1
#ifdef SDL_USE_CPS
/* Portions of CPS.h */
typedef struct CPSProcessSerNum {
UInt32 lo;
UInt32 hi;
} CPSProcessSerNum;
extern OSErr CPSGetCurrentProcess(CPSProcessSerNum *psn);
extern OSErr
CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr CPSSetFrontProcess(CPSProcessSerNum *psn);
#endif /* SDL_USE_CPS */
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
static NSString *getApplicationName(void) {
const NSDictionary *dict;
NSString *appName = 0;
/* Determine the application name */
dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey:@"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#endif
@interface NSApplication (SDLApplication)
@end
@implementation NSApplication (SDLApplication)
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender {
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
/* Set the working directory to the .app's parent directory */
- (void)setupWorkingDirectory:(BOOL)shouldChdir {
if (shouldChdir) {
char parentdir[MAXPATHLEN];
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
chdir(parentdir); /* chdir to the binary app's parent */
}
CFRelease(url);
CFRelease(url2);
}
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName {
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle:[[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject])) {
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle:[[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
}
#else
static void setApplicationMenu(void) {
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
}
/* Create a window menu */
static void setupWindowMenu(void) {
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[NSApplication sharedApplication];
#ifdef SDL_USE_CPS
{
CPSProcessSerNum PSN;
/* Tell the dock about us */
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN, 0x03, 0x3C, 0x2C, 0x1103))
if (!CPSSetFrontProcess(&PSN))
[NSApplication sharedApplication];
}
#endif /* SDL_USE_CPS */
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
setupWindowMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
* dragged/dropped on the app's icon. You need to have a
* CFBundleDocumentsType section in your Info.plist to get this message,
* apparently.
*
* Files are added to gArgv, so to the app, they'll look like command line
* arguments. Previously, apps launched from the finder had nothing but
* an argv[0].
*
* This message may be received multiple times to open several docs on launch.
*
* This message is ignored once the app's mainline has been called.
*/
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
if (!gFinderLaunch) /* MacOS is passing command line args. */
return FALSE;
if (gCalledAppMainline) /* app has started, ignore this document. */
return FALSE;
temparg = [filename UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *)SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
newargv = (char **)realloc(gArgv, sizeof(char *) * (gArgc + 2));
if (newargv == NULL) {
SDL_free(arg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
gArgv[gArgc] = NULL;
return TRUE;
}
/* Called when the internal event loop has just started running */
- (void)applicationDidFinishLaunching:(NSNotification *)note {
int status;
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main(gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString {
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = (unichar *)NSAllocateMemoryPages(bufferSize * sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer + aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer + aRange.location + aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
#undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main(int argc, char **argv) {
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
gArgv = (char **)SDL_malloc(sizeof(char *) * 2);
gArgv[0] = argv[0];
gArgv[1] = NULL;
gArgc = 1;
gFinderLaunch = YES;
} else {
int i;
gArgc = argc;
gArgv = (char **)SDL_malloc(sizeof(char *) * (argc + 1));
for (i = 0; i <= argc; i++)
gArgv[i] = argv[i];
gFinderLaunch = NO;
}
#if SDL_USE_NIB_FILE
NSApplicationMain(argc, argv);
#else
CustomApplicationMain(argc, argv);
#endif
return 0;
}

View File

@@ -1,244 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <stdio.h>
#include <stdlib.h>
#include "Anim.h"
#include "Draw.h"
////////////////////////////////////////////////
// Animation //
///////////////
//
typedef struct {
DrawImg img;
int32_t w;
float fps;
int32_t frames;
int32_t frameTime;
int32_t time;
} Animation;
/////////////////////////////
// Anim_LoadAnim
//
//
Anim Anim_LoadAnim(char *filename, int width, int frames, float fps) {
DrawImg img;
Animation *anim;
int w, h;
img = Draw_LoadImage(filename);
if (!img) {
return (NULL);
}
Draw_GetSize(img, &w, &h);
Draw_SetOffset(img, -(width / 2), -(h / 2));
// Create the animation container
anim = malloc(sizeof(Animation));
anim->img = img;
anim->w = width;
if (width <= 0) {
anim->w = w / frames;
}
anim->fps = fps;
anim->frames = frames;
anim->frameTime = (int)(1000.0f / fps);
anim->time = anim->frameTime * frames;
return ((Anim)anim);
}
/////////////////////////////
// Anim_GetTime
//
//
int Anim_GetTime(Anim a) {
Animation *anim = a;
return (anim->time);
}
/////////////////////////////
// Anim_GetSize
//
// Gets the animation size.
void Anim_GetSize(Anim a, int *w, int *h) {
Animation *anim = a;
int widthAux;
*w = anim->w;
Draw_GetSize(anim->img, &widthAux, h);
}
/////////////////////////////
// Anim_SetOffset
// Anim_GetOffset
//
//
void Anim_SetOffset(Anim a, int x, int y) {
Animation *anim = a;
Draw_SetOffset(anim->img, x, y);
}
void Anim_GetOffset(Anim a, int *x, int *y) {
Animation *anim = a;
Draw_GetOffset(anim->img, x, y);
}
/////////////////////////////
// Anim_SetFlip
// Anim_GetFlip
//
//
void Anim_SetFlip(Anim a, int flip) {
Animation *anim = a;
Draw_SetFlip(anim->img, flip);
}
int Anim_GetFlip(Anim a) {
Animation *anim = a;
return Draw_GetFlip(anim->img);
}
/////////////////////////////
// Anim_Draw
//
//
void Anim_Draw(Anim a, int time_ms, int x, int y, float scale[2]) {
Animation *anim = a;
int frame;
frame = (time_ms / anim->frameTime) % anim->frames;
Draw_DrawImgPartHoriz(anim->img, x, y, anim->w, frame, scale);
}
/////////////////////////////
// AnimPlay_Copy
//
//
void AnimPlay_Copy(AnimPlay *ad, AnimPlay *ao) {
ad->img = ao->img;
ad->imgPart = ao->imgPart;
ad->w = ao->w;
ad->h = ao->h;
ad->i = ao->i;
ad->j = ao->j;
ad->anim = ao->anim;
ad->time_ms = ao->time_ms;
}
/////////////////////////////
// AnimPlay_SetImg
// AnimPlay_SetAnim
// AnimPlay_SetImgPart
//
//
void AnimPlay_SetImg(AnimPlay *ap, DrawImg img) {
ap->anim = NULL;
ap->time_ms = 0;
ap->img = img;
ap->imgPart = NULL;
}
void AnimPlay_SetAnim(AnimPlay *ap, Anim ani) {
ap->pause = 0;
if (ap->anim == ani) {
return;
}
ap->anim = ani;
ap->time_ms = 0;
ap->img = NULL;
ap->imgPart = NULL;
}
void AnimPlay_SetImgPart(AnimPlay *ap, DrawImg img, int w, int h, int i, int j) {
ap->anim = NULL;
ap->time_ms = 0;
ap->img = NULL;
ap->imgPart = img;
ap->w = w;
ap->h = h;
ap->i = i;
ap->j = j;
}
/////////////////////////////
// AnimPlay_Draw
//
//
void AnimPlay_Draw(AnimPlay *ani, int x, int y, float scale[2]) {
if (ani->anim) {
Anim_Draw(ani->anim, ani->time_ms, x, y, scale);
return;
}
if (ani->img) {
Draw_DrawImg(ani->img, x, y, scale);
return;
}
if (ani->imgPart) {
Draw_DrawImgPart(ani->imgPart, x, y, ani->w, ani->h, ani->i, ani->j, scale);
return;
}
}
/////////////////////////////
// AnimPlay_GetOffset
// AnimPlay_GetSize
//
//
void AnimPlay_GetOffset(AnimPlay *ani, int *x, int *y) {
if (ani->anim) {
Anim_GetOffset(ani->anim, x, y);
return;
}
if (ani->img) {
Draw_GetOffset(ani->img, x, y);
return;
}
if (ani->imgPart) {
Draw_GetOffset(ani->imgPart, x, y);
return;
}
}
void AnimPlay_GetSize(AnimPlay *ani, int *w, int *h) {
if (ani->anim) {
Anim_GetSize(ani->anim, w, h);
return;
}
if (ani->img) {
Draw_GetSize(ani->img, w, h);
return;
}
if (ani->imgPart) {
Draw_GetSize(ani->imgPart, w, h);
return;
}
}
/////////////////////////////
// AnimPlay_SetPause
//
//
void AnimPlay_SetPause(AnimPlay *ani, int p) { ani->pause = p; }
/////////////////////////////
// AnimPlay_IncTime
//
//
void AnimPlay_IncTime(AnimPlay *ani, int t) {
if (ani->anim) {
if (!ani->pause) {
ani->time_ms += t;
}
}
}

View File

@@ -1,112 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Amin_H
#define Amin_H
#include "Draw.h"
////////////////////////////////////////////////
// Anim //
//////////
//
typedef void *Anim;
/////////////////////////////
// Anim_LoadAnim
//
//
Anim Anim_LoadAnim(char *filename, int width, int frames, float fps);
/////////////////////////////
// Anim_GetTime
//
//
int Anim_GetTime(Anim anim);
/////////////////////////////
// Anim_GetSize
//
// Gets the animation size.
void Anim_GetSize(Anim anim, int *w, int *h);
/////////////////////////////
// Anim_SetOffset
// Anim_GetOffset
//
//
void Anim_SetOffset(Anim anim, int x, int y);
void Anim_GetOffset(Anim anim, int *x, int *y);
/////////////////////////////
// Anim_SetFlip
// Draw_GetFlip
//
//
void Anim_SetFlip(Anim anim, int flip);
int Anim_GetFlip(Anim anim);
/////////////////////////////
// Anim_Draw
//
//
void Anim_Draw(Anim anim, int time_ms, int x, int y, float scale[2]);
////////////////////////////////////////////////
// AnimPlay //
//////////////
//
typedef struct {
Anim anim;
int pause;
int time_ms;
DrawImg img;
DrawImg imgPart;
int w, h, i, j;
} AnimPlay;
/////////////////////////////
// AnimPlay_Copy
//
//
void AnimPlay_Copy(AnimPlay *ad, AnimPlay *ao);
/////////////////////////////
// AnimPlay_SetImg
// AnimPlay_SetAnim
// AnimPlay_SetImgPart
//
//
void AnimPlay_SetImg(AnimPlay *ap, DrawImg img);
void AnimPlay_SetAnim(AnimPlay *ap, Anim ani);
void AnimPlay_SetImgPart(AnimPlay *ap, DrawImg img, int w, int h, int i, int j);
/////////////////////////////
// AnimPlay_Draw
//
//
void AnimPlay_Draw(AnimPlay *ani, int x, int y, float scale[2]);
/////////////////////////////
// AnimPlay_GetOffset
// AnimPlay_GetSize
//
//
void AnimPlay_GetOffset(AnimPlay *ani, int *x, int *y);
void AnimPlay_GetSize(AnimPlay *ani, int *w, int *h);
/////////////////////////////
// AnimPlay_SetPause
//
//
void AnimPlay_SetPause(AnimPlay *ani, int p);
/////////////////////////////
// AnimPlay_IncTime
//
//
void AnimPlay_IncTime(AnimPlay *ani, int t);
#endif

View File

@@ -1,363 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include "Audio.h"
#include "Util.h"
static void Audio_MixerCallback(void *ud, Uint8 *stream, int l);
////////////////////////////////////////////////
// AudioWave //
///////////////
// Reference to a sound.
typedef struct TAudioWave TAudioWave, *AudioWave;
struct TAudioWave {
uint32_t sampleRate;
int32_t channels;
int32_t bpb;
int32_t BPB;
int32_t len;
uint8_t *buffer;
AudioWave next;
};
AudioWave g_Waves = NULL;
////////////////////////////////////////////////
// AudioChan //
///////////////
// Reference to a sound.
typedef struct TAudioChan TAudioChan, *AudioChan;
struct TAudioChan {
AudioWave wave;
int32_t pos;
uint8_t rightVolume;
uint8_t leftVolume;
int32_t loop;
AudioChan next;
};
AudioChan g_Channels = NULL;
AudioChan g_FreeChannels = NULL;
static SDL_AudioDeviceID g_AudioDeviceID = 0;
/////////////////////////////
// Audio_Init
//
// Initializes the game audio.
int Audio_Init() {
SDL_AudioSpec as;
SDL_AudioSpec as2;
// Initialize audio subsystem
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
Print("ERROR: Audio_Init: Failure initializing SDL Audio. %s\n", SDL_GetError());
return (0);
}
// Open the audio device using the desired parameters
as.freq = 44100;
as.format = AUDIO_S16SYS;
as.channels = 2;
as.samples = 2048;
as.callback = Audio_MixerCallback;
g_AudioDeviceID = SDL_OpenAudioDevice(NULL, 0, &as, &as2, 0);
if (g_AudioDeviceID == 0) {
Print("ERROR: Audio_Init: Failure opening audio. %s\n", SDL_GetError());
return (0);
}
// Asert results
if (as2.format != AUDIO_S16SYS || as2.freq != 44100 || as2.channels != 2) {
Print("ERROR: Audio_Init: Failure opening audio. (44.1Khz/16b/2c).\n");
SDL_CloseAudio();
return (0);
}
// Unpause and ready to go
SDL_PauseAudioDevice(g_AudioDeviceID, 0);
return (1);
}
/////////////////////////////
// Audio_MixerCallback
//
// Mixes the audio channels.
static void Audio_MixerCallback(void *ud, uint8_t *stream, int l) {
int16_t *ptr_out, *ptr_wave;
AudioChan previousChannel;
AudioChan chan;
AudioWave wave;
int len = l / 4; // Asume 16bpb and 2 output chan
int channelRemaining;
int len_mix;
int i;
// Clean
memset(stream, 0, l);
// Mix all the channels
previousChannel = NULL;
chan = g_Channels;
while (chan) {
if (!chan->wave) {
// Remove finished channels
AudioChan aux_chan = chan->next;
chan->next = g_FreeChannels;
g_FreeChannels = chan;
chan = aux_chan;
if (previousChannel) {
previousChannel->next = chan;
} else {
g_Channels = chan;
}
continue;
}
// Prepare the pointers
ptr_out = (signed short *)stream;
ptr_wave = ((signed short *)chan->wave->buffer) + chan->pos;
wave = chan->wave;
// Determine mixing length
channelRemaining = wave->len - chan->pos;
if (channelRemaining > len) {
len_mix = len;
} else {
if (chan->loop) {
len_mix = len;
} else {
len_mix = channelRemaining;
}
chan->wave = NULL;
}
// Mix the buffer
for (i = 0; i < len_mix; i++) {
int temp;
// Left Channel
temp = ptr_out[0];
temp += (ptr_wave[0] * chan->leftVolume) >> 8;
if (temp > (1 << 14)) {
ptr_out[0] = 1 << 14;
} else if (temp < -(1 << 14)) {
ptr_out[0] = -(1 << 14);
} else {
ptr_out[0] = (int16_t)temp;
}
// Right Channel
temp = ptr_out[1];
temp += (ptr_wave[0] * chan->rightVolume) >> 8;
if (temp > (1 << 14)) {
ptr_out[1] = 1 << 14;
} else if (temp < -(1 << 14)) {
ptr_out[1] = -(1 << 14);
} else {
ptr_out[1] = (int16_t)temp;
}
// Next sample
ptr_out += 2;
if (ptr_wave >= (((signed short *)wave->buffer) + (wave->len - 1))) {
ptr_wave = ((signed short *)wave->buffer);
} else {
ptr_wave++;
}
}
chan->pos += len_mix;
if (chan->wave == NULL && chan->loop == 1) {
chan->wave = wave;
while (chan->pos > wave->len) {
chan->pos -= wave->len;
}
}
// Next channel
previousChannel = chan;
chan = chan->next;
}
}
/////////////////////////////
// Audio_Frame
//
// Notify a frame update to the audio subsystem.
void Audio_Frame() {}
/////////////////////////////
// Audio_LoadSound
//
// Loads a sound, giving a reference.
AudioSnd Audio_LoadSound(char *filename) {
FILE *f;
char id[5] = {0, 0, 0, 0, 0}, *sndBuffer = NULL;
short formatTag, channels, bitsPerSample;
int formatLen, sampleRate, dataSize;
f = fopen(filename, "rb");
if (!f) {
Print("ERROR: Audio_LoadSound: Failure opening file. \"%s\".\n", filename);
return (NULL);
}
// Read id "RIFF"
fread(id, 4, sizeof(char), f);
if (strcmp(id, "RIFF") != 0) {
Print("ERROR: Audio_LoadSound: File is not RIFF. \"%s\".\n", filename);
fclose(f);
return (NULL);
}
// File size (-"RIFF")
fseek(f, 4, SEEK_CUR); // size
// Read id "WAVE"
fread(id, 4, sizeof(char), f);
if (strcmp(id, "WAVE") != 0) {
Print("ERROR:Audio_LoadSound: File is not WAVE. \"%s\".\n", filename);
fclose(f);
return (NULL);
}
// Read the format
fread(id, 1, sizeof(char) * 4, f); // Read "fmt "
fread(&formatLen, 1, sizeof(int), f);
if (formatLen < 14) {
Print("ERROR: Audio_LoadSound: File too short. \"%s\".\n", filename);
fclose(f);
return (NULL);
}
fread(&formatTag, 1, sizeof(short), f); // 1=PCM
if (formatTag != 1) {
Print("ERROR: Audio_LoadSound: Not PCM format. \"%s\".\n", filename);
fclose(f);
return (NULL);
}
fread(&channels, 1, sizeof(short), f);
fread(&sampleRate, 1, sizeof(int), f);
fseek(f, 2, SEEK_CUR); // avgBytesSec
fseek(f, 2, SEEK_CUR); // blockAlign
fread(&bitsPerSample, 1, sizeof(short), f);
fseek(f, formatLen - 14, SEEK_CUR); // Align read
// Assert sound format
if (sampleRate != 44100 || channels != 1 || bitsPerSample != 2) {
Print(
"ERROR: Audio_LoadSound: Format not supported: "
"sampleRate:%d; channels:%d; BPB:%d. \"%s\"\n",
sampleRate,
channels,
bitsPerSample,
filename);
fclose(f);
return (NULL);
}
// Skip no "data" blocks
do {
size_t lenRead = fread(id, 1, sizeof(char) * 4, f);
if (lenRead < 4) {
break;
}
if (strcmp(id, "data") != 0) {
fread(&dataSize, 1, sizeof(int), f);
fseek(f, dataSize, SEEK_CUR);
} else {
break;
}
} while (1);
if (strcmp(id, "data") != 0) {
Print("ERROR: Audio_LoadSound: DATA block not found. \"%s\".\n", filename);
fclose(f);
return (NULL);
}
// Read the "data" block
fread(&dataSize, 1, sizeof(int), f);
sndBuffer = malloc(sizeof(char) * dataSize);
fread(sndBuffer, dataSize, sizeof(char), f);
fclose(f);
// Build the wave object
AudioWave wave = malloc(sizeof(TAudioWave));
wave->sampleRate = sampleRate;
wave->channels = channels;
wave->buffer = (Uint8 *)sndBuffer;
wave->BPB = bitsPerSample;
wave->bpb = wave->BPB * 8;
wave->len = dataSize / (wave->BPB * wave->channels);
// Take a reference
wave->next = g_Waves;
g_Waves = wave;
return (wave);
}
/////////////////////////////
// Audio_PlaySound
//
// Loads a sound, giving a reference.
AudioChn Audio_PlaySound(AudioSnd snd, float leftVolume, float rightVolume, int loop) {
AudioChan chan;
AudioWave wave;
if (!snd) {
return (NULL);
}
// Cast AudioSnd to AudioWave
wave = snd;
// Get a free channel
if (g_FreeChannels) {
chan = g_FreeChannels;
g_FreeChannels = chan->next;
chan->next = NULL;
} else {
chan = malloc(sizeof(TAudioChan));
chan->next = NULL;
}
// Initialize the channel
chan->wave = wave;
chan->pos = 0;
chan->rightVolume = (uint8_t)(rightVolume * 255.0f);
chan->leftVolume = (uint8_t)(leftVolume * 255.0f);
chan->loop = loop;
// Include in sounds list
chan->next = g_Channels;
g_Channels = chan;
return chan;
}
/////////////////////////////
// Audio_StopChan
//
// Stops an audio chanel
void Audio_StopChan(AudioChn c) {
AudioChan chan;
chan = c;
if (c == NULL) {
return;
}
chan->loop = 0;
chan->wave = NULL;
}

View File

@@ -1,48 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Audio_H
#define Audio_H
/////////////////////////////
// Audio_Init
//
// Initializes the game audio.
int Audio_Init();
/////////////////////////////
// Audio_Frame
//
// Notify a frame update to the audio subsystem.
void Audio_Frame();
////////////////////////////////////////////////
// AudioSnd //
//////////////
// Reference to a sound.
typedef void *AudioSnd;
////////////////////////////////////////////////
// AudioChn //
//////////////
// Reference to a playing sound.
typedef void *AudioChn;
/////////////////////////////
// Audio_LoadSound
//
// Loads a sound, giving a reference.
AudioSnd Audio_LoadSound(char *filename);
/////////////////////////////
// Audio_PlaySound
//
// Loads a sound, giving a reference.
AudioChn Audio_PlaySound(AudioSnd snd, float leftVolume, float rightVolume, int loop);
/////////////////////////////
// Audio_StopChan
//
// Stops an audio chanel
void Audio_StopChan(AudioChn chan);
#endif

View File

@@ -1,185 +0,0 @@
// Copyright (C) 2024 Valeriano Alfonso Rodriguez (Kableado)
#include "Bucket.h"
#include "Util.h"
#include <stdlib.h>
#include <tgmath.h>
////////////////////////////////////////////////
// BBox
//
int BBox_Intersect(BBox bbox1, BBox bbox2) {
if (bbox1->x2 >= bbox2->x1 && bbox1->x1 <= bbox2->x2 && bbox1->y2 >= bbox2->y1 && bbox1->y1 <= bbox2->y2) {
return (1);
}
return (0);
}
////////////////////////////////////////////////
// Bucket
//
void Bucket_Init(Bucket bucket) { bucket->count = 0; }
void Bucket_AddItem(Bucket bucket, BBox item) {
if (bucket->count >= Max_ItemsPerBucket) {
Print("Bucket Overflow\n");
return;
}
bucket->bbox[bucket->count] = item;
bucket->count++;
}
void Bucket_AddItemUnique(Bucket bucket, BBox item) {
for (int i = 0; i < bucket->count; i++) {
if (bucket->bbox[i]->parent == item->parent) {
return;
}
}
Bucket_AddItem(bucket, item);
}
int Bucket_SearchItem(Bucket bucket, BBox item) {
for (int i = 0; i < bucket->count; i++) {
if (bucket->bbox[i]->parent == item->parent) {
return i;
}
}
return -1;
}
void Bucket_RemoveIndex(Bucket bucket, int index) {
bucket->bbox[index] = bucket->bbox[bucket->count - 1];
bucket->count--;
bucket->bbox[bucket->count] = NULL;
}
void Bucket_RemoveItem(Bucket bucket, BBox item) {
int index = Bucket_SearchItem(bucket, item);
if (index < 0) {
return;
}
Bucket_RemoveIndex(bucket, index);
}
////////////////////////////////////////////////
// BucketGrid
//
void BucketGrid_Init(BucketGrid bucketGrid, int width, int height, float bucketSize, float offsetX, float offsetY) {
bucketGrid->width = width;
bucketGrid->height = height;
bucketGrid->bucketSize = bucketSize;
bucketGrid->offsetX = offsetX;
bucketGrid->offsetY = offsetY;
bucketGrid->bucket = (TBucket *)malloc(sizeof(TBucket) * bucketGrid->width * bucketGrid->height);
for (int y = 0; y < bucketGrid->height; y++) {
for (int x = 0; x < bucketGrid->width; x++) {
Bucket_Init(&bucketGrid->bucket[x + y * width]);
}
}
}
void BucketGrid_DeInit(BucketGrid bucketGrid) { free(bucketGrid->bucket); }
int BucketGrid_AddItem(BucketGrid bucketGrid, BBox item) {
const int x1Bucket = (int)floorf((item->x1 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int x2Bucket = (int)ceilf((item->x2 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int y1Bucket = (int)floorf((item->y1 + bucketGrid->offsetY) / bucketGrid->bucketSize);
const int y2Bucket = (int)ceilf((item->y2 + bucketGrid->offsetY) / bucketGrid->bucketSize);
int inserted = 0;
for (int y = y1Bucket; y <= y2Bucket; y++) {
for (int x = x1Bucket; x <= x2Bucket; x++) {
if (y < 0 || y >= bucketGrid->height || x < 0 || x >= bucketGrid->width) {
continue;
}
Bucket bucket = &bucketGrid->bucket[x + y * bucketGrid->width];
Bucket_AddItem(bucket, item);
inserted = 1;
}
}
if (inserted) {
item->changed = 0;
}
return inserted;
}
void BucketGrid_RemoveItem(BucketGrid bucketGrid, BBox item) {
const int x1Bucket = (int)floorf((item->x1 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int x2Bucket = (int)ceilf((item->x2 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int y1Bucket = (int)floorf((item->y1 + bucketGrid->offsetY) / bucketGrid->bucketSize);
const int y2Bucket = (int)ceilf((item->y2 + bucketGrid->offsetY) / bucketGrid->bucketSize);
for (int y = y1Bucket; y <= y2Bucket; y++) {
for (int x = x1Bucket; x <= x2Bucket; x++) {
if (y < 0 || y >= bucketGrid->height || x < 0 || x >= bucketGrid->width) {
continue;
}
Bucket bucket = &bucketGrid->bucket[x + y * bucketGrid->width];
Bucket_RemoveItem(bucket, item);
}
}
}
void BucketGrid_Query(BucketGrid bucketGrid, BBox item, Bucket resultBucket) {
const int x1Bucket = (int)floorf((item->x1 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int x2Bucket = (int)ceilf((item->x2 + bucketGrid->offsetX) / bucketGrid->bucketSize);
const int y1Bucket = (int)floorf((item->y1 + bucketGrid->offsetY) / bucketGrid->bucketSize);
const int y2Bucket = (int)ceilf((item->y2 + bucketGrid->offsetY) / bucketGrid->bucketSize);
Bucket_Init(resultBucket);
for (int y = y1Bucket; y <= y2Bucket; y++) {
for (int x = x1Bucket; x <= x2Bucket; x++) {
if (y < 0 || y >= bucketGrid->height || x < 0 || x >= bucketGrid->width) {
continue;
}
Bucket bucket = &bucketGrid->bucket[x + y * bucketGrid->width];
for (int i = 0; i < bucket->count; i++) {
if (BBox_Intersect(bucket->bbox[i], item)) {
Bucket_AddItemUnique(resultBucket, bucket->bbox[i]);
}
}
}
}
}
int BucketGrid_ProcessChanged(BucketGrid bucketGrid) {
TBucket bucketChanged;
Bucket_Init(&bucketChanged);
for (int y = 0; y < bucketGrid->height; y++) {
for (int x = 0; x <= bucketGrid->width; x++) {
Bucket bucket = &bucketGrid->bucket[x + y * bucketGrid->width];
int i = 0;
while (i < bucket->count) {
if (bucket->bbox[i]->changed) {
if (bucketChanged.count == Max_ItemsPerBucket) {
return 0;
}
Bucket_AddItemUnique(&bucketChanged, bucket->bbox[i]);
Bucket_RemoveIndex(bucket, i);
} else {
i++;
}
}
}
}
for (int i = 0; i < bucketChanged.count; i++) {
BucketGrid_AddItem(bucketGrid, bucketChanged.bbox[i]);
}
return 1;
}
void BucketGrid_Clean(BucketGrid bucketGrid) {
for (int y = 0; y < bucketGrid->height; y++) {
for (int x = 0; x <= bucketGrid->width; x++) {
Bucket bucket = &bucketGrid->bucket[x + y * bucketGrid->width];
Bucket_Init(bucket);
}
}
}

View File

@@ -1,68 +0,0 @@
// Copyright (C) 2024 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Bucket_H
#define Bucket_H
////////////////////////////////////////////////
// BBox
//
typedef struct TBBox TBBox, *BBox;
struct TBBox {
float x1, x2;
float y1, y2;
void *parent;
int changed;
};
int BBox_Intersect(BBox bbox1, BBox bbox2);
////////////////////////////////////////////////
// Bucket
//
#define Max_ItemsPerBucket 200
typedef struct TBucket TBucket, *Bucket;
struct TBucket {
BBox bbox[Max_ItemsPerBucket];
int count;
};
void Bucket_Init(Bucket bucket);
void Bucket_AddItem(Bucket bucket, BBox item);
void Bucket_AddItemUnique(Bucket bucket, BBox item);
int Bucket_SearchItem(Bucket bucket, BBox item);
void Bucket_RemoveIndex(Bucket bucket, int index);
void Bucket_RemoveItem(Bucket bucket, BBox item);
////////////////////////////////////////////////
// BucketGrid
//
typedef struct TBucketGrid TBucketGrid, *BucketGrid;
struct TBucketGrid {
TBucket *bucket;
int width;
int height;
float bucketSize;
float offsetX;
float offsetY;
};
void BucketGrid_Init(BucketGrid bucketGrid, int width, int height, float bucketSize, float offsetX, float offsetY);
void BucketGrid_DeInit(BucketGrid bucketGrid);
int BucketGrid_AddItem(BucketGrid bucketGrid, BBox item);
void BucketGrid_RemoveItem(BucketGrid bucketGrid, BBox item);
void BucketGrid_Query(BucketGrid bucketGrid, BBox item, Bucket resultBucket);
int BucketGrid_ProcessChanged(BucketGrid bucketGrid);
void BucketGrid_Clean(BucketGrid bucketGrid);
#endif

1260
src/Draw.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,201 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Draw_H
#define Draw_H
#include <stdint.h>
/////////////////////////////
// Draw_Init
//
// Initializes the game window.
int Draw_Init(int width, int height, const char *title, int pFps, int fps);
/////////////////////////////
// Draw_Clean
//
// Cleans the game window.
void Draw_Clean(uint8_t r, uint8_t g, uint8_t b);
/////////////////////////////
// Draw_Loop
//
// Loops updating the game window.
void Draw_Loop(void (*proc)(void *data), void (*draw)(void *data, float f), void *data);
/////////////////////////////
// Draw_BreakLoop
//
// Breaks the drawing loop
void Draw_BreakLoop();
/////////////////////////////
// Draw_OverrideExit
//
// Overrides the default exit mechanism
void Draw_OverrideExit(int override);
/////////////////////////////
// Draw_Flush
//
// Performs all the queued draw actions.
void Draw_Flush();
////////////////////////////////////////////////
// DrawImg //
/////////////
// Reference to an image.
typedef void *DrawImg;
typedef uint8_t ColorRgba[4];
/////////////////////////////
// Draw_CreateImage
//
DrawImg Draw_CreateImage(int w, int h);
/////////////////////////////
// Draw_LoadImage
//
// Loads an image, giving a reference.
DrawImg Draw_LoadImage(char *filename);
/////////////////////////////
// Draw_GetSize
//
// Gets the image size.
void Draw_GetSize(DrawImg img, int *w, int *h);
/////////////////////////////
// Draw_SetOffset
// Draw_GetOffset
//
// Sets and Gets the image offset.
void Draw_SetOffset(DrawImg img, int x, int y);
void Draw_GetOffset(DrawImg img, int *x, int *y);
/////////////////////////////
// Draw_SetFlip
// Draw_GetFlip
//
//
void Draw_SetFlip(DrawImg img, int flip);
int Draw_GetFlip(DrawImg img);
/////////////////////////////
// Draw_SetPixel
// Draw_AddPixel
//
//
DrawImg Draw_SetPixel(DrawImg img, int x, int y, const ColorRgba color);
DrawImg Draw_AddPixel(DrawImg img, int x, int y, const ColorRgba color, float factor);
/////////////////////////////
// Draw_DrawBoxFilled
//
//
DrawImg Draw_DrawBoxFilled(DrawImg img, int x1, int y1, int x2, int y2, const ColorRgba color);
/////////////////////////////
// Draw_DrawBox
//
//
DrawImg Draw_DrawBox(DrawImg img, int x1, int y1, int x2, int y2, const ColorRgba color);
/////////////////////////////
// Draw_DrawCircle
//
//
DrawImg Draw_DrawCircle(DrawImg img, int centerX, int centerY, int radius, int innerRadius, const ColorRgba color);
/////////////////////////////
// Draw_DrawImg
//
// Draws an image.
void Draw_DrawImg(DrawImg img, int x, int y, const float scale[2]);
/////////////////////////////
// Draw_DrawImgResized
//
// Draws an image, resizing.
void Draw_DrawImgResized(DrawImg img, int x, int y, float w, float h);
/////////////////////////////
// Draw_DrawImgPart
//
// Draws an image part.
void Draw_DrawImgPart(DrawImg img, int x, int y, int w, int h, int i, int j, const float scale[2]);
/////////////////////////////
// Draw_DrawImgPartHoriz
//
// Draws an image part horizontally.
void Draw_DrawImgPartHoriz(DrawImg img, int x, int y, int w, int i, const float scale[2]);
/////////////////////////////
// Draw_ImgParallax
//
//
void Draw_ImgParallax(
DrawImg img, int imgSize[2], const int imgOffset[2], const float parallaxFactor[2], const int gamePos[2],
const int gameSize[2]);
/////////////////////////////
// Draw_SetColor
//
//
void Draw_SetColor(float r, float g, float b, float a);
////////////////////////////////////////////////
// DrawFnt //
/////////////
// Reference to a Font.
typedef void *DrawFnt;
/////////////////////////////
// Draw_DefaultFont
//
// Creates the default font.
DrawFnt Draw_DefaultFont(ColorRgba color);
/////////////////////////////
// Draw_LoadFont
//
// Load a font from a file.
DrawFnt Draw_LoadFont(char *fichero, int min, int max);
/////////////////////////////
// Draw_FontScale
//
void Draw_FontScale(DrawFnt f, const float scale[2]);
/////////////////////////////
// Draw_DrawText
//
// Draws text using a font
void Draw_DrawText(DrawFnt f, const char *text, int x, int y);
/////////////////////////////
// Draw_SaveRGBAToBMP
//
//
void Draw_SaveRGBAToBMP(const char *filename, const uint8_t *data, int width, int height);
/////////////////////////////
// Draw_SaveRGBAToPNG
//
//
void Draw_SaveRGBAToPNG(const char *filename, const uint8_t *data, int width, int height);
/////////////////////////////
// Draw_SaveScreenshot
//
//
void Draw_SaveScreenshot(char *filename);
/////////////////////////////
// Draw_ShowCursor
//
//
void Draw_ShowCursor(int showCursor);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,286 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Entity_H
#define Entity_H
#include "Anim.h"
#include "Bucket.h"
#include "Draw.h"
#include "Util.h"
////////////////////////////////////////////////
// Entity
//
#define EntityFlag_Collision 0x00000001
#define EntityFlag_Overlap 0x00000002
#define EntityFlag_Light 0x00000004
#define EntityFlag_BlockTop 0x00000100
#define EntityFlag_BlockRight 0x00000200
#define EntityFlag_BlockBottom 0x00000400
#define EntityFlag_BlockLeft 0x00000800
#define EntityFlag_Block 0x0000FF00
#define EntityFlag_PlatformCollision 0x00000101
#define EntityFlag_BlockCollision 0x0000FF01
typedef struct TEntity TEntity, *Entity;
struct TEntity {
Entity base;
int type;
vec2 oldpos;
vec2 pos0;
vec2 pos;
int flags;
int internalFlags;
int zorder;
float sortYOffset;
vec2 dir;
vec2 vel;
vec2 bod_offset;
float radius;
float width;
float height;
float mass;
float elast;
float backFric_static;
float backFric_dynamic;
float fric_static;
float fric_dynamic;
AnimPlay anim;
float color0[4];
float color[4];
float light[4];
float defaultColor[4];
float scale0[2];
float scale[2];
void (*oncopy)(Entity ent);
void (*oninit)(Entity ent);
void (*ondelete)(Entity ent);
void (*proc)(Entity ent, int ft);
void (*postproc)(Entity ent, int ft);
int (*collision)(Entity ent, Entity ent2, float t, vec2 n);
void (*overlap)(Entity ent, Entity ent2);
int A;
int B;
int C;
int D;
int E;
vec2 VecA;
vec2 VecB;
Entity child;
TBBox bbox;
Entity next;
};
/////////////////////////////
// Entity_GetFree
//
Entity Entity_GetFree();
/////////////////////////////
// Entity_New
//
Entity Entity_New();
/////////////////////////////
// Entity_Init
//
Entity Entity_Init(Entity e);
/////////////////////////////
// Entity_Destroy
//
void Entity_Destroy(Entity e);
/////////////////////////////
// Entity_Copy
//
Entity Entity_Copy(Entity e);
/////////////////////////////
// Entity_CalcBBox
//
//
void Entity_CalcBBox(Entity e);
/////////////////////////////
// Entity_BBoxIntersect
//
//
int Entity_BBoxIntersect(Entity ent1, Entity ent2);
/////////////////////////////
// Entity_Draw
//
void Entity_Draw(Entity e, int x, int y, float f);
/////////////////////////////
// Entity_IsVisible
//
int Entity_IsVisible(Entity e, int x, int y, int w, int h);
/////////////////////////////
// Entity_Process
//
void Entity_Process(Entity e, int ft);
/////////////////////////////
// Entity_PostProcess
//
void Entity_PostProcess(Entity e, int ft);
////////////////////////////////////////////////
// CollisionInfo
//
#define CollisionResponse_Circle 1
#define CollisionResponse_Line 2
typedef struct TCollisionInfo TCollisionInfo, *CollisionInfo;
struct TCollisionInfo {
int responseType;
Entity ent1;
Entity ent2;
float t;
vec2 n;
int applyFriction;
CollisionInfo next;
};
/////////////////////////////
// CollisionInfo_New
//
//
CollisionInfo CollisionInfo_New(int responseType, Entity ent1, Entity ent2, float t, const vec2 n, int applyFriction);
/////////////////////////////
// CollisionInfo_Destroy
//
//
void CollisionInfo_Destroy(CollisionInfo *collInfoRef);
/////////////////////////////
// CollisionInfo_Add
//
//
void CollisionInfo_Add(
CollisionInfo *collInfo, int responseType, Entity ent1, Entity ent2, float t, vec2 n, int applyFriction);
/////////////////////////////
// CollisionInfo_CheckRepetition
//
//
int CollisionInfo_CheckRepetition(CollisionInfo collInfo, Entity ent1, Entity ent2);
/////////////////////////////
// Entity_CheckCollision
//
//
int Entity_CheckCollision(Entity ent1, Entity ent2, CollisionInfo *collInfoRef);
/////////////////////////////
// Entity_CollisionResponseClircle
//
// Normal response to a collision of spheres.
void Entity_CollisionResponseCircle(Entity b1, Entity b2, float t, const vec2 n);
/////////////////////////////
// Entity_CollisionResponseLine
//
// Normal response to a collision with a line.
void Entity_CollisionResponseLine(Entity ent, Entity ent2, float t, vec2 n, int applyFriction);
/////////////////////////////
// Entity_CollisionInfoResponse
//
//
int Entity_CollisionInfoResponse(CollisionInfo collInfo);
/////////////////////////////
// Entity_Overlaps
//
void Entity_Overlaps(Entity b1, Entity b2);
/////////////////////////////
// Entity_GetPos
// Entity_SetPos
// Entity_AddPos
// Entity_UpdatePos
//
void Entity_GetPos(Entity e, vec2 pos);
void Entity_SetPos(Entity e, const vec2 pos);
void Entity_AddPos(Entity e, const vec2 pos);
void Entity_UpdatePos(Entity e, const vec2 pos);
/////////////////////////////
// Entity_AddVel
// Entity_SetVel
// Entity_SetVelH
// Entity_SetVelV
// Entity_AddVelLimit
// Entity_AddVelLimitH
// Entity_AddVelLimitH
//
void Entity_AddVel(Entity e, const vec2 vel);
void Entity_SetVel(Entity e, const vec2 vel);
void Entity_SetVelH(Entity e, float v);
void Entity_SetVelV(Entity e, float v);
void Entity_AddVelLimit(Entity e, const vec2 vel, float limit);
void Entity_AddVelLimitH(Entity e, float v, float limit);
void Entity_AddVelLimitV(Entity e, float v, float limit);
/////////////////////////////
// Entity_SetColor
// Entity_AddColor
// Entity_MultColor
// Entity_AddColor
// Entity_SetDefaultColor
//
void Entity_SetColor(Entity e, float r, float g, float b, float a);
void Entity_AddColor(Entity e, float r, float g, float b, float a);
void Entity_MultColor(Entity e, float r, float g, float b, float a);
void Entity_SetLight(Entity e, float r, float g, float b, float rad);
void Entity_SetDefaultColor(Entity e, float r, float g, float b, float a);
/////////////////////////////
// Entity_SetScale
// Entity_GetScale
//
void Entity_SetScale(Entity e, const float scale[2]);
void Entity_GetScale(Entity e, float scale[2]);
/////////////////////////////
// Entity_Iluminate
//
void Entity_Iluminate(Entity e, Entity *entityList, int n);
/////////////////////////////
// Entity_MarkUpdateLight
//
void Entity_MarkUpdateLight(Entity e, Entity *elist, int n);
/////////////////////////////
// Entity_IsLight
//
int Entity_IsLight(Entity e);
/////////////////////////////
// Entity_IsUpdateLight
//
int Entity_IsUpdateLight(Entity e);
/////////////////////////////
// Entity_IsMoving
//
int Entity_IsMoving(Entity e);
#endif

View File

@@ -1,260 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
static uint8_t fontData_8x8[2048] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00, //
0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, //
0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00, //
0x04, 0x0c, 0x1c, 0x3c, 0x1c, 0x0c, 0x04, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, //
0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, //
0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00, //
0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, //
0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, //
0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, //
0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, //
0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, //
0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, //
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, //
0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, //
0x3c, 0x66, 0x6e, 0x76, 0x66, 0x3c, 0x00, 0x00, //
0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x00, 0x00, //
0x3c, 0x66, 0x06, 0x1c, 0x30, 0x7e, 0x00, 0x00, //
0x3c, 0x66, 0x0c, 0x06, 0x66, 0x3c, 0x00, 0x00, //
0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x00, 0x00, //
0x7e, 0x60, 0x7c, 0x06, 0x66, 0x3c, 0x00, 0x00, //
0x1c, 0x30, 0x60, 0x7c, 0x66, 0x3c, 0x00, 0x00, //
0x7e, 0x06, 0x06, 0x0c, 0x18, 0x18, 0x00, 0x00, //
0x3c, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00, 0x00, //
0x3c, 0x66, 0x3e, 0x06, 0x0c, 0x38, 0x00, 0x00, //
0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, //
0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, 0x00, //
0x00, 0x06, 0x18, 0x60, 0x18, 0x06, 0x00, 0x00, //
0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, //
0x00, 0x60, 0x18, 0x06, 0x18, 0x60, 0x00, 0x00, //
0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00, //
0x3c, 0x66, 0x5a, 0x5a, 0x5e, 0x60, 0x3c, 0x00, //
0x3c, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x00, 0x00, //
0x7c, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, //
0x3c, 0x60, 0x60, 0x60, 0x60, 0x3c, 0x00, 0x00, //
0x78, 0x6c, 0x66, 0x66, 0x6c, 0x78, 0x00, 0x00, //
0x7e, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00, 0x00, //
0x7e, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00, 0x00, //
0x3c, 0x66, 0x60, 0x6e, 0x66, 0x3e, 0x00, 0x00, //
0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00, 0x00, //
0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, //
0x06, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, //
0xc6, 0xcc, 0xd8, 0xf8, 0xcc, 0xc6, 0x00, 0x00, //
0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x00, 0x00, //
0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x00, //
0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, 0x00, //
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, //
0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x00, 0x00, //
0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x7e, 0x00, 0x00, //
0x7c, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x00, 0x00, //
0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, //
0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, //
0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, //
0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, //
0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, 0x00, //
0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, //
0xc6, 0x6c, 0x38, 0x30, 0x30, 0x30, 0x00, 0x00, //
0xfe, 0x0c, 0x18, 0x30, 0x60, 0xfe, 0x00, 0x00, //
0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, //
0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, //
0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, //
0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, //
0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00, 0x00, //
0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, //
0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00, 0x00, //
0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00, 0x00, //
0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0x00, //
0x1c, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x00, 0x00, //
0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x3c, 0x00, //
0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00, 0x00, //
0x30, 0x00, 0x30, 0x30, 0x30, 0x18, 0x00, 0x00, //
0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x78, 0x00, //
0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x00, 0x00, //
0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, //
0x00, 0xec, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x00, //
0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, //
0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, //
0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x00, //
0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x00, //
0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00, 0x00, //
0x00, 0x3c, 0x60, 0x3c, 0x06, 0x7c, 0x00, 0x00, //
0x30, 0x30, 0x7c, 0x30, 0x30, 0x1c, 0x00, 0x00, //
0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, //
0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, //
0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, //
0x00, 0xcc, 0x78, 0x30, 0x78, 0xcc, 0x00, 0x00, //
0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x30, 0x00, //
0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00, 0x00, //
0x0c, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0c, 0x00, //
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, //
0x30, 0x18, 0x18, 0x0c, 0x18, 0x18, 0x30, 0x00, //
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};

View File

@@ -1,808 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "GameLib.h"
#include <float.h>
// Globals
Entity *g_Entity = NULL;
int *g_EntityFlag = NULL;
int g_NumEntities = 0;
int g_NumEntitiesAllocated = 0;
int g_EntitiesLock = 0;
int g_EntitiesCompactate = 0;
void (*g_GameProcFunc)() = NULL;
void (*g_GamePostProcFunc)() = NULL;
void (*g_GamePreDrawFunc)(float f) = NULL;
void (*g_GameDrawFunc)(float f) = NULL;
int g_ProcFt;
int g_GameSize[2];
int g_GamePos0[2];
int g_GamePos1[2];
int g_GamePosOffset[2];
long long t_proc;
long long t_col;
long long t_over;
long long t_postproc;
long long t_draw;
int fproc_count;
int fdraw_count;
typedef struct TParallaxBackground TParallaxBackground, *ParallaxBackground;
struct TParallaxBackground {
DrawImg img;
int imgSize[2];
int imgOffset[2];
float parallaxFactor[2];
};
#define MaxParallaxBackgrounds 10
TParallaxBackground g_ParallaxBackground[MaxParallaxBackgrounds];
int g_NumParallaxBackgrounds = 0;
TBucketGrid g_BucketGrid;
/////////////////////////////
// GameLib_Init
//
// Initializes the game.
int GameLib_Init(int w, int h, char *title, int pFps, int fps) {
if (!Draw_Init(w, h, title, pFps, fps)) {
return (0);
}
if (!Input_Init()) {
return (0);
}
Audio_Init();
g_GameSize[0] = w;
g_GameSize[1] = h;
g_GamePos0[0] = 0;
g_GamePos0[1] = 0;
g_GamePos1[0] = 0;
g_GamePos1[1] = 0;
g_ProcFt = 1000 / pFps;
BucketGrid_Init(&g_BucketGrid, 1, 1, 64, 32, 32);
return (1);
}
/////////////////////////////
// GameLib_PrepareSize
//
//
void GameLib_PrepareSize(const float x1, const float y1, const float x2, const float y2) {
const float bucketSize = 64;
const float width = x2 - x1;
const float height = y2 - y1;
const int widthBuckets = (int)ceilf(width / bucketSize);
const int heightBuckets = (int)ceilf(height / bucketSize);
BucketGrid_DeInit(&g_BucketGrid);
BucketGrid_Init(&g_BucketGrid, widthBuckets, heightBuckets, bucketSize, -x1, -y1);
for (int i = 0; i < g_NumEntities; i++) {
BucketGrid_AddItem(&g_BucketGrid, &g_Entity[i]->bbox);
}
}
/////////////////////////////
// GameLib_CheckSize
//
//
void GameLib_CheckSize() {
float xMin = FLT_MAX;
float yMin = FLT_MAX;
float xMax = FLT_MIN;
float yMax = FLT_MIN;
for (int i = 0; i < g_NumEntities; i++) {
if (g_Entity[i]->bbox.x1 < xMin)
xMin = g_Entity[i]->bbox.x1;
if (g_Entity[i]->bbox.x2 > xMax)
xMax = g_Entity[i]->bbox.x2;
if (g_Entity[i]->bbox.y1 < yMin)
yMin = g_Entity[i]->bbox.y1;
if (g_Entity[i]->bbox.y2 > yMax)
yMax = g_Entity[i]->bbox.y2;
}
GameLib_PrepareSize(xMin, yMin, xMax, yMax);
}
/////////////////////////////
// GameLib_AddEntity
//
// Adds an entity to the game.
void GameLib_AddEntity(Entity e) {
// Avoid duplications
for (int i = 0; i < g_NumEntities; i++) {
if (g_Entity[i] == e) {
return;
}
}
if (g_NumEntities >= g_NumEntitiesAllocated) {
Entity *entity_aux;
int *entity_flag_aux;
int i;
// Grow the array
if (g_NumEntitiesAllocated == 0) {
g_NumEntitiesAllocated = 32;
} else {
g_NumEntitiesAllocated *= 2;
}
entity_aux = malloc(sizeof(Entity) * g_NumEntitiesAllocated);
entity_flag_aux = malloc(sizeof(int) * g_NumEntitiesAllocated);
for (i = 0; i < g_NumEntities; i++) {
entity_aux[i] = g_Entity[i];
entity_flag_aux[i] = g_EntityFlag[i];
}
if (g_Entity) {
free(g_Entity);
free(g_EntityFlag);
}
g_Entity = entity_aux;
g_EntityFlag = entity_flag_aux;
}
// Add the entity
g_Entity[g_NumEntities] = e;
g_EntityFlag[g_NumEntities] = 1;
g_NumEntities++;
// Mark for light update
Entity_MarkUpdateLight(e, g_Entity, g_NumEntities);
Entity_CalcBBox(e);
if (BucketGrid_AddItem(&g_BucketGrid, &e->bbox) == 0) {
GameLib_CheckSize();
}
Entity_Init(e);
}
/////////////////////////////
// GameLib_RemoveEntity
//
// removes the entity.
int GameLib_RemoveEntity(Entity e) {
int i;
for (i = 0; i < g_NumEntities; i++) {
if (e == g_Entity[i]) {
// Mark to forget
g_EntityFlag[i] = -2;
g_EntitiesCompactate = 1;
return (i);
}
}
return (-1);
}
/////////////////////////////
// GameLib_UnrefEntity
//
// removes the reference to the entity.
int GameLib_UnrefEntity(Entity e) {
int i;
for (i = 0; i < g_NumEntities; i++) {
if (e == g_Entity[i]) {
// Mark or unref
if (g_EntitiesLock) {
g_EntityFlag[i] = -2;
} else {
g_Entity[i] = NULL;
g_EntityFlag[i] = 0;
}
g_EntitiesCompactate = 1;
// Mark for light update
Entity_MarkUpdateLight(e, g_Entity, g_NumEntities);
return (i);
}
}
return (-1);
}
/////////////////////////////
// GameLib_DelEntity
//
// Adds an entity to the game.
int GameLib_DelEntity(Entity e) {
int i;
if ((i = GameLib_UnrefEntity(e)) == -1) {
return (0);
}
if (g_EntitiesLock) {
// Delete latter
g_Entity[i] = e;
g_EntityFlag[i] = -1;
} else {
// Delete now
BucketGrid_RemoveItem(&g_BucketGrid, &g_Entity[i]->bbox);
Entity_Destroy(e);
}
return (1);
}
/////////////////////////////
// GameLib_Compactate
//
//
void GameLib_Compactate() {
int i, j;
j = 0;
if (!g_EntitiesCompactate) {
return;
}
for (i = 0; i < g_NumEntities; i++) {
if (!g_Entity[i] || g_EntityFlag[i] == -2) {
continue;
}
if (g_EntityFlag[i] == -1) {
BucketGrid_RemoveItem(&g_BucketGrid, &g_Entity[i]->bbox);
Entity_Destroy(g_Entity[i]);
continue;
}
if (i > j) {
g_Entity[j] = g_Entity[i];
g_EntityFlag[j] = g_EntityFlag[i];
}
j++;
}
g_NumEntities = j;
g_EntitiesCompactate = 0;
}
/////////////////////////////
// GameLib_ProcLoop
//
// Process the loop.
void GameLib_ProcLoop(void *data) {
int i, j;
int repeat;
long long time;
// Step the gamePosition
g_GamePos0[0] = g_GamePos1[0] + g_GamePosOffset[0];
g_GamePos0[1] = g_GamePos1[1] + g_GamePosOffset[1];
// Process
time = Time_GetTime();
g_EntitiesLock = 1;
if (g_GameProcFunc) {
g_GameProcFunc();
}
for (i = 0; i < g_NumEntities; i++) {
if (!g_Entity[i]) {
continue;
}
Entity_Process(g_Entity[i], g_ProcFt);
}
GameLib_Compactate();
g_EntitiesLock = 0;
if (BucketGrid_ProcessChanged(&g_BucketGrid) == 0) {
Print("Rebuild BucketGrid");
BucketGrid_Clean(&g_BucketGrid);
for (int i = 0; i < g_NumEntities; i++) {
BucketGrid_AddItem(&g_BucketGrid, &g_Entity[i]->bbox);
}
}
t_proc += Time_GetTime() - time;
// Collisions between entities
time = Time_GetTime();
g_EntitiesLock = 1;
int count = 0;
int maxCount = 50;
do {
repeat = 0;
CollisionInfo collInfo = NULL;
for (i = 0; i < g_NumEntities; i++) {
Entity ent = g_Entity[i];
if (!(ent->flags & EntityFlag_Collision) || ent->mass < 0.0f) {
continue;
}
if (ent->vel[0] <= 0.0f && ent->vel[0] >= -0.0f && ent->vel[1] <= 0.0f && ent->vel[1] >= -0.0f) {
continue;
}
TBucket bucket;
BucketGrid_Query(&g_BucketGrid, &ent->bbox, &bucket);
for (j = 0; j < bucket.count; j++) {
Entity entCollision = bucket.bbox[j]->parent;
if (ent == entCollision || !(entCollision->flags & EntityFlag_Collision) ||
CollisionInfo_CheckRepetition(collInfo, ent, entCollision)) {
continue;
}
Entity_CheckCollision(ent, entCollision, &collInfo);
}
}
if (Entity_CollisionInfoResponse(collInfo)) {
repeat = 1;
}
CollisionInfo_Destroy(&collInfo);
count++;
} while (repeat && count < maxCount);
// Stop remaining collisions
if (count >= maxCount) {
for (i = 0; i < g_NumEntities; i++) {
Entity ent = g_Entity[i];
if (!(ent->flags & EntityFlag_Collision) || ent->mass < 0.0f) {
continue;
}
TBucket bucket;
BucketGrid_Query(&g_BucketGrid, &ent->bbox, &bucket);
for (j = 0; j < bucket.count; j++) {
Entity entCollision = bucket.bbox[j]->parent;
if (ent == entCollision || !(entCollision->flags & EntityFlag_Collision)) {
continue;
}
if (Entity_CheckCollision(ent, entCollision, NULL)) {
vec2_set(ent->vel, 0, 0);
Entity_CalcBBox(ent);
vec2_set(entCollision->vel, 0, 0);
Entity_CalcBBox(entCollision);
}
}
}
}
GameLib_Compactate();
g_EntitiesLock = 0;
t_col += Time_GetTime() - time;
// Process Overlaps
time = Time_GetTime();
g_EntitiesLock = 1;
for (i = 0; i < g_NumEntities; i++) {
Entity ent = g_Entity[i];
if (!(ent->flags & EntityFlag_Overlap) || ent->mass < 0.0f) {
continue;
}
TBucket bucket;
BucketGrid_Query(&g_BucketGrid, &ent->bbox, &bucket);
for (j = 0; j < bucket.count; j++) {
Entity entCollision = bucket.bbox[j]->parent;
if (!(entCollision->flags & EntityFlag_Overlap) || ent == entCollision) {
continue;
}
Entity_Overlaps(ent, entCollision);
}
}
GameLib_Compactate();
g_EntitiesLock = 0;
t_over += Time_GetTime() - time;
// Sort
int n = g_NumEntities;
do {
int n2 = 0;
for (i = 1; i < n; i++) {
Entity ent1 = g_Entity[i - 1];
Entity ent2 = g_Entity[i];
int swap = 0;
if (ent1->zorder > ent2->zorder) {
// Lower level
swap = 1;
} else if (ent1->zorder < ent2->zorder) {
// Upper level
} else {
// Same level
const float y1 = ent1->pos[1] + ent1->sortYOffset;
const float y2 = ent2->pos[1] + ent2->sortYOffset;
if (y1 == y2) {
if (ent1->pos[0] < ent2->pos[0]) {
swap = 1;
}
} else if (y1 > y2) {
swap = 1;
}
}
if (swap) {
Entity ent = g_Entity[i];
g_Entity[i] = g_Entity[i - 1];
g_Entity[i - 1] = ent;
n2 = i;
}
}
n = n2;
} while (n > 0);
// PostProcess
time = Time_GetTime();
g_EntitiesLock = 1;
for (i = 0; i < g_NumEntities; i++) {
Entity_PostProcess(g_Entity[i], g_ProcFt);
if (Entity_IsMoving(g_Entity[i])) {
Entity_MarkUpdateLight(g_Entity[i], g_Entity, g_NumEntities);
}
}
if (g_GamePostProcFunc) {
g_GamePostProcFunc();
}
GameLib_Compactate();
g_EntitiesLock = 0;
t_postproc += Time_GetTime() - time;
fproc_count++;
}
/////////////////////////////
// GameLib_DrawLoop
//
//
void GameLib_DrawLoop(void *data, float f) {
long long time;
int i;
int game_pos[2];
GameLib_GetPosInstant(game_pos, f);
time = Time_GetTime();
// PreDraw
if (g_GamePreDrawFunc) {
g_GamePreDrawFunc(f);
} else {
if (g_NumParallaxBackgrounds == 0) {
// Clean screen
Draw_Clean(0, 0, 0);
}
}
// Draw parallax backgrounds
for (i = 0; i < g_NumParallaxBackgrounds; i++) {
Draw_ImgParallax(
g_ParallaxBackground[i].img,
g_ParallaxBackground[i].imgSize,
g_ParallaxBackground[i].imgOffset,
g_ParallaxBackground[i].parallaxFactor,
game_pos,
g_GameSize);
}
// Draw entities
GameLib_Compactate();
for (i = 0; i < g_NumEntities; i++) {
Entity e = g_Entity[i];
// Check visibility
if (!Entity_IsVisible(e, game_pos[0], game_pos[1], g_GameSize[0], g_GameSize[1])) {
continue;
}
// Update illumination of this entity
if (Entity_IsUpdateLight(e)) {
Entity_Iluminate(e, g_Entity, g_NumEntities);
}
Entity_Draw(e, -game_pos[0], -game_pos[1], f);
}
Draw_SetColor(1, 1, 1, 1);
g_EntitiesLock = 1;
if (g_GameDrawFunc) {
g_GameDrawFunc(f);
}
GameLib_Compactate();
g_EntitiesLock = 0;
t_draw += Time_GetTime() - time;
fdraw_count++;
#ifndef EMSCRIPTEN
if (Input_GetKey(InputKey_Screenshot) == InputKey_Pressed) {
// Screenshot key
char strFile[255];
int idx = -1;
do {
idx++;
snprintf(strFile, 255, "shot-%04d.png", idx);
} while (access(strFile, F_OK) != -1);
Draw_SaveScreenshot(strFile);
Print("Screenshot saved \"%s\"\n", strFile);
}
#endif // EMSCRIPTEN
if (Input_GetKey(InputKey_DumpProfiling) == InputKey_Pressed && fproc_count > 0 && fdraw_count > 0) {
Print("Profiling:::::::::\n");
Print("t_proc.....:%6lldus\n", t_proc / fproc_count);
Print("t_col......:%6lldus\n", t_col / fproc_count);
Print("t_over.....:%6lldus\n", t_over / fproc_count);
Print("t_postproc.:%6lldus\n", t_postproc / fproc_count);
Print("t_draw.....:%6lldus\n", t_draw / fdraw_count);
Print("n_ents.....:%6lld\n", g_NumEntities);
t_proc = 0;
t_col = 0;
t_over = 0;
t_postproc = 0;
t_draw = 0;
fproc_count = 0;
fdraw_count = 0;
}
}
/////////////////////////////
// GameLib_Loop
//
// Loops the game.
void GameLib_Loop(void (*gameProc)(), void (*gamePostProc)(), void (*gamePreDraw)(float f), void (*gameDraw)(float f)) {
g_GameProcFunc = gameProc;
g_GamePostProcFunc = gamePostProc;
g_GamePreDrawFunc = gamePreDraw;
g_GameDrawFunc = gameDraw;
t_proc = 0;
t_col = 0;
t_over = 0;
t_postproc = 0;
t_draw = 0;
fproc_count = 0;
fdraw_count = 0;
Draw_Loop(GameLib_ProcLoop, GameLib_DrawLoop, NULL);
}
/////////////////////////////
// GameLib_GetPos
// GameLib_SetPos
// GameLib_UpdatePos
// GameLib_SetPos
// GameLib_GetPosInstant
// GameLib_SetPosOffset
//
//
void GameLib_GetPos(int pos[2]) {
pos[0] = g_GamePos1[0];
pos[1] = g_GamePos1[1];
}
void GameLib_SetPos(const int pos[2]) {
g_GamePos0[0] = pos[0];
g_GamePos0[1] = pos[1];
g_GamePos1[0] = pos[0];
g_GamePos1[1] = pos[1];
}
void GameLib_UpdatePos(const int pos[2]) {
g_GamePos1[0] = pos[0];
g_GamePos1[1] = pos[1];
}
void GameLib_GetSize(int size[2]) {
size[0] = g_GameSize[0];
size[1] = g_GameSize[1];
}
void GameLib_GetPosInstant(int pos[2], float f) {
pos[0] = g_GamePos0[0] + f * ((g_GamePos1[0] + g_GamePosOffset[0]) - g_GamePos0[0]);
pos[1] = g_GamePos0[1] + f * ((g_GamePos1[1] + g_GamePosOffset[1]) - g_GamePos0[1]);
}
void GameLib_SetPosOffset(const int posOffset[2]) {
g_GamePosOffset[0] = posOffset[0];
g_GamePosOffset[1] = posOffset[1];
}
/////////////////////////////
// GameLib_MoveToPos
// GameLib_MoveToPosH
// GameLib_MoveToPosV
//
//
void GameLib_MoveToPos(vec2 pos, float f) {
GameLib_MoveToPosH(pos, f);
GameLib_MoveToPosV(pos, f);
}
void GameLib_MoveToPosH(const vec2 pos, const float f) {
g_GamePos1[0] = g_GamePos1[0] + (pos[0] - (g_GamePos1[0] + (g_GameSize[0] / 2.0f))) * f;
}
void GameLib_MoveToPosV(const vec2 pos, const float f) {
g_GamePos1[1] = g_GamePos1[1] + (pos[1] - (g_GamePos1[1] + (g_GameSize[1] / 2.0f))) * f;
}
/////////////////////////////
// GameLib_ForEachEn
//
// Deletes every entity.
void GameLib_DelEnts() {
for (int i = 0; i < g_NumEntities; i++) {
if (!g_Entity[i]) {
continue;
}
Entity_Destroy(g_Entity[i]);
}
g_NumEntities = 0;
BucketGrid_DeInit(&g_BucketGrid);
BucketGrid_Init(&g_BucketGrid, 1, 1, 100, 50, 50);
}
/////////////////////////////
// GameLib_ForEachEn
//
// Iterates every entity.
void GameLib_ForEachEnt(int (*func)(Entity ent)) {
for (int i = 0; i < g_NumEntities; i++) {
if (!g_Entity[i]) {
continue;
}
if (!func(g_Entity[i])) {
break;
}
}
}
/////////////////////////////
// GameLib_SearchEnt
//
// Searches through the entities.
Entity GameLib_SearchEnt(int (*func)(Entity ent, void *d), void *d) {
Entity ent = NULL;
for (int i = 0; i < g_NumEntities; i++) {
if (!g_Entity[i]) {
continue;
}
if (func(g_Entity[i], d)) {
ent = g_Entity[i];
break;
}
}
return ent;
}
/////////////////////////////
// GameLib_SearchEntInArea
//
// Searches through the entities, in an area.
Entity GameLib_SearchEntInArea(int (*func)(Entity ent, void *d), void *d, BBox area) {
TBucket searchBucket;
BucketGrid_Query(&g_BucketGrid, area, &searchBucket);
Entity ent = NULL;
for (int i = 0; i < searchBucket.count; i++) {
ent = searchBucket.bbox[i]->parent;
if (!ent) {
continue;
}
if (func(ent, d)) {
break;
}
}
return ent;
}
/////////////////////////////
// GameLib_EntityCustomCheckCollision
//
//
int GameLib_EntityCustomCheckCollision(Entity ent, vec2 vel) {
int collision = 0;
CollisionInfo collInfo = NULL;
vec2 originalVel;
vec2_copy(originalVel, ent->vel);
vec2_copy(ent->vel, vel);
Entity_CalcBBox(ent);
for (int j = 0; j < g_NumEntities; j++) {
if (!(g_Entity[j]->flags & EntityFlag_Collision) || !Entity_BBoxIntersect(ent, g_Entity[j])) {
continue;
}
Entity_CheckCollision(ent, g_Entity[j], &collInfo);
if (collInfo != NULL) {
collision = 1;
break;
}
}
vec2_copy(ent->vel, originalVel);
Entity_CalcBBox(ent);
CollisionInfo_Destroy(&collInfo);
return collision;
}
/////////////////////////////
// GameLib_PlaySound
//
//
void GameLib_PlaySound(AudioSnd snd, int x, int y) {
int r;
// Get the screen context
int cx = g_GamePos1[0] + g_GameSize[0] / 2;
int cy = g_GamePos1[1] + g_GameSize[1] / 2;
if (g_GameSize[0] > g_GameSize[1]) {
r = g_GameSize[0] / 2;
} else {
r = g_GameSize[1] / 2;
}
r = r * 1.2f;
int off = r / 10.0f;
// Calculate volumes
float dx = x - (cx + off);
float dy = y - (cy);
float vRight = 1.0f - (sqrtf(dx * dx + dy * dy) / (float)r);
dx = x - (cx - off);
dy = y - (cy);
float vLeft = 1.0f - (sqrtf(dx * dx + dy * dy) / (float)r);
// Clamp to 0
if (vLeft < 0.0f) {
vLeft = 0.0f;
}
if (vRight < 0.0f) {
vRight = 0.0f;
}
if (vLeft <= 0.0f && vRight <= 0.0f) {
return;
}
// PLAY!
Audio_PlaySound(snd, vLeft, vRight, 0);
}
/////////////////////////////
// GameLib_PlayLoopingSound
//
//
AudioChn GameLib_PlayLoopingSound(AudioSnd snd) {
// PLAY!
return Audio_PlaySound(snd, 1.0f, 1.0f, 1);
}
/////////////////////////////
// GameLib_EntitySetLight
//
//
void GameLib_EntitySetLight(Entity e, float r, float g, float b, float rad) {
if (Entity_IsLight(e)) {
Entity_MarkUpdateLight(e, g_Entity, g_NumEntities);
Entity_SetLight(e, r, g, b, rad);
Entity_MarkUpdateLight(e, g_Entity, g_NumEntities);
} else {
Entity_SetLight(e, r, g, b, rad);
}
}
/////////////////////////////
// GameLib_ConvertScreenPositionToGamePosition
//
//
void GameLib_ConvertScreenPositionToGamePosition(vec2 screenPos, vec2 gamePos, float f) {
int game_pos[2];
game_pos[0] = g_GamePos0[0] + f * ((g_GamePos1[0] + g_GamePosOffset[0]) - g_GamePos0[0]);
game_pos[1] = g_GamePos0[1] + f * ((g_GamePos1[1] + g_GamePosOffset[1]) - g_GamePos0[1]);
gamePos[0] = (screenPos[0] * g_GameSize[0]) + game_pos[0];
gamePos[1] = (screenPos[1] * g_GameSize[1]) + game_pos[1];
}
/////////////////////////////
// GameLib_AddParallaxBackground
//
//
void GameLib_AddParallaxBackground(DrawImg img, int imgSize[2], int imgOffset[2], float parallaxFactor[2]) {
const int idx = g_NumParallaxBackgrounds;
if ((idx + 1) >= MaxParallaxBackgrounds) {
Print("GameLib: Can't add parallaxBackground, limit reached.");
return;
}
g_ParallaxBackground[idx].img = img;
g_ParallaxBackground[idx].imgSize[0] = imgSize[0];
g_ParallaxBackground[idx].imgSize[1] = imgSize[1];
g_ParallaxBackground[idx].imgOffset[0] = imgOffset[0];
g_ParallaxBackground[idx].imgOffset[1] = imgOffset[1];
g_ParallaxBackground[idx].parallaxFactor[0] = parallaxFactor[0];
g_ParallaxBackground[idx].parallaxFactor[1] = parallaxFactor[1];
g_NumParallaxBackgrounds++;
}
/////////////////////////////
// GameLib_CleanParallaxBackgrounds
//
//
void GameLib_CleanParallaxBackgrounds() { g_NumParallaxBackgrounds = 0; }

View File

@@ -1,154 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef GameLib_H
#define GameLib_H
#include "Anim.h"
#include "Audio.h"
#include "Draw.h"
#include "Entity.h"
#include "Input.h"
#include "TimeUtils.h"
#include "Util.h"
/////////////////////////////
// GameLib_Init
//
// Initializes the game.
int GameLib_Init(int w, int h, char *title, int pFps, int fps);
/////////////////////////////
// GameLib_PrepareSize
//
//
void GameLib_PrepareSize(float x1, float y1, float x2, float y2);
/////////////////////////////
// GameLib_CheckSize
//
//
void GameLib_CheckSize();
/////////////////////////////
// GameLib_AddEntity
//
// Adds an entity to the game.
void GameLib_AddEntity(Entity e);
/////////////////////////////
// GameLib_RemoveEntity
//
// removes the entity.
int GameLib_RemoveEntity(Entity e);
/////////////////////////////
// GameLib_UnrefEntity
//
// removes the reference to the entity.
int GameLib_UnrefEntity(Entity e);
/////////////////////////////
// GameLib_DelEntity
//
// Adds an entity to the game.
int GameLib_DelEntity(Entity e);
/////////////////////////////
// GameLib_Loop
//
// Loops the game.
void GameLib_Loop(void (*gameProc)(), void (*gamePostProc)(), void (*gamePreDraw)(float f), void (*gameDraw)(float f));
/////////////////////////////
// GameLib_GetPos
// GameLib_SetPos
// GameLib_UpdatePos
// GameLib_SetPos
// GameLib_GetPosInstant
// GameLib_SetPosOffset
//
//
void GameLib_GetPos(int pos[2]);
void GameLib_SetPos(const int pos[2]);
void GameLib_UpdatePos(const int pos[2]);
void GameLib_GetSize(int size[2]);
void GameLib_GetPosInstant(int pos[2], float f);
void GameLib_SetPosOffset(const int posOffset[2]);
/////////////////////////////
// GameLib_MoveToPos
// GameLib_MoveToPosH
// GameLib_MoveToPosV
//
//
void GameLib_MoveToPos(vec2 pos, float f);
void GameLib_MoveToPosH(const vec2 pos, float f);
void GameLib_MoveToPosV(const vec2 pos, float f);
/////////////////////////////
// GameLib_ForEachEn
//
// Deletes every entity.
void GameLib_DelEnts();
/////////////////////////////
// GameLib_ForEachEnt
//
// Iterates every entity.
void GameLib_ForEachEnt(int (*func)(Entity ent));
/////////////////////////////
// GameLib_SearchEnt
//
// Searches through the entities.
Entity GameLib_SearchEnt(int (*func)(Entity ent, void *d), void *d);
/////////////////////////////
// GameLib_SearchEntInArea
//
// Searches through the entities, in an area.
Entity GameLib_SearchEntInArea(int (*func)(Entity ent, void *d), void *d, BBox area);
/////////////////////////////
// GameLib_EntityCustomCheckCollision
//
//
int GameLib_EntityCustomCheckCollision(Entity ent, vec2 vel);
/////////////////////////////
// GameLib_PlaySound
//
// Play a sound position aware.
void GameLib_PlaySound(AudioSnd snd, int x, int y);
/////////////////////////////
// GameLib_PlayLoopingSound
//
// Play a sound looping
AudioChn GameLib_PlayLoopingSound(AudioSnd snd);
/////////////////////////////
// GameLib_EntitySetLight
//
//
void GameLib_EntitySetLight(Entity e, float r, float g, float b, float rad);
/////////////////////////////
// GameLib_ConvertScreenPositionToGamePosition
//
//
void GameLib_ConvertScreenPositionToGamePosition(vec2 screenPos, vec2 gamePos, float f);
/////////////////////////////
// GameLib_AddParallaxBackground
//
//
void GameLib_AddParallaxBackground(DrawImg img, int imgSize[2], int imgOffset[2], float parallaxFactor[2]);
/////////////////////////////
// GameLib_CleanParallaxBackgrounds
//
//
void GameLib_CleanParallaxBackgrounds();
#endif

View File

@@ -1,226 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <SDL.h>
#include <math.h>
#ifdef EMSCRIPTEN
#define SDL_GetKeyState SDL_GetKeyboardState
#endif
#include "Input.h"
#include "Util.h"
// Globals
InputKeyStatus _keys[InputKey_Max];
int _pointerDown = 0;
float _pointerX = 0;
float _pointerY = 0;
int _clicked = 0;
float _clickedPositionX = 0;
float _clickedPositionY = 0;
/////////////////////////////
// Input_Init
//
// Initializes the game input.
int Input_Init() {
int i;
// Mark released all the keys
for (i = 0; i < InputKey_Max; i++) {
_keys[i] = InputKey_Released;
}
return (1);
}
/////////////////////////////
// Input_Frame
//
// Notify a frame update to the input subsystem.
void Input_Frame() {
Uint8 *keys;
// Get keyboard state
keys = (Uint8 *)SDL_GetKeyboardState(NULL);
// Process Keys
Input_SetKey(InputKey_Action1, keys[SDL_SCANCODE_Z] | keys[SDL_SCANCODE_O]);
Input_SetKey(InputKey_Action2, keys[SDL_SCANCODE_X] | keys[SDL_SCANCODE_P]);
Input_SetKey(InputKey_Up, keys[SDL_SCANCODE_UP] | keys[SDL_SCANCODE_W]);
Input_SetKey(InputKey_Down, keys[SDL_SCANCODE_DOWN] | keys[SDL_SCANCODE_S]);
Input_SetKey(InputKey_Left, keys[SDL_SCANCODE_LEFT] | keys[SDL_SCANCODE_A]);
Input_SetKey(InputKey_Right, keys[SDL_SCANCODE_RIGHT] | keys[SDL_SCANCODE_D]);
Input_SetKey(InputKey_Jump, keys[SDL_SCANCODE_SPACE]);
Input_SetKey(
InputKey_Continue,
keys[SDL_SCANCODE_RETURN] | keys[SDL_SCANCODE_RETURN2] | keys[SDL_SCANCODE_KP_ENTER] | _pointerDown);
Input_SetKey(InputKey_DumpProfiling, keys[SDL_SCANCODE_M]);
Input_SetKey(InputKey_Screenshot, keys[SDL_SCANCODE_F12]);
}
/////////////////////////////
// Input_PostFrame
//
// Notify a frame update to the input subsystem.
void Input_PostFrame() {
Input_SetKey(InputKey_Exit, 0);
_clicked = 0;
}
/////////////////////////////
// Input_SetKey
//
// Notify a key press to the input subsystem.
void Input_SetKey(InputKey key, int status) {
if (!status) {
_keys[key] = InputKey_Released;
} else {
if (_keys[key] >= InputKey_Pressed) {
_keys[key] = InputKey_Holded;
} else {
_keys[key] = InputKey_Pressed;
}
}
}
/////////////////////////////
// Input_GetKey
//
// Reports a the status of a key.
InputKeyStatus Input_GetKey(InputKey key) { return (_keys[key]); }
/////////////////////////////
// Input_SetPointerPosition
//
void Input_SetPointerPosition(float x, float y) {
_pointerX = x;
_pointerY = y;
}
/////////////////////////////
// Input_SetPointerDown
//
void Input_SetPointerDown(int pointerDown) {
if (pointerDown == 0 && _pointerDown == 1) {
_clicked = 1;
_clickedPositionX = _pointerX;
_clickedPositionY = _pointerY;
}
_pointerDown = pointerDown;
}
/////////////////////////////
// Input_GetPointerDown
//
int Input_GetPointerDown() { return _pointerDown; }
/////////////////////////////
// Input_GetPointerPosition
//
int Input_GetPointerPosition(vec2 pointer) {
pointer[0] = _pointerX;
pointer[1] = _pointerY;
return _pointerDown;
}
/////////////////////////////
// Input_GetClickedPosition
//
int Input_GetClickedPosition(vec2 clickPosition) {
clickPosition[0] = _clickedPositionX;
clickPosition[1] = _clickedPositionY;
return _clicked;
}
/////////////////////////////
// Input_AnyKey
//
//
int Input_AnyKey() {
int i;
for (i = 0; i < InputKey_Max; i++) {
if (_keys[i] == InputKey_Pressed) {
return (1);
}
}
return (0);
}
/////////////////////////////
// Input_GetDir
//
// Reports the direction of the dpad and mouse.
int Input_GetDir(vec2 dir) {
float vlen;
Uint8 buttons;
int mx, my;
float dlen;
extern int g_Width, g_Height;
// Get mouse state
buttons = SDL_GetMouseState(&mx, &my);
if (buttons) {
// Use the mouse
vec2_set(dir, mx - (g_Width / 2), my - (g_Height / 2.0f));
dlen = 1.0f / sqrtf(vec2_dot(dir, dir));
vec2_scale(dir, dir, dlen);
return (1);
} else {
// Use the keyboar
vec2_set(dir, 0.0f, 0.0f);
if (Input_GetKey(InputKey_Up)) {
dir[1] -= 1.0f;
}
if (Input_GetKey(InputKey_Down)) {
dir[1] += 1.0f;
}
if (Input_GetKey(InputKey_Left)) {
dir[0] -= 1.0f;
}
if (Input_GetKey(InputKey_Right)) {
dir[0] += 1.0f;
}
vlen = vec2_dot(dir, dir);
if (vlen > 0.0f) {
vlen = sqrtf(vlen);
vec2_scale(dir, dir, 1.0f / vlen);
return (1);
} else {
return (0);
}
}
}
/////////////////////////////
// Input_GetKeyDir
//
// Reports the direction of the dpad.
int Input_GetKeyDir(vec2 dir) {
float vlen;
// Use the keyboard
vec2_set(dir, 0.0f, 0.0f);
if (Input_GetKey(InputKey_Up)) {
dir[1] -= 1.0f;
}
if (Input_GetKey(InputKey_Down)) {
dir[1] += 1.0f;
}
if (Input_GetKey(InputKey_Left)) {
dir[0] -= 1.0f;
}
if (Input_GetKey(InputKey_Right)) {
dir[0] += 1.0f;
}
vlen = vec2_dot(dir, dir);
if (vlen > 0.0f) {
vlen = sqrtf(vlen);
vec2_scale(dir, dir, 1.0f / vlen);
return (1);
} else {
return (0);
}
}

View File

@@ -1,108 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Input_H
#define Input_H
#include "Util.h"
/////////////////////////////
// Input_Init
//
// Initializes the game input.
int Input_Init();
/////////////////////////////
// Input_Frame
//
// Notify a frame update to the input subsystem.
void Input_Frame();
/////////////////////////////
// Input_PostFrame
//
// Notify a frame update end to the input subsystem.
void Input_PostFrame();
////////////////////////////////////////////////
// InputKey //
//////////////
// Key enumeration.
typedef enum {
InputKey_Action1,
InputKey_Action2,
InputKey_Up,
InputKey_Down,
InputKey_Left,
InputKey_Right,
InputKey_Jump,
InputKey_Continue,
InputKey_Exit,
InputKey_DumpProfiling,
InputKey_Screenshot,
InputKey_Max
} InputKey;
/////////////////////////////
// Input_SetKey
//
// Notify a key press to the input subsystem.
void Input_SetKey(InputKey key, int status);
////////////////////////////////////////////////
// InputKeyStatus //
///////////////////
// Key status enumeration.
typedef enum { InputKey_Released, InputKey_Pressed, InputKey_Holded } InputKeyStatus;
/////////////////////////////
// Input_GetKey
//
// Reports a the status of a key.
InputKeyStatus Input_GetKey(InputKey key);
/////////////////////////////
// Input_SetPointerPosition
//
void Input_SetPointerPosition(float x, float y);
/////////////////////////////
// Input_SetPointerDown
//
void Input_SetPointerDown(int pointerDown);
/////////////////////////////
// Input_GetPointerDown
//
int Input_GetPointerDown();
/////////////////////////////
// Input_GetPointerPosition
//
int Input_GetPointerPosition(vec2 pointer);
/////////////////////////////
// Input_GetClickedPosition
//
int Input_GetClickedPosition(vec2 clickPosition);
/////////////////////////////
// Input_AnyKey
//
//
int Input_AnyKey();
/////////////////////////////
// Input_GetDir
//
// Reports the direction of the dpad and mouse.
int Input_GetDir(vec2 dir);
/////////////////////////////
// Input_GetKeyDir
//
// Reports the direction of the dpad.
int Input_GetKeyDir(vec2 dir);
#endif

View File

@@ -1,93 +0,0 @@
// Copyright (C) 2013-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <stdlib.h>
#include <string.h>
#include "QuadArray2D.h"
QuadArray2D QuadArray2D_Create(int resVertex) {
QuadArray2D quadArray = NULL;
quadArray = malloc(sizeof(TQuadArray2D));
quadArray->vertexData = malloc(sizeof(float) * Vertex2D_Length * resVertex);
quadArray->nVertex = 0;
quadArray->resVertex = resVertex;
return quadArray;
}
void QuadArray2D_Destroy(QuadArray2D *quadArray) {
if (!quadArray) {
return;
}
if (!quadArray[0]) {
return;
}
free(quadArray[0]->vertexData);
free(quadArray[0]);
quadArray[0] = NULL;
}
void QuadArray2D_Clean(QuadArray2D quadArray) { quadArray->nVertex = 0; }
void QuadArray2D_AddVertex(QuadArray2D quadArray, float v[]) {
if (quadArray->resVertex <= quadArray->nVertex) {
// Grow vertexData
quadArray->resVertex *= 2;
float *newVertexData = malloc(sizeof(float) * Vertex2D_Length * quadArray->resVertex);
memcpy(newVertexData, quadArray->vertexData, sizeof(float) * Vertex2D_Length * quadArray->nVertex);
free(quadArray->vertexData);
quadArray->vertexData = newVertexData;
}
// Add the vertex
memcpy(quadArray->vertexData + (Vertex2D_Length * quadArray->nVertex), v, sizeof(float) * Vertex2D_Length);
quadArray->nVertex++;
}
void QuadArray2D_AddQuad(
QuadArray2D quadArray, float x0, float y0, float u0, float v0, float x1, float y1, float u1, float v1,
const float color[]) {
float v[Vertex2D_Length];
// Set the color
v[4] = color[0];
v[5] = color[1];
v[6] = color[2];
v[7] = color[3];
// Add the vertexes
v[0] = x0;
v[1] = y0;
v[2] = u0;
v[3] = v0;
QuadArray2D_AddVertex(quadArray, v);
v[0] = x1;
v[1] = y0;
v[2] = u1;
v[3] = v0;
QuadArray2D_AddVertex(quadArray, v);
v[0] = x1;
v[1] = y1;
v[2] = u1;
v[3] = v1;
QuadArray2D_AddVertex(quadArray, v);
v[0] = x1;
v[1] = y1;
v[2] = u1;
v[3] = v1;
QuadArray2D_AddVertex(quadArray, v);
v[0] = x0;
v[1] = y1;
v[2] = u0;
v[3] = v1;
QuadArray2D_AddVertex(quadArray, v);
v[0] = x0;
v[1] = y0;
v[2] = u0;
v[3] = v0;
QuadArray2D_AddVertex(quadArray, v);
}

View File

@@ -1,31 +0,0 @@
// Copyright (C) 2013-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef QuadArray2D_H
#define QuadArray2D_H
// Vertex2D -> (x,y) (u,v) (r,g,b,a)
#define Vertex2D_Length 8
////////////////////////////////////////////////
// QuadArray2D
//
typedef struct TQuadArray2D TQuadArray2D, *QuadArray2D;
struct TQuadArray2D {
float *vertexData;
int nVertex;
int resVertex;
};
QuadArray2D QuadArray2D_Create(int resVertex);
void QuadArray2D_Destroy(QuadArray2D *quadArray);
void QuadArray2D_Clean(QuadArray2D quadArray);
void QuadArray2D_AddVertex(QuadArray2D quadArray, float v[]);
void QuadArray2D_AddQuad(
QuadArray2D quadArray, float x0, float y0, float u0, float v0, float x1, float y1, float u1, float v1,
const float color[]);
#endif

View File

@@ -1,59 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <sys/time.h>
#include <unistd.h>
#include "TimeUtils.h"
/////////////////////////////
// Time_GetTime
//
// Gets the current time in usecs.
/////////////////////////////
// Time_Pause
//
// Pauses the execution for t usecs.
#if WIN32
#include <windows.h>
// WIN32
long long Time_GetTime() {
LARGE_INTEGER freq;
LARGE_INTEGER tim;
long long int microt;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&tim);
microt = (tim.QuadPart * 1000000) / freq.QuadPart;
return (microt);
}
void Time_Pause(int pausa) {
long long tend, t, diff;
t = Time_GetTime();
tend = t + pausa;
do {
diff = tend - t;
if (diff > 1000) {
Sleep(diff / 1000);
} else {
Sleep(0);
}
t = Time_GetTime();
} while (tend >= t);
}
#else
// UNIX
long long Time_GetTime() {
struct timeval t;
long long usecs;
gettimeofday(&t, NULL);
usecs = (t.tv_sec * 1000000ll) + (t.tv_usec);
return (usecs);
}
void Time_Pause(long long pause) {
struct timeval tv;
tv.tv_sec = (long long)pause / 1000000;
tv.tv_usec = (long long)pause % 1000000;
select(0, NULL, NULL, NULL, &tv);
}
#endif // if WIN32

View File

@@ -1,18 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef TimeUtils_H
#define TimeUtils_H
/////////////////////////////
// Time_GetTime
//
// Gets the current time in usecs.
long long Time_GetTime();
/////////////////////////////
// Time_Pause
//
// Pauses the execution for t usecs.
void Time_Pause(long long pause);
#endif

View File

@@ -1,421 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "Util.h"
/////////////////////////////
// Misc
//
float CosineInterpolation(float f) { return (1.0f - cosf(f * Pi)) * 0.5f; }
int MinimumInt(int i0, int i1) {
if (i1 < i0) {
return i1;
}
return i0;
}
int MaximumInt(int i0, int i1) {
if (i1 > i0) {
return i1;
}
return i0;
}
uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b) {
const uint16_t sum = a + b;
if (sum > 255) {
return 255;
}
return sum;
}
/////////////////////////////
// Rect
//
void Rect_UnionRect(Rect r0, Rect r1, Rect rd) {
rd->x0 = MinimumInt(r0->x0, r1->x0);
rd->y0 = MinimumInt(r0->y0, r1->y0);
rd->x1 = MaximumInt(r0->x1, r1->x1);
rd->y1 = MaximumInt(r0->y1, r1->y1);
}
int Rect_PointInside(Rect r, int x, int y) { return (x >= r->x0 && x < r->x1 && y >= r->y0 && y < r->y1); }
int Rect_PointInsideAny(TRect r[], int rCount, int x, int y) {
int insideAny = 0;
int i;
for (i = 0; i < rCount; i++) {
if (Rect_PointInside(&(r[i]), x, y)) {
insideAny = 1;
break;
}
}
return insideAny;
}
/////////////////////////////
// SolveQuadratic
//
// Solves a Quadratic equation using a, b and c coeficients.
int SolveQuadratic(float a, float b, float c, float *RMin, float *RMax) {
float root;
float divisor;
float b2;
b2 = b * b;
root = b2 - 4.0f * a * c;
if (root < 0) {
// Complex
return (0);
}
divisor = (2.0f * a);
if (fabsf(divisor) == 0.0f) {
// +inf -inf
return (0);
}
root = sqrtf(root);
RMin[0] = (float)((-b - root) / divisor);
RMax[0] = (float)((-b + root) / divisor);
return (1);
}
////////////////////////////////////////////////
// vec2 //
//////////
// A 2D vector.
float vec2_norm(vec2 v) {
float len;
len = vec2_len(v);
vec2_scale(v, v, 1.0f / len);
return (len);
}
void vec2_orthogonalize4(vec2 v) {
if (fabsf(v[0]) > fabsf(v[1])) {
if (v[0] >= 0) {
v[0] = 1.0f;
v[1] = 0.0f;
} else {
v[0] = -1.0f;
v[1] = 0.0f;
}
} else {
if (v[1] >= 0) {
v[1] = 1.0f;
v[0] = 0.0f;
} else {
v[1] = -1.0f;
v[0] = 0.0f;
}
}
}
void vec2_orthogonalize8(vec2 v) {
float diff = fabsf(fabsf(v[0]) - fabsf(v[1]));
if (diff > 0.2f) {
if (fabsf(v[0]) > fabsf(v[1])) {
if (v[0] >= 0) {
v[0] = 1.0f;
v[1] = 0.0f;
} else {
v[0] = -1.0f;
v[1] = 0.0f;
}
} else {
if (v[1] >= 0) {
v[1] = 1.0f;
v[0] = 0.0f;
} else {
v[1] = -1.0f;
v[0] = 0.0f;
}
}
} else {
if (v[0] > 0.0f) {
v[0] = 0.707f;
} else {
v[0] = -0.707f;
}
if (v[1] > 0.0f) {
v[1] = 0.707f;
} else {
v[1] = -0.707f;
}
}
}
/////////////////////////////
// Intersect_RayUnitCircle
//
// Intersection between a ray and a Unit Circle.
int Intersect_RayUnitCircle(const vec2 orig, const vec2 vel, const vec2 center, float *t) {
float a, b, c;
float Rmin, Rmax;
vec2 distv;
float qlvel;
float qdistv;
// Check if the collision is even posible
qlvel = vec2_dot(vel, vel);
if (fabsf(qlvel) <= 0.0f) {
return (0);
}
vec2_minus(distv, orig, center);
qdistv = vec2_dot(distv, distv);
// Solve as a unit circle
a = qlvel;
b = 2.0f * vec2_dot(distv, vel);
c = qdistv - 1.0f;
if (SolveQuadratic(a, b, c, &Rmin, &Rmax)) {
if (Rmin >= -0.0f && Rmin < Rmax && Rmin <= 1.0f) {
*t = Rmin;
return (1);
}
if (Rmax >= -0.0f && Rmin > Rmax && Rmax <= 1.0f) {
*t = Rmax;
return (1);
}
}
return (0);
}
/////////////////////////////
// Collision_CircleCircle
//
// Collision point of a circle against another circle.
int Collision_CircleCircle(const vec2 cir1, float ra, const vec2 vel, const vec2 cb, float rb, float *t, vec2 n) {
vec2 vel_a, orig_a, cen_a, temp;
float rads, invrads;
float maxx, minx;
float maxy, miny;
// Check if the collision is even posible
rads = ra + rb;
minx = cir1[0] - rads;
maxx = cir1[0] + rads;
if (vel[0] > 0) {
maxx += vel[0];
} else {
minx += vel[0];
}
if (cb[0] < minx || cb[0] > maxx)
return (0);
miny = cir1[1] - rads;
maxy = cir1[1] + rads;
if (vel[1] > 0) {
maxy += vel[1];
} else {
miny += vel[1];
}
if (cb[1] < miny || cb[1] > maxy)
return (0);
// Convert to a unit circle vs ray
invrads = 1.0f / rads;
vec2_scale(vel_a, vel, invrads);
vec2_scale(orig_a, cir1, invrads);
vec2_scale(cen_a, cb, invrads);
if (Intersect_RayUnitCircle(orig_a, vel_a, cen_a, t)) {
// Calculate n
vec2_scaleadd(temp, cir1, vel, *t);
vec2_minus(n, temp, cb);
vec2_scale(n, n, invrads);
return (1);
}
return (0);
}
/////////////////////////////
// Intersect_RayEdge
//
// Intersection between a ray and an edge.
int Intersect_RayEdge(const vec2 pos, const vec2 vel, const vec2 norm, const vec2 edgePos, float len, float *t) {
vec2 pos2, intersection, perp, edgePos2;
float delta, d1, d2, hLen;
vec2_plus(pos2, pos, vel);
hLen = len / 2;
// Check intersection against the line
delta = vec2_dot(norm, edgePos);
d1 = vec2_dot(pos, norm) - delta;
d2 = vec2_dot(pos2, norm) - delta;
if (d1 >= -0.0001f && d2 <= 0.0001f) {
// Intersection with line, Calculate intersection point
*t = d1 / (d1 - d2);
vec2_scaleadd(intersection, pos, vel, *t);
// Perpendicular
vec2_perp(perp, norm);
// Check sides
vec2_scaleadd(edgePos2, edgePos, perp, -hLen);
delta = -vec2_dot(perp, edgePos2);
d1 = (-vec2_dot(perp, intersection)) - delta;
vec2_scaleadd(edgePos2, edgePos, perp, hLen);
delta = vec2_dot(perp, edgePos2);
d2 = vec2_dot(perp, intersection) - delta;
if (d1 <= 0.0f && d2 <= 0.0f) {
// Intersection inside Edge.
return (1);
}
}
return (0);
}
/////////////////////////////
// AbsMod
//
int AbsMod(int v, int d) {
if (v < 0) {
v += d * (((v / d) * (-1)) + 1);
return (v);
} else {
return (v % d);
}
}
float AbsModFloat(float v, int d) {
if (v < 0) {
v += d * ((((int)(v / d)) * (-1)) + 1);
return (v);
} else {
v -= d * (((int)(v / d)) + 1);
return (v);
}
}
/////////////////////////////
// IsBigEndian
//
int IsBigEndian() {
union {
unsigned int i;
char c[4];
} bint = {0x01020304};
return bint.c[0] == 1;
}
/////////////////////////////
// EndsWith
//
int EndsWith(char *str, char *suffix) {
if (!str || !suffix) {
return 0;
}
size_t lenStr = strlen(str);
size_t lenSuffix = strlen(suffix);
if (lenSuffix > lenStr) {
return 0;
}
return strncmp(str + lenStr - lenSuffix, suffix, lenSuffix) == 0;
}
/////////////////////////////
// Rand
//
// (LGC++) + Seed change
#define g_LGC_Seed_N 30
#define g_LGC_Seed_A 30
#define g_LGC_Seed_B 5
#define g_LGC_Seed_C 10
#define g_LGC_Seed_D 15
#define g_LGC_A 16807ul
#define g_LGC_C 2
#define g_LGC_M 2147483647ul
unsigned g_LGC_Seeds[30];
int g_LGC_Seed_I = -1;
unsigned g_RandCount;
unsigned g_RandOrigSeed;
void Rand_Seed(unsigned seed) {
int i;
g_LGC_Seeds[0] = seed;
for (i = 1; i < 30; i++) {
g_LGC_Seeds[i] = (g_LGC_Seeds[i - 1] * g_LGC_A + g_LGC_C) % g_LGC_M;
}
g_LGC_Seed_I = 29;
// Cambio de semilla
g_RandCount = 0;
g_RandOrigSeed = seed;
}
unsigned Rand_Get() {
unsigned val;
int a, b, c, d;
if (g_LGC_Seed_I == -1) {
Rand_Seed(1);
}
a = g_LGC_Seed_I - g_LGC_Seed_A;
if (a < 0) {
a += g_LGC_Seed_N;
}
b = g_LGC_Seed_I - g_LGC_Seed_B;
if (b < 0) {
b += g_LGC_Seed_N;
}
c = g_LGC_Seed_I - g_LGC_Seed_C;
if (c < 0) {
c += g_LGC_Seed_N;
}
d = g_LGC_Seed_I - g_LGC_Seed_D;
if (d < 0) {
d += g_LGC_Seed_N;
}
val = g_LGC_Seeds[a] ^ g_LGC_Seeds[b] ^ g_LGC_Seeds[c] ^ g_LGC_Seeds[d];
a = g_LGC_Seed_I - 1;
if (a < 0) {
a = g_LGC_Seed_N - 1;
}
g_LGC_Seeds[g_LGC_Seed_I] = (g_LGC_Seeds[a] * g_LGC_A + g_LGC_C) % g_LGC_M;
g_LGC_Seed_I++;
if (g_LGC_Seed_I == g_LGC_Seed_N) {
g_LGC_Seed_I = 0;
}
// Cambio de semilla
g_RandCount++;
if (g_RandCount > (1 << 15)) {
Rand_Seed(g_RandOrigSeed + 1);
}
return (val);
}
unsigned Rand_GetBetween(int min, int max) {
if (min == max) {
return max;
}
return (Rand_Get() % (max - min)) + min;
}
/////////////////////////////
// Print
//
// Prints the formatted text
int Print(char *fmt, ...) {
va_list ap;
int n;
// Print
va_start(ap, fmt);
n = vprintf(fmt, ap);
va_end(ap);
// Flush
fflush(stdout);
return (n);
}

View File

@@ -1,133 +0,0 @@
// Copyright (C) 2011-2023 Valeriano Alfonso Rodriguez (Kableado)
#ifndef Util_H
#define Util_H
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#define Pi (3.1415925f)
/////////////////////////////
// Misc
//
float CosineInterpolation(float f);
int MinimumInt(int i0, int i1);
int MaximumInt(int i0, int i1);
uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b);
/////////////////////////////
// Rect
//
typedef struct SRect TRect, *Rect;
struct SRect {
int x0;
int y0;
int x1;
int y1;
};
void Rect_UnionRect(Rect r0, Rect r1, Rect rd);
int Rect_PointInside(Rect r, int x, int y);
int Rect_PointInsideAny(TRect r[], int rCount, int x, int y);
/////////////////////////////
// SolveQuadratic
//
// Solves a Quadratic equation using a, b and c coefficients.
int SolveQuadratic(float a, float b, float c, float *RMin, float *RMax);
////////////////////////////////////////////////
// vec2 //
//////////
// A 2D vector.
typedef float vec2[2];
#define vec2_set(v, x, y) \
(v)[0] = (x); \
(v)[1] = (y)
#define vec2_copy(v1, v2) \
(v1)[0] = (v2)[0]; \
(v1)[1] = (v2)[1]
#define vec2_plus(v, v1, v2) \
(v)[0] = (v1)[0] + (v2)[0]; \
(v)[1] = (v1)[1] + (v2)[1]
#define vec2_minus(v, v1, v2) \
(v)[0] = (v1)[0] - (v2)[0]; \
(v)[1] = (v1)[1] - (v2)[1]
#define vec2_scale(v, v1, s) \
(v)[0] = (v1)[0] * (s); \
(v)[1] = (v1)[1] * (s)
#define vec2_dot(v1, v2) ((v1)[0] * (v2)[0] + (v1)[1] * (v2)[1])
#define vec2_len(v) sqrtf((v)[0] * (v)[0] + (v)[1] * (v)[1])
#define vec2_perp(v, n) \
(v)[0] = -(n)[1]; \
(v)[1] = (n)[0]
#define vec2_scaleadd(v, v1, v2, s) \
(v)[0] = (v2)[0] * (s) + (v1)[0]; \
(v)[1] = (v2)[1] * (s) + (v1)[1]
float vec2_norm(vec2 v);
#define vec2_interpol(v, v1, v2, f) \
(v)[0] = (v1)[0] - f * ((v1)[0] - (v2)[0]); \
(v)[1] = (v1)[1] - f * ((v1)[1] - (v2)[1])
void vec2_orthogonalize4(vec2 v);
void vec2_orthogonalize8(vec2 v);
/////////////////////////////
// Intersect_RayUnitCircle
//
// Intersection between a ray and a Unit Circle.
int Intersect_RayUnitCircle(const vec2 orig, const vec2 vel, const vec2 center, float *t);
/////////////////////////////
// Collision_CircleCircle
//
// Collision point of a circle against another circle.
int Collision_CircleCircle(const vec2 cir1, float ra, const vec2 vel, const vec2 cb, float rb, float *t, vec2 n);
/////////////////////////////
// Intersect_RayEdge
//
// Intersection between a ray and an edge.
int Intersect_RayEdge(const vec2 pos, const vec2 vel, const vec2 norm, const vec2 edgePos, float len, float *t);
/////////////////////////////
// AbsMod
//
int AbsMod(int v, int d);
float AbsModFloat(float v, int d);
/////////////////////////////
// IsBigEndian
//
int IsBigEndian();
/////////////////////////////
// EndsWith
//
int EndsWith(char *str, char *suffix);
/////////////////////////////
// Rand
//
void Rand_Seed(unsigned seed);
unsigned Rand_Get();
#define Rand_GetFloat(x) (((float)(Rand_Get() % 1048576)) / 1048576.0f)
unsigned Rand_GetBetween(int min, int max);
/////////////////////////////
// Print
//
// Prints the formated text
int Print(char *fmt, ...);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff