annotate src/video/SDL_bmp.c @ 4157:baf615f9f2a0 SDL-1.2

Date: Thu, 16 Oct 2008 20:27:34 +0400 From: "Ilya Kasnacheev" <ilya.kasnacheev@gmail.com> To: sdl@lists.libsdl.org Subject: [SDL] SDL for Windows CE: a few GAPI patches Hi *! I've just ported a POWDER roguelike ( http://www.zincland.com/powder/ ) to Windows CE (PDAs, Windows Mobile/Pocket PC). To do that, I had to get libsdl working. Thanks for the awesome project files, it built without a hitch. Nevertheless, I've found quite a few bugs in Windows CE (GAPI) SDL implementation, which I've solved and now present as a serie of patches. I'll try carefully annotate them. Please annotate them so I can work toward accepting them into the main source tree since without them SDL isn't really working on Windows CE (I wonder why nobody fixed them before, btw: why isn't SDL popular as a way to develop Windows CE games? Where are no ports?) These changes can't be considered flawless, but they can be considered working because I've yet to hear complains about things I fixed and POWDER build for Windows CE is now considered stable. Note: my comments start with !!, delete them before applying. diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.c SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c --- SDL-1.2.13/src/video/gapi/SDL_gapivideo.c 2007-12-31 07:48:00.000000000 +0300 +++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.c 2008-10-16 20:02:11.000000000 +0400 @@ -643,6 +643,7 @@ } gapi->userOrientation = SDL_ORIENTATION_UP; + gapi->systemOrientation = SDL_ORIENTATION_UP; video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports fullscreen only */ /* GAPI or VGA? */ @@ -661,18 +662,21 @@ } /* detect user landscape mode */ - if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN))) + if( (width > height) && (gapi->gxProperties.cxWidth < gapi->gxProperties.cyHeight)) gapi->userOrientation = SDL_ORIENTATION_RIGHT; + if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN)) + gapi->systemOrientation = SDL_ORIENTATION_RIGHT; + /* shall we apply hires fix? for example when we do not use hires resource */ gapi->hiresFix = 0; - if( gapi->userOrientation == SDL_ORIENTATION_RIGHT ) + if( gapi->systemOrientation == gapi->userOrientation ) { - if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height > GetSystemMetrics(SM_CXSCREEN))) + if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height > GetSystemMetrics(SM_CYSCREEN))) gapi->hiresFix = 1; } else - if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height > GetSystemMetrics(SM_CYSCREEN))) - if( !((width == GetSystemMetrics(SM_CYSCREEN)) && (height == GetSystemMetrics(SM_CXSCREEN)))) // user portrait, device landscape + if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height > GetSystemMetrics(SM_CXSCREEN))) +// if( !((width == gapi->gxProperties.cyHeight) && (height == gapi->gxProperties.cxWidth))) // user portrait, device landscape gapi->hiresFix = 1; switch( gapi->userOrientation ) !! It used to query system metrics which return dimensions according to screen !! orientation, which can really be portrait, left landscape or right landscape. !! This is presumably incorrect because we couldn't care less about user mode !! dimensions - all we want are the GAPI framebuffer dimensions, which only match !! user dimensions in one of possible orientations. !! There's a fair dose of cargo cult programming involved in this fix, but it !! used to work only in one orientation (portrait for PDAs, where frame-buffer !! have same orientation as user screen), and now it works on all orientations. @@ -742,21 +746,30 @@ WIN_FlushMessageQueue(); /* Open GAPI display */ - if( !gapi->useVga && this->hidden->useGXOpenDisplay ) + if( !gapi->useVga && this->hidden->useGXOpenDisplay && !this->hidden->alreadyGXOpened ) + { + this->hidden->alreadyGXOpened = 1; if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) ) { SDL_SetError("Couldn't initialize GAPI"); return(NULL); } + } #if REPORT_VIDEO_INFO printf("Video properties:\n"); printf("display bpp: %d\n", gapi->gxProperties.cBPP); printf("display width: %d\n", gapi->gxProperties.cxWidth); printf("display height: %d\n", gapi->gxProperties.cyHeight); + printf("system display width: %d\n", GetSystemMetrics(SM_CXSCREEN)); + printf("system display height: %d\n", GetSystemMetrics(SM_CYSCREEN)); printf("x pitch: %d\n", gapi->gxProperties.cbxPitch); printf("y pitch: %d\n", gapi->gxProperties.cbyPitch); printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat); + printf("user orientation: %d\n", gapi->userOrientation); + printf("system orientation: %d\n", gapi->userOrientation); + printf("gapi orientation: %d\n", gapi->gapiOrientation); + if( !gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate) { !! Previous version used to call gapi->gxFunc.GXOpenDisplay each time the video !! mode would be changed. You shouldn't, because this call has a meaning "Lock the !! GAPI framebuffer, designate it as busy", so the second call will fail (it is !! already locked/busy). !! Testing might not find that because most programs set up the video mode only !! once, but POWDER does this once in a while, so it crashed when in 320x240 mode !! (640x480 mode doesn't use that code, it worked fine). diff -bru SDL-1.2.13/src/video/gapi/SDL_gapivideo.h SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h --- SDL-1.2.13/src/video/gapi/SDL_gapivideo.h 2007-12-31 07:48:00.000000000 +0300 +++ SDL-1.2.13-new/src/video/gapi/SDL_gapivideo.h 2008-10-16 20:02:11.000000000 +0400 @@ -132,12 +132,17 @@ #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ int SDL_nummodes[NUM_MODELISTS]; SDL_Rect **SDL_modelist[NUM_MODELISTS]; + // The orientation of the video mode user wants to get + // Probably restricted to UP and RIGHT enum SDL_ScreenOrientation userOrientation; int invert; char hiresFix; // using hires mode without defining hires resource // -------------- int useGXOpenDisplay; /* use GXOpenDispplay */ + int alreadyGXOpened; int w, h; + // The orientation of GAPI framebuffer. + // Never changes on the same device. enum SDL_ScreenOrientation gapiOrientation; void *buffer; // may be 8, 16, 24, 32 bpp @@ -153,6 +158,10 @@ int startOffset; // in bytes int useVga; int suspended; // do not pu anything into video memory + // The orientation of the system, as defined by SM_CXSCREEN and SM_CYSCREEN + // User can change it by using 'screen layout' in system options + // Restricted to UP or RIGHT + enum SDL_ScreenOrientation systemOrientation; }; !! This is a flag variable, see the previous comment !! And yet another orientation: now we have to keep three of them in mind. diff -bru SDL-1.2.13/src/video/wincommon/SDL_sysevents.c SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c --- SDL-1.2.13/src/video/wincommon/SDL_sysevents.c 2007-12-31 07:48:02.000000000 +0300 +++ SDL-1.2.13-new/src/video/wincommon/SDL_sysevents.c 2008-10-16 20:02:12.000000000 +0400 @@ -160,10 +160,22 @@ #endif */ } break; + // FIXME: Older version used just SDL_VideoSurface->(w, h) + // w and h are "clipped" while x and y are "raw", which caused + // x in former and y in latter case to be clipped in a wrong direction, + // thus offsetting the coordinate on 2 x clip pixels + // (like, 128 for 640 -> 512 clipping). + // We will now try to extract and use raw values. + // The way to do that RIGHT is do (orientation-dependent) clipping before + // doing this transform, but it's hardly possible. + + // SEE SDL_mouse.c /ClipOffset to understand these calculations. case SDL_ORIENTATION_RIGHT: if (!SDL_VideoSurface) break; - rotatedX = SDL_VideoSurface->w - *y; + rotatedX = (2 * ((SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/ + SDL_VideoSurface->format->BytesPerPixel)) + + SDL_VideoSurface->w - *y; rotatedY = *x; *x = rotatedX; *y = rotatedY; @@ -172,7 +184,8 @@ if (!SDL_VideoSurface) break; rotatedX = *y; - rotatedY = SDL_VideoSurface->h - *x; + rotatedY = (2 * (SDL_VideoSurface->offset/SDL_VideoSurface->pitch)) + + SDL_VideoSurface->h - *x; *x = rotatedX; *y = rotatedY; break; !! That's the trickest part, hence the long comment. !! GAPI would really support only 320x240 or 640x480 mode, if application !! requested the different screen size (as POWDER did, wishing 256x192), then SDL !! is going to grab the first mode that fits the requested, and pad the screen !! with black bars (as they do with wide-screen films). !! It would also get, say, 240x320 mode, and to turn it into 256x192 it would !! need to rotate mouse clicks. !! It worked, but one bug slipped through: it would receive mouse clicks !! unpadded, then rotate them, and then pad the black bars. The problem is: rotate !! is done by GAPI driver while padding is done by SDL core. SDL core doesn't know !! anything about rotating, so it would pad one of dimensions incorrectly. I understand that some of my claims (or code) might seem unbacked, but you can always grab the POWDER binary, compile your own libsdl with one or more of those fixes turned off, and see how weird it would misbehave. I can even supply you with those custom builds of libsdl if you don't want to set up the build environment for windows ce, you'll just need a PDA or a smartphone with it. I plan to take care of SDL on Windows CE as long as I maintain the POWDER port. POWDER is good for that because it: Employs both padded (with centered image, black bars) and unpadded (image occupies full screen) graphics; initializes video more than once; uses both 320x240 and 640x480 video; uses both stylus and buttons. There's still a list of unresolved issues which I'm planning to fix: 1) Arrow buttons on PDA return weird scancodes compared to PC, this caused the game to misbehave before I've fixed that. You can see it on those diagrams: http://wrar.name/upload/powder-htc.png http://wrar.name/upload/powder-pda.png 2) SDL (or underlying windows) doesn't care to rotate arrow presses when we're in a low-res GAPI mode, but it will rotate them in VGA mode (because of different screen orientations, the same arrow buttons can suddently mean different directions). Solution: we should stick to GAPI user orientation (the orientation the program supposedly wants) and rotate the keys on our own. _______________________________________________ SDL mailing list SDL@lists.libsdl.org http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
author Sam Lantinga <slouken@libsdl.org>
date Fri, 07 Nov 2008 04:15:36 +0000
parents d910939febfa
children 782fd950bd46 c121d94672cb a1b03ba2fcd0
rev   line source
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
1 /*
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
2 SDL - Simple DirectMedia Layer
1312
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
3 Copyright (C) 1997-2006 Sam Lantinga
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
4
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
5 This library is free software; you can redistribute it and/or
1312
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
6 modify it under the terms of the GNU Lesser General Public
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
7 License as published by the Free Software Foundation; either
1312
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
8 version 2.1 of the License, or (at your option) any later version.
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
9
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
10 This library is distributed in the hope that it will be useful,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1312
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
13 Lesser General Public License for more details.
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
14
1312
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
15 You should have received a copy of the GNU Lesser General Public
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
16 License along with this library; if not, write to the Free Software
c9b51268668f Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents: 1012
diff changeset
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
18
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
19 Sam Lantinga
252
e8157fcb3114 Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents: 0
diff changeset
20 slouken@libsdl.org
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
21 */
1402
d910939febfa Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents: 1361
diff changeset
22 #include "SDL_config.h"
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
23
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
24 /*
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
25 Code to load and save surfaces in Windows BMP format.
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
26
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
27 Why support BMP format? Well, it's a native format for Windows, and
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
28 most image processing programs can read and write it. It would be nice
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
29 to be able to have at least one image format that we can natively load
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
30 and save, and since PNG is so complex that it would bloat the library,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
31 BMP is a good alternative.
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
32
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
33 This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp.
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
34 */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
35
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
36 #include "SDL_video.h"
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
37 #include "SDL_endian.h"
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
38
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
39 /* Compression encodings for BMP files */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
40 #ifndef BI_RGB
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
41 #define BI_RGB 0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
42 #define BI_RLE8 1
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
43 #define BI_RLE4 2
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
44 #define BI_BITFIELDS 3
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
45 #endif
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
46
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
47
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
48 SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
49 {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
50 int was_error;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
51 long fp_offset;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
52 int bmpPitch;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
53 int i, pad;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
54 SDL_Surface *surface;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
55 Uint32 Rmask;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
56 Uint32 Gmask;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
57 Uint32 Bmask;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
58 SDL_Palette *palette;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
59 Uint8 *bits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
60 int ExpandBMP;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
61
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
62 /* The Win32 BMP file header (14 bytes) */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
63 char magic[2];
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
64 Uint32 bfSize;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
65 Uint16 bfReserved1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
66 Uint16 bfReserved2;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
67 Uint32 bfOffBits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
68
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
69 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
70 Uint32 biSize;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
71 Sint32 biWidth;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
72 Sint32 biHeight;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
73 Uint16 biPlanes;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
74 Uint16 biBitCount;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
75 Uint32 biCompression;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
76 Uint32 biSizeImage;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
77 Sint32 biXPelsPerMeter;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
78 Sint32 biYPelsPerMeter;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
79 Uint32 biClrUsed;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
80 Uint32 biClrImportant;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
81
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
82 /* Make sure we are passed a valid data source */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
83 surface = NULL;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
84 was_error = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
85 if ( src == NULL ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
86 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
87 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
88 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
89
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
90 /* Read in the BMP file header */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
91 fp_offset = SDL_RWtell(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
92 SDL_ClearError();
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
93 if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
94 SDL_Error(SDL_EFREAD);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
95 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
96 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
97 }
1336
3692456e7b0f Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents: 1330
diff changeset
98 if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
99 SDL_SetError("File is not a Windows BMP file");
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
100 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
101 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
102 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
103 bfSize = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
104 bfReserved1 = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
105 bfReserved2 = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
106 bfOffBits = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
107
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
108 /* Read the Win32 BITMAPINFOHEADER */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
109 biSize = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
110 if ( biSize == 12 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
111 biWidth = (Uint32)SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
112 biHeight = (Uint32)SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
113 biPlanes = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
114 biBitCount = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
115 biCompression = BI_RGB;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
116 biSizeImage = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
117 biXPelsPerMeter = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
118 biYPelsPerMeter = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
119 biClrUsed = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
120 biClrImportant = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
121 } else {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
122 biWidth = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
123 biHeight = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
124 biPlanes = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
125 biBitCount = SDL_ReadLE16(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
126 biCompression = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
127 biSizeImage = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
128 biXPelsPerMeter = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
129 biYPelsPerMeter = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
130 biClrUsed = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
131 biClrImportant = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
132 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
133
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
134 /* Check for read error */
1336
3692456e7b0f Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents: 1330
diff changeset
135 if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
136 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
137 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
138 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
139
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
140 /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
141 switch (biBitCount) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
142 case 1:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
143 case 4:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
144 ExpandBMP = biBitCount;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
145 biBitCount = 8;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
146 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
147 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
148 ExpandBMP = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
149 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
150 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
151
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
152 /* We don't support any BMP compression right now */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
153 Rmask = Gmask = Bmask = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
154 switch (biCompression) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
155 case BI_RGB:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
156 /* If there are no masks, use the defaults */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
157 if ( bfOffBits == (14+biSize) ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
158 /* Default values for the BMP format */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
159 switch (biBitCount) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
160 case 15:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
161 case 16:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
162 Rmask = 0x7C00;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
163 Gmask = 0x03E0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
164 Bmask = 0x001F;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
165 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
166 case 24:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
167 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
168 Rmask = 0x000000FF;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
169 Gmask = 0x0000FF00;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
170 Bmask = 0x00FF0000;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
171 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
172 #endif
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
173 case 32:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
174 Rmask = 0x00FF0000;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
175 Gmask = 0x0000FF00;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
176 Bmask = 0x000000FF;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
177 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
178 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
179 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
180 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
181 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
182 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
183 /* Fall through -- read the RGB masks */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
184
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
185 case BI_BITFIELDS:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
186 switch (biBitCount) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
187 case 15:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
188 case 16:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
189 case 32:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
190 Rmask = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
191 Gmask = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
192 Bmask = SDL_ReadLE32(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
193 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
194 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
195 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
196 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
197 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
198 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
199 SDL_SetError("Compressed BMP files not supported");
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
200 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
201 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
202 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
203
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
204 /* Create a compatible surface, note that the colors are RGB ordered */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
205 surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
206 biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
207 if ( surface == NULL ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
208 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
209 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
210 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
211
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
212 /* Load the palette, if any */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
213 palette = (surface->format)->palette;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
214 if ( palette ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
215 if ( biClrUsed == 0 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
216 biClrUsed = 1 << biBitCount;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
217 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
218 if ( biSize == 12 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
219 for ( i = 0; i < (int)biClrUsed; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
220 SDL_RWread(src, &palette->colors[i].b, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
221 SDL_RWread(src, &palette->colors[i].g, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
222 SDL_RWread(src, &palette->colors[i].r, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
223 palette->colors[i].unused = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
224 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
225 } else {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
226 for ( i = 0; i < (int)biClrUsed; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
227 SDL_RWread(src, &palette->colors[i].b, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
228 SDL_RWread(src, &palette->colors[i].g, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
229 SDL_RWread(src, &palette->colors[i].r, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
230 SDL_RWread(src, &palette->colors[i].unused, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
231 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
232 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
233 palette->ncolors = biClrUsed;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
234 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
235
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
236 /* Read the surface pixels. Note that the bmp image is upside down */
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
237 if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
238 SDL_Error(SDL_EFSEEK);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
239 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
240 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
241 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
242 bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
243 switch (ExpandBMP) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
244 case 1:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
245 bmpPitch = (biWidth + 7) >> 3;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
246 pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
247 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
248 case 4:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
249 bmpPitch = (biWidth + 1) >> 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
250 pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
251 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
252 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
253 pad = ((surface->pitch%4) ?
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
254 (4-(surface->pitch%4)) : 0);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
255 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
256 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
257 while ( bits > (Uint8 *)surface->pixels ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
258 bits -= surface->pitch;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
259 switch (ExpandBMP) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
260 case 1:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
261 case 4: {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
262 Uint8 pixel = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
263 int shift = (8-ExpandBMP);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
264 for ( i=0; i<surface->w; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
265 if ( i%(8/ExpandBMP) == 0 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
266 if ( !SDL_RWread(src, &pixel, 1, 1) ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
267 SDL_SetError(
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
268 "Error reading from BMP");
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
269 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
270 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
271 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
272 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
273 *(bits+i) = (pixel>>shift);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
274 pixel <<= ExpandBMP;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
275 } }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
276 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
277
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
278 default:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
279 if ( SDL_RWread(src, bits, 1, surface->pitch)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
280 != surface->pitch ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
281 SDL_Error(SDL_EFREAD);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
282 was_error = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
283 goto done;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
284 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
285 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
286 /* Byte-swap the pixels if needed. Note that the 24bpp
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
287 case has already been taken care of above. */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
288 switch(biBitCount) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
289 case 15:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
290 case 16: {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
291 Uint16 *pix = (Uint16 *)bits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
292 for(i = 0; i < surface->w; i++)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
293 pix[i] = SDL_Swap16(pix[i]);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
294 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
295 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
296
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
297 case 32: {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
298 Uint32 *pix = (Uint32 *)bits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
299 for(i = 0; i < surface->w; i++)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
300 pix[i] = SDL_Swap32(pix[i]);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
301 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
302 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
303 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
304 #endif
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
305 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
306 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
307 /* Skip padding bytes, ugh */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
308 if ( pad ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
309 Uint8 padbyte;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
310 for ( i=0; i<pad; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
311 SDL_RWread(src, &padbyte, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
312 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
313 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
314 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
315 done:
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
316 if ( was_error ) {
1329
bc67bbf87818 Seek back to start on error
Sam Lantinga <slouken@libsdl.org>
parents: 1312
diff changeset
317 if ( src ) {
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
318 SDL_RWseek(src, fp_offset, RW_SEEK_SET);
1329
bc67bbf87818 Seek back to start on error
Sam Lantinga <slouken@libsdl.org>
parents: 1312
diff changeset
319 }
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
320 if ( surface ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
321 SDL_FreeSurface(surface);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
322 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
323 surface = NULL;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
324 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
325 if ( freesrc && src ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
326 SDL_RWclose(src);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
327 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
328 return(surface);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
329 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
330
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
331 int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
332 {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
333 long fp_offset;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
334 int i, pad;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
335 SDL_Surface *surface;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
336 Uint8 *bits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
337
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
338 /* The Win32 BMP file header (14 bytes) */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
339 char magic[2] = { 'B', 'M' };
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
340 Uint32 bfSize;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
341 Uint16 bfReserved1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
342 Uint16 bfReserved2;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
343 Uint32 bfOffBits;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
344
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
345 /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
346 Uint32 biSize;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
347 Sint32 biWidth;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
348 Sint32 biHeight;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
349 Uint16 biPlanes;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
350 Uint16 biBitCount;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
351 Uint32 biCompression;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
352 Uint32 biSizeImage;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
353 Sint32 biXPelsPerMeter;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
354 Sint32 biYPelsPerMeter;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
355 Uint32 biClrUsed;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
356 Uint32 biClrImportant;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
357
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
358 /* Make sure we have somewhere to save */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
359 surface = NULL;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
360 if ( dst ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
361 if ( saveme->format->palette ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
362 if ( saveme->format->BitsPerPixel == 8 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
363 surface = saveme;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
364 } else {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
365 SDL_SetError("%d bpp BMP files not supported",
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
366 saveme->format->BitsPerPixel);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
367 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
368 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
369 else if ( (saveme->format->BitsPerPixel == 24) &&
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
370 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
371 (saveme->format->Rmask == 0x00FF0000) &&
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
372 (saveme->format->Gmask == 0x0000FF00) &&
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
373 (saveme->format->Bmask == 0x000000FF)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
374 #else
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
375 (saveme->format->Rmask == 0x000000FF) &&
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
376 (saveme->format->Gmask == 0x0000FF00) &&
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
377 (saveme->format->Bmask == 0x00FF0000)
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
378 #endif
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
379 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
380 surface = saveme;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
381 } else {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
382 SDL_Rect bounds;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
383
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
384 /* Convert to 24 bits per pixel */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
385 surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
386 saveme->w, saveme->h, 24,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
387 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
388 0x00FF0000, 0x0000FF00, 0x000000FF,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
389 #else
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
390 0x000000FF, 0x0000FF00, 0x00FF0000,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
391 #endif
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
392 0);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
393 if ( surface != NULL ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
394 bounds.x = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
395 bounds.y = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
396 bounds.w = saveme->w;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
397 bounds.h = saveme->h;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
398 if ( SDL_LowerBlit(saveme, &bounds, surface,
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
399 &bounds) < 0 ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
400 SDL_FreeSurface(surface);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
401 SDL_SetError(
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
402 "Couldn't convert image to 24 bpp");
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
403 surface = NULL;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
404 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
405 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
406 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
407 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
408
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
409 if ( surface && (SDL_LockSurface(surface) == 0) ) {
1012
f14e3059e138 Date: Mon, 13 Dec 2004 21:28:18 -0500
Sam Lantinga <slouken@libsdl.org>
parents: 769
diff changeset
410 const int bw = surface->w*surface->format->BytesPerPixel;
f14e3059e138 Date: Mon, 13 Dec 2004 21:28:18 -0500
Sam Lantinga <slouken@libsdl.org>
parents: 769
diff changeset
411
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
412 /* Set the BMP file header values */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
413 bfSize = 0; /* We'll write this when we're done */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
414 bfReserved1 = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
415 bfReserved2 = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
416 bfOffBits = 0; /* We'll write this when we're done */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
417
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
418 /* Write the BMP file header values */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
419 fp_offset = SDL_RWtell(dst);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
420 SDL_ClearError();
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
421 SDL_RWwrite(dst, magic, 2, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
422 SDL_WriteLE32(dst, bfSize);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
423 SDL_WriteLE16(dst, bfReserved1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
424 SDL_WriteLE16(dst, bfReserved2);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
425 SDL_WriteLE32(dst, bfOffBits);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
426
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
427 /* Set the BMP info values */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
428 biSize = 40;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
429 biWidth = surface->w;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
430 biHeight = surface->h;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
431 biPlanes = 1;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
432 biBitCount = surface->format->BitsPerPixel;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
433 biCompression = BI_RGB;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
434 biSizeImage = surface->h*surface->pitch;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
435 biXPelsPerMeter = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
436 biYPelsPerMeter = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
437 if ( surface->format->palette ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
438 biClrUsed = surface->format->palette->ncolors;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
439 } else {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
440 biClrUsed = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
441 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
442 biClrImportant = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
443
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
444 /* Write the BMP info values */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
445 SDL_WriteLE32(dst, biSize);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
446 SDL_WriteLE32(dst, biWidth);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
447 SDL_WriteLE32(dst, biHeight);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
448 SDL_WriteLE16(dst, biPlanes);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
449 SDL_WriteLE16(dst, biBitCount);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
450 SDL_WriteLE32(dst, biCompression);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
451 SDL_WriteLE32(dst, biSizeImage);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
452 SDL_WriteLE32(dst, biXPelsPerMeter);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
453 SDL_WriteLE32(dst, biYPelsPerMeter);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
454 SDL_WriteLE32(dst, biClrUsed);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
455 SDL_WriteLE32(dst, biClrImportant);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
456
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
457 /* Write the palette (in BGR color order) */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
458 if ( surface->format->palette ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
459 SDL_Color *colors;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
460 int ncolors;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
461
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
462 colors = surface->format->palette->colors;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
463 ncolors = surface->format->palette->ncolors;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
464 for ( i=0; i<ncolors; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
465 SDL_RWwrite(dst, &colors[i].b, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
466 SDL_RWwrite(dst, &colors[i].g, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
467 SDL_RWwrite(dst, &colors[i].r, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
468 SDL_RWwrite(dst, &colors[i].unused, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
469 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
470 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
471
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
472 /* Write the bitmap offset */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
473 bfOffBits = SDL_RWtell(dst)-fp_offset;
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
474 if ( SDL_RWseek(dst, fp_offset+10, RW_SEEK_SET) < 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
475 SDL_Error(SDL_EFSEEK);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
476 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
477 SDL_WriteLE32(dst, bfOffBits);
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
478 if ( SDL_RWseek(dst, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
479 SDL_Error(SDL_EFSEEK);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
480 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
481
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
482 /* Write the bitmap image upside down */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
483 bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
1012
f14e3059e138 Date: Mon, 13 Dec 2004 21:28:18 -0500
Sam Lantinga <slouken@libsdl.org>
parents: 769
diff changeset
484 pad = ((bw%4) ? (4-(bw%4)) : 0);
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
485 while ( bits > (Uint8 *)surface->pixels ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
486 bits -= surface->pitch;
1012
f14e3059e138 Date: Mon, 13 Dec 2004 21:28:18 -0500
Sam Lantinga <slouken@libsdl.org>
parents: 769
diff changeset
487 if ( SDL_RWwrite(dst, bits, 1, bw) != bw) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
488 SDL_Error(SDL_EFWRITE);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
489 break;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
490 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
491 if ( pad ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
492 const Uint8 padbyte = 0;
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
493 for ( i=0; i<pad; ++i ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
494 SDL_RWwrite(dst, &padbyte, 1, 1);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
495 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
496 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
497 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
498
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
499 /* Write the BMP file size */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
500 bfSize = SDL_RWtell(dst)-fp_offset;
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
501 if ( SDL_RWseek(dst, fp_offset+2, RW_SEEK_SET) < 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
502 SDL_Error(SDL_EFSEEK);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
503 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
504 SDL_WriteLE32(dst, bfSize);
1330
450721ad5436 It's now possible to build SDL without any C runtime at all on Windows,
Sam Lantinga <slouken@libsdl.org>
parents: 1329
diff changeset
505 if ( SDL_RWseek(dst, fp_offset+bfSize, RW_SEEK_SET) < 0 ) {
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
506 SDL_Error(SDL_EFSEEK);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
507 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
508
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
509 /* Close it up.. */
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
510 SDL_UnlockSurface(surface);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
511 if ( surface != saveme ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
512 SDL_FreeSurface(surface);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
513 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
514 }
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
515
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
516 if ( freedst && dst ) {
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
517 SDL_RWclose(dst);
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
518 }
1336
3692456e7b0f Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents: 1330
diff changeset
519 return((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1);
0
74212992fb08 Initial revision
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
520 }