Mac OS X woes

Hello all,

I just started with SDL, and I’ve been going through Marius Andra’s
excellent tutorials.

I have a problem, however; actually, a few, and I’d be very
appreciative of solutions. My system config:

  • Mac OS 10.15
  • 384 meg of ram
  • iBook 500
  • using command-line GNU tools and static library; building .APP bundle
    by hand as per the README

My problem: full screen mode simply does not work. It’s strange – I
get good results with blitting and pixels in windowed modes, but once I
try full screen mode I get a black screen, lockups, and even crashes.

Here’s the code (nothing much):

//--------------------
/* test1.cpp

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>

#include “gamedefs.h”
#include “game.h”

SDL_Surface *screen = NULL;

int main(int argc, char *argv[])
{
SDL_Surface *sprite;
SDL_Event event;
Uint8 *keys;
int i,j;
bool fullscreen = false;
bool done = false;

if (!g_init())
	return (1);

screen = SDL_SetVideoMode(1024,768,16, SDL_HWSURFACE | 
	SDL_DOUBLEBUF | SDL_FULLSCREEN);

sprite = SDL_LoadBMP("sprite16.bmp");
if (!sprite)
	crash("main: couldn't load sprite1.bmp.");

log("main: screen pixel depth is %i.", screen->format->BytesPerPixel);

/*
SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
sprite->format->palette->colors, 0,
sprite->format->palette->ncolors);
*/
i = screen->w/2 - sprite->w/2;
j = screen->h/2 - sprite->h/2;

// main game loop

while (!done)
{
	// capture events
	while (SDL_PollEvent(&event))
	{
		if (event.type == SDL_QUIT)
			return (1);
		else if (event.type == SDL_KEYDOWN)
		{
			// these check for independent presses
			if (event.key.keysym.sym == SDLK_ESCAPE)
				done = true;
			else if (event.key.keysym.sym == SDLK_f)
			{
			  fullscreen = !fullscreen;
			  //setmode(fullscreen);
			}
		}
	}

	// input update
	keys = SDL_GetKeyState(NULL);
	if (keys[SDLK_UP]) 		j-=4;
	if (keys[SDLK_DOWN])	j+=4;
	if (keys[SDLK_LEFT])	i-=4;
	if (keys[SDLK_RIGHT])	i+=4;
			
	// double check bounds... really half-assed
	if (i < 0) i = 0;
	if (j < 0) j = 0;
			
	// draw
	g_lock(screen);
	SDL_FillRect(screen, NULL, 0);
	g_drawimg(sprite, screen, i, j);
	g_unlock(screen);
	g_flip(screen);
}	

// screenshot!
//	SDL_SaveBMP(screen, "00screen.bmp");

// to keep the compiler happy
return (0);

}

//----------------------------------------------------------------------
/*
bool g_init()

Initializes low-level drivers (SDL).

Return true on success, or false on error.  If false, also dumps
debug information through printf to the console.

*/

bool g_init()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf(“Unable to initialize video subsystem (%s).\n\n”,
SDL_GetError());
return (false);
}
else
{
srand(time(NULL));
atexit(g_shutdown);
return (true);
}
}

//----------------------------------------------------------------------
/*
g_shutdown()

Does cleanup after program execution finishes.

*/

void g_shutdown()
{
// free memory here
SDL_Quit();
}

void g_drawimg(SDL_Surface *source, SDL_Surface *dest, int x, int y)
{
SDL_Rect destrect;
destrect.x = x;
destrect.y = y;
SDL_BlitSurface(source, NULL, dest, &destrect);
}

void g_lock(SDL_Surface *surface)
{
// should error checking be added?

if (SDL_MUSTLOCK(surface))
	SDL_LockSurface(surface);

}

void g_unlock(SDL_Surface *surface)
{
// should error checking be added?

if (SDL_MUSTLOCK(surface))
	SDL_UnlockSurface(surface);

}

I want to use full screen mode for the speed. I’ve noticed that under
Mac OS X there’s a huge speed drop among other programs that move from
full screen to windowed.

Have I missed something? Is there some trick that I should know about?

On a side note, the docs aren’t very helpful with the Mac OS X port,
and the stationary doesn’t work. Something that would be really nice
to add to the docs would be that the libSDLMain.o is created, which I
didn’t see anywhere (or maybe I just missed it?). As far as the
stationary goes, it seems to have been written for another version of
the Project Builder (or perhaps, not even for the Mac at all,
considering the port was done blindly?). I’d submit a changed version,
but I can’t figure out the stationary stuff (nothing in the PB docs),
and I’m a console builder anyways…

Another side note: the terminal traps all keyboard input if you run the
generated executable from it. Double-clicking an APP bundle works
fine, but then you don’t trap the printf()s. I don’t think this is
SDL’s problem, but all the same has anyone figured out how to get it to
not do that, and to launch the SDL window above the terminal one
instead of under it?

Thanks in advance,

Just for giggles, try setting video mode windowed first, then
immediately set video mode fullscreen afterwards, and see if that fixes
it.> -----Original Message-----

From: sdl-admin at libsdl.org [mailto:sdl-admin at libsdl.org] On
Behalf Of Charles Wardlaw
Sent: Friday, August 23, 2002 11:46 AM
To: sdl at libsdl.org
Subject: [SDL] Mac OS X woes

Hello all,

I just started with SDL, and I’ve been going through Marius
Andra’s excellent tutorials.

I have a problem, however; actually, a few, and I’d be very
appreciative of solutions. My system config:

  • Mac OS 10.15
  • 384 meg of ram
  • iBook 500
  • using command-line GNU tools and static library; building
    .APP bundle by hand as per the README

My problem: full screen mode simply does not work. It’s
strange – I get good results with blitting and pixels in
windowed modes, but once I try full screen mode I get a black
screen, lockups, and even crashes.

Here’s the code (nothing much):

//--------------------
/* test1.cpp

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>

#include “gamedefs.h”
#include “game.h”

SDL_Surface *screen = NULL;

int main(int argc, char *argv[])
{
SDL_Surface *sprite;
SDL_Event event;
Uint8 *keys;
int i,j;
bool fullscreen = false;
bool done = false;

  if (!g_init())
  	return (1);

screen = SDL_SetVideoMode(1024,768,16, SDL_HWSURFACE |
SDL_DOUBLEBUF | SDL_FULLSCREEN);

sprite = SDL_LoadBMP(“sprite16.bmp”);
if (!sprite)
crash(“main: couldn’t load sprite1.bmp.”);

log(“main: screen pixel depth is %i.”,
screen->format->BytesPerPixel);

/*
SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
sprite->format->palette->colors, 0,
sprite->format->palette->ncolors);
*/
i = screen->w/2 - sprite->w/2;
j = screen->h/2 - sprite->h/2;

// main game loop

while (!done)
{
// capture events
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
return (1);
else if (event.type == SDL_KEYDOWN)
{
// these check for independent presses
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
else if (event.key.keysym.sym == SDLK_f)
{
fullscreen = !fullscreen;
//setmode(fullscreen);
}
}
}

  // input update
  keys = SDL_GetKeyState(NULL);
  if (keys[SDLK_UP]) 		j-=4;
  if (keys[SDLK_DOWN])	j+=4;
  if (keys[SDLK_LEFT])	i-=4;
  if (keys[SDLK_RIGHT])	i+=4;
  		
  // double check bounds... really half-assed
  if (i < 0) i = 0;
  if (j < 0) j = 0;
  		
  // draw
  g_lock(screen);
  SDL_FillRect(screen, NULL, 0);
  g_drawimg(sprite, screen, i, j);
  g_unlock(screen);
  g_flip(screen);

}

// screenshot!
// SDL_SaveBMP(screen, “00screen.bmp”);

// to keep the compiler happy
return (0);
}

//------------------------------------------------------------

/*
bool g_init()

Initializes low-level drivers (SDL).

Return true on success, or false on error. If false, also dumps
debug information through printf to the console.
*/

bool g_init()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf(“Unable to initialize video subsystem (%s).\n\n”,
SDL_GetError());
return (false);
}
else
{
srand(time(NULL));
atexit(g_shutdown);
return (true);
}
}

//------------------------------------------------------------

/*
g_shutdown()

Does cleanup after program execution finishes.
*/

void g_shutdown()
{
// free memory here
SDL_Quit();
}

void g_drawimg(SDL_Surface *source, SDL_Surface *dest, int x, int y) {
SDL_Rect destrect;
destrect.x = x;
destrect.y = y;
SDL_BlitSurface(source, NULL, dest, &destrect);
}

void g_lock(SDL_Surface *surface)
{
// should error checking be added?

if (SDL_MUSTLOCK(surface))
SDL_LockSurface(surface);
}

void g_unlock(SDL_Surface *surface)
{
// should error checking be added?

if (SDL_MUSTLOCK(surface))
SDL_UnlockSurface(surface);
}

I want to use full screen mode for the speed. I’ve noticed
that under Mac OS X there’s a huge speed drop among other
programs that move from full screen to windowed.

Have I missed something? Is there some trick that I should
know about?

On a side note, the docs aren’t very helpful with the Mac OS
X port, and the stationary doesn’t work. Something that
would be really nice to add to the docs would be that the
libSDLMain.o is created, which I didn’t see anywhere (or
maybe I just missed it?). As far as the stationary goes, it
seems to have been written for another version of the Project
Builder (or perhaps, not even for the Mac at all, considering
the port was done blindly?). I’d submit a changed version,
but I can’t figure out the stationary stuff (nothing in the
PB docs), and I’m a console builder anyways…

Another side note: the terminal traps all keyboard input if
you run the generated executable from it. Double-clicking an
APP bundle works fine, but then you don’t trap the printf()s.
I don’t think this is SDL’s problem, but all the same has
anyone figured out how to get it to not do that, and to
launch the SDL window above the terminal one instead of under it?

Thanks in advance,


Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes http://finance.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Just for giggles, try setting video mode windowed first, then
immediately set video mode fullscreen afterwards, and see if that fixes
it.

Anyone have any luck tracking this down? I’d like to get the patch in CVS
before 1.2.5 comes out, if at all possible (and me stuck here without a
Mac…)

–ryan.

Hello all,

I just started with SDL, and I’ve been going through Marius Andra’s
excellent tutorials.

My problem: full screen mode simply does not work. It’s strange – I
get good results with blitting and pixels in windowed modes, but once I
try full screen mode I get a black screen, lockups, and even crashes.

Here’s the code (nothing much):

  // draw
  g_lock(screen);
  SDL_FillRect(screen, NULL, 0);
  g_drawimg(sprite, screen, i, j);
  g_unlock(screen);
  g_flip(screen);

What you have here is a lock-up. You should only call SDL_LockSurface()
if you are touching the surface’s pixels directly, and unlock before
calling any SDL_BlitSurface() or SDL_Fill(), (there may be others as
well, but you get the idea). Read the documentation for
SDL_LockSurface(). Since only hardware surfaces require locking, this is
why you had this problem in fullscreen mode and not windowed mode.

I want to use full screen mode for the speed. I’ve noticed that under
Mac OS X there’s a huge speed drop among other programs that move from
full screen to windowed.

That’s generally true, though some apps have been shown to run faster in
a window (KoboDeluxe). I suspect that apps that update the entire window
every frame will run faster in a window, since we don’t have accelerated
software->hardware blits implemented.

All windows in Mac OS X are double-buffered, so if you’re not careful
you’ll end up copying/blitting twice as much as you think. Use the
QuartzDebug() application to see what areas of the screen you are
updating.

There are two basic workarounds. One is to use SDL_UpdateRects() - in
the case that you only change relatively small portions of the screen
per frame. If that’s not the case you can use OpenGL which has hardware
double-buffering.

Have I missed something? Is there some trick that I should know about?

Yes, and I’ve just let you in on the big secret :wink: I’m adding this to
the FAQ.

On a side note, the docs aren’t very helpful with the Mac OS X port,
and the stationary doesn’t work.

See comment on this below

Something that would be really nice
to add to the docs would be that the libSDLMain.o is created, which I
didn’t see anywhere (or maybe I just missed it?).

I thought it was created for the configure/make build system. Max Horn
has the details on this.

As far as the
stationary goes, it seems to have been written for another version of
the Project Builder (or perhaps, not even for the Mac at all,
considering the port was done blindly?). I’d submit a changed version,
but I can’t figure out the stationary stuff (nothing in the PB docs),
and I’m a console builder anyways…

I maintain the stationary, so if you can provide a hint as to what
exactly doesn’t work I can fix it. It seems to work fine on my end. Then
again, I am using the April Beta dev tools release which you probably
don’t have. I am pretty sure that it works in the previous release
though.

Another side note: the terminal traps all keyboard input if you run the
generated executable from it. Double-clicking an APP bundle works
fine, but then you don’t trap the printf()s. I don’t think this is
SDL’s problem, but all the same has anyone figured out how to get it to
not do that, and to launch the SDL window above the terminal one
instead of under it?

We do tell the window to grab the keyboard input and come to the
foreground, but because you run it from the command line, Mac OS X
doesn’t recognize it as a proper citizen of the GUI world, hence this
doesn’t work (Mac OS X apps aren’t (normally) connected to a terminal
device the way they usually are on other UNIX flavors). I’ve heard of a
hack that fixes this - it was even mentioned on this list, grep for Mac
OS X and erlang - but I’ve forgotten the specifics. I’ll see if I can
dredge this up.

In the meantime, you can use the “open” command from the console to
launch the .app , and use the “Console” application to view your
stdout/stderr.On Friday, August 23, 2002, at 02:46 PM, Charles Wardlaw wrote:

What you have here is a lock-up. You should only call
SDL_LockSurface()
if you are touching the surface’s pixels directly, and unlock before
calling any SDL_BlitSurface() or SDL_Fill(), (there may be others as
well, but you get the idea). Read the documentation for
SDL_LockSurface(). Since only hardware surfaces require locking, this
is
why you had this problem in fullscreen mode and not windowed mode.

Ahh… So, any standard SDL function aside from my own personal
putpixel routines should work without locking? I assume, then, that
this is like the retain/release methodology of Objective C?

I come from doing graphics in DOS, where locking was never an issue,
the gameboy, and just drawing using the GUI system calls, so the
lock/unlock phase has never made any sense to me. Are there any
tutorials on the web explaining this fully?

That’s generally true, though some apps have been shown to run faster
in a window (KoboDeluxe). I suspect that apps that update the entire
window every frame will run faster in a window, since we don’t have
accelerated software->hardware blits implemented.

Yes, but on my iBook I have 8 meg of video ram, which should be plenty
for holding more hardware images (I just haven’t gotten that far yet
because of my fullscreen woes :). I’m sure the ATI chip has
video-to-video acceleration, no?

If that’s not the case you can use OpenGL which has
hardware double-buffering.

Yeah, I’ve noticed that a lot of really hardcore 2D stuff is being done
through OpenGL these days. Free alphablending. :slight_smile: I’m not really
savvy enough to try that yet, though. If performance issues on my
iBook persist, however, that’s where I’ll have to take my engine.

I maintain the stationary, so if you can provide a hint as to what
exactly doesn’t work I can fix it. It seems to work fine on my end.
Then again, I am using the April Beta dev tools release which you
probably don’t have. I am pretty sure that it works in the previous
release though.

I didn’t insteall the April beta because it was a beta; I figured I
could wait for Jaguar. Since it’s out today, I’m going to grab a copy
if possible and rebuild SDL when I get home on Sunday.

As for my problems in PB: the stationary simply wasn’t recognized. I
tried moving stuff around, editing files, looking at similar stationary
for other projects, but I got nothing. It’s probably something that’s
inherent and obvious to anyone who’s used to IDE’s, but I’ve been using
EMACS for so long that I have no clue. :slight_smile: Maybe a more idiot-proof
(read: for folks like me :), slower description would help?

In the meantime, you can use the “open” command from the console to
launch the .app , and use the “Console” application to view your
stdout/stderr.

Yeah, that’s what I’ve been doing so far.

Thanks for all your help! I’m on vacation now, but I’ll try everything
on monday. I’ll also run the SDL system tests under Jaguar and post
the results, if anyone’s interested. Is there an SDL profiling app?

  • Charles__________________________________________________
    Do You Yahoo!?
    Yahoo! Finance - Get real-time stock quotes
    http://finance.yahoo.com

It’s not SDL-specific, but it’s quite useful:

http://www.2dgame-tutorial.com/sdl/profile.htmOn Saturday, August 24, 2002, at 11:12 , Charles Wardlaw wrote:

Is there an SDL profiling app?

What you have here is a lock-up. You should only call
SDL_LockSurface()
if you are touching the surface’s pixels directly, and unlock before
calling any SDL_BlitSurface() or SDL_Fill(), (there may be others as
well, but you get the idea). Read the documentation for
SDL_LockSurface(). Since only hardware surfaces require locking, this
is
why you had this problem in fullscreen mode and not windowed mode.

Ahh… So, any standard SDL function aside from my own personal
putpixel routines should work without locking?

Yes.

I assume, then, that
this is like the retain/release methodology of Objective C?

Not really. It is more like a mutex lock or semaphore. The key
difference from retain/release is that when a surface is locked, any
additional lock ontop of that will block the application until the
surface is unlocked. ObjC will allow you to retain an object multiple
times without blocking.

I come from doing graphics in DOS, where locking was never an issue,
the gameboy, and just drawing using the GUI system calls, so the
lock/unlock phase has never made any sense to me. Are there any
tutorials on the web explaining this fully?

I think the major reason you need lock/unlock is because hardware
surfaces can move around in vram (and out of vram entirely!) and if they
did move you’ll have to obtain the new pointer to the pixels. Also, some
hardware surfaces are like a shared resource (like the display’s pixels)
so you want to avoid race conditions when you access that data.

That’s generally true, though some apps have been shown to run faster
in a window (KoboDeluxe). I suspect that apps that update the entire
window every frame will run faster in a window, since we don’t have
accelerated software->hardware blits implemented.

Yes, but on my iBook I have 8 meg of video ram, which should be plenty
for holding more hardware images (I just haven’t gotten that far yet
because of my fullscreen woes :). I’m sure the ATI chip has
video-to-video acceleration, no?

Mac OS X doesn’t support offscreen hardware surfaces, except in OpenGL.
So most of that 8MB is gone to waste.

I maintain the stationary, so if you can provide a hint as to what
exactly doesn’t work I can fix it. It seems to work fine on my end.
Then again, I am using the April Beta dev tools release which you
probably don’t have. I am pretty sure that it works in the previous
release though.

As for my problems in PB: the stationary simply wasn’t recognized. I
tried moving stuff around, editing files, looking at similar stationary
for other projects, but I got nothing. It’s probably something that’s
inherent and obvious to anyone who’s used to IDE’s, but I’ve been using
EMACS for so long that I have no clue. :slight_smile: Maybe a more idiot-proof
(read: for folks like me :), slower description would help?

I can provide a shell script with the projects in CVS that installs the
stationary. Is that the sort of thing you are looking for? The
stationary is (usually) correctly installed if you use the SDL developer
installer package. I say “usually” because there are still some
unidentified cases where it fails. I found a great doc on Installer.app
that I’ll be using to fix these problems.

Is there an SDL profiling app?

There is no specific app for this purpose. The “QuartzDebug” app can
show what areas of the window are updated. The “Sampler” application
provides a coarse-grained view of time spent in each function, without
recompiling. A standard “gprof” run provides more accurate results.

-DOn Saturday, August 24, 2002, at 09:12 AM, Charles Wardlaw wrote:

At 12:45 AM 8/25/02 +1000, you wrote:>On Saturday, August 24, 2002, at 11:12 , Charles Wardlaw wrote:

Is there an SDL profiling app?

It’s not SDL-specific, but it’s quite useful:

http://www.2dgame-tutorial.com/sdl/profile.htm

Would this one happen to work with multithreaded and/or recursive code?

At 12:31 PM 8/24/02 -0400, you wrote:

Would this one happen to work with multithreaded and/or recursive code?

Nevermind. Taking another look at the examples, it looks like it won’t
work with nested PROFILE_STARTs of equal tags.

I’d go use gprof (for Win32/minGW or Win32/cygwin), but for some reason it
doesn’t like the SDL code I was using (giving me inaccurate calling data
and no timing info). Also, if that problem is fixable, would it do
multithreaded code under Win32?

At 12:31 PM 8/24/02 -0400, you wrote:

I’d go use gprof (for Win32/minGW or Win32/cygwin), but for some reason
it doesn’t like the SDL code I was using (giving me inaccurate calling
data and no timing info).

You’ll have to recompile SDL with profiling turned on. Add “-pg” to the
CFLAGS variable, make distclean, and reconfigure/compile.

-DOn Saturday, August 24, 2002, at 12:55 PM, Christopher Subich wrote:

It’s not SDL-specific, but it’s quite useful:

http://www.2dgame-tutorial.com/sdl/profile.htm

Ooh, perhaps I misspoke: What I meant to say was, is there a buildable
SDL program that does stress testing of various system elements, a la a
high-poly Quake III map? Something that people use as a base to test
machine speed on various tasks and video modes. Allegro’s got a test
program sort of like that. Or a game that’s a perennial favorite?

  • Charles__________________________________________________
    Do You Yahoo!?
    Yahoo! Finance - Get real-time stock quotes
    http://finance.yahoo.com

— Darrell Walisser wrote:

Mac OS X doesn’t support offscreen hardware surfaces, except in
OpenGL. So most of that 8MB is gone to waste.

That’s interesting. Does this mean, then, that under Mac OS X/SDL it’s
better to have all software surfaces at the moment, given that the
software->hardware acceleration isn’t in yet? What’s the general
consensus among developers who’ve released completed projects?

  • Charles__________________________________________________
    Do You Yahoo!?
    Yahoo! Finance - Get real-time stock quotes
    http://finance.yahoo.com

— Darrell Walisser wrote:

Mac OS X doesn’t support offscreen hardware surfaces, except in
OpenGL. So most of that 8MB is gone to waste.

That’s interesting. Does this mean, then, that under Mac OS X/SDL it’s
better to have all software surfaces at the moment, given that the
software->hardware acceleration isn’t in yet? What’s the general
consensus among developers who’ve released completed projects?

I’ve used many of the SDL test programs to check out various combinations
of hardware and software features. I don’t have a canonical benchmark
program though… so much depends on the way you use the API and the
underlying drivers. All the games that I used to push the hardware
with don’t even make modern computers break a sweat. :slight_smile:

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

— Darrell Walisser wrote:

What you have here is a lock-up. You should only call
SDL_LockSurface()
if you are touching the surface’s pixels directly, and unlock before
calling any SDL_BlitSurface() or SDL_Fill(), (there may be others as
well, but you get the idea). Read the documentation for
SDL_LockSurface(). Since only hardware surfaces require locking, this
is
why you had this problem in fullscreen mode and not windowed mode.

All windows in Mac OS X are double-buffered, so if you’re not careful
you’ll end up copying/blitting twice as much as you think. Use the
QuartzDebug() application to see what areas of the screen you are
updating.

First, thanks for your advice – now full screen is sort-of working.

Interestingly, on my iBook double-buffering never gets set. I pass the
hardware flag with the buffering flag, but the screen surface never
reads as being buffered. In full-screen hardware mode gets set
(bufferless), and in windowed mode I seem stuck with unbuffered
software. Windowed mode stays smooth (albeit slow) because of OS X’s
double buffering. Is the lack of a hardware double buffer a part of OS
X not directly supporting other hardware surfaces? I have an 8 meg
card, so even at 640x480x32 there’s plenty of ram at least for the back
buffer.

Another newbie question:

I’ve noticed a lot of discussion in the mail archives on retrace
syncing under Xf86 and Direct X, but mostly the conversation seems to
go unresolved. I can understand that, under a windowed mode, a retrace
sync could be impossible, but what of under full screen mode in OS X?
Has anyone had any success doing software double-buffering in
fullscreen under OS X without shearing? I’m working towards a
tile-based scroller, and the screen’s going go have to be completely
redrawn every frame. How did the SDL_VSync() function discussion end?

Thanks again,

  • Charles__________________________________________________
    Do You Yahoo!?
    Yahoo! Finance - Get real-time stock quotes
    http://finance.yahoo.com