#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(char* args) { Kaos* core = rawKaos(); PlaySound* self = malloc(sizeof(PlaySound)); int i; if (sscanf(args, "slot %d", &i) != 1) { free(core); free(self); core = NULL; self = NULL; return core; } 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* args) { Kaos* core = rawKaos(); Erase* self = malloc(sizeof(Erase)); char t; int i; if (sscanf(args, "objType %c, slot %d", &t, &i) != 2) { free(core); free(self); core = NULL; self = NULL; return core; } 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* args) { Kaos* core = rawKaos(); Wait* self = malloc(sizeof(Wait)); char t; int i; if (sscanf(args, "wType %c, time %d", &t, &i) != 2) { free(core); free(self); core = NULL; self = NULL; return core; } 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); }