@@ -39,6 +39,11 @@ static void drawFramerateBar(void);
3939#include < windows.h>
4040#include < io.h>
4141#include < time.h>
42+ #include < thread>
43+ #include < memory>
44+
45+ #define STB_IMAGE_WRITE_IMPLEMENTATION
46+ #include < stb_image_write.h>
4247
4348// USER INCLUDES //////////////////////////////////////////////////////////////
4449#include " Common/FramePacer.h"
@@ -3022,6 +3027,85 @@ void W3DDisplay::takeScreenShot(void)
30223027 TheInGameUI->message (TheGameText->fetch (" GUI:ScreenCapture" ), ufileName.str ());
30233028}
30243029
3030+ void W3DDisplay::takeScreenShotCompressed (void )
3031+ {
3032+ char leafname[256 ];
3033+ char pathname[1024 ];
3034+ static int frame_number = 1 ;
3035+
3036+ Bool done = false ;
3037+ while (!done) {
3038+ sprintf (leafname, " sshot%.3d.jpg" , frame_number++);
3039+ strcpy (pathname, TheGlobalData->getPath_UserData ().str ());
3040+ strlcat (pathname, leafname, ARRAY_SIZE (pathname));
3041+ if (_access (pathname, 0 ) == -1 )
3042+ done = true ;
3043+ }
3044+
3045+ SurfaceClass* surface = DX8Wrapper::_Get_DX8_Back_Buffer ();
3046+ SurfaceClass::SurfaceDescription surfaceDesc;
3047+ surface->Get_Description (surfaceDesc);
3048+
3049+ SurfaceClass* surfaceCopy = NEW_REF (SurfaceClass, (DX8Wrapper::_Create_DX8_Surface (surfaceDesc.Width , surfaceDesc.Height , surfaceDesc.Format )));
3050+ DX8Wrapper::_Copy_DX8_Rects (surface->Peek_D3D_Surface (), NULL , 0 , surfaceCopy->Peek_D3D_Surface (), NULL );
3051+
3052+ surface->Release_Ref ();
3053+ surface = NULL ;
3054+
3055+ struct Rect
3056+ {
3057+ int Pitch;
3058+ void * pBits;
3059+ } lrect;
3060+
3061+ lrect.pBits = surfaceCopy->Lock (&lrect.Pitch );
3062+ if (lrect.pBits == NULL )
3063+ {
3064+ surfaceCopy->Release_Ref ();
3065+ return ;
3066+ }
3067+
3068+ unsigned int x, y, index, index2;
3069+ unsigned int width = surfaceDesc.Width ;
3070+ unsigned int height = surfaceDesc.Height ;
3071+
3072+ std::shared_ptr<unsigned char > imageData (new unsigned char [3 * width * height],
3073+ std::default_delete<unsigned char []>());
3074+ unsigned char * image = imageData.get ();
3075+
3076+ for (y = 0 ; y < height; y++)
3077+ {
3078+ for (x = 0 ; x < width; x++)
3079+ {
3080+ index = 3 * (x + y * width);
3081+ index2 = y * lrect.Pitch + 4 * x;
3082+
3083+ image[index] = *((unsigned char *)lrect.pBits + index2 + 2 );
3084+ image[index + 1 ] = *((unsigned char *)lrect.pBits + index2 + 1 );
3085+ image[index + 2 ] = *((unsigned char *)lrect.pBits + index2 + 0 );
3086+ }
3087+ }
3088+
3089+ surfaceCopy->Unlock ();
3090+ surfaceCopy->Release_Ref ();
3091+ surfaceCopy = NULL ;
3092+
3093+ std::string pathnameCopy (pathname);
3094+ std::string leafnameCopy (leafname);
3095+
3096+ std::thread ([imageData, width, height, pathnameCopy, leafnameCopy]() {
3097+ int result = stbi_write_jpg (pathnameCopy.c_str (), width, height, 3 , imageData.get (), 90 );
3098+
3099+ if (!result) {
3100+ OutputDebugStringA (" Failed to write screenshot JPEG\n " );
3101+ }
3102+ }).detach ();
3103+
3104+ UnicodeString ufileName;
3105+ ufileName.translate (leafnameCopy.c_str ());
3106+ TheInGameUI->message (TheGameText->fetch (" GUI:ScreenCapture" ), ufileName.str ());
3107+ }
3108+
30253109/* * Start/Stop capturing an AVI movie*/
30263110void W3DDisplay::toggleMovieCapture (void )
30273111{
0 commit comments