2 Copyright (C) 2004 Parallel Realities
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "mapEditor.h"
23 void drawMap(int mapX, int mapY)
28 for (int x = 0 ; x < 20 ; x++)
30 for (int y = 0 ; y < 15 ; y++)
34 r.w = r.h = BRICKSIZE - 1;
36 tile = map.data[x + mapX][y + mapY];
38 if (tile == MAP_WATERANIM)
40 tile = graphics.getWaterAnim();
45 graphics.blit(graphics.tile[tile], r.x, r.y, graphics.screen, false);
47 if ((tile >= MAP_NORESET) && (tile < MAP_DECORATION))
49 graphics.drawRect(r.x, r.y, 32, 4, graphics.yellow, graphics.screen);
56 void showMap(int *mapX, int *mapY)
58 SDL_FillRect(graphics.screen, NULL, graphics.black);
60 engine.keyState[SDLK_SPACE] = 0;
65 graphics.updateScreen();
69 if (engine.keyState[SDLK_SPACE])
72 for (int x = 0 ; x < MAPWIDTH ; x++)
74 for (int y = 0 ; y < MAPHEIGHT ; y++)
76 switch (map.data[x][y])
79 graphics.putPixel(x, y, 9, graphics.screen);
82 graphics.putPixel(x, y,graphics.blue, graphics.screen);
85 graphics.putPixel(x, y, graphics.green, graphics.screen);
88 graphics.putPixel(x, y, graphics.red, graphics.screen);
91 graphics.putPixel(x, y, graphics.white, graphics.screen);
99 if (engine.keyState[SDLK_LEFT])
102 if (engine.keyState[SDLK_RIGHT])
105 if (engine.keyState[SDLK_UP])
108 if (engine.keyState[SDLK_DOWN])
113 Math::limitInt(&moveTimer, 0, 60);
115 graphics.drawRect(*mapX, *mapY, 20, 1, graphics.green, graphics.screen);
116 graphics.drawRect(*mapX, *mapY, 1, 15, graphics.green, graphics.screen);
117 graphics.drawRect(*mapX, *mapY + 15, 20, 1, graphics.green, graphics.screen);
118 graphics.drawRect(*mapX + 20, *mapY, 1, 15, graphics.green, graphics.screen);
123 engine.keyState[SDLK_SPACE] = 0;
126 int nextBlock(int current, int dir)
128 if ((current + dir) > 255)
131 if ((current + dir) < 0)
134 int wanted = current;
140 if (wanted < 0) return current;
141 if (wanted > 255) return current;
143 if (graphics.tile[wanted])
150 Entity *enemy = (Entity*)map.enemyList.getHead();
152 int x, y, absX, absY;
154 while (enemy->next != NULL)
156 enemy = (Entity*)enemy->next;
158 if (enemy->owner != enemy)
160 enemy->face = enemy->owner->face;
161 (enemy->face == 0) ? enemy->x = enemy->owner->x + enemy->tx : enemy->x = enemy->owner->x + -enemy->tx;
162 enemy->y = enemy->owner->y + enemy->ty;
165 x = (int)(enemy->x - engine.playerPosX);
166 y = (int)(enemy->y - engine.playerPosY);
171 if ((absX < 800) && (absY < 600))
173 graphics.blit(enemy->getFaceImage(), x, y, graphics.screen, false);
176 if ((!(enemy->flags & ENT_WEIGHTLESS)) && (!(enemy->flags & ENT_FLIES)) && (!(enemy->flags & ENT_SWIMS)))
177 enemy->applyGravity();
182 void deleteEnemy(int x, int y)
187 Entity *enemy = (Entity*)map.enemyList.getHead();
188 Entity *previous = enemy;
190 while (enemy->next != NULL)
192 enemy = (Entity*)enemy->next;
194 if ((enemy->x == x) && (enemy->y == y))
196 map.enemyList.remove(previous, enemy);
206 void saveMap(const char *name)
208 FILE *fp = fopen(name, "wb");
209 Entity *enemy = (Entity*)map.enemyList.getHead();
214 for (int y = 0 ; y < MAPHEIGHT ; y++)
216 for (int x = 0 ; x < MAPWIDTH ; x++)
218 fprintf(fp, "%d ", map.data[x][y]);
223 str = stringHead->next;
226 fprintf(fp, "%s", str->string);
230 while (enemy->next != NULL)
232 enemy = (Entity*)enemy->next;
233 fprintf(fp, "EMH ENEMY \"%s\" %d %d\n", enemy->name, (int)enemy->x, (int)enemy->y);
236 fprintf(fp, "@EOF@\n");
241 printf("Saved %s (%d)\n", name, SDL_GetTicks());
244 void collectMapData()
246 FILE *fp = fopen(game.mapName, "rb");
253 for (int y = 0 ; y < 300 ; y++)
254 fgets(string, 1024, fp);
258 fgets(string, 1024, fp);
259 printf("Read: %s", string);
261 if (strstr(string, "@EOF@"))
264 if (!strstr(string, " ENEMY \""))
267 strncpy(str->string, string, sizeof str->string);
268 stringTail->next = str;
272 if (strstr(string, "TILESET gfx/ancient"))
274 for (int x = 0 ; x < MAPWIDTH ; x++)
276 for (int y = 0 ; y < MAPHEIGHT ; y++)
278 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20) && ((Math::prand() % 2) == 0))
279 map.data[x][y] = Math::rrand(9, 20);
284 if (strstr(string, "TILESET gfx/caves"))
286 for (int x = 0 ; x < MAPWIDTH ; x++)
288 for (int y = 0 ; y < MAPHEIGHT ; y++)
290 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20))
291 map.data[x][y] = Math::rrand(9, 12);
300 void newMap(const char *name)
302 FILE *fp = fopen(name, "wb");
306 for (int y = 0 ; y < MAPHEIGHT ; y++)
308 for (int x = 0 ; x < MAPWIDTH ; x++)
310 fprintf(fp, "%d ", map.data[x][y]);
315 fprintf(fp, "EMH STAGENAME \"unnamed\"\n");
317 fprintf(fp, "EMH TILESET gfx/grasslands\n");
318 fprintf(fp, "EMH BACKGROUND gfx/grasslands/stone.jpg\n");
319 fprintf(fp, "EMH MUSIC music/viking.mod\n");
321 fprintf(fp, "EMH ALPHATILES 1 2 3 200 201 202 203 204 244 245 246 -1\n");
323 fprintf(fp, "EMH START 10 10\n");
325 fprintf(fp, "@EOF@\n");
335 void addTileDecoration()
337 printf("Adding Tile Decoration...\n");
339 for (int y = 1 ; y < MAPHEIGHT ; y++)
341 for (int x = 0 ; x < MAPWIDTH ; x++)
343 if ((map.data[x][y] == 9) && (map.data[x][y - 1] == MAP_AIR))
345 if (Math::prand() % 4)
346 map.data[x][y - 1] = 241;
351 for (int y = 0 ; y < MAPHEIGHT ; y++)
353 for (int x = 0 ; x < MAPWIDTH ; x++)
355 if (map.data[x][y] == 241)
357 if ((Math::prand() % 3) == 0)
358 map.data[x][y] = 242;
363 engine.keyState[SDLK_F1] = 0;
366 void fillHorizontal(int block, int x, int y)
368 bool moveLeft = true;
369 bool moveRight = true;
375 if (map.data[x][y] == 0)
377 map.data[x][y] = block;
390 if (map.data[left][y] == 0)
392 map.data[left][y] = block;
403 if (right >= MAPWIDTH)
405 right = MAPWIDTH - 1;
409 if (map.data[right][y] == 0)
411 map.data[right][y] = block;
418 if ((!moveLeft) && (!moveRight))
426 int main(int argc, char *argv[])
430 printf("Usage: mapeditor <filename>\n\n");
440 FILE *fp = fopen(argv[1], "rb");
446 game.setMapName(argv[1]);
452 int mapX, mapY, allowMove, x, y;
453 mapX = mapY = allowMove = x = y = 0;
456 int currentMonster = 0;
458 int currentBlock = 1;
466 unsigned int frameLimit = SDL_GetTicks() + 16;
473 engine.doFrameLoop();
475 graphics.updateScreen();
476 graphics.animateSprites();
477 graphics.drawBackground();
479 engine.setPlayerPosition((mapX * 32) + 320, (mapY * 32) + 240, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
495 x = engine.getMouseX();
496 y = engine.getMouseY();
509 graphics.drawRect(r.x - 1, r.y - 1, 34, 1, graphics.yellow, graphics.screen);
510 graphics.drawRect(r.x - 1, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
511 graphics.drawRect(r.x + 32, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
512 graphics.drawRect(r.x - 1, r.y + 32, 34, 1, graphics.yellow, graphics.screen);
513 graphics.blit(graphics.tile[currentBlock], r.x, r.y, graphics.screen, false);
514 if (engine.mouseLeft)
515 map.data[mapX + x][mapY + y] = currentBlock;
518 graphics.blit(defEnemy[currentMonster].getFaceImage(), r.x, r.y, graphics.screen, false);
519 if (engine.mouseLeft)
521 addEnemy(defEnemy[currentMonster].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, 0);
522 engine.mouseLeft = 0;
526 graphics.blit(defItem[currentItem].getFaceImage(), r.x, r.y, graphics.screen, false);
527 if (engine.mouseLeft)
529 addItem(defItem[currentItem].id, defItem[currentItem].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].sprite[0]->name, 0, defItem[currentItem].value, 0, true);
530 engine.mouseLeft = 0;
535 if (engine.mouseRight)
537 if (editing == 0) map.data[mapX + x][mapY + y] = MAP_AIR;
538 if (editing == 1) deleteEnemy(mapX + x, mapY + y);
542 if (allowMove < 1) allowMove = 0;
546 if (engine.keyState[SDLK_UP]) {mapY--; allowMove = MOVESPEED;}
547 if (engine.keyState[SDLK_DOWN]) {mapY++; allowMove = MOVESPEED;}
548 if (engine.keyState[SDLK_LEFT]) {mapX--; allowMove = MOVESPEED;}
549 if (engine.keyState[SDLK_RIGHT]) {mapX++; allowMove = MOVESPEED;}
551 if (engine.keyState[SDLK_PAGEDOWN]) {mapY += 10; allowMove = MOVESPEED;}
552 if (engine.keyState[SDLK_PAGEUP]) {mapY -= 10; allowMove = MOVESPEED;}
554 if (engine.keyState[SDLK_1]) editing = 0;
555 if (engine.keyState[SDLK_2]) editing = 1;
556 if (engine.keyState[SDLK_3]) editing = 2;
558 if (engine.keyState[SDLK_0]) fillHorizontal(currentBlock, mapX + x, mapY + y);
560 if (engine.keyState[SDLK_F1]) addTileDecoration();
562 if (engine.keyState[SDLK_ESCAPE]) break;
565 if (engine.keyState[SDLK_PERIOD])
570 currentBlock = nextBlock(currentBlock, 1);
580 engine.keyState[SDLK_PERIOD] = 0;
583 if (engine.keyState[SDLK_COMMA])
588 currentBlock = nextBlock(currentBlock, -1);
598 engine.keyState[SDLK_COMMA] = 0;
601 Math::limitInt(¤tMonster, 0, MAX_ENEMIES - 1);
602 Math::limitInt(¤tItem, 0, MAX_ITEMS - 1);
604 if (defEnemy[currentMonster].sprite[0] == NULL)
607 if (defItem[currentItem].sprite[0] == NULL)
610 if (engine.keyState[SDLK_SPACE]) {showMap(&mapX, &mapY);}
612 if (engine.keyState[SDLK_s]) {saveMap(game.mapName); engine.keyState[SDLK_s] = 0;}
614 if (mapX < 0) mapX = 0;
615 if (mapY < 0) mapY = 0;
616 if (mapX > MAPWIDTH - 40) mapX = MAPWIDTH - 40;
617 if (mapY > MAPHEIGHT - 30) mapY = MAPHEIGHT - 30;
620 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; Tile %d", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, currentBlock);
621 else if (editing == 1)
622 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defEnemy[currentMonster].name);
623 else if (editing == 2)
624 snprintf(string, sizeof string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].name);
630 if (mapY < MAPHEIGHT - 30)
635 SDL_FillRect(graphics.screen, &r, graphics.black);
637 graphics.drawString(string, 320, r.y + 5, true, graphics.screen);
639 engine.delay(frameLimit);
640 frameLimit = SDL_GetTicks() + 16;
643 String *str = stringHead->next;
648 printf("Deleting %s", str->string);