Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swiftでつくるファミコンエミュレータのススメ

Tomochika Hara
September 06, 2019

 Swiftでつくるファミコンエミュレータのススメ

Tomochika Hara

September 06, 2019
Tweet

More Decks by Tomochika Hara

Other Decks in Programming

Transcript

  1. SwiftͰͭ͘Δ
    ϑΝϛίϯΤϛϡϨʔλͷ
    εεϝ
    2019-09-05
    iOSDC Japan 2019
    thara @zetta1985

    View Slide

  2. View Slide

  3. View Slide

  4. ໨ඪ

    View Slide

  5. $16 116
    13(30.
    $)"30.
    3".

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. ϑΝϛίϯΤϛϡϨʔλΛ
    SwiftͰॻ͘͜ͱͷϝϦοτ

    View Slide

  10. ϝϦοτ 1
    ݻఆ௕੔਺ܕ

    View Slide

  11. ݻఆ௕੔਺ܕ
    • UInt8 / Int8
    • UInt16 / Int16
    • UInt32 / Int32
    • ͜ΕΒ͕ͳ͚Ε͹ɺANDԋࢉͩΒ͚ʹͳΔ
    • Javaܥͱ͔LLͱ͔͸͜Ε͕͠ΜͲ͍͔΋

    View Slide

  12. ࢀߟɿJava࣮૷ͷ৔߹
    https://github.com/andrew-hoffman/halfnes

    View Slide

  13. ࢀߟɿTypeScript࣮૷ͷ৔߹
    https://github.com/r7kamura/nes8

    View Slide

  14. ϝϦοτ 2
    Overflow Operator

    View Slide

  15. Overflow Operator
    // 65535
    let value = UInt16.max
    // 0
    let result = value &+ 1

    View Slide

  16. ϝϦοτ 3
    OptionSet

    View Slide

  17. ϏοτϚεΫఆٛ
    struct Status: OptionSet {
    let rawValue: UInt8
    /// Negative
    static let N = Status(rawValue: 1 << 7)
    /// Overflow
    static let V = Status(rawValue: 1 << 6)
    /// Decimal mode
    static let D = Status(rawValue: 1 << 3)
    /// IRQ prevention
    static let I = Status(rawValue: 1 << 2)
    /// Zero
    static let Z = Status(rawValue: 1 << 1)
    /// Carry
    static let C = Status(rawValue: 1 << 0)
    /// The B flag
    static let B = Status(rawValue: 0b00110000)
    }

    View Slide

  18. ҙਤ͕Θ͔Γ΍͍͢Ϗοτԋࢉ
    // 0b1001100
    var cpuStatus: Status = [.V, .D, .I]
    // 0b1001100 & ~0b00001101 = 0b1000000
    cpuStatus.remove([.C, .D, .I])
    // 0b1000000 | 0b0000001 = 0b1000001
    cpuStatus.formUnion(.C)

    View Slide

  19. ϝϦοτ 4
    ύϑΥʔϚϯε

    View Slide

  20. swift run -c debug
    3 FPS

    View Slide

  21. swift run -c release
    100 FPS

    View Slide

  22. ؾΛ͚͍ͭͯͨ͜ͱ
    • ΦϒδΣΫτΛແବʹ࡞Βͳ͍
    • ΫϩʔδϟΛಈతʹ࡞Βͳ͍
    • ແବͳܭࢉ͸͠ͳ͍
    • ܧঝ͠ͳ͍Ϋϥεʹ͸finalΛ͚ͭΔ
    • ͳΔ΂͘privateʹ͢Δ

    View Slide

  23. ͜ͷఔ౓ͷҙࣝͰ΋
    100FPSग़Δ

    Θ͔Γ΍͢͞ΛॏࢹͰ͖Δ

    View Slide

  24. ϋϚͬͨ͜ͱ

    View Slide

  25. Release BuildͷΈ
    ϨϯμϦϯά͞Εͳ͍

    View Slide

  26. PureSwift/SDL
    public func copy(_ texture: SDLTexture,
    source: SDL_Rect? = nil,
    destination: SDL_Rect? = nil) throws
    {
    let srcPtr: UnsafePointer?
    if let rect = source {
    srcPtr = withUnsafePointer(to: rect) { $0 }
    } else {
    srcPtr = nil
    }
    ...
    try SDL_RenderCopy(ptr, texture.ptr,
    sourcePointer,
    destPtr).sdlThrow(...
    }
    https://github.com/PureSwift/SDL

    View Slide

  27. thara/SDL
    public func copy(_ texture: SDLTexture,
    _ s: inout SDL_Rect,
    _ d: inout SDL_Rect) throws {
    try SDL_RenderCopy(ptr, texture.ptr,
    &s, &d).sdlThrow(type: type(of: self))
    }
    public func copy(_ texture: SDLTexture,
    _ s: inout SDL_Rect) throws {
    try SDL_RenderCopy(ptr, texture.ptr,
    &s, nil).sdlThrow(type: type(of: self))
    }
    public func copy(_ texture: SDLTexture,
    _ d: inout SDL_Rect) throws {
    try SDL_RenderCopy(ptr, texture.ptr,
    nil, &d).sdlThrow(type: type(of: self))
    }

    View Slide

  28. ·ͱΊ
    • SwiftͰ͸ίʔυͷΘ͔Γ΍͢͞Λॏࢹͯ͠ΤϛϡϨʔλ։ൃͰ͖Δ
    • ݻఆ௕੔਺ܕͰϊΠζͱͳΔϚεΫ͕ෆཁ
    • Overflow OperatorͰϥοϓΞϥ΢ϯυ͢Δԋࢉ͕ࣗ໌
    • OptionSetʹΑΔϏοτϚεΫͷߴ͍දݱྗ
    • ίϯύΠϥͷ࠷దԽ͕͍͢͝
    • ͗ͯ͢͢͝όάͷݪҼ͕Θ͔Βͳ͍

    View Slide

  29. ΤϛϡϨʔλ։ൃλΠϜϥΠϯ

    View Slide

  30. View Slide