Advertisement
ZoriaRPG

ZScript String Table Processor & Display System, (v2.0)

Oct 15th, 2018
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.97 KB | None | 0 0
  1. //////////////////////////////////////////////////
  2. /// Revised String Table Processor for ZScript ///
  3. /// Allows defining custom string tables       ///
  4. /// and displaying fancy messages with custom  ///
  5. /// backgrounds, music and sound effects.      ///
  6. /// v2.1                                       ///
  7. /// 15th October, 2018                         ///
  8. /// By: ZoriaRPG                               ///
  9. //////////////////////////////////////////////////
  10. /// 1.0 : Rewrote string processor.
  11. ///
  12. /// 2.0 : Added Display generation and music playback.
  13. /// 2.1 : Changed str_template.draw(id) to str_template.draw(id, number_of_lines),
  14. ///     : adding in the ability to apeend multiple strings to a single display call.
  15. ///
  16.  
  17. //! STRING TABLE AND PROCESSOR
  18.  
  19. namespace script strings
  20. {
  21.     const int BUFFER_SIZE = 1024;
  22.     const int MAX_STRINGS = 4096;
  23.     const int CURRENT_STRING_ID = 4095; //The 'TOP'. This will always be the ID of the last string called.
  24.     int buffer[BUFFER_SIZE];
  25.     int ids[MAX_STRINGS];
  26.    
  27.    
  28.     /*List strings in the table using the following format:
  29.    
  30.     $ <NUMBER> : <string>
  31.    
  32.     Tokens:
  33.     $ -- Indicates the beginning of a string ID.
  34.     <NUMBER> a series of numeric characters that represent the numeric ID of the string.
  35.     : -- COlon separator between <NUMBER> and <string>
  36.     <string> The string text.
  37.     */
  38.     int table[]=
  39.     "$000001:This is a string.
  40.     $000002:This is a second.
  41.     $000003:This is a third.
  42.     $000004:This is a fourth
  43.     $000005:This is a fifth.";
  44.     void run(){}
  45.    
  46.     //stores the initial position of all strings in the table into ids[]
  47.     //where the index of ids[index] == the string ID.
  48.     void init()
  49.     {
  50.         int token[7]; int token_pos; int table_pos;
  51.        
  52.         for ( table_pos = 0; table[table_pos] != NULL; ++table_pos )
  53.         {
  54.             //find the tokens
  55.             if ( table[table_pos] == '$' )
  56.             {  
  57.                 //copy the string ID into the token
  58.                 token_pos = 0;
  59.                 while( table[table_pos] != ':' )
  60.                 {
  61.                     token[token_pos] = table[q];
  62.                     ++token_pos;
  63.                     ++q;
  64.                 }
  65.                 //store the index where the token ends + 2
  66.                 ids[atoi(token)] = table_pos +2;
  67.             }
  68.         }
  69.     }
  70.     void clear()
  71.     {
  72.         for ( int q = 0; q < BUFFER_SIZE; ++q )
  73.         {
  74.             buffer[q] = 0;
  75.         }
  76.     }
  77.     void fetch(int string_id)
  78.     {
  79.         int table_pos = ids[string_id];
  80.         for ( int buffer_pos = 0; table[table_pos+1] != '$'; ++buffer_pos )
  81.         {
  82.             buffer[buffer_pos] = table[table_pos];
  83.             ++table_pos;
  84.             ids[CURRENT_STRING_ID] = string_id;
  85.         }
  86.     }
  87.        
  88.        
  89.     void store(int msg_id)
  90.     {
  91.         if ( msg_id <= 0 )
  92.         {
  93.             TraceError("Invalid message ID passed to strings.store()", msg_id);
  94.             return;
  95.         }
  96.         if ( msg_id >= Game->NumMessages )
  97.         {
  98.             TraceError("Invalid message ID passed to strings.store()", msg_id);
  99.             return;
  100.         }
  101.         SetMessage(msg_id, buffer);
  102.     }
  103.     void display(int string_id)
  104.     {
  105.         fetch(string_id);
  106.         store(Game->NumMessages);
  107.         Screen->Message(Game->NumMessages);
  108.     }
  109.     void display(int string_id, int template_message)
  110.     {
  111.         fetch(string_id);
  112.         store(template_message);
  113.         Screen->Message(template_message);
  114.     }
  115. }
  116.  
  117. //SPECIALTY DRAWING WITH MUSIC AND SOUNDS
  118.  
  119.  
  120. namespace script str_template
  121. {
  122.     define FONT         = l;
  123.         define F_COLOUR     = 2;
  124.         define F_BCOLOUR    = 3;
  125.        
  126.         //Window, Solid colour
  127.         define W_COLOUR     = 4;
  128.        
  129.         //Window Tiles
  130.         define TILE     = 5;
  131.         define TILE_W       = 6;
  132.         define TILE_H       = 7;
  133.         define TILE_X       = 8;
  134.         define TILE_Y       = 9;
  135.        
  136.         define CHAR_WIDTH   = 10;
  137.         define CHAR_HEIGHT  = 11;
  138.        
  139.         define WINDOW_X     = 12;
  140.         define WINDOW_Y     = 13;
  141.         define WINDOW_H     = 14;
  142.         define WINDOW_W     = 15;
  143.         define CHAR_X       = 16;
  144.         define CHAR_Y       = 17;
  145.         define W_OPACITY    = 18;
  146.         define T_OPACITY    = 19;
  147.         define F_OPACITY    = 20;
  148.         define W_LAYER      = 21;
  149.         define T_LAYER      = 22;
  150.         define F_LAYER      = 23;
  151.        
  152.         define SOUND_DISPLAY    = 24;
  153.         define SOUND_EXIT   = 25;
  154.         define MUSIC_SPECIAL    = 26; //This is a ZQuest Message String containing the track filename.
  155.         define MUSIC_TRACK  = 27;
  156.         define MIDI_SPECIAL = 28;
  157.        
  158.         define TILE_CSET    = 29;
  159.         define TILE_XSCALE  = 30;
  160.         define TILE_YSCALE  = 31;
  161.        
  162.         define NUM_SETTINGS = 32;
  163.     void run(){}
  164.     //Define a tyle ID
  165.     define BLACK = 1;
  166.     //Declare a function for the style, and list all of the atyle attributes, assigning their data.
  167.     void black(int style_ptr)
  168.     {
  169.         style_ptr[FONT]     = FONT_APPLE2; //Apple II
  170.         style_ptr[F_COLOUR]     = 0x01; //font colour, white
  171.         style_ptr[F_BCOLOUR]    = 0x00; //font background colour, translucent
  172.         style_ptr[W_COLOUR]     = 0x0F; //window colour (background), black
  173.         style_ptr[TILE]     = 0;
  174.         style_ptr[TILE_W]   = 0;
  175.         style_ptr[TILE_H]   = 0;
  176.         style_ptr[TILE_X]   = 0;
  177.         style_ptr[TILE_Y]   = 0;
  178.        
  179.         style_ptr[TILE_CSET]    = 0;
  180.         style_ptr[TILE_XSCALE]  = -1;
  181.         style_ptr[TILE_YSCALE]  = -1;
  182.        
  183.         style_ptr[CHAR_WIDTH]   = 6; //5 + one space
  184.         style_ptr[CHAR_HEIGHT]  = 9; //8 + one space
  185.         style_ptr[WINDOW_X]     = 12; //window indent over screen
  186.         style_ptr[WINDOW_Y]     = 16; //window indent over screen
  187.         style_ptr[WINDOW_H]     = 180; //style_ptr[CHAR_WIDTH * style_ptr[BUFFER_LENGTH;
  188.         style_ptr[WINDOW_W]     = 60; //style_ptrCHAR_HEIGHT * 3;
  189.         style_ptr[CHAR_X]   = 4; //Initial x indent
  190.         style_ptr[CHAR_Y]   = 12; //Initial y indent
  191.         style_ptr[W_OPACITY]    = OP_OPAQUE; //Window translucency.
  192.         style_ptr[F_OPACITY]    = OP_OPAQUE; //Font translucency.
  193.         style_ptr[T_OPACITY]    = OP_OPAQUE; //Font translucency.
  194.         style_ptr[W_LAYER]  = 6; //window draw layer
  195.         style_ptr[T_LAYER]  = 6; //font draw layer
  196.         style_ptr[F_LAYER]  = 6; //font draw layer
  197.        
  198.         style_ptr[SOUND_EXIT]   = 63;
  199.         style_ptr[NUM_SETTINGS] = 64;
  200.        
  201.         style_ptr[MUSIC_SPECIAL]= 0; //Needs a function call assign. May not work.
  202.         style_ptr[MIDI_SPECIAL] = 0;
  203.        
  204.     }
  205.    
  206.     //! We need a way to append messages without restarting the music or closing the box entirely.
  207.     //! perhaps in the function to press a button? Or some kind of CALLBACK.
  208.     void draw(int mode, int number_of_lines) //number_of_lines is to append more strings, to advance
  209.     {
  210.        
  211.         int style[NUM_SETTINGS]; //The mode arg will call a function to populate this.
  212.        
  213.         //! List all STYLE CASEs here, and call their functions.
  214.         switch(mode)
  215.         {
  216.             //Populate the 'style' array with attributed defined in the
  217.             //style population function for the CASE value.
  218.             case BLACK: black(style); break; //'style' is the pointer to our array
  219.                    
  220.             default: TraceError("Invalid Message Style passed to str_template.draw()", mode); break;
  221.         }
  222.        
  223.        
  224.         //STORE OLD MIDI AND MUSIC
  225.        
  226.         int old_music[256]; int old_track = Game->GetDMapMusicTrack(Game->GetCurDMap());
  227.         GetDMapMusicFilename(Game->GetCurDMap(), old_music);
  228.        
  229.         int old_midi = Game->GetMIDI();
  230.        
  231.         //Play the display sound.
  232.         Audio->PlaySound(style[SOUND_DISPLAY]);
  233.        
  234.         //IF SET, PLAY SPECIAL MIDI OR MUSIC
  235.         bool playing = false;
  236.         if ( style[MUSIC_SPECIAL] )
  237.         {
  238.             //! This is tricky, because we need to pass the name of the track without wasying a variable.
  239.             //! Let's use a message for it!
  240.             int music_buf[256]; GetMessage(style[MUSIC_SPECIAL], music_buf);
  241.             playing = PlayEnhancedMusic(music_buf, style[MUSIC_TRACK]);
  242.         }
  243.        
  244.         if ( !playing )
  245.         {   //if the enhanced muwsic failed, or we are only using MIDIs,
  246.             if ( style[MIDI_SPECIAL] )
  247.             {
  248.                 //and we have set a MIDI to play,
  249.                 //PLAY IT HERE
  250.                 Audio->PlayMIDI(style[MIDI_SPECIAL]);
  251.             }
  252.         }
  253.        
  254.         //Do the drawing
  255.         do
  256.         {
  257.             Screen->Rectangle(style[W_LAYER], style[WINDOW_X], style[WINDOW_Y], style[WINDOW_X+WINDOW_W],
  258.             style[WINDOW_Y+WINDOW_H], style[W_COLOUR], 100, 0,0,0,true,style[W_OPACITY]);
  259.            
  260.             //if we are overlaying a tile block, or just using that:
  261.             if ( style[TILE] )
  262.             {
  263.                 Screen->DrawTile(style[T_LAYER], style[TILE_X], style[TILE_Y], style[TILE],
  264.                     style[TILE_W], style[TILE_H], style[TILE_CSET], style[TILE_XSCALE],
  265.                     style[TILE_YSCALE], 0, 0, 0, 0, false, T_OPACITY);
  266.             }
  267.             Screen->DrawString(F_LAYER,CHAR_X,CHAR_Y,FONT,F_COLOUR,F_BCOLOUR,0,strings.buffer,F_OPACITY);
  268.             if ( Input->Press[CB_A] || Input->Press[CB_B] ) //advance the message
  269.             {
  270.                 strings.fetch(strings.ids[CURRENT_STRING_ID]+1); //Get the next string in the sequence.
  271.                 --number_of_lines
  272.             }
  273.             Waitframe();
  274.         }while(waiting_for_press() && number_of_lines > 0); //
  275.        
  276.         //Play the exit sound, for closing the display.
  277.         Audio->PlaySound(style[SOUND_EXIT]);
  278.         playing = false; //Restore its state to reuse it.
  279.        
  280.         //RESTORE OLD MIDI OR MUSIC
  281.         if ( old_music[4] ) //if there was ednhanced music, restore it
  282.             //using the 4th character to avoid error return data being read.
  283.             //IDR what GetDMapMusicFilename() stores in the array if there is no enhanced music.
  284.             //if there is music playing, it will need at least four characters (1.mp3, the fourth character is 'p').
  285.         {
  286.             playing = Game->PlayEnhancedMusic(old_music, old_track);
  287.            
  288.         }
  289.         if ( !playing ) //Either the restored music did not load, or there was none.
  290.         {
  291.             Game->PlayMIDI(old_midi); //Restore the MIDI
  292.         }
  293.     }
  294.     bool waiting_for_press()
  295.     {
  296.         if ( Input->Pres[CB_A] ) return false;
  297.         if ( Input->Pres[CB_B] ) return false;
  298.         return true;
  299.     }
  300.        
  301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement