472 lines
No EOL
9.5 KiB
C
472 lines
No EOL
9.5 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|
|
} |