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

Password:

Omatrix.cpp Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Omatrix.cpp

Go to the documentation of this file.
00001 //Filename    : OMATRIX.CPP
00002 //Description : Object road direction turn, derived by World, Chain class
00003 
00004 #include <ALL.H>
00005 #include <COLCODE.H>
00006 #include <OVGA.H>
00007 #include <OMOUSE.H>
00008 #include <OTERRAIN.H>
00009 #include <OPLANT.H>
00010 #include <OROAD.H>
00011 #include <OSYS.H>
00012 #include <OFONT.H>
00013 #include <OFIRM.H>
00014 #include <OSPRITE.H>
00015 //## fred 990511 #include <OSPRITEA.H>
00016 #include <OWORLD.H>
00017 #include <OBITMAPW.H>
00018 #include <OMATRIX.H>
00019 #include <OBLOB2W.H>
00020 
00021 #define DRAW_SPRITE_ON_MAPVIEW  0                 // 0 or 1
00022 
00023 //-------- Declare static functions ---------//
00024 
00025 static int sort_disp_function( const void *a, const void *b );
00026 
00027 //------- Define static class member functions ----//
00028 
00029 DynArray Matrix::disp_sort_array(sizeof(DisplaySort),100);
00030 
00031 //----------- Begin of function Matrix::Matrix ----------//
00033 Matrix::Matrix() {
00034     save_image_buf = NULL;
00035 }
00036 
00037 //------------- End of function Matrix::Matrix -----------//
00038 
00039 //----------- Begin of function Matrix::~Matrix ----------//
00041 Matrix::~Matrix() {
00042     if( save_image_buf ) {
00043         mem_del( save_image_buf );
00044         save_image_buf = NULL;
00045     }
00046     disp_sort_array.zap(0);                         // 0-don't resize the array, keep its current size
00047 }
00048 
00049 //------------- End of function Matrix::~Matrix -----------//
00050 
00051 //----------- Begin of function Matrix::init ----------//
00068 void Matrix::init(int winX1, int winY1, int winX2, int winY2,
00069                   int locWidth, int locHeight, Location* locMatrix,
00070                   int maxXLoc, int maxYLoc, int zoomLevel, char saveImageFlag) {
00071     win_x1 = winX1;                                 // bitmap area only
00072     win_y1 = winY1;
00073     win_x2 = winX2;
00074     win_y2 = winY2;
00075 
00076     win_width  = win_x2 - win_x1 + 1;
00077     win_height = win_y2 - win_y1 + 1;
00078 
00079     loc_width  = locWidth;
00080     loc_height = locHeight;
00081 
00082     //---------------------------------------------//
00083 
00084     loc_matrix = locMatrix;
00085 
00086     max_x_loc = maxXLoc;
00087     max_y_loc = maxYLoc;
00088 
00089     disp_x_loc = win_width/loc_width;
00090 
00091     if( disp_x_loc > max_x_loc )
00092         disp_x_loc = max_x_loc;
00093 
00094     disp_y_loc = win_height/(loc_height/2);
00095 
00096     if( disp_y_loc > max_y_loc )
00097         disp_y_loc = max_y_loc;
00098 
00099     set_top_loc( MAX_WORLD_X_LOC/2, 0 );
00100 
00101     zoom_level = zoomLevel;
00102 
00103     //----- allocate a buffer for saving the image ------//
00104 
00105     save_image_flag = saveImageFlag;
00106 
00107     if( saveImageFlag ) {
00108         if ( save_image_buf )
00109             mem_del( save_image_buf );
00110 
00111         save_image_buf = (short *)mem_add( BitmapW::size(win_width, win_height) );
00112         is_image_buf_latest = 0;
00113     }
00114 }
00115 
00116 //------------- End of function Matrix::init -----------//
00117 
00118 //----------- Begin of function Matrix::set_top_loc ----------//
00120 void Matrix::set_top_loc(int topXLoc, int topYLoc) {
00121     top_x_loc = topXLoc;
00122     top_y_loc = topYLoc;
00123 
00124     loc_to_abs_center_left( abs_top_x, abs_top_y, top_x_loc, top_y_loc );
00125 }
00126 
00127 //------------- End of function Matrix::set_top_loc -----------//
00128 
00129 //--------- Begin of function Matrix::loc_to_abs_top_left --------//
00138 void Matrix::loc_to_abs_top_left(int& absX, int& absY, int locX, int locY) {
00139     absX = (loc_width/2) * (locX + locY);
00140     absY = (max_y_loc/2*loc_height) + (loc_height/2) * (-locX + locY -1);
00141 }
00142 
00143 //--------- End of function Matrix::loc_to_abs_top_left --------//
00144 
00145 //--------- Begin of function Matrix::loc_to_abs_center_left --------//
00154 void Matrix::loc_to_abs_center_left(int& absX, int& absY, int locX, int locY) {
00155     absX = (loc_width/2) * (locX + locY);
00156     absY = (max_y_loc/2*loc_height) + (loc_height/2) * (-locX + locY);
00157 }
00158 
00159 //--------- End of function Matrix::loc_to_abs_center_left --------//
00160 
00161 //--------- Begin of function Matrix::loc_to_abs_bottom_right --------//
00170 void Matrix::loc_to_abs_bottom_right(int& absX, int& absY, int locX, int locY) {
00171     absX = (loc_width/2) * (locX + locY + 3) - 1;
00172     absY = (max_y_loc/2*loc_height) + (loc_height/2) * (-locX + locY + 1) - 1;
00173 }
00174 
00175 //--------- End of function Matrix::loc_to_abs_bottom_right --------//
00176 
00177 //--------- Begin of function Matrix::abs_to_loc --------//
00184 void Matrix::abs_to_loc(int& locX, int& locY, int absX, int absY) {
00185     locX = (absX/loc_width) - (absY/loc_height) + (max_y_loc/2);
00186     locY = (absX/loc_width) + (absY/loc_height) - (max_y_loc/2);
00187 }
00188 
00189 //--------- End of function Matrix::abs_to_loc --------//
00190 
00191 //---------- Begin of function Matrix::draw_all ------------//
00193 void Matrix::draw_all() {
00194     //--- if the saved image buffer contains the latest image, use it instead redrawing a new one ---//
00195 
00196     if( save_image_flag && is_image_buf_latest ) {
00197         vga_back.put_bitmapW( win_x1, win_y1, save_image_buf );
00198     }
00199     else {
00200         draw_objects();
00201 
00202         if( save_image_flag ) {
00203             vga_back.read_bitmapW( win_x1, win_y1, win_x2, win_y2, save_image_buf );
00204             is_image_buf_latest = 1;
00205         }
00206     }
00207 
00208 #if(GAME_VERSION>=200)
00209     draw_text();
00210 #endif
00211 }
00212 
00213 //------------ End of function Matrix::draw_all ------------//
00214 
00215 //---------- Begin of function Matrix::draw_update ------------//
00217 void Matrix::draw_update() {
00218 }
00219 
00220 //------------ End of function Matrix::draw_update ------------//
00221 
00222 //--------- Begin of function Matrix::draw_objects ---------//
00224 void Matrix::draw_objects() {
00225     //----- get the location of the zoom area ------//
00226 
00227     enum { DRAW_OUTSIDE = 12 };
00228 
00229     int     xLocRow = top_x_loc;
00230     int     yLocRow = top_y_loc-DRAW_OUTSIDE;
00231     DisplaySort displaySort;
00232 
00233     disp_sort_array.zap(0);                         // 0-don't resize the array, keep its current size
00234 
00235     for( int yCount=disp_y_loc+DRAW_OUTSIDE*2 ; yCount>0 ; yCount-- ) {
00236         //------ process a diagonal row -----//
00237 
00238         int xLoc = xLocRow;
00239         int yLoc = yLocRow;
00240 
00241         for( int xCount=disp_x_loc+DRAW_OUTSIDE ; xCount>0 ; xCount--, xLoc++, yLoc++ ) {
00242             if( xLoc < 0 || xLoc >= MAX_WORLD_X_LOC ||
00243                 yLoc < 0 || yLoc >= MAX_WORLD_Y_LOC ) {
00244                 continue;
00245             }
00246 
00247             //------------------------------------------//
00248 
00249             Location* locPtr = world.get_loc(xLoc, yLoc);
00250 
00251             //-------- if there is a road ---------//
00252 
00253             if( locPtr->is_road() ) {                   // roads do not have height, so they can be drawn at the bottommost layer
00254                 int absX, absY;
00255 
00256                 loc_to_abs_top_left( absX, absY, xLoc, yLoc );
00257 
00258                 char* bmpPtr = road_res[locPtr->road_id()]->bitmap_ptr[zoom_level];
00259 
00260                 draw_bitmap( absX, absY-loc_height/2, bmpPtr );
00261 
00262                 //continue;
00263             }
00264 
00265             else if( locPtr->is_road_sub() ) {
00266                 //continue;
00267             }
00268 
00269             //------ draw terrain --------//
00270 
00271             else {
00272                 draw_terrain(xLoc, yLoc, locPtr->terrain_id);
00273             }
00274 
00275             //-------- there is a firm on the location --------//
00276 
00277             if( locPtr->is_firm() ) {
00278                 displaySort.object_type  = OBJECT_FIRM;
00279                 displaySort.object_recno = locPtr->firm_recno();
00280 
00281                 Firm* firmPtr = firm_array[locPtr->firm_recno()];
00282 
00283                 //##chwg1207
00284                 displaySort.loc_x = firmPtr->loc_x1;
00285                 displaySort.loc_y = firmPtr->loc_y2;
00286 
00287                 if( xLoc==firmPtr->loc_x1 &&              // only link in the top-left Location to prevent repeated adding of firms
00288                     yLoc==firmPtr->loc_y1 ) {                 // since size of firm can be greater than 1x1
00289                     disp_sort_array.linkin(&displaySort);
00290                 }
00291                 if( xLoc==firmPtr->loc_x2 &&              // only link in the top-right Location to prevent repeated adding of firms
00292                     yLoc==firmPtr->loc_y1 ) {                 // since size of firm can be greater than 1x1
00293                     disp_sort_array.linkin(&displaySort);
00294                 }
00295             }
00296 
00297             //-------- there is a plant ---------//
00298 
00299             else if( locPtr->is_plant() ) {
00300                 err_when( locPtr->is_walkable() );
00301                 displaySort.object_type = OBJECT_PLANT;
00302 
00303                 int absX, absY;
00304 
00305                 loc_to_abs_top_left( absX, absY, xLoc, yLoc );
00306 
00307                 displaySort.bitmap_ptr = plant_res[locPtr->plant_id()]->bitmap_ptr[zoom_level];
00308 
00309                 int bmpWidth  = *((short*)displaySort.bitmap_ptr);
00310                 int bmpHeight = *( ((short*)displaySort.bitmap_ptr)+1 );
00311 
00312                 //##chwg1207
00313                 displaySort.abs_x1 = absX + (int)loc_width  * locPtr->plant_inner_x() / 100;
00314                 // plant_inner_x() returns a relative offset as a percentage ranging from 0 to 100
00315                 displaySort.abs_y2 = absY + (int)loc_height * locPtr->plant_inner_y() / 100;
00316                 displaySort.abs_y1 = displaySort.abs_y2 - bmpHeight + 1;
00317                 displaySort.loc_x = xLoc;
00318                 displaySort.loc_y = yLoc;
00319                 disp_sort_array.linkin(&displaySort);
00320             }
00321             //-------- there is a unit ---------//
00322             /*  //## fred 990511
00323                 else if( locPtr->has_sprite()
00324                 && ( zoom_level != ZOOM_SMALL || DRAW_SPRITE_ON_MAPVIEW ) )
00325                 {
00326                 // memset(&displaySort, 0, sizeof(displaySort));
00327                 Sprite *spritePtr = sprite_array[locPtr->sprite_recno()];
00328                 spritePtr->update_abs_pos();            // update its absolute position
00329 
00330                 //##chwg1207
00331                 displaySort.object_type  = OBJECT_SPRITE;
00332                 displaySort.object_recno = locPtr->sprite_recno();
00333                 displaySort.loc_x = xLoc;
00334                 displaySort.loc_y = yLoc;
00335                 disp_sort_array.linkin(&displaySort);
00336                 }
00337             */
00338             //## fred 990511
00339         }                                             // for x
00340 
00341         //------- next row --------//
00342 
00343         if( yCount%2==0 )                             // alternately
00344             yLocRow++;
00345         else
00346             xLocRow--;
00347     }                                               // for y
00348 
00349     //---------- quicksort the array -----------//
00350 
00351     //  disp_sort_array.quick_sort( sort_disp_function );
00352     //  Quick sort cannot check all objects! Use bubble sort instead.
00353     disp_sort_array.bubble_sort( sort_disp_function );
00354 
00355     //------------ draw unit path and objects ---------------//
00356 
00357     draw_objects_now( &disp_sort_array );
00358 
00359     //----------- clean up the array ----------//
00360 
00361     //  disp_sort_array.zap(0);         // 0-don't resize the array, keep its current size
00362 }
00363 
00364 //----------- End of function Matrix::draw_objects -----------//
00365 
00366 //---------- Begin of function Matrix::draw_objects_now -----------//
00368 void Matrix::draw_objects_now(DynArray* dispSortArray) {
00369     DisplaySort *displaySortPtr;
00370     Firm      *firmPtr;
00371     //## fred 990511    Sprite          *spritePtr;
00372     int       i, dispCount = dispSortArray->size();
00373 
00374     for( i=1 ; i<=dispCount ; i++ ) {
00375         if( i%10==1 )
00376             sys.yield();
00377 
00378         displaySortPtr = (DisplaySort*) dispSortArray->get(i);
00379 
00380         switch(displaySortPtr->object_type) {
00381         case OBJECT_FIRM:
00382             firmPtr = firm_array[displaySortPtr->object_recno];
00383             firmPtr->draw(this);
00384             break;
00385 
00386         case OBJECT_PLANT:
00387             // shift the tree to left with 44 pixels for the space of shadow.
00388             draw_bitmap( displaySortPtr->abs_x1-44, displaySortPtr->abs_y1-2, displaySortPtr->bitmap_ptr );
00389             break;
00390 
00391         case OBJECT_SPRITE:
00392             err_here();                               //## fred 990511
00393             //## fred 990511    spritePtr = sprite_array[displaySortPtr->object_recno];
00394             //## fred 990511    spritePtr->draw(this);
00395             break;
00396         }
00397     }
00398 }
00399 
00400 //----------- End of function Matrix::draw_objects_now ------------//
00401 
00402 //---------- Begin of function Matrix::draw_terrain -----------//
00404 void Matrix::draw_terrain(int xLoc, int yLoc, int terrainId) {
00405     int absX, absY;
00406 
00407     loc_to_abs_top_left( absX, absY, xLoc, yLoc );
00408 
00409     draw_bitmap( absX, absY, terrain_res[terrainId]->bitmap_ptr[zoom_level] );
00410 }
00411 
00412 //----------- End of function Matrix::draw_terrain ------------//
00413 
00414 //---------- Begin of function Matrix::draw_plant -----------//
00416 void Matrix::draw_plant(int xLoc, int yLoc, int terrainId) {
00417     int absX, absY;
00418 
00419     loc_to_abs_top_left( absX, absY, xLoc, yLoc );
00420 
00421     draw_bitmap( absX, absY, terrain_res[terrainId]->bitmap_ptr[zoom_level] );
00422 }
00423 
00424 //----------- End of function Matrix::draw_plant ------------//
00425 
00426 //--------- Begin of function Matrix::draw_bitmap ----------//
00430 void Matrix::draw_bitmap(int absX, int absY, char* bmpPtr) {
00431     int zoomLevel = zoom_level;
00432     int bmpWidth  = *( (short*)bmpPtr );
00433     int bmpHeight = *( ((short*)bmpPtr)+1 );
00434 
00435     int x1 = absX - abs_top_x;
00436 
00437     if( x1 <= -bmpWidth || x1 >= win_width )        // out of the view area, not even a slight part of it appears in the view area
00438         return;
00439 
00440     int y1 = absY - abs_top_y;
00441 
00442     if( y1 <= -bmpHeight || y1 >= win_height )
00443         return;
00444 
00445     int x2 = absX + bmpWidth - 1 - abs_top_x;
00446     int y2 = absY + bmpHeight - 1 - abs_top_y;
00447 
00448     if( x2 < 0 || y2 < 0 )
00449         return;
00450     if( x2 <= x1 || y2 <=y1 )
00451         return;
00452 
00453     //---- only portion of the sprite is inside the view area ------//
00454 
00455     if( x1 < 0 || x2 >= win_width || y1 < 0 || y2 >= win_height ) {
00456         vga_back.put_bitmap_area_trans_decompress( x1+win_x1, y1+win_y1, bmpPtr,
00457                                                    max(0,x1)-x1, max(0,y1)-y1, min(win_width-1,x2)-x1, min(win_height-1,y2)-y1 );
00458     }
00459 
00460     //---- the whole sprite is inside the view area ------//
00461 
00462     else {
00463         vga_back.put_bitmap_trans_decompress( x1+win_x1, y1+win_y1, bmpPtr );
00464     }
00465 }
00466 
00467 //--------- End of function Matrix::draw_bitmap -----------//
00468 
00469 //---------- Begin of function Location::set_firm ------------//
00471 void Location::set_firm(int firmRecno) {
00472     loc_type    = LOC_IS_FIRM;
00473     cargo_recno = firmRecno;
00474     set_walkable_off();
00475 }
00476 
00477 //------------ End of function Location::set_firm ------------//
00478 
00479 //---------- Begin of function Location::remove_firm ------------//
00481 void Location::remove_firm() {
00482     err_when( !is_firm() );
00483 
00484     loc_type = LOC_EMPTY;
00485     cargo_recno = 0;
00486 }
00487 
00488 //------------ End of function Location::remove_firm ------------//
00489 
00490 //---------- Begin of function Location::set_plant ------------//
00492 void Location::set_plant(int plantId, int offsetX, int offsetY) {
00493     loc_type    = LOC_IS_PLANT;
00494 
00495     extra_para  = plantId;
00496     cargo_recno = (offsetY<<8) + offsetX;
00497     set_walkable_off();
00498 }
00499 
00500 //------------ End of function Location::set_plant ------------//
00501 
00502 //---------- Begin of function Location::remove_plant ------------//
00504 void Location::remove_plant() {
00505     err_when( !is_plant() );
00506 
00507     loc_type  = LOC_EMPTY;
00508     cargo_recno = 0;
00509     extra_para  = 0;
00510 }
00511 
00512 //------------ End of function Location::remove_plant ------------//
00513 
00514 //---------- Begin of function Location::set_road ------------//
00516 void Location::set_road(int roadId) {
00517     loc_type    = LOC_IS_ROAD;
00518     cargo_recno = roadId;
00519     extra_para  = 0;
00520     set_walkable_on();
00521 }
00522 
00523 //------------ End of function Location::set_road ------------//
00524 
00525 //---------- Begin of function Location::remove_road ------------//
00527 void Location::remove_road() {
00528     err_when( !is_road() );
00529 
00530     loc_type  = LOC_EMPTY;
00531     cargo_recno = 0;
00532     extra_para  = 0;
00533     set_walkable_off();
00534 }
00535 
00536 //------------ End of function Location::remove_road ------------//
00537 
00538 //---------- Begin of function Location::set_sprite ------------//
00540 void Location::set_sprite(int recno) {
00541     err_when(recno <=0);
00542     err_when( !is_walkable() );
00543     //loc_type          = LOC_IS_SPRITE;
00544     extra_para  = recno;
00545 }
00546 
00547 //------------ End of function Location::set_sprite ------------//
00548 
00549 //---------- Begin of function Location::remove_sprite ------------//
00551 void Location::remove_sprite() {
00552     err_when( !has_sprite() );
00553     //loc_type = LOC_EMPTY;
00554     extra_para  = 0;
00555 }
00556 
00557 //------------ End of function Location::remove_sprite ------------//
00558 
00559 #if(GAME_VERSION>=200)
00560 //---------- Begin of function Matrix::draw_text -----------//
00562 void Matrix::draw_text() {
00563     // nothing
00564 }
00565 
00566 //---------- End of function Matrix::draw_text -----------//
00567 #endif
00568 
00569 //---------- Begin of function Matrix::put_center_text -----------//
00574 void Matrix::put_center_text(int x, int y, char* str) {
00575     str = translate.process(str);
00576 
00577     // #### begin Gilbert 12/09/2001 ######//
00578     /*
00579       const TEMP_BUFFER_SIZE = 0x2000;
00580       char      tempBuffer[TEMP_BUFFER_SIZE];
00581 
00582       short w = font_news.text_width(str);
00583       short h = font_news.max_font_height;
00584 
00585       if( w * h + 2*sizeof(short) <= TEMP_BUFFER_SIZE )
00586       {
00587       char *bufferPtr = tempBuffer;
00588 
00589       *(short *)bufferPtr = w;
00590       bufferPtr += sizeof(short);
00591 
00592       *(short *)bufferPtr = h;
00593       bufferPtr += sizeof(short);
00594 
00595       memset( bufferPtr, TRANSPARENT_CODE, w * h );
00596       font_news.put_to_buffer(bufferPtr, w, 0, 0, str);
00597 
00598       //-- test clipping against win_x1, win_y1, win_x2, win_y2 --//
00599 
00600       int x1 = x - abs_top_x - w / 2 ;
00601       int x2 = x1 + w - 1;
00602       int y1 = y - abs_top_y - h / 2;
00603       int y2 = y1 + h - 1;
00604 
00605       if( x1 < win_x2 && x2 >= 0 && y1 < win_height && y2 >= 0 )
00606       {
00607       if( x1 < 0 || x2 >= win_width || y1 < 0 || y2 >= win_height )
00608       {
00609       vga_back.put_bitmap_area_trans( x1+win_x1, y1+win_y1, tempBuffer,
00610       max(0,x1)-x1, max(0,y1)-y1, min(win_width-1,x2)-x1, min(win_height-1,y2)-y1);
00611       }
00612       else
00613       {
00614       vga_back.put_bitmap_trans( x1+win_x1, y1+win_y1, tempBuffer );
00615       }
00616       }
00617       }
00618     */
00619 
00620     static Blob2DW tempBuffer;
00621 
00622     const gap = 2;                                  // outside area for drawing black background
00623     short w = font_fblack.text_width(str) + 2*gap;
00624     short h = font_fblack.max_font_height + 2*gap;
00625 
00626     //-- test clipping against win_x1, win_y1, win_x2, win_y2 --//
00627 
00628     int x1 = x - abs_top_x - w / 2 ;
00629     int x2 = x1 + w - 1;
00630     int y1 = y - abs_top_y - h / 2;
00631     int y2 = y1 + h - 1;
00632 
00633     if( x1 < win_width && x2 >= 0 && y1 < win_height && y2 >= 0 ) {
00634         tempBuffer.clear();
00635         tempBuffer.resize(-w/2, -h/2, w, h);
00636         // black background
00637         tempBuffer.fill_area(-w/2, -h/2, -w/2+w-1, -h/2+h-1, (short)vga_back.translate_color(V_BLACK), 0);
00638 
00639         font_fblack.put_to_bufferW(tempBuffer.ptr->get_ptr(gap,gap), tempBuffer.buf_true_pitch(), 0, 0, str);
00640 
00641         if( x1 < 0 || x2 >= win_width || y1 < 0 || y2 >= win_height ) {
00642             vga_back.put_bitmapW_area_trans( x1+win_x1, y1+win_y1, tempBuffer.bitmap_ptr(),
00643                                              max(0,x1)-x1, max(0,y1)-y1, min(win_width-1,x2)-x1, min(win_height-1,y2)-y1);
00644         }
00645         else {
00646             vga_back.put_bitmapW_trans( x1+win_x1, y1+win_y1, tempBuffer.bitmap_ptr() );
00647         }
00648     }
00649 }
00650 
00651 //----------- End of function Matrix::put_center_text ------------//
00652 
00653 //------ Begin of function sort_disp_function ------//
00655 static int sort_disp_function( const void *a, const void *b ) {
00656     //##chwg1207
00657     if (((DisplaySort*)a)->loc_y<((DisplaySort*)b)->loc_y)
00658         return -1;
00659     if (((DisplaySort*)a)->loc_x>((DisplaySort*)b)->loc_x)
00660         return -1;
00661     return 1;
00662 }
00663 
00664 //------- End of function sort_disp_function ------//

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