Commit | Line | Data |
---|---|---|
ef79bbde P |
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 |