1 /**************************************************************************
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 3
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 **************************************************************************/
16 // ////////////////////////////////////////////////////////////////////////// //
20 BackTileStore bgtileStore;
30 //spr[0] = sprStore['sDuckLeft'];
31 //spr[0] = sprStore['sSkull'];
32 //spr[0] = sprStore['sGoldIdol'];
34 spr[0] = sprStore['sMagmz'];
37 spr[1] = sprStore['sExplosionMask'];
40 spr[1] = sprStore['sDuckLeft'];
42 spr[1] = sprStore['sMagma'];
48 bool isInEllipse (int px, int py, int x0, int y0, int x1, int y1) {
49 if (x1 < x0 || y1 < y0) return false;
50 if (px < x0 || py < y0 || px > x1 || py > y1) return false;
53 float _xRadius = ewdt/2.0;
54 float _yRadius = ehgt/2.0;
55 if (_xRadius <= 0.0 || _yRadius <= 0.0) return false;
56 float cx = x0+_xRadius;
57 float cy = y0+_yRadius;
58 /* This is a more general form of the circle equation
60 * X^2/a^2 + Y^2/b^2 <= 1
62 float normx = px+0.5-cx;
63 float normy = py+0.5-cy;
64 //Point normalized = new Point(px - center.X, py - center.Y);
65 return ((normx*normx)/(_xRadius*_xRadius)+(normy*normy)/(_yRadius*_yRadius) <= 1.0);
70 int x0 = 20, y0 = 200;
71 int x1 = 90, y1 = 220;
72 foreach (int py; y0..y1+1) {
73 foreach (int px; x0..x1+1) {
74 if (isInEllipse(px, py, x0, y0, x1, y1)) {
75 Video.fillRect(px, py, 1, 1);
79 Video.color = 0xff_7f_00;
80 Video.drawRect(x0-1, y0-1, x1-x0+3, y1-y0+3);
84 void drawMask (SpriteFrame frm, int x0, int y0, int scale, int col) {
87 Video.color = 0x7f_ff_ff_00;
88 foreach (int y; 0..frm.height) {
89 foreach (int x; 0..frm.width) {
90 if (frm.getMaskPixel(x, y)) {
91 Video.color = 0x3f_ff_ff_00;
93 Video.color = 0xcf_ff_ff_00;
95 Video.fillRect(x0+x*scale, y0+y*scale, scale, scale);
99 CollisionMask cm = CollisionMask.Create(frm, false);
100 foreach (int y; 0..cm.height) {
101 foreach (int ix; 0..cm.width) {
102 int v = cm.mask[ix, y];
103 foreach (int dx; 0..32) {
105 // missed collision: red
106 Video.color = (v < 0 ? 0x3f_ff_00_00 : 0xcf_ff_00_00);
107 } else if (col == -999) {
108 // superfluous collision: blue
109 Video.color = (v < 0 ? 0x3f_00_00_ff : 0xcf_00_00_ff);
110 } else if (col <= 0) {
111 // no collision: yellow
112 Video.color = (v < 0 ? 0x3f_ff_ff_00 : 0xcf_ff_ff_00);
113 } else if (col > 0) {
115 Video.color = (v < 0 ? 0x3f_00_ff_00 : 0xcf_00_ff_00);
117 Video.fillRect(x0+(ix*32+dx)*scale, y0+y*scale, scale, scale);
126 void sprTestRender () {
127 Video.color = 0xff_ff_ff;
131 auto frm0 = spr[0].frames[frms[0]];
132 auto frm1 = spr[1].frames[frms[1]];
134 frm0.tex.blitAt(10, 10, 2);
135 frm1.tex.blitAt(10, 100, 2);
140 auto cm0 = CollisionMask.Create(frm0, false, dumpCheck);
141 auto cm1 = CollisionMask.Create(frm1, false, dumpCheck);
142 //bool collided = cm1.colCheck(cm0, spr0x/2-x1/2, spr0y/2-y1/2);
143 bool collided = cm0.colCheck(cm1, x1/2-spr0x/2, y1/2-spr0y/2);
148 bool slowCol = frm1.pixelCheck(frm0, spr0x/2-x1/2, spr0y/2-y1/2);
150 drawMask(frm0, spr0x, spr0y, 2, (slowCol == collided ? (collided ? 1 : 0) : (slowCol ? -666 : -999)));
151 drawMask(frm1, x1, y1, 2, -1);
153 Video.color = 0xff_ff_ff;
158 // ////////////////////////////////////////////////////////////////////////// //
159 final void onDraw () {
160 if (Video.frameTime == 0) {
161 Video.requestRefresh();
168 // ////////////////////////////////////////////////////////////////////////// //
172 final void onEvent (ref event_t evt) {
173 if (evt.type == ev_closequery) { Video.requestQuit(); return; }
175 if (evt.type == ev_winfocus) {
176 if (!evt.focused) escCount = 0;
180 if (evt.type == ev_keyup && evt.keycode != K_ESCAPE) escCount = 0;
182 if (evt.type == ev_keyup && evt.keycode == K_ESCAPE) {
183 if (++escCount == 2) Video.requestQuit();
187 if (evt.type == ev_mouse) {
188 //writeln("!!!! x=", evt.x, "; y=", evt.y);
189 spr0x = (evt.x&~1)-16*3;
190 spr0y = (evt.y&~1)-16*3;
194 if (evt.type == ev_keydown && evt.keycode == K_d) { dumpCheck = true; return; }
198 final void runIn () {
199 Video.frameTime = 0; // unlimited FPS
201 sprStore = SpawnObject(SpriteStore);
202 sprStore.bDumpLoaded = false;
204 bgtileStore = SpawnObject(BackTileStore);
205 bgtileStore.bDumpLoaded = false;
209 Video.swapInterval = 1;
210 //Video.openScreen("Spelunky/VaVoom C", GameLevel::TilesWidth*16, GameLevel::TilesHeight*16);
211 Video.openScreen("Spelunky/VaVoom C", 320*3, 240*3);
212 Video.runEventLoop();
217 // ////////////////////////////////////////////////////////////////////////// //
219 appSetName("k8spelunky");