option to spawn ghost on the first level
[k8vacspelynky.git] / pxcdtest1.vc
blob90715179612f468b253de9f67049aab017ccaaf4
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 'Video';
13 import 'Sprites';
14 //import 'Game';
16 #define STANDALONE_MAP_ENTITY
17 #include "packages/Game/0classes.vc"
18 #include "mapent/MapEntity.vc"
19 #include "mapent/MapObject.vc"
22 // ////////////////////////////////////////////////////////////////////////// //
23 class Main : Object;
25 SpriteStore sprStore;
26 BackTileStore bgtileStore;
28 MapObject[2] ent;
30 int spr0x, spr0y;
31 bool dumpCheck;
32 int scale = 6;
35 void sprInit () {
36   //spr[0] = sprStore['sDuckLeft'];
37   //spr[0] = sprStore['sSkull'];
38   //spr[0] = sprStore['sGoldIdol'];
39   //frms[0] = 0;
40   ent[0] = SpawnObject(MapObject);
41   //ent[0].spriteL = sprStore['sDuckLeft'];
42   ent[0].spriteL = sprStore['sExplosionMask'];
43   ent[0].imageFrame = 3;
45   ent[0].spriteL = sprStore['sMegaMouth'];
46   ent[0].imageFrame = 0;
48   ent[0].setXY(60, 60);
49   ent[0].setCollisionBoundsFromFrame();
51   //writeln("(", ent[0].x0, ",", ent[0].x1, "):(", ent[0].width, "x", ent[0].height, ")");
53   ent[1] = SpawnObject(MapObject);
54   //ent[1].spriteL = sprStore['sMagma'];
55   ent[1].spriteL = sprStore['sDuckLeft'];
56   ent[1].setXY(60, 100);
58   //spr[1] = sprStore['sExplosionMask'];
59   //frms[1] = 3;
60   /*
61   spr[1] = sprStore['sDuckLeft'];
62   frms[1] = 0;
63   spr[1] = sprStore['sMagma'];
64   frms[1] = 0;
65   */
69 final void setColorByIdx (bool isset, int col) {
70   if (col == -666) {
71     // missed collision: red
72     Video.color = (isset ? 0x3f_ff_00_00 : 0xcf_ff_00_00);
73   } else if (col == -999) {
74     // superfluous collision: blue
75     Video.color = (isset ? 0x3f_00_00_ff : 0xcf_00_00_ff);
76   } else if (col <= 0) {
77     // no collision: yellow
78     Video.color = (isset ? 0x3f_ff_ff_00 : 0xcf_ff_ff_00);
79   } else if (col > 0) {
80     // collision: green
81     Video.color = (isset ? 0x3f_00_ff_00 : 0xcf_00_ff_00);
82   }
86 final void drawMask (SpriteFrame frm, int sx, int sy, int scale, int x0, int y0, int x1, int y1, int col, bool mirror) {
87   if (!frm) return;
88   CollisionMask cm = CollisionMask.Create(frm, mirror);
89   if (!cm) return;
90   sx += x0*scale;
91   sy += y0*scale;
92   x1 -= x0;
93   y1 -= y0;
94   x0 = 0;
95   y0 = 0;
96   int bx0, by0, bx1, by1;
97   frm.getBBox(out bx0, out by0, out bx1, out by1, mirror);
98   Video.color = 0x7f_00_00_ff;
99   Video.fillRect(sx+bx0*scale, sy+by0*scale, (bx1-bx0+1)*scale, (by1-by0+1)*scale);
100   if (!cm.isEmptyMask) {
101     //writeln(cm.mask.length, "; ", cm.width, "x", cm.height, "; (", cm.x0, ",", cm.y0, ")-(", cm.x1, ",", cm.y1, ")");
102     foreach (int iy; 0..cm.height) {
103       foreach (int ix; 0..cm.width) {
104         int v = cm.mask[ix, iy];
105         foreach (int dx; 0..32) {
106           int xx = ix*32+dx;
107           if (v < 0) {
108             setColorByIdx(v < 0, col);
109             if (xx < x0 || xx > x1 || iy < y0 || iy > y1) Video.color = 0x3f_ff_00_00;
110           } else {
111             Video.color = (xx >= x0 && xx <= x1 && iy >= y0 && iy <= y1 ? 0xaf_00_ff_00 : 0xdf_00_ff_00);
112           }
113           Video.fillRect(sx+xx*scale, sy+iy*scale, scale, scale);
114           v <<= 1;
115         }
116       }
117     }
118   } else {
119     // bounding box
120     foreach (int iy; 0..frm.tex.height) {
121       foreach (int ix; 0..(frm.tex.width+31)/31) {
122         foreach (int dx; 0..32) {
123           int xx = ix*32+dx;
124           //if (xx >= frm.bx && xx < frm.bx+frm.bw && iy >= frm.by && iy < frm.by+frm.bh) {
125           if (xx >= x0 && xx <= x1 && iy >= y0 && iy <= y1) {
126             setColorByIdx(true, col);
127             if (col <= 0) Video.color = 0xaf_ff_ff_00;
128           } else {
129             Video.color = 0xaf_00_ff_00;
130           }
131           Video.fillRect(sx+xx*scale, sy+iy*scale, scale, scale);
132         }
133       }
134     }
135     /*
136     if (frm.bw > 0 && frm.bh > 0) {
137       setColorByIdx(true, col);
138       Video.fillRect(x0+frm.bx*scale, y0+frm.by*scale, frm.bw*scale, frm.bh*scale);
139       Video.color = 0xff_00_00;
140       Video.drawRect(x0+frm.bx*scale, y0+frm.by*scale, frm.bw*scale, frm.bh*scale);
141     }
142     */
143   }
144   delete cm;
148 void renderEnt (MapEntity e, optional MapEntity other) {
149   if (!e) return;
150   Video.color = 0x7f_ff_ff_ff;
151   e.drawWithOfs(0, 0, scale, 0);
152   bool doMirror;
153   int fx0, fy0, fx1, fy1;
154   // right-bottom exclusive
155   auto frm = e.getSpriteFrame(out doMirror, out fx0, out fy0, out fx1, out fy1);
156   if (!frm) return;
157   if (other) {
158     bool col = e.collidesWith(other);
159     drawMask(frm, e.ix*scale, e.iy*scale, scale, fx0, fy0, fx1-1, fy1-1, (col ? 1 : 0), doMirror);
160   } else {
161     //writeln("fx0=", fx0, "; fy0=", fy0, "; fx1=", fx1, "; fy1=", fy1);
162     drawMask(frm, e.ix*scale, e.iy*scale, scale, fx0, fy0, fx1-1, fy1-1, -1, doMirror);
163   }
164   Video.color = 0x00_7f_ff;
165   Video.drawRect(e.x0*scale, e.y0*scale, e.width*scale, e.height*scale);
166   /*
167   Video.color = 0xff_00_ff;
168   Video.drawRect(e.ix*scale, e.iy*scale, 32*scale, 32*scale);
169   */
173 void sprTestRender () {
174   Video.color = 0xff_ff_ff;
175   Video.clearScreen();
177   foreach (MapObject e; ent) e.setCollisionBoundsFromFrame();
179   ent[1].setXY(spr0x/scale-8, spr0y/scale-8);
181   //ent[0].drawWithOfs(0, 0, scale, 0);
182   //ent[1].drawWithOfs(0, 0, scale, 0);
183   renderEnt(ent[0]/*, ent[1]*/);
184   renderEnt(ent[1], ent[0]);
188 // ////////////////////////////////////////////////////////////////////////// //
189 final void onDraw () {
190   if (Video.frameTime == 0) {
191     Video.requestRefresh();
192   }
194   sprTestRender();
198 // ////////////////////////////////////////////////////////////////////////// //
199 int escCount;
202 final void onEvent (ref event_t evt) {
203   //writeln(va("%x", evt.buildModMask), "; ctrl:", evt.bCtrl, "; alt:", evt.bAlt, "; shift:", evt.bShift, "; hyper:", evt.bHyper, "; LMB:", evt.bLMB, "; RMB:", evt.bRMB, "; MMB:", evt.bMMB);
205   if (evt.type == ev_closequery) { Video.requestQuit(); return; }
207   if (evt.type == ev_winfocus) {
208     if (!evt.focused) escCount = 0;
209     return;
210   }
212   if (evt.type == ev_keyup && evt.keycode != K_ESCAPE) escCount = 0;
214   if (evt.type == ev_keyup && evt.keycode == K_ESCAPE) {
215     if (++escCount == 2) Video.requestQuit();
216     return;
217   }
219   if (evt.type == ev_mouse) {
220     //writeln("!!!! x=", evt.x, "; y=", evt.y);
221     spr0x = evt.x;
222     spr0y = evt.y;
223     return;
224   }
226   if (evt.type == ev_keydown && evt.keycode == K_d) { dumpCheck = true; return; }
227   if (evt.type == ev_keydown && evt.keycode == K_f) { ent[0].dir ^= 1; return; }
228   if (evt.type == ev_keydown && evt.keycode == K_v) { ent[1].dir ^= 1; return; }
232 final void runIn () {
233   Video.frameTime = 0; // unlimited FPS
235   sprStore = SpawnObject(SpriteStore);
236   sprStore.bDumpLoaded = false;
238   bgtileStore = SpawnObject(BackTileStore);
239   bgtileStore.bDumpLoaded = false;
241   sprInit();
243   Video.swapInterval = 1;
244   //Video.openScreen("Spelunky/VaVoom C", GameLevel::TilesWidth*16, GameLevel::TilesHeight*16);
245   Video.openScreen("Spelunky/VaVoom C", 320*3, 240*3);
246   Video.runEventLoop();
247   Video.closeScreen();
251 // ////////////////////////////////////////////////////////////////////////// //
252 void main () {
253   appSetName("k8spelunky");
254   runIn();