@@ -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"
@@ -3141,6 +3146,85 @@ void W3DDisplay::takeScreenShot(void)
31413146 TheInGameUI->message (TheGameText->fetch (" GUI:ScreenCapture" ), ufileName.str ());
31423147}
31433148
3149+ void W3DDisplay::takeScreenShotCompressed (void )
3150+ {
3151+ char leafname[256 ];
3152+ char pathname[1024 ];
3153+ static int frame_number = 1 ;
3154+
3155+ Bool done = false ;
3156+ while (!done) {
3157+ sprintf (leafname, " sshot%.3d.jpg" , frame_number++);
3158+ strcpy (pathname, TheGlobalData->getPath_UserData ().str ());
3159+ strlcat (pathname, leafname, ARRAY_SIZE (pathname));
3160+ if (_access (pathname, 0 ) == -1 )
3161+ done = true ;
3162+ }
3163+
3164+ SurfaceClass* surface = DX8Wrapper::_Get_DX8_Back_Buffer ();
3165+ SurfaceClass::SurfaceDescription surfaceDesc;
3166+ surface->Get_Description (surfaceDesc);
3167+
3168+ SurfaceClass* surfaceCopy = NEW_REF (SurfaceClass, (DX8Wrapper::_Create_DX8_Surface (surfaceDesc.Width , surfaceDesc.Height , surfaceDesc.Format )));
3169+ DX8Wrapper::_Copy_DX8_Rects (surface->Peek_D3D_Surface (), NULL , 0 , surfaceCopy->Peek_D3D_Surface (), NULL );
3170+
3171+ surface->Release_Ref ();
3172+ surface = NULL ;
3173+
3174+ struct Rect
3175+ {
3176+ int Pitch;
3177+ void * pBits;
3178+ } lrect;
3179+
3180+ lrect.pBits = surfaceCopy->Lock (&lrect.Pitch );
3181+ if (lrect.pBits == NULL )
3182+ {
3183+ surfaceCopy->Release_Ref ();
3184+ return ;
3185+ }
3186+
3187+ unsigned int x, y, index, index2;
3188+ unsigned int width = surfaceDesc.Width ;
3189+ unsigned int height = surfaceDesc.Height ;
3190+
3191+ std::shared_ptr<unsigned char > imageData (new unsigned char [3 * width * height],
3192+ std::default_delete<unsigned char []>());
3193+ unsigned char * image = imageData.get ();
3194+
3195+ for (y = 0 ; y < height; y++)
3196+ {
3197+ for (x = 0 ; x < width; x++)
3198+ {
3199+ index = 3 * (x + y * width);
3200+ index2 = y * lrect.Pitch + 4 * x;
3201+
3202+ image[index] = *((unsigned char *)lrect.pBits + index2 + 2 );
3203+ image[index + 1 ] = *((unsigned char *)lrect.pBits + index2 + 1 );
3204+ image[index + 2 ] = *((unsigned char *)lrect.pBits + index2 + 0 );
3205+ }
3206+ }
3207+
3208+ surfaceCopy->Unlock ();
3209+ surfaceCopy->Release_Ref ();
3210+ surfaceCopy = NULL ;
3211+
3212+ std::string pathnameCopy (pathname);
3213+ std::string leafnameCopy (leafname);
3214+
3215+ std::thread ([imageData, width, height, pathnameCopy, leafnameCopy]() {
3216+ int result = stbi_write_jpg (pathnameCopy.c_str (), width, height, 3 , imageData.get (), 90 );
3217+
3218+ if (!result) {
3219+ OutputDebugStringA (" Failed to write screenshot JPEG\n " );
3220+ }
3221+ }).detach ();
3222+
3223+ UnicodeString ufileName;
3224+ ufileName.translate (leafnameCopy.c_str ());
3225+ TheInGameUI->message (TheGameText->fetch (" GUI:ScreenCapture" ), ufileName.str ());
3226+ }
3227+
31443228/* * Start/Stop capturing an AVI movie*/
31453229void W3DDisplay::toggleMovieCapture (void )
31463230{
0 commit comments