Message "[Uncluding ]"; !--------------------------------------------------------------------- ! Glk stuff stolen from Doe's "Just a Dream" ! *** Sound Channels - Creates (opens) and destroys (closes) sound channels. [ CreateMyChannels; ! The *last* one added has precedence (?!?) ! if (gg_backchannel ~= 0) ! { DestroyChannel(gg_backchannel); ! gg_backchannel = 0; ! } if (gg_forechannel ~= 0) { DestroyChannel(gg_forechannel); gg_forechannel = 0; } ! if (gg_backchannel == 0) ! gg_backchannel = CreateChannel(GG_BACKCHANNEL_ROCK); if (gg_forechannel == 0) gg_forechannel = CreateChannel(GG_FORECHANNEL_ROCK); ! Turns out I can't do what I had intended, which was to put a MOD ! on the back channel and AIFFs over it. So we'll just let ! foreground sounds interrupt any playing music. Sigh. gg_backchannel = gg_forechannel; ]; ! From Unglklib.... ! *** IdentifyGlkObj ! If you create any of your own Glk objects, you must include your own ! IdentifyGlkOject. ! IdentifyGlkObject essentially reinitializes Glk objects after the player ! uses UNDO/RESTART/RESTORE. Since Glk objects ARE CREATED IN MEMORY, only ! the variables & constants pointing to them are actually saved. So their ! corresponding Glk objects in memory may not match their recovered variables. ! This resets the Glk objects in memory to match their variables. [ IdentifyGlkObject phase type ref rock id; ! Zero out variables (references). Include all author-created Glk objects. if (phase == 0) { gg_stiffywin = 0; gg_dialoguewin = 0; gg_graphicwin = 0; gg_objectwin = 0; gg_forechannel = 0; gg_backchannel = 0; return; } ! Find what current objects actually exist in memory ( 0 (GLK_NULL) == doesn't ! exist # = do exist). if (phase == 1) { switch (type) { 0: ! it's a window switch (rock) { GG_STIFFYWIN_ROCK : gg_stiffywin = ref; GG_DIALOGUEWIN_ROCK : gg_dialoguewin = ref; GG_GRAPHICWIN_ROCK : gg_graphicwin = ref; GG_OBJECTWIN_ROCK : gg_objectwin = ref; } 1: ! it's a stream, and I have no stream refs. 2: ! it's a fileref, and I have no file refs. } return; } ! Now change Glk objects in memory to match their restored variables. For ! instance, gg_bigwin could be currently showing on the screen as a text ! buffer window, but after being restored it should be a graphic window. ! If the restored variables pointing to the Glk objects don't match the Glk ! objects currently in memory or their current state in memory, then change ! the Glk objects in memory so they matched the restored variables. Routines ! to do that should be placed here, in phase 2. Sound channel resetting is ! also placed in phase 2, because it is not a normal Glk object. ! NOTE: I had a hard time making ArrangeWindows work when called by ! IdentifyGlkObj. Upon restore the two additional windows need to be changed ! if during_intro or text_mode has changed. But when I initially put ! ArrangeMyWindows in phase 2, the game would not load. Finally I figured out ! that IdentifyGlkObject is called when a Glulx game first loads, even before ! InitGlkWindow is called. By adding a line to ArrangeMyWindows the game would ! load, and window states could be restored (see ArrangeMyWindows). if (phase == 2) { ! check the interpreter again upon RESTART/RESTORE to update global ! variables that report its state (the Glk gestalt) timer_on = SupportsGlkTimer(); sound_on = SupportsSounds(); if (sound_on) sndnotify_on = SupportsSoundNotify(); ! Loop through sound channels and fix references. if (sound_on) { id = GetNextChannel(0, gg_arguments); while (id) { switch (gg_arguments-->0) { GG_FORECHANNEL_ROCK : gg_forechannel = id; ! GG_BACKCHANNEL_ROCK : gg_backchannel = id; } id = GetNextChannel(id, gg_arguments); } } ! Now restore everything: windows, graphics, and sounds. Reopen windows, ! redraw graphics, and/or replay sounds. Or close windows, remove ! graphics, and stop sounds to match Glk objects' variables (references). SetupWindows(); ! closes/reopens windows DrawMyGraphics(); ! reloads graphics ! code to reload the ancillary window state should go here... if (sound_on) ! plays sounds, or stops sounds playing { CreateMyChannels(); PlaySound(gg_forechannel,0); PlaySound(gg_backchannel,0); ! stop any playing sounds if (fore_snd) PlaySound(gg_forechannel, fore_snd, 1); if (back_mus) { PlaySound(gg_backchannel, back_mus, 1); } } } ]; !--------------------------------------------------------------------- ! *** HandleGlkEvent ! If you include any of your Glk events, you must include HandleGlkEvent. ! HandleGlkEvent processes player multimedia input, such as hyperlinks and the ! mouse. The Glk timer and sound notification are the only Glk events triggered ! solely by the game author (with coding). Note that all input events: line, ! char, hyperlink, and mouse input are associated with a specific window. [ HandleGlkEvent ev context abortres newcmd cmdlen; ! ev = event array ! ev-->0 = event type ! ev-->1 = window event is associated with ! ev-->2 = value, depends on usage ! ev-->3 = value, depends on usage ! context = when happened, 1 = when char input was pending ! 0 = when line input was pending ! abortres = input buffer ! ------ ! newcmd = new command ! cmdlen = length of command context = context; abortres = abortres; newcmd = newcmd; cmdlen = cmdlen; switch (ev-->0){ ! *** Windows - Windows are resized by the player, so update windows and ! redraw graphics. evtype_Arrange : SetupWindows(); DrawMyGraphics(); ! *** Graphics - Color/resolution settings are changed by the player, so ! fix graphics. evtype_Redraw : DrawMyGraphics(); ! *** Sound Notification - Sound has finished playing, so open wooden door. ! Note: In "Dream", if sound notification is supported, the door won't open ! until the creaking door sound finishes playing. evtype_SoundNotify: if (sndnotify_on) { switch (snd_magic) { TERRI_AROUSAL_EXTREME: snd_magic = HALFMAST; penis.ejaculate(); MOAN: snd_magic = HALFMAST; PlaySound(gg_forechannel,snd_moan,0,1,TRUE); THROBBING: if (torpedo has general) { PlaySound(gg_forechannel,snd_torpedo,0,1,TRUE); } else { PlaySound(gg_forechannel,snd_phaser,0,1,TRUE); } snd_magic = HALFMAST; HALFMAST: snd_magic = 0; default: } ! This is how we're getting around the "no mixing AIFFs ! and MODS" restriction: just restart the background music if (back_mus && (snd_magic ==0)) PlaySound(gg_backchannel,back_mus); } ! *** Mouse Input - If the player clicks the mouse anywhere in the gg_smallwin ! when the ClosedJournal_pic is on the screen, mouse input can open the journal. ! The command is passed back to the parser, the from it to the journal object. ! Mouse input doesn't need to be in a specific rectangular screen location of ! gg_smallwin, just in gg_smallwin. See other notes under hyperlink events. evtype_MouseInput : rfalse; ! *** Hyperlinks - Returns command as if it had been typed in by the player, ! passing it through the parser back to the button object or room location. ! Return value of 2 passes the command along as if player typed it. ! 1. Command "n" (or "s", "ne", "nw", or "push button") is put into the ! abortres array (the input buffer) to be passed along to and processed ! by the Inform parser. PrintAnyToArray actually copies the command to ! the input buffer, and also returning the byte length of the command string ! (the Inform parser needs the exact length). 2. Next, put the length into ! the first word of the input buffer (some Inform strings have the length of ! the string in the first word). 3. Then return 2 to return command to parser. ! See Zarf's Game Author's Guide to Inform Glulx for more details. ! ! ev--2> = value, in this case, the specific hyperlink number evtype_HyperLink : rfalse; ! *** Glk Timer - Don't turn off the Glk timer unless all timer counters ! are NULL (but since in "Dream" no timed events overlap, that shouldn't ! be a problem). If a counter is "active" run the appropriate special effect. ! (Note that since Glk timer event handling won't even be called unless the ! timer was started, counters which also start at NULL, can then be reset to ! NULL to cancel special effects.) evtype_Timer : ticks++; ! ! if (ticker_count == NULL) ! { if ((flash_count == NULL) && (animate_count == NULL)) ! StopGlkTimer(); ! } else TickerTape(); ! if (flash_count == NULL) ! { if ((ticker_count == NULL) && (animate_count == NULL)) ! StopGlkTimer(); ! } else FlashWindowColors(gg_stiffywin, $FF0000, $000000); ! if (animate_count == NULL) ! { if ((ticker_count == NULL) && (flash_count == NULL)) ! StopGlkTimer(); ! } else StiffyMovie(now_showing); if ((ticks % divisor) == 0) StiffyMovie(now_showing); if (titlescroll) { if (gg_titlewin) { FloodFillWindow(gg_titlewin,$000000); ! titlescroll = ! Scroll(gg_titlewin,pic_credits,titlescroll,0,128); ScrollTitlePic(pic_credits); } else { titlescroll = 0; } } if (scene == 7) { dummy.picture = random(pic_borg,pic_excretus,pic_ass,pic_ham,pic_borg2, pic_excretus2); DrawBigPic(dummy); dummy.picture = random(pic_borg,pic_excretus,pic_ass,pic_ham,pic_borg2, pic_excretus2); DrawObjectPic(dummy); if ((phaser has general) && (torpedo has general)) { penis.setStatus(THROBBING+10); } else if ((phaser has general) || (torpedo has general)) { penis.setStatus(GREASY+2); } else penis.setStatus(0); } if (scene == 8) { dummy.picture = random(pic_fuck_1,pic_fuck_2,pic_fuck_3, pic_fuck_4,pic_fuck_5,pic_fuck_6, pic_tom_1,pic_tom_2,pic_tom_3); DrawObjectPic(dummy); dummy.picture = random(pic_fuck_1,pic_fuck_2,pic_fuck_3, pic_fuck_4,pic_fuck_5,pic_fuck_6, pic_tom_1,pic_tom_2,pic_tom_3); DrawBigPic(dummy); } } ]; [ StopSound channel; PlaySound(channel,0); ]; [ InitGlkWindow winrock; switch(winrock) { GG_MAINWIN_ROCK: glk_stylehint_set(wintype_AllTypes, style_User1, stylehint_Oblique, 1); glk_stylehint_set(wintype_AllTypes, style_User2, stylehint_Weight, 1); } rfalse; ];