Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmeteor/source/graphics/objects.cpp
2 views
1
// Meteor - A Nintendo Gameboy Advance emulator
2
// Copyright (C) 2009-2011 Philippe Daouadi
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
#include "ameteor/graphics/objects.hpp"
18
#include "../debug.hpp"
19
#include <string.h>
20
21
namespace AMeteor
22
{
23
namespace Graphics
24
{
25
Objects::Objects (Memory& memory, Io& io, uint16_t* pPalette) :
26
m_io(io),
27
m_objs(128, Object(pPalette,
28
memory.GetRealAddress(0x06010000))),
29
m_pOam((uint16_t*)memory.GetRealAddress(0x07000000))
30
{
31
}
32
33
void Objects::DrawLine (uint8_t line, uint32_t* surface)
34
{
35
bool oneDim = m_io.DRead16(Io::DISPCNT) & (0x1 << 6);
36
uint8_t mosaic = m_io.DRead8(Io::MOSAIC+1);
37
int16_t rotSel;
38
for (Objs::iterator iter = m_objs.begin();
39
iter != m_objs.end(); ++iter)
40
{
41
rotSel = iter->GetRotationParam();
42
if (rotSel == -1)
43
iter->DrawLine (line, surface, oneDim, mosaic);
44
else
45
{
46
rotSel *= 16;
47
iter->DrawLineRot (line, surface, oneDim, m_pOam[rotSel + 3],
48
m_pOam[rotSel + 7], m_pOam[rotSel + 11], m_pOam[rotSel + 15],
49
mosaic);
50
}
51
}
52
}
53
54
void Objects::DrawLineHighOnly (uint8_t line, uint32_t* surface)
55
{
56
bool oneDim = m_io.DRead16(Io::DISPCNT) & (0x1 << 6);
57
uint8_t mosaic = m_io.DRead8(Io::MOSAIC+1);
58
int16_t rotSel;
59
for (Objs::iterator iter = m_objs.begin();
60
iter != m_objs.end(); ++iter)
61
if (iter->GetTileNum() >= 512)
62
{
63
rotSel = iter->GetRotationParam();
64
if (rotSel == -1)
65
iter->DrawLine (line, surface, oneDim, mosaic);
66
else
67
{
68
rotSel *= 16;
69
iter->DrawLineRot (line, surface, oneDim, m_pOam[rotSel + 3],
70
m_pOam[rotSel + 7], m_pOam[rotSel + 11], m_pOam[rotSel + 15],
71
mosaic);
72
}
73
}
74
}
75
76
void Objects::DrawWindow (uint8_t line, uint8_t* surface)
77
{
78
bool oneDim = m_io.DRead16(Io::DISPCNT) & (0x1 << 6);
79
int16_t rotSel;
80
uint8_t mask = (m_io.DRead16(Io::WINOUT) >> 8) & 0x3F;
81
for (Objs::iterator iter = m_objs.begin(); iter != m_objs.end(); ++iter)
82
if (iter->IsWindow())
83
{
84
rotSel = iter->GetRotationParam();
85
if (rotSel == -1)
86
iter->DrawWindow (line, surface, oneDim, mask);
87
else
88
{
89
rotSel *= 16;
90
iter->DrawWindowRot (line, surface, oneDim, m_pOam[rotSel + 3],
91
m_pOam[rotSel + 7], m_pOam[rotSel + 11], m_pOam[rotSel + 15],
92
mask);
93
}
94
}
95
}
96
97
void Objects::OamWrite (uint32_t begin, uint32_t end)
98
{
99
uint32_t objnum;
100
// FIXME is this possible ?
101
if (begin & 0x3)
102
met_abort("OamWrite not 4 byte aligned");
103
if (begin <= 0x07000000)
104
objnum = 0;
105
else
106
objnum = (begin - 0x07000000);
107
uint16_t* pOam = m_pOam + objnum/2;
108
objnum /= 8;
109
110
Objs::iterator iterStart;
111
iterStart = m_objs.begin() + objnum;
112
Objs::iterator iterEnd = m_objs.begin() + (end - 0x07000000 + 7)/8;
113
if (iterEnd > m_objs.end())
114
iterEnd = m_objs.end();
115
116
for (Objs::iterator iter = iterStart; iter != iterEnd; ++iter, ++objnum)
117
{
118
iter->UpdateAttrs(pOam[0], pOam[1], pOam[2]);
119
pOam += 4;
120
}
121
}
122
123
void Objects::OamWrite16 (uint32_t add)
124
{
125
uint16_t objnum = (add - 0x07000000) / 8;
126
uint16_t* pOam = m_pOam + objnum*4;
127
Objs::iterator iter = m_objs.begin() + objnum;
128
switch ((add - 0x07000000) % 8)
129
{
130
case 0:
131
iter->UpdateAttr0(pOam[0]);
132
break;
133
case 2:
134
iter->UpdateAttr1(pOam[1]);
135
break;
136
case 4:
137
iter->UpdateAttr2(pOam[2]);
138
break;
139
case 6:
140
break;
141
default :
142
met_abort("Oam access not 16 bits aligned");
143
break;
144
}
145
}
146
147
void Objects::OamWrite32 (uint32_t add)
148
{
149
add -= 0x07000000;
150
uint16_t objnum = add / 8;
151
uint16_t* pOam = m_pOam + objnum * 4;
152
Objs::iterator iter = m_objs.begin() + objnum;
153
switch (add % 8)
154
{
155
case 0:
156
iter->UpdateAttr0(pOam[0]);
157
iter->UpdateAttr1(pOam[1]);
158
break;
159
case 4:
160
iter->UpdateAttr2(pOam[2]);
161
break;
162
default :
163
met_abort("Oam access not 32 bits aligned");
164
break;
165
}
166
}
167
}
168
}
169
170