#include #include #include "config.h" #include "SDL/SDL.h" #include "SDL/SDL_image.h" #include "SDL/SDL_ttf.h" #include "SDL/SDL_mixer.h" #include "enum.h" #include "Engine.h" #include "Player.h" #include "Room.h" #include "Kaos.h" #include "HyperKaos.h" #include "TextBox.h" #include "Scene.h" #include "Synergy.h" #include "WorldData.h" typedef struct timer Timer; #include "extern.h" void bufferData(enum dataChunks chunk) { hasMusic = 0; applySurface(8,8, loadingTxt, screen, NULL); frameAdvance(); printf("Loading map chunk\n"); if(!worldBuilder(chunk)) { quit = 1; playing = 0; printf("Fatal map error. Quitting\n"); return; }; printf("Loaded map chunk\n"); } int hashCmd(char* x) { int hash = 7951; int coef = 181; while (*x) { hash += coef*(*x); x++; } hash %= 256; return hash; } int worldBuilder(enum dataChunks chunk) { char datafile[256]; char lineBuffer[1024]; char cmdBuffer[24]; char cchunk[4]; char propsBuffer[998]; int savequery; int conditional = 0; int (*fp)(char* props); FILE* worldInfo; sprintf(cchunk, "%d", chunk); strcpy(datafile, "mapdata/"); strcat(datafile, cchunk); strcat(datafile, ".txt"); worldInfo = fopen(datafile, "r"); if (!worldInfo) { printf("Couldn't read world data\n"); return 1; } while (fgets(lineBuffer, 1024, worldInfo)) { if (!strcmp(lineBuffer,"\n") || !strcmp(lineBuffer,"\r\n")) continue; if (lineBuffer[0] == '<') { conditional = 0; continue; } if (!conditional) { if (sscanf(lineBuffer, "%[^:]: %[^\t\n]", cmdBuffer, propsBuffer) < 2) { printf("World data line malformed\n"); return 0; } else { switch (hashCmd(cmdBuffer)) { case 106: //if if ((sscanf(propsBuffer, "%d", &savequery) == 1) && notCompleted(savequery)) { conditional = 1; continue; } break; case 15: //ifNot if ((sscanf(propsBuffer, "%d", &savequery) == 1) && hasCompleted(savequery)) { conditional = 1; continue; } break; case 200: //mkRoom fp = &buildRoom; break; case 45: //mkKaos fp = &buildKaos; break; case 109: //mkTextBox fp = &buildTextBox; break; case 181: //addText fp = &modTextBox; break; case 229: //loadFX fp = &buildSFX; break; case 125: //loadBGM fp = &buildBGM; break; case 100: //addSigil fp = &buildSynergy; break; case 47: //addPerson fp = &buildPerson; break; case 88: //addObstruction fp = &buildObstruction; break; case 141: //addImg fp = &buildFGImage; break; case 240: //addTrigger fp = &buildHyper; break; case 148: //chainKaos fp = &chainKaos; break; case 238: //addWarp fp = &buildWarp; break; } if (!fp(propsBuffer)) return 0; } }} fclose(worldInfo); return 1; } int buildBGM(char* props) { #ifdef SOUND_ON int slot; char filename[256]; if (sscanf(props, "slot %u, file %[^\t\n]", &slot, filename) != 2) return 0; bgmData[slot] = loadBGM(filename); #endif return 1; } int buildSFX(char* props) { #ifdef SOUND_ON int slot; char filename[256]; if (sscanf(props, "slot %u, file %[^\t\n]", &slot, filename) != 2) return 0; sfxData[slot] = loadSFX(filename); #endif return 1; } int buildRoom(char* props) { int slot; char filename[256]; int breathe; if (sscanf(props, "slot %u, sprite %[^,], spd %u", &slot, filename, &breathe) != 3) return 0; printf("Building room in map slot %d: bg = %s; spd = %d\n", slot, filename, breathe); mapBuffer[slot] = newRoom(filename, breathe); return 1; } int buildTextBox(char* props) { int slot; char portrait[256]; if (sscanf(props, "slot %u, portrait %[^\n]", &slot, portrait) != 2) return 0; printf("building textbox...\n"); if (strcmp(portrait, "none") != 0) dialogueData[slot] = newTextBox(); else dialogueData[slot] = newGTextBox(loadImage(portrait)); return 1; } int modTextBox(char* props) { int slot; char textData[64]; if (sscanf(props, "slot %u, %[^\n]", &slot, textData) != 2) return 0; printf("adding line of text to textbox...\n"); addText(dialogueData[slot], textData); return 1; } int buildSynergy(char* props) { int rm, x, y, w, h; char d; int spell, effect; if (sscanf(props, "room %u, x %d, y %d, w %u, h %u, spell %u, dir %c, effect %d", &rm, &x, &y, &w, &h, &spell, &d, &effect) != 8) return 0; printf("building synergy...\n"); addSigil(mapBuffer[rm], newSynergy(spell, d, x, y, w, h, mapBuffer[rm]->eventTriggers[effect])); return 1; } int buildKaos(char* props) { int slot; char kType, kProps[990]; Kaos* (*fp)(char* args); fp = NULL; if (sscanf(props, "slot %u, class %c, %[^\n]", &slot, &kType, kProps) != 3) return 0; printf("building kaos...\n"); switch (kType) { case 'C': fp = &newConversation; break; case 'W': fp = &newWait; break; case 'M': fp = &newManip; break; case 'L': fp = &newLook; break; case 'F': fp = &newFaceEachother; break; case 'Y': fp = &newChoice; break; case 'S': #ifdef SOUND_ON fp = &newPlaySound; break; #endif case 'T': fp = &newTeleport; break; case 'E': fp = &newErase; break; } if (fp && !(kaosData[slot] = fp(kProps))) { printf("Malformed args to Kaos or no memory!"); return 0; } return 1; } int buildObstruction(char* props) { int rm, x, y, w, h; if (sscanf(props, "room %u, x %d, y %d, w %u, h %u", &rm, &x, &y, &w, &h) != 5) return 0; printf("Building obstacle...\n"); addObstacle(mapBuffer[rm], x, y, w, h); return 1; } int buildFGImage(char* props) { int rm, x, y, w, h, f, d, a; char filename[256]; if (sscanf(props, "room %u, x %d, y %d, w %u, h %u, sprite %[^,], frames %u, dual %u, alpha %u", &rm, &x, &y, &w, &h, filename, &f, &d, &a) !=9) return 0; printf("Building FG Image...\n"); addFgObj(mapBuffer[rm], x, y, w, h, filename, f, d, a); return 1; } int buildWarp(char* props) { int r, x, y, w, h, dC, dR, dX, dY; if (sscanf(props, "room %u, x %d, y %d, w %u, h %u, dest %u,%u, dX %d, dY %d", &r, &x, &y, &w, &h, &dC, &dR, &dX, &dY) != 9) return 0; printf("Building warp...\n"); addWarp(mapBuffer[r], x, y, w, h, dC, dR, dX, dY); return 1; } int buildHyper(char* props) { int rm, id, tType, x, y, w, h; if (sscanf(props, "room %u, id %u, type %u, x %d, y %d, w %u, h %u", &rm, &id, &tType, &x, &y, &w, &h) != 7) return 0; printf("Building hyperkaos...\n"); HyperKaos* temp = newHyperKaos(id, tType, x, y, w, h); addTrigger(mapBuffer[rm], temp); return 1; } int chainKaos(char* props) { int rm, trig, k; if (sscanf(props, "room %u, trigger %u, kaos %u", &rm, &trig, &k) != 3) return 0; printf("Chaining kaos...\n"); addKaos(mapBuffer[rm]->eventTriggers[trig], kaosData[k]); return 1; } int buildPerson(char* props) { int rm, x, y; char filename[256]; if (sscanf(props, "room %u, sprite %[^,], x %d, y%d", &rm, filename, &x, &y) != 4) return 0; printf("Building person...\n"); Player* temp = newPlayer(filename, x, y); addPerson(mapBuffer[rm], temp); return 1; } int* countMapThings(int* count, enum dataChunks chunk) { char datafile[256]; char lineBuffer[1024]; char cmdBuffer[24]; char propsBuffer[998]; char cchunk[4]; FILE* worldInfo; sprintf(cchunk, "%d", chunk); strcpy(datafile, "mapdata/"); strcat(datafile, cchunk); strcat(datafile, ".txt"); worldInfo = fopen(datafile, "r"); while (fgets(lineBuffer, 1024, worldInfo)) { sscanf(lineBuffer, "%[^:]: %[^\t\n]", cmdBuffer, propsBuffer); switch(hashCmd(cmdBuffer)) { case 200: count[0]++; break; case 45: count[1]++; break; case 109: count[2]++; break; case 229: count[3]++; break; case 125: count[4]++; break; } } return count; } void dataPurge(int* objs) { int i; for (i = 0; i < objs[0]; i++) deleteRoom(mapData[i]); for (i = 0; i < objs[2]; i++) deleteTextBox(dialogueData[i]); for (i = 0; i < objs[1]; i++) kaosData[i]->destroy(kaosData[i]); #ifdef SOUND_ON for (i = 0; i < objs[3]; i++) Mix_FreeMusic(bgmData[i]); for (i = 0; i < objs[4]; i++) Mix_FreeChunk(sfxData[i]); #endif } void unloadData(enum dataChunks chunk) { int thingsCount[5] = {0,0,0,0,0}; printf("Unloading old map chunk\n"); dataPurge(countMapThings(thingsCount, chunk)); printf("Unloaded old map chunk\n"); } void pushBufferData() { printf("Pushing map buffer\n"); mapData = mapBuffer; mapBuffer = (Room**)malloc(64*sizeof(Room*)); #ifdef SOUND_ON if (hasMusic) Mix_PlayMusic(bgmData[0], -1); #endif printf("Map buffer clean\n"); } void pager() { if (thisChunk != nextChunk) { #ifdef SOUND_ON if (Mix_PlayingMusic()) { Mix_HaltMusic(); } #endif unloadData(thisChunk); pushBufferData(); thisChunk=nextChunk; } }