/* demo.c Shows how to use the Madhouse-interface with a C-like language. Instructions to compile the program: - Perhaps your compiler doesn't like , then use another name for this directory. - This program can be compiled without problems with MaxonC++ v3. For other compilers, you might have to change something. */ #include #include #include #include #include #include #include #include #include #include #include #define ABNC 0x40 #define ABC 0x80 /* Prototypes */ void write_stopblank(); void read_prefs(); void write_error( char *str ); /* Variables */ char text[40]; short color, scroll; time_t start; short duration_sec=0; struct Library *IntuitionBase = NULL; struct Library *GfxBase = NULL; struct Screen *scr = NULL; struct Window *win = NULL; struct Message *msg = NULL; USHORT DemoPalette[] = { 0x0000, 0x0FFF }; struct TextAttr topaz8 = { "topaz.font", 8, 0, 0 }; /*************************************************************************** *** open_all() *** Opens all things we need. ***************************************************************************/ BOOL open_all() { IntuitionBase = OpenLibrary("intuition.library",37); if( !IntuitionBase ) return FALSE; GfxBase = OpenLibrary("graphics.library",37); if( !GfxBase ) return FALSE; /* Open a standard LowRes-screen. */ scr = OpenScreenTags(NULL, SA_Depth, 1, SA_Width, 320, SA_Height, 256, SA_Font, &topaz8, TAG_DONE); if(!scr) return FALSE; /* Set the colors of the mouse-pointer to the background-colors. */ SetRGB4( &scr->ViewPort,17,0,0,0); SetRGB4( &scr->ViewPort,18,0,0,0); SetRGB4( &scr->ViewPort,19,0,0,0); win = OpenWindowTags(NULL, WA_AutoAdjust, TRUE, WA_NoCareRefresh, TRUE, WA_CustomScreen, scr, WA_Flags, WFLG_RMBTRAP, WA_Borderless, TRUE, WA_Activate, TRUE, WA_IDCMP, IDCMP_MOUSEBUTTONS+IDCMP_RAWKEY, TAG_DONE ); if( !win ) return FALSE; LoadRGB4( &scr->ViewPort, DemoPalette, 2 ); return TRUE; } /*************************************************************************** *** close_all() *** Closes all things we needed. ***************************************************************************/ void close_all() { /* This brings the screen behind all others and should avoid some stupid effects when closing screen with 68000-Amigas. */ if( scr ) ScreenToBack( scr ); /* If something went wrong, we should tell this Madhouse. But mustn't write more then one lines in the errors-file. So we use this nice if-construct: */ if( !IntuitionBase ) write_error( "No intuition.lib V37!" ); else { if( !GfxBase ) write_error( "No graphics.lib V37!" ); else { if( !scr ) write_error( "Out of memory: Couldn't open screen."); else { if( !win ) write_error( "Out of memory: Couldn't open window."); } } } /* Now we close all what we could open. */ if( win ) CloseWindow( win ); if( scr ) CloseScreen( scr ); if( GfxBase ) CloseLibrary( GfxBase ); if( IntuitionBase ) CloseLibrary( IntuitionBase ); } /*************************************************************************** *** main() *** Here the real blanker begins. ***************************************************************************/ void main() { BOOL quit = FALSE; BOOL user_quit = FALSE; short ypos = 20; short direction = 1; short oldy; /* First read the settings for our blanker and the duration-value.*/ read_prefs(); /* Now we start our stop-watch. */ start = time(NULL); /* Open screen and window. */ if(open_all()) { /* Color-parameter: set the right color. */ switch( color ) { case 0: SetRGB4( &scr->ViewPort, 1, 15,0,0 ); break; case 1: SetRGB4( &scr->ViewPort, 1, 15,15,0 ); break; case 2: SetRGB4( &scr->ViewPort, 1, 0,0,15 ); } /* Text-parameter: write the text. */ SetAPen( win->RPort, 1 ); Move( win->RPort, 5, ypos ); Text( win->RPort, text, ( strlen(text) > 38 ? 38 : strlen(text)) ); /* Main-Loop. */ while( !quit ) { /* If the user selected Scroll, scroll the text. */ if( scroll ) { oldy = ypos; ypos += direction; if( (ypos > 220) || (ypos < 20) ) direction *= -1; ClipBlit(win->RPort, 5, oldy-10, win->RPort, 5, ypos-10, 310, 20, ABNC | ABC ); /* Minterms ABNC | ABC -> copy the rectangle without modifications. */ } /* Mousbutton or key? */ if( msg = GetMsg(win->UserPort) ) { quit = TRUE; user_quit = TRUE; ReplyMsg( msg ); } /* When 'Change Blanker' is activated ( duration_sec is not 0 ) AND we blanked (one second) longer as we are allowed to ( difftime(time(NULL),start) > time_counter ) then quit. */ if( duration_sec && difftime(time(NULL),start) > duration_sec ) quit = TRUE; WaitTOF(); } } /* Close our stuff and -perhaps- write the error. */ close_all(); /* If the user stopped our Blanker, we have to inform Madhouse about this, otherwise it would perhaps (if 'Change Blanker' is activated) start a new blanker. */ if( user_quit ) write_stopblank(); /* And finished! */ } /*************************************************************************** *** *** *** Functions for the communication with Madhouse *** *** *** ***************************************************************************/ /* Some global variables: */ char bu[1500]; /* The buffer bu[] includes the whole prefs-file. */ short bu_seek = 0; /* bu_seek is the read-offset of bu[]. We need this variable to see where we have to read the next parameter. */ /* First some useful functions: */ /*************************************************************************** *** read_next_digit() *** Reads the next parameter out of our prefs-file. *** The next parameter must be a number. ***************************************************************************/ long read_next_digit() { short number_cnt = 0; char number[50]; while( bu[bu_seek] != (char) 0x0D ) { number[number_cnt] = bu[bu_seek]; bu_seek++; number_cnt++; } number[number_cnt] = (char) 0x00; /* Overjump the (0x0D)(0x0A) * (Madhouse places these sequences between the lines.) */ bu_seek+=2; return strtol( number, 0, 10 ); } /*************************************************************************** *** read_next_string() *** Reads the next parameter out of our prefs-file. *** The next parameter must be a string. ***************************************************************************/ void read_next_string( char *string, short maxlen ) { short text_cnt = 0; /* A Madhouse-Text begins begins with a "$", so we jump over the first char. */ bu_seek++; while( (bu[bu_seek] != (char) 0x0D) && (text_cnt < maxlen) ) { string[text_cnt] = bu[bu_seek]; bu_seek++; text_cnt++; } string[text_cnt] = (char) 0x00; /* Now we have the text in string[]. */ /* * Jump over the (0x0D)(0x0A) */ bu_seek+=2; } /*************************************************************************** *** read_prefs() *** Reads the preferences. ***************************************************************************/ void read_prefs() { short text_cnt = 0; short number_cnt = 0; BPTR f = NULL; f = Open( "RAM:Madhouse_Storage/prefs", MODE_OLDFILE ); if (f) { Read( f, bu, sizeof( bu ) ); /* Now, bu[] has a contents like this: "$Hello, this is a text(0x0D)(0x0A)2(0x0D)(0x0A)0(0x0D)(0x0A) 5(0x0D)(0x0A)RAM:Madhouse_Storage(0x0D)(0x0A)". (0x0D) and (0x0A) are between every line. Hello,... is our first parameter, 2 our second, 0 our third, 5 the duration in minutes and RAM:.. a path to our directory, if we need data from it. All Madhouse-strings begin with a "$". We will put the first parameter in text[], the second in color, the duration in duration_sec and the path is not needed. */ /* * First parameter (Text) */ read_next_string( text, 40 ); /* * Second parameter (Color) */ color = read_next_digit(); /* * Third parameter (Scroll) */ scroll = read_next_digit(); /* * Duration-Parameter. */ duration_sec = read_next_digit() * 60; /*Minutes -> Seconds*/ Close( f ); } else { /* The Blanker was not started by Madhouse. Quit here.*/ exit(0); } } /*************************************************************************** *** write_stopblank() *** Must be used if the user aborted the blanker himself. ***************************************************************************/ void write_stopblank() { /* Just create a new empty file to inform Madhouse that the user has aborted the blanker. */ BPTR f; f = Open( "RAM:Madhouse_Storage/stopblank", MODE_NEWFILE ); if( f ) Close( f ); } /*************************************************************************** *** write_error() *** Tells Madhouse that an error occurred - can only be used ONCE! ***************************************************************************/ void write_error( char *str ) { BPTR f; char eol_marker = 0x0D; f = Open( "RAM:Madhouse_Storage/errors", MODE_READWRITE ); if( f ) { Seek( f, 0, OFFSET_END ); Write( f, str, strlen(str) ); Write( f, &eol_marker, 1 ); Close( f ); } }