diff --git a/games/repair/LICENSE.txt b/games/repair/LICENSE.txt new file mode 100644 index 000000000..d8fb27384 --- /dev/null +++ b/games/repair/LICENSE.txt @@ -0,0 +1,20 @@ + +This game sources are licensed under an unmodified zlib/libpng license, +which is an OSI-certified, BSD-like license: + +Copyright (c) 2020 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. \ No newline at end of file diff --git a/games/repair/Makefile b/games/repair/Makefile new file mode 100644 index 000000000..5e4dd9d87 --- /dev/null +++ b/games/repair/Makefile @@ -0,0 +1,406 @@ +#************************************************************************************************** +# +# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5 +# +# Copyright (c) 2013-2020 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. +# +#************************************************************************************************** + +.PHONY: all clean + +# Define required raylib variables +PROJECT_NAME ?= repair +RAYLIB_VERSION ?= 3.0.0 +RAYLIB_API_VERSION ?= 3 +RAYLIB_PATH ?= C:\GitHub\raylib + +# Define default options + +# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB +PLATFORM ?= PLATFORM_DESKTOP + +# Locations of your newly installed library and associated headers. See ../src/Makefile +# On Linux, if you have installed raylib but cannot compile the examples, check that +# the *_INSTALL_PATH values here are the same as those in src/Makefile or point to known locations. +# To enable system-wide compile-time and runtime linking to libraylib.so, run ../src/$ sudo make install RAYLIB_LIBTYPE_SHARED. +# To enable compile-time linking to a special version of libraylib.so, change these variables here. +# To enable runtime linking to a special version of libraylib.so, see EXAMPLE_RUNTIME_PATH below. +# If there is a libraylib in both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH, at runtime, +# the library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over the one at RAYLIB_INSTALL_PATH. +# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths. +DESTDIR ?= /usr/local +RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib +# RAYLIB_H_INSTALL_PATH locates the installed raylib header and associated source files. +RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include + +# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) +RAYLIB_LIBTYPE ?= STATIC + +# Build mode for project: DEBUG or RELEASE +BUILD_MODE ?= DEBUG + +# Use external GLFW library instead of rglfw module +# TODO: Review usage on Linux. Target version of choice. Switch on -lglfw or -lglfw3 +USE_EXTERNAL_GLFW ?= FALSE + +# Use Wayland display server protocol on Linux desktop +# by default it uses X11 windowing system +USE_WAYLAND_DISPLAY ?= FALSE + +# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # No uname.exe on MinGW!, but OS=Windows_NT on Windows! + # ifeq ($(UNAME),Msys) -> Windows + ifeq ($(OS),Windows_NT) + PLATFORM_OS=WINDOWS + else + UNAMEOS=$(shell uname) + ifeq ($(UNAMEOS),Linux) + PLATFORM_OS=LINUX + endif + ifeq ($(UNAMEOS),FreeBSD) + PLATFORM_OS=BSD + endif + ifeq ($(UNAMEOS),OpenBSD) + PLATFORM_OS=BSD + endif + ifeq ($(UNAMEOS),NetBSD) + PLATFORM_OS=BSD + endif + ifeq ($(UNAMEOS),DragonFly) + PLATFORM_OS=BSD + endif + ifeq ($(UNAMEOS),Darwin) + PLATFORM_OS=OSX + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + UNAMEOS=$(shell uname) + ifeq ($(UNAMEOS),Linux) + PLATFORM_OS=LINUX + endif +endif + +# RAYLIB_PATH adjustment for different platforms. +# If using GNU make, we can get the full path to the top of the tree. Windows? BSD? +# Required for ldconfig or other tools that do not perform path expansion. +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),LINUX) + RAYLIB_PREFIX ?= .. + RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX)) + endif +endif +# Default path for raylib on Raspberry Pi, if installed in different path, update it! +# This is not currently used by src/Makefile. Not sure of its origin or usage. Refer to wiki. +# TODO: update install: target in src/Makefile for RPI, consider relation to LINUX. +ifeq ($(PLATFORM),PLATFORM_RPI) + RAYLIB_PATH ?= /home/pi/raylib +endif + +ifeq ($(PLATFORM),PLATFORM_WEB) + # Emscripten required variables + EMSDK_PATH ?= C:/emsdk + EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/fastcomp/emscripten + CLANG_PATH = $(EMSDK_PATH)/fastcomp/bin + PYTHON_PATH = $(EMSDK_PATH)/python/2.7.13.1_64bit/python-2.7.13.amd64 + NODE_PATH = $(EMSDK_PATH)/node/12.9.1_64bit/bin + export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:\raylib\MinGW\bin:$$(PATH) +endif + +# Define raylib release directory for compiled library. +# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version +RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src + +# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries +# into each example binary compiled with RAYLIB_LIBTYPE=SHARED. It defaults to RAYLIB_RELEASE_PATH +# so that these examples link at runtime with your version of libraylib.so in ../release/libs/linux +# without formal installation from ../src/Makefile. It aids portability and is useful if you have +# multiple versions of raylib, have raylib installed to a non-standard location, or want to +# bundle libraylib.so with your game. Change it to your liking. +# NOTE: If, at runtime, there is a libraylib.so at both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH, +# The library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over RAYLIB_INSTALL_PATH, +# Implemented for LINUX below with CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH) +# To see the result, run readelf -d core/core_basic_window; looking at the RPATH or RUNPATH attribute. +# To see which libraries a built example is linking to, ldd core/core_basic_window; +# Look for libraylib.so.1 => $(RAYLIB_INSTALL_PATH)/libraylib.so.1 or similar listing. +EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH) + +# Define default C compiler: gcc +# NOTE: define g++ compiler if using C++ +CC = gcc + +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),OSX) + # OSX default compiler + CC = clang + endif + ifeq ($(PLATFORM_OS),BSD) + # FreeBSD, OpenBSD, NetBSD, DragonFly default compiler + CC = clang + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) + # Define RPI cross-compiler + #CC = armv6j-hardfloat-linux-gnueabi-gcc + CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc + endif +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + # HTML5 emscripten compiler + # WARNING: To compile to HTML5, code must be redesigned + # to use emscripten.h and emscripten_set_main_loop() + CC = emcc +endif + +# Define default make program: Mingw32-make +MAKE = mingw32-make + +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),LINUX) + MAKE = make + endif +endif + +# Define compiler flags: +# -O1 defines optimization level +# -g include debug information on compilation +# -s strip unnecessary data from build +# -Wall turns on most, but not all, compiler warnings +# -std=c99 defines C language mode (standard C from 1999 revision) +# -std=gnu99 defines C language mode (GNU C from 1999 revision) +# -Wno-missing-braces ignore invalid warning (GCC bug 53119) +# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec +CFLAGS += -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces + +ifeq ($(BUILD_MODE),DEBUG) + CFLAGS += -g + ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS += -s ASSERTIONS=1 --profiling + endif +else + ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS += -Os + else + CFLAGS += -s -O1 + endif +endif + +# Additional flags for compiler (if desired) +#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),WINDOWS) + # resource file contains windows executable icon and properties + # -Wl,--subsystem,windows hides the console window + CFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data + ifeq ($(BUILD_MODE), RELEASE) + CFLAGS += -Wl,--subsystem,windows + endif + endif + ifeq ($(PLATFORM_OS),LINUX) + ifeq ($(RAYLIB_LIBTYPE),STATIC) + CFLAGS += -D_DEFAULT_SOURCE + endif + ifeq ($(RAYLIB_LIBTYPE),SHARED) + # Explicitly enable runtime link to libraylib.so + CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH) + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + CFLAGS += -std=gnu99 +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + # -Os # size optimization + # -O2 # optimization level 2, if used, also set --memory-init-file 0 + # -s USE_GLFW=3 # Use glfw3 library (context/input management) + # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL! + # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) + # -s USE_PTHREADS=1 # multithreading support + # -s WASM=0 # disable Web Assembly, emitted by default + # -s EMTERPRETIFY=1 # enable emscripten code interpreter (very slow) + # -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter + # -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data + # -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off) + # --profiling # include information for code profiling + # --memory-init-file 0 # to avoid an external memory initialization code file (.mem) + # --preload-file resources # specify a resources folder for data compilation + CFLAGS += -s USE_GLFW=3 -s TOTAL_MEMORY=67108864 --preload-file resources + + # Define a custom shell .html and output extension + CFLAGS += --shell-file $(RAYLIB_PATH)/src/shell.html + EXT = .html +endif + +# Define include paths for required headers +# NOTE: Several external required libraries (stb and others) +INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external + +# Define additional directories containing required header files +ifeq ($(PLATFORM),PLATFORM_RPI) + # RPI required libraries + INCLUDE_PATHS += -I/opt/vc/include + INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux + INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads +endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),BSD) + # Consider -L$(RAYLIB_H_INSTALL_PATH) + INCLUDE_PATHS += -I/usr/local/include + endif + ifeq ($(PLATFORM_OS),LINUX) + # Reset everything. + # Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include + INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external + endif +endif + +# Define library paths containing required libs. +LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src + +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),BSD) + # Consider -L$(RAYLIB_INSTALL_PATH) + LDFLAGS += -L. -Lsrc -L/usr/local/lib + endif + ifeq ($(PLATFORM_OS),LINUX) + # Reset everything. + # Precedence: immediately local, installed version, raysan5 provided libs + LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH) + endif +endif + +ifeq ($(PLATFORM),PLATFORM_RPI) + LDFLAGS += -L/opt/vc/lib +endif + +# Define any libraries required on linking +# if you want to link libraries (libname.so or libname.a), use the -lname +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),WINDOWS) + # Libraries for Windows desktop compilation + # NOTE: WinMM library required to set high-res timer resolution + LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm + # Required for physac examples + LDLIBS += -static -lpthread + endif + ifeq ($(PLATFORM_OS),LINUX) + # Libraries for Debian GNU/Linux desktop compiling + # NOTE: Required packages: libegl1-mesa-dev + LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt + + # On X11 requires also below libraries + LDLIBS += -lX11 + # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them + #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + + # On Wayland windowing system, additional libraries requires + ifeq ($(USE_WAYLAND_DISPLAY),TRUE) + LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon + endif + # Explicit link to libc + ifeq ($(RAYLIB_LIBTYPE),SHARED) + LDLIBS += -lc + endif + endif + ifeq ($(PLATFORM_OS),OSX) + # Libraries for OSX 10.9 desktop compiling + # NOTE: Required packages: libopenal-dev libegl1-mesa-dev + LDLIBS = -lraylib -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo + endif + ifeq ($(PLATFORM_OS),BSD) + # Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling + # NOTE: Required packages: mesa-libs + LDLIBS = -lraylib -lGL -lpthread -lm + + # On XWindow requires also below libraries + LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + endif + ifeq ($(USE_EXTERNAL_GLFW),TRUE) + # NOTE: It could require additional packages installed: libglfw3-dev + LDLIBS += -lglfw + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + # Libraries for Raspberry Pi compiling + # NOTE: Required packages: libasound2-dev (ALSA) + LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + # Libraries for web (HTML5) compiling + LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc +endif + +# Define all source files required +PROJECT_SOURCE_FILES ?= \ + repair.c \ + screens/screen_logo.c \ + screens/screen_title.c \ + screens/screen_gameplay.c \ + screens/screen_ending.c + +# Define all object files from source files +OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES)) + +# For Android platform we call a custom Makefile.Android +ifeq ($(PLATFORM),PLATFORM_ANDROID) + MAKEFILE_PARAMS = -f Makefile.Android + export PROJECT_NAME + export PROJECT_SOURCE_FILES +else + MAKEFILE_PARAMS = $(PROJECT_NAME) +endif + +# Default target entry +# NOTE: We call this Makefile target or Makefile.Android target +all: + $(MAKE) $(MAKEFILE_PARAMS) + +# Project target defined by PROJECT_NAME +$(PROJECT_NAME): $(OBJS) + $(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +# Compile source files +# NOTE: This pattern will compile every module defined on $(OBJS) +%.o: %.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) + +# Clean everything +clean: +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),WINDOWS) + del *.o *.exe /s + endif + ifeq ($(PLATFORM_OS),LINUX) + find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable|x-pie-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv + endif + ifeq ($(PLATFORM_OS),OSX) + find . -type f -perm +ugo+x -delete + rm -f *.o + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + find . -type f -executable -delete + rm -fv *.o +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + del *.o *.html *.js +endif + @echo Cleaning done + diff --git a/games/repair/repair.c b/games/repair/repair.c new file mode 100644 index 000000000..f66ce6687 --- /dev/null +++ b/games/repair/repair.c @@ -0,0 +1,315 @@ +/******************************************************************************************* +* +* raylib - Advance Game template +* +* +* +* +* This game has been created using raylib (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2014-2020 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "screens/screens.h" // NOTE: Defines global variable: currentScreen + +#if defined(PLATFORM_WEB) + #include +#endif + +GameScreen currentScreen = 0; +Font font = { 0 }; +Music music = { 0 }; +Sound fxCoin = { 0 }; +Texture2D background = { 0 }; +Texture2D texNPatch = { 0 }; +NPatchInfo npInfo = { 0 }; + +Texture2D texHead, texHair, texNose, texMouth, texEyes, texComp; +Texture2D texMakeup = { 0 }; + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- +const int screenWidth = 1280; +const int screenHeight = 720; + +// Required variables to manage screen transitions (fade-in, fade-out) +static float transAlpha = 0.0f; +static bool onTransition = false; +static bool transFadeOut = false; +static int transFromScreen = -1; +static int transToScreen = -1; + +// NOTE: Some global variables that require to be visible for all screens, +// are defined in screens.h (i.e. currentScreen) + +//---------------------------------------------------------------------------------- +// Local Functions Declaration +//---------------------------------------------------------------------------------- +static void ChangeToScreen(int screen); // No transition effect + +static void TransitionToScreen(int screen); +static void UpdateTransition(void); +static void DrawTransition(void); + +static void UpdateDrawFrame(void); // Update and Draw one frame + +//---------------------------------------------------------------------------------- +// Main entry point +//---------------------------------------------------------------------------------- +int main(void) +{ + // Initialization (Note windowTitle is unused on Android) + //--------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "raylib template - advance game"); + + // Global data loading (assets that must be available in all screens, i.e. fonts) + InitAudioDevice(); + + font = LoadFont("resources/font.png"); + music = LoadMusicStream("resources/elevator_romance.ogg"); + fxCoin = LoadSound("resources/coin.wav"); + + background = LoadTexture("resources/background.png"); + + texNPatch = LoadTexture("resources/npatch.png"); + npInfo.sourceRec = (Rectangle){ 0, 0, 80, texNPatch.height }, + npInfo.left = 24; + npInfo.top = 24; + npInfo.right = 24; + npInfo.bottom = 24; + + // Load required textures + texHead = LoadTexture("resources/head_models.png"); + texHair = LoadTexture("resources/hair_models.png"); + texNose = LoadTexture("resources/nose_models.png"); + texMouth = LoadTexture("resources/mouth_models.png"); + texEyes = LoadTexture("resources/eyes_models.png"); + //texComp = LoadTexture("resources/comp_models.png"); + texMakeup = LoadTexture("resources/makeup.png"); + + SetMusicVolume(music, 0.5f); + //PlayMusicStream(music); + + // Setup and Init first screen + currentScreen = TITLE; + InitTitleScreen(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + UpdateDrawFrame(); + } +#endif + + // De-Initialization + //-------------------------------------------------------------------------------------- + + // Unload current screen data before closing + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + // Unload all global loaded data (i.e. fonts) here! + UnloadFont(font); + UnloadMusicStream(music); + UnloadSound(fxCoin); + UnloadTexture(background); + UnloadTexture(texNPatch); + + CloseAudioDevice(); // Close audio context + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Change to next screen, no transition +static void ChangeToScreen(int screen) +{ + // Unload current screen + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + // Init next screen + switch (screen) + { + case LOGO: InitLogoScreen(); break; + case TITLE: InitTitleScreen(); break; + case GAMEPLAY: InitGameplayScreen(); break; + case ENDING: InitEndingScreen(); break; + default: break; + } + + currentScreen = screen; +} + +// Define transition to next screen +static void TransitionToScreen(int screen) +{ + onTransition = true; + transFadeOut = false; + transFromScreen = currentScreen; + transToScreen = screen; + transAlpha = 0.0f; +} + +// Update transition effect +static void UpdateTransition(void) +{ + if (!transFadeOut) + { + transAlpha += 0.02f; + + // NOTE: Due to float internal representation, condition jumps on 1.0f instead of 1.05f + // For that reason we compare against 1.01f, to avoid last frame loading stop + if (transAlpha > 1.01f) + { + transAlpha = 1.0f; + + // Unload current screen + switch (transFromScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + // Load next screen + switch (transToScreen) + { + case LOGO: InitLogoScreen(); break; + case TITLE: InitTitleScreen(); break; + case GAMEPLAY: InitGameplayScreen(); break; + case ENDING: InitEndingScreen(); break; + default: break; + } + + currentScreen = transToScreen; + + // Activate fade out effect to next loaded screen + transFadeOut = true; + } + } + else // Transition fade out logic + { + transAlpha -= 0.02f; + + if (transAlpha < -0.01f) + { + transAlpha = 0.0f; + transFadeOut = false; + onTransition = false; + transFromScreen = -1; + transToScreen = -1; + } + } +} + +// Draw transition effect (full-screen rectangle) +static void DrawTransition(void) +{ + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, transAlpha)); +} + +// Update and draw game frame +static void UpdateDrawFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + UpdateMusicStream(music); // NOTE: Music keeps playing between screens + + if (!onTransition) + { + switch(currentScreen) + { + case LOGO: + { + UpdateLogoScreen(); + + if (FinishLogoScreen()) + { + TransitionToScreen(TITLE); + PlayMusicStream(music); + } + + } break; + case TITLE: + { + UpdateTitleScreen(); + + if (FinishTitleScreen() == 1) TransitionToScreen(GAMEPLAY); + //else if (FinishTitleScreen() == 2) TransitionToScreen(GAMEPLAY); + + } break; + case GAMEPLAY: + { + UpdateGameplayScreen(); + + if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING); + //else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE); + + } break; + case ENDING: + { + UpdateEndingScreen(); + + if (FinishEndingScreen() == 1) TransitionToScreen(TITLE); + + } break; + default: break; + } + } + else UpdateTransition(); // Update transition (fade-in, fade-out) + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + switch(currentScreen) + { + case LOGO: DrawLogoScreen(); break; + case TITLE: DrawTitleScreen(); break; + case GAMEPLAY: DrawGameplayScreen(); break; + case ENDING: DrawEndingScreen(); break; + default: break; + } + + // Draw full screen rectangle in front of everything + if (onTransition) DrawTransition(); + + //DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} diff --git a/games/repair/resources/background.png b/games/repair/resources/background.png new file mode 100644 index 000000000..ecd8969fe Binary files /dev/null and b/games/repair/resources/background.png differ diff --git a/games/repair/resources/coin.wav b/games/repair/resources/coin.wav new file mode 100644 index 000000000..6684ffc6a Binary files /dev/null and b/games/repair/resources/coin.wav differ diff --git a/games/repair/resources/elevator_romance.ogg b/games/repair/resources/elevator_romance.ogg new file mode 100644 index 000000000..0bcb12480 Binary files /dev/null and b/games/repair/resources/elevator_romance.ogg differ diff --git a/games/repair/resources/eyes_models.png b/games/repair/resources/eyes_models.png new file mode 100644 index 000000000..cd0eb603e Binary files /dev/null and b/games/repair/resources/eyes_models.png differ diff --git a/games/repair/resources/font.png b/games/repair/resources/font.png new file mode 100644 index 000000000..dab375017 Binary files /dev/null and b/games/repair/resources/font.png differ diff --git a/games/repair/resources/hair_models.png b/games/repair/resources/hair_models.png new file mode 100644 index 000000000..a7c86ad0b Binary files /dev/null and b/games/repair/resources/hair_models.png differ diff --git a/games/repair/resources/head_models.png b/games/repair/resources/head_models.png new file mode 100644 index 000000000..6990db1b0 Binary files /dev/null and b/games/repair/resources/head_models.png differ diff --git a/games/repair/resources/makeup.png b/games/repair/resources/makeup.png new file mode 100644 index 000000000..0b8f60692 Binary files /dev/null and b/games/repair/resources/makeup.png differ diff --git a/games/repair/resources/mouth_models.png b/games/repair/resources/mouth_models.png new file mode 100644 index 000000000..88a165a03 Binary files /dev/null and b/games/repair/resources/mouth_models.png differ diff --git a/games/repair/resources/nose_models.png b/games/repair/resources/nose_models.png new file mode 100644 index 000000000..7f4782d38 Binary files /dev/null and b/games/repair/resources/nose_models.png differ diff --git a/games/repair/resources/npatch.png b/games/repair/resources/npatch.png new file mode 100644 index 000000000..824083ab3 Binary files /dev/null and b/games/repair/resources/npatch.png differ diff --git a/games/repair/resources/raylib_logo.png b/games/repair/resources/raylib_logo.png new file mode 100644 index 000000000..665456277 Binary files /dev/null and b/games/repair/resources/raylib_logo.png differ diff --git a/games/repair/resources/title.png b/games/repair/resources/title.png new file mode 100644 index 000000000..0d9b725a0 Binary files /dev/null and b/games/repair/resources/title.png differ diff --git a/games/repair/screens/screen_ending.c b/games/repair/screens/screen_ending.c new file mode 100644 index 000000000..c953fff8f --- /dev/null +++ b/games/repair/screens/screen_ending.c @@ -0,0 +1,81 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Ending Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014-2020 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) +//---------------------------------------------------------------------------------- + +// Ending screen global variables +static int framesCounter; +static int finishScreen; + +//---------------------------------------------------------------------------------- +// Ending Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Ending Screen Initialization logic +void InitEndingScreen(void) +{ + // TODO: Initialize ENDING screen variables here! + framesCounter = 0; + finishScreen = 0; +} + +// Ending Screen Update logic +void UpdateEndingScreen(void) +{ + // TODO: Update ENDING screen variables here! + + // Press enter or tap to return to TITLE screen + if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) + { + finishScreen = 1; + PlaySound(fxCoin); + } +} + +// Ending Screen Draw logic +void DrawEndingScreen(void) +{ + // TODO: Draw ENDING screen here! + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLUE); + DrawTextEx(font, "ENDING SCREEN", (Vector2){ 20, 10 }, font.baseSize*3, 4, DARKBLUE); + DrawText("PRESS ENTER or TAP to RETURN to TITLE SCREEN", 120, 220, 20, DARKBLUE); +} + +// Ending Screen Unload logic +void UnloadEndingScreen(void) +{ + // TODO: Unload ENDING screen variables here! +} + +// Ending Screen should finish? +int FinishEndingScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/repair/screens/screen_gameplay.c b/games/repair/screens/screen_gameplay.c new file mode 100644 index 000000000..e531aad5f --- /dev/null +++ b/games/repair/screens/screen_gameplay.c @@ -0,0 +1,274 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014-2020 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" + +static bool doHairCut = false; +static bool doHairTint = false; +static bool doEyeLiner = false; +static bool doLipStick = false; +static bool doMakeup = false; +static bool doGlasses = false; +static bool doPiercing = false; + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +const unsigned int headColors[6] = { 0xffe29bff, 0xfed5a8ff, 0xad8962ff, 0xfff1b8ff, 0xffd6c4ff, 0xd49c8dff }; +const unsigned int hairColors[10] = { 0xf5bf60ff, 0xaa754aff, 0x974e14ff, 0xf36347ff, 0x87f347ff, 0xfc48d0ff, 0x3b435dff, 0x5f5e60ff, 0xe7e7e7ff, 0xfb386bff }; + +// Gameplay screen global variables +static int framesCounter = 0; +static int finishScreen = 0; + +static Character player = { 0 }; +static Character dating = { 0 }; + +static RenderTexture target = { 0 }; + +//---------------------------------------------------------------------------------- +// Gameplay Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Gameplay Screen Initialization logic +void InitGameplayScreen(void) +{ + // Initialize GAMEPLAY screen variables + framesCounter = 0; + finishScreen = 0; + + target = LoadRenderTexture(720, 720); + SetTextureFilter(target.texture, FILTER_BILINEAR); + + // Generate player character! + player = GenerateCharacter(); + + // Generate dating character! + dating = GenerateCharacter(); + + // TODO: Generate dating character likes + // For the different types of properties we assign random like values: 0% (total-dislike) -> 100% (total-like) + + // The total match point will be the (like accumulated amount)/(num properties) + // Some of the elements add points or remove points + + // At the end we can show the like percentadge of every element +} + +// Gameplay Screen Update logic +void UpdateGameplayScreen(void) +{ + // Update GAMEPLAY screen + + // TODO: Check buttons and checkboxes to update player properties + + if (IsKeyPressed(KEY_SPACE)) player = GenerateCharacter(); + + // Press enter or tap to change to ENDING screen + if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP)) + { + finishScreen = 1; + PlaySound(fxCoin); + } +} + +// Gameplay Screen Draw logic +void DrawGameplayScreen(void) +{ + // Draw background (texture, color, vignette?) + DrawTexture(background, 0, 0, GetColor(0xf6aa60ff)); + + // TODO: Draw left menu buttons + if (GuiButton((Rectangle){ 20, 40, 300, 80 }, "HAIR CUT", doHairCut? 3 : -1)) + { + doHairCut = true; + + if (GetRandomValue(0, 100) > 20) player.hair = GetRandomValue(0, texHair.width/BASE_HAIR_WIDTH); + else + { + player.hair = -1; + + // TODO: Play problem sound! + } + } + if (GuiButton((Rectangle){ 20, 40 + 90, 300, 80 }, "HAIR TINT", doHairTint? 3 : -1)) + { + doHairTint = true; + player.colHair = hairColors[GetRandomValue(0, 9)]; + } + if (GuiButton((Rectangle){ 20, 40 + 180, 300, 80 }, "EYELINER", doEyeLiner? 3 : -1)) + { + doEyeLiner = true; + } + if (GuiButton((Rectangle){ 20, 40 + 270, 300, 80 }, "LIPSTICK", doLipStick? 3 : -1)) + { + doLipStick = true; + } + if (GuiButton((Rectangle){ 20, 40 + 360, 300, 80 }, "MAKEUP", doMakeup? 3 : -1)) + { + doMakeup = true; + player.makeup = GetRandomValue(1, 2); + } + if (GuiButton((Rectangle){ 20, 40 + 540, 300, 80 }, "GLASSES", doGlasses? 3 : -1)) + { + doGlasses = true; + } + if (GuiButton((Rectangle){ 20, 40 + 540, 300, 80 }, "PIERCING", doPiercing? 3 : -1)) + { + doPiercing = true; + } + + // Draw player + DrawCharacter(player); + + // Draw dating view + GuiButton((Rectangle){ 970, 40, 260, 60 }, "DATING...", 2); + GuiButton((Rectangle){ 970, 40 + 70, 260, 260 }, " ", 0); + BeginTextureMode(target); + DrawTextureRec(texHair, (Rectangle){ BASE_HAIR_WIDTH*dating.hair, 240, BASE_HAIR_WIDTH, texHair.height - 240 }, (Vector2){ target.texture.width/2 - BASE_HAIR_WIDTH/2, 80 + 240 }, GetColor(dating.colHair)); + DrawTextureRec(texHead, (Rectangle){ BASE_HEAD_WIDTH*dating.head, 0, BASE_HEAD_WIDTH, texHead.height }, (Vector2){ target.texture.width/2 - BASE_HEAD_WIDTH/2, 140 }, GetColor(dating.colHead)); + DrawTextureRec(texHair, (Rectangle){ BASE_HAIR_WIDTH*dating.hair, 0, BASE_HAIR_WIDTH, 240 }, (Vector2){ target.texture.width/2 - BASE_HAIR_WIDTH/2, 80 }, GetColor(dating.colHair)); + DrawTextureRec(texEyes, (Rectangle){ BASE_EYES_WIDTH*dating.eyes, 0, BASE_EYES_WIDTH, texEyes.height }, (Vector2){ target.texture.width/2 - BASE_EYES_WIDTH/2, 270 }, WHITE); + DrawTextureRec(texNose, (Rectangle){ BASE_NOSE_WIDTH*dating.nose, 0, BASE_NOSE_WIDTH, texNose.height }, (Vector2){ target.texture.width/2 - BASE_NOSE_WIDTH/2, 355 }, GetColor(dating.colHead)); + DrawTextureRec(texMouth, (Rectangle){ BASE_MOUTH_WIDTH*dating.mouth, 0, BASE_MOUTH_WIDTH, texMouth.height }, (Vector2){ target.texture.width/2 - BASE_MOUTH_WIDTH/2, 450 }, GetColor(dating.colHead)); + + if (dating.makeup) DrawTextureRec(texMakeup, (Rectangle){ 0, 0, texMakeup.width, texMakeup.height }, (Vector2){ target.texture.width/2 - texMakeup.width/2, 350 }, Fade(RED, 0.3f)); + EndTextureMode(); + + DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height }, (Rectangle){ 970, 40 + 70, 260, 260 }, (Vector2){ 0, 0 }, 0.0f, WHITE); + + // Draw left button: date! + if (GuiButton((Rectangle){ 970, 580, 260, 90 }, "GO DATE!", -1)) + { + CustomizeCharacter(&dating); + + finishScreen = 1; + PlaySound(fxCoin); + } +} + +// Gameplay Screen Unload logic +void UnloadGameplayScreen(void) +{ + // Unload GAMEPLAY screen variables + + // Unload required textures + UnloadTexture(texHead); + UnloadTexture(texHair); + UnloadTexture(texNose); + UnloadTexture(texMouth); + UnloadTexture(texEyes); + //UnloadTexture(texComp); + UnloadTexture(texMakeup); +} + +// Gameplay Screen should finish? +int FinishGameplayScreen(void) +{ + return finishScreen; +} + +Character GenerateCharacter(void) +{ + Character character = { 0 }; + + // Generate player character! + character.head = GetRandomValue(0, texHead.width/BASE_HEAD_WIDTH); + character.colHead = headColors[GetRandomValue(0, 5)]; + character.hair = GetRandomValue(0, texHair.width/BASE_HAIR_WIDTH); // Config (decrease value only) + character.colHair = hairColors[GetRandomValue(0, 9)]; // Config + character.eyes = GetRandomValue(0, texEyes.width/BASE_EYES_WIDTH); + character.nose = GetRandomValue(0, texNose.width/BASE_NOSE_WIDTH); + character.mouth = GetRandomValue(0, texMouth.width/BASE_MOUTH_WIDTH); + + // NOTE: No character customization at this point + + return character; +} + +void CustomizeCharacter(Character *character) +{ + character->eyeLine = GetRandomValue(0, 2); // Config + character->paintLips = GetRandomValue(0, 2); // Config + character->makeup = GetRandomValue(0, 2); // Config + //character->bear = GetRandomValue(0, 1); // Config: remove + //character->moustache = GetRandomValue(0, 1); // Config: remove + character->glasses = GetRandomValue(0, 3); // Config: put/remove + character->piercing = GetRandomValue(0, 3); // Config: put/remove +} + +void DrawCharacter(Character character) +{ + if (player.hair >= 0) DrawTextureRec(texHair, (Rectangle){ BASE_HAIR_WIDTH*character.hair, 240, BASE_HAIR_WIDTH, texHair.height - 240 }, (Vector2){ GetScreenWidth()/2 - BASE_HAIR_WIDTH/2, 80 + 240 }, GetColor(character.colHair)); + DrawTextureRec(texHead, (Rectangle){ BASE_HEAD_WIDTH*character.head, 0, BASE_HEAD_WIDTH, texHead.height }, (Vector2){ GetScreenWidth()/2 - BASE_HEAD_WIDTH/2, 140 }, GetColor(character.colHead)); + DrawTextureRec(texHair, (Rectangle){ BASE_HAIR_WIDTH*character.hair, 0, BASE_HAIR_WIDTH, 240 }, (Vector2){ GetScreenWidth()/2 - BASE_HAIR_WIDTH/2, 80 }, GetColor(character.colHair)); + DrawTextureRec(texEyes, (Rectangle){ BASE_EYES_WIDTH*character.eyes, 0, BASE_EYES_WIDTH, texEyes.height }, (Vector2){ GetScreenWidth()/2 - BASE_EYES_WIDTH/2, 270 }, WHITE); + DrawTextureRec(texNose, (Rectangle){ BASE_NOSE_WIDTH*character.nose, 0, BASE_NOSE_WIDTH, texNose.height }, (Vector2){ GetScreenWidth()/2 - BASE_NOSE_WIDTH/2, 355 }, GetColor(character.colHead)); + DrawTextureRec(texMouth, (Rectangle){ BASE_MOUTH_WIDTH*character.mouth, 0, BASE_MOUTH_WIDTH, texMouth.height }, (Vector2){ GetScreenWidth()/2 - BASE_MOUTH_WIDTH/2, 450 }, GetColor(character.colHead)); + + if (character.makeup) DrawTextureRec(texMakeup, (Rectangle){ 0, 0, texMakeup.width, texMakeup.height }, (Vector2){ GetScreenWidth()/2 - texMakeup.width/2, 350 }, Fade(RED, 0.3f)); +} + +// Gui Button +bool GuiButton(Rectangle bounds, const char *text, int forcedState) +{ + static const int textColor[4] = { 0xeff6ffff, 0x78e782ff, 0xb04d5fff, 0xd6d6d6ff }; + + int state = (forcedState >= 0)? forcedState : 0; // NORMAL + bool pressed = false; + Vector2 textSize = MeasureTextEx(font, text, font.baseSize, 1); + + // Update control + //-------------------------------------------------------------------- + if ((state < 3) && (forcedState < 0)) + { + Vector2 mousePoint = GetMousePosition(); + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = 2; // PRESSED + else state = 1; // FOCUSED + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + } + } + + npInfo.sourceRec.x = 80*state; + + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + //DrawRectangleRec(bounds, GREEN); + //DrawRectangleLinesEx(bounds, 4, DARKGREEN); + DrawTextureNPatch(texNPatch, npInfo, bounds, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE); + DrawTextEx(font, text, (Vector2){ bounds.x + bounds.width/2 - textSize.x/2, bounds.y + bounds.height/2 - textSize.y/2 + 4 }, font.baseSize, 1, GetColor(textColor[state])); + //------------------------------------------------------------------ + + return pressed; +} \ No newline at end of file diff --git a/games/repair/screens/screen_logo.c b/games/repair/screens/screen_logo.c new file mode 100644 index 000000000..1d8fa9783 --- /dev/null +++ b/games/repair/screens/screen_logo.c @@ -0,0 +1,211 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Logo Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014-2019 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" + +#define LOGO_RECS_SIDE 16 + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Logo screen global variables +static int framesCounter = 0; +static int finishScreen = 0; + +static int logoPositionX = 0; +static int logoPositionY = 0; + +static int lettersCount = 0; + +static int topSideRecWidth = 0; +static int leftSideRecHeight = 0; + +static int bottomSideRecWidth = 0; +static int rightSideRecHeight = 0; + +static char raylib[8] = { 0 }; // raylib text array, max 8 letters +static int state = 0; // Tracking animation states (State Machine) +static float alpha = 1.0f; // Useful for fading + +//---------------------------------------------------------------------------------- +// Logo Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Logo Screen Initialization logic +void InitLogoScreen(void) +{ + // Initialize LOGO screen variables here! + finishScreen = 0; + framesCounter = 0; + lettersCount = 0; + + logoPositionX = GetScreenWidth()/2 - 128; + logoPositionY = GetScreenHeight()/2 - 128; + + topSideRecWidth = LOGO_RECS_SIDE; + leftSideRecHeight = LOGO_RECS_SIDE; + bottomSideRecWidth = LOGO_RECS_SIDE; + rightSideRecHeight = LOGO_RECS_SIDE; + + for (int i = 0; i < 8; i++) raylib[i] = '\0'; + + state = 0; + alpha = 1.0f; +} + +// Logo Screen Update logic +void UpdateLogoScreen(void) +{ + // Update LOGO screen variables here! + if (state == 0) // State 0: Small box blinking + { + framesCounter++; + + if (framesCounter == 80) + { + state = 1; + framesCounter = 0; // Reset counter... will be used later... + } + } + else if (state == 1) // State 1: Top and left bars growing + { + topSideRecWidth += 8; + leftSideRecHeight += 8; + + if (topSideRecWidth == 256) state = 2; + } + else if (state == 2) // State 2: Bottom and right bars growing + { + bottomSideRecWidth += 8; + rightSideRecHeight += 8; + + if (bottomSideRecWidth == 256) state = 3; + } + else if (state == 3) // State 3: Letters appearing (one by one) + { + framesCounter++; + + if (framesCounter/10) // Every 12 frames, one more letter! + { + lettersCount++; + framesCounter = 0; + } + + switch (lettersCount) + { + case 1: raylib[0] = 'r'; break; + case 2: raylib[1] = 'a'; break; + case 3: raylib[2] = 'y'; break; + case 4: raylib[3] = 'l'; break; + case 5: raylib[4] = 'i'; break; + case 6: raylib[5] = 'b'; break; + default: break; + } + + // When all letters have appeared... + if (lettersCount >= 10) + { + state = 4; + framesCounter = 0; + } + } + else if (state == 4) + { + framesCounter++; + + if (framesCounter > 100) + { + alpha -= 0.02f; + + if (alpha <= 0.0f) + { + alpha = 0.0f; + finishScreen = 1; + } + } + } +} + +// Logo Screen Draw logic +void DrawLogoScreen(void) +{ + if (state == 0) + { + if ((framesCounter/10)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK); + } + else if (state == 1) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + } + else if (state == 2) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + + DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK); + } + else if (state == 3) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha)); + + DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)); + + DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); + + DrawText(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha)); + } + else if (state == 4) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha)); + + DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)); + + DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); + + DrawText(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha)); + + if (framesCounter > 20) DrawText("powered by", logoPositionX, logoPositionY - 27, 20, Fade(DARKGRAY, alpha)); + } +} + +// Logo Screen Unload logic +void UnloadLogoScreen(void) +{ + // Unload LOGO screen variables here! +} + +// Logo Screen should finish? +int FinishLogoScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/repair/screens/screen_title.c b/games/repair/screens/screen_title.c new file mode 100644 index 000000000..e4ed88b0d --- /dev/null +++ b/games/repair/screens/screen_title.c @@ -0,0 +1,127 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Title Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014-2020 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) +//---------------------------------------------------------------------------------- + +// Title screen global variables +static int framesCounter = 0; +static int finishScreen = 0; + +static Texture2D texTitle = { 0 }; + +static Character demoChar = { 0 }; + +static int titlePositionY = 0; +static int buttonPositionY = 0; + +//---------------------------------------------------------------------------------- +// Title Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Title Screen Initialization logic +void InitTitleScreen(void) +{ + framesCounter = 0; + finishScreen = 0; + + texTitle = LoadTexture("resources/title.png"); + + demoChar = GenerateCharacter(); + + titlePositionY = -600; + buttonPositionY = 1600; +} + +// Title Screen Update logic +void UpdateTitleScreen(void) +{ + framesCounter++; + + if (framesCounter > 60) + { + int partToChange = GetRandomValue(0, 4); + + if (partToChange == 0) + { + demoChar.head = GetRandomValue(0, texHead.width/BASE_HEAD_WIDTH); + demoChar.colHead = headColors[GetRandomValue(0, 5)]; + } + else if (partToChange == 1) demoChar.eyes = GetRandomValue(0, texEyes.width/BASE_EYES_WIDTH); + else if (partToChange == 2) demoChar.nose = GetRandomValue(0, texNose.width/BASE_NOSE_WIDTH); + else if (partToChange == 3) demoChar.mouth = GetRandomValue(0, texMouth.width/BASE_MOUTH_WIDTH); + else if (partToChange == 4) + { + demoChar.hair = GetRandomValue(0, texHair.width/BASE_HAIR_WIDTH); + demoChar.colHair = hairColors[GetRandomValue(0, 9)]; + } + + framesCounter = 0; + } + + titlePositionY++; + if (titlePositionY > 40) titlePositionY = 40; + + buttonPositionY--; + if (buttonPositionY < 580) buttonPositionY = 580; +} + +// Title Screen Draw logic +void DrawTitleScreen(void) +{ + DrawTexture(background, 0, 0, GetColor(0xf6aa60ff)); + + // Draw face, parts keep changing ranomly + DrawCharacter(demoChar); + + // Draw face rectangles + DrawRectangleRec((Rectangle){ GetScreenWidth()/2 - BASE_EYES_WIDTH/2, 270, BASE_EYES_WIDTH, texEyes.height }, Fade(GREEN, 0.3f)); + DrawRectangleRec((Rectangle){ GetScreenWidth()/2 - BASE_NOSE_WIDTH/2, 355, BASE_NOSE_WIDTH, texNose.height }, Fade(SKYBLUE, 0.3f)); + DrawRectangleRec((Rectangle){ GetScreenWidth()/2 - BASE_MOUTH_WIDTH/2, 450, BASE_MOUTH_WIDTH, texMouth.height }, Fade(RED, 0.3f)); + + DrawTexture(texTitle, GetScreenWidth()/2 - texTitle.width/2, titlePositionY, WHITE); + + if (GuiButton((Rectangle){ GetScreenWidth()/2 - 440/2, buttonPositionY, 440, 80 }, "START DATE!", -1)) + { + finishScreen = 1; // GAMEPLAY + PlaySound(fxCoin); + } +} + +// Title Screen Unload logic +void UnloadTitleScreen(void) +{ + UnloadTexture(texTitle); +} + +// Title Screen should finish? +int FinishTitleScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/repair/screens/screens.h b/games/repair/screens/screens.h new file mode 100644 index 000000000..872ff0cce --- /dev/null +++ b/games/repair/screens/screens.h @@ -0,0 +1,135 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Screens Functions Declarations (Init, Update, Draw, Unload) +* +* Copyright (c) 2014-2020 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 BASE_HEAD_WIDTH 400 +#define BASE_HAIR_WIDTH 500 +#define BASE_NOSE_WIDTH 80 +#define BASE_MOUTH_WIDTH 170 +#define BASE_EYES_WIDTH 240 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO = 0, TITLE, OPTIONS, GAMEPLAY, ENDING } GameScreen; + +typedef struct { + int head; + int colHead; + int eyes; + int nose; + int mouth; + int hair; // Config (decrease value only) + int colHair; // Config + int eyeLine; // Config -> 0, 1, 2 + int paintLips; // Config -> 0, 1, 2 + //Color colLips; // Config + bool makeup; // Config + bool bear; // Config: remove + bool moustache; // Config: remove + bool glasses; // Config: put/remove + bool piercing; // Config: put/remove + //bool freckles; +} Character; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern const unsigned int headColors[6]; +extern const unsigned int hairColors[10]; + +extern GameScreen currentScreen; +extern Font font; +extern Music music; +extern Sound fxCoin; +extern Texture2D background; +extern Texture2D texNPatch; +extern NPatchInfo npInfo; +extern Texture2D texHead, texHair, texNose, texMouth, texEyes, texComp; +extern Texture2D texMakeup; + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +// Gui Button +bool GuiButton(Rectangle rec, const char *text, int forcedState); + +Character GenerateCharacter(void); +void CustomizeCharacter(Character *character); +void DrawCharacter(Character character); + +//---------------------------------------------------------------------------------- +// 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); + +//---------------------------------------------------------------------------------- +// Options Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitOptionsScreen(void); +void UpdateOptionsScreen(void); +void DrawOptionsScreen(void); +void UnloadOptionsScreen(void); +int FinishOptionsScreen(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 diff --git a/src/core.c b/src/core.c index 3ac9064c1..d6b13c01c 100644 --- a/src/core.c +++ b/src/core.c @@ -1969,15 +1969,15 @@ const char *GetDirectoryPath(const char *filePath) // For security, we set starting path to current directory, // obtained path will be concated to this - dirPath[0] = '.'; - dirPath[1] = '/'; + //dirPath[0] = '.'; + //dirPath[1] = '/'; lastSlash = strprbrk(filePath, "\\/"); if (lastSlash) { // NOTE: Be careful, strncpy() is not safe, it does not care about '\0' - strncpy(dirPath + 2, filePath, strlen(filePath) - (strlen(lastSlash) - 1)); - dirPath[2 + strlen(filePath) - strlen(lastSlash)] = '\0'; // Add '\0' manually + strncpy(dirPath, filePath, strlen(filePath) - (strlen(lastSlash) - 1)); + dirPath[strlen(filePath) - strlen(lastSlash)] = '\0'; // Add '\0' manually } return dirPath;