├── samples ├── CMakeLists.txt ├── callout │ ├── res │ │ ├── bg.png │ │ ├── callout.png │ │ └── cofont.png │ └── Makefile ├── image │ ├── res │ │ └── cage.png │ ├── Makefile │ └── src │ │ └── image.c ├── state │ ├── res │ │ └── font.png │ ├── Makefile │ └── src │ │ └── state.c ├── tiled │ ├── raw │ │ ├── sprite.psd │ │ ├── sprite.xcf │ │ ├── _sprite.gif │ │ └── README.md │ ├── res │ │ ├── sprite.png │ │ ├── overlay.png │ │ ├── shadowmap.png │ │ ├── tileset.png │ │ └── spritemask.png │ ├── Makefile │ └── src │ │ └── tiled_actor.h ├── wizard │ ├── res │ │ ├── font.png │ │ ├── mask.png │ │ ├── spot.png │ │ ├── title.png │ │ ├── tree.png │ │ ├── wizard.ogg │ │ ├── wizard.png │ │ ├── earth_tile.png │ │ ├── grass_tile.png │ │ └── game.conf │ ├── CMakeLists.txt │ └── Makefile ├── collisions │ ├── res │ │ └── star.png │ ├── Makefile │ └── src │ │ └── collisions.c ├── sprite │ ├── res │ │ └── wizard.png │ ├── Makefile │ └── src │ │ └── sprite.c ├── timeline │ ├── res │ │ ├── cage.png │ │ └── font.png │ ├── Makefile │ └── src │ │ └── timeline.c ├── chipmunk │ ├── res │ │ ├── particle.png │ │ └── game.conf │ └── Makefile └── common.mk ├── docs └── source │ ├── mouse.rst │ ├── screen.rst │ ├── images │ ├── cage.png │ ├── cage-callbacks.png │ └── cage-gamestates.png │ ├── color.rst │ ├── file.rst │ ├── _static │ └── breathe.css │ ├── keyboard.rst │ ├── font.rst │ ├── animate.rst │ ├── sound.rst │ ├── sprite.rst │ ├── timeline.rst │ ├── image.rst │ ├── start.rst │ ├── advanced.rst │ ├── index.rst │ └── game.rst ├── .gitignore ├── vc ├── Image │ ├── Image.vcxproj.user │ ├── Image.vcxproj.filters │ └── Image.vcxproj ├── Sprite │ ├── Sprite.vcxproj.user │ └── Sprite.vcxproj.filters ├── State │ ├── State.vcxproj.user │ ├── State.vcxproj.filters │ └── State.vcxproj ├── Wizard │ ├── Wizard.vcxproj.user │ └── Wizard.vcxproj.filters ├── Callout │ ├── Callout.vcxproj.user │ └── Callout.vcxproj.filters ├── Timeline │ ├── Timeline.vcxproj.user │ └── Timeline.vcxproj.filters ├── Collisions │ ├── Collisions.vcxproj.user │ └── Collisions.vcxproj.filters ├── Cage │ ├── Cage.vcxproj.filters │ └── Cage.vcxproj └── Cage.sln ├── 3rdparty ├── unzip.vbs ├── GetSDL2.bat └── dl.vbs ├── gen_prefix_files.sh ├── CMakeLists.txt ├── src ├── CMakeLists.txt ├── internals.h ├── types.h ├── toolbox.h ├── mouse.c ├── color.c ├── mouse.h ├── keyboard.c ├── geometry.c ├── geometry.h ├── screen.h ├── color.h ├── keyboard.h ├── utils.h ├── sound.c ├── animate.c ├── vec.h ├── file.h ├── vec.c ├── file.c ├── screen.c ├── sound.h ├── font.h ├── end_prefix.h ├── animate.h ├── cage.h ├── timeline.h ├── timeline.c ├── ccage.hh ├── sprite.h └── begin_prefix.h ├── Android.mk ├── LICENSE ├── literst.awk ├── linux.mk ├── README.md ├── Makefile └── cmake ├── FindSDL2_image.cmake ├── FindSDL2_mixer.cmake └── FindSDL2.cmake /samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(wizard/) 2 | -------------------------------------------------------------------------------- /docs/source/mouse.rst: -------------------------------------------------------------------------------- 1 | mouse 2 | ===== 3 | 4 | .. doxygenfile:: src/mouse.h 5 | -------------------------------------------------------------------------------- /docs/source/screen.rst: -------------------------------------------------------------------------------- 1 | screen 2 | ====== 3 | 4 | .. doxygenfile:: src/screen.h 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | obj/** 2 | build 3 | docs/build 4 | samples/**/obj 5 | samples/**/build 6 | -------------------------------------------------------------------------------- /samples/callout/res/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/callout/res/bg.png -------------------------------------------------------------------------------- /samples/image/res/cage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/image/res/cage.png -------------------------------------------------------------------------------- /samples/state/res/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/state/res/font.png -------------------------------------------------------------------------------- /docs/source/images/cage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/docs/source/images/cage.png -------------------------------------------------------------------------------- /samples/tiled/raw/sprite.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/raw/sprite.psd -------------------------------------------------------------------------------- /samples/tiled/raw/sprite.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/raw/sprite.xcf -------------------------------------------------------------------------------- /samples/tiled/res/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/res/sprite.png -------------------------------------------------------------------------------- /samples/wizard/res/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/font.png -------------------------------------------------------------------------------- /samples/wizard/res/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/mask.png -------------------------------------------------------------------------------- /samples/wizard/res/spot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/spot.png -------------------------------------------------------------------------------- /samples/wizard/res/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/title.png -------------------------------------------------------------------------------- /samples/wizard/res/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/tree.png -------------------------------------------------------------------------------- /samples/callout/res/callout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/callout/res/callout.png -------------------------------------------------------------------------------- /samples/callout/res/cofont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/callout/res/cofont.png -------------------------------------------------------------------------------- /samples/collisions/res/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/collisions/res/star.png -------------------------------------------------------------------------------- /samples/sprite/res/wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/sprite/res/wizard.png -------------------------------------------------------------------------------- /samples/tiled/raw/_sprite.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/raw/_sprite.gif -------------------------------------------------------------------------------- /samples/tiled/res/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/res/overlay.png -------------------------------------------------------------------------------- /samples/tiled/res/shadowmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/res/shadowmap.png -------------------------------------------------------------------------------- /samples/tiled/res/tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/res/tileset.png -------------------------------------------------------------------------------- /samples/timeline/res/cage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/timeline/res/cage.png -------------------------------------------------------------------------------- /samples/timeline/res/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/timeline/res/font.png -------------------------------------------------------------------------------- /samples/wizard/res/wizard.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/wizard.ogg -------------------------------------------------------------------------------- /samples/wizard/res/wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/wizard.png -------------------------------------------------------------------------------- /samples/chipmunk/res/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/chipmunk/res/particle.png -------------------------------------------------------------------------------- /samples/tiled/res/spritemask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/tiled/res/spritemask.png -------------------------------------------------------------------------------- /samples/wizard/res/earth_tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/earth_tile.png -------------------------------------------------------------------------------- /samples/wizard/res/grass_tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/samples/wizard/res/grass_tile.png -------------------------------------------------------------------------------- /samples/chipmunk/res/game.conf: -------------------------------------------------------------------------------- 1 | window_width 650 2 | window_height 365 3 | logical_width 325 4 | logical_height 182 5 | -------------------------------------------------------------------------------- /docs/source/images/cage-callbacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/docs/source/images/cage-callbacks.png -------------------------------------------------------------------------------- /docs/source/images/cage-gamestates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlofc/cage/HEAD/docs/source/images/cage-gamestates.png -------------------------------------------------------------------------------- /samples/wizard/res/game.conf: -------------------------------------------------------------------------------- 1 | # Game configuration 2 | window_width 1280 3 | window_height 720 4 | logical_width 192 5 | logical_height 108 6 | -------------------------------------------------------------------------------- /vc/Image/Image.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/Sprite/Sprite.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/State/State.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/Wizard/Wizard.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/Callout/Callout.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/Timeline/Timeline.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /vc/Collisions/Collisions.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /samples/tiled/raw/README.md: -------------------------------------------------------------------------------- 1 | # Sprite Base 2 | I created this RPG-inspired sprite base for the upcoming CAGE tiled 3 | tutorial. 4 | 5 | ![Sprite Base](_sprite.gif) 6 | 7 | It has different effect layers you can turn on and off. This 8 | makes it very easy to customize and create different sprites. 9 | -------------------------------------------------------------------------------- /docs/source/color.rst: -------------------------------------------------------------------------------- 1 | color 2 | ========= 3 | 4 | .. highlight:: c 5 | 6 | struct color 7 | ------------ 8 | .. doxygenstruct:: color 9 | 10 | color_from_RGBA 11 | ---------------- 12 | .. doxygenfunction:: color_from_RGBA 13 | 14 | color_from_RGB 15 | ----------------- 16 | .. doxygenfunction:: color_from_RGB 17 | -------------------------------------------------------------------------------- /docs/source/file.rst: -------------------------------------------------------------------------------- 1 | file 2 | ===== 3 | 4 | struct file_spec 5 | ----------------- 6 | .. doxygenstruct:: file_spec 7 | 8 | read_file 9 | --------- 10 | .. doxygenfunction:: read_file 11 | 12 | write_file 13 | ---------- 14 | .. doxygenfunction:: write_file 15 | 16 | is_file_exists 17 | -------------- 18 | .. doxygenfunction:: is_file_exists 19 | -------------------------------------------------------------------------------- /docs/source/_static/breathe.css: -------------------------------------------------------------------------------- 1 | 2 | /* -- breathe specific styles ----------------------------------------------- */ 3 | 4 | /* So enum value descriptions are displayed inline to the item */ 5 | .breatheenumvalues li tt + p { 6 | display: inline; 7 | } 8 | 9 | /* So parameter descriptions are displayed inline to the item */ 10 | .breatheparameterlist li tt + p { 11 | display: inline; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /3rdparty/unzip.vbs: -------------------------------------------------------------------------------- 1 | Dim fileName, workingDir 2 | fileName = WScript.Arguments(0) 3 | workingDir = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") 4 | Set objShell = CreateObject("Shell.Application") 5 | Set objSource = objShell.NameSpace(workingDir & "\" & fileName).Items() 6 | Set objTarget = objShell.NameSpace(workingDir & "\") 7 | intOptions = 256 8 | objTarget.CopyHere objSource, intOptions -------------------------------------------------------------------------------- /samples/wizard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable( 2 | wizard 3 | src/wizard.cc 4 | ) 5 | 6 | file(COPY ${CMAKE_SOURCE_DIR}/samples/wizard/res 7 | DESTINATION 8 | ${CMAKE_BINARY_DIR}/samples/wizard/) 9 | 10 | set_target_properties(wizard 11 | PROPERTIES 12 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/samples/wizard/" 13 | ) 14 | target_link_libraries(wizard ccage ${COMMON_LIBS}) 15 | SET_TARGET_PROPERTIES(wizard PROPERTIES LINKER_LANGUAGE CXX) 16 | -------------------------------------------------------------------------------- /docs/source/keyboard.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: c 2 | 3 | keyboard 4 | ======== 5 | 6 | Key presses can be detected using two methods: 7 | 8 | key_pressed 9 | ----------- 10 | .. doxygenfunction:: key_pressed 11 | 12 | key_down 13 | -------- 14 | .. doxygenfunction:: key_down 15 | 16 | key symbols 17 | ----------- 18 | 19 | These symbols can be used for key_pressed() or key_down(): 20 | 21 | ========== ====== 22 | KB_SPACE KB_W 23 | KB_RIGHT KB_S 24 | KB_LEFT KB_A 25 | KB_UP KB_D 26 | KB_DOWN 27 | KB_ESC 28 | ========== ====== 29 | -------------------------------------------------------------------------------- /docs/source/font.rst: -------------------------------------------------------------------------------- 1 | font 2 | ==== 3 | 4 | .. highlight:: c 5 | 6 | struct font 7 | ----------- 8 | .. doxygenstruct:: font 9 | 10 | create_font 11 | ----------- 12 | .. doxygenfunction:: create_font 13 | 14 | destroy_font 15 | ------------ 16 | .. doxygenfunction:: destroy_font 17 | 18 | load_font 19 | ------------ 20 | .. doxygenfunction:: load_font 21 | 22 | cleanup_font 23 | ------------ 24 | .. doxygenfunction:: cleanup_font 25 | 26 | draw_text 27 | ------------ 28 | .. doxygenfunction:: draw_text 29 | 30 | measure_text 31 | ------------ 32 | .. doxygenfunction:: measure_text 33 | -------------------------------------------------------------------------------- /gen_prefix_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "#ifdef CAGE_PREFIX" > src/begin_prefix.h 3 | ctags -x --c-kinds=pgs-d src/*.h | cut -f1 -d' ' |\ 4 | while read symbol; do echo "#define $symbol cage_$symbol" ; done >> src/begin_prefix.h 5 | ctags -x --c-kinds=e src/*.h | cut -f1 -d' ' |\ 6 | while read symbol; do echo "#define $symbol CAGE_$symbol" ; done >> src/begin_prefix.h 7 | echo "#endif" >> src/begin_prefix.h 8 | echo "#ifdef CAGE_PREFIX" > src/end_prefix.h 9 | ctags -x --c-kinds=pges-d src/*.h | cut -f1 -d' ' |\ 10 | while read symbol; do echo "#undef $symbol" ; done >> src/end_prefix.h 11 | echo "#endif" >> src/end_prefix.h 12 | 13 | -------------------------------------------------------------------------------- /docs/source/animate.rst: -------------------------------------------------------------------------------- 1 | animation 2 | ========= 3 | 4 | .. highlight:: c 5 | 6 | struct animation 7 | ---------------- 8 | .. doxygenstruct:: animation 9 | 10 | struct frame 11 | ------------ 12 | .. doxygenstruct:: frame 13 | 14 | animation modes 15 | --------------- 16 | .. doxygenenum:: animation_mode 17 | 18 | create_animation 19 | ---------------- 20 | .. doxygenfunction:: create_animation 21 | 22 | destroy_animation 23 | ----------------- 24 | .. doxygenfunction:: destroy_animation 25 | 26 | add_frame 27 | --------- 28 | .. doxygenfunction:: add_frame 29 | 30 | add_frames 31 | ---------- 32 | .. doxygenfunction:: add_frames 33 | 34 | -------------------------------------------------------------------------------- /docs/source/sound.rst: -------------------------------------------------------------------------------- 1 | sound 2 | ===== 3 | 4 | struct sound 5 | ------------ 6 | .. doxygenstruct:: sound 7 | 8 | create_sound 9 | ------------ 10 | .. doxygenfunction:: create_sound 11 | 12 | destroy_sound 13 | ------------- 14 | .. doxygenfunction:: destroy_sound 15 | 16 | load_sound 17 | ------------- 18 | .. doxygenfunction:: load_sound 19 | 20 | cleanup_sound 21 | ------------- 22 | .. doxygenfunction:: cleanup_sound 23 | 24 | play_sound 25 | ------------- 26 | .. doxygenfunction:: play_sound 27 | 28 | stop_sound 29 | ------------- 30 | .. doxygenfunction:: stop_sound 31 | 32 | is_playing 33 | ---------- 34 | .. doxygenfunction:: is_playing 35 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 2 | add_compile_options(-std=c++1z) 3 | project(CCAGE VERSION 0.9 LANGUAGES CXX) 4 | add_definitions(-DCAGE_PREFIX) 5 | SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 6 | INCLUDE(FindPkgConfig) 7 | 8 | find_package(SDL2 REQUIRED) 9 | find_package(SDL2_mixer REQUIRED) 10 | find_package(SDL2_image REQUIRED) 11 | find_package(PkgConfig REQUIRED) 12 | 13 | include_directories(${CMAKE_SOURCE_DIR}/src) 14 | include_directories(${SDL2_INCLUDE_DIR}) 15 | 16 | set (COMMON_LIBS 17 | SDL2 SDL2_mixer SDL2_image) 18 | 19 | add_subdirectory(src/) 20 | add_subdirectory(samples/) 21 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_SOURCE_DIR}) 2 | include_directories(${SDL2_INCLUDE_DIR}) 3 | include_directories(/usr/include/SDL2) 4 | 5 | set(SOURCE_FILES 6 | animate.c 7 | cage.c 8 | color.c 9 | easing.c 10 | file.c 11 | font.c 12 | geometry.c 13 | image.c 14 | keyboard.c 15 | mouse.c 16 | screen.c 17 | sound.c 18 | sprite.c 19 | timeline.c 20 | vec.c 21 | ccage.cc 22 | 23 | ) 24 | 25 | set_source_files_properties(${SOURCE_FILES} 26 | PROPERTIES LANGUAGE CXX) 27 | add_library( 28 | ccage STATIC 29 | ${SOURCE_FILES} 30 | ) 31 | 32 | SET_TARGET_PROPERTIES(ccage PROPERTIES LINKER_LANGUAGE CXX) 33 | 34 | -------------------------------------------------------------------------------- /3rdparty/GetSDL2.bat: -------------------------------------------------------------------------------- 1 | REM Getting SDL2, SDL2_Image and SDL2_Mixer 2 | REM --------------------------------------- 3 | 4 | set prefix1=http://www.libsdl.org/release 5 | set filename1=SDL2-devel-2.0.3-VC.zip 6 | 7 | set prefix2=https://www.libsdl.org/projects/SDL_image/release 8 | set filename2=SDL2_image-devel-2.0.0-VC.zip 9 | 10 | set prefix3=http://www.libsdl.org/projects/SDL_mixer/release 11 | set filename3=SDL2_mixer-devel-2.0.0-VC.zip 12 | 13 | cscript dl.vbs %prefix1%/%filename1% %filename1% 14 | cscript dl.vbs %prefix2%/%filename2% %filename2% 15 | cscript dl.vbs %prefix3%/%filename3% %filename3% 16 | 17 | cscript unzip.vbs %filename1% 18 | cscript unzip.vbs %filename2% 19 | cscript unzip.vbs %filename3% 20 | 21 | del %filename1% 22 | del %filename2% 23 | del %filename3% 24 | 25 | -------------------------------------------------------------------------------- /docs/source/sprite.rst: -------------------------------------------------------------------------------- 1 | sprite 2 | ================================ 3 | 4 | .. highlight:: c 5 | 6 | struct sprite 7 | ------------- 8 | .. doxygenstruct:: sprite 9 | 10 | create_sprite 11 | ------------- 12 | .. doxygenfunction:: create_sprite 13 | 14 | destroy_sprite 15 | -------------- 16 | .. doxygenfunction:: destroy_sprite 17 | 18 | prepare_sprite 19 | -------------- 20 | .. doxygenfunction:: prepare_sprite 21 | 22 | draw_sprite 23 | ----------- 24 | .. doxygenfunction:: draw_sprite 25 | 26 | draw_sprite_frame 27 | ----------------- 28 | .. doxygenfunction:: draw_sprite_frame 29 | 30 | animate_sprite 31 | -------------- 32 | .. doxygenfunction:: animate_sprite 33 | 34 | play_animation 35 | -------------- 36 | .. doxygenfunction:: play_animation 37 | 38 | stop_animation 39 | -------------- 40 | .. doxygenfunction:: stop_animation 41 | 42 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := CAGE 6 | 7 | LOCAL_C_INCLUDES := $(LOCAL_PATH) \ 8 | ../SDL2_mixer/ \ 9 | ../SDL2_image/ 10 | 11 | LOCAL_SRC_FILES := src/animate.c \ 12 | src/cage.c \ 13 | src/easing.c \ 14 | src/font.c \ 15 | src/geometry.c \ 16 | src/image.c \ 17 | src/keyboard.c \ 18 | src/mouse.c \ 19 | src/screen.c \ 20 | src/sound.c \ 21 | src/sprite.c \ 22 | src/timeline.c 23 | 24 | 25 | LOCAL_LDLIBS := 26 | LOCAL_STATIC_LIBRARIES := 27 | LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_mixer 28 | 29 | LOCAL_EXPORT_C_INCLUDES += $(LOCAL_C_INCLUDES) 30 | 31 | include $(BUILD_SHARED_LIBRARY) 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Ithai Levi @RLofC 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source 20 | distribution. 21 | -------------------------------------------------------------------------------- /src/internals.h: -------------------------------------------------------------------------------- 1 | #ifndef INTERNALS_H_G9CYEQL6 2 | #define INTERNALS_H_G9CYEQL6 3 | 4 | #include "SDL.h" 5 | 6 | #include "begin_prefix.h" 7 | /* The game drawing surface 8 | * A screen is you drawing surface for you to draw on 9 | * your game images, sprites and text. 10 | * 11 | * Your functions will get a screen 12 | * to work with inside the parameter. 13 | */ 14 | struct screen { 15 | /* internal SDL renderer */ 16 | SDL_Renderer* impl; 17 | /* internal SDL window */ 18 | SDL_Window* window; 19 | /* Rendering X offset, for scrolling or shaking */ 20 | float offset_x; 21 | /* Rendering Y offset, for scrolling or shaking */ 22 | float offset_y; 23 | }; 24 | extern struct screen* screen; 25 | 26 | struct keyboard { 27 | const uint8_t* keys; 28 | int states[256]; 29 | }; 30 | extern struct keyboard* keyboard; 31 | 32 | #include "end_prefix.h" 33 | #endif /* end of include guard: INTERNALS_H_G9CYEQL6 */ 34 | -------------------------------------------------------------------------------- /literst.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | block=0; 3 | printf(".. highlight:: c\n\n"); 4 | } 5 | 6 | { 7 | spos=match($0,"^[/][*]"); 8 | mpos=match($0,"^[ ][*][ ]|^[ ][*]$"); 9 | epos=match($0,"^[ ][*][/]"); 10 | 11 | if(spos > 0 && epos ==0) 12 | { 13 | printf("%s\n",substr($0,spos+3,length($0))); 14 | block=0; 15 | } 16 | else if ( spos == 0 && epos > 0) 17 | { 18 | printf("%s\n",substr($0,spos+3,epos-3)); 19 | block=1; 20 | } 21 | else if(mpos > 0) 22 | { 23 | printf("%s\n",substr($0,mpos+3,length($0))); 24 | block=0; 25 | } 26 | else if (epos > 0) 27 | { 28 | block=1; 29 | } 30 | else if ( epos == 0 && mpos == 0 && spos == 0 ) 31 | { 32 | if (block==1) 33 | { 34 | block = 0; 35 | printf("\n::\n\n"); 36 | } 37 | printf("\t%s\n",$0); 38 | } 39 | } 40 | 41 | END { 42 | if(found==1) 43 | { 44 | print "there is unmatched comment" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /3rdparty/dl.vbs: -------------------------------------------------------------------------------- 1 | 'Set your settings 2 | 3 | strFileURL = WScript.Arguments.Item(0) 4 | strHDLocation = WScript.Arguments.Item(1) 5 | 6 | ' Fetch the file 7 | 8 | Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") 9 | 10 | objXMLHTTP.open "GET", strFileURL, false 11 | objXMLHTTP.send() 12 | 13 | If objXMLHTTP.Status = 200 Then 14 | Set objADOStream = CreateObject("ADODB.Stream") 15 | objADOStream.Open 16 | objADOStream.Type = 1 'adTypeBinary 17 | 18 | objADOStream.Write objXMLHTTP.ResponseBody 19 | objADOStream.Position = 0 'Set the stream position to the start 20 | 21 | Set objFSO = Createobject("Scripting.FileSystemObject") 22 | If objFSO.Fileexists(strHDLocation) Then objFSO.DeleteFile strHDLocation 23 | Set objFSO = Nothing 24 | 25 | objADOStream.SaveToFile strHDLocation 26 | objADOStream.Close 27 | Set objADOStream = Nothing 28 | End if 29 | 30 | Set objXMLHTTP = Nothing -------------------------------------------------------------------------------- /samples/image/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/image 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/sprite/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/sprite 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/state/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/state 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/wizard/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/wizard 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/callout/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/callout 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/timeline/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/timeline 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /samples/collisions/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/collisions 22 | include ../common.mk 23 | -------------------------------------------------------------------------------- /vc/Wizard/Wizard.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /vc/Image/Image.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {F11EC6F1-2B85-44B7-80B4-8FBCEF798445} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {C7C8C413-FD68-40CA-9822-B41F9DB8D1E4} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {0E3F329A-5C9A-459D-B81F-23B283C3D7D2} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vc/Sprite/Sprite.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {7E9FFDD7-5FB5-4C87-8899-89DC562ABAC0} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {FE2A6DAE-0E50-49C0-A000-9E8B255DC65C} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {781DB685-7D6A-491D-80B2-557868B0DE9C} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vc/State/State.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {8BABEC67-6B89-4248-9382-B0E3D0E9D520} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {261DBCDC-E7B8-4704-8A82-59F70667CBD3} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {D42EA566-8A6F-4A55-8D8D-863BCE64C076} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vc/Callout/Callout.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {72E9D8FF-2046-4805-B814-83ED674475D5} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {88A8A113-E796-4725-BCA7-EB034B09952C} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {D3657C46-1483-4A3C-974E-D8F550F8E57B} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vc/Timeline/Timeline.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {226D2E04-E599-4FF4-A5F2-E2687C5FEA0B} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {3355A630-5A09-4E2B-9258-BB92181FC5EA} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {5CB9EEB9-BBC4-4954-8CFF-50E368AEC3DF} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vc/Collisions/Collisions.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {D25D86C1-F20D-44C1-BACB-B4FC3A651E35} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {FE06877F-3501-40FA-8E9A-F8875B166A92} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {CF965404-5B51-44AB-8418-FD13B157C5BC} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/types.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef TYPES_H_ZAIL4YD9 23 | #define TYPES_H_ZAIL4YD9 24 | #include "begin_prefix.h" 25 | #include 26 | #include "end_prefix.h" 27 | #endif /* TYPES_H_ZAIL4YD9 */ 28 | -------------------------------------------------------------------------------- /src/toolbox.h: -------------------------------------------------------------------------------- 1 | #ifndef TOOLBOX_H_W7RODJL2 2 | #define TOOLBOX_H_W7RODJL2 3 | 4 | #include 5 | 6 | 7 | #include "begin_prefix.h" 8 | struct gamestate; 9 | 10 | /* Game toolbox passed to state callbacks 11 | * The toolbox contains a set of utilities 12 | * to help the state functions work. 13 | * Additionally, you can store a custom 14 | * data structure inside the 15 | * field: 16 | * 17 | * struct my_data { 18 | * struct sprite* my_sprite; 19 | * }; 20 | * 21 | * int prepare_my_level( struct toolbox* toolbox ) 22 | * { 23 | * toolbox->data = malloc( sizeof( struct my_data ) ); 24 | * } 25 | * 26 | * int teardown_my_level( struct toolbox* toolbox ) 27 | * { 28 | * free( toolbox->data ); 29 | * } 30 | * 31 | */ 32 | struct toolbox { 33 | /* user data; set as you like */ 34 | void* data; 35 | /* elapsed time since last frame ( in render-time only ) */ 36 | float stopwatch; 37 | /* optionally set this to the next state ( in render-time only ) */ 38 | struct gamestate* state; 39 | struct gamestate* next_state; 40 | }; 41 | 42 | #include "end_prefix.h" 43 | #endif /* end of include guard: TOOLBOX_H_W7RODJL2 */ 44 | -------------------------------------------------------------------------------- /docs/source/timeline.rst: -------------------------------------------------------------------------------- 1 | timeline 2 | ======== 3 | 4 | .. highlight:: c 5 | 6 | struct timeline 7 | --------------- 8 | .. doxygenstruct:: timeline 9 | 10 | struct timeline_event 11 | --------------------- 12 | .. doxygenstruct:: timeline_event 13 | 14 | create_timeline 15 | --------------- 16 | .. doxygenfunction:: create_timeline 17 | 18 | destroy_timeline 19 | ---------------- 20 | .. doxygenfunction:: destroy_timeline 21 | 22 | append_event 23 | ------------ 24 | .. doxygenfunction:: append_event 25 | 26 | append_events 27 | ------------- 28 | .. doxygenfunction:: append_events 29 | 30 | update_timeline 31 | --------------- 32 | .. doxygenfunction:: update_timeline 33 | 34 | init_timeline 35 | ------------- 36 | .. doxygenfunction:: init_timeline 37 | 38 | pause_timeline 39 | -------------- 40 | .. doxygenfunction:: pause_timeline 41 | 42 | reset_timeline 43 | -------------- 44 | .. doxygenfunction:: reset_timeline 45 | 46 | cleanup_timeline 47 | ---------------- 48 | .. doxygenfunction:: cleanup_timeline 49 | 50 | Easing 51 | ------ 52 | 53 | Using easing interpolation functions you can use the progress 54 | argument in the timeline callbacks to create a factor value for 55 | animation effects such as smoothing the motion of a game title 56 | or even bouncing a ball. 57 | 58 | .. doxygenfile:: easing.h 59 | -------------------------------------------------------------------------------- /docs/source/image.rst: -------------------------------------------------------------------------------- 1 | image 2 | ================================ 3 | 4 | .. highlight:: c 5 | 6 | struct image 7 | ------------ 8 | .. doxygenstruct:: image 9 | 10 | create_image 11 | ------------ 12 | .. doxygenfunction:: create_image 13 | 14 | create_blank_image 15 | ------------------ 16 | .. doxygenfunction:: create_blank_image 17 | 18 | create_target_image 19 | ------------------- 20 | .. doxygenfunction:: create_target_image 21 | 22 | destroy_image 23 | ------------- 24 | .. doxygenfunction:: destroy_image 25 | 26 | draw_image 27 | ---------- 28 | .. doxygenfunction:: draw_image 29 | 30 | get_image_alpha 31 | ------------- 32 | .. doxygenfunction:: get_image_alpha 33 | 34 | set_image_alpha 35 | ------------- 36 | .. doxygenfunction:: set_image_alpha 37 | 38 | set_blend_mode 39 | -------------- 40 | .. doxygenfunction:: set_blend_mode 41 | 42 | load_image 43 | ---------- 44 | .. doxygenfunction:: load_image 45 | 46 | cleanup_image 47 | ------------- 48 | .. doxygenfunction:: cleanup_image 49 | 50 | lock_image 51 | ------------- 52 | .. doxygenfunction:: lock_image 53 | 54 | unlock_image 55 | ------------- 56 | .. doxygenfunction:: unlock_image 57 | 58 | draw_on_image 59 | ------------- 60 | .. doxygenfunction:: draw_on_image 61 | 62 | pixels_collide 63 | -------------- 64 | .. doxygenfunction:: pixels_collide 65 | -------------------------------------------------------------------------------- /docs/source/start.rst: -------------------------------------------------------------------------------- 1 | Getting Started 2 | =============== 3 | 4 | 5 | Install 6 | ------- 7 | 8 | First, clone the repo: 9 | 10 | :: 11 | 12 | git clone https://github.com/rlofc/cage.git 13 | 14 | To use CAGE you will need **SDL2**, **SDL2_Image** and **SDL2_Mixer**. 15 | 16 | For **Windows**, run ``getSDL2.bat`` inside the ``3rdparty`` folder. 17 | 18 | If you're using **Mac OS/X**, you can use brew: 19 | 20 | :: 21 | 22 | brew install SDL2 SDL2_Image SDL2_Mixer 23 | 24 | In **Arch Linux**, use pacman: 25 | 26 | :: 27 | 28 | sudo pacman -S sdl2 sdl2_image sdl2_mixer 29 | 30 | Build 31 | ----- 32 | 33 | Once you have **SDL2**, **SDL2_Mixer** and **SDL2_Image**, you can build CAGE and run the 34 | samples. 35 | 36 | In **Windows**, open the Visual Studio 2013 project inside the ``vc`` folder of CAGE 37 | and build the solution. You will find the samples executable inside ``vc\Debug`` or ``vc\Release``. 38 | 39 | In **Mac OS/X** or **Linux**, simply: 40 | 41 | :: 42 | 43 | cd cage && make 44 | 45 | New Games 46 | --------- 47 | 48 | To start a new game project, clone **cage-bp** (CAGE 49 | Boilerplate): 50 | 51 | :: 52 | 53 | git clone https://github.com/rlofc/cage-bp.git my_game 54 | 55 | By default, the boilerplate project is configured to find CAGE 56 | side-by-side relative to its location, but you can edit the Makefile to change 57 | this. 58 | -------------------------------------------------------------------------------- /docs/source/advanced.rst: -------------------------------------------------------------------------------- 1 | (More) Advanced 2 | =============== 3 | 4 | 5 | Memory Management 6 | ----------------- 7 | 8 | CAGE lets you decide how to manage your game's memory. 9 | Resources such as image, sprite and animation 10 | will usually have a set of **create** and **destroy** 11 | functions you can use, releasing you from explicitly allocating and freeing memory. 12 | 13 | Alternatively, you can allocate and free structure memory by yourself 14 | but you will have to initialize and cleanup the resource 15 | internal state. 16 | 17 | For example, you can easily create and destroy images like so: 18 | 19 | :: 20 | 21 | struct image* image; 22 | image = create_image("res/image.png"); 23 | 24 | if (image!=NULL) { 25 | destroy_image(image); 26 | } 27 | 28 | Or, if you want, you can do: 29 | 30 | :: 31 | 32 | struct image image; 33 | // this will work on already allocated image structs 34 | if (load_image(&image, "res/image.png") == -1) { 35 | // something went wrong 36 | } 37 | // clean up any internally allocated resources 38 | cleanup_image(&image); 39 | 40 | 41 | Coding Style 42 | ------------ 43 | CAGE uses a slightly modified version of the Linux kernel 44 | coding style. The main differences are: 45 | 46 | * Indentation size is 4 spaces. 47 | * Pointer '*' sign is adjacent to the type and not to the 48 | variable. 49 | -------------------------------------------------------------------------------- /samples/tiled/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/tiled 22 | LDFLAGS += -L./deps/tmx/build/ 23 | LIBRARIES += -ltmx -lz -lxml2 24 | CFLAGS += -I./deps/tmx/src 25 | CFLAGS += -I./src 26 | 27 | include ../common.mk 28 | 29 | deps/tmx: 30 | git clone https://github.com/baylej/tmx.git deps/tmx 31 | 32 | deps/tmx/build/libtmx.a: deps/tmx 33 | cd deps/tmx && mkdir build && cd build && cmake .. && make 34 | 35 | deps: deps/tmx/build/libtmx.a 36 | -------------------------------------------------------------------------------- /samples/image/src/image.c: -------------------------------------------------------------------------------- 1 | /* samples / image.c 2 | * ================= 3 | * This short sample demonstrate how to use images in Cage 4 | */ 5 | #include "cage.h" 6 | 7 | /* Create 8 | * ------ 9 | * 10 | * We use the game state create() function to load the image resource 11 | * and return it as the state user data pointer. 12 | */ 13 | static void* create_sample(void) 14 | { 15 | return create_image("res/cage.png"); 16 | } 17 | 18 | /* Update 19 | * ------ 20 | * 21 | * For each frame, the update state function will draw the image 22 | * using the image size as clipping boundaries. 23 | * We explicitly eliminate the unused parameter warning using 24 | * the UNUSED macro. 25 | */ 26 | static void update_sample(void* data, float elapsed_ms) 27 | { 28 | struct rectangle clip = { 0, 0, 144, 76 }; 29 | draw_image(data, 4, 5, &clip, 0); 30 | UNUSED(elapsed_ms); 31 | } 32 | 33 | /* Destroy 34 | * ------- 35 | * 36 | * A create_image() call allocates the image and its 37 | * internal resources. To properly clean up our state we 38 | * need to use destroy_image() in the destroy state function. 39 | * 40 | */ 41 | static void destroy_sample(void* data) 42 | { 43 | destroy_image(data); 44 | } 45 | 46 | /* Finally, the main 47 | * ----------------- 48 | * 49 | * Finally, the game's main function delegates the 50 | * execution to Cage's game_loop() function together with 51 | * the 3 state functions we wrote. 52 | */ 53 | int main(void) 54 | { 55 | return game_loop(create_sample, update_sample, destroy_sample); 56 | } 57 | -------------------------------------------------------------------------------- /src/mouse.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "mouse.h" 23 | #include "internals.h" 24 | #include "SDL.h" 25 | 26 | #include "begin_prefix.h" 27 | void update_mouse(struct mouse* mouse) 28 | { 29 | int x, y, w, h; 30 | Uint32 ms = SDL_GetMouseState(&x, &y); 31 | SDL_GetWindowSize(screen->window, &w, &h); 32 | mouse->x_position = x / (w * 1.0); 33 | mouse->y_position = y / (h * 1.0); 34 | mouse->left_click = ms & SDL_BUTTON(SDL_BUTTON_LEFT); 35 | mouse->right_click = ms & SDL_BUTTON(SDL_BUTTON_RIGHT); 36 | mouse->middle_click = ms & SDL_BUTTON(SDL_BUTTON_MIDDLE); 37 | } 38 | #include "end_prefix.h" 39 | -------------------------------------------------------------------------------- /samples/chipmunk/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | BINARY = build/chipmunk 22 | LDFLAGS += -L./deps/Chipmunk2D/build/src 23 | LIBRARIES += -lchipmunk 24 | CFLAGS += -DTARGET_OS_MAC=0 -DTARGET_OS_IPHONE=0 -DCP_USE_CGTYPES=0 25 | CFLAGS += -I./deps/Chipmunk2D/include/chipmunk 26 | 27 | include ../common.mk 28 | 29 | deps/Chipmunk2D: 30 | git clone https://github.com/slembcke/Chipmunk2D.git deps/Chipmunk2D 31 | 32 | deps/Chipmunk2D/build/src/libchipmunk.a: deps/Chipmunk2D 33 | cd deps/Chipmunk2D && mkdir build && cd build && cmake -DBUILD_DEMOS=OFF \ 34 | -DINSTALL_DEMOS=OFF -DBUILD_SHARED=OFF -DINSTALL_STATIC=OFF .. && make 35 | 36 | deps: deps/Chipmunk2D/build/src/libchipmunk.a 37 | -------------------------------------------------------------------------------- /src/color.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "color.h" 23 | #include "begin_prefix.h" 24 | struct color color_from_RGBA(uint8_t red, 25 | uint8_t green, 26 | uint8_t blue, 27 | uint8_t alpha) 28 | { 29 | struct color c; 30 | c.red = red; 31 | c.green = green; 32 | c.blue = blue; 33 | c.alpha = alpha; 34 | return c; 35 | } 36 | 37 | struct color color_from_RGB(uint8_t red, 38 | uint8_t green, 39 | uint8_t blue) 40 | { 41 | return color_from_RGBA(red, green, blue, UINT8_MAX); 42 | } 43 | #include "end_prefix.h" 44 | -------------------------------------------------------------------------------- /src/mouse.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef MOUSE_H_UQ7XHW8V 23 | #define MOUSE_H_UQ7XHW8V 24 | 25 | #include "types.h" 26 | 27 | #include "begin_prefix.h" 28 | struct mouse { 29 | /** Set to true if left click was detected */ 30 | bool left_click; 31 | /** Set to true if right click was detected */ 32 | bool right_click; 33 | /** Set to true if middle click was detected */ 34 | bool middle_click; 35 | /** Normalized value. 0.0 is the left edge of the screen. 1.0 is the 36 | * right edge of the screen. */ 37 | float x_position; 38 | /** Normalized value. 0.0 is the top edge of the screen. 1.0 is the 39 | * bottom edge of the screen. */ 40 | float y_position; 41 | }; 42 | 43 | /** 44 | * Query the current mouse state and update the passed mouse struct. 45 | */ 46 | void update_mouse(struct mouse* mouse); 47 | 48 | #include "end_prefix.h" 49 | #endif /* end of include guard: MOUSE_H_UQ7XHW8V */ 50 | -------------------------------------------------------------------------------- /src/keyboard.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "internals.h" 23 | #include "keyboard.h" 24 | #include "SDL.h" 25 | #include "begin_prefix.h" 26 | 27 | static struct keyboard global_keyboard; 28 | struct keyboard* keyboard = &global_keyboard; 29 | 30 | int KB_SPACE = SDL_SCANCODE_SPACE; 31 | int KB_RIGHT = SDL_SCANCODE_RIGHT; 32 | int KB_LEFT = SDL_SCANCODE_LEFT; 33 | int KB_UP = SDL_SCANCODE_UP; 34 | int KB_DOWN = SDL_SCANCODE_DOWN; 35 | int KB_ESC = SDL_SCANCODE_ESCAPE; 36 | int KB_W = SDL_SCANCODE_W; 37 | int KB_S = SDL_SCANCODE_S; 38 | int KB_A = SDL_SCANCODE_A; 39 | int KB_D = SDL_SCANCODE_D; 40 | int KB_BACK = SDL_SCANCODE_AC_BACK; 41 | 42 | int key_pressed(int key) 43 | { 44 | if (keyboard->keys[key]) { 45 | if (keyboard->states[key] == 0) { 46 | keyboard->states[key] = 1; 47 | return 1; 48 | } 49 | } else { 50 | keyboard->states[key] = 0; 51 | } 52 | return 0; 53 | } 54 | 55 | int key_down(int key) 56 | { 57 | return (keyboard->keys[key]); 58 | } 59 | #include "end_prefix.h" 60 | -------------------------------------------------------------------------------- /samples/common.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | CC = gcc 22 | CFLAGS += `sdl2-config --cflags` -I../../src/ -c 23 | DEBUG ?= 0 24 | ifeq (DEBUG, 1) 25 | CFLAGS += -g3 26 | else 27 | CFLAGS += -O3 28 | endif 29 | ifeq ($(UNAME_S),Linux) 30 | CFLAGS += -std=c89 31 | endif 32 | WARNINGS = -Wall -Wno-unused-label 33 | LDFLAGS += 34 | LIBRARIES += -L../../build/ -lSDL2_image -lSDL2_mixer -lcage -lm \ 35 | `sdl2-config --libs` 36 | SOURCES = $(wildcard src/*.c) 37 | OBJECTS = $(addprefix obj/,$(patsubst src/%,%,$(SOURCES:.c=.o) ) ) 38 | 39 | NO_COLOR=\x1b[0m 40 | INFO_COLOR=\x1b[35;01m 41 | 42 | .PHONY: all 43 | 44 | all: $(BINARY) resources 45 | 46 | ../../build/libcage.a: 47 | @cd ../../ && make build/libcage.a 48 | 49 | $(BINARY): deps $(OBJECTS) ../../build/libcage.a 50 | @mkdir -p build 51 | @echo -e "Building $(INFO_COLOR)$(BINARY)$(NO_COLOR)" 52 | @$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBRARIES) 53 | @echo "Done!" 54 | 55 | obj/%.o: src/%.c 56 | @mkdir -p obj 57 | @echo -e "Building $(INFO_COLOR)$@$(NO_COLOR)" 58 | @$(CC) $< -o $@ $(CFLAGS) $(WARNINGS) 59 | 60 | resources: 61 | @cp -rf res build/ 62 | 63 | clean: 64 | rm -rf $(BINARY) $(OBJECTS) build/res deps/** 65 | 66 | deps: 67 | -------------------------------------------------------------------------------- /src/geometry.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "geometry.h" 23 | #include "utils.h" 24 | #include 25 | 26 | #include "begin_prefix.h" 27 | int point_in_bbox(point p, bbox b) 28 | { 29 | return ((p.x >= b.p1.x && p.x <= b.p2.x) && 30 | (p.y >= b.p1.y && p.y <= b.p2.y)); 31 | } 32 | 33 | int bbox_in_bbox(bbox i, bbox o) 34 | { 35 | return point_in_bbox(i.p1, o) && point_in_bbox(i.p2, o); 36 | } 37 | 38 | int bbox_intersect(bbox b1, bbox b2, bbox* r) 39 | { 40 | r->p1.x = max(b1.p1.x, b2.p1.x); 41 | r->p1.y = max(b1.p1.y, b2.p1.y); 42 | r->p2.x = min(b1.p2.x, b2.p2.x); 43 | r->p2.y = min(b1.p2.y, b2.p2.y); 44 | 45 | return r->p2.x > r->p1.x && r->p2.y > r->p1.y; 46 | } 47 | 48 | bbox translate_bbox(bbox b, vec t) 49 | { 50 | vec d = sub_vec(b.p2, b.p1); 51 | b.p1 = t; 52 | b.p2 = add_vec(t, d); 53 | return b; 54 | } 55 | 56 | struct rectangle rect_from_sub_bbox(bbox outer, bbox inner) 57 | { 58 | struct rectangle r; 59 | r.x = (int)inner.p1.x - (int)outer.p1.x; 60 | r.y = (int)inner.p1.y - (int)outer.p1.y; 61 | r.w = (int)inner.p2.x - (int)inner.p1.x; 62 | r.h = (int)inner.p2.y - (int)inner.p1.y; 63 | return r; 64 | } 65 | #include "end_prefix.h" 66 | -------------------------------------------------------------------------------- /src/geometry.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef GEOMETRY_H_NQUPRW4D 23 | #define GEOMETRY_H_NQUPRW4D 24 | #include "vec.h" 25 | #include "begin_prefix.h" 26 | /* point is a kind of a vec */ 27 | typedef vec point; 28 | /** 29 | * Just a simple rectangle shape for image operations 30 | */ 31 | struct rectangle { 32 | int x; 33 | int y; 34 | int w; 35 | int h; 36 | }; 37 | 38 | /** 39 | * Point in sub-pixel space 40 | */ 41 | struct coords { 42 | int x; 43 | int y; 44 | }; 45 | 46 | #define xy(X, Y) X, Y 47 | 48 | /* bounding box is made of two points, 49 | * p1 - upper left 50 | * p2 - lower right 51 | */ 52 | typedef struct { 53 | point p1; 54 | point p2; 55 | } bbox; 56 | 57 | /* test if point is inside a bbox */ 58 | int point_in_bbox(point p, bbox b); 59 | /* test if a bbox is inside another bbox */ 60 | int bbox_in_bbox(bbox i, bbox o); 61 | /* test if bboxes intersect each other */ 62 | /* and return the intersection bbox */ 63 | int bbox_intersect(bbox b1, bbox b2, bbox* r); 64 | /* move a bbox to a new position, while preserving its 65 | * dimensions 66 | */ 67 | bbox translate_bbox(bbox b, vec t); 68 | /* returns the rectangle of an inner bbox */ 69 | struct rectangle rect_from_sub_bbox(bbox outer, bbox inner); 70 | 71 | #include "end_prefix.h" 72 | #endif /* end of include guard: GEOMETRY_H_NQUPRW4D */ 73 | -------------------------------------------------------------------------------- /src/screen.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef SCREEN_H_PCFZWLG4 23 | #define SCREEN_H_PCFZWLG4 24 | 25 | #include "color.h" 26 | 27 | #include "begin_prefix.h" 28 | /** 29 | * Change the screen background color. 30 | */ 31 | void screen_color(struct color background); 32 | 33 | /** 34 | * Shake the virtual camera (e.g. for explosions and hits). 35 | * The screen will keep shaking as long as you call shake_screen(). 36 | * To return the screen to its normal state, you should complement 37 | * with calling relax_screen(). 38 | */ 39 | void shake_screen(float stopwatch); 40 | 41 | /** 42 | * Undo the screen shake effect. 43 | */ 44 | void relax_screen(float stopwatch); 45 | 46 | /** 47 | * Switch back to draw on the actual screen following 48 | * a call to ``draw_on_image()`` on an \ref image. 49 | */ 50 | void draw_on_screen(void); 51 | 52 | /** 53 | * Change the screen size. 54 | */ 55 | void set_screen_size(int width, int height); 56 | 57 | /** 58 | * Get the screen size. 59 | */ 60 | void get_screen_size(int* width, int* height); 61 | 62 | /** 63 | * Change the real window size. 64 | */ 65 | void set_window_size(int width, int height); 66 | 67 | /** 68 | * Get the real window size. 69 | */ 70 | void get_window_size(int* width, int* height); 71 | 72 | 73 | /* cldoc:end-category() */ 74 | 75 | #include "end_prefix.h" 76 | #endif /* end of include guard: SCREEN_H_PCFZWLG4 */ 77 | -------------------------------------------------------------------------------- /src/color.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef COLOR_H_5S0TOI9O 23 | #define COLOR_H_5S0TOI9O 24 | 25 | #include 26 | 27 | #include "begin_prefix.h" 28 | /* Color using the RGBA representation 29 | */ 30 | struct color { 31 | uint8_t red; 32 | uint8_t green; 33 | uint8_t blue; 34 | uint8_t alpha; 35 | }; 36 | 37 | /** 38 | * Create a new color using Red Green Blue and Alpha 39 | * values. 40 | * 41 | * @param red 0-255 intensity of red 42 | * @param green 0-255 intensity of blue 43 | * @param blue 0-255 intensity of green 44 | * @param alpha 0-255 alpha value 45 | * 46 | * @return new color struct by value 47 | */ 48 | struct color color_from_RGBA(uint8_t red, 49 | uint8_t green, 50 | uint8_t blue, 51 | uint8_t alpha); 52 | 53 | /** 54 | * Create a new color using Red Green and Blue 55 | * values. 56 | * The color will be opaque with a default alpha 57 | * value of 255. 58 | * 59 | * @param red 0-255 intensity of red 60 | * @param green 0-255 intensity of blue 61 | * @param blue 0-255 intensity of green 62 | * 63 | * @return new color struct by value 64 | */ 65 | struct color color_from_RGB(uint8_t red, 66 | uint8_t green, 67 | uint8_t blue); 68 | 69 | #include "end_prefix.h" 70 | #endif /* end of include guard: COLOR_H_5S0TOI9O */ 71 | -------------------------------------------------------------------------------- /samples/tiled/src/tiled_actor.h: -------------------------------------------------------------------------------- 1 | #ifndef CAGE_TILES_H_ 2 | #define CAGE_TILES_H_ 3 | 4 | #include 5 | 6 | struct map_spec { 7 | int rows; 8 | int cols; 9 | int tile_size; 10 | void* data; 11 | }; 12 | 13 | enum actor_dir { ACTOR_DOWN, 14 | ACTOR_LEFT, 15 | ACTOR_RIGHT, 16 | ACTOR_UP, 17 | _NUM_OF_ACTOR_DIRS }; 18 | 19 | enum actor_state { ACTOR_STILL, 20 | ACTOR_MOVING, 21 | ACTOR_INACTIVE, 22 | _NUM_OF_ACTOR_STATES }; 23 | 24 | struct actor_mode { 25 | enum actor_state state; 26 | enum actor_dir dir; 27 | }; 28 | 29 | struct actor { 30 | point pos; 31 | float speed; 32 | struct actor_mode old_mode, 33 | active_mode, 34 | intent_mode; 35 | float current_speed; 36 | float elapsed_ms_acc; 37 | }; 38 | 39 | struct tile_pos { 40 | int row; 41 | int col; 42 | }; 43 | 44 | void set_actor_mode(struct actor* actor, 45 | struct actor_mode intent); 46 | 47 | struct tile_pos get_current_tile(struct map_spec* map, 48 | struct actor* actor); 49 | 50 | struct tile_pos get_target_tile(struct map_spec* map, 51 | struct actor* actor, 52 | enum actor_dir intent); 53 | 54 | bool is_actor_in_integral_tile(struct map_spec* map, 55 | struct actor* actor); 56 | 57 | /** 58 | * @brief update_walk 59 | * This function will expects the actor to have its 60 | * intent_dir set to a certain direction and will attempt moving 61 | * its position in that direction for the distance elapsed_ms/actor->speed. 62 | * custom_code will be called 63 | * @param map 64 | * @param actor 65 | * @param elapsed_ms 66 | */ 67 | void 68 | update_actor(struct map_spec* map, struct actor* actor, float elapsed_ms, 69 | int (*is_walkable)(struct map_spec* map, 70 | struct actor* actor, 71 | struct tile_pos pos), 72 | bool (*custom_code)(struct map_spec* map, 73 | struct actor* actor, 74 | float elapsed_ms)); 75 | #endif 76 | -------------------------------------------------------------------------------- /src/keyboard.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef KEYBOARD_H_UQ7XHW8V 23 | #define KEYBOARD_H_UQ7XHW8V 24 | 25 | #include 26 | 27 | #include "begin_prefix.h" 28 | /** 29 | * Checks if a specific key has been pressed. 30 | * @param key Key to test 31 | * 32 | * void update_super_cool_level(void* data, float elapsed_ms) 33 | * { 34 | * if (key_pressed(KB_SPACE)) { 35 | * // do something once per key click 36 | * } 37 | * } 38 | * 39 | * This will return 0 after the first positive test, so 40 | * you will get 1 only once. 41 | * 42 | * @return 1 if the key was pressed or 0 otherwise 43 | */ 44 | int key_pressed( int key ); 45 | 46 | /** 47 | * Check if a specific key is being held down. 48 | * @param key Key to test 49 | * 50 | * void update_super_cool_level(void* data, float elapsed_ms) 51 | * { 52 | * if (key_down(KB_RIGHT)) { 53 | * // do something 54 | * } 55 | * } 56 | * 57 | * This will return 1 as long as the key is being held down. 58 | * 59 | * @return 1 if the key is being held down or 0 otherwise 60 | */ 61 | int key_down( int key ); 62 | 63 | /* Key symbols 64 | */ 65 | extern int KB_SPACE; 66 | extern int KB_RIGHT; 67 | extern int KB_LEFT; 68 | extern int KB_UP; 69 | extern int KB_DOWN; 70 | extern int KB_ESC; 71 | extern int KB_W; 72 | extern int KB_S; 73 | extern int KB_A; 74 | extern int KB_D; 75 | extern int KB_BACK; 76 | 77 | #include "end_prefix.h" 78 | #endif /* end of include guard: KEYBOARD_H_UQ7XHW8V */ 79 | -------------------------------------------------------------------------------- /samples/state/src/state.c: -------------------------------------------------------------------------------- 1 | /* samples / state.c 2 | * ================= 3 | * This sample demonstrates how to use state functions 4 | * to alternate game states. 5 | * 6 | * We begin with including Cage: 7 | */ 8 | #include "cage.h" 9 | 10 | /* State prototypes 11 | * ---------------- 12 | * 13 | * The following function prototypes are the sample 14 | * state functions for an **intro** state and an **outro** state. 15 | */ 16 | static void* create_intro(void); 17 | static void update_intro(void* data, float elapsed_ms); 18 | static void destroy_intro(void* data); 19 | 20 | static void* create_outro(void); 21 | static void update_outro(void* data, float elapsed_ms); 22 | static void destroy_outro(void* data); 23 | 24 | /* Intro state 25 | * ----------- 26 | * 27 | * The first state in the game is the intro state. 28 | * In this state we simply ask the user to press the space key. 29 | * When the key gets pressed, we switch to the outro state. 30 | */ 31 | static void* create_intro(void) 32 | { 33 | screen_color(color_from_RGB(255, 255, 255)); 34 | return create_font("res/font.png", 32, 4); 35 | } 36 | 37 | static void update_intro(void* data, float elapsed_ms) 38 | { 39 | draw_text(data, "Press to continue...", 10, 10); 40 | if (key_pressed(KB_SPACE)) { 41 | game_state(create_outro, update_outro, destroy_outro); 42 | } 43 | UNUSED(elapsed_ms); 44 | } 45 | 46 | static void destroy_intro(void* data) 47 | { 48 | destroy_font(data); 49 | } 50 | 51 | /* Outro state 52 | * ----------- 53 | * 54 | * The second state in the game is the outro state. Once the player press space, 55 | * we use game_state() to change the state using the following three 56 | * state functions. 57 | */ 58 | static void* create_outro(void) 59 | { 60 | screen_color(color_from_RGB(255, 255, 255)); 61 | return create_font("res/font.png", 32, 4); 62 | } 63 | 64 | static void update_outro(void* data, float elapsed_ms) 65 | { 66 | draw_text(data, "Press to exit!", 60, 40); 67 | if (key_pressed(KB_ESC)) { 68 | exit(0); 69 | } 70 | UNUSED(elapsed_ms); 71 | } 72 | 73 | static void destroy_outro(void* data) 74 | { 75 | destroy_font(data); 76 | } 77 | 78 | /* Sample's main 79 | * ------------- 80 | * 81 | * Finally, the game's main function delegates the 82 | * execution to Cage's game_loop() function together with 83 | * the 3 state functions of the intro state. 84 | */ 85 | int main(void) 86 | { 87 | return game_loop(create_intro, update_intro, destroy_intro); 88 | } 89 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef UTILS_H_EZIL3YD2 23 | #define UTILS_H_EZIL3YD2 24 | 25 | #include 26 | 27 | #include "begin_prefix.h" 28 | /* 29 | * M A T H 30 | */ 31 | 32 | /** 1 second is 1000 milliseconds */ 33 | #define SECOND 1000 34 | /** n seconds are n*1000 milliseconds */ 35 | #define SECONDS 1000 36 | 37 | static const double Pi = 3.14159265358979323846264338328; 38 | static const double Pi_2 = 3.14159265358979323846264338328 * 2; 39 | 40 | static __inline float max(float x, float y) 41 | { 42 | return x > y ? x : y; 43 | } 44 | 45 | static __inline float min(float x, float y) 46 | { 47 | return x < y ? x : y; 48 | } 49 | 50 | static __inline float clamp(float x, float bottom, float top) 51 | { 52 | x = max(x, bottom); 53 | x = min(x, top); 54 | return x; 55 | } 56 | 57 | /* 58 | * D E B U G G I N G 59 | */ 60 | 61 | /* Set an error message 62 | */ 63 | #define STRINGIFY(val) #val 64 | #define TOSTRING(val) STRINGIFY(val) 65 | #define AT __FILE__ ":" TOSTRING(__LINE__) 66 | 67 | /** 68 | * error_msg() will append an error message to the error 69 | * string. Cage will display the list of error messages 70 | * if the game state create() function fails. 71 | */ 72 | void error_msg(const char* msg); 73 | 74 | /** 75 | * Using the ERROR() macro will add the filename and 76 | * line number to an error message. 77 | */ 78 | #define ERROR(msg) error_msg(msg " @ " AT) 79 | 80 | /* 81 | * M I S C 82 | */ 83 | 84 | #define UNUSED(x) (void)(x) 85 | 86 | #include "end_prefix.h" 87 | #endif /* end of include guard: UTILS_H_EZIL3YD2 */ 88 | -------------------------------------------------------------------------------- /src/sound.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "sound.h" 23 | #include 24 | 25 | #include "begin_prefix.h" 26 | struct sound* create_sound(const char* filepath) 27 | { 28 | struct sound* sound = (struct sound*)malloc(sizeof(struct sound)); 29 | if (sound != NULL) { 30 | if (load_sound(sound, filepath) == -1) goto error; 31 | sound->channel = -1; 32 | } 33 | return sound; 34 | error: 35 | free(sound); 36 | return NULL; 37 | } 38 | 39 | void destroy_sound(struct sound* sound) 40 | { 41 | if (sound != NULL) { 42 | cleanup_sound(sound); 43 | free(sound); 44 | } 45 | } 46 | 47 | int load_sound(struct sound* sound, const char* pathname) 48 | { 49 | if ((sound->sound = Mix_LoadWAV(pathname)) != NULL) 50 | return 0; 51 | else 52 | return -1; 53 | } 54 | 55 | int play_sound(struct sound* sound, int loops) 56 | { 57 | static int channel = 0; 58 | if (is_playing(sound)) stop_sound(sound); 59 | sound->channel = Mix_PlayChannel(channel, sound->sound, loops); 60 | channel++; 61 | if (channel == CAGE_NUM_OF_MIX_CHANNELS) channel=0; 62 | return sound->channel; 63 | } 64 | 65 | void stop_sound(struct sound* sound) 66 | { 67 | Mix_HaltChannel(sound->channel); 68 | sound->channel = -1; 69 | } 70 | 71 | void cleanup_sound(struct sound* sound) 72 | { 73 | Mix_FreeChunk(sound->sound); 74 | } 75 | 76 | void set_volume(struct sound* sound, float volume) 77 | { 78 | Mix_Volume(sound->channel, volume * MIX_MAX_VOLUME); 79 | } 80 | 81 | int is_playing(struct sound* sound) 82 | { 83 | return (sound->channel != -1); 84 | } 85 | #include "end_prefix.h" 86 | -------------------------------------------------------------------------------- /src/animate.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "animate.h" 23 | #include 24 | #include "begin_prefix.h" 25 | 26 | struct animation* create_animation(void) 27 | { 28 | struct animation* ret = (struct animation*)calloc(1, sizeof(struct animation)); 29 | if (ret != NULL) { 30 | ret->mode = LOOP_FRAMES; 31 | ret->loop_from = -1; 32 | ret->loop_to = -1; 33 | ret->n_frames = 0; 34 | } 35 | return ret; 36 | } 37 | 38 | void add_frame(struct animation* animation, 39 | int index_in_sprite, 40 | int duration, 41 | void* userdata) 42 | { 43 | if (animation->n_frames < MAX_FRAMES_PER_ANIMATION) { 44 | animation->frames[animation->n_frames].frame = index_in_sprite; 45 | animation->frames[animation->n_frames].duration = duration; 46 | animation->frames[animation->n_frames].userdata = userdata; 47 | if (animation->mode == LOOP_FRAMES) { 48 | if (animation->loop_from == -1) { 49 | animation->loop_from = 0; 50 | } 51 | if (animation->loop_to == -1 || 52 | animation->loop_to == animation->n_frames - 1) { 53 | animation->loop_to = animation->n_frames; 54 | } 55 | } 56 | animation->n_frames++; 57 | } 58 | } 59 | 60 | void add_frames(struct animation* animation, int nframes, struct frame frames[]) 61 | { 62 | int i; 63 | for (i = 0; i < nframes; i++) { 64 | add_frame(animation, frames[i].frame, frames[i].duration, 65 | frames[i].userdata); 66 | } 67 | } 68 | 69 | void destroy_animation(struct animation* animation) 70 | { 71 | free(animation); 72 | } 73 | 74 | #include "end_prefix.h" 75 | -------------------------------------------------------------------------------- /src/vec.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef VEC_H_NQUPRW4D 23 | #define VEC_H_NQUPRW4D 24 | #include "begin_prefix.h" 25 | 26 | /** 27 | * 2D vector type for geometric calculation 28 | * and collision detection. 29 | */ 30 | typedef struct { 31 | float x; 32 | float y; 33 | } vec; 34 | 35 | /* make a new vector using x and y values */ 36 | vec xy_vec(float x, float y); 37 | /* break a vector into x and y components */ 38 | #define VEC_XY(vec) vec.x, vec.y 39 | /* make a new vector with x = y = 0 */ 40 | vec zero_vec(void); 41 | /* make a new vector with x = y = 1 */ 42 | vec unit_vec(void); 43 | /* make a new vector using a heading angle */ 44 | vec hdg_vec(float a); 45 | 46 | /* add two vectors, returns the resulting vec */ 47 | vec add_vec(vec v1, vec v2); 48 | /* subtract two vectors, return the resulting vec */ 49 | vec sub_vec(vec v1, vec v2); 50 | /* multiply a vector by a factor, return the resulting vec */ 51 | vec mul_vec(vec v, float f); 52 | /* divide a vector by a factor, return the resulting vec */ 53 | vec div_vec(vec v, float f); 54 | 55 | /* raw (sqrd) vector length */ 56 | float vec_len_sqrd(vec v); 57 | /* vector length (norm) */ 58 | float vec_len(vec v); 59 | /* distance between two vectors */ 60 | float vec_dist(vec v1, vec v2); 61 | /* squared distance between two vectors */ 62 | float vec_dist_sqrd(vec v1, vec v2); 63 | /* Manhattan distance between two vectors, meaning */ 64 | /* the distance between the two vectors when following */ 65 | /* only axis-aligned directions */ 66 | float vec_dist_mntn(vec v1, vec v2); 67 | /* normalize a vector */ 68 | vec norm_vec(vec v); 69 | /* swap two vectors.. */ 70 | void swap_vecs(vec* a, vec* b); 71 | 72 | #include "end_prefix.h" 73 | #endif /* end of include guard: VEC_H_NQUPRW4D */ 74 | -------------------------------------------------------------------------------- /src/file.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef FILE_H_KV23ASZC 23 | #define FILE_H_KV23ASZC 24 | #include "types.h" 25 | #include "begin_prefix.h" 26 | /** 27 | * You can use files to store your players score, progress and settings. 28 | * Various platforms have restrictions on where you can store your game 29 | * files and SDL (and so, CAGE as well) has the functionality to handle this. 30 | */ 31 | struct file_spec 32 | { 33 | /** 34 | * Use file_spec to provide CAGE with the information required to read 35 | * and write files: Your company name (or any other identifier you use), 36 | * your game name and the filename. 37 | */ 38 | const char* company; 39 | const char* game; 40 | const char* filename; 41 | }; 42 | 43 | /** 44 | * Read the full file content and store in a new buffer. Buffer is allocated 45 | * by the read_file and must be freed by the caller. 46 | * @param buf a buffer that will hold the entire file content. To be freed 47 | * by the caller. 48 | * @param file_spec the file specifier to use for reading. 49 | * 50 | * @return number of bytes read or -1 on error. 51 | */ 52 | int read_file(char** buf, 53 | struct file_spec file_spec); 54 | 55 | /** 56 | * Write the full content of buf to a file. File will be rewritten. 57 | * @param file_spec file specifier to use for writing. 58 | * @param buf buf with the content to write. 59 | * 60 | * @return number of bytes written or -1 on error. 61 | */ 62 | int write_file(struct file_spec file_spec, 63 | const char* buf); 64 | 65 | /** 66 | * Check is a file already exists. 67 | * @param file_spec file specifier to check. 68 | * 69 | * @return true if the file is there or false if it isn't. 70 | */ 71 | bool is_file_exists(struct file_spec file_spec); 72 | 73 | #include "end_prefix.h" 74 | #endif /* end of include guard: FILE_H_KV23ASZC*/ 75 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. image:: images/cage.png 2 | :align: right 3 | 4 | Welcome to CAGE 5 | =============== 6 | 7 | CAGE is an elementary game development library. 8 | It was initially designed and developed to help teach 2D game 9 | development using the C programming language. 10 | CAGE prefers readability over flexibility and ease-of-use over 11 | a rich feature set, in the spirit of **less is more**. 12 | 13 | 14 | .. raw:: html 15 | 16 |
17 | 18 | 20 | 21 | 23 | 24 | 25 |
26 | 27 | 28 | As a library, CAGE is just a thin layer on top of SDL2, 29 | the Simple Direct-media Library. CAGE offers the essential 30 | constructs for developing 2D games. It lets you handle images, 31 | sprites, animations, fonts, sounds and other game-specific 32 | entities using a clear and straighforward API. 33 | 34 | The short version 35 | ----------------- 36 | 37 | Here is one of the shortest and most boring game you can write using CAGE: 38 | 39 | .. highlight:: c 40 | 41 | :: 42 | 43 | void* create(void) 44 | { 45 | return (void*)create_font("font.png"); 46 | } 47 | 48 | void update(void* data, float elapsed_ms) 49 | { 50 | draw_text((font*)data, "Hello, World", xy(0, 0)); 51 | } 52 | 53 | void destroy(void* data) 54 | { 55 | destroy_font((font*)data); 56 | } 57 | 58 | int main(int argc, char ** argv) 59 | { 60 | return game_loop(create, update, destroy); 61 | } 62 | 63 | 64 | Yes, there are easier ways to write games, and C may not look like 65 | the best choice. There is no `but` here. LÖVE2D, HaxeFlixer and 66 | Cocos2D are fine examples. 67 | 68 | However, if you enjoy the beauty of C, if you want minimal cognitive burden 69 | and if you want to have long-living, portable code, then CAGE could be 70 | a viable option. 71 | 72 | For the full story all at once, jump over to :doc:`wizard`. 73 | Or, follow along with the docs and learn CAGE step by step. 74 | 75 | .. toctree:: 76 | :hidden: 77 | 78 | start 79 | game 80 | image 81 | font 82 | sprite 83 | animate 84 | timeline 85 | sound 86 | keyboard 87 | mouse 88 | screen 89 | color 90 | file 91 | state_sample 92 | image_sample 93 | sprite_sample 94 | timeline_sample 95 | callout_sample 96 | collisions_sample 97 | chipmunk_sample 98 | wizard 99 | tiled 100 | android 101 | advanced 102 | -------------------------------------------------------------------------------- /src/vec.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "vec.h" 23 | #include 24 | #include "begin_prefix.h" 25 | vec xy_vec(float x, float y) 26 | { 27 | vec v; 28 | v.x = x; 29 | v.y = y; 30 | return v; 31 | } 32 | 33 | vec zero_vec(void) 34 | { 35 | return xy_vec(0, 0); 36 | } 37 | 38 | vec unit_vec(void) 39 | { 40 | return xy_vec(1, 1); 41 | } 42 | 43 | vec hdg_vec(float a) 44 | { 45 | return xy_vec(cos(a), sin(a)); 46 | } 47 | 48 | vec add_vec(vec v1, vec v2) 49 | { 50 | vec v; 51 | v.x = v1.x + v2.x; 52 | v.y = v1.y + v2.y; 53 | return v; 54 | } 55 | 56 | vec sub_vec(vec v1, vec v2) 57 | { 58 | vec v; 59 | v.x = v1.x - v2.x; 60 | v.y = v1.y - v2.y; 61 | return v; 62 | } 63 | 64 | vec mul_vec(vec v, float f) 65 | { 66 | v.x *= f; 67 | v.y *= f; 68 | return v; 69 | } 70 | 71 | vec div_vec(vec v, float f) 72 | { 73 | v.x /= f; 74 | v.y /= f; 75 | return v; 76 | } 77 | 78 | float vec_len_sqrd(vec v) 79 | { 80 | float len = 0.0; 81 | len += v.x * v.x; 82 | len += v.y * v.y; 83 | return len; 84 | } 85 | 86 | float vec_len(vec v) 87 | { 88 | return sqrt(vec_len_sqrd(v)); 89 | } 90 | 91 | float vec_dist(vec v1, vec v2) 92 | { 93 | return sqrt(vec_dist_sqrd(v1, v2)); 94 | } 95 | 96 | float vec_dist_sqrd(vec v1, vec v2) 97 | { 98 | return (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y); 99 | } 100 | 101 | float vec_dist_mntn(vec v1, vec v2) 102 | { 103 | return fabs(v1.x - v2.x) + fabs(v1.y - v2.y); 104 | } 105 | 106 | vec norm_vec(vec v) 107 | { 108 | float len = vec_len(v); 109 | return div_vec(v, len); 110 | } 111 | 112 | void swap_vecs(vec* a, vec* b) 113 | { 114 | vec tmp = *a; 115 | a->x = b->x; 116 | a->y = b->y; 117 | b->x = tmp.x; 118 | b->y = tmp.y; 119 | } 120 | #include "end_prefix.h" 121 | -------------------------------------------------------------------------------- /src/file.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "file.h" 23 | #include "SDL.h" 24 | 25 | #define MAX_PATH_LEN 1024 26 | 27 | #include "begin_prefix.h" 28 | static void make_game_path(char* full_path, struct file_spec file_spec) 29 | { 30 | char* perf_path = SDL_GetPrefPath(file_spec.company, file_spec.game); 31 | strncat(full_path, perf_path, MAX_PATH_LEN); 32 | strncat(full_path, "/", MAX_PATH_LEN); 33 | strncat(full_path, file_spec.filename, MAX_PATH_LEN); 34 | SDL_free(perf_path); 35 | } 36 | 37 | bool is_file_exists(struct file_spec file_spec) 38 | { 39 | char full_path[MAX_PATH_LEN + 1] = ""; 40 | make_game_path(full_path, file_spec); 41 | SDL_RWops* rw = SDL_RWFromFile(full_path, "r"); 42 | if (rw == NULL) return false; 43 | SDL_RWclose(rw); 44 | return true; 45 | } 46 | 47 | int read_file(char** buf, struct file_spec file_spec) 48 | { 49 | char full_path[MAX_PATH_LEN + 1] = ""; 50 | make_game_path(full_path, file_spec); 51 | SDL_RWops* rw = SDL_RWFromFile(full_path, "r"); 52 | if (rw == NULL) return -1; 53 | 54 | Sint64 res_size = SDL_RWsize(rw); 55 | *buf = (char*)malloc(res_size + 1); 56 | 57 | Sint64 nb_read_total = 0, nb_read = 1; 58 | char* buf_ = *buf; 59 | while (nb_read_total < res_size && nb_read != 0) { 60 | nb_read = SDL_RWread(rw, buf_, 1, (res_size - nb_read_total)); 61 | nb_read_total += nb_read; 62 | buf_ += nb_read; 63 | } 64 | SDL_RWclose(rw); 65 | if (nb_read_total != res_size) { 66 | free(*buf); 67 | return -1; 68 | } 69 | 70 | *buf[nb_read_total] = '\0'; 71 | return nb_read_total; 72 | } 73 | 74 | int write_file(struct file_spec file_spec, const char* buf) 75 | { 76 | char full_path[MAX_PATH_LEN + 1] = ""; 77 | make_game_path(full_path, file_spec); 78 | SDL_RWops* rw = SDL_RWFromFile(full_path, "w"); 79 | if (rw != NULL) { 80 | size_t len = SDL_strlen(buf); 81 | if (SDL_RWwrite(rw, buf, 1, len) != len) { 82 | SDL_RWclose(rw); 83 | return -1; 84 | } 85 | SDL_RWclose(rw); 86 | return len; 87 | } else 88 | return -1; 89 | } 90 | #include "end_prefix.h" 91 | -------------------------------------------------------------------------------- /linux.mk: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | 22 | 23 | # Include this makefile from your project to build your game 24 | # using CAGE. Put this in your Makefile: 25 | # 26 | # GAME_BUILD_PATH = build/linux 27 | # GAME_BINARY = your-game 28 | # include deps/cage/linux.mk 29 | # 30 | MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) 31 | CURRENT_DIR := $(dir $(MKFILE_PATH)) 32 | CC = gcc # or clang 33 | CFLAGS = `sdl2-config --cflags` -I$(CURRENT_DIR)/src/ -c 34 | # Flip the optimization flag if you want to debug. 35 | CFLAGS += -O3 36 | # CFLAGS += -g3 37 | ifeq ($(UNAME_S),Linux) 38 | # Note, CAGE is c89 compliant, but your game doesn't have to be. 39 | # Feel free to change this as needed. 40 | CFLAGS += -std=c89 41 | endif 42 | WARNINGS = -Werror -Wall -Wextra -pedantic-errors -Wformat=2 -Wno-import \ 43 | -Wimplicit -Wmain -Wchar-subscripts -Wsequence-point \ 44 | -Wmissing-braces -Wparentheses -Winit-self -Wswitch-enum \ 45 | -Wstrict-aliasing=2 -Wundef -Wshadow -Wpointer-arith \ 46 | -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings \ 47 | -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes \ 48 | -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \ 49 | -Wdisabled-optimization -Wunused-macros -Wno-unused 50 | LDFLAGS = 51 | LIBRARIES = `sdl2-config --libs` -L$(CURRENT_DIR)/build/ -lSDL2_image \ 52 | -lSDL2_mixer -lcage -lm 53 | SOURCES = $(wildcard src/*.c) 54 | OBJECTS = $(addprefix obj/,$(patsubst src/%,%,$(SOURCES:.c=.o) ) ) 55 | 56 | NO_COLOR=\x1b[0m 57 | INFO_COLOR=\x1b[35;01m 58 | 59 | .PHONY: all 60 | 61 | all: $(GAME_BUILD_PATH)/$(GAME_BINARY) resources 62 | 63 | $(CURRENT_DIR)/build/libcage.a: 64 | @cd $(CURRENT_DIR) && make build/libcage.a 65 | 66 | $(GAME_BUILD_PATH)/$(GAME_BINARY): $(OBJECTS) $(CURRENT_DIR)/build/libcage.a 67 | @mkdir -p build 68 | @echo -e "Building $(INFO_COLOR)$(GAME_BUILD_PATH)$(GAME_BINARY)$(NO_COLOR)" 69 | @$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBRARIES) 70 | @echo "Done!" 71 | 72 | obj/%.o: src/%.c 73 | @mkdir -p obj 74 | @echo -e "Building $(INFO_COLOR)$@$(NO_COLOR)" 75 | @$(CC) $< -o $@ $(CFLAGS) $(WARNINGS) 76 | 77 | resources: 78 | @cp -rf res $(GAME_BUILD_PATH) 79 | 80 | clean: 81 | rm -rf $(GAME_BUILD_PATH)$(GAME_BINARY) $(OBJECTS) $(GAME_BUILD_PATH)/res 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CAGE](https://raw.githubusercontent.com/rlofc/rlofc.github.com/master/cage/_images/cage.png) (CAGE Ain't a Game Engine) 2 | ============================================================================================= 3 | 4 | CAGE is an elementary game development library, written in the spirit of less is more (or 5 | worse is better). CAGE favors readability over flexibility and 6 | ease-of-use over a rich set of features (read: it's barely 7 | usable). 8 | 9 | ![CAGE Screenshots](https://github.com/rlofc/rlofc.github.com/raw/master/cage/docs/_images/cage-samples.png) 10 | 11 | CAGE makes it easier to write 2D games using C by 12 | adding a very thin layer on top of SDL2. 13 | CAGE has just enough to help you build your game faster, 14 | but if you want to, it lets you to reach inside and hack anything you need. 15 | 16 | I initially wrote CAGE to help me teach my kids game development using 17 | C. I wanted to have a native library by which I can introduce them 18 | to the nuts and bolts of software engineering. 19 | While still trying to do so, I'm now also using the library 20 | to write actual games, the first being 21 | [Spy Game Over](https://forums.tigsource.com/index.php?topic=52287.0). 22 | 23 | ### Highlights 24 | 25 | * Plain C - No abstractions, no distractions. 26 | * Easy to learn - Simple, readable and well documented code. 27 | * Useful samples - Code you can learn from and use in your own games. 28 | * It's just a library - You are in control. Hack, mix-in, 29 | and bring your own libraries. It's your code. 30 | * SDL2 inside - Runs on **Windows**, **Linux**, **Mac/OSX**, **iOS** and **Android**, can potentially do anything SDL can 31 | 32 | ### Library Features 33 | 34 | * Sprite animation - Animate sequences of frames in image files. 35 | * Timelines - Sequence Time-driven event callbacks for story-telling and effects. 36 | * Game states - Helps your game have a scalable internal structure. 37 | * Bitmap fonts, sound playback, file reading and 38 | writing, yada yada. 39 | 40 | ### Getting Started 41 | 42 | First, clone the repo: 43 | 44 | git clone https://github.com/rlofc/cage.git 45 | 46 | To use CAGE you will need SDL2, SDL2_Image and SDL2_Mixer. 47 | 48 | For **Windows**, run `getSDL2.bat` inside the `3rdparty` folder. 49 | 50 | If you're using **Mac OS/X**, you can use brew: 51 | 52 | brew install SDL2 SDL2_Image SDL2_Mixer 53 | 54 | In **Arch Linux**, use pacman: 55 | 56 | sudo pacman -S sdl2 sdl2_image sdl2_mixer 57 | 58 | 59 | Once you have SDL2, SDL2_Mixer and SDL2_Image, you can build CAGE and run the 60 | Wizard sample. 61 | 62 | In **Windows**, open the Visual Studio 2013 project inside the `vc` folder of CAGE 63 | and build the solution. You will find the Wizard executable inside `vc\Debug` or `vc\Release`. 64 | 65 | In **Mac OS/X** or **Linux**, simply: 66 | 67 | cd cage && make 68 | 69 | 70 | ### Documentation 71 | 72 | The docs are still work-in-progress: 73 | 74 | [http://rlofc.github.io/cage/docs](http://rlofc.github.io/cage/docs) 75 | 76 | All samples are written using using literate programming. 77 | 78 | For a not-so-basic example, check out the Wizard sample code: 79 | [http://rlofc.github.io/cage/docs/wizard.html](http://rlofc.github.io/cage/docs/wizard.html) 80 | 81 | ### License 82 | 83 | CAGE is licensed under the **zlib license**. 84 | -------------------------------------------------------------------------------- /docs/source/game.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: c 2 | 3 | Game essentials 4 | =============== 5 | 6 | The heart of almost every game is the game loop. The game 7 | loop processes events, runs the game logic and generates the 8 | game visuals and sounds. 9 | 10 | .. image:: images/cage-callbacks.png 11 | :align: center 12 | 13 | game_loop 14 | --------- 15 | .. doxygenfunction:: game_loop 16 | 17 | To run its game loop, CAGE must have a game state. The 18 | game state is created, updated and destroyed using three pointers to three functions: 19 | 20 | create function 21 | -------------------- 22 | .. doxygentypedef:: create_func_t 23 | 24 | 25 | update function 26 | -------------------- 27 | .. doxygentypedef:: update_func_t 28 | 29 | 30 | destroy function 31 | -------------------- 32 | .. doxygentypedef:: destroy_func_t 33 | 34 | 35 | 36 | The state functions share a common feature - the state data 37 | argument. The create function creates a state and returns 38 | a valid data pointer. The common pattern is to 39 | have a dedicated struct per state that holds all required 40 | state assets. 41 | 42 | The update function will get the same state data pointer 43 | back, so it is able to use it to update and draw the game. 44 | 45 | The destroy function will also get the same user data 46 | pointer, this time it will usually use it to clean any 47 | allocated assets. 48 | 49 | Games will usually have different levels, menus, high score 50 | displays and the likes. These are represented as different 51 | game states. 52 | 53 | .. image:: images/cage-gamestates.png 54 | :align: center 55 | 56 | Transitioning between different states allow you 57 | to have a more complex game structure. Use game_state() to change 58 | the active game state using a new set of state functions: 59 | 60 | game_state 61 | ---------- 62 | .. doxygenfunction:: game_state 63 | 64 | 65 | For example: 66 | 67 | :: 68 | 69 | // These are the level state functions 70 | void* create_level(void) 71 | { 72 | struct level_data* data = malloc(sizeof(struct level_data)); 73 | return level_data; 74 | } 75 | 76 | void update_level(void* data, float elapsed_ms) 77 | { 78 | // Update and draw your game 79 | } 80 | 81 | void destroy_level(void* data) 82 | { 83 | // Put any cleanup code here... 84 | free(data); 85 | } 86 | 87 | // These are the game menu state functions 88 | void* create_menu(void) 89 | { 90 | struct menu_data* data = malloc(sizeof(struct menu_data)); 91 | return menu_data; 92 | } 93 | 94 | void update_menu(void* data, float elapsed_ms) 95 | { 96 | // Handle the menu behavior. 97 | // When ready, switch to the level game state: 98 | game_state(create_level, update_level, destroy_level); 99 | } 100 | 101 | void destroy_menu(void* data) 102 | { 103 | // Put any cleamup code here... 104 | free(data); 105 | } 106 | 107 | // This is your game! 108 | int main(int argc, char ** argv) 109 | { 110 | // Set up the initial game state 111 | return game_loop(create_menu, update_menu, destroy_menu); 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/screen.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "screen.h" 23 | #include "easing.h" 24 | #include "internals.h" 25 | #include "utils.h" 26 | #include 27 | 28 | #include "begin_prefix.h" 29 | static struct screen global_screen; 30 | struct screen* screen = &global_screen; 31 | 32 | struct cam { 33 | float progress; 34 | float tgt; 35 | }; 36 | 37 | static struct cam cam_x = { 0.0f, 0.0f }; 38 | static struct cam cam_y = { 0.0f, 0.0f }; 39 | 40 | static float animate_shake(struct cam* cam, float stopwatch, float rate) 41 | { 42 | float offset; 43 | float interp = 44 | interpolate(cam->tgt * -1.0f, cam->tgt, cam->progress, sine_ease_in_out); 45 | offset = cam->tgt * -1 + fabs(interp); 46 | cam->progress = clamp(cam->progress + (stopwatch / rate), 0.0f, 1.0f); 47 | ; 48 | if (cam->progress == 1.0f) { 49 | cam->progress = 0.0f; 50 | } 51 | return offset; 52 | } 53 | 54 | void shake_screen(float stopwatch) 55 | { 56 | if (cam_x.progress == 0.0f) { 57 | cam_x.tgt = (rand() % 2) + 2; 58 | } 59 | screen->offset_x = animate_shake(&cam_x, stopwatch, 100.0f); 60 | if (cam_y.progress == 0.0f) { 61 | cam_y.tgt = (rand() % 2) + 2; 62 | } 63 | screen->offset_y = animate_shake(&cam_y, stopwatch, 100.0f); 64 | } 65 | 66 | void relax_screen(float stopwatch) 67 | { 68 | if (cam_x.progress != 0.0f) 69 | screen->offset_x = animate_shake(&cam_x, stopwatch, 500.0f); 70 | if (cam_y.progress != 0.0f) 71 | screen->offset_y = animate_shake(&cam_y, stopwatch, 500.0f); 72 | } 73 | 74 | void screen_color(struct color bg) 75 | { 76 | SDL_SetRenderDrawColor(screen->impl, bg.red, bg.green, bg.blue, bg.alpha); 77 | } 78 | 79 | void draw_on_screen(void) 80 | { 81 | int ret = SDL_SetRenderTarget(screen->impl, NULL); 82 | if (ret != 0) exit(1); 83 | } 84 | 85 | void set_screen_size(int width, int height) 86 | { 87 | SDL_RenderSetLogicalSize(screen->impl, width, height); 88 | } 89 | 90 | void get_screen_size(int* width, int* height) 91 | { 92 | SDL_RenderGetLogicalSize(screen->impl, width, height); 93 | } 94 | 95 | void set_window_size(int width, int height) 96 | { 97 | SDL_SetWindowSize(screen->window, width, height); 98 | } 99 | 100 | void get_window_size(int* width, int* height) 101 | { 102 | SDL_GetWindowSize(screen->window, width, height); 103 | } 104 | #include "end_prefix.h" 105 | -------------------------------------------------------------------------------- /src/sound.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef AUDIO_H_IJ4N19XA 23 | #define AUDIO_H_IJ4N19XA 24 | #include "SDL_mixer.h" 25 | #define CAGE_NUM_OF_MIX_CHANNELS 16 26 | #include "begin_prefix.h" 27 | /** 28 | * Sound effect 29 | */ 30 | struct sound { 31 | /** Internal SDL2_Mixer sound chunk */ 32 | Mix_Chunk* sound; 33 | /** When playing, channel number in SDL2_Mixer */ 34 | int channel; 35 | }; 36 | 37 | /** 38 | * Create a new sound effect from an OGG, WAV or MP3 file 39 | * 40 | * @return a \ref sound effect resource or NULL on error 41 | */ 42 | struct sound* create_sound(const char* filepath); 43 | 44 | /** 45 | * Cleanup and deallocate a sound effect 46 | * @param sound sound effect to cleanup and free 47 | */ 48 | void destroy_sound(struct sound* sound); 49 | 50 | /** 51 | * Initialize an already allocated sound effect 52 | * @param sound \ref sound instance to use 53 | * @param filepath file path to the sound file in ogg, wav or mp3 format 54 | * 55 | * The sound file will be loaded and stored 56 | * for use in the \ref sound effect. 57 | * 58 | * @return 0 or higher on success or -1 or lower on failure 59 | */ 60 | int load_sound(struct sound* sound, const char* filepath); 61 | 62 | /** 63 | * Play sound effect 64 | * @param sound sound effect to play 65 | * @param loops -1 - infinite, 0 - play once, 1 - twice and so on.. 66 | * 67 | * Will play an initialized sound effect 68 | * 69 | * @return 0 or higher means success 70 | * -1 or lower means failure 71 | */ 72 | int play_sound(struct sound* sound, int loops); 73 | 74 | /** 75 | * Stop playing a sound 76 | * @param sound sound effect to stop playing 77 | */ 78 | void stop_sound(struct sound* sound); 79 | 80 | /** 81 | * Internally cleanup an initialized sound effect 82 | * @param sound sound effect to cleanup 83 | */ 84 | void cleanup_sound(struct sound* sound); 85 | 86 | /** 87 | * Set the volume of a sound effect 88 | * @param sound sound effect to modify 89 | * @param volume volume value between 0.0 and 1.0 90 | */ 91 | void set_volume(struct sound* sound, float volume); 92 | 93 | /** 94 | * Test if a sound effect is playing 95 | * @param sound sound effect to test 96 | * 97 | * @return 1 if the sound effect is being played or 0 otherwise 98 | */ 99 | int is_playing(struct sound* sound); 100 | 101 | #include "end_prefix.h" 102 | #endif /* end of include guard: AUDIO_H_IJ4N19XA */ 103 | -------------------------------------------------------------------------------- /samples/sprite/src/sprite.c: -------------------------------------------------------------------------------- 1 | /* samples / sprite.c 2 | * ================== 3 | * 4 | * In this example we create a wizard sprite and a walk cycle 5 | * animation. We then animate the sprite and draw it on screen. 6 | */ 7 | #include "cage.h" 8 | 9 | /* The sprite struct 10 | * ----------------- 11 | * 12 | * This is our wizard struct. It holds the wizard 13 | * sprite resource and the walk cycle animation resource. 14 | * In this sample, we use a static variable instead of dynamically 15 | * allocating an instance. 16 | */ 17 | static struct wizard { 18 | struct sprite* sprite; 19 | struct animation* walk_cycle; 20 | } wizard = { NULL, NULL }; 21 | static void* create_sample(void); 22 | static void destroy_sample(void* data); 23 | 24 | /* Prepare the sprite 25 | * ------------------ 26 | * 27 | * We use the game state create() function to create the sprite 28 | * using an image resource, as well as the animation resource 29 | * for the walk cycle. 30 | * If no errors are encountered, we proceed to add frames to 31 | * the walk cycle animation. 32 | * Finally, we play the animation, making it active for the 33 | * sprite. 34 | * Notice the way we use a static variable to hold the wizard 35 | * struct and use its pointer as the create() function return 36 | * value. 37 | */ 38 | static void* create_sample(void) 39 | { 40 | wizard.sprite = create_sprite(create_image("res/wizard.png"), 32, 32); 41 | if (wizard.sprite == NULL) goto error; 42 | wizard.walk_cycle = create_animation(); 43 | if (wizard.walk_cycle == NULL) 44 | goto error; 45 | else { 46 | struct frame frames[] = { { 0, 300, NULL }, 47 | { 1, 300, NULL }, 48 | { 2, 300, NULL }, 49 | { 3, 300, NULL } }; 50 | add_frames(wizard.walk_cycle, 4, frames); 51 | wizard.walk_cycle->loop_from = 0; 52 | wizard.walk_cycle->loop_to = 3; 53 | } 54 | play_animation(wizard.sprite, wizard.walk_cycle); 55 | return &wizard; 56 | error: 57 | destroy_sample(&wizard); 58 | return NULL; 59 | } 60 | 61 | /* Animate & draw 62 | * -------------- 63 | * 64 | * During the game, the update function uses the wizard 65 | * data to animate and draw the sprite. The elapsed_ms 66 | * argument is used by the animate_sprite() function so it 67 | * can track how long to play each animation frame. 68 | */ 69 | static void update_sample(void* data, float elapsed_ms) 70 | { 71 | struct wizard* w = data; 72 | animate_sprite(w->sprite, elapsed_ms); 73 | draw_sprite(w->sprite, 10, 10); 74 | } 75 | 76 | /* Clean-up 77 | * -------- 78 | * 79 | * Before exiting a state (or the game), Cage 80 | * will call the destroy function. Having allocated 3 resources 81 | * earlier in the create function, now is the time to clean up 82 | * by matching each create with a destory call. 83 | */ 84 | static void destroy_sample(void* data) 85 | { 86 | struct wizard* w = data; 87 | destroy_image(w->sprite->image); 88 | destroy_sprite(w->sprite); 89 | destroy_animation(w->walk_cycle); 90 | } 91 | 92 | /* Main 93 | * ---- 94 | * 95 | * Finally, the game's main function delegates the 96 | * execution to the game_loop() function together with 97 | * the 3 state functions we wrote. 98 | */ 99 | int main(void) 100 | { 101 | return game_loop(create_sample, update_sample, destroy_sample); 102 | } 103 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 Ithai Levi @RLofC 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | CC = gcc 22 | CFLAGS = `sdl2-config --cflags` -c 23 | DEBUG ?= 0 24 | ifeq (DEBUG, 1) 25 | CFLAGS += -g3 26 | else 27 | CFLAGS += -O3 28 | endif 29 | ifeq ($(UNAME_S),Linux) 30 | CFLAGS += -std=c89 31 | endif 32 | WARNINGS = -Wall -Wno-unused-label 33 | SOURCES = $(wildcard src/*.c) 34 | OBJECTS = $(addprefix obj/,$(patsubst src/%,%,$(SOURCES:.c=.o) ) ) 35 | LIBRARY = build/libcage.a 36 | 37 | NO_COLOR=\x1b[0m 38 | INFO_COLOR=\x1b[35;01m 39 | 40 | .PHONY: all 41 | 42 | all: $(LIBRARY) extra 43 | 44 | $(LIBRARY): $(OBJECTS) 45 | @mkdir -p build 46 | @echo -e "Archiving $(INFO_COLOR)$(LIBRARY)$(NO_COLOR)" 47 | @ar rcs $(LIBRARY) $(OBJECTS) 48 | @echo "Done!" 49 | 50 | obj/%.o: src/%.c 51 | @mkdir -p obj 52 | @echo -e "Building $(INFO_COLOR)$@$(NO_COLOR)" 53 | @$(CC) $< -o $@ $(CFLAGS) $(WARNINGS) 54 | 55 | clean: 56 | @cd samples/state && $(MAKE) clean 57 | @cd samples/image && $(MAKE) clean 58 | @cd samples/sprite && $(MAKE) clean 59 | @cd samples/timeline && $(MAKE) clean 60 | @cd samples/callout && $(MAKE) clean 61 | @cd samples/collisions && $(MAKE) clean 62 | @cd samples/wizard && $(MAKE) clean 63 | @cd samples/chipmunk && $(MAKE) clean 64 | @cd samples/tiled && $(MAKE) clean 65 | @rm -rf $(LIBRARY) $(OBJECTS) 66 | @rm -rf docs/build 67 | 68 | doc: 69 | @echo "Generating docs.." 70 | @awk -f literst.awk samples/state/src/state.c > docs/source/state_sample.rst 71 | @awk -f literst.awk samples/image/src/image.c > docs/source/image_sample.rst 72 | @awk -f literst.awk samples/sprite/src/sprite.c > docs/source/sprite_sample.rst 73 | @awk -f literst.awk samples/timeline/src/timeline.c > docs/source/timeline_sample.rst 74 | @awk -f literst.awk samples/callout/src/callout.c > docs/source/callout_sample.rst 75 | @awk -f literst.awk samples/collisions/src/collisions.c > docs/source/collisions_sample.rst 76 | @awk -f literst.awk samples/wizard/src/wizard.c > docs/source/wizard.rst 77 | @awk -f literst.awk samples/chipmunk/src/chipmunk.c > docs/source/chipmunk_sample.rst 78 | @awk -f literst.awk samples/tiled/src/tiled.c > docs/source/tiled.rst 79 | @doxygen cage 80 | @cp -Rf build/doxygen docs/build 81 | @cd docs && make html 82 | 83 | extra: $(LIBRARY) 84 | cd samples/state && $(MAKE) DEBUG=$(DEBUG) 85 | cd samples/image && $(MAKE) DEBUG=$(DEBUG) 86 | cd samples/sprite && $(MAKE) DEBUG=$(DEBUG) 87 | cd samples/timeline && $(MAKE) DEBUG=$(DEBUG) 88 | cd samples/callout && $(MAKE) DEBUG=$(DEBUG) 89 | cd samples/collisions && $(MAKE) DEBUG=$(DEBUG) 90 | cd samples/wizard && $(MAKE) DEBUG=$(DEBUG) 91 | cd samples/chipmunk && $(MAKE) DEBUG=$(DEBUG) 92 | cd samples/tiled && $(MAKE) DEBUG=$(DEBUG) 93 | -------------------------------------------------------------------------------- /src/font.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef FONT_H_XYTHJIBT 23 | #define FONT_H_XYTHJIBT 24 | 25 | #include "geometry.h" 26 | #include "image.h" 27 | 28 | #include "begin_prefix.h" 29 | #define MAX_FONT_CHARS 256 30 | 31 | /** 32 | * Use bitmap fonts to draw text 33 | * Bitmap fonts are made from images with a 34 | * matrix of characters in ascii order. 35 | */ 36 | struct font { 37 | /** font characters image */ 38 | struct image image; 39 | /** SDL character boundries */ 40 | struct rectangle chars_rects[MAX_FONT_CHARS]; 41 | /** line height */ 42 | int line_height; 43 | /** height of spacing between lines */ 44 | int line_spacing; 45 | /** width of a single space character */ 46 | int space_width; 47 | /** width of spacing between characters */ 48 | int char_spacing; 49 | }; 50 | 51 | /** 52 | * Create a new font from an image file 53 | * @param filepath Image to use for font 54 | * @param cols Number of columns in the font bitmap image. 55 | * @param rows Number of rows in the font bitmap image. 56 | * 57 | * @return New font, ready to use 58 | */ 59 | struct font* create_font(const char* filepath, int cols, int rows); 60 | 61 | /** 62 | * Destory an existing font 63 | * @param font Font to cleanup and deallocate 64 | */ 65 | void destroy_font(struct font* font); 66 | 67 | /** 68 | * Build a font from a font image file containing 16x16 (256) characters 69 | * @param font Font resource to generate 70 | * @param filepath font image to load 71 | * @param cols Number of columns in the font bitmap 72 | * @param rows Number of rows in the font bitmap 73 | * 74 | * @return -1 on error 75 | */ 76 | int load_font(struct font* font, const char* filepath, int cols, int rows); 77 | 78 | /** 79 | * Free any internally allocated resources for the font 80 | * @param font Font to cleanup 81 | * 82 | * @return -1 on error 83 | */ 84 | int cleanup_font(struct font* font); 85 | 86 | /** 87 | * Use font to render text 88 | * @param font Font to use 89 | * @param text text to render 90 | * @param x x coordinates 91 | * @param y y coordinates 92 | */ 93 | void draw_text(struct font* font, const char* text, int x, int y); 94 | 95 | /** 96 | * Measure the expected width and height of some text using a font 97 | * @param font Font to use 98 | * @param text text to render 99 | * @param width a pointer to where the width will be stored 100 | * @param height a pointer to where the height will be stored 101 | */ 102 | void measure_text(struct font* font, const char* text, int* width, int* height); 103 | 104 | #include "end_prefix.h" 105 | #endif /* end of include guard: FONT_H_XYTHJIBT */ 106 | -------------------------------------------------------------------------------- /vc/Cage/Cage.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/end_prefix.h: -------------------------------------------------------------------------------- 1 | #ifdef CAGE_PREFIX 2 | #undef ADD 3 | #undef BLEND 4 | #undef FREEZE_LAST_FRAME 5 | #undef LOOP_FRAMES 6 | #undef MULTIPLY 7 | #undef NONE 8 | #undef PINGPONG_FRAMES 9 | #undef add_frame 10 | #undef add_frames 11 | #undef add_vec 12 | #undef animate_sprite 13 | #undef animation 14 | #undef animation_mode 15 | #undef append_event 16 | #undef append_events 17 | #undef back_ease_in 18 | #undef back_ease_in_out 19 | #undef back_ease_out 20 | #undef bbox_in_bbox 21 | #undef bbox_intersect 22 | #undef blend_mode 23 | #undef bounce_ease_in 24 | #undef bounce_ease_in_out 25 | #undef bounce_ease_out 26 | #undef circular_ease_in 27 | #undef circular_ease_in_out 28 | #undef circular_ease_out 29 | #undef cleanup_font 30 | #undef cleanup_image 31 | #undef cleanup_sound 32 | #undef cleanup_sprite 33 | #undef cleanup_timeline 34 | #undef clear_image 35 | #undef color 36 | #undef color_from_RGB 37 | #undef color_from_RGBA 38 | #undef coords 39 | #undef create_animation 40 | #undef create_blank_image 41 | #undef create_font 42 | #undef create_image 43 | #undef create_sound 44 | #undef create_sprite 45 | #undef create_target_image 46 | #undef create_timeline 47 | #undef cubic_ease_in 48 | #undef cubic_ease_in_out 49 | #undef cubic_ease_out 50 | #undef destroy_animation 51 | #undef destroy_font 52 | #undef destroy_image 53 | #undef destroy_sound 54 | #undef destroy_sprite 55 | #undef destroy_timeline 56 | #undef div_vec 57 | #undef draw_image 58 | #undef draw_on_image 59 | #undef draw_on_screen 60 | #undef draw_sprite 61 | #undef draw_sprite_frame 62 | #undef draw_text 63 | #undef elastic_ease_in 64 | #undef elastic_ease_in_out 65 | #undef elastic_ease_out 66 | #undef error_msg 67 | #undef exit_with_error_msg 68 | #undef exponential_ease_in 69 | #undef exponential_ease_in_out 70 | #undef exponential_ease_out 71 | #undef file_spec 72 | #undef font 73 | #undef frame 74 | #undef game_loop 75 | #undef game_setup_and_loop 76 | #undef game_state 77 | #undef get_error_msgs 78 | #undef get_image_alpha 79 | #undef get_screen_size 80 | #undef get_window_size 81 | #undef hdg_vec 82 | #undef image 83 | #undef init_image_from_file 84 | #undef init_timeline 85 | #undef interpolate 86 | #undef is_file_exists 87 | #undef is_playing 88 | #undef key_down 89 | #undef key_pressed 90 | #undef keyboard 91 | #undef linear_interpolation 92 | #undef load_font 93 | #undef load_sound 94 | #undef lock_image 95 | #undef measure_text 96 | #undef message_box 97 | #undef mouse 98 | #undef mul_vec 99 | #undef norm_vec 100 | #undef pause_timeline 101 | #undef pixels_collide 102 | #undef play_animation 103 | #undef play_sound 104 | #undef point_in_bbox 105 | #undef prepare_sprite 106 | #undef quadratic_ease_in 107 | #undef quadratic_ease_in_out 108 | #undef quadratic_ease_out 109 | #undef quartic_ease_in 110 | #undef quartic_ease_in_out 111 | #undef quartic_ease_out 112 | #undef quintic_ease_in 113 | #undef quintic_ease_in_out 114 | #undef quintic_ease_out 115 | #undef read_file 116 | #undef rect_from_sub_bbox 117 | #undef rectangle 118 | #undef relax_screen 119 | #undef reset_timeline 120 | #undef screen 121 | #undef screen_color 122 | #undef set_blend_mode 123 | #undef set_image_alpha 124 | #undef set_screen_blend_mode 125 | #undef set_screen_size 126 | #undef set_volume 127 | #undef set_window_size 128 | #undef settings 129 | #undef shake_screen 130 | #undef sine_ease_in 131 | #undef sine_ease_in_out 132 | #undef sine_ease_out 133 | #undef sound 134 | #undef sprite 135 | #undef stop_animation 136 | #undef stop_sound 137 | #undef sub_vec 138 | #undef swap_vecs 139 | #undef timeline 140 | #undef timeline_event 141 | #undef toolbox 142 | #undef translate_bbox 143 | #undef unit_vec 144 | #undef unlock_image 145 | #undef update_mouse 146 | #undef update_timeline 147 | #undef vec_dist 148 | #undef vec_dist_mntn 149 | #undef vec_dist_sqrd 150 | #undef vec_len 151 | #undef vec_len_sqrd 152 | #undef write_file 153 | #undef xy_vec 154 | #undef zero_vec 155 | #endif 156 | -------------------------------------------------------------------------------- /src/animate.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef ANIMATE_H_QVL0GFIR 23 | #define ANIMATE_H_QVL0GFIR 24 | #include "begin_prefix.h" 25 | 26 | #define MAX_FRAMES_PER_ANIMATION 256 27 | 28 | /** Animation playback mode */ 29 | enum animation_mode { 30 | /** Loop back to loop_from */ 31 | LOOP_FRAMES, 32 | /** go back in reverse and then return endlessly */ 33 | PINGPONG_FRAMES, 34 | /** stop at the last frame */ 35 | FREEZE_LAST_FRAME, 36 | }; 37 | 38 | /** Animation frame */ 39 | struct frame { 40 | /** frame number (top-left frame is 0) */ 41 | int frame; 42 | /** duration of frame in milliseconds */ 43 | int duration; 44 | /** user data */ 45 | void* userdata; 46 | }; 47 | 48 | /** Animation frames and durations for a sprite. 49 | * You may use the same animation definition 50 | * for any number of sprites: 51 | * 52 | * struct animation* walk = create_animation(); 53 | * 54 | * add_frame(walk, 0, 50, NULL); 55 | * add_frame(walk, 1, 100, NULL); 56 | * add_frame(walk, 2, 50,NULL); 57 | * 58 | * ... 59 | * play_animation(zombie, walk); 60 | * ... 61 | * play_animation(robot, walk); 62 | * 63 | * 64 | * You may also associate custom data with specific 65 | * key frames. 66 | * 67 | */ 68 | struct animation { 69 | /* frames */ 70 | struct frame frames[MAX_FRAMES_PER_ANIMATION]; 71 | /* number of frames for this animation */ 72 | int n_frames; 73 | /* Animation playback mode */ 74 | enum animation_mode mode; 75 | /* when mode is LOOP_FRAMES, where to loop from */ 76 | int loop_from; 77 | int loop_to; 78 | }; 79 | 80 | /** 81 | * Create a new animation. 82 | * 83 | * @return New animation instance, ready to have frames 84 | * added using add_frame(). 85 | */ 86 | struct animation* create_animation(void); 87 | 88 | /** 89 | * Destory a previously created animation. 90 | * @param animation A previously created /ref animation to deallocate. 91 | */ 92 | void destroy_animation(struct animation* animation); 93 | 94 | /** 95 | * Add a new frame to an \ref animation 96 | * @param animation Animation to add the frame to 97 | * @param index_in_sprite The frame index in the sprite frames image 98 | * @param duration The time in milliseconds to play this frame 99 | * @param userdata Any data you would like to associate with this frame 100 | * You will get this data pointer back when this frame gets played 101 | */ 102 | void add_frame(struct animation* animation, 103 | int index_in_sprite, 104 | int duration, 105 | void* userdata); 106 | 107 | /** 108 | * Add a new set of frames to an \ref animation. 109 | * @param animation Animation to add the frame to 110 | * @param nframes Number of frames to add 111 | * @param frames The frames to add as an array of \ref frame structs 112 | */ 113 | void add_frames(struct animation* animation, 114 | int nframes, 115 | struct frame frames[]); 116 | 117 | #include "end_prefix.h" 118 | #endif /* end of include guard: ANIMATE_H_QVL0GFIR */ 119 | -------------------------------------------------------------------------------- /samples/timeline/src/timeline.c: -------------------------------------------------------------------------------- 1 | /* samples / timeline.c 2 | * ==================== 3 | * In this example we will learn how to use the timeline. 4 | */ 5 | #include "cage.h" 6 | 7 | /* The sample data struct 8 | * ---------------------- 9 | * 10 | * We use a struct to hold the sample resources: 11 | * a timeline and a font. 12 | * 13 | */ 14 | struct sample_data { 15 | struct timeline* timeline; 16 | struct font* font; 17 | }; 18 | 19 | /* Timeline event callbacks 20 | * ------------------------ 21 | * 22 | * The following functions are timeline event callbacks. These 23 | * functions will be called by the timeline based on its registered 24 | * events. 25 | * Each function gets call on every frame update during its duration. 26 | * The **data** argument will hold any data you pass to **update_timeline**. 27 | * The **progress** argument will range from 0 to 1 based on the event 28 | * duration. 29 | */ 30 | static void* fade_in(void* data, float elapsed_ms, float progress) 31 | { 32 | screen_color(color_from_RGB(255 * progress, 33 | 255 * progress, 34 | 255 * progress)); 35 | UNUSED(data); 36 | UNUSED(elapsed_ms); 37 | return NULL; 38 | } 39 | 40 | static void* caption_1(void* data, float elapsed_ms, float progress) 41 | { 42 | struct sample_data* sd = data; 43 | draw_text(sd->font, "Once upon a time,", 10, 10); 44 | UNUSED(elapsed_ms); 45 | UNUSED(progress); 46 | return NULL; 47 | } 48 | 49 | static void* caption_2(void* data, float elapsed_ms, float progress) 50 | { 51 | struct sample_data* sd = data; 52 | draw_text(sd->font, "in a land far, far away...", 10, 10); 53 | UNUSED(elapsed_ms); 54 | UNUSED(progress); 55 | return NULL; 56 | } 57 | 58 | static void* quit(void* data, float elapsed_ms, float progress) 59 | { 60 | exit(0); 61 | UNUSED(data); 62 | UNUSED(elapsed_ms); 63 | UNUSED(progress); 64 | return NULL; 65 | } 66 | 67 | /* Create 68 | * ------ 69 | * 70 | * We use the game state create() function to create the sample data 71 | * struct instance that holds the timeline and a font. 72 | * Once we have a new timeline, we use append_event() to add events. 73 | */ 74 | static void* create_sample(void) 75 | { 76 | struct sample_data* sd = malloc(sizeof(struct sample_data)); 77 | if (sd == NULL) goto error; 78 | 79 | sd->timeline = create_timeline(); 80 | if (sd->timeline) { 81 | append_event(sd->timeline, 0, 1000, fade_in); 82 | append_event(sd->timeline, 0, 1000, caption_1); 83 | append_event(sd->timeline, 0, 1000, caption_2); 84 | append_event(sd->timeline, 0, 0, quit); 85 | } else 86 | goto cleanup; 87 | 88 | sd->font = create_font("res/font.png", 32, 4); 89 | if (sd->font == NULL) goto cleanup; 90 | return sd; 91 | 92 | cleanup: 93 | if (sd != NULL) { 94 | destroy_timeline(sd->timeline); 95 | destroy_font(sd->font); 96 | } 97 | 98 | error: 99 | return NULL; 100 | } 101 | 102 | /* Update 103 | * ------ 104 | * 105 | * For each frame, the update state function will update the timeline, 106 | * resulting event callbacks invocation. 107 | * The data and elapsed_ms arguments we pass along will eventually end 108 | * up getting to the timeline callbacks. 109 | */ 110 | static void update_sample(void* data, float elapsed_ms) 111 | { 112 | struct sample_data* sd = data; 113 | update_timeline(sd->timeline, sd, elapsed_ms); 114 | } 115 | 116 | /* Destroy 117 | * ------- 118 | * 119 | * In the destroy() function we destroy the timeline, 120 | * destroy the font and free the memory we allocated for 121 | * the sample data struct. 122 | */ 123 | static void destroy_sample(void* data) 124 | { 125 | struct sample_data* sd = data; 126 | destroy_timeline(sd->timeline); 127 | destroy_font(sd->font); 128 | free(data); 129 | } 130 | 131 | /* Main 132 | * ---- 133 | * 134 | * Finally, the game's main function delegates the 135 | * execution to Cage's game_loop() function together with 136 | * the 3 state functions we wrote. 137 | */ 138 | int main(void) 139 | { 140 | return game_loop(create_sample, update_sample, destroy_sample); 141 | } 142 | -------------------------------------------------------------------------------- /vc/Cage.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cage", "Cage\Cage.vcxproj", "{3F1CBAC0-0997-4884-92FD-45286306C5F5}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Wizard", "Wizard\Wizard.vcxproj", "{BAC3341A-0105-46B2-9C4B-7778C799425A}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Callout", "Callout\Callout.vcxproj", "{746CF6AC-6680-46E4-9E38-CA986B40BE2C}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Collisions", "Collisions\Collisions.vcxproj", "{C864F365-BC64-4943-8B48-DD143AEA0223}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sprite", "Sprite\Sprite.vcxproj", "{3888F420-718C-4F36-BC3D-310A06333257}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Timeline", "Timeline\Timeline.vcxproj", "{8AA9B824-51CC-483E-B798-B53EF5B8B9F5}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "State", "State\State.vcxproj", "{37C9D4F5-FF73-41D1-A0E0-956A47153965}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Image", "Image\Image.vcxproj", "{86BECCD5-3FF4-4CD7-84A5-80222AB00F98}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Win32 = Debug|Win32 25 | Release|Win32 = Release|Win32 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {3F1CBAC0-0997-4884-92FD-45286306C5F5}.Debug|Win32.ActiveCfg = Debug|Win32 29 | {3F1CBAC0-0997-4884-92FD-45286306C5F5}.Debug|Win32.Build.0 = Debug|Win32 30 | {3F1CBAC0-0997-4884-92FD-45286306C5F5}.Release|Win32.ActiveCfg = Release|Win32 31 | {3F1CBAC0-0997-4884-92FD-45286306C5F5}.Release|Win32.Build.0 = Release|Win32 32 | {BAC3341A-0105-46B2-9C4B-7778C799425A}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {BAC3341A-0105-46B2-9C4B-7778C799425A}.Debug|Win32.Build.0 = Debug|Win32 34 | {BAC3341A-0105-46B2-9C4B-7778C799425A}.Release|Win32.ActiveCfg = Release|Win32 35 | {BAC3341A-0105-46B2-9C4B-7778C799425A}.Release|Win32.Build.0 = Release|Win32 36 | {746CF6AC-6680-46E4-9E38-CA986B40BE2C}.Debug|Win32.ActiveCfg = Debug|Win32 37 | {746CF6AC-6680-46E4-9E38-CA986B40BE2C}.Debug|Win32.Build.0 = Debug|Win32 38 | {746CF6AC-6680-46E4-9E38-CA986B40BE2C}.Release|Win32.ActiveCfg = Release|Win32 39 | {746CF6AC-6680-46E4-9E38-CA986B40BE2C}.Release|Win32.Build.0 = Release|Win32 40 | {C864F365-BC64-4943-8B48-DD143AEA0223}.Debug|Win32.ActiveCfg = Debug|Win32 41 | {C864F365-BC64-4943-8B48-DD143AEA0223}.Debug|Win32.Build.0 = Debug|Win32 42 | {C864F365-BC64-4943-8B48-DD143AEA0223}.Release|Win32.ActiveCfg = Release|Win32 43 | {C864F365-BC64-4943-8B48-DD143AEA0223}.Release|Win32.Build.0 = Release|Win32 44 | {3888F420-718C-4F36-BC3D-310A06333257}.Debug|Win32.ActiveCfg = Debug|Win32 45 | {3888F420-718C-4F36-BC3D-310A06333257}.Debug|Win32.Build.0 = Debug|Win32 46 | {3888F420-718C-4F36-BC3D-310A06333257}.Release|Win32.ActiveCfg = Release|Win32 47 | {3888F420-718C-4F36-BC3D-310A06333257}.Release|Win32.Build.0 = Release|Win32 48 | {8AA9B824-51CC-483E-B798-B53EF5B8B9F5}.Debug|Win32.ActiveCfg = Debug|Win32 49 | {8AA9B824-51CC-483E-B798-B53EF5B8B9F5}.Debug|Win32.Build.0 = Debug|Win32 50 | {8AA9B824-51CC-483E-B798-B53EF5B8B9F5}.Release|Win32.ActiveCfg = Release|Win32 51 | {8AA9B824-51CC-483E-B798-B53EF5B8B9F5}.Release|Win32.Build.0 = Release|Win32 52 | {37C9D4F5-FF73-41D1-A0E0-956A47153965}.Debug|Win32.ActiveCfg = Debug|Win32 53 | {37C9D4F5-FF73-41D1-A0E0-956A47153965}.Debug|Win32.Build.0 = Debug|Win32 54 | {37C9D4F5-FF73-41D1-A0E0-956A47153965}.Release|Win32.ActiveCfg = Release|Win32 55 | {37C9D4F5-FF73-41D1-A0E0-956A47153965}.Release|Win32.Build.0 = Release|Win32 56 | {86BECCD5-3FF4-4CD7-84A5-80222AB00F98}.Debug|Win32.ActiveCfg = Debug|Win32 57 | {86BECCD5-3FF4-4CD7-84A5-80222AB00F98}.Debug|Win32.Build.0 = Debug|Win32 58 | {86BECCD5-3FF4-4CD7-84A5-80222AB00F98}.Release|Win32.ActiveCfg = Release|Win32 59 | {86BECCD5-3FF4-4CD7-84A5-80222AB00F98}.Release|Win32.Build.0 = Release|Win32 60 | EndGlobalSection 61 | GlobalSection(SolutionProperties) = preSolution 62 | HideSolutionNode = FALSE 63 | EndGlobalSection 64 | EndGlobal 65 | -------------------------------------------------------------------------------- /samples/collisions/src/collisions.c: -------------------------------------------------------------------------------- 1 | /* samples / collisions.c 2 | * ====================== 3 | * 4 | * This sample demonstrates a method for pixel-perfect 5 | * collision detection. While this may not be the most 6 | * optimized way to do this, it is clear and effective. 7 | * 8 | */ 9 | #include "cage.h" 10 | 11 | /* Sample setup 12 | * ------------ 13 | * 14 | * For this demo we will use a star image. 15 | * Each star will have its own position, 16 | * motion vector and bounding box. 17 | */ 18 | #define MAX_STARS 12 19 | 20 | struct star { 21 | vec star_pos; 22 | vec star_vec; 23 | bbox star_bbox; 24 | }; 25 | 26 | struct state { 27 | struct image* star_img; 28 | struct star stars[MAX_STARS]; 29 | }; 30 | 31 | /* 32 | * Web begin by creating, positioning 33 | * and propelling the stars. 34 | */ 35 | static void* create_sample(void) 36 | { 37 | int i; 38 | struct state* state = malloc(sizeof(struct state)); 39 | state->star_img = create_image("res/star.png"); 40 | for (i = 0; i < MAX_STARS; i++) { 41 | state->stars[i].star_pos = xy_vec(i * 16, i * 16); 42 | state->stars[i].star_vec = xy_vec(2 - rand() % 4, 2 - rand() % 4); 43 | state->stars[i].star_bbox.p1 = state->stars[i].star_pos; 44 | state->stars[i].star_bbox.p2 = 45 | add_vec(state->stars[i].star_pos, xy_vec(16, 16)); 46 | } 47 | return state; 48 | } 49 | 50 | /* Moving the stars 51 | * ---------------- 52 | * 53 | * update_star() moves a star on the screen using the star 54 | * motion vector and tests for screen bounds collisions. 55 | */ 56 | static void update_star(struct star* star, float elapsed_ms) 57 | { 58 | bbox screen_bbox = { { 0, 0 }, { 192, 108 } }; 59 | star->star_pos = add_vec(star->star_pos, star->star_vec); 60 | star->star_bbox = translate_bbox(star->star_bbox, star->star_pos); 61 | if (bbox_in_bbox(star->star_bbox, screen_bbox) == 0) { 62 | if (star->star_bbox.p1.x < screen_bbox.p1.x) star->star_vec.x = 1; 63 | if (star->star_bbox.p1.y < screen_bbox.p1.y) star->star_vec.y = 1; 64 | if (star->star_bbox.p2.x > screen_bbox.p2.x) star->star_vec.x = -1; 65 | if (star->star_bbox.p2.y > screen_bbox.p2.y) star->star_vec.y = -1; 66 | } 67 | UNUSED(elapsed_ms); 68 | } 69 | 70 | /* Collision detection 71 | * ------------------- 72 | * 73 | * When updating a frame, we traverse the star pairs 74 | * graph and test for a bounding box intersection. 75 | * To detect pixel-level collisions, we us pixels_collide() 76 | * using the portion of intersection as a test area. 77 | * If we detect a collision, we swap the star pair 78 | * motion vectors to create a deflection effect. 79 | * 80 | * When done, we update and draw the stars. 81 | */ 82 | static void update_sample(void* data, float elapsed_ms) 83 | { 84 | struct state* state = data; 85 | int visited[MAX_STARS][MAX_STARS] = { { 0 } }; 86 | int i, j; 87 | for (i = 0; i < MAX_STARS; i++) { 88 | for (j = 0; j < MAX_STARS; j++) { 89 | if (i != j && visited[i][j] == 0 && visited[j][i] == 0) { 90 | bbox sub; 91 | struct star* a = &state->stars[i]; 92 | struct star* b = &state->stars[j]; 93 | if (bbox_intersect(a->star_bbox, b->star_bbox, &sub)) { 94 | struct rectangle r1, r2; 95 | r1 = rect_from_sub_bbox(a->star_bbox, sub); 96 | r2 = rect_from_sub_bbox(b->star_bbox, sub); 97 | if (pixels_collide(state->star_img, &r1, state->star_img, 98 | &r2)) 99 | swap_vecs(&a->star_vec, &b->star_vec); 100 | } 101 | visited[i][j] = 1; 102 | } 103 | } 104 | } 105 | screen_color(color_from_RGB(10, 20, 50)); 106 | for (i = 0; i < MAX_STARS; i++) { 107 | update_star(&state->stars[i], elapsed_ms); 108 | draw_image(state->star_img, VEC_XY(state->stars[i].star_pos), NULL, 0); 109 | } 110 | } 111 | 112 | /* Cleanup 113 | * ------- 114 | * 115 | * Clean up is simple enough. Just destroy the star 116 | * image and free the state structure memory. 117 | */ 118 | static void destroy_sample(void* data) 119 | { 120 | struct state* state = data; 121 | destroy_image(state->star_img); 122 | free(data); 123 | } 124 | 125 | /* Main 126 | * ---- 127 | * 128 | * The usual game_loop call, using the usual state 129 | * functions. 130 | */ 131 | int main(void) 132 | { 133 | return game_loop(create_sample, update_sample, destroy_sample); 134 | } 135 | -------------------------------------------------------------------------------- /cmake/FindSDL2_image.cmake: -------------------------------------------------------------------------------- 1 | # - Locate SDL_image library 2 | # This module defines: 3 | # SDL2_IMAGE_LIBRARIES, the name of the library to link against 4 | # SDL2_IMAGE_INCLUDE_DIRS, where to find the headers 5 | # SDL2_IMAGE_FOUND, if false, do not try to link against 6 | # SDL2_IMAGE_VERSION_STRING - human-readable string containing the version of SDL_image 7 | # 8 | # For backward compatiblity the following variables are also set: 9 | # SDLIMAGE_LIBRARY (same value as SDL2_IMAGE_LIBRARIES) 10 | # SDLIMAGE_INCLUDE_DIR (same value as SDL2_IMAGE_INCLUDE_DIRS) 11 | # SDLIMAGE_FOUND (same value as SDL2_IMAGE_FOUND) 12 | # 13 | # $SDLDIR is an environment variable that would 14 | # correspond to the ./configure --prefix=$SDLDIR 15 | # used in building SDL. 16 | # 17 | # Created by Eric Wing. This was influenced by the FindSDL.cmake 18 | # module, but with modifications to recognize OS X frameworks and 19 | # additional Unix paths (FreeBSD, etc). 20 | 21 | #============================================================================= 22 | # Copyright 2005-2009 Kitware, Inc. 23 | # Copyright 2012 Benjamin Eikel 24 | # 25 | # Distributed under the OSI-approved BSD License (the "License"); 26 | # see accompanying file Copyright.txt for details. 27 | # 28 | # This software is distributed WITHOUT ANY WARRANTY; without even the 29 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 30 | # See the License for more information. 31 | #============================================================================= 32 | # (To distribute this file outside of CMake, substitute the full 33 | # License text for the above reference.) 34 | 35 | SET(SDL2_SEARCH_PATHS 36 | ~/Library/Frameworks 37 | /Library/Frameworks 38 | /usr/local 39 | /usr 40 | /sw # Fink 41 | /opt/local # DarwinPorts 42 | /opt/csw # Blastwave 43 | /opt 44 | ) 45 | 46 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 47 | set(SDL2_ARCH_64 TRUE) 48 | set(SDL2_PROCESSOR_ARCH "x64") 49 | else() 50 | set(SDL2_ARCH_64 FALSE) 51 | set(SDL2_PROCESSOR_ARCH "x86") 52 | endif(CMAKE_SIZEOF_VOID_P EQUAL 8) 53 | 54 | if(NOT SDL2_IMAGE_INCLUDE_DIR AND SDL2IMAGE_INCLUDE_DIR) 55 | set(SDL2_IMAGE_INCLUDE_DIR ${SDL2IMAGE_INCLUDE_DIR} CACHE PATH "directory cache 56 | entry initialized from old variable name") 57 | endif() 58 | find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h 59 | HINTS 60 | ENV SDL2IMAGEDIR 61 | ENV SDL2DIR 62 | PATH_SUFFIXES include include/SDL2 63 | PATHS ${SDL2_SEARCH_PATHS} 64 | ) 65 | 66 | if(NOT SDL2_IMAGE_LIBRARY AND SDL2IMAGE_LIBRARY) 67 | set(SDL2_IMAGE_LIBRARY ${SDL2IMAGE_LIBRARY} CACHE FILEPATH "file cache entry 68 | initialized from old variable name") 69 | endif() 70 | find_library(SDL2_IMAGE_LIBRARY 71 | NAMES SDL2_image 72 | HINTS 73 | ENV SDL2IMAGEDIR 74 | ENV SDL2DIR 75 | PATH_SUFFIXES lib64 lib lib/${SDL2_PROCESSOR_ARCH} 76 | PATHS ${SDL2_SEARCH_PATHS} 77 | ) 78 | 79 | if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h") 80 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$") 81 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+[0-9]+$") 82 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+[0-9]+$") 83 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}") 84 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}") 85 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}") 86 | set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH}) 87 | unset(SDL2_IMAGE_VERSION_MAJOR_LINE) 88 | unset(SDL2_IMAGE_VERSION_MINOR_LINE) 89 | unset(SDL2_IMAGE_VERSION_PATCH_LINE) 90 | unset(SDL2_IMAGE_VERSION_MAJOR) 91 | unset(SDL2_IMAGE_VERSION_MINOR) 92 | unset(SDL2_IMAGE_VERSION_PATCH) 93 | endif() 94 | 95 | set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY}) 96 | set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR}) 97 | 98 | include(FindPackageHandleStandardArgs) 99 | 100 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image 101 | REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS 102 | VERSION_VAR SDL2_IMAGE_VERSION_STRING) 103 | 104 | # for backward compatiblity 105 | set(SDL2IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARIES}) 106 | set(SDL2IMAGE_INCLUDE_DIR ${SDL2_IMAGE_INCLUDE_DIRS}) 107 | set(SDL2IMAGE_FOUND ${SDL2_IMAGE_FOUND}) 108 | 109 | mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR) 110 | -------------------------------------------------------------------------------- /cmake/FindSDL2_mixer.cmake: -------------------------------------------------------------------------------- 1 | # - Locate SDL_mixer library 2 | # This module defines: 3 | # SDL2_MIXER_LIBRARIES, the name of the library to link against 4 | # SDL2_MIXER_INCLUDE_DIRS, where to find the headers 5 | # SDL2_MIXER_FOUND, if false, do not try to link against 6 | # SDL2_MIXER_VERSION_STRING - human-readable string containing the version of SDL_mixer 7 | # 8 | # For backward compatiblity the following variables are also set: 9 | # SDLMIXER_LIBRARY (same value as SDL2_MIXER_LIBRARIES) 10 | # SDLMIXER_INCLUDE_DIR (same value as SDL2_MIXER_INCLUDE_DIRS) 11 | # SDLMIXER_FOUND (same value as SDL2_MIXER_FOUND) 12 | # 13 | # $SDLDIR is an environment variable that would 14 | # correspond to the ./configure --prefix=$SDLDIR 15 | # used in building SDL. 16 | # 17 | # Created by Eric Wing. This was influenced by the FindSDL.cmake 18 | # module, but with modifications to recognize OS X frameworks and 19 | # additional Unix paths (FreeBSD, etc). 20 | 21 | #============================================================================= 22 | # Copyright 2005-2009 Kitware, Inc. 23 | # Copyright 2012 Benjamin Eikel 24 | # 25 | # Distributed under the OSI-approved BSD License (the "License"); 26 | # see accompanying file Copyright.txt for details. 27 | # 28 | # This software is distributed WITHOUT ANY WARRANTY; without even the 29 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 30 | # See the License for more information. 31 | #============================================================================= 32 | # (To distribute this file outside of CMake, substitute the full 33 | # License text for the above reference.) 34 | 35 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 36 | set(SDL2_ARCH_64 TRUE) 37 | set(SDL2_PROCESSOR_ARCH "x64") 38 | else() 39 | set(SDL2_ARCH_64 FALSE) 40 | set(SDL2_PROCESSOR_ARCH "x86") 41 | endif(CMAKE_SIZEOF_VOID_P EQUAL 8) 42 | 43 | SET(SDL2_SEARCH_PATHS 44 | ~/Library/Frameworks 45 | /Library/Frameworks 46 | /usr/local 47 | /usr 48 | /sw # Fink 49 | /opt/local # DarwinPorts 50 | /opt/csw # Blastwave 51 | /opt 52 | ) 53 | 54 | if(NOT SDL2_MIXER_INCLUDE_DIR AND SDL2MIXER_INCLUDE_DIR) 55 | set(SDL2_MIXER_INCLUDE_DIR ${SDL2MIXER_INCLUDE_DIR} CACHE PATH "directory cache 56 | entry initialized from old variable name") 57 | endif() 58 | find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h 59 | HINTS 60 | ENV SDL2MIXERDIR 61 | ENV SDL2DIR 62 | PATH_SUFFIXES include include/SDL2 63 | PATHS ${SDL2_SEARCH_PATHS} 64 | ) 65 | 66 | if(NOT SDL2_MIXER_LIBRARY AND SDL2MIXER_LIBRARY) 67 | set(SDL2_MIXER_LIBRARY ${SDL2MIXER_LIBRARY} CACHE FILEPATH "file cache entry 68 | initialized from old variable name") 69 | endif() 70 | find_library(SDL2_MIXER_LIBRARY 71 | NAMES SDL2_mixer 72 | HINTS 73 | ENV SDL2MIXERDIR 74 | ENV SDL2DIR 75 | PATH_SUFFIXES lib64 lib lib/${SDL2_PROCESSOR_ARCH} 76 | PATHS ${SDL2_SEARCH_PATHS} 77 | ) 78 | 79 | if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h") 80 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$") 81 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$") 82 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$") 83 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}") 84 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}") 85 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}") 86 | set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH}) 87 | unset(SDL2_MIXER_VERSION_MAJOR_LINE) 88 | unset(SDL2_MIXER_VERSION_MINOR_LINE) 89 | unset(SDL2_MIXER_VERSION_PATCH_LINE) 90 | unset(SDL2_MIXER_VERSION_MAJOR) 91 | unset(SDL2_MIXER_VERSION_MINOR) 92 | unset(SDL2_MIXER_VERSION_PATCH) 93 | endif() 94 | 95 | set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY}) 96 | set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR}) 97 | 98 | include(FindPackageHandleStandardArgs) 99 | 100 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer 101 | REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS 102 | VERSION_VAR SDL2_MIXER_VERSION_STRING) 103 | 104 | # for backward compatiblity 105 | set(SDL2MIXER_LIBRARY ${SDL2_MIXER_LIBRARIES}) 106 | set(SDL2MIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS}) 107 | set(SDL2MIXER_FOUND ${SDL2_MIXER_FOUND}) 108 | 109 | mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR) 110 | -------------------------------------------------------------------------------- /src/cage.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef NGX_H_F8WRBKFT 23 | #define NGX_H_F8WRBKFT 24 | 25 | #include "utils.h" 26 | #include "vec.h" 27 | #include "geometry.h" 28 | #include "screen.h" 29 | #include "image.h" 30 | #include "sprite.h" 31 | #include "keyboard.h" 32 | #include "mouse.h" 33 | #include "font.h" 34 | #include "sound.h" 35 | #include "animate.h" 36 | #include "timeline.h" 37 | #include "toolbox.h" 38 | #include "easing.h" 39 | #include "file.h" 40 | #include "begin_prefix.h" 41 | 42 | /** 43 | * This is the prototype of the create function: 44 | * 45 | * void* create_game(void) 46 | * { 47 | * // Put any level, menu or other game state setup code here 48 | * // and return a pointer to your level data or NULL 49 | * // in case of a failure. 50 | * } 51 | * 52 | * You may provide a create function to create and set up a game state. 53 | * A game state will usually be a struct, holding sprites, images, fonts 54 | * or any other assert required to run a level, a game menu or other game 55 | * states. 56 | * You pass a pointer to this function when 57 | * you call game_loop() or game_state(). 58 | * 59 | * @return pointer to your game state data or NULL on failure 60 | */ 61 | typedef void* (*create_func_t)(void); 62 | 63 | /** 64 | * This is the prototype of the update function: 65 | * 66 | * void update_game(void* data, float elapsed_ms) 67 | * { 68 | * // Update and draw your game 69 | * } 70 | * 71 | * The update function is called each time Cage wants you to update a new game 72 | * frame. This is the place to change your game state, play or stop sound 73 | * effects and draw your graphics. 74 | * 75 | * You pass a pointer to this function when you 76 | * call game_loop() or game_state(). 77 | * 78 | * @param data the pointer you returned from the create 79 | * function. 80 | * @param elapsed_ms time passed since last update in 81 | * milliseconds. 82 | */ 83 | typedef void (*update_func_t)(void* data, float elpased_ms); 84 | 85 | /** 86 | * This is the prototype of the destroy function that may be provided 87 | * to Cage in order to free any allocated resources once a game state 88 | * is being dismissed. 89 | * 90 | * void destroy_game(void* data) 91 | * { 92 | * // Put any cleanup code here... 93 | * } 94 | * 95 | * You may pass a pointer to this function when you 96 | * call game_loop() or game_state(). 97 | * 98 | * @param data the pointer you returned from the create function. 99 | */ 100 | typedef void (*destroy_func_t)(void* data); 101 | 102 | /** 103 | * This is the prototype of the setup function: 104 | * 105 | */ 106 | struct settings { 107 | int window_width; 108 | int window_height; 109 | int logical_width; 110 | int logical_height; 111 | bool fullscreen; 112 | }; 113 | 114 | typedef void (*setup_func_t)(struct settings*); 115 | 116 | /** 117 | * Call this function to start your game. 118 | * 119 | * int main(void) 120 | * { 121 | * return game_loop(create_game, update_game, destroy_game); 122 | * } 123 | */ 124 | int game_loop(create_func_t create, 125 | update_func_t update, 126 | destroy_func_t destroy); 127 | 128 | int game_setup_and_loop(setup_func_t setup, 129 | create_func_t create, 130 | update_func_t update, 131 | destroy_func_t destroy); 132 | 133 | /** 134 | * Call this function to change your game state functions. 135 | * 136 | * void update_current_level(void* data, float elapsed_ms) 137 | * { 138 | * // Yay.. level was just completed, let's 139 | * // change the game state to the next level. 140 | * game_state(create_next_level, 141 | * update_next_level, 142 | * destroy_next_level); 143 | * } 144 | */ 145 | void game_state(create_func_t create, 146 | update_func_t update, 147 | destroy_func_t destroy); 148 | 149 | void exit_with_error_msg(const char* msg); 150 | void message_box(const char* title, const char* message); 151 | 152 | const char * get_error_msgs(); 153 | 154 | #include "end_prefix.h" 155 | #endif /* end of include guard: NGX_H_F8WRBKFT */ 156 | -------------------------------------------------------------------------------- /src/timeline.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef TIMELINE_H_G613QT9P 23 | #define TIMELINE_H_G613QT9P 24 | 25 | #include 26 | #include "types.h" 27 | 28 | #define MAX_TIMELINE_EVENTS 100 29 | 30 | #include "begin_prefix.h" 31 | /** 32 | * Timeline event holds a single registered 33 | * event in a timeline. Timeline events can have a gap 34 | * of time between the last scheduled event. 35 | * Timeline events can also have a duration, which makes 36 | * them long-running events. 37 | * The manifestation of a timeline event is a callback call. 38 | */ 39 | struct timeline_event { 40 | /** Time to wait before activating the event */ 41 | uint32_t ms_wait; 42 | /** Callback to call to */ 43 | void* (*callback)(void* data, float elapsed_ms, float progress); 44 | /** Duration of the event */ 45 | uint32_t ms_duration; 46 | }; 47 | 48 | /** 49 | * A timeline holds a sequence of events 50 | * on a, well.. time line. Each event has a start time, 51 | * a duration and a callback function. 52 | * The callback gets called each time the timeline 53 | * is updated, as long as the event is active. 54 | * 55 | * You can use a time line to sequence animations, 56 | * cut-scenes, in-level scenes and other event-driven 57 | * behaviors. 58 | * 59 | * Events in a timeline cannot overlap. If you need 60 | * events to overlap (such as in a dialogue) 61 | * you will need to create more than one timeline, 62 | * just like you would have separate tracks in a 63 | * video editor or an animation software. 64 | */ 65 | struct timeline { 66 | /* Events to activate */ 67 | struct timeline_event events[MAX_TIMELINE_EVENTS]; 68 | /* Number of registered events */ 69 | int n_events; 70 | /* Timer to keep track of the timeline running time */ 71 | uint32_t timer; 72 | /* Accumulated timer to keep track of the timeline running time */ 73 | uint32_t acc_timer; 74 | /* Pending event */ 75 | int next_event; 76 | int curr_event; 77 | bool paused; 78 | }; 79 | 80 | /** 81 | * Allocate and prepare a new timeline 82 | * ready for use. 83 | * 84 | * @return - an allocated, ready to use timeline. 85 | */ 86 | struct timeline* create_timeline(void); 87 | 88 | /** 89 | * Destroy a previously created timeline 90 | */ 91 | void destroy_timeline(struct timeline* timeline); 92 | 93 | /** 94 | * Append an event to the timeline 95 | * @param timeline Timeline to append the event to 96 | * @param wait Time to wait after the last event 97 | * @param duration Time to actively call the callback or 0 for 98 | * a single call 99 | * @param callback Callback function to call to 100 | * 101 | * @return -1 on error or the new event index 102 | */ 103 | int append_event(struct timeline* timeline, 104 | uint32_t wait, 105 | uint32_t duration, 106 | void* (*callback)(void* data, 107 | float elapsed_ms, 108 | float progress)); 109 | /** 110 | * Append an set of events to the timeline 111 | * @param timeline Timeline to append the events to 112 | * @param nevents Number of events to append 113 | * @param events \ref timeline_event array 114 | * 115 | * @return -1 on error or the number of appended events 116 | */ 117 | int append_events(struct timeline* timeline, 118 | int nevents, 119 | struct timeline_event events[]); 120 | 121 | /** 122 | * Update the timeline timers and invoke event callbacks 123 | */ 124 | void* update_timeline(struct timeline* timeline, void* data, float elapsed_ms); 125 | 126 | /** 127 | * Pause a running timeline, stopping any running timer 128 | * accounting. 129 | */ 130 | void pause_timeline(struct timeline* timeline); 131 | 132 | /** 133 | * Reset & restart a running or completed timeline. 134 | */ 135 | void reset_timeline(struct timeline* timeline); 136 | 137 | /** 138 | * Used to prepare an already allocated timeline 139 | */ 140 | void init_timeline(struct timeline* timeline); 141 | 142 | /** 143 | * Cleans a used timeline, but does not deallocate it 144 | */ 145 | void cleanup_timeline(struct timeline* timeline); 146 | 147 | #include "end_prefix.h" 148 | #endif /* end of include guard: TIMELINE_H_G613QT9P */ 149 | -------------------------------------------------------------------------------- /src/timeline.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014-2016 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #include "timeline.h" 23 | #include "utils.h" 24 | #include 25 | #include "begin_prefix.h" 26 | 27 | struct timeline* create_timeline(void) 28 | { 29 | struct timeline* timeline = (struct timeline*)malloc(sizeof(struct timeline)); 30 | if (timeline != NULL) 31 | init_timeline(timeline); 32 | else 33 | ERROR("Unable to malloc a timeline"); 34 | return timeline; 35 | } 36 | 37 | void destroy_timeline(struct timeline* timeline) 38 | { 39 | free(timeline); 40 | } 41 | 42 | int append_event(struct timeline* timeline, 43 | uint32_t wait, 44 | uint32_t duration, 45 | void* (*callback)(void* data, 46 | float elapsed_ms, 47 | float progress)) 48 | { 49 | struct timeline_event* event; 50 | if (timeline->acc_timer != 0) { 51 | ERROR("Cannot append event after timeline updates"); 52 | return -1; 53 | } 54 | if (timeline->n_events == MAX_TIMELINE_EVENTS) { 55 | ERROR("Reached timeline events capacity limit"); 56 | return -1; 57 | } 58 | event = &timeline->events[timeline->n_events]; 59 | event->ms_wait = wait; 60 | event->ms_duration = duration; 61 | event->callback = callback; 62 | timeline->n_events++; 63 | return 0; 64 | } 65 | 66 | int append_events(struct timeline* timeline, 67 | int nevents, 68 | struct timeline_event events[]) 69 | { 70 | int i; 71 | for (i = 0; i < nevents; i++) { 72 | if (append_event(timeline, events[i].ms_wait, events[i].ms_duration, 73 | events[i].callback) == -1) 74 | break; 75 | } 76 | return i == nevents ? i : -1; 77 | } 78 | 79 | void* update_timeline(struct timeline* timeline, void* data, float elapsed_ms) 80 | { 81 | void* ret = NULL; 82 | if (timeline->paused) return ret; 83 | uint32_t next_acc_timer; 84 | 85 | if (timeline->next_event < timeline->n_events) { 86 | timeline->timer += elapsed_ms; 87 | /* loop to make sure we will not miss a consecutive callback */ 88 | next_acc_timer = 89 | timeline->acc_timer + timeline->events[timeline->next_event].ms_wait; 90 | while (timeline->timer > next_acc_timer) { 91 | int reg_next_event = timeline->next_event; 92 | uint32_t elapsed = timeline->timer - next_acc_timer; 93 | uint32_t duration = 94 | timeline->events[timeline->next_event].ms_duration; 95 | if (duration < elapsed_ms || elapsed > duration) { 96 | timeline->acc_timer += 97 | timeline->events[timeline->next_event].ms_wait; 98 | timeline->acc_timer += 99 | timeline->events[timeline->next_event].ms_duration; 100 | timeline->next_event++; 101 | if (timeline->next_event < timeline->n_events) // break; 102 | next_acc_timer = 103 | timeline->acc_timer + 104 | timeline->events[timeline->next_event].ms_wait; 105 | } 106 | if ((elapsed <= duration || duration < elapsed_ms) && 107 | reg_next_event < timeline->n_events) { 108 | float progress = 109 | duration == 0 ? 1.0f : (float)elapsed / (float)duration; 110 | timeline->curr_event = reg_next_event; 111 | ret = 112 | timeline->events[reg_next_event].callback(data, 113 | elapsed_ms, 114 | progress); 115 | } 116 | if (elapsed <= duration || 117 | timeline->next_event == timeline->n_events) 118 | break; 119 | } 120 | } 121 | return ret; 122 | } 123 | 124 | void init_timeline(struct timeline* timeline) 125 | { 126 | timeline->n_events = 0; 127 | reset_timeline(timeline); 128 | } 129 | 130 | void pause_timeline(struct timeline* timeline) 131 | { 132 | timeline->paused = true; 133 | } 134 | 135 | void reset_timeline(struct timeline* timeline) 136 | { 137 | timeline->paused = false; 138 | timeline->timer = 0; 139 | timeline->next_event = 0; 140 | timeline->acc_timer = 0; 141 | } 142 | 143 | void cleanup_timeline(struct timeline* timeline) 144 | { 145 | init_timeline(timeline); 146 | } 147 | #include "end_prefix.h" 148 | -------------------------------------------------------------------------------- /src/ccage.hh: -------------------------------------------------------------------------------- 1 | #ifndef CCAGE_HH_INCLUDED 2 | #define CCAGE_HH_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "cage.h" 12 | 13 | namespace cage { 14 | 15 | using rectangle = cage_rectangle; 16 | 17 | //---------------------------------------------------------------------------- 18 | // Color wrapper 19 | class color { 20 | public: 21 | static cage_color rgb(int r, int g, int b); 22 | static cage_color rgba(int r, int g, int b, int a); 23 | }; 24 | 25 | //---------------------------------------------------------------------------- 26 | // Image wrapper 27 | class image { 28 | private: 29 | cage_image *_image; 30 | 31 | public: 32 | image(std::string filename); 33 | image(int width, int height, cage_color color); 34 | virtual ~image(); 35 | operator cage_image *() const; 36 | void set_blend_mode(cage_blend_mode blend_mode); 37 | void clear(cage_color color); 38 | void draw_on(); 39 | void draw_off(); 40 | void draw(int x, int y, cage_rectangle *clip, float angle); 41 | void draw(int x, int y); 42 | void blend(); 43 | void multiply(); 44 | void add(); 45 | void none(); 46 | int width() const { return _image->width; } 47 | int height() const { return _image->height; } 48 | }; 49 | 50 | //---------------------------------------------------------------------------- 51 | // Animation wrapper 52 | class animation { 53 | private: 54 | cage_animation *_animation; 55 | 56 | public: 57 | animation(); 58 | virtual ~animation(); 59 | animation &add_frame(int index_in_sprite, int duration, void *user_data); 60 | animation &loop(int from, int to); 61 | animation &mode(cage_animation_mode m); 62 | animation &freeze_last_frame(); 63 | 64 | operator cage_animation *() const; 65 | cage_animation *impl() const; 66 | }; 67 | 68 | //---------------------------------------------------------------------------- 69 | // Sprite wrapper 70 | class sprite { 71 | private: 72 | cage_sprite *_sprite; 73 | 74 | public: 75 | sprite(const image &image, int w, int h); 76 | int draw(int x, int y) const; 77 | void draw_frame(int x, int y, int frame) const; 78 | void *animate(uint32_t elapsed); 79 | void play(const animation &animation); 80 | operator cage_sprite *() const; 81 | cage_sprite *impl() const; 82 | }; 83 | 84 | //---------------------------------------------------------------------------- 85 | // State wrapper 86 | class state { 87 | public: 88 | virtual void update(float elapsed) = 0; 89 | template 90 | void handoff() { 91 | cage_game_state( 92 | []() -> void * { return new S(); }, 93 | [](void *d, float e) { static_cast(d)->update(e); }, 94 | [](void *d) { delete static_cast(d); }); 95 | } 96 | }; 97 | 98 | //---------------------------------------------------------------------------- 99 | // Timeline wrapper 100 | class timeline { 101 | private: 102 | cage_timeline *_timeline; 103 | static std::unordered_map>> 105 | _callbacks; 106 | 107 | public: 108 | timeline(); 109 | 110 | static void *global_timeline_callback(void *data, 111 | float elapsed, 112 | float progress); 113 | timeline &append_event(uint32_t wait, 114 | uint32_t duration, 115 | std::function 116 | callback); 117 | void update(float elapsed_ms); 118 | void reset(); 119 | void pause(); 120 | virtual ~timeline(); 121 | }; 122 | 123 | //---------------------------------------------------------------------------- 124 | // Sound wrapper 125 | class sound { 126 | private: 127 | cage_sound *_sound; 128 | 129 | public: 130 | sound(std::string filename); 131 | virtual ~sound(); 132 | void play(int loops); 133 | void stop(); 134 | void set_volume(float volume); 135 | bool is_playing(); 136 | }; 137 | 138 | //---------------------------------------------------------------------------- 139 | // Font wrapper 140 | class font { 141 | private: 142 | cage_font *_font; 143 | 144 | public: 145 | font(std::string filename, int cols, int rows); 146 | virtual ~font(); 147 | void draw_text(std::string text, int x, int y); 148 | void measure_text(std::string text, int *x, int *y); 149 | }; 150 | 151 | //---------------------------------------------------------------------------- 152 | // Screen wrapper 153 | class screen { 154 | public: 155 | static void draw_on(); 156 | static void shake(float elapsed_ms); 157 | static void relax(float elapsed_ms); 158 | static void get_size(int * w, int * h); 159 | static void set_blend_mode(cage_blend_mode blend_mode); 160 | }; 161 | 162 | //---------------------------------------------------------------------------- 163 | // Game wrapper 164 | class game { 165 | public: 166 | template 167 | static int start() { 168 | try { 169 | return cage_game_loop( 170 | []() -> void * { return new S(); }, 171 | [](void *d, float e) { static_cast(d)->update(e); }, 172 | [](void *d) { delete static_cast(d); }); 173 | } 174 | catch (const std::exception & e) { 175 | cage_message_box("CAGE", e.what()); 176 | } 177 | } 178 | }; 179 | } 180 | 181 | #endif // CCAGE_HH_INCLUDED 182 | -------------------------------------------------------------------------------- /vc/Cage/Cage.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {3F1CBAC0-0997-4884-92FD-45286306C5F5} 15 | Cage 16 | 17 | 18 | 19 | StaticLibrary 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | StaticLibrary 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | ..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 48 | Default 49 | 4244;%(DisableSpecificWarnings) 50 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | true 63 | ..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 64 | 4244;%(DisableSpecificWarnings) 65 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 66 | 67 | 68 | true 69 | true 70 | true 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/sprite.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Ithai Levi @RLofC 2 | * 3 | * This software is provided 'as-is', without any express or implied 4 | * warranty. In no event will the authors be held liable for any damages 5 | * arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 11 | * 1. The origin of this software must not be misrepresented; you must not 12 | * claim that you wrote the original software. If you use this software 13 | * in a product, an acknowledgment in the product documentation would be 14 | * appreciated but is not required. 15 | * 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 19 | * 3. This notice may not be removed or altered from any source 20 | * distribution. 21 | */ 22 | #ifndef SPRITE_H_XF4APTCE 23 | #define SPRITE_H_XF4APTCE 24 | 25 | #include "image.h" 26 | #include "animate.h" 27 | 28 | #include "begin_prefix.h" 29 | /** 30 | * Sprites use images sliced into frames to play short animations. 31 | * Sprites can be used for game characters, props, tiles and titles. 32 | * To create a sprite, you will need to create an image containing 33 | * a set of fixed-sized frames and then pass it to create_sprite(): 34 | * 35 | * struct sprite* wizard = NULL; 36 | * wizard = create_sprite(create_image("wizard.png", screen), 32, 32); 37 | * 38 | * Note that by creating both the sprite and the image, you are 39 | * responsible to the clean-up once you're done: 40 | * 41 | * destroy_image(wizard->image); 42 | * destroy_sprite(wizard); 43 | * 44 | * To animate a sprite, you need to create \ref animation instances, 45 | * indicating the frames to play. To actually play an animation, 46 | * use play_animation(): 47 | * 48 | * play_animation(wizard, walk); 49 | * 50 | * Finally, to update the sprite animation, call animate_sprite(): 51 | * 52 | * void* data; 53 | * data = animate_sprite(wizard, elapsed_ms); 54 | * 55 | * Once a frame that has a user-data associated with it is played, 56 | * you will get the data pointer back. 57 | * 58 | */ 59 | struct sprite { 60 | /** image used to draw sprite frames */ 61 | struct image* image; 62 | /** width of each frame of the sprite */ 63 | int frame_width; 64 | /** height of each frame of the sprite */ 65 | int frame_height; 66 | /** the animation currently being played */ 67 | struct animation* active_animation; 68 | /** the animation pending to be played in the next frame */ 69 | struct animation* next_animation; 70 | /** currenlty played frame in the active animation */ 71 | int current_frame; 72 | /** time the current frame is in display in milliseconds */ 73 | int elapsed_frame; 74 | }; 75 | 76 | /** 77 | * allocate and initialize a new sprite 78 | * @param image sprite \ref image 79 | * @param w sprite frame width 80 | * @param h sprite frame height 81 | * 82 | * @return valid sprite pointer or NULL on error 83 | */ 84 | struct sprite* create_sprite(struct image* image, int w, int h); 85 | 86 | /** 87 | * destroy an allocated sprite 88 | * @param sprite sprite created using create_sprite(). 89 | */ 90 | void destroy_sprite(struct sprite* sprite); 91 | 92 | /** 93 | * Build a sprite from a sprite image file containing frame tiles. 94 | * @param sprite sprite resource to generate 95 | * @param image image containing the sprite frames. 96 | * @param frame_width width of each frame tile 97 | * @param frame_height height of each frame tile 98 | * 99 | * @return -1 on error 100 | */ 101 | int prepare_sprite(struct sprite* sprite, 102 | struct image* image, 103 | int frame_width, 104 | int frame_height); 105 | 106 | /** 107 | * Free any internally allocated resources for the \ref sprite 108 | * @param sprite \ref sprite to cleanup 109 | */ 110 | void cleanup_sprite(struct sprite* sprite); 111 | 112 | /** 113 | * Draw the active frame of the sprite. 114 | * @param sprite sprite to use 115 | * @param x x coordinates 116 | * @param y y coordinates 117 | * 118 | * @return rendered sprite frame index 119 | * 120 | * If no sprite \ref animation is active, the first frame will 121 | * be drawn. 122 | * If an \ref animation is active, the animation state 123 | * will determine the frame to draw. 124 | */ 125 | int draw_sprite(struct sprite* sprite, int x, int y); 126 | 127 | /** 128 | * Draw the specified frame of the sprite. 129 | * @param sprite sprite to use 130 | * @param x x coordinates 131 | * @param y y coordinates 132 | * @param frame frame index to draw from the sprite sheet 133 | * 134 | * This function can be used to override any animation or just 135 | * use a sprite for its sprite sheet. 136 | */ 137 | void draw_sprite_frame(struct sprite* sprite, int x, int y, int frame); 138 | 139 | /** 140 | * Update the sprite animation state 141 | * @param sprite sprite to animate 142 | * @param elapsed_ms time since last rendered frame (usually elapsed_ms) 143 | */ 144 | void* animate_sprite(struct sprite* sprite, uint32_t elapsed_ms); 145 | 146 | /** 147 | * Play a any binded sprite animation 148 | * @param sprite /ref sprite to use the animation for. 149 | * @param animation /ref animation to play. 150 | * 151 | * @note If a previous animation keyframe is not through 152 | * playing, the requested animation will be defered 153 | * until the previous keyframe is completed. 154 | */ 155 | void play_animation(struct sprite* sprite, struct animation* animation); 156 | 157 | /** 158 | * Stop any playing animation 159 | * @param sprite /ref sprite to work on. 160 | * 161 | * Use this function to stop any currently playing or staged 162 | * animation. This will clear any running animation and so 163 | * any new animation activated using /ref play_animation 164 | * will start immediately. 165 | */ 166 | void stop_animation(struct sprite* sprite); 167 | 168 | #include "end_prefix.h" 169 | #endif /* end of include guard: SPRITE_H_XF4APTCE */ 170 | -------------------------------------------------------------------------------- /src/begin_prefix.h: -------------------------------------------------------------------------------- 1 | #ifdef CAGE_PREFIX 2 | #define add_frame cage_add_frame 3 | #define add_frames cage_add_frames 4 | #define add_vec cage_add_vec 5 | #define animate_sprite cage_animate_sprite 6 | #define animation cage_animation 7 | #define animation_mode cage_animation_mode 8 | #define append_event cage_append_event 9 | #define append_events cage_append_events 10 | #define back_ease_in cage_back_ease_in 11 | #define back_ease_in_out cage_back_ease_in_out 12 | #define back_ease_out cage_back_ease_out 13 | #define bbox_in_bbox cage_bbox_in_bbox 14 | #define bbox_intersect cage_bbox_intersect 15 | #define blend_mode cage_blend_mode 16 | #define bounce_ease_in cage_bounce_ease_in 17 | #define bounce_ease_in_out cage_bounce_ease_in_out 18 | #define bounce_ease_out cage_bounce_ease_out 19 | #define circular_ease_in cage_circular_ease_in 20 | #define circular_ease_in_out cage_circular_ease_in_out 21 | #define circular_ease_out cage_circular_ease_out 22 | #define cleanup_font cage_cleanup_font 23 | #define cleanup_image cage_cleanup_image 24 | #define cleanup_sound cage_cleanup_sound 25 | #define cleanup_sprite cage_cleanup_sprite 26 | #define cleanup_timeline cage_cleanup_timeline 27 | #define clear_image cage_clear_image 28 | #define color cage_color 29 | #define color_from_RGB cage_color_from_RGB 30 | #define color_from_RGBA cage_color_from_RGBA 31 | #define coords cage_coords 32 | #define create_animation cage_create_animation 33 | #define create_blank_image cage_create_blank_image 34 | #define create_font cage_create_font 35 | #define create_image cage_create_image 36 | #define create_sound cage_create_sound 37 | #define create_sprite cage_create_sprite 38 | #define create_target_image cage_create_target_image 39 | #define create_timeline cage_create_timeline 40 | #define cubic_ease_in cage_cubic_ease_in 41 | #define cubic_ease_in_out cage_cubic_ease_in_out 42 | #define cubic_ease_out cage_cubic_ease_out 43 | #define destroy_animation cage_destroy_animation 44 | #define destroy_font cage_destroy_font 45 | #define destroy_image cage_destroy_image 46 | #define destroy_sound cage_destroy_sound 47 | #define destroy_sprite cage_destroy_sprite 48 | #define destroy_timeline cage_destroy_timeline 49 | #define div_vec cage_div_vec 50 | #define draw_image cage_draw_image 51 | #define draw_on_image cage_draw_on_image 52 | #define draw_on_screen cage_draw_on_screen 53 | #define draw_sprite cage_draw_sprite 54 | #define draw_sprite_frame cage_draw_sprite_frame 55 | #define draw_text cage_draw_text 56 | #define elastic_ease_in cage_elastic_ease_in 57 | #define elastic_ease_in_out cage_elastic_ease_in_out 58 | #define elastic_ease_out cage_elastic_ease_out 59 | #define error_msg cage_error_msg 60 | #define exit_with_error_msg cage_exit_with_error_msg 61 | #define exponential_ease_in cage_exponential_ease_in 62 | #define exponential_ease_in_out cage_exponential_ease_in_out 63 | #define exponential_ease_out cage_exponential_ease_out 64 | #define file_spec cage_file_spec 65 | #define font cage_font 66 | #define frame cage_frame 67 | #define game_loop cage_game_loop 68 | #define game_setup_and_loop cage_game_setup_and_loop 69 | #define game_state cage_game_state 70 | #define get_error_msgs cage_get_error_msgs 71 | #define get_image_alpha cage_get_image_alpha 72 | #define get_screen_size cage_get_screen_size 73 | #define get_window_size cage_get_window_size 74 | #define hdg_vec cage_hdg_vec 75 | #define image cage_image 76 | #define init_image_from_file cage_init_image_from_file 77 | #define init_timeline cage_init_timeline 78 | #define interpolate cage_interpolate 79 | #define is_file_exists cage_is_file_exists 80 | #define is_playing cage_is_playing 81 | #define key_down cage_key_down 82 | #define key_pressed cage_key_pressed 83 | #define keyboard cage_keyboard 84 | #define linear_interpolation cage_linear_interpolation 85 | #define load_font cage_load_font 86 | #define load_sound cage_load_sound 87 | #define lock_image cage_lock_image 88 | #define measure_text cage_measure_text 89 | #define message_box cage_message_box 90 | #define mouse cage_mouse 91 | #define mul_vec cage_mul_vec 92 | #define norm_vec cage_norm_vec 93 | #define pause_timeline cage_pause_timeline 94 | #define pixels_collide cage_pixels_collide 95 | #define play_animation cage_play_animation 96 | #define play_sound cage_play_sound 97 | #define point_in_bbox cage_point_in_bbox 98 | #define prepare_sprite cage_prepare_sprite 99 | #define quadratic_ease_in cage_quadratic_ease_in 100 | #define quadratic_ease_in_out cage_quadratic_ease_in_out 101 | #define quadratic_ease_out cage_quadratic_ease_out 102 | #define quartic_ease_in cage_quartic_ease_in 103 | #define quartic_ease_in_out cage_quartic_ease_in_out 104 | #define quartic_ease_out cage_quartic_ease_out 105 | #define quintic_ease_in cage_quintic_ease_in 106 | #define quintic_ease_in_out cage_quintic_ease_in_out 107 | #define quintic_ease_out cage_quintic_ease_out 108 | #define read_file cage_read_file 109 | #define rect_from_sub_bbox cage_rect_from_sub_bbox 110 | #define rectangle cage_rectangle 111 | #define relax_screen cage_relax_screen 112 | #define reset_timeline cage_reset_timeline 113 | #define screen cage_screen 114 | #define screen_color cage_screen_color 115 | #define set_blend_mode cage_set_blend_mode 116 | #define set_image_alpha cage_set_image_alpha 117 | #define set_screen_blend_mode cage_set_screen_blend_mode 118 | #define set_screen_size cage_set_screen_size 119 | #define set_volume cage_set_volume 120 | #define set_window_size cage_set_window_size 121 | #define settings cage_settings 122 | #define shake_screen cage_shake_screen 123 | #define sine_ease_in cage_sine_ease_in 124 | #define sine_ease_in_out cage_sine_ease_in_out 125 | #define sine_ease_out cage_sine_ease_out 126 | #define sound cage_sound 127 | #define sprite cage_sprite 128 | #define stop_animation cage_stop_animation 129 | #define stop_sound cage_stop_sound 130 | #define sub_vec cage_sub_vec 131 | #define swap_vecs cage_swap_vecs 132 | #define timeline cage_timeline 133 | #define timeline_event cage_timeline_event 134 | #define toolbox cage_toolbox 135 | #define translate_bbox cage_translate_bbox 136 | #define unit_vec cage_unit_vec 137 | #define unlock_image cage_unlock_image 138 | #define update_mouse cage_update_mouse 139 | #define update_timeline cage_update_timeline 140 | #define vec_dist cage_vec_dist 141 | #define vec_dist_mntn cage_vec_dist_mntn 142 | #define vec_dist_sqrd cage_vec_dist_sqrd 143 | #define vec_len cage_vec_len 144 | #define vec_len_sqrd cage_vec_len_sqrd 145 | #define write_file cage_write_file 146 | #define xy_vec cage_xy_vec 147 | #define zero_vec cage_zero_vec 148 | #define ADD CAGE_ADD 149 | #define BLEND CAGE_BLEND 150 | #define FREEZE_LAST_FRAME CAGE_FREEZE_LAST_FRAME 151 | #define LOOP_FRAMES CAGE_LOOP_FRAMES 152 | #define MULTIPLY CAGE_MULTIPLY 153 | #define NONE CAGE_NONE 154 | #define PINGPONG_FRAMES CAGE_PINGPONG_FRAMES 155 | #endif 156 | -------------------------------------------------------------------------------- /vc/Image/Image.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {86BECCD5-3FF4-4CD7-84A5-80222AB00F98} 15 | Win32Proj 16 | Image 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 55 | ..\..\src\;..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 56 | 4244 57 | 58 | 59 | Windows 60 | true 61 | ..\Debug;..\..\3rdparty\SDL2-2.0.3\lib\x86;..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86;..\..\3rdparty\SDL2_image-2.0.0\lib\x86;%(AdditionalLibraryDirectories) 62 | Cage.lib;SDL2.lib;SDL2main.lib;SDL2_Image.lib;SDL2_Mixer.lib;%(AdditionalDependencies) 63 | 64 | 65 | xcopy ..\..\samples\image\res ..\$(Configuration)\res\ /S /Y 66 | copy ..\..\3rdparty\SDL2-2.0.3\lib\x86\SDL2.dll ..\$(Configuration)\SDL2.dll /Y 67 | copy ..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86\SDL2_mixer.dll ..\$(Configuration)\SDL2_mixer.dll /Y 68 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\SDL2_image.dll ..\$(Configuration)\SDL2_image.dll /Y 69 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\zlib1.dll ..\$(Configuration)\ /Y 70 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\libpng16-16.dll ..\$(Configuration)\ /Y 71 | 72 | 73 | 74 | 75 | Level3 76 | 77 | 78 | MaxSpeed 79 | true 80 | true 81 | WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 82 | ..\..\src\;..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 83 | 4244 84 | 85 | 86 | Windows 87 | true 88 | true 89 | true 90 | Cage.lib;SDL2.lib;SDL2main.lib;SDL2_Image.lib;SDL2_Mixer.lib;%(AdditionalDependencies) 91 | ..\Release;..\..\3rdparty\SDL2-2.0.3\lib\x86;..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86;..\..\3rdparty\SDL2_image-2.0.0\lib\x86;%(AdditionalLibraryDirectories) 92 | 93 | 94 | xcopy ..\..\samples\image\res ..\$(Configuration)\res\ /S /Y 95 | copy ..\..\3rdparty\SDL2-2.0.3\lib\x86\SDL2.dll ..\$(Configuration)\SDL2.dll /Y 96 | copy ..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86\SDL2_mixer.dll ..\$(Configuration)\SDL2_mixer.dll /Y 97 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\SDL2_image.dll ..\$(Configuration)\SDL2_image.dll /Y 98 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\zlib1.dll ..\$(Configuration)\ /Y 99 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\libpng16-16.dll ..\$(Configuration)\ /Y 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /vc/State/State.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {37C9D4F5-FF73-41D1-A0E0-956A47153965} 15 | Win32Proj 16 | State 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 55 | ..\..\src\;..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 56 | 4244 57 | 58 | 59 | Windows 60 | true 61 | ..\Debug;..\..\3rdparty\SDL2-2.0.3\lib\x86;..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86;..\..\3rdparty\SDL2_image-2.0.0\lib\x86;%(AdditionalLibraryDirectories) 62 | Cage.lib;SDL2.lib;SDL2main.lib;SDL2_Image.lib;SDL2_Mixer.lib;%(AdditionalDependencies) 63 | 64 | 65 | xcopy ..\..\samples\state\res ..\$(Configuration)\res\ /S /Y 66 | copy ..\..\3rdparty\SDL2-2.0.3\lib\x86\SDL2.dll ..\$(Configuration)\SDL2.dll /Y 67 | copy ..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86\SDL2_mixer.dll ..\$(Configuration)\SDL2_mixer.dll /Y 68 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\SDL2_image.dll ..\$(Configuration)\SDL2_image.dll /Y 69 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\zlib1.dll ..\$(Configuration)\ /Y 70 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\libpng16-16.dll ..\$(Configuration)\ /Y 71 | 72 | 73 | 74 | 75 | Level3 76 | 77 | 78 | MaxSpeed 79 | true 80 | true 81 | WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 82 | ..\..\src\;..\..\3rdparty\SDL2-2.0.3\include;..\..\3rdparty\SDL2_image-2.0.0\include;..\..\3rdparty\SDL2_mixer-2.0.0\include;%(AdditionalIncludeDirectories) 83 | 4244 84 | 85 | 86 | Windows 87 | true 88 | true 89 | true 90 | Cage.lib;SDL2.lib;SDL2main.lib;SDL2_Image.lib;SDL2_Mixer.lib;%(AdditionalDependencies) 91 | ..\Release;..\..\3rdparty\SDL2-2.0.3\lib\x86;..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86;..\..\3rdparty\SDL2_image-2.0.0\lib\x86;%(AdditionalLibraryDirectories) 92 | 93 | 94 | xcopy ..\..\samples\state\res ..\$(Configuration)\res\ /S /Y 95 | copy ..\..\3rdparty\SDL2-2.0.3\lib\x86\SDL2.dll ..\$(Configuration)\SDL2.dll /Y 96 | copy ..\..\3rdparty\SDL2_mixer-2.0.0\lib\x86\SDL2_mixer.dll ..\$(Configuration)\SDL2_mixer.dll /Y 97 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\SDL2_image.dll ..\$(Configuration)\SDL2_image.dll /Y 98 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\zlib1.dll ..\$(Configuration)\ /Y 99 | copy ..\..\3rdparty\SDL2_image-2.0.0\lib\x86\libpng16-16.dll ..\$(Configuration)\ /Y 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /cmake/FindSDL2.cmake: -------------------------------------------------------------------------------- 1 | # Locate SDL2 library 2 | # This module defines 3 | # SDL2_LIBRARY, the name of the library to link against 4 | # SDL2_FOUND, if false, do not try to link to SDL2 5 | # SDL2_INCLUDE_DIR, where to find SDL.h 6 | # 7 | # This module responds to the the flag: 8 | # SDL2_BUILDING_LIBRARY 9 | # If this is defined, then no SDL2main will be linked in because 10 | # only applications need main(). 11 | # Otherwise, it is assumed you are building an application and this 12 | # module will attempt to locate and set the the proper link flags 13 | # as part of the returned SDL2_LIBRARY variable. 14 | # 15 | # Don't forget to include SDLmain.h and SDLmain.m your project for the 16 | # OS X framework based version. (Other versions link to -lSDL2main which 17 | # this module will try to find on your behalf.) Also for OS X, this 18 | # module will automatically add the -framework Cocoa on your behalf. 19 | # 20 | # 21 | # Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration 22 | # and no SDL2_LIBRARY, it means CMake did not find your SDL2 library 23 | # (SDL2.dll, libsdl2.so, SDL2.framework, etc). 24 | # Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. 25 | # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value 26 | # as appropriate. These values are used to generate the final SDL2_LIBRARY 27 | # variable, but when these values are unset, SDL2_LIBRARY does not get created. 28 | # 29 | # 30 | # $SDL2DIR is an environment variable that would 31 | # correspond to the ./configure --prefix=$SDL2DIR 32 | # used in building SDL2. 33 | # l.e.galup 9-20-02 34 | # 35 | # Modified by Eric Wing. 36 | # Added code to assist with automated building by using environmental variables 37 | # and providing a more controlled/consistent search behavior. 38 | # Added new modifications to recognize OS X frameworks and 39 | # additional Unix paths (FreeBSD, etc). 40 | # Also corrected the header search path to follow "proper" SDL guidelines. 41 | # Added a search for SDL2main which is needed by some platforms. 42 | # Added a search for threads which is needed by some platforms. 43 | # Added needed compile switches for MinGW. 44 | # 45 | # On OSX, this will prefer the Framework version (if found) over others. 46 | # People will have to manually change the cache values of 47 | # SDL2_LIBRARY to override this selection or set the CMake environment 48 | # CMAKE_INCLUDE_PATH to modify the search paths. 49 | # 50 | # Note that the header path has changed from SDL2/SDL.h to just SDL.h 51 | # This needed to change because "proper" SDL convention 52 | # is #include "SDL.h", not . This is done for portability 53 | # reasons because not all systems place things in SDL2/ (see FreeBSD). 54 | 55 | #============================================================================= 56 | # Copyright 2003-2009 Kitware, Inc. 57 | # 58 | # Distributed under the OSI-approved BSD License (the "License"); 59 | # see accompanying file Copyright.txt for details. 60 | # 61 | # This software is distributed WITHOUT ANY WARRANTY; without even the 62 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 63 | # See the License for more information. 64 | #============================================================================= 65 | # (To distribute this file outside of CMake, substitute the full 66 | # License text for the above reference.) 67 | 68 | SET(SDL2_SEARCH_PATHS 69 | ~/Library/Frameworks 70 | /Library/Frameworks 71 | /usr/local 72 | /usr 73 | /sw # Fink 74 | /opt/local # DarwinPorts 75 | /opt/csw # Blastwave 76 | /opt 77 | ) 78 | 79 | FIND_PATH(SDL2_INCLUDE_DIR SDL.h 80 | HINTS 81 | $ENV{SDL2DIR} 82 | PATH_SUFFIXES include/SDL2 include 83 | PATHS ${SDL2_SEARCH_PATHS} 84 | ) 85 | 86 | FIND_LIBRARY(SDL2_LIBRARY_TEMP 87 | NAMES SDL2 88 | HINTS 89 | $ENV{SDL2DIR} 90 | PATH_SUFFIXES lib64 lib 91 | PATHS ${SDL2_SEARCH_PATHS} 92 | ) 93 | 94 | IF(NOT SDL2_BUILDING_LIBRARY) 95 | IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 96 | # Non-OS X framework versions expect you to also dynamically link to 97 | # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms 98 | # seem to provide SDL2main for compatibility even though they don't 99 | # necessarily need it. 100 | FIND_LIBRARY(SDL2MAIN_LIBRARY 101 | NAMES SDL2main 102 | HINTS 103 | $ENV{SDL2DIR} 104 | PATH_SUFFIXES lib64 lib 105 | PATHS ${SDL2_SEARCH_PATHS} 106 | ) 107 | ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 108 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 109 | 110 | # SDL2 may require threads on your system. 111 | # The Apple build may not need an explicit flag because one of the 112 | # frameworks may already provide it. 113 | # But for non-OSX systems, I will use the CMake Threads package. 114 | IF(NOT APPLE) 115 | FIND_PACKAGE(Threads) 116 | ENDIF(NOT APPLE) 117 | 118 | # MinGW needs an additional library, mwindows 119 | # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows 120 | # (Actually on second look, I think it only needs one of the m* libraries.) 121 | IF(MINGW) 122 | SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") 123 | ENDIF(MINGW) 124 | 125 | IF(SDL2_LIBRARY_TEMP) 126 | # For SDL2main 127 | IF(NOT SDL2_BUILDING_LIBRARY) 128 | IF(SDL2MAIN_LIBRARY) 129 | SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) 130 | ENDIF(SDL2MAIN_LIBRARY) 131 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 132 | 133 | # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. 134 | # CMake doesn't display the -framework Cocoa string in the UI even 135 | # though it actually is there if I modify a pre-used variable. 136 | # I think it has something to do with the CACHE STRING. 137 | # So I use a temporary variable until the end so I can set the 138 | # "real" variable in one-shot. 139 | IF(APPLE) 140 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") 141 | ENDIF(APPLE) 142 | 143 | # For threads, as mentioned Apple doesn't need this. 144 | # In fact, there seems to be a problem if I used the Threads package 145 | # and try using this line, so I'm just skipping it entirely for OS X. 146 | IF(NOT APPLE) 147 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) 148 | ENDIF(NOT APPLE) 149 | 150 | # For MinGW library 151 | IF(MINGW) 152 | SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) 153 | ENDIF(MINGW) 154 | 155 | # Set the final string here so the GUI reflects the final state. 156 | SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") 157 | # Set the temp variable to INTERNAL so it is not seen in the CMake GUI 158 | SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") 159 | ENDIF(SDL2_LIBRARY_TEMP) 160 | 161 | INCLUDE(FindPackageHandleStandardArgs) 162 | 163 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) 164 | --------------------------------------------------------------------------------