commit 3eebc5c61aeca5bbba5ba737c4cf3ad224f2de9f Author: Scott Duensing Date: Sun Aug 7 19:11:43 2022 -0500 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..77282fa --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.ttf filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3ed8b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +Docs/ +Unused/ diff --git a/Fonts/FreeLicense.txt b/Fonts/FreeLicense.txt new file mode 100644 index 0000000..e48a09b --- /dev/null +++ b/Fonts/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/Fonts/PrintChar21.ttf b/Fonts/PrintChar21.ttf new file mode 100644 index 0000000..9e7a35c --- /dev/null +++ b/Fonts/PrintChar21.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c199b39eeae2a817c4f44bd1bdbcbead974e87dc4c7401193db831be2f2470e1 +size 501992 diff --git a/Images/01234.jpg b/Images/01234.jpg new file mode 100644 index 0000000..8578a90 --- /dev/null +++ b/Images/01234.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67adcef5f4179edcb138edafe423ddf077089df05e0b8bc59bee36c866e46a9f +size 42091 diff --git a/Images/02550.jpg b/Images/02550.jpg new file mode 100644 index 0000000..153d698 --- /dev/null +++ b/Images/02550.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b88ff828aa892ea0cc429bf0176bf3e1a36e0cfab180ad644592559f5a4bd0eb +size 44555 diff --git a/Images/02818.jpg b/Images/02818.jpg new file mode 100644 index 0000000..60e64c0 --- /dev/null +++ b/Images/02818.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:047f2dca29f614cd6723b75396d524dafa9160339fd8c52bf6d7fb40fcec1ce2 +size 55512 diff --git a/Images/04002.jpg b/Images/04002.jpg new file mode 100644 index 0000000..bcf113b --- /dev/null +++ b/Images/04002.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:917ee9b2a12829cd5aa0b44b383a747dc1dfa9646355cb6e115c23289ce26c36 +size 68908 diff --git a/Images/04627.jpg b/Images/04627.jpg new file mode 100644 index 0000000..1c391f2 --- /dev/null +++ b/Images/04627.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1a11ada13088a4a8afe4481d6a2faca010cb4d1e50f0f6e41669a063568547d +size 61152 diff --git a/Images/04750.jpg b/Images/04750.jpg new file mode 100644 index 0000000..161f2bc --- /dev/null +++ b/Images/04750.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5290e3df11c3ea94e46e6daf0591f2ad866d19d665c7268022f1a3e113cd3825 +size 53458 diff --git a/Images/05890.jpg b/Images/05890.jpg new file mode 100644 index 0000000..e07af8a --- /dev/null +++ b/Images/05890.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f6622d3c6a036e0c528d57cc1ff900b6e53790aa7102d9ea4ebacb82dff113c +size 58189 diff --git a/Images/07343.jpg b/Images/07343.jpg new file mode 100644 index 0000000..e35757c --- /dev/null +++ b/Images/07343.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91cdacb98fc5d3919addb2d52fbe79af3edeae530517104e878af734a958577d +size 31491 diff --git a/Images/11000.jpg b/Images/11000.jpg new file mode 100644 index 0000000..9927d14 --- /dev/null +++ b/Images/11000.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7c95237bf700479c7b4ef27bbb610ecbab0be93de9438c9e08eb708b24e5b8b +size 43208 diff --git a/Images/15362.jpg b/Images/15362.jpg new file mode 100644 index 0000000..c2d2946 --- /dev/null +++ b/Images/15362.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d597976b70c9878fc72123d8c2439cccaa059f3aa90937181a376001e99b518 +size 41440 diff --git a/Images/21130.jpg b/Images/21130.jpg new file mode 100644 index 0000000..eaec930 --- /dev/null +++ b/Images/21130.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94f82d6981893261da5b85cd790378c17c1a8f1067db514ea4c1df6c3ee90f02 +size 34613 diff --git a/Images/23100.jpg b/Images/23100.jpg new file mode 100644 index 0000000..648b71e --- /dev/null +++ b/Images/23100.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30c8c9b363ac5fce7c5a436f031d006867ec26992794b0fdcbb514a019c00525 +size 44567 diff --git a/Images/28322.jpg b/Images/28322.jpg new file mode 100644 index 0000000..ed9d703 --- /dev/null +++ b/Images/28322.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca79172047348042b6a6714dd14792f9a708fce79d5493264724a16337fc7964 +size 46261 diff --git a/Images/33900.jpg b/Images/33900.jpg new file mode 100644 index 0000000..0ff5326 --- /dev/null +++ b/Images/33900.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11f0163753f593432c44aa527e3c41fd80d5b50cdfa523f0933c488dcb032880 +size 44699 diff --git a/Rollercoaster.singe b/Rollercoaster.singe new file mode 100644 index 0000000..f212904 --- /dev/null +++ b/Rollercoaster.singe @@ -0,0 +1,1065 @@ + +-- Load the Singe Framework. +dofile("Singe/Framework.singe") + + +-- Declare any global variables you need here. +GAME = "Rollercoaster" + +ON = 1 +OFF = 0 + +MARGIN = 10 -- How many pixels from the edges to display text +INPUT = "" -- Keyboard input buffer +KEY = 0 -- Last key pressed +BLINK = 0 -- Cursor blink timer +KEYHIT_ON = OFF -- Waiting for a single key? +KEYBOARD_ON = OFF -- Keyboard on or off +SCREEN = {} -- Text screen buffer +SCREEN_LINES = 0 -- Number of lines that fit on the screen +SCREEN_COLS = 0 -- Number of columns that fit on the screen +SCREEN_ON = ON -- Screen being displayed or hidden +STATES = {} -- Game engine states +STATE = 0 -- Current game state +NEXT_STATE = 0 -- Used when we need to assign a new state after a long operation +JPGS = {} -- Loaded JPG images +SHOW_JPG = -1 -- If not -1, the id of the JPG to display +END_FRAME = -1 -- If not -1, play video until this frame is reached +DELAY = 0 -- How long to sit before next state, in roughly half seconds + +-- Game Engine States +STATE_NONE = -1 +STATE_GET_NAME = 1 +STATE_GOT_NAME = 2 +STATE_BOMB_PLANTED = 3 +STATE_PLANE_ARRIVED = 4 +STATE_INSTRUCTIONS = 5 +STATE_LOOK = 6 +STATE_LOOK_DELAY = 7 +STATE_LOOK_VIDEO = 8 +STATE_LOOK_TEXT = 9 +STATE_ROOM_5 = 10 +STATE_ROOM_8 = 11 +STATE_ROOM_9 = 12 +STATE_ROOM_15 = 13 +STATE_ROOM_18 = 14 +STATE_PARSER = 15 +STATE_BOOM = 16 +STATE_PLAY_AGAIN = 17 + +-- Apple II 40 column font. +fntApple12 = fontLoad(GAME .. "/Fonts/PrintChar21.ttf", 12) +fntApple12Height = 0 -- We'll figure this out later +fntApple12Width = 0 -- We'll figure this out later + +-- Game Data +L = 0 -- Current location +NO = 0 -- Number of objects +NA = "" -- Player's name +T = 0 -- Time +BK = 0 -- Has read book + +DIRECTIONS = { + "NORTH", + "EAST", + "SOUTH", + "WEST" +} + +ROOMS = { + { -- A 1 + EXITS = "EDKC", + NAME = "THE MIDWAY", + DESCRIPTION = "WHICH STRETCHES TO THE EAST AND WEST. A RESTAURANT IS TO THE NORTH.", + VIDEO = "FR4002SE/" + }, { + -- B 2 + EXITS = "@JC@", + NAME = "THE FIRST AID STATION", + DESCRIPTION = "CONTAINING STRANGE EQUIPMENT. LIGHTS FLASH FROM AN ELECTRONIC BOX.", + VIDEO = "FR21130SE/" + }, { + -- C 3 + EXITS = "BAFG", + NAME = "THE MIDWAY", + DESCRIPTION = "AN AID STATION IS TO THE NORTH. THE SOUND OF GUNFIRE COMES FROM A SHOOTING GALLERY TO THE SOUTH.", + VIDEO = "FR4627SE/" + }, { + -- D 4 + EXITS = "@PHA", + NAME = "THE MIDWAY", + DESCRIPTION = "FROM A TENT TO THE SOUTH YOU HEAR EXOTIC MUSIC.", + VIDEO = "FR4750SE/" + }, { + -- E 5 + EXITS = "@@A@", + NAME = "A RESTAURANT", + DESCRIPTION = "THE ROOM IS CROWDED BUT YOU SEE AN EMPTY TABLE IN THE CORNER.", + VIDEO = "FR23100SE/" + }, { + -- F 6 + EXITS = "C@@@", + NAME = "A SHOOTING GALLERY", + DESCRIPTION = "A SIGN READS '3 SHOTS FOR 25 CENTS.'", + VIDEO = "FR11000SE/" + }, { + -- G 7 + EXITS = "MCQ@", + NAME = "A MAINTENANCE ROOM", + DESCRIPTION = "THERE ARE DOORS TO THE NORTH AND SOUTH. THE NORTHERN DOOR IS OPEN. YOU CAN HEAR THE ROLLER COASTER.", + VIDEO = "FR14038SE/FR14100PL/" + }, { + -- H 8 + EXITS = "D@N@", + NAME = "THE BELLY DANCER'S TENT", + DESCRIPTION = "SHE STOPS AND LOOKS AT YOU.", + VIDEO = "FR11818SE/FR11907PL/" + }, { + -- I 9 + EXITS = "@@M@", + NAME = "THE TOP OF THE ROLLER COASTER", + DESCRIPTION = "A DANGEROUS PLACE TO BE.", + VIDEO = "FR15362SE/" + }, { + -- J 10 + EXITS = "@@@B", + NAME = "A CLOSET", + DESCRIPTION = "", + VIDEO = "" + }, { + -- K 11 + EXITS = "A@O@", + NAME = "AN ALLEY", + DESCRIPTION = "THERE IS A DOOR LEADING TO A SMALL ROOM TO THE SOUTH.", + VIDEO = "" + }, { + -- L 12 + EXITS = "Q@@@", + NAME = "THE OBSERVATION TOWER", + DESCRIPTION = "BELOW, YOU CAN SEE THE WHOLE CARNIVAL. THE TOP OF THE ROLLER COASTER IS IN SIGHT.", + VIDEO = "FR8300SE/FR8488PL/" + }, { + -- M 13 + EXITS = "I@G@", + NAME = "A CRAWLWAY", + DESCRIPTION = "THE PASSAGE LEADS NORTH TO THE TOP OF THE ROLLER COASTER. THE NOISE IS QUITE LOUD.", + VIDEO = "FR14724SE/FR14855PL/" + }, { + -- N 14 + EXITS = "@@@R", + NAME = "A STORAGE ROOM", + DESCRIPTION = "THE DOOR IS LOCKED BEHIND YOU, BUT THERE IS A WINDOW TO THE WEST.", + VIDEO = "FR33900SE/" + }, { + -- O 15 + EXITS = "K@@@", + NAME = "A SMALL SHACK", + DESCRIPTION = "THE ROOM IS LITTERED WITH FRAGMENTS OF ELECTRONIC PARTS, BUT NONE OF IT IS SALVAGEABLE. A GUARD BLOCKS YOUR PATH.", + VIDEO = "FR28322SE/" + }, { + -- P 16 + EXITS = "@@@D", + NAME = "A GAME BOOTH", + DESCRIPTION = "A SIGN SAYS, '50 CENTS A BALL. WINNER'S CHOICE.'", + VIDEO = "FR7343SE/" + }, { + -- Q 17 + EXITS = "G@L@", + NAME = "A NARROW TUNNEL", + DESCRIPTION = "THE PASSAGE LEADS SOUTH TO THE TOP OF THE OBSERVATION TOWER.", + VIDEO = "" + }, { + -- R 18 + EXITS = "@@@@", + NAME = "A DARK, TWISTING PATH.", + DESCRIPTION = "", + VIDEO = "" + } +} + +OBJECTS = { + { + NAME = "COINS", + DESCRIPTION = "TWO DIMES AND A NICKEL", + LOCATION = 4 + }, { + NAME = "TOOLKIT", + DESCRIPTION = "IT CONTAINS EVERYTHING NEEDED FOR SMALL ELECTRONIC REPAIRS", + LOCATION = 7 + }, { + NAME = "TICKET", + DESCRIPTION = "IT SAYS, 'GOOD FOR 1 FREE GAME AT THE BALL TOSS, COURTESY OF CREATIVE COMPUTING, THE #1 MAGAZINE OF SOFTWARE AND APPLICATIONS.'", + LOCATION = 14 + }, { + NAME = "BOOK", + DESCRIPTION = "THE TITLE IS 'RADIO FREQUENCY JAMMING TECHNIQUES.'", + LOCATION = 15 + }, { + NAME = "LAMP", + DESCRIPTION = "IT IS VERY GAUDY.", + LOCATION = -1 + }, { + NAME = "TOWELS", + DESCRIPTION = "NICE AND FLUFFY.", + LOCATION = -1 + }, { + NAME = "POSTER", + DESCRIPTION = "WHOOPIE -- IT'S THE DALLAS CHEERLEADERS.", + LOCATION = -1 + }, { + NAME = "BEAR", + DESCRIPTION = "WHEN YOU PUSH THE BUTTON ON ITS BACK, IT SAYS 'I WUV YOU.'", + LOCATION = -1 + }, { + NAME = "UNIFORM", + DESCRIPTION = "", + LOCATION = 10 + }, { + NAME = "RADIO", + DESCRIPTION = "", + LOCATION = -1 + }, { + NAME = "BATTERIES", + DESCRIPTION = "", + LOCATION = -1 + }, { + NAME = "JAMMER", + DESCRIPTION = "", + LOCATION = -1 + } +} + +FURNITURE = { + { + NAME = "BOX", + DESCRIPTION = "IT IS FIRMLY ATTACHED TO THE TABLE. THERE ARE KNOBS AND A BUTTON ON IT.", + LOCATION = 0 + }, { + NAME = "RIFLE", + DESCRIPTION = "IT IS CHAINED TO THE COUNTER.", + LOCATION = 6 + }, { + NAME = "GUN", + DESCRIPTION = "IT IS CHAINED TO THE COUNTER.", + LOCATION = 6 + } +} + + +function onKeyPressed(key, scancode) + + -- Rude exit + if scancode == SCANCODE.ESCAPE.value then + singeQuit() + end + + if KEYBOARD_ON == ON then + -- SPACE, ENTER, and BACKSPACE + if key == 32 or key == 13 or key == 8 then + KEY = key + end + + -- Letters + if key > 96 and key < 123 then + KEY = key - 32 + end + end + + -- Handle waiting for any keypress + if KEYHIT_ON == ON then + KEYHIT_ON = OFF + STATE = NEXT_STATE + NEXT_STATE = STATE_NONE + end + +end + + +function onOverlayUpdate() + + local cursor = "_" -- Can't use the nice Apple II cursor - it's outside the ASCII range on this font! + local x = 0 + local y = 0 + + if SHOW_JPG ~= -1 then + colorBackground(0, 0, 0, 255) -- The 255 makes this black opaque to hide the blue disc stopped screen. + overlayClear() + colorBackground(0, 0, 0, 0) -- Then we set it back to transparent for future rendering. + + x = (overlayGetWidth() - spriteGetWidth(SHOW_JPG)) * 0.5 + y = (overlayGetHeight() - spriteGetHeight(SHOW_JPG)) * 0.5 + if x < 0 then x = 0 end + if y < 0 then y = 0 end + spriteDraw(x, y, SHOW_JPG) + discStop() + else + overlayClear() + end + + if END_FRAME ~= -1 then + if (discGetFrame() >= END_FRAME) then + discSearch(END_FRAME) + END_FRAME = -1 + STATE = NEXT_STATE + NEXT_STATE = STATE_NONE + KEYBOARD_ON = ON + end + end + + -- Blink cursor and handle delay events + BLINK = BLINK + 1 + if BLINK > 15 then + cursor = " " + if BLINK > 30 then + BLINK = 0 + -- Are we delaying for something? + if DELAY > 0 then + KEYBOARD_ON = OFF + DELAY = DELAY - 1 + if DELAY == 0 then + STATE = NEXT_STATE + NEXT_STATE = STATE_NONE + KEYBOARD_ON = ON + end + end + end + end + + if KEYHIT_ON == ON then + KEYBOARD_ON = OFF + end + + if KEYBOARD_ON == ON then + -- Handle keyboard + if KEY ~= 0 then + if KEY == 13 then + -- ENTER + processInput() + else + if KEY == 8 then + -- Backspace + if string.len(INPUT) > 0 then + INPUT = INPUT:sub(1, -2) + end + else + -- Typing + if string.len(INPUT) < 40 then + INPUT = INPUT .. string.char(KEY) + end + end + end + KEY = 0 + end + + -- Draw input buffer + shadowPrint(MARGIN, overlayGetHeight() - fntApple12Height - MARGIN, ">" .. INPUT .. cursor) + + end + + if SCREEN_ON == ON then + -- Draw text screen + y = overlayGetHeight() - fntApple12Height * (SCREEN_LINES + 1) - MARGIN + for i = 1,SCREEN_LINES,1 do + shadowPrint(MARGIN, y, SCREEN[i]) + y = y + fntApple12Height + end + end + + processGameState("") + + return(OVERLAY_UPDATED) +end + + +function pioneer(newstate, command) + + local frames = {} -- List of frames in command string. + local count = 0 -- How many did we get? + + -- Split up multiple commands + for temp in string.gmatch(command, "([^/]+)") do + -- Clean up string so we only have frame numbers + temp = temp:gsub("FR", "") + temp = temp:gsub("SE", "") + temp = temp:gsub("PL", "") + -- Ensure frame numbers are zero padded to 5 digits. + while(string.len(temp) < 5) do + temp = "0" .. temp + end + -- Add to frame list + table.insert(frames, temp) + count = count + 1 + end + + -- All used commands in this program are either a single + -- seek to display a JPG or a seek and then a play to + -- display a bit of video. That's all we handle. + + -- Are we just seeking to a static frame? + if count == 1 then + -- Have we loaded this JPG already? + if JPGS[frames[1]] == nil then + -- Nope! Load it. + JPGS[frames[1]] = spriteLoad(GAME .. "/Images/" .. frames[1] .. ".jpg") + end + -- Show it. + SHOW_JPG = JPGS[frames[1]] + STATE = newstate + end + + -- Are we playing a sequence? + if count == 2 then + -- Hide any displayed JPG. + SHOW_JPG = -1 + -- Start playing at requested frame. + discSkipToFrame(tonumber(frames[1])) + -- Tell onOverlayUpdate to watch for the end frame. + END_FRAME = tonumber(frames[2]) + -- Hide keyboard while video runs. + KEYBOARD_ON = OFF + NEXT_STATE = newstate + end + +end + + +function processGameState(what) + + -- If we have a next state, we should not have a current state. + if NEXT_STATE ~= STATE_NONE then + STATE = STATE_NONE + end + + local func = STATES[STATE] + + if (func) then + func(what) + end + +end + + +function processInput() + + -- Send input to processGameState and display on screen. + if INPUT ~= "" then + screenPrint(INPUT) + if NEXT_STATE ~= STATE_NONE then + STATE = NEXT_STATE + NEXT_STATE = STATE_NONE + end + processGameState(INPUT) + end + + INPUT = "" + +end + + +function resetGameData() + L = 1 -- Current location + NO = 12 -- Number of objects + NA = "" -- Player's name + T = 0 -- Time + BK = 0 -- Has read book +end + + +function screenClear() + -- Get our screen metrics + SCREEN_LINES = ((overlayGetHeight() - MARGIN * 2) // fntApple12Height) - 1 + SCREEN_COLS = ((overlayGetWidth() - MARGIN * 2) // fntApple12Width) + + -- Fill it with nothing. + for i = 1,SCREEN_LINES,1 do + SCREEN[i] = " " + end +end + + +function screenPrint(what) + + local x = 0 + + -- Do we need to word wrap this line? + if string.len(what) > SCREEN_COLS then + x = SCREEN_COLS + while (what:sub(x, x) ~= " " and x > 1) do + x = x - 1 + end + if x > 1 then + screenPrint(what:sub(1, x - 1)) + screenPrint(what:sub(x + 1, string.len(what))) + return + end + end + + -- Scroll screen up a line. + for i = 1,SCREEN_LINES-1,1 do + SCREEN[i] = SCREEN[i + 1] + end + + -- Can't render empty text, it crashes Singe. + if what == "" then + what = " " + end + + SCREEN[SCREEN_LINES] = what + +end + + +function shadowPrint(x, y, what) + + colorForeground(0, 0, 0) + for i = -1,1,1 do + fontPrint(x + 1, y + i, what) + fontPrint(x - 1, y + i, what) + end + colorForeground(255, 255, 255) + fontPrint(x, y, what) + +end + + +-- Game engine states +STATES = { + [STATE_GET_NAME] = function(what) + screenPrint("WHAT IS YOUR FIRST NAME?") + KEYBOARD_ON = ON + NEXT_STATE = STATE_GOT_NAME + end, + + [STATE_GOT_NAME] = function(what) + NA = what + screenPrint("") + screenPrint("YOU HAVE JUST RECEIVED AN ANONYMOUS") + screenPrint("TIP THAT A BOMB HAS BEEN PLANTED") + screenPrint("ON A ROLLER COASTER.") + pioneer(STATE_BOMB_PLANTED, "FR6726SE/FR6959PL/") + end, + + [STATE_BOMB_PLANTED] = function(what) + screenPrint("") + screenPrint("YOU ARE CALLED TO INVESTIGATE AND FLY") + screenPrint("OFF TO STOP THE SABOTEUR.") + pioneer(STATE_PLANE_ARRIVED, "FR30032SE/FR30214PL/") + end, + + [STATE_PLANE_ARRIVED] = function(what) + screenPrint("") + screenPrint("ON HIS SIDE, HE HAS THE BRILLIANCE OF") + screenPrint("AN INSANE MIND, AND THE AID OF ALLIES") + screenPrint("WHO ARE DETERMINED TO SEE THAT YOU FAIL.") + screenPrint("") + screenPrint("ON YOUR SIDE, YOU HAVE CUNNING,") + screenPrint("TRAINING, AND DEDICATION.") + screenPrint("") + screenPrint("YOU HAVE INFILTRATED THE PARK WITH") + screenPrint("THE KNOWLEDGE THAT THE SABOTEUR") + screenPrint("WILL STRIKE SOMETIME TONIGHT.") + screenPrint("") + screenPrint("ALL YOU NEED DO IS STOP HIM.") + screenPrint("") + screenPrint("") + screenPrint("PRESS ANY KEY TO CONTINUE.") + KEYHIT_ON = ON + NEXT_STATE = STATE_INSTRUCTIONS + end, + + [STATE_INSTRUCTIONS] = function(what) + screenClear() + screenPrint("BY GIVING THE RIGHT COMMAND, YOU CAN") + screenPrint("MOVE, EXAMINE OBJECTS, AND PERFORM") + screenPrint("OTHER ACTIONS.") + screenPrint("") + screenPrint("I UNDERSTAND TWO-WORD COMMANDS SUCH AS") + screenPrint("'DROP BOOK' OR 'TAKE KNIFE'.") + screenPrint("TO MOVE, YOU CAN SIMPLY ENTER 'N' FOR") + screenPrint("NORTH, ETC.") + screenPrint("") + screenPrint("AT TIMES, I WILL AWAIT YOUR COMMAND") + screenPrint("IN OTHER SITUATIONS, I WILL PRESENT YOU") + screenPrint("WITH A CHOICE OF ACTIONS.") + screenPrint("") + screenPrint("BUT SUCCESS OR FAILURE IS UP TO YOU.") + screenPrint("") + screenPrint("") + screenPrint("PRESS ANY KEY TO BEGIN. MAY LUCK BE") + screenPrint("WITH YOU, " .. NA .. ".") + KEYHIT_ON = ON + NEXT_STATE = STATE_LOOK + end, + + [STATE_LOOK] = function(what) + -- Do we want to show the "looking" frame? + if math.random() > 10.6 then + pioneer(STATE_LOOK_DELAY, "FR2550SE/") + else + STATE = STATE_LOOK_VIDEO + end + end, + + [STATE_LOOK_DELAY] = function(what) + DELAY = 4 + NEXT_STATE = STATE_LOOK_VIDEO + end, + + [STATE_LOOK_VIDEO] = function(what) + if ROOMS[L].VIDEO ~= "" then + -- Show room + pioneer(STATE_LOOK_TEXT, ROOMS[L].VIDEO) + else + STATE = STATE_LOOK_TEXT + end + end, + + [STATE_LOOK_TEXT] = function(what) + local found = 0 + local exits = "" + + KEYBOARD_ON = ON + + -- Description + screenPrint("") + screenPrint("YOU ARE IN " .. ROOMS[L].NAME) + screenPrint(ROOMS[L].DESCRIPTION) + -- Contents + screenPrint("THIS LOCATION CONTAINS:") + for i = 1,NO,1 do + if OBJECTS[i].LOCATION == L then + screenPrint(OBJECTS[i].NAME) + found = 1 + end + end + if found == 0 then + screenPrint("NOTHING") + end + -- Exits + for i = 1,4,1 do + if ROOMS[L].EXITS:sub(i, 1) ~= "@" then + exits = exits .. DIRECTIONS[i] .. " " + end + end + if exits == "" then + exits = "DON'T EXIST" + end + screenPrint("VISIBLE EXITS: " .. exits) + screenPrint("") + + -- Special room code. Not the best way to do this, but it follows the original code. + if L == 5 then + STATE = STATE_ROOM_5 + return + end + if L == 8 then + STATE = STATE_ROOM_8 + return + end + if L == 9 then + STATE = STATE_ROOM_9 + return + end + if L == 15 then + STATE = STATE_ROOM_15 + return + end + if L == 18 then + STATE = STATE_ROOM_18 + return + end + + -- Use standard parser for this room. + NEXT_STATE = STATE_PARSER + end, + + [STATE_ROOM_5] = function(what) + if what == "" then + screenPrint("") + screenPrint("A WAITER APPROACHES AND ASKS IF YOU") + screenPrint("WOULD LIKE A SEAT.") + screenPrint("SINCE YOU MISSED LUNCH TODAY, YOU") + screenPrint("ARE HUNGRY.") + screenPrint("") + screenPrint("DO YOU WANT TO EAT?") + NEXT_STATE = STATE_ROOM_5 + else + screenPrint("") + if what == "NO" or what == "N" then + screenPrint("THE WAITER CALLED YOU A STIFF") + screenPrint("AND THREW YOU OUT.") + L = 3 + STATE = STATE_LOOK + else + if what == "YES" or what == "Y" then + screenPrint("YOU ARE SERVED A DELICIOUS MEAL") + screenPrint("UNFORTUNATELY, THE SERVICE IS") + screenPrint("RATHER SLOW.") + pioneer(STATE_BOOM, "FR19453SE/FR19799PL/") + else + screenPrint("PLEASE ANSWER YES OR NO.") + NEXT_STATE = STATE_ROOM_5 + end + end + end + end, + + [STATE_ROOM_8] = function(what) + if what == "" then + if OBJECTS[8].LOCATION ~= 0 and OBJECTS[8].LOCATION ~= -2 then + screenPrint("SHE SAYS YOU CAN'T COME IN UNLESS YOU") + screenPrint("HAVE A PRESENT FOR HER. SHE PUSHES YOU OUT.") + L = 4 + STATE = STATE_LOOK + return + end + + if OBJECTS[8].LOCATION == -2 then + screenPrint("SHE SAYS, 'YOU THINK ONE PRESENT") + screenPrint("ENTITLES YOU TO COME IN HERE ANY TIME") + screenPrint("YOU WANT?' SHE TURNS HER BACK AND IGNORES YOU.") + STATE = STATE_PARSER + return + end + + screenPrint("SHE LETS YOU IN AND EYES THE BEAR.") + screenPrint("DO YOU WANT TO GIVE IT TO HER?") + + NEXT_STATE = STATE_ROOM_8 + else + screenPrint("") + if what == "NO" or what == "N" then + screenPrint("SHE THROWS YOU OUT.") + L = 4 + STATE = STATE_LOOK + else + if what == "YES" or what == "Y" then + screenPrint("SHE UNLOCKS THE DOOR TO THE SOUTH.") + OBJECTS[8].LOCATION = -2 + else + screenPrint("PLEASE ANSWER YES OR NO.") + NEXT_STATE = STATE_ROOM_8 + end + end + end + end, + + [STATE_ROOM_9] = function(what) + screenPrint("IF YOU LOOK BACK, YOU'LL NOTICE") + screenPrint("A CAR SPEEDING TOWARD YOU.") + pioneer(STATE_PLAY_AGAIN, "FR16185SE/FR16223PL/") + end, + + [STATE_ROOM_15] = function(what) + -- 47100 + if OBJECTS[9].LOCATION == 0 then + screenPrint("HE SEES YOUR UNIFORM AND LETS YOU IN.") + STATE = STATE_PARSER + else + screenPrint("HE SAYS, 'EMPLOYEES ONLY' AND THROWS YOU OUT.") + L = 11 + STATE = STATE_LOOK + end + end, + + [STATE_ROOM_18] = function(what) + screenPrint("YOU FOLLOW A WINDING PATH, FINALLY") + screenPrint("RETURNING TO FAMILIAR GROUND.") + L = 1 + STATE = STATE_LOOK + end, + + [STATE_PARSER] = function(what) + local N = "" -- Noun + local V = "" -- Verb + local D = 0 -- Direction to go + local KW = 0 -- Known word? + local R = 0 -- Room to exit to + local c = "" + local t = 0 + + -- Split input into verb/noun. + for i = 1,string.len(what),1 do + c = what:sub(i, i) + if c == " " then + t = 1 + else + if t == 1 then + N = N .. c + else + V = V .. c + end + end + end + + STATE = STATE_NONE + + -- And now the fun! + if what == "BREAK BOX" then + KW = 1 + -- 53000 + end + + if what == "BREAK DOOR" then + KW = 1 + screenPrint("TOO SOLID TO EVEN TRY.") + end + + if V == "DROP" and N ~= "" then + KW = 1 + -- 26000 + end + + if what == "E" or what == "EAST" then + KW = 1 + D = 2 + end + + if V == "EXAMINE" and N ~= "" then + KW = 1 + -- 27000 + end + + if V == "FIND" then + KW = 1 + if N == "BATTERIES" then + screenPrint("TRY THE BEAR.") + else + screenPrint("I CAN'T HELP YOU.") + end + end + + if V == "GO" then + KW = 1 + -- 19000 + end + + if what == "GIVE COINS" and L == 5 then + KW = 1 + -- 43000 + end + + if what == "GIVE TICKET" and L == 16 then + KW = 1 + -- 48000 + end + + if V == "HELP" then + KW = 1 + screenPrint("JUST KEEP MOVING AND EXAMINING THINGS, AND AVOID DANGEROUS PLACES.") + end + + if what == "I" or what == "INV" or what == "INVENTORY" then + KW = 1 + -- 24000 + end + + if V == "JAM" then + KW = 1 + -- 54000 + end + + if V == "KILL" then + KW = 1 + screenPrint("THAT IS BEYOND MY POWER.") + end + + if what == "LOOK" then + KW = 1 + -- 22000 + end + + if V == "LOOK" and N ~= "" then + KW = 1 + -- 27000 + end + + if what == "MAKE JAMMER" then + KW = 1 + -- 55000 + end + + if what == "N" or what == "NORTH" then + KW = 1 + D = 1 + end + + if what == "OPEN BEAR" then + KW = 1 + screenPrint("TWO BATTERIES JUST FELL") + screenPrint("OUT OF THE BACK.") + screenPrint("THEY'RE ON THE GROUND.") + OBJECT[11].LOCATION = L + end + + if (V == "PUT" or V == "PLACE") and N ~= "" then + KW = 1 + -- 28000 + end + + if V == "PLAY" and L == 6 then + KW = 1 + -- 43000 + end + + if V == "PLAY" and L == 16 then + KW = 1 + -- 48000 + end + + if (what == "PUSH BUTTON" or what == "PRESS BUTTON") and L == 2 then + KW = 1 + -- 53000 + end + + if what == "QUIT" then + KW = 1 + singeQuit() + end + + if what == "READ BOOK" and (OBJECT[3].LOCATION == 0 or OBJECT[3].LOCATION == L) then + KW = 1 + screenPrint("YOU NOW KNOW HOw TO MAKE A") + screenPrint("JAMMER FROM A RADIO.") + BK = 1 + end + + if what == "READ TICKET" or what == "LOOK TICKET" then + KW = 1 + -- 27000 + end + + if what == "S" or what == "SOUTH" then + KW = 1 + D = 3 + end + + if what == "SHOOT" then + KW = 1 + -- 43000 + end + + if what == "SHOW TICKET" and L == 16 then + KW = 1 + -- 48000 + end + + if what == "TAKE" and N ~= "" then + KW = 1 + -- 25000 + end + + if (what == "TURN KNOB" or what == "TURN DIAL") and L == 2 then + KW = 1 + -- 53000 + end + + if what == "USE JAMMER" then + KW = 1 + -- 54000 + end + + if what == "VISIT DANCER" then + KW = 1 + screenPrint("SHE DOESN'T WANT TO SEE YOU.") + end + + if what == "W" or what == "WEST" then + KW = 1 + D = 4 + end + + if what == "WEAR UNIFORM" and (OBJECT[9].LOCATION == 0 or OBJECT[9].LOCATION == L) then + KW = 1 + screenPrint("IT FITS WELL AND MAKES A GOOD") + screenPrint("DISGUISE.") + OBJECT[9].LOCATION = 0 + pioneer(STATE_PARSER, "FR5890SE/") + end + + -- Did they move? + if D > 0 then + R = ROOMS[L].EXITS:byte(D) - 64 + if R > 0 then + L = R + STATE = STATE_LOOK + else + screenPrint("YOU CAN'T GO THAT WAY.") + end + end + + -- Did any of this make sense? + if KW == 0 then + screenPrint("I DON'T KNOW HOW TO DO THAT.") + end + + -- Tick, tick goes the bomb! + T = T + 1 + if T > 150 then + screenPrint("I THINK TIME JUST RAN OUT.") + pioneer(STATE_PLAY_AGAIN, "FR19801SE/FR20007PL/") + end + + if STATE == STATE_NONE then + NEXT_STATE = STATE_PARSER + end + end, + + [STATE_BOOM] = function(what) + screenPrint("") + screenPrint("THE BOMB WENT OFF AND THE BOMBER ESCAPED.") + DELAY = 8 + NEXT_STATE = STATE_PLAY_AGAIN + end, + + [STATE_PLAY_AGAIN] = function(what) + if what == "" then + screenClear() + screenPrint("IT IS ONE YEAR LATER.") + screenPrint("THE ROLLER COASTER HAS BEEN REBUILT.") + screenPrint("THE SABOTEUR PLANS TO DESTROY IT AGAIN.") + screenPrint("WOULD YOU LIKE TO TRY TO SAVE IT?") + else + screenPrint("") + if what == "NO" or what == "N" then + singeQuit() + else + if what == "YES" or what == "Y" then + resetGameData() + STATE = STATE_LOOK + else + screenPrint("YES OR NO.") + NEXT_STATE = STATE_PLAY_AGAIN + end + end + end + end +} + +-- Startup +discPause() +overlaySetResolution(vldpGetWidth(), vldpGetHeight()) +keyboardSetMode(1) -- Whoops! Forgot to put MODE_FULL in the framework! +colorBackground(0, 0, 0) +fontQuality(FONT_QUALITY_SHADED) +fontSelect(fntApple12) +math.randomseed(os.time()) + +-- Ugly hack to get the metrics of our font +sprApple12 = fontToSprite("X") +fntApple12Height = spriteGetHeight(sprApple12) + 2 +fntApple12Width = spriteGetWidth(sprApple12) + 1 +spriteUnload(sprApple12) + +resetGameData() + +-- Initialize text screen +screenClear() + +NEXT_STATE = STATE_NONE +STATE = STATE_GET_NAME + +--NA = "SCOTT" +--STATE = STATE_LOOK + +pioneer(STATE, "FR2818SE/") diff --git a/Video/06726_06959.mp4 b/Video/06726_06959.mp4 new file mode 100644 index 0000000..204d059 --- /dev/null +++ b/Video/06726_06959.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aabe5b0b5f560bcbff25c67d31e313a91f4bb5b965c6f884a7ebe3f02bdd221 +size 2459286 diff --git a/Video/08300_08488.mp4 b/Video/08300_08488.mp4 new file mode 100644 index 0000000..75b4f76 --- /dev/null +++ b/Video/08300_08488.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7296c00d5b38e2808ae4c2e0251324b011f76de962f9aed7ada2035fd3842543 +size 1848921 diff --git a/Video/10960_11107.mp4 b/Video/10960_11107.mp4 new file mode 100644 index 0000000..31d148d --- /dev/null +++ b/Video/10960_11107.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72ed2344696682d61006fb5595bddc564faea9d6fceb587664f63721739174ee +size 1682031 diff --git a/Video/11818_11907.mp4 b/Video/11818_11907.mp4 new file mode 100644 index 0000000..d1781f3 --- /dev/null +++ b/Video/11818_11907.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcb5e90da14f126e50f49bd40f652b245979bdb35f198e4a010040c7906c42c5 +size 1208083 diff --git a/Video/12169_12227.mp4 b/Video/12169_12227.mp4 new file mode 100644 index 0000000..158f57d --- /dev/null +++ b/Video/12169_12227.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26eb20c2ba9b73588f9c68ab6ea505b834e6b476046d486b711614fa62af917c +size 632546 diff --git a/Video/14038_14100.mp4 b/Video/14038_14100.mp4 new file mode 100644 index 0000000..a92bf15 --- /dev/null +++ b/Video/14038_14100.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44ae515d823e723ffb7bf4bf08bec7f9db971e07f93e393d712db638d3c716ec +size 879878 diff --git a/Video/14724_14855.mp4 b/Video/14724_14855.mp4 new file mode 100644 index 0000000..73fdafb --- /dev/null +++ b/Video/14724_14855.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c9e9c29160ca2c9cf22eff670473dadc03b7b937a91685058e025639ceee16a +size 1281808 diff --git a/Video/16185_16223.mp4 b/Video/16185_16223.mp4 new file mode 100644 index 0000000..899d9cc --- /dev/null +++ b/Video/16185_16223.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c19cfba08f9195f686a5bb7ee4a92e9833dd7c7dae4582f40eed3efb238626d +size 466086 diff --git a/Video/18722_18807.mp4 b/Video/18722_18807.mp4 new file mode 100644 index 0000000..a91ab7b --- /dev/null +++ b/Video/18722_18807.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c0206bba40dbc0280ab9a65fea73f0ba668088c982aa16d993e9a4b829c150c +size 1310001 diff --git a/Video/19453_19799.mp4 b/Video/19453_19799.mp4 new file mode 100644 index 0000000..0690462 --- /dev/null +++ b/Video/19453_19799.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd76548c8e45b0b686ee25ae2c5ec8dc0389cc898120df0920b09b55aee4b97e +size 5329328 diff --git a/Video/19801_20007.mp4 b/Video/19801_20007.mp4 new file mode 100644 index 0000000..f520e4f --- /dev/null +++ b/Video/19801_20007.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e341ce96a2a6a515c1215fdae0ea401cba9b1f3c955ac99afc7c3c1eae654e5a +size 3075597 diff --git a/Video/30032_30214.mp4 b/Video/30032_30214.mp4 new file mode 100644 index 0000000..41c3e7b --- /dev/null +++ b/Video/30032_30214.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22fbf77a2dec86dc0e9930857860a204740d70b9b65ae985a3d4b019f79f1060 +size 1457570 diff --git a/Video/framefile.txt b/Video/framefile.txt new file mode 100644 index 0000000..a9b1bf6 --- /dev/null +++ b/Video/framefile.txt @@ -0,0 +1,13 @@ +. +6726 06726_06959.mp4 +08300 08300_08488.mp4 +10960 10960_11107.mp4 +11818 11818_11907.mp4 +12169 12169_12227.mp4 +14038 14038_14100.mp4 +14724 14724_14855.mp4 +16185 16185_16223.mp4 +18722 18722_18807.mp4 +19453 19453_19799.mp4 +19801 19801_20007.mp4 +30032 30032_30214.mp4