all repos — mgba @ 3310210dc7b7ea79f711dc0e41076c2bf4589c9d

mGBA Game Boy Advance Emulator

src/platform/python/mgba/gba.py (view raw)

 1# Copyright (c) 2013-2016 Jeffrey Pfau
 2#
 3# This Source Code Form is subject to the terms of the Mozilla Public
 4# License, v. 2.0. If a copy of the MPL was not distributed with this
 5# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 6from ._pylib import ffi, lib
 7from .arm import ARMCore
 8from .core import Core
 9from .tile import Sprite
10from .memory import Memory
11
12class GBA(Core):
13    KEY_A = lib.GBA_KEY_A
14    KEY_B = lib.GBA_KEY_B
15    KEY_SELECT = lib.GBA_KEY_SELECT
16    KEY_START = lib.GBA_KEY_START
17    KEY_DOWN = lib.GBA_KEY_DOWN
18    KEY_UP = lib.GBA_KEY_UP
19    KEY_LEFT = lib.GBA_KEY_LEFT
20    KEY_RIGHT = lib.GBA_KEY_RIGHT
21    KEY_L = lib.GBA_KEY_L
22    KEY_R = lib.GBA_KEY_R
23
24    def __init__(self, native):
25        super(GBA, self).__init__(native)
26        self._native = ffi.cast("struct GBA*", native.board)
27        self.sprites = GBAObjs(self)
28        self.cpu = ARMCore(self._core.cpu)
29        self.memory = GBAMemory(self._core)
30
31    def _initTileCache(self, cache):
32        lib.GBAVideoTileCacheInit(cache)
33        lib.GBAVideoTileCacheAssociate(cache, ffi.addressof(self._native.video))
34
35    def _deinitTileCache(self, cache):
36        self._native.video.renderer.cache = ffi.NULL
37        lib.mTileCacheDeinit(cache)
38
39class GBAMemory(Memory):
40    def __init__(self, core):
41        super(GBAMemory, self).__init__(core, 0x100000000)
42
43        self.bios = Memory(core, lib.SIZE_BIOS, lib.BASE_BIOS)
44        self.wram = Memory(core, lib.SIZE_WORKING_RAM, lib.BASE_WORKING_RAM)
45        self.iwram = Memory(core, lib.SIZE_WORKING_IRAM, lib.BASE_WORKING_IRAM)
46        self.io = Memory(core, lib.SIZE_IO, lib.BASE_IO)
47        self.palette = Memory(core, lib.SIZE_PALETTE_RAM, lib.BASE_PALETTE_RAM)
48        self.vram = Memory(core, lib.SIZE_VRAM, lib.BASE_VRAM)
49        self.oam = Memory(core, lib.SIZE_OAM, lib.BASE_OAM)
50        self.cart0 = Memory(core, lib.SIZE_CART0, lib.BASE_CART0)
51        self.cart1 = Memory(core, lib.SIZE_CART1, lib.BASE_CART1)
52        self.cart2 = Memory(core, lib.SIZE_CART2, lib.BASE_CART2)
53        self.cart = self.cart0
54        self.sram = Memory(core, lib.SIZE_CART_SRAM, lib.BASE_CART_SRAM)
55
56class GBASprite(Sprite):
57    TILE_BASE = 0x800, 0x400
58    PALETTE_BASE = 0x10, 1
59
60    def __init__(self, obj):
61        self._a = obj.a
62        self._b = obj.b
63        self._c = obj.c
64        self.x = self._b & 0x1FF
65        self.y = self._a & 0xFF
66        self._shape = self._a >> 14
67        self._size = self._b >> 14
68        self._256Color = bool(self._a & 0x2000)
69        self.width, self.height = lib.GBAVideoObjSizes[self._shape * 4 + self._size]
70        self.tile = self._c & 0x3FF
71        if self._256Color:
72            self.paletteId = 0
73            self.tile >>= 1
74        else:
75            self.paletteId = self._c >> 12
76
77class GBAObjs:
78    def __init__(self, core):
79        self._core = core
80        self._obj = core._native.video.oam.obj
81
82    def __len__(self):
83        return 128
84
85    def __getitem__(self, index):
86        if index >= len(self):
87            raise IndexError()
88        sprite = GBASprite(self._obj[index])
89        map1D = bool(self._core._native.memory.io[0] & 0x40)
90        sprite.constitute(self._core.tiles, 0 if map1D else 0x20, int(sprite._256Color))
91        return sprite