hyperkaos/Engine.c

531 lines
12 KiB
C

#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 "config.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 "Scene.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 DPAD_UP:
hero->bearing.y = -2;
break;
case DPAD_LEFT:
hero->bearing.x = -2;
break;
case DPAD_DOWN:
hero->bearing.y = 2;
break;
case DPAD_RIGHT:
hero->bearing.x = 2;
break;
case A_BUTTON:
actionbutton = 1;
break;
case B_BUTTON:
spellbutton = 1;
case PAUSE_BUTTON:
pausemenu();
break;
case FS_BUTTON:
toggleFullscreen();
break;
default: break;
}
break;
case SDL_KEYUP:
switch( event.key.keysym.sym )
{
case DPAD_UP:
if (hero->bearing.y < 0)
{
hero->bearing.y = 0;
}
break;
case DPAD_LEFT:
if (hero->bearing.x < 0)
{
hero->bearing.x = 0 ;
}
break;
case DPAD_DOWN:
if (hero->bearing.y > 0)
{
hero->bearing.y = 0;
}
break;
case DPAD_RIGHT:
if (hero->bearing.x > 0)
{
hero->bearing.x = 0;
}
break;
case A_BUTTON:
actionbutton = 0;
break;
case B_BUTTON:
spellbutton = 0;
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 = malloc(64*sizeof(Room*));
mapBuffer= malloc(64*sizeof(Room*));
dialogueData = malloc(124*sizeof(Room*));
bgmData = malloc(8*sizeof(Mix_Music*));
sfxData = malloc(24*sizeof(Mix_Chunk*));
kaosData = malloc(124*sizeof(Kaos*));
theatre = malloc(8*sizeof(Scene*));
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);
free(theatre);
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 intro()
{
SDL_Color black = {0,0,0};
SLayer* nebula = newSLayer(loadImage("assets/img/backgrounds/presents.png"), 0,0,0,0,255);
SLayer* fogF = newSLayer(loadImage("assets/img/fx/fog.png"), 0,0,-1,0,128);
SLayer* fogB = newSLayer(loadImage("assets/img/fx/plasma.png"), -320,0,1,0,56);
SLayer* presents = newSLayer(TTF_RenderText_Solid(font, "nilFM presents", textColor), 120,84,0,0,128);
SLayer* menuTransition = newSLayer(loadImage("assets/img/backgrounds/mainmenu.png"),0,0,0,0,255);
Scene* intro = newScene(30,30, 200, black, black);
Scene* transition = newScene(30,0,30, black, black);
buildScene(intro, nebula);
buildScene(intro, fogB);
buildScene(intro, fogF);
buildScene(intro, presents);
buildScene(transition, menuTransition);
playScene(intro);
playScene(transition);
deleteScene(intro);
deleteScene(transition);
}
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 DPAD_UP:
menucounter--;
break;
case DPAD_DOWN:
menucounter++;
break;
case A_BUTTON:
select = 1;
break;
case FS_BUTTON:
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 DPAD_UP:
menucounter--;
break;
case DPAD_DOWN:
menucounter++;
break;
case A_BUTTON:
select = 1;
break;
case PAUSE_BUTTON:
paused = 0;
break;
case FS_BUTTON:
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);
}