First commit

This commit is contained in:
2017-10-13 08:11:07 +02:00
commit a51ea64692
28 changed files with 7990 additions and 0 deletions

19
.hgignore Normal file
View File

@@ -0,0 +1,19 @@
syntax: glob
mathwars
recursos/*
bin/*
obj/*
Debug/*
Release/*
data/*
*.suo
*.sdf
*.opensdf
*.user
*.dll
.DS_Store
trick.ini
*.xcuserstate
project.xcworkspace/
xcuserdata/

136
Enemies.cpp Normal file
View File

@@ -0,0 +1,136 @@
#include "Enemies.h"
#include "api.h"
#define MAX_ENEMIES 5
struct Enemy {
float x, y, by, fn;
int m1, m2;
int state;
int type;
};
Enemy enemies[MAX_ENEMIES];
int enemyTimer = 0;
int kills = 0;
int wave = 5;
int betweenWaves = 300;
int generations = 0;
int table[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
bool visited[8] = { false, false, false, false, false, false, false, false };
int tableSize = 8;
void ResetEnemies() {
enemyTimer = 0;
kills = 0;
generations = 0;
tableSize = 8;
for (int i = 0; i < 8; i++) { table[i] = i; visited[i] = false; }
for (int i = 0; i < MAX_ENEMIES; i++) {
enemies[i].x = enemies[i].y = enemies[i].by = -1;
enemies[i].fn = 0;
enemies[i].state = 0;
enemies[i].type = rand() % 2;
}
}
Enemies::Enemies() {
ResetEnemies();
RegisterMessage("CheckEnemyHit", this);
RegisterMessage("ResetEnemies", this);
}
void GenerateNewEnemy() {
if (generations >= 16) return;
enemyTimer = 60 + SDL_max(60 - (kills), 0);
for (int i = 0; i < MAX_ENEMIES; i++) {
if (enemies[i].y == -1) {
generations++;
enemies[i].by = enemies[i].y = 20 + rand() % 230;
enemies[i].fn = 0;
enemies[i].x = 480;
enemies[i].m1 = 1 + wave; // (rand() % (3 + SDL_min(int(SDL_floor(kills / 5.0f)), 4)));
int num = rand() % tableSize;
/*char peiv[10]; itoa(table[num], peiv, 10);
SDL_Log(peiv);*/
enemies[i].m2 = 2 + table[num];
if (visited[table[num]]) { tableSize--; if (num < tableSize) table[num] = table[tableSize]; } else { visited[table[num]] = true; }
enemies[i].state = 0;
enemies[i].type = rand() % 2;
return;
}
}
}
void Enemies::Update() {
if (betweenWaves > 0) {
betweenWaves--;
if (betweenWaves < 240) {
char waveText[7] = "WAVE 0"; waveText[5] = wave + 48;
Print(200, 120, waveText, 255, 255, 255);
}
} else {
enemyTimer--;
if (enemyTimer <= 0) GenerateNewEnemy();
for (int i = 0; i < MAX_ENEMIES; i++) {
if (enemies[i].y > -1) {
enemies[i].fn += (0.01f + kills*0.0025f);
enemies[i].y = enemies[i].by + SDL_sinf(enemies[i].fn)*10.0f;
enemies[i].x -= (0.5f + kills*0.02f);
if (enemies[i].state == 0 && enemies[i].x <= 100) {
SendMessage("CreateNewLaser", enemies[i].x, enemies[i].y, 40, 125, 1);
Blink();
SendMessage("HeroHit");
enemyTimer = 400;
for (int j = 0; j < MAX_ENEMIES; j++) {
if (enemies[j].y < 135) { enemies[j].state = 10; }
else { enemies[j].state = -10; }
enemies[j].m1 = enemies[j].m2 = 0;
}
//betweenWaves = 420; ResetEnemies();
}
if (enemies[i].state != 0) enemies[i].x -= 1.0f;
if (enemies[i].state > 0) enemies[i].y -= 1.0f;
if (enemies[i].state < 0) enemies[i].y += 1.0f;
if (enemies[i].type == 0) {
Draw(enemies[i].x, enemies[i].y, 37, 64, 17, 13, enemies[i].state - SDL_cosf(enemies[i].fn)*10.0f);
}
else {
Draw(enemies[i].x, enemies[i].y, 54, 64, 21, 13, enemies[i].state - SDL_cosf(enemies[i].fn)*10.0f);
}
if (enemies[i].state == 0) {
PrintChar(enemies[i].x - 2, enemies[i].y - 10, enemies[i].m1 + 48, 0, 255, 0);
PrintChar(enemies[i].x + 5, enemies[i].y - 10, 'x', 128, 128, 128);
PrintChar(enemies[i].x + 12, enemies[i].y - 10, enemies[i].m2 + 48, 0, 255, 0);
}
if (enemies[i].x < -20) { enemies[i].x = enemies[i].y = -1; }
}
}
}
}
void CheckEnemyHit(int n1, int n2) {
for (int i = 0; i < MAX_ENEMIES; i++) {
if (enemies[i].y > -1) {
if (enemies[i].m1 * enemies[i].m2 == n1 * 10 + n2) {
SendMessage("CreateNewLaser", 40, 125, enemies[i].x, enemies[i].y, 0);
Blink();
kills++;
SendMessage("GenerateExplosion", enemies[i].x, enemies[i].y); //GenerateExplosion(enemies[i].x, enemies[i].y);
enemies[i].x = enemies[i].y = -1;
SendMessage("IncreaseScore", 100); //score += 100;
if (kills == 16) {
betweenWaves = 360; wave++; ResetEnemies();
}
}
}
}
}
void Enemies::ProcessMessage(const char* msg) {
if (msg == "CheckEnemyHit") {
int* params = GetMessageParams();
CheckEnemyHit(params[0], params[1]);
} else if (msg == "ResetEnemies") {
betweenWaves = 420; ResetEnemies();
}
}

10
Enemies.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Enemies : public System {
public:
Enemies();
void Update();
void ProcessMessage(const char* msg);
};

95
Explosions.cpp Normal file
View File

@@ -0,0 +1,95 @@
#include "Explosions.h"
#include "api.h"
#define MAX_EXPLOSIONS 5
#define PIXELS_PER_EXPLOSION 24
#define PARTICLES_PER_EXPLOSION 4
struct Particle {
Point pos;
Point dir;
float scale;
float angle;
};
struct Explosion {
Point pos;
Point dir;
float scale;
float angle;
int ttl;
};
Explosion explosions[MAX_EXPLOSIONS][PIXELS_PER_EXPLOSION];
Particle particles[MAX_EXPLOSIONS][PARTICLES_PER_EXPLOSION];
Explosions::Explosions() {
for (int i = 0; i < MAX_EXPLOSIONS; i++) {
explosions[i][0].ttl = 0;
}
RegisterMessage("GenerateExplosion", this);
}
void Explosions::Update() {
for (int i = 0; i < MAX_EXPLOSIONS; i++) {
if (explosions[i][0].ttl > 0) {
for (int j = 0; j < PIXELS_PER_EXPLOSION; j++) {
explosions[i][j].pos.x += explosions[i][j].dir.x;
explosions[i][j].pos.y += explosions[i][j].dir.y;
//SetColor(128+rand()%128, 128+rand()%128, 128+rand()%128);
//DrawPoint(explosions[i][j].pos.x, explosions[i][j].pos.y);
Tint(128 + rand() % 128, 128 + rand() % 128, 128 + rand() % 128);
DrawEx(explosions[i][j].pos.x, explosions[i][j].pos.y, 3, 85, 1, 1, explosions[i][j].scale, explosions[i][j].angle);
if (explosions[i][j].scale > 1) explosions[i][j].scale -= 0.01f;
explosions[i][j].angle += explosions[i][j].dir.x + explosions[i][j].dir.y;
}
explosions[i][0].ttl--;
SetBlend(BlendAdd);
SetAlpha(128);
for (int j = 0; j < 4; j++) DrawEx(particles[i][j].pos.x, particles[i][j].pos.y, 0, 85, 10, 10, particles[i][j].scale, particles[i][j].angle);
Tint(255, 128, 0);
SetAlpha(64);
for (int j = 0; j < 4; j++) DrawEx(particles[i][j].pos.x, particles[i][j].pos.y, 0, 85, 10, 10, particles[i][j].scale * 2, particles[i][j].angle);
SetBlend(BlendBlend);
Tint(255, 255, 255);
SetAlpha(255);
for (int j = 0; j < 4; j++) {
if (particles[i][j].scale > 0.0f) {
particles[i][j].pos.x += particles[i][j].dir.x;
particles[i][j].pos.y += particles[i][j].dir.y;
particles[i][j].scale -= 0.1f;
}
}
}
}
}
void GenerateExplosion(int x, int y) {
for (int i = 0; i < MAX_EXPLOSIONS; i++) {
if (explosions[i][0].ttl == 0) {
explosions[i][0].ttl = 60;
for (int j = 0; j < PIXELS_PER_EXPLOSION; j++) {
explosions[i][j].pos.x = x;
explosions[i][j].pos.y = y;
explosions[i][j].dir.x = ((rand() % 200) - 100)*0.1f;
explosions[i][j].dir.y = ((rand() % 200) - 100)*0.1f;
explosions[i][j].scale = 1 + (rand() % 100)*0.04f;
explosions[i][j].angle = rand() % 360;
}
for (int j = 0; j < PARTICLES_PER_EXPLOSION; j++) {
particles[i][j].pos.x = x;
particles[i][j].pos.y = y;
particles[i][j].dir.x = ((rand() % 200) - 100)*0.02f;
particles[i][j].dir.y = ((rand() % 200) - 100)*0.02f;
particles[i][j].scale = 4;
particles[i][j].angle = rand() % 360;
}
}
}
}
void Explosions::ProcessMessage(const char* msg) {
if (msg == "GenerateExplosion") {
int* params = GetMessageParams();
GenerateExplosion(params[0], params[1]);
}
}

10
Explosions.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Explosions : public System {
public:
Explosions();
void Update();
void ProcessMessage(const char* msg);
};

83
Lasers.cpp Normal file
View File

@@ -0,0 +1,83 @@
#include "Lasers.h"
#include "api.h"
#define MAX_LASERS 5
struct Laser {
Point ini, fin;
float pos;
unsigned char r, g, b;
};
Laser lasers[MAX_LASERS];
int randomLaserCounter = 60;
Lasers::Lasers() {
randomLaserCounter = 60;
for (int i = 0; i < MAX_LASERS; i++) lasers[i].pos = -1.0f;
RegisterMessage("CreateNewLaser", this);
}
void GenerateNewLaser() {
randomLaserCounter = rand() % 60;
for (int i = 0; i < MAX_LASERS; i++) {
if (lasers[i].pos < 0.0f) {
if (rand() % 2 == 0) {
lasers[i].ini.x = 0;
lasers[i].ini.y = rand() % 270;
lasers[i].fin.x = 480;
lasers[i].fin.y = (rand() % 200) - 100;
lasers[i].pos = 0.0f;
lasers[i].r = 255; lasers[i].g = 0; lasers[i].b = 0;
}
else {
lasers[i].ini.x = 480;
lasers[i].ini.y = rand() % 270;
lasers[i].fin.x = -480;
lasers[i].fin.y = (rand() % 200) - 100;
lasers[i].pos = 0.0f;
lasers[i].r = 0; lasers[i].g = 255; lasers[i].b = 0;
}
return;
}
}
}
void Lasers::Update() {
randomLaserCounter--;
if (randomLaserCounter <= 0) GenerateNewLaser();
for (int i = 0; i < MAX_LASERS; i++) {
if (lasers[i].pos >= 0.0f) {
lasers[i].pos += 0.1f;
SetColor(lasers[i].r, lasers[i].g, lasers[i].b);
DrawLine(lasers[i].ini.x + lasers[i].fin.x*lasers[i].pos, lasers[i].ini.y + lasers[i].fin.y*lasers[i].pos, lasers[i].ini.x + lasers[i].fin.x*(lasers[i].pos + 0.2f), lasers[i].ini.y + lasers[i].fin.y*(lasers[i].pos + 0.2f));
DrawLine(lasers[i].ini.x + lasers[i].fin.x*lasers[i].pos, 0.5 + lasers[i].ini.y + lasers[i].fin.y*lasers[i].pos, lasers[i].ini.x + lasers[i].fin.x*(lasers[i].pos + 0.2f), 0.5 + lasers[i].ini.y + lasers[i].fin.y*(lasers[i].pos + 0.2f));
DrawLine(lasers[i].ini.x + lasers[i].fin.x*lasers[i].pos, 1 + lasers[i].ini.y + lasers[i].fin.y*lasers[i].pos, lasers[i].ini.x + lasers[i].fin.x*(lasers[i].pos + 0.2f), 1 + lasers[i].ini.y + lasers[i].fin.y*(lasers[i].pos + 0.2f));
if (lasers[i].pos >= 0.8f)
lasers[i].pos = -1.0f;
}
}
}
void CreateNewLaser(float x1, float y1, float x2, float y2, unsigned char r, unsigned char g, unsigned char b) {
for (int i = 0; i < MAX_LASERS; i++) {
if (lasers[i].pos < 0.0f) {
lasers[i].ini.x = x1;
lasers[i].ini.y = y1;
lasers[i].fin.x = x2 - x1;
lasers[i].fin.y = y2 - y1;
lasers[i].pos = 0.0f;
lasers[i].r = r; lasers[i].g = g; lasers[i].b = b;
return;
}
}
}
void Lasers::ProcessMessage(const char* msg) {
if (msg == "CreateNewLaser") {
int* params = GetMessageParams();
if (params[4] == 0) {
CreateNewLaser(params[0], params[1], params[2], params[3], 255, 0, 0);
} else {
CreateNewLaser(params[0], params[1], params[2], params[3], 0, 255, 0);
}
}
}

10
Lasers.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Lasers : public System {
public:
Lasers();
void Update();
void ProcessMessage(const char* msg);
};

23
Menu.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "Menu.h"
#include "api.h"
#include "StarField.h"
#include "Explosions.h"
#include "Lasers.h"
#include "Enemies.h"
#include "Xwing.h"
#include "Score.h"
Menu::Menu() {
SendMessage("SetStarFieldVelocity", 25);
}
void Menu::Update() {
Draw(176, 50, 128, 0, 128, 64);
Print(130, 150, "PULSA UNA TECLA PARA EMPEZAR", 255, 255, 255);
}
void Menu::ProcessMessage(const char* msg) {
}

10
Menu.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Menu : public System {
public:
Menu();
void Update();
void ProcessMessage(const char* msg);
};

15
Scene.cpp Normal file
View File

@@ -0,0 +1,15 @@
#include "Scene.h"
Scene::Scene()
{
}
Scene::~Scene()
{
}
bool Scene::Update() {
return true;
}

8
Scene.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
class Scene {
public:
Scene();
virtual ~Scene() = 0;
virtual bool Update();
};

32
Score.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include "Score.h"
#include "api.h"
namespace {
int lives = 3;
int score = 0;
}
Score::Score() {
lives = 3;
score = 0;
RegisterMessage("IncreaseScore", this);
RegisterMessage("DecreaseLives", this);
}
void Score::Update() {
char strScore[10];
itoa(score, strScore, 10);
Print(220, 4, strScore, 255, 255, 0);
if (lives > 0) Draw(5, 5, 10, 85, 18, 18);
if (lives > 1) Draw(25, 5, 10, 85, 18, 18);
if (lives > 2) Draw(45, 5, 10, 85, 18, 18);
}
void Score::ProcessMessage(const char* msg) {
if (msg == "IncreaseScore") {
int* params = GetMessageParams();
score += params[0];
} else if (msg == "DecreaseLives") {
lives--;
}
}

10
Score.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Score : public System {
public:
Score();
void Update();
void ProcessMessage(const char* msg);
};

41
StarField.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include "StarField.h"
#include "api.h"
Point starField[3][24];
float speed = 1;
StarField::StarField() {
speed = 1;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 24; j++) {
starField[i][j].x = rand() % 480;
starField[i][j].y = rand() % 270;
}
}
RegisterMessage("SetStarFieldVelocity", this);
}
void StarField::Update() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 24; j++) {
starField[i][j].x -= (speed + i*speed);
if (starField[i][j].x < 0) {
starField[i][j].x = 480;
starField[i][j].y = rand() % 270;
}
}
}
SetColor(32, 32, 32);
for (int j = 0; j < 24; j++) DrawPoint(starField[0][j].x, starField[0][j].y);
SetColor(96, 96, 96);
for (int j = 0; j < 24; j++) DrawPoint(starField[1][j].x, starField[1][j].y);
SetColor(192, 192, 192);
for (int j = 0; j < 24; j++) DrawPoint(starField[2][j].x, starField[2][j].y);
}
void StarField::ProcessMessage(const char* msg) {
if (msg == "SetStarFieldVelocity") {
int* params = GetMessageParams();
speed = params[0] * 0.01f;
}
}

10
StarField.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class StarField : public System {
public:
StarField();
void Update();
void ProcessMessage(const char* msg);
};

9
System.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
class System {
public:
virtual ~System() {};
virtual void Update() = 0;
virtual void ProcessMessage(const char* msg) {};
};

82
Xwing.cpp Normal file
View File

@@ -0,0 +1,82 @@
#include "Xwing.h"
#include "api.h"
#include "keyHandlers.h"
#include "StarField.h"
#include "Menu.h"
namespace {
int hit = 0;
int lives = 3;
int n1 = -1;
int n2 = -1;
int dead = 0;
float y = 125;
float fn = 0;
}
Xwing::Xwing() {
hit = 0;
lives = 3;
n1 = -1;
n2 = -1;
dead = 0;
y = 125;
RegisterMessage("HeroHit", this);
RegisterMessage("SetNumbers", this);
}
void Xwing::Update() {
if (dead == 0) {
if (n1 != -1) PrintChar(20, 115, n1 + 48, 0, 255, 0);
if (n2 != -1) {
PrintChar(27, 115, n2 + 48, 0, 255, 0);
n1 = n2 = -1;
}
if (hit > 0) hit--;
//Tint(255, 0, 0);
fn += 0.05f;
y = 125 + SDL_sinf(fn)*10.0f;
if ((hit / 15) % 2 == 0) Draw(20, y, 0, 64, 37, 21, SDL_cosf(fn)*5.0f);
//Tint(255, 255, 255);
}
else {
dead--;
if (lives == 0) {
if (dead < 120) Print(200, 120, "GAME OVER", 255, 255, 255);
if (dead == 0) {
Reset();
RegisterSystem(new StarField());
RegisterSystem(new Menu());
RegisterKeyboardHandler(&menuKeyHandler);
}
} else {
if (dead == 0) SendMessage("ResetEnemies");
}
}
}
void HeroHit(int x, int y) {
SendMessage("CreateNewLaser", x, y, 40, 125, 1);
hit = 240;
lives--;
dead = lives == 0 ? 300 : 180;
SendMessage("DecreaseLives");
//if (lives == 0)
SendMessage("GenerateExplosion", 60, 135);
}
void SetNumbers(int p1, int p2) {
if (p1 >= 0) n1 = p1;
if (p2 >= 0) n2 = p2;
}
void Xwing::ProcessMessage(const char* msg) {
if (msg == "HeroHit") {
int* params = GetMessageParams();
HeroHit(params[0], params[1]);
} else if (msg == "SetNumbers") {
int* params = GetMessageParams();
SetNumbers(params[0], params[1]);
}
}

10
Xwing.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "System.h"
class Xwing : public System {
public:
Xwing();
void Update();
void ProcessMessage(const char* msg);
};

193
api.cpp Normal file
View File

@@ -0,0 +1,193 @@
#include "api.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <vector>
#include <algorithm>
SDL_Window* sdlWindow = NULL;
SDL_Renderer* sdlRenderer = NULL;
SDL_Texture* sdlTexture = NULL;
SDL_Event sdlEvent;
SDL_Scancode keyJustPressed = SDL_SCANCODE_UNKNOWN;
const Uint8* keyboard = nullptr;
bool blink = false;
KeyboardHandler keyboardHandler = NULL;
std::vector<System*> systems;
std::vector<std::string> msgTexts;
std::vector<System*> msgSystems;
int msgParams[5];
bool reseted = false;
bool anyKey = false;
void Init() {
SDL_Init(SDL_INIT_EVERYTHING);
sdlWindow = SDL_CreateWindow("Math Wars v0.1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 960, 540, SDL_WINDOW_FULLSCREEN_DESKTOP); // SDL_WINDOW_SHOWN
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_PRESENTVSYNC);
SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BLENDMODE_BLEND);
SDL_RenderSetLogicalSize(sdlRenderer, 480, 270);
}
void Quit() {
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
}
void LoadImage(const char* filename) {
int w, h, c;
FILE* f = fopen(filename, "rb");
//if (!f) { error = 2; return; }
unsigned char* buffer = stbi_load_from_file(f, &w, &h, &c, 4);
if (sdlTexture) SDL_DestroyTexture(sdlTexture);
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, w, h);
SDL_UpdateTexture(sdlTexture, NULL, buffer, w * sizeof(Uint32));
SDL_SetTextureBlendMode(sdlTexture, SDL_BLENDMODE_BLEND);
fclose(f);
}
void Flip() {
SDL_RenderPresent(sdlRenderer);
}
void Clear() {
if (blink) {
SDL_SetRenderDrawColor(sdlRenderer, 255, 255, 255, 255);
}
else {
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
}
blink = false;
SDL_RenderClear(sdlRenderer);
}
void Blink() {
blink = true;
}
void Draw(int x, int y, int sx, int sy, int w, int h, int angle) {
SDL_Rect src, dst;
src.x = sx; src.y = sy;
dst.x = x; dst.y = y;
src.w = dst.w = w;
src.h = dst.h = h;
SDL_RenderCopyEx(sdlRenderer, sdlTexture, &src, &dst, angle, NULL, SDL_FLIP_NONE);
}
void DrawScale(int x, int y, int sx, int sy, int w, int h, float scale) {
SDL_Rect src, dst;
src.x = sx; src.y = sy;
dst.x = x; dst.y = y;
src.w = w; dst.w = w*scale;
src.h = h; dst.h = h*scale;
SDL_RenderCopy(sdlRenderer, sdlTexture, &src, &dst);
}
void DrawEx(int x, int y, int sx, int sy, int w, int h, float scale, int angle) {
SDL_Rect src, dst;
float xx = x - (w*scale - w) / 2;
float yy = y - (h*scale - h) / 2;
src.x = sx; src.y = sy;
dst.x = xx; dst.y = yy;
src.w = w; dst.w = w*scale;
src.h = h; dst.h = h*scale;
SDL_RenderCopyEx(sdlRenderer, sdlTexture, &src, &dst, angle, NULL, SDL_FLIP_NONE);
}
void Print(int x, int y, const char* text, int r, int g, int b) {
int str_size = strlen(text);
SDL_SetTextureColorMod(sdlTexture, r, g, b);
for (int i = 0; i < str_size; i++) {
char chr = text[i];
Draw(x + (i * 8), y, (chr & 0x0f) * 8, (chr >> 4) * 8, 8, 8);
}
SDL_SetTextureColorMod(sdlTexture, 255, 255, 255);
}
void PrintChar(int x, int y, const char text, int r, int g, int b) {
SDL_SetTextureColorMod(sdlTexture, r, g, b);
Draw(x, y, (text & 0x0f) * 8, (text >> 4) * 8, 8, 8);
SDL_SetTextureColorMod(sdlTexture, 255, 255, 255);
}
void SetColor(int r, int g, int b) {
SDL_SetRenderDrawColor(sdlRenderer, r, g, b, 255);
}
void DrawPoint(int x, int y) {
SDL_RenderDrawPoint(sdlRenderer, x, y);
}
void DrawLine(int x1, int y1, int x2, int y2) {
SDL_RenderDrawLine(sdlRenderer, x1, y1, x2, y2);
}
void Tint(int r, int g, int b) {
SDL_SetTextureColorMod(sdlTexture, r, g, b);
}
void SetBlend(BlendMode mode) {
SDL_BlendMode m = mode == BlendNone ? SDL_BLENDMODE_NONE : mode == BlendBlend ? SDL_BLENDMODE_BLEND : mode == BlendAdd ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD;
SDL_SetTextureBlendMode(sdlTexture, m);
}
void SetAlpha(int alpha) {
SDL_SetTextureAlphaMod(sdlTexture, alpha);
}
void RegisterKeyboardHandler(KeyboardHandler handler) {
keyboardHandler = handler;
}
void RegisterSystem(System* system) {
systems.push_back(system);
}
void RemoveSystem(System* system) {
systems.erase(std::remove(systems.begin(), systems.end(), system), systems.end());
}
void Reset() {
systems.clear();
msgSystems.clear();
msgTexts.clear();
reseted = true;
}
bool Update() {
while (SDL_PollEvent(&sdlEvent)) {
if (sdlEvent.type == SDL_QUIT) { return true; break; }
else if (sdlEvent.type == SDL_KEYDOWN) {
anyKey = true;
keyJustPressed = sdlEvent.key.keysym.scancode;
if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { return true; }
if (keyboardHandler) keyboardHandler(keyJustPressed);
anyKey = false;
}
}
Clear();
for (auto system : systems) {
system->Update();
if (reseted) {
reseted = false; break;
}
}
Flip();
return false;
}
void RegisterMessage(const char* msg, System* handler) {
msgTexts.push_back(msg);
msgSystems.push_back(handler);
}
void SendMessage(const char* msg, int p1, int p2, int p3, int p4, int p5) {
msgParams[0] = p1; msgParams[1] = p2; msgParams[2] = p3; msgParams[3] = p4; msgParams[4] = p5;
auto it = std::find(msgTexts.begin(), msgTexts.end(), msg);
if (it != msgTexts.end()) {
auto index = std::distance(msgTexts.begin(), it);
msgSystems[index]->ProcessMessage(msg);
}
}
int* GetMessageParams() {
return msgParams;
}

49
api.h Normal file
View File

@@ -0,0 +1,49 @@
#pragma once
#include <SDL.h>
#include "System.h"
#include <stdlib.h>
enum BlendMode { BlendNone, BlendBlend, BlendAdd, BlendMod };
struct Point {
float x, y;
};
typedef void(*KeyboardHandler)(SDL_Scancode);
void Init();
void Quit();
void LoadImage(const char* filename);
void Flip();
void Clear();
void Blink();
void Draw(int x, int y, int sx, int sy, int w, int h, int angle = 0);
void DrawScale(int x, int y, int sx, int sy, int w, int h, float scale = 1.0f);
void DrawEx(int x, int y, int sx, int sy, int w, int h, float scale, int angle);
void Print(int x, int y, const char* text, int r, int g, int b);
void PrintChar(int x, int y, const char text, int r, int g, int b);
void SetColor(int r, int g, int b);
void DrawPoint(int x, int y);
void DrawLine(int x1, int y1, int x2, int y2);
void Tint(int r, int g, int b);
void SetBlend(BlendMode mode);
void SetAlpha(int alpha);
void RegisterKeyboardHandler(KeyboardHandler handler);
void RegisterSystem(System* system);
void RemoveSystem(System* system);
void Reset();
bool Update();
void RegisterMessage(const char* msg, System* handler);
void SendMessage(const char* msg, int p1 = 0, int p2 = 0, int p3 = 0, int p4 = 0, int p5 = 0);
int* GetMessageParams();

BIN
gfx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

40
keyHandlers.cpp Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include "api.h"
#include "keyHandlers.h"
#include "StarField.h"
#include "Explosions.h"
#include "Lasers.h"
#include "Enemies.h"
#include "Xwing.h"
#include "Score.h"
int digit = -1;
void keyHandler(SDL_Scancode key) {
if (key >= 89 && key <= 98) {
int num = key == 98 ? 0 : key - 88;
if (digit == -1) {
digit = num;
SendMessage("SetNumbers", num, -1);
}
else {
SendMessage("SetNumbers", -1, num);
SendMessage("CheckEnemyHit", digit, num);
digit = -1;
}
}
}
void menuKeyHandler(SDL_Scancode key) {
Reset();
RegisterSystem(new StarField());
RegisterSystem(new Xwing());
RegisterSystem(new Enemies());
RegisterSystem(new Lasers());
RegisterSystem(new Explosions());
RegisterSystem(new Score());
RegisterKeyboardHandler(&keyHandler);
}

6
keyHandlers.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include "api.h"
void keyHandler(SDL_Scancode key);
void menuKeyHandler(SDL_Scancode key);

21
main.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "api.h"
#include <time.h>
#include <stdlib.h>
#include "keyHandlers.h"
#include "StarField.h"
#include "Menu.h"
int main(int argc, char* argv[]) {
srand(time(NULL));
Init();
LoadImage("gfx.png");
RegisterSystem(new StarField());
RegisterSystem(new Menu());
RegisterKeyboardHandler(&menuKeyHandler);
while (!Update()) {}
Quit();
return 0;
}

22
mathwars.sln Normal file
View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mathwars", "mathwars.vcxproj", "{5CCE4316-2638-47DA-9C0B-3075E1120FD1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5CCE4316-2638-47DA-9C0B-3075E1120FD1}.Debug|Win32.ActiveCfg = Debug|Win32
{5CCE4316-2638-47DA-9C0B-3075E1120FD1}.Debug|Win32.Build.0 = Debug|Win32
{5CCE4316-2638-47DA-9C0B-3075E1120FD1}.Release|Win32.ActiveCfg = Release|Win32
{5CCE4316-2638-47DA-9C0B-3075E1120FD1}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

111
mathwars.vcxproj Normal file
View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5CCE4316-2638-47DA-9C0B-3075E1120FD1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>mathwars</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>C:\dev\lib\sdl2\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\dev\lib\sdl2\lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="api.cpp" />
<ClCompile Include="Enemies.cpp" />
<ClCompile Include="Explosions.cpp" />
<ClCompile Include="keyHandlers.cpp" />
<ClCompile Include="Lasers.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Menu.cpp" />
<ClCompile Include="Scene.cpp" />
<ClCompile Include="Score.cpp" />
<ClCompile Include="StarField.cpp" />
<ClCompile Include="Xwing.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h" />
<ClInclude Include="Enemies.h" />
<ClInclude Include="Explosions.h" />
<ClInclude Include="keyHandlers.h" />
<ClInclude Include="Lasers.h" />
<ClInclude Include="Menu.h" />
<ClInclude Include="Scene.h" />
<ClInclude Include="Score.h" />
<ClInclude Include="StarField.h" />
<ClInclude Include="stb_image.h" />
<ClInclude Include="System.h" />
<ClInclude Include="Xwing.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

90
mathwars.vcxproj.filters Normal file
View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="api.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StarField.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Explosions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Lasers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Enemies.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Xwing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Score.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Scene.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Menu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="keyHandlers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stb_image.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="System.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="StarField.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Explosions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Lasers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Enemies.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Xwing.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Score.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Scene.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Menu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="keyHandlers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

6845
stb_image.h Normal file

File diff suppressed because it is too large Load Diff