2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (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.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "gameglobals.h"
36 ////////////////////////////////////////////////////////////////////////////////
37 VMRSTCB gameRSTCB
= NULL
;
40 ////////////////////////////////////////////////////////////////////////////////
41 #define VIS_WIDTH (15)
42 #define VIS_HEIGHT (17)
47 ////////////////////////////////////////////////////////////////////////////////
59 int size
; // # of slots
64 #define MAX_LAYER (63)
65 static SpriteLayer spLayers
[MAX_LAYER
];
66 static int spLayersInitialized
= 0;
69 static void clearSpriteLayers (void) {
70 if (!spLayersInitialized
) {
71 for (int f
= 0; f
<= MAX_LAYER
; ++f
) {
73 spLayers
[f
].list
= NULL
;
75 spLayersInitialized
= 1;
77 for (int f
= 0; f
<= MAX_LAYER
; ++f
) spLayers
[f
].count
= 0;
81 static void addSpriteToLayer (int x
, int y
, int layer
, int bank
, int num
, int dir
, int inlevel
) {
82 //fprintf(stderr, "*x=%d, y=%d, layer=%d, bank=%d, num=%d, dir=%d, inlevel=%d\n", x, y, layer, bank, num, dir, inlevel);
83 if (layer
>= 0 && layer
<= MAX_LAYER
&&
84 bank
>= 0 && bank
<= 256 &&
85 num
>= 0 && num
< 256) {
86 if (spLayers
[layer
].count
+1 >= spLayers
[layer
].size
) {
87 int newsz
= spLayers
[layer
].size
+64;
88 SpriteInfo
*n
= realloc(spLayers
[layer
].list
, newsz
);
90 if (n
== NULL
) fatal("out of memory");
91 spLayers
[layer
].list
= n
;
93 spLayers
[layer
].list
[spLayers
[layer
].count
].x
= x
;
94 spLayers
[layer
].list
[spLayers
[layer
].count
].y
= y
;
95 spLayers
[layer
].list
[spLayers
[layer
].count
].bank
= bank
;
96 spLayers
[layer
].list
[spLayers
[layer
].count
].num
= num
;
97 spLayers
[layer
].list
[spLayers
[layer
].count
].dir
= dir
;
98 spLayers
[layer
].list
[spLayers
[layer
].count
].inlevel
= inlevel
;
99 ++(spLayers
[layer
].count
);
104 ////////////////////////////////////////////////////////////////////////////////
105 static int redrawLevel
;
106 static int oldScrX
, oldScrY
;
108 static int mapHeight
;
110 static char levelname
[257];
111 static char levelcode
[257];
112 static char itemname
[257];
114 static Uint8
*levelData
= NULL
;
115 static int levelDataSize
= 0;
116 static Uint8
*bmap
= NULL
, *fmap
= NULL
;
117 static Uint8
*xflags
= NULL
;
118 static int inMinimap
;
120 static int doSave
= 0;
122 static int demorecmode
= 0; // 0: none; 1: recording; -1: playing
123 static int demoSize
= 0;
124 static int demoPos
= 0;
125 static Uint8
*demoData
= NULL
;
126 static Uint8 demoPrevKeyState
= 0;
127 static int demoKeyStateRepeats
= 0;
129 static char message
[256];
130 //static Uint32 msgEndTime = 0;
132 static Uint32 demo_m_w
= 0;
133 static Uint32 demo_m_z
= 0;
136 ////////////////////////////////////////////////////////////////////////////////
137 static int gamekeys
[12];
138 static int fkeys
[10];
141 static void setGameKeysGVars (void) {
142 vmGVars
[GVAR_KEY_LEFT
] = gamekeys
[0] ? 1 : 0;
143 vmGVars
[GVAR_KEY_RIGHT
] = gamekeys
[1] ? 1 : 0;
144 vmGVars
[GVAR_KEY_UP
] = gamekeys
[2] ? 1 : 0;
145 vmGVars
[GVAR_KEY_DOWN
] = gamekeys
[3] ? 1 : 0;
146 vmGVars
[GVAR_KEY_TAKE
] = gamekeys
[4] ? 1 : 0;
147 vmGVars
[GVAR_KEY_USE
] = gamekeys
[5] ? 1 : 0;
149 vmGVars
[GVAR_KEY_MINIMAP
] = gamekeys
[6] ? 1 : 0;
150 vmGVars
[GVAR_KEY_RESTART
] = gamekeys
[7] ? 1 : 0;
152 vmGVars
[GVAR_KEY_FALL_CHEAT
] = gamekeys
[8] ? 1 : 0;
153 vmGVars
[GVAR_KEY_WALK_CHEAT
] = gamekeys
[9] ? 1 : 0;
154 vmGVars
[GVAR_KEY_PLEV_CHEAT
] = gamekeys
[10] ? 1 : 0;
155 vmGVars
[GVAR_KEY_NLEV_CHEAT
] = gamekeys
[11] ? 1 : 0;
159 ////////////////////////////////////////////////////////////////////////////////
164 static int readBuf (FILE *fl
, void *buf
, int len
) {
165 unsigned char *c
= (unsigned char *)buf
;
170 if (fread(&b
, 1, 1, fl
) != 1) return -1;
178 static int writeBuf (FILE *fl
, const void *buf
, int len
) {
179 const unsigned char *c
= (const unsigned char *)buf
;
182 unsigned char b
= *c
++;
185 if (fwrite(&b
, 1, 1, fl
) != 1) return -1;
191 static int readDW (FILE *fl
, int *v
) {
194 for (int f
= 0; f
< 4; ++f
) {
197 if (fread(&b
, 1, 1, fl
) != 1) return -1;
203 for (int f
= 0; f
< 4; ++f
) *v
|= t
[f
]<<(8*f
);
209 static int writeDW (FILE *fl
, int v
) {
210 for (int f
= 0; f
< 4; ++f
) {
215 if (fwrite(&b
, 1, 1, fl
) != 1) return -1;
222 static int readUDW (FILE *fl
, Uint32
*v
) {
225 for (int f
= 0; f
< 4; ++f
) {
228 if (fread(&b
, 1, 1, fl
) != 1) return -1;
234 for (int f
= 0; f
< 4; ++f
) *v
|= t
[f
]<<(8*f
);
240 static int writeUDW (FILE *fl
, Uint32 v
) {
241 for (int f
= 0; f
< 4; ++f
) {
246 if (fwrite(&b
, 1, 1, fl
) != 1) return -1;
253 ////////////////////////////////////////////////////////////////////////////////
254 static const char *SAVE_GAME_SIGNATURE
= "ASG1";
257 static int saveGame (void) {
258 FILE *fl
= fopen("awish.sav", "wb");
261 demo_m_w
= getSeedL();
262 demo_m_z
= getSeedH();
263 if (fwrite(SAVE_GAME_SIGNATURE
, 4, 1, fl
) != 1) goto error
;
264 if (vmSaveState(fl
) != 0) goto error
;
265 if (writeDW(fl
, mapWidth
) != 0) goto error
;
266 if (writeDW(fl
, mapHeight
) != 0) goto error
;
267 if (writeUDW(fl
, demo_m_w
) != 0) goto error
;
268 if (writeUDW(fl
, demo_m_z
) != 0) goto error
;
269 if (writeDW(fl
, inMinimap
) != 0) goto error
;
270 if (writeDW(fl
, curLevel
) != 0) goto error
;
271 if (writeBuf(fl
, levelname
, sizeof(levelname
)) != 0) goto error
;
272 if (writeDW(fl
, lnamex
) != 0) goto error
;
273 if (writeBuf(fl
, levelcode
, sizeof(levelcode
)) != 0) goto error
;
274 if (writeBuf(fl
, itemname
, sizeof(itemname
)) != 0) goto error
;
275 if (writeBuf(fl
, bmap
, mapWidth
*mapHeight
) != 0) goto error
;
276 if (writeBuf(fl
, fmap
, mapWidth
*mapHeight
) != 0) goto error
;
277 if (writeBuf(fl
, xflags
, mapWidth
) != 0) goto error
;
284 if (goobers
) fprintf(stderr
, "error saving game\n");
289 static int loadGame (void) {
290 FILE *fl
= fopen("awish.sav", "rb");
295 if (fread(sign
, 4, 1, fl
) != 1) goto error
;
296 if (memcmp(sign
, SAVE_GAME_SIGNATURE
, 4) != 0) goto error
;
297 if (vmLoadState(fl
) != 0) goto error
;
298 if (readDW(fl
, &mapWidth
) != 0) goto error
;
299 if (readDW(fl
, &mapHeight
) != 0) goto error
;
300 if (readUDW(fl
, &demo_m_w
) != 0) goto error
;
301 if (readUDW(fl
, &demo_m_z
) != 0) goto error
;
302 if (readDW(fl
, &inMinimap
) != 0) goto error
;
303 if (readDW(fl
, &curLevel
) != 0) goto error
;
304 if (readBuf(fl
, levelname
, sizeof(levelname
)) != 0) goto error
;
305 if (readDW(fl
, &lnamex
) != 0) goto error
;
306 if (readBuf(fl
, levelcode
, sizeof(levelcode
)) != 0) goto error
;
307 if (readBuf(fl
, itemname
, sizeof(itemname
)) != 0) goto error
;
308 if (bmap
!= NULL
) free(bmap
); bmap
= NULL
;
309 if (fmap
!= NULL
) free(fmap
); fmap
= NULL
;
310 if (xflags
!= NULL
) free(xflags
); xflags
= NULL
;
311 fmap
= calloc(mapWidth
*mapHeight
, 1); if (fmap
== NULL
) fatal("out of memory in loadGame");
312 bmap
= calloc(mapWidth
*mapHeight
, 1); if (bmap
== NULL
) fatal("out of memory in loadGame");
313 xflags
= calloc(mapWidth
, 1); if (xflags
== NULL
) fatal("out of memory in loadGame");
314 if (readBuf(fl
, bmap
, mapWidth
*mapHeight
) != 0) goto error
;
315 if (readBuf(fl
, fmap
, mapWidth
*mapHeight
) != 0) goto error
;
316 if (readBuf(fl
, xflags
, mapWidth
) != 0) goto error
;
321 oldScrX
= oldScrY
= -1;
326 if (goobers
) fprintf(stderr
, "error loading saved game\n");
331 ////////////////////////////////////////////////////////////////////////////////
332 static void demoClear (void) {
336 demoPrevKeyState
= 0;
337 demoKeyStateRepeats
= 0;
338 if (demoData
!= NULL
) free(demoData
);
343 static void demoAddByte (Uint8 b
) {
344 if (demoPos
+1 > demoSize
&& demoSize
> 1024*1024*16) fatal("out of memory in demo recording!");
345 if (demoPos
+1 > demoSize
) {
346 int newsz
= demoSize
+1024*32;
347 Uint8
*nn
= realloc(demoData
, newsz
);
349 if (!nn
) fatal("out of memory in demo recording!");
353 demoData
[demoPos
++] = b
;
357 static Uint8
demoGetKeyState (void) {
359 ((gamekeys
[0]?1:0)<<0) |
360 ((gamekeys
[1]?1:0)<<1) |
361 ((gamekeys
[2]?1:0)<<2) |
362 ((gamekeys
[3]?1:0)<<3) |
363 ((gamekeys
[4]?1:0)<<4) |
364 ((gamekeys
[5]?1:0)<<5);
368 static void demoSetKeyState (Uint8 kstate
) {
369 gamekeys
[0] = (kstate
&(1<<0)) != 0;
370 gamekeys
[1] = (kstate
&(1<<1)) != 0;
371 gamekeys
[2] = (kstate
&(1<<2)) != 0;
372 gamekeys
[3] = (kstate
&(1<<3)) != 0;
373 gamekeys
[4] = (kstate
&(1<<4)) != 0;
374 gamekeys
[5] = (kstate
&(1<<5)) != 0;
378 static void demoAddFrameData (void) {
379 Uint8 kstate
= demoGetKeyState();
381 if (demoKeyStateRepeats
== 256) {
382 demoAddByte(demoKeyStateRepeats
-1);
383 demoAddByte(demoPrevKeyState
);
384 demoKeyStateRepeats
= 0;
387 if (kstate
!= demoPrevKeyState
) {
388 if (demoKeyStateRepeats
> 0) {
389 demoAddByte(demoKeyStateRepeats
-1);
390 demoAddByte(demoPrevKeyState
);
392 demoPrevKeyState
= kstate
;
393 demoKeyStateRepeats
= 1;
395 ++demoKeyStateRepeats
;
400 static void demoGetFrameData (void) {
401 while (demoKeyStateRepeats
< 1) {
402 if (demoPos
+2 > demoSize
) {
405 if (goobers
) fprintf(stderr
, "demo complete\n");
406 strcpy(message
, "demo stopped");
409 demoKeyStateRepeats
= demoData
[demoPos
++];
410 ++demoKeyStateRepeats
;
411 demoPrevKeyState
= demoData
[demoPos
++];
413 --demoKeyStateRepeats
;
415 demoSetKeyState(demoPrevKeyState
);
419 static int demoSave (void) {
424 if (demoKeyStateRepeats
> 0) {
425 demoAddByte(demoKeyStateRepeats
-1);
426 demoAddByte(demoPrevKeyState
);
429 sprintf(buf
, "awish%02d.dmo", curLevel
+1);
430 fl
= fopen(buf
, "wb");
432 if (goobers
) fprintf(stderr
, "can't create demo file '%s'\n", buf
);
435 strcpy(sign
, "AWD1");
436 if (fwrite(sign
, 4, 1, fl
) != 1) goto error
;
437 if (writeDW(fl
, curLevel
) != 0) goto error
;
438 if (writeUDW(fl
, demo_m_w
) != 0) goto error
;
439 if (writeUDW(fl
, demo_m_z
) != 0) goto error
;
440 if (writeDW(fl
, demoPos
) != 0) goto error
;
441 if (writeBuf(fl
, demoData
, demoPos
) != 0) goto error
;
443 if (goobers
) fprintf(stderr
, "demo saved to file '%s'\n", buf
);
448 if (goobers
) fprintf(stderr
, "can't write demo file '%s'\n", buf
);
453 static int demoLoad (void) {
460 sprintf(buf
, "awish%02d.dmo", curLevel
+1);
461 fl
= fopen(buf
, "rb");
463 if (goobers
) fprintf(stderr
, "can't open demo file '%s'\n", buf
);
467 if (fread(sign
, 4, 1, fl
) != 1) goto error
;
468 if (memcmp(sign
, "AWD1", 4) != 0) goto error
;
469 if (readDW(fl
, &level
) != 0) goto error
;
470 if (readUDW(fl
, &demo_m_w
) != 0) goto error
;
471 if (readUDW(fl
, &demo_m_z
) != 0) goto error
;
472 if (readDW(fl
, &size
) != 0) goto error
;
473 if (size
< 1 || size
> 1024*1024*16) goto error
;
474 demoData
= malloc(size
);
475 if (demoData
== NULL
) goto error
;
476 if (readBuf(fl
, demoData
, size
) != 0) goto error
;
482 if (goobers
) fprintf(stderr
, "loaded demo file '%s'\n", buf
);
487 if (goobers
) fprintf(stderr
, "can't load demo file '%s'\n", buf
);
493 static inline int isGameStopped (void) {
495 vmGVars
[GVAR_GAME_STATE
] == CONST_GAME_STATE_DEAD
||
496 vmGVars
[GVAR_GAME_STATE
] == CONST_GAME_STATE_COMPLETE
;
500 static void demoCB (void) {
501 //if (vmGVars[GVAR_GAME_STATE] == CONST_GAME_STATE_STARTED) unloadMapScript();
503 if (vmGVars
[GVAR_SCR_X
] != oldScrX
|| vmGVars
[GVAR_SCR_Y
] != oldScrY
) {
504 oldScrX
= vmGVars
[GVAR_SCR_X
];
505 oldScrY
= vmGVars
[GVAR_SCR_Y
];
509 switch (demorecmode
) {
510 case -666: // prepare to load demo
511 if (demoLoad() != 0) {
517 case 666: // prepare to save demo
518 vmSetPC(0, CODE_ENTRY_GAME_RESTART_LEVEL
);
519 vmGVars
[GVAR_CUR_LEVEL
] = curLevel
;
520 vmGVars
[GVAR_GAME_STATE
] = -1; // invalid state
521 if (demorecmode
> 0) {
526 case -1: // demo replaying
527 case 1: // demo saving
528 if (isGameStopped()) {
529 // the level is over or prof is dead
530 if (demorecmode
> 0) demoSave();
534 ((demorecmode
< 0) ? demoGetFrameData
: demoAddFrameData
)();
537 case -2: // waiting for 'game started' trigger
538 case 2: // waiting for 'game started' trigger
539 if (vmGVars
[GVAR_GAME_STATE
] >= 0) {
540 if (goobers
) fprintf(stderr
, "demo %s started...\n", demorecmode
<0?"replaying":"recording");
541 if (demorecmode
< 0) {
547 demo_m_w
= getSeedL();
548 demo_m_z
= getSeedH();
550 demorecmode
= (demorecmode
< 0) ? -1 : 1;
558 ////////////////////////////////////////////////////////////////////////////////
559 static void frmGameKey (SDL_KeyboardEvent
*key
) {
560 if (key
->type
== SDL_KEYDOWN
) {
561 switch (key
->keysym
.sym
) {
565 if (vmPaused
&& inMinimap
) {
574 vmGVars
[GVAR_KEY_QUIT
] = 1;
591 if (demorecmode
!= 0) { demoClear(); demorecmode
= 0; }
592 if ((key
->keysym
.mod
&(KMOD_CTRL
)) != 0) {
598 if (vmPaused
== 0 && !demorecmode
) {
599 if (goobers
&& (key
->keysym
.mod
&(KMOD_CTRL
)) != 0) { doSave
= 1; vmPaused
= 1; }
603 if (vmPaused
== 0 && !demorecmode
) {
604 if (goobers
&& (key
->keysym
.mod
&(KMOD_CTRL
)) != 0) { doSave
= -1; vmPaused
= 1; }
609 if (goobers
&& (key
->keysym
.mod
&(KMOD_CTRL
)) != 0) {
611 demorecmode
= 666; // 'start saving'
622 if (goobers
&& (key
->keysym
.mod
&(KMOD_CTRL
)) != 0) {
624 demorecmode
= -666; // 'start playing'
637 if (demorecmode
== 0 || demorecmode
== 1) {
638 switch (key
->keysym
.sym
) {
639 case SDLK_LEFT
: case SDLK_KP4
: gamekeys
[0] = (key
->type
== SDL_KEYDOWN
); break;
640 case SDLK_RIGHT
: case SDLK_KP6
: gamekeys
[1] = (key
->type
== SDL_KEYDOWN
); break;
641 case SDLK_UP
: case SDLK_KP8
: gamekeys
[2] = (key
->type
== SDL_KEYDOWN
); break;
642 case SDLK_DOWN
: case SDLK_KP2
: gamekeys
[3] = (key
->type
== SDL_KEYDOWN
); break;
643 case SDLK_SPACE
: case SDLK_KP0
: gamekeys
[4] = (key
->type
== SDL_KEYDOWN
); break;
644 case SDLK_RETURN
: case SDLK_KP_PERIOD
: gamekeys
[5] = (key
->type
== SDL_KEYDOWN
); break;
648 if (goobers
&& !demorecmode
) {
649 switch (key
->keysym
.sym
) {
650 case SDLK_f
: gamekeys
[8] = (key
->type
== SDL_KEYDOWN
); break;
651 case SDLK_w
: gamekeys
[9] = (key
->type
== SDL_KEYDOWN
); break;
652 case SDLK_KP_MINUS
: gamekeys
[10] = (key
->type
== SDL_KEYDOWN
); break;
653 case SDLK_KP_PLUS
: gamekeys
[11] = (key
->type
== SDL_KEYDOWN
); break;
655 case SDLK_F1
: fkeys
[1] = (key
->type
== SDL_KEYDOWN
); break;
656 case SDLK_F2
: fkeys
[2] = (key
->type
== SDL_KEYDOWN
); break;
657 case SDLK_F3
: fkeys
[3] = (key
->type
== SDL_KEYDOWN
); break;
658 case SDLK_F4
: fkeys
[4] = (key
->type
== SDL_KEYDOWN
); break;
659 case SDLK_F5
: fkeys
[5] = (key
->type
== SDL_KEYDOWN
); break;
660 case SDLK_F6
: fkeys
[6] = (key
->type
== SDL_KEYDOWN
); break;
661 case SDLK_F7
: fkeys
[7] = (key
->type
== SDL_KEYDOWN
); break;
662 case SDLK_F8
: fkeys
[8] = (key
->type
== SDL_KEYDOWN
); break;
663 case SDLK_F9
: fkeys
[9] = (key
->type
== SDL_KEYDOWN
); break;
671 static void frmMouse (int x
, int y
, int buttons
) {
672 vmGVars
[GVAR_MOUSE_X
] = x
;
673 vmGVars
[GVAR_MOUSE_Y
] = y
;
674 vmGVars
[GVAR_MOUSE_BUTTONS
] = buttons
;
678 ////////////////////////////////////////////////////////////////////////////////
679 static inline Uint8
fgTile (int x
, int y
) {
680 return (x
>= 0 && y
>= 0 && x
< mapWidth
&& y
< mapHeight
) ? fmap
[y
*mapWidth
+x
] : 0;
684 static inline Uint8
bgTile (int x
, int y
) {
685 if (y
== -666) return (x
>= 0 && x
< mapWidth
) ? xflags
[x
] : 0;
686 return (x
>= 0 && y
>= 0 && x
< mapWidth
&& y
< mapHeight
) ? bmap
[y
*mapWidth
+x
] : 0;
690 static inline void setFGTile (int x
, int y
, Uint8 tile
) {
691 if (x
>= 0 && y
>= 0 && x
< mapWidth
&& y
< mapHeight
) {
692 if (fmap
[y
*mapWidth
+x
] != tile
) {
694 fmap
[y
*mapWidth
+x
] = tile
;
700 static inline void setBGTile (int x
, int y
, Uint8 tile
) {
701 if (y
== -666 && x
>= 0 && x
< mapWidth
) xflags
[x
] = tile
;
702 if (x
>= 0 && y
>= 0 && x
< mapWidth
&& y
< mapHeight
) {
703 if (bmap
[y
*mapWidth
+x
] != tile
) {
705 bmap
[y
*mapWidth
+x
] = tile
;
711 static int mapGet (int tid
, int fg
, int x
, int y
) {
712 if (fmap
!= NULL
) return fg
? fgTile(x
, y
) : bgTile(x
, y
);
717 static void mapSet (int tid
, int fg
, int x
, int y
, int tile
) {
719 if (fg
) setFGTile(x
, y
, tile
); else setBGTile(x
, y
, tile
);
724 ////////////////////////////////////////////////////////////////////////////////
725 // cliprect should be set
726 static void levelDrawMap (SDL_Surface
*frame
) {
731 rc
.w
= VIS_WIDTH
*20*2;
732 rc
.h
= VIS_HEIGHT
*10*2;
735 int levelback
= vmGVars
[GVAR_LEVEL_BACKPIC
];
736 int scrX
= vmGVars
[GVAR_SCR_X
], scrY
= vmGVars
[GVAR_SCR_Y
];
738 if (levelback
< 1 || levelback
> 7) levelback
= 1;
739 blitSurface(frame
, 0, 0, backs
[levelback
]);
741 SDL_SetClipRect(frame
, &rc
);
742 for (int dy
= 0; dy
< VIS_HEIGHT
; ++dy
) {
743 for (int dx
= 0; dx
< VIS_WIDTH
; ++dx
) {
744 int x
= scrX
+dx
, y
= scrY
+dy
;
745 Uint8 b
= bgTile(x
, y
), f
= fgTile(x
, y
);
747 if (b
) blitSurface2x(frame
, VIS_X
+dx
*20, VIS_Y
+dy
*10, banks
[CONST_BANK_BG_TILES
].spr
[b
-1][0]);
748 if (f
) blitSurface2x(frame
, VIS_X
+dx
*20, VIS_Y
+dy
*10, banks
[CONST_BANK_FG_TILES
].spr
[f
-1][0]);
752 blitSurface(frame
, 0, 0, backs
[1]);
753 SDL_SetClipRect(frame
, &rc
);
754 for (int dy
= 0; dy
< mapHeight
; ++dy
) {
755 for (int dx
= 1; dx
< mapWidth
; ++dx
) {
756 Uint8 b
= bgTile(dx
, dy
), f
= fgTile(dx
, dy
), t
= 8;
759 if (b
>= 1 && b
<= 8) t
= b
-1; else t
= 8;
763 if (banks
[CONST_BANK_MAP_TILES
].spr
[t
][0]) {
764 blitSurface2x(frame
, VIS_X
+dx
*6, VIS_Y
+dy
*4, banks
[CONST_BANK_MAP_TILES
].spr
[t
][0]);
766 blitSurface2x(frame
, VIS_X
+dx
*6, VIS_Y
+dy
*4, banks
[CONST_BANK_MAP_TILES
].spr
[0][0]);
771 SDL_SetClipRect(frame
, NULL
);
776 static void levelDrawSprites (SDL_Surface
*frame
) {
778 int scrX
= vmGVars
[GVAR_SCR_X
], scrY
= vmGVars
[GVAR_SCR_Y
];
779 int py
= vmGetTVar(0, TVAR_POS_Y
)-scrY
;
781 for (int cc
= 0; cc
<= 2; ++cc
) {
782 for (int f
= cc
==1?1:0; f
<= vmLastThread(); ++f
) {
783 if (vmIsThreadAlive(f
) && !vmIsSuspendedThread(f
)) {
784 int b
= vmGetTVar(f
, TVAR_SPR_BANK
);
785 int s
= vmGetTVar(f
, TVAR_SPR_NUM
);
786 int d
= vmGetTVar(f
, TVAR_SPR_DIR
);
788 if (d
>= 0 && d
<= 1 && s
>= 0 && b
>= 0 && b
<= 255 && s
< banks
[b
].count
&& banks
[b
].spr
[s
][d
]) {
789 SDL_Surface
*sf
= banks
[b
].spr
[s
][d
];
790 int x
= vmGetTVar(f
, TVAR_POS_X
)-scrX
;
791 int y
= vmGetTVar(f
, TVAR_POS_Y
)-scrY
;
792 int tx
= vmGetTVar(f
, TVAR_POS_TX
);
793 int ty
= vmGetTVar(f
, TVAR_POS_TY
);
794 int si
= vmGetTVar(f
, TVAR_SPR_ITEM
);
796 if (cc
== 0 && b
== CONST_BANK_ITEMS
) continue;
797 if (cc
== 1 && b
!= CONST_BANK_ITEMS
) continue;
799 if (b
!= CONST_BANK_PROF
) {
800 if (b
!= CONST_BANK_ITEMS
) continue;
801 if (y
< py
) continue;
804 if (b
== CONST_BANK_IM_PROF
|| b
== CONST_BANK_PROF
) tx
-= 5;
805 blitSurface2x(frame
, VIS_X
+x
*20+tx
, VIS_Y
+y
*10+ty
-sf
->h
/2, sf
);
806 if (si
> 0 && si
< banks
[CONST_BANK_ITEMS
].count
) {
807 sf
= banks
[CONST_BANK_ITEMS
].spr
[si
][0];
808 blitSurface2x(frame
, VIS_X
+x
*20+tx
, VIS_Y
+y
*10+ty
-sf
->h
/2-24, sf
);
815 blitSurface2x(frame
, VIS_X
+(vmGetTVar(0, TVAR_POS_X
)+0)*6, VIS_Y
+(vmGetTVar(0, TVAR_POS_Y
)-4)*4, banks
[CONST_BANK_MAP_ITEMS
].spr
[0][0]);
816 for (int f
= 1; f
< VM_MAX_THREADS
; ++f
) {
817 if (vmIsThreadAlive(f
) && !vmIsSuspendedThread(f
)) {
818 int i
= vmGetTVar(f
, TVAR_ITEM_ID
);
819 if (i
> 0 && i
<= 255) {
820 SDL_Surface
*sf
= banks
[CONST_BANK_MAP_ITEMS
].spr
[i
][0];
821 int x
= vmGetTVar(f
, TVAR_POS_X
);
822 int y
= vmGetTVar(f
, TVAR_POS_Y
);
824 blitSurface2x(frame
, VIS_X
+(x
+0)*6, VIS_Y
+(y
-2)*4, sf
);
832 static void levelDrawSpriteLayers (SDL_Surface
*frame
) {
837 rc
.w
= VIS_WIDTH
*20*2;
838 rc
.h
= VIS_HEIGHT
*10*2;
839 SDL_SetClipRect(frame
, &rc
);
840 for (int f
= MAX_LAYER
; f
>= 0; --f
) {
841 SpriteInfo
*list
= spLayers
[f
].list
;
843 if (list
== NULL
&& spLayers
[f
].count
!= 0) {
844 fatal("WTF? f=%d; count=%d", f
, spLayers
[f
].count
);
846 for (int c
= spLayers
[f
].count
; c
> 0; --c
, ++list
) {
848 list
->dir
>= 0 && list
->dir
<= 1 &&
849 list
->bank
>= 0 && list
->bank
<= 256 &&
850 list
->num
>= 0 && list
->num
< banks
[list
->bank
].count
&&
851 banks
[list
->bank
].spr
[list
->num
][list
->dir
]) {
852 blitSurface2x(frame
, VIS_X
+list
->x
, VIS_Y
+list
->y
, banks
[list
->bank
].spr
[list
->num
][list
->dir
]);
857 SDL_SetClipRect(frame
, NULL
);
858 for (int f
= MAX_LAYER
; f
>= 0; --f
) {
859 SpriteInfo
*list
= spLayers
[f
].list
;
861 if (list
== NULL
) continue;
862 for (int c
= spLayers
[f
].count
; c
> 0; --c
, ++list
) {
863 //fprintf(stderr, ":x=%d, y=%d, layer=%d, bank=%d, num=%d, dir=%d, inlevel=%d\n", list->x, list->y, f, list->bank, list->num, list->dir, list->inlevel);
864 if (!list
->inlevel
&&
865 list
->dir
>= 0 && list
->dir
<= 1 &&
866 list
->bank
>= 0 && list
->bank
<= 256 &&
867 list
->num
>= 0 && list
->num
< banks
[list
->bank
].count
&&
868 banks
[list
->bank
].spr
[list
->num
][list
->dir
]) {
869 blitSurface2x(frame
, list
->x
, list
->y
, banks
[list
->bank
].spr
[list
->num
][list
->dir
]);
876 static void levelDrawName (SDL_Surface
*frame
) {
877 drawString(frame
, levelname
, lnamex
, 0, 0x76);
881 static void levelDrawNumber (SDL_Surface
*frame
) {
884 sprintf(buf
, "%d", curLevel
+1);
885 drawString(frame
, buf
, 320-strlen(buf
)*8, 0, 1);
889 static void levelDrawCode (SDL_Surface
*frame
) {
892 sprintf(buf
, "%d", curLevel
+1);
893 drawString(frame
, levelcode
, 320-strlen(levelcode
)*8-strlen(buf
)*8, 0, 3);
897 static void levelDrawItemName (SDL_Surface
*frame
) {
898 drawString(frame
, itemname
, 0, 0, 1);
902 static void levelDrawMisc (SDL_Surface
*frame
) {
903 if (demorecmode
< 0) {
904 if (SDL_GetTicks()%1000 < 500) drawChar(frame
, 'R', 0, 8, 3);
905 } else if (demorecmode
> 0) {
906 if (SDL_GetTicks()%1000 < 500) drawChar(frame
, 'D', 0, 8, 3);
911 static void drawSpriteBank (SDL_Surface
*frame
, SpriteBank
*bank
) {
913 int x
= 0, y
= 0, maxh
= 0;
915 SDL_SetClipRect(frame
, NULL
);
920 SDL_FillRect(frame
, &dst
, palette
[3]);
922 for (int num
= 0; num
< bank
->count
; ++num
) {
923 SDL_Surface
*s
= bank
->spr
[num
][0];
929 if (gamekeys
[4] || gamekeys
[5]) {
931 sprintf(buf
, "%d", num
);
932 if (w
< strlen(buf
)*8+2) w
= strlen(buf
)*8+2;
939 if (maxh
< s
->h
/2+1) maxh
= s
->h
/2+1;
940 blitSurface2x(frame
, x
, y
, s
);
941 if (gamekeys
[4] || gamekeys
[5]) drawString(frame
, buf
, x
, y
, 1);
948 static void drawPalette (SDL_Surface
*frame
) {
951 SDL_SetClipRect(frame
, NULL
);
956 SDL_FillRect(frame
, &dst
, palette
[0]);
958 for (int y
= 0; y
< 16; ++y
) {
959 for (int x
= 0; x
< 16; ++x
) {
964 SDL_FillRect(frame
, &dst
, palette
[y
*16+x
]);
965 if (gamekeys
[4] || gamekeys
[5]) {
968 sprintf(buf
, "%d", y
*16+x
);
969 drawString(frame
, buf
, x
*20, y
*20, 1);
976 static void frmGameDraw (SDL_Surface
*frame
) {
979 if (vmPaused
&& doSave
) {
981 if (loadGame() != 0) fatal("can't load game, VM is inconsistent, dying.");
987 vmPaused
= inMinimap
;
990 SDL_SetClipRect(frame
, NULL
);
994 levelDrawMap(backbuf
);
995 levelDrawName(backbuf
);
996 levelDrawNumber(backbuf
);
997 levelDrawCode(backbuf
);
998 levelDrawItemName(backbuf
);
1000 blitSurface(frame
, 0, 0, backbuf
);
1001 levelDrawMisc(frame
);
1005 rc
.w
= VIS_WIDTH
*20*2;
1006 rc
.h
= VIS_HEIGHT
*10*2;
1007 SDL_SetClipRect(frame
, &rc
);
1008 levelDrawSprites(frame
);
1009 levelDrawSpriteLayers(frame
);
1010 SDL_SetClipRect(frame
, NULL
);
1016 SDL_FillRect(frame
, &rc
, palette
[0]);
1019 rc
.w
= VIS_WIDTH
*20*2;
1020 rc
.h
= VIS_HEIGHT
*10*2;
1021 SDL_SetClipRect(frame
, &rc
);
1022 levelDrawSpriteLayers(frame
);
1023 SDL_SetClipRect(frame
, NULL
);
1025 clearSpriteLayers();
1027 polymodStr(frame
, "TEST", 50, 50, POLYFIX_BASE
, 0, 1, 128);
1029 static int angle
= 0;
1030 static int mult
= 1;
1031 static int multdir
= 1;
1034 angle
= (angle
+1)%360;
1036 if (mult
< 2 || mult
> 50) multdir
= -multdir
;
1037 //fprintf(stderr, "a=%d\n", angle);
1039 polyDump
= fkeys
[8];
1041 polymodStart(320/2, 200/2, (mult
+20)*POLYFIX_BASE
/50, angle
);
1044 polymodAddPoint(-20, -20);
1045 polymodAddPoint(20, -20);
1046 polymodAddPoint(20, 20);
1047 polymodAddPoint(-20, 20);
1050 polymodAddPoint(-10, -10);
1051 polymodAddPoint(20, -10);
1052 polymodAddPoint(-10, 20);
1053 polymodAddPoint(20, 20);
1056 polymodAddPoint(36, 0);
1057 polymodAddPoint(46, 12);
1058 polymodAddPoint(31, 17);
1059 polymodAddPoint(33, 33);
1060 polymodAddPoint(18, 31);
1061 polymodAddPoint(12, 46);
1062 polymodAddPoint(0, 36);
1063 polymodAddPoint(-12, 46);
1064 polymodAddPoint(-17, 31);
1065 polymodAddPoint(-33, 33);
1066 polymodAddPoint(-31, 17);
1067 polymodAddPoint(-46, 12);
1068 polymodAddPoint(-36, 0);
1069 polymodAddPoint(-46, -12);
1070 polymodAddPoint(-31, -18);
1071 polymodAddPoint(-33, -33);
1072 polymodAddPoint(-18, -31);
1073 polymodAddPoint(-12, -46);
1074 polymodAddPoint(0, -36);
1075 polymodAddPoint(12, -46);
1076 polymodAddPoint(18, -31);
1077 polymodAddPoint(33, -33);
1078 polymodAddPoint(31, -18);
1079 polymodAddPoint(46, -12);
1082 polymodAddPoint(42, 0);
1083 polymodAddPoint(40, 10);
1084 polymodAddPoint(36, 20);
1085 polymodAddPoint(29, 29);
1086 polymodAddPoint(21, 36);
1087 polymodAddPoint(10, 40);
1088 polymodAddPoint(0, 42);
1089 polymodAddPoint(-10, 40);
1090 polymodAddPoint(-20, 36);
1091 polymodAddPoint(-29, 29);
1092 polymodAddPoint(-36, 20);
1093 polymodAddPoint(-40, 10);
1094 polymodAddPoint(-42, 0);
1095 polymodAddPoint(-40, -10);
1096 polymodAddPoint(-36, -21);
1097 polymodAddPoint(-29, -29);
1098 polymodAddPoint(-21, -36);
1099 polymodAddPoint(-10, -40);
1100 polymodAddPoint(0, -42);
1101 polymodAddPoint(10, -40);
1102 polymodAddPoint(21, -36);
1103 polymodAddPoint(29, -29);
1104 polymodAddPoint(36, -21);
1105 polymodAddPoint(40, -10);
1109 polymodFill(frame
, 3, 100);
1113 for (int f
= 84; f
<= 90; ++f
) if (fkeys
[f
-83]) drawSpriteBank(frame
, &banks
[f
]);
1114 if (fkeys
[8]) drawPalette(frame
);
1116 if (vmGVars
[GVAR_MOUSE_HIDDEN
] == 0) {
1117 int cur
= vmGVars
[GVAR_MOUSE_CURSOR
];
1119 if (cur
>= 0 && cur
< banks
[256].count
) {
1120 blitSurface2x(frame
, vmGVars
[GVAR_MOUSE_X
], vmGVars
[GVAR_MOUSE_Y
], banks
[256].spr
[cur
][0]);
1126 ////////////////////////////////////////////////////////////////////////////////
1127 #define ROOM_SCRIPTS_MARK " room script labels starts here "
1130 static void loadMapScript (ResFile
*resfile
) {
1134 l
= vmLabelAddMark(ROOM_SCRIPTS_MARK
);
1135 l
->value
= vmCodeSize
;
1136 if ((csz
= loadCodeFile(resfile
, vmCodeSize
, 94+curLevel
, 1)) > 1) {
1142 static void unloadMapScript (void) {
1143 VMLabelInfo
*l
, *ucl
;
1145 while ((l
= vmFindMark(ROOM_SCRIPTS_MARK
)) != NULL
) {
1146 ucl
= vmFindLabel("entry_local_room_script_onunload");
1147 if (ucl
!= NULL
&& ucl
->type
== LB_CODE
) vmExecuteBSR(0, ucl
->value
, 0);
1148 vmCodeSize
= l
->value
;
1149 vmFreeLabelsUntilMark(ROOM_SCRIPTS_MARK
);
1152 ucl
= vmFindLabel("entry_goobers_room_onunload");
1153 if (ucl
!= NULL
&& ucl
->type
== LB_CODE
) vmExecuteBSR(0, ucl
->value
, 0);
1155 ucl
= vmFindLabel("entry_room_onunload");
1156 if (ucl
!= NULL
&& ucl
->type
== LB_CODE
) vmExecuteBSR(0, ucl
->value
, 0);
1160 ////////////////////////////////////////////////////////////////////////////////
1161 static int loadLevelInternal (ResFile
*resfile
, int lidx
) {
1165 vmGVars
[GVAR_VIS_WIDTH
] = VIS_WIDTH
;
1166 vmGVars
[GVAR_VIS_HEIGHT
] = VIS_HEIGHT
;
1167 levelname
[0] = levelcode
[0] = itemname
[0] = 0;
1169 if (levelData
!= NULL
) free(levelData
); levelData
= NULL
; levelDataSize
= 0;
1170 if (bmap
!= NULL
) free(bmap
); bmap
= NULL
;
1171 if (fmap
!= NULL
) free(fmap
); fmap
= NULL
;
1172 if (xflags
!= NULL
) free(xflags
); xflags
= NULL
;
1175 if (lidx
< 0 || lidx
> 73) return -1;
1176 if ((levelData
= loadResFile(resfile
, lidx
+9, &levelDataSize
)) == NULL
) return -1;
1178 loadMapScript(resfile
);
1179 return levelDataSize
;
1183 ////////////////////////////////////////////////////////////////////////////////
1184 static void activateMinimap (void) {
1192 ////////////////////////////////////////////////////////////////////////////////
1193 static void getVMString (char *dest
, int destsize
, int argc
, int argv
[]) {
1195 int pos
= 0, len
= destsize
-1, lp
= 0;
1198 case 1: fatal("out of args in FRST_SET_LEVEL_NAME");
1199 case 2: pos
= argv
[1]; break;
1200 case 3: pos
= argv
[1]; len
= argv
[2]; break;
1202 memset(dest
, 0, destsize
);
1203 if (len
< 0) len
= destsize
-1;
1204 if (len
> destsize
-1) len
= destsize
-1;
1206 while (len
> 0 && pos
< vmCodeSize
&& vmCode
[pos
]) {
1207 dest
[lp
++] = vmCode
[pos
++];
1212 while (len
> 0 && pos
< levelDataSize
&& levelData
[pos
]) {
1213 dest
[lp
++] = levelData
[pos
++];
1217 } else if (destsize
== 1) {
1223 static int gameRST (int tid
, int opcode
, int argc
, int argv
[], int *argp
[]) {
1224 if (argv
[0] == CONST_FRST_MINIMAP
) {
1226 } else if (argv
[0] == CONST_FRST_OPEN_LEVEL_FILE
) {
1228 //if (vmLoadArgs(tid, 2, argv, argp, argc, argv, argp) != 0) fatal("out of args");
1229 if (argc
< 2) fatal("out of args in FRST_LOAD_LEVEL");
1230 vmGVars
[GVAR_RST_RESULT
] = loadLevelInternal(&resfile
, argv
[1]);
1231 //if (goobers) fprintf(stderr, "FRST_OPEN_LEVEL_FILE(%d): %d\n", argv[1], vmGVars[GVAR_RST_RESULT]);
1232 } else if (argv
[0] == CONST_FRST_GET_LEVEL_DATA_SIZE
) {
1233 vmGVars
[GVAR_RST_RESULT
] = levelDataSize
;
1234 } else if (argv
[0] == CONST_FRST_GET_LEVEL_LOADER
) {
1235 VMLabelInfo
*ucl
= vmFindLabel("entry_local_room_loader");
1237 vmGVars
[GVAR_RST_RESULT
] = (ucl
!= NULL
&& ucl
->type
== LB_CODE
) ? ucl
->value
: -1;
1238 } else if (argv
[0] == CONST_FRST_GET_LEVEL_INITER
) {
1239 VMLabelInfo
*ucl
= vmFindLabel("entry_local_room_onload");
1241 vmGVars
[GVAR_RST_RESULT
] = (ucl
!= NULL
&& ucl
->type
== LB_CODE
) ? ucl
->value
: -1;
1242 } else if (argv
[0] == CONST_FRST_GET_GOOBERS_INITER
) {
1243 VMLabelInfo
*ucl
= vmFindLabel("entry_goobers_game_init");
1245 vmGVars
[GVAR_RST_RESULT
] = (ucl
!= NULL
&& ucl
->type
== LB_CODE
) ? ucl
->value
: -1;
1246 } else if (argv
[0] == CONST_FRST_GET_GOOBERS_ONLOAD
) {
1247 VMLabelInfo
*ucl
= vmFindLabel("entry_goobers_room_onload");
1249 vmGVars
[GVAR_RST_RESULT
] = (ucl
!= NULL
&& ucl
->type
== LB_CODE
) ? ucl
->value
: -1;
1250 } else if (argv
[0] == CONST_FRST_GET_LEVEL_FILE_BYTE
) {
1251 if (argc
< 2) fatal("out of args in FRST_GET_LEVEL_FILE_BYTE");
1252 if (argv
[1] < 0 || argv
[1] >= levelDataSize
) fatal("invalid offset in FRST_GET_LEVEL_FILE_BYTE: %d", argv
[1]);
1253 vmGVars
[GVAR_RST_RESULT
] = levelData
[argv
[1]];
1254 } else if (argv
[0] == CONST_FRST_GET_LEVEL_FILE_WORD
) {
1255 if (argc
< 2) fatal("out of args in FRST_GET_LEVEL_FILE_WORD");
1256 if (argv
[1] < 0 || argv
[1]+1 >= levelDataSize
) fatal("invalid offset in FRST_GET_LEVEL_FILE_WORD: %d", argv
[1]);
1257 vmGVars
[GVAR_RST_RESULT
] = levelData
[argv
[1]+1];
1258 vmGVars
[GVAR_RST_RESULT
] <<= 8;
1259 vmGVars
[GVAR_RST_RESULT
] |= levelData
[argv
[1]];
1260 if (vmGVars
[GVAR_RST_RESULT
] >= 32768) vmGVars
[GVAR_RST_RESULT
] -= 65536;
1261 } else if (argv
[0] == CONST_FRST_SET_LEVEL_SIZE
) {
1264 if (argc
!= 3) fatal("out of args in FRST_SET_LEVEL_SIZE");
1267 if (w
< 1 || w
> 32700 || h
< 1 || h
> 32700) fatal("invalid dimensions in FRST_SET_LEVEL_SIZE: %dx%d", w
, h
);
1268 if (bmap
!= NULL
) free(bmap
); bmap
= NULL
;
1269 if (fmap
!= NULL
) free(fmap
); fmap
= NULL
;
1270 if (xflags
!= NULL
) free(xflags
); xflags
= NULL
;
1271 fmap
= calloc(w
*h
, 1); if (fmap
== NULL
) fatal("out of memory in FRST_SET_LEVEL_SIZE");
1272 bmap
= calloc(w
*h
, 1); if (bmap
== NULL
) fatal("out of memory in FRST_SET_LEVEL_SIZE");
1273 xflags
= calloc(w
, 1); if (xflags
== NULL
) fatal("out of memory in FRST_SET_LEVEL_SIZE");
1274 mapWidth
= vmGVars
[GVAR_MAP_WIDTH
] = w
;
1275 mapHeight
= vmGVars
[GVAR_MAP_HEIGHT
] = h
;
1279 } else if (argv
[0] == CONST_FRST_SET_LEVEL_NAME
) {
1282 getVMString(levelname
, sizeof(levelname
), argc
, argv
);
1283 lnamex
= (320-strlen(levelname
)*8)/2;
1284 sprintf(buf
, "%d", curLevel
+1);
1285 while (lnamex
+strlen(levelname
)*8+strlen(buf
)*8+6*8 > 320) lnamex
-= 8;
1287 } else if (argv
[0] == CONST_FRST_SET_LEVEL_CODE
) {
1288 getVMString(levelcode
, sizeof(levelcode
), argc
, argv
);
1290 } else if (argv
[0] == CONST_FRST_SET_ITEM_NAME
) {
1291 getVMString(itemname
, sizeof(itemname
), argc
, argv
);
1293 } else if (argv
[0] == CONST_FRST_LOAD_SPRITES
) {
1294 // arg1: bank, arg2: filename (0-terminated)
1299 argv
[2] = vmPop(tid
);
1300 argv
[1] = vmPop(tid
);
1303 argv
[2] = vmPop(tid
);
1308 vmGVars
[GVAR_RST_RESULT
] = -1;
1309 if (fnpos
>= 0 && fnpos
< vmCodeSize
-1 && argv
[1] >= 0 && argv
[1] <= 256) {
1312 for (end
= fnpos
; end
< vmCodeSize
&& vmCode
[end
]; ++end
) ;
1313 if (end
< vmCodeSize
) {
1314 //fprintf(stderr, "!!! %d: [%s]\n", argv[1], (const char *)(vmCode+fnpos));
1315 vmGVars
[GVAR_RST_RESULT
] = loadSpriteBankFromFile(&banks
[argv
[1]], (const char *)(vmCode
+fnpos
));
1318 } else if (argv
[0] == CONST_FRST_ADD_LEVEL_SPRITE
|| argv
[0] == CONST_FRST_ADD_SPRITE
) {
1319 // x, y, layer, bank, num, dir (can take 1st 2 args from stack too)
1320 int inlevel
= (argv
[0] == CONST_FRST_ADD_LEVEL_SPRITE
);
1321 int x
= 0, y
= 0, layer
, bank
, num
, dir
;
1341 //fprintf(stderr, "x=%d, y=%d, layer=%d, bank=%d, num=%d, dir=%d, inlevel=%d\n", x, y, layer, bank, num, dir, inlevel);
1342 addSpriteToLayer(x
, y
, layer
, bank
, num
, dir
, inlevel
);
1344 if (gameRSTCB
) return gameRSTCB(tid
, opcode
, argc
, argv
, argp
);
1345 fatal("invalid RST: %d", argv
[0]);
1347 return 0; // continue
1351 ////////////////////////////////////////////////////////////////////////////////
1352 void setMainLoopGame (void) {
1353 frameCB
= frmGameDraw
;
1356 gameRSTCB
= gameRST
;
1357 beforeVMCB
= demoCB
;
1358 vmMapGetCB
= mapGet
;
1359 vmMapSetCB
= mapSet
;
1361 clearSpriteLayers();
1362 setSeed(time(NULL
));
1367 levelname
[0] = levelcode
[0] = itemname
[0] = 0;
1371 memset(fkeys
, 0, sizeof(fkeys
));
1372 memset(gamekeys
, 0, sizeof(gamekeys
));