Move EpocSdlEnv functionality do CSDL.
[SDL.s60v3.git] / src / video / symbian / SDL_epocvideo.cpp
blob2e56e4493d8ac51db16203fd66559d9a5b835993
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 return(0);
230 SDL_Rect **S60_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
232 if(flags & SDL_HWSURFACE)
234 if(format->BytesPerPixel != 4) //in HW only full color is supported
235 return NULL;
237 if(flags & SDL_FULLSCREEN)
239 return Private->iRect;
242 return (SDL_Rect **)(-1); //everythingisok, but too small shoes
245 int S60_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
247 if ((firstcolor+ncolors) > 256)
248 return -1;
249 TUint32 palette[256];
250 const TDisplayMode mode = EpocSdlEnv::DisplayMode();
251 int c = 0;
253 if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096)
255 // Set 12 bit palette
256 for(int i = firstcolor; i < firstcolor+ncolors; i++)
258 // 4k value: 0000 rrrr gggg bbbb
259 TUint32 color4K = (colors[c].r & 0x0000f0) << 4;
260 color4K |= (colors[c].g & 0x0000f0);
261 color4K |= (colors[c].b & 0x0000f0) >> 4;
262 palette[i] = color4K;
263 c++;
266 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536)
268 for(int i = firstcolor; i < firstcolor+ncolors; i++)
270 // 64k-colour displays effectively support RGB values
271 // with 5 bits allocated to red, 6 to green and 5 to blue
272 // 64k value: rrrr rggg gggb bbbb
273 TUint32 color64K = (colors[c].r & 0x0000f8) << 8;
274 color64K |= (colors[c].g & 0x0000fc) << 3;
275 color64K |= (colors[c].b & 0x0000f8) >> 3;
276 palette[i] = color64K;
277 c++;
280 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216)
282 for(int i = firstcolor; i < firstcolor+ncolors; i++)
284 // 16M-colour
285 //0000 0000 rrrr rrrr gggg gggg bbbb bbbb
286 TUint32 color16M = colors[c].r << 16;
287 color16M |= colors[c].g << 8;
288 color16M |= colors[c].b;
289 palette[i] = color16M;
290 c++;
293 else
295 return -2;
297 if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone)
299 // palette has been updated, redraw whole screen to include changes
300 EpocSdlEnv::UpdateWholeScreen(true);
302 return 0;
304 return -1;
307 int S60_GlesLoadLibrary(SDL_VideoDevice* _this, const char* path)
309 if(_this->gl_data->iLibrary.Handle() != 0)
310 return KErrAlreadyExists; //already loaded
311 const char* const gles_lib[] = {"libgles_cm.dll", "libSWGLES.dll"};
312 int err = KErrNotFound;
313 for(int i = 0; i < 2 && err != KErrNone; i++)
315 const char* name8 = path == NULL ? gles_lib[i] : path;
316 TFileName lib;
317 lib.Copy(TPtrC8((unsigned char*)name8));
318 err = _this->gl_data->iLibrary.Load(lib);
320 if(err == KErrNone)
321 _this->gl_config.driver_loaded = 1;
322 return err;
325 typedef int (*Ftp)(...);
326 #define DC(x) ((Ftp) S60_GlesGetProcAddress(_this, #x))
328 const char* const OpenGL[] = //these funtions are in gl, but not in gles, at least in all in all versions...
330 "glBegin",
331 "glEnd",
332 "glOrtho",
333 "glPopAttrib",
334 "glPopClientAttrib",
335 "glPushAttrib",
336 "glPushClientAttrib",
337 "glTexCoord2f",
338 "glVertex2i",
339 "glTexParameteri"
342 int NotSupported()
344 User::Panic(_L("SDL, Gles"), KErrNotSupported);
345 return 0;
348 void* S60_GlesGetProcAddress(_THIS, const char *proc)
350 if(_this->gl_data->iLibrary.Handle() == 0)
351 return NULL; //not loaded
352 TLibraryFunction f = NULL;
353 for(int i = 0; i < G_ordinals_count; i++)
355 if(strcmp(G_ordinals[i].name, proc) == 0)
357 f = _this->gl_data->iLibrary.Lookup(G_ordinals[i].ord);
358 break;
362 if(f != NULL) /*Lookup may fail*/
363 return (void*) f;
365 for(int i = 0; i < sizeof(OpenGL) / sizeof(char*); i++)
367 if(strcmp(OpenGL[i], proc) == 0)
368 return (void*) NotSupported;
371 return NULL;
374 int S60_GlesGetAttribute(_THIS, SDL_GLattr aAttrib, int* aValue)
376 EGLint attrib;
377 switch(aAttrib)
379 /*todo*/
380 case SDL_GL_RED_SIZE: attrib = EGL_RED_SIZE; break;
381 case SDL_GL_GREEN_SIZE: attrib = EGL_GREEN_SIZE; break;
382 case SDL_GL_BLUE_SIZE:attrib = EGL_BLUE_SIZE; break;
383 case SDL_GL_ALPHA_SIZE: attrib = EGL_ALPHA_SIZE; break;
384 case SDL_GL_BUFFER_SIZE: attrib = EGL_BUFFER_SIZE; break;
385 case SDL_GL_DOUBLEBUFFER: *aValue = 1; return 0; //always
386 case SDL_GL_DEPTH_SIZE: attrib = EGL_DEPTH_SIZE; break;
387 case SDL_GL_STENCIL_SIZE: attrib = EGL_STENCIL_SIZE; break;
388 case SDL_GL_ACCUM_RED_SIZE:
389 case SDL_GL_ACCUM_GREEN_SIZE:
390 case SDL_GL_ACCUM_BLUE_SIZE:
391 case SDL_GL_ACCUM_ALPHA_SIZE:
392 case SDL_GL_STEREO:
393 case SDL_GL_MULTISAMPLEBUFFERS:
394 case SDL_GL_MULTISAMPLESAMPLES:
395 case SDL_GL_ACCELERATED_VISUAL:
396 case SDL_GL_SWAP_CONTROL:
397 *aValue = 0;
398 return -1;
400 const int success = DC(eglGetConfigAttrib)
402 _this->gl_data->iDisplay,
403 _this->gl_data->iConfig,
404 attrib,
405 aValue);
406 return success == EGL_FALSE ? -1 : 0;
410 int S60_GlesMakeCurrent(_THIS)
412 DC(eglMakeCurrent)
413 (_this->gl_data->iDisplay,
414 _this->gl_data->iSurface,
415 _this->gl_data->iSurface,
416 _this->gl_data->iContext);
417 return DC(eglGetError)();
420 void S60_GlesSwapBuffers(_THIS)
422 DC(eglSwapBuffers)(
423 _this->gl_data->iDisplay,
424 _this->gl_data->iSurface);
427 TDisplayMode GetDisplayMode(int aBitsPerPixel)
429 const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
430 int dmode = EColorLast;
431 if(TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) == aBitsPerPixel)
433 dmode = displayMode;
435 else
439 --dmode;
441 while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
442 TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != aBitsPerPixel);
444 return TDisplayMode(dmode);
448 static void glAssert(_THIS)
450 const EGLint err = DC(eglGetError)();
451 if(err != EGL_SUCCESS)
453 User::Leave(err);
457 static void CreateGles(_THIS, RWindow& aWindow, int bpp, SDL_PrivateGLData& aData)
459 SDL_GL_LoadLibrary(NULL); //just if its not already loaded
460 aData.iDisplay = DC(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
461 DC(eglInitialize)(aData.iDisplay, NULL, NULL);
463 glAssert(_this);
465 int configs = 0;
466 EGLConfig* configList = NULL;
467 int configSz = 0;
468 DC(eglGetConfigs)(aData.iDisplay, configList, configSz, &configs);
469 configSz = configs;
471 glAssert(_this);
473 configList = new EGLConfig[configSz];
475 int red, green, blue;
476 if(bpp == 16)
478 red = 5;
479 green = 6;
480 blue = 5;
482 else
484 red = 8;
485 green = 8;
486 blue = 8;
489 const EGLint attribList[] =
491 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
492 EGL_RED_SIZE, red,
493 EGL_GREEN_SIZE, green,
494 EGL_BLUE_SIZE, blue,
495 EGL_BUFFER_SIZE, EGL_DONT_CARE,
496 EGL_DEPTH_SIZE, 8,
497 EGL_NONE
500 DC(eglChooseConfig)(aData.iDisplay,
501 attribList,
502 configList,
503 configSz,
504 &configs);
507 glAssert(_this);
509 __ASSERT_ALWAYS(configs > 0, User::Invariant());
511 aData.iConfig = configList[0];
513 delete[] configList;
515 aData.iContext = DC(eglCreateContext)(aData.iDisplay,
516 aData.iConfig,
517 EGL_NO_CONTEXT,
518 NULL);
520 glAssert(_this);
522 aData.iSurface = DC(eglCreateWindowSurface)(aData.iDisplay,
523 aData.iConfig,
524 &aWindow,
525 NULL);
527 glAssert(_this);
531 static void DestroyGles(_THIS)
533 if( _this->gl_config.driver_loaded)
535 DC(eglMakeCurrent)(_this->gl_data->iDisplay,
536 EGL_NO_SURFACE,
537 EGL_NO_SURFACE,
538 EGL_NO_CONTEXT);
539 DC(eglDestroySurface)(_this->gl_data->iDisplay, _this->gl_data->iSurface);
540 DC(eglDestroyContext)(_this->gl_data->iDisplay, _this->gl_data->iContext);
541 DC(eglTerminate)(_this->gl_data->iDisplay);
542 _this->gl_data->iLibrary.Close();
543 _this->gl_config.driver_loaded = 0;
547 SDL_Surface *S60_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
549 if(flags & SDL_OPENGL)
551 current->flags |= SDL_OPENGL;
552 current->w = width;
553 current->h = height;
555 RWindow* win = EpocSdlEnv::Window();
556 EpocSdlEnv::ApplyGlesDsa();
558 CreateGles(_this, *win, bpp, *_this->gl_data);
560 return current;
563 if(flags & SDL_HWSURFACE)
564 return NULL;
566 // check orientation and resolution validity
567 bool resValid = false;
568 Orientation orientation = CAknAppUi::EAppUiOrientationUnspecified;
569 for(int i=0; i<2; i++)
571 if(width <= Private->iRect[i]->w && height <= Private->iRect[i]->h)
573 orientation = Private->iOrientation[i];
574 resValid = true;
575 break;
578 if(!resValid)
579 return NULL;
581 if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0))
582 return NULL;
584 const int numBytesPerPixel = ((bpp-1)>>3) + 1;
585 current->pitch = numBytesPerPixel * width;
587 // set proper surface flags
588 current->flags = SDL_SWSURFACE | SDL_PREALLOC;
589 if(flags & SDL_FULLSCREEN)
590 current->flags |= SDL_FULLSCREEN;
591 if(flags & SDL_RESIZABLE)
592 current->flags |= SDL_RESIZABLE;
593 if(bpp <= 8)
594 current->flags |= SDL_HWPALETTE;
596 current->w = width;
597 current->h = height;
599 // allocate surface
600 const int surfacesize = width * height * numBytesPerPixel;
601 Private->iSwSurfaceSize = TSize(width, height);
603 delete[] (TUint8*)current->pixels;
604 current->pixels = new TUint8[surfacesize];
605 Private->iSwSurface = (TUint8*) current->pixels;
607 if(current->pixels == NULL)
608 return NULL;
610 const TSize sz = GetScreenSize();
612 if(sz.iWidth < sz.iHeight && orientation != CAknAppUi::EAppUiOrientationPortrait ||
613 sz.iWidth > sz.iHeight && orientation != CAknAppUi::EAppUiOrientationLandscape)
615 g_SDL->SetOrientation(orientation, TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
617 else
619 if((flags & SDL_RESIZABLE) == 0)
621 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(orientation));
623 else
625 TRAPD(err, static_cast<CAknAppUi*>(CEikonEnv::Static()->EikAppUi())->SetOrientationL(CAknAppUi::EAppUiOrientationUnspecified));
628 const int err = EpocSdlEnv::AllocSurface(TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
629 if(err != KErrNone)
630 return NULL;
633 // Set the blit function
634 _this->UpdateRects = S60_DirectUpdate;
636 // Centralize game window on device screen
637 Private->iScreenPos.iX = 0;
638 Private->iScreenPos.iY = 0;
640 return current;
643 static int S60_AllocHWSurface(_THIS, SDL_Surface* surface)
645 return KErrNone == EpocSdlEnv::AllocSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel));
648 static void S60_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
652 static int S60_LockHWSurface(_THIS, SDL_Surface* surface)
654 if(EpocSdlEnv::IsDsaAvailable())
656 TUint8* address = EpocSdlEnv::LockHwSurface();
657 if(address != NULL)
659 surface->pixels = address;
660 return 1;
663 return 0;
665 static void S60_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
667 EpocSdlEnv::UnlockHwSurface();
670 static int S60_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
672 return(0);
675 static void S60_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
677 if(EpocSdlEnv::IsDsaAvailable())
679 if(Private->iSwSurface)
681 const TRect target(TPoint(0, 0), Private->iSwSurfaceSize);
683 if(EpocSdlEnv::GetUpdateWholeScreen())
685 if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, target, target))
686 return;
688 else
690 for(int i = 0; i < numrects ;i++)
692 const TRect rect(TPoint(rects[i].x, rects[i].y),
693 TSize(rects[i].w, rects[i].h));
694 if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target))
695 return; //not succesful
696 EpocSdlEnv::UpdateWholeScreen(false);
699 EpocSdlEnv::UpdateSwSurface();
701 SDL_PauseAudio(0);
703 else
705 SDL_PauseAudio(1);
709 /* Note: If we are terminated, this could be called in the middle of
710 another SDL video routine -- notably UpdateRects.
712 void S60_VideoQuit(_THIS)
714 delete[] Private->iOrientation;
716 delete Private->iRect[0];
717 delete Private->iRect[1];
718 delete[] Private->iRect;
720 if(_this->gl_data)
721 DestroyGles(_this);
723 delete[] Private->iSwSurface;
724 Private->iSwSurface = NULL;
725 EpocSdlEnv::FreeSurface();
729 WMcursor *S60_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
731 // prevents SDL from displaying standard cursor
732 return (WMcursor*) 1;
735 void S60_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
739 int S60_ShowWMCursor(_THIS, WMcursor *cursor)
741 return true;
744 /*FOR GL comp*/
746 void glBegin(GLenum a) {}
747 void glEnd(void) {}
748 void glOrtho(GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f) {}
749 void glPopAttrib(void) {}
750 void glPopClientAttrib(void){}
751 void glPushAttrib(GLbitfield mask) {}
752 void glPushClientAttrib(GLbitfield mask) {}
753 void glTexCoord2f(GLfloat s, GLfloat t) {}
754 void glVertex2i(GLint x, GLint y) {}