!===============================================================================!
! SGW - a Simple Glulxe Wrapper
!===============================================================================!
! (by Alessandro Schillaci) 
! WeB   : http://slade.altervista.org
! @mail : silver.slade@tiscalinet.it
!
! 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;
