├── .gitignore ├── CMakeLists.txt ├── COPYRIGHT ├── README.md ├── animation.c ├── animation.h ├── bg.c ├── bg.h ├── box.c ├── box.h ├── c_array.c ├── c_array.h ├── camera.c ├── camera.h ├── cfgpath.h ├── chipmunk ├── include │ └── chipmunk │ │ ├── chipmunk.h │ │ ├── chipmunk_ffi.h │ │ ├── chipmunk_private.h │ │ ├── chipmunk_types.h │ │ ├── chipmunk_unsafe.h │ │ ├── cpArbiter.h │ │ ├── cpBB.h │ │ ├── cpBody.h │ │ ├── cpConstraint.h │ │ ├── cpDampedRotarySpring.h │ │ ├── cpDampedSpring.h │ │ ├── cpGearJoint.h │ │ ├── cpGrooveJoint.h │ │ ├── cpHastySpace.h │ │ ├── cpMarch.h │ │ ├── cpPinJoint.h │ │ ├── cpPivotJoint.h │ │ ├── cpPolyShape.h │ │ ├── cpPolyline.h │ │ ├── cpRatchetJoint.h │ │ ├── cpRotaryLimitJoint.h │ │ ├── cpShape.h │ │ ├── cpSimpleMotor.h │ │ ├── cpSlideJoint.h │ │ ├── cpSpace.h │ │ ├── cpSpatialIndex.h │ │ ├── cpTransform.h │ │ └── cpVect.h └── src │ ├── CMakeLists.txt │ ├── chipmunk.c │ ├── cpArbiter.c │ ├── cpArray.c │ ├── cpBBTree.c │ ├── cpBody.c │ ├── cpCollision.c │ ├── cpConstraint.c │ ├── cpDampedRotarySpring.c │ ├── cpDampedSpring.c │ ├── cpGearJoint.c │ ├── cpGrooveJoint.c │ ├── cpHashSet.c │ ├── cpHastySpace.c │ ├── cpMarch.c │ ├── cpPinJoint.c │ ├── cpPivotJoint.c │ ├── cpPolyShape.c │ ├── cpPolyline.c │ ├── cpRatchetJoint.c │ ├── cpRotaryLimitJoint.c │ ├── cpShape.c │ ├── cpSimpleMotor.c │ ├── cpSlideJoint.c │ ├── cpSpace.c │ ├── cpSpaceComponent.c │ ├── cpSpaceDebug.c │ ├── cpSpaceHash.c │ ├── cpSpaceQuery.c │ ├── cpSpaceStep.c │ ├── cpSpatialIndex.c │ ├── cpSweep1D.c │ └── prime.h ├── cmake ├── FindSDL2.cmake ├── FindSDL2_image.cmake ├── FindSDL2_mixer.cmake └── FindSDL2_ttf.cmake ├── data ├── LondrinaSolid-Regular.otf ├── graphics │ ├── 360.png │ ├── anim.png │ ├── eggplant.png │ ├── flare.png │ ├── floor0.png │ ├── floor1.png │ ├── floor2.png │ ├── floor3.png │ ├── floor4.png │ ├── floor5.png │ ├── gameover.png │ ├── gcw0.png │ ├── gcw0analog.png │ ├── gcw0g.png │ ├── gcw1.png │ ├── icebergs.png │ ├── icon.png │ ├── keyboard0.png │ ├── keyboard1.png │ ├── penguin_ball.png │ ├── penguin_black.png │ ├── penguin_blue.png │ ├── penguin_red.png │ ├── sparks.png │ ├── sparks_red.png │ ├── stars.png │ └── tail.png └── sounds │ ├── beep.ogg │ ├── bounce.ogg │ ├── chicken.ogg │ ├── lose.ogg │ ├── music.ogg │ ├── penguin.ogg │ ├── quack.ogg │ ├── roll.ogg │ ├── score.ogg │ ├── start.ogg │ └── turkey.ogg ├── draw.c ├── draw.h ├── game.c ├── game.h ├── gap.c ├── gap.h ├── high_score.c ├── high_score.h ├── init.c ├── init.h ├── input.c ├── input.h ├── main.c ├── main.h ├── particle.c ├── particle.h ├── pickup.c ├── pickup.h ├── pkg ├── default.gcw0.desktop ├── linux │ ├── fallingtime.png │ └── io.github.cxong.fallingtime.desktop ├── macosx │ ├── SDLMain.h │ ├── SDLMain.m │ └── icon.icns └── make_opk.sh ├── platform.h ├── platform ├── general.c └── opendingux.c ├── player.c ├── player.h ├── screenshot.png ├── sound.c ├── sound.h ├── space.c ├── space.h ├── sys_config.h.cmake ├── sys_specifics.h ├── text.c ├── text.h ├── title.c ├── title.h └── utils.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | falling_time 3 | falling_time.opk 4 | .opk_data/ 5 | libchipmunk.a 6 | sys_config.h 7 | 8 | # CMake 9 | _CPack_Packages/ 10 | CMakeFiles/ 11 | CMakeCache.txt 12 | cmake_install.cmake 13 | CPackConfig.cmake 14 | CPackSourceConfig.cmake 15 | Makefile 16 | install_manifest.txt 17 | 18 | # Windows 19 | *.vcxproj* 20 | *.opensdf 21 | *.sdf 22 | *.sln 23 | *.dir/ 24 | Falling Time-*-win32.zip 25 | Win32/ 26 | 27 | # OSX 28 | CMakeScripts/ 29 | *.build/ 30 | *.xcodeproj/ 31 | *.dmg 32 | *.app/ 33 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | The code for FallingTime is licensed under the GNU General Public License, version 2 or later at your option. 2 | 3 | Code (c) Nebuleon Fumika 4 | Cong Xu 5 | 6 | The following assets are under the licenses: 7 | 8 | SFX: 9 | - beep.ogg by pan14 (CC0) 10 | - bounce.ogg by kwahmah_02 (CC-BY) 11 | - chicken.ogg by mich3d https://freesound.org/people/mich3d/sounds/24967/ (CC-BY) 12 | - lose.ogg by Nick Bowler (CC-BY) 13 | - penguin.ogg by soundbytez https://freesound.org/people/soundbytez/sounds/111079/ (CC-BY 3.0) 14 | - quack.ogg by dobroide https://freesound.org/people/dobroide/sounds/185134/ (CC-BY 3.0) 15 | - roll.ogg by qubodup (CC0) 16 | - score.ogg by NenadSimic (CC-BY) 17 | - start.ogg by Nick Bowler (CC-BY) 18 | - turkey.ogg by JarredGibb https://freesound.org/people/JarredGibb/sounds/233123/ (CC0) 19 | 20 | Graphics: 21 | - 360.png / keyboardX.png / gcwX.png by xelu http://opengameart.org/content/free-keyboard-and-controllers-prompts-pack (CC0) 22 | - anim.png by Gab1975 (CC-BY-SA) 23 | - eggplant.png by Master484 (CC0) 24 | - icebergs.png by Brandon Blackwood (CC-BY-SA) 25 | - floor_XX.png by Gab1975 (CC-BY-SA) 26 | - gameover.png by Gab1975 (CC-BY-SA) 27 | - penguin_X.png by Gab1975 (CC-BY-SA) 28 | 29 | Music: 30 | - Space Philately by Subdream (CC-BY-SA) 31 | 32 | Font: 33 | - LondrinaSolid-Regular.otf by Marcelo Magalhães Pereira (CC-BY-SA) 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Falling Time 2 | [![Github All Releases](https://img.shields.io/github/downloads/cxong/fallingtime/total.svg)]() 3 | 4 | Like the fall down games, you are a ball and you must fall into the holes to avoid being crushed by the top of the screen! 5 | 6 | [![Gameplay video](http://img.youtube.com/vi/3MVMJkOYHSg/0.jpg)](https://www.youtube.com/watch?v=3MVMJkOYHSg) 7 | 8 | ![gameplay](https://github.com/cxong/fallingtime/blob/master/screenshot.png) 9 | 10 | This game requires SDL 2, CMake and a C compiler. It is optimised for low-resolution screens. 11 | 12 | Code is under the GPL version 2; for asset licenses see the `COPYRIGHT` file. 13 | 14 | ### Building 15 | 16 | Use **CMake**, and the libraries **SDL 2**, **SDL2_image**, **SDL2_mixer** and **SDL2_ttf**. 17 | 18 | To compile this for PC, use `cmake . && make`. You'll then get a windowed SDL game. 19 | 20 | To compile this for GCW-Zero, run `pkg/make_opk.sh` after installing the toolchain as specified in the developer docs. 21 | 22 | ### Notes 23 | 24 | The game uses a custom version of Chipmunk 2D physics; it cannot be replaced with standard libraries. 25 | -------------------------------------------------------------------------------- /animation.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "animation.h" 27 | 28 | #include 29 | 30 | #include "draw.h" 31 | #include "init.h" 32 | 33 | 34 | bool AnimationLoad( 35 | Animation *a, const char *filename, const int w, const int h, 36 | const int frameRate) 37 | { 38 | a->T = LoadTex(filename); 39 | if (a->T.T == NULL) goto bail; 40 | a->w = w; 41 | a->h = h; 42 | a->frame = 0; 43 | a->frameCounter = 0; 44 | a->frameRate = frameRate; 45 | 46 | return true; 47 | 48 | bail: 49 | AnimationFree(a); 50 | return false; 51 | } 52 | void AnimationFree(Animation *a) 53 | { 54 | SDL_DestroyTexture(a->T.T); 55 | } 56 | 57 | bool AnimationUpdate(Animation *a, const Uint32 ms) 58 | { 59 | a->frameCounter += ms; 60 | const int msPerFrame = 1000 / a->frameRate; 61 | if (a->frameCounter > msPerFrame) 62 | { 63 | a->frameCounter -= msPerFrame; 64 | a->frame++; 65 | if (a->frame == (a->T.W / a->w) * (a->T.H / a->h)) 66 | { 67 | a->frame = 0; 68 | return true; 69 | } 70 | } 71 | return false; 72 | } 73 | void AnimationDraw(const Animation *a, const int x, const int y) 74 | { 75 | const int stride = a->T.W / a->w; 76 | SDL_Rect src = { 77 | (a->frame % stride) * a->w, (a->frame / stride) * a->h, 78 | a->w, a->h 79 | }; 80 | SDL_Rect dest = { x - a->w / 2, y - a->h / 2, src.w, src.h }; 81 | RenderTex(a->T.T, &src, &dest); 82 | } 83 | void AnimationDrawUpperCenter(const Animation *a) 84 | { 85 | AnimationDraw(a, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 4); 86 | } 87 | -------------------------------------------------------------------------------- /animation.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include "c_array.h" 29 | #include "draw.h" 30 | 31 | 32 | typedef struct 33 | { 34 | Tex T; 35 | int w; 36 | int h; 37 | int frame; 38 | int frameRate; 39 | int frameCounter; 40 | } Animation; 41 | 42 | // Load an animation from a single spritesheet file 43 | bool AnimationLoad( 44 | Animation *a, const char *filename, const int w, const int h, 45 | const int frameRate); 46 | void AnimationFree(Animation *a); 47 | 48 | // Return whether the animation looped 49 | bool AnimationUpdate(Animation *a, const Uint32 ms); 50 | void AnimationDraw(const Animation *a, const int x, const int y); 51 | void AnimationDrawUpperCenter(const Animation *a); 52 | -------------------------------------------------------------------------------- /bg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #include "bg.h" 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include "draw.h" 27 | #include "init.h" 28 | #include "main.h" 29 | #include "sys_config.h" 30 | #include "utils.h" 31 | 32 | #define ICICLE_WIDTH 58 33 | #define ICICLE_HEIGHT 77 34 | #define ICICLE_Y_GAP_MIN 60 35 | #define ICICLE_Y_GAP_MAX 120 36 | #define ICICYLE_NUM 6 37 | #define FLARE_WIDTH 12 38 | #define FLARE_HEIGHT 12 39 | #define FLARE_Y_GAP_MIN 20 40 | #define FLARE_Y_GAP_MAX 40 41 | #define FLARE_NUM 4 42 | #define STAR_WIDTH 4 43 | #define STAR_HEIGHT 4 44 | #define STAR_Y_GAP_MIN 0 45 | #define STAR_Y_GAP_MAX 8 46 | #define STAR_NUM 4 47 | #define PARTICLE_RAND_X(_w) (-(_w) + (rand() % ((_w) + SCREEN_WIDTH))) 48 | #define PARTICLE_RAND_Y(_y, _gmin, _gmax) ((_y) + (_gmin) + (rand() % ((_gmax) - (_gmin)))) 49 | #define PARTICLE_RAND_INDEX(_num) (rand() % (_num)) 50 | 51 | #define SCROLL_FACTOR 0.1f 52 | #define SCALE_1 1.0f 53 | #define SCALE_2 2.0f 54 | #define SCALE_3 3.0f 55 | 56 | Backgrounds BG; 57 | 58 | static void ParticlesInit( 59 | BGParticles *p, 60 | const int w, const int gmin, const int gmax, const int num) 61 | { 62 | int y = PARTICLE_RAND_Y(0, gmin, gmax); 63 | for (int i = 0; i < MAX_PARTICLES; i++) 64 | { 65 | // Generate some random particles 66 | p->Positions[i].X = PARTICLE_RAND_X(w); 67 | p->Positions[i].Y = PARTICLE_RAND_Y(y, gmin, gmax); 68 | p->Positions[i].Index = PARTICLE_RAND_INDEX(num); 69 | y = p->Positions[i].Y; 70 | } 71 | } 72 | 73 | void BackgroundsInit(Backgrounds *bg) 74 | { 75 | ParticlesInit( 76 | &bg->Icicles, 77 | ICICLE_WIDTH, ICICLE_Y_GAP_MIN, ICICLE_Y_GAP_MAX, ICICYLE_NUM); 78 | ParticlesInit( 79 | &bg->Flares, 80 | FLARE_WIDTH, FLARE_Y_GAP_MIN, FLARE_Y_GAP_MAX, FLARE_NUM); 81 | ParticlesInit( 82 | &bg->Stars, 83 | STAR_WIDTH, STAR_Y_GAP_MIN, STAR_Y_GAP_MAX, STAR_NUM); 84 | } 85 | 86 | static void DrawParticleScroll( 87 | BGParticles *p, const int s, 88 | const int w, const int h, const int gmin, const int gmax, const int num); 89 | void DrawBackground(Backgrounds *bg, const float y) 90 | { 91 | SDL_SetRenderDrawColor(Renderer, 8, 3, 32, 255); 92 | SDL_RenderClear(Renderer); 93 | DrawParticleScroll( 94 | &bg->Icicles, (int)(y * SCROLL_FACTOR * SCALE_1), 95 | ICICLE_WIDTH, ICICLE_HEIGHT, 96 | ICICLE_Y_GAP_MIN, ICICLE_Y_GAP_MAX, ICICYLE_NUM); 97 | DrawParticleScroll( 98 | &bg->Flares, (int)(y * SCROLL_FACTOR * SCALE_2), 99 | FLARE_WIDTH, FLARE_HEIGHT, 100 | FLARE_Y_GAP_MIN, FLARE_Y_GAP_MAX, FLARE_NUM); 101 | DrawParticleScroll( 102 | &bg->Stars, (int)(y * SCROLL_FACTOR * SCALE_3), 103 | STAR_WIDTH, STAR_HEIGHT, 104 | STAR_Y_GAP_MIN, STAR_Y_GAP_MAX, STAR_NUM); 105 | } 106 | static void DrawParticleScroll( 107 | BGParticles *p, const int s, 108 | const int w, const int h, const int gmin, const int gmax, const int num) 109 | { 110 | // Remove, draw or add icicles 111 | int lastY = -1; 112 | for (int i = 0; i < MAX_PARTICLES; i++) 113 | { 114 | if (p->Positions[i].Index == -1) 115 | { 116 | // No icicles past this point; generate a new one in its place 117 | p->Positions[i].X = PARTICLE_RAND_X(w); 118 | p->Positions[i].Y = PARTICLE_RAND_Y(lastY, gmin, gmax); 119 | if (p->Positions[i].Y < s + SCREEN_HEIGHT) 120 | { 121 | // Always spawn past the bottom 122 | p->Positions[i].Y = s + SCREEN_HEIGHT; 123 | } 124 | p->Positions[i].Index = PARTICLE_RAND_INDEX(num); 125 | } 126 | else if (p->Positions[i].Y < s - h) 127 | { 128 | // Icicle past screen top, shuffle items forward 129 | memmove( 130 | &p->Positions[i], 131 | &p->Positions[i + 1], 132 | sizeof p->Positions[i] * (MAX_PARTICLES - i - 1)); 133 | // Make sure to initialise a new one at the end 134 | if (i < MAX_PARTICLES - 1) 135 | { 136 | p->Positions[MAX_PARTICLES - 1].Index = -1; 137 | } 138 | i--; 139 | continue; 140 | } 141 | 142 | // Draw if in range 143 | if (p->Positions[i].Y < s + SCREEN_HEIGHT) 144 | { 145 | SDL_Rect src = { p->Positions[i].Index * w, 0, w, h }; 146 | SDL_Rect dst = { 147 | p->Positions[i].X, p->Positions[i].Y - s, src.w, src.h 148 | }; 149 | RenderTex(p->T.T, &src, &dst); 150 | } 151 | 152 | lastY = p->Positions[i].Y; 153 | } 154 | } 155 | 156 | bool BackgroundsLoad(Backgrounds* bg) 157 | { 158 | #define LOAD_TEX(_t, _filename)\ 159 | _t = LoadTex(DATA_DIR "graphics/" _filename);\ 160 | if (_t.T == NULL)\ 161 | {\ 162 | return false;\ 163 | } 164 | LOAD_TEX(bg->Icicles.T, "icebergs.png"); 165 | LOAD_TEX(bg->Flares.T, "flare.png"); 166 | LOAD_TEX(bg->Stars.T, "stars.png"); 167 | return true; 168 | } 169 | void BackgroundsFree(Backgrounds* bg) 170 | { 171 | SDL_DestroyTexture(bg->Icicles.T.T); 172 | SDL_DestroyTexture(bg->Flares.T.T); 173 | SDL_DestroyTexture(bg->Stars.T.T); 174 | } 175 | -------------------------------------------------------------------------------- /bg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "draw.h" 25 | 26 | 27 | typedef struct 28 | { 29 | int X; 30 | int Y; 31 | int Index; 32 | } ParticlePos; 33 | #define MAX_PARTICLES 64 34 | typedef struct 35 | { 36 | Tex T; 37 | ParticlePos Positions[MAX_PARTICLES]; 38 | } BGParticles; 39 | 40 | typedef struct 41 | { 42 | BGParticles Icicles; 43 | BGParticles Flares; 44 | BGParticles Stars; 45 | } Backgrounds; 46 | extern Backgrounds BG; 47 | 48 | void BackgroundsInit(Backgrounds *bg); 49 | 50 | void DrawBackground(Backgrounds *bg, const float y); 51 | 52 | bool BackgroundsLoad(Backgrounds *bg); 53 | void BackgroundsFree(Backgrounds *bg); 54 | -------------------------------------------------------------------------------- /box.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "box.h" 27 | 28 | #include 29 | 30 | #include "draw.h" 31 | #include "game.h" 32 | #include "gap.h" 33 | #include "main.h" 34 | #include "space.h" 35 | #include "sys_config.h" 36 | #include "utils.h" 37 | 38 | #define BLOCK_SPRITE_HEIGHT 15 39 | 40 | Tex BoxTexes[6]; 41 | 42 | static cpBody *MakeBody(const float x, const float y, const float w); 43 | static Tex RandomTex(void); 44 | void BlockInit(Block *block, const float x, const float y, const float w) 45 | { 46 | block->Body = MakeBody(x, y, w); 47 | block->W = w; 48 | block->H = GAP_HEIGHT; 49 | block->T = RandomTex(); 50 | } 51 | static cpBody *MakeBody(const float x, const float y, const float w) 52 | { 53 | cpBody *body = cpSpaceAddBody(space.Space, cpBodyNewStatic()); 54 | cpBodySetPosition(body, cpv(x + w / 2, y - GAP_HEIGHT / 2)); 55 | cpShape *shape = cpSpaceAddShape( 56 | space.Space, cpBoxShapeNew(body, w, GAP_HEIGHT, 0.0)); 57 | cpShapeSetElasticity(shape, BLOCK_ELASTICITY); 58 | cpShapeSetFriction(shape, 1.0f); 59 | return body; 60 | } 61 | static Tex RandomTex(void) 62 | { 63 | return BoxTexes[rand() % 6]; 64 | } 65 | 66 | static void RemoveShape(cpBody *body, cpShape *shape, void *data); 67 | void BlockRemove(Block *block) 68 | { 69 | cpBodyEachShape(block->Body, RemoveShape, space.Space); 70 | cpSpaceRemoveBody(space.Space, block->Body); 71 | } 72 | static void RemoveShape(cpBody *body, cpShape *shape, void *data) 73 | { 74 | UNUSED(body); 75 | cpSpace *s = data; 76 | cpSpaceRemoveShape(s, shape); 77 | cpShapeFree(shape); 78 | } 79 | 80 | void BlockDraw(const Block *block, const float y) 81 | { 82 | const cpVect pos = cpBodyGetPosition(block->Body); 83 | SDL_Rect src = { 0, 0, SCREEN_X(block->W), block->T.H }; 84 | SDL_Rect dest = 85 | { 86 | (int)SCREEN_X((float)pos.x - block->W / 2), 87 | (int)(SCREEN_Y((float)pos.y + block->H / 2) - y), 88 | src.w, src.h 89 | }; 90 | RenderTex(block->T.T, &src, &dest); 91 | } 92 | 93 | 94 | bool BoxTexesLoad(void) 95 | { 96 | for (int i = 0; i < 6; i++) 97 | { 98 | char buf[256]; 99 | sprintf(buf, DATA_DIR "graphics/floor%d.png", i); 100 | BoxTexes[i] = LoadTex(buf); 101 | if (BoxTexes[i].T == NULL) 102 | { 103 | return false; 104 | } 105 | } 106 | return true; 107 | } 108 | void BoxTexesFree(void) 109 | { 110 | for (int i = 0; i < 6; i++) 111 | { 112 | SDL_DestroyTexture(BoxTexes[i].T); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /box.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | #include 30 | 31 | #include "draw.h" 32 | 33 | 34 | // Rectangular block with body 35 | typedef struct 36 | { 37 | cpBody *Body; 38 | float W, H; 39 | Tex T; 40 | } Block; 41 | 42 | extern Tex BoxTexes[6]; 43 | 44 | void BlockInit(Block *block, const float x, const float y, const float w); 45 | void BlockRemove(Block *block); 46 | void BlockDraw(const Block *block, const float y); 47 | 48 | bool BoxTexesLoad(void); 49 | void BoxTexesFree(void); 50 | -------------------------------------------------------------------------------- /c_array.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013-2014, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "c_array.h" 27 | 28 | #include 29 | #include 30 | 31 | #include "utils.h" 32 | 33 | void CArrayInit(CArray *a, size_t elemSize) 34 | { 35 | a->data = NULL; 36 | a->elemSize = elemSize; 37 | a->size = 0; 38 | a->capacity = 0; 39 | CArrayReserve(a, 1); 40 | } 41 | void CArrayReserve(CArray *a, size_t capacity) 42 | { 43 | if (a->capacity == capacity) 44 | { 45 | return; 46 | } 47 | a->capacity = capacity; 48 | CREALLOC(a->data, a->capacity * a->elemSize); 49 | } 50 | void CArrayCopy(CArray *dst, const CArray *src) 51 | { 52 | CArrayTerminate(dst); 53 | CArrayInit(dst, src->elemSize); 54 | CArrayReserve(dst, (int)src->size); 55 | for (int i = 0; i < (int)src->size; i++) 56 | { 57 | CArrayPushBack(dst, CArrayGet(src, i)); 58 | } 59 | } 60 | 61 | void CArrayPushBack(CArray *a, const void *elem) 62 | { 63 | CASSERT(a->elemSize > 0, "array has not been initialised"); 64 | if (a->size == a->capacity) 65 | { 66 | CArrayReserve(a, a->capacity * 2); 67 | } 68 | a->size++; 69 | memcpy(CArrayGet(a, a->size - 1), elem, a->elemSize); 70 | } 71 | void CArrayInsert(CArray *a, int idx, void *elem) 72 | { 73 | CASSERT(a->elemSize > 0, "array has not been initialised"); 74 | if (a->size == a->capacity) 75 | { 76 | CArrayReserve(a, a->capacity * 2); 77 | } 78 | a->size++; 79 | if (idx < (int)a->size - 1) 80 | { 81 | memmove( 82 | CArrayGet(a, idx + 1), 83 | CArrayGet(a, idx), 84 | a->elemSize * ((int)a->size - 1 - idx)); 85 | } 86 | memcpy(CArrayGet(a, idx), elem, a->elemSize); 87 | } 88 | void CArrayDelete(CArray *a, int idx) 89 | { 90 | CASSERT(a->size != 0, "Cannot delete from empty array"); 91 | CASSERT(a->elemSize > 0, "array has not been initialised"); 92 | CASSERT(idx >= 0 && idx < (int)a->size, "array index out of bounds"); 93 | if (idx < (int)a->size - 1) 94 | { 95 | memmove( 96 | CArrayGet(a, idx), 97 | CArrayGet(a, idx + 1), 98 | a->elemSize * ((int)a->size - 1 - idx)); 99 | } 100 | a->size--; 101 | } 102 | 103 | void *CArrayGet(const CArray *a, int idx) 104 | { 105 | CASSERT(a->elemSize > 0, "array has not been initialised"); 106 | CASSERT(idx >= 0 && idx < (int)a->size, "array index out of bounds"); 107 | return &((char *)a->data)[idx * a->elemSize]; 108 | } 109 | 110 | void CArrayClear(CArray *a) 111 | { 112 | a->size = 0; 113 | } 114 | 115 | void CArrayRemoveIf(CArray *a, bool (*removeIf)(const void *)) 116 | { 117 | // Note: this is the erase-remove idiom 118 | // Check all elements to see if they need to be removed 119 | // Move all the elements that don't need to be removed to the head 120 | void *dst = a->data; 121 | size_t shrunkSize = 0; 122 | for (int i = 0; i < (int)a->size; i++) 123 | { 124 | const void *elem = CArrayGet(a, i); 125 | if (!removeIf(elem)) 126 | { 127 | memmove(dst, elem, a->elemSize); 128 | dst = (char *)dst + a->elemSize; 129 | shrunkSize++; 130 | } 131 | } 132 | 133 | // Shrink the array to fit 134 | a->size = shrunkSize; 135 | } 136 | 137 | void CArrayTerminate(CArray *a) 138 | { 139 | if (!a) 140 | { 141 | return; 142 | } 143 | CFREE(a->data); 144 | memset(a, 0, sizeof *a); 145 | } 146 | -------------------------------------------------------------------------------- /c_array.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013-2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | #include 30 | 31 | // dynamic array 32 | typedef struct 33 | { 34 | void *data; 35 | size_t elemSize; 36 | size_t size; 37 | size_t capacity; 38 | } CArray; 39 | 40 | void CArrayInit(CArray *a, size_t elemSize); 41 | void CArrayReserve(CArray *a, size_t capacity); 42 | void CArrayCopy(CArray *dst, const CArray *src); 43 | void CArrayPushBack(CArray *a, const void *elem); // insert address 44 | void CArrayInsert(CArray *a, int index, void *elem); 45 | void CArrayDelete(CArray *a, int index); 46 | void *CArrayGet(const CArray *a, int index); // gets address 47 | void CArrayClear(CArray *a); 48 | void CArrayRemoveIf(CArray *a, bool (*removeIf)(const void *)); 49 | void CArrayTerminate(CArray *a); 50 | 51 | // Convenience macro for looping through a CArray 52 | #define CA_FOREACH(_type, _var, _a)\ 53 | for (int i = 0; i < (int)(_a).size; i++)\ 54 | {\ 55 | _type *_var = CArrayGet(&(_a), i); 56 | #define CA_FOREACH_END() } -------------------------------------------------------------------------------- /camera.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "camera.h" 27 | 28 | #include "game.h" 29 | #include "utils.h" 30 | 31 | // The rate at which the camera tracks the target position 32 | // Every frame it will pan from its current position to the target with 33 | // this ratio 34 | #define CAMERA_TRACK_RATIO 0.1f 35 | 36 | Camera camera; 37 | 38 | void CameraInit(Camera *c) 39 | { 40 | // Initialise camera so that players are at the bottom 41 | c->Y = FIELD_HEIGHT * (0.5f + 0.75f) - PLAYER_RADIUS; 42 | c->DY = c->Y; 43 | c->ScrollRate = FIELD_SCROLL; 44 | c->ScrollCounter = 0; 45 | } 46 | 47 | void CameraUpdate(Camera *c, const float playerY, const uint32_t ms) 48 | { 49 | c->DY -= ms * c->ScrollRate / 1000; 50 | float targetY; 51 | if (c->DY < playerY) 52 | { 53 | targetY = c->DY; 54 | } 55 | else 56 | { 57 | targetY = 0.8f * playerY + 0.2f * c->DY; 58 | } 59 | 60 | c->Y = c->Y * (1 - CAMERA_TRACK_RATIO) + targetY * CAMERA_TRACK_RATIO; 61 | 62 | c->DY = MIN(c->DY, playerY + FIELD_HEIGHT / 2); 63 | c->ScrollCounter += ms; 64 | if (c->ScrollCounter >= 1000) 65 | { 66 | c->ScrollRate += FIELD_SCROLL_SPEED; 67 | c->ScrollRate = MIN(FIELD_SCROLL_MAX, c->ScrollRate); 68 | c->ScrollCounter -= 1000; 69 | } 70 | //printf("%f\n", c->ScrollRate); 71 | // Disable scrolling 72 | //printf("%f %f\n", c->DY, c->Y); 73 | //c->Y = playerY; 74 | } 75 | -------------------------------------------------------------------------------- /camera.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | typedef struct 31 | { 32 | float DY; 33 | float Y; 34 | float ScrollRate; 35 | uint32_t ScrollCounter; 36 | } Camera; 37 | extern Camera camera; 38 | 39 | void CameraInit(Camera *c); 40 | void CameraUpdate(Camera *c, const float playerY, const uint32_t ms); 41 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/chipmunk_ffi.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #ifdef CHIPMUNK_FFI 23 | 24 | // Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs 25 | // This file should only be included in chipmunk.c 26 | 27 | // TODO: get rid of the reliance on static inlines. 28 | // They make a mess for FFIs. 29 | 30 | #ifdef _MSC_VER 31 | #if _MSC_VER >= 1600 32 | #define MAKE_REF(name) decltype(name) *_##name = name 33 | #else 34 | #define MAKE_REF(name) 35 | #endif 36 | #else 37 | #define MAKE_REF(name) __typeof__(name) *_##name = name 38 | #endif 39 | 40 | #define MAKE_PROPERTIES_REF(struct, property) \ 41 | MAKE_REF(struct##Get##property); MAKE_REF(struct##Set##property) 42 | 43 | MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv() 44 | MAKE_REF(cpveql); 45 | MAKE_REF(cpvadd); 46 | MAKE_REF(cpvneg); 47 | MAKE_REF(cpvsub); 48 | MAKE_REF(cpvmult); 49 | MAKE_REF(cpvdot); 50 | MAKE_REF(cpvcross); 51 | MAKE_REF(cpvperp); 52 | MAKE_REF(cpvrperp); 53 | MAKE_REF(cpvproject); 54 | MAKE_REF(cpvforangle); 55 | MAKE_REF(cpvtoangle); 56 | MAKE_REF(cpvrotate); 57 | MAKE_REF(cpvunrotate); 58 | MAKE_REF(cpvlengthsq); 59 | MAKE_REF(cpvlength); 60 | MAKE_REF(cpvlerp); 61 | MAKE_REF(cpvnormalize); 62 | MAKE_REF(cpvclamp); 63 | MAKE_REF(cpvlerpconst); 64 | MAKE_REF(cpvdist); 65 | MAKE_REF(cpvdistsq); 66 | MAKE_REF(cpvnear); 67 | 68 | MAKE_REF(cpfmax); 69 | MAKE_REF(cpfmin); 70 | MAKE_REF(cpfabs); 71 | MAKE_REF(cpfclamp); 72 | MAKE_REF(cpflerp); 73 | MAKE_REF(cpflerpconst); 74 | 75 | MAKE_REF(cpBBNew); 76 | MAKE_REF(cpBBNewForCircle); 77 | MAKE_REF(cpBBIntersects); 78 | MAKE_REF(cpBBContainsBB); 79 | MAKE_REF(cpBBContainsVect); 80 | MAKE_REF(cpBBMerge); 81 | MAKE_REF(cpBBExpand); 82 | MAKE_REF(cpBBArea); 83 | MAKE_REF(cpBBMergedArea); 84 | MAKE_REF(cpBBSegmentQuery); 85 | MAKE_REF(cpBBIntersectsSegment); 86 | MAKE_REF(cpBBClampVect); 87 | 88 | MAKE_REF(cpSpatialIndexDestroy); 89 | MAKE_REF(cpSpatialIndexCount); 90 | MAKE_REF(cpSpatialIndexEach); 91 | MAKE_REF(cpSpatialIndexContains); 92 | MAKE_REF(cpSpatialIndexInsert); 93 | MAKE_REF(cpSpatialIndexRemove); 94 | MAKE_REF(cpSpatialIndexReindex); 95 | MAKE_REF(cpSpatialIndexReindexObject); 96 | MAKE_REF(cpSpatialIndexSegmentQuery); 97 | MAKE_REF(cpSpatialIndexQuery); 98 | MAKE_REF(cpSpatialIndexReindexQuery); 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/chipmunk_unsafe.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /* This header defines a number of "unsafe" operations on Chipmunk objects. 23 | * In this case "unsafe" is referring to operations which may reduce the 24 | * physical accuracy or numerical stability of the simulation, but will not 25 | * cause crashes. 26 | * 27 | * The prime example is mutating collision shapes. Chipmunk does not support 28 | * this directly. Mutating shapes using this API will caused objects in contact 29 | * to be pushed apart using Chipmunk's overlap solver, but not using real 30 | * persistent velocities. Probably not what you meant, but perhaps close enough. 31 | */ 32 | 33 | /// @defgroup unsafe Chipmunk Unsafe Shape Operations 34 | /// These functions are used for mutating collision shapes. 35 | /// Chipmunk does not have any way to get velocity information on changing shapes, 36 | /// so the results will be unrealistic. You must explicity include the chipmunk_unsafe.h header to use them. 37 | /// @{ 38 | 39 | #ifndef CHIPMUNK_UNSAFE_H 40 | #define CHIPMUNK_UNSAFE_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /// Set the radius of a circle shape. 47 | void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius); 48 | /// Set the offset of a circle shape. 49 | void cpCircleShapeSetOffset(cpShape *shape, cpVect offset); 50 | 51 | /// Set the endpoints of a segment shape. 52 | void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b); 53 | /// Set the radius of a segment shape. 54 | void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius); 55 | 56 | /// Set the vertexes of a poly shape. 57 | void cpPolyShapeSetVerts(cpShape *shape, int count, cpVect *verts, cpTransform transform); 58 | void cpPolyShapeSetVertsRaw(cpShape *shape, int count, cpVect *verts); 59 | /// Set the radius of a poly shape. 60 | void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | #endif 66 | /// @} 67 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpConstraint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpConstraint cpConstraint 23 | /// @{ 24 | 25 | /// Callback function type that gets called before solving a joint. 26 | typedef void (*cpConstraintPreSolveFunc)(cpConstraint *constraint, cpSpace *space); 27 | /// Callback function type that gets called after solving a joint. 28 | typedef void (*cpConstraintPostSolveFunc)(cpConstraint *constraint, cpSpace *space); 29 | 30 | /// Destroy a constraint. 31 | void cpConstraintDestroy(cpConstraint *constraint); 32 | /// Destroy and free a constraint. 33 | void cpConstraintFree(cpConstraint *constraint); 34 | 35 | /// Get the cpSpace this constraint is added to. 36 | cpSpace* cpConstraintGetSpace(const cpConstraint *constraint); 37 | 38 | /// Get the first body the constraint is attached to. 39 | cpBody* cpConstraintGetBodyA(const cpConstraint *constraint); 40 | 41 | /// Get the second body the constraint is attached to. 42 | cpBody* cpConstraintGetBodyB(const cpConstraint *constraint); 43 | 44 | /// Get the maximum force that this constraint is allowed to use. 45 | cpFloat cpConstraintGetMaxForce(const cpConstraint *constraint); 46 | /// Set the maximum force that this constraint is allowed to use. (defaults to INFINITY) 47 | void cpConstraintSetMaxForce(cpConstraint *constraint, cpFloat maxForce); 48 | 49 | /// Get rate at which joint error is corrected. 50 | cpFloat cpConstraintGetErrorBias(const cpConstraint *constraint); 51 | /// Set rate at which joint error is corrected. 52 | /// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will 53 | /// correct 10% of the error every 1/60th of a second. 54 | void cpConstraintSetErrorBias(cpConstraint *constraint, cpFloat errorBias); 55 | 56 | /// Get the maximum rate at which joint error is corrected. 57 | cpFloat cpConstraintGetMaxBias(const cpConstraint *constraint); 58 | /// Set the maximum rate at which joint error is corrected. (defaults to INFINITY) 59 | void cpConstraintSetMaxBias(cpConstraint *constraint, cpFloat maxBias); 60 | 61 | /// Get if the two bodies connected by the constraint are allowed to collide or not. 62 | cpBool cpConstraintGetCollideBodies(const cpConstraint *constraint); 63 | /// Set if the two bodies connected by the constraint are allowed to collide or not. (defaults to cpFalse) 64 | void cpConstraintSetCollideBodies(cpConstraint *constraint, cpBool collideBodies); 65 | 66 | /// Get the pre-solve function that is called before the solver runs. 67 | cpConstraintPreSolveFunc cpConstraintGetPreSolveFunc(const cpConstraint *constraint); 68 | /// Set the pre-solve function that is called before the solver runs. 69 | void cpConstraintSetPreSolveFunc(cpConstraint *constraint, cpConstraintPreSolveFunc preSolveFunc); 70 | 71 | /// Get the post-solve function that is called before the solver runs. 72 | cpConstraintPostSolveFunc cpConstraintGetPostSolveFunc(const cpConstraint *constraint); 73 | /// Set the post-solve function that is called before the solver runs. 74 | void cpConstraintSetPostSolveFunc(cpConstraint *constraint, cpConstraintPostSolveFunc postSolveFunc); 75 | 76 | /// Get the user definable data pointer for this constraint 77 | cpDataPointer cpConstraintGetUserData(const cpConstraint *constraint); 78 | /// Set the user definable data pointer for this constraint 79 | void cpConstraintSetUserData(cpConstraint *constraint, cpDataPointer userData); 80 | 81 | /// Get the last impulse applied by this constraint. 82 | cpFloat cpConstraintGetImpulse(cpConstraint *constraint); 83 | 84 | #include "cpPinJoint.h" 85 | #include "cpSlideJoint.h" 86 | #include "cpPivotJoint.h" 87 | #include "cpGrooveJoint.h" 88 | #include "cpDampedSpring.h" 89 | #include "cpDampedRotarySpring.h" 90 | #include "cpRotaryLimitJoint.h" 91 | #include "cpRatchetJoint.h" 92 | #include "cpGearJoint.h" 93 | #include "cpSimpleMotor.h" 94 | 95 | ///@} 96 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpDampedRotarySpring.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpDampedRotarySpring cpDampedRotarySpring 23 | /// @{ 24 | 25 | /// Check if a constraint is a damped rotary springs. 26 | cpBool cpConstraintIsDampedRotarySpring(const cpConstraint *constraint); 27 | 28 | /// Function type used for damped rotary spring force callbacks. 29 | typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle); 30 | 31 | /// Allocate a damped rotary spring. 32 | cpDampedRotarySpring* cpDampedRotarySpringAlloc(void); 33 | /// Initialize a damped rotary spring. 34 | cpDampedRotarySpring* cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping); 35 | /// Allocate and initialize a damped rotary spring. 36 | cpConstraint* cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping); 37 | 38 | /// Get the rest length of the spring. 39 | cpFloat cpDampedRotarySpringGetRestAngle(const cpConstraint *constraint); 40 | /// Set the rest length of the spring. 41 | void cpDampedRotarySpringSetRestAngle(cpConstraint *constraint, cpFloat restAngle); 42 | 43 | /// Get the stiffness of the spring in force/distance. 44 | cpFloat cpDampedRotarySpringGetStiffness(const cpConstraint *constraint); 45 | /// Set the stiffness of the spring in force/distance. 46 | void cpDampedRotarySpringSetStiffness(cpConstraint *constraint, cpFloat stiffness); 47 | 48 | /// Get the damping of the spring. 49 | cpFloat cpDampedRotarySpringGetDamping(const cpConstraint *constraint); 50 | /// Set the damping of the spring. 51 | void cpDampedRotarySpringSetDamping(cpConstraint *constraint, cpFloat damping); 52 | 53 | /// Get the damping of the spring. 54 | cpDampedRotarySpringTorqueFunc cpDampedRotarySpringGetSpringTorqueFunc(const cpConstraint *constraint); 55 | /// Set the damping of the spring. 56 | void cpDampedRotarySpringSetSpringTorqueFunc(cpConstraint *constraint, cpDampedRotarySpringTorqueFunc springTorqueFunc); 57 | 58 | /// @} 59 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpDampedSpring.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpDampedSpring cpDampedSpring 23 | /// @{ 24 | 25 | /// Check if a constraint is a slide joint. 26 | cpBool cpConstraintIsDampedSpring(const cpConstraint *constraint); 27 | 28 | /// Function type used for damped spring force callbacks. 29 | typedef cpFloat (*cpDampedSpringForceFunc)(cpConstraint *spring, cpFloat dist); 30 | 31 | /// Allocate a damped spring. 32 | cpDampedSpring* cpDampedSpringAlloc(void); 33 | /// Initialize a damped spring. 34 | cpDampedSpring* cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping); 35 | /// Allocate and initialize a damped spring. 36 | cpConstraint* cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB, cpFloat restLength, cpFloat stiffness, cpFloat damping); 37 | 38 | /// Get the location of the first anchor relative to the first body. 39 | cpVect cpDampedSpringGetAnchorA(const cpConstraint *constraint); 40 | /// Set the location of the first anchor relative to the first body. 41 | void cpDampedSpringSetAnchorA(cpConstraint *constraint, cpVect anchorA); 42 | 43 | /// Get the location of the second anchor relative to the second body. 44 | cpVect cpDampedSpringGetAnchorB(const cpConstraint *constraint); 45 | /// Set the location of the second anchor relative to the second body. 46 | void cpDampedSpringSetAnchorB(cpConstraint *constraint, cpVect anchorB); 47 | 48 | /// Get the rest length of the spring. 49 | cpFloat cpDampedSpringGetRestLength(const cpConstraint *constraint); 50 | /// Set the rest length of the spring. 51 | void cpDampedSpringSetRestLength(cpConstraint *constraint, cpFloat restLength); 52 | 53 | /// Get the stiffness of the spring in force/distance. 54 | cpFloat cpDampedSpringGetStiffness(const cpConstraint *constraint); 55 | /// Set the stiffness of the spring in force/distance. 56 | void cpDampedSpringSetStiffness(cpConstraint *constraint, cpFloat stiffness); 57 | 58 | /// Get the damping of the spring. 59 | cpFloat cpDampedSpringGetDamping(const cpConstraint *constraint); 60 | /// Set the damping of the spring. 61 | void cpDampedSpringSetDamping(cpConstraint *constraint, cpFloat damping); 62 | 63 | /// Get the damping of the spring. 64 | cpDampedSpringForceFunc cpDampedSpringGetSpringForceFunc(const cpConstraint *constraint); 65 | /// Set the damping of the spring. 66 | void cpDampedSpringSetSpringForceFunc(cpConstraint *constraint, cpDampedSpringForceFunc springForceFunc); 67 | 68 | /// @} 69 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpGearJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpGearJoint cpGearJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a damped rotary springs. 26 | cpBool cpConstraintIsGearJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a gear joint. 29 | cpGearJoint* cpGearJointAlloc(void); 30 | /// Initialize a gear joint. 31 | cpGearJoint* cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio); 32 | /// Allocate and initialize a gear joint. 33 | cpConstraint* cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio); 34 | 35 | /// Get the phase offset of the gears. 36 | cpFloat cpGearJointGetPhase(const cpConstraint *constraint); 37 | /// Set the phase offset of the gears. 38 | void cpGearJointSetPhase(cpConstraint *constraint, cpFloat phase); 39 | 40 | /// Get the angular distance of each ratchet. 41 | cpFloat cpGearJointGetRatio(const cpConstraint *constraint); 42 | /// Set the ratio of a gear joint. 43 | void cpGearJointSetRatio(cpConstraint *constraint, cpFloat ratio); 44 | 45 | /// @} 46 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpGrooveJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpGrooveJoint cpGrooveJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a slide joint. 26 | cpBool cpConstraintIsGrooveJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a groove joint. 29 | cpGrooveJoint* cpGrooveJointAlloc(void); 30 | /// Initialize a groove joint. 31 | cpGrooveJoint* cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchorB); 32 | /// Allocate and initialize a groove joint. 33 | cpConstraint* cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchorB); 34 | 35 | /// Get the first endpoint of the groove relative to the first body. 36 | cpVect cpGrooveJointGetGrooveA(const cpConstraint *constraint); 37 | /// Set the first endpoint of the groove relative to the first body. 38 | void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect grooveA); 39 | 40 | /// Get the first endpoint of the groove relative to the first body. 41 | cpVect cpGrooveJointGetGrooveB(const cpConstraint *constraint); 42 | /// Set the first endpoint of the groove relative to the first body. 43 | void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect grooveB); 44 | 45 | /// Get the location of the second anchor relative to the second body. 46 | cpVect cpGrooveJointGetAnchorB(const cpConstraint *constraint); 47 | /// Set the location of the second anchor relative to the second body. 48 | void cpGrooveJointSetAnchorB(cpConstraint *constraint, cpVect anchorB); 49 | 50 | /// @} 51 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpHastySpace.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Howling Moon Software. All rights reserved. 2 | // See http://chipmunk2d.net/legal.php for more information. 3 | 4 | /// cpHastySpace is exclusive to Chipmunk Pro 5 | /// Currently it enables ARM NEON optimizations in the solver, but in the future will include other optimizations such as 6 | /// a multi-threaded solver and multi-threaded collision broadphases. 7 | 8 | struct cpHastySpace; 9 | typedef struct cpHastySpace cpHastySpace; 10 | 11 | /// Create a new hasty space. 12 | /// On ARM platforms that support NEON, this will enable the vectorized solver. 13 | /// cpHastySpace also supports multiple threads, but runs single threaded by default for determinism. 14 | cpSpace *cpHastySpaceNew(void); 15 | void cpHastySpaceFree(cpSpace *space); 16 | 17 | /// Set the number of threads to use for the solver. 18 | /// Currently Chipmunk is limited to 2 threads as using more generally provides very minimal performance gains. 19 | /// Passing 0 as the thread count on iOS or OS X will cause Chipmunk to automatically detect the number of threads it should use. 20 | /// On other platforms passing 0 for the thread count will set 1 thread. 21 | void cpHastySpaceSetThreads(cpSpace *space, unsigned long threads); 22 | 23 | /// Returns the number of threads the solver is using to run. 24 | unsigned long cpHastySpaceGetThreads(cpSpace *space); 25 | 26 | /// When stepping a hasty space, you must use this function. 27 | void cpHastySpaceStep(cpSpace *space, cpFloat dt); 28 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpMarch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Howling Moon Software. All rights reserved. 2 | // See http://chipmunk2d.net/legal.php for more information. 3 | 4 | /// Function type used as a callback from the marching squares algorithm to sample an image function. 5 | /// It passes you the point to sample and your context pointer, and you return the density. 6 | typedef cpFloat (*cpMarchSampleFunc)(cpVect point, void *data); 7 | 8 | /// Function type used as a callback from the marching squares algorithm to output a line segment. 9 | /// It passes you the two endpoints and your context pointer. 10 | typedef void (*cpMarchSegmentFunc)(cpVect v0, cpVect v1, void *data); 11 | 12 | /// Trace an anti-aliased contour of an image along a particular threshold. 13 | /// The given number of samples will be taken and spread across the bounding box area using the sampling function and context. 14 | /// The segment function will be called for each segment detected that lies along the density contour for @c threshold. 15 | void cpMarchSoft( 16 | cpBB bb, unsigned long x_samples, unsigned long y_samples, cpFloat threshold, 17 | cpMarchSegmentFunc segment, void *segment_data, 18 | cpMarchSampleFunc sample, void *sample_data 19 | ); 20 | 21 | /// Trace an aliased curve of an image along a particular threshold. 22 | /// The given number of samples will be taken and spread across the bounding box area using the sampling function and context. 23 | /// The segment function will be called for each segment detected that lies along the density contour for @c threshold. 24 | void cpMarchHard( 25 | cpBB bb, unsigned long x_samples, unsigned long y_samples, cpFloat threshold, 26 | cpMarchSegmentFunc segment, void *segment_data, 27 | cpMarchSampleFunc sample, void *sample_data 28 | ); 29 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpPinJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpPinJoint cpPinJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a pin joint. 26 | cpBool cpConstraintIsPinJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a pin joint. 29 | cpPinJoint* cpPinJointAlloc(void); 30 | /// Initialize a pin joint. 31 | cpPinJoint* cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB); 32 | /// Allocate and initialize a pin joint. 33 | cpConstraint* cpPinJointNew(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB); 34 | 35 | /// Get the location of the first anchor relative to the first body. 36 | cpVect cpPinJointGetAnchorA(const cpConstraint *constraint); 37 | /// Set the location of the first anchor relative to the first body. 38 | void cpPinJointSetAnchorA(cpConstraint *constraint, cpVect anchorA); 39 | 40 | /// Get the location of the second anchor relative to the second body. 41 | cpVect cpPinJointGetAnchorB(const cpConstraint *constraint); 42 | /// Set the location of the second anchor relative to the second body. 43 | void cpPinJointSetAnchorB(cpConstraint *constraint, cpVect anchorB); 44 | 45 | /// Get the distance the joint will maintain between the two anchors. 46 | cpFloat cpPinJointGetDist(const cpConstraint *constraint); 47 | /// Set the distance the joint will maintain between the two anchors. 48 | void cpPinJointSetDist(cpConstraint *constraint, cpFloat dist); 49 | 50 | ///@} 51 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpPivotJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpPivotJoint cpPivotJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a slide joint. 26 | cpBool cpConstraintIsPivotJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a pivot joint 29 | cpPivotJoint* cpPivotJointAlloc(void); 30 | /// Initialize a pivot joint. 31 | cpPivotJoint* cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB); 32 | /// Allocate and initialize a pivot joint. 33 | cpConstraint* cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot); 34 | /// Allocate and initialize a pivot joint with specific anchors. 35 | cpConstraint* cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB); 36 | 37 | /// Get the location of the first anchor relative to the first body. 38 | cpVect cpPivotJointGetAnchorA(const cpConstraint *constraint); 39 | /// Set the location of the first anchor relative to the first body. 40 | void cpPivotJointSetAnchorA(cpConstraint *constraint, cpVect anchorA); 41 | 42 | /// Get the location of the second anchor relative to the second body. 43 | cpVect cpPivotJointGetAnchorB(const cpConstraint *constraint); 44 | /// Set the location of the second anchor relative to the second body. 45 | void cpPivotJointSetAnchorB(cpConstraint *constraint, cpVect anchorB); 46 | 47 | /// @} 48 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpPolyShape.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpPolyShape cpPolyShape 23 | /// @{ 24 | 25 | /// Allocate a polygon shape. 26 | cpPolyShape* cpPolyShapeAlloc(void); 27 | /// Initialize a polygon shape with rounded corners. 28 | /// A convex hull will be created from the vertexes. 29 | cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius); 30 | /// Initialize a polygon shape with rounded corners. 31 | /// The vertexes must be convex with a counter-clockwise winding. 32 | cpPolyShape* cpPolyShapeInitRaw(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpFloat radius); 33 | /// Allocate and initialize a polygon shape with rounded corners. 34 | /// A convex hull will be created from the vertexes. 35 | cpShape* cpPolyShapeNew(cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius); 36 | /// Allocate and initialize a polygon shape with rounded corners. 37 | /// The vertexes must be convex with a counter-clockwise winding. 38 | cpShape* cpPolyShapeNewRaw(cpBody *body, int count, const cpVect *verts, cpFloat radius); 39 | 40 | /// Initialize a box shaped polygon shape with rounded corners. 41 | cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height, cpFloat radius); 42 | /// Initialize an offset box shaped polygon shape with rounded corners. 43 | cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius); 44 | /// Allocate and initialize a box shaped polygon shape. 45 | cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height, cpFloat radius); 46 | /// Allocate and initialize an offset box shaped polygon shape. 47 | cpShape* cpBoxShapeNew2(cpBody *body, cpBB box, cpFloat radius); 48 | 49 | /// Get the number of verts in a polygon shape. 50 | int cpPolyShapeGetCount(const cpShape *shape); 51 | /// Get the @c ith vertex of a polygon shape. 52 | cpVect cpPolyShapeGetVert(const cpShape *shape, int index); 53 | /// Get the radius of a polygon shape. 54 | cpFloat cpPolyShapeGetRadius(const cpShape *shape); 55 | 56 | /// @} 57 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpPolyline.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Howling Moon Software. All rights reserved. 2 | // See http://chipmunk2d.net/legal.php for more information. 3 | 4 | // Polylines are just arrays of vertexes. 5 | // They are looped if the first vertex is equal to the last. 6 | // cpPolyline structs are intended to be passed by value and destroyed when you are done with them. 7 | typedef struct cpPolyline { 8 | int count, capacity; 9 | cpVect verts[]; 10 | } cpPolyline; 11 | 12 | /// Destroy and free a polyline instance. 13 | void cpPolylineFree(cpPolyline *line); 14 | 15 | /// Returns true if the first vertex is equal to the last. 16 | cpBool cpPolylineIsClosed(cpPolyline *line); 17 | 18 | /** 19 | Returns a copy of a polyline simplified by using the Douglas-Peucker algorithm. 20 | This works very well on smooth or gently curved shapes, but not well on straight edged or angular shapes. 21 | */ 22 | cpPolyline *cpPolylineSimplifyCurves(cpPolyline *line, cpFloat tol); 23 | 24 | /** 25 | Returns a copy of a polyline simplified by discarding "flat" vertexes. 26 | This works well on straigt edged or angular shapes, not as well on smooth shapes. 27 | */ 28 | cpPolyline *cpPolylineSimplifyVertexes(cpPolyline *line, cpFloat tol); 29 | 30 | /// Get the convex hull of a polyline as a looped polyline. 31 | cpPolyline *cpPolylineToConvexHull(cpPolyline *line, cpFloat tol); 32 | 33 | 34 | /// Polyline sets are collections of polylines, generally built by cpMarchSoft() or cpMarchHard(). 35 | typedef struct cpPolylineSet { 36 | int count, capacity; 37 | cpPolyline **lines; 38 | } cpPolylineSet; 39 | 40 | /// Allocate a new polyline set. 41 | cpPolylineSet *cpPolylineSetAlloc(void); 42 | 43 | /// Initialize a new polyline set. 44 | cpPolylineSet *cpPolylineSetInit(cpPolylineSet *set); 45 | 46 | /// Allocate and initialize a polyline set. 47 | cpPolylineSet *cpPolylineSetNew(void); 48 | 49 | /// Destroy a polyline set. 50 | void cpPolylineSetDestroy(cpPolylineSet *set, cpBool freePolylines); 51 | 52 | /// Destroy and free a polyline set. 53 | void cpPolylineSetFree(cpPolylineSet *set, cpBool freePolylines); 54 | 55 | /** 56 | Add a line segment to a polyline set. 57 | A segment will either start a new polyline, join two others, or add to or loop an existing polyline. 58 | This is mostly intended to be used as a callback directly from cpMarchSoft() or cpMarchHard(). 59 | */ 60 | void cpPolylineSetCollectSegment(cpVect v0, cpVect v1, cpPolylineSet *lines); 61 | 62 | /** 63 | Get an approximate convex decomposition from a polyline. 64 | Returns a cpPolylineSet of convex hulls that match the original shape to within 'tol'. 65 | NOTE: If the input is a self intersecting polygon, the output might end up overly simplified. 66 | */ 67 | 68 | cpPolylineSet *cpPolylineConvexDecomposition(cpPolyline *line, cpFloat tol); 69 | 70 | #define cpPolylineConvexDecomposition_BETA cpPolylineConvexDecomposition 71 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpRatchetJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpRatchetJoint cpRatchetJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a damped rotary springs. 26 | cpBool cpConstraintIsRatchetJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a ratchet joint. 29 | cpRatchetJoint* cpRatchetJointAlloc(void); 30 | /// Initialize a ratched joint. 31 | cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet); 32 | /// Allocate and initialize a ratchet joint. 33 | cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet); 34 | 35 | /// Get the angle of the current ratchet tooth. 36 | cpFloat cpRatchetJointGetAngle(const cpConstraint *constraint); 37 | /// Set the angle of the current ratchet tooth. 38 | void cpRatchetJointSetAngle(cpConstraint *constraint, cpFloat angle); 39 | 40 | /// Get the phase offset of the ratchet. 41 | cpFloat cpRatchetJointGetPhase(const cpConstraint *constraint); 42 | /// Get the phase offset of the ratchet. 43 | void cpRatchetJointSetPhase(cpConstraint *constraint, cpFloat phase); 44 | 45 | /// Get the angular distance of each ratchet. 46 | cpFloat cpRatchetJointGetRatchet(const cpConstraint *constraint); 47 | /// Set the angular distance of each ratchet. 48 | void cpRatchetJointSetRatchet(cpConstraint *constraint, cpFloat ratchet); 49 | 50 | /// @} 51 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpRotaryLimitJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpRotaryLimitJoint cpRotaryLimitJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a damped rotary springs. 26 | cpBool cpConstraintIsRotaryLimitJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a damped rotary limit joint. 29 | cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void); 30 | /// Initialize a damped rotary limit joint. 31 | cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max); 32 | /// Allocate and initialize a damped rotary limit joint. 33 | cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max); 34 | 35 | /// Get the minimum distance the joint will maintain between the two anchors. 36 | cpFloat cpRotaryLimitJointGetMin(const cpConstraint *constraint); 37 | /// Set the minimum distance the joint will maintain between the two anchors. 38 | void cpRotaryLimitJointSetMin(cpConstraint *constraint, cpFloat min); 39 | 40 | /// Get the maximum distance the joint will maintain between the two anchors. 41 | cpFloat cpRotaryLimitJointGetMax(const cpConstraint *constraint); 42 | /// Set the maximum distance the joint will maintain between the two anchors. 43 | void cpRotaryLimitJointSetMax(cpConstraint *constraint, cpFloat max); 44 | 45 | /// @} 46 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpSimpleMotor.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpSimpleMotor cpSimpleMotor 23 | /// @{ 24 | 25 | /// Opaque struct type for damped rotary springs. 26 | typedef struct cpSimpleMotor cpSimpleMotor; 27 | 28 | /// Check if a constraint is a damped rotary springs. 29 | cpBool cpConstraintIsSimpleMotor(const cpConstraint *constraint); 30 | 31 | /// Allocate a simple motor. 32 | cpSimpleMotor* cpSimpleMotorAlloc(void); 33 | /// initialize a simple motor. 34 | cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate); 35 | /// Allocate and initialize a simple motor. 36 | cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate); 37 | 38 | /// Get the rate of the motor. 39 | cpFloat cpSimpleMotorGetRate(const cpConstraint *constraint); 40 | /// Set the rate of the motor. 41 | void cpSimpleMotorSetRate(cpConstraint *constraint, cpFloat rate); 42 | 43 | /// @} 44 | -------------------------------------------------------------------------------- /chipmunk/include/chipmunk/cpSlideJoint.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | /// @defgroup cpSlideJoint cpSlideJoint 23 | /// @{ 24 | 25 | /// Check if a constraint is a slide joint. 26 | cpBool cpConstraintIsSlideJoint(const cpConstraint *constraint); 27 | 28 | /// Allocate a slide joint. 29 | cpSlideJoint* cpSlideJointAlloc(void); 30 | /// Initialize a slide joint. 31 | cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB, cpFloat min, cpFloat max); 32 | /// Allocate and initialize a slide joint. 33 | cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB, cpFloat min, cpFloat max); 34 | 35 | /// Get the location of the first anchor relative to the first body. 36 | cpVect cpSlideJointGetAnchorA(const cpConstraint *constraint); 37 | /// Set the location of the first anchor relative to the first body. 38 | void cpSlideJointSetAnchorA(cpConstraint *constraint, cpVect anchorA); 39 | 40 | /// Get the location of the second anchor relative to the second body. 41 | cpVect cpSlideJointGetAnchorB(const cpConstraint *constraint); 42 | /// Set the location of the second anchor relative to the second body. 43 | void cpSlideJointSetAnchorB(cpConstraint *constraint, cpVect anchorB); 44 | 45 | /// Get the minimum distance the joint will maintain between the two anchors. 46 | cpFloat cpSlideJointGetMin(const cpConstraint *constraint); 47 | /// Set the minimum distance the joint will maintain between the two anchors. 48 | void cpSlideJointSetMin(cpConstraint *constraint, cpFloat min); 49 | 50 | /// Get the maximum distance the joint will maintain between the two anchors. 51 | cpFloat cpSlideJointGetMax(const cpConstraint *constraint); 52 | /// Set the maximum distance the joint will maintain between the two anchors. 53 | void cpSlideJointSetMax(cpConstraint *constraint, cpFloat max); 54 | 55 | /// @} 56 | -------------------------------------------------------------------------------- /chipmunk/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB chipmunk_source_files "*.c") 2 | file(GLOB chipmunk_public_header "${chipmunk_SOURCE_DIR}/include/chipmunk/*.h") 3 | 4 | list(REMOVE_ITEM chipmunk_source_files "${chipmunk_SOURCE_DIR}/src/cpHastySpace.c") 5 | list(REMOVE_ITEM chipmunk_source_files "${chipmunk_SOURCE_DIR}/src/cpPolyline.c") 6 | 7 | include_directories(${chipmunk_SOURCE_DIR}/include) 8 | 9 | set(CHIPMUNK_VERSION_MAJOR 7) 10 | set(CHIPMUNK_VERSION_MINOR 0) 11 | set(CHIPMUNK_VERSION_PATCH 0) 12 | set(CHIPMUNK_VERSION "${CHIPMUNK_VERSION_MAJOR}.${CHIPMUNK_VERSION_MINOR}.${CHIPMUNK_VERSION_PATCH}") 13 | message("Configuring Chipmunk2D version ${CHIPMUNK_VERSION}") 14 | 15 | 16 | if(BUILD_SHARED) 17 | add_library(chipmunk SHARED 18 | ${chipmunk_source_files} 19 | ) 20 | # Tell MSVC to compile the code as C++. 21 | if(MSVC) 22 | set_source_files_properties(${chipmunk_source_files} PROPERTIES LANGUAGE CXX) 23 | set_target_properties(chipmunk PROPERTIES LINKER_LANGUAGE CXX) 24 | else() 25 | add_definitions(-std=c99) 26 | endif() 27 | # set the lib's version number 28 | # But avoid on Android because symlinks to version numbered .so's don't work with Android's Java-side loadLibrary. 29 | if(NOT ANDROID) 30 | set_target_properties(chipmunk PROPERTIES 31 | SOVERSION ${CHIPMUNK_VERSION_MAJOR} 32 | VERSION ${CHIPMUNK_VERSION}) 33 | endif(NOT ANDROID) 34 | if(ANDROID OR UNIX) 35 | # need to explicitly link to the math library because the CMake/Android toolchains may not do it automatically 36 | target_link_libraries(chipmunk m) 37 | endif(ANDROID OR UNIX) 38 | install(TARGETS chipmunk RUNTIME DESTINATION ${BIN_INSTALL_DIR} 39 | LIBRARY DESTINATION ${LIB_INSTALL_DIR} 40 | ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) 41 | endif(BUILD_SHARED) 42 | 43 | if(BUILD_STATIC) 44 | add_library(chipmunk_static STATIC 45 | ${chipmunk_source_files} 46 | ) 47 | # Tell MSVC to compile the code as C++. 48 | if(MSVC) 49 | set_source_files_properties(${chipmunk_source_files} PROPERTIES LANGUAGE CXX) 50 | set_target_properties(chipmunk_static PROPERTIES LINKER_LANGUAGE CXX) 51 | else() 52 | add_definitions(-std=c99) 53 | endif() 54 | # Sets chipmunk_static to output "libchipmunk.a" not "libchipmunk_static.a" 55 | set_target_properties(chipmunk_static PROPERTIES OUTPUT_NAME chipmunk) 56 | if(INSTALL_STATIC) 57 | install(TARGETS chipmunk_static ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) 58 | endif(INSTALL_STATIC) 59 | endif(BUILD_STATIC) 60 | 61 | if(BUILD_SHARED OR INSTALL_STATIC) 62 | # FIXME: change to PUBLIC_HEADER to allow building frameworks 63 | install(FILES ${chipmunk_public_header} DESTINATION include/chipmunk) 64 | install(FILES ${chipmunk_constraint_header} DESTINATION include/chipmunk/constraints) 65 | endif(BUILD_SHARED OR INSTALL_STATIC) 66 | 67 | if(CMAKE_BUILD_TYPE STREQUAL "Release") 68 | set(CMAKE_C_FLAGS_RELEASE "-O2 -g0") 69 | add_definitions(-DNDEBUG) 70 | elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") 71 | set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g") 72 | add_definitions(-DNDEBUG) 73 | elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") 74 | set(CMAKE_C_FLAGS_MINSIZEREL "-Os -g0") 75 | add_definitions(-DNDEBUG) 76 | elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") 77 | set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -pg") 78 | set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg") 79 | set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-pg") 80 | set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-pg") 81 | endif() 82 | -------------------------------------------------------------------------------- /chipmunk/src/cpArray.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include 23 | 24 | #include "chipmunk/chipmunk_private.h" 25 | 26 | 27 | cpArray * 28 | cpArrayNew(int size) 29 | { 30 | cpArray *arr = (cpArray *)cpcalloc(1, sizeof(cpArray)); 31 | 32 | arr->num = 0; 33 | arr->max = (size ? size : 4); 34 | arr->arr = (void **)cpcalloc(arr->max, sizeof(void*)); 35 | 36 | return arr; 37 | } 38 | 39 | void 40 | cpArrayFree(cpArray *arr) 41 | { 42 | if(arr){ 43 | cpfree(arr->arr); 44 | arr->arr = NULL; 45 | 46 | cpfree(arr); 47 | } 48 | } 49 | 50 | void 51 | cpArrayPush(cpArray *arr, void *object) 52 | { 53 | if(arr->num == arr->max){ 54 | arr->max *= 2; 55 | arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void*)); 56 | } 57 | 58 | arr->arr[arr->num] = object; 59 | arr->num++; 60 | } 61 | 62 | void * 63 | cpArrayPop(cpArray *arr) 64 | { 65 | arr->num--; 66 | 67 | void *value = arr->arr[arr->num]; 68 | arr->arr[arr->num] = NULL; 69 | 70 | return value; 71 | } 72 | 73 | void 74 | cpArrayDeleteObj(cpArray *arr, void *obj) 75 | { 76 | for(int i=0; inum; i++){ 77 | if(arr->arr[i] == obj){ 78 | arr->num--; 79 | 80 | arr->arr[i] = arr->arr[arr->num]; 81 | arr->arr[arr->num] = NULL; 82 | 83 | return; 84 | } 85 | } 86 | } 87 | 88 | void 89 | cpArrayFreeEach(cpArray *arr, void (freeFunc)(void*)) 90 | { 91 | for(int i=0; inum; i++) freeFunc(arr->arr[i]); 92 | } 93 | 94 | cpBool 95 | cpArrayContains(cpArray *arr, void *ptr) 96 | { 97 | for(int i=0; inum; i++) 98 | if(arr->arr[i] == ptr) return cpTrue; 99 | 100 | return cpFalse; 101 | } 102 | -------------------------------------------------------------------------------- /chipmunk/src/cpConstraint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | // TODO: Comment me! 25 | 26 | void cpConstraintDestroy(cpConstraint *constraint){} 27 | 28 | void 29 | cpConstraintFree(cpConstraint *constraint) 30 | { 31 | if(constraint){ 32 | cpConstraintDestroy(constraint); 33 | cpfree(constraint); 34 | } 35 | } 36 | 37 | void 38 | cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b) 39 | { 40 | constraint->klass = klass; 41 | 42 | constraint->a = a; 43 | constraint->b = b; 44 | constraint->space = NULL; 45 | 46 | constraint->next_a = NULL; 47 | constraint->next_b = NULL; 48 | 49 | constraint->maxForce = (cpFloat)INFINITY; 50 | constraint->errorBias = cpfpow(1.0f - 0.1f, 60.0f); 51 | constraint->maxBias = (cpFloat)INFINITY; 52 | 53 | constraint->collideBodies = cpTrue; 54 | 55 | constraint->preSolve = NULL; 56 | constraint->postSolve = NULL; 57 | } 58 | 59 | cpSpace * 60 | cpConstraintGetSpace(const cpConstraint *constraint) 61 | { 62 | return constraint->space; 63 | } 64 | 65 | cpBody * 66 | cpConstraintGetBodyA(const cpConstraint *constraint) 67 | { 68 | return constraint->a; 69 | } 70 | 71 | cpBody * 72 | cpConstraintGetBodyB(const cpConstraint *constraint) 73 | { 74 | return constraint->b; 75 | } 76 | 77 | cpFloat 78 | cpConstraintGetMaxForce(const cpConstraint *constraint) 79 | { 80 | return constraint->maxForce; 81 | } 82 | 83 | void 84 | cpConstraintSetMaxForce(cpConstraint *constraint, cpFloat maxForce) 85 | { 86 | cpAssertHard(maxForce >= 0.0f, "maxForce must be positive."); 87 | cpConstraintActivateBodies(constraint); 88 | constraint->maxForce = maxForce; 89 | } 90 | 91 | cpFloat 92 | cpConstraintGetErrorBias(const cpConstraint *constraint) 93 | { 94 | return constraint->errorBias; 95 | } 96 | 97 | void 98 | cpConstraintSetErrorBias(cpConstraint *constraint, cpFloat errorBias) 99 | { 100 | cpAssertHard(errorBias >= 0.0f, "errorBias must be positive."); 101 | cpConstraintActivateBodies(constraint); 102 | constraint->errorBias = errorBias; 103 | } 104 | 105 | cpFloat 106 | cpConstraintGetMaxBias(const cpConstraint *constraint) 107 | { 108 | return constraint->maxBias; 109 | } 110 | 111 | void 112 | cpConstraintSetMaxBias(cpConstraint *constraint, cpFloat maxBias) 113 | { 114 | cpAssertHard(maxBias >= 0.0f, "maxBias must be positive."); 115 | cpConstraintActivateBodies(constraint); 116 | constraint->maxBias = maxBias; 117 | } 118 | 119 | cpBool 120 | cpConstraintGetCollideBodies(const cpConstraint *constraint) 121 | { 122 | return constraint->collideBodies; 123 | } 124 | 125 | void 126 | cpConstraintSetCollideBodies(cpConstraint *constraint, cpBool collideBodies) 127 | { 128 | cpConstraintActivateBodies(constraint); 129 | constraint->collideBodies = collideBodies; 130 | } 131 | 132 | cpConstraintPreSolveFunc 133 | cpConstraintGetPreSolveFunc(const cpConstraint *constraint) 134 | { 135 | return constraint->preSolve; 136 | } 137 | 138 | void 139 | cpConstraintSetPreSolveFunc(cpConstraint *constraint, cpConstraintPreSolveFunc preSolveFunc) 140 | { 141 | constraint->preSolve = preSolveFunc; 142 | } 143 | 144 | cpConstraintPostSolveFunc 145 | cpConstraintGetPostSolveFunc(const cpConstraint *constraint) 146 | { 147 | return constraint->postSolve; 148 | } 149 | 150 | void 151 | cpConstraintSetPostSolveFunc(cpConstraint *constraint, cpConstraintPostSolveFunc postSolveFunc) 152 | { 153 | constraint->postSolve = postSolveFunc; 154 | } 155 | 156 | cpDataPointer 157 | cpConstraintGetUserData(const cpConstraint *constraint) 158 | { 159 | return constraint->userData; 160 | } 161 | 162 | void 163 | cpConstraintSetUserData(cpConstraint *constraint, cpDataPointer userData) 164 | { 165 | constraint->userData = userData; 166 | } 167 | 168 | 169 | cpFloat 170 | cpConstraintGetImpulse(cpConstraint *constraint) 171 | { 172 | return constraint->klass->getImpulse(constraint); 173 | } 174 | -------------------------------------------------------------------------------- /chipmunk/src/cpGearJoint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpGearJoint *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | // calculate moment of inertia coefficient. 31 | joint->iSum = 1.0f/(a->i_inv*joint->ratio_inv + joint->ratio*b->i_inv); 32 | 33 | // calculate bias velocity 34 | cpFloat maxBias = joint->constraint.maxBias; 35 | joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*(b->a*joint->ratio - a->a - joint->phase)/dt, -maxBias, maxBias); 36 | } 37 | 38 | static void 39 | applyCachedImpulse(cpGearJoint *joint, cpFloat dt_coef) 40 | { 41 | cpBody *a = joint->constraint.a; 42 | cpBody *b = joint->constraint.b; 43 | 44 | cpFloat j = joint->jAcc*dt_coef; 45 | a->w -= j*a->i_inv*joint->ratio_inv; 46 | b->w += j*b->i_inv; 47 | } 48 | 49 | static void 50 | applyImpulse(cpGearJoint *joint, cpFloat dt) 51 | { 52 | cpBody *a = joint->constraint.a; 53 | cpBody *b = joint->constraint.b; 54 | 55 | // compute relative rotational velocity 56 | cpFloat wr = b->w*joint->ratio - a->w; 57 | 58 | cpFloat jMax = joint->constraint.maxForce*dt; 59 | 60 | // compute normal impulse 61 | cpFloat j = (joint->bias - wr)*joint->iSum; 62 | cpFloat jOld = joint->jAcc; 63 | joint->jAcc = cpfclamp(jOld + j, -jMax, jMax); 64 | j = joint->jAcc - jOld; 65 | 66 | // apply impulse 67 | a->w -= j*a->i_inv*joint->ratio_inv; 68 | b->w += j*b->i_inv; 69 | } 70 | 71 | static cpFloat 72 | getImpulse(cpGearJoint *joint) 73 | { 74 | return cpfabs(joint->jAcc); 75 | } 76 | 77 | static const cpConstraintClass klass = { 78 | (cpConstraintPreStepImpl)preStep, 79 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 80 | (cpConstraintApplyImpulseImpl)applyImpulse, 81 | (cpConstraintGetImpulseImpl)getImpulse, 82 | }; 83 | 84 | cpGearJoint * 85 | cpGearJointAlloc(void) 86 | { 87 | return (cpGearJoint *)cpcalloc(1, sizeof(cpGearJoint)); 88 | } 89 | 90 | cpGearJoint * 91 | cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio) 92 | { 93 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 94 | 95 | joint->phase = phase; 96 | joint->ratio = ratio; 97 | joint->ratio_inv = 1.0f/ratio; 98 | 99 | joint->jAcc = 0.0f; 100 | 101 | return joint; 102 | } 103 | 104 | cpConstraint * 105 | cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio) 106 | { 107 | return (cpConstraint *)cpGearJointInit(cpGearJointAlloc(), a, b, phase, ratio); 108 | } 109 | 110 | cpBool 111 | cpConstraintIsGearJoint(const cpConstraint *constraint) 112 | { 113 | return (constraint->klass == &klass); 114 | } 115 | 116 | cpFloat 117 | cpGearJointGetPhase(const cpConstraint *constraint) 118 | { 119 | cpAssertHard(cpConstraintIsGearJoint(constraint), "Constraint is not a ratchet joint."); 120 | return ((cpGearJoint *)constraint)->phase; 121 | } 122 | 123 | void 124 | cpGearJointSetPhase(cpConstraint *constraint, cpFloat phase) 125 | { 126 | cpAssertHard(cpConstraintIsGearJoint(constraint), "Constraint is not a ratchet joint."); 127 | cpConstraintActivateBodies(constraint); 128 | ((cpGearJoint *)constraint)->phase = phase; 129 | } 130 | 131 | cpFloat 132 | cpGearJointGetRatio(const cpConstraint *constraint) 133 | { 134 | cpAssertHard(cpConstraintIsGearJoint(constraint), "Constraint is not a ratchet joint."); 135 | return ((cpGearJoint *)constraint)->ratio; 136 | } 137 | 138 | void 139 | cpGearJointSetRatio(cpConstraint *constraint, cpFloat ratio) 140 | { 141 | cpAssertHard(cpConstraintIsGearJoint(constraint), "Constraint is not a ratchet joint."); 142 | cpConstraintActivateBodies(constraint); 143 | ((cpGearJoint *)constraint)->ratio = ratio; 144 | ((cpGearJoint *)constraint)->ratio_inv = 1.0f/ratio; 145 | } 146 | -------------------------------------------------------------------------------- /chipmunk/src/cpPinJoint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpPinJoint *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | joint->r1 = cpTransformVect(a->transform, cpvsub(joint->anchorA, a->cog)); 31 | joint->r2 = cpTransformVect(b->transform, cpvsub(joint->anchorB, b->cog)); 32 | 33 | cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1)); 34 | cpFloat dist = cpvlength(delta); 35 | joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY)); 36 | 37 | // calculate mass normal 38 | joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n); 39 | 40 | // calculate bias velocity 41 | cpFloat maxBias = joint->constraint.maxBias; 42 | joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*(dist - joint->dist)/dt, -maxBias, maxBias); 43 | } 44 | 45 | static void 46 | applyCachedImpulse(cpPinJoint *joint, cpFloat dt_coef) 47 | { 48 | cpBody *a = joint->constraint.a; 49 | cpBody *b = joint->constraint.b; 50 | 51 | cpVect j = cpvmult(joint->n, joint->jnAcc*dt_coef); 52 | apply_impulses(a, b, joint->r1, joint->r2, j); 53 | } 54 | 55 | static void 56 | applyImpulse(cpPinJoint *joint, cpFloat dt) 57 | { 58 | cpBody *a = joint->constraint.a; 59 | cpBody *b = joint->constraint.b; 60 | cpVect n = joint->n; 61 | 62 | // compute relative velocity 63 | cpFloat vrn = normal_relative_velocity(a, b, joint->r1, joint->r2, n); 64 | 65 | cpFloat jnMax = joint->constraint.maxForce*dt; 66 | 67 | // compute normal impulse 68 | cpFloat jn = (joint->bias - vrn)*joint->nMass; 69 | cpFloat jnOld = joint->jnAcc; 70 | joint->jnAcc = cpfclamp(jnOld + jn, -jnMax, jnMax); 71 | jn = joint->jnAcc - jnOld; 72 | 73 | // apply impulse 74 | apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn)); 75 | } 76 | 77 | static cpFloat 78 | getImpulse(cpPinJoint *joint) 79 | { 80 | return cpfabs(joint->jnAcc); 81 | } 82 | 83 | static const cpConstraintClass klass = { 84 | (cpConstraintPreStepImpl)preStep, 85 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 86 | (cpConstraintApplyImpulseImpl)applyImpulse, 87 | (cpConstraintGetImpulseImpl)getImpulse, 88 | }; 89 | 90 | 91 | cpPinJoint * 92 | cpPinJointAlloc(void) 93 | { 94 | return (cpPinJoint *)cpcalloc(1, sizeof(cpPinJoint)); 95 | } 96 | 97 | cpPinJoint * 98 | cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB) 99 | { 100 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 101 | 102 | joint->anchorA = anchorA; 103 | joint->anchorB = anchorB; 104 | 105 | // STATIC_BODY_CHECK 106 | cpVect p1 = (a ? cpTransformPoint(a->transform, anchorA) : anchorA); 107 | cpVect p2 = (b ? cpTransformPoint(b->transform, anchorB) : anchorB); 108 | joint->dist = cpvlength(cpvsub(p2, p1)); 109 | 110 | cpAssertWarn(joint->dist > 0.0, "You created a 0 length pin joint. A pivot joint will be much more stable."); 111 | 112 | joint->jnAcc = 0.0f; 113 | 114 | return joint; 115 | } 116 | 117 | cpConstraint * 118 | cpPinJointNew(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB) 119 | { 120 | return (cpConstraint *)cpPinJointInit(cpPinJointAlloc(), a, b, anchorA, anchorB); 121 | } 122 | 123 | cpBool 124 | cpConstraintIsPinJoint(const cpConstraint *constraint) 125 | { 126 | return (constraint->klass == &klass); 127 | } 128 | 129 | cpVect 130 | cpPinJointGetAnchorA(const cpConstraint *constraint) 131 | { 132 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 133 | return ((cpPinJoint *)constraint)->anchorA; 134 | } 135 | 136 | void 137 | cpPinJointSetAnchorA(cpConstraint *constraint, cpVect anchorA) 138 | { 139 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 140 | cpConstraintActivateBodies(constraint); 141 | ((cpPinJoint *)constraint)->anchorA = anchorA; 142 | } 143 | 144 | cpVect 145 | cpPinJointGetAnchorB(const cpConstraint *constraint) 146 | { 147 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 148 | return ((cpPinJoint *)constraint)->anchorB; 149 | } 150 | 151 | void 152 | cpPinJointSetAnchorB(cpConstraint *constraint, cpVect anchorB) 153 | { 154 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 155 | cpConstraintActivateBodies(constraint); 156 | ((cpPinJoint *)constraint)->anchorB = anchorB; 157 | } 158 | 159 | cpFloat 160 | cpPinJointGetDist(const cpConstraint *constraint) 161 | { 162 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 163 | return ((cpPinJoint *)constraint)->dist; 164 | } 165 | 166 | void 167 | cpPinJointSetDist(cpConstraint *constraint, cpFloat dist) 168 | { 169 | cpAssertHard(cpConstraintIsPinJoint(constraint), "Constraint is not a pin joint."); 170 | cpConstraintActivateBodies(constraint); 171 | ((cpPinJoint *)constraint)->dist = dist; 172 | } 173 | -------------------------------------------------------------------------------- /chipmunk/src/cpPivotJoint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpPivotJoint *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | joint->r1 = cpTransformVect(a->transform, cpvsub(joint->anchorA, a->cog)); 31 | joint->r2 = cpTransformVect(b->transform, cpvsub(joint->anchorB, b->cog)); 32 | 33 | // Calculate mass tensor 34 | joint-> k = k_tensor(a, b, joint->r1, joint->r2); 35 | 36 | // calculate bias velocity 37 | cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1)); 38 | joint->bias = cpvclamp(cpvmult(delta, -bias_coef(joint->constraint.errorBias, dt)/dt), joint->constraint.maxBias); 39 | } 40 | 41 | static void 42 | applyCachedImpulse(cpPivotJoint *joint, cpFloat dt_coef) 43 | { 44 | cpBody *a = joint->constraint.a; 45 | cpBody *b = joint->constraint.b; 46 | 47 | apply_impulses(a, b, joint->r1, joint->r2, cpvmult(joint->jAcc, dt_coef)); 48 | } 49 | 50 | static void 51 | applyImpulse(cpPivotJoint *joint, cpFloat dt) 52 | { 53 | cpBody *a = joint->constraint.a; 54 | cpBody *b = joint->constraint.b; 55 | 56 | cpVect r1 = joint->r1; 57 | cpVect r2 = joint->r2; 58 | 59 | // compute relative velocity 60 | cpVect vr = relative_velocity(a, b, r1, r2); 61 | 62 | // compute normal impulse 63 | cpVect j = cpMat2x2Transform(joint->k, cpvsub(joint->bias, vr)); 64 | cpVect jOld = joint->jAcc; 65 | joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->constraint.maxForce*dt); 66 | j = cpvsub(joint->jAcc, jOld); 67 | 68 | // apply impulse 69 | apply_impulses(a, b, joint->r1, joint->r2, j); 70 | } 71 | 72 | static cpFloat 73 | getImpulse(cpConstraint *joint) 74 | { 75 | return cpvlength(((cpPivotJoint *)joint)->jAcc); 76 | } 77 | 78 | static const cpConstraintClass klass = { 79 | (cpConstraintPreStepImpl)preStep, 80 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 81 | (cpConstraintApplyImpulseImpl)applyImpulse, 82 | (cpConstraintGetImpulseImpl)getImpulse, 83 | }; 84 | 85 | cpPivotJoint * 86 | cpPivotJointAlloc(void) 87 | { 88 | return (cpPivotJoint *)cpcalloc(1, sizeof(cpPivotJoint)); 89 | } 90 | 91 | cpPivotJoint * 92 | cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB) 93 | { 94 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 95 | 96 | joint->anchorA = anchorA; 97 | joint->anchorB = anchorB; 98 | 99 | joint->jAcc = cpvzero; 100 | 101 | return joint; 102 | } 103 | 104 | cpConstraint * 105 | cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchorA, cpVect anchorB) 106 | { 107 | return (cpConstraint *)cpPivotJointInit(cpPivotJointAlloc(), a, b, anchorA, anchorB); 108 | } 109 | 110 | cpConstraint * 111 | cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot) 112 | { 113 | cpVect anchorA = (a ? cpBodyWorldToLocal(a, pivot) : pivot); 114 | cpVect anchorB = (b ? cpBodyWorldToLocal(b, pivot) : pivot); 115 | return cpPivotJointNew2(a, b, anchorA, anchorB); 116 | } 117 | 118 | cpBool 119 | cpConstraintIsPivotJoint(const cpConstraint *constraint) 120 | { 121 | return (constraint->klass == &klass); 122 | } 123 | 124 | cpVect 125 | cpPivotJointGetAnchorA(const cpConstraint *constraint) 126 | { 127 | cpAssertHard(cpConstraintIsPivotJoint(constraint), "Constraint is not a pivot joint."); 128 | return ((cpPivotJoint *)constraint)->anchorA; 129 | } 130 | 131 | void 132 | cpPivotJointSetAnchorA(cpConstraint *constraint, cpVect anchorA) 133 | { 134 | cpAssertHard(cpConstraintIsPivotJoint(constraint), "Constraint is not a pivot joint."); 135 | cpConstraintActivateBodies(constraint); 136 | ((cpPivotJoint *)constraint)->anchorA = anchorA; 137 | } 138 | 139 | cpVect 140 | cpPivotJointGetAnchorB(const cpConstraint *constraint) 141 | { 142 | cpAssertHard(cpConstraintIsPivotJoint(constraint), "Constraint is not a pivot joint."); 143 | return ((cpPivotJoint *)constraint)->anchorB; 144 | } 145 | 146 | void 147 | cpPivotJointSetAnchorB(cpConstraint *constraint, cpVect anchorB) 148 | { 149 | cpAssertHard(cpConstraintIsPivotJoint(constraint), "Constraint is not a pivot joint."); 150 | cpConstraintActivateBodies(constraint); 151 | ((cpPivotJoint *)constraint)->anchorB = anchorB; 152 | } 153 | -------------------------------------------------------------------------------- /chipmunk/src/cpRatchetJoint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpRatchetJoint *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | cpFloat angle = joint->angle; 31 | cpFloat phase = joint->phase; 32 | cpFloat ratchet = joint->ratchet; 33 | 34 | cpFloat delta = b->a - a->a; 35 | cpFloat diff = angle - delta; 36 | cpFloat pdist = 0.0f; 37 | 38 | if(diff*ratchet > 0.0f){ 39 | pdist = diff; 40 | } else { 41 | joint->angle = cpffloor((delta - phase)/ratchet)*ratchet + phase; 42 | } 43 | 44 | // calculate moment of inertia coefficient. 45 | joint->iSum = 1.0f/(a->i_inv + b->i_inv); 46 | 47 | // calculate bias velocity 48 | cpFloat maxBias = joint->constraint.maxBias; 49 | joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*pdist/dt, -maxBias, maxBias); 50 | 51 | // If the bias is 0, the joint is not at a limit. Reset the impulse. 52 | if(!joint->bias) joint->jAcc = 0.0f; 53 | } 54 | 55 | static void 56 | applyCachedImpulse(cpRatchetJoint *joint, cpFloat dt_coef) 57 | { 58 | cpBody *a = joint->constraint.a; 59 | cpBody *b = joint->constraint.b; 60 | 61 | cpFloat j = joint->jAcc*dt_coef; 62 | a->w -= j*a->i_inv; 63 | b->w += j*b->i_inv; 64 | } 65 | 66 | static void 67 | applyImpulse(cpRatchetJoint *joint, cpFloat dt) 68 | { 69 | if(!joint->bias) return; // early exit 70 | 71 | cpBody *a = joint->constraint.a; 72 | cpBody *b = joint->constraint.b; 73 | 74 | // compute relative rotational velocity 75 | cpFloat wr = b->w - a->w; 76 | cpFloat ratchet = joint->ratchet; 77 | 78 | cpFloat jMax = joint->constraint.maxForce*dt; 79 | 80 | // compute normal impulse 81 | cpFloat j = -(joint->bias + wr)*joint->iSum; 82 | cpFloat jOld = joint->jAcc; 83 | joint->jAcc = cpfclamp((jOld + j)*ratchet, 0.0f, jMax*cpfabs(ratchet))/ratchet; 84 | j = joint->jAcc - jOld; 85 | 86 | // apply impulse 87 | a->w -= j*a->i_inv; 88 | b->w += j*b->i_inv; 89 | } 90 | 91 | static cpFloat 92 | getImpulse(cpRatchetJoint *joint) 93 | { 94 | return cpfabs(joint->jAcc); 95 | } 96 | 97 | static const cpConstraintClass klass = { 98 | (cpConstraintPreStepImpl)preStep, 99 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 100 | (cpConstraintApplyImpulseImpl)applyImpulse, 101 | (cpConstraintGetImpulseImpl)getImpulse, 102 | }; 103 | 104 | cpRatchetJoint * 105 | cpRatchetJointAlloc(void) 106 | { 107 | return (cpRatchetJoint *)cpcalloc(1, sizeof(cpRatchetJoint)); 108 | } 109 | 110 | cpRatchetJoint * 111 | cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet) 112 | { 113 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 114 | 115 | joint->angle = 0.0f; 116 | joint->phase = phase; 117 | joint->ratchet = ratchet; 118 | 119 | // STATIC_BODY_CHECK 120 | joint->angle = (b ? b->a : 0.0f) - (a ? a->a : 0.0f); 121 | 122 | return joint; 123 | } 124 | 125 | cpConstraint * 126 | cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet) 127 | { 128 | return (cpConstraint *)cpRatchetJointInit(cpRatchetJointAlloc(), a, b, phase, ratchet); 129 | } 130 | 131 | cpBool 132 | cpConstraintIsRatchetJoint(const cpConstraint *constraint) 133 | { 134 | return (constraint->klass == &klass); 135 | } 136 | 137 | cpFloat 138 | cpRatchetJointGetAngle(const cpConstraint *constraint) 139 | { 140 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 141 | return ((cpRatchetJoint *)constraint)->angle; 142 | } 143 | 144 | void 145 | cpRatchetJointSetAngle(cpConstraint *constraint, cpFloat angle) 146 | { 147 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 148 | cpConstraintActivateBodies(constraint); 149 | ((cpRatchetJoint *)constraint)->angle = angle; 150 | } 151 | 152 | cpFloat 153 | cpRatchetJointGetPhase(const cpConstraint *constraint) 154 | { 155 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 156 | return ((cpRatchetJoint *)constraint)->phase; 157 | } 158 | 159 | void 160 | cpRatchetJointSetPhase(cpConstraint *constraint, cpFloat phase) 161 | { 162 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 163 | cpConstraintActivateBodies(constraint); 164 | ((cpRatchetJoint *)constraint)->phase = phase; 165 | } 166 | cpFloat 167 | cpRatchetJointGetRatchet(const cpConstraint *constraint) 168 | { 169 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 170 | return ((cpRatchetJoint *)constraint)->ratchet; 171 | } 172 | 173 | void 174 | cpRatchetJointSetRatchet(cpConstraint *constraint, cpFloat ratchet) 175 | { 176 | cpAssertHard(cpConstraintIsRatchetJoint(constraint), "Constraint is not a ratchet joint."); 177 | cpConstraintActivateBodies(constraint); 178 | ((cpRatchetJoint *)constraint)->ratchet = ratchet; 179 | } 180 | -------------------------------------------------------------------------------- /chipmunk/src/cpRotaryLimitJoint.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpRotaryLimitJoint *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | cpFloat dist = b->a - a->a; 31 | cpFloat pdist = 0.0f; 32 | if(dist > joint->max) { 33 | pdist = joint->max - dist; 34 | } else if(dist < joint->min) { 35 | pdist = joint->min - dist; 36 | } 37 | 38 | // calculate moment of inertia coefficient. 39 | joint->iSum = 1.0f/(a->i_inv + b->i_inv); 40 | 41 | // calculate bias velocity 42 | cpFloat maxBias = joint->constraint.maxBias; 43 | joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*pdist/dt, -maxBias, maxBias); 44 | 45 | // If the bias is 0, the joint is not at a limit. Reset the impulse. 46 | if(!joint->bias) joint->jAcc = 0.0f; 47 | } 48 | 49 | static void 50 | applyCachedImpulse(cpRotaryLimitJoint *joint, cpFloat dt_coef) 51 | { 52 | cpBody *a = joint->constraint.a; 53 | cpBody *b = joint->constraint.b; 54 | 55 | cpFloat j = joint->jAcc*dt_coef; 56 | a->w -= j*a->i_inv; 57 | b->w += j*b->i_inv; 58 | } 59 | 60 | static void 61 | applyImpulse(cpRotaryLimitJoint *joint, cpFloat dt) 62 | { 63 | if(!joint->bias) return; // early exit 64 | 65 | cpBody *a = joint->constraint.a; 66 | cpBody *b = joint->constraint.b; 67 | 68 | // compute relative rotational velocity 69 | cpFloat wr = b->w - a->w; 70 | 71 | cpFloat jMax = joint->constraint.maxForce*dt; 72 | 73 | // compute normal impulse 74 | cpFloat j = -(joint->bias + wr)*joint->iSum; 75 | cpFloat jOld = joint->jAcc; 76 | if(joint->bias < 0.0f){ 77 | joint->jAcc = cpfclamp(jOld + j, 0.0f, jMax); 78 | } else { 79 | joint->jAcc = cpfclamp(jOld + j, -jMax, 0.0f); 80 | } 81 | j = joint->jAcc - jOld; 82 | 83 | // apply impulse 84 | a->w -= j*a->i_inv; 85 | b->w += j*b->i_inv; 86 | } 87 | 88 | static cpFloat 89 | getImpulse(cpRotaryLimitJoint *joint) 90 | { 91 | return cpfabs(joint->jAcc); 92 | } 93 | 94 | static const cpConstraintClass klass = { 95 | (cpConstraintPreStepImpl)preStep, 96 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 97 | (cpConstraintApplyImpulseImpl)applyImpulse, 98 | (cpConstraintGetImpulseImpl)getImpulse, 99 | }; 100 | 101 | cpRotaryLimitJoint * 102 | cpRotaryLimitJointAlloc(void) 103 | { 104 | return (cpRotaryLimitJoint *)cpcalloc(1, sizeof(cpRotaryLimitJoint)); 105 | } 106 | 107 | cpRotaryLimitJoint * 108 | cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max) 109 | { 110 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 111 | 112 | joint->min = min; 113 | joint->max = max; 114 | 115 | joint->jAcc = 0.0f; 116 | 117 | return joint; 118 | } 119 | 120 | cpConstraint * 121 | cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max) 122 | { 123 | return (cpConstraint *)cpRotaryLimitJointInit(cpRotaryLimitJointAlloc(), a, b, min, max); 124 | } 125 | 126 | cpBool 127 | cpConstraintIsRotaryLimitJoint(const cpConstraint *constraint) 128 | { 129 | return (constraint->klass == &klass); 130 | } 131 | 132 | cpFloat 133 | cpRotaryLimitJointGetMin(const cpConstraint *constraint) 134 | { 135 | cpAssertHard(cpConstraintIsRotaryLimitJoint(constraint), "Constraint is not a rotary limit joint."); 136 | return ((cpRotaryLimitJoint *)constraint)->min; 137 | } 138 | 139 | void 140 | cpRotaryLimitJointSetMin(cpConstraint *constraint, cpFloat min) 141 | { 142 | cpAssertHard(cpConstraintIsRotaryLimitJoint(constraint), "Constraint is not a rotary limit joint."); 143 | cpConstraintActivateBodies(constraint); 144 | ((cpRotaryLimitJoint *)constraint)->min = min; 145 | } 146 | 147 | cpFloat 148 | cpRotaryLimitJointGetMax(const cpConstraint *constraint) 149 | { 150 | cpAssertHard(cpConstraintIsRotaryLimitJoint(constraint), "Constraint is not a rotary limit joint."); 151 | return ((cpRotaryLimitJoint *)constraint)->max; 152 | } 153 | 154 | void 155 | cpRotaryLimitJointSetMax(cpConstraint *constraint, cpFloat max) 156 | { 157 | cpAssertHard(cpConstraintIsRotaryLimitJoint(constraint), "Constraint is not a rotary limit joint."); 158 | cpConstraintActivateBodies(constraint); 159 | ((cpRotaryLimitJoint *)constraint)->max = max; 160 | } 161 | -------------------------------------------------------------------------------- /chipmunk/src/cpSimpleMotor.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | static void 25 | preStep(cpSimpleMotor *joint, cpFloat dt) 26 | { 27 | cpBody *a = joint->constraint.a; 28 | cpBody *b = joint->constraint.b; 29 | 30 | // calculate moment of inertia coefficient. 31 | joint->iSum = 1.0f/(a->i_inv + b->i_inv); 32 | } 33 | 34 | static void 35 | applyCachedImpulse(cpSimpleMotor *joint, cpFloat dt_coef) 36 | { 37 | cpBody *a = joint->constraint.a; 38 | cpBody *b = joint->constraint.b; 39 | 40 | cpFloat j = joint->jAcc*dt_coef; 41 | a->w -= j*a->i_inv; 42 | b->w += j*b->i_inv; 43 | } 44 | 45 | static void 46 | applyImpulse(cpSimpleMotor *joint, cpFloat dt) 47 | { 48 | cpBody *a = joint->constraint.a; 49 | cpBody *b = joint->constraint.b; 50 | 51 | // compute relative rotational velocity 52 | cpFloat wr = b->w - a->w + joint->rate; 53 | 54 | cpFloat jMax = joint->constraint.maxForce*dt; 55 | 56 | // compute normal impulse 57 | cpFloat j = -wr*joint->iSum; 58 | cpFloat jOld = joint->jAcc; 59 | joint->jAcc = cpfclamp(jOld + j, -jMax, jMax); 60 | j = joint->jAcc - jOld; 61 | 62 | // apply impulse 63 | a->w -= j*a->i_inv; 64 | b->w += j*b->i_inv; 65 | } 66 | 67 | static cpFloat 68 | getImpulse(cpSimpleMotor *joint) 69 | { 70 | return cpfabs(joint->jAcc); 71 | } 72 | 73 | static const cpConstraintClass klass = { 74 | (cpConstraintPreStepImpl)preStep, 75 | (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, 76 | (cpConstraintApplyImpulseImpl)applyImpulse, 77 | (cpConstraintGetImpulseImpl)getImpulse, 78 | }; 79 | 80 | cpSimpleMotor * 81 | cpSimpleMotorAlloc(void) 82 | { 83 | return (cpSimpleMotor *)cpcalloc(1, sizeof(cpSimpleMotor)); 84 | } 85 | 86 | cpSimpleMotor * 87 | cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate) 88 | { 89 | cpConstraintInit((cpConstraint *)joint, &klass, a, b); 90 | 91 | joint->rate = rate; 92 | 93 | joint->jAcc = 0.0f; 94 | 95 | return joint; 96 | } 97 | 98 | cpConstraint * 99 | cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate) 100 | { 101 | return (cpConstraint *)cpSimpleMotorInit(cpSimpleMotorAlloc(), a, b, rate); 102 | } 103 | 104 | cpBool 105 | cpConstraintIsSimpleMotor(const cpConstraint *constraint) 106 | { 107 | return (constraint->klass == &klass); 108 | } 109 | 110 | cpFloat 111 | cpSimpleMotorGetRate(const cpConstraint *constraint) 112 | { 113 | cpAssertHard(cpConstraintIsSimpleMotor(constraint), "Constraint is not a pin joint."); 114 | return ((cpSimpleMotor *)constraint)->rate; 115 | } 116 | 117 | void 118 | cpSimpleMotorSetRate(cpConstraint *constraint, cpFloat rate) 119 | { 120 | cpAssertHard(cpConstraintIsSimpleMotor(constraint), "Constraint is not a pin joint."); 121 | cpConstraintActivateBodies(constraint); 122 | ((cpSimpleMotor *)constraint)->rate = rate; 123 | } 124 | -------------------------------------------------------------------------------- /chipmunk/src/cpSpatialIndex.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | #include "chipmunk/chipmunk_private.h" 23 | 24 | void 25 | cpSpatialIndexFree(cpSpatialIndex *index) 26 | { 27 | if(index){ 28 | cpSpatialIndexDestroy(index); 29 | cpfree(index); 30 | } 31 | } 32 | 33 | cpSpatialIndex * 34 | cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex) 35 | { 36 | index->klass = klass; 37 | index->bbfunc = bbfunc; 38 | index->staticIndex = staticIndex; 39 | 40 | if(staticIndex){ 41 | cpAssertHard(!staticIndex->dynamicIndex, "This static index is already associated with a dynamic index."); 42 | staticIndex->dynamicIndex = index; 43 | } 44 | 45 | return index; 46 | } 47 | 48 | typedef struct dynamicToStaticContext { 49 | cpSpatialIndexBBFunc bbfunc; 50 | cpSpatialIndex *staticIndex; 51 | cpSpatialIndexQueryFunc queryFunc; 52 | void *data; 53 | } dynamicToStaticContext; 54 | 55 | static void 56 | dynamicToStaticIter(void *obj, dynamicToStaticContext *context) 57 | { 58 | cpSpatialIndexQuery(context->staticIndex, obj, context->bbfunc(obj), context->queryFunc, context->data); 59 | } 60 | 61 | void 62 | cpSpatialIndexCollideStatic(cpSpatialIndex *dynamicIndex, cpSpatialIndex *staticIndex, cpSpatialIndexQueryFunc func, void *data) 63 | { 64 | if(staticIndex && cpSpatialIndexCount(staticIndex) > 0){ 65 | dynamicToStaticContext context = {dynamicIndex->bbfunc, staticIndex, func, data}; 66 | cpSpatialIndexEach(dynamicIndex, (cpSpatialIndexIteratorFunc)dynamicToStaticIter, &context); 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /chipmunk/src/prime.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | 22 | // Used for resizing hash tables. 23 | // Values approximately double. 24 | // http://planetmath.org/encyclopedia/GoodHashTablePrimes.html 25 | static int primes[] = { 26 | 5, 27 | 13, 28 | 23, 29 | 47, 30 | 97, 31 | 193, 32 | 389, 33 | 769, 34 | 1543, 35 | 3079, 36 | 6151, 37 | 12289, 38 | 24593, 39 | 49157, 40 | 98317, 41 | 196613, 42 | 393241, 43 | 786433, 44 | 1572869, 45 | 3145739, 46 | 6291469, 47 | 12582917, 48 | 25165843, 49 | 50331653, 50 | 100663319, 51 | 201326611, 52 | 402653189, 53 | 805306457, 54 | 1610612741, 55 | 0, 56 | }; 57 | 58 | static inline int 59 | next_prime(int n) 60 | { 61 | int i = 0; 62 | while(n > primes[i]){ 63 | i++; 64 | cpAssertHard(primes[i], "Tried to resize a hash table to a size greater than 1610612741 O_o"); // realistically this should never happen 65 | } 66 | 67 | return primes[i]; 68 | } 69 | -------------------------------------------------------------------------------- /cmake/FindSDL2_image.cmake: -------------------------------------------------------------------------------- 1 | # - Locate SDL2_image library (modified from Cmake's FindSDL_image.cmake) 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 SDL2_image 7 | # 8 | # For backward compatiblity the following variables are also set: 9 | # SDL2IMAGE_LIBRARY (same value as SDL2_IMAGE_LIBRARIES) 10 | # SDL2IMAGE_INCLUDE_DIR (same value as SDL2_IMAGE_INCLUDE_DIRS) 11 | # SDL2IMAGE_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 | #============================================================================= 18 | # Copyright 2014 Justin Jacobs 19 | # 20 | # Distributed under the OSI-approved BSD License (the "License"); 21 | # see accompanying file Copyright.txt for details. 22 | # 23 | # This software is distributed WITHOUT ANY WARRANTY; without even the 24 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 25 | # See the License for more information. 26 | #============================================================================= 27 | 28 | if(NOT SDL2_IMAGE_INCLUDE_DIR AND SDL2IMAGE_INCLUDE_DIR) 29 | set(SDL2_IMAGE_INCLUDE_DIR ${SDL2IMAGE_INCLUDE_DIR} CACHE PATH "directory cache 30 | entry initialized from old variable name") 31 | endif() 32 | find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h 33 | HINTS 34 | ENV SDLIMAGEDIR 35 | ENV SDLDIR 36 | PATH_SUFFIXES include/SDL2 include 37 | ) 38 | 39 | if(NOT SDL2_IMAGE_LIBRARY AND SDL2IMAGE_LIBRARY) 40 | set(SDL2_IMAGE_LIBRARY ${SDL2IMAGE_LIBRARY} CACHE FILEPATH "file cache entry 41 | initialized from old variable name") 42 | endif() 43 | find_library(SDL2_IMAGE_LIBRARY 44 | NAMES SDL2_image 45 | HINTS 46 | ENV SDLIMAGEDIR 47 | ENV SDLDIR 48 | PATH_SUFFIXES lib 49 | ) 50 | 51 | if(SDL2_IMAGE_INCLUDE_DIR AND EXISTS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h") 52 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+[0-9]+$") 53 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+[0-9]+$") 54 | file(STRINGS "${SDL2_IMAGE_INCLUDE_DIR}/SDL_image.h" SDL2_IMAGE_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+[0-9]+$") 55 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MAJOR "${SDL2_IMAGE_VERSION_MAJOR_LINE}") 56 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_MINOR "${SDL2_IMAGE_VERSION_MINOR_LINE}") 57 | string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_IMAGE_VERSION_PATCH "${SDL2_IMAGE_VERSION_PATCH_LINE}") 58 | set(SDL2_IMAGE_VERSION_STRING ${SDL2_IMAGE_VERSION_MAJOR}.${SDL2_IMAGE_VERSION_MINOR}.${SDL2_IMAGE_VERSION_PATCH}) 59 | unset(SDL2_IMAGE_VERSION_MAJOR_LINE) 60 | unset(SDL2_IMAGE_VERSION_MINOR_LINE) 61 | unset(SDL2_IMAGE_VERSION_PATCH_LINE) 62 | unset(SDL2_IMAGE_VERSION_MAJOR) 63 | unset(SDL2_IMAGE_VERSION_MINOR) 64 | unset(SDL2_IMAGE_VERSION_PATCH) 65 | endif() 66 | 67 | set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY}) 68 | set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR}) 69 | 70 | include(FindPackageHandleStandardArgs) 71 | 72 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image 73 | REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS 74 | VERSION_VAR SDL2_IMAGE_VERSION_STRING) 75 | 76 | # for backward compatiblity 77 | set(SDL2IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARIES}) 78 | set(SDL2IMAGE_INCLUDE_DIR ${SDL2_IMAGE_INCLUDE_DIRS}) 79 | set(SDL2IMAGE_FOUND ${SDL2_IMAGE_FOUND}) 80 | 81 | mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR) 82 | -------------------------------------------------------------------------------- /cmake/FindSDL2_mixer.cmake: -------------------------------------------------------------------------------- 1 | # - Locate SDL2_mixer library (modified from Cmake's FindSDL_mixer.cmake) 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 SDL2_mixer 7 | # 8 | # For backward compatiblity the following variables are also set: 9 | # SDL2MIXER_LIBRARY (same value as SDL2_MIXER_LIBRARIES) 10 | # SDL2MIXER_INCLUDE_DIR (same value as SDL2_MIXER_INCLUDE_DIRS) 11 | # SDL2MIXER_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 | #============================================================================= 18 | # Copyright 2014 Justin Jacobs 19 | # 20 | # Distributed under the OSI-approved BSD License (the "License"); 21 | # see accompanying file Copyright.txt for details. 22 | # 23 | # This software is distributed WITHOUT ANY WARRANTY; without even the 24 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 25 | # See the License for more information. 26 | #============================================================================= 27 | 28 | if(NOT SDL2_MIXER_INCLUDE_DIR AND SDL2MIXER_INCLUDE_DIR) 29 | set(SDL2_MIXER_INCLUDE_DIR ${SDL2MIXER_INCLUDE_DIR} CACHE PATH "directory cache 30 | entry initialized from old variable name") 31 | endif() 32 | find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h 33 | HINTS 34 | ENV SDLMIXERDIR 35 | ENV SDLDIR 36 | PATH_SUFFIXES include/SDL2 include 37 | ) 38 | 39 | if(NOT SDL2_MIXER_LIBRARY AND SDL2MIXER_LIBRARY) 40 | set(SDL2_MIXER_LIBRARY ${SDL2MIXER_LIBRARY} CACHE FILEPATH "file cache entry 41 | initialized from old variable name") 42 | endif() 43 | find_library(SDL2_MIXER_LIBRARY 44 | NAMES SDL2_mixer 45 | HINTS 46 | ENV SDLMIXERDIR 47 | ENV SDLDIR 48 | PATH_SUFFIXES lib 49 | ) 50 | 51 | if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h") 52 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$") 53 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$") 54 | file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$") 55 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}") 56 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}") 57 | string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}") 58 | set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH}) 59 | unset(SDL2_MIXER_VERSION_MAJOR_LINE) 60 | unset(SDL2_MIXER_VERSION_MINOR_LINE) 61 | unset(SDL2_MIXER_VERSION_PATCH_LINE) 62 | unset(SDL2_MIXER_VERSION_MAJOR) 63 | unset(SDL2_MIXER_VERSION_MINOR) 64 | unset(SDL2_MIXER_VERSION_PATCH) 65 | endif() 66 | 67 | set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY}) 68 | set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR}) 69 | 70 | include(FindPackageHandleStandardArgs) 71 | 72 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer 73 | REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS 74 | VERSION_VAR SDL2_MIXER_VERSION_STRING) 75 | 76 | # for backward compatiblity 77 | set(SDL2MIXER_LIBRARY ${SDL2_MIXER_LIBRARIES}) 78 | set(SDL2MIXER_INCLUDE_DIR ${SDL2_MIXER_INCLUDE_DIRS}) 79 | set(SDL2MIXER_FOUND ${SDL2_MIXER_FOUND}) 80 | 81 | mark_as_advanced(SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR) 82 | -------------------------------------------------------------------------------- /cmake/FindSDL2_ttf.cmake: -------------------------------------------------------------------------------- 1 | # - Locate SDL2_ttf library (modified from Cmake's FindSDL_ttf.cmake) 2 | # This module defines: 3 | # SDL2_TTF_LIBRARIES, the name of the library to link against 4 | # SDL2_TTF_INCLUDE_DIRS, where to find the headers 5 | # SDL2_TTF_FOUND, if false, do not try to link against 6 | # SDL2_TTF_VERSION_STRING - human-readable string containing the version of SDL2_ttf 7 | # 8 | # For backward compatiblity the following variables are also set: 9 | # SDL2TTF_LIBRARY (same value as SDL2_TTF_LIBRARIES) 10 | # SDL2TTF_INCLUDE_DIR (same value as SDL2_TTF_INCLUDE_DIRS) 11 | # SDL2TTF_FOUND (same value as SDL2_TTF_FOUND) 12 | # 13 | # $SDLDIR is an environment variable that would 14 | # correspond to the ./configure --prefix=$SDLDIR 15 | # used in building SDL. 16 | # 17 | #============================================================================= 18 | # Copyright 2014 Justin Jacobs 19 | # 20 | # Distributed under the OSI-approved BSD License (the "License"); 21 | # see accompanying file Copyright.txt for details. 22 | # 23 | # This software is distributed WITHOUT ANY WARRANTY; without even the 24 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 25 | # See the License for more information. 26 | #============================================================================= 27 | 28 | if(NOT SDL2_TTF_INCLUDE_DIR AND SDL2TTF_INCLUDE_DIR) 29 | set(SDL2_TTF_INCLUDE_DIR ${SDL2TTF_INCLUDE_DIR} CACHE PATH "directory cache 30 | entry initialized from old variable name") 31 | endif() 32 | find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h 33 | HINTS 34 | ENV SDLTTFDIR 35 | ENV SDLDIR 36 | PATH_SUFFIXES include/SDL2 include 37 | ) 38 | 39 | if(NOT SDL2_TTF_LIBRARY AND SDL2TTF_LIBRARY) 40 | set(SDL2_TTF_LIBRARY ${SDLTTF_LIBRARY} CACHE FILEPATH "file cache entry 41 | initialized from old variable name") 42 | endif() 43 | find_library(SDL2_TTF_LIBRARY 44 | NAMES SDL2_ttf 45 | HINTS 46 | ENV SDLTTFDIR 47 | ENV SDLDIR 48 | PATH_SUFFIXES lib 49 | ) 50 | 51 | if(SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h") 52 | file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$") 53 | file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$") 54 | file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$") 55 | string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}") 56 | string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}") 57 | string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}") 58 | set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH}) 59 | unset(SDL2_TTF_VERSION_MAJOR_LINE) 60 | unset(SDL2_TTF_VERSION_MINOR_LINE) 61 | unset(SDL2_TTF_VERSION_PATCH_LINE) 62 | unset(SDL2_TTF_VERSION_MAJOR) 63 | unset(SDL2_TTF_VERSION_MINOR) 64 | unset(SDL2_TTF_VERSION_PATCH) 65 | endif() 66 | 67 | set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY}) 68 | set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR}) 69 | 70 | include(FindPackageHandleStandardArgs) 71 | 72 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf 73 | REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS 74 | VERSION_VAR SDL2_TTF_VERSION_STRING) 75 | 76 | # for backward compatiblity 77 | set(SDL2TTF_LIBRARY ${SDL2_TTF_LIBRARIES}) 78 | set(SDL2TTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS}) 79 | set(SDL2TTF_FOUND ${SDL2_TTF_FOUND}) 80 | 81 | mark_as_advanced(SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR) 82 | -------------------------------------------------------------------------------- /data/LondrinaSolid-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/LondrinaSolid-Regular.otf -------------------------------------------------------------------------------- /data/graphics/360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/360.png -------------------------------------------------------------------------------- /data/graphics/anim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/anim.png -------------------------------------------------------------------------------- /data/graphics/eggplant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/eggplant.png -------------------------------------------------------------------------------- /data/graphics/flare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/flare.png -------------------------------------------------------------------------------- /data/graphics/floor0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor0.png -------------------------------------------------------------------------------- /data/graphics/floor1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor1.png -------------------------------------------------------------------------------- /data/graphics/floor2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor2.png -------------------------------------------------------------------------------- /data/graphics/floor3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor3.png -------------------------------------------------------------------------------- /data/graphics/floor4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor4.png -------------------------------------------------------------------------------- /data/graphics/floor5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/floor5.png -------------------------------------------------------------------------------- /data/graphics/gameover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/gameover.png -------------------------------------------------------------------------------- /data/graphics/gcw0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/gcw0.png -------------------------------------------------------------------------------- /data/graphics/gcw0analog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/gcw0analog.png -------------------------------------------------------------------------------- /data/graphics/gcw0g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/gcw0g.png -------------------------------------------------------------------------------- /data/graphics/gcw1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/gcw1.png -------------------------------------------------------------------------------- /data/graphics/icebergs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/icebergs.png -------------------------------------------------------------------------------- /data/graphics/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/icon.png -------------------------------------------------------------------------------- /data/graphics/keyboard0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/keyboard0.png -------------------------------------------------------------------------------- /data/graphics/keyboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/keyboard1.png -------------------------------------------------------------------------------- /data/graphics/penguin_ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/penguin_ball.png -------------------------------------------------------------------------------- /data/graphics/penguin_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/penguin_black.png -------------------------------------------------------------------------------- /data/graphics/penguin_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/penguin_blue.png -------------------------------------------------------------------------------- /data/graphics/penguin_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/penguin_red.png -------------------------------------------------------------------------------- /data/graphics/sparks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/sparks.png -------------------------------------------------------------------------------- /data/graphics/sparks_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/sparks_red.png -------------------------------------------------------------------------------- /data/graphics/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/stars.png -------------------------------------------------------------------------------- /data/graphics/tail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/graphics/tail.png -------------------------------------------------------------------------------- /data/sounds/beep.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/beep.ogg -------------------------------------------------------------------------------- /data/sounds/bounce.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/bounce.ogg -------------------------------------------------------------------------------- /data/sounds/chicken.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/chicken.ogg -------------------------------------------------------------------------------- /data/sounds/lose.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/lose.ogg -------------------------------------------------------------------------------- /data/sounds/music.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/music.ogg -------------------------------------------------------------------------------- /data/sounds/penguin.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/penguin.ogg -------------------------------------------------------------------------------- /data/sounds/quack.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/quack.ogg -------------------------------------------------------------------------------- /data/sounds/roll.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/roll.ogg -------------------------------------------------------------------------------- /data/sounds/score.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/score.ogg -------------------------------------------------------------------------------- /data/sounds/start.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/start.ogg -------------------------------------------------------------------------------- /data/sounds/turkey.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/data/sounds/turkey.ogg -------------------------------------------------------------------------------- /draw.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "draw.h" 27 | 28 | #include 29 | 30 | #include "main.h" 31 | 32 | 33 | static Tex Surf2Tex(SDL_Surface *s); 34 | 35 | Tex LoadTex(const char *filename) 36 | { 37 | SDL_Surface* s = IMG_Load(filename); 38 | if (s == NULL) 39 | { 40 | printf("Failed to IMG_Load: %s\n", SDL_GetError()); 41 | SDL_ClearError(); 42 | Tex t = { NULL, 0, 0 }; 43 | return t; 44 | } 45 | return Surf2Tex(s); 46 | } 47 | 48 | Tex LoadText(const char *text, TTF_Font *font, const SDL_Color c) 49 | { 50 | SDL_Surface *s = TTF_RenderText_Blended(font, text, c); 51 | if (s == NULL) 52 | { 53 | printf("Failed to render text: %s\n", SDL_GetError()); 54 | SDL_ClearError(); 55 | Tex t = { NULL, 0, 0 }; 56 | return t; 57 | } 58 | return Surf2Tex(s); 59 | } 60 | 61 | static Tex Surf2Tex(SDL_Surface *s) 62 | { 63 | Tex t = { NULL, 0, 0 }; 64 | t.T = SDL_CreateTextureFromSurface(Renderer, s); 65 | SDL_FreeSurface(s); 66 | if (SDL_QueryTexture(t.T, NULL, NULL, &t.W, &t.H) != 0) 67 | { 68 | printf("Failed to query texture: %s\n", SDL_GetError()); 69 | SDL_ClearError(); 70 | } 71 | return t; 72 | } 73 | 74 | void RenderTex(SDL_Texture *t, const SDL_Rect *src, const SDL_Rect *dst) 75 | { 76 | if (SDL_RenderCopy(Renderer, t, src, dst) != 0) 77 | { 78 | printf("Failed to render texture: %s\n", SDL_GetError()); 79 | SDL_ClearError(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /draw.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | #include 30 | 31 | typedef struct 32 | { 33 | SDL_Texture *T; 34 | int W; 35 | int H; 36 | } Tex; 37 | 38 | Tex LoadTex(const char *filename); 39 | Tex LoadText(const char *text, TTF_Font *font, const SDL_Color c); 40 | void RenderTex(SDL_Texture *t, const SDL_Rect *src, const SDL_Rect *dst); 41 | -------------------------------------------------------------------------------- /game.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Ativayeban, game header 3 | * Copyright (C) 2014 Nebuleon Fumika 4 | * 2015 Cong Xu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include "init.h" 28 | 29 | // All speed and acceleration modifiers follow the same directions. 30 | // Vertically: Positive values go upward, and negative values go downward. 31 | // Horizontally: Positive values go rightward, and negative values go leftward. 32 | 33 | // The horizontal acceleration when the user presses to go to the right fully. 34 | // Negated and multiplied by a fraction when going to the left or not fully in 35 | // one direction, respectively. 36 | // Given in (meters per second) per second (m/s^2). 37 | #define ACCELERATION 50.00f 38 | // Acceleration when at max speed 39 | #define ACCELERATION_MAX_SPEED 10.0f 40 | #define MAX_SPEED 6.0f 41 | #define MIN_SPEED 2.0f 42 | // Extra acceleration when below min speed 43 | #define MIN_SPEED_ACCEL_BONUS 100.0f 44 | // Extra acceleration when rolling 45 | #define ROLL_ACCEL_BONUS 50.0f 46 | 47 | // The gravitational force exerted by the bottom of the screen. 48 | // Given in (meters per second) per second (m/s^2). 49 | #define GRAVITY -9.78f /* like Earth */ 50 | 51 | // The speed at which the screen scrolls. 52 | // Given in meters per second (m/s). 53 | #define FIELD_SCROLL 1.60f 54 | #define FIELD_SCROLL_MAX 1.86f 55 | 56 | // The speed at which the scroll speed increases, every second 57 | #define FIELD_SCROLL_SPEED 0.01f 58 | 59 | #define FIELD_ELASTICITY 0.25f 60 | 61 | // The distance between the edges of two successive gaps to begin with. 62 | // Given in meters. 63 | #define GAP_GEN_START 1.50f 64 | 65 | #define GAP_GEN_MIN 1.0f 66 | 67 | // The change in distance between the edges of two successive gaps as 68 | // the player passes through each of them. 69 | // Given in meters (per rectangle). 70 | #define GAP_GEN_SPEED -0.01f 71 | 72 | // The width of the area to leave empty for the player to pass through. 73 | // Given in meters. 74 | // Gaps start out big and gradually shrink over time. 75 | #define GAP_WIDTH_MIN 0.75f 76 | #define GAP_WIDTH_MAX 1.5f 77 | #define GAP_WIDTH_SHRINK_SPEED -0.01f 78 | 79 | // The height of gap surfaces. 80 | // Given in meters. 81 | #define GAP_HEIGHT 0.25f 82 | 83 | #define MAX_GAPS 3 84 | 85 | #define MIN_BLOCK_WIDTH 0.25f 86 | 87 | #define BLOCK_ELASTICITY 0.25f 88 | 89 | // The radius of the player's character. 90 | // Given in meters. 91 | #define PLAYER_RADIUS 0.185f 92 | 93 | #define PLAYER_ELASTICITY 1.0f 94 | 95 | // The width of the playing field. 96 | // Given in meters. 97 | #define FIELD_WIDTH 5.33f 98 | 99 | #define FIELD_HEIGHT (SCREEN_HEIGHT * (FIELD_WIDTH / SCREEN_WIDTH)) 100 | 101 | // Convert game coordinates to screen coordinates 102 | #define SCREEN_X(_x) ((int)roundf((_x) * SCREEN_WIDTH / FIELD_WIDTH)) 103 | #define SCREEN_Y(_y) ((int)roundf(SCREEN_HEIGHT - (_y) * SCREEN_HEIGHT / FIELD_HEIGHT)) 104 | 105 | extern Mix_Chunk* SoundBeep; 106 | extern Mix_Chunk* SoundStart; 107 | extern Mix_Chunk* SoundLose; 108 | extern Mix_Chunk* SoundScore; 109 | 110 | extern TTF_Font *font; 111 | 112 | extern void ToGame(void); 113 | -------------------------------------------------------------------------------- /gap.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "gap.h" 27 | 28 | #include 29 | #include 30 | 31 | #include "SDL_image.h" 32 | 33 | #include "box.h" 34 | #include "game.h" 35 | #include "main.h" 36 | #include "pickup.h" 37 | 38 | 39 | #define GAP_SPRITE_WIDTH 318 40 | #define GAP_SPRITE_HEIGHT 15 41 | 42 | static int compareFloat(const void *a, const void *b); 43 | void GapInit(struct Gap* gap, const float w, const float y) 44 | { 45 | // Randomly generate some gaps, and place blocks around them 46 | float gapXs[MAX_GAPS]; 47 | for (int i = 0; i < MAX_GAPS; i++) 48 | { 49 | gapXs[i] = w / 2 + (float)rand() / (float)RAND_MAX * (FIELD_WIDTH - w); 50 | } 51 | qsort(gapXs, MAX_GAPS, sizeof gapXs[0], compareFloat); 52 | // Merge gaps if they are too close 53 | for (int i = 1; i < MAX_GAPS; i++) 54 | { 55 | if (gapXs[i] - gapXs[i - 1] < w + MIN_BLOCK_WIDTH) 56 | { 57 | gapXs[i] = (gapXs[i] + gapXs[i - 1]) / 2; 58 | gapXs[i - 1] = 0; 59 | } 60 | } 61 | // Generate blocks 62 | CArrayInit(&gap->blocks, sizeof(Block)); 63 | Block b; 64 | float left = 0; 65 | for (int i = 0; i < MAX_GAPS; i++) 66 | { 67 | if (gapXs[i] == 0) continue; 68 | BlockInit(&b, left, y, gapXs[i] - w / 2 - left); 69 | CArrayPushBack(&gap->blocks, &b); 70 | left = gapXs[i] + w / 2; 71 | } 72 | // Add last block 73 | BlockInit(&b, left, y, FIELD_WIDTH - left); 74 | CArrayPushBack(&gap->blocks, &b); 75 | 76 | // Randomly add a pickup above a block 77 | if (rand() > (RAND_MAX / 2)) 78 | { 79 | const Block *bl = CArrayGet(&gap->blocks, rand() % gap->blocks.size); 80 | const cpVect pos = cpBodyGetPosition(bl->Body); 81 | PickupsAdd((float)pos.x, (float)pos.y + bl->H / 2); 82 | } 83 | 84 | memset(gap->Passed, 0, sizeof gap->Passed); 85 | gap->Y = y; 86 | } 87 | static int compareFloat(const void *a, const void *b) 88 | { 89 | const float fa = *(const float *)a; 90 | const float fb = *(const float *)b; 91 | return (fa > fb) - (fa < fb); 92 | } 93 | void GapRemove(struct Gap* gap) 94 | { 95 | for (int i = 0; i < (int)gap->blocks.size; i++) 96 | { 97 | BlockRemove(CArrayGet(&gap->blocks, i)); 98 | } 99 | CArrayTerminate(&gap->blocks); 100 | } 101 | 102 | void GapDraw(const struct Gap* gap, const float y) 103 | { 104 | for (int i = 0; i < (int)gap->blocks.size; i++) 105 | { 106 | BlockDraw(CArrayGet(&gap->blocks, i), y); 107 | } 108 | } 109 | 110 | float GapBottom(const struct Gap* gap) 111 | { 112 | return gap->Y - GAP_HEIGHT; 113 | } 114 | -------------------------------------------------------------------------------- /gap.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #include "c_array.h" 34 | #include "player.h" 35 | 36 | // Gaps are a pair of rectangles with a gap in between. 37 | // The player scores after falling through a gap. 38 | 39 | struct Gap 40 | { 41 | CArray blocks; // of Block 42 | // Where the gap layer is. 43 | float Y; 44 | 45 | // Whether each player has passed this gap 46 | bool Passed[MAX_PLAYERS]; 47 | }; 48 | 49 | void GapInit(struct Gap* gap, const float w, const float y); 50 | void GapRemove(struct Gap* gap); 51 | void GapDraw(const struct Gap* gap, const float y); 52 | 53 | extern float GapBottom(const struct Gap* gap); 54 | -------------------------------------------------------------------------------- /high_score.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "high_score.h" 27 | 28 | #include 29 | 30 | #include "cfgpath.h" 31 | #include "init.h" 32 | #include "main.h" 33 | #include "text.h" 34 | #include "utils.h" 35 | 36 | 37 | #define HIGH_SCORE_FILE "falling_time_high_scores" 38 | #define MAX_HIGH_SCORES 20 39 | 40 | CArray HighScores; 41 | 42 | void HighScoresInit(void) 43 | { 44 | CArrayInit(&HighScores, sizeof(HighScore)); 45 | char buf[MAX_PATH]; 46 | get_user_config_file(buf, MAX_PATH, HIGH_SCORE_FILE); 47 | if (strlen(buf) == 0) 48 | { 49 | printf("Error: cannot find config file path\n"); 50 | return; 51 | } 52 | FILE *f = fopen(buf, "r"); 53 | if (f == NULL) 54 | { 55 | // No high score file found 56 | return; 57 | } 58 | while (fgets(buf, sizeof buf, f)) 59 | { 60 | HighScore hs; 61 | struct tm tm; 62 | sscanf( 63 | buf, "%d %04d-%02d-%02d %02d:%02d:%02d", 64 | &hs.Score, &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 65 | &tm.tm_hour, &tm.tm_min, &tm.tm_sec); 66 | // Time correction 67 | tm.tm_year -= 1900; 68 | tm.tm_mon--; 69 | hs.Time = mktime(&tm); 70 | CArrayPushBack(&HighScores, &hs); 71 | } 72 | fclose(f); 73 | } 74 | void HighScoresFree(void) 75 | { 76 | CArrayTerminate(&HighScores); 77 | } 78 | 79 | void HighScoresAdd(const int s) 80 | { 81 | // Find the right position to add the score 82 | // Scores are in descending order 83 | HighScore hsNew; 84 | hsNew.Score = s; 85 | hsNew.Time = time(NULL); 86 | bool inserted = false; 87 | for (int i = 0; i < (int)HighScores.size; i++) 88 | { 89 | const HighScore *hs = CArrayGet(&HighScores, i); 90 | if (hs->Score <= s) 91 | { 92 | CArrayInsert(&HighScores, i, &hsNew); 93 | inserted = true; 94 | break; 95 | } 96 | } 97 | if (!inserted) 98 | { 99 | CArrayPushBack(&HighScores, &hsNew); 100 | } 101 | 102 | // Save to file 103 | char buf[MAX_PATH]; 104 | get_user_config_file(buf, MAX_PATH, HIGH_SCORE_FILE); 105 | if (strlen(buf) == 0) 106 | { 107 | printf("Error: cannot find config file path\n"); 108 | return; 109 | } 110 | FILE *f = fopen(buf, "w"); 111 | if (f == NULL) 112 | { 113 | printf("Error: cannot open config file %s\n", buf); 114 | return; 115 | } 116 | for (int i = 0; i < MIN((int)HighScores.size, MAX_HIGH_SCORES); i++) 117 | { 118 | const HighScore *hs = CArrayGet(&HighScores, i); 119 | struct tm *ptm = gmtime(&hs->Time); 120 | strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", ptm); 121 | fprintf(f, "%d %s\n", hs->Score, buf); 122 | } 123 | fclose(f); 124 | } 125 | 126 | 127 | TTF_Font *hsFont = NULL; 128 | 129 | #define HIGH_SCORE_DISPLAY_DY 20.0f 130 | #define HIGH_SCORE_DISPLAY_DDY 20.0f 131 | #define TEXT_COUNTER_LENGTH 1.5f 132 | #define TEXT_BLUE_LOW 64 133 | #define TEXT_BLUE_HIGH 196 134 | 135 | void HighScoreDisplayInit(HighScoreDisplay *h) 136 | { 137 | h->y = SCREEN_HEIGHT; 138 | h->dy = -HIGH_SCORE_DISPLAY_DY; 139 | h->h = 0; 140 | h->textCounter = 0; 141 | } 142 | 143 | void HighScoreDisplayUpdate(HighScoreDisplay *h, const Uint32 ms) 144 | { 145 | // If display reached top or bottom of screen, scroll the other way 146 | if (h->y >= SCREEN_HEIGHT - h->h && h->y >= 0) 147 | { 148 | h->dy -= HIGH_SCORE_DISPLAY_DDY * ms / 1000; 149 | if (h->dy < -HIGH_SCORE_DISPLAY_DY) h->dy = -HIGH_SCORE_DISPLAY_DY; 150 | } 151 | else if (h->y <= 0 && h->y + h->h <= SCREEN_HEIGHT) 152 | { 153 | h->dy += HIGH_SCORE_DISPLAY_DDY * ms / 1000; 154 | if (h->dy > HIGH_SCORE_DISPLAY_DY) h->dy = HIGH_SCORE_DISPLAY_DY; 155 | } 156 | h->y += h->dy * ms / 1000; 157 | h->textCounter += ms / TEXT_COUNTER_LENGTH / 1000; 158 | if (h->textCounter > 1.0f) h->textCounter -= 1.0f; 159 | } 160 | 161 | void HighScoreDisplayDraw(HighScoreDisplay *h) 162 | { 163 | char buf[2048]; 164 | strcpy(buf, "High Scores\n\n"); 165 | const bool countHeight = h->h == 0; 166 | if (countHeight) h->h += TTF_FontHeight(hsFont) * 2; 167 | for (int i = 0; i < (int)HighScores.size; i++) 168 | { 169 | const HighScore *hs = CArrayGet(&HighScores, i); 170 | char lbuf[256]; 171 | struct tm *ptm = gmtime(&hs->Time); 172 | char tbuf[256]; 173 | strftime(tbuf, sizeof tbuf, "%Y-%m-%d", ptm); 174 | sprintf(lbuf, "#%d %d (%s)\n", i + 1, hs->Score, tbuf); 175 | strcat(buf, lbuf); 176 | if (countHeight) 177 | { 178 | h->h += TTF_FontHeight(hsFont); 179 | } 180 | } 181 | // Pulsate 182 | const float scalar = 183 | h->textCounter > 0.5f ? 1.0f - h->textCounter : h->textCounter; 184 | SDL_Color c; 185 | c.b = TEXT_BLUE_LOW + (Uint8)((TEXT_BLUE_HIGH - TEXT_BLUE_LOW) * scalar); 186 | c.r = c.g = c.b / 2; 187 | TextRenderCentered(hsFont, buf, (int)h->y, c); 188 | } 189 | -------------------------------------------------------------------------------- /high_score.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include "c_array.h" 33 | 34 | 35 | typedef struct 36 | { 37 | int Score; 38 | time_t Time; 39 | } HighScore; 40 | 41 | extern CArray HighScores; // of HighScore 42 | 43 | void HighScoresInit(void); 44 | void HighScoresFree(void); 45 | 46 | // Add and also save the high scores 47 | void HighScoresAdd(const int s); 48 | 49 | typedef struct 50 | { 51 | float y; 52 | float dy; 53 | int h; 54 | 55 | // Counter from 0 to 1 for animating text colour 56 | float textCounter; 57 | } HighScoreDisplay; 58 | 59 | extern TTF_Font *hsFont; 60 | 61 | void HighScoreDisplayInit(HighScoreDisplay *h); 62 | void HighScoreDisplayUpdate(HighScoreDisplay *h, const Uint32 ms); 63 | void HighScoreDisplayDraw(HighScoreDisplay *h); -------------------------------------------------------------------------------- /init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #pragma once 20 | 21 | #include 22 | 23 | #define SCREEN_WIDTH 320 24 | #define SCREEN_HEIGHT 240 25 | #ifdef __GCW0__ 26 | #define SCREEN_SCALE 1 27 | #else 28 | #define SCREEN_SCALE 2 29 | #endif 30 | 31 | void Initialize(bool* Continue, bool* Error); 32 | void Finalize(void); 33 | -------------------------------------------------------------------------------- /input.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #include "input.h" 20 | 21 | #include 22 | 23 | #include "player.h" 24 | #include "utils.h" 25 | 26 | 27 | #define P1_LEFT SDL_SCANCODE_LEFT 28 | #define P1_RIGHT SDL_SCANCODE_RIGHT 29 | #define P1_CALL1 SDL_SCANCODE_UP 30 | #define P1_CALL2 SDL_SCANCODE_DOWN 31 | #ifdef __GCW0__ 32 | #define P2_LEFT0 SDL_SCANCODE_LSHIFT 33 | #define P2_RIGHT0 SDL_SCANCODE_LCTRL 34 | #define P2_LEFT1 SDL_SCANCODE_SPACE 35 | #define P2_RIGHT1 SDL_SCANCODE_LALT 36 | #else 37 | #define P2_LEFT0 SDL_SCANCODE_A 38 | #define P2_RIGHT0 SDL_SCANCODE_D 39 | #define P2_LEFT1 SDL_SCANCODE_Z 40 | #define P2_RIGHT1 SDL_SCANCODE_X 41 | #define P2_CALL1 SDL_SCANCODE_W 42 | #define P2_CALL2 SDL_SCANCODE_S 43 | #endif 44 | 45 | static bool pressed[SDL_NUM_SCANCODES]; 46 | #define JOY_DEADZONE 2000 47 | #ifdef __GCW0__ 48 | static SDL_Joystick *analog = NULL; 49 | static SDL_Joystick *gSensor = NULL; 50 | static int16_t gZero = 0; 51 | int JoystickIndex = -1; 52 | #define G_SENSITIVITY 7 53 | #else 54 | static SDL_Joystick *joysticks[MAX_PLAYERS]; 55 | #endif 56 | 57 | 58 | void InputInit(void) 59 | { 60 | memset(pressed, 0, sizeof pressed); 61 | for (int i = 0; i < SDL_NumJoysticks(); i++) 62 | { 63 | #ifdef __GCW0__ 64 | // Look for the right joysticks by name 65 | if (strcmp(SDL_JoystickName(i), "linkdev device (Analog 2-axis 8-button 2-hat)") == 0) 66 | analog = SDL_JoystickOpen(i); 67 | else if (strcmp(SDL_JoystickName(i), "mxc6225") == 0) 68 | gSensor = SDL_JoystickOpen(i); 69 | #else 70 | joysticks[i] = SDL_JoystickOpen(i); 71 | #endif 72 | } 73 | } 74 | void InputFree(void) 75 | { 76 | #ifdef __GCW0__ 77 | if (analog) SDL_JoystickClose(analog); 78 | if (gSensor) SDL_JoystickClose(gSensor); 79 | #endif 80 | } 81 | 82 | void InputOnEvent(const SDL_Event* event) 83 | { 84 | switch (event->type) 85 | { 86 | case SDL_KEYUP: 87 | case SDL_KEYDOWN: 88 | pressed[event->key.keysym.scancode] = event->type == SDL_KEYDOWN; 89 | break; 90 | default: 91 | break; 92 | } 93 | } 94 | 95 | static int16_t GetJoyX(SDL_Joystick *joy, const int16_t zero); 96 | int16_t GetMovement(const int player) 97 | { 98 | #ifdef __GCW0__ 99 | if (player == 0) 100 | { 101 | if (JoystickIndex == 0) 102 | { 103 | // Analog nub 104 | const int16_t x = GetJoyX(analog, 0); 105 | if (abs(x) > JOY_DEADZONE) return x; 106 | } 107 | else if (JoystickIndex == 1) 108 | { 109 | // G sensor 110 | const int gx = GetJoyX(gSensor, gZero) * G_SENSITIVITY; 111 | return (int16_t)CLAMP(gx, -32768, 32767); 112 | } 113 | } 114 | const bool left = player == 0 ? 115 | pressed[P1_LEFT] : (pressed[P2_LEFT0] || pressed[P2_LEFT1]); 116 | const bool right = player == 0 ? 117 | pressed[P1_RIGHT] : (pressed[P2_RIGHT0] || pressed[P2_RIGHT1]); 118 | return left ? (right ? 0 : -32768) : (right ? 32767 : 0); 119 | #else 120 | if (player < NumJoysticks) 121 | { 122 | // Joystick player; return analog stick 123 | const int16_t x = GetJoyX(joysticks[player], 0); 124 | if (abs(x) > JOY_DEADZONE) return x; 125 | return 0; 126 | // TODO: use D-pad as well 127 | } 128 | else 129 | { 130 | // Keyboards 131 | const bool left = player == NumJoysticks ? 132 | pressed[P1_LEFT] : (pressed[P2_LEFT0] || pressed[P2_LEFT1]); 133 | const bool right = player == NumJoysticks ? 134 | pressed[P1_RIGHT] : (pressed[P2_RIGHT0] || pressed[P2_RIGHT1]); 135 | return left ? (right ? 0 : -32768) : (right ? 32767 : 0); 136 | } 137 | #endif 138 | } 139 | static int16_t GetJoyX(SDL_Joystick *joy, const int16_t zero) 140 | { 141 | if (!joy) return 0; 142 | // Read X-axis of chosen joystick 143 | return (int16_t)SDL_JoystickGetAxis(joy, 0) + zero; 144 | } 145 | 146 | void ResetMovement(void) 147 | { 148 | memset(pressed, 0, sizeof pressed); 149 | } 150 | 151 | void InputSwitchJoystick(const int inc) 152 | { 153 | #ifdef __GCW0__ 154 | JoystickIndex = CLAMP_OPPOSITE(JoystickIndex + inc, -1, 1); 155 | if (JoystickIndex == 1 && gSensor) 156 | { 157 | // Recalibrate G sensor 158 | gZero = (int16_t)SDL_JoystickGetAxis(gSensor, 0); 159 | } 160 | #else 161 | UNUSED(inc); 162 | #endif 163 | } 164 | 165 | bool InputIsCalling(const int player) 166 | { 167 | #ifdef __GCW0__ 168 | if (player == 0) 169 | { 170 | // Left shoulder 171 | return pressed[SDLK_TAB]; 172 | } 173 | else 174 | { 175 | // Right shoulder 176 | return pressed[SDLK_BACKSPACE]; 177 | } 178 | #else 179 | if (player < NumJoysticks) 180 | { 181 | // Joystick player; return button 1 182 | return SDL_JoystickGetButton(joysticks[player], 0); 183 | } 184 | else 185 | { 186 | // Keyboards 187 | return player == NumJoysticks ? 188 | (pressed[P1_CALL1] || pressed[P1_CALL2]) : 189 | (pressed[P2_CALL1] || pressed[P2_CALL2]); 190 | } 191 | #endif 192 | } 193 | -------------------------------------------------------------------------------- /input.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | 25 | 26 | #ifdef __GCW0__ 27 | // Number determining which "joystick" to use 28 | // -1 means don't use joystick 29 | // 0 is the analog nub 30 | // 1 is G sensor 31 | extern int JoystickIndex; 32 | #endif 33 | 34 | void InputInit(void); 35 | void InputFree(void); 36 | 37 | void InputOnEvent(const SDL_Event* event); 38 | 39 | // GetMovement returns, after updating the platform-specific input status, a 40 | // value between -32768 and +32767 to indicate how far the ball needs to go. 41 | // Negative values go to the left; positive values go to the right. 42 | int16_t GetMovement(const int player); 43 | void ResetMovement(void); 44 | 45 | void InputSwitchJoystick(const int inc); 46 | 47 | bool InputIsCalling(const int player); 48 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include "main.h" 26 | #include "init.h" 27 | #include "platform.h" 28 | 29 | static bool Continue = true; 30 | static bool Error = false; 31 | 32 | SDL_Window *Window = NULL; 33 | SDL_Renderer *Renderer = NULL; 34 | 35 | TGatherInput GatherInput; 36 | TDoLogic DoLogic; 37 | TOutputFrame OutputFrame; 38 | 39 | int main(int argc, char* argv[]) 40 | { 41 | (void)argc; 42 | (void)argv; 43 | Initialize(&Continue, &Error); 44 | Uint32 Duration = 16; 45 | while (Continue) 46 | { 47 | GatherInput(&Continue); 48 | if (!Continue) 49 | break; 50 | DoLogic(&Continue, &Error, Duration); 51 | if (!Continue) 52 | break; 53 | OutputFrame(); 54 | Duration = ToNextFrame(); 55 | } 56 | Finalize(); 57 | return Error ? 1 : 0; 58 | } 59 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Nebuleon Fumika 3 | * 2015 Cong Xu 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "bg.h" 26 | 27 | typedef void (*TGatherInput) (bool* Continue); 28 | typedef void (*TDoLogic) (bool* Continue, bool* Error, Uint32 Milliseconds); 29 | typedef void (*TOutputFrame) (void); 30 | 31 | extern SDL_Window *Window; 32 | extern SDL_Renderer *Renderer; 33 | extern TGatherInput GatherInput; 34 | extern TDoLogic DoLogic; 35 | extern TOutputFrame OutputFrame; 36 | -------------------------------------------------------------------------------- /particle.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "particle.h" 27 | 28 | #include 29 | #ifndef M_PI 30 | #define M_PI 3.14159265358979323846264338327950288 31 | #endif 32 | #include 33 | #include 34 | #include 35 | 36 | #include "game.h" 37 | 38 | 39 | typedef struct 40 | { 41 | Animation anim; // note: no ownership, don't free 42 | float x; 43 | float y; 44 | float dx; 45 | float dy; 46 | } Particle; 47 | 48 | CArray Particles; 49 | 50 | 51 | void ParticlesInit(void) 52 | { 53 | CArrayInit(&Particles, sizeof(Particle)); 54 | } 55 | void ParticlesFree(void) 56 | { 57 | CArrayTerminate(&Particles); 58 | } 59 | 60 | void ParticlesAdd( 61 | const Animation *anim, const float x, const float y, 62 | const float dx, const float dy) 63 | { 64 | Particle p; 65 | memset(&p, 0, sizeof p); 66 | memcpy(&p.anim, anim, sizeof *anim); 67 | p.x = x; 68 | p.y = y; 69 | p.dx = dx; 70 | p.dy = dy; 71 | CArrayPushBack(&Particles, &p); 72 | } 73 | void ParticlesAddExplosion( 74 | const Animation *anim, const float x, const float y, const int n, 75 | const float speed) 76 | { 77 | for (int i = 0; i < n; i++) 78 | { 79 | const float theta = (float)rand() / RAND_MAX * (float)M_PI * 2; 80 | ParticlesAdd( 81 | anim, x, y, (float)cos(theta) * speed, (float)sin(theta) * speed); 82 | } 83 | } 84 | 85 | static bool ParticleUpdate(Particle *p, const Uint32 ms); 86 | void ParticlesUpdate(const Uint32 ms) 87 | { 88 | for (int i = 0; i < (int)Particles.size; i++) 89 | { 90 | Particle *p = CArrayGet(&Particles, i); 91 | if (!ParticleUpdate(p, ms)) 92 | { 93 | CArrayDelete(&Particles, i); 94 | } 95 | } 96 | } 97 | // Return whether to keep the particle 98 | static bool ParticleUpdate(Particle *p, const Uint32 ms) 99 | { 100 | p->x += p->dx * ms / 1000; 101 | p->y += p->dy * ms / 1000; 102 | return !AnimationUpdate(&p->anim, ms); 103 | } 104 | static void ParticleDraw(const Particle *p, const float y); 105 | void ParticlesDraw(const float y) 106 | { 107 | for (int i = 0; i < (int)Particles.size; i++) 108 | { 109 | ParticleDraw(CArrayGet(&Particles, i), y); 110 | } 111 | } 112 | static void ParticleDraw(const Particle *p, const float y) 113 | { 114 | AnimationDraw( 115 | &p->anim, (int)SCREEN_X(p->x), (int)(SCREEN_Y(p->y) - y)); 116 | } 117 | -------------------------------------------------------------------------------- /particle.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include "animation.h" 29 | 30 | 31 | extern CArray Particles; // of Particle 32 | 33 | void ParticlesInit(void); 34 | void ParticlesFree(void); 35 | 36 | void ParticlesAdd( 37 | const Animation *anim, const float x, const float y, 38 | const float dx, const float dy); 39 | void ParticlesAddExplosion( 40 | const Animation *anim, const float x, const float y, const int n, 41 | const float speed); 42 | 43 | void ParticlesUpdate(const Uint32 ms); 44 | void ParticlesDraw(const float y); 45 | -------------------------------------------------------------------------------- /pickup.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "pickup.h" 27 | 28 | #include 29 | #include 30 | 31 | #include "game.h" 32 | 33 | 34 | typedef struct 35 | { 36 | float x; 37 | float y; 38 | } Pickup; 39 | 40 | #define PICKUP_RADIUS 0.15f 41 | 42 | CArray Pickups; 43 | 44 | Tex PickupTex = { NULL, 0, 0 }; 45 | 46 | 47 | void PickupsInit(void) 48 | { 49 | CArrayInit(&Pickups, sizeof(Pickup)); 50 | } 51 | void PickupsFree(void) 52 | { 53 | CArrayTerminate(&Pickups); 54 | } 55 | void PickupsReset(void) 56 | { 57 | CArrayClear(&Pickups); 58 | } 59 | 60 | void PickupsAdd(const float x, const float y) 61 | { 62 | Pickup p; 63 | memset(&p, 0, sizeof p); 64 | p.x = x; 65 | p.y = y + PICKUP_RADIUS; 66 | CArrayPushBack(&Pickups, &p); 67 | } 68 | 69 | static bool PickupCollide( 70 | Pickup *p, const float x, const float y, const float r); 71 | bool PickupsCollide(const float x, const float y, const float r) 72 | { 73 | for (int i = 0; i < (int)Pickups.size; i++) 74 | { 75 | Pickup *p = CArrayGet(&Pickups, i); 76 | 77 | // Remove pickups that are off the top of the screen 78 | if (p->y > y + FIELD_HEIGHT * 2) 79 | { 80 | CArrayDelete(&Pickups, i); 81 | continue; 82 | } 83 | 84 | if (PickupCollide(p, x, y, r)) 85 | { 86 | CArrayDelete(&Pickups, i); 87 | return true; 88 | } 89 | } 90 | return false; 91 | } 92 | static bool PickupCollide( 93 | Pickup *p, const float x, const float y, const float r) 94 | { 95 | const float dx = p->x - x; 96 | const float dy = p->y - y; 97 | const float d2 = dx * dx + dy * dy; 98 | const float rTotal = r + PICKUP_RADIUS; 99 | const float r2 = rTotal * rTotal; 100 | return d2 <= r2; 101 | } 102 | static void PickupDraw(const Pickup *p, const float y); 103 | void PickupsDraw(const float y) 104 | { 105 | for (int i = 0; i < (int)Pickups.size; i++) 106 | { 107 | PickupDraw(CArrayGet(&Pickups, i), y); 108 | } 109 | } 110 | static void PickupDraw(const Pickup *p, const float y) 111 | { 112 | SDL_Rect dest = { 113 | (int)SCREEN_X(p->x) - PickupTex.W / 2, 114 | (int)(SCREEN_Y(p->y) - PickupTex.H / 2 - y), 115 | PickupTex.W, PickupTex.H 116 | }; 117 | RenderTex(PickupTex.T, NULL, &dest); 118 | } 119 | -------------------------------------------------------------------------------- /pickup.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include "c_array.h" 29 | #include "draw.h" 30 | 31 | 32 | extern CArray Pickups; // of Pickup 33 | 34 | extern Tex PickupTex; 35 | 36 | void PickupsInit(void); 37 | void PickupsFree(void); 38 | void PickupsReset(void); 39 | 40 | void PickupsAdd(const float x, const float y); 41 | 42 | // Only collides once, and removes the colliding pickup 43 | bool PickupsCollide(const float x, const float y, const float r); 44 | void PickupsDraw(const float y); 45 | -------------------------------------------------------------------------------- /pkg/default.gcw0.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | 3 | Name=Falling Time 4 | Comment=Guide a falling ball through blocks. Avoid getting crushed! 5 | Icon=icon 6 | Exec=falling_time 7 | Terminal=false 8 | Type=Application 9 | StartupNotify=true 10 | Categories=games; 11 | X-OD-NeedsGSensor=true 12 | -------------------------------------------------------------------------------- /pkg/linux/fallingtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/pkg/linux/fallingtime.png -------------------------------------------------------------------------------- /pkg/linux/io.github.cxong.fallingtime.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Falling Time 3 | GenericName=Vertical sidescroller 4 | Comment=Vertical sidescroller for 1 or 2 players rolling down platforms 5 | Exec=fallingtime 6 | Icon=fallingtime 7 | Terminal=false 8 | Type=Application 9 | Categories=Game;ArcadeGame; 10 | -------------------------------------------------------------------------------- /pkg/macosx/SDLMain.h: -------------------------------------------------------------------------------- 1 | /* SDLMain.m - main entry point for our Cocoa-ized SDL app 2 | Initial Version: Darrell Walisser 3 | Non-NIB-Code & other changes: Max Horn 4 | 5 | Feel free to customize this file to suit your needs 6 | */ 7 | 8 | #ifndef _SDLMain_h_ 9 | #define _SDLMain_h_ 10 | 11 | #import 12 | 13 | @interface SDLMain : NSObject 14 | @end 15 | 16 | #endif /* _SDLMain_h_ */ 17 | -------------------------------------------------------------------------------- /pkg/macosx/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/pkg/macosx/icon.icns -------------------------------------------------------------------------------- /pkg/make_opk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # usage: path/to/make_opk.sh [ ] 4 | # The parameters are needed, because cmake supports out-of-source builds. 5 | # When missing, a in-source build is assumed and default directories are set. 6 | 7 | mydir=`dirname $0` 8 | 9 | if [ -z "$1" ]; then 10 | datadir=${mydir}/.. 11 | else 12 | datadir=$1 13 | fi 14 | 15 | # to prevent interfering with an existing desktop build, build in a separate directory 16 | mkdir -p "${datadir}/pkg/gcw_build" 17 | cd "${datadir}/pkg/gcw_build" 18 | # this is important, otherwise the existing CMakeCache will be used (and overwritten) 19 | touch CMakeCache.txt 20 | 21 | cmake -DCMAKE_TOOLCHAIN_FILE="/opt/gcw0-toolchain/usr/share/buildroot/toolchainfile.cmake" -DCMAKE_BUILD_TYPE=Release ../../ 22 | make clean 23 | make 24 | cd - 25 | 26 | bin="${datadir}/pkg/gcw_build/falling_time" 27 | 28 | data="${datadir}/data ${datadir}/COPYRIGHT" 29 | 30 | gcwzdata="${mydir}/default.gcw0.desktop" 31 | gcwzdata="${gcwzdata} ${datadir}/data/graphics/icon.png" 32 | 33 | alldata="${gcwzdata} ${bin} ${data}" 34 | 35 | /opt/gcw0-toolchain/usr/bin/mksquashfs ${alldata} falling_time.opk -all-root -noappend -no-exports -no-xattrs 36 | -------------------------------------------------------------------------------- /platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Ativayeban, platform-specific functions, header 3 | * Copyright (C) 2014 Nebuleon Fumika 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define FPS 60 24 | 25 | extern void InitializePlatform(void); 26 | 27 | /* 28 | * Advances the game by a platform-appropriate time, and returns the number of 29 | * milliseconds that have been skipped over. 30 | */ 31 | extern Uint32 ToNextFrame(void); 32 | 33 | // Is???Event returns true if the specified event is used to trigger the ??? 34 | // function. 35 | // EnterGamePressing: true if the event can be used to start a game from the 36 | // title and score screens. 37 | // EnterGameReleasing: true if the event releases buttons from the above. 38 | // ExitGame: true if the event can be used to exit the entire application. 39 | // Pause: true if the event can be used to pause a game in progress. 40 | 41 | // Get???Prompt returns the text that can be used to describe the actions that 42 | // can trigger a feature on the platform. 43 | 44 | extern bool IsEnterGamePressingEvent(const SDL_Event* event); 45 | extern bool IsEnterGameReleasingEvent(const SDL_Event* event); 46 | extern const char* GetEnterGamePrompt(void); 47 | 48 | extern bool IsExitGameEvent(const SDL_Event* event); 49 | extern const char* GetExitGamePrompt(void); 50 | 51 | extern bool IsPauseEvent(const SDL_Event* event); 52 | extern const char* GetPausePrompt(void); 53 | -------------------------------------------------------------------------------- /platform/general.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Ativayeban, default platform-specific code file 3 | * Copyright (C) 2014 Nebuleon Fumika 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "SDL.h" 24 | 25 | #include "platform.h" 26 | 27 | static Uint32 LastTicks = 0; 28 | static Uint32 TicksElapsed = 0; 29 | 30 | void InitializePlatform(void) 31 | { 32 | LastTicks = SDL_GetTicks(); 33 | } 34 | 35 | Uint32 ToNextFrame(void) 36 | { 37 | const Uint32 duration = 1000 / FPS; 38 | for (;;) 39 | { 40 | Uint32 Ticks = SDL_GetTicks(); 41 | TicksElapsed += Ticks - LastTicks; 42 | LastTicks = Ticks; 43 | if (TicksElapsed <= duration) 44 | { 45 | SDL_Delay(1); 46 | continue; 47 | } 48 | break; 49 | } 50 | TicksElapsed -= duration; 51 | return duration; 52 | } 53 | 54 | bool IsEnterGamePressingEvent(const SDL_Event* event) 55 | { 56 | return event->type == SDL_KEYDOWN 57 | && (event->key.keysym.sym == SDLK_RETURN 58 | || event->key.keysym.sym == SDLK_SPACE); 59 | } 60 | 61 | bool IsEnterGameReleasingEvent(const SDL_Event* event) 62 | { 63 | return event->type == SDL_KEYUP 64 | && (event->key.keysym.sym == SDLK_RETURN 65 | || event->key.keysym.sym == SDLK_SPACE); 66 | } 67 | 68 | const char* GetEnterGamePrompt(void) 69 | { 70 | return "Enter/Space"; 71 | } 72 | 73 | bool IsExitGameEvent(const SDL_Event* event) 74 | { 75 | return event->type == SDL_QUIT 76 | || (event->type == SDL_KEYDOWN 77 | && event->key.keysym.sym == SDLK_ESCAPE); 78 | } 79 | 80 | const char* GetExitGamePrompt(void) 81 | { 82 | return "Esc"; 83 | } 84 | 85 | bool IsPauseEvent(const SDL_Event* event) 86 | { 87 | return event->type == SDL_KEYDOWN 88 | && event->key.keysym.sym == SDLK_p; 89 | } 90 | 91 | const char* GetPausePrompt(void) 92 | { 93 | return "P"; 94 | } 95 | -------------------------------------------------------------------------------- /platform/opendingux.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Ativayeban, OpenDingux platform-specific code file 3 | * Copyright (C) 2014 Nebuleon Fumika 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 2 8 | * of the License, or (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "SDL.h" 24 | 25 | #include "platform.h" 26 | 27 | void InitializePlatform(void) 28 | { 29 | } 30 | 31 | Uint32 ToNextFrame(void) 32 | { 33 | // OpenDingux waits for vertical sync by itself. 34 | return 16; 35 | } 36 | 37 | bool IsEnterGamePressingEvent(const SDL_Event* event) 38 | { 39 | return event->type == SDL_KEYDOWN 40 | && (event->key.keysym.sym == SDLK_RETURN /* Start */); 41 | } 42 | 43 | bool IsEnterGameReleasingEvent(const SDL_Event* event) 44 | { 45 | return event->type == SDL_KEYUP 46 | && (event->key.keysym.sym == SDLK_RETURN /* Start */); 47 | } 48 | 49 | const char* GetEnterGamePrompt(void) 50 | { 51 | return "Start"; 52 | } 53 | 54 | bool IsExitGameEvent(const SDL_Event* event) 55 | { 56 | return event->type == SDL_QUIT 57 | || (event->type == SDL_KEYDOWN 58 | && (event->key.keysym.sym == SDLK_ESCAPE /* Select */)); 59 | } 60 | 61 | const char* GetExitGamePrompt(void) 62 | { 63 | return "Select"; 64 | } 65 | 66 | bool IsPauseEvent(const SDL_Event* event) 67 | { 68 | return event->type == SDL_KEYDOWN 69 | && event->key.keysym.sym == SDLK_RETURN /* Start */; 70 | } 71 | 72 | const char* GetPausePrompt(void) 73 | { 74 | return "Start"; 75 | } 76 | -------------------------------------------------------------------------------- /player.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "animation.h" 9 | 10 | 11 | typedef struct 12 | { 13 | int Index; 14 | 15 | // Whether the player is in the game or not 16 | bool Enabled; 17 | bool Alive; 18 | // Once dead, wait this long before respawning 19 | int RespawnCounter; 20 | 21 | int Score; 22 | 23 | cpBody *Body; 24 | // Cached positions for drawing only 25 | float x, y; 26 | 27 | // The last value returned by GetMovement. 28 | int16_t AccelX; 29 | 30 | // Used to detect rolling for rolling sound 31 | bool WasOnSurface; 32 | 33 | // Used to detect consecutive fall scoring 34 | bool ScoredInAir; 35 | 36 | // Used to animate the player rolling 37 | int Roll; 38 | 39 | // Blink until counter runs out 40 | int BlinkCounter; 41 | // Blink when counter reaches zero 42 | int NextBlinkCounter; 43 | 44 | // Leave tail particles 45 | int TailCounter; 46 | 47 | Tex T; 48 | } Player; 49 | 50 | #define MAX_PLAYERS 4 51 | extern Player players[MAX_PLAYERS]; 52 | extern int NumPlayers; 53 | #ifndef __GCW0__ 54 | extern int NumJoysticks; 55 | #endif 56 | 57 | #define PLAYER_SPRITESHEET_WIDTH 35 58 | #define PLAYER_SPRITESHEET_HEIGHT 35 59 | 60 | extern Tex PlayerSpritesheets[MAX_PLAYERS]; 61 | extern Animation Spark; 62 | extern Animation SparkRed; 63 | extern Animation Tail; 64 | extern Mix_Chunk* SoundPlayerBounce; 65 | extern int SoundPlayerRollChannel; 66 | 67 | void PlayerUpdate(Player *player, const Uint32 ms); 68 | void PlayerDraw(const Player *player, const float y); 69 | void PlayerInit(Player *player, const int i, const cpVect pos); 70 | void PlayerReset(Player *player, const int i); 71 | 72 | void PlayerScore(Player *player, const bool air); 73 | void PlayerKill(Player *player); 74 | void PlayerRespawn(Player *player, const float x, const float y); 75 | void PlayerRevive(Player *player); 76 | 77 | int PlayerAliveCount(void); 78 | int PlayerEnabledCount(void); -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cxong/FallingTime/ddc439795e91afc14b04e6df03fd8bde55e1481f/screenshot.png -------------------------------------------------------------------------------- /sound.c: -------------------------------------------------------------------------------- 1 | #include "sound.h" 2 | 3 | #include 4 | 5 | #include "player.h" 6 | #include "sys_config.h" 7 | #include "utils.h" 8 | 9 | #define BOUNCE_SPEED_MAX_VOLUME 150.0f 10 | #define BOUNCE_SPEED_MIN_VOLUME 10.0f 11 | #define ROLL_SPEED_MAX_VOLUME 20.0f 12 | static int rollChannels[MAX_PLAYERS]; 13 | static int callChannels[MAX_PLAYERS]; 14 | 15 | #define MUSIC_VOLUME_LOW 24 16 | #define MUSIC_VOLUME_HIGH 64 17 | 18 | Mix_Music *music; 19 | Mix_Chunk* SoundPlayerRoll = NULL; 20 | Mix_Chunk *SoundPlayerCalls[MAX_PLAYERS]; 21 | 22 | 23 | bool SoundLoad(void) 24 | { 25 | #define LOAD_SOUND(_sound, _path)\ 26 | _sound = Mix_LoadWAV(DATA_DIR "sounds/" _path);\ 27 | if (_sound == NULL)\ 28 | {\ 29 | printf("Mix_LoadWAV failed: %s\n", SDL_GetError());\ 30 | SDL_ClearError();\ 31 | return false;\ 32 | } 33 | LOAD_SOUND(SoundPlayerRoll, "roll.ogg"); 34 | LOAD_SOUND(SoundPlayerCalls[0], "penguin.ogg"); 35 | LOAD_SOUND(SoundPlayerCalls[1], "chicken.ogg"); 36 | LOAD_SOUND(SoundPlayerCalls[2], "quack.ogg"); 37 | LOAD_SOUND(SoundPlayerCalls[3], "turkey.ogg"); 38 | 39 | for (int i = 0; i < MAX_PLAYERS; i++) 40 | { 41 | rollChannels[i] = -1; 42 | callChannels[i] = -1; 43 | } 44 | 45 | return true; 46 | } 47 | void SoundFree(void) 48 | { 49 | Mix_FreeChunk(SoundPlayerRoll); 50 | for (int i = 0; i < MAX_PLAYERS; i++) 51 | { 52 | Mix_FreeChunk(SoundPlayerCalls[i]); 53 | } 54 | } 55 | 56 | void SoundPlay(Mix_Chunk *sound, const float volume) 57 | { 58 | const int channel = Mix_PlayChannel(-1, sound, 0); 59 | if (channel >= 0) 60 | { 61 | Mix_Volume(channel, (int)round(MIN(1.0f, volume) * MIX_MAX_VOLUME)); 62 | } 63 | } 64 | 65 | void SoundPlayBounce(const float speed) 66 | { 67 | const float imp = (float)fabs(speed); 68 | if (imp < BOUNCE_SPEED_MIN_VOLUME) return; 69 | SoundPlay(SoundPlayerBounce, imp / BOUNCE_SPEED_MAX_VOLUME); 70 | } 71 | 72 | void SoundPlayRoll(const int player, const float speed) 73 | { 74 | if (rollChannels[player] == -1) 75 | { 76 | rollChannels[player] = Mix_PlayChannel(-1, SoundPlayerRoll, -1); 77 | } 78 | if (rollChannels[player] != -1) 79 | { 80 | const float volume = (float)fabs(speed) / ROLL_SPEED_MAX_VOLUME; 81 | Mix_Volume( 82 | rollChannels[player], 83 | (int)round(MIN(1.0f, volume) * MIX_MAX_VOLUME)); 84 | } 85 | } 86 | 87 | void SoundStopRoll(const int player) 88 | { 89 | if (rollChannels[player] != -1) 90 | { 91 | Mix_HaltChannel(rollChannels[player]); 92 | rollChannels[player] = -1; 93 | } 94 | } 95 | 96 | void SoundPlayCall(const int player) 97 | { 98 | if (callChannels[player] == -1) 99 | { 100 | callChannels[player] = 101 | Mix_PlayChannel(-1, SoundPlayerCalls[player], -1); 102 | } 103 | if (callChannels[player] != -1) 104 | { 105 | Mix_Volume(callChannels[player], MIX_MAX_VOLUME); 106 | } 107 | } 108 | void SoundStopCall(const int player) 109 | { 110 | if (callChannels[player] != -1) 111 | { 112 | Mix_HaltChannel(callChannels[player]); 113 | callChannels[player] = -1; 114 | } 115 | } 116 | 117 | void MusicSetLoud(const bool fullVolume) 118 | { 119 | Mix_VolumeMusic(fullVolume ? MUSIC_VOLUME_HIGH : MUSIC_VOLUME_LOW); 120 | } 121 | -------------------------------------------------------------------------------- /sound.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | #include 31 | 32 | extern Mix_Music *music; 33 | 34 | void SoundPlay(Mix_Chunk *sound, const float volume); 35 | void SoundPlayBounce(const float speed); 36 | void SoundPlayRoll(const int player, const float speed); 37 | void SoundStopRoll(const int player); 38 | void SoundPlayCall(const int player); 39 | void SoundStopCall(const int player); 40 | 41 | void MusicSetLoud(const bool fullVolume); 42 | 43 | bool SoundLoad(void); 44 | void SoundFree(void); 45 | -------------------------------------------------------------------------------- /space.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | #include "c_array.h" 31 | #include "player.h" 32 | 33 | 34 | // Represents physical space of the level 35 | typedef struct 36 | { 37 | cpSpace *Space; 38 | cpBody *edgeBodies; 39 | float edgeBodiesBottom; 40 | 41 | CArray Gaps; // of Gap 42 | float gapGenDistance; 43 | float gapWidth; 44 | } Space; 45 | 46 | extern Space space; 47 | 48 | void SpaceInit(Space *s); 49 | void SpaceReset(Space *s); 50 | void SpaceFree(Space *s); 51 | 52 | void SpaceAddBottomEdge(Space *s); 53 | void SpaceUpdate( 54 | Space *s, const float y, const float cameraY, const float playerMaxY, 55 | Player *players); 56 | void SpaceDraw(const Space *s, const float y); 57 | 58 | void SpaceRespawnPlayer(Space *s, Player *p); 59 | -------------------------------------------------------------------------------- /sys_config.h.cmake: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DATA_DIR "@DATA_DIR@" 4 | -------------------------------------------------------------------------------- /sys_specifics.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #ifdef _MSC_VER 29 | #define snprintf _snprintf 30 | #endif -------------------------------------------------------------------------------- /text.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "text.h" 27 | 28 | #include 29 | #include 30 | 31 | #include "init.h" 32 | #include "main.h" 33 | 34 | 35 | void TextRenderCentered( 36 | TTF_Font *font, const char *text, const int startY, 37 | const SDL_Color c) 38 | { 39 | int y = startY; 40 | for (;;) 41 | { 42 | // Render the text line-by-line 43 | const char *nl = strchr(text, '\n'); 44 | char buf[256]; 45 | if (nl != NULL) 46 | { 47 | const size_t len = nl - text; 48 | strncpy(buf, text, len); 49 | buf[len] = '\0'; 50 | } 51 | else 52 | { 53 | strcpy(buf, text); 54 | } 55 | 56 | if (strlen(buf) > 0) 57 | { 58 | Tex t = LoadText(buf, font, c); 59 | if (t.T == NULL) return; 60 | const int x = (SCREEN_WIDTH - t.W) / 2; 61 | SDL_Rect dest = { x, y, t.W, t.H }; 62 | RenderTex(t.T, NULL, &dest); 63 | SDL_DestroyTexture(t.T); 64 | } 65 | y += TTF_FontHeight(font); 66 | 67 | if (nl == NULL) 68 | { 69 | break; 70 | } 71 | text = nl + 1; 72 | } 73 | } -------------------------------------------------------------------------------- /text.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | 30 | void TextRenderCentered( 31 | TTF_Font *font, const char *text, const int startY, 32 | const SDL_Color c); 33 | -------------------------------------------------------------------------------- /title.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Ativayeban, title screen header 3 | * Copyright (C) 2014 Nebuleon Fumika 4 | * 2015 Cong Xu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | 26 | void ToTitleScreen(const bool start); 27 | 28 | bool TitleImagesLoad(void); 29 | void TitleImagesFree(void); 30 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Cong Xu 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #pragma once 27 | 28 | #include 29 | #include 30 | 31 | #ifndef __func__ 32 | #define __func__ __FUNCTION__ 33 | #endif 34 | 35 | #ifndef MAX 36 | #define MAX(x, y) ((x) > (y) ? (x) : (y)) 37 | #endif 38 | #ifndef MIN 39 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) 40 | #endif 41 | #define CLAMP(v, _min, _max) MAX((_min), MIN((_max), (v))) 42 | #define CLAMP_OPPOSITE(v, _min, _max)\ 43 | ((v) > (_max) ? (_min) : ((v) < (_min) ? (_max) : (v))) 44 | #define SIGN(_x) ((_x) < 0 ? -1 : 1) 45 | #define UNUSED(expr) (void)(expr) 46 | 47 | #ifdef _MSC_VER 48 | #define CHALT() __debugbreak() 49 | #else 50 | #define CHALT() 51 | #endif 52 | 53 | #define CASSERT(_x, _errmsg)\ 54 | {\ 55 | volatile bool isOk = _x;\ 56 | if (!isOk)\ 57 | {\ 58 | static char _buf[1024];\ 59 | sprintf(\ 60 | _buf,\ 61 | "In %s %d:%s: " _errmsg " (" #_x ")",\ 62 | __FILE__, __LINE__, __func__);\ 63 | CHALT();\ 64 | assert(_x);\ 65 | }\ 66 | } 67 | 68 | #define _CCHECKALLOC(_func, _var, _size)\ 69 | {\ 70 | if (_var == NULL && _size > 0)\ 71 | {\ 72 | exit(1);\ 73 | }\ 74 | } 75 | 76 | #define CMALLOC(_var, _size)\ 77 | {\ 78 | _var = malloc(_size);\ 79 | _CCHECKALLOC("CMALLOC", _var, (_size))\ 80 | } 81 | #define CCALLOC(_var, _size)\ 82 | {\ 83 | _var = calloc(1, _size);\ 84 | _CCHECKALLOC("CCALLOC", _var, (_size))\ 85 | } 86 | #define CREALLOC(_var, _size)\ 87 | {\ 88 | _var = realloc(_var, _size);\ 89 | _CCHECKALLOC("CREALLOC", _var, (_size))\ 90 | } 91 | #define CSTRDUP(_var, _str)\ 92 | {\ 93 | CMALLOC(_var, strlen(_str) + 1);\ 94 | strcpy(_var, _str);\ 95 | } 96 | 97 | #define CFREE(_var)\ 98 | {\ 99 | free(_var);\ 100 | } 101 | --------------------------------------------------------------------------------