/*************************************************************/ /* */ /* Invaded Levelset Editor */ /* Version 1.0 */ /* */ /* Copyright (c)2000-2001 TI-Calculator Programming Alliance */ /* Written and Programmed by James Vernon */ /* ICQ#: 71589304 */ /* http://tcpa.calc.org */ /* */ /* You may use any of this code as long as you give me */ /* credit. You are not allowed to distribute a modified */ /* source nor the compiled version of it without my */ /* permission. */ /* */ /* Compiled using Borland C++ v4.02. */ /* */ /*************************************************************/ ///////////////////////////////////////////////// // Include files ///////////////////////////////////////////////// #include #include #include #include #include ///////////////////////////////////////////////// // Keypress defines ///////////////////////////////////////////////// #define K_UP 72 #define K_DOWN 80 #define K_LEFT 75 #define K_RIGHT 77 #define K_ESC 27 #define K_SPACE ' ' #define K_HOME 71 #define K_END 79 #define K_DELETE 83 #define K_PGDOWN 81 #define K_1 '1' #define K_2 '2' #define K_3 '3' #define K_4 '4' #define K_5 '5' #define K_6 '6' #define K_7 '7' #define K_8 '8' #define K_9 '9' #define K_0 '0' #define K_F1 59 #define K_F2 60 #define K_F3 61 #define K_F4 62 #define K_F5 63 #define K_F6 64 #define K_F7 65 #define K_F8 66 #define K_F9 67 #define K_F10 68 #define K_H 'h' #define K_O 'o' #define K_E 'e' #define K_D 'd' #define K_C 'c' #define K_N 'n' #define K_P 'p' #define K_Q 'q' #define K_W 'w' #define K_R 'r' #define K_T 't' #define K_Y 'y' #define K_U 'u' #define K_I 'i' #define K_SMALLERTHAN 44 #define K_GREATERTHAN 46 #define K_PLUS 43 #define K_MINUS 45 #define K_ENTER 13 #define K_BACKSPACE 8 #define K_CTRLA 1 #define K_CTRLS 19 #define K_CTRLD 4 #define K_CTRLF 6 #define K_CTRLG 7 #define K_TAB 9 ///////////////////////////////////////////////// // Function headers ///////////////////////////////////////////////// int setGraphicsMode(void); void mainMenuHelp(void); void changeTileset(void); FILE *checkFileExists(char *name); void createNewLevelset(void); int loadLevelset(FILE *fp); int saveLevelset(char *name); int loadTileset(void); void putSprite(int x, int y, unsigned char *spr); void putMaskedSprite(int x, int y, unsigned char *spr); void putSpriteLarge(int x, int y, unsigned char *spr); void showTileset(void); void highlightTileset(int tile, int mode); void highlightBlock(int x, int y); void drawBox(int x, int y, int w, int h, int c); void drawLevel(int level, int xOffset); void levelsetHelp(void); void findAndReplace(void); void insertTile(void); void removeTile(void); void editLevelset(void); void enemyHelp(void); void showAIScript(int n); void swapUnsignedChars(unsigned char *first, unsigned char *second); void reverseUnsignedChar(unsigned char *byte); void editEnemies(void); void enemyPlacementHelp(void); int putEnemy(unsigned char level, char type, char blockX); void swapEnemyEntries(int i, int j, int k); void placeEnemies(void); void guardianHelp(void); void editGuardians(void); ///////////////////////////////////////////////// // Defines for levelStructure.enemyData ///////////////////////////////////////////////// #define MAX_ENEMIES 100 #define E_BLOCKX 0 #define E_TYPE 1 #define E_X 2 #define E_Y 3 ///////////////////////////////////////////////// // Typedefs ///////////////////////////////////////////////// typedef struct { unsigned char sprite[16]; unsigned char ai1; unsigned char ai2; unsigned char energy; unsigned char speed; unsigned char bonusItem; } enemyStructure; typedef struct { unsigned char length; unsigned char numEnemies; unsigned char guardianXSize; unsigned char guardianYSize; unsigned char gSpriteTL[16]; unsigned char gSpriteTR[16]; unsigned char gSpriteBL[16]; unsigned char gSpriteBR[16]; char gX; char gY; unsigned char gEnergy; unsigned char guardianAI1; unsigned char guardianAI2; unsigned char gClearScreen; unsigned char gEnemy; unsigned char cp1; unsigned char cp2; unsigned char cp3; char enemyData[MAX_ENEMIES][4]; unsigned char tileData[200][7]; } levelStructure; ///////////////////////////////////////////////// // Global variables ///////////////////////////////////////////////// unsigned char numLevels, numTiles, solidTiles, hurtyTiles, numEnemies, tileset[256][8], tilesetDetect[11]; unsigned short hiScore; char tilesetName[6], tilesetFileName[13]; enemyStructure enemyData[20]; levelStructure levelData[5]; unsigned char checkeredSprite[8] = {0x55, 0xAA,0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}; ///////////////////////////////////////////////// // AI Scripts ///////////////////////////////////////////////// char *aiScripts[] = {"None ", "Zig Zag Left ", "Hover Up & Down ", "Normal Shoot ", "Move Left ", "Power Shoot Left ", "Down then Left ", "Diagonally Up and Left ", "Diagonally Up and Right ", "Diagonally Down and Left ", "Diagonally Down and Right", "Up/Down and Follow Player", "Left With Level ", "3-Way Powerball Shoot ", "Random Up Powerball Shoot", "Shoot Through Walls ", "Hover Horizontally from L", "Hover Horizontally from R", "Shoot Twin Lasers ", "Follow Player ", "Move Left/Follow Player ", "Up then Left "}; ///////////////////////////////////////////////// // Main function ///////////////////////////////////////////////// int main(int argc, char *argv[]) { // Local variables char levelsetName[13], c, listName[10]; FILE *fp, *listP; unsigned char quit = 0; int i; char *listLevelNames[] = {"level1.inv\n", "level2.inv\n", "level3.inv\n", "level4.inv\n", "level5.inv\n"}; char *listLevelNames2[] = {"level1.inv", "level2.inv", "level3.inv", "level4.inv", "level5.inv"}; char detect[12]; // Show program information printf("\nInvaded Levelset Editor v1.0\n\n"); printf("Copyright (c)2000-2001 TI-Calculator Programming Alliance\n"); printf("Written and Programmed by James Vernon \n"); printf("ICQ#: 71589304\n"); printf("http://tcpa.calc.org\n\n"); // Check to make sure correct number of arguments were entered if (argc != 2) { printf("USAGE: ieditor \n"); printf("eg. \"ieditor jim01\"\n"); return 1; } // Check to make sure Levelset name is valid if (strlen(argv[1]) != 5) { printf("Invalid Levelset name: \"%s\"!\n", argv[1]); return 1; } // Otherwise, all is cool, initialise and wait for a keypress ;) levelsetName[0] = NULL; strcpy(levelsetName, "zil"); strcat(levelsetName, argv[1]); strcat(levelsetName, ".bin"); // Check to see if Levelset already exists fp = checkFileExists(levelsetName); if (fp == NULL) createNewLevelset(); else { if ((loadLevelset(fp)) != NULL) { printf("Error loading Levelset \"%s\"!\n", argv[1]); fclose(fp); return 1; } fclose(fp); } // Load required Tileset if ((loadTileset()) != NULL) { printf("Error loading Tileset \"%s\"!\n", tilesetName); return 1; } while (1) { clrscr(); printf("\n"); printf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»"); printf("º Invaded Levelset Editor v1.0 º"); printf("ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹"); printf("º Levelset: %5s º Levels: %d º Tileset: %5s º", strupr(argv[1]), (int)numLevels, strupr(tilesetName)); printf("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n\n"); printf("1) Edit Levels\n"); printf("2) Change Tileset\n"); printf("3) Edit Enemies\n"); printf("4) Place Enemies\n"); printf("5) Edit End-of-Level Bosses\n"); printf("6) Online Help\n"); printf("7) Save Levelset\n"); printf("8) Exit\n\n"); printf("Enter your selection: "); switch (getch()) { case K_1: editLevelset(); break; case K_2: changeTileset(); break; case K_3: editEnemies(); break; case K_4: placeEnemies(); break; case K_5: editGuardians(); break; case K_6: mainMenuHelp(); break; case K_7: if ((saveLevelset(levelsetName)) != NULL) { printf("\n\nError saving Level \"%s\"!", argv[1]); } else { printf("\n\nSaved successfully!"); } getch(); break; case K_8: do { printf("\n\nSave on exit - (y)es, (n)o? "); c = getch(); } while ((c != 'y') && (c != 'n')); if (c == 'y') quit = 1; else quit = 2; break; } if (quit != NULL) break; } clrscr(); printf("\nInvaded Levelset Editor v1.0\n\n"); printf("Copyright (c)2000-2001 TI-Calculator Programming Alliance\n"); printf("Written and Programmed by James Vernon \n"); printf("ICQ#: 71589304\n"); printf("http://tcpa.calc.org\n"); if (quit != 2) { if ((saveLevelset(levelsetName)) != NULL) { printf("Error saving Levelset \"%s\"!\n", argv[1]); return 1; } } // Split Levelset file into separate files for compression :) fp = checkFileExists(levelsetName); if (fp == NULL) return 1; if ((loadLevelset(fp)) != NULL) return 1; listName[0] = NULL; strcat(listName, argv[1]); strcat(listName, ".lst"); // Open list file to be used by Huffman Compression program listP = fopen(listName, "w"); // Write levelset header into separate file that won't be compressed fp = fopen("header.inv", "wb"); strcpy(detect, "I0L_"); strncat(detect, strupr(argv[1]), 5); fwrite(detect, 9, 1, fp); fwrite(&numLevels, 1, 1, fp); fwrite(&numEnemies, 1, 1, fp); fwrite(&hiScore, 2, 1, fp); fwrite(tilesetName, 5, 1, fp); fclose(fp); // Write name of enemy data file into list file, then write enemy data to file called enemydat.inv fprintf(listP, "enemydat.inv\n"); fp = fopen("enemydat.inv", "wb"); for (i = 0; i < numEnemies; i++) fwrite(&enemyData[i], sizeof(enemyData[i]), 1, fp); fclose(fp); // Write names of level files into list and write level data in separate files for (i = 0; i < numLevels; i++) { fprintf(listP, listLevelNames[i]); fp = fopen(listLevelNames2[i], "wb"); fwrite(&levelData[i], sizeof(levelData[i]) - (200 * 7) - (MAX_ENEMIES * 4), 1, fp); if (levelData[i].numEnemies) fwrite(levelData[i].enemyData, levelData[i].numEnemies * 4, 1, fp); fwrite(levelData[i].tileData, levelData[i].length * 7, 1, fp); fclose(fp); } return 0; } ///////////////////////////////////////////////// // setGraphicsMode - Set video mode to graphics mode // // Input: void // Output: int = 0 if no error ///////////////////////////////////////////////// int setGraphicsMode(void) { int gdriver = CGA, gmode = CGAC0, errorCode; initgraph(&gdriver, &gmode, ""); errorCode = graphresult(); if (errorCode != 0) { printf("Graphics error: %s\n", grapherrormsg(errorCode)); return 1; } return 0; } ///////////////////////////////////////////////// // mainMenuHelp - Help screen for Main Menu // // Input: void // Output: void ///////////////////////////////////////////////// void mainMenuHelp(void) { clrscr(); printf("\nInvaded Levelset Editor v1.0: Main Menu Help\n\n"); printf("1) Edit Levels\n"); printf(" Choose this option to run the Level Editor. From here you can change the\n"); printf(" look of levels, adjust size & number of levels, place/remove enemies, etc.\n"); printf("2) Change Tileset\n"); printf(" This option allows you to change the Tileset you want to use for your\n"); printf(" Levelset. Tileset names are always 5 characters long.\n"); printf("3) Edit Enemies\n"); printf(" This runs the Enemy Editor. You can add/remove enemies, change how they\n"); printf(" look, what they do, how strong they are and how fast they are.\n"); printf("4) Place Enemies\n"); printf(" This is where you place enemies in the levels you have designed.\n"); printf("5) Edit End-of-Level Bosses\n"); printf(" Runs the End-of-Level Boss Editor. You can adjust the features of all\n"); printf(" the Bosses in your Levelset.\n"); printf("6) Online Help\n"); printf(" Shows this help screen.\n"); printf("7) Save Levelset\n"); printf(" Save your Levelset without exiting.\n"); printf("8) Exit (no save)\n"); printf(" Exit without saving, useful if you have made a mistake.\n"); getch(); } ///////////////////////////////////////////////// // changeTileset - Use a different Tileset // // Input: void // Output: void ///////////////////////////////////////////////// void changeTileset(void) { char oldTilesetName[6], str[81]; strcpy(oldTilesetName, tilesetName); clrscr(); printf("\nChange Tileset\n\n"); printf("Old Tileset: %s\n", tilesetName); printf("Enter new Tileset (5 chars.): "); gets(str); if (strlen(str) != 5) { printf("Invalid Tileset name!\n"); getch(); return; } strcpy(tilesetName, strupr(str)); if ((loadTileset()) != NULL) { printf("Error loading Tileset \"%s\"!\n", tilesetName); getch(); strcpy(tilesetName, oldTilesetName); loadTileset(); return; } } ///////////////////////////////////////////////// // checkFileExists - Check to see if a Levelset already exists // // Input: char => Name of file to check for // Output: FILE => Start of file if it exists, NULL if doesn't exist ///////////////////////////////////////////////// FILE *checkFileExists(char *name) { return (fopen(name, "rb")); } ///////////////////////////////////////////////// // createNewLevelset - Initialise all Levelset vars to default // // Input: void // Output: void ///////////////////////////////////////////////// void createNewLevelset(void) { register int i, j, k; numLevels = numEnemies = 1; hiScore = 0; strcpy(tilesetName, "TCPA1"); for (i = 0; i < 20; i++) { for (j = 0; j < 16; j++) enemyData[i].sprite[j] = 0; enemyData[i].ai1 = 0; enemyData[i].ai2 = 0; enemyData[i].energy = 1; enemyData[i].speed = 0x01; enemyData[i].bonusItem = 0; } for (i = 0; i < 5; i++) { levelData[i].guardianXSize = 1; levelData[i].guardianYSize = 1; for (j = 0; j < 16; j++) levelData[i].gSpriteTL[j] = 0; for (j = 0; j < 16; j++) levelData[i].gSpriteTR[j] = 0; for (j = 0; j < 16; j++) levelData[i].gSpriteBL[j] = 0; for (j = 0; j < 16; j++) levelData[i].gSpriteBR[j] = 0; levelData[i].guardianAI1 = 0; levelData[i].guardianAI2 = 0; levelData[i].gEnergy = 100; levelData[i].gClearScreen = 0; levelData[i].gX = 96 - 16; levelData[i].gY = 2 * 8 + 4; levelData[i].gEnemy = 0; levelData[i].length = 20; levelData[i].numEnemies = 0; levelData[i].cp1 = 0; levelData[i].cp2 = 0; levelData[i].cp3 = 0; for (j = 0; j < MAX_ENEMIES; j++) for (k = 0; k < 4; k++) levelData[i].enemyData[j][k] = 0; for (j = 0; j < 200; j++) for (k = 0; k < 7; k++) levelData[i].tileData[j][k] = 0; } } ///////////////////////////////////////////////// // loadLevelset - Load a Levelset from a file to memory // // Input: FILE => Start of Levelset file // Output: int = 0 if Levelset loaded successfully ///////////////////////////////////////////////// int loadLevelset(FILE *fp) { char detect[12]; register int i, j = 0; // Clear all variables createNewLevelset(); // Start reading data j += fread(detect, 9, 1, fp); j += fread(&numLevels, 1, 1, fp); j += fread(&numEnemies, 1, 1, fp); j += fread(&hiScore, 2, 1, fp); j += fread(tilesetName, 5, 1, fp); for (i = 0; i < numEnemies; i++) j += fread(&enemyData[i], sizeof(enemyData[i]), 1, fp); for (i = 0; i < numLevels; i++) { j += fread(&levelData[i], sizeof(levelData[i]) - (200 * 7) - (MAX_ENEMIES * 4), 1, fp); if (levelData[i].numEnemies) j += fread(levelData[i].enemyData, levelData[i].numEnemies * 4, 1, fp); else j++; j += fread(levelData[i].tileData, levelData[i].length * 7, 1, fp); } fclose(fp); if (j != (5 + numEnemies + (3 * numLevels))) return 1; return 0; } ///////////////////////////////////////////////// // saveLevelset - Save a Levelset from memory to a file // // Input: char => Name of file to save to // Output: int = 0 if Levelset saved successfully ///////////////////////////////////////////////// int saveLevelset(char *name) { FILE *fp; char detect[12]; register int i, j = 0; // Create file fp = fopen(name, "wb"); // Create detection string strcpy(detect, "I0L_"); strncat(detect, strupr(name)+3, 5); // Start writing data j += fwrite(detect, 9, 1, fp); j += fwrite(&numLevels, 1, 1, fp); j += fwrite(&numEnemies, 1, 1, fp); j += fwrite(&hiScore, 2, 1, fp); j += fwrite(tilesetName, 5, 1, fp); for (i = 0; i < numEnemies; i++) j += fwrite(&enemyData[i], sizeof(enemyData[i]), 1, fp); for (i = 0; i < numLevels; i++) { j += fwrite(&levelData[i], sizeof(levelData[i]) - (200 * 7) - (MAX_ENEMIES * 4), 1, fp); if (levelData[i].numEnemies) j += fwrite(levelData[i].enemyData, levelData[i].numEnemies * 4, 1, fp); else j++; j += fwrite(levelData[i].tileData, levelData[i].length * 7, 1, fp); } fclose(fp); if (j != (5 + numEnemies + (3 * numLevels))) return 1; return 0; } ///////////////////////////////////////////////// // loadTileset - Load a Tileset from a file to memory // // Input: char => Name of Tileset // Output: int = 0 if Tileset loaded successfully ///////////////////////////////////////////////// int loadTileset(void) { FILE *fp; register i, j, k = 0; // Work out filename of Tileset strcpy(tilesetFileName, "zit"); strcat(tilesetFileName, tilesetName); strcat(tilesetFileName, ".bin"); // Try to open Tileset file fp = fopen(tilesetFileName, "rb"); if (fp == NULL) return 1; // Clear Tileset variable for (i =0; i < 256; i++) for (j = 0; j < 8; j++) tileset[i][j] = 0; // Read header data from Tileset file k += fread(tilesetDetect, 9, 1, fp); k += fread(&numTiles, 1, 1, fp); k += fread(&solidTiles, 1, 1, fp); k += fread(&hurtyTiles, 1, 1, fp); // Read tile data from Tileset file for (i = 0; i < numTiles; i++) k += fread(tileset[i], 8, 1, fp); // Check to make sure file was read successfully & leave fclose(fp); if (k != (4 + numTiles)) return 1; return 0; } ///////////////////////////////////////////////// // putSprite - Put a sprite to the graphics screen // // Input: int = X Coord // int = Y Coord // unsigned char => Sprite data (8 bytes) // Output: void ///////////////////////////////////////////////// void putSprite(int x, int y, unsigned char *spr) { register int row, col, color; register unsigned char bitmask; for (row = 0; row < 8; row++, spr++) { bitmask = 0x80; for (col = 0; col < 8; col++) { if ((*spr & bitmask) == NULL) color = 3; else color = 0; putpixel(col+x, row+y, color); bitmask >>= 1; } } } ///////////////////////////////////////////////// // putMaskedSprite - Put an 8x8 masked sprite to graphics screen // // Input: int = X Coord // int = Y Coord // unsigned char => Sprite data (8 bytes, followed by 8 byte mask) // Output: void ///////////////////////////////////////////////// void putMaskedSprite(int x, int y, unsigned char *spr) { register int row, col, color; register unsigned char bitmask; for (row = 0; row < 8; row++, spr++) { bitmask = 0x80; for (col = 0; col < 8; col++) { if (((*(spr+8)) & bitmask)) { if ((*spr & bitmask) == NULL) color = 3; else color = 0; putpixel(col+x, row+y, color); } bitmask >>= 1; } } } ///////////////////////////////////////////////// // putSpriteLarge - Put a sprite to the graphics screen, but draw it large // // Input: int = X Coord // int = Y Coord // unsigned char => Sprite data (8 bytes) // Output: void ///////////////////////////////////////////////// void putSpriteLarge(int x, int y, unsigned char *spr) { register int row, col, color; register unsigned char bitmask; for (row = 0; row < 32; row += 4, spr++) { bitmask = 0x80; for (col = 0; col < 32; col += 4) { if ((*spr & bitmask) == NULL) color = 3; else color = 0; putpixel(col+x+0, row+y+0, color); putpixel(col+x+1, row+y+0, color); putpixel(col+x+2, row+y+0, color); putpixel(col+x+3, row+y+0, color); putpixel(col+x+0, row+y+1, color); putpixel(col+x+1, row+y+1, color); putpixel(col+x+2, row+y+1, color); putpixel(col+x+3, row+y+1, color); putpixel(col+x+0, row+y+2, color); putpixel(col+x+1, row+y+2, color); putpixel(col+x+2, row+y+2, color); putpixel(col+x+3, row+y+2, color); putpixel(col+x+0, row+y+3, color); putpixel(col+x+1, row+y+3, color); putpixel(col+x+2, row+y+3, color); putpixel(col+x+3, row+y+3, color); bitmask >>= 1; } } } ///////////////////////////////////////////////// // showTileset - Display the entire Tileset at the bottom of the screen // // Input: void // Output: void ///////////////////////////////////////////////// void showTileset(void) { register int num = 0, x, y; for (y = 118; y < 198; y++) for (x = 0; x < 320; x++) putpixel(x, y, 1); for (y = 119; y < 199; y += 10) for (x = 1; x < 320; x +=10, num++) putSprite(x, y, tileset[num]); } ///////////////////////////////////////////////// // highlightTileset - Put a box around the selected tile in the Tileset and show where solid/hurty tiles begin // // Input: int = Tile number to highlight // int = 0 to erase box, 1 to draw box // Output: void ///////////////////////////////////////////////// void highlightTileset(int tile, int mode) { int x, y; y = (int)solidTiles / 32; y *= 10; y += 118; x = (int)solidTiles % 32; x *= 10; drawBox(x, y, 10, 10, 0); y = (int)hurtyTiles / 32; y *= 10; y += 118; x = (int)hurtyTiles % 32; x *= 10; drawBox(x, y, 10, 10, 0); y = tile / 32; y *= 10; y += 118; x = tile % 32; x *= 10; drawBox(x, y, 10, 10, mode+1); } ///////////////////////////////////////////////// // highlightBlock - Put a box around currently selected block // // Input: int = X coord on screen // int = Y coord on screen // Output: void ///////////////////////////////////////////////// void highlightBlock(int x, int y) { y *= 8; y += 55; x *= 8; x += 112; drawBox(x, y, 8, 8, 2); } ///////////////////////////////////////////////// // drawBox - Put a box whereever // // Input: int = X coord on screen // int = Y coord on screen // int = Width // int = Height // int = Color // Output: void ///////////////////////////////////////////////// void drawBox(int x, int y, int w, int h, int c) { setcolor(c); setlinestyle(SOLID_LINE, 0, NORM_WIDTH); w--; h--; line(x, y, x+w, y); line(x, y+h, x+w, y+h); line(x, y, x, y+h); line(x+w, y, x+w, y+h); } ///////////////////////////////////////////////// // drawLevel - Draw a level // // Input: int = Level to draw // int = X offset to start drawing from // Output: void ///////////////////////////////////////////////// void drawLevel(int level, int xOffset) { int xScr = 112, yScr, yOffset, xCnt, yCnt; for (xCnt = 0; xCnt < 12; xCnt++, xOffset++, xScr += 8) for (yCnt = 0, yOffset = 0, yScr = 55; yCnt < 7; yCnt++, yOffset++, yScr +=8) putSprite(xScr, yScr, tileset[levelData[level].tileData[xOffset][yOffset]]); setcolor(1); setlinestyle(SOLID_LINE, 0, NORM_WIDTH); line(111, 54, 111+97, 54); line(111, 54+57, 111+97, 54+57); line(111, 54, 111, 54+57); line(111+97, 54, 111+97, 54+57); } ///////////////////////////////////////////////// // levelsetHelp - Help screen for Levelset Editor // // Input: void // Output: void ///////////////////////////////////////////////// void levelsetHelp(void) { cleardevice(); gotoxy(1, 1); printf("Key Summary\n\n"); printf("Arrow keys - Move around in level\n"); printf("HOME, END,\n"); printf("DEL, PGDOWN - Change tile selection\n"); printf("<, > - Scroll left/right\n"); printf("SPACEBAR - Place tile\n"); printf("ESCAPE - Return to Main Menu\n"); printf("1 - Set checkpoint 1\n"); printf("2 - Set checkpoint 2\n"); printf("3 - Set checkpoint 3\n"); printf("F1 - This help screen\n"); printf("F2 - Find & Replace\n"); printf("F3 - Insert tile\n"); printf("F4 - Remove tile\n"); printf("F5 - Decrease number of levels\n"); printf("F6 - Increase number of levels\n"); printf("F7 - Move to previous level\n"); printf("F8 - Move to next level\n"); printf("F9 - Remove column at cursor\n"); printf("F10 - Insert column at cursor\n"); getch(); cleardevice(); showTileset(); } ///////////////////////////////////////////////// // findAndReplace - Find and replace routine // // Input: void // Output: void ///////////////////////////////////////////////// void findAndReplace(void) { int x, y, l; unsigned char f, r; char str[81]; cleardevice(); gotoxy(1, 1); printf("FIND & REPLACE\n\n"); printf("Find tile number: "); gets(str); f = (unsigned char)atoi(str); printf("Replace with tile number: "); gets(str); r = (unsigned char)atoi(str); for (l = 0; l < 5; l++) for (x = 0; x < 200; x++) for (y = 0; y < 7; y++) if (levelData[l].tileData[x][y] == f) levelData[l].tileData[x][y] = r; cleardevice(); showTileset(); } ///////////////////////////////////////////////// // insertTile - Insert a tile // // Input: void // Output: void ///////////////////////////////////////////////// void insertTile(void) { register int x, y, l; unsigned char t; char str[81]; cleardevice(); gotoxy(1, 1); printf("INSERT TILE\n\n"); printf("(Enter 255 to Cancel)\n"); printf("Insert tile at number: "); gets(str); t = (unsigned char)atoi(str); if (t == 255) { cleardevice(); showTileset(); return; } for (l = 0; l < 5; l++) for (x = 0; x < 200; x++) for (y = 0; y < 7; y++) if (levelData[l].tileData[x][y] >= t) levelData[l].tileData[x][y]++; cleardevice(); showTileset(); } ///////////////////////////////////////////////// // removeTile - Remove a tile // // Input: void // Output: void ///////////////////////////////////////////////// void removeTile(void) { register int x, y, l; unsigned char t; char str[81]; cleardevice(); gotoxy(1, 1); printf("REMOVE TILE\n\n"); printf("(Enter 255 to Cancel)\n"); printf("Remove tile number: "); gets(str); t = (unsigned char)atoi(str); if (t == 255) { cleardevice(); showTileset(); return; } for (l = 0; l < 5; l++) for (x = 0; x < 200; x++) for (y = 0; y < 7; y++) if (levelData[l].tileData[x][y] > t) levelData[l].tileData[x][y]--; cleardevice(); showTileset(); } ///////////////////////////////////////////////// // editLevelset - Run editting screen for Levelset // // Input: void // Output: void ///////////////////////////////////////////////// void editLevelset(void) { // Local vars to editting unsigned char tileNumber = 0, quit = 0, xOffset = 0, level = 0, x = 0, y = 0; register int i, j; // Try to set graphics mode, if can't, return to menu if (setGraphicsMode() != NULL) { getch(); return; } showTileset(); while (1) { gotoxy(1, 1); printf("LEVEL EDITOR"); gotoxy(24, 1); printf("Press F1 for help\n"); printf("X: %3d/%3d", (int)(x+xOffset), (int)(levelData[level].length-1)); gotoxy(20, 3); printf("Selected Tile: %3d", (int)tileNumber); gotoxy(20, 4); printf("Selected Block: %3d", (int)levelData[level].tileData[x+xOffset][y]); gotoxy(1, 8); printf("Tileset: %s\n\n", tilesetName); printf("Level: %2d/%2d\n", (int)(level+1), (int)numLevels); gotoxy(28, 8); printf("Checkpoint 1:"); gotoxy(30, 9); printf("%3d", levelData[level].cp1); gotoxy(28, 10); printf("Checkpoint 2:"); gotoxy(30, 11); printf("%3d", levelData[level].cp2); gotoxy(28, 12); printf("Checkpoint 3:"); gotoxy(30, 13); printf("%3d", levelData[level].cp3); highlightTileset((int)tileNumber, 1); drawLevel((int)level, (int)xOffset); highlightBlock((int)x, (int)y); switch (getch()) { case K_ESC: quit = 1; break; case K_SPACE: levelData[level].tileData[x+xOffset][y] = tileNumber; break; case K_SMALLERTHAN: if (xOffset != 0) xOffset--; break; case K_GREATERTHAN: if ((xOffset + 12) != levelData[level].length) xOffset++; break; case K_PLUS: if (levelData[level].length < 200) levelData[level].length++; break; case K_MINUS: if (levelData[level].length > 20) levelData[level].length--; if ((xOffset + 12) > levelData[level].length) xOffset--; break; case K_1: levelData[level].cp1 = xOffset; break; case K_2: levelData[level].cp2 = xOffset; break; case K_3: levelData[level].cp3 = xOffset; break; case 0: // Extended keycode switch (getch()) { case K_UP: if (y != 0) y--; break; case K_DOWN: if (y != 6) y++; break; case K_LEFT: if (x != 0) x--; break; case K_RIGHT: if (x != 11) x++; break; case K_HOME: highlightTileset((int)tileNumber, 0); tileNumber -= 32; break; case K_END: highlightTileset((int)tileNumber, 0); tileNumber += 32; break; case K_DELETE: highlightTileset((int)tileNumber, 0); tileNumber--; break; case K_PGDOWN: highlightTileset((int)tileNumber, 0); tileNumber++; break; case K_F1: levelsetHelp(); break; case K_F2: findAndReplace(); break; case K_F3: insertTile(); break; case K_F4: removeTile(); break; case K_F5: if (numLevels == 1) break; if ((level + 1) == numLevels) break; numLevels--; break; case K_F6: if (numLevels < 5) numLevels++; break; case K_F7: if (level > 0) { level--; xOffset = x = y = 0; } break; case K_F8: if ((level < 4) && ((level + 1) < numLevels)) { level++; xOffset = x = y = 0; } break; case K_F9: if (levelData[level].length <= 20) break; for (i = (xOffset + x); i < 200; i++) for (j = 0; j < 7; j++) levelData[level].tileData[i][j] = levelData[level].tileData[i+1][j]; levelData[level].length--; if ((xOffset + 12) > levelData[level].length) xOffset--; break; case K_F10: if (levelData[level].length >= 200) break; levelData[level].length++; for (i = 199; i > (int)(xOffset + x); i--) for (j = 0; j < 7; j++) levelData[level].tileData[i][j] = levelData[level].tileData[i-1][j]; for (j = 0; j < 7; j++) levelData[level].tileData[x + xOffset][j] = 0; break; } } if (quit) break; } closegraph(); } ///////////////////////////////////////////////// // enemyHelp - Help screen for Enemy Editor // // Input: void // Output: void ///////////////////////////////////////////////// void enemyHelp(void) { cleardevice(); gotoxy(1, 1); printf("Key Summary\n\n"); printf("Arrow keys - Move cursor\n"); printf("SPACEBAR - Toggle pixel\n"); printf("ESCAPE - Return to Main Menu\n"); printf("ENTER - Toggle mode\n"); printf("CTRL+A - Flip sprite vertically\n"); printf("CTRL+S - Flip sprite horizontally\n"); printf("CTRL+D - Copy enemy attributes\n"); printf("CTRL+F - Paste enemy attributes\n"); printf("CTRL+G - Toggle bonus item\n"); printf("F1 - This help screen\n"); printf("F2 - Change speed\n"); printf("F3 - Decrease strength\n"); printf("F4 - Increase strength\n"); printf("F5 - Decrease number of enemies"); printf("F6 - Increase number of enemies"); printf("F7 - Move to previous enemy\n"); printf("F8 - Move to next enemy\n"); printf("F9 - Change AI Script 1\n"); printf("F10 - Change AI Script 2\n"); getch(); cleardevice(); } ///////////////////////////////////////////////// // showAIScript - Show the name of an AI script // // Input: int = Number of AI script // Output: void ///////////////////////////////////////////////// void showAIScript(int n) { printf(aiScripts[n]); } ///////////////////////////////////////////////// // swapUnsignedChars - Swap two unsigned characters // // Input: unsigned char => First value // unsigned char => Second value // Output: void ///////////////////////////////////////////////// void swapUnsignedChars(unsigned char *first, unsigned char *second) { unsigned char t; t = *first; *first = *second; *second = t; } ///////////////////////////////////////////////// // reverseUnsignedChar - Reverse the bit order in an unsigned character // // Input: unsigned char => Byte to reverse // Output: void ///////////////////////////////////////////////// void reverseUnsignedChar(unsigned char *byte) { unsigned char bitmask = 0x80, outmask = 0x01, out = 0; register i; for (i = 0; i < 8; i++) { if ((*byte) & bitmask) out |= outmask; bitmask >>= 1; outmask <<= 1; } *byte = out; } ///////////////////////////////////////////////// // editEnemies - Run editting screen for enemies // // Input: void // Output: void ///////////////////////////////////////////////// void editEnemies(void) { // Local vars for editting unsigned char enemy = 0, quit = 0, x = 0, y = 0, mode = 0, bitmask = 0x80; enemyStructure enemyBuffer; register int i; // Clear clipboard structure for (i = 0; i < 16; i++) enemyBuffer.sprite[i] = 0; enemyBuffer.ai1 = 0; enemyBuffer.ai2 = 0; enemyBuffer.energy = 1; enemyBuffer.speed = 0x01; // Try to set graphics mode, if can't, return to menu if (setGraphicsMode() != NULL) { getch(); return; } while (1) { gotoxy(1, 1); printf("ENEMY EDITOR"); gotoxy(24, 1); printf("Press F1 for help\n"); printf("Number of enemies: %d \n", (int)numEnemies); printf("Current enemy number: %d \n", (int)(enemy+1)); gotoxy(13, 7); printf("Preview:"); drawBox(164, 47, 10, 10, 1); putSprite(165, 48, enemyData[enemy].sprite); drawBox(180, 47, 10, 10, 1); putSprite(181, 48, checkeredSprite); putMaskedSprite(181, 48, enemyData[enemy].sprite); gotoxy(1, 9); printf("Mode: "); if (mode == 0) printf("Sprite"); else printf("Mask "); putSpriteLarge(96, 90, enemyData[enemy].sprite); putSpriteLarge(160, 90, enemyData[enemy].sprite+8); drawBox(95, 89, 34, 34, 1); drawBox(95+64, 89, 34, 34, 1); drawBox(96 + (4 * x) + (64 * mode), 90 + (4 * y), 4, 4, 2); gotoxy(12, 11); printf("Sprite Mask"); gotoxy(1, 17); printf("Strength: %d \n", (int)enemyData[enemy].energy); printf("Speed: "); switch (enemyData[enemy].speed) { case 0x00: printf("Fast "); break; case 0x01: printf("Normal"); break; case 0x03: printf("Slow "); break; } printf("\n\nBonus Item: "); switch (enemyData[enemy].bonusItem) { case 0: printf("None "); break; case 1: printf("Life/Score "); break; case 2: printf("Orb - Power Gun "); break; case 3: printf("Orb - Two-Way Gun "); break; case 4: printf("Orb - Vertical Gun"); break; } printf("\n\nAI Script 1: "); showAIScript((int)enemyData[enemy].ai1); printf("\nAI Script 2: "); showAIScript((int)enemyData[enemy].ai2); switch (getch()) { case K_ESC: quit = 1; break; case K_SPACE: enemyData[enemy].sprite[y + (8*mode)] ^= bitmask; break; case K_ENTER: if (mode == 0) mode = 1; else mode = 0; break; case K_CTRLG: if (++enemyData[enemy].bonusItem >= 5) enemyData[enemy].bonusItem = 0; break; case K_CTRLD: for (i = 0; i < 16; i++) enemyBuffer.sprite[i] = enemyData[enemy].sprite[i]; enemyBuffer.ai1 = enemyData[enemy].ai1; enemyBuffer.ai2 = enemyData[enemy].ai2; enemyBuffer.energy = enemyData[enemy].energy; enemyBuffer.speed = enemyData[enemy].speed; enemyBuffer.bonusItem = enemyData[enemy].bonusItem; break; case K_CTRLF: for (i = 0; i < 16; i++) enemyData[enemy].sprite[i] = enemyBuffer.sprite[i]; enemyData[enemy].ai1 = enemyBuffer.ai1; enemyData[enemy].ai2 = enemyBuffer.ai2; enemyData[enemy].energy = enemyBuffer.energy; enemyData[enemy].speed = enemyBuffer.speed; enemyData[enemy].bonusItem = enemyBuffer.bonusItem; break; case K_CTRLA: swapUnsignedChars(&enemyData[enemy].sprite[0], &enemyData[enemy].sprite[7]); swapUnsignedChars(&enemyData[enemy].sprite[1], &enemyData[enemy].sprite[6]); swapUnsignedChars(&enemyData[enemy].sprite[2], &enemyData[enemy].sprite[5]); swapUnsignedChars(&enemyData[enemy].sprite[3], &enemyData[enemy].sprite[4]); swapUnsignedChars(&enemyData[enemy].sprite[8], &enemyData[enemy].sprite[15]); swapUnsignedChars(&enemyData[enemy].sprite[9], &enemyData[enemy].sprite[14]); swapUnsignedChars(&enemyData[enemy].sprite[10], &enemyData[enemy].sprite[13]); swapUnsignedChars(&enemyData[enemy].sprite[11], &enemyData[enemy].sprite[12]); break; case K_CTRLS: for (i = 0; i < 16; i++) reverseUnsignedChar(&enemyData[enemy].sprite[i]); break; case 0: // Extended keycode switch (getch()) { case K_UP: if (y != 0) y--; break; case K_DOWN: if (y != 7) y++; break; case K_LEFT: if (x != 0) { x--; bitmask <<= 1; } break; case K_RIGHT: if (x != 7) { x++; bitmask >>= 1; } break; case K_F1: enemyHelp(); break; case K_F2: switch (enemyData[enemy].speed) { case 0x00: enemyData[enemy].speed = 0x03; break; case 0x01: enemyData[enemy].speed = 0x00; break; case 0x03: enemyData[enemy].speed = 0x01; break; } break; case K_F3: if (enemyData[enemy].energy > 1) enemyData[enemy].energy--; break; case K_F4: if (enemyData[enemy].energy < 128) enemyData[enemy].energy++; break; case K_F5: if (numEnemies == 1) break; if ((enemy + 1) == numEnemies) break; numEnemies--; break; case K_F6: if (numEnemies < 20) numEnemies++; break; case K_F7: if (enemy > 0) { enemy--; x = y = 0; bitmask = 0x80; } break; case K_F8: if ((enemy < 19) && ((enemy + 1) < numEnemies)) { enemy++; x = y = 0; bitmask = 0x80; } break; case K_F9: enemyData[enemy].ai1++; if (enemyData[enemy].ai1 == (sizeof(aiScripts)/sizeof(char *))) enemyData[enemy].ai1 = 0; break; case K_F10: enemyData[enemy].ai2++; if (enemyData[enemy].ai2 == (sizeof(aiScripts)/sizeof(char *))) enemyData[enemy].ai2 = 0; break; } } if (quit) break; } closegraph(); } ///////////////////////////////////////////////// // enemyPlacementHelp - Show help screen for enemy placement // // Input: void // Output: void ///////////////////////////////////////////////// void enemyPlacementHelp(void) { cleardevice(); gotoxy(1, 1); printf("Key Summary\n\n"); printf("UP, DOWN - Browse through enemies on "); printf(" screen\n"); printf("HOME, END,\n"); printf("DEL, PGDOWN - Move selected enemy\n"); printf("ESCAPE - Return to Main Menu\n"); printf("<, > - Scroll left/right\n"); printf("1,2,3,4,5,\n"); printf("6,7,8,9,0,\n"); printf("q,w,e,r,t,\n"); printf("y,u,i,o,p - Put enemy\n"); printf("BACKSPACE - Remove selected enemy\n"); printf("F1 - This help screen\n"); printf("F5 - Enemy at top of screen\n"); printf("F6 - Enemy at bottom of screen\n"); printf("F7 - Enemy at left of screen\n"); printf("F8 - Enemy at right of screen\n"); printf("F9 - Move to previous level\n"); printf("F10 - Move to next level\n"); getch(); cleardevice(); } ///////////////////////////////////////////////// // putEnemy - Add an enemy to the current level // // Input: unsigned char = Level to put enemy on // char = Type of enemy to put // char = blockX that triggers the enemy // Output: int = 0 if failed ///////////////////////////////////////////////// int putEnemy(unsigned char level, char type, char blockX) { register int i; for (i = 0; i < MAX_ENEMIES, levelData[level].enemyData[i][E_TYPE]; i++); if (i == MAX_ENEMIES) return 0; levelData[level].enemyData[i][E_TYPE] = type; levelData[level].enemyData[i][E_BLOCKX] = blockX; levelData[level].enemyData[i][E_X] = 95; levelData[level].enemyData[i][E_Y] = 3 * 8; return 1; } ///////////////////////////////////////////////// // swapEnemyEntries - Swap 2 entries in enemy placement array // // Input: int = Level that entries are located on // int = Index of first entry // int = Index of second entry // Output: void ///////////////////////////////////////////////// void swapEnemyEntries(int i, int j, int k) { char temp[4]; temp[E_TYPE] = levelData[i].enemyData[j][E_TYPE]; temp[E_BLOCKX] = levelData[i].enemyData[j][E_BLOCKX]; temp[E_X] = levelData[i].enemyData[j][E_X]; temp[E_Y] = levelData[i].enemyData[j][E_Y]; levelData[i].enemyData[j][E_TYPE] = levelData[i].enemyData[k][E_TYPE]; levelData[i].enemyData[j][E_BLOCKX] = levelData[i].enemyData[k][E_BLOCKX]; levelData[i].enemyData[j][E_X] = levelData[i].enemyData[k][E_X]; levelData[i].enemyData[j][E_Y] = levelData[i].enemyData[k][E_Y]; levelData[i].enemyData[k][E_TYPE] = temp[E_TYPE]; levelData[i].enemyData[k][E_BLOCKX] = temp[E_BLOCKX]; levelData[i].enemyData[k][E_X] = temp[E_X]; levelData[i].enemyData[k][E_Y] = temp[E_Y]; } ///////////////////////////////////////////////// // placeEnemies - Screen where you can place enemies in your levels // // Input: void // Output: void ///////////////////////////////////////////////// void placeEnemies(void) { // Local vars unsigned char quit = 0, xOffset = 0, level = 0, selEnemy = 0, thisEnemy = 0, enemiesOnScreen = 0; register int i, j, k; // Try to set graphics mode, if can't, return to menu if (setGraphicsMode() != NULL) { getch(); return; } while (1) { drawLevel((int)level, (int)xOffset); gotoxy(1, 1); printf("ENEMY PLACEMENT TOOL"); gotoxy(24, 1); printf("Press F1 for help\n"); printf("X: %3d/%3d", (int)(xOffset), (int)(levelData[level].length-1)); gotoxy(28, 3); printf("Level: %2d/%2d\n", (int)(level+1), (int)numLevels); printf("Enemies in this level: %d ", (int)levelData[level].numEnemies); gotoxy(1, 16); printf(" Type\n"); // Search through levelData[level].enemyData to print enemies on this screen thisEnemy = 255; for (i = 0, j = 0, enemiesOnScreen = 0; i < MAX_ENEMIES; i++) if ((levelData[level].enemyData[i][E_TYPE]) && ((unsigned char)levelData[level].enemyData[i][E_BLOCKX] == xOffset)) { printf(" %d \n", (int)levelData[level].enemyData[i][E_TYPE]); if (j == selEnemy) { if (levelData[level].enemyData[i][E_Y] == -7) putMaskedSprite((int)levelData[level].enemyData[i][E_X] + 112, 55, enemyData[levelData[level].enemyData[i][E_TYPE]-1].sprite); if (levelData[level].enemyData[i][E_Y] == 55) putMaskedSprite((int)levelData[level].enemyData[i][E_X] + 112, 55 + (6 * 8), enemyData[levelData[level].enemyData[i][E_TYPE]-1].sprite); if (levelData[level].enemyData[i][E_X] == -7) putMaskedSprite(112, (int)levelData[level].enemyData[i][E_Y] + 55, enemyData[levelData[level].enemyData[i][E_TYPE]-1].sprite); if (levelData[level].enemyData[i][E_X] == 95) putMaskedSprite(112 + (11 * 8), (int)levelData[level].enemyData[i][E_Y] + 55, enemyData[levelData[level].enemyData[i][E_TYPE]-1].sprite); thisEnemy = i; } j++; enemiesOnScreen++; } for ( ; j < 5; j++) printf(" \n"); gotoxy(1, 17+(int)selEnemy); printf("->"); switch (getch()) { case K_ESC: quit = 1; break; case K_SMALLERTHAN: if (xOffset != 0) xOffset--; break; case K_GREATERTHAN: if ((xOffset + 12) != levelData[level].length) xOffset++; break; case K_1: if (enemiesOnScreen < 5) if (putEnemy(level, 1, xOffset)) levelData[level].numEnemies++; break; case K_2: if (enemiesOnScreen < 5) if (putEnemy(level, 2, xOffset)) levelData[level].numEnemies++; break; case K_3: if (enemiesOnScreen < 5) if (putEnemy(level, 3, xOffset)) levelData[level].numEnemies++; break; case K_4: if (enemiesOnScreen < 5) if (putEnemy(level, 4, xOffset)) levelData[level].numEnemies++; break; case K_5: if (enemiesOnScreen < 5) if (putEnemy(level, 5, xOffset)) levelData[level].numEnemies++; break; case K_6: if (enemiesOnScreen < 5) if (putEnemy(level, 6, xOffset)) levelData[level].numEnemies++; break; case K_7: if (enemiesOnScreen < 5) if (putEnemy(level, 7, xOffset)) levelData[level].numEnemies++; break; case K_8: if (enemiesOnScreen < 5) if (putEnemy(level, 8, xOffset)) levelData[level].numEnemies++; break; case K_9: if (enemiesOnScreen < 5) if (putEnemy(level, 9, xOffset)) levelData[level].numEnemies++; break; case K_0: if (enemiesOnScreen < 5) if (putEnemy(level, 10, xOffset)) levelData[level].numEnemies++; break; case K_Q: if (enemiesOnScreen < 5) if (putEnemy(level, 11, xOffset)) levelData[level].numEnemies++; break; case K_W: if (enemiesOnScreen < 5) if (putEnemy(level, 12, xOffset)) levelData[level].numEnemies++; break; case K_E: if (enemiesOnScreen < 5) if (putEnemy(level, 13, xOffset)) levelData[level].numEnemies++; break; case K_R: if (enemiesOnScreen < 5) if (putEnemy(level, 14, xOffset)) levelData[level].numEnemies++; break; case K_T: if (enemiesOnScreen < 5) if (putEnemy(level, 15, xOffset)) levelData[level].numEnemies++; break; case K_Y: if (enemiesOnScreen < 5) if (putEnemy(level, 16, xOffset)) levelData[level].numEnemies++; break; case K_U: if (enemiesOnScreen < 5) if (putEnemy(level, 17, xOffset)) levelData[level].numEnemies++; break; case K_I: if (enemiesOnScreen < 5) if (putEnemy(level, 18, xOffset)) levelData[level].numEnemies++; break; case K_O: if (enemiesOnScreen < 5) if (putEnemy(level, 19, xOffset)) levelData[level].numEnemies++; break; case K_P: if (enemiesOnScreen < 5) if (putEnemy(level, 20, xOffset)) levelData[level].numEnemies++; break; case K_BACKSPACE: if (thisEnemy != 255) { levelData[level].numEnemies--; levelData[level].enemyData[thisEnemy][E_TYPE] = 0; } break; case 0: // Extended keycode switch (getch()) { case K_UP: if (selEnemy) selEnemy--; break; case K_DOWN: if (selEnemy < 4) selEnemy++; break; case K_HOME: if ((thisEnemy != 255) && ((levelData[level].enemyData[thisEnemy][E_X] == -7) || (levelData[level].enemyData[thisEnemy][E_X] == 95)) && (levelData[level].enemyData[thisEnemy][E_Y] > 0)) levelData[level].enemyData[thisEnemy][E_Y]--; break; case K_END: if ((thisEnemy != 255) && ((levelData[level].enemyData[thisEnemy][E_X] == -7) || (levelData[level].enemyData[thisEnemy][E_X] == 95)) && (levelData[level].enemyData[thisEnemy][E_Y] < 48)) levelData[level].enemyData[thisEnemy][E_Y]++; break; case K_DELETE: if ((thisEnemy != 255) && ((levelData[level].enemyData[thisEnemy][E_Y] == -7) || (levelData[level].enemyData[thisEnemy][E_Y] == 55)) && (levelData[level].enemyData[thisEnemy][E_X] > 0)) levelData[level].enemyData[thisEnemy][E_X]--; break; case K_PGDOWN: if ((thisEnemy != 255) && ((levelData[level].enemyData[thisEnemy][E_Y] == -7) || (levelData[level].enemyData[thisEnemy][E_Y] == 55)) && (levelData[level].enemyData[thisEnemy][E_X] < 88)) levelData[level].enemyData[thisEnemy][E_X]++; break; case K_F1: enemyPlacementHelp(); break; case K_F5: if (thisEnemy != 255) { levelData[level].enemyData[thisEnemy][E_X] = 5 * 8; levelData[level].enemyData[thisEnemy][E_Y] = -7; } break; case K_F6: if (thisEnemy != 255) { levelData[level].enemyData[thisEnemy][E_X] = 5 * 8; levelData[level].enemyData[thisEnemy][E_Y] = 55; } break; case K_F7: if (thisEnemy != 255) { levelData[level].enemyData[thisEnemy][E_X] = -7; levelData[level].enemyData[thisEnemy][E_Y] = 3 * 8; } break; case K_F8: if (thisEnemy != 255) { levelData[level].enemyData[thisEnemy][E_X] = 95; levelData[level].enemyData[thisEnemy][E_Y] = 3 * 8; } break; case K_F9: if (level > 0) { level--; xOffset = selEnemy = 0; } break; case K_F10: if (level < (numLevels - 1)) { level++; xOffset = selEnemy = 0; } break; } } if (quit) break; } closegraph(); // Now we need to sort all the enemy placement data // First, stack all enemies at start of array, ie. move all empty entries to rear of array for (i = 0; i < 5; i++) for (j = 0; j < MAX_ENEMIES; j++) if (levelData[i].enemyData[j][E_TYPE] == 0) for (k = j; k < (MAX_ENEMIES - 1); k++) swapEnemyEntries(i, k, k+1); // Now sort the occupied entries in ascending order by the E_BLOCKX cell for (i = 0; i < 5; i++) for (j = 0; j < levelData[i].numEnemies; j++) for (k = 0; k < (levelData[i].numEnemies - 1); k++) if ((unsigned char)levelData[i].enemyData[k][E_BLOCKX] > (unsigned char)levelData[i].enemyData[k+1][E_BLOCKX]) swapEnemyEntries(i, k, k+1); } ///////////////////////////////////////////////// // guardianHelp - Help screen for End-Of-Level Boss Editor // // Input: void // Output: void ///////////////////////////////////////////////// void guardianHelp(void) { cleardevice(); gotoxy(1, 1); printf("Key Summary\n\n"); printf("Arrow keys - Move cursor\n"); printf("SPACEBAR - Toggle pixel\n"); printf("ESCAPE - Return to Main Menu\n"); printf("ENTER - Toggle mode\n"); printf("TAB - Toggle enemy\n"); printf("1-4 - Edit that sprite\n"); printf("CTRL+A - Decrease X Coord\n"); printf("CTRL+S - Increase X Coord\n"); printf("CTRL+D - Decrease Y Coord\n"); printf("CTRL+F - Increase X Coord\n"); printf("F1 - This help screen\n"); printf("F2 - Toggle clear screen\n"); printf("F3 - Decrease strength\n"); printf("F4 - Increase strength\n"); printf("F5 - Toggle Y size\n"); printf("F6 - Toggle X size\n"); printf("F7 - Change AI Script 1\n"); printf("F8 - Change AI Script 2\n"); printf("F9 - Move to previous level\n"); printf("F10 - Move to next level\n"); getch(); cleardevice(); } ///////////////////////////////////////////////// // editGuardians - Run editting screen for end-of-level bosses // // Input: void // Output: void ///////////////////////////////////////////////// void editGuardians(void) { // Local vars for editting unsigned char level = 0, quit = 0, x = 0, y = 0, mode = 0, bitmask = 0x80, sprite = 0; // Try to set graphics mode, if can't, return to menu if (setGraphicsMode() != NULL) { getch(); return; } while (1) { gotoxy(1, 1); printf("END-OF-LEVEL\nBOSS EDITOR"); gotoxy(24, 1); printf("Press F1 for help\n"); gotoxy(1, 4); printf("Level: %2d/%2d", (int)level + 1, (int)numLevels); gotoxy(20, 4); printf("Size: %dx%d \n", (int)(levelData[level].guardianYSize * 8) + 8, (int)(levelData[level].guardianXSize * 8) + 8); printf("Enemy: "); if (levelData[level].gEnemy) printf("%d ", levelData[level].gEnemy); else printf("None"); gotoxy(13, 7); printf("Preview:"); drawBox(164, 43, 18, 18, 1); putSprite(165, 44, levelData[level].gSpriteTL); putSprite(165+8, 44, levelData[level].gSpriteTR); putSprite(165, 44+8, levelData[level].gSpriteBL); putSprite(165+8, 44+8, levelData[level].gSpriteBR); drawBox(185, 43, 18, 18, 1); putSprite(186, 44, checkeredSprite); putSprite(186+8, 44, checkeredSprite); putSprite(186, 44+8, checkeredSprite); putSprite(186+8, 44+8, checkeredSprite); putMaskedSprite(186, 44, levelData[level].gSpriteTL); putMaskedSprite(186+8, 44, levelData[level].gSpriteTR); putMaskedSprite(186, 44+8, levelData[level].gSpriteBL); putMaskedSprite(186+8, 44+8, levelData[level].gSpriteBR); gotoxy(1, 9); printf("Mode: "); if (mode == 0) printf("Sprite"); else printf("Mask "); drawBox(95, 89, 34, 34, 1); drawBox(95+64, 89, 34, 34, 1); gotoxy(12, 11); printf("Sprite Mask\n"); printf("+-+-+\n"); printf("|1|2|\n"); printf("+-+-+\n"); printf("|3|4|\n"); printf("+-+-+\n\n"); printf("Strength: %d \n", (int)levelData[level].gEnergy); printf("Clear Screen? "); if (levelData[level].gClearScreen) printf("Yes\n\n"); else printf("No \n\n"); printf("AI Script 1: "); showAIScript((int)levelData[level].guardianAI1); printf("\nAI Script 2: "); showAIScript((int)levelData[level].guardianAI2); gotoxy(25, 18); printf("X Coord: %d ", (int)levelData[level].gX); gotoxy(25, 19); printf("Y Coord: %d ", (int)levelData[level].gY); putSpriteLarge(96, 90, &levelData[level].gSpriteTL[0 + (16 * sprite)]); putSpriteLarge(160, 90, &levelData[level].gSpriteTL[8 + (16 * sprite)]); drawBox(96 + (4 * x) + (64 * mode), 90 + (4 * y), 4, 4, 2); switch (getch()) { case K_ESC: quit = 1; break; case K_1: sprite = 0; break; case K_2: sprite = 1; break; case K_3: sprite = 2; break; case K_4: sprite = 3; break; case K_SPACE: levelData[level].gSpriteTL[y + (8 * mode) + (16 * sprite)] ^= bitmask; break; case K_ENTER: mode ^= 0x01; break; case K_CTRLA: if (levelData[level].gX > -14) levelData[level].gX--; break; case K_CTRLS: if (levelData[level].gX < 95) levelData[level].gX++; break; case K_CTRLD: if (levelData[level].gY > -14) levelData[level].gY--; break; case K_CTRLF: if (levelData[level].gY < 55) levelData[level].gY++; break; case K_TAB: if (++levelData[level].gEnemy > 20) levelData[level].gEnemy = 0; break; case 0: // Extended keycode switch (getch()) { case K_UP: if (y != 0) y--; break; case K_DOWN: if (y != 7) y++; break; case K_LEFT: if (x != 0) { x--; bitmask <<= 1; } break; case K_RIGHT: if (x != 7) { x++; bitmask >>= 1; } break; case K_F1: guardianHelp(); break; case K_F2: levelData[level].gClearScreen ^= 0x01; break; case K_F3: if (levelData[level].gEnergy > 1) levelData[level].gEnergy--; break; case K_F4: if (levelData[level].gEnergy < 220) levelData[level].gEnergy++; break; case K_F5: levelData[level].guardianYSize ^= 0x01; break; case K_F6: levelData[level].guardianXSize ^= 0x01; break; case K_F7: levelData[level].guardianAI1++; if (levelData[level].guardianAI1 == (sizeof(aiScripts)/sizeof(char *))) levelData[level].guardianAI1 = 0; break; case K_F8: levelData[level].guardianAI2++; if (levelData[level].guardianAI2 == (sizeof(aiScripts)/sizeof(char *))) levelData[level].guardianAI2 = 0; break; case K_F9: if (level > 0) { level--; } break; case K_F10: if (level < (numLevels - 1)) { level++; } break; } } if (quit) break; } closegraph(); }