Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

OSERES.CPP Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

OSERES.CPP

Go to the documentation of this file.
00001 // Filename    : OSERES.CPP
00002 // Description : Sound resource
00003 //  search a sound effect id from subject verb object
00004 //  pass the id to se_ctrl.request to trigger the sound effect
00005 // Owner       : Gilbert
00006 
00007 #include <OSERES.H>
00008 #include <OSE.H>
00009 #include <OGAMESET.H>
00010 #include <OWORLD.H>
00011 #include <OCONFIG.H>
00012 #include <string.h>
00013 #include <stdlib.h>
00014 
00015 // ---------- Define constant ----------//
00016 #define SERES_DB "SOUNDRES"
00017 unsigned long SERes::last_select_time = 0;
00018 unsigned long SERes::last_command_time = 0;
00019 unsigned long SERes::select_sound_length = 600;   // time between successive select sound
00020 
00021 // --------- begin of function SEInfo::match ----------//
00022 int SEInfo::match(char subjectType, short subjectId, char *act,
00023                   char objectType, short objectId) {
00024     // object_type == -1, match all object type
00025     // object_id == -1, match all object id of that type
00026     return subject_type == subjectType &&
00027         (subject_id == -1 || subject_id == subjectId) &&
00028         strncmp(action, act, VERB_LEN )== 0 &&
00029         (object_type == -1 || (object_type == objectType &&
00030                                (object_id == -1 || object_id == objectId)));
00031 }
00032 
00033 // --------- end of function SEInfo::match ----------//
00034 
00035 // --------- begin of function SERes::SERes ----------//
00036 SERes::SERes() {
00037     init_flag = 0;
00038     se_array_count = 0;
00039     se_array = NULL;
00040     se_index_count = 0;
00041     se_index_array = NULL;
00042     type_index_count = 0;
00043     type_index_array = NULL;
00044 }
00045 
00046 // --------- end of function SERes::SERes ----------//
00047 
00048 // --------- begin of function SERes::~SERes ----------//
00049 SERes::~SERes() {
00050     deinit();
00051 }
00052 
00053 // --------- end of function SERes::~SERes ----------//
00054 
00055 // --------- begin of function SERes::init1 ----------//
00056 void SERes::init1() {
00057     deinit();
00058     seed = m.get_time();
00059     load_info();
00060     sort_info();
00061     build_index();
00062     init_flag = 1;
00063 }
00064 
00065 // --------- end of function SERes::init1 ----------//
00066 
00067 // --------- begin of function SERes::init2 ----------//
00068 // called after se_ctrl is init
00069 void SERes::init2(SECtrl *seCtrl) {
00070     err_when( !seCtrl || !seCtrl->init_flag );
00071     err_when( init_flag == 0 );
00072     se_output = seCtrl;
00073     int i;
00074     SEInfo *seInfo;
00075     for(i = 0, seInfo = se_array; i < se_array_count; ++i, ++seInfo ) {
00076         seInfo->effect_id = seCtrl->search_effect_id(seInfo->file_name);
00077     }
00078 
00079     init_flag = 2;
00080 }
00081 
00082 // --------- end of function SERes::init2 ----------//
00083 
00084 // --------- begin of function SERes::deinit ----------//
00085 void SERes::deinit() {
00086     if( init_flag ) {
00087         mem_del(se_array);
00088         se_array = NULL;
00089         se_array_count = 0;
00090 
00091         mem_del(se_index_array);
00092         se_index_array = NULL;
00093         se_index_count = 0;
00094 
00095         mem_del(type_index_array);
00096         type_index_array = NULL;
00097         type_index_count = 0;
00098 
00099         init_flag = 0;
00100     }
00101 }
00102 
00103 // --------- end of function SERes::deinit ----------//
00104 
00105 // --------- begin of function SERes::load_info ----------//
00106 void SERes::load_info() {
00107     SERec *seRec;
00108     SEInfo *seInfo;
00109     int i;
00110     Database *dbSE = game_set.open_db(SERES_DB);
00111 
00112     se_array_count = dbSE->rec_count();
00113     se_array = (SEInfo *)mem_add(sizeof(SEInfo) * se_array_count);
00114     memset( se_array, 0, sizeof(SEInfo) * se_array_count );
00115 
00116     for( i = 0; i < se_array_count; ++i ) {
00117         seRec = (SERec *) dbSE->read(i+1);
00118         seInfo = se_array+i;
00119 
00120         // ------- copy subject ---------//
00121         seInfo->subject_type = seRec->subject_type;
00122         seInfo->subject_id = m.atoi(seRec->subject_id, seRec->RECNO_LEN);
00123 
00124         // -------- copy verb ---------//
00125         memcpy( seInfo->action, seRec->action, seRec->VERB_LEN );
00126         seInfo->action[seInfo->VERB_LEN] = '\0';
00127         m.rtrim( seInfo->action );
00128 
00129         // --------- copy object ---------//
00130         if( seRec->object_type == ' ' || seRec->object_type == '\0') {
00131             seInfo->object_type = 0;
00132             seInfo->object_id = 0;
00133         }
00134         else if( seRec->object_type == '*' ) {
00135             seInfo->object_type = -1;                   // all object
00136             seInfo->object_id = -1;
00137         }
00138         else {
00139             seInfo->object_type = seRec->object_type;
00140             if( seRec->object_id[0] != '*' )
00141                 seInfo->object_id = m.atoi(seRec->object_id, seRec->RECNO_LEN);
00142             else
00143                 seInfo->object_id = -1;                   // all of the objectType
00144         }
00145 
00146         // -------- copy out frame ---------//
00147         seInfo->out_frame = m.atoi(seRec->out_frame, seRec->OUT_FRAME_LEN);
00148         err_when(seInfo->out_frame <= 0);
00149 
00150         // -------- copy file name --------//
00151         memcpy(seInfo->file_name, seRec->file_name, seRec->FILE_NAME_LEN);
00152         seInfo->file_name[seInfo->FILE_NAME_LEN] = '\0';
00153         m.rtrim(seInfo->file_name);
00154         seInfo->effect_id = 0;
00155     }
00156 }
00157 
00158 // --------- end of function SERes::load_info ----------//
00159 
00160 // --------- begin of function SERes::sort_info --------//
00161 static int seinfo_cmp(const void *r1, const void *r2) {
00162     return memcmp(r1, r2, sizeof(SEInfo));
00163 }
00164 
00165 void SERes::sort_info() {
00166     // notice object_id -1 are put after any other object_id
00167     qsort(se_array, se_array_count, sizeof(SEInfo), seinfo_cmp);
00168 }
00169 
00170 // --------- end of function SERes::sort_info --------//
00171 
00172 // --------- begin of function SERes::build_index -------//
00173 // build index on (subject_type, subject_id)
00174 void SERes::build_index() {
00175     // ---------- first pass, count the size of index ---------//
00176 
00177     int i,j,k;
00178     SEInfo *seInfo;
00179     char lastType = -1;
00180     short lastId;
00181 
00182     type_index_count = 0;
00183     se_index_count = 0;
00184 
00185     for(i = 0, seInfo = se_array; i < se_array_count; ++i, ++seInfo) {
00186         if( lastType != seInfo->subject_type) {
00187             type_index_count++;
00188             se_index_count++;
00189             lastType = seInfo->subject_type;
00190             lastId = seInfo->subject_id;
00191         }
00192         else if( lastId != seInfo->subject_id) {
00193             se_index_count++;
00194             lastId = seInfo->subject_id;
00195         }
00196     }
00197 
00198     // --------- allocate memory for index ----------//
00199 
00200     SEInfoIndex *seIndex = se_index_array = (SEInfoIndex *)
00201         mem_resize( se_index_array, sizeof(SEInfoIndex) * se_index_count);
00202     memset( se_index_array, 0, sizeof(SEInfoIndex) * se_index_count);
00203 
00204     SETypeIndex *typeIndex = type_index_array = (SETypeIndex *)
00205         mem_resize( type_index_array, sizeof(SETypeIndex) * type_index_count);
00206     memset( type_index_array, 0, sizeof(SETypeIndex) * type_index_count);
00207 
00208     // ---------- pass 2, build indices -----------//
00209     seIndex--;                                      // move one step backward
00210     typeIndex--;
00211     j = -1;
00212     k = -1;
00213     lastType = -1;
00214     for(i = 0, seInfo = se_array; i < se_array_count; ++i, ++seInfo) {
00215         if( lastType != seInfo->subject_type) {
00216             // ----------- new (type,Id) ---------//
00217             ++seIndex;
00218             ++j;
00219             seIndex->subject_type = seInfo->subject_type;
00220             seIndex->subject_id = seInfo->subject_id;
00221             seIndex->start_rec = seIndex->end_rec = i;
00222 
00223             // ----------- new type ---------//
00224             ++typeIndex;
00225             ++k;
00226             typeIndex->subject_type = seInfo->subject_type;
00227             typeIndex->start_rec = typeIndex->end_rec = j;
00228 
00229             lastType = seInfo->subject_type;
00230             lastId = seInfo->subject_id;
00231         }
00232         else {
00233             err_when(typeIndex < type_index_array);     // must not enter here for the first time
00234 
00235             if( lastId != seInfo->subject_id) {
00236                 // ----------- new (type,Id) ---------//
00237                 ++seIndex;
00238                 ++j;
00239                 seIndex->subject_type = seInfo->subject_type;
00240                 seIndex->subject_id = seInfo->subject_id;
00241                 seIndex->start_rec = i;
00242                 seIndex->end_rec = i;
00243 
00244                 lastId = seInfo->subject_id;
00245             }
00246             else {
00247                 err_when(seIndex < se_index_array);
00248                 seIndex->end_rec = i;
00249             }
00250             typeIndex->end_rec = j;
00251         }
00252     }
00253 }
00254 
00255 // --------- end of function SERes::build_index -------//
00256 
00257 // --------- begin of function SERes::scan ----------//
00258 // search the SEInfo whose subject, action and object match
00259 // <char> subjectType        type of subject 'S'= sprite,
00260 //                           'U'=unit, 'R'=race, 'F'=firm, 'T'=town
00261 // <short> subjectId         sprite_id, unit_id, race_id or firm_id ...
00262 // <char *> act              name of the action, first four chars are significant
00263 // [char] objectType         type of object 'S'= sprite,
00264 //                           'U'=unit, 'R'=race, 'F'=firm, 'T'=town
00265 //                           default : 0 (none)
00266 // [short] objectId          sprite_id, unit_id, race_id or firm_id ...
00267 //                           default : 0 (none)
00268 //
00269 // return NULL if not found
00270 //
00271 SEInfo* SERes::scan(char subjectType, short subjectId, char *act,
00272                     char objectType, short objectId, int findFirst) {
00273     err_when(!init_flag);
00274 
00275     int startRec, endRec, i;
00276     SETypeIndex *typeIndex;
00277     SEInfoIndex *seIndex;
00278     SEInfo *seInfo;
00279 
00280   // ---------- search the type_index_array ---------//
00281     int foundFlag = 0;
00282     for( i = 0, typeIndex = type_index_array; i < type_index_count; ++i, ++typeIndex) {
00283         if( subjectType == typeIndex->subject_type) {
00284             startRec = typeIndex->start_rec;
00285             endRec = typeIndex->end_rec;
00286             foundFlag = 1;
00287             break;
00288         }
00289     }
00290     if( !foundFlag )
00291         return NULL;
00292 
00293   // ---------- search the se_index_array ---------//
00294     foundFlag = 0;
00295     for( i = startRec, seIndex = se_index_array + startRec; i <= endRec;
00296          ++i, ++seIndex) {
00297         if( subjectId == seIndex->subject_id && subjectType == seIndex->subject_type) {
00298             startRec = seIndex->start_rec;
00299             endRec = seIndex->end_rec;
00300             foundFlag = 1;
00301             break;
00302         }
00303     }
00304     if( !foundFlag )                                // not found
00305         return NULL;
00306 
00307   // ----------- search the se_array ----------//
00308     for(i = startRec, seInfo = se_array + startRec; i <= endRec;
00309         ++i, ++seInfo) {
00310         if( seInfo->match(subjectType, subjectId, act, objectType, objectId) )
00311             break;
00312     }
00313     if( i <= endRec ) {                             // found
00314         if( findFirst )
00315             return seInfo;
00316         int found = 1;
00317         SEInfo *retSEInfo = seInfo;
00318         for( ++i, ++seInfo ; i <= endRec && found <= 4 &&
00319                  seInfo->match(subjectType, subjectId, act, objectType, objectId);
00320              ++i, ++seInfo ) {
00321             ++found;
00322             if( random(found+1) == 0)
00323                 retSEInfo = seInfo;
00324         }
00325         return retSEInfo;
00326     }
00327     return NULL;
00328 }
00329 
00330 // --------- end of function SERes::scan ----------//
00331 
00332 // --------- begin of function SERes::scan_id ----------//
00333 short SERes::scan_id(char subjectType, short subjectId, char *act,
00334                      char objectType, short objectId, int findFirst) {
00335     SEInfo *seInfo;
00336     if( (seInfo = scan(subjectType, subjectId, act, objectType, objectId, findFirst))
00337         != NULL)
00338         return seInfo->effect_id;
00339     return 0;
00340 }
00341 
00342 // --------- end of function SERes::scan_id ----------//
00343 
00344 // --------- begin of function SERes::operator[] ----------//
00345 SEInfo* SERes::operator[] (int i) {
00346     err_when(!init_flag || i <= 0 || i > se_array_count);
00347     return se_array + i - 1;
00348 }
00349 
00350 // --------- end of function SERes::operator[] ----------//
00351 
00352 // --------- begin of function SERes::sound ----------//
00353 void SERes::sound(short xLoc, short yLoc, short frame,
00354                   char subjectType,short subjectId, char *action, char objectType,short objectId) {
00355     /*
00356       //### begin trevor 20/8 ###//
00357       if( !config.sound_effect_flag )
00358       return;
00359       //### end trevor 20/8 ###//
00360 
00361       short relXLoc = xLoc - (world.zoom_matrix->top_x_loc + world.zoom_matrix->disp_x_loc/2);
00362       short relYLoc = yLoc - (world.zoom_matrix->top_y_loc + world.zoom_matrix->disp_y_loc/2);
00363       RelVolume relVolume( PosVolume(relXLoc, relYLoc) );
00364       if( !config.pan_control )
00365       relVolume.ds_pan = 0;
00366       SEInfo *seInfo;
00367 
00368       if( relVolume.rel_vol < 5)
00369       return;
00370 
00371       if( (seInfo=scan(subjectType, subjectId, action, objectType, objectId))
00372       != NULL && frame == seInfo->out_frame)
00373       {
00374       se_output->request(seInfo->effect_id, relVolume );
00375       }
00376     */
00377 }
00378 
00379 // --------- end of function SERes::sound ----------//
00380 
00381 // --------- begin of function SERes::far_sound ----------//
00382 //
00383 // as same as far_sound, but no cut_off volume
00384 // usually used in acknowlege voice
00385 //
00386 void SERes::far_sound(short xLoc, short yLoc, short frame,
00387                       char subjectType,short subjectId, char *action, char objectType,short objectId) {
00388     /*
00389       //### begin trevor 20/8 ###//
00390       if( !config.sound_effect_flag )
00391       return;
00392       //### end trevor 20/8 ###//
00393 
00394       short relXLoc = xLoc - (world.zoom_matrix->top_x_loc + world.zoom_matrix->disp_x_loc/2);
00395       short relYLoc = yLoc - (world.zoom_matrix->top_y_loc + world.zoom_matrix->disp_y_loc/2);
00396       RelVolume relVolume( PosVolume(relXLoc, relYLoc), 200, MAX_MAP_WIDTH );
00397       if( !config.pan_control )
00398       relVolume.ds_pan = 0;
00399       SEInfo *seInfo;
00400 
00401       if( relVolume.rel_vol < 80)
00402       relVolume.rel_vol = 80;
00403 
00404       if( (seInfo=scan(subjectType, subjectId, action, objectType, objectId))
00405       != NULL && frame == seInfo->out_frame)
00406       {
00407       se_output->request(seInfo->effect_id, relVolume );
00408       }
00409     */
00410 }
00411 
00412 // --------- end of function SERes::far_sound ----------//
00413 
00414 // --------- begin of function SERes::mark_select_object_time ----------//
00415 int SERes::mark_select_object_time() {            // return false if this sound should be skipped due to too frequent
00416     unsigned long t = m.get_time();
00417     if( t - last_select_time >= select_sound_length ) {
00418         last_select_time = t;
00419         return 1;
00420     }
00421     return 0;
00422 }
00423 
00424 // --------- end of function SERes::mark_select_object_time ----------//
00425 
00426 // --------- begin of function SERes::mark_select_object_time ----------//
00427 int SERes::mark_command_time() {                  // return false if this sound should be skipped due to too frequent
00428     unsigned long t = m.get_time();
00429     //  if( t - last_command_time >= select_sound_length )
00430     //  {
00431     //          last_command_time = t;
00432     //          return 1;
00433     //  }
00434     if( t - last_select_time >= select_sound_length ) {
00435         last_select_time = t;
00436         return 1;
00437     }
00438     return 0;
00439 }
00440 
00441 // --------- end of function SERes::mark_select_object_time ----------//
00442 
00443 //-------------- Begin Function SERes::random ---------//
00444 unsigned SERes::random(unsigned bound) {
00445 #define MULTIPLIER      0x015a4e35L
00446 #define INCREMENT       1
00447     seed = MULTIPLIER * seed + INCREMENT;
00448     return seed % bound;
00449 }
00450 
00451 //-------------- End Function SERes::random ---------//

Generated on Fri Aug 23 01:38:22 2002 for VirtualU by doxygen1.2.17