all repos — hyperkaos @ 4bab74888b510130417d3861c2ed2c13aef221a0

lightweight modular puzzle/adventure game engine in C with SDL 1.2

refactor in pure C, new Kaos: FaceEachother, PlaySound, Teleport
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAlui95MACgkQO3+8IhRO
Y5hRGBAAlSVoNRIubQDI6CyXqa4Bx1JGBKFVGKNgSbnrQ+387BTflujJAyn+KEKN
/nxOIdoWUVmzSKcRrg5khpp12HiuJjrOWY4vJhUEsMga/sDhqWu0eMb7sfUAYq9A
WoGejJIDoVI6KUyUG+cyQEsYwKJGwyxfuAjNoX0S254wgxCjl8TqWyHL2VUg+sye
03bID8EvDnwObMOh86HzsLRtY1or9mTD7mXA5iF60lijeMVu+MNlOalfGVpwH08k
RNpZwSeo8nIr+0KJBkNy9hTO+nRefHzqwaOL4wypcuMtkYh0Q6egLN0docXDJHcd
+XffcLb3t/o7Q6+toGNz2wylF6qYXckJtFkMECUQy3r8ZTfYtDt35srrfQKpsR6D
XKIWUef5BNBvW2NrVXmAf5zZM1n6QYn820TuJOIxvComCbFmN8TjQ6JEeIC6THkv
9fV7GPW+QRncVS8ZTtMiwGJyyLJ2JqXSWxFS181nxXQlVn9nfcMfte4k05d+mlaV
ftD5oQZSbK6t4mZAwq9DOPnTIUquAs0fMeNNE8Byfh7hYQHCf+XG8mdQidxNBaPA
2oDo1BNVAAHV/wyYX4xAo2ktPixeh4yXiUfGolGkJIBiQp6DdfXDgPq+QYuvKbc1
3aFCXGrrh0dvyp5clyluh7UXnoR4v32EGJjxE0k7BCN0lPxLg0o=
=nLNo
-----END PGP SIGNATURE-----
commit

4bab74888b510130417d3861c2ed2c13aef221a0

81 files changed, 2612 insertions(+), 0 deletions(-)

jump to
A Engine.c

@@ -0,0 +1,492 @@

+#include <stdio.h> +#include <string.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 "Player.h" +#include "Room.h" +#include "WorldData.h" +#include "TextBox.h" +#include "Kaos.h" +#include "HyperKaos.h" +#include "extern.h" + +// +// graphics primitives +// + +SDL_Surface* loadImage(char* filename) +{ + SDL_Surface* loadedImage = NULL; + SDL_Surface* optimizedImage = NULL; + loadedImage = IMG_Load(filename); + if (loadedImage != NULL) + { + optimizedImage = SDL_DisplayFormat(loadedImage); + SDL_FreeSurface(loadedImage); + } + + return optimizedImage; +} + +void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip) +{ + SDL_Rect offset; + offset.x = x; + offset.y = y; + + SDL_BlitSurface(source, clip, destination, &offset); +} + +// +// sound +// + +Mix_Music* loadBGM(char* filename) +{ + Mix_Music* bgmTrack = Mix_LoadMUS(filename); + hasMusic = 1; + return bgmTrack; +} + +Mix_Chunk* loadSFX(char* filename) +{ + Mix_Chunk* sfxClip = Mix_LoadWAV(filename); + return sfxClip; +} + +// +// world +// + +void renderBackground() +{ + applySurface(0, 0, rightHere->bgImage, screen, NULL); + animate(rightHere); +} + +void renderForeground() +{ + drawFgObjects1(rightHere); + drawPeople(rightHere); + drawPlayer(hero); + drawFgObjects2(rightHere); +} + +void interact() +{ + while(SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_w: + hero->bearing.y = -2; + break; + case SDLK_a: + hero->bearing.x = -2; + break; + case SDLK_s: + hero->bearing.y = 2; + break; + case SDLK_d: + hero->bearing.x = 2; + break; + case SDLK_j: + actionbutton = 1; + break; + case SDLK_q: + pausemenu(); + break; + case SDLK_f: + toggleFullscreen(); + break; + default: break; + } + break; + case SDL_KEYUP: + switch( event.key.keysym.sym ) + { + case SDLK_w: + if (hero->bearing.y < 0) + { + hero->bearing.y = 0; + } + break; + case SDLK_a: + if (hero->bearing.x < 0) + { + hero->bearing.x = 0 ; + } + break; + case SDLK_s: + if (hero->bearing.y > 0) + { + hero->bearing.y = 0; + } + break; + case SDLK_d: + if (hero->bearing.x > 0) + { + hero->bearing.x = 0; + } + break; + case SDLK_j: + actionbutton = 0; + break; + default: break; + } + break; + case SDL_QUIT: quit = 1; playing = 0; break; + } + } + walkAnim(hero); +} + +void kListen(int* whichKaos) +{ + if (*whichKaos >= 0) + { + run(rightHere->eventTriggers[*whichKaos]); + *whichKaos = -1; + } +} + +// +// system +// + +int init(int argc, char* args[]) +{ + printf("Initializing SDL\n"); + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) == -1) return 0; + printf("Initialized\nOpening soundsystem\n"); + if (Mix_OpenAudio(22050,MIX_DEFAULT_FORMAT, 2, 4096) == -1) return 0; + printf("Soundsystem open\nCreating window\n"); + if (argc >= 2) + { + if (strcmp(args[1], "-w")) + { + screen = SDL_SetVideoMode( 320, 180, 32, SDL_FULLSCREEN|SDL_HWSURFACE); + SDL_ShowCursor(0); + fullscreen = 1; + } + else screen = SDL_SetVideoMode( 320, 180, 32, SDL_HWSURFACE|SDL_RESIZABLE); + } + else + { + screen = SDL_SetVideoMode( 320, 180, 32, SDL_FULLSCREEN|SDL_HWSURFACE); + SDL_ShowCursor(0); + fullscreen = 1; + } + if (screen == NULL) return 0; + SDL_WM_SetCaption("Kaos Mage's Infinite Sidequest", NULL); + printf("Window created\nInitializing fonts\n"); + if (TTF_Init() == -1) return 0; + printf("Fonts initialized\nInitializing data\n"); + + + menuBG = newRoom("assets/img/backgrounds/mainmenu.png", 1); + + font = TTF_OpenFont("assets/charriot.ttf", 10); + + saveMenu = loadImage("assets/img/windows/saveMenu.gif"); + textBoxBG = loadImage("assets/img/windows/textBox.gif"); + choiceBox = loadImage("assets/img/windows/choiceBox.gif"); + nextArrow = loadImage("assets/img/windows/nextButton.gif"); + selectArrow = loadImage("assets/img/windows/selectArrow.gif"); + loadingTxt = TTF_RenderText_Solid(font, "loading map data...", textColor); + hero = newPlayer("assets/img/characters/kmage.png", 160, 90); + + + mapData = (Room**)malloc(64*sizeof(Room*)); + mapBuffer= (Room**)malloc(64*sizeof(Room*)); + dialogueData = (TextBox**)malloc(124*sizeof(Room*)); + bgmData = (Mix_Music**)malloc(4*sizeof(Mix_Music*)); + sfxData = (Mix_Chunk**)malloc(24*sizeof(Mix_Chunk*)); + kaosData = (Kaos**)malloc(124*sizeof(Kaos*)); + printf("Init complete\n"); + return 1; +} + +void toggleFullscreen() +{ + if (!fullscreen) + { + SDL_SetVideoMode(320, 180, 32, SDL_FULLSCREEN|SDL_HWSURFACE); + SDL_ShowCursor(0); + fullscreen = 1; + } + else + { + SDL_SetVideoMode(320, 180, 32, SDL_HWSURFACE|SDL_RESIZABLE); + SDL_ShowCursor(1); + fullscreen = 0; + } +} + +void timeDilation() +{ + int i = getTicks(fps); + + if (i < 1000 / 30) + SDL_Delay(1000/30 - i); +} + +void cleanup() +{ + if(fullscreen) + SDL_ShowCursor(1); + printf("Freeing map data\n"); + + unloadData(thisChunk); + + printf("Freeing global data\n"); + + killPlayer(hero); + deleteRoom(menuBG); + + free(mapData); + free(kaosData); + free(dialogueData); + + free(bgmData); + free(sfxData); + + SDL_FreeSurface(textBoxBG); + SDL_FreeSurface(nextArrow); + SDL_FreeSurface(saveMenu); + SDL_FreeSurface(selectArrow); + SDL_FreeSurface(loadingTxt); + SDL_FreeSurface(screen); + + printf("Closing SDL\n"); + Mix_CloseAudio(); + TTF_CloseFont(font); + TTF_Quit(); + SDL_Quit(); + + printf("Cleanup complete\n"); +} + +void mainmenu() +{ + int menucounter = 0; + int select = 0; + FILE* saveData = fopen("sram", "r"); + + int level = 1; + int roomNo = 0; + int xPos = 180; + int yPos = 90; + long long int eventState = 2; + warpto(menuBG); + + if (menuBGM == NULL) + Mix_HaltMusic(); + else + Mix_PlayMusic(menuBGM, -1); + + while (!select) + { + timeStart(fps); + applySurface(0, 0, rightHere->bgImage, screen, NULL); + animate(rightHere); + + while(SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_w: + menucounter--; + break; + case SDLK_s: + menucounter++; + break; + + case SDLK_j: + select = 1; + break; + case SDLK_f: + toggleFullscreen(); + break; + default: break; + } + break; + case SDL_QUIT: quit = 1; playing = 0; select = 1; break; + } + if (menucounter == 3) menucounter = 0; + if (menucounter == -1) menucounter = 2; + } + switch (menucounter) + { + case 0: + applySurface(230, 61, selectArrow, screen, NULL); + break; + case 1: + applySurface(230, 83, selectArrow, screen, NULL); + break; + case 2: + applySurface(230, 105, selectArrow, screen, NULL); + } + SDL_Flip(screen); + timeDilation(); + } + switch (menucounter) + { + case 0: + thisChunk = LEVEL1; + nextChunk = LEVEL1; + + savestate = eventState; + bufferData(LEVEL1); + pushBufferData(); + + warpto(mapData[0]); + hero->point.x = 160; + hero->point.y = 90; + + playing = 1; + fclose(saveData); + break; + + case 1: + if (saveData) + { + fscanf(saveData, "%d %d %d %d %lld", &level, &roomNo, &xPos, &yPos, &eventState); + } + thisChunk = (enum dataChunks)(level); + nextChunk = (enum dataChunks)(level); + + savestate = eventState; + bufferData((enum dataChunks)(level)); + pushBufferData(); + + hero->point.x = xPos; + hero->point.y = yPos; + warpto(mapData[roomNo]); + + playing = 1; + fclose(saveData); + printf("Loaded save: level %d, room %d (%d,%d) state: %lld\n", level, roomNo, xPos, yPos, eventState); + break; + + case 2: + quit = 1; + playing = 0; + fclose(saveData); + } +} + +void pausemenu() +{ + int paused = 1; + int menucounter = 0; + int select = 0; + int roomNo; + int i; + FILE* saveData; + hero->bearing.x = 0; + hero->bearing.y = 0; + Mix_VolumeMusic(MIX_MAX_VOLUME/3); + for (i = 0; i < 64; i++) + { + if (rightHere == mapData[i]) + { + roomNo = i; + break; + } + } + while (paused) + { + timeStart(fps); + applySurface(60, 45, saveMenu ,screen, NULL); + while(SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_w: + menucounter--; + break; + case SDLK_s: + menucounter++; + break; + case SDLK_j: + select = 1; + break; + case SDLK_q: + paused = 0; + break; + case SDLK_f: + toggleFullscreen(); + break; + default: break; + } + break; + case SDL_QUIT: quit = 1; paused = 0; playing = 0; break; + } + if (menucounter == 3) menucounter = 0; + if (menucounter == -1) menucounter = 2; + } + + switch (menucounter) + { + case 0: + applySurface(93, 60, selectArrow, screen, NULL); + break; + case 1: + applySurface(93, 82, selectArrow, screen, NULL); + break; + case 2: + applySurface(93, 104, selectArrow, screen, NULL); + } + + if (select) + { + switch (menucounter) + { + case 0: + { + printf("Saving data: level %d, room %d (%d,%d) state: %lld\n", thisChunk, roomNo, hero->point.x, hero->point.y, savestate); + saveData = fopen("sram", "w"); + fprintf(saveData, "%d %d %d %d %lld", (int)(thisChunk), roomNo, hero->point.x, hero->point.y, savestate); + paused = 0; + fclose(saveData); + break; + } + case 1: + { + printf("Saving data: level %d, room %d (%d,%d) state: %lld\n", thisChunk, roomNo, hero->point.x, hero->point.y, savestate); + saveData = fopen("sram", "w"); + fprintf(saveData, "%d %d %d %d %lld", (int)(thisChunk), roomNo, hero->point.x, hero->point.y, savestate); + paused = 0; + playing = 0; + fclose(saveData); + break; + } + case 2: + paused = 0; + playing = 0; + break; + } + } + SDL_Flip(screen); + timeDilation(); + } + Mix_VolumeMusic(MIX_MAX_VOLUME); + +}
A Engine.h

@@ -0,0 +1,37 @@

+// graphics primitives + +SDL_Surface* loadImage(char* filename); + +void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip); + +// SDL sound + +Mix_Music* loadBGM(char* filename); + +Mix_Chunk* loadSFX(char* filename); + +// world + +void renderBackground(); + +void renderForeground(); + +void interact(); + +void kListen(int* whichKaos); + +// system + +int init(int argc, char* args[]); + +void toggleFullscreen(); + +void timeDilation(); + +void cleanup(); + +void mainmenu(); + +void filemenu(); + +void pausemenu();
A HyperKaos.c

@@ -0,0 +1,90 @@

+#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_ttf.h" +#include "SDL/SDL_mixer.h" + +#include "enum.h" +#include "Kaos.h" +#include "HyperKaos.h" + +typedef struct room Room; +typedef struct player Player; +typedef struct timer Timer; +typedef struct textBox TextBox; + +#include "extern.h" + +HyperKaos* newHyperKaos(int id, int type, int x, int y, int w, int h) +{ + HyperKaos* self = (HyperKaos*)malloc(sizeof(HyperKaos)); + + self->domain.x = x; + self->domain.y = y; + self->domain.w = w; + self->domain.h = h; + self->kaosID = id; + self->eventType = type; + self->head = NULL; + + return self; +} + +void deleteHyperKaos(HyperKaos* self) +{ + free(self); +} + +// +// chains of events +// + +void addKaos(HyperKaos* self, Kaos* target) +{ + Kaos* here = self->head; + Kaos* next; + + if (self->head == NULL) + self->head = target; + else + { + next = here->next; + while (next != NULL) + { + here = next; + next = here->next; + } + here->next = target; + } +} + +void run(HyperKaos* self) +{ + Kaos* here = self->head; + Kaos* next; + savestate *= self->kaosID; + if (self->head == NULL) return; + + else + { + next = here->next; + while (here != NULL) + { + here->run(here); + here = next; + if (here != NULL) + next = here->next; + } + } +} + +int notCompleted(int x) +{ + if (savestate%x) return 1; + else return 0; +} + +int hasCompleted(int x) +{ + if (!notCompleted(x)) return 1; + else return 0; +}
A HyperKaos.h

@@ -0,0 +1,17 @@

+typedef struct kaos Kaos; + +typedef struct hyperKaos +{ + int kaosID; + int eventType; + SDL_Rect domain; + Kaos* head; +} HyperKaos; + +HyperKaos* newHyperKaos(int id, int type, int x, int y, int w, int h); +void deleteHyperKaos(HyperKaos* target); + +void run(HyperKaos* self); +void addKaos(HyperKaos* self, Kaos* target); +int isCompleted(int x); +int notCompleted(int x);
A Kaos.c

@@ -0,0 +1,411 @@

+#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 "extern.h" + +Kaos* rawKaos() +{ + Kaos* self = (Kaos*)malloc(sizeof(Kaos)); + self->next = NULL; + return self; +} + +Kaos* newConversation(int i) +{ + Kaos* core = rawKaos(); + Conversation* self = (Conversation*)malloc(sizeof(Conversation)); + + self->index = i; + + core->kType = self; + self->core = core; + core->run = &runConversation; + core->destroy = &deleteConversation; + return core; +} + +void runConversation(Kaos* self) +{ + Conversation* kSelf = (Conversation*)self->kType; + displayTextBox(dialogueData[kSelf->index]); +} + +void deleteConversation(Kaos* target) +{ + free(target->kType); + free(target); +} + +Kaos* newChoice(char* q, char* a1, char* a2, HyperKaos* p1, HyperKaos* p2) +{ + Kaos* core = rawKaos(); + Choice* self = (Choice*)malloc(sizeof(Choice)); + + 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 = p1; + self->path2 = p2; + + core->kType = self; + self->core = core; + core->run = &runChoice; + core->destroy = &deleteChoice; + return core; +} + +void runChoice(Kaos* self) +{ + Choice* kSelf = (Choice*)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 SDLK_a: + case SDLK_d: + if (choice == 0) choice = 1; + else choice = 0; + break; + case SDLK_j: + textIsRelevent = 0; + if (choice == 0) run(kSelf->path1); + else run(kSelf->path2); + break; + case SDLK_f: + toggleFullscreen(); + break; + default: break; + } + default: break; + } + } + SDL_Flip(screen); + timeDilation(); + } +} + +void deleteChoice(Kaos* self) +{ + SDL_FreeSurface(((Choice*)(self->kType))->question); + SDL_FreeSurface(((Choice*)(self->kType))->answ1); + SDL_FreeSurface(((Choice*)(self->kType))->answ2); + free(self->kType); + free(self); +} + +Kaos* newManip(Player* t, int x, int y) +{ + Kaos* core = rawKaos(); + Manip* self = (Manip*)malloc(sizeof(Manip)); + + 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 = (Manip*)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(Player* t, char d) +{ + Kaos* core = rawKaos(); + Look* self = (Look*)malloc(sizeof(Look)); + + self->target = t; + self->dir = d; + + self->core = core; + core->kType = self; + core->run = &runLook; + core->destroy = &deleteLook; + return core; +} + +void runLook(Kaos* self) +{ + Look* kSelf = (Look*)self->kType; + SDL_Rect playerClip = { 0,0,16,16}; + switch(kSelf->dir) + { + case 'n': + playerClip.x = 96; + break; + case 's': + playerClip.x = 32; + break; + case 'e': + playerClip.x = 64; + break; + case 'w': + default: + break; + } + changeSprite(kSelf->target, &playerClip); +} + +void deleteLook(Kaos* target) +{ + free(target->kType); + free(target); +} + +Kaos* newTeleport(Player* p, int x, int y, int o) +{ + Kaos* core = rawKaos(); + Teleport* self = (Teleport*)malloc(sizeof(Teleport)); + + self->target = p; + self->x = x; + self->y = y; + self->out = o; + 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) + { + if (kSelf->out) + { + kSelf->target->point.x = -16; + kSelf->target->point.y = -16; + } + else + { + 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); + SDL_Flip(screen); + timeDilation(); + } +} + +void deleteTeleport(Kaos* target) +{ + Teleport* kSelf = (Teleport*)target->kType; + SDL_FreeSurface(kSelf->aura); + free(target->kType); + free(target); +} + +Kaos* newFaceEachother(Player* p1, Player* p2) +{ + Kaos* core = rawKaos(); + FaceEachother* self = (FaceEachother*)malloc(sizeof(FaceEachother)); + + self->p1 = p1; + self->p2 = p2; + + core->kType = self; + self->core = core; + core->run = &runFaceEachother; + core->destroy = &deleteFaceEachother; + return core; +} + +void runFaceEachother(Kaos* self) +{ + FaceEachother* kSelf = (FaceEachother*)self->kType; + SDL_Rect p1Clip = {0,0,16,16}; + SDL_Rect p2Clip = {0,0,16,16}; + if (kSelf->p1->point.x > kSelf->p2->point.x) + p2Clip.x = 64; + if (kSelf->p1->point.x < kSelf->p2->point.x) + p1Clip.x = 64; + if (kSelf->p1->point.y > kSelf->p2->point.y) + { + p1Clip.x = 96; + p2Clip.x = 32; + } + if (kSelf->p1->point.y < kSelf->p2->point.y) + { + p1Clip.x = 32; + p2Clip.x = 96; + } + changeSprite(kSelf->p1, &p1Clip); + changeSprite(kSelf->p2, &p2Clip); +} + +void deleteFaceEachother(Kaos* target) +{ + free(target->kType); + free(target); +} + +Kaos* newPlaySound(int i) +{ + Kaos* core = rawKaos(); + PlaySound* self = (PlaySound*)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 = (PlaySound*)self->kType; + Mix_PlayChannel(-1, sfxData[kSelf->i], 0); +} + +void deletePlaySound(Kaos* target) +{ + free(target->kType); + free(target); +} + +Kaos* newErase(char t, int i) +{ + Kaos* core = rawKaos(); + Erase* self = (Erase*)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 = (Erase*)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; + default:break; + } +} + +void deleteErase(Kaos* target) +{ + free(target->kType); + free(target); +} + +Kaos* newWait(char t, int i) +{ + Kaos* core = rawKaos(); + Wait* self = (Wait*)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 = (Wait*)self->kType; + int i; + if (kSelf->type == 'f') + captive = 1; + + for (i = 0; i < kSelf->frames; i++) + { + timeStart(fps); + if (captive) + interact(); + renderBackground(); + renderForeground(); + SDL_Flip(screen); + timeDilation(); + } + captive = 0; +} + +void deleteWait(Kaos* target) +{ + free(target->kType); + free(target); +}
A Kaos.h

@@ -0,0 +1,114 @@

+typedef struct player Player; +typedef struct hyperKaos HyperKaos; + +typedef struct kaos +{ + void* kType; + void (*run)(struct kaos* self); + void (*destroy)(struct kaos* self); + struct kaos* next; +} Kaos; + +typedef struct kaos_Conversation +{ + Kaos* core; + int index; +} Conversation; + +typedef struct kaos_Choice +{ + Kaos* core; + SDL_Surface* question; + SDL_Surface* answ1; + SDL_Surface* answ2; + HyperKaos* path1; + HyperKaos* path2; +} Choice; + +typedef struct kaos_Manip +{ + Kaos* core; + Player* target; + int xSpd, ySpd; +} Manip; + +typedef struct kaos_Look +{ + Kaos* core; + Player* target; + char dir; +} Look; + +typedef struct kaos_FaceEachother +{ + Kaos* core; + Player* p1; + Player* p2; +} FaceEachother; + +typedef struct kaos_PlaySound +{ + Kaos* core; + int i; +} PlaySound; + +typedef struct kaos_Teleport +{ + Kaos* core; + Player* target; + int x, y; + int out; + SDL_Surface* aura; +} Teleport; + +typedef struct kaos_Erase +{ + Kaos* core; + char type; + int index; +} Erase; + +typedef struct kaos_Wait +{ + Kaos* core; + char type; + int frames; +} Wait; + +Kaos* rawKaos(); + +Kaos* newConversation(int i); +void runConversation(Kaos* self); +void deleteConversation(Kaos* target); + +Kaos* newChoice(char* q, char* a1, char* a2, HyperKaos* p1, HyperKaos* p2); +void runChoice(Kaos* self); +void deleteChoice(Kaos* target); + +Kaos* newManip(Player* t, int x, int y); +void runManip(Kaos* self); +void deleteManip(Kaos* target); + +Kaos* newLook(Player* t, char d); +void runLook(Kaos* self); +void deleteLook(Kaos* target); + +Kaos* newTeleport(Player* p, int x, int y, int o); +void runTeleport(Kaos* self); +void deleteTeleport(Kaos* target); + +Kaos* newFaceEachother(Player* p1, Player* p2); +void runFaceEachother(Kaos* self); +void deleteFaceEachother(Kaos* target); + +Kaos* newPlaySound(int i); +void runPlaySound(Kaos* self); +void deletePlaySound(Kaos* target); + +Kaos* newErase(char t, int i); +void runErase(Kaos* self); +void deleteErase(Kaos* target); + +Kaos* newWait(char t, int i); +void runWait(Kaos* self); +void deleteWait(Kaos* target);
A Kaos.o

          
A Makefile

@@ -0,0 +1,14 @@

+CFLAGS= -Wall -I/usr/include/SDL -L/usr/lib/ -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer + +.PHONY: all clean cleanobj + +all: game + +game: main.c Player.o Engine.o Timer.o Room.o WorldData.o TextBox.o Kaos.o HyperKaos.o + $(CC) -o $@ $^ $(CFLAGS) + +cleanobj: + rm -f *.o + +clean: + rm -f game *.o
A Player.c

@@ -0,0 +1,247 @@

+#include <stdio.h> + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_mixer.h" + +#include "enum.h" +#include "Engine.h" +#include "Player.h" +#include "Room.h" +#include "WorldData.h" + +typedef struct TTF_Font TTF_Font; +typedef struct timer Timer; +typedef struct textBox TextBox; +typedef struct kaos Kaos; +#include "extern.h" + +Player* newPlayer(char* filename, int a, int b) +{ + SDL_Rect originClip; + originClip.x = 32; + originClip.y = 0; + originClip.h = 16; + originClip.w = 16; + Uint32 rmask, gmask, bmask, amask; + + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; + #else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; + #endif + + Player* self = (Player*)malloc(sizeof(Player)); + + self->counter = 0; + self->spriteSheet = NULL; + self->spriteSheet = loadImage(filename); + self->sprite = SDL_CreateRGBSurface(0,16,16,32,rmask,gmask,bmask,amask); + applySurface(0, 0, self->spriteSheet, self->sprite, &originClip); + self->point.x = a; + self->point.y = b; + self->bearing.x = 0; + self->bearing.y = 0; + self->boundBox.x = self->point.x - 8; + self->boundBox.y = self->point.y - 8; + self->boundBox.h = 16; + self->boundBox.w = 16; + self->frontFaceBox.x = self->boundBox.x; + self->frontFaceBox.y = self->boundBox.y + 16; + self->frontFaceBox.w = 16; + self->frontFaceBox.h = 16; + + return self; +} + +void killPlayer(Player* self) +{ + + SDL_FreeSurface(self->sprite); + SDL_FreeSurface(self->spriteSheet); + free(self); +} + +void movePlayer(Player* self, Room* hereNow) +{ + self->point.x += self->bearing.x; + self->boundBox.x = self->point.x - 8; + + // obstacle collision + + if (checkCollision(rightHere, &(self->boundBox), rightHere->obstacle)) + { + self->point.x -= self->bearing.x; + self->boundBox.x = self->point.x - 8; + } + + self->point.y += self->bearing.y; + self->boundBox.y = self->point.y - 8; + + + if (checkCollision(rightHere, &(self->boundBox), rightHere->obstacle)) + { + self->point.y -= self->bearing.y; + self->boundBox.y = self->point.y - 8; + } + + // event trigger collision + + if (self->bearing.y > 0) + { + self->frontFaceBox.x = self->boundBox.x; + self->frontFaceBox.y = self->boundBox.y + 16; + } + + if (self->bearing.y < 0) + { + self->frontFaceBox.x = self->boundBox.x; + self->frontFaceBox.y = self->boundBox.y - 16; + } + + if (self->bearing.x > 0) + { + self->frontFaceBox.x = self->boundBox.x + 16; + self->frontFaceBox.y = self->boundBox.y; + } + if (self->bearing.x < 0) + { + self->frontFaceBox.x = self->boundBox.x - 16; + self->frontFaceBox.y = self->boundBox.y; + } + + int kt = 0; + int kf = 0; + if (checkKCollision(rightHere, &(self->boundBox), rightHere->eventTriggers, &kf, &kt)) + { + if (!kt) + { + kaosFlag = kf; + } + else if (actionbutton) + { + kaosFlag = kf; + } + } + if (checkKCollision(rightHere, &(self->frontFaceBox), rightHere->eventTriggers, &kf, &kt)) + { + if (kt) + { + if (actionbutton) + kaosFlag = kf; + } + } + + // warp collision + + int outgoing = 0; + if (!captive) + { + if (checkWCollision(rightHere, &(self->boundBox), rightHere->warps, &outgoing)) + { + nextChunk = ((rightHere->warps) + outgoing)->chunk; + + if (nextChunk != thisChunk) + { + bufferData(((hereNow->warps) + outgoing)->chunk); + warpto(mapBuffer[((rightHere->warps) + outgoing)->destination]); + } + else warpto(mapData[((rightHere->warps) + outgoing)->destination]); + self->point.x = ((hereNow->warps) + outgoing)->x; + self->point.y = ((hereNow->warps) + outgoing)->y; + } + } + //stay onscreen + + if (self->point.x < 1) self->point.x = 1; + if (self->point.x > 320 - 1) self->point.x = 320 - 1; + if (self->point.y < 1) self->point.y = 1; + if (self->point.y > 180) self->point.y = 180 - 1; +} + +// +// graphics +// + +void drawPlayer(Player* self) +{ + applySurface(self->point.x - 8, self->point.y - 8, self->sprite, screen, NULL); +} + + +void changeSprite(Player* self, SDL_Rect* clip) +{ + SDL_Rect zeroOffset; + zeroOffset.x = 0; + zeroOffset.y = 0; + SDL_FillRect(self->sprite, NULL, 0x000000); + SDL_BlitSurface(self->spriteSheet, clip, self->sprite, &zeroOffset); +} + +void walkAnim(Player* self) +{ + SDL_Rect playerClip; + playerClip.w = 16; + playerClip.h = 16; + playerClip.y = 0; + if (self->bearing.y > 0) + { + if (self->counter == 0) + { + playerClip.x = 32; + changeSprite(self, &playerClip); + } + if (self->counter == 4) + { + playerClip.x = 48; + changeSprite(self, &playerClip); + } + } + if (self->bearing.y < 0) + { + if (self->counter == 0) + { + playerClip.x = 112; + changeSprite(self, &playerClip); + } + if (self->counter == 4) + { + playerClip.x = 96; + changeSprite(self, &playerClip); + } + } + if (self->bearing.x > 0) + { + if (self->counter == 0) + { + playerClip.x = 64; + changeSprite(self, &playerClip); + } + if (self->counter == 4) + { + playerClip.x = 80; + changeSprite(self, &playerClip); + } + } + if (self->bearing.x < 0) + { + if (self->counter == 0) + { + playerClip.x = 0; + changeSprite(self, &playerClip); + } + if (self->counter == 4) + { + playerClip.x = 16; + changeSprite(self, &playerClip); + } + } + self->counter++; + if (self->counter == 8) self->counter = 0; +}
A Player.h

@@ -0,0 +1,26 @@

+typedef struct room Room; + +typedef struct +{ + int x, y; +} Coord; + +typedef struct player +{ + int counter; + Coord point; + Coord bearing; + SDL_Rect boundBox; + SDL_Rect frontFaceBox; + SDL_Surface* spriteSheet; + SDL_Surface* sprite; + +} Player; + +Player* newPlayer(char* filename, int a, int b); +void killPlayer(Player* target); + +void movePlayer(Player* self, Room* rightHere); +void changeSprite(Player* self, SDL_Rect* clip); +void drawPlayer(Player* self); +void walkAnim(Player* self);
A Room.c

@@ -0,0 +1,498 @@

+#include <stdio.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 "HyperKaos.h" + +typedef struct timer Timer; +typedef struct textBox TextBox; +#include "extern.h" + +Room* newRoom(char* filename, int a) +{ + Room* self = (Room*)malloc(sizeof(Room)); + + self->obstacle = NULL; + self->obstacle = (SDL_Rect*)malloc(4*sizeof(SDL_Rect)); + self->numberOfObstacles = 0; + self->maxNumberOfObstacles = 4; + + self->fgObject = NULL; + self->fgObject = (FGImage*)malloc(4*sizeof(FGImage)); + self->numberOfObj = 0; + self->maxNumberOfObj = 4; + self->objSpeed = a; + self->objIterator = 0; + + self->warps = NULL; + self->warps = (WarpZone*)malloc(4*sizeof(WarpZone)); + self->numberOfWarps = 0; + self->maxNumberOfWarps = 4; + + self->eventTriggers = NULL; + self->eventTriggers = (HyperKaos**)malloc(4*sizeof(HyperKaos*)); + self->numberOfTriggers = 0; + self->maxNumberOfTriggers =4; + + self->people = NULL; + self->people = (Player**)malloc(4*sizeof(Player*)); + self->numberOfPeople = 0; + self->maxNumberOfPeople = 4; + + SDL_Rect zeroRect; + zeroRect.x=0; + zeroRect.y=0; + zeroRect.w=320; + zeroRect.h=180; + self->spriteSheet = loadImage(filename); + self->bgImage = loadImage("assets/img/backgrounds/loading.gif"); + SDL_BlitSurface(self->spriteSheet, &zeroRect, self->bgImage, &zeroRect); + self->frameNo = 0; + + return self; +} + +void deleteRoom(Room* target) +{ + int i; + free(target->obstacle); + target->obstacle = NULL; + + for (i = 0; i < target->numberOfObj; i++) + { + SDL_FreeSurface(target->fgObject[i].spriteSheet); + target->fgObject[i].spriteSheet = NULL; + } + free(target->fgObject); + target->fgObject = NULL; + + free(target->warps); + target->warps = NULL; + + for (i = 0; i < target->numberOfTriggers; i++) + { + deleteHyperKaos(target->eventTriggers[i]); + } + free(target->eventTriggers); + target->eventTriggers = NULL; + + for (i = 0; i < target->numberOfPeople; i++) + { + killPlayer(target->people[i]); + } + free(target->people); + + + SDL_FreeSurface(target->spriteSheet); + SDL_FreeSurface(target->bgImage); + target->spriteSheet = NULL; + target->bgImage = NULL; + + free(target); +} + +// +// room bg graphics +// + +void changeRSprite(Room* self, SDL_Rect* clip) +{ + SDL_Rect zeroOffset; + zeroOffset.x = 0; + zeroOffset.y = 0; + SDL_BlitSurface(self->spriteSheet, clip, self->bgImage, &zeroOffset); +} + +void animate(Room* self) +{ + SDL_Rect animClip; + animClip.w = 320; + animClip.h = 180; + animClip.x = 0; + + if (self->frameNo == 0) + { + animClip.y = 180; + changeRSprite(self, &animClip); + } + if (self->frameNo == 10) + { + animClip.y = 360; + changeRSprite(self, &animClip); + } + if (self->frameNo == 20) + { + animClip.y = 540; + changeRSprite(self, &animClip); + } + if (self->frameNo == 30) + { + animClip.y = 360; + changeRSprite(self, &animClip); + } + if (self->frameNo == 40) + { + animClip.y = 180; + changeRSprite(self, &animClip); + } + if (self->frameNo == 50) + { + animClip.y = 0; + changeRSprite(self, &animClip); + } + self->frameNo++; + if (self->frameNo == 60) self->frameNo = 0; +} + +// +// collision detection +// + +int checkCollision(Room* self, SDL_Rect* player, SDL_Rect* box) +{ + int i; + int playerX = player->x + (player->w)/2; + int playerY = player->y + (player->h)/2; + + for (i = 1; i <= self->numberOfObstacles; i++) + { + if ( (playerX >= box->x && playerX <= box->x + box->w) + && (playerY >= box->y && playerY <= box->y + box->h) ) + { + return 1; + } + box++; + } + return 0; +} + +int checkWCollision(Room* self, SDL_Rect* player, WarpZone* warpBoxes, int* whichWarp) +{ + int i; + int playerX = player->x + (player->w)/2; + int playerY = player->y + (player->h)/2; + + for (i = 1; i <= self->numberOfWarps; i++) + { + if ( (playerX >= (warpBoxes->location).x && playerX <= (warpBoxes->location).x + (warpBoxes->location).w) + && (playerY >= (warpBoxes->location).y && playerY <= (warpBoxes->location).y + (warpBoxes->location).h)) + { + *whichWarp = i-1; + return 1; + } + warpBoxes++; + } + return 0; +} + +int checkKCollision(Room* self, SDL_Rect* player, HyperKaos** triggers, int* whichTrigger, int* kType) +{ + int i; + int playerX = player->x + (player->w)/2; + int playerY = player->y + (player->h)/2; + + for (i = 1; i <= self->numberOfTriggers; i++) + { + + if ( (playerX > ((*triggers)->domain).x && playerX < ((*triggers)->domain).x + ((*triggers)->domain).w) + && (playerY > ((*triggers)->domain).y && playerY < ((*triggers)->domain).y + ((*triggers)->domain).h) ) + { + if ((*triggers)->eventType == 0) + { + *whichTrigger = i-1; + *kType = 0; + return 1; + } + else + { + *whichTrigger = i-1; + *kType = 1; + return 1; + } + } + triggers++; + } + return 0; +} + +// +// obstacles +// + +void addObstacle(Room* self, int x, int y, int w, int h) +{ + int i; + if (self->numberOfObstacles+1 > self->maxNumberOfObstacles) + { + self->maxNumberOfObstacles *= 2; + SDL_Rect* temp = (SDL_Rect*)malloc(self->maxNumberOfObstacles*sizeof(SDL_Rect)); + for (i = 0; i < self->numberOfObstacles; i++) + temp[i] = self->obstacle[i]; + free(self->obstacle); + self->obstacle = temp; + temp = NULL; + } + + self->obstacle[self->numberOfObstacles].x = x; + self->obstacle[self->numberOfObstacles].y = y; + self->obstacle[self->numberOfObstacles].w = w; + self->obstacle[self->numberOfObstacles].h = h; + + self->numberOfObstacles++; +} + +void deleteObstacle(Room* self, int i) +{ + int j; + SDL_Rect* temp = (SDL_Rect*)malloc(self->maxNumberOfObstacles*sizeof(SDL_Rect)); + for (j = 0; j < i; j++) + temp[j] = self->obstacle[j]; + for (j = i + 1; j < self->numberOfObstacles; j++) + temp[j-1] = self->obstacle[j]; + free(self->obstacle); + self->obstacle = temp; + temp = NULL; + self->numberOfObstacles--; +} + +// +// fg objects +// + +void addFgObj(Room* self, int x, int y, int w, int h, char* filename, int f, int dual) +{ + int i; + if (self->numberOfObj+1 > self->maxNumberOfObj) + { + self->maxNumberOfObj *= 2; + FGImage* temp = (FGImage*)malloc(self->maxNumberOfObj*sizeof(FGImage));; + for (i = 0; i < self->numberOfObj; i++) + temp[i] = self->fgObject[i]; + free(self->fgObject); + self->fgObject = temp; + temp = NULL; + } + + self->fgObject[self->numberOfObj].location.x = x; + self->fgObject[self->numberOfObj].location.y = y; + self->fgObject[self->numberOfObj].location.w = w; + self->fgObject[self->numberOfObj].location.h = h; + + self->fgObject[self->numberOfObj].frames = f; + self->fgObject[self->numberOfObj].frameNow = 0; + self->fgObject[self->numberOfObj].dualLayer = dual; + + self->fgObject[self->numberOfObj].spriteSheet = loadImage(filename); + self->numberOfObj++; + +} + +void deleteFgObj(Room* self, int i) +{ + int j; + FGImage* temp = (FGImage*)malloc(self->maxNumberOfObj*sizeof(FGImage)); + for (j = 0; j < i; j++) + temp[j] = self->fgObject[j]; + for (j = i + 1; j < self->numberOfObj; j++) + temp[j-1] = self->fgObject[j]; + free(self->fgObject[i].spriteSheet); + free(self->fgObject); + self->fgObject = temp; + temp = NULL; + self->numberOfObj--; +} + +void drawFgObjects1(Room* self) +{ + int i; + SDL_Rect clip; + clip.y = 0; + + if (self->numberOfObj != 0) + { + self->objIterator++; + + for (i = 0; i < self->numberOfObj; i++) + { + clip.w = self->fgObject[i].location.w; + clip.x = self->fgObject[i].frameNow*clip.w; + clip.h = self->fgObject[i].location.h; + applySurface(self->fgObject[i].location.x, self->fgObject[i].location.y, self->fgObject[i].spriteSheet, screen, &clip ); + if (self->objIterator == self->objSpeed) + self->fgObject[i].frameNow++; + if (self->fgObject[i].frameNow == self->fgObject[i].frames) + self->fgObject[i].frameNow = 0; + } + if (self->objIterator == self->objSpeed) + self->objIterator = 0; + } +} + +void drawFgObjects2(Room* self) +{ + int i; + SDL_Rect clip; + clip.y = 0; + + if (self->numberOfObj != 0) + { + self->objIterator++; + + for (i = 0; i < self->numberOfObj; i++) + { + if (self->fgObject[i].dualLayer) + { + clip.w = self->fgObject[i].location.w; + clip.x = self->fgObject[i].frameNow*clip.w; + clip.h = self->fgObject[i].location.h; + clip.y = clip.h; + applySurface(self->fgObject[i].location.x, self->fgObject[i].location.y, self->fgObject[i].spriteSheet, screen, &clip ); + if (self->objIterator == self->objSpeed) + self->fgObject[i].frameNow++; + if (self->fgObject[i].frameNow == self->fgObject[i].frames) + self->fgObject[i].frameNow = 0; + } + } + if (self->objIterator == self->objSpeed) + self->objIterator = 0; + } +} + +// +// warps +// + +void addWarp(Room* self, int x, int y, int w, int h, enum dataChunks toChunk, int goesTo, int goesX, int goesY) +{ + int i; + if (self->numberOfWarps+1 > self->maxNumberOfWarps) + { + self->maxNumberOfWarps *= 2; + WarpZone* temp = (WarpZone*)malloc(self->maxNumberOfWarps*sizeof(WarpZone)); + for (i = 0; i < self->numberOfWarps; i++) + temp[i] = self->warps[i]; + free(self->warps); + self->warps = temp; + temp = NULL; + } + + self->warps[self->numberOfWarps].x = goesX; + self->warps[self->numberOfWarps].y = goesY; + + self->warps[self->numberOfWarps].location.x = x; + self->warps[self->numberOfWarps].location.y = y; + self->warps[self->numberOfWarps].location.w = w; + self->warps[self->numberOfWarps].location.h = h; + + self->warps[self->numberOfWarps].chunk = toChunk; + self->warps[self->numberOfWarps++].destination = goesTo; + +} + +void deleteWarp(Room* self, int i) +{ + int j; + WarpZone* temp = (WarpZone*)malloc(self->maxNumberOfWarps*sizeof(WarpZone)); + for (j = 0; j < i; j++) + temp[j] = self->warps[j]; + for (j = i + 1; j < self->numberOfWarps; j++) + temp[j-1] = self->warps[j]; + free(self->warps); + self->warps = temp; + temp = NULL; + self->numberOfWarps--; +} + +// +// event triggers +// + +void addTrigger(Room* self, HyperKaos* newTrigger) +{ + int i; + if (self->numberOfTriggers+1 > self->maxNumberOfTriggers) + { + self->maxNumberOfTriggers *= 2; + HyperKaos** temp = (HyperKaos**)malloc(self->maxNumberOfTriggers*sizeof(HyperKaos*)); + for (i = 0; i < self->numberOfTriggers; i++) + temp[i] = self->eventTriggers[i]; + free(self->eventTriggers); + self->eventTriggers = temp; + temp = NULL; + } + + self->eventTriggers[self->numberOfTriggers++] = newTrigger; +} + +void deleteTrigger(Room* self, int i) +{ + int j; + HyperKaos** temp = (HyperKaos**)malloc(self->maxNumberOfTriggers*sizeof(HyperKaos*)); + for (j = 0; j < i; j++) + temp[j] = self->eventTriggers[j]; + for (j = i + 1; j < self->numberOfTriggers; j++) + temp[j-1] = self->eventTriggers[j]; + deleteHyperKaos(self->eventTriggers[i]); + free(self->eventTriggers); + self->eventTriggers = temp; + temp = NULL; + self->numberOfTriggers--; +} + +void addPerson(Room* self, Player* newPlayer) +{ + int i; + if (self->numberOfPeople+1 > self->maxNumberOfPeople) + { + self->maxNumberOfPeople *= 2; + Player** temp = (Player**)malloc(self->maxNumberOfPeople*sizeof(Player*)); + for (i = 0; i < self->numberOfPeople; i++) + temp[i] = self->people[i]; + free(self->people); + self->people = temp; + temp = NULL; + } + + self->people[self->numberOfPeople++] = newPlayer; +} + +void deletePerson(Room* self, int i) +{ + int j; + Player** temp = (Player**)malloc(self->maxNumberOfPeople*sizeof(Player*)); + for (j = 0; j < i; j++) + temp[j] = self->people[j]; + for (j = i + 1; j < self->numberOfPeople; j++) + temp[j] = self->people[j]; + killPlayer(self->people[i]); + free(self->people); + self->people = temp; + temp = NULL; + self->numberOfPeople--; +} + +void drawPeople(Room* self) +{ + int i; + for (i = 0; i < self->numberOfPeople; i++) + { + drawPlayer(self->people[i]); + } +} + +// +// warp +// + +void warpto(Room* destination) +{ + rightHere = destination; +} +
A Room.h

@@ -0,0 +1,80 @@

+typedef struct hyperKaos HyperKaos; + +typedef struct fgImage +{ + int frames; + int frameNow; + int dualLayer; + + SDL_Rect location; + SDL_Surface* spriteSheet; +} FGImage; + + +typedef struct warpZone +{ + SDL_Rect location; + enum dataChunks chunk; + int destination; + int x, y; +} WarpZone; + +typedef struct room +{ + SDL_Surface* spriteSheet; + SDL_Surface* bgImage; + int frameNo; + + SDL_Rect* obstacle; + int numberOfObstacles; + int maxNumberOfObstacles; + + struct fgImage* fgObject; + int numberOfObj; + int maxNumberOfObj; + int objSpeed; + int objIterator; + + WarpZone* warps; + int numberOfWarps; + int maxNumberOfWarps; + + HyperKaos** eventTriggers; + int numberOfTriggers; + int maxNumberOfTriggers; + + Player** people; + int numberOfPeople; + int maxNumberOfPeople; + +} Room; + +void warpto(Room* destination); + +Room* newRoom(char* filename, int a); +void deleteRoom(Room* target); + +void changeRSprite(Room* self, SDL_Rect* clip); +void animate(Room* self); + +int checkCollision(Room* self, SDL_Rect* player, SDL_Rect* box); +int checkWCollision(Room* self, SDL_Rect* player, WarpZone* warpBoxes, int* whichWarp); +int checkKCollision(Room* self, SDL_Rect* player, HyperKaos** triggers, int* whichTrigger, int* triggerType); + +void addObstacle(Room* self, int x, int y, int w, int h); +void deleteObstacle(Room* self, int i); + +void addFgObj(Room* self, int x, int y, int w, int h, char* filename, int f, int dual); +void deleteFgObj(Room* self, int i); +void drawFgObjects1(Room* self); +void drawFgObjects2(Room* self); + +void addWarp(Room* self, int x, int y, int w, int h, enum dataChunks toChunk, int toRoom, int toX, int toY); +void deleteWarp(Room* self, int i); + +void addTrigger(Room* self, HyperKaos* newTrigger); +void deleteTrigger(Room* self, int i); + +void addPerson(Room* self, Player* newPlayer); +void deletePerson(Room* self, int i); +void drawPeople(Room* self);
A Room.o

          
A TextBox.c

@@ -0,0 +1,168 @@

+#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_ttf.h" +#include "SDL/SDL_mixer.h" +#include "Engine.h" +#include "Timer.h" +#include "Player.h" +#include "TextBox.h" + +extern int quit; +extern int playing; +extern int actionbutton; + +extern SDL_Event event; +extern SDL_Surface* screen; +extern Timer fps; + +extern SDL_Rect* textScroller; +extern SDL_Surface* textBoxBG; +extern SDL_Surface* nextArrow; + +extern TTF_Font* font; +extern SDL_Color textColor; + +extern Player* hero; + +TextBox* newTextBox() +{ + TextBox* self = (TextBox*)malloc(sizeof(TextBox)); + self->portrait = NULL; + self->message = (SDL_Surface**)malloc(4*sizeof(SDL_Surface*)); + self->lines = 0; + self->cursor = 0; + self->scroll = 0; + self->scrollFrom = 0; + return self; +} + +TextBox* newGTextBox(SDL_Surface* image) +{ + TextBox* self = (TextBox*)malloc(sizeof(TextBox)); + self->portrait = image; + self->message = (SDL_Surface**)malloc(4*sizeof(SDL_Surface*)); + self->lines = 0; + self->cursor = 0; + self->scroll = 0; + self->scrollFrom = 0; + return self; +} + +void deleteTextBox(TextBox* target) +{ + int i; + if (target->portrait) SDL_FreeSurface(target->portrait); + for (i = 0; i < target->lines; i++) + { + SDL_FreeSurface(target->message[i]); + } + free(target->message); +} + +void addText(TextBox* self, char* text) +{ + int i; + if ( self->lines != 0 && self->lines%4 == 0) + { + SDL_Surface** templines = (SDL_Surface**)malloc((self->lines+4)*sizeof(SDL_Surface*)); + for (i = 0; i < self->lines; i++) + templines[i] = self->message[i]; + free(self->message); + self->message = templines; + templines = NULL; + } + self->message[self->lines] = TTF_RenderText_Solid(font, text, textColor); + self->lines++; +} + +void displayTextBox(TextBox* self) +{ + int textIsRelevent = 1; + int offset = -32; + int i; + SDL_Rect textScroller = {0, 0, 0, 14}; + actionbutton = 0; + while (textIsRelevent) + { + timeStart(fps); + renderBackground(); + renderForeground(); + + applySurface(22, 51, textBoxBG, screen, NULL); + if (self->portrait) + { + applySurface(32, 58, self->portrait, screen, NULL); + offset = 0; + } + + for (i = self->scrollFrom; i < self->scroll; i++) + { + applySurface(106 + offset, 64+(14*(i%4)), self->message[i], screen, NULL); + } + + textScroller.w = self->cursor*10; + applySurface(106 + offset, 64+(14*(self->scroll%4)), self->message[self->scroll], screen, &textScroller); + + if (self->cursor != 17) + { + self->cursor++; + 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 SDLK_j: + if (self->cursor < 15) self->cursor += 3; + break; + default: break; + } + } + } + } + + + if (self->cursor == 17 && self->scroll+1 != self->lines && (self->scroll+1)%4 != 0) + { + self->cursor = 0; + self->scroll++; + } + if (self->cursor == 17 && ((self->scroll+1)%4 == 0 || self->scroll+1 == self->lines)) + { + applySurface(274, 120, nextArrow, screen, NULL); + 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 SDLK_j: + if (self->scroll + 1 != self->lines) + { + self->cursor = 0; + self->scroll++; + self->scrollFrom += 4; + } + else textIsRelevent = 0; + break; + case SDLK_f: + toggleFullscreen(); + break; + + default: break; + } + } + } + } + SDL_Flip(screen); + timeDilation(); + + } + self->scroll = 0; + self->cursor = 0; + self->scrollFrom = 0; +}
A TextBox.h

@@ -0,0 +1,17 @@

+typedef struct textBox +{ + SDL_Surface* portrait; + SDL_Surface** message; + + int lines; + int cursor; + int scroll; + int scrollFrom; +} TextBox; + +TextBox* newTextBox(); +TextBox* newGTextBox(SDL_Surface* image); +void deleteTextBox(TextBox* target); + +void addText(TextBox* self, char* text); +void displayTextBox(TextBox* self);
A Timer.c

@@ -0,0 +1,27 @@

+#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_ttf.h" + +#include "Timer.h" + +Timer* newTimer() +{ + Timer* self = (Timer*)malloc(sizeof(Timer)); + self->startTicks = 0; + return self; +} + +void timeStart(Timer self) +{ + self.startTicks = SDL_GetTicks(); +} + + + +int getTicks(Timer self) +{ + if (self.startTicks) + return SDL_GetTicks() - self.startTicks; + else return 0; +} +
A Timer.h

@@ -0,0 +1,8 @@

+typedef struct timer +{ + int startTicks; + +} Timer; + +void timeStart(Timer self); +int getTicks(Timer self);
A WorldData.c

@@ -0,0 +1,215 @@

+#include <stdio.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" + +typedef struct timer Timer; +#include "extern.h" + +void bufferData(enum dataChunks chunk) +{ + hasMusic = 0; + applySurface(0,0, loadingTxt, screen, NULL); + SDL_Flip(screen); + switch (chunk){ + case LEVEL1: + bgmData[0] = loadBGM("assets/snd/bgm/artificial sun stage (mamon machine mix).mp3"); + + mapBuffer[0] = newRoom("assets/img/backgrounds/blueroom.gif", 10); + mapBuffer[1] = newRoom("assets/img/backgrounds/redroom.gif", 4); + mapBuffer[2] = newRoom("assets/img/backgrounds/greenroom.gif", 4); + mapBuffer[3] = newRoom("assets/img/backgrounds/darkroom.gif", 4); + + addObstacle(mapBuffer[0], 64,92,22,16); + addFgObj(mapBuffer[0], 64,64,22,55,"assets/img/objects/floatingChips.png", 4, 1); + addObstacle(mapBuffer[0], 320 - 64 - 22, 92,22,16); + addFgObj(mapBuffer[0], 320 - 64 - 22, 64, 22, 55, "assets/img/objects/floatingChips.png", 4, 1); + + addWarp(mapBuffer[0], 0,0,8,180, LEVEL1, 1, 304,90); + addWarp(mapBuffer[0], 312,0,8,180, LEVEL1, 2, 16,90); + addWarp(mapBuffer[0], 0,0,320,8, LEVEL1, 3, 160,164); + + addWarp(mapBuffer[2], 0,0,8,180, LEVEL1, 0, 304,90); + addWarp(mapBuffer[1], 312,0,8,180, LEVEL1, 0, 16,90); + addWarp(mapBuffer[3], 0,172,320,8, LEVEL1, 0, 160,16); + + addWarp(mapBuffer[2], 312,0,8,180, LEVEL2,0, 16,165); + + + dialogueData[0] = newGTextBox(loadImage("assets/img/portraits/test.gif")); + addText(dialogueData[0], "I can't help but feel like I'm"); + addText(dialogueData[0], "trapped in the universe..."); + addText(dialogueData[0], "Do you ever feel that way?"); + addText(dialogueData[0], "It's maddening."); + addText(dialogueData[0], "Let me know if you feel it."); + + dialogueData[1] = newGTextBox(loadImage("assets/img/portraits/kmage.gif")); + addText(dialogueData[1], "Whoa! You and I look so alike!"); + + dialogueData[2] = newTextBox(); + addText(dialogueData[2], "It's a floating computer chip."); + addText(dialogueData[2], "How it can spin forever"); + addText(dialogueData[2], "without slowing or stopping"); + addText(dialogueData[2], "is a mystery to me..."); + addText(dialogueData[2], "Looks damn cool though!"); + + dialogueData[3] = newGTextBox(loadImage("assets/img/portraits/test.gif")); + addText(dialogueData[3], "Well fine then!"); + + dialogueData[4] = newGTextBox(loadImage("assets/img/portraits/test.gif")); + addText(dialogueData[4], "Thanks buddy."); + + kaosData[0] = newConversation(0); + kaosData[1] = newErase('t', 2); + kaosData[2] = newManip(hero, 0, 0); + kaosData[3] = newConversation(1); + kaosData[4] = newManip(hero, 0 ,0); + kaosData[5] = newConversation(2); + kaosData[6] = newConversation(3); + kaosData[7] = newConversation(4); + + HyperKaos* choiceBranchA = newHyperKaos(1,0, 0, 0, 0, 0); + addKaos(choiceBranchA, kaosData[7]); + addKaos(choiceBranchA, kaosData[2]); + addTrigger(mapBuffer[3], choiceBranchA); + choiceBranchA = NULL; + + HyperKaos* choiceBranchB = newHyperKaos(1,0, 0, 0, 0, 0); + addKaos(choiceBranchB, kaosData[6]); + addKaos(choiceBranchB, kaosData[2]); + addTrigger(mapBuffer[3], choiceBranchB); + choiceBranchB = NULL; + + kaosData[8] = newChoice("Let her know?", "Sure thing", "Nope", mapBuffer[3]->eventTriggers[0], mapBuffer[3]->eventTriggers[1]); + + if(notCompleted(3)) + { + HyperKaos* testTextBox = newHyperKaos(3, 0, 0, 0, 320, 180); + addKaos(testTextBox, kaosData[0]); + addKaos(testTextBox, kaosData[1]); + addKaos(testTextBox, kaosData[4]); + addKaos(testTextBox, kaosData[8]); + + addTrigger(mapBuffer[3], testTextBox); + testTextBox = NULL; + } + + Player* randomDude; + if (notCompleted(5)) + randomDude = newPlayer("assets/img/characters/kmage.png", -16, -16); + else + randomDude = newPlayer("assets/img/characters/kmage.png", 160, 90); + + + addPerson(mapBuffer[1], randomDude); + addObstacle(mapBuffer[1], 152,76,16,22); + kaosData[9] = newFaceEachother(hero, randomDude); + kaosData[10] = newTeleport(randomDude, 160, 90, 0); + kaosData[11] = newErase('t', 0); + randomDude = NULL; + + if(notCompleted(5)) + { + HyperKaos* tpDude = newHyperKaos(5, 0, 300, 0, 20, 180); + addKaos(tpDude, kaosData[10]); + addKaos(tpDude, kaosData[11]); + addTrigger(mapBuffer[1],tpDude); + tpDude = NULL; + } + + HyperKaos* randomDudeConvo = newHyperKaos(1, 1, 152, 82, 16, 16); + addKaos(randomDudeConvo, kaosData[3]); + addKaos(randomDudeConvo, kaosData[9]); + addKaos(randomDudeConvo, kaosData[2]); + addTrigger(mapBuffer[1], randomDudeConvo); + randomDudeConvo = NULL; + + HyperKaos* chipDesc1 = newHyperKaos(1,1, 64, 64, 22, 55); + addKaos(chipDesc1, kaosData[5]); + addKaos(chipDesc1, kaosData[2]); + addTrigger(mapBuffer[0], chipDesc1); + chipDesc1 = NULL; + HyperKaos* chipDesc2 = newHyperKaos(1,1, 320 - 64 - 22, 64, 22, 55); + addKaos(chipDesc2, kaosData[5]); + addTrigger(mapBuffer[0], chipDesc2); + chipDesc2 = NULL; + break; + + case LEVEL2: + mapBuffer[0] = newRoom("assets/img/backgrounds/crystal_path.png", 4); + addObstacle(mapBuffer[0], 0,0,320,155); + addObstacle(mapBuffer[0], 0,175,320,10); + addWarp(mapBuffer[0], 0,155,8,20, LEVEL1, 2, 304, 90); + addWarp(mapBuffer[0], 312,155,8,20, LEVEL2, 1, 295, 158); + + mapBuffer[1] = newRoom("assets/img/backgrounds/crystal_room.png", 4); + addObstacle(mapBuffer[1], 0,0,320,115); + addObstacle(mapBuffer[1], 0,115,180,65); + addWarp(mapBuffer[1], 312,172,8,8, LEVEL2, 0, 304, 165); + break; + + case LEVEL3: + break; + } +} + +void dataPurge(int a, int b, int c, int d, int e) +{ + int i; + for (i = 0; i < a; i++) + deleteRoom(mapData[i]); + for (i = 0; i < b; i++) + deleteTextBox(dialogueData[i]); + for (i = 0; i < c; i++) + kaosData[i]->destroy(kaosData[i]); + for (i = 0; i < d; i++) + Mix_FreeMusic(bgmData[i]); + for (i = 0; i < e; i++) + Mix_FreeChunk(sfxData[i]); +} + +void unloadData(enum dataChunks chunk) +{ + switch(chunk) + { + case LEVEL1: + dataPurge(4,5,12,1,0); + break; + case LEVEL2: + dataPurge(2,0,0,0,0); + break; + case LEVEL3: + break; + } +} + +void pushBufferData() +{ + mapData = mapBuffer; + mapBuffer = (Room**)malloc(64*sizeof(Room*)); + if (hasMusic) + Mix_PlayMusic(bgmData[0], -1); +} + +void pager() +{ + if (thisChunk != nextChunk) + { + if (Mix_PlayingMusic()) + { + Mix_HaltMusic(); + } + unloadData(thisChunk); + pushBufferData(); + thisChunk=nextChunk; + } +}
A WorldData.h

@@ -0,0 +1,8 @@

+ +void bufferData(enum dataChunks chunk); + +void unloadData(enum dataChunks chunk); + +void pushBufferData(); + +void pager();
A enum.h

@@ -0,0 +1,8 @@

+#define CHUNKS_H + +enum dataChunks +{ + LEVEL1 = 1, + LEVEL2, + LEVEL3 +};
A extern.h

@@ -0,0 +1,41 @@

+ +extern int fullscreen; +extern int quit; +extern int playing; +extern int actionbutton; +extern int captive; +extern int hasMusic; + + +extern SDL_Event event; +extern SDL_Surface* screen; +extern Timer fps; + +extern Room* rightHere; +extern Room* menuBG; +extern int kaosFlag; +extern long long int savestate; +extern Player* hero; + +extern SDL_Surface* saveMenu; +extern SDL_Surface* textBoxBG; +extern SDL_Surface* choiceBox; +extern SDL_Surface* nextArrow; +extern SDL_Surface* selectArrow; +extern SDL_Surface* loadingTxt; + +extern Mix_Music* menuBGM; + +extern TTF_Font* font; +extern SDL_Color textColor; + +extern enum dataChunks thisChunk; +extern enum dataChunks nextChunk; + +extern Room** mapData; +extern Room** mapBuffer; +extern TextBox** dialogueData; +extern Mix_Music** bgmData; +extern Mix_Chunk** sfxData; +extern Kaos** kaosData; +
A game

          
A main.c

@@ -0,0 +1,93 @@

+#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_ttf.h" +#include "SDL/SDL_mixer.h" +#include <stdio.h> +#include "enum.h" +#include "Engine.h" +#include "Timer.h" +#include "Player.h" +#include "Room.h" +#include "TextBox.h" +#include "Kaos.h" +#include "HyperKaos.h" +#include "WorldData.h" + +/*const int SCREEN_WIDTH = 320; +const int SCREEN_HEIGHT = 180; +const int SCREEN_BPP = 32; + +const int FRAMES_PER_SECOND = 30;*/ + +int fullscreen = 0; +int playing = 0; +int quit = 0; +int actionbutton = 0; +int captive = 0; +int hasMusic = 0; + +Timer fps = { 0 }; +SDL_Event event; + +SDL_Surface* screen = NULL; +Room* rightHere = NULL; + +SDL_Surface* saveMenu = NULL; +SDL_Surface* textBoxBG = NULL; +SDL_Surface* choiceBox = NULL; +SDL_Surface* nextArrow = NULL; +SDL_Surface* selectArrow = NULL; +SDL_Surface* loadingTxt = NULL; + +TTF_Font* font = NULL; +SDL_Color textColor = {255, 255, 255}; + +Player* hero = NULL; +Room* menuBG = NULL; +Mix_Music* menuBGM = NULL; + +long long int savestate = 2; + +Room** mapData = NULL; +Room** mapBuffer = NULL; +TextBox** dialogueData = NULL; +Mix_Music** bgmData = NULL; +Mix_Chunk** sfxData = NULL; +Kaos** kaosData = NULL; + +int kaosFlag = -1; + +enum dataChunks thisChunk; +enum dataChunks nextChunk; + +int main (int argc, char* args[]) +{ + if (!init(argc, args)) + { + printf("Init failed\n"); + return 1; + } + + + // main game loop + while (!quit) + { + mainmenu(); + + while (playing) + { + timeStart(fps); + interact(); + movePlayer(hero, rightHere); + renderBackground(); + renderForeground(); + SDL_Flip(screen); + kListen(&kaosFlag); + pager(); + timeDilation(); + } + } + + cleanup(); + return 0; +}
A sram

@@ -0,0 +1,1 @@

+1 0 198 136 2