Advertisement
ZoriaRPG

New String Table Processor, (Fix Compile)

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