Существует ли “правильный” способ сделать, чтобы NSTextFieldCell нарисовал вертикально центрируемый текст?

Эмуляция является многоаспектной областью. Вот основные идеи и функциональные компоненты. Я собираюсь разломать его на кусочки и затем заполнить детали через редактирования. Многие вещи, которые я собираюсь описать, потребуют знания внутренних работ процессоров - знание блока необходимо. Если я немного слишком неопределенен на определенных вещах, задайте вопросы, таким образом, я могу продолжить улучшать этот ответ.

Основная идея:

Эмуляция работает путем обработки поведения процессора и отдельных компонентов. Вы создаете каждую отдельную часть системы и затем соединяетесь, части во многом как провода делают в аппаратных средствах.

эмуляция Процессора:

существует три способа обработать эмуляцию процессора:

  • Интерпретация
  • Динамическая перекомпиляция
  • Статическая перекомпиляция

Со всеми этими путями, у Вас есть та же полная цель: выполните часть кода, чтобы изменить состояние процессора и взаимодействовать с 'аппаратными средствами'. Состояние процессора является скоплением регистров процессора, обработчиков прерываний, и т.д. для данной цели процессора. Для этих 6502 у Вас было бы много 8-разрядных целых чисел, представляющих регистры: A, X, Y, P, и S; у Вас также было бы 16-разрядное PC регистр.

С интерпретацией, Вы запускаете в IP (указатель команд - также названный PC, счетчик команд) и читаете инструкцию из памяти. Ваш код анализирует эту инструкцию и использует эту информацию для изменения состояния процессора, как определено процессором. Базовая проблема с интерпретацией состоит в том, что это очень медленно; каждый раз, когда Вы обрабатываете данную инструкцию, необходимо декодировать ее и выполнить необходимую операцию.

С динамической перекомпиляцией, Вы выполняете итерации по коду во многом как интерпретация, но вместо того, чтобы просто выполнить коды операций, Вы создаете список операций. Как только Вы достигаете команды перехода, Вы составляете этот список операций к машинному коду для Вашей серверной платформы, тогда Вы кэшируете этот скомпилированный код и выполняете его. Тогда при ударе данной группы инструкции снова только необходимо выполнить код от кэша. (BTW, большинство людей на самом деле не составляет список инструкций, но компилирует их в машинный код на лету - это делает более трудным оптимизировать, но это вне объема этого ответа, если достаточному количеству людей не интересно)

Со статической перекомпиляцией, Вы делаете то же как в динамической перекомпиляции, но Вы следуете за ответвлениями. Вы заканчиваете тем, что создали блок кода, который представляет весь код в программе, которая может тогда быть выполнена без дальнейшей интерференции. Это было бы большим механизмом если бы не следующие проблемы:

  • Код, который не находится в программе для начала (например, сжатый, зашифрованный, генерировал/изменил во времени выполнения, и т.д.) не будет перекомпилирован, таким образом, это не будет работать
  • , было доказано, что нахождение всего кода в данном двоичном файле эквивалентно Проблема остановки

, Они объединяются для создания статической перекомпиляции абсолютно неосуществимой в 99% случаев. Для получения дополнительной информации Michael Steil провел некоторое большое исследование в статическую перекомпиляцию - лучшее, которое я видел.

другая сторона к эмуляции процессора является путем, которым Вы взаимодействуете с аппаратными средствами. Это действительно имеет две стороны:

  • Процессор, синхронизирующий
  • Обработка прерываний

синхронизация Процессора:

платформы Certain - особенно более старые консоли как NES, SNES, и т.д. - требуют, чтобы Ваш эмулятор имел строгую синхронизацию, чтобы быть абсолютно совместимым. С NES у Вас есть PPU (пиксельный блок обработки), который требует, чтобы ЦП поместил пиксели в свою память в точные моменты. При использовании интерпретации можно легко считать циклы и эмулировать надлежащую синхронизацию; с динамической/статичной перекомпиляцией вещами является/lot/более сложное.

Обработка прерываний:

Прерывания являются основным механизмом, который ЦП передает с аппаратными средствами. Обычно Ваши аппаратные компоненты скажут ЦП, что прерывает его заботы о. Это довольно просто - когда Ваш код бросает данное прерывание, Вы смотрите на таблицу обработчика прерываний и называете соответствующий обратный вызов.

Аппаратная эмуляция:

существует две стороны к эмуляции данного устройства:

  • Эмуляция функциональности устройства
  • Эмуляция интерфейсов существующего устройства

Берут случай жесткого диска. Функциональность эмулирована путем создания внешней памяти, считайте/пишите/форматируйте стандартные программы и т.д. Эта часть обычно очень проста.

фактический интерфейс устройства немного более сложен. Это обычно - некоторая комбинация регистров с отображенной памятью (например, части памяти, которую устройство наблюдает за изменениями, чтобы сделать передачу сигналов), и прерывания. Для жесткого диска у Вас может быть область с отображенной памятью, куда Вы помещаете команды чтения, записи, и т.д., затем считывают эти данные назад.

я вдавался бы в большее количество подробностей, но существует миллион путей, которыми можно пойти с ними. Если у Вас есть какие-либо конкретные вопросы здесь, не стесняйтесь спрашивать, и я добавлю информацию

Ресурсы:

я думаю, что дал довольно хорошее введение здесь, но существует тонна из дополнительных областей. Я более, чем рад помочь с любыми вопросами; я был очень неопределенен в большей части из этого просто из-за огромной сложности.

Обязательные ссылки Википедии:

Общие ресурсы эмуляции:

  • Zophar - Это - то, где я получил свой запуск с эмуляцией, сначала загрузив эмуляторы и в конечном счете разграбив их огромные архивы документации. Это - абсолютный лучший ресурс, который Вы можете возможно иметь.
  • NGEmu - Не много прямых ресурсов, но их форумы непобедимы.
  • RomHacking.net - раздел документов содержит ресурсы относительно архитектуры машины для популярных консолей

проекты Эмулятора сослаться:

  • IronBabel - Это - платформа эмуляции для.NET, записанной в Nemerle, и перекомпилировало код к C# на лету.Отказ от ответственности: Это - мой проект, так простите бесстыдный разъем.
  • BSnes - потрясающий эмулятор SNES с целью идеальной для цикла точности.
  • MAME - эмулятор галереи. Большая ссылка.
  • 6502asm.com - Это - эмулятор JavaScript 6502 с прохладным небольшим форумом.
  • dynarec'd 6502asm - Это - немного взлома, я сделал более чем день или два. Я взял существующий эмулятор с 6502asm.com и изменил его для динамичной перекомпиляции кода к JavaScript для крупных увеличений скорости.

ссылки перекомпиляции Процессора:

Приложение:

Это был хорошо более чем год, с тех пор как этот ответ был отправлен, и со всем вниманием это добиралось, я полагал, что пора обновить некоторые вещи.

, Возможно, самая захватывающая вещь в эмуляции прямо сейчас libcpu, запущенный вышеупомянутым Michael Steil. Это - библиотека, предназначенная для поддержки большого количества ядер процессора, которые используют LLVM для перекомпиляции (статичный и динамичный!). Это имеет огромный потенциал, и я думаю, что это сделает большие вещи для эмуляции.

на документы страуса эму также обратили мое внимание, который содержит большой репозиторий документации по системе, которая очень полезна для целей эмуляции. Я не провел много времени там, но похоже, что у них есть много больших ресурсов.

я рад, что это сообщение было полезно, и я надеюсь, что могу выйти своей задницы и закончить мою книгу по предмету к концу года в следующем году / ранний в следующем году.

50
задан e.James 5 August 2009 в 08:25
поделиться

3 ответа

Переопределение NSCell's -titleRectForBounds: должно сделать это - это метод, отвечающий за указание ячейке, где рисовать текст:

- (NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
    titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
    return titleFrame;
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSRect titleRect = [self titleRectForBounds:cellFrame];
    [[self attributedStringValue] drawInRect:titleRect];
}
31
ответ дан 7 November 2019 в 10:59
поделиться

К вашему сведению, это работает хорошо, хотя мне не удалось заставить его оставаться в центре при редактировании ячейки ... Иногда у меня есть ячейки с большим количеством текста, и этот код может привести к в них они смещены, если высота текста больше, чем высота ячейки, в которой он пытается центрировать его по вертикали. Вот мой модифицированный метод:

- (NSRect)titleRectForBounds:(NSRect)theRect 
 {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
     // test to see if the text height is bigger then the cell, if it is,
     // don't try to center it or it will be pushed up out of the cell!
     if ( titleSize.height < theRect.size.height ) {
         titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
     }
    return titleFrame;
}
4
ответ дан 7 November 2019 в 10:59
поделиться

Любой, кто пытается это сделать, используя метод Мэтта Болла drawInteriorWithFrame: inView: , больше не будет рисовать фон, если вы настроили его рисование в ячейке. Чтобы решить эту проблему, добавьте что-нибудь вроде

[[NSColor lightGrayColor] set];
NSRectFill(cellFrame);

в начало вашего метода drawInteriorWithFrame: inView: .

5
ответ дан 7 November 2019 в 10:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: