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"
24 ReplayData replayData;
26 void drawMap(int mapX, int mapY)
31 for (int x = 0 ; x < 20 ; x++)
33 for (int y = 0 ; y < 15 ; y++)
37 r.w = r.h = BRICKSIZE - 1;
39 tile = map.data[x + mapX][y + mapY];
41 if (tile == MAP_WATERANIM)
43 tile = graphics.getWaterAnim();
48 graphics.blit(graphics.tile[tile], r.x, r.y, graphics.screen, false);
50 if ((tile >= MAP_NORESET) && (tile < MAP_DECORATION))
52 graphics.drawRect(r.x, r.y, 32, 4, graphics.yellow, graphics.screen);
59 void showMap(int *mapX, int *mapY)
61 SDL_FillRect(graphics.screen, NULL, graphics.black);
63 engine.keyState[SDLK_SPACE] = 0;
68 graphics.updateScreen();
72 if (engine.keyState[SDLK_SPACE])
75 for (int x = 0 ; x < MAPWIDTH ; x++)
77 for (int y = 0 ; y < MAPHEIGHT ; y++)
79 switch (map.data[x][y])
82 graphics.putPixel(x, y, 9, graphics.screen);
85 graphics.putPixel(x, y,graphics.blue, graphics.screen);
88 graphics.putPixel(x, y, graphics.green, graphics.screen);
91 graphics.putPixel(x, y, graphics.red, graphics.screen);
94 graphics.putPixel(x, y, graphics.white, graphics.screen);
102 if (engine.keyState[SDLK_LEFT])
105 if (engine.keyState[SDLK_RIGHT])
108 if (engine.keyState[SDLK_UP])
111 if (engine.keyState[SDLK_DOWN])
116 Math::limitInt(&moveTimer, 0, 60);
118 graphics.drawRect(*mapX, *mapY, 20, 1, graphics.green, graphics.screen);
119 graphics.drawRect(*mapX, *mapY, 1, 15, graphics.green, graphics.screen);
120 graphics.drawRect(*mapX, *mapY + 15, 20, 1, graphics.green, graphics.screen);
121 graphics.drawRect(*mapX + 20, *mapY, 1, 15, graphics.green, graphics.screen);
126 engine.keyState[SDLK_SPACE] = 0;
129 int nextBlock(int current, int dir)
131 if ((current + dir) > 255)
134 if ((current + dir) < 0)
137 int wanted = current;
143 if (wanted < 0) return current;
144 if (wanted > 255) return current;
146 if (graphics.tile[wanted])
153 Entity *enemy = (Entity*)map.enemyList.getHead();
155 int x, y, absX, absY;
157 while (enemy->next != NULL)
159 enemy = (Entity*)enemy->next;
161 if (enemy->owner != enemy)
163 enemy->face = enemy->owner->face;
164 (enemy->face == 0) ? enemy->x = enemy->owner->x + enemy->tx : enemy->x = enemy->owner->x + -enemy->tx;
165 enemy->y = enemy->owner->y + enemy->ty;
168 x = (int)(enemy->x - engine.playerPosX);
169 y = (int)(enemy->y - engine.playerPosY);
174 if ((absX < 800) && (absY < 600))
176 graphics.blit(enemy->getFaceImage(), x, y, graphics.screen, false);
179 if ((!(enemy->flags & ENT_WEIGHTLESS)) && (!(enemy->flags & ENT_FLIES)) && (!(enemy->flags & ENT_SWIMS)))
180 enemy->applyGravity();
185 void deleteEnemy(int x, int y)
190 Entity *enemy = (Entity*)map.enemyList.getHead();
191 Entity *previous = enemy;
193 while (enemy->next != NULL)
195 enemy = (Entity*)enemy->next;
197 if ((enemy->x == x) && (enemy->y == y))
199 map.enemyList.remove(previous, enemy);
209 void saveMap(const char *name)
211 FILE *fp = fopen(name, "wb");
212 Entity *enemy = (Entity*)map.enemyList.getHead();
217 for (int y = 0 ; y < MAPHEIGHT ; y++)
219 for (int x = 0 ; x < MAPWIDTH ; x++)
221 fprintf(fp, "%d ", map.data[x][y]);
226 str = stringHead->next;
229 fprintf(fp, "%s", str->string);
233 while (enemy->next != NULL)
235 enemy = (Entity*)enemy->next;
236 fprintf(fp, "EMH ENEMY \"%s\" %d %d\n", enemy->name, (int)enemy->x, (int)enemy->y);
239 fprintf(fp, "@EOF@\n");
244 printf("Saved %s (%d)\n", name, SDL_GetTicks());
247 void collectMapData()
249 FILE *fp = fopen(game.mapName, "rb");
256 for (int y = 0 ; y < 300 ; y++)
257 fgets(string, 1024, fp);
261 fgets(string, 1024, fp);
262 printf("Read: %s", string);
264 if (strstr(string, "@EOF@"))
267 if (!strstr(string, " ENEMY \""))
270 strcpy(str->string, string);
271 stringTail->next = str;
275 if (strstr(string, "TILESET gfx/ancient"))
277 for (int x = 0 ; x < MAPWIDTH ; x++)
279 for (int y = 0 ; y < MAPHEIGHT ; y++)
281 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20) && ((Math::prand() % 2) == 0))
282 map.data[x][y] = Math::rrand(9, 20);
287 if (strstr(string, "TILESET gfx/caves"))
289 for (int x = 0 ; x < MAPWIDTH ; x++)
291 for (int y = 0 ; y < MAPHEIGHT ; y++)
293 if ((map.data[x][y] >= 9) && (map.data[x][y] <= 20))
294 map.data[x][y] = Math::rrand(9, 12);
303 void newMap(const char *name)
305 FILE *fp = fopen(name, "wb");
309 for (int y = 0 ; y < MAPHEIGHT ; y++)
311 for (int x = 0 ; x < MAPWIDTH ; x++)
313 fprintf(fp, "%d ", map.data[x][y]);
318 fprintf(fp, "EMH STAGENAME \"unnamed\"\n");
320 fprintf(fp, "EMH TILESET gfx/grasslands\n");
321 fprintf(fp, "EMH BACKGROUND gfx/grasslands/stone.jpg\n");
322 fprintf(fp, "EMH MUSIC music/viking.mod\n");
324 fprintf(fp, "EMH ALPHATILES 1 2 3 200 201 202 203 204 244 245 246 -1\n");
326 fprintf(fp, "EMH START 10 10\n");
328 fprintf(fp, "@EOF@\n");
338 void addTileDecoration()
340 printf("Adding Tile Decoration...\n");
342 for (int y = 1 ; y < MAPHEIGHT ; y++)
344 for (int x = 0 ; x < MAPWIDTH ; x++)
346 if ((map.data[x][y] == 9) && (map.data[x][y - 1] == MAP_AIR))
348 if (Math::prand() % 4)
349 map.data[x][y - 1] = 241;
354 for (int y = 0 ; y < MAPHEIGHT ; y++)
356 for (int x = 0 ; x < MAPWIDTH ; x++)
358 if (map.data[x][y] == 241)
360 if ((Math::prand() % 3) == 0)
361 map.data[x][y] = 242;
366 engine.keyState[SDLK_F1] = 0;
369 void fillHorizontal(int block, int x, int y)
371 bool moveLeft = true;
372 bool moveRight = true;
378 if (map.data[x][y] == 0)
380 map.data[x][y] = block;
393 if (map.data[left][y] == 0)
395 map.data[left][y] = block;
406 if (right >= MAPWIDTH)
408 right = MAPWIDTH - 1;
412 if (map.data[right][y] == 0)
414 map.data[right][y] = block;
421 if ((!moveLeft) && (!moveRight))
429 int main(int argc, char *argv[])
433 printf("Usage: mapeditor <filename>\n\n");
437 config.engine = &engine;
447 FILE *fp = fopen(argv[1], "rb");
453 game.setMapName(argv[1]);
459 int mapX, mapY, allowMove, x, y;
460 mapX = mapY = allowMove = x = y = 0;
463 int currentMonster = 0;
465 int currentBlock = 1;
473 unsigned int frameLimit = SDL_GetTicks() + 16;
480 engine.doFrameLoop();
482 graphics.updateScreen();
483 graphics.animateSprites();
484 graphics.drawBackground();
486 engine.setPlayerPosition((mapX * 32) + 320, (mapY * 32) + 240, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
502 x = engine.getMouseX();
503 y = engine.getMouseY();
516 graphics.drawRect(r.x - 1, r.y - 1, 34, 1, graphics.yellow, graphics.screen);
517 graphics.drawRect(r.x - 1, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
518 graphics.drawRect(r.x + 32, r.y - 1, 1, 34, graphics.yellow, graphics.screen);
519 graphics.drawRect(r.x - 1, r.y + 32, 34, 1, graphics.yellow, graphics.screen);
520 graphics.blit(graphics.tile[currentBlock], r.x, r.y, graphics.screen, false);
521 if (engine.mouseLeft)
522 map.data[mapX + x][mapY + y] = currentBlock;
525 graphics.blit(defEnemy[currentMonster].getFaceImage(), r.x, r.y, graphics.screen, false);
526 if (engine.mouseLeft)
528 addEnemy(defEnemy[currentMonster].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, 0);
529 engine.mouseLeft = 0;
533 graphics.blit(defItem[currentItem].getFaceImage(), r.x, r.y, graphics.screen, false);
534 if (engine.mouseLeft)
536 addItem(defItem[currentItem].id, defItem[currentItem].name, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].sprite[0]->name, 0, defItem[currentItem].value, 0, true);
537 engine.mouseLeft = 0;
542 if (engine.mouseRight)
544 if (editing == 0) map.data[mapX + x][mapY + y] = MAP_AIR;
545 if (editing == 1) deleteEnemy(mapX + x, mapY + y);
549 if (allowMove < 1) allowMove = 0;
553 if (engine.keyState[SDLK_UP]) {mapY--; allowMove = MOVESPEED;}
554 if (engine.keyState[SDLK_DOWN]) {mapY++; allowMove = MOVESPEED;}
555 if (engine.keyState[SDLK_LEFT]) {mapX--; allowMove = MOVESPEED;}
556 if (engine.keyState[SDLK_RIGHT]) {mapX++; allowMove = MOVESPEED;}
558 if (engine.keyState[SDLK_PAGEDOWN]) {mapY += 10; allowMove = MOVESPEED;}
559 if (engine.keyState[SDLK_PAGEUP]) {mapY -= 10; allowMove = MOVESPEED;}
561 if (engine.keyState[SDLK_1]) editing = 0;
562 if (engine.keyState[SDLK_2]) editing = 1;
563 if (engine.keyState[SDLK_3]) editing = 2;
565 if (engine.keyState[SDLK_0]) fillHorizontal(currentBlock, mapX + x, mapY + y);
567 if (engine.keyState[SDLK_F1]) addTileDecoration();
569 if (engine.keyState[SDLK_ESCAPE]) break;
572 if (engine.keyState[SDLK_PERIOD])
577 currentBlock = nextBlock(currentBlock, 1);
587 engine.keyState[SDLK_PERIOD] = 0;
590 if (engine.keyState[SDLK_COMMA])
595 currentBlock = nextBlock(currentBlock, -1);
605 engine.keyState[SDLK_COMMA] = 0;
608 Math::limitInt(¤tMonster, 0, MAX_ENEMIES - 1);
609 Math::limitInt(¤tItem, 0, MAX_ITEMS - 1);
611 if (defEnemy[currentMonster].sprite[0] == NULL)
614 if (defItem[currentItem].sprite[0] == NULL)
617 if (engine.keyState[SDLK_SPACE]) {showMap(&mapX, &mapY);}
619 if (engine.keyState[SDLK_s]) {saveMap(game.mapName); engine.keyState[SDLK_s] = 0;}
621 if (mapX < 0) mapX = 0;
622 if (mapY < 0) mapY = 0;
623 if (mapX > MAPWIDTH - 40) mapX = MAPWIDTH - 40;
624 if (mapY > MAPHEIGHT - 30) mapY = MAPHEIGHT - 30;
627 sprintf(string, "Index : %d:%d ; Screen %d:%d ; Tile %d", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, currentBlock);
628 else if (editing == 1)
629 sprintf(string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defEnemy[currentMonster].name);
630 else if (editing == 2)
631 sprintf(string, "Index : %d:%d ; Screen %d:%d ; %s", mapX + x, mapY + y, (mapX + x) * BRICKSIZE, (mapY + y) * BRICKSIZE, defItem[currentItem].name);
637 if (mapY < MAPHEIGHT - 30)
642 SDL_FillRect(graphics.screen, &r, graphics.black);
644 graphics.drawString(string, 320, r.y + 5, true, graphics.screen);
646 engine.delay(frameLimit);
647 frameLimit = SDL_GetTicks() + 16;
650 String *str = stringHead->next;
655 printf("Deleting %s", str->string);