mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 17:46:53 -10:00
1867 lines
45 KiB
C++
1867 lines
45 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* $Logfile: /Freespace2/code/Graphics/GrSoft.cpp $
|
|
* $Revision: 2.3 $
|
|
* $Date: 2003-03-02 05:43:49 $
|
|
* $Author: penguin $
|
|
*
|
|
* Code for our software renderer using standard Win32 functions. (Dibsections, etc)
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 2.2 2002/08/01 01:41:05 penguin
|
|
* The big include file move
|
|
*
|
|
* Revision 2.1 2002/07/07 19:55:59 penguin
|
|
* Back-port to MSVC
|
|
*
|
|
* Revision 2.0 2002/06/03 04:02:23 penguin
|
|
* Warpcore CVS sync
|
|
*
|
|
* Revision 1.2 2002/05/17 02:52:38 mharris
|
|
* More porting hacks
|
|
*
|
|
* Revision 1.1 2002/05/02 18:03:07 mharris
|
|
* Initial checkin - converted filenames and includes to lower case
|
|
*
|
|
*
|
|
* 12 7/14/99 9:42a Dave
|
|
* Put in clear_color debug function. Put in base for 3dnow stuff / P3
|
|
* stuff
|
|
*
|
|
* 11 7/09/99 9:51a Dave
|
|
* Added thick polyline code.
|
|
*
|
|
* 10 6/29/99 10:35a Dave
|
|
* Interface polygon bitmaps! Whee!
|
|
*
|
|
* 9 2/03/99 11:44a Dave
|
|
* Fixed d3d transparent textures.
|
|
*
|
|
* 8 1/24/99 11:37p Dave
|
|
* First full rev of beam weapons. Very customizable. Removed some bogus
|
|
* Int3()'s in low level net code.
|
|
*
|
|
* 7 12/18/98 1:13a Dave
|
|
* Rough 1024x768 support for Direct3D. Proper detection and usage through
|
|
* the launcher.
|
|
*
|
|
* 6 12/06/98 2:36p Dave
|
|
* Drastically improved nebula fogging.
|
|
*
|
|
* 5 11/30/98 5:31p Dave
|
|
* Fixed up Fred support for software mode.
|
|
*
|
|
* 4 11/30/98 1:07p Dave
|
|
* 16 bit conversion, first run.
|
|
*
|
|
* 3 11/11/98 5:37p Dave
|
|
* Checkin for multiplayer testing.
|
|
*
|
|
* 2 10/07/98 10:53a Dave
|
|
* Initial checkin.
|
|
*
|
|
* 1 10/07/98 10:49a Dave
|
|
*
|
|
* 84 5/20/98 9:46p John
|
|
* added code so the places in code that change half the palette don't
|
|
* have to clear the screen.
|
|
*
|
|
* 83 5/18/98 11:17a John
|
|
* Fixed some bugs with software window and output window.
|
|
*
|
|
* 82 5/17/98 5:03p John
|
|
* Fixed some bugs that make the taskbar interfere with the DEBUG-only
|
|
* mouse cursor.
|
|
*
|
|
* 81 5/15/98 2:44p John
|
|
* Made windowed mode not touch the window if no handle to window found.
|
|
*
|
|
* 80 5/14/98 5:42p John
|
|
* Revamped the whole window position/mouse code for the graphics windows.
|
|
*
|
|
* 79 5/07/98 6:58p Hoffoss
|
|
* Made changes to mouse code to fix a number of problems.
|
|
*
|
|
* 78 5/06/98 5:30p John
|
|
* Removed unused cfilearchiver. Removed/replaced some unused/little used
|
|
* graphics functions, namely gradient_h and _v and pixel_sp. Put in new
|
|
* DirectX header files and libs that fixed the Direct3D alpha blending
|
|
* problems.
|
|
*
|
|
* 77 4/23/98 8:24a John
|
|
* Changed the way palette effect works so that:
|
|
* 1. If gr_flash isn't called this frame, screen shows no flash.
|
|
* 2. With hardware, only 3d portion of screen gets flashed.
|
|
*
|
|
* 76 4/21/98 5:22p John
|
|
* Fixed all the &^#@$ cursor bugs with popups. For Glide, had problem
|
|
* with mouse restoring assuming back buffer was same buffer last frame,
|
|
* for software, problems with half drawn new frames, then mouse got
|
|
* restored on top of that with old data.
|
|
*
|
|
* 75 4/14/98 12:15p John
|
|
* Made 16-bpp movies work.
|
|
*
|
|
* 74 4/11/98 12:48p John
|
|
* Made software fade out actually clear screen to black.
|
|
*
|
|
* 73 4/01/98 9:21p John
|
|
* Made NDEBUG, optimized build with no warnings or errors.
|
|
*
|
|
* 72 3/25/98 8:07p John
|
|
* Restructured software rendering into two modules; One for windowed
|
|
* debug mode and one for DirectX fullscreen.
|
|
*
|
|
* 71 3/24/98 3:58p John
|
|
* Put in (hopefully) final gamma setting code.
|
|
*
|
|
* 70 3/17/98 5:55p John
|
|
* Added code to dump Glide frames. Moved Allender's "hack" code out of
|
|
* Freespace.cpp into the proper place, graphics lib.
|
|
*
|
|
* 69 3/14/98 5:46p John
|
|
*
|
|
* 68 3/14/98 5:43p John
|
|
* Saved area under mouse cursor. Made save_Screen restore it so no mouse
|
|
* is on those screens.
|
|
*
|
|
* 67 3/12/98 8:50a John
|
|
* took out "allocating zbuffer" mprintf
|
|
*
|
|
* 66 3/10/98 4:18p John
|
|
* Cleaned up graphics lib. Took out most unused gr functions. Made D3D
|
|
* & Glide have popups and print screen. Took out all >8bpp software
|
|
* support. Made Fred zbuffer. Made zbuffer allocate dynamically to
|
|
* support Fred. Made zbuffering key off of functions rather than one
|
|
* global variable.
|
|
*
|
|
* 65 3/06/98 4:09p John
|
|
* Changed the way we do bitmap RLE'ing... this speds up HUD bitmaps by
|
|
* about 2x
|
|
*
|
|
* 64 3/05/98 4:28p John
|
|
* Made mouse cursor hide while setting palette.
|
|
*
|
|
* 63 3/02/98 5:42p John
|
|
* Removed WinAVI stuff from Freespace. Made all HUD gauges wriggle from
|
|
* afterburner. Made gr_set_clip work good with negative x &y. Made
|
|
* model_caching be on by default. Made each cached model have it's own
|
|
* bitmap id. Made asteroids not rotate when model_caching is on.
|
|
*
|
|
* 62 2/24/98 3:50p John
|
|
* Made Alt+Tabbing work with Glide. Made Int3's restore Glide screen on
|
|
* next flip.
|
|
*
|
|
* 61 2/24/98 1:59p John
|
|
* Made gr_aabitmap_ex clip properly
|
|
*
|
|
* 60 2/05/98 9:21p John
|
|
* Some new Direct3D code. Added code to monitor a ton of stuff in the
|
|
* game.
|
|
*
|
|
* 59 1/19/98 6:15p John
|
|
* Fixed all my Optimized Build compiler warnings
|
|
*
|
|
* 58 1/15/98 4:07p John
|
|
* added grx_set_palette_internal which doesn't clear the screen and flip
|
|
* before setting the palette.
|
|
*
|
|
* 57 1/15/98 4:02p John
|
|
* Fixed stupid bug on my part where I called graphics rendering functions
|
|
* from another thread!!! Duh! Fixed it by setting a variable and then
|
|
* resetting the palette at the next flip.
|
|
*
|
|
* 56 1/08/98 5:06p John
|
|
* Replaced Int3 with a mprintf
|
|
*
|
|
* 55 1/08/98 3:10p John
|
|
* Undid my palette changes for interplay rev
|
|
*
|
|
* 54 1/08/98 3:03p John
|
|
*
|
|
* 53 1/05/98 11:52a Jasen
|
|
* JAS: Made graphics code work if os_get_window returns NULL when trying
|
|
* to go fullscreen.
|
|
*
|
|
* 52 12/30/97 6:47p John
|
|
* Made fade time correct
|
|
*
|
|
* 51 12/30/97 6:46p John
|
|
* Added first rev of palette fade in out functions
|
|
*
|
|
* 50 12/21/97 4:33p John
|
|
* Made debug console functions a class that registers itself
|
|
* automatically, so you don't need to add the function to
|
|
* debugfunctions.cpp.
|
|
*
|
|
* 49 12/05/97 4:26p John
|
|
* made palette set code be like it was before.
|
|
*
|
|
* 48 12/04/97 8:05p John
|
|
* added test code to brighten palette
|
|
*
|
|
* 47 12/03/97 2:16p John
|
|
* Took out blur code and fake_vram buffer.
|
|
*
|
|
* 46 12/02/97 4:00p John
|
|
* Added first rev of thruster glow, along with variable levels of
|
|
* translucency, which retquired some restructing of palman.
|
|
*
|
|
* 45 11/30/97 12:18p John
|
|
* added more 24 & 32-bpp primitives
|
|
*
|
|
* 44 11/29/97 2:06p John
|
|
* added mode 16-bpp support
|
|
*
|
|
* 43 11/21/97 11:32a John
|
|
* Added nebulas. Fixed some warpout bugs.
|
|
*
|
|
* 42 11/20/97 9:51a John
|
|
* added code to force screen to 16-bit even if rendering 8.
|
|
*
|
|
* 41 11/17/97 10:33a John
|
|
* updated force_windowed code.
|
|
*
|
|
* 40 11/14/97 3:54p John
|
|
* Added triple buffering.
|
|
*
|
|
* 39 11/14/97 3:08p Johnson
|
|
* fixed bug with fred.
|
|
*
|
|
* 38 11/14/97 12:30p John
|
|
* Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
|
|
* libs. Made 16-bpp DirectX modes know what bitmap format they're in.
|
|
*
|
|
* 37 11/06/97 4:12p John
|
|
* Took out debug code that returned NULL for DD.
|
|
*
|
|
* 36 11/05/97 12:35p John
|
|
* added correct gr_bitmap_ex that does clipping
|
|
*
|
|
*
|
|
* 35 10/31/97 9:43a John
|
|
* fixed red background color bug.
|
|
*
|
|
* 34 10/19/97 1:53p John
|
|
* hacked in a fix to a zbuffer error caused by inaccuracies.
|
|
*
|
|
* 33 10/19/97 12:55p John
|
|
* new code to lock / unlock surfaces for smooth directx integration.
|
|
*
|
|
* 32 10/15/97 4:48p John
|
|
* added 16-bpp aascaler
|
|
*
|
|
* 31 10/14/97 4:50p John
|
|
* more 16 bpp stuff.
|
|
*
|
|
* 30 10/14/97 8:08a John
|
|
* added a bunch more 16 bit support
|
|
*
|
|
* 29 10/09/97 5:23p John
|
|
* Added support for more 16-bpp functions
|
|
*
|
|
* 28 10/03/97 9:10a John
|
|
* added better antialiased line drawer
|
|
*
|
|
* 27 9/23/97 11:50a Lawrance
|
|
* jas: added xparency to rle'd bitblts
|
|
*
|
|
* 26 9/23/97 10:45a John
|
|
* made so you can tell bitblt code to rle a bitmap by passing flag to
|
|
* gr_set_bitmap
|
|
*
|
|
* 25 9/20/97 10:48a John
|
|
* added motion blur code.
|
|
*
|
|
* 24 9/09/97 10:39a Sandeep
|
|
* fixed warning level 4
|
|
*
|
|
* 23 9/07/97 2:34p John
|
|
* fixed bug with fullscreen toggling not working when in > 8bpp mode.
|
|
*
|
|
* 22 9/03/97 4:32p John
|
|
* changed bmpman to only accept ani and pcx's. made passing .pcx or .ani
|
|
* to bm_load functions not needed. Made bmpman keep track of palettes
|
|
* for bitmaps not mapped into game palettes.
|
|
*
|
|
* 21 8/26/97 11:30a John
|
|
* removed call to restoredisplymode when going from fullscreen to
|
|
* windowed, which hopefully fixes the screwey taskbar problem.
|
|
*
|
|
* 20 8/04/97 4:47p John
|
|
* added gr_aascaler.
|
|
*
|
|
* 19 7/17/97 9:31a John
|
|
* made all directX header files name start with a v
|
|
*
|
|
* 18 7/10/97 2:06p John
|
|
* added code to specify alphablending type for bitmaps.
|
|
*
|
|
* 17 6/20/97 1:50p John
|
|
* added rle code to bmpman. made gr8_aabitmap use it.
|
|
*
|
|
* 16 6/17/97 12:03p John
|
|
* Moved color/alphacolor functions into their own module. Made all color
|
|
* functions be part of the low-level graphics drivers, not just the
|
|
* grsoft.
|
|
*
|
|
* 15 6/13/97 5:35p John
|
|
* added some antialiased bitmaps and lines
|
|
*
|
|
* 14 6/12/97 2:50a Lawrance
|
|
* bm_unlock() now passed bitmap number, not pointer
|
|
*
|
|
* 13 6/11/97 5:49p John
|
|
* Changed palette code to only recalculate alphacolors when needed, not
|
|
* when palette changes.
|
|
*
|
|
* 12 6/11/97 1:12p John
|
|
* Started fixing all the text colors in the game.
|
|
*
|
|
* 11 6/06/97 5:03p John
|
|
* fixed bug withalpha colors failing after gr_init
|
|
*
|
|
* 10 6/06/97 4:41p John
|
|
* Fixed alpha colors to be smoothly integrated into gr_set_color_fast
|
|
* code.
|
|
*
|
|
* 9 5/29/97 3:09p John
|
|
* Took out debug menu.
|
|
* Made software scaler draw larger bitmaps.
|
|
* Optimized Direct3D some.
|
|
*
|
|
* 8 5/16/97 9:11a John
|
|
* fixed bug that made Ctrl+Break in fullscreen hang
|
|
*
|
|
* 7 5/14/97 4:40p John
|
|
* took out mprintf
|
|
*
|
|
* 6 5/14/97 4:38p John
|
|
* Fixed print_screen bug.
|
|
*
|
|
* 5 5/14/97 2:09p John
|
|
* made fullscreen use 254 palette entries. Used
|
|
* CreateCompatibleDC(NULL) Instead of GetDC(HWND_DESKTOP) because the
|
|
* GetDC method fails when you change screen depth dynamically under NT.
|
|
*
|
|
* 4 5/14/97 10:53a John
|
|
* fixed some discrepencies between d3d and software palette setting.
|
|
*
|
|
* 3 5/14/97 8:53a John
|
|
* Fixed a palette bug when switching into/outof d3d mode.
|
|
*
|
|
* 2 5/13/97 12:39p John
|
|
* Got fullscreen mode working.
|
|
*
|
|
* 1 5/12/97 12:14p John
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include <math.h>
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
|
|
#include "osapi/osapi.h"
|
|
#include "graphics/2d.h"
|
|
#include "bmpman/bmpman.h"
|
|
#include "io/key.h"
|
|
#include "math/floating.h"
|
|
#include "palman/palman.h"
|
|
#include "graphics/grsoft.h"
|
|
#include "graphics/grinternal.h"
|
|
|
|
// Headers for 2d functions
|
|
#include "graphics/pixel.h"
|
|
#include "graphics/line.h"
|
|
#include "graphics/scaler.h"
|
|
#include "graphics/tmapper.h"
|
|
#include "graphics/circle.h"
|
|
#include "graphics/shade.h"
|
|
#include "graphics/rect.h"
|
|
#include "graphics/gradient.h"
|
|
#include "pcxutils/pcxutils.h"
|
|
#include "osapi/osapi.h"
|
|
#include "io/mouse.h"
|
|
#include "graphics/font.h"
|
|
#include "io/timer.h"
|
|
#include "graphics/colors.h"
|
|
#include "graphics/bitblt.h"
|
|
|
|
#ifdef _WIN32
|
|
// Windows specific
|
|
|
|
// This structure is the same as LOGPALETTE except that LOGPALETTE
|
|
// requires you to malloc out space for the palette, which just isn't
|
|
// worth the trouble.
|
|
|
|
typedef struct {
|
|
WORD palVersion;
|
|
WORD palNumEntries;
|
|
PALETTEENTRY palPalEntry[256];
|
|
} EZ_LOGPALETTE;
|
|
|
|
// This structure is the same as BITMAPINFO except that BITMAPINFO
|
|
// requires you to malloc out space for the palette, which just isn't
|
|
// worth the trouble. I also went ahead and threw a handy union to
|
|
// easily reference the hicolor masks in 15/16 bpp modes.
|
|
typedef struct {
|
|
BITMAPINFOHEADER Header;
|
|
union {
|
|
RGBQUAD aColors[256];
|
|
ushort PalIndex[256];
|
|
uint hicolor_masks[3];
|
|
} Colors;
|
|
} EZ_BITMAPINFO;
|
|
|
|
EZ_BITMAPINFO DibInfo;
|
|
HBITMAP hDibSection = NULL;
|
|
HBITMAP hOldBitmap = NULL;
|
|
HDC hDibDC = NULL;
|
|
void *lpDibBits=NULL;
|
|
|
|
HPALETTE hOldPalette=NULL, hPalette = NULL;
|
|
#endif // ifdef WIN32
|
|
|
|
int Gr_soft_inited = 0;
|
|
|
|
static volatile int Grsoft_activated = 0; // If set, that means application got focus, so reset palette
|
|
|
|
void gr_buffer_release()
|
|
{
|
|
if ( hPalette ) {
|
|
if (hDibDC)
|
|
SelectPalette( hDibDC, hOldPalette, FALSE );
|
|
if (!DeleteObject(hPalette)) {
|
|
mprintf(( "JOHN: Couldn't delete palette object\n" ));
|
|
}
|
|
hPalette = NULL;
|
|
}
|
|
|
|
if ( hDibDC ) {
|
|
SelectObject(hDibDC, hOldBitmap );
|
|
DeleteDC(hDibDC);
|
|
hDibDC = NULL;
|
|
}
|
|
|
|
if ( hDibSection ) {
|
|
DeleteObject(hDibSection);
|
|
hDibSection = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void gr_buffer_create( int w, int h, int bpp )
|
|
{
|
|
int i;
|
|
|
|
if (w & 3) {
|
|
Int3(); // w must be multiple 4
|
|
return;
|
|
}
|
|
|
|
gr_buffer_release();
|
|
|
|
memset( &DibInfo, 0, sizeof(EZ_BITMAPINFO));
|
|
DibInfo.Header.biSize = sizeof(BITMAPINFOHEADER);
|
|
DibInfo.Header.biWidth = w;
|
|
DibInfo.Header.biHeight = h;
|
|
DibInfo.Header.biPlanes = 1;
|
|
DibInfo.Header.biClrUsed = 0;
|
|
|
|
switch( bpp ) {
|
|
case 8:
|
|
Gr_red.bits = 8;
|
|
Gr_red.shift = 16;
|
|
Gr_red.scale = 1;
|
|
Gr_red.mask = 0xff0000;
|
|
|
|
Gr_green.bits = 8;
|
|
Gr_green.shift = 8;
|
|
Gr_green.scale = 1;
|
|
Gr_green.mask = 0xff00;
|
|
|
|
Gr_blue.bits = 8;
|
|
Gr_blue.shift = 0;
|
|
Gr_blue.scale = 1;
|
|
Gr_blue.mask = 0xff;
|
|
|
|
DibInfo.Header.biCompression = BI_RGB;
|
|
DibInfo.Header.biBitCount = 8;
|
|
for (i=0; i<256; i++ ) {
|
|
DibInfo.Colors.aColors[i].rgbRed = 0;
|
|
DibInfo.Colors.aColors[i].rgbGreen = 0;
|
|
DibInfo.Colors.aColors[i].rgbBlue = 0;
|
|
DibInfo.Colors.aColors[i].rgbReserved = 0;
|
|
}
|
|
break;
|
|
|
|
case 15:
|
|
Gr_red.bits = 5;
|
|
Gr_red.shift = 10;
|
|
Gr_red.scale = 8;
|
|
Gr_red.mask = 0x7C00;
|
|
|
|
Gr_green.bits = 5;
|
|
Gr_green.shift = 5;
|
|
Gr_green.scale = 8;
|
|
Gr_green.mask = 0x3E0;
|
|
|
|
Gr_blue.bits = 5;
|
|
Gr_blue.shift = 0;
|
|
Gr_blue.scale = 8;
|
|
Gr_blue.mask = 0x1F;
|
|
|
|
DibInfo.Header.biCompression = BI_BITFIELDS;
|
|
DibInfo.Header.biBitCount = 16;
|
|
DibInfo.Colors.hicolor_masks[0] = Gr_red.mask;
|
|
DibInfo.Colors.hicolor_masks[1] = Gr_green.mask;
|
|
DibInfo.Colors.hicolor_masks[2] = Gr_blue.mask;
|
|
|
|
|
|
break;
|
|
|
|
case 16:
|
|
Gr_red.bits = 5;
|
|
Gr_red.shift = 11;
|
|
Gr_red.scale = 8;
|
|
Gr_red.mask = 0xF800;
|
|
|
|
Gr_green.bits = 6;
|
|
Gr_green.shift = 5;
|
|
Gr_green.scale = 4;
|
|
Gr_green.mask = 0x7E0;
|
|
|
|
Gr_blue.bits = 5;
|
|
Gr_blue.shift = 0;
|
|
Gr_blue.scale = 8;
|
|
Gr_blue.mask = 0x1F;
|
|
|
|
DibInfo.Header.biCompression = BI_BITFIELDS;
|
|
DibInfo.Header.biBitCount = 16;
|
|
DibInfo.Colors.hicolor_masks[0] = Gr_red.mask;
|
|
DibInfo.Colors.hicolor_masks[1] = Gr_green.mask;
|
|
DibInfo.Colors.hicolor_masks[2] = Gr_blue.mask;
|
|
break;
|
|
|
|
case 24:
|
|
case 32:
|
|
Gr_red.bits = 8;
|
|
Gr_red.shift = 16;
|
|
Gr_red.scale = 1;
|
|
Gr_red.mask = 0xff0000;
|
|
|
|
Gr_green.bits = 8;
|
|
Gr_green.shift = 8;
|
|
Gr_green.scale = 1;
|
|
Gr_green.mask = 0xff00;
|
|
|
|
Gr_blue.bits = 8;
|
|
Gr_blue.shift = 0;
|
|
Gr_blue.scale = 1;
|
|
Gr_blue.mask = 0xff;
|
|
|
|
DibInfo.Header.biCompression = BI_RGB;
|
|
DibInfo.Header.biBitCount = (unsigned short)(bpp);
|
|
break;
|
|
|
|
default:
|
|
Int3(); // Illegal bpp
|
|
}
|
|
|
|
lpDibBits = NULL;
|
|
|
|
hDibDC = CreateCompatibleDC(NULL);
|
|
hDibSection = CreateDIBSection(hDibDC,(BITMAPINFO *)&DibInfo,DIB_RGB_COLORS,&lpDibBits,NULL,NULL);
|
|
hOldBitmap = (HBITMAP)SelectObject(hDibDC, hDibSection );
|
|
|
|
if ( hDibSection == NULL ) {
|
|
Int3(); // couldn't allocate dib section
|
|
}
|
|
}
|
|
|
|
|
|
// This makes a best-fit palette from the 256 target colors and
|
|
// the system colors which should look better than only using the
|
|
// colors in the range 10-246, but it will totally reorder the palette.
|
|
// All colors get changed in target_palette.
|
|
|
|
|
|
HPALETTE gr_create_palette_0(ubyte * target_palette)
|
|
{
|
|
EZ_LOGPALETTE LogicalPalette;
|
|
HDC ScreenDC;
|
|
HPALETTE hpal,hpalOld;
|
|
PALETTEENTRY pe[256];
|
|
int NumSysColors, NumColors;
|
|
int i;
|
|
|
|
// Create a 1-1 mapping of the system palette
|
|
LogicalPalette.palVersion = 0x300;
|
|
LogicalPalette.palNumEntries = 256;
|
|
|
|
// Pack in all the colors
|
|
for (i=0;i<256; i++) {
|
|
LogicalPalette.palPalEntry[i].peRed = target_palette[i*3+0];
|
|
LogicalPalette.palPalEntry[i].peGreen = target_palette[i*3+1];
|
|
LogicalPalette.palPalEntry[i].peBlue = target_palette[i*3+2];
|
|
LogicalPalette.palPalEntry[i].peFlags = 0; //PC_EXPLICIT;
|
|
}
|
|
|
|
hpal = CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
|
|
ScreenDC = CreateCompatibleDC(NULL);
|
|
|
|
if ( !(GetDeviceCaps(ScreenDC,RASTERCAPS) & RC_PALETTE) ) {
|
|
DeleteDC(ScreenDC);
|
|
return hpal;
|
|
}
|
|
|
|
NumSysColors = GetDeviceCaps( ScreenDC, NUMCOLORS );
|
|
NumColors = GetDeviceCaps( ScreenDC, SIZEPALETTE );
|
|
|
|
// Reset all the Palette Manager tables
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_NOSTATIC );
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_STATIC );
|
|
|
|
// Enter our palette's values into the free slots
|
|
hpalOld=SelectPalette( ScreenDC, hpal, FALSE );
|
|
RealizePalette( ScreenDC );
|
|
SelectPalette( ScreenDC, hpalOld, FALSE );
|
|
|
|
GetSystemPaletteEntries(ScreenDC,0,NumColors,pe);
|
|
|
|
for (i=0; i<NumSysColors/2; i++ ) {
|
|
pe[i].peFlags = 0;
|
|
}
|
|
for (; i<NumColors - NumSysColors/2; i++ ) {
|
|
pe[i].peFlags = PC_NOCOLLAPSE;
|
|
}
|
|
for (; i<NumColors; i++ ) {
|
|
pe[i].peFlags = 0;
|
|
}
|
|
ResizePalette( hpal, NumColors);
|
|
SetPaletteEntries( hpal, 0, NumColors, pe );
|
|
|
|
for (i=0; i<256; i++ ) {
|
|
target_palette[i*3+0] = pe[i].peRed;
|
|
target_palette[i*3+1] = pe[i].peGreen;
|
|
target_palette[i*3+2] = pe[i].peBlue;
|
|
}
|
|
|
|
DeleteDC(ScreenDC);
|
|
|
|
return hpal;
|
|
}
|
|
|
|
HPALETTE gr_create_palette_256( ubyte * target_palette )
|
|
{
|
|
EZ_LOGPALETTE LogicalPalette;
|
|
int i;
|
|
|
|
// Pack in all the colors
|
|
for (i=0;i<256; i++) {
|
|
LogicalPalette.palPalEntry[i].peRed = target_palette[i*3+0];
|
|
LogicalPalette.palPalEntry[i].peGreen = target_palette[i*3+1];
|
|
LogicalPalette.palPalEntry[i].peBlue = target_palette[i*3+2];
|
|
LogicalPalette.palPalEntry[i].peFlags = 0; //PC_RESERVED; //PC_EXPLICIT;
|
|
}
|
|
|
|
// Create a 1-1 mapping of the system palette
|
|
LogicalPalette.palVersion = 0x300;
|
|
LogicalPalette.palNumEntries = 256;
|
|
|
|
return CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
}
|
|
|
|
// This makes an indentity logical palette that saves entries 10-246
|
|
// and leaves them in place. Colors 0-9 and 246-255 get changed in
|
|
// target_palette. trash_flag tells us whether to trash the system palette
|
|
// or not
|
|
HPALETTE gr_create_palette_236( ubyte * target_palette )
|
|
{
|
|
EZ_LOGPALETTE LogicalPalette;
|
|
HDC ScreenDC;
|
|
int NumSysColors, NumColors, UserLowest, UserHighest;
|
|
int i;
|
|
|
|
// Pack in all the colors
|
|
for (i=0;i<256; i++) {
|
|
LogicalPalette.palPalEntry[i].peRed = target_palette[i*3+0];
|
|
LogicalPalette.palPalEntry[i].peGreen = target_palette[i*3+1];
|
|
LogicalPalette.palPalEntry[i].peBlue = target_palette[i*3+2];
|
|
LogicalPalette.palPalEntry[i].peFlags = 0; //PC_EXPLICIT;
|
|
}
|
|
|
|
// Create a 1-1 mapping of the system palette
|
|
LogicalPalette.palVersion = 0x300;
|
|
LogicalPalette.palNumEntries = 256;
|
|
|
|
ScreenDC = CreateCompatibleDC(NULL);
|
|
|
|
// Reset all the Palette Manager tables
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_NOSTATIC );
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_STATIC );
|
|
|
|
if ( !(GetDeviceCaps(ScreenDC,RASTERCAPS) & RC_PALETTE) ) {
|
|
DeleteDC(ScreenDC);
|
|
return CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
}
|
|
|
|
NumSysColors = GetDeviceCaps( ScreenDC, NUMCOLORS );
|
|
NumColors = GetDeviceCaps( ScreenDC, SIZEPALETTE );
|
|
|
|
Assert( NumColors <= 256 );
|
|
|
|
UserLowest = NumSysColors/2; // 10 normally
|
|
UserHighest = NumColors - NumSysColors/2 - 1; // 245 normally
|
|
|
|
Assert( (UserHighest - UserLowest + 1) >= 236 );
|
|
|
|
GetSystemPaletteEntries(ScreenDC,0,NumSysColors/2,LogicalPalette.palPalEntry);
|
|
GetSystemPaletteEntries(ScreenDC,UserHighest+1,NumSysColors/2,LogicalPalette.palPalEntry+1+UserHighest);
|
|
|
|
DeleteDC(ScreenDC);
|
|
|
|
for (i=0; i<256; i++ ) {
|
|
|
|
if ( (i >= UserLowest) && (i<=UserHighest) ) {
|
|
LogicalPalette.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
|
|
} else
|
|
LogicalPalette.palPalEntry[i].peFlags = 0;
|
|
|
|
target_palette[i*3+0] = LogicalPalette.palPalEntry[i].peRed;
|
|
target_palette[i*3+1] = LogicalPalette.palPalEntry[i].peGreen;
|
|
target_palette[i*3+2] = LogicalPalette.palPalEntry[i].peBlue;
|
|
}
|
|
|
|
return CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
}
|
|
|
|
HPALETTE gr_create_palette_254( ubyte * target_palette )
|
|
{
|
|
EZ_LOGPALETTE LogicalPalette;
|
|
HDC ScreenDC;
|
|
int NumSysColors, NumColors, UserLowest, UserHighest;
|
|
int i;
|
|
|
|
// Pack in all the colors
|
|
for (i=0;i<256; i++) {
|
|
LogicalPalette.palPalEntry[i].peRed = target_palette[i*3+0];
|
|
LogicalPalette.palPalEntry[i].peGreen = target_palette[i*3+1];
|
|
LogicalPalette.palPalEntry[i].peBlue = target_palette[i*3+2];
|
|
LogicalPalette.palPalEntry[i].peFlags = 0; //PC_EXPLICIT;
|
|
}
|
|
|
|
// Create a 1-1 mapping of the system palette
|
|
LogicalPalette.palVersion = 0x300;
|
|
LogicalPalette.palNumEntries = 256;
|
|
|
|
ScreenDC = CreateCompatibleDC(NULL);
|
|
|
|
// Reset all the Palette Manager tables
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_NOSTATIC );
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_STATIC );
|
|
|
|
if ( !(GetDeviceCaps(ScreenDC,RASTERCAPS) & RC_PALETTE) ) {
|
|
DeleteDC(ScreenDC);
|
|
return CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
}
|
|
|
|
SetSystemPaletteUse( ScreenDC, SYSPAL_NOSTATIC );
|
|
NumSysColors = 2;
|
|
NumColors = GetDeviceCaps( ScreenDC, SIZEPALETTE );
|
|
|
|
Assert( NumColors <= 256 );
|
|
|
|
UserLowest = NumSysColors/2; // 10 normally
|
|
UserHighest = NumColors - NumSysColors/2 - 1; // 245 normally
|
|
|
|
Assert( (UserHighest - UserLowest + 1) >= 236 );
|
|
|
|
GetSystemPaletteEntries(ScreenDC,0,NumSysColors/2,LogicalPalette.palPalEntry);
|
|
GetSystemPaletteEntries(ScreenDC,UserHighest+1,NumSysColors/2,LogicalPalette.palPalEntry+1+UserHighest);
|
|
|
|
DeleteDC(ScreenDC);
|
|
|
|
for (i=0; i<256; i++ ) {
|
|
|
|
if ( (i >= UserLowest) && (i<=UserHighest) ) {
|
|
LogicalPalette.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
|
|
} else
|
|
LogicalPalette.palPalEntry[i].peFlags = 0;
|
|
|
|
target_palette[i*3+0] = LogicalPalette.palPalEntry[i].peRed;
|
|
target_palette[i*3+1] = LogicalPalette.palPalEntry[i].peGreen;
|
|
target_palette[i*3+2] = LogicalPalette.palPalEntry[i].peBlue;
|
|
}
|
|
|
|
return CreatePalette( (LOGPALETTE *)&LogicalPalette );
|
|
}
|
|
|
|
void grx_set_palette_internal( ubyte * new_pal )
|
|
{
|
|
if ( hPalette ) {
|
|
if (hDibDC)
|
|
SelectPalette( hDibDC, hOldPalette, FALSE );
|
|
if (!DeleteObject(hPalette)) {
|
|
mprintf(( "JOHN: Couldn't delete palette object\n" ));
|
|
}
|
|
hPalette = NULL;
|
|
}
|
|
|
|
|
|
// Make sure color 0 is black
|
|
if ( (new_pal[0]!=0) || (new_pal[1]!=0) || (new_pal[2]!=0) ) {
|
|
// color 0 isn't black!! switch it!
|
|
int i;
|
|
int black_index = -1;
|
|
|
|
for (i=1; i<256; i++ ) {
|
|
if ( (new_pal[i*3+0]==0) && (new_pal[i*3+1]==0) && (new_pal[i*3+2]==0) ) {
|
|
black_index = i;
|
|
break;
|
|
}
|
|
}
|
|
if ( black_index > -1 ) {
|
|
// swap black and color 0, so color 0 is black
|
|
ubyte tmp[3];
|
|
tmp[0] = new_pal[black_index*3+0];
|
|
tmp[1] = new_pal[black_index*3+1];
|
|
tmp[2] = new_pal[black_index*3+2];
|
|
|
|
new_pal[black_index*3+0] = new_pal[0];
|
|
new_pal[black_index*3+1] = new_pal[1];
|
|
new_pal[black_index*3+2] = new_pal[2];
|
|
|
|
new_pal[0] = tmp[0];
|
|
new_pal[1] = tmp[1];
|
|
new_pal[2] = tmp[2];
|
|
} else {
|
|
// no black in palette, force color 0 to be black.
|
|
new_pal[0] = 0;
|
|
new_pal[1] = 0;
|
|
new_pal[2] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if ( gr_screen.bits_per_pixel==8 ) {
|
|
|
|
// Name n_preserved One-one Speed Windowed?
|
|
// -------------------------------------------------------------------
|
|
// gr_create_palette_256 256 0-255 Slow Yes
|
|
// gr_create_palette_254 254 1-254 Fast No
|
|
// gr_create_palette_236 236 10-245 Fast Yes
|
|
// gr_create_palette_0 0 none Fast Yes
|
|
|
|
/*
|
|
n_preserved = 256;
|
|
|
|
if ( n_preserved <= 0 ) {
|
|
hPalette = gr_create_palette_0(new_pal); // No colors mapped one-to-one, but probably has close to all 256 colors in it somewhere.
|
|
} else if ( n_preserved <= 236 ) {
|
|
hPalette = gr_create_palette_236(new_pal); // All colors except low 10 and high 10 mapped one-to-one
|
|
} else if ( n_preserved <= 254 ) {
|
|
hPalette = gr_create_palette_254(new_pal); // All colors except 0 and 255 mapped one-to-one, but changes system colors. Not pretty in a window.
|
|
} else {
|
|
*/
|
|
hPalette = gr_create_palette_256(new_pal); // All 256 mapped one-to-one, but BLT's are slow.
|
|
|
|
if ( hDibDC ) {
|
|
int i;
|
|
for (i=0; i<256; i++ ) {
|
|
DibInfo.Colors.aColors[i].rgbRed = new_pal[i*3+0];
|
|
DibInfo.Colors.aColors[i].rgbGreen = new_pal[i*3+1];
|
|
DibInfo.Colors.aColors[i].rgbBlue = new_pal[i*3+2];
|
|
DibInfo.Colors.aColors[i].rgbReserved = 0;
|
|
}
|
|
|
|
hOldPalette = SelectPalette( hDibDC, hPalette, FALSE );
|
|
SetDIBColorTable( hDibDC, 0, 256, DibInfo.Colors.aColors );
|
|
}
|
|
} else {
|
|
hPalette = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void grx_set_palette( ubyte * new_pal, int is_alphacolor )
|
|
{
|
|
if ( hPalette ) {
|
|
Mouse_hidden++;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
}
|
|
|
|
grx_set_palette_internal(new_pal);
|
|
}
|
|
|
|
|
|
void grx_print_screen(char * filename)
|
|
{
|
|
int i;
|
|
ubyte **row_data = (ubyte **)malloc( gr_screen.max_h * sizeof(ubyte *) );
|
|
if ( !row_data ) {
|
|
mprintf(( "couldn't allocate enough memory to dump screen\n" ));
|
|
return;
|
|
}
|
|
|
|
gr_lock();
|
|
|
|
for (i=0; i<gr_screen.max_h; i++ ) {
|
|
row_data[i] = GR_SCREEN_PTR(ubyte,0,i);
|
|
}
|
|
|
|
pcx_write_bitmap( filename, gr_screen.max_w, gr_screen.max_h, row_data, Gr_current_palette );
|
|
|
|
gr_unlock();
|
|
|
|
free(row_data);
|
|
}
|
|
|
|
|
|
uint gr_soft_lock()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void gr_soft_unlock()
|
|
{
|
|
}
|
|
|
|
|
|
void grx_set_palette_internal( ubyte * new_pal );
|
|
|
|
int Grx_mouse_saved = 0;
|
|
int Grx_mouse_saved_x1 = 0;
|
|
int Grx_mouse_saved_y1 = 0;
|
|
int Grx_mouse_saved_x2 = 0;
|
|
int Grx_mouse_saved_y2 = 0;
|
|
int Grx_mouse_saved_w = 0;
|
|
int Grx_mouse_saved_h = 0;
|
|
#define MAX_SAVE_SIZE (32*32)
|
|
ubyte Grx_mouse_saved_data[MAX_SAVE_SIZE];
|
|
|
|
// Clamps X between R1 and R2
|
|
#define CLAMP(x,r1,r2) do { if ( (x) < (r1) ) (x) = (r1); else if ((x) > (r2)) (x) = (r2); } while(0)
|
|
|
|
void grx_save_mouse_area(int x, int y, int w, int h )
|
|
{
|
|
Grx_mouse_saved_x1 = x;
|
|
Grx_mouse_saved_y1 = y;
|
|
Grx_mouse_saved_x2 = x+w-1;
|
|
Grx_mouse_saved_y2 = y+h-1;
|
|
|
|
CLAMP(Grx_mouse_saved_x1, gr_screen.clip_left, gr_screen.clip_right );
|
|
CLAMP(Grx_mouse_saved_x2, gr_screen.clip_left, gr_screen.clip_right );
|
|
CLAMP(Grx_mouse_saved_y1, gr_screen.clip_top, gr_screen.clip_bottom );
|
|
CLAMP(Grx_mouse_saved_y2, gr_screen.clip_top, gr_screen.clip_bottom );
|
|
|
|
Grx_mouse_saved_w = Grx_mouse_saved_x2 - Grx_mouse_saved_x1 + 1;
|
|
Grx_mouse_saved_h = Grx_mouse_saved_y2 - Grx_mouse_saved_y1 + 1;
|
|
|
|
if ( Grx_mouse_saved_w < 1 ) return;
|
|
if ( Grx_mouse_saved_h < 1 ) return;
|
|
|
|
// Make sure we're not saving too much!
|
|
Assert( (Grx_mouse_saved_w*Grx_mouse_saved_h) <= MAX_SAVE_SIZE );
|
|
|
|
Grx_mouse_saved = 1;
|
|
|
|
gr_lock();
|
|
|
|
ubyte *sptr, *dptr;
|
|
|
|
dptr = Grx_mouse_saved_data;
|
|
|
|
for (int i=0; i<Grx_mouse_saved_h; i++ ) {
|
|
sptr = GR_SCREEN_PTR(ubyte,Grx_mouse_saved_x1,Grx_mouse_saved_y1+i);
|
|
|
|
for(int j=0; j<Grx_mouse_saved_w; j++ ) {
|
|
*dptr++ = *sptr++;
|
|
}
|
|
}
|
|
|
|
gr_unlock();
|
|
}
|
|
|
|
|
|
void grx_restore_mouse_area()
|
|
{
|
|
if ( !Grx_mouse_saved ) {
|
|
return;
|
|
}
|
|
|
|
gr_lock();
|
|
|
|
ubyte *sptr, *dptr;
|
|
|
|
sptr = Grx_mouse_saved_data;
|
|
|
|
for (int i=0; i<Grx_mouse_saved_h; i++ ) {
|
|
dptr = GR_SCREEN_PTR(ubyte,Grx_mouse_saved_x1,Grx_mouse_saved_y1+i);
|
|
|
|
for(int j=0; j<Grx_mouse_saved_w; j++ ) {
|
|
*dptr++ = *sptr++;
|
|
}
|
|
}
|
|
|
|
gr_unlock();
|
|
}
|
|
|
|
|
|
void gr_soft_activate(int active)
|
|
{
|
|
if ( active ) {
|
|
Grsoft_activated++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int Palette_flashed = 0;
|
|
static int Palette_flashed_last_frame = 0;
|
|
|
|
void grx_change_palette( ubyte *pal );
|
|
|
|
void grx_flip()
|
|
{
|
|
if ( (!Palette_flashed) && (Palette_flashed_last_frame) ) {
|
|
// Reset flash
|
|
grx_change_palette( gr_palette );
|
|
}
|
|
|
|
Palette_flashed_last_frame = Palette_flashed;
|
|
Palette_flashed = 0;
|
|
|
|
// If program reactivated, flip set new palette.
|
|
// We do the cnt temporary variable because Grsoft_activated
|
|
// can be set during interrupts.
|
|
|
|
int cnt = Grsoft_activated;
|
|
if ( cnt ) {
|
|
Grsoft_activated -= cnt;
|
|
|
|
ubyte new_pal[768];
|
|
memcpy( new_pal, gr_palette, 768 );
|
|
grx_set_palette_internal( new_pal ); // Call internal one so it doesn't clear screen and call flip
|
|
}
|
|
|
|
gr_reset_clip();
|
|
|
|
// if (0) {
|
|
// int i;
|
|
// for (i=0; i<gr_screen.max_h; i++ ) {
|
|
// memset( gr_screen.row_data[i], i & 255, abs(gr_screen.rowsize) );
|
|
// }
|
|
// }
|
|
|
|
int mx, my;
|
|
|
|
Grx_mouse_saved = 0; // assume not saved
|
|
|
|
mouse_eval_deltas();
|
|
if ( mouse_is_visible() ) {
|
|
gr_reset_clip();
|
|
mouse_get_pos( &mx, &my );
|
|
grx_save_mouse_area(mx,my,32,32);
|
|
if ( Gr_cursor == -1 ) {
|
|
gr_set_color(255,255,255);
|
|
gr_line( mx, my, mx+7, my + 7 );
|
|
gr_line( mx, my, mx+5, my );
|
|
gr_line( mx, my, mx, my+5 );
|
|
} else {
|
|
gr_set_bitmap(Gr_cursor);
|
|
gr_bitmap( mx, my );
|
|
}
|
|
}
|
|
|
|
fix t1, t2, d, t;
|
|
|
|
HWND hwnd = (HWND)os_get_window();
|
|
|
|
if ( hwnd ) {
|
|
int x = gr_screen.offset_x;
|
|
int y = gr_screen.offset_y;
|
|
int w = gr_screen.clip_width;
|
|
int h = gr_screen.clip_height;
|
|
|
|
HPALETTE hOldPalette = NULL;
|
|
HDC hdc = GetDC(hwnd);
|
|
|
|
if ( hdc ) {
|
|
t1 = timer_get_fixed_seconds();
|
|
|
|
if (hPalette) {
|
|
hOldPalette=SelectPalette(hdc,hPalette, FALSE );
|
|
uint nColors = RealizePalette( hdc );
|
|
nColors;
|
|
//if (nColors) mprintf(( "Actually set %d palette colors.\n", nColors ));
|
|
}
|
|
|
|
#if 0
|
|
BitBlt(hdc,0,h/2,w,h/2,hDibDC,x,y+h/2,SRCCOPY);
|
|
#else
|
|
BitBlt(hdc,0,0,w,h,hDibDC,x,y,SRCCOPY);
|
|
#endif
|
|
|
|
if ( hOldPalette )
|
|
SelectPalette(hdc,hOldPalette, FALSE );
|
|
|
|
ReleaseDC( hwnd, hdc );
|
|
|
|
t2 = timer_get_fixed_seconds();
|
|
d = t2 - t1;
|
|
t = (w*h*gr_screen.bytes_per_pixel)/1024;
|
|
//mprintf(( "%d MB/s\n", fixmuldiv(t,65,d) ));
|
|
|
|
}
|
|
}
|
|
|
|
if ( Grx_mouse_saved ) {
|
|
grx_restore_mouse_area();
|
|
}
|
|
}
|
|
|
|
|
|
// switch onscreen, offscreen
|
|
// Set msg to 0 if calling outside of the window handler.
|
|
void grx_flip_window(uint _hdc, int x, int y, int w, int h )
|
|
{
|
|
HDC hdc = (HDC)_hdc;
|
|
HPALETTE hOldPalette = NULL;
|
|
int min_w, min_h;
|
|
|
|
if (hPalette) {
|
|
hOldPalette=SelectPalette(hdc,hPalette, FALSE );
|
|
RealizePalette( hdc );
|
|
}
|
|
|
|
min_w = gr_screen.clip_width;
|
|
if ( w < min_w ) min_w = w;
|
|
|
|
min_h = gr_screen.clip_height;
|
|
if ( h < min_h ) min_h = h;
|
|
|
|
BitBlt(hdc,x,y,min_w,min_h,hDibDC,gr_screen.offset_x,gr_screen.offset_y,SRCCOPY);
|
|
|
|
//StretchBlt( hdc, 0, 0, w, h, hDibDC, 0, 0, 640, 480, SRCCOPY );
|
|
|
|
if ( hOldPalette ){
|
|
SelectPalette(hdc,hOldPalette, FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
// sets the clipping region & offset
|
|
void grx_set_clip(int x,int y,int w,int h)
|
|
{
|
|
gr_screen.offset_x = x;
|
|
gr_screen.offset_y = y;
|
|
|
|
gr_screen.clip_left = 0;
|
|
gr_screen.clip_right = w-1;
|
|
|
|
gr_screen.clip_top = 0;
|
|
gr_screen.clip_bottom = h-1;
|
|
|
|
// check for sanity of parameters
|
|
if ( gr_screen.clip_left+x < 0 ) {
|
|
gr_screen.clip_left = -x;
|
|
} else if ( gr_screen.clip_left+x > gr_screen.max_w-1 ) {
|
|
gr_screen.clip_left = gr_screen.max_w-1-x;
|
|
}
|
|
if ( gr_screen.clip_right+x < 0 ) {
|
|
gr_screen.clip_right = -x;
|
|
} else if ( gr_screen.clip_right+x >= gr_screen.max_w-1 ) {
|
|
gr_screen.clip_right = gr_screen.max_w-1-x;
|
|
}
|
|
|
|
if ( gr_screen.clip_top+y < 0 ) {
|
|
gr_screen.clip_top = -y;
|
|
} else if ( gr_screen.clip_top+y > gr_screen.max_h-1 ) {
|
|
gr_screen.clip_top = gr_screen.max_h-1-y;
|
|
}
|
|
|
|
if ( gr_screen.clip_bottom+y < 0 ) {
|
|
gr_screen.clip_bottom = -y;
|
|
} else if ( gr_screen.clip_bottom+y > gr_screen.max_h-1 ) {
|
|
gr_screen.clip_bottom = gr_screen.max_h-1-y;
|
|
}
|
|
|
|
gr_screen.clip_width = gr_screen.clip_right - gr_screen.clip_left + 1;
|
|
gr_screen.clip_height = gr_screen.clip_bottom - gr_screen.clip_top + 1;
|
|
}
|
|
|
|
// resets the clipping region to entire screen
|
|
//
|
|
// should call this before gr_surface_flip() if you clipped some portion of the screen but still
|
|
// want a full-screen display
|
|
void grx_reset_clip()
|
|
{
|
|
gr_screen.offset_x = 0;
|
|
gr_screen.offset_y = 0;
|
|
gr_screen.clip_left = 0;
|
|
gr_screen.clip_top = 0;
|
|
gr_screen.clip_right = gr_screen.max_w - 1;
|
|
gr_screen.clip_bottom = gr_screen.max_h - 1;
|
|
gr_screen.clip_width = gr_screen.max_w;
|
|
gr_screen.clip_height = gr_screen.max_h;
|
|
}
|
|
|
|
|
|
// Sets the current bitmap
|
|
void grx_set_bitmap( int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy )
|
|
{
|
|
gr_screen.current_alpha = alpha;
|
|
gr_screen.current_alphablend_mode = alphablend_mode;
|
|
gr_screen.current_bitblt_mode = bitblt_mode;
|
|
gr_screen.current_bitmap = bitmap_num;
|
|
gr_screen.current_bitmap_sx = sx;
|
|
gr_screen.current_bitmap_sy = sy;
|
|
}
|
|
|
|
|
|
// clears entire clipping region to black.
|
|
void grx_clear()
|
|
{
|
|
gr_lock();
|
|
|
|
int i,w;
|
|
ubyte *pDestBits;
|
|
|
|
w = gr_screen.clip_right-gr_screen.clip_left+1;
|
|
for (i=gr_screen.clip_top; i<=gr_screen.clip_bottom; i++) {
|
|
pDestBits = GR_SCREEN_PTR(ubyte,gr_screen.clip_left,i);
|
|
memset( pDestBits, 0, w );
|
|
}
|
|
|
|
gr_unlock();
|
|
}
|
|
|
|
|
|
|
|
void grx_start_frame()
|
|
{
|
|
}
|
|
|
|
void grx_stop_frame()
|
|
{
|
|
}
|
|
|
|
void gr_soft_fog_set(int fog_mode, int r, int g, int b, float near, float far)
|
|
{
|
|
}
|
|
|
|
void gr_soft_get_pixel(int x, int y, int *r, int *g, int *b)
|
|
{
|
|
}
|
|
|
|
void grx_fade_in(int instantaneous);
|
|
void grx_fade_out(int instantaneous);
|
|
void grx_flash(int r, int g, int b);
|
|
|
|
static ubyte *Gr_saved_screen = NULL;
|
|
static uint Gr_saved_screen_palette_checksum = 0;
|
|
static ubyte Gr_saved_screen_palette[768];
|
|
|
|
int gr8_save_screen()
|
|
{
|
|
int i;
|
|
gr_reset_clip();
|
|
|
|
if (gr_screen.bits_per_pixel != 8) {
|
|
mprintf(( "Save Screen only works in 8 bpp!\n" ));
|
|
return -1;
|
|
}
|
|
|
|
if ( Gr_saved_screen ) {
|
|
mprintf(( "Screen alread saved!\n" ));
|
|
return -1;
|
|
}
|
|
|
|
Gr_saved_screen = (ubyte *)malloc( gr_screen.max_w*gr_screen.max_h );
|
|
if (!Gr_saved_screen) {
|
|
mprintf(( "Couldn't get memory for saved screen!\n" ));
|
|
return -1;
|
|
}
|
|
|
|
Gr_saved_screen_palette_checksum = gr_palette_checksum;
|
|
memcpy( Gr_saved_screen_palette, gr_palette, 768 );
|
|
|
|
gr_lock();
|
|
|
|
for (i=0; i<gr_screen.max_h; i++ ) {
|
|
ubyte *dptr = GR_SCREEN_PTR(ubyte,0,i);
|
|
memcpy( &Gr_saved_screen[gr_screen.max_w*i], dptr, gr_screen.max_w );
|
|
}
|
|
|
|
gr_unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void gr8_restore_screen(int id)
|
|
{
|
|
int i;
|
|
gr_reset_clip();
|
|
|
|
if ( !Gr_saved_screen ) {
|
|
gr_clear();
|
|
return;
|
|
}
|
|
|
|
if ( Gr_saved_screen_palette_checksum != gr_palette_checksum ) {
|
|
// Palette changed! Remap the bitmap!
|
|
ubyte xlat[256];
|
|
for (i=0; i<256; i++ ) {
|
|
xlat[i] = (ubyte)palette_find( Gr_saved_screen_palette[i*3+0], Gr_saved_screen_palette[i*3+1], Gr_saved_screen_palette[i*3+2] );
|
|
}
|
|
|
|
for (i=0; i<gr_screen.max_h*gr_screen.max_w; i++ ) {
|
|
Gr_saved_screen[i] = xlat[Gr_saved_screen[i]];
|
|
}
|
|
|
|
memcpy( Gr_saved_screen_palette, gr_palette, 768 );
|
|
Gr_saved_screen_palette_checksum = gr_palette_checksum;
|
|
}
|
|
|
|
gr_lock();
|
|
|
|
for (i=0; i<gr_screen.max_h; i++ ) {
|
|
ubyte *dptr = GR_SCREEN_PTR(ubyte,0,i);
|
|
memcpy( dptr, &Gr_saved_screen[gr_screen.max_w*i], gr_screen.max_w );
|
|
}
|
|
|
|
gr_unlock();
|
|
}
|
|
|
|
|
|
void gr8_free_screen(int id)
|
|
{
|
|
if ( Gr_saved_screen ) {
|
|
free( Gr_saved_screen );
|
|
Gr_saved_screen = NULL;
|
|
}
|
|
}
|
|
|
|
static int Gr8_dump_frames = 0;
|
|
static ubyte *Gr8_dump_buffer = NULL;
|
|
static int Gr8_dump_frame_number = 0;
|
|
static int Gr8_dump_frame_count = 0;
|
|
static int Gr8_dump_frame_count_max = 0;
|
|
static int Gr8_dump_frame_size = 0;
|
|
|
|
|
|
void gr8_dump_frame_start(int first_frame, int frames_between_dumps)
|
|
{
|
|
if ( Gr8_dump_frames ) {
|
|
Int3(); // We're already dumping frames. See John.
|
|
return;
|
|
}
|
|
Gr8_dump_frames = 1;
|
|
Gr8_dump_frame_number = first_frame;
|
|
Gr8_dump_frame_count = 0;
|
|
Gr8_dump_frame_count_max = frames_between_dumps;
|
|
Gr8_dump_frame_size = 640 * 480;
|
|
|
|
if ( !Gr8_dump_buffer ) {
|
|
int size = Gr8_dump_frame_count_max * Gr8_dump_frame_size;
|
|
Gr8_dump_buffer = (ubyte *)malloc(size);
|
|
if ( !Gr8_dump_buffer ) {
|
|
Error(LOCATION, "Unable to malloc %d bytes for dump buffer", size );
|
|
}
|
|
}
|
|
}
|
|
|
|
// A hacked function to dump the frame buffer contents
|
|
void gr8_dump_screen_hack( void * dst )
|
|
{
|
|
int i;
|
|
|
|
gr_lock();
|
|
for (i = 0; i < 480; i++) {
|
|
memcpy( (ubyte *)dst+(i*640), GR_SCREEN_PTR(ubyte,0,i), 640 );
|
|
}
|
|
gr_unlock();
|
|
}
|
|
|
|
void gr8_flush_frame_dump()
|
|
{
|
|
ubyte *buffer[480];
|
|
char filename[MAX_PATH_LEN], *movie_path = "";
|
|
|
|
int i;
|
|
for (i = 0; i < Gr8_dump_frame_count; i++) {
|
|
int j;
|
|
|
|
for ( j = 0; j < 480; j++ )
|
|
buffer[j] = Gr8_dump_buffer+(i*Gr8_dump_frame_size)+(j*640);
|
|
|
|
sprintf(filename, NOX("%sfrm%04d"), movie_path, Gr8_dump_frame_number );
|
|
pcx_write_bitmap(filename, 640, 480, buffer, gr_palette);
|
|
Gr8_dump_frame_number++;
|
|
}
|
|
}
|
|
|
|
void gr8_dump_frame()
|
|
{
|
|
// A hacked function to dump the frame buffer contents
|
|
gr8_dump_screen_hack( Gr8_dump_buffer+(Gr8_dump_frame_count*Gr8_dump_frame_size) );
|
|
|
|
Gr8_dump_frame_count++;
|
|
|
|
if ( Gr8_dump_frame_count == Gr8_dump_frame_count_max ) {
|
|
gr8_flush_frame_dump();
|
|
Gr8_dump_frame_count = 0;
|
|
}
|
|
}
|
|
|
|
void grx_get_region(int front, int w, int h, ubyte *data)
|
|
{
|
|
}
|
|
|
|
// resolution checking
|
|
int gr_soft_supports_res_ingame(int res)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int gr_soft_supports_res_interface(int res)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void gr8_dump_frame_stop()
|
|
{
|
|
if ( !Gr8_dump_frames ) {
|
|
Int3(); // We're not dumping frames. See John.
|
|
return;
|
|
}
|
|
|
|
// dump any remaining frames
|
|
gr8_flush_frame_dump();
|
|
|
|
Gr8_dump_frames = 0;
|
|
if ( Gr8_dump_buffer ) {
|
|
free(Gr8_dump_buffer);
|
|
Gr8_dump_buffer = NULL;
|
|
}
|
|
}
|
|
|
|
void gr_soft_set_cull(int cull)
|
|
{
|
|
}
|
|
|
|
// cross fade
|
|
void gr_soft_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct)
|
|
{
|
|
if ( pct <= 50 ) {
|
|
gr_set_bitmap(bmap1);
|
|
gr_bitmap(x1, y1);
|
|
} else {
|
|
gr_set_bitmap(bmap2);
|
|
gr_bitmap(x2, y2);
|
|
}
|
|
}
|
|
|
|
// filter
|
|
void gr_soft_filter_set(int filter)
|
|
{
|
|
}
|
|
|
|
// tcache
|
|
int gr_soft_tcache_set(int bitmap_id, int bitmap_type, float *u_ratio, float *v_ratio, int fail_on_full = 0, int sx = -1, int sy = -1, int force = 0 )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// clear color
|
|
void gr_soft_set_clear_color(int r, int g, int b)
|
|
{
|
|
}
|
|
|
|
extern uint Gr_signature;
|
|
|
|
//extern void gr_set_palette_internal(char *name, ubyte *pal);
|
|
|
|
void gr8_set_gamma(float gamma)
|
|
{
|
|
Gr_gamma = gamma;
|
|
Gr_gamma_int = int(Gr_gamma*100);
|
|
|
|
// Create the Gamma lookup table
|
|
int i;
|
|
for (i=0; i<256; i++ ) {
|
|
int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f);
|
|
if ( v > 255 ) {
|
|
v = 255;
|
|
} else if ( v < 0 ) {
|
|
v = 0;
|
|
}
|
|
Gr_gamma_lookup[i] = v;
|
|
}
|
|
|
|
// ubyte new_pal[768];
|
|
// if ( gr_screen.bits_per_pixel!=8 ) return;
|
|
//
|
|
// for (i=0; i<768; i++ ) {
|
|
// new_pal[i] = ubyte(Gr_gamma_lookup[gr_palette[i]]);
|
|
// }
|
|
// grx_change_palette( new_pal );
|
|
|
|
gr_screen.signature = Gr_signature++;
|
|
}
|
|
|
|
void gr_soft_init()
|
|
{
|
|
// int i;
|
|
HWND hwnd = (HWND)os_get_window();
|
|
|
|
// software mode only supports 640x480
|
|
Assert(gr_screen.res == GR_640);
|
|
if(gr_screen.res != GR_640){
|
|
gr_screen.res = GR_640;
|
|
gr_screen.max_w = 640;
|
|
gr_screen.max_h = 480;
|
|
}
|
|
|
|
// Prepare the window to go full screen
|
|
if ( hwnd ) {
|
|
DWORD style, exstyle;
|
|
RECT client_rect;
|
|
|
|
exstyle = 0;
|
|
style = WS_CAPTION | WS_SYSMENU;
|
|
|
|
// Create Game Window
|
|
client_rect.left = client_rect.top = 0;
|
|
client_rect.right = gr_screen.max_w;
|
|
client_rect.bottom = gr_screen.max_h;
|
|
AdjustWindowRect(&client_rect,style,FALSE);
|
|
|
|
RECT work_rect;
|
|
SystemParametersInfo( SPI_GETWORKAREA, 0, &work_rect, 0 );
|
|
int x = work_rect.left + (( work_rect.right - work_rect.left )-(client_rect.right - client_rect.left))/2;
|
|
int y = work_rect.top;
|
|
if ( x < work_rect.left ) {
|
|
x = work_rect.left;
|
|
}
|
|
int WinX = x;
|
|
int WinY = y;
|
|
int WinW = client_rect.right - client_rect.left;
|
|
int WinH = client_rect.bottom - client_rect.top;
|
|
|
|
ShowWindow(hwnd, SW_SHOWNORMAL );
|
|
SetWindowLong( hwnd, GWL_STYLE, style );
|
|
SetWindowLong( hwnd, GWL_EXSTYLE, exstyle );
|
|
SetWindowPos( hwnd, HWND_NOTOPMOST, WinX, WinY, WinW, WinH, SWP_SHOWWINDOW );
|
|
SetActiveWindow(hwnd);
|
|
SetForegroundWindow(hwnd);
|
|
}
|
|
|
|
Palette_flashed = 0;
|
|
Palette_flashed_last_frame = 0;
|
|
|
|
gr_screen.bits_per_pixel = 8;
|
|
gr_screen.bytes_per_pixel = 1;
|
|
|
|
gr_buffer_create( gr_screen.max_w, gr_screen.max_h, gr_screen.bits_per_pixel );
|
|
|
|
gr_screen.offscreen_buffer_base = lpDibBits;
|
|
|
|
gr_screen.rowsize = DibInfo.Header.biWidth*((gr_screen.bits_per_pixel+7)/8);
|
|
Assert( DibInfo.Header.biWidth == gr_screen.max_w );
|
|
|
|
if (DibInfo.Header.biHeight > 0) {
|
|
// top down
|
|
gr_screen.offscreen_buffer = (void *)((uint)gr_screen.offscreen_buffer_base + (gr_screen.max_h - 1) * gr_screen.rowsize);
|
|
gr_screen.rowsize *= -1;
|
|
} else {
|
|
// top up
|
|
gr_screen.offscreen_buffer = gr_screen.offscreen_buffer_base;
|
|
}
|
|
|
|
grx_init_alphacolors();
|
|
|
|
gr_screen.gf_flip = grx_flip;
|
|
gr_screen.gf_flip_window = grx_flip_window;
|
|
gr_screen.gf_set_clip = grx_set_clip;
|
|
gr_screen.gf_reset_clip = grx_reset_clip;
|
|
gr_screen.gf_set_font = grx_set_font;
|
|
gr_screen.gf_set_color = grx_set_color;
|
|
gr_screen.gf_set_bitmap = grx_set_bitmap;
|
|
gr_screen.gf_create_shader = grx_create_shader;
|
|
gr_screen.gf_set_shader = grx_set_shader;
|
|
gr_screen.gf_clear = grx_clear;
|
|
// gr_screen.gf_bitmap = grx_bitmap;
|
|
// ]gr_screen.gf_bitmap_ex = grx_bitmap_ex;
|
|
|
|
gr_screen.gf_aabitmap = grx_aabitmap;
|
|
gr_screen.gf_aabitmap_ex = grx_aabitmap_ex;
|
|
|
|
gr_screen.gf_rect = grx_rect;
|
|
gr_screen.gf_shade = gr8_shade;
|
|
gr_screen.gf_string = gr8_string;
|
|
gr_screen.gf_circle = gr8_circle;
|
|
|
|
gr_screen.gf_line = gr8_line;
|
|
gr_screen.gf_aaline = gr8_aaline;
|
|
gr_screen.gf_pixel = gr8_pixel;
|
|
gr_screen.gf_scaler = gr8_scaler;
|
|
gr_screen.gf_aascaler = gr8_aascaler;
|
|
gr_screen.gf_tmapper = grx_tmapper;
|
|
|
|
gr_screen.gf_gradient = gr8_gradient;
|
|
|
|
gr_screen.gf_set_palette = grx_set_palette;
|
|
gr_screen.gf_get_color = grx_get_color;
|
|
gr_screen.gf_init_color = grx_init_color;
|
|
gr_screen.gf_init_alphacolor = grx_init_alphacolor;
|
|
gr_screen.gf_set_color_fast = grx_set_color_fast;
|
|
gr_screen.gf_print_screen = grx_print_screen;
|
|
gr_screen.gf_start_frame = grx_start_frame;
|
|
gr_screen.gf_stop_frame = grx_stop_frame;
|
|
|
|
gr_screen.gf_fade_in = grx_fade_in;
|
|
gr_screen.gf_fade_out = grx_fade_out;
|
|
gr_screen.gf_flash = grx_flash;
|
|
|
|
|
|
// Retrieves the zbuffer mode.
|
|
gr_screen.gf_zbuffer_get = gr8_zbuffer_get;
|
|
gr_screen.gf_zbuffer_set = gr8_zbuffer_set;
|
|
gr_screen.gf_zbuffer_clear = gr8_zbuffer_clear;
|
|
|
|
gr_screen.gf_save_screen = gr8_save_screen;
|
|
gr_screen.gf_restore_screen = gr8_restore_screen;
|
|
gr_screen.gf_free_screen = gr8_free_screen;
|
|
|
|
// Screen dumping stuff
|
|
gr_screen.gf_dump_frame_start = gr8_dump_frame_start;
|
|
gr_screen.gf_dump_frame_stop = gr8_dump_frame_stop;
|
|
gr_screen.gf_dump_frame = gr8_dump_frame;
|
|
|
|
// Gamma stuff
|
|
gr_screen.gf_set_gamma = gr8_set_gamma;
|
|
|
|
// Lock/unlock stuff
|
|
gr_screen.gf_lock = gr_soft_lock;
|
|
gr_screen.gf_unlock = gr_soft_unlock;
|
|
|
|
// region
|
|
gr_screen.gf_get_region = grx_get_region;
|
|
|
|
// fog stuff
|
|
gr_screen.gf_fog_set = gr_soft_fog_set;
|
|
|
|
// pixel get
|
|
gr_screen.gf_get_pixel = gr_soft_get_pixel;
|
|
|
|
// poly culling
|
|
gr_screen.gf_set_cull = gr_soft_set_cull;
|
|
|
|
// cross fade
|
|
gr_screen.gf_cross_fade = gr_soft_cross_fade;
|
|
|
|
// filter
|
|
gr_screen.gf_filter_set = gr_soft_filter_set;
|
|
|
|
// tcache set
|
|
gr_screen.gf_tcache_set = gr_soft_tcache_set;
|
|
|
|
// set clear color
|
|
gr_screen.gf_set_clear_color = gr_soft_set_clear_color;
|
|
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
}
|
|
|
|
void gr_soft_force_windowed()
|
|
{
|
|
}
|
|
|
|
void gr_soft_cleanup()
|
|
{
|
|
if (Gr_soft_inited) {
|
|
gr_buffer_release();
|
|
Gr_soft_inited = 0;
|
|
}
|
|
}
|
|
|
|
void grx_change_palette( ubyte * new_pal )
|
|
{
|
|
if ( hPalette ) {
|
|
if (hDibDC)
|
|
SelectPalette( hDibDC, hOldPalette, FALSE );
|
|
if (!DeleteObject(hPalette))
|
|
Int3();
|
|
hPalette = NULL;
|
|
}
|
|
|
|
hPalette = gr_create_palette_256(new_pal); // All 256 mapped one-to-one, but BLT's are slow.
|
|
|
|
if ( hDibDC ) {
|
|
int i;
|
|
for (i=0; i<256; i++ ) {
|
|
DibInfo.Colors.aColors[i].rgbRed = new_pal[i*3+0];
|
|
DibInfo.Colors.aColors[i].rgbGreen = new_pal[i*3+1];
|
|
DibInfo.Colors.aColors[i].rgbBlue = new_pal[i*3+2];
|
|
DibInfo.Colors.aColors[i].rgbReserved = 0;
|
|
}
|
|
|
|
hOldPalette = SelectPalette( hDibDC, hPalette, FALSE );
|
|
SetDIBColorTable( hDibDC, 0, 256, DibInfo.Colors.aColors );
|
|
}
|
|
}
|
|
|
|
void grx_flash( int r, int g, int b )
|
|
{
|
|
int t,i;
|
|
ubyte new_pal[768];
|
|
|
|
if ( (r==0) && (g==0) && (b==0) ) {
|
|
return;
|
|
}
|
|
|
|
Palette_flashed++;
|
|
|
|
for (i=0; i<256; i++ ) {
|
|
t = gr_palette[i*3+0] + r;
|
|
if ( t < 0 ) t = 0; else if (t>255) t = 255;
|
|
new_pal[i*3+0] = (ubyte)t;
|
|
|
|
t = gr_palette[i*3+1] + g;
|
|
if ( t < 0 ) t = 0; else if (t>255) t = 255;
|
|
new_pal[i*3+1] = (ubyte)t;
|
|
|
|
t = gr_palette[i*3+2] + b;
|
|
if ( t < 0 ) t = 0; else if (t>255) t = 255;
|
|
new_pal[i*3+2] = (ubyte)t;
|
|
}
|
|
|
|
grx_change_palette( new_pal );
|
|
}
|
|
|
|
|
|
static int gr_palette_faded_out = 0;
|
|
|
|
#define FADE_TIME (F1_0/4) // How long to fade out
|
|
|
|
void grx_fade_out(int instantaneous)
|
|
{
|
|
#ifndef HARDWARE_ONLY
|
|
int i;
|
|
ubyte new_pal[768];
|
|
|
|
if (!gr_palette_faded_out) {
|
|
|
|
if ( !instantaneous ) {
|
|
|
|
int count = 0;
|
|
fix start_time, stop_time, t1;
|
|
|
|
start_time = timer_get_fixed_seconds();
|
|
t1 = 0;
|
|
|
|
do {
|
|
for (i=0; i<768; i++ ) {
|
|
int c = (gr_palette[i]*(FADE_TIME-t1))/FADE_TIME;
|
|
if (c < 0 )
|
|
c = 0;
|
|
else if ( c > 255 )
|
|
c = 255;
|
|
|
|
new_pal[i] = (ubyte)c;
|
|
}
|
|
grx_change_palette( new_pal );
|
|
gr_flip();
|
|
count++;
|
|
|
|
t1 = timer_get_fixed_seconds() - start_time;
|
|
|
|
} while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
|
|
|
|
stop_time = timer_get_fixed_seconds();
|
|
|
|
mprintf(( "Took %d frames (and %.1f secs) to fade out\n", count, f2fl(stop_time-start_time) ));
|
|
|
|
}
|
|
gr_palette_faded_out = 1;
|
|
}
|
|
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
memset( new_pal, 0, 768 );
|
|
grx_change_palette( new_pal );
|
|
#else
|
|
Int3();
|
|
#endif
|
|
}
|
|
|
|
|
|
void grx_fade_in(int instantaneous)
|
|
{
|
|
#ifndef HARDWARE_ONLY
|
|
int i;
|
|
ubyte new_pal[768];
|
|
|
|
if (gr_palette_faded_out) {
|
|
|
|
if ( !instantaneous ) {
|
|
int count = 0;
|
|
fix start_time, stop_time, t1;
|
|
|
|
start_time = timer_get_fixed_seconds();
|
|
t1 = 0;
|
|
|
|
do {
|
|
for (i=0; i<768; i++ ) {
|
|
int c = (gr_palette[i]*t1)/FADE_TIME;
|
|
if (c < 0 )
|
|
c = 0;
|
|
else if ( c > 255 )
|
|
c = 255;
|
|
|
|
new_pal[i] = (ubyte)c;
|
|
}
|
|
grx_change_palette( new_pal );
|
|
gr_flip();
|
|
count++;
|
|
|
|
t1 = timer_get_fixed_seconds() - start_time;
|
|
|
|
} while ( (t1 < FADE_TIME) && (t1>=0) ); // Loop as long as time not up and timer hasn't rolled
|
|
|
|
stop_time = timer_get_fixed_seconds();
|
|
|
|
mprintf(( "Took %d frames (and %.1f secs) to fade in\n", count, f2fl(stop_time-start_time) ));
|
|
}
|
|
gr_palette_faded_out = 0;
|
|
}
|
|
|
|
memcpy( new_pal, gr_palette, 768 );
|
|
grx_change_palette( new_pal );
|
|
#else
|
|
Int3();
|
|
#endif
|
|
}
|
|
|
|
|