diff --git a/sc2/ChangeLog b/sc2/ChangeLog index a07ae34ef..ff72708c4 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.2: +- Optimized DCQ to be much smaller and faster - Added stat data in outfit screen (use --font=pc) - from Nic - Added fixed introx.mod, from fOSSiL - Fixed Orz .mod file, from fOSSiL diff --git a/sc2/src/sc2code/libs/graphics/drawcmd.h b/sc2/src/sc2code/libs/graphics/drawcmd.h index b009852de..55d898c70 100644 --- a/sc2/src/sc2code/libs/graphics/drawcmd.h +++ b/sc2/src/sc2code/libs/graphics/drawcmd.h @@ -37,27 +37,92 @@ enum TFB_DRAWCOMMANDTYPE_SENDSIGNAL, }; -typedef struct tfb_drawcommand +typedef struct tfb_dc_line +{ + int x1, y1, x2, y2; + int r, g, b; + SCREEN destBuffer; +} TFB_DrawCommand_Line; + +typedef struct tfb_dc_rect +{ + int x, y, w, h; + int r, g, b; + SCREEN destBuffer; +} TFB_DrawCommand_Rect; + +typedef struct tfb_dc_img { - int Type; - int x; - int y; - int w; - int h; TFB_ImageStruct *image; - int r; - int g; - int b; - int index; - int BlendNumerator; - int BlendDenominator; - DWORD thread; - SCREEN srcBuffer; + int x, y; + int BlendNumerator, BlendDenominator; SCREEN destBuffer; BOOLEAN UsePalette; BOOLEAN UseScaling; -} TFB_DrawCommand; +} TFB_DrawCommand_Image; +typedef struct tfb_dc_filledimg +{ + TFB_ImageStruct *image; + int x, y; + int r, g, b; + int BlendNumerator, BlendDenominator; + SCREEN destBuffer; + BOOLEAN UseScaling; +} TFB_DrawCommand_FilledImage; + +typedef struct tfb_dc_copy +{ + int x, y, w, h; + int BlendNumerator, BlendDenominator; + SCREEN srcBuffer, destBuffer; +} TFB_DrawCommand_Copy; + +typedef struct tfb_dc_copyimg +{ + TFB_ImageStruct *image; + int x, y, w, h; + int BlendNumerator, BlendDenominator; + SCREEN srcBuffer; +} TFB_DrawCommand_CopyToImage; + +typedef struct tfb_dc_scissor +{ + int x, y, w, h; +} TFB_DrawCommand_Scissor; + +typedef struct tfb_dc_setpal +{ + int index; + int r, g, b; +} TFB_DrawCommand_SetPalette; + +typedef struct tfb_dc_delimg +{ + TFB_ImageStruct *image; +} TFB_DrawCommand_DeleteImage; + +typedef struct tfb_dc_signal +{ + DWORD thread; +} TFB_DrawCommand_SendSignal; + +typedef struct tfb_drawcommand +{ + int Type; + union { + TFB_DrawCommand_Line line; + TFB_DrawCommand_Rect rect; + TFB_DrawCommand_Image image; + TFB_DrawCommand_FilledImage filledimage; + TFB_DrawCommand_Copy copy; + TFB_DrawCommand_CopyToImage copytoimage; + TFB_DrawCommand_Scissor scissor; + TFB_DrawCommand_SetPalette setpalette; + TFB_DrawCommand_DeleteImage deleteimage; + TFB_DrawCommand_SendSignal sendsignal; + } data; +} TFB_DrawCommand; // Queue Stuff diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.c b/sc2/src/sc2code/libs/graphics/gfx_common.c index d81752f21..b2085d3ec 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.c +++ b/sc2/src/sc2code/libs/graphics/gfx_common.c @@ -51,19 +51,14 @@ TFB_Draw_Line (int x1, int y1, int x2, int y2, int r, int g, int b, SCREEN dest) TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_LINE; - DC.x = x1; - DC.y = y1; - DC.w = x2; - DC.h = y2; - DC.r = r; - DC.g = g; - DC.b = b; - DC.image = 0; - DC.UsePalette = FALSE; - DC.destBuffer = dest; - - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.line.x1 = x1; + DC.data.line.y1 = y1; + DC.data.line.x2 = x2; + DC.data.line.y2 = y2; + DC.data.line.r = r; + DC.data.line.g = g; + DC.data.line.b = b; + DC.data.line.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); } @@ -83,19 +78,14 @@ TFB_Draw_Rect (PRECT rect, int r, int g, int b, SCREEN dest) } DC.Type = TFB_DRAWCOMMANDTYPE_RECTANGLE; - DC.x = rect->corner.x; - DC.y = rect->corner.y; - DC.w = rect->extent.width; - DC.h = rect->extent.height; - DC.r = r; - DC.g = g; - DC.b = b; - DC.image = 0; - DC.UsePalette = FALSE; - DC.destBuffer = dest; - - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.rect.x = rect->corner.x; + DC.data.rect.y = rect->corner.y; + DC.data.rect.w = rect->extent.width; + DC.data.rect.h = rect->extent.height; + DC.data.rect.r = r; + DC.data.rect.g = g; + DC.data.rect.b = b; + DC.data.rect.destBuffer = dest; TFB_EnqueueDrawCommand (&DC); } @@ -106,13 +96,10 @@ TFB_Draw_SetPalette (int index, int r, int g, int b) TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_SETPALETTE; - DC.r = r; - DC.g = g; - DC.b = b; - DC.index = index; - DC.image = 0; - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.setpalette.r = r; + DC.data.setpalette.g = g; + DC.data.setpalette.b = b; + DC.data.setpalette.index = index; TFB_EnqueueDrawCommand (&DC); } @@ -140,10 +127,10 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_IMAGE; - DC.image = img; - DC.x = x; - DC.y = y; - DC.UseScaling = scaled; + DC.data.image.image = img; + DC.data.image.x = x; + DC.data.image.y = y; + DC.data.image.UseScaling = scaled; if (palette != NULL) { @@ -165,17 +152,17 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette } } // if (changed) { fprintf (stderr, "Actually changing palette! "); } - DC.UsePalette = TRUE; + DC.data.image.UsePalette = TRUE; } else { Lock_DCQ (1); - DC.UsePalette = FALSE; + DC.data.image.UsePalette = FALSE; } - DC.destBuffer = dest; - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.image.destBuffer = dest; + DC.data.image.BlendNumerator = BlendNumerator; + DC.data.image.BlendDenominator = BlendDenominator; TFB_EnqueueDrawCommand (&DC); Unlock_DCQ (); @@ -187,16 +174,16 @@ TFB_Draw_FilledImage (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, int r, TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_FILLEDIMAGE; - DC.image = img; - DC.x = x; - DC.y = y; - DC.UseScaling = scaled; - DC.r = r; - DC.g = g; - DC.b = b; - DC.destBuffer = dest; - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.filledimage.image = img; + DC.data.filledimage.x = x; + DC.data.filledimage.y = y; + DC.data.filledimage.UseScaling = scaled; + DC.data.filledimage.r = r; + DC.data.filledimage.g = g; + DC.data.filledimage.b = b; + DC.data.filledimage.destBuffer = dest; + DC.data.filledimage.BlendNumerator = BlendNumerator; + DC.data.filledimage.BlendDenominator = BlendDenominator; TFB_EnqueueDrawCommand (&DC); } @@ -207,15 +194,15 @@ TFB_Draw_CopyToImage (TFB_ImageStruct *img, PRECT lpRect, SCREEN src) TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_COPYTOIMAGE; - DC.x = lpRect->corner.x; - DC.y = lpRect->corner.y; - DC.w = lpRect->extent.width; - DC.h = lpRect->extent.height; - DC.image = img; - DC.srcBuffer = src; + DC.data.copytoimage.x = lpRect->corner.x; + DC.data.copytoimage.y = lpRect->corner.y; + DC.data.copytoimage.w = lpRect->extent.width; + DC.data.copytoimage.h = lpRect->extent.height; + DC.data.copytoimage.image = img; + DC.data.copytoimage.srcBuffer = src; - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.copytoimage.BlendNumerator = BlendNumerator; + DC.data.copytoimage.BlendDenominator = BlendDenominator; TFB_EnqueueDrawCommand (&DC); } @@ -235,16 +222,15 @@ TFB_Draw_Copy (PRECT r, SCREEN src, SCREEN dest) } DC.Type = TFB_DRAWCOMMANDTYPE_COPY; - DC.x = r->corner.x; - DC.y = r->corner.y; - DC.w = r->extent.width; - DC.h = r->extent.height; - DC.image = 0; - DC.srcBuffer = src; - DC.destBuffer = dest; + DC.data.copy.x = r->corner.x; + DC.data.copy.y = r->corner.y; + DC.data.copy.w = r->extent.width; + DC.data.copy.h = r->extent.height; + DC.data.copy.srcBuffer = src; + DC.data.copy.destBuffer = dest; - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; + DC.data.copy.BlendNumerator = BlendNumerator; + DC.data.copy.BlendDenominator = BlendDenominator; TFB_EnqueueDrawCommand (&DC); } @@ -257,7 +243,7 @@ TFB_Draw_DeleteImage (TFB_ImageStruct *img) TFB_DrawCommand DC; DC.Type = TFB_DRAWCOMMANDTYPE_DELETEIMAGE; - DC.image = img; + DC.data.deleteimage.image = img; TFB_EnqueueDrawCommand (&DC); } @@ -268,7 +254,6 @@ TFB_Draw_WaitForSignal (void) { TFB_DrawCommand DrawCommand; DrawCommand.Type = TFB_DRAWCOMMANDTYPE_SENDSIGNAL; - DrawCommand.image = 0; // We need to lock the mutex before enqueueing the DC to prevent races LockSignalMutex (); Lock_DCQ (1); diff --git a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c index dd7f979de..1ff373c08 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c +++ b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c @@ -231,7 +231,9 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) return; } - DrawCommand->thread = CurrentThreadID (); + if (DrawCommand->Type == TFB_DRAWCOMMANDTYPE_SENDSIGNAL) + DrawCommand->data.sendsignal.thread = CurrentThreadID (); + if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYTOIMAGE && TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) { @@ -250,20 +252,19 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) scissor_rect = _pCurContext->ClipRect; - DC.Type = scissor_rect.extent.width - ? (DC.x = scissor_rect.corner.x, - DC.y=scissor_rect.corner.y, - DC.w=scissor_rect.extent.width, - DC.h=scissor_rect.extent.height), - TFB_DRAWCOMMANDTYPE_SCISSORENABLE - : TFB_DRAWCOMMANDTYPE_SCISSORDISABLE; - - DC.image = 0; - DC.UsePalette = FALSE; - - DC.BlendNumerator = BlendNumerator; - DC.BlendDenominator = BlendDenominator; - + if (scissor_rect.extent.width) + { + DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORENABLE; + DC.data.scissor.x = scissor_rect.corner.x; + DC.data.scissor.y = scissor_rect.corner.y; + DC.data.scissor.w = scissor_rect.extent.width; + DC.data.scissor.h = scissor_rect.extent.height; + } + else + { + DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORDISABLE; + } + TFB_EnqueueDrawCommand(&DC); } } diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index 0ed70b2bc..061e14bfb 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -525,7 +525,6 @@ TFB_FlushGraphics () // Only call from main thread!! while (!done) { TFB_DrawCommand DC; - TFB_Image *DC_image; if (!TFB_DrawCommandQueue_Pop (&DC)) { @@ -542,24 +541,20 @@ TFB_FlushGraphics () // Only call from main thread!! Lock_DCQ (-1); } - DC_image = (TFB_Image*) DC.image; - if (DC_image) - LockMutex (DC_image->mutex); - switch (DC.Type) { case TFB_DRAWCOMMANDTYPE_SETPALETTE: { - int index = DC.index; + int index = DC.data.setpalette.index; if (index < 0 || index > 255) { fprintf(stderr, "DCQ panic: Tried to set palette #%i", index); } else { - palette[index].r = DC.r & 0xFF; - palette[index].g = DC.g & 0xFF; - palette[index].b = DC.b & 0xFF; + palette[index].r = DC.data.setpalette.r & 0xFF; + palette[index].g = DC.data.setpalette.g & 0xFF; + palette[index].b = DC.data.setpalette.b & 0xFF; } break; } @@ -567,25 +562,26 @@ TFB_FlushGraphics () // Only call from main thread!! { SDL_Rect targetRect; SDL_Surface *surf; - + TFB_Image *DC_image = (TFB_Image *)DC.data.image.image; if (DC_image == 0) { - fprintf (stderr, "TFB_FlushGraphics(): error, DC_image == 0\n"); + fprintf (stderr, "DCQ ERROR: IMAGE passed null image ptr\n"); break; } - targetRect.x = DC.x; - targetRect.y = DC.y; + LockMutex (DC_image->mutex); + targetRect.x = DC.data.image.x; + targetRect.y = DC.data.image.y; - if (DC.UseScaling) + if (DC.data.image.UseScaling) surf = DC_image->ScaledImg; else surf = DC_image->NormalImg; if (surf->format->palette) { - if (DC.UsePalette) + if (DC.data.image.UsePalette) { SDL_SetColors (surf, (SDL_Color*)palette, 0, 256); } @@ -595,7 +591,8 @@ TFB_FlushGraphics () // Only call from main thread!! } } - TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator); + TFB_BlitSurface(surf, NULL, SDL_Screens[DC.data.image.destBuffer], &targetRect, DC.data.image.BlendNumerator, DC.data.image.BlendDenominator); + UnlockMutex (DC_image->mutex); break; } @@ -605,32 +602,33 @@ TFB_FlushGraphics () // Only call from main thread!! SDL_Surface *surf; int i; TFB_Palette pal[256]; - + TFB_Image *DC_image = (TFB_Image *)DC.data.filledimage.image; if (DC_image == 0) { - fprintf (stderr, "TFB_FlushGraphics(): error, DC_image == 0\n"); + fprintf (stderr, "DCQ ERROR: FILLEDIMAGE passed null image ptr\n"); break; } + LockMutex (DC_image->mutex); - targetRect.x = DC.x; - targetRect.y = DC.y; + targetRect.x = DC.data.filledimage.x; + targetRect.y = DC.data.filledimage.y; - if (DC.UseScaling) + if (DC.data.filledimage.UseScaling) surf = DC_image->ScaledImg; else surf = DC_image->NormalImg; for (i = 0; i < 256; i++) { - pal[i].r = DC.r; - pal[i].g = DC.g; - pal[i].b = DC.b; + pal[i].r = DC.data.filledimage.r; + pal[i].g = DC.data.filledimage.g; + pal[i].b = DC.data.filledimage.b; } SDL_SetColors (surf, (SDL_Color*)pal, 0, 256); - TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator); - + TFB_BlitSurface(surf, NULL, SDL_Screens[DC.data.filledimage.destBuffer], &targetRect, DC.data.filledimage.BlendNumerator, DC.data.filledimage.BlendDenominator); + UnlockMutex (DC_image->mutex); break; } case TFB_DRAWCOMMANDTYPE_LINE: @@ -641,15 +639,20 @@ TFB_FlushGraphics () // Only call from main thread!! PutPixelFn screen_plot; screen_plot = putpixel_for (SDL_Screen); - color = SDL_MapRGB (SDL_Screen->format, DC.r, DC.g, DC.b); + color = SDL_MapRGB (SDL_Screen->format, DC.data.line.r, DC.data.line.g, DC.data.line.b); - x1 = DC.x; - x2 = DC.w; - y1 = DC.y; - y2 = DC.h; + x1 = DC.data.line.x1; + x2 = DC.data.line.x2; + y1 = DC.data.line.y1; + y2 = DC.data.line.y2; SDL_GetClipRect(SDL_Screen, &r); + /* Danger, Will Robinson! This code + looks VERY suspicious. It will end + up changing the slope of the + line! */ + if (x1 < r.x) x1 = r.x; else if (x1 > r.x + r.w) @@ -670,30 +673,30 @@ TFB_FlushGraphics () // Only call from main thread!! else if (y2 > r.y + r.h) y2 = r.y + r.h; - SDL_LockSurface (SDL_Screens[DC.destBuffer]); - line (x1, y1, x2, y2, color, screen_plot, SDL_Screens[DC.destBuffer]); - SDL_UnlockSurface (SDL_Screens[DC.destBuffer]); + SDL_LockSurface (SDL_Screens[DC.data.line.destBuffer]); + line (x1, y1, x2, y2, color, screen_plot, SDL_Screens[DC.data.line.destBuffer]); + SDL_UnlockSurface (SDL_Screens[DC.data.line.destBuffer]); break; } case TFB_DRAWCOMMANDTYPE_RECTANGLE: { SDL_Rect r; - r.x = DC.x; - r.y = DC.y; - r.w = DC.w; - r.h = DC.h; + r.x = DC.data.rect.x; + r.y = DC.data.rect.y; + r.w = DC.data.rect.w; + r.h = DC.data.rect.h; - SDL_FillRect(SDL_Screens[DC.destBuffer], &r, SDL_MapRGB(SDL_Screen->format, DC.r, DC.g, DC.b)); + SDL_FillRect(SDL_Screens[DC.data.rect.destBuffer], &r, SDL_MapRGB(SDL_Screen->format, DC.data.rect.r, DC.data.rect.g, DC.data.rect.b)); break; } case TFB_DRAWCOMMANDTYPE_SCISSORENABLE: { SDL_Rect r; - r.x = DC.x; - r.y = DC.y; - r.w = DC.w; - r.h = DC.h; + r.x = DC.data.scissor.x; + r.y = DC.data.scissor.y; + r.w = DC.data.scissor.w; + r.h = DC.data.scissor.h; SDL_SetClipRect(SDL_Screen, &r); break; @@ -704,50 +707,67 @@ TFB_FlushGraphics () // Only call from main thread!! case TFB_DRAWCOMMANDTYPE_COPYTOIMAGE: { SDL_Rect src, dest; - src.x = dest.x = DC.x; - src.y = dest.y = DC.y; - src.w = DC.w; - src.h = DC.h; + TFB_Image *DC_image = (TFB_Image *)DC.data.copytoimage.image; + + if (DC_image == 0) + { + fprintf (stderr, "DCQ ERROR: COPYTOIMAGE passed null image ptr\n"); + break; + } + LockMutex (DC_image->mutex); + + src.x = dest.x = DC.data.copytoimage.x; + src.y = dest.y = DC.data.copytoimage.y; + src.w = DC.data.copytoimage.w; + src.h = DC.data.copytoimage.h; dest.x = 0; dest.y = 0; - TFB_BlitSurface(SDL_Screens[DC.srcBuffer], &src, DC_image->NormalImg, &dest, DC.BlendNumerator, DC.BlendDenominator); + TFB_BlitSurface(SDL_Screens[DC.data.copytoimage.srcBuffer], &src, DC_image->NormalImg, &dest, DC.data.copytoimage.BlendNumerator, DC.data.copytoimage.BlendDenominator); + UnlockMutex (DC_image->mutex); break; } case TFB_DRAWCOMMANDTYPE_COPY: { SDL_Rect src, dest; - src.x = dest.x = DC.x; - src.y = dest.y = DC.y; - src.w = DC.w; - src.h = DC.h; + src.x = dest.x = DC.data.copy.x; + src.y = dest.y = DC.data.copy.y; + src.w = DC.data.copy.w; + src.h = DC.data.copy.h; - TFB_BlitSurface(SDL_Screens[DC.srcBuffer], &src, SDL_Screens[DC.destBuffer], &dest, DC.BlendNumerator, DC.BlendDenominator); + TFB_BlitSurface(SDL_Screens[DC.data.copy.srcBuffer], &src, SDL_Screens[DC.data.copy.destBuffer], &dest, DC.data.copy.BlendNumerator, DC.data.copy.BlendDenominator); break; } case TFB_DRAWCOMMANDTYPE_DELETEIMAGE: - SDL_FreeSurface (DC_image->NormalImg); + { + TFB_Image *DC_image = (TFB_Image *)DC.data.deleteimage.image; + + if (DC_image == 0) + { + fprintf (stderr, "DCQ ERROR: DELETEIMAGE passed null image ptr\n"); + break; + } + LockMutex (DC_image->mutex); + + SDL_FreeSurface (DC_image->NormalImg); - if (DC_image->ScaledImg) { - //fprintf (stderr, "DELETEIMAGE to ScaledImg %x, size %d %d\n",DC_image->ScaledImg,DC_image->ScaledImg->w,DC_image->ScaledImg->h); - SDL_FreeSurface (DC_image->ScaledImg); + if (DC_image->ScaledImg) { + SDL_FreeSurface (DC_image->ScaledImg); + } + + if (DC_image->Palette) + HFree (DC_image->Palette); + + UnlockMutex (DC_image->mutex); + DestroyMutex (DC_image->mutex); + + HFree (DC_image); + break; } - - if (DC_image->Palette) - HFree (DC_image->Palette); - - UnlockMutex (DC_image->mutex); - DestroyMutex (DC_image->mutex); - - HFree (DC_image); - DC_image = 0; - break; case TFB_DRAWCOMMANDTYPE_SENDSIGNAL: - SignalThread (DC.thread); + SignalThread (DC.data.sendsignal.thread); break; } - if (DC_image) - UnlockMutex (DC_image->mutex); } if (livelock_deterrence)