aboutsummaryrefslogtreecommitdiff
path: root/games/transmission/screens
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2018-01-29 13:46:04 +0100
committerRay <raysan5@gmail.com>2018-01-29 13:46:04 +0100
commiteb508bf75f5bab64cccd93d0e2d54d2e5bdbf6ce (patch)
tree1f06d0dac2a59318f1a14d3a7d31c15d077755b3 /games/transmission/screens
parent1ce8c80de9f2270735ac371b655b2ca7de90d55a (diff)
downloadraylib-eb508bf75f5bab64cccd93d0e2d54d2e5bdbf6ce.tar.gz
raylib-eb508bf75f5bab64cccd93d0e2d54d2e5bdbf6ce.zip
Upload GGJ18 game: transmission mission
Game developed in the GGJ18, it has some bugs and ending screen is incomplete... I'll try to keep working a bit more on it.
Diffstat (limited to 'games/transmission/screens')
-rw-r--r--games/transmission/screens/screen_ending.c212
-rw-r--r--games/transmission/screens/screen_gameplay.c423
-rw-r--r--games/transmission/screens/screen_logo.c102
-rw-r--r--games/transmission/screens/screen_mission.c293
-rw-r--r--games/transmission/screens/screen_title.c168
-rw-r--r--games/transmission/screens/screens.h143
6 files changed, 1341 insertions, 0 deletions
diff --git a/games/transmission/screens/screen_ending.c b/games/transmission/screens/screen_ending.c
new file mode 100644
index 00000000..e1fd6156
--- /dev/null
+++ b/games/transmission/screens/screen_ending.c
@@ -0,0 +1,212 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define MAX_TITLE_CHAR 128
+#define MAX_SUBTITLE_CHAR 256
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+static char *codingWords[MAX_CODING_WORDS] = {
+ "pollo\0",
+ "conejo\0",
+ "huevo\0",
+ "nido\0",
+ "aire\0",
+ "armario\0",
+ "agujero\0",
+ "platano\0",
+ "pastel\0",
+ "mercado\0",
+ "raton\0",
+ "melon\0",
+};
+
+// Ending screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static Texture2D texNewspaper;
+static Texture2D texVignette;
+
+static Sound fxNews;
+
+static float rotation = 0.1f;
+static float scale = 0.05f;
+static int state = 0;
+
+static Mission *missions = NULL;
+
+static bool showResults = false;
+
+//----------------------------------------------------------------------------------
+// Ending Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Ending Screen Initialization logic
+void InitEndingScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ rotation = 0.1f;
+ scale = 0.05f;
+ state = 0;
+
+ texBackground = LoadTexture("resources/textures/ending_background.png");
+ texVignette = LoadTexture("resources/textures/message_vignette.png");
+
+ fxNews = LoadSound("resources/audio/fx_batman.ogg");
+
+ // TODO: Check game results!
+ missions = LoadMissions("resources/missions.txt");
+ int wordsCount = missions[currentMission].wordsCount;
+ TraceLog(LOG_WARNING, "Words count %i", wordsCount);
+
+ char title[MAX_TITLE_CHAR] = "\0";
+ //char subtitle[MAX_SUBTITLE_CHAR] = "\0";
+
+ char *ptrTitle = title;
+ int len = 0;
+
+ for (int i = 0; i < wordsCount; i++)
+ {
+ if (messageWords[i].id == missions[currentMission].sols[i])
+ {
+ len = strlen(messageWords[i].text);
+ strncpy(ptrTitle, messageWords[i].text, len);
+ ptrTitle += len;
+
+ // title[len] = ' ';
+ // len++;
+ // ptrTitle++;
+ }
+ else
+ {
+ TraceLog(LOG_WARNING, "Coding word: %s", codingWords[messageWords[i].id]);
+ len = strlen(codingWords[messageWords[i].id]);
+ TraceLog(LOG_WARNING, "Lenght: %i", len);
+ strncpy(ptrTitle, codingWords[messageWords[i].id], len);
+ ptrTitle += len;
+
+ // title[len] = ' ';
+ // len++;
+ // ptrTitle++;
+ }
+ }
+
+ ptrTitle = '\0';
+
+ //TraceLog(LOG_WARNING, "Titular: %s", title);
+
+ // Generate newspaper with title and subtitle
+ Image imNewspaper = LoadImage("resources/textures/ending_newspaper.png");
+ SpriteFont fontNews = LoadSpriteFontEx("resources/fonts/Lora-Bold.ttf", 82, 250, 0);
+ ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 220 }, fontNews, "FRACASO EN LA GGJ18!", fontNews.baseSize, 0, DARKGRAY);
+
+ // TODO: Draw subtitle message
+ //ImageDrawTextEx(&imNewspaper, (Vector2){ 50, 210 }, fontNews, "SUBE LA ESCALERA!", fontNews.baseSize, 0, DARKGRAY);
+
+ texNewspaper = LoadTextureFromImage(imNewspaper);
+ UnloadSpriteFont(fontNews);
+ UnloadImage(imNewspaper);
+}
+
+// Ending Screen Update logic
+void UpdateEndingScreen(void)
+{
+ framesCounter++;
+
+ if (framesCounter == 10) PlaySound(fxNews);
+
+ if (state == 0)
+ {
+ rotation += 18.0f;
+ scale += 0.0096f;
+
+ if (scale >= 1.0f)
+ {
+ scale = 1.0f;
+ state = 1;
+ }
+ }
+
+ if ((state == 1) && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
+ {
+ currentMission++;
+
+ if (currentMission >= totalMissions) finishScreen = 2;
+ else finishScreen = 1;
+ }
+
+ if (IsKeyPressed(KEY_SPACE)) showResults = !showResults;
+}
+
+// Ending Screen Draw logic
+void DrawEndingScreen(void)
+{
+ DrawTexture(texBackground, 0, 0, WHITE);
+
+ DrawTexturePro(texNewspaper, (Rectangle){ 0, 0, texNewspaper.width, texNewspaper.height },
+ (Rectangle){ GetScreenWidth()/2, GetScreenHeight()/2, texNewspaper.width*scale, texNewspaper.height*scale },
+ (Vector2){ (float)texNewspaper.width*scale/2, (float)texNewspaper.height*scale/2 }, rotation, WHITE);
+
+ DrawTextureEx(texVignette, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
+
+ if (showResults)
+ {
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ if (messageWords[i].id == missions[currentMission].sols[i]) DrawText(messageWords[i].text, 10, 10 + 30*i, 20, GREEN);
+ else DrawText(codingWords[messageWords[i].id], 10, 10 + 30*i, 20, RED);
+ }
+ }
+
+ if (state == 1) DrawButton("continuar");
+}
+
+// Ending Screen Unload logic
+void UnloadEndingScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadTexture(texNewspaper);
+ UnloadTexture(texVignette);
+
+ UnloadSound(fxNews);
+ free(missions);
+}
+
+// Ending Screen should finish?
+int FinishEndingScreen(void)
+{
+ return finishScreen;
+} \ No newline at end of file
diff --git a/games/transmission/screens/screen_gameplay.c b/games/transmission/screens/screen_gameplay.c
new file mode 100644
index 00000000..00c451fc
--- /dev/null
+++ b/games/transmission/screens/screen_gameplay.c
@@ -0,0 +1,423 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+//#define MAX_CODING_WORDS 12
+//#define MAX_MISSION_WORDS 8
+#define MAX_LINE_CHAR 30
+
+/*
+// NOTE: Coding words are generic and the same words
+// are used for all missions,
+typedef enum CodingWords {
+ POLLO = 0,
+ CONEJO,
+ HUEVO,
+ NIDO,
+ AIRE,
+ ARMARIO,
+ AGUJERO,
+ COSA,
+ WORD,
+} CodingWords;
+*/
+
+static char *codingWords[MAX_CODING_WORDS] = {
+ "pollo\0",
+ "conejo\0",
+ "huevo\0",
+ "nido\0",
+ "aire\0",
+ "armario\0",
+ "agujero\0",
+ "platano\0",
+ "pastel\0",
+ "mercado\0",
+ "raton\0",
+ "melon\0"
+};
+
+// Words to be coded or coding words
+/*typedef struct Word {
+ int id;
+ Rectangle rec;
+ Rectangle iniRec;
+ bool hover;
+ bool picked;
+ char text[32]; // text
+} Word;*/
+
+/*
+// Mission information
+typedef struct Mission {
+ int id;
+ char brief[512]; // Mission briefing
+ char key[32]; // Mission keyword
+ char msg[256]; // Message to be coded
+ int wordsCount; // Number of words to coded
+ int sols[8]; // Solution code, depends on wordsCount
+} Mission;
+*/
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Gameplay screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static SpriteFont fontMessage;
+static Texture2D texWordsAtlas;
+static Texture2D texVignette;
+
+static Sound fxGrab;
+static Sound fxPlace;
+static Sound fxLeave;
+
+static Music musSpy;
+
+static Word words[MAX_CODING_WORDS] = { 0 };
+
+// Hay que hacerlo global, para poder consultar el resultado desde la endingscreen
+//static Word messageWords[MAX_MISSION_WORDS] = { 0 };
+
+static Mission *missions = NULL;
+
+static bool canSend = false;
+
+Vector2 msgOffset = { 430, 300 };
+
+//----------------------------------------------------------------------------------
+// Gameplay Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Gameplay Screen Initialization logic
+void InitGameplayScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ fontMessage = LoadSpriteFontEx("resources/fonts/traveling_typewriter.ttf", 30, 250, 0);
+
+ texBackground = LoadTexture("resources/textures/message_background.png");
+ texVignette = LoadTexture("resources/textures/message_vignette.png");
+
+ fxGrab = LoadSound("resources/audio/fx_grab.ogg");
+ fxPlace = LoadSound("resources/audio/fx_place.ogg");
+ fxLeave = LoadSound("resources/audio/fx_leave.ogg");
+
+ musSpy = LoadMusicStream("resources/audio/s_p_y.xm");
+ PlayMusicStream(musSpy);
+
+#if defined(PLATFORM_WEB)
+ #define WORD_ATLAS_FROM_FILE
+#endif
+#if defined(WORD_ATLAS_FROM_FILE)
+ texWordsAtlas = LoadTexture("resources/textures/mission_words.png");
+#else
+ // Generate coding words atlas directly from text
+ Image imWordsBase = LoadImage("resources/textures/words_base.png");
+ Image imWords = GenImageColor(imWordsBase.width, imWordsBase.height*MAX_CODING_WORDS, WHITE);
+
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ ImageDraw(&imWords, imWordsBase,
+ (Rectangle){ 0, 0, imWordsBase.width, imWordsBase.height },
+ (Rectangle){ 0, imWordsBase.height*i, imWordsBase.width, imWordsBase.height });
+
+ ImageDrawTextEx(&imWords,(Vector2){ imWordsBase.width/2 - MeasureTextEx(fontMessage, codingWords[i],
+ fontMessage.baseSize, 0).x/2, imWordsBase.height*i }, fontMessage, codingWords[i],
+ fontMessage.baseSize, 0, BLACK);
+ }
+
+ texWordsAtlas = LoadTextureFromImage(imWords);
+
+ UnloadImage(imWordsBase);
+ UnloadImage(imWords);
+#endif
+
+ // Initialize missions
+ // WARNING: Some problem with imWords image generation (memory leak?) could cause
+ // that loading missions before/after generation breaks game, on web is the other way round... :(
+ missions = LoadMissions("resources/missions.txt");
+ TraceLog(LOG_WARNING, "Words count %i", missions[currentMission].wordsCount);
+
+ // Initialize coding words
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ words[i].id = -1; // Not placed anywhere
+
+ words[i].rec.x = 110 + 940*(i/(MAX_CODING_WORDS/2));
+ words[i].rec.y = 200 + 60*(i%(MAX_CODING_WORDS/2));
+ words[i].rec.width = 140; // texWordsAtlas.width/MAX_MISSIONS
+ words[i].rec.height = 35; // texWordsAtlas.height/MAX_MISSION_WORDS
+ words[i].iniRec = words[i].rec;
+ words[i].hover = false; // Mouse hover detected
+ words[i].picked = false; // Mouse picked
+
+ //words[i].text = ''; //codingWords[i]; // Fill text if required...
+ }
+
+ // Analize missions[currentMission].msg string for words!
+ int msgLen = strlen(missions[currentMission].msg);
+
+ // Add '/' each MAX_LINE_CHAR chars
+ int currentLine = 1;
+ int i = currentLine * MAX_LINE_CHAR;
+
+ while (i < msgLen - 1)
+ {
+ if (missions[currentMission].msg[i] == ' ')
+ {
+ missions[currentMission].msg[i] = '/';
+ currentLine++;
+ i = currentLine*MAX_LINE_CHAR;
+ }
+ else i++;
+ }
+
+ int currentWord = 0;
+ int offsetX = 0;
+ int offsetY = 0;
+ bool foundWord = false;
+ int wordInitPosX = 0;
+ int wordInitPosY = 0;
+
+ // TODO: messageWords should be reseted every mission
+ //memcpy(messageWords, 0, sizeof(Word)*MAX_MISSION_WORDS);
+
+ for (int i = 0; i < msgLen; i++)
+ {
+ char c = missions[currentMission].msg[i];
+ if (foundWord && (c == ' ' || c == '.'))
+ {
+ foundWord = false;
+
+ messageWords[currentWord - 1].rec.width = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), 30, 0).x;
+ messageWords[currentWord - 1].rec.height = fontMessage.baseSize;
+
+ //TODO: Guardar en message
+ strncpy(messageWords[currentWord - 1].text, SubText(missions[currentMission].msg, wordInitPosX, (i - wordInitPosX)), i - wordInitPosX);
+ }
+
+ if (c == '@') // One word to change
+ {
+ foundWord = true;
+ missions[currentMission].msg[i] = ' ';
+
+ offsetX = (int)MeasureTextEx(fontMessage, SubText(missions[currentMission].msg, wordInitPosY, (i + 1) - wordInitPosY), 30, 0).x;
+
+ messageWords[currentWord].rec.x = offsetX;
+ messageWords[currentWord].rec.y = offsetY;
+
+ wordInitPosX = i + 1;
+
+ currentWord++;
+ }
+ else if (c == '/')
+ {
+ missions[currentMission].msg[i] = '\n';
+ wordInitPosY = i;
+ offsetY += (fontMessage.baseSize + fontMessage.baseSize/2); // raylib internal increment on line break...
+ }
+ }
+
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ messageWords[i].id = -1; // Not required for message words, id is the array position
+
+ // Recalculate words rectangles considering text offset on screen
+ messageWords[i].rec.x += msgOffset.x;
+ messageWords[i].rec.y += msgOffset.y;
+
+ // Recalculate words rectangle considering new width height
+ messageWords[i].rec.x -= (texWordsAtlas.width - messageWords[i].rec.width)/2;
+ messageWords[i].rec.y -= ((texWordsAtlas.height / MAX_CODING_WORDS) - messageWords[i].rec.height)/2;
+
+ //Recalculate width height
+ messageWords[i].rec.width = texWordsAtlas.width;
+ messageWords[i].rec.height = texWordsAtlas.height / MAX_CODING_WORDS;
+
+ messageWords[i].hover = false; // Mouse hover detected
+ messageWords[i].picked = false; // Mouse picked
+ }
+}
+
+// Gameplay Screen Update logic
+void UpdateGameplayScreen(void)
+{
+ UpdateMusicStream(musSpy);
+
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ if (CheckCollisionPointRec(GetMousePosition(), words[i].rec))
+ {
+ words[i].hover = true;
+
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ words[i].picked = true;
+ PlaySound(fxGrab);
+ }
+ }
+ else words[i].hover = false;
+
+
+ if (words[i].picked)
+ {
+ for (int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec)) messageWords[j].hover = true;
+ else messageWords[j].hover = false;
+ }
+
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ words[i].picked = false;
+
+ for (int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ messageWords[j].hover = false;
+
+ if (CheckCollisionPointRec(GetMousePosition(), messageWords[j].rec))
+ {
+ PlaySound(fxPlace);
+
+ words[i].rec.x = messageWords[j].rec.x;
+ words[i].rec.y = messageWords[j].rec.y;
+
+ if (messageWords[j].id != -1)
+ {
+ int id = messageWords[j].id;
+ words[id].rec = words[id].iniRec;
+ }
+
+ messageWords[j].id = i;
+ for (int k = 0; k < missions[currentMission].wordsCount; k++)
+ {
+ if (j != k && messageWords[j].id == messageWords[k].id)
+ {
+ messageWords[k].id = -1;
+ break;
+ }
+ }
+ break;
+ }
+ else
+ {
+ PlaySound(fxLeave);
+
+ words[i].rec = words[i].iniRec;
+ if (i == messageWords[j].id) messageWords[j].id = -1;
+ }
+ }
+ }
+ }
+
+ // TODO: Move word picked with mouse
+ if (words[i].picked)
+ {
+ words[i].rec.x = GetMouseX() - words[i].rec.width/2;
+ words[i].rec.y = GetMouseY() - words[i].rec.height/2;
+
+ // TODO: Check if label is placed in some mission word position
+ //if (CheckCollisionRecs(words[i].rec))
+ }
+ else
+ {
+ //if (words[i].id != -1)
+ }
+ }
+
+ canSend = true;
+ for(int j = 0; j < missions[currentMission].wordsCount; j++)
+ {
+ if(messageWords[j].id == -1)
+ {
+ canSend = false;
+ break;
+ }
+ }
+
+ if (canSend && (IsKeyPressed(KEY_ENTER) || IsButtonPressed()))
+ {
+ finishScreen = true;
+ }
+}
+
+// Gameplay Screen Draw logic
+void DrawGameplayScreen(void)
+{
+ DrawTexture(texBackground, 0, 0, WHITE);
+
+ DrawTextEx(fontMessage, missions[currentMission].msg, msgOffset, fontMessage.baseSize, 0, BLACK);
+
+ for (int i = 0; i < missions[currentMission].wordsCount; i++)
+ {
+ Rectangle recLines = messageWords[i].rec;
+ DrawRectangleLines(recLines.x, recLines.y, recLines.width, recLines.height, Fade(RED, 0.35f));
+ if(messageWords[i].hover) DrawRectangleRec(messageWords[i].rec, Fade(RED, 0.30f));
+ DrawText(FormatText("%i", messageWords[i].id), i*25, 0, 30, RED);
+ }
+ for (int i = 0; i < MAX_CODING_WORDS; i++)
+ {
+ if (words[i].picked) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, MAROON);
+ else if (words[i].hover) DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, RED);
+ else DrawTextureRec(texWordsAtlas, (Rectangle){ 0, i*35, 140, 35 }, (Vector2){ words[i].rec.x, words[i].rec.y }, WHITE);
+ }
+
+ DrawTexturePro(texVignette, (Rectangle){0,0,texVignette.width, texVignette.height}, (Rectangle){0,0,GetScreenWidth(), GetScreenHeight()}, (Vector2){0,0}, 0, WHITE);
+
+ if (canSend) DrawButton("enviar");
+}
+
+// Gameplay Screen Unload logic
+void UnloadGameplayScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadTexture(texVignette);
+ UnloadTexture(texWordsAtlas);
+
+ UnloadSound(fxGrab);
+ UnloadSound(fxLeave);
+ UnloadSound(fxPlace);
+
+ UnloadMusicStream(musSpy);
+
+ free(missions);
+}
+
+// Gameplay Screen should finish?
+int FinishGameplayScreen(void)
+{
+ return finishScreen;
+}
diff --git a/games/transmission/screens/screen_logo.c b/games/transmission/screens/screen_logo.c
new file mode 100644
index 00000000..30271ba6
--- /dev/null
+++ b/games/transmission/screens/screen_logo.c
@@ -0,0 +1,102 @@
+/**********************************************************************************************
+*
+* raylib - Advance Game template
+*
+* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Logo screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D logoCW;
+
+static float fadeValue;
+static int showLogoFrames;
+static bool fadeOut;
+
+//----------------------------------------------------------------------------------
+// Logo Screen Functions Definition
+//----------------------------------------------------------------------------------
+
+// Logo Screen Initialization logic
+void InitLogoScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ logoCW = LoadTexture("resources/textures/cw_logo.png");
+
+ showLogoFrames = 60;
+ fadeValue = 0;
+
+ fadeOut = false;
+}
+
+// Logo Screen Update logic
+void UpdateLogoScreen(void)
+{
+ if(!fadeOut)
+ {
+ fadeValue += 0.02f;
+ if(fadeValue > 1.01f)
+ {
+ fadeValue = 1.0f;
+ framesCounter++;
+
+ if(framesCounter % showLogoFrames == 0)
+ {
+ fadeOut = true;
+ finishScreen = true;
+ }
+ }
+ }
+
+ if(IsKeyPressed(KEY_ENTER))
+ {
+ finishScreen = true;
+ }
+}
+
+// Logo Screen Draw logic
+void DrawLogoScreen(void)
+{
+ DrawTexture(logoCW, GetScreenWidth()/2 - logoCW.width/2, GetScreenHeight()/2 - logoCW.height/2, Fade(WHITE, fadeValue));
+}
+
+// Logo Screen Unload logic
+void UnloadLogoScreen(void)
+{
+ UnloadTexture(logoCW);
+}
+
+// Logo Screen should finish?
+int FinishLogoScreen(void)
+{
+ return finishScreen;
+} \ No newline at end of file
diff --git a/games/transmission/screens/screen_mission.c b/games/transmission/screens/screen_mission.c
new file mode 100644
index 00000000..0f996502
--- /dev/null
+++ b/games/transmission/screens/screen_mission.c
@@ -0,0 +1,293 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define MISSION_MAX_LENGTH 256
+#define KEYWORD_MAX_LENGTH 32
+#define MAX_LINE_CHAR 75
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Mission screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+
+static Texture2D texBackline; //mission_backline
+static Rectangle sourceRecBackLine;
+static Rectangle destRecBackLine;
+static float fadeBackLine;
+
+static Vector2 numberPosition;
+static Color numberColor;
+
+//static char textMission[MISSION_MAX_LENGTH];
+static Vector2 missionPosition;
+static int missionSize;
+static Color missionColor;
+static int missionLenght;
+static bool missionMaxLength;
+static int missionSpeed;
+
+//static char textKeyword[KEYWORD_MAX_LENGTH];
+static Vector2 keywordPosition;
+static Color keywordColor;
+
+static int showMissionWaitFrames;
+static int showNumberWaitFrames;
+static int showKeywordWaitFrames;
+
+static bool startWritting;
+static bool writeMission;
+static bool writeNumber;
+static bool writeKeyword;
+static bool writeEnd;
+
+static bool writtingMission;
+
+static int blinkFrames;
+static bool blinkKeyWord = true;
+
+static bool showButton = false;
+
+static Mission *missions = NULL;
+
+static Sound fxTransmit;
+static Music musMission;
+
+//----------------------------------------------------------------------------------
+// Mission Screen Functions Definition
+//----------------------------------------------------------------------------------
+static void WriteMissionText();
+static void EndWritting();
+static void BlinkKeyword();
+
+// Mission Screen Initialization logic
+void InitMissionScreen(void)
+{
+ framesCounter = 0;
+ finishScreen = 0;
+
+ fadeButton = 0.80f;
+
+ texBackground = LoadTexture("resources/textures/mission_background.png");
+
+ texBackline = LoadTexture("resources/textures/mission_backline.png");
+ sourceRecBackLine = (Rectangle){0,0,GetScreenWidth(), texBackline.height};
+ destRecBackLine = (Rectangle){0,0,sourceRecBackLine.width, sourceRecBackLine.height};
+ fadeBackLine = 0;
+
+ fxTransmit = LoadSound("resources/audio/fx_message.ogg");
+ musMission = LoadMusicStream("resources/audio/music_mission.ogg");
+
+ PlayMusicStream(musMission);
+
+ // Initialize missions
+ missions = LoadMissions("resources/missions.txt");
+
+ missionMaxLength = strlen(missions[currentMission].brief);
+
+ // Insert line breaks every MAX_LINE_CHAR
+ int currentLine = 1;
+ int i = currentLine * MAX_LINE_CHAR;
+
+ while (i < missionMaxLength)
+ {
+ if (missions[currentMission].brief[i] == ' ')
+ {
+ missions[currentMission].brief[i] = '\n';
+ currentLine++;
+ i = currentLine*MAX_LINE_CHAR;
+ }
+ else i++;
+ }
+
+ missionSize = 30;
+ missionLenght = 0;
+ missionSpeed = 1;
+
+ numberColor = RAYWHITE;
+ missionColor = LIGHTGRAY;
+ keywordColor = (Color){198, 49, 60, 255}; //RED
+
+ numberPosition = (Vector2){150, 185};
+ missionPosition = (Vector2){numberPosition.x, numberPosition.y + 60};
+ keywordPosition = (Vector2){missionPosition.x, missionPosition.y + MeasureTextEx(fontMission, missions[currentMission].brief, missionSize, 0).y + 60};
+
+ startWritting = false;
+ writeNumber = false;
+ writeMission = false;
+ writeKeyword = false;
+ writeEnd = false;
+
+ writtingMission = false;
+
+ showNumberWaitFrames = 30;
+ showMissionWaitFrames = 60;
+ showKeywordWaitFrames = 60;
+
+ blinkKeyWord = true;
+ blinkFrames = 15;
+
+ PlaySound(fxTransmit);
+}
+
+// Mission Screen Update logic
+void UpdateMissionScreen(void)
+{
+ UpdateMusicStream(musMission);
+
+ if (!writeEnd) WriteMissionText();
+ else BlinkKeyword();
+
+ if (showButton)
+ {
+ if (IsKeyPressed(KEY_ENTER) || IsButtonPressed())
+ {
+ if (!writeEnd) EndWritting();
+ else
+ {
+ finishScreen = true;
+ showButton = false;
+ }
+ }
+ }
+}
+
+// Mission Screen Draw logic
+void DrawMissionScreen(void)
+{
+ // TODO: Draw MISSION screen here!
+ DrawTexture(texBackground, 0,0, WHITE);
+ DrawTexturePro(texBackline, sourceRecBackLine, destRecBackLine, (Vector2){0,0},0, Fade(WHITE, fadeBackLine));
+
+ if (writeNumber) DrawTextEx(fontMission, FormatText("Filtración #%02i ", currentMission + 1), numberPosition, missionSize + 10, 0, numberColor);
+ DrawTextEx(fontMission, SubText(missions[currentMission].brief, 0, missionLenght), missionPosition, missionSize, 0, missionColor);
+ if (writeKeyword && blinkKeyWord) DrawTextEx(fontMission, FormatText("Keyword: %s", missions[currentMission].key), keywordPosition, missionSize + 10, 0, keywordColor);
+
+ if (showButton)
+ {
+ if (!writeEnd) DrawButton("saltar");
+ else DrawButton("codificar");
+ }
+}
+
+// Mission Screen Unload logic
+void UnloadMissionScreen(void)
+{
+ // TODO: Unload MISSION screen variables here!
+ UnloadTexture(texBackground);
+ UnloadTexture(texBackline);
+ UnloadSound(fxTransmit);
+ UnloadMusicStream(musMission);
+ free(missions);
+}
+
+// Mission Screen should finish?
+int FinishMissionScreen(void)
+{
+ return finishScreen;
+}
+
+static void WriteMissionText()
+{
+ if(!startWritting)
+ {
+ framesCounter++;
+ if(framesCounter % 60 == 0)
+ {
+ framesCounter = 0;
+ startWritting = true;
+ }
+ }
+ else if(!writeNumber)
+ {
+ framesCounter++;
+ fadeBackLine += 0.020f;
+ if(framesCounter % showNumberWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeNumber = true;
+ showButton = true;
+ }
+ }
+ else if(!writeMission)
+ {
+ framesCounter ++;
+ if(framesCounter % showMissionWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeMission = true;
+ writtingMission = true;
+ }
+ }
+ else if(writeMission && writtingMission)
+ {
+ framesCounter++;
+ if(framesCounter % missionSpeed == 0)
+ {
+ framesCounter = 0;
+ missionLenght++;
+
+ if(missionLenght == missionMaxLength)
+ {
+ writtingMission = false;
+ }
+ }
+ }
+ else if(!writeKeyword)
+ {
+ framesCounter++;
+ if(framesCounter % showKeywordWaitFrames == 0)
+ {
+ framesCounter = 0;
+ writeKeyword = true;
+ writeEnd = true;
+ }
+ }
+}
+static void EndWritting()
+{
+ writeEnd = true;
+ writeKeyword = true;
+ writeNumber = true;
+ missionLenght = missionMaxLength;
+}
+static void BlinkKeyword()
+{
+ framesCounter++;
+ if(framesCounter % blinkFrames == 0)
+ {
+ framesCounter = 0;
+ blinkKeyWord = !blinkKeyWord;
+ }
+}
diff --git a/games/transmission/screens/screen_title.c b/games/transmission/screens/screen_title.c
new file mode 100644
index 00000000..dc062069
--- /dev/null
+++ b/games/transmission/screens/screen_title.c
@@ -0,0 +1,168 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#include "raylib.h"
+#include "screens.h"
+
+#include <string.h>
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition (local to this module)
+//----------------------------------------------------------------------------------
+
+// Title screen global variables
+static int framesCounter;
+static int finishScreen;
+
+static Texture2D texBackground;
+static SpriteFont fontTitle;
+static Sound fxTyping;
+
+static float titleSize;
+static Vector2 transmissionPosition;
+static Vector2 missionPositon;
+
+static const char textTitle[20] = "transmissionmission";
+
+static Color titleColor;
+static int speedText;
+
+static int transmissionLenght;
+static int missionLenght;
+static int transmissionMaxLenght;
+static int missionMaxLenght;
+
+static bool writeTransmission;
+static bool writeMission;
+static bool writeEnd;
+
+//----------------------------------------------------------------------------------
+// Title Screen Functions Definition
+//----------------------------------------------------------------------------------
+static void MissionScreen();
+
+// Title Screen Initialization logic
+void InitTitleScreen(void)
+{
+ // TODO: Initialize TITLE screen variables here!
+ framesCounter = 0;
+ finishScreen = 0;
+
+ texBackground = LoadTexture("resources/textures/title_background.png");
+ fxTyping = LoadSound("resources/audio/fx_typing.ogg");
+ fontTitle = LoadSpriteFontEx("resources/fonts/fontTitle.ttf", 96, 0, 0);
+
+ titleSize = 44;
+ transmissionPosition = (Vector2){519, 221};
+ missionPositon = (Vector2){580, 261};
+
+ titleColor = BLACK;
+ speedText = 15;
+
+ missionLenght = 0;
+ transmissionLenght = 0;
+
+ missionMaxLenght = 7;
+ transmissionMaxLenght = 12;
+
+ writeTransmission = true;
+ writeMission = false;
+ writeEnd = false;
+
+ currentMission = 0;
+}
+
+// Title Screen Update logic
+void UpdateTitleScreen(void)
+{
+ if (!writeEnd)
+ {
+ framesCounter ++;
+
+ if (framesCounter%speedText == 0)
+ {
+ framesCounter = 0;
+ if (writeTransmission)
+ {
+ transmissionLenght++;
+ if (transmissionLenght == transmissionMaxLenght)
+ {
+ writeTransmission = false;
+ writeMission = true;
+ }
+ }
+ else if (writeMission)
+ {
+ missionLenght++;
+ if (missionLenght == missionMaxLenght)
+ {
+ writeMission = false;
+ writeEnd = true;
+ }
+ }
+
+ PlaySound(fxTyping);
+ }
+ }
+
+ if(IsButtonPressed())
+ {
+ MissionScreen();
+ }
+ else if (IsKeyPressed(KEY_ENTER)) MissionScreen();
+}
+
+// Title Screen Draw logic
+void DrawTitleScreen(void)
+{
+ DrawTexture(texBackground, 0,0, WHITE);
+ DrawTextEx(fontTitle, SubText(textTitle, 0, transmissionLenght), transmissionPosition, titleSize, 0, titleColor);
+ DrawTextEx(fontTitle, SubText(textTitle, 12, missionLenght), missionPositon, titleSize, 0, titleColor);
+
+ DrawButton("start");
+}
+
+// Title Screen Unload logic
+void UnloadTitleScreen(void)
+{
+ UnloadTexture(texBackground);
+ UnloadSound(fxTyping);
+ UnloadSpriteFont(fontTitle);
+}
+
+// Title Screen should finish?
+int FinishTitleScreen(void)
+{
+ return finishScreen;
+}
+
+static void MissionScreen()
+{
+ transmissionLenght = transmissionMaxLenght;
+ missionLenght = missionMaxLenght;
+ writeEnd = true;
+ //finishScreen = 1; // OPTIONS
+ finishScreen = true; // GAMEPLAY
+ //PlaySound(fxCoin);
+} \ No newline at end of file
diff --git a/games/transmission/screens/screens.h b/games/transmission/screens/screens.h
new file mode 100644
index 00000000..27560d8b
--- /dev/null
+++ b/games/transmission/screens/screens.h
@@ -0,0 +1,143 @@
+/**********************************************************************************************
+*
+* raylib - transmission mission
+*
+* Screens Functions Declarations (Init, Update, Draw, Unload)
+*
+* Copyright (c) 2014-2018 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#ifndef SCREENS_H
+#define SCREENS_H
+
+#define MAX_CODING_WORDS 12
+#define MAX_MISSION_WORDS 8
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef enum GameScreen { LOGO = 0, TITLE, MISSION, GAMEPLAY, ENDING } GameScreen;
+
+// Words to be coded or coding words
+typedef struct Word {
+ int id;
+ Rectangle rec;
+ Rectangle iniRec;
+ bool hover;
+ bool picked;
+ char text[32]; // text
+} Word;
+
+// Mission information
+typedef struct Mission {
+ int id;
+ char brief[512]; // Mission briefing
+ char key[32]; // Mission keyword
+ char msg[256]; // Message to be coded
+ int wordsCount; // Number of words to coded
+ int sols[10]; // Solution code, depends on wordsCount
+} Mission;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+GameScreen currentScreen;
+
+Music music;
+Sound fxButton;
+
+//Mission *missions;
+
+// UI BUTTON
+Rectangle recButton;
+float fadeButton;
+Color colorButton;
+Texture2D texButton;
+Vector2 textPositionButton;
+int fontSizeButton;
+Color textColorButton;
+
+int currentMission;
+int totalMissions;
+
+SpriteFont fontMission;
+
+Word messageWords[MAX_MISSION_WORDS];
+
+#ifdef __cplusplus
+extern "C" { // Prevents name mangling of functions
+#endif
+
+//----------------------------------------------------------------------------------
+// Transmission Functions Declaration
+//----------------------------------------------------------------------------------
+bool IsButtonPressed();
+void DrawButton(const char *text);
+Mission *LoadMissions(const char *fileName);
+
+//----------------------------------------------------------------------------------
+// Logo Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitLogoScreen(void);
+void UpdateLogoScreen(void);
+void DrawLogoScreen(void);
+void UnloadLogoScreen(void);
+int FinishLogoScreen(void);
+
+//----------------------------------------------------------------------------------
+// Title Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitTitleScreen(void);
+void UpdateTitleScreen(void);
+void DrawTitleScreen(void);
+void UnloadTitleScreen(void);
+int FinishTitleScreen(void);
+
+//----------------------------------------------------------------------------------
+// Mission Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitMissionScreen(void);
+void UpdateMissionScreen(void);
+void DrawMissionScreen(void);
+void UnloadMissionScreen(void);
+int FinishMissionScreen(void);
+
+//----------------------------------------------------------------------------------
+// Gameplay Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitGameplayScreen(void);
+void UpdateGameplayScreen(void);
+void DrawGameplayScreen(void);
+void UnloadGameplayScreen(void);
+int FinishGameplayScreen(void);
+
+//----------------------------------------------------------------------------------
+// Ending Screen Functions Declaration
+//----------------------------------------------------------------------------------
+void InitEndingScreen(void);
+void UpdateEndingScreen(void);
+void DrawEndingScreen(void);
+void UnloadEndingScreen(void);
+int FinishEndingScreen(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SCREENS_H \ No newline at end of file