00001
00002
00003
00004
00005
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
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;
00020
00021
00022 int SEInfo::match(char subjectType, short subjectId, char *act,
00023 char objectType, short objectId) {
00024
00025
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
00034
00035
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
00047
00048
00049 SERes::~SERes() {
00050 deinit();
00051 }
00052
00053
00054
00055
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
00066
00067
00068
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
00083
00084
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
00104
00105
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
00121 seInfo->subject_type = seRec->subject_type;
00122 seInfo->subject_id = m.atoi(seRec->subject_id, seRec->RECNO_LEN);
00123
00124
00125 memcpy( seInfo->action, seRec->action, seRec->VERB_LEN );
00126 seInfo->action[seInfo->VERB_LEN] = '\0';
00127 m.rtrim( seInfo->action );
00128
00129
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;
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;
00144 }
00145
00146
00147 seInfo->out_frame = m.atoi(seRec->out_frame, seRec->OUT_FRAME_LEN);
00148 err_when(seInfo->out_frame <= 0);
00149
00150
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
00159
00160
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
00167 qsort(se_array, se_array_count, sizeof(SEInfo), seinfo_cmp);
00168 }
00169
00170
00171
00172
00173
00174 void SERes::build_index() {
00175
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
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
00209 seIndex--;
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
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
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);
00234
00235 if( lastId != seInfo->subject_id) {
00236
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
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
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
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
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 )
00305 return NULL;
00306
00307
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 ) {
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
00331
00332
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
00343
00344
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
00351
00352
00353 void SERes::sound(short xLoc, short yLoc, short frame,
00354 char subjectType,short subjectId, char *action, char objectType,short objectId) {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 }
00378
00379
00380
00381
00382
00383
00384
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
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 }
00411
00412
00413
00414
00415 int SERes::mark_select_object_time() {
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
00425
00426
00427 int SERes::mark_command_time() {
00428 unsigned long t = m.get_time();
00429
00430
00431
00432
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
00442
00443
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