diff -r 000000000000 -r b2e3aa63e96c src/devlicks.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devlicks.c Thu Jul 17 22:03:19 2025 -0400 @@ -0,0 +1,309 @@ +/* +Copyright (c) 2023 MCL Software + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "kbdinput.h" +#include "draw.h" +#include "texture.h" +#include "intro.h" +#include "level.h" +#include "common.h" +#include + +SDL_Point offset; +Player player; + +int stealProgress = 0; +Uint64 now = 0; +Uint64 then = 0; +bool fireAlarmSystemActivated = 0; +bool missionScreenShown = 1; + +float applyZoomFactor(float i) +{ + if(zoomFactor > 0) + { + i *= zoomFactor; + } + else + { + i /= -zoomFactor; + } + + return i; +} + +void updateZoomFactor() +{ + destRect.w = applyZoomFactor(TILE_WIDTH); + destRect.h = applyZoomFactor(TILE_HEIGHT); +} + +void drawTiles() +{ + + for(int y = 0; y < 4; y ++) + { + + for(int i = (player.x < 64 ? 0 : player.x - 63); i < (player.x + 64 < LEVEL_WIDTH ? player.x + 64 : LEVEL_WIDTH); i ++) + { + for(int j = (player.y < 64 ? 0 : player.y - 63); j < (player.y + 64 < LEVEL_DEPTH ? player.y + 64 : LEVEL_DEPTH); j ++) + { + SDL_Point coords = tileToPixelCoordinates(i, j); + destRect.x = applyZoomFactor(coords.x + offset.x) + applyZoomFactor(LEVEL_WIDTH); + destRect.y = applyZoomFactor(coords.y + offset.y) - applyZoomFactor(LEVEL_HEIGHT);; + destRect.y -= applyZoomFactor(TILE_HEIGHT / 2 * y); + + // Transform coordinates according to rotation formula + SDL_Point trans = getLevelTransformation(i, j); + + // Check what tile is currently being drawn; this will later be needed + // to determine how it should be drawn. + Object object = getObjectFromIdent(levelTiles[trans.x * LEVEL_WIDTH + trans.y]); + + SDL_Point textureClip; + + // Get the tile's texture + if(object.textureHeight == 2 && y == object.placementHeight + 1) + // For tiles with a texture higher than TILE_HEIGHT + textureClip = getTextureFromIndex(object.textureIndex - 16); + else + textureClip = getTextureFromIndex(object.textureIndex); + + // Multiply coordinates by tile width and height to get the real coordinates on the tilemap + clip.x = textureClip.x * 89; + clip.y = textureClip.y * 90; + + // This sets the destination rectangle's width and height + // TODO: figure out a more efficient way to do this without calling this function for every tile + updateZoomFactor(); + + if(y < object.placementHeight + object.height && y >= object.placementHeight) + SDL_RenderCopyEx(renderer, tilemap, &clip, &destRect, 0, 0, SDL_FLIP_HORIZONTAL ? orientation % 2 == 0 ? object.flipTexture : !object.flipTexture : 0); + else if(y == 0 && object.renderUnder) + // Render tile at Y: 0 for tiles that are transparent and/or above the ground + SDL_RenderCopy(renderer, tilemap, &(SDL_Rect){89, 0, 89, 90}, &destRect); + else if(y == 3 && object.renderAbove) + { + SDL_RenderCopy(renderer, tilemap, &(SDL_Rect){356, 0, 89, 90}, &destRect); + } + + //SDL_Point transPlayer = getTransformation(player.x, player.y); + + // Render player + if(y == 1 && trans.x == player.x && trans.y == player.y) + { + textureClip = getTextureFromIndex(33); + clip.x = textureClip.x * 89; + clip.y = textureClip.y * 90; + clip.w = 89; + clip.h = 90; + + //SDL_Point newDestRect = getTransformation(applyZoomFactor(coords.x + offset.x) + applyZoomFactor(LEVEL_WIDTH), applyZoomFactor(coords.y + offset.y) - applyZoomFactor(LEVEL_HEIGHT)); + + //destRect.x = newDestRect.x; + //destRect.y = newDestRect.y; + //destRect.y -= applyZoomFactor(TILE_HEIGHT / 2 * y); + SDL_RenderCopy(renderer, tilemap, &clip, &destRect); + } + } + } + } +} + + + +Object getObjectProperties(char object) +{ + Object objectProps; + objectProps.textureIndex = 0; + objectProps.stealable = true; + objectProps.height = 2; + objectProps.interactable = -1;; + objectProps.passable = false; + + return objectProps; +} + +int main(int argc, char *argv[]) +{ + loadLevelFromFile(); + + initMissions(); + + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO); + + Mix_Init(MIX_INIT_OGG); + + Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048); + + alarmSound = Mix_LoadWAV("alarm.wav"); + + themeSong = Mix_LoadMUS("audio/music/DeviousLicks.ogg"); + bgm1 = Mix_LoadMUS("audio/music/Class1.ogg"); + bgm2 = Mix_LoadMUS("audio/music/Class2.ogg"); + bgm3 = Mix_LoadMUS("audio/music/Class3.ogg"); + bgm4 = Mix_LoadMUS("audio/music/ANewReality.ogg"); // todo: move this track further down + bgm5 = Mix_LoadMUS("audio/music/Recollection.ogg"); + bgm6 = Mix_LoadMUS("audio/music/TheSadReality1.ogg"); + bgm7 = Mix_LoadMUS("audio/music/TheSadReality2.ogg"); + bgm8 = Mix_LoadMUS("audio/music/TheXXXReality.ogg"); + bgm9 = Mix_LoadMUS("audio/music/FirstDay.ogg"); + bgm10 = Mix_LoadMUS("audio/music/FirstDayAlternateVersion.ogg"); + bgm11 = Mix_LoadMUS("audio/music/Hallway1.ogg"); + bgm12 = Mix_LoadMUS("audio/music/Hallway2.ogg"); + bgm13 = Mix_LoadMUS("audio/music/Hallway3.ogg"); + bgm14 = Mix_LoadMUS("audio/music/Hallway4.ogg"); + //creditsTheme = Mix_LoadMUS("audio/music/Credits.ogg"); + + Mix_PlayMusic(themeSong, -1); + + SDL_Window* window = SDL_CreateWindow("Devious Licks", 170, 70, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + initGraphics(); + + SDL_Event event; + bool quit = false; + + // Title Screen + while(!gameRunning) + { + drawTitleScreen(); + while(SDL_PollEvent(&event)) + { + handleKeyboard(event); + + if(!performMenuKeyActions() || event.type == SDL_QUIT) + { + gameRunning = 1; + quit = true; + } + } + } + + // Intro + // 0 - enabled + // 1 - disabled (skip) + gameRunning = 0; + + Mix_PlayMusic(bgm7, -1); + + while(!gameRunning && !quit) + { + if(INTR_DrawIntro()) + gameRunning = 1; + + while(SDL_PollEvent(&event)) + { + handleKeyboard(event); + + if(event.type == SDL_QUIT) + { + gameRunning = 1; + quit = true; + } + } + } + + Mix_HaltMusic(); + + srand(time(0)); // set seed for pseudoRNG with RTC + + /*int nextTrack = rand() % 16; + + Mix_PlayMusic(nextTrack == 0 ? bgm1 : nextTrack == 1 ? bgm2 : nextTrack == 2 ? bgm3 : nextTrack == 3 ? bgm4 : nextTrack == 4 ? bgm5 : nextTrack == 5 ? bgm6 : nextTrack == 6 ? bgm7 : nextTrack == 7 ? bgm8 : nextTrack == 8 ? bgm9 : nextTrack == 9 ? bgm10 : nextTrack == 10 ? bgm11 : nextTrack == 11 ? bgm12 : nextTrack == 12 ? bgm13 : bgm14, 1); + */ + clip = (SDL_Rect){89, 0, 89, 90}; + + destRect.x = 0; + destRect.y = 0; + updateZoomFactor(); + + offset.x = -2420; + offset.y = -1870; + + player.x = 75; + player.y = 25; + + while(!quit) + { + now = SDL_GetTicks(); + + SDL_RenderClear(renderer); + + //SDL_GetMouseState(&mouseX, &mouseY); + + drawTiles(); + + if(levelTiles[(player.x + 1) * LEVEL_WIDTH + player.y] == 'D' || levelTiles[(player.x - 1) * LEVEL_WIDTH + player.y] == 'D' || levelTiles[player.x * LEVEL_WIDTH + player.y + 1] == 'D' || levelTiles[player.x * LEVEL_WIDTH + player.y - 1] == 'D') + { + drawLeaveSchool(); + player.leftCampus = performYesNo() ? true : false; + } + + drawHUD(); + + if(missionScreenShown && drawMissionScreen()) + { + missionScreenShown = 0; + } + + if(checkForMissionComplete(currentMission)) + { + drawGoToExit(); + if(player.leftCampus) + { + offset.x = -2420; + offset.y = -1870; + player.x = 75; + player.y = 25; + if(drawMissionComplete()) + { + missionScreenShown = 1; + } + } + } + SDL_SetRenderDrawColor(renderer, 10, 180, 255, 255); + SDL_RenderPresent(renderer); + + // Cycle music + if(!Mix_PlayingMusic()) + { + int nextTrack = rand() % 16; + + Mix_PlayMusic(nextTrack == 0 ? bgm1 : nextTrack == 1 ? bgm2 : nextTrack == 2 ? bgm3 : nextTrack == 3 ? bgm4 : nextTrack == 4 ? bgm5 : nextTrack == 5 ? bgm6 : nextTrack == 6 ? bgm7 : nextTrack == 7 ? bgm8 : nextTrack == 8 ? bgm9 : nextTrack == 9 ? bgm10 : nextTrack == 10 ? bgm11 : nextTrack == 11 ? bgm12 : nextTrack == 12 ? bgm13 : bgm14, 1); + } + + + // Handle all queued events + while(SDL_PollEvent(&event)) + { + handleKeyboard(event); + + if(event.type == SDL_QUIT) + quit = true; + } + + if(now - then > 100) + { + if(performPlayerMovement()) + then = now; + } + } + + SDL_RemoveTimer(fireAlarmTimer); + SDL_DestroyWindow(window); + + return ISOL_Terminate(); +}