View difference between Paste ID: vmX6rb1h and EkPVTVRZ
SHOW: | | - or go back to the newest paste.
1
//
2
//  InterfaceController.m
3
//  cemu_core WatchKit Extension
4
//
5
//  Created by Adrien Bertrand on 2016-01-07.
6
//  Copyright © 2016 adriweb. All rights reserved.
7
//
8
9
#import "InterfaceController.h"
10
#import <WatchConnectivity/WatchConnectivity.h>
11
#import <UIKit/UIGraphics.h>
12
#import "emu.h"
13
#import "lcd.h"
14
15
@interface InterfaceController() <WCSessionDelegate>
16
17
@property (strong, nonatomic) WCSession *session;
18
19
@end
20
21
@implementation InterfaceController
22
23
uint16_t framebuffer[320 * 240];
24
uint32_t outPixel8888[320 * 240];
25
uint32_t bitfields[] = { 0x01F, 0x000, 0x000 };
26
CGSize scaleSize;
27
bool portraitOrientation = true;
28
bool lcdOff = true;
29
30
extern bool doGuiStuff;
31
32
-(instancetype)init {
33
    self = [super init];
34
    
35
    if (self) {
36
        if ([WCSession isSupported]) {
37
            self.session = [WCSession defaultSession];
38
            self.session.delegate = self;
39
            [self.session activateSession];
40
        }
41
    }
42
    
43
    return self;
44
}
45
46
- (void)awakeWithContext:(id)context {
47
    [super awakeWithContext:context];
48
    // Configure interface objects here.
49
    
50
    [self.screenButton setBackgroundImage:[UIImage imageNamed:@"icon"]];
51
    
52
    CGFloat viewHeight = self.contentFrame.size.height;
53
    scaleSize = CGSizeMake(viewHeight * 240.0 / 320.0, viewHeight);
54
        
55
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
56
        NSString *romPath = [[[NSBundle mainBundle] URLForResource:@"84pce_51" withExtension:@"rom"] path];
57
        NSLog(@"romPath = %@", romPath);
58
        rom_image = strdup([romPath UTF8String]);
59
        
60
        bool reset_true = true;
61
        bool success = emu_start();
62
        
63
        NSLog(@"started");
64
        
65
        if (success) {
66
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
67
                while (!exiting) {
68
                    [self updateLCD];
69
                    usleep(25000);
70
                }
71
            });
72
            emu_loop(reset_true);
73
        }
74
    });
75
     
76
    NSLog(@"finished");
77
}
78
79
- (IBAction)toggleOrientation:(id)sender
80
{
81
    portraitOrientation = !portraitOrientation;
82
}
83
84
85
- (UIImage *) convertBitmapRGB16ToUIImage:(const uint16_t*) buffer
86
                                withWidth:(int) width
87
                               withHeight:(int) height
88
{
89
    size_t outBufferLength = width * height * sizeof(uint32_t);
90
    
91
    uint16_t *inPixel565 = (uint16_t*)buffer;
92
    
93
    for (unsigned int cnt=0; cnt < width * height; inPixel565++, cnt++)
94
    {
95
        outPixel8888[cnt] = ( ((((*inPixel565 >> 11) & 0x1F) * 527) + 23) >> 6 )
96
                          | ( ((((*inPixel565 >> 5)  & 0x3F) * 259) + 33) >> 6 ) << 8
97
                          | ( ((( *inPixel565        & 0x1F) * 527) + 23) >> 6 ) << 16;
98
    }
99
    
100
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, outPixel8888, outBufferLength, NULL);
101
    size_t bitsPerComponent = 8;
102
    size_t bitsPerPixel = 32;
103
    size_t bytesPerRow = sizeof(uint32_t) * width;
104
    
105
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
106
    if(colorSpaceRef == NULL) {
107
        NSLog(@"Error allocating color space");
108
        CGDataProviderRelease(provider);
109
        return nil;
110
    }
111
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast;
112
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
113
    
114
    CGImageRef iref = CGImageCreate(width,
115
                                    height,
116
                                    bitsPerComponent,
117
                                    bitsPerPixel,
118
                                    bytesPerRow,
119
                                    colorSpaceRef,
120
                                    bitmapInfo,
121
                                    provider,	// data provider
122
                                    NULL,		// decode
123
                                    YES,		// should interpolate
124
                                    renderingIntent);
125
    
126
    uint32_t* pixels = (uint32_t*)malloc(outBufferLength);
127
    
128
    if(pixels == NULL) {
129
        NSLog(@"Error: Memory not allocated for bitmap");
130
        CGDataProviderRelease(provider);
131
        CGColorSpaceRelease(colorSpaceRef);
132
        CGImageRelease(iref);
133
        return nil;
134
    }
135
    
136
    CGContextRef context = CGBitmapContextCreate(pixels,
137
                                                 width,
138
                                                 height,
139
                                                 bitsPerComponent,
140
                                                 bytesPerRow,
141
                                                 colorSpaceRef,
142
                                                 bitmapInfo);
143
    
144
    if(context == NULL) {
145
        NSLog(@"Error context not created");
146
        free(pixels);
147
    }
148
    
149
    UIImage *image = nil;
150
    if(context) {
151
        
152
        CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);
153
        
154
        CGImageRef imageRef = CGBitmapContextCreateImage(context);
155
        
156
        image = [UIImage imageWithCGImage:imageRef];
157
        
158
        CGImageRelease(imageRef);	
159
        CGContextRelease(context);	
160
    }
161
    
162
    CGColorSpaceRelease(colorSpaceRef);
163
    CGImageRelease(iref);
164
    CGDataProviderRelease(provider);
165
    
166
    if (pixels) {
167
        free(pixels);
168
    }
169
    
170
    return image;
171
}
172
173
174
- (void)updateLCD
175
{
176
    if (!doGuiStuff)
177
    {
178
        return;
179
    } else {
180
        doGuiStuff = false;
181
    }
182
    
183
    if (!(lcd.control & 0x800))
184
    {
185
        if (!lcdOff)
186
        {
187
            lcdOff = true;
188
            [self.screenButton setBackgroundImage:nil];
189
            [self.screenButton setTitle:@"LCD Off"];
190
        }
191
        return;
192
    } else {
193
        lcdOff = false;
194
        [self.screenButton setTitle:@""];
195
    }
196
        
197
    lcd_drawframe(framebuffer, bitfields);
198
    
199
    UIImage *tmpImage = [self convertBitmapRGB16ToUIImage:(const uint16_t*)framebuffer withWidth:320 withHeight:240];
200
    
201
    if (!portraitOrientation)
202
    {
203
        UIImage *screenRotated = [[UIImage alloc] initWithCGImage: tmpImage.CGImage
204
                                                            scale: 1
205
                                                      orientation: UIImageOrientationRight];
206
        
207
        @autoreleasepool {
208
            UIGraphicsBeginImageContextWithOptions(scaleSize, NO, 0.0);
209
            [screenRotated drawInRect:CGRectMake(0, 0, scaleSize.width, scaleSize.height)];
210
            UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
211
            UIGraphicsEndImageContext();
212
            [self.screenButton setBackgroundImage:resizedImage];
213
        }
214
        
215
        [screenRotated release];
216
    } else {
217
        [self.screenButton setBackgroundImage:tmpImage];
218
    }
219
220
    [tmpImage release];
221
}
222
223
- (void)willActivate {
224
    // This method is called when watch view controller is about to be visible to user
225
    [super willActivate];
226
}
227
228
- (void)didDeactivate {
229
    // This method is called when watch view controller is no longer visible
230
    [super didDeactivate];
231
}
232
233
@end