Decrease energy usage in idle.
[SDL.s60v3.git] / src / video / symbian / SDL_epocvideo.cpp
blob90b70c04acc652fde71865583fa953ca0daa299d
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 Sam Lantinga
20 slouken@devolution.com
23 #include "epoc_sdl.h"
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
28 extern "C" {
29 #include "SDL_error.h"
30 #include "SDL_timer.h"
31 #include "SDL_video.h"
32 #undef NULL
33 #include "SDL_pixels_c.h"
34 #include "SDL.h"
35 #include "SDL_mouse.h"
38 #include "SDL_epocvideo.h"
39 #include "SDL_epocevents_c.h"
40 #include <coedef.h>
41 #include <flogger.h>
42 #include <eikenv.h>
43 #include <eikappui.h>
44 #include <eikapp.h>
45 #include "sdlepocapi.h"
46 #include <SDL_gliop.h>
47 #include <egl.h>
48 #include "gles_armv5_def.h"
50 extern "C"
52 /* Initialization/Query functions */
53 static int S60_VideoInit(_THIS, SDL_PixelFormat *vformat);
54 static SDL_Rect **S60_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
55 static SDL_Surface *S60_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
56 static int S60_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
57 static void S60_VideoQuit(_THIS);
59 /* Hardware surface functions */
60 static int S60_AllocHWSurface(_THIS, SDL_Surface *surface);
61 static int S60_LockHWSurface(_THIS, SDL_Surface *surface);
62 static int S60_FlipHWSurface(_THIS, SDL_Surface *surface);
63 static void S60_UnlockHWSurface(_THIS, SDL_Surface *surface);
64 static void S60_FreeHWSurface(_THIS, SDL_Surface *surface);
65 static void S60_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
67 static int S60_Available(void);
68 static SDL_VideoDevice *S60_CreateDevice(int devindex);
70 /* Mouse functions */
71 static WMcursor *S60_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
72 static void S60_FreeWMCursor(_THIS, WMcursor *cursor);
73 static int S60_ShowWMCursor(_THIS, WMcursor *cursor);
75 /*GL Functions*/
76 static int S60_GlesLoadLibrary(_THIS, const char* path);
77 static void* S60_GlesGetProcAddress(_THIS, const char *proc);
78 static int S60_GlesGetAttribute(_THIS, SDL_GLattr attrib, int* value);
79 static int S60_GlesMakeCurrent(_THIS);
80 static void S60_GlesSwapBuffers(_THIS);
82 struct WMcursor
87 static TSize GetScreenSize()
89 CWsScreenDevice *sd = new CWsScreenDevice(CEikonEnv::Static()->WsSession());
90 sd->Construct();
91 const TSize sz(sd->SizeInPixels());
92 delete sd;
94 return sz;
97 /* Epoc video driver bootstrap functions */
98 static int S60_Available(void)
100 return 1; /* Always available */
103 static void S60_DeleteDevice(SDL_VideoDevice *device)
105 delete device->gl_data;
106 delete device->hidden;
107 delete device;
110 static SDL_VideoDevice *S60_CreateDevice(int /*devindex*/)
112 SDL_VideoDevice *device;
114 /* Allocate all variables that we free on delete */
115 device = new SDL_VideoDevice;
116 if (device)
118 Mem::FillZ(device, (sizeof *device));
119 device->hidden = new SDL_PrivateVideoData;
120 device->gl_data = new SDL_PrivateGLData;
122 else
124 SDL_OutOfMemory();
125 return 0;
127 if((device->hidden == NULL) || (device->gl_data == NULL))
129 SDL_OutOfMemory();
130 delete device->hidden;
131 delete device->gl_data;
132 delete device;
133 return 0;
136 Mem::FillZ(device->hidden, (sizeof *device->hidden));
138 /* Set the function pointers */
139 device->VideoInit = S60_VideoInit;
140 device->ListModes = S60_ListModes;
141 device->SetVideoMode = S60_SetVideoMode;
142 device->SetColors = S60_SetColors;
143 device->UpdateRects = NULL;
144 device->VideoQuit = S60_VideoQuit;
145 device->AllocHWSurface = S60_AllocHWSurface;
146 device->CheckHWBlit = NULL;
147 device->FillHWRect = NULL;
148 device->SetHWColorKey = NULL;
149 device->SetHWAlpha = NULL;
150 device->LockHWSurface = S60_LockHWSurface;
151 device->UnlockHWSurface = S60_UnlockHWSurface;
152 device->FlipHWSurface = S60_FlipHWSurface;
153 device->FreeHWSurface = S60_FreeHWSurface;
154 device->SetIcon = NULL;
155 device->SetCaption = NULL;
156 device->GetWMInfo = NULL;
157 device->FreeWMCursor = S60_FreeWMCursor;
158 device->CreateWMCursor = S60_CreateWMCursor;
159 device->ShowWMCursor = S60_ShowWMCursor;
160 device->WarpWMCursor = NULL;
161 device->InitOSKeymap = EPOC_InitOSKeymap;
162 device->PumpEvents = EPOC_PumpEvents;
163 device->free = S60_DeleteDevice;
165 /*gles funtions*/
166 device->GL_LoadLibrary = S60_GlesLoadLibrary;
167 device->GL_GetProcAddress = S60_GlesGetProcAddress;
168 device->GL_GetAttribute = S60_GlesGetAttribute;
169 device->GL_MakeCurrent = S60_GlesMakeCurrent;
170 device->GL_SwapBuffers = S60_GlesSwapBuffers;
172 device->gl_data->iLibrary.SetHandle(0);
174 return device;
177 VideoBootStrap EPOC_bootstrap = {
178 "epoc\0\0\0", "EPOC system",
179 S60_Available, S60_CreateDevice
182 int S60_VideoInit(_THIS, SDL_PixelFormat *vformat)
184 /* Initialise Epoc frame buffer */
186 const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
188 /* The "best" video format should be returned to caller. */
190 vformat->BitsPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode);
191 vformat->BytesPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) / 8;
193 Private->iRect = new SDL_Rect*[3];
194 Private->iRect[0] = new SDL_Rect;
195 Private->iRect[1] = new SDL_Rect;
196 Private->iRect[2] = NULL;
198 Private->iScreenPos = TPoint(0, 0);
200 Private->iRect[0]->x = Private->iScreenPos.iX;
201 Private->iRect[0]->y = Private->iScreenPos.iY;
203 Private->iRect[1]->x = Private->iScreenPos.iX;
204 Private->iRect[1]->y = Private->iScreenPos.iY;
206 const TSize sz = GetScreenSize();
208 Private->iRect[0]->w = sz.iWidth;
209 Private->iRect[0]->h = sz.iHeight;
211 Private->iRect[1]->w = sz.iHeight;
212 Private->iRect[1]->h = sz.iWidth;
214 Private->iOrientation = new CAknAppUi::TAppUiOrientation[2];
216 if(sz.iWidth < sz.iHeight)
218 Private->iOrientation[0] = CAknAppUi::EAppUiOrientationPortrait;
219 Private->iOrientation[1] = CAknAppUi::EAppUiOrientationLandscape;
221 else
223 Private->iOrientation[0] = CAknAppUi::EAppUiOrientationLandscape;
224 Private->iOrientation[1] = CAknAppUi::EAppUiOrientationPortrait;
227 Private->iUpdateWholeScreen = false;
229 return(0);
232 SDL_Rect **S60_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
234 if(flags & SDL_HWSURFACE)
236 if(format->BytesPerPixel != 4) //in HW only full color is supported
237 return NULL;
239 if(flags & SDL_FULLSCREEN)
241 return Private->iRect;
244 return (SDL_Rect **)(-1); //everythingisok, but too small shoes
247 int S60_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
249 if ((firstcolor+ncolors) > 256)
250 return -1;
251 TUint32 palette[256];
252 const TDisplayMode mode = EpocSdlEnv::DisplayMode();
253 int c = 0;
255 if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096)
257 // Set 12 bit palette
258 for(int i = firstcolor; i < firstcolor+ncolors; i++)
260 // 4k value: 0000 rrrr gggg bbbb
261 TUint32 color4K = (colors[c].r & 0x0000f0) << 4;
262 color4K |= (colors[c].g & 0x0000f0);
263 color4K |= (colors[c].b & 0x0000f0) >> 4;
264 palette[i] = color4K;
265 c++;
268 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536)
270 for(int i = firstcolor; i < firstcolor+ncolors; i++)
272 // 64k-colour displays effectively support RGB values
273 // with 5 bits allocated to red, 6 to green and 5 to blue
274 // 64k value: rrrr rggg gggb bbbb
275 TUint32 color64K = (colors[c].r & 0x0000f8) << 8;
276 color64K |= (colors[c].g & 0x0000fc) << 3;
277 color64K |= (colors[c].b & 0x0000f8) >> 3;
278 palette[i] = color64K;
279 c++;
282 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216)
284 for(int i = firstcolor; i < firstcolor+ncolors; i++)
286 // 16M-colour
287 //0000 0000 rrrr rrrr gggg gggg bbbb bbbb
288 TUint32 color16M = colors[c].r << 16;
289 color16M |= colors[c].g << 8;
290 color16M |= colors[c].b;
291 palette[i] = color16M;
292 c++;
295 else
297 return -2;
299 if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone)
301 // palette has been updated, redraw whole screen to include changes
302 Private->iUpdateWholeScreen = true;
304 return 0;
306 return -1;
309 int S60_GlesLoadLibrary(SDL_VideoDevice* _this, const char* path)
311 if(_this->gl_data->iLibrary.Handle() != 0)
312 return KErrAlreadyExists; //already loaded
313 const char* const gles_lib[] = {"libgles_cm.dll", "libSWGLES.dll"};
314 int err = KErrNotFound;
315 for(int i = 0; i < 2 && err != KErrNone; i++)
317 const char* name8 = path == NULL ? gles_lib[i] : path;
318 TFileName lib;
319 lib.Copy(TPtrC8((unsigned char*)name8));
320 err = _this->gl_data->iLibrary.Load(lib);
322 if(err == KErrNone)
323 _this->gl_config.driver_loaded = 1;
324 return err;
327 typedef int (*Ftp)(...);
328 #define DC(x) ((Ftp) S60_GlesGetProcAddress(_this, #x))
330 const char* const OpenGL[] = //these funtions are in gl, but not in gles, at least in all in all versions...
332 "glBegin",
333 "glEnd",
334 "glOrtho",
335 "glPopAttrib",
336 "glPopClientAttrib",
337 "glPushAttrib",
338 "glPushClientAttrib",
339 "glTexCoord2f",
340 "glVertex2i",
341 "glTexParameteri"
344 int NotSupported()
346 User::Panic(_L("SDL, Gles"), KErrNotSupported);
347 return 0;
350 void* S60_GlesGetProcAddress(_THIS, const char *proc)
352 if(_this->gl_data->iLibrary.Handle() == 0)
353 return NULL; //not loaded
354 TLibraryFunction f = NULL;
355 for(int i = 0; i < G_ordinals_count; i++)
357 if(strcmp(G_ordinals[i].name, proc) == 0)
359 f = _this->gl_data->iLibrary.Lookup(G_ordinals[i].ord);
360 break;
364 if(f != NULL) /*Lookup may fail*/
365 return (void*) f;
367 for(int i = 0; i < sizeof(OpenGL) / sizeof(char*); i++)
369 if(strcmp(OpenGL[i], proc) == 0)
370 return (void*) NotSupported;
373 return NULL;
376 int S60_GlesGetAttribute(_THIS, SDL_GLattr aAttrib, int* aValue)
378 EGLint attrib;
379 switch(aAttrib)
381 /*todo*/
382 case SDL_GL_RED_SIZE: attrib = EGL_RED_SIZE; break;
383 case SDL_GL_GREEN_SIZE: attrib = EGL_GREEN_SIZE; break;
384 case SDL_GL_BLUE_SIZE:attrib = EGL_BLUE_SIZE; break;
385 case SDL_GL_ALPHA_SIZE: attrib = EGL_ALPHA_SIZE; break;
386 case SDL_GL_BUFFER_SIZE: attrib = EGL_BUFFER_SIZE; break;
387 case SDL_GL_DOUBLEBUFFER: *aValue = 1; return 0; //always
388 case SDL_GL_DEPTH_SIZE: attrib = EGL_DEPTH_SIZE; break;
389 case SDL_GL_STENCIL_SIZE: attrib = EGL_STENCIL_SIZE; break;
390 case SDL_GL_ACCUM_RED_SIZE:
391 case SDL_GL_ACCUM_GREEN_SIZE:
392 case SDL_GL_ACCUM_BLUE_SIZE:
393 case SDL_GL_ACCUM_ALPHA_SIZE:
394 case SDL_GL_STEREO:
395 case SDL_GL_MULTISAMPLEBUFFERS:
396 case SDL_GL_MULTISAMPLESAMPLES:
397 case SDL_GL_ACCELERATED_VISUAL:
398 case SDL_GL_SWAP_CONTROL:
399 *aValue = 0;
400 return -1;
402 const int success = DC(eglGetConfigAttrib)
404 _this->gl_data->iDisplay,
405 _this->gl_data->iConfig,
406 attrib,
407 aValue);
408 return success == EGL_FALSE ? -1 : 0;
412 int S60_GlesMakeCurrent(_THIS)
414 DC(eglMakeCurrent)
415 (_this->gl_data->iDisplay,
416 _this->gl_data->iSurface,
417 _this->gl_data->iSurface,
418 _this->gl_data->iContext);
419 return DC(eglGetError)();
422 void S60_GlesSwapBuffers(_THIS)
424 DC(eglSwapBuffers)(
425 _this->gl_data->iDisplay,
426 _this->gl_data->iSurface);
429 TDisplayMode GetDisplayMode(int aBitsPerPixel)
431 const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
432 int dmode = EColorLast;
433 if(TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) == aBitsPerPixel)
435 dmode = displayMode;
437 else
441 --dmode;
443 while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
444 TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != aBitsPerPixel);
446 return TDisplayMode(dmode);
450 static void glAssert(_THIS)
452 const EGLint err = DC(eglGetError)();
453 if(err != EGL_SUCCESS)
455 User::Leave(err);
459 static void CreateGles(_THIS, RWindow& aWindow, int bpp, SDL_PrivateGLData& aData)
461 SDL_GL_LoadLibrary(NULL); //just if its not already loaded
462 aData.iDisplay = DC(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
463 DC(eglInitialize)(aData.iDisplay, NULL, NULL);
465 glAssert(_this);
467 int configs = 0;
468 EGLConfig* configList = NULL;
469 int configSz = 0;
470 DC(eglGetConfigs)(aData.iDisplay, configList, configSz, &configs);
471 configSz = configs;
473 glAssert(_this);
475 configList = new EGLConfig[configSz];
477 int red, green, blue;
478 if(bpp == 16)
480 red = 5;
481 green = 6;
482 blue = 5;
484 else
486 red = 8;
487 green = 8;
488 blue = 8;
491 const EGLint attribList[] =
493 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
494 EGL_RED_SIZE, red,
495 EGL_GREEN_SIZE, green,
496 EGL_BLUE_SIZE, blue,
497 EGL_BUFFER_SIZE, EGL_DONT_CARE,
498 EGL_DEPTH_SIZE, 8,
499 EGL_NONE
502 DC(eglChooseConfig)(aData.iDisplay,
503 attribList,
504 configList,
505 configSz,
506 &configs);
509 glAssert(_this);
511 __ASSERT_ALWAYS(configs > 0, User::Invariant());
513 aData.iConfig = configList[0];
515 delete[] configList;
517 aData.iContext = DC(eglCreateContext)(aData.iDisplay,
518 aData.iConfig,
519 EGL_NO_CONTEXT,
520 NULL);
522 glAssert(_this);
524 aData.iSurface = DC(eglCreateWindowSurface)(aData.iDisplay,
525 aData.iConfig,
526 &aWindow,
527 NULL);
529 glAssert(_this);
533 static void DestroyGles(_THIS)
535 if( _this->gl_config.driver_loaded)
537 DC(eglMakeCurrent)(_this->gl_data->iDisplay,
538 EGL_NO_SURFACE,
539 EGL_NO_SURFACE,
540 EGL_NO_CONTEXT);
541 DC(eglDestroySurface)(_this->gl_data->iDisplay, _this->gl_data->iSurface);
542 DC(eglDestroyContext)(_this->gl_data->iDisplay, _this->gl_data->iContext);
543 DC(eglTerminate)(_this->gl_data->iDisplay);
544 _this->gl_data->iLibrary.Close();
545 _this->gl_config.driver_loaded = 0;
549 SDL_Surface *S60_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
551 if(flags & SDL_OPENGL)
553 current->flags |= SDL_OPENGL;
554 current->w = width;
555 current->h = height;
557 RWindow* win = EpocSdlEnv::Window();
558 EpocSdlEnv::ApplyGlesDsa();
560 CreateGles(_this, *win, bpp, *_this->gl_data);
562 return current;
565 if(flags & SDL_HWSURFACE)
566 return NULL;
568 // check orientation and resolution validity
569 bool resValid = false;
570 Orientation orientation = CAknAppUi::EAppUiOrientationUnspecified;
571 for(int i=0; i<2; i++)
573 if(width <= Private->iRect[i]->w && height <= Private->iRect[i]->h)
575 orientation = Private->iOrientation[i];
576 resValid = true;
577 break;
580 if(!resValid)
581 return NULL;
583 if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0))
584 return NULL;
586 const int numBytesPerPixel = ((bpp-1)>>3) + 1;
587 current->pitch = numBytesPerPixel * width;
589 // set proper surface flags
590 current->flags = SDL_SWSURFACE | SDL_PREALLOC;
591 if(flags & SDL_FULLSCREEN)
592 current->flags |= SDL_FULLSCREEN;
593 if(flags & SDL_RESIZABLE)
594 current->flags |= SDL_RESIZABLE;
595 if(bpp <= 8)
596 current->flags |= SDL_HWPALETTE;
598 current->w = width;
599 current->h = height;
601 // allocate surface
602 const int surfacesize = width * height * numBytesPerPixel;
603 Private->iSwSurfaceSize = TSize(width, height);
605 delete[] (TUint8*)current->pixels;
606 current->pixels = new TUint8[surfacesize];
607 Private->iSwSurface = (TUint8*) current->pixels;
609 if(current->pixels == NULL)
610 return NULL;
612 const TSize sz = GetScreenSize();
614 if(sz.iWidth < sz.iHeight && orientation != CAknAppUi::EAppUiOrientationPortrait ||
615 sz.iWidth > sz.iHeight && orientation != CAknAppUi::EAppUiOrientationLandscape)
617 g_SDL->SetOrientation(orientation, TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
619 else
621 if((flags & SDL_RESIZABLE) == 0)
623 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation));
625 else
627 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(CAknAppUi::EAppUiOrientationUnspecified));
630 const int err = EpocSdlEnv::AllocSurface(TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
631 if(err != KErrNone)
632 return NULL;
635 // Set the blit function
636 _this->UpdateRects = S60_DirectUpdate;
638 // Centralize game window on device screen
639 Private->iScreenPos.iX = 0;
640 Private->iScreenPos.iY = 0;
642 return current;
645 static int S60_AllocHWSurface(_THIS, SDL_Surface* surface)
647 return KErrNone == EpocSdlEnv::AllocSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel));
650 static void S60_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
654 static int S60_LockHWSurface(_THIS, SDL_Surface* surface)
656 if(EpocSdlEnv::IsDsaAvailable())
658 TUint8* address = EpocSdlEnv::LockHwSurface();
659 if(address != NULL)
661 surface->pixels = address;
662 return 1;
665 return 0;
667 static void S60_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
669 EpocSdlEnv::UnlockHwSurface();
672 static int S60_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
674 return(0);
677 static void S60_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
679 if(EpocSdlEnv::IsDsaAvailable())
681 if(Private->iSwSurface)
683 const TRect target(TPoint(0, 0), Private->iSwSurfaceSize);
685 if(Private->iUpdateWholeScreen)
687 if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, target, target))
688 return;
690 else
692 for(int i = 0; i < numrects ;i++)
694 const TRect rect(TPoint(rects[i].x, rects[i].y),
695 TSize(rects[i].w, rects[i].h));
696 if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target))
697 return; //not succesful
698 Private->iUpdateWholeScreen = false;
701 EpocSdlEnv::UpdateSwSurface();
703 if(!Private->iIsWindowFocused)
705 User::After(100000);
710 /* Note: If we are terminated, this could be called in the middle of
711 another SDL video routine -- notably UpdateRects.
713 void S60_VideoQuit(_THIS)
715 delete[] Private->iOrientation;
717 delete Private->iRect[0];
718 delete Private->iRect[1];
719 delete[] Private->iRect;
721 if(_this->gl_data)
722 DestroyGles(_this);
724 delete[] Private->iSwSurface;
725 Private->iSwSurface = NULL;
726 EpocSdlEnv::FreeSurface();
730 WMcursor *S60_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
732 // prevents SDL from displaying standard cursor
733 return (WMcursor*) 1;
736 void S60_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
740 int S60_ShowWMCursor(_THIS, WMcursor *cursor)
742 return true;
745 /*FOR GL comp*/
747 void glBegin(GLenum a) {}
748 void glEnd(void) {}
749 void glOrtho(GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f) {}
750 void glPopAttrib(void) {}
751 void glPopClientAttrib(void){}
752 void glPushAttrib(GLbitfield mask) {}
753 void glPushClientAttrib(GLbitfield mask) {}
754 void glTexCoord2f(GLfloat s, GLfloat t) {}
755 void glVertex2i(GLint x, GLint y) {}