git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

JoyKit/JOYSubElement.m

      1 #import "JOYSubElement.h"
      2 
      3 @interface JOYElement ()
      4 {
      5     @public uint16_t _usage;
      6     @public uint16_t _usagePage;
      7     @public uint32_t _uniqueID;
      8     @public int32_t _min;
      9     @public int32_t _max;
     10     @public int32_t _reportID;
     11     @public int32_t _parentID;
     12 }
     13 @end
     14 
     15 @implementation JOYSubElement
     16 {
     17     JOYElement *_parent;
     18     size_t _size; // in bits
     19     size_t _offset; // in bits
     20 }
     21 
     22 - (instancetype)initWithRealElement:(JOYElement *)element
     23                                size:(size_t) size // in bits
     24                              offset:(size_t) offset // in bits
     25                           usagePage:(uint16_t)usagePage
     26                               usage:(uint16_t)usage
     27                                 min:(int32_t)min
     28                                 max:(int32_t)max
     29 {
     30     if ((self = [super init])) {
     31         _parent = element;
     32         _size = size;
     33         _offset = offset;
     34         _usage = usage;
     35         _usagePage = usagePage;
     36         _uniqueID = (uint32_t)((_parent.uniqueID << 16) | offset);
     37         _min = min;
     38         _max = max;
     39         _reportID = _parent.reportID;
     40         _parentID = _parent.parentID;
     41     }
     42     return self;
     43 }
     44 
     45 - (int32_t)value
     46 {
     47     NSData *parentValue = [_parent dataValue];
     48     if (!parentValue) return 0;
     49     if (_size > 32) return 0;
     50     if (_size + (_offset % 8) > 32) return 0;
     51     size_t parentLength = parentValue.length;
     52     if (_size > parentLength * 8) return 0;
     53     if (_size + _offset >= parentLength * 8) return 0;
     54     const uint8_t *bytes = parentValue.bytes;
     55     
     56     uint8_t temp[4] = {0,};
     57     memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
     58     uint32_t ret = (*(uint32_t *)temp) >> (_offset % 8);
     59     ret &= (1 << _size) - 1;
     60     //
     61     if (_min < 0 || _max < 0) { // Uses unsigned values
     62         if (ret & (1 << (_size - 1)) ) { // Is negative
     63             ret |= ~((1 << _size) - 1); // Fill with 1s
     64         }
     65     }
     66     
     67     if (_max < _min) {
     68         return _max + _min - ret;
     69     }
     70 
     71     return ret;
     72 }
     73 
     74 - (IOReturn)setValue: (uint32_t) value
     75 {
     76     NSMutableData *dataValue = [[_parent dataValue] mutableCopy];
     77     if (!dataValue) return -1;
     78     if (_size > 32) return -1;
     79     if (_size + (_offset % 8) > 32) return -1;
     80     size_t parentLength = dataValue.length;
     81     if (_size > parentLength * 8) return -1;
     82     if (_size + _offset >= parentLength * 8) return -1;
     83     uint8_t *bytes = dataValue.mutableBytes;
     84     
     85     uint8_t temp[4] = {0,};
     86     memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
     87     (*(uint32_t *)temp) &= ~((1 << (_size - 1)) << (_offset % 8));
     88     (*(uint32_t *)temp) |= (value) << (_offset % 8);
     89     memcpy(bytes + _offset / 8, temp, (_offset + _size - 1) / 8 - _offset / 8 + 1);
     90     return [_parent setDataValue:dataValue];
     91 }
     92 
     93 - (NSData *)dataValue
     94 {
     95     [self doesNotRecognizeSelector:_cmd];
     96     return nil;
     97 }
     98 
     99 - (IOReturn)setDataValue:(NSData *)data
    100 {
    101     [self doesNotRecognizeSelector:_cmd];
    102     return -1;
    103 }
    104 
    105 
    106 @end

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.