pcsxr-1.9.92
[pcsx_rearmed.git] / macosx / plugins / DFXVideo / macsrc / PluginGLView.m
1 /***************************************************************************
2     PluginGLView.m
3     PeopsSoftGPU
4   
5     Created by Gil Pedersen on Sun April 18 2004.
6     Copyright (c) 2004 Gil Pedersen.
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version. See also the license.txt file for *
15  *   additional informations.                                              *
16  *                                                                         *
17  ***************************************************************************/
18
19 #import <OpenGL/gl.h>
20 #import <OpenGL/glext.h>
21 #import <OpenGL/glu.h>
22 #import <GLUT/glut.h>
23 #import <Carbon/Carbon.h>
24 #import "PluginGLView.h"
25 #include "externals.h"
26 #undef BOOL
27 #include "gpu.h"
28 #include "swap.h"
29
30 #include <time.h>
31 extern time_t tStart;
32
33 static int mylog2(int val)
34 {
35         int i;
36         for (i=1; i<31; i++)
37                 if (val <= (1 << i))
38                         return (1 << i);
39         
40         return -1;
41 }
42
43 #if 0
44 void BlitScreen16NS(unsigned char * surf,long x,long y)
45 {
46  unsigned long lu;
47  unsigned short row,column;
48  unsigned short dx=PreviousPSXDisplay.Range.x1>>1;
49  unsigned short dy=PreviousPSXDisplay.DisplayMode.y;
50  unsigned short LineOffset,SurfOffset;
51  long lPitch=image_width<<1;
52
53  if(PreviousPSXDisplay.Range.y0)                                                                // centering needed?
54   {
55    surf+=PreviousPSXDisplay.Range.y0*lPitch;
56    dy-=PreviousPSXDisplay.Range.y0;
57   }
58
59   {
60    unsigned long * SRCPtr = (unsigned long *)(psxVuw + (y<<10) + x);
61    unsigned long * DSTPtr = ((unsigned long *)surf)+(PreviousPSXDisplay.Range.x0>>1);
62
63    LineOffset = 512 - dx;
64    SurfOffset = (lPitch>>2) - dx;
65
66    for(column=0;column<dy;column++)
67     {
68      for(row=0;row<dx;row++)
69       {
70        lu=GETLE16D(SRCPtr++);
71
72        *DSTPtr++= lu;//((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
73       }
74      SRCPtr += LineOffset;
75      DSTPtr += SurfOffset;
76     }
77   }
78 }
79 #endif
80
81 @implementation PluginGLView
82
83 //- (id)initWithFrame:(NSRect)frameRect
84 - (id) initWithCoder: (NSCoder *) coder
85 {
86         const GLubyte * strExt;
87         
88         if ((self = [super initWithCoder:coder]) == nil)
89                 return nil;
90
91         glLock = [[NSLock alloc] init];
92         if (nil == glLock) {
93                 [self release];
94                 return nil;
95         }
96
97         // Init pixel format attribs
98         NSOpenGLPixelFormatAttribute attrs[] =
99         {
100                 NSOpenGLPFAAccelerated,
101                 NSOpenGLPFANoRecovery,
102                 NSOpenGLPFADoubleBuffer,
103                 0
104         };
105
106         // Get pixel format from OpenGL
107         NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
108         if (!pixFmt)
109         {
110                 NSLog(@"No Accelerated OpenGL pixel format found\n");
111                 
112                 NSOpenGLPixelFormatAttribute attrs2[] =
113                 {
114                         NSOpenGLPFANoRecovery,
115                         0
116                 };
117
118                 // Get pixel format from OpenGL
119                 pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2];
120                 if (!pixFmt) {
121                         NSLog(@"No OpenGL pixel format found!\n");
122                         
123                         [self release];
124                         return nil;
125                 }
126         }
127         
128         [self setPixelFormat:[pixFmt autorelease]];
129
130         /*
131         long swapInterval = 1 ;
132         [[self openGLContext]
133                         setValues:&swapInterval
134                         forParameter:NSOpenGLCPSwapInterval];
135         */
136         [glLock lock];
137         [[self openGLContext] makeCurrentContext];
138
139         // Init object members
140         strExt = glGetString (GL_EXTENSIONS);
141         texture_range  = gluCheckExtension ((const unsigned char *)"GL_APPLE_texture_range", strExt) ? GL_TRUE : GL_FALSE;
142         texture_hint   = GL_STORAGE_SHARED_APPLE ;
143         client_storage = gluCheckExtension ((const unsigned char *)"GL_APPLE_client_storage", strExt) ? GL_TRUE : GL_FALSE;
144         rect_texture   = gluCheckExtension((const unsigned char *)"GL_EXT_texture_rectangle", strExt) ? GL_TRUE : GL_FALSE;
145
146         // Setup some basic OpenGL stuff
147         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
148         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
149         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
150         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
151         glClear(GL_COLOR_BUFFER_BIT);
152
153         [NSOpenGLContext clearCurrentContext];
154         [glLock unlock];
155
156         image_width = 1024;
157         image_height = 512;
158         image_depth = 16;
159
160         image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
161         image_base = (GLubyte *) calloc(((IMAGE_COUNT * image_width * image_height) / 3) * 4, image_depth >> 3);
162         if (image_base == nil) {
163                 [self release];
164                 return nil;
165         }
166
167         // Create and load textures for the first time
168         [self loadTextures:GL_TRUE];
169         
170         // Init fps timer
171         //gettimeofday(&cycle_time, NULL);
172         
173         drawBG = YES;
174         
175         // Call for a redisplay
176         noDisplay = YES;
177         PSXDisplay.Disabled = 1;
178         [self setNeedsDisplay:true];
179         
180         return self;
181 }
182
183 - (void)dealloc
184 {
185         int i;
186
187         [glLock lock];
188
189         [[self openGLContext] makeCurrentContext];
190         for(i = 0; i < IMAGE_COUNT; i++)
191         {
192                 GLuint dt = i+1;
193                 glDeleteTextures(1, &dt);
194         }
195         if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, IMAGE_COUNT * image_width * image_height * (image_depth >> 3), image_base);
196
197         [NSOpenGLContext clearCurrentContext];
198         [glLock unlock];
199         [glLock release];
200
201         if (image_base)
202                 free(image_base);
203
204         [super dealloc];
205 }
206
207 - (BOOL)isOpaque
208 {
209         return YES;
210 }
211
212 - (BOOL)acceptsFirstResponder
213 {
214         return NO;
215 }
216
217 - (void)drawRect:(NSRect)aRect
218 {
219         // Check if an update has occured to the buffer
220         if ([self lockFocusIfCanDraw]) {
221
222         // Make this context current
223         if (drawBG) {
224                 [[NSColor blackColor] setFill];
225                 [NSBezierPath fillRect:[self visibleRect]];
226         }
227
228         //glFinish() ;
229         // Swap buffer to screen
230         //[[self openGLContext] flushBuffer];
231
232         [self unlockFocus];
233         }
234 }
235
236 #if 0
237 - (void)update  // moved or resized
238 {
239         NSRect rect;
240
241         [super update];
242
243         [[self openGLContext] makeCurrentContext];
244         [[self openGLContext] update];
245
246         rect = [self bounds];
247         
248         glViewport(0, 0, (int) rect.size.width, (int) rect.size.height);
249
250         glMatrixMode(GL_PROJECTION);
251         glLoadIdentity();
252
253         glMatrixMode(GL_MODELVIEW);
254         glLoadIdentity(); 
255
256         //[self setNeedsDisplay:true];
257 }
258 #endif
259
260 - (void)reshape // scrolled, moved or resized
261 {
262         [glLock lock];
263
264         NSOpenGLContext *oglContext = [self openGLContext];
265         NSRect rect;
266
267         [super reshape];
268
269         [oglContext makeCurrentContext];
270         [oglContext update];
271
272         rect = [[oglContext view] bounds];
273
274         glViewport(0, 0, (int) rect.size.width, (int) rect.size.height);
275
276         glMatrixMode(GL_PROJECTION);
277         glLoadIdentity();
278
279         glMatrixMode(GL_MODELVIEW);
280         glLoadIdentity();
281         
282         drawBG = YES;
283
284         [NSOpenGLContext clearCurrentContext];
285         
286 //      [self setNeedsDisplay:true];
287         
288         [self renderScreen];
289         [glLock unlock];
290 }
291
292 - (void)renderScreen
293 {
294         int bufferIndex = whichImage;
295
296         if (1/*[glLock tryLock]*/) {
297                 // Make this context current
298                 [[self openGLContext] makeCurrentContext];
299                 if (PSXDisplay.Disabled) {
300                         glClear(GL_COLOR_BUFFER_BIT);
301                 } else {
302                         // Bind, update and draw new image
303                         if(rect_texture)
304                         {
305                                 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, bufferIndex+1);
306
307                                 glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, image_width, image_height, GL_BGRA, image_type, image[bufferIndex]);
308                                 glBegin(GL_QUADS);
309                                         glTexCoord2f(0.0f, 0.0f);
310                                         glVertex2f(-1.0f, 1.0f);
311                                         
312                                         glTexCoord2f(0.0f, image_height);
313                                         glVertex2f(-1.0f, -1.0f);
314                                         
315                                         glTexCoord2f(image_width, image_height);
316                                         glVertex2f(1.0f, -1.0f);
317                                         
318                                         glTexCoord2f(image_width, 0.0f);
319                                         glVertex2f(1.0f, 1.0f);
320                                 glEnd();
321                         }
322                         else
323                         {
324                                 glBindTexture(GL_TEXTURE_2D, whichImage+1);
325                                 
326                                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width2, image_height2, GL_BGRA, image_type, image[bufferIndex]);
327                                 glBegin(GL_QUADS);
328                                         glTexCoord2f(0.0f, 0.0f);
329                                         glVertex2f(-1.0f, 1.0f);
330                                         
331                                         glTexCoord2f(0.0f, image_ty);
332                                         glVertex2f(-1.0f, -1.0f);
333                                         
334                                         glTexCoord2f(image_tx, image_ty);
335                                         glVertex2f(1.0f, -1.0f);
336                                         
337                                         glTexCoord2f(image_tx, 0.0f);
338                                         glVertex2f(1.0f, 1.0f);
339                                 glEnd();
340                         }
341                 }
342         
343                 // FPS Display
344                 if(ulKeybits&KEY_SHOWFPS)
345                 {
346                         int len, i;
347                         if(szDebugText[0] && ((time(NULL) - tStart) < 2))
348                         {
349                                 strncpy(szDispBuf, szDebugText, 63);
350                         }
351                         else 
352                         {
353                                 szDebugText[0]=0;
354                                 if (szMenuBuf) {
355                                         strncat(szDispBuf, szMenuBuf, 63 - strlen(szDispBuf));
356                                 }
357                         }
358                         
359                         NSRect rect = [[[self openGLContext] view] bounds];
360                         len = (int) strlen(szDispBuf);
361                         
362                         glMatrixMode(GL_PROJECTION);
363                         glPushMatrix();
364                         
365                         gluOrtho2D(0.0, rect.size.width, 0.0, rect.size.height);
366                         glDisable(rect_texture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D);
367
368                         glColor4f(0.0, 0.0, 0.0, 0.5);
369                         glRasterPos2f(3.0, rect.size.height - 14.0);
370                         for (i = 0; i < len; i++) {
371                                 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, szDispBuf[i]);
372                         }
373
374                         glColor3f(1.0, 1.0, 1.0);
375                         glRasterPos2f(2.0, rect.size.height - 13.0);
376                         for (i = 0; i < len; i++) {
377                                 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, szDispBuf[i]);
378                         }
379
380
381                         glEnable(rect_texture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D);
382                         glPopMatrix();
383                 }
384         
385                 [[self openGLContext] flushBuffer];
386                 [NSOpenGLContext clearCurrentContext];
387                 //[glLock unlock];
388         }
389 }
390
391 - (void)loadTextures:(GLboolean)first
392 {
393         GLint i;
394         
395         //[glLock lock];
396         [[self openGLContext] makeCurrentContext];
397         
398         /*
399         printf("Range.x0=%i\n"
400                          "Range.x1=%i\n"
401                          "Range.y0=%i\n"
402                          "Range.y1=%i\n", 
403                          PreviousPSXDisplay.Range.x0,
404                          PreviousPSXDisplay.Range.x1,
405                          PreviousPSXDisplay.Range.y0,
406                          PreviousPSXDisplay.Range.y1);
407
408         printf("DisplayMode.x=%d\n"
409                          "DisplayMode.y=%d\n",
410                          PreviousPSXDisplay.DisplayMode.x,
411                          PreviousPSXDisplay.DisplayMode.y);
412
413         printf("DisplayPosition.x=%i\n"
414                          "DisplayPosition.y=%i\n",
415                          PreviousPSXDisplay.DisplayPosition.x,
416                          PreviousPSXDisplay.DisplayPosition.y);
417
418         printf("DisplayEnd.x=%i\n"
419                          "DisplayEnd.y=%i\n",
420                          PreviousPSXDisplay.DisplayEnd.x,
421                          PreviousPSXDisplay.DisplayEnd.y);
422         
423         printf("Double=%i\n"
424                          "Height=%i\n",
425                          PreviousPSXDisplay.Double,
426                          PreviousPSXDisplay.Height);
427         
428         printf("Disabled=%i\n", PreviousPSXDisplay.Disabled);
429         */
430
431         image_width = PreviousPSXDisplay.Range.x1;
432         image_height = PreviousPSXDisplay.DisplayMode.y;
433         if (PSXDisplay.RGB24) {
434                 image_depth = 32;
435                 image_type = GL_UNSIGNED_INT_8_8_8_8_REV;
436         } else {
437                 image_depth = 16;
438                 image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
439                 //image_width >>= 1;
440         }
441
442         if (image_width * image_height * (image_depth >> 3) > ((1024*512*2)/3)*4)
443                 printf("Fatal error: desired dimension are too large! (%ix%i %ibpp)\n",
444                                  image_width, image_height, image_depth);
445
446         for(i = 0; i < IMAGE_COUNT; i++)
447                 image[i] = image_base + i * image_width * image_height * (image_depth >> 3);
448
449         if(rect_texture)
450         {
451                 image_width2 = image_width;
452                 image_height2 = image_height;
453                 image_tx = (float)image_width;
454                 image_ty = (float)image_height;
455
456                 if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, IMAGE_COUNT * image_width * image_height * (image_depth >> 3), image_base);
457                 else              glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, 0, NULL);
458
459                 for(i = 0; i < IMAGE_COUNT; i++)
460                 {
461                         if(!first)
462                         {
463                                 GLuint dt = i+1;
464                                 glDeleteTextures(1, &dt);
465                         }
466
467                         glDisable(GL_TEXTURE_2D);
468                         glEnable(GL_TEXTURE_RECTANGLE_EXT);
469                         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, i+1);
470
471                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , texture_hint);
472                         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, client_storage);
473                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
474                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
475                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
476                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
477                         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
478
479                         glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, image_width,
480                                 image_height, 0, GL_BGRA, image_type, image[i]);
481                 }
482         }
483         else
484         {
485                 image_width2 = mylog2(image_width);
486                 image_height2 = mylog2(image_height);
487                 image_tx = (float)image_width/(float)image_width2;
488                 image_ty = (float)image_height/(float)image_height2;
489
490                 glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, 0, NULL);
491                 if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_2D, IMAGE_COUNT * image_width2 * image_height2 * (image_depth >> 3), image_base);
492                 else              glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL);
493
494                 for(i = 0; i < IMAGE_COUNT; i++)
495                 {
496                         if(!first)
497                         {
498                                 GLuint dt = i+1;
499                                 glDeleteTextures(1, &dt);
500                         }
501
502                         glDisable(GL_TEXTURE_RECTANGLE_EXT);
503                         glEnable(GL_TEXTURE_2D);
504                         glBindTexture(GL_TEXTURE_2D, i+1);
505
506                         //if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_2D, IMAGE_COUNT * image_width2 * image_height2 * (image_depth >> 3), image_base);
507                         //else              glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL);
508
509                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , texture_hint);
510                         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, client_storage);
511                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
512                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
513                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
514                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
515                         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
516
517                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width2,
518                                 image_height2, 0, GL_BGRA, image_type, image[i]);
519                 }
520         }
521
522         [NSOpenGLContext clearCurrentContext];
523         //[glLock unlock];
524 }
525
526 - (void)swapBuffer
527 {
528         unsigned char * surf;
529         long x = PSXDisplay.DisplayPosition.x;
530         long y = PSXDisplay.DisplayPosition.y;
531         unsigned long lu;
532         unsigned short row,column;
533         unsigned short dx=(unsigned short)PSXDisplay.DisplayEnd.x;//PreviousPSXDisplay.Range.x1;
534         unsigned short dy=(unsigned short)PSXDisplay.DisplayEnd.y;//PreviousPSXDisplay.DisplayMode.y;
535         long lPitch;
536
537         //printf("y=%i",PSXDisplay.DisplayPosition.y);
538
539         if ([glLock tryLock]) {
540                 // make sure the texture area is ready to be written to
541                 glFinishObjectAPPLE(GL_TEXTURE, 2-whichImage);
542
543                 if ((image_width != PreviousPSXDisplay.Range.x1) || 
544                         (image_height != PreviousPSXDisplay.DisplayMode.y) ||
545                         ((PSXDisplay.RGB24 ? 32 : 16) != image_depth)) {
546                         [self loadTextures:NO];
547                 }
548  
549                 surf = image[1-whichImage];
550                 lPitch=image_width2<<(image_depth >> 4);
551
552                 if(PreviousPSXDisplay.Range.y0)                       // centering needed?
553                 {
554                         surf+=PreviousPSXDisplay.Range.y0*lPitch;
555                         dy-=PreviousPSXDisplay.Range.y0;
556                 }
557
558                 if(PSXDisplay.RGB24)
559                 {
560                         unsigned char * pD;unsigned int startxy;
561
562                         surf+=PreviousPSXDisplay.Range.x0<<2;
563
564                         for(column=0;column<dy;column++)
565                         { 
566                                 startxy = (1024 * (column + y)) + x;
567                                 pD = (unsigned char *)&psxVuw[startxy];
568
569                                 row = 0;
570                                 // make sure the reads are aligned
571                                 while ((int)pD & 0x3) {
572                                         *((unsigned long *)((surf)+(column*lPitch)+(row<<2))) =
573                                                 (*(pD+0)<<16)|(*(pD+1)<<8)|*(pD+2);
574
575                                         pD+=3;
576                                         row++;
577                                 }
578
579                                 for(;row<dx;row+=4)
580                                 {
581                                         unsigned long lu1 = *((unsigned long *)pD);
582                                         unsigned long lu2 = *((unsigned long *)pD+1);
583                                         unsigned long lu3 = *((unsigned long *)pD+2);
584                                         unsigned long *dst = ((unsigned long *)((surf)+(column*lPitch)+(row<<2)));
585 #ifdef __POWERPC__
586                                         *(dst)=
587                                                 (((lu1>>24)&0xff)<<16)|(((lu1>>16)&0xff)<<8)|(((lu1>>8)&0xff));
588                                         *(dst+1)=
589                                                 (((lu1>>0)&0xff)<<16)|(((lu2>>24)&0xff)<<8)|(((lu2>>16)&0xff));
590                                         *(dst+2)=
591                                                 (((lu2>>8)&0xff)<<16)|(((lu2>>0)&0xff)<<8)|(((lu3>>24)&0xff));
592                                         *(dst+3)=
593                                                 (((lu3>>16)&0xff)<<16)|(((lu3>>8)&0xff)<<8)|(((lu3>>0)&0xff));
594 #else
595                                         *(dst)=
596                                                 (((lu1>>0)&0xff)<<16)|(((lu1>>8)&0xff)<<8)|(((lu1>>16)&0xff));
597                                         *(dst+1)=
598                                                 (((lu1>>24)&0xff)<<16)|(((lu2>>0)&0xff)<<8)|(((lu2>>8)&0xff));
599                                         *(dst+2)=
600                                                 (((lu2>>16)&0xff)<<16)|(((lu2>>24)&0xff)<<8)|(((lu3>>0)&0xff));
601                                         *(dst+3)=
602                                                 (((lu3>>8)&0xff)<<16)|(((lu3>>16)&0xff)<<8)|(((lu3>>24)&0xff));
603 #endif
604                                         pD+=12;
605                                 }
606
607                                 //for(;row<dx;row+=4)
608                                 /*while (pD&0x3) {
609                                         *((unsigned long *)((surf)+(column*lPitch)+(row<<2)))=
610                                                 (*(pD+0)<<16)|(*(pD+1)<<8)|(*(pD+2)&0xff));
611                                         pD+=3;
612                                         row++;
613                                 }*/
614                         }
615                 }
616                 else
617                 {
618                         int LineOffset,SurfOffset;
619                         unsigned long * SRCPtr = (unsigned long *)(psxVuw + (y << 10) + x);
620                         unsigned long * DSTPtr =
621                                 ((unsigned long *)surf) + (PreviousPSXDisplay.Range.x0 >> 1);
622
623                         dx >>= 1;
624
625                         LineOffset = 512 - dx;
626                         SurfOffset = (lPitch >> 2) - dx;
627
628                         for(column=0;column<dy;column++)
629                         {
630                                 for(row=0;row<dx;row++)
631                                 {
632 #ifdef __POWERPC__
633                                         lu=GETLE16D(SRCPtr++);
634 #else
635                                         lu=*SRCPtr++;
636 #endif
637                                         *DSTPtr++=
638                                                 ((lu << 10) & 0x7c007c00)|
639                                                 ((lu) & 0x3e003e0)|
640                                                 ((lu >> 10) & 0x1f001f);
641                                 }
642                                 SRCPtr += LineOffset;
643                                 DSTPtr += SurfOffset;
644                         }
645                 }
646
647         // Swap image buffer
648                 whichImage = 1 - whichImage;
649
650                 [self renderScreen];
651                 [glLock unlock];
652         }
653 }
654
655 - (void)clearBuffer:(BOOL)display
656 {
657         if (display == NO) {
658                 //[[self openGLContext] makeCurrentContext];
659                 //glClear(GL_COLOR_BUFFER_BIT);
660                 //[self loadTextures:NO];
661         } else {
662                 noDisplay = YES;
663 //              [self setNeedsDisplay:true];
664         }
665 }
666 /*
667 - (void)mouseDown:(NSEvent *)theEvent
668 {
669         PluginWindowController *controller = [[self window] windowController];
670         
671         static unsigned long lastTime = 0;
672         unsigned long time;
673         
674         time = TickCount();
675         
676         if (lastTime != 0) {
677                 if (time - lastTime > GetDblTime()) {
678                         if (isFullscreen) {
679                                 [[self openGLContext] clearDrawable];
680                         } else {
681                                 [[self openGLContext] setFullScreen];
682                         }
683                         isFullscreen = 1-isFullscreen;
684                         lastTime = 0;
685                         return;
686                 }
687         }
688         
689         lastTime = time;
690 }*/
691
692 @end