src/video/gem/SDL_gemvideo.c
author Patrice Mandin <patmandin@gmail.com>
Sat, 07 Oct 2017 12:00:04 +0200
branchSDL-1.2
changeset 11576 b3255371e439
parent 11571 49fa2a49574b
child 11580 b28174b10269
permissions -rw-r--r--
atari:gem: Handle padding redraw when moving window behind other windows
slouken@281
     1
/*
slouken@281
     2
    SDL - Simple DirectMedia Layer
slouken@6137
     3
    Copyright (C) 1997-2012 Sam Lantinga
slouken@281
     4
slouken@281
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@281
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@281
     9
slouken@281
    10
    This library is distributed in the hope that it will be useful,
slouken@281
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@281
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@281
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@281
    18
slouken@281
    19
    Sam Lantinga
slouken@281
    20
    slouken@libsdl.org
slouken@281
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@281
    23
slouken@281
    24
/*
patmandin@736
    25
	GEM video driver
patmandin@736
    26
patmandin@736
    27
	Patrice Mandin
patmandin@736
    28
	and work from
patmandin@736
    29
	Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
patmandin@736
    30
*/
slouken@281
    31
slouken@281
    32
/* Mint includes */
slouken@281
    33
#include <gem.h>
slouken@281
    34
#include <gemx.h>
slouken@281
    35
#include <mint/osbind.h>
slouken@557
    36
#include <mint/cookie.h>
slouken@281
    37
slouken@1358
    38
#include "SDL_endian.h"
slouken@281
    39
#include "SDL_video.h"
slouken@281
    40
#include "SDL_mouse.h"
slouken@1361
    41
#include "../SDL_sysvideo.h"
slouken@1361
    42
#include "../SDL_pixels_c.h"
slouken@1361
    43
#include "../../events/SDL_events_c.h"
slouken@1361
    44
#include "../SDL_cursor_c.h"
slouken@281
    45
patmandin@1412
    46
#include "../ataricommon/SDL_ataric2p_s.h"
patmandin@1412
    47
#include "../ataricommon/SDL_atarieddi_s.h"
patmandin@1412
    48
#include "../ataricommon/SDL_atarimxalloc_c.h"
patmandin@1412
    49
#include "../ataricommon/SDL_atarigl_c.h"
patmandin@989
    50
slouken@281
    51
#include "SDL_gemvideo.h"
slouken@281
    52
#include "SDL_gemevents_c.h"
slouken@281
    53
#include "SDL_gemmouse_c.h"
slouken@281
    54
#include "SDL_gemwm_c.h"
patmandin@1412
    55
#include "../ataricommon/SDL_xbiosevents_c.h"
patmandin@1420
    56
#include "../ataricommon/SDL_ataridevmouse_c.h"
slouken@281
    57
slouken@281
    58
/* Defines */
slouken@281
    59
patmandin@984
    60
/*#define DEBUG_VIDEO_GEM	1*/
patmandin@736
    61
slouken@281
    62
#define GEM_VID_DRIVER_NAME "gem"
slouken@281
    63
patmandin@737
    64
#undef MIN
patmandin@737
    65
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
patmandin@737
    66
#undef MAX
patmandin@737
    67
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
patmandin@737
    68
slouken@281
    69
/* Variables */
slouken@281
    70
slouken@281
    71
static unsigned char vdi_index[256] = {
slouken@281
    72
	0,  2,  3,  6,  4,  7,  5,   8,
slouken@281
    73
	9, 10, 11, 14, 12, 15, 13, 255
slouken@281
    74
};
slouken@281
    75
patmandin@5653
    76
static const char empty_name[]="";
slouken@281
    77
slouken@281
    78
/* Initialization/Query functions */
slouken@281
    79
static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
slouken@281
    80
static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
slouken@281
    81
static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
slouken@281
    82
static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
slouken@281
    83
static void GEM_VideoQuit(_THIS);
slouken@281
    84
slouken@281
    85
/* Hardware surface functions */
slouken@281
    86
static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
slouken@281
    87
static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
slouken@281
    88
static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
slouken@281
    89
static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
slouken@281
    90
static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
slouken@281
    91
static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
slouken@281
    92
slouken@281
    93
/* Internal functions */
slouken@281
    94
static void GEM_FreeBuffers(_THIS);
slouken@319
    95
static void GEM_ClearScreen(_THIS);
patmandin@11569
    96
static void GEM_ClearRect(_THIS, short *pxy);
patmandin@11569
    97
static void GEM_ClearRectXYWH(_THIS, short *rect);
patmandin@1074
    98
static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
slouken@319
    99
static void GEM_LockScreen(_THIS);
slouken@319
   100
static void GEM_UnlockScreen(_THIS);
patmandin@11576
   101
static void refresh_window(_THIS, int winhandle, short *rect, SDL_bool pad_only);
slouken@281
   102
slouken@1361
   103
#if SDL_VIDEO_OPENGL
patmandin@984
   104
/* OpenGL functions */
patmandin@984
   105
static void GEM_GL_SwapBuffers(_THIS);
patmandin@984
   106
#endif
patmandin@984
   107
slouken@281
   108
/* GEM driver bootstrap functions */
slouken@281
   109
slouken@281
   110
static int GEM_Available(void)
slouken@281
   111
{
slouken@281
   112
	/* Test if AES available */
slouken@557
   113
	if (appl_init() == -1)
slouken@281
   114
		return 0;
slouken@281
   115
slouken@281
   116
	appl_exit();
slouken@281
   117
	return 1;
slouken@281
   118
}
slouken@281
   119
slouken@281
   120
static void GEM_DeleteDevice(SDL_VideoDevice *device)
slouken@281
   121
{
slouken@1336
   122
	SDL_free(device->hidden);
slouken@1336
   123
	SDL_free(device);
slouken@281
   124
}
slouken@281
   125
slouken@281
   126
static SDL_VideoDevice *GEM_CreateDevice(int devindex)
slouken@281
   127
{
slouken@281
   128
	SDL_VideoDevice *device;
patmandin@1237
   129
	int vectors_mask;
patmandin@5649
   130
/*	unsigned long dummy;*/
slouken@281
   131
slouken@281
   132
	/* Initialize all variables that we clean on shutdown */
slouken@1336
   133
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
slouken@281
   134
	if ( device ) {
slouken@1336
   135
		SDL_memset(device, 0, (sizeof *device));
slouken@281
   136
		device->hidden = (struct SDL_PrivateVideoData *)
slouken@1336
   137
				SDL_malloc((sizeof *device->hidden));
patmandin@989
   138
		device->gl_data = (struct SDL_PrivateGLData *)
slouken@1336
   139
				SDL_malloc((sizeof *device->gl_data));
slouken@281
   140
	}
slouken@281
   141
	if ( (device == NULL) || (device->hidden == NULL) ) {
slouken@281
   142
		SDL_OutOfMemory();
slouken@281
   143
		if ( device ) {
slouken@1336
   144
			SDL_free(device);
slouken@281
   145
		}
slouken@281
   146
		return(0);
slouken@281
   147
	}
slouken@1336
   148
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
slouken@1336
   149
	SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
slouken@281
   150
slouken@281
   151
	/* Set the function pointers */
slouken@281
   152
	device->VideoInit = GEM_VideoInit;
slouken@281
   153
	device->ListModes = GEM_ListModes;
slouken@281
   154
	device->SetVideoMode = GEM_SetVideoMode;
slouken@281
   155
	device->SetColors = GEM_SetColors;
slouken@281
   156
	device->UpdateRects = NULL /*GEM_UpdateRects*/;
slouken@281
   157
	device->VideoQuit = GEM_VideoQuit;
slouken@281
   158
	device->AllocHWSurface = GEM_AllocHWSurface;
slouken@281
   159
	device->LockHWSurface = GEM_LockHWSurface;
slouken@281
   160
	device->UnlockHWSurface = GEM_UnlockHWSurface;
slouken@281
   161
	device->FlipHWSurface = GEM_FlipHWSurface;
slouken@281
   162
	device->FreeHWSurface = GEM_FreeHWSurface;
patmandin@11554
   163
	device->ToggleFullScreen = NULL;
slouken@281
   164
slouken@281
   165
	/* Window manager */
slouken@281
   166
	device->SetCaption = GEM_SetCaption;
patmandin@736
   167
	device->SetIcon = GEM_SetIcon;
slouken@281
   168
	device->IconifyWindow = GEM_IconifyWindow;
slouken@281
   169
	device->GrabInput = GEM_GrabInput;
slouken@281
   170
slouken@281
   171
	/* Events */
slouken@281
   172
	device->InitOSKeymap = GEM_InitOSKeymap;
slouken@281
   173
	device->PumpEvents = GEM_PumpEvents;
slouken@281
   174
slouken@281
   175
	/* Mouse */
slouken@281
   176
	device->FreeWMCursor = GEM_FreeWMCursor;
slouken@281
   177
	device->CreateWMCursor = GEM_CreateWMCursor;
slouken@281
   178
	device->ShowWMCursor = GEM_ShowWMCursor;
slouken@319
   179
	device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
slouken@281
   180
	device->CheckMouseMode = GEM_CheckMouseMode;
slouken@281
   181
slouken@1361
   182
#if SDL_VIDEO_OPENGL
patmandin@984
   183
	/* OpenGL functions */
patmandin@989
   184
	device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
patmandin@989
   185
	device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
patmandin@989
   186
	device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
patmandin@989
   187
	device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
patmandin@984
   188
	device->GL_SwapBuffers = GEM_GL_SwapBuffers;
patmandin@984
   189
#endif
patmandin@984
   190
patmandin@1420
   191
	device->hidden->use_dev_mouse =
patmandin@1420
   192
		(SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
patmandin@1420
   193
patmandin@1420
   194
	vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS;	/* XBIOS joystick events */
patmandin@1420
   195
	if (!(device->hidden->use_dev_mouse)) {
patmandin@1420
   196
		vectors_mask |= ATARI_XBIOS_MOUSEEVENTS;	/* XBIOS mouse events */
patmandin@1420
   197
	}
patmandin@3858
   198
/*	if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
patmandin@1237
   199
		vectors_mask = 0;
patmandin@3858
   200
	}*/
patmandin@1237
   201
patmandin@1237
   202
	SDL_AtariXbios_InstallVectors(vectors_mask);
slouken@305
   203
slouken@281
   204
	device->free = GEM_DeleteDevice;
slouken@281
   205
slouken@281
   206
	return device;
slouken@281
   207
}
slouken@281
   208
slouken@281
   209
VideoBootStrap GEM_bootstrap = {
slouken@281
   210
	GEM_VID_DRIVER_NAME, "Atari GEM video driver",
slouken@281
   211
	GEM_Available, GEM_CreateDevice
slouken@281
   212
};
slouken@281
   213
slouken@281
   214
static void VDI_ReadExtInfo(_THIS, short *work_out)
slouken@281
   215
{
slouken@281
   216
	unsigned long EdDI_version;
patmandin@5653
   217
	long cookie_EdDI;
patmandin@5867
   218
	Uint16 clut_type;
slouken@281
   219
slouken@281
   220
	/* Read EdDI informations */
patmandin@9060
   221
	if  (Getcookie(C_EdDI, &cookie_EdDI) != C_FOUND) {
slouken@281
   222
		return;
slouken@281
   223
	}
patmandin@11554
   224
slouken@281
   225
	EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
slouken@281
   226
slouken@281
   227
	vq_scrninfo(VDI_handle, work_out);
slouken@281
   228
slouken@281
   229
	VDI_format = work_out[0];
slouken@281
   230
	clut_type = work_out[1];
slouken@281
   231
slouken@281
   232
	/* With EdDI>=1.1, we can have screen pitch, address and format
slouken@281
   233
	 * so we can directly write to screen without using vro_cpyfm
slouken@281
   234
	 */
slouken@281
   235
	if (EdDI_version >= EDDI_11) {
slouken@281
   236
		VDI_pitch = work_out[5];
slouken@281
   237
		VDI_screen = (void *) *((unsigned long *) &work_out[6]);
slouken@281
   238
	}
slouken@281
   239
slouken@281
   240
	switch(clut_type) {
slouken@281
   241
		case VDI_CLUT_HARDWARE:
slouken@281
   242
			{
slouken@281
   243
				int i;
slouken@281
   244
				Uint16 *tmp_p;
slouken@281
   245
slouken@281
   246
				tmp_p = (Uint16 *)&work_out[16];
slouken@281
   247
slouken@281
   248
				for (i=0;i<256;i++) {
slouken@319
   249
					vdi_index[*tmp_p++] = i;
slouken@281
   250
				}
slouken@281
   251
			}
slouken@281
   252
			break;
slouken@281
   253
		case VDI_CLUT_SOFTWARE:
patmandin@800
   254
			{
slouken@281
   255
				int component; /* red, green, blue, alpha, overlay */
slouken@281
   256
				int num_bit;
slouken@281
   257
				unsigned short *tmp_p;
slouken@281
   258
slouken@281
   259
				/* We can build masks with info here */
slouken@281
   260
				tmp_p = (unsigned short *) &work_out[16];
slouken@281
   261
				for (component=0;component<5;component++) {
slouken@281
   262
					for (num_bit=0;num_bit<16;num_bit++) {
slouken@281
   263
						unsigned short valeur;
slouken@281
   264
slouken@281
   265
						valeur = *tmp_p++;
slouken@281
   266
slouken@281
   267
						if (valeur == 0xffff) {
slouken@281
   268
							continue;
slouken@281
   269
						}
slouken@281
   270
slouken@281
   271
						switch(component) {
slouken@281
   272
							case 0:
slouken@281
   273
								VDI_redmask |= 1<< valeur;
slouken@281
   274
								break;
slouken@281
   275
							case 1:
slouken@281
   276
								VDI_greenmask |= 1<< valeur;
slouken@281
   277
								break;
slouken@281
   278
							case 2:
slouken@281
   279
								VDI_bluemask |= 1<< valeur;
slouken@281
   280
								break;
slouken@281
   281
							case 3:
slouken@281
   282
								VDI_alphamask |= 1<< valeur;
slouken@281
   283
								break;
slouken@281
   284
						}
slouken@281
   285
					}
slouken@281
   286
				}
slouken@319
   287
			}
slouken@281
   288
slouken@319
   289
			/* Remove lower green bits for Intel endian screen */
slouken@319
   290
			if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
slouken@319
   291
				VDI_greenmask &= ~(7<<13);
slouken@281
   292
			}
slouken@281
   293
			break;
slouken@281
   294
		case VDI_CLUT_NONE:
slouken@281
   295
			break;
slouken@281
   296
	}
slouken@281
   297
}
slouken@281
   298
slouken@281
   299
int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@281
   300
{
patmandin@1070
   301
	int i, menubar_size;
slouken@281
   302
	short work_in[12], work_out[272], dummy;
slouken@281
   303
slouken@281
   304
	/* Open AES (Application Environment Services) */
patmandin@9131
   305
	GEM_ap_id = appl_init();
patmandin@9131
   306
	if (GEM_ap_id == -1) {
slouken@281
   307
		fprintf(stderr,"Can not open AES\n");
slouken@281
   308
		return 1;
slouken@281
   309
	}
slouken@281
   310
slouken@281
   311
	/* Read version and features */
patmandin@736
   312
	GEM_version = aes_global[0];
patmandin@736
   313
	if (GEM_version >= 0x0410) {
patmandin@736
   314
		short ap_gout[4], errorcode;
patmandin@11554
   315
slouken@281
   316
		GEM_wfeatures=0;
patmandin@736
   317
		errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
patmandin@736
   318
patmandin@736
   319
		if (errorcode==0) {
patmandin@11554
   320
			GEM_wfeatures=ap_gout[0];
slouken@281
   321
		}
patmandin@11554
   322
	}
slouken@281
   323
slouken@281
   324
	/* Ask VDI physical workstation handle opened by AES */
slouken@281
   325
	VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
slouken@281
   326
	if (VDI_handle<1) {
slouken@281
   327
		fprintf(stderr,"Wrong VDI handle %d returned by AES\n",VDI_handle);
slouken@281
   328
		return 1;
slouken@281
   329
	}
slouken@281
   330
slouken@281
   331
	/* Open virtual VDI workstation */
slouken@281
   332
	work_in[0]=Getrez()+2;
slouken@281
   333
	for(i = 1; i < 10; i++)
slouken@281
   334
		work_in[i] = 1;
slouken@281
   335
	work_in[10] = 2;
slouken@281
   336
slouken@281
   337
	v_opnvwk(work_in, &VDI_handle, work_out);
slouken@281
   338
	if (VDI_handle == 0) {
slouken@281
   339
		fprintf(stderr,"Can not open VDI virtual workstation\n");
slouken@281
   340
		return 1;
slouken@281
   341
	}
slouken@281
   342
slouken@281
   343
	/* Read fullscreen size */
slouken@281
   344
	VDI_w = work_out[0] + 1;
slouken@281
   345
	VDI_h = work_out[1] + 1;
slouken@281
   346
slouken@281
   347
	/* Read desktop size and position */
slouken@281
   348
	if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
slouken@281
   349
		fprintf(stderr,"Can not read desktop properties\n");
slouken@281
   350
		return 1;
slouken@281
   351
	}
slouken@281
   352
patmandin@11555
   353
	GEM_work_x = GEM_desk_x;
patmandin@11555
   354
	GEM_work_y = GEM_desk_y;
patmandin@11555
   355
	GEM_work_w = GEM_desk_w;
patmandin@11555
   356
	GEM_work_h = GEM_desk_h;
patmandin@11555
   357
slouken@281
   358
	/* Read bit depth */
slouken@281
   359
	vq_extnd(VDI_handle, 1, work_out);
slouken@281
   360
	VDI_bpp = work_out[4];
slouken@281
   361
	VDI_oldnumcolors=0;
slouken@281
   362
slouken@281
   363
	switch(VDI_bpp) {
slouken@281
   364
		case 8:
slouken@281
   365
			VDI_pixelsize=1;
slouken@281
   366
			break;
slouken@281
   367
		case 15:
slouken@281
   368
		case 16:
slouken@281
   369
			VDI_pixelsize=2;
slouken@281
   370
			break;
slouken@281
   371
		case 24:
slouken@281
   372
			VDI_pixelsize=3;
slouken@281
   373
			break;
slouken@281
   374
		case 32:
slouken@281
   375
			VDI_pixelsize=4;
slouken@281
   376
			break;
slouken@281
   377
		default:
slouken@281
   378
			fprintf(stderr,"%d bits colour depth not supported\n",VDI_bpp);
slouken@281
   379
			return 1;
slouken@281
   380
	}
slouken@281
   381
slouken@281
   382
	/* Setup hardware -> VDI palette mapping */
slouken@281
   383
	for(i = 16; i < 255; i++) {
slouken@281
   384
		vdi_index[i] = i;
slouken@281
   385
	}
slouken@281
   386
	vdi_index[255] = 1;
slouken@281
   387
slouken@281
   388
	/* Save current palette */
slouken@281
   389
	if (VDI_bpp>8) {
slouken@281
   390
		VDI_oldnumcolors=1<<8;
slouken@281
   391
	} else {
slouken@281
   392
		VDI_oldnumcolors=1<<VDI_bpp;
slouken@281
   393
	}
patmandin@11554
   394
slouken@281
   395
	for(i = 0; i < VDI_oldnumcolors; i++) {
slouken@281
   396
		short rgb[3];
slouken@281
   397
slouken@281
   398
		vq_color(VDI_handle, i, 0, rgb);
slouken@281
   399
slouken@281
   400
		VDI_oldpalette[i][0] = rgb[0];
slouken@281
   401
		VDI_oldpalette[i][1] = rgb[1];
slouken@281
   402
		VDI_oldpalette[i][2] = rgb[2];
slouken@281
   403
	}
patmandin@1074
   404
	VDI_setpalette = GEM_SetNewPalette;
slouken@1336
   405
	SDL_memcpy(VDI_curpalette,VDI_oldpalette,sizeof(VDI_curpalette));
slouken@281
   406
slouken@281
   407
	/* Setup screen info */
slouken@281
   408
	GEM_title_name = empty_name;
slouken@281
   409
	GEM_icon_name = empty_name;
slouken@281
   410
slouken@281
   411
	GEM_handle = -1;
slouken@281
   412
	GEM_locked = SDL_FALSE;
slouken@281
   413
	GEM_win_fulled = SDL_FALSE;
patmandin@11568
   414
	GEM_iconified = SDL_FALSE;
patmandin@926
   415
	GEM_fullscreen = SDL_FALSE;
patmandin@964
   416
	GEM_lock_redraw = SDL_TRUE;	/* Prevent redraw till buffers are setup */
slouken@281
   417
slouken@281
   418
	VDI_screen = NULL;
patmandin@799
   419
	VDI_pitch = VDI_w * VDI_pixelsize;
patmandin@799
   420
	VDI_format = ( (VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
patmandin@799
   421
	VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
patmandin@799
   422
	VDI_ReadExtInfo(this, work_out);
patmandin@799
   423
patmandin@799
   424
#ifdef DEBUG_VIDEO_GEM
patmandin@799
   425
	printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, VDI_pitch);
patmandin@799
   426
	printf("sdl:video:gem: format=%d\n", VDI_format);
patmandin@799
   427
	printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
patmandin@799
   428
		VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask
patmandin@799
   429
	);
patmandin@799
   430
#endif
slouken@281
   431
slouken@281
   432
	/* Setup destination mfdb */
slouken@281
   433
	VDI_dst_mfdb.fd_addr = NULL;
slouken@281
   434
slouken@1545
   435
	/* Determine the current screen size */
slouken@1545
   436
	this->info.current_w = VDI_w;
slouken@1545
   437
	this->info.current_h = VDI_h;
slouken@281
   438
slouken@281
   439
	/* Determine the screen depth */
slouken@281
   440
	/* we change this during the SDL_SetVideoMode implementation... */
slouken@281
   441
	vformat->BitsPerPixel = VDI_bpp;
slouken@281
   442
slouken@281
   443
	/* Set mouse cursor to arrow */
slouken@281
   444
	graf_mouse(ARROW, NULL);
patmandin@11564
   445
	GEM_cursor = GEM_prev_cursor = NULL;
slouken@281
   446
slouken@281
   447
	/* Init chunky to planar routine */
patmandin@736
   448
	SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
patmandin@736
   449
patmandin@736
   450
	/* Setup VDI fill functions */
patmandin@736
   451
	vsf_color(VDI_handle,0);
patmandin@736
   452
	vsf_interior(VDI_handle,1);
patmandin@736
   453
	vsf_perimeter(VDI_handle,0);
patmandin@736
   454
patmandin@1069
   455
	/* Menu bar save buffer */
patmandin@1069
   456
	menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
patmandin@1069
   457
	GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
patmandin@1069
   458
patmandin@902
   459
	/* Fill video modes list */
slouken@1336
   460
	SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect));
patmandin@902
   461
	SDL_modelist[0]->x = 0;
patmandin@902
   462
	SDL_modelist[0]->y = 0;
patmandin@902
   463
	SDL_modelist[0]->w = VDI_w;
patmandin@902
   464
	SDL_modelist[0]->h = VDI_h;
patmandin@902
   465
patmandin@902
   466
	SDL_modelist[1] = NULL;
patmandin@902
   467
slouken@1361
   468
#if SDL_VIDEO_OPENGL
patmandin@991
   469
	SDL_AtariGL_InitPointers(this);
patmandin@736
   470
#endif
slouken@281
   471
patmandin@3943
   472
	this->info.wm_available = 1;
patmandin@3941
   473
slouken@281
   474
	/* We're done! */
slouken@281
   475
	return(0);
slouken@281
   476
}
slouken@281
   477
slouken@281
   478
SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
slouken@281
   479
{
patmandin@902
   480
	if (format->BitsPerPixel != VDI_bpp) {
slouken@281
   481
		return ((SDL_Rect **)NULL);
slouken@281
   482
	}
patmandin@902
   483
patmandin@902
   484
	if (flags & SDL_FULLSCREEN) {
patmandin@902
   485
		return (SDL_modelist);
patmandin@902
   486
	}
patmandin@902
   487
patmandin@902
   488
	return((SDL_Rect **)-1);
slouken@281
   489
}
slouken@281
   490
slouken@281
   491
static void GEM_FreeBuffers(_THIS)
slouken@281
   492
{
slouken@281
   493
	/* Release buffer */
patmandin@736
   494
	if ( GEM_buffer2 ) {
patmandin@1072
   495
		Mfree( GEM_buffer2 );
patmandin@736
   496
		GEM_buffer2=NULL;
patmandin@736
   497
	}
patmandin@736
   498
patmandin@736
   499
	if ( GEM_buffer1 ) {
patmandin@1072
   500
		Mfree( GEM_buffer1 );
patmandin@736
   501
		GEM_buffer1=NULL;
slouken@281
   502
	}
slouken@281
   503
}
slouken@281
   504
patmandin@11569
   505
void GEM_ClearRect(_THIS, short *pxy)
patmandin@736
   506
{
patmandin@736
   507
	short oldrgb[3], rgb[3]={0,0,0};
patmandin@736
   508
patmandin@11570
   509
	vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
patmandin@736
   510
	vs_color(VDI_handle, vdi_index[0], rgb);
patmandin@736
   511
patmandin@736
   512
	vsf_color(VDI_handle,0);
patmandin@736
   513
	vsf_interior(VDI_handle,1);
patmandin@736
   514
	vsf_perimeter(VDI_handle,0);
patmandin@11569
   515
	v_bar(VDI_handle, pxy);
patmandin@736
   516
patmandin@736
   517
	vs_color(VDI_handle, vdi_index[0], oldrgb);
patmandin@736
   518
}
patmandin@736
   519
patmandin@11569
   520
void GEM_ClearRectXYWH(_THIS, short *rect)
patmandin@11569
   521
{
patmandin@11569
   522
	short pxy[4];
patmandin@11569
   523
patmandin@11569
   524
	pxy[0] = rect[0];
patmandin@11569
   525
	pxy[1] = rect[1];
patmandin@11569
   526
	pxy[2] = rect[0]+rect[2]-1;
patmandin@11569
   527
	pxy[3] = rect[1]+rect[3]-1;
patmandin@11569
   528
patmandin@11569
   529
	GEM_ClearRect(this, pxy);
patmandin@11569
   530
}
patmandin@11569
   531
slouken@319
   532
static void GEM_ClearScreen(_THIS)
slouken@319
   533
{
slouken@319
   534
	short pxy[4];
slouken@319
   535
slouken@319
   536
	v_hide_c(VDI_handle);
slouken@319
   537
slouken@319
   538
	pxy[0] = pxy[1] = 0;
slouken@319
   539
	pxy[2] = VDI_w - 1;
slouken@319
   540
	pxy[3] = VDI_h - 1;
patmandin@11560
   541
	GEM_ClearRect(this, pxy);
slouken@319
   542
slouken@319
   543
	v_show_c(VDI_handle, 1);
slouken@319
   544
}
slouken@319
   545
patmandin@1074
   546
static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3])
patmandin@1074
   547
{
patmandin@1074
   548
	int i;
patmandin@1074
   549
	short rgb[3];
patmandin@1074
   550
patmandin@1074
   551
	if (VDI_oldnumcolors==0)
patmandin@1074
   552
		return;
patmandin@1074
   553
patmandin@1074
   554
	for(i = 0; i < VDI_oldnumcolors; i++) {
patmandin@1074
   555
		rgb[0] = newpal[i][0];
patmandin@1074
   556
		rgb[1] = newpal[i][1];
patmandin@1074
   557
		rgb[2] = newpal[i][2];
patmandin@1074
   558
patmandin@1074
   559
		vs_color(VDI_handle, i, rgb);
patmandin@1074
   560
	}
patmandin@1074
   561
}
patmandin@1074
   562
slouken@319
   563
static void GEM_LockScreen(_THIS)
slouken@319
   564
{
slouken@319
   565
	if (!GEM_locked) {
slouken@319
   566
		/* Lock AES */
slouken@319
   567
		wind_update(BEG_UPDATE);
slouken@319
   568
		wind_update(BEG_MCTRL);
patmandin@917
   569
		/* Reserve memory space, used to be sure of compatibility */
patmandin@917
   570
		form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
slouken@319
   571
patmandin@1069
   572
		/* Save menu bar */
patmandin@1069
   573
		if (GEM_menubar) {
patmandin@1069
   574
			MFDB mfdb_src;
patmandin@1069
   575
			short blitcoords[8];
patmandin@1069
   576
patmandin@1069
   577
			mfdb_src.fd_addr=GEM_menubar;
patmandin@1069
   578
			mfdb_src.fd_w=GEM_desk_w;
patmandin@1069
   579
			mfdb_src.fd_h=GEM_desk_y;
patmandin@1075
   580
			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
patmandin@1069
   581
			mfdb_src.fd_nplanes=VDI_bpp;
patmandin@1069
   582
			mfdb_src.fd_stand=
patmandin@1069
   583
				mfdb_src.fd_r1=
patmandin@1069
   584
				mfdb_src.fd_r2=
patmandin@1069
   585
				mfdb_src.fd_r3= 0;
patmandin@1069
   586
patmandin@1069
   587
			blitcoords[0] = blitcoords[4] = 0;
patmandin@1069
   588
			blitcoords[1] = blitcoords[5] = 0;
patmandin@1069
   589
			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
patmandin@1069
   590
			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
patmandin@1069
   591
patmandin@1069
   592
			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
patmandin@1069
   593
		}
patmandin@1069
   594
slouken@319
   595
		GEM_locked=SDL_TRUE;
slouken@319
   596
	}
slouken@319
   597
}
slouken@319
   598
slouken@319
   599
static void GEM_UnlockScreen(_THIS)
slouken@319
   600
{
slouken@319
   601
	if (GEM_locked) {
patmandin@1069
   602
		/* Restore menu bar */
patmandin@1069
   603
		if (GEM_menubar) {
patmandin@1069
   604
			MFDB mfdb_src;
patmandin@1069
   605
			short blitcoords[8];
patmandin@1069
   606
patmandin@1069
   607
			mfdb_src.fd_addr=GEM_menubar;
patmandin@1069
   608
			mfdb_src.fd_w=GEM_desk_w;
patmandin@1069
   609
			mfdb_src.fd_h=GEM_desk_y;
patmandin@1075
   610
			mfdb_src.fd_wdwidth=GEM_desk_w>>4;
patmandin@1069
   611
			mfdb_src.fd_nplanes=VDI_bpp;
patmandin@1069
   612
			mfdb_src.fd_stand=
patmandin@1069
   613
				mfdb_src.fd_r1=
patmandin@1069
   614
				mfdb_src.fd_r2=
patmandin@1069
   615
				mfdb_src.fd_r3= 0;
patmandin@1069
   616
patmandin@1069
   617
			blitcoords[0] = blitcoords[4] = 0;
patmandin@1069
   618
			blitcoords[1] = blitcoords[5] = 0;
patmandin@1069
   619
			blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
patmandin@1069
   620
			blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
patmandin@1069
   621
patmandin@1069
   622
			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
patmandin@1069
   623
		}
patmandin@1069
   624
slouken@319
   625
		/* Restore screen memory, and send REDRAW to all apps */
slouken@319
   626
		form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
slouken@319
   627
		/* Unlock AES */
slouken@319
   628
		wind_update(END_MCTRL);
slouken@319
   629
		wind_update(END_UPDATE);
slouken@319
   630
slouken@319
   631
		GEM_locked=SDL_FALSE;
slouken@319
   632
	}
slouken@319
   633
}
slouken@319
   634
slouken@281
   635
SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
slouken@281
   636
				int width, int height, int bpp, Uint32 flags)
slouken@281
   637
{
slouken@281
   638
	Uint32 modeflags, screensize;
patmandin@736
   639
	SDL_bool use_shadow1, use_shadow2;
slouken@281
   640
patmandin@799
   641
	/* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
patmandin@918
   642
	if ((width & 15) != 0) {
patmandin@799
   643
		width = (width | 15) +1;
patmandin@799
   644
	}
patmandin@799
   645
patmandin@3944
   646
	/*--- Verify if asked mode can be used ---*/
patmandin@3944
   647
	if (VDI_bpp != bpp) {
patmandin@3944
   648
		SDL_SetError("%d bpp mode not supported", bpp);
slouken@281
   649
		return(NULL);
slouken@281
   650
	}
slouken@281
   651
patmandin@3944
   652
	if (flags & SDL_FULLSCREEN) {
patmandin@3944
   653
		if ((VDI_w < width) || (VDI_h < height)) {
patmandin@3944
   654
			SDL_SetError("%dx%d mode is too large", width, height);
patmandin@3944
   655
			return(NULL);
patmandin@3944
   656
		}
patmandin@3944
   657
	}
patmandin@3944
   658
slouken@281
   659
	/*--- Allocate the new pixel format for the screen ---*/
slouken@281
   660
	if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
slouken@281
   661
		SDL_SetError("Couldn't allocate new pixel format for requested mode");
slouken@281
   662
		return(NULL);
slouken@281
   663
	}
slouken@281
   664
patmandin@736
   665
	screensize = width * height * VDI_pixelsize;
patmandin@736
   666
patmandin@799
   667
#ifdef DEBUG_VIDEO_GEM
patmandin@799
   668
	printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);
patmandin@799
   669
#endif
patmandin@799
   670
patmandin@736
   671
	/*--- Allocate shadow buffers if needed, and conversion operations ---*/
patmandin@925
   672
	GEM_FreeBuffers(this);
patmandin@925
   673
patmandin@736
   674
	GEM_bufops=0;
patmandin@736
   675
	use_shadow1=use_shadow2=SDL_FALSE;
patmandin@736
   676
	if (VDI_screen && (flags & SDL_FULLSCREEN)) {
patmandin@736
   677
		if (VDI_format==VDI_FORMAT_INTER) {
patmandin@736
   678
			use_shadow1=SDL_TRUE;
patmandin@736
   679
			GEM_bufops = B2S_C2P_1TOS;
slouken@281
   680
		}
slouken@281
   681
	} else {
patmandin@736
   682
		use_shadow1=SDL_TRUE;
patmandin@736
   683
		if (VDI_format==VDI_FORMAT_PACK) {
patmandin@736
   684
			GEM_bufops = B2S_VROCPYFM_1TOS;
patmandin@736
   685
		} else {
patmandin@736
   686
			use_shadow2=SDL_TRUE;
patmandin@736
   687
			GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS;
patmandin@736
   688
		}
slouken@281
   689
	}
slouken@281
   690
patmandin@736
   691
	if (use_shadow1) {
patmandin@736
   692
		GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
patmandin@736
   693
		if (GEM_buffer1==NULL) {
patmandin@1104
   694
			SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10);
slouken@281
   695
			return NULL;
slouken@281
   696
		}
slouken@1336
   697
		SDL_memset(GEM_buffer1, 0, screensize);
patmandin@736
   698
#ifdef DEBUG_VIDEO_GEM
patmandin@736
   699
		printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");
patmandin@736
   700
#endif
patmandin@736
   701
	}
patmandin@736
   702
patmandin@736
   703
	if (use_shadow2) {
patmandin@736
   704
		GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
patmandin@736
   705
		if (GEM_buffer2==NULL) {
patmandin@1104
   706
			SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10);
patmandin@736
   707
			return NULL;
patmandin@736
   708
		}
slouken@1336
   709
		SDL_memset(GEM_buffer2, 0, screensize);
patmandin@736
   710
#ifdef DEBUG_VIDEO_GEM
patmandin@736
   711
		printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");
patmandin@736
   712
#endif
slouken@281
   713
	}
slouken@281
   714
slouken@281
   715
	/*--- Initialize screen ---*/
patmandin@1103
   716
	modeflags = SDL_PREALLOC;
slouken@508
   717
	if (VDI_bpp == 8) {
slouken@508
   718
		modeflags |= SDL_HWPALETTE;
slouken@508
   719
	}
slouken@508
   720
slouken@281
   721
	if (flags & SDL_FULLSCREEN) {
slouken@319
   722
		GEM_LockScreen(this);
slouken@281
   723
slouken@319
   724
		GEM_ClearScreen(this);
slouken@281
   725
slouken@281
   726
		modeflags |= SDL_FULLSCREEN;
patmandin@736
   727
		if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) {
slouken@281
   728
			modeflags |= SDL_HWSURFACE;
slouken@281
   729
		} else {
slouken@281
   730
			modeflags |= SDL_SWSURFACE;
slouken@281
   731
		}
patmandin@926
   732
patmandin@926
   733
		GEM_fullscreen = SDL_TRUE;
slouken@281
   734
	} else {
patmandin@925
   735
		int old_win_type;
slouken@281
   736
		short x2,y2,w2,h2;
slouken@281
   737
slouken@319
   738
		GEM_UnlockScreen(this);
slouken@281
   739
patmandin@923
   740
		/* Set window gadgets */
patmandin@925
   741
		old_win_type = GEM_win_type;
slouken@281
   742
		if (!(flags & SDL_NOFRAME)) {
slouken@281
   743
			GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
slouken@281
   744
			if (flags & SDL_RESIZABLE) {
slouken@281
   745
				GEM_win_type |= FULLER|SIZER;
slouken@281
   746
				modeflags |= SDL_RESIZABLE;
slouken@281
   747
			}
slouken@281
   748
		} else {
slouken@281
   749
			GEM_win_type=0;
slouken@281
   750
			modeflags |= SDL_NOFRAME;
slouken@281
   751
		}
patmandin@925
   752
		modeflags |= SDL_SWSURFACE;
slouken@281
   753
patmandin@925
   754
		/* Recreate window ? only for different widget or non-created window */
patmandin@959
   755
		if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
patmandin@925
   756
			/* Calculate window size */
patmandin@11562
   757
			if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width+16,height, &x2,&y2,&w2,&h2)) {
patmandin@925
   758
				GEM_FreeBuffers(this);
patmandin@925
   759
				SDL_SetError("Can not calculate window attributes");
patmandin@925
   760
				return NULL;
patmandin@925
   761
			}
slouken@281
   762
patmandin@925
   763
			/* Center window */
patmandin@3944
   764
			x2 = (GEM_desk_w-w2)>>1;
patmandin@3944
   765
			y2 = (GEM_desk_h-h2)>>1;
patmandin@3944
   766
			if (x2<0) {
patmandin@3944
   767
				x2 = 0;
patmandin@3944
   768
			}
patmandin@3944
   769
			if (y2<0) {
patmandin@3944
   770
				y2 = 0;
patmandin@3944
   771
			}
patmandin@3944
   772
			x2 += GEM_desk_x;
patmandin@3944
   773
			y2 += GEM_desk_y;
patmandin@923
   774
patmandin@11554
   775
			/* Align work area on 16 pixels boundary (faster for bitplanes modes) */
patmandin@11554
   776
			wind_calc(WC_WORK, GEM_win_type, x2,y2,w2,h2, &x2,&y2,&w2,&h2);
patmandin@11569
   777
			x2 &= ~15;
patmandin@11560
   778
			x2 -= 8;
patmandin@11554
   779
			wind_calc(WC_BORDER, GEM_win_type, x2,y2,w2,h2, &x2,&y2,&w2,&h2);
patmandin@11554
   780
patmandin@925
   781
			/* Destroy existing window */
patmandin@925
   782
			if (GEM_handle >= 0) {
patmandin@925
   783
				wind_close(GEM_handle);
patmandin@925
   784
				wind_delete(GEM_handle);
patmandin@925
   785
			}
patmandin@925
   786
patmandin@925
   787
			/* Create window */
patmandin@925
   788
			GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
patmandin@925
   789
			if (GEM_handle<0) {
patmandin@925
   790
				GEM_FreeBuffers(this);
patmandin@925
   791
				SDL_SetError("Can not create window");
patmandin@925
   792
				return NULL;
patmandin@925
   793
			}
slouken@281
   794
patmandin@736
   795
#ifdef DEBUG_VIDEO_GEM
patmandin@925
   796
			printf("sdl:video:gem: handle=%d\n", GEM_handle);
patmandin@736
   797
#endif
patmandin@736
   798
patmandin@925
   799
			/* Setup window name */
patmandin@11554
   800
			wind_set(GEM_handle,WF_NAME,
patmandin@11554
   801
				(short)(((unsigned long)GEM_title_name)>>16),
patmandin@11554
   802
				(short)(((unsigned long)GEM_title_name) & 0xffff),
patmandin@11554
   803
				0,0);
patmandin@925
   804
			GEM_refresh_name = SDL_FALSE;
patmandin@959
   805
patmandin@959
   806
			/* Open the window */
patmandin@959
   807
			wind_open(GEM_handle,x2,y2,w2,h2);
patmandin@11568
   808
patmandin@11568
   809
			GEM_iconified = SDL_FALSE;
patmandin@1066
   810
		} else {
patmandin@3942
   811
			/* Resize window to fit asked video mode */
patmandin@3942
   812
			wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
patmandin@11562
   813
			if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width+16,height, &x2,&y2,&w2,&h2)) {
patmandin@3942
   814
				wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
patmandin@1066
   815
			}
patmandin@925
   816
		}
patmandin@926
   817
patmandin@11568
   818
		GEM_align_work_area(this, GEM_handle, 0);
patmandin@926
   819
		GEM_fullscreen = SDL_FALSE;
slouken@281
   820
	}
slouken@281
   821
slouken@281
   822
	/* Set up the new mode framebuffer */
slouken@281
   823
	current->w = width;
slouken@281
   824
	current->h = height;
patmandin@736
   825
	if (use_shadow1) {
patmandin@736
   826
		current->pixels = GEM_buffer1;
patmandin@799
   827
		current->pitch = width * VDI_pixelsize;
slouken@281
   828
	} else {
slouken@281
   829
		current->pixels = VDI_screen;
slouken@281
   830
		current->pitch = VDI_pitch;
slouken@281
   831
	}
slouken@281
   832
slouken@1361
   833
#if SDL_VIDEO_OPENGL
patmandin@984
   834
	if (flags & SDL_OPENGL) {
patmandin@989
   835
		if (!SDL_AtariGL_Init(this, current)) {
patmandin@984
   836
			GEM_FreeBuffers(this);
patmandin@989
   837
			SDL_SetError("Can not create OpenGL context");
patmandin@989
   838
			return NULL;
patmandin@984
   839
		}
patmandin@984
   840
patmandin@984
   841
		modeflags |= SDL_OPENGL;
patmandin@984
   842
	}
patmandin@984
   843
#endif
patmandin@984
   844
patmandin@984
   845
	current->flags = modeflags;
patmandin@984
   846
patmandin@799
   847
#ifdef DEBUG_VIDEO_GEM
patmandin@799
   848
	printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
patmandin@799
   849
#endif
patmandin@799
   850
slouken@281
   851
	this->UpdateRects = GEM_UpdateRects;
patmandin@964
   852
	GEM_lock_redraw = SDL_FALSE;	/* Enable redraw */
slouken@281
   853
slouken@281
   854
	/* We're done */
slouken@281
   855
	return(current);
slouken@281
   856
}
slouken@281
   857
patmandin@11576
   858
void GEM_align_work_area(_THIS, short windowid, SDL_bool clear_pads)
patmandin@11560
   859
{
patmandin@11576
   860
	int new_x, new_w, old_x, old_w;
patmandin@11560
   861
patmandin@11560
   862
	wind_get(windowid, WF_WORKXYWH, &GEM_work_x,&GEM_work_y,&GEM_work_w,&GEM_work_h);
patmandin@11568
   863
	if (GEM_iconified) {
patmandin@11561
   864
		return;
patmandin@11561
   865
	}
patmandin@11560
   866
patmandin@11560
   867
	/* Align work area on 16 pixels boundary (faster for bitplanes modes) */
patmandin@11576
   868
	new_x = old_x = GEM_work_x;
patmandin@11576
   869
	new_w = old_w = GEM_work_w;
patmandin@11560
   870
	if (new_x & 15) {
patmandin@11560
   871
		new_x = (new_x|15)+1;
patmandin@11566
   872
	} else {
patmandin@11566
   873
		new_w -= 16;
patmandin@11560
   874
	}
patmandin@11560
   875
	new_w -= (new_x - GEM_work_x);
patmandin@11569
   876
	new_w &= ~15;
patmandin@11560
   877
patmandin@11576
   878
	GEM_work_x = new_x;
patmandin@11576
   879
	GEM_work_w = new_w;
patmandin@11576
   880
patmandin@11560
   881
	if (clear_pads) {
patmandin@11570
   882
		short rect[4];
patmandin@11560
   883
patmandin@11570
   884
		rect[1] = GEM_work_y;
patmandin@11570
   885
		rect[3] = GEM_work_h;
patmandin@11560
   886
patmandin@11560
   887
		/* Left padding */
patmandin@11576
   888
		rect[0] = old_x;
patmandin@11576
   889
		rect[2] = new_x-old_x+1;
patmandin@11576
   890
		GEM_wind_redraw(this, GEM_handle, rect, SDL_TRUE);
patmandin@11560
   891
patmandin@11560
   892
		/* Right padding */
patmandin@11570
   893
		rect[0] = new_x + new_w;
patmandin@11576
   894
		rect[2] = (old_w-new_w)-(new_x-old_x)+1;
patmandin@11576
   895
		GEM_wind_redraw(this, GEM_handle, rect, SDL_TRUE);
patmandin@11560
   896
	}
patmandin@11560
   897
}
patmandin@11560
   898
slouken@281
   899
static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
slouken@281
   900
{
slouken@281
   901
	return -1;
slouken@281
   902
}
patmandin@800
   903
slouken@281
   904
static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
slouken@281
   905
{
slouken@281
   906
	return;
slouken@281
   907
}
slouken@281
   908
slouken@281
   909
static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
slouken@281
   910
{
slouken@281
   911
	return(0);
slouken@281
   912
}
slouken@281
   913
slouken@281
   914
static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
slouken@281
   915
{
slouken@281
   916
	return;
slouken@281
   917
}
slouken@281
   918
slouken@281
   919
static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
slouken@281
   920
{
slouken@281
   921
	SDL_Surface *surface;
patmandin@799
   922
	int i, surf_width;
slouken@281
   923
slouken@281
   924
	surface = this->screen;
patmandin@799
   925
	/* Need to be a multiple of 16 pixels */
patmandin@799
   926
	surf_width=surface->w;
patmandin@918
   927
	if ((surf_width & 15) != 0) {
patmandin@799
   928
		surf_width = (surf_width | 15) + 1;
patmandin@799
   929
	}
slouken@281
   930
patmandin@736
   931
	if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
patmandin@736
   932
		void *destscr;
patmandin@736
   933
		int destpitch;
patmandin@736
   934
patmandin@736
   935
		if (GEM_bufops & B2S_C2P_1TOS) {
slouken@281
   936
			destscr = VDI_screen;
patmandin@736
   937
			destpitch = VDI_pitch;
patmandin@736
   938
		} else {
patmandin@736
   939
			destscr = GEM_buffer2;
patmandin@736
   940
			destpitch = surface->pitch;
patmandin@736
   941
		}
slouken@319
   942
patmandin@736
   943
		for (i=0;i<numrects;i++) {
patmandin@736
   944
			void *source,*destination;
patmandin@736
   945
			int x1,x2;
slouken@319
   946
patmandin@736
   947
			x1 = rects[i].x & ~15;
patmandin@736
   948
			x2 = rects[i].x+rects[i].w;
patmandin@736
   949
			if (x2 & 15) {
patmandin@736
   950
				x2 = (x2 | 15) +1;
slouken@319
   951
			}
slouken@319
   952
patmandin@736
   953
			source = surface->pixels;
patmandin@736
   954
			source += surface->pitch * rects[i].y;
patmandin@736
   955
			source += x1;
slouken@319
   956
patmandin@736
   957
			destination = destscr;
patmandin@736
   958
			destination += destpitch * rects[i].y;
patmandin@736
   959
			destination += x1;
patmandin@736
   960
patmandin@736
   961
			SDL_Atari_C2pConvert(
patmandin@736
   962
				source, destination,
patmandin@736
   963
				x2-x1, rects[i].h,
patmandin@736
   964
				SDL_FALSE,
patmandin@736
   965
				surface->pitch, destpitch
patmandin@736
   966
			);
slouken@319
   967
		}
slouken@319
   968
	}
slouken@281
   969
patmandin@736
   970
	if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
patmandin@736
   971
		MFDB mfdb_src;
patmandin@736
   972
		short blitcoords[8];
slouken@281
   973
patmandin@736
   974
		mfdb_src.fd_addr=surface->pixels;
patmandin@799
   975
		mfdb_src.fd_w=surf_width;
patmandin@736
   976
		mfdb_src.fd_h=surface->h;
patmandin@1041
   977
		mfdb_src.fd_wdwidth= (surface->pitch/VDI_pixelsize) >> 4;
patmandin@736
   978
		mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
patmandin@736
   979
		mfdb_src.fd_stand=
patmandin@736
   980
			mfdb_src.fd_r1=
patmandin@736
   981
			mfdb_src.fd_r2=
patmandin@736
   982
			mfdb_src.fd_r3= 0;
patmandin@736
   983
		if (GEM_bufops & B2S_VROCPYFM_2TOS) {
patmandin@736
   984
			mfdb_src.fd_addr=GEM_buffer2;
patmandin@736
   985
		}
slouken@281
   986
patmandin@736
   987
		for ( i=0; i<numrects; ++i ) {
patmandin@1071
   988
			blitcoords[0] = blitcoords[4] = rects[i].x;
patmandin@1071
   989
			blitcoords[1] = blitcoords[5] = rects[i].y;
patmandin@1071
   990
			blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1;
patmandin@1071
   991
			blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1;
patmandin@736
   992
patmandin@736
   993
			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
patmandin@736
   994
		}
slouken@281
   995
	}
slouken@281
   996
}
slouken@281
   997
slouken@281
   998
static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
slouken@281
   999
{
patmandin@11569
  1000
	short rect[4];
slouken@281
  1001
	int i;
slouken@281
  1002
slouken@281
  1003
	for ( i=0; i<numrects; ++i ) {
patmandin@11569
  1004
		rect[0] = GEM_work_x + rects[i].x;
patmandin@11569
  1005
		rect[1] = GEM_work_y + rects[i].y;
patmandin@11569
  1006
		rect[2] = rects[i].w;
patmandin@11569
  1007
		rect[3] = rects[i].h;
slouken@281
  1008
patmandin@11576
  1009
		GEM_wind_redraw(this, GEM_handle, rect, SDL_FALSE);
slouken@281
  1010
	}
slouken@281
  1011
}
slouken@281
  1012
slouken@281
  1013
static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
slouken@281
  1014
{
slouken@281
  1015
	SDL_Surface *surface;
slouken@281
  1016
patmandin@964
  1017
	if (GEM_lock_redraw) {
patmandin@964
  1018
		return;
patmandin@964
  1019
	}
patmandin@964
  1020
slouken@281
  1021
	surface = this->screen;
slouken@281
  1022
slouken@281
  1023
	if (surface->flags & SDL_FULLSCREEN) {
slouken@281
  1024
		GEM_UpdateRectsFullscreen(this, numrects, rects);
slouken@281
  1025
	} else {
slouken@281
  1026
		GEM_UpdateRectsWindowed(this, numrects, rects);
slouken@281
  1027
	}
slouken@281
  1028
}
slouken@281
  1029
slouken@281
  1030
static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
slouken@281
  1031
{
patmandin@799
  1032
	int surf_width;
patmandin@799
  1033
patmandin@799
  1034
	/* Need to be a multiple of 16 pixels */
patmandin@799
  1035
	surf_width=surface->w;
patmandin@918
  1036
	if ((surf_width & 15) != 0) {
patmandin@799
  1037
		surf_width = (surf_width | 15) + 1;
patmandin@799
  1038
	}
patmandin@799
  1039
patmandin@736
  1040
	if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
patmandin@736
  1041
		void *destscr;
patmandin@736
  1042
		int destpitch;
slouken@319
  1043
patmandin@736
  1044
		if (GEM_bufops & B2S_C2P_1TOS) {
slouken@281
  1045
			destscr = VDI_screen;
patmandin@736
  1046
			destpitch = VDI_pitch;
patmandin@736
  1047
		} else {
patmandin@736
  1048
			destscr = GEM_buffer2;
patmandin@736
  1049
			destpitch = surface->pitch;
slouken@281
  1050
		}
slouken@281
  1051
patmandin@736
  1052
		SDL_Atari_C2pConvert(
patmandin@736
  1053
			surface->pixels, destscr,
patmandin@799
  1054
			surf_width, surface->h,
patmandin@736
  1055
			SDL_FALSE,
patmandin@736
  1056
			surface->pitch, destpitch
patmandin@736
  1057
		);
slouken@319
  1058
	}
patmandin@736
  1059
patmandin@736
  1060
	if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
patmandin@736
  1061
		MFDB mfdb_src;
patmandin@736
  1062
		short blitcoords[8];
slouken@281
  1063
patmandin@799
  1064
		mfdb_src.fd_w=surf_width;
patmandin@736
  1065
		mfdb_src.fd_h=surface->h;
patmandin@799
  1066
		mfdb_src.fd_wdwidth=mfdb_src.fd_w >> 4;
patmandin@736
  1067
		mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
patmandin@736
  1068
		mfdb_src.fd_stand=
patmandin@736
  1069
			mfdb_src.fd_r1=
patmandin@736
  1070
			mfdb_src.fd_r2=
patmandin@736
  1071
			mfdb_src.fd_r3= 0;
patmandin@736
  1072
		if (GEM_bufops & B2S_VROCPYFM_1TOS) {
patmandin@736
  1073
			mfdb_src.fd_addr=surface->pixels;
patmandin@736
  1074
		} else {
patmandin@736
  1075
			mfdb_src.fd_addr=GEM_buffer2;
patmandin@736
  1076
		}
slouken@281
  1077
patmandin@1071
  1078
		blitcoords[0] = blitcoords[4] = 0;
patmandin@1071
  1079
		blitcoords[1] = blitcoords[5] = 0;
patmandin@1071
  1080
		blitcoords[2] = blitcoords[6] = surface->w - 1;
patmandin@1071
  1081
		blitcoords[3] = blitcoords[7] = surface->h - 1;
patmandin@736
  1082
patmandin@736
  1083
		vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
patmandin@736
  1084
	}
slouken@281
  1085
slouken@281
  1086
	return(0);
slouken@281
  1087
}
slouken@281
  1088
slouken@281
  1089
static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
slouken@281
  1090
{
patmandin@11569
  1091
	short rect[4];
slouken@281
  1092
slouken@281
  1093
	/* Update the whole window */
patmandin@11569
  1094
	rect[0] = GEM_work_x;
patmandin@11569
  1095
	rect[1] = GEM_work_y;
patmandin@11569
  1096
	rect[2] = GEM_work_w;
patmandin@11569
  1097
	rect[3] = GEM_work_h;
slouken@281
  1098
patmandin@11576
  1099
	GEM_wind_redraw(this, GEM_handle, rect, SDL_FALSE);
slouken@281
  1100
slouken@281
  1101
	return(0);
slouken@281
  1102
}
slouken@281
  1103
slouken@281
  1104
static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface)
slouken@281
  1105
{
patmandin@964
  1106
	if (GEM_lock_redraw) {
patmandin@964
  1107
		return(0);
patmandin@964
  1108
	}
patmandin@964
  1109
slouken@281
  1110
	if (surface->flags & SDL_FULLSCREEN) {
slouken@281
  1111
		return GEM_FlipHWSurfaceFullscreen(this, surface);
slouken@281
  1112
	} else {
slouken@281
  1113
		return GEM_FlipHWSurfaceWindowed(this, surface);
slouken@281
  1114
	}
slouken@281
  1115
}
slouken@281
  1116
slouken@281
  1117
static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@281
  1118
{
slouken@281
  1119
	int i;
slouken@281
  1120
	SDL_Surface *surface;
slouken@281
  1121
patmandin@736
  1122
#ifdef DEBUG_VIDEO_GEM
patmandin@736
  1123
	printf("sdl:video:gem: setcolors()\n");
patmandin@736
  1124
#endif
patmandin@736
  1125
slouken@281
  1126
	/* Do not change palette in True Colour */
slouken@281
  1127
	surface = this->screen;
slouken@281
  1128
	if (surface->format->BitsPerPixel > 8) {
slouken@281
  1129
		return 1;
slouken@281
  1130
	}
slouken@281
  1131
slouken@281
  1132
	for(i = 0; i < ncolors; i++)
slouken@281
  1133
	{
patmandin@11554
  1134
		int r, g, b;
patmandin@11554
  1135
		short rgb[3];
slouken@281
  1136
slouken@281
  1137
		r = colors[i].r;
slouken@281
  1138
		g = colors[i].g;
slouken@281
  1139
		b = colors[i].b;
slouken@281
  1140
patmandin@1074
  1141
		rgb[0] = VDI_curpalette[i][0] = (1000 * r) / 255;
patmandin@11554
  1142
		rgb[1] = VDI_curpalette[i][1] = (1000 * g) / 255;
patmandin@11554
  1143
		rgb[2] = VDI_curpalette[i][2] = (1000 * b) / 255;
slouken@281
  1144
slouken@281
  1145
		vs_color(VDI_handle, vdi_index[firstcolor+i], rgb);
slouken@281
  1146
	}
slouken@281
  1147
slouken@281
  1148
	return(1);
slouken@281
  1149
}
slouken@281
  1150
slouken@281
  1151
/* Note:  If we are terminated, this could be called in the middle of
slouken@281
  1152
   another SDL video routine -- notably UpdateRects.
slouken@281
  1153
*/
slouken@281
  1154
void GEM_VideoQuit(_THIS)
slouken@281
  1155
{
patmandin@9130
  1156
	/* Restore mouse cursor */
patmandin@9130
  1157
	if (GEM_cursor_hidden) {
patmandin@9130
  1158
		graf_mouse(M_ON, NULL);
patmandin@9130
  1159
	}
patmandin@9130
  1160
	graf_mouse(ARROW, NULL);
patmandin@9130
  1161
slouken@305
  1162
	SDL_AtariXbios_RestoreVectors();
patmandin@1420
  1163
	if (GEM_usedevmouse) {
patmandin@1420
  1164
		SDL_AtariDevMouse_Close();
patmandin@1420
  1165
	}
slouken@305
  1166
slouken@281
  1167
	GEM_FreeBuffers(this);
slouken@281
  1168
slouken@1361
  1169
#if SDL_VIDEO_OPENGL
patmandin@992
  1170
	if (gl_active) {
patmandin@992
  1171
		SDL_AtariGL_Quit(this, SDL_TRUE);
patmandin@992
  1172
	}
patmandin@992
  1173
#endif
patmandin@992
  1174
patmandin@925
  1175
	/* Destroy window */
patmandin@925
  1176
	if (GEM_handle>=0) {
patmandin@925
  1177
		wind_close(GEM_handle);
patmandin@925
  1178
		wind_delete(GEM_handle);
patmandin@925
  1179
		GEM_handle=-1;
patmandin@925
  1180
	}
patmandin@925
  1181
slouken@319
  1182
	GEM_UnlockScreen(this);
patmandin@1069
  1183
	if (GEM_menubar) {
patmandin@1069
  1184
		Mfree(GEM_menubar);
patmandin@1069
  1185
		GEM_menubar=NULL;
patmandin@1069
  1186
	}
slouken@281
  1187
slouken@281
  1188
	appl_exit();
slouken@281
  1189
patmandin@1074
  1190
	GEM_SetNewPalette(this, VDI_oldpalette);
slouken@281
  1191
slouken@281
  1192
	/* Close VDI workstation */
slouken@281
  1193
	if (VDI_handle) {
slouken@281
  1194
		v_clsvwk(VDI_handle);
slouken@281
  1195
	}
slouken@281
  1196
slouken@281
  1197
	/* Free mode list */
slouken@281
  1198
	if (SDL_modelist[0]) {
slouken@1336
  1199
		SDL_free(SDL_modelist[0]);
slouken@281
  1200
		SDL_modelist[0]=NULL;
slouken@281
  1201
	}
slouken@281
  1202
patmandin@11554
  1203
	this->screen->pixels = NULL;
slouken@281
  1204
}
slouken@281
  1205
patmandin@11576
  1206
void GEM_wind_redraw(_THIS, int winhandle, short *inside, SDL_bool pad_only)
slouken@281
  1207
{
slouken@281
  1208
	short todo[4];
slouken@281
  1209
slouken@281
  1210
	/* Tell AES we are going to update */
slouken@319
  1211
	wind_update(BEG_UPDATE);
slouken@281
  1212
slouken@281
  1213
	v_hide_c(VDI_handle);
slouken@281
  1214
slouken@281
  1215
	/* Browse the rectangle list to redraw */
patmandin@736
  1216
	if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
slouken@281
  1217
patmandin@736
  1218
		while (todo[2] && todo[3]) {
slouken@281
  1219
patmandin@736
  1220
			if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
patmandin@11576
  1221
				refresh_window(this, winhandle, todo, pad_only);
patmandin@736
  1222
			}
patmandin@736
  1223
patmandin@736
  1224
			if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
patmandin@736
  1225
				break;
patmandin@736
  1226
			}
slouken@281
  1227
		}
slouken@281
  1228
slouken@281
  1229
	}
slouken@281
  1230
slouken@281
  1231
	/* Update finished */
slouken@281
  1232
	wind_update(END_UPDATE);
slouken@281
  1233
slouken@281
  1234
	v_show_c(VDI_handle,1);
slouken@281
  1235
}
slouken@281
  1236
patmandin@11576
  1237
static void refresh_window(_THIS, int winhandle, short *rect, SDL_bool pad_only)
slouken@281
  1238
{
patmandin@736
  1239
	MFDB mfdb_src;
patmandin@11570
  1240
	short pxy[8], work_rect[4];
patmandin@736
  1241
	SDL_Surface *surface;
patmandin@11570
  1242
	int max_width, max_height;
patmandin@11554
  1243
patmandin@11570
  1244
	work_rect[0] = GEM_work_x;
patmandin@11570
  1245
	work_rect[1] = GEM_work_y;
patmandin@11570
  1246
	work_rect[2] = GEM_work_w;
patmandin@11570
  1247
	work_rect[3] = GEM_work_h;
patmandin@737
  1248
patmandin@11570
  1249
	surface = this->screen;
patmandin@736
  1250
patmandin@11570
  1251
	if (GEM_iconified) {
patmandin@11570
  1252
		/* Fill all iconified window */
patmandin@11570
  1253
		GEM_ClearRectXYWH(this, rect);
patmandin@736
  1254
patmandin@11570
  1255
		if (GEM_icon) {
patmandin@11570
  1256
			surface = GEM_icon;
patmandin@736
  1257
		}
patmandin@736
  1258
patmandin@11570
  1259
		/* Center icon inside window if it is smaller */
patmandin@11570
  1260
		if (GEM_work_w>surface->w) {
patmandin@11570
  1261
			work_rect[0] += (GEM_work_w-surface->w)>>1;
patmandin@11570
  1262
			work_rect[2] = surface->w;
patmandin@11570
  1263
		}
patmandin@11570
  1264
		if (GEM_work_h>surface->h) {
patmandin@11570
  1265
			work_rect[1] += (GEM_work_h-surface->h)>>1;
patmandin@11570
  1266
			work_rect[3] = surface->h;
patmandin@11570
  1267
		}
slouken@281
  1268
	} else {
patmandin@11566
  1269
		/* Y1,Y2 for padding zones */
patmandin@11566
  1270
		pxy[1] = rect[1];
patmandin@11570
  1271
		pxy[3] = rect[1]+rect[3]-1;
patmandin@11566
  1272
patmandin@11566
  1273
		/* Clear left padding zone ? */
patmandin@11566
  1274
		pxy[0] = rect[0];
patmandin@11570
  1275
		pxy[2] = MIN(rect[0]+rect[2]-1, GEM_work_x-1);
patmandin@11570
  1276
		if (pxy[0]<=pxy[2]) {
patmandin@11566
  1277
			GEM_ClearRect(this, pxy);
patmandin@11566
  1278
		}
patmandin@11566
  1279
patmandin@11566
  1280
		/* Clear right padding zone ? */
patmandin@11570
  1281
		pxy[0] = MAX(rect[0], GEM_work_x+GEM_work_w);
patmandin@11570
  1282
		pxy[2] = rect[0]+rect[2]-1;
patmandin@11570
  1283
		if (pxy[0]<=pxy[2]) {
patmandin@11566
  1284
			GEM_ClearRect(this, pxy);
patmandin@11566
  1285
		}
patmandin@11570
  1286
	}
patmandin@736
  1287
patmandin@11570
  1288
	/* Do we intersect zone to redraw ? */
patmandin@11576
  1289
	if (pad_only || !rc_intersect((GRECT *)work_rect, (GRECT *)rect)) {
patmandin@11570
  1290
		return;
patmandin@11570
  1291
	}
patmandin@11570
  1292
patmandin@11570
  1293
	/* Calculate intersection rectangle to redraw */
patmandin@11570
  1294
	max_width = MIN(work_rect[2], rect[2]);
patmandin@11570
  1295
	max_height = MIN(work_rect[3], rect[3]);
patmandin@11570
  1296
patmandin@11570
  1297
	pxy[4]=pxy[0]=MAX(work_rect[0],rect[0]);
patmandin@11570
  1298
	pxy[5]=pxy[1]=MAX(work_rect[1],rect[1]);
patmandin@11570
  1299
	pxy[6]=pxy[2]=pxy[0]+max_width-1;
patmandin@11570
  1300
	pxy[7]=pxy[3]=pxy[1]+max_height-1;
patmandin@736
  1301
patmandin@11570
  1302
	/* Calculate source image pos relative to window */
patmandin@11570
  1303
	pxy[0] -= GEM_work_x;
patmandin@11570
  1304
	pxy[1] -= GEM_work_y;
patmandin@11570
  1305
	pxy[2] -= GEM_work_x;
patmandin@11570
  1306
	pxy[3] -= GEM_work_y;
patmandin@11570
  1307
patmandin@11570
  1308
	/* TODO: finally clip against screen */
patmandin@11570
  1309
patmandin@11570
  1310
#if DEBUG_VIDEO_GEM
patmandin@11570
  1311
	printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n",
patmandin@11570
  1312
		surface->w, surface->h,
patmandin@11570
  1313
		pxy[0],pxy[1],pxy[2],pxy[3],
patmandin@11570
  1314
		pxy[4],pxy[5],pxy[6],pxy[7]
patmandin@11570
  1315
	);
patmandin@11570
  1316
#endif
slouken@281
  1317
patmandin@736
  1318
	if (GEM_bufops & B2S_C2P_1TO2) {
patmandin@736
  1319
		void *src, *dest;
patmandin@736
  1320
		int x1,x2;
patmandin@736
  1321
patmandin@11570
  1322
		x1 = pxy[0] & ~15;
patmandin@11570
  1323
		x2 = pxy[2];
patmandin@736
  1324
		if (x2 & 15) {
patmandin@736
  1325
			x2 = (x2 | 15) +1;
patmandin@736
  1326
		}
patmandin@736
  1327
patmandin@736
  1328
		src = surface->pixels;
patmandin@11570
  1329
		src += surface->pitch * pxy[1];
patmandin@736
  1330
		src += x1;
patmandin@736
  1331
patmandin@736
  1332
		dest = GEM_buffer2;
patmandin@11570
  1333
		dest += surface->pitch * pxy[1];
patmandin@736
  1334
		dest += x1;
slouken@281
  1335
patmandin@736
  1336
		SDL_Atari_C2pConvert(
patmandin@736
  1337
			src, dest,
patmandin@11570
  1338
			x2-x1, pxy[3]-pxy[1]+1,
patmandin@736
  1339
			SDL_FALSE,
patmandin@736
  1340
			surface->pitch, surface->pitch
patmandin@736
  1341
		);
patmandin@736
  1342
	}
patmandin@736
  1343
patmandin@736
  1344
	mfdb_src.fd_addr=surface->pixels;
patmandin@799
  1345
	{
patmandin@799
  1346
		int width;
patmandin@799
  1347
patmandin@799
  1348
		/* Need to be a multiple of 16 pixels */
patmandin@799
  1349
		width=surface->w;
patmandin@918
  1350
		if ((width & 15) != 0) {
patmandin@799
  1351
			width = (width | 15) + 1;
patmandin@799
  1352
		}
patmandin@799
  1353
		mfdb_src.fd_w=width;
patmandin@799
  1354
	}
patmandin@736
  1355
	mfdb_src.fd_h=surface->h;
patmandin@11569
  1356
	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
patmandin@736
  1357
	mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
patmandin@736
  1358
	mfdb_src.fd_stand=
patmandin@736
  1359
		mfdb_src.fd_r1=
patmandin@11569
  1360
		mfdb_src.fd_r2=
patmandin@11569
  1361
		mfdb_src.fd_r3= 0;
patmandin@736
  1362
patmandin@736
  1363
	if (GEM_bufops & B2S_VROCPYFM_2TOS) {
patmandin@736
  1364
		mfdb_src.fd_addr=GEM_buffer2;
patmandin@736
  1365
	}
patmandin@736
  1366
slouken@281
  1367
	vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
slouken@281
  1368
}
patmandin@984
  1369
slouken@1361
  1370
#if SDL_VIDEO_OPENGL
patmandin@984
  1371
patmandin@989
  1372
static void GEM_GL_SwapBuffers(_THIS)
patmandin@984
  1373
{
patmandin@993
  1374
	SDL_AtariGL_SwapBuffers(this);
patmandin@993
  1375
	GEM_FlipHWSurface(this, this->screen);
patmandin@984
  1376
}
patmandin@984
  1377
patmandin@984
  1378
#endif