sdlwindow.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. unit sdlwindow;
  2. {
  3. $Id: sdlwindow.pas,v 1.7 2004/09/30 22:35:47 savage Exp $
  4. }
  5. {******************************************************************************}
  6. { }
  7. { JEDI-SDL : Pascal units for SDL - Simple DirectMedia Layer }
  8. { SDL Window Wrapper }
  9. { }
  10. { }
  11. { The initial developer of this Pascal code was : }
  12. { Dominique Louis <[email protected]> }
  13. { }
  14. { Portions created by Dominique Louis are }
  15. { Copyright (C) 2004 - 2100 Dominique Louis. }
  16. { }
  17. { }
  18. { Contributor(s) }
  19. { -------------- }
  20. { Dominique Louis <[email protected]> }
  21. { }
  22. { Obtained through: }
  23. { Joint Endeavour of Delphi Innovators ( Project JEDI ) }
  24. { }
  25. { You may retrieve the latest version of this file at the Project }
  26. { JEDI home page, located at http://delphi-jedi.org }
  27. { }
  28. { The contents of this file are used with permission, subject to }
  29. { the Mozilla Public License Version 1.1 (the "License"); you may }
  30. { not use this file except in compliance with the License. You may }
  31. { obtain a copy of the License at }
  32. { http://www.mozilla.org/MPL/MPL-1.1.html }
  33. { }
  34. { Software distributed under the License is distributed on an }
  35. { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
  36. { implied. See the License for the specific language governing }
  37. { rights and limitations under the License. }
  38. { }
  39. { Description }
  40. { ----------- }
  41. { SDL Window Wrapper }
  42. { }
  43. { }
  44. { Requires }
  45. { -------- }
  46. { SDL.dll on Windows platforms }
  47. { libSDL-1.1.so.0 on Linux platform }
  48. { }
  49. { Programming Notes }
  50. { ----------------- }
  51. { }
  52. { }
  53. { }
  54. { }
  55. { Revision History }
  56. { ---------------- }
  57. { January 31 2003 - DL : Initial creation }
  58. { }
  59. {
  60. $Log: sdlwindow.pas,v $
  61. Revision 1.7 2004/09/30 22:35:47 savage
  62. Changes, enhancements and additions as required to get SoAoS working.
  63. Revision 1.6 2004/09/12 21:52:58 savage
  64. Slight changes to fix some issues with the sdl classes.
  65. Revision 1.5 2004/05/10 21:11:49 savage
  66. changes required to help get SoAoS off the ground.
  67. Revision 1.4 2004/05/01 14:59:27 savage
  68. Updated code
  69. Revision 1.3 2004/04/23 10:45:28 savage
  70. Changes made by Dean Ellis to work more modularly.
  71. Revision 1.2 2004/03/31 10:06:41 savage
  72. Changed so that it now compiles, but is untested.
  73. Revision 1.1 2004/02/05 00:08:20 savage
  74. Module 1.0 release
  75. }
  76. {******************************************************************************}
  77. interface
  78. {$i jedi-sdl.inc}
  79. uses
  80. Classes,
  81. sdl,
  82. sdlinput,
  83. sdlticks;
  84. type
  85. TSDLNotifyEvent = procedure {$IFNDEF NOT_OO}of object{$ENDIF};
  86. TSDLUpdateEvent = procedure( aElapsedTime : single ) {$IFNDEF NOT_OO}of object{$ENDIF};
  87. TSDLResizeEvent = procedure( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  88. TSDLUserEvent = procedure( aType : UInt8; aCode : integer; aData1 : Pointer; aData2 : Pointer ) {$IFNDEF NOT_OO}of object{$ENDIF};
  89. TSDLActiveEvent = procedure( aGain: UInt8; aState: UInt8 ) {$IFNDEF NOT_OO}of object{$ENDIF};
  90. TSDLBaseWindow = class( TObject )
  91. private
  92. FDisplaySurface : PSDL_Surface;
  93. FVideoFlags : Uint32;
  94. FOnDestroy: TSDLNotifyEvent;
  95. FOnCreate: TSDLNotifyEvent;
  96. FOnShow: TSDLNotifyEvent;
  97. FOnResize: TSDLResizeEvent;
  98. FOnUpdate: TSDLUpdateEvent;
  99. FOnRender: TSDLNotifyEvent;
  100. FOnClose: TSDLNotifyEvent;
  101. FLoaded: Boolean;
  102. FRendering: Boolean;
  103. FHeight: integer;
  104. FBitDepth: integer;
  105. FWidth: integer;
  106. FInputManager: TSDLInputManager;
  107. FCaptionText : PChar;
  108. FIconName : PChar;
  109. FOnActive: TSDLActiveEvent;
  110. FOnQuit: TSDLNotifyEvent;
  111. FOnExpose: TSDLNotifyEvent;
  112. FOnUser: TSDLUserEvent;
  113. FTimer : TSDLTicks;
  114. protected
  115. procedure DoActive( aGain: UInt8; aState: UInt8 );
  116. procedure DoCreate;
  117. procedure DoClose;
  118. procedure DoDestroy;
  119. procedure DoUpdate( aElapsedTime : single );
  120. procedure DoQuit;
  121. procedure DoRender;
  122. procedure DoResize( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 );
  123. procedure DoShow;
  124. procedure DoUser( aType : UInt8; aCode : integer; aData1 : Pointer; aData2 : Pointer );
  125. procedure DoExpose;
  126. procedure Render; virtual;
  127. procedure Update( aElapsedTime : single ); virtual;
  128. procedure InitialiseObjects; virtual;
  129. procedure RestoreObjects; virtual;
  130. procedure DeleteObjects; virtual;
  131. function Flip : integer; virtual;
  132. property OnActive : TSDLActiveEvent read FOnActive write FOnActive;
  133. property OnClose: TSDLNotifyEvent read FOnClose write FOnClose;
  134. property OnDestroy : TSDLNotifyEvent read FOnDestroy write FOnDestroy;
  135. property OnCreate : TSDLNotifyEvent read FOnCreate write FOnCreate;
  136. property OnUpdate: TSDLUpdateEvent read FOnUpdate write FOnUpdate;
  137. property OnQuit : TSDLNotifyEvent read FOnQuit write FOnQuit;
  138. property OnResize : TSDLResizeEvent read FOnResize write FOnResize;
  139. property OnRender: TSDLNotifyEvent read FOnRender write FOnRender;
  140. property OnShow : TSDLNotifyEvent read FOnShow write FOnShow;
  141. property OnUser : TSDLUserEvent read FOnUser write FOnUser;
  142. property OnExpose : TSDLNotifyEvent read FOnExpose write FOnExpose;
  143. property DisplaySurface: PSDL_Surface read FDisplaySurface;
  144. public
  145. property InputManager : TSDLInputManager read FInputManager;
  146. property Loaded : Boolean read FLoaded;
  147. property Width : integer read FWidth;
  148. property Height : integer read FHeight;
  149. property BitDepth : integer read FBitDepth;
  150. property Rendering : Boolean read FRendering write FRendering;
  151. procedure SetCaption( const aCaptionText : string; const aIconName : string );
  152. procedure GetCaption( var aCaptionText : string; var aIconName : string );
  153. procedure SetIcon( aIcon : PSDL_Surface; aMask: UInt8 );
  154. procedure ActivateVideoMode;
  155. constructor Create( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 ); virtual;
  156. destructor Destroy; override;
  157. procedure InitialiseEnvironment;
  158. function Show : Boolean; virtual;
  159. end;
  160. TSDL2DWindow = class( TSDLBaseWindow )
  161. public
  162. constructor Create( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 = SDL_DOUBLEBUF or SDL_SWSURFACE); override;
  163. procedure Render; override;
  164. procedure Update( aElapsedTime : single ); override;
  165. procedure InitialiseObjects; override;
  166. procedure RestoreObjects; override;
  167. procedure DeleteObjects; override;
  168. function Flip : integer; override;
  169. property OnCreate;
  170. property OnDestroy;
  171. property OnClose;
  172. property OnShow;
  173. property OnResize;
  174. property OnRender;
  175. property OnUpdate;
  176. property DisplaySurface;
  177. end;
  178. TSDL3DWindow = class( TSDLBaseWindow )
  179. public
  180. constructor Create( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 = SDL_OPENGL or SDL_DOUBLEBUF); override;
  181. function Flip : integer; override;
  182. procedure Render; override;
  183. procedure Update( aElapsedTime : single ); override;
  184. procedure InitialiseObjects; override;
  185. procedure RestoreObjects; override;
  186. procedure DeleteObjects; override;
  187. property OnCreate;
  188. property OnDestroy;
  189. property OnClose;
  190. property OnShow;
  191. property OnResize;
  192. property OnRender;
  193. property OnUpdate;
  194. property DisplaySurface;
  195. end;
  196. implementation
  197. uses
  198. logger,
  199. SysUtils;
  200. { TSDLBaseWindow }
  201. procedure TSDLBaseWindow.ActivateVideoMode;
  202. begin
  203. FDisplaySurface := SDL_SetVideoMode( FWidth, FHeight, FBitDepth, FVideoFlags);
  204. if (FDisplaySurface = nil) then
  205. begin
  206. Log.LogError( Format('Could not set video mode: %s', [SDL_GetError]), 'Main');
  207. exit;
  208. end;
  209. SetCaption( 'Made with JEDI-SDL', 'JEDI-SDL Icon' );
  210. end;
  211. constructor TSDLBaseWindow.Create( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 );
  212. begin
  213. inherited Create;
  214. SDL_Init(SDL_INIT_EVERYTHING);
  215. FInputManager := TSDLInputManager.Create( [ itJoystick, itKeyBoard, itMouse ]);
  216. FTimer := TSDLTicks.Create;
  217. FWidth := aWidth;
  218. FHeight := aHeight;
  219. FBitDepth := aBitDepth;
  220. FVideoFlags := aVideoFlags;
  221. DoCreate;
  222. end;
  223. procedure TSDLBaseWindow.DeleteObjects;
  224. begin
  225. FLoaded := False;
  226. end;
  227. destructor TSDLBaseWindow.Destroy;
  228. begin
  229. DoDestroy;
  230. if FLoaded then
  231. DeleteObjects;
  232. if FInputManager <> nil then
  233. FreeAndNil( FInputManager );
  234. if FTimer <> nil then
  235. FreeAndNil( FTimer );
  236. if FDisplaySurface <> nil then
  237. SDL_FreeSurface( FDisplaySurface );
  238. inherited Destroy;
  239. SDL_Quit;
  240. end;
  241. procedure TSDLBaseWindow.DoActive(aGain, aState: UInt8);
  242. begin
  243. if Assigned( FOnActive ) then
  244. begin
  245. FOnActive( aGain, aState );
  246. end;
  247. end;
  248. procedure TSDLBaseWindow.DoClose;
  249. begin
  250. if Assigned( FOnClose ) then
  251. begin
  252. FOnClose;
  253. end;
  254. end;
  255. procedure TSDLBaseWindow.DoCreate;
  256. begin
  257. if Assigned( FOnCreate ) then
  258. begin
  259. FOnCreate;
  260. end;
  261. end;
  262. procedure TSDLBaseWindow.DoDestroy;
  263. begin
  264. if Assigned( FOnDestroy ) then
  265. begin
  266. FOnDestroy;
  267. end;
  268. end;
  269. procedure TSDLBaseWindow.DoExpose;
  270. begin
  271. if Assigned( FOnExpose ) then
  272. begin
  273. FOnExpose;
  274. end;
  275. end;
  276. procedure TSDLBaseWindow.DoUpdate( aElapsedTime : single );
  277. begin
  278. if Assigned( FOnUpdate ) then
  279. begin
  280. FOnUpdate( aElapsedTime );
  281. end;
  282. end;
  283. procedure TSDLBaseWindow.DoQuit;
  284. begin
  285. FRendering := false;
  286. if Assigned( FOnQuit ) then
  287. begin
  288. FOnQuit;
  289. end;
  290. end;
  291. procedure TSDLBaseWindow.DoRender;
  292. begin
  293. if Assigned( FOnRender ) then
  294. begin
  295. FOnRender;
  296. end;
  297. end;
  298. procedure TSDLBaseWindow.DoResize( aWidth : integer; aHeight : integer; aBitDepth : integer; aVideoFlags : Uint32 );
  299. begin
  300. // resize to the new size
  301. SDL_FreeSurface(FDisplaySurface);
  302. FWidth := aWidth;
  303. FHeight := aHeight;
  304. FBitDepth := aBitDepth;
  305. FVideoFlags := aVideoFlags;
  306. FDisplaySurface := SDL_SetVideoMode(aWidth, aHeight, aBitDepth, aVideoFlags);
  307. if Assigned( FOnResize ) then
  308. begin
  309. FOnResize( aWidth, aHeight, aBitDepth, aVideoFlags );
  310. end;
  311. end;
  312. procedure TSDLBaseWindow.DoShow;
  313. begin
  314. if Assigned( FOnShow ) then
  315. begin
  316. FOnShow;
  317. end;
  318. end;
  319. procedure TSDLBaseWindow.DoUser(aType: UInt8; aCode: integer; aData1, aData2: Pointer);
  320. begin
  321. if Assigned( FOnUser ) then
  322. begin
  323. FOnUser( aType, aCode, aData1, aData2 );
  324. end;
  325. end;
  326. function TSDLBaseWindow.Flip : integer;
  327. begin
  328. result := 0;
  329. end;
  330. procedure TSDLBaseWindow.GetCaption( var aCaptionText : string; var aIconName : string );
  331. begin
  332. aCaptionText := string( FCaptionText );
  333. aIconName := string( FIconName );
  334. end;
  335. procedure TSDLBaseWindow.InitialiseEnvironment;
  336. begin
  337. InitialiseObjects;
  338. RestoreObjects;
  339. end;
  340. procedure TSDLBaseWindow.InitialiseObjects;
  341. begin
  342. FLoaded := True;
  343. end;
  344. procedure TSDLBaseWindow.Update( aElapsedTime : single );
  345. begin
  346. DoUpdate( aElapsedTime );
  347. end;
  348. procedure TSDLBaseWindow.Render;
  349. begin
  350. DoRender;
  351. end;
  352. procedure TSDLBaseWindow.RestoreObjects;
  353. begin
  354. FLoaded := false;
  355. end;
  356. procedure TSDLBaseWindow.SetCaption( const aCaptionText : string; const aIconName : string );
  357. begin
  358. if FCaptionText <> aCaptionText then
  359. begin
  360. FCaptionText := PChar( aCaptionText );
  361. FIconName := PChar( aIconName );
  362. SDL_WM_SetCaption( FCaptionText, FIconName );
  363. end;
  364. end;
  365. procedure TSDLBaseWindow.SetIcon(aIcon: PSDL_Surface; aMask: UInt8);
  366. begin
  367. SDL_WM_SetIcon( aIcon, aMask );
  368. end;
  369. function TSDLBaseWindow.Show : Boolean;
  370. var
  371. eBaseWindowEvent : TSDL_Event;
  372. begin
  373. DoShow;
  374. FTimer.Init;
  375. FRendering := true;
  376. // repeat until we are told not to render
  377. while FRendering do
  378. begin
  379. // wait for an event
  380. while SDL_PollEvent( @eBaseWindowEvent ) > 0 do
  381. begin
  382. // check for a quit event
  383. case eBaseWindowEvent.type_ of
  384. SDL_ACTIVEEVENT :
  385. begin
  386. DoActive( eBaseWindowEvent.active.gain, eBaseWindowEvent.active.state );
  387. end;
  388. SDL_QUITEV :
  389. begin
  390. DoQuit;
  391. DoClose;
  392. end;
  393. SDL_USEREVENT :
  394. begin
  395. DoUser( eBaseWindowEvent.user.type_, eBaseWindowEvent.user.code, eBaseWindowEvent.user.data1, eBaseWindowEvent.user.data2 );
  396. end;
  397. SDL_VIDEOEXPOSE :
  398. begin
  399. DoExpose;
  400. end;
  401. SDL_VIDEORESIZE :
  402. begin
  403. DoResize( eBaseWindowEvent.resize.w, eBaseWindowEvent.resize.h, FDisplaySurface.format.BitsPerPixel, FVideoflags );
  404. end;
  405. end;
  406. InputManager.UpdateInputs( eBaseWindowEvent );
  407. end;
  408. // Prepare the Next Frame
  409. Update( FTimer.GetElapsedSeconds );
  410. // Display the Next Frame
  411. Render;
  412. // Flip the surfaces
  413. Flip;
  414. end;
  415. Result := FRendering;
  416. end;
  417. { TSDL2DWindow }
  418. constructor TSDL2DWindow.Create(aWidth, aHeight, aBitDepth: integer; aVideoFlags: Uint32);
  419. begin
  420. // make sure double buffer is always included in the video flags
  421. inherited Create(aWidth,aHeight, aBitDepth, aVideoFlags or SDL_DOUBLEBUF);
  422. end;
  423. procedure TSDL2DWindow.DeleteObjects;
  424. begin
  425. inherited;
  426. end;
  427. function TSDL2DWindow.Flip: integer;
  428. begin
  429. // let's show the back buffer
  430. result := SDL_Flip( FDisplaySurface );
  431. end;
  432. procedure TSDL2DWindow.InitialiseObjects;
  433. begin
  434. inherited;
  435. end;
  436. procedure TSDL2DWindow.Update( aElapsedTime : single );
  437. begin
  438. inherited;
  439. end;
  440. procedure TSDL2DWindow.Render;
  441. begin
  442. inherited;
  443. end;
  444. procedure TSDL2DWindow.RestoreObjects;
  445. begin
  446. inherited;
  447. end;
  448. { TSDL3DWindow }
  449. constructor TSDL3DWindow.Create(aWidth,
  450. aHeight, aBitDepth: integer; aVideoFlags: Uint32);
  451. begin
  452. // make sure opengl is always included in the video flags
  453. inherited Create(aWidth,aHeight, aBitDepth, aVideoFlags or SDL_OPENGL or SDL_DOUBLEBUF);
  454. end;
  455. procedure TSDL3DWindow.DeleteObjects;
  456. begin
  457. inherited;
  458. end;
  459. function TSDL3DWindow.Flip : integer;
  460. begin
  461. SDL_GL_SwapBuffers;
  462. result := 0;
  463. end;
  464. procedure TSDL3DWindow.InitialiseObjects;
  465. begin
  466. inherited;
  467. end;
  468. procedure TSDL3DWindow.Update( aElapsedTime : single );
  469. begin
  470. inherited;
  471. end;
  472. procedure TSDL3DWindow.Render;
  473. begin
  474. inherited;
  475. end;
  476. procedure TSDL3DWindow.RestoreObjects;
  477. begin
  478. inherited;
  479. end;
  480. end.