small fixes for API changes
[k8vacspelynky.git] / pxcdtest.vc
blob9b030825ae05e70300d3286aac2d3022b9cd88a7
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.
6  *
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  **************************************************************************/
12 import 'GLVideo';
13 import 'Sprites';
16 // ////////////////////////////////////////////////////////////////////////// //
17 class Main : Object;
19 SpriteStore sprStore;
20 BackTileStore bgtileStore;
22 SpriteImage[2] spr;
23 int[2] frms;
25 int spr0x, spr0y;
26 bool dumpCheck;
29 void sprInit () {
30   //spr[0] = sprStore['sDuckLeft'];
31   //spr[0] = sprStore['sSkull'];
32   //spr[0] = sprStore['sGoldIdol'];
33   //frms[0] = 0;
34   spr[0] = sprStore['sMagmz'];
35   frms[0] = 0;
37   spr[1] = sprStore['sExplosionMask'];
38   frms[1] = 3;
39   /*
40   spr[1] = sprStore['sDuckLeft'];
41   frms[1] = 0;
42   spr[1] = sprStore['sMagma'];
43   frms[1] = 0;
44   */
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;
51   int ewdt = (x1-x0+1);
52   int ehgt = (y1-y0+1);
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
59    *
60    * X^2/a^2 + Y^2/b^2 <= 1
61    */
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);
69 void testEllipse () {
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         GLVideo.fillRect(px, py, 1, 1);
76       }
77     }
78   }
79   GLVideo.color = 0xff_7f_00;
80   GLVideo.drawRect(x0-1, y0-1, x1-x0+3, y1-y0+3);
84 void drawMask (SpriteFrame frm, int x0, int y0, int scale, int col) {
85   if (!frm) return;
86   /*
87   GLVideo.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         GLVideo.color = 0x3f_ff_ff_00;
92       } else {
93         GLVideo.color = 0xcf_ff_ff_00;
94       }
95       GLVideo.fillRect(x0+x*scale, y0+y*scale, scale, scale);
96     }
97   }
98   */
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) {
104         if (col == -666) {
105           // missed collision: red
106           GLVideo.color = (v < 0 ? 0x3f_ff_00_00 : 0xcf_ff_00_00);
107         } else if (col == -999) {
108           // superfluous collision: blue
109           GLVideo.color = (v < 0 ? 0x3f_00_00_ff : 0xcf_00_00_ff);
110         } else if (col <= 0) {
111           // no collision: yellow
112           GLVideo.color = (v < 0 ? 0x3f_ff_ff_00 : 0xcf_ff_ff_00);
113         } else if (col > 0) {
114           // collision: green
115           GLVideo.color = (v < 0 ? 0x3f_00_ff_00 : 0xcf_00_ff_00);
116         }
117         GLVideo.fillRect(x0+(ix*32+dx)*scale, y0+y*scale, scale, scale);
118         v <<= 1;
119       }
120     }
121   }
122   delete cm;
126 void sprTestRender () {
127   GLVideo.color = 0xff_ff_ff;
128   GLVideo.clearScreen();
130   //writeln(!!spr[0]);
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);
137   int x1 = 200;
138   int y1 = 150;
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);
144   delete cm1;
145   delete cm0;
146   dumpCheck = false;
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   GLVideo.color = 0xff_ff_ff;
154   testEllipse();
158 // ////////////////////////////////////////////////////////////////////////// //
159 final void onDraw () {
160   if (GLVideo.frameTime == 0) {
161     GLVideo.requestRefresh();
162   }
164   sprTestRender();
168 // ////////////////////////////////////////////////////////////////////////// //
169 int escCount;
172 final void onEvent (ref event_t evt) {
173   if (evt.type == ev_closequery) { GLVideo.requestQuit(); return; }
175   if (evt.type == ev_winfocus) {
176     if (!evt.focused) escCount = 0;
177     return;
178   }
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) GLVideo.requestQuit();
184     return;
185   }
187   if (evt.type == ev_uimouse) {
188     //writeln("!!!! x=", evt.x, "; y=", evt.y);
189     spr0x = (evt.x&~1)-16*3;
190     spr0y = (evt.y&~1)-16*3;
191     return;
192   }
194   if (evt.type == ev_keydown && evt.keycode == K_d) { dumpCheck = true; return; }
198 final void runIn () {
199   GLVideo.frameTime = 0; // unlimited FPS
201   sprStore = SpawnObject(SpriteStore);
202   sprStore.bDumpLoaded = false;
204   bgtileStore = SpawnObject(BackTileStore);
205   bgtileStore.bDumpLoaded = false;
207   sprInit();
209   GLVideo.swapInterval = 1;
210   //GLVideo.openScreen("Spelunky/VaVoom C", GameLevel::TilesWidth*16, GameLevel::TilesHeight*16);
211   GLVideo.openScreen("Spelunky/VaVoom C", 320*3, 240*3);
212   GLVideo.runEventLoop();
213   GLVideo.closeScreen();
217 // ////////////////////////////////////////////////////////////////////////// //
218 void main () {
219   appSetName("k8spelunky");
220   runIn();