680 lines
15 KiB
C
680 lines
15 KiB
C
// Copyright (C) 2011 Valeriano Alfonso Rodriguez (Kableado)
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <SDL/SDL.h>
|
|
|
|
#include "Time.h"
|
|
#include "Util.h"
|
|
#include "Draw.h"
|
|
#include "Input.h"
|
|
#include "Audio.h"
|
|
#include "Anim.h"
|
|
#include "Entity.h"
|
|
|
|
#include "GameLib.h"
|
|
|
|
// Globals
|
|
Entity *_entity = NULL;
|
|
int *_entity_flag = NULL;
|
|
int _n_entities = 0;
|
|
int _n_entities_res = 0;
|
|
int _entities_lock = 0;
|
|
int _entities_compactate = 0;
|
|
void (*_gameproc)() = NULL;
|
|
void (*_gamepostproc)() = NULL;
|
|
void (*_gamepredraw)(float f) = NULL;
|
|
void (*_gamedraw)(float f) = NULL;
|
|
int _pft;
|
|
int _game_size[2];
|
|
int _game_pos0[2];
|
|
int _game_pos1[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 _parallaxBackground[MaxParallaxBackgrounds];
|
|
int _nParallaxBackgrounds = 0;
|
|
|
|
int gamelib_debug = 0;
|
|
|
|
/////////////////////////////
|
|
// 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();
|
|
|
|
_game_size[0] = w;
|
|
_game_size[1] = h;
|
|
_game_pos0[0] = 0;
|
|
_game_pos0[1] = 0;
|
|
_game_pos1[0] = 0;
|
|
_game_pos1[1] = 0;
|
|
|
|
_pft = 1000 / pfps;
|
|
|
|
return (1);
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_AddEntity
|
|
//
|
|
// Adds an entity to the game.
|
|
void GameLib_AddEntity(Entity e) {
|
|
if (_n_entities >= _n_entities_res) {
|
|
Entity *entity_aux;
|
|
int *entity_flag_aux;
|
|
int i;
|
|
|
|
// Grow the array
|
|
if (_n_entities_res == 0)
|
|
_n_entities_res = 32;
|
|
else
|
|
_n_entities_res *= 2;
|
|
entity_aux = malloc(sizeof(Entity) * _n_entities_res);
|
|
entity_flag_aux = malloc(sizeof(int) * _n_entities_res);
|
|
for (i = 0; i < _n_entities; i++) {
|
|
entity_aux[i] = _entity[i];
|
|
entity_flag_aux[i] = _entity_flag[i];
|
|
}
|
|
if (_entity) {
|
|
free(_entity);
|
|
free(_entity_flag);
|
|
}
|
|
_entity = entity_aux;
|
|
_entity_flag = entity_flag_aux;
|
|
}
|
|
|
|
// Add the entity
|
|
_entity[_n_entities] = e;
|
|
_entity_flag[_n_entities] = 1;
|
|
_n_entities++;
|
|
|
|
// Mark for light update
|
|
Entity_MarkUpdateLight(e, _entity, _n_entities);
|
|
|
|
Entity_CalcBBox(e);
|
|
|
|
Entity_Init(e);
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_UnrefEntity
|
|
//
|
|
// removes the reference to the entity.
|
|
int GameLib_UnrefEntity(Entity e) {
|
|
int i;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (e == _entity[i]) {
|
|
// Mark or unref
|
|
if (_entities_lock) {
|
|
_entity_flag[i] = -2;
|
|
} else {
|
|
_entity[i] = NULL;
|
|
_entity_flag[i] = 0;
|
|
}
|
|
_entities_compactate = 1;
|
|
|
|
// Mark for light update
|
|
Entity_MarkUpdateLight(e, _entity, _n_entities);
|
|
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 (_entities_lock) {
|
|
// Delete latter
|
|
_entity[i] = e;
|
|
_entity_flag[i] = -1;
|
|
} else {
|
|
// Delete now
|
|
Entity_Destroy(e);
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_Compactate
|
|
//
|
|
//
|
|
void GameLib_Compactate() {
|
|
int i, j;
|
|
j = 0;
|
|
if (!_entities_compactate)
|
|
return;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!_entity[i] || _entity_flag[i] == -2)
|
|
continue;
|
|
if (_entity_flag[i] == -1) {
|
|
Entity_Destroy(_entity[i]);
|
|
continue;
|
|
}
|
|
if (i > j) {
|
|
_entity[j] = _entity[i];
|
|
_entity_flag[j] = _entity_flag[i];
|
|
}
|
|
j++;
|
|
}
|
|
_n_entities = j;
|
|
_entities_compactate = 0;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_ProcLoop
|
|
//
|
|
// Process the loop.
|
|
void GameLib_ProcLoop(void *data) {
|
|
int i, j;
|
|
int repeat, count;
|
|
long long time;
|
|
|
|
// Step the gamePosition
|
|
_game_pos0[0] = _game_pos1[0];
|
|
_game_pos0[1] = _game_pos1[1];
|
|
|
|
// Process
|
|
time = Time_GetTime();
|
|
_entities_lock = 1;
|
|
if (_gameproc) {
|
|
_gameproc();
|
|
}
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!_entity[i])
|
|
continue;
|
|
Entity_Process(_entity[i], _pft);
|
|
}
|
|
GameLib_Compactate();
|
|
_entities_lock = 0;
|
|
t_proc += Time_GetTime() - time;
|
|
|
|
// Colisions between entities
|
|
time = Time_GetTime();
|
|
_entities_lock = 1;
|
|
count = 0;
|
|
do {
|
|
repeat = 0;
|
|
CollisionInfo collInfo = NULL;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!(_entity[i]->flags & EntityFlag_Collision) ||
|
|
_entity[i]->mass < 0.0f)
|
|
continue;
|
|
if (_entity[i]->vel[0] <= 0.0f && _entity[i]->vel[0] >= -0.0f &&
|
|
_entity[i]->vel[1] <= 0.0f && _entity[i]->vel[1] >= -0.0f) {
|
|
continue;
|
|
}
|
|
for (j = 0; j < _n_entities; j++) {
|
|
if (i == j || !(_entity[j]->flags & EntityFlag_Collision) ||
|
|
CollisionInfo_CheckRepetition(collInfo, _entity[i],
|
|
_entity[j]) ||
|
|
!Entity_BBoxIntersect(_entity[i], _entity[j])) {
|
|
continue;
|
|
}
|
|
Entity_CheckCollision(_entity[i], _entity[j], &collInfo);
|
|
}
|
|
}
|
|
if (Entity_CollisionInfoResponse(collInfo)) {
|
|
repeat = 1;
|
|
}
|
|
CollisionInfo_Destroy(&collInfo);
|
|
count++;
|
|
} while (repeat && count < 50);
|
|
|
|
// Stop remaining collisions
|
|
if (count == 10) {
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!(_entity[i]->flags & EntityFlag_Collision) ||
|
|
_entity[i]->mass < 0.0f)
|
|
continue;
|
|
for (j = 0; j < _n_entities; j++) {
|
|
if (i == j || !(_entity[j]->flags & EntityFlag_Collision) ||
|
|
!Entity_BBoxIntersect(_entity[i], _entity[j])) {
|
|
continue;
|
|
}
|
|
if (Entity_CheckCollision(_entity[i], _entity[j], NULL)) {
|
|
vec2_set(_entity[i]->vel, 0, 0);
|
|
Entity_CalcBBox(_entity[i]);
|
|
vec2_set(_entity[j]->vel, 0, 0);
|
|
Entity_CalcBBox(_entity[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GameLib_Compactate();
|
|
_entities_lock = 0;
|
|
t_col += Time_GetTime() - time;
|
|
|
|
// Process Overlaps
|
|
time = Time_GetTime();
|
|
_entities_lock = 1;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!(_entity[i]->flags & EntityFlag_Overlap) ||
|
|
_entity[i]->mass < 0.0f)
|
|
continue;
|
|
for (j = 0; j < _n_entities; j++) {
|
|
if (!(_entity[j]->flags & EntityFlag_Overlap) || i == j)
|
|
continue;
|
|
Entity_Overlaps(_entity[i], _entity[j]);
|
|
}
|
|
}
|
|
GameLib_Compactate();
|
|
_entities_lock = 0;
|
|
t_over += Time_GetTime() - time;
|
|
|
|
// Sort
|
|
int n, n2, swap;
|
|
n = _n_entities;
|
|
do {
|
|
n2 = 0;
|
|
for (i = 1; i < n; i++) {
|
|
Entity ent1 = _entity[i - 1];
|
|
Entity ent2 = _entity[i];
|
|
swap = 0;
|
|
if (ent1->zorder > ent2->zorder) {
|
|
// Lower level
|
|
swap = 1;
|
|
} else if (ent1->zorder < ent2->zorder) {
|
|
// Upper level
|
|
} else {
|
|
// Same level
|
|
float y1 = ent1->pos[1] + ent1->sortYOffset;
|
|
float y2 = ent2->pos[1] + ent2->sortYOffset;
|
|
if (y1 > y2) {
|
|
swap = 1;
|
|
}
|
|
}
|
|
if (swap) {
|
|
Entity ent;
|
|
ent = _entity[i];
|
|
_entity[i] = _entity[i - 1];
|
|
_entity[i - 1] = ent;
|
|
n2 = i;
|
|
}
|
|
}
|
|
n = n2;
|
|
} while (n > 0);
|
|
|
|
// PostProcess
|
|
time = Time_GetTime();
|
|
_entities_lock = 1;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
Entity_PostProcess(_entity[i], _pft);
|
|
if (Entity_IsMoving(_entity[i])) {
|
|
Entity_MarkUpdateLight(_entity[i], _entity, _n_entities);
|
|
}
|
|
}
|
|
if (_gamepostproc) {
|
|
_gamepostproc();
|
|
}
|
|
GameLib_Compactate();
|
|
_entities_lock = 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 (_gamepredraw) {
|
|
_gamepredraw(f);
|
|
} else {
|
|
if (_nParallaxBackgrounds == 0) {
|
|
// Clean screen
|
|
Draw_Clean(0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// Draw parallax backgrounds
|
|
for (i = 0; i < _nParallaxBackgrounds; i++) {
|
|
Draw_ImgParallax(
|
|
_parallaxBackground[i].img, _parallaxBackground[i].imgSize,
|
|
_parallaxBackground[i].imgOffset,
|
|
_parallaxBackground[i].parallaxFactor, game_pos, _game_size);
|
|
}
|
|
|
|
// Draw entities
|
|
GameLib_Compactate();
|
|
for (i = 0; i < _n_entities; i++) {
|
|
Entity e = _entity[i];
|
|
|
|
// Check visivility
|
|
if (!Entity_IsVisible(e, game_pos[0], game_pos[1], _game_size[0],
|
|
_game_size[1])) {
|
|
continue;
|
|
}
|
|
|
|
// Update ilumination of this entity
|
|
if (Entity_IsUpdateLight(e)) {
|
|
Entity_Iluminate(e, _entity, _n_entities);
|
|
}
|
|
|
|
Entity_Draw(e, -game_pos[0], -game_pos[1], f);
|
|
}
|
|
Draw_SetColor(1, 1, 1, 1);
|
|
_entities_lock = 1;
|
|
if (_gamedraw) {
|
|
_gamedraw(f);
|
|
}
|
|
GameLib_Compactate();
|
|
_entities_lock = 0;
|
|
|
|
t_draw += Time_GetTime() - time;
|
|
|
|
fdraw_count++;
|
|
|
|
if (Input_GetKey(InputKey_DumpProfiling) == InputKey_Pressed &&
|
|
fproc_count > 0 && fdraw_count > 0) {
|
|
Print("Profiling:::::::::\n");
|
|
Print("t_proc.....:%6lld\n", t_proc / fproc_count);
|
|
Print("t_col......:%6lld\n", t_col / fproc_count);
|
|
Print("t_over.....:%6lld\n", t_over / fproc_count);
|
|
Print("t_postproc.:%6lld\n", t_postproc / fproc_count);
|
|
Print("t_draw.....:%6lld\n", t_draw / fdraw_count);
|
|
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)) {
|
|
_gameproc = gameproc;
|
|
_gamepostproc = gamepostproc;
|
|
_gamepredraw = gamepredraw;
|
|
_gamedraw = 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
|
|
//
|
|
//
|
|
void GameLib_GetPos(int pos[2]) {
|
|
pos[0] = _game_pos1[0];
|
|
pos[1] = _game_pos1[1];
|
|
}
|
|
void GameLib_SetPos(int pos[2]) {
|
|
_game_pos0[0] = pos[0];
|
|
_game_pos0[1] = pos[1];
|
|
_game_pos1[0] = pos[0];
|
|
_game_pos1[1] = pos[1];
|
|
}
|
|
void GameLib_UpdatePos(int pos[2]) {
|
|
_game_pos1[0] = pos[0];
|
|
_game_pos1[1] = pos[1];
|
|
}
|
|
void GameLib_GetSize(int size[2]) {
|
|
size[0] = _game_size[0];
|
|
size[1] = _game_size[1];
|
|
}
|
|
void GameLib_GetPosInstant(int pos[2], float f) {
|
|
pos[0] = _game_pos0[0] + f * (_game_pos1[0] - _game_pos0[0]);
|
|
pos[1] = _game_pos0[1] + f * (_game_pos1[1] - _game_pos0[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(vec2 pos, float f) {
|
|
_game_pos1[0] =
|
|
_game_pos1[0] + (pos[0] - (_game_pos1[0] + (_game_size[0] / 2.0f))) * f;
|
|
}
|
|
void GameLib_MoveToPosV(vec2 pos, float f) {
|
|
_game_pos1[1] =
|
|
_game_pos1[1] + (pos[1] - (_game_pos1[1] + (_game_size[1] / 2.0f))) * f;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_ForEachEn
|
|
//
|
|
// Deletes every entity.
|
|
void GameLib_DelEnts() {
|
|
int i;
|
|
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!_entity[i])
|
|
continue;
|
|
Entity_Destroy(_entity[i]);
|
|
}
|
|
_n_entities = 0;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_ForEachEn
|
|
//
|
|
// Iterates every entity.
|
|
void GameLib_ForEachEnt(int (*func)(Entity ent)) {
|
|
int i;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!_entity[i])
|
|
continue;
|
|
if (!func(_entity[i])) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_SearchEnt
|
|
//
|
|
// Searches throught the entities.
|
|
Entity GameLib_SearchEnt(int (*func)(Entity ent, void *d), void *d) {
|
|
int i;
|
|
Entity ent = NULL;
|
|
for (i = 0; i < _n_entities; i++) {
|
|
if (!_entity[i])
|
|
continue;
|
|
if (func(_entity[i], d)) {
|
|
ent = _entity[i];
|
|
break;
|
|
}
|
|
}
|
|
return ent;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_EntityCustomCheckCollision
|
|
//
|
|
//
|
|
int GameLib_EntityCustomCheckCollision(Entity ent, vec2 vel) {
|
|
int collision = 0;
|
|
CollisionInfo collInfo = NULL;
|
|
vec2 originalVel;
|
|
int j;
|
|
|
|
vec2_copy(originalVel, ent->vel);
|
|
vec2_copy(ent->vel, vel);
|
|
Entity_CalcBBox(ent);
|
|
|
|
for (j = 0; j < _n_entities; j++) {
|
|
if (!(_entity[j]->flags & EntityFlag_Collision) ||
|
|
!Entity_BBoxIntersect(ent, _entity[j])) {
|
|
continue;
|
|
}
|
|
Entity_CheckCollision(ent, _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) {
|
|
float vleft, vright, dx, dy;
|
|
int r, cx, cy, off;
|
|
|
|
// Get the screen context
|
|
cx = _game_pos1[0] + _game_size[0] / 2;
|
|
cy = _game_pos1[1] + _game_size[1] / 2;
|
|
if (_game_size[0] > _game_size[1]) {
|
|
r = _game_size[0] / 2;
|
|
} else {
|
|
r = _game_size[1] / 2;
|
|
}
|
|
r = r * 1.2f;
|
|
off = r / 10.0f;
|
|
|
|
// Calculate volumes
|
|
dx = x - (cx + off);
|
|
dy = y - (cy);
|
|
vright = 1.0f - (sqrtf(dx * dx + dy * dy) / (float)r);
|
|
dx = x - (cx - off);
|
|
dy = y - (cy);
|
|
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, _entity, _n_entities);
|
|
Entity_SetLight(e, r, g, b, rad);
|
|
Entity_MarkUpdateLight(e, _entity, _n_entities);
|
|
} 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] = _game_pos0[0] + f * (_game_pos1[0] - _game_pos0[0]);
|
|
game_pos[1] = _game_pos0[1] + f * (_game_pos1[1] - _game_pos0[1]);
|
|
|
|
gamePos[0] = (screenPos[0] * _game_size[0]) + game_pos[0];
|
|
gamePos[1] = (screenPos[1] * _game_size[1]) + game_pos[1];
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_AddParallaxBackground
|
|
//
|
|
//
|
|
void GameLib_AddParallaxBackground(DrawImg img, int imgSize[2],
|
|
int imgOffset[2], float parallaxFactor[2]) {
|
|
int idx = _nParallaxBackgrounds;
|
|
if ((idx + 1) >= MaxParallaxBackgrounds) {
|
|
Print("GameLib: Can't add parallaxBackground, limit reached.");
|
|
return;
|
|
}
|
|
_parallaxBackground[idx].img = img;
|
|
_parallaxBackground[idx].imgSize[0] = imgSize[0];
|
|
_parallaxBackground[idx].imgSize[1] = imgSize[1];
|
|
_parallaxBackground[idx].imgOffset[0] = imgOffset[0];
|
|
_parallaxBackground[idx].imgOffset[1] = imgOffset[1];
|
|
_parallaxBackground[idx].parallaxFactor[0] = parallaxFactor[0];
|
|
_parallaxBackground[idx].parallaxFactor[1] = parallaxFactor[1];
|
|
_nParallaxBackgrounds++;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// GameLib_CleanParallaxBackgrounds
|
|
//
|
|
//
|
|
void GameLib_CleanParallaxBackgrounds() { _nParallaxBackgrounds = 0; }
|