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 #define STANDALONE_MAP_ENTITY
17 #include "packages/Game/0classes.vc"
18 #include "mapent/MapEntity.vc"
19 #include "mapent/MapObject.vc"
22 // ////////////////////////////////////////////////////////////////////////// //
26 BackTileStore bgtileStore;
36 //spr[0] = sprStore['sDuckLeft'];
37 //spr[0] = sprStore['sSkull'];
38 //spr[0] = sprStore['sGoldIdol'];
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;
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'];
61 spr[1] = sprStore['sDuckLeft'];
63 spr[1] = sprStore['sMagma'];
69 final void setColorByIdx (bool isset, int col) {
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);
81 Video.color = (isset ? 0x3f_00_ff_00 : 0xcf_00_ff_00);
86 final void drawMask (SpriteFrame frm, int sx, int sy, int scale, int x0, int y0, int x1, int y1, int col, bool mirror) {
88 CollisionMask cm = CollisionMask.Create(frm, mirror);
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) {
108 setColorByIdx(v < 0, col);
109 if (xx < x0 || xx > x1 || iy < y0 || iy > y1) Video.color = 0x3f_ff_00_00;
111 Video.color = (xx >= x0 && xx <= x1 && iy >= y0 && iy <= y1 ? 0xaf_00_ff_00 : 0xdf_00_ff_00);
113 Video.fillRect(sx+xx*scale, sy+iy*scale, scale, scale);
120 foreach (int iy; 0..frm.tex.height) {
121 foreach (int ix; 0..(frm.tex.width+31)/31) {
122 foreach (int dx; 0..32) {
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;
129 Video.color = 0xaf_00_ff_00;
131 Video.fillRect(sx+xx*scale, sy+iy*scale, scale, scale);
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);
148 void renderEnt (MapEntity e, optional MapEntity other) {
150 Video.color = 0x7f_ff_ff_ff;
151 e.drawWithOfs(0, 0, scale, 0);
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);
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);
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);
164 Video.color = 0x00_7f_ff;
165 Video.drawRect(e.x0*scale, e.y0*scale, e.width*scale, e.height*scale);
167 Video.color = 0xff_00_ff;
168 Video.drawRect(e.ix*scale, e.iy*scale, 32*scale, 32*scale);
173 void sprTestRender () {
174 Video.color = 0xff_ff_ff;
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();
198 // ////////////////////////////////////////////////////////////////////////// //
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;
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();
219 if (evt.type == ev_mouse) {
220 //writeln("!!!! x=", evt.x, "; y=", evt.y);
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;
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();
251 // ////////////////////////////////////////////////////////////////////////// //
253 appSetName("k8spelunky");