Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libgambatte/src/video/sprite_mapper.h
2 views
1
/***************************************************************************
2
* Copyright (C) 2007 by Sindre AamÄs *
3
* [email protected] *
4
* *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License version 2 as *
7
* published by the Free Software Foundation. *
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 version 2 for more details. *
13
* *
14
* You should have received a copy of the GNU General Public License *
15
* version 2 along with this program; if not, write to the *
16
* Free Software Foundation, Inc., *
17
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18
***************************************************************************/
19
#ifndef SPRITE_MAPPER_H
20
#define SPRITE_MAPPER_H
21
22
#include "ly_counter.h"
23
#include "../savestate.h"
24
#include "newstate.h"
25
26
namespace gambatte {
27
class NextM0Time;
28
29
class SpriteMapper {
30
class OamReader {
31
unsigned char buf[80];
32
bool szbuf[40];
33
34
public:
35
const LyCounter &lyCounter;
36
37
private:
38
const unsigned char *oamram;
39
unsigned long lu;
40
unsigned char lastChange;
41
bool largeSpritesSrc;
42
bool cgb_;
43
44
public:
45
OamReader(const LyCounter &lyCounter, const unsigned char *oamram);
46
void reset(const unsigned char *oamram, bool cgb);
47
void change(unsigned long cc);
48
void change(const unsigned char *oamram, unsigned long cc) { change(cc); this->oamram = oamram; }
49
bool changed() const { return lastChange != 0xFF; }
50
bool largeSprites(unsigned spNr) const { return szbuf[spNr]; }
51
const unsigned char *oam() const { return oamram; }
52
void resetCycleCounter(const unsigned long oldCc, const unsigned long newCc) { lu -= oldCc - newCc; }
53
void setLargeSpritesSrc(const bool src) { largeSpritesSrc = src; }
54
void update(unsigned long cc);
55
const unsigned char *spritePosBuf() const { return buf; }
56
void setStatePtrs(SaveState &state);
57
void enableDisplay(unsigned long cc);
58
void loadState(const SaveState &ss, const unsigned char *oamram);
59
bool inactivePeriodAfterDisplayEnable(const unsigned long cc) const { return cc < lu; }
60
61
template<bool isReader>void SyncState(NewState *ns);
62
};
63
64
enum { NEED_SORTING_MASK = 0x80 };
65
66
public:
67
class SpxLess {
68
const unsigned char *const posbuf_plus1;
69
70
public:
71
explicit SpxLess(const unsigned char *const posbuf) : posbuf_plus1(posbuf + 1) {}
72
73
bool operator()(const unsigned char l, const unsigned char r) const {
74
return posbuf_plus1[l] < posbuf_plus1[r];
75
}
76
};
77
78
private:
79
mutable unsigned char spritemap[144*10];
80
mutable unsigned char num[144];
81
82
NextM0Time &nextM0Time_;
83
OamReader oamReader;
84
85
void clearMap();
86
void mapSprites();
87
void sortLine(unsigned ly) const;
88
89
public:
90
SpriteMapper(NextM0Time &nextM0Time,
91
const LyCounter &lyCounter,
92
const unsigned char *oamram_in);
93
void reset(const unsigned char *oamram, bool cgb);
94
unsigned long doEvent(unsigned long time);
95
bool largeSprites(unsigned spNr) const { return oamReader.largeSprites(spNr); }
96
unsigned numSprites(const unsigned ly) const { return num[ly] & ~NEED_SORTING_MASK; }
97
void oamChange(unsigned long cc) { oamReader.change(cc); }
98
void oamChange(const unsigned char *oamram, unsigned long cc) { oamReader.change(oamram, cc); }
99
const unsigned char *oamram() const { return oamReader.oam(); }
100
const unsigned char *posbuf() const { return oamReader.spritePosBuf(); }
101
void preSpeedChange(const unsigned long cc) { oamReader.update(cc); }
102
void postSpeedChange(const unsigned long cc) { oamReader.change(cc); }
103
104
void resetCycleCounter(const unsigned long oldCc, const unsigned long newCc) {
105
oamReader.update(oldCc);
106
oamReader.resetCycleCounter(oldCc, newCc);
107
}
108
109
static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) {
110
return lyCounter.nextLineCycle(80, cycleCounter);
111
}
112
113
void setLargeSpritesSource(bool src) { oamReader.setLargeSpritesSrc(src); }
114
115
const unsigned char* sprites(const unsigned ly) const {
116
if (num[ly] & NEED_SORTING_MASK)
117
sortLine(ly);
118
119
return spritemap + ly * 10;
120
}
121
122
void setStatePtrs(SaveState &state) { oamReader.setStatePtrs(state); }
123
void enableDisplay(unsigned long cc) { oamReader.enableDisplay(cc); }
124
void loadState(const SaveState &state, const unsigned char *const oamram) { oamReader.loadState(state, oamram); mapSprites(); }
125
bool inactivePeriodAfterDisplayEnable(unsigned long cc) const { return oamReader.inactivePeriodAfterDisplayEnable(cc); }
126
127
template<bool isReader>void SyncState(NewState *ns);
128
};
129
130
}
131
132
#endif
133
134