#include "mungal4.h" #pragma hdrstop #include "l4vb8.h" //######################################################################## //######################### Video8BitBuffered ########################### //######################################################################## // //NOTE: the application assumes that the origin is in the lower left // corner of the display, and all parameters passed to these routines // use the application's coordinate system. // // All of the methods here convert these values to the SCREEN // coordinate system, with the origin in the UPPER LEFT corner of // the display. // //=================================================================== // Creator //=================================================================== Video8BitBuffered::Video8BitBuffered(int x, int y): GraphicsDisplay(x, y) { # if defined(DEBUG) Tell( "Video8BitBuffered::Video8BitBuffered()\n" ); # endif int i; Word *line_dest; pixelBuffer = new PixelMap8(x, y); Check(pixelBuffer); Verify(pixelBuffer->Data.MapPointer != NULL); Register_Object(pixelBuffer); createdPixelmap = True; height = y; width = x; maximumY = height-1; maximumX = width-1; //--------------------------------------------------------- // Create 'changedLine' array //--------------------------------------------------------- changedLine = new Word[height]; Register_Pointer(changedLine); valid = True; //--------------------------------------------------------- // Clear the 'changedLine' array //--------------------------------------------------------- for (i=height,line_dest=changedLine; i>0; --i,++line_dest) { *line_dest = 0; } Check_Fpu(); } Video8BitBuffered::Video8BitBuffered(PixelMap8 *pixel_buffer): GraphicsDisplay(pixel_buffer->Data.Size.x, pixel_buffer->Data.Size.y) { # if defined(DEBUG) Tell( "Video8BitBuffered::Video8BitBuffered()\n" ); # endif int i; Word *line_dest; pixelBuffer = pixel_buffer; Verify(pixelBuffer->Data.MapPointer != NULL); createdPixelmap = False; height = pixelBuffer->Data.Size.y; width = pixelBuffer->Data.Size.x; maximumY = height-1; maximumX = width-1; //--------------------------------------------------------- // Create 'changedLine' array //--------------------------------------------------------- changedLine = new Word[height]; Register_Pointer(changedLine); # if defined(DEBUG) Tell("changedLine=" << changedLine << "\n"); # endif if (changedLine == NULL) { # if defined(DEBUG) Tell("INVALID!\n"); # endif valid = False; return; } else { Register_Pointer(changedLine); valid = True; } //--------------------------------------------------------- // Clear the 'changedLine' array //--------------------------------------------------------- for (i=height,line_dest=changedLine; i>0; --i,++line_dest) { *line_dest = 0; } Check_Fpu(); } //=================================================================== // Destructor //=================================================================== Video8BitBuffered::~Video8BitBuffered() { Check(this); if (changedLine != NULL) { Unregister_Pointer(changedLine); delete changedLine; changedLine = NULL; } if (createdPixelmap) { if (pixelBuffer != NULL) { Check(pixelBuffer); Unregister_Object(pixelBuffer); delete pixelBuffer; pixelBuffer = NULL; } createdPixelmap = False; } Check_Fpu(); } //=================================================================== // TestInstance //=================================================================== Logical Video8BitBuffered::TestInstance() const { return True; } //=================================================================== // ShowInstance //=================================================================== void Video8BitBuffered::ShowInstance( char *indent ) { std::cout << indent << "Video8BitBuffered:\n"; Check(this); char temp[80]; Str_Copy(temp,indent, 80); Str_Cat(temp,"...", 80); std::cout << temp << "width =" << width << "\n"; std::cout << temp << "height =" << height << "\n"; std::cout << temp << "maximumX =" << maximumX << "\n"; std::cout << temp << "maximumY =" << maximumY << "\n"; std::cout << temp << "changedLine=" << changedLine << "\n"; pixelBuffer->ShowInstance(temp); GraphicsDisplay::ShowInstance(temp); Check_Fpu(); } //=================================================================== // buildDestPointer //=================================================================== void Video8BitBuffered::buildDestPointer( int screenX, int screenY, Byte **pixel_pointer ) { Verify(valid); Verify(pixel_pointer != NULL); Verify(screenX >= 0); Verify(screenX < width); Verify(screenY >= 0); Verify(screenY < height); *pixel_pointer = pixelBuffer->Data.MapPointer + screenX + (screenY * width); Verify(*pixel_pointer >= pixelBuffer->Data.MapPointer); Verify(*pixel_pointer < &pixelBuffer->Data.MapPointer[height*width]); Check_Fpu(); } #define LEFT_DEST(pointer) --pointer #define RIGHT_DEST(pointer) ++pointer #define UP_DEST(pointer) pointer -= width #define DOWN_DEST(pointer) pointer += width #define LEFT_SOURCE(pointer,map) --pointer #define RIGHT_SOURCE(pointer,map) ++pointer #define UP_SOURCE(pointer,map) pointer -= map->Data.Size.x #define DOWN_SOURCE(pointer,map) pointer += map->Data.Size.x #define LEFT_BITMAP(pointer,bits) \ bits <<= 1; \ if (bits == 0) { --pointer; bits=0x0001; } #define RIGHT_BITMAP(pointer, bits) \ bits >>= 1; \ if (bits == 0) { ++pointer; bits=0x8000; } #define UP_BITMAP(pointer,map) pointer -= map->Data.WidthInWords #define DOWN_BITMAP(pointer,map) pointer += map->Data.WidthInWords #define WRITEPIXEL(dest_pointer, operation, color) \ switch (operation) \ {\ case GraphicsDisplay::Replace:\ *dest_pointer = (Byte)color;\ break;\ case GraphicsDisplay::And:\ *dest_pointer &= (Byte) color;\ break;\ case GraphicsDisplay::Or:\ *dest_pointer |= (Byte) color;\ break;\ case GraphicsDisplay::Xor:\ *dest_pointer ^= (Byte) color;\ break;\ } //=================================================================== // MarkChangedLines //=================================================================== // // Inputs are in DISPLAY COORDINATES, i.e., (0,0) in top left corner! // void Video8BitBuffered::MarkChangedLines( int start, int stop ) { # if defined(DEBUG) Tell( "Video8BitBuffered::MarkChangedLines(" << start << ", " << stop << ")\n" ); # endif Check(this); if (start > stop) { # if defined(DEBUG) Tell("MarkChangedLines FLIPPING\n"); # endif int temp; temp = start; start = stop; stop = temp; } Verify(start >= 0); Verify(start <= maximumY); Verify(stop >= 0); Verify(stop <= maximumY); ++changedLine[start]; // // Always include at least one line // if (stop < maximumY) { --changedLine[stop+1]; } Check_Fpu(); } //=================================================================== // DrawPoint //=================================================================== void Video8BitBuffered::DrawPoint( int color, int /*bitmask*/, Enumeration operation, int x, int y ) { Check(this); Verify(x >= bounds.bottomLeft.x); Verify(x <= bounds.topRight.x); Verify(y >= bounds.bottomLeft.y); Verify(y <= bounds.topRight.y); Byte *dest_pointer; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y = maximumY - y; # if defined(DEBUG) Tell("x=" << x << ", y=" << y << "\n"); # endif Verify(x >= 0); Verify(x < width); Verify(y >= 0); Verify(y < height); //--------------------------------------------------------- // Update changedLine array //--------------------------------------------------------- MarkChangedLines(y, y); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Create pointers //--------------------------------------------------------- buildDestPointer( x, y, &dest_pointer ); //--------------------------------------------------------- // Write the point //--------------------------------------------------------- WRITEPIXEL(dest_pointer, operation, color) Check_Fpu(); } //=================================================================== // DrawLine //=================================================================== void Video8BitBuffered::DrawLine( int color, int /*bitmask*/, Enumeration operation, int x1, int y1, int x2, int y2, Logical include_last_pixel ) { # if defined(DEBUG) Tell( "Video8BitBuffered::DrawLine(" << color << ", " << bitmask << ", " << operation << ", " << x1 << "," << y1 << "," << x2 << "," << y2 << ", " << include_last_pixel << "\n" ); # endif Check(this); Verify(x1 >= bounds.bottomLeft.x); Verify(x1 <= bounds.topRight.x); Verify(y1 >= bounds.bottomLeft.y); Verify(y1 <= bounds.topRight.y); Verify(x2 >= bounds.bottomLeft.x); Verify(x2 <= bounds.topRight.x); Verify(y2 >= bounds.bottomLeft.y); Verify(y2 <= bounds.topRight.y); enum { negative_delta_x = 1, negative_delta_y = 2, delta_y_greater = 0, delta_x_greater = 4 }; long length, rate, accumulator; int octant, delta_x, delta_y; Byte *dest_pointer; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Route to DrawPoint if single pixel //--------------------------------------------------------- if (x1 == x2 && y1 == y2) { if (include_last_pixel) { DrawPoint(color, 0 /*bitmask*/, operation, x1, y1); } Check_Fpu(); return; } //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y1 = maximumY - y1; y2 = maximumY - y2; //--------------------------------------------------------- // Ensure that endpoints are legitimate //--------------------------------------------------------- Verify(x1 >= 0); Verify(x1 < width); Verify(x2 >= 0); Verify(x2 < width); Verify(y1 >= 0); Verify(y1 < height); Verify(y2 >= 0); Verify(y2 < height); # if defined(DEBUG) Tell( "Transformed coordinates=" << x1 << "," << y1 << "," << x2 << "," << y2 << "\n" ); # endif //--------------------------------------------------------- // Update changedLine array //--------------------------------------------------------- MarkChangedLines(y1, y2); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Determine which octant to use //--------------------------------------------------------- octant = 0; delta_x = x2 - x1; if (delta_x < 0) { # if defined(DEBUG) Tell("negative dx\n"); # endif octant |= negative_delta_x; delta_x = - delta_x; } delta_y = y2 - y1; if (delta_y < 0) { # if defined(DEBUG) Tell("negative dy\n"); # endif octant |= negative_delta_y; delta_y = - delta_y; } if (delta_x > delta_y) { # if defined(DEBUG) Tell("dx > dy\n"); # endif octant |= delta_x_greater; } # if defined(DEBUG) Tell( "dx=" << delta_x << ", dy=" << delta_y << ", octant=" << octant << ", color=" << color << "\n" ); # endif //--------------------------------------------------------- // Prepare to draw line //--------------------------------------------------------- buildDestPointer( x1, y1, &dest_pointer ); accumulator = 1024L; // preset accumulator to 1/2 full //--------------------------------------------------------- // Draw the line! //--------------------------------------------------------- switch (octant) { case delta_y_greater: //------------------------------------- // delta y greater // positive delta x // positive delta y // // + // \ & // \ & //------------------------------------- length = delta_y; if (!include_last_pixel) { -- length; } Verify(delta_y > 0); rate = (delta_x*2048L)/delta_y; # if defined(DEBUG) Tell( "delta_y_greater, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif DOWN_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; RIGHT_DEST(dest_pointer); } } break; case delta_y_greater+negative_delta_x: //------------------------------------- // delta y greater // negative delta x // positive delta y // // + // / // / //------------------------------------- length = delta_y; if (!include_last_pixel) { -- length; } rate = (delta_x*2048L)/delta_y; # if defined(DEBUG) Tell( "delta_y_greater+negative_delta_x, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif DOWN_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; LEFT_DEST(dest_pointer); } } break; case delta_y_greater+negative_delta_y: //------------------------------------- // delta y greater // positive delta x // negative delta y // // / // / // + //------------------------------------- length = delta_y; if (!include_last_pixel) { -- length; } rate = (delta_x*2048L)/delta_y; # if defined(DEBUG) Tell( "delta_y_greater+negative_delta_y, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif UP_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; RIGHT_DEST(dest_pointer); } } break; case delta_y_greater+negative_delta_x+negative_delta_y: //------------------------------------- // delta y greater // negative delta x // negative delta y // // \ & // \ & // + //------------------------------------- length = delta_y; if (!include_last_pixel) { -- length; } rate = (delta_x*2048L)/delta_y; # if defined(DEBUG) Tell( "delta_y_greater+negative_delta_x+negative_delta_y, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif UP_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; LEFT_DEST(dest_pointer); } } break; case delta_x_greater: //------------------------------------- // delta x greater // positive delta x // positive delta y // // +---___ // // //------------------------------------- length = delta_x; if (!include_last_pixel) { -- length; } rate = (delta_y*2048L)/delta_x; # if defined(DEBUG) Tell( "delta_x_greater, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif RIGHT_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; DOWN_DEST(dest_pointer); } } break; case delta_x_greater+negative_delta_x: //------------------------------------- // delta x greater // negative delta x // positive delta y // // ___---+ // // //------------------------------------- length = delta_x; if (!include_last_pixel) { -- length; } rate = (delta_y*2048L)/delta_x; # if defined(DEBUG) Tell( "delta_x_greater+negative_delta_x, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif LEFT_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; DOWN_DEST(dest_pointer); } } break; case delta_x_greater+negative_delta_y: //------------------------------------- // delta x greater // positive delta x // negative delta y // // +___--- // // //------------------------------------- length = delta_x; if (!include_last_pixel) { -- length; } rate = (delta_y*2048L)/delta_x; # if defined(DEBUG) Tell( "delta_x_greater+negative_delta_y, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif RIGHT_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; UP_DEST(dest_pointer); } } break; case delta_x_greater+negative_delta_x+negative_delta_y: //------------------------------------- // delta x greater // negative delta x // negative delta y // // ---___+ // // //------------------------------------- length = delta_x; if (!include_last_pixel) { -- length; } rate = (delta_y*2048L)/delta_x; # if defined(DEBUG) Tell( "delta_x_greater+negative_delta_x+negative_delta_y, length=" << length << ", rate=" << rate << "\n" ); # endif Verify(rate >= 0L); Verify(rate <= 2048L); Verify(length >= 0); for ( ; length>0; --length) { WRITEPIXEL(dest_pointer, operation, color) # if defined(DEBUG) Tell( length << ", accum=" << accumulator << ", dest_pointer=" << dest_pointer << "\n" ); # endif LEFT_DEST(dest_pointer); accumulator += rate; if (accumulator > 2048L) { # if defined(DEBUG) Tell("OVERFLOW\n"); # endif accumulator -= 2048L; UP_DEST(dest_pointer); } } break; } Check_Fpu(); } //=================================================================== // DrawFilledRectangle //=================================================================== void Video8BitBuffered::DrawFilledRectangle( int color, int /*bitmask*/, Enumeration operation, int x1, int y1, int x2, int y2 ) { # if defined(DEBUG) Tell("Video8BitBuffered::DrawFilledRectangle(" << color << ", " << std::hex << bitmask << ", " << std::dec << operation << ", " << x1 << ", " << y1 << ", " << x2 << ", " << y2 << ", " << ")\n"); # endif Check(this); Verify(x1 >= bounds.bottomLeft.x); Verify(x1 <= bounds.topRight.x); Verify(y1 >= bounds.bottomLeft.y); Verify(y1 <= bounds.topRight.y); Verify(x2 >= bounds.bottomLeft.x); Verify(x2 <= bounds.topRight.x); Verify(y2 >= bounds.bottomLeft.y); Verify(y2 <= bounds.topRight.y); Byte *dest_pointer; int x, dest_fixup, rect_width, rect_height; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y1 = maximumY - y1; y2 = maximumY - y2; //--------------------------------------------------------- // Ensure that rectangle is properly specified //--------------------------------------------------------- if (x2 < x1) { int temp; temp = x1; x1 = x2; x2 = temp; } if (y2 < y1) { int temp; temp = y1; y1 = y2; y2 = temp; } //--------------------------------------------------------- // Verify that values are legitimate //--------------------------------------------------------- Verify(pixelBuffer->Data.MapPointer != NULL); Verify(x1 >= 0); Verify(x1 <= x2); Verify(x2 < width); Verify(y1 >= 0); Verify(y1 <= y2); Verify(y2 < height); //--------------------------------------------------------- // Update changedLine array //--------------------------------------------------------- MarkChangedLines(y1, y2); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Prepare to fill //--------------------------------------------------------- # if defined(DEBUG) Tell( "x1=" << x1 << ", " << "y1=" << y1 << "\n" << "x2=" << x2 << ", " << "y2=" << y2 << "\n" << std::flush ); # endif buildDestPointer(x1, y1, &dest_pointer); rect_height = y2 - y1 + 1; rect_width = x2 - x1 + 1; dest_fixup = width - rect_width; # if defined(DEBUG) Tell( "rect_height=" << rect_height << "\n" << "rect_width=" << rect_width << "\n" << "dest_fixup=" << dest_fixup << "\n" << std::flush ); # endif //--------------------------------------------------------- // Fill the rectangle //--------------------------------------------------------- switch(operation) { case GraphicsDisplay::Replace: for( ; rect_height>0; --rect_height) { for(x=rect_width; x>0; --x) { *dest_pointer = (Byte) color; dest_pointer++; } dest_pointer += dest_fixup; } break; case GraphicsDisplay::And: for( ; rect_height>0; --rect_height) { for(x=rect_width; x>0; --x) { *dest_pointer++ &= (Byte) color; } dest_pointer += dest_fixup; } break; case GraphicsDisplay::Or: for( ; rect_height>0; --rect_height) { for(x=rect_width; x>0; --x) { *dest_pointer++ |= (Byte) color; } dest_pointer += dest_fixup; } break; case GraphicsDisplay::Xor: for( ; rect_height>0; --rect_height) { for(x=rect_width; x>0; --x) { *dest_pointer++ ^= (Byte) color; } dest_pointer += dest_fixup; } break; } Check_Fpu(); } void Video8BitBuffered::DrawText( int /*color*/, int /*bitmask*/, Enumeration /*operation*/, Logical /*opaque*/, int /*rotation*/, Enumeration /*fontNumber*/, Logical /*vertical*/, GraphicsDisplay::Justification /*justification*/, Rectangle2D */*clippingRectanglepointer*/, char */*stringPointer*/ ) { # if defined(DEBUG) Tell("Video8BitBuffered::DrawText()\n"); # endif Check(this); //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- Check_Fpu(); if (!valid) { return; } } //=================================================================== // DrawBitMap //=================================================================== void Video8BitBuffered::DrawBitMap( int color, int /*bitmask*/, Enumeration operation, int rotation, int x, int y, BitMap *bitmap, int sLeft, int sBottom, int sRight, int sTop ) { # if defined(DEBUG) Tell( "Video8BitBuffered::DrawBitMap(<" << x << ", " << y << ">,<" << sLeft << ", " << sBottom << ", " << sRight << ", " << sTop << ">" << ")\n" ); # endif Check(this); Verify(x >= bounds.bottomLeft.x); Verify(x <= bounds.topRight.x); Verify(y >= bounds.bottomLeft.y); Verify(y <= bounds.topRight.y); int map_width, map_height, map_max_y, bits, bit_test, first_bit_test; Word *source_pointer_begin, *source_pointer; Byte *dest_pointer_begin, *dest_pointer; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Ensure that source rectangle is properly specified //--------------------------------------------------------- Verify(bitmap != NULL); Verify(sLeft >= 0); Verify(sLeft <= sRight); Verify(sRight < bitmap->Data.Size.x); Verify(sBottom >= 0); Verify(sBottom <= sTop); Verify(sTop < bitmap->Data.Size.y); //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y = maximumY - y; map_max_y = bitmap->Data.Size.y-1; sTop = map_max_y - sTop; sBottom = map_max_y - sBottom; map_width = sRight - sLeft + 1; map_height = sBottom - sTop + 1; # if defined(DEBUG) Tell("x=" << x << ", y=" << y << "\n"); Tell("sTop=" << sTop << ", sBottom=" << sBottom << "\n"); Tell("map_width=" << map_width << ", map_height=" << map_height << "\n"); # endif Verify(map_width > 0); Verify(map_width <= bitmap->Data.Size.x); Verify(map_height > 0); Verify(map_height <= bitmap->Data.Size.y); Verify(x >= 0); Verify(x < width); Verify(y >= 0); Verify(y < height); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Prepare to draw bitmap //--------------------------------------------------------- Verify(pixelBuffer->Data.MapPointer != NULL); source_pointer_begin = bitmap->Data.MapPointer + (sLeft >> 4) + (sBottom * bitmap->Data.WidthInWords); first_bit_test = 1 << (15-(sLeft & 15)); buildDestPointer( x, y, &dest_pointer_begin ); switch (rotation) { default: //-------------------------------------------- // transparent bitmap, zero degrees // .-----. // | | // | | // Y | // #X----. //-------------------------------------------- # if defined(DEBUG) Tell("zero: xp=" << (x+map_width-1) << ", yp=" << (y-map_height+1) << "\n"); # endif Verify(x+map_width-1 >= 0); Verify(x+map_width-1 < width); Verify(y-map_height+1 >= 0); Verify(y-map_height+1 < height); MarkChangedLines(y-map_height+1, y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); UP_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { WRITEPIXEL(dest_pointer, operation, color) } RIGHT_DEST(dest_pointer); } } break; case 90: //-------------------------------------------- // Transparent bitmap, 90 degrees // #Y----. // X | // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell("90 xp=" << (x+map_height) << ", yp=" << (y+map_width) << "\n"); # endif Verify(x+map_height >= 0); Verify(x+map_height < width); Verify(y+map_width >= 0); Verify(y+map_width < height); MarkChangedLines(y, y+map_width); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); RIGHT_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { WRITEPIXEL(dest_pointer, operation, color) } DOWN_DEST(dest_pointer); } } break; case 180: //-------------------------------------------- // Transparent bitmap, 180 degrees // .----X# // | Y // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell("xp=" << (x-map_width+1) << ", yp=" << (y+map_height) << "\n"); # endif Verify(x-map_width+1 >= 0); Verify(x-map_width+1 < width); Verify(y+map_height >= 0); Verify(y+map_height < height); MarkChangedLines(y, y+map_height); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); DOWN_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { WRITEPIXEL(dest_pointer, operation, color) } LEFT_DEST(dest_pointer); } } break; case 270: //-------------------------------------------- // Transparent bitmap, 270 degrees // .-----. // | | // | X // | | // .--Y--# //-------------------------------------------- # if defined(DEBUG) Tell("xp=" << (x-map_height) << ", yp=" << (y-(map_width-1)) << "\n"); # endif Verify(x-map_height >= 0); Verify(x-map_height < width); Verify(y-(map_width-1) >= 0); Verify(y-(map_width-1) < height); MarkChangedLines(y-(map_width-1), y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); LEFT_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { WRITEPIXEL(dest_pointer, operation, color) } UP_DEST(dest_pointer); } } break; } Check_Fpu(); } //=================================================================== // DrawBitMapOpaque //=================================================================== void Video8BitBuffered::DrawBitMapOpaque( int foreground, int background, int /*bitmask*/, Enumeration operation, int rotation, int x, int y, BitMap *bitmap, int sLeft, int sBottom, int sRight, int sTop ) { # if defined(DEBUG) Tell( "Video8BitBuffered::DrawBitMapOpaque(<" << x << ", " << y << ">,<" << sLeft << ", " << sBottom << ", " << sRight << ", " << sTop << ">" << ")\n" ); # endif Check(this); Verify(x >= bounds.bottomLeft.x); Verify(x <= bounds.topRight.x); Verify(y >= bounds.bottomLeft.y); Verify(y <= bounds.topRight.y); int map_width, map_height, map_max_y, bits, bit_test, first_bit_test; Word *source_pointer_begin, *source_pointer; Byte *dest_pointer_begin, *dest_pointer; Byte color; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Ensure that source rectangle is properly specified //--------------------------------------------------------- Verify(bitmap != NULL); Verify(sLeft >= 0); Verify(sLeft <= sRight); Verify(sRight < bitmap->Data.Size.x); Verify(sBottom >= 0); Verify(sBottom <= sTop); Verify(sTop < bitmap->Data.Size.y); //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y = maximumY - y; map_max_y = bitmap->Data.Size.y-1; sTop = map_max_y - sTop; sBottom = map_max_y - sBottom; map_width = sRight - sLeft + 1; map_height = sBottom - sTop + 1; # if defined(DEBUG) Tell("x=" << x << ", y=" << y << "\n"); Tell("sTop=" << sTop << ", sBottom=" << sBottom << "\n"); Tell("map_width=" << map_width << ", map_height=" << map_height << "\n"); # endif Verify(map_width > 0); Verify(map_width <= bitmap->Data.Size.x); Verify(map_height > 0); Verify(map_height <= bitmap->Data.Size.y); Verify(x >= 0); Verify(x < width); Verify(y >= 0); Verify(y < height); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Prepare to draw bitmap //--------------------------------------------------------- Verify(pixelBuffer->Data.MapPointer != NULL); source_pointer_begin = bitmap->Data.MapPointer + (sLeft >> 4) + (sBottom * bitmap->Data.WidthInWords); first_bit_test = 1 << (15-(sLeft & 15)); buildDestPointer( x, y, &dest_pointer_begin ); switch (rotation) { default: //-------------------------------------------- // opaque bitmap, zero degrees // .-----. // | | // | | // Y | // #X----. //-------------------------------------------- # if defined(DEBUG) Tell("zero: xp=" << (x+map_width) << ", yp=" << (y-map_height+1) << "\n"); # endif Verify(x+map_width >= 0); Verify(x+map_width <= width); // HACK? <, or <=? Verify(y-map_height+1 >= 0); Verify(y-map_height+1 < height); MarkChangedLines(y-map_height+1, y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); UP_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { color = (Byte) foreground; } else { color = (Byte) background; } WRITEPIXEL(dest_pointer, operation, color) RIGHT_DEST(dest_pointer); } } break; case 90: //-------------------------------------------- // opaque bitmap, 90 degrees // #Y----. // X | // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell("90 xp=" << (x+map_height) << ", yp=" << (y+map_width) << "\n"); # endif Verify(x+map_height >= 0); Verify(x+map_height < width); Verify(y+map_width >= 0); Verify(y+map_width < height); MarkChangedLines(y, y+map_width); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); RIGHT_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { color = (Byte) foreground; } else { color = (Byte) background; } WRITEPIXEL(dest_pointer, operation, color) DOWN_DEST(dest_pointer); } } break; case 180: //-------------------------------------------- // opaque bitmap, 180 degrees // .----X# // | Y // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell("xp=" << (x-map_width+1) << ", yp=" << (y+map_height) << "\n"); # endif Verify(x-map_width+1 >= 0); Verify(x-map_width+1 < width); Verify(y+map_height >= 0); Verify(y+map_height < height); MarkChangedLines(y, y+map_height); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); DOWN_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { color = (Byte) foreground; } else { color = (Byte) background; } WRITEPIXEL(dest_pointer, operation, color) LEFT_DEST(dest_pointer); } } break; case 270: //-------------------------------------------- // opaque bitmap, 270 degrees // .-----. // | | // | X // | | // .--Y--# //-------------------------------------------- # if defined(DEBUG) Tell("xp=" << (x-map_height+1) << ", yp=" << (y-(map_width-1)) << "\n"); # endif Verify(x-map_height >= 0); Verify(x-map_height < width); Verify(y-(map_width-1) >= 0); Verify(y-(map_width-1) < height); MarkChangedLines(y-(map_width-1), y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_BITMAP(source_pointer_begin, bitmap); LEFT_DEST(dest_pointer_begin); bit_test = first_bit_test; bits = *source_pointer++; for(x=map_width; x>0; --x,bit_test>>=1) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); if (bit_test == 0) { bit_test = 0x8000; bits = *source_pointer++; } if (bits & bit_test) { color = (Byte) foreground; } else { color = (Byte) background; } WRITEPIXEL(dest_pointer, operation, color) UP_DEST(dest_pointer); } } break; } Check_Fpu(); } //=================================================================== // DrawPixelMap8 //=================================================================== void Video8BitBuffered::DrawPixelMap8( int */*translation_table*/, int /*bitmask*/, Enumeration operation, Logical opaque, int rotation, int x, int y, PixelMap8 *pixelmap, int sLeft, int sBottom, int sRight, int sTop ) { # if defined(DEBUG) Tell( "Video8BitBuffered::DrawPixelMap8(<" << x << ", " << y << ">,<" << sLeft << ", " << sBottom << ", " << sRight << ", " << sTop << ">" << ")\n" ); # endif Check(this); Verify(x >= bounds.bottomLeft.x); Verify(x <= bounds.topRight.x); Verify(y >= bounds.bottomLeft.y); Verify(y <= bounds.topRight.y); int map_width, map_height, map_max_y; Byte color, *source_pointer_begin, *source_pointer, *dest_pointer_begin, *dest_pointer; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Ensure that source rectangle is properly specified //--------------------------------------------------------- Verify(pixelmap != NULL); Verify(sLeft >= 0); Verify(sLeft <= sRight); Verify(sRight < pixelmap->Data.Size.x); Verify(sBottom >= 0); Verify(sBottom <= sTop); Verify(sTop < pixelmap->Data.Size.y); //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y = maximumY - y; map_max_y = pixelmap->Data.Size.y-1; sTop = map_max_y - sTop; sBottom = map_max_y - sBottom; map_width = sRight - sLeft + 1; map_height = sBottom - sTop + 1; # if defined(DEBUG) Tell("x=" << x << ", y=" << y << "\n"); Tell("sTop=" << sTop << ", sBottom=" << sBottom << "\n"); Tell("map_width=" << map_width << ", map_height=" << map_height << "\n"); # endif Verify(map_width > 0); Verify(map_width <= pixelmap->Data.Size.x); Verify(map_height > 0); Verify(map_height <= pixelmap->Data.Size.y); Verify(x >= 0); Verify(x < width); Verify(y >= 0); Verify(y < height); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Prepare to draw bitmap //--------------------------------------------------------- Verify(pixelBuffer->Data.MapPointer != NULL); source_pointer_begin = pixelmap->Data.MapPointer + sLeft + (sBottom * pixelmap->Data.Size.x); buildDestPointer( x, y, &dest_pointer_begin ); if (opaque) { switch (rotation) { default: //-------------------------------------------- // Opaque pixelmap, zero degrees // .-----. // | | // | | // Y | // #X----. //-------------------------------------------- # if defined(DEBUG) Tell( "Opaque zero: xp=" << (x+map_width) << ", yp=" << (y-map_height+1) << "\n" ); # endif Verify(x+map_width >= 0); Verify(x+map_width < width); Verify(y-map_height+1 >= 0); Verify(y-map_height+1 < height); MarkChangedLines(y-map_height+1, y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); UP_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT WRITEPIXEL(dest_pointer, operation, color) RIGHT_DEST(dest_pointer); } } break; case 90: //-------------------------------------------- // Opaque pixelmap, 90 degrees // #Y----. // X | // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "Opaque 90: xp=" << (x+map_height) << ", yp=" << (y+map_width) << "\n" ); # endif Verify(x+map_height >= 0); Verify(x+map_height < width); Verify(y+map_width >= 0); Verify(y+map_width < height); MarkChangedLines(y, y+map_width); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); RIGHT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT WRITEPIXEL(dest_pointer, operation, color) DOWN_DEST(dest_pointer); } } break; case 180: //-------------------------------------------- // Opaque pixelmap, 180 degrees // .----X# // | Y // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "Opaque 180: xp=" << (x-map_width+1) << ", yp=" << (y+map_height) << "\n" ); # endif Verify(x-map_width+1 >= 0); Verify(x-map_width+1 < width); Verify(y+map_height >= 0); Verify(y+map_height < height); MarkChangedLines(y, y+map_height); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); DOWN_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT WRITEPIXEL(dest_pointer, operation, color) LEFT_DEST(dest_pointer); } } break; case 270: //-------------------------------------------- // Opaque pixelmap, 270 degrees // .-----. // | | // | X // | | // .--Y--# //-------------------------------------------- # if defined(DEBUG) Tell("Opaque 270: x=" << x << ", y=" << y << "\n"); Tell("xp=" << x-map_height << ", yp=" << y-(map_width-1) << "\n"); # endif Verify(x-map_height >= 0); Verify(x-map_height < width); Verify(y-(map_width-1) >= 0); Verify(y-(map_width-1) < height); MarkChangedLines(y-(map_width-1), y); for(y=map_height ; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); LEFT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); color = *source_pointer++; //SOURCE_RIGHT WRITEPIXEL(dest_pointer, operation, color) UP_DEST(dest_pointer); } } break; } } else { switch (rotation) { default: //-------------------------------------------- // Transparent pixelmap, zero degrees // .-----. // | | // | | // Y | // #X----. //-------------------------------------------- # if defined(DEBUG) Tell( "transparent zero: xp=" << (x+map_width) << ", yp=" << (y-map_height+1) << "\n" ); # endif Verify(x+map_width >= 0); Verify(x+map_width < width); Verify(y-map_height+1 >= 0); Verify(y-map_height+1 < height); MarkChangedLines(y-map_height+1, y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); UP_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT if (color) { WRITEPIXEL(dest_pointer, operation, color) } RIGHT_DEST(dest_pointer); } } break; case 90: //-------------------------------------------- // Transparent pixelmap, 90 degrees // #Y----. // X | // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "transparent 90: xp=" << (x+map_height) << ", yp=" << (y+map_width) << "\n" ); # endif Verify(x+map_height >= 0); Verify(x+map_height < width); Verify(y+map_width >= 0); Verify(y+map_width < height); MarkChangedLines(y, y+map_width); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); RIGHT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT if (color) { WRITEPIXEL(dest_pointer, operation, color) } DOWN_DEST(dest_pointer); } } break; case 180: //-------------------------------------------- // Transparent pixelmap, 180 degrees // .----X# // | Y // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "transparent 180: xp=" << (x-map_width+1) << ", yp=" << (y+map_height) << "\n" ); # endif Verify(x-map_width+1 >= 0); Verify(x-map_width+1 < width); Verify(y+map_height >= 0); Verify(y+map_height < height); MarkChangedLines(y, y+map_height); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); DOWN_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { color = *source_pointer++; //SOURCE_RIGHT if (color) { WRITEPIXEL(dest_pointer, operation, color) } LEFT_DEST(dest_pointer); } } break; case 270: //-------------------------------------------- // Transparent pixelmap, 270 degrees // .-----. // | | // | X // | | // .--Y--# //-------------------------------------------- # if defined(DEBUG) Tell("transparent 270: x=" << x << ", y=" << y << "\n"); Tell("xp=" << x-map_height << ", yp=" << y-(map_width-1) << "\n"); # endif Verify(x-map_height >= 0); Verify(x-map_height < width); Verify(y-(map_width-1) >= 0); Verify(y-(map_width-1) < height); MarkChangedLines(y-(map_width-1), y); for(y=map_height ; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); LEFT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); color = *source_pointer++; //SOURCE_RIGHT if (color) { WRITEPIXEL(dest_pointer, operation, color) } UP_DEST(dest_pointer); } } break; } } Check_Fpu(); } //=================================================================== // DrawPixelMap8SingleColor //=================================================================== void Video8BitBuffered::DrawPixelMap8SingleColor( int color, int /*bitmask*/, Enumeration operation, int rotation, int x, int y, PixelMap8 *pixelmap, int sLeft, int sBottom, int sRight, int sTop ) { # if defined(DEBUG) Tell( "Video8BitBuffered::DrawPixelMap8SingleColor(<" << x << ", " << y << ">,<" << sLeft << ", " << sBottom << ", " << sRight << ", " << sTop << ">" << ")\n" ); # endif Check(this); Verify(x >= bounds.bottomLeft.x); Verify(x <= bounds.topRight.x); Verify(y >= bounds.bottomLeft.y); Verify(y <= bounds.topRight.y); int map_width, map_height, map_max_y; Byte source_data, *source_pointer_begin, *source_pointer, *dest_pointer_begin, *dest_pointer; //--------------------------------------------------------- // If pixelbuffer is invalid, do nothing //--------------------------------------------------------- if (!valid) { Check_Fpu(); return; } //--------------------------------------------------------- // Ensure that source rectangle is properly specified //--------------------------------------------------------- Verify(pixelmap != NULL); Verify(sLeft >= 0); Verify(sLeft <= sRight); Verify(sRight < pixelmap->Data.Size.x); Verify(sBottom >= 0); Verify(sBottom <= sTop); Verify(sTop < pixelmap->Data.Size.y); //--------------------------------------------------------- // Convert to screen co-ordinates //--------------------------------------------------------- y = maximumY - y; map_max_y = pixelmap->Data.Size.y-1; sTop = map_max_y - sTop; sBottom = map_max_y - sBottom; map_width = sRight - sLeft + 1; map_height = sBottom - sTop + 1; # if defined(DEBUG) Tell("x=" << x << ", y=" << y << "\n"); Tell("sTop=" << sTop << ", sBottom=" << sBottom << "\n"); Tell("map_width=" << map_width << ", map_height=" << map_height << "\n"); # endif Verify(map_width > 0); Verify(map_width <= pixelmap->Data.Size.x); Verify(map_height > 0); Verify(map_height <= pixelmap->Data.Size.y); Verify(x >= 0); Verify(x < width); Verify(y >= 0); Verify(y < height); //--------------------------------------------------------- // We really need inverse bitmap here //--------------------------------------------------------- // bitmask = ~bitmask; //--------------------------------------------------------- // Prepare to draw bitmap //--------------------------------------------------------- Verify(pixelBuffer->Data.MapPointer != NULL); source_pointer_begin = pixelmap->Data.MapPointer + sLeft + (sBottom * pixelmap->Data.Size.x); buildDestPointer( x, y, &dest_pointer_begin ); { switch (rotation) { default: //-------------------------------------------- // Single-color pixelmap, zero degrees // .-----. // | | // | | // Y | // #X----. //-------------------------------------------- # if defined(DEBUG) Tell( "Single-color zero: xp=" << (x+map_width) << ", yp=" << (y-map_height+1) << "\n" ); # endif Verify(x+map_width >= 0); Verify(x+map_width < width); Verify(y-map_height+1 >= 0); Verify(y-map_height+1 < height); MarkChangedLines(y-map_height+1, y); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); UP_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { source_data = *source_pointer++; //SOURCE_RIGHT if (source_data) { WRITEPIXEL(dest_pointer, operation, color) } RIGHT_DEST(dest_pointer); } } break; case 90: //-------------------------------------------- // Single-color pixelmap, 90 degrees // #Y----. // X | // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "Single-color 90: xp=" << (x+map_height) << ", yp=" << (y+map_width) << "\n" ); # endif Verify(x+map_height >= 0); Verify(x+map_height < width); Verify(y+map_width >= 0); Verify(y+map_width < height); MarkChangedLines(y, y+map_width); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); RIGHT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { source_data = *source_pointer++; //SOURCE_RIGHT if (source_data) { WRITEPIXEL(dest_pointer, operation, color) } DOWN_DEST(dest_pointer); } } break; case 180: //-------------------------------------------- // Single-color pixelmap, 180 degrees // .----X# // | Y // | | // | | // .-----. //-------------------------------------------- # if defined(DEBUG) Tell( "Single-color 180: xp=" << (x-map_width+1) << ", yp=" << (y+map_height) << "\n" ); # endif Verify(x-map_width+1 >= 0); Verify(x-map_width+1 < width); Verify(y+map_height >= 0); Verify(y+map_height < height); MarkChangedLines(y, y+map_height); for(y=map_height; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); DOWN_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { source_data = *source_pointer++; //SOURCE_RIGHT if (source_data) { WRITEPIXEL(dest_pointer, operation, color) } LEFT_DEST(dest_pointer); } } break; case 270: //-------------------------------------------- // Single-color pixelmap, 270 degrees // .-----. // | | // | X // | | // .--Y--# //-------------------------------------------- # if defined(DEBUG) Tell("Single-color 270: x=" << x << ", y=" << y << "\n"); Tell("xp=" << x-map_height << ", yp=" << y-map_width << "\n"); # endif Verify(x-map_height >= 0); Verify(x-map_height < width); Verify(y-map_width >= 0); Verify(y-map_width < height); MarkChangedLines(y-map_width, y); for(y=map_height ; y>0; --y) { source_pointer = source_pointer_begin; dest_pointer = dest_pointer_begin; UP_SOURCE(source_pointer_begin, pixelmap); LEFT_DEST(dest_pointer_begin); for(x=map_width; x>0; --x) { Verify(dest_pointer >= pixelBuffer->Data.MapPointer); Verify(dest_pointer < pixelBuffer->Data.MapPointer+ (width*height)); source_data = *source_pointer++; //SOURCE_RIGHT if (source_data) { WRITEPIXEL(dest_pointer, operation, color) } UP_DEST(dest_pointer); } } break; } } Check_Fpu(); } //######################################################################## //########################### L4BytePort ############################# //######################################################################## L4BytePort::L4BytePort( Video8BitBuffered *graphics_display, const char *name, int rotation ):GraphicsPort(graphics_display, name) { // // Save the base rotation value // baseRotation = rotation; // // Initialize conversion constants // maximumX = bounds.topRight.x - bounds.bottomLeft.x; maximumY = bounds.topRight.y - bounds.bottomLeft.y; // // Overwrite the GraphicsPort::bounds data with rotated values // for GraphView's benefit // switch(baseRotation) { default: // do nothing break; case 90: case 270: if (graphics_display != NULL) { Check(graphics_display); bounds.bottomLeft.x = graphics_display->bounds.bottomLeft.y; bounds.bottomLeft.y = graphics_display->bounds.bottomLeft.x; bounds.topRight.x = graphics_display->bounds.topRight.y; bounds.topRight.y = graphics_display->bounds.topRight.x; } break; } Check_Fpu(); } L4BytePort::~L4BytePort() { Check(this); Check_Fpu(); } Logical L4BytePort::TestInstance() const { return True; } void L4BytePort::ShowInstance(char *indent) { Check(this); std::cout << indent << "L4BytePort:\n"; char temp[80]; Str_Copy(temp,indent, 80); Str_Cat(temp,"...", 80); std::cout << temp << "baseRotation =" << baseRotation << "\n"; std::cout << temp << "maximumX =" << maximumX << "\n"; std::cout << temp << "maximumY =" << maximumY << "\n"; std::cout << temp << "bounds =" << bounds << "\n"; std::cout << std::flush; GraphicsPort::ShowInstance(temp); Check_Fpu(); } void L4BytePort::DrawPoint( int color, Enumeration operation, int x, int y ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); int xp, yp; convertPortPair(&xp, &yp, x, y); graphicsDisplay-> DrawPoint( color, 0, operation, xp+bounds.bottomLeft.x, yp+bounds.bottomLeft.y ); Check_Fpu(); } void L4BytePort::DrawLine( int color, Enumeration operation, int x1, int y1, int x2, int y2, Logical include_last_pixel ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); int x1p, y1p, x2p, y2p; convertPortPair(&x1p, &y1p, x1, y1); convertPortPair(&x2p, &y2p, x2, y2); graphicsDisplay-> DrawLine( color, 0, operation, x1p+bounds.bottomLeft.x, y1p+bounds.bottomLeft.y, x2p+bounds.bottomLeft.x, y2p+bounds.bottomLeft.y, include_last_pixel ); Check_Fpu(); } void L4BytePort::DrawFilledRectangle( int color, Enumeration operation, int x1, int y1, int x2, int y2 ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); int x1p, y1p, x2p, y2p; convertPortPair(&x1p, &y1p, x1, y1); convertPortPair(&x2p, &y2p, x2, y2); graphicsDisplay-> DrawFilledRectangle( color, 0, operation, x1p+bounds.bottomLeft.x, y1p+bounds.bottomLeft.y, x2p+bounds.bottomLeft.x, y2p+bounds.bottomLeft.y ); Check_Fpu(); } void L4BytePort::DrawText( int /*color*/, Enumeration /*operation*/, Logical /*opaque*/, int /*rotation*/, Enumeration /*fontNumber*/, Logical /*vertical*/, GraphicsDisplay::Justification /*justification*/, Rectangle2D */*clippingRectanglepointer*/, char */*stringPointer*/ ) { } void L4BytePort::DrawBitMap( int color, Enumeration operation, int rotation, int x, int y, BitMap *bitmap, int sLeft, int sBottom, int sRight, int sTop ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); if (bitmap == NULL) { Check_Fpu(); return; } if (bitmap->Data.MapPointer == NULL) { Check_Fpu(); return; } Check(bitmap); int xp, yp; convertPortPair(&xp, &yp, x, y); rotation += baseRotation; while (rotation < 0) { rotation += 360; } while (rotation >= 360) { rotation -= 360; } graphicsDisplay-> DrawBitMap( color, 0, operation, rotation, xp+bounds.bottomLeft.x, yp+bounds.bottomLeft.y, bitmap, sLeft, sBottom, sRight, sTop ); Check_Fpu(); } void L4BytePort::DrawBitMapOpaque( int color, int background, Enumeration operation, int rotation, int x, int y, BitMap *bitmap, int sLeft, int sBottom, int sRight, int sTop ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); if (bitmap == NULL) { Check_Fpu(); return; } if (bitmap->Data.MapPointer == NULL) { Check_Fpu(); return; } Check(bitmap); int xp, yp; convertPortPair(&xp, &yp, x, y); rotation += baseRotation; while (rotation < 0) { rotation += 360; } while (rotation >= 360) { rotation -= 360; } graphicsDisplay-> DrawBitMapOpaque( color, background, 0, operation, rotation, xp+bounds.bottomLeft.x, yp+bounds.bottomLeft.y, bitmap, sLeft, sBottom, sRight, sTop ); } void L4BytePort::DrawPixelMap8( Enumeration operation, Logical opaque, int rotation, int x, int y, PixelMap8 *pixelmap, int sLeft, int sBottom, int sRight, int sTop ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); if (pixelmap == NULL) { Check_Fpu(); return; } if (pixelmap->Data.MapPointer == NULL) { Check_Fpu(); return; } Check(pixelmap); int xp, yp; convertPortPair(&xp, &yp, x, y); rotation += baseRotation; while (rotation < 0) { rotation += 360; } while (rotation >= 360) { rotation -= 360; } graphicsDisplay-> DrawPixelMap8( NULL, 0, operation, opaque, rotation, xp+bounds.bottomLeft.x, yp+bounds.bottomLeft.y, pixelmap, sLeft, sBottom, sRight, sTop ); Check_Fpu(); } void L4BytePort::DrawPixelMap8SingleColor( int color, Enumeration operation, int rotation, int x, int y, PixelMap8 *pixelmap, int sLeft, int sBottom, int sRight, int sTop ) { Check(this); if (graphicsDisplay == NULL) { Check_Fpu(); return; } Check(graphicsDisplay); if (pixelmap == NULL) { Check_Fpu(); return; } if (pixelmap->Data.MapPointer == NULL) { Check_Fpu(); return; } Check(pixelmap); int xp, yp; convertPortPair(&xp, &yp, x, y); rotation += baseRotation; while (rotation < 0) { rotation += 360; } while (rotation >= 360) { rotation -= 360; } graphicsDisplay-> DrawPixelMap8SingleColor( color, 0, operation, rotation, xp+bounds.bottomLeft.x, yp+bounds.bottomLeft.y, pixelmap, sLeft, sBottom, sRight, sTop ); Check_Fpu(); } void L4BytePort::convertPortPair( int *xp, int *yp, int x, int y ) { switch(baseRotation) { default: *xp = x; *yp = y; break; case 90: *xp = y; *yp = maximumY - x; break; case 180: *xp = maximumX - x; *yp = maximumY - y; break; case 270: *xp = maximumX - y; *yp = x; break; } Check_Fpu(); }