PDA

View Full Version : SDL initialization problem



Brainer
17-11-2007, 10:21 AM
Hello. :)

I have a problem initializing SDL. I want to use OpenGL but I get AccessViolation every time I try setting the flag to SDL_OPENGL. Here's the code I use:

unit UBECore;

interface

uses
SDL, dglOpenGL, UBELogger;

type
{ .: TBaseEngine :. }
TBaseEngine = class(TObject)
private
{ Private declarations }
FLastTick: Integer;
FWidth: Integer;
FHeight: Integer;
FQuit: Boolean;
FTitle: String;
FScreen: PSDL_Surface;
FMinimized: Boolean;
FFPSTickCounter: Integer;
FFPSCounter: Integer;
FCurrentFPS: Integer;
FOldExitHandler: Pointer;
procedure SetTitle(const ATitle: String);
protected
{ Protected declarations }
procedure DoThink();
procedure DoRender();

procedure HandleInput();
public
{ Public declarations }
constructor Create();
destructor Destroy(); override;

procedure Init();
procedure Start();

procedure SetSize(const AWidth: Integer; const AHeight: Integer);

procedure AdditionalInit(); virtual;
procedure Think(const AElapsedTime: Integer); virtual;
procedure Render(ADestSurface: PSDL_Surface); virtual;
procedure EndAll(); virtual;
procedure WindowActive(); virtual;
procedure WindowInactive(); virtual;
procedure KeyUp(const KeyEnum: Integer); virtual;
procedure KeyDown(const KeyEnum: Integer); virtual;
procedure MouseMove(const Button: Integer; const X: Integer;
const Y: Integer; const RelX: Integer; const RelY: Integer); virtual;
procedure MouseButtonDown(const Button: Integer; const X: Integer;
const Y: Integer; const RelX: Integer; const RelY: Integer); virtual;
procedure MouseButtonUp(const Button: Integer; const X: Integer;
const Y: Integer; const RelX: Integer; const RelY: Integer); virtual;

property Title: String read FTitle write SetTitle;
property Surface: PSDL_Surface read FScreen;
property FPS: Integer read FCurrentFPS;
end;

implementation

{ TBaseEngine }

procedure TBaseEngine.AdditionalInit;
begin

end;

constructor TBaseEngine.Create;
begin
FLastTick := 0;
FWidth := 800;
FHeight := 600;
FTitle := '';

FScreen := nil;

FFPSTickCounter := 0;
FFPSCounter := 0;
FCurrentFPS := 0;

FMinimized := False;
end;

destructor TBaseEngine.Destroy;
begin
SDL_Quit();
ExitProc := FOldExitHandler;

inherited Destroy();
end;

procedure TBaseEngine.DoRender;
begin
FFPSCounter := FFPSCounter + 1;

if (FFPSTickCounter >= 1000) then
begin
FCurrentFPS := FFPSCounter;
FFPSCounter := 0;
FFPSTickCounter := 0;
end;

SDL_FillRect(FScreen, nil, SDL_MapRGB(FScreen.format, 0, 0, 0));

if SDL_MUSTLOCK(FScreen) then
if (SDL_LockSurface(FScreen) < 0) then
exit;

Render(Surface);

if SDL_MUSTLOCK(FScreen) then
SDL_UnlockSurface(FScreen);

SDL_Flip(FScreen);
end;

procedure TBaseEngine.DoThink;
var
ElapsedTicks: Integer;
begin
ElapsedTicks := SDL_GetTicks() - FLastTick;
FLastTick := SDL_GetTicks();
Think(ElapsedTicks);
FFPSTickCounter := FFPSTickCounter + ElapsedTicks;
end;

procedure TBaseEngine.EndAll;
begin

end;

procedure TBaseEngine.HandleInput;
var
Event: TSDL_Event;
begin
while (SDL_PollEvent(@Event) > 0) do
begin
case Event.type_ of
SDL_KEYDOWN: begin
if (Event.key.keysym.sym = SDLK_ESCAPE) then
begin
FQuit := True;
break;
end;
KeyDown(Event.key.keysym.sym);
end;
SDL_KEYUP: KeyUp(Event.key.keysym.sym);
SDL_QUITEV: FQuit := True;
SDL_MOUSEMOTION: MouseMove(Event.button.button, Event.motion.x,
Event.motion.y, Event.motion.xrel, Event.motion.yrel);
SDL_MOUSEBUTTONUP: MouseButtonUp(Event.button.button, Event.motion.x,
Event.motion.y, Event.motion.xrel, Event.motion.yrel);
SDL_MOUSEBUTTONDOWN: MouseButtonDown(Event.button.button, Event.motion.x,
Event.motion.y, Event.motion.xrel, Event.motion.yrel);
SDL_ACTIVEEVENT: if ((Event.active.state and SDL_APPACTIVE) =
SDL_APPACTIVE) then
if (Event.active.gain = 1) then
begin
FMinimized := False;
WindowActive();
end else
begin
FMinimized := True;
WindowInactive();
end;
end;
end;
end;

procedure TBaseEngine.Init;
var
Flags: Integer;
Info: PSDL_VideoInfo;
begin
ExitProc := @SDL_Quit;
Info := nil;
Flags := 0;

if (SDL_Init(SDL_INIT_VIDEO) < 0) then
begin
Log.LogError('Unable to init SDL: ' + SDL_GetError(), 'Engine Init');
Halt(1);
end;

Info := SDL_GetVideoInfo();
if (Info = nil) then
begin
Log.LogError('Video query failed : ' + SDL_GetError(), 'Engine Init');
Halt(1);
end;

Flags := SDL_OPENGL or SDL_DOUBLEBUF;

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SetSize(800, 600);

FScreen := SDL_SetVideoMode(FWidth, FHeight, Info.vfmt.BitsPerPixel,
Flags);
if (FScreen = nil) then
begin
Log.LogError('Unable to set up video: ' + SDL_GetError(), 'Engine Init');
Halt(1);
end;

AdditionalInit();
end;

procedure TBaseEngine.KeyDown(const KeyEnum: Integer);
begin

end;

procedure TBaseEngine.KeyUp(const KeyEnum: Integer);
begin

end;

procedure TBaseEngine.MouseButtonDown(const Button, X, Y, RelX, RelY: Integer);
begin

end;

procedure TBaseEngine.MouseButtonUp(const Button, X, Y, RelX, RelY: Integer);
begin

end;

procedure TBaseEngine.MouseMove(const Button, X, Y, RelX, RelY: Integer);
begin

end;

procedure TBaseEngine.Render(ADestSurface: PSDL_Surface);
begin

end;

procedure TBaseEngine.SetSize(const AWidth, AHeight: Integer);
begin
FWidth := AWidth;
FHeight := AHeight;
end;

procedure TBaseEngine.SetTitle(const ATitle: String);
begin
FTitle := ATitle;
SDL_WM_SetCaption(PChar(FTitle), nil);
end;

procedure TBaseEngine.Start;
begin
FLastTick := SDL_GetTicks();
FQuit := False;

while (not FQuit) do
begin
HandleInput();

if FMinimized then
begin
// Release some system resources if the app. is minimized.
// WaitMessage();
end else
begin
DoThink();
DoRender();
end;
end;
EndAll();
end;

procedure TBaseEngine.Think(const AElapsedTime: Integer);
begin

end;

procedure TBaseEngine.WindowActive;
begin

end;

procedure TBaseEngine.WindowInactive;
begin

end;

end.


What is wrong? Any ideas?
:?

VilleK
17-11-2007, 03:23 PM
Not sure if it is important but Flags should be of type SDL.UINT32 and not integer.

Here is the code I use:


procedure Platform_InitScreen&#40;Width, Height &#58; integer; UseFullScreen &#58; boolean; Title &#58; PChar&#41;;
var
Flags &#58; SDL.UINT32;
Mode &#58; PSDL_Surface;
begin
if UseFullScreen then
begin
flags &#58;= SDL_OPENGL or SDL_FULLSCREEN;
SDL_ShowCursor&#40;0&#41;;
end
else
flags &#58;= SDL_OPENGL or SDL_RESIZABLE;

SDL_WM_SetCaption&#40;Title, nil&#41;;

SDL_GL_SetAttribute&#40; SDL_GL_RED_SIZE, 8 &#41;;
SDL_GL_SetAttribute&#40; SDL_GL_GREEN_SIZE, 8 &#41;;
SDL_GL_SetAttribute&#40; SDL_GL_BLUE_SIZE, 8 &#41;;
SDL_GL_SetAttribute&#40; SDL_GL_DEPTH_SIZE, 16 &#41;;
SDL_GL_SetAttribute&#40; SDL_GL_DOUBLEBUFFER, 1 &#41;;

Mode &#58;= SDL_SetVideoMode&#40;Width, Height, 0, flags&#41;;
if &#40;Mode = nil&#41; then
Halt&#40;0&#41;;
end;

Brainer
17-11-2007, 03:49 PM
Unfortunately, it doesn't solve the problem. :( Any other ideas?

arthurprs
17-11-2007, 05:10 PM
keep flags as integer

here is the code i use in my engine


// commom flags
flags := SDL_OPENGL or SDL_HWPALETTE or SDL_DOUBLEBUF;

// check if have gpu
if videoinfo.hw_available <> 0 then
flags := flags or SDL_HWSURFACE
else
flags := flags or SDL_SWSURFACE;

// check for hwbliting
if videoinfo.blit_hw <> 0 then
flags := flags or SDL_HWACCEL;

Brainer
17-11-2007, 05:20 PM
Thanks! :) I've solved the problem myself. There were bugs in DoRender method. :)