!===============================================================================!
! SGW - a Simple Glulxe Wrapper
!===============================================================================!
! (by Alessandro Schillaci)
! WeB   : http://slade.altervista.org
! @mail : [email protected]
!
! Version 1.1 2005-07-04
!===============================================================================!
! WHAT IS THIS FOR ?
! ==================
! "sgw.h" (this file) is a simple and small glulxe wrapper, created for a novice
! inform programming level.
! With this library it's possible to visualize an image or simply to play a sound
! (or a music) by using a small set of functions that wrap the glulx functions.
!
! It's possible to convert a z-code adventure to a glulx adventure with
! multimedia support.
!
! You can use 3 audio channles:
! - music : for the music channel
! - chan1 : channel 1 for audio (sound effects)
! - chan2 : channel 2 for audio (sound effects)
!
!===============================================================================!
! HOW TO USE
! ==========
!
! Just follow these points:
!
! 1) Put in your main file the directive
!    include "sgw.h";
!    before the Include "Parser"; directive
!
! 2) Use the initializeWrap() function in your initialize standard function.
!
!    Example:
!
!    initializeWrap(240);
!
!    This will set the main graphic window to have an height=240 pixels but
!    you can change this resolution as you like.
!
! 3) Now you can play a sound or visualize an image simply using
!    these two functions: viewImage and playSound
!
! 4) You can customize colors settings, by create these Globals
!    before you include the "sgw.h" library, to override them
!
!    Constant SCBACK $110101;
!    Constant SCTEXT $DDBB99;
!    Constant SCSOFT $665544;
!    Constant SCEMPH $FFFFDD;
!    Constant SCHEAD $EEDDAA;
!    Constant SCINPU $DDEEAA;
!
! You can use these new simple functions in your game, also :
!
! GRAPHIC FUNCTIONS
! =================
! clearMainWindow()     = clears the main window
! closeAllWindows       ()      = closes all graphic windows
! initializeWrap(w,h)   = graphic window dimension is set to w=width h=height
! viewImage(image)      = shows the "image" in the graphic window
!
!
! AUDIO FUNCTIONS
! ===============
! playSound(channel,sound,lenght,volume)        = plays a sound/music
! silenceAll()                                                  = silences all audio channels
! silenceChannel(channel)                                       = silences the audio "channel"
! setVolume(val, channel)                                       = set "val" for volume of the channel
!
!===============================================================================!
! LICENSE
! =======
!
! This file is free software, it can be freely used, copied, distribuited and
! modified. Any modified or unmodified copy of this file distribuited as source
! code must acknoledge the original author and must be freely usable, copyable,
! distributable and modifiable.
! There's absolutely no condition or binding on the distribution as compiled
! binary file.
! This software is distribuited as-is, with NO WARRANTY. The author cannot be
! held as responsable for any damage due directly or indirectly to this file.
!
!===============================================================================!

message "Using the SGW 1.1 (Simple Glulxe Wrapper) library by Alessandro Schillaci";

Global music                                    = 0;                    ! Music Channel
Global chan1                                    = 0;                    ! Channel 1 sound effects
Global chan2                                    = 0;                    ! Channel 2 sound effects

Constant VOLUME_HIGH                    5;
Constant VOLUME_NORMAL          3;
Constant VOLUME_LOW                     2;

#IfDef TARGET_GLULX;
Global current_music                    = 0;
Global gg_VolumeSupport         = false;                ! Change Volume supported?
Global gg_statuswin;
Global gg_mainwin;                                              ! Text window
Global gg_bigwin ;                                              ! Image Location window
Global curr_pic;

Constant GG_MUSICCHAN_ROCK              410;
Constant GG_MUSICCHANSOUND1_ROCK        411;
Constant GG_MUSICCHANSOUND2_ROCK        412;
Constant GG_BIGWIN_ROCK                         210;            ! Image Location window

#Ifndef SCBACK;
       Constant SCBACK                                         $110101;        ! Colors settings
#Endif;
#Ifndef SCTEXT;
       Constant SCTEXT                                         $DDBB99;
#Endif;
#Ifndef SCSOFT;
       Constant SCSOFT                                         $665544;
#Endif;
#Ifndef SCEMPH;
       Constant SCEMPH                                         $FFFFDD;
#Endif;
#Ifndef SCHEAD;
       Constant SCHEAD                                         $EEDDAA;
#Endif;
#Ifndef SCINPU;
       Constant SCINPU                                         $DDEEAA;
#Endif;
#Endif;


[ initializeSGW h;
       #Ifdef TARGET_GLULX;
               if (music == 0) {music = glk_schannel_create(GG_MUSICCHAN_ROCK);                        }
               if (chan1 == 0) {chan1 = glk_schannel_create(GG_MUSICCHANSOUND1_ROCK);  }
               if (chan2 == 0) {chan2 = glk_schannel_create(GG_MUSICCHANSOUND2_ROCK);  }
               testGlulx();                    ! Test about Interpreter's performances
               closeAllWindows();      ! Closing all window
               silenceAll();           ! Silence all audio channels
               inizializeGlulx(h);     ! Inizialize the glulx system
       #Endif;
];


! --- Graphics functions -------------------------------------------------------------

! View an image on main graphic window
[ viewImage image;
       #Ifdef TARGET_GLULX;
               curr_pic = image;
               if (gg_bigwin && glk_gestalt(gestalt_Graphics, 0)) {
                       glk_image_draw(gg_bigwin, curr_pic, 0, 0);
               }
       #Endif; ! TARGET_
];


! Clean the main window
[ clearMainWindow;
       #Ifdef TARGET_GLULX;
               glk_window_set_background_color(gg_mainwin,$00000000);
               glk_window_clear(gg_mainwin);
               glk_window_set_background_color(gg_bigwin,$00000000);
               glk_window_clear(gg_bigwin);
       #endif;
];

! Close all windows
[ closeAllWindows;
       #Ifdef TARGET_GLULX;
               if (gg_bigwin) {
                       glk_window_close(gg_bigwin,0);
                       gg_bigwin = 0;
               }
       #endif;
];

! Redraws an image
[ MyRedrawGraphicsWindows;
       #Ifdef TARGET_GLULX;
       if (gg_bigwin && glk_gestalt(gestalt_Graphics, 0)) {
               glk_image_draw(gg_bigwin, curr_pic, 0, 0);
       }
       #endif;
];




! --- Audio functions -------------------------------------------------------------

! Plays the sound "sound" for the channel "channel" , with "lenght" and "volume"
[ playSound channel sound lenght volume;
       #Ifdef TARGET_GLULX;
               if (channel) {
                       current_music = sound;
                       glk_schannel_stop(channel);
                       SetVolume(volume,channel);
                       glk_schannel_play_ext(channel, sound, lenght, 0);
               }
       #endif;
];

! Sileces all the audio channels
[ silenceAll;
       #Ifdef TARGET_GLULX;
               if (chan1) {            glk_schannel_stop(chan1);       }
               if (chan2) {            glk_schannel_stop(chan2);       }
               if (music) {            glk_schannel_stop(music);       }
       #Endif;
];

! Silences the channel "channel"
[ silenceChannel channel;
       #Ifdef TARGET_GLULX;
               if (channel) {
                       glk_schannel_stop(channel);
               }
       #endif;
];

! Reset all audio channels
[ resetMusicChannel;
       #Ifdef TARGET_GLULX;
               glk_schannel_stop(music);
               glk_schannel_stop(chan1);
               glk_schannel_stop(chan2);
       #endif;
];

! Set a volume for the channel
[ setVolume val chan;
       #Ifdef TARGET_GLULX;
           if (~~gg_VolumeSupport) return;
               if (val > 0) glk_schannel_set_volume(chan, val * 16384);
       #endif;
];



! --- GLULX functions ------------------------------------------------------------- !

#Ifdef TARGET_GLULX;

[ HandleGlkEvent event ;
       switch (event-->0) {
               evtype_Redraw, evtype_Arrange  :        MyRedrawGraphicsWindows();
                                       evtype_SoundNotify:     glk_schannel_play_ext(music, current_music, 1, 1);
                                       evtype_SoundNotify:     glk_schannel_play_ext(music, , 1, 1);

               4:                              ! mouse
               1:                              ! timer
               5, 6:                   ! arrange/redraw
       }
];

! Glk window initialization entry point.
[ InitGlkWindow winrock;
       switch (winrock) {
               GG_MAINWIN_ROCK:
                       glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_TextColor, SCTEXT);
                       glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Justification, stylehint_just_LeftRight);
                       glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_TextColor, SCEMPH);
                       glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_TextColor, SCEMPH);
                       glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_TextColor, SCHEAD);
                       glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_TextColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_BackColor, SCTEXT);
                       glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_TextColor, SCINPU);
                       glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Blockquote, stylehint_TextColor, SCINPU);
                       glk_stylehint_set(wintype_AllTypes, style_Blockquote, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Input, stylehint_TextColor, SCINPU);
                       glk_stylehint_set(wintype_AllTypes, style_Input, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_TextColor, SCINPU);
                       glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_BackColor, SCBACK);
                       glk_stylehint_set(wintype_AllTypes, style_User1, stylehint_TextColor, SCSOFT);
                       glk_stylehint_set(wintype_AllTypes, style_User1, stylehint_BackColor, SCBACK);
       }
       rfalse;
];


! Glk object identification entry point.
[ IdentifyGlkObject phase type ref rock id;

       switch (phase) {
       0:      ! start
               gg_bigwin                       = 0;
               gg_statuswin                    = 0;
               music                           = 0;
               chan1                           = 0;
               chan2                           = 0;
               return;
       1:      ! pass ref
               switch (type) {
               0:      ! window ref
                       switch (rock) {
                               GG_BIGWIN_ROCK  :       gg_bigwin       = ref;
                       }
               }
               return;
       2:  ! Update objects
        id = glk_schannel_iterate(0, gg_arguments);
        while (id) {
           switch (gg_arguments-->0) {
              GG_MUSICCHAN_ROCK                : music = id;
              GG_MUSICCHANSOUND1_ROCK  : chan1 = id;
              GG_MUSICCHANSOUND2_ROCK  : chan2 = id;
          }
          id = glk_schannel_iterate(id, gg_arguments);
        }
        ResetMusicChannel();
        MyRedrawGraphicsWindows();
        return;
       }
   return;
];


! Test the Glulx Interpreter's performances
[ testGlulx;
       if (~~glk_gestalt(gestalt_Graphics, 0)) {
               print "^[This Interpreter doesn't support graphics.]^";
       }

       if (~~glk_gestalt(gestalt_Sound, 0)){
               print "^[This Interpreter doesn't support audio files.]^^";
       }

       if (~~glk_gestalt(gestalt_SoundVolume, 0)){
               print "^[This Interpreter doesn't support audio volume.]^";
       }
];


! Glulx Inizialize function
[ inizializeGlulx h;

       ! Graphics
       if (gg_statuswin == 0) {
               gg_statuswin = glk_window_open(gg_mainwin,(winmethod_Above+winmethod_Fixed), 2, wintype_TextGrid, GG_BIGWIN_ROCK);
       }

       if (gg_bigwin == 0) {
               gg_bigwin = glk_window_open(gg_mainwin,(winmethod_Above+winmethod_Fixed), h , wintype_Graphics, GG_BIGWIN_ROCK);
       }

       ! Set black as background colour for all windows
       glk_window_set_background_color(gg_bigwin,$00000000);
       glk_window_clear(gg_bigwin);
       glk_window_set_background_color(gg_mainwin,$00000000);
       glk_window_clear(gg_mainwin);
];

#Endif;