643 lines
No EOL
12 KiB
C
643 lines
No EOL
12 KiB
C
#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 "Timer.h"
|
|
#include "Kaos.h"
|
|
#include "TextBox.h"
|
|
#include "Player.h"
|
|
#include "Room.h"
|
|
#include "HyperKaos.h"
|
|
#include "Scene.h"
|
|
|
|
#include "extern.h"
|
|
|
|
Kaos* rawKaos()
|
|
{
|
|
Kaos* self = malloc(sizeof(Kaos));
|
|
self->next = NULL;
|
|
return self;
|
|
}
|
|
|
|
Kaos* newConversation(char* args)
|
|
{
|
|
int i;
|
|
Kaos* core = rawKaos();
|
|
Conversation* self = malloc(sizeof(Conversation));
|
|
|
|
if (sscanf(args, "textBox %d", &i) != 1)
|
|
{
|
|
free(core);
|
|
free(self);
|
|
self = NULL;
|
|
core = NULL;
|
|
return core;
|
|
}
|
|
|
|
self->index = i;
|
|
|
|
core->kType = self;
|
|
self->core = core;
|
|
core->run = &runConversation;
|
|
core->destroy = &deleteConversation;
|
|
return core;
|
|
}
|
|
|
|
void runConversation(Kaos* self)
|
|
{
|
|
Conversation* kSelf = self->kType;
|
|
displayTextBox(dialogueData[kSelf->index]);
|
|
}
|
|
|
|
void deleteConversation(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newChoice(char* args)
|
|
{
|
|
char q[32], a1[32], a2[32];
|
|
int rm, p1, p2;
|
|
Kaos* core = rawKaos();
|
|
Choice* self = malloc(sizeof(Choice));
|
|
|
|
if (sscanf(args, "q %[^,], a1 %[^,], a2 %[^,], rm %d, p1 %d, p2 %d", q, a1, a2, &rm, &p1, &p2) != 5)
|
|
{
|
|
free(core);
|
|
free(self);
|
|
self = NULL;
|
|
core = NULL;
|
|
return core;
|
|
}
|
|
|
|
self->question = TTF_RenderText_Solid(font, q, textColor);
|
|
self->answ1 = TTF_RenderText_Solid(font, a1, textColor);
|
|
self->answ2 = TTF_RenderText_Solid(font, a2, textColor);
|
|
self->path1 = mapBuffer[rm]->eventTriggers[p1];
|
|
self->path2 = mapBuffer[rm]->eventTriggers[p2];
|
|
|
|
core->kType = self;
|
|
self->core = core;
|
|
core->run = &runChoice;
|
|
core->destroy = &deleteChoice;
|
|
return core;
|
|
}
|
|
|
|
void runChoice(Kaos* self)
|
|
{
|
|
Choice* kSelf = self->kType;
|
|
int choice = 0;
|
|
int textIsRelevent = 1;
|
|
actionbutton = 0;
|
|
while (textIsRelevent)
|
|
{
|
|
timeStart(&fps);
|
|
renderBackground();
|
|
renderForeground();
|
|
|
|
applySurface(22,73, choiceBox, screen, NULL);
|
|
applySurface(74,76, kSelf->question, screen, NULL);
|
|
|
|
applySurface(74,90, kSelf->answ1, screen, NULL);
|
|
applySurface(180,90, kSelf->answ2, screen, NULL);
|
|
|
|
switch(choice)
|
|
{
|
|
case 0: applySurface(59,86, selectArrow, screen, NULL); break;
|
|
case 1: applySurface(165,86, selectArrow, screen, NULL); break;
|
|
}
|
|
|
|
while (SDL_PollEvent(&event))
|
|
{
|
|
switch (event.type)
|
|
{
|
|
case SDL_QUIT: quit = 1; playing = 0; textIsRelevent = 0; break;
|
|
case SDL_KEYDOWN:
|
|
switch(event.key.keysym.sym)
|
|
{
|
|
case DPAD_LEFT:
|
|
case DPAD_RIGHT:
|
|
if (choice == 0) choice = 1;
|
|
else choice = 0;
|
|
break;
|
|
case A_BUTTON:
|
|
textIsRelevent = 0;
|
|
if (choice == 0) run(kSelf->path1);
|
|
else run(kSelf->path2);
|
|
break;
|
|
case FS_BUTTON:
|
|
toggleFullscreen();
|
|
break;
|
|
default: break;
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
frameAdvance();
|
|
}
|
|
}
|
|
|
|
void deleteChoice(Kaos* self)
|
|
{
|
|
Choice* kSelf = self->kType;
|
|
SDL_FreeSurface(kSelf->question);
|
|
SDL_FreeSurface(kSelf->answ1);
|
|
SDL_FreeSurface(kSelf->answ2);
|
|
free(self->kType);
|
|
free(self);
|
|
}
|
|
|
|
Kaos* newManip(char* args)
|
|
{
|
|
Player* t;
|
|
int rm, x, y;
|
|
int pSlot = -1;
|
|
Kaos* core = rawKaos();
|
|
Manip* self = malloc(sizeof(Manip));
|
|
|
|
t = hero;
|
|
|
|
if (sscanf(args, "room %u, person %u, xSpd %d, ySpd %d",
|
|
&rm, &pSlot, &x, &y) != 4)
|
|
if (sscanf(args, "hero, xSpd %d, ySpd %d",
|
|
&x, &y) != 2)
|
|
{
|
|
free(core);
|
|
core = NULL;
|
|
free(self);
|
|
self = NULL;
|
|
return core;
|
|
}
|
|
|
|
if (pSlot >=0)
|
|
t = mapBuffer[rm]->people[pSlot];
|
|
|
|
self->target= t;
|
|
self->xSpd = x;
|
|
self->ySpd = y;
|
|
|
|
core->kType = self;
|
|
self->core = core;
|
|
core->run = &runManip;
|
|
core->destroy = &deleteManip;
|
|
return core;
|
|
}
|
|
|
|
void runManip(Kaos* self)
|
|
{
|
|
Manip* kSelf = self->kType;
|
|
kSelf->target->bearing.x = kSelf->xSpd;
|
|
kSelf->target->bearing.y = kSelf->ySpd;
|
|
}
|
|
|
|
void deleteManip(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newLook(char* args)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Look* self = malloc(sizeof(Look));
|
|
|
|
int rm, pSlot;
|
|
char d;
|
|
pSlot = -1;
|
|
|
|
if (sscanf(args, "room %u, person %u, dir %c",
|
|
&rm, &pSlot, &d) != 3)
|
|
if (sscanf(args, "hero, dir %c",
|
|
&d) != 1)
|
|
{
|
|
free(core);
|
|
core = NULL;
|
|
free(self);
|
|
self = NULL;
|
|
return core;
|
|
}
|
|
|
|
if (pSlot >= 0)
|
|
self->target = mapBuffer[rm]->people[pSlot];
|
|
else self->target = hero;
|
|
|
|
self->dir = d;
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
core->run = &runLook;
|
|
core->destroy = &deleteLook;
|
|
return core;
|
|
}
|
|
|
|
void runLook(Kaos* self)
|
|
{
|
|
Look* kSelf = self->kType;
|
|
switch(kSelf->dir)
|
|
{
|
|
case 'n':
|
|
kSelf->target->clip.x = 96;
|
|
break;
|
|
case 's':
|
|
kSelf->target->clip.x = 32;
|
|
break;
|
|
case 'e':
|
|
kSelf->target->clip.x = 64;
|
|
break;
|
|
case 'w':
|
|
kSelf->target->clip.x = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void deleteLook(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newTeleport(char* args)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Teleport* self = malloc(sizeof(Teleport));
|
|
|
|
int rm, pSlot, x, y;
|
|
pSlot = -1;
|
|
|
|
if (sscanf(args, "room %u, person %u, x %d, y %d",
|
|
&rm, &pSlot, &x, &y) != 4)
|
|
if (sscanf(args, "hero, x %d, y %d",
|
|
&x, &y) != 2)
|
|
{
|
|
free(core);
|
|
core = NULL;
|
|
free(self);
|
|
self = NULL;
|
|
return core;
|
|
}
|
|
|
|
if (pSlot >= 0)
|
|
self->target = mapBuffer[rm]->people[pSlot];
|
|
else
|
|
self->target = hero;
|
|
self->x = x;
|
|
self->y = y;
|
|
self->aura = loadImage("assets/img/fx/blkthunder.png");
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
core->run = &runTeleport;
|
|
core->destroy = &deleteTeleport;
|
|
return core;
|
|
}
|
|
|
|
void runTeleport(Kaos* self)
|
|
{
|
|
Teleport* kSelf = self->kType;
|
|
int i;
|
|
SDL_Rect clip = {0,0,32,32};
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
if (i == 11)
|
|
{
|
|
kSelf->target->point.x = kSelf->x;
|
|
kSelf->target->point.y = kSelf->y;
|
|
}
|
|
clip.x = (i%4)*32;
|
|
timeStart(&fps);
|
|
renderBackground();
|
|
renderForeground();
|
|
applySurface(kSelf->x-16, kSelf->y-16, kSelf->aura, screen, &clip);
|
|
frameAdvance();
|
|
}
|
|
}
|
|
|
|
void deleteTeleport(Kaos* target)
|
|
{
|
|
Teleport* kSelf = target->kType;
|
|
SDL_FreeSurface(kSelf->aura);
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newFaceEachother(char* args)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
FaceEachother* self = malloc(sizeof(FaceEachother));
|
|
int r1, r2;
|
|
int p1, p2;
|
|
p1 = -1;
|
|
if (sscanf(args, "rm %d, person %d, rm %d, person %d", &r1, &p1, &r2, &p2) != 4)
|
|
if (sscanf(args, "hero, rm %d, person %d", &r2, &p2) != 2)
|
|
{
|
|
free(core);
|
|
core = NULL;
|
|
free(self);
|
|
self = NULL;
|
|
return core;
|
|
}
|
|
|
|
if (p1 >= 0)
|
|
{
|
|
self->p1 = mapBuffer[r1]->people[p1];
|
|
}
|
|
else self->p1 = hero;
|
|
self->p2 = mapBuffer[r2]->people[p2];
|
|
|
|
core->kType = self;
|
|
self->core = core;
|
|
core->run = &runFaceEachother;
|
|
core->destroy = &deleteFaceEachother;
|
|
return core;
|
|
}
|
|
|
|
void runFaceEachother(Kaos* self)
|
|
{
|
|
FaceEachother* kSelf = self->kType;
|
|
|
|
if (kSelf->p1->point.x > kSelf->p2->point.x)
|
|
kSelf->p2->clip.x = 64;
|
|
|
|
if (kSelf->p1->point.x < kSelf->p2->point.x)
|
|
kSelf->p1->clip.x = 64;
|
|
|
|
if (kSelf->p1->point.y > kSelf->p2->point.y)
|
|
{
|
|
kSelf->p1->clip.x = 96;
|
|
kSelf->p2->clip.x = 32;
|
|
}
|
|
|
|
if (kSelf->p1->point.y < kSelf->p2->point.y)
|
|
{
|
|
kSelf->p1->clip.x = 32;
|
|
kSelf->p2->clip.x = 96;
|
|
}
|
|
}
|
|
|
|
void deleteFaceEachother(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
#ifdef SOUND_ON
|
|
Kaos* newPlaySound(int i)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
PlaySound* self = malloc(sizeof(PlaySound));
|
|
|
|
self->i = i;
|
|
|
|
core->kType = self;
|
|
self->core = core;
|
|
core->run = &runPlaySound;
|
|
core->destroy = &deletePlaySound;
|
|
return core;
|
|
}
|
|
|
|
void runPlaySound(Kaos* self)
|
|
{
|
|
PlaySound* kSelf = self->kType;
|
|
Mix_PlayChannel(-1, sfxData[kSelf->i], 0);
|
|
}
|
|
|
|
void deletePlaySound(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
#endif
|
|
|
|
Kaos* newErase(char t, int i)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Erase* self = malloc(sizeof(Erase));
|
|
|
|
self->type = t;
|
|
self->index = i;
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
core->run = &runErase;
|
|
core->destroy = &deleteErase;
|
|
return core;
|
|
}
|
|
|
|
void runErase(Kaos* self)
|
|
{
|
|
Erase* kSelf = self->kType;
|
|
switch (kSelf->type)
|
|
{
|
|
case 'w':
|
|
deleteWarp(rightHere, kSelf->index);
|
|
break;
|
|
case 't':
|
|
deleteTrigger(rightHere, kSelf->index);
|
|
break;
|
|
case 'o':
|
|
deleteObstacle(rightHere, kSelf->index);
|
|
break;
|
|
case 'f':
|
|
deleteFgObj(rightHere, kSelf->index);
|
|
break;
|
|
case 's':
|
|
deleteSigil(rightHere, kSelf->index);
|
|
break;
|
|
default:break;
|
|
}
|
|
}
|
|
|
|
void deleteErase(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newWait(char t, int i)
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Wait* self = malloc(sizeof(Wait));
|
|
|
|
self->type = t;
|
|
self->frames = i;
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
core->run = &runWait;
|
|
core->destroy = &deleteWait;
|
|
return core;
|
|
}
|
|
|
|
void runWait(Kaos* self)
|
|
{
|
|
Wait* kSelf = self->kType;
|
|
int i;
|
|
if (kSelf->type == 'f')
|
|
captive = 1;
|
|
|
|
for (i = 0; i < kSelf->frames; i++)
|
|
{
|
|
timeStart(&fps);
|
|
if (captive)
|
|
interact();
|
|
renderBackground();
|
|
renderForeground();
|
|
frameAdvance();
|
|
}
|
|
captive = 0;
|
|
}
|
|
|
|
void deleteWait(Kaos* target)
|
|
{
|
|
free(target->kType);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newSpell_Beam()
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Spell_Beam* self = malloc(sizeof(Spell_Beam));
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
|
|
self->aura = loadImage("assets/img/fx/spellBeam.png");
|
|
SDL_SetAlpha(self->aura, SDL_SRCALPHA|SDL_RLEACCEL, 124);
|
|
core->run = &runSpell_Beam;
|
|
core->destroy = &deleteSpell_Beam;
|
|
|
|
return core;
|
|
}
|
|
|
|
void runSpell_Beam(Kaos* self)
|
|
{
|
|
int i;
|
|
char facing;
|
|
SDL_Rect offset, clip;
|
|
Spell_Beam* kSelf = self->kType;
|
|
if (playerFaces(hero, 's'))
|
|
{
|
|
facing = 's';
|
|
offset.x = hero->boundBox.x - hero->boundBox.w/2;
|
|
offset.y = hero->boundBox.y + hero->boundBox.h;
|
|
clip.x = 0;
|
|
clip.y = 128;
|
|
clip.w = 32;
|
|
clip.h = 180;
|
|
}
|
|
else if (playerFaces(hero, 'w'))
|
|
{
|
|
facing = 'w';
|
|
offset.x = hero->boundBox.x - SCREEN_WIDTH;
|
|
offset.y = hero->boundBox.y - hero->boundBox.h/2;
|
|
clip.x = 15;
|
|
clip.y = 0;
|
|
clip.w = 320;
|
|
clip.h = 32;
|
|
}
|
|
else if (playerFaces(hero, 'e'))
|
|
{
|
|
facing = 'e';
|
|
offset.x = hero->boundBox.x + hero->boundBox.w;
|
|
offset.y = hero->boundBox.y - hero->boundBox.h/2;
|
|
clip.x = 0;
|
|
clip.y = 0;
|
|
clip.w = 320;
|
|
clip.h = 32;
|
|
}
|
|
else
|
|
{
|
|
facing = 'n';
|
|
offset.x = hero->boundBox.x - hero->boundBox.w/2;
|
|
offset.y = hero->boundBox.y - SCREEN_HEIGHT;
|
|
clip.x = 128;
|
|
clip.y = 128;
|
|
clip.w = 32;
|
|
clip.h = 180;
|
|
}
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
timeStart(&fps);
|
|
renderBackground();
|
|
renderForeground();
|
|
switch (facing)
|
|
{
|
|
case 'n':
|
|
clip.x = 128 + (i%4)*32;
|
|
applySurface(offset.x, offset.y, kSelf->aura, screen, &clip);
|
|
break;
|
|
case 's':
|
|
clip.x = (i%4)*32;
|
|
applySurface(offset.x, offset.y, kSelf->aura, screen, &clip);
|
|
break;
|
|
case 'w':
|
|
case 'e':
|
|
clip.y = (i%4)*32;
|
|
applySurface(offset.x, offset.y, kSelf->aura, screen, &clip);
|
|
break;
|
|
}
|
|
frameAdvance();
|
|
}
|
|
}
|
|
|
|
void deleteSpell_Beam(Kaos* target)
|
|
{
|
|
Spell_Beam* kSelf = target->kType;
|
|
|
|
SDL_FreeSurface(kSelf->aura);
|
|
free(kSelf);
|
|
free(target);
|
|
}
|
|
|
|
Kaos* newSpell_Flash()
|
|
{
|
|
Kaos* core = rawKaos();
|
|
Spell_Beam* self = malloc(sizeof(Spell_Flash));
|
|
|
|
self->core = core;
|
|
core->kType = self;
|
|
|
|
self->aura = loadImage("assets/img/fx/mactivate.png");
|
|
SDL_SetAlpha(self->aura, SDL_SRCALPHA|SDL_RLEACCEL, 124);
|
|
core->run = &runSpell_Flash;
|
|
core->destroy = &deleteSpell_Flash;
|
|
|
|
return core;
|
|
}
|
|
|
|
void runSpell_Flash(Kaos* self)
|
|
{
|
|
Spell_Flash* kSelf = self->kType;
|
|
int i;
|
|
SDL_Rect offset, clip;
|
|
offset.x = hero->point.x - 20;
|
|
offset.y = hero->point.y - 56;
|
|
clip.x = 0;
|
|
clip.y = 0;
|
|
clip.w = 41;
|
|
clip.h = 72;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
clip.x = 41*i;
|
|
timeStart(&fps);
|
|
renderBackground();
|
|
renderForeground();
|
|
applySurface(offset.x, offset.y, kSelf->aura, screen, &clip);
|
|
frameAdvance();
|
|
}
|
|
}
|
|
|
|
void deleteSpell_Flash(Kaos* target)
|
|
{
|
|
Spell_Flash* kSelf = target->kType;
|
|
SDL_FreeSurface(kSelf->aura);
|
|
free(kSelf);
|
|
free(target);
|
|
} |