1 /*
2  * Copyright (c) 2007-2013 Scott Lembcke and Howling Moon Software
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 module demo.LogoSmash;
23 
24 import demo.dchip;
25 
26 import demo.ChipmunkDebugDraw;
27 import demo.ChipmunkDemo;
28 import demo.types;
29 
30 const int image_width      = 188;
31 const int image_height     = 35;
32 const int image_row_length = 24;
33 
34 immutable byte[] image_bitmap = [
35     15, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, -64, 15, 63, -32, -2, 0, 0, 0, 0, 0, 0, 0,
36     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -64, 15, 127, -125, -1, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37     0, 0, 0, 127, -64, 15, 127, 15, -1, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 15, -2,
38     31, -1, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 0, -4, 63, -1, -32, 0, 0, 0, 0, 0, 0,
39     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -64, 15, -8, 127, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40     1, -1, -64, 0, -8, -15, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -31, -1, -64, 15, -8, -32,
41     -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, -15, -1, -64, 9, -15, -32, -1, -32, 0, 0, 0, 0, 0,
42     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -15, -1, -64, 0, -15, -32, -1, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43     0, 0, 63, -7, -1, -64, 9, -29, -32, 127, -61, -16, 63, 15, -61, -1, -8, 31, -16, 15, -8, 126, 7, -31,
44     -8, 31, -65, -7, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -2, 63, -8, 31, -4, -1, 15, -13,
45     -4, 63, -1, -3, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -2, 63, -8, 31, -4, -1, 15, -13,
46     -2, 63, -1, -3, -1, -64, 9, -29, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
47     -2, 63, -33, -1, -1, -32, 9, -25, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
48     -1, 63, -33, -1, -1, -16, 9, -25, -32, 0, 7, -8, 127, -97, -25, -1, -1, 63, -4, 63, -4, -1, 15, -13,
49     -1, 63, -49, -1, -1, -8, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
50     -1, -65, -49, -1, -1, -4, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
51     -1, -65, -57, -1, -1, -2, 9, -57, -32, 0, 7, -8, 127, -97, -25, -8, -1, 63, -2, 127, -4, -1, 15, -13,
52     -1, -1, -57, -1, -1, -1, 9, -57, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
53     -1, -61, -1, -1, -1, -119, -57, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
54     -1, -61, -1, -1, -1, -55, -49, -32, 0, 7, -1, -1, -97, -25, -8, -1, 63, -1, -1, -4, -1, 15, -13, -1,
55     -1, -63, -1, -1, -1, -23, -49, -32, 127, -57, -1, -1, -97, -25, -1, -1, 63, -1, -1, -4, -1, 15, -13,
56     -1, -1, -63, -1, -1, -1, -16, -49, -32, -1, -25, -1, -1, -97, -25, -1, -1, 63, -33, -5, -4, -1, 15,
57     -13, -1, -1, -64, -1, -9, -1, -7, -49, -32, -1, -25, -8, 127, -97, -25, -1, -1, 63, -33, -5, -4, -1,
58     15, -13, -1, -1, -64, -1, -13, -1, -32, -49, -32, -1, -25, -8, 127, -97, -25, -1, -2, 63, -49, -13,
59     -4, -1, 15, -13, -1, -1, -64, 127, -7, -1, -119, -17, -15, -1, -25, -8, 127, -97, -25, -1, -2, 63,
60     -49, -13, -4, -1, 15, -13, -3, -1, -64, 127, -8, -2, 15, -17, -1, -1, -25, -8, 127, -97, -25, -1,
61     -8, 63, -49, -13, -4, -1, 15, -13, -3, -1, -64, 63, -4, 120, 0, -17, -1, -1, -25, -8, 127, -97, -25,
62     -8, 0, 63, -57, -29, -4, -1, 15, -13, -4, -1, -64, 63, -4, 0, 15, -17, -1, -1, -25, -8, 127, -97,
63     -25, -8, 0, 63, -57, -29, -4, -1, -1, -13, -4, -1, -64, 31, -2, 0, 0, 103, -1, -1, -57, -8, 127, -97,
64     -25, -8, 0, 63, -57, -29, -4, -1, -1, -13, -4, 127, -64, 31, -2, 0, 15, 103, -1, -1, -57, -8, 127,
65     -97, -25, -8, 0, 63, -61, -61, -4, 127, -1, -29, -4, 127, -64, 15, -8, 0, 0, 55, -1, -1, -121, -8,
66     127, -97, -25, -8, 0, 63, -61, -61, -4, 127, -1, -29, -4, 63, -64, 15, -32, 0, 0, 23, -1, -2, 3, -16,
67     63, 15, -61, -16, 0, 31, -127, -127, -8, 31, -1, -127, -8, 31, -128, 7, -128, 0, 0
68 ];
69 
70 int get_pixel(int x, int y)
71 {
72     return (image_bitmap[(x >> 3) + y * image_row_length] >> (~x & 0x7)) & 1;
73 }
74 
75 int bodyCount = 0;
76 
77 void update(cpSpace* space, double dt)
78 {
79     cpSpaceStep(space, dt);
80 }
81 
82 void DrawDot(cpBody* body_, void* unused)
83 {
84     ChipmunkDebugDrawDot(3.0, cpBodyGetPos(body_), RGBAColor(200.0f / 255.0f, 210.0f / 255.0f, 230.0f / 255.0f, 1.0f));
85 }
86 
87 void draw(cpSpace* space)
88 {
89     cpSpaceEachBody(space, &DrawDot, null);
90 
91     ChipmunkDebugDrawCollisionPoints(space);
92 }
93 
94 cpShape* make_ball(cpFloat x, cpFloat y)
95 {
96     cpBody* body_ = cpBodyNew(1.0, INFINITY);
97     cpBodySetPos(body_, cpv(x, y));
98 
99     cpShape* shape = cpCircleShapeNew(body_, 0.95, cpvzero);
100     cpShapeSetElasticity(shape, 0.0);
101     cpShapeSetFriction(shape, 0.0);
102 
103     return shape;
104 }
105 
106 cpSpace* init()
107 {
108     cpSpace* space = cpSpaceNew();
109     cpSpaceSetIterations(space, 1);
110 
111     // The space will contain a very large number of similary sized objects.
112     // This is the perfect candidate for using the spatial hash.
113     // Generally you will never need to do this.
114     cpSpaceUseSpatialHash(space, 2.0, 10000);
115 
116     bodyCount = 0;
117 
118     cpBody * body_;
119     cpShape* shape;
120 
121     for (int y = 0; y < image_height; y++)
122     {
123         for (int x = 0; x < image_width; x++)
124         {
125             if (!get_pixel(x, y))
126                 continue;
127 
128             cpFloat x_jitter = 0.05 * frand();
129             cpFloat y_jitter = 0.05 * frand();
130 
131             shape = make_ball(2 * (x - image_width / 2 + x_jitter), 2 * (image_height / 2 - y + y_jitter));
132             cpSpaceAddBody(space, cpShapeGetBody(shape));
133             cpSpaceAddShape(space, shape);
134 
135             bodyCount++;
136         }
137     }
138 
139     body_ = cpSpaceAddBody(space, cpBodyNew(INFINITY, INFINITY));
140     cpBodySetPos(body_, cpv(-1000, -10));
141     cpBodySetVel(body_, cpv(400, 0));
142 
143     shape = cpSpaceAddShape(space, cpCircleShapeNew(body_, 8.0f, cpvzero));
144     cpShapeSetElasticity(shape, 0.0);
145     cpShapeSetFriction(shape, 0.0);
146     cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
147 
148     bodyCount++;
149 
150     return space;
151 }
152 
153 void destroy(cpSpace* space)
154 {
155     ChipmunkDemoFreeSpaceChildren(space);
156     cpSpaceFree(space);
157 }
158 
159 ChipmunkDemo LogoSmash = {
160     "Logo Smash",
161     1.0 / 60.0,
162     &init,
163     &update,
164     &draw,
165     &destroy,
166 };