mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-04-27 22:05:06 -06:00
352 lines
9.3 KiB
Plaintext
352 lines
9.3 KiB
Plaintext
//
|
|
// wiview.mm
|
|
// wi
|
|
//
|
|
// Created by Scott Ludwig on 4/21/08.
|
|
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
|
//
|
|
|
|
#import "game/iphone/wiview.h"
|
|
#import "game/iphone/spritemgradapter.h"
|
|
#import "game/iphone/iphoneanimsprite.h"
|
|
#import "game/iphone/selectionsprite.h"
|
|
#import "game/iphone/webviewcontroller.h"
|
|
#include "game/iphone/input.h"
|
|
#include "mpshared/misc.h"
|
|
|
|
@implementation WiView
|
|
|
|
- (id)initWithFrame:(struct CGRect)rect
|
|
{
|
|
self = [super initWithFrame: rect];
|
|
if (self == nil) {
|
|
return nil;
|
|
}
|
|
|
|
#if 0 // iOS <= 7
|
|
rect_ = CGRectMake(0, 0, rect.size.height, rect.size.width);
|
|
#else
|
|
// As of iOS 8 screen coordinates are interface oriented not device oriented.
|
|
rect_ = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
|
#endif
|
|
|
|
[self setMultipleTouchEnabled: YES];
|
|
atouch_[0] = NULL;
|
|
atouch_[1] = NULL;
|
|
havePalette_ = false;
|
|
pb_ = NULL;
|
|
memset(&rcClip1_, 0, sizeof(rcClip1_));
|
|
memset(&rcClip2_, 0, sizeof(rcClip2_));
|
|
pcrit_ = new base::CriticalSection();
|
|
psprm_ = new wi::SpriteManagerAdapter(self);
|
|
cpspr_ = 0;
|
|
fSpriteDirty_ = false;
|
|
game_thread_ = NULL;
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
if (pb_ != NULL) {
|
|
free(pb_);
|
|
}
|
|
delete psprm_;
|
|
delete pcrit_;
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)setGameThread:(base::Thread *)thread
|
|
{
|
|
game_thread_ = thread;
|
|
}
|
|
|
|
- (void)checkTracking:(UIEvent *)event
|
|
{
|
|
// This is just in case - if we lose an up, this detects it and resets
|
|
// things. So far touchesCancelled appears to be working as advertised.
|
|
|
|
int cTouchesTracking = 0;
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] != NULL) {
|
|
cTouchesTracking++;
|
|
}
|
|
}
|
|
int cTouchesFound = 0;
|
|
NSSet *allTouches = [event allTouches];
|
|
for (UITouch *touch in allTouches) {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (touch == atouch_[i]) {
|
|
cTouchesFound++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If it's whacked, post an up and set the slot to NULL.
|
|
|
|
if (cTouchesFound != cTouchesTracking) {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] != NULL) {
|
|
atouch_[i] = NULL;
|
|
base::Message msg;
|
|
msg.id = (i == 0) ? kidmMouseUp : kidmMouseUp2;
|
|
msg.x = aptLast_[i].x;
|
|
msg.y = aptLast_[i].y;
|
|
msg.ff = 0;
|
|
msg.ms = wi::HostGetMillisecondCount();
|
|
if (game_thread_ != NULL) {
|
|
game_thread_->Post(&msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
|
|
{
|
|
// Sometimes we won't get an up. Handle this case.
|
|
|
|
[self checkTracking:event];
|
|
|
|
// Keep track of touches. According to the documentation, the touch *
|
|
// pointer value is constant throughout the life of the touch, so it
|
|
// can be used as sort of an id.
|
|
|
|
|
|
// Only process touches for this view. WebView and ChatView are
|
|
// handled as children, and events in their toolbar area somehow
|
|
// get sent here. However this parent only wants touches for its
|
|
// own view, not for the whole window.
|
|
|
|
for (UITouch *touch in touches) {
|
|
if (touch.view != self) {
|
|
continue;
|
|
}
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] == NULL) {
|
|
atouch_[i] = touch;
|
|
CGPoint point = [touch locationInView: nil];
|
|
base::Message msg;
|
|
msg.id = (i == 0) ? kidmMouseDown : kidmMouseDown2;
|
|
msg.x = (int)point.x;
|
|
msg.y = (int)point.y;
|
|
msg.ff = 0;
|
|
msg.ms = wi::HostGetMillisecondCount();
|
|
if (game_thread_ != NULL) {
|
|
game_thread_->Post(&msg);
|
|
}
|
|
aptLast_[i].x = (int)point.x;
|
|
aptLast_[i].y = (int)point.y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
|
|
{
|
|
for (UITouch *touch in touches) {
|
|
if (touch.view != self) {
|
|
continue;
|
|
}
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] == touch) {
|
|
CGPoint point = [touch locationInView: nil];
|
|
base::Message msg;
|
|
msg.id = (i == 0) ? kidmMouseMove : kidmMouseMove2;
|
|
msg.x = (int)point.x;
|
|
msg.y = (int)point.y;
|
|
msg.ff = 0;
|
|
msg.ms = wi::HostGetMillisecondCount();
|
|
if (game_thread_ != NULL) {
|
|
game_thread_->Post(&msg,
|
|
(i == 0) ? kidmMouseMove2 : kidmMouseMove);
|
|
}
|
|
aptLast_[i].x = (int)point.x;
|
|
aptLast_[i].y = (int)point.y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
|
|
{
|
|
for (UITouch *touch in touches) {
|
|
if (touch.view != self) {
|
|
continue;
|
|
}
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] == touch) {
|
|
atouch_[i] = NULL;
|
|
CGPoint point = [touch locationInView: nil];
|
|
base::Message msg;
|
|
msg.id = (i == 0) ? kidmMouseUp : kidmMouseUp2;
|
|
msg.x = (int)point.x;
|
|
msg.y = (int)point.y;
|
|
msg.ff = 0;
|
|
msg.ms = wi::HostGetMillisecondCount();
|
|
if (game_thread_ != NULL) {
|
|
game_thread_->Post(&msg);
|
|
}
|
|
aptLast_[i].x = (int)point.x;
|
|
aptLast_[i].y = (int)point.y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
|
|
{
|
|
for (int i = 0; i < 2; i++) {
|
|
if (atouch_[i] != NULL) {
|
|
atouch_[i] = NULL;
|
|
base::Message msg;
|
|
msg.id = (i == 0) ? kidmMouseUp : kidmMouseUp2;
|
|
msg.x = aptLast_[i].x;
|
|
msg.y = aptLast_[i].y;
|
|
msg.ff = 0;
|
|
msg.ms = wi::HostGetMillisecondCount();
|
|
if (game_thread_ != NULL) {
|
|
game_thread_->Post(&msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)getSurfaceProperties:(wi::SurfaceProperties *)pprops
|
|
{
|
|
pprops->cxWidth = (int)rect_.size.width;
|
|
pprops->cyHeight = (int)rect_.size.height;
|
|
pprops->cbxPitch = 2;
|
|
pprops->cbyPitch = (int)rect_.size.width * 2;
|
|
pprops->ffFormat = wi::kfDirect565;
|
|
}
|
|
|
|
- (wi::SpriteManager *)getSpriteManager
|
|
{
|
|
return psprm_;
|
|
}
|
|
|
|
- (void)setClipRects:(wi::Rect *)prc1 prc2:(wi::Rect *)prc2
|
|
{
|
|
rcClip1_ = *prc1;
|
|
rcClip2_ = *prc2;
|
|
}
|
|
|
|
- (wi::AnimSprite *)createAnimSprite
|
|
{
|
|
return new wi::IPhoneAnimSprite(psprm_);
|
|
}
|
|
|
|
- (wi::SelectionSprite *)createSelectionSprite
|
|
{
|
|
return new wi::IPhoneSelectionSprite(psprm_);
|
|
}
|
|
|
|
- (void)addSprite:(wi::Sprite *)pspr
|
|
{
|
|
base::CritScope cs(pcrit_);
|
|
|
|
// If already added, just recreate the layer
|
|
|
|
bool fFound = false;
|
|
for (int i = 0; i < cpspr_; i++) {
|
|
if (pspr == apspr_[i]) {
|
|
fFound = true;
|
|
}
|
|
}
|
|
if (!fFound && cpspr_ < ARRAYSIZE(apspr_) - 1) {
|
|
apspr_[cpspr_] = pspr;
|
|
cpspr_++;
|
|
}
|
|
|
|
fSpriteDirty_ = true;
|
|
}
|
|
|
|
- (void)removeSprite:(wi::Sprite *)pspr
|
|
{
|
|
base::CritScope cs(pcrit_);
|
|
|
|
bool fFound = false;
|
|
for (int i = 0; i < cpspr_; i++) {
|
|
if (pspr == apspr_[i]) {
|
|
cpspr_--;
|
|
if (i < ARRAYSIZE(apspr_) - 1) {
|
|
memmove(&apspr_[i], &apspr_[i + 1],
|
|
(ARRAYSIZE(apspr_) - 1 - i) * ELEMENTSIZE(apspr_));
|
|
}
|
|
fFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
fSpriteDirty_ = true;
|
|
}
|
|
|
|
- (void)updateSprite:(wi::Sprite *)pspr
|
|
{
|
|
fSpriteDirty_ = true;
|
|
}
|
|
|
|
- (void)drawSprites:(CGContextRef)ctx
|
|
{
|
|
base::CritScope cs(pcrit_);
|
|
|
|
if (cpspr_ == 0) {
|
|
return;
|
|
}
|
|
|
|
// Save context before setting clip rects
|
|
CGContextSaveGState(ctx);
|
|
|
|
// First clip to the playfield up to just before the left edge of the
|
|
// minimap, then the area above the minimap.
|
|
|
|
#if 0
|
|
CGRect arcClip[2];
|
|
arcClip[0].origin.x = rcClip1_.left;
|
|
arcClip[0].origin.y = (int)rect_.size.width - rcClip1_.top -
|
|
rcClip1_.Height();
|
|
arcClip[0].size.width = rcClip1_.Width();
|
|
arcClip[0].size.height = rcClip1_.Height();
|
|
arcClip[1].origin.x = rcClip2_.left;
|
|
arcClip[1].origin.y = (int)rect_.size.width - rcClip2_.top -
|
|
rcClip2_.Height();
|
|
arcClip[1].size.width = rcClip2_.Width();
|
|
arcClip[1].size.height = rcClip2_.Height();
|
|
#else
|
|
CGRect arcClip[2];
|
|
arcClip[0].origin.x = rcClip1_.left;
|
|
arcClip[0].origin.y = rect_.size.height - rcClip1_.bottom;
|
|
arcClip[0].size.width = rcClip1_.Width();
|
|
arcClip[0].size.height = rcClip1_.Height();
|
|
arcClip[1].origin.x = rcClip2_.left;
|
|
arcClip[1].origin.y = rect_.size.height - rcClip2_.bottom;
|
|
arcClip[1].size.width = rcClip2_.Width();
|
|
arcClip[1].size.height = rcClip2_.Height();
|
|
#endif
|
|
CGContextClipToRects(ctx, arcClip, 2);
|
|
|
|
// Draw sprites
|
|
wi::Size siz;
|
|
siz.cx = (int)rect_.size.width;
|
|
siz.cy = (int)rect_.size.height;
|
|
for (int i = 0; i < cpspr_; i++) {
|
|
apspr_[i]->Draw(ctx, &siz);
|
|
}
|
|
|
|
// Restore context
|
|
CGContextRestoreGState(ctx);
|
|
}
|
|
|
|
- (void)setFormMgrs:(wi::FormMgr *)pfrmmSimUI input:(wi::FormMgr *)pfrmmInput
|
|
{
|
|
}
|
|
|
|
- (void)resetScrollOffset
|
|
{
|
|
}
|
|
@end
|