00001
00002
00003
00004
00005 #include <windows.h>
00006 #include <ALL.H>
00007 #include <OBATTLE.H>
00008 #include <OCOMBUF.H>
00009 #include <OCONFIG.H>
00010 #include <ODATE.H>
00011 #include <ODEBUGX.H>
00012 #include <OGAME.H>
00013 #include <OGAMESET.H>
00014 #include <OIMGRES.H>
00015 #include <OINFO.H>
00016 #include <OMISC.H>
00017 #include <OMATH.H>
00018 #include <OMOUSE.H>
00019 #include <OMOUSECR.H>
00020 #include <OPOWER.H>
00021 #include <OSYS.H>
00022 #include <OVGA.H>
00023 #include <OWORLD.H>
00024 #include <OTRANSL.H>
00025 #include <OAUDIO.H>
00026 #include <OBOX.H>
00027 #include <OFONT.H>
00028 #include <OGFILE.H>
00029 #include <OVIDEO.H>
00030 #include <OSE.H>
00031 #include <OSERES.H>
00032 #include <OMUSIC.H>
00033 #include <OHELP.H>
00034 #include <OGCONFIG.H>
00035 #include <OSCHLRES.H>
00036 #include <OCOURRES.H>
00037 #include <ODEPTRES.H>
00038 #include <OFACURES.H>
00039 #include <OGAMESTR.H>
00040 #include <OFPHOTO.H>
00041 #include <OFIELD.H>
00042 #include <OFIRMRES.H>
00043 #include <OSPRTRES.H>
00044 #include <OTERRAIN.H>
00045 #include <OPLANT.H>
00046 #include <OROAD.H>
00047 #include <ONAMERES.H>
00048
00049 #include <OENROLL.H>
00050 #include <ONEWS.H>
00051 #include <OTASK.H>
00052 #include <OCHANCE.H>
00053 #include <ODEPT.H>
00054 #include <OFINANCE.H>
00055 #include <OPSCHOOL.H>
00056 #include <OFIRMA.H>
00057
00058
00059
00060 #include <OIFACE.H>
00061 #include <OADM_OFF.H>
00062 #include <OOPT.H>
00063 #include <OOPT3.H>
00064 #include <OATHLETI.H>
00065 #include <ODEVELOP.H>
00066 #include <OFACILIT.H>
00067 #include <OLIBTECH.H>
00068 #include <OINVEST.H>
00069 #include <OSTUOFF.H>
00070 #include <OTEST.H>
00071 #include <OGSET.H>
00072 #include <OHELPIF.H>
00073 #include <OLETTER.H>
00074 #include <OBLCKBRD.H>
00075 #include <OMORERPT.H>
00076 #include <ODEPTLST.H>
00077 #include <OPARKING.H>
00078 #include <OCRIME.H>
00079 #include <ORETIRE.H>
00080 #include <OBANKRUP.H>
00081 #include <OFINSCOR.H>
00082 #include <OSCEN_IF.H>
00083 #include <OLOSEGAM.H>
00084 #include <OPRTMENU.H>
00085 #include <OMISCREP.H>
00086
00087 #include <OPRINT.H>
00088 #include <excpt.h>
00089
00090
00091
00092
00093
00094 char *GAME_VERSION_STR = "2.01";
00095
00096
00097
00098 #ifndef NO_MEM_CLASS
00099 Mem mem;
00100 #endif
00101
00102 CommonBuf common_buf;
00103 DateInfo date;
00104 DebugX debugx;
00105 Error err;
00106 Misc m;
00107 Math math;
00108
00109
00110 Video video;
00111 Config config;
00112
00113
00114
00115 Audio audio;
00116 Music music;
00117 SECtrl se_ctrl(&audio);
00118 SERes se_res;
00119 Vga vga;
00120 VgaBuf vga_front, vga_back, vga_true_front;
00121
00122
00123
00124 MouseCursor mouse_cursor;
00125 Mouse mouse;
00126 Help help;
00127
00128 Box box;
00129 Translate translate;
00130 UserInterface user_interface;
00131
00132
00133
00134 Font font_san, font_std, font_small, font_mid, font_news, font_casa;
00135
00136 Font font_yellow_diamond;
00137 Font font_fdiamond;
00138 Font font_fblack;
00139 Font font_charts;
00140 Font font_chartsm;
00141 Font font_chart_red_sm;
00142 Font font_chart_green_sm;
00143 Font font_chart_blue_sm;
00144 Font font_chart_orange_sm;
00145 Font font_chart_purple_sm;
00146 Font font_redcharts;
00147 Font font_barcharts;
00148 Font font_fscore;
00149 Font font_numbers;
00150 Font font_stone;
00151 Font font_hstone;
00152 Font font_small_san;
00153 Font font_red_san;
00154 Font font_green_san;
00155 Font font_blue_san;
00156 Font font_letter;
00157 Font font_pgold;
00158 Font font_psilver;
00159 Font font_pbronze;
00160
00161 ImageRes image_sys, image_interface, image_mascot, image_pict;
00162 GameSet game_set;
00163 Print print;
00164
00165
00166
00167 TerrainRes terrain_res;
00168 PlantRes plant_res;
00169 RoadRes road_res;
00170
00171 SchoolRes school_res;
00172 FieldRes field_res;
00173 DepartmentRes department_res;
00174 FirmRes firm_res;
00175 FacultyRes faculty_res;
00176 FacultyPhotoRes faculty_photo_res;
00177 NameRes name_res;
00178 Letter letter;
00179 CourseRes course_res;
00180 EnrollRes enroll_res;
00181
00182
00183
00184 FirmArray firm_array;
00185 DepartmentArray department_array;
00186
00187
00188 GameStrRes game_str_res;
00189 BlackBoard blackboard;
00190
00191
00192
00193
00194 NewsArray news_array;
00195 TaskArray task_array;
00196 ChanceEvent chance_event;
00197
00198
00199
00200 PlayerSchool player_school;
00201 Battle battle;
00202 GoalConfig goal_config;
00203 Info info;
00204 Power power;
00205 World world;
00206 Finance finance;
00207
00208
00209 AdmOffice adm_office;
00210 Development development_office;
00211 Optimization optimization;
00212 OptStage3 opt_stage3;
00213 Athletics athletics_office;
00214 LibTech library_tech_office;
00215 Facility facility_office;
00216 Investment investment_office;
00217 StudentOffice student_office;
00218 HelpIf help_if;
00219 GameSetting game_setting;
00220 MiscReport misc_report;
00221 MoreReport more_report;
00222 DeptList dept_list;
00223 Crime crime;
00224 Parking parking;
00225
00226 BankruptcyReport bankruptcy;
00227 FinalScoreReport final_score;
00228 ScenarioReport scenario_report;
00229 RetirementReport retirement;
00230 LoseGameReport lose_game;
00231
00232 PrintMenu print_menu;
00233
00234
00235
00236
00237
00238 Game game;
00239 GameFileArray game_file_array;
00240 GameFile game_file;
00241
00242
00243
00244 Sys sys;
00245
00246
00247
00248 static void extra_error_handler();
00249 static int is_math_exception( DWORD, _EXCEPTION_POINTERS * );
00250 static void play_video(HINSTANCE hInstance, int videoId);
00251
00252 #ifdef DEMO
00253 static void demo_screen();
00254 static void open_http(char* shortcutFilename, char* httpAddr);
00255 #endif
00256
00257
00275
00276 LPSTR lpCmdLine, int nCmdShow) {
00277
00278
00279 sys.set_game_dir();
00280
00281 #ifndef NO_CDCHECK
00282
00283 #ifndef DEMO
00284 if( !sys.cdrom_drive ) {
00285 #ifdef ADMIN
00286 char* msg = "Please insert Virtual U - Administrator Version CDROM and try again.";
00287 #else
00288 char* msg = "Please insert Virtual U CDROM and try again.";
00289 #endif
00290
00291 MessageBox(sys.main_hwnd, msg, WIN_TITLE, MB_OK | MB_ICONERROR);
00292 return 0;
00293 }
00294 #endif
00295 #endif
00296
00297
00298
00299 OSVERSIONINFO osVersion;
00300 memset( &osVersion, 0, sizeof(osVersion) );
00301
00302 osVersion.dwOSVersionInfoSize = sizeof(osVersion);
00303
00304 if( !m.is_file_exist("SKIPAVI.SYS")
00305 && GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) {
00306 play_video(hInstance, 0);
00307 }
00308
00309 config.init();
00310
00311
00312
00313 if( !sys.init(hInstance) )
00314 return FALSE;
00315
00316 err.set_extra_handler( extra_error_handler );
00317
00318 #if(GAME_VERSION>=200)
00319 #ifdef DEBUG
00320
00321 if( sys.debug_session ) {
00322
00323
00324 _control87( _EM_INEXACT | _EM_UNDERFLOW | _EM_DENORMAL, _MCW_EM );
00325 }
00326 #endif // DEBUG
00327 #endif // GAME_VERSION>=200
00328
00329 #ifdef DEMO
00330 audio.play_wav("DEMOOPEN",audio.int_to_DsVolume(config.sound_effect_volume));
00331 #endif
00332
00333 game.main_menu();
00334
00335 #ifdef DEMO
00336 demo_screen();
00337 #endif
00338
00339 sys.deinit();
00340
00341 return 0;
00342 }
00343
00344
00345
00346
00350
00351 #ifdef DEBUG
00352
00353 void __cdecl debug_msg( char* fmt, ... ) {
00354 char buff[256];
00355
00356 lstrcpy( buff, "Virtual U: " );
00357 wvsprintf( buff+lstrlen(buff), fmt, (char*)(&fmt+1) );
00358 lstrcat( buff, "\r\n" );
00359
00360 OutputDebugString( buff );
00361 }
00362 #endif
00363
00364
00365
00366
00367
00368 static void extra_error_handler() {
00369
00370
00371
00372
00373
00374
00375
00376
00377 }
00378
00379
00380
00381
00382
00383 static void play_video(HINSTANCE hInstance, int videoId) {
00384 String movieFileStr;
00385
00386 if( videoId == 0 ) {
00387 movieFileStr += "INTRO.AVI";
00388 }
00389 else {
00390 movieFileStr += "MOVIE";
00391 movieFileStr += videoId;
00392 movieFileStr += ".AVI";
00393 }
00394
00395 video.set_skip_on_fail();
00396
00397 if( m.is_file_exist(movieFileStr) ) {
00398
00399
00400 video.init();
00401
00402 if( video.init_success ) {
00403 video.play_until_end( movieFileStr, hInstance, 60 );
00404 }
00405 else {
00406
00407
00408
00409 }
00410
00411 video.deinit();
00412 }
00413 }
00414
00415
00416
00417 #ifdef DEMO
00418
00419
00420
00421 #define DEMO_BUTTON_COUNT 3
00422
00423 enum {
00424 BUTTON_WIDTH = 201,
00425 BUTTON_HEIGHT = 37
00426 };
00427
00430 struct DemoButton {
00431 short x1;
00432 short y1;
00433 short width;
00434 short height;
00435 char* file_name;
00436 };
00437
00438
00439
00440 static DemoButton demo_button_array[] = {
00441 { 83 , 508, 186, 65, "DEMOSCR1" },
00442 { 339, 508, 183, 64, "DEMOSCR2" },
00443 { 622, 508, 80, 65, "DEMOSCR3" },
00444 };
00445
00446
00447
00448 static void demo_screen() {
00449
00450
00451 int dataSize;
00452 File* filePtr = image_interface.get_file("DEMOSCR", dataSize);
00453
00454 if (filePtr->file_get_short() != -1 ) {
00455 filePtr->file_seek(filePtr->file_pos() - sizeof(short));
00456 vga_back.put_large_bitmap(0, 0, filePtr);
00457 }
00458 else {
00459 unsigned char palette[256 * 3];
00460 short *remapTable;
00461 filePtr->file_read(palette, 256 * 3);
00462 PalDesc palDesc(palette, 3, 256, 6);
00463 ColorTable colorTable;
00464 colorTable.generate_table_fast(MAX_BRIGHTNESS_ADJUST_DEGREE, palDesc, ColorTable::bright_func);
00465 remapTable = (short *) colorTable.get_table(0);
00466 vga_back.put_large_bitmap(0, 0, filePtr, remapTable);
00467 }
00468
00469 vga.blt_buf(0,0,VGA_WIDTH-1,VGA_HEIGHT-1);
00470 sys.blt_virtual_buf();
00471
00472
00473
00474 int highlightButton=0;
00475
00476 while(1) {
00477 MSG msg;
00478
00479 if (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) {
00480 if (!GetMessage( &msg, NULL, 0, 0)) {
00481 return;
00482 }
00483
00484 TranslateMessage(&msg);
00485 DispatchMessage(&msg);
00486 continue;
00487 }
00488 else if( sys.paused_flag || !sys.active_flag ) {
00489 WaitMessage();
00490 continue;
00491 }
00492
00493
00494
00495 sys.yield();
00496 mouse.get_event();
00497
00498 DemoButton* buttonPtr = demo_button_array;
00499
00500 for( int i=0 ; i<DEMO_BUTTON_COUNT ; i++, buttonPtr++ ) {
00501
00502
00503 if( mouse.single_click( buttonPtr->x1, buttonPtr->y1,
00504 buttonPtr->x1+buttonPtr->width-1, buttonPtr->y1+buttonPtr->height-1, 0 ) ) {
00505 audio.play_wav("BEEPS-1",audio.int_to_DsVolume(config.sound_effect_volume));
00506
00507 switch(i) {
00508 case 0:
00509 open_http( "anker.url", "http://www.ankerpub.com" );
00510 return;
00511
00512 case 1:
00513 open_http( "vu.url", "http://www.virtual-u.org" );
00514 return;
00515
00516 case 2:
00517 return;
00518 }
00519 }
00520
00521
00522
00523 if( mouse.in_area( buttonPtr->x1, buttonPtr->y1,
00524 buttonPtr->x1+buttonPtr->width-1, buttonPtr->y1+buttonPtr->height-1 ) ) {
00525 if( highlightButton != i+1 ) {
00526 highlightButton = i+1;
00527
00528
00529 vga.blt_buf(0,0,VGA_WIDTH-1,VGA_HEIGHT-1);
00530
00531 mouse.hide_area(buttonPtr->x1, buttonPtr->y1,
00532 buttonPtr->x1+buttonPtr->width-1, buttonPtr->y1+buttonPtr->height-1);
00533
00534 image_interface.put_front( buttonPtr->x1, buttonPtr->y1, buttonPtr->file_name );
00535
00536 mouse.show_area();
00537
00538 sys.blt_virtual_buf();
00539 }
00540 break;
00541 }
00542 }
00543
00544
00545
00546 if( i==DEMO_BUTTON_COUNT ) {
00547 if( highlightButton != 0 ) {
00548 vga.blt_buf(0,0,VGA_WIDTH-1,VGA_HEIGHT-1);
00549 highlightButton = 0;
00550 }
00551 }
00552 }
00553 }
00554
00555
00556
00557
00558
00559 static void open_http(char* shortcutFilename, char* httpAddr) {
00560 if( !m.is_file_exist(shortcutFilename) ) {
00561
00562
00563 String str = "[InternetShortcut]\r\nURL=";
00564 str += httpAddr;
00565 str += "\r\n";
00566
00567 File urlFile;
00568 urlFile.file_create(shortcutFilename);
00569 urlFile.file_write( str, strlen(str) );
00570 urlFile.file_close();
00571 }
00572
00573 if( m.is_file_exist(shortcutFilename) ) {
00574 sys.deinit();
00575 HINSTANCE hinst = ShellExecute( sys.main_hwnd, "open", shortcutFilename, NULL, "", SW_SHOWNORMAL );
00576 }
00577 }
00578
00579
00580 #endif
00581
00582
00583 static int is_math_exception( DWORD exceptionCode, _EXCEPTION_POINTERS *exceptInfo ) {
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 switch( exceptionCode ) {
00594 case EXCEPTION_FLT_INVALID_OPERATION:
00595 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
00596 case EXCEPTION_INT_DIVIDE_BY_ZERO:
00597 case EXCEPTION_INT_OVERFLOW: {
00598 void *pAddr = exceptInfo->ExceptionRecord->ExceptionAddress;
00599 err.msg( "math exception at %p", pAddr );
00600 }
00601 return EXCEPTION_EXECUTE_HANDLER;
00602 default:
00603 return EXCEPTION_CONTINUE_SEARCH;
00604 }
00605 }