Logo Search packages:      
Sourcecode: sarien version File versions  Download package

SarienView.m

/*  Sarien - A Sierra AGI resource interpreter engine
 *  Copyright (C) 1999-2002 Stuart George and Claudio Matsuoka
 *
 *  $Id: SarienView.m,v 1.6 2002/11/09 11:32:10 cmatsuoka Exp $
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; see docs/COPYING for further details.
 *
 *  MacOS X port by Richard Houle <richard.houle@sandtechnology.com>
 */

#import "SarienView.h"
#include "sarien.h"
#include "graphics.h"
#include "keyboard.h"
#include "cocoa.h"

#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
#error You must compile with either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ flag.
#endif

@implementation SarienView

- (id)initWithFrame:(NSRect)frameRect
{
      CGDataProviderRef provider;
      CGColorSpaceRef   colors;
      unsigned int*     c;
      unsigned int      i, size;
    
      [super initWithFrame:frameRect];
      mutex = [[NSLock alloc] init];
    
      colors   = CGColorSpaceCreateDeviceRGB();
      size     = GFX_WIDTH * GFX_HEIGHT * 4;
      screen   = (unsigned int*)malloc(size);
      provider = CGDataProviderCreateWithData(NULL, screen, size, NULL);
    
      c = screen;
      for (i = 0; i < (GFX_WIDTH * GFX_HEIGHT); i++) {
#ifdef __BIG_ENDIAN__
            *c++ = 0xff000000; // ARGB -> 100% Opaque pixel entirely black.
#else
            *c++ = 0x000000ff; // BGRA -> 100% Opaque pixel entirely black.
#endif
      }
    
      screenImage = CGImageCreate(
            GFX_WIDTH,
            GFX_HEIGHT,
            8,
            32,
            GFX_WIDTH * 4,
            colors,
            kCGImageAlphaFirst,
            provider,
            NULL,
            0,
            kCGRenderingIntentDefault);

      CGDataProviderRelease(provider);
      CGColorSpaceRelease(colors);
    
      sarienView = self;
      return self;
}


- (void)dealloc
{
      CGImageRelease(screenImage);
      free(screen);
      [mutex release];
      [super dealloc];
}


- (void)displayIfNeeded
{
      [self setNeedsDisplay: YES];
      [super displayIfNeeded];
}


- (BOOL)needsDisplay
{
      return YES;
}


- (void)drawRect:(NSRect)aRect
{
      CGContextRef context;
      CGRect rc;
      NSRect bnd;

      [mutex lock];

      context = [[NSGraphicsContext graphicsContextWithWindow:
            [self window]] graphicsPort];
      bnd = [self frame];
      rc  = CGRectMake(bnd.origin.x, bnd.origin.y,
            aRect.size.width, aRect.size.height);

      CGContextDrawImage(context, rc, screenImage);

      [mutex unlock];
}


- (unsigned int*)screenContent
{
      return screen;
}


- (BOOL)acceptsFirstResponder
{
      return YES;
}


- (void)keyDown:(NSEvent*)event
{
      NSString* characters;
      int i, length;
    
      characters = [event characters];
      length     = [characters length];
    
      [mutex lock];
      for (i = 0; i < length; i++) {
            // NSLog(@"Key Down: %d", [characters characterAtIndex: i]);
            key_queue = [characters characterAtIndex: i];
            key_queue_end %= KEY_QUEUE_SIZE;
      }
      [mutex unlock];
}


- (void)mouseDown:(NSEvent *)event
{
      NSPoint mouseLoc;
      NSRect wndFrame;
      float wCvt, hCvt;

      wndFrame = [self frame];
      wCvt = (float)GFX_WIDTH / (float)(wndFrame.size.width);
      hCvt = (float)GFX_HEIGHT / (float)(wndFrame.size.height);  
      mouseLoc = [self convertPoint:[event locationInWindow] fromView:nil];
      mouse.x = mouseLoc.x * wCvt;
      mouse.y = GFX_HEIGHT - (mouseLoc.y * hCvt);
  
      [mutex lock];
  
      switch ([event type]) {
      case NSRightMouseUp:
      case NSLeftMouseUp:
            mouse.button = FALSE;
            break;
      case NSLeftMouseDown:
            key_queue = BUTTON_LEFT;
            key_queue_end %= KEY_QUEUE_SIZE;
            mouse.button = TRUE;
            break;
      case NSRightMouseDown:
            key_queue = BUTTON_RIGHT;
            key_queue_end %= KEY_QUEUE_SIZE;
            mouse.button = TRUE;
            break;
      default:    // address enumeration value not handled warning
            break;
      }

      [mutex unlock];
}


- (BOOL)hasPendingKey
{
      return key_queue_start != key_queue_end;
}


- (int)getKey
{
      unichar k;
    
      while (key_queue_start == key_queue_end)
            cocoa_timer();

      [mutex lock];
      k = key_queue;
      key_queue_start %= KEY_QUEUE_SIZE;
      [mutex unlock];
            
      /* FIXME: use NSAlternateKeyMask/NSControlKeyMask to handle modifiers */

      switch (k) {
            case NSUpArrowFunctionKey:    return KEY_UP;
            case NSDownArrowFunctionKey:  return KEY_DOWN;
            case NSLeftArrowFunctionKey:  return KEY_LEFT;
            case NSRightArrowFunctionKey: return KEY_RIGHT;

            case 127:
            case NSDeleteFunctionKey:
            case NSDeleteCharFunctionKey: return KEY_BACKSPACE;

            case NSHomeFunctionKey:       return KEY_UP_LEFT;
            case NSPageUpFunctionKey:     return KEY_UP_RIGHT;
            case NSEndFunctionKey:        return KEY_DOWN_LEFT;
            case NSPageDownFunctionKey:   return KEY_DOWN_RIGHT;

            case NSExecuteFunctionKey:    return KEY_ENTER;

            case NSF1FunctionKey:         return 0x3b00;
            case NSF2FunctionKey:         return 0x3c00;
            case NSF3FunctionKey:         return 0x3d00;
            case NSF4FunctionKey:         return 0x3e00;
            case NSF5FunctionKey:         return 0x3f00;
            case NSF6FunctionKey:         return 0x4000;
            case NSF7FunctionKey:         return 0x4100;
            case NSF8FunctionKey:         return 0x4200;
            case NSF9FunctionKey:         return 0x4300;
            case NSF10FunctionKey:        return 0x4400;
            case NSF11FunctionKey:        return KEY_STATUSLN;
            case NSF12FunctionKey:        return KEY_PRIORITY;

            default:                break;
      }
    
      return k;
}


- (void)lock
{
      [mutex lock];
}


- (void)unlock
{
      [mutex unlock];
}

@end


Generated by  Doxygen 1.6.0   Back to index