SDL_gemvideo.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:27k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_gemvideo.c,v 1.1 2002/04/22 21:38:05 wmay Exp $";
  21. #endif
  22. /*
  23.  * GEM SDL video driver implementation
  24.  * inspired from the Dummy SDL driver
  25.  * 
  26.  * Patrice Mandin
  27.  * and work from
  28.  * Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
  29.  */
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. /* Mint includes */
  34. #include <gem.h>
  35. #include <gemx.h>
  36. #include <mint/osbind.h>
  37. #include <sys/cookie.h>
  38. #include "SDL.h"
  39. #include "SDL_error.h"
  40. #include "SDL_video.h"
  41. #include "SDL_mouse.h"
  42. #include "SDL_sysvideo.h"
  43. #include "SDL_pixels_c.h"
  44. #include "SDL_events_c.h"
  45. #include "SDL_cursor_c.h"
  46. #include "SDL_ataric2p_s.h"
  47. #include "SDL_ataric2p060_c.h"
  48. #include "SDL_atarieddi_s.h"
  49. #include "SDL_atarimxalloc_c.h"
  50. #include "SDL_gemvideo.h"
  51. #include "SDL_gemevents_c.h"
  52. #include "SDL_gemmouse_c.h"
  53. #include "SDL_gemwm_c.h"
  54. #include "SDL_xbiosevents_c.h"
  55. /* Defines */
  56. #define GEM_VID_DRIVER_NAME "gem"
  57. /* Variables */
  58. static unsigned char vdi_index[256] = {
  59. 0,  2,  3,  6,  4,  7,  5,   8,
  60. 9, 10, 11, 14, 12, 15, 13, 255
  61. };
  62. static const unsigned char empty_name[]="";
  63. /* Initialization/Query functions */
  64. static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
  65. static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
  66. static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
  67. static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
  68. static void GEM_VideoQuit(_THIS);
  69. /* Hardware surface functions */
  70. static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
  71. static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
  72. static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
  73. static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
  74. static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
  75. static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
  76. #if 0
  77. static int GEM_ToggleFullScreen(_THIS, int on);
  78. #endif
  79. /* Internal functions */
  80. static void GEM_FreeBuffers(_THIS);
  81. static void GEM_ClearScreen(_THIS);
  82. static void GEM_LockScreen(_THIS);
  83. static void GEM_UnlockScreen(_THIS);
  84. static void refresh_window(_THIS, int winhandle, short *rect);
  85. /* GEM driver bootstrap functions */
  86. static int GEM_Available(void)
  87. {
  88. short ap_id;
  89. const char *envr = getenv("SDL_VIDEODRIVER");
  90. /* Check if user asked a different video driver */
  91. if ((envr) && (strcmp(envr, GEM_VID_DRIVER_NAME)!=0)) {
  92. return 0;
  93. }
  94. /* Test if AES available */
  95. ap_id = appl_init();
  96. if (ap_id == -1)
  97. return 0;
  98. appl_exit();
  99. return 1;
  100. }
  101. static void GEM_DeleteDevice(SDL_VideoDevice *device)
  102. {
  103. free(device->hidden);
  104. free(device);
  105. }
  106. static SDL_VideoDevice *GEM_CreateDevice(int devindex)
  107. {
  108. SDL_VideoDevice *device;
  109. /* Initialize all variables that we clean on shutdown */
  110. device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
  111. if ( device ) {
  112. memset(device, 0, (sizeof *device));
  113. device->hidden = (struct SDL_PrivateVideoData *)
  114. malloc((sizeof *device->hidden));
  115. }
  116. if ( (device == NULL) || (device->hidden == NULL) ) {
  117. SDL_OutOfMemory();
  118. if ( device ) {
  119. free(device);
  120. }
  121. return(0);
  122. }
  123. memset(device->hidden, 0, (sizeof *device->hidden));
  124. atari_test_cpu060_present();
  125. /* Set the function pointers */
  126. device->VideoInit = GEM_VideoInit;
  127. device->ListModes = GEM_ListModes;
  128. device->SetVideoMode = GEM_SetVideoMode;
  129. device->SetColors = GEM_SetColors;
  130. device->UpdateRects = NULL /*GEM_UpdateRects*/;
  131. device->VideoQuit = GEM_VideoQuit;
  132. device->AllocHWSurface = GEM_AllocHWSurface;
  133. device->LockHWSurface = GEM_LockHWSurface;
  134. device->UnlockHWSurface = GEM_UnlockHWSurface;
  135. device->FlipHWSurface = GEM_FlipHWSurface;
  136. device->FreeHWSurface = GEM_FreeHWSurface;
  137. device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen*/;
  138. /* Window manager */
  139. device->SetCaption = GEM_SetCaption;
  140. device->SetIcon = NULL /*GEM_SetIcon*/;
  141. device->IconifyWindow = GEM_IconifyWindow;
  142. device->GrabInput = GEM_GrabInput;
  143. /* Events */
  144. device->InitOSKeymap = GEM_InitOSKeymap;
  145. device->PumpEvents = GEM_PumpEvents;
  146. /* Mouse */
  147. device->FreeWMCursor = GEM_FreeWMCursor;
  148. device->CreateWMCursor = GEM_CreateWMCursor;
  149. device->ShowWMCursor = GEM_ShowWMCursor;
  150. device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
  151. device->CheckMouseMode = GEM_CheckMouseMode;
  152. /* Joystick + Mouse relative motion */
  153. SDL_AtariXbios_InstallVectors(ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS);
  154. device->free = GEM_DeleteDevice;
  155. return device;
  156. }
  157. VideoBootStrap GEM_bootstrap = {
  158. GEM_VID_DRIVER_NAME, "Atari GEM video driver",
  159. GEM_Available, GEM_CreateDevice
  160. };
  161. static void VDI_ReadExtInfo(_THIS, short *work_out)
  162. {
  163. unsigned long EdDI_version;
  164. unsigned long cookie_EdDI;
  165. Uint32 num_colours;
  166. Uint16 clut_type, num_bits;
  167. /* Read EdDI informations */
  168. if  (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) {
  169. return;
  170. }
  171. EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
  172. vq_scrninfo(VDI_handle, work_out);
  173. VDI_format = work_out[0];
  174. clut_type = work_out[1];
  175. num_bits = work_out[2];
  176. num_colours = *((Uint32 *) &work_out[3]);
  177. /* With EdDI>=1.1, we can have screen pitch, address and format
  178.  * so we can directly write to screen without using vro_cpyfm
  179.  */
  180. if (EdDI_version >= EDDI_11) {
  181. VDI_pitch = work_out[5];
  182. VDI_screen = (void *) *((unsigned long *) &work_out[6]);
  183. switch(num_colours) {
  184. case 32768UL:
  185. if (work_out[14] & (1<<7)) {
  186. /* Little endian */
  187. if (work_out[14] & (1<<1)) {
  188. /* Falcon */
  189. VDI_alphamask = 1 << 13;
  190. VDI_redmask = 31 << 3;
  191. VDI_greenmask = (3 << 14) | 7;
  192. VDI_bluemask = 31 << 8;
  193. } else {
  194. /* Others */
  195. VDI_alphamask = 1 << 7;
  196. VDI_redmask = 31 << 2;
  197. VDI_greenmask = (7 << 13) | 3;
  198. VDI_bluemask = 31 << 8;
  199. }
  200. } else {
  201. /* Big endian */
  202. if (work_out[14] & (1<<1)) {
  203. /* Falcon */
  204. VDI_alphamask = 1 << 5;
  205. VDI_redmask = 31 << 11;
  206. VDI_greenmask = 31 << 6;
  207. VDI_bluemask = 31;
  208. } else {
  209. /* Others */
  210. VDI_alphamask = 1 << 15;
  211. VDI_redmask = 31 << 10;
  212. VDI_greenmask = 31 << 5;
  213. VDI_bluemask = 31;
  214. }
  215. }
  216. break;
  217. case 65536UL:
  218. if (work_out[14] & (1<<7)) {
  219. /* Little endian */
  220. VDI_alphamask = 0;
  221. VDI_redmask = 31 << 3;
  222. VDI_greenmask = (7 << 13) | 7;
  223. VDI_bluemask = 31 << 8;
  224. } else {
  225. /* Big endian */
  226. VDI_alphamask = 0;
  227. VDI_redmask = 31 << 11;
  228. VDI_greenmask = 63 << 5;
  229. VDI_bluemask = 31;
  230. }
  231. break;
  232. case 16777216UL:
  233. if (work_out[14] & (1<<7)) {
  234. /* Little endian */
  235. switch(num_bits) {
  236. case 24:
  237. VDI_alphamask = 0;
  238. VDI_redmask = 255;
  239. VDI_greenmask = 255 << 8;
  240. VDI_bluemask = 255 << 16;
  241. break;
  242. case 32:
  243. VDI_alphamask = 255;
  244. VDI_redmask = 255 << 8;
  245. VDI_greenmask = 255 << 16;
  246. VDI_bluemask = 255 << 24;
  247. break;
  248. }
  249. } else {
  250. /* Big endian */
  251. switch(num_bits) {
  252. case 24:
  253. VDI_alphamask = 0;
  254. VDI_redmask = 255 << 16;
  255. VDI_greenmask = 255 << 8;
  256. VDI_bluemask = 255;
  257. break;
  258. case 32:
  259. VDI_alphamask = 255 << 24;
  260. VDI_redmask = 255 << 16;
  261. VDI_greenmask = 255 << 8;
  262. VDI_bluemask = 255;
  263. break;
  264. }
  265. }
  266. break;
  267. }
  268. }
  269. switch(clut_type) {
  270. case VDI_CLUT_HARDWARE:
  271. {
  272. int i;
  273. Uint16 *tmp_p;
  274. tmp_p = (Uint16 *)&work_out[16];
  275. for (i=0;i<256;i++) {
  276. vdi_index[*tmp_p++] = i;
  277. }
  278. }
  279. break;
  280. case VDI_CLUT_SOFTWARE:
  281. if (EdDI_version < EDDI_11) {
  282. int component; /* red, green, blue, alpha, overlay */
  283. int num_bit;
  284. unsigned short *tmp_p;
  285. /* We can build masks with info here */
  286. tmp_p = (unsigned short *) &work_out[16];
  287. for (component=0;component<5;component++) {
  288. for (num_bit=0;num_bit<16;num_bit++) {
  289. unsigned short valeur;
  290. valeur = *tmp_p++;
  291. if (valeur == 0xffff) {
  292. continue;
  293. }
  294. switch(component) {
  295. case 0:
  296. VDI_redmask |= 1<< valeur;
  297. break;
  298. case 1:
  299. VDI_greenmask |= 1<< valeur;
  300. break;
  301. case 2:
  302. VDI_bluemask |= 1<< valeur;
  303. break;
  304. case 3:
  305. VDI_alphamask |= 1<< valeur;
  306. break;
  307. }
  308. }
  309. }
  310. }
  311. /* Remove lower green bits for Intel endian screen */
  312. if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
  313. VDI_greenmask &= ~(7<<13);
  314. }
  315. break;
  316. case VDI_CLUT_NONE:
  317. break;
  318. }
  319. }
  320. int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
  321. {
  322. int i;
  323. short work_in[12], work_out[272], dummy;
  324. /* Open AES (Application Environment Services) */
  325. GEM_ap_id = appl_init();
  326. if (GEM_ap_id == -1) {
  327. fprintf(stderr,"Can not open AESn");
  328. return 1;
  329. }
  330. /* Read version and features */
  331. GEM_version = aes_global[0];
  332. if (GEM_version >= 0x0400) {
  333. short ap_gout[4];
  334. GEM_wfeatures=0;
  335. if (appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3])==0) {
  336. GEM_wfeatures=ap_gout[0];
  337. }
  338. }
  339. /* Ask VDI physical workstation handle opened by AES */
  340. VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
  341. if (VDI_handle<1) {
  342. fprintf(stderr,"Wrong VDI handle %d returned by AESn",VDI_handle);
  343. return 1;
  344. }
  345. /* Open virtual VDI workstation */
  346. work_in[0]=Getrez()+2;
  347. for(i = 1; i < 10; i++)
  348. work_in[i] = 1;
  349. work_in[10] = 2;
  350. v_opnvwk(work_in, &VDI_handle, work_out);
  351. if (VDI_handle == 0) {
  352. fprintf(stderr,"Can not open VDI virtual workstationn");
  353. return 1;
  354. }
  355. /* Read fullscreen size */
  356. VDI_w = work_out[0] + 1;
  357. VDI_h = work_out[1] + 1;
  358. /* Read desktop size and position */
  359. if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
  360. fprintf(stderr,"Can not read desktop propertiesn");
  361. return 1;
  362. }
  363. /* Read bit depth */
  364. vq_extnd(VDI_handle, 1, work_out);
  365. VDI_bpp = work_out[4];
  366. VDI_oldnumcolors=0;
  367. switch(VDI_bpp) {
  368. case 8:
  369. VDI_pixelsize=1;
  370. break;
  371. case 15:
  372. case 16:
  373. VDI_pixelsize=2;
  374. break;
  375. case 24:
  376. VDI_pixelsize=3;
  377. break;
  378. case 32:
  379. VDI_pixelsize=4;
  380. break;
  381. default:
  382. fprintf(stderr,"%d bits colour depth not supportedn",VDI_bpp);
  383. return 1;
  384. }
  385. /* Setup hardware -> VDI palette mapping */
  386. for(i = 16; i < 255; i++) {
  387. vdi_index[i] = i;
  388. }
  389. vdi_index[255] = 1;
  390. /* Save current palette */
  391. if (VDI_bpp>8) {
  392. VDI_oldnumcolors=1<<8;
  393. } else {
  394. VDI_oldnumcolors=1<<VDI_bpp;
  395. }
  396. for(i = 0; i < VDI_oldnumcolors; i++) {
  397. short rgb[3];
  398. vq_color(VDI_handle, i, 0, rgb);
  399. VDI_oldpalette[i][0] = rgb[0];
  400. VDI_oldpalette[i][1] = rgb[1];
  401. VDI_oldpalette[i][2] = rgb[2];
  402. }
  403. /* Setup screen info */
  404. GEM_title_name = empty_name;
  405. GEM_icon_name = empty_name;
  406. GEM_handle = -1;
  407. GEM_locked = SDL_FALSE;
  408. GEM_win_fulled = SDL_FALSE;
  409. VDI_screen = NULL;
  410. VDI_ReadExtInfo(this, work_out);
  411. if (VDI_screen == NULL) {
  412. VDI_pitch = VDI_w * VDI_pixelsize;
  413. VDI_format = VDI_FORMAT_UNKNOWN;
  414. VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
  415. }
  416. /* Setup destination mfdb */
  417. VDI_dst_mfdb.fd_addr = NULL;
  418. /* Update hardware info */
  419. this->info.hw_available = 0;
  420. this->info.video_mem = 0;
  421. /* TC, screen : no shadow (direct)
  422.      *  8P, screen: no shadow (direct)
  423.      *  8I, screen: shadow, c2p (shadow -> c2p)
  424.  *  TC, no screen: shadow (vro_cpyfm)
  425.  *  8P, no screen: shadow (vro_cpyfm)
  426.  *  8I/U, no screen: shadow, shadow_c2p, c2p (shadow -> c2p -> vro_cpyfm)
  427.  */
  428. /* Determine the screen depth */
  429. /* we change this during the SDL_SetVideoMode implementation... */
  430. vformat->BitsPerPixel = VDI_bpp;
  431. /* Set mouse cursor to arrow */
  432. graf_mouse(ARROW, NULL);
  433. /* Init chunky to planar routine */
  434. Atari_C2pInit = Atari_C2pInit8;
  435. if (atari_cpu060_avail) {
  436. Atari_C2pConvert = Atari_C2pConvert8_060;
  437. } else {
  438. Atari_C2pConvert = Atari_C2pConvert8;
  439. }
  440. Atari_C2pInit();
  441. /* We're done! */
  442. return(0);
  443. }
  444. SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
  445. {
  446. if (format->BitsPerPixel == VDI_bpp) {
  447. return((SDL_Rect **)-1);
  448. } else {
  449. return ((SDL_Rect **)NULL);
  450. }
  451. }
  452. static void GEM_FreeBuffers(_THIS)
  453. {
  454. /* Release buffer */
  455. if ( GEM_buffer ) {
  456. free( GEM_buffer );
  457. GEM_buffer=NULL;
  458. }
  459. /* Destroy window */
  460. if (GEM_handle>=0) {
  461. wind_close(GEM_handle);
  462. wind_delete(GEM_handle);
  463. GEM_handle=-1;
  464. }
  465. }
  466. static void GEM_ClearScreen(_THIS)
  467. {
  468. short rgb[3]={0,0,0};
  469. short oldrgb[3];
  470. short pxy[4];
  471. v_hide_c(VDI_handle);
  472. vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
  473. vs_color(VDI_handle, vdi_index[0], rgb);
  474. pxy[0] = pxy[1] = 0;
  475. pxy[2] = VDI_w - 1;
  476. pxy[3] = VDI_h - 1;
  477. vsf_color(VDI_handle,0);
  478. vsf_interior(VDI_handle,1);
  479. vsf_perimeter(VDI_handle,0);
  480. v_bar(VDI_handle,pxy);
  481. vs_color(VDI_handle, vdi_index[0], oldrgb);
  482. v_show_c(VDI_handle, 1);
  483. }
  484. static void GEM_LockScreen(_THIS)
  485. {
  486. if (!GEM_locked) {
  487. /* Reserve memory space, used to be sure of compatibility */
  488. form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
  489. /* Lock AES */
  490. wind_update(BEG_UPDATE);
  491. wind_update(BEG_MCTRL);
  492. GEM_locked=SDL_TRUE;
  493. }
  494. }
  495. static void GEM_UnlockScreen(_THIS)
  496. {
  497. if (GEM_locked) {
  498. /* Restore screen memory, and send REDRAW to all apps */
  499. form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
  500. /* Unlock AES */
  501. wind_update(END_MCTRL);
  502. wind_update(END_UPDATE);
  503. GEM_locked=SDL_FALSE;
  504. }
  505. }
  506. SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
  507. int width, int height, int bpp, Uint32 flags)
  508. {
  509. int maxwidth, maxheight;
  510. Uint32 modeflags, screensize;
  511. SDL_bool use_shadow;
  512. modeflags = SDL_HWPALETTE;
  513. GEM_FreeBuffers(this);
  514. /*--- Verify if asked mode can be used ---*/
  515. if (flags & SDL_FULLSCREEN) {
  516. maxwidth=VDI_w;
  517. maxheight=VDI_h;
  518. } else {
  519. /* Windowed mode */
  520. maxwidth=GEM_desk_w;
  521. maxheight=GEM_desk_h;
  522. }
  523. if ((maxwidth < width) || (maxheight < height) || (VDI_bpp != bpp)) {
  524. SDL_SetError("Couldn't find requested mode in list");
  525. return(NULL);
  526. }
  527. /*--- Allocate the new pixel format for the screen ---*/
  528. if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
  529. SDL_SetError("Couldn't allocate new pixel format for requested mode");
  530. return(NULL);
  531. }
  532. /*--- Allocate shadow buffer if needed ---*/
  533. use_shadow=SDL_FALSE;
  534. if (flags & SDL_FULLSCREEN) {
  535. if (!VDI_screen) {
  536. /* No access to real framebuffer, use shadow surface */
  537. use_shadow=SDL_TRUE;
  538. } else {
  539. if (VDI_format==VDI_FORMAT_INTER) {
  540. /* Real framebuffer, interleaved bitplanes,
  541.   use shadow surface */
  542. use_shadow=SDL_TRUE;
  543. } else if (flags & SDL_DOUBLEBUF) {
  544. /* Real framebuffer, double-buffered,
  545.   use shadow surface */
  546. use_shadow=SDL_TRUE;
  547. modeflags |= SDL_DOUBLEBUF;
  548. }
  549. }
  550. } else {
  551. /* Windowed mode, always with shadow surface */
  552. use_shadow=SDL_TRUE;
  553. }
  554. if (use_shadow) {
  555. screensize = width * height * VDI_pixelsize;
  556. GEM_buffer = Atari_SysMalloc(screensize, MX_PREFTTRAM);
  557. if (GEM_buffer==NULL) {
  558. fprintf(stderr,"Unable to allocate shadow buffern");
  559. return NULL;
  560. }
  561. memset(GEM_buffer, 0, screensize);
  562. }
  563. /*--- Initialize screen ---*/
  564. if (flags & SDL_FULLSCREEN) {
  565. GEM_LockScreen(this);
  566. GEM_ClearScreen(this);
  567. modeflags |= SDL_FULLSCREEN;
  568. if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow) {
  569. modeflags |= SDL_HWSURFACE;
  570. } else {
  571. modeflags |= SDL_SWSURFACE;
  572. }
  573. } else {
  574. int posx,posy;
  575. short x2,y2,w2,h2;
  576. GEM_UnlockScreen(this);
  577. /* Center our window */
  578. posx = GEM_desk_x;
  579. posy = GEM_desk_y;
  580. if (width<GEM_desk_w)
  581. posx += (GEM_desk_w - width) >> 1;
  582. if (height<GEM_desk_h)
  583. posy += (GEM_desk_h - height) >> 1;
  584. /* Calculate our window size and position */
  585. if (!(flags & SDL_NOFRAME)) {
  586. GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
  587. if (flags & SDL_RESIZABLE) {
  588. GEM_win_type |= FULLER|SIZER;
  589. modeflags |= SDL_RESIZABLE;
  590. }
  591. } else {
  592. GEM_win_type=0;
  593. modeflags |= SDL_NOFRAME;
  594. }
  595. if (!wind_calc(0, GEM_win_type, posx, posy, width, height, &x2, &y2, &w2, &h2)) {
  596. GEM_FreeBuffers(this);
  597. fprintf(stderr,"Can not calculate window attributesn");
  598. return NULL;
  599. }
  600. /* Create window */
  601. GEM_handle=wind_create(GEM_win_type, x2, y2, w2, h2);
  602. if (GEM_handle<0) {
  603. GEM_FreeBuffers(this);
  604. fprintf(stderr,"Can not create windown");
  605. return NULL;
  606. }
  607. /* Setup window name */
  608. wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
  609. /* Open the window */
  610. wind_open(GEM_handle,x2,y2,w2,h2);
  611. modeflags |= SDL_SWSURFACE;
  612. }
  613. /* Set up the new mode framebuffer */
  614. current->flags = modeflags;
  615. current->w = width;
  616. current->h = height;
  617. if (use_shadow) {
  618. current->pixels = GEM_buffer;
  619. current->pitch = width * (VDI_bpp >> 3);
  620. } else {
  621. current->pixels = VDI_screen;
  622. current->pixels += VDI_pitch * ((VDI_h - height) >> 1);
  623. current->pixels += VDI_pixelsize * ((VDI_w - width) >> 1);
  624. current->pitch = VDI_pitch;
  625. }
  626. this->UpdateRects = GEM_UpdateRects;
  627. /* We're done */
  628. return(current);
  629. }
  630. /* We don't actually allow hardware surfaces other than the main one */
  631. static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
  632. {
  633. return -1;
  634. }
  635. static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
  636. {
  637. return;
  638. }
  639. /* We need to wait for vertical retrace on page flipped displays */
  640. static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
  641. {
  642. return(0);
  643. }
  644. static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
  645. {
  646. return;
  647. }
  648. static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
  649. {
  650. SDL_Surface *surface;
  651. MFDB mfdb_src;
  652. short blitcoords[8];
  653. int i;
  654. surface = this->screen;
  655. if (VDI_screen) {
  656. if (VDI_format==VDI_FORMAT_INTER) {
  657. void *destscr;
  658. int destx;
  659. destscr = VDI_screen;
  660. destscr += VDI_pitch * ((VDI_h - surface->h) >> 1);
  661. destx = (VDI_w - surface->w) >> 1;
  662. destx &= ~15;
  663. destscr += destx;
  664. for (i=0;i<numrects;i++) {
  665. void *source,*destination;
  666. int x1,x2;
  667. x1 = rects[i].x & ~15;
  668. x2 = rects[i].x+rects[i].w;
  669. if (x2 & 15) {
  670. x2 = (x2 | 15) +1;
  671. }
  672. source = surface->pixels;
  673. source += surface->pitch * rects[i].y;
  674. source += x1;
  675. destination = destscr;
  676. destination += VDI_pitch * rects[i].y;
  677. destination += x1;
  678. /* Convert chunky to planar screen */
  679. Atari_C2pConvert(
  680. source,
  681. destination,
  682. x2-x1,
  683. rects[i].h,
  684. SDL_FALSE,
  685. surface->pitch,
  686. VDI_pitch
  687. );
  688. }
  689. return;
  690. }
  691. if (!(surface->flags & SDL_DOUBLEBUF)) {
  692. return;
  693. }
  694. }
  695. mfdb_src.fd_addr=surface->pixels;
  696. mfdb_src.fd_w=surface->w;
  697. mfdb_src.fd_h=surface->h;
  698. mfdb_src.fd_wdwidth=(surface->w) >> 4;
  699. mfdb_src.fd_stand=0;
  700. mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
  701. mfdb_src.fd_r1=0;
  702. mfdb_src.fd_r2=0;
  703. mfdb_src.fd_r3=0;
  704. for ( i=0; i<numrects; ++i ) {
  705. blitcoords[0] = rects[i].x;
  706. blitcoords[1] = rects[i].y;
  707. blitcoords[2] = blitcoords[0] + rects[i].w - 1;
  708. blitcoords[3] = blitcoords[1] + rects[i].h - 1;
  709. blitcoords[4] = rects[i].x + ((VDI_w - surface->w) >> 1);
  710. blitcoords[5] = rects[i].y + ((VDI_h - surface->h) >> 1);
  711. blitcoords[6] = blitcoords[4] + rects[i].w - 1;
  712. blitcoords[7] = blitcoords[5] + rects[i].h - 1;
  713. vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
  714. }
  715. }
  716. static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
  717. {
  718. short pxy[8], wind_pxy[8];
  719. int i;
  720. wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3]);
  721. for ( i=0; i<numrects; ++i ) {
  722. pxy[0] = wind_pxy[0] + rects[i].x;
  723. pxy[1] = wind_pxy[1] + rects[i].y;
  724. pxy[2] = rects[i].w;
  725. pxy[3] = rects[i].h;
  726. GEM_wind_redraw(this, GEM_handle, pxy);
  727. }
  728. }
  729. static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
  730. {
  731. SDL_Surface *surface;
  732. surface = this->screen;
  733. if (surface->flags & SDL_FULLSCREEN) {
  734. GEM_UpdateRectsFullscreen(this, numrects, rects);
  735. } else {
  736. GEM_UpdateRectsWindowed(this, numrects, rects);
  737. }
  738. }
  739. static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
  740. {
  741. MFDB mfdb_src;
  742. short blitcoords[8];
  743. if (VDI_screen) {
  744. if (VDI_format==VDI_FORMAT_INTER) {
  745. void *destscr;
  746. int destx;
  747. /* Center on destination screen */
  748. destscr = VDI_screen;
  749. destscr += VDI_pitch * ((VDI_h - surface->h) >> 1);
  750. destx = (VDI_w - surface->w) >> 1;
  751. destx &= ~15;
  752. destscr += destx;
  753. /* Convert chunky to planar screen */
  754. Atari_C2pConvert(
  755. surface->pixels,
  756. destscr,
  757. surface->w,
  758. surface->h,
  759. SDL_FALSE,
  760. surface->pitch,
  761. VDI_pitch
  762. );
  763. return(0);
  764. }
  765. if (!(surface->flags & SDL_DOUBLEBUF)) {
  766. return(0);
  767. }
  768. }
  769. mfdb_src.fd_addr=surface->pixels;
  770. mfdb_src.fd_w=surface->w;
  771. mfdb_src.fd_h=surface->h;
  772. mfdb_src.fd_wdwidth=(surface->w) >> 4;
  773. mfdb_src.fd_stand=0;
  774. mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
  775. mfdb_src.fd_r1=0;
  776. mfdb_src.fd_r2=0;
  777. mfdb_src.fd_r3=0;
  778. blitcoords[0] = 0;
  779. blitcoords[1] = 0;
  780. blitcoords[2] = surface->w - 1;
  781. blitcoords[3] = surface->h - 1;
  782. blitcoords[4] = (VDI_w - surface->w) >> 1;
  783. blitcoords[5] = (VDI_h - surface->h) >> 1;
  784. blitcoords[6] = blitcoords[4] + surface->w - 1;
  785. blitcoords[7] = blitcoords[5] + surface->h - 1;
  786. vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
  787. return(0);
  788. }
  789. static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
  790. {
  791. short pxy[8];
  792. /* Update the whole window */
  793. wind_get(GEM_handle, WF_WORKXYWH, &pxy[0], &pxy[1], &pxy[2], &pxy[3]);
  794. GEM_wind_redraw(this, GEM_handle, pxy);
  795. return(0);
  796. }
  797. static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface)
  798. {
  799. if (surface->flags & SDL_FULLSCREEN) {
  800. return GEM_FlipHWSurfaceFullscreen(this, surface);
  801. } else {
  802. return GEM_FlipHWSurfaceWindowed(this, surface);
  803. }
  804. }
  805. static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  806. {
  807. int i;
  808. SDL_Surface *surface;
  809. /* Do not change palette in True Colour */
  810. surface = this->screen;
  811. if (surface->format->BitsPerPixel > 8) {
  812. return 1;
  813. }
  814. for(i = 0; i < ncolors; i++)
  815. {
  816. int r, g, b;
  817. short rgb[3];
  818. r = colors[i].r;
  819. g = colors[i].g;
  820. b = colors[i].b;
  821. rgb[0] = (1000 * r) / 255;
  822. rgb[1] = (1000 * g) / 255;
  823. rgb[2] = (1000 * b) / 255;
  824. vs_color(VDI_handle, vdi_index[firstcolor+i], rgb);
  825. }
  826. return(1);
  827. }
  828. #if 0
  829. static int GEM_ToggleFullScreen(_THIS, int on)
  830. {
  831. if (on) {
  832. GEM_LockScreen(this);
  833. } else {
  834. GEM_UnlockScreen(this);
  835. }
  836. return(1);
  837. }
  838. #endif
  839. /* Note:  If we are terminated, this could be called in the middle of
  840.    another SDL video routine -- notably UpdateRects.
  841. */
  842. void GEM_VideoQuit(_THIS)
  843. {
  844. SDL_AtariXbios_RestoreVectors();
  845. GEM_FreeBuffers(this);
  846. GEM_UnlockScreen(this);
  847. appl_exit();
  848. /* Restore palette */
  849. if (VDI_oldnumcolors) {
  850. int i;
  851. for(i = 0; i < VDI_oldnumcolors; i++) {
  852. short rgb[3];
  853. rgb[0] = VDI_oldpalette[i][0];
  854. rgb[1] = VDI_oldpalette[i][1];
  855. rgb[2] = VDI_oldpalette[i][2];
  856. vs_color(VDI_handle, i, rgb);
  857. }
  858. }
  859. /* Close VDI workstation */
  860. if (VDI_handle) {
  861. v_clsvwk(VDI_handle);
  862. }
  863. /* Free mode list */
  864. if (SDL_modelist[0]) {
  865. free(SDL_modelist[0]);
  866. SDL_modelist[0]=NULL;
  867. }
  868. this->screen->pixels = NULL;
  869. }
  870. void GEM_wind_redraw(_THIS, int winhandle, short *inside)
  871. {
  872. short todo[4];
  873. /* Tell AES we are going to update */
  874. wind_update(BEG_UPDATE);
  875. v_hide_c(VDI_handle);
  876. /* Browse the rectangle list to redraw */
  877. wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3]);
  878. while (todo[2] && todo[3]) {
  879. if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
  880. todo[2] += todo[0]-1;
  881. todo[3] += todo[1]-1;
  882. refresh_window(this, winhandle, todo);
  883. }
  884. wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3]);
  885. }
  886. /* Update finished */
  887. wind_update(END_UPDATE);
  888. v_show_c(VDI_handle,1);
  889. }
  890. static void refresh_window(_THIS, int winhandle, short *rect)
  891. {
  892. MFDB mfdb_src;
  893. short pxy[8], wind_pxy[8];
  894. int iconified;
  895. SDL_Surface *surface;
  896. surface=this->screen;
  897. /* Is window iconified ? */
  898. iconified = 0;
  899. if (GEM_wfeatures & (1<<WF_ICONIFY)) {
  900. wind_get(winhandle, WF_ICONIFY, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3]);
  901. iconified = pxy[0];
  902. }
  903. wind_get(winhandle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3]);
  904. if (iconified) {
  905. /* Refresh icon */
  906. mfdb_src.fd_addr=surface->pixels; /* Should be icon image */
  907. mfdb_src.fd_w=surface->w;
  908. mfdb_src.fd_h=surface->h;
  909. mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
  910.    mfdb_src.fd_stand=0;
  911.    mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
  912. mfdb_src.fd_r1=0;
  913.    mfdb_src.fd_r2=0;
  914.    mfdb_src.fd_r3=0;
  915. } else {
  916. /* Refresh window */
  917. mfdb_src.fd_addr=surface->pixels;
  918. mfdb_src.fd_w=surface->w;
  919. mfdb_src.fd_h=surface->h;
  920. mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
  921.    mfdb_src.fd_stand=0;
  922.    mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
  923. mfdb_src.fd_r1=0;
  924.    mfdb_src.fd_r2=0;
  925.    mfdb_src.fd_r3=0;
  926. }
  927. pxy[0] = rect[0] - wind_pxy[0];
  928. pxy[1] = rect[1] - wind_pxy[1];
  929.   pxy[2] = pxy[0] + rect[2] - rect[0];   
  930.   pxy[3] = pxy[1] + rect[3] - rect[1];  
  931. pxy[4] = rect[0];
  932. pxy[5] = rect[1];
  933. pxy[6] = rect[2];  
  934. pxy[7] = rect[3];
  935. vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
  936. }