Subversion Repositories eduke32

Rev

Rev 7705 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6074 hendricks2 1
#include "compat.h"
5791 terminx 2
#include "build.h"
3
#include "editor.h"
4
 
6365 terminx 5
#include "pngwrite.h"
5791 terminx 6
 
7359 hendricks2 7
#include "vfs.h"
8094 hendricks2 8
#include "communityapi.h"
7359 hendricks2 9
 
5791 terminx 10
//
11
// screencapture
12
//
13
 
7359 hendricks2 14
buildvfs_FILE OutputFileCounter::opennextfile(char *fn, char *zeros)
5791 terminx 15
{
7359 hendricks2 16
    buildvfs_FILE file;
5791 terminx 17
 
18
    do      // JBF 2004022: So we don't overwrite existing screenshots
19
    {
6532 hendricks2 20
        if (count > 9999) return nullptr;
5791 terminx 21
 
6532 hendricks2 22
        zeros[0] = ((count/1000)%10)+'0';
23
        zeros[1] = ((count/100)%10)+'0';
24
        zeros[2] = ((count/10)%10)+'0';
25
        zeros[3] = (count%10)+'0';
5791 terminx 26
 
7359 hendricks2 27
        if ((file = buildvfs_fopen_read(fn)) == nullptr) break;
28
        buildvfs_fclose(file);
6532 hendricks2 29
        count++;
5791 terminx 30
    } while (1);
31
 
7359 hendricks2 32
    return buildvfs_fopen_write(fn);
6532 hendricks2 33
}
5791 terminx 34
 
7359 hendricks2 35
buildvfs_FILE OutputFileCounter::opennextfile_withext(char *fn, const char *ext)
6532 hendricks2 36
{
37
    char *dot = strrchr(fn, '.');
38
    strcpy(dot+1, ext);
39
    return opennextfile(fn, dot-4);
5791 terminx 40
}
41
 
6532 hendricks2 42
static OutputFileCounter capturecounter;
43
 
7359 hendricks2 44
static void screencapture_end(char *fn, buildvfs_FILE * filptr)
5791 terminx 45
{
8094 hendricks2 46
#ifdef VWSCREENSHOT
47
    communityapiSendScreenshot(fn);
48
#endif
7359 hendricks2 49
    buildvfs_fclose(*filptr);
6365 terminx 50
    OSD_Printf("Saved screenshot to %s\n", fn);
7705 terminx 51
    Xfree(fn);
6532 hendricks2 52
    capturecounter.count++;
6365 terminx 53
}
54
 
5791 terminx 55
# ifdef USE_OPENGL
6829 terminx 56
#  define HICOLOR (videoGetRenderMode() >= REND_POLYMOST && in3dmode())
5791 terminx 57
# else
58
#  define HICOLOR 0
59
# endif
60
 
6831 terminx 61
int videoCaptureScreen(const char *filename, char inverseit)
6365 terminx 62
{
63
    char *fn = Xstrdup(filename);
7359 hendricks2 64
    buildvfs_FILE fp = capturecounter.opennextfile_withext(fn, "png");
5791 terminx 65
 
6532 hendricks2 66
    if (fp == nullptr)
6365 terminx 67
    {
7705 terminx 68
        Xfree(fn);
6532 hendricks2 69
        return -1;
5791 terminx 70
    }
71
 
6365 terminx 72
    uint8_t * const imgBuf = (uint8_t *) Xmalloc(xdim * ydim * (HICOLOR ? 3 : 1));
5791 terminx 73
 
6828 terminx 74
    videoBeginDrawing(); //{{{
6365 terminx 75
 
76
#ifdef USE_OPENGL
77
    if (HICOLOR)
5791 terminx 78
    {
6656 pogokeen 79
        glReadPixels(0, 0, xdim, ydim, GL_RGB, GL_UNSIGNED_BYTE, imgBuf);
6365 terminx 80
        int const bytesPerLine = xdim * 3;
5791 terminx 81
 
6365 terminx 82
        if (inverseit)
83
        {
7673 terminx 84
            for (int i=0, j = ydim * bytesPerLine; i<j; i+=3)
6365 terminx 85
                swapchar(&imgBuf[i], &imgBuf[i+2]);
86
        }
5791 terminx 87
 
6365 terminx 88
        // flip rows
89
        uint8_t* rowBuf = (uint8_t *) Xmalloc(bytesPerLine);
5791 terminx 90
 
6365 terminx 91
        for (int i = 0, numRows = ydim >> 1; i < numRows; ++i)
92
        {
93
            Bmemcpy(rowBuf, imgBuf + i * bytesPerLine, bytesPerLine);
94
            Bmemcpy(imgBuf + i * bytesPerLine, imgBuf + (ydim - i - 1) * bytesPerLine, bytesPerLine);
95
            Bmemcpy(imgBuf + (ydim - i - 1) * bytesPerLine, rowBuf, bytesPerLine);
96
        }
5791 terminx 97
 
7705 terminx 98
        Xfree(rowBuf);
6365 terminx 99
    }
100
    else
5791 terminx 101
#endif
6365 terminx 102
    {
103
        struct {
104
            uint8_t r, g, b;
105
        } palette[256];
5791 terminx 106
 
5867 hendricks2 107
        if (inverseit)
5791 terminx 108
        {
5867 hendricks2 109
            for (bssize_t i = 0; i < 256; ++i)
110
            {
6365 terminx 111
                palette[i].r = 255 - curpalettefaded[i].r;
112
                palette[i].g = 255 - curpalettefaded[i].g;
113
                palette[i].b = 255 - curpalettefaded[i].b;
5867 hendricks2 114
            }
5791 terminx 115
        }
5867 hendricks2 116
        else
117
        {
118
            for (bssize_t i = 0; i < 256; ++i)
6365 terminx 119
                Bmemcpy(&palette[i], &curpalettefaded[i], sizeof(palette[0]));
5867 hendricks2 120
        }
5791 terminx 121
 
6365 terminx 122
        png_set_pal((uint8_t *)palette, 256);
123
 
124
        for (int i = 0; i < ydim; ++i)
125
            Bmemcpy(imgBuf + i * xdim, (uint8_t *)frameplace + ylookup[i], xdim);
5791 terminx 126
    }
127
 
6828 terminx 128
    videoEndDrawing(); //}}}
5791 terminx 129
 
6365 terminx 130
    png_set_text("Software", osd->version.buf);
131
    png_write(fp, xdim, ydim, HICOLOR ? PNG_TRUECOLOR : PNG_INDEXED, imgBuf);
7705 terminx 132
    Xfree(imgBuf);
6365 terminx 133
    screencapture_end(fn, &fp);
5791 terminx 134
 
135
    return 0;
136
}
137
 
6831 terminx 138
int videoCaptureScreenTGA(const char *filename, char inverseit)
5791 terminx 139
{
140
    int32_t i;
6365 terminx 141
    char head[18] = { 0,1,1,0,0,0,1,24,0,0,0,0,0/*wlo*/,0/*whi*/,0/*hlo*/,0/*hhi*/,8,0 };
5791 terminx 142
    //char palette[4*256];
143
    char *fn = Xstrdup(filename);
144
 
7359 hendricks2 145
    buildvfs_FILE fil = capturecounter.opennextfile_withext(fn, "tga");
6532 hendricks2 146
    if (fil == nullptr)
5791 terminx 147
    {
7705 terminx 148
        Xfree(fn);
6532 hendricks2 149
        return -1;
5791 terminx 150
    }
151
 
6365 terminx 152
#ifdef USE_OPENGL
153
    if (HICOLOR)
5791 terminx 154
    {
155
        head[1] = 0;    // no colourmap
156
        head[2] = 2;    // uncompressed truecolour
157
        head[3] = 0;    // (low) first colourmap index
158
        head[4] = 0;    // (high) first colourmap index
159
        head[5] = 0;    // (low) number colourmap entries
160
        head[6] = 0;    // (high) number colourmap entries
161
        head[7] = 0;    // colourmap entry size
162
        head[16] = 24;  // 24 bits per pixel
163
    }
6365 terminx 164
#endif
5791 terminx 165
 
166
    head[12] = xdim & 0xff;
167
    head[13] = (xdim >> 8) & 0xff;
168
    head[14] = ydim & 0xff;
169
    head[15] = (ydim >> 8) & 0xff;
170
 
7359 hendricks2 171
    buildvfs_fwrite(head, 18, 1, fil);
5791 terminx 172
 
6400 hendricks2 173
    // palette first
6365 terminx 174
#ifdef USE_OPENGL
175
    if (!HICOLOR)
176
#endif
5791 terminx 177
    {
6365 terminx 178
        if (inverseit)
5791 terminx 179
        {
6365 terminx 180
            for (i=0; i<256; i++)
181
            {
7359 hendricks2 182
                buildvfs_fputc(255 - curpalettefaded[i].b, fil);
183
                buildvfs_fputc(255 - curpalettefaded[i].g, fil);
184
                buildvfs_fputc(255 - curpalettefaded[i].r, fil);
6365 terminx 185
            }
5791 terminx 186
        }
6365 terminx 187
        else
188
        {
189
            for (i=0; i<256; i++)
190
            {
7359 hendricks2 191
                buildvfs_fputc(curpalettefaded[i].b, fil);
192
                buildvfs_fputc(curpalettefaded[i].g, fil);
193
                buildvfs_fputc(curpalettefaded[i].r, fil);
6365 terminx 194
            }
195
        }
5791 terminx 196
    }
197
 
6828 terminx 198
    videoBeginDrawing(); //{{{
6365 terminx 199
 
5791 terminx 200
# ifdef USE_OPENGL
6365 terminx 201
    if (HICOLOR)
5791 terminx 202
    {
203
        // 24bit
6365 terminx 204
        int const size = xdim * ydim * 3;
205
        uint8_t *inversebuf = (uint8_t *) Xmalloc(size);
5791 terminx 206
 
6656 pogokeen 207
        glReadPixels(0, 0, xdim, ydim, GL_RGB, GL_UNSIGNED_BYTE, inversebuf);
6400 hendricks2 208
 
6365 terminx 209
        for (i = 0; i < size; i += 3)
210
            swapchar(&inversebuf[i], &inversebuf[i + 2]);
211
 
7359 hendricks2 212
        buildvfs_fwrite(inversebuf, xdim*ydim, 3, fil);
7705 terminx 213
        Xfree(inversebuf);
5791 terminx 214
    }
215
    else
216
# endif
217
    {
6365 terminx 218
        char * const ptr = (char *) frameplace;
219
 
220
        for (i = ydim-1; i >= 0; i--)
7359 hendricks2 221
            buildvfs_fwrite(ptr + i * bytesperline, xdim, 1, fil);
5791 terminx 222
    }
223
 
6828 terminx 224
    videoEndDrawing();   //}}}
5791 terminx 225
 
6365 terminx 226
    screencapture_end(fn, &fil);
227
 
5803 terminx 228
    return 0;
5791 terminx 229
}
6365 terminx 230
#undef HICOLOR
5791 terminx 231